aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBrice Goglin <brice@myri.com>2006-12-11 05:25:42 -0500
committerJeff Garzik <jeff@garzik.org>2006-12-11 09:54:06 -0500
commitc7dab99b080accb2751c96bf66cd5ab12c78f8e4 (patch)
treee8d290ede4fe7b2ce85b5d36c0d644353179fc0e /drivers
parentdd50f3361f9f0bb407658e9087947c9bdcdefffc (diff)
[PATCH] myri10ge: switch to page-based skb
Switch to physical page skb, by calling the new page-based allocation routines and using myri10ge_page_rx_done(). Signed-off-by: Brice Goglin <brice@myri.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/myri10ge/myri10ge.c172
1 files changed, 93 insertions, 79 deletions
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 05b4f93518f5..4d2be9c59164 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -1264,13 +1264,13 @@ static inline void myri10ge_clean_rx_done(struct myri10ge_priv *mgp, int *limit)
1264 rx_done->entry[idx].length = 0; 1264 rx_done->entry[idx].length = 0;
1265 checksum = csum_unfold(rx_done->entry[idx].checksum); 1265 checksum = csum_unfold(rx_done->entry[idx].checksum);
1266 if (length <= mgp->small_bytes) 1266 if (length <= mgp->small_bytes)
1267 rx_ok = myri10ge_rx_done(mgp, &mgp->rx_small, 1267 rx_ok = myri10ge_page_rx_done(mgp, &mgp->rx_small,
1268 mgp->small_bytes, 1268 mgp->small_bytes,
1269 length, checksum); 1269 length, checksum);
1270 else 1270 else
1271 rx_ok = myri10ge_rx_done(mgp, &mgp->rx_big, 1271 rx_ok = myri10ge_page_rx_done(mgp, &mgp->rx_big,
1272 mgp->dev->mtu + ETH_HLEN, 1272 mgp->big_bytes,
1273 length, checksum); 1273 length, checksum);
1274 rx_packets += rx_ok; 1274 rx_packets += rx_ok;
1275 rx_bytes += rx_ok * (unsigned long)length; 1275 rx_bytes += rx_ok * (unsigned long)length;
1276 cnt++; 1276 cnt++;
@@ -1284,6 +1284,14 @@ static inline void myri10ge_clean_rx_done(struct myri10ge_priv *mgp, int *limit)
1284 rx_done->cnt = cnt; 1284 rx_done->cnt = cnt;
1285 mgp->stats.rx_packets += rx_packets; 1285 mgp->stats.rx_packets += rx_packets;
1286 mgp->stats.rx_bytes += rx_bytes; 1286 mgp->stats.rx_bytes += rx_bytes;
1287
1288 /* restock receive rings if needed */
1289 if (mgp->rx_small.fill_cnt - mgp->rx_small.cnt < myri10ge_fill_thresh)
1290 myri10ge_alloc_rx_pages(mgp, &mgp->rx_small,
1291 mgp->small_bytes + MXGEFW_PAD, 0);
1292 if (mgp->rx_big.fill_cnt - mgp->rx_big.cnt < myri10ge_fill_thresh)
1293 myri10ge_alloc_rx_pages(mgp, &mgp->rx_big, mgp->big_bytes, 0);
1294
1287} 1295}
1288 1296
1289static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp) 1297static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp)
@@ -1674,56 +1682,48 @@ static int myri10ge_allocate_rings(struct net_device *dev)
1674 goto abort_with_rx_small_info; 1682 goto abort_with_rx_small_info;
1675 1683
1676 /* Fill the receive rings */ 1684 /* Fill the receive rings */
1685 mgp->rx_big.cnt = 0;
1686 mgp->rx_small.cnt = 0;
1687 mgp->rx_big.fill_cnt = 0;
1688 mgp->rx_small.fill_cnt = 0;
1689 mgp->rx_small.page_offset = MYRI10GE_ALLOC_SIZE;
1690 mgp->rx_big.page_offset = MYRI10GE_ALLOC_SIZE;
1691 mgp->rx_small.watchdog_needed = 0;
1692 mgp->rx_big.watchdog_needed = 0;
1693 myri10ge_alloc_rx_pages(mgp, &mgp->rx_small,
1694 mgp->small_bytes + MXGEFW_PAD, 0);
1677 1695
1678 for (i = 0; i <= mgp->rx_small.mask; i++) { 1696 if (mgp->rx_small.fill_cnt < mgp->rx_small.mask + 1) {
1679 status = myri10ge_getbuf(&mgp->rx_small, mgp, 1697 printk(KERN_ERR "myri10ge: %s: alloced only %d small bufs\n",
1680 mgp->small_bytes, i); 1698 dev->name, mgp->rx_small.fill_cnt);
1681 if (status) { 1699 goto abort_with_rx_small_ring;
1682 printk(KERN_ERR
1683 "myri10ge: %s: alloced only %d small bufs\n",
1684 dev->name, i);
1685 goto abort_with_rx_small_ring;
1686 }
1687 } 1700 }
1688 1701
1689 for (i = 0; i <= mgp->rx_big.mask; i++) { 1702 myri10ge_alloc_rx_pages(mgp, &mgp->rx_big, mgp->big_bytes, 0);
1690 status = 1703 if (mgp->rx_big.fill_cnt < mgp->rx_big.mask + 1) {
1691 myri10ge_getbuf(&mgp->rx_big, mgp, dev->mtu + ETH_HLEN, i); 1704 printk(KERN_ERR "myri10ge: %s: alloced only %d big bufs\n",
1692 if (status) { 1705 dev->name, mgp->rx_big.fill_cnt);
1693 printk(KERN_ERR 1706 goto abort_with_rx_big_ring;
1694 "myri10ge: %s: alloced only %d big bufs\n",
1695 dev->name, i);
1696 goto abort_with_rx_big_ring;
1697 }
1698 } 1707 }
1699 1708
1700 return 0; 1709 return 0;
1701 1710
1702abort_with_rx_big_ring: 1711abort_with_rx_big_ring:
1703 for (i = 0; i <= mgp->rx_big.mask; i++) { 1712 for (i = mgp->rx_big.cnt; i < mgp->rx_big.fill_cnt; i++) {
1704 if (mgp->rx_big.info[i].skb != NULL) 1713 int idx = i & mgp->rx_big.mask;
1705 dev_kfree_skb_any(mgp->rx_big.info[i].skb); 1714 myri10ge_unmap_rx_page(mgp->pdev, &mgp->rx_big.info[idx],
1706 if (pci_unmap_len(&mgp->rx_big.info[i], len)) 1715 mgp->big_bytes);
1707 pci_unmap_single(mgp->pdev, 1716 put_page(mgp->rx_big.info[idx].page);
1708 pci_unmap_addr(&mgp->rx_big.info[i],
1709 bus),
1710 pci_unmap_len(&mgp->rx_big.info[i],
1711 len),
1712 PCI_DMA_FROMDEVICE);
1713 } 1717 }
1714 1718
1715abort_with_rx_small_ring: 1719abort_with_rx_small_ring:
1716 for (i = 0; i <= mgp->rx_small.mask; i++) { 1720 for (i = mgp->rx_small.cnt; i < mgp->rx_small.fill_cnt; i++) {
1717 if (mgp->rx_small.info[i].skb != NULL) 1721 int idx = i & mgp->rx_small.mask;
1718 dev_kfree_skb_any(mgp->rx_small.info[i].skb); 1722 myri10ge_unmap_rx_page(mgp->pdev, &mgp->rx_small.info[idx],
1719 if (pci_unmap_len(&mgp->rx_small.info[i], len)) 1723 mgp->small_bytes + MXGEFW_PAD);
1720 pci_unmap_single(mgp->pdev, 1724 put_page(mgp->rx_small.info[idx].page);
1721 pci_unmap_addr(&mgp->rx_small.info[i],
1722 bus),
1723 pci_unmap_len(&mgp->rx_small.info[i],
1724 len),
1725 PCI_DMA_FROMDEVICE);
1726 } 1725 }
1726
1727 kfree(mgp->rx_big.info); 1727 kfree(mgp->rx_big.info);
1728 1728
1729abort_with_rx_small_info: 1729abort_with_rx_small_info:
@@ -1756,30 +1756,24 @@ static void myri10ge_free_rings(struct net_device *dev)
1756 1756
1757 mgp = netdev_priv(dev); 1757 mgp = netdev_priv(dev);
1758 1758
1759 for (i = 0; i <= mgp->rx_big.mask; i++) { 1759 for (i = mgp->rx_big.cnt; i < mgp->rx_big.fill_cnt; i++) {
1760 if (mgp->rx_big.info[i].skb != NULL) 1760 idx = i & mgp->rx_big.mask;
1761 dev_kfree_skb_any(mgp->rx_big.info[i].skb); 1761 if (i == mgp->rx_big.fill_cnt - 1)
1762 if (pci_unmap_len(&mgp->rx_big.info[i], len)) 1762 mgp->rx_big.info[idx].page_offset = MYRI10GE_ALLOC_SIZE;
1763 pci_unmap_single(mgp->pdev, 1763 myri10ge_unmap_rx_page(mgp->pdev, &mgp->rx_big.info[idx],
1764 pci_unmap_addr(&mgp->rx_big.info[i], 1764 mgp->big_bytes);
1765 bus), 1765 put_page(mgp->rx_big.info[idx].page);
1766 pci_unmap_len(&mgp->rx_big.info[i],
1767 len),
1768 PCI_DMA_FROMDEVICE);
1769 }
1770
1771 for (i = 0; i <= mgp->rx_small.mask; i++) {
1772 if (mgp->rx_small.info[i].skb != NULL)
1773 dev_kfree_skb_any(mgp->rx_small.info[i].skb);
1774 if (pci_unmap_len(&mgp->rx_small.info[i], len))
1775 pci_unmap_single(mgp->pdev,
1776 pci_unmap_addr(&mgp->rx_small.info[i],
1777 bus),
1778 pci_unmap_len(&mgp->rx_small.info[i],
1779 len),
1780 PCI_DMA_FROMDEVICE);
1781 } 1766 }
1782 1767
1768 for (i = mgp->rx_small.cnt; i < mgp->rx_small.fill_cnt; i++) {
1769 idx = i & mgp->rx_small.mask;
1770 if (i == mgp->rx_small.fill_cnt - 1)
1771 mgp->rx_small.info[idx].page_offset =
1772 MYRI10GE_ALLOC_SIZE;
1773 myri10ge_unmap_rx_page(mgp->pdev, &mgp->rx_small.info[idx],
1774 mgp->small_bytes + MXGEFW_PAD);
1775 put_page(mgp->rx_small.info[idx].page);
1776 }
1783 tx = &mgp->tx; 1777 tx = &mgp->tx;
1784 while (tx->done != tx->req) { 1778 while (tx->done != tx->req) {
1785 idx = tx->done & tx->mask; 1779 idx = tx->done & tx->mask;
@@ -1847,19 +1841,18 @@ static int myri10ge_open(struct net_device *dev)
1847 */ 1841 */
1848 1842
1849 if (dev->mtu <= ETH_DATA_LEN) 1843 if (dev->mtu <= ETH_DATA_LEN)
1850 mgp->small_bytes = 128; /* enough for a TCP header */ 1844 /* enough for a TCP header */
1845 mgp->small_bytes = (128 > SMP_CACHE_BYTES)
1846 ? (128 - MXGEFW_PAD)
1847 : (SMP_CACHE_BYTES - MXGEFW_PAD);
1851 else 1848 else
1852 mgp->small_bytes = ETH_FRAME_LEN; /* enough for an ETH_DATA_LEN frame */ 1849 /* enough for an ETH_DATA_LEN frame */
1850 mgp->small_bytes = ETH_FRAME_LEN;
1853 1851
1854 /* Override the small buffer size? */ 1852 /* Override the small buffer size? */
1855 if (myri10ge_small_bytes > 0) 1853 if (myri10ge_small_bytes > 0)
1856 mgp->small_bytes = myri10ge_small_bytes; 1854 mgp->small_bytes = myri10ge_small_bytes;
1857 1855
1858 /* If the user sets an obscenely small MTU, adjust the small
1859 * bytes down to nearly nothing */
1860 if (mgp->small_bytes >= (dev->mtu + ETH_HLEN))
1861 mgp->small_bytes = 64;
1862
1863 /* get the lanai pointers to the send and receive rings */ 1856 /* get the lanai pointers to the send and receive rings */
1864 1857
1865 status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SEND_OFFSET, &cmd, 0); 1858 status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SEND_OFFSET, &cmd, 0);
@@ -1895,17 +1888,23 @@ static int myri10ge_open(struct net_device *dev)
1895 mgp->rx_big.wc_fifo = NULL; 1888 mgp->rx_big.wc_fifo = NULL;
1896 } 1889 }
1897 1890
1898 status = myri10ge_allocate_rings(dev);
1899 if (status != 0)
1900 goto abort_with_nothing;
1901
1902 /* Firmware needs the big buff size as a power of 2. Lie and 1891 /* Firmware needs the big buff size as a power of 2. Lie and
1903 * tell him the buffer is larger, because we only use 1 1892 * tell him the buffer is larger, because we only use 1
1904 * buffer/pkt, and the mtu will prevent overruns. 1893 * buffer/pkt, and the mtu will prevent overruns.
1905 */ 1894 */
1906 big_pow2 = dev->mtu + ETH_HLEN + MXGEFW_PAD; 1895 big_pow2 = dev->mtu + ETH_HLEN + MXGEFW_PAD;
1907 while ((big_pow2 & (big_pow2 - 1)) != 0) 1896 if (big_pow2 < MYRI10GE_ALLOC_SIZE / 2) {
1908 big_pow2++; 1897 while ((big_pow2 & (big_pow2 - 1)) != 0)
1898 big_pow2++;
1899 mgp->big_bytes = dev->mtu + ETH_HLEN + MXGEFW_PAD;
1900 } else {
1901 big_pow2 = MYRI10GE_ALLOC_SIZE;
1902 mgp->big_bytes = big_pow2;
1903 }
1904
1905 status = myri10ge_allocate_rings(dev);
1906 if (status != 0)
1907 goto abort_with_nothing;
1909 1908
1910 /* now give firmware buffers sizes, and MTU */ 1909 /* now give firmware buffers sizes, and MTU */
1911 cmd.data0 = dev->mtu + ETH_HLEN + VLAN_HLEN; 1910 cmd.data0 = dev->mtu + ETH_HLEN + VLAN_HLEN;
@@ -2888,6 +2887,21 @@ static void myri10ge_watchdog_timer(unsigned long arg)
2888 struct myri10ge_priv *mgp; 2887 struct myri10ge_priv *mgp;
2889 2888
2890 mgp = (struct myri10ge_priv *)arg; 2889 mgp = (struct myri10ge_priv *)arg;
2890
2891 if (mgp->rx_small.watchdog_needed) {
2892 myri10ge_alloc_rx_pages(mgp, &mgp->rx_small,
2893 mgp->small_bytes + MXGEFW_PAD, 1);
2894 if (mgp->rx_small.fill_cnt - mgp->rx_small.cnt >=
2895 myri10ge_fill_thresh)
2896 mgp->rx_small.watchdog_needed = 0;
2897 }
2898 if (mgp->rx_big.watchdog_needed) {
2899 myri10ge_alloc_rx_pages(mgp, &mgp->rx_big, mgp->big_bytes, 1);
2900 if (mgp->rx_big.fill_cnt - mgp->rx_big.cnt >=
2901 myri10ge_fill_thresh)
2902 mgp->rx_big.watchdog_needed = 0;
2903 }
2904
2891 if (mgp->tx.req != mgp->tx.done && 2905 if (mgp->tx.req != mgp->tx.done &&
2892 mgp->tx.done == mgp->watchdog_tx_done && 2906 mgp->tx.done == mgp->watchdog_tx_done &&
2893 mgp->watchdog_tx_req != mgp->watchdog_tx_done) 2907 mgp->watchdog_tx_req != mgp->watchdog_tx_done)