diff options
author | David S. Miller <davem@davemloft.net> | 2018-04-11 14:42:00 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-04-11 14:42:00 -0400 |
commit | 9cf74f593aa728ea4ed1760b74f31c02c4dd777b (patch) | |
tree | 40224fb747b9e4a9733c6a4874815eff998da672 | |
parent | 949989b36c2261125a7d01a4ca3d5b5ee64da05c (diff) | |
parent | cb98526bf9b985866d648dbb9c983ba9eb59daba (diff) |
Merge branch 'bnxt_en-Fixes-for-net'
Michael Chan says:
====================
bnxt_en: Fixes for net.
This bug fix series include NULL pointer fixes in ethtool -x code path
and in the error clean up path when freeing IRQs, a ring accounting bug
that missed rings used by the RDMA driver, and 3 bug fixes related to TC
Flower and VF-reps.
v2: Fixed commit message of patch 4. Changed the pound sign to $ sign
in front of the ip command.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 11 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c | 63 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c | 30 |
4 files changed, 103 insertions, 5 deletions
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 1991f0c7bc0e..f83769d8047b 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c | |||
@@ -6090,7 +6090,7 @@ static void bnxt_free_irq(struct bnxt *bp) | |||
6090 | free_irq_cpu_rmap(bp->dev->rx_cpu_rmap); | 6090 | free_irq_cpu_rmap(bp->dev->rx_cpu_rmap); |
6091 | bp->dev->rx_cpu_rmap = NULL; | 6091 | bp->dev->rx_cpu_rmap = NULL; |
6092 | #endif | 6092 | #endif |
6093 | if (!bp->irq_tbl) | 6093 | if (!bp->irq_tbl || !bp->bnapi) |
6094 | return; | 6094 | return; |
6095 | 6095 | ||
6096 | for (i = 0; i < bp->cp_nr_rings; i++) { | 6096 | for (i = 0; i < bp->cp_nr_rings; i++) { |
@@ -7686,6 +7686,8 @@ int bnxt_check_rings(struct bnxt *bp, int tx, int rx, bool sh, int tcs, | |||
7686 | if (bp->flags & BNXT_FLAG_AGG_RINGS) | 7686 | if (bp->flags & BNXT_FLAG_AGG_RINGS) |
7687 | rx_rings <<= 1; | 7687 | rx_rings <<= 1; |
7688 | cp = sh ? max_t(int, tx_rings_needed, rx) : tx_rings_needed + rx; | 7688 | cp = sh ? max_t(int, tx_rings_needed, rx) : tx_rings_needed + rx; |
7689 | if (bp->flags & BNXT_FLAG_NEW_RM) | ||
7690 | cp += bnxt_get_ulp_msix_num(bp); | ||
7689 | return bnxt_hwrm_check_rings(bp, tx_rings_needed, rx_rings, rx, cp, | 7691 | return bnxt_hwrm_check_rings(bp, tx_rings_needed, rx_rings, rx, cp, |
7690 | vnics); | 7692 | vnics); |
7691 | } | 7693 | } |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index 8d8ccd67e0e2..1f622ca2a64f 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | |||
@@ -870,17 +870,22 @@ static int bnxt_get_rxfh(struct net_device *dev, u32 *indir, u8 *key, | |||
870 | u8 *hfunc) | 870 | u8 *hfunc) |
871 | { | 871 | { |
872 | struct bnxt *bp = netdev_priv(dev); | 872 | struct bnxt *bp = netdev_priv(dev); |
873 | struct bnxt_vnic_info *vnic = &bp->vnic_info[0]; | 873 | struct bnxt_vnic_info *vnic; |
874 | int i = 0; | 874 | int i = 0; |
875 | 875 | ||
876 | if (hfunc) | 876 | if (hfunc) |
877 | *hfunc = ETH_RSS_HASH_TOP; | 877 | *hfunc = ETH_RSS_HASH_TOP; |
878 | 878 | ||
879 | if (indir) | 879 | if (!bp->vnic_info) |
880 | return 0; | ||
881 | |||
882 | vnic = &bp->vnic_info[0]; | ||
883 | if (indir && vnic->rss_table) { | ||
880 | for (i = 0; i < HW_HASH_INDEX_SIZE; i++) | 884 | for (i = 0; i < HW_HASH_INDEX_SIZE; i++) |
881 | indir[i] = le16_to_cpu(vnic->rss_table[i]); | 885 | indir[i] = le16_to_cpu(vnic->rss_table[i]); |
886 | } | ||
882 | 887 | ||
883 | if (key) | 888 | if (key && vnic->rss_hash_key) |
884 | memcpy(key, vnic->rss_hash_key, HW_HASH_KEY_SIZE); | 889 | memcpy(key, vnic->rss_hash_key, HW_HASH_KEY_SIZE); |
885 | 890 | ||
886 | return 0; | 891 | return 0; |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c index 65c2cee35766..795f45024c20 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c | |||
@@ -377,6 +377,30 @@ static bool is_wildcard(void *mask, int len) | |||
377 | return true; | 377 | return true; |
378 | } | 378 | } |
379 | 379 | ||
380 | static bool is_exactmatch(void *mask, int len) | ||
381 | { | ||
382 | const u8 *p = mask; | ||
383 | int i; | ||
384 | |||
385 | for (i = 0; i < len; i++) | ||
386 | if (p[i] != 0xff) | ||
387 | return false; | ||
388 | |||
389 | return true; | ||
390 | } | ||
391 | |||
392 | static bool bits_set(void *key, int len) | ||
393 | { | ||
394 | const u8 *p = key; | ||
395 | int i; | ||
396 | |||
397 | for (i = 0; i < len; i++) | ||
398 | if (p[i] != 0) | ||
399 | return true; | ||
400 | |||
401 | return false; | ||
402 | } | ||
403 | |||
380 | static int bnxt_hwrm_cfa_flow_alloc(struct bnxt *bp, struct bnxt_tc_flow *flow, | 404 | static int bnxt_hwrm_cfa_flow_alloc(struct bnxt *bp, struct bnxt_tc_flow *flow, |
381 | __le16 ref_flow_handle, | 405 | __le16 ref_flow_handle, |
382 | __le32 tunnel_handle, __le16 *flow_handle) | 406 | __le32 tunnel_handle, __le16 *flow_handle) |
@@ -764,6 +788,41 @@ static bool bnxt_tc_can_offload(struct bnxt *bp, struct bnxt_tc_flow *flow) | |||
764 | return false; | 788 | return false; |
765 | } | 789 | } |
766 | 790 | ||
791 | /* Currently source/dest MAC cannot be partial wildcard */ | ||
792 | if (bits_set(&flow->l2_key.smac, sizeof(flow->l2_key.smac)) && | ||
793 | !is_exactmatch(flow->l2_mask.smac, sizeof(flow->l2_mask.smac))) { | ||
794 | netdev_info(bp->dev, "Wildcard match unsupported for Source MAC\n"); | ||
795 | return false; | ||
796 | } | ||
797 | if (bits_set(&flow->l2_key.dmac, sizeof(flow->l2_key.dmac)) && | ||
798 | !is_exactmatch(&flow->l2_mask.dmac, sizeof(flow->l2_mask.dmac))) { | ||
799 | netdev_info(bp->dev, "Wildcard match unsupported for Dest MAC\n"); | ||
800 | return false; | ||
801 | } | ||
802 | |||
803 | /* Currently VLAN fields cannot be partial wildcard */ | ||
804 | if (bits_set(&flow->l2_key.inner_vlan_tci, | ||
805 | sizeof(flow->l2_key.inner_vlan_tci)) && | ||
806 | !is_exactmatch(&flow->l2_mask.inner_vlan_tci, | ||
807 | sizeof(flow->l2_mask.inner_vlan_tci))) { | ||
808 | netdev_info(bp->dev, "Wildcard match unsupported for VLAN TCI\n"); | ||
809 | return false; | ||
810 | } | ||
811 | if (bits_set(&flow->l2_key.inner_vlan_tpid, | ||
812 | sizeof(flow->l2_key.inner_vlan_tpid)) && | ||
813 | !is_exactmatch(&flow->l2_mask.inner_vlan_tpid, | ||
814 | sizeof(flow->l2_mask.inner_vlan_tpid))) { | ||
815 | netdev_info(bp->dev, "Wildcard match unsupported for VLAN TPID\n"); | ||
816 | return false; | ||
817 | } | ||
818 | |||
819 | /* Currently Ethertype must be set */ | ||
820 | if (!is_exactmatch(&flow->l2_mask.ether_type, | ||
821 | sizeof(flow->l2_mask.ether_type))) { | ||
822 | netdev_info(bp->dev, "Wildcard match unsupported for Ethertype\n"); | ||
823 | return false; | ||
824 | } | ||
825 | |||
767 | return true; | 826 | return true; |
768 | } | 827 | } |
769 | 828 | ||
@@ -992,8 +1051,10 @@ static int bnxt_tc_get_decap_handle(struct bnxt *bp, struct bnxt_tc_flow *flow, | |||
992 | 1051 | ||
993 | /* Check if there's another flow using the same tunnel decap. | 1052 | /* Check if there's another flow using the same tunnel decap. |
994 | * If not, add this tunnel to the table and resolve the other | 1053 | * If not, add this tunnel to the table and resolve the other |
995 | * tunnel header fileds | 1054 | * tunnel header fileds. Ignore src_port in the tunnel_key, |
1055 | * since it is not required for decap filters. | ||
996 | */ | 1056 | */ |
1057 | decap_key->tp_src = 0; | ||
997 | decap_node = bnxt_tc_get_tunnel_node(bp, &tc_info->decap_table, | 1058 | decap_node = bnxt_tc_get_tunnel_node(bp, &tc_info->decap_table, |
998 | &tc_info->decap_ht_params, | 1059 | &tc_info->decap_ht_params, |
999 | decap_key); | 1060 | decap_key); |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c index 26290403f38f..38f635cf8408 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c | |||
@@ -64,6 +64,31 @@ static int hwrm_cfa_vfr_free(struct bnxt *bp, u16 vf_idx) | |||
64 | return rc; | 64 | return rc; |
65 | } | 65 | } |
66 | 66 | ||
67 | static int bnxt_hwrm_vfr_qcfg(struct bnxt *bp, struct bnxt_vf_rep *vf_rep, | ||
68 | u16 *max_mtu) | ||
69 | { | ||
70 | struct hwrm_func_qcfg_output *resp = bp->hwrm_cmd_resp_addr; | ||
71 | struct hwrm_func_qcfg_input req = {0}; | ||
72 | u16 mtu; | ||
73 | int rc; | ||
74 | |||
75 | bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_QCFG, -1, -1); | ||
76 | req.fid = cpu_to_le16(bp->pf.vf[vf_rep->vf_idx].fw_fid); | ||
77 | |||
78 | mutex_lock(&bp->hwrm_cmd_lock); | ||
79 | |||
80 | rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); | ||
81 | if (!rc) { | ||
82 | mtu = le16_to_cpu(resp->max_mtu_configured); | ||
83 | if (!mtu) | ||
84 | *max_mtu = BNXT_MAX_MTU; | ||
85 | else | ||
86 | *max_mtu = mtu; | ||
87 | } | ||
88 | mutex_unlock(&bp->hwrm_cmd_lock); | ||
89 | return rc; | ||
90 | } | ||
91 | |||
67 | static int bnxt_vf_rep_open(struct net_device *dev) | 92 | static int bnxt_vf_rep_open(struct net_device *dev) |
68 | { | 93 | { |
69 | struct bnxt_vf_rep *vf_rep = netdev_priv(dev); | 94 | struct bnxt_vf_rep *vf_rep = netdev_priv(dev); |
@@ -365,6 +390,7 @@ static void bnxt_vf_rep_netdev_init(struct bnxt *bp, struct bnxt_vf_rep *vf_rep, | |||
365 | struct net_device *dev) | 390 | struct net_device *dev) |
366 | { | 391 | { |
367 | struct net_device *pf_dev = bp->dev; | 392 | struct net_device *pf_dev = bp->dev; |
393 | u16 max_mtu; | ||
368 | 394 | ||
369 | dev->netdev_ops = &bnxt_vf_rep_netdev_ops; | 395 | dev->netdev_ops = &bnxt_vf_rep_netdev_ops; |
370 | dev->ethtool_ops = &bnxt_vf_rep_ethtool_ops; | 396 | dev->ethtool_ops = &bnxt_vf_rep_ethtool_ops; |
@@ -380,6 +406,10 @@ static void bnxt_vf_rep_netdev_init(struct bnxt *bp, struct bnxt_vf_rep *vf_rep, | |||
380 | bnxt_vf_rep_eth_addr_gen(bp->pf.mac_addr, vf_rep->vf_idx, | 406 | bnxt_vf_rep_eth_addr_gen(bp->pf.mac_addr, vf_rep->vf_idx, |
381 | dev->perm_addr); | 407 | dev->perm_addr); |
382 | ether_addr_copy(dev->dev_addr, dev->perm_addr); | 408 | ether_addr_copy(dev->dev_addr, dev->perm_addr); |
409 | /* Set VF-Rep's max-mtu to the corresponding VF's max-mtu */ | ||
410 | if (!bnxt_hwrm_vfr_qcfg(bp, vf_rep, &max_mtu)) | ||
411 | dev->max_mtu = max_mtu; | ||
412 | dev->min_mtu = ETH_ZLEN; | ||
383 | } | 413 | } |
384 | 414 | ||
385 | static int bnxt_pcie_dsn_get(struct bnxt *bp, u8 dsn[]) | 415 | static int bnxt_pcie_dsn_get(struct bnxt *bp, u8 dsn[]) |