diff options
Diffstat (limited to 'drivers/net/skge.c')
-rw-r--r-- | drivers/net/skge.c | 233 |
1 files changed, 108 insertions, 125 deletions
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 5cacc7ad9e79..f15739481d62 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.7" | 45 | #define DRV_VERSION "0.8" |
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 |
@@ -55,7 +55,7 @@ | |||
55 | #define ETH_JUMBO_MTU 9000 | 55 | #define ETH_JUMBO_MTU 9000 |
56 | #define TX_WATCHDOG (5 * HZ) | 56 | #define TX_WATCHDOG (5 * HZ) |
57 | #define NAPI_WEIGHT 64 | 57 | #define NAPI_WEIGHT 64 |
58 | #define BLINK_HZ (HZ/4) | 58 | #define BLINK_MS 250 |
59 | 59 | ||
60 | MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver"); | 60 | MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver"); |
61 | MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>"); | 61 | MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>"); |
@@ -75,7 +75,6 @@ static const struct pci_device_id skge_id_table[] = { | |||
75 | { PCI_DEVICE(PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940B) }, | 75 | { PCI_DEVICE(PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940B) }, |
76 | { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE) }, | 76 | { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE) }, |
77 | { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_YU) }, | 77 | { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_YU) }, |
78 | { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, /* SK-9Exx */ | ||
79 | { PCI_DEVICE(PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_DGE510T), }, | 78 | { PCI_DEVICE(PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_DGE510T), }, |
80 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4320) }, | 79 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4320) }, |
81 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5005) }, /* Belkin */ | 80 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5005) }, /* Belkin */ |
@@ -249,7 +248,7 @@ static int skge_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) | |||
249 | } else { | 248 | } else { |
250 | u32 setting; | 249 | u32 setting; |
251 | 250 | ||
252 | switch(ecmd->speed) { | 251 | switch (ecmd->speed) { |
253 | case SPEED_1000: | 252 | case SPEED_1000: |
254 | if (ecmd->duplex == DUPLEX_FULL) | 253 | if (ecmd->duplex == DUPLEX_FULL) |
255 | setting = SUPPORTED_1000baseT_Full; | 254 | setting = SUPPORTED_1000baseT_Full; |
@@ -620,84 +619,98 @@ static int skge_set_coalesce(struct net_device *dev, | |||
620 | return 0; | 619 | return 0; |
621 | } | 620 | } |
622 | 621 | ||
623 | static void skge_led_on(struct skge_hw *hw, int port) | 622 | enum led_mode { LED_MODE_OFF, LED_MODE_ON, LED_MODE_TST }; |
623 | static void skge_led(struct skge_port *skge, enum led_mode mode) | ||
624 | { | 624 | { |
625 | struct skge_hw *hw = skge->hw; | ||
626 | int port = skge->port; | ||
627 | |||
628 | spin_lock_bh(&hw->phy_lock); | ||
625 | if (hw->chip_id == CHIP_ID_GENESIS) { | 629 | if (hw->chip_id == CHIP_ID_GENESIS) { |
626 | skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON); | 630 | switch (mode) { |
627 | skge_write8(hw, B0_LED, LED_STAT_ON); | 631 | case LED_MODE_OFF: |
632 | xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_OFF); | ||
633 | skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF); | ||
634 | skge_write32(hw, SK_REG(port, RX_LED_VAL), 0); | ||
635 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_T_OFF); | ||
636 | break; | ||
628 | 637 | ||
629 | skge_write8(hw, SK_REG(port, RX_LED_TST), LED_T_ON); | 638 | case LED_MODE_ON: |
630 | skge_write32(hw, SK_REG(port, RX_LED_VAL), 100); | 639 | skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON); |
631 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START); | 640 | skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_LINKSYNC_ON); |
632 | 641 | ||
633 | /* For Broadcom Phy only */ | 642 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START); |
634 | xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_ON); | 643 | skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_START); |
635 | } else { | ||
636 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); | ||
637 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, | ||
638 | PHY_M_LED_MO_DUP(MO_LED_ON) | | ||
639 | PHY_M_LED_MO_10(MO_LED_ON) | | ||
640 | PHY_M_LED_MO_100(MO_LED_ON) | | ||
641 | PHY_M_LED_MO_1000(MO_LED_ON) | | ||
642 | PHY_M_LED_MO_RX(MO_LED_ON)); | ||
643 | } | ||
644 | } | ||
645 | 644 | ||
646 | static void skge_led_off(struct skge_hw *hw, int port) | 645 | break; |
647 | { | ||
648 | if (hw->chip_id == CHIP_ID_GENESIS) { | ||
649 | skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF); | ||
650 | skge_write8(hw, B0_LED, LED_STAT_OFF); | ||
651 | 646 | ||
652 | skge_write32(hw, SK_REG(port, RX_LED_VAL), 0); | 647 | case LED_MODE_TST: |
653 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_T_OFF); | 648 | skge_write8(hw, SK_REG(port, RX_LED_TST), LED_T_ON); |
649 | skge_write32(hw, SK_REG(port, RX_LED_VAL), 100); | ||
650 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START); | ||
654 | 651 | ||
655 | /* Broadcom only */ | 652 | xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_ON); |
656 | xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_OFF); | 653 | break; |
654 | } | ||
657 | } else { | 655 | } else { |
658 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); | 656 | switch (mode) { |
659 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, | 657 | case LED_MODE_OFF: |
660 | PHY_M_LED_MO_DUP(MO_LED_OFF) | | 658 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); |
661 | PHY_M_LED_MO_10(MO_LED_OFF) | | 659 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, |
662 | PHY_M_LED_MO_100(MO_LED_OFF) | | 660 | PHY_M_LED_MO_DUP(MO_LED_OFF) | |
663 | PHY_M_LED_MO_1000(MO_LED_OFF) | | 661 | PHY_M_LED_MO_10(MO_LED_OFF) | |
664 | PHY_M_LED_MO_RX(MO_LED_OFF)); | 662 | PHY_M_LED_MO_100(MO_LED_OFF) | |
663 | PHY_M_LED_MO_1000(MO_LED_OFF) | | ||
664 | PHY_M_LED_MO_RX(MO_LED_OFF)); | ||
665 | break; | ||
666 | case LED_MODE_ON: | ||
667 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, | ||
668 | PHY_M_LED_PULS_DUR(PULS_170MS) | | ||
669 | PHY_M_LED_BLINK_RT(BLINK_84MS) | | ||
670 | PHY_M_LEDC_TX_CTRL | | ||
671 | PHY_M_LEDC_DP_CTRL); | ||
672 | |||
673 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, | ||
674 | PHY_M_LED_MO_RX(MO_LED_OFF) | | ||
675 | (skge->speed == SPEED_100 ? | ||
676 | PHY_M_LED_MO_100(MO_LED_ON) : 0)); | ||
677 | break; | ||
678 | case LED_MODE_TST: | ||
679 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); | ||
680 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, | ||
681 | PHY_M_LED_MO_DUP(MO_LED_ON) | | ||
682 | PHY_M_LED_MO_10(MO_LED_ON) | | ||
683 | PHY_M_LED_MO_100(MO_LED_ON) | | ||
684 | PHY_M_LED_MO_1000(MO_LED_ON) | | ||
685 | PHY_M_LED_MO_RX(MO_LED_ON)); | ||
686 | } | ||
665 | } | 687 | } |
666 | } | 688 | spin_unlock_bh(&hw->phy_lock); |
667 | |||
668 | static void skge_blink_timer(unsigned long data) | ||
669 | { | ||
670 | struct skge_port *skge = (struct skge_port *) data; | ||
671 | struct skge_hw *hw = skge->hw; | ||
672 | unsigned long flags; | ||
673 | |||
674 | spin_lock_irqsave(&hw->phy_lock, flags); | ||
675 | if (skge->blink_on) | ||
676 | skge_led_on(hw, skge->port); | ||
677 | else | ||
678 | skge_led_off(hw, skge->port); | ||
679 | spin_unlock_irqrestore(&hw->phy_lock, flags); | ||
680 | |||
681 | skge->blink_on = !skge->blink_on; | ||
682 | mod_timer(&skge->led_blink, jiffies + BLINK_HZ); | ||
683 | } | 689 | } |
684 | 690 | ||
685 | /* blink LED's for finding board */ | 691 | /* blink LED's for finding board */ |
686 | static int skge_phys_id(struct net_device *dev, u32 data) | 692 | static int skge_phys_id(struct net_device *dev, u32 data) |
687 | { | 693 | { |
688 | struct skge_port *skge = netdev_priv(dev); | 694 | struct skge_port *skge = netdev_priv(dev); |
695 | unsigned long ms; | ||
696 | enum led_mode mode = LED_MODE_TST; | ||
689 | 697 | ||
690 | if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ)) | 698 | if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ)) |
691 | data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ); | 699 | ms = jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT / HZ) * 1000; |
700 | else | ||
701 | ms = data * 1000; | ||
692 | 702 | ||
693 | /* start blinking */ | 703 | while (ms > 0) { |
694 | skge->blink_on = 1; | 704 | skge_led(skge, mode); |
695 | mod_timer(&skge->led_blink, jiffies+1); | 705 | mode ^= LED_MODE_TST; |
696 | 706 | ||
697 | msleep_interruptible(data * 1000); | 707 | if (msleep_interruptible(BLINK_MS)) |
698 | del_timer_sync(&skge->led_blink); | 708 | break; |
709 | ms -= BLINK_MS; | ||
710 | } | ||
699 | 711 | ||
700 | skge_led_off(skge->hw, skge->port); | 712 | /* back to regular LED state */ |
713 | skge_led(skge, netif_running(dev) ? LED_MODE_ON : LED_MODE_OFF); | ||
701 | 714 | ||
702 | return 0; | 715 | return 0; |
703 | } | 716 | } |
@@ -1028,7 +1041,7 @@ static void bcom_check_link(struct skge_hw *hw, int port) | |||
1028 | } | 1041 | } |
1029 | 1042 | ||
1030 | /* Check Duplex mismatch */ | 1043 | /* Check Duplex mismatch */ |
1031 | switch(aux & PHY_B_AS_AN_RES_MSK) { | 1044 | switch (aux & PHY_B_AS_AN_RES_MSK) { |
1032 | case PHY_B_RES_1000FD: | 1045 | case PHY_B_RES_1000FD: |
1033 | skge->duplex = DUPLEX_FULL; | 1046 | skge->duplex = DUPLEX_FULL; |
1034 | break; | 1047 | break; |
@@ -1099,7 +1112,7 @@ static void bcom_phy_init(struct skge_port *skge, int jumbo) | |||
1099 | r |= XM_MMU_NO_PRE; | 1112 | r |= XM_MMU_NO_PRE; |
1100 | xm_write16(hw, port, XM_MMU_CMD,r); | 1113 | xm_write16(hw, port, XM_MMU_CMD,r); |
1101 | 1114 | ||
1102 | switch(id1) { | 1115 | switch (id1) { |
1103 | case PHY_BCOM_ID1_C0: | 1116 | case PHY_BCOM_ID1_C0: |
1104 | /* | 1117 | /* |
1105 | * Workaround BCOM Errata for the C0 type. | 1118 | * Workaround BCOM Errata for the C0 type. |
@@ -1194,13 +1207,6 @@ static void genesis_mac_init(struct skge_hw *hw, int port) | |||
1194 | xm_write16(hw, port, XM_STAT_CMD, | 1207 | xm_write16(hw, port, XM_STAT_CMD, |
1195 | XM_SC_CLR_RXC | XM_SC_CLR_TXC); | 1208 | XM_SC_CLR_RXC | XM_SC_CLR_TXC); |
1196 | 1209 | ||
1197 | /* initialize Rx, Tx and Link LED */ | ||
1198 | skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON); | ||
1199 | skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_LINKSYNC_ON); | ||
1200 | |||
1201 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START); | ||
1202 | skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_START); | ||
1203 | |||
1204 | /* Unreset the XMAC. */ | 1210 | /* Unreset the XMAC. */ |
1205 | skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_CLR_MAC_RST); | 1211 | skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_CLR_MAC_RST); |
1206 | 1212 | ||
@@ -1209,7 +1215,6 @@ static void genesis_mac_init(struct skge_hw *hw, int port) | |||
1209 | * namely for the 1000baseTX cards that use the XMAC's | 1215 | * namely for the 1000baseTX cards that use the XMAC's |
1210 | * GMII mode. | 1216 | * GMII mode. |
1211 | */ | 1217 | */ |
1212 | spin_lock_bh(&hw->phy_lock); | ||
1213 | /* Take external Phy out of reset */ | 1218 | /* Take external Phy out of reset */ |
1214 | r = skge_read32(hw, B2_GP_IO); | 1219 | r = skge_read32(hw, B2_GP_IO); |
1215 | if (port == 0) | 1220 | if (port == 0) |
@@ -1219,7 +1224,6 @@ static void genesis_mac_init(struct skge_hw *hw, int port) | |||
1219 | 1224 | ||
1220 | skge_write32(hw, B2_GP_IO, r); | 1225 | skge_write32(hw, B2_GP_IO, r); |
1221 | skge_read32(hw, B2_GP_IO); | 1226 | skge_read32(hw, B2_GP_IO); |
1222 | spin_unlock_bh(&hw->phy_lock); | ||
1223 | 1227 | ||
1224 | /* Enable GMII interfac */ | 1228 | /* Enable GMII interfac */ |
1225 | xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD); | 1229 | xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD); |
@@ -1569,7 +1573,6 @@ static void yukon_init(struct skge_hw *hw, int port) | |||
1569 | { | 1573 | { |
1570 | struct skge_port *skge = netdev_priv(hw->dev[port]); | 1574 | struct skge_port *skge = netdev_priv(hw->dev[port]); |
1571 | u16 ctrl, ct1000, adv; | 1575 | u16 ctrl, ct1000, adv; |
1572 | u16 ledctrl, ledover; | ||
1573 | 1576 | ||
1574 | pr_debug("yukon_init\n"); | 1577 | pr_debug("yukon_init\n"); |
1575 | if (skge->autoneg == AUTONEG_ENABLE) { | 1578 | if (skge->autoneg == AUTONEG_ENABLE) { |
@@ -1641,32 +1644,11 @@ static void yukon_init(struct skge_hw *hw, int port) | |||
1641 | gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv); | 1644 | gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv); |
1642 | gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl); | 1645 | gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl); |
1643 | 1646 | ||
1644 | /* Setup Phy LED's */ | ||
1645 | ledctrl = PHY_M_LED_PULS_DUR(PULS_170MS); | ||
1646 | ledover = 0; | ||
1647 | |||
1648 | ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL; | ||
1649 | |||
1650 | /* turn off the Rx LED (LED_RX) */ | ||
1651 | ledover |= PHY_M_LED_MO_RX(MO_LED_OFF); | ||
1652 | |||
1653 | /* disable blink mode (LED_DUPLEX) on collisions */ | ||
1654 | ctrl |= PHY_M_LEDC_DP_CTRL; | ||
1655 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); | ||
1656 | |||
1657 | if (skge->autoneg == AUTONEG_DISABLE || skge->speed == SPEED_100) { | ||
1658 | /* turn on 100 Mbps LED (LED_LINK100) */ | ||
1659 | ledover |= PHY_M_LED_MO_100(MO_LED_ON); | ||
1660 | } | ||
1661 | |||
1662 | if (ledover) | ||
1663 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover); | ||
1664 | |||
1665 | /* Enable phy interrupt on autonegotiation complete (or link up) */ | 1647 | /* Enable phy interrupt on autonegotiation complete (or link up) */ |
1666 | if (skge->autoneg == AUTONEG_ENABLE) | 1648 | if (skge->autoneg == AUTONEG_ENABLE) |
1667 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL); | 1649 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_MSK); |
1668 | else | 1650 | else |
1669 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); | 1651 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_DEF_MSK); |
1670 | } | 1652 | } |
1671 | 1653 | ||
1672 | static void yukon_reset(struct skge_hw *hw, int port) | 1654 | static void yukon_reset(struct skge_hw *hw, int port) |
@@ -1691,7 +1673,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port) | |||
1691 | 1673 | ||
1692 | /* WA code for COMA mode -- set PHY reset */ | 1674 | /* WA code for COMA mode -- set PHY reset */ |
1693 | if (hw->chip_id == CHIP_ID_YUKON_LITE && | 1675 | if (hw->chip_id == CHIP_ID_YUKON_LITE && |
1694 | hw->chip_rev == CHIP_REV_YU_LITE_A3) | 1676 | hw->chip_rev >= CHIP_REV_YU_LITE_A3) |
1695 | skge_write32(hw, B2_GP_IO, | 1677 | skge_write32(hw, B2_GP_IO, |
1696 | (skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9)); | 1678 | (skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9)); |
1697 | 1679 | ||
@@ -1701,7 +1683,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port) | |||
1701 | 1683 | ||
1702 | /* WA code for COMA mode -- clear PHY reset */ | 1684 | /* WA code for COMA mode -- clear PHY reset */ |
1703 | if (hw->chip_id == CHIP_ID_YUKON_LITE && | 1685 | if (hw->chip_id == CHIP_ID_YUKON_LITE && |
1704 | hw->chip_rev == CHIP_REV_YU_LITE_A3) | 1686 | hw->chip_rev >= CHIP_REV_YU_LITE_A3) |
1705 | skge_write32(hw, B2_GP_IO, | 1687 | skge_write32(hw, B2_GP_IO, |
1706 | (skge_read32(hw, B2_GP_IO) | GP_DIR_9) | 1688 | (skge_read32(hw, B2_GP_IO) | GP_DIR_9) |
1707 | & ~GP_IO_9); | 1689 | & ~GP_IO_9); |
@@ -1745,9 +1727,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port) | |||
1745 | gma_write16(hw, port, GM_GP_CTRL, reg); | 1727 | gma_write16(hw, port, GM_GP_CTRL, reg); |
1746 | skge_read16(hw, GMAC_IRQ_SRC); | 1728 | skge_read16(hw, GMAC_IRQ_SRC); |
1747 | 1729 | ||
1748 | spin_lock_bh(&hw->phy_lock); | ||
1749 | yukon_init(hw, port); | 1730 | yukon_init(hw, port); |
1750 | spin_unlock_bh(&hw->phy_lock); | ||
1751 | 1731 | ||
1752 | /* MIB clear */ | 1732 | /* MIB clear */ |
1753 | reg = gma_read16(hw, port, GM_PHY_ADDR); | 1733 | reg = gma_read16(hw, port, GM_PHY_ADDR); |
@@ -1796,7 +1776,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port) | |||
1796 | skge_write16(hw, SK_REG(port, RX_GMF_FL_MSK), RX_FF_FL_DEF_MSK); | 1776 | skge_write16(hw, SK_REG(port, RX_GMF_FL_MSK), RX_FF_FL_DEF_MSK); |
1797 | reg = GMF_OPER_ON | GMF_RX_F_FL_ON; | 1777 | reg = GMF_OPER_ON | GMF_RX_F_FL_ON; |
1798 | if (hw->chip_id == CHIP_ID_YUKON_LITE && | 1778 | if (hw->chip_id == CHIP_ID_YUKON_LITE && |
1799 | hw->chip_rev == CHIP_REV_YU_LITE_A3) | 1779 | hw->chip_rev >= CHIP_REV_YU_LITE_A3) |
1800 | reg &= ~GMF_RX_F_FL_ON; | 1780 | reg &= ~GMF_RX_F_FL_ON; |
1801 | skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); | 1781 | skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); |
1802 | skge_write16(hw, SK_REG(port, RX_GMF_CTRL_T), reg); | 1782 | skge_write16(hw, SK_REG(port, RX_GMF_CTRL_T), reg); |
@@ -1813,19 +1793,19 @@ static void yukon_stop(struct skge_port *skge) | |||
1813 | int port = skge->port; | 1793 | int port = skge->port; |
1814 | 1794 | ||
1815 | if (hw->chip_id == CHIP_ID_YUKON_LITE && | 1795 | if (hw->chip_id == CHIP_ID_YUKON_LITE && |
1816 | hw->chip_rev == CHIP_REV_YU_LITE_A3) { | 1796 | hw->chip_rev >= CHIP_REV_YU_LITE_A3) { |
1817 | skge_write32(hw, B2_GP_IO, | 1797 | skge_write32(hw, B2_GP_IO, |
1818 | skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9); | 1798 | skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9); |
1819 | } | 1799 | } |
1820 | 1800 | ||
1821 | gma_write16(hw, port, GM_GP_CTRL, | 1801 | gma_write16(hw, port, GM_GP_CTRL, |
1822 | gma_read16(hw, port, GM_GP_CTRL) | 1802 | gma_read16(hw, port, GM_GP_CTRL) |
1823 | & ~(GM_GPCR_RX_ENA|GM_GPCR_RX_ENA)); | 1803 | & ~(GM_GPCR_TX_ENA|GM_GPCR_RX_ENA)); |
1824 | gma_read16(hw, port, GM_GP_CTRL); | 1804 | gma_read16(hw, port, GM_GP_CTRL); |
1825 | 1805 | ||
1826 | /* set GPHY Control reset */ | 1806 | /* set GPHY Control reset */ |
1827 | gma_write32(hw, port, GPHY_CTRL, GPC_RST_SET); | 1807 | skge_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); |
1828 | gma_write32(hw, port, GMAC_CTRL, GMC_RST_SET); | 1808 | skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET); |
1829 | } | 1809 | } |
1830 | 1810 | ||
1831 | static void yukon_get_stats(struct skge_port *skge, u64 *data) | 1811 | static void yukon_get_stats(struct skge_port *skge, u64 *data) |
@@ -1856,11 +1836,12 @@ static void yukon_mac_intr(struct skge_hw *hw, int port) | |||
1856 | 1836 | ||
1857 | if (status & GM_IS_RX_FF_OR) { | 1837 | if (status & GM_IS_RX_FF_OR) { |
1858 | ++skge->net_stats.rx_fifo_errors; | 1838 | ++skge->net_stats.rx_fifo_errors; |
1859 | gma_write8(hw, port, RX_GMF_CTRL_T, GMF_CLI_RX_FO); | 1839 | skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_CLI_RX_FO); |
1860 | } | 1840 | } |
1841 | |||
1861 | if (status & GM_IS_TX_FF_UR) { | 1842 | if (status & GM_IS_TX_FF_UR) { |
1862 | ++skge->net_stats.tx_fifo_errors; | 1843 | ++skge->net_stats.tx_fifo_errors; |
1863 | gma_write8(hw, port, TX_GMF_CTRL_T, GMF_CLI_TX_FU); | 1844 | skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_CLI_TX_FU); |
1864 | } | 1845 | } |
1865 | 1846 | ||
1866 | } | 1847 | } |
@@ -1896,7 +1877,7 @@ static void yukon_link_up(struct skge_port *skge) | |||
1896 | reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA; | 1877 | reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA; |
1897 | gma_write16(hw, port, GM_GP_CTRL, reg); | 1878 | gma_write16(hw, port, GM_GP_CTRL, reg); |
1898 | 1879 | ||
1899 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); | 1880 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_DEF_MSK); |
1900 | skge_link_up(skge); | 1881 | skge_link_up(skge); |
1901 | } | 1882 | } |
1902 | 1883 | ||
@@ -1904,12 +1885,14 @@ static void yukon_link_down(struct skge_port *skge) | |||
1904 | { | 1885 | { |
1905 | struct skge_hw *hw = skge->hw; | 1886 | struct skge_hw *hw = skge->hw; |
1906 | int port = skge->port; | 1887 | int port = skge->port; |
1888 | u16 ctrl; | ||
1907 | 1889 | ||
1908 | pr_debug("yukon_link_down\n"); | 1890 | pr_debug("yukon_link_down\n"); |
1909 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0); | 1891 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0); |
1910 | gm_phy_write(hw, port, GM_GP_CTRL, | 1892 | |
1911 | gm_phy_read(hw, port, GM_GP_CTRL) | 1893 | ctrl = gma_read16(hw, port, GM_GP_CTRL); |
1912 | & ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA)); | 1894 | ctrl &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA); |
1895 | gma_write16(hw, port, GM_GP_CTRL, ctrl); | ||
1913 | 1896 | ||
1914 | if (skge->flow_control == FLOW_MODE_REM_SEND) { | 1897 | if (skge->flow_control == FLOW_MODE_REM_SEND) { |
1915 | /* restore Asymmetric Pause bit */ | 1898 | /* restore Asymmetric Pause bit */ |
@@ -2097,10 +2080,12 @@ static int skge_up(struct net_device *dev) | |||
2097 | skge_write32(hw, B0_IMSK, hw->intr_mask); | 2080 | skge_write32(hw, B0_IMSK, hw->intr_mask); |
2098 | 2081 | ||
2099 | /* Initialze MAC */ | 2082 | /* Initialze MAC */ |
2083 | spin_lock_bh(&hw->phy_lock); | ||
2100 | if (hw->chip_id == CHIP_ID_GENESIS) | 2084 | if (hw->chip_id == CHIP_ID_GENESIS) |
2101 | genesis_mac_init(hw, port); | 2085 | genesis_mac_init(hw, port); |
2102 | else | 2086 | else |
2103 | yukon_mac_init(hw, port); | 2087 | yukon_mac_init(hw, port); |
2088 | spin_unlock_bh(&hw->phy_lock); | ||
2104 | 2089 | ||
2105 | /* Configure RAMbuffers */ | 2090 | /* Configure RAMbuffers */ |
2106 | chunk = hw->ram_size / ((hw->ports + 1)*2); | 2091 | chunk = hw->ram_size / ((hw->ports + 1)*2); |
@@ -2116,6 +2101,7 @@ static int skge_up(struct net_device *dev) | |||
2116 | /* Start receiver BMU */ | 2101 | /* Start receiver BMU */ |
2117 | wmb(); | 2102 | wmb(); |
2118 | skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_START | CSR_IRQ_CL_F); | 2103 | skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_START | CSR_IRQ_CL_F); |
2104 | skge_led(skge, LED_MODE_ON); | ||
2119 | 2105 | ||
2120 | pr_debug("skge_up completed\n"); | 2106 | pr_debug("skge_up completed\n"); |
2121 | return 0; | 2107 | return 0; |
@@ -2140,8 +2126,6 @@ static int skge_down(struct net_device *dev) | |||
2140 | 2126 | ||
2141 | netif_stop_queue(dev); | 2127 | netif_stop_queue(dev); |
2142 | 2128 | ||
2143 | del_timer_sync(&skge->led_blink); | ||
2144 | |||
2145 | /* Stop transmitter */ | 2129 | /* Stop transmitter */ |
2146 | skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP); | 2130 | skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP); |
2147 | skge_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), | 2131 | skge_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), |
@@ -2175,15 +2159,12 @@ static int skge_down(struct net_device *dev) | |||
2175 | if (hw->chip_id == CHIP_ID_GENESIS) { | 2159 | if (hw->chip_id == CHIP_ID_GENESIS) { |
2176 | skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_RST_SET); | 2160 | skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_RST_SET); |
2177 | skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_RST_SET); | 2161 | skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_RST_SET); |
2178 | skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_STOP); | ||
2179 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_STOP); | ||
2180 | } else { | 2162 | } else { |
2181 | skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); | 2163 | skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); |
2182 | skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); | 2164 | skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); |
2183 | } | 2165 | } |
2184 | 2166 | ||
2185 | /* turn off led's */ | 2167 | skge_led(skge, LED_MODE_OFF); |
2186 | skge_write16(hw, B0_LED, LED_STAT_OFF); | ||
2187 | 2168 | ||
2188 | skge_tx_clean(skge); | 2169 | skge_tx_clean(skge); |
2189 | skge_rx_clean(skge); | 2170 | skge_rx_clean(skge); |
@@ -2633,11 +2614,17 @@ static inline void skge_tx_intr(struct net_device *dev) | |||
2633 | spin_unlock(&skge->tx_lock); | 2614 | spin_unlock(&skge->tx_lock); |
2634 | } | 2615 | } |
2635 | 2616 | ||
2617 | /* Parity errors seem to happen when Genesis is connected to a switch | ||
2618 | * with no other ports present. Heartbeat error?? | ||
2619 | */ | ||
2636 | static void skge_mac_parity(struct skge_hw *hw, int port) | 2620 | static void skge_mac_parity(struct skge_hw *hw, int port) |
2637 | { | 2621 | { |
2638 | printk(KERN_ERR PFX "%s: mac data parity error\n", | 2622 | struct net_device *dev = hw->dev[port]; |
2639 | hw->dev[port] ? hw->dev[port]->name | 2623 | |
2640 | : (port == 0 ? "(port A)": "(port B")); | 2624 | if (dev) { |
2625 | struct skge_port *skge = netdev_priv(dev); | ||
2626 | ++skge->net_stats.tx_heartbeat_errors; | ||
2627 | } | ||
2641 | 2628 | ||
2642 | if (hw->chip_id == CHIP_ID_GENESIS) | 2629 | if (hw->chip_id == CHIP_ID_GENESIS) |
2643 | skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), | 2630 | skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), |
@@ -3083,10 +3070,6 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, | |||
3083 | 3070 | ||
3084 | spin_lock_init(&skge->tx_lock); | 3071 | spin_lock_init(&skge->tx_lock); |
3085 | 3072 | ||
3086 | init_timer(&skge->led_blink); | ||
3087 | skge->led_blink.function = skge_blink_timer; | ||
3088 | skge->led_blink.data = (unsigned long) skge; | ||
3089 | |||
3090 | if (hw->chip_id != CHIP_ID_GENESIS) { | 3073 | if (hw->chip_id != CHIP_ID_GENESIS) { |
3091 | dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; | 3074 | dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; |
3092 | skge->rx_csum = 1; | 3075 | skge->rx_csum = 1; |