| From foo@baz Sun Aug 26 09:13:00 CEST 2018 |
| From: Sudarsana Reddy Kalluru <sudarsana.kalluru@cavium.com> |
| Date: Wed, 18 Jul 2018 22:50:04 -0700 |
| Subject: qed: Correct Multicast API to reflect existence of 256 approximate buckets. |
| |
| From: Sudarsana Reddy Kalluru <sudarsana.kalluru@cavium.com> |
| |
| [ Upstream commit 25c020a90919632b3425c19dc09188d56b9ed59a ] |
| |
| 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> |
| Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/net/ethernet/qlogic/qed/qed_l2.c | 15 +++++++-------- |
| drivers/net/ethernet/qlogic/qed/qed_l2.h | 2 +- |
| drivers/net/ethernet/qlogic/qed/qed_sriov.c | 2 +- |
| drivers/net/ethernet/qlogic/qed/qed_vf.c | 4 ++-- |
| drivers/net/ethernet/qlogic/qed/qed_vf.h | 7 ++++++- |
| 5 files changed, 17 insertions(+), 13 deletions(-) |
| |
| --- a/drivers/net/ethernet/qlogic/qed/qed_l2.c |
| +++ b/drivers/net/ethernet/qlogic/qed/qed_l2.c |
| @@ -663,7 +663,7 @@ qed_sp_update_mcast_bin(struct qed_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]); |
| } |
| @@ -1474,8 +1474,8 @@ qed_sp_eth_filter_mcast(struct qed_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; |
| @@ -1511,26 +1511,25 @@ qed_sp_eth_filter_mcast(struct qed_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]); |
| } |
| } |
| |
| --- a/drivers/net/ethernet/qlogic/qed/qed_l2.h |
| +++ b/drivers/net/ethernet/qlogic/qed/qed_l2.h |
| @@ -214,7 +214,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; |
| --- a/drivers/net/ethernet/qlogic/qed/qed_sriov.c |
| +++ b/drivers/net/ethernet/qlogic/qed/qed_sriov.c |
| @@ -2826,7 +2826,7 @@ qed_iov_vp_update_mcast_bin_param(struct |
| |
| 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; |
| } |
| |
| --- a/drivers/net/ethernet/qlogic/qed/qed_vf.c |
| +++ b/drivers/net/ethernet/qlogic/qed/qed_vf.c |
| @@ -1126,7 +1126,7 @@ int qed_vf_pf_vport_update(struct qed_hw |
| 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_h |
| 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); |
| } |
| } |
| |
| --- a/drivers/net/ethernet/qlogic/qed/qed_vf.h |
| +++ b/drivers/net/ethernet/qlogic/qed/qed_vf.h |
| @@ -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 { |