[PATCH] skge: led toggle cleanup
authorStephen Hemminger <shemminger@osdl.org>
Fri, 22 Jul 2005 23:26:10 +0000 (16:26 -0700)
committerJeff Garzik <jgarzik@pobox.com>
Sun, 31 Jul 2005 04:40:54 +0000 (00:40 -0400)
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>
drivers/net/skge.c
drivers/net/skge.h

index 43a275d..6b889a3 100644 (file)
@@ -55,7 +55,7 @@
 #define ETH_JUMBO_MTU          9000
 #define TX_WATCHDOG            (5 * HZ)
 #define NAPI_WEIGHT            64
-#define BLINK_HZ               (HZ/4)
+#define BLINK_MS               250
 
 MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver");
 MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>");
@@ -619,83 +619,98 @@ static int skge_set_coalesce(struct net_device *dev,
        return 0;
 }
 
-static void skge_led_on(struct skge_hw *hw, int port)
+enum led_mode { LED_MODE_OFF, LED_MODE_ON, LED_MODE_TST };
+static void skge_led(struct skge_port *skge, enum led_mode mode)
 {
+       struct skge_hw *hw = skge->hw;
+       int port = skge->port;
+
+       spin_lock_bh(&hw->phy_lock);
        if (hw->chip_id == CHIP_ID_GENESIS) {
-               skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON);
-               skge_write8(hw, B0_LED, LED_STAT_ON);
+               switch (mode) {
+               case LED_MODE_OFF:
+                       xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_OFF);
+                       skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF);
+                       skge_write32(hw, SK_REG(port, RX_LED_VAL), 0);
+                       skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_T_OFF);
+                       break;
 
-               skge_write8(hw, SK_REG(port, RX_LED_TST), LED_T_ON);
-               skge_write32(hw, SK_REG(port, RX_LED_VAL), 100);
-               skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START);
+               case LED_MODE_ON:
+                       skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON);
+                       skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_LINKSYNC_ON);
 
-               /* For Broadcom Phy only */
-               xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_ON);
-       } else {
-               gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0);
-               gm_phy_write(hw, port, PHY_MARV_LED_OVER,
-                                 PHY_M_LED_MO_DUP(MO_LED_ON)  |
-                                 PHY_M_LED_MO_10(MO_LED_ON)   |
-                                 PHY_M_LED_MO_100(MO_LED_ON)  |
-                                 PHY_M_LED_MO_1000(MO_LED_ON) |
-                                 PHY_M_LED_MO_RX(MO_LED_ON));
-       }
-}
+                       skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START);
+                       skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_START);
 
-static void skge_led_off(struct skge_hw *hw, int port)
-{
-       if (hw->chip_id == CHIP_ID_GENESIS) {
-               skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF);
-               skge_write8(hw, B0_LED, LED_STAT_OFF);
+                       break;
 
-               skge_write32(hw, SK_REG(port, RX_LED_VAL), 0);
-               skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_T_OFF);
+               case LED_MODE_TST:
+                       skge_write8(hw, SK_REG(port, RX_LED_TST), LED_T_ON);
+                       skge_write32(hw, SK_REG(port, RX_LED_VAL), 100);
+                       skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START);
 
-               /* Broadcom only */
-               xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_OFF);
+                       xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_ON);
+                       break;
+               }
        } else {
-               gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0);
-               gm_phy_write(hw, port, PHY_MARV_LED_OVER,
-                                 PHY_M_LED_MO_DUP(MO_LED_OFF)  |
-                                 PHY_M_LED_MO_10(MO_LED_OFF)   |
-                                 PHY_M_LED_MO_100(MO_LED_OFF)  |
-                                 PHY_M_LED_MO_1000(MO_LED_OFF) |
-                                 PHY_M_LED_MO_RX(MO_LED_OFF));
+               switch (mode) {
+               case LED_MODE_OFF:
+                       gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0);
+                       gm_phy_write(hw, port, PHY_MARV_LED_OVER,
+                                    PHY_M_LED_MO_DUP(MO_LED_OFF)  |
+                                    PHY_M_LED_MO_10(MO_LED_OFF)   |
+                                    PHY_M_LED_MO_100(MO_LED_OFF)  |
+                                    PHY_M_LED_MO_1000(MO_LED_OFF) |
+                                    PHY_M_LED_MO_RX(MO_LED_OFF));
+                       break;
+               case LED_MODE_ON:
+                       gm_phy_write(hw, port, PHY_MARV_LED_CTRL,
+                                    PHY_M_LED_PULS_DUR(PULS_170MS) |
+                                    PHY_M_LED_BLINK_RT(BLINK_84MS) |
+                                    PHY_M_LEDC_TX_CTRL |
+                                    PHY_M_LEDC_DP_CTRL);
+               
+                       gm_phy_write(hw, port, PHY_MARV_LED_OVER,
+                                    PHY_M_LED_MO_RX(MO_LED_OFF) |
+                                    (skge->speed == SPEED_100 ?
+                                     PHY_M_LED_MO_100(MO_LED_ON) : 0));
+                       break;
+               case LED_MODE_TST:
+                       gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0);
+                       gm_phy_write(hw, port, PHY_MARV_LED_OVER,
+                                    PHY_M_LED_MO_DUP(MO_LED_ON)  |
+                                    PHY_M_LED_MO_10(MO_LED_ON)   |
+                                    PHY_M_LED_MO_100(MO_LED_ON)  |
+                                    PHY_M_LED_MO_1000(MO_LED_ON) |
+                                    PHY_M_LED_MO_RX(MO_LED_ON));
+               }
        }
-}
-
-static void skge_blink_timer(unsigned long data)
-{
-       struct skge_port *skge = (struct skge_port *) data;
-       struct skge_hw *hw = skge->hw;
-
-       spin_lock_bh(&hw->phy_lock);
-       if (skge->blink_on)
-               skge_led_on(hw, skge->port);
-       else
-               skge_led_off(hw, skge->port);
        spin_unlock_bh(&hw->phy_lock);
-
-       skge->blink_on = !skge->blink_on;
-       mod_timer(&skge->led_blink, jiffies + BLINK_HZ);
 }
 
 /* blink LED's for finding board */
 static int skge_phys_id(struct net_device *dev, u32 data)
 {
        struct skge_port *skge = netdev_priv(dev);
+       unsigned long ms;
+       enum led_mode mode = LED_MODE_TST;
 
        if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
-               data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
+               ms = jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT / HZ) * 1000;
+       else
+               ms = data * 1000;
 
-       /* start blinking */
-       skge->blink_on = 1;
-       mod_timer(&skge->led_blink, jiffies+1);
+       while (ms > 0) {
+               skge_led(skge, mode);
+               mode ^= LED_MODE_TST;
 
-       msleep_interruptible(data * 1000);
-       del_timer_sync(&skge->led_blink);
+               if (msleep_interruptible(BLINK_MS))
+                       break;
+               ms -= BLINK_MS;
+       }
 
-       skge_led_off(skge->hw, skge->port);
+       /* back to regular LED state */
+       skge_led(skge, netif_running(dev) ? LED_MODE_ON : LED_MODE_OFF);
 
        return 0;
 }
@@ -1192,13 +1207,6 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
        xm_write16(hw, port, XM_STAT_CMD,
                        XM_SC_CLR_RXC | XM_SC_CLR_TXC);
 
-       /* initialize Rx, Tx and Link LED */
-       skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON);
-       skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_LINKSYNC_ON);
-
-       skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START);
-       skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_START);
-
        /* Unreset the XMAC. */
        skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
 
@@ -1565,7 +1573,6 @@ static void yukon_init(struct skge_hw *hw, int port)
 {
        struct skge_port *skge = netdev_priv(hw->dev[port]);
        u16 ctrl, ct1000, adv;
-       u16 ledctrl, ledover;
 
        pr_debug("yukon_init\n");
        if (skge->autoneg == AUTONEG_ENABLE) {
@@ -1637,27 +1644,6 @@ static void yukon_init(struct skge_hw *hw, int port)
        gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv);
        gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
 
-       /* Setup Phy LED's */
-       ledctrl = PHY_M_LED_PULS_DUR(PULS_170MS);
-       ledover = 0;
-
-       ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL;
-
-       /* turn off the Rx LED (LED_RX) */
-       ledover |= PHY_M_LED_MO_RX(MO_LED_OFF);
-
-       /* disable blink mode (LED_DUPLEX) on collisions */
-       ctrl |= PHY_M_LEDC_DP_CTRL;
-       gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
-
-       if (skge->autoneg == AUTONEG_DISABLE || skge->speed == SPEED_100) {
-               /* turn on 100 Mbps LED (LED_LINK100) */
-               ledover |= PHY_M_LED_MO_100(MO_LED_ON);
-       }
-
-       if (ledover)
-               gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover);
-
        /* Enable phy interrupt on autonegotiation complete (or link up) */
        if (skge->autoneg == AUTONEG_ENABLE)
                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)
        /* Start receiver BMU */
        wmb();
        skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_START | CSR_IRQ_CL_F);
+       skge_led(skge, LED_MODE_ON);
 
        pr_debug("skge_up completed\n");
        return 0;
@@ -2139,8 +2126,6 @@ static int skge_down(struct net_device *dev)
 
        netif_stop_queue(dev);
 
-       del_timer_sync(&skge->led_blink);
-
        /* Stop transmitter */
        skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP);
        skge_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL),
@@ -2174,15 +2159,12 @@ static int skge_down(struct net_device *dev)
        if (hw->chip_id == CHIP_ID_GENESIS) {
                skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_RST_SET);
                skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_RST_SET);
-               skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_STOP);
-               skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_STOP);
        } else {
                skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
                skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
        }
 
-       /* turn off led's */
-       skge_write16(hw, B0_LED, LED_STAT_OFF);
+       skge_led(skge, LED_MODE_OFF);
 
        skge_tx_clean(skge);
        skge_rx_clean(skge);
@@ -3088,10 +3070,6 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
 
        spin_lock_init(&skge->tx_lock);
 
-       init_timer(&skge->led_blink);
-       skge->led_blink.function = skge_blink_timer;
-       skge->led_blink.data = (unsigned long) skge;
-
        if (hw->chip_id != CHIP_ID_GENESIS) {
                dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
                skge->rx_csum = 1;
index c372146..b432f1b 100644 (file)
@@ -2507,8 +2507,6 @@ struct skge_port {
        dma_addr_t           dma;
        unsigned long        mem_size;
        unsigned int         rx_buf_size;
-
-       struct timer_list    led_blink;
 };