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.c75
1 files changed, 29 insertions, 46 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 104e20456e6f..adfbe81693a6 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -40,7 +40,6 @@
40#include <linux/if_vlan.h> 40#include <linux/if_vlan.h>
41#include <linux/prefetch.h> 41#include <linux/prefetch.h>
42#include <linux/mii.h> 42#include <linux/mii.h>
43#include <linux/dmi.h>
44 43
45#include <asm/irq.h> 44#include <asm/irq.h>
46 45
@@ -151,8 +150,6 @@ static const char *yukon2_name[] = {
151 "FE", /* 0xb7 */ 150 "FE", /* 0xb7 */
152}; 151};
153 152
154static int dmi_blacklisted;
155
156/* Access to external PHY */ 153/* Access to external PHY */
157static int gm_phy_write(struct sky2_hw *hw, unsigned port, u16 reg, u16 val) 154static int gm_phy_write(struct sky2_hw *hw, unsigned port, u16 reg, u16 val)
158{ 155{
@@ -307,10 +304,13 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
307 PHY_M_EC_MAC_S_MSK); 304 PHY_M_EC_MAC_S_MSK);
308 ectrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ); 305 ectrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ);
309 306
307 /* on PHY 88E1040 Rev.D0 (and newer) downshift control changed */
310 if (hw->chip_id == CHIP_ID_YUKON_EC) 308 if (hw->chip_id == CHIP_ID_YUKON_EC)
309 /* set downshift counter to 3x and enable downshift */
311 ectrl |= PHY_M_EC_DSC_2(2) | PHY_M_EC_DOWN_S_ENA; 310 ectrl |= PHY_M_EC_DSC_2(2) | PHY_M_EC_DOWN_S_ENA;
312 else 311 else
313 ectrl |= PHY_M_EC_M_DSC(2) | PHY_M_EC_S_DSC(3); 312 /* set master & slave downshift counter to 1x */
313 ectrl |= PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1);
314 314
315 gm_phy_write(hw, port, PHY_MARV_EXT_CTRL, ectrl); 315 gm_phy_write(hw, port, PHY_MARV_EXT_CTRL, ectrl);
316 } 316 }
@@ -327,10 +327,12 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
327 /* enable automatic crossover */ 327 /* enable automatic crossover */
328 ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO); 328 ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO);
329 329
330 /* downshift on PHY 88E1112 and 88E1149 is changed */
330 if (sky2->autoneg == AUTONEG_ENABLE 331 if (sky2->autoneg == AUTONEG_ENABLE
331 && (hw->chip_id == CHIP_ID_YUKON_XL 332 && (hw->chip_id == CHIP_ID_YUKON_XL
332 || hw->chip_id == CHIP_ID_YUKON_EC_U 333 || hw->chip_id == CHIP_ID_YUKON_EC_U
333 || hw->chip_id == CHIP_ID_YUKON_EX)) { 334 || hw->chip_id == CHIP_ID_YUKON_EX)) {
335 /* set downshift counter to 3x and enable downshift */
334 ctrl &= ~PHY_M_PC_DSC_MSK; 336 ctrl &= ~PHY_M_PC_DSC_MSK;
335 ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA; 337 ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA;
336 } 338 }
@@ -362,7 +364,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
362 /* for SFP-module set SIGDET polarity to low */ 364 /* for SFP-module set SIGDET polarity to low */
363 ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL); 365 ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
364 ctrl |= PHY_M_FIB_SIGD_POL; 366 ctrl |= PHY_M_FIB_SIGD_POL;
365 gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl); 367 gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
366 } 368 }
367 369
368 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); 370 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)
656 const u8 *addr = hw->dev[port]->dev_addr; 658 const u8 *addr = hw->dev[port]->dev_addr;
657 659
658 sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); 660 sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
659 sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR|GPC_ENA_PAUSE); 661 sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR);
660 662
661 sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR); 663 sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR);
662 664
@@ -842,10 +844,12 @@ static inline struct tx_ring_info *tx_le_re(struct sky2_port *sky2,
842/* Update chip's next pointer */ 844/* Update chip's next pointer */
843static inline void sky2_put_idx(struct sky2_hw *hw, unsigned q, u16 idx) 845static inline void sky2_put_idx(struct sky2_hw *hw, unsigned q, u16 idx)
844{ 846{
845 q = Y2_QADDR(q, PREF_UNIT_PUT_IDX); 847 /* Make sure write' to descriptors are complete before we tell hardware */
846 wmb(); 848 wmb();
847 sky2_write16(hw, q, idx); 849 sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), idx);
848 sky2_read16(hw, q); 850
851 /* Synchronize I/O on since next processor may write to tail */
852 mmiowb();
849} 853}
850 854
851 855
@@ -977,6 +981,7 @@ stopped:
977 981
978 /* reset the Rx prefetch unit */ 982 /* reset the Rx prefetch unit */
979 sky2_write32(hw, Y2_QADDR(rxq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET); 983 sky2_write32(hw, Y2_QADDR(rxq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
984 mmiowb();
980} 985}
981 986
982/* Clean out receive buffer area, assumes receiver hardware stopped */ 987/* Clean out receive buffer area, assumes receiver hardware stopped */
@@ -1196,7 +1201,7 @@ static int sky2_rx_start(struct sky2_port *sky2)
1196 } 1201 }
1197 1202
1198 /* Tell chip about available buffers */ 1203 /* Tell chip about available buffers */
1199 sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put); 1204 sky2_put_idx(hw, rxq, sky2->rx_put);
1200 return 0; 1205 return 0;
1201nomem: 1206nomem:
1202 sky2_rx_clean(sky2); 1207 sky2_rx_clean(sky2);
@@ -1427,7 +1432,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1427 tcpsum = offset << 16; /* sum start */ 1432 tcpsum = offset << 16; /* sum start */
1428 tcpsum |= offset + skb->csum_offset; /* sum write */ 1433 tcpsum |= offset + skb->csum_offset; /* sum write */
1429 1434
1430 ctrl = CALSUM | WR_SUM | INIT_SUM | LOCK_SUM; 1435 ctrl |= CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
1431 if (ip_hdr(skb)->protocol == IPPROTO_UDP) 1436 if (ip_hdr(skb)->protocol == IPPROTO_UDP)
1432 ctrl |= UDPTCP; 1437 ctrl |= UDPTCP;
1433 1438
@@ -1538,6 +1543,8 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
1538 } 1543 }
1539 1544
1540 sky2->tx_cons = idx; 1545 sky2->tx_cons = idx;
1546 smp_mb();
1547
1541 if (tx_avail(sky2) > MAX_SKB_TX_LE + 4) 1548 if (tx_avail(sky2) > MAX_SKB_TX_LE + 4)
1542 netif_wake_queue(dev); 1549 netif_wake_queue(dev);
1543} 1550}
@@ -1577,13 +1584,6 @@ static int sky2_down(struct net_device *dev)
1577 imask &= ~portirq_msk[port]; 1584 imask &= ~portirq_msk[port];
1578 sky2_write32(hw, B0_IMSK, imask); 1585 sky2_write32(hw, B0_IMSK, imask);
1579 1586
1580 /*
1581 * Both ports share the NAPI poll on port 0, so if necessary undo the
1582 * the disable that is done in dev_close.
1583 */
1584 if (sky2->port == 0 && hw->ports > 1)
1585 netif_poll_enable(dev);
1586
1587 sky2_gmac_reset(hw, port); 1587 sky2_gmac_reset(hw, port);
1588 1588
1589 /* Stop transmitter */ 1589 /* Stop transmitter */
@@ -2139,8 +2139,10 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do)
2139 switch (le->opcode & ~HW_OWNER) { 2139 switch (le->opcode & ~HW_OWNER) {
2140 case OP_RXSTAT: 2140 case OP_RXSTAT:
2141 skb = sky2_receive(dev, length, status); 2141 skb = sky2_receive(dev, length, status);
2142 if (!skb) 2142 if (unlikely(!skb)) {
2143 sky2->net_stats.rx_dropped++;
2143 goto force_update; 2144 goto force_update;
2145 }
2144 2146
2145 skb->protocol = eth_type_trans(skb, dev); 2147 skb->protocol = eth_type_trans(skb, dev);
2146 sky2->net_stats.rx_packets++; 2148 sky2->net_stats.rx_packets++;
@@ -2221,6 +2223,7 @@ force_update:
2221 2223
2222 /* Fully processed status ring so clear irq */ 2224 /* Fully processed status ring so clear irq */
2223 sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); 2225 sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
2226 mmiowb();
2224 2227
2225exit_loop: 2228exit_loop:
2226 if (buf_write[0]) { 2229 if (buf_write[0]) {
@@ -2341,6 +2344,12 @@ static void sky2_mac_intr(struct sky2_hw *hw, unsigned port)
2341 printk(KERN_INFO PFX "%s: mac interrupt status 0x%x\n", 2344 printk(KERN_INFO PFX "%s: mac interrupt status 0x%x\n",
2342 dev->name, status); 2345 dev->name, status);
2343 2346
2347 if (status & GM_IS_RX_CO_OV)
2348 gma_read16(hw, port, GM_RX_IRQ_SRC);
2349
2350 if (status & GM_IS_TX_CO_OV)
2351 gma_read16(hw, port, GM_TX_IRQ_SRC);
2352
2344 if (status & GM_IS_RX_FF_OR) { 2353 if (status & GM_IS_RX_FF_OR) {
2345 ++sky2->net_stats.rx_fifo_errors; 2354 ++sky2->net_stats.rx_fifo_errors;
2346 sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_CLI_RX_FO); 2355 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)
2439 if (work_done < work_limit) { 2448 if (work_done < work_limit) {
2440 netif_rx_complete(dev0); 2449 netif_rx_complete(dev0);
2441 2450
2451 /* end of interrupt, re-enables also acts as I/O synchronization */
2442 sky2_read32(hw, B0_Y2_SP_LISR); 2452 sky2_read32(hw, B0_Y2_SP_LISR);
2443 return 0; 2453 return 0;
2444 } else { 2454 } else {
@@ -2534,17 +2544,6 @@ static int __devinit sky2_init(struct sky2_hw *hw)
2534 return -EOPNOTSUPP; 2544 return -EOPNOTSUPP;
2535 } 2545 }
2536 2546
2537
2538 /* Some Gigabyte motherboards have 88e8056 but cause problems
2539 * There is some unresolved hardware related problem that causes
2540 * descriptor errors and receive data corruption.
2541 */
2542 if (hw->chip_id == CHIP_ID_YUKON_EC_U && dmi_blacklisted) {
2543 dev_err(&hw->pdev->dev,
2544 "88E8056 on this motherboard not supported\n");
2545 return -EOPNOTSUPP;
2546 }
2547
2548 hw->pmd_type = sky2_read8(hw, B2_PMD_TYP); 2547 hw->pmd_type = sky2_read8(hw, B2_PMD_TYP);
2549 hw->ports = 1; 2548 hw->ports = 1;
2550 t8 = sky2_read8(hw, B2_Y2_HW_RES); 2549 t8 = sky2_read8(hw, B2_Y2_HW_RES);
@@ -3910,24 +3909,8 @@ static struct pci_driver sky2_driver = {
3910 .shutdown = sky2_shutdown, 3909 .shutdown = sky2_shutdown,
3911}; 3910};
3912 3911
3913static struct dmi_system_id __initdata broken_dmi_table[] = {
3914 {
3915 .ident = "Gigabyte 965P-S3",
3916 .matches = {
3917 DMI_MATCH(DMI_SYS_VENDOR, "Gigabyte Technology Co., Ltd."),
3918 DMI_MATCH(DMI_PRODUCT_NAME, "965P-S3"),
3919
3920 },
3921 },
3922 { }
3923};
3924
3925static int __init sky2_init_module(void) 3912static int __init sky2_init_module(void)
3926{ 3913{
3927 /* Look for sick motherboards */
3928 if (dmi_check_system(broken_dmi_table))
3929 dmi_blacklisted = 1;
3930
3931 return pci_register_driver(&sky2_driver); 3914 return pci_register_driver(&sky2_driver);
3932} 3915}
3933 3916