Skip to content

Commit 3ca6c4c

Browse files
sgoutham-marvelldavem330
authored andcommitted
octeontx2-pf: Add packet transmission support
This patch adds the packet transmission support. For a given skb prepares send queue descriptors (SQEs) and pushes them to HW. Here driver doesn't maintain it's own SQ rings, SQEs are pushed to HW using a silicon specific operations called LMTST. From the instuction HW derives the transmit queue number and queues the SQE to that queue. These LMTST instructions are designed to avoid queue maintenance in SW and lockless behavior ie when multiple cores are trying to add SQEs to same queue then HW will takecare of serialization, no need for SW to hold locks. Also supports scatter/gather. Co-developed-by: Geetha sowjanya <[email protected]> Signed-off-by: Geetha sowjanya <[email protected]> Signed-off-by: Sunil Goutham <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent abe0254 commit 3ca6c4c

File tree

6 files changed

+470
-2
lines changed

6 files changed

+470
-2
lines changed

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,9 +287,15 @@ static int otx2_sq_init(struct otx2_nic *pfvf, u16 qidx, u16 sqb_aura)
287287
return err;
288288

289289
sq->sqe_base = sq->sqe->base;
290+
sq->sg = kcalloc(qset->sqe_cnt, sizeof(struct sg_list), GFP_KERNEL);
291+
if (!sq->sg)
292+
return -ENOMEM;
290293

294+
sq->head = 0;
291295
sq->sqe_per_sqb = (pfvf->hw.sqb_size / sq->sqe_size) - 1;
292296
sq->num_sqbs = (qset->sqe_cnt + sq->sqe_per_sqb) / sq->sqe_per_sqb;
297+
/* Set SQE threshold to 10% of total SQEs */
298+
sq->sqe_thresh = ((sq->num_sqbs * sq->sqe_per_sqb) * 10) / 100;
293299
sq->aura_id = sqb_aura;
294300
sq->aura_fc_addr = pool->fc_addr->base;
295301
sq->lmt_addr = (__force u64 *)(pfvf->reg_base + LMT_LF_LMTLINEX(qidx));
@@ -338,6 +344,7 @@ static int otx2_cq_init(struct otx2_nic *pfvf, u16 qidx)
338344
cq->cqe_cnt = qset->rqe_cnt;
339345
} else {
340346
cq->cq_type = CQ_TX;
347+
cq->cint_idx = qidx - pfvf->hw.rx_queues;
341348
cq->cqe_cnt = qset->sqe_cnt;
342349
}
343350
cq->cqe_size = pfvf->qset.xqe_size;

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,9 +300,21 @@ static inline u64 otx2_atomic64_add(u64 incr, u64 *ptr)
300300
return result;
301301
}
302302

303+
static inline u64 otx2_lmt_flush(uint64_t addr)
304+
{
305+
u64 result = 0;
306+
307+
__asm__ volatile(".cpu generic+lse\n"
308+
"ldeor xzr,%x[rf],[%[rs]]"
309+
: [rf]"=r"(result)
310+
: [rs]"r"(addr));
311+
return result;
312+
}
313+
303314
#else
304315
#define otx2_write128(lo, hi, addr)
305316
#define otx2_atomic64_add(incr, ptr) ({ *ptr += incr; })
317+
#define otx2_lmt_flush(addr) ({ 0; })
306318
#endif
307319

308320
/* Alloc pointer from pool/aura */
@@ -475,6 +487,7 @@ dma_addr_t otx2_alloc_rbuf(struct otx2_nic *pfvf, struct otx2_pool *pool,
475487
gfp_t gfp);
476488
void otx2_ctx_disable(struct mbox *mbox, int type, bool npa);
477489
void otx2_cleanup_rx_cqes(struct otx2_nic *pfvf, struct otx2_cq_queue *cq);
490+
void otx2_cleanup_tx_cqes(struct otx2_nic *pfvf, struct otx2_cq_queue *cq);
478491

479492
/* Mbox handlers */
480493
void mbox_handler_msix_offset(struct otx2_nic *pfvf,

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

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@ static void otx2_free_sq_res(struct otx2_nic *pf)
445445
for (qidx = 0; qidx < pf->hw.tx_queues; qidx++) {
446446
sq = &qset->sq[qidx];
447447
qmem_free(pf->dev, sq->sqe);
448+
kfree(sq->sg);
448449
kfree(sq->sqb_ptrs);
449450
}
450451
}
@@ -569,6 +570,8 @@ static void otx2_free_hw_resources(struct otx2_nic *pf)
569570
cq = &qset->cq[qidx];
570571
if (cq->cq_type == CQ_RX)
571572
otx2_cleanup_rx_cqes(pf, cq);
573+
else
574+
otx2_cleanup_tx_cqes(pf, cq);
572575
}
573576

574577
otx2_free_sq_res(pf);
@@ -741,9 +744,41 @@ static int otx2_stop(struct net_device *netdev)
741744
return 0;
742745
}
743746

747+
static netdev_tx_t otx2_xmit(struct sk_buff *skb, struct net_device *netdev)
748+
{
749+
struct otx2_nic *pf = netdev_priv(netdev);
750+
int qidx = skb_get_queue_mapping(skb);
751+
struct otx2_snd_queue *sq;
752+
struct netdev_queue *txq;
753+
754+
/* Check for minimum packet length */
755+
if (skb->len <= ETH_HLEN) {
756+
dev_kfree_skb(skb);
757+
return NETDEV_TX_OK;
758+
}
759+
760+
sq = &pf->qset.sq[qidx];
761+
txq = netdev_get_tx_queue(netdev, qidx);
762+
763+
if (!otx2_sq_append_skb(netdev, sq, skb, qidx)) {
764+
netif_tx_stop_queue(txq);
765+
766+
/* Check again, incase SQBs got freed up */
767+
smp_mb();
768+
if (((sq->num_sqbs - *sq->aura_fc_addr) * sq->sqe_per_sqb)
769+
> sq->sqe_thresh)
770+
netif_tx_wake_queue(txq);
771+
772+
return NETDEV_TX_BUSY;
773+
}
774+
775+
return NETDEV_TX_OK;
776+
}
777+
744778
static const struct net_device_ops otx2_netdev_ops = {
745779
.ndo_open = otx2_open,
746780
.ndo_stop = otx2_stop,
781+
.ndo_start_xmit = otx2_xmit,
747782
};
748783

749784
static int otx2_check_pf_usable(struct otx2_nic *nic)
@@ -910,7 +945,8 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id)
910945
*/
911946
pf->iommu_domain = iommu_get_domain_for_dev(dev);
912947

913-
netdev->hw_features = NETIF_F_RXCSUM;
948+
netdev->hw_features = (NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
949+
NETIF_F_IPV6_CSUM | NETIF_F_SG);
914950
netdev->features |= netdev->hw_features;
915951

916952
netdev->hw_features |= NETIF_F_RXALL;

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

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,21 @@ enum nix_send_ldtype {
2828
NIX_SEND_LDTYPE_LDWB = 0x2,
2929
};
3030

31+
/* CSUM offload */
32+
enum nix_sendl3type {
33+
NIX_SENDL3TYPE_NONE = 0x0,
34+
NIX_SENDL3TYPE_IP4 = 0x2,
35+
NIX_SENDL3TYPE_IP4_CKSUM = 0x3,
36+
NIX_SENDL3TYPE_IP6 = 0x4,
37+
};
38+
39+
enum nix_sendl4type {
40+
NIX_SENDL4TYPE_NONE,
41+
NIX_SENDL4TYPE_TCP_CKSUM,
42+
NIX_SENDL4TYPE_SCTP_CKSUM,
43+
NIX_SENDL4TYPE_UDP_CKSUM,
44+
};
45+
3146
/* NIX wqe/cqe types */
3247
enum nix_xqe_type {
3348
NIX_XQE_TYPE_INVALID = 0x0,
@@ -51,6 +66,20 @@ enum nix_subdc {
5166
NIX_SUBDC_SOD = 0xf,
5267
};
5368

69+
/* Algorithm for nix_sqe_mem_s header (value of the `alg` field) */
70+
enum nix_sendmemalg {
71+
NIX_SENDMEMALG_E_SET = 0x0,
72+
NIX_SENDMEMALG_E_SETTSTMP = 0x1,
73+
NIX_SENDMEMALG_E_SETRSLT = 0x2,
74+
NIX_SENDMEMALG_E_ADD = 0x8,
75+
NIX_SENDMEMALG_E_SUB = 0x9,
76+
NIX_SENDMEMALG_E_ADDLEN = 0xa,
77+
NIX_SENDMEMALG_E_SUBLEN = 0xb,
78+
NIX_SENDMEMALG_E_ADDMBUF = 0xc,
79+
NIX_SENDMEMALG_E_SUBMBUF = 0xd,
80+
NIX_SENDMEMALG_E_ENUM_LAST = 0xe,
81+
};
82+
5483
/* NIX CQE header structure */
5584
struct nix_cqe_hdr_s {
5685
u64 flow_tag : 32;
@@ -130,10 +159,90 @@ struct nix_rx_sg_s {
130159
u64 seg3_addr;
131160
};
132161

162+
struct nix_send_comp_s {
163+
u64 status : 8;
164+
u64 sqe_id : 16;
165+
u64 rsvd_24_63 : 40;
166+
};
167+
133168
struct nix_cqe_rx_s {
134169
struct nix_cqe_hdr_s hdr;
135170
struct nix_rx_parse_s parse;
136171
struct nix_rx_sg_s sg;
137172
};
138173

174+
struct nix_cqe_tx_s {
175+
struct nix_cqe_hdr_s hdr;
176+
struct nix_send_comp_s comp;
177+
};
178+
179+
/* NIX SQE header structure */
180+
struct nix_sqe_hdr_s {
181+
u64 total : 18; /* W0 */
182+
u64 reserved_18 : 1;
183+
u64 df : 1;
184+
u64 aura : 20;
185+
u64 sizem1 : 3;
186+
u64 pnc : 1;
187+
u64 sq : 20;
188+
u64 ol3ptr : 8; /* W1 */
189+
u64 ol4ptr : 8;
190+
u64 il3ptr : 8;
191+
u64 il4ptr : 8;
192+
u64 ol3type : 4;
193+
u64 ol4type : 4;
194+
u64 il3type : 4;
195+
u64 il4type : 4;
196+
u64 sqe_id : 16;
197+
198+
};
199+
200+
/* NIX send extended header subdescriptor structure */
201+
struct nix_sqe_ext_s {
202+
u64 lso_mps : 14; /* W0 */
203+
u64 lso : 1;
204+
u64 tstmp : 1;
205+
u64 lso_sb : 8;
206+
u64 lso_format : 5;
207+
u64 rsvd_31_29 : 3;
208+
u64 shp_chg : 9;
209+
u64 shp_dis : 1;
210+
u64 shp_ra : 2;
211+
u64 markptr : 8;
212+
u64 markform : 7;
213+
u64 mark_en : 1;
214+
u64 subdc : 4;
215+
u64 vlan0_ins_ptr : 8; /* W1 */
216+
u64 vlan0_ins_tci : 16;
217+
u64 vlan1_ins_ptr : 8;
218+
u64 vlan1_ins_tci : 16;
219+
u64 vlan0_ins_ena : 1;
220+
u64 vlan1_ins_ena : 1;
221+
u64 rsvd_127_114 : 14;
222+
};
223+
224+
struct nix_sqe_sg_s {
225+
u64 seg1_size : 16;
226+
u64 seg2_size : 16;
227+
u64 seg3_size : 16;
228+
u64 segs : 2;
229+
u64 rsvd_54_50 : 5;
230+
u64 i1 : 1;
231+
u64 i2 : 1;
232+
u64 i3 : 1;
233+
u64 ld_type : 2;
234+
u64 subdc : 4;
235+
};
236+
237+
/* NIX send memory subdescriptor structure */
238+
struct nix_sqe_mem_s {
239+
u64 offset : 16; /* W0 */
240+
u64 rsvd_52_16 : 37;
241+
u64 wmem : 1;
242+
u64 dsz : 2;
243+
u64 alg : 4;
244+
u64 subdc : 4;
245+
u64 addr; /* W1 */
246+
};
247+
139248
#endif /* OTX2_STRUCT_H */

0 commit comments

Comments
 (0)