bnx2x: driver support routines

More code for the Broadcom/Qlogic NetExtreme II poll mode driver.
Split into pieces for review and not to overwhelm mailers.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Harish Patil <harish.patil@qlogic.com>
This commit is contained in:
Stephen Hemminger 2015-07-20 09:33:19 -07:00 committed by Thomas Monjalon
parent 540a211084
commit b5bf771922
12 changed files with 33720 additions and 0 deletions

113
drivers/net/bnx2x/debug.c Normal file
View File

@ -0,0 +1,113 @@
/*-
* Copyright (c) 2007-2013 QLogic Corporation. All rights reserved.
*
* Eric Davis <edavis@broadcom.com>
* David Christensen <davidch@broadcom.com>
* Gary Zambrano <zambrano@broadcom.com>
*
* Copyright (c) 2013-2015 Brocade Communications Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Broadcom Corporation nor the name of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written consent.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "bnx2x.h"
/*
* Debug versions of the 8/16/32 bit OS register read/write functions to
* capture/display values read/written from/to the controller.
*/
void
bnx2x_reg_write8(struct bnx2x_softc *sc, size_t offset, uint8_t val)
{
PMD_DRV_LOG(DEBUG, "offset=0x%08lx val=0x%02x", offset, val);
*((volatile uint8_t*)((uint64_t)sc->bar[BAR0].base_addr + offset)) = val;
}
void
bnx2x_reg_write16(struct bnx2x_softc *sc, size_t offset, uint16_t val)
{
if ((offset % 2) != 0) {
PMD_DRV_LOG(DEBUG, "Unaligned 16-bit write to 0x%08lx", offset);
}
PMD_DRV_LOG(DEBUG, "offset=0x%08lx val=0x%04x", offset, val);
*((volatile uint16_t*)((uint64_t)sc->bar[BAR0].base_addr + offset)) = val;
}
void
bnx2x_reg_write32(struct bnx2x_softc *sc, size_t offset, uint32_t val)
{
if ((offset % 4) != 0) {
PMD_DRV_LOG(DEBUG, "Unaligned 32-bit write to 0x%08lx", offset);
}
PMD_DRV_LOG(DEBUG, "offset=0x%08lx val=0x%08x", offset, val);
*((volatile uint32_t*)((uint64_t)sc->bar[BAR0].base_addr + offset)) = val;
}
uint8_t
bnx2x_reg_read8(struct bnx2x_softc *sc, size_t offset)
{
uint8_t val;
val = (uint8_t)(*((volatile uint8_t*)((uint64_t)sc->bar[BAR0].base_addr + offset)));
PMD_DRV_LOG(DEBUG, "offset=0x%08lx val=0x%02x", offset, val);
return (val);
}
uint16_t
bnx2x_reg_read16(struct bnx2x_softc *sc, size_t offset)
{
uint16_t val;
if ((offset % 2) != 0) {
PMD_DRV_LOG(DEBUG, "Unaligned 16-bit read from 0x%08lx", offset);
}
val = (uint16_t)(*((volatile uint16_t*)((uint64_t)sc->bar[BAR0].base_addr + offset)));
PMD_DRV_LOG(DEBUG, "offset=0x%08lx val=0x%08x", offset, val);
return (val);
}
uint32_t
bnx2x_reg_read32(struct bnx2x_softc *sc, size_t offset)
{
uint32_t val;
if ((offset % 4) != 0) {
PMD_DRV_LOG(DEBUG, "Unaligned 32-bit read from 0x%08lx", offset);
return 0;
}
val = (uint32_t)(*((volatile uint32_t*)((uint64_t)sc->bar[BAR0].base_addr + offset)));
PMD_DRV_LOG(DEBUG, "offset=0x%08lx val=0x%08x", offset, val);
return (val);
}

View File

@ -0,0 +1,422 @@
/*-
* Copyright (c) 2007-2013 QLogic Corporation. All rights reserved.
*
* Eric Davis <edavis@broadcom.com>
* David Christensen <davidch@broadcom.com>
* Gary Zambrano <zambrano@broadcom.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Broadcom Corporation nor the name of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written consent.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ECORE_FW_DEFS_H
#define ECORE_FW_DEFS_H
#define CSTORM_ASSERT_LIST_INDEX_OFFSET (IRO[148].base)
#define CSTORM_ASSERT_LIST_OFFSET(assertListEntry) \
(IRO[147].base + ((assertListEntry) * IRO[147].m1))
#define CSTORM_EVENT_RING_DATA_OFFSET(pfId) \
(IRO[153].base + (((pfId)>>1) * IRO[153].m1) + (((pfId)&1) * \
IRO[153].m2))
#define CSTORM_EVENT_RING_PROD_OFFSET(pfId) \
(IRO[154].base + (((pfId)>>1) * IRO[154].m1) + (((pfId)&1) * \
IRO[154].m2))
#define CSTORM_VF_PF_CHANNEL_STATE_OFFSET(vfId) \
(IRO[155].base + ((vfId) * IRO[155].m1))
#define CSTORM_VF_PF_CHANNEL_VALID_OFFSET(vfId) \
(IRO[156].base + ((vfId) * IRO[156].m1))
#define CSTORM_VF_TO_PF_OFFSET(funcId) \
(IRO[150].base + ((funcId) * IRO[150].m1))
#define CSTORM_FINAL_CLEANUP_COMPLETE_OFFSET(funcId) \
(IRO[159].base + ((funcId) * IRO[159].m1))
#define CSTORM_FUNC_EN_OFFSET(funcId) \
(IRO[149].base + ((funcId) * IRO[149].m1))
#define CSTORM_HC_SYNC_LINE_INDEX_E1X_OFFSET(hcIndex, sbId) \
(IRO[139].base + ((hcIndex) * IRO[139].m1) + ((sbId) * IRO[139].m2))
#define CSTORM_HC_SYNC_LINE_INDEX_E2_OFFSET(hcIndex, sbId) \
(IRO[138].base + (((hcIndex)>>2) * IRO[138].m1) + (((hcIndex)&3) \
* IRO[138].m2) + ((sbId) * IRO[138].m3))
#define CSTORM_IGU_MODE_OFFSET (IRO[157].base)
#define CSTORM_ISCSI_CQ_SIZE_OFFSET(pfId) \
(IRO[317].base + ((pfId) * IRO[317].m1))
#define CSTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfId) \
(IRO[318].base + ((pfId) * IRO[318].m1))
#define CSTORM_ISCSI_EQ_CONS_OFFSET(pfId, iscsiEqId) \
(IRO[310].base + ((pfId) * IRO[310].m1) + ((iscsiEqId) * IRO[310].m2))
#define CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(pfId, iscsiEqId) \
(IRO[312].base + ((pfId) * IRO[312].m1) + ((iscsiEqId) * IRO[312].m2))
#define CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(pfId, iscsiEqId) \
(IRO[311].base + ((pfId) * IRO[311].m1) + ((iscsiEqId) * IRO[311].m2))
#define CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_VALID_OFFSET(pfId, iscsiEqId) \
(IRO[313].base + ((pfId) * IRO[313].m1) + ((iscsiEqId) * IRO[313].m2))
#define CSTORM_ISCSI_EQ_PROD_OFFSET(pfId, iscsiEqId) \
(IRO[309].base + ((pfId) * IRO[309].m1) + ((iscsiEqId) * IRO[309].m2))
#define CSTORM_ISCSI_EQ_SB_INDEX_OFFSET(pfId, iscsiEqId) \
(IRO[315].base + ((pfId) * IRO[315].m1) + ((iscsiEqId) * IRO[315].m2))
#define CSTORM_ISCSI_EQ_SB_NUM_OFFSET(pfId, iscsiEqId) \
(IRO[314].base + ((pfId) * IRO[314].m1) + ((iscsiEqId) * IRO[314].m2))
#define CSTORM_ISCSI_HQ_SIZE_OFFSET(pfId) \
(IRO[316].base + ((pfId) * IRO[316].m1))
#define CSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \
(IRO[308].base + ((pfId) * IRO[308].m1))
#define CSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \
(IRO[307].base + ((pfId) * IRO[307].m1))
#define CSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \
(IRO[306].base + ((pfId) * IRO[306].m1))
#define CSTORM_RECORD_SLOW_PATH_OFFSET(funcId) \
(IRO[151].base + ((funcId) * IRO[151].m1))
#define CSTORM_SP_STATUS_BLOCK_DATA_OFFSET(pfId) \
(IRO[142].base + ((pfId) * IRO[142].m1))
#define CSTORM_SP_STATUS_BLOCK_DATA_STATE_OFFSET(pfId) \
(IRO[143].base + ((pfId) * IRO[143].m1))
#define CSTORM_SP_STATUS_BLOCK_OFFSET(pfId) \
(IRO[141].base + ((pfId) * IRO[141].m1))
#define CSTORM_SP_STATUS_BLOCK_SIZE (IRO[141].size)
#define CSTORM_SP_SYNC_BLOCK_OFFSET(pfId) \
(IRO[144].base + ((pfId) * IRO[144].m1))
#define CSTORM_SP_SYNC_BLOCK_SIZE (IRO[144].size)
#define CSTORM_STATUS_BLOCK_DATA_FLAGS_OFFSET(sbId, hcIndex) \
(IRO[136].base + ((sbId) * IRO[136].m1) + ((hcIndex) * IRO[136].m2))
#define CSTORM_STATUS_BLOCK_DATA_OFFSET(sbId) \
(IRO[133].base + ((sbId) * IRO[133].m1))
#define CSTORM_STATUS_BLOCK_DATA_STATE_OFFSET(sbId) \
(IRO[134].base + ((sbId) * IRO[134].m1))
#define CSTORM_STATUS_BLOCK_DATA_TIMEOUT_OFFSET(sbId, hcIndex) \
(IRO[135].base + ((sbId) * IRO[135].m1) + ((hcIndex) * IRO[135].m2))
#define CSTORM_STATUS_BLOCK_OFFSET(sbId) \
(IRO[132].base + ((sbId) * IRO[132].m1))
#define CSTORM_STATUS_BLOCK_SIZE (IRO[132].size)
#define CSTORM_SYNC_BLOCK_OFFSET(sbId) \
(IRO[137].base + ((sbId) * IRO[137].m1))
#define CSTORM_SYNC_BLOCK_SIZE (IRO[137].size)
#define CSTORM_VF_TO_PF_OFFSET(funcId) \
(IRO[150].base + ((funcId) * IRO[150].m1))
#define TSTORM_ACCEPT_CLASSIFY_FAILED_OFFSET (IRO[204].base)
#define TSTORM_APPROXIMATE_MATCH_MULTICAST_FILTERING_OFFSET(pfId) \
(IRO[203].base + ((pfId) * IRO[203].m1))
#define TSTORM_ASSERT_LIST_INDEX_OFFSET (IRO[102].base)
#define TSTORM_ASSERT_LIST_OFFSET(assertListEntry) \
(IRO[101].base + ((assertListEntry) * IRO[101].m1))
#define TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(pfId) \
(IRO[201].base + ((pfId) * IRO[201].m1))
#define TSTORM_FUNC_EN_OFFSET(funcId) \
(IRO[103].base + ((funcId) * IRO[103].m1))
#define TSTORM_ISCSI_ERROR_BITMAP_OFFSET(pfId) \
(IRO[272].base + ((pfId) * IRO[272].m1))
#define TSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \
(IRO[271].base + ((pfId) * IRO[271].m1))
#define TSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \
(IRO[270].base + ((pfId) * IRO[270].m1))
#define TSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \
(IRO[269].base + ((pfId) * IRO[269].m1))
#define TSTORM_ISCSI_RQ_SIZE_OFFSET(pfId) \
(IRO[268].base + ((pfId) * IRO[268].m1))
#define TSTORM_ISCSI_TCP_LOCAL_ADV_WND_OFFSET(pfId) \
(IRO[278].base + ((pfId) * IRO[278].m1))
#define TSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(pfId) \
(IRO[264].base + ((pfId) * IRO[264].m1))
#define TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(pfId) \
(IRO[265].base + ((pfId) * IRO[265].m1))
#define TSTORM_ISCSI_TCP_VARS_MID_LOCAL_MAC_ADDR_OFFSET(pfId) \
(IRO[266].base + ((pfId) * IRO[266].m1))
#define TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(pfId) \
(IRO[267].base + ((pfId) * IRO[267].m1))
#define TSTORM_MAC_FILTER_CONFIG_OFFSET(pfId) \
(IRO[202].base + ((pfId) * IRO[202].m1))
#define TSTORM_RECORD_SLOW_PATH_OFFSET(funcId) \
(IRO[105].base + ((funcId) * IRO[105].m1))
#define TSTORM_TCP_MAX_CWND_OFFSET(pfId) \
(IRO[217].base + ((pfId) * IRO[217].m1))
#define TSTORM_VF_TO_PF_OFFSET(funcId) \
(IRO[104].base + ((funcId) * IRO[104].m1))
#define USTORM_AGG_DATA_OFFSET (IRO[206].base)
#define USTORM_AGG_DATA_SIZE (IRO[206].size)
#define USTORM_ASSERT_LIST_INDEX_OFFSET (IRO[177].base)
#define USTORM_ASSERT_LIST_OFFSET(assertListEntry) \
(IRO[176].base + ((assertListEntry) * IRO[176].m1))
#define USTORM_CQE_PAGE_NEXT_OFFSET(portId, clientId) \
(IRO[205].base + ((portId) * IRO[205].m1) + ((clientId) * IRO[205].m2))
#define USTORM_ETH_PAUSE_ENABLED_OFFSET(portId) \
(IRO[183].base + ((portId) * IRO[183].m1))
#define USTORM_FCOE_EQ_PROD_OFFSET(pfId) \
(IRO[319].base + ((pfId) * IRO[319].m1))
#define USTORM_FUNC_EN_OFFSET(funcId) \
(IRO[178].base + ((funcId) * IRO[178].m1))
#define USTORM_ISCSI_CQ_SIZE_OFFSET(pfId) \
(IRO[283].base + ((pfId) * IRO[283].m1))
#define USTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfId) \
(IRO[284].base + ((pfId) * IRO[284].m1))
#define USTORM_ISCSI_ERROR_BITMAP_OFFSET(pfId) \
(IRO[288].base + ((pfId) * IRO[288].m1))
#define USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(pfId) \
(IRO[285].base + ((pfId) * IRO[285].m1))
#define USTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \
(IRO[281].base + ((pfId) * IRO[281].m1))
#define USTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \
(IRO[280].base + ((pfId) * IRO[280].m1))
#define USTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \
(IRO[279].base + ((pfId) * IRO[279].m1))
#define USTORM_ISCSI_R2TQ_SIZE_OFFSET(pfId) \
(IRO[282].base + ((pfId) * IRO[282].m1))
#define USTORM_ISCSI_RQ_BUFFER_SIZE_OFFSET(pfId) \
(IRO[286].base + ((pfId) * IRO[286].m1))
#define USTORM_ISCSI_RQ_SIZE_OFFSET(pfId) \
(IRO[287].base + ((pfId) * IRO[287].m1))
#define USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(pfId) \
(IRO[182].base + ((pfId) * IRO[182].m1))
#define USTORM_RECORD_SLOW_PATH_OFFSET(funcId) \
(IRO[180].base + ((funcId) * IRO[180].m1))
#define USTORM_RX_PRODS_E1X_OFFSET(portId, clientId) \
(IRO[209].base + ((portId) * IRO[209].m1) + ((clientId) * \
IRO[209].m2))
#define USTORM_RX_PRODS_E2_OFFSET(qzoneId) \
(IRO[210].base + ((qzoneId) * IRO[210].m1))
#define USTORM_TPA_BTR_OFFSET (IRO[207].base)
#define USTORM_TPA_BTR_SIZE (IRO[207].size)
#define USTORM_VF_TO_PF_OFFSET(funcId) \
(IRO[179].base + ((funcId) * IRO[179].m1))
#define XSTORM_AGG_INT_FINAL_CLEANUP_COMP_TYPE (IRO[67].base)
#define XSTORM_AGG_INT_FINAL_CLEANUP_INDEX (IRO[66].base)
#define XSTORM_ASSERT_LIST_INDEX_OFFSET (IRO[51].base)
#define XSTORM_ASSERT_LIST_OFFSET(assertListEntry) \
(IRO[50].base + ((assertListEntry) * IRO[50].m1))
#define XSTORM_CMNG_PER_PORT_VARS_OFFSET(portId) \
(IRO[43].base + ((portId) * IRO[43].m1))
#define XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(pfId) \
(IRO[45].base + ((pfId) * IRO[45].m1))
#define XSTORM_FUNC_EN_OFFSET(funcId) \
(IRO[47].base + ((funcId) * IRO[47].m1))
#define XSTORM_ISCSI_HQ_SIZE_OFFSET(pfId) \
(IRO[296].base + ((pfId) * IRO[296].m1))
#define XSTORM_ISCSI_LOCAL_MAC_ADDR0_OFFSET(pfId) \
(IRO[299].base + ((pfId) * IRO[299].m1))
#define XSTORM_ISCSI_LOCAL_MAC_ADDR1_OFFSET(pfId) \
(IRO[300].base + ((pfId) * IRO[300].m1))
#define XSTORM_ISCSI_LOCAL_MAC_ADDR2_OFFSET(pfId) \
(IRO[301].base + ((pfId) * IRO[301].m1))
#define XSTORM_ISCSI_LOCAL_MAC_ADDR3_OFFSET(pfId) \
(IRO[302].base + ((pfId) * IRO[302].m1))
#define XSTORM_ISCSI_LOCAL_MAC_ADDR4_OFFSET(pfId) \
(IRO[303].base + ((pfId) * IRO[303].m1))
#define XSTORM_ISCSI_LOCAL_MAC_ADDR5_OFFSET(pfId) \
(IRO[304].base + ((pfId) * IRO[304].m1))
#define XSTORM_ISCSI_LOCAL_VLAN_OFFSET(pfId) \
(IRO[305].base + ((pfId) * IRO[305].m1))
#define XSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \
(IRO[295].base + ((pfId) * IRO[295].m1))
#define XSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \
(IRO[294].base + ((pfId) * IRO[294].m1))
#define XSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \
(IRO[293].base + ((pfId) * IRO[293].m1))
#define XSTORM_ISCSI_R2TQ_SIZE_OFFSET(pfId) \
(IRO[298].base + ((pfId) * IRO[298].m1))
#define XSTORM_ISCSI_SQ_SIZE_OFFSET(pfId) \
(IRO[297].base + ((pfId) * IRO[297].m1))
#define XSTORM_ISCSI_TCP_VARS_ADV_WND_SCL_OFFSET(pfId) \
(IRO[292].base + ((pfId) * IRO[292].m1))
#define XSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(pfId) \
(IRO[291].base + ((pfId) * IRO[291].m1))
#define XSTORM_ISCSI_TCP_VARS_TOS_OFFSET(pfId) \
(IRO[290].base + ((pfId) * IRO[290].m1))
#define XSTORM_ISCSI_TCP_VARS_TTL_OFFSET(pfId) \
(IRO[289].base + ((pfId) * IRO[289].m1))
#define XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(pfId) \
(IRO[44].base + ((pfId) * IRO[44].m1))
#define XSTORM_RECORD_SLOW_PATH_OFFSET(funcId) \
(IRO[49].base + ((funcId) * IRO[49].m1))
#define XSTORM_SPQ_DATA_OFFSET(funcId) \
(IRO[32].base + ((funcId) * IRO[32].m1))
#define XSTORM_SPQ_DATA_SIZE (IRO[32].size)
#define XSTORM_SPQ_PAGE_BASE_OFFSET(funcId) \
(IRO[30].base + ((funcId) * IRO[30].m1))
#define XSTORM_SPQ_PROD_OFFSET(funcId) \
(IRO[31].base + ((funcId) * IRO[31].m1))
#define XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_ENABLED_OFFSET(portId) \
(IRO[211].base + ((portId) * IRO[211].m1))
#define XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_MAX_COUNT_OFFSET(portId) \
(IRO[212].base + ((portId) * IRO[212].m1))
#define XSTORM_TCP_TX_SWS_TIMER_VAL_OFFSET(pfId) \
(IRO[214].base + (((pfId)>>1) * IRO[214].m1) + (((pfId)&1) * \
IRO[214].m2))
#define XSTORM_VF_TO_PF_OFFSET(funcId) \
(IRO[48].base + ((funcId) * IRO[48].m1))
#define COMMON_ASM_INVALID_ASSERT_OPCODE (IRO[7].base)
/* Ethernet Ring parameters */
#define X_ETH_LOCAL_RING_SIZE 13
#define FIRST_BD_IN_PKT 0
#define PARSE_BD_INDEX 1
#define NUM_OF_ETH_BDS_IN_PAGE ((PAGE_SIZE)/(STRUCT_SIZE(eth_tx_bd)/8))
/* Rx ring params */
#define U_ETH_LOCAL_BD_RING_SIZE 8
#define U_ETH_SGL_SIZE 8
/* The fw will padd the buffer with this value, so the IP header \
will be align to 4 Byte */
#define IP_HEADER_ALIGNMENT_PADDING 2
#define TU_ETH_CQES_PER_PAGE (PAGE_SIZE/(STRUCT_SIZE(eth_rx_cqe)/8))
#define U_ETH_BDS_PER_PAGE (PAGE_SIZE/(STRUCT_SIZE(eth_rx_bd)/8))
#define U_ETH_BDS_PER_PAGE_MASK (U_ETH_BDS_PER_PAGE-1)
#define U_ETH_CQE_PER_PAGE_MASK (TU_ETH_CQES_PER_PAGE-1)
#define U_ETH_UNDEFINED_Q 0xFF
#define T_ETH_INDIRECTION_TABLE_SIZE 128
#define T_ETH_RSS_KEY 10
#define ETH_NUM_OF_RSS_ENGINES_E2 72
#define FILTER_RULES_COUNT 16
#define MULTICAST_RULES_COUNT 16
#define CLASSIFY_RULES_COUNT 16
/*The CRC32 seed, that is used for the hash(reduction) multicast address */
#define ETH_CRC32_HASH_SEED 0x00000000
#define ETH_CRC32_HASH_BIT_SIZE (8)
#define ETH_CRC32_HASH_MASK EVAL((1<<ETH_CRC32_HASH_BIT_SIZE)-1)
/* Maximal L2 clients supported */
#define ETH_MAX_RX_CLIENTS_E1H 28
#define ETH_MAX_RX_CLIENTS_E2 152
/* Maximal statistics client Ids */
#define MAX_STAT_COUNTER_ID_E1H 56
#define MAX_STAT_COUNTER_ID_E2 140
#define MAX_MAC_CREDIT_E1H 256 /* Per Chip */
#define MAX_MAC_CREDIT_E2 272 /* Per Path */
#define MAX_VLAN_CREDIT_E1H 0 /* Per Chip */
#define MAX_VLAN_CREDIT_E2 272 /* Per Path */
/* Maximal aggregation queues supported */
#define ETH_MAX_AGGREGATION_QUEUES_E1H_E2 64
#define ETH_NUM_OF_MCAST_BINS 256
#define ETH_NUM_OF_MCAST_ENGINES_E2 72
#define ETH_MIN_RX_CQES_WITHOUT_TPA (MAX_RAMRODS_PER_PORT + 3)
#define ETH_MIN_RX_CQES_WITH_TPA_E1H_E2 \
(ETH_MAX_AGGREGATION_QUEUES_E1H_E2 + ETH_MIN_RX_CQES_WITHOUT_TPA)
#define DISABLE_STATISTIC_COUNTER_ID_VALUE 0
/* This file defines HSI constants common to all microcode flows */
/* offset in bits of protocol in the state context parameter */
#define PROTOCOL_STATE_BIT_OFFSET 6
#define ETH_STATE (ETH_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
#define TOE_STATE (TOE_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
#define RDMA_STATE (RDMA_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
/* microcode fixed page page size 4K (chains and ring segments) */
#define MC_PAGE_SIZE 4096
/* Number of indices per slow-path SB */
#define HC_SP_SB_MAX_INDICES 16 /* The Maximum of all */
/* Number of indices per SB */
#define HC_SB_MAX_INDICES_E1X 8 /* Multiple of 4 */
#define HC_SB_MAX_INDICES_E2 8 /* Multiple of 4 */
/* Number of SB */
#define HC_SB_MAX_SB_E1X 32
#define HC_SB_MAX_SB_E2 136 /* include PF */
/* ID of slow path status block */
#define HC_SP_SB_ID 0xde
/* Num of State machines */
#define HC_SB_MAX_SM 2 /* Fixed */
/* Num of dynamic indices */
#define HC_SB_MAX_DYNAMIC_INDICES 4 /* 0..3 fixed */
/* max number of slow path commands per port */
#define MAX_RAMRODS_PER_PORT 8
/**** DEFINES FOR TIMERS/CLOCKS RESOLUTIONS ****/
/* chip timers frequency constants */
#define TIMERS_TICK_SIZE_CHIP (1e-3)
/* used in toe: TsRecentAge, MaxRt, and temporarily RTT */
#define TSEMI_CLK1_RESUL_CHIP (1e-3)
/* temporarily used for RTT */
#define XSEMI_CLK1_RESUL_CHIP (1e-3)
/* used for Host Coallescing */
#define SDM_TIMER_TICK_RESUL_CHIP (4 * (1e-6))
/**** END DEFINES FOR TIMERS/CLOCKS RESOLUTIONS ****/
#define XSTORM_IP_ID_ROLL_HALF 0x8000
#define XSTORM_IP_ID_ROLL_ALL 0
/* assert list: number of entries */
#define FW_LOG_LIST_SIZE 50
#define NUM_OF_SAFC_BITS 16
#define MAX_COS_NUMBER 4
#define MAX_TRAFFIC_TYPES 8
#define MAX_PFC_PRIORITIES 8
/* used by array traffic_type_to_priority[] to mark traffic type \
that is not mapped to priority*/
#define LLFC_TRAFFIC_TYPE_TO_PRIORITY_UNMAPPED 0xFF
/* Event Ring definitions */
#define C_ERES_PER_PAGE \
(PAGE_SIZE / BITS_TO_BYTES(STRUCT_SIZE(event_ring_elem)))
#define C_ERE_PER_PAGE_MASK (C_ERES_PER_PAGE - 1)
/* number of statistic command */
#define STATS_QUERY_CMD_COUNT 16
/* niv list table size */
#define AFEX_LIST_TABLE_SIZE 4096
/* invalid VNIC Id. used in VNIC classification */
#define INVALID_VNIC_ID 0xFF
/* used for indicating an undefined RAM offset in the IRO arrays */
#define UNDEF_IRO 0x80000000
/* used for defining the amount of FCoE tasks supported for PF */
#define MAX_FCOE_FUNCS_PER_ENGINE 2
#define MAX_NUM_FCOE_TASKS_PER_ENGINE \
4096 /*Each port can have at max 1 function*/
#endif /* ECORE_FW_DEFS_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,841 @@
/*-
* Copyright (c) 2007-2013 QLogic Corporation. All rights reserved.
*
* Eric Davis <edavis@broadcom.com>
* David Christensen <davidch@broadcom.com>
* Gary Zambrano <zambrano@broadcom.com>
*
* Copyright (c) 2013-2015 Brocade Communications Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Broadcom Corporation nor the name of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written consent.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ECORE_INIT_H
#define ECORE_INIT_H
/* Init operation types and structures */
enum {
OP_RD = 0x1, /* read a single register */
OP_WR, /* write a single register */
OP_SW, /* copy a string to the device */
OP_ZR, /* clear memory */
OP_ZP, /* unzip then copy with DMAE */
OP_WR_64, /* write 64 bit pattern */
OP_WB, /* copy a string using DMAE */
OP_WB_ZR, /* Clear a string using DMAE or indirect-wr */
OP_IF_MODE_OR, /* Skip the following ops if all init modes don't match */
OP_IF_MODE_AND, /* Skip the following ops if any init modes don't match */
OP_IF_PHASE,
OP_RT,
OP_DELAY,
OP_VERIFY,
OP_MAX
};
enum {
STAGE_START,
STAGE_END,
};
/* Returns the index of start or end of a specific block stage in ops array*/
#define BLOCK_OPS_IDX(block, stage, end) \
(2*(((block)*NUM_OF_INIT_PHASES) + (stage)) + (end))
/* structs for the various opcodes */
struct raw_op {
uint32_t op:8;
uint32_t offset:24;
uint32_t raw_data;
};
struct op_read {
uint32_t op:8;
uint32_t offset:24;
uint32_t val;
};
struct op_write {
uint32_t op:8;
uint32_t offset:24;
uint32_t val;
};
struct op_arr_write {
uint32_t op:8;
uint32_t offset:24;
#ifdef __BIG_ENDIAN
uint16_t data_len;
uint16_t data_off;
#else /* __LITTLE_ENDIAN */
uint16_t data_off;
uint16_t data_len;
#endif
};
struct op_zero {
uint32_t op:8;
uint32_t offset:24;
uint32_t len;
};
struct op_if_mode {
uint32_t op:8;
uint32_t cmd_offset:24;
uint32_t mode_bit_map;
};
struct op_if_phase {
uint32_t op:8;
uint32_t cmd_offset:24;
uint32_t phase_bit_map;
};
struct op_delay {
uint32_t op:8;
uint32_t reserved:24;
uint32_t delay;
};
union init_op {
struct op_read read;
struct op_write write;
struct op_arr_write arr_wr;
struct op_zero zero;
struct raw_op raw;
struct op_if_mode if_mode;
struct op_if_phase if_phase;
struct op_delay delay;
};
/* Init Phases */
enum {
PHASE_COMMON,
PHASE_PORT0,
PHASE_PORT1,
PHASE_PF0,
PHASE_PF1,
PHASE_PF2,
PHASE_PF3,
PHASE_PF4,
PHASE_PF5,
PHASE_PF6,
PHASE_PF7,
NUM_OF_INIT_PHASES
};
/* Init Modes */
enum {
MODE_ASIC = 0x00000001,
MODE_FPGA = 0x00000002,
MODE_EMUL = 0x00000004,
MODE_E2 = 0x00000008,
MODE_E3 = 0x00000010,
MODE_PORT2 = 0x00000020,
MODE_PORT4 = 0x00000040,
MODE_SF = 0x00000080,
MODE_MF = 0x00000100,
MODE_MF_SD = 0x00000200,
MODE_MF_SI = 0x00000400,
MODE_MF_AFEX = 0x00000800,
MODE_E3_A0 = 0x00001000,
MODE_E3_B0 = 0x00002000,
MODE_COS3 = 0x00004000,
MODE_COS6 = 0x00008000,
MODE_LITTLE_ENDIAN = 0x00010000,
MODE_BIG_ENDIAN = 0x00020000,
};
/* Init Blocks */
enum {
BLOCK_ATC,
BLOCK_BRB1,
BLOCK_CCM,
BLOCK_CDU,
BLOCK_CFC,
BLOCK_CSDM,
BLOCK_CSEM,
BLOCK_DBG,
BLOCK_DMAE,
BLOCK_DORQ,
BLOCK_HC,
BLOCK_IGU,
BLOCK_MISC,
BLOCK_NIG,
BLOCK_PBF,
BLOCK_PGLUE_B,
BLOCK_PRS,
BLOCK_PXP2,
BLOCK_PXP,
BLOCK_QM,
BLOCK_SRC,
BLOCK_TCM,
BLOCK_TM,
BLOCK_TSDM,
BLOCK_TSEM,
BLOCK_UCM,
BLOCK_UPB,
BLOCK_USDM,
BLOCK_USEM,
BLOCK_XCM,
BLOCK_XPB,
BLOCK_XSDM,
BLOCK_XSEM,
BLOCK_MISC_AEU,
NUM_OF_INIT_BLOCKS
};
/* Vnics per mode */
#define ECORE_PORT2_MODE_NUM_VNICS 4
/* QM queue numbers */
#define ECORE_ETH_Q 0
#define ECORE_TOE_Q 3
#define ECORE_TOE_ACK_Q 6
#define ECORE_ISCSI_Q 9
#define ECORE_ISCSI_ACK_Q 11
#define ECORE_FCOE_Q 10
/* Vnics per mode */
#define ECORE_PORT4_MODE_NUM_VNICS 2
/* COS offset for port1 in E3 B0 4port mode */
#define ECORE_E3B0_PORT1_COS_OFFSET 3
/* QM Register addresses */
#define ECORE_Q_VOQ_REG_ADDR(pf_q_num)\
(QM_REG_QVOQIDX_0 + 4 * (pf_q_num))
#define ECORE_VOQ_Q_REG_ADDR(cos, pf_q_num)\
(QM_REG_VOQQMASK_0_LSB + 4 * ((cos) * 2 + ((pf_q_num) >> 5)))
#define ECORE_Q_CMDQ_REG_ADDR(pf_q_num)\
(QM_REG_BYTECRDCMDQ_0 + 4 * ((pf_q_num) >> 4))
/* extracts the QM queue number for the specified port and vnic */
#define ECORE_PF_Q_NUM(q_num, port, vnic)\
((((port) << 1) | (vnic)) * 16 + (q_num))
/* Maps the specified queue to the specified COS */
static inline void ecore_map_q_cos(struct bnx2x_softc *sc, uint32_t q_num, uint32_t new_cos)
{
/* find current COS mapping */
uint32_t curr_cos = REG_RD(sc, QM_REG_QVOQIDX_0 + q_num * 4);
/* check if queue->COS mapping has changed */
if (curr_cos != new_cos) {
uint32_t num_vnics = ECORE_PORT2_MODE_NUM_VNICS;
uint32_t reg_addr, reg_bit_map, vnic;
/* update parameters for 4port mode */
if (INIT_MODE_FLAGS(sc) & MODE_PORT4) {
num_vnics = ECORE_PORT4_MODE_NUM_VNICS;
if (PORT_ID(sc)) {
curr_cos += ECORE_E3B0_PORT1_COS_OFFSET;
new_cos += ECORE_E3B0_PORT1_COS_OFFSET;
}
}
/* change queue mapping for each VNIC */
for (vnic = 0; vnic < num_vnics; vnic++) {
uint32_t pf_q_num =
ECORE_PF_Q_NUM(q_num, PORT_ID(sc), vnic);
uint32_t q_bit_map = 1 << (pf_q_num & 0x1f);
/* overwrite queue->VOQ mapping */
REG_WR(sc, ECORE_Q_VOQ_REG_ADDR(pf_q_num), new_cos);
/* clear queue bit from current COS bit map */
reg_addr = ECORE_VOQ_Q_REG_ADDR(curr_cos, pf_q_num);
reg_bit_map = REG_RD(sc, reg_addr);
REG_WR(sc, reg_addr, reg_bit_map & (~q_bit_map));
/* set queue bit in new COS bit map */
reg_addr = ECORE_VOQ_Q_REG_ADDR(new_cos, pf_q_num);
reg_bit_map = REG_RD(sc, reg_addr);
REG_WR(sc, reg_addr, reg_bit_map | q_bit_map);
/* set/clear queue bit in command-queue bit map
(E2/E3A0 only, valid COS values are 0/1) */
if (!(INIT_MODE_FLAGS(sc) & MODE_E3_B0)) {
reg_addr = ECORE_Q_CMDQ_REG_ADDR(pf_q_num);
reg_bit_map = REG_RD(sc, reg_addr);
q_bit_map = 1 << (2 * (pf_q_num & 0xf));
reg_bit_map = new_cos ?
(reg_bit_map | q_bit_map) :
(reg_bit_map & (~q_bit_map));
REG_WR(sc, reg_addr, reg_bit_map);
}
}
}
}
/* Configures the QM according to the specified per-traffic-type COSes */
static inline void ecore_dcb_config_qm(struct bnx2x_softc *sc, enum cos_mode mode,
struct priority_cos *traffic_cos)
{
ecore_map_q_cos(sc, ECORE_FCOE_Q,
traffic_cos[LLFC_TRAFFIC_TYPE_FCOE].cos);
ecore_map_q_cos(sc, ECORE_ISCSI_Q,
traffic_cos[LLFC_TRAFFIC_TYPE_ISCSI].cos);
ecore_map_q_cos(sc, ECORE_ISCSI_ACK_Q,
traffic_cos[LLFC_TRAFFIC_TYPE_ISCSI].cos);
if (mode != STATIC_COS) {
/* required only in OVERRIDE_COS mode */
ecore_map_q_cos(sc, ECORE_ETH_Q,
traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos);
ecore_map_q_cos(sc, ECORE_TOE_Q,
traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos);
ecore_map_q_cos(sc, ECORE_TOE_ACK_Q,
traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos);
}
}
/*
* congestion managment port init api description
* the api works as follows:
* the driver should pass the cmng_init_input struct, the port_init function
* will prepare the required internal ram structure which will be passed back
* to the driver (cmng_init) that will write it into the internal ram.
*
* IMPORTANT REMARKS:
* 1. the cmng_init struct does not represent the contiguous internal ram
* structure. the driver should use the XSTORM_CMNG_PERPORT_VARS_OFFSET
* offset in order to write the port sub struct and the
* PFID_FROM_PORT_AND_VNIC offset for writing the vnic sub struct (in other
* words - don't use memcpy!).
* 2. although the cmng_init struct is filled for the maximal vnic number
* possible, the driver should only write the valid vnics into the internal
* ram according to the appropriate port mode.
*/
#define BITS_TO_BYTES(x) ((x)/8)
/* CMNG constants, as derived from system spec calculations */
/* default MIN rate in case VNIC min rate is configured to zero- 100Mbps */
#define DEF_MIN_RATE 100
/* resolution of the rate shaping timer - 400 usec */
#define RS_PERIODIC_TIMEOUT_USEC 400
/*
* number of bytes in single QM arbitration cycle -
* coefficient for calculating the fairness timer
*/
#define QM_ARB_BYTES 160000
/* resolution of Min algorithm 1:100 */
#define MIN_RES 100
/*
* how many bytes above threshold for
* the minimal credit of Min algorithm
*/
#define MIN_ABOVE_THRESH 32768
/*
* Fairness algorithm integration time coefficient -
* for calculating the actual Tfair
*/
#define T_FAIR_COEF ((MIN_ABOVE_THRESH + QM_ARB_BYTES) * 8 * MIN_RES)
/* Memory of fairness algorithm - 2 cycles */
#define FAIR_MEM 2
#define SAFC_TIMEOUT_USEC 52
#define SDM_TICKS 4
static inline void ecore_init_max(const struct cmng_init_input *input_data,
uint32_t r_param, struct cmng_init *ram_data)
{
uint32_t vnic;
struct cmng_vnic *vdata = &ram_data->vnic;
struct cmng_struct_per_port *pdata = &ram_data->port;
/*
* rate shaping per-port variables
* 100 micro seconds in SDM ticks = 25
* since each tick is 4 microSeconds
*/
pdata->rs_vars.rs_periodic_timeout =
RS_PERIODIC_TIMEOUT_USEC / SDM_TICKS;
/* this is the threshold below which no timer arming will occur.
* 1.25 coefficient is for the threshold to be a little bigger
* then the real time to compensate for timer in-accuracy
*/
pdata->rs_vars.rs_threshold =
(5 * RS_PERIODIC_TIMEOUT_USEC * r_param)/4;
/* rate shaping per-vnic variables */
for (vnic = 0; vnic < ECORE_PORT2_MODE_NUM_VNICS; vnic++) {
/* global vnic counter */
vdata->vnic_max_rate[vnic].vn_counter.rate =
input_data->vnic_max_rate[vnic];
/*
* maximal Mbps for this vnic
* the quota in each timer period - number of bytes
* transmitted in this period
*/
vdata->vnic_max_rate[vnic].vn_counter.quota =
RS_PERIODIC_TIMEOUT_USEC *
(uint32_t)vdata->vnic_max_rate[vnic].vn_counter.rate / 8;
}
}
static inline void ecore_init_max_per_vn(uint16_t vnic_max_rate,
struct rate_shaping_vars_per_vn *ram_data)
{
/* global vnic counter */
ram_data->vn_counter.rate = vnic_max_rate;
/*
* maximal Mbps for this vnic
* the quota in each timer period - number of bytes
* transmitted in this period
*/
ram_data->vn_counter.quota =
RS_PERIODIC_TIMEOUT_USEC * (uint32_t)vnic_max_rate / 8;
}
static inline void ecore_init_min(const struct cmng_init_input *input_data,
uint32_t r_param, struct cmng_init *ram_data)
{
uint32_t vnic, fair_periodic_timeout_usec, vnicWeightSum, tFair;
struct cmng_vnic *vdata = &ram_data->vnic;
struct cmng_struct_per_port *pdata = &ram_data->port;
/* this is the resolution of the fairness timer */
fair_periodic_timeout_usec = QM_ARB_BYTES / r_param;
/*
* fairness per-port variables
* for 10G it is 1000usec. for 1G it is 10000usec.
*/
tFair = T_FAIR_COEF / input_data->port_rate;
/* this is the threshold below which we won't arm the timer anymore */
pdata->fair_vars.fair_threshold = QM_ARB_BYTES;
/*
* we multiply by 1e3/8 to get bytes/msec. We don't want the credits
* to pass a credit of the T_FAIR*FAIR_MEM (algorithm resolution)
*/
pdata->fair_vars.upper_bound = r_param * tFair * FAIR_MEM;
/* since each tick is 4 microSeconds */
pdata->fair_vars.fairness_timeout =
fair_periodic_timeout_usec / SDM_TICKS;
/* calculate sum of weights */
vnicWeightSum = 0;
for (vnic = 0; vnic < ECORE_PORT2_MODE_NUM_VNICS; vnic++)
vnicWeightSum += input_data->vnic_min_rate[vnic];
/* global vnic counter */
if (vnicWeightSum > 0) {
/* fairness per-vnic variables */
for (vnic = 0; vnic < ECORE_PORT2_MODE_NUM_VNICS; vnic++) {
/*
* this is the credit for each period of the fairness
* algorithm - number of bytes in T_FAIR (this vnic
* share of the port rate)
*/
vdata->vnic_min_rate[vnic].vn_credit_delta =
((uint32_t)(input_data->vnic_min_rate[vnic]) * 100 *
(T_FAIR_COEF / (8 * 100 * vnicWeightSum)));
if (vdata->vnic_min_rate[vnic].vn_credit_delta <
pdata->fair_vars.fair_threshold +
MIN_ABOVE_THRESH) {
vdata->vnic_min_rate[vnic].vn_credit_delta =
pdata->fair_vars.fair_threshold +
MIN_ABOVE_THRESH;
}
}
}
}
static inline void ecore_init_fw_wrr(const struct cmng_init_input *input_data,
struct cmng_init *ram_data)
{
uint32_t vnic, cos;
uint32_t cosWeightSum = 0;
struct cmng_vnic *vdata = &ram_data->vnic;
struct cmng_struct_per_port *pdata = &ram_data->port;
for (cos = 0; cos < MAX_COS_NUMBER; cos++)
cosWeightSum += input_data->cos_min_rate[cos];
if (cosWeightSum > 0) {
for (vnic = 0; vnic < ECORE_PORT2_MODE_NUM_VNICS; vnic++) {
/*
* Since cos and vnic shouldn't work together the rate
* to divide between the coses is the port rate.
*/
uint32_t *ccd = vdata->vnic_min_rate[vnic].cos_credit_delta;
for (cos = 0; cos < MAX_COS_NUMBER; cos++) {
/*
* this is the credit for each period of
* the fairness algorithm - number of bytes
* in T_FAIR (this cos share of the vnic rate)
*/
ccd[cos] =
((uint32_t)input_data->cos_min_rate[cos] * 100 *
(T_FAIR_COEF / (8 * 100 * cosWeightSum)));
if (ccd[cos] < pdata->fair_vars.fair_threshold
+ MIN_ABOVE_THRESH) {
ccd[cos] =
pdata->fair_vars.fair_threshold +
MIN_ABOVE_THRESH;
}
}
}
}
}
static inline void ecore_init_safc(struct cmng_init *ram_data)
{
/* in microSeconds */
ram_data->port.safc_vars.safc_timeout_usec = SAFC_TIMEOUT_USEC;
}
/* Congestion management port init */
static inline void ecore_init_cmng(const struct cmng_init_input *input_data,
struct cmng_init *ram_data)
{
uint32_t r_param;
ECORE_MEMSET(ram_data, 0,sizeof(struct cmng_init));
ram_data->port.flags = input_data->flags;
/*
* number of bytes transmitted in a rate of 10Gbps
* in one usec = 1.25KB.
*/
r_param = BITS_TO_BYTES(input_data->port_rate);
ecore_init_max(input_data, r_param, ram_data);
ecore_init_min(input_data, r_param, ram_data);
ecore_init_fw_wrr(input_data, ram_data);
ecore_init_safc(ram_data);
}
/* Returns the index of start or end of a specific block stage in ops array*/
#define BLOCK_OPS_IDX(block, stage, end) \
(2*(((block)*NUM_OF_INIT_PHASES) + (stage)) + (end))
#define INITOP_SET 0 /* set the HW directly */
#define INITOP_CLEAR 1 /* clear the HW directly */
#define INITOP_INIT 2 /* set the init-value array */
/****************************************************************************
* ILT management
****************************************************************************/
struct ilt_line {
ecore_dma_addr_t page_mapping;
void *page;
uint32_t size;
};
struct ilt_client_info {
uint32_t page_size;
uint16_t start;
uint16_t end;
uint16_t client_num;
uint16_t flags;
#define ILT_CLIENT_SKIP_INIT 0x1
#define ILT_CLIENT_SKIP_MEM 0x2
};
struct ecore_ilt {
uint32_t start_line;
struct ilt_line *lines;
struct ilt_client_info clients[4];
#define ILT_CLIENT_CDU 0
#define ILT_CLIENT_QM 1
#define ILT_CLIENT_SRC 2
#define ILT_CLIENT_TM 3
};
/****************************************************************************
* SRC configuration
****************************************************************************/
struct src_ent {
uint8_t opaque[56];
uint64_t next;
};
/****************************************************************************
* Parity configuration
****************************************************************************/
#define BLOCK_PRTY_INFO(block, en_mask, m1h, m2, m3) \
{ \
block##_REG_##block##_PRTY_MASK, \
block##_REG_##block##_PRTY_STS_CLR, \
en_mask, {m1h, m2, m3}, #block \
}
#define BLOCK_PRTY_INFO_0(block, en_mask, m1h, m2, m3) \
{ \
block##_REG_##block##_PRTY_MASK_0, \
block##_REG_##block##_PRTY_STS_CLR_0, \
en_mask, {m1h, m2, m3}, #block"_0" \
}
#define BLOCK_PRTY_INFO_1(block, en_mask, m1h, m2, m3) \
{ \
block##_REG_##block##_PRTY_MASK_1, \
block##_REG_##block##_PRTY_STS_CLR_1, \
en_mask, {m1h, m2, m3}, #block"_1" \
}
static const struct {
uint32_t mask_addr;
uint32_t sts_clr_addr;
uint32_t en_mask; /* Mask to enable parity attentions */
struct {
uint32_t e1h; /* 57711 */
uint32_t e2; /* 57712 */
uint32_t e3; /* 578xx */
} reg_mask; /* Register mask (all valid bits) */
char name[8]; /* Block's longest name is 7 characters long
* (name + suffix)
*/
} ecore_blocks_parity_data[] = {
/* bit 19 masked */
/* REG_WR(bp, PXP_REG_PXP_PRTY_MASK, 0x80000); */
/* bit 5,18,20-31 */
/* REG_WR(bp, PXP2_REG_PXP2_PRTY_MASK_0, 0xfff40020); */
/* bit 5 */
/* REG_WR(bp, PXP2_REG_PXP2_PRTY_MASK_1, 0x20); */
/* REG_WR(bp, HC_REG_HC_PRTY_MASK, 0x0); */
/* REG_WR(bp, MISC_REG_MISC_PRTY_MASK, 0x0); */
/* Block IGU, MISC, PXP and PXP2 parity errors as long as we don't
* want to handle "system kill" flow at the moment.
*/
BLOCK_PRTY_INFO(PXP, 0x7ffffff, 0x3ffffff, 0x7ffffff,
0x7ffffff),
BLOCK_PRTY_INFO_0(PXP2, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff),
BLOCK_PRTY_INFO_1(PXP2, 0x1ffffff, 0x7f, 0x7ff, 0x1ffffff),
BLOCK_PRTY_INFO(HC, 0x7, 0x7, 0, 0),
BLOCK_PRTY_INFO(NIG, 0xffffffff, 0xffffffff, 0, 0),
BLOCK_PRTY_INFO_0(NIG, 0xffffffff, 0, 0xffffffff, 0xffffffff),
BLOCK_PRTY_INFO_1(NIG, 0xffff, 0, 0xff, 0xffff),
BLOCK_PRTY_INFO(IGU, 0x7ff, 0, 0x7ff, 0x7ff),
BLOCK_PRTY_INFO(MISC, 0x1, 0x1, 0x1, 0x1),
BLOCK_PRTY_INFO(QM, 0, 0xfff, 0xfff, 0xfff),
BLOCK_PRTY_INFO(ATC, 0x1f, 0, 0x1f, 0x1f),
BLOCK_PRTY_INFO(PGLUE_B, 0x3, 0, 0x3, 0x3),
BLOCK_PRTY_INFO(DORQ, 0, 0x3, 0x3, 0x3),
{GRCBASE_UPB + PB_REG_PB_PRTY_MASK,
GRCBASE_UPB + PB_REG_PB_PRTY_STS_CLR, 0xf,
{0xf, 0xf, 0xf}, "UPB"},
{GRCBASE_XPB + PB_REG_PB_PRTY_MASK,
GRCBASE_XPB + PB_REG_PB_PRTY_STS_CLR, 0,
{0xf, 0xf, 0xf}, "XPB"},
BLOCK_PRTY_INFO(SRC, 0x4, 0x7, 0x7, 0x7),
BLOCK_PRTY_INFO(CDU, 0, 0x1f, 0x1f, 0x1f),
BLOCK_PRTY_INFO(CFC, 0, 0xf, 0xf, 0x3f),
BLOCK_PRTY_INFO(DBG, 0, 0x1, 0x1, 0x1),
BLOCK_PRTY_INFO(DMAE, 0, 0xf, 0xf, 0xf),
BLOCK_PRTY_INFO(BRB1, 0, 0xf, 0xf, 0xf),
BLOCK_PRTY_INFO(PRS, (1<<6), 0xff, 0xff, 0xff),
BLOCK_PRTY_INFO(PBF, 0, 0x3ffff, 0xfffff, 0xfffffff),
BLOCK_PRTY_INFO(TM, 0, 0x7f, 0x7f, 0x7f),
BLOCK_PRTY_INFO(TSDM, 0x18, 0x7ff, 0x7ff, 0x7ff),
BLOCK_PRTY_INFO(CSDM, 0x8, 0x7ff, 0x7ff, 0x7ff),
BLOCK_PRTY_INFO(USDM, 0x38, 0x7ff, 0x7ff, 0x7ff),
BLOCK_PRTY_INFO(XSDM, 0x8, 0x7ff, 0x7ff, 0x7ff),
BLOCK_PRTY_INFO(TCM, 0, 0x7ffffff, 0x7ffffff, 0x7ffffff),
BLOCK_PRTY_INFO(CCM, 0, 0x7ffffff, 0x7ffffff, 0x7ffffff),
BLOCK_PRTY_INFO(UCM, 0, 0x7ffffff, 0x7ffffff, 0x7ffffff),
BLOCK_PRTY_INFO(XCM, 0, 0x3fffffff, 0x3fffffff, 0x3fffffff),
BLOCK_PRTY_INFO_0(TSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff),
BLOCK_PRTY_INFO_1(TSEM, 0, 0x1f, 0x3f, 0x3f),
BLOCK_PRTY_INFO_0(USEM, 0, 0xffffffff, 0xffffffff, 0xffffffff),
BLOCK_PRTY_INFO_1(USEM, 0, 0x1f, 0x1f, 0x1f),
BLOCK_PRTY_INFO_0(CSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff),
BLOCK_PRTY_INFO_1(CSEM, 0, 0x1f, 0x1f, 0x1f),
BLOCK_PRTY_INFO_0(XSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff),
BLOCK_PRTY_INFO_1(XSEM, 0, 0x1f, 0x3f, 0x3f),
};
/* [28] MCP Latched rom_parity
* [29] MCP Latched ump_rx_parity
* [30] MCP Latched ump_tx_parity
* [31] MCP Latched scpad_parity
*/
#define MISC_AEU_ENABLE_MCP_PRTY_BITS \
(AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY | \
AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY | \
AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY | \
AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY)
/* Below registers control the MCP parity attention output. When
* MISC_AEU_ENABLE_MCP_PRTY_BITS are set - attentions are
* enabled, when cleared - disabled.
*/
static const uint32_t mcp_attn_ctl_regs[] = {
MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0,
MISC_REG_AEU_ENABLE4_NIG_0,
MISC_REG_AEU_ENABLE4_PXP_0,
MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0,
MISC_REG_AEU_ENABLE4_NIG_1,
MISC_REG_AEU_ENABLE4_PXP_1
};
static inline void ecore_set_mcp_parity(struct bnx2x_softc *sc, uint8_t enable)
{
uint32_t i;
uint32_t reg_val;
for (i = 0; i < ARRSIZE(mcp_attn_ctl_regs); i++) {
reg_val = REG_RD(sc, mcp_attn_ctl_regs[i]);
if (enable)
reg_val |= MISC_AEU_ENABLE_MCP_PRTY_BITS;
else
reg_val &= ~MISC_AEU_ENABLE_MCP_PRTY_BITS;
REG_WR(sc, mcp_attn_ctl_regs[i], reg_val);
}
}
static inline uint32_t ecore_parity_reg_mask(struct bnx2x_softc *sc, int idx)
{
if (CHIP_IS_E1H(sc))
return ecore_blocks_parity_data[idx].reg_mask.e1h;
else if (CHIP_IS_E2(sc))
return ecore_blocks_parity_data[idx].reg_mask.e2;
else /* CHIP_IS_E3 */
return ecore_blocks_parity_data[idx].reg_mask.e3;
}
static inline void ecore_disable_blocks_parity(struct bnx2x_softc *sc)
{
uint32_t i;
for (i = 0; i < ARRSIZE(ecore_blocks_parity_data); i++) {
uint32_t dis_mask = ecore_parity_reg_mask(sc, i);
if (dis_mask) {
REG_WR(sc, ecore_blocks_parity_data[i].mask_addr,
dis_mask);
ECORE_MSG("Setting parity mask "
"for %s to\t\t0x%x",
ecore_blocks_parity_data[i].name, dis_mask);
}
}
/* Disable MCP parity attentions */
ecore_set_mcp_parity(sc, FALSE);
}
/**
* Clear the parity error status registers.
*/
static inline void ecore_clear_blocks_parity(struct bnx2x_softc *sc)
{
uint32_t i;
uint32_t reg_val, mcp_aeu_bits =
AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY |
AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY |
AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY |
AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY;
/* Clear SEM_FAST parities */
REG_WR(sc, XSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1);
REG_WR(sc, TSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1);
REG_WR(sc, USEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1);
REG_WR(sc, CSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1);
for (i = 0; i < ARRSIZE(ecore_blocks_parity_data); i++) {
uint32_t reg_mask = ecore_parity_reg_mask(sc, i);
if (reg_mask) {
reg_val = REG_RD(sc, ecore_blocks_parity_data[i].
sts_clr_addr);
if (reg_val & reg_mask)
ECORE_MSG(sc,
"Parity errors in %s: 0x%x",
ecore_blocks_parity_data[i].name,
reg_val & reg_mask);
}
}
/* Check if there were parity attentions in MCP */
reg_val = REG_RD(sc, MISC_REG_AEU_AFTER_INVERT_4_MCP);
if (reg_val & mcp_aeu_bits)
ECORE_MSG("Parity error in MCP: 0x%x",
reg_val & mcp_aeu_bits);
/* Clear parity attentions in MCP:
* [7] clears Latched rom_parity
* [8] clears Latched ump_rx_parity
* [9] clears Latched ump_tx_parity
* [10] clears Latched scpad_parity (both ports)
*/
REG_WR(sc, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0x780);
}
static inline void ecore_enable_blocks_parity(struct bnx2x_softc *sc)
{
uint32_t i;
for (i = 0; i < ARRSIZE(ecore_blocks_parity_data); i++) {
uint32_t reg_mask = ecore_parity_reg_mask(sc, i);
if (reg_mask)
REG_WR(sc, ecore_blocks_parity_data[i].mask_addr,
ecore_blocks_parity_data[i].en_mask & reg_mask);
}
/* Enable MCP parity attentions */
ecore_set_mcp_parity(sc, TRUE);
}
#endif /* ECORE_INIT_H */

View File

@ -0,0 +1,886 @@
/*-
* Copyright (c) 2007-2013 QLogic Corporation. All rights reserved.
*
* Eric Davis <edavis@broadcom.com>
* David Christensen <davidch@broadcom.com>
* Gary Zambrano <zambrano@broadcom.com>
*
* Copyright (c) 2013-2015 Brocade Communications Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Broadcom Corporation nor the name of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written consent.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ECORE_INIT_OPS_H
#define ECORE_INIT_OPS_H
static int ecore_gunzip(struct bnx2x_softc *sc, const uint8_t *zbuf, int len);
static void ecore_write_dmae_phys_len(struct bnx2x_softc *sc,
ecore_dma_addr_t phys_addr, uint32_t addr,
uint32_t len);
static void ecore_init_str_wr(struct bnx2x_softc *sc, uint32_t addr,
const uint32_t *data, uint32_t len)
{
uint32_t i;
for (i = 0; i < len; i++)
REG_WR(sc, addr + i*4, data[i]);
}
static void ecore_write_big_buf(struct bnx2x_softc *sc, uint32_t addr, uint32_t len)
{
if (DMAE_READY(sc))
ecore_write_dmae_phys_len(sc, GUNZIP_PHYS(sc), addr, len);
else ecore_init_str_wr(sc, addr, GUNZIP_BUF(sc), len);
}
static void ecore_init_fill(struct bnx2x_softc *sc, uint32_t addr, int fill,
uint32_t len)
{
uint32_t buf_len = (((len*4) > FW_BUF_SIZE) ? FW_BUF_SIZE : (len*4));
uint32_t buf_len32 = buf_len/4;
uint32_t i;
ECORE_MEMSET(GUNZIP_BUF(sc), (uint8_t)fill, buf_len);
for (i = 0; i < len; i += buf_len32) {
uint32_t cur_len = min(buf_len32, len - i);
ecore_write_big_buf(sc, addr + i*4, cur_len);
}
}
static void ecore_write_big_buf_wb(struct bnx2x_softc *sc, uint32_t addr, uint32_t len)
{
if (DMAE_READY(sc))
ecore_write_dmae_phys_len(sc, GUNZIP_PHYS(sc), addr, len);
else ecore_init_str_wr(sc, addr, GUNZIP_BUF(sc), len);
}
static void ecore_init_wr_64(struct bnx2x_softc *sc, uint32_t addr,
const uint32_t *data, uint32_t len64)
{
uint32_t buf_len32 = FW_BUF_SIZE/4;
uint32_t len = len64*2;
uint64_t data64 = 0;
uint32_t i;
/* 64 bit value is in a blob: first low DWORD, then high DWORD */
data64 = HILO_U64((*(data + 1)), (*data));
len64 = min((uint32_t)(FW_BUF_SIZE/8), len64);
for (i = 0; i < len64; i++) {
uint64_t *pdata = ((uint64_t *)(GUNZIP_BUF(sc))) + i;
*pdata = data64;
}
for (i = 0; i < len; i += buf_len32) {
uint32_t cur_len = min(buf_len32, len - i);
ecore_write_big_buf_wb(sc, addr + i*4, cur_len);
}
}
/*********************************************************
There are different blobs for each PRAM section.
In addition, each blob write operation is divided into a few operations
in order to decrease the amount of phys. contiguous buffer needed.
Thus, when we select a blob the address may be with some offset
from the beginning of PRAM section.
The same holds for the INT_TABLE sections.
**********************************************************/
#define IF_IS_INT_TABLE_ADDR(base, addr) \
if (((base) <= (addr)) && ((base) + 0x400 >= (addr)))
#define IF_IS_PRAM_ADDR(base, addr) \
if (((base) <= (addr)) && ((base) + 0x40000 >= (addr)))
static const uint8_t *ecore_sel_blob(struct bnx2x_softc *sc, uint32_t addr,
const uint8_t *data)
{
IF_IS_INT_TABLE_ADDR(TSEM_REG_INT_TABLE, addr)
data = INIT_TSEM_INT_TABLE_DATA(sc);
else
IF_IS_INT_TABLE_ADDR(CSEM_REG_INT_TABLE, addr)
data = INIT_CSEM_INT_TABLE_DATA(sc);
else
IF_IS_INT_TABLE_ADDR(USEM_REG_INT_TABLE, addr)
data = INIT_USEM_INT_TABLE_DATA(sc);
else
IF_IS_INT_TABLE_ADDR(XSEM_REG_INT_TABLE, addr)
data = INIT_XSEM_INT_TABLE_DATA(sc);
else
IF_IS_PRAM_ADDR(TSEM_REG_PRAM, addr)
data = INIT_TSEM_PRAM_DATA(sc);
else
IF_IS_PRAM_ADDR(CSEM_REG_PRAM, addr)
data = INIT_CSEM_PRAM_DATA(sc);
else
IF_IS_PRAM_ADDR(USEM_REG_PRAM, addr)
data = INIT_USEM_PRAM_DATA(sc);
else
IF_IS_PRAM_ADDR(XSEM_REG_PRAM, addr)
data = INIT_XSEM_PRAM_DATA(sc);
return data;
}
static void ecore_init_wr_wb(struct bnx2x_softc *sc, uint32_t addr,
const uint32_t *data, uint32_t len)
{
if (DMAE_READY(sc))
VIRT_WR_DMAE_LEN(sc, data, addr, len, 0);
else ecore_init_str_wr(sc, addr, data, len);
}
static void ecore_wr_64(struct bnx2x_softc *sc, uint32_t reg, uint32_t val_lo,
uint32_t val_hi)
{
uint32_t wb_write[2];
wb_write[0] = val_lo;
wb_write[1] = val_hi;
REG_WR_DMAE_LEN(sc, reg, wb_write, 2);
}
static void ecore_init_wr_zp(struct bnx2x_softc *sc, uint32_t addr, uint32_t len,
uint32_t blob_off)
{
const uint8_t *data = NULL;
int rc;
uint32_t i;
data = ecore_sel_blob(sc, addr, data) + blob_off*4;
rc = ecore_gunzip(sc, data, len);
if (rc)
return;
/* gunzip_outlen is in dwords */
len = GUNZIP_OUTLEN(sc);
for (i = 0; i < len; i++)
((uint32_t *)GUNZIP_BUF(sc))[i] = (uint32_t)
ECORE_CPU_TO_LE32(((uint32_t *)GUNZIP_BUF(sc))[i]);
ecore_write_big_buf_wb(sc, addr, len);
}
static void ecore_init_block(struct bnx2x_softc *sc, uint32_t block, uint32_t stage)
{
uint16_t op_start =
INIT_OPS_OFFSETS(sc)[BLOCK_OPS_IDX(block, stage,
STAGE_START)];
uint16_t op_end =
INIT_OPS_OFFSETS(sc)[BLOCK_OPS_IDX(block, stage,
STAGE_END)];
const union init_op *op;
uint32_t op_idx, op_type, addr, len;
const uint32_t *data, *data_base;
/* If empty block */
if (op_start == op_end)
return;
data_base = INIT_DATA(sc);
for (op_idx = op_start; op_idx < op_end; op_idx++) {
op = (const union init_op *)&(INIT_OPS(sc)[op_idx]);
/* Get generic data */
op_type = op->raw.op;
addr = op->raw.offset;
/* Get data that's used for OP_SW, OP_WB, OP_FW, OP_ZP and
* OP_WR64 (we assume that op_arr_write and op_write have the
* same structure).
*/
len = op->arr_wr.data_len;
data = data_base + op->arr_wr.data_off;
switch (op_type) {
case OP_RD:
REG_RD(sc, addr);
break;
case OP_WR:
REG_WR(sc, addr, op->write.val);
break;
case OP_SW:
ecore_init_str_wr(sc, addr, data, len);
break;
case OP_WB:
ecore_init_wr_wb(sc, addr, data, len);
break;
case OP_ZR:
case OP_WB_ZR:
ecore_init_fill(sc, addr, 0, op->zero.len);
break;
case OP_ZP:
ecore_init_wr_zp(sc, addr, len, op->arr_wr.data_off);
break;
case OP_WR_64:
ecore_init_wr_64(sc, addr, data, len);
break;
case OP_IF_MODE_AND:
/* if any of the flags doesn't match, skip the
* conditional block.
*/
if ((INIT_MODE_FLAGS(sc) &
op->if_mode.mode_bit_map) !=
op->if_mode.mode_bit_map)
op_idx += op->if_mode.cmd_offset;
break;
case OP_IF_MODE_OR:
/* if all the flags don't match, skip the conditional
* block.
*/
if ((INIT_MODE_FLAGS(sc) &
op->if_mode.mode_bit_map) == 0)
op_idx += op->if_mode.cmd_offset;
break;
/* the following opcodes are unused at the moment. */
case OP_IF_PHASE:
case OP_RT:
case OP_DELAY:
case OP_VERIFY:
default:
/* Should never get here! */
break;
}
}
}
/****************************************************************************
* PXP Arbiter
****************************************************************************/
/*
* This code configures the PCI read/write arbiter
* which implements a weighted round robin
* between the virtual queues in the chip.
*
* The values were derived for each PCI max payload and max request size.
* since max payload and max request size are only known at run time,
* this is done as a separate init stage.
*/
#define NUM_WR_Q 13
#define NUM_RD_Q 29
#define MAX_RD_ORD 3
#define MAX_WR_ORD 2
/* configuration for one arbiter queue */
struct arb_line {
int l;
int add;
int ubound;
};
/* derived configuration for each read queue for each max request size */
static const struct arb_line read_arb_data[NUM_RD_Q][MAX_RD_ORD + 1] = {
/* 1 */ { {8, 64, 25}, {16, 64, 25}, {32, 64, 25}, {64, 64, 41} },
{ {4, 8, 4}, {4, 8, 4}, {4, 8, 4}, {4, 8, 4} },
{ {4, 3, 3}, {4, 3, 3}, {4, 3, 3}, {4, 3, 3} },
{ {8, 3, 6}, {16, 3, 11}, {16, 3, 11}, {16, 3, 11} },
{ {8, 64, 25}, {16, 64, 25}, {32, 64, 25}, {64, 64, 41} },
{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {64, 3, 41} },
{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {64, 3, 41} },
{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {64, 3, 41} },
{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {64, 3, 41} },
/* 10 */{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
{ {8, 64, 6}, {16, 64, 11}, {32, 64, 21}, {32, 64, 21} },
{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
/* 20 */{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
{ {8, 64, 25}, {16, 64, 41}, {32, 64, 81}, {64, 64, 120} }
};
/* derived configuration for each write queue for each max request size */
static const struct arb_line write_arb_data[NUM_WR_Q][MAX_WR_ORD + 1] = {
/* 1 */ { {4, 6, 3}, {4, 6, 3}, {4, 6, 3} },
{ {4, 2, 3}, {4, 2, 3}, {4, 2, 3} },
{ {8, 2, 6}, {16, 2, 11}, {16, 2, 11} },
{ {8, 2, 6}, {16, 2, 11}, {32, 2, 21} },
{ {8, 2, 6}, {16, 2, 11}, {32, 2, 21} },
{ {8, 2, 6}, {16, 2, 11}, {32, 2, 21} },
{ {8, 64, 25}, {16, 64, 25}, {32, 64, 25} },
{ {8, 2, 6}, {16, 2, 11}, {16, 2, 11} },
{ {8, 2, 6}, {16, 2, 11}, {16, 2, 11} },
/* 10 */{ {8, 9, 6}, {16, 9, 11}, {32, 9, 21} },
{ {8, 47, 19}, {16, 47, 19}, {32, 47, 21} },
{ {8, 9, 6}, {16, 9, 11}, {16, 9, 11} },
{ {8, 64, 25}, {16, 64, 41}, {32, 64, 81} }
};
/* register addresses for read queues */
static const struct arb_line read_arb_addr[NUM_RD_Q-1] = {
/* 1 */ {PXP2_REG_RQ_BW_RD_L0, PXP2_REG_RQ_BW_RD_ADD0,
PXP2_REG_RQ_BW_RD_UBOUND0},
{PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
PXP2_REG_PSWRQ_BW_UB1},
{PXP2_REG_PSWRQ_BW_L2, PXP2_REG_PSWRQ_BW_ADD2,
PXP2_REG_PSWRQ_BW_UB2},
{PXP2_REG_PSWRQ_BW_L3, PXP2_REG_PSWRQ_BW_ADD3,
PXP2_REG_PSWRQ_BW_UB3},
{PXP2_REG_RQ_BW_RD_L4, PXP2_REG_RQ_BW_RD_ADD4,
PXP2_REG_RQ_BW_RD_UBOUND4},
{PXP2_REG_RQ_BW_RD_L5, PXP2_REG_RQ_BW_RD_ADD5,
PXP2_REG_RQ_BW_RD_UBOUND5},
{PXP2_REG_PSWRQ_BW_L6, PXP2_REG_PSWRQ_BW_ADD6,
PXP2_REG_PSWRQ_BW_UB6},
{PXP2_REG_PSWRQ_BW_L7, PXP2_REG_PSWRQ_BW_ADD7,
PXP2_REG_PSWRQ_BW_UB7},
{PXP2_REG_PSWRQ_BW_L8, PXP2_REG_PSWRQ_BW_ADD8,
PXP2_REG_PSWRQ_BW_UB8},
/* 10 */{PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9,
PXP2_REG_PSWRQ_BW_UB9},
{PXP2_REG_PSWRQ_BW_L10, PXP2_REG_PSWRQ_BW_ADD10,
PXP2_REG_PSWRQ_BW_UB10},
{PXP2_REG_PSWRQ_BW_L11, PXP2_REG_PSWRQ_BW_ADD11,
PXP2_REG_PSWRQ_BW_UB11},
{PXP2_REG_RQ_BW_RD_L12, PXP2_REG_RQ_BW_RD_ADD12,
PXP2_REG_RQ_BW_RD_UBOUND12},
{PXP2_REG_RQ_BW_RD_L13, PXP2_REG_RQ_BW_RD_ADD13,
PXP2_REG_RQ_BW_RD_UBOUND13},
{PXP2_REG_RQ_BW_RD_L14, PXP2_REG_RQ_BW_RD_ADD14,
PXP2_REG_RQ_BW_RD_UBOUND14},
{PXP2_REG_RQ_BW_RD_L15, PXP2_REG_RQ_BW_RD_ADD15,
PXP2_REG_RQ_BW_RD_UBOUND15},
{PXP2_REG_RQ_BW_RD_L16, PXP2_REG_RQ_BW_RD_ADD16,
PXP2_REG_RQ_BW_RD_UBOUND16},
{PXP2_REG_RQ_BW_RD_L17, PXP2_REG_RQ_BW_RD_ADD17,
PXP2_REG_RQ_BW_RD_UBOUND17},
{PXP2_REG_RQ_BW_RD_L18, PXP2_REG_RQ_BW_RD_ADD18,
PXP2_REG_RQ_BW_RD_UBOUND18},
/* 20 */{PXP2_REG_RQ_BW_RD_L19, PXP2_REG_RQ_BW_RD_ADD19,
PXP2_REG_RQ_BW_RD_UBOUND19},
{PXP2_REG_RQ_BW_RD_L20, PXP2_REG_RQ_BW_RD_ADD20,
PXP2_REG_RQ_BW_RD_UBOUND20},
{PXP2_REG_RQ_BW_RD_L22, PXP2_REG_RQ_BW_RD_ADD22,
PXP2_REG_RQ_BW_RD_UBOUND22},
{PXP2_REG_RQ_BW_RD_L23, PXP2_REG_RQ_BW_RD_ADD23,
PXP2_REG_RQ_BW_RD_UBOUND23},
{PXP2_REG_RQ_BW_RD_L24, PXP2_REG_RQ_BW_RD_ADD24,
PXP2_REG_RQ_BW_RD_UBOUND24},
{PXP2_REG_RQ_BW_RD_L25, PXP2_REG_RQ_BW_RD_ADD25,
PXP2_REG_RQ_BW_RD_UBOUND25},
{PXP2_REG_RQ_BW_RD_L26, PXP2_REG_RQ_BW_RD_ADD26,
PXP2_REG_RQ_BW_RD_UBOUND26},
{PXP2_REG_RQ_BW_RD_L27, PXP2_REG_RQ_BW_RD_ADD27,
PXP2_REG_RQ_BW_RD_UBOUND27},
{PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28,
PXP2_REG_PSWRQ_BW_UB28}
};
/* register addresses for write queues */
static const struct arb_line write_arb_addr[NUM_WR_Q-1] = {
/* 1 */ {PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
PXP2_REG_PSWRQ_BW_UB1},
{PXP2_REG_PSWRQ_BW_L2, PXP2_REG_PSWRQ_BW_ADD2,
PXP2_REG_PSWRQ_BW_UB2},
{PXP2_REG_PSWRQ_BW_L3, PXP2_REG_PSWRQ_BW_ADD3,
PXP2_REG_PSWRQ_BW_UB3},
{PXP2_REG_PSWRQ_BW_L6, PXP2_REG_PSWRQ_BW_ADD6,
PXP2_REG_PSWRQ_BW_UB6},
{PXP2_REG_PSWRQ_BW_L7, PXP2_REG_PSWRQ_BW_ADD7,
PXP2_REG_PSWRQ_BW_UB7},
{PXP2_REG_PSWRQ_BW_L8, PXP2_REG_PSWRQ_BW_ADD8,
PXP2_REG_PSWRQ_BW_UB8},
{PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9,
PXP2_REG_PSWRQ_BW_UB9},
{PXP2_REG_PSWRQ_BW_L10, PXP2_REG_PSWRQ_BW_ADD10,
PXP2_REG_PSWRQ_BW_UB10},
{PXP2_REG_PSWRQ_BW_L11, PXP2_REG_PSWRQ_BW_ADD11,
PXP2_REG_PSWRQ_BW_UB11},
/* 10 */{PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28,
PXP2_REG_PSWRQ_BW_UB28},
{PXP2_REG_RQ_BW_WR_L29, PXP2_REG_RQ_BW_WR_ADD29,
PXP2_REG_RQ_BW_WR_UBOUND29},
{PXP2_REG_RQ_BW_WR_L30, PXP2_REG_RQ_BW_WR_ADD30,
PXP2_REG_RQ_BW_WR_UBOUND30}
};
static void ecore_init_pxp_arb(struct bnx2x_softc *sc, int r_order,
int w_order)
{
uint32_t val, i;
if (r_order > MAX_RD_ORD) {
ECORE_MSG("read order of %d order adjusted to %d",
r_order, MAX_RD_ORD);
r_order = MAX_RD_ORD;
}
if (w_order > MAX_WR_ORD) {
ECORE_MSG("write order of %d order adjusted to %d",
w_order, MAX_WR_ORD);
w_order = MAX_WR_ORD;
}
if (CHIP_REV_IS_FPGA(sc)) {
ECORE_MSG("write order adjusted to 1 for FPGA");
w_order = 0;
}
ECORE_MSG("read order %d write order %d", r_order, w_order);
for (i = 0; i < NUM_RD_Q-1; i++) {
REG_WR(sc, read_arb_addr[i].l, read_arb_data[i][r_order].l);
REG_WR(sc, read_arb_addr[i].add,
read_arb_data[i][r_order].add);
REG_WR(sc, read_arb_addr[i].ubound,
read_arb_data[i][r_order].ubound);
}
for (i = 0; i < NUM_WR_Q-1; i++) {
if ((write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L29) ||
(write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L30)) {
REG_WR(sc, write_arb_addr[i].l,
write_arb_data[i][w_order].l);
REG_WR(sc, write_arb_addr[i].add,
write_arb_data[i][w_order].add);
REG_WR(sc, write_arb_addr[i].ubound,
write_arb_data[i][w_order].ubound);
} else {
val = REG_RD(sc, write_arb_addr[i].l);
REG_WR(sc, write_arb_addr[i].l,
val | (write_arb_data[i][w_order].l << 10));
val = REG_RD(sc, write_arb_addr[i].add);
REG_WR(sc, write_arb_addr[i].add,
val | (write_arb_data[i][w_order].add << 10));
val = REG_RD(sc, write_arb_addr[i].ubound);
REG_WR(sc, write_arb_addr[i].ubound,
val | (write_arb_data[i][w_order].ubound << 7));
}
}
val = write_arb_data[NUM_WR_Q-1][w_order].add;
val += write_arb_data[NUM_WR_Q-1][w_order].ubound << 10;
val += write_arb_data[NUM_WR_Q-1][w_order].l << 17;
REG_WR(sc, PXP2_REG_PSWRQ_BW_RD, val);
val = read_arb_data[NUM_RD_Q-1][r_order].add;
val += read_arb_data[NUM_RD_Q-1][r_order].ubound << 10;
val += read_arb_data[NUM_RD_Q-1][r_order].l << 17;
REG_WR(sc, PXP2_REG_PSWRQ_BW_WR, val);
REG_WR(sc, PXP2_REG_RQ_WR_MBS0, w_order);
REG_WR(sc, PXP2_REG_RQ_WR_MBS1, w_order);
REG_WR(sc, PXP2_REG_RQ_RD_MBS0, r_order);
REG_WR(sc, PXP2_REG_RQ_RD_MBS1, r_order);
if (CHIP_IS_E1H(sc) && (r_order == MAX_RD_ORD))
REG_WR(sc, PXP2_REG_RQ_PDR_LIMIT, 0xe00);
if (CHIP_IS_E3(sc))
REG_WR(sc, PXP2_REG_WR_USDMDP_TH, (0x4 << w_order));
else if (CHIP_IS_E2(sc))
REG_WR(sc, PXP2_REG_WR_USDMDP_TH, (0x8 << w_order));
else
REG_WR(sc, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order));
/* MPS w_order optimal TH presently TH
* 128 0 0 2
* 256 1 1 3
* >=512 2 2 3
*/
/* DMAE is special */
if (!CHIP_IS_E1H(sc)) {
/* E2 can use optimal TH */
val = w_order;
REG_WR(sc, PXP2_REG_WR_DMAE_MPS, val);
} else {
val = ((w_order == 0) ? 2 : 3);
REG_WR(sc, PXP2_REG_WR_DMAE_MPS, 2);
}
REG_WR(sc, PXP2_REG_WR_HC_MPS, val);
REG_WR(sc, PXP2_REG_WR_USDM_MPS, val);
REG_WR(sc, PXP2_REG_WR_CSDM_MPS, val);
REG_WR(sc, PXP2_REG_WR_TSDM_MPS, val);
REG_WR(sc, PXP2_REG_WR_XSDM_MPS, val);
REG_WR(sc, PXP2_REG_WR_QM_MPS, val);
REG_WR(sc, PXP2_REG_WR_TM_MPS, val);
REG_WR(sc, PXP2_REG_WR_SRC_MPS, val);
REG_WR(sc, PXP2_REG_WR_DBG_MPS, val);
REG_WR(sc, PXP2_REG_WR_CDU_MPS, val);
/* Validate number of tags suppoted by device */
#define PCIE_REG_PCIER_TL_HDR_FC_ST 0x2980
val = REG_RD(sc, PCIE_REG_PCIER_TL_HDR_FC_ST);
val &= 0xFF;
if (val <= 0x20)
REG_WR(sc, PXP2_REG_PGL_TAGS_LIMIT, 0x20);
}
/****************************************************************************
* ILT management
****************************************************************************/
/*
* This codes hides the low level HW interaction for ILT management and
* configuration. The API consists of a shadow ILT table which is set by the
* driver and a set of routines to use it to configure the HW.
*
*/
/* ILT HW init operations */
/* ILT memory management operations */
#define ILT_MEMOP_ALLOC 0
#define ILT_MEMOP_FREE 1
/* the phys address is shifted right 12 bits and has an added
* 1=valid bit added to the 53rd bit
* then since this is a wide register(TM)
* we split it into two 32 bit writes
*/
#define ILT_ADDR1(x) ((uint32_t)(((uint64_t)x >> 12) & 0xFFFFFFFF))
#define ILT_ADDR2(x) ((uint32_t)((1 << 20) | ((uint64_t)x >> 44)))
#define ILT_RANGE(f, l) (((l) << 10) | f)
static int ecore_ilt_line_mem_op(struct bnx2x_softc *sc,
struct ilt_line *line, uint32_t size, uint8_t memop, int cli_num, int i)
{
#define ECORE_ILT_NAMESIZE 10
char str[ECORE_ILT_NAMESIZE];
if (memop == ILT_MEMOP_FREE) {
ECORE_ILT_FREE(line->page, line->page_mapping, line->size);
return 0;
}
snprintf(str, ECORE_ILT_NAMESIZE, "ILT_%d_%d", cli_num, i);
ECORE_ILT_ZALLOC(line->page, &line->page_mapping, size, str);
if (!line->page)
return -1;
line->size = size;
return 0;
}
static int ecore_ilt_client_mem_op(struct bnx2x_softc *sc, int cli_num,
uint8_t memop)
{
int i, rc = 0;
struct ecore_ilt *ilt = SC_ILT(sc);
struct ilt_client_info *ilt_cli = &ilt->clients[cli_num];
if (!ilt || !ilt->lines)
return -1;
if (ilt_cli->flags & (ILT_CLIENT_SKIP_INIT | ILT_CLIENT_SKIP_MEM))
return 0;
for (i = ilt_cli->start; i <= ilt_cli->end && !rc; i++) {
rc = ecore_ilt_line_mem_op(sc, &ilt->lines[i],
ilt_cli->page_size, memop, cli_num, i);
}
return rc;
}
static inline int ecore_ilt_mem_op_cnic(struct bnx2x_softc *sc, uint8_t memop)
{
int rc = 0;
if (CONFIGURE_NIC_MODE(sc))
rc = ecore_ilt_client_mem_op(sc, ILT_CLIENT_SRC, memop);
if (!rc)
rc = ecore_ilt_client_mem_op(sc, ILT_CLIENT_TM, memop);
return rc;
}
static int ecore_ilt_mem_op(struct bnx2x_softc *sc, uint8_t memop)
{
int rc = ecore_ilt_client_mem_op(sc, ILT_CLIENT_CDU, memop);
if (!rc)
rc = ecore_ilt_client_mem_op(sc, ILT_CLIENT_QM, memop);
if (!rc && CNIC_SUPPORT(sc) && !CONFIGURE_NIC_MODE(sc))
rc = ecore_ilt_client_mem_op(sc, ILT_CLIENT_SRC, memop);
return rc;
}
static void ecore_ilt_line_wr(struct bnx2x_softc *sc, int abs_idx,
ecore_dma_addr_t page_mapping)
{
uint32_t reg;
reg = PXP2_REG_RQ_ONCHIP_AT_B0 + abs_idx*8;
ecore_wr_64(sc, reg, ILT_ADDR1(page_mapping), ILT_ADDR2(page_mapping));
}
static void ecore_ilt_line_init_op(struct bnx2x_softc *sc,
struct ecore_ilt *ilt, int idx, uint8_t initop)
{
ecore_dma_addr_t null_mapping;
int abs_idx = ilt->start_line + idx;
switch (initop) {
case INITOP_INIT:
/* set in the init-value array */
case INITOP_SET:
ecore_ilt_line_wr(sc, abs_idx, ilt->lines[idx].page_mapping);
break;
case INITOP_CLEAR:
null_mapping = 0;
ecore_ilt_line_wr(sc, abs_idx, null_mapping);
break;
}
}
static void ecore_ilt_boundry_init_op(struct bnx2x_softc *sc,
struct ilt_client_info *ilt_cli,
uint32_t ilt_start)
{
uint32_t start_reg = 0;
uint32_t end_reg = 0;
/* The boundary is either SET or INIT,
CLEAR => SET and for now SET ~~ INIT */
/* find the appropriate regs */
switch (ilt_cli->client_num) {
case ILT_CLIENT_CDU:
start_reg = PXP2_REG_RQ_CDU_FIRST_ILT;
end_reg = PXP2_REG_RQ_CDU_LAST_ILT;
break;
case ILT_CLIENT_QM:
start_reg = PXP2_REG_RQ_QM_FIRST_ILT;
end_reg = PXP2_REG_RQ_QM_LAST_ILT;
break;
case ILT_CLIENT_SRC:
start_reg = PXP2_REG_RQ_SRC_FIRST_ILT;
end_reg = PXP2_REG_RQ_SRC_LAST_ILT;
break;
case ILT_CLIENT_TM:
start_reg = PXP2_REG_RQ_TM_FIRST_ILT;
end_reg = PXP2_REG_RQ_TM_LAST_ILT;
break;
}
REG_WR(sc, start_reg, (ilt_start + ilt_cli->start));
REG_WR(sc, end_reg, (ilt_start + ilt_cli->end));
}
static void ecore_ilt_client_init_op_ilt(struct bnx2x_softc *sc,
struct ecore_ilt *ilt,
struct ilt_client_info *ilt_cli,
uint8_t initop)
{
int i;
if (ilt_cli->flags & ILT_CLIENT_SKIP_INIT)
return;
for (i = ilt_cli->start; i <= ilt_cli->end; i++)
ecore_ilt_line_init_op(sc, ilt, i, initop);
/* init/clear the ILT boundries */
ecore_ilt_boundry_init_op(sc, ilt_cli, ilt->start_line);
}
static void ecore_ilt_client_init_op(struct bnx2x_softc *sc,
struct ilt_client_info *ilt_cli, uint8_t initop)
{
struct ecore_ilt *ilt = SC_ILT(sc);
ecore_ilt_client_init_op_ilt(sc, ilt, ilt_cli, initop);
}
static void ecore_ilt_client_id_init_op(struct bnx2x_softc *sc,
int cli_num, uint8_t initop)
{
struct ecore_ilt *ilt = SC_ILT(sc);
struct ilt_client_info *ilt_cli = &ilt->clients[cli_num];
ecore_ilt_client_init_op(sc, ilt_cli, initop);
}
static inline void ecore_ilt_init_op_cnic(struct bnx2x_softc *sc, uint8_t initop)
{
if (CONFIGURE_NIC_MODE(sc))
ecore_ilt_client_id_init_op(sc, ILT_CLIENT_SRC, initop);
ecore_ilt_client_id_init_op(sc, ILT_CLIENT_TM, initop);
}
static void ecore_ilt_init_op(struct bnx2x_softc *sc, uint8_t initop)
{
ecore_ilt_client_id_init_op(sc, ILT_CLIENT_CDU, initop);
ecore_ilt_client_id_init_op(sc, ILT_CLIENT_QM, initop);
if (CNIC_SUPPORT(sc) && !CONFIGURE_NIC_MODE(sc))
ecore_ilt_client_id_init_op(sc, ILT_CLIENT_SRC, initop);
}
static void ecore_ilt_init_client_psz(struct bnx2x_softc *sc, int cli_num,
uint32_t psz_reg, uint8_t initop)
{
struct ecore_ilt *ilt = SC_ILT(sc);
struct ilt_client_info *ilt_cli = &ilt->clients[cli_num];
if (ilt_cli->flags & ILT_CLIENT_SKIP_INIT)
return;
switch (initop) {
case INITOP_INIT:
/* set in the init-value array */
case INITOP_SET:
REG_WR(sc, psz_reg, ILOG2(ilt_cli->page_size >> 12));
break;
case INITOP_CLEAR:
break;
}
}
/*
* called during init common stage, ilt clients should be initialized
* prioir to calling this function
*/
static void ecore_ilt_init_page_size(struct bnx2x_softc *sc, uint8_t initop)
{
ecore_ilt_init_client_psz(sc, ILT_CLIENT_CDU,
PXP2_REG_RQ_CDU_P_SIZE, initop);
ecore_ilt_init_client_psz(sc, ILT_CLIENT_QM,
PXP2_REG_RQ_QM_P_SIZE, initop);
ecore_ilt_init_client_psz(sc, ILT_CLIENT_SRC,
PXP2_REG_RQ_SRC_P_SIZE, initop);
ecore_ilt_init_client_psz(sc, ILT_CLIENT_TM,
PXP2_REG_RQ_TM_P_SIZE, initop);
}
/****************************************************************************
* QM initializations
****************************************************************************/
#define QM_QUEUES_PER_FUNC 16
#define QM_INIT_MIN_CID_COUNT 31
#define QM_INIT(cid_cnt) (cid_cnt > QM_INIT_MIN_CID_COUNT)
/* called during init port stage */
static void ecore_qm_init_cid_count(struct bnx2x_softc *sc, int qm_cid_count,
uint8_t initop)
{
int port = SC_PORT(sc);
if (QM_INIT(qm_cid_count)) {
switch (initop) {
case INITOP_INIT:
/* set in the init-value array */
case INITOP_SET:
REG_WR(sc, QM_REG_CONNNUM_0 + port*4,
qm_cid_count/16 - 1);
break;
case INITOP_CLEAR:
break;
}
}
}
static void ecore_qm_set_ptr_table(struct bnx2x_softc *sc, int qm_cid_count,
uint32_t base_reg, uint32_t reg)
{
int i;
uint32_t wb_data[2] = {0, 0};
for (i = 0; i < 4 * QM_QUEUES_PER_FUNC; i++) {
REG_WR(sc, base_reg + i*4,
qm_cid_count * 4 * (i % QM_QUEUES_PER_FUNC));
ecore_init_wr_wb(sc, reg + i*8,
wb_data, 2);
}
}
/* called during init common stage */
static void ecore_qm_init_ptr_table(struct bnx2x_softc *sc, int qm_cid_count,
uint8_t initop)
{
if (!QM_INIT(qm_cid_count))
return;
switch (initop) {
case INITOP_INIT:
/* set in the init-value array */
case INITOP_SET:
ecore_qm_set_ptr_table(sc, qm_cid_count,
QM_REG_BASEADDR, QM_REG_PTRTBL);
if (CHIP_IS_E1H(sc))
ecore_qm_set_ptr_table(sc, qm_cid_count,
QM_REG_BASEADDR_EXT_A,
QM_REG_PTRTBL_EXT_A);
break;
case INITOP_CLEAR:
break;
}
}
/****************************************************************************
* SRC initializations
****************************************************************************/
#ifdef ECORE_L5
/* called during init func stage */
static void ecore_src_init_t2(struct bnx2x_softc *sc, struct src_ent *t2,
ecore_dma_addr_t t2_mapping, int src_cid_count)
{
int i;
int port = SC_PORT(sc);
/* Initialize T2 */
for (i = 0; i < src_cid_count-1; i++)
t2[i].next = (uint64_t)(t2_mapping +
(i+1)*sizeof(struct src_ent));
/* tell the searcher where the T2 table is */
REG_WR(sc, SRC_REG_COUNTFREE0 + port*4, src_cid_count);
ecore_wr_64(sc, SRC_REG_FIRSTFREE0 + port*16,
U64_LO(t2_mapping), U64_HI(t2_mapping));
ecore_wr_64(sc, SRC_REG_LASTFREE0 + port*16,
U64_LO((uint64_t)t2_mapping +
(src_cid_count-1) * sizeof(struct src_ent)),
U64_HI((uint64_t)t2_mapping +
(src_cid_count-1) * sizeof(struct src_ent)));
}
#endif
#endif /* ECORE_INIT_OPS_H */

View File

@ -0,0 +1,206 @@
/*-
* Copyright (c) 2007-2013 QLogic Corporation. All rights reserved.
*
* Eric Davis <edavis@broadcom.com>
* David Christensen <davidch@broadcom.com>
* Gary Zambrano <zambrano@broadcom.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Broadcom Corporation nor the name of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written consent.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ECORE_MFW_REQ_H
#define ECORE_MFW_REQ_H
#define PORT_0 0
#define PORT_1 1
#define PORT_MAX 2
#define NVM_PATH_MAX 2
/* FCoE capabilities required from the driver */
struct fcoe_capabilities {
uint32_t capability1;
/* Maximum number of I/Os per connection */
#define FCOE_IOS_PER_CONNECTION_MASK 0x0000ffff
#define FCOE_IOS_PER_CONNECTION_SHIFT 0
/* Maximum number of Logins per port */
#define FCOE_LOGINS_PER_PORT_MASK 0xffff0000
#define FCOE_LOGINS_PER_PORT_SHIFT 16
uint32_t capability2;
/* Maximum number of exchanges */
#define FCOE_NUMBER_OF_EXCHANGES_MASK 0x0000ffff
#define FCOE_NUMBER_OF_EXCHANGES_SHIFT 0
/* Maximum NPIV WWN per port */
#define FCOE_NPIV_WWN_PER_PORT_MASK 0xffff0000
#define FCOE_NPIV_WWN_PER_PORT_SHIFT 16
uint32_t capability3;
/* Maximum number of targets supported */
#define FCOE_TARGETS_SUPPORTED_MASK 0x0000ffff
#define FCOE_TARGETS_SUPPORTED_SHIFT 0
/* Maximum number of outstanding commands across all connections */
#define FCOE_OUTSTANDING_COMMANDS_MASK 0xffff0000
#define FCOE_OUTSTANDING_COMMANDS_SHIFT 16
uint32_t capability4;
#define FCOE_CAPABILITY4_STATEFUL 0x00000001
#define FCOE_CAPABILITY4_STATELESS 0x00000002
#define FCOE_CAPABILITY4_CAPABILITIES_REPORTED_VALID 0x00000004
};
struct glob_ncsi_oem_data
{
uint32_t driver_version;
uint32_t unused[3];
struct fcoe_capabilities fcoe_features[NVM_PATH_MAX][PORT_MAX];
};
/* current drv_info version */
#define DRV_INFO_CUR_VER 2
/* drv_info op codes supported */
enum drv_info_opcode {
ETH_STATS_OPCODE,
FCOE_STATS_OPCODE,
ISCSI_STATS_OPCODE
};
#define ETH_STAT_INFO_VERSION_LEN 12
/* Per PCI Function Ethernet Statistics required from the driver */
struct eth_stats_info {
/* Function's Driver Version. padded to 12 */
char version[ETH_STAT_INFO_VERSION_LEN];
/* Locally Admin Addr. BigEndian EIU48. Actual size is 6 bytes */
uint8_t mac_local[8];
uint8_t mac_add1[8]; /* Additional Programmed MAC Addr 1. */
uint8_t mac_add2[8]; /* Additional Programmed MAC Addr 2. */
uint32_t mtu_size; /* MTU Size. Note : Negotiated MTU */
uint32_t feature_flags; /* Feature_Flags. */
#define FEATURE_ETH_CHKSUM_OFFLOAD_MASK 0x01
#define FEATURE_ETH_LSO_MASK 0x02
#define FEATURE_ETH_BOOTMODE_MASK 0x1C
#define FEATURE_ETH_BOOTMODE_SHIFT 2
#define FEATURE_ETH_BOOTMODE_NONE (0x0 << 2)
#define FEATURE_ETH_BOOTMODE_PXE (0x1 << 2)
#define FEATURE_ETH_BOOTMODE_ISCSI (0x2 << 2)
#define FEATURE_ETH_BOOTMODE_FCOE (0x3 << 2)
#define FEATURE_ETH_TOE_MASK 0x20
uint32_t lso_max_size; /* LSO MaxOffloadSize. */
uint32_t lso_min_seg_cnt; /* LSO MinSegmentCount. */
/* Num Offloaded Connections TCP_IPv4. */
uint32_t ipv4_ofld_cnt;
/* Num Offloaded Connections TCP_IPv6. */
uint32_t ipv6_ofld_cnt;
uint32_t promiscuous_mode; /* Promiscuous Mode. non-zero true */
uint32_t txq_size; /* TX Descriptors Queue Size */
uint32_t rxq_size; /* RX Descriptors Queue Size */
/* TX Descriptor Queue Avg Depth. % Avg Queue Depth since last poll */
uint32_t txq_avg_depth;
/* RX Descriptors Queue Avg Depth. % Avg Queue Depth since last poll */
uint32_t rxq_avg_depth;
/* IOV_Offload. 0=none; 1=MultiQueue, 2=VEB 3= VEPA*/
uint32_t iov_offload;
/* Number of NetQueue/VMQ Config'd. */
uint32_t netq_cnt;
uint32_t vf_cnt; /* Num VF assigned to this PF. */
};
/* Per PCI Function FCOE Statistics required from the driver */
struct fcoe_stats_info {
uint8_t version[12]; /* Function's Driver Version. */
uint8_t mac_local[8]; /* Locally Admin Addr. */
uint8_t mac_add1[8]; /* Additional Programmed MAC Addr 1. */
uint8_t mac_add2[8]; /* Additional Programmed MAC Addr 2. */
/* QoS Priority (per 802.1p). 0-7255 */
uint32_t qos_priority;
uint32_t txq_size; /* FCoE TX Descriptors Queue Size. */
uint32_t rxq_size; /* FCoE RX Descriptors Queue Size. */
/* FCoE TX Descriptor Queue Avg Depth. */
uint32_t txq_avg_depth;
/* FCoE RX Descriptors Queue Avg Depth. */
uint32_t rxq_avg_depth;
uint32_t rx_frames_lo; /* FCoE RX Frames received. */
uint32_t rx_frames_hi; /* FCoE RX Frames received. */
uint32_t rx_bytes_lo; /* FCoE RX Bytes received. */
uint32_t rx_bytes_hi; /* FCoE RX Bytes received. */
uint32_t tx_frames_lo; /* FCoE TX Frames sent. */
uint32_t tx_frames_hi; /* FCoE TX Frames sent. */
uint32_t tx_bytes_lo; /* FCoE TX Bytes sent. */
uint32_t tx_bytes_hi; /* FCoE TX Bytes sent. */
uint32_t rx_fcs_errors; /* number of receive packets with FCS errors */
uint32_t rx_fc_crc_errors; /* number of FC frames with CRC errors*/
uint32_t fip_login_failures; /* number of FCoE/FIP Login failures */
};
/* Per PCI Function iSCSI Statistics required from the driver*/
struct iscsi_stats_info {
uint8_t version[12]; /* Function's Driver Version. */
uint8_t mac_local[8]; /* Locally Admin iSCSI MAC Addr. */
uint8_t mac_add1[8]; /* Additional Programmed MAC Addr 1. */
/* QoS Priority (per 802.1p). 0-7255 */
uint32_t qos_priority;
uint8_t initiator_name[64]; /* iSCSI Boot Initiator Node name. */
uint8_t ww_port_name[64]; /* iSCSI World wide port name */
uint8_t boot_target_name[64];/* iSCSI Boot Target Name. */
uint8_t boot_target_ip[16]; /* iSCSI Boot Target IP. */
uint32_t boot_target_portal; /* iSCSI Boot Target Portal. */
uint8_t boot_init_ip[16]; /* iSCSI Boot Initiator IP Address. */
uint32_t max_frame_size; /* Max Frame Size. bytes */
uint32_t txq_size; /* PDU TX Descriptors Queue Size. */
uint32_t rxq_size; /* PDU RX Descriptors Queue Size. */
uint32_t txq_avg_depth; /*PDU TX Descriptor Queue Avg Depth. */
uint32_t rxq_avg_depth; /*PDU RX Descriptors Queue Avg Depth. */
uint32_t rx_pdus_lo; /* iSCSI PDUs received. */
uint32_t rx_pdus_hi; /* iSCSI PDUs received. */
uint32_t rx_bytes_lo; /* iSCSI RX Bytes received. */
uint32_t rx_bytes_hi; /* iSCSI RX Bytes received. */
uint32_t tx_pdus_lo; /* iSCSI PDUs sent. */
uint32_t tx_pdus_hi; /* iSCSI PDUs sent. */
uint32_t tx_bytes_lo; /* iSCSI PDU TX Bytes sent. */
uint32_t tx_bytes_hi; /* iSCSI PDU TX Bytes sent. */
uint32_t pcp_prior_map_tbl; /*C-PCP to S-PCP Priority MapTable.
9 nibbles, the position of each nibble
represents the C-PCP value, the value
of the nibble = S-PCP value.*/
};
union drv_info_to_mcp {
struct eth_stats_info ether_stat;
struct fcoe_stats_info fcoe_stat;
struct iscsi_stats_info iscsi_stat;
};
#endif /* ECORE_MFW_REQ_H */

File diff suppressed because it is too large Load Diff

5455
drivers/net/bnx2x/ecore_sp.c Normal file

File diff suppressed because it is too large Load Diff

1795
drivers/net/bnx2x/ecore_sp.h Normal file

File diff suppressed because it is too large Load Diff

13378
drivers/net/bnx2x/elink.c Normal file

File diff suppressed because it is too large Load Diff

609
drivers/net/bnx2x/elink.h Normal file
View File

@ -0,0 +1,609 @@
/*-
* Copyright (c) 2007-2013 QLogic Corporation. All rights reserved.
*
* Eric Davis <edavis@broadcom.com>
* David Christensen <davidch@broadcom.com>
* Gary Zambrano <zambrano@broadcom.com>
*
* Copyright (c) 2013-2015 Brocade Communications Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Broadcom Corporation nor the name of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written consent.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ELINK_H
#define ELINK_H
#define ELINK_DEBUG
/***********************************************************/
/* CLC Call backs functions */
/***********************************************************/
/* CLC device structure */
struct bnx2x_softc;
extern uint32_t elink_cb_reg_read(struct bnx2x_softc *sc, uint32_t reg_addr);
extern void elink_cb_reg_write(struct bnx2x_softc *sc, uint32_t reg_addr, uint32_t val);
/* mode - 0( LOW ) /1(HIGH)*/
extern uint8_t elink_cb_gpio_write(struct bnx2x_softc *sc,
uint16_t gpio_num,
uint8_t mode, uint8_t port);
extern uint8_t elink_cb_gpio_mult_write(struct bnx2x_softc *sc,
uint8_t pins,
uint8_t mode);
extern uint32_t elink_cb_gpio_read(struct bnx2x_softc *sc, uint16_t gpio_num, uint8_t port);
extern uint8_t elink_cb_gpio_int_write(struct bnx2x_softc *sc,
uint16_t gpio_num,
uint8_t mode, uint8_t port);
extern uint32_t elink_cb_fw_command(struct bnx2x_softc *sc, uint32_t command, uint32_t param);
/* This function is called every 1024 bytes downloading of phy firmware.
Driver can use it to print to screen indication for download progress */
extern void elink_cb_download_progress(struct bnx2x_softc *sc, uint32_t cur, uint32_t total);
/* Each log type has its own parameters */
typedef enum elink_log_id {
ELINK_LOG_ID_UNQUAL_IO_MODULE = 0, /* uint8_t port, const char* vendor_name, const char* vendor_pn */
ELINK_LOG_ID_OVER_CURRENT = 1, /* uint8_t port */
ELINK_LOG_ID_PHY_UNINITIALIZED = 2, /* uint8_t port */
ELINK_LOG_ID_MDIO_ACCESS_TIMEOUT= 3, /* No params */
ELINK_LOG_ID_NON_10G_MODULE = 4, /* uint8_t port */
}elink_log_id_t;
typedef enum elink_status {
ELINK_STATUS_OK = 0,
ELINK_STATUS_ERROR,
ELINK_STATUS_TIMEOUT,
ELINK_STATUS_NO_LINK,
ELINK_STATUS_INVALID_IMAGE,
ELINK_OP_NOT_SUPPORTED = 122
} elink_status_t;
extern void elink_cb_event_log(struct bnx2x_softc *sc, const elink_log_id_t log_id, ...);
extern void elink_cb_load_warpcore_microcode(void);
extern void elink_cb_notify_link_changed(struct bnx2x_softc *sc);
#define ELINK_EVENT_LOG_LEVEL_ERROR 1
#define ELINK_EVENT_LOG_LEVEL_WARNING 2
#define ELINK_EVENT_ID_SFP_UNQUALIFIED_MODULE 1
#define ELINK_EVENT_ID_SFP_POWER_FAULT 2
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
/* Debug prints */
/***********************************************************/
/* Defines */
/***********************************************************/
#define ELINK_DEFAULT_PHY_DEV_ADDR 3
#define ELINK_E2_DEFAULT_PHY_DEV_ADDR 5
#define DUPLEX_FULL 1
#define DUPLEX_HALF 2
#define ELINK_FLOW_CTRL_AUTO PORT_FEATURE_FLOW_CONTROL_AUTO
#define ELINK_FLOW_CTRL_TX PORT_FEATURE_FLOW_CONTROL_TX
#define ELINK_FLOW_CTRL_RX PORT_FEATURE_FLOW_CONTROL_RX
#define ELINK_FLOW_CTRL_BOTH PORT_FEATURE_FLOW_CONTROL_BOTH
#define ELINK_FLOW_CTRL_NONE PORT_FEATURE_FLOW_CONTROL_NONE
#define ELINK_NET_SERDES_IF_XFI 1
#define ELINK_NET_SERDES_IF_SFI 2
#define ELINK_NET_SERDES_IF_KR 3
#define ELINK_NET_SERDES_IF_DXGXS 4
#define ELINK_SPEED_AUTO_NEG 0
#define ELINK_SPEED_10 10
#define ELINK_SPEED_100 100
#define ELINK_SPEED_1000 1000
#define ELINK_SPEED_2500 2500
#define ELINK_SPEED_10000 10000
#define ELINK_SPEED_20000 20000
#define ELINK_I2C_DEV_ADDR_A0 0xa0
#define ELINK_I2C_DEV_ADDR_A2 0xa2
#define ELINK_SFP_EEPROM_PAGE_SIZE 16
#define ELINK_SFP_EEPROM_VENDOR_NAME_ADDR 0x14
#define ELINK_SFP_EEPROM_VENDOR_NAME_SIZE 16
#define ELINK_SFP_EEPROM_VENDOR_OUI_ADDR 0x25
#define ELINK_SFP_EEPROM_VENDOR_OUI_SIZE 3
#define ELINK_SFP_EEPROM_PART_NO_ADDR 0x28
#define ELINK_SFP_EEPROM_PART_NO_SIZE 16
#define ELINK_SFP_EEPROM_REVISION_ADDR 0x38
#define ELINK_SFP_EEPROM_REVISION_SIZE 4
#define ELINK_SFP_EEPROM_SERIAL_ADDR 0x44
#define ELINK_SFP_EEPROM_SERIAL_SIZE 16
#define ELINK_SFP_EEPROM_DATE_ADDR 0x54 /* ASCII YYMMDD */
#define ELINK_SFP_EEPROM_DATE_SIZE 6
#define ELINK_SFP_EEPROM_DIAG_TYPE_ADDR 0x5c
#define ELINK_SFP_EEPROM_DIAG_TYPE_SIZE 1
#define ELINK_SFP_EEPROM_DIAG_ADDR_CHANGE_REQ (1<<2)
#define ELINK_SFP_EEPROM_SFF_8472_COMP_ADDR 0x5e
#define ELINK_SFP_EEPROM_SFF_8472_COMP_SIZE 1
#define ELINK_SFP_EEPROM_A2_CHECKSUM_RANGE 0x5e
#define ELINK_SFP_EEPROM_A2_CC_DMI_ADDR 0x5f
#define ELINK_PWR_FLT_ERR_MSG_LEN 250
#define ELINK_XGXS_EXT_PHY_TYPE(ext_phy_config) \
((ext_phy_config) & PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK)
#define ELINK_XGXS_EXT_PHY_ADDR(ext_phy_config) \
(((ext_phy_config) & PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> \
PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT)
#define ELINK_SERDES_EXT_PHY_TYPE(ext_phy_config) \
((ext_phy_config) & PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK)
/* Single Media Direct board is the plain 577xx board with CX4/RJ45 jacks */
#define ELINK_SINGLE_MEDIA_DIRECT(params) (params->num_phys == 1)
/* Single Media board contains single external phy */
#define ELINK_SINGLE_MEDIA(params) (params->num_phys == 2)
/* Dual Media board contains two external phy with different media */
#define ELINK_DUAL_MEDIA(params) (params->num_phys == 3)
#define ELINK_FW_PARAM_PHY_ADDR_MASK 0x000000FF
#define ELINK_FW_PARAM_PHY_TYPE_MASK 0x0000FF00
#define ELINK_FW_PARAM_MDIO_CTRL_MASK 0xFFFF0000
#define ELINK_FW_PARAM_MDIO_CTRL_OFFSET 16
#define ELINK_FW_PARAM_PHY_ADDR(fw_param) (fw_param & \
ELINK_FW_PARAM_PHY_ADDR_MASK)
#define ELINK_FW_PARAM_PHY_TYPE(fw_param) (fw_param & \
ELINK_FW_PARAM_PHY_TYPE_MASK)
#define ELINK_FW_PARAM_MDIO_CTRL(fw_param) ((fw_param & \
ELINK_FW_PARAM_MDIO_CTRL_MASK) >> \
ELINK_FW_PARAM_MDIO_CTRL_OFFSET)
#define ELINK_FW_PARAM_SET(phy_addr, phy_type, mdio_access) \
(phy_addr | phy_type | mdio_access << ELINK_FW_PARAM_MDIO_CTRL_OFFSET)
#define ELINK_PFC_BRB_FULL_LB_XOFF_THRESHOLD 170
#define ELINK_PFC_BRB_FULL_LB_XON_THRESHOLD 250
#define ELINK_MAXVAL(a, b) (((a) > (b)) ? (a) : (b))
#define ELINK_BMAC_CONTROL_RX_ENABLE 2
/***********************************************************/
/* Structs */
/***********************************************************/
#define ELINK_INT_PHY 0
#define ELINK_EXT_PHY1 1
#define ELINK_EXT_PHY2 2
#define ELINK_MAX_PHYS 3
/* Same configuration is shared between the XGXS and the first external phy */
#define ELINK_LINK_CONFIG_SIZE (ELINK_MAX_PHYS - 1)
#define ELINK_LINK_CONFIG_IDX(_phy_idx) ((_phy_idx == ELINK_INT_PHY) ? \
0 : (_phy_idx - 1))
/***********************************************************/
/* elink_phy struct */
/* Defines the required arguments and function per phy */
/***********************************************************/
struct elink_vars;
struct elink_params;
struct elink_phy;
typedef uint8_t (*config_init_t)(struct elink_phy *phy, struct elink_params *params,
struct elink_vars *vars);
typedef uint8_t (*read_status_t)(struct elink_phy *phy, struct elink_params *params,
struct elink_vars *vars);
typedef void (*link_reset_t)(struct elink_phy *phy,
struct elink_params *params);
typedef void (*config_loopback_t)(struct elink_phy *phy,
struct elink_params *params);
typedef uint8_t (*format_fw_ver_t)(uint32_t raw, uint8_t *str, uint16_t *len);
typedef void (*hw_reset_t)(struct elink_phy *phy, struct elink_params *params);
typedef void (*set_link_led_t)(struct elink_phy *phy,
struct elink_params *params, uint8_t mode);
typedef void (*phy_specific_func_t)(struct elink_phy *phy,
struct elink_params *params, uint32_t action);
struct elink_reg_set {
uint8_t devad;
uint16_t reg;
uint16_t val;
};
struct elink_phy {
uint32_t type;
/* Loaded during init */
uint8_t addr;
uint8_t def_md_devad;
uint16_t flags;
/* No Over-Current detection */
#define ELINK_FLAGS_NOC (1<<1)
/* Fan failure detection required */
#define ELINK_FLAGS_FAN_FAILURE_DET_REQ (1<<2)
/* Initialize first the XGXS and only then the phy itself */
#define ELINK_FLAGS_INIT_XGXS_FIRST (1<<3)
#define ELINK_FLAGS_WC_DUAL_MODE (1<<4)
#define ELINK_FLAGS_4_PORT_MODE (1<<5)
#define ELINK_FLAGS_REARM_LATCH_SIGNAL (1<<6)
#define ELINK_FLAGS_SFP_NOT_APPROVED (1<<7)
#define ELINK_FLAGS_MDC_MDIO_WA (1<<8)
#define ELINK_FLAGS_DUMMY_READ (1<<9)
#define ELINK_FLAGS_MDC_MDIO_WA_B0 (1<<10)
#define ELINK_FLAGS_SFP_MODULE_PLUGGED_IN_WC (1<<11)
#define ELINK_FLAGS_TX_ERROR_CHECK (1<<12)
#define ELINK_FLAGS_EEE (1<<13)
#define ELINK_FLAGS_TEMPERATURE (1<<14)
#define ELINK_FLAGS_MDC_MDIO_WA_G (1<<15)
/* preemphasis values for the rx side */
uint16_t rx_preemphasis[4];
/* preemphasis values for the tx side */
uint16_t tx_preemphasis[4];
/* EMAC address for access MDIO */
uint32_t mdio_ctrl;
uint32_t supported;
#define ELINK_SUPPORTED_10baseT_Half (1<<0)
#define ELINK_SUPPORTED_10baseT_Full (1<<1)
#define ELINK_SUPPORTED_100baseT_Half (1<<2)
#define ELINK_SUPPORTED_100baseT_Full (1<<3)
#define ELINK_SUPPORTED_1000baseT_Full (1<<4)
#define ELINK_SUPPORTED_2500baseX_Full (1<<5)
#define ELINK_SUPPORTED_10000baseT_Full (1<<6)
#define ELINK_SUPPORTED_TP (1<<7)
#define ELINK_SUPPORTED_FIBRE (1<<8)
#define ELINK_SUPPORTED_Autoneg (1<<9)
#define ELINK_SUPPORTED_Pause (1<<10)
#define ELINK_SUPPORTED_Asym_Pause (1<<11)
#define ELINK_SUPPORTED_20000baseMLD2_Full (1<<21)
#define ELINK_SUPPORTED_20000baseKR2_Full (1<<22)
uint32_t media_type;
#define ELINK_ETH_PHY_UNSPECIFIED 0x0
#define ELINK_ETH_PHY_SFPP_10G_FIBER 0x1
#define ELINK_ETH_PHY_XFP_FIBER 0x2
#define ELINK_ETH_PHY_DA_TWINAX 0x3
#define ELINK_ETH_PHY_BASE_T 0x4
#define ELINK_ETH_PHY_SFP_1G_FIBER 0x5
#define ELINK_ETH_PHY_KR 0xf0
#define ELINK_ETH_PHY_CX4 0xf1
#define ELINK_ETH_PHY_NOT_PRESENT 0xff
/* The address in which version is located*/
uint32_t ver_addr;
uint16_t req_flow_ctrl;
uint16_t req_line_speed;
uint32_t speed_cap_mask;
uint16_t req_duplex;
uint16_t rsrv;
/* Called per phy/port init, and it configures LASI, speed, autoneg,
duplex, flow control negotiation, etc. */
config_init_t config_init;
/* Called due to interrupt. It determines the link, speed */
read_status_t read_status;
/* Called when driver is unloading. Should reset the phy */
link_reset_t link_reset;
/* Set the loopback configuration for the phy */
config_loopback_t config_loopback;
/* Format the given raw number into str up to len */
format_fw_ver_t format_fw_ver;
/* Reset the phy (both ports) */
hw_reset_t hw_reset;
/* Set link led mode (on/off/oper)*/
set_link_led_t set_link_led;
/* PHY Specific tasks */
phy_specific_func_t phy_specific_func;
#define ELINK_DISABLE_TX 1
#define ELINK_ENABLE_TX 2
#define ELINK_PHY_INIT 3
};
/* Inputs parameters to the CLC */
struct elink_params {
uint8_t port;
/* Default / User Configuration */
uint8_t loopback_mode;
#define ELINK_LOOPBACK_NONE 0
#define ELINK_LOOPBACK_EMAC 1
#define ELINK_LOOPBACK_BMAC 2
#define ELINK_LOOPBACK_XGXS 3
#define ELINK_LOOPBACK_EXT_PHY 4
#define ELINK_LOOPBACK_EXT 5
#define ELINK_LOOPBACK_UMAC 6
#define ELINK_LOOPBACK_XMAC 7
/* Device parameters */
uint8_t mac_addr[6];
uint16_t req_duplex[ELINK_LINK_CONFIG_SIZE];
uint16_t req_flow_ctrl[ELINK_LINK_CONFIG_SIZE];
uint16_t req_line_speed[ELINK_LINK_CONFIG_SIZE]; /* Also determine AutoNeg */
/* shmem parameters */
uint32_t shmem_base;
uint32_t shmem2_base;
uint32_t speed_cap_mask[ELINK_LINK_CONFIG_SIZE];
uint32_t switch_cfg;
#define ELINK_SWITCH_CFG_1G PORT_FEATURE_CON_SWITCH_1G_SWITCH
#define ELINK_SWITCH_CFG_10G PORT_FEATURE_CON_SWITCH_10G_SWITCH
#define ELINK_SWITCH_CFG_AUTO_DETECT PORT_FEATURE_CON_SWITCH_AUTO_DETECT
uint32_t lane_config;
/* Phy register parameter */
uint32_t chip_id;
/* features */
uint32_t feature_config_flags;
#define ELINK_FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED (1<<0)
#define ELINK_FEATURE_CONFIG_PFC_ENABLED (1<<1)
#define ELINK_FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY (1<<2)
#define ELINK_FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY (1<<3)
#define ELINK_FEATURE_CONFIG_EMUL_DISABLE_EMAC (1<<4)
#define ELINK_FEATURE_CONFIG_EMUL_DISABLE_BMAC (1<<5)
#define ELINK_FEATURE_CONFIG_EMUL_DISABLE_UMAC (1<<6)
#define ELINK_FEATURE_CONFIG_EMUL_DISABLE_XMAC (1<<7)
#define ELINK_FEATURE_CONFIG_BC_SUPPORTS_AFEX (1<<8)
#define ELINK_FEATURE_CONFIG_AUTOGREEEN_ENABLED (1<<9)
#define ELINK_FEATURE_CONFIG_BC_SUPPORTS_SFP_TX_DISABLED (1<<10)
#define ELINK_FEATURE_CONFIG_DISABLE_REMOTE_FAULT_DET (1<<11)
#define ELINK_FEATURE_CONFIG_IEEE_PHY_TEST (1<<12)
#define ELINK_FEATURE_CONFIG_MT_SUPPORT (1<<13)
#define ELINK_FEATURE_CONFIG_BOOT_FROM_SAN (1<<14)
/* Will be populated during common init */
struct elink_phy phy[ELINK_MAX_PHYS];
/* Will be populated during common init */
uint8_t num_phys;
uint8_t rsrv;
/* Used to configure the EEE Tx LPI timer, has several modes of
* operation, according to bits 29:28 -
* 2'b00: Timer will be configured by nvram, output will be the value
* from nvram.
* 2'b01: Timer will be configured by nvram, output will be in
* microseconds.
* 2'b10: bits 1:0 contain an nvram value which will be used instead
* of the one located in the nvram. Output will be that value.
* 2'b11: bits 19:0 contain the idle timer in microseconds; output
* will be in microseconds.
* Bits 31:30 should be 2'b11 in order for EEE to be enabled.
*/
uint32_t eee_mode;
#define ELINK_EEE_MODE_NVRAM_BALANCED_TIME (0xa00)
#define ELINK_EEE_MODE_NVRAM_AGGRESSIVE_TIME (0x100)
#define ELINK_EEE_MODE_NVRAM_LATENCY_TIME (0x6000)
#define ELINK_EEE_MODE_NVRAM_MASK (0x3)
#define ELINK_EEE_MODE_TIMER_MASK (0xfffff)
#define ELINK_EEE_MODE_OUTPUT_TIME (1<<28)
#define ELINK_EEE_MODE_OVERRIDE_NVRAM (1<<29)
#define ELINK_EEE_MODE_ENABLE_LPI (1<<30)
#define ELINK_EEE_MODE_ADV_LPI (1<<31)
uint16_t hw_led_mode; /* part of the hw_config read from the shmem */
uint32_t multi_phy_config;
/* Device pointer passed to all callback functions */
struct bnx2x_softc *sc;
uint16_t req_fc_auto_adv; /* Should be set to TX / BOTH when
req_flow_ctrl is set to AUTO */
uint16_t link_flags;
#define ELINK_LINK_FLAGS_INT_DISABLED (1<<0)
#define ELINK_PHY_INITIALIZED (1<<1)
uint32_t lfa_base;
};
/* Output parameters */
struct elink_vars {
uint8_t phy_flags;
#define PHY_XGXS_FLAG (1<<0)
#define PHY_SGMII_FLAG (1<<1)
#define PHY_PHYSICAL_LINK_FLAG (1<<2)
#define PHY_HALF_OPEN_CONN_FLAG (1<<3)
#define PHY_OVER_CURRENT_FLAG (1<<4)
#define PHY_SFP_TX_FAULT_FLAG (1<<5)
uint8_t mac_type;
#define ELINK_MAC_TYPE_NONE 0
#define ELINK_MAC_TYPE_EMAC 1
#define ELINK_MAC_TYPE_BMAC 2
#define ELINK_MAC_TYPE_UMAC 3
#define ELINK_MAC_TYPE_XMAC 4
uint8_t phy_link_up; /* internal phy link indication */
uint8_t link_up;
uint16_t line_speed;
uint16_t duplex;
uint16_t flow_ctrl;
uint16_t ieee_fc;
/* The same definitions as the shmem parameter */
uint32_t link_status;
uint32_t eee_status;
uint8_t fault_detected;
uint8_t check_kr2_recovery_cnt;
#define ELINK_CHECK_KR2_RECOVERY_CNT 5
uint16_t periodic_flags;
#define ELINK_PERIODIC_FLAGS_LINK_EVENT 0x0001
uint32_t aeu_int_mask;
uint8_t rx_tx_asic_rst;
uint8_t turn_to_run_wc_rt;
uint16_t rsrv2;
/* The same definitions as the shmem2 parameter */
uint32_t link_attr_sync;
};
/***********************************************************/
/* Functions */
/***********************************************************/
elink_status_t elink_phy_init(struct elink_params *params, struct elink_vars *vars);
/* Reset the link. Should be called when driver or interface goes down
Before calling phy firmware upgrade, the reset_ext_phy should be set
to 0 */
elink_status_t elink_lfa_reset(struct elink_params *params, struct elink_vars *vars);
/* elink_link_update should be called upon link interrupt */
elink_status_t elink_link_update(struct elink_params *params, struct elink_vars *vars);
/* Reads the link_status from the shmem,
and update the link vars accordingly */
void elink_link_status_update(struct elink_params *input,
struct elink_vars *output);
/* Set/Unset the led
Basically, the CLC takes care of the led for the link, but in case one needs
to set/unset the led unnaturally, set the "mode" to ELINK_LED_MODE_OPER to
blink the led, and ELINK_LED_MODE_OFF to set the led off.*/
elink_status_t elink_set_led(struct elink_params *params,
struct elink_vars *vars, uint8_t mode, uint32_t speed);
#define ELINK_LED_MODE_OFF 0
#define ELINK_LED_MODE_ON 1
#define ELINK_LED_MODE_OPER 2
#define ELINK_LED_MODE_FRONT_PANEL_OFF 3
/* elink_handle_module_detect_int should be called upon module detection
interrupt */
void elink_handle_module_detect_int(struct elink_params *params);
/* One-time initialization for external phy after power up */
elink_status_t elink_common_init_phy(struct bnx2x_softc *sc, uint32_t shmem_base_path[],
uint32_t shmem2_base_path[], uint32_t chip_id, uint8_t one_port_enabled);
void elink_hw_reset_phy(struct elink_params *params);
/* Check swap bit and adjust PHY order */
uint32_t elink_phy_selection(struct elink_params *params);
/* Probe the phys on board, and populate them in "params" */
elink_status_t elink_phy_probe(struct elink_params *params);
/* Checks if fan failure detection is required on one of the phys on board */
uint8_t elink_fan_failure_det_req(struct bnx2x_softc *sc, uint32_t shmem_base,
uint32_t shmem2_base, uint8_t port);
/* Open / close the gate between the NIG and the BRB */
void elink_set_rx_filter(struct elink_params *params, uint8_t en);
/* DCBX structs */
/* Number of maximum COS per chip */
#define ELINK_DCBX_E2E3_MAX_NUM_COS (2)
#define ELINK_DCBX_E3B0_MAX_NUM_COS_PORT0 (6)
#define ELINK_DCBX_E3B0_MAX_NUM_COS_PORT1 (3)
#define ELINK_DCBX_E3B0_MAX_NUM_COS ( \
ELINK_MAXVAL(ELINK_DCBX_E3B0_MAX_NUM_COS_PORT0, \
ELINK_DCBX_E3B0_MAX_NUM_COS_PORT1))
#define ELINK_DCBX_MAX_NUM_COS ( \
ELINK_MAXVAL(ELINK_DCBX_E3B0_MAX_NUM_COS, \
ELINK_DCBX_E2E3_MAX_NUM_COS))
/* PFC port configuration params */
struct elink_nig_brb_pfc_port_params {
/* NIG */
uint32_t pause_enable;
uint32_t llfc_out_en;
uint32_t llfc_enable;
uint32_t pkt_priority_to_cos;
uint8_t num_of_rx_cos_priority_mask;
uint32_t rx_cos_priority_mask[ELINK_DCBX_MAX_NUM_COS];
uint32_t llfc_high_priority_classes;
uint32_t llfc_low_priority_classes;
};
/* ETS port configuration params */
struct elink_ets_bw_params {
uint8_t bw;
};
struct elink_ets_sp_params {
/**
* valid values are 0 - 5. 0 is highest strict priority.
* There can't be two COS's with the same pri.
*/
uint8_t pri;
};
enum elink_cos_state {
elink_cos_state_strict = 0,
elink_cos_state_bw = 1,
};
struct elink_ets_cos_params {
enum elink_cos_state state ;
union {
struct elink_ets_bw_params bw_params;
struct elink_ets_sp_params sp_params;
} params;
};
struct elink_ets_params {
uint8_t num_of_cos; /* Number of valid COS entries*/
struct elink_ets_cos_params cos[ELINK_DCBX_MAX_NUM_COS];
};
/* Used to update the PFC attributes in EMAC, BMAC, NIG and BRB
* when link is already up
*/
elink_status_t elink_update_pfc(struct elink_params *params,
struct elink_vars *vars,
struct elink_nig_brb_pfc_port_params *pfc_params);
void elink_init_mod_abs_int(struct bnx2x_softc *sc, struct elink_vars *vars,
uint32_t chip_id, uint32_t shmem_base, uint32_t shmem2_base,
uint8_t port);
void elink_period_func(struct elink_params *params, struct elink_vars *vars);
void elink_enable_pmd_tx(struct elink_params *params);
#endif /* ELINK_H */

View File

@ -0,0 +1,4 @@
DPDK_2.1 {
local: *;
};