13
13
#define ENETC_MAX_SKB_FRAGS 13
14
14
#define ENETC_TXBDS_MAX_NEEDED ENETC_TXBDS_NEEDED(ENETC_MAX_SKB_FRAGS + 1)
15
15
16
- static int enetc_map_tx_buffs (struct enetc_bdr * tx_ring , struct sk_buff * skb );
16
+ static int enetc_map_tx_buffs (struct enetc_bdr * tx_ring , struct sk_buff * skb ,
17
+ int active_offloads );
17
18
18
19
netdev_tx_t enetc_xmit (struct sk_buff * skb , struct net_device * ndev )
19
20
{
@@ -33,7 +34,7 @@ netdev_tx_t enetc_xmit(struct sk_buff *skb, struct net_device *ndev)
33
34
return NETDEV_TX_BUSY ;
34
35
}
35
36
36
- count = enetc_map_tx_buffs (tx_ring , skb );
37
+ count = enetc_map_tx_buffs (tx_ring , skb , priv -> active_offloads );
37
38
if (unlikely (!count ))
38
39
goto drop_packet_err ;
39
40
@@ -105,7 +106,8 @@ static void enetc_free_tx_skb(struct enetc_bdr *tx_ring,
105
106
}
106
107
}
107
108
108
- static int enetc_map_tx_buffs (struct enetc_bdr * tx_ring , struct sk_buff * skb )
109
+ static int enetc_map_tx_buffs (struct enetc_bdr * tx_ring , struct sk_buff * skb ,
110
+ int active_offloads )
109
111
{
110
112
struct enetc_tx_swbd * tx_swbd ;
111
113
struct skb_frag_struct * frag ;
@@ -137,7 +139,10 @@ static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb)
137
139
count ++ ;
138
140
139
141
do_vlan = skb_vlan_tag_present (skb );
140
- do_tstamp = skb_shinfo (skb )-> tx_flags & SKBTX_HW_TSTAMP ;
142
+ do_tstamp = (active_offloads & ENETC_F_TX_TSTAMP ) &&
143
+ (skb_shinfo (skb )-> tx_flags & SKBTX_HW_TSTAMP );
144
+ tx_swbd -> do_tstamp = do_tstamp ;
145
+ tx_swbd -> check_wb = tx_swbd -> do_tstamp ;
141
146
142
147
if (do_vlan || do_tstamp )
143
148
flags |= ENETC_TXBD_FLAGS_EX ;
@@ -299,24 +304,69 @@ static int enetc_bd_ready_count(struct enetc_bdr *tx_ring, int ci)
299
304
return pi >= ci ? pi - ci : tx_ring -> bd_count - ci + pi ;
300
305
}
301
306
307
+ static void enetc_get_tx_tstamp (struct enetc_hw * hw , union enetc_tx_bd * txbd ,
308
+ u64 * tstamp )
309
+ {
310
+ u32 lo , hi ;
311
+
312
+ lo = enetc_rd (hw , ENETC_SICTR0 );
313
+ hi = enetc_rd (hw , ENETC_SICTR1 );
314
+ if (lo <= txbd -> wb .tstamp )
315
+ hi -= 1 ;
316
+ * tstamp = (u64 )hi << 32 | txbd -> wb .tstamp ;
317
+ }
318
+
319
+ static void enetc_tstamp_tx (struct sk_buff * skb , u64 tstamp )
320
+ {
321
+ struct skb_shared_hwtstamps shhwtstamps ;
322
+
323
+ if (skb_shinfo (skb )-> tx_flags & SKBTX_IN_PROGRESS ) {
324
+ memset (& shhwtstamps , 0 , sizeof (shhwtstamps ));
325
+ shhwtstamps .hwtstamp = ns_to_ktime (tstamp );
326
+ skb_tstamp_tx (skb , & shhwtstamps );
327
+ }
328
+ }
329
+
302
330
static bool enetc_clean_tx_ring (struct enetc_bdr * tx_ring , int napi_budget )
303
331
{
304
332
struct net_device * ndev = tx_ring -> ndev ;
305
333
int tx_frm_cnt = 0 , tx_byte_cnt = 0 ;
306
334
struct enetc_tx_swbd * tx_swbd ;
307
335
int i , bds_to_clean ;
336
+ bool do_tstamp ;
337
+ u64 tstamp = 0 ;
308
338
309
339
i = tx_ring -> next_to_clean ;
310
340
tx_swbd = & tx_ring -> tx_swbd [i ];
311
341
bds_to_clean = enetc_bd_ready_count (tx_ring , i );
312
342
343
+ do_tstamp = false;
344
+
313
345
while (bds_to_clean && tx_frm_cnt < ENETC_DEFAULT_TX_WORK ) {
314
346
bool is_eof = !!tx_swbd -> skb ;
315
347
348
+ if (unlikely (tx_swbd -> check_wb )) {
349
+ struct enetc_ndev_priv * priv = netdev_priv (ndev );
350
+ union enetc_tx_bd * txbd ;
351
+
352
+ txbd = ENETC_TXBD (* tx_ring , i );
353
+
354
+ if (txbd -> flags & ENETC_TXBD_FLAGS_W &&
355
+ tx_swbd -> do_tstamp ) {
356
+ enetc_get_tx_tstamp (& priv -> si -> hw , txbd ,
357
+ & tstamp );
358
+ do_tstamp = true;
359
+ }
360
+ }
361
+
316
362
if (likely (tx_swbd -> dma ))
317
363
enetc_unmap_tx_buff (tx_ring , tx_swbd );
318
364
319
365
if (is_eof ) {
366
+ if (unlikely (do_tstamp )) {
367
+ enetc_tstamp_tx (tx_swbd -> skb , tstamp );
368
+ do_tstamp = false;
369
+ }
320
370
napi_consume_skb (tx_swbd -> skb , napi_budget );
321
371
tx_swbd -> skb = NULL ;
322
372
}
@@ -425,10 +475,37 @@ static int enetc_refill_rx_ring(struct enetc_bdr *rx_ring, const int buff_cnt)
425
475
return j ;
426
476
}
427
477
478
+ #ifdef CONFIG_FSL_ENETC_HW_TIMESTAMPING
479
+ static void enetc_get_rx_tstamp (struct net_device * ndev ,
480
+ union enetc_rx_bd * rxbd ,
481
+ struct sk_buff * skb )
482
+ {
483
+ struct skb_shared_hwtstamps * shhwtstamps = skb_hwtstamps (skb );
484
+ struct enetc_ndev_priv * priv = netdev_priv (ndev );
485
+ struct enetc_hw * hw = & priv -> si -> hw ;
486
+ u32 lo , hi ;
487
+ u64 tstamp ;
488
+
489
+ if (rxbd -> r .flags & ENETC_RXBD_FLAG_TSTMP ) {
490
+ lo = enetc_rd (hw , ENETC_SICTR0 );
491
+ hi = enetc_rd (hw , ENETC_SICTR1 );
492
+ if (lo <= rxbd -> r .tstamp )
493
+ hi -= 1 ;
494
+
495
+ tstamp = (u64 )hi << 32 | rxbd -> r .tstamp ;
496
+ memset (shhwtstamps , 0 , sizeof (* shhwtstamps ));
497
+ shhwtstamps -> hwtstamp = ns_to_ktime (tstamp );
498
+ }
499
+ }
500
+ #endif
501
+
428
502
static void enetc_get_offloads (struct enetc_bdr * rx_ring ,
429
503
union enetc_rx_bd * rxbd , struct sk_buff * skb )
430
504
{
431
- /* TODO: add tstamp, hashing */
505
+ #ifdef CONFIG_FSL_ENETC_HW_TIMESTAMPING
506
+ struct enetc_ndev_priv * priv = netdev_priv (rx_ring -> ndev );
507
+ #endif
508
+ /* TODO: hashing */
432
509
if (rx_ring -> ndev -> features & NETIF_F_RXCSUM ) {
433
510
u16 inet_csum = le16_to_cpu (rxbd -> r .inet_csum );
434
511
@@ -442,6 +519,10 @@ static void enetc_get_offloads(struct enetc_bdr *rx_ring,
442
519
if (le16_to_cpu (rxbd -> r .flags ) & ENETC_RXBD_FLAG_VLAN )
443
520
__vlan_hwaccel_put_tag (skb , htons (ETH_P_8021Q ),
444
521
le16_to_cpu (rxbd -> r .vlan_opt ));
522
+ #ifdef CONFIG_FSL_ENETC_HW_TIMESTAMPING
523
+ if (priv -> active_offloads & ENETC_F_RX_TSTAMP )
524
+ enetc_get_rx_tstamp (rx_ring -> ndev , rxbd , skb );
525
+ #endif
445
526
}
446
527
447
528
static void enetc_process_skb (struct enetc_bdr * rx_ring ,
@@ -1074,6 +1155,9 @@ static void enetc_setup_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring)
1074
1155
enetc_rxbdr_wr (hw , idx , ENETC_RBICIR0 , ENETC_RBICIR0_ICEN | 0x1 );
1075
1156
1076
1157
rbmr = ENETC_RBMR_EN ;
1158
+ #ifdef CONFIG_FSL_ENETC_HW_TIMESTAMPING
1159
+ rbmr |= ENETC_RBMR_BDS ;
1160
+ #endif
1077
1161
if (rx_ring -> ndev -> features & NETIF_F_HW_VLAN_CTAG_RX )
1078
1162
rbmr |= ENETC_RBMR_VTE ;
1079
1163
@@ -1396,6 +1480,70 @@ int enetc_set_features(struct net_device *ndev,
1396
1480
return 0 ;
1397
1481
}
1398
1482
1483
+ #ifdef CONFIG_FSL_ENETC_HW_TIMESTAMPING
1484
+ static int enetc_hwtstamp_set (struct net_device * ndev , struct ifreq * ifr )
1485
+ {
1486
+ struct enetc_ndev_priv * priv = netdev_priv (ndev );
1487
+ struct hwtstamp_config config ;
1488
+
1489
+ if (copy_from_user (& config , ifr -> ifr_data , sizeof (config )))
1490
+ return - EFAULT ;
1491
+
1492
+ switch (config .tx_type ) {
1493
+ case HWTSTAMP_TX_OFF :
1494
+ priv -> active_offloads &= ~ENETC_F_TX_TSTAMP ;
1495
+ break ;
1496
+ case HWTSTAMP_TX_ON :
1497
+ priv -> active_offloads |= ENETC_F_TX_TSTAMP ;
1498
+ break ;
1499
+ default :
1500
+ return - ERANGE ;
1501
+ }
1502
+
1503
+ switch (config .rx_filter ) {
1504
+ case HWTSTAMP_FILTER_NONE :
1505
+ priv -> active_offloads &= ~ENETC_F_RX_TSTAMP ;
1506
+ break ;
1507
+ default :
1508
+ priv -> active_offloads |= ENETC_F_RX_TSTAMP ;
1509
+ config .rx_filter = HWTSTAMP_FILTER_ALL ;
1510
+ }
1511
+
1512
+ return copy_to_user (ifr -> ifr_data , & config , sizeof (config )) ?
1513
+ - EFAULT : 0 ;
1514
+ }
1515
+
1516
+ static int enetc_hwtstamp_get (struct net_device * ndev , struct ifreq * ifr )
1517
+ {
1518
+ struct enetc_ndev_priv * priv = netdev_priv (ndev );
1519
+ struct hwtstamp_config config ;
1520
+
1521
+ config .flags = 0 ;
1522
+
1523
+ if (priv -> active_offloads & ENETC_F_TX_TSTAMP )
1524
+ config .tx_type = HWTSTAMP_TX_ON ;
1525
+ else
1526
+ config .tx_type = HWTSTAMP_TX_OFF ;
1527
+
1528
+ config .rx_filter = (priv -> active_offloads & ENETC_F_RX_TSTAMP ) ?
1529
+ HWTSTAMP_FILTER_ALL : HWTSTAMP_FILTER_NONE ;
1530
+
1531
+ return copy_to_user (ifr -> ifr_data , & config , sizeof (config )) ?
1532
+ - EFAULT : 0 ;
1533
+ }
1534
+ #endif
1535
+
1536
+ int enetc_ioctl (struct net_device * ndev , struct ifreq * rq , int cmd )
1537
+ {
1538
+ #ifdef CONFIG_FSL_ENETC_HW_TIMESTAMPING
1539
+ if (cmd == SIOCSHWTSTAMP )
1540
+ return enetc_hwtstamp_set (ndev , rq );
1541
+ if (cmd == SIOCGHWTSTAMP )
1542
+ return enetc_hwtstamp_get (ndev , rq );
1543
+ #endif
1544
+ return - EINVAL ;
1545
+ }
1546
+
1399
1547
int enetc_alloc_msix (struct enetc_ndev_priv * priv )
1400
1548
{
1401
1549
struct pci_dev * pdev = priv -> si -> pdev ;
0 commit comments