Skip to content

Commit 9e58c8b

Browse files
LorenzoBianconidavem330
authored andcommitted
net: mvneta: make tx buffer array agnostic
Allow tx buffer array to contain both skb and xdp buffers in order to enable xdp frame recycling adding XDP_TX verdict support Signed-off-by: Lorenzo Bianconi <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent fa383f6 commit 9e58c8b

File tree

1 file changed

+43
-23
lines changed

1 file changed

+43
-23
lines changed

drivers/net/ethernet/marvell/mvneta.c

Lines changed: 43 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,20 @@ struct mvneta_rx_desc {
561561
};
562562
#endif
563563

564+
enum mvneta_tx_buf_type {
565+
MVNETA_TYPE_SKB,
566+
MVNETA_TYPE_XDP_TX,
567+
MVNETA_TYPE_XDP_NDO,
568+
};
569+
570+
struct mvneta_tx_buf {
571+
enum mvneta_tx_buf_type type;
572+
union {
573+
struct xdp_frame *xdpf;
574+
struct sk_buff *skb;
575+
};
576+
};
577+
564578
struct mvneta_tx_queue {
565579
/* Number of this TX queue, in the range 0-7 */
566580
u8 id;
@@ -576,8 +590,8 @@ struct mvneta_tx_queue {
576590
int tx_stop_threshold;
577591
int tx_wake_threshold;
578592

579-
/* Array of transmitted skb */
580-
struct sk_buff **tx_skb;
593+
/* Array of transmitted buffers */
594+
struct mvneta_tx_buf *buf;
581595

582596
/* Index of last TX DMA descriptor that was inserted */
583597
int txq_put_index;
@@ -1780,24 +1794,22 @@ static void mvneta_txq_bufs_free(struct mvneta_port *pp,
17801794
int i;
17811795

17821796
for (i = 0; i < num; i++) {
1797+
struct mvneta_tx_buf *buf = &txq->buf[txq->txq_get_index];
17831798
struct mvneta_tx_desc *tx_desc = txq->descs +
17841799
txq->txq_get_index;
1785-
struct sk_buff *skb = txq->tx_skb[txq->txq_get_index];
1786-
1787-
if (skb) {
1788-
bytes_compl += skb->len;
1789-
pkts_compl++;
1790-
}
17911800

17921801
mvneta_txq_inc_get(txq);
17931802

17941803
if (!IS_TSO_HEADER(txq, tx_desc->buf_phys_addr))
17951804
dma_unmap_single(pp->dev->dev.parent,
17961805
tx_desc->buf_phys_addr,
17971806
tx_desc->data_size, DMA_TO_DEVICE);
1798-
if (!skb)
1807+
if (!buf->skb)
17991808
continue;
1800-
dev_kfree_skb_any(skb);
1809+
1810+
bytes_compl += buf->skb->len;
1811+
pkts_compl++;
1812+
dev_kfree_skb_any(buf->skb);
18011813
}
18021814

18031815
netdev_tx_completed_queue(nq, pkts_compl, bytes_compl);
@@ -2324,16 +2336,19 @@ static inline void
23242336
mvneta_tso_put_hdr(struct sk_buff *skb,
23252337
struct mvneta_port *pp, struct mvneta_tx_queue *txq)
23262338
{
2327-
struct mvneta_tx_desc *tx_desc;
23282339
int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
2340+
struct mvneta_tx_buf *buf = &txq->buf[txq->txq_put_index];
2341+
struct mvneta_tx_desc *tx_desc;
23292342

2330-
txq->tx_skb[txq->txq_put_index] = NULL;
23312343
tx_desc = mvneta_txq_next_desc_get(txq);
23322344
tx_desc->data_size = hdr_len;
23332345
tx_desc->command = mvneta_skb_tx_csum(pp, skb);
23342346
tx_desc->command |= MVNETA_TXD_F_DESC;
23352347
tx_desc->buf_phys_addr = txq->tso_hdrs_phys +
23362348
txq->txq_put_index * TSO_HEADER_SIZE;
2349+
buf->type = MVNETA_TYPE_SKB;
2350+
buf->skb = NULL;
2351+
23372352
mvneta_txq_inc_put(txq);
23382353
}
23392354

@@ -2342,6 +2357,7 @@ mvneta_tso_put_data(struct net_device *dev, struct mvneta_tx_queue *txq,
23422357
struct sk_buff *skb, char *data, int size,
23432358
bool last_tcp, bool is_last)
23442359
{
2360+
struct mvneta_tx_buf *buf = &txq->buf[txq->txq_put_index];
23452361
struct mvneta_tx_desc *tx_desc;
23462362

23472363
tx_desc = mvneta_txq_next_desc_get(txq);
@@ -2355,15 +2371,16 @@ mvneta_tso_put_data(struct net_device *dev, struct mvneta_tx_queue *txq,
23552371
}
23562372

23572373
tx_desc->command = 0;
2358-
txq->tx_skb[txq->txq_put_index] = NULL;
2374+
buf->type = MVNETA_TYPE_SKB;
2375+
buf->skb = NULL;
23592376

23602377
if (last_tcp) {
23612378
/* last descriptor in the TCP packet */
23622379
tx_desc->command = MVNETA_TXD_L_DESC;
23632380

23642381
/* last descriptor in SKB */
23652382
if (is_last)
2366-
txq->tx_skb[txq->txq_put_index] = skb;
2383+
buf->skb = skb;
23672384
}
23682385
mvneta_txq_inc_put(txq);
23692386
return 0;
@@ -2448,6 +2465,7 @@ static int mvneta_tx_frag_process(struct mvneta_port *pp, struct sk_buff *skb,
24482465
int i, nr_frags = skb_shinfo(skb)->nr_frags;
24492466

24502467
for (i = 0; i < nr_frags; i++) {
2468+
struct mvneta_tx_buf *buf = &txq->buf[txq->txq_put_index];
24512469
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
24522470
void *addr = skb_frag_address(frag);
24532471

@@ -2467,12 +2485,13 @@ static int mvneta_tx_frag_process(struct mvneta_port *pp, struct sk_buff *skb,
24672485
if (i == nr_frags - 1) {
24682486
/* Last descriptor */
24692487
tx_desc->command = MVNETA_TXD_L_DESC | MVNETA_TXD_Z_PAD;
2470-
txq->tx_skb[txq->txq_put_index] = skb;
2488+
buf->skb = skb;
24712489
} else {
24722490
/* Descriptor in the middle: Not First, Not Last */
24732491
tx_desc->command = 0;
2474-
txq->tx_skb[txq->txq_put_index] = NULL;
2492+
buf->skb = NULL;
24752493
}
2494+
buf->type = MVNETA_TYPE_SKB;
24762495
mvneta_txq_inc_put(txq);
24772496
}
24782497

@@ -2500,6 +2519,7 @@ static netdev_tx_t mvneta_tx(struct sk_buff *skb, struct net_device *dev)
25002519
struct mvneta_port *pp = netdev_priv(dev);
25012520
u16 txq_id = skb_get_queue_mapping(skb);
25022521
struct mvneta_tx_queue *txq = &pp->txqs[txq_id];
2522+
struct mvneta_tx_buf *buf = &txq->buf[txq->txq_put_index];
25032523
struct mvneta_tx_desc *tx_desc;
25042524
int len = skb->len;
25052525
int frags = 0;
@@ -2532,16 +2552,17 @@ static netdev_tx_t mvneta_tx(struct sk_buff *skb, struct net_device *dev)
25322552
goto out;
25332553
}
25342554

2555+
buf->type = MVNETA_TYPE_SKB;
25352556
if (frags == 1) {
25362557
/* First and Last descriptor */
25372558
tx_cmd |= MVNETA_TXD_FLZ_DESC;
25382559
tx_desc->command = tx_cmd;
2539-
txq->tx_skb[txq->txq_put_index] = skb;
2560+
buf->skb = skb;
25402561
mvneta_txq_inc_put(txq);
25412562
} else {
25422563
/* First but not Last */
25432564
tx_cmd |= MVNETA_TXD_F_DESC;
2544-
txq->tx_skb[txq->txq_put_index] = NULL;
2565+
buf->skb = NULL;
25452566
mvneta_txq_inc_put(txq);
25462567
tx_desc->command = tx_cmd;
25472568
/* Continue with other skb fragments */
@@ -3128,9 +3149,8 @@ static int mvneta_txq_sw_init(struct mvneta_port *pp,
31283149

31293150
txq->last_desc = txq->size - 1;
31303151

3131-
txq->tx_skb = kmalloc_array(txq->size, sizeof(*txq->tx_skb),
3132-
GFP_KERNEL);
3133-
if (!txq->tx_skb) {
3152+
txq->buf = kmalloc_array(txq->size, sizeof(*txq->buf), GFP_KERNEL);
3153+
if (!txq->buf) {
31343154
dma_free_coherent(pp->dev->dev.parent,
31353155
txq->size * MVNETA_DESC_ALIGNED_SIZE,
31363156
txq->descs, txq->descs_phys);
@@ -3142,7 +3162,7 @@ static int mvneta_txq_sw_init(struct mvneta_port *pp,
31423162
txq->size * TSO_HEADER_SIZE,
31433163
&txq->tso_hdrs_phys, GFP_KERNEL);
31443164
if (!txq->tso_hdrs) {
3145-
kfree(txq->tx_skb);
3165+
kfree(txq->buf);
31463166
dma_free_coherent(pp->dev->dev.parent,
31473167
txq->size * MVNETA_DESC_ALIGNED_SIZE,
31483168
txq->descs, txq->descs_phys);
@@ -3195,7 +3215,7 @@ static void mvneta_txq_sw_deinit(struct mvneta_port *pp,
31953215
{
31963216
struct netdev_queue *nq = netdev_get_tx_queue(pp->dev, txq->id);
31973217

3198-
kfree(txq->tx_skb);
3218+
kfree(txq->buf);
31993219

32003220
if (txq->tso_hdrs)
32013221
dma_free_coherent(pp->dev->dev.parent,

0 commit comments

Comments
 (0)