Skip to content

Commit bd3191b

Browse files
Michael Chandavem330
authored andcommitted
bnxt_en: Implement ethtool -X to set indirection table.
With the new infrastructure in place, we can now support the setting of the indirection table from ethtool. When changing channels, in a rare case that firmware cannot reserve the rings that were promised, we will still try to keep the RSS map and only revert to default when absolutely necessary. v4: Revert RSS map to default during ring change only when absolutely necessary. v3: Add warning messages when firmware cannot reserve the requested RX rings, and when the RSS table entries have to change to default. v2: When changing channels, if the RSS table size changes and RSS map is non-default, return error. Signed-off-by: Michael Chan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent adc38ac commit bd3191b

File tree

2 files changed

+67
-1
lines changed

2 files changed

+67
-1
lines changed

drivers/net/ethernet/broadcom/bnxt/bnxt.c

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4869,6 +4869,19 @@ static void bnxt_set_dflt_rss_indir_tbl(struct bnxt *bp)
48694869
memset(&bp->rss_indir_tbl[i], 0, pad * sizeof(u16));
48704870
}
48714871

4872+
static u16 bnxt_get_max_rss_ring(struct bnxt *bp)
4873+
{
4874+
u16 i, tbl_size, max_ring = 0;
4875+
4876+
if (!bp->rss_indir_tbl)
4877+
return 0;
4878+
4879+
tbl_size = bnxt_get_rxfh_indir_size(bp->dev);
4880+
for (i = 0; i < tbl_size; i++)
4881+
max_ring = max(max_ring, bp->rss_indir_tbl[i]);
4882+
return max_ring;
4883+
}
4884+
48724885
int bnxt_get_nr_rss_ctxs(struct bnxt *bp, int rx_rings)
48734886
{
48744887
if (bp->flags & BNXT_FLAG_CHIP_P5)
@@ -6058,6 +6071,21 @@ static int __bnxt_reserve_rings(struct bnxt *bp)
60586071
rx = rx_rings << 1;
60596072
cp = sh ? max_t(int, tx, rx_rings) : tx + rx_rings;
60606073
bp->tx_nr_rings = tx;
6074+
6075+
/* If we cannot reserve all the RX rings, reset the RSS map only
6076+
* if absolutely necessary
6077+
*/
6078+
if (rx_rings != bp->rx_nr_rings) {
6079+
netdev_warn(bp->dev, "Able to reserve only %d out of %d requested RX rings\n",
6080+
rx_rings, bp->rx_nr_rings);
6081+
if ((bp->dev->priv_flags & IFF_RXFH_CONFIGURED) &&
6082+
(bnxt_get_nr_rss_ctxs(bp, bp->rx_nr_rings) !=
6083+
bnxt_get_nr_rss_ctxs(bp, rx_rings) ||
6084+
bnxt_get_max_rss_ring(bp) >= rx_rings)) {
6085+
netdev_warn(bp->dev, "RSS table entries reverting to default\n");
6086+
bp->dev->priv_flags &= ~IFF_RXFH_CONFIGURED;
6087+
}
6088+
}
60616089
bp->rx_nr_rings = rx_rings;
60626090
bp->cp_nr_rings = cp;
60636091

@@ -8262,7 +8290,8 @@ int bnxt_reserve_rings(struct bnxt *bp, bool irq_re_init)
82628290
rc = bnxt_init_int_mode(bp);
82638291
bnxt_ulp_irq_restart(bp, rc);
82648292
}
8265-
bnxt_set_dflt_rss_indir_tbl(bp);
8293+
if (!netif_is_rxfh_configured(bp->dev))
8294+
bnxt_set_dflt_rss_indir_tbl(bp);
82668295

82678296
if (rc) {
82688297
netdev_err(bp->dev, "ring reservation/IRQ init failure rc: %d\n", rc);

drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -926,6 +926,13 @@ static int bnxt_set_channels(struct net_device *dev,
926926
return rc;
927927
}
928928

929+
if (bnxt_get_nr_rss_ctxs(bp, req_rx_rings) !=
930+
bnxt_get_nr_rss_ctxs(bp, bp->rx_nr_rings) &&
931+
(dev->priv_flags & IFF_RXFH_CONFIGURED)) {
932+
netdev_warn(dev, "RSS table size change required, RSS table entries must be default to proceed\n");
933+
return -EINVAL;
934+
}
935+
929936
if (netif_running(dev)) {
930937
if (BNXT_PF(bp)) {
931938
/* TODO CHIMP_FW: Send message to all VF's
@@ -1313,6 +1320,35 @@ static int bnxt_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
13131320
return 0;
13141321
}
13151322

1323+
static int bnxt_set_rxfh(struct net_device *dev, const u32 *indir,
1324+
const u8 *key, const u8 hfunc)
1325+
{
1326+
struct bnxt *bp = netdev_priv(dev);
1327+
int rc = 0;
1328+
1329+
if (hfunc && hfunc != ETH_RSS_HASH_TOP)
1330+
return -EOPNOTSUPP;
1331+
1332+
if (key)
1333+
return -EOPNOTSUPP;
1334+
1335+
if (indir) {
1336+
u32 i, pad, tbl_size = bnxt_get_rxfh_indir_size(dev);
1337+
1338+
for (i = 0; i < tbl_size; i++)
1339+
bp->rss_indir_tbl[i] = indir[i];
1340+
pad = bp->rss_indir_tbl_entries - tbl_size;
1341+
if (pad)
1342+
memset(&bp->rss_indir_tbl[i], 0, pad * sizeof(u16));
1343+
}
1344+
1345+
if (netif_running(bp->dev)) {
1346+
bnxt_close_nic(bp, false, false);
1347+
rc = bnxt_open_nic(bp, false, false);
1348+
}
1349+
return rc;
1350+
}
1351+
13161352
static void bnxt_get_drvinfo(struct net_device *dev,
13171353
struct ethtool_drvinfo *info)
13181354
{
@@ -3619,6 +3655,7 @@ const struct ethtool_ops bnxt_ethtool_ops = {
36193655
.get_rxfh_indir_size = bnxt_get_rxfh_indir_size,
36203656
.get_rxfh_key_size = bnxt_get_rxfh_key_size,
36213657
.get_rxfh = bnxt_get_rxfh,
3658+
.set_rxfh = bnxt_set_rxfh,
36223659
.flash_device = bnxt_flash_device,
36233660
.get_eeprom_len = bnxt_get_eeprom_len,
36243661
.get_eeprom = bnxt_get_eeprom,

0 commit comments

Comments
 (0)