diff options
author | Dmitry Kravkov <dmitry@broadcom.com> | 2010-10-06 03:23:26 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-10-06 14:10:35 -0700 |
commit | 523224a3b3cd407ce4e6731a087194e13a90db18 (patch) | |
tree | bb0fda289682e4259c401b8a5763ba4cc4d41659 /drivers | |
parent | 0c5b77152e736d23a23eb2546eab323e27a37f52 (diff) |
bnx2x, cnic, bnx2i: use new FW/HSI
This is the new FW HSI blob and the relevant definitions without logic changes.
It also included code adaptation for new HSI. New features are not enabled.
New FW/HSI includes:
- Support for 57712 HW
- Future support for VF (not used)
- Improvements in FW interrupts scheme
- FW FCoE hooks (stubs for future usage)
Signed-off-by: Dmitry Kravkov <dmitry@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/bnx2x/bnx2x.h | 532 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_cmn.c | 488 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_cmn.h | 256 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_ethtool.c | 20 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_fw_defs.h | 819 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_fw_file_hdr.h | 1 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_hsi.h | 1465 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_init.h | 41 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_init_ops.h | 338 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_link.c | 3 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_main.c | 3208 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_stats.c | 12 | ||||
-rw-r--r-- | drivers/net/cnic.c | 285 | ||||
-rw-r--r-- | drivers/net/cnic.h | 51 | ||||
-rw-r--r-- | drivers/net/cnic_defs.h | 456 | ||||
-rw-r--r-- | drivers/net/cnic_if.h | 2 | ||||
-rw-r--r-- | drivers/scsi/bnx2i/bnx2i.h | 2 | ||||
-rw-r--r-- | drivers/scsi/bnx2i/bnx2i_hwi.c | 3 |
18 files changed, 4762 insertions, 3220 deletions
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 64329c5fbdea..8b053e0c00ab 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -33,13 +33,11 @@ #define BNX2X_NEW_NAPI - #if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE) #define BCM_CNIC 1 #include "../cnic_if.h" #endif - #ifdef BCM_CNIC #define BNX2X_MIN_MSIX_VEC_CNT 3 #define BNX2X_MSIX_VEC_FP_START 2 @@ -129,16 +127,18 @@ void bnx2x_panic_dump(struct bnx2x *bp); } while (0) #endif +#define bnx2x_mc_addr(ha) ((ha)->addr) #define U64_LO(x) (u32)(((u64)(x)) & 0xffffffff) #define U64_HI(x) (u32)(((u64)(x)) >> 32) #define HILO_U64(hi, lo) ((((u64)(hi)) << 32) + (lo)) -#define REG_ADDR(bp, offset) (bp->regview + offset) +#define REG_ADDR(bp, offset) ((bp->regview) + (offset)) #define REG_RD(bp, offset) readl(REG_ADDR(bp, offset)) #define REG_RD8(bp, offset) readb(REG_ADDR(bp, offset)) +#define REG_RD16(bp, offset) readw(REG_ADDR(bp, offset)) #define REG_WR(bp, offset, val) writel((u32)val, REG_ADDR(bp, offset)) #define REG_WR8(bp, offset, val) writeb((u8)val, REG_ADDR(bp, offset)) @@ -160,6 +160,9 @@ void bnx2x_panic_dump(struct bnx2x *bp); offset, len32); \ } while (0) +#define REG_WR_DMAE_LEN(bp, offset, valp, len32) \ + REG_WR_DMAE(bp, offset, valp, len32) + #define VIRT_WR_DMAE_LEN(bp, data, addr, len32, le32_swap) \ do { \ memcpy(GUNZIP_BUF(bp), data, (len32) * 4); \ @@ -175,16 +178,52 @@ void bnx2x_panic_dump(struct bnx2x *bp); offsetof(struct shmem2_region, field)) #define SHMEM2_RD(bp, field) REG_RD(bp, SHMEM2_ADDR(bp, field)) #define SHMEM2_WR(bp, field, val) REG_WR(bp, SHMEM2_ADDR(bp, field), val) +#define MF_CFG_ADDR(bp, field) (bp->common.mf_cfg_base + \ + offsetof(struct mf_cfg, field)) -#define MF_CFG_RD(bp, field) SHMEM_RD(bp, mf_cfg.field) -#define MF_CFG_WR(bp, field, val) SHMEM_WR(bp, mf_cfg.field, val) +#define MF_CFG_RD(bp, field) REG_RD(bp, MF_CFG_ADDR(bp, field)) +#define MF_CFG_WR(bp, field, val) REG_WR(bp,\ + MF_CFG_ADDR(bp, field), (val)) #define EMAC_RD(bp, reg) REG_RD(bp, emac_base + reg) #define EMAC_WR(bp, reg, val) REG_WR(bp, emac_base + reg, val) +/* SP SB indices */ + +/* General SP events - stats query, cfc delete, etc */ +#define HC_SP_INDEX_ETH_DEF_CONS 3 + +/* EQ completions */ +#define HC_SP_INDEX_EQ_CONS 7 + +/* iSCSI L2 */ +#define HC_SP_INDEX_ETH_ISCSI_CQ_CONS 5 +#define HC_SP_INDEX_ETH_ISCSI_RX_CQ_CONS 1 + +/** + * CIDs and CLIDs: + * CLIDs below is a CLID for func 0, then the CLID for other + * functions will be calculated by the formula: + * + * FUNC_N_CLID_X = N * NUM_SPECIAL_CLIENTS + FUNC_0_CLID_X + * + */ +/* iSCSI L2 */ +#define BNX2X_ISCSI_ETH_CL_ID 17 +#define BNX2X_ISCSI_ETH_CID 17 + +/** Additional rings budgeting */ +#ifdef BCM_CNIC +#define CNIC_CONTEXT_USE 1 +#else +#define CNIC_CONTEXT_USE 0 +#endif /* BCM_CNIC */ + #define AEU_IN_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR \ AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR +#define SM_RX_ID 0 +#define SM_TX_ID 1 /* fast path */ @@ -254,11 +293,21 @@ union db_prod { #define RX_SGE_MASK_LEN_MASK (RX_SGE_MASK_LEN - 1) #define NEXT_SGE_MASK_ELEM(el) (((el) + 1) & RX_SGE_MASK_LEN_MASK) +union host_hc_status_block { + /* pointer to fp status block e1x */ + struct host_hc_status_block_e1x *e1x_sb; +}; struct bnx2x_fastpath { struct napi_struct napi; - struct host_status_block *status_blk; + union host_hc_status_block status_blk; + /* chip independed shortcuts into sb structure */ + __le16 *sb_index_values; + __le16 *sb_running_index; + /* chip independed shortcut into rx_prods_offset memory */ + u32 ustorm_rx_prods_offset; + dma_addr_t status_blk_mapping; struct sw_tx_bd *tx_buf_ring; @@ -288,10 +337,15 @@ struct bnx2x_fastpath { #define BNX2X_FP_STATE_OPEN 0xa0000 #define BNX2X_FP_STATE_HALTING 0xb0000 #define BNX2X_FP_STATE_HALTED 0xc0000 +#define BNX2X_FP_STATE_TERMINATING 0xd0000 +#define BNX2X_FP_STATE_TERMINATED 0xe0000 u8 index; /* number in fp array */ u8 cl_id; /* eth client id */ - u8 sb_id; /* status block number in HW */ + u8 cl_qzone_id; + u8 fw_sb_id; /* status block number in FW */ + u8 igu_sb_id; /* status block number in HW */ + u32 cid; union db_prod tx_db; @@ -301,8 +355,7 @@ struct bnx2x_fastpath { u16 tx_bd_cons; __le16 *tx_cons_sb; - __le16 fp_c_idx; - __le16 fp_u_idx; + __le16 fp_hc_idx; u16 rx_bd_prod; u16 rx_bd_cons; @@ -312,7 +365,7 @@ struct bnx2x_fastpath { /* The last maximal completed SGE */ u16 last_max_sge; __le16 *rx_cons_sb; - __le16 *rx_bd_cons_sb; + unsigned long tx_pkt, @@ -356,6 +409,8 @@ struct bnx2x_fastpath { #define NUM_TX_BD (TX_DESC_CNT * NUM_TX_RINGS) #define MAX_TX_BD (NUM_TX_BD - 1) #define MAX_TX_AVAIL (MAX_TX_DESC_CNT * NUM_TX_RINGS - 2) +#define INIT_JUMBO_TX_RING_SIZE MAX_TX_AVAIL +#define INIT_TX_RING_SIZE MAX_TX_AVAIL #define NEXT_TX_IDX(x) ((((x) & MAX_TX_DESC_CNT) == \ (MAX_TX_DESC_CNT - 1)) ? (x) + 2 : (x) + 1) #define TX_BD(x) ((x) & MAX_TX_BD) @@ -370,6 +425,8 @@ struct bnx2x_fastpath { #define MAX_RX_BD (NUM_RX_BD - 1) #define MAX_RX_AVAIL (MAX_RX_DESC_CNT * NUM_RX_RINGS - 2) #define MIN_RX_AVAIL 128 +#define INIT_JUMBO_RX_RING_SIZE MAX_RX_AVAIL +#define INIT_RX_RING_SIZE MAX_RX_AVAIL #define NEXT_RX_IDX(x) ((((x) & RX_DESC_MASK) == \ (MAX_RX_DESC_CNT - 1)) ? (x) + 3 : (x) + 1) #define RX_BD(x) ((x) & MAX_RX_BD) @@ -420,11 +477,12 @@ struct bnx2x_fastpath { le32_to_cpu((bd)->addr_lo)) #define BD_UNMAP_LEN(bd) (le16_to_cpu((bd)->nbytes)) - +#define BNX2X_DB_MIN_SHIFT 3 /* 8 bytes */ +#define BNX2X_DB_SHIFT 7 /* 128 bytes*/ #define DPM_TRIGER_TYPE 0x40 #define DOORBELL(bp, cid, val) \ do { \ - writel((u32)(val), bp->doorbells + (BCM_PAGE_SIZE * (cid)) + \ + writel((u32)(val), bp->doorbells + (bp->db_size * (cid)) + \ DPM_TRIGER_TYPE); \ } while (0) @@ -482,31 +540,15 @@ struct bnx2x_fastpath { #define BNX2X_RX_SUM_FIX(cqe) \ BNX2X_PRS_FLAG_OVERETH_IPV4(cqe->fast_path_cqe.pars_flags.flags) - -#define FP_USB_FUNC_OFF (2 + 2*HC_USTORM_SB_NUM_INDICES) -#define FP_CSB_FUNC_OFF (2 + 2*HC_CSTORM_SB_NUM_INDICES) - -#define U_SB_ETH_RX_CQ_INDEX HC_INDEX_U_ETH_RX_CQ_CONS -#define U_SB_ETH_RX_BD_INDEX HC_INDEX_U_ETH_RX_BD_CONS -#define C_SB_ETH_TX_CQ_INDEX HC_INDEX_C_ETH_TX_CQ_CONS +#define U_SB_ETH_RX_CQ_INDEX 1 +#define U_SB_ETH_RX_BD_INDEX 2 +#define C_SB_ETH_TX_CQ_INDEX 5 #define BNX2X_RX_SB_INDEX \ - (&fp->status_blk->u_status_block.index_values[U_SB_ETH_RX_CQ_INDEX]) - -#define BNX2X_RX_SB_BD_INDEX \ - (&fp->status_blk->u_status_block.index_values[U_SB_ETH_RX_BD_INDEX]) - -#define BNX2X_RX_SB_INDEX_NUM \ - (((U_SB_ETH_RX_CQ_INDEX << \ - USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER_SHIFT) & \ - USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER) | \ - ((U_SB_ETH_RX_BD_INDEX << \ - USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER_SHIFT) & \ - USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER)) + (&fp->sb_index_values[U_SB_ETH_RX_CQ_INDEX]) #define BNX2X_TX_SB_INDEX \ - (&fp->status_blk->c_status_block.index_values[C_SB_ETH_TX_CQ_INDEX]) - + (&fp->sb_index_values[C_SB_ETH_TX_CQ_INDEX]) /* end of fast path */ @@ -553,10 +595,16 @@ struct bnx2x_common { u32 shmem_base; u32 shmem2_base; + u32 mf_cfg_base; u32 hw_config; u32 bc_ver; + + u8 int_block; +#define INT_BLOCK_HC 0 + u8 chip_port_mode; +#define CHIP_PORT_MODE_NONE 0x2 }; @@ -590,27 +638,98 @@ struct bnx2x_port { /* end of port */ +/* e1h Classification CAM line allocations */ +enum { + CAM_ETH_LINE = 0, + CAM_ISCSI_ETH_LINE, + CAM_MAX_PF_LINE = CAM_ISCSI_ETH_LINE +}; +#define BNX2X_VF_ID_INVALID 0xFF -#ifdef BCM_CNIC -#define MAX_CONTEXT 15 -#else -#define MAX_CONTEXT 16 -#endif +/* + * The total number of L2 queues, MSIX vectors and HW contexts (CIDs) is + * control by the number of fast-path status blocks supported by the + * device (HW/FW). Each fast-path status block (FP-SB) aka non-default + * status block represents an independent interrupts context that can + * serve a regular L2 networking queue. However special L2 queues such + * as the FCoE queue do not require a FP-SB and other components like + * the CNIC may consume FP-SB reducing the number of possible L2 queues + * + * If the maximum number of FP-SB available is X then: + * a. If CNIC is supported it consumes 1 FP-SB thus the max number of + * regular L2 queues is Y=X-1 + * b. in MF mode the actual number of L2 queues is Y= (X-1/MF_factor) + * c. If the FCoE L2 queue is supported the actual number of L2 queues + * is Y+1 + * d. The number of irqs (MSIX vectors) is either Y+1 (one extra for + * slow-path interrupts) or Y+2 if CNIC is supported (one additional + * FP interrupt context for the CNIC). + * e. The number of HW context (CID count) is always X or X+1 if FCoE + * L2 queue is supported. the cid for the FCoE L2 queue is always X. + */ + +#define FP_SB_MAX_E1x 16 /* fast-path interrupt contexts E1x */ +#define MAX_CONTEXT FP_SB_MAX_E1x + +/* + * cid_cnt paramter below refers to the value returned by + * 'bnx2x_get_l2_cid_count()' routine + */ + +/* + * The number of FP context allocated by the driver == max number of regular + * L2 queues + 1 for the FCoE L2 queue + */ +#define L2_FP_COUNT(cid_cnt) ((cid_cnt) - CNIC_CONTEXT_USE) union cdu_context { struct eth_context eth; char pad[1024]; }; +/* CDU host DB constants */ +#define CDU_ILT_PAGE_SZ_HW 3 +#define CDU_ILT_PAGE_SZ (4096 << CDU_ILT_PAGE_SZ_HW) /* 32K */ +#define ILT_PAGE_CIDS (CDU_ILT_PAGE_SZ / sizeof(union cdu_context)) + +#ifdef BCM_CNIC +#define CNIC_ISCSI_CID_MAX 256 +#define CNIC_CID_MAX (CNIC_ISCSI_CID_MAX) +#define CNIC_ILT_LINES DIV_ROUND_UP(CNIC_CID_MAX, ILT_PAGE_CIDS) +#endif + +#define QM_ILT_PAGE_SZ_HW 3 +#define QM_ILT_PAGE_SZ (4096 << QM_ILT_PAGE_SZ_HW) /* 32K */ +#define QM_CID_ROUND 1024 + +#ifdef BCM_CNIC +/* TM (timers) host DB constants */ +#define TM_ILT_PAGE_SZ_HW 2 +#define TM_ILT_PAGE_SZ (4096 << TM_ILT_PAGE_SZ_HW) /* 16K */ +/* #define TM_CONN_NUM (CNIC_STARTING_CID+CNIC_ISCSI_CXT_MAX) */ +#define TM_CONN_NUM 1024 +#define TM_ILT_SZ (8 * TM_CONN_NUM) +#define TM_ILT_LINES DIV_ROUND_UP(TM_ILT_SZ, TM_ILT_PAGE_SZ) + +/* SRC (Searcher) host DB constants */ +#define SRC_ILT_PAGE_SZ_HW 3 +#define SRC_ILT_PAGE_SZ (4096 << SRC_ILT_PAGE_SZ_HW) /* 32K */ +#define SRC_HASH_BITS 10 +#define SRC_CONN_NUM (1 << SRC_HASH_BITS) /* 1024 */ +#define SRC_ILT_SZ (sizeof(struct src_ent) * SRC_CONN_NUM) +#define SRC_T2_SZ SRC_ILT_SZ +#define SRC_ILT_LINES DIV_ROUND_UP(SRC_ILT_SZ, SRC_ILT_PAGE_SZ) +#endif + #define MAX_DMAE_C 8 /* DMA memory not used in fastpath */ struct bnx2x_slowpath { - union cdu_context context[MAX_CONTEXT]; struct eth_stats_query fw_stats; struct mac_configuration_cmd mac_config; struct mac_configuration_cmd mcast_config; + struct client_init_ramrod_data client_init_data; /* used by dmae command executer */ struct dmae_command dmae[MAX_DMAE_C]; @@ -638,37 +757,71 @@ struct attn_route { u32 sig[4]; }; +struct iro { + u32 base; + u16 m1; + u16 m2; + u16 m3; + u16 size; +}; + +struct hw_context { + union cdu_context *vcxt; + dma_addr_t cxt_mapping; + size_t size; +}; + +/* forward */ +struct bnx2x_ilt; + typedef enum { BNX2X_RECOVERY_DONE, BNX2X_RECOVERY_INIT, BNX2X_RECOVERY_WAIT, } bnx2x_recovery_state_t; +/** + * Event queue (EQ or event ring) MC hsi + * NUM_EQ_PAGES and EQ_DESC_CNT_PAGE must be power of 2 + */ +#define NUM_EQ_PAGES 1 +#define EQ_DESC_CNT_PAGE (BCM_PAGE_SIZE / sizeof(union event_ring_elem)) +#define EQ_DESC_MAX_PAGE (EQ_DESC_CNT_PAGE - 1) +#define NUM_EQ_DESC (EQ_DESC_CNT_PAGE * NUM_EQ_PAGES) +#define EQ_DESC_MASK (NUM_EQ_DESC - 1) +#define MAX_EQ_AVAIL (EQ_DESC_MAX_PAGE * NUM_EQ_PAGES - 2) + +/* depends on EQ_DESC_CNT_PAGE being a power of 2 */ +#define NEXT_EQ_IDX(x) ((((x) & EQ_DESC_MAX_PAGE) == \ + (EQ_DESC_MAX_PAGE - 1)) ? (x) + 2 : (x) + 1) + +/* depends on the above and on NUM_EQ_PAGES being a power of 2 */ +#define EQ_DESC(x) ((x) & EQ_DESC_MASK) + +#define BNX2X_EQ_INDEX \ + (&bp->def_status_blk->sp_sb.\ + index_values[HC_SP_INDEX_EQ_CONS]) + struct bnx2x { /* Fields used in the tx and intr/napi performance paths * are grouped together in the beginning of the structure */ - struct bnx2x_fastpath fp[MAX_CONTEXT]; + struct bnx2x_fastpath *fp; void __iomem *regview; void __iomem *doorbells; -#ifdef BCM_CNIC -#define BNX2X_DB_SIZE (18*BCM_PAGE_SIZE) -#else -#define BNX2X_DB_SIZE (16*BCM_PAGE_SIZE) -#endif + u16 db_size; struct net_device *dev; struct pci_dev *pdev; + struct iro *iro_arr; +#define IRO (bp->iro_arr) + atomic_t intr_sem; bnx2x_recovery_state_t recovery_state; int is_leader; -#ifdef BCM_CNIC - struct msix_entry msix_table[MAX_CONTEXT+2]; -#else - struct msix_entry msix_table[MAX_CONTEXT+1]; -#endif + struct msix_entry *msix_table; #define INT_MODE_INTx 1 #define INT_MODE_MSI 2 @@ -680,7 +833,8 @@ struct bnx2x { u32 rx_csum; u32 rx_buf_size; -#define ETH_OVREHEAD (ETH_HLEN + 8) /* 8 for CRC + VLAN */ +/* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */ +#define ETH_OVREHEAD (ETH_HLEN + 8 + 8) #define ETH_MIN_PACKET_SIZE 60 #define ETH_MAX_PACKET_SIZE 1500 #define ETH_MAX_JUMBO_PACKET_SIZE 9600 @@ -689,13 +843,12 @@ struct bnx2x { #define BNX2X_RX_ALIGN_SHIFT ((L1_CACHE_SHIFT < 8) ? \ L1_CACHE_SHIFT : 8) #define BNX2X_RX_ALIGN (1 << BNX2X_RX_ALIGN_SHIFT) +#define BNX2X_PXP_DRAM_ALIGN (BNX2X_RX_ALIGN_SHIFT - 5) - struct host_def_status_block *def_status_blk; -#define DEF_SB_ID 16 - __le16 def_c_idx; - __le16 def_u_idx; - __le16 def_x_idx; - __le16 def_t_idx; + struct host_sp_status_block *def_status_blk; +#define DEF_SB_IGU_ID 16 +#define DEF_SB_ID HC_SP_SB_ID + __le16 def_idx; __le16 def_att_idx; u32 attn_state; struct attn_route attn_group[MAX_DYNAMIC_ATTN_GRPS]; @@ -711,6 +864,13 @@ struct bnx2x { /* used to synchronize spq accesses */ spinlock_t spq_lock; + /* event queue */ + union event_ring_elem *eq_ring; + dma_addr_t eq_mapping; + u16 eq_prod; + u16 eq_cons; + __le16 *eq_cons_sb; + /* Flags for marking that there is a STAT_QUERY or SET_MAC ramrod pending */ int stats_pending; @@ -737,6 +897,8 @@ struct bnx2x { #define MF_FUNC_DIS 0x1000 int func; + int base_fw_ndsb; + #define BP_PORT(bp) (bp->func % PORT_MAX) #define BP_FUNC(bp) (bp->func) #define BP_E1HVN(bp) (bp->func >> 1) @@ -801,6 +963,7 @@ struct bnx2x { #define BNX2X_STATE_CLOSING_WAIT4_HALT 0x4000 #define BNX2X_STATE_CLOSING_WAIT4_DELETE 0x5000 #define BNX2X_STATE_CLOSING_WAIT4_UNLOAD 0x6000 +#define BNX2X_STATE_FUNC_STARTED 0x7000 #define BNX2X_STATE_DIAG 0xe000 #define BNX2X_STATE_ERROR 0xf000 @@ -809,6 +972,15 @@ struct bnx2x { int disable_tpa; int int_mode; + struct tstorm_eth_mac_filter_config mac_filters; +#define BNX2X_ACCEPT_NONE 0x0000 +#define BNX2X_ACCEPT_UNICAST 0x0001 +#define BNX2X_ACCEPT_MULTICAST 0x0002 +#define BNX2X_ACCEPT_ALL_UNICAST 0x0004 +#define BNX2X_ACCEPT_ALL_MULTICAST 0x0008 +#define BNX2X_ACCEPT_BROADCAST 0x0010 +#define BNX2X_PROMISCUOUS_MODE 0x10000 + u32 rx_mode; #define BNX2X_RX_MODE_NONE 0 #define BNX2X_RX_MODE_NORMAL 1 @@ -817,12 +989,25 @@ struct bnx2x { #define BNX2X_MAX_MULTICAST 64 #define BNX2X_MAX_EMUL_MULTI 16 - u32 rx_mode_cl_mask; - + u8 igu_dsb_id; + u8 igu_base_sb; + u8 igu_sb_cnt; dma_addr_t def_status_blk_mapping; struct bnx2x_slowpath *slowpath; dma_addr_t slowpath_mapping; + struct hw_context context; + + struct bnx2x_ilt *ilt; +#define BP_ILT(bp) ((bp)->ilt) +#define ILT_MAX_LINES 128 + + int l2_cid_count; +#define L2_ILT_LINES(bp) (DIV_ROUND_UP((bp)->l2_cid_count, \ + ILT_PAGE_CIDS)) +#define BNX2X_DB_SIZE(bp) ((bp)->l2_cid_count * (1 << BNX2X_DB_SHIFT)) + + int qm_cid_count; int dropless_fc; @@ -842,9 +1027,10 @@ struct bnx2x { void *cnic_data; u32 cnic_tag; struct cnic_eth_dev cnic_eth_dev; - struct host_status_block *cnic_sb; + union host_hc_status_block cnic_sb; dma_addr_t cnic_sb_mapping; -#define CNIC_SB_ID(bp) BP_L_ID(bp) +#define CNIC_SB_ID(bp) ((bp)->base_fw_ndsb + BP_L_ID(bp)) +#define CNIC_IGU_SB_ID(bp) ((bp)->igu_base_sb) struct eth_spe *cnic_kwq; struct eth_spe *cnic_kwq_prod; struct eth_spe *cnic_kwq_cons; @@ -914,12 +1100,167 @@ struct bnx2x { const struct firmware *firmware; }; +/** + * Init queue/func interface + */ +/* queue init flags */ +#define QUEUE_FLG_TPA 0x0001 +#define QUEUE_FLG_CACHE_ALIGN 0x0002 +#define QUEUE_FLG_STATS 0x0004 +#define QUEUE_FLG_OV 0x0008 +#define QUEUE_FLG_VLAN 0x0010 +#define QUEUE_FLG_COS 0x0020 +#define QUEUE_FLG_HC 0x0040 +#define QUEUE_FLG_DHC 0x0080 +#define QUEUE_FLG_OOO 0x0100 + +#define QUEUE_DROP_IP_CS_ERR TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR +#define QUEUE_DROP_TCP_CS_ERR TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR +#define QUEUE_DROP_TTL0 TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0 +#define QUEUE_DROP_UDP_CS_ERR TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR + + + +/* rss capabilities */ +#define RSS_IPV4_CAP 0x0001 +#define RSS_IPV4_TCP_CAP 0x0002 +#define RSS_IPV6_CAP 0x0004 +#define RSS_IPV6_TCP_CAP 0x0008 #define BNX2X_MAX_QUEUES(bp) (IS_E1HMF(bp) ? (MAX_CONTEXT/E1HVN_MAX) \ : MAX_CONTEXT) #define BNX2X_NUM_QUEUES(bp) (bp->num_queues) #define is_multi(bp) (BNX2X_NUM_QUEUES(bp) > 1) + +#define RSS_IPV4_CAP_MASK \ + TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY + +#define RSS_IPV4_TCP_CAP_MASK \ + TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY + +#define RSS_IPV6_CAP_MASK \ + TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY + +#define RSS_IPV6_TCP_CAP_MASK \ + TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY + +/* func init flags */ +#define FUNC_FLG_RSS 0x0001 +#define FUNC_FLG_STATS 0x0002 +/* removed FUNC_FLG_UNMATCHED 0x0004 */ +#define FUNC_FLG_TPA 0x0008 +#define FUNC_FLG_SPQ 0x0010 +#define FUNC_FLG_LEADING 0x0020 /* PF only */ + +#define FUNC_CONFIG(flgs) ((flgs) & (FUNC_FLG_RSS | FUNC_FLG_TPA | \ + FUNC_FLG_LEADING)) + +struct rxq_pause_params { + u16 bd_th_lo; + u16 bd_th_hi; + u16 rcq_th_lo; + u16 rcq_th_hi; + u16 sge_th_lo; /* valid iff QUEUE_FLG_TPA */ + u16 sge_th_hi; /* valid iff QUEUE_FLG_TPA */ + u16 pri_map; +}; + +struct bnx2x_rxq_init_params { + /* cxt*/ + struct eth_context *cxt; + + /* dma */ + dma_addr_t dscr_map; + dma_addr_t sge_map; + dma_addr_t rcq_map; + dma_addr_t rcq_np_map; + + u16 flags; + u16 drop_flags; + u16 mtu; + u16 buf_sz; + u16 fw_sb_id; + u16 cl_id; + u16 spcl_id; + u16 cl_qzone_id; + + /* valid iff QUEUE_FLG_STATS */ + u16 stat_id; + + /* valid iff QUEUE_FLG_TPA */ + u16 tpa_agg_sz; + u16 sge_buf_sz; + u16 max_sges_pkt; + + /* valid iff QUEUE_FLG_CACHE_ALIGN */ + u8 cache_line_log; + + u8 sb_cq_index; + u32 cid; + + /* desired interrupts per sec. valid iff QUEUE_FLG_HC */ + u32 hc_rate; +}; + +struct bnx2x_txq_init_params { + /* cxt*/ + struct eth_context *cxt; + + /* dma */ + dma_addr_t dscr_map; + + u16 flags; + u16 fw_sb_id; + u8 sb_cq_index; + u8 cos; /* valid iff QUEUE_FLG_COS */ + u16 stat_id; /* valid iff QUEUE_FLG_STATS */ + u16 traffic_type; + u32 cid; + u16 hc_rate; /* desired interrupts per sec.*/ + /* valid iff QUEUE_FLG_HC */ + +}; + +struct bnx2x_client_ramrod_params { + int *pstate; + int state; + u16 index; + u16 cl_id; + u32 cid; + u8 poll; +#define CLIENT_IS_LEADING_RSS 0x02 + u8 flags; +}; + +struct bnx2x_client_init_params { + struct rxq_pause_params pause; + struct bnx2x_rxq_init_params rxq_params; + struct bnx2x_txq_init_params txq_params; + struct bnx2x_client_ramrod_params ramrod_params; +}; + +struct bnx2x_rss_params { + int mode; + u16 cap; + u16 result_mask; +}; + +struct bnx2x_func_init_params { + + /* rss */ + struct bnx2x_rss_params *rss; /* valid iff FUNC_FLG_RSS */ + + /* dma */ + dma_addr_t fw_stat_map; /* valid iff FUNC_FLG_STATS */ + dma_addr_t spq_map; /* valid iff FUNC_FLG_SPQ */ + + u16 func_flgs; + u16 func_id; /* abs fid */ + u16 pf_id; + u16 spq_prod; /* valid iff FUNC_FLG_SPQ */ +}; + #define for_each_queue(bp, var) \ for (var = 0; var < BNX2X_NUM_QUEUES(bp); var++) #define for_each_nondefault_queue(bp, var) \ @@ -957,6 +1298,38 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, return val; } +#define BNX2X_ILT_ZALLOC(x, y, size) \ + do { \ + x = pci_alloc_consistent(bp->pdev, size, y); \ + if (x) \ + memset(x, 0, size); \ + } while (0) + +#define BNX2X_ILT_FREE(x, y, size) \ + do { \ + if (x) { \ + pci_free_consistent(bp->pdev, size, x, y); \ + x = NULL; \ + y = 0; \ + } \ + } while (0) + +#define ILOG2(x) (ilog2((x))) + +#define ILT_NUM_PAGE_ENTRIES (3072) +/* In 57710/11 we use whole table since we have 8 func + */ +#define ILT_PER_FUNC (ILT_NUM_PAGE_ENTRIES/8) + +#define FUNC_ILT_BASE(func) (func * ILT_PER_FUNC) +/* + * 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 ONCHIP_ADDR1(x) ((u32)(((u64)x >> 12) & 0xFFFFFFFF)) +#define ONCHIP_ADDR2(x) ((u32)((1 << 20) | ((u64)x >> 44))) /* load/unload mode */ @@ -1032,7 +1405,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define MAX_SP_DESC_CNT (SP_DESC_CNT - 1) -#define BNX2X_BTR 1 +#define BNX2X_BTR 4 #define MAX_SPQ_PENDING 8 @@ -1149,20 +1522,22 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT)) #define MULTI_MASK 0x7f - -#define DEF_USB_FUNC_OFF (2 + 2*HC_USTORM_DEF_SB_NUM_INDICES) -#define DEF_CSB_FUNC_OFF (2 + 2*HC_CSTORM_DEF_SB_NUM_INDICES) -#define DEF_XSB_FUNC_OFF (2 + 2*HC_XSTORM_DEF_SB_NUM_INDICES) -#define DEF_TSB_FUNC_OFF (2 + 2*HC_TSTORM_DEF_SB_NUM_INDICES) - -#define C_DEF_SB_SP_INDEX HC_INDEX_DEF_C_ETH_SLOW_PATH - #define BNX2X_SP_DSB_INDEX \ -(&bp->def_status_blk->c_def_status_block.index_values[C_DEF_SB_SP_INDEX]) + (&bp->def_status_blk->sp_sb.\ + index_values[HC_SP_INDEX_ETH_DEF_CONS]) +#define SET_FLAG(value, mask, flag) \ + do {\ + (value) &= ~(mask);\ + (value) |= ((flag) << (mask##_SHIFT));\ + } while (0) +#define GET_FLAG(value, mask) \ + (((value) &= (mask)) >> (mask##_SHIFT)) #define CAM_IS_INVALID(x) \ -(x.target_table_entry.flags == TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE) + (GET_FLAG(x.flags, \ + MAC_CONFIGURATION_ENTRY_ACTION_TYPE) == \ + (T_ETH_MAC_COMMAND_INVALIDATE)) #define CAM_INVALIDATE(x) \ (x.target_table_entry.flags = TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE) @@ -1181,6 +1556,14 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define BNX2X_VPD_LEN 128 #define VENDOR_ID_LEN 4 +/* Congestion management fairness mode */ +#define CMNG_FNS_NONE 0 +#define CMNG_FNS_MINMAX 1 + +#define HC_SEG_ACCESS_DEF 0 /*Driver decision 0-3*/ +#define HC_SEG_ACCESS_ATTN 4 +#define HC_SEG_ACCESS_NORM 0 /*Driver decision 0-1*/ + #ifdef BNX2X_MAIN #define BNX2X_EXTERN #else @@ -1195,4 +1578,9 @@ extern void bnx2x_set_ethtool_ops(struct net_device *netdev); void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae, int idx); +#define WAIT_RAMROD_POLL 0x01 +#define WAIT_RAMROD_COMMON 0x02 + +int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, + int *state_p, int flags); #endif /* bnx2x.h */ diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 8d42067a6989..bcc4a8f4677b 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -27,6 +27,8 @@ #include <linux/if_vlan.h> #endif +#include "bnx2x_init.h" + static int bnx2x_poll(struct napi_struct *napi, int budget); /* free skb in the packet ring at pos idx @@ -190,14 +192,16 @@ static void bnx2x_update_sge_prod(struct bnx2x_fastpath *fp, /* First mark all used pages */ for (i = 0; i < sge_len; i++) - SGE_MASK_CLEAR_BIT(fp, RX_SGE(le16_to_cpu(fp_cqe->sgl[i]))); + SGE_MASK_CLEAR_BIT(fp, + RX_SGE(le16_to_cpu(fp_cqe->sgl_or_raw_data.sgl[i]))); DP(NETIF_MSG_RX_STATUS, "fp_cqe->sgl[%d] = %d\n", - sge_len - 1, le16_to_cpu(fp_cqe->sgl[sge_len - 1])); + sge_len - 1, le16_to_cpu(fp_cqe->sgl_or_raw_data.sgl[sge_len - 1])); /* Here we assume that the last SGE index is the biggest */ prefetch((void *)(fp->sge_mask)); - bnx2x_update_last_max_sge(fp, le16_to_cpu(fp_cqe->sgl[sge_len - 1])); + bnx2x_update_last_max_sge(fp, + le16_to_cpu(fp_cqe->sgl_or_raw_data.sgl[sge_len - 1])); last_max = RX_SGE(fp->last_max_sge); last_elem = last_max >> RX_SGE_MASK_ELEM_SHIFT; @@ -298,7 +302,8 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, /* Run through the SGL and compose the fragmented skb */ for (i = 0, j = 0; i < pages; i += PAGES_PER_SGE, j++) { - u16 sge_idx = RX_SGE(le16_to_cpu(fp_cqe->sgl[j])); + u16 sge_idx = + RX_SGE(le16_to_cpu(fp_cqe->sgl_or_raw_data.sgl[j])); /* FW gives the indices of the SGE as if the ring is an array (meaning that "next" element will consume 2 indices) */ @@ -394,8 +399,9 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, if (!bnx2x_fill_frag_skb(bp, fp, skb, &cqe->fast_path_cqe, cqe_idx)) { #ifdef BCM_VLAN - if ((bp->vlgrp != NULL) && is_vlan_cqe && - (!is_not_hwaccel_vlan_cqe)) + if ((bp->vlgrp != NULL) && + (le16_to_cpu(cqe->fast_path_cqe. + pars_flags.flags) & PARSING_FLAGS_VLAN)) vlan_gro_receive(&fp->napi, bp->vlgrp, le16_to_cpu(cqe->fast_path_cqe. vlan_tag), skb); @@ -686,9 +692,10 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie) return IRQ_HANDLED; } - DP(BNX2X_MSG_FP, "got an MSI-X interrupt on IDX:SB [%d:%d]\n", - fp->index, fp->sb_id); - bnx2x_ack_sb(bp, fp->sb_id, USTORM_ID, 0, IGU_INT_DISABLE, 0); + DP(BNX2X_MSG_FP, "got an MSI-X interrupt on IDX:SB " + "[fp %d fw_sd %d igusb %d]\n", + fp->index, fp->fw_sb_id, fp->igu_sb_id); + bnx2x_ack_sb(bp, fp->igu_sb_id, USTORM_ID, 0, IGU_INT_DISABLE, 0); #ifdef BNX2X_STOP_ON_ERROR if (unlikely(bp->panic)) @@ -698,8 +705,7 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie) /* Handle Rx and Tx according to MSI-X vector */ prefetch(fp->rx_cons_sb); prefetch(fp->tx_cons_sb); - prefetch(&fp->status_blk->u_status_block.status_block_index); - prefetch(&fp->status_blk->c_status_block.status_block_index); + prefetch(&fp->sb_running_index[SM_RX_ID]); napi_schedule(&bnx2x_fp(bp, fp->index, napi)); return IRQ_HANDLED; @@ -774,27 +780,73 @@ void bnx2x_link_report(struct bnx2x *bp) } } +/* Returns the number of actually allocated BDs */ +static inline int bnx2x_alloc_rx_bds(struct bnx2x_fastpath *fp, + int rx_ring_size) +{ + struct bnx2x *bp = fp->bp; + u16 ring_prod, cqe_ring_prod; + int i; + + fp->rx_comp_cons = 0; + cqe_ring_prod = ring_prod = 0; + for (i = 0; i < rx_ring_size; i++) { + if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) { + BNX2X_ERR("was only able to allocate " + "%d rx skbs on queue[%d]\n", i, fp->index); + fp->eth_q_stats.rx_skb_alloc_failed++; + break; + } + ring_prod = NEXT_RX_IDX(ring_prod); + cqe_ring_prod = NEXT_RCQ_IDX(cqe_ring_prod); + WARN_ON(ring_prod <= i); + } + + fp->rx_bd_prod = ring_prod; + /* Limit the CQE producer by the CQE ring size */ + fp->rx_comp_prod = min_t(u16, NUM_RCQ_RINGS*RCQ_DESC_CNT, + cqe_ring_prod); + fp->rx_pkt = fp->rx_calls = 0; + + return i; +} + +static inline void bnx2x_alloc_rx_bd_ring(struct bnx2x_fastpath *fp) +{ + struct bnx2x *bp = fp->bp; + int rx_ring_size = bp->rx_ring_size ? bp->rx_ring_size : + MAX_RX_AVAIL/bp->num_queues; + + rx_ring_size = max_t(int, MIN_RX_AVAIL, rx_ring_size); + + bnx2x_alloc_rx_bds(fp, rx_ring_size); + + /* Warning! + * this will generate an interrupt (to the TSTORM) + * must only be done after chip is initialized + */ + bnx2x_update_rx_prod(bp, fp, fp->rx_bd_prod, fp->rx_comp_prod, + fp->rx_sge_prod); +} + void bnx2x_init_rx_rings(struct bnx2x *bp) { int func = BP_FUNC(bp); int max_agg_queues = CHIP_IS_E1(bp) ? ETH_MAX_AGGREGATION_QUEUES_E1 : ETH_MAX_AGGREGATION_QUEUES_E1H; - u16 ring_prod, cqe_ring_prod; + u16 ring_prod; int i, j; - int rx_ring_size = bp->rx_ring_size ? bp->rx_ring_size : - MAX_RX_AVAIL/bp->num_queues; - rx_ring_size = max_t(int, MIN_RX_AVAIL, rx_ring_size); + bp->rx_buf_size = bp->dev->mtu + ETH_OVREHEAD + BNX2X_RX_ALIGN + + BNX2X_FW_IP_HDR_ALIGN_PAD; - bp->rx_buf_size = bp->dev->mtu + ETH_OVREHEAD + BNX2X_RX_ALIGN; DP(NETIF_MSG_IFUP, "mtu %d rx_buf_size %d\n", bp->dev->mtu, bp->rx_buf_size); - if (bp->flags & TPA_ENABLE_FLAG) { - - for_each_queue(bp, j) { - struct bnx2x_fastpath *fp = &bp->fp[j]; + for_each_queue(bp, j) { + struct bnx2x_fastpath *fp = |