Skip to content

Commit

Permalink
octeontx2-pf: Add RSS multi group support
Browse files Browse the repository at this point in the history
Hardware supports 8 RSS groups per interface. Currently we are using
only group '0'. This patch allows user to create new RSS groups/contexts
and use the same as destination for flow steering rules.

usage:
To steer the traffic to RQ 2,3

ethtool -X eth0 weight 0 0 1 1 context new
(It will print the allocated context id number)
New RSS context is 1

ethtool -N eth0 flow-type tcp4 dst-port 80 context 1 loc 1

To delete the context
ethtool -X eth0 context 1 delete

When an RSS context is removed, the active classification
rules using this context are also removed.

Change-log:

v4
- Fixed compiletime warning.
- Address Saeed's comments on v3.

v3
- Coverted otx2_set_rxfh() to use new function.

v2
- Removed unrelated whitespace
- Coverted otx2_get_rxfh() to use new function.

Signed-off-by: Sunil Kovvuri Goutham <sgoutham@marvell.com>
Signed-off-by: Geetha sowjanya <gakula@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Geetha sowjanya authored and David S. Miller committed Jan 6, 2021
1 parent f011539 commit 81a4362
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 44 deletions.
26 changes: 18 additions & 8 deletions drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,14 +270,17 @@ int otx2_set_flowkey_cfg(struct otx2_nic *pfvf)
return err;
}

int otx2_set_rss_table(struct otx2_nic *pfvf)
int otx2_set_rss_table(struct otx2_nic *pfvf, int ctx_id)
{
struct otx2_rss_info *rss = &pfvf->hw.rss_info;
const int index = rss->rss_size * ctx_id;
struct mbox *mbox = &pfvf->mbox;
struct otx2_rss_ctx *rss_ctx;
struct nix_aq_enq_req *aq;
int idx, err;

mutex_lock(&mbox->lock);
rss_ctx = rss->rss_ctx[ctx_id];
/* Get memory to put this msg */
for (idx = 0; idx < rss->rss_size; idx++) {
aq = otx2_mbox_alloc_msg_nix_aq_enq(mbox);
Expand All @@ -297,10 +300,10 @@ int otx2_set_rss_table(struct otx2_nic *pfvf)
}
}

aq->rss.rq = rss->ind_tbl[idx];
aq->rss.rq = rss_ctx->ind_tbl[idx];

/* Fill AQ info */
aq->qidx = idx;
aq->qidx = index + idx;
aq->ctype = NIX_AQ_CTYPE_RSS;
aq->op = NIX_AQ_INSTOP_INIT;
}
Expand Down Expand Up @@ -335,23 +338,30 @@ void otx2_set_rss_key(struct otx2_nic *pfvf)
int otx2_rss_init(struct otx2_nic *pfvf)
{
struct otx2_rss_info *rss = &pfvf->hw.rss_info;
struct otx2_rss_ctx *rss_ctx;
int idx, ret = 0;

rss->rss_size = sizeof(rss->ind_tbl);
rss->rss_size = sizeof(*rss->rss_ctx[DEFAULT_RSS_CONTEXT_GROUP]);

/* Init RSS key if it is not setup already */
if (!rss->enable)
netdev_rss_key_fill(rss->key, sizeof(rss->key));
otx2_set_rss_key(pfvf);

if (!netif_is_rxfh_configured(pfvf->netdev)) {
/* Default indirection table */
/* Set RSS group 0 as default indirection table */
rss->rss_ctx[DEFAULT_RSS_CONTEXT_GROUP] = kzalloc(rss->rss_size,
GFP_KERNEL);
if (!rss->rss_ctx[DEFAULT_RSS_CONTEXT_GROUP])
return -ENOMEM;

rss_ctx = rss->rss_ctx[DEFAULT_RSS_CONTEXT_GROUP];
for (idx = 0; idx < rss->rss_size; idx++)
rss->ind_tbl[idx] =
rss_ctx->ind_tbl[idx] =
ethtool_rxfh_indir_default(idx,
pfvf->hw.rx_queues);
}
ret = otx2_set_rss_table(pfvf);
ret = otx2_set_rss_table(pfvf, DEFAULT_RSS_CONTEXT_GROUP);
if (ret)
return ret;

Expand Down Expand Up @@ -986,7 +996,7 @@ int otx2_config_nix(struct otx2_nic *pfvf)
nixlf->sq_cnt = pfvf->hw.tx_queues;
nixlf->cq_cnt = pfvf->qset.cq_cnt;
nixlf->rss_sz = MAX_RSS_INDIR_TBL_SIZE;
nixlf->rss_grps = 1; /* Single RSS indir table supported, for now */
nixlf->rss_grps = MAX_RSS_GROUPS;
nixlf->xqe_sz = NIX_XQESZ_W16;
/* We don't know absolute NPA LF idx attached.
* AF will replace 'RVU_DEFAULT_PF_FUNC' with
Expand Down
11 changes: 8 additions & 3 deletions drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,17 @@ enum arua_mapped_qtypes {
#define NIX_LF_POISON_VEC 0x82

/* RSS configuration */
struct otx2_rss_ctx {
u8 ind_tbl[MAX_RSS_INDIR_TBL_SIZE];
};

struct otx2_rss_info {
u8 enable;
u32 flowkey_cfg;
u16 rss_size;
u8 ind_tbl[MAX_RSS_INDIR_TBL_SIZE];
#define RSS_HASH_KEY_SIZE 44 /* 352 bit key */
u8 key[RSS_HASH_KEY_SIZE];
struct otx2_rss_ctx *rss_ctx[MAX_RSS_GROUPS];
};

/* NIX (or NPC) RX errors */
Expand Down Expand Up @@ -643,7 +647,7 @@ void otx2_cleanup_tx_cqes(struct otx2_nic *pfvf, struct otx2_cq_queue *cq);
int otx2_rss_init(struct otx2_nic *pfvf);
int otx2_set_flowkey_cfg(struct otx2_nic *pfvf);
void otx2_set_rss_key(struct otx2_nic *pfvf);
int otx2_set_rss_table(struct otx2_nic *pfvf);
int otx2_set_rss_table(struct otx2_nic *pfvf, int ctx_id);

/* Mbox handlers */
void mbox_handler_msix_offset(struct otx2_nic *pfvf,
Expand Down Expand Up @@ -684,10 +688,11 @@ int otx2_get_flow(struct otx2_nic *pfvf,
int otx2_get_all_flows(struct otx2_nic *pfvf,
struct ethtool_rxnfc *nfc, u32 *rule_locs);
int otx2_add_flow(struct otx2_nic *pfvf,
struct ethtool_rx_flow_spec *fsp);
struct ethtool_rxnfc *nfc);
int otx2_remove_flow(struct otx2_nic *pfvf, u32 location);
int otx2_prepare_flow_request(struct ethtool_rx_flow_spec *fsp,
struct npc_install_flow_req *req);
void otx2_rss_ctx_flow_del(struct otx2_nic *pfvf, int ctx_id);
int otx2_del_macfilter(struct net_device *netdev, const u8 *mac);
int otx2_add_macfilter(struct net_device *netdev, const u8 *mac);
int otx2_enable_rxvlan(struct otx2_nic *pf, bool enable);
Expand Down
133 changes: 105 additions & 28 deletions drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ static int otx2_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *nfc)
break;
case ETHTOOL_SRXCLSRLINS:
if (netif_running(dev) && ntuple)
ret = otx2_add_flow(pfvf, &nfc->fs);
ret = otx2_add_flow(pfvf, nfc);
break;
case ETHTOOL_SRXCLSRLDEL:
if (netif_running(dev) && ntuple)
Expand Down Expand Up @@ -641,42 +641,50 @@ static u32 otx2_get_rxfh_key_size(struct net_device *netdev)

static u32 otx2_get_rxfh_indir_size(struct net_device *dev)
{
struct otx2_nic *pfvf = netdev_priv(dev);

return pfvf->hw.rss_info.rss_size;
return MAX_RSS_INDIR_TBL_SIZE;
}

/* Get RSS configuration */
static int otx2_get_rxfh(struct net_device *dev, u32 *indir,
u8 *hkey, u8 *hfunc)
static int otx2_rss_ctx_delete(struct otx2_nic *pfvf, int ctx_id)
{
struct otx2_nic *pfvf = netdev_priv(dev);
struct otx2_rss_info *rss;
int idx;
struct otx2_rss_info *rss = &pfvf->hw.rss_info;

rss = &pfvf->hw.rss_info;
otx2_rss_ctx_flow_del(pfvf, ctx_id);
kfree(rss->rss_ctx[ctx_id]);
rss->rss_ctx[ctx_id] = NULL;

if (indir) {
for (idx = 0; idx < rss->rss_size; idx++)
indir[idx] = rss->ind_tbl[idx];
}
return 0;
}

if (hkey)
memcpy(hkey, rss->key, sizeof(rss->key));
static int otx2_rss_ctx_create(struct otx2_nic *pfvf,
u32 *rss_context)
{
struct otx2_rss_info *rss = &pfvf->hw.rss_info;
u8 ctx;

if (hfunc)
*hfunc = ETH_RSS_HASH_TOP;
for (ctx = 0; ctx < MAX_RSS_GROUPS; ctx++) {
if (!rss->rss_ctx[ctx])
break;
}
if (ctx == MAX_RSS_GROUPS)
return -EINVAL;

rss->rss_ctx[ctx] = kzalloc(sizeof(*rss->rss_ctx[ctx]), GFP_KERNEL);
if (!rss->rss_ctx[ctx])
return -ENOMEM;
*rss_context = ctx;

return 0;
}

/* Configure RSS table and hash key */
static int otx2_set_rxfh(struct net_device *dev, const u32 *indir,
const u8 *hkey, const u8 hfunc)
/* RSS context configuration */
static int otx2_set_rxfh_context(struct net_device *dev, const u32 *indir,
const u8 *hkey, const u8 hfunc,
u32 *rss_context, bool delete)
{
struct otx2_nic *pfvf = netdev_priv(dev);
struct otx2_rss_ctx *rss_ctx;
struct otx2_rss_info *rss;
int idx;
int ret, idx;

if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
return -EOPNOTSUPP;
Expand All @@ -688,20 +696,85 @@ static int otx2_set_rxfh(struct net_device *dev, const u32 *indir,
return -EIO;
}

if (hkey) {
memcpy(rss->key, hkey, sizeof(rss->key));
otx2_set_rss_key(pfvf);
}
if (delete)
return otx2_rss_ctx_delete(pfvf, *rss_context);

if (*rss_context == ETH_RXFH_CONTEXT_ALLOC) {
ret = otx2_rss_ctx_create(pfvf, rss_context);
if (ret)
return ret;
}
if (indir) {
rss_ctx = rss->rss_ctx[*rss_context];
for (idx = 0; idx < rss->rss_size; idx++)
rss->ind_tbl[idx] = indir[idx];
rss_ctx->ind_tbl[idx] = indir[idx];
}
otx2_set_rss_table(pfvf, *rss_context);

if (hkey) {
memcpy(rss->key, hkey, sizeof(rss->key));
otx2_set_rss_key(pfvf);
return 0;
}

static int otx2_get_rxfh_context(struct net_device *dev, u32 *indir,
u8 *hkey, u8 *hfunc, u32 rss_context)
{
struct otx2_nic *pfvf = netdev_priv(dev);
struct otx2_rss_ctx *rss_ctx;
struct otx2_rss_info *rss;
int idx, rx_queues;

rss = &pfvf->hw.rss_info;

if (hfunc)
*hfunc = ETH_RSS_HASH_TOP;

if (!indir)
return 0;

if (!rss->enable && rss_context == DEFAULT_RSS_CONTEXT_GROUP) {
rx_queues = pfvf->hw.rx_queues;
for (idx = 0; idx < MAX_RSS_INDIR_TBL_SIZE; idx++)
indir[idx] = ethtool_rxfh_indir_default(idx, rx_queues);
return 0;
}
if (rss_context >= MAX_RSS_GROUPS)
return -ENOENT;

rss_ctx = rss->rss_ctx[rss_context];
if (!rss_ctx)
return -ENOENT;

if (indir) {
for (idx = 0; idx < rss->rss_size; idx++)
indir[idx] = rss_ctx->ind_tbl[idx];
}
if (hkey)
memcpy(hkey, rss->key, sizeof(rss->key));

otx2_set_rss_table(pfvf);
return 0;
}

/* Get RSS configuration */
static int otx2_get_rxfh(struct net_device *dev, u32 *indir,
u8 *hkey, u8 *hfunc)
{
return otx2_get_rxfh_context(dev, indir, hkey, hfunc,
DEFAULT_RSS_CONTEXT_GROUP);
}

/* Configure RSS table and hash key */
static int otx2_set_rxfh(struct net_device *dev, const u32 *indir,
const u8 *hkey, const u8 hfunc)
{

u32 rss_context = DEFAULT_RSS_CONTEXT_GROUP;

return otx2_set_rxfh_context(dev, indir, hkey, hfunc, &rss_context, 0);
}

static u32 otx2_get_msglevel(struct net_device *netdev)
{
struct otx2_nic *pfvf = netdev_priv(netdev);
Expand Down Expand Up @@ -771,6 +844,8 @@ static const struct ethtool_ops otx2_ethtool_ops = {
.get_rxfh_indir_size = otx2_get_rxfh_indir_size,
.get_rxfh = otx2_get_rxfh,
.set_rxfh = otx2_set_rxfh,
.get_rxfh_context = otx2_get_rxfh_context,
.set_rxfh_context = otx2_set_rxfh_context,
.get_msglevel = otx2_get_msglevel,
.set_msglevel = otx2_set_msglevel,
.get_pauseparam = otx2_get_pauseparam,
Expand Down Expand Up @@ -866,6 +941,8 @@ static const struct ethtool_ops otx2vf_ethtool_ops = {
.get_rxfh_indir_size = otx2_get_rxfh_indir_size,
.get_rxfh = otx2_get_rxfh,
.set_rxfh = otx2_set_rxfh,
.get_rxfh_context = otx2_get_rxfh_context,
.set_rxfh_context = otx2_set_rxfh_context,
.get_ringparam = otx2_get_ringparam,
.set_ringparam = otx2_set_ringparam,
.get_coalesce = otx2_get_coalesce,
Expand Down
Loading

0 comments on commit 81a4362

Please sign in to comment.