@@ -103,6 +103,14 @@ static struct net_buf *rx_frag_list_que1[PRIORITY_QUEUE1_RX_DESC_COUNT];
103
103
#if GMAC_PRIORITY_QUEUE_NO == 2
104
104
static struct net_buf * rx_frag_list_que2 [PRIORITY_QUEUE2_RX_DESC_COUNT ];
105
105
#endif
106
+ /* TX buffer accounting list */
107
+ static struct net_buf * tx_frag_list_que0 [MAIN_QUEUE_TX_DESC_COUNT ];
108
+ #if GMAC_PRIORITY_QUEUE_NO >= 1
109
+ static struct net_buf * tx_frag_list_que1 [PRIORITY_QUEUE1_TX_DESC_COUNT ];
110
+ #endif
111
+ #if GMAC_PRIORITY_QUEUE_NO == 2
112
+ static struct net_buf * tx_frag_list_que2 [PRIORITY_QUEUE2_TX_DESC_COUNT ];
113
+ #endif
106
114
/* TX frames accounting list */
107
115
static struct net_pkt * tx_frame_list_que0 [CONFIG_NET_PKT_TX_COUNT + 1 ];
108
116
#if GMAC_PRIORITY_QUEUE_NO >= 1
@@ -274,6 +282,7 @@ static void tx_descriptors_init(Gmac *gmac, struct gmac_queue *queue)
274
282
tx_desc_list -> buf [tx_desc_list -> len - 1 ].w1 |= GMAC_TXW1_WRAP ;
275
283
276
284
/* Reset TX frame list */
285
+ ring_buf_reset (& queue -> tx_frag_list );
277
286
ring_buf_reset (& queue -> tx_frames );
278
287
}
279
288
@@ -474,6 +483,7 @@ static void tx_completed(Gmac *gmac, struct gmac_queue *queue)
474
483
{
475
484
struct gmac_desc_list * tx_desc_list = & queue -> tx_desc_list ;
476
485
struct gmac_desc * tx_desc ;
486
+ struct net_buf * frag ;
477
487
struct net_pkt * pkt ;
478
488
#if defined(CONFIG_PTP_CLOCK_SAM_GMAC )
479
489
u16_t vlan_tag = NET_VLAN_TAG_UNSPEC ;
@@ -492,8 +502,13 @@ static void tx_completed(Gmac *gmac, struct gmac_queue *queue)
492
502
MODULO_INC (tx_desc_list -> tail , tx_desc_list -> len );
493
503
k_sem_give (& queue -> tx_desc_sem );
494
504
505
+ /* Release net buffer to the buffer pool */
506
+ frag = UINT_TO_POINTER (ring_buf_get (& queue -> tx_frag_list ));
507
+ net_pkt_frag_unref (frag );
508
+ LOG_DBG ("Dropping frag %p" , frag );
509
+
495
510
if (tx_desc -> w1 & GMAC_TXW1_LASTBUFFER ) {
496
- /* Release net buffer to the buffer pool */
511
+ /* Release net packet to the packet pool */
497
512
pkt = UINT_TO_POINTER (ring_buf_get (& queue -> tx_frames ));
498
513
#if defined(CONFIG_PTP_CLOCK_SAM_GMAC )
499
514
#if defined(CONFIG_NET_VLAN )
@@ -526,16 +541,27 @@ static void tx_completed(Gmac *gmac, struct gmac_queue *queue)
526
541
static void tx_error_handler (Gmac * gmac , struct gmac_queue * queue )
527
542
{
528
543
struct net_pkt * pkt ;
544
+ struct net_buf * frag ;
545
+ struct ring_buf * tx_frag_list = & queue -> tx_frag_list ;
529
546
struct ring_buf * tx_frames = & queue -> tx_frames ;
530
547
531
548
queue -> err_tx_flushed_count ++ ;
532
549
533
550
/* Stop transmission, clean transmit pipeline and control registers */
534
551
gmac -> GMAC_NCR &= ~GMAC_NCR_TXEN ;
535
552
553
+ /* Free all frag resources in the TX path */
554
+ while (tx_frag_list -> tail != tx_frag_list -> head ) {
555
+ /* Release net buffer to the buffer pool */
556
+ frag = UINT_TO_POINTER (tx_frag_list -> buf [tx_frag_list -> tail ]);
557
+ net_pkt_frag_unref (frag );
558
+ LOG_DBG ("Dropping frag %p" , frag );
559
+ MODULO_INC (tx_frag_list -> tail , tx_frag_list -> len );
560
+ }
561
+
536
562
/* Free all pkt resources in the TX path */
537
563
while (tx_frames -> tail != tx_frames -> head ) {
538
- /* Release net buffer to the buffer pool */
564
+ /* Release net packet to the packet pool */
539
565
pkt = UINT_TO_POINTER (tx_frames -> buf [tx_frames -> tail ]);
540
566
net_pkt_unref (pkt );
541
567
LOG_DBG ("Dropping pkt %p" , pkt );
@@ -1306,6 +1332,12 @@ static int eth_tx(struct device *dev, struct net_pkt *pkt)
1306
1332
__ASSERT (tx_desc_list -> head != tx_desc_list -> tail ,
1307
1333
"tx_desc_list overflow" );
1308
1334
1335
+ /* Account for a sent frag */
1336
+ ring_buf_put (& queue -> tx_frag_list , POINTER_TO_UINT (frag ));
1337
+
1338
+ /* frag is internally queued, so it requires to hold a reference */
1339
+ net_pkt_frag_ref (frag );
1340
+
1309
1341
irq_unlock (key );
1310
1342
1311
1343
/* Continue with the rest of fragments (only data) */
@@ -1860,6 +1892,10 @@ static struct eth_sam_dev_data eth0_data = {
1860
1892
.buf = (u32_t * )rx_frag_list_que0 ,
1861
1893
.len = ARRAY_SIZE (rx_frag_list_que0 ),
1862
1894
},
1895
+ .tx_frag_list = {
1896
+ .buf = (u32_t * )tx_frag_list_que0 ,
1897
+ .len = ARRAY_SIZE (tx_frag_list_que0 ),
1898
+ },
1863
1899
.tx_frames = {
1864
1900
.buf = (u32_t * )tx_frame_list_que0 ,
1865
1901
.len = ARRAY_SIZE (tx_frame_list_que0 ),
@@ -1879,6 +1915,10 @@ static struct eth_sam_dev_data eth0_data = {
1879
1915
.buf = (u32_t * )rx_frag_list_que1 ,
1880
1916
.len = ARRAY_SIZE (rx_frag_list_que1 ),
1881
1917
},
1918
+ .tx_frag_list = {
1919
+ .buf = (u32_t * )tx_frag_list_que1 ,
1920
+ .len = ARRAY_SIZE (tx_frag_list_que1 ),
1921
+ },
1882
1922
.tx_frames = {
1883
1923
.buf = (u32_t * )tx_frame_list_que1 ,
1884
1924
.len = ARRAY_SIZE (tx_frame_list_que1 ),
@@ -1899,6 +1939,10 @@ static struct eth_sam_dev_data eth0_data = {
1899
1939
.buf = (u32_t * )rx_frag_list_que2 ,
1900
1940
.len = ARRAY_SIZE (rx_frag_list_que2 ),
1901
1941
},
1942
+ .tx_frag_list = {
1943
+ .buf = (u32_t * )tx_frag_list_que2 ,
1944
+ .len = ARRAY_SIZE (tx_frag_list_que2 ),
1945
+ },
1902
1946
.tx_frames = {
1903
1947
.buf = (u32_t * )tx_frame_list_que2 ,
1904
1948
.len = ARRAY_SIZE (tx_frame_list_que2 ),
0 commit comments