aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/skge.c
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2005-07-22 19:26:10 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-07-31 00:40:54 -0400
commit6abebb538d317ead09cc0f3c2a0752047f9ff961 (patch)
tree82c60d2629615bec70b149ada645a2399af4a9e8 /drivers/net/skge.c
parent4cde06ed0fb58402ec1d6d117122d1058983a393 (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.c170
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
60MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver"); 60MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver");
61MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>"); 61MODULE_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
622static void skge_led_on(struct skge_hw *hw, int port) 622enum led_mode { LED_MODE_OFF, LED_MODE_ON, LED_MODE_TST };
623static 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
645static 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
667static 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 */
684static int skge_phys_id(struct net_device *dev, u32 data) 692static 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;