summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom/bnxt/bnxt.c
diff options
context:
space:
mode:
authorMichael Chan2015-12-28 00:19:24 +0100
committerDavid S. Miller2015-12-28 06:57:28 +0100
commit2bcfa6f6e7cf867e4aa623f84caea4bc413d38c9 (patch)
tree8cb243504224f2f51c0608ee49c7f94a23398bb9 /drivers/net/ethernet/broadcom/bnxt/bnxt.c
parentbnxt_en: Don't treat single segment rx frames as GRO frames. (diff)
downloadkernel-qcow2-linux-2bcfa6f6e7cf867e4aa623f84caea4bc413d38c9.tar.gz
kernel-qcow2-linux-2bcfa6f6e7cf867e4aa623f84caea4bc413d38c9.tar.xz
kernel-qcow2-linux-2bcfa6f6e7cf867e4aa623f84caea4bc413d38c9.zip
bnxt_en: Check hardware resources before enabling NTUPLE.
The hardware resources required to enable NTUPLE varies depending on how many rx channels are configured. We need to make sure we have the resources before we enable NTUPLE. Add bnxt_rfs_capable() to do the checking. In addition, we need to do the same checking in ndo_fix_features(). As the rx channels are changed using ethtool -L, we call netdev_update_features() to make the necessary adjustment for NTUPLE. Calling netdev_update_features() in netif_running() state but before calling bnxt_open_nic() would be a problem. To make this work, bnxt_set_features() has to be modified to test for BNXT_STATE_OPEN for the true hardware state instead of checking netif_running(). Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/broadcom/bnxt/bnxt.c')
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt.c41
1 files changed, 33 insertions, 8 deletions
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 082c1e95edc7..8827b7bf4bce 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -4916,9 +4916,32 @@ skip_uc:
return rc;
}
+static bool bnxt_rfs_capable(struct bnxt *bp)
+{
+#ifdef CONFIG_RFS_ACCEL
+ struct bnxt_pf_info *pf = &bp->pf;
+ int vnics;
+
+ if (BNXT_VF(bp) || !(bp->flags & BNXT_FLAG_MSIX_CAP))
+ return false;
+
+ vnics = 1 + bp->rx_nr_rings;
+ if (vnics > pf->max_rsscos_ctxs || vnics > pf->max_vnics)
+ return false;
+
+ return true;
+#else
+ return false;
+#endif
+}
+
static netdev_features_t bnxt_fix_features(struct net_device *dev,
netdev_features_t features)
{
+ struct bnxt *bp = netdev_priv(dev);
+
+ if (!bnxt_rfs_capable(bp))
+ features &= ~NETIF_F_NTUPLE;
return features;
}
@@ -4959,7 +4982,7 @@ static int bnxt_set_features(struct net_device *dev, netdev_features_t features)
bp->flags = flags;
- if (!netif_running(dev)) {
+ if (!test_bit(BNXT_STATE_OPEN, &bp->state)) {
if (update_tpa)
bnxt_set_ring_params(bp);
return rc;
@@ -5639,11 +5662,8 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (bnxt_vf_pciid(ent->driver_data))
bp->flags |= BNXT_FLAG_VF;
- if (pdev->msix_cap) {
+ if (pdev->msix_cap)
bp->flags |= BNXT_FLAG_MSIX_CAP;
- if (BNXT_PF(bp))
- bp->flags |= BNXT_FLAG_RFS;
- }
rc = bnxt_init_board(pdev, dev);
if (rc < 0)
@@ -5662,9 +5682,6 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
NETIF_F_RXHASH |
NETIF_F_RXCSUM | NETIF_F_LRO | NETIF_F_GRO;
- if (bp->flags & BNXT_FLAG_RFS)
- dev->hw_features |= NETIF_F_NTUPLE;
-
dev->hw_enc_features =
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_SG |
NETIF_F_TSO | NETIF_F_TSO6 |
@@ -5723,6 +5740,14 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
bp->cp_nr_rings = max_t(int, bp->rx_nr_rings, bp->tx_nr_rings);
bp->num_stat_ctxs = bp->cp_nr_rings;
+ if (BNXT_PF(bp)) {
+ dev->hw_features |= NETIF_F_NTUPLE;
+ if (bnxt_rfs_capable(bp)) {
+ bp->flags |= BNXT_FLAG_RFS;
+ dev->features |= NETIF_F_NTUPLE;
+ }
+ }
+
if (dev->hw_features & NETIF_F_HW_VLAN_CTAG_RX)
bp->flags |= BNXT_FLAG_STRIP_VLAN;