diff options
Diffstat (limited to 'drivers/net/skge.c')
-rw-r--r-- | drivers/net/skge.c | 267 |
1 files changed, 176 insertions, 91 deletions
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 572f121b1f4e..596c93b12daa 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
@@ -37,12 +37,13 @@ | |||
37 | #include <linux/delay.h> | 37 | #include <linux/delay.h> |
38 | #include <linux/crc32.h> | 38 | #include <linux/crc32.h> |
39 | #include <linux/dma-mapping.h> | 39 | #include <linux/dma-mapping.h> |
40 | #include <linux/mii.h> | ||
40 | #include <asm/irq.h> | 41 | #include <asm/irq.h> |
41 | 42 | ||
42 | #include "skge.h" | 43 | #include "skge.h" |
43 | 44 | ||
44 | #define DRV_NAME "skge" | 45 | #define DRV_NAME "skge" |
45 | #define DRV_VERSION "1.1" | 46 | #define DRV_VERSION "1.2" |
46 | #define PFX DRV_NAME " " | 47 | #define PFX DRV_NAME " " |
47 | 48 | ||
48 | #define DEFAULT_TX_RING_SIZE 128 | 49 | #define DEFAULT_TX_RING_SIZE 128 |
@@ -88,8 +89,8 @@ MODULE_DEVICE_TABLE(pci, skge_id_table); | |||
88 | static int skge_up(struct net_device *dev); | 89 | static int skge_up(struct net_device *dev); |
89 | static int skge_down(struct net_device *dev); | 90 | static int skge_down(struct net_device *dev); |
90 | static void skge_tx_clean(struct skge_port *skge); | 91 | static void skge_tx_clean(struct skge_port *skge); |
91 | static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); | 92 | static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); |
92 | static void gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); | 93 | static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); |
93 | static void genesis_get_stats(struct skge_port *skge, u64 *data); | 94 | static void genesis_get_stats(struct skge_port *skge, u64 *data); |
94 | static void yukon_get_stats(struct skge_port *skge, u64 *data); | 95 | static void yukon_get_stats(struct skge_port *skge, u64 *data); |
95 | static void yukon_init(struct skge_hw *hw, int port); | 96 | static void yukon_init(struct skge_hw *hw, int port); |
@@ -129,7 +130,7 @@ static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs, | |||
129 | regs->len - B3_RI_WTO_R1); | 130 | regs->len - B3_RI_WTO_R1); |
130 | } | 131 | } |
131 | 132 | ||
132 | /* Wake on Lan only supported on Yukon chps with rev 1 or above */ | 133 | /* Wake on Lan only supported on Yukon chips with rev 1 or above */ |
133 | static int wol_supported(const struct skge_hw *hw) | 134 | static int wol_supported(const struct skge_hw *hw) |
134 | { | 135 | { |
135 | return !((hw->chip_id == CHIP_ID_GENESIS || | 136 | return !((hw->chip_id == CHIP_ID_GENESIS || |
@@ -169,8 +170,8 @@ static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | |||
169 | return 0; | 170 | return 0; |
170 | } | 171 | } |
171 | 172 | ||
172 | /* Determine supported/adverised modes based on hardware. | 173 | /* Determine supported/advertised modes based on hardware. |
173 | * Note: ethtoool ADVERTISED_xxx == SUPPORTED_xxx | 174 | * Note: ethtool ADVERTISED_xxx == SUPPORTED_xxx |
174 | */ | 175 | */ |
175 | static u32 skge_supported_modes(const struct skge_hw *hw) | 176 | static u32 skge_supported_modes(const struct skge_hw *hw) |
176 | { | 177 | { |
@@ -531,13 +532,13 @@ static inline u32 hwkhz(const struct skge_hw *hw) | |||
531 | return 78215; /* or: 78.125 MHz */ | 532 | return 78215; /* or: 78.125 MHz */ |
532 | } | 533 | } |
533 | 534 | ||
534 | /* Chip hz to microseconds */ | 535 | /* Chip HZ to microseconds */ |
535 | static inline u32 skge_clk2usec(const struct skge_hw *hw, u32 ticks) | 536 | static inline u32 skge_clk2usec(const struct skge_hw *hw, u32 ticks) |
536 | { | 537 | { |
537 | return (ticks * 1000) / hwkhz(hw); | 538 | return (ticks * 1000) / hwkhz(hw); |
538 | } | 539 | } |
539 | 540 | ||
540 | /* Microseconds to chip hz */ | 541 | /* Microseconds to chip HZ */ |
541 | static inline u32 skge_usecs2clk(const struct skge_hw *hw, u32 usec) | 542 | static inline u32 skge_usecs2clk(const struct skge_hw *hw, u32 usec) |
542 | { | 543 | { |
543 | return hwkhz(hw) * usec / 1000; | 544 | return hwkhz(hw) * usec / 1000; |
@@ -883,32 +884,37 @@ static void skge_link_down(struct skge_port *skge) | |||
883 | printk(KERN_INFO PFX "%s: Link is down.\n", skge->netdev->name); | 884 | printk(KERN_INFO PFX "%s: Link is down.\n", skge->netdev->name); |
884 | } | 885 | } |
885 | 886 | ||
886 | static u16 xm_phy_read(struct skge_hw *hw, int port, u16 reg) | 887 | static int __xm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val) |
887 | { | 888 | { |
888 | int i; | 889 | int i; |
889 | u16 v; | ||
890 | 890 | ||
891 | xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr); | 891 | xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr); |
892 | v = xm_read16(hw, port, XM_PHY_DATA); | 892 | xm_read16(hw, port, XM_PHY_DATA); |
893 | 893 | ||
894 | /* Need to wait for external PHY */ | 894 | /* Need to wait for external PHY */ |
895 | for (i = 0; i < PHY_RETRIES; i++) { | 895 | for (i = 0; i < PHY_RETRIES; i++) { |
896 | udelay(1); | 896 | udelay(1); |
897 | if (xm_read16(hw, port, XM_MMU_CMD) | 897 | if (xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_RDY) |
898 | & XM_MMU_PHY_RDY) | ||
899 | goto ready; | 898 | goto ready; |
900 | } | 899 | } |
901 | 900 | ||
902 | printk(KERN_WARNING PFX "%s: phy read timed out\n", | 901 | return -ETIMEDOUT; |
903 | hw->dev[port]->name); | ||
904 | return 0; | ||
905 | ready: | 902 | ready: |
906 | v = xm_read16(hw, port, XM_PHY_DATA); | 903 | *val = xm_read16(hw, port, XM_PHY_DATA); |
907 | 904 | ||
905 | return 0; | ||
906 | } | ||
907 | |||
908 | static u16 xm_phy_read(struct skge_hw *hw, int port, u16 reg) | ||
909 | { | ||
910 | u16 v = 0; | ||
911 | if (__xm_phy_read(hw, port, reg, &v)) | ||
912 | printk(KERN_WARNING PFX "%s: phy read timed out\n", | ||
913 | hw->dev[port]->name); | ||
908 | return v; | 914 | return v; |
909 | } | 915 | } |
910 | 916 | ||
911 | static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val) | 917 | static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val) |
912 | { | 918 | { |
913 | int i; | 919 | int i; |
914 | 920 | ||
@@ -918,19 +924,11 @@ static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val) | |||
918 | goto ready; | 924 | goto ready; |
919 | udelay(1); | 925 | udelay(1); |
920 | } | 926 | } |
921 | printk(KERN_WARNING PFX "%s: phy write failed to come ready\n", | 927 | return -EIO; |
922 | hw->dev[port]->name); | ||
923 | |||
924 | 928 | ||
925 | ready: | 929 | ready: |
926 | xm_write16(hw, port, XM_PHY_DATA, val); | 930 | xm_write16(hw, port, XM_PHY_DATA, val); |
927 | for (i = 0; i < PHY_RETRIES; i++) { | 931 | return 0; |
928 | udelay(1); | ||
929 | if (!(xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY)) | ||
930 | return; | ||
931 | } | ||
932 | printk(KERN_WARNING PFX "%s: phy write timed out\n", | ||
933 | hw->dev[port]->name); | ||
934 | } | 932 | } |
935 | 933 | ||
936 | static void genesis_init(struct skge_hw *hw) | 934 | static void genesis_init(struct skge_hw *hw) |
@@ -1165,7 +1163,7 @@ static void bcom_phy_init(struct skge_port *skge, int jumbo) | |||
1165 | xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ext); | 1163 | xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ext); |
1166 | xm_phy_write(hw, port, PHY_BCOM_CTRL, ctl); | 1164 | xm_phy_write(hw, port, PHY_BCOM_CTRL, ctl); |
1167 | 1165 | ||
1168 | /* Use link status change interrrupt */ | 1166 | /* Use link status change interrupt */ |
1169 | xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK); | 1167 | xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK); |
1170 | 1168 | ||
1171 | bcom_check_link(hw, port); | 1169 | bcom_check_link(hw, port); |
@@ -1205,7 +1203,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port) | |||
1205 | skge_write32(hw, B2_GP_IO, r); | 1203 | skge_write32(hw, B2_GP_IO, r); |
1206 | skge_read32(hw, B2_GP_IO); | 1204 | skge_read32(hw, B2_GP_IO); |
1207 | 1205 | ||
1208 | /* Enable GMII interfac */ | 1206 | /* Enable GMII interface */ |
1209 | xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD); | 1207 | xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD); |
1210 | 1208 | ||
1211 | bcom_phy_init(skge, jumbo); | 1209 | bcom_phy_init(skge, jumbo); |
@@ -1256,7 +1254,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port) | |||
1256 | * that jumbo frames larger than 8192 bytes will be | 1254 | * that jumbo frames larger than 8192 bytes will be |
1257 | * truncated. Disabling all bad frame filtering causes | 1255 | * truncated. Disabling all bad frame filtering causes |
1258 | * the RX FIFO to operate in streaming mode, in which | 1256 | * the RX FIFO to operate in streaming mode, in which |
1259 | * case the XMAC will start transfering frames out of the | 1257 | * case the XMAC will start transferring frames out of the |
1260 | * RX FIFO as soon as the FIFO threshold is reached. | 1258 | * RX FIFO as soon as the FIFO threshold is reached. |
1261 | */ | 1259 | */ |
1262 | xm_write32(hw, port, XM_MODE, XM_DEF_MODE); | 1260 | xm_write32(hw, port, XM_MODE, XM_DEF_MODE); |
@@ -1323,7 +1321,7 @@ static void genesis_stop(struct skge_port *skge) | |||
1323 | port == 0 ? PA_CLR_TO_TX1 : PA_CLR_TO_TX2); | 1321 | port == 0 ? PA_CLR_TO_TX1 : PA_CLR_TO_TX2); |
1324 | 1322 | ||
1325 | /* | 1323 | /* |
1326 | * If the transfer stucks at the MAC the STOP command will not | 1324 | * If the transfer sticks at the MAC the STOP command will not |
1327 | * terminate if we don't flush the XMAC's transmit FIFO ! | 1325 | * terminate if we don't flush the XMAC's transmit FIFO ! |
1328 | */ | 1326 | */ |
1329 | xm_write32(hw, port, XM_MODE, | 1327 | xm_write32(hw, port, XM_MODE, |
@@ -1400,42 +1398,6 @@ static void genesis_mac_intr(struct skge_hw *hw, int port) | |||
1400 | } | 1398 | } |
1401 | } | 1399 | } |
1402 | 1400 | ||
1403 | static void gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val) | ||
1404 | { | ||
1405 | int i; | ||
1406 | |||
1407 | gma_write16(hw, port, GM_SMI_DATA, val); | ||
1408 | gma_write16(hw, port, GM_SMI_CTRL, | ||
1409 | GM_SMI_CT_PHY_AD(hw->phy_addr) | GM_SMI_CT_REG_AD(reg)); | ||
1410 | for (i = 0; i < PHY_RETRIES; i++) { | ||
1411 | udelay(1); | ||
1412 | |||
1413 | if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY)) | ||
1414 | break; | ||
1415 | } | ||
1416 | } | ||
1417 | |||
1418 | static u16 gm_phy_read(struct skge_hw *hw, int port, u16 reg) | ||
1419 | { | ||
1420 | int i; | ||
1421 | |||
1422 | gma_write16(hw, port, GM_SMI_CTRL, | ||
1423 | GM_SMI_CT_PHY_AD(hw->phy_addr) | ||
1424 | | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD); | ||
1425 | |||
1426 | for (i = 0; i < PHY_RETRIES; i++) { | ||
1427 | udelay(1); | ||
1428 | if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL) | ||
1429 | goto ready; | ||
1430 | } | ||
1431 | |||
1432 | printk(KERN_WARNING PFX "%s: phy read timeout\n", | ||
1433 | hw->dev[port]->name); | ||
1434 | return 0; | ||
1435 | ready: | ||
1436 | return gma_read16(hw, port, GM_SMI_DATA); | ||
1437 | } | ||
1438 | |||
1439 | static void genesis_link_up(struct skge_port *skge) | 1401 | static void genesis_link_up(struct skge_port *skge) |
1440 | { | 1402 | { |
1441 | struct skge_hw *hw = skge->hw; | 1403 | struct skge_hw *hw = skge->hw; |
@@ -1549,7 +1511,55 @@ static inline void bcom_phy_intr(struct skge_port *skge) | |||
1549 | 1511 | ||
1550 | } | 1512 | } |
1551 | 1513 | ||
1552 | /* Marvell Phy Initailization */ | 1514 | static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val) |
1515 | { | ||
1516 | int i; | ||
1517 | |||
1518 | gma_write16(hw, port, GM_SMI_DATA, val); | ||
1519 | gma_write16(hw, port, GM_SMI_CTRL, | ||
1520 | GM_SMI_CT_PHY_AD(hw->phy_addr) | GM_SMI_CT_REG_AD(reg)); | ||
1521 | for (i = 0; i < PHY_RETRIES; i++) { | ||
1522 | udelay(1); | ||
1523 | |||
1524 | if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY)) | ||
1525 | return 0; | ||
1526 | } | ||
1527 | |||
1528 | printk(KERN_WARNING PFX "%s: phy write timeout\n", | ||
1529 | hw->dev[port]->name); | ||
1530 | return -EIO; | ||
1531 | } | ||
1532 | |||
1533 | static int __gm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val) | ||
1534 | { | ||
1535 | int i; | ||
1536 | |||
1537 | gma_write16(hw, port, GM_SMI_CTRL, | ||
1538 | GM_SMI_CT_PHY_AD(hw->phy_addr) | ||
1539 | | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD); | ||
1540 | |||
1541 | for (i = 0; i < PHY_RETRIES; i++) { | ||
1542 | udelay(1); | ||
1543 | if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL) | ||
1544 | goto ready; | ||
1545 | } | ||
1546 | |||
1547 | return -ETIMEDOUT; | ||
1548 | ready: | ||
1549 | *val = gma_read16(hw, port, GM_SMI_DATA); | ||
1550 | return 0; | ||
1551 | } | ||
1552 | |||
1553 | static u16 gm_phy_read(struct skge_hw *hw, int port, u16 reg) | ||
1554 | { | ||
1555 | u16 v = 0; | ||
1556 | if (__gm_phy_read(hw, port, reg, &v)) | ||
1557 | printk(KERN_WARNING PFX "%s: phy read timeout\n", | ||
1558 | hw->dev[port]->name); | ||
1559 | return v; | ||
1560 | } | ||
1561 | |||
1562 | /* Marvell Phy Initialization */ | ||
1553 | static void yukon_init(struct skge_hw *hw, int port) | 1563 | static void yukon_init(struct skge_hw *hw, int port) |
1554 | { | 1564 | { |
1555 | struct skge_port *skge = netdev_priv(hw->dev[port]); | 1565 | struct skge_port *skge = netdev_priv(hw->dev[port]); |
@@ -1794,6 +1804,25 @@ static void yukon_mac_init(struct skge_hw *hw, int port) | |||
1794 | skge_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON); | 1804 | skge_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON); |
1795 | } | 1805 | } |
1796 | 1806 | ||
1807 | /* Go into power down mode */ | ||
1808 | static void yukon_suspend(struct skge_hw *hw, int port) | ||
1809 | { | ||
1810 | u16 ctrl; | ||
1811 | |||
1812 | ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL); | ||
1813 | ctrl |= PHY_M_PC_POL_R_DIS; | ||
1814 | gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl); | ||
1815 | |||
1816 | ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL); | ||
1817 | ctrl |= PHY_CT_RESET; | ||
1818 | gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl); | ||
1819 | |||
1820 | /* switch IEEE compatible power down mode on */ | ||
1821 | ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL); | ||
1822 | ctrl |= PHY_CT_PDOWN; | ||
1823 | gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl); | ||
1824 | } | ||
1825 | |||
1797 | static void yukon_stop(struct skge_port *skge) | 1826 | static void yukon_stop(struct skge_port *skge) |
1798 | { | 1827 | { |
1799 | struct skge_hw *hw = skge->hw; | 1828 | struct skge_hw *hw = skge->hw; |
@@ -1807,14 +1836,7 @@ static void yukon_stop(struct skge_port *skge) | |||
1807 | & ~(GM_GPCR_TX_ENA|GM_GPCR_RX_ENA)); | 1836 | & ~(GM_GPCR_TX_ENA|GM_GPCR_RX_ENA)); |
1808 | gma_read16(hw, port, GM_GP_CTRL); | 1837 | gma_read16(hw, port, GM_GP_CTRL); |
1809 | 1838 | ||
1810 | if (hw->chip_id == CHIP_ID_YUKON_LITE && | 1839 | yukon_suspend(hw, port); |
1811 | hw->chip_rev >= CHIP_REV_YU_LITE_A3) { | ||
1812 | u32 io = skge_read32(hw, B2_GP_IO); | ||
1813 | |||
1814 | io |= GP_DIR_9 | GP_IO_9; | ||
1815 | skge_write32(hw, B2_GP_IO, io); | ||
1816 | skge_read32(hw, B2_GP_IO); | ||
1817 | } | ||
1818 | 1840 | ||
1819 | /* set GPHY Control reset */ | 1841 | /* set GPHY Control reset */ |
1820 | skge_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); | 1842 | skge_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); |
@@ -1997,6 +2019,51 @@ static void yukon_phy_intr(struct skge_port *skge) | |||
1997 | /* XXX restart autonegotiation? */ | 2019 | /* XXX restart autonegotiation? */ |
1998 | } | 2020 | } |
1999 | 2021 | ||
2022 | /* Basic MII support */ | ||
2023 | static int skge_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | ||
2024 | { | ||
2025 | struct mii_ioctl_data *data = if_mii(ifr); | ||
2026 | struct skge_port *skge = netdev_priv(dev); | ||
2027 | struct skge_hw *hw = skge->hw; | ||
2028 | int err = -EOPNOTSUPP; | ||
2029 | |||
2030 | if (!netif_running(dev)) | ||
2031 | return -ENODEV; /* Phy still in reset */ | ||
2032 | |||
2033 | switch(cmd) { | ||
2034 | case SIOCGMIIPHY: | ||
2035 | data->phy_id = hw->phy_addr; | ||
2036 | |||
2037 | /* fallthru */ | ||
2038 | case SIOCGMIIREG: { | ||
2039 | u16 val = 0; | ||
2040 | spin_lock_bh(&hw->phy_lock); | ||
2041 | if (hw->chip_id == CHIP_ID_GENESIS) | ||
2042 | err = __xm_phy_read(hw, skge->port, data->reg_num & 0x1f, &val); | ||
2043 | else | ||
2044 | err = __gm_phy_read(hw, skge->port, data->reg_num & 0x1f, &val); | ||
2045 | spin_unlock_bh(&hw->phy_lock); | ||
2046 | data->val_out = val; | ||
2047 | break; | ||
2048 | } | ||
2049 | |||
2050 | case SIOCSMIIREG: | ||
2051 | if (!capable(CAP_NET_ADMIN)) | ||
2052 | return -EPERM; | ||
2053 | |||
2054 | spin_lock_bh(&hw->phy_lock); | ||
2055 | if (hw->chip_id == CHIP_ID_GENESIS) | ||
2056 | err = xm_phy_write(hw, skge->port, data->reg_num & 0x1f, | ||
2057 | data->val_in); | ||
2058 | else | ||
2059 | err = gm_phy_write(hw, skge->port, data->reg_num & 0x1f, | ||
2060 | data->val_in); | ||
2061 | spin_unlock_bh(&hw->phy_lock); | ||
2062 | break; | ||
2063 | } | ||
2064 | return err; | ||
2065 | } | ||
2066 | |||
2000 | static void skge_ramset(struct skge_hw *hw, u16 q, u32 start, size_t len) | 2067 | static void skge_ramset(struct skge_hw *hw, u16 q, u32 start, size_t len) |
2001 | { | 2068 | { |
2002 | u32 end; | 2069 | u32 end; |
@@ -2089,7 +2156,7 @@ static int skge_up(struct net_device *dev) | |||
2089 | hw->intr_mask |= portirqmask[port]; | 2156 | hw->intr_mask |= portirqmask[port]; |
2090 | skge_write32(hw, B0_IMSK, hw->intr_mask); | 2157 | skge_write32(hw, B0_IMSK, hw->intr_mask); |
2091 | 2158 | ||
2092 | /* Initialze MAC */ | 2159 | /* Initialize MAC */ |
2093 | spin_lock_bh(&hw->phy_lock); | 2160 | spin_lock_bh(&hw->phy_lock); |
2094 | if (hw->chip_id == CHIP_ID_GENESIS) | 2161 | if (hw->chip_id == CHIP_ID_GENESIS) |
2095 | genesis_mac_init(hw, port); | 2162 | genesis_mac_init(hw, port); |
@@ -2409,7 +2476,7 @@ static void yukon_set_multicast(struct net_device *dev) | |||
2409 | reg = gma_read16(hw, port, GM_RX_CTRL); | 2476 | reg = gma_read16(hw, port, GM_RX_CTRL); |
2410 | reg |= GM_RXCR_UCF_ENA; | 2477 | reg |= GM_RXCR_UCF_ENA; |
2411 | 2478 | ||
2412 | if (dev->flags & IFF_PROMISC) /* promiscious */ | 2479 | if (dev->flags & IFF_PROMISC) /* promiscuous */ |
2413 | reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); | 2480 | reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); |
2414 | else if (dev->flags & IFF_ALLMULTI) /* all multicast */ | 2481 | else if (dev->flags & IFF_ALLMULTI) /* all multicast */ |
2415 | memset(filter, 0xff, sizeof(filter)); | 2482 | memset(filter, 0xff, sizeof(filter)); |
@@ -2560,7 +2627,7 @@ static int skge_poll(struct net_device *dev, int *budget) | |||
2560 | unsigned int to_do = min(dev->quota, *budget); | 2627 | unsigned int to_do = min(dev->quota, *budget); |
2561 | unsigned int work_done = 0; | 2628 | unsigned int work_done = 0; |
2562 | 2629 | ||
2563 | for (e = ring->to_clean; work_done < to_do; e = e->next) { | 2630 | for (e = ring->to_clean; prefetch(e->next), work_done < to_do; e = e->next) { |
2564 | struct skge_rx_desc *rd = e->desc; | 2631 | struct skge_rx_desc *rd = e->desc; |
2565 | struct sk_buff *skb; | 2632 | struct sk_buff *skb; |
2566 | u32 control; | 2633 | u32 control; |
@@ -2593,11 +2660,11 @@ static int skge_poll(struct net_device *dev, int *budget) | |||
2593 | if (work_done >= to_do) | 2660 | if (work_done >= to_do) |
2594 | return 1; /* not done */ | 2661 | return 1; /* not done */ |
2595 | 2662 | ||
2596 | local_irq_disable(); | 2663 | netif_rx_complete(dev); |
2597 | __netif_rx_complete(dev); | ||
2598 | hw->intr_mask |= portirqmask[skge->port]; | 2664 | hw->intr_mask |= portirqmask[skge->port]; |
2599 | skge_write32(hw, B0_IMSK, hw->intr_mask); | 2665 | skge_write32(hw, B0_IMSK, hw->intr_mask); |
2600 | local_irq_enable(); | 2666 | skge_read32(hw, B0_IMSK); |
2667 | |||
2601 | return 0; | 2668 | return 0; |
2602 | } | 2669 | } |
2603 | 2670 | ||
@@ -2609,7 +2676,7 @@ static inline void skge_tx_intr(struct net_device *dev) | |||
2609 | struct skge_element *e; | 2676 | struct skge_element *e; |
2610 | 2677 | ||
2611 | spin_lock(&skge->tx_lock); | 2678 | spin_lock(&skge->tx_lock); |
2612 | for (e = ring->to_clean; e != ring->to_use; e = e->next) { | 2679 | for (e = ring->to_clean; prefetch(e->next), e != ring->to_use; e = e->next) { |
2613 | struct skge_tx_desc *td = e->desc; | 2680 | struct skge_tx_desc *td = e->desc; |
2614 | u32 control; | 2681 | u32 control; |
2615 | 2682 | ||
@@ -2732,7 +2799,7 @@ static void skge_error_irq(struct skge_hw *hw) | |||
2732 | } | 2799 | } |
2733 | 2800 | ||
2734 | /* | 2801 | /* |
2735 | * Interrrupt from PHY are handled in tasklet (soft irq) | 2802 | * Interrupt from PHY are handled in tasklet (soft irq) |
2736 | * because accessing phy registers requires spin wait which might | 2803 | * because accessing phy registers requires spin wait which might |
2737 | * cause excess interrupt latency. | 2804 | * cause excess interrupt latency. |
2738 | */ | 2805 | */ |
@@ -2762,6 +2829,14 @@ static void skge_extirq(unsigned long data) | |||
2762 | local_irq_enable(); | 2829 | local_irq_enable(); |
2763 | } | 2830 | } |
2764 | 2831 | ||
2832 | static inline void skge_wakeup(struct net_device *dev) | ||
2833 | { | ||
2834 | struct skge_port *skge = netdev_priv(dev); | ||
2835 | |||
2836 | prefetch(skge->rx_ring.to_clean); | ||
2837 | netif_rx_schedule(dev); | ||
2838 | } | ||
2839 | |||
2765 | static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) | 2840 | static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) |
2766 | { | 2841 | { |
2767 | struct skge_hw *hw = dev_id; | 2842 | struct skge_hw *hw = dev_id; |
@@ -2773,12 +2848,12 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
2773 | status &= hw->intr_mask; | 2848 | status &= hw->intr_mask; |
2774 | if (status & IS_R1_F) { | 2849 | if (status & IS_R1_F) { |
2775 | hw->intr_mask &= ~IS_R1_F; | 2850 | hw->intr_mask &= ~IS_R1_F; |
2776 | netif_rx_schedule(hw->dev[0]); | 2851 | skge_wakeup(hw->dev[0]); |
2777 | } | 2852 | } |
2778 | 2853 | ||
2779 | if (status & IS_R2_F) { | 2854 | if (status & IS_R2_F) { |
2780 | hw->intr_mask &= ~IS_R2_F; | 2855 | hw->intr_mask &= ~IS_R2_F; |
2781 | netif_rx_schedule(hw->dev[1]); | 2856 | skge_wakeup(hw->dev[1]); |
2782 | } | 2857 | } |
2783 | 2858 | ||
2784 | if (status & IS_XA1_F) | 2859 | if (status & IS_XA1_F) |
@@ -2893,6 +2968,7 @@ static const char *skge_board_name(const struct skge_hw *hw) | |||
2893 | */ | 2968 | */ |
2894 | static int skge_reset(struct skge_hw *hw) | 2969 | static int skge_reset(struct skge_hw *hw) |
2895 | { | 2970 | { |
2971 | u32 reg; | ||
2896 | u16 ctst; | 2972 | u16 ctst; |
2897 | u8 t8, mac_cfg, pmd_type, phy_type; | 2973 | u8 t8, mac_cfg, pmd_type, phy_type; |
2898 | int i; | 2974 | int i; |
@@ -2971,6 +3047,7 @@ static int skge_reset(struct skge_hw *hw) | |||
2971 | /* switch power to VCC (WA for VAUX problem) */ | 3047 | /* switch power to VCC (WA for VAUX problem) */ |
2972 | skge_write8(hw, B0_POWER_CTRL, | 3048 | skge_write8(hw, B0_POWER_CTRL, |
2973 | PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON); | 3049 | PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON); |
3050 | |||
2974 | /* avoid boards with stuck Hardware error bits */ | 3051 | /* avoid boards with stuck Hardware error bits */ |
2975 | if ((skge_read32(hw, B0_ISRC) & IS_HW_ERR) && | 3052 | if ((skge_read32(hw, B0_ISRC) & IS_HW_ERR) && |
2976 | (skge_read32(hw, B0_HWE_ISRC) & IS_IRQ_SENSOR)) { | 3053 | (skge_read32(hw, B0_HWE_ISRC) & IS_IRQ_SENSOR)) { |
@@ -2978,6 +3055,14 @@ static int skge_reset(struct skge_hw *hw) | |||
2978 | hw->intr_mask &= ~IS_HW_ERR; | 3055 | hw->intr_mask &= ~IS_HW_ERR; |
2979 | } | 3056 | } |
2980 | 3057 | ||
3058 | /* Clear PHY COMA */ | ||
3059 | skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); | ||
3060 | pci_read_config_dword(hw->pdev, PCI_DEV_REG1, ®); | ||
3061 | reg &= ~PCI_PHY_COMA; | ||
3062 | pci_write_config_dword(hw->pdev, PCI_DEV_REG1, reg); | ||
3063 | skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); | ||
3064 | |||
3065 | |||
2981 | for (i = 0; i < hw->ports; i++) { | 3066 | for (i = 0; i < hw->ports; i++) { |
2982 | skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET); | 3067 | skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET); |
2983 | skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR); | 3068 | skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR); |
@@ -3048,6 +3133,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, | |||
3048 | SET_NETDEV_DEV(dev, &hw->pdev->dev); | 3133 | SET_NETDEV_DEV(dev, &hw->pdev->dev); |
3049 | dev->open = skge_up; | 3134 | dev->open = skge_up; |
3050 | dev->stop = skge_down; | 3135 | dev->stop = skge_down; |
3136 | dev->do_ioctl = skge_ioctl; | ||
3051 | dev->hard_start_xmit = skge_xmit_frame; | 3137 | dev->hard_start_xmit = skge_xmit_frame; |
3052 | dev->get_stats = skge_get_stats; | 3138 | dev->get_stats = skge_get_stats; |
3053 | if (hw->chip_id == CHIP_ID_GENESIS) | 3139 | if (hw->chip_id == CHIP_ID_GENESIS) |
@@ -3147,7 +3233,7 @@ static int __devinit skge_probe(struct pci_dev *pdev, | |||
3147 | } | 3233 | } |
3148 | 3234 | ||
3149 | #ifdef __BIG_ENDIAN | 3235 | #ifdef __BIG_ENDIAN |
3150 | /* byte swap decriptors in hardware */ | 3236 | /* byte swap descriptors in hardware */ |
3151 | { | 3237 | { |
3152 | u32 reg; | 3238 | u32 reg; |
3153 | 3239 | ||
@@ -3158,14 +3244,13 @@ static int __devinit skge_probe(struct pci_dev *pdev, | |||
3158 | #endif | 3244 | #endif |
3159 | 3245 | ||
3160 | err = -ENOMEM; | 3246 | err = -ENOMEM; |
3161 | hw = kmalloc(sizeof(*hw), GFP_KERNEL); | 3247 | hw = kzalloc(sizeof(*hw), GFP_KERNEL); |
3162 | if (!hw) { | 3248 | if (!hw) { |
3163 | printk(KERN_ERR PFX "%s: cannot allocate hardware struct\n", | 3249 | printk(KERN_ERR PFX "%s: cannot allocate hardware struct\n", |
3164 | pci_name(pdev)); | 3250 | pci_name(pdev)); |
3165 | goto err_out_free_regions; | 3251 | goto err_out_free_regions; |
3166 | } | 3252 | } |
3167 | 3253 | ||
3168 | memset(hw, 0, sizeof(*hw)); | ||
3169 | hw->pdev = pdev; | 3254 | hw->pdev = pdev; |
3170 | spin_lock_init(&hw->phy_lock); | 3255 | spin_lock_init(&hw->phy_lock); |
3171 | tasklet_init(&hw->ext_tasklet, skge_extirq, (unsigned long) hw); | 3256 | tasklet_init(&hw->ext_tasklet, skge_extirq, (unsigned long) hw); |
@@ -3188,7 +3273,7 @@ static int __devinit skge_probe(struct pci_dev *pdev, | |||
3188 | if (err) | 3273 | if (err) |
3189 | goto err_out_free_irq; | 3274 | goto err_out_free_irq; |
3190 | 3275 | ||
3191 | printk(KERN_INFO PFX "addr 0x%lx irq %d chip %s rev %d\n", | 3276 | printk(KERN_INFO PFX DRV_VERSION " addr 0x%lx irq %d chip %s rev %d\n", |
3192 | pci_resource_start(pdev, 0), pdev->irq, | 3277 | pci_resource_start(pdev, 0), pdev->irq, |
3193 | skge_board_name(hw), hw->chip_rev); | 3278 | skge_board_name(hw), hw->chip_rev); |
3194 | 3279 | ||