69
69
#include <soc/imx/cpuidle.h>
70
70
#include <linux/filter.h>
71
71
#include <linux/bpf.h>
72
+ #include <linux/bpf_trace.h>
72
73
73
74
#include <asm/cacheflush.h>
74
75
75
76
#include "fec.h"
76
77
77
78
static void set_multicast_list (struct net_device * ndev );
78
79
static void fec_enet_itr_coal_set (struct net_device * ndev );
80
+ static int fec_enet_xdp_tx_xmit (struct fec_enet_private * fep ,
81
+ int cpu , struct xdp_buff * xdp ,
82
+ u32 dma_sync_len );
79
83
80
84
#define DRIVER_NAME "fec"
81
85
@@ -396,7 +400,7 @@ static void fec_dump(struct net_device *ndev)
396
400
fec16_to_cpu (bdp -> cbd_sc ),
397
401
fec32_to_cpu (bdp -> cbd_bufaddr ),
398
402
fec16_to_cpu (bdp -> cbd_datlen ),
399
- txq -> tx_buf [index ].skb );
403
+ txq -> tx_buf [index ].buf_p );
400
404
bdp = fec_enet_get_nextdesc (bdp , & txq -> bd );
401
405
index ++ ;
402
406
} while (bdp != txq -> bd .base );
@@ -653,7 +657,7 @@ static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq,
653
657
654
658
index = fec_enet_get_bd_index (last_bdp , & txq -> bd );
655
659
/* Save skb pointer */
656
- txq -> tx_buf [index ].skb = skb ;
660
+ txq -> tx_buf [index ].buf_p = skb ;
657
661
658
662
/* Make sure the updates to rest of the descriptor are performed before
659
663
* transferring ownership.
@@ -859,7 +863,7 @@ static int fec_enet_txq_submit_tso(struct fec_enet_priv_tx_q *txq,
859
863
}
860
864
861
865
/* Save skb pointer */
862
- txq -> tx_buf [index ].skb = skb ;
866
+ txq -> tx_buf [index ].buf_p = skb ;
863
867
864
868
skb_tx_timestamp (skb );
865
869
txq -> bd .cur = bdp ;
@@ -956,26 +960,27 @@ static void fec_enet_bd_init(struct net_device *dev)
956
960
fec32_to_cpu (bdp -> cbd_bufaddr ),
957
961
fec16_to_cpu (bdp -> cbd_datlen ),
958
962
DMA_TO_DEVICE );
959
- if (txq -> tx_buf [i ].skb ) {
960
- dev_kfree_skb_any (txq -> tx_buf [i ].skb );
961
- txq -> tx_buf [i ].skb = NULL ;
962
- }
963
- } else {
963
+ if (txq -> tx_buf [i ].buf_p )
964
+ dev_kfree_skb_any (txq -> tx_buf [i ].buf_p );
965
+ } else if (txq -> tx_buf [i ].type == FEC_TXBUF_T_XDP_NDO ) {
964
966
if (bdp -> cbd_bufaddr )
965
967
dma_unmap_single (& fep -> pdev -> dev ,
966
968
fec32_to_cpu (bdp -> cbd_bufaddr ),
967
969
fec16_to_cpu (bdp -> cbd_datlen ),
968
970
DMA_TO_DEVICE );
969
971
970
- if (txq -> tx_buf [i ].xdp ) {
971
- xdp_return_frame (txq -> tx_buf [i ].xdp );
972
- txq -> tx_buf [ i ]. xdp = NULL ;
973
- }
972
+ if (txq -> tx_buf [i ].buf_p )
973
+ xdp_return_frame (txq -> tx_buf [i ].buf_p );
974
+ } else {
975
+ struct page * page = txq -> tx_buf [ i ]. buf_p ;
974
976
975
- /* restore default tx buffer type: FEC_TXBUF_T_SKB */
976
- txq -> tx_buf [ i ]. type = FEC_TXBUF_T_SKB ;
977
+ if ( page )
978
+ page_pool_put_page ( page -> pp , page , 0 , false) ;
977
979
}
978
980
981
+ txq -> tx_buf [i ].buf_p = NULL ;
982
+ /* restore default tx buffer type: FEC_TXBUF_T_SKB */
983
+ txq -> tx_buf [i ].type = FEC_TXBUF_T_SKB ;
979
984
bdp -> cbd_bufaddr = cpu_to_fec32 (0 );
980
985
bdp = fec_enet_get_nextdesc (bdp , & txq -> bd );
981
986
}
@@ -1382,6 +1387,8 @@ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id, int budget)
1382
1387
struct netdev_queue * nq ;
1383
1388
int index = 0 ;
1384
1389
int entries_free ;
1390
+ struct page * page ;
1391
+ int frame_len ;
1385
1392
1386
1393
fep = netdev_priv (ndev );
1387
1394
@@ -1403,8 +1410,7 @@ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id, int budget)
1403
1410
index = fec_enet_get_bd_index (bdp , & txq -> bd );
1404
1411
1405
1412
if (txq -> tx_buf [index ].type == FEC_TXBUF_T_SKB ) {
1406
- skb = txq -> tx_buf [index ].skb ;
1407
- txq -> tx_buf [index ].skb = NULL ;
1413
+ skb = txq -> tx_buf [index ].buf_p ;
1408
1414
if (bdp -> cbd_bufaddr &&
1409
1415
!IS_TSO_HEADER (txq , fec32_to_cpu (bdp -> cbd_bufaddr )))
1410
1416
dma_unmap_single (& fep -> pdev -> dev ,
@@ -1423,17 +1429,24 @@ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id, int budget)
1423
1429
if (unlikely (!budget ))
1424
1430
break ;
1425
1431
1426
- xdpf = txq -> tx_buf [index ].xdp ;
1427
- if (bdp -> cbd_bufaddr )
1428
- dma_unmap_single (& fep -> pdev -> dev ,
1429
- fec32_to_cpu (bdp -> cbd_bufaddr ),
1430
- fec16_to_cpu (bdp -> cbd_datlen ),
1431
- DMA_TO_DEVICE );
1432
+ if (txq -> tx_buf [index ].type == FEC_TXBUF_T_XDP_NDO ) {
1433
+ xdpf = txq -> tx_buf [index ].buf_p ;
1434
+ if (bdp -> cbd_bufaddr )
1435
+ dma_unmap_single (& fep -> pdev -> dev ,
1436
+ fec32_to_cpu (bdp -> cbd_bufaddr ),
1437
+ fec16_to_cpu (bdp -> cbd_datlen ),
1438
+ DMA_TO_DEVICE );
1439
+ } else {
1440
+ page = txq -> tx_buf [index ].buf_p ;
1441
+ }
1442
+
1432
1443
bdp -> cbd_bufaddr = cpu_to_fec32 (0 );
1433
- if (! xdpf ) {
1444
+ if (unlikely (! txq -> tx_buf [ index ]. buf_p ) ) {
1434
1445
txq -> tx_buf [index ].type = FEC_TXBUF_T_SKB ;
1435
1446
goto tx_buf_done ;
1436
1447
}
1448
+
1449
+ frame_len = fec16_to_cpu (bdp -> cbd_datlen );
1437
1450
}
1438
1451
1439
1452
/* Check for errors. */
@@ -1457,7 +1470,7 @@ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id, int budget)
1457
1470
if (txq -> tx_buf [index ].type == FEC_TXBUF_T_SKB )
1458
1471
ndev -> stats .tx_bytes += skb -> len ;
1459
1472
else
1460
- ndev -> stats .tx_bytes += xdpf -> len ;
1473
+ ndev -> stats .tx_bytes += frame_len ;
1461
1474
}
1462
1475
1463
1476
/* Deferred means some collisions occurred during transmit,
@@ -1482,14 +1495,17 @@ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id, int budget)
1482
1495
1483
1496
/* Free the sk buffer associated with this last transmit */
1484
1497
dev_kfree_skb_any (skb );
1485
- } else {
1486
- xdp_return_frame (xdpf );
1487
-
1488
- txq -> tx_buf [index ].xdp = NULL ;
1489
- /* restore default tx buffer type: FEC_TXBUF_T_SKB */
1490
- txq -> tx_buf [index ].type = FEC_TXBUF_T_SKB ;
1498
+ } else if (txq -> tx_buf [index ].type == FEC_TXBUF_T_XDP_NDO ) {
1499
+ xdp_return_frame_rx_napi (xdpf );
1500
+ } else { /* recycle pages of XDP_TX frames */
1501
+ /* The dma_sync_size = 0 as XDP_TX has already synced DMA for_device */
1502
+ page_pool_put_page (page -> pp , page , 0 , true);
1491
1503
}
1492
1504
1505
+ txq -> tx_buf [index ].buf_p = NULL ;
1506
+ /* restore default tx buffer type: FEC_TXBUF_T_SKB */
1507
+ txq -> tx_buf [index ].type = FEC_TXBUF_T_SKB ;
1508
+
1493
1509
tx_buf_done :
1494
1510
/* Make sure the update to bdp and tx_buf are performed
1495
1511
* before dirty_tx
@@ -1542,7 +1558,7 @@ static void fec_enet_update_cbd(struct fec_enet_priv_rx_q *rxq,
1542
1558
1543
1559
static u32
1544
1560
fec_enet_run_xdp (struct fec_enet_private * fep , struct bpf_prog * prog ,
1545
- struct xdp_buff * xdp , struct fec_enet_priv_rx_q * rxq , int index )
1561
+ struct xdp_buff * xdp , struct fec_enet_priv_rx_q * rxq , int cpu )
1546
1562
{
1547
1563
unsigned int sync , len = xdp -> data_end - xdp -> data ;
1548
1564
u32 ret = FEC_ENET_XDP_PASS ;
@@ -1552,8 +1568,10 @@ fec_enet_run_xdp(struct fec_enet_private *fep, struct bpf_prog *prog,
1552
1568
1553
1569
act = bpf_prog_run_xdp (prog , xdp );
1554
1570
1555
- /* Due xdp_adjust_tail: DMA sync for_device cover max len CPU touch */
1556
- sync = xdp -> data_end - xdp -> data_hard_start - FEC_ENET_XDP_HEADROOM ;
1571
+ /* Due xdp_adjust_tail and xdp_adjust_head: DMA sync for_device cover
1572
+ * max len CPU touch
1573
+ */
1574
+ sync = xdp -> data_end - xdp -> data ;
1557
1575
sync = max (sync , len );
1558
1576
1559
1577
switch (act ) {
@@ -1574,11 +1592,19 @@ fec_enet_run_xdp(struct fec_enet_private *fep, struct bpf_prog *prog,
1574
1592
}
1575
1593
break ;
1576
1594
1577
- default :
1578
- bpf_warn_invalid_xdp_action (fep -> netdev , prog , act );
1579
- fallthrough ;
1580
-
1581
1595
case XDP_TX :
1596
+ err = fec_enet_xdp_tx_xmit (fep , cpu , xdp , sync );
1597
+ if (unlikely (err )) {
1598
+ ret = FEC_ENET_XDP_CONSUMED ;
1599
+ page = virt_to_head_page (xdp -> data );
1600
+ page_pool_put_page (rxq -> page_pool , page , sync , true);
1601
+ trace_xdp_exception (fep -> netdev , prog , act );
1602
+ } else {
1603
+ ret = FEC_ENET_XDP_TX ;
1604
+ }
1605
+ break ;
1606
+
1607
+ default :
1582
1608
bpf_warn_invalid_xdp_action (fep -> netdev , prog , act );
1583
1609
fallthrough ;
1584
1610
@@ -1620,6 +1646,7 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
1620
1646
struct bpf_prog * xdp_prog = READ_ONCE (fep -> xdp_prog );
1621
1647
u32 ret , xdp_result = FEC_ENET_XDP_PASS ;
1622
1648
u32 data_start = FEC_ENET_XDP_HEADROOM ;
1649
+ int cpu = smp_processor_id ();
1623
1650
struct xdp_buff xdp ;
1624
1651
struct page * page ;
1625
1652
u32 sub_len = 4 ;
@@ -1698,7 +1725,7 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
1698
1725
/* subtract 16bit shift and FCS */
1699
1726
xdp_prepare_buff (& xdp , page_address (page ),
1700
1727
data_start , pkt_len - sub_len , false);
1701
- ret = fec_enet_run_xdp (fep , xdp_prog , & xdp , rxq , index );
1728
+ ret = fec_enet_run_xdp (fep , xdp_prog , & xdp , rxq , cpu );
1702
1729
xdp_result |= ret ;
1703
1730
if (ret != FEC_ENET_XDP_PASS )
1704
1731
goto rx_processing_done ;
@@ -3208,7 +3235,6 @@ static void fec_enet_free_buffers(struct net_device *ndev)
3208
3235
{
3209
3236
struct fec_enet_private * fep = netdev_priv (ndev );
3210
3237
unsigned int i ;
3211
- struct sk_buff * skb ;
3212
3238
struct fec_enet_priv_tx_q * txq ;
3213
3239
struct fec_enet_priv_rx_q * rxq ;
3214
3240
unsigned int q ;
@@ -3233,18 +3259,23 @@ static void fec_enet_free_buffers(struct net_device *ndev)
3233
3259
kfree (txq -> tx_bounce [i ]);
3234
3260
txq -> tx_bounce [i ] = NULL ;
3235
3261
3262
+ if (!txq -> tx_buf [i ].buf_p ) {
3263
+ txq -> tx_buf [i ].type = FEC_TXBUF_T_SKB ;
3264
+ continue ;
3265
+ }
3266
+
3236
3267
if (txq -> tx_buf [i ].type == FEC_TXBUF_T_SKB ) {
3237
- skb = txq -> tx_buf [i ].skb ;
3238
- txq -> tx_buf [i ].skb = NULL ;
3239
- dev_kfree_skb ( skb );
3268
+ dev_kfree_skb ( txq -> tx_buf [i ].buf_p ) ;
3269
+ } else if ( txq -> tx_buf [i ].type == FEC_TXBUF_T_XDP_NDO ) {
3270
+ xdp_return_frame ( txq -> tx_buf [ i ]. buf_p );
3240
3271
} else {
3241
- if (txq -> tx_buf [i ].xdp ) {
3242
- xdp_return_frame (txq -> tx_buf [i ].xdp );
3243
- txq -> tx_buf [i ].xdp = NULL ;
3244
- }
3272
+ struct page * page = txq -> tx_buf [i ].buf_p ;
3245
3273
3246
- txq -> tx_buf [ i ]. type = FEC_TXBUF_T_SKB ;
3274
+ page_pool_put_page ( page -> pp , page , 0 , false) ;
3247
3275
}
3276
+
3277
+ txq -> tx_buf [i ].buf_p = NULL ;
3278
+ txq -> tx_buf [i ].type = FEC_TXBUF_T_SKB ;
3248
3279
}
3249
3280
}
3250
3281
}
@@ -3767,12 +3798,14 @@ fec_enet_xdp_get_tx_queue(struct fec_enet_private *fep, int index)
3767
3798
3768
3799
static int fec_enet_txq_xmit_frame (struct fec_enet_private * fep ,
3769
3800
struct fec_enet_priv_tx_q * txq ,
3770
- struct xdp_frame * frame )
3801
+ void * frame , u32 dma_sync_len ,
3802
+ bool ndo_xmit )
3771
3803
{
3772
3804
unsigned int index , status , estatus ;
3773
3805
struct bufdesc * bdp ;
3774
3806
dma_addr_t dma_addr ;
3775
3807
int entries_free ;
3808
+ u16 frame_len ;
3776
3809
3777
3810
entries_free = fec_enet_get_free_txdesc_num (txq );
3778
3811
if (entries_free < MAX_SKB_FRAGS + 1 ) {
@@ -3787,17 +3820,37 @@ static int fec_enet_txq_xmit_frame(struct fec_enet_private *fep,
3787
3820
3788
3821
index = fec_enet_get_bd_index (bdp , & txq -> bd );
3789
3822
3790
- dma_addr = dma_map_single (& fep -> pdev -> dev , frame -> data ,
3791
- frame -> len , DMA_TO_DEVICE );
3792
- if (dma_mapping_error (& fep -> pdev -> dev , dma_addr ))
3793
- return - ENOMEM ;
3823
+ if (ndo_xmit ) {
3824
+ struct xdp_frame * xdpf = frame ;
3825
+
3826
+ dma_addr = dma_map_single (& fep -> pdev -> dev , xdpf -> data ,
3827
+ xdpf -> len , DMA_TO_DEVICE );
3828
+ if (dma_mapping_error (& fep -> pdev -> dev , dma_addr ))
3829
+ return - ENOMEM ;
3830
+
3831
+ frame_len = xdpf -> len ;
3832
+ txq -> tx_buf [index ].buf_p = xdpf ;
3833
+ txq -> tx_buf [index ].type = FEC_TXBUF_T_XDP_NDO ;
3834
+ } else {
3835
+ struct xdp_buff * xdpb = frame ;
3836
+ struct page * page ;
3837
+
3838
+ page = virt_to_page (xdpb -> data );
3839
+ dma_addr = page_pool_get_dma_addr (page ) +
3840
+ (xdpb -> data - xdpb -> data_hard_start );
3841
+ dma_sync_single_for_device (& fep -> pdev -> dev , dma_addr ,
3842
+ dma_sync_len , DMA_BIDIRECTIONAL );
3843
+ frame_len = xdpb -> data_end - xdpb -> data ;
3844
+ txq -> tx_buf [index ].buf_p = page ;
3845
+ txq -> tx_buf [index ].type = FEC_TXBUF_T_XDP_TX ;
3846
+ }
3794
3847
3795
3848
status |= (BD_ENET_TX_INTR | BD_ENET_TX_LAST );
3796
3849
if (fep -> bufdesc_ex )
3797
3850
estatus = BD_ENET_TX_INT ;
3798
3851
3799
3852
bdp -> cbd_bufaddr = cpu_to_fec32 (dma_addr );
3800
- bdp -> cbd_datlen = cpu_to_fec16 (frame -> len );
3853
+ bdp -> cbd_datlen = cpu_to_fec16 (frame_len );
3801
3854
3802
3855
if (fep -> bufdesc_ex ) {
3803
3856
struct bufdesc_ex * ebdp = (struct bufdesc_ex * )bdp ;
@@ -3809,9 +3862,6 @@ static int fec_enet_txq_xmit_frame(struct fec_enet_private *fep,
3809
3862
ebdp -> cbd_esc = cpu_to_fec32 (estatus );
3810
3863
}
3811
3864
3812
- txq -> tx_buf [index ].type = FEC_TXBUF_T_XDP_NDO ;
3813
- txq -> tx_buf [index ].xdp = frame ;
3814
-
3815
3865
/* Make sure the updates to rest of the descriptor are performed before
3816
3866
* transferring ownership.
3817
3867
*/
@@ -3837,6 +3887,29 @@ static int fec_enet_txq_xmit_frame(struct fec_enet_private *fep,
3837
3887
return 0 ;
3838
3888
}
3839
3889
3890
+ static int fec_enet_xdp_tx_xmit (struct fec_enet_private * fep ,
3891
+ int cpu , struct xdp_buff * xdp ,
3892
+ u32 dma_sync_len )
3893
+ {
3894
+ struct fec_enet_priv_tx_q * txq ;
3895
+ struct netdev_queue * nq ;
3896
+ int queue , ret ;
3897
+
3898
+ queue = fec_enet_xdp_get_tx_queue (fep , cpu );
3899
+ txq = fep -> tx_queue [queue ];
3900
+ nq = netdev_get_tx_queue (fep -> netdev , queue );
3901
+
3902
+ __netif_tx_lock (nq , cpu );
3903
+
3904
+ /* Avoid tx timeout as XDP shares the queue with kernel stack */
3905
+ txq_trans_cond_update (nq );
3906
+ ret = fec_enet_txq_xmit_frame (fep , txq , xdp , dma_sync_len , false);
3907
+
3908
+ __netif_tx_unlock (nq );
3909
+
3910
+ return ret ;
3911
+ }
3912
+
3840
3913
static int fec_enet_xdp_xmit (struct net_device * dev ,
3841
3914
int num_frames ,
3842
3915
struct xdp_frame * * frames ,
@@ -3859,7 +3932,7 @@ static int fec_enet_xdp_xmit(struct net_device *dev,
3859
3932
/* Avoid tx timeout as XDP shares the queue with kernel stack */
3860
3933
txq_trans_cond_update (nq );
3861
3934
for (i = 0 ; i < num_frames ; i ++ ) {
3862
- if (fec_enet_txq_xmit_frame (fep , txq , frames [i ]) < 0 )
3935
+ if (fec_enet_txq_xmit_frame (fep , txq , frames [i ], 0 , true ) < 0 )
3863
3936
break ;
3864
3937
sent_frames ++ ;
3865
3938
}
0 commit comments