@@ -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+
564578struct 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
23242336mvneta_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