@@ -862,13 +862,10 @@ static void rswitch_tx_free(struct net_device *ndev)
862862 struct rswitch_ext_desc * desc ;
863863 struct sk_buff * skb ;
864864
865- for (; rswitch_get_num_cur_queues (gq ) > 0 ;
866- gq -> dirty = rswitch_next_queue_index (gq , false, 1 )) {
867- desc = & gq -> tx_ring [gq -> dirty ];
868- if ((desc -> desc .die_dt & DT_MASK ) != DT_FEMPTY )
869- break ;
870-
865+ desc = & gq -> tx_ring [gq -> dirty ];
866+ while ((desc -> desc .die_dt & DT_MASK ) == DT_FEMPTY ) {
871867 dma_rmb ();
868+
872869 skb = gq -> skbs [gq -> dirty ];
873870 if (skb ) {
874871 rdev -> ndev -> stats .tx_packets ++ ;
@@ -879,7 +876,10 @@ static void rswitch_tx_free(struct net_device *ndev)
879876 dev_kfree_skb_any (gq -> skbs [gq -> dirty ]);
880877 gq -> skbs [gq -> dirty ] = NULL ;
881878 }
879+
882880 desc -> desc .die_dt = DT_EEMPTY ;
881+ gq -> dirty = rswitch_next_queue_index (gq , false, 1 );
882+ desc = & gq -> tx_ring [gq -> dirty ];
883883 }
884884}
885885
@@ -1681,8 +1681,11 @@ static netdev_tx_t rswitch_start_xmit(struct sk_buff *skb, struct net_device *nd
16811681 if (dma_mapping_error (ndev -> dev .parent , dma_addr_orig ))
16821682 goto err_kfree ;
16831683
1684- gq -> skbs [gq -> cur ] = skb ;
1685- gq -> unmap_addrs [gq -> cur ] = dma_addr_orig ;
1684+ /* Stored the skb at the last descriptor to avoid skb free before hardware completes send */
1685+ gq -> skbs [(gq -> cur + nr_desc - 1 ) % gq -> ring_size ] = skb ;
1686+ gq -> unmap_addrs [(gq -> cur + nr_desc - 1 ) % gq -> ring_size ] = dma_addr_orig ;
1687+
1688+ dma_wmb ();
16861689
16871690 /* DT_FSTART should be set at last. So, this is reverse order. */
16881691 for (i = nr_desc ; i -- > 0 ; ) {
@@ -1694,14 +1697,13 @@ static netdev_tx_t rswitch_start_xmit(struct sk_buff *skb, struct net_device *nd
16941697 goto err_unmap ;
16951698 }
16961699
1697- wmb (); /* gq->cur must be incremented after die_dt was set */
1698-
16991700 gq -> cur = rswitch_next_queue_index (gq , true, nr_desc );
17001701 rswitch_modify (rdev -> addr , GWTRC (gq -> index ), 0 , BIT (gq -> index % 32 ));
17011702
17021703 return ret ;
17031704
17041705err_unmap :
1706+ gq -> skbs [(gq -> cur + nr_desc - 1 ) % gq -> ring_size ] = NULL ;
17051707 dma_unmap_single (ndev -> dev .parent , dma_addr_orig , skb -> len , DMA_TO_DEVICE );
17061708
17071709err_kfree :
@@ -1889,7 +1891,6 @@ static int rswitch_device_alloc(struct rswitch_private *priv, unsigned int index
18891891 rdev -> np_port = rswitch_get_port_node (rdev );
18901892 rdev -> disabled = !rdev -> np_port ;
18911893 err = of_get_ethdev_address (rdev -> np_port , ndev );
1892- of_node_put (rdev -> np_port );
18931894 if (err ) {
18941895 if (is_valid_ether_addr (rdev -> etha -> mac_addr ))
18951896 eth_hw_addr_set (ndev , rdev -> etha -> mac_addr );
@@ -1919,6 +1920,7 @@ static int rswitch_device_alloc(struct rswitch_private *priv, unsigned int index
19191920
19201921out_rxdmac :
19211922out_get_params :
1923+ of_node_put (rdev -> np_port );
19221924 netif_napi_del (& rdev -> napi );
19231925 free_netdev (ndev );
19241926
@@ -1932,6 +1934,7 @@ static void rswitch_device_free(struct rswitch_private *priv, unsigned int index
19321934
19331935 rswitch_txdmac_free (ndev );
19341936 rswitch_rxdmac_free (ndev );
1937+ of_node_put (rdev -> np_port );
19351938 netif_napi_del (& rdev -> napi );
19361939 free_netdev (ndev );
19371940}
0 commit comments