aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/nxp
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2012-06-12 19:58:16 -0400
committerDavid S. Miller <davem@davemloft.net>2012-06-17 19:28:32 -0400
commita7e2eaadd0edf6d71637c0d99aca404b0da8c1be (patch)
treefa4a711366c8e547e648c5e98ac89c5f1628ae19 /drivers/net/ethernet/nxp
parent79504d708d8be4131fbb115912521739c11db750 (diff)
net: lpc_eth: free skbs in start_xmit
Transmitted skbs can be freed immediately in lpc_eth_hard_start_xmit() instead of at TX completion, since driver copies the frames in DMA area. Signed-off-by: Eric Dumazet <edumazet@google.com> Tested-by: Roland Stigge <stigge@antcom.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/nxp')
-rw-r--r--drivers/net/ethernet/nxp/lpc_eth.c11
1 files changed, 5 insertions, 6 deletions
diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c
index 083d6715335c..028dde4d4979 100644
--- a/drivers/net/ethernet/nxp/lpc_eth.c
+++ b/drivers/net/ethernet/nxp/lpc_eth.c
@@ -440,7 +440,7 @@ struct netdata_local {
440 spinlock_t lock; 440 spinlock_t lock;
441 void __iomem *net_base; 441 void __iomem *net_base;
442 u32 msg_enable; 442 u32 msg_enable;
443 struct sk_buff *skb[ENET_TX_DESC]; 443 unsigned int skblen[ENET_TX_DESC];
444 unsigned int last_tx_idx; 444 unsigned int last_tx_idx;
445 unsigned int num_used_tx_buffs; 445 unsigned int num_used_tx_buffs;
446 struct mii_bus *mii_bus; 446 struct mii_bus *mii_bus;
@@ -903,12 +903,11 @@ err_out:
903static void __lpc_handle_xmit(struct net_device *ndev) 903static void __lpc_handle_xmit(struct net_device *ndev)
904{ 904{
905 struct netdata_local *pldat = netdev_priv(ndev); 905 struct netdata_local *pldat = netdev_priv(ndev);
906 struct sk_buff *skb;
907 u32 txcidx, *ptxstat, txstat; 906 u32 txcidx, *ptxstat, txstat;
908 907
909 txcidx = readl(LPC_ENET_TXCONSUMEINDEX(pldat->net_base)); 908 txcidx = readl(LPC_ENET_TXCONSUMEINDEX(pldat->net_base));
910 while (pldat->last_tx_idx != txcidx) { 909 while (pldat->last_tx_idx != txcidx) {
911 skb = pldat->skb[pldat->last_tx_idx]; 910 unsigned int skblen = pldat->skblen[pldat->last_tx_idx];
912 911
913 /* A buffer is available, get buffer status */ 912 /* A buffer is available, get buffer status */
914 ptxstat = &pldat->tx_stat_v[pldat->last_tx_idx]; 913 ptxstat = &pldat->tx_stat_v[pldat->last_tx_idx];
@@ -945,9 +944,8 @@ static void __lpc_handle_xmit(struct net_device *ndev)
945 } else { 944 } else {
946 /* Update stats */ 945 /* Update stats */
947 ndev->stats.tx_packets++; 946 ndev->stats.tx_packets++;
948 ndev->stats.tx_bytes += skb->len; 947 ndev->stats.tx_bytes += skblen;
949 } 948 }
950 dev_kfree_skb_irq(skb);
951 949
952 txcidx = readl(LPC_ENET_TXCONSUMEINDEX(pldat->net_base)); 950 txcidx = readl(LPC_ENET_TXCONSUMEINDEX(pldat->net_base));
953 } 951 }
@@ -1132,7 +1130,7 @@ static int lpc_eth_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1132 memcpy(pldat->tx_buff_v + txidx * ENET_MAXF_SIZE, skb->data, len); 1130 memcpy(pldat->tx_buff_v + txidx * ENET_MAXF_SIZE, skb->data, len);
1133 1131
1134 /* Save the buffer and increment the buffer counter */ 1132 /* Save the buffer and increment the buffer counter */
1135 pldat->skb[txidx] = skb; 1133 pldat->skblen[txidx] = len;
1136 pldat->num_used_tx_buffs++; 1134 pldat->num_used_tx_buffs++;
1137 1135
1138 /* Start transmit */ 1136 /* Start transmit */
@@ -1147,6 +1145,7 @@ static int lpc_eth_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1147 1145
1148 spin_unlock_irq(&pldat->lock); 1146 spin_unlock_irq(&pldat->lock);
1149 1147
1148 dev_kfree_skb(skb);
1150 return NETDEV_TX_OK; 1149 return NETDEV_TX_OK;
1151} 1150}
1152 1151