diff options
author | Vladislav Zolotarov <vladz@broadcom.com> | 2011-06-14 01:33:39 +0000 |
---|---|---|
committer | David S. Miller <davem@conan.davemloft.net> | 2011-06-15 10:56:15 -0400 |
commit | 042181f5aa8833a8918e1a91cfaf292146ffc62c (patch) | |
tree | 8011639e79d72485e96285a3668101596528eaee | |
parent | 9ee3d37b05c2fc5c6c01e09dd3bcc4500babf76a (diff) | |
download | op-kernel-dev-042181f5aa8833a8918e1a91cfaf292146ffc62c.zip op-kernel-dev-042181f5aa8833a8918e1a91cfaf292146ffc62c.tar.gz |
bnx2x: Created bnx2x_sp
Moved the HSI dependent slow path code to a separate file.
Currently it contains the implementation of MACs, Rx mode,
multicast addresses, indirection table, fast path queue and function
configuration code.
Signed-off-by: Vladislav Zolotarov <vladz@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@conan.davemloft.net>
-rw-r--r-- | drivers/net/bnx2x/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x.h | 6 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_cmn.c | 2 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_cmn.h | 10 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_ethtool.c | 1 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_main.c | 824 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_sp.c | 819 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_sp.h | 43 |
8 files changed, 874 insertions, 833 deletions
diff --git a/drivers/net/bnx2x/Makefile b/drivers/net/bnx2x/Makefile index bb83a29..48fbdd4 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_dcb.o +bnx2x-objs := bnx2x_main.o bnx2x_link.o bnx2x_cmn.o bnx2x_ethtool.o bnx2x_stats.o bnx2x_dcb.o bnx2x_sp.o diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 3cf0768..6d4d6d4 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -1482,10 +1482,11 @@ int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, u32 data_hi, u32 data_lo, int common); /* Clears multicast and unicast list configuration in the chip. */ -void bnx2x_invalidate_e1_mc_list(struct bnx2x *bp); -void bnx2x_invalidate_e1h_mc_list(struct bnx2x *bp); void bnx2x_invalidate_uc_list(struct bnx2x *bp); +int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, + int *state_p, int flags); + void bnx2x_update_coalesce(struct bnx2x *bp); int bnx2x_get_cur_phy_idx(struct bnx2x *bp); @@ -1825,6 +1826,5 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, BNX2X_EXTERN int load_count[2][3]; /* per path: 0-common, 1-port0, 2-port1 */ extern void bnx2x_set_ethtool_ops(struct net_device *netdev); -void bnx2x_push_indir_table(struct bnx2x *bp); #endif /* bnx2x.h */ diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index ed1d695..c72e1df 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -24,8 +24,8 @@ #include <linux/firmware.h> #include <linux/prefetch.h> #include "bnx2x_cmn.h" - #include "bnx2x_init.h" +#include "bnx2x_sp.h" static int bnx2x_setup_irqs(struct bnx2x *bp); diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 57d9354..5a97f92 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -292,13 +292,6 @@ int bnx2x_set_all_enode_macs(struct bnx2x *bp, int set); */ void bnx2x_set_rx_mode(struct net_device *dev); -/** - * bnx2x_set_storm_rx_mode - configure MAC filtering rules in a FW. - * - * @bp: driver handle - */ -void bnx2x_set_storm_rx_mode(struct bnx2x *bp); - /* Parity errors related */ void bnx2x_inc_load_cnt(struct bnx2x *bp); u32 bnx2x_dec_load_cnt(struct bnx2x *bp); @@ -1117,6 +1110,9 @@ static inline void storm_memset_cmng(struct bnx2x *bp, void bnx2x_acquire_phy_lock(struct bnx2x *bp); void bnx2x_release_phy_lock(struct bnx2x *bp); +void bnx2x_update_coalesce_sb_index(struct bnx2x *bp, u16 fw_sb_id, + u8 sb_index, u8 disable, u16 usec); + /** * bnx2x_extract_max_cfg - extract MAX BW part from MF configuration. * diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index ddb99a9..7a13305 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -25,6 +25,7 @@ #include "bnx2x_cmn.h" #include "bnx2x_dump.h" #include "bnx2x_init.h" +#include "bnx2x_sp.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 diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index d7cab0d..84f419f 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -56,6 +56,7 @@ #include "bnx2x_init_ops.h" #include "bnx2x_cmn.h" #include "bnx2x_dcb.h" +#include "bnx2x_sp.h" #include <linux/firmware.h> #include "bnx2x_fw_file_hdr.h" @@ -162,186 +163,11 @@ MODULE_DEVICE_TABLE(pci, bnx2x_pci_tbl); * General service functions ****************************************************************************/ -static inline void __storm_memset_dma_mapping(struct bnx2x *bp, - u32 addr, dma_addr_t mapping) -{ - REG_WR(bp, addr, U64_LO(mapping)); - REG_WR(bp, addr + 4, U64_HI(mapping)); -} - -static inline void __storm_memset_fill(struct bnx2x *bp, - u32 addr, size_t size, u32 val) -{ - int i; - for (i = 0; i < size/4; i++) - REG_WR(bp, addr + (i * 4), val); -} - -static inline void storm_memset_ustats_zero(struct bnx2x *bp, - u8 port, u16 stat_id) -{ - size_t size = sizeof(struct ustorm_per_client_stats); - - u32 addr = BAR_USTRORM_INTMEM + - USTORM_PER_COUNTER_ID_STATS_OFFSET(port, stat_id); - - __storm_memset_fill(bp, addr, size, 0); -} - -static inline void storm_memset_tstats_zero(struct bnx2x *bp, - u8 port, u16 stat_id) -{ - size_t size = sizeof(struct tstorm_per_client_stats); - - u32 addr = BAR_TSTRORM_INTMEM + - TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stat_id); - - __storm_memset_fill(bp, addr, size, 0); -} - -static inline void storm_memset_xstats_zero(struct bnx2x *bp, - u8 port, u16 stat_id) -{ - size_t size = sizeof(struct xstorm_per_client_stats); - - u32 addr = BAR_XSTRORM_INTMEM + - XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stat_id); - - __storm_memset_fill(bp, addr, size, 0); -} - - -static inline void storm_memset_spq_addr(struct bnx2x *bp, - dma_addr_t mapping, u16 abs_fid) -{ - u32 addr = XSEM_REG_FAST_MEMORY + - XSTORM_SPQ_PAGE_BASE_OFFSET(abs_fid); - - __storm_memset_dma_mapping(bp, addr, mapping); -} - static inline void storm_memset_ov(struct bnx2x *bp, u16 ov, u16 abs_fid) { REG_WR16(bp, BAR_XSTRORM_INTMEM + XSTORM_E1HOV_OFFSET(abs_fid), ov); } -static inline void storm_memset_func_cfg(struct bnx2x *bp, - struct tstorm_eth_function_common_config *tcfg, - u16 abs_fid) -{ - size_t size = sizeof(struct tstorm_eth_function_common_config); - - u32 addr = BAR_TSTRORM_INTMEM + - TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(abs_fid); - - __storm_memset_struct(bp, addr, size, (u32 *)tcfg); -} - -static inline void storm_memset_xstats_flags(struct bnx2x *bp, - struct stats_indication_flags *flags, - u16 abs_fid) -{ - size_t size = sizeof(struct stats_indication_flags); - - u32 addr = BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(abs_fid); - - __storm_memset_struct(bp, addr, size, (u32 *)flags); -} - -static inline void storm_memset_tstats_flags(struct bnx2x *bp, - struct stats_indication_flags *flags, - u16 abs_fid) -{ - size_t size = sizeof(struct stats_indication_flags); - - u32 addr = BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(abs_fid); - - __storm_memset_struct(bp, addr, size, (u32 *)flags); -} - -static inline void storm_memset_ustats_flags(struct bnx2x *bp, - struct stats_indication_flags *flags, - u16 abs_fid) -{ - size_t size = sizeof(struct stats_indication_flags); - - u32 addr = BAR_USTRORM_INTMEM + USTORM_STATS_FLAGS_OFFSET(abs_fid); - - __storm_memset_struct(bp, addr, size, (u32 *)flags); -} - -static inline void storm_memset_cstats_flags(struct bnx2x *bp, - struct stats_indication_flags *flags, - u16 abs_fid) -{ - size_t size = sizeof(struct stats_indication_flags); - - u32 addr = BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(abs_fid); - - __storm_memset_struct(bp, addr, size, (u32 *)flags); -} - -static inline void storm_memset_xstats_addr(struct bnx2x *bp, - dma_addr_t mapping, u16 abs_fid) -{ - u32 addr = BAR_XSTRORM_INTMEM + - XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); - - __storm_memset_dma_mapping(bp, addr, mapping); -} - -static inline void storm_memset_tstats_addr(struct bnx2x *bp, - dma_addr_t mapping, u16 abs_fid) -{ - u32 addr = BAR_TSTRORM_INTMEM + - TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); - - __storm_memset_dma_mapping(bp, addr, mapping); -} - -static inline void storm_memset_ustats_addr(struct bnx2x *bp, - dma_addr_t mapping, u16 abs_fid) -{ - u32 addr = BAR_USTRORM_INTMEM + - USTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); - - __storm_memset_dma_mapping(bp, addr, mapping); -} - -static inline void storm_memset_cstats_addr(struct bnx2x *bp, - dma_addr_t mapping, u16 abs_fid) -{ - u32 addr = BAR_CSTRORM_INTMEM + - CSTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); - - __storm_memset_dma_mapping(bp, addr, mapping); -} - -static inline void storm_memset_vf_to_pf(struct bnx2x *bp, u16 abs_fid, - u16 pf_id) -{ - REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_VF_TO_PF_OFFSET(abs_fid), - pf_id); - REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_VF_TO_PF_OFFSET(abs_fid), - pf_id); - REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_VF_TO_PF_OFFSET(abs_fid), - pf_id); - REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_VF_TO_PF_OFFSET(abs_fid), - pf_id); -} - -static inline void storm_memset_func_en(struct bnx2x *bp, u16 abs_fid, - u8 enable) -{ - REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNC_EN_OFFSET(abs_fid), - enable); - REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_FUNC_EN_OFFSET(abs_fid), - enable); - REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_FUNC_EN_OFFSET(abs_fid), - enable); - REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_FUNC_EN_OFFSET(abs_fid), - enable); -} static inline void storm_memset_eq_data(struct bnx2x *bp, struct event_ring_data *eq_data, @@ -2239,143 +2065,6 @@ static u8 stat_counter_valid(struct bnx2x *bp, struct bnx2x_fastpath *fp) return true; } -/* must be called under rtnl_lock */ -static void bnx2x_rxq_set_mac_filters(struct bnx2x *bp, u16 cl_id, u32 filters) -{ - u32 mask = (1 << cl_id); - - /* initial seeting is BNX2X_ACCEPT_NONE */ - u8 drop_all_ucast = 1, drop_all_bcast = 1, drop_all_mcast = 1; - 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 */ - drop_all_ucast = 0; - } - if (filters & BNX2X_ACCEPT_MULTICAST) - /* accept matched mcast */ - drop_all_mcast = 0; - - if (filters & BNX2X_ACCEPT_ALL_UNICAST) { - /* accept all mcast */ - drop_all_ucast = 0; - accp_all_ucast = 1; - } - if (filters & BNX2X_ACCEPT_ALL_MULTICAST) { - /* accept all mcast */ - drop_all_mcast = 0; - accp_all_mcast = 1; - } - if (filters & BNX2X_ACCEPT_BROADCAST) { - /* accept (all) bcast */ - drop_all_bcast = 0; - accp_all_bcast = 1; - } - - bp->mac_filters.ucast_drop_all = drop_all_ucast ? - bp->mac_filters.ucast_drop_all | mask : - bp->mac_filters.ucast_drop_all & ~mask; - - bp->mac_filters.mcast_drop_all = drop_all_mcast ? - bp->mac_filters.mcast_drop_all | mask : - bp->mac_filters.mcast_drop_all & ~mask; - - bp->mac_filters.bcast_drop_all = drop_all_bcast ? - bp->mac_filters.bcast_drop_all | mask : - bp->mac_filters.bcast_drop_all & ~mask; - - bp->mac_filters.ucast_accept_all = accp_all_ucast ? - bp->mac_filters.ucast_accept_all | mask : - bp->mac_filters.ucast_accept_all & ~mask; - - bp->mac_filters.mcast_accept_all = accp_all_mcast ? - bp->mac_filters.mcast_accept_all | mask : - bp->mac_filters.mcast_accept_all & ~mask; - - bp->mac_filters.bcast_accept_all = accp_all_bcast ? - bp->mac_filters.bcast_accept_all | mask : - bp->mac_filters.bcast_accept_all & ~mask; - - bp->mac_filters.unmatched_unicast = unmatched_unicast ? - bp->mac_filters.unmatched_unicast | mask : - bp->mac_filters.unmatched_unicast & ~mask; -} - -static void bnx2x_func_init(struct bnx2x *bp, struct bnx2x_func_init_params *p) -{ - struct tstorm_eth_function_common_config tcfg = {0}; - u16 rss_flgs; - - /* tpa */ - if (p->func_flgs & FUNC_FLG_TPA) - tcfg.config_flags |= - TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA; - - /* set rss flags */ - rss_flgs = (p->rss->mode << - TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT); - - if (p->rss->cap & RSS_IPV4_CAP) - rss_flgs |= RSS_IPV4_CAP_MASK; - if (p->rss->cap & RSS_IPV4_TCP_CAP) - rss_flgs |= RSS_IPV4_TCP_CAP_MASK; - if (p->rss->cap & RSS_IPV6_CAP) - rss_flgs |= RSS_IPV6_CAP_MASK; - if (p->rss->cap & RSS_IPV6_TCP_CAP) - rss_flgs |= RSS_IPV6_TCP_CAP_MASK; - - tcfg.config_flags |= rss_flgs; - tcfg.rss_result_mask = p->rss->result_mask; - - storm_memset_func_cfg(bp, &tcfg, p->func_id); - - /* Enable the function in the FW */ - storm_memset_vf_to_pf(bp, p->func_id, p->pf_id); - storm_memset_func_en(bp, p->func_id, 1); - - /* statistics */ - if (p->func_flgs & FUNC_FLG_STATS) { - struct stats_indication_flags stats_flags = {0}; - stats_flags.collect_eth = 1; - - storm_memset_xstats_flags(bp, &stats_flags, p->func_id); - storm_memset_xstats_addr(bp, p->fw_stat_map, p->func_id); - - storm_memset_tstats_flags(bp, &stats_flags, p->func_id); - storm_memset_tstats_addr(bp, p->fw_stat_map, p->func_id); - - storm_memset_ustats_flags(bp, &stats_flags, p->func_id); - storm_memset_ustats_addr(bp, p->fw_stat_map, p->func_id); - - storm_memset_cstats_flags(bp, &stats_flags, p->func_id); - storm_memset_cstats_addr(bp, p->fw_stat_map, p->func_id); - } - - /* spq */ - if (p->func_flgs & FUNC_FLG_SPQ) { - storm_memset_spq_addr(bp, p->spq_map, p->func_id); - REG_WR(bp, XSEM_REG_FAST_MEMORY + - XSTORM_SPQ_PROD_OFFSET(p->func_id), p->spq_prod); - } -} - static inline u16 bnx2x_get_cl_flags(struct bnx2x *bp, struct bnx2x_fastpath *fp) { @@ -4068,7 +3757,7 @@ static void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid, bnx2x_wr_fp_sb_data(bp, fw_sb_id, sb_data_p, data_size); } -static void bnx2x_update_coalesce_sb_index(struct bnx2x *bp, u16 fw_sb_id, +void bnx2x_update_coalesce_sb_index(struct bnx2x *bp, u16 fw_sb_id, u8 sb_index, u8 disable, u16 usec) { int port = BP_PORT(bp); @@ -4213,20 +3902,6 @@ static void bnx2x_init_eq_ring(struct bnx2x *bp) min_t(int, MAX_SP_DESC_CNT - MAX_SPQ_PENDING, NUM_EQ_DESC) - 1); } -void bnx2x_push_indir_table(struct bnx2x *bp) -{ - int func = BP_FUNC(bp); - int i; - - if (bp->multi_mode == ETH_RSS_MODE_DISABLED) - return; - - 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 + bp->rx_indir_table[i]); -} - static void bnx2x_init_ind_table(struct bnx2x *bp) { int i; @@ -4237,104 +3912,6 @@ static void bnx2x_init_ind_table(struct bnx2x *bp) bnx2x_push_indir_table(bp); } -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 = - NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_BRCST | - NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_MLCST | - NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_VLAN | - NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_NO_VLAN; - - switch (mode) { - case BNX2X_RX_MODE_NONE: /* no Rx */ - 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: - def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST | - BNX2X_ACCEPT_MULTICAST; -#ifdef BCM_CNIC - if (!NO_FCOE(bp)) { - 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: - def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST | - BNX2X_ACCEPT_ALL_MULTICAST; -#ifdef BCM_CNIC - /* - * Prevent duplication of multicast packets by configuring FCoE - * L2 Client to receive only matched unicast frames. - */ - if (!NO_FCOE(bp)) { - cl_id = bnx2x_fcoe(bp, cl_id); - bnx2x_rxq_set_mac_filters(bp, cl_id, - BNX2X_ACCEPT_UNICAST); - } -#endif - break; - - case BNX2X_RX_MODE_PROMISC: - def_q_filters |= BNX2X_PROMISCUOUS_MODE; -#ifdef BCM_CNIC - /* - * Prevent packets duplication by configuring DROP_ALL for FCoE - * L2 Client. - */ - if (!NO_FCOE(bp)) { - cl_id = bnx2x_fcoe(bp, cl_id); - bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_NONE); - } -#endif - /* pass management unicast packets as well */ - llh_mask |= NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST; - break; - - default: - BNX2X_ERR("BAD rx mode (%d)\n", mode); - break; - } - - cl_id = BP_L_ID(bp); - bnx2x_rxq_set_mac_filters(bp, cl_id, def_q_filters); - - REG_WR(bp, - (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" - "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.unmatched_unicast - ); - - storm_memset_mac_filters(bp, &bp->mac_filters, BP_FUNC(bp)); -} - static void bnx2x_init_internal_common(struct bnx2x *bp) { int i; @@ -5976,9 +5553,6 @@ alloc_mem_err: /* * Init service functions */ -static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, - int *state_p, int flags); - int bnx2x_func_start(struct bnx2x *bp) { bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_FUNCTION_START, 0, 0, 0, 1); @@ -5997,75 +5571,7 @@ static int bnx2x_func_stop(struct bnx2x *bp) 0, &(bp->state), WAIT_RAMROD_COMMON); } -/** - * bnx2x_set_mac_addr_gen - set a MAC in a CAM for a few L2 Clients for E1x chips - * - * @bp: driver handle - * @set: set or clear an entry (1 or 0) - * @mac: pointer to a buffer containing a MAC - * @cl_bit_vec: bit vector of clients to register a MAC for - * @cam_offset: offset in a CAM to use - * @is_bcast: is the set MAC a broadcast address (for E1 only) - */ -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) -{ - struct mac_configuration_cmd *config = - (struct mac_configuration_cmd *)bnx2x_sp(bp, mac_config); - int ramrod_flags = WAIT_RAMROD_COMMON; - - bp->set_mac_pending = 1; - - config->hdr.length = 1; - config->hdr.offset = cam_offset; - config->hdr.client_id = 0xff; - /* Mark the single MAC configuration ramrod as opposed to a - * UC/MC list configuration). - */ - config->hdr.echo = 1; - - /* primary MAC */ - config->config_table[0].msb_mac_addr = - swab16(*(u16 *)&mac[0]); - config->config_table[0].middle_mac_addr = - swab16(*(u16 *)&mac[2]); - config->config_table[0].lsb_mac_addr = - swab16(*(u16 *)&mac[4]); - config->config_table[0].clients_bit_vector = - cpu_to_le32(cl_bit_vec); - config->config_table[0].vlan_id = 0; - config->config_table[0].pf_id = BP_FUNC(bp); - if (set) - SET_FLAG(config->config_table[0].flags, - MAC_CONFIGURATION_ENTRY_ACTION_TYPE, - T_ETH_MAC_COMMAND_SET); - else - SET_FLAG(config->config_table[0].flags, - MAC_CONFIGURATION_ENTRY_ACTION_TYPE, - T_ETH_MAC_COMMAND_INVALIDATE); - - if (is_bcast) - SET_FLAG(config->config_table[0].flags, - MAC_CONFIGURATION_ENTRY_BROADCAST, 1); - - DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x) PF_ID %d CLID mask %d\n", - (set ? "setting" : "clearing"), - config->config_table[0].msb_mac_addr, - config->config_table[0].middle_mac_addr, - config->config_table[0].lsb_mac_addr, BP_FUNC(bp), cl_bit_vec); - - mb(); - - bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, - U64_HI(bnx2x_sp_mapping(bp, mac_config)), - U64_LO(bnx2x_sp_mapping(bp, mac_config)), 1); - - /* Wait for a completion */ - bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, ramrod_flags); -} - -static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, +int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, int *state_p, int flags) { /* can take a while if any port is running */ @@ -6205,164 +5711,6 @@ void bnx2x_set_eth_mac(struct bnx2x *bp, int set) } } -static inline u8 bnx2x_e1_cam_mc_offset(struct bnx2x *bp) -{ - return CHIP_REV_IS_SLOW(bp) ? - (BNX2X_MAX_EMUL_MULTI * (1 + BP_PORT(bp))) : - (BNX2X_MAX_MULTICAST * (1 + BP_PORT(bp))); -} - -/* set mc list, do not wait as wait implies sleep and - * set_rx_mode can be invoked from non-sleepable context. - * - * Instead we use the same ramrod data buffer each time we need - * to configure a list of addresses, and use the fact that the - * list of MACs is changed in an incremental way and that the - * function is called under the netif_addr_lock. A temporary - * inconsistent CAM configuration (possible in case of a very fast - * sequence of add/del/add on the host side) will shortly be - * restored by the handler of the last ramrod. - */ -static int bnx2x_set_e1_mc_list(struct bnx2x *bp) -{ - int i = 0, old; - struct net_device *dev = bp->dev; - u8 offset = bnx2x_e1_cam_mc_offset(bp); - struct netdev_hw_addr *ha; - struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, mcast_config); - dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, mcast_config); - - if (netdev_mc_count(dev) > BNX2X_MAX_MULTICAST) - return -EINVAL; - - netdev_for_each_mc_addr(ha, dev) { - /* copy mac */ - config_cmd->config_table[i].msb_mac_addr = - swab16(*(u16 *)&bnx2x_mc_addr(ha)[0]); - config_cmd->config_table[i].middle_mac_addr = - swab16(*(u16 *)&bnx2x_mc_addr(ha)[2]); - config_cmd->config_table[i].lsb_mac_addr = - swab16(*(u16 *)&bnx2x_mc_addr(ha)[4]); - - config_cmd->config_table[i].vlan_id = 0; - config_cmd->config_table[i].pf_id = BP_FUNC(bp); - config_cmd->config_table[i].clients_bit_vector = - cpu_to_le32(1 << BP_L_ID(bp)); - - SET_FLAG(config_cmd->config_table[i].flags, - MAC_CONFIGURATION_ENTRY_ACTION_TYPE, - T_ETH_MAC_COMMAND_SET); - - DP(NETIF_MSG_IFUP, - "setting MCAST[%d] (%04x:%04x:%04x)\n", i, - config_cmd->config_table[i].msb_mac_addr, - config_cmd->config_table[i].middle_mac_addr, - config_cmd->config_table[i].lsb_mac_addr); - i++; - } - old = config_cmd->hdr.length; - if (old > i) { - for (; i < old; i++) { - if (CAM_IS_INVALID(config_cmd-> - config_table[i])) { - /* already invalidated */ - break; - } - /* invalidate */ - SET_FLAG(config_cmd->config_table[i].flags, - MAC_CONFIGURATION_ENTRY_ACTION_TYPE, - T_ETH_MAC_COMMAND_INVALIDATE); - } - } - - wmb(); - - config_cmd->hdr.length = i; - config_cmd->hdr.offset = offset; - config_cmd->hdr.client_id = 0xff; - /* Mark that this ramrod doesn't use bp->set_mac_pending for - * synchronization. - */ - config_cmd->hdr.echo = 0; - - mb(); - - return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, - U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1); -} - -void bnx2x_invalidate_e1_mc_list(struct bnx2x *bp) -{ - int i; - struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, mcast_config); - dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, mcast_config); - int ramrod_flags = WAIT_RAMROD_COMMON; - u8 offset = bnx2x_e1_cam_mc_offset(bp); - - for (i = 0; i < BNX2X_MAX_MULTICAST; i++) - SET_FLAG(config_cmd->config_table[i].flags, - MAC_CONFIGURATION_ENTRY_ACTION_TYPE, - T_ETH_MAC_COMMAND_INVALIDATE); - - wmb(); - - config_cmd->hdr.length = BNX2X_MAX_MULTICAST; - config_cmd->hdr.offset = offset; - config_cmd->hdr.client_id = 0xff; - /* We'll wait for a completion this time... */ - config_cmd->hdr.echo = 1; - - bp->set_mac_pending = 1; - - mb(); - - bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, - U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1); - - /* Wait for a completion */ - bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, - ramrod_flags); - -} - -/* Accept one or more multicasts */ -static int bnx2x_set_e1h_mc_list(struct bnx2x *bp) -{ - struct net_device *dev = bp->dev; - struct netdev_hw_addr *ha; - u32 mc_filter[MC_HASH_SIZE]; - u32 crc, bit, regidx; - int i; - - memset(mc_filter, 0, 4 * MC_HASH_SIZE); - - netdev_for_each_mc_addr(ha, dev) { - DP(NETIF_MSG_IFUP, "Adding mcast MAC: %pM\n", - bnx2x_mc_addr(ha)); - - crc = crc32c_le(0, bnx2x_mc_addr(ha), - ETH_ALEN); - bit = (crc >> 24) & 0xff; - regidx = bit >> 5; - bit &= 0x1f; - mc_filter[regidx] |= (1 << bit); - } - - for (i = 0; i < MC_HASH_SIZE; i++) - REG_WR(bp, MC_HASH_OFFSET(bp, i), - mc_filter[i]); - - return 0; -} - -void bnx2x_invalidate_e1h_mc_list(struct bnx2x *bp) -{ - int i; - - for (i = 0; i < MC_HASH_SIZE; i++) - REG_WR(bp, MC_HASH_OFFSET(bp, i), 0); -} - #ifdef BCM_CNIC /** * bnx2x_set_iscsi_eth_mac_addr - set iSCSI MAC(s). @@ -6434,172 +5782,6 @@ int bnx2x_set_all_enode_macs(struct bnx2x *bp, int set) } #endif -static void bnx2x_fill_cl_init_data(struct bnx2x *bp, - struct bnx2x_client_init_params *params, - u8 activate, - struct client_init_ramrod_data *data) -{ - /* Clear the buffer */ - memset(data, 0, sizeof(*data)); - - /* general */ - data->general.client_id = params->rxq_params.cl_id; - 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; - - /* Rx data */ - data->rx.tpa_en_flg = - (params->rxq_params.flags & QUEUE_FLG_TPA) ? 1 : 0; - data->rx.vmqueue_mode_en_flg = 0; - data->rx.cache_line_alignment_log_size = - params->rxq_params.cache_line_log; - data->rx.enable_dynamic_hc = - (params->rxq_params.flags & QUEUE_FLG_DHC) ? 1 : 0; - data->rx.max_sges_for_packet = params->rxq_params.max_sges_pkt; - data->rx.client_qzone_id = params->rxq_params.cl_qzone_id; - data->rx.max_agg_size = params->rxq_params.tpa_agg_sz; - - /* We don't set drop flags */ - data->rx.drop_ip_cs_err_flg = 0; - data->rx.drop_tcp_cs_err_flg = 0; - data->rx.drop_ttl0_flg = 0; - data->rx.drop_udp_cs_err_flg = 0; - - data->rx.inner_vlan_removal_enable_flg = - (params->rxq_params.flags & QUEUE_FLG_VLAN) ? 1 : 0; - data->rx.outer_vlan_removal_enable_flg = - (params->rxq_params.flags & QUEUE_FLG_OV) ? 1 : 0; - data->rx.status_block_id = params->rxq_params.fw_sb_id; - data->rx.rx_sb_index_number = params->rxq_params.sb_cq_index; - data->rx.bd_buff_size = cpu_to_le16(params->rxq_params.buf_sz); - data->rx.sge_buff_size = cpu_to_le16(params->rxq_params.sge_buf_sz); - data->rx.mtu = cpu_to_le16(params->rxq_params.mtu); - data->rx.bd_page_base.lo = - cpu_to_le32(U64_LO(params->rxq_params.dscr_map)); - data->rx.bd_page_base.hi = - cpu_to_le32(U64_HI(params->rxq_params.dscr_map)); - data->rx.sge_page_base.lo = - cpu_to_le32(U64_LO(params->rxq_params.sge_map)); - data->rx.sge_page_base.hi = - cpu_to_le32(U64_HI(params->rxq_params.sge_map)); - data->rx.cqe_page_base.lo = - cpu_to_le32(U64_LO(params->rxq_params.rcq_map)); - data->rx.cqe_page_base.hi = - cpu_to_le32(U64_HI(params->rxq_params.rcq_map)); - data->rx.is_leading_rss = - (params->ramrod_params.flags & CLIENT_IS_LEADING_RSS) ? 1 : 0; - data->rx.is_approx_mcast = data->rx.is_leading_rss; - - /* Tx data */ - data->tx.enforce_security_flg = 0; /* VF specific */ - data->tx.tx_status_block_id = params->txq_params.fw_sb_id; - data->tx.tx_sb_index_number = params->txq_params.sb_cq_index; - data->tx.mtu = 0; /* VF specific */ - data->tx.tx_bd_page_base.lo = - cpu_to_le32(U64_LO(params->txq_params.dscr_map)); - data->tx.tx_bd_page_base.hi = - cpu_to_le32(U64_HI(params->txq_params.dscr_map)); - - /* flow control data */ - data->fc.cqe_pause_thr_low = cpu_to_le16(params->pause.rcq_th_lo); - data->fc.cqe_pause_thr_high = cpu_to_le16(params->pause.rcq_th_hi); - data->fc.bd_pause_thr_low = cpu_to_le16(params->pause.bd_th_lo); - data->fc.bd_pause_thr_high = cpu_to_le16(params->pause.bd_th_hi); - data->fc.sge_pause_thr_low = cpu_to_le16(params->pause.sge_th_lo); - data->fc.sge_pause_thr_high = cpu_to_le16(params->pause.sge_th_hi); - data->fc.rx_cos_mask = cpu_to_le16(params->pause.pri_map); - - 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 = - (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) -{ - /* ustorm cxt validation */ - cxt->ustorm_ag_context.cdu_usage = - CDU_RSRVD_VALUE_TYPE_A(cid, CDU_REGION_NUMBER_UCM_AG, - ETH_CONNECTION_TYPE); - /* xcontext validation */ - cxt->xstorm_ag_context.cdu_reserved = - CDU_RSRVD_VALUE_TYPE_A(cid, CDU_REGION_NUMBER_XCM_AG, - ETH_CONNECTION_TYPE); -} - -static int bnx2x_setup_fw_client(struct bnx2x *bp, - struct bnx2x_client_init_params *params, - u8 activate, - struct client_init_ramrod_data *data, - dma_addr_t data_mapping) -{ - u16 hc_usec; - int ramrod = RAMROD_CMD_ID_ETH_CLIENT_SETUP; - int ramrod_flags = 0, rc; - - /* HC and context validation values */ - hc_usec = params->txq_params.hc_rate ? - 1000000 / params->txq_params.hc_rate : 0; - bnx2x_update_coalesce_sb_index(bp, - params->txq_params.fw_sb_id, - params->txq_params.sb_cq_index, - !(params->txq_params.flags & QUEUE_FLG_HC), - hc_usec); - - *(params->ramrod_params.pstate) = BNX2X_FP_STATE_OPENING; - - hc_usec = params->rxq_params.hc_rate ? - 1000000 / params->rxq_params.hc_rate : 0; - bnx2x_update_coalesce_sb_index(bp, - params->rxq_params.fw_sb_id, - params->rxq_params.sb_cq_index, - !(params->rxq_params.flags & QUEUE_FLG_HC), - hc_usec); - - bnx2x_set_ctx_validation(params->rxq_params.cxt, - params->rxq_params.cid); - - /* zero stats */ - if (params->txq_params.flags & QUEUE_FLG_STATS) - storm_memset_xstats_zero(bp, BP_PORT(bp), - params->txq_params.stat_id); - - if (params->rxq_params.flags & QUEUE_FLG_STATS) { - storm_memset_ustats_zero(bp, BP_PORT(bp), - params->rxq_params.stat_id); - storm_memset_tstats_zero(bp, BP_PORT(bp), - params->rxq_params.stat_id); - } - - /* Fill the ramrod data */ - bnx2x_fill_cl_init_data(bp, params, activate, data); - - /* SETUP ramrod. - * - * bnx2x_sp_post() takes a spin_lock thus no other explict memory - * barrier except from mmiowb() is needed to impose a - * proper ordering of memory operations. - */ - mmiowb(); - - - bnx2x_sp_post(bp, ramrod, params->ramrod_params.cid, - U64_HI(data_mapping), U64_LO(data_mapping), 0); - - /* Wait for completion */ - rc = bnx2x_wait_ramrod(bp, params->ramrod_params.state, - params->ramrod_params.index, - params->ramrod_params.pstate, - ramrod_flags); - return rc; -} /** * bnx2x_set_int_mode - configure interrupt mode diff --git a/drivers/net/bnx2x/bnx2x_sp.c b/drivers/net/bnx2x/bnx2x_sp.c new file mode 100644 index 0000000..7c876a0 --- /dev/null +++ b/drivers/net/bnx2x/bnx2x_sp.c @@ -0,0 +1,819 @@ +#include <linux/version.h> +#include <linux/module.h> +#include <linux/crc32.h> +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/crc32c.h> +#include "bnx2x.h" +#include "bnx2x_cmn.h" +#include "bnx2x_sp.h" + + +/** + * bnx2x_set_mac_addr_gen - set a MAC in a CAM for a few L2 Clients for E1x chips + * + * @bp: driver handle + * @set: set or clear an entry (1 or 0) + * @mac: pointer to a buffer containing a MAC + * @cl_bit_vec: bit vector of clients to register a MAC for + * @cam_offset: offset in a CAM to use + * @is_bcast: is the set MAC a broadcast address (for E1 only) + */ +void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, const u8 *mac, + u32 cl_bit_vec, u8 cam_offset, + u8 is_bcast) +{ + struct mac_configuration_cmd *config = + (struct mac_configuration_cmd *)bnx2x_sp(bp, mac_config); + int ramrod_flags = WAIT_RAMROD_COMMON; + + bp->set_mac_pending = 1; + + config->hdr.length = 1; + config->hdr.offset = cam_offset; + config->hdr.client_id = 0xff; + /* Mark the single MAC configuration ramrod as opposed to a + * UC/MC list configuration). + */ + config->hdr.echo = 1; + + /* primary MAC */ + config->config_table[0].msb_mac_addr = + swab16(*(u16 *)&mac[0]); + config->config_table[0].middle_mac_addr = + swab16(*(u16 *)&mac[2]); + config->config_table[0].lsb_mac_addr = + swab16(*(u16 *)&mac[4]); + config->config_table[0].clients_bit_vector = + cpu_to_le32(cl_bit_vec); + config->config_table[0].vlan_id = 0; + config->config_table[0].pf_id = BP_FUNC(bp); + if (set) + SET_FLAG(config->config_table[0].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_SET); + else + SET_FLAG(config->config_table[0].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_INVALIDATE); + + if (is_bcast) + SET_FLAG(config->config_table[0].flags, + MAC_CONFIGURATION_ENTRY_BROADCAST, 1); + + DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x) PF_ID %d CLID mask %d\n", + (set ? "setting" : "clearing"), + config->config_table[0].msb_mac_addr, + config->config_table[0].middle_mac_addr, + config->config_table[0].lsb_mac_addr, BP_FUNC(bp), cl_bit_vec); + + mb(); + + bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, + U64_HI(bnx2x_sp_mapping(bp, mac_config)), + U64_LO(bnx2x_sp_mapping(bp, mac_config)), 1); + + /* Wait for a completion */ + bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, ramrod_flags); +} + + +static inline u8 bnx2x_e1_cam_mc_offset(struct bnx2x *bp) +{ + return CHIP_REV_IS_SLOW(bp) ? + (BNX2X_MAX_EMUL_MULTI * (1 + BP_PORT(bp))) : + (BNX2X_MAX_MULTICAST * (1 + BP_PORT(bp))); +} + +/* set mc list, do not wait as wait implies sleep and + * set_rx_mode can be invoked from non-sleepable context. + * + * Instead we use the same ramrod data buffer each time we need + * to configure a list of addresses, and use the fact that the + * list of MACs is changed in an incremental way and that the + * function is called under the netif_addr_lock. A temporary + * inconsistent CAM configuration (possible in case of a very fast + * sequence of add/del/add on the host side) will shortly be + * restored by the handler of the last ramrod. + */ +int bnx2x_set_e1_mc_list(struct bnx2x *bp) +{ + int i = 0, old; + struct net_device *dev = bp->dev; + u8 offset = bnx2x_e1_cam_mc_offset(bp); + struct netdev_hw_addr *ha; + struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, mcast_config); + dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, mcast_config); + + if (netdev_mc_count(dev) > BNX2X_MAX_MULTICAST) + return -EINVAL; + + netdev_for_each_mc_addr(ha, dev) { + /* copy mac */ + config_cmd->config_table[i].msb_mac_addr = + swab16(*(u16 *)&bnx2x_mc_addr(ha)[0]); + config_cmd->config_table[i].middle_mac_addr = + swab16(*(u16 *)&bnx2x_mc_addr(ha)[2]); + config_cmd->config_table[i].lsb_mac_addr = + swab16(*(u16 *)&bnx2x_mc_addr(ha)[4]); + + config_cmd->config_table[i].vlan_id = 0; + config_cmd->config_table[i].pf_id = BP_FUNC(bp); + config_cmd->config_table[i].clients_bit_vector = + cpu_to_le32(1 << BP_L_ID(bp)); + + SET_FLAG(config_cmd->config_table[i].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_SET); + + DP(NETIF_MSG_IFUP, + "setting MCAST[%d] (%04x:%04x:%04x)\n", i, + config_cmd->config_table[i].msb_mac_addr, + config_cmd->config_table[i].middle_mac_addr, + config_cmd->config_table[i].lsb_mac_addr); + i++; + } + old = config_cmd->hdr.length; + if (old > i) { + for (; i < old; i++) { + if (CAM_IS_INVALID(config_cmd-> + config_table[i])) { + /* already invalidated */ + break; + } + /* invalidate */ + SET_FLAG(config_cmd->config_table[i].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_INVALIDATE); + } + } + + wmb(); + + config_cmd->hdr.length = i; + config_cmd->hdr.offset = offset; + config_cmd->hdr.client_id = 0xff; + /* Mark that this ramrod doesn't use bp->set_mac_pending for + * synchronization. + */ + config_cmd->hdr.echo = 0; + + mb(); + + return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, + U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1); +} + +void bnx2x_invalidate_e1_mc_list(struct bnx2x *bp) +{ + int i; + struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, mcast_config); + dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, mcast_config); + int ramrod_flags = WAIT_RAMROD_COMMON; + u8 offset = bnx2x_e1_cam_mc_offset(bp); + + for (i = 0; i < BNX2X_MAX_MULTICAST; i++) + SET_FLAG(config_cmd->config_table[i].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_INVALIDATE); + + wmb(); + + config_cmd->hdr.length = BNX2X_MAX_MULTICAST; + config_cmd->hdr.offset = offset; + config_cmd->hdr.client_id = 0xff; + /* We'll wait for a completion this time... */ + config_cmd->hdr.echo = 1; + + bp->set_mac_pending = 1; + + mb(); + + bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, + U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1); + + /* Wait for a completion */ + bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, + ramrod_flags); + +} + +/* Accept one or more multicasts */ +int bnx2x_set_e1h_mc_list(struct bnx2x *bp) +{ + struct net_device *dev = bp->dev; + struct netdev_hw_addr *ha; + u32 mc_filter[MC_HASH_SIZE]; + u32 crc, bit, regidx; + int i; + + memset(mc_filter, 0, 4 * MC_HASH_SIZE); + + netdev_for_each_mc_addr(ha, dev) { + DP(NETIF_MSG_IFUP, "Adding mcast MAC: %pM\n", + bnx2x_mc_addr(ha)); + + crc = crc32c_le(0, bnx2x_mc_addr(ha), + ETH_ALEN); + bit = (crc >> 24) & 0xff; + regidx = bit >> 5; + bit &= 0x1f; + mc_filter[regidx] |= (1 << bit); + } + + for (i = 0; i < MC_HASH_SIZE; i++) + REG_WR(bp, MC_HASH_OFFSET(bp, i), + mc_filter[i]); + + return 0; +} + +void bnx2x_invalidate_e1h_mc_list(struct bnx2x *bp) +{ + int i; + + for (i = 0; i < MC_HASH_SIZE; i++) + REG_WR(bp, MC_HASH_OFFSET(bp, i), 0); +} + +/* must be called under rtnl_lock */ +void bnx2x_rxq_set_mac_filters(struct bnx2x *bp, u16 cl_id, u32 filters) +{ + u32 mask = (1 << cl_id); + + /* initial seeting is BNX2X_ACCEPT_NONE */ + u8 drop_all_ucast = 1, drop_all_bcast = 1, drop_all_mcast = 1; + 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 */ + drop_all_ucast = 0; + } + if (filters & BNX2X_ACCEPT_MULTICAST) + /* accept matched mcast */ + drop_all_mcast = 0; + + if (filters & BNX2X_ACCEPT_ALL_UNICAST) { + /* accept all mcast */ + drop_all_ucast = 0; + accp_all_ucast = 1; + } + if (filters & BNX2X_ACCEPT_ALL_MULTICAST) { + /* accept all mcast */ + drop_all_mcast = 0; + accp_all_mcast = 1; + } + if (filters & BNX2X_ACCEPT_BROADCAST) { + /* accept (all) bcast */ + drop_all_bcast = 0; + accp_all_bcast = 1; + } + + bp->mac_filters.ucast_drop_all = drop_all_ucast ? + bp->mac_filters.ucast_drop_all | mask : + bp->mac_filters.ucast_drop_all & ~mask; + + bp->mac_filters.mcast_drop_all = drop_all_mcast ? + bp->mac_filters.mcast_drop_all | mask : + bp->mac_filters.mcast_drop_all & ~mask; + + bp->mac_filters.bcast_drop_all = drop_all_bcast ? + bp->mac_filters.bcast_drop_all | mask : + bp->mac_filters.bcast_drop_all & ~mask; + + bp->mac_filters.ucast_accept_all = accp_all_ucast ? + bp->mac_filters.ucast_accept_all | mask : + bp->mac_filters.ucast_accept_all & ~mask; + + bp->mac_filters.mcast_accept_all = accp_all_mcast ? + bp->mac_filters.mcast_accept_all | mask : + bp->mac_filters.mcast_accept_all & ~mask; + + bp->mac_filters.bcast_accept_all = accp_all_bcast ? + bp->mac_filters.bcast_accept_all | mask : + bp->mac_filters.bcast_accept_all & ~mask; + + bp->mac_filters.unmatched_unicast = unmatched_unicast ? + bp->mac_filters.unmatched_unicast | mask : + bp->mac_filters.unmatched_unicast & ~mask; +} + +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 = + NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_BRCST | + NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_MLCST | + NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_VLAN | + NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_NO_VLAN; + + switch (mode) { + case BNX2X_RX_MODE_NONE: /* no Rx */ + 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: + def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST | + BNX2X_ACCEPT_MULTICAST; +#ifdef BCM_CNIC + if (!NO_FCOE(bp)) { + 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: + def_q_filters |= BNX2X_ACCEPT_UNICAST | BNX2X_ACCEPT_BROADCAST | + BNX2X_ACCEPT_ALL_MULTICAST; +#ifdef BCM_CNIC + /* + * Prevent duplication of multicast packets by configuring FCoE + * L2 Client to receive only matched unicast frames. + */ + if (!NO_FCOE(bp)) { + cl_id = bnx2x_fcoe(bp, cl_id); + bnx2x_rxq_set_mac_filters(bp, cl_id, + BNX2X_ACCEPT_UNICAST); + } +#endif + break; + + case BNX2X_RX_MODE_PROMISC: + def_q_filters |= BNX2X_PROMISCUOUS_MODE; +#ifdef BCM_CNIC + /* + * Prevent packets duplication by configuring DROP_ALL for FCoE + * L2 Client. + */ + if (!NO_FCOE(bp)) { + cl_id = bnx2x_fcoe(bp, cl_id); + bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_NONE); + } +#endif + /* pass management unicast packets as well */ + llh_mask |= NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST; + break; + + default: + BNX2X_ERR("BAD rx mode (%d)\n", mode); + break; + } + + cl_id = BP_L_ID(bp); + bnx2x_rxq_set_mac_filters(bp, cl_id, def_q_filters); + + REG_WR(bp, + (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" + "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.unmatched_unicast + ); + + storm_memset_mac_filters(bp, &bp->mac_filters, BP_FUNC(bp)); +} + +/* RSS configuration */ +static inline void __storm_memset_dma_mapping(struct bnx2x *bp, + u32 addr, dma_addr_t mapping) +{ + REG_WR(bp, addr, U64_LO(mapping)); + REG_WR(bp, addr + 4, U64_HI(mapping)); +} + +static inline void __storm_fill(struct bnx2x *bp, + u32 addr, size_t size, u32 val) +{ + int i; + for (i = 0; i < size/4; i++) + REG_WR(bp, addr + (i * 4), val); +} + +static inline void storm_memset_ustats_zero(struct bnx2x *bp, + u8 port, u16 stat_id) +{ + size_t size = sizeof(struct ustorm_per_client_stats); + + u32 addr = BAR_USTRORM_INTMEM + + USTORM_PER_COUNTER_ID_STATS_OFFSET(port, stat_id); + + __storm_fill(bp, addr, size, 0); +} + +static inline void storm_memset_tstats_zero(struct bnx2x *bp, + u8 port, u16 stat_id) +{ + size_t size = sizeof(struct tstorm_per_client_stats); + + u32 addr = BAR_TSTRORM_INTMEM + + TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stat_id); + + __storm_fill(bp, addr, size, 0); +} + +static inline void storm_memset_xstats_zero(struct bnx2x *bp, + u8 port, u16 stat_id) +{ + size_t size = sizeof(struct xstorm_per_client_stats); + + u32 addr = BAR_XSTRORM_INTMEM + + XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stat_id); + + __storm_fill(bp, addr, size, 0); +} + + +static inline void storm_memset_spq_addr(struct bnx2x *bp, + dma_addr_t mapping, u16 abs_fid) +{ + u32 addr = XSEM_REG_FAST_MEMORY + + XSTORM_SPQ_PAGE_BASE_OFFSET(abs_fid); + + __storm_memset_dma_mapping(bp, addr, mapping); +} + +static inline void storm_memset_xstats_flags(struct bnx2x *bp, + struct stats_indication_flags *flags, + u16 abs_fid) +{ + size_t size = sizeof(struct stats_indication_flags); + + u32 addr = BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(abs_fid); + + __storm_memset_struct(bp, addr, size, (u32 *)flags); +} + +static inline void storm_memset_tstats_flags(struct bnx2x *bp, + struct stats_indication_flags *flags, + u16 abs_fid) +{ + size_t size = sizeof(struct stats_indication_flags); + + u32 addr = BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(abs_fid); + + __storm_memset_struct(bp, addr, size, (u32 *)flags); +} + +static inline void storm_memset_ustats_flags(struct bnx2x *bp, + struct stats_indication_flags *flags, + u16 abs_fid) +{ + size_t size = sizeof(struct stats_indication_flags); + + u32 addr = BAR_USTRORM_INTMEM + USTORM_STATS_FLAGS_OFFSET(abs_fid); + + __storm_memset_struct(bp, addr, size, (u32 *)flags); +} + +static inline void storm_memset_cstats_flags(struct bnx2x *bp, + struct stats_indication_flags *flags, + u16 abs_fid) +{ + size_t size = sizeof(struct stats_indication_flags); + + u32 addr = BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(abs_fid); + + __storm_memset_struct(bp, addr, size, (u32 *)flags); +} + +static inline void storm_memset_xstats_addr(struct bnx2x *bp, + dma_addr_t mapping, u16 abs_fid) +{ + u32 addr = BAR_XSTRORM_INTMEM + + XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); + + __storm_memset_dma_mapping(bp, addr, mapping); +} + +static inline void storm_memset_tstats_addr(struct bnx2x *bp, + dma_addr_t mapping, u16 abs_fid) +{ + u32 addr = BAR_TSTRORM_INTMEM + + TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); + + __storm_memset_dma_mapping(bp, addr, mapping); +} + +static inline void storm_memset_ustats_addr(struct bnx2x *bp, + dma_addr_t mapping, u16 abs_fid) +{ + u32 addr = BAR_USTRORM_INTMEM + + USTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); + + __storm_memset_dma_mapping(bp, addr, mapping); +} + +static inline void storm_memset_cstats_addr(struct bnx2x *bp, + dma_addr_t mapping, u16 abs_fid) +{ + u32 addr = BAR_CSTRORM_INTMEM + + CSTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); + + __storm_memset_dma_mapping(bp, addr, mapping); +} + +static inline void storm_memset_vf_to_pf(struct bnx2x *bp, u16 abs_fid, + u16 pf_id) +{ + REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_VF_TO_PF_OFFSET(abs_fid), + pf_id); + REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_VF_TO_PF_OFFSET(abs_fid), + pf_id); + REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_VF_TO_PF_OFFSET(abs_fid), + pf_id); + REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_VF_TO_PF_OFFSET(abs_fid), + pf_id); +} + +static inline void storm_memset_func_en(struct bnx2x *bp, u16 abs_fid, + u8 enable) +{ + REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNC_EN_OFFSET(abs_fid), + enable); + REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_FUNC_EN_OFFSET(abs_fid), + enable); + REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_FUNC_EN_OFFSET(abs_fid), + enable); + REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_FUNC_EN_OFFSET(abs_fid), + enable); +} + +static inline void storm_memset_func_cfg(struct bnx2x *bp, + struct tstorm_eth_function_common_config *tcfg, + u16 abs_fid) +{ + size_t size = sizeof(struct tstorm_eth_function_common_config); + + u32 addr = BAR_TSTRORM_INTMEM + + TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(abs_fid); + + __storm_memset_struct(bp, addr, size, (u32 *)tcfg); +} + +void bnx2x_func_init(struct bnx2x *bp, struct bnx2x_func_init_params *p) +{ + struct tstorm_eth_function_common_config tcfg = {0}; + u16 rss_flgs; + + /* tpa */ + if (p->func_flgs & FUNC_FLG_TPA) + tcfg.config_flags |= + TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA; + + /* set rss flags */ + rss_flgs = (p->rss->mode << + TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT); + + if (p->rss->cap & RSS_IPV4_CAP) + rss_flgs |= RSS_IPV4_CAP_MASK; + if (p->rss->cap & RSS_IPV4_TCP_CAP) + rss_flgs |= RSS_IPV4_TCP_CAP_MASK; + if (p->rss->cap & RSS_IPV6_CAP) + rss_flgs |= RSS_IPV6_CAP_MASK; + if (p->rss->cap & RSS_IPV6_TCP_CAP) + rss_flgs |= RSS_IPV6_TCP_CAP_MASK; + + tcfg.config_flags |= rss_flgs; + tcfg.rss_result_mask = p->rss->result_mask; + + storm_memset_func_cfg(bp, &tcfg, p->func_id); + + /* Enable the function in the FW */ + storm_memset_vf_to_pf(bp, p->func_id, p->pf_id); + storm_memset_func_en(bp, p->func_id, 1); + + /* statistics */ + if (p->func_flgs & FUNC_FLG_STATS) { + struct stats_indication_flags stats_flags = {0}; + stats_flags.collect_eth = 1; + + storm_memset_xstats_flags(bp, &stats_flags, p->func_id); + storm_memset_xstats_addr(bp, p->fw_stat_map, p->func_id); + + storm_memset_tstats_flags(bp, &stats_flags, p->func_id); + storm_memset_tstats_addr(bp, p->fw_stat_map, p->func_id); + + storm_memset_ustats_flags(bp, &stats_flags, p->func_id); + storm_memset_ustats_addr(bp, p->fw_stat_map, p->func_id); + + storm_memset_cstats_flags(bp, &stats_flags, p->func_id); + storm_memset_cstats_addr(bp, p->fw_stat_map, p->func_id); + } + + /* spq */ + if (p->func_flgs & FUNC_FLG_SPQ) { + storm_memset_spq_addr(bp, p->spq_map, p->func_id); + REG_WR(bp, XSEM_REG_FAST_MEMORY + + XSTORM_SPQ_PROD_OFFSET(p->func_id), p->spq_prod); + } +} + +static void bnx2x_fill_cl_init_data(struct bnx2x *bp, + struct bnx2x_client_init_params *params, + u8 activate, + struct client_init_ramrod_data *data) +{ + /* Clear the buffer */ + memset(data, 0, sizeof(*data)); + + /* general */ + data->general.client_id = params->rxq_params.cl_id; + 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; + + /* Rx data */ + data->rx.tpa_en_flg = + (params->rxq_params.flags & QUEUE_FLG_TPA) ? 1 : 0; + data->rx.vmqueue_mode_en_flg = 0; + data->rx.cache_line_alignment_log_size = + params->rxq_params.cache_line_log; + data->rx.enable_dynamic_hc = + (params->rxq_params.flags & QUEUE_FLG_DHC) ? 1 : 0; + data->rx.max_sges_for_packet = params->rxq_params.max_sges_pkt; + data->rx.client_qzone_id = params->rxq_params.cl_qzone_id; + data->rx.max_agg_size = params->rxq_params.tpa_agg_sz; + + /* We don't set drop flags */ + data->rx.drop_ip_cs_err_flg = 0; + data->rx.drop_tcp_cs_err_flg = 0; + data->rx.drop_ttl0_flg = 0; + data->rx.drop_udp_cs_err_flg = 0; + + data->rx.inner_vlan_removal_enable_flg = + (params->rxq_params.flags & QUEUE_FLG_VLAN) ? 1 : 0; + data->rx.outer_vlan_removal_enable_flg = + (params->rxq_params.flags & QUEUE_FLG_OV) ? 1 : 0; + data->rx.status_block_id = params->rxq_params.fw_sb_id; + data->rx.rx_sb_index_number = params->rxq_params.sb_cq_index; + data->rx.bd_buff_size = cpu_to_le16(params->rxq_params.buf_sz); + data->rx.sge_buff_size = cpu_to_le16(params->rxq_params.sge_buf_sz); + data->rx.mtu = cpu_to_le16(params->rxq_params.mtu); + data->rx.bd_page_base.lo = + cpu_to_le32(U64_LO(params->rxq_params.dscr_map)); + data->rx.bd_page_base.hi = + cpu_to_le32(U64_HI(params->rxq_params.dscr_map)); + data->rx.sge_page_base.lo = + cpu_to_le32(U64_LO(params->rxq_params.sge_map)); + data->rx.sge_page_base.hi = + cpu_to_le32(U64_HI(params->rxq_params.sge_map)); + data->rx.cqe_page_base.lo = + cpu_to_le32(U64_LO(params->rxq_params.rcq_map)); + data->rx.cqe_page_base.hi = + cpu_to_le32(U64_HI(params->rxq_params.rcq_map)); + data->rx.is_leading_rss = + (params->ramrod_params.flags & CLIENT_IS_LEADING_RSS) ? 1 : 0; + data->rx.is_approx_mcast = data->rx.is_leading_rss; + + /* Tx data */ + data->tx.enforce_security_flg = 0; /* VF specific */ + data->tx.tx_status_block_id = params->txq_params.fw_sb_id; + data->tx.tx_sb_index_number = params->txq_params.sb_cq_index; + data->tx.mtu = 0; /* VF specific */ + data->tx.tx_bd_page_base.lo = + cpu_to_le32(U64_LO(params->txq_params.dscr_map)); + data->tx.tx_bd_page_base.hi = + cpu_to_le32(U64_HI(params->txq_params.dscr_map)); + + /* flow control data */ + data->fc.cqe_pause_thr_low = cpu_to_le16(params->pause.rcq_th_lo); + data->fc.cqe_pause_thr_high = cpu_to_le16(params->pause.rcq_th_hi); + data->fc.bd_pause_thr_low = cpu_to_le16(params->pause.bd_th_lo); + data->fc.bd_pause_thr_high = cpu_to_le16(params->pause.bd_th_hi); + data->fc.sge_pause_thr_low = cpu_to_le16(params->pause.sge_th_lo); + data->fc.sge_pause_thr_high = cpu_to_le16(params->pause.sge_th_hi); + data->fc.rx_cos_mask = cpu_to_le16(params->pause.pri_map); + + 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 = + (params->ramrod_params.flags & CLIENT_IS_FCOE) ? + LLFC_TRAFFIC_TYPE_FCOE : LLFC_TRAFFIC_TYPE_NW; +} + + +int bnx2x_setup_fw_client(struct bnx2x *bp, + struct bnx2x_client_init_params *params, + u8 activate, + struct client_init_ramrod_data *data, + dma_addr_t data_mapping) +{ + u16 hc_usec; + int ramrod = RAMROD_CMD_ID_ETH_CLIENT_SETUP; + int ramrod_flags = 0, rc; + + /* HC and context validation values */ + hc_usec = params->txq_params.hc_rate ? + 1000000 / params->txq_params.hc_rate : 0; + bnx2x_update_coalesce_sb_index(bp, + params->txq_params.fw_sb_id, + params->txq_params.sb_cq_index, + !(params->txq_params.flags & QUEUE_FLG_HC), + hc_usec); + + *(params->ramrod_params.pstate) = BNX2X_FP_STATE_OPENING; + + hc_usec = params->rxq_params.hc_rate ? + 1000000 / params->rxq_params.hc_rate : 0; + bnx2x_update_coalesce_sb_index(bp, + params->rxq_params.fw_sb_id, + params->rxq_params.sb_cq_index, + !(params->rxq_params.flags & QUEUE_FLG_HC), + hc_usec); + + bnx2x_set_ctx_validation(params->rxq_params.cxt, + params->rxq_params.cid); + + /* zero stats */ + if (params->txq_params.flags & QUEUE_FLG_STATS) + storm_memset_xstats_zero(bp, BP_PORT(bp), + params->txq_params.stat_id); + + if (params->rxq_params.flags & QUEUE_FLG_STATS) { + storm_memset_ustats_zero(bp, BP_PORT(bp), + params->rxq_params.stat_id); + storm_memset_tstats_zero(bp, BP_PORT(bp), + params->rxq_params.stat_id); + } + + /* Fill the ramrod data */ + bnx2x_fill_cl_init_data(bp, params, activate, data); + + /* SETUP ramrod. + * + * bnx2x_sp_post() takes a spin_lock thus no other explict memory + * barrier except from mmiowb() is needed to impose a + * proper ordering of memory operations. + */ + mmiowb(); + + + bnx2x_sp_post(bp, ramrod, params->ramrod_params.cid, + U64_HI(data_mapping), U64_LO(data_mapping), 0); + + /* Wait for completion */ + rc = bnx2x_wait_ramrod(bp, params->ramrod_params.state, + params->ramrod_params.index, + params->ramrod_params.pstate, + ramrod_flags); + return rc; +} + +void bnx2x_push_indir_table(struct bnx2x *bp) +{ + int func = BP_FUNC(bp); + int i; + + if (bp->multi_mode == ETH_RSS_MODE_DISABLED) + return; + + 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 + bp->rx_indir_table[i]); +} diff --git a/drivers/net/bnx2x/bnx2x_sp.h b/drivers/net/bnx2x/bnx2x_sp.h new file mode 100644 index 0000000..f9b755e --- /dev/null +++ b/drivers/net/bnx2x/bnx2x_sp.h @@ -0,0 +1,43 @@ +#ifndef BNX2X_SP +#define BNX2X_SP + +#include "bnx2x_reg.h" + +/* MAC configuration */ +void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, const u8 *mac, + u32 cl_bit_vec, u8 cam_offset, + u8 is_bcast); + +/* Multicast */ +void bnx2x_invalidate_e1_mc_list(struct bnx2x *bp); +void bnx2x_invalidate_e1h_mc_list(struct bnx2x *bp); +int bnx2x_set_e1_mc_list(struct bnx2x *bp); +int bnx2x_set_e1h_mc_list(struct bnx2x *bp); + +/* Rx mode */ +void bnx2x_set_storm_rx_mode(struct bnx2x *bp); +void bnx2x_rxq_set_mac_filters(struct bnx2x *bp, u16 cl_id, u32 filters); + +/* RSS configuration */ +void bnx2x_func_init(struct bnx2x *bp, struct bnx2x_func_init_params *p); +void bnx2x_push_indir_table(struct bnx2x *bp); + +/* Queue configuration */ +static inline void bnx2x_set_ctx_validation(struct eth_context *cxt, u32 cid) +{ + /* ustorm cxt validation */ + cxt->ustorm_ag_context.cdu_usage = + CDU_RSRVD_VALUE_TYPE_A(cid, CDU_REGION_NUMBER_UCM_AG, + ETH_CONNECTION_TYPE); + /* xcontext validation */ + cxt->xstorm_ag_context.cdu_reserved = + CDU_RSRVD_VALUE_TYPE_A(cid, CDU_REGION_NUMBER_XCM_AG, + ETH_CONNECTION_TYPE); +} + +int bnx2x_setup_fw_client(struct bnx2x *bp, + struct bnx2x_client_init_params *params, + u8 activate, + struct client_init_ramrod_data *data, + dma_addr_t data_mapping); +#endif /* BNX2X_SP */ |