Skip to content

Commit 4c236d5

Browse files
Geetha sowjanyadavem330
authored andcommitted
octeontx2-pf: cn10k: Use LMTST lines for NPA/NIX operations
This patch adds support to use new LMTST lines for NPA batch free and burst SQE flush. Adds new dev_hw_ops structure to hold platform specific functions and create new files cn10k.c and cn10k.h. Signed-off-by: Geetha sowjanya <[email protected]> Signed-off-by: Sunil Goutham <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 6e8ad43 commit 4c236d5

File tree

11 files changed

+336
-135
lines changed

11 files changed

+336
-135
lines changed

drivers/net/ethernet/marvell/octeontx2/nic/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ obj-$(CONFIG_OCTEONTX2_PF) += rvu_nicpf.o
77
obj-$(CONFIG_OCTEONTX2_VF) += rvu_nicvf.o
88

99
rvu_nicpf-y := otx2_pf.o otx2_common.o otx2_txrx.o otx2_ethtool.o \
10-
otx2_ptp.o otx2_flows.o
10+
otx2_ptp.o otx2_flows.o cn10k.o
1111
rvu_nicvf-y := otx2_vf.o
1212

1313
ccflags-y += -I$(srctree)/drivers/net/ethernet/marvell/octeontx2/af
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Marvell OcteonTx2 RVU Physcial Function ethernet driver
3+
*
4+
* Copyright (C) 2020 Marvell.
5+
*/
6+
7+
#include "cn10k.h"
8+
#include "otx2_reg.h"
9+
#include "otx2_struct.h"
10+
11+
static struct dev_hw_ops otx2_hw_ops = {
12+
.sq_aq_init = otx2_sq_aq_init,
13+
.sqe_flush = otx2_sqe_flush,
14+
.aura_freeptr = otx2_aura_freeptr,
15+
.refill_pool_ptrs = otx2_refill_pool_ptrs,
16+
};
17+
18+
static struct dev_hw_ops cn10k_hw_ops = {
19+
.sq_aq_init = cn10k_sq_aq_init,
20+
.sqe_flush = cn10k_sqe_flush,
21+
.aura_freeptr = cn10k_aura_freeptr,
22+
.refill_pool_ptrs = cn10k_refill_pool_ptrs,
23+
};
24+
25+
int cn10k_pf_lmtst_init(struct otx2_nic *pf)
26+
{
27+
int size, num_lines;
28+
u64 base;
29+
30+
if (!test_bit(CN10K_LMTST, &pf->hw.cap_flag)) {
31+
pf->hw_ops = &otx2_hw_ops;
32+
return 0;
33+
}
34+
35+
pf->hw_ops = &cn10k_hw_ops;
36+
base = pci_resource_start(pf->pdev, PCI_MBOX_BAR_NUM) +
37+
(MBOX_SIZE * (pf->total_vfs + 1));
38+
39+
size = pci_resource_len(pf->pdev, PCI_MBOX_BAR_NUM) -
40+
(MBOX_SIZE * (pf->total_vfs + 1));
41+
42+
pf->hw.lmt_base = ioremap(base, size);
43+
44+
if (!pf->hw.lmt_base) {
45+
dev_err(pf->dev, "Unable to map PF LMTST region\n");
46+
return -ENOMEM;
47+
}
48+
49+
/* FIXME: Get the num of LMTST lines from LMT table */
50+
pf->tot_lmt_lines = size / LMT_LINE_SIZE;
51+
num_lines = (pf->tot_lmt_lines - NIX_LMTID_BASE) /
52+
pf->hw.tx_queues;
53+
/* Number of LMT lines per SQ queues */
54+
pf->nix_lmt_lines = num_lines > 32 ? 32 : num_lines;
55+
56+
pf->nix_lmt_size = pf->nix_lmt_lines * LMT_LINE_SIZE;
57+
return 0;
58+
}
59+
60+
int cn10k_vf_lmtst_init(struct otx2_nic *vf)
61+
{
62+
int size, num_lines;
63+
64+
if (!test_bit(CN10K_LMTST, &vf->hw.cap_flag)) {
65+
vf->hw_ops = &otx2_hw_ops;
66+
return 0;
67+
}
68+
69+
vf->hw_ops = &cn10k_hw_ops;
70+
size = pci_resource_len(vf->pdev, PCI_MBOX_BAR_NUM);
71+
vf->hw.lmt_base = ioremap_wc(pci_resource_start(vf->pdev,
72+
PCI_MBOX_BAR_NUM),
73+
size);
74+
if (!vf->hw.lmt_base) {
75+
dev_err(vf->dev, "Unable to map VF LMTST region\n");
76+
return -ENOMEM;
77+
}
78+
79+
vf->tot_lmt_lines = size / LMT_LINE_SIZE;
80+
/* LMTST lines per SQ */
81+
num_lines = (vf->tot_lmt_lines - NIX_LMTID_BASE) /
82+
vf->hw.tx_queues;
83+
vf->nix_lmt_lines = num_lines > 32 ? 32 : num_lines;
84+
vf->nix_lmt_size = vf->nix_lmt_lines * LMT_LINE_SIZE;
85+
return 0;
86+
}
87+
EXPORT_SYMBOL(cn10k_vf_lmtst_init);
88+
89+
int cn10k_sq_aq_init(void *dev, u16 qidx, u16 sqb_aura)
90+
{
91+
struct nix_cn10k_aq_enq_req *aq;
92+
struct otx2_nic *pfvf = dev;
93+
struct otx2_snd_queue *sq;
94+
95+
sq = &pfvf->qset.sq[qidx];
96+
sq->lmt_addr = (__force u64 *)((u64)pfvf->hw.nix_lmt_base +
97+
(qidx * pfvf->nix_lmt_size));
98+
99+
/* Get memory to put this msg */
100+
aq = otx2_mbox_alloc_msg_nix_cn10k_aq_enq(&pfvf->mbox);
101+
if (!aq)
102+
return -ENOMEM;
103+
104+
aq->sq.cq = pfvf->hw.rx_queues + qidx;
105+
aq->sq.max_sqe_size = NIX_MAXSQESZ_W16; /* 128 byte */
106+
aq->sq.cq_ena = 1;
107+
aq->sq.ena = 1;
108+
/* Only one SMQ is allocated, map all SQ's to that SMQ */
109+
aq->sq.smq = pfvf->hw.txschq_list[NIX_TXSCH_LVL_SMQ][0];
110+
/* FIXME: set based on NIX_AF_DWRR_RPM_MTU*/
111+
aq->sq.smq_rr_weight = OTX2_MAX_MTU;
112+
aq->sq.default_chan = pfvf->hw.tx_chan_base;
113+
aq->sq.sqe_stype = NIX_STYPE_STF; /* Cache SQB */
114+
aq->sq.sqb_aura = sqb_aura;
115+
aq->sq.sq_int_ena = NIX_SQINT_BITS;
116+
aq->sq.qint_idx = 0;
117+
/* Due pipelining impact minimum 2000 unused SQ CQE's
118+
* need to maintain to avoid CQ overflow.
119+
*/
120+
aq->sq.cq_limit = ((SEND_CQ_SKID * 256) / (pfvf->qset.sqe_cnt));
121+
122+
/* Fill AQ info */
123+
aq->qidx = qidx;
124+
aq->ctype = NIX_AQ_CTYPE_SQ;
125+
aq->op = NIX_AQ_INSTOP_INIT;
126+
127+
return otx2_sync_mbox_msg(&pfvf->mbox);
128+
}
129+
130+
#define NPA_MAX_BURST 16
131+
void cn10k_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq)
132+
{
133+
struct otx2_nic *pfvf = dev;
134+
u64 ptrs[NPA_MAX_BURST];
135+
int num_ptrs = 1;
136+
dma_addr_t bufptr;
137+
138+
/* Refill pool with new buffers */
139+
while (cq->pool_ptrs) {
140+
if (otx2_alloc_buffer(pfvf, cq, &bufptr)) {
141+
if (num_ptrs--)
142+
__cn10k_aura_freeptr(pfvf, cq->cq_idx, ptrs,
143+
num_ptrs,
144+
cq->rbpool->lmt_addr);
145+
break;
146+
}
147+
cq->pool_ptrs--;
148+
ptrs[num_ptrs] = (u64)bufptr + OTX2_HEAD_ROOM;
149+
num_ptrs++;
150+
if (num_ptrs == NPA_MAX_BURST || cq->pool_ptrs == 0) {
151+
__cn10k_aura_freeptr(pfvf, cq->cq_idx, ptrs,
152+
num_ptrs,
153+
cq->rbpool->lmt_addr);
154+
num_ptrs = 1;
155+
}
156+
}
157+
}
158+
159+
void cn10k_sqe_flush(void *dev, struct otx2_snd_queue *sq, int size, int qidx)
160+
{
161+
struct otx2_nic *pfvf = dev;
162+
int lmt_id = NIX_LMTID_BASE + (qidx * pfvf->nix_lmt_lines);
163+
u64 val = 0, tar_addr = 0;
164+
165+
/* FIXME: val[0:10] LMT_ID.
166+
* [12:15] no of LMTST - 1 in the burst.
167+
* [19:63] data size of each LMTST in the burst except first.
168+
*/
169+
val = (lmt_id & 0x7FF);
170+
/* Target address for LMTST flush tells HW how many 128bit
171+
* words are present.
172+
* tar_addr[6:4] size of first LMTST - 1 in units of 128b.
173+
*/
174+
tar_addr |= sq->io_addr | (((size / 16) - 1) & 0x7) << 4;
175+
dma_wmb();
176+
memcpy(sq->lmt_addr, sq->sqe_base, size);
177+
cn10k_lmt_flush(val, tar_addr);
178+
179+
sq->head++;
180+
sq->head &= (sq->sqe_cnt - 1);
181+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/* SPDX-License-Identifier: GPL-2.0
2+
* Marvell OcteonTx2 RVU Ethernet driver
3+
*
4+
* Copyright (C) 2020 Marvell.
5+
*/
6+
7+
#ifndef CN10K_H
8+
#define CN10K_H
9+
10+
#include "otx2_common.h"
11+
12+
void cn10k_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq);
13+
void cn10k_sqe_flush(void *dev, struct otx2_snd_queue *sq, int size, int qidx);
14+
int cn10k_sq_aq_init(void *dev, u16 qidx, u16 sqb_aura);
15+
int cn10k_pf_lmtst_init(struct otx2_nic *pf);
16+
int cn10k_vf_lmtst_init(struct otx2_nic *vf);
17+
#endif /* CN10K_H */

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

Lines changed: 36 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "otx2_reg.h"
1616
#include "otx2_common.h"
1717
#include "otx2_struct.h"
18+
#include "cn10k.h"
1819

1920
static void otx2_nix_rq_op_stats(struct queue_stats *stats,
2021
struct otx2_nic *pfvf, int qidx)
@@ -526,6 +527,26 @@ static int otx2_alloc_rbuf(struct otx2_nic *pfvf, struct otx2_pool *pool,
526527
return ret;
527528
}
528529

530+
int otx2_alloc_buffer(struct otx2_nic *pfvf, struct otx2_cq_queue *cq,
531+
dma_addr_t *dma)
532+
{
533+
if (unlikely(__otx2_alloc_rbuf(pfvf, cq->rbpool, dma))) {
534+
struct refill_work *work;
535+
struct delayed_work *dwork;
536+
537+
work = &pfvf->refill_wrk[cq->cq_idx];
538+
dwork = &work->pool_refill_work;
539+
/* Schedule a task if no other task is running */
540+
if (!cq->refill_task_sched) {
541+
cq->refill_task_sched = true;
542+
schedule_delayed_work(dwork,
543+
msecs_to_jiffies(100));
544+
}
545+
return -ENOMEM;
546+
}
547+
return 0;
548+
}
549+
529550
void otx2_tx_timeout(struct net_device *netdev, unsigned int txq)
530551
{
531552
struct otx2_nic *pfvf = netdev_priv(netdev);
@@ -728,9 +749,6 @@ void otx2_sqb_flush(struct otx2_nic *pfvf)
728749
#define RQ_PASS_LVL_AURA (255 - ((95 * 256) / 100)) /* RED when 95% is full */
729750
#define RQ_DROP_LVL_AURA (255 - ((99 * 256) / 100)) /* Drop when 99% is full */
730751

731-
/* Send skid of 2000 packets required for CQ size of 4K CQEs. */
732-
#define SEND_CQ_SKID 2000
733-
734752
static int otx2_rq_init(struct otx2_nic *pfvf, u16 qidx, u16 lpb_aura)
735753
{
736754
struct otx2_qset *qset = &pfvf->qset;
@@ -764,45 +782,14 @@ static int otx2_rq_init(struct otx2_nic *pfvf, u16 qidx, u16 lpb_aura)
764782
return otx2_sync_mbox_msg(&pfvf->mbox);
765783
}
766784

767-
static int cn10k_sq_aq_init(struct otx2_nic *pfvf, u16 qidx, u16 sqb_aura)
768-
{
769-
struct nix_cn10k_aq_enq_req *aq;
770-
771-
/* Get memory to put this msg */
772-
aq = otx2_mbox_alloc_msg_nix_cn10k_aq_enq(&pfvf->mbox);
773-
if (!aq)
774-
return -ENOMEM;
775-
776-
aq->sq.cq = pfvf->hw.rx_queues + qidx;
777-
aq->sq.max_sqe_size = NIX_MAXSQESZ_W16; /* 128 byte */
778-
aq->sq.cq_ena = 1;
779-
aq->sq.ena = 1;
780-
/* Only one SMQ is allocated, map all SQ's to that SMQ */
781-
aq->sq.smq = pfvf->hw.txschq_list[NIX_TXSCH_LVL_SMQ][0];
782-
/* FIXME: set based on NIX_AF_DWRR_RPM_MTU*/
783-
aq->sq.smq_rr_weight = OTX2_MAX_MTU;
784-
aq->sq.default_chan = pfvf->hw.tx_chan_base;
785-
aq->sq.sqe_stype = NIX_STYPE_STF; /* Cache SQB */
786-
aq->sq.sqb_aura = sqb_aura;
787-
aq->sq.sq_int_ena = NIX_SQINT_BITS;
788-
aq->sq.qint_idx = 0;
789-
/* Due pipelining impact minimum 2000 unused SQ CQE's
790-
* need to maintain to avoid CQ overflow.
791-
*/
792-
aq->sq.cq_limit = ((SEND_CQ_SKID * 256) / (pfvf->qset.sqe_cnt));
793-
794-
/* Fill AQ info */
795-
aq->qidx = qidx;
796-
aq->ctype = NIX_AQ_CTYPE_SQ;
797-
aq->op = NIX_AQ_INSTOP_INIT;
798-
799-
return otx2_sync_mbox_msg(&pfvf->mbox);
800-
}
801-
802-
static int otx2_sq_aq_init(struct otx2_nic *pfvf, u16 qidx, u16 sqb_aura)
785+
int otx2_sq_aq_init(void *dev, u16 qidx, u16 sqb_aura)
803786
{
787+
struct otx2_nic *pfvf = dev;
788+
struct otx2_snd_queue *sq;
804789
struct nix_aq_enq_req *aq;
805790

791+
sq = &pfvf->qset.sq[qidx];
792+
sq->lmt_addr = (__force u64 *)(pfvf->reg_base + LMT_LF_LMTLINEX(qidx));
806793
/* Get memory to put this msg */
807794
aq = otx2_mbox_alloc_msg_nix_aq_enq(&pfvf->mbox);
808795
if (!aq)
@@ -873,16 +860,12 @@ static int otx2_sq_init(struct otx2_nic *pfvf, u16 qidx, u16 sqb_aura)
873860
sq->sqe_thresh = ((sq->num_sqbs * sq->sqe_per_sqb) * 10) / 100;
874861
sq->aura_id = sqb_aura;
875862
sq->aura_fc_addr = pool->fc_addr->base;
876-
sq->lmt_addr = (__force u64 *)(pfvf->reg_base + LMT_LF_LMTLINEX(qidx));
877863
sq->io_addr = (__force u64)otx2_get_regaddr(pfvf, NIX_LF_OP_SENDX(0));
878864

879865
sq->stats.bytes = 0;
880866
sq->stats.pkts = 0;
881867

882-
if (is_dev_otx2(pfvf->pdev))
883-
return otx2_sq_aq_init(pfvf, qidx, sqb_aura);
884-
else
885-
return cn10k_sq_aq_init(pfvf, qidx, sqb_aura);
868+
return pfvf->hw_ops->sq_aq_init(pfvf, qidx, sqb_aura);
886869

887870
}
888871

@@ -987,7 +970,7 @@ static void otx2_pool_refill_task(struct work_struct *work)
987970
}
988971
return;
989972
}
990-
otx2_aura_freeptr(pfvf, qidx, bufptr + OTX2_HEAD_ROOM);
973+
pfvf->hw_ops->aura_freeptr(pfvf, qidx, bufptr + OTX2_HEAD_ROOM);
991974
cq->pool_ptrs--;
992975
}
993976
cq->refill_task_sched = false;
@@ -1231,6 +1214,11 @@ static int otx2_pool_init(struct otx2_nic *pfvf, u16 pool_id,
12311214

12321215
pool->rbsize = buf_size;
12331216

1217+
/* Set LMTST addr for NPA batch free */
1218+
if (test_bit(CN10K_LMTST, &pfvf->hw.cap_flag))
1219+
pool->lmt_addr = (__force u64 *)((u64)pfvf->hw.npa_lmt_base +
1220+
(pool_id * LMT_LINE_SIZE));
1221+
12341222
/* Initialize this pool's context via AF */
12351223
aq = otx2_mbox_alloc_msg_npa_aq_enq(&pfvf->mbox);
12361224
if (!aq) {
@@ -1319,7 +1307,7 @@ int otx2_sq_aura_pool_init(struct otx2_nic *pfvf)
13191307
for (ptr = 0; ptr < num_sqbs; ptr++) {
13201308
if (otx2_alloc_rbuf(pfvf, pool, &bufptr))
13211309
return -ENOMEM;
1322-
otx2_aura_freeptr(pfvf, pool_id, bufptr);
1310+
pfvf->hw_ops->aura_freeptr(pfvf, pool_id, bufptr);
13231311
sq->sqb_ptrs[sq->sqb_count++] = (u64)bufptr;
13241312
}
13251313
}
@@ -1369,8 +1357,8 @@ int otx2_rq_aura_pool_init(struct otx2_nic *pfvf)
13691357
for (ptr = 0; ptr < num_ptrs; ptr++) {
13701358
if (otx2_alloc_rbuf(pfvf, pool, &bufptr))
13711359
return -ENOMEM;
1372-
otx2_aura_freeptr(pfvf, pool_id,
1373-
bufptr + OTX2_HEAD_ROOM);
1360+
pfvf->hw_ops->aura_freeptr(pfvf, pool_id,
1361+
bufptr + OTX2_HEAD_ROOM);
13741362
}
13751363
}
13761364

0 commit comments

Comments
 (0)