3636#include <linux/in.h>
3737#include <linux/ip.h>
3838#include <net/ip.h>
39+ #include <net/tso.h>
3940#include <linux/tcp.h>
4041#include <linux/udp.h>
4142#include <linux/icmp.h>
@@ -228,6 +229,15 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
228229#define FEC_PAUSE_FLAG_AUTONEG 0x1
229230#define FEC_PAUSE_FLAG_ENABLE 0x2
230231
232+ #define TSO_HEADER_SIZE 128
233+ /* Max number of allowed TCP segments for software TSO */
234+ #define FEC_MAX_TSO_SEGS 100
235+ #define FEC_MAX_SKB_DESCS (FEC_MAX_TSO_SEGS * 2 + MAX_SKB_FRAGS)
236+
237+ #define IS_TSO_HEADER (txq , addr ) \
238+ ((addr >= txq->tso_hdrs_dma) && \
239+ (addr < txq->tso_hdrs_dma + txq->tx_ring_size * TSO_HEADER_SIZE))
240+
231241static int mii_cnt ;
232242
233243static inline
@@ -438,8 +448,17 @@ static int fec_enet_txq_submit_skb(struct sk_buff *skb, struct net_device *ndev)
438448 unsigned short buflen ;
439449 unsigned int estatus = 0 ;
440450 unsigned int index ;
451+ int entries_free ;
441452 int ret ;
442453
454+ entries_free = fec_enet_get_free_txdesc_num (fep );
455+ if (entries_free < MAX_SKB_FRAGS + 1 ) {
456+ dev_kfree_skb_any (skb );
457+ if (net_ratelimit ())
458+ netdev_err (ndev , "NOT enough BD for SG!\n" );
459+ return NETDEV_TX_OK ;
460+ }
461+
443462 /* Protocol checksum off-load for TCP and UDP. */
444463 if (fec_enet_clear_csum (skb , ndev )) {
445464 dev_kfree_skb_any (skb );
@@ -534,35 +553,210 @@ static int fec_enet_txq_submit_skb(struct sk_buff *skb, struct net_device *ndev)
534553 return 0 ;
535554}
536555
537- static netdev_tx_t
538- fec_enet_start_xmit (struct sk_buff * skb , struct net_device * ndev )
556+ static int
557+ fec_enet_txq_put_data_tso (struct sk_buff * skb , struct net_device * ndev ,
558+ struct bufdesc * bdp , int index , char * data ,
559+ int size , bool last_tcp , bool is_last )
539560{
540561 struct fec_enet_private * fep = netdev_priv (ndev );
541- struct bufdesc * bdp ;
542- unsigned short status ;
543- int entries_free ;
544- int ret ;
545-
546- /* Fill in a Tx ring entry */
547- bdp = fep -> cur_tx ;
562+ const struct platform_device_id * id_entry =
563+ platform_get_device_id (fep -> pdev );
564+ struct bufdesc_ex * ebdp = (struct bufdesc_ex * )bdp ;
565+ unsigned short status ;
566+ unsigned int estatus = 0 ;
548567
549568 status = bdp -> cbd_sc ;
569+ status &= ~BD_ENET_TX_STATS ;
550570
551- if (status & BD_ENET_TX_READY ) {
552- /* Ooops. All transmit buffers are full. Bail out.
553- * This should not happen, since ndev->tbusy should be set.
554- */
571+ status |= (BD_ENET_TX_TC | BD_ENET_TX_READY );
572+ bdp -> cbd_datlen = size ;
573+
574+ if (((unsigned long ) data ) & FEC_ALIGNMENT ||
575+ id_entry -> driver_data & FEC_QUIRK_SWAP_FRAME ) {
576+ memcpy (fep -> tx_bounce [index ], data , size );
577+ data = fep -> tx_bounce [index ];
578+
579+ if (id_entry -> driver_data & FEC_QUIRK_SWAP_FRAME )
580+ swap_buffer (data , size );
581+ }
582+
583+ bdp -> cbd_bufaddr = dma_map_single (& fep -> pdev -> dev , data ,
584+ size , DMA_TO_DEVICE );
585+ if (dma_mapping_error (& fep -> pdev -> dev , bdp -> cbd_bufaddr )) {
586+ dev_kfree_skb_any (skb );
555587 if (net_ratelimit ())
556- netdev_err (ndev , "tx queue full! \n" );
588+ netdev_err (ndev , "Tx DMA memory map failed \n" );
557589 return NETDEV_TX_BUSY ;
558590 }
559591
560- ret = fec_enet_txq_submit_skb (skb , ndev );
592+ if (fep -> bufdesc_ex ) {
593+ if (skb -> ip_summed == CHECKSUM_PARTIAL )
594+ estatus |= BD_ENET_TX_PINS | BD_ENET_TX_IINS ;
595+ ebdp -> cbd_bdu = 0 ;
596+ ebdp -> cbd_esc = estatus ;
597+ }
598+
599+ /* Handle the last BD specially */
600+ if (last_tcp )
601+ status |= (BD_ENET_TX_LAST | BD_ENET_TX_TC );
602+ if (is_last ) {
603+ status |= BD_ENET_TX_INTR ;
604+ if (fep -> bufdesc_ex )
605+ ebdp -> cbd_esc |= BD_ENET_TX_INT ;
606+ }
607+
608+ bdp -> cbd_sc = status ;
609+
610+ return 0 ;
611+ }
612+
613+ static int
614+ fec_enet_txq_put_hdr_tso (struct sk_buff * skb , struct net_device * ndev ,
615+ struct bufdesc * bdp , int index )
616+ {
617+ struct fec_enet_private * fep = netdev_priv (ndev );
618+ const struct platform_device_id * id_entry =
619+ platform_get_device_id (fep -> pdev );
620+ int hdr_len = skb_transport_offset (skb ) + tcp_hdrlen (skb );
621+ struct bufdesc_ex * ebdp = (struct bufdesc_ex * )bdp ;
622+ void * bufaddr ;
623+ unsigned long dmabuf ;
624+ unsigned short status ;
625+ unsigned int estatus = 0 ;
626+
627+ status = bdp -> cbd_sc ;
628+ status &= ~BD_ENET_TX_STATS ;
629+ status |= (BD_ENET_TX_TC | BD_ENET_TX_READY );
630+
631+ bufaddr = fep -> tso_hdrs + index * TSO_HEADER_SIZE ;
632+ dmabuf = fep -> tso_hdrs_dma + index * TSO_HEADER_SIZE ;
633+ if (((unsigned long ) bufaddr ) & FEC_ALIGNMENT ||
634+ id_entry -> driver_data & FEC_QUIRK_SWAP_FRAME ) {
635+ memcpy (fep -> tx_bounce [index ], skb -> data , hdr_len );
636+ bufaddr = fep -> tx_bounce [index ];
637+
638+ if (id_entry -> driver_data & FEC_QUIRK_SWAP_FRAME )
639+ swap_buffer (bufaddr , hdr_len );
640+
641+ dmabuf = dma_map_single (& fep -> pdev -> dev , bufaddr ,
642+ hdr_len , DMA_TO_DEVICE );
643+ if (dma_mapping_error (& fep -> pdev -> dev , dmabuf )) {
644+ dev_kfree_skb_any (skb );
645+ if (net_ratelimit ())
646+ netdev_err (ndev , "Tx DMA memory map failed\n" );
647+ return NETDEV_TX_BUSY ;
648+ }
649+ }
650+
651+ bdp -> cbd_bufaddr = dmabuf ;
652+ bdp -> cbd_datlen = hdr_len ;
653+
654+ if (fep -> bufdesc_ex ) {
655+ if (skb -> ip_summed == CHECKSUM_PARTIAL )
656+ estatus |= BD_ENET_TX_PINS | BD_ENET_TX_IINS ;
657+ ebdp -> cbd_bdu = 0 ;
658+ ebdp -> cbd_esc = estatus ;
659+ }
660+
661+ bdp -> cbd_sc = status ;
662+
663+ return 0 ;
664+ }
665+
666+ static int fec_enet_txq_submit_tso (struct sk_buff * skb , struct net_device * ndev )
667+ {
668+ struct fec_enet_private * fep = netdev_priv (ndev );
669+ int hdr_len = skb_transport_offset (skb ) + tcp_hdrlen (skb );
670+ int total_len , data_left ;
671+ struct bufdesc * bdp = fep -> cur_tx ;
672+ struct tso_t tso ;
673+ unsigned int index = 0 ;
674+ int ret ;
675+
676+ if (tso_count_descs (skb ) >= fec_enet_get_free_txdesc_num (fep )) {
677+ dev_kfree_skb_any (skb );
678+ if (net_ratelimit ())
679+ netdev_err (ndev , "NOT enough BD for TSO!\n" );
680+ return NETDEV_TX_OK ;
681+ }
682+
683+ /* Protocol checksum off-load for TCP and UDP. */
684+ if (fec_enet_clear_csum (skb , ndev )) {
685+ dev_kfree_skb_any (skb );
686+ return NETDEV_TX_OK ;
687+ }
688+
689+ /* Initialize the TSO handler, and prepare the first payload */
690+ tso_start (skb , & tso );
691+
692+ total_len = skb -> len - hdr_len ;
693+ while (total_len > 0 ) {
694+ char * hdr ;
695+
696+ index = fec_enet_get_bd_index (fep -> tx_bd_base , bdp , fep );
697+ data_left = min_t (int , skb_shinfo (skb )-> gso_size , total_len );
698+ total_len -= data_left ;
699+
700+ /* prepare packet headers: MAC + IP + TCP */
701+ hdr = fep -> tso_hdrs + index * TSO_HEADER_SIZE ;
702+ tso_build_hdr (skb , hdr , & tso , data_left , total_len == 0 );
703+ ret = fec_enet_txq_put_hdr_tso (skb , ndev , bdp , index );
704+ if (ret )
705+ goto err_release ;
706+
707+ while (data_left > 0 ) {
708+ int size ;
709+
710+ size = min_t (int , tso .size , data_left );
711+ bdp = fec_enet_get_nextdesc (bdp , fep );
712+ index = fec_enet_get_bd_index (fep -> tx_bd_base , bdp , fep );
713+ ret = fec_enet_txq_put_data_tso (skb , ndev , bdp , index , tso .data ,
714+ size , size == data_left ,
715+ total_len == 0 );
716+ if (ret )
717+ goto err_release ;
718+
719+ data_left -= size ;
720+ tso_build_data (skb , & tso , size );
721+ }
722+
723+ bdp = fec_enet_get_nextdesc (bdp , fep );
724+ }
725+
726+ /* Save skb pointer */
727+ fep -> tx_skbuff [index ] = skb ;
728+
729+ fec_enet_submit_work (bdp , fep );
730+
731+ skb_tx_timestamp (skb );
732+ fep -> cur_tx = bdp ;
733+
734+ /* Trigger transmission start */
735+ writel (0 , fep -> hwp + FEC_X_DES_ACTIVE );
736+
737+ return 0 ;
738+
739+ err_release :
740+ /* TODO: Release all used data descriptors for TSO */
741+ return ret ;
742+ }
743+
744+ static netdev_tx_t
745+ fec_enet_start_xmit (struct sk_buff * skb , struct net_device * ndev )
746+ {
747+ struct fec_enet_private * fep = netdev_priv (ndev );
748+ int entries_free ;
749+ int ret ;
750+
751+ if (skb_is_gso (skb ))
752+ ret = fec_enet_txq_submit_tso (skb , ndev );
753+ else
754+ ret = fec_enet_txq_submit_skb (skb , ndev );
561755 if (ret )
562756 return ret ;
563757
564758 entries_free = fec_enet_get_free_txdesc_num (fep );
565- if (entries_free < MAX_SKB_FRAGS + 1 )
759+ if (entries_free <= fep -> tx_stop_threshold )
566760 netif_stop_queue (ndev );
567761
568762 return NETDEV_TX_OK ;
@@ -883,7 +1077,7 @@ fec_enet_tx(struct net_device *ndev)
8831077 unsigned short status ;
8841078 struct sk_buff * skb ;
8851079 int index = 0 ;
886- int entries ;
1080+ int entries_free ;
8871081
8881082 fep = netdev_priv (ndev );
8891083 bdp = fep -> dirty_tx ;
@@ -900,8 +1094,9 @@ fec_enet_tx(struct net_device *ndev)
9001094 index = fec_enet_get_bd_index (fep -> tx_bd_base , bdp , fep );
9011095
9021096 skb = fep -> tx_skbuff [index ];
903- dma_unmap_single (& fep -> pdev -> dev , bdp -> cbd_bufaddr , bdp -> cbd_datlen ,
904- DMA_TO_DEVICE );
1097+ if (!IS_TSO_HEADER (fep , bdp -> cbd_bufaddr ))
1098+ dma_unmap_single (& fep -> pdev -> dev , bdp -> cbd_bufaddr ,
1099+ bdp -> cbd_datlen , DMA_TO_DEVICE );
9051100 bdp -> cbd_bufaddr = 0 ;
9061101 if (!skb ) {
9071102 bdp = fec_enet_get_nextdesc (bdp , fep );
@@ -962,9 +1157,11 @@ fec_enet_tx(struct net_device *ndev)
9621157
9631158 /* Since we have freed up a buffer, the ring is no longer full
9641159 */
965- entries = fec_enet_get_free_txdesc_num (fep );
966- if (entries >= MAX_SKB_FRAGS + 1 && netif_queue_stopped (ndev ))
967- netif_wake_queue (ndev );
1160+ if (netif_queue_stopped (ndev )) {
1161+ entries_free = fec_enet_get_free_txdesc_num (fep );
1162+ if (entries_free >= fep -> tx_wake_threshold )
1163+ netif_wake_queue (ndev );
1164+ }
9681165 }
9691166 return ;
9701167}
@@ -2166,6 +2363,9 @@ static int fec_enet_init(struct net_device *ndev)
21662363 fep -> tx_ring_size = TX_RING_SIZE ;
21672364 fep -> rx_ring_size = RX_RING_SIZE ;
21682365
2366+ fep -> tx_stop_threshold = FEC_MAX_SKB_DESCS ;
2367+ fep -> tx_wake_threshold = (fep -> tx_ring_size - fep -> tx_stop_threshold ) / 2 ;
2368+
21692369 if (fep -> bufdesc_ex )
21702370 fep -> bufdesc_size = sizeof (struct bufdesc_ex );
21712371 else
@@ -2179,6 +2379,13 @@ static int fec_enet_init(struct net_device *ndev)
21792379 if (!cbd_base )
21802380 return - ENOMEM ;
21812381
2382+ fep -> tso_hdrs = dma_alloc_coherent (NULL , fep -> tx_ring_size * TSO_HEADER_SIZE ,
2383+ & fep -> tso_hdrs_dma , GFP_KERNEL );
2384+ if (!fep -> tso_hdrs ) {
2385+ dma_free_coherent (NULL , bd_size , cbd_base , fep -> bd_dma );
2386+ return - ENOMEM ;
2387+ }
2388+
21822389 memset (cbd_base , 0 , PAGE_SIZE );
21832390
21842391 fep -> netdev = ndev ;
@@ -2209,9 +2416,11 @@ static int fec_enet_init(struct net_device *ndev)
22092416 ndev -> features |= NETIF_F_HW_VLAN_CTAG_RX ;
22102417
22112418 if (id_entry -> driver_data & FEC_QUIRK_HAS_CSUM ) {
2419+ ndev -> gso_max_segs = FEC_MAX_TSO_SEGS ;
2420+
22122421 /* enable hw accelerator */
22132422 ndev -> features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM
2214- | NETIF_F_RXCSUM | NETIF_F_SG );
2423+ | NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO );
22152424 fep -> csum_flags |= FLAG_RX_CSUM_ENABLED ;
22162425 }
22172426
0 commit comments