Skip to content

Commit 85069e9

Browse files
sgoutham-marvelldavem330
authored andcommitted
octeontx2-pf: Receive side scaling support
Adds receive side scaling (RSS) support to distribute pkts/flows across multiple queues. Sets up key, indirection table etc. Also added extraction of HW calculated rxhash and adding to same to SKB ie NETIF_F_RXHASH offload support. Signed-off-by: Sunil Goutham <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 4ff7d14 commit 85069e9

File tree

4 files changed

+167
-1
lines changed

4 files changed

+167
-1
lines changed

drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,126 @@ int otx2_hw_set_mtu(struct otx2_nic *pfvf, int mtu)
106106
return err;
107107
}
108108

109+
static int otx2_set_flowkey_cfg(struct otx2_nic *pfvf)
110+
{
111+
struct otx2_rss_info *rss = &pfvf->hw.rss_info;
112+
struct nix_rss_flowkey_cfg *req;
113+
int err;
114+
115+
otx2_mbox_lock(&pfvf->mbox);
116+
req = otx2_mbox_alloc_msg_nix_rss_flowkey_cfg(&pfvf->mbox);
117+
if (!req) {
118+
otx2_mbox_unlock(&pfvf->mbox);
119+
return -ENOMEM;
120+
}
121+
req->mcam_index = -1; /* Default or reserved index */
122+
req->flowkey_cfg = rss->flowkey_cfg;
123+
req->group = DEFAULT_RSS_CONTEXT_GROUP;
124+
125+
err = otx2_sync_mbox_msg(&pfvf->mbox);
126+
otx2_mbox_unlock(&pfvf->mbox);
127+
return err;
128+
}
129+
130+
static int otx2_set_rss_table(struct otx2_nic *pfvf)
131+
{
132+
struct otx2_rss_info *rss = &pfvf->hw.rss_info;
133+
struct mbox *mbox = &pfvf->mbox;
134+
struct nix_aq_enq_req *aq;
135+
int idx, err;
136+
137+
otx2_mbox_lock(mbox);
138+
/* Get memory to put this msg */
139+
for (idx = 0; idx < rss->rss_size; idx++) {
140+
aq = otx2_mbox_alloc_msg_nix_aq_enq(mbox);
141+
if (!aq) {
142+
/* The shared memory buffer can be full.
143+
* Flush it and retry
144+
*/
145+
err = otx2_sync_mbox_msg(mbox);
146+
if (err) {
147+
otx2_mbox_unlock(mbox);
148+
return err;
149+
}
150+
aq = otx2_mbox_alloc_msg_nix_aq_enq(mbox);
151+
if (!aq) {
152+
otx2_mbox_unlock(mbox);
153+
return -ENOMEM;
154+
}
155+
}
156+
157+
aq->rss.rq = rss->ind_tbl[idx];
158+
159+
/* Fill AQ info */
160+
aq->qidx = idx;
161+
aq->ctype = NIX_AQ_CTYPE_RSS;
162+
aq->op = NIX_AQ_INSTOP_INIT;
163+
}
164+
err = otx2_sync_mbox_msg(mbox);
165+
otx2_mbox_unlock(mbox);
166+
return err;
167+
}
168+
169+
static void otx2_set_rss_key(struct otx2_nic *pfvf)
170+
{
171+
struct otx2_rss_info *rss = &pfvf->hw.rss_info;
172+
u64 *key = (u64 *)&rss->key[4];
173+
int idx;
174+
175+
/* 352bit or 44byte key needs to be configured as below
176+
* NIX_LF_RX_SECRETX0 = key<351:288>
177+
* NIX_LF_RX_SECRETX1 = key<287:224>
178+
* NIX_LF_RX_SECRETX2 = key<223:160>
179+
* NIX_LF_RX_SECRETX3 = key<159:96>
180+
* NIX_LF_RX_SECRETX4 = key<95:32>
181+
* NIX_LF_RX_SECRETX5<63:32> = key<31:0>
182+
*/
183+
otx2_write64(pfvf, NIX_LF_RX_SECRETX(5),
184+
(u64)(*((u32 *)&rss->key)) << 32);
185+
idx = sizeof(rss->key) / sizeof(u64);
186+
while (idx > 0) {
187+
idx--;
188+
otx2_write64(pfvf, NIX_LF_RX_SECRETX(idx), *key++);
189+
}
190+
}
191+
192+
int otx2_rss_init(struct otx2_nic *pfvf)
193+
{
194+
struct otx2_rss_info *rss = &pfvf->hw.rss_info;
195+
int idx, ret = 0;
196+
197+
rss->rss_size = sizeof(rss->ind_tbl);
198+
199+
/* Init RSS key if it is not setup already */
200+
if (!rss->enable)
201+
netdev_rss_key_fill(rss->key, sizeof(rss->key));
202+
otx2_set_rss_key(pfvf);
203+
204+
if (!netif_is_rxfh_configured(pfvf->netdev)) {
205+
/* Default indirection table */
206+
for (idx = 0; idx < rss->rss_size; idx++)
207+
rss->ind_tbl[idx] =
208+
ethtool_rxfh_indir_default(idx,
209+
pfvf->hw.rx_queues);
210+
}
211+
ret = otx2_set_rss_table(pfvf);
212+
if (ret)
213+
return ret;
214+
215+
/* Flowkey or hash config to be used for generating flow tag */
216+
rss->flowkey_cfg = rss->enable ? rss->flowkey_cfg :
217+
NIX_FLOW_KEY_TYPE_IPV4 | NIX_FLOW_KEY_TYPE_IPV6 |
218+
NIX_FLOW_KEY_TYPE_TCP | NIX_FLOW_KEY_TYPE_UDP |
219+
NIX_FLOW_KEY_TYPE_SCTP;
220+
221+
ret = otx2_set_flowkey_cfg(pfvf);
222+
if (ret)
223+
return ret;
224+
225+
rss->enable = true;
226+
return 0;
227+
}
228+
109229
void otx2_config_irq_coalescing(struct otx2_nic *pfvf, int qidx)
110230
{
111231
/* Configure CQE interrupt coalescing parameters
@@ -608,6 +728,8 @@ int otx2_config_nix(struct otx2_nic *pfvf)
608728
nixlf->rq_cnt = pfvf->hw.rx_queues;
609729
nixlf->sq_cnt = pfvf->hw.tx_queues;
610730
nixlf->cq_cnt = pfvf->qset.cq_cnt;
731+
nixlf->rss_sz = MAX_RSS_INDIR_TBL_SIZE;
732+
nixlf->rss_grps = 1; /* Single RSS indir table supported, for now */
611733
nixlf->xqe_sz = NIX_XQESZ_W16;
612734
/* We don't know absolute NPA LF idx attached.
613735
* AF will replace 'RVU_DEFAULT_PF_FUNC' with

drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,16 @@ enum arua_mapped_qtypes {
4141
#define NIX_LF_ERR_VEC 0x81
4242
#define NIX_LF_POISON_VEC 0x82
4343

44+
/* RSS configuration */
45+
struct otx2_rss_info {
46+
u8 enable;
47+
u32 flowkey_cfg;
48+
u16 rss_size;
49+
u8 ind_tbl[MAX_RSS_INDIR_TBL_SIZE];
50+
#define RSS_HASH_KEY_SIZE 44 /* 352 bit key */
51+
u8 key[RSS_HASH_KEY_SIZE];
52+
};
53+
4454
/* NIX (or NPC) RX errors */
4555
enum otx2_errlvl {
4656
NPC_ERRLVL_RE,
@@ -95,6 +105,7 @@ struct mbox {
95105

96106
struct otx2_hw {
97107
struct pci_dev *pdev;
108+
struct otx2_rss_info rss_info;
98109
u16 rx_queues;
99110
u16 tx_queues;
100111
u16 max_queues;
@@ -510,6 +521,9 @@ void otx2_ctx_disable(struct mbox *mbox, int type, bool npa);
510521
void otx2_cleanup_rx_cqes(struct otx2_nic *pfvf, struct otx2_cq_queue *cq);
511522
void otx2_cleanup_tx_cqes(struct otx2_nic *pfvf, struct otx2_cq_queue *cq);
512523

524+
/* RSS configuration APIs*/
525+
int otx2_rss_init(struct otx2_nic *pfvf);
526+
513527
/* Mbox handlers */
514528
void mbox_handler_msix_offset(struct otx2_nic *pfvf,
515529
struct msix_offset_rsp *rsp);

drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,11 @@ int otx2_open(struct net_device *netdev)
838838
if (err)
839839
goto err_disable_napi;
840840

841+
/* Initialize RSS */
842+
err = otx2_rss_init(pf);
843+
if (err)
844+
goto err_disable_napi;
845+
841846
/* Register Queue IRQ handlers */
842847
vec = pf->hw.nix_msixoff + NIX_LF_QINT_VEC_START;
843848
irq_name = &pf->hw.irq_name[vec * NAME_SIZE];
@@ -1237,7 +1242,8 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id)
12371242
pf->iommu_domain = iommu_get_domain_for_dev(dev);
12381243

12391244
netdev->hw_features = (NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
1240-
NETIF_F_IPV6_CSUM | NETIF_F_SG);
1245+
NETIF_F_IPV6_CSUM | NETIF_F_RXHASH |
1246+
NETIF_F_SG);
12411247
netdev->features |= netdev->hw_features;
12421248

12431249
netdev->hw_features |= NETIF_F_LOOPBACK | NETIF_F_RXALL;

drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,28 @@ static void otx2_skb_add_frag(struct otx2_nic *pfvf, struct sk_buff *skb,
115115
pfvf->rbsize, DMA_FROM_DEVICE);
116116
}
117117

118+
static void otx2_set_rxhash(struct otx2_nic *pfvf,
119+
struct nix_cqe_rx_s *cqe, struct sk_buff *skb)
120+
{
121+
enum pkt_hash_types hash_type = PKT_HASH_TYPE_NONE;
122+
struct otx2_rss_info *rss;
123+
u32 hash = 0;
124+
125+
if (!(pfvf->netdev->features & NETIF_F_RXHASH))
126+
return;
127+
128+
rss = &pfvf->hw.rss_info;
129+
if (rss->flowkey_cfg) {
130+
if (rss->flowkey_cfg &
131+
~(NIX_FLOW_KEY_TYPE_IPV4 | NIX_FLOW_KEY_TYPE_IPV6))
132+
hash_type = PKT_HASH_TYPE_L4;
133+
else
134+
hash_type = PKT_HASH_TYPE_L3;
135+
hash = cqe->hdr.flow_tag;
136+
}
137+
skb_set_hash(skb, hash, hash_type);
138+
}
139+
118140
static bool otx2_check_rcv_errors(struct otx2_nic *pfvf,
119141
struct nix_cqe_rx_s *cqe, int qidx)
120142
{
@@ -194,6 +216,8 @@ static void otx2_rcv_pkt_handler(struct otx2_nic *pfvf,
194216
otx2_skb_add_frag(pfvf, skb, cqe->sg.seg_addr, cqe->sg.seg_size);
195217
cq->pool_ptrs++;
196218

219+
otx2_set_rxhash(pfvf, cqe, skb);
220+
197221
skb_record_rx_queue(skb, cq->cq_idx);
198222
if (pfvf->netdev->features & NETIF_F_RXCSUM)
199223
skb->ip_summed = CHECKSUM_UNNECESSARY;

0 commit comments

Comments
 (0)