aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sky2.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r--drivers/net/sky2.c73
1 files changed, 48 insertions, 25 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 62be6d99d05c..959109609d85 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -51,7 +51,7 @@
51#include "sky2.h" 51#include "sky2.h"
52 52
53#define DRV_NAME "sky2" 53#define DRV_NAME "sky2"
54#define DRV_VERSION "1.3" 54#define DRV_VERSION "1.4"
55#define PFX DRV_NAME " " 55#define PFX DRV_NAME " "
56 56
57/* 57/*
@@ -105,6 +105,7 @@ MODULE_PARM_DESC(idle_timeout, "Idle timeout workaround for lost interrupts (ms)
105static const struct pci_device_id sky2_id_table[] = { 105static const struct pci_device_id sky2_id_table[] = {
106 { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, 106 { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) },
107 { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, 107 { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) },
108 { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) }, /* DGE-560T */
108 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) }, 109 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) },
109 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4341) }, 110 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4341) },
110 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4342) }, 111 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4342) },
@@ -235,6 +236,7 @@ static int sky2_set_power_state(struct sky2_hw *hw, pci_power_t state)
235 } 236 }
236 237
237 if (hw->chip_id == CHIP_ID_YUKON_EC_U) { 238 if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
239 sky2_write16(hw, B0_CTST, Y2_HW_WOL_ON);
238 sky2_pci_write32(hw, PCI_DEV_REG3, 0); 240 sky2_pci_write32(hw, PCI_DEV_REG3, 0);
239 reg1 = sky2_pci_read32(hw, PCI_DEV_REG4); 241 reg1 = sky2_pci_read32(hw, PCI_DEV_REG4);
240 reg1 &= P_ASPM_CONTROL_MSK; 242 reg1 &= P_ASPM_CONTROL_MSK;
@@ -306,7 +308,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
306 u16 ctrl, ct1000, adv, pg, ledctrl, ledover; 308 u16 ctrl, ct1000, adv, pg, ledctrl, ledover;
307 309
308 if (sky2->autoneg == AUTONEG_ENABLE && 310 if (sky2->autoneg == AUTONEG_ENABLE &&
309 (hw->chip_id != CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)) { 311 !(hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)) {
310 u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL); 312 u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
311 313
312 ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK | 314 ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
@@ -977,6 +979,7 @@ static int sky2_rx_start(struct sky2_port *sky2)
977 struct sky2_hw *hw = sky2->hw; 979 struct sky2_hw *hw = sky2->hw;
978 unsigned rxq = rxqaddr[sky2->port]; 980 unsigned rxq = rxqaddr[sky2->port];
979 int i; 981 int i;
982 unsigned thresh;
980 983
981 sky2->rx_put = sky2->rx_next = 0; 984 sky2->rx_put = sky2->rx_next = 0;
982 sky2_qset(hw, rxq); 985 sky2_qset(hw, rxq);
@@ -1001,9 +1004,21 @@ static int sky2_rx_start(struct sky2_port *sky2)
1001 sky2_rx_add(sky2, re->mapaddr); 1004 sky2_rx_add(sky2, re->mapaddr);
1002 } 1005 }
1003 1006
1004 /* Truncate oversize frames */ 1007
1005 sky2_write16(hw, SK_REG(sky2->port, RX_GMF_TR_THR), sky2->rx_bufsize - 8); 1008 /*
1006 sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_ON); 1009 * The receiver hangs if it receives frames larger than the
1010 * packet buffer. As a workaround, truncate oversize frames, but
1011 * the register is limited to 9 bits, so if you do frames > 2052
1012 * you better get the MTU right!
1013 */
1014 thresh = (sky2->rx_bufsize - 8) / sizeof(u32);
1015 if (thresh > 0x1ff)
1016 sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_OFF);
1017 else {
1018 sky2_write16(hw, SK_REG(sky2->port, RX_GMF_TR_THR), thresh);
1019 sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_ON);
1020 }
1021
1007 1022
1008 /* Tell chip about available buffers */ 1023 /* Tell chip about available buffers */
1009 sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put); 1024 sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put);
@@ -1020,19 +1035,26 @@ static int sky2_up(struct net_device *dev)
1020 struct sky2_hw *hw = sky2->hw; 1035 struct sky2_hw *hw = sky2->hw;
1021 unsigned port = sky2->port; 1036 unsigned port = sky2->port;
1022 u32 ramsize, rxspace, imask; 1037 u32 ramsize, rxspace, imask;
1023 int err; 1038 int cap, err = -ENOMEM;
1024 struct net_device *otherdev = hw->dev[sky2->port^1]; 1039 struct net_device *otherdev = hw->dev[sky2->port^1];
1025 1040
1026 /* Block bringing up both ports at the same time on a dual port card. 1041 /*
1027 * There is an unfixed bug where receiver gets confused and picks up 1042 * On dual port PCI-X card, there is an problem where status
1028 * packets out of order. Until this is fixed, prevent data corruption. 1043 * can be received out of order due to split transactions
1029 */ 1044 */
1030 if (otherdev && netif_running(otherdev)) { 1045 if (otherdev && netif_running(otherdev) &&
1031 printk(KERN_INFO PFX "dual port support is disabled.\n"); 1046 (cap = pci_find_capability(hw->pdev, PCI_CAP_ID_PCIX))) {
1032 return -EBUSY; 1047 struct sky2_port *osky2 = netdev_priv(otherdev);
1033 } 1048 u16 cmd;
1049
1050 cmd = sky2_pci_read16(hw, cap + PCI_X_CMD);
1051 cmd &= ~PCI_X_CMD_MAX_SPLIT;
1052 sky2_pci_write16(hw, cap + PCI_X_CMD, cmd);
1053
1054 sky2->rx_csum = 0;
1055 osky2->rx_csum = 0;
1056 }
1034 1057
1035 err = -ENOMEM;
1036 if (netif_msg_ifup(sky2)) 1058 if (netif_msg_ifup(sky2))
1037 printk(KERN_INFO PFX "%s: enabling interface\n", dev->name); 1059 printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
1038 1060
@@ -1910,6 +1932,12 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)
1910 } 1932 }
1911} 1933}
1912 1934
1935/* Is status ring empty or is there more to do? */
1936static inline int sky2_more_work(const struct sky2_hw *hw)
1937{
1938 return (hw->st_idx != sky2_read16(hw, STAT_PUT_IDX));
1939}
1940
1913/* Process status response ring */ 1941/* Process status response ring */
1914static int sky2_status_intr(struct sky2_hw *hw, int to_do) 1942static int sky2_status_intr(struct sky2_hw *hw, int to_do)
1915{ 1943{
@@ -2182,19 +2210,19 @@ static int sky2_poll(struct net_device *dev0, int *budget)
2182 if (status & Y2_IS_CHK_TXA2) 2210 if (status & Y2_IS_CHK_TXA2)
2183 sky2_descriptor_error(hw, 1, "transmit", Y2_IS_CHK_TXA2); 2211 sky2_descriptor_error(hw, 1, "transmit", Y2_IS_CHK_TXA2);
2184 2212
2185 if (status & Y2_IS_STAT_BMU)
2186 sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
2187
2188 work_done = sky2_status_intr(hw, work_limit); 2213 work_done = sky2_status_intr(hw, work_limit);
2189 *budget -= work_done; 2214 *budget -= work_done;
2190 dev0->quota -= work_done; 2215 dev0->quota -= work_done;
2191 2216
2192 if (work_done >= work_limit) 2217 if (status & Y2_IS_STAT_BMU)
2218 sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
2219
2220 if (sky2_more_work(hw))
2193 return 1; 2221 return 1;
2194 2222
2195 netif_rx_complete(dev0); 2223 netif_rx_complete(dev0);
2196 2224
2197 status = sky2_read32(hw, B0_Y2_SP_LISR); 2225 sky2_read32(hw, B0_Y2_SP_LISR);
2198 return 0; 2226 return 0;
2199} 2227}
2200 2228
@@ -3078,12 +3106,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
3078 sky2->duplex = -1; 3106 sky2->duplex = -1;
3079 sky2->speed = -1; 3107 sky2->speed = -1;
3080 sky2->advertising = sky2_supported_modes(hw); 3108 sky2->advertising = sky2_supported_modes(hw);
3081 3109 sky2->rx_csum = 1;
3082 /* Receive checksum disabled for Yukon XL
3083 * because of observed problems with incorrect
3084 * values when multiple packets are received in one interrupt
3085 */
3086 sky2->rx_csum = (hw->chip_id != CHIP_ID_YUKON_XL);
3087 3110
3088 spin_lock_init(&sky2->phy_lock); 3111 spin_lock_init(&sky2->phy_lock);
3089 sky2->tx_pending = TX_DEF_PENDING; 3112 sky2->tx_pending = TX_DEF_PENDING;