]> git.proxmox.com Git - mirror_ubuntu-disco-kernel.git/commitdiff
bnx2x: Created bnx2x_sp
authorVladislav Zolotarov <vladz@broadcom.com>
Tue, 14 Jun 2011 01:33:39 +0000 (01:33 +0000)
committerDavid S. Miller <davem@conan.davemloft.net>
Wed, 15 Jun 2011 14:56:15 +0000 (10:56 -0400)
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>
drivers/net/bnx2x/Makefile
drivers/net/bnx2x/bnx2x.h
drivers/net/bnx2x/bnx2x_cmn.c
drivers/net/bnx2x/bnx2x_cmn.h
drivers/net/bnx2x/bnx2x_ethtool.c
drivers/net/bnx2x/bnx2x_main.c
drivers/net/bnx2x/bnx2x_sp.c [new file with mode: 0644]
drivers/net/bnx2x/bnx2x_sp.h [new file with mode: 0644]

index bb83a296127386abd98718c056bd267d1a84944a..48fbdd48f88f9fcf5a9d3b35f60b250fa45cb329 100644 (file)
@@ -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
index 3cf0768c890e6a6b6dc9d5019bc942d2ac63add9..6d4d6d4e53c6aa43626b401250530b3b241bc2e7 100644 (file)
@@ -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 */
index ed1d695b1777cc5c1fe014c3d57a51e7dee4bf9b..c72e1df0472841a23f46a5ca1c65fb25721a7084 100644 (file)
@@ -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);
 
index 57d9354da617a2247ebca1e4e9377f633cefb7a7..5a97f92b340c6ebc90301fede2d0cef031c019e5 100644 (file)
@@ -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.
  *
index ddb99a9a803d489b0d105f0836f3b94c7818386f..7a133052660a4f88dcc2612dd388b9bcf85f1236 100644 (file)
@@ -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
index d7cab0dc57f86b92481f23febf175bdf86a13689..84f419fcde267407c89b1c67bc0454f7bf21c4bd 100644 (file)
@@ -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 (file)
index 0000000..7c876a0
--- /dev/null
@@ -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 (file)
index 0000000..f9b755e
--- /dev/null
@@ -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 */