aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sky2.c
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2006-05-20 00:26:26 -0400
committerJeff Garzik <jeff@garzik.org>2006-05-20 00:26:26 -0400
commit4e3ceac609cce39cb96e0eb8604934592371ed8c (patch)
tree019b674bf79489128b4f1985ea99c5deca2cb15b /drivers/net/sky2.c
parentbadc48e6605ddeeb2484afae5993c859494decaa (diff)
parentbb02aacc02c6002143a1cfc313d144a413eec8d0 (diff)
Merge branch 'upstream-fixes' into upstream
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r--drivers/net/sky2.c54
1 files changed, 32 insertions, 22 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 62be6d99d05c..60779ebf2ff6 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 |
@@ -1020,19 +1022,26 @@ static int sky2_up(struct net_device *dev)
1020 struct sky2_hw *hw = sky2->hw; 1022 struct sky2_hw *hw = sky2->hw;
1021 unsigned port = sky2->port; 1023 unsigned port = sky2->port;
1022 u32 ramsize, rxspace, imask; 1024 u32 ramsize, rxspace, imask;
1023 int err; 1025 int cap, err = -ENOMEM;
1024 struct net_device *otherdev = hw->dev[sky2->port^1]; 1026 struct net_device *otherdev = hw->dev[sky2->port^1];
1025 1027
1026 /* Block bringing up both ports at the same time on a dual port card. 1028 /*
1027 * There is an unfixed bug where receiver gets confused and picks up 1029 * On dual port PCI-X card, there is an problem where status
1028 * packets out of order. Until this is fixed, prevent data corruption. 1030 * can be received out of order due to split transactions
1029 */ 1031 */
1030 if (otherdev && netif_running(otherdev)) { 1032 if (otherdev && netif_running(otherdev) &&
1031 printk(KERN_INFO PFX "dual port support is disabled.\n"); 1033 (cap = pci_find_capability(hw->pdev, PCI_CAP_ID_PCIX))) {
1032 return -EBUSY; 1034 struct sky2_port *osky2 = netdev_priv(otherdev);
1033 } 1035 u16 cmd;
1036
1037 cmd = sky2_pci_read16(hw, cap + PCI_X_CMD);
1038 cmd &= ~PCI_X_CMD_MAX_SPLIT;
1039 sky2_pci_write16(hw, cap + PCI_X_CMD, cmd);
1040
1041 sky2->rx_csum = 0;
1042 osky2->rx_csum = 0;
1043 }
1034 1044
1035 err = -ENOMEM;
1036 if (netif_msg_ifup(sky2)) 1045 if (netif_msg_ifup(sky2))
1037 printk(KERN_INFO PFX "%s: enabling interface\n", dev->name); 1046 printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
1038 1047
@@ -1910,6 +1919,12 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)
1910 } 1919 }
1911} 1920}
1912 1921
1922/* Is status ring empty or is there more to do? */
1923static inline int sky2_more_work(const struct sky2_hw *hw)
1924{
1925 return (hw->st_idx != sky2_read16(hw, STAT_PUT_IDX));
1926}
1927
1913/* Process status response ring */ 1928/* Process status response ring */
1914static int sky2_status_intr(struct sky2_hw *hw, int to_do) 1929static int sky2_status_intr(struct sky2_hw *hw, int to_do)
1915{ 1930{
@@ -2182,19 +2197,19 @@ static int sky2_poll(struct net_device *dev0, int *budget)
2182 if (status & Y2_IS_CHK_TXA2) 2197 if (status & Y2_IS_CHK_TXA2)
2183 sky2_descriptor_error(hw, 1, "transmit", Y2_IS_CHK_TXA2); 2198 sky2_descriptor_error(hw, 1, "transmit", Y2_IS_CHK_TXA2);
2184 2199
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); 2200 work_done = sky2_status_intr(hw, work_limit);
2189 *budget -= work_done; 2201 *budget -= work_done;
2190 dev0->quota -= work_done; 2202 dev0->quota -= work_done;
2191 2203
2192 if (work_done >= work_limit) 2204 if (status & Y2_IS_STAT_BMU)
2205 sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
2206
2207 if (sky2_more_work(hw))
2193 return 1; 2208 return 1;
2194 2209
2195 netif_rx_complete(dev0); 2210 netif_rx_complete(dev0);
2196 2211
2197 status = sky2_read32(hw, B0_Y2_SP_LISR); 2212 sky2_read32(hw, B0_Y2_SP_LISR);
2198 return 0; 2213 return 0;
2199} 2214}
2200 2215
@@ -3078,12 +3093,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
3078 sky2->duplex = -1; 3093 sky2->duplex = -1;
3079 sky2->speed = -1; 3094 sky2->speed = -1;
3080 sky2->advertising = sky2_supported_modes(hw); 3095 sky2->advertising = sky2_supported_modes(hw);
3081 3096 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 3097
3088 spin_lock_init(&sky2->phy_lock); 3098 spin_lock_init(&sky2->phy_lock);
3089 sky2->tx_pending = TX_DEF_PENDING; 3099 sky2->tx_pending = TX_DEF_PENDING;