aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/oki-semi
diff options
context:
space:
mode:
authorAndy Cress <andycress@gmail.com>2012-07-26 02:00:11 -0400
committerDavid S. Miller <davem@davemloft.net>2012-07-26 17:30:23 -0400
commitf2c31662762b9e82b9891d6b385b17f9e5ef0ed2 (patch)
tree143048e8a3d4e8da0ede50187bcb761522afeb72 /drivers/net/ethernet/oki-semi
parent913f53e4c8a464c46a70898c88f2291ade28c196 (diff)
pch_gbe: add extra clean tx
This adds extra cleaning to the pch_gbe_clean_tx routine to avoid transmit timeouts on some BCM PHYs that have different timing. Also update the DRV_VERSION to 1.01, and show it. Signed-off-by: Andy Cress <andy.cress@us.kontron.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/oki-semi')
-rw-r--r--drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c57
1 files changed, 44 insertions, 13 deletions
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
index 99bba29e0553..1bb4cd14b149 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -26,7 +26,7 @@
26#include <linux/ptp_classify.h> 26#include <linux/ptp_classify.h>
27#endif 27#endif
28 28
29#define DRV_VERSION "1.00" 29#define DRV_VERSION "1.01"
30const char pch_driver_version[] = DRV_VERSION; 30const char pch_driver_version[] = DRV_VERSION;
31 31
32#define PCI_DEVICE_ID_INTEL_IOH1_GBE 0x8802 /* Pci device ID */ 32#define PCI_DEVICE_ID_INTEL_IOH1_GBE 0x8802 /* Pci device ID */
@@ -1579,7 +1579,8 @@ pch_gbe_clean_tx(struct pch_gbe_adapter *adapter,
1579 struct sk_buff *skb; 1579 struct sk_buff *skb;
1580 unsigned int i; 1580 unsigned int i;
1581 unsigned int cleaned_count = 0; 1581 unsigned int cleaned_count = 0;
1582 bool cleaned = true; 1582 bool cleaned = false;
1583 int unused, thresh;
1583 1584
1584 pr_debug("next_to_clean : %d\n", tx_ring->next_to_clean); 1585 pr_debug("next_to_clean : %d\n", tx_ring->next_to_clean);
1585 1586
@@ -1588,10 +1589,36 @@ pch_gbe_clean_tx(struct pch_gbe_adapter *adapter,
1588 pr_debug("gbec_status:0x%04x dma_status:0x%04x\n", 1589 pr_debug("gbec_status:0x%04x dma_status:0x%04x\n",
1589 tx_desc->gbec_status, tx_desc->dma_status); 1590 tx_desc->gbec_status, tx_desc->dma_status);
1590 1591
1592 unused = PCH_GBE_DESC_UNUSED(tx_ring);
1593 thresh = tx_ring->count - PCH_GBE_TX_WEIGHT;
1594 if ((tx_desc->gbec_status == DSC_INIT16) && (unused < thresh))
1595 { /* current marked clean, tx queue filling up, do extra clean */
1596 int j, k;
1597 if (unused < 8) { /* tx queue nearly full */
1598 pr_debug("clean_tx: transmit queue warning (%x,%x) unused=%d\n",
1599 tx_ring->next_to_clean,tx_ring->next_to_use,unused);
1600 }
1601
1602 /* current marked clean, scan for more that need cleaning. */
1603 k = i;
1604 for (j = 0; j < PCH_GBE_TX_WEIGHT; j++)
1605 {
1606 tx_desc = PCH_GBE_TX_DESC(*tx_ring, k);
1607 if (tx_desc->gbec_status != DSC_INIT16) break; /*found*/
1608 if (++k >= tx_ring->count) k = 0; /*increment, wrap*/
1609 }
1610 if (j < PCH_GBE_TX_WEIGHT) {
1611 pr_debug("clean_tx: unused=%d loops=%d found tx_desc[%x,%x:%x].gbec_status=%04x\n",
1612 unused,j, i,k, tx_ring->next_to_use, tx_desc->gbec_status);
1613 i = k; /*found one to clean, usu gbec_status==2000.*/
1614 }
1615 }
1616
1591 while ((tx_desc->gbec_status & DSC_INIT16) == 0x0000) { 1617 while ((tx_desc->gbec_status & DSC_INIT16) == 0x0000) {
1592 pr_debug("gbec_status:0x%04x\n", tx_desc->gbec_status); 1618 pr_debug("gbec_status:0x%04x\n", tx_desc->gbec_status);
1593 buffer_info = &tx_ring->buffer_info[i]; 1619 buffer_info = &tx_ring->buffer_info[i];
1594 skb = buffer_info->skb; 1620 skb = buffer_info->skb;
1621 cleaned = true;
1595 1622
1596 if ((tx_desc->gbec_status & PCH_GBE_TXD_GMAC_STAT_ABT)) { 1623 if ((tx_desc->gbec_status & PCH_GBE_TXD_GMAC_STAT_ABT)) {
1597 adapter->stats.tx_aborted_errors++; 1624 adapter->stats.tx_aborted_errors++;
@@ -1639,18 +1666,21 @@ pch_gbe_clean_tx(struct pch_gbe_adapter *adapter,
1639 } 1666 }
1640 pr_debug("called pch_gbe_unmap_and_free_tx_resource() %d count\n", 1667 pr_debug("called pch_gbe_unmap_and_free_tx_resource() %d count\n",
1641 cleaned_count); 1668 cleaned_count);
1642 /* Recover from running out of Tx resources in xmit_frame */ 1669 if (cleaned_count > 0) { /*skip this if nothing cleaned*/
1643 spin_lock(&tx_ring->tx_lock); 1670 /* Recover from running out of Tx resources in xmit_frame */
1644 if (unlikely(cleaned && (netif_queue_stopped(adapter->netdev)))) { 1671 spin_lock(&tx_ring->tx_lock);
1645 netif_wake_queue(adapter->netdev); 1672 if (unlikely(cleaned && (netif_queue_stopped(adapter->netdev))))
1646 adapter->stats.tx_restart_count++; 1673 {
1647 pr_debug("Tx wake queue\n"); 1674 netif_wake_queue(adapter->netdev);
1648 } 1675 adapter->stats.tx_restart_count++;
1676 pr_debug("Tx wake queue\n");
1677 }
1649 1678
1650 tx_ring->next_to_clean = i; 1679 tx_ring->next_to_clean = i;
1651 1680
1652 pr_debug("next_to_clean : %d\n", tx_ring->next_to_clean); 1681 pr_debug("next_to_clean : %d\n", tx_ring->next_to_clean);
1653 spin_unlock(&tx_ring->tx_lock); 1682 spin_unlock(&tx_ring->tx_lock);
1683 }
1654 return cleaned; 1684 return cleaned;
1655} 1685}
1656 1686
@@ -2389,7 +2419,7 @@ static int pch_gbe_napi_poll(struct napi_struct *napi, int budget)
2389 pch_gbe_clean_rx(adapter, adapter->rx_ring, &work_done, budget); 2419 pch_gbe_clean_rx(adapter, adapter->rx_ring, &work_done, budget);
2390 cleaned = pch_gbe_clean_tx(adapter, adapter->tx_ring); 2420 cleaned = pch_gbe_clean_tx(adapter, adapter->tx_ring);
2391 2421
2392 if (!cleaned) 2422 if (cleaned)
2393 work_done = budget; 2423 work_done = budget;
2394 /* If no Tx and not enough Rx work done, 2424 /* If no Tx and not enough Rx work done,
2395 * exit the polling mode 2425 * exit the polling mode
@@ -2795,6 +2825,7 @@ static int __init pch_gbe_init_module(void)
2795{ 2825{
2796 int ret; 2826 int ret;
2797 2827
2828 pr_info("EG20T PCH Gigabit Ethernet Driver - version %s\n",DRV_VERSION);
2798 ret = pci_register_driver(&pch_gbe_driver); 2829 ret = pci_register_driver(&pch_gbe_driver);
2799 if (copybreak != PCH_GBE_COPYBREAK_DEFAULT) { 2830 if (copybreak != PCH_GBE_COPYBREAK_DEFAULT) {
2800 if (copybreak == 0) { 2831 if (copybreak == 0) {