diff options
Diffstat (limited to 'drivers/net/ethernet/freescale/fec_main.c')
-rw-r--r-- | drivers/net/ethernet/freescale/fec_main.c | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 1c7a7e43dd9c..58cabee00abf 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c | |||
@@ -1189,12 +1189,13 @@ static void | |||
1189 | fec_enet_tx_queue(struct net_device *ndev, u16 queue_id) | 1189 | fec_enet_tx_queue(struct net_device *ndev, u16 queue_id) |
1190 | { | 1190 | { |
1191 | struct fec_enet_private *fep; | 1191 | struct fec_enet_private *fep; |
1192 | struct bufdesc *bdp; | 1192 | struct bufdesc *bdp, *bdp_t; |
1193 | unsigned short status; | 1193 | unsigned short status; |
1194 | struct sk_buff *skb; | 1194 | struct sk_buff *skb; |
1195 | struct fec_enet_priv_tx_q *txq; | 1195 | struct fec_enet_priv_tx_q *txq; |
1196 | struct netdev_queue *nq; | 1196 | struct netdev_queue *nq; |
1197 | int index = 0; | 1197 | int index = 0; |
1198 | int i, bdnum; | ||
1198 | int entries_free; | 1199 | int entries_free; |
1199 | 1200 | ||
1200 | fep = netdev_priv(ndev); | 1201 | fep = netdev_priv(ndev); |
@@ -1215,18 +1216,29 @@ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id) | |||
1215 | if (bdp == txq->cur_tx) | 1216 | if (bdp == txq->cur_tx) |
1216 | break; | 1217 | break; |
1217 | 1218 | ||
1218 | index = fec_enet_get_bd_index(txq->tx_bd_base, bdp, fep); | 1219 | bdp_t = bdp; |
1219 | 1220 | bdnum = 1; | |
1221 | index = fec_enet_get_bd_index(txq->tx_bd_base, bdp_t, fep); | ||
1220 | skb = txq->tx_skbuff[index]; | 1222 | skb = txq->tx_skbuff[index]; |
1221 | txq->tx_skbuff[index] = NULL; | 1223 | while (!skb) { |
1222 | if (!IS_TSO_HEADER(txq, bdp->cbd_bufaddr)) | 1224 | bdp_t = fec_enet_get_nextdesc(bdp_t, fep, queue_id); |
1223 | dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr, | 1225 | index = fec_enet_get_bd_index(txq->tx_bd_base, bdp_t, fep); |
1224 | bdp->cbd_datlen, DMA_TO_DEVICE); | 1226 | skb = txq->tx_skbuff[index]; |
1225 | bdp->cbd_bufaddr = 0; | 1227 | bdnum++; |
1226 | if (!skb) { | ||
1227 | bdp = fec_enet_get_nextdesc(bdp, fep, queue_id); | ||
1228 | continue; | ||
1229 | } | 1228 | } |
1229 | if (skb_shinfo(skb)->nr_frags && | ||
1230 | (status = bdp_t->cbd_sc) & BD_ENET_TX_READY) | ||
1231 | break; | ||
1232 | |||
1233 | for (i = 0; i < bdnum; i++) { | ||
1234 | if (!IS_TSO_HEADER(txq, bdp->cbd_bufaddr)) | ||
1235 | dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr, | ||
1236 | bdp->cbd_datlen, DMA_TO_DEVICE); | ||
1237 | bdp->cbd_bufaddr = 0; | ||
1238 | if (i < bdnum - 1) | ||
1239 | bdp = fec_enet_get_nextdesc(bdp, fep, queue_id); | ||
1240 | } | ||
1241 | txq->tx_skbuff[index] = NULL; | ||
1230 | 1242 | ||
1231 | /* Check for errors. */ | 1243 | /* Check for errors. */ |
1232 | if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC | | 1244 | if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC | |