aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/gianfar.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/gianfar.c')
-rw-r--r--drivers/net/gianfar.c48
1 files changed, 26 insertions, 22 deletions
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 9d81e7a48dba..6a38800be3f1 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -1239,19 +1239,9 @@ static int gfar_enet_open(struct net_device *dev)
1239 return err; 1239 return err;
1240} 1240}
1241 1241
1242static inline struct txfcb *gfar_add_fcb(struct sk_buff **skbp) 1242static inline struct txfcb *gfar_add_fcb(struct sk_buff *skb)
1243{ 1243{
1244 struct txfcb *fcb; 1244 struct txfcb *fcb = (struct txfcb *)skb_push(skb, GMAC_FCB_LEN);
1245 struct sk_buff *skb = *skbp;
1246
1247 if (unlikely(skb_headroom(skb) < GMAC_FCB_LEN)) {
1248 struct sk_buff *old_skb = skb;
1249 skb = skb_realloc_headroom(old_skb, GMAC_FCB_LEN);
1250 if (!skb)
1251 return NULL;
1252 dev_kfree_skb_any(old_skb);
1253 }
1254 fcb = (struct txfcb *)skb_push(skb, GMAC_FCB_LEN);
1255 cacheable_memzero(fcb, GMAC_FCB_LEN); 1245 cacheable_memzero(fcb, GMAC_FCB_LEN);
1256 1246
1257 return fcb; 1247 return fcb;
@@ -1320,6 +1310,22 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
1320 1310
1321 base = priv->tx_bd_base; 1311 base = priv->tx_bd_base;
1322 1312
1313 /* make space for additional header when fcb is needed */
1314 if (((skb->ip_summed == CHECKSUM_PARTIAL) ||
1315 (priv->vlgrp && vlan_tx_tag_present(skb))) &&
1316 (skb_headroom(skb) < GMAC_FCB_LEN)) {
1317 struct sk_buff *skb_new;
1318
1319 skb_new = skb_realloc_headroom(skb, GMAC_FCB_LEN);
1320 if (!skb_new) {
1321 dev->stats.tx_errors++;
1322 kfree_skb(skb);
1323 return NETDEV_TX_OK;
1324 }
1325 kfree_skb(skb);
1326 skb = skb_new;
1327 }
1328
1323 /* total number of fragments in the SKB */ 1329 /* total number of fragments in the SKB */
1324 nr_frags = skb_shinfo(skb)->nr_frags; 1330 nr_frags = skb_shinfo(skb)->nr_frags;
1325 1331
@@ -1372,20 +1378,18 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
1372 1378
1373 /* Set up checksumming */ 1379 /* Set up checksumming */
1374 if (CHECKSUM_PARTIAL == skb->ip_summed) { 1380 if (CHECKSUM_PARTIAL == skb->ip_summed) {
1375 fcb = gfar_add_fcb(&skb); 1381 fcb = gfar_add_fcb(skb);
1376 if (likely(fcb != NULL)) { 1382 lstatus |= BD_LFLAG(TXBD_TOE);
1377 lstatus |= BD_LFLAG(TXBD_TOE); 1383 gfar_tx_checksum(skb, fcb);
1378 gfar_tx_checksum(skb, fcb);
1379 }
1380 } 1384 }
1381 1385
1382 if (priv->vlgrp && vlan_tx_tag_present(skb)) { 1386 if (priv->vlgrp && vlan_tx_tag_present(skb)) {
1383 if (unlikely(NULL == fcb)) 1387 if (unlikely(NULL == fcb)) {
1384 fcb = gfar_add_fcb(&skb); 1388 fcb = gfar_add_fcb(skb);
1385 if (likely(fcb != NULL)) {
1386 lstatus |= BD_LFLAG(TXBD_TOE); 1389 lstatus |= BD_LFLAG(TXBD_TOE);
1387 gfar_tx_vlan(skb, fcb);
1388 } 1390 }
1391
1392 gfar_tx_vlan(skb, fcb);
1389 } 1393 }
1390 1394
1391 /* setup the TxBD length and buffer pointer for the first BD */ 1395 /* setup the TxBD length and buffer pointer for the first BD */
@@ -1433,7 +1437,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
1433 /* Unlock priv */ 1437 /* Unlock priv */
1434 spin_unlock_irqrestore(&priv->txlock, flags); 1438 spin_unlock_irqrestore(&priv->txlock, flags);
1435 1439
1436 return 0; 1440 return NETDEV_TX_OK;
1437} 1441}
1438 1442
1439/* Stops the kernel queue, and halts the controller */ 1443/* Stops the kernel queue, and halts the controller */