diff options
Diffstat (limited to 'drivers/net/bnx2x')
-rw-r--r-- | drivers/net/bnx2x/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x.h | 166 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_cmn.c | 155 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_cmn.h | 73 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_dcb.c | 2118 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_dcb.h | 196 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_dump.h | 988 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_ethtool.c | 379 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_hsi.h | 327 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_init.h | 220 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_link.c | 666 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_link.h | 56 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_main.c | 770 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_reg.h | 126 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_stats.c | 18 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_stats.h | 2 |
16 files changed, 5382 insertions, 880 deletions
diff --git a/drivers/net/bnx2x/Makefile b/drivers/net/bnx2x/Makefile index 084afce89ae9..bb83a2961273 100644 --- a/drivers/net/bnx2x/Makefile +++ b/drivers/net/bnx2x/Makefile @@ -4,4 +4,4 @@ obj-$(CONFIG_BNX2X) += bnx2x.o -bnx2x-objs := bnx2x_main.o bnx2x_link.o bnx2x_cmn.o bnx2x_ethtool.o bnx2x_stats.o +bnx2x-objs := bnx2x_main.o bnx2x_link.o bnx2x_cmn.o bnx2x_ethtool.o bnx2x_stats.o bnx2x_dcb.o diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index d255428122fc..6a858a29db56 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -13,6 +13,8 @@ #ifndef BNX2X_H #define BNX2X_H +#include <linux/netdevice.h> +#include <linux/types.h> /* compilation time flags */ @@ -20,15 +22,17 @@ * (you will need to reboot afterwards) */ /* #define BNX2X_STOP_ON_ERROR */ -#define DRV_MODULE_VERSION "1.60.01-0" -#define DRV_MODULE_RELDATE "2010/11/12" +#define DRV_MODULE_VERSION "1.62.00-3" +#define DRV_MODULE_RELDATE "2010/12/21" #define BNX2X_BC_VER 0x040200 #define BNX2X_MULTI_QUEUE #define BNX2X_NEW_NAPI - +#if defined(CONFIG_DCB) +#define BCM_DCB +#endif #if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE) #define BCM_CNIC 1 #include "../cnic_if.h" @@ -48,6 +52,7 @@ #include "bnx2x_fw_defs.h" #include "bnx2x_hsi.h" #include "bnx2x_link.h" +#include "bnx2x_dcb.h" #include "bnx2x_stats.h" /* error/debug prints */ @@ -199,10 +204,25 @@ void bnx2x_panic_dump(struct bnx2x *bp); /* EQ completions */ #define HC_SP_INDEX_EQ_CONS 7 +/* FCoE L2 connection completions */ +#define HC_SP_INDEX_ETH_FCOE_TX_CQ_CONS 6 +#define HC_SP_INDEX_ETH_FCOE_RX_CQ_CONS 4 /* iSCSI L2 */ #define HC_SP_INDEX_ETH_ISCSI_CQ_CONS 5 #define HC_SP_INDEX_ETH_ISCSI_RX_CQ_CONS 1 +/* Special clients parameters */ + +/* SB indices */ +/* FCoE L2 */ +#define BNX2X_FCOE_L2_RX_INDEX \ + (&bp->def_status_blk->sp_sb.\ + index_values[HC_SP_INDEX_ETH_FCOE_RX_CQ_CONS]) + +#define BNX2X_FCOE_L2_TX_INDEX \ + (&bp->def_status_blk->sp_sb.\ + index_values[HC_SP_INDEX_ETH_FCOE_TX_CQ_CONS]) + /** * CIDs and CLIDs: * CLIDs below is a CLID for func 0, then the CLID for other @@ -215,12 +235,19 @@ void bnx2x_panic_dump(struct bnx2x *bp); #define BNX2X_ISCSI_ETH_CL_ID 17 #define BNX2X_ISCSI_ETH_CID 17 +/* FCoE L2 */ +#define BNX2X_FCOE_ETH_CL_ID 18 +#define BNX2X_FCOE_ETH_CID 18 + /** Additional rings budgeting */ #ifdef BCM_CNIC #define CNIC_CONTEXT_USE 1 +#define FCOE_CONTEXT_USE 1 #else #define CNIC_CONTEXT_USE 0 +#define FCOE_CONTEXT_USE 0 #endif /* BCM_CNIC */ +#define NONE_ETH_CONTEXT_USE (FCOE_CONTEXT_USE) #define AEU_IN_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR \ AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR @@ -401,6 +428,17 @@ struct bnx2x_fastpath { }; #define bnx2x_fp(bp, nr, var) (bp->fp[nr].var) +#ifdef BCM_CNIC +/* FCoE L2 `fastpath' is right after the eth entries */ +#define FCOE_IDX BNX2X_NUM_ETH_QUEUES(bp) +#define bnx2x_fcoe_fp(bp) (&bp->fp[FCOE_IDX]) +#define bnx2x_fcoe(bp, var) (bnx2x_fcoe_fp(bp)->var) +#define IS_FCOE_FP(fp) (fp->index == FCOE_IDX) +#define IS_FCOE_IDX(idx) ((idx) == FCOE_IDX) +#else +#define IS_FCOE_FP(fp) false +#define IS_FCOE_IDX(idx) false +#endif /* MC hsi */ @@ -598,6 +636,7 @@ struct bnx2x_common { #define CHIP_METAL(bp) (bp->common.chip_id & 0x00000ff0) #define CHIP_BOND_ID(bp) (bp->common.chip_id & 0x0000000f) +#define CHIP_PARITY_ENABLED(bp) (CHIP_IS_E1(bp) || CHIP_IS_E1H(bp)) int flash_size; #define NVRAM_1MB_SIZE 0x20000 /* 1M bit in bytes */ @@ -669,8 +708,14 @@ struct bnx2x_port { enum { CAM_ETH_LINE = 0, CAM_ISCSI_ETH_LINE, - CAM_MAX_PF_LINE = CAM_ISCSI_ETH_LINE + CAM_FIP_ETH_LINE, + CAM_FIP_MCAST_LINE, + CAM_MAX_PF_LINE = CAM_FIP_MCAST_LINE }; +/* number of MACs per function in NIG memory - used for SI mode */ +#define NIG_LLH_FUNC_MEM_SIZE 16 +/* number of entries in NIG_REG_LLHX_FUNC_MEM */ +#define NIG_LLH_FUNC_MEM_MAX_OFFSET 8 #define BNX2X_VF_ID_INVALID 0xFF @@ -710,6 +755,14 @@ enum { */ #define L2_FP_COUNT(cid_cnt) ((cid_cnt) - CNIC_CONTEXT_USE) +/* + * The number of FP-SB allocated by the driver == max number of regular L2 + * queues + 1 for the CNIC which also consumes an FP-SB + */ +#define FP_SB_COUNT(cid_cnt) ((cid_cnt) - FCOE_CONTEXT_USE) +#define NUM_IGU_SB_REQUIRED(cid_cnt) \ + (FP_SB_COUNT(cid_cnt) - NONE_ETH_CONTEXT_USE) + union cdu_context { struct eth_context eth; char pad[1024]; @@ -722,7 +775,8 @@ union cdu_context { #ifdef BCM_CNIC #define CNIC_ISCSI_CID_MAX 256 -#define CNIC_CID_MAX (CNIC_ISCSI_CID_MAX) +#define CNIC_FCOE_CID_MAX 2048 +#define CNIC_CID_MAX (CNIC_ISCSI_CID_MAX + CNIC_FCOE_CID_MAX) #define CNIC_ILT_LINES DIV_ROUND_UP(CNIC_CID_MAX, ILT_PAGE_CIDS) #endif @@ -770,6 +824,8 @@ struct bnx2x_slowpath { u32 wb_comp; u32 wb_data[4]; + /* pfc configuration for DCBX ramrod */ + struct flow_control_configuration pfc_config; }; #define bnx2x_sp(bp, var) (&bp->slowpath->var) @@ -918,6 +974,10 @@ struct bnx2x { #define DISABLE_MSI_FLAG 0x200 #define BP_NOMCP(bp) (bp->flags & NO_MCP_FLAG) #define MF_FUNC_DIS 0x1000 +#define FCOE_MACS_SET 0x2000 +#define NO_FCOE_FLAG 0x4000 + +#define NO_FCOE(bp) ((bp)->flags & NO_FCOE_FLAG) int pf_num; /* absolute PF number */ int pfid; /* per-path PF number */ @@ -967,6 +1027,8 @@ struct bnx2x { u16 mf_ov; u8 mf_mode; #define IS_MF(bp) (bp->mf_mode != 0) +#define IS_MF_SI(bp) (bp->mf_mode == MULTI_FUNCTION_SI) +#define IS_MF_SD(bp) (bp->mf_mode == MULTI_FUNCTION_SD) u8 wol; @@ -1010,6 +1072,7 @@ struct bnx2x { #define BNX2X_ACCEPT_ALL_UNICAST 0x0004 #define BNX2X_ACCEPT_ALL_MULTICAST 0x0008 #define BNX2X_ACCEPT_BROADCAST 0x0010 +#define BNX2X_ACCEPT_UNMATCHED_UCAST 0x0020 #define BNX2X_PROMISCUOUS_MODE 0x10000 u32 rx_mode; @@ -1062,7 +1125,8 @@ struct bnx2x { u16 cnic_kwq_pending; u16 cnic_spq_pending; struct mutex cnic_mutex; - u8 iscsi_mac[6]; + u8 iscsi_mac[ETH_ALEN]; + u8 fip_mac[ETH_ALEN]; #endif int dmae_ready; @@ -1122,6 +1186,31 @@ struct bnx2x { char fw_ver[32]; const struct firmware *firmware; + /* LLDP params */ + struct bnx2x_config_lldp_params lldp_config_params; + + /* DCB support on/off */ + u16 dcb_state; +#define BNX2X_DCB_STATE_OFF 0 +#define BNX2X_DCB_STATE_ON 1 + + /* DCBX engine mode */ + int dcbx_enabled; +#define BNX2X_DCBX_ENABLED_OFF 0 +#define BNX2X_DCBX_ENABLED_ON_NEG_OFF 1 +#define BNX2X_DCBX_ENABLED_ON_NEG_ON 2 +#define BNX2X_DCBX_ENABLED_INVALID (-1) + + bool dcbx_mode_uset; + + struct bnx2x_config_dcbx_params dcbx_config_params; + + struct bnx2x_dcbx_port_params dcbx_port_params; + int dcb_version; + + /* DCBX Negotation results */ + struct dcbx_features dcbx_local_feat; + u32 dcbx_error; }; /** @@ -1152,10 +1241,17 @@ struct bnx2x { #define RSS_IPV6_TCP_CAP 0x0008 #define BNX2X_NUM_QUEUES(bp) (bp->num_queues) +#define BNX2X_NUM_ETH_QUEUES(bp) (BNX2X_NUM_QUEUES(bp) - NONE_ETH_CONTEXT_USE) + +/* ethtool statistics are displayed for all regular ethernet queues and the + * fcoe L2 queue if not disabled + */ +#define BNX2X_NUM_STAT_QUEUES(bp) (NO_FCOE(bp) ? BNX2X_NUM_ETH_QUEUES(bp) : \ + (BNX2X_NUM_ETH_QUEUES(bp) + FCOE_CONTEXT_USE)) + #define is_multi(bp) (BNX2X_NUM_QUEUES(bp) > 1) #define BNX2X_MAX_QUEUES(bp) (bp->igu_sb_cnt - CNIC_CONTEXT_USE) -#define is_eth_multi(bp) (BNX2X_NUM_ETH_QUEUES(bp) > 1) #define RSS_IPV4_CAP_MASK \ TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY @@ -1248,6 +1344,7 @@ struct bnx2x_client_ramrod_params { u16 cl_id; u32 cid; u8 poll; +#define CLIENT_IS_FCOE 0x01 #define CLIENT_IS_LEADING_RSS 0x02 u8 flags; }; @@ -1280,11 +1377,54 @@ struct bnx2x_func_init_params { u16 spq_prod; /* valid iff FUNC_FLG_SPQ */ }; +#define for_each_eth_queue(bp, var) \ + for (var = 0; var < BNX2X_NUM_ETH_QUEUES(bp); var++) + +#define for_each_nondefault_eth_queue(bp, var) \ + for (var = 1; var < BNX2X_NUM_ETH_QUEUES(bp); var++) + +#define for_each_napi_queue(bp, var) \ + for (var = 0; \ + var < BNX2X_NUM_ETH_QUEUES(bp) + FCOE_CONTEXT_USE; var++) \ + if (skip_queue(bp, var)) \ + continue; \ + else + #define for_each_queue(bp, var) \ - for (var = 0; var < BNX2X_NUM_QUEUES(bp); var++) + for (var = 0; var < BNX2X_NUM_QUEUES(bp); var++) \ + if (skip_queue(bp, var)) \ + continue; \ + else + +#define for_each_rx_queue(bp, var) \ + for (var = 0; var < BNX2X_NUM_QUEUES(bp); var++) \ + if (skip_rx_queue(bp, var)) \ + continue; \ + else + +#define for_each_tx_queue(bp, var) \ + for (var = 0; var < BNX2X_NUM_QUEUES(bp); var++) \ + if (skip_tx_queue(bp, var)) \ + continue; \ + else + #define for_each_nondefault_queue(bp, var) \ - for (var = 1; var < BNX2X_NUM_QUEUES(bp); var++) + for (var = 1; var < BNX2X_NUM_QUEUES(bp); var++) \ + if (skip_queue(bp, var)) \ + continue; \ + else + +/* skip rx queue + * if FCOE l2 support is diabled and this is the fcoe L2 queue + */ +#define skip_rx_queue(bp, idx) (NO_FCOE(bp) && IS_FCOE_IDX(idx)) +/* skip tx queue + * if FCOE l2 support is diabled and this is the fcoe L2 queue + */ +#define skip_tx_queue(bp, idx) (NO_FCOE(bp) && IS_FCOE_IDX(idx)) + +#define skip_queue(bp, idx) (NO_FCOE(bp) && IS_FCOE_IDX(idx)) #define WAIT_RAMROD_POLL 0x01 #define WAIT_RAMROD_COMMON 0x02 @@ -1329,7 +1469,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define BNX2X_ILT_ZALLOC(x, y, size) \ do { \ - x = pci_alloc_consistent(bp->pdev, size, y); \ + x = dma_alloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \ if (x) \ memset(x, 0, size); \ } while (0) @@ -1337,7 +1477,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define BNX2X_ILT_FREE(x, y, size) \ do { \ if (x) { \ - pci_free_consistent(bp->pdev, size, x, y); \ + dma_free_coherent(&bp->pdev->dev, size, x, y); \ x = NULL; \ y = 0; \ } \ @@ -1608,10 +1748,6 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, 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) - - /* Number of u32 elements in MC hash array */ #define MC_HASH_SIZE 8 #define MC_HASH_OFFSET(bp, i) (BAR_TSTRORM_INTMEM + \ diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 0af361e4e3d1..710ce5d04c53 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -698,6 +698,29 @@ void bnx2x_release_phy_lock(struct bnx2x *bp) mutex_unlock(&bp->port.phy_mutex); } +/* calculates MF speed according to current linespeed and MF configuration */ +u16 bnx2x_get_mf_speed(struct bnx2x *bp) +{ + u16 line_speed = bp->link_vars.line_speed; + if (IS_MF(bp)) { + u16 maxCfg = (bp->mf_config[BP_VN(bp)] & + FUNC_MF_CFG_MAX_BW_MASK) >> + FUNC_MF_CFG_MAX_BW_SHIFT; + /* Calculate the current MAX line speed limit for the DCC + * capable devices + */ + if (IS_MF_SD(bp)) { + u16 vn_max_rate = maxCfg * 100; + + if (vn_max_rate < line_speed) + line_speed = vn_max_rate; + } else /* IS_MF_SI(bp)) */ + line_speed = (line_speed * maxCfg) / 100; + } + + return line_speed; +} + void bnx2x_link_report(struct bnx2x *bp) { if (bp->flags & MF_FUNC_DIS) { @@ -713,17 +736,8 @@ void bnx2x_link_report(struct bnx2x *bp) netif_carrier_on(bp->dev); netdev_info(bp->dev, "NIC Link is Up, "); - line_speed = bp->link_vars.line_speed; - if (IS_MF(bp)) { - u16 vn_max_rate; + line_speed = bnx2x_get_mf_speed(bp); - vn_max_rate = - ((bp->mf_config[BP_VN(bp)] & - FUNC_MF_CFG_MAX_BW_MASK) >> - FUNC_MF_CFG_MAX_BW_SHIFT) * 100; - if (vn_max_rate < line_speed) - line_speed = vn_max_rate; - } pr_cont("%d Mbps ", line_speed); if (bp->link_vars.duplex == DUPLEX_FULL) @@ -813,7 +827,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) DP(NETIF_MSG_IFUP, "mtu %d rx_buf_size %d\n", bp->dev->mtu, bp->rx_buf_size); - for_each_queue(bp, j) { + for_each_rx_queue(bp, j) { struct bnx2x_fastpath *fp = &bp->fp[j]; if (!fp->disable_tpa) { @@ -866,7 +880,7 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) } } - for_each_queue(bp, j) { + for_each_rx_queue(bp, j) { struct bnx2x_fastpath *fp = &bp->fp[j]; fp->rx_bd_cons = 0; @@ -897,7 +911,7 @@ static void bnx2x_free_tx_skbs(struct bnx2x *bp) { int i; - for_each_queue(bp, i) { + for_each_tx_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; u16 bd_cons = fp->tx_bd_cons; @@ -915,7 +929,7 @@ static void bnx2x_free_rx_skbs(struct bnx2x *bp) { int i, j; - for_each_queue(bp, j) { + for_each_rx_queue(bp, j) { struct bnx2x_fastpath *fp = &bp->fp[j]; for (i = 0; i < NUM_RX_BD; i++) { @@ -956,7 +970,7 @@ static void bnx2x_free_msix_irqs(struct bnx2x *bp) #ifdef BCM_CNIC offset++; #endif - for_each_queue(bp, i) { + for_each_eth_queue(bp, i) { DP(NETIF_MSG_IFDOWN, "about to release fp #%d->%d irq " "state %x\n", i, bp->msix_table[i + offset].vector, bnx2x_fp(bp, i, state)); @@ -990,14 +1004,14 @@ int bnx2x_enable_msix(struct bnx2x *bp) bp->msix_table[msix_vec].entry, bp->msix_table[msix_vec].entry); msix_vec++; #endif - for_each_queue(bp, i) { + for_each_eth_queue(bp, i) { bp->msix_table[msix_vec].entry = msix_vec; DP(NETIF_MSG_IFUP, "msix_table[%d].entry = %d " "(fastpath #%u)\n", msix_vec, msix_vec, i); msix_vec++; } - req_cnt = BNX2X_NUM_QUEUES(bp) + CNIC_CONTEXT_USE + 1; + req_cnt = BNX2X_NUM_ETH_QUEUES(bp) + CNIC_CONTEXT_USE + 1; rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], req_cnt); @@ -1053,7 +1067,7 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp) #ifdef BCM_CNIC offset++; #endif - for_each_queue(bp, i) { + for_each_eth_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; snprintf(fp->name, sizeof(fp->name), "%s-fp-%d", bp->dev->name, i); @@ -1070,7 +1084,7 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp) fp->state = BNX2X_FP_STATE_IRQ; } - i = BNX2X_NUM_QUEUES(bp); + i = BNX2X_NUM_ETH_QUEUES(bp); offset = 1 + CNIC_CONTEXT_USE; netdev_info(bp->dev, "using MSI-X IRQs: sp %d fp[%d] %d" " ... fp[%d] %d\n", @@ -1117,7 +1131,7 @@ static void bnx2x_napi_enable(struct bnx2x *bp) { int i; - for_each_queue(bp, i) + for_each_napi_queue(bp, i) napi_enable(&bnx2x_fp(bp, i, napi)); } @@ -1125,7 +1139,7 @@ static void bnx2x_napi_disable(struct bnx2x *bp) { int i; - for_each_queue(bp, i) + for_each_napi_queue(bp, i) napi_disable(&bnx2x_fp(bp, i, napi)); } @@ -1153,6 +1167,35 @@ void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw) netif_tx_disable(bp->dev); } +u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb) +{ +#ifdef BCM_CNIC + struct bnx2x *bp = netdev_priv(dev); + if (NO_FCOE(bp)) + return skb_tx_hash(dev, skb); + else { + struct ethhdr *hdr = (struct ethhdr *)skb->data; + u16 ether_type = ntohs(hdr->h_proto); + + /* Skip VLAN tag if present */ + if (ether_type == ETH_P_8021Q) { + struct vlan_ethhdr *vhdr = + (struct vlan_ethhdr *)skb->data; + + ether_type = ntohs(vhdr->h_vlan_encapsulated_proto); + } + + /* If ethertype is FCoE or FIP - use FCoE ring */ + if ((ether_type == ETH_P_FCOE) || (ether_type == ETH_P_FIP)) + return bnx2x_fcoe(bp, index); + } +#endif + /* Select a none-FCoE queue: if FCoE is enabled, exclude FCoE L2 ring + */ + return __skb_tx_hash(dev, skb, + dev->real_num_tx_queues - FCOE_CONTEXT_USE); +} + void bnx2x_set_num_queues(struct bnx2x *bp) { switch (bp->multi_mode) { @@ -1167,7 +1210,22 @@ void bnx2x_set_num_queues(struct bnx2x *bp) bp->num_queues = 1; break; } + + /* Add special queues */ + bp->num_queues += NONE_ETH_CONTEXT_USE; +} + +#ifdef BCM_CNIC +static inline void bnx2x_set_fcoe_eth_macs(struct bnx2x *bp) +{ + if (!NO_FCOE(bp)) { + if (!IS_MF_SD(bp)) + bnx2x_set_fip_eth_mac_addr(bp, 1); + bnx2x_set_all_enode_macs(bp, 1); + bp->flags |= FCOE_MACS_SET; + } } +#endif static void bnx2x_release_firmware(struct bnx2x *bp) { @@ -1177,6 +1235,20 @@ static void bnx2x_release_firmware(struct bnx2x *bp) release_firmware(bp->firmware); } +static inline int bnx2x_set_real_num_queues(struct bnx2x *bp) +{ + int rc, num = bp->num_queues; + +#ifdef BCM_CNIC + if (NO_FCOE(bp)) + num -= FCOE_CONTEXT_USE; + +#endif + netif_set_real_num_tx_queues(bp->dev, num); + rc = netif_set_real_num_rx_queues(bp->dev, num); + return rc; +} + /* must be called with rtnl_lock */ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) { @@ -1203,10 +1275,9 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) if (bnx2x_alloc_mem(bp)) return -ENOMEM; - netif_set_real_num_tx_queues(bp->dev, bp->num_queues); - rc = netif_set_real_num_rx_queues(bp->dev, bp->num_queues); + rc = bnx2x_set_real_num_queues(bp); if (rc) { - BNX2X_ERR("Unable to update real_num_rx_queues\n"); + BNX2X_ERR("Unable to set real_num_queues\n"); goto load_error0; } @@ -1214,6 +1285,10 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) bnx2x_fp(bp, i, disable_tpa) = ((bp->flags & TPA_ENABLE_FLAG) == 0); +#ifdef BCM_CNIC + /* We don't want TPA on FCoE L2 ring */ + bnx2x_fcoe(bp, disable_tpa) = 1; +#endif bnx2x_napi_enable(bp); /* Send LOAD_REQUEST command to MCP @@ -1296,6 +1371,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) } } + bnx2x_dcbx_init(bp); + bp->state = BNX2X_STATE_OPENING_WAIT4_PORT; rc = bnx2x_func_start(bp); @@ -1344,6 +1421,10 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) /* Now when Clients are configured we are ready to work */ bp->state = BNX2X_STATE_OPEN; +#ifdef BCM_CNIC + bnx2x_set_fcoe_eth_macs(bp); +#endif + bnx2x_set_eth_mac(bp, 1); if (bp->port.pmf) @@ -1402,7 +1483,7 @@ load_error3: /* Free SKBs, SGEs, TPA pool and driver internals */ bnx2x_free_skbs(bp); - for_each_queue(bp, i) + for_each_rx_queue(bp, i) bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); /* Release IRQs */ @@ -1473,7 +1554,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) /* Free SKBs, SGEs, TPA pool and driver internals */ bnx2x_free_skbs(bp); - for_each_queue(bp, i) + for_each_rx_queue(bp, i) bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); bnx2x_free_mem(bp); @@ -1577,6 +1658,17 @@ int bnx2x_poll(struct napi_struct *napi, int budget) /* Fall out from the NAPI loop if needed */ if (!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) { +#ifdef BCM_CNIC + /* No need to update SB for FCoE L2 ring as long as + * it's connected to the default SB and the SB + * has been updated when NAPI was scheduled. + */ + if (IS_FCOE_FP(fp)) { + napi_complete(napi); + break; + } +#endif + bnx2x_update_fpsb_idx(fp); /* bnx2x_has_rx_work() reads the status block, * thus we need to ensure that status block indices @@ -1692,11 +1784,10 @@ static inline u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb) } } - if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) - rc |= (XMIT_GSO_V4 | XMIT_CSUM_V4 | XMIT_CSUM_TCP); - - else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) - rc |= (XMIT_GSO_V6 | XMIT_CSUM_TCP | XMIT_CSUM_V6); + if (skb_is_gso_v6(skb)) + rc |= XMIT_GSO_V6 | XMIT_CSUM_TCP | XMIT_CSUM_V6; + else if (skb_is_gso(skb)) + rc |= XMIT_GSO_V4 | XMIT_CSUM_V4 | XMIT_CSUM_TCP; return rc; } @@ -2242,7 +2333,7 @@ int __devinit bnx2x_alloc_mem_bp(struct bnx2x *bp) bp->fp = fp; /* msix table */ - tbl = kzalloc((bp->l2_cid_count + 1) * sizeof(*tbl), + tbl = kzalloc((FP_SB_COUNT(bp->l2_cid_count) + 1) * sizeof(*tbl), GFP_KERNEL); if (!tbl) goto alloc_err; diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 6b28739c5302..03eb4d68e6bb 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -73,6 +73,16 @@ void bnx2x__link_status_update(struct bnx2x *bp); void bnx2x_link_report(struct bnx2x *bp); /** + * calculates MF speed according to current linespeed and MF + * configuration + * + * @param bp + * + * @return u16 + */ +u16 bnx2x_get_mf_speed(struct bnx2x *bp); + +/** * MSI-X slowpath interrupt handler * * @param irq @@ -232,6 +242,30 @@ int bnx2x_release_hw_lock(struct bnx2x *bp, u32 resource); */ void bnx2x_set_eth_mac(struct bnx2x *bp, int set); +#ifdef BCM_CNIC +/** + * Set/Clear FIP MAC(s) at the next enties in the CAM after the ETH + * MAC(s). This function will wait until the ramdord completion + * returns. + * + * @param bp driver handle + * @param set set or clear the CAM entry + * + * @return 0 if cussess, -ENODEV if ramrod doesn't return. + */ +int bnx2x_set_fip_eth_mac_addr(struct bnx2x *bp, int set); + +/** + * Set/Clear ALL_ENODE mcast MAC. + * + * @param bp + * @param set + * + * @return int + */ +int bnx2x_set_all_enode_macs(struct bnx2x *bp, int set); +#endif + /** * Set MAC filtering configurations. * @@ -290,6 +324,13 @@ int bnx2x_func_start(struct bnx2x *bp); void bnx2x_ilt_set_info(struct bnx2x *bp); /** + * Inintialize dcbx protocol + * + * @param bp + */ +void bnx2x_dcbx_init(struct bnx2x *bp); + +/** * Set power state to the requested value. Currently only D0 and * D3hot are supported. * @@ -309,6 +350,9 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode); /* hard_xmit callback */ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev); +/* select_queue callback */ +u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb); + int bnx2x_change_mac_addr(struct net_device *dev, void *p); /* NAPI poll Rx part */ @@ -685,7 +729,7 @@ static inline void bnx2x_add_all_napi(struct bnx2x *bp) int i; /* Add NAPI objects */ - for_each_queue(bp, i) + for_each_napi_queue(bp, i) netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), bnx2x_poll, BNX2X_NAPI_WEIGHT); } @@ -694,7 +738,7 @@ static inline void bnx2x_del_all_napi(struct bnx2x *bp) { int i; - for_each_queue(bp, i) + for_each_napi_queue(bp, i) netif_napi_del(&bnx2x_fp(bp, i, napi)); } @@ -860,7 +904,7 @@ static inline void bnx2x_init_tx_rings(struct bnx2x *bp) { int i, j; - for_each_queue(bp, j) { + for_each_tx_queue(bp, j) { struct bnx2x_fastpath *fp = &bp->fp[j]; for (i = 1; i <= NUM_TX_RINGS; i++) { @@ -939,7 +983,30 @@ static inline void bnx2x_set_next_page_rx_cq(struct bnx2x_fastpath *fp) } } +#ifdef BCM_CNIC +static inline void bnx2x_init_fcoe_fp(struct bnx2x *bp) +{ + bnx2x_fcoe(bp, cl_id) = BNX2X_FCOE_ETH_CL_ID + + BP_E1HVN(bp) * NONE_ETH_CONTEXT_USE; + bnx2x_fcoe(bp, cid) = BNX2X_FCOE_ETH_CID; + bnx2x_fcoe(bp, fw_sb_id) = DEF_SB_ID; + bnx2x_fcoe(bp, igu_sb_id) = bp->igu_dsb_id; + bnx2x_fcoe(bp, bp) = bp; + bnx2x_fcoe(bp, state) = BNX2X_FP_STATE_CLOSED; + bnx2x_fcoe(bp, index) = FCOE_IDX; + bnx2x_fcoe(bp, rx_cons_sb) = BNX2X_FCOE_L2_RX_INDEX; + bnx2x_fcoe(bp, tx_cons_sb) = BNX2X_FCOE_L2_TX_INDEX; + /* qZone id equals to FW (per path) client id */ + bnx2x_fcoe(bp, cl_qzone_id) = bnx2x_fcoe(bp, cl_id) + + BP_PORT(bp)*(CHIP_IS_E2(bp) ? ETH_MAX_RX_CLIENTS_E2 : + ETH_MAX_RX_CLIENTS_E1H); + /* init shortcut */ + bnx2x_fcoe(bp, ustorm_rx_prods_offset) = CHIP_IS_E2(bp) ? + USTORM_RX_PRODS_E2_OFFSET(bnx2x_fcoe(bp, cl_qzone_id)) : + USTORM_RX_PRODS_E1X_OFFSET(BP_PORT(bp), bnx2x_fcoe_fp(bp)->cl_id); +} +#endif static inline void __storm_memset_struct(struct bnx2x *bp, u32 addr, size_t size, u32 *data) diff --git a/drivers/net/bnx2x/bnx2x_dcb.c b/drivers/net/bnx2x/bnx2x_dcb.c new file mode 100644 index 000000000000..fb60021f81fb --- /dev/null +++ b/drivers/net/bnx2x/bnx2x_dcb.c @@ -0,0 +1,2118 @@ +/* bnx2x_dcb.c: Broadcom Everest network driver. + * + * Copyright 2009-2010 Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2, available + * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL"). + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a + * license other than the GPL, without Broadcom's express prior written + * consent. + * + * Maintained by: Eilon Greenstein <eilong@broadcom.com> + * Written by: Dmitry Kravkov + * + */ +#include <linux/netdevice.h> +#include <linux/types.h> +#include <linux/errno.h> + +#include "bnx2x.h" +#include "bnx2x_cmn.h" +#include "bnx2x_dcb.h" + + +/* forward declarations of dcbx related functions */ +static void bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp); +static void bnx2x_pfc_set_pfc(struct bnx2x *bp); +static void bnx2x_dcbx_update_ets_params(struct bnx2x *bp); +static void bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp); +static void bnx2x_dcbx_get_ets_pri_pg_tbl(struct bnx2x *bp, + u32 *set_configuration_ets_pg, + u32 *pri_pg_tbl); +static void bnx2x_dcbx_get_num_pg_traf_type(struct bnx2x *bp, + u32 *pg_pri_orginal_spread, + struct pg_help_data *help_data); +static void bnx2x_dcbx_fill_cos_params(struct bnx2x *bp, + struct pg_help_data *help_data, + struct dcbx_ets_feature *ets, + u32 *pg_pri_orginal_spread); +static void bnx2x_dcbx_separate_pauseable_from_non(struct bnx2x *bp, + struct cos_help_data *cos_data, + u32 *pg_pri_orginal_spread, + struct dcbx_ets_feature *ets); +static void bnx2x_pfc_fw_struct_e2(struct bnx2x *bp); + + +static void bnx2x_pfc_set(struct bnx2x *bp) +{ + struct bnx2x_nig_brb_pfc_port_params pfc_params = {0}; + u32 pri_bit, val = 0; + u8 pri; + + /* Tx COS configuration */ + if (bp->dcbx_port_params.ets.cos_params[0].pauseable) + pfc_params.rx_cos0_priority_mask = + bp->dcbx_port_params.ets.cos_params[0].pri_bitmask; + if (bp->dcbx_port_params.ets.cos_params[1].pauseable) + pfc_params.rx_cos1_priority_mask = + bp->dcbx_port_params.ets.cos_params[1].pri_bitmask; + + + /** + * Rx COS configuration + * Changing PFC RX configuration . + * In RX COS0 will always be configured to lossy and COS1 to lossless + */ + for (pri = 0 ; pri < MAX_PFC_PRIORITIES ; pri++) { + pri_bit = 1 << pri; + + if (pri_bit & DCBX_PFC_PRI_PAUSE_MASK(bp)) + val |= 1 << (pri * 4); + } + + pfc_params.pkt_priority_to_cos = val; + + /* RX COS0 */ + pfc_params.llfc_low_priority_classes = 0; + /* RX COS1 */ + pfc_params.llfc_high_priority_classes = DCBX_PFC_PRI_PAUSE_MASK(bp); + + /* BRB configuration */ + pfc_params.cos0_pauseable = false; + pfc_params.cos1_pauseable = true; + + bnx2x_acquire_phy_lock(bp); + bp->link_params.feature_config_flags |= FEATURE_CONFIG_PFC_ENABLED; + bnx2x_update_pfc(&bp->link_params, &bp->link_vars, &pfc_params); + bnx2x_release_phy_lock(bp); +} + +static void bnx2x_pfc_clear(struct bnx2x *bp) +{ + struct bnx2x_nig_brb_pfc_port_params nig_params = {0}; + nig_params.pause_enable = 1; +#ifdef BNX2X_SAFC + if (bp->flags & SAFC_TX_FLAG) { + u32 high = 0, low = 0; + int i; + + for (i = 0; i < BNX2X_MAX_PRIORITY; i++) { + if (bp->pri_map[i] == 1) + high |= (1 << i); + if (bp->pri_map[i] == 0) + low |= (1 << i); + } + + nig_params.llfc_low_priority_classes = high; + nig_params.llfc_low_priority_classes = low; + + nig_params.pause_enable = 0; + nig_params.llfc_enable = 1; + nig_params.llfc_out_en = 1; + } +#endif /* BNX2X_SAFC */ + bnx2x_acquire_phy_lock(bp); + bp->link_params.feature_config_flags &= ~FEATURE_CONFIG_PFC_ENABLED; + bnx2x_update_pfc(&bp->link_params, &bp->link_vars, &nig_params); + bnx2x_release_phy_lock(bp); +} + +static void bnx2x_dump_dcbx_drv_param(struct bnx2x *bp, + struct dcbx_features *features, + u32 error) +{ + u8 i = 0; + DP(NETIF_MSG_LINK, "local_mib.error %x\n", error); + + /* PG */ + DP(NETIF_MSG_LINK, + "local_mib.features.ets.enabled %x\n", features->ets.enabled); + for (i = 0; i < DCBX_MAX_NUM_PG_BW_ENTRIES; i++) + DP(NETIF_MSG_LINK, + "local_mib.features.ets.pg_bw_tbl[%d] %d\n", i, + DCBX_PG_BW_GET(features->ets.pg_bw_tbl, i)); + for (i = 0; i < DCBX_MAX_NUM_PRI_PG_ENTRIES; i++) + DP(NETIF_MSG_LINK, + "local_mib.features.ets.pri_pg_tbl[%d] %d\n", i, + DCBX_PRI_PG_GET(features->ets.pri_pg_tbl, i)); + + /* pfc */ + DP(NETIF_MSG_LINK, "dcbx_features.pfc.pri_en_bitmap %x\n", + features->pfc.pri_en_bitmap); + DP(NETIF_MSG_LINK, "dcbx_features.pfc.pfc_caps %x\n", + features->pfc.pfc_caps); + DP(NETIF_MSG_LINK, "dcbx_features.pfc.enabled %x\n", + features->pfc.enabled); + + DP(NETIF_MSG_LINK, "dcbx_features.app.default_pri %x\n", + features->app.default_pri); + DP(NETIF_MSG_LINK, "dcbx_features.app.tc_supported %x\n", + features->app.tc_supported); + DP(NETIF_MSG_LINK, "dcbx_features.app.enabled %x\n", + features->app.enabled); + for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++) { + DP(NETIF_MSG_LINK, + "dcbx_features.app.app_pri_tbl[%x].app_id %x\n", + i, features->app.app_pri_tbl[i].app_id); + DP(NETIF_MSG_LINK, + "dcbx_features.app.app_pri_tbl[%x].pri_bitmap %x\n", + i, features->app.app_pri_tbl[i].pri_bitmap); + DP(NETIF_MSG_LINK, + "dcbx_features.app.app_pri_tbl[%x].appBitfield %x\n", + i, features->app.app_pri_tbl[i].appBitfield); + } +} + +static void bnx2x_dcbx_get_ap_priority(struct bnx2x *bp, + u8 pri_bitmap, + u8 llfc_traf_type) +{ + u32 pri = MAX_PFC_PRIORITIES; + u32 index = MAX_PFC_PRIORITIES - 1; + u32 pri_mask; + u32 *ttp = bp->dcbx_port_params.app.traffic_type_priority; + + /* Choose the highest priority */ + while ((MAX_PFC_PRIORITIES == pri) && (0 != index)) { + pri_mask = 1 << index; + if (GET_FLAGS(pri_bitmap, pri_mask)) + pri = index ; + index--; + } + + if (pri < MAX_PFC_PRIORITIES) + ttp[llfc_traf_type] = max_t(u32, ttp[llfc_traf_type], pri); +} + +static void bnx2x_dcbx_get_ap_feature(struct bnx2x *bp, + struct dcbx_app_priority_feature *app, + u32 error) { + u8 index; + u32 *ttp = bp->dcbx_port_params.app.traffic_type_priority; + + if (GET_FLAGS(error, DCBX_LOCAL_APP_ERROR)) + DP(NETIF_MSG_LINK, "DCBX_LOCAL_APP_ERROR\n"); + + if (app->enabled && !GET_FLAGS(error, DCBX_LOCAL_APP_ERROR)) { + + bp->dcbx_port_params.app.enabled = true; + + for (index = 0 ; index < LLFC_DRIVER_TRAFFIC_TYPE_MAX; index++) + ttp[index] = 0; + + if (app->default_pri < MAX_PFC_PRIORITIES) + ttp[LLFC_TRAFFIC_TYPE_NW] = app->default_pri; + + for (index = 0 ; index < DCBX_MAX_APP_PROTOCOL; index++) { + struct dcbx_app_priority_entry *entry = + app->app_pri_tbl; + + if (GET_FLAGS(entry[index].appBitfield, + DCBX_APP_SF_ETH_TYPE) && + ETH_TYPE_FCOE == entry[index].app_id) + bnx2x_dcbx_get_ap_priority(bp, + entry[index].pri_bitmap, + LLFC_TRAFFIC_TYPE_FCOE); + + if (GET_FLAGS(entry[index].appBitfield, + DCBX_APP_SF_PORT) && + TCP_PORT_ISCSI == entry[index].app_id) + bnx2x_dcbx_get_ap_priority(bp, + entry[index].pri_bitmap, + LLFC_TRAFFIC_TYPE_ISCSI); + } + } else { + DP(NETIF_MSG_LINK, "DCBX_LOCAL_APP_DISABLED\n"); + bp->dcbx_port_params.app.enabled = false; + for (index = 0 ; index < LLFC_DRIVER_TRAFFIC_TYPE_MAX; index++) + ttp[index] = INVALID_TRAFFIC_TYPE_PRIORITY; + } +} + +static void bnx2x_dcbx_get_ets_feature(struct bnx2x *bp, + struct dcbx_ets_feature *ets, + u32 error) { + int i = 0; + u32 pg_pri_orginal_spread[DCBX_MAX_NUM_PG_BW_ENTRIES] = {0}; + struct pg_help_data pg_help_data; + struct bnx2x_dcbx_cos_params *cos_params = + bp->dcbx_port_params.ets.cos_params; + + memset(&pg_help_data, 0, sizeof(struct pg_help_data)); + + + if (GET_FLAGS(error, DCBX_LOCAL_ETS_ERROR)) + DP(NETIF_MSG_LINK, "DCBX_LOCAL_ETS_ERROR\n"); + + + /* Clean up old settings of ets on COS */ + for (i = 0; i < E2_NUM_OF_COS ; i++) { + + cos_params[i].pauseable = false; + cos_params[i].strict = BNX2X_DCBX_COS_NOT_STRICT; + cos_params[i].bw_tbl = DCBX_INVALID_COS_BW; + cos_params[i].pri_bitmask = DCBX_PFC_PRI_GET_NON_PAUSE(bp, 0); + } + + if (bp->dcbx_port_params.app.enabled && + !GET_FLAGS(error, DCBX_LOCAL_ETS_ERROR) && + ets->enabled) { + DP(NETIF_MSG_LINK, "DCBX_LOCAL_ETS_ENABLE\n"); + bp->dcbx_port_params.ets.enabled = true; + + bnx2x_dcbx_get_ets_pri_pg_tbl(bp, + pg_pri_orginal_spread, + ets->pri_pg_tbl); + + bnx2x_dcbx_get_num_pg_traf_type(bp, + pg_pri_orginal_spread, + &pg_help_data); + + bnx2x_dcbx_fill_cos_params(bp, &pg_help_data, + ets, pg_pri_orginal_spread); + + } else { + DP(NETIF_MSG_LINK, "DCBX_LOCAL_ETS_DISABLED\n"); + bp->dcbx_port_params.ets.enabled = false; + ets->pri_pg_tbl[0] = 0; + + for (i = 0; i < DCBX_MAX_NUM_PRI_PG_ENTRIES ; i++) + DCBX_PG_BW_SET(ets->pg_bw_tbl, i, 1); + } +} + +static void bnx2x_dcbx_get_pfc_feature(struct bnx2x *bp, + struct dcbx_pfc_feature *pfc, u32 error) +{ + + if (GET_FLAGS(error, DCBX_LOCAL_PFC_ERROR)) + DP(NETIF_MSG_LINK, "DCBX_LOCAL_PFC_ERROR\n"); + + if (bp->dcbx_port_params.app.enabled && + !GET_FLAGS(error, DCBX_LOCAL_PFC_ERROR) && + pfc->enabled) { + bp->dcbx_port_params.pfc.enabled = true; + bp->dcbx_port_params.pfc.priority_non_pauseable_mask = + ~(pfc->pri_en_bitmap); + } else { + DP(NETIF_MSG_LINK, "DCBX_LOCAL_PFC_DISABLED\n"); + bp->dcbx_port_params.pfc.enabled = false; + bp->dcbx_port_params.pfc.priority_non_pauseable_mask = 0; + } +} + +static void bnx2x_get_dcbx_drv_param(struct bnx2x *bp, + struct dcbx_features *features, + u32 error) +{ + bnx2x_dcbx_get_ap_feature(bp, &features->app, error); + + bnx2x_dcbx_get_pfc_feature(bp, &features->pfc, error); + + bnx2x_dcbx_get_ets_feature(bp, &features->ets, error); +} + +#define DCBX_LOCAL_MIB_MAX_TRY_READ (100) +static int bnx2x_dcbx_read_mib(struct bnx2x *bp, + u32 *base_mib_addr, + u32 offset, + int read_mib_type) +{ + int max_try_read = 0, i; + u32 *buff, mib_size, prefix_seq_num, suffix_seq_num; + struct lldp_remote_mib *remote_mib ; + struct lldp_local_mib *local_mib; + + + switch (read_mib_type) { + case DCBX_READ_LOCAL_MIB: + mib_size = sizeof(struct lldp_local_mib); + break; + case DCBX_READ_REMOTE_MIB: + mib_size = sizeof(struct lldp_remote_mib); + break; + default: + return 1; /*error*/ + } + + offset += BP_PORT(bp) * mib_size; + + do { + buff = base_mib_addr; + for (i = 0; i < mib_size; i += 4, buff++) + *buff = REG_RD(bp, offset + i); + + max_try_read++; + + switch (read_mib_type) { + case DCBX_READ_LOCAL_MIB: + local_mib = (struct lldp_local_mib *) base_mib_addr; + prefix_seq_num = local_mib->prefix_seq_num; + suffix_seq_num = local_mib->suffix_seq_num; + break; + case DCBX_READ_REMOTE_MIB: + remote_mib = (struct lldp_remote_mib *) base_mib_addr; + prefix_seq_num = remote_mib->prefix_seq_num; + suffix_seq_num = remote_mib->suffix_seq_num; + break; + default: + return 1; /*error*/ + } + } while ((prefix_seq_num != suffix_seq_num) && + (max_try_read < DCBX_LOCAL_MIB_MAX_TRY_READ)); + + if (max_try_read >= DCBX_LOCAL_MIB_MAX_TRY_READ) { + BNX2X_ERR("MIB could not be read\n"); + return 1; + } + + return 0; +} + +static void bnx2x_pfc_set_pfc(struct bnx2x *bp) +{ + if (CHIP_IS_E2(bp)) { + if (BP_PORT(bp)) { + BNX2X_ERR("4 port mode is not supported"); + return; + } + + if (bp->dcbx_port_params.pfc.enabled) + + /* 1. Fills up common PFC structures if required.*/ + /* 2. Configure NIG, MAC and BRB via the elink: + * elink must first check if BMAC is not in reset + * and only then configures the BMAC + * Or, configure EMAC. + */ + bnx2x_pfc_set(bp); + + else + bnx2x_pfc_clear(bp); + } +} + +static void bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp) +{ + DP(NETIF_MSG_LINK, "sending STOP TRAFFIC\n"); + bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_STOP_TRAFFIC, + 0 /* connectionless */, + 0 /* dataHi is zero */, + 0 /* dataLo is zero */, + 1 /* common */); +} + +static void bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp) +{ + bnx2x_pfc_fw_struct_e2(bp); + DP(NETIF_MSG_LINK, "sending START TRAFFIC\n"); + bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_START_TRAFFIC, + 0, /* connectionless */ + U64_HI(bnx2x_sp_mapping(bp, pfc_config)), + U64_LO(bnx2x_sp_mapping(bp, pfc_config)), + 1 /* commmon */); +} + +static void bnx2x_dcbx_update_ets_params(struct bnx2x *bp) +{ + struct bnx2x_dcbx_pg_params *ets = &(bp->dcbx_port_params.ets); + u8 status = 0; + + bnx2x_ets_disabled(&bp->link_params); + + if (!ets->enabled) + return; + + if ((ets->num_of_cos == 0) || (ets->num_of_cos > E2_NUM_OF_COS)) { + BNX2X_ERR("illegal num of cos= %x", ets->num_of_cos); + return; + } + + /* valid COS entries */ + if (ets->num_of_cos == 1) /* no ETS */ + return; + + /* sanity */ + if (((BNX2X_DCBX_COS_NOT_STRICT == ets->cos_params[0].strict) && + (DCBX_INVALID_COS_BW == ets->cos_params[0].bw_tbl)) || + ((BNX2X_DCBX_COS_NOT_STRICT == ets->cos_params[1].strict) && + (DCBX_INVALID_COS_BW == ets->cos_params[1].bw_tbl))) { + BNX2X_ERR("all COS should have at least bw_limit or strict" + "ets->cos_params[0].strict= %x" + "ets->cos_params[0].bw_tbl= %x" + "ets->cos_params[1].strict= %x" + "ets->cos_params[1].bw_tbl= %x", + ets->cos_params[0].strict, + ets->cos_params[0].bw_tbl, + ets->cos_params[1].strict, + ets->cos_params[1].bw_tbl); + return; + } + /* If we join a group and there is bw_tbl and strict then bw rules */ + if ((DCBX_INVALID_COS_BW != ets->cos_params[0].bw_tbl) && + (DCBX_INVALID_COS_BW != ets->cos_params[1].bw_tbl)) { + u32 bw_tbl_0 = ets->cos_params[0].bw_tbl; + u32 bw_tbl_1 = ets->cos_params[1].bw_tbl; + /* Do not allow 0-100 configuration + * since PBF does not support it + * force 1-99 instead + */ + if (bw_tbl_0 == 0) { + bw_tbl_0 = 1; + bw_tbl_1 = 99; + } else if (bw_tbl_1 == 0) { + bw_tbl_1 = 1; + bw_tbl_0 = 99; + } + + bnx2x_ets_bw_limit(&bp->link_params, bw_tbl_0, bw_tbl_1); + } else { + if (ets->cos_params[0].strict == BNX2X_DCBX_COS_HIGH_STRICT) + status = bnx2x_ets_strict(&bp->link_params, 0); + else if (ets->cos_params[1].strict + == BNX2X_DCBX_COS_HIGH_STRICT) + status = bnx2x_ets_strict(&bp->link_params, 1); + + if (status) + BNX2X_ERR("update_ets_params failed\n"); + } +} + +static int bnx2x_dcbx_read_shmem_neg_results(struct bnx2x *bp) +{ + struct lldp_local_mib local_mib = {0}; + u32 dcbx_neg_res_offset = SHMEM2_RD(bp, dcbx_neg_res_offset); + int rc; + + DP(NETIF_MSG_LINK, "dcbx_neg_res_offset 0x%x\n", dcbx_neg_res_offset); + + if (SHMEM_DCBX_NEG_RES_NONE == dcbx_neg_res_offset) { + BNX2X_ERR("FW doesn't support dcbx_neg_res_offset\n"); + return -EINVAL; + } + rc = bnx2x_dcbx_read_mib(bp, (u32 *)&local_mib, dcbx_neg_res_offset, + DCBX_READ_LOCAL_MIB); + + if (rc) { + BNX2X_ERR("Faild to read local mib from FW\n"); + return rc; + } + + /* save features and error */ + bp->dcbx_local_feat = local_mib.features; + bp->dcbx_error = local_mib.error; + return 0; +} + +void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state) +{ + switch (state) { + case BNX2X_DCBX_STATE_NEG_RECEIVED: + { + DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_NEG_RECEIVED\n"); + + /* Read neg results if dcbx is in the FW */ + if (bnx2x_dcbx_read_shmem_neg_results(bp)) + return; + + bnx2x_dump_dcbx_drv_param(bp, &bp->dcbx_local_feat, + bp->dcbx_error); + + bnx2x_get_dcbx_drv_param(bp, &bp->dcbx_local_feat, + bp->dcbx_error); + + if (bp->state != BNX2X_STATE_OPENING_WAIT4_LOAD) { + bnx2x_dcbx_stop_hw_tx(bp); + return; + } + /* fall through */ + } + case BNX2X_DCBX_STATE_TX_PAUSED: + DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_TX_PAUSED\n"); + bnx2x_pfc_set_pfc(bp); + + bnx2x_dcbx_update_ets_params(bp); + if (bp->state != BNX2X_STATE_OPENING_WAIT4_LOAD) { + bnx2x_dcbx_resume_hw_tx(bp); + return; + } + /* fall through */ + case BNX2X_DCBX_STATE_TX_RELEASED: + DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_TX_RELEASED\n"); + if (bp->state != BNX2X_STATE_OPENING_WAIT4_LOAD) + bnx2x_fw_command(bp, DRV_MSG_CODE_DCBX_PMF_DRV_OK, 0); + + return; + default: + BNX2X_ERR("Unknown DCBX_STATE\n"); + } +} + + +#define LLDP_STATS_OFFSET(bp) (BP_PORT(bp)*\ + sizeof(struct lldp_dcbx_stat)) + +/* calculate struct offset in array according to chip information */ +#define LLDP_PARAMS_OFFSET(bp) (BP_PORT(bp)*sizeof(struct lldp_params)) + +#define LLDP_ADMIN_MIB_OFFSET(bp) (PORT_MAX*sizeof(struct lldp_params) + \ + BP_PORT(bp)*sizeof(struct lldp_admin_mib)) + +static void bnx2x_dcbx_lldp_updated_params(struct bnx2x *bp, + u32 dcbx_lldp_params_offset) +{ + struct lldp_params lldp_params = {0}; + u32 i = 0, *buff = NULL; + u32 offset = dcbx_lldp_params_offset + LLDP_PARAMS_OFFSET(bp); + + DP(NETIF_MSG_LINK, "lldp_offset 0x%x\n", offset); + + if ((bp->lldp_config_params.overwrite_settings == + BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE)) { + /* Read the data first */ + buff = (u32 *)&lldp_params; + for (i = 0; i < sizeof(struct lldp_params); i += 4, buff++) + *buff = REG_RD(bp, (offset + i)); + + lldp_params.msg_tx_hold = + (u8)bp->lldp_config_params.msg_tx_hold; + lldp_params.msg_fast_tx_interval = + (u8)bp->lldp_config_params.msg_fast_tx; + lldp_params.tx_crd_max = + (u8)bp->lldp_config_params.tx_credit_max; + lldp_params.msg_tx_interval = + (u8)bp->lldp_config_params.msg_tx_interval; + lldp_params.tx_fast = + (u8)bp->lldp_config_params.tx_fast; + + /* Write the data.*/ + buff = (u32 *)&lldp_params; + for (i = 0; i < sizeof(struct lldp_params); i += 4, buff++) + REG_WR(bp, (offset + i) , *buff); + + + } else if (BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE == + bp->lldp_config_params.overwrite_settings) + bp->lldp_config_params.overwrite_settings = + BNX2X_DCBX_OVERWRITE_SETTINGS_INVALID; +} + +static void bnx2x_dcbx_admin_mib_updated_params(struct bnx2x *bp, + u32 dcbx_lldp_params_offset) +{ + struct lldp_admin_mib admin_mib; + u32 i, other_traf_type = PREDEFINED_APP_IDX_MAX, traf_type = 0; + u32 *buff; + u32 offset = dcbx_lldp_params_offset + LLDP_ADMIN_MIB_OFFSET(bp); + + /*shortcuts*/ + struct dcbx_features *af = &admin_mib.features; + struct bnx2x_config_dcbx_params *dp = &bp->dcbx_config_params; + + memset(&admin_mib, 0, sizeof(struct lldp_admin_mib)); + buff = (u32 *)&admin_mib; + /* Read the data first */ + for (i = 0; i < sizeof(struct lldp_admin_mib); i += 4, buff++) + *buff = REG_RD(bp, (offset + i)); + + if (bp->dcbx_enabled == BNX2X_DCBX_ENABLED_ON_NEG_ON) + SET_FLAGS(admin_mib.ver_cfg_flags, DCBX_DCBX_ENABLED); + else + RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_DCBX_ENABLED); + + if ((BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE == + dp->overwrite_settings)) { + RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_CEE_VERSION_MASK); + admin_mib.ver_cfg_flags |= + (dp->admin_dcbx_version << DCBX_CEE_VERSION_SHIFT) & + DCBX_CEE_VERSION_MASK; + + af->ets.enabled = (u8)dp->admin_ets_enable; + + af->pfc.enabled = (u8)dp->admin_pfc_enable; + + /* FOR IEEE dp->admin_tc_supported_tx_enable */ + if (dp->admin_ets_configuration_tx_enable) + SET_FLAGS(admin_mib.ver_cfg_flags, + DCBX_ETS_CONFIG_TX_ENABLED); + else + RESET_FLAGS(admin_mib.ver_cfg_flags, + DCBX_ETS_CONFIG_TX_ENABLED); + /* For IEEE admin_ets_recommendation_tx_enable */ + if (dp->admin_pfc_tx_enable) + SET_FLAGS(admin_mib.ver_cfg_flags, + DCBX_PFC_CONFIG_TX_ENABLED); + else + RESET_FLAGS(admin_mib.ver_cfg_flags, + DCBX_PFC_CONFIG_TX_ENABLED); + + if (dp->admin_application_priority_tx_enable) + SET_FLAGS(admin_mib.ver_cfg_flags, + DCBX_APP_CONFIG_TX_ENABLED); + else + RESET_FLAGS(admin_mib.ver_cfg_flags, + DCBX_APP_CONFIG_TX_ENABLED); + + if (dp->admin_ets_willing) + SET_FLAGS(admin_mib.ver_cfg_flags, DCBX_ETS_WILLING); + else + RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_ETS_WILLING); + /* For IEEE admin_ets_reco_valid */ + if (dp->admin_pfc_willing) + SET_FLAGS(admin_mib.ver_cfg_flags, DCBX_PFC_WILLING); + else + RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_PFC_WILLING); + + if (dp->admin_app_priority_willing) + SET_FLAGS(admin_mib.ver_cfg_flags, DCBX_APP_WILLING); + else + RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_APP_WILLING); + + for (i = 0 ; i < DCBX_MAX_NUM_PG_BW_ENTRIES; i++) { + DCBX_PG_BW_SET(af->ets.pg_bw_tbl, i, + (u8)dp->admin_configuration_bw_precentage[i]); + + DP(NETIF_MSG_LINK, "pg_bw_tbl[%d] = %02x\n", + i, DCBX_PG_BW_GET(af->ets.pg_bw_tbl, i)); + } + + for (i = 0; i < DCBX_MAX_NUM_PRI_PG_ENTRIES; i++) { + DCBX_PRI_PG_SET(af->ets.pri_pg_tbl, i, + (u8)dp->admin_configuration_ets_pg[i]); + + DP(NETIF_MSG_LINK, "pri_pg_tbl[%d] = %02x\n", + i, DCBX_PRI_PG_GET(af->ets.pri_pg_tbl, i)); + } + + /*For IEEE admin_recommendation_bw_precentage + *For IEEE admin_recommendation_ets_pg */ + af->pfc.pri_en_bitmap = (u8)dp->admin_pfc_bitmap; + for (i = 0; i < 4; i++) { + if (dp->admin_priority_app_table[i].valid) { + struct bnx2x_admin_priority_app_table *table = + dp->admin_priority_app_table; + if ((ETH_TYPE_FCOE == table[i].app_id) && + (TRAFFIC_TYPE_ETH == table[i].traffic_type)) + traf_type = FCOE_APP_IDX; + else if ((TCP_PORT_ISCSI == table[i].app_id) && + (TRAFFIC_TYPE_PORT == table[i].traffic_type)) + traf_type = ISCSI_APP_IDX; + else + traf_type = other_traf_type++; + + af->app.app_pri_tbl[traf_type].app_id = + table[i].app_id; + + af->app.app_pri_tbl[traf_type].pri_bitmap = + (u8)(1 << table[i].priority); + + af->app.app_pri_tbl[traf_type].appBitfield = + (DCBX_APP_ENTRY_VALID); + + af->app.app_pri_tbl[traf_type].appBitfield |= + (TRAFFIC_TYPE_ETH == table[i].traffic_type) ? + DCBX_APP_SF_ETH_TYPE : DCBX_APP_SF_PORT; + } + } + + af->app.default_pri = (u8)dp->admin_default_priority; + + } else if (BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE == + dp->overwrite_settings) + dp->overwrite_settings = BNX2X_DCBX_OVERWRITE_SETTINGS_INVALID; + + /* Write the data. */ + buff = (u32 *)&admin_mib; + for (i = 0; i < sizeof(struct lldp_admin_mib); i += 4, buff++) + REG_WR(bp, (offset + i), *buff); +} + +void bnx2x_dcbx_set_state(struct bnx2x *bp, bool dcb_on, u32 dcbx_enabled) +{ + if (CHIP_IS_E2(bp) && !CHIP_MODE_IS_4_PORT(bp)) { + bp->dcb_state = dcb_on; + bp->dcbx_enabled = dcbx_enabled; + } else { + bp->dcb_state = false; + bp->dcbx_enabled = BNX2X_DCBX_ENABLED_INVALID; + } + DP(NETIF_MSG_LINK, "DCB state [%s:%s]\n", + dcb_on ? "ON" : "OFF", + dcbx_enabled == BNX2X_DCBX_ENABLED_OFF ? "user-mode" : + dcbx_enabled == BNX2X_DCBX_ENABLED_ON_NEG_OFF ? "on-chip static" : + dcbx_enabled == BNX2X_DCBX_ENABLED_ON_NEG_ON ? + "on-chip with negotiation" : "invalid"); +} + +void bnx2x_dcbx_init_params(struct bnx2x *bp) +{ + bp->dcbx_config_params.admin_dcbx_version = 0x0; /* 0 - CEE; 1 - IEEE */ + bp->dcbx_config_params.admin_ets_willing = 1; + bp->dcbx_config_params.admin_pfc_willing = 1; + bp->dcbx_config_params.overwrite_settings = 1; + bp->dcbx_config_params.admin_ets_enable = 1; + bp->dcbx_config_params.admin_pfc_enable = 1; + bp->dcbx_config_params.admin_tc_supported_tx_enable = 1; + bp->dcbx_config_params.admin_ets_configuration_tx_enable = 1; + bp->dcbx_config_params.admin_pfc_tx_enable = 1; + bp->dcbx_config_params.admin_application_priority_tx_enable = 1; + bp->dcbx_config_params.admin_ets_reco_valid = 1; + bp->dcbx_config_params.admin_app_priority_willing = 1; + bp->dcbx_config_params.admin_configuration_bw_precentage[0] = 00; + bp->dcbx_config_params.admin_configuration_bw_precentage[1] = 50; + bp->dcbx_config_params.admin_configuration_bw_precentage[2] = 50; + bp->dcbx_config_params.admin_configuration_bw_precentage[3] = 0; + bp->dcbx_config_params.admin_configuration_bw_precentage[4] = 0; + bp->dcbx_config_params.admin_configuration_bw_precentage[5] = 0; + bp->dcbx_config_params.admin_configuration_bw_precentage[6] = 0; + bp->dcbx_config_params.admin_configuration_bw_precentage[7] = 0; + bp->dcbx_config_params.admin_configuration_ets_pg[0] = 1; + bp->dcbx_config_params.admin_configuration_ets_pg[1] = 0; + bp->dcbx_config_params.admin_configuration_ets_pg[2] = 0; + bp->dcbx_config_params.admin_configuration_ets_pg[3] = 2; + bp->dcbx_config_params.admin_configuration_ets_pg[4] = 0; + bp->dcbx_config_params.admin_configuration_ets_pg[5] = 0; + bp->dcbx_config_params.admin_configuration_ets_pg[6] = 0; + bp->dcbx_config_params.admin_configuration_ets_pg[7] = 0; + bp->dcbx_config_params.admin_recommendation_bw_precentage[0] = 0; + bp->dcbx_config_params.admin_recommendation_bw_precentage[1] = 1; + bp->dcbx_config_params.admin_recommendation_bw_precentage[2] = 2; + bp->dcbx_config_params.admin_recommendation_bw_precentage[3] = 0; + bp->dcbx_config_params.admin_recommendation_bw_precentage[4] = 7; + bp->dcbx_config_params.admin_recommendation_bw_precentage[5] = 5; + bp->dcbx_config_params.admin_recommendation_bw_precentage[6] = 6; + bp->dcbx_config_params.admin_recommendation_bw_precentage[7] = 7; + bp->dcbx_config_params.admin_recommendation_ets_pg[0] = 0; + bp->dcbx_config_params.admin_recommendation_ets_pg[1] = 1; + bp->dcbx_config_params.admin_recommendation_ets_pg[2] = 2; + bp->dcbx_config_params.admin_recommendation_ets_pg[3] = 3; + bp->dcbx_config_params.admin_recommendation_ets_pg[4] = 4; + bp->dcbx_config_params.admin_recommendation_ets_pg[5] = 5; + bp->dcbx_config_params.admin_recommendation_ets_pg[6] = 6; + bp->dcbx_config_params.admin_recommendation_ets_pg[7] = 7; + bp->dcbx_config_params.admin_pfc_bitmap = 0x8; /* FCoE(3) enable */ + bp->dcbx_config_params.admin_priority_app_table[0].valid = 1; + bp->dcbx_config_params.admin_priority_app_table[1].valid = 1; + bp->dcbx_config_params.admin_priority_app_table[2].valid = 0; + bp->dcbx_config_params.admin_priority_app_table[3].valid = 0; + bp->dcbx_config_params.admin_priority_app_table[0].priority = 3; + bp->dcbx_config_params.admin_priority_app_table[1].priority = 0; + bp->dcbx_config_params.admin_priority_app_table[2].priority = 0; + bp->dcbx_config_params.admin_priority_app_table[3].priority = 0; + bp->dcbx_config_params.admin_priority_app_table[0].traffic_type = 0; + bp->dcbx_config_params.admin_priority_app_table[1].traffic_type = 1; + bp->dcbx_config_params.admin_priority_app_table[2].traffic_type = 0; + bp->dcbx_config_params.admin_priority_app_table[3].traffic_type = 0; + bp->dcbx_config_params.admin_priority_app_table[0].app_id = 0x8906; + bp->dcbx_config_params.admin_priority_app_table[1].app_id = 3260; + bp->dcbx_config_params.admin_priority_app_table[2].app_id = 0; + bp->dcbx_config_params.admin_priority_app_table[3].app_id = 0; + bp->dcbx_config_params.admin_default_priority = + bp->dcbx_config_params.admin_priority_app_table[1].priority; +} + +void bnx2x_dcbx_init(struct bnx2x *bp) +{ + u32 dcbx_lldp_params_offset = SHMEM_LLDP_DCBX_PARAMS_NONE; + + if (bp->dcbx_enabled <= 0) + return; + + /* validate: + * chip of good for dcbx version, + * dcb is wanted + * the function is pmf + * shmem2 contains DCBX support fields + */ + DP(NETIF_MSG_LINK, "dcb_state %d bp->port.pmf %d\n", + bp->dcb_state, bp->port.pmf); + + if (bp->dcb_state == BNX2X_DCB_STATE_ON && bp->port.pmf && + SHMEM2_HAS(bp, dcbx_lldp_params_offset)) { + dcbx_lldp_params_offset = + SHMEM2_RD(bp, dcbx_lldp_params_offset); + + DP(NETIF_MSG_LINK, "dcbx_lldp_params_offset 0x%x\n", + dcbx_lldp_params_offset); + + if (SHMEM_LLDP_DCBX_PARAMS_NONE != dcbx_lldp_params_offset) { + bnx2x_dcbx_lldp_updated_params(bp, + dcbx_lldp_params_offset); + + bnx2x_dcbx_admin_mib_updated_params(bp, + dcbx_lldp_params_offset); + + /* set default configuration BC has */ + bnx2x_dcbx_set_params(bp, + BNX2X_DCBX_STATE_NEG_RECEIVED); + + bnx2x_fw_command(bp, + DRV_MSG_CODE_DCBX_ADMIN_PMF_MSG, 0); + } + } +} + +void bnx2x_dcb_init_intmem_pfc(struct bnx2x *bp) +{ + struct priority_cos pricos[MAX_PFC_TRAFFIC_TYPES]; + u32 i = 0, addr; + memset(pricos, 0, sizeof(pricos)); + /* Default initialization */ + for (i = 0; i < MAX_PFC_TRAFFIC_TYPES; i++) + pricos[i].priority = LLFC_TRAFFIC_TYPE_TO_PRIORITY_UNMAPPED; + + /* Store per port struct to internal memory */ + addr = BAR_XSTRORM_INTMEM + + XSTORM_CMNG_PER_PORT_VARS_OFFSET(BP_PORT(bp)) + + offsetof(struct cmng_struct_per_port, + traffic_type_to_priority_cos); + __storm_memset_struct(bp, addr, sizeof(pricos), (u32 *)pricos); + + + /* LLFC disabled.*/ + REG_WR8(bp , BAR_XSTRORM_INTMEM + + XSTORM_CMNG_PER_PORT_VARS_OFFSET(BP_PORT(bp)) + + offsetof(struct cmng_struct_per_port, llfc_mode), + LLFC_MODE_NONE); + + /* DCBX disabled.*/ + REG_WR8(bp , BAR_XSTRORM_INTMEM + + XSTORM_CMNG_PER_PORT_VARS_OFFSET(BP_PORT(bp)) + + offsetof(struct cmng_struct_per_port, dcb_enabled), + DCB_DISABLED); +} + +static void +bnx2x_dcbx_print_cos_params(struct bnx2x *bp, + struct flow_control_configuration *pfc_fw_cfg) +{ + u8 pri = 0; + u8 cos = 0; + + DP(NETIF_MSG_LINK, + "pfc_fw_cfg->dcb_version %x\n", pfc_fw_cfg->dcb_version); + DP(NETIF_MSG_LINK, + "pdev->params.dcbx_port_params.pfc." + "priority_non_pauseable_mask %x\n", + bp->dcbx_port_params.pfc.priority_non_pauseable_mask); + + for (cos = 0 ; cos < bp->dcbx_port_params.ets.num_of_cos ; cos++) { + DP(NETIF_MSG_LINK, "pdev->params.dcbx_port_params.ets." + "cos_params[%d].pri_bitmask %x\n", cos, + bp->dcbx_port_params.ets.cos_params[cos].pri_bitmask); + + DP(NETIF_MSG_LINK, "pdev->params.dcbx_port_params.ets." + "cos_params[%d].bw_tbl %x\n", cos, + bp->dcbx_port_params.ets.cos_params[cos].bw_tbl); + + DP(NETIF_MSG_LINK, "pdev->params.dcbx_port_params.ets." + "cos_params[%d].strict %x\n", cos, + bp->dcbx_port_params.ets.cos_params[cos].strict); + + DP(NETIF_MSG_LINK, "pdev->params.dcbx_port_params.ets." + "cos_params[%d].pauseable %x\n", cos, + bp->dcbx_port_params.ets.cos_params[cos].pauseable); + } + + for (pri = 0; pri < LLFC_DRIVER_TRAFFIC_TYPE_MAX; pri++) { + DP(NETIF_MSG_LINK, + "pfc_fw_cfg->traffic_type_to_priority_cos[%d]." + "priority %x\n", pri, + pfc_fw_cfg->traffic_type_to_priority_cos[pri].priority); + + DP(NETIF_MSG_LINK, + "pfc_fw_cfg->traffic_type_to_priority_cos[%d].cos %x\n", + pri, pfc_fw_cfg->traffic_type_to_priority_cos[pri].cos); + } +} + +/* fills help_data according to pg_info */ +static void bnx2x_dcbx_get_num_pg_traf_type(struct bnx2x *bp, + u32 *pg_pri_orginal_spread, + struct pg_help_data *help_data) +{ + bool pg_found = false; + u32 i, traf_type, add_traf_type, add_pg; + u32 *ttp = bp->dcbx_port_params.app.traffic_type_priority; + struct pg_entry_help_data *data = help_data->data; /*shotcut*/ + + /* Set to invalid */ + for (i = 0; i < LLFC_DRIVER_TRAFFIC_TYPE_MAX; i++) + data[i].pg = DCBX_ILLEGAL_PG; + + for (add_traf_type = 0; + add_traf_type < LLFC_DRIVER_TRAFFIC_TYPE_MAX; add_traf_type++) { + pg_found = false; + if (ttp[add_traf_type] < MAX_PFC_PRIORITIES) { + add_pg = (u8)pg_pri_orginal_spread[ttp[add_traf_type]]; + for (traf_type = 0; + traf_type < LLFC_DRIVER_TRAFFIC_TYPE_MAX; + traf_type++) { + if (data[traf_type].pg == add_pg) { + if (!(data[traf_type].pg_priority & + (1 << ttp[add_traf_type]))) + data[traf_type]. + num_of_dif_pri++; + data[traf_type].pg_priority |= + (1 << ttp[add_traf_type]); + pg_found = true; + break; + } + } + if (false == pg_found) { + data[help_data->num_of_pg].pg = add_pg; + data[help_data->num_of_pg].pg_priority = + (1 << ttp[add_traf_type]); + data[help_data->num_of_pg].num_of_dif_pri = 1; + help_data->num_of_pg++; + } + } + DP(NETIF_MSG_LINK, + "add_traf_type %d pg_found %s num_of_pg %d\n", + add_traf_type, (false == pg_found) ? "NO" : "YES", + help_data->num_of_pg); + } +} + + +/******************************************************************************* + * Description: single priority group + * + * Return: + ******************************************************************************/ +static void bnx2x_dcbx_ets_disabled_entry_data(struct bnx2x *bp, + struct cos_help_data *cos_data, + u32 pri_join_mask) +{ + /* Only one priority than only one COS */ + cos_data->data[0].pausable = + IS_DCBX_PFC_PRI_ONLY_PAUSE(bp, pri_join_mask); + cos_data->data[0].pri_join_mask = pri_join_mask; + cos_data->data[0].cos_bw = 100; + cos_data->num_of_cos = 1; +} + +/******************************************************************************* + * Description: updating the cos bw + * + * Return: + ******************************************************************************/ +static inline void bnx2x_dcbx_add_to_cos_bw(struct bnx2x *bp, + struct cos_entry_help_data *data, + u8 pg_bw) +{ + if (data->cos_bw == DCBX_INVALID_COS_BW) + data->cos_bw = pg_bw; + else + data->cos_bw += pg_bw; +} + +/******************************************************************************* + * Description: single priority group + * + * Return: + ******************************************************************************/ +static void bnx2x_dcbx_separate_pauseable_from_non(struct bnx2x *bp, + struct cos_help_data *cos_data, + u32 *pg_pri_orginal_spread, + struct dcbx_ets_feature *ets) +{ + u32 pri_tested = 0; + u8 i = 0; + u8 entry = 0; + u8 pg_entry = 0; + u8 num_of_pri = LLFC_DRIVER_TRAFFIC_TYPE_MAX; + + cos_data->data[0].pausable = true; + cos_data->data[1].pausable = false; + cos_data->data[0].pri_join_mask = cos_data->data[1].pri_join_mask = 0; + + for (i = 0 ; i < num_of_pri ; i++) { + pri_tested = 1 << bp->dcbx_port_params. + app.traffic_type_priority[i]; + + if (pri_tested & DCBX_PFC_PRI_NON_PAUSE_MASK(bp)) { + cos_data->data[1].pri_join_mask |= pri_tested; + entry = 1; + } else { + cos_data->data[0].pri_join_mask |= pri_tested; + entry = 0; + } + pg_entry = (u8)pg_pri_orginal_spread[bp->dcbx_port_params. + app.traffic_type_priority[i]]; + /* There can be only one strict pg */ + if (pg_entry < DCBX_MAX_NUM_PG_BW_ENTRIES) + bnx2x_dcbx_add_to_cos_bw(bp, &cos_data->data[entry], + DCBX_PG_BW_GET(ets->pg_bw_tbl, pg_entry)); + else + /* If we join a group and one is strict + * than the bw rulls */ + cos_data->data[entry].strict = + BNX2X_DCBX_COS_HIGH_STRICT; + } + if ((0 == cos_data->data[0].pri_join_mask) && + (0 == cos_data->data[1].pri_join_mask)) + BNX2X_ERR("dcbx error: Both groups must have priorities\n"); +} + + +#ifndef POWER_OF_2 +#define POWER_OF_2(x) ((0 != x) && (0 == (x & (x-1)))) +#endif + +static void bxn2x_dcbx_single_pg_to_cos_params(struct bnx2x *bp, + struct pg_help_data *pg_help_data, + struct cos_help_data *cos_data, + u32 pri_join_mask, + u8 num_of_dif_pri) +{ + u8 i = 0; + u32 pri_tested = 0; + u32 pri_mask_without_pri = 0; + u32 *ttp = bp->dcbx_port_params.app.traffic_type_priority; + /*debug*/ + if (num_of_dif_pri == 1) { + bnx2x_dcbx_ets_disabled_entry_data(bp, cos_data, pri_join_mask); + return; + } + /* single priority group */ + if (pg_help_data->data[0].pg < DCBX_MAX_NUM_PG_BW_ENTRIES) { + /* If there are both pauseable and non-pauseable priorities, + * the pauseable priorities go to the first queue and + * the non-pauseable priorities go to the second queue. + */ + if (IS_DCBX_PFC_PRI_MIX_PAUSE(bp, pri_join_mask)) { + /* Pauseable */ + cos_data->data[0].pausable = true; + /* Non pauseable.*/ + cos_data->data[1].pausable = false; + + if (2 == num_of_dif_pri) { + cos_data->data[0].cos_bw = 50; + cos_data->data[1].cos_bw = 50; + } + + if (3 == num_of_dif_pri) { + if (POWER_OF_2(DCBX_PFC_PRI_GET_PAUSE(bp, + pri_join_mask))) { + cos_data->data[0].cos_bw = 33; + cos_data->data[1].cos_bw = 67; + } else { + cos_data->data[0].cos_bw = 67; + cos_data->data[1].cos_bw = 33; + } + } + + } else if (IS_DCBX_PFC_PRI_ONLY_PAUSE(bp, pri_join_mask)) { + /* If there are only pauseable priorities, + * then one/two priorities go to the first queue + * and one priority goes to the second queue. + */ + if (2 == num_of_dif_pri) { + cos_data->data[0].cos_bw = 50; + cos_data->data[1].cos_bw = 50; + } else { + cos_data->data[0].cos_bw = 67; + cos_data->data[1].cos_bw = 33; + } + cos_data->data[1].pausable = true; + cos_data->data[0].pausable = true; + /* All priorities except FCOE */ + cos_data->data[0].pri_join_mask = (pri_join_mask & + ((u8)~(1 << ttp[LLFC_TRAFFIC_TYPE_FCOE]))); + /* Only FCOE priority.*/ + cos_data->data[1].pri_join_mask = + (1 << ttp[LLFC_TRAFFIC_TYPE_FCOE]); + } else + /* If there are only non-pauseable priorities, + * they will all go to the same queue. + */ + bnx2x_dcbx_ets_disabled_entry_data(bp, + cos_data, pri_join_mask); + } else { + /* priority group which is not BW limited (PG#15):*/ + if (IS_DCBX_PFC_PRI_MIX_PAUSE(bp, pri_join_mask)) { + /* If there are both pauseable and non-pauseable + * priorities, the pauseable priorities go to the first + * queue and the non-pauseable priorities + * go to the second queue. + */ + if (DCBX_PFC_PRI_GET_PAUSE(bp, pri_join_mask) > + DCBX_PFC_PRI_GET_NON_PAUSE(bp, pri_join_mask)) { + cos_data->data[0].strict = + BNX2X_DCBX_COS_HIGH_STRICT; + cos_data->data[1].strict = + BNX2X_DCBX_COS_LOW_STRICT; + } else { + cos_data->data[0].strict = + BNX2X_DCBX_COS_LOW_STRICT; + cos_data->data[1].strict = + BNX2X_DCBX_COS_HIGH_STRICT; + } + /* Pauseable */ + cos_data->data[0].pausable = true; + /* Non pause-able.*/ + cos_data->data[1].pausable = false; + } else { + /* If there are only pauseable priorities or + * only non-pauseable,* the lower priorities go + * to the first queue and the higherpriorities go + * to the second queue. + */ + cos_data->data[0].pausable = + cos_data->data[1].pausable = + IS_DCBX_PFC_PRI_ONLY_PAUSE(bp, pri_join_mask); + + for (i = 0 ; i < LLFC_DRIVER_TRAFFIC_TYPE_MAX; i++) { + pri_tested = 1 << bp->dcbx_port_params. + app.traffic_type_priority[i]; + /* Remove priority tested */ + pri_mask_without_pri = + (pri_join_mask & ((u8)(~pri_tested))); + if (pri_mask_without_pri < pri_tested) + break; + } + + if (i == LLFC_DRIVER_TRAFFIC_TYPE_MAX) + BNX2X_ERR("Invalid value for pri_join_mask -" + " could not find a priority\n"); + + cos_data->data[0].pri_join_mask = pri_mask_without_pri; + cos_data->data[1].pri_join_mask = pri_tested; + /* Both queues are strict priority, + * and that with the highest priority + * gets the highest strict priority in the arbiter. + */ + cos_data->data[0].strict = BNX2X_DCBX_COS_LOW_STRICT; + cos_data->data[1].strict = BNX2X_DCBX_COS_HIGH_STRICT; + } + } +} + +static void bnx2x_dcbx_two_pg_to_cos_params( + struct bnx2x *bp, + struct pg_help_data *pg_help_data, + struct dcbx_ets_feature *ets, + struct cos_help_data *cos_data, + u32 *pg_pri_orginal_spread, + u32 pri_join_mask, + u8 num_of_dif_pri) +{ + u8 i = 0; + u8 pg[E2_NUM_OF_COS] = {0}; + + /* If there are both pauseable and non-pauseable priorities, + * the pauseable priorities go to the first queue and + * the non-pauseable priorities go to the second queue. + */ + if (IS_DCBX_PFC_PRI_MIX_PAUSE(bp, pri_join_mask)) { + if (IS_DCBX_PFC_PRI_MIX_PAUSE(bp, + pg_help_data->data[0].pg_priority) || + IS_DCBX_PFC_PRI_MIX_PAUSE(bp, + pg_help_data->data[1].pg_priority)) { + /* If one PG contains both pauseable and + * non-pauseable priorities then ETS is disabled. + */ + bnx2x_dcbx_separate_pauseable_from_non(bp, cos_data, + pg_pri_orginal_spread, ets); + bp->dcbx_port_params.ets.enabled = false; + return; + } + + /* Pauseable */ + cos_data->data[0].pausable = true; + /* Non pauseable. */ + cos_data->data[1].pausable = false; + if (IS_DCBX_PFC_PRI_ONLY_PAUSE(bp, + pg_help_data->data[0].pg_priority)) { + /* 0 is pauseable */ + cos_data->data[0].pri_join_mask = + pg_help_data->data[0].pg_priority; + pg[0] = pg_help_data->data[0].pg; + cos_data->data[1].pri_join_mask = + pg_help_data->data[1].pg_priority; + pg[1] = pg_help_data->data[1].pg; + } else {/* 1 is pauseable */ + cos_data->data[0].pri_join_mask = + pg_help_data->data[1].pg_priority; + pg[0] = pg_help_data->data[1].pg; + cos_data->data[1].pri_join_mask = + pg_help_data->data[0].pg_priority; + pg[1] = pg_help_data->data[0].pg; + } + } else { + /* If there are only pauseable priorities or + * only non-pauseable, each PG goes to a queue. + */ + cos_data->data[0].pausable = cos_data->data[1].pausable = + IS_DCBX_PFC_PRI_ONLY_PAUSE(bp, pri_join_mask); + cos_data->data[0].pri_join_mask = + pg_help_data->data[0].pg_priority; + pg[0] = pg_help_data->data[0].pg; + cos_data->data[1].pri_join_mask = + pg_help_data->data[1].pg_priority; + pg[1] = pg_help_data->data[1].pg; + } + + /* There can be only one strict pg */ + for (i = 0 ; i < E2_NUM_OF_COS; i++) { + if (pg[i] < DCBX_MAX_NUM_PG_BW_ENTRIES) + cos_data->data[i].cos_bw = + DCBX_PG_BW_GET(ets->pg_bw_tbl, pg[i]); + else + cos_data->data[i].strict = BNX2X_DCBX_COS_HIGH_STRICT; + } +} + +/******************************************************************************* + * Description: Still + * + * Return: + ******************************************************************************/ +static void bnx2x_dcbx_three_pg_to_cos_params( + struct bnx2x *bp, + struct pg_help_data *pg_help_data, + struct dcbx_ets_feature *ets, + struct cos_help_data *cos_data, + u32 *pg_pri_orginal_spread, + u32 pri_join_mask, + u8 num_of_dif_pri) +{ + u8 i = 0; + u32 pri_tested = 0; + u8 entry = 0; + u8 pg_entry = 0; + bool b_found_strict = false; + u8 num_of_pri = LLFC_DRIVER_TRAFFIC_TYPE_MAX; + + cos_data->data[0].pri_join_mask = cos_data->data[1].pri_join_mask = 0; + /* If there are both pauseable and non-pauseable priorities, + * the pauseable priorities go to the first queue and the + * non-pauseable priorities go to the second queue. + */ + if (IS_DCBX_PFC_PRI_MIX_PAUSE(bp, pri_join_mask)) + bnx2x_dcbx_separate_pauseable_from_non(bp, + cos_data, pg_pri_orginal_spread, ets); + else { + /* If two BW-limited PG-s were combined to one queue, + * the BW is their sum. + * + * If there are only pauseable priorities or only non-pauseable, + * and there are both BW-limited and non-BW-limited PG-s, + * the BW-limited PG/s go to one queue and the non-BW-limited + * PG/s go to the second queue. + * + * If there are only pauseable priorities or only non-pauseable + * and all are BW limited, then two priorities go to the first + * queue and one priority goes to the second queue. + * + * We will join this two cases: + * if one is BW limited it will go to the secoend queue + * otherwise the last priority will get it + */ + + cos_data->data[0].pausable = cos_data->data[1].pausable = + IS_DCBX_PFC_PRI_ONLY_PAUSE(bp, pri_join_mask); + + for (i = 0 ; i < num_of_pri; i++) { + pri_tested = 1 << bp->dcbx_port_params. + app.traffic_type_priority[i]; + pg_entry = (u8)pg_pri_orginal_spread[bp-> + dcbx_port_params.app.traffic_type_priority[i]]; + + if (pg_entry < DCBX_MAX_NUM_PG_BW_ENTRIES) { + entry = 0; + + if (i == (num_of_pri-1) && + false == b_found_strict) + /* last entry will be handled separately + * If no priority is strict than last + * enty goes to last queue.*/ + entry = 1; + cos_data->data[entry].pri_join_mask |= + pri_tested; + bnx2x_dcbx_add_to_cos_bw(bp, + &cos_data->data[entry], + DCBX_PG_BW_GET(ets->pg_bw_tbl, + pg_entry)); + } else { + b_found_strict = true; + cos_data->data[1].pri_join_mask |= pri_tested; + /* If we join a group and one is strict + * than the bw rulls */ + cos_data->data[1].strict = + BNX2X_DCBX_COS_HIGH_STRICT; + } + } + } +} + + +static void bnx2x_dcbx_fill_cos_params(struct bnx2x *bp, + struct pg_help_data *help_data, + struct dcbx_ets_feature *ets, + u32 *pg_pri_orginal_spread) +{ + struct cos_help_data cos_data ; + u8 i = 0; + u32 pri_join_mask = 0; + u8 num_of_dif_pri = 0; + + memset(&cos_data, 0, sizeof(cos_data)); + /* Validate the pg value */ + for (i = 0; i < help_data->num_of_pg ; i++) { + if (DCBX_STRICT_PRIORITY != help_data->data[i].pg && + DCBX_MAX_NUM_PG_BW_ENTRIES <= help_data->data[i].pg) + BNX2X_ERR("Invalid pg[%d] data %x\n", i, + help_data->data[i].pg); + pri_join_mask |= help_data->data[i].pg_priority; + num_of_dif_pri += help_data->data[i].num_of_dif_pri; + } + + /* default settings */ + cos_data.num_of_cos = 2; + for (i = 0; i < E2_NUM_OF_COS ; i++) { + cos_data.data[i].pri_join_mask = pri_join_mask; + cos_data.data[i].pausable = false; + cos_data.data[i].strict = BNX2X_DCBX_COS_NOT_STRICT; + cos_data.data[i].cos_bw = DCBX_INVALID_COS_BW; + } + + switch (help_data->num_of_pg) { + case 1: + + bxn2x_dcbx_single_pg_to_cos_params( + bp, + help_data, + &cos_data, + pri_join_mask, + num_of_dif_pri); + break; + case 2: + bnx2x_dcbx_two_pg_to_cos_params( + bp, + help_data, + ets, + &cos_data, + pg_pri_orginal_spread, + pri_join_mask, + num_of_dif_pri); + break; + + case 3: + bnx2x_dcbx_three_pg_to_cos_params( + bp, + help_data, + ets, + &cos_data, + pg_pri_orginal_spread, + pri_join_mask, + num_of_dif_pri); + + break; + default: + BNX2X_ERR("Wrong pg_help_data.num_of_pg\n"); + bnx2x_dcbx_ets_disabled_entry_data(bp, + &cos_data, pri_join_mask); + } + + for (i = 0; i < cos_data.num_of_cos ; i++) { + struct bnx2x_dcbx_cos_params *params = + &bp->dcbx_port_params.ets.cos_params[i]; + + params->pauseable = cos_data.data[i].pausable; + params->strict = cos_data.data[i].strict; + params->bw_tbl = cos_data.data[i].cos_bw; + if (params->pauseable) { + params->pri_bitmask = + DCBX_PFC_PRI_GET_PAUSE(bp, + cos_data.data[i].pri_join_mask); + DP(NETIF_MSG_LINK, "COS %d PAUSABLE prijoinmask 0x%x\n", + i, cos_data.data[i].pri_join_mask); + } else { + params->pri_bitmask = + DCBX_PFC_PRI_GET_NON_PAUSE(bp, + cos_data.data[i].pri_join_mask); + DP(NETIF_MSG_LINK, "COS %d NONPAUSABLE prijoinmask " + "0x%x\n", + i, cos_data.data[i].pri_join_mask); + } + } + + bp->dcbx_port_params.ets.num_of_cos = cos_data.num_of_cos ; +} + +static void bnx2x_dcbx_get_ets_pri_pg_tbl(struct bnx2x *bp, + u32 *set_configuration_ets_pg, + u32 *pri_pg_tbl) +{ + int i; + + for (i = 0; i < DCBX_MAX_NUM_PRI_PG_ENTRIES; i++) { + set_configuration_ets_pg[i] = DCBX_PRI_PG_GET(pri_pg_tbl, i); + + DP(NETIF_MSG_LINK, "set_configuration_ets_pg[%d] = 0x%x\n", + i, set_configuration_ets_pg[i]); + } +} + +/******************************************************************************* + * Description: Fill pfc_config struct that will be sent in DCBX start ramrod + * + * Return: + ******************************************************************************/ +static void bnx2x_pfc_fw_struct_e2(struct bnx2x *bp) +{ + struct flow_control_configuration *pfc_fw_cfg = NULL; + u16 pri_bit = 0; + u8 cos = 0, pri = 0; + struct priority_cos *tt2cos; + u32 *ttp = bp->dcbx_port_params.app.traffic_type_priority; + + pfc_fw_cfg = (struct flow_control_configuration *) + bnx2x_sp(bp, pfc_config); + memset(pfc_fw_cfg, 0, sizeof(struct flow_control_configuration)); + + /*shortcut*/ + tt2cos = pfc_fw_cfg->traffic_type_to_priority_cos; + + /* Fw version should be incremented each update */ + pfc_fw_cfg->dcb_version = ++bp->dcb_version; + pfc_fw_cfg->dcb_enabled = DCB_ENABLED; + + /* Default initialization */ + for (pri = 0; pri < MAX_PFC_TRAFFIC_TYPES ; pri++) { + tt2cos[pri].priority = LLFC_TRAFFIC_TYPE_TO_PRIORITY_UNMAPPED; + tt2cos[pri].cos = 0; + } + + /* Fill priority parameters */ + for (pri = 0; pri < LLFC_DRIVER_TRAFFIC_TYPE_MAX; pri++) { + tt2cos[pri].priority = ttp[pri]; + pri_bit = 1 << tt2cos[pri].priority; + + /* Fill COS parameters based on COS calculated to + * make it more generally for future use */ + for (cos = 0; cos < bp->dcbx_port_params.ets.num_of_cos; cos++) + if (bp->dcbx_port_params.ets.cos_params[cos]. + pri_bitmask & pri_bit) + tt2cos[pri].cos = cos; + } + bnx2x_dcbx_print_cos_params(bp, pfc_fw_cfg); +} +/* DCB netlink */ +#ifdef BCM_DCB +#include <linux/dcbnl.h> + +#define BNX2X_DCBX_CAPS (DCB_CAP_DCBX_LLD_MANAGED | \ + DCB_CAP_DCBX_VER_CEE | DCB_CAP_DCBX_STATIC) + +static inline bool bnx2x_dcbnl_set_valid(struct bnx2x *bp) +{ + /* validate dcbnl call that may change HW state: + * DCB is on and DCBX mode was SUCCESSFULLY set by the user. + */ + return bp->dcb_state && bp->dcbx_mode_uset; +} + +static u8 bnx2x_dcbnl_get_state(struct net_device *netdev) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "state = %d\n", bp->dcb_state); + return bp->dcb_state; +} + +static u8 bnx2x_dcbnl_set_state(struct net_device *netdev, u8 state) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "state = %s\n", state ? "on" : "off"); + + bnx2x_dcbx_set_state(bp, (state ? true : false), bp->dcbx_enabled); + return 0; +} + +static void bnx2x_dcbnl_get_perm_hw_addr(struct net_device *netdev, + u8 *perm_addr) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "GET-PERM-ADDR\n"); + + /* first the HW mac address */ + memcpy(perm_addr, netdev->dev_addr, netdev->addr_len); + +#ifdef BCM_CNIC + /* second SAN address */ + memcpy(perm_addr+netdev->addr_len, bp->fip_mac, netdev->addr_len); +#endif +} + +static void bnx2x_dcbnl_set_pg_tccfg_tx(struct net_device *netdev, int prio, + u8 prio_type, u8 pgid, u8 bw_pct, + u8 up_map) +{ + struct bnx2x *bp = netdev_priv(netdev); + + DP(NETIF_MSG_LINK, "prio[%d] = %d\n", prio, pgid); + if (!bnx2x_dcbnl_set_valid(bp) || prio >= DCBX_MAX_NUM_PRI_PG_ENTRIES) + return; + + /** + * bw_pct ingnored - band-width percentage devision between user + * priorities within the same group is not + * standard and hence not supported + * + * prio_type igonred - priority levels within the same group are not + * standard and hence are not supported. According + * to the standard pgid 15 is dedicated to strict + * prioirty traffic (on the port level). + * + * up_map ignored + */ + + bp->dcbx_config_params.admin_configuration_ets_pg[prio] = pgid; + bp->dcbx_config_params.admin_ets_configuration_tx_enable = 1; +} + +static void bnx2x_dcbnl_set_pg_bwgcfg_tx(struct net_device *netdev, + int pgid, u8 bw_pct) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "pgid[%d] = %d\n", pgid, bw_pct); + + if (!bnx2x_dcbnl_set_valid(bp) || pgid >= DCBX_MAX_NUM_PG_BW_ENTRIES) + return; + + bp->dcbx_config_params.admin_configuration_bw_precentage[pgid] = bw_pct; + bp->dcbx_config_params.admin_ets_configuration_tx_enable = 1; +} + +static void bnx2x_dcbnl_set_pg_tccfg_rx(struct net_device *netdev, int prio, + u8 prio_type, u8 pgid, u8 bw_pct, + u8 up_map) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "Nothing to set; No RX support\n"); +} + +static void bnx2x_dcbnl_set_pg_bwgcfg_rx(struct net_device *netdev, + int pgid, u8 bw_pct) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "Nothing to set; No RX support\n"); +} + +static void bnx2x_dcbnl_get_pg_tccfg_tx(struct net_device *netdev, int prio, + u8 *prio_type, u8 *pgid, u8 *bw_pct, + u8 *up_map) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "prio = %d\n", prio); + + /** + * bw_pct ingnored - band-width percentage devision between user + * priorities within the same group is not + * standard and hence not supported + * + * prio_type igonred - priority levels within the same group are not + * standard and hence are not supported. According + * to the standard pgid 15 is dedicated to strict + * prioirty traffic (on the port level). + * + * up_map ignored + */ + *up_map = *bw_pct = *prio_type = *pgid = 0; + + if (!bp->dcb_state || prio >= DCBX_MAX_NUM_PRI_PG_ENTRIES) + return; + + *pgid = DCBX_PRI_PG_GET(bp->dcbx_local_feat.ets.pri_pg_tbl, prio); +} + +static void bnx2x_dcbnl_get_pg_bwgcfg_tx(struct net_device *netdev, + int pgid, u8 *bw_pct) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "pgid = %d\n", pgid); + + *bw_pct = 0; + + if (!bp->dcb_state || pgid >= DCBX_MAX_NUM_PG_BW_ENTRIES) + return; + + *bw_pct = DCBX_PG_BW_GET(bp->dcbx_local_feat.ets.pg_bw_tbl, pgid); +} + +static void bnx2x_dcbnl_get_pg_tccfg_rx(struct net_device *netdev, int prio, + u8 *prio_type, u8 *pgid, u8 *bw_pct, + u8 *up_map) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "Nothing to get; No RX support\n"); + + *prio_type = *pgid = *bw_pct = *up_map = 0; +} + +static void bnx2x_dcbnl_get_pg_bwgcfg_rx(struct net_device *netdev, + int pgid, u8 *bw_pct) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "Nothing to get; No RX support\n"); + + *bw_pct = 0; +} + +static void bnx2x_dcbnl_set_pfc_cfg(struct net_device *netdev, int prio, + u8 setting) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "prio[%d] = %d\n", prio, setting); + + if (!bnx2x_dcbnl_set_valid(bp) || prio >= MAX_PFC_PRIORITIES) + return; + + bp->dcbx_config_params.admin_pfc_bitmap |= ((setting ? 1 : 0) << prio); + + if (setting) + bp->dcbx_config_params.admin_pfc_tx_enable = 1; +} + +static void bnx2x_dcbnl_get_pfc_cfg(struct net_device *netdev, int prio, + u8 *setting) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "prio = %d\n", prio); + + *setting = 0; + + if (!bp->dcb_state || prio >= MAX_PFC_PRIORITIES) + return; + + *setting = (bp->dcbx_local_feat.pfc.pri_en_bitmap >> prio) & 0x1; +} + +static u8 bnx2x_dcbnl_set_all(struct net_device *netdev) +{ + struct bnx2x *bp = netdev_priv(netdev); + int rc = 0; + + DP(NETIF_MSG_LINK, "SET-ALL\n"); + + if (!bnx2x_dcbnl_set_valid(bp)) + return 1; + + if (bp->recovery_state != BNX2X_RECOVERY_DONE) { + netdev_err(bp->dev, "Handling parity error recovery. " + "Try again later\n"); + return 1; + } + if (netif_running(bp->dev)) { + bnx2x_nic_unload(bp, UNLOAD_NORMAL); + rc = bnx2x_nic_load(bp, LOAD_NORMAL); + } + DP(NETIF_MSG_LINK, "set_dcbx_params done (%d)\n", rc); + if (rc) + return 1; + + return 0; +} + +static u8 bnx2x_dcbnl_get_cap(struct net_device *netdev, int capid, u8 *cap) +{ + struct bnx2x *bp = netdev_priv(netdev); + u8 rval = 0; + + if (bp->dcb_state) { + switch (capid) { + case DCB_CAP_ATTR_PG: + *cap = true; + break; + case DCB_CAP_ATTR_PFC: + *cap = true; + break; + case DCB_CAP_ATTR_UP2TC: + *cap = false; + break; + case DCB_CAP_ATTR_PG_TCS: + *cap = 0x80; /* 8 priorities for PGs */ + break; + case DCB_CAP_ATTR_PFC_TCS: + *cap = 0x80; /* 8 priorities for PFC */ + break; + case DCB_CAP_ATTR_GSP: + *cap = true; + break; + case DCB_CAP_ATTR_BCN: + *cap = false; + break; + case DCB_CAP_ATTR_DCBX: + *cap = BNX2X_DCBX_CAPS; + default: + rval = -EINVAL; + break; + } + } else + rval = -EINVAL; + + DP(NETIF_MSG_LINK, "capid %d:%x\n", capid, *cap); + return rval; +} + +static u8 bnx2x_dcbnl_get_numtcs(struct net_device *netdev, int tcid, u8 *num) +{ + struct bnx2x *bp = netdev_priv(netdev); + u8 rval = 0; + + DP(NETIF_MSG_LINK, "tcid %d\n", tcid); + + if (bp->dcb_state) { + switch (tcid) { + case DCB_NUMTCS_ATTR_PG: + *num = E2_NUM_OF_COS; + break; + case DCB_NUMTCS_ATTR_PFC: + *num = E2_NUM_OF_COS; + break; + default: + rval = -EINVAL; + break; + } + } else + rval = -EINVAL; + + return rval; +} + +static u8 bnx2x_dcbnl_set_numtcs(struct net_device *netdev, int tcid, u8 num) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "num tcs = %d; Not supported\n", num); + return -EINVAL; +} + +static u8 bnx2x_dcbnl_get_pfc_state(struct net_device *netdev) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "state = %d\n", bp->dcbx_local_feat.pfc.enabled); + + if (!bp->dcb_state) + return 0; + + return bp->dcbx_local_feat.pfc.enabled; +} + +static void bnx2x_dcbnl_set_pfc_state(struct net_device *netdev, u8 state) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "state = %s\n", state ? "on" : "off"); + + if (!bnx2x_dcbnl_set_valid(bp)) + return; + + bp->dcbx_config_params.admin_pfc_tx_enable = + bp->dcbx_config_params.admin_pfc_enable = (state ? 1 : 0); +} + +static bool bnx2x_app_is_equal(struct dcbx_app_priority_entry *app_ent, + u8 idtype, u16 idval) +{ + if (!(app_ent->appBitfield & DCBX_APP_ENTRY_VALID)) + return false; + + switch (idtype) { + case DCB_APP_IDTYPE_ETHTYPE: + if ((app_ent->appBitfield & DCBX_APP_ENTRY_SF_MASK) != + DCBX_APP_SF_ETH_TYPE) + return false; + break; + case DCB_APP_IDTYPE_PORTNUM: + if ((app_ent->appBitfield & DCBX_APP_ENTRY_SF_MASK) != + DCBX_APP_SF_PORT) + return false; + break; + default: + return false; + } + if (app_ent->app_id != idval) + return false; + + return true; +} + +static void bnx2x_admin_app_set_ent( + struct bnx2x_admin_priority_app_table *app_ent, + u8 idtype, u16 idval, u8 up) +{ + app_ent->valid = 1; + + switch (idtype) { + case DCB_APP_IDTYPE_ETHTYPE: + app_ent->traffic_type = TRAFFIC_TYPE_ETH; + break; + case DCB_APP_IDTYPE_PORTNUM: + app_ent->traffic_type = TRAFFIC_TYPE_PORT; + break; + default: + break; /* never gets here */ + } + app_ent->app_id = idval; + app_ent->priority = up; +} + +static bool bnx2x_admin_app_is_equal( + struct bnx2x_admin_priority_app_table *app_ent, + u8 idtype, u16 idval) +{ + if (!app_ent->valid) + return false; + + switch (idtype) { + case DCB_APP_IDTYPE_ETHTYPE: + if (app_ent->traffic_type != TRAFFIC_TYPE_ETH) + return false; + break; + case DCB_APP_IDTYPE_PORTNUM: + if (app_ent->traffic_type != TRAFFIC_TYPE_PORT) + return false; + break; + default: + return false; + } + if (app_ent->app_id != idval) + return false; + + return true; +} + +static int bnx2x_set_admin_app_up(struct bnx2x *bp, u8 idtype, u16 idval, u8 up) +{ + int i, ff; + + /* iterate over the app entries looking for idtype and idval */ + for (i = 0, ff = -1; i < 4; i++) { + struct bnx2x_admin_priority_app_table *app_ent = + &bp->dcbx_config_params.admin_priority_app_table[i]; + if (bnx2x_admin_app_is_equal(app_ent, idtype, idval)) + break; + + if (ff < 0 && !app_ent->valid) + ff = i; + } + if (i < 4) + /* if found overwrite up */ + bp->dcbx_config_params. + admin_priority_app_table[i].priority = up; + else if (ff >= 0) + /* not found use first-free */ + bnx2x_admin_app_set_ent( + &bp->dcbx_config_params.admin_priority_app_table[ff], + idtype, idval, up); + else + /* app table is full */ + return -EBUSY; + + /* up configured, if not 0 make sure feature is enabled */ + if (up) + bp->dcbx_config_params.admin_application_priority_tx_enable = 1; + + return 0; +} + +static u8 bnx2x_dcbnl_set_app_up(struct net_device *netdev, u8 idtype, + u16 idval, u8 up) +{ + struct bnx2x *bp = netdev_priv(netdev); + + DP(NETIF_MSG_LINK, "app_type %d, app_id %x, prio bitmap %d\n", + idtype, idval, up); + + if (!bnx2x_dcbnl_set_valid(bp)) + return -EINVAL; + + /* verify idtype */ + switch (idtype) { + case DCB_APP_IDTYPE_ETHTYPE: + case DCB_APP_IDTYPE_PORTNUM: + break; + default: + return -EINVAL; + } + return bnx2x_set_admin_app_up(bp, idtype, idval, up); +} + +static u8 bnx2x_dcbnl_get_app_up(struct net_device *netdev, u8 idtype, + u16 idval) +{ + int i; + u8 up = 0; + + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "app_type %d, app_id 0x%x\n", idtype, idval); + + /* iterate over the app entries looking for idtype and idval */ + for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++) + if (bnx2x_app_is_equal(&bp->dcbx_local_feat.app.app_pri_tbl[i], + idtype, idval)) + break; + + if (i < DCBX_MAX_APP_PROTOCOL) + /* if found return up */ + up = bp->dcbx_local_feat.app.app_pri_tbl[i].pri_bitmap; + else + DP(NETIF_MSG_LINK, "app not found\n"); + + return up; +} + +static u8 bnx2x_dcbnl_get_dcbx(struct net_device *netdev) +{ + struct bnx2x *bp = netdev_priv(netdev); + u8 state; + + state = DCB_CAP_DCBX_LLD_MANAGED | DCB_CAP_DCBX_VER_CEE; + + if (bp->dcbx_enabled == BNX2X_DCBX_ENABLED_ON_NEG_OFF) + state |= DCB_CAP_DCBX_STATIC; + + return state; +} + +static u8 bnx2x_dcbnl_set_dcbx(struct net_device *netdev, u8 state) +{ + struct bnx2x *bp = netdev_priv(netdev); + DP(NETIF_MSG_LINK, "state = %02x\n", state); + + /* set dcbx mode */ + + if ((state & BNX2X_DCBX_CAPS) != state) { + BNX2X_ERR("Requested DCBX mode %x is beyond advertised " + "capabilities\n", state); + return 1; + } + + if (bp->dcb_state != BNX2X_DCB_STATE_ON) { + BNX2X_ERR("DCB turned off, DCBX configuration is invalid\n"); + return 1; + } + + if (state & DCB_CAP_DCBX_STATIC) + bp->dcbx_enabled = BNX2X_DCBX_ENABLED_ON_NEG_OFF; + else + bp->dcbx_enabled = BNX2X_DCBX_ENABLED_ON_NEG_ON; + + bp->dcbx_mode_uset = true; + return 0; +} + + +static u8 bnx2x_dcbnl_get_featcfg(struct net_device *netdev, int featid, + u8 *flags) +{ + struct bnx2x *bp = netdev_priv(netdev); + u8 rval = 0; + + DP(NETIF_MSG_LINK, "featid %d\n", featid); + + if (bp->dcb_state) { + *flags = 0; + switch (featid) { + case DCB_FEATCFG_ATTR_PG: + if (bp->dcbx_local_feat.ets.enabled) + *flags |= DCB_FEATCFG_ENABLE; + if (bp->dcbx_error & DCBX_LOCAL_ETS_ERROR) + *flags |= DCB_FEATCFG_ERROR; + break; + case DCB_FEATCFG_ATTR_PFC: + if (bp->dcbx_local_feat.pfc.enabled) + *flags |= DCB_FEATCFG_ENABLE; + if (bp->dcbx_error & (DCBX_LOCAL_PFC_ERROR | + DCBX_LOCAL_PFC_MISMATCH)) + *flags |= DCB_FEATCFG_ERROR; + break; + case DCB_FEATCFG_ATTR_APP: + if (bp->dcbx_local_feat.app.enabled) + *flags |= DCB_FEATCFG_ENABLE; + if (bp->dcbx_error & (DCBX_LOCAL_APP_ERROR | + DCBX_LOCAL_APP_MISMATCH)) + *flags |= DCB_FEATCFG_ERROR; + break; + default: + rval = -EINVAL; + break; + } + } else + rval = -EINVAL; + + return rval; +} + +static u8 bnx2x_dcbnl_set_featcfg(struct net_device *netdev, int featid, + u8 flags) +{ + struct bnx2x *bp = netdev_priv(netdev); + u8 rval = 0; + + DP(NETIF_MSG_LINK, "featid = %d flags = %02x\n", featid, flags); + + /* ignore the 'advertise' flag */ + if (bnx2x_dcbnl_set_valid(bp)) { + switch (featid) { + case DCB_FEATCFG_ATTR_PG: + bp->dcbx_config_params.admin_ets_enable = + flags & DCB_FEATCFG_ENABLE ? 1 : 0; + bp->dcbx_config_params.admin_ets_willing = + flags & DCB_FEATCFG_WILLING ? 1 : 0; + break; + case DCB_FEATCFG_ATTR_PFC: + bp->dcbx_config_params.admin_pfc_enable = + flags & DCB_FEATCFG_ENABLE ? 1 : 0; + bp->dcbx_config_params.admin_pfc_willing = + flags & DCB_FEATCFG_WILLING ? 1 : 0; + break; + case DCB_FEATCFG_ATTR_APP: + /* ignore enable, always enabled */ + bp->dcbx_config_params.admin_app_priority_willing = + flags & DCB_FEATCFG_WILLING ? 1 : 0; + break; + default: + rval = -EINVAL; + break; + } + } else + rval = -EINVAL; + + return rval; +} + +const struct dcbnl_rtnl_ops bnx2x_dcbnl_ops = { + .getstate = bnx2x_dcbnl_get_state, + .setstate = bnx2x_dcbnl_set_state, + .getpermhwaddr = bnx2x_dcbnl_get_perm_hw_addr, + .setpgtccfgtx = bnx2x_dcbnl_set_pg_tccfg_tx, + .setpgbwgcfgtx = bnx2x_dcbnl_set_pg_bwgcfg_tx, + .setpgtccfgrx = bnx2x_dcbnl_set_pg_tccfg_rx, + .setpgbwgcfgrx = bnx2x_dcbnl_set_pg_bwgcfg_rx, + .getpgtccfgtx = bnx2x_dcbnl_get_pg_tccfg_tx, + .getpgbwgcfgtx = bnx2x_dcbnl_get_pg_bwgcfg_tx, + .getpgtccfgrx = bnx2x_dcbnl_get_pg_tccfg_rx, + .getpgbwgcfgrx = bnx2x_dcbnl_get_pg_bwgcfg_rx, + .setpfccfg = bnx2x_dcbnl_set_pfc_cfg, + .getpfccfg = bnx2x_dcbnl_get_pfc_cfg, + .setall = bnx2x_dcbnl_set_all, + .getcap = bnx2x_dcbnl_get_cap, + .getnumtcs = bnx2x_dcbnl_get_numtcs, + .setnumtcs = bnx2x_dcbnl_set_numtcs, + .getpfcstate = bnx2x_dcbnl_get_pfc_state, + .setpfcstate = bnx2x_dcbnl_set_pfc_state, + .getapp = bnx2x_dcbnl_get_app_up, + .setapp = bnx2x_dcbnl_set_app_up, + .getdcbx = bnx2x_dcbnl_get_dcbx, + .setdcbx = bnx2x_dcbnl_set_dcbx, + .getfeatcfg = bnx2x_dcbnl_get_featcfg, + .setfeatcfg = bnx2x_dcbnl_set_featcfg, +}; + +#endif /* BCM_DCB */ diff --git a/drivers/net/bnx2x/bnx2x_dcb.h b/drivers/net/bnx2x/bnx2x_dcb.h new file mode 100644 index 000000000000..f650f98e4092 --- /dev/null +++ b/drivers/net/bnx2x/bnx2x_dcb.h @@ -0,0 +1,196 @@ +/* bnx2x_dcb.h: Broadcom Everest network driver. + * + * Copyright 2009-2010 Broadcom Corporation + * + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2, available + * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL"). + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a + * license other than the GPL, without Broadcom's express prior written + * consent. + * + * Maintained by: Eilon Greenstein <eilong@broadcom.com> + * Written by: Dmitry Kravkov + * + */ +#ifndef BNX2X_DCB_H +#define BNX2X_DCB_H + +#include "bnx2x_hsi.h" + +#define LLFC_DRIVER_TRAFFIC_TYPE_MAX 3 /* NW, iSCSI, FCoE */ +struct bnx2x_dcbx_app_params { + u32 enabled; + u32 traffic_type_priority[LLFC_DRIVER_TRAFFIC_TYPE_MAX]; +}; + +#define E2_NUM_OF_COS 2 +#define BNX2X_DCBX_COS_NOT_STRICT 0 +#define BNX2X_DCBX_COS_LOW_STRICT 1 +#define BNX2X_DCBX_COS_HIGH_STRICT 2 + +struct bnx2x_dcbx_cos_params { + u32 bw_tbl; + u32 pri_bitmask; + u8 strict; + u8 pauseable; +}; + +struct bnx2x_dcbx_pg_params { + u32 enabled; + u8 num_of_cos; /* valid COS entries */ + struct bnx2x_dcbx_cos_params cos_params[E2_NUM_OF_COS]; +}; + +struct bnx2x_dcbx_pfc_params { + u32 enabled; + u32 priority_non_pauseable_mask; +}; + +struct bnx2x_dcbx_port_params { + struct bnx2x_dcbx_pfc_params pfc; + struct bnx2x_dcbx_pg_params ets; + struct bnx2x_dcbx_app_params app; +}; + +#define BNX2X_DCBX_CONFIG_INV_VALUE (0xFFFFFFFF) +#define BNX2X_DCBX_OVERWRITE_SETTINGS_DISABLE 0 +#define BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE 1 +#define BNX2X_DCBX_OVERWRITE_SETTINGS_INVALID (BNX2X_DCBX_CONFIG_INV_VALUE) + +/******************************************************************************* + * LLDP protocol configuration parameters. + ******************************************************************************/ +struct bnx2x_config_lldp_params { + u32 overwrite_settings; + u32 msg_tx_hold; + u32 msg_fast_tx; + u32 tx_credit_max; + u32 msg_tx_interval; + u32 tx_fast; +}; + +struct bnx2x_admin_priority_app_table { + u32 valid; + u32 priority; +#define INVALID_TRAFFIC_TYPE_PRIORITY (0xFFFFFFFF) + u32 traffic_type; +#define TRAFFIC_TYPE_ETH 0 +#define TRAFFIC_TYPE_PORT 1 + u32 app_id; +}; + +/******************************************************************************* + * DCBX protocol configuration parameters. + ******************************************************************************/ +struct bnx2x_config_dcbx_params { + u32 overwrite_settings; + u32 admin_dcbx_version; + u32 admin_ets_enable; + u32 admin_pfc_enable; + u32 admin_tc_supported_tx_enable; + u32 admin_ets_configuration_tx_enable; + u32 admin_ets_recommendation_tx_enable; + u32 admin_pfc_tx_enable; + u32 admin_application_priority_tx_enable; + u32 admin_ets_willing; + u32 admin_ets_reco_valid; + u32 admin_pfc_willing; + u32 admin_app_priority_willing; + u32 admin_configuration_bw_precentage[8]; + u32 admin_configuration_ets_pg[8]; + u32 admin_recommendation_bw_precentage[8]; + u32 admin_recommendation_ets_pg[8]; + u32 admin_pfc_bitmap; + struct bnx2x_admin_priority_app_table admin_priority_app_table[4]; + u32 admin_default_priority; +}; + +#define GET_FLAGS(flags, bits) ((flags) & (bits)) +#define SET_FLAGS(flags, bits) ((flags) |= (bits)) +#define RESET_FLAGS(flags, bits) ((flags) &= ~(bits)) + +enum { + DCBX_READ_LOCAL_MIB, + DCBX_READ_REMOTE_MIB +}; + +#define ETH_TYPE_FCOE (0x8906) +#define TCP_PORT_ISCSI (0xCBC) + +#define PFC_VALUE_FRAME_SIZE (512) +#define PFC_QUANTA_IN_NANOSEC_FROM_SPEED_MEGA(mega_speed) \ + ((1000 * PFC_VALUE_FRAME_SIZE)/(mega_speed)) + +#define PFC_BRB1_REG_HIGH_LLFC_LOW_THRESHOLD 130 +#define PFC_BRB1_REG_HIGH_LLFC_HIGH_THRESHOLD 170 + + + +struct cos_entry_help_data { + u32 pri_join_mask; + u32 cos_bw; + u8 strict; + bool pausable; +}; + +struct cos_help_data { + struct cos_entry_help_data data[E2_NUM_OF_COS]; + u8 num_of_cos; +}; + +#define DCBX_ILLEGAL_PG (0xFF) +#define DCBX_PFC_PRI_MASK (0xFF) +#define DCBX_STRICT_PRIORITY (15) +#define DCBX_INVALID_COS_BW (0xFFFFFFFF) +#define DCBX_PFC_PRI_NON_PAUSE_MASK(bp) \ + ((bp)->dcbx_port_params.pfc.priority_non_pauseable_mask) +#define DCBX_PFC_PRI_PAUSE_MASK(bp) \ + ((u8)~DCBX_PFC_PRI_NON_PAUSE_MASK(bp)) +#define DCBX_PFC_PRI_GET_PAUSE(bp, pg_pri) \ + ((pg_pri) & (DCBX_PFC_PRI_PAUSE_MASK(bp))) +#define DCBX_PFC_PRI_GET_NON_PAUSE(bp, pg_pri) \ + (DCBX_PFC_PRI_NON_PAUSE_MASK(bp) & (pg_pri)) +#define IS_DCBX_PFC_PRI_ONLY_PAUSE(bp, pg_pri) \ + (pg_pri == DCBX_PFC_PRI_GET_PAUSE((bp), (pg_pri))) +#define IS_DCBX_PFC_PRI_ONLY_NON_PAUSE(bp, pg_pri)\ + ((pg_pri) == DCBX_PFC_PRI_GET_NON_PAUSE((bp), (pg_pri))) +#define IS_DCBX_PFC_PRI_MIX_PAUSE(bp, pg_pri) \ + (!(IS_DCBX_PFC_PRI_ONLY_NON_PAUSE((bp), (pg_pri)) || \ + IS_DCBX_PFC_PRI_ONLY_PAUSE((bp), (pg_pri)))) + + +struct pg_entry_help_data { + u8 num_of_dif_pri; + u8 pg; + u32 pg_priority; +}; + +struct pg_help_data { + struct pg_entry_help_data data[LLFC_DRIVER_TRAFFIC_TYPE_MAX]; + u8 num_of_pg; +}; + +/* forward DCB/PFC related declarations */ +struct bnx2x; +void bnx2x_dcb_init_intmem_pfc(struct bnx2x *bp); +void bnx2x_dcbx_update(struct work_struct *work); +void bnx2x_dcbx_init_params(struct bnx2x *bp); +void bnx2x_dcbx_set_state(struct bnx2x *bp, bool dcb_on, u32 dcbx_enabled); + +enum { + BNX2X_DCBX_STATE_NEG_RECEIVED = 0x1, + BNX2X_DCBX_STATE_TX_PAUSED = 0x2, + BNX2X_DCBX_STATE_TX_RELEASED = 0x4 +}; +void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state); + +/* DCB netlink */ +#ifdef BCM_DCB +extern const struct dcbnl_rtnl_ops bnx2x_dcbnl_ops; +#endif /* BCM_DCB */ + +#endif /* BNX2X_DCB_H */ diff --git a/drivers/net/bnx2x/bnx2x_dump.h b/drivers/net/bnx2x/bnx2x_dump.h index dc18c25ca9e5..fb3ff7c4d7ca 100644 --- a/drivers/net/bnx2x/bnx2x_dump.h +++ b/drivers/net/bnx2x/bnx2x_dump.h @@ -1,10 +1,16 @@ /* bnx2x_dump.h: Broadcom Everest network driver. * - * Copyright (c) 2009 Broadcom Corporation + * Copyright (c) 2011 Broadcom Corporation * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation. + * Unless you and Broadcom execute a separate written software license + * agreement governing use of this software, this software is licensed to you + * under the terms of the GNU General Public License version 2, available + * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL"). + * + * Notwithstanding the above, under no circumstances may you combine this + * software in any way with any other Broadcom software provided under a + * license other than the GPL, without Broadcom's express prior written + * consent. */ @@ -17,53 +23,53 @@ #define BNX2X_DUMP_H -struct dump_sign { - u32 time_stamp; - u32 diag_ver; - u32 grc_dump_ver; -}; -#define TSTORM_WAITP_ADDR 0x1b8a80 -#define CSTORM_WAITP_ADDR 0x238a80 -#define XSTORM_WAITP_ADDR 0x2b8a80 -#define USTORM_WAITP_ADDR 0x338a80 -#define TSTORM_CAM_MODE 0x1b1440 +/*definitions */ +#define XSTORM_WAITP_ADDR 0x2b8a80 +#define TSTORM_WAITP_ADDR 0x1b8a80 +#define USTORM_WAITP_ADDR 0x338a80 +#define CSTORM_WAITP_ADDR 0x238a80 +#define TSTORM_CAM_MODE 0x1B1440 -#define RI_E1 0x1 -#define RI_E1H 0x2 +#define MAX_TIMER_PENDING 200 +#define TIMER_SCAN_DONT_CARE 0xFF +#define RI_E1 0x1 +#define RI_E1H 0x2 #define RI_E2 0x4 -#define RI_ONLINE 0x100 +#define RI_ONLINE 0x100 #define RI_PATH0_DUMP 0x200 #define RI_PATH1_DUMP 0x400 -#define RI_E1_OFFLINE (RI_E1) -#define RI_E1_ONLINE (RI_E1 | RI_ONLINE) -#define RI_E1H_OFFLINE (RI_E1H) -#define RI_E1H_ONLINE (RI_E1H | RI_ONLINE) -#define RI_E2_OFFLINE (RI_E2) -#define RI_E2_ONLINE (RI_E2 | RI_ONLINE) -#define RI_E1E1H_OFFLINE (RI_E1 | RI_E1H) -#define RI_E1E1H_ONLINE (RI_E1 | RI_E1H | RI_ONLINE) -#define RI_E1HE2_OFFLINE (RI_E2 | RI_E1H) -#define RI_E1HE2_ONLINE (RI_E2 | RI_E1H | RI_ONLINE) -#define RI_E1E2_OFFLINE (RI_E2 | RI_E1) -#define RI_E1E2_ONLINE (RI_E2 | RI_E1 | RI_ONLINE) -#define RI_ALL_OFFLINE (RI_E1 | RI_E1H | RI_E2) -#define RI_ALL_ONLINE (RI_E1 | RI_E1H | RI_E2 | RI_ONLINE) - -#define MAX_TIMER_PENDING 200 -#define TIMER_SCAN_DONT_CARE 0xFF +#define RI_E1_OFFLINE (RI_E1) +#define RI_E1_ONLINE (RI_E1 | RI_ONLINE) +#define RI_E1H_OFFLINE (RI_E1H) +#define RI_E1H_ONLINE (RI_E1H | RI_ONLINE) +#define RI_E2_OFFLINE (RI_E2) +#define RI_E2_ONLINE (RI_E2 | RI_ONLINE) +#define RI_E1E1H_OFFLINE (RI_E1 | RI_E1H) +#define RI_E1E1H_ONLINE (RI_E1 | RI_E1H | RI_ONLINE) +#define RI_E1HE2_OFFLINE (RI_E2 | RI_E1H) +#define RI_E1HE2_ONLINE (RI_E2 | RI_E1H | RI_ONLINE) +#define RI_E1E2_OFFLINE (RI_E2 | RI_E1) +#define RI_E1E2_ONLINE (RI_E2 | RI_E1 | RI_ONLINE) +#define RI_ALL_OFFLINE (RI_E1 | RI_E1H | RI_E2) +#define RI_ALL_ONLINE (RI_E1 | RI_E1H | RI_E2 | RI_ONLINE) +struct dump_sign { + u32 time_stamp; + u32 diag_ver; + u32 grc_dump_ver; +}; struct dump_hdr { - u32 hdr_size; /* in dwords, excluding this field */ - struct dump_sign dump_sign; - u32 xstorm_waitp; - u32 tstorm_waitp; - u32 ustorm_waitp; - u32 cstorm_waitp; - u16 info; - u8 idle_chk; - u8 reserved; + u32 hdr_size; /* in dwords, excluding this field */ + struct dump_sign dump_sign; + u32 xstorm_waitp; + u32 tstorm_waitp; + u32 ustorm_waitp; + u32 cstorm_waitp; + u16 info; + u8 idle_chk; + u8 reserved; }; struct reg_addr { @@ -80,202 +86,185 @@ struct wreg_addr { u16 info; }; - -#define REGS_COUNT 558 +#define REGS_COUNT 834 static const struct reg_addr reg_addrs[REGS_COUNT] = { { 0x2000, 341, RI_ALL_ONLINE }, { 0x2800, 103, RI_ALL_ONLINE }, { 0x3000, 287, RI_ALL_ONLINE }, { 0x3800, 331, RI_ALL_ONLINE }, - { 0x8800, 6, RI_E1_ONLINE }, { 0xa000, 223, RI_ALL_ONLINE }, - { 0xa388, 1, RI_ALL_ONLINE }, { 0xa398, 1, RI_ALL_ONLINE }, - { 0xa39c, 7, RI_E1H_ONLINE }, { 0xa3c0, 3, RI_E1H_ONLINE }, - { 0xa3d0, 1, RI_E1H_ONLINE }, { 0xa3d8, 1, RI_E1H_ONLINE }, - { 0xa3e0, 1, RI_E1H_ONLINE }, { 0xa3e8, 1, RI_E1H_ONLINE }, - { 0xa3f0, 1, RI_E1H_ONLINE }, { 0xa3f8, 1, RI_E1H_ONLINE }, - { 0xa400, 69, RI_ALL_ONLINE }, { 0xa518, 1, RI_ALL_ONLINE }, - { 0xa520, 1, RI_ALL_ONLINE }, { 0xa528, 1, RI_ALL_ONLINE }, - { 0xa530, 1, RI_ALL_ONLINE }, { 0xa538, 1, RI_ALL_ONLINE }, - { 0xa540, 1, RI_ALL_ONLINE }, { 0xa548, 1, RI_ALL_ONLINE }, - { 0xa550, 1, RI_ALL_ONLINE }, { 0xa558, 1, RI_ALL_ONLINE }, - { 0xa560, 1, RI_ALL_ONLINE }, { 0xa568, 1, RI_ALL_ONLINE }, - { 0xa570, 1, RI_ALL_ONLINE }, { 0xa580, 1, RI_ALL_ONLINE }, - { 0xa590, 1, RI_ALL_ONLINE }, { 0xa5a0, 1, RI_ALL_ONLINE }, - { 0xa5c0, 1, RI_ALL_ONLINE }, { 0xa5e0, 1, RI_E1H_ONLINE }, - { 0xa5e8, 1, RI_E1H_ONLINE }, { 0xa5f0, 1, RI_E1H_ONLINE }, - { 0xa5f8, 10, RI_E1H_ONLINE }, { 0x10000, 236, RI_ALL_ONLINE }, - { 0x103bc, 1, RI_ALL_ONLINE }, { 0x103cc, 1, RI_ALL_ONLINE }, - { 0x103dc, 1, RI_ALL_ONLINE }, { 0x10400, 57, RI_ALL_ONLINE }, - { 0x104e8, 2, RI_ALL_ONLINE }, { 0x104f4, 2, RI_ALL_ONLINE }, - { 0x10500, 146, RI_ALL_ONLINE }, { 0x10750, 2, RI_ALL_ONLINE }, - { 0x10760, 2, RI_ALL_ONLINE }, { 0x10770, 2, RI_ALL_ONLINE }, - { 0x10780, 2, RI_ALL_ONLINE }, { 0x10790, 2, RI_ALL_ONLINE }, - { 0x107a0, 2, RI_ALL_ONLINE }, { 0x107b0, 2, RI_ALL_ONLINE }, - { 0x107c0, 2, RI_ALL_ONLINE }, { 0x107d0, 2, RI_ALL_ONLINE }, - { 0x107e0, 2, RI_ALL_ONLINE }, { 0x10880, 2, RI_ALL_ONLINE }, - { 0x10900, 2, RI_ALL_ONLINE }, { 0x12000, 1, RI_ALL_ONLINE }, - { 0x14000, 1, RI_ALL_ONLINE }, { 0x16000, 26, RI_E1H_ONLINE }, - { 0x16070, 18, RI_E1H_ONLINE }, { 0x160c0, 27, RI_E1H_ONLINE }, - { 0x16140, 1, RI_E1H_ONLINE }, { 0x16160, 1, RI_E1H_ONLINE }, - { 0x16180, 2, RI_E1H_ONLINE }, { 0x161c0, 2, RI_E1H_ONLINE }, - { 0x16204, 5, RI_E1H_ONLINE }, { 0x18000, 1, RI_E1H_ONLINE }, - { 0x18008, 1, RI_E1H_ONLINE }, { 0x20000, 24, RI_ALL_ONLINE }, - { 0x20060, 8, RI_ALL_ONLINE }, { 0x20080, 138, RI_ALL_ONLINE }, - { 0x202b4, 1, RI_ALL_ONLINE }, { 0x202c4, 1, RI_ALL_ONLINE }, - { 0x20400, 2, RI_ALL_ONLINE }, { 0x2040c, 8, RI_ALL_ONLINE }, - { 0x2042c, 18, RI_E1H_ONLINE }, { 0x20480, 1, RI_ALL_ONLINE }, - { 0x20500, 1, RI_ALL_ONLINE }, { 0x20600, 1, RI_ALL_ONLINE }, - { 0x28000, 1, RI_ALL_ONLINE }, { 0x28004, 8191, RI_ALL_OFFLINE }, - { 0x30000, 1, RI_ALL_ONLINE }, { 0x30004, 16383, RI_ALL_OFFLINE }, - { 0x40000, 98, RI_ALL_ONLINE }, { 0x40194, 1, RI_ALL_ONLINE }, - { 0x401a4, 1, RI_ALL_ONLINE }, { 0x401a8, 11, RI_E1H_ONLINE }, - { 0x40200, 4, RI_ALL_ONLINE }, { 0x40400, 43, RI_ALL_ONLINE }, - { 0x404b8, 1, RI_ALL_ONLINE }, { 0x404c8, 1, RI_ALL_ONLINE }, - { 0x404cc, 3, RI_E1H_ONLINE }, { 0x40500, 2, RI_ALL_ONLINE }, + { 0x8800, 6, RI_ALL_ONLINE }, { 0x8818, 1, RI_E1HE2_ONLINE }, + { 0x9000, 164, RI_E2_ONLINE }, { 0x9400, 33, RI_E2_ONLINE }, + { 0xa000, 27, RI_ALL_ONLINE }, { 0xa06c, 1, RI_E1E1H_ONLINE }, + { 0xa070, 71, RI_ALL_ONLINE }, { 0xa18c, 4, RI_E1E1H_ONLINE }, + { 0xa19c, 62, RI_ALL_ONLINE }, { 0xa294, 2, RI_E1E1H_ONLINE }, + { 0xa29c, 56, RI_ALL_ONLINE }, { 0xa39c, 7, RI_E1HE2_ONLINE }, + { 0xa3c0, 3, RI_E1HE2_ONLINE }, { 0xa3d0, 1, RI_E1HE2_ONLINE }, + { 0xa3d8, 1, RI_E1HE2_ONLINE }, { 0xa3e0, 1, RI_E1HE2_ONLINE }, + { 0xa3e8, 1, RI_E1HE2_ONLINE }, { 0xa3f0, 1, RI_E1HE2_ONLINE }, + { 0xa3f8, 1, RI_E1HE2_ONLINE }, { 0xa400, 43, RI_ALL_ONLINE }, + { 0xa4ac, 2, RI_E1E1H_ONLINE }, { 0xa4b4, 1, RI_ALL_ONLINE }, + { 0xa4b8, 2, RI_E1E1H_ONLINE }, { 0xa4c0, 3, RI_ALL_ONLINE }, + { 0xa4cc, 5, RI_E1E1H_ONLINE }, { 0xa4e0, 9, RI_ALL_ONLINE }, + { 0xa504, 1, RI_E1E1H_ONLINE }, { 0xa508, 3, RI_ALL_ONLINE }, + { 0xa518, 1, RI_ALL_ONLINE }, { 0xa520, 1, RI_ALL_ONLINE }, + { 0xa528, 1, RI_ALL_ONLINE }, { 0xa530, 1, RI_ALL_ONLINE }, + { 0xa538, 1, RI_ALL_ONLINE }, { 0xa540, 1, RI_ALL_ONLINE }, + { 0xa548, 1, RI_E1E1H_ONLINE }, { 0xa550, 1, RI_E1E1H_ONLINE }, + { 0xa558, 1, RI_E1E1H_ONLINE }, { 0xa560, 1, RI_E1E1H_ONLINE }, + { 0xa568, 1, RI_E1E1H_ONLINE }, { 0xa570, 1, RI_ALL_ONLINE }, + { 0xa580, 1, RI_ALL_ONLINE }, { 0xa590, 1, RI_ALL_ONLINE }, + { 0xa5a0, 1, RI_ALL_ONLINE }, { 0xa5c0, 1, RI_ALL_ONLINE }, + { 0xa5e0, 1, RI_E1HE2_ONLINE }, { 0xa5e8, 1, RI_E1HE2_ONLINE }, + { 0xa5f0, 1, RI_E1HE2_ONLINE }, { 0xa5f8, 10, RI_E1HE2_ONLINE }, + { 0xa620, 111, RI_E2_ONLINE }, { 0xa800, 51, RI_E2_ONLINE }, + { 0xa8d4, 4, RI_E2_ONLINE }, { 0xa8e8, 1, RI_E2_ONLINE }, + { 0xa8f0, 1, RI_E2_ONLINE }, { 0x10000, 236, RI_ALL_ONLINE }, + { 0x10400, 57, RI_ALL_ONLINE }, { 0x104e8, 2, RI_ALL_ONLINE }, + { 0x104f4, 2, RI_ALL_ONLINE }, { 0x10500, 146, RI_ALL_ONLINE }, + { 0x10750, 2, RI_ALL_ONLINE }, { 0x10760, 2, RI_ALL_ONLINE }, + { 0x10770, 2, RI_ALL_ONLINE }, { 0x10780, 2, RI_ALL_ONLINE }, + { 0x10790, 2, RI_ALL_ONLINE }, { 0x107a0, 2, RI_ALL_ONLINE }, + { 0x107b0, 2, RI_ALL_ONLINE }, { 0x107c0, 2, RI_ALL_ONLINE }, + { 0x107d0, 2, RI_ALL_ONLINE }, { 0x107e0, 2, RI_ALL_ONLINE }, + { 0x10880, 2, RI_ALL_ONLINE }, { 0x10900, 2, RI_ALL_ONLINE }, + { 0x16000, 26, RI_E1HE2_ONLINE }, { 0x16070, 18, RI_E1HE2_ONLINE }, + { 0x160c0, 27, RI_E1HE2_ONLINE }, { 0x16140, 1, RI_E1HE2_ONLINE }, + { 0x16160, 1, RI_E1HE2_ONLINE }, { 0x16180, 2, RI_E1HE2_ONLINE }, + { 0x161c0, 2, RI_E1HE2_ONLINE }, { 0x16204, 5, RI_E1HE2_ONLINE }, + { 0x18000, 1, RI_E1HE2_ONLINE }, { 0x18008, 1, RI_E1HE2_ONLINE }, + { 0x18010, 35, RI_E2_ONLINE }, { 0x180a4, 2, RI_E2_ONLINE }, + { 0x180c0, 191, RI_E2_ONLINE }, { 0x18440, 1, RI_E2_ONLINE }, + { 0x18460, 1, RI_E2_ONLINE }, { 0x18480, 2, RI_E2_ONLINE }, + { 0x184c0, 2, RI_E2_ONLINE }, { 0x18500, 15, RI_E2_ONLINE }, + { 0x20000, 24, RI_ALL_ONLINE }, { 0x20060, 8, RI_ALL_ONLINE }, + { 0x20080, 94, RI_ALL_ONLINE }, { 0x201f8, 1, RI_E1E1H_ONLINE }, + { 0x201fc, 1, RI_ALL_ONLINE }, { 0x20200, 1, RI_E1E1H_ONLINE }, + { 0x20204, 1, RI_ALL_ONLINE }, { 0x20208, 1, RI_E1E1H_ONLINE }, + { 0x2020c, 39, RI_ALL_ONLINE }, { 0x202c8, 1, RI_E2_ONLINE }, + { 0x202d8, 4, RI_E2_ONLINE }, { 0x20400, 2, RI_ALL_ONLINE }, + { 0x2040c, 8, RI_ALL_ONLINE }, { 0x2042c, 18, RI_E1HE2_ONLINE }, + { 0x20480, 1, RI_ALL_ONLINE }, { 0x20500, 1, RI_ALL_ONLINE }, + { 0x20600, 1, RI_ALL_ONLINE }, { 0x28000, 1, RI_ALL_ONLINE }, + { 0x28004, 8191, RI_ALL_OFFLINE }, { 0x30000, 1, RI_ALL_ONLINE }, + { 0x30004, 16383, RI_ALL_OFFLINE }, { 0x40000, 98, RI_ALL_ONLINE }, + { 0x401a8, 8, RI_E1HE2_ONLINE }, { 0x401c8, 1, RI_E1H_ONLINE }, + { 0x401cc, 2, RI_E1HE2_ONLINE }, { 0x401d4, 2, RI_E2_ONLINE }, + { 0x40200, 4, RI_ALL_ONLINE }, { 0x40220, 18, RI_E2_ONLINE }, + { 0x40400, 43, RI_ALL_ONLINE }, { 0x404cc, 3, RI_E1HE2_ONLINE }, + { 0x404e0, 1, RI_E2_ONLINE }, { 0x40500, 2, RI_ALL_ONLINE }, { 0x40510, 2, RI_ALL_ONLINE }, { 0x40520, 2, RI_ALL_ONLINE }, { 0x40530, 2, RI_ALL_ONLINE }, { 0x40540, 2, RI_ALL_ONLINE }, - { 0x42000, 164, RI_ALL_ONLINE }, { 0x4229c, 1, RI_ALL_ONLINE }, - { 0x422ac, 1, RI_ALL_ONLINE }, { 0x422bc, 1, RI_ALL_ONLINE }, - { 0x422d4, 5, RI_E1H_ONLINE }, { 0x42400, 49, RI_ALL_ONLINE }, - { 0x424c8, 38, RI_ALL_ONLINE }, { 0x42568, 2, RI_ALL_ONLINE }, - { 0x42800, 1, RI_ALL_ONLINE }, { 0x50000, 20, RI_ALL_ONLINE }, - { 0x50050, 8, RI_ALL_ONLINE }, { 0x50070, 88, RI_ALL_ONLINE }, - { 0x501dc, 1, RI_ALL_ONLINE }, { 0x501ec, 1, RI_ALL_ONLINE }, - { 0x501f0, 4, RI_E1H_ONLINE }, { 0x50200, 2, RI_ALL_ONLINE }, - { 0x5020c, 7, RI_ALL_ONLINE }, { 0x50228, 6, RI_E1H_ONLINE }, - { 0x50240, 1, RI_ALL_ONLINE }, { 0x50280, 1, RI_ALL_ONLINE }, + { 0x40550, 10, RI_E2_ONLINE }, { 0x40610, 2, RI_E2_ONLINE }, + { 0x42000, 164, RI_ALL_ONLINE }, { 0x422c0, 4, RI_E2_ONLINE }, + { 0x422d4, 5, RI_E1HE2_ONLINE }, { 0x422e8, 1, RI_E2_ONLINE }, + { 0x42400, 49, RI_ALL_ONLINE }, { 0x424c8, 38, RI_ALL_ONLINE }, + { 0x42568, 2, RI_ALL_ONLINE }, { 0x42640, 5, RI_E2_ONLINE }, + { 0x42800, 1, RI_ALL_ONLINE }, { 0x50000, 1, RI_ALL_ONLINE }, + { 0x50004, 19, RI_ALL_ONLINE }, { 0x50050, 8, RI_ALL_ONLINE }, + { 0x50070, 88, RI_ALL_ONLINE }, { 0x501f0, 4, RI_E1HE2_ONLINE }, + { 0x50200, 2, RI_ALL_ONLINE }, { 0x5020c, 7, RI_ALL_ONLINE }, + { 0x50228, 6, RI_E1HE2_ONLINE }, { 0x50240, 1, RI_ALL_ONLINE }, + { 0x50280, 1, RI_ALL_ONLINE }, { 0x50300, 1, RI_E2_ONLINE }, + { 0x5030c, 1, RI_E2_ONLINE }, { 0x50318, 1, RI_E2_ONLINE }, + { 0x5031c, 1, RI_E2_ONLINE }, { 0x50320, 2, RI_E2_ONLINE }, { 0x52000, 1, RI_ALL_ONLINE }, { 0x54000, 1, RI_ALL_ONLINE }, { 0x54004, 3327, RI_ALL_OFFLINE }, { 0x58000, 1, RI_ALL_ONLINE }, - { 0x58004, 8191, RI_ALL_OFFLINE }, { 0x60000, 71, RI_ALL_ONLINE }, - { 0x60128, 1, RI_ALL_ONLINE }, { 0x60138, 1, RI_ALL_ONLINE }, - { 0x6013c, 24, RI_E1H_ONLINE }, { 0x60200, 1, RI_ALL_ONLINE }, + { 0x58004, 8191, RI_E1E1H_OFFLINE }, { 0x60000, 26, RI_ALL_ONLINE }, + { 0x60068, 8, RI_E1E1H_ONLINE }, { 0x60088, 12, RI_ALL_ONLINE }, + { 0x600b8, 9, RI_E1E1H_ONLINE }, { 0x600dc, 1, RI_ALL_ONLINE }, + { 0x600e0, 5, RI_E1E1H_ONLINE }, { 0x600f4, 1, RI_ALL_ONLINE }, + { 0x600f8, 1, RI_E1E1H_ONLINE }, { 0x600fc, 8, RI_ALL_ONLINE }, + { 0x6013c, 24, RI_E1H_ONLINE }, { 0x6019c, 2, RI_E2_ONLINE }, + { 0x601ac, 18, RI_E2_ONLINE }, { 0x60200, 1, RI_ALL_ONLINE }, + { 0x60204, 2, RI_ALL_OFFLINE }, { 0x60210, 13, RI_E2_ONLINE }, { 0x61000, 1, RI_ALL_ONLINE }, { 0x61004, 511, RI_ALL_OFFLINE }, - { 0x70000, 8, RI_ALL_ONLINE }, { 0x70020, 21496, RI_ALL_OFFLINE }, - { 0x85000, 3, RI_ALL_ONLINE }, { 0x8500c, 4, RI_ALL_OFFLINE }, - { 0x8501c, 7, RI_ALL_ONLINE }, { 0x85038, 4, RI_ALL_OFFLINE }, - { 0x85048, 1, RI_ALL_ONLINE }, { 0x8504c, 109, RI_ALL_OFFLINE }, - { 0x85200, 32, RI_ALL_ONLINE }, { 0x85280, 11104, RI_ALL_OFFLINE }, - { 0xa0000, 16384, RI_ALL_ONLINE }, { 0xb0000, 16384, RI_E1H_ONLINE }, - { 0xc1000, 7, RI_ALL_ONLINE }, { 0xc1028, 1, RI_ALL_ONLINE }, - { 0xc1038, 1, RI_ALL_ONLINE }, { 0xc1800, 2, RI_ALL_ONLINE }, - { 0xc2000, 164, RI_ALL_ONLINE }, { 0xc229c, 1, RI_ALL_ONLINE }, - { 0xc22ac, 1, RI_ALL_ONLINE }, { 0xc22bc, 1, RI_ALL_ONLINE }, + { 0x70000, 8, RI_ALL_ONLINE }, { 0x70020, 8184, RI_ALL_OFFLINE }, + { 0x85000, 3, RI_ALL_ONLINE }, { 0x8501c, 7, RI_ALL_ONLINE }, + { 0x85048, 1, RI_ALL_ONLINE }, { 0x85200, 32, RI_ALL_ONLINE }, + { 0xc1000, 7, RI_ALL_ONLINE }, { 0xc103c, 2, RI_E2_ONLINE }, + { 0xc1800, 2, RI_ALL_ONLINE }, { 0xc2000, 164, RI_ALL_ONLINE }, + { 0xc22c0, 5, RI_E2_ONLINE }, { 0xc22d8, 4, RI_E2_ONLINE }, { 0xc2400, 49, RI_ALL_ONLINE }, { 0xc24c8, 38, RI_ALL_ONLINE }, { 0xc2568, 2, RI_ALL_ONLINE }, { 0xc2600, 1, RI_ALL_ONLINE }, - { 0xc4000, 165, RI_ALL_ONLINE }, { 0xc42a0, 1, RI_ALL_ONLINE }, - { 0xc42b0, 1, RI_ALL_ONLINE }, { 0xc42c0, 1, RI_ALL_ONLINE }, - { 0xc42e0, 7, RI_E1H_ONLINE }, { 0xc4400, 51, RI_ALL_ONLINE }, - { 0xc44d0, 38, RI_ALL_ONLINE }, { 0xc4570, 2, RI_ALL_ONLINE }, + { 0xc4000, 165, RI_ALL_ONLINE }, { 0xc42d8, 2, RI_E2_ONLINE }, + { 0xc42e0, 7, RI_E1HE2_ONLINE }, { 0xc42fc, 1, RI_E2_ONLINE }, + { 0xc4400, 51, RI_ALL_ONLINE }, { 0xc44d0, 38, RI_ALL_ONLINE }, + { 0xc4570, 2, RI_ALL_ONLINE }, { 0xc4578, 5, RI_E2_ONLINE }, { 0xc4600, 1, RI_ALL_ONLINE }, { 0xd0000, 19, RI_ALL_ONLINE }, { 0xd004c, 8, RI_ALL_ONLINE }, { 0xd006c, 91, RI_ALL_ONLINE }, - { 0xd01e4, 1, RI_ALL_ONLINE }, { 0xd01f4, 1, RI_ALL_ONLINE }, - { 0xd0200, 2, RI_ALL_ONLINE }, { 0xd020c, 7, RI_ALL_ONLINE }, - { 0xd0228, 18, RI_E1H_ONLINE }, { 0xd0280, 1, RI_ALL_ONLINE }, - { 0xd0300, 1, RI_ALL_ONLINE }, { 0xd0400, 1, RI_ALL_ONLINE }, - { 0xd4000, 1, RI_ALL_ONLINE }, { 0xd4004, 2559, RI_ALL_OFFLINE }, - { 0xd8000, 1, RI_ALL_ONLINE }, { 0xd8004, 8191, RI_ALL_OFFLINE }, - { 0xe0000, 21, RI_ALL_ONLINE }, { 0xe0054, 8, RI_ALL_ONLINE }, - { 0xe0074, 85, RI_ALL_ONLINE }, { 0xe01d4, 1, RI_ALL_ONLINE }, - { 0xe01e4, 1, RI_ALL_ONLINE }, { 0xe0200, 2, RI_ALL_ONLINE }, - { 0xe020c, 8, RI_ALL_ONLINE }, { 0xe022c, 18, RI_E1H_ONLINE }, + { 0xd01fc, 1, RI_E2_ONLINE }, { 0xd0200, 2, RI_ALL_ONLINE }, + { 0xd020c, 7, RI_ALL_ONLINE }, { 0xd0228, 18, RI_E1HE2_ONLINE }, + { 0xd0280, 1, RI_ALL_ONLINE }, { 0xd0300, 1, RI_ALL_ONLINE }, + { 0xd0400, 1, RI_ALL_ONLINE }, { 0xd4000, 1, RI_ALL_ONLINE }, + { 0xd4004, 2559, RI_ALL_OFFLINE }, { 0xd8000, 1, RI_ALL_ONLINE }, + { 0xd8004, 8191, RI_ALL_OFFLINE }, { 0xe0000, 21, RI_ALL_ONLINE }, + { 0xe0054, 8, RI_ALL_ONLINE }, { 0xe0074, 49, RI_ALL_ONLINE }, + { 0xe0138, 1, RI_E1E1H_ONLINE }, { 0xe013c, 35, RI_ALL_ONLINE }, + { 0xe01f4, 2, RI_E2_ONLINE }, { 0xe0200, 2, RI_ALL_ONLINE }, + { 0xe020c, 8, RI_ALL_ONLINE }, { 0xe022c, 18, RI_E1HE2_ONLINE }, { 0xe0280, 1, RI_ALL_ONLINE }, { 0xe0300, 1, RI_ALL_ONLINE }, { 0xe1000, 1, RI_ALL_ONLINE }, { 0xe2000, 1, RI_ALL_ONLINE }, { 0xe2004, 2047, RI_ALL_OFFLINE }, { 0xf0000, 1, RI_ALL_ONLINE }, { 0xf0004, 16383, RI_ALL_OFFLINE }, { 0x101000, 12, RI_ALL_ONLINE }, - { 0x10103c, 1, RI_ALL_ONLINE }, { 0x10104c, 1, RI_ALL_ONLINE }, - { 0x101050, 1, RI_E1H_ONLINE }, { 0x101100, 1, RI_ALL_ONLINE }, - { 0x101800, 8, RI_ALL_ONLINE }, { 0x102000, 18, RI_ALL_ONLINE }, - { 0x102054, 1, RI_ALL_ONLINE }, { 0x102064, 1, RI_ALL_ONLINE }, + { 0x101050, 1, RI_E1HE2_ONLINE }, { 0x101054, 3, RI_E2_ONLINE }, + { 0x101100, 1, RI_ALL_ONLINE }, { 0x101800, 8, RI_ALL_ONLINE }, + { 0x102000, 18, RI_ALL_ONLINE }, { 0x102068, 6, RI_E2_ONLINE }, { 0x102080, 17, RI_ALL_ONLINE }, { 0x1020c8, 8, RI_E1H_ONLINE }, - { 0x102400, 1, RI_ALL_ONLINE }, { 0x103000, 26, RI_ALL_ONLINE }, - { 0x103074, 1, RI_ALL_ONLINE }, { 0x103084, 1, RI_ALL_ONLINE }, - { 0x103094, 1, RI_ALL_ONLINE }, { 0x103098, 5, RI_E1H_ONLINE }, + { 0x1020e8, 9, RI_E2_ONLINE }, { 0x102400, 1, RI_ALL_ONLINE }, + { 0x103000, 26, RI_ALL_ONLINE }, { 0x103098, 5, RI_E1HE2_ONLINE }, + { 0x1030ac, 10, RI_E2_ONLINE }, { 0x1030d8, 8, RI_E2_ONLINE }, + { 0x103400, 1, RI_E2_ONLINE }, { 0x103404, 135, RI_E2_OFFLINE }, { 0x103800, 8, RI_ALL_ONLINE }, { 0x104000, 63, RI_ALL_ONLINE }, - { 0x104108, 1, RI_ALL_ONLINE }, { 0x104118, 1, RI_ALL_ONLINE }, - { 0x104200, 17, RI_ALL_ONLINE }, { 0x104400, 64, RI_ALL_ONLINE }, - { 0x104500, 192, RI_ALL_OFFLINE }, { 0x104800, 64, RI_ALL_ONLINE }, - { 0x104900, 192, RI_ALL_OFFLINE }, { 0x105000, 7, RI_ALL_ONLINE }, - { 0x10501c, 1, RI_ALL_OFFLINE }, { 0x105020, 3, RI_ALL_ONLINE }, - { 0x10502c, 1, RI_ALL_OFFLINE }, { 0x105030, 3, RI_ALL_ONLINE }, - { 0x10503c, 1, RI_ALL_OFFLINE }, { 0x105040, 3, RI_ALL_ONLINE }, - { 0x10504c, 1, RI_ALL_OFFLINE }, { 0x105050, 3, RI_ALL_ONLINE }, - { 0x10505c, 1, RI_ALL_OFFLINE }, { 0x105060, 3, RI_ALL_ONLINE }, - { 0x10506c, 1, RI_ALL_OFFLINE }, { 0x105070, 3, RI_ALL_ONLINE }, - { 0x10507c, 1, RI_ALL_OFFLINE }, { 0x105080, 3, RI_ALL_ONLINE }, - { 0x10508c, 1, RI_ALL_OFFLINE }, { 0x105090, 3, RI_ALL_ONLINE }, - { 0x10509c, 1, RI_ALL_OFFLINE }, { 0x1050a0, 3, RI_ALL_ONLINE }, - { 0x1050ac, 1, RI_ALL_OFFLINE }, { 0x1050b0, 3, RI_ALL_ONLINE }, - { 0x1050bc, 1, RI_ALL_OFFLINE }, { 0x1050c0, 3, RI_ALL_ONLINE }, - { 0x1050cc, 1, RI_ALL_OFFLINE }, { 0x1050d0, 3, RI_ALL_ONLINE }, - { 0x1050dc, 1, RI_ALL_OFFLINE }, { 0x1050e0, 3, RI_ALL_ONLINE }, - { 0x1050ec, 1, RI_ALL_OFFLINE }, { 0x1050f0, 3, RI_ALL_ONLINE }, - { 0x1050fc, 1, RI_ALL_OFFLINE }, { 0x105100, 3, RI_ALL_ONLINE }, - { 0x10510c, 1, RI_ALL_OFFLINE }, { 0x105110, 3, RI_ALL_ONLINE }, - { 0x10511c, 1, RI_ALL_OFFLINE }, { 0x105120, 3, RI_ALL_ONLINE }, - { 0x10512c, 1, RI_ALL_OFFLINE }, { 0x105130, 3, RI_ALL_ONLINE }, - { 0x10513c, 1, RI_ALL_OFFLINE }, { 0x105140, 3, RI_ALL_ONLINE }, - { 0x10514c, 1, RI_ALL_OFFLINE }, { 0x105150, 3, RI_ALL_ONLINE }, - { 0x10515c, 1, RI_ALL_OFFLINE }, { 0x105160, 3, RI_ALL_ONLINE }, - { 0x10516c, 1, RI_ALL_OFFLINE }, { 0x105170, 3, RI_ALL_ONLINE }, - { 0x10517c, 1, RI_ALL_OFFLINE }, { 0x105180, 3, RI_ALL_ONLINE }, - { 0x10518c, 1, RI_ALL_OFFLINE }, { 0x105190, 3, RI_ALL_ONLINE }, - { 0x10519c, 1, RI_ALL_OFFLINE }, { 0x1051a0, 3, RI_ALL_ONLINE }, - { 0x1051ac, 1, RI_ALL_OFFLINE }, { 0x1051b0, 3, RI_ALL_ONLINE }, - { 0x1051bc, 1, RI_ALL_OFFLINE }, { 0x1051c0, 3, RI_ALL_ONLINE }, - { 0x1051cc, 1, RI_ALL_OFFLINE }, { 0x1051d0, 3, RI_ALL_ONLINE }, - { 0x1051dc, 1, RI_ALL_OFFLINE }, { 0x1051e0, 3, RI_ALL_ONLINE }, - { 0x1051ec, 1, RI_ALL_OFFLINE }, { 0x1051f0, 3, RI_ALL_ONLINE }, - { 0x1051fc, 1, RI_ALL_OFFLINE }, { 0x105200, 3, RI_ALL_ONLINE }, - { 0x10520c, 1, RI_ALL_OFFLINE }, { 0x105210, 3, RI_ALL_ONLINE }, - { 0x10521c, 1, RI_ALL_OFFLINE }, { 0x105220, 3, RI_ALL_ONLINE }, - { 0x10522c, 1, RI_ALL_OFFLINE }, { 0x105230, 3, RI_ALL_ONLINE }, - { 0x10523c, 1, RI_ALL_OFFLINE }, { 0x105240, 3, RI_ALL_ONLINE }, - { 0x10524c, 1, RI_ALL_OFFLINE }, { 0x105250, 3, RI_ALL_ONLINE }, - { 0x10525c, 1, RI_ALL_OFFLINE }, { 0x105260, 3, RI_ALL_ONLINE }, - { 0x10526c, 1, RI_ALL_OFFLINE }, { 0x105270, 3, RI_ALL_ONLINE }, - { 0x10527c, 1, RI_ALL_OFFLINE }, { 0x105280, 3, RI_ALL_ONLINE }, - { 0x10528c, 1, RI_ALL_OFFLINE }, { 0x105290, 3, RI_ALL_ONLINE }, - { 0x10529c, 1, RI_ALL_OFFLINE }, { 0x1052a0, 3, RI_ALL_ONLINE }, - { 0x1052ac, 1, RI_ALL_OFFLINE }, { 0x1052b0, 3, RI_ALL_ONLINE }, - { 0x1052bc, 1, RI_ALL_OFFLINE }, { 0x1052c0, 3, RI_ALL_ONLINE }, - { 0x1052cc, 1, RI_ALL_OFFLINE }, { 0x1052d0, 3, RI_ALL_ONLINE }, - { 0x1052dc, 1, RI_ALL_OFFLINE }, { 0x1052e0, 3, RI_ALL_ONLINE }, - { 0x1052ec, 1, RI_ALL_OFFLINE }, { 0x1052f0, 3, RI_ALL_ONLINE }, - { 0x1052fc, 1, RI_ALL_OFFLINE }, { 0x105300, 3, RI_ALL_ONLINE }, - { 0x10530c, 1, RI_ALL_OFFLINE }, { 0x105310, 3, RI_ALL_ONLINE }, - { 0x10531c, 1, RI_ALL_OFFLINE }, { 0x105320, 3, RI_ALL_ONLINE }, - { 0x10532c, 1, RI_ALL_OFFLINE }, { 0x105330, 3, RI_ALL_ONLINE }, - { 0x10533c, 1, RI_ALL_OFFLINE }, { 0x105340, 3, RI_ALL_ONLINE }, - { 0x10534c, 1, RI_ALL_OFFLINE }, { 0x105350, 3, RI_ALL_ONLINE }, - { 0x10535c, 1, RI_ALL_OFFLINE }, { 0x105360, 3, RI_ALL_ONLINE }, - { 0x10536c, 1, RI_ALL_OFFLINE }, { 0x105370, 3, RI_ALL_ONLINE }, - { 0x10537c, 1, RI_ALL_OFFLINE }, { 0x105380, 3, RI_ALL_ONLINE }, - { 0x10538c, 1, RI_ALL_OFFLINE }, { 0x105390, 3, RI_ALL_ONLINE }, - { 0x10539c, 1, RI_ALL_OFFLINE }, { 0x1053a0, 3, RI_ALL_ONLINE }, - { 0x1053ac, 1, RI_ALL_OFFLINE }, { 0x1053b0, 3, RI_ALL_ONLINE }, - { 0x1053bc, 1, RI_ALL_OFFLINE }, { 0x1053c0, 3, RI_ALL_ONLINE }, - { 0x1053cc, 1, RI_ALL_OFFLINE }, { 0x1053d0, 3, RI_ALL_ONLINE }, - { 0x1053dc, 1, RI_ALL_OFFLINE }, { 0x1053e0, 3, RI_ALL_ONLINE }, - { 0x1053ec, 1, RI_ALL_OFFLINE }, { 0x1053f0, 3, RI_ALL_ONLINE }, - { 0x1053fc, 769, RI_ALL_OFFLINE }, { 0x108000, 33, RI_ALL_ONLINE }, - { 0x108090, 1, RI_ALL_ONLINE }, { 0x1080a0, 1, RI_ALL_ONLINE }, - { 0x1080ac, 5, RI_E1H_ONLINE }, { 0x108100, 5, RI_ALL_ONLINE }, - { 0x108120, 5, RI_ALL_ONLINE }, { 0x108200, 74, RI_ALL_ONLINE }, - { 0x108400, 74, RI_ALL_ONLINE }, { 0x108800, 152, RI_ALL_ONLINE }, - { 0x109000, 1, RI_ALL_ONLINE }, { 0x120000, 347, RI_ALL_ONLINE }, - { 0x120578, 1, RI_ALL_ONLINE }, { 0x120588, 1, RI_ALL_ONLINE }, - { 0x120598, 1, RI_ALL_ONLINE }, { 0x12059c, 23, RI_E1H_ONLINE }, - { 0x120614, 1, RI_E1H_ONLINE }, { 0x12061c, 30, RI_E1H_ONLINE }, - { 0x12080c, 65, RI_ALL_ONLINE }, { 0x120a00, 2, RI_ALL_ONLINE }, - { 0x122000, 2, RI_ALL_ONLINE }, { 0x128000, 2, RI_E1H_ONLINE }, - { 0x140000, 114, RI_ALL_ONLINE }, { 0x1401d4, 1, RI_ALL_ONLINE }, - { 0x1401e4, 1, RI_ALL_ONLINE }, { 0x140200, 6, RI_ALL_ONLINE }, - { 0x144000, 4, RI_ALL_ONLINE }, { 0x148000, 4, RI_ALL_ONLINE }, - { 0x14c000, 4, RI_ALL_ONLINE }, { 0x150000, 4, RI_ALL_ONLINE }, - { 0x154000, 4, RI_ALL_ONLINE }, { 0x158000, 4, RI_ALL_ONLINE }, - { 0x15c000, 7, RI_E1H_ONLINE }, { 0x161000, 7, RI_ALL_ONLINE }, - { 0x161028, 1, RI_ALL_ONLINE }, { 0x161038, 1, RI_ALL_ONLINE }, - { 0x161800, 2, RI_ALL_ONLINE }, { 0x164000, 60, RI_ALL_ONLINE }, - { 0x1640fc, 1, RI_ALL_ONLINE }, { 0x16410c, 1, RI_ALL_ONLINE }, - { 0x164110, 2, RI_E1H_ONLINE }, { 0x164200, 1, RI_ALL_ONLINE }, + { 0x10411c, 16, RI_E2_ONLINE }, { 0x104200, 17, RI_ALL_ONLINE }, + { 0x104400, 64, RI_ALL_ONLINE }, { 0x104500, 192, RI_ALL_OFFLINE }, + { 0x104800, 64, RI_ALL_ONLINE }, { 0x104900, 192, RI_ALL_OFFLINE }, + { 0x105000, 256, RI_ALL_ONLINE }, { 0x105400, 768, RI_ALL_OFFLINE }, + { 0x107000, 7, RI_E2_ONLINE }, { 0x108000, 33, RI_E1E1H_ONLINE }, + { 0x1080ac, 5, RI_E1H_ONLINE }, { 0x108100, 5, RI_E1E1H_ONLINE }, + { 0x108120, 5, RI_E1E1H_ONLINE }, { 0x108200, 74, RI_E1E1H_ONLINE }, + { 0x108400, 74, RI_E1E1H_ONLINE }, { 0x108800, 152, RI_E1E1H_ONLINE }, + { 0x110000, 111, RI_E2_ONLINE }, { 0x110200, 4, RI_E2_ONLINE }, + { 0x120000, 2, RI_ALL_ONLINE }, { 0x120008, 4, RI_ALL_ONLINE }, + { 0x120018, 3, RI_ALL_ONLINE }, { 0x120024, 4, RI_ALL_ONLINE }, + { 0x120034, 3, RI_ALL_ONLINE }, { 0x120040, 4, RI_ALL_ONLINE }, + { 0x120050, 3, RI_ALL_ONLINE }, { 0x12005c, 4, RI_ALL_ONLINE }, + { 0x12006c, 3, RI_ALL_ONLINE }, { 0x120078, 4, RI_ALL_ONLINE }, + { 0x120088, 3, RI_ALL_ONLINE }, { 0x120094, 4, RI_ALL_ONLINE }, + { 0x1200a4, 3, RI_ALL_ONLINE }, { 0x1200b0, 4, RI_ALL_ONLINE }, + { 0x1200c0, 3, RI_ALL_ONLINE }, { 0x1200cc, 4, RI_ALL_ONLINE }, + { 0x1200dc, 3, RI_ALL_ONLINE }, { 0x1200e8, 4, RI_ALL_ONLINE }, + { 0x1200f8, 3, RI_ALL_ONLINE }, { 0x120104, 4, RI_ALL_ONLINE }, + { 0x120114, 1, RI_ALL_ONLINE }, { 0x120118, 22, RI_ALL_ONLINE }, + { 0x120170, 2, RI_E1E1H_ONLINE }, { 0x120178, 243, RI_ALL_ONLINE }, + { 0x120544, 4, RI_E1E1H_ONLINE }, { 0x120554, 7, RI_ALL_ONLINE }, + { 0x12059c, 6, RI_E1HE2_ONLINE }, { 0x1205b4, 1, RI_E1HE2_ONLINE }, + { 0x1205b8, 16, RI_E1HE2_ONLINE }, { 0x1205f8, 4, RI_E2_ONLINE }, + { 0x120618, 1, RI_E2_ONLINE }, { 0x12061c, 20, RI_E1HE2_ONLINE }, + { 0x12066c, 11, RI_E1HE2_ONLINE }, { 0x120698, 5, RI_E2_ONLINE }, + { 0x1206b0, 76, RI_E2_ONLINE }, { 0x1207fc, 1, RI_E2_ONLINE }, + { 0x120808, 66, RI_ALL_ONLINE }, { 0x120910, 7, RI_E2_ONLINE }, + { 0x120930, 9, RI_E2_ONLINE }, { 0x120a00, 2, RI_ALL_ONLINE }, + { 0x122000, 2, RI_ALL_ONLINE }, { 0x122008, 2046, RI_E1_OFFLINE }, + { 0x128000, 2, RI_E1HE2_ONLINE }, { 0x128008, 6142, RI_E1HE2_OFFLINE }, + { 0x130000, 35, RI_E2_ONLINE }, { 0x130100, 29, RI_E2_ONLINE }, + { 0x130180, 1, RI_E2_ONLINE }, { 0x130200, 1, RI_E2_ONLINE }, + { 0x130280, 1, RI_E2_ONLINE }, { 0x130300, 5, RI_E2_ONLINE }, + { 0x130380, 1, RI_E2_ONLINE }, { 0x130400, 1, RI_E2_ONLINE }, + { 0x130480, 5, RI_E2_ONLINE }, { 0x130800, 72, RI_E2_ONLINE }, + { 0x131000, 136, RI_E2_ONLINE }, { 0x132000, 148, RI_E2_ONLINE }, + { 0x134000, 544, RI_E2_ONLINE }, { 0x140000, 64, RI_ALL_ONLINE }, + { 0x140100, 5, RI_E1E1H_ONLINE }, { 0x140114, 45, RI_ALL_ONLINE }, + { 0x140200, 6, RI_ALL_ONLINE }, { 0x140220, 4, RI_E2_ONLINE }, + { 0x140240, 4, RI_E2_ONLINE }, { 0x140260, 4, RI_E2_ONLINE }, + { 0x140280, 4, RI_E2_ONLINE }, { 0x1402a0, 4, RI_E2_ONLINE }, + { 0x1402c0, 4, RI_E2_ONLINE }, { 0x1402e0, 13, RI_E2_ONLINE }, + { 0x144000, 4, RI_E1E1H_ONLINE }, { 0x148000, 4, RI_E1E1H_ONLINE }, + { 0x14c000, 4, RI_E1E1H_ONLINE }, { 0x150000, 4, RI_E1E1H_ONLINE }, + { 0x154000, 4, RI_E1E1H_ONLINE }, { 0x158000, 4, RI_E1E1H_ONLINE }, + { 0x15c000, 2, RI_E1HE2_ONLINE }, { 0x15c008, 5, RI_E1H_ONLINE }, + { 0x15c020, 27, RI_E2_ONLINE }, { 0x15c090, 13, RI_E2_ONLINE }, + { 0x15c0c8, 34, RI_E2_ONLINE }, { 0x161000, 7, RI_ALL_ONLINE }, + { 0x16103c, 2, RI_E2_ONLINE }, { 0x161800, 2, RI_ALL_ONLINE }, + { 0x164000, 60, RI_ALL_ONLINE }, { 0x164110, 2, RI_E1HE2_ONLINE }, + { 0x164118, 15, RI_E2_ONLINE }, { 0x164200, 1, RI_ALL_ONLINE }, { 0x164208, 1, RI_ALL_ONLINE }, { 0x164210, 1, RI_ALL_ONLINE }, { 0x164218, 1, RI_ALL_ONLINE }, { 0x164220, 1, RI_ALL_ONLINE }, { 0x164228, 1, RI_ALL_ONLINE }, { 0x164230, 1, RI_ALL_ONLINE }, @@ -284,169 +273,298 @@ static const struct reg_addr reg_addrs[REGS_COUNT] = { { 0x164258, 1, RI_ALL_ONLINE }, { 0x164260, 1, RI_ALL_ONLINE }, { 0x164270, 2, RI_ALL_ONLINE }, { 0x164280, 2, RI_ALL_ONLINE }, { 0x164800, 2, RI_ALL_ONLINE }, { 0x165000, 2, RI_ALL_ONLINE }, - { 0x166000, 164, RI_ALL_ONLINE }, { 0x16629c, 1, RI_ALL_ONLINE }, - { 0x1662ac, 1, RI_ALL_ONLINE }, { 0x1662bc, 1, RI_ALL_ONLINE }, + { 0x166000, 164, RI_ALL_ONLINE }, { 0x1662cc, 7, RI_E2_ONLINE }, { 0x166400, 49, RI_ALL_ONLINE }, { 0x1664c8, 38, RI_ALL_ONLINE }, - { 0x166568, 2, RI_ALL_ONLINE }, { 0x166800, 1, RI_ALL_ONLINE }, - { 0x168000, 270, RI_ALL_ONLINE }, { 0x168444, 1, RI_ALL_ONLINE }, - { 0x168454, 1, RI_ALL_ONLINE }, { 0x168800, 19, RI_ALL_ONLINE }, - { 0x168900, 1, RI_ALL_ONLINE }, { 0x168a00, 128, RI_ALL_ONLINE }, - { 0x16a000, 1, RI_ALL_ONLINE }, { 0x16a004, 1535, RI_ALL_OFFLINE }, - { 0x16c000, 1, RI_ALL_ONLINE }, { 0x16c004, 1535, RI_ALL_OFFLINE }, - { 0x16e000, 16, RI_E1H_ONLINE }, { 0x16e100, 1, RI_E1H_ONLINE }, - { 0x16e200, 2, RI_E1H_ONLINE }, { 0x16e400, 183, RI_E1H_ONLINE }, - { 0x170000, 93, RI_ALL_ONLINE }, { 0x170180, 1, RI_ALL_ONLINE }, - { 0x170190, 1, RI_ALL_ONLINE }, { 0x170200, 4, RI_ALL_ONLINE }, - { 0x170214, 1, RI_ALL_ONLINE }, { 0x178000, 1, RI_ALL_ONLINE }, - { 0x180000, 61, RI_ALL_ONLINE }, { 0x180100, 1, RI_ALL_ONLINE }, - { 0x180110, 1, RI_ALL_ONLINE }, { 0x180120, 1, RI_ALL_ONLINE }, - { 0x180130, 1, RI_ALL_ONLINE }, { 0x18013c, 2, RI_E1H_ONLINE }, - { 0x180200, 58, RI_ALL_ONLINE }, { 0x180340, 4, RI_ALL_ONLINE }, - { 0x180400, 1, RI_ALL_ONLINE }, { 0x180404, 255, RI_ALL_OFFLINE }, + { 0x166568, 2, RI_ALL_ONLINE }, { 0x166570, 5, RI_E2_ONLINE }, + { 0x166800, 1, RI_ALL_ONLINE }, { 0x168000, 137, RI_ALL_ONLINE }, + { 0x168224, 2, RI_E1E1H_ONLINE }, { 0x16822c, 29, RI_ALL_ONLINE }, + { 0x1682a0, 12, RI_E1E1H_ONLINE }, { 0x1682d0, 12, RI_ALL_ONLINE }, + { 0x168300, 2, RI_E1E1H_ONLINE }, { 0x168308, 68, RI_ALL_ONLINE }, + { 0x168418, 2, RI_E1E1H_ONLINE }, { 0x168420, 6, RI_ALL_ONLINE }, + { 0x168800, 19, RI_ALL_ONLINE }, { 0x168900, 1, RI_ALL_ONLINE }, + { 0x168a00, 128, RI_ALL_ONLINE }, { 0x16a000, 1, RI_ALL_ONLINE }, + { 0x16a004, 1535, RI_ALL_OFFLINE }, { 0x16c000, 1, RI_ALL_ONLINE }, + { 0x16c004, 1535, RI_ALL_OFFLINE }, { 0x16e000, 16, RI_E1H_ONLINE }, + { 0x16e040, 8, RI_E2_ONLINE }, { 0x16e100, 1, RI_E1H_ONLINE }, + { 0x16e200, 2, RI_E1H_ONLINE }, { 0x16e400, 161, RI_E1H_ONLINE }, + { 0x16e684, 2, RI_E1HE2_ONLINE }, { 0x16e68c, 12, RI_E1H_ONLINE }, + { 0x16e6bc, 4, RI_E1HE2_ONLINE }, { 0x16e6cc, 4, RI_E1H_ONLINE }, + { 0x16e6e0, 12, RI_E2_ONLINE }, { 0x16e768, 17, RI_E2_ONLINE }, + { 0x170000, 24, RI_ALL_ONLINE }, { 0x170060, 4, RI_E1E1H_ONLINE }, + { 0x170070, 65, RI_ALL_ONLINE }, { 0x170194, 11, RI_E2_ONLINE }, + { 0x1701c4, 1, RI_E2_ONLINE }, { 0x1701cc, 7, RI_E2_ONLINE }, + { 0x1701ec, 1, RI_E2_ONLINE }, { 0x1701f4, 1, RI_E2_ONLINE }, + { 0x170200, 4, RI_ALL_ONLINE }, { 0x170214, 1, RI_ALL_ONLINE }, + { 0x170218, 77, RI_E2_ONLINE }, { 0x170400, 64, RI_E2_ONLINE }, + { 0x178000, 1, RI_ALL_ONLINE }, { 0x180000, 61, RI_ALL_ONLINE }, + { 0x18013c, 2, RI_E1HE2_ONLINE }, { 0x180200, 58, RI_ALL_ONLINE }, + { 0x180340, 4, RI_ALL_ONLINE }, { 0x180380, 1, RI_E2_ONLINE }, + { 0x180388, 1, RI_E2_ONLINE }, { 0x180390, 1, RI_E2_ONLINE }, + { 0x180398, 1, RI_E2_ONLINE }, { 0x1803a0, 5, RI_E2_ONLINE }, + { 0x180400, 1, RI_ALL_ONLINE }, { 0x180404, 255, RI_E1E1H_OFFLINE }, { 0x181000, 4, RI_ALL_ONLINE }, { 0x181010, 1020, RI_ALL_OFFLINE }, - { 0x1a0000, 1, RI_ALL_ONLINE }, { 0x1a0004, 1023, RI_ALL_OFFLINE }, - { 0x1a1000, 1, RI_ALL_ONLINE }, { 0x1a1004, 4607, RI_ALL_OFFLINE }, - { 0x1a5800, 2560, RI_E1H_OFFLINE }, { 0x1a8000, 64, RI_ALL_OFFLINE }, - { 0x1a8100, 1984, RI_E1H_OFFLINE }, { 0x1aa000, 1, RI_E1H_ONLINE }, - { 0x1aa004, 6655, RI_E1H_OFFLINE }, { 0x1b1800, 128, RI_ALL_OFFLINE }, - { 0x1b1c00, 128, RI_ALL_OFFLINE }, { 0x1b2000, 1, RI_ALL_OFFLINE }, - { 0x1b2400, 64, RI_E1H_OFFLINE }, { 0x1b8200, 1, RI_ALL_ONLINE }, + { 0x1a0000, 1, RI_ALL_ONLINE }, { 0x1a0004, 5631, RI_ALL_OFFLINE }, + { 0x1a5800, 2560, RI_E1HE2_OFFLINE }, { 0x1a8000, 1, RI_ALL_ONLINE }, + { 0x1a8004, 8191, RI_E1HE2_OFFLINE }, { 0x1b0000, 1, RI_ALL_ONLINE }, + { 0x1b0004, 15, RI_E1H_OFFLINE }, { 0x1b0040, 1, RI_E1HE2_ONLINE }, + { 0x1b0044, 239, RI_E1H_OFFLINE }, { 0x1b0400, 1, RI_ALL_ONLINE }, + { 0x1b0404, 255, RI_E1H_OFFLINE }, { 0x1b0800, 1, RI_ALL_ONLINE }, + { 0x1b0840, 1, RI_E1HE2_ONLINE }, { 0x1b0c00, 1, RI_ALL_ONLINE }, + { 0x1b1000, 1, RI_ALL_ONLINE }, { 0x1b1040, 1, RI_E1HE2_ONLINE }, + { 0x1b1400, 1, RI_ALL_ONLINE }, { 0x1b1440, 1, RI_E1HE2_ONLINE }, + { 0x1b1480, 1, RI_E1HE2_ONLINE }, { 0x1b14c0, 1, RI_E1HE2_ONLINE }, + { 0x1b1800, 128, RI_ALL_OFFLINE }, { 0x1b1c00, 128, RI_ALL_OFFLINE }, + { 0x1b2000, 1, RI_ALL_ONLINE }, { 0x1b2400, 1, RI_E1HE2_ONLINE }, + { 0x1b2404, 5631, RI_E2_OFFLINE }, { 0x1b8000, 1, RI_ALL_ONLINE }, + { 0x1b8040, 1, RI_ALL_ONLINE }, { 0x1b8080, 1, RI_ALL_ONLINE }, + { 0x1b80c0, 1, RI_ALL_ONLINE }, { 0x1b8100, 1, RI_ALL_ONLINE }, + { 0x1b8140, 1, RI_ALL_ONLINE }, { 0x1b8180, 1, RI_ALL_ONLINE }, + { 0x1b81c0, 1, RI_ALL_ONLINE }, { 0x1b8200, 1, RI_ALL_ONLINE }, { 0x1b8240, 1, RI_ALL_ONLINE }, { 0x1b8280, 1, RI_ALL_ONLINE }, - { 0x1b82c0, 1, RI_ALL_ONLINE }, { 0x1b8a00, 1, RI_ALL_ONLINE }, - { 0x1b8a80, 1, RI_ALL_ONLINE }, { 0x1c0000, 2, RI_ALL_ONLINE }, - { 0x200000, 65, RI_ALL_ONLINE }, { 0x200110, 1, RI_ALL_ONLINE }, - { 0x200120, 1, RI_ALL_ONLINE }, { 0x200130, 1, RI_ALL_ONLINE }, - { 0x200140, 1, RI_ALL_ONLINE }, { 0x20014c, 2, RI_E1H_ONLINE }, - { 0x200200, 58, RI_ALL_ONLINE }, { 0x200340, 4, RI_ALL_ONLINE }, - { 0x200400, 1, RI_ALL_ONLINE }, { 0x200404, 255, RI_ALL_OFFLINE }, - { 0x202000, 4, RI_ALL_ONLINE }, { 0x202010, 2044, RI_ALL_OFFLINE }, - { 0x220000, 1, RI_ALL_ONLINE }, { 0x220004, 1023, RI_ALL_OFFLINE }, - { 0x221000, 1, RI_ALL_ONLINE }, { 0x221004, 4607, RI_ALL_OFFLINE }, - { 0x225800, 1536, RI_E1H_OFFLINE }, { 0x227000, 1, RI_E1H_ONLINE }, - { 0x227004, 1023, RI_E1H_OFFLINE }, { 0x228000, 64, RI_ALL_OFFLINE }, - { 0x228100, 8640, RI_E1H_OFFLINE }, { 0x231800, 128, RI_ALL_OFFLINE }, - { 0x231c00, 128, RI_ALL_OFFLINE }, { 0x232000, 1, RI_ALL_OFFLINE }, - { 0x232400, 64, RI_E1H_OFFLINE }, { 0x238200, 1, RI_ALL_ONLINE }, - { 0x238240, 1, RI_ALL_ONLINE }, { 0x238280, 1, RI_ALL_ONLINE }, - { 0x2382c0, 1, RI_ALL_ONLINE }, { 0x238a00, 1, RI_ALL_ONLINE }, - { 0x238a80, 1, RI_ALL_ONLINE }, { 0x240000, 2, RI_ALL_ONLINE }, - { 0x280000, 65, RI_ALL_ONLINE }, { 0x280110, 1, RI_ALL_ONLINE }, - { 0x280120, 1, RI_ALL_ONLINE }, { 0x280130, 1, RI_ALL_ONLINE }, - { 0x280140, 1, RI_ALL_ONLINE }, { 0x28014c, 2, RI_E1H_ONLINE }, - { 0x280200, 58, RI_ALL_ONLINE }, { 0x280340, 4, RI_ALL_ONLINE }, - { 0x280400, 1, RI_ALL_ONLINE }, { 0x280404, 255, RI_ALL_OFFLINE }, - { 0x282000, 4, RI_ALL_ONLINE }, { 0x282010, 2044, RI_ALL_OFFLINE }, - { 0x2a0000, 1, RI_ALL_ONLINE }, { 0x2a0004, 1023, RI_ALL_OFFLINE }, - { 0x2a1000, 1, RI_ALL_ONLINE }, { 0x2a1004, 4607, RI_ALL_OFFLINE }, - { 0x2a5800, 2560, RI_E1H_OFFLINE }, { 0x2a8000, 64, RI_ALL_OFFLINE }, - { 0x2a8100, 960, RI_E1H_OFFLINE }, { 0x2a9000, 1, RI_E1H_ONLINE }, - { 0x2a9004, 7679, RI_E1H_OFFLINE }, { 0x2b1800, 128, RI_ALL_OFFLINE }, - { 0x2b1c00, 128, RI_ALL_OFFLINE }, { 0x2b2000, 1, RI_ALL_OFFLINE }, - { 0x2b2400, 64, RI_E1H_OFFLINE }, { 0x2b8200, 1, RI_ALL_ONLINE }, - { 0x2b8240, 1, RI_ALL_ONLINE }, { 0x2b8280, 1, RI_ALL_ONLINE }, - { 0x2b82c0, 1, RI_ALL_ONLINE }, { 0x2b8a00, 1, RI_ALL_ONLINE }, - { 0x2b8a80, 1, RI_ALL_ONLINE }, { 0x2c0000, 2, RI_ALL_ONLINE }, - { 0x300000, 65, RI_ALL_ONLINE }, { 0x300110, 1, RI_ALL_ONLINE }, - { 0x300120, 1, RI_ALL_ONLINE }, { 0x300130, 1, RI_ALL_ONLINE }, - { 0x300140, 1, RI_ALL_ONLINE }, { 0x30014c, 2, RI_E1H_ONLINE }, + { 0x1b82c0, 1, RI_ALL_ONLINE }, { 0x1b8300, 1, RI_ALL_ONLINE }, + { 0x1b8340, 1, RI_ALL_ONLINE }, { 0x1b8380, 1, RI_ALL_ONLINE }, + { 0x1b83c0, 1, RI_ALL_ONLINE }, { 0x1b8400, 1, RI_ALL_ONLINE }, + { 0x1b8440, 1, RI_ALL_ONLINE }, { 0x1b8480, 1, RI_ALL_ONLINE }, + { 0x1b84c0, 1, RI_ALL_ONLINE }, { 0x1b8500, 1, RI_ALL_ONLINE }, + { 0x1b8540, 1, RI_ALL_ONLINE }, { 0x1b8580, 1, RI_ALL_ONLINE }, + { 0x1b85c0, 19, RI_E2_ONLINE }, { 0x1b8800, 1, RI_ALL_ONLINE }, + { 0x1b8840, 1, RI_ALL_ONLINE }, { 0x1b8880, 1, RI_ALL_ONLINE }, + { 0x1b88c0, 1, RI_ALL_ONLINE }, { 0x1b8900, 1, RI_ALL_ONLINE }, + { 0x1b8940, 1, RI_ALL_ONLINE }, { 0x1b8980, 1, RI_ALL_ONLINE }, + { 0x1b89c0, 1, RI_ALL_ONLINE }, { 0x1b8a00, 1, RI_ALL_ONLINE }, + { 0x1b8a40, 1, RI_ALL_ONLINE }, { 0x1b8a80, 1, RI_ALL_ONLINE }, + { 0x1b8ac0, 1, RI_ALL_ONLINE }, { 0x1b8b00, 1, RI_ALL_ONLINE }, + { 0x1b8b40, 1, RI_ALL_ONLINE }, { 0x1b8b80, 1, RI_ALL_ONLINE }, + { 0x1b8bc0, 1, RI_ALL_ONLINE }, { 0x1b8c00, 1, RI_ALL_ONLINE }, + { 0x1b8c40, 1, RI_ALL_ONLINE }, { 0x1b8c80, 1, RI_ALL_ONLINE }, + { 0x1b8cc0, 1, RI_ALL_ONLINE }, { 0x1b8cc4, 1, RI_E2_ONLINE }, + { 0x1b8d00, 1, RI_ALL_ONLINE }, { 0x1b8d40, 1, RI_ALL_ONLINE }, + { 0x1b8d80, 1, RI_ALL_ONLINE }, { 0x1b8dc0, 1, RI_ALL_ONLINE }, + { 0x1b8e00, 1, RI_ALL_ONLINE }, { 0x1b8e40, 1, RI_ALL_ONLINE }, + { 0x1b8e80, 1, RI_ALL_ONLINE }, { 0x1b8e84, 1, RI_E2_ONLINE }, + { 0x1b8ec0, 1, RI_E1HE2_ONLINE }, { 0x1b8f00, 1, RI_E1HE2_ONLINE }, + { 0x1b8f40, 1, RI_E1HE2_ONLINE }, { 0x1b8f80, 1, RI_E1HE2_ONLINE }, + { 0x1b8fc0, 1, RI_E1HE2_ONLINE }, { 0x1b8fc4, 2, RI_E2_ONLINE }, + { 0x1b8fd0, 6, RI_E2_ONLINE }, { 0x1b9000, 1, RI_E2_ONLINE }, + { 0x1b9040, 3, RI_E2_ONLINE }, { 0x1b9400, 14, RI_E2_ONLINE }, + { 0x1b943c, 19, RI_E2_ONLINE }, { 0x1b9490, 10, RI_E2_ONLINE }, + { 0x1c0000, 2, RI_ALL_ONLINE }, { 0x200000, 65, RI_ALL_ONLINE }, + { 0x20014c, 2, RI_E1HE2_ONLINE }, { 0x200200, 58, RI_ALL_ONLINE }, + { 0x200340, 4, RI_ALL_ONLINE }, { 0x200380, 1, RI_E2_ONLINE }, + { 0x200388, 1, RI_E2_ONLINE }, { 0x200390, 1, RI_E2_ONLINE }, + { 0x200398, 1, RI_E2_ONLINE }, { 0x2003a0, 1, RI_E2_ONLINE }, + { 0x2003a8, 2, RI_E2_ONLINE }, { 0x200400, 1, RI_ALL_ONLINE }, + { 0x200404, 255, RI_E1E1H_OFFLINE }, { 0x202000, 4, RI_ALL_ONLINE }, + { 0x202010, 2044, RI_ALL_OFFLINE }, { 0x220000, 1, RI_ALL_ONLINE }, + { 0x220004, 5631, RI_ALL_OFFLINE }, { 0x225800, 2560, RI_E1HE2_OFFLINE}, + { 0x228000, 1, RI_ALL_ONLINE }, { 0x228004, 8191, RI_E1HE2_OFFLINE }, + { 0x230000, 1, RI_ALL_ONLINE }, { 0x230004, 15, RI_E1H_OFFLINE }, + { 0x230040, 1, RI_E1HE2_ONLINE }, { 0x230044, 239, RI_E1H_OFFLINE }, + { 0x230400, 1, RI_ALL_ONLINE }, { 0x230404, 255, RI_E1H_OFFLINE }, + { 0x230800, 1, RI_ALL_ONLINE }, { 0x230840, 1, RI_E1HE2_ONLINE }, + { 0x230c00, 1, RI_ALL_ONLINE }, { 0x231000, 1, RI_ALL_ONLINE }, + { 0x231040, 1, RI_E1HE2_ONLINE }, { 0x231400, 1, RI_ALL_ONLINE }, + { 0x231440, 1, RI_E1HE2_ONLINE }, { 0x231480, 1, RI_E1HE2_ONLINE }, + { 0x2314c0, 1, RI_E1HE2_ONLINE }, { 0x231800, 128, RI_ALL_OFFLINE }, + { 0x231c00, 128, RI_ALL_OFFLINE }, { 0x232000, 1, RI_ALL_ONLINE }, + { 0x232400, 1, RI_E1HE2_ONLINE }, { 0x232404, 5631, RI_E2_OFFLINE }, + { 0x238000, 1, RI_ALL_ONLINE }, { 0x238040, 1, RI_ALL_ONLINE }, + { 0x238080, 1, RI_ALL_ONLINE }, { 0x2380c0, 1, RI_ALL_ONLINE }, + { 0x238100, 1, RI_ALL_ONLINE }, { 0x238140, 1, RI_ALL_ONLINE }, + { 0x238180, 1, RI_ALL_ONLINE }, { 0x2381c0, 1, RI_ALL_ONLINE }, + { 0x238200, 1, RI_ALL_ONLINE }, { 0x238240, 1, RI_ALL_ONLINE }, + { 0x238280, 1, RI_ALL_ONLINE }, { 0x2382c0, 1, RI_ALL_ONLINE }, + { 0x238300, 1, RI_ALL_ONLINE }, { 0x238340, 1, RI_ALL_ONLINE }, + { 0x238380, 1, RI_ALL_ONLINE }, { 0x2383c0, 1, RI_ALL_ONLINE }, + { 0x238400, 1, RI_ALL_ONLINE }, { 0x238440, 1, RI_ALL_ONLINE }, + { 0x238480, 1, RI_ALL_ONLINE }, { 0x2384c0, 1, RI_ALL_ONLINE }, + { 0x238500, 1, RI_ALL_ONLINE }, { 0x238540, 1, RI_ALL_ONLINE }, + { 0x238580, 1, RI_ALL_ONLINE }, { 0x2385c0, 19, RI_E2_ONLINE }, + { 0x238800, 1, RI_ALL_ONLINE }, { 0x238840, 1, RI_ALL_ONLINE }, + { 0x238880, 1, RI_ALL_ONLINE }, { 0x2388c0, 1, RI_ALL_ONLINE }, + { 0x238900, 1, RI_ALL_ONLINE }, { 0x238940, 1, RI_ALL_ONLINE }, + { 0x238980, 1, RI_ALL_ONLINE }, { 0x2389c0, 1, RI_ALL_ONLINE }, + { 0x238a00, 1, RI_ALL_ONLINE }, { 0x238a40, 1, RI_ALL_ONLINE }, + { 0x238a80, 1, RI_ALL_ONLINE }, { 0x238ac0, 1, RI_ALL_ONLINE }, + { 0x238b00, 1, RI_ALL_ONLINE }, { 0x238b40, 1, RI_ALL_ONLINE }, + { 0x238b80, 1, RI_ALL_ONLINE }, { 0x238bc0, 1, RI_ALL_ONLINE }, + { 0x238c00, 1, RI_ALL_ONLINE }, { 0x238c40, 1, RI_ALL_ONLINE }, + { 0x238c80, 1, RI_ALL_ONLINE }, { 0x238cc0, 1, RI_ALL_ONLINE }, + { 0x238cc4, 1, RI_E2_ONLINE }, { 0x238d00, 1, RI_ALL_ONLINE }, + { 0x238d40, 1, RI_ALL_ONLINE }, { 0x238d80, 1, RI_ALL_ONLINE }, + { 0x238dc0, 1, RI_ALL_ONLINE }, { 0x238e00, 1, RI_ALL_ONLINE }, + { 0x238e40, 1, RI_ALL_ONLINE }, { 0x238e80, 1, RI_ALL_ONLINE }, + { 0x238e84, 1, RI_E2_ONLINE }, { 0x238ec0, 1, RI_E1HE2_ONLINE }, + { 0x238f00, 1, RI_E1HE2_ONLINE }, { 0x238f40, 1, RI_E1HE2_ONLINE }, + { 0x238f80, 1, RI_E1HE2_ONLINE }, { 0x238fc0, 1, RI_E1HE2_ONLINE }, + { 0x238fc4, 2, RI_E2_ONLINE }, { 0x238fd0, 6, RI_E2_ONLINE }, + { 0x239000, 1, RI_E2_ONLINE }, { 0x239040, 3, RI_E2_ONLINE }, + { 0x240000, 2, RI_ALL_ONLINE }, { 0x280000, 65, RI_ALL_ONLINE }, + { 0x28014c, 2, RI_E1HE2_ONLINE }, { 0x280200, 58, RI_ALL_ONLINE }, + { 0x280340, 4, RI_ALL_ONLINE }, { 0x280380, 1, RI_E2_ONLINE }, + { 0x280388, 1, RI_E2_ONLINE }, { 0x280390, 1, RI_E2_ONLINE }, + { 0x280398, 1, RI_E2_ONLINE }, { 0x2803a0, 1, RI_E2_ONLINE }, + { 0x2803a8, 2, RI_E2_ONLINE }, { 0x280400, 1, RI_ALL_ONLINE }, + { 0x280404, 255, RI_E1E1H_OFFLINE }, { 0x282000, 4, RI_ALL_ONLINE }, + { 0x282010, 2044, RI_ALL_OFFLINE }, { 0x2a0000, 1, RI_ALL_ONLINE }, + { 0x2a0004, 5631, RI_ALL_OFFLINE }, { 0x2a5800, 2560, RI_E1HE2_OFFLINE}, + { 0x2a8000, 1, RI_ALL_ONLINE }, { 0x2a8004, 8191, RI_E1HE2_OFFLINE }, + { 0x2b0000, 1, RI_ALL_ONLINE }, { 0x2b0004, 15, RI_E1H_OFFLINE }, + { 0x2b0040, 1, RI_E1HE2_ONLINE }, { 0x2b0044, 239, RI_E1H_OFFLINE }, + { 0x2b0400, 1, RI_ALL_ONLINE }, { 0x2b0404, 255, RI_E1H_OFFLINE }, + { 0x2b0800, 1, RI_ALL_ONLINE }, { 0x2b0840, 1, RI_E1HE2_ONLINE }, + { 0x2b0c00, 1, RI_ALL_ONLINE }, { 0x2b1000, 1, RI_ALL_ONLINE }, + { 0x2b1040, 1, RI_E1HE2_ONLINE }, { 0x2b1400, 1, RI_ALL_ONLINE }, + { 0x2b1440, 1, RI_E1HE2_ONLINE }, { 0x2b1480, 1, RI_E1HE2_ONLINE }, + { 0x2b14c0, 1, RI_E1HE2_ONLINE }, { 0x2b1800, 128, RI_ALL_OFFLINE }, + { 0x2b1c00, 128, RI_ALL_OFFLINE }, { 0x2b2000, 1, RI_ALL_ONLINE }, + { 0x2b2400, 1, RI_E1HE2_ONLINE }, { 0x2b2404, 5631, RI_E2_OFFLINE }, + { 0x2b8000, 1, RI_ALL_ONLINE }, { 0x2b8040, 1, RI_ALL_ONLINE }, + { 0x2b8080, 1, RI_ALL_ONLINE }, { 0x2b80c0, 1, RI_ALL_ONLINE }, + { 0x2b8100, 1, RI_ALL_ONLINE }, { 0x2b8140, 1, RI_ALL_ONLINE }, + { 0x2b8180, 1, RI_ALL_ONLINE }, { 0x2b81c0, 1, RI_ALL_ONLINE }, + { 0x2b8200, 1, RI_ALL_ONLINE }, { 0x2b8240, 1, RI_ALL_ONLINE }, + { 0x2b8280, 1, RI_ALL_ONLINE }, { 0x2b82c0, 1, RI_ALL_ONLINE }, + { 0x2b8300, 1, RI_ALL_ONLINE }, { 0x2b8340, 1, RI_ALL_ONLINE }, + { 0x2b8380, 1, RI_ALL_ONLINE }, { 0x2b83c0, 1, RI_ALL_ONLINE }, + { 0x2b8400, 1, RI_ALL_ONLINE }, { 0x2b8440, 1, RI_ALL_ONLINE }, + { 0x2b8480, 1, RI_ALL_ONLINE }, { 0x2b84c0, 1, RI_ALL_ONLINE }, + { 0x2b8500, 1, RI_ALL_ONLINE }, { 0x2b8540, 1, RI_ALL_ONLINE }, + { 0x2b8580, 1, RI_ALL_ONLINE }, { 0x2b85c0, 19, RI_E2_ONLINE }, + { 0x2b8800, 1, RI_ALL_ONLINE }, { 0x2b8840, 1, RI_ALL_ONLINE }, + { 0x2b8880, 1, RI_ALL_ONLINE }, { 0x2b88c0, 1, RI_ALL_ONLINE }, + { 0x2b8900, 1, RI_ALL_ONLINE }, { 0x2b8940, 1, RI_ALL_ONLINE }, + { 0x2b8980, 1, RI_ALL_ONLINE }, { 0x2b89c0, 1, RI_ALL_ONLINE }, + { 0x2b8a00, 1, RI_ALL_ONLINE }, { 0x2b8a40, 1, RI_ALL_ONLINE }, + { 0x2b8a80, 1, RI_ALL_ONLINE }, { 0x2b8ac0, 1, RI_ALL_ONLINE }, + { 0x2b8b00, 1, RI_ALL_ONLINE }, { 0x2b8b40, 1, RI_ALL_ONLINE }, + { 0x2b8b80, 1, RI_ALL_ONLINE }, { 0x2b8bc0, 1, RI_ALL_ONLINE }, + { 0x2b8c00, 1, RI_ALL_ONLINE }, { 0x2b8c40, 1, RI_ALL_ONLINE }, + { 0x2b8c80, 1, RI_ALL_ONLINE }, { 0x2b8cc0, 1, RI_ALL_ONLINE }, + { 0x2b8cc4, 1, RI_E2_ONLINE }, { 0x2b8d00, 1, RI_ALL_ONLINE }, + { 0x2b8d40, 1, RI_ALL_ONLINE }, { 0x2b8d80, 1, RI_ALL_ONLINE }, + { 0x2b8dc0, 1, RI_ALL_ONLINE }, { 0x2b8e00, 1, RI_ALL_ONLINE }, + { 0x2b8e40, 1, RI_ALL_ONLINE }, { 0x2b8e80, 1, RI_ALL_ONLINE }, + { 0x2b8e84, 1, RI_E2_ONLINE }, { 0x2b8ec0, 1, RI_E1HE2_ONLINE }, + { 0x2b8f00, 1, RI_E1HE2_ONLINE }, { 0x2b8f40, 1, RI_E1HE2_ONLINE }, + { 0x2b8f80, 1, RI_E1HE2_ONLINE }, { 0x2b8fc0, 1, RI_E1HE2_ONLINE }, + { 0x2b8fc4, 2, RI_E2_ONLINE }, { 0x2b8fd0, 6, RI_E2_ONLINE }, + { 0x2b9000, 1, RI_E2_ONLINE }, { 0x2b9040, 3, RI_E2_ONLINE }, + { 0x2b9400, 14, RI_E2_ONLINE }, { 0x2b943c, 19, RI_E2_ONLINE }, + { 0x2b9490, 10, RI_E2_ONLINE }, { 0x2c0000, 2, RI_ALL_ONLINE }, + { 0x300000, 65, RI_ALL_ONLINE }, { 0x30014c, 2, RI_E1HE2_ONLINE }, { 0x300200, 58, RI_ALL_ONLINE }, { 0x300340, 4, RI_ALL_ONLINE }, - { 0x300400, 1, RI_ALL_ONLINE }, { 0x300404, 255, RI_ALL_OFFLINE }, + { 0x300380, 1, RI_E2_ONLINE }, { 0x300388, 1, RI_E2_ONLINE }, + { 0x300390, 1, RI_E2_ONLINE }, { 0x300398, 1, RI_E2_ONLINE }, + { 0x3003a0, 1, RI_E2_ONLINE }, { 0x3003a8, 2, RI_E2_ONLINE }, + { 0x300400, 1, RI_ALL_ONLINE }, { 0x300404, 255, RI_E1E1H_OFFLINE }, { 0x302000, 4, RI_ALL_ONLINE }, { 0x302010, 2044, RI_ALL_OFFLINE }, - { 0x320000, 1, RI_ALL_ONLINE }, { 0x320004, 1023, RI_ALL_OFFLINE }, - { 0x321000, 1, RI_ALL_ONLINE }, { 0x321004, 4607, RI_ALL_OFFLINE }, - { 0x325800, 2560, RI_E1H_OFFLINE }, { 0x328000, 64, RI_ALL_OFFLINE }, - { 0x328100, 536, RI_E1H_OFFLINE }, { 0x328960, 1, RI_E1H_ONLINE }, - { 0x328964, 8103, RI_E1H_OFFLINE }, { 0x331800, 128, RI_ALL_OFFLINE }, - { 0x331c00, 128, RI_ALL_OFFLINE }, { 0x332000, 1, RI_ALL_OFFLINE }, - { 0x332400, 64, RI_E1H_OFFLINE }, { 0x338200, 1, RI_ALL_ONLINE }, + { 0x320000, 1, RI_ALL_ONLINE }, { 0x320004, 5631, RI_ALL_OFFLINE }, + { 0x325800, 2560, RI_E1HE2_OFFLINE }, { 0x328000, 1, RI_ALL_ONLINE }, + { 0x328004, 8191, RI_E1HE2_OFFLINE }, { 0x330000, 1, RI_ALL_ONLINE }, + { 0x330004, 15, RI_E1H_OFFLINE }, { 0x330040, 1, RI_E1HE2_ONLINE }, + { 0x330044, 239, RI_E1H_OFFLINE }, { 0x330400, 1, RI_ALL_ONLINE }, + { 0x330404, 255, RI_E1H_OFFLINE }, { 0x330800, 1, RI_ALL_ONLINE }, + { 0x330840, 1, RI_E1HE2_ONLINE }, { 0x330c00, 1, RI_ALL_ONLINE }, + { 0x331000, 1, RI_ALL_ONLINE }, { 0x331040, 1, RI_E1HE2_ONLINE }, + { 0x331400, 1, RI_ALL_ONLINE }, { 0x331440, 1, RI_E1HE2_ONLINE }, + { 0x331480, 1, RI_E1HE2_ONLINE }, { 0x3314c0, 1, RI_E1HE2_ONLINE }, + { 0x331800, 128, RI_ALL_OFFLINE }, { 0x331c00, 128, RI_ALL_OFFLINE }, + { 0x332000, 1, RI_ALL_ONLINE }, { 0x332400, 1, RI_E1HE2_ONLINE }, + { 0x332404, 5631, RI_E2_OFFLINE }, { 0x338000, 1, RI_ALL_ONLINE }, + { 0x338040, 1, RI_ALL_ONLINE }, { 0x338080, 1, RI_ALL_ONLINE }, + { 0x3380c0, 1, RI_ALL_ONLINE }, { 0x338100, 1, RI_ALL_ONLINE }, + { 0x338140, 1, RI_ALL_ONLINE }, { 0x338180, 1, RI_ALL_ONLINE }, + { 0x3381c0, 1, RI_ALL_ONLINE }, { 0x338200, 1, RI_ALL_ONLINE }, { 0x338240, 1, RI_ALL_ONLINE }, { 0x338280, 1, RI_ALL_ONLINE }, - { 0x3382c0, 1, RI_ALL_ONLINE }, { 0x338a00, 1, RI_ALL_ONLINE }, - { 0x338a80, 1, RI_ALL_ONLINE }, { 0x340000, 2, RI_ALL_ONLINE } + { 0x3382c0, 1, RI_ALL_ONLINE }, { 0x338300, 1, RI_ALL_ONLINE }, + { 0x338340, 1, RI_ALL_ONLINE }, { 0x338380, 1, RI_ALL_ONLINE }, + { 0x3383c0, 1, RI_ALL_ONLINE }, { 0x338400, 1, RI_ALL_ONLINE }, + { 0x338440, 1, RI_ALL_ONLINE }, { 0x338480, 1, RI_ALL_ONLINE }, + { 0x3384c0, 1, RI_ALL_ONLINE }, { 0x338500, 1, RI_ALL_ONLINE }, + { 0x338540, 1, RI_ALL_ONLINE }, { 0x338580, 1, RI_ALL_ONLINE }, + { 0x3385c0, 19, RI_E2_ONLINE }, { 0x338800, 1, RI_ALL_ONLINE }, + { 0x338840, 1, RI_ALL_ONLINE }, { 0x338880, 1, RI_ALL_ONLINE }, + { 0x3388c0, 1, RI_ALL_ONLINE }, { 0x338900, 1, RI_ALL_ONLINE }, + { 0x338940, 1, RI_ALL_ONLINE }, { 0x338980, 1, RI_ALL_ONLINE }, + { 0x3389c0, 1, RI_ALL_ONLINE }, { 0x338a00, 1, RI_ALL_ONLINE }, + { 0x338a40, 1, RI_ALL_ONLINE }, { 0x338a80, 1, RI_ALL_ONLINE }, + { 0x338ac0, 1, RI_ALL_ONLINE }, { 0x338b00, 1, RI_ALL_ONLINE }, + { 0x338b40, 1, RI_ALL_ONLINE }, { 0x338b80, 1, RI_ALL_ONLINE }, + { 0x338bc0, 1, RI_ALL_ONLINE }, { 0x338c00, 1, RI_ALL_ONLINE }, + { 0x338c40, 1, RI_ALL_ONLINE }, { 0x338c80, 1, RI_ALL_ONLINE }, + { 0x338cc0, 1, RI_ALL_ONLINE }, { 0x338cc4, 1, RI_E2_ONLINE }, + { 0x338d00, 1, RI_ALL_ONLINE }, { 0x338d40, 1, RI_ALL_ONLINE }, + { 0x338d80, 1, RI_ALL_ONLINE }, { 0x338dc0, 1, RI_ALL_ONLINE }, + { 0x338e00, 1, RI_ALL_ONLINE }, { 0x338e40, 1, RI_ALL_ONLINE }, + { 0x338e80, 1, RI_ALL_ONLINE }, { 0x338e84, 1, RI_E2_ONLINE }, + { 0x338ec0, 1, RI_E1HE2_ONLINE }, { 0x338f00, 1, RI_E1HE2_ONLINE }, + { 0x338f40, 1, RI_E1HE2_ONLINE }, { 0x338f80, 1, RI_E1HE2_ONLINE }, + { 0x338fc0, 1, RI_E1HE2_ONLINE }, { 0x338fc4, 2, RI_E2_ONLINE }, + { 0x338fd0, 6, RI_E2_ONLINE }, { 0x339000, 1, RI_E2_ONLINE }, + { 0x339040, 3, RI_E2_ONLINE }, { 0x340000, 2, RI_ALL_ONLINE }, }; - -#define IDLE_REGS_COUNT 277 +#define IDLE_REGS_COUNT 237 static const struct reg_addr idle_addrs[IDLE_REGS_COUNT] = { - { 0x2114, 1, RI_ALL_ONLINE }, { 0x2120, 1, RI_ALL_ONLINE }, - { 0x212c, 4, RI_ALL_ONLINE }, { 0x2814, 1, RI_ALL_ONLINE }, - { 0x281c, 2, RI_ALL_ONLINE }, { 0xa38c, 1, RI_ALL_ONLINE }, + { 0x2104, 1, RI_ALL_ONLINE }, { 0x2110, 2, RI_ALL_ONLINE }, + { 0x211c, 8, RI_ALL_ONLINE }, { 0x2814, 1, RI_ALL_ONLINE }, + { 0x281c, 2, RI_ALL_ONLINE }, { 0x2854, 1, RI_ALL_ONLINE }, + { 0x285c, 1, RI_ALL_ONLINE }, { 0x9010, 7, RI_E2_ONLINE }, + { 0x9030, 1, RI_E2_ONLINE }, { 0x9068, 16, RI_E2_ONLINE }, + { 0x9230, 2, RI_E2_ONLINE }, { 0x9244, 1, RI_E2_ONLINE }, + { 0x9298, 1, RI_E2_ONLINE }, { 0x92a8, 1, RI_E2_ONLINE }, + { 0xa38c, 1, RI_ALL_ONLINE }, { 0xa3c4, 1, RI_E1HE2_ONLINE }, { 0xa408, 1, RI_ALL_ONLINE }, { 0xa42c, 12, RI_ALL_ONLINE }, - { 0xa600, 5, RI_E1H_ONLINE }, { 0xa618, 1, RI_E1H_ONLINE }, - { 0xc09c, 1, RI_ALL_ONLINE }, { 0x103b0, 1, RI_ALL_ONLINE }, - { 0x103c0, 1, RI_ALL_ONLINE }, { 0x103d0, 1, RI_E1H_ONLINE }, - { 0x2021c, 11, RI_ALL_ONLINE }, { 0x202a8, 1, RI_ALL_ONLINE }, - { 0x202b8, 1, RI_ALL_ONLINE }, { 0x20404, 1, RI_ALL_ONLINE }, - { 0x2040c, 2, RI_ALL_ONLINE }, { 0x2041c, 2, RI_ALL_ONLINE }, - { 0x40154, 14, RI_ALL_ONLINE }, { 0x40198, 1, RI_ALL_ONLINE }, - { 0x404ac, 1, RI_ALL_ONLINE }, { 0x404bc, 1, RI_ALL_ONLINE }, - { 0x42290, 1, RI_ALL_ONLINE }, { 0x422a0, 1, RI_ALL_ONLINE }, - { 0x422b0, 1, RI_ALL_ONLINE }, { 0x42548, 1, RI_ALL_ONLINE }, - { 0x42550, 1, RI_ALL_ONLINE }, { 0x42558, 1, RI_ALL_ONLINE }, - { 0x50160, 8, RI_ALL_ONLINE }, { 0x501d0, 1, RI_ALL_ONLINE }, - { 0x501e0, 1, RI_ALL_ONLINE }, { 0x50204, 1, RI_ALL_ONLINE }, - { 0x5020c, 2, RI_ALL_ONLINE }, { 0x5021c, 1, RI_ALL_ONLINE }, - { 0x60090, 1, RI_ALL_ONLINE }, { 0x6011c, 1, RI_ALL_ONLINE }, - { 0x6012c, 1, RI_ALL_ONLINE }, { 0xc101c, 1, RI_ALL_ONLINE }, - { 0xc102c, 1, RI_ALL_ONLINE }, { 0xc2290, 1, RI_ALL_ONLINE }, - { 0xc22a0, 1, RI_ALL_ONLINE }, { 0xc22b0, 1, RI_ALL_ONLINE }, - { 0xc2548, 1, RI_ALL_ONLINE }, { 0xc2550, 1, RI_ALL_ONLINE }, - { 0xc2558, 1, RI_ALL_ONLINE }, { 0xc4294, 1, RI_ALL_ONLINE }, - { 0xc42a4, 1, RI_ALL_ONLINE }, { 0xc42b4, 1, RI_ALL_ONLINE }, - { 0xc4550, 1, RI_ALL_ONLINE }, { 0xc4558, 1, RI_ALL_ONLINE }, - { 0xc4560, 1, RI_ALL_ONLINE }, { 0xd016c, 8, RI_ALL_ONLINE }, - { 0xd01d8, 1, RI_ALL_ONLINE }, { 0xd01e8, 1, RI_ALL_ONLINE }, - { 0xd0204, 1, RI_ALL_ONLINE }, { 0xd020c, 3, RI_ALL_ONLINE }, - { 0xe0154, 8, RI_ALL_ONLINE }, { 0xe01c8, 1, RI_ALL_ONLINE }, - { 0xe01d8, 1, RI_ALL_ONLINE }, { 0xe0204, 1, RI_ALL_ONLINE }, - { 0xe020c, 2, RI_ALL_ONLINE }, { 0xe021c, 2, RI_ALL_ONLINE }, - { 0x101014, 1, RI_ALL_ONLINE }, { 0x101030, 1, RI_ALL_ONLINE }, - { 0x101040, 1, RI_ALL_ONLINE }, { 0x102058, 1, RI_ALL_ONLINE }, - { 0x102080, 16, RI_ALL_ONLINE }, { 0x103004, 2, RI_ALL_ONLINE }, - { 0x103068, 1, RI_ALL_ONLINE }, { 0x103078, 1, RI_ALL_ONLINE }, - { 0x103088, 1, RI_ALL_ONLINE }, { 0x10309c, 2, RI_E1H_ONLINE }, + { 0xa600, 5, RI_E1HE2_ONLINE }, { 0xa618, 1, RI_E1HE2_ONLINE }, + { 0xa714, 1, RI_E2_ONLINE }, { 0xa720, 1, RI_E2_ONLINE }, + { 0xa750, 1, RI_E2_ONLINE }, { 0xc09c, 1, RI_E1E1H_ONLINE }, + { 0x103b0, 1, RI_ALL_ONLINE }, { 0x103c0, 1, RI_ALL_ONLINE }, + { 0x103d0, 1, RI_E1H_ONLINE }, { 0x183bc, 1, RI_E2_ONLINE }, + { 0x183cc, 1, RI_E2_ONLINE }, { 0x2021c, 11, RI_ALL_ONLINE }, + { 0x202a8, 1, RI_ALL_ONLINE }, { 0x202b8, 1, RI_ALL_ONLINE }, + { 0x20404, 1, RI_ALL_ONLINE }, { 0x2040c, 2, RI_ALL_ONLINE }, + { 0x2041c, 2, RI_ALL_ONLINE }, { 0x40154, 14, RI_ALL_ONLINE }, + { 0x40198, 1, RI_ALL_ONLINE }, { 0x404ac, 1, RI_ALL_ONLINE }, + { 0x404bc, 1, RI_ALL_ONLINE }, { 0x42290, 1, RI_ALL_ONLINE }, + { 0x422a0, 1, RI_ALL_ONLINE }, { 0x422b0, 1, RI_ALL_ONLINE }, + { 0x42548, 1, RI_ALL_ONLINE }, { 0x42550, 1, RI_ALL_ONLINE }, + { 0x42558, 1, RI_ALL_ONLINE }, { 0x50160, 8, RI_ALL_ONLINE }, + { 0x501d0, 1, RI_ALL_ONLINE }, { 0x501e0, 1, RI_ALL_ONLINE }, + { 0x50204, 1, RI_ALL_ONLINE }, { 0x5020c, 2, RI_ALL_ONLINE }, + { 0x5021c, 1, RI_ALL_ONLINE }, { 0x60090, 1, RI_ALL_ONLINE }, + { 0x6011c, 1, RI_ALL_ONLINE }, { 0x6012c, 1, RI_ALL_ONLINE }, + { 0xc101c, 1, RI_ALL_ONLINE }, { 0xc102c, 1, RI_ALL_ONLINE }, + { 0xc2290, 1, RI_ALL_ONLINE }, { 0xc22a0, 1, RI_ALL_ONLINE }, + { 0xc22b0, 1, RI_ALL_ONLINE }, { 0xc2548, 1, RI_ALL_ONLINE }, + { 0xc2550, 1, RI_ALL_ONLINE }, { 0xc2558, 1, RI_ALL_ONLINE }, + { 0xc4294, 1, RI_ALL_ONLINE }, { 0xc42a4, 1, RI_ALL_ONLINE }, + { 0xc42b4, 1, RI_ALL_ONLINE }, { 0xc4550, 1, RI_ALL_ONLINE }, + { 0xc4558, 1, RI_ALL_ONLINE }, { 0xc4560, 1, RI_ALL_ONLINE }, + { 0xd016c, 8, RI_ALL_ONLINE }, { 0xd01d8, 1, RI_ALL_ONLINE }, + { 0xd01e8, 1, RI_ALL_ONLINE }, { 0xd0204, 1, RI_ALL_ONLINE }, + { 0xd020c, 3, RI_ALL_ONLINE }, { 0xe0154, 8, RI_ALL_ONLINE }, + { 0xe01c8, 1, RI_ALL_ONLINE }, { 0xe01d8, 1, RI_ALL_ONLINE }, + { 0xe0204, 1, RI_ALL_ONLINE }, { 0xe020c, 2, RI_ALL_ONLINE }, + { 0xe021c, 2, RI_ALL_ONLINE }, { 0x101014, 1, RI_ALL_ONLINE }, + { 0x101030, 1, RI_ALL_ONLINE }, { 0x101040, 1, RI_ALL_ONLINE }, + { 0x102058, 1, RI_ALL_ONLINE }, { 0x102080, 16, RI_ALL_ONLINE }, + { 0x103004, 2, RI_ALL_ONLINE }, { 0x103068, 1, RI_ALL_ONLINE }, + { 0x103078, 1, RI_ALL_ONLINE }, { 0x103088, 1, RI_ALL_ONLINE }, + { 0x10309c, 2, RI_E1HE2_ONLINE }, { 0x1030b8, 2, RI_E2_ONLINE }, + { 0x1030cc, 1, RI_E2_ONLINE }, { 0x1030e0, 1, RI_E2_ONLINE }, { 0x104004, 1, RI_ALL_ONLINE }, { 0x104018, 1, RI_ALL_ONLINE }, { 0x104020, 1, RI_ALL_ONLINE }, { 0x10403c, 1, RI_ALL_ONLINE }, { 0x1040fc, 1, RI_ALL_ONLINE }, { 0x10410c, 1, RI_ALL_ONLINE }, { 0x104400, 64, RI_ALL_ONLINE }, { 0x104800, 64, RI_ALL_ONLINE }, - { 0x105000, 3, RI_ALL_ONLINE }, { 0x105010, 3, RI_ALL_ONLINE }, - { 0x105020, 3, RI_ALL_ONLINE }, { 0x105030, 3, RI_ALL_ONLINE }, - { 0x105040, 3, RI_ALL_ONLINE }, { 0x105050, 3, RI_ALL_ONLINE }, - { 0x105060, 3, RI_ALL_ONLINE }, { 0x105070, 3, RI_ALL_ONLINE }, - { 0x105080, 3, RI_ALL_ONLINE }, { 0x105090, 3, RI_ALL_ONLINE }, - { 0x1050a0, 3, RI_ALL_ONLINE }, { 0x1050b0, 3, RI_ALL_ONLINE }, - { 0x1050c0, 3, RI_ALL_ONLINE }, { 0x1050d0, 3, RI_ALL_ONLINE }, - { 0x1050e0, 3, RI_ALL_ONLINE }, { 0x1050f0, 3, RI_ALL_ONLINE }, - { 0x105100, 3, RI_ALL_ONLINE }, { 0x105110, 3, RI_ALL_ONLINE }, - { 0x105120, 3, RI_ALL_ONLINE }, { 0x105130, 3, RI_ALL_ONLINE }, - { 0x105140, 3, RI_ALL_ONLINE }, { 0x105150, 3, RI_ALL_ONLINE }, - { 0x105160, 3, RI_ALL_ONLINE }, { 0x105170, 3, RI_ALL_ONLINE }, - { 0x105180, 3, RI_ALL_ONLINE }, { 0x105190, 3, RI_ALL_ONLINE }, - { 0x1051a0, 3, RI_ALL_ONLINE }, { 0x1051b0, 3, RI_ALL_ONLINE }, - { 0x1051c0, 3, RI_ALL_ONLINE }, { 0x1051d0, 3, RI_ALL_ONLINE }, - { 0x1051e0, 3, RI_ALL_ONLINE }, { 0x1051f0, 3, RI_ALL_ONLINE }, - { 0x105200, 3, RI_ALL_ONLINE }, { 0x105210, 3, RI_ALL_ONLINE }, - { 0x105220, 3, RI_ALL_ONLINE }, { 0x105230, 3, RI_ALL_ONLINE }, - { 0x105240, 3, RI_ALL_ONLINE }, { 0x105250, 3, RI_ALL_ONLINE }, - { 0x105260, 3, RI_ALL_ONLINE }, { 0x105270, 3, RI_ALL_ONLINE }, - { 0x105280, 3, RI_ALL_ONLINE }, { 0x105290, 3, RI_ALL_ONLINE }, - { 0x1052a0, 3, RI_ALL_ONLINE }, { 0x1052b0, 3, RI_ALL_ONLINE }, - { 0x1052c0, 3, RI_ALL_ONLINE }, { 0x1052d0, 3, RI_ALL_ONLINE }, - { 0x1052e0, 3, RI_ALL_ONLINE }, { 0x1052f0, 3, RI_ALL_ONLINE }, - { 0x105300, 3, RI_ALL_ONLINE }, { 0x105310, 3, RI_ALL_ONLINE }, - { 0x105320, 3, RI_ALL_ONLINE }, { 0x105330, 3, RI_ALL_ONLINE }, - { 0x105340, 3, RI_ALL_ONLINE }, { 0x105350, 3, RI_ALL_ONLINE }, - { 0x105360, 3, RI_ALL_ONLINE }, { 0x105370, 3, RI_ALL_ONLINE }, - { 0x105380, 3, RI_ALL_ONLINE }, { 0x105390, 3, RI_ALL_ONLINE }, - { 0x1053a0, 3, RI_ALL_ONLINE }, { 0x1053b0, 3, RI_ALL_ONLINE }, - { 0x1053c0, 3, RI_ALL_ONLINE }, { 0x1053d0, 3, RI_ALL_ONLINE }, - { 0x1053e0, 3, RI_ALL_ONLINE }, { 0x1053f0, 3, RI_ALL_ONLINE }, - { 0x108094, 1, RI_ALL_ONLINE }, { 0x1201b0, 2, RI_ALL_ONLINE }, - { 0x12032c, 1, RI_ALL_ONLINE }, { 0x12036c, 3, RI_ALL_ONLINE }, - { 0x120408, 2, RI_ALL_ONLINE }, { 0x120414, 15, RI_ALL_ONLINE }, - { 0x120478, 2, RI_ALL_ONLINE }, { 0x12052c, 1, RI_ALL_ONLINE }, - { 0x120564, 3, RI_ALL_ONLINE }, { 0x12057c, 1, RI_ALL_ONLINE }, - { 0x12058c, 1, RI_ALL_ONLINE }, { 0x120608, 1, RI_E1H_ONLINE }, - { 0x120808, 1, RI_E1_ONLINE }, { 0x12080c, 2, RI_ALL_ONLINE }, + { 0x105000, 256, RI_ALL_ONLINE }, { 0x108094, 1, RI_E1E1H_ONLINE }, + { 0x1201b0, 2, RI_ALL_ONLINE }, { 0x12032c, 1, RI_ALL_ONLINE }, + { 0x12036c, 3, RI_ALL_ONLINE }, { 0x120408, 2, RI_ALL_ONLINE }, + { 0x120414, 15, RI_ALL_ONLINE }, { 0x120478, 2, RI_ALL_ONLINE }, + { 0x12052c, 1, RI_ALL_ONLINE }, { 0x120564, 3, RI_ALL_ONLINE }, + { 0x12057c, 1, RI_ALL_ONLINE }, { 0x12058c, 1, RI_ALL_ONLINE }, + { 0x120608, 1, RI_E1HE2_ONLINE }, { 0x120738, 1, RI_E2_ONLINE }, + { 0x120778, 2, RI_E2_ONLINE }, { 0x120808, 3, RI_ALL_ONLINE }, { 0x120818, 1, RI_ALL_ONLINE }, { 0x120820, 1, RI_ALL_ONLINE }, { 0x120828, 1, RI_ALL_ONLINE }, { 0x120830, 1, RI_ALL_ONLINE }, { 0x120838, 1, RI_ALL_ONLINE }, { 0x120840, 1, RI_ALL_ONLINE }, @@ -462,48 +580,50 @@ static const struct reg_addr idle_addrs[IDLE_REGS_COUNT] = { { 0x1208d8, 1, RI_ALL_ONLINE }, { 0x1208e0, 1, RI_ALL_ONLINE }, { 0x1208e8, 1, RI_ALL_ONLINE }, { 0x1208f0, 1, RI_ALL_ONLINE }, { 0x1208f8, 1, RI_ALL_ONLINE }, { 0x120900, 1, RI_ALL_ONLINE }, - { 0x120908, 1, RI_ALL_ONLINE }, { 0x14005c, 2, RI_ALL_ONLINE }, - { 0x1400d0, 2, RI_ALL_ONLINE }, { 0x1400e0, 1, RI_ALL_ONLINE }, - { 0x1401c8, 1, RI_ALL_ONLINE }, { 0x140200, 6, RI_ALL_ONLINE }, - { 0x16101c, 1, RI_ALL_ONLINE }, { 0x16102c, 1, RI_ALL_ONLINE }, - { 0x164014, 2, RI_ALL_ONLINE }, { 0x1640f0, 1, RI_ALL_ONLINE }, - { 0x166290, 1, RI_ALL_ONLINE }, { 0x1662a0, 1, RI_ALL_ONLINE }, - { 0x1662b0, 1, RI_ALL_ONLINE }, { 0x166548, 1, RI_ALL_ONLINE }, - { 0x166550, 1, RI_ALL_ONLINE }, { 0x166558, 1, RI_ALL_ONLINE }, - { 0x168000, 1, RI_ALL_ONLINE }, { 0x168008, 1, RI_ALL_ONLINE }, - { 0x168010, 1, RI_ALL_ONLINE }, { 0x168018, 1, RI_ALL_ONLINE }, - { 0x168028, 2, RI_ALL_ONLINE }, { 0x168058, 4, RI_ALL_ONLINE }, - { 0x168070, 1, RI_ALL_ONLINE }, { 0x168238, 1, RI_ALL_ONLINE }, - { 0x1682d0, 2, RI_ALL_ONLINE }, { 0x1682e0, 1, RI_ALL_ONLINE }, - { 0x168300, 67, RI_ALL_ONLINE }, { 0x168410, 2, RI_ALL_ONLINE }, + { 0x120908, 1, RI_ALL_ONLINE }, { 0x120940, 5, RI_E2_ONLINE }, + { 0x130030, 1, RI_E2_ONLINE }, { 0x13004c, 3, RI_E2_ONLINE }, + { 0x130064, 2, RI_E2_ONLINE }, { 0x13009c, 1, RI_E2_ONLINE }, + { 0x130130, 1, RI_E2_ONLINE }, { 0x13016c, 1, RI_E2_ONLINE }, + { 0x130300, 1, RI_E2_ONLINE }, { 0x130480, 1, RI_E2_ONLINE }, + { 0x14005c, 2, RI_ALL_ONLINE }, { 0x1400d0, 2, RI_ALL_ONLINE }, + { 0x1400e0, 1, RI_ALL_ONLINE }, { 0x1401c8, 1, RI_ALL_ONLINE }, + { 0x140200, 6, RI_ALL_ONLINE }, { 0x16101c, 1, RI_ALL_ONLINE }, + { 0x16102c, 1, RI_ALL_ONLINE }, { 0x164014, 2, RI_ALL_ONLINE }, + { 0x1640f0, 1, RI_ALL_ONLINE }, { 0x166290, 1, RI_ALL_ONLINE }, + { 0x1662a0, 1, RI_ALL_ONLINE }, { 0x1662b0, 1, RI_ALL_ONLINE }, + { 0x166548, 1, RI_ALL_ONLINE }, { 0x166550, 1, RI_ALL_ONLINE }, + { 0x166558, 1, RI_ALL_ONLINE }, { 0x168000, 1, RI_ALL_ONLINE }, + { 0x168008, 1, RI_ALL_ONLINE }, { 0x168010, 1, RI_ALL_ONLINE }, + { 0x168018, 1, RI_ALL_ONLINE }, { 0x168028, 2, RI_ALL_ONLINE }, + { 0x168058, 4, RI_ALL_ONLINE }, { 0x168070, 1, RI_ALL_ONLINE }, + { 0x168238, 1, RI_ALL_ONLINE }, { 0x1682d0, 2, RI_ALL_ONLINE }, + { 0x1682e0, 1, RI_ALL_ONLINE }, { 0x168300, 2, RI_E1E1H_ONLINE }, + { 0x168308, 65, RI_ALL_ONLINE }, { 0x168410, 2, RI_ALL_ONLINE }, { 0x168438, 1, RI_ALL_ONLINE }, { 0x168448, 1, RI_ALL_ONLINE }, { 0x168a00, 128, RI_ALL_ONLINE }, { 0x16e200, 128, RI_E1H_ONLINE }, - { 0x16e404, 2, RI_E1H_ONLINE }, { 0x16e584, 70, RI_E1H_ONLINE }, - { 0x1700a4, 1, RI_ALL_ONLINE }, { 0x1700ac, 2, RI_ALL_ONLINE }, - { 0x1700c0, 1, RI_ALL_ONLINE }, { 0x170174, 1, RI_ALL_ONLINE }, - { 0x170184, 1, RI_ALL_ONLINE }, { 0x1800f4, 1, RI_ALL_ONLINE }, - { 0x180104, 1, RI_ALL_ONLINE }, { 0x180114, 1, RI_ALL_ONLINE }, - { 0x180124, 1, RI_ALL_ONLINE }, { 0x18026c, 1, RI_ALL_ONLINE }, - { 0x1802a0, 1, RI_ALL_ONLINE }, { 0x1a1000, 1, RI_ALL_ONLINE }, - { 0x1aa000, 1, RI_E1H_ONLINE }, { 0x1b8000, 1, RI_ALL_ONLINE }, - { 0x1b8040, 1, RI_ALL_ONLINE }, { 0x1b8080, 1, RI_ALL_ONLINE }, - { 0x1b80c0, 1, RI_ALL_ONLINE }, { 0x200104, 1, RI_ALL_ONLINE }, - { 0x200114, 1, RI_ALL_ONLINE }, { 0x200124, 1, RI_ALL_ONLINE }, - { 0x200134, 1, RI_ALL_ONLINE }, { 0x20026c, 1, RI_ALL_ONLINE }, - { 0x2002a0, 1, RI_ALL_ONLINE }, { 0x221000, 1, RI_ALL_ONLINE }, - { 0x227000, 1, RI_E1H_ONLINE }, { 0x238000, 1, RI_ALL_ONLINE }, - { 0x238040, 1, RI_ALL_ONLINE }, { 0x238080, 1, RI_ALL_ONLINE }, - { 0x2380c0, 1, RI_ALL_ONLINE }, { 0x280104, 1, RI_ALL_ONLINE }, - { 0x280114, 1, RI_ALL_ONLINE }, { 0x280124, 1, RI_ALL_ONLINE }, - { 0x280134, 1, RI_ALL_ONLINE }, { 0x28026c, 1, RI_ALL_ONLINE }, - { 0x2802a0, 1, RI_ALL_ONLINE }, { 0x2a1000, 1, RI_ALL_ONLINE }, - { 0x2a9000, 1, RI_E1H_ONLINE }, { 0x2b8000, 1, RI_ALL_ONLINE }, - { 0x2b8040, 1, RI_ALL_ONLINE }, { 0x2b8080, 1, RI_ALL_ONLINE }, - { 0x2b80c0, 1, RI_ALL_ONLINE }, { 0x300104, 1, RI_ALL_ONLINE }, + { 0x16e404, 2, RI_E1H_ONLINE }, { 0x16e584, 64, RI_E1H_ONLINE }, + { 0x16e684, 2, RI_E1HE2_ONLINE }, { 0x16e68c, 4, RI_E1H_ONLINE }, + { 0x16e6fc, 4, RI_E2_ONLINE }, { 0x1700a4, 1, RI_ALL_ONLINE }, + { 0x1700ac, 2, RI_ALL_ONLINE }, { 0x1700c0, 1, RI_ALL_ONLINE }, + { 0x170174, 1, RI_ALL_ONLINE }, { 0x170184, 1, RI_ALL_ONLINE }, + { 0x1800f4, 1, RI_ALL_ONLINE }, { 0x180104, 1, RI_ALL_ONLINE }, + { 0x180114, 1, RI_ALL_ONLINE }, { 0x180124, 1, RI_ALL_ONLINE }, + { 0x18026c, 1, RI_ALL_ONLINE }, { 0x1802a0, 1, RI_ALL_ONLINE }, + { 0x1b8000, 1, RI_ALL_ONLINE }, { 0x1b8040, 1, RI_ALL_ONLINE }, + { 0x1b8080, 1, RI_ALL_ONLINE }, { 0x1b80c0, 1, RI_ALL_ONLINE }, + { 0x200104, 1, RI_ALL_ONLINE }, { 0x200114, 1, RI_ALL_ONLINE }, + { 0x200124, 1, RI_ALL_ONLINE }, { 0x200134, 1, RI_ALL_ONLINE }, + { 0x20026c, 1, RI_ALL_ONLINE }, { 0x2002a0, 1, RI_ALL_ONLINE }, + { 0x238000, 1, RI_ALL_ONLINE }, { 0x238040, 1, RI_ALL_ONLINE }, + { 0x238080, 1, RI_ALL_ONLINE }, { 0x2380c0, 1, RI_ALL_ONLINE }, + { 0x280104, 1, RI_ALL_ONLINE }, { 0x280114, 1, RI_ALL_ONLINE }, + { 0x280124, 1, RI_ALL_ONLINE }, { 0x280134, 1, RI_ALL_ONLINE }, + { 0x28026c, 1, RI_ALL_ONLINE }, { 0x2802a0, 1, RI_ALL_ONLINE }, + { 0x2b8000, 1, RI_ALL_ONLINE }, { 0x2b8040, 1, RI_ALL_ONLINE }, + { 0x2b8080, 1, RI_ALL_ONLINE }, { 0x300104, 1, RI_ALL_ONLINE }, { 0x300114, 1, RI_ALL_ONLINE }, { 0x300124, 1, RI_ALL_ONLINE }, { 0x300134, 1, RI_ALL_ONLINE }, { 0x30026c, 1, RI_ALL_ONLINE }, - { 0x3002a0, 1, RI_ALL_ONLINE }, { 0x321000, 1, RI_ALL_ONLINE }, - { 0x328960, 1, RI_E1H_ONLINE }, { 0x338000, 1, RI_ALL_ONLINE }, + { 0x3002a0, 1, RI_ALL_ONLINE }, { 0x338000, 1, RI_ALL_ONLINE }, { 0x338040, 1, RI_ALL_ONLINE }, { 0x338080, 1, RI_ALL_ONLINE }, { 0x3380c0, 1, RI_ALL_ONLINE } }; @@ -515,7 +635,6 @@ static const struct wreg_addr wreg_addrs_e1[WREGS_COUNT_E1] = { { 0x1b0c00, 192, 1, read_reg_e1_0, RI_E1_OFFLINE } }; - #define WREGS_COUNT_E1H 1 static const u32 read_reg_e1h_0[] = { 0x1b1040, 0x1b1000 }; @@ -530,22 +649,53 @@ static const struct wreg_addr wreg_addrs_e2[WREGS_COUNT_E2] = { { 0x1b0c00, 128, 2, read_reg_e2_0, RI_E2_OFFLINE } }; -static const struct dump_sign dump_sign_all = { 0x49aa93ee, 0x40835, 0x22 }; - +static const struct dump_sign dump_sign_all = { 0x4d18b0a4, 0x60010, 0x3a }; #define TIMER_REGS_COUNT_E1 2 -static const u32 timer_status_regs_e1[TIMER_REGS_COUNT_E1] = - { 0x164014, 0x164018 }; -static const u32 timer_scan_regs_e1[TIMER_REGS_COUNT_E1] = - { 0x1640d0, 0x1640d4 }; +static const u32 timer_status_regs_e1[TIMER_REGS_COUNT_E1] = { + 0x164014, 0x164018 }; +static const u32 timer_scan_regs_e1[TIMER_REGS_COUNT_E1] = { + 0x1640d0, 0x1640d4 }; #define TIMER_REGS_COUNT_E1H 2 -static const u32 timer_status_regs_e1h[TIMER_REGS_COUNT_E1H] = - { 0x164014, 0x164018 }; -static const u32 timer_scan_regs_e1h[TIMER_REGS_COUNT_E1H] = - { 0x1640d0, 0x1640d4 }; +static const u32 timer_status_regs_e1h[TIMER_REGS_COUNT_E1H] = { + 0x164014, 0x164018 }; +static const u32 timer_scan_regs_e1h[TIMER_REGS_COUNT_E1H] = { + 0x1640d0, 0x1640d4 }; + +#define TIMER_REGS_COUNT_E2 2 + +static const u32 timer_status_regs_e2[TIMER_REGS_COUNT_E2] = { + 0x164014, 0x164018 }; +static const u32 timer_scan_regs_e2[TIMER_REGS_COUNT_E2] = { + 0x1640d0, 0x1640d4 }; + +#define PAGE_MODE_VALUES_E1 0 + +#define PAGE_READ_REGS_E1 0 + +#define PAGE_WRITE_REGS_E1 0 + +static const u32 page_vals_e1[] = { 0 }; + +static const u32 page_write_regs_e1[] = { 0 }; + +static const struct reg_addr page_read_regs_e1[] = { { 0x0, 0, RI_E1_ONLINE } }; + +#define PAGE_MODE_VALUES_E1H 0 + +#define PAGE_READ_REGS_E1H 0 + +#define PAGE_WRITE_REGS_E1H 0 + +static const u32 page_vals_e1h[] = { 0 }; + +static const u32 page_write_regs_e1h[] = { 0 }; + +static const struct reg_addr page_read_regs_e1h[] = { + { 0x0, 0, RI_E1H_ONLINE } }; #define PAGE_MODE_VALUES_E2 2 diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index d02ffbdc9f0e..5b44a8b48509 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -24,6 +24,144 @@ #include "bnx2x.h" #include "bnx2x_cmn.h" #include "bnx2x_dump.h" +#include "bnx2x_init.h" + +/* Note: in the format strings below %s is replaced by the queue-name which is + * either its index or 'fcoe' for the fcoe queue. Make sure the format string + * length does not exceed ETH_GSTRING_LEN - MAX_QUEUE_NAME_LEN + 2 + */ +#define MAX_QUEUE_NAME_LEN 4 +static const struct { + long offset; + int size; + char string[ETH_GSTRING_LEN]; +} bnx2x_q_stats_arr[] = { +/* 1 */ { Q_STATS_OFFSET32(total_bytes_received_hi), 8, "[%s]: rx_bytes" }, + { Q_STATS_OFFSET32(error_bytes_received_hi), + 8, "[%s]: rx_error_bytes" }, + { Q_STATS_OFFSET32(total_unicast_packets_received_hi), + 8, "[%s]: rx_ucast_packets" }, + { Q_STATS_OFFSET32(total_multicast_packets_received_hi), + 8, "[%s]: rx_mcast_packets" }, + { Q_STATS_OFFSET32(total_broadcast_packets_received_hi), + 8, "[%s]: rx_bcast_packets" }, + { Q_STATS_OFFSET32(no_buff_discard_hi), 8, "[%s]: rx_discards" }, + { Q_STATS_OFFSET32(rx_err_discard_pkt), + 4, "[%s]: rx_phy_ip_err_discards"}, + { Q_STATS_OFFSET32(rx_skb_alloc_failed), + 4, "[%s]: rx_skb_alloc_discard" }, + { Q_STATS_OFFSET32(hw_csum_err), 4, "[%s]: rx_csum_offload_errors" }, + +/* 10 */{ Q_STATS_OFFSET32(total_bytes_transmitted_hi), 8, "[%s]: tx_bytes" }, + { Q_STATS_OFFSET32(total_unicast_packets_transmitted_hi), + 8, "[%s]: tx_ucast_packets" }, + { Q_STATS_OFFSET32(total_multicast_packets_transmitted_hi), + 8, "[%s]: tx_mcast_packets" }, + { Q_STATS_OFFSET32(total_broadcast_packets_transmitted_hi), + 8, "[%s]: tx_bcast_packets" } +}; + +#define BNX2X_NUM_Q_STATS ARRAY_SIZE(bnx2x_q_stats_arr) + +static const struct { + long offset; + int size; + u32 flags; +#define STATS_FLAGS_PORT 1 +#define STATS_FLAGS_FUNC 2 +#define STATS_FLAGS_BOTH (STATS_FLAGS_FUNC | STATS_FLAGS_PORT) + char string[ETH_GSTRING_LEN]; +} bnx2x_stats_arr[] = { +/* 1 */ { STATS_OFFSET32(total_bytes_received_hi), + 8, STATS_FLAGS_BOTH, "rx_bytes" }, + { STATS_OFFSET32(error_bytes_received_hi), + 8, STATS_FLAGS_BOTH, "rx_error_bytes" }, + { STATS_OFFSET32(total_unicast_packets_received_hi), + 8, STATS_FLAGS_BOTH, "rx_ucast_packets" }, + { STATS_OFFSET32(total_multicast_packets_received_hi), + 8, STATS_FLAGS_BOTH, "rx_mcast_packets" }, + { STATS_OFFSET32(total_broadcast_packets_received_hi), + 8, STATS_FLAGS_BOTH, "rx_bcast_packets" }, + { STATS_OFFSET32(rx_stat_dot3statsfcserrors_hi), + 8, STATS_FLAGS_PORT, "rx_crc_errors" }, + { STATS_OFFSET32(rx_stat_dot3statsalignmenterrors_hi), + 8, STATS_FLAGS_PORT, "rx_align_errors" }, + { STATS_OFFSET32(rx_stat_etherstatsundersizepkts_hi), + 8, STATS_FLAGS_PORT, "rx_undersize_packets" }, + { STATS_OFFSET32(etherstatsoverrsizepkts_hi), + 8, STATS_FLAGS_PORT, "rx_oversize_packets" }, +/* 10 */{ STATS_OFFSET32(rx_stat_etherstatsfragments_hi), + 8, STATS_FLAGS_PORT, "rx_fragments" }, + { STATS_OFFSET32(rx_stat_etherstatsjabbers_hi), + 8, STATS_FLAGS_PORT, "rx_jabbers" }, + { STATS_OFFSET32(no_buff_discard_hi), + 8, STATS_FLAGS_BOTH, "rx_discards" }, + { STATS_OFFSET32(mac_filter_discard), + 4, STATS_FLAGS_PORT, "rx_filtered_packets" }, + { STATS_OFFSET32(xxoverflow_discard), + 4, STATS_FLAGS_PORT, "rx_fw_discards" }, + { STATS_OFFSET32(brb_drop_hi), + 8, STATS_FLAGS_PORT, "rx_brb_discard" }, + { STATS_OFFSET32(brb_truncate_hi), + 8, STATS_FLAGS_PORT, "rx_brb_truncate" }, + { STATS_OFFSET32(pause_frames_received_hi), + 8, STATS_FLAGS_PORT, "rx_pause_frames" }, + { STATS_OFFSET32(rx_stat_maccontrolframesreceived_hi), + 8, STATS_FLAGS_PORT, "rx_mac_ctrl_frames" }, + { STATS_OFFSET32(nig_timer_max), + 4, STATS_FLAGS_PORT, "rx_constant_pause_events" }, +/* 20 */{ STATS_OFFSET32(rx_err_discard_pkt), + 4, STATS_FLAGS_BOTH, "rx_phy_ip_err_discards"}, + { STATS_OFFSET32(rx_skb_alloc_failed), + 4, STATS_FLAGS_BOTH, "rx_skb_alloc_discard" }, + { STATS_OFFSET32(hw_csum_err), + 4, STATS_FLAGS_BOTH, "rx_csum_offload_errors" }, + + { STATS_OFFSET32(total_bytes_transmitted_hi), + 8, STATS_FLAGS_BOTH, "tx_bytes" }, + { STATS_OFFSET32(tx_stat_ifhcoutbadoctets_hi), + 8, STATS_FLAGS_PORT, "tx_error_bytes" }, + { STATS_OFFSET32(total_unicast_packets_transmitted_hi), + 8, STATS_FLAGS_BOTH, "tx_ucast_packets" }, + { STATS_OFFSET32(total_multicast_packets_transmitted_hi), + 8, STATS_FLAGS_BOTH, "tx_mcast_packets" }, + { STATS_OFFSET32(total_broadcast_packets_transmitted_hi), + 8, STATS_FLAGS_BOTH, "tx_bcast_packets" }, + { STATS_OFFSET32(tx_stat_dot3statsinternalmactransmiterrors_hi), + 8, STATS_FLAGS_PORT, "tx_mac_errors" }, + { STATS_OFFSET32(rx_stat_dot3statscarriersenseerrors_hi), + 8, STATS_FLAGS_PORT, "tx_carrier_errors" }, +/* 30 */{ STATS_OFFSET32(tx_stat_dot3statssinglecollisionframes_hi), + 8, STATS_FLAGS_PORT, "tx_single_collisions" }, + { STATS_OFFSET32(tx_stat_dot3statsmultiplecollisionframes_hi), + 8, STATS_FLAGS_PORT, "tx_multi_collisions" }, + { STATS_OFFSET32(tx_stat_dot3statsdeferredtransmissions_hi), + 8, STATS_FLAGS_PORT, "tx_deferred" }, + { STATS_OFFSET32(tx_stat_dot3statsexcessivecollisions_hi), + 8, STATS_FLAGS_PORT, "tx_excess_collisions" }, + { STATS_OFFSET32(tx_stat_dot3statslatecollisions_hi), + 8, STATS_FLAGS_PORT, "tx_late_collisions" }, + { STATS_OFFSET32(tx_stat_etherstatscollisions_hi), + 8, STATS_FLAGS_PORT, "tx_total_collisions" }, + { STATS_OFFSET32(tx_stat_etherstatspkts64octets_hi), + 8, STATS_FLAGS_PORT, "tx_64_byte_packets" }, + { STATS_OFFSET32(tx_stat_etherstatspkts65octetsto127octets_hi), + 8, STATS_FLAGS_PORT, "tx_65_to_127_byte_packets" }, + { STATS_OFFSET32(tx_stat_etherstatspkts128octetsto255octets_hi), + 8, STATS_FLAGS_PORT, "tx_128_to_255_byte_packets" }, + { STATS_OFFSET32(tx_stat_etherstatspkts256octetsto511octets_hi), + 8, STATS_FLAGS_PORT, "tx_256_to_511_byte_packets" }, +/* 40 */{ STATS_OFFSET32(tx_stat_etherstatspkts512octetsto1023octets_hi), + 8, STATS_FLAGS_PORT, "tx_512_to_1023_byte_packets" }, + { STATS_OFFSET32(etherstatspkts1024octetsto1522octets_hi), + 8, STATS_FLAGS_PORT, "tx_1024_to_1522_byte_packets" }, + { STATS_OFFSET32(etherstatspktsover1522octets_hi), + 8, STATS_FLAGS_PORT, "tx_1523_to_9022_byte_packets" }, + { STATS_OFFSET32(pause_frames_sent_hi), + 8, STATS_FLAGS_PORT, "tx_pause_frames" } +}; + +#define BNX2X_NUM_STATS ARRAY_SIZE(bnx2x_stats_arr) static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { @@ -45,14 +183,9 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) cmd->speed = bp->link_params.req_line_speed[cfg_idx]; cmd->duplex = bp->link_params.req_duplex[cfg_idx]; } - if (IS_MF(bp)) { - u16 vn_max_rate = ((bp->mf_config[BP_VN(bp)] & - FUNC_MF_CFG_MAX_BW_MASK) >> FUNC_MF_CFG_MAX_BW_SHIFT) * - 100; - if (vn_max_rate < cmd->speed) - cmd->speed = vn_max_rate; - } + if (IS_MF(bp)) + cmd->speed = bnx2x_get_mf_speed(bp); if (bp->port.supported[cfg_idx] & SUPPORTED_TP) cmd->port = PORT_TP; @@ -87,18 +220,57 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct bnx2x *bp = netdev_priv(dev); u32 advertising, cfg_idx, old_multi_phy_config, new_multi_phy_config; + u32 speed; - if (IS_MF(bp)) + if (IS_MF_SD(bp)) return 0; DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n" - DP_LEVEL " supported 0x%x advertising 0x%x speed %d\n" - DP_LEVEL " duplex %d port %d phy_address %d transceiver %d\n" - DP_LEVEL " autoneg %d maxtxpkt %d maxrxpkt %d\n", + " supported 0x%x advertising 0x%x speed %d speed_hi %d\n" + " duplex %d port %d phy_address %d transceiver %d\n" + " autoneg %d maxtxpkt %d maxrxpkt %d\n", cmd->cmd, cmd->supported, cmd->advertising, cmd->speed, + cmd->speed_hi, cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver, cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt); + speed = cmd->speed; + speed |= (cmd->speed_hi << 16); + + if (IS_MF_SI(bp)) { + u32 param = 0; + u32 line_speed = bp->link_vars.line_speed; + + /* use 10G if no link detected */ + if (!line_speed) + line_speed = 10000; + + if (bp->common.bc_ver < REQ_BC_VER_4_SET_MF_BW) { + BNX2X_DEV_INFO("To set speed BC %X or higher " + "is required, please upgrade BC\n", + REQ_BC_VER_4_SET_MF_BW); + return -EINVAL; + } + if (line_speed < speed) { + BNX2X_DEV_INFO("New speed should be less or equal " + "to actual line speed\n"); + return -EINVAL; + } + /* load old values */ + param = bp->mf_config[BP_VN(bp)]; + + /* leave only MIN value */ + param &= FUNC_MF_CFG_MIN_BW_MASK; + + /* set new MAX value */ + param |= (((speed * 100) / line_speed) + << FUNC_MF_CFG_MAX_BW_SHIFT) + & FUNC_MF_CFG_MAX_BW_MASK; + + bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW, param); + return 0; + } + cfg_idx = bnx2x_get_link_cfg_idx(bp); old_multi_phy_config = bp->link_params.multi_phy_config; switch (cmd->port) { @@ -168,8 +340,6 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) } else { /* forced speed */ /* advertise the requested speed and duplex if supported */ - u32 speed = cmd->speed; - speed |= (cmd->speed_hi << 16); switch (speed) { case SPEED_10: if (cmd->duplex == DUPLEX_FULL) { @@ -303,7 +473,7 @@ static int bnx2x_get_regs_len(struct net_device *dev) { struct bnx2x *bp = netdev_priv(dev); int regdump_len = 0; - int i; + int i, j, k; if (CHIP_IS_E1(bp)) { for (i = 0; i < REGS_COUNT; i++) @@ -333,6 +503,15 @@ static int bnx2x_get_regs_len(struct net_device *dev) if (IS_E2_ONLINE(wreg_addrs_e2[i].info)) regdump_len += wreg_addrs_e2[i].size * (1 + wreg_addrs_e2[i].read_regs_count); + + for (i = 0; i < PAGE_MODE_VALUES_E2; i++) + for (j = 0; j < PAGE_WRITE_REGS_E2; j++) { + for (k = 0; k < PAGE_READ_REGS_E2; k++) + if (IS_E2_ONLINE(page_read_regs_e2[k]. + info)) + regdump_len += + page_read_regs_e2[k].size; + } } regdump_len *= 4; regdump_len += sizeof(struct dump_hdr); @@ -370,6 +549,12 @@ static void bnx2x_get_regs(struct net_device *dev, if (!netif_running(bp->dev)) return; + /* Disable parity attentions as long as following dump may + * cause false alarms by reading never written registers. We + * will re-enable parity attentions right after the dump. + */ + bnx2x_disable_blocks_parity(bp); + dump_hdr.hdr_size = (sizeof(struct dump_hdr) / 4) - 1; dump_hdr.dump_sign = dump_sign_all; dump_hdr.xstorm_waitp = REG_RD(bp, XSTORM_WAITP_ADDR); @@ -411,6 +596,10 @@ static void bnx2x_get_regs(struct net_device *dev, bnx2x_read_pages_regs_e2(bp, p); } + /* Re-enable parity attentions */ + bnx2x_clear_blocks_parity(bp); + if (CHIP_PARITY_ENABLED(bp)) + bnx2x_enable_blocks_parity(bp); } #define PHY_FW_VER_LEN 20 @@ -1286,7 +1475,7 @@ static int bnx2x_test_registers(struct bnx2x *bp) save_val = REG_RD(bp, offset); - REG_WR(bp, offset, (wr_val & mask)); + REG_WR(bp, offset, wr_val & mask); val = REG_RD(bp, offset); @@ -1499,8 +1688,15 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) * updates that have been performed while interrupts were * disabled. */ - if (bp->common.int_block == INT_BLOCK_IGU) + if (bp->common.int_block == INT_BLOCK_IGU) { + /* Disable local BHes to prevent a dead-lock situation between + * sch_direct_xmit() and bnx2x_run_loopback() (calling + * bnx2x_tx_int()), as both are taking netif_tx_lock(). + */ + local_bh_disable(); bnx2x_tx_int(fp_tx); + local_bh_enable(); + } rx_idx = le16_to_cpu(*fp_rx->rx_cons_sb); if (rx_idx != rx_start_idx + num_pkts) @@ -1650,7 +1846,7 @@ static int bnx2x_test_intr(struct bnx2x *bp) config->hdr.client_id = bp->fp->cl_id; config->hdr.reserved1 = 0; - bp->set_mac_pending++; + bp->set_mac_pending = 1; smp_wmb(); rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, U64_HI(bnx2x_sp_mapping(bp, mac_config)), @@ -1748,134 +1944,6 @@ static void bnx2x_self_test(struct net_device *dev, #endif } -static const struct { - long offset; - int size; - u8 string[ETH_GSTRING_LEN]; -} bnx2x_q_stats_arr[BNX2X_NUM_Q_STATS] = { -/* 1 */ { Q_STATS_OFFSET32(total_bytes_received_hi), 8, "[%d]: rx_bytes" }, - { Q_STATS_OFFSET32(error_bytes_received_hi), - 8, "[%d]: rx_error_bytes" }, - { Q_STATS_OFFSET32(total_unicast_packets_received_hi), - 8, "[%d]: rx_ucast_packets" }, - { Q_STATS_OFFSET32(total_multicast_packets_received_hi), - 8, "[%d]: rx_mcast_packets" }, - { Q_STATS_OFFSET32(total_broadcast_packets_received_hi), - 8, "[%d]: rx_bcast_packets" }, - { Q_STATS_OFFSET32(no_buff_discard_hi), 8, "[%d]: rx_discards" }, - { Q_STATS_OFFSET32(rx_err_discard_pkt), - 4, "[%d]: rx_phy_ip_err_discards"}, - { Q_STATS_OFFSET32(rx_skb_alloc_failed), - 4, "[%d]: rx_skb_alloc_discard" }, - { Q_STATS_OFFSET32(hw_csum_err), 4, "[%d]: rx_csum_offload_errors" }, - -/* 10 */{ Q_STATS_OFFSET32(total_bytes_transmitted_hi), 8, "[%d]: tx_bytes" }, - { Q_STATS_OFFSET32(total_unicast_packets_transmitted_hi), - 8, "[%d]: tx_ucast_packets" }, - { Q_STATS_OFFSET32(total_multicast_packets_transmitted_hi), - 8, "[%d]: tx_mcast_packets" }, - { Q_STATS_OFFSET32(total_broadcast_packets_transmitted_hi), - 8, "[%d]: tx_bcast_packets" } -}; - -static const struct { - long offset; - int size; - u32 flags; -#define STATS_FLAGS_PORT 1 -#define STATS_FLAGS_FUNC 2 -#define STATS_FLAGS_BOTH (STATS_FLAGS_FUNC | STATS_FLAGS_PORT) - u8 string[ETH_GSTRING_LEN]; -} bnx2x_stats_arr[BNX2X_NUM_STATS] = { -/* 1 */ { STATS_OFFSET32(total_bytes_received_hi), - 8, STATS_FLAGS_BOTH, "rx_bytes" }, - { STATS_OFFSET32(error_bytes_received_hi), - 8, STATS_FLAGS_BOTH, "rx_error_bytes" }, - { STATS_OFFSET32(total_unicast_packets_received_hi), - 8, STATS_FLAGS_BOTH, "rx_ucast_packets" }, - { STATS_OFFSET32(total_multicast_packets_received_hi), - 8, STATS_FLAGS_BOTH, "rx_mcast_packets" }, - { STATS_OFFSET32(total_broadcast_packets_received_hi), - 8, STATS_FLAGS_BOTH, "rx_bcast_packets" }, - { STATS_OFFSET32(rx_stat_dot3statsfcserrors_hi), - 8, STATS_FLAGS_PORT, "rx_crc_errors" }, - { STATS_OFFSET32(rx_stat_dot3statsalignmenterrors_hi), - 8, STATS_FLAGS_PORT, "rx_align_errors" }, - { STATS_OFFSET32(rx_stat_etherstatsundersizepkts_hi), - 8, STATS_FLAGS_PORT, "rx_undersize_packets" }, - { STATS_OFFSET32(etherstatsoverrsizepkts_hi), - 8, STATS_FLAGS_PORT, "rx_oversize_packets" }, -/* 10 */{ STATS_OFFSET32(rx_stat_etherstatsfragments_hi), - 8, STATS_FLAGS_PORT, "rx_fragments" }, - { STATS_OFFSET32(rx_stat_etherstatsjabbers_hi), - 8, STATS_FLAGS_PORT, "rx_jabbers" }, - { STATS_OFFSET32(no_buff_discard_hi), - 8, STATS_FLAGS_BOTH, "rx_discards" }, - { STATS_OFFSET32(mac_filter_discard), - 4, STATS_FLAGS_PORT, "rx_filtered_packets" }, - { STATS_OFFSET32(xxoverflow_discard), - 4, STATS_FLAGS_PORT, "rx_fw_discards" }, - { STATS_OFFSET32(brb_drop_hi), - 8, STATS_FLAGS_PORT, "rx_brb_discard" }, - { STATS_OFFSET32(brb_truncate_hi), - 8, STATS_FLAGS_PORT, "rx_brb_truncate" }, - { STATS_OFFSET32(pause_frames_received_hi), - 8, STATS_FLAGS_PORT, "rx_pause_frames" }, - { STATS_OFFSET32(rx_stat_maccontrolframesreceived_hi), - 8, STATS_FLAGS_PORT, "rx_mac_ctrl_frames" }, - { STATS_OFFSET32(nig_timer_max), - 4, STATS_FLAGS_PORT, "rx_constant_pause_events" }, -/* 20 */{ STATS_OFFSET32(rx_err_discard_pkt), - 4, STATS_FLAGS_BOTH, "rx_phy_ip_err_discards"}, - { STATS_OFFSET32(rx_skb_alloc_failed), - 4, STATS_FLAGS_BOTH, "rx_skb_alloc_discard" }, - { STATS_OFFSET32(hw_csum_err), - 4, STATS_FLAGS_BOTH, "rx_csum_offload_errors" }, - - { STATS_OFFSET32(total_bytes_transmitted_hi), - 8, STATS_FLAGS_BOTH, "tx_bytes" }, - { STATS_OFFSET32(tx_stat_ifhcoutbadoctets_hi), - 8, STATS_FLAGS_PORT, "tx_error_bytes" }, - { STATS_OFFSET32(total_unicast_packets_transmitted_hi), - 8, STATS_FLAGS_BOTH, "tx_ucast_packets" }, - { STATS_OFFSET32(total_multicast_packets_transmitted_hi), - 8, STATS_FLAGS_BOTH, "tx_mcast_packets" }, - { STATS_OFFSET32(total_broadcast_packets_transmitted_hi), - 8, STATS_FLAGS_BOTH, "tx_bcast_packets" }, - { STATS_OFFSET32(tx_stat_dot3statsinternalmactransmiterrors_hi), - 8, STATS_FLAGS_PORT, "tx_mac_errors" }, - { STATS_OFFSET32(rx_stat_dot3statscarriersenseerrors_hi), - 8, STATS_FLAGS_PORT, "tx_carrier_errors" }, -/* 30 */{ STATS_OFFSET32(tx_stat_dot3statssinglecollisionframes_hi), - 8, STATS_FLAGS_PORT, "tx_single_collisions" }, - { STATS_OFFSET32(tx_stat_dot3statsmultiplecollisionframes_hi), - 8, STATS_FLAGS_PORT, "tx_multi_collisions" }, - { STATS_OFFSET32(tx_stat_dot3statsdeferredtransmissions_hi), - 8, STATS_FLAGS_PORT, "tx_deferred" }, - { STATS_OFFSET32(tx_stat_dot3statsexcessivecollisions_hi), - 8, STATS_FLAGS_PORT, "tx_excess_collisions" }, - { STATS_OFFSET32(tx_stat_dot3statslatecollisions_hi), - 8, STATS_FLAGS_PORT, "tx_late_collisions" }, - { STATS_OFFSET32(tx_stat_etherstatscollisions_hi), - 8, STATS_FLAGS_PORT, "tx_total_collisions" }, - { STATS_OFFSET32(tx_stat_etherstatspkts64octets_hi), - 8, STATS_FLAGS_PORT, "tx_64_byte_packets" }, - { STATS_OFFSET32(tx_stat_etherstatspkts65octetsto127octets_hi), - 8, STATS_FLAGS_PORT, "tx_65_to_127_byte_packets" }, - { STATS_OFFSET32(tx_stat_etherstatspkts128octetsto255octets_hi), - 8, STATS_FLAGS_PORT, "tx_128_to_255_byte_packets" }, - { STATS_OFFSET32(tx_stat_etherstatspkts256octetsto511octets_hi), - 8, STATS_FLAGS_PORT, "tx_256_to_511_byte_packets" }, -/* 40 */{ STATS_OFFSET32(tx_stat_etherstatspkts512octetsto1023octets_hi), - 8, STATS_FLAGS_PORT, "tx_512_to_1023_byte_packets" }, - { STATS_OFFSET32(etherstatspkts1024octetsto1522octets_hi), - 8, STATS_FLAGS_PORT, "tx_1024_to_1522_byte_packets" }, - { STATS_OFFSET32(etherstatspktsover1522octets_hi), - 8, STATS_FLAGS_PORT, "tx_1523_to_9022_byte_packets" }, - { STATS_OFFSET32(pause_frames_sent_hi), - 8, STATS_FLAGS_PORT, "tx_pause_frames" } -}; - #define IS_PORT_STAT(i) \ ((bnx2x_stats_arr[i].flags & STATS_FLAGS_BOTH) == STATS_FLAGS_PORT) #define IS_FUNC_STAT(i) (bnx2x_stats_arr[i].flags & STATS_FLAGS_FUNC) @@ -1890,7 +1958,8 @@ static int bnx2x_get_sset_count(struct net_device *dev, int stringset) switch (stringset) { case ETH_SS_STATS: if (is_multi(bp)) { - num_stats = BNX2X_NUM_Q_STATS * bp->num_queues; + num_stats = BNX2X_NUM_STAT_QUEUES(bp) * + BNX2X_NUM_Q_STATS; if (!IS_MF_MODE_STAT(bp)) num_stats += BNX2X_NUM_STATS; } else { @@ -1916,15 +1985,25 @@ static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf) { struct bnx2x *bp = netdev_priv(dev); int i, j, k; + char queue_name[MAX_QUEUE_NAME_LEN+1]; switch (stringset) { case ETH_SS_STATS: if (is_multi(bp)) { k = 0; - for_each_queue(bp, i) { + for_each_napi_queue(bp, i) { + memset(queue_name, 0, sizeof(queue_name)); + + if (IS_FCOE_IDX(i)) + sprintf(queue_name, "fcoe"); + else + sprintf(queue_name, "%d", i); + for (j = 0; j < BNX2X_NUM_Q_STATS; j++) - sprintf(buf + (k + j)*ETH_GSTRING_LEN, - bnx2x_q_stats_arr[j].string, i); + snprintf(buf + (k + j)*ETH_GSTRING_LEN, + ETH_GSTRING_LEN, + bnx2x_q_stats_arr[j].string, + queue_name); k += BNX2X_NUM_Q_STATS; } if (IS_MF_MODE_STAT(bp)) @@ -1958,7 +2037,7 @@ static void bnx2x_get_ethtool_stats(struct net_device *dev, if (is_multi(bp)) { k = 0; - for_each_queue(bp, i) { + for_each_napi_queue(bp, i) { hw_stats = (u32 *)&bp->fp[i].eth_q_stats; for (j = 0; j < BNX2X_NUM_Q_STATS; j++) { if (bnx2x_q_stats_arr[j].size == 0) { diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index 4cfd4e9b5586..6238d4f63989 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -434,7 +434,12 @@ struct shared_feat_cfg { /* NVRAM Offset */ #define SHARED_FEAT_CFG_OVERRIDE_PREEMPHASIS_CFG_DISABLED 0x00000000 #define SHARED_FEAT_CFG_OVERRIDE_PREEMPHASIS_CFG_ENABLED 0x00000002 -#define SHARED_FEATURE_MF_MODE_DISABLED 0x00000100 +#define SHARED_FEAT_CFG_FORCE_SF_MODE_MASK 0x00000700 +#define SHARED_FEAT_CFG_FORCE_SF_MODE_SHIFT 8 +#define SHARED_FEAT_CFG_FORCE_SF_MODE_MF_ALLOWED 0x00000000 +#define SHARED_FEAT_CFG_FORCE_SF_MODE_FORCED_SF 0x00000100 +#define SHARED_FEAT_CFG_FORCE_SF_MODE_SPIO4 0x00000200 +#define SHARED_FEAT_CFG_FORCE_SF_MODE_SWITCH_INDEPT 0x00000300 }; @@ -679,7 +684,7 @@ struct shm_dev_info { /* size */ #define E1VN_MAX 1 #define E1HVN_MAX 4 - +#define E2_VF_MAX 64 /* This value (in milliseconds) determines the frequency of the driver * issuing the PULSE message code. The firmware monitors this periodic * pulse to determine when to switch to an OS-absent mode. */ @@ -815,6 +820,11 @@ struct drv_func_mb { #define DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL 0xa1000000 #define REQ_BC_VER_4_VRFY_SPECIFIC_PHY_OPT_MDL 0x00050234 +#define DRV_MSG_CODE_DCBX_ADMIN_PMF_MSG 0xb0000000 +#define DRV_MSG_CODE_DCBX_PMF_DRV_OK 0xb2000000 +#define DRV_MSG_CODE_SET_MF_BW 0xe0000000 +#define REQ_BC_VER_4_SET_MF_BW 0x00060202 +#define DRV_MSG_CODE_SET_MF_BW_ACK 0xe1000000 #define BIOS_MSG_CODE_LIC_CHALLENGE 0xff010000 #define BIOS_MSG_CODE_LIC_RESPONSE 0xff020000 #define BIOS_MSG_CODE_VIRT_MAC_PRIM 0xff030000 @@ -888,6 +898,7 @@ struct drv_func_mb { u32 drv_status; #define DRV_STATUS_PMF 0x00000001 +#define DRV_STATUS_SET_MF_BW 0x00000004 #define DRV_STATUS_DCC_EVENT_MASK 0x0000ff00 #define DRV_STATUS_DCC_DISABLE_ENABLE_PF 0x00000100 @@ -896,6 +907,8 @@ struct drv_func_mb { #define DRV_STATUS_DCC_RESERVED1 0x00000800 #define DRV_STATUS_DCC_SET_PROTOCOL 0x00001000 #define DRV_STATUS_DCC_SET_PRIORITY 0x00002000 +#define DRV_STATUS_DCBX_EVENT_MASK 0x000f0000 +#define DRV_STATUS_DCBX_NEGOTIATION_RESULTS 0x00010000 u32 virt_mac_upper; #define VIRT_MAC_SIGN_MASK 0xffff0000 @@ -988,12 +1001,43 @@ struct func_mf_cfg { }; +/* This structure is not applicable and should not be accessed on 57711 */ +struct func_ext_cfg { + u32 func_cfg; +#define MACP_FUNC_CFG_FLAGS_MASK 0x000000FF +#define MACP_FUNC_CFG_FLAGS_SHIFT 0 +#define MACP_FUNC_CFG_FLAGS_ENABLED 0x00000001 +#define MACP_FUNC_CFG_FLAGS_ETHERNET 0x00000002 +#define MACP_FUNC_CFG_FLAGS_ISCSI_OFFLOAD 0x00000004 +#define MACP_FUNC_CFG_FLAGS_FCOE_OFFLOAD 0x00000008 + + u32 iscsi_mac_addr_upper; + u32 iscsi_mac_addr_lower; + + u32 fcoe_mac_addr_upper; + u32 fcoe_mac_addr_lower; + + u32 fcoe_wwn_port_name_upper; + u32 fcoe_wwn_port_name_lower; + + u32 fcoe_wwn_node_name_upper; + u32 fcoe_wwn_node_name_lower; + + u32 preserve_data; +#define MF_FUNC_CFG_PRESERVE_L2_MAC (1<<0) +#define MF_FUNC_CFG_PRESERVE_ISCSI_MAC (1<<1) +#define MF_FUNC_CFG_PRESERVE_FCOE_MAC (1<<2) +#define MF_FUNC_CFG_PRESERVE_FCOE_WWN_P (1<<3) +#define MF_FUNC_CFG_PRESERVE_FCOE_WWN_N (1<<4) +}; + struct mf_cfg { struct shared_mf_cfg shared_mf_config; struct port_mf_cfg port_mf_config[PORT_MAX]; struct func_mf_cfg func_mf_config[E1H_FUNC_MAX]; + struct func_ext_cfg func_ext_config[E1H_FUNC_MAX]; }; @@ -1049,6 +1093,251 @@ struct fw_flr_mb { struct fw_flr_ack ack; }; +/**** SUPPORT FOR SHMEM ARRRAYS *** + * The SHMEM HSI is aligned on 32 bit boundaries which makes it difficult to + * define arrays with storage types smaller then unsigned dwords. + * The macros below add generic support for SHMEM arrays with numeric elements + * that can span 2,4,8 or 16 bits. The array underlying type is a 32 bit dword + * array with individual bit-filed elements accessed using shifts and masks. + * + */ + +/* eb is the bitwidth of a single element */ +#define SHMEM_ARRAY_MASK(eb) ((1<<(eb))-1) +#define SHMEM_ARRAY_ENTRY(i, eb) ((i)/(32/(eb))) + +/* the bit-position macro allows the used to flip the order of the arrays + * elements on a per byte or word boundary. + * + * example: an array with 8 entries each 4 bit wide. This array will fit into + * a single dword. The diagrmas below show the array order of the nibbles. + * + * SHMEM_ARRAY_BITPOS(i, 4, 4) defines the stadard ordering: + * + * | | | | + * 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | + * | | | | + * + * SHMEM_ARRAY_BITPOS(i, 4, 8) defines a flip ordering per byte: + * + * | | | | + * 1 | 0 | 3 | 2 | 5 | 4 | 7 | 6 | + * | | | | + * + * SHMEM_ARRAY_BITPOS(i, 4, 16) defines a flip ordering per word: + * + * | | | | + * 3 | 2 | 1 | 0 | 7 | 6 | 5 | 4 | + * | | | | + */ +#define SHMEM_ARRAY_BITPOS(i, eb, fb) \ + ((((32/(fb)) - 1 - ((i)/((fb)/(eb))) % (32/(fb))) * (fb)) + \ + (((i)%((fb)/(eb))) * (eb))) + +#define SHMEM_ARRAY_GET(a, i, eb, fb) \ + ((a[SHMEM_ARRAY_ENTRY(i, eb)] >> SHMEM_ARRAY_BITPOS(i, eb, fb)) & \ + SHMEM_ARRAY_MASK(eb)) + +#define SHMEM_ARRAY_SET(a, i, eb, fb, val) \ +do { \ + a[SHMEM_ARRAY_ENTRY(i, eb)] &= ~(SHMEM_ARRAY_MASK(eb) << \ + SHMEM_ARRAY_BITPOS(i, eb, fb)); \ + a[SHMEM_ARRAY_ENTRY(i, eb)] |= (((val) & SHMEM_ARRAY_MASK(eb)) << \ + SHMEM_ARRAY_BITPOS(i, eb, fb)); \ +} while (0) + + +/****START OF DCBX STRUCTURES DECLARATIONS****/ +#define DCBX_MAX_NUM_PRI_PG_ENTRIES 8 +#define DCBX_PRI_PG_BITWIDTH 4 +#define DCBX_PRI_PG_FBITS 8 +#define DCBX_PRI_PG_GET(a, i) \ + SHMEM_ARRAY_GET(a, i, DCBX_PRI_PG_BITWIDTH, DCBX_PRI_PG_FBITS) +#define DCBX_PRI_PG_SET(a, i, val) \ + SHMEM_ARRAY_SET(a, i, DCBX_PRI_PG_BITWIDTH, DCBX_PRI_PG_FBITS, val) +#define DCBX_MAX_NUM_PG_BW_ENTRIES 8 +#define DCBX_BW_PG_BITWIDTH 8 +#define DCBX_PG_BW_GET(a, i) \ + SHMEM_ARRAY_GET(a, i, DCBX_BW_PG_BITWIDTH, DCBX_BW_PG_BITWIDTH) +#define DCBX_PG_BW_SET(a, i, val) \ + SHMEM_ARRAY_SET(a, i, DCBX_BW_PG_BITWIDTH, DCBX_BW_PG_BITWIDTH, val) +#define DCBX_STRICT_PRI_PG 15 +#define DCBX_MAX_APP_PROTOCOL 16 +#define FCOE_APP_IDX 0 +#define ISCSI_APP_IDX 1 +#define PREDEFINED_APP_IDX_MAX 2 + +struct dcbx_ets_feature { + u32 enabled; + u32 pg_bw_tbl[2]; + u32 pri_pg_tbl[1]; +}; + +struct dcbx_pfc_feature { +#ifdef __BIG_ENDIAN + u8 pri_en_bitmap; +#define DCBX_PFC_PRI_0 0x01 +#define DCBX_PFC_PRI_1 0x02 +#define DCBX_PFC_PRI_2 0x04 +#define DCBX_PFC_PRI_3 0x08 +#define DCBX_PFC_PRI_4 0x10 +#define DCBX_PFC_PRI_5 0x20 +#define DCBX_PFC_PRI_6 0x40 +#define DCBX_PFC_PRI_7 0x80 + u8 pfc_caps; + u8 reserved; + u8 enabled; +#elif defined(__LITTLE_ENDIAN) + u8 enabled; + u8 reserved; + u8 pfc_caps; + u8 pri_en_bitmap; +#define DCBX_PFC_PRI_0 0x01 +#define DCBX_PFC_PRI_1 0x02 +#define DCBX_PFC_PRI_2 0x04 +#define DCBX_PFC_PRI_3 0x08 +#define DCBX_PFC_PRI_4 0x10 +#define DCBX_PFC_PRI_5 0x20 +#define DCBX_PFC_PRI_6 0x40 +#define DCBX_PFC_PRI_7 0x80 +#endif +}; + +struct dcbx_app_priority_entry { +#ifdef __BIG_ENDIAN + u16 app_id; + u8 pri_bitmap; + u8 appBitfield; +#define DCBX_APP_ENTRY_VALID 0x01 +#define DCBX_APP_ENTRY_SF_MASK 0x30 +#define DCBX_APP_ENTRY_SF_SHIFT 4 +#define DCBX_APP_SF_ETH_TYPE 0x10 +#define DCBX_APP_SF_PORT 0x20 +#elif defined(__LITTLE_ENDIAN) + u8 appBitfield; +#define DCBX_APP_ENTRY_VALID 0x01 +#define DCBX_APP_ENTRY_SF_MASK 0x30 +#define DCBX_APP_ENTRY_SF_SHIFT 4 +#define DCBX_APP_SF_ETH_TYPE 0x10 +#define DCBX_APP_SF_PORT 0x20 + u8 pri_bitmap; + u16 app_id; +#endif +}; + +struct dcbx_app_priority_feature { +#ifdef __BIG_ENDIAN + u8 reserved; + u8 default_pri; + u8 tc_supported; + u8 enabled; +#elif defined(__LITTLE_ENDIAN) + u8 enabled; + u8 tc_supported; + u8 default_pri; + u8 reserved; +#endif + struct dcbx_app_priority_entry app_pri_tbl[DCBX_MAX_APP_PROTOCOL]; +}; + +struct dcbx_features { + struct dcbx_ets_feature ets; + struct dcbx_pfc_feature pfc; + struct dcbx_app_priority_feature app; +}; + +struct lldp_params { +#ifdef __BIG_ENDIAN + u8 msg_fast_tx_interval; + u8 msg_tx_hold; + u8 msg_tx_interval; + u8 admin_status; +#define LLDP_TX_ONLY 0x01 +#define LLDP_RX_ONLY 0x02 +#define LLDP_TX_RX 0x03 +#define LLDP_DISABLED 0x04 + u8 reserved1; + u8 tx_fast; + u8 tx_crd_max; + u8 tx_crd; +#elif defined(__LITTLE_ENDIAN) + u8 admin_status; +#define LLDP_TX_ONLY 0x01 +#define LLDP_RX_ONLY 0x02 +#define LLDP_TX_RX 0x03 +#define LLDP_DISABLED 0x04 + u8 msg_tx_interval; + u8 msg_tx_hold; + u8 msg_fast_tx_interval; + u8 tx_crd; + u8 tx_crd_max; + u8 tx_fast; + u8 reserved1; +#endif +#define REM_CHASSIS_ID_STAT_LEN 4 +#define REM_PORT_ID_STAT_LEN 4 + u32 peer_chassis_id[REM_CHASSIS_ID_STAT_LEN]; + u32 peer_port_id[REM_PORT_ID_STAT_LEN]; +}; + +struct lldp_dcbx_stat { +#define LOCAL_CHASSIS_ID_STAT_LEN 2 +#define LOCAL_PORT_ID_STAT_LEN 2 + u32 local_chassis_id[LOCAL_CHASSIS_ID_STAT_LEN]; + u32 local_port_id[LOCAL_PORT_ID_STAT_LEN]; + u32 num_tx_dcbx_pkts; + u32 num_rx_dcbx_pkts; +}; + +struct lldp_admin_mib { + u32 ver_cfg_flags; +#define DCBX_ETS_CONFIG_TX_ENABLED 0x00000001 +#define DCBX_PFC_CONFIG_TX_ENABLED 0x00000002 +#define DCBX_APP_CONFIG_TX_ENABLED 0x00000004 +#define DCBX_ETS_RECO_TX_ENABLED 0x00000008 +#define DCBX_ETS_RECO_VALID 0x00000010 +#define DCBX_ETS_WILLING 0x00000020 +#define DCBX_PFC_WILLING 0x00000040 +#define DCBX_APP_WILLING 0x00000080 +#define DCBX_VERSION_CEE 0x00000100 +#define DCBX_VERSION_IEEE 0x00000200 +#define DCBX_DCBX_ENABLED 0x00000400 +#define DCBX_CEE_VERSION_MASK 0x0000f000 +#define DCBX_CEE_VERSION_SHIFT 12 +#define DCBX_CEE_MAX_VERSION_MASK 0x000f0000 +#define DCBX_CEE_MAX_VERSION_SHIFT 16 + struct dcbx_features features; +}; + +struct lldp_remote_mib { + u32 prefix_seq_num; + u32 flags; +#define DCBX_ETS_TLV_RX 0x00000001 +#define DCBX_PFC_TLV_RX 0x00000002 +#define DCBX_APP_TLV_RX 0x00000004 +#define DCBX_ETS_RX_ERROR 0x00000010 +#define DCBX_PFC_RX_ERROR 0x00000020 +#define DCBX_APP_RX_ERROR 0x00000040 +#define DCBX_ETS_REM_WILLING 0x00000100 +#define DCBX_PFC_REM_WILLING 0x00000200 +#define DCBX_APP_REM_WILLING 0x00000400 +#define DCBX_REMOTE_ETS_RECO_VALID 0x00001000 + struct dcbx_features features; + u32 suffix_seq_num; +}; + +struct lldp_local_mib { + u32 prefix_seq_num; + u32 error; +#define DCBX_LOCAL_ETS_ERROR 0x00000001 +#define DCBX_LOCAL_PFC_ERROR 0x00000002 +#define DCBX_LOCAL_APP_ERROR 0x00000004 +#define DCBX_LOCAL_PFC_MISMATCH 0x00000010 +#define DCBX_LOCAL_APP_MISMATCH 0x00000020 + struct dcbx_features features; + u32 suffix_seq_num; +}; +/***END OF DCBX STRUCTURES DECLARATIONS***/ struct shmem2_region { @@ -1072,7 +1361,12 @@ struct shmem2_region { #define SHMEM_MF_CFG_ADDR_NONE 0x00000000 struct fw_flr_mb flr_mb; - u32 reserved[3]; + u32 dcbx_lldp_params_offset; +#define SHMEM_LLDP_DCBX_PARAMS_NONE 0x00000000 + u32 dcbx_neg_res_offset; +#define SHMEM_DCBX_NEG_RES_NONE 0x00000000 + u32 dcbx_remote_mib_offset; +#define SHMEM_DCBX_REMOTE_MIB_NONE 0x00000000 /* * The other shmemX_base_addr holds the other path's shmem address * required for example in case of common phy init, or for path1 to know @@ -1081,6 +1375,10 @@ struct shmem2_region { */ u32 other_shmem_base_addr; u32 other_shmem2_base_addr; + u32 reserved1[E2_VF_MAX / 32]; + u32 reserved2[E2_FUNC_MAX][E2_VF_MAX / 32]; + u32 dcbx_lldp_dcbx_stat_offset; +#define SHMEM_LLDP_DCBX_STAT_NONE 0x00000000 }; @@ -1534,8 +1832,8 @@ struct host_func_stats { #define BCM_5710_FW_MAJOR_VERSION 6 -#define BCM_5710_FW_MINOR_VERSION 0 -#define BCM_5710_FW_REVISION_VERSION 34 +#define BCM_5710_FW_MINOR_VERSION 2 +#define BCM_5710_FW_REVISION_VERSION 5 #define BCM_5710_FW_ENGINEERING_VERSION 0 #define BCM_5710_FW_COMPILE_FLAGS 1 @@ -2983,6 +3281,25 @@ struct fairness_vars_per_vn { /* + * The data for flow control configuration + */ +struct flow_control_configuration { + struct priority_cos + traffic_type_to_priority_cos[MAX_PFC_TRAFFIC_TYPES]; +#if defined(__BIG_ENDIAN) + u16 reserved1; + u8 dcb_version; + u8 dcb_enabled; +#elif defined(__LITTLE_ENDIAN) + u8 dcb_enabled; + u8 dcb_version; + u16 reserved1; +#endif + u32 reserved2; +}; + + +/* * FW version stored in the Xstorm RAM */ struct fw_version { diff --git a/drivers/net/bnx2x/bnx2x_init.h b/drivers/net/bnx2x/bnx2x_init.h index a9d54874a559..5a268e9a0895 100644 --- a/drivers/net/bnx2x/bnx2x_init.h +++ b/drivers/net/bnx2x/bnx2x_init.h @@ -192,5 +192,225 @@ struct src_ent { u64 next; }; +/**************************************************************************** +* Parity configuration +****************************************************************************/ +#define BLOCK_PRTY_INFO(block, en_mask, m1, m1h, m2) \ +{ \ + block##_REG_##block##_PRTY_MASK, \ + block##_REG_##block##_PRTY_STS_CLR, \ + en_mask, {m1, m1h, m2}, #block \ +} + +#define BLOCK_PRTY_INFO_0(block, en_mask, m1, m1h, m2) \ +{ \ + block##_REG_##block##_PRTY_MASK_0, \ + block##_REG_##block##_PRTY_STS_CLR_0, \ + en_mask, {m1, m1h, m2}, #block"_0" \ +} + +#define BLOCK_PRTY_INFO_1(block, en_mask, m1, m1h, m2) \ +{ \ + block##_REG_##block##_PRTY_MASK_1, \ + block##_REG_##block##_PRTY_STS_CLR_1, \ + en_mask, {m1, m1h, m2}, #block"_1" \ +} + +static const struct { + u32 mask_addr; + u32 sts_clr_addr; + u32 en_mask; /* Mask to enable parity attentions */ + struct { + u32 e1; /* 57710 */ + u32 e1h; /* 57711 */ + u32 e2; /* 57712 */ + } reg_mask; /* Register mask (all valid bits) */ + char name[7]; /* Block's longest name is 6 characters long + * (name + suffix) + */ +} bnx2x_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, 0x3ffffff, 0x3ffffff, 0x3ffffff, 0x3ffffff), + BLOCK_PRTY_INFO_0(PXP2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), + BLOCK_PRTY_INFO_1(PXP2, 0x7ff, 0x7f, 0x7f, 0x7ff), + BLOCK_PRTY_INFO(HC, 0x7, 0x7, 0x7, 0), + BLOCK_PRTY_INFO(IGU, 0x7ff, 0, 0, 0x7ff), + BLOCK_PRTY_INFO(MISC, 0x1, 0x1, 0x1, 0x1), + BLOCK_PRTY_INFO(QM, 0, 0x1ff, 0xfff, 0xfff), + BLOCK_PRTY_INFO(DORQ, 0, 0x3, 0x3, 0x3), + {GRCBASE_UPB + PB_REG_PB_PRTY_MASK, + GRCBASE_UPB + PB_REG_PB_PRTY_STS_CLR, 0, + {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, 0xf), + 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(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_0(TSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff), + BLOCK_PRTY_INFO_1(TSEM, 0, 0x3, 0x1f, 0x3f), + BLOCK_PRTY_INFO_0(USEM, 0, 0xffffffff, 0xffffffff, 0xffffffff), + BLOCK_PRTY_INFO_1(USEM, 0, 0x3, 0x1f, 0x1f), + BLOCK_PRTY_INFO_0(CSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff), + BLOCK_PRTY_INFO_1(CSEM, 0, 0x3, 0x1f, 0x1f), + BLOCK_PRTY_INFO_0(XSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff), + BLOCK_PRTY_INFO_1(XSEM, 0, 0x3, 0x1f, 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 u32 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 bnx2x_set_mcp_parity(struct bnx2x *bp, u8 enable) +{ + int i; + u32 reg_val; + + for (i = 0; i < ARRAY_SIZE(mcp_attn_ctl_regs); i++) { + reg_val = REG_RD(bp, 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(bp, mcp_attn_ctl_regs[i], reg_val); + } +} + +static inline u32 bnx2x_parity_reg_mask(struct bnx2x *bp, int idx) +{ + if (CHIP_IS_E1(bp)) + return bnx2x_blocks_parity_data[idx].reg_mask.e1; + else if (CHIP_IS_E1H(bp)) + return bnx2x_blocks_parity_data[idx].reg_mask.e1h; + else + return bnx2x_blocks_parity_data[idx].reg_mask.e2; +} + +static inline void bnx2x_disable_blocks_parity(struct bnx2x *bp) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(bnx2x_blocks_parity_data); i++) { + u32 dis_mask = bnx2x_parity_reg_mask(bp, i); + + if (dis_mask) { + REG_WR(bp, bnx2x_blocks_parity_data[i].mask_addr, + dis_mask); + DP(NETIF_MSG_HW, "Setting parity mask " + "for %s to\t\t0x%x\n", + bnx2x_blocks_parity_data[i].name, dis_mask); + } + } + + /* Disable MCP parity attentions */ + bnx2x_set_mcp_parity(bp, false); +} + +/** + * Clear the parity error status registers. + */ +static inline void bnx2x_clear_blocks_parity(struct bnx2x *bp) +{ + int i; + u32 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(bp, XSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1); + REG_WR(bp, TSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1); + REG_WR(bp, USEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1); + REG_WR(bp, CSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1); + + for (i = 0; i < ARRAY_SIZE(bnx2x_blocks_parity_data); i++) { + u32 reg_mask = bnx2x_parity_reg_mask(bp, i); + + if (reg_mask) { + reg_val = REG_RD(bp, bnx2x_blocks_parity_data[i]. + sts_clr_addr); + if (reg_val & reg_mask) + DP(NETIF_MSG_HW, + "Parity errors in %s: 0x%x\n", + bnx2x_blocks_parity_data[i].name, + reg_val & reg_mask); + } + } + + /* Check if there were parity attentions in MCP */ + reg_val = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_4_MCP); + if (reg_val & mcp_aeu_bits) + DP(NETIF_MSG_HW, "Parity error in MCP: 0x%x\n", + 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(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0x780); +} + +static inline void bnx2x_enable_blocks_parity(struct bnx2x *bp) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(bnx2x_blocks_parity_data); i++) { + u32 reg_mask = bnx2x_parity_reg_mask(bp, i); + + if (reg_mask) + REG_WR(bp, bnx2x_blocks_parity_data[i].mask_addr, + bnx2x_blocks_parity_data[i].en_mask & reg_mask); + } + + /* Enable MCP parity attentions */ + bnx2x_set_mcp_parity(bp, true); +} + + #endif /* BNX2X_INIT_H */ diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 580919619252..43b0de24f391 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -164,7 +164,8 @@ #define EDC_MODE_PASSIVE_DAC 0x0055 - +#define ETS_BW_LIMIT_CREDIT_UPPER_BOUND (0x5000) +#define ETS_BW_LIMIT_CREDIT_WEIGHT (0x5000) /**********************************************************/ /* INTERFACE */ /**********************************************************/ @@ -205,6 +206,270 @@ static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits) return val; } +/******************************************************************/ +/* ETS section */ +/******************************************************************/ +void bnx2x_ets_disabled(struct link_params *params) +{ + /* ETS disabled configuration*/ + struct bnx2x *bp = params->bp; + + DP(NETIF_MSG_LINK, "ETS disabled configuration\n"); + + /** + * mapping between entry priority to client number (0,1,2 -debug and + * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST) + * 3bits client num. + * PRI4 | PRI3 | PRI2 | PRI1 | PRI0 + * cos1-100 cos0-011 dbg1-010 dbg0-001 MCP-000 + */ + + REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, 0x4688); + /** + * Bitmap of 5bits length. Each bit specifies whether the entry behaves + * as strict. Bits 0,1,2 - debug and management entries, 3 - + * COS0 entry, 4 - COS1 entry. + * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT + * bit4 bit3 bit2 bit1 bit0 + * MCP and debug are strict + */ + + REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7); + /* defines which entries (clients) are subjected to WFQ arbitration */ + REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0); + /** + * For strict priority entries defines the number of consecutive + * slots for the highest priority. + */ + REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100); + /** + * mapping between the CREDIT_WEIGHT registers and actual client + * numbers + */ + REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0); + REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0); + REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0); + + REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, 0); + REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, 0); + REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, 0); + /* ETS mode disable */ + REG_WR(bp, PBF_REG_ETS_ENABLED, 0); + /** + * If ETS mode is enabled (there is no strict priority) defines a WFQ + * weight for COS0/COS1. + */ + REG_WR(bp, PBF_REG_COS0_WEIGHT, 0x2710); + REG_WR(bp, PBF_REG_COS1_WEIGHT, 0x2710); + /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter */ + REG_WR(bp, PBF_REG_COS0_UPPER_BOUND, 0x989680); + REG_WR(bp, PBF_REG_COS1_UPPER_BOUND, 0x989680); + /* Defines the number of consecutive slots for the strict priority */ + REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0); +} + +void bnx2x_ets_bw_limit_common(const struct link_params *params) +{ + /* ETS disabled configuration */ + struct bnx2x *bp = params->bp; + DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n"); + /** + * defines which entries (clients) are subjected to WFQ arbitration + * COS0 0x8 + * COS1 0x10 + */ + REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0x18); + /** + * mapping between the ARB_CREDIT_WEIGHT registers and actual + * client numbers (WEIGHT_0 does not actually have to represent + * client 0) + * PRI4 | PRI3 | PRI2 | PRI1 | PRI0 + * cos1-001 cos0-000 dbg1-100 dbg0-011 MCP-010 + */ + REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0x111A); + + REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, + ETS_BW_LIMIT_CREDIT_UPPER_BOUND); + REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, + ETS_BW_LIMIT_CREDIT_UPPER_BOUND); + + /* ETS mode enabled*/ + REG_WR(bp, PBF_REG_ETS_ENABLED, 1); + + /* Defines the number of consecutive slots for the strict priority */ + REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0); + /** + * Bitmap of 5bits length. Each bit specifies whether the entry behaves + * as strict. Bits 0,1,2 - debug and management entries, 3 - COS0 + * entry, 4 - COS1 entry. + * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT + * bit4 bit3 bit2 bit1 bit0 + * MCP and debug are strict + */ + REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7); + + /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter.*/ + REG_WR(bp, PBF_REG_COS0_UPPER_BOUND, + ETS_BW_LIMIT_CREDIT_UPPER_BOUND); + REG_WR(bp, PBF_REG_COS1_UPPER_BOUND, + ETS_BW_LIMIT_CREDIT_UPPER_BOUND); +} + +void bnx2x_ets_bw_limit(const struct link_params *params, const u32 cos0_bw, + const u32 cos1_bw) +{ + /* ETS disabled configuration*/ + struct bnx2x *bp = params->bp; + const u32 total_bw = cos0_bw + cos1_bw; + u32 cos0_credit_weight = 0; + u32 cos1_credit_weight = 0; + + DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n"); + + if ((0 == total_bw) || + (0 == cos0_bw) || + (0 == cos1_bw)) { + DP(NETIF_MSG_LINK, + "bnx2x_ets_bw_limit: Total BW can't be zero\n"); + return; + } + + cos0_credit_weight = (cos0_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/ + total_bw; + cos1_credit_weight = (cos1_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/ + total_bw; + + bnx2x_ets_bw_limit_common(params); + + REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, cos0_credit_weight); + REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, cos1_credit_weight); + + REG_WR(bp, PBF_REG_COS0_WEIGHT, cos0_credit_weight); + REG_WR(bp, PBF_REG_COS1_WEIGHT, cos1_credit_weight); +} + +u8 bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos) +{ + /* ETS disabled configuration*/ + struct bnx2x *bp = params->bp; + u32 val = 0; + + DP(NETIF_MSG_LINK, "ETS enabled strict configuration\n"); + /** + * Bitmap of 5bits length. Each bit specifies whether the entry behaves + * as strict. Bits 0,1,2 - debug and management entries, + * 3 - COS0 entry, 4 - COS1 entry. + * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT + * bit4 bit3 bit2 bit1 bit0 + * MCP and debug are strict + */ + REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1F); + /** + * For strict priority entries defines the number of consecutive slots + * for the highest priority. + */ + REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100); + /* ETS mode disable */ + REG_WR(bp, PBF_REG_ETS_ENABLED, 0); + /* Defines the number of consecutive slots for the strict priority */ + REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0x100); + + /* Defines the number of consecutive slots for the strict priority */ + REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, strict_cos); + + /** + * mapping between entry priority to client number (0,1,2 -debug and + * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST) + * 3bits client num. + * PRI4 | PRI3 | PRI2 | PRI1 | PRI0 + * dbg0-010 dbg1-001 cos1-100 cos0-011 MCP-000 + * dbg0-010 dbg1-001 cos0-011 cos1-100 MCP-000 + */ + val = (0 == strict_cos) ? 0x2318 : 0x22E0; + REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, val); + + return 0; +} +/******************************************************************/ +/* ETS section */ +/******************************************************************/ + +static void bnx2x_bmac2_get_pfc_stat(struct link_params *params, + u32 pfc_frames_sent[2], + u32 pfc_frames_received[2]) +{ + /* Read pfc statistic */ + struct bnx2x *bp = params->bp; + u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM : + NIG_REG_INGRESS_BMAC0_MEM; + + DP(NETIF_MSG_LINK, "pfc statistic read from BMAC\n"); + + REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_STAT_GTPP, + pfc_frames_sent, 2); + + REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_STAT_GRPP, + pfc_frames_received, 2); + +} +static void bnx2x_emac_get_pfc_stat(struct link_params *params, + u32 pfc_frames_sent[2], + u32 pfc_frames_received[2]) +{ + /* Read pfc statistic */ + struct bnx2x *bp = params->bp; + u32 emac_base = params->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; + u32 val_xon = 0; + u32 val_xoff = 0; + + DP(NETIF_MSG_LINK, "pfc statistic read from EMAC\n"); + + /* PFC received frames */ + val_xoff = REG_RD(bp, emac_base + + EMAC_REG_RX_PFC_STATS_XOFF_RCVD); + val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_RCVD_COUNT; + val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_RCVD); + val_xon &= EMAC_REG_RX_PFC_STATS_XON_RCVD_COUNT; + + pfc_frames_received[0] = val_xon + val_xoff; + + /* PFC received sent */ + val_xoff = REG_RD(bp, emac_base + + EMAC_REG_RX_PFC_STATS_XOFF_SENT); + val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_SENT_COUNT; + val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_SENT); + val_xon &= EMAC_REG_RX_PFC_STATS_XON_SENT_COUNT; + + pfc_frames_sent[0] = val_xon + val_xoff; +} + +void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars, + u32 pfc_frames_sent[2], + u32 pfc_frames_received[2]) +{ + /* Read pfc statistic */ + struct bnx2x *bp = params->bp; + u32 val = 0; + DP(NETIF_MSG_LINK, "pfc statistic\n"); + + if (!vars->link_up) + return; + + val = REG_RD(bp, MISC_REG_RESET_REG_2); + if ((val & (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) + == 0) { + DP(NETIF_MSG_LINK, "About to read stats from EMAC\n"); + bnx2x_emac_get_pfc_stat(params, pfc_frames_sent, + pfc_frames_received); + } else { + DP(NETIF_MSG_LINK, "About to read stats from BMAC\n"); + bnx2x_bmac2_get_pfc_stat(params, pfc_frames_sent, + pfc_frames_received); + } +} +/******************************************************************/ +/* MAC/PBF section */ +/******************************************************************/ static void bnx2x_emac_init(struct link_params *params, struct link_vars *vars) { @@ -315,24 +580,55 @@ static u8 bnx2x_emac_enable(struct link_params *params, /* pause enable/disable */ bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE, EMAC_RX_MODE_FLOW_EN); - if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX) - bnx2x_bits_en(bp, emac_base + - EMAC_REG_EMAC_RX_MODE, - EMAC_RX_MODE_FLOW_EN); bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE, - (EMAC_TX_MODE_EXT_PAUSE_EN | - EMAC_TX_MODE_FLOW_EN)); - if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) - bnx2x_bits_en(bp, emac_base + - EMAC_REG_EMAC_TX_MODE, - (EMAC_TX_MODE_EXT_PAUSE_EN | - EMAC_TX_MODE_FLOW_EN)); + (EMAC_TX_MODE_EXT_PAUSE_EN | + EMAC_TX_MODE_FLOW_EN)); + if (!(params->feature_config_flags & + FEATURE_CONFIG_PFC_ENABLED)) { + if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX) + bnx2x_bits_en(bp, emac_base + + EMAC_REG_EMAC_RX_MODE, + EMAC_RX_MODE_FLOW_EN); + + if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) + bnx2x_bits_en(bp, emac_base + + EMAC_REG_EMAC_TX_MODE, + (EMAC_TX_MODE_EXT_PAUSE_EN | + EMAC_TX_MODE_FLOW_EN)); + } else + bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE, + EMAC_TX_MODE_FLOW_EN); } /* KEEP_VLAN_TAG, promiscuous */ val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE); val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS; + + /** + * Setting this bit causes MAC control frames (except for pause + * frames) to be passed on for processing. This setting has no + * affect on the operation of the pause frames. This bit effects + * all packets regardless of RX Parser packet sorting logic. + * Turn the PFC off to make sure we are in Xon state before + * enabling it. + */ + EMAC_WR(bp, EMAC_REG_RX_PFC_MODE, 0); + if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) { + DP(NETIF_MSG_LINK, "PFC is enabled\n"); + /* Enable PFC again */ + EMAC_WR(bp, EMAC_REG_RX_PFC_MODE, + EMAC_REG_RX_PFC_MODE_RX_EN | + EMAC_REG_RX_PFC_MODE_TX_EN | + EMAC_REG_RX_PFC_MODE_PRIORITIES); + + EMAC_WR(bp, EMAC_REG_RX_PFC_PARAM, + ((0x0101 << + EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT) | + (0x00ff << + EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT))); + val |= EMAC_RX_MODE_KEEP_MAC_CONTROL; + } EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val); /* Set Loopback */ @@ -362,7 +658,9 @@ static u8 bnx2x_emac_enable(struct link_params *params, /* enable the NIG in/out to the emac */ REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1); val = 0; - if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) + if ((params->feature_config_flags & + FEATURE_CONFIG_PFC_ENABLED) || + (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)) val = 1; REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val); @@ -383,9 +681,38 @@ static u8 bnx2x_emac_enable(struct link_params *params, return 0; } -static void bnx2x_update_bmac2(struct link_params *params, - struct link_vars *vars, - u8 is_lb) +static void bnx2x_update_pfc_bmac1(struct link_params *params, + struct link_vars *vars) +{ + u32 wb_data[2]; + struct bnx2x *bp = params->bp; + u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM : + NIG_REG_INGRESS_BMAC0_MEM; + + u32 val = 0x14; + if ((!(params->feature_config_flags & + FEATURE_CONFIG_PFC_ENABLED)) && + (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)) + /* Enable BigMAC to react on received Pause packets */ + val |= (1<<5); + wb_data[0] = val; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_data, 2); + + /* tx control */ + val = 0xc0; + if (!(params->feature_config_flags & + FEATURE_CONFIG_PFC_ENABLED) && + (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)) + val |= 0x800000; + wb_data[0] = val; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_data, 2); +} + +static void bnx2x_update_pfc_bmac2(struct link_params *params, + struct link_vars *vars, + u8 is_lb) { /* * Set rx control: Strip CRC and enable BigMAC to relay @@ -397,7 +724,9 @@ static void bnx2x_update_bmac2(struct link_params *params, NIG_REG_INGRESS_BMAC0_MEM; u32 val = 0x14; - if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX) + if ((!(params->feature_config_flags & + FEATURE_CONFIG_PFC_ENABLED)) && + (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)) /* Enable BigMAC to react on received Pause packets */ val |= (1<<5); wb_data[0] = val; @@ -408,14 +737,47 @@ static void bnx2x_update_bmac2(struct link_params *params, /* Tx control */ val = 0xc0; - if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) + if (!(params->feature_config_flags & + FEATURE_CONFIG_PFC_ENABLED) && + (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)) val |= 0x800000; wb_data[0] = val; wb_data[1] = 0; - REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, - wb_data, 2); + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, wb_data, 2); + + if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) { + DP(NETIF_MSG_LINK, "PFC is enabled\n"); + /* Enable PFC RX & TX & STATS and set 8 COS */ + wb_data[0] = 0x0; + wb_data[0] |= (1<<0); /* RX */ + wb_data[0] |= (1<<1); /* TX */ + wb_data[0] |= (1<<2); /* Force initial Xon */ + wb_data[0] |= (1<<3); /* 8 cos */ + wb_data[0] |= (1<<5); /* STATS */ + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, + wb_data, 2); + /* Clear the force Xon */ + wb_data[0] &= ~(1<<2); + } else { + DP(NETIF_MSG_LINK, "PFC is disabled\n"); + /* disable PFC RX & TX & STATS and set 8 COS */ + wb_data[0] = 0x8; + wb_data[1] = 0; + } + + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, wb_data, 2); + /** + * Set Time (based unit is 512 bit time) between automatic + * re-sending of PP packets amd enable automatic re-send of + * Per-Priroity Packet as long as pp_gen is asserted and + * pp_disable is low. + */ val = 0x8000; + if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) + val |= (1<<16); /* enable automatic re-send */ + wb_data[0] = val; wb_data[1] = 0; REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL, @@ -427,6 +789,9 @@ static void bnx2x_update_bmac2(struct link_params *params, val |= 0x4; /* Local loopback */ DP(NETIF_MSG_LINK, "enable bmac loopback\n"); } + /* When PFC enabled, Pass pause frames towards the NIG. */ + if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) + val |= ((1<<6)|(1<<5)); wb_data[0] = val; wb_data[1] = 0; @@ -434,6 +799,239 @@ static void bnx2x_update_bmac2(struct link_params *params, wb_data, 2); } +static void bnx2x_update_pfc_brb(struct link_params *params, + struct link_vars *vars, + struct bnx2x_nig_brb_pfc_port_params *pfc_params) +{ + struct bnx2x *bp = params->bp; + int set_pfc = params->feature_config_flags & + FEATURE_CONFIG_PFC_ENABLED; + + /* default - pause configuration */ + u32 pause_xoff_th = PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_PAUSEABLE; + u32 pause_xon_th = PFC_BRB_MAC_PAUSE_XON_THRESHOLD_PAUSEABLE; + u32 full_xoff_th = PFC_BRB_MAC_FULL_XOFF_THRESHOLD_PAUSEABLE; + u32 full_xon_th = PFC_BRB_MAC_FULL_XON_THRESHOLD_PAUSEABLE; + + if (set_pfc && pfc_params) + /* First COS */ + if (!pfc_params->cos0_pauseable) { + pause_xoff_th = + PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_NON_PAUSEABLE; + pause_xon_th = + PFC_BRB_MAC_PAUSE_XON_THRESHOLD_NON_PAUSEABLE; + full_xoff_th = + PFC_BRB_MAC_FULL_XOFF_THRESHOLD_NON_PAUSEABLE; + full_xon_th = + PFC_BRB_MAC_FULL_XON_THRESHOLD_NON_PAUSEABLE; + } + /* The number of free blocks below which the pause signal to class 0 + of MAC #n is asserted. n=0,1 */ + REG_WR(bp, BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 , pause_xoff_th); + /* The number of free blocks above which the pause signal to class 0 + of MAC #n is de-asserted. n=0,1 */ + REG_WR(bp, BRB1_REG_PAUSE_0_XON_THRESHOLD_0 , pause_xon_th); + /* The number of free blocks below which the full signal to class 0 + of MAC #n is asserted. n=0,1 */ + REG_WR(bp, BRB1_REG_FULL_0_XOFF_THRESHOLD_0 , full_xoff_th); + /* The number of free blocks above which the full signal to class 0 + of MAC #n is de-asserted. n=0,1 */ + REG_WR(bp, BRB1_REG_FULL_0_XON_THRESHOLD_0 , full_xon_th); + + if (set_pfc && pfc_params) { + /* Second COS */ + if (pfc_params->cos1_pauseable) { + pause_xoff_th = + PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_PAUSEABLE; + pause_xon_th = + PFC_BRB_MAC_PAUSE_XON_THRESHOLD_PAUSEABLE; + full_xoff_th = + PFC_BRB_MAC_FULL_XOFF_THRESHOLD_PAUSEABLE; + full_xon_th = + PFC_BRB_MAC_FULL_XON_THRESHOLD_PAUSEABLE; + } else { + pause_xoff_th = + PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_NON_PAUSEABLE; + pause_xon_th = + PFC_BRB_MAC_PAUSE_XON_THRESHOLD_NON_PAUSEABLE; + full_xoff_th = + PFC_BRB_MAC_FULL_XOFF_THRESHOLD_NON_PAUSEABLE; + full_xon_th = + PFC_BRB_MAC_FULL_XON_THRESHOLD_NON_PAUSEABLE; + } + /** + * The number of free blocks below which the pause signal to + * class 1 of MAC #n is asserted. n=0,1 + **/ + REG_WR(bp, BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0, pause_xoff_th); + /** + * The number of free blocks above which the pause signal to + * class 1 of MAC #n is de-asserted. n=0,1 + **/ + REG_WR(bp, BRB1_REG_PAUSE_1_XON_THRESHOLD_0, pause_xon_th); + /** + * The number of free blocks below which the full signal to + * class 1 of MAC #n is asserted. n=0,1 + **/ + REG_WR(bp, BRB1_REG_FULL_1_XOFF_THRESHOLD_0, full_xoff_th); + /** + * The number of free blocks above which the full signal to + * class 1 of MAC #n is de-asserted. n=0,1 + **/ + REG_WR(bp, BRB1_REG_FULL_1_XON_THRESHOLD_0, full_xon_th); + } +} + +static void bnx2x_update_pfc_nig(struct link_params *params, + struct link_vars *vars, + struct bnx2x_nig_brb_pfc_port_params *nig_params) +{ + u32 xcm_mask = 0, ppp_enable = 0, pause_enable = 0, llfc_out_en = 0; + u32 llfc_enable = 0, xcm0_out_en = 0, p0_hwpfc_enable = 0; + u32 pkt_priority_to_cos = 0; + u32 val; + struct bnx2x *bp = params->bp; + int port = params->port; + int set_pfc = params->feature_config_flags & + FEATURE_CONFIG_PFC_ENABLED; + DP(NETIF_MSG_LINK, "updating pfc nig parameters\n"); + + /** + * When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set + * MAC control frames (that are not pause packets) + * will be forwarded to the XCM. + */ + xcm_mask = REG_RD(bp, + port ? NIG_REG_LLH1_XCM_MASK : + NIG_REG_LLH0_XCM_MASK); + /** + * nig params will override non PFC params, since it's possible to + * do transition from PFC to SAFC + */ + if (set_pfc) { + pause_enable = 0; + llfc_out_en = 0; + llfc_enable = 0; + ppp_enable = 1; + xcm_mask &= ~(port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN : + NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN); + xcm0_out_en = 0; + p0_hwpfc_enable = 1; + } else { + if (nig_params) { + llfc_out_en = nig_params->llfc_out_en; + llfc_enable = nig_params->llfc_enable; + pause_enable = nig_params->pause_enable; + } else /*defaul non PFC mode - PAUSE */ + pause_enable = 1; + + xcm_mask |= (port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN : + NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN); + xcm0_out_en = 1; + } + + REG_WR(bp, port ? NIG_REG_LLFC_OUT_EN_1 : + NIG_REG_LLFC_OUT_EN_0, llfc_out_en); + REG_WR(bp, port ? NIG_REG_LLFC_ENABLE_1 : + NIG_REG_LLFC_ENABLE_0, llfc_enable); + REG_WR(bp, port ? NIG_REG_PAUSE_ENABLE_1 : + NIG_REG_PAUSE_ENABLE_0, pause_enable); + + REG_WR(bp, port ? NIG_REG_PPP_ENABLE_1 : + NIG_REG_PPP_ENABLE_0, ppp_enable); + + REG_WR(bp, port ? NIG_REG_LLH1_XCM_MASK : + NIG_REG_LLH0_XCM_MASK, xcm_mask); + + REG_WR(bp, NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7); + + /* output enable for RX_XCM # IF */ + REG_WR(bp, NIG_REG_XCM0_OUT_EN, xcm0_out_en); + + /* HW PFC TX enable */ + REG_WR(bp, NIG_REG_P0_HWPFC_ENABLE, p0_hwpfc_enable); + + /* 0x2 = BMAC, 0x1= EMAC */ + switch (vars->mac_type) { + case MAC_TYPE_EMAC: + val = 1; + break; + case MAC_TYPE_BMAC: + val = 0; + break; + default: + val = 0; + break; + } + REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT, val); + + if (nig_params) { + pkt_priority_to_cos = nig_params->pkt_priority_to_cos; + + REG_WR(bp, port ? NIG_REG_P1_RX_COS0_PRIORITY_MASK : + NIG_REG_P0_RX_COS0_PRIORITY_MASK, + nig_params->rx_cos0_priority_mask); + + REG_WR(bp, port ? NIG_REG_P1_RX_COS1_PRIORITY_MASK : + NIG_REG_P0_RX_COS1_PRIORITY_MASK, + nig_params->rx_cos1_priority_mask); + + REG_WR(bp, port ? NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 : + NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0, + nig_params->llfc_high_priority_classes); + + REG_WR(bp, port ? NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 : + NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0, + nig_params->llfc_low_priority_classes); + } + REG_WR(bp, port ? NIG_REG_P1_PKT_PRIORITY_TO_COS : + NIG_REG_P0_PKT_PRIORITY_TO_COS, + pkt_priority_to_cos); +} + + +void bnx2x_update_pfc(struct link_params *params, + struct link_vars *vars, + struct bnx2x_nig_brb_pfc_port_params *pfc_params) +{ + /** + * The PFC and pause are orthogonal to one another, meaning when + * PFC is enabled, the pause are disabled, and when PFC is + * disabled, pause are set according to the pause result. + */ + u32 val; + struct bnx2x *bp = params->bp; + + /* update NIG params */ + bnx2x_update_pfc_nig(params, vars, pfc_params); + + /* update BRB params */ + bnx2x_update_pfc_brb(params, vars, pfc_params); + + if (!vars->link_up) + return; + + val = REG_RD(bp, MISC_REG_RESET_REG_2); + if ((val & (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) + == 0) { + DP(NETIF_MSG_LINK, "About to update PFC in EMAC\n"); + bnx2x_emac_enable(params, vars, 0); + return; + } + + DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n"); + if (CHIP_IS_E2(bp)) + bnx2x_update_pfc_bmac2(params, vars, 0); + else + bnx2x_update_pfc_bmac1(params, vars); + + val = 0; + if ((params->feature_config_flags & + FEATURE_CONFIG_PFC_ENABLED) || + (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)) + val = 1; + REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port*4, val); +} static u8 bnx2x_bmac1_enable(struct link_params *params, struct link_vars *vars, @@ -465,15 +1063,6 @@ static u8 bnx2x_bmac1_enable(struct link_params *params, REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR, wb_data, 2); - /* tx control */ - val = 0xc0; - if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) - val |= 0x800000; - wb_data[0] = val; - wb_data[1] = 0; - REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, - wb_data, 2); - /* mac control */ val = 0x3; if (is_lb) { @@ -491,14 +1080,7 @@ static u8 bnx2x_bmac1_enable(struct link_params *params, REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE, wb_data, 2); - /* rx control set to don't strip crc */ - val = 0x14; - if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX) - val |= 0x20; - wb_data[0] = val; - wb_data[1] = 0; - REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, - wb_data, 2); + bnx2x_update_pfc_bmac1(params, vars); /* set tx mtu */ wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; @@ -595,7 +1177,7 @@ static u8 bnx2x_bmac2_enable(struct link_params *params, REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE, wb_data, 2); udelay(30); - bnx2x_update_bmac2(params, vars, is_lb); + bnx2x_update_pfc_bmac2(params, vars, is_lb); return 0; } @@ -627,7 +1209,9 @@ static u8 bnx2x_bmac_enable(struct link_params *params, REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0); REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0); val = 0; - if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) + if ((params->feature_config_flags & + FEATURE_CONFIG_PFC_ENABLED) || + (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)) val = 1; REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val); REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0); @@ -3904,7 +4488,7 @@ static u8 bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE) - return 0;; + return 0; msleep(1); } return -EINVAL; @@ -3988,7 +4572,7 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE) - return 0;; + return 0; msleep(1); } diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index 171abf8097ee..bedab1a942c4 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h @@ -65,6 +65,22 @@ #define FW_PARAM_MDIO_CTRL_OFFSET 16 #define FW_PARAM_SET(phy_addr, phy_type, mdio_access) \ (phy_addr | phy_type | mdio_access << FW_PARAM_MDIO_CTRL_OFFSET) + +#define PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_PAUSEABLE 170 +#define PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_NON_PAUSEABLE 0 + +#define PFC_BRB_MAC_PAUSE_XON_THRESHOLD_PAUSEABLE 250 +#define PFC_BRB_MAC_PAUSE_XON_THRESHOLD_NON_PAUSEABLE 0 + +#define PFC_BRB_MAC_FULL_XOFF_THRESHOLD_PAUSEABLE 10 +#define PFC_BRB_MAC_FULL_XOFF_THRESHOLD_NON_PAUSEABLE 90 + +#define PFC_BRB_MAC_FULL_XON_THRESHOLD_PAUSEABLE 50 +#define PFC_BRB_MAC_FULL_XON_THRESHOLD_NON_PAUSEABLE 250 + +#define PFC_BRB_FULL_LB_XOFF_THRESHOLD 170 +#define PFC_BRB_FULL_LB_XON_THRESHOLD 250 + /***********************************************************/ /* Structs */ /***********************************************************/ @@ -216,6 +232,7 @@ struct link_params { u32 feature_config_flags; #define FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED (1<<0) +#define FEATURE_CONFIG_PFC_ENABLED (1<<1) #define FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY (1<<2) #define FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY (1<<3) /* Will be populated during common init */ @@ -332,4 +349,43 @@ u8 bnx2x_phy_probe(struct link_params *params); u8 bnx2x_fan_failure_det_req(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base, u8 port); +/* PFC port configuration params */ +struct bnx2x_nig_brb_pfc_port_params { + /* NIG */ + u32 pause_enable; + u32 llfc_out_en; + u32 llfc_enable; + u32 pkt_priority_to_cos; + u32 rx_cos0_priority_mask; + u32 rx_cos1_priority_mask; + u32 llfc_high_priority_classes; + u32 llfc_low_priority_classes; + /* BRB */ + u32 cos0_pauseable; + u32 cos1_pauseable; +}; + +/** + * Used to update the PFC attributes in EMAC, BMAC, NIG and BRB + * when link is already up + */ +void bnx2x_update_pfc(struct link_params *params, + struct link_vars *vars, + struct bnx2x_nig_brb_pfc_port_params *pfc_params); + + +/* Used to configure the ETS to disable */ +void bnx2x_ets_disabled(struct link_params *params); + +/* Used to configure the ETS to BW limited */ +void bnx2x_ets_bw_limit(const struct link_params *params, const u32 cos0_bw, + const u32 cos1_bw); + +/* Used to configure the ETS to strict */ +u8 bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos); + +/* Read pfc statistic*/ +void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars, + u32 pfc_frames_sent[2], + u32 pfc_frames_received[2]); #endif /* BNX2X_LINK_H */ diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 9709b8569666..84e1af4d65e1 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -55,6 +55,7 @@ #include "bnx2x_init.h" #include "bnx2x_init_ops.h" #include "bnx2x_cmn.h" +#include "bnx2x_dcb.h" #include <linux/firmware.h> #include "bnx2x_fw_file_hdr.h" @@ -121,6 +122,10 @@ MODULE_PARM_DESC(debug, " Default debug msglevel"); static struct workqueue_struct *bnx2x_wq; +#ifdef BCM_CNIC +static u8 ALL_ENODE_MACS[] = {0x01, 0x10, 0x18, 0x01, 0x00, 0x01}; +#endif + enum bnx2x_board_type { BCM57710 = 0, BCM57711 = 1, @@ -921,7 +926,7 @@ void bnx2x_panic_dump(struct bnx2x *bp) sp_sb_data.p_func.vf_valid); - for_each_queue(bp, i) { + for_each_eth_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; int loop; struct hc_status_block_data_e2 sb_data_e2; @@ -961,6 +966,10 @@ void bnx2x_panic_dump(struct bnx2x *bp) /* host sb data */ +#ifdef BCM_CNIC + if (IS_FCOE_FP(fp)) + continue; +#endif BNX2X_ERR(" run indexes ("); for (j = 0; j < HC_SB_MAX_SM; j++) pr_cont("0x%x%s", @@ -1029,7 +1038,7 @@ void bnx2x_panic_dump(struct bnx2x *bp) #ifdef BNX2X_STOP_ON_ERROR /* Rings */ /* Rx */ - for_each_queue(bp, i) { + for_each_rx_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; start = RX_BD(le16_to_cpu(*fp->rx_cons_sb) - 10); @@ -1063,7 +1072,7 @@ void bnx2x_panic_dump(struct bnx2x *bp) } /* Tx */ - for_each_queue(bp, i) { + for_each_tx_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; start = TX_BD(le16_to_cpu(*fp->tx_cons_sb) - 10); @@ -1298,7 +1307,7 @@ void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw) #ifdef BCM_CNIC offset++; #endif - for_each_queue(bp, i) + for_each_eth_queue(bp, i) synchronize_irq(bp->msix_table[i + offset].vector); } else synchronize_irq(bp->pdev->irq); @@ -1420,7 +1429,7 @@ irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) return IRQ_HANDLED; #endif - for_each_queue(bp, i) { + for_each_eth_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; mask = 0x2 << (fp->index + CNIC_CONTEXT_USE); @@ -2026,13 +2035,28 @@ static int bnx2x_get_cmng_fns_mode(struct bnx2x *bp) static void bnx2x_read_mf_cfg(struct bnx2x *bp) { - int vn; + int vn, n = (CHIP_MODE_IS_4_PORT(bp) ? 2 : 1); if (BP_NOMCP(bp)) return; /* what should be the default bvalue in this case */ + /* For 2 port configuration the absolute function number formula + * is: + * abs_func = 2 * vn + BP_PORT + BP_PATH + * + * and there are 4 functions per port + * + * For 4 port configuration it is + * abs_func = 4 * vn + 2 * BP_PORT + BP_PATH + * + * and there are 2 functions per port + */ for (vn = VN_0; vn < E1HVN_MAX; vn++) { - int /*abs*/func = 2*vn + BP_PORT(bp); + int /*abs*/func = n * (2 * vn + BP_PORT(bp)) + BP_PATH(bp); + + if (func >= E1H_FUNC_MAX) + break; + bp->mf_config[vn] = MF_CFG_RD(bp, func_mf_config[func].config); } @@ -2238,6 +2262,15 @@ u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param) return rc; } +static u8 stat_counter_valid(struct bnx2x *bp, struct bnx2x_fastpath *fp) +{ +#ifdef BCM_CNIC + if (IS_FCOE_FP(fp) && IS_MF(bp)) + return false; +#endif + return true; +} + /* must be called under rtnl_lock */ static void bnx2x_rxq_set_mac_filters(struct bnx2x *bp, u16 cl_id, u32 filters) { @@ -2248,10 +2281,21 @@ static void bnx2x_rxq_set_mac_filters(struct bnx2x *bp, u16 cl_id, u32 filters) u8 accp_all_ucast = 0, accp_all_bcast = 0, accp_all_mcast = 0; u8 unmatched_unicast = 0; + if (filters & BNX2X_ACCEPT_UNMATCHED_UCAST) + unmatched_unicast = 1; + if (filters & BNX2X_PROMISCUOUS_MODE) { /* promiscious - accept all, drop none */ drop_all_ucast = drop_all_bcast = drop_all_mcast = 0; accp_all_ucast = accp_all_bcast = accp_all_mcast = 1; + if (IS_MF_SI(bp)) { + /* + * SI mode defines to accept in promiscuos mode + * only unmatched packets + */ + unmatched_unicast = 1; + accp_all_ucast = 0; + } } if (filters & BNX2X_ACCEPT_UNICAST) { /* accept matched ucast */ @@ -2260,6 +2304,11 @@ static void bnx2x_rxq_set_mac_filters(struct bnx2x *bp, u16 cl_id, u32 filters) if (filters & BNX2X_ACCEPT_MULTICAST) { /* accept matched mcast */ drop_all_mcast = 0; + if (IS_MF_SI(bp)) + /* since mcast addresses won't arrive with ovlan, + * fw needs to accept all of them in + * switch-independent mode */ + accp_all_mcast = 1; } if (filters & BNX2X_ACCEPT_ALL_UNICAST) { /* accept all mcast */ @@ -2372,7 +2421,7 @@ static inline u16 bnx2x_get_cl_flags(struct bnx2x *bp, /* calculate queue flags */ flags |= QUEUE_FLG_CACHE_ALIGN; flags |= QUEUE_FLG_HC; - flags |= IS_MF(bp) ? QUEUE_FLG_OV : 0; + flags |= IS_MF_SD(bp) ? QUEUE_FLG_OV : 0; flags |= QUEUE_FLG_VLAN; DP(NETIF_MSG_IFUP, "vlan removal enabled\n"); @@ -2380,7 +2429,8 @@ static inline u16 bnx2x_get_cl_flags(struct bnx2x *bp, if (!fp->disable_tpa) flags |= QUEUE_FLG_TPA; - flags |= QUEUE_FLG_STATS; + flags = stat_counter_valid(bp, fp) ? + (flags | QUEUE_FLG_STATS) : (flags & ~QUEUE_FLG_STATS); return flags; } @@ -2440,7 +2490,10 @@ static void bnx2x_pf_rx_cl_prep(struct bnx2x *bp, rxq_init->cache_line_log = BNX2X_RX_ALIGN_SHIFT; rxq_init->fw_sb_id = fp->fw_sb_id; - rxq_init->sb_cq_index = U_SB_ETH_RX_CQ_INDEX; + if (IS_FCOE_FP(fp)) + rxq_init->sb_cq_index = HC_SP_INDEX_ETH_FCOE_RX_CQ_CONS; + else + rxq_init->sb_cq_index = U_SB_ETH_RX_CQ_INDEX; rxq_init->cid = HW_CID(bp, fp->cid); @@ -2460,6 +2513,12 @@ static void bnx2x_pf_tx_cl_prep(struct bnx2x *bp, txq_init->sb_cq_index = C_SB_ETH_TX_CQ_INDEX; txq_init->traffic_type = LLFC_TRAFFIC_TYPE_NW; txq_init->fw_sb_id = fp->fw_sb_id; + + if (IS_FCOE_FP(fp)) { + txq_init->sb_cq_index = HC_SP_INDEX_ETH_FCOE_TX_CQ_CONS; + txq_init->traffic_type = LLFC_TRAFFIC_TYPE_FCOE; + } + txq_init->hc_rate = bp->tx_ticks ? (1000000 / bp->tx_ticks) : 0; } @@ -2573,6 +2632,26 @@ static void bnx2x_e1h_enable(struct bnx2x *bp) */ } +/* called due to MCP event (on pmf): + * reread new bandwidth configuration + * configure FW + * notify others function about the change + */ +static inline void bnx2x_config_mf_bw(struct bnx2x *bp) +{ + if (bp->link_vars.link_up) { + bnx2x_cmng_fns_init(bp, true, CMNG_FNS_MINMAX); + bnx2x_link_sync_notify(bp); + } + storm_memset_cmng(bp, &bp->cmng, BP_PORT(bp)); +} + +static inline void bnx2x_set_mf_bw(struct bnx2x *bp) +{ + bnx2x_config_mf_bw(bp); + bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW_ACK, 0); +} + static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event) { DP(BNX2X_MSG_MCP, "dcc_event 0x%x\n", dcc_event); @@ -2598,10 +2677,7 @@ static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event) dcc_event &= ~DRV_STATUS_DCC_DISABLE_ENABLE_PF; } if (dcc_event & DRV_STATUS_DCC_BANDWIDTH_ALLOCATION) { - - bnx2x_cmng_fns_init(bp, true, CMNG_FNS_MINMAX); - bnx2x_link_sync_notify(bp); - storm_memset_cmng(bp, &bp->cmng, BP_PORT(bp)); + bnx2x_config_mf_bw(bp); dcc_event &= ~DRV_STATUS_DCC_BANDWIDTH_ALLOCATION; } @@ -3022,10 +3098,20 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn) if (val & DRV_STATUS_DCC_EVENT_MASK) bnx2x_dcc_event(bp, (val & DRV_STATUS_DCC_EVENT_MASK)); + + if (val & DRV_STATUS_SET_MF_BW) + bnx2x_set_mf_bw(bp); + bnx2x__link_status_update(bp); if ((bp->port.pmf == 0) && (val & DRV_STATUS_PMF)) bnx2x_pmf_update(bp); + if (bp->port.pmf && + (val & DRV_STATUS_DCBX_NEGOTIATION_RESULTS) && + bp->dcbx_enabled > 0) + /* start dcbx state machine */ + bnx2x_dcbx_set_params(bp, + BNX2X_DCBX_STATE_NEG_RECEIVED); } else if (attn & BNX2X_MC_ASSERT_BITS) { BNX2X_ERR("MC assert!\n"); @@ -3066,7 +3152,6 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn) #define LOAD_COUNTER_MASK (((u32)0x1 << LOAD_COUNTER_BITS) - 1) #define RESET_DONE_FLAG_MASK (~LOAD_COUNTER_MASK) #define RESET_DONE_FLAG_SHIFT LOAD_COUNTER_BITS -#define CHIP_PARITY_SUPPORTED(bp) (CHIP_IS_E1(bp) || CHIP_IS_E1H(bp)) /* * should be run under rtnl lock @@ -3441,7 +3526,7 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) try to handle this event */ bnx2x_acquire_alr(bp); - if (bnx2x_chk_parity_attn(bp)) { + if (CHIP_PARITY_ENABLED(bp) && bnx2x_chk_parity_attn(bp)) { bp->recovery_state = BNX2X_RECOVERY_INIT; bnx2x_set_reset_in_progress(bp); schedule_delayed_work(&bp->reset_task, 0); @@ -3637,11 +3722,23 @@ static void bnx2x_eq_int(struct bnx2x *bp) #ifdef BCM_CNIC if (!bnx2x_cnic_handle_cfc_del(bp, cid, elem)) goto next_spqe; + if (cid == BNX2X_FCOE_ETH_CID) + bnx2x_fcoe(bp, state) = BNX2X_FP_STATE_CLOSED; + else #endif - bnx2x_fp(bp, cid, state) = + bnx2x_fp(bp, cid, state) = BNX2X_FP_STATE_CLOSED; goto next_spqe; + + case EVENT_RING_OPCODE_STOP_TRAFFIC: + DP(NETIF_MSG_IFUP, "got STOP TRAFFIC\n"); + bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_TX_PAUSED); + goto next_spqe; + case EVENT_RING_OPCODE_START_TRAFFIC: + DP(NETIF_MSG_IFUP, "got START TRAFFIC\n"); + bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_TX_RELEASED); + goto next_spqe; } switch (opcode | bp->state) { @@ -3714,7 +3811,13 @@ static void bnx2x_sp_task(struct work_struct *work) /* SP events: STAT_QUERY and others */ if (status & BNX2X_DEF_SB_IDX) { +#ifdef BCM_CNIC + struct bnx2x_fastpath *fp = bnx2x_fcoe_fp(bp); + if ((!NO_FCOE(bp)) && + (bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) + napi_schedule(&bnx2x_fcoe(bp, napi)); +#endif /* Handle EQ completions */ bnx2x_eq_int(bp); @@ -4097,7 +4200,7 @@ void bnx2x_update_coalesce(struct bnx2x *bp) { int i; - for_each_queue(bp, i) + for_each_eth_queue(bp, i) bnx2x_update_coalesce_sb(bp, bp->fp[i].fw_sb_id, bp->rx_ticks, bp->tx_ticks); } @@ -4145,13 +4248,16 @@ static void bnx2x_init_ind_table(struct bnx2x *bp) for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++) REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_INDIRECTION_TABLE_OFFSET(func) + i, - bp->fp->cl_id + (i % bp->num_queues)); + bp->fp->cl_id + (i % (bp->num_queues - + NONE_ETH_CONTEXT_USE))); } void bnx2x_set_storm_rx_mode(struct bnx2x *bp) { int mode = bp->rx_mode; + int port = BP_PORT(bp); u16 cl_id; + u32 def_q_filters = 0; /* All but management unicast packets should pass to the host as well */ u32 llh_mask = @@ -4162,30 +4268,42 @@ void bnx2x_set_storm_rx_mode(struct bnx2x *bp) switch (mode) { case BNX2X_RX_MODE_NONE: /* no Rx */ - cl_id = BP_L_ID(bp); - bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_NONE); + def_q_filters = BNX2X_ACCEPT_NONE; +#ifdef BCM_CNIC + if (!NO_FCOE(bp)) { + cl_id = bnx2x_fcoe(bp, cl_id); + bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_NONE); + } +#endif break; case BNX2X_RX_MODE_NORMAL: - cl_id = BP_L_ID(bp); - bnx2x_rxq_set_mac_filters(bp, cl_id, - BNX2X_ACCEPT_UNICAST | - BNX2X_ACCEPT_BROADCAST | - BNX2X_ACCEPT_MULTICAST); + def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST | + BNX2X_ACCEPT_MULTICAST; +#ifdef BCM_CNIC + cl_id = bnx2x_fcoe(bp, cl_id); + bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_UNICAST | + BNX2X_ACCEPT_MULTICAST); +#endif break; case BNX2X_RX_MODE_ALLMULTI: - cl_id = BP_L_ID(bp); - bnx2x_rxq_set_mac_filters(bp, cl_id, - BNX2X_ACCEPT_UNICAST | - BNX2X_ACCEPT_BROADCAST | - BNX2X_ACCEPT_ALL_MULTICAST); + def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST | + BNX2X_ACCEPT_ALL_MULTICAST; +#ifdef BCM_CNIC + cl_id = bnx2x_fcoe(bp, cl_id); + bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_UNICAST | + BNX2X_ACCEPT_MULTICAST); +#endif break; case BNX2X_RX_MODE_PROMISC: - cl_id = BP_L_ID(bp); - bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_PROMISCUOUS_MODE); - + def_q_filters |= BNX2X_PROMISCUOUS_MODE; +#ifdef BCM_CNIC + cl_id = bnx2x_fcoe(bp, cl_id); + bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_UNICAST | + BNX2X_ACCEPT_MULTICAST); +#endif /* pass management unicast packets as well */ llh_mask |= NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST; break; @@ -4195,20 +4313,24 @@ void bnx2x_set_storm_rx_mode(struct bnx2x *bp) break; } + cl_id = BP_L_ID(bp); + bnx2x_rxq_set_mac_filters(bp, cl_id, def_q_filters); + REG_WR(bp, - BP_PORT(bp) ? NIG_REG_LLH1_BRB1_DRV_MASK : - NIG_REG_LLH0_BRB1_DRV_MASK, - llh_mask); + (port ? NIG_REG_LLH1_BRB1_DRV_MASK : + NIG_REG_LLH0_BRB1_DRV_MASK), llh_mask); DP(NETIF_MSG_IFUP, "rx mode %d\n" "drop_ucast 0x%x\ndrop_mcast 0x%x\ndrop_bcast 0x%x\n" - "accp_ucast 0x%x\naccp_mcast 0x%x\naccp_bcast 0x%x\n", mode, + "accp_ucast 0x%x\naccp_mcast 0x%x\naccp_bcast 0x%x\n" + "unmatched_ucast 0x%x\n", mode, bp->mac_filters.ucast_drop_all, bp->mac_filters.mcast_drop_all, bp->mac_filters.bcast_drop_all, bp->mac_filters.ucast_accept_all, bp->mac_filters.mcast_accept_all, - bp->mac_filters.bcast_accept_all + bp->mac_filters.bcast_accept_all, + bp->mac_filters.unmatched_unicast ); storm_memset_mac_filters(bp, &bp->mac_filters, BP_FUNC(bp)); @@ -4232,6 +4354,15 @@ static void bnx2x_init_internal_common(struct bnx2x *bp) bp->mf_mode); } + if (IS_MF_SI(bp)) + /* + * In switch independent mode, the TSTORM needs to accept + * packets that failed classification, since approximate match + * mac addresses aren't written to NIG LLH + */ + REG_WR8(bp, BAR_TSTRORM_INTMEM + + TSTORM_ACCEPT_CLASSIFY_FAILED_OFFSET, 2); + /* Zero this manually as its initialization is currently missing in the initTool */ for (i = 0; i < (USTORM_AGG_DATA_SIZE >> 2); i++) @@ -4247,6 +4378,7 @@ static void bnx2x_init_internal_common(struct bnx2x *bp) static void bnx2x_init_internal_port(struct bnx2x *bp) { /* port */ + bnx2x_dcb_init_intmem_pfc(bp); } static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code) @@ -4308,9 +4440,11 @@ void bnx2x_nic_init(struct bnx2x *bp, u32 load_code) { int i; - for_each_queue(bp, i) + for_each_eth_queue(bp, i) bnx2x_init_fp_sb(bp, i); #ifdef BCM_CNIC + if (!NO_FCOE(bp)) + bnx2x_init_fcoe_fp(bp); bnx2x_init_sb(bp, bp->cnic_sb_mapping, BNX2X_VF_ID_INVALID, false, @@ -4619,7 +4753,7 @@ static int bnx2x_int_mem_test(struct bnx2x *bp) return 0; /* OK */ } -static void enable_blocks_attention(struct bnx2x *bp) +static void bnx2x_enable_blocks_attention(struct bnx2x *bp) { REG_WR(bp, PXP_REG_PXP_INT_MASK_0, 0); if (CHIP_IS_E2(bp)) @@ -4673,53 +4807,9 @@ static void enable_blocks_attention(struct bnx2x *bp) REG_WR(bp, CDU_REG_CDU_INT_MASK, 0); REG_WR(bp, DMAE_REG_DMAE_INT_MASK, 0); /* REG_WR(bp, MISC_REG_MISC_INT_MASK, 0); */ - REG_WR(bp, PBF_REG_PBF_INT_MASK, 0X18); /* bit 3,4 masked */ -} - -static const struct { - u32 addr; - u32 mask; -} bnx2x_parity_mask[] = { - {PXP_REG_PXP_PRTY_MASK, 0x3ffffff}, - {PXP2_REG_PXP2_PRTY_MASK_0, 0xffffffff}, - {PXP2_REG_PXP2_PRTY_MASK_1, 0x7f}, - {HC_REG_HC_PRTY_MASK, 0x7}, - {MISC_REG_MISC_PRTY_MASK, 0x1}, - {QM_REG_QM_PRTY_MASK, 0x0}, - {DORQ_REG_DORQ_PRTY_MASK, 0x0}, - {GRCBASE_UPB + PB_REG_PB_PRTY_MASK, 0x0}, - {GRCBASE_XPB + PB_REG_PB_PRTY_MASK, 0x0}, - {SRC_REG_SRC_PRTY_MASK, 0x4}, /* bit 2 */ - {CDU_REG_CDU_PRTY_MASK, 0x0}, - {CFC_REG_CFC_PRTY_MASK, 0x0}, - {DBG_REG_DBG_PRTY_MASK, 0x0}, - {DMAE_REG_DMAE_PRTY_MASK, 0x0}, - {BRB1_REG_BRB1_PRTY_MASK, 0x0}, - {PRS_REG_PRS_PRTY_MASK, (1<<6)},/* bit 6 */ - {TSDM_REG_TSDM_PRTY_MASK, 0x18}, /* bit 3,4 */ - {CSDM_REG_CSDM_PRTY_MASK, 0x8}, /* bit 3 */ - {USDM_REG_USDM_PRTY_MASK, 0x38}, /* bit 3,4,5 */ - {XSDM_REG_XSDM_PRTY_MASK, 0x8}, /* bit 3 */ - {TSEM_REG_TSEM_PRTY_MASK_0, 0x0}, - {TSEM_REG_TSEM_PRTY_MASK_1, 0x0}, - {USEM_REG_USEM_PRTY_MASK_0, 0x0}, - {USEM_REG_USEM_PRTY_MASK_1, 0x0}, - {CSEM_REG_CSEM_PRTY_MASK_0, 0x0}, - {CSEM_REG_CSEM_PRTY_MASK_1, 0x0}, - {XSEM_REG_XSEM_PRTY_MASK_0, 0x0}, - {XSEM_REG_XSEM_PRTY_MASK_1, 0x0} -}; - -static void enable_blocks_parity(struct bnx2x *bp) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(bnx2x_parity_mask); i++) - REG_WR(bp, bnx2x_parity_mask[i].addr, - bnx2x_parity_mask[i].mask); + REG_WR(bp, PBF_REG_PBF_INT_MASK, 0x18); /* bit 3,4 masked */ } - static void bnx2x_reset_common(struct bnx2x *bp) { /* reset_common */ @@ -5048,12 +5138,12 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) REG_WR(bp, PRS_REG_NIC_MODE, 1); #endif if (!CHIP_IS_E1(bp)) - REG_WR(bp, PRS_REG_E1HOV_MODE, IS_MF(bp)); + REG_WR(bp, PRS_REG_E1HOV_MODE, IS_MF_SD(bp)); if (CHIP_IS_E2(bp)) { /* Bit-map indicating which L2 hdrs may appear after the basic Ethernet header */ - int has_ovlan = IS_MF(bp); + int has_ovlan = IS_MF_SD(bp); REG_WR(bp, PRS_REG_HDRS_AFTER_BASIC, (has_ovlan ? 7 : 6)); REG_WR(bp, PRS_REG_MUST_HAVE_HDRS, (has_ovlan ? 1 : 0)); } @@ -5087,7 +5177,7 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) bnx2x_init_block(bp, PBF_BLOCK, COMMON_STAGE); if (CHIP_IS_E2(bp)) { - int has_ovlan = IS_MF(bp); + int has_ovlan = IS_MF_SD(bp); REG_WR(bp, PBF_REG_HDRS_AFTER_BASIC, (has_ovlan ? 7 : 6)); REG_WR(bp, PBF_REG_MUST_HAVE_HDRS, (has_ovlan ? 1 : 0)); } @@ -5164,12 +5254,12 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) bnx2x_init_block(bp, NIG_BLOCK, COMMON_STAGE); if (!CHIP_IS_E1(bp)) { REG_WR(bp, NIG_REG_LLH_MF_MODE, IS_MF(bp)); - REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_MF(bp)); + REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_MF_SD(bp)); } if (CHIP_IS_E2(bp)) { /* Bit-map indicating which L2 hdrs may appear after the basic Ethernet header */ - REG_WR(bp, NIG_REG_P0_HDRS_AFTER_BASIC, (IS_MF(bp) ? 7 : 6)); + REG_WR(bp, NIG_REG_P0_HDRS_AFTER_BASIC, (IS_MF_SD(bp) ? 7 : 6)); } if (CHIP_REV_IS_SLOW(bp)) @@ -5215,9 +5305,9 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) /* clear PXP2 attentions */ REG_RD(bp, PXP2_REG_PXP2_INT_STS_CLR_0); - enable_blocks_attention(bp); - if (CHIP_PARITY_SUPPORTED(bp)) - enable_blocks_parity(bp); + bnx2x_enable_blocks_attention(bp); + if (CHIP_PARITY_ENABLED(bp)) + bnx2x_enable_blocks_parity(bp); if (!BP_NOMCP(bp)) { /* In E2 2-PORT mode, same ext phy is used for the two paths */ @@ -5370,8 +5460,10 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) * - SF mode: bits 3-7 are masked. only bits 0-2 are in use * - MF mode: bit 3 is masked. bits 0-2 are in use as in SF * bits 4-7 are used for "per vn group attention" */ - REG_WR(bp, MISC_REG_AEU_MASK_ATTN_FUNC_0 + port*4, - (IS_MF(bp) ? 0xF7 : 0x7)); + val = IS_MF(bp) ? 0xF7 : 0x7; + /* Enable DCBX attention for all but E1 */ + val |= CHIP_IS_E1(bp) ? 0 : 0x10; + REG_WR(bp, MISC_REG_AEU_MASK_ATTN_FUNC_0 + port*4, val); bnx2x_init_block(bp, PXPCS_BLOCK, init_stage); bnx2x_init_block(bp, EMAC0_BLOCK, init_stage); @@ -5386,7 +5478,7 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) if (!CHIP_IS_E1(bp)) { /* 0x2 disable mf_ov, 0x1 enable */ REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK_MF + port*4, - (IS_MF(bp) ? 0x1 : 0x2)); + (IS_MF_SD(bp) ? 0x1 : 0x2)); if (CHIP_IS_E2(bp)) { val = 0; @@ -5816,6 +5908,15 @@ void bnx2x_free_mem(struct bnx2x *bp) /* fastpath */ /* Common */ for_each_queue(bp, i) { +#ifdef BCM_CNIC + /* FCoE client uses default status block */ + if (IS_FCOE_IDX(i)) { + union host_hc_status_block *sb = + &bnx2x_fp(bp, i, status_blk); + memset(sb, 0, sizeof(union host_hc_status_block)); + bnx2x_fp(bp, i, status_blk_mapping) = 0; + } else { +#endif /* status blocks */ if (CHIP_IS_E2(bp)) BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk.e2_sb), @@ -5825,9 +5926,12 @@ void bnx2x_free_mem(struct bnx2x *bp) BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk.e1x_sb), bnx2x_fp(bp, i, status_blk_mapping), sizeof(struct host_hc_status_block_e1x)); +#ifdef BCM_CNIC + } +#endif } /* Rx */ - for_each_queue(bp, i) { + for_each_rx_queue(bp, i) { /* fastpath rx rings: rx_buf rx_desc rx_comp */ BNX2X_FREE(bnx2x_fp(bp, i, rx_buf_ring)); @@ -5847,7 +5951,7 @@ void bnx2x_free_mem(struct bnx2x *bp) BCM_PAGE_SIZE * NUM_RX_SGE_PAGES); } /* Tx */ - for_each_queue(bp, i) { + for_each_tx_queue(bp, i) { /* fastpath tx rings: tx_buf tx_desc */ BNX2X_FREE(bnx2x_fp(bp, i, tx_buf_ring)); @@ -5931,15 +6035,20 @@ int bnx2x_alloc_mem(struct bnx2x *bp) union host_hc_status_block *sb = &bnx2x_fp(bp, i, status_blk); bnx2x_fp(bp, i, bp) = bp; /* status blocks */ - if (CHIP_IS_E2(bp)) - BNX2X_PCI_ALLOC(sb->e2_sb, - &bnx2x_fp(bp, i, status_blk_mapping), - sizeof(struct host_hc_status_block_e2)); - else - BNX2X_PCI_ALLOC(sb->e1x_sb, - &bnx2x_fp(bp, i, status_blk_mapping), - sizeof(struct host_hc_status_block_e1x)); - +#ifdef BCM_CNIC + if (!IS_FCOE_IDX(i)) { +#endif + if (CHIP_IS_E2(bp)) + BNX2X_PCI_ALLOC(sb->e2_sb, + &bnx2x_fp(bp, i, status_blk_mapping), + sizeof(struct host_hc_status_block_e2)); + else + BNX2X_PCI_ALLOC(sb->e1x_sb, + &bnx2x_fp(bp, i, status_blk_mapping), + sizeof(struct host_hc_status_block_e1x)); +#ifdef BCM_CNIC + } +#endif set_sb_shortcuts(bp, i); } /* Rx */ @@ -6055,7 +6164,7 @@ static int bnx2x_func_stop(struct bnx2x *bp) * @param cam_offset offset in a CAM to use * @param is_bcast is the set MAC a broadcast address (for E1 only) */ -static void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, u8 *mac, +static void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, const u8 *mac, u32 cl_bit_vec, u8 cam_offset, u8 is_bcast) { @@ -6170,6 +6279,70 @@ static u8 bnx2x_e1h_cam_offset(struct bnx2x *bp, u8 rel_offset) return BP_VN(bp) * 32 + rel_offset; } +/** + * LLH CAM line allocations: currently only iSCSI and ETH macs are + * relevant. In addition, current implementation is tuned for a + * single ETH MAC. + * + * When multiple unicast ETH MACs PF configuration in switch + * independent mode is required (NetQ, multiple netdev MACs, + * etc.), consider better utilisation of 16 per function MAC + * entries in the LLH memory. + */ +enum { + LLH_CAM_ISCSI_ETH_LINE = 0, + LLH_CAM_ETH_LINE, + LLH_CAM_MAX_PF_LINE = NIG_REG_LLH1_FUNC_MEM_SIZE +}; + +static void bnx2x_set_mac_in_nig(struct bnx2x *bp, + int set, + unsigned char *dev_addr, + int index) +{ + u32 wb_data[2]; + u32 mem_offset, ena_offset, mem_index; + /** + * indexes mapping: + * 0..7 - goes to MEM + * 8..15 - goes to MEM2 + */ + + if (!IS_MF_SI(bp) || index > LLH_CAM_MAX_PF_LINE) + return; + + /* calculate memory start offset according to the mapping + * and index in the memory */ + if (index < NIG_LLH_FUNC_MEM_MAX_OFFSET) { + mem_offset = BP_PORT(bp) ? NIG_REG_LLH1_FUNC_MEM : + NIG_REG_LLH0_FUNC_MEM; + ena_offset = BP_PORT(bp) ? NIG_REG_LLH1_FUNC_MEM_ENABLE : + NIG_REG_LLH0_FUNC_MEM_ENABLE; + mem_index = index; + } else { + mem_offset = BP_PORT(bp) ? NIG_REG_P1_LLH_FUNC_MEM2 : + NIG_REG_P0_LLH_FUNC_MEM2; + ena_offset = BP_PORT(bp) ? NIG_REG_P1_LLH_FUNC_MEM2_ENABLE : + NIG_REG_P0_LLH_FUNC_MEM2_ENABLE; + mem_index = index - NIG_LLH_FUNC_MEM_MAX_OFFSET; + } + + if (set) { + /* LLH_FUNC_MEM is a u64 WB register */ + mem_offset += 8*mem_index; + + wb_data[0] = ((dev_addr[2] << 24) | (dev_addr[3] << 16) | + (dev_addr[4] << 8) | dev_addr[5]); + wb_data[1] = ((dev_addr[0] << 8) | dev_addr[1]); + + REG_WR_DMAE(bp, mem_offset, wb_data, 2); + } + + /* enable/disable the entry */ + REG_WR(bp, ena_offset + 4*mem_index, set); + +} + void bnx2x_set_eth_mac(struct bnx2x *bp, int set) { u8 cam_offset = (CHIP_IS_E1(bp) ? (BP_PORT(bp) ? 32 : 0) : @@ -6179,9 +6352,13 @@ void bnx2x_set_eth_mac(struct bnx2x *bp, int set) bnx2x_set_mac_addr_gen(bp, set, bp->dev->dev_addr, (1 << bp->fp->cl_id), cam_offset , 0); + bnx2x_set_mac_in_nig(bp, set, bp->dev->dev_addr, LLH_CAM_ETH_LINE); + if (CHIP_IS_E1(bp)) { /* broadcast MAC */ - u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + static const u8 bcast[ETH_ALEN] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; bnx2x_set_mac_addr_gen(bp, set, bcast, 0, cam_offset + 1, 1); } } @@ -6283,12 +6460,59 @@ static int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp, int set) { u8 cam_offset = (CHIP_IS_E1(bp) ? ((BP_PORT(bp) ? 32 : 0) + 2) : bnx2x_e1h_cam_offset(bp, CAM_ISCSI_ETH_LINE)); - u32 iscsi_l2_cl_id = BNX2X_ISCSI_ETH_CL_ID; + u32 iscsi_l2_cl_id = BNX2X_ISCSI_ETH_CL_ID + + BP_E1HVN(bp) * NONE_ETH_CONTEXT_USE; u32 cl_bit_vec = (1 << iscsi_l2_cl_id); /* Send a SET_MAC ramrod */ bnx2x_set_mac_addr_gen(bp, set, bp->iscsi_mac, cl_bit_vec, cam_offset, 0); + + bnx2x_set_mac_in_nig(bp, set, bp->iscsi_mac, LLH_CAM_ISCSI_ETH_LINE); + + return 0; +} + +/** + * Set FCoE L2 MAC(s) at the next enties in the CAM after the + * ETH MAC(s). This function will wait until the ramdord + * completion returns. + * + * @param bp driver handle + * @param set set or clear the CAM entry + * + * @return 0 if cussess, -ENODEV if ramrod doesn't return. + */ +int bnx2x_set_fip_eth_mac_addr(struct bnx2x *bp, int set) +{ + u32 cl_bit_vec = (1 << bnx2x_fcoe(bp, cl_id)); + /** + * CAM allocation for E1H + * eth unicasts: by func number + * iscsi: by func number + * fip unicast: by func number + * fip multicast: by func number + */ + bnx2x_set_mac_addr_gen(bp, set, bp->fip_mac, + cl_bit_vec, bnx2x_e1h_cam_offset(bp, CAM_FIP_ETH_LINE), 0); + + return 0; +} + +int bnx2x_set_all_enode_macs(struct bnx2x *bp, int set) +{ + u32 cl_bit_vec = (1 << bnx2x_fcoe(bp, cl_id)); + + /** + * CAM allocation for E1H + * eth unicasts: by func number + * iscsi: by func number + * fip unicast: by func number + * fip multicast: by func number + */ + bnx2x_set_mac_addr_gen(bp, set, ALL_ENODE_MACS, cl_bit_vec, + bnx2x_e1h_cam_offset(bp, CAM_FIP_MCAST_LINE), 0); + return 0; } #endif @@ -6306,6 +6530,8 @@ static void bnx2x_fill_cl_init_data(struct bnx2x *bp, data->general.statistics_counter_id = params->rxq_params.stat_id; data->general.statistics_en_flg = (params->rxq_params.flags & QUEUE_FLG_STATS) ? 1 : 0; + data->general.is_fcoe_flg = + (params->ramrod_params.flags & CLIENT_IS_FCOE) ? 1 : 0; data->general.activate_flg = activate; data->general.sp_client_id = params->rxq_params.spcl_id; @@ -6374,7 +6600,9 @@ static void bnx2x_fill_cl_init_data(struct bnx2x *bp, data->fc.safc_group_num = params->txq_params.cos; data->fc.safc_group_en_flg = (params->txq_params.flags & QUEUE_FLG_COS) ? 1 : 0; - data->fc.traffic_type = LLFC_TRAFFIC_TYPE_NW; + data->fc.traffic_type = + (params->ramrod_params.flags & CLIENT_IS_FCOE) ? + LLFC_TRAFFIC_TYPE_FCOE : LLFC_TRAFFIC_TYPE_NW; } static inline void bnx2x_set_ctx_validation(struct eth_context *cxt, u32 cid) @@ -6473,7 +6701,7 @@ static int __devinit bnx2x_set_int_mode(struct bnx2x *bp) bnx2x_enable_msi(bp); /* falling through... */ case INT_MODE_INTx: - bp->num_queues = 1; + bp->num_queues = 1 + NONE_ETH_CONTEXT_USE; DP(NETIF_MSG_IFUP, "set number of queues to 1\n"); break; default: @@ -6496,8 +6724,8 @@ static int __devinit bnx2x_set_int_mode(struct bnx2x *bp) "enable MSI-X (%d), " "set number of queues to %d\n", bp->num_queues, - 1); - bp->num_queues = 1; + 1 + NONE_ETH_CONTEXT_USE); + bp->num_queues = 1 + NONE_ETH_CONTEXT_USE; if (!(bp->flags & DISABLE_MSI_FLAG)) bnx2x_enable_msi(bp); @@ -6618,7 +6846,9 @@ int bnx2x_setup_client(struct bnx2x *bp, struct bnx2x_fastpath *fp, struct bnx2x_client_init_params params = { {0} }; int rc; - bnx2x_ack_sb(bp, fp->igu_sb_id, USTORM_ID, 0, + /* reset IGU state skip FCoE L2 queue */ + if (!IS_FCOE_FP(fp)) + bnx2x_ack_sb(bp, fp->igu_sb_id, USTORM_ID, 0, IGU_INT_ENABLE, 0); params.ramrod_params.pstate = &fp->state; @@ -6626,6 +6856,12 @@ int bnx2x_setup_client(struct bnx2x *bp, struct bnx2x_fastpath *fp, params.ramrod_params.index = fp->index; params.ramrod_params.cid = fp->cid; +#ifdef BCM_CNIC + if (IS_FCOE_FP(fp)) + params.ramrod_params.flags |= CLIENT_IS_FCOE; + +#endif + if (is_leading) params.ramrod_params.flags |= CLIENT_IS_LEADING_RSS; @@ -6710,7 +6946,7 @@ static void bnx2x_reset_func(struct bnx2x *bp) REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_FUNC_EN_OFFSET(func), 0); /* FP SBs */ - for_each_queue(bp, i) { + for_each_eth_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; REG_WR8(bp, BAR_CSTRORM_INTMEM + @@ -6830,6 +7066,20 @@ static void bnx2x_reset_chip(struct bnx2x *bp, u32 reset_code) } } +#ifdef BCM_CNIC +static inline void bnx2x_del_fcoe_eth_macs(struct bnx2x *bp) +{ + if (bp->flags & FCOE_MACS_SET) { + if (!IS_MF_SD(bp)) + bnx2x_set_fip_eth_mac_addr(bp, 0); + + bnx2x_set_all_enode_macs(bp, 0); + + bp->flags &= ~FCOE_MACS_SET; + } +} +#endif + void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) { int port = BP_PORT(bp); @@ -6837,7 +7087,7 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) int i, cnt, rc; /* Wait until tx fastpath tasks complete */ - for_each_queue(bp, i) { + for_each_tx_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; cnt = 1000; @@ -6877,13 +7127,7 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) } #ifdef BCM_CNIC - /* Clear iSCSI L2 MAC */ - mutex_lock(&bp->cnic_mutex); - if (bp->cnic_flags & BNX2X_CNIC_FLAG_MAC_SET) { - bnx2x_set_iscsi_eth_mac_addr(bp, 0); - bp->cnic_flags &= ~BNX2X_CNIC_FLAG_MAC_SET; - } - mutex_unlock(&bp->cnic_mutex); + bnx2x_del_fcoe_eth_macs(bp); #endif if (unload_mode == UNLOAD_NORMAL) @@ -7736,7 +7980,7 @@ static void __devinit bnx2x_get_igu_cam_info(struct bnx2x *bp) bp->igu_sb_cnt = 0; if (CHIP_INT_MODE_IS_BC(bp)) { bp->igu_sb_cnt = min_t(u8, FP_SB_MAX_E1x, - bp->l2_cid_count); + NUM_IGU_SB_REQUIRED(bp->l2_cid_count)); bp->igu_base_sb = (CHIP_MODE_IS_4_PORT(bp) ? pfid : vn) * FP_SB_MAX_E1x; @@ -7767,7 +8011,8 @@ static void __devinit bnx2x_get_igu_cam_info(struct bnx2x *bp) } } } - bp->igu_sb_cnt = min_t(u8, bp->igu_sb_cnt, bp->l2_cid_count); + bp->igu_sb_cnt = min_t(u8, bp->igu_sb_cnt, + NUM_IGU_SB_REQUIRED(bp->l2_cid_count)); if (bp->igu_sb_cnt == 0) BNX2X_ERR("CAM configuration error\n"); } @@ -8076,9 +8321,8 @@ static void __devinit bnx2x_set_mac_buf(u8 *mac_buf, u32 mac_lo, u16 mac_hi) static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) { int port = BP_PORT(bp); - u32 val, val2; u32 config; - u32 ext_phy_type, ext_phy_config;; + u32 ext_phy_type, ext_phy_config; bp->link_params.bp = bp; bp->link_params.port = port; @@ -8135,25 +8379,73 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) bp->mdio.prtad = XGXS_EXT_PHY_ADDR(ext_phy_config); +} + +static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp) +{ + u32 val, val2; + int func = BP_ABS_FUNC(bp); + int port = BP_PORT(bp); + + if (BP_NOMCP(bp)) { + BNX2X_ERROR("warning: random MAC workaround active\n"); + random_ether_addr(bp->dev->dev_addr); + } else if (IS_MF(bp)) { + val2 = MF_CFG_RD(bp, func_mf_config[func].mac_upper); + val = MF_CFG_RD(bp, func_mf_config[func].mac_lower); + if ((val2 != FUNC_MF_CFG_UPPERMAC_DEFAULT) && + (val != FUNC_MF_CFG_LOWERMAC_DEFAULT)) + bnx2x_set_mac_buf(bp->dev->dev_addr, val, val2); + +#ifdef BCM_CNIC + /* iSCSI NPAR MAC */ + if (IS_MF_SI(bp)) { + u32 cfg = MF_CFG_RD(bp, func_ext_config[func].func_cfg); + if (cfg & MACP_FUNC_CFG_FLAGS_ISCSI_OFFLOAD) { + val2 = MF_CFG_RD(bp, func_ext_config[func]. + iscsi_mac_addr_upper); + val = MF_CFG_RD(bp, func_ext_config[func]. + iscsi_mac_addr_lower); + bnx2x_set_mac_buf(bp->iscsi_mac, val, val2); + } + } +#endif + } else { + /* in SF read MACs from port configuration */ + val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper); + val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower); + bnx2x_set_mac_buf(bp->dev->dev_addr, val, val2); + +#ifdef BCM_CNIC + val2 = SHMEM_RD(bp, dev_info.port_hw_config[port]. + iscsi_mac_upper); + val = SHMEM_RD(bp, dev_info.port_hw_config[port]. + iscsi_mac_lower); + bnx2x_set_mac_buf(bp->iscsi_mac, val, val2); +#endif + } - val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper); - val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower); - bnx2x_set_mac_buf(bp->dev->dev_addr, val, val2); memcpy(bp->link_params.mac_addr, bp->dev->dev_addr, ETH_ALEN); memcpy(bp->dev->perm_addr, bp->dev->dev_addr, ETH_ALEN); #ifdef BCM_CNIC - val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].iscsi_mac_upper); - val = SHMEM_RD(bp, dev_info.port_hw_config[port].iscsi_mac_lower); - bnx2x_set_mac_buf(bp->iscsi_mac, val, val2); + /* Inform the upper layers about FCoE MAC */ + if (!CHIP_IS_E1x(bp)) { + if (IS_MF_SD(bp)) + memcpy(bp->fip_mac, bp->dev->dev_addr, + sizeof(bp->fip_mac)); + else + memcpy(bp->fip_mac, bp->iscsi_mac, + sizeof(bp->fip_mac)); + } #endif } static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) { - int func = BP_ABS_FUNC(bp); - int vn; - u32 val, val2; + int /*abs*/func = BP_ABS_FUNC(bp); + int vn, port; + u32 val = 0; int rc = 0; bnx2x_get_common_hwinfo(bp); @@ -8163,7 +8455,8 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) bp->igu_dsb_id = DEF_SB_IGU_ID; bp->igu_base_sb = 0; - bp->igu_sb_cnt = min_t(u8, FP_SB_MAX_E1x, bp->l2_cid_count); + bp->igu_sb_cnt = min_t(u8, FP_SB_MAX_E1x, + NUM_IGU_SB_REQUIRED(bp->l2_cid_count)); } else { bp->common.int_block = INT_BLOCK_IGU; val = REG_RD(bp, IGU_REG_BLOCK_CONFIGURATION); @@ -8186,44 +8479,99 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) bp->mf_ov = 0; bp->mf_mode = 0; vn = BP_E1HVN(bp); + port = BP_PORT(bp); + if (!CHIP_IS_E1(bp) && !BP_NOMCP(bp)) { + DP(NETIF_MSG_PROBE, + "shmem2base 0x%x, size %d, mfcfg offset %d\n", + bp->common.shmem2_base, SHMEM2_RD(bp, size), + (u32)offsetof(struct shmem2_region, mf_cfg_addr)); if (SHMEM2_HAS(bp, mf_cfg_addr)) bp->common.mf_cfg_base = SHMEM2_RD(bp, mf_cfg_addr); else bp->common.mf_cfg_base = bp->common.shmem_base + offsetof(struct shmem_region, func_mb) + E1H_FUNC_MAX * sizeof(struct drv_func_mb); - bp->mf_config[vn] = - MF_CFG_RD(bp, func_mf_config[func].config); + /* + * get mf configuration: + * 1. existance of MF configuration + * 2. MAC address must be legal (check only upper bytes) + * for Switch-Independent mode; + * OVLAN must be legal for Switch-Dependent mode + * 3. SF_MODE configures specific MF mode + */ + if (bp->common.mf_cfg_base != SHMEM_MF_CFG_ADDR_NONE) { + /* get mf configuration */ + val = SHMEM_RD(bp, + dev_info.shared_feature_config.config); + val &= SHARED_FEAT_CFG_FORCE_SF_MODE_MASK; + + switch (val) { + case SHARED_FEAT_CFG_FORCE_SF_MODE_SWITCH_INDEPT: + val = MF_CFG_RD(bp, func_mf_config[func]. + mac_upper); + /* check for legal mac (upper bytes)*/ + if (val != 0xffff) { + bp->mf_mode = MULTI_FUNCTION_SI; + bp->mf_config[vn] = MF_CFG_RD(bp, + func_mf_config[func].config); + } else + DP(NETIF_MSG_PROBE, "illegal MAC " + "address for SI\n"); + break; + case SHARED_FEAT_CFG_FORCE_SF_MODE_MF_ALLOWED: + /* get OV configuration */ + val = MF_CFG_RD(bp, + func_mf_config[FUNC_0].e1hov_tag); + val &= FUNC_MF_CFG_E1HOV_TAG_MASK; + + if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) { + bp->mf_mode = MULTI_FUNCTION_SD; + bp->mf_config[vn] = MF_CFG_RD(bp, + func_mf_config[func].config); + } else + DP(NETIF_MSG_PROBE, "illegal OV for " + "SD\n"); + break; + default: + /* Unknown configuration: reset mf_config */ + bp->mf_config[vn] = 0; + DP(NETIF_MSG_PROBE, "Unkown MF mode 0x%x\n", + val); + } + } - val = (MF_CFG_RD(bp, func_mf_config[FUNC_0].e1hov_tag) & - FUNC_MF_CFG_E1HOV_TAG_MASK); - if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) - bp->mf_mode = 1; BNX2X_DEV_INFO("%s function mode\n", IS_MF(bp) ? "multi" : "single"); - if (IS_MF(bp)) { - val = (MF_CFG_RD(bp, func_mf_config[func]. - e1hov_tag) & - FUNC_MF_CFG_E1HOV_TAG_MASK); + switch (bp->mf_mode) { + case MULTI_FUNCTION_SD: + val = MF_CFG_RD(bp, func_mf_config[func].e1hov_tag) & + FUNC_MF_CFG_E1HOV_TAG_MASK; if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) { bp->mf_ov = val; - BNX2X_DEV_INFO("MF OV for func %d is %d " - "(0x%04x)\n", - func, bp->mf_ov, bp->mf_ov); + BNX2X_DEV_INFO("MF OV for func %d is %d" + " (0x%04x)\n", func, + bp->mf_ov, bp->mf_ov); } else { - BNX2X_ERROR("No valid MF OV for func %d," - " aborting\n", func); + BNX2X_ERR("No valid MF OV for func %d," + " aborting\n", func); rc = -EPERM; } - } else { - if (BP_VN(bp)) { - BNX2X_ERROR("VN %d in single function mode," - " aborting\n", BP_E1HVN(bp)); + break; + case MULTI_FUNCTION_SI: + BNX2X_DEV_INFO("func %d is in MF " + "switch-independent mode\n", func); + break; + default: + if (vn) { + BNX2X_ERR("VN %d in single function mode," + " aborting\n", vn); rc = -EPERM; } + break; } + } /* adjust igu_sb_cnt to MF for E1x */ @@ -8248,32 +8596,8 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq); } - if (IS_MF(bp)) { - val2 = MF_CFG_RD(bp, func_mf_config[func].mac_upper); - val = MF_CFG_RD(bp, func_mf_config[func].mac_lower); - if ((val2 != FUNC_MF_CFG_UPPERMAC_DEFAULT) && - (val != FUNC_MF_CFG_LOWERMAC_DEFAULT)) { - bp->dev->dev_addr[0] = (u8)(val2 >> 8 & 0xff); - bp->dev->dev_addr[1] = (u8)(val2 & 0xff); - bp->dev->dev_addr[2] = (u8)(val >> 24 & 0xff); - bp->dev->dev_addr[3] = (u8)(val >> 16 & 0xff); - bp->dev->dev_addr[4] = (u8)(val >> 8 & 0xff); - bp->dev->dev_addr[5] = (u8)(val & 0xff); - memcpy(bp->link_params.mac_addr, bp->dev->dev_addr, - ETH_ALEN); - memcpy(bp->dev->perm_addr, bp->dev->dev_addr, - ETH_ALEN); - } - - return rc; - } - - if (BP_NOMCP(bp)) { - /* only supposed to happen on emulation/FPGA */ - BNX2X_ERROR("warning: random MAC workaround active\n"); - random_ether_addr(bp->dev->dev_addr); - memcpy(bp->dev->perm_addr, bp->dev->dev_addr, ETH_ALEN); - } + /* Get MAC addresses */ + bnx2x_get_mac_hwinfo(bp); return rc; } @@ -8382,13 +8706,6 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) dev_err(&bp->pdev->dev, "MCP disabled, " "must load devices in order!\n"); - /* Set multi queue mode */ - if ((multi_mode != ETH_RSS_MODE_DISABLED) && - ((int_mode == INT_MODE_INTx) || (int_mode == INT_MODE_MSI))) { - dev_err(&bp->pdev->dev, "Multi disabled since int_mode " - "requested is not MSI-X\n"); - multi_mode = ETH_RSS_MODE_DISABLED; - } bp->multi_mode = multi_mode; bp->int_mode = int_mode; @@ -8427,6 +8744,9 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) bp->timer.data = (unsigned long) bp; bp->timer.function = bnx2x_timer; + bnx2x_dcbx_set_state(bp, true, BNX2X_DCBX_ENABLED_ON_NEG_ON); + bnx2x_dcbx_init_params(bp); + return rc; } @@ -8629,6 +8949,7 @@ static const struct net_device_ops bnx2x_netdev_ops = { .ndo_open = bnx2x_open, .ndo_stop = bnx2x_close, .ndo_start_xmit = bnx2x_start_xmit, + .ndo_select_queue = bnx2x_select_queue, .ndo_set_multicast_list = bnx2x_set_rx_mode, .ndo_set_mac_address = bnx2x_change_mac_addr, .ndo_validate_addr = eth_validate_addr, @@ -8761,7 +9082,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, dev->netdev_ops = &bnx2x_netdev_ops; bnx2x_set_ethtool_ops(dev); dev->features |= NETIF_F_SG; - dev->features |= NETIF_F_HW_CSUM; + dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; if (bp->flags & USING_DAC_FLAG) dev->features |= NETIF_F_HIGHDMA; dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN); @@ -8769,12 +9090,16 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, dev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX); dev->vlan_features |= NETIF_F_SG; - dev->vlan_features |= NETIF_F_HW_CSUM; + dev->vlan_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; if (bp->flags & USING_DAC_FLAG) dev->vlan_features |= NETIF_F_HIGHDMA; dev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO_ECN); dev->vlan_features |= NETIF_F_TSO6; +#ifdef BCM_DCB + dev->dcbnl_ops = &bnx2x_dcbnl_ops; +#endif + /* get_port_hwinfo() will set prtad and mmds properly */ bp->mdio.prtad = MDIO_PRTAD_NONE; bp->mdio.mmds = 0; @@ -9067,7 +9392,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, return -ENODEV; } - cid_count += CNIC_CONTEXT_USE; + cid_count += NONE_ETH_CONTEXT_USE + CNIC_CONTEXT_USE; /* dev zeroed in init_etherdev */ dev = alloc_etherdev_mq(sizeof(*bp), cid_count); @@ -9096,11 +9421,12 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, /* calc qm_cid_count */ bp->qm_cid_count = bnx2x_set_qm_cid_count(bp, cid_count); - rc = register_netdev(dev); - if (rc) { - dev_err(&pdev->dev, "Cannot register net device\n"); - goto init_one_exit; - } +#ifdef BCM_CNIC + /* disable FCOE L2 queue for E1x*/ + if (CHIP_IS_E1x(bp)) + bp->flags |= NO_FCOE_FLAG; + +#endif /* Configure interupt mode: try to enable MSI-X/MSI if * needed, set bp->num_queues appropriately. @@ -9110,6 +9436,21 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, /* Add all NAPI objects */ bnx2x_add_all_napi(bp); + rc = register_netdev(dev); + if (rc) { + dev_err(&pdev->dev, "Cannot register net device\n"); + goto init_one_exit; + } + +#ifdef BCM_CNIC + if (!NO_FCOE(bp)) { + /* Add storage MAC address */ + rtnl_lock(); + dev_addr_add(bp->dev, bp->fip_mac, NETDEV_HW_ADDR_T_SAN); + rtnl_unlock(); + } +#endif + bnx2x_get_pcie_width_speed(bp, &pcie_width, &pcie_speed); netdev_info(dev, "%s (%c%d) PCI-E x%d %s found at mem %lx," @@ -9153,14 +9494,29 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev) } bp = netdev_priv(dev); +#ifdef BCM_CNIC + /* Delete storage MAC address */ + if (!NO_FCOE(bp)) { + rtnl_lock(); + dev_addr_del(bp->dev, bp->fip_mac, NETDEV_HW_ADDR_T_SAN); + rtnl_unlock(); + } +#endif + unregister_netdev(dev); /* Delete all NAPI objects */ bnx2x_del_all_napi(bp); + /* Power on: we can't let PCI layer write to us while we are in D3 */ + bnx2x_set_power_state(bp, PCI_D0); + /* Disable MSI/MSI-X */ bnx2x_disable_msi(bp); + /* Power off */ + bnx2x_set_power_state(bp, PCI_D3hot); + /* Make sure RESET task is not scheduled before continuing */ cancel_delayed_work_sync(&bp->reset_task); @@ -9202,7 +9558,7 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp) /* Free SKBs, SGEs, TPA pool and driver internals */ bnx2x_free_skbs(bp); - for_each_queue(bp, i) + for_each_rx_queue(bp, i) bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); bnx2x_free_mem(bp); @@ -9429,7 +9785,8 @@ static void bnx2x_cnic_sp_post(struct bnx2x *bp, int count) break; else atomic_dec(&bp->spq_left); - } else if (type == ISCSI_CONNECTION_TYPE) { + } else if ((type == ISCSI_CONNECTION_TYPE) || + (type == FCOE_CONNECTION_TYPE)) { if (bp->cnic_spq_pending >= bp->cnic_eth_dev.max_kwqe_pending) break; @@ -9576,6 +9933,9 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl) case DRV_CTL_START_L2_CMD: { u32 cli = ctl->data.ring.client_id; + /* Clear FCoE FIP and ALL ENODE MACs addresses first */ + bnx2x_del_fcoe_eth_macs(bp); + /* Set iSCSI MAC address */ bnx2x_set_iscsi_eth_mac_addr(bp, 1); @@ -9697,10 +10057,6 @@ static int bnx2x_unregister_cnic(struct net_device *dev) struct cnic_eth_dev *cp = &bp->cnic_eth_dev; mutex_lock(&bp->cnic_mutex); - if (bp->cnic_flags & BNX2X_CNIC_FLAG_MAC_SET) { - bp->cnic_flags &= ~BNX2X_CNIC_FLAG_MAC_SET; - bnx2x_set_iscsi_eth_mac_addr(bp, 0); - } cp->drv_state = 0; rcu_assign_pointer(bp->cnic_ops, NULL); mutex_unlock(&bp->cnic_mutex); @@ -9731,7 +10087,9 @@ struct cnic_eth_dev *bnx2x_cnic_probe(struct net_device *dev) cp->drv_ctl = bnx2x_drv_ctl; cp->drv_register_cnic = bnx2x_register_cnic; cp->drv_unregister_cnic = bnx2x_unregister_cnic; - cp->iscsi_l2_client_id = BNX2X_ISCSI_ETH_CL_ID; + cp->fcoe_init_cid = BNX2X_FCOE_ETH_CID; + cp->iscsi_l2_client_id = BNX2X_ISCSI_ETH_CL_ID + + BP_E1HVN(bp) * NONE_ETH_CONTEXT_USE; cp->iscsi_l2_cid = BNX2X_ISCSI_ETH_CID; DP(BNX2X_MSG_SP, "page_size %d, tbl_offset %d, tbl_lines %d, " diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 1cefe489a955..38ef7ca9f21d 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -18,6 +18,8 @@ * WR - Write Clear (write 1 to clear the bit) * */ +#ifndef BNX2X_REG_H +#define BNX2X_REG_H #define ATC_ATC_INT_STS_REG_ADDRESS_ERROR (0x1<<0) #define ATC_ATC_INT_STS_REG_ATC_GPA_MULTIPLE_HITS (0x1<<2) @@ -39,6 +41,8 @@ #define BRB1_REG_BRB1_PRTY_MASK 0x60138 /* [R 4] Parity register #0 read */ #define BRB1_REG_BRB1_PRTY_STS 0x6012c +/* [RC 4] Parity register #0 read clear */ +#define BRB1_REG_BRB1_PRTY_STS_CLR 0x60130 /* [RW 10] At address BRB1_IND_FREE_LIST_PRS_CRDT initialize free head. At * address BRB1_IND_FREE_LIST_PRS_CRDT+1 initialize free tail. At address * BRB1_IND_FREE_LIST_PRS_CRDT+2 initialize parser initial credit. Warning - @@ -132,8 +136,12 @@ #define CCM_REG_CCM_INT_MASK 0xd01e4 /* [R 11] Interrupt register #0 read */ #define CCM_REG_CCM_INT_STS 0xd01d8 +/* [RW 27] Parity mask register #0 read/write */ +#define CCM_REG_CCM_PRTY_MASK 0xd01f4 /* [R 27] Parity register #0 read */ #define CCM_REG_CCM_PRTY_STS 0xd01e8 +/* [RC 27] Parity register #0 read clear */ +#define CCM_REG_CCM_PRTY_STS_CLR 0xd01ec /* [RW 3] The size of AG context region 0 in REG-pairs. Designates the MS REG-pair number (e.g. if region 0 is 6 REG-pairs; the value should be 5). Is used to determine the number of the AG context REG-pairs written back; @@ -350,6 +358,8 @@ #define CDU_REG_CDU_PRTY_MASK 0x10104c /* [R 5] Parity register #0 read */ #define CDU_REG_CDU_PRTY_STS 0x101040 +/* [RC 5] Parity register #0 read clear */ +#define CDU_REG_CDU_PRTY_STS_CLR 0x101044 /* [RC 32] logging of error data in case of a CDU load error: {expected_cid[15:0]; xpected_type[2:0]; xpected_region[2:0]; ctive_error; ype_error; ctual_active; ctual_compressed_context}; */ @@ -381,6 +391,8 @@ #define CFC_REG_CFC_PRTY_MASK 0x104118 /* [R 4] Parity register #0 read */ #define CFC_REG_CFC_PRTY_STS 0x10410c +/* [RC 4] Parity register #0 read clear */ +#define CFC_REG_CFC_PRTY_STS_CLR 0x104110 /* [RW 21] CID cam access (21:1 - Data; alid - 0) */ #define CFC_REG_CID_CAM 0x104800 #define CFC_REG_CONTROL0 0x104028 @@ -466,6 +478,8 @@ #define CSDM_REG_CSDM_PRTY_MASK 0xc22bc /* [R 11] Parity register #0 read */ #define CSDM_REG_CSDM_PRTY_STS 0xc22b0 +/* [RC 11] Parity register #0 read clear */ +#define CSDM_REG_CSDM_PRTY_STS_CLR 0xc22b4 #define CSDM_REG_ENABLE_IN1 0xc2238 #define CSDM_REG_ENABLE_IN2 0xc223c #define CSDM_REG_ENABLE_OUT1 0xc2240 @@ -556,6 +570,9 @@ /* [R 32] Parity register #0 read */ #define CSEM_REG_CSEM_PRTY_STS_0 0x200124 #define CSEM_REG_CSEM_PRTY_STS_1 0x200134 +/* [RC 32] Parity register #0 read clear */ +#define CSEM_REG_CSEM_PRTY_STS_CLR_0 0x200128 +#define CSEM_REG_CSEM_PRTY_STS_CLR_1 0x200138 #define CSEM_REG_ENABLE_IN 0x2000a4 #define CSEM_REG_ENABLE_OUT 0x2000a8 /* [RW 32] This address space contains all registers and memories that are @@ -648,6 +665,8 @@ #define DBG_REG_DBG_PRTY_MASK 0xc0a8 /* [R 1] Parity register #0 read */ #define DBG_REG_DBG_PRTY_STS 0xc09c +/* [RC 1] Parity register #0 read clear */ +#define DBG_REG_DBG_PRTY_STS_CLR 0xc0a0 /* [RW 1] When set the DMAE will process the commands as in E1.5. 1.The * function that is used is always SRC-PCI; 2.VF_Valid = 0; 3.VFID=0; * 4.Completion function=0; 5.Error handling=0 */ @@ -668,6 +687,8 @@ #define DMAE_REG_DMAE_PRTY_MASK 0x102064 /* [R 4] Parity register #0 read */ #define DMAE_REG_DMAE_PRTY_STS 0x102058 +/* [RC 4] Parity register #0 read clear */ +#define DMAE_REG_DMAE_PRTY_STS_CLR 0x10205c /* [RW 1] Command 0 go. */ #define DMAE_REG_GO_C0 0x102080 /* [RW 1] Command 1 go. */ @@ -734,6 +755,8 @@ #define DORQ_REG_DORQ_PRTY_MASK 0x170190 /* [R 2] Parity register #0 read */ #define DORQ_REG_DORQ_PRTY_STS 0x170184 +/* [RC 2] Parity register #0 read clear */ +#define DORQ_REG_DORQ_PRTY_STS_CLR 0x170188 /* [RW 8] The address to write the DPM CID to STORM. */ #define DORQ_REG_DPM_CID_ADDR 0x170044 /* [RW 5] The DPM mode CID extraction offset. */ @@ -842,8 +865,12 @@ /* [R 1] data availble for error memory. If this bit is clear do not red * from error_handling_memory. */ #define IGU_REG_ERROR_HANDLING_DATA_VALID 0x130130 +/* [RW 11] Parity mask register #0 read/write */ +#define IGU_REG_IGU_PRTY_MASK 0x1300a8 /* [R 11] Parity register #0 read */ #define IGU_REG_IGU_PRTY_STS 0x13009c +/* [RC 11] Parity register #0 read clear */ +#define IGU_REG_IGU_PRTY_STS_CLR 0x1300a0 /* [R 4] Debug: int_handle_fsm */ #define IGU_REG_INT_HANDLE_FSM 0x130050 #define IGU_REG_LEADING_EDGE_LATCH 0x130134 @@ -1501,6 +1528,8 @@ #define MISC_REG_MISC_PRTY_MASK 0xa398 /* [R 1] Parity register #0 read */ #define MISC_REG_MISC_PRTY_STS 0xa38c +/* [RC 1] Parity register #0 read clear */ +#define MISC_REG_MISC_PRTY_STS_CLR 0xa390 #define MISC_REG_NIG_WOL_P0 0xa270 #define MISC_REG_NIG_WOL_P1 0xa274 /* [R 1] If set indicate that the pcie_rst_b was asserted without perst @@ -1615,6 +1644,8 @@ #define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_NO_VLAN (0x1<<4) #define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST (0x1<<2) #define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_VLAN (0x1<<3) +#define NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN (0x1<<0) +#define NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN (0x1<<0) #define NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT (0x1<<0) #define NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS (0x1<<9) #define NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G (0x1<<15) @@ -1744,12 +1775,16 @@ ~ppp_enable.ppp_enable = 0 and pause_enable.pause_enable =0 for the same port */ #define NIG_REG_LLFC_ENABLE_0 0x16208 +#define NIG_REG_LLFC_ENABLE_1 0x1620c /* [RW 16] classes are high-priority for port0 */ #define NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0 0x16058 +#define NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 0x1605c /* [RW 16] classes are low-priority for port0 */ #define NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0 0x16060 +#define NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 0x16064 /* [RW 1] Output enable of message to LLFC BMAC IF for port0 */ #define NIG_REG_LLFC_OUT_EN_0 0x160c8 +#define NIG_REG_LLFC_OUT_EN_1 0x160cc #define NIG_REG_LLH0_ACPI_PAT_0_CRC 0x1015c #define NIG_REG_LLH0_ACPI_PAT_6_LEN 0x10154 #define NIG_REG_LLH0_BRB1_DRV_MASK 0x10244 @@ -1774,6 +1809,8 @@ /* [RW 8] event id for llh0 */ #define NIG_REG_LLH0_EVENT_ID 0x10084 #define NIG_REG_LLH0_FUNC_EN 0x160fc +#define NIG_REG_LLH0_FUNC_MEM 0x16180 +#define NIG_REG_LLH0_FUNC_MEM_ENABLE 0x16140 #define NIG_REG_LLH0_FUNC_VLAN_ID 0x16100 /* [RW 1] Determine the IP version to look for in ~nig_registers_llh0_dest_ip_0.llh0_dest_ip_0. 0 - IPv6; 1-IPv4 */ @@ -1797,6 +1834,9 @@ #define NIG_REG_LLH1_ERROR_MASK 0x10090 /* [RW 8] event id for llh1 */ #define NIG_REG_LLH1_EVENT_ID 0x10088 +#define NIG_REG_LLH1_FUNC_MEM 0x161c0 +#define NIG_REG_LLH1_FUNC_MEM_ENABLE 0x16160 +#define NIG_REG_LLH1_FUNC_MEM_SIZE 16 /* [RW 8] init credit counter for port1 in LLH */ #define NIG_REG_LLH1_XCM_INIT_CREDIT 0x10564 #define NIG_REG_LLH1_XCM_MASK 0x10134 @@ -1907,11 +1947,17 @@ ~safc_enable.safc_enable = 0 and ppp_enable.ppp_enable =0 for the same port */ #define NIG_REG_PAUSE_ENABLE_0 0x160c0 +#define NIG_REG_PAUSE_ENABLE_1 0x160c4 /* [RW 1] Input enable for RX PBF LP IF */ #define NIG_REG_PBF_LB_IN_EN 0x100b4 /* [RW 1] Value of this register will be transmitted to port swap when ~nig_registers_strap_override.strap_override =1 */ #define NIG_REG_PORT_SWAP 0x10394 +/* [RW 1] PPP enable for port0. This register may get 1 only when + * ~safc_enable.safc_enable = 0 and pause_enable.pause_enable =0 for the + * same port */ +#define NIG_REG_PPP_ENABLE_0 0x160b0 +#define NIG_REG_PPP_ENABLE_1 0x160b4 /* [RW 1] output enable for RX parser descriptor IF */ #define NIG_REG_PRS_EOP_OUT_EN 0x10104 /* [RW 1] Input enable for RX parser request IF */ @@ -1978,6 +2024,14 @@ #define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G (0x1<<15) #define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS (0xf<<18) #define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE 18 +/* [RW 31] The upper bound of the weight of COS0 in the ETS command arbiter. */ +#define PBF_REG_COS0_UPPER_BOUND 0x15c05c +/* [RW 31] The weight of COS0 in the ETS command arbiter. */ +#define PBF_REG_COS0_WEIGHT 0x15c054 +/* [RW 31] The upper bound of the weight of COS1 in the ETS command arbiter. */ +#define PBF_REG_COS1_UPPER_BOUND 0x15c060 +/* [RW 31] The weight of COS1 in the ETS command arbiter. */ +#define PBF_REG_COS1_WEIGHT 0x15c058 /* [RW 1] Disable processing further tasks from port 0 (after ending the current task in process). */ #define PBF_REG_DISABLE_NEW_TASK_PROC_P0 0x14005c @@ -1988,9 +2042,16 @@ current task in process). */ #define PBF_REG_DISABLE_NEW_TASK_PROC_P4 0x14006c #define PBF_REG_DISABLE_PF 0x1402e8 +/* [RW 1] Indicates that ETS is performed between the COSes in the command + * arbiter. If reset strict priority w/ anti-starvation will be performed + * w/o WFQ. */ +#define PBF_REG_ETS_ENABLED 0x15c050 /* [RW 6] Bit-map indicating which L2 hdrs may appear after the basic * Ethernet header. */ #define PBF_REG_HDRS_AFTER_BASIC 0x15c0a8 +/* [RW 1] Indicates which COS is conncted to the highest priority in the + * command arbiter. */ +#define PBF_REG_HIGH_PRIORITY_COS_NUM 0x15c04c #define PBF_REG_IF_ENABLE_REG 0x140044 /* [RW 1] Init bit. When set the initial credits are copied to the credit registers (except the port credits). Should be set and then reset after @@ -2016,6 +2077,10 @@ #define PBF_REG_MAC_LB_ENABLE 0x140040 /* [RW 6] Bit-map indicating which headers must appear in the packet */ #define PBF_REG_MUST_HAVE_HDRS 0x15c0c4 +/* [RW 16] The number of strict priority arbitration slots between 2 RR + * arbitration slots. A value of 0 means no strict priority cycles; i.e. the + * strict-priority w/ anti-starvation arbiter is a RR arbiter. */ +#define PBF_REG_NUM_STRICT_ARB_SLOTS 0x15c064 /* [RW 10] Port 0 threshold used by arbiter in 16 byte lines used when pause not suppoterd. */ #define PBF_REG_P0_ARB_THRSH 0x1400e4 @@ -2046,6 +2111,10 @@ #define PBF_REG_PBF_INT_MASK 0x1401d4 /* [R 5] Interrupt register #0 read */ #define PBF_REG_PBF_INT_STS 0x1401c8 +/* [RW 20] Parity mask register #0 read/write */ +#define PBF_REG_PBF_PRTY_MASK 0x1401e4 +/* [RC 20] Parity register #0 read clear */ +#define PBF_REG_PBF_PRTY_STS_CLR 0x1401dc #define PB_REG_CONTROL 0 /* [RW 2] Interrupt mask register #0 read/write */ #define PB_REG_PB_INT_MASK 0x28 @@ -2055,6 +2124,8 @@ #define PB_REG_PB_PRTY_MASK 0x38 /* [R 4] Parity register #0 read */ #define PB_REG_PB_PRTY_STS 0x2c +/* [RC 4] Parity register #0 read clear */ +#define PB_REG_PB_PRTY_STS_CLR 0x30 #define PGLUE_B_PGLUE_B_INT_STS_REG_ADDRESS_ERROR (0x1<<0) #define PGLUE_B_PGLUE_B_INT_STS_REG_CSSNOOP_FIFO_OVERFLOW (0x1<<8) #define PGLUE_B_PGLUE_B_INT_STS_REG_INCORRECT_RCV_BEHAVIOR (0x1<<1) @@ -2410,6 +2481,8 @@ #define PRS_REG_PRS_PRTY_MASK 0x401a4 /* [R 8] Parity register #0 read */ #define PRS_REG_PRS_PRTY_STS 0x40198 +/* [RC 8] Parity register #0 read clear */ +#define PRS_REG_PRS_PRTY_STS_CLR 0x4019c /* [RW 8] Context region for pure acknowledge packets. Used in CFC load request message */ #define PRS_REG_PURE_REGIONS 0x40024 @@ -2563,6 +2636,9 @@ /* [R 32] Parity register #0 read */ #define PXP2_REG_PXP2_PRTY_STS_0 0x12057c #define PXP2_REG_PXP2_PRTY_STS_1 0x12058c +/* [RC 32] Parity register #0 read clear */ +#define PXP2_REG_PXP2_PRTY_STS_CLR_0 0x120580 +#define PXP2_REG_PXP2_PRTY_STS_CLR_1 0x120590 /* [R 1] Debug only: The 'almost full' indication from each fifo (gives indication about backpressure) */ #define PXP2_REG_RD_ALMOST_FULL_0 0x120424 @@ -2965,6 +3041,8 @@ #define PXP_REG_PXP_PRTY_MASK 0x103094 /* [R 26] Parity register #0 read */ #define PXP_REG_PXP_PRTY_STS 0x103088 +/* [RC 27] Parity register #0 read clear */ +#define PXP_REG_PXP_PRTY_STS_CLR 0x10308c /* [RW 4] The activity counter initial increment value sent in the load request */ #define QM_REG_ACTCTRINITVAL_0 0x168040 @@ -3121,6 +3199,8 @@ #define QM_REG_QM_PRTY_MASK 0x168454 /* [R 12] Parity register #0 read */ #define QM_REG_QM_PRTY_STS 0x168448 +/* [RC 12] Parity register #0 read clear */ +#define QM_REG_QM_PRTY_STS_CLR 0x16844c /* [R 32] Current queues in pipeline: Queues from 32 to 63 */ #define QM_REG_QSTATUS_HIGH 0x16802c /* [R 32] Current queues in pipeline: Queues from 96 to 127 */ @@ -3406,6 +3486,8 @@ #define QM_REG_WRRWEIGHTS_9 0x168848 /* [R 6] Keep the fill level of the fifo from write client 1 */ #define QM_REG_XQM_WRC_FIFOLVL 0x168000 +/* [W 1] reset to parity interrupt */ +#define SEM_FAST_REG_PARITY_RST 0x18840 #define SRC_REG_COUNTFREE0 0x40500 /* [RW 1] If clr the searcher is compatible to E1 A0 - support only two ports. If set the searcher support 8 functions. */ @@ -3434,6 +3516,8 @@ #define SRC_REG_SRC_PRTY_MASK 0x404c8 /* [R 3] Parity register #0 read */ #define SRC_REG_SRC_PRTY_STS 0x404bc +/* [RC 3] Parity register #0 read clear */ +#define SRC_REG_SRC_PRTY_STS_CLR 0x404c0 /* [R 4] Used to read the value of the XX protection CAM occupancy counter. */ #define TCM_REG_CAM_OCCUP 0x5017c /* [RW 1] CDU AG read Interface enable. If 0 - the request input is @@ -3560,8 +3644,12 @@ #define TCM_REG_TCM_INT_MASK 0x501dc /* [R 11] Interrupt register #0 read */ #define TCM_REG_TCM_INT_STS 0x501d0 +/* [RW 27] Parity mask register #0 read/write */ +#define TCM_REG_TCM_PRTY_MASK 0x501ec /* [R 27] Parity register #0 read */ #define TCM_REG_TCM_PRTY_STS 0x501e0 +/* [RC 27] Parity register #0 read clear */ +#define TCM_REG_TCM_PRTY_STS_CLR 0x501e4 /* [RW 3] The size of AG context region 0 in REG-pairs. Designates the MS REG-pair number (e.g. if region 0 is 6 REG-pairs; the value should be 5). Is used to determine the number of the AG context REG-pairs written back; @@ -3719,6 +3807,10 @@ #define TM_REG_TM_INT_MASK 0x1640fc /* [R 1] Interrupt register #0 read */ #define TM_REG_TM_INT_STS 0x1640f0 +/* [RW 7] Parity mask register #0 read/write */ +#define TM_REG_TM_PRTY_MASK 0x16410c +/* [RC 7] Parity register #0 read clear */ +#define TM_REG_TM_PRTY_STS_CLR 0x164104 /* [RW 8] The event id for aggregated interrupt 0 */ #define TSDM_REG_AGG_INT_EVENT_0 0x42038 #define TSDM_REG_AGG_INT_EVENT_1 0x4203c @@ -3799,6 +3891,8 @@ #define TSDM_REG_TSDM_PRTY_MASK 0x422bc /* [R 11] Parity register #0 read */ #define TSDM_REG_TSDM_PRTY_STS 0x422b0 +/* [RC 11] Parity register #0 read clear */ +#define TSDM_REG_TSDM_PRTY_STS_CLR 0x422b4 /* [RW 5] The number of time_slots in the arbitration cycle */ #define TSEM_REG_ARB_CYCLE_SIZE 0x180034 /* [RW 3] The source that is associated with arbitration element 0. Source @@ -3878,6 +3972,9 @@ #define TSEM_REG_SLOW_EXT_STORE_EMPTY 0x1802a0 /* [RW 8] List of free threads . There is a bit per thread. */ #define TSEM_REG_THREADS_LIST 0x1802e4 +/* [RC 32] Parity register #0 read clear */ +#define TSEM_REG_TSEM_PRTY_STS_CLR_0 0x180118 +#define TSEM_REG_TSEM_PRTY_STS_CLR_1 0x180128 /* [RW 3] The arbitration scheme of time_slot 0 */ #define TSEM_REG_TS_0_AS 0x180038 /* [RW 3] The arbitration scheme of time_slot 10 */ @@ -4080,6 +4177,8 @@ #define UCM_REG_UCM_INT_STS 0xe01c8 /* [R 27] Parity register #0 read */ #define UCM_REG_UCM_PRTY_STS 0xe01d8 +/* [RC 27] Parity register #0 read clear */ +#define UCM_REG_UCM_PRTY_STS_CLR 0xe01dc /* [RW 2] The size of AG context region 0 in REG-pairs. Designates the MS REG-pair number (e.g. if region 0 is 6 REG-pairs; the value should be 5). Is used to determine the number of the AG context REG-pairs written back; @@ -4256,6 +4355,8 @@ #define USDM_REG_USDM_PRTY_MASK 0xc42c0 /* [R 11] Parity register #0 read */ #define USDM_REG_USDM_PRTY_STS 0xc42b4 +/* [RC 11] Parity register #0 read clear */ +#define USDM_REG_USDM_PRTY_STS_CLR 0xc42b8 /* [RW 5] The number of time_slots in the arbitration cycle */ #define USEM_REG_ARB_CYCLE_SIZE 0x300034 /* [RW 3] The source that is associated with arbitration element 0. Source @@ -4385,6 +4486,9 @@ /* [R 32] Parity register #0 read */ #define USEM_REG_USEM_PRTY_STS_0 0x300124 #define USEM_REG_USEM_PRTY_STS_1 0x300134 +/* [RC 32] Parity register #0 read clear */ +#define USEM_REG_USEM_PRTY_STS_CLR_0 0x300128 +#define USEM_REG_USEM_PRTY_STS_CLR_1 0x300138 /* [W 7] VF or PF ID for reset error bit. Values 0-63 reset error bit for 64 * VF; values 64-67 reset error for 4 PF; values 68-127 are not valid. */ #define USEM_REG_VFPF_ERR_NUM 0x300380 @@ -4761,6 +4865,8 @@ #define XSDM_REG_XSDM_PRTY_MASK 0x1662bc /* [R 11] Parity register #0 read */ #define XSDM_REG_XSDM_PRTY_STS 0x1662b0 +/* [RC 11] Parity register #0 read clear */ +#define XSDM_REG_XSDM_PRTY_STS_CLR 0x1662b4 /* [RW 5] The number of time_slots in the arbitration cycle */ #define XSEM_REG_ARB_CYCLE_SIZE 0x280034 /* [RW 3] The source that is associated with arbitration element 0. Source @@ -4893,6 +4999,9 @@ /* [R 32] Parity register #0 read */ #define XSEM_REG_XSEM_PRTY_STS_0 0x280124 #define XSEM_REG_XSEM_PRTY_STS_1 0x280134 +/* [RC 32] Parity register #0 read clear */ +#define XSEM_REG_XSEM_PRTY_STS_CLR_0 0x280128 +#define XSEM_REG_XSEM_PRTY_STS_CLR_1 0x280138 #define MCPR_NVM_ACCESS_ENABLE_EN (1L<<0) #define MCPR_NVM_ACCESS_ENABLE_WR_EN (1L<<1) #define MCPR_NVM_ADDR_NVM_ADDR_VALUE (0xffffffL<<0) @@ -4970,7 +5079,23 @@ #define EMAC_REG_EMAC_TX_MODE 0xbc #define EMAC_REG_EMAC_TX_STAT_AC 0x280 #define EMAC_REG_EMAC_TX_STAT_AC_COUNT 22 +#define EMAC_REG_RX_PFC_MODE 0x320 +#define EMAC_REG_RX_PFC_MODE_PRIORITIES (1L<<2) +#define EMAC_REG_RX_PFC_MODE_RX_EN (1L<<1) +#define EMAC_REG_RX_PFC_MODE_TX_EN (1L<<0) +#define EMAC_REG_RX_PFC_PARAM 0x324 +#define EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT 0 +#define EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT 16 +#define EMAC_REG_RX_PFC_STATS_XOFF_RCVD 0x328 +#define EMAC_REG_RX_PFC_STATS_XOFF_RCVD_COUNT (0xffff<<0) +#define EMAC_REG_RX_PFC_STATS_XOFF_SENT 0x330 +#define EMAC_REG_RX_PFC_STATS_XOFF_SENT_COUNT (0xffff<<0) +#define EMAC_REG_RX_PFC_STATS_XON_RCVD 0x32c +#define EMAC_REG_RX_PFC_STATS_XON_RCVD_COUNT (0xffff<<0) +#define EMAC_REG_RX_PFC_STATS_XON_SENT 0x334 +#define EMAC_REG_RX_PFC_STATS_XON_SENT_COUNT (0xffff<<0) #define EMAC_RX_MODE_FLOW_EN (1L<<2) +#define EMAC_RX_MODE_KEEP_MAC_CONTROL (1L<<3) #define EMAC_RX_MODE_KEEP_VLAN_TAG (1L<<10) #define EMAC_RX_MODE_PROMISCUOUS (1L<<8) #define EMAC_RX_MODE_RESET (1L<<0) @@ -6264,3 +6389,4 @@ static inline u8 calc_crc8(u32 data, u8 crc) } +#endif /* BNX2X_REG_H */ diff --git a/drivers/net/bnx2x/bnx2x_stats.c b/drivers/net/bnx2x/bnx2x_stats.c index 4733c835dad9..bda60d590fa8 100644 --- a/drivers/net/bnx2x/bnx2x_stats.c +++ b/drivers/net/bnx2x/bnx2x_stats.c @@ -158,9 +158,14 @@ static void bnx2x_storm_stats_post(struct bnx2x *bp) spin_lock_bh(&bp->stats_lock); + if (bp->stats_pending) { + spin_unlock_bh(&bp->stats_lock); + return; + } + ramrod_data.drv_counter = bp->stats_counter++; ramrod_data.collect_port = bp->port.pmf ? 1 : 0; - for_each_queue(bp, i) + for_each_eth_queue(bp, i) ramrod_data.ctr_id_vector |= (1 << bp->fp[i].cl_id); rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_STAT_QUERY, 0, @@ -766,7 +771,7 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp) estats->no_buff_discard_hi = 0; estats->no_buff_discard_lo = 0; - for_each_queue(bp, i) { + for_each_eth_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; int cl_id = fp->cl_id; struct tstorm_per_client_stats *tclient = @@ -996,7 +1001,7 @@ static void bnx2x_net_stats_update(struct bnx2x *bp) nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi); tmp = estats->mac_discard; - for_each_queue(bp, i) + for_each_rx_queue(bp, i) tmp += le32_to_cpu(bp->fp[i].old_tclient.checksum_discard); nstats->rx_dropped = tmp; @@ -1087,7 +1092,7 @@ static void bnx2x_stats_update(struct bnx2x *bp) bp->dev->name, estats->brb_drop_lo, estats->brb_truncate_lo); - for_each_queue(bp, i) { + for_each_eth_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats; @@ -1101,7 +1106,7 @@ static void bnx2x_stats_update(struct bnx2x *bp) fp->rx_calls, fp->rx_pkt); } - for_each_queue(bp, i) { + for_each_eth_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats; struct netdev_queue *txq = @@ -1381,7 +1386,8 @@ void bnx2x_stats_init(struct bnx2x *bp) memset(&fp->eth_q_stats, 0, sizeof(struct bnx2x_eth_q_stats)); } - for_each_queue(bp, i) { + /* FW stats are currently collected for ETH clients only */ + for_each_eth_queue(bp, i) { /* Set initial stats counter in the stats ramrod data to -1 */ int cl_id = bp->fp[i].cl_id; diff --git a/drivers/net/bnx2x/bnx2x_stats.h b/drivers/net/bnx2x/bnx2x_stats.h index afd15efa429a..596798c47452 100644 --- a/drivers/net/bnx2x/bnx2x_stats.h +++ b/drivers/net/bnx2x/bnx2x_stats.h @@ -53,7 +53,6 @@ struct bnx2x_eth_q_stats { u32 hw_csum_err; }; -#define BNX2X_NUM_Q_STATS 13 #define Q_STATS_OFFSET32(stat_name) \ (offsetof(struct bnx2x_eth_q_stats, stat_name) / 4) @@ -225,7 +224,6 @@ struct bnx2x_eth_stats { u32 nig_timer_max; }; -#define BNX2X_NUM_STATS 43 #define STATS_OFFSET32(stat_name) \ (offsetof(struct bnx2x_eth_stats, stat_name) / 4) |