@@ -236,6 +236,8 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
236
236
#define FEC_PAUSE_FLAG_AUTONEG 0x1
237
237
#define FEC_PAUSE_FLAG_ENABLE 0x2
238
238
239
+ #define COPYBREAK_DEFAULT 256
240
+
239
241
#define TSO_HEADER_SIZE 128
240
242
/* Max number of allowed TCP segments for software TSO */
241
243
#define FEC_MAX_TSO_SEGS 100
@@ -1322,6 +1324,50 @@ fec_enet_tx(struct net_device *ndev)
1322
1324
return ;
1323
1325
}
1324
1326
1327
+ static int
1328
+ fec_enet_new_rxbdp (struct net_device * ndev , struct bufdesc * bdp , struct sk_buff * skb )
1329
+ {
1330
+ struct fec_enet_private * fep = netdev_priv (ndev );
1331
+ int off ;
1332
+
1333
+ off = ((unsigned long )skb -> data ) & fep -> rx_align ;
1334
+ if (off )
1335
+ skb_reserve (skb , fep -> rx_align + 1 - off );
1336
+
1337
+ bdp -> cbd_bufaddr = dma_map_single (& fep -> pdev -> dev , skb -> data ,
1338
+ FEC_ENET_RX_FRSIZE - fep -> rx_align ,
1339
+ DMA_FROM_DEVICE );
1340
+ if (dma_mapping_error (& fep -> pdev -> dev , bdp -> cbd_bufaddr )) {
1341
+ if (net_ratelimit ())
1342
+ netdev_err (ndev , "Rx DMA memory map failed\n" );
1343
+ return - ENOMEM ;
1344
+ }
1345
+
1346
+ return 0 ;
1347
+ }
1348
+
1349
+ static bool fec_enet_copybreak (struct net_device * ndev , struct sk_buff * * skb ,
1350
+ struct bufdesc * bdp , u32 length )
1351
+ {
1352
+ struct fec_enet_private * fep = netdev_priv (ndev );
1353
+ struct sk_buff * new_skb ;
1354
+
1355
+ if (length > fep -> rx_copybreak )
1356
+ return false;
1357
+
1358
+ new_skb = netdev_alloc_skb (ndev , length );
1359
+ if (!new_skb )
1360
+ return false;
1361
+
1362
+ dma_sync_single_for_cpu (& fep -> pdev -> dev , bdp -> cbd_bufaddr ,
1363
+ FEC_ENET_RX_FRSIZE - fep -> rx_align ,
1364
+ DMA_FROM_DEVICE );
1365
+ memcpy (new_skb -> data , (* skb )-> data , length );
1366
+ * skb = new_skb ;
1367
+
1368
+ return true;
1369
+ }
1370
+
1325
1371
/* During a receive, the cur_rx points to the current incoming buffer.
1326
1372
* When we update through the ring, if the next incoming buffer has
1327
1373
* not been given to the system, we just set the empty indicator,
@@ -1336,14 +1382,16 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
1336
1382
struct fec_enet_priv_rx_q * rxq ;
1337
1383
struct bufdesc * bdp ;
1338
1384
unsigned short status ;
1339
- struct sk_buff * skb ;
1385
+ struct sk_buff * skb_new = NULL ;
1386
+ struct sk_buff * skb ;
1340
1387
ushort pkt_len ;
1341
1388
__u8 * data ;
1342
1389
int pkt_received = 0 ;
1343
1390
struct bufdesc_ex * ebdp = NULL ;
1344
1391
bool vlan_packet_rcvd = false;
1345
1392
u16 vlan_tag ;
1346
1393
int index = 0 ;
1394
+ bool is_copybreak ;
1347
1395
1348
1396
#ifdef CONFIG_M532x
1349
1397
flush_cache_all ();
@@ -1401,11 +1449,27 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
1401
1449
ndev -> stats .rx_bytes += pkt_len ;
1402
1450
1403
1451
index = fec_enet_get_bd_index (rxq -> rx_bd_base , bdp , fep );
1404
- data = rxq -> rx_skbuff [index ]-> data ;
1405
- dma_sync_single_for_cpu (& fep -> pdev -> dev , bdp -> cbd_bufaddr ,
1406
- FEC_ENET_RX_FRSIZE - fep -> rx_align ,
1407
- DMA_FROM_DEVICE );
1452
+ skb = rxq -> rx_skbuff [index ];
1408
1453
1454
+ /* The packet length includes FCS, but we don't want to
1455
+ * include that when passing upstream as it messes up
1456
+ * bridging applications.
1457
+ */
1458
+ is_copybreak = fec_enet_copybreak (ndev , & skb , bdp , pkt_len - 4 );
1459
+ if (!is_copybreak ) {
1460
+ skb_new = netdev_alloc_skb (ndev , FEC_ENET_RX_FRSIZE );
1461
+ if (unlikely (!skb_new )) {
1462
+ ndev -> stats .rx_dropped ++ ;
1463
+ goto rx_processing_done ;
1464
+ }
1465
+ dma_unmap_single (& fep -> pdev -> dev , bdp -> cbd_bufaddr ,
1466
+ FEC_ENET_RX_FRSIZE - fep -> rx_align ,
1467
+ DMA_FROM_DEVICE );
1468
+ }
1469
+
1470
+ prefetch (skb -> data - NET_IP_ALIGN );
1471
+ skb_put (skb , pkt_len - 4 );
1472
+ data = skb -> data ;
1409
1473
if (id_entry -> driver_data & FEC_QUIRK_SWAP_FRAME )
1410
1474
swap_buffer (data , pkt_len );
1411
1475
@@ -1422,62 +1486,48 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
1422
1486
struct vlan_hdr * vlan_header =
1423
1487
(struct vlan_hdr * ) (data + ETH_HLEN );
1424
1488
vlan_tag = ntohs (vlan_header -> h_vlan_TCI );
1425
- pkt_len -= VLAN_HLEN ;
1426
1489
1427
1490
vlan_packet_rcvd = true;
1491
+
1492
+ skb_copy_to_linear_data_offset (skb , VLAN_HLEN ,
1493
+ data , (2 * ETH_ALEN ));
1494
+ skb_pull (skb , VLAN_HLEN );
1428
1495
}
1429
1496
1430
- /* This does 16 byte alignment, exactly what we need.
1431
- * The packet length includes FCS, but we don't want to
1432
- * include that when passing upstream as it messes up
1433
- * bridging applications.
1434
- */
1435
- skb = netdev_alloc_skb (ndev , pkt_len - 4 + NET_IP_ALIGN );
1497
+ skb -> protocol = eth_type_trans (skb , ndev );
1436
1498
1437
- if (unlikely (!skb )) {
1438
- ndev -> stats .rx_dropped ++ ;
1439
- } else {
1440
- int payload_offset = (2 * ETH_ALEN );
1441
- skb_reserve (skb , NET_IP_ALIGN );
1442
- skb_put (skb , pkt_len - 4 ); /* Make room */
1443
-
1444
- /* Extract the frame data without the VLAN header. */
1445
- skb_copy_to_linear_data (skb , data , (2 * ETH_ALEN ));
1446
- if (vlan_packet_rcvd )
1447
- payload_offset = (2 * ETH_ALEN ) + VLAN_HLEN ;
1448
- skb_copy_to_linear_data_offset (skb , (2 * ETH_ALEN ),
1449
- data + payload_offset ,
1450
- pkt_len - 4 - (2 * ETH_ALEN ));
1451
-
1452
- skb -> protocol = eth_type_trans (skb , ndev );
1453
-
1454
- /* Get receive timestamp from the skb */
1455
- if (fep -> hwts_rx_en && fep -> bufdesc_ex )
1456
- fec_enet_hwtstamp (fep , ebdp -> ts ,
1457
- skb_hwtstamps (skb ));
1458
-
1459
- if (fep -> bufdesc_ex &&
1460
- (fep -> csum_flags & FLAG_RX_CSUM_ENABLED )) {
1461
- if (!(ebdp -> cbd_esc & FLAG_RX_CSUM_ERROR )) {
1462
- /* don't check it */
1463
- skb -> ip_summed = CHECKSUM_UNNECESSARY ;
1464
- } else {
1465
- skb_checksum_none_assert (skb );
1466
- }
1499
+ /* Get receive timestamp from the skb */
1500
+ if (fep -> hwts_rx_en && fep -> bufdesc_ex )
1501
+ fec_enet_hwtstamp (fep , ebdp -> ts ,
1502
+ skb_hwtstamps (skb ));
1503
+
1504
+ if (fep -> bufdesc_ex &&
1505
+ (fep -> csum_flags & FLAG_RX_CSUM_ENABLED )) {
1506
+ if (!(ebdp -> cbd_esc & FLAG_RX_CSUM_ERROR )) {
1507
+ /* don't check it */
1508
+ skb -> ip_summed = CHECKSUM_UNNECESSARY ;
1509
+ } else {
1510
+ skb_checksum_none_assert (skb );
1467
1511
}
1512
+ }
1468
1513
1469
- /* Handle received VLAN packets */
1470
- if (vlan_packet_rcvd )
1471
- __vlan_hwaccel_put_tag (skb ,
1472
- htons (ETH_P_8021Q ),
1473
- vlan_tag );
1514
+ /* Handle received VLAN packets */
1515
+ if (vlan_packet_rcvd )
1516
+ __vlan_hwaccel_put_tag (skb ,
1517
+ htons (ETH_P_8021Q ),
1518
+ vlan_tag );
1474
1519
1475
- napi_gro_receive (& fep -> napi , skb );
1520
+ napi_gro_receive (& fep -> napi , skb );
1521
+
1522
+ if (is_copybreak ) {
1523
+ dma_sync_single_for_device (& fep -> pdev -> dev , bdp -> cbd_bufaddr ,
1524
+ FEC_ENET_RX_FRSIZE - fep -> rx_align ,
1525
+ DMA_FROM_DEVICE );
1526
+ } else {
1527
+ rxq -> rx_skbuff [index ] = skb_new ;
1528
+ fec_enet_new_rxbdp (ndev , bdp , skb_new );
1476
1529
}
1477
1530
1478
- dma_sync_single_for_device (& fep -> pdev -> dev , bdp -> cbd_bufaddr ,
1479
- FEC_ENET_RX_FRSIZE - fep -> rx_align ,
1480
- DMA_FROM_DEVICE );
1481
1531
rx_processing_done :
1482
1532
/* Clear the status flags for this buffer */
1483
1533
status &= ~BD_ENET_RX_STATS ;
@@ -2392,6 +2442,44 @@ static void fec_enet_itr_coal_init(struct net_device *ndev)
2392
2442
fec_enet_set_coalesce (ndev , & ec );
2393
2443
}
2394
2444
2445
+ static int fec_enet_get_tunable (struct net_device * netdev ,
2446
+ const struct ethtool_tunable * tuna ,
2447
+ void * data )
2448
+ {
2449
+ struct fec_enet_private * fep = netdev_priv (netdev );
2450
+ int ret = 0 ;
2451
+
2452
+ switch (tuna -> id ) {
2453
+ case ETHTOOL_RX_COPYBREAK :
2454
+ * (u32 * )data = fep -> rx_copybreak ;
2455
+ break ;
2456
+ default :
2457
+ ret = - EINVAL ;
2458
+ break ;
2459
+ }
2460
+
2461
+ return ret ;
2462
+ }
2463
+
2464
+ static int fec_enet_set_tunable (struct net_device * netdev ,
2465
+ const struct ethtool_tunable * tuna ,
2466
+ const void * data )
2467
+ {
2468
+ struct fec_enet_private * fep = netdev_priv (netdev );
2469
+ int ret = 0 ;
2470
+
2471
+ switch (tuna -> id ) {
2472
+ case ETHTOOL_RX_COPYBREAK :
2473
+ fep -> rx_copybreak = * (u32 * )data ;
2474
+ break ;
2475
+ default :
2476
+ ret = - EINVAL ;
2477
+ break ;
2478
+ }
2479
+
2480
+ return ret ;
2481
+ }
2482
+
2395
2483
static const struct ethtool_ops fec_enet_ethtool_ops = {
2396
2484
.get_settings = fec_enet_get_settings ,
2397
2485
.set_settings = fec_enet_set_settings ,
@@ -2408,6 +2496,8 @@ static const struct ethtool_ops fec_enet_ethtool_ops = {
2408
2496
.get_sset_count = fec_enet_get_sset_count ,
2409
2497
#endif
2410
2498
.get_ts_info = fec_enet_get_ts_info ,
2499
+ .get_tunable = fec_enet_get_tunable ,
2500
+ .set_tunable = fec_enet_set_tunable ,
2411
2501
};
2412
2502
2413
2503
static int fec_enet_ioctl (struct net_device * ndev , struct ifreq * rq , int cmd )
@@ -2553,33 +2643,20 @@ fec_enet_alloc_rxq_buffers(struct net_device *ndev, unsigned int queue)
2553
2643
struct sk_buff * skb ;
2554
2644
struct bufdesc * bdp ;
2555
2645
struct fec_enet_priv_rx_q * rxq ;
2556
- unsigned int off ;
2557
2646
2558
2647
rxq = fep -> rx_queue [queue ];
2559
2648
bdp = rxq -> rx_bd_base ;
2560
2649
for (i = 0 ; i < rxq -> rx_ring_size ; i ++ ) {
2561
- dma_addr_t addr ;
2562
-
2563
2650
skb = netdev_alloc_skb (ndev , FEC_ENET_RX_FRSIZE );
2564
2651
if (!skb )
2565
2652
goto err_alloc ;
2566
2653
2567
- off = ((unsigned long )skb -> data ) & fep -> rx_align ;
2568
- if (off )
2569
- skb_reserve (skb , fep -> rx_align + 1 - off );
2570
-
2571
- addr = dma_map_single (& fep -> pdev -> dev , skb -> data ,
2572
- FEC_ENET_RX_FRSIZE - fep -> rx_align , DMA_FROM_DEVICE );
2573
-
2574
- if (dma_mapping_error (& fep -> pdev -> dev , addr )) {
2654
+ if (fec_enet_new_rxbdp (ndev , bdp , skb )) {
2575
2655
dev_kfree_skb (skb );
2576
- if (net_ratelimit ())
2577
- netdev_err (ndev , "Rx DMA memory map failed\n" );
2578
2656
goto err_alloc ;
2579
2657
}
2580
2658
2581
2659
rxq -> rx_skbuff [i ] = skb ;
2582
- bdp -> cbd_bufaddr = addr ;
2583
2660
bdp -> cbd_sc = BD_ENET_RX_EMPTY ;
2584
2661
2585
2662
if (fep -> bufdesc_ex ) {
@@ -3240,6 +3317,7 @@ fec_probe(struct platform_device *pdev)
3240
3317
if (fep -> bufdesc_ex && fep -> ptp_clock )
3241
3318
netdev_info (ndev , "registered PHC device %d\n" , fep -> dev_id );
3242
3319
3320
+ fep -> rx_copybreak = COPYBREAK_DEFAULT ;
3243
3321
INIT_WORK (& fep -> tx_timeout_work , fec_enet_timeout_work );
3244
3322
return 0 ;
3245
3323
0 commit comments