diff options
author | Stephen Hemminger <shemminger@osdl.org> | 2005-07-22 19:26:10 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-07-31 00:40:54 -0400 |
commit | 6abebb538d317ead09cc0f3c2a0752047f9ff961 (patch) | |
tree | 82c60d2629615bec70b149ada645a2399af4a9e8 /drivers/net/skge.c | |
parent | 4cde06ed0fb58402ec1d6d117122d1058983a393 (diff) |
[PATCH] skge: led toggle cleanup
Cleanup code that is used to toggle LED's. Since we
get called from ethtool, can use that thread rather than
setting up a timer.
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/net/skge.c')
-rw-r--r-- | drivers/net/skge.c | 170 |
1 files changed, 74 insertions, 96 deletions
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 43a275d97107..6b889a346a16 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
@@ -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>"); |
@@ -619,83 +619,98 @@ static int skge_set_coalesce(struct net_device *dev, | |||
619 | return 0; | 619 | return 0; |
620 | } | 620 | } |
621 | 621 | ||
622 | 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) | ||
623 | { | 624 | { |
625 | struct skge_hw *hw = skge->hw; | ||
626 | int port = skge->port; | ||
627 | |||
628 | spin_lock_bh(&hw->phy_lock); | ||
624 | if (hw->chip_id == CHIP_ID_GENESIS) { | 629 | if (hw->chip_id == CHIP_ID_GENESIS) { |
625 | skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON); | 630 | switch (mode) { |
626 | 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; | ||
627 | 637 | ||
628 | skge_write8(hw, SK_REG(port, RX_LED_TST), LED_T_ON); | 638 | case LED_MODE_ON: |
629 | skge_write32(hw, SK_REG(port, RX_LED_VAL), 100); | 639 | skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON); |
630 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START); | 640 | skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_LINKSYNC_ON); |
631 | 641 | ||
632 | /* For Broadcom Phy only */ | 642 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START); |
633 | 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); |
634 | } else { | ||
635 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); | ||
636 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, | ||
637 | PHY_M_LED_MO_DUP(MO_LED_ON) | | ||
638 | PHY_M_LED_MO_10(MO_LED_ON) | | ||
639 | PHY_M_LED_MO_100(MO_LED_ON) | | ||
640 | PHY_M_LED_MO_1000(MO_LED_ON) | | ||
641 | PHY_M_LED_MO_RX(MO_LED_ON)); | ||
642 | } | ||
643 | } | ||
644 | 644 | ||
645 | static void skge_led_off(struct skge_hw *hw, int port) | 645 | break; |
646 | { | ||
647 | if (hw->chip_id == CHIP_ID_GENESIS) { | ||
648 | skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF); | ||
649 | skge_write8(hw, B0_LED, LED_STAT_OFF); | ||
650 | 646 | ||
651 | skge_write32(hw, SK_REG(port, RX_LED_VAL), 0); | 647 | case LED_MODE_TST: |
652 | 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); | ||
653 | 651 | ||
654 | /* Broadcom only */ | 652 | xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_ON); |
655 | xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_OFF); | 653 | break; |
654 | } | ||
656 | } else { | 655 | } else { |
657 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); | 656 | switch (mode) { |
658 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, | 657 | case LED_MODE_OFF: |
659 | PHY_M_LED_MO_DUP(MO_LED_OFF) | | 658 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); |
660 | PHY_M_LED_MO_10(MO_LED_OFF) | | 659 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, |
661 | PHY_M_LED_MO_100(MO_LED_OFF) | | 660 | PHY_M_LED_MO_DUP(MO_LED_OFF) | |
662 | PHY_M_LED_MO_1000(MO_LED_OFF) | | 661 | PHY_M_LED_MO_10(MO_LED_OFF) | |
663 | 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 | } | ||
664 | } | 687 | } |
665 | } | ||
666 | |||
667 | static void skge_blink_timer(unsigned long data) | ||
668 | { | ||
669 | struct skge_port *skge = (struct skge_port *) data; | ||
670 | struct skge_hw *hw = skge->hw; | ||
671 | |||
672 | spin_lock_bh(&hw->phy_lock); | ||
673 | if (skge->blink_on) | ||
674 | skge_led_on(hw, skge->port); | ||
675 | else | ||
676 | skge_led_off(hw, skge->port); | ||
677 | spin_unlock_bh(&hw->phy_lock); | 688 | spin_unlock_bh(&hw->phy_lock); |
678 | |||
679 | skge->blink_on = !skge->blink_on; | ||
680 | mod_timer(&skge->led_blink, jiffies + BLINK_HZ); | ||
681 | } | 689 | } |
682 | 690 | ||
683 | /* blink LED's for finding board */ | 691 | /* blink LED's for finding board */ |
684 | static int skge_phys_id(struct net_device *dev, u32 data) | 692 | static int skge_phys_id(struct net_device *dev, u32 data) |
685 | { | 693 | { |
686 | 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; | ||
687 | 697 | ||
688 | if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ)) | 698 | if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ)) |
689 | data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ); | 699 | ms = jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT / HZ) * 1000; |
700 | else | ||
701 | ms = data * 1000; | ||
690 | 702 | ||
691 | /* start blinking */ | 703 | while (ms > 0) { |
692 | skge->blink_on = 1; | 704 | skge_led(skge, mode); |
693 | mod_timer(&skge->led_blink, jiffies+1); | 705 | mode ^= LED_MODE_TST; |
694 | 706 | ||
695 | msleep_interruptible(data * 1000); | 707 | if (msleep_interruptible(BLINK_MS)) |
696 | del_timer_sync(&skge->led_blink); | 708 | break; |
709 | ms -= BLINK_MS; | ||
710 | } | ||
697 | 711 | ||
698 | 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); | ||
699 | 714 | ||
700 | return 0; | 715 | return 0; |
701 | } | 716 | } |
@@ -1192,13 +1207,6 @@ static void genesis_mac_init(struct skge_hw *hw, int port) | |||
1192 | xm_write16(hw, port, XM_STAT_CMD, | 1207 | xm_write16(hw, port, XM_STAT_CMD, |
1193 | XM_SC_CLR_RXC | XM_SC_CLR_TXC); | 1208 | XM_SC_CLR_RXC | XM_SC_CLR_TXC); |
1194 | 1209 | ||
1195 | /* initialize Rx, Tx and Link LED */ | ||
1196 | skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON); | ||
1197 | skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_LINKSYNC_ON); | ||
1198 | |||
1199 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START); | ||
1200 | skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_START); | ||
1201 | |||
1202 | /* Unreset the XMAC. */ | 1210 | /* Unreset the XMAC. */ |
1203 | 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); |
1204 | 1212 | ||
@@ -1565,7 +1573,6 @@ static void yukon_init(struct skge_hw *hw, int port) | |||
1565 | { | 1573 | { |
1566 | struct skge_port *skge = netdev_priv(hw->dev[port]); | 1574 | struct skge_port *skge = netdev_priv(hw->dev[port]); |
1567 | u16 ctrl, ct1000, adv; | 1575 | u16 ctrl, ct1000, adv; |
1568 | u16 ledctrl, ledover; | ||
1569 | 1576 | ||
1570 | pr_debug("yukon_init\n"); | 1577 | pr_debug("yukon_init\n"); |
1571 | if (skge->autoneg == AUTONEG_ENABLE) { | 1578 | if (skge->autoneg == AUTONEG_ENABLE) { |
@@ -1637,27 +1644,6 @@ static void yukon_init(struct skge_hw *hw, int port) | |||
1637 | gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv); | 1644 | gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv); |
1638 | gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl); | 1645 | gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl); |
1639 | 1646 | ||
1640 | /* Setup Phy LED's */ | ||
1641 | ledctrl = PHY_M_LED_PULS_DUR(PULS_170MS); | ||
1642 | ledover = 0; | ||
1643 | |||
1644 | ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL; | ||
1645 | |||
1646 | /* turn off the Rx LED (LED_RX) */ | ||
1647 | ledover |= PHY_M_LED_MO_RX(MO_LED_OFF); | ||
1648 | |||
1649 | /* disable blink mode (LED_DUPLEX) on collisions */ | ||
1650 | ctrl |= PHY_M_LEDC_DP_CTRL; | ||
1651 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); | ||
1652 | |||
1653 | if (skge->autoneg == AUTONEG_DISABLE || skge->speed == SPEED_100) { | ||
1654 | /* turn on 100 Mbps LED (LED_LINK100) */ | ||
1655 | ledover |= PHY_M_LED_MO_100(MO_LED_ON); | ||
1656 | } | ||
1657 | |||
1658 | if (ledover) | ||
1659 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover); | ||
1660 | |||
1661 | /* Enable phy interrupt on autonegotiation complete (or link up) */ | 1647 | /* Enable phy interrupt on autonegotiation complete (or link up) */ |
1662 | if (skge->autoneg == AUTONEG_ENABLE) | 1648 | if (skge->autoneg == AUTONEG_ENABLE) |
1663 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_MSK); | 1649 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_MSK); |
@@ -2115,6 +2101,7 @@ static int skge_up(struct net_device *dev) | |||
2115 | /* Start receiver BMU */ | 2101 | /* Start receiver BMU */ |
2116 | wmb(); | 2102 | wmb(); |
2117 | 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); | ||
2118 | 2105 | ||
2119 | pr_debug("skge_up completed\n"); | 2106 | pr_debug("skge_up completed\n"); |
2120 | return 0; | 2107 | return 0; |
@@ -2139,8 +2126,6 @@ static int skge_down(struct net_device *dev) | |||
2139 | 2126 | ||
2140 | netif_stop_queue(dev); | 2127 | netif_stop_queue(dev); |
2141 | 2128 | ||
2142 | del_timer_sync(&skge->led_blink); | ||
2143 | |||
2144 | /* Stop transmitter */ | 2129 | /* Stop transmitter */ |
2145 | skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP); | 2130 | skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP); |
2146 | skge_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), | 2131 | skge_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), |
@@ -2174,15 +2159,12 @@ static int skge_down(struct net_device *dev) | |||
2174 | if (hw->chip_id == CHIP_ID_GENESIS) { | 2159 | if (hw->chip_id == CHIP_ID_GENESIS) { |
2175 | 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); |
2176 | 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); |
2177 | skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_STOP); | ||
2178 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_STOP); | ||
2179 | } else { | 2162 | } else { |
2180 | 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); |
2181 | 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); |
2182 | } | 2165 | } |
2183 | 2166 | ||
2184 | /* turn off led's */ | 2167 | skge_led(skge, LED_MODE_OFF); |
2185 | skge_write16(hw, B0_LED, LED_STAT_OFF); | ||
2186 | 2168 | ||
2187 | skge_tx_clean(skge); | 2169 | skge_tx_clean(skge); |
2188 | skge_rx_clean(skge); | 2170 | skge_rx_clean(skge); |
@@ -3088,10 +3070,6 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, | |||
3088 | 3070 | ||
3089 | spin_lock_init(&skge->tx_lock); | 3071 | spin_lock_init(&skge->tx_lock); |
3090 | 3072 | ||
3091 | init_timer(&skge->led_blink); | ||
3092 | skge->led_blink.function = skge_blink_timer; | ||
3093 | skge->led_blink.data = (unsigned long) skge; | ||
3094 | |||
3095 | if (hw->chip_id != CHIP_ID_GENESIS) { | 3073 | if (hw->chip_id != CHIP_ID_GENESIS) { |
3096 | dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; | 3074 | dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; |
3097 | skge->rx_csum = 1; | 3075 | skge->rx_csum = 1; |