Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gianfar: Add Scatter Gather support

Scatter Gather support in gianfar driver to handle fragmented frames on
the transmit side.

Signed-off-by: Poonam Aggrwal <poonam.aggrwal@freescale.com>
Signed-off-by: Dai Haruki <dai.haruki@freescale.com>
Signed-off-by: Andy Fleming <afleming@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Dai Haruki and committed by
David S. Miller
4669bc90 8882d9a6

+153 -75
+150 -75
drivers/net/gianfar.c
··· 368 368 369 369 if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) { 370 370 priv->rx_csum_enable = 1; 371 - dev->features |= NETIF_F_IP_CSUM; 371 + dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_HIGHDMA; 372 372 } else 373 373 priv->rx_csum_enable = 0; 374 374 ··· 426 426 priv->rx_buffer_size = DEFAULT_RX_BUFFER_SIZE; 427 427 priv->tx_ring_size = DEFAULT_TX_RING_SIZE; 428 428 priv->rx_ring_size = DEFAULT_RX_RING_SIZE; 429 + priv->num_txbdfree = DEFAULT_TX_RING_SIZE; 429 430 430 431 priv->txcoalescing = DEFAULT_TX_COALESCE; 431 432 priv->txic = DEFAULT_TXIC; ··· 820 819 { 821 820 struct rxbd8 *rxbdp; 822 821 struct txbd8 *txbdp; 823 - int i; 822 + int i, j; 824 823 825 824 /* Go through all the buffer descriptors and free their data buffers */ 826 825 txbdp = priv->tx_bd_base; 827 826 828 827 for (i = 0; i < priv->tx_ring_size; i++) { 828 + if (!priv->tx_skbuff[i]) 829 + continue; 829 830 830 - if (priv->tx_skbuff[i]) { 831 - dma_unmap_single(&priv->dev->dev, txbdp->bufPtr, 832 - txbdp->length, 833 - DMA_TO_DEVICE); 834 - dev_kfree_skb_any(priv->tx_skbuff[i]); 835 - priv->tx_skbuff[i] = NULL; 831 + dma_unmap_single(&priv->dev->dev, txbdp->bufPtr, 832 + txbdp->length, DMA_TO_DEVICE); 833 + txbdp->lstatus = 0; 834 + for (j = 0; j < skb_shinfo(priv->tx_skbuff[i])->nr_frags; j++) { 835 + txbdp++; 836 + dma_unmap_page(&priv->dev->dev, txbdp->bufPtr, 837 + txbdp->length, DMA_TO_DEVICE); 836 838 } 837 - 838 839 txbdp++; 840 + dev_kfree_skb_any(priv->tx_skbuff[i]); 841 + priv->tx_skbuff[i] = NULL; 839 842 } 840 843 841 844 kfree(priv->tx_skbuff); ··· 972 967 priv->rx_skbuff[i] = NULL; 973 968 974 969 /* Initialize some variables in our dev structure */ 970 + priv->num_txbdfree = priv->tx_ring_size; 975 971 priv->dirty_tx = priv->cur_tx = priv->tx_bd_base; 976 972 priv->cur_rx = priv->rx_bd_base; 977 973 priv->skb_curtx = priv->skb_dirtytx = 0; ··· 1213 1207 fcb->vlctl = vlan_tx_tag_get(skb); 1214 1208 } 1215 1209 1210 + static inline struct txbd8 *skip_txbd(struct txbd8 *bdp, int stride, 1211 + struct txbd8 *base, int ring_size) 1212 + { 1213 + struct txbd8 *new_bd = bdp + stride; 1214 + 1215 + return (new_bd >= (base + ring_size)) ? (new_bd - ring_size) : new_bd; 1216 + } 1217 + 1218 + static inline struct txbd8 *next_txbd(struct txbd8 *bdp, struct txbd8 *base, 1219 + int ring_size) 1220 + { 1221 + return skip_txbd(bdp, 1, base, ring_size); 1222 + } 1223 + 1216 1224 /* This is called by the kernel when a frame is ready for transmission. */ 1217 1225 /* It is pointed to by the dev->hard_start_xmit function pointer */ 1218 1226 static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) 1219 1227 { 1220 1228 struct gfar_private *priv = netdev_priv(dev); 1221 1229 struct txfcb *fcb = NULL; 1222 - struct txbd8 *txbdp, *base; 1230 + struct txbd8 *txbdp, *txbdp_start, *base; 1223 1231 u32 lstatus; 1232 + int i; 1233 + u32 bufaddr; 1224 1234 unsigned long flags; 1235 + unsigned int nr_frags, length; 1236 + 1237 + base = priv->tx_bd_base; 1238 + 1239 + /* total number of fragments in the SKB */ 1240 + nr_frags = skb_shinfo(skb)->nr_frags; 1241 + 1242 + spin_lock_irqsave(&priv->txlock, flags); 1243 + 1244 + /* check if there is space to queue this packet */ 1245 + if (nr_frags > priv->num_txbdfree) { 1246 + /* no space, stop the queue */ 1247 + netif_stop_queue(dev); 1248 + dev->stats.tx_fifo_errors++; 1249 + spin_unlock_irqrestore(&priv->txlock, flags); 1250 + return NETDEV_TX_BUSY; 1251 + } 1225 1252 1226 1253 /* Update transmit stats */ 1227 1254 dev->stats.tx_bytes += skb->len; 1228 1255 1229 - /* Lock priv now */ 1230 - spin_lock_irqsave(&priv->txlock, flags); 1256 + txbdp = txbdp_start = priv->cur_tx; 1231 1257 1232 - /* Point at the first free tx descriptor */ 1233 - txbdp = priv->cur_tx; 1234 - base = priv->tx_bd_base; 1258 + if (nr_frags == 0) { 1259 + lstatus = txbdp->lstatus | BD_LFLAG(TXBD_LAST | TXBD_INTERRUPT); 1260 + } else { 1261 + /* Place the fragment addresses and lengths into the TxBDs */ 1262 + for (i = 0; i < nr_frags; i++) { 1263 + /* Point at the next BD, wrapping as needed */ 1264 + txbdp = next_txbd(txbdp, base, priv->tx_ring_size); 1235 1265 1236 - /* Clear all but the WRAP status flags */ 1237 - lstatus = txbdp->lstatus & BD_LFLAG(TXBD_WRAP); 1266 + length = skb_shinfo(skb)->frags[i].size; 1267 + 1268 + lstatus = txbdp->lstatus | length | 1269 + BD_LFLAG(TXBD_READY); 1270 + 1271 + /* Handle the last BD specially */ 1272 + if (i == nr_frags - 1) 1273 + lstatus |= BD_LFLAG(TXBD_LAST | TXBD_INTERRUPT); 1274 + 1275 + bufaddr = dma_map_page(&dev->dev, 1276 + skb_shinfo(skb)->frags[i].page, 1277 + skb_shinfo(skb)->frags[i].page_offset, 1278 + length, 1279 + DMA_TO_DEVICE); 1280 + 1281 + /* set the TxBD length and buffer pointer */ 1282 + txbdp->bufPtr = bufaddr; 1283 + txbdp->lstatus = lstatus; 1284 + } 1285 + 1286 + lstatus = txbdp_start->lstatus; 1287 + } 1238 1288 1239 1289 /* Set up checksumming */ 1240 1290 if (CHECKSUM_PARTIAL == skb->ip_summed) { ··· 1308 1246 gfar_tx_vlan(skb, fcb); 1309 1247 } 1310 1248 1311 - /* Set buffer length and pointer */ 1312 - txbdp->bufPtr = dma_map_single(&dev->dev, skb->data, 1313 - skb->len, DMA_TO_DEVICE); 1314 - 1315 - /* Save the skb pointer so we can free it later */ 1249 + /* setup the TxBD length and buffer pointer for the first BD */ 1316 1250 priv->tx_skbuff[priv->skb_curtx] = skb; 1251 + txbdp_start->bufPtr = dma_map_single(&dev->dev, skb->data, 1252 + skb_headlen(skb), DMA_TO_DEVICE); 1317 1253 1318 - /* Update the current skb pointer (wrapping if this was the last) */ 1319 - priv->skb_curtx = 1320 - (priv->skb_curtx + 1) & TX_RING_MOD_MASK(priv->tx_ring_size); 1254 + lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | skb_headlen(skb); 1321 1255 1322 - /* Flag the BD as ready, interrupt-causing, last, and in need of CRC */ 1323 - lstatus |= 1324 - BD_LFLAG(TXBD_READY | TXBD_LAST | TXBD_CRC | TXBD_INTERRUPT) | 1325 - skb->len; 1326 - 1327 - dev->trans_start = jiffies; 1328 - 1329 - /* The powerpc-specific eieio() is used, as wmb() has too strong 1256 + /* 1257 + * The powerpc-specific eieio() is used, as wmb() has too strong 1330 1258 * semantics (it requires synchronization between cacheable and 1331 1259 * uncacheable mappings, which eieio doesn't provide and which we 1332 1260 * don't need), thus requiring a more expensive sync instruction. At 1333 1261 * some point, the set of architecture-independent barrier functions 1334 1262 * should be expanded to include weaker barriers. 1335 1263 */ 1336 - 1337 1264 eieio(); 1338 - txbdp->lstatus = lstatus; 1339 1265 1340 - txbdp = next_bd(txbdp, base, priv->tx_ring_size); 1266 + txbdp_start->lstatus = lstatus; 1267 + 1268 + /* Update the current skb pointer to the next entry we will use 1269 + * (wrapping if necessary) */ 1270 + priv->skb_curtx = (priv->skb_curtx + 1) & 1271 + TX_RING_MOD_MASK(priv->tx_ring_size); 1272 + 1273 + priv->cur_tx = next_txbd(txbdp, base, priv->tx_ring_size); 1274 + 1275 + /* reduce TxBD free count */ 1276 + priv->num_txbdfree -= (nr_frags + 1); 1277 + 1278 + dev->trans_start = jiffies; 1341 1279 1342 1280 /* If the next BD still needs to be cleaned up, then the bds 1343 1281 are full. We need to tell the kernel to stop sending us stuff. */ 1344 - if (txbdp == priv->dirty_tx) { 1282 + if (!priv->num_txbdfree) { 1345 1283 netif_stop_queue(dev); 1346 1284 1347 1285 dev->stats.tx_fifo_errors++; 1348 1286 } 1349 - 1350 - /* Update the current txbd to the next one */ 1351 - priv->cur_tx = txbdp; 1352 1287 1353 1288 /* Tell the DMA to go go go */ 1354 1289 gfar_write(&priv->regs->tstat, TSTAT_CLEAR_THALT); ··· 1520 1461 /* Interrupt Handler for Transmit complete */ 1521 1462 static int gfar_clean_tx_ring(struct net_device *dev) 1522 1463 { 1523 - struct txbd8 *bdp, *base; 1524 1464 struct gfar_private *priv = netdev_priv(dev); 1465 + struct txbd8 *bdp; 1466 + struct txbd8 *lbdp = NULL; 1467 + struct txbd8 *base = priv->tx_bd_base; 1468 + struct sk_buff *skb; 1469 + int skb_dirtytx; 1470 + int tx_ring_size = priv->tx_ring_size; 1471 + int frags = 0; 1472 + int i; 1525 1473 int howmany = 0; 1474 + u32 lstatus; 1526 1475 1527 1476 bdp = priv->dirty_tx; 1528 - base = priv->tx_bd_base; 1529 - while ((bdp->status & TXBD_READY) == 0) { 1530 - /* If dirty_tx and cur_tx are the same, then either the */ 1531 - /* ring is empty or full now (it could only be full in the beginning, */ 1532 - /* obviously). If it is empty, we are done. */ 1533 - if ((bdp == priv->cur_tx) && (netif_queue_stopped(dev) == 0)) 1477 + skb_dirtytx = priv->skb_dirtytx; 1478 + 1479 + while ((skb = priv->tx_skbuff[skb_dirtytx])) { 1480 + frags = skb_shinfo(skb)->nr_frags; 1481 + lbdp = skip_txbd(bdp, frags, base, tx_ring_size); 1482 + 1483 + lstatus = lbdp->lstatus; 1484 + 1485 + /* Only clean completed frames */ 1486 + if ((lstatus & BD_LFLAG(TXBD_READY)) && 1487 + (lstatus & BD_LENGTH_MASK)) 1534 1488 break; 1535 1489 1490 + dma_unmap_single(&dev->dev, 1491 + bdp->bufPtr, 1492 + bdp->length, 1493 + DMA_TO_DEVICE); 1494 + 1495 + bdp->lstatus &= BD_LFLAG(TXBD_WRAP); 1496 + bdp = next_txbd(bdp, base, tx_ring_size); 1497 + 1498 + for (i = 0; i < frags; i++) { 1499 + dma_unmap_page(&dev->dev, 1500 + bdp->bufPtr, 1501 + bdp->length, 1502 + DMA_TO_DEVICE); 1503 + bdp->lstatus &= BD_LFLAG(TXBD_WRAP); 1504 + bdp = next_txbd(bdp, base, tx_ring_size); 1505 + } 1506 + 1507 + dev_kfree_skb_any(skb); 1508 + priv->tx_skbuff[skb_dirtytx] = NULL; 1509 + 1510 + skb_dirtytx = (skb_dirtytx + 1) & 1511 + TX_RING_MOD_MASK(tx_ring_size); 1512 + 1536 1513 howmany++; 1514 + priv->num_txbdfree += frags + 1; 1515 + } 1537 1516 1538 - /* Deferred means some collisions occurred during transmit, */ 1539 - /* but we eventually sent the packet. */ 1540 - if (bdp->status & TXBD_DEF) 1541 - dev->stats.collisions++; 1517 + /* If we freed a buffer, we can restart transmission, if necessary */ 1518 + if (netif_queue_stopped(dev) && priv->num_txbdfree) 1519 + netif_wake_queue(dev); 1542 1520 1543 - /* Unmap the DMA memory */ 1544 - dma_unmap_single(&priv->dev->dev, bdp->bufPtr, 1545 - bdp->length, DMA_TO_DEVICE); 1546 - 1547 - /* Free the sk buffer associated with this TxBD */ 1548 - dev_kfree_skb_irq(priv->tx_skbuff[priv->skb_dirtytx]); 1549 - 1550 - priv->tx_skbuff[priv->skb_dirtytx] = NULL; 1551 - priv->skb_dirtytx = 1552 - (priv->skb_dirtytx + 1553 - 1) & TX_RING_MOD_MASK(priv->tx_ring_size); 1554 - 1555 - /* Clean BD length for empty detection */ 1556 - bdp->length = 0; 1557 - 1558 - bdp = next_bd(bdp, base, priv->tx_ring_size); 1559 - 1560 - /* Move dirty_tx to be the next bd */ 1561 - priv->dirty_tx = bdp; 1562 - 1563 - /* We freed a buffer, so now we can restart transmission */ 1564 - if (netif_queue_stopped(dev)) 1565 - netif_wake_queue(dev); 1566 - } /* while ((bdp->status & TXBD_READY) == 0) */ 1521 + /* Update dirty indicators */ 1522 + priv->skb_dirtytx = skb_dirtytx; 1523 + priv->dirty_tx = bdp; 1567 1524 1568 1525 dev->stats.tx_packets += howmany; 1569 1526
+1
drivers/net/gianfar.h
··· 728 728 struct txbd8 *dirty_tx; /* First buffer in line 729 729 to be transmitted */ 730 730 unsigned int tx_ring_size; 731 + unsigned int num_txbdfree; /* number of TxBDs free */ 731 732 732 733 /* RX Locked fields */ 733 734 spinlock_t rxlock;
+2
drivers/net/gianfar_ethtool.c
··· 475 475 /* Change the size */ 476 476 priv->rx_ring_size = rvals->rx_pending; 477 477 priv->tx_ring_size = rvals->tx_pending; 478 + priv->num_txbdfree = priv->tx_ring_size; 478 479 479 480 /* Rebuild the rings with the new size */ 480 481 if (dev->flags & IFF_UP) { ··· 624 623 .get_tx_csum = gfar_get_tx_csum, 625 624 .set_rx_csum = gfar_set_rx_csum, 626 625 .set_tx_csum = gfar_set_tx_csum, 626 + .set_sg = ethtool_op_set_sg, 627 627 .get_msglevel = gfar_get_msglevel, 628 628 .set_msglevel = gfar_set_msglevel, 629 629 #ifdef CONFIG_PM