diff options
Diffstat (limited to 'drivers/net/skge.c')
-rw-r--r-- | drivers/net/skge.c | 290 |
1 files changed, 144 insertions, 146 deletions
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index d7c98515fdfd..ae1996a3bc5c 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
@@ -42,7 +42,7 @@ | |||
42 | #include "skge.h" | 42 | #include "skge.h" |
43 | 43 | ||
44 | #define DRV_NAME "skge" | 44 | #define DRV_NAME "skge" |
45 | #define DRV_VERSION "0.9" | 45 | #define DRV_VERSION "1.1" |
46 | #define PFX DRV_NAME " " | 46 | #define PFX DRV_NAME " " |
47 | 47 | ||
48 | #define DEFAULT_TX_RING_SIZE 128 | 48 | #define DEFAULT_TX_RING_SIZE 128 |
@@ -105,41 +105,28 @@ static const u32 rxirqmask[] = { IS_R1_F, IS_R2_F }; | |||
105 | static const u32 txirqmask[] = { IS_XA1_F, IS_XA2_F }; | 105 | static const u32 txirqmask[] = { IS_XA1_F, IS_XA2_F }; |
106 | static const u32 portirqmask[] = { IS_PORT_1, IS_PORT_2 }; | 106 | static const u32 portirqmask[] = { IS_PORT_1, IS_PORT_2 }; |
107 | 107 | ||
108 | /* Don't need to look at whole 16K. | ||
109 | * last interesting register is descriptor poll timer. | ||
110 | */ | ||
111 | #define SKGE_REGS_LEN (29*128) | ||
112 | |||
113 | static int skge_get_regs_len(struct net_device *dev) | 108 | static int skge_get_regs_len(struct net_device *dev) |
114 | { | 109 | { |
115 | return SKGE_REGS_LEN; | 110 | return 0x4000; |
116 | } | 111 | } |
117 | 112 | ||
118 | /* | 113 | /* |
119 | * Returns copy of control register region | 114 | * Returns copy of whole control register region |
120 | * I/O region is divided into banks and certain regions are unreadable | 115 | * Note: skip RAM address register because accessing it will |
116 | * cause bus hangs! | ||
121 | */ | 117 | */ |
122 | static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs, | 118 | static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs, |
123 | void *p) | 119 | void *p) |
124 | { | 120 | { |
125 | const struct skge_port *skge = netdev_priv(dev); | 121 | const struct skge_port *skge = netdev_priv(dev); |
126 | unsigned long offs; | ||
127 | const void __iomem *io = skge->hw->regs; | 122 | const void __iomem *io = skge->hw->regs; |
128 | static const unsigned long bankmap | ||
129 | = (1<<0) | (1<<2) | (1<<8) | (1<<9) | ||
130 | | (1<<12) | (1<<13) | (1<<14) | (1<<15) | (1<<16) | ||
131 | | (1<<17) | (1<<20) | (1<<21) | (1<<22) | (1<<23) | ||
132 | | (1<<24) | (1<<25) | (1<<26) | (1<<27) | (1<<28); | ||
133 | 123 | ||
134 | regs->version = 1; | 124 | regs->version = 1; |
135 | for (offs = 0; offs < regs->len; offs += 128) { | 125 | memset(p, 0, regs->len); |
136 | u32 len = min_t(u32, 128, regs->len - offs); | 126 | memcpy_fromio(p, io, B3_RAM_ADDR); |
137 | 127 | ||
138 | if (bankmap & (1<<(offs/128))) | 128 | memcpy_fromio(p + B3_RI_WTO_R1, io + B3_RI_WTO_R1, |
139 | memcpy_fromio(p + offs, io + offs, len); | 129 | regs->len - B3_RI_WTO_R1); |
140 | else | ||
141 | memset(p + offs, 0, len); | ||
142 | } | ||
143 | } | 130 | } |
144 | 131 | ||
145 | /* Wake on Lan only supported on Yukon chps with rev 1 or above */ | 132 | /* Wake on Lan only supported on Yukon chps with rev 1 or above */ |
@@ -669,7 +656,7 @@ static void skge_led(struct skge_port *skge, enum led_mode mode) | |||
669 | PHY_M_LED_BLINK_RT(BLINK_84MS) | | 656 | PHY_M_LED_BLINK_RT(BLINK_84MS) | |
670 | PHY_M_LEDC_TX_CTRL | | 657 | PHY_M_LEDC_TX_CTRL | |
671 | PHY_M_LEDC_DP_CTRL); | 658 | PHY_M_LEDC_DP_CTRL); |
672 | 659 | ||
673 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, | 660 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, |
674 | PHY_M_LED_MO_RX(MO_LED_OFF) | | 661 | PHY_M_LED_MO_RX(MO_LED_OFF) | |
675 | (skge->speed == SPEED_100 ? | 662 | (skge->speed == SPEED_100 ? |
@@ -775,17 +762,6 @@ static int skge_ring_alloc(struct skge_ring *ring, void *vaddr, u64 base) | |||
775 | return 0; | 762 | return 0; |
776 | } | 763 | } |
777 | 764 | ||
778 | static struct sk_buff *skge_rx_alloc(struct net_device *dev, unsigned int size) | ||
779 | { | ||
780 | struct sk_buff *skb = dev_alloc_skb(size); | ||
781 | |||
782 | if (likely(skb)) { | ||
783 | skb->dev = dev; | ||
784 | skb_reserve(skb, NET_IP_ALIGN); | ||
785 | } | ||
786 | return skb; | ||
787 | } | ||
788 | |||
789 | /* Allocate and setup a new buffer for receiving */ | 765 | /* Allocate and setup a new buffer for receiving */ |
790 | static void skge_rx_setup(struct skge_port *skge, struct skge_element *e, | 766 | static void skge_rx_setup(struct skge_port *skge, struct skge_element *e, |
791 | struct sk_buff *skb, unsigned int bufsize) | 767 | struct sk_buff *skb, unsigned int bufsize) |
@@ -858,16 +834,17 @@ static int skge_rx_fill(struct skge_port *skge) | |||
858 | { | 834 | { |
859 | struct skge_ring *ring = &skge->rx_ring; | 835 | struct skge_ring *ring = &skge->rx_ring; |
860 | struct skge_element *e; | 836 | struct skge_element *e; |
861 | unsigned int bufsize = skge->rx_buf_size; | ||
862 | 837 | ||
863 | e = ring->start; | 838 | e = ring->start; |
864 | do { | 839 | do { |
865 | struct sk_buff *skb = skge_rx_alloc(skge->netdev, bufsize); | 840 | struct sk_buff *skb; |
866 | 841 | ||
842 | skb = dev_alloc_skb(skge->rx_buf_size + NET_IP_ALIGN); | ||
867 | if (!skb) | 843 | if (!skb) |
868 | return -ENOMEM; | 844 | return -ENOMEM; |
869 | 845 | ||
870 | skge_rx_setup(skge, e, skb, bufsize); | 846 | skb_reserve(skb, NET_IP_ALIGN); |
847 | skge_rx_setup(skge, e, skb, skge->rx_buf_size); | ||
871 | } while ( (e = e->next) != ring->start); | 848 | } while ( (e = e->next) != ring->start); |
872 | 849 | ||
873 | ring->to_clean = ring->start; | 850 | ring->to_clean = ring->start; |
@@ -876,7 +853,7 @@ static int skge_rx_fill(struct skge_port *skge) | |||
876 | 853 | ||
877 | static void skge_link_up(struct skge_port *skge) | 854 | static void skge_link_up(struct skge_port *skge) |
878 | { | 855 | { |
879 | skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), | 856 | skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), |
880 | LED_BLK_OFF|LED_SYNC_OFF|LED_ON); | 857 | LED_BLK_OFF|LED_SYNC_OFF|LED_ON); |
881 | 858 | ||
882 | netif_carrier_on(skge->netdev); | 859 | netif_carrier_on(skge->netdev); |
@@ -987,6 +964,8 @@ static void genesis_reset(struct skge_hw *hw, int port) | |||
987 | { | 964 | { |
988 | const u8 zero[8] = { 0 }; | 965 | const u8 zero[8] = { 0 }; |
989 | 966 | ||
967 | skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0); | ||
968 | |||
990 | /* reset the statistics module */ | 969 | /* reset the statistics module */ |
991 | xm_write32(hw, port, XM_GP_PORT, XM_GP_RES_STAT); | 970 | xm_write32(hw, port, XM_GP_PORT, XM_GP_RES_STAT); |
992 | xm_write16(hw, port, XM_IMSK, 0xffff); /* disable XMAC IRQs */ | 971 | xm_write16(hw, port, XM_IMSK, 0xffff); /* disable XMAC IRQs */ |
@@ -1021,8 +1000,6 @@ static void bcom_check_link(struct skge_hw *hw, int port) | |||
1021 | (void) xm_phy_read(hw, port, PHY_BCOM_STAT); | 1000 | (void) xm_phy_read(hw, port, PHY_BCOM_STAT); |
1022 | status = xm_phy_read(hw, port, PHY_BCOM_STAT); | 1001 | status = xm_phy_read(hw, port, PHY_BCOM_STAT); |
1023 | 1002 | ||
1024 | pr_debug("bcom_check_link status=0x%x\n", status); | ||
1025 | |||
1026 | if ((status & PHY_ST_LSYNC) == 0) { | 1003 | if ((status & PHY_ST_LSYNC) == 0) { |
1027 | u16 cmd = xm_read16(hw, port, XM_MMU_CMD); | 1004 | u16 cmd = xm_read16(hw, port, XM_MMU_CMD); |
1028 | cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX); | 1005 | cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX); |
@@ -1106,8 +1083,6 @@ static void bcom_phy_init(struct skge_port *skge, int jumbo) | |||
1106 | { 0x17, 0x0013 }, { 0x15, 0x0A04 }, { 0x18, 0x0420 }, | 1083 | { 0x17, 0x0013 }, { 0x15, 0x0A04 }, { 0x18, 0x0420 }, |
1107 | }; | 1084 | }; |
1108 | 1085 | ||
1109 | pr_debug("bcom_phy_init\n"); | ||
1110 | |||
1111 | /* read Id from external PHY (all have the same address) */ | 1086 | /* read Id from external PHY (all have the same address) */ |
1112 | id1 = xm_phy_read(hw, port, PHY_XMAC_ID1); | 1087 | id1 = xm_phy_read(hw, port, PHY_XMAC_ID1); |
1113 | 1088 | ||
@@ -1340,6 +1315,8 @@ static void genesis_stop(struct skge_port *skge) | |||
1340 | int port = skge->port; | 1315 | int port = skge->port; |
1341 | u32 reg; | 1316 | u32 reg; |
1342 | 1317 | ||
1318 | genesis_reset(hw, port); | ||
1319 | |||
1343 | /* Clear Tx packet arbiter timeout IRQ */ | 1320 | /* Clear Tx packet arbiter timeout IRQ */ |
1344 | skge_write16(hw, B3_PA_CTRL, | 1321 | skge_write16(hw, B3_PA_CTRL, |
1345 | port == 0 ? PA_CLR_TO_TX1 : PA_CLR_TO_TX2); | 1322 | port == 0 ? PA_CLR_TO_TX1 : PA_CLR_TO_TX2); |
@@ -1465,7 +1442,6 @@ static void genesis_link_up(struct skge_port *skge) | |||
1465 | u16 cmd; | 1442 | u16 cmd; |
1466 | u32 mode, msk; | 1443 | u32 mode, msk; |
1467 | 1444 | ||
1468 | pr_debug("genesis_link_up\n"); | ||
1469 | cmd = xm_read16(hw, port, XM_MMU_CMD); | 1445 | cmd = xm_read16(hw, port, XM_MMU_CMD); |
1470 | 1446 | ||
1471 | /* | 1447 | /* |
@@ -1578,7 +1554,6 @@ static void yukon_init(struct skge_hw *hw, int port) | |||
1578 | struct skge_port *skge = netdev_priv(hw->dev[port]); | 1554 | struct skge_port *skge = netdev_priv(hw->dev[port]); |
1579 | u16 ctrl, ct1000, adv; | 1555 | u16 ctrl, ct1000, adv; |
1580 | 1556 | ||
1581 | pr_debug("yukon_init\n"); | ||
1582 | if (skge->autoneg == AUTONEG_ENABLE) { | 1557 | if (skge->autoneg == AUTONEG_ENABLE) { |
1583 | u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL); | 1558 | u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL); |
1584 | 1559 | ||
@@ -1677,9 +1652,11 @@ static void yukon_mac_init(struct skge_hw *hw, int port) | |||
1677 | 1652 | ||
1678 | /* WA code for COMA mode -- set PHY reset */ | 1653 | /* WA code for COMA mode -- set PHY reset */ |
1679 | if (hw->chip_id == CHIP_ID_YUKON_LITE && | 1654 | if (hw->chip_id == CHIP_ID_YUKON_LITE && |
1680 | hw->chip_rev >= CHIP_REV_YU_LITE_A3) | 1655 | hw->chip_rev >= CHIP_REV_YU_LITE_A3) { |
1681 | skge_write32(hw, B2_GP_IO, | 1656 | reg = skge_read32(hw, B2_GP_IO); |
1682 | (skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9)); | 1657 | reg |= GP_DIR_9 | GP_IO_9; |
1658 | skge_write32(hw, B2_GP_IO, reg); | ||
1659 | } | ||
1683 | 1660 | ||
1684 | /* hard reset */ | 1661 | /* hard reset */ |
1685 | skge_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); | 1662 | skge_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); |
@@ -1687,10 +1664,12 @@ static void yukon_mac_init(struct skge_hw *hw, int port) | |||
1687 | 1664 | ||
1688 | /* WA code for COMA mode -- clear PHY reset */ | 1665 | /* WA code for COMA mode -- clear PHY reset */ |
1689 | if (hw->chip_id == CHIP_ID_YUKON_LITE && | 1666 | if (hw->chip_id == CHIP_ID_YUKON_LITE && |
1690 | hw->chip_rev >= CHIP_REV_YU_LITE_A3) | 1667 | hw->chip_rev >= CHIP_REV_YU_LITE_A3) { |
1691 | skge_write32(hw, B2_GP_IO, | 1668 | reg = skge_read32(hw, B2_GP_IO); |
1692 | (skge_read32(hw, B2_GP_IO) | GP_DIR_9) | 1669 | reg |= GP_DIR_9; |
1693 | & ~GP_IO_9); | 1670 | reg &= ~GP_IO_9; |
1671 | skge_write32(hw, B2_GP_IO, reg); | ||
1672 | } | ||
1694 | 1673 | ||
1695 | /* Set hardware config mode */ | 1674 | /* Set hardware config mode */ |
1696 | reg = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP | | 1675 | reg = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP | |
@@ -1729,7 +1708,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port) | |||
1729 | } | 1708 | } |
1730 | 1709 | ||
1731 | gma_write16(hw, port, GM_GP_CTRL, reg); | 1710 | gma_write16(hw, port, GM_GP_CTRL, reg); |
1732 | skge_read16(hw, GMAC_IRQ_SRC); | 1711 | skge_read16(hw, SK_REG(port, GMAC_IRQ_SRC)); |
1733 | 1712 | ||
1734 | yukon_init(hw, port); | 1713 | yukon_init(hw, port); |
1735 | 1714 | ||
@@ -1801,20 +1780,26 @@ static void yukon_stop(struct skge_port *skge) | |||
1801 | struct skge_hw *hw = skge->hw; | 1780 | struct skge_hw *hw = skge->hw; |
1802 | int port = skge->port; | 1781 | int port = skge->port; |
1803 | 1782 | ||
1804 | if (hw->chip_id == CHIP_ID_YUKON_LITE && | 1783 | skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0); |
1805 | hw->chip_rev >= CHIP_REV_YU_LITE_A3) { | 1784 | yukon_reset(hw, port); |
1806 | skge_write32(hw, B2_GP_IO, | ||
1807 | skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9); | ||
1808 | } | ||
1809 | 1785 | ||
1810 | gma_write16(hw, port, GM_GP_CTRL, | 1786 | gma_write16(hw, port, GM_GP_CTRL, |
1811 | gma_read16(hw, port, GM_GP_CTRL) | 1787 | gma_read16(hw, port, GM_GP_CTRL) |
1812 | & ~(GM_GPCR_TX_ENA|GM_GPCR_RX_ENA)); | 1788 | & ~(GM_GPCR_TX_ENA|GM_GPCR_RX_ENA)); |
1813 | gma_read16(hw, port, GM_GP_CTRL); | 1789 | gma_read16(hw, port, GM_GP_CTRL); |
1814 | 1790 | ||
1791 | if (hw->chip_id == CHIP_ID_YUKON_LITE && | ||
1792 | hw->chip_rev >= CHIP_REV_YU_LITE_A3) { | ||
1793 | u32 io = skge_read32(hw, B2_GP_IO); | ||
1794 | |||
1795 | io |= GP_DIR_9 | GP_IO_9; | ||
1796 | skge_write32(hw, B2_GP_IO, io); | ||
1797 | skge_read32(hw, B2_GP_IO); | ||
1798 | } | ||
1799 | |||
1815 | /* set GPHY Control reset */ | 1800 | /* set GPHY Control reset */ |
1816 | skge_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); | 1801 | skge_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); |
1817 | skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET); | 1802 | skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET); |
1818 | } | 1803 | } |
1819 | 1804 | ||
1820 | static void yukon_get_stats(struct skge_port *skge, u64 *data) | 1805 | static void yukon_get_stats(struct skge_port *skge, u64 *data) |
@@ -1873,10 +1858,8 @@ static void yukon_link_up(struct skge_port *skge) | |||
1873 | int port = skge->port; | 1858 | int port = skge->port; |
1874 | u16 reg; | 1859 | u16 reg; |
1875 | 1860 | ||
1876 | pr_debug("yukon_link_up\n"); | ||
1877 | |||
1878 | /* Enable Transmit FIFO Underrun */ | 1861 | /* Enable Transmit FIFO Underrun */ |
1879 | skge_write8(hw, GMAC_IRQ_MSK, GMAC_DEF_MSK); | 1862 | skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK); |
1880 | 1863 | ||
1881 | reg = gma_read16(hw, port, GM_GP_CTRL); | 1864 | reg = gma_read16(hw, port, GM_GP_CTRL); |
1882 | if (skge->duplex == DUPLEX_FULL || skge->autoneg == AUTONEG_ENABLE) | 1865 | if (skge->duplex == DUPLEX_FULL || skge->autoneg == AUTONEG_ENABLE) |
@@ -1896,7 +1879,6 @@ static void yukon_link_down(struct skge_port *skge) | |||
1896 | int port = skge->port; | 1879 | int port = skge->port; |
1897 | u16 ctrl; | 1880 | u16 ctrl; |
1898 | 1881 | ||
1899 | pr_debug("yukon_link_down\n"); | ||
1900 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0); | 1882 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0); |
1901 | 1883 | ||
1902 | ctrl = gma_read16(hw, port, GM_GP_CTRL); | 1884 | ctrl = gma_read16(hw, port, GM_GP_CTRL); |
@@ -2112,7 +2094,6 @@ static int skge_up(struct net_device *dev) | |||
2112 | skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_START | CSR_IRQ_CL_F); | 2094 | skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_START | CSR_IRQ_CL_F); |
2113 | skge_led(skge, LED_MODE_ON); | 2095 | skge_led(skge, LED_MODE_ON); |
2114 | 2096 | ||
2115 | pr_debug("skge_up completed\n"); | ||
2116 | return 0; | 2097 | return 0; |
2117 | 2098 | ||
2118 | free_rx_ring: | 2099 | free_rx_ring: |
@@ -2135,15 +2116,20 @@ static int skge_down(struct net_device *dev) | |||
2135 | 2116 | ||
2136 | netif_stop_queue(dev); | 2117 | netif_stop_queue(dev); |
2137 | 2118 | ||
2119 | skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_OFF); | ||
2120 | if (hw->chip_id == CHIP_ID_GENESIS) | ||
2121 | genesis_stop(skge); | ||
2122 | else | ||
2123 | yukon_stop(skge); | ||
2124 | |||
2125 | hw->intr_mask &= ~portirqmask[skge->port]; | ||
2126 | skge_write32(hw, B0_IMSK, hw->intr_mask); | ||
2127 | |||
2138 | /* Stop transmitter */ | 2128 | /* Stop transmitter */ |
2139 | skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP); | 2129 | skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP); |
2140 | skge_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), | 2130 | skge_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), |
2141 | RB_RST_SET|RB_DIS_OP_MD); | 2131 | RB_RST_SET|RB_DIS_OP_MD); |
2142 | 2132 | ||
2143 | if (hw->chip_id == CHIP_ID_GENESIS) | ||
2144 | genesis_stop(skge); | ||
2145 | else | ||
2146 | yukon_stop(skge); | ||
2147 | 2133 | ||
2148 | /* Disable Force Sync bit and Enable Alloc bit */ | 2134 | /* Disable Force Sync bit and Enable Alloc bit */ |
2149 | skge_write8(hw, SK_REG(port, TXA_CTRL), | 2135 | skge_write8(hw, SK_REG(port, TXA_CTRL), |
@@ -2367,8 +2353,6 @@ static void genesis_set_multicast(struct net_device *dev) | |||
2367 | u32 mode; | 2353 | u32 mode; |
2368 | u8 filter[8]; | 2354 | u8 filter[8]; |
2369 | 2355 | ||
2370 | pr_debug("genesis_set_multicast flags=%x count=%d\n", dev->flags, dev->mc_count); | ||
2371 | |||
2372 | mode = xm_read32(hw, port, XM_MODE); | 2356 | mode = xm_read32(hw, port, XM_MODE); |
2373 | mode |= XM_MD_ENA_HASH; | 2357 | mode |= XM_MD_ENA_HASH; |
2374 | if (dev->flags & IFF_PROMISC) | 2358 | if (dev->flags & IFF_PROMISC) |
@@ -2435,6 +2419,14 @@ static void yukon_set_multicast(struct net_device *dev) | |||
2435 | gma_write16(hw, port, GM_RX_CTRL, reg); | 2419 | gma_write16(hw, port, GM_RX_CTRL, reg); |
2436 | } | 2420 | } |
2437 | 2421 | ||
2422 | static inline u16 phy_length(const struct skge_hw *hw, u32 status) | ||
2423 | { | ||
2424 | if (hw->chip_id == CHIP_ID_GENESIS) | ||
2425 | return status >> XMR_FS_LEN_SHIFT; | ||
2426 | else | ||
2427 | return status >> GMR_FS_LEN_SHIFT; | ||
2428 | } | ||
2429 | |||
2438 | static inline int bad_phy_status(const struct skge_hw *hw, u32 status) | 2430 | static inline int bad_phy_status(const struct skge_hw *hw, u32 status) |
2439 | { | 2431 | { |
2440 | if (hw->chip_id == CHIP_ID_GENESIS) | 2432 | if (hw->chip_id == CHIP_ID_GENESIS) |
@@ -2444,80 +2436,99 @@ static inline int bad_phy_status(const struct skge_hw *hw, u32 status) | |||
2444 | (status & GMR_FS_RX_OK) == 0; | 2436 | (status & GMR_FS_RX_OK) == 0; |
2445 | } | 2437 | } |
2446 | 2438 | ||
2447 | static void skge_rx_error(struct skge_port *skge, int slot, | ||
2448 | u32 control, u32 status) | ||
2449 | { | ||
2450 | if (netif_msg_rx_err(skge)) | ||
2451 | printk(KERN_DEBUG PFX "%s: rx err, slot %d control 0x%x status 0x%x\n", | ||
2452 | skge->netdev->name, slot, control, status); | ||
2453 | |||
2454 | if ((control & (BMU_EOF|BMU_STF)) != (BMU_STF|BMU_EOF)) | ||
2455 | skge->net_stats.rx_length_errors++; | ||
2456 | else if (skge->hw->chip_id == CHIP_ID_GENESIS) { | ||
2457 | if (status & (XMR_FS_RUNT|XMR_FS_LNG_ERR)) | ||
2458 | skge->net_stats.rx_length_errors++; | ||
2459 | if (status & XMR_FS_FRA_ERR) | ||
2460 | skge->net_stats.rx_frame_errors++; | ||
2461 | if (status & XMR_FS_FCS_ERR) | ||
2462 | skge->net_stats.rx_crc_errors++; | ||
2463 | } else { | ||
2464 | if (status & (GMR_FS_LONG_ERR|GMR_FS_UN_SIZE)) | ||
2465 | skge->net_stats.rx_length_errors++; | ||
2466 | if (status & GMR_FS_FRAGMENT) | ||
2467 | skge->net_stats.rx_frame_errors++; | ||
2468 | if (status & GMR_FS_CRC_ERR) | ||
2469 | skge->net_stats.rx_crc_errors++; | ||
2470 | } | ||
2471 | } | ||
2472 | 2439 | ||
2473 | /* Get receive buffer from descriptor. | 2440 | /* Get receive buffer from descriptor. |
2474 | * Handles copy of small buffers and reallocation failures | 2441 | * Handles copy of small buffers and reallocation failures |
2475 | */ | 2442 | */ |
2476 | static inline struct sk_buff *skge_rx_get(struct skge_port *skge, | 2443 | static inline struct sk_buff *skge_rx_get(struct skge_port *skge, |
2477 | struct skge_element *e, | 2444 | struct skge_element *e, |
2478 | unsigned int len) | 2445 | u32 control, u32 status, u16 csum) |
2479 | { | 2446 | { |
2480 | struct sk_buff *nskb, *skb; | 2447 | struct sk_buff *skb; |
2448 | u16 len = control & BMU_BBC; | ||
2449 | |||
2450 | if (unlikely(netif_msg_rx_status(skge))) | ||
2451 | printk(KERN_DEBUG PFX "%s: rx slot %td status 0x%x len %d\n", | ||
2452 | skge->netdev->name, e - skge->rx_ring.start, | ||
2453 | status, len); | ||
2454 | |||
2455 | if (len > skge->rx_buf_size) | ||
2456 | goto error; | ||
2457 | |||
2458 | if ((control & (BMU_EOF|BMU_STF)) != (BMU_STF|BMU_EOF)) | ||
2459 | goto error; | ||
2460 | |||
2461 | if (bad_phy_status(skge->hw, status)) | ||
2462 | goto error; | ||
2463 | |||
2464 | if (phy_length(skge->hw, status) != len) | ||
2465 | goto error; | ||
2481 | 2466 | ||
2482 | if (len < RX_COPY_THRESHOLD) { | 2467 | if (len < RX_COPY_THRESHOLD) { |
2483 | nskb = skge_rx_alloc(skge->netdev, len + NET_IP_ALIGN); | 2468 | skb = dev_alloc_skb(len + 2); |
2484 | if (unlikely(!nskb)) | 2469 | if (!skb) |
2485 | return NULL; | 2470 | goto resubmit; |
2486 | 2471 | ||
2472 | skb_reserve(skb, 2); | ||
2487 | pci_dma_sync_single_for_cpu(skge->hw->pdev, | 2473 | pci_dma_sync_single_for_cpu(skge->hw->pdev, |
2488 | pci_unmap_addr(e, mapaddr), | 2474 | pci_unmap_addr(e, mapaddr), |
2489 | len, PCI_DMA_FROMDEVICE); | 2475 | len, PCI_DMA_FROMDEVICE); |
2490 | memcpy(nskb->data, e->skb->data, len); | 2476 | memcpy(skb->data, e->skb->data, len); |
2491 | pci_dma_sync_single_for_device(skge->hw->pdev, | 2477 | pci_dma_sync_single_for_device(skge->hw->pdev, |
2492 | pci_unmap_addr(e, mapaddr), | 2478 | pci_unmap_addr(e, mapaddr), |
2493 | len, PCI_DMA_FROMDEVICE); | 2479 | len, PCI_DMA_FROMDEVICE); |
2494 | |||
2495 | if (skge->rx_csum) { | ||
2496 | struct skge_rx_desc *rd = e->desc; | ||
2497 | nskb->csum = le16_to_cpu(rd->csum2); | ||
2498 | nskb->ip_summed = CHECKSUM_HW; | ||
2499 | } | ||
2500 | skge_rx_reuse(e, skge->rx_buf_size); | 2480 | skge_rx_reuse(e, skge->rx_buf_size); |
2501 | return nskb; | ||
2502 | } else { | 2481 | } else { |
2503 | nskb = skge_rx_alloc(skge->netdev, skge->rx_buf_size); | 2482 | struct sk_buff *nskb; |
2504 | if (unlikely(!nskb)) | 2483 | nskb = dev_alloc_skb(skge->rx_buf_size + NET_IP_ALIGN); |
2505 | return NULL; | 2484 | if (!nskb) |
2485 | goto resubmit; | ||
2506 | 2486 | ||
2507 | pci_unmap_single(skge->hw->pdev, | 2487 | pci_unmap_single(skge->hw->pdev, |
2508 | pci_unmap_addr(e, mapaddr), | 2488 | pci_unmap_addr(e, mapaddr), |
2509 | pci_unmap_len(e, maplen), | 2489 | pci_unmap_len(e, maplen), |
2510 | PCI_DMA_FROMDEVICE); | 2490 | PCI_DMA_FROMDEVICE); |
2511 | skb = e->skb; | 2491 | skb = e->skb; |
2512 | if (skge->rx_csum) { | 2492 | prefetch(skb->data); |
2513 | struct skge_rx_desc *rd = e->desc; | ||
2514 | skb->csum = le16_to_cpu(rd->csum2); | ||
2515 | skb->ip_summed = CHECKSUM_HW; | ||
2516 | } | ||
2517 | |||
2518 | skge_rx_setup(skge, e, nskb, skge->rx_buf_size); | 2493 | skge_rx_setup(skge, e, nskb, skge->rx_buf_size); |
2519 | return skb; | ||
2520 | } | 2494 | } |
2495 | |||
2496 | skb_put(skb, len); | ||
2497 | skb->dev = skge->netdev; | ||
2498 | if (skge->rx_csum) { | ||
2499 | skb->csum = csum; | ||
2500 | skb->ip_summed = CHECKSUM_HW; | ||
2501 | } | ||
2502 | |||
2503 | skb->protocol = eth_type_trans(skb, skge->netdev); | ||
2504 | |||
2505 | return skb; | ||
2506 | error: | ||
2507 | |||
2508 | if (netif_msg_rx_err(skge)) | ||
2509 | printk(KERN_DEBUG PFX "%s: rx err, slot %td control 0x%x status 0x%x\n", | ||
2510 | skge->netdev->name, e - skge->rx_ring.start, | ||
2511 | control, status); | ||
2512 | |||
2513 | if (skge->hw->chip_id == CHIP_ID_GENESIS) { | ||
2514 | if (status & (XMR_FS_RUNT|XMR_FS_LNG_ERR)) | ||
2515 | skge->net_stats.rx_length_errors++; | ||
2516 | if (status & XMR_FS_FRA_ERR) | ||
2517 | skge->net_stats.rx_frame_errors++; | ||
2518 | if (status & XMR_FS_FCS_ERR) | ||
2519 | skge->net_stats.rx_crc_errors++; | ||
2520 | } else { | ||
2521 | if (status & (GMR_FS_LONG_ERR|GMR_FS_UN_SIZE)) | ||
2522 | skge->net_stats.rx_length_errors++; | ||
2523 | if (status & GMR_FS_FRAGMENT) | ||
2524 | skge->net_stats.rx_frame_errors++; | ||
2525 | if (status & GMR_FS_CRC_ERR) | ||
2526 | skge->net_stats.rx_crc_errors++; | ||
2527 | } | ||
2528 | |||
2529 | resubmit: | ||
2530 | skge_rx_reuse(e, skge->rx_buf_size); | ||
2531 | return NULL; | ||
2521 | } | 2532 | } |
2522 | 2533 | ||
2523 | 2534 | ||
@@ -2530,37 +2541,19 @@ static int skge_poll(struct net_device *dev, int *budget) | |||
2530 | unsigned int to_do = min(dev->quota, *budget); | 2541 | unsigned int to_do = min(dev->quota, *budget); |
2531 | unsigned int work_done = 0; | 2542 | unsigned int work_done = 0; |
2532 | 2543 | ||
2533 | pr_debug("skge_poll\n"); | ||
2534 | |||
2535 | for (e = ring->to_clean; work_done < to_do; e = e->next) { | 2544 | for (e = ring->to_clean; work_done < to_do; e = e->next) { |
2536 | struct skge_rx_desc *rd = e->desc; | 2545 | struct skge_rx_desc *rd = e->desc; |
2537 | struct sk_buff *skb; | 2546 | struct sk_buff *skb; |
2538 | u32 control, len, status; | 2547 | u32 control; |
2539 | 2548 | ||
2540 | rmb(); | 2549 | rmb(); |
2541 | control = rd->control; | 2550 | control = rd->control; |
2542 | if (control & BMU_OWN) | 2551 | if (control & BMU_OWN) |
2543 | break; | 2552 | break; |
2544 | 2553 | ||
2545 | len = control & BMU_BBC; | 2554 | skb = skge_rx_get(skge, e, control, rd->status, |
2546 | status = rd->status; | 2555 | le16_to_cpu(rd->csum2)); |
2547 | |||
2548 | if (unlikely((control & (BMU_EOF|BMU_STF)) != (BMU_STF|BMU_EOF) | ||
2549 | || bad_phy_status(hw, status))) { | ||
2550 | skge_rx_error(skge, e - ring->start, control, status); | ||
2551 | skge_rx_reuse(e, skge->rx_buf_size); | ||
2552 | continue; | ||
2553 | } | ||
2554 | |||
2555 | if (netif_msg_rx_status(skge)) | ||
2556 | printk(KERN_DEBUG PFX "%s: rx slot %td status 0x%x len %d\n", | ||
2557 | dev->name, e - ring->start, rd->status, len); | ||
2558 | |||
2559 | skb = skge_rx_get(skge, e, len); | ||
2560 | if (likely(skb)) { | 2556 | if (likely(skb)) { |
2561 | skb_put(skb, len); | ||
2562 | skb->protocol = eth_type_trans(skb, dev); | ||
2563 | |||
2564 | dev->last_rx = jiffies; | 2557 | dev->last_rx = jiffies; |
2565 | netif_receive_skb(skb); | 2558 | netif_receive_skb(skb); |
2566 | 2559 | ||
@@ -2672,9 +2665,9 @@ static void skge_error_irq(struct skge_hw *hw) | |||
2672 | if (hw->chip_id == CHIP_ID_GENESIS) { | 2665 | if (hw->chip_id == CHIP_ID_GENESIS) { |
2673 | /* clear xmac errors */ | 2666 | /* clear xmac errors */ |
2674 | if (hwstatus & (IS_NO_STAT_M1|IS_NO_TIST_M1)) | 2667 | if (hwstatus & (IS_NO_STAT_M1|IS_NO_TIST_M1)) |
2675 | skge_write16(hw, SK_REG(0, RX_MFF_CTRL1), MFF_CLR_INSTAT); | 2668 | skge_write16(hw, RX_MFF_CTRL1, MFF_CLR_INSTAT); |
2676 | if (hwstatus & (IS_NO_STAT_M2|IS_NO_TIST_M2)) | 2669 | if (hwstatus & (IS_NO_STAT_M2|IS_NO_TIST_M2)) |
2677 | skge_write16(hw, SK_REG(0, RX_MFF_CTRL2), MFF_CLR_INSTAT); | 2670 | skge_write16(hw, RX_MFF_CTRL2, MFF_CLR_INSTAT); |
2678 | } else { | 2671 | } else { |
2679 | /* Timestamp (unused) overflow */ | 2672 | /* Timestamp (unused) overflow */ |
2680 | if (hwstatus & IS_IRQ_TIST_OV) | 2673 | if (hwstatus & IS_IRQ_TIST_OV) |
@@ -3000,9 +2993,6 @@ static int skge_reset(struct skge_hw *hw) | |||
3000 | 2993 | ||
3001 | skge_write32(hw, B0_IMSK, hw->intr_mask); | 2994 | skge_write32(hw, B0_IMSK, hw->intr_mask); |
3002 | 2995 | ||
3003 | if (hw->chip_id != CHIP_ID_GENESIS) | ||
3004 | skge_write8(hw, GMAC_IRQ_MSK, 0); | ||
3005 | |||
3006 | spin_lock_bh(&hw->phy_lock); | 2996 | spin_lock_bh(&hw->phy_lock); |
3007 | for (i = 0; i < hw->ports; i++) { | 2997 | for (i = 0; i < hw->ports; i++) { |
3008 | if (hw->chip_id == CHIP_ID_GENESIS) | 2998 | if (hw->chip_id == CHIP_ID_GENESIS) |
@@ -3230,6 +3220,11 @@ static void __devexit skge_remove(struct pci_dev *pdev) | |||
3230 | dev0 = hw->dev[0]; | 3220 | dev0 = hw->dev[0]; |
3231 | unregister_netdev(dev0); | 3221 | unregister_netdev(dev0); |
3232 | 3222 | ||
3223 | skge_write32(hw, B0_IMSK, 0); | ||
3224 | skge_write16(hw, B0_LED, LED_STAT_OFF); | ||
3225 | skge_pci_clear(hw); | ||
3226 | skge_write8(hw, B0_CTST, CS_RST_SET); | ||
3227 | |||
3233 | tasklet_kill(&hw->ext_tasklet); | 3228 | tasklet_kill(&hw->ext_tasklet); |
3234 | 3229 | ||
3235 | free_irq(pdev->irq, hw); | 3230 | free_irq(pdev->irq, hw); |
@@ -3238,7 +3233,7 @@ static void __devexit skge_remove(struct pci_dev *pdev) | |||
3238 | if (dev1) | 3233 | if (dev1) |
3239 | free_netdev(dev1); | 3234 | free_netdev(dev1); |
3240 | free_netdev(dev0); | 3235 | free_netdev(dev0); |
3241 | skge_write16(hw, B0_LED, LED_STAT_OFF); | 3236 | |
3242 | iounmap(hw->regs); | 3237 | iounmap(hw->regs); |
3243 | kfree(hw); | 3238 | kfree(hw); |
3244 | pci_set_drvdata(pdev, NULL); | 3239 | pci_set_drvdata(pdev, NULL); |
@@ -3257,7 +3252,10 @@ static int skge_suspend(struct pci_dev *pdev, pm_message_t state) | |||
3257 | struct skge_port *skge = netdev_priv(dev); | 3252 | struct skge_port *skge = netdev_priv(dev); |
3258 | if (netif_running(dev)) { | 3253 | if (netif_running(dev)) { |
3259 | netif_carrier_off(dev); | 3254 | netif_carrier_off(dev); |
3260 | skge_down(dev); | 3255 | if (skge->wol) |
3256 | netif_stop_queue(dev); | ||
3257 | else | ||
3258 | skge_down(dev); | ||
3261 | } | 3259 | } |
3262 | netif_device_detach(dev); | 3260 | netif_device_detach(dev); |
3263 | wol |= skge->wol; | 3261 | wol |= skge->wol; |