Skip to content

Commit b3d0083

Browse files
Pavan Chebbikuba-moo
authored andcommitted
bnxt_en: Support RSS contexts in ethtool .{get|set}_rxfh()
Support up to 32 RSS contexts per device if supported by the device. Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com> Signed-off-by: Pavan Chebbi <pavan.chebbi@broadcom.com> Signed-off-by: Michael Chan <michael.chan@broadcom.com> Link: https://lore.kernel.org/r/20240325222902.220712-11-michael.chan@broadcom.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 77a614f commit b3d0083

File tree

3 files changed

+196
-8
lines changed

3 files changed

+196
-8
lines changed

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

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5939,8 +5939,8 @@ static void bnxt_hwrm_vnic_update_tunl_tpa(struct bnxt *bp,
59395939
req->tnl_tpa_en_bitmap = cpu_to_le32(tunl_tpa_bmap);
59405940
}
59415941

5942-
static int bnxt_hwrm_vnic_set_tpa(struct bnxt *bp, struct bnxt_vnic_info *vnic,
5943-
u32 tpa_flags)
5942+
int bnxt_hwrm_vnic_set_tpa(struct bnxt *bp, struct bnxt_vnic_info *vnic,
5943+
u32 tpa_flags)
59445944
{
59455945
u16 max_aggs = VNIC_TPA_CFG_REQ_MAX_AGGS_MAX;
59465946
struct hwrm_vnic_tpa_cfg_input *req;
@@ -6129,6 +6129,8 @@ static void bnxt_fill_hw_rss_tbl_p5(struct bnxt *bp,
61296129

61306130
if (vnic->flags & BNXT_VNIC_NTUPLE_FLAG)
61316131
j = ethtool_rxfh_indir_default(i, bp->rx_nr_rings);
6132+
else if (vnic->flags & BNXT_VNIC_RSSCTX_FLAG)
6133+
j = vnic->rss_ctx->rss_indir_tbl[i];
61326134
else
61336135
j = bp->rss_indir_tbl[i];
61346136
rxr = &bp->rx_ring[j];
@@ -6423,9 +6425,9 @@ static void bnxt_hwrm_vnic_free(struct bnxt *bp)
64236425
bnxt_hwrm_vnic_free_one(bp, &bp->vnic_info[i]);
64246426
}
64256427

6426-
static int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic,
6427-
unsigned int start_rx_ring_idx,
6428-
unsigned int nr_rings)
6428+
int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic,
6429+
unsigned int start_rx_ring_idx,
6430+
unsigned int nr_rings)
64296431
{
64306432
unsigned int i, j, grp_idx, end_idx = start_rx_ring_idx + nr_rings;
64316433
struct hwrm_vnic_alloc_output *resp;
@@ -9852,7 +9854,7 @@ int bnxt_hwrm_vnic_rss_cfg_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic)
98529854
return rc;
98539855
}
98549856

9855-
static int __bnxt_setup_vnic_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic)
9857+
int __bnxt_setup_vnic_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic)
98569858
{
98579859
int rc, i, nr_ctxs;
98589860

@@ -9939,15 +9941,46 @@ static int bnxt_alloc_rfs_vnics(struct bnxt *bp)
99399941
void bnxt_del_one_rss_ctx(struct bnxt *bp, struct bnxt_rss_ctx *rss_ctx,
99409942
bool all)
99419943
{
9944+
struct bnxt_vnic_info *vnic = &rss_ctx->vnic;
9945+
int i;
9946+
9947+
bnxt_hwrm_vnic_free_one(bp, &rss_ctx->vnic);
9948+
for (i = 0; i < BNXT_MAX_CTX_PER_VNIC; i++) {
9949+
if (vnic->fw_rss_cos_lb_ctx[i] != INVALID_HW_RING_ID)
9950+
bnxt_hwrm_vnic_ctx_free_one(bp, vnic, i);
9951+
}
99429952
if (!all)
99439953
return;
99449954

9955+
if (vnic->rss_table)
9956+
dma_free_coherent(&bp->pdev->dev, vnic->rss_table_size,
9957+
vnic->rss_table,
9958+
vnic->rss_table_dma_addr);
9959+
kfree(rss_ctx->rss_indir_tbl);
99459960
list_del(&rss_ctx->list);
99469961
bp->num_rss_ctx--;
99479962
clear_bit(rss_ctx->index, bp->rss_ctx_bmap);
99489963
kfree(rss_ctx);
99499964
}
99509965

9966+
static void bnxt_hwrm_realloc_rss_ctx_vnic(struct bnxt *bp)
9967+
{
9968+
bool set_tpa = !!(bp->flags & BNXT_FLAG_TPA);
9969+
struct bnxt_rss_ctx *rss_ctx, *tmp;
9970+
9971+
list_for_each_entry_safe(rss_ctx, tmp, &bp->rss_ctx_list, list) {
9972+
struct bnxt_vnic_info *vnic = &rss_ctx->vnic;
9973+
9974+
if (bnxt_hwrm_vnic_alloc(bp, vnic, 0, bp->rx_nr_rings) ||
9975+
bnxt_hwrm_vnic_set_tpa(bp, vnic, set_tpa) ||
9976+
__bnxt_setup_vnic_p5(bp, vnic)) {
9977+
netdev_err(bp->dev, "Failed to restore RSS ctx %d\n",
9978+
rss_ctx->index);
9979+
bnxt_del_one_rss_ctx(bp, rss_ctx, true);
9980+
}
9981+
}
9982+
}
9983+
99519984
struct bnxt_rss_ctx *bnxt_alloc_rss_ctx(struct bnxt *bp)
99529985
{
99539986
struct bnxt_rss_ctx *rss_ctx = NULL;
@@ -11829,6 +11862,8 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
1182911862
bnxt_vf_reps_open(bp);
1183011863
bnxt_ptp_init_rtc(bp, true);
1183111864
bnxt_ptp_cfg_tstamp_filters(bp);
11865+
if (BNXT_SUPPORTS_MULTI_RSS_CTX(bp))
11866+
bnxt_hwrm_realloc_rss_ctx_vnic(bp);
1183211867
bnxt_cfg_usr_fltrs(bp);
1183311868
return 0;
1183411869

@@ -11977,6 +12012,8 @@ static void __bnxt_close_nic(struct bnxt *bp, bool irq_re_init,
1197712012
while (bnxt_drv_busy(bp))
1197812013
msleep(20);
1197912014

12015+
if (BNXT_SUPPORTS_MULTI_RSS_CTX(bp))
12016+
bnxt_clear_rss_ctxs(bp, false);
1198012017
/* Flush rings and disable interrupts */
1198112018
bnxt_shutdown_nic(bp, irq_re_init);
1198212019

drivers/net/ethernet/broadcom/bnxt/bnxt.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1270,6 +1270,7 @@ struct bnxt_rss_ctx {
12701270

12711271
#define BNXT_MAX_ETH_RSS_CTX 32
12721272
#define BNXT_RSS_CTX_BMAP_LEN (BNXT_MAX_ETH_RSS_CTX + 1)
1273+
#define BNXT_VNIC_ID_INVALID 0xffffffff
12731274

12741275
struct bnxt_hw_rings {
12751276
int tx;
@@ -2714,11 +2715,16 @@ int bnxt_hwrm_cfa_ntuple_filter_free(struct bnxt *bp,
27142715
struct bnxt_ntuple_filter *fltr);
27152716
int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp,
27162717
struct bnxt_ntuple_filter *fltr);
2718+
int bnxt_hwrm_vnic_set_tpa(struct bnxt *bp, struct bnxt_vnic_info *vnic,
2719+
u32 tpa_flags);
27172720
void bnxt_fill_ipv6_mask(__be32 mask[4]);
27182721
int bnxt_alloc_rss_indir_tbl(struct bnxt *bp, struct bnxt_rss_ctx *rss_ctx);
27192722
void bnxt_set_dflt_rss_indir_tbl(struct bnxt *bp, struct bnxt_rss_ctx *rss_ctx);
27202723
int bnxt_get_nr_rss_ctxs(struct bnxt *bp, int rx_rings);
27212724
int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic);
2725+
int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic,
2726+
unsigned int start_rx_ring_idx,
2727+
unsigned int nr_rings);
27222728
int __bnxt_hwrm_get_tx_rings(struct bnxt *bp, u16 fid, int *tx_rings);
27232729
int bnxt_nq_rings_in_use(struct bnxt *bp);
27242730
int bnxt_hwrm_set_coal(struct bnxt *);
@@ -2745,6 +2751,7 @@ int bnxt_hwrm_func_resc_qcaps(struct bnxt *bp, bool all);
27452751
int bnxt_hwrm_func_qcaps(struct bnxt *bp);
27462752
int bnxt_hwrm_fw_set_time(struct bnxt *);
27472753
int bnxt_hwrm_vnic_rss_cfg_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic);
2754+
int __bnxt_setup_vnic_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic);
27482755
void bnxt_del_one_rss_ctx(struct bnxt *bp, struct bnxt_rss_ctx *rss_ctx,
27492756
bool all);
27502757
struct bnxt_rss_ctx *bnxt_alloc_rss_ctx(struct bnxt *bp);

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

Lines changed: 146 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,6 +1207,36 @@ static int bnxt_grxclsrule(struct bnxt *bp, struct ethtool_rxnfc *cmd)
12071207
return rc;
12081208
}
12091209

1210+
static struct bnxt_rss_ctx *bnxt_get_rss_ctx_from_index(struct bnxt *bp,
1211+
u32 index)
1212+
{
1213+
struct bnxt_rss_ctx *rss_ctx, *tmp;
1214+
1215+
list_for_each_entry_safe(rss_ctx, tmp, &bp->rss_ctx_list, list)
1216+
if (rss_ctx->index == index)
1217+
return rss_ctx;
1218+
return NULL;
1219+
}
1220+
1221+
static int bnxt_alloc_rss_ctx_rss_table(struct bnxt *bp,
1222+
struct bnxt_rss_ctx *rss_ctx)
1223+
{
1224+
int size = L1_CACHE_ALIGN(BNXT_MAX_RSS_TABLE_SIZE_P5);
1225+
struct bnxt_vnic_info *vnic = &rss_ctx->vnic;
1226+
1227+
vnic->rss_table_size = size + HW_HASH_KEY_SIZE;
1228+
vnic->rss_table = dma_alloc_coherent(&bp->pdev->dev,
1229+
vnic->rss_table_size,
1230+
&vnic->rss_table_dma_addr,
1231+
GFP_KERNEL);
1232+
if (!vnic->rss_table)
1233+
return -ENOMEM;
1234+
1235+
vnic->rss_hash_key = ((void *)vnic->rss_table) + size;
1236+
vnic->rss_hash_key_dma_addr = vnic->rss_table_dma_addr + size;
1237+
return 0;
1238+
}
1239+
12101240
static int bnxt_add_l2_cls_rule(struct bnxt *bp,
12111241
struct ethtool_rx_flow_spec *fs)
12121242
{
@@ -1756,7 +1786,10 @@ static u32 bnxt_get_rxfh_key_size(struct net_device *dev)
17561786
static int bnxt_get_rxfh(struct net_device *dev,
17571787
struct ethtool_rxfh_param *rxfh)
17581788
{
1789+
u32 rss_context = rxfh->rss_context;
1790+
struct bnxt_rss_ctx *rss_ctx = NULL;
17591791
struct bnxt *bp = netdev_priv(dev);
1792+
u16 *indir_tbl = bp->rss_indir_tbl;
17601793
struct bnxt_vnic_info *vnic;
17611794
u32 i, tbl_size;
17621795

@@ -1766,10 +1799,18 @@ static int bnxt_get_rxfh(struct net_device *dev,
17661799
return 0;
17671800

17681801
vnic = &bp->vnic_info[BNXT_VNIC_DEFAULT];
1769-
if (rxfh->indir && bp->rss_indir_tbl) {
1802+
if (rxfh->rss_context) {
1803+
rss_ctx = bnxt_get_rss_ctx_from_index(bp, rss_context);
1804+
if (!rss_ctx)
1805+
return -EINVAL;
1806+
indir_tbl = rss_ctx->rss_indir_tbl;
1807+
vnic = &rss_ctx->vnic;
1808+
}
1809+
1810+
if (rxfh->indir && indir_tbl) {
17701811
tbl_size = bnxt_get_rxfh_indir_size(dev);
17711812
for (i = 0; i < tbl_size; i++)
1772-
rxfh->indir[i] = bp->rss_indir_tbl[i];
1813+
rxfh->indir[i] = indir_tbl[i];
17731814
}
17741815

17751816
if (rxfh->key && vnic->rss_hash_key)
@@ -1804,6 +1845,105 @@ static void bnxt_modify_rss(struct bnxt *bp, struct bnxt_rss_ctx *rss_ctx,
18041845
}
18051846
}
18061847

1848+
static int bnxt_set_rxfh_context(struct bnxt *bp,
1849+
struct ethtool_rxfh_param *rxfh,
1850+
struct netlink_ext_ack *extack)
1851+
{
1852+
u32 *rss_context = &rxfh->rss_context;
1853+
struct bnxt_rss_ctx *rss_ctx;
1854+
struct bnxt_vnic_info *vnic;
1855+
bool modify = false;
1856+
int bit_id;
1857+
int rc;
1858+
1859+
if (!BNXT_SUPPORTS_MULTI_RSS_CTX(bp)) {
1860+
NL_SET_ERR_MSG_MOD(extack, "RSS contexts not supported");
1861+
return -EOPNOTSUPP;
1862+
}
1863+
1864+
if (*rss_context != ETH_RXFH_CONTEXT_ALLOC) {
1865+
rss_ctx = bnxt_get_rss_ctx_from_index(bp, *rss_context);
1866+
if (!rss_ctx) {
1867+
NL_SET_ERR_MSG_FMT_MOD(extack, "RSS context %u not found",
1868+
*rss_context);
1869+
return -EINVAL;
1870+
}
1871+
if (*rss_context && rxfh->rss_delete) {
1872+
bnxt_del_one_rss_ctx(bp, rss_ctx, true);
1873+
return 0;
1874+
}
1875+
modify = true;
1876+
vnic = &rss_ctx->vnic;
1877+
goto modify_context;
1878+
}
1879+
1880+
if (bp->num_rss_ctx >= BNXT_MAX_ETH_RSS_CTX) {
1881+
NL_SET_ERR_MSG_FMT_MOD(extack, "Out of RSS contexts, maximum %u",
1882+
BNXT_MAX_ETH_RSS_CTX);
1883+
return -EINVAL;
1884+
}
1885+
1886+
if (!bnxt_rfs_capable(bp, true)) {
1887+
NL_SET_ERR_MSG_MOD(extack, "Out hardware resources");
1888+
return -ENOMEM;
1889+
}
1890+
1891+
rss_ctx = bnxt_alloc_rss_ctx(bp);
1892+
if (!rss_ctx)
1893+
return -ENOMEM;
1894+
1895+
vnic = &rss_ctx->vnic;
1896+
vnic->flags |= BNXT_VNIC_RSSCTX_FLAG;
1897+
vnic->vnic_id = BNXT_VNIC_ID_INVALID;
1898+
rc = bnxt_alloc_rss_ctx_rss_table(bp, rss_ctx);
1899+
if (rc)
1900+
goto out;
1901+
1902+
rc = bnxt_alloc_rss_indir_tbl(bp, rss_ctx);
1903+
if (rc)
1904+
goto out;
1905+
1906+
bnxt_set_dflt_rss_indir_tbl(bp, rss_ctx);
1907+
memcpy(vnic->rss_hash_key, bp->rss_hash_key, HW_HASH_KEY_SIZE);
1908+
1909+
rc = bnxt_hwrm_vnic_alloc(bp, vnic, 0, bp->rx_nr_rings);
1910+
if (rc) {
1911+
NL_SET_ERR_MSG_MOD(extack, "Unable to allocate VNIC");
1912+
goto out;
1913+
}
1914+
1915+
rc = bnxt_hwrm_vnic_set_tpa(bp, vnic, bp->flags & BNXT_FLAG_TPA);
1916+
if (rc) {
1917+
NL_SET_ERR_MSG_MOD(extack, "Unable to setup TPA");
1918+
goto out;
1919+
}
1920+
modify_context:
1921+
bnxt_modify_rss(bp, rss_ctx, rxfh);
1922+
1923+
if (modify)
1924+
return bnxt_hwrm_vnic_rss_cfg_p5(bp, vnic);
1925+
1926+
rc = __bnxt_setup_vnic_p5(bp, vnic);
1927+
if (rc) {
1928+
NL_SET_ERR_MSG_MOD(extack, "Unable to setup TPA");
1929+
goto out;
1930+
}
1931+
1932+
bit_id = bitmap_find_free_region(bp->rss_ctx_bmap,
1933+
BNXT_RSS_CTX_BMAP_LEN, 0);
1934+
if (bit_id < 0) {
1935+
rc = -ENOMEM;
1936+
goto out;
1937+
}
1938+
rss_ctx->index = (u16)bit_id;
1939+
*rss_context = rss_ctx->index;
1940+
1941+
return 0;
1942+
out:
1943+
bnxt_del_one_rss_ctx(bp, rss_ctx, true);
1944+
return rc;
1945+
}
1946+
18071947
static int bnxt_set_rxfh(struct net_device *dev,
18081948
struct ethtool_rxfh_param *rxfh,
18091949
struct netlink_ext_ack *extack)
@@ -1814,6 +1954,9 @@ static int bnxt_set_rxfh(struct net_device *dev,
18141954
if (rxfh->hfunc && rxfh->hfunc != ETH_RSS_HASH_TOP)
18151955
return -EOPNOTSUPP;
18161956

1957+
if (rxfh->rss_context)
1958+
return bnxt_set_rxfh_context(bp, rxfh, extack);
1959+
18171960
bnxt_modify_rss(bp, NULL, rxfh);
18181961

18191962
bnxt_clear_usr_fltrs(bp, false);
@@ -5087,6 +5230,7 @@ void bnxt_ethtool_free(struct bnxt *bp)
50875230

50885231
const struct ethtool_ops bnxt_ethtool_ops = {
50895232
.cap_link_lanes_supported = 1,
5233+
.cap_rss_ctx_supported = 1,
50905234
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
50915235
ETHTOOL_COALESCE_MAX_FRAMES |
50925236
ETHTOOL_COALESCE_USECS_IRQ |

0 commit comments

Comments
 (0)