@@ -795,8 +795,18 @@ static int gfar_hwtstamp_ioctl(struct net_device *netdev,
795
795
if (config .flags )
796
796
return - EINVAL ;
797
797
798
- if (config .tx_type )
798
+ switch (config .tx_type ) {
799
+ case HWTSTAMP_TX_OFF :
800
+ priv -> hwts_tx_en = 0 ;
801
+ break ;
802
+ case HWTSTAMP_TX_ON :
803
+ if (!(priv -> device_flags & FSL_GIANFAR_DEV_HAS_TIMER ))
804
+ return - ERANGE ;
805
+ priv -> hwts_tx_en = 1 ;
806
+ break ;
807
+ default :
799
808
return - ERANGE ;
809
+ }
800
810
801
811
switch (config .rx_filter ) {
802
812
case HWTSTAMP_FILTER_NONE :
@@ -1972,23 +1982,29 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
1972
1982
struct netdev_queue * txq ;
1973
1983
struct gfar __iomem * regs = NULL ;
1974
1984
struct txfcb * fcb = NULL ;
1975
- struct txbd8 * txbdp , * txbdp_start , * base ;
1985
+ struct txbd8 * txbdp , * txbdp_start , * base , * txbdp_tstamp = NULL ;
1976
1986
u32 lstatus ;
1977
- int i , rq = 0 ;
1987
+ int i , rq = 0 , do_tstamp = 0 ;
1978
1988
u32 bufaddr ;
1979
1989
unsigned long flags ;
1980
- unsigned int nr_frags , length ;
1981
-
1990
+ unsigned int nr_frags , nr_txbds , length ;
1991
+ union skb_shared_tx * shtx ;
1982
1992
1983
1993
rq = skb -> queue_mapping ;
1984
1994
tx_queue = priv -> tx_queue [rq ];
1985
1995
txq = netdev_get_tx_queue (dev , rq );
1986
1996
base = tx_queue -> tx_bd_base ;
1987
1997
regs = tx_queue -> grp -> regs ;
1998
+ shtx = skb_tx (skb );
1999
+
2000
+ /* check if time stamp should be generated */
2001
+ if (unlikely (shtx -> hardware && priv -> hwts_tx_en ))
2002
+ do_tstamp = 1 ;
1988
2003
1989
2004
/* make space for additional header when fcb is needed */
1990
2005
if (((skb -> ip_summed == CHECKSUM_PARTIAL ) ||
1991
- (priv -> vlgrp && vlan_tx_tag_present (skb ))) &&
2006
+ (priv -> vlgrp && vlan_tx_tag_present (skb )) ||
2007
+ unlikely (do_tstamp )) &&
1992
2008
(skb_headroom (skb ) < GMAC_FCB_LEN )) {
1993
2009
struct sk_buff * skb_new ;
1994
2010
@@ -2005,8 +2021,14 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
2005
2021
/* total number of fragments in the SKB */
2006
2022
nr_frags = skb_shinfo (skb )-> nr_frags ;
2007
2023
2024
+ /* calculate the required number of TxBDs for this skb */
2025
+ if (unlikely (do_tstamp ))
2026
+ nr_txbds = nr_frags + 2 ;
2027
+ else
2028
+ nr_txbds = nr_frags + 1 ;
2029
+
2008
2030
/* check if there is space to queue this packet */
2009
- if (( nr_frags + 1 ) > tx_queue -> num_txbdfree ) {
2031
+ if (nr_txbds > tx_queue -> num_txbdfree ) {
2010
2032
/* no space, stop the queue */
2011
2033
netif_tx_stop_queue (txq );
2012
2034
dev -> stats .tx_fifo_errors ++ ;
@@ -2018,9 +2040,19 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
2018
2040
txq -> tx_packets ++ ;
2019
2041
2020
2042
txbdp = txbdp_start = tx_queue -> cur_tx ;
2043
+ lstatus = txbdp -> lstatus ;
2044
+
2045
+ /* Time stamp insertion requires one additional TxBD */
2046
+ if (unlikely (do_tstamp ))
2047
+ txbdp_tstamp = txbdp = next_txbd (txbdp , base ,
2048
+ tx_queue -> tx_ring_size );
2021
2049
2022
2050
if (nr_frags == 0 ) {
2023
- lstatus = txbdp -> lstatus | BD_LFLAG (TXBD_LAST | TXBD_INTERRUPT );
2051
+ if (unlikely (do_tstamp ))
2052
+ txbdp_tstamp -> lstatus |= BD_LFLAG (TXBD_LAST |
2053
+ TXBD_INTERRUPT );
2054
+ else
2055
+ lstatus |= BD_LFLAG (TXBD_LAST | TXBD_INTERRUPT );
2024
2056
} else {
2025
2057
/* Place the fragment addresses and lengths into the TxBDs */
2026
2058
for (i = 0 ; i < nr_frags ; i ++ ) {
@@ -2066,11 +2098,32 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
2066
2098
gfar_tx_vlan (skb , fcb );
2067
2099
}
2068
2100
2069
- /* setup the TxBD length and buffer pointer for the first BD */
2101
+ /* Setup tx hardware time stamping if requested */
2102
+ if (unlikely (do_tstamp )) {
2103
+ shtx -> in_progress = 1 ;
2104
+ if (fcb == NULL )
2105
+ fcb = gfar_add_fcb (skb );
2106
+ fcb -> ptp = 1 ;
2107
+ lstatus |= BD_LFLAG (TXBD_TOE );
2108
+ }
2109
+
2070
2110
txbdp_start -> bufPtr = dma_map_single (& priv -> ofdev -> dev , skb -> data ,
2071
2111
skb_headlen (skb ), DMA_TO_DEVICE );
2072
2112
2073
- lstatus |= BD_LFLAG (TXBD_CRC | TXBD_READY ) | skb_headlen (skb );
2113
+ /*
2114
+ * If time stamping is requested one additional TxBD must be set up. The
2115
+ * first TxBD points to the FCB and must have a data length of
2116
+ * GMAC_FCB_LEN. The second TxBD points to the actual frame data with
2117
+ * the full frame length.
2118
+ */
2119
+ if (unlikely (do_tstamp )) {
2120
+ txbdp_tstamp -> bufPtr = txbdp_start -> bufPtr + GMAC_FCB_LEN ;
2121
+ txbdp_tstamp -> lstatus |= BD_LFLAG (TXBD_READY ) |
2122
+ (skb_headlen (skb ) - GMAC_FCB_LEN );
2123
+ lstatus |= BD_LFLAG (TXBD_CRC | TXBD_READY ) | GMAC_FCB_LEN ;
2124
+ } else {
2125
+ lstatus |= BD_LFLAG (TXBD_CRC | TXBD_READY ) | skb_headlen (skb );
2126
+ }
2074
2127
2075
2128
/*
2076
2129
* We can work in parallel with gfar_clean_tx_ring(), except
@@ -2110,7 +2163,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
2110
2163
tx_queue -> cur_tx = next_txbd (txbdp , base , tx_queue -> tx_ring_size );
2111
2164
2112
2165
/* reduce TxBD free count */
2113
- tx_queue -> num_txbdfree -= (nr_frags + 1 );
2166
+ tx_queue -> num_txbdfree -= (nr_txbds );
2114
2167
2115
2168
dev -> trans_start = jiffies ;
2116
2169
@@ -2301,16 +2354,18 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
2301
2354
struct net_device * dev = tx_queue -> dev ;
2302
2355
struct gfar_private * priv = netdev_priv (dev );
2303
2356
struct gfar_priv_rx_q * rx_queue = NULL ;
2304
- struct txbd8 * bdp ;
2357
+ struct txbd8 * bdp , * next = NULL ;
2305
2358
struct txbd8 * lbdp = NULL ;
2306
2359
struct txbd8 * base = tx_queue -> tx_bd_base ;
2307
2360
struct sk_buff * skb ;
2308
2361
int skb_dirtytx ;
2309
2362
int tx_ring_size = tx_queue -> tx_ring_size ;
2310
- int frags = 0 ;
2363
+ int frags = 0 , nr_txbds = 0 ;
2311
2364
int i ;
2312
2365
int howmany = 0 ;
2313
2366
u32 lstatus ;
2367
+ size_t buflen ;
2368
+ union skb_shared_tx * shtx ;
2314
2369
2315
2370
rx_queue = priv -> rx_queue [tx_queue -> qindex ];
2316
2371
bdp = tx_queue -> dirty_tx ;
@@ -2320,7 +2375,18 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
2320
2375
unsigned long flags ;
2321
2376
2322
2377
frags = skb_shinfo (skb )-> nr_frags ;
2323
- lbdp = skip_txbd (bdp , frags , base , tx_ring_size );
2378
+
2379
+ /*
2380
+ * When time stamping, one additional TxBD must be freed.
2381
+ * Also, we need to dma_unmap_single() the TxPAL.
2382
+ */
2383
+ shtx = skb_tx (skb );
2384
+ if (unlikely (shtx -> in_progress ))
2385
+ nr_txbds = frags + 2 ;
2386
+ else
2387
+ nr_txbds = frags + 1 ;
2388
+
2389
+ lbdp = skip_txbd (bdp , nr_txbds - 1 , base , tx_ring_size );
2324
2390
2325
2391
lstatus = lbdp -> lstatus ;
2326
2392
@@ -2329,10 +2395,24 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
2329
2395
(lstatus & BD_LENGTH_MASK ))
2330
2396
break ;
2331
2397
2332
- dma_unmap_single (& priv -> ofdev -> dev ,
2333
- bdp -> bufPtr ,
2334
- bdp -> length ,
2335
- DMA_TO_DEVICE );
2398
+ if (unlikely (shtx -> in_progress )) {
2399
+ next = next_txbd (bdp , base , tx_ring_size );
2400
+ buflen = next -> length + GMAC_FCB_LEN ;
2401
+ } else
2402
+ buflen = bdp -> length ;
2403
+
2404
+ dma_unmap_single (& priv -> ofdev -> dev , bdp -> bufPtr ,
2405
+ buflen , DMA_TO_DEVICE );
2406
+
2407
+ if (unlikely (shtx -> in_progress )) {
2408
+ struct skb_shared_hwtstamps shhwtstamps ;
2409
+ u64 * ns = (u64 * ) (((u32 )skb -> data + 0x10 ) & ~0x7 );
2410
+ memset (& shhwtstamps , 0 , sizeof (shhwtstamps ));
2411
+ shhwtstamps .hwtstamp = ns_to_ktime (* ns );
2412
+ skb_tstamp_tx (skb , & shhwtstamps );
2413
+ bdp -> lstatus &= BD_LFLAG (TXBD_WRAP );
2414
+ bdp = next ;
2415
+ }
2336
2416
2337
2417
bdp -> lstatus &= BD_LFLAG (TXBD_WRAP );
2338
2418
bdp = next_txbd (bdp , base , tx_ring_size );
@@ -2364,7 +2444,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
2364
2444
2365
2445
howmany ++ ;
2366
2446
spin_lock_irqsave (& tx_queue -> txlock , flags );
2367
- tx_queue -> num_txbdfree += frags + 1 ;
2447
+ tx_queue -> num_txbdfree += nr_txbds ;
2368
2448
spin_unlock_irqrestore (& tx_queue -> txlock , flags );
2369
2449
}
2370
2450
0 commit comments