Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] skge: gmac register access errors in dual port

Merge of four previous patches and the Kconfig fix
* Remove debug printk's
* whitespace cleanup and version number change
* clear interrupts, reset phy, and reset hardware on shutdown
* ignore 64bit counter overflow interrupts
* fix a couple of places where second port could clobber state
of first port.

Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>

authored by

Stephen Hemminger and committed by
Jeff Garzik
46a60f2d c535a9dd

+56 -46
+1 -1
drivers/net/Kconfig
··· 1951 1951 ---help--- 1952 1952 This driver support the Marvell Yukon or SysKonnect SK-98xx/SK-95xx 1953 1953 and related Gigabit Ethernet adapters. It is a new smaller driver 1954 - driver with better performance and more complete ethtool support. 1954 + with better performance and more complete ethtool support. 1955 1955 1956 1956 It does not support the link failover and network management 1957 1957 features that "portable" vendor supplied sk98lin driver does.
+54 -44
drivers/net/skge.c
··· 42 42 #include "skge.h" 43 43 44 44 #define DRV_NAME "skge" 45 - #define DRV_VERSION "0.9" 45 + #define DRV_VERSION "1.0" 46 46 #define PFX DRV_NAME " " 47 47 48 48 #define DEFAULT_TX_RING_SIZE 128 ··· 669 669 PHY_M_LED_BLINK_RT(BLINK_84MS) | 670 670 PHY_M_LEDC_TX_CTRL | 671 671 PHY_M_LEDC_DP_CTRL); 672 - 672 + 673 673 gm_phy_write(hw, port, PHY_MARV_LED_OVER, 674 674 PHY_M_LED_MO_RX(MO_LED_OFF) | 675 675 (skge->speed == SPEED_100 ? ··· 876 876 877 877 static void skge_link_up(struct skge_port *skge) 878 878 { 879 - skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), 879 + skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), 880 880 LED_BLK_OFF|LED_SYNC_OFF|LED_ON); 881 881 882 882 netif_carrier_on(skge->netdev); ··· 987 987 { 988 988 const u8 zero[8] = { 0 }; 989 989 990 + skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0); 991 + 990 992 /* reset the statistics module */ 991 993 xm_write32(hw, port, XM_GP_PORT, XM_GP_RES_STAT); 992 994 xm_write16(hw, port, XM_IMSK, 0xffff); /* disable XMAC IRQs */ ··· 1022 1020 /* read twice because of latch */ 1023 1021 (void) xm_phy_read(hw, port, PHY_BCOM_STAT); 1024 1022 status = xm_phy_read(hw, port, PHY_BCOM_STAT); 1025 - 1026 - pr_debug("bcom_check_link status=0x%x\n", status); 1027 1023 1028 1024 if ((status & PHY_ST_LSYNC) == 0) { 1029 1025 u16 cmd = xm_read16(hw, port, XM_MMU_CMD); ··· 1105 1105 { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1204 }, 1106 1106 { 0x17, 0x0013 }, { 0x15, 0x0A04 }, { 0x18, 0x0420 }, 1107 1107 }; 1108 - 1109 - pr_debug("bcom_phy_init\n"); 1110 1108 1111 1109 /* read Id from external PHY (all have the same address) */ 1112 1110 id1 = xm_phy_read(hw, port, PHY_XMAC_ID1); ··· 1338 1340 int port = skge->port; 1339 1341 u32 reg; 1340 1342 1343 + genesis_reset(hw, port); 1344 + 1341 1345 /* Clear Tx packet arbiter timeout IRQ */ 1342 1346 skge_write16(hw, B3_PA_CTRL, 1343 1347 port == 0 ? PA_CLR_TO_TX1 : PA_CLR_TO_TX2); ··· 1465 1465 u16 cmd; 1466 1466 u32 mode, msk; 1467 1467 1468 - pr_debug("genesis_link_up\n"); 1469 1468 cmd = xm_read16(hw, port, XM_MMU_CMD); 1470 1469 1471 1470 /* ··· 1577 1578 struct skge_port *skge = netdev_priv(hw->dev[port]); 1578 1579 u16 ctrl, ct1000, adv; 1579 1580 1580 - pr_debug("yukon_init\n"); 1581 1581 if (skge->autoneg == AUTONEG_ENABLE) { 1582 1582 u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL); 1583 1583 ··· 1675 1677 1676 1678 /* WA code for COMA mode -- set PHY reset */ 1677 1679 if (hw->chip_id == CHIP_ID_YUKON_LITE && 1678 - hw->chip_rev >= CHIP_REV_YU_LITE_A3) 1679 - skge_write32(hw, B2_GP_IO, 1680 - (skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9)); 1680 + hw->chip_rev >= CHIP_REV_YU_LITE_A3) { 1681 + reg = skge_read32(hw, B2_GP_IO); 1682 + reg |= GP_DIR_9 | GP_IO_9; 1683 + skge_write32(hw, B2_GP_IO, reg); 1684 + } 1681 1685 1682 1686 /* hard reset */ 1683 1687 skge_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); ··· 1687 1687 1688 1688 /* WA code for COMA mode -- clear PHY reset */ 1689 1689 if (hw->chip_id == CHIP_ID_YUKON_LITE && 1690 - hw->chip_rev >= CHIP_REV_YU_LITE_A3) 1691 - skge_write32(hw, B2_GP_IO, 1692 - (skge_read32(hw, B2_GP_IO) | GP_DIR_9) 1693 - & ~GP_IO_9); 1690 + hw->chip_rev >= CHIP_REV_YU_LITE_A3) { 1691 + reg = skge_read32(hw, B2_GP_IO); 1692 + reg |= GP_DIR_9; 1693 + reg &= ~GP_IO_9; 1694 + skge_write32(hw, B2_GP_IO, reg); 1695 + } 1694 1696 1695 1697 /* Set hardware config mode */ 1696 1698 reg = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP | ··· 1731 1729 } 1732 1730 1733 1731 gma_write16(hw, port, GM_GP_CTRL, reg); 1734 - skge_read16(hw, GMAC_IRQ_SRC); 1732 + skge_read16(hw, SK_REG(port, GMAC_IRQ_SRC)); 1735 1733 1736 1734 yukon_init(hw, port); 1737 1735 ··· 1803 1801 struct skge_hw *hw = skge->hw; 1804 1802 int port = skge->port; 1805 1803 1806 - if (hw->chip_id == CHIP_ID_YUKON_LITE && 1807 - hw->chip_rev >= CHIP_REV_YU_LITE_A3) { 1808 - skge_write32(hw, B2_GP_IO, 1809 - skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9); 1810 - } 1804 + skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0); 1805 + yukon_reset(hw, port); 1811 1806 1812 1807 gma_write16(hw, port, GM_GP_CTRL, 1813 1808 gma_read16(hw, port, GM_GP_CTRL) 1814 1809 & ~(GM_GPCR_TX_ENA|GM_GPCR_RX_ENA)); 1815 1810 gma_read16(hw, port, GM_GP_CTRL); 1816 1811 1812 + if (hw->chip_id == CHIP_ID_YUKON_LITE && 1813 + hw->chip_rev >= CHIP_REV_YU_LITE_A3) { 1814 + u32 io = skge_read32(hw, B2_GP_IO); 1815 + 1816 + io |= GP_DIR_9 | GP_IO_9; 1817 + skge_write32(hw, B2_GP_IO, io); 1818 + skge_read32(hw, B2_GP_IO); 1819 + } 1820 + 1817 1821 /* set GPHY Control reset */ 1818 - skge_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); 1819 - skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET); 1822 + skge_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); 1823 + skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET); 1820 1824 } 1821 1825 1822 1826 static void yukon_get_stats(struct skge_port *skge, u64 *data) ··· 1881 1873 int port = skge->port; 1882 1874 u16 reg; 1883 1875 1884 - pr_debug("yukon_link_up\n"); 1885 - 1886 1876 /* Enable Transmit FIFO Underrun */ 1887 - skge_write8(hw, GMAC_IRQ_MSK, GMAC_DEF_MSK); 1877 + skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK); 1888 1878 1889 1879 reg = gma_read16(hw, port, GM_GP_CTRL); 1890 1880 if (skge->duplex == DUPLEX_FULL || skge->autoneg == AUTONEG_ENABLE) ··· 1902 1896 int port = skge->port; 1903 1897 u16 ctrl; 1904 1898 1905 - pr_debug("yukon_link_down\n"); 1906 1899 gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0); 1907 1900 1908 1901 ctrl = gma_read16(hw, port, GM_GP_CTRL); ··· 2117 2112 skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_START | CSR_IRQ_CL_F); 2118 2113 skge_led(skge, LED_MODE_ON); 2119 2114 2120 - pr_debug("skge_up completed\n"); 2121 2115 return 0; 2122 2116 2123 2117 free_rx_ring: ··· 2139 2135 2140 2136 netif_stop_queue(dev); 2141 2137 2138 + skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_OFF); 2139 + if (hw->chip_id == CHIP_ID_GENESIS) 2140 + genesis_stop(skge); 2141 + else 2142 + yukon_stop(skge); 2143 + 2144 + hw->intr_mask &= ~portirqmask[skge->port]; 2145 + skge_write32(hw, B0_IMSK, hw->intr_mask); 2146 + 2142 2147 /* Stop transmitter */ 2143 2148 skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP); 2144 2149 skge_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), 2145 2150 RB_RST_SET|RB_DIS_OP_MD); 2146 2151 2147 - if (hw->chip_id == CHIP_ID_GENESIS) 2148 - genesis_stop(skge); 2149 - else 2150 - yukon_stop(skge); 2151 2152 2152 2153 /* Disable Force Sync bit and Enable Alloc bit */ 2153 2154 skge_write8(hw, SK_REG(port, TXA_CTRL), ··· 2376 2367 u32 mode; 2377 2368 u8 filter[8]; 2378 2369 2379 - pr_debug("genesis_set_multicast flags=%x count=%d\n", dev->flags, dev->mc_count); 2380 - 2381 2370 mode = xm_read32(hw, port, XM_MODE); 2382 2371 mode |= XM_MD_ENA_HASH; 2383 2372 if (dev->flags & IFF_PROMISC) ··· 2537 2530 unsigned int to_do = min(dev->quota, *budget); 2538 2531 unsigned int work_done = 0; 2539 2532 2540 - pr_debug("skge_poll\n"); 2541 - 2542 2533 for (e = ring->to_clean; work_done < to_do; e = e->next) { 2543 2534 struct skge_rx_desc *rd = e->desc; 2544 2535 struct sk_buff *skb; ··· 2677 2672 if (hw->chip_id == CHIP_ID_GENESIS) { 2678 2673 /* clear xmac errors */ 2679 2674 if (hwstatus & (IS_NO_STAT_M1|IS_NO_TIST_M1)) 2680 - skge_write16(hw, SK_REG(0, RX_MFF_CTRL1), MFF_CLR_INSTAT); 2675 + skge_write16(hw, RX_MFF_CTRL1, MFF_CLR_INSTAT); 2681 2676 if (hwstatus & (IS_NO_STAT_M2|IS_NO_TIST_M2)) 2682 - skge_write16(hw, SK_REG(0, RX_MFF_CTRL2), MFF_CLR_INSTAT); 2677 + skge_write16(hw, RX_MFF_CTRL2, MFF_CLR_INSTAT); 2683 2678 } else { 2684 2679 /* Timestamp (unused) overflow */ 2685 2680 if (hwstatus & IS_IRQ_TIST_OV) ··· 3005 3000 3006 3001 skge_write32(hw, B0_IMSK, hw->intr_mask); 3007 3002 3008 - if (hw->chip_id != CHIP_ID_GENESIS) 3009 - skge_write8(hw, GMAC_IRQ_MSK, 0); 3010 - 3011 3003 spin_lock_bh(&hw->phy_lock); 3012 3004 for (i = 0; i < hw->ports; i++) { 3013 3005 if (hw->chip_id == CHIP_ID_GENESIS) ··· 3232 3230 dev0 = hw->dev[0]; 3233 3231 unregister_netdev(dev0); 3234 3232 3233 + skge_write32(hw, B0_IMSK, 0); 3234 + skge_write16(hw, B0_LED, LED_STAT_OFF); 3235 + skge_pci_clear(hw); 3236 + skge_write8(hw, B0_CTST, CS_RST_SET); 3237 + 3235 3238 tasklet_kill(&hw->ext_tasklet); 3236 3239 3237 3240 free_irq(pdev->irq, hw); ··· 3245 3238 if (dev1) 3246 3239 free_netdev(dev1); 3247 3240 free_netdev(dev0); 3248 - skge_write16(hw, B0_LED, LED_STAT_OFF); 3241 + 3249 3242 iounmap(hw->regs); 3250 3243 kfree(hw); 3251 3244 pci_set_drvdata(pdev, NULL); ··· 3264 3257 struct skge_port *skge = netdev_priv(dev); 3265 3258 if (netif_running(dev)) { 3266 3259 netif_carrier_off(dev); 3267 - skge_down(dev); 3260 + if (skge->wol) 3261 + netif_stop_queue(dev); 3262 + else 3263 + skge_down(dev); 3268 3264 } 3269 3265 netif_device_detach(dev); 3270 3266 wol |= skge->wol;
+1 -1
drivers/net/skge.h
··· 2008 2008 GM_IS_RX_FF_OR = 1<<1, /* Receive FIFO Overrun */ 2009 2009 GM_IS_RX_COMPL = 1<<0, /* Frame Reception Complete */ 2010 2010 2011 - #define GMAC_DEF_MSK (GM_IS_TX_CO_OV | GM_IS_RX_CO_OV | GM_IS_TX_FF_UR) 2011 + #define GMAC_DEF_MSK (GM_IS_RX_FF_OR | GM_IS_TX_FF_UR) 2012 2012 2013 2013 /* GMAC_LINK_CTRL 16 bit GMAC Link Control Reg (YUKON only) */ 2014 2014 /* Bits 15.. 2: reserved */