diff options
author | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-05-30 23:57:05 -0500 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-05-30 23:57:05 -0500 |
commit | 5bc65793cbf8da0d35f19ef025dda22887e79e80 (patch) | |
tree | 8291998abd73055de6f487fafa174ee2a5d3afee /drivers/net/sky2.c | |
parent | 6edae708bf77e012d855a7e2c7766f211d234f4f (diff) | |
parent | 3f0a6766e0cc5a577805732e5adb50a585c58175 (diff) |
[SCSI] Merge up to linux-2.6 head
Conflicts:
drivers/scsi/jazz_esp.c
Same changes made by both SCSI and SPARC trees: problem with UTF-8
conversion in the copyright.
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r-- | drivers/net/sky2.c | 75 |
1 files changed, 29 insertions, 46 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 104e20456e6..adfbe81693a 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -40,7 +40,6 @@ #include <linux/if_vlan.h> #include <linux/prefetch.h> #include <linux/mii.h> -#include <linux/dmi.h> #include <asm/irq.h> @@ -151,8 +150,6 @@ static const char *yukon2_name[] = { "FE", /* 0xb7 */ }; -static int dmi_blacklisted; - /* Access to external PHY */ static int gm_phy_write(struct sky2_hw *hw, unsigned port, u16 reg, u16 val) { @@ -307,10 +304,13 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) PHY_M_EC_MAC_S_MSK); ectrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ); + /* on PHY 88E1040 Rev.D0 (and newer) downshift control changed */ if (hw->chip_id == CHIP_ID_YUKON_EC) + /* set downshift counter to 3x and enable downshift */ ectrl |= PHY_M_EC_DSC_2(2) | PHY_M_EC_DOWN_S_ENA; else - ectrl |= PHY_M_EC_M_DSC(2) | PHY_M_EC_S_DSC(3); + /* set master & slave downshift counter to 1x */ + ectrl |= PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1); gm_phy_write(hw, port, PHY_MARV_EXT_CTRL, ectrl); } @@ -327,10 +327,12 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) /* enable automatic crossover */ ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO); + /* downshift on PHY 88E1112 and 88E1149 is changed */ if (sky2->autoneg == AUTONEG_ENABLE && (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX)) { + /* set downshift counter to 3x and enable downshift */ ctrl &= ~PHY_M_PC_DSC_MSK; ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA; } @@ -362,7 +364,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) /* for SFP-module set SIGDET polarity to low */ ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL); ctrl |= PHY_M_FIB_SIGD_POL; - gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl); + gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl); } gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); @@ -656,7 +658,7 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) const u8 *addr = hw->dev[port]->dev_addr; sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); - sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR|GPC_ENA_PAUSE); + sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR); sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR); @@ -842,10 +844,12 @@ static inline struct tx_ring_info *tx_le_re(struct sky2_port *sky2, /* Update chip's next pointer */ static inline void sky2_put_idx(struct sky2_hw *hw, unsigned q, u16 idx) { - q = Y2_QADDR(q, PREF_UNIT_PUT_IDX); + /* Make sure write' to descriptors are complete before we tell hardware */ wmb(); - sky2_write16(hw, q, idx); - sky2_read16(hw, q); + sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), idx); + + /* Synchronize I/O on since next processor may write to tail */ + mmiowb(); } @@ -977,6 +981,7 @@ stopped: /* reset the Rx prefetch unit */ sky2_write32(hw, Y2_QADDR(rxq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET); + mmiowb(); } /* Clean out receive buffer area, assumes receiver hardware stopped */ @@ -1196,7 +1201,7 @@ static int sky2_rx_start(struct sky2_port *sky2) } /* Tell chip about available buffers */ - sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put); + sky2_put_idx(hw, rxq, sky2->rx_put); return 0; nomem: sky2_rx_clean(sky2); @@ -1427,7 +1432,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) tcpsum = offset << 16; /* sum start */ tcpsum |= offset + skb->csum_offset; /* sum write */ - ctrl = CALSUM | WR_SUM | INIT_SUM | LOCK_SUM; + ctrl |= CALSUM | WR_SUM | INIT_SUM | LOCK_SUM; if (ip_hdr(skb)->protocol == IPPROTO_UDP) ctrl |= UDPTCP; @@ -1538,6 +1543,8 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done) } sky2->tx_cons = idx; + smp_mb(); + if (tx_avail(sky2) > MAX_SKB_TX_LE + 4) netif_wake_queue(dev); } @@ -1577,13 +1584,6 @@ static int sky2_down(struct net_device *dev) imask &= ~portirq_msk[port]; sky2_write32(hw, B0_IMSK, imask); - /* - * Both ports share the NAPI poll on port 0, so if necessary undo the - * the disable that is done in dev_close. - */ - if (sky2->port == 0 && hw->ports > 1) - netif_poll_enable(dev); - sky2_gmac_reset(hw, port); /* Stop transmitter */ @@ -2139,8 +2139,10 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) switch (le->opcode & ~HW_OWNER) { case OP_RXSTAT: skb = sky2_receive(dev, length, status); - if (!skb) + if (unlikely(!skb)) { + sky2->net_stats.rx_dropped++; goto force_update; + } skb->protocol = eth_type_trans(skb, dev); sky2->net_stats.rx_packets++; @@ -2221,6 +2223,7 @@ force_update: /* Fully processed status ring so clear irq */ sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); + mmiowb(); exit_loop: if (buf_write[0]) { @@ -2341,6 +2344,12 @@ static void sky2_mac_intr(struct sky2_hw *hw, unsigned port) printk(KERN_INFO PFX "%s: mac interrupt status 0x%x\n", dev->name, status); + if (status & GM_IS_RX_CO_OV) + gma_read16(hw, port, GM_RX_IRQ_SRC); + + if (status & GM_IS_TX_CO_OV) + gma_read16(hw, port, GM_TX_IRQ_SRC); + if (status & GM_IS_RX_FF_OR) { ++sky2->net_stats.rx_fifo_errors; sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_CLI_RX_FO); @@ -2439,6 +2448,7 @@ static int sky2_poll(struct net_device *dev0, int *budget) if (work_done < work_limit) { netif_rx_complete(dev0); + /* end of interrupt, re-enables also acts as I/O synchronization */ sky2_read32(hw, B0_Y2_SP_LISR); return 0; } else { @@ -2534,17 +2544,6 @@ static int __devinit sky2_init(struct sky2_hw *hw) return -EOPNOTSUPP; } - - /* Some Gigabyte motherboards have 88e8056 but cause problems - * There is some unresolved hardware related problem that causes - * descriptor errors and receive data corruption. - */ - if (hw->chip_id == CHIP_ID_YUKON_EC_U && dmi_blacklisted) { - dev_err(&hw->pdev->dev, - "88E8056 on this motherboard not supported\n"); - return -EOPNOTSUPP; - } - hw->pmd_type = sky2_read8(hw, B2_PMD_TYP); hw->ports = 1; t8 = sky2_read8(hw, B2_Y2_HW_RES); @@ -3910,24 +3909,8 @@ static struct pci_driver sky2_driver = { .shutdown = sky2_shutdown, }; -static struct dmi_system_id __initdata broken_dmi_table[] = { - { - .ident = "Gigabyte 965P-S3", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Gigabyte Technology Co., Ltd."), - DMI_MATCH(DMI_PRODUCT_NAME, "965P-S3"), - - }, - }, - { } -}; - static int __init sky2_init_module(void) { - /* Look for sick motherboards */ - if (dmi_check_system(broken_dmi_table)) - dmi_blacklisted = 1; - return pci_register_driver(&sky2_driver); } |