qed: Correct Multicast API to reflect existence of 256 approximate buckets.
authorSudarsana Reddy Kalluru <sudarsana.kalluru@cavium.com>
Thu, 19 Jul 2018 05:50:04 +0000 (22:50 -0700)
committerDavid S. Miller <davem@davemloft.net>
Sat, 21 Jul 2018 23:19:04 +0000 (16:19 -0700)
FW hsi contains 256 approximation buckets which are split in ramrod into
eight u32 values, but driver is using eight 'unsigned long' variables.

This patch fixes the mcast logic by making the API utilize u32.

Fixes: 83aeb933 ("qed*: Trivial modifications")
Signed-off-by: Sudarsana Reddy Kalluru <Sudarsana.Kalluru@cavium.com>
Signed-off-by: Ariel Elior <ariel.elior@cavium.com>
Signed-off-by: Michal Kalderon <Michal.Kalderon@cavium.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/qlogic/qed/qed_l2.c
drivers/net/ethernet/qlogic/qed/qed_l2.h
drivers/net/ethernet/qlogic/qed/qed_sriov.c
drivers/net/ethernet/qlogic/qed/qed_vf.c
drivers/net/ethernet/qlogic/qed/qed_vf.h

index 99973e10b17977561be6536fee84cf2901622c3e..5ede6408649d66c25c85a25f0c9337feeb428670 100644 (file)
@@ -665,7 +665,7 @@ qed_sp_update_mcast_bin(struct qed_hwfn *p_hwfn,
 
        p_ramrod->common.update_approx_mcast_flg = 1;
        for (i = 0; i < ETH_MULTICAST_MAC_BINS_IN_REGS; i++) {
-               u32 *p_bins = (u32 *)p_params->bins;
+               u32 *p_bins = p_params->bins;
 
                p_ramrod->approx_mcast.bins[i] = cpu_to_le32(p_bins[i]);
        }
@@ -1476,8 +1476,8 @@ qed_sp_eth_filter_mcast(struct qed_hwfn *p_hwfn,
                        enum spq_mode comp_mode,
                        struct qed_spq_comp_cb *p_comp_data)
 {
-       unsigned long bins[ETH_MULTICAST_MAC_BINS_IN_REGS];
        struct vport_update_ramrod_data *p_ramrod = NULL;
+       u32 bins[ETH_MULTICAST_MAC_BINS_IN_REGS];
        struct qed_spq_entry *p_ent = NULL;
        struct qed_sp_init_data init_data;
        u8 abs_vport_id = 0;
@@ -1513,26 +1513,25 @@ qed_sp_eth_filter_mcast(struct qed_hwfn *p_hwfn,
        /* explicitly clear out the entire vector */
        memset(&p_ramrod->approx_mcast.bins, 0,
               sizeof(p_ramrod->approx_mcast.bins));
-       memset(bins, 0, sizeof(unsigned long) *
-              ETH_MULTICAST_MAC_BINS_IN_REGS);
+       memset(bins, 0, sizeof(bins));
        /* filter ADD op is explicit set op and it removes
         *  any existing filters for the vport
         */
        if (p_filter_cmd->opcode == QED_FILTER_ADD) {
                for (i = 0; i < p_filter_cmd->num_mc_addrs; i++) {
-                       u32 bit;
+                       u32 bit, nbits;
 
                        bit = qed_mcast_bin_from_mac(p_filter_cmd->mac[i]);
-                       __set_bit(bit, bins);
+                       nbits = sizeof(u32) * BITS_PER_BYTE;
+                       bins[bit / nbits] |= 1 << (bit % nbits);
                }
 
                /* Convert to correct endianity */
                for (i = 0; i < ETH_MULTICAST_MAC_BINS_IN_REGS; i++) {
                        struct vport_update_ramrod_mcast *p_ramrod_bins;
-                       u32 *p_bins = (u32 *)bins;
 
                        p_ramrod_bins = &p_ramrod->approx_mcast;
-                       p_ramrod_bins->bins[i] = cpu_to_le32(p_bins[i]);
+                       p_ramrod_bins->bins[i] = cpu_to_le32(bins[i]);
                }
        }
 
index 806a8da257e9a48cd553c6d173fc69300917391e..8d80f1095d171c85b7d010bb5297a58a1961808d 100644 (file)
@@ -215,7 +215,7 @@ struct qed_sp_vport_update_params {
        u8                              anti_spoofing_en;
        u8                              update_accept_any_vlan_flg;
        u8                              accept_any_vlan;
-       unsigned long                   bins[8];
+       u32                             bins[8];
        struct qed_rss_params           *rss_params;
        struct qed_filter_accept_flags  accept_flags;
        struct qed_sge_tpa_params       *sge_tpa_params;
index fd59cf45f4be8cb008d8728398870cc1ab41210b..26e918d7f2f9c0603ab6b0f2f132daba6d7bcc3b 100644 (file)
@@ -2831,7 +2831,7 @@ qed_iov_vp_update_mcast_bin_param(struct qed_hwfn *p_hwfn,
 
        p_data->update_approx_mcast_flg = 1;
        memcpy(p_data->bins, p_mcast_tlv->bins,
-              sizeof(unsigned long) * ETH_MULTICAST_MAC_BINS_IN_REGS);
+              sizeof(u32) * ETH_MULTICAST_MAC_BINS_IN_REGS);
        *tlvs_mask |= 1 << QED_IOV_VP_UPDATE_MCAST;
 }
 
index 2d7fcd6a0777aa264b8e228d14eae3cc0e2d212d..be6ddde1a104ff34050ee72b7dc5bc40658e6c2b 100644 (file)
@@ -1126,7 +1126,7 @@ int qed_vf_pf_vport_update(struct qed_hwfn *p_hwfn,
                resp_size += sizeof(struct pfvf_def_resp_tlv);
 
                memcpy(p_mcast_tlv->bins, p_params->bins,
-                      sizeof(unsigned long) * ETH_MULTICAST_MAC_BINS_IN_REGS);
+                      sizeof(u32) * ETH_MULTICAST_MAC_BINS_IN_REGS);
        }
 
        update_rx = p_params->accept_flags.update_rx_mode_config;
@@ -1272,7 +1272,7 @@ void qed_vf_pf_filter_mcast(struct qed_hwfn *p_hwfn,
                        u32 bit;
 
                        bit = qed_mcast_bin_from_mac(p_filter_cmd->mac[i]);
-                       __set_bit(bit, sp_params.bins);
+                       sp_params.bins[bit / 32] |= 1 << (bit % 32);
                }
        }
 
index 4f05d5eb3cf50ae51298a1711f2a850bcac1fe93..033409db86ae7bbbe63b79f80490bd2857abfe7c 100644 (file)
@@ -392,7 +392,12 @@ struct vfpf_vport_update_mcast_bin_tlv {
        struct channel_tlv tl;
        u8 padding[4];
 
-       u64 bins[8];
+       /* There are only 256 approx bins, and in HSI they're divided into
+        * 32-bit values. As old VFs used to set-bit to the values on its side,
+        * the upper half of the array is never expected to contain any data.
+        */
+       u64 bins[4];
+       u64 obsolete_bins[4];
 };
 
 struct vfpf_vport_update_accept_param_tlv {