diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2009-11-23 11:03:45 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-11-24 13:58:39 -0500 |
commit | 398468ed1b5c61fe8bcbc8cc1ed323e3c23b58ef (patch) | |
tree | 2c9f8932143b91d8affe388bd21d98beab7c7488 /drivers/net | |
parent | dcf477b2d205abb8ccdb3b1cb668a0db2de202c0 (diff) |
sfc: Use a single blink implementation
Only some PHYs have firmware support for a LED blink mode, so we
currently blink the others in a timer function. Since all PHYs have
simple on and off modes, we don't gain anything by using multiple
blink implementations. Also, since we have a process context there
is no need to use a timer.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/sfc/efx.c | 7 | ||||
-rw-r--r-- | drivers/net/sfc/efx.h | 3 | ||||
-rw-r--r-- | drivers/net/sfc/ethtool.c | 16 | ||||
-rw-r--r-- | drivers/net/sfc/falcon_boards.c | 66 | ||||
-rw-r--r-- | drivers/net/sfc/net_driver.h | 18 | ||||
-rw-r--r-- | drivers/net/sfc/phy.h | 2 | ||||
-rw-r--r-- | drivers/net/sfc/qt202x_phy.c | 3 | ||||
-rw-r--r-- | drivers/net/sfc/tenxpress.c | 24 |
8 files changed, 62 insertions, 77 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 0d0243b7ac34..612cd815088f 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c | |||
@@ -1890,7 +1890,9 @@ int efx_port_dummy_op_int(struct efx_nic *efx) | |||
1890 | return 0; | 1890 | return 0; |
1891 | } | 1891 | } |
1892 | void efx_port_dummy_op_void(struct efx_nic *efx) {} | 1892 | void efx_port_dummy_op_void(struct efx_nic *efx) {} |
1893 | void efx_port_dummy_op_blink(struct efx_nic *efx, bool blink) {} | 1893 | void efx_port_dummy_op_set_id_led(struct efx_nic *efx, enum efx_led_mode mode) |
1894 | { | ||
1895 | } | ||
1894 | 1896 | ||
1895 | static struct efx_mac_operations efx_dummy_mac_operations = { | 1897 | static struct efx_mac_operations efx_dummy_mac_operations = { |
1896 | .reconfigure = efx_port_dummy_op_void, | 1898 | .reconfigure = efx_port_dummy_op_void, |
@@ -1909,9 +1911,8 @@ static struct efx_phy_operations efx_dummy_phy_operations = { | |||
1909 | static struct efx_board efx_dummy_board_info = { | 1911 | static struct efx_board efx_dummy_board_info = { |
1910 | .init = efx_port_dummy_op_int, | 1912 | .init = efx_port_dummy_op_int, |
1911 | .init_leds = efx_port_dummy_op_void, | 1913 | .init_leds = efx_port_dummy_op_void, |
1912 | .set_id_led = efx_port_dummy_op_blink, | 1914 | .set_id_led = efx_port_dummy_op_set_id_led, |
1913 | .monitor = efx_port_dummy_op_int, | 1915 | .monitor = efx_port_dummy_op_int, |
1914 | .blink = efx_port_dummy_op_blink, | ||
1915 | .fini = efx_port_dummy_op_void, | 1916 | .fini = efx_port_dummy_op_void, |
1916 | }; | 1917 | }; |
1917 | 1918 | ||
diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h index 179e0e3b0ec6..6f4639465163 100644 --- a/drivers/net/sfc/efx.h +++ b/drivers/net/sfc/efx.h | |||
@@ -69,7 +69,8 @@ extern void efx_hex_dump(const u8 *, unsigned int, const char *); | |||
69 | /* Dummy PHY ops for PHY drivers */ | 69 | /* Dummy PHY ops for PHY drivers */ |
70 | extern int efx_port_dummy_op_int(struct efx_nic *efx); | 70 | extern int efx_port_dummy_op_int(struct efx_nic *efx); |
71 | extern void efx_port_dummy_op_void(struct efx_nic *efx); | 71 | extern void efx_port_dummy_op_void(struct efx_nic *efx); |
72 | extern void efx_port_dummy_op_blink(struct efx_nic *efx, bool blink); | 72 | extern void |
73 | efx_port_dummy_op_set_id_led(struct efx_nic *efx, enum efx_led_mode mode); | ||
73 | 74 | ||
74 | /* MTD */ | 75 | /* MTD */ |
75 | #ifdef CONFIG_SFC_MTD | 76 | #ifdef CONFIG_SFC_MTD |
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index a313b61c8ff4..18e02712818c 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c | |||
@@ -187,13 +187,15 @@ static int efx_ethtool_phys_id(struct net_device *net_dev, u32 count) | |||
187 | { | 187 | { |
188 | struct efx_nic *efx = netdev_priv(net_dev); | 188 | struct efx_nic *efx = netdev_priv(net_dev); |
189 | 189 | ||
190 | efx->board_info.blink(efx, 1); | 190 | do { |
191 | set_current_state(TASK_INTERRUPTIBLE); | 191 | efx->board_info.set_id_led(efx, EFX_LED_ON); |
192 | if (count) | 192 | schedule_timeout_interruptible(HZ / 2); |
193 | schedule_timeout(count * HZ); | 193 | |
194 | else | 194 | efx->board_info.set_id_led(efx, EFX_LED_OFF); |
195 | schedule(); | 195 | schedule_timeout_interruptible(HZ / 2); |
196 | efx->board_info.blink(efx, 0); | 196 | } while (!signal_pending(current) && --count != 0); |
197 | |||
198 | efx->board_info.set_id_led(efx, EFX_LED_DEFAULT); | ||
197 | return 0; | 199 | return 0; |
198 | } | 200 | } |
199 | 201 | ||
diff --git a/drivers/net/sfc/falcon_boards.c b/drivers/net/sfc/falcon_boards.c index d31c134981fd..b2505fc5c1f7 100644 --- a/drivers/net/sfc/falcon_boards.c +++ b/drivers/net/sfc/falcon_boards.c | |||
@@ -29,40 +29,6 @@ | |||
29 | #define FALCON_BOARD_SFN4111T 0x51 | 29 | #define FALCON_BOARD_SFN4111T 0x51 |
30 | #define FALCON_BOARD_SFN4112F 0x52 | 30 | #define FALCON_BOARD_SFN4112F 0x52 |
31 | 31 | ||
32 | /* Blink support. If the PHY has no auto-blink mode so we hang it off a timer */ | ||
33 | #define BLINK_INTERVAL (HZ/2) | ||
34 | |||
35 | static void blink_led_timer(unsigned long context) | ||
36 | { | ||
37 | struct efx_nic *efx = (struct efx_nic *)context; | ||
38 | struct efx_board *board = &efx->board_info; | ||
39 | |||
40 | board->set_id_led(efx, board->blink_state); | ||
41 | board->blink_state = !board->blink_state; | ||
42 | if (board->blink_resubmit) | ||
43 | mod_timer(&board->blink_timer, jiffies + BLINK_INTERVAL); | ||
44 | } | ||
45 | |||
46 | static void board_blink(struct efx_nic *efx, bool blink) | ||
47 | { | ||
48 | struct efx_board *board = &efx->board_info; | ||
49 | |||
50 | /* The rtnl mutex serialises all ethtool ioctls, so | ||
51 | * nothing special needs doing here. */ | ||
52 | if (blink) { | ||
53 | board->blink_resubmit = true; | ||
54 | board->blink_state = false; | ||
55 | setup_timer(&board->blink_timer, blink_led_timer, | ||
56 | (unsigned long)efx); | ||
57 | mod_timer(&board->blink_timer, jiffies + BLINK_INTERVAL); | ||
58 | } else { | ||
59 | board->blink_resubmit = false; | ||
60 | if (board->blink_timer.function) | ||
61 | del_timer_sync(&board->blink_timer); | ||
62 | board->init_leds(efx); | ||
63 | } | ||
64 | } | ||
65 | |||
66 | /***************************************************************************** | 32 | /***************************************************************************** |
67 | * Support for LM87 sensor chip used on several boards | 33 | * Support for LM87 sensor chip used on several boards |
68 | */ | 34 | */ |
@@ -469,7 +435,7 @@ static int sfe4001_init(struct efx_nic *efx) | |||
469 | 435 | ||
470 | /* 10Xpress has fixed-function LED pins, so there is no board-specific | 436 | /* 10Xpress has fixed-function LED pins, so there is no board-specific |
471 | * blink code. */ | 437 | * blink code. */ |
472 | efx->board_info.blink = tenxpress_phy_blink; | 438 | efx->board_info.set_id_led = tenxpress_set_id_led; |
473 | 439 | ||
474 | efx->board_info.monitor = sfe4001_check_hw; | 440 | efx->board_info.monitor = sfe4001_check_hw; |
475 | efx->board_info.fini = sfe4001_fini; | 441 | efx->board_info.fini = sfe4001_fini; |
@@ -546,7 +512,7 @@ static int sfn4111t_init(struct efx_nic *efx) | |||
546 | if (!efx->board_info.hwmon_client) | 512 | if (!efx->board_info.hwmon_client) |
547 | return -EIO; | 513 | return -EIO; |
548 | 514 | ||
549 | efx->board_info.blink = tenxpress_phy_blink; | 515 | efx->board_info.set_id_led = tenxpress_set_id_led; |
550 | efx->board_info.monitor = sfn4111t_check_hw; | 516 | efx->board_info.monitor = sfn4111t_check_hw; |
551 | efx->board_info.fini = sfn4111t_fini; | 517 | efx->board_info.fini = sfn4111t_fini; |
552 | 518 | ||
@@ -619,10 +585,11 @@ static void sfe4002_init_leds(struct efx_nic *efx) | |||
619 | falcon_qt202x_set_led(efx, SFE4002_FAULT_LED, QUAKE_LED_OFF); | 585 | falcon_qt202x_set_led(efx, SFE4002_FAULT_LED, QUAKE_LED_OFF); |
620 | } | 586 | } |
621 | 587 | ||
622 | static void sfe4002_set_id_led(struct efx_nic *efx, bool state) | 588 | static void sfe4002_set_id_led(struct efx_nic *efx, enum efx_led_mode mode) |
623 | { | 589 | { |
624 | falcon_qt202x_set_led(efx, SFE4002_FAULT_LED, state ? QUAKE_LED_ON : | 590 | falcon_qt202x_set_led( |
625 | QUAKE_LED_OFF); | 591 | efx, SFE4002_FAULT_LED, |
592 | (mode == EFX_LED_ON) ? QUAKE_LED_ON : QUAKE_LED_OFF); | ||
626 | } | 593 | } |
627 | 594 | ||
628 | static int sfe4002_check_hw(struct efx_nic *efx) | 595 | static int sfe4002_check_hw(struct efx_nic *efx) |
@@ -644,7 +611,6 @@ static int sfe4002_init(struct efx_nic *efx) | |||
644 | efx->board_info.monitor = sfe4002_check_hw; | 611 | efx->board_info.monitor = sfe4002_check_hw; |
645 | efx->board_info.init_leds = sfe4002_init_leds; | 612 | efx->board_info.init_leds = sfe4002_init_leds; |
646 | efx->board_info.set_id_led = sfe4002_set_id_led; | 613 | efx->board_info.set_id_led = sfe4002_set_id_led; |
647 | efx->board_info.blink = board_blink; | ||
648 | efx->board_info.fini = efx_fini_lm87; | 614 | efx->board_info.fini = efx_fini_lm87; |
649 | return 0; | 615 | return 0; |
650 | } | 616 | } |
@@ -683,10 +649,23 @@ static void sfn4112f_init_leds(struct efx_nic *efx) | |||
683 | QUAKE_LED_RXLINK | QUAKE_LED_LINK_STAT); | 649 | QUAKE_LED_RXLINK | QUAKE_LED_LINK_STAT); |
684 | } | 650 | } |
685 | 651 | ||
686 | static void sfn4112f_set_id_led(struct efx_nic *efx, bool state) | 652 | static void sfn4112f_set_id_led(struct efx_nic *efx, enum efx_led_mode mode) |
687 | { | 653 | { |
688 | falcon_qt202x_set_led(efx, SFN4112F_LINK_LED, | 654 | int reg; |
689 | state ? QUAKE_LED_ON : QUAKE_LED_OFF); | 655 | |
656 | switch (mode) { | ||
657 | case EFX_LED_OFF: | ||
658 | reg = QUAKE_LED_OFF; | ||
659 | break; | ||
660 | case EFX_LED_ON: | ||
661 | reg = QUAKE_LED_ON; | ||
662 | break; | ||
663 | default: | ||
664 | reg = QUAKE_LED_RXLINK | QUAKE_LED_LINK_STAT; | ||
665 | break; | ||
666 | } | ||
667 | |||
668 | falcon_qt202x_set_led(efx, SFN4112F_LINK_LED, reg); | ||
690 | } | 669 | } |
691 | 670 | ||
692 | static int sfn4112f_check_hw(struct efx_nic *efx) | 671 | static int sfn4112f_check_hw(struct efx_nic *efx) |
@@ -703,7 +682,6 @@ static int sfn4112f_init(struct efx_nic *efx) | |||
703 | efx->board_info.monitor = sfn4112f_check_hw; | 682 | efx->board_info.monitor = sfn4112f_check_hw; |
704 | efx->board_info.init_leds = sfn4112f_init_leds; | 683 | efx->board_info.init_leds = sfn4112f_init_leds; |
705 | efx->board_info.set_id_led = sfn4112f_set_id_led; | 684 | efx->board_info.set_id_led = sfn4112f_set_id_led; |
706 | efx->board_info.blink = board_blink; | ||
707 | efx->board_info.fini = efx_fini_lm87; | 685 | efx->board_info.fini = efx_fini_lm87; |
708 | return 0; | 686 | return 0; |
709 | } | 687 | } |
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index bc6fb2b29664..6b05d69429ee 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h | |||
@@ -388,6 +388,12 @@ struct efx_channel { | |||
388 | 388 | ||
389 | }; | 389 | }; |
390 | 390 | ||
391 | enum efx_led_mode { | ||
392 | EFX_LED_OFF = 0, | ||
393 | EFX_LED_ON = 1, | ||
394 | EFX_LED_DEFAULT = 2 | ||
395 | }; | ||
396 | |||
391 | /** | 397 | /** |
392 | * struct efx_board - board information | 398 | * struct efx_board - board information |
393 | * @type: Board model type | 399 | * @type: Board model type |
@@ -395,13 +401,9 @@ struct efx_channel { | |||
395 | * @minor: Minor rev. (0, 1, ...) | 401 | * @minor: Minor rev. (0, 1, ...) |
396 | * @init: Initialisation function | 402 | * @init: Initialisation function |
397 | * @init_leds: Sets up board LEDs. May be called repeatedly. | 403 | * @init_leds: Sets up board LEDs. May be called repeatedly. |
398 | * @set_id_led: Turns the identification LED on or off | 404 | * @set_id_led: Set state of identifying LED or revert to automatic function |
399 | * @blink: Starts/stops blinking | ||
400 | * @monitor: Board-specific health check function | 405 | * @monitor: Board-specific health check function |
401 | * @fini: Cleanup function | 406 | * @fini: Cleanup function |
402 | * @blink_state: Current blink state | ||
403 | * @blink_resubmit: Blink timer resubmission flag | ||
404 | * @blink_timer: Blink timer | ||
405 | * @hwmon_client: I2C client for hardware monitor | 407 | * @hwmon_client: I2C client for hardware monitor |
406 | * @ioexp_client: I2C client for power/port control | 408 | * @ioexp_client: I2C client for power/port control |
407 | */ | 409 | */ |
@@ -414,13 +416,9 @@ struct efx_board { | |||
414 | * have a separate init callback that happens later than | 416 | * have a separate init callback that happens later than |
415 | * board init. */ | 417 | * board init. */ |
416 | void (*init_leds)(struct efx_nic *efx); | 418 | void (*init_leds)(struct efx_nic *efx); |
417 | void (*set_id_led) (struct efx_nic *efx, bool state); | 419 | void (*set_id_led) (struct efx_nic *efx, enum efx_led_mode mode); |
418 | int (*monitor) (struct efx_nic *nic); | 420 | int (*monitor) (struct efx_nic *nic); |
419 | void (*blink) (struct efx_nic *efx, bool start); | ||
420 | void (*fini) (struct efx_nic *nic); | 421 | void (*fini) (struct efx_nic *nic); |
421 | bool blink_state; | ||
422 | bool blink_resubmit; | ||
423 | struct timer_list blink_timer; | ||
424 | struct i2c_client *hwmon_client, *ioexp_client; | 422 | struct i2c_client *hwmon_client, *ioexp_client; |
425 | }; | 423 | }; |
426 | 424 | ||
diff --git a/drivers/net/sfc/phy.h b/drivers/net/sfc/phy.h index b5150f3bca31..2ad1cec2c720 100644 --- a/drivers/net/sfc/phy.h +++ b/drivers/net/sfc/phy.h | |||
@@ -16,7 +16,7 @@ | |||
16 | extern struct efx_phy_operations falcon_sfx7101_phy_ops; | 16 | extern struct efx_phy_operations falcon_sfx7101_phy_ops; |
17 | extern struct efx_phy_operations falcon_sft9001_phy_ops; | 17 | extern struct efx_phy_operations falcon_sft9001_phy_ops; |
18 | 18 | ||
19 | extern void tenxpress_phy_blink(struct efx_nic *efx, bool blink); | 19 | extern void tenxpress_set_id_led(struct efx_nic *efx, enum efx_led_mode mode); |
20 | 20 | ||
21 | /* Wait for the PHY to boot. Return 0 on success, -EINVAL if the PHY failed | 21 | /* Wait for the PHY to boot. Return 0 on success, -EINVAL if the PHY failed |
22 | * to boot due to corrupt flash, or some other negative error code. */ | 22 | * to boot due to corrupt flash, or some other negative error code. */ |
diff --git a/drivers/net/sfc/qt202x_phy.c b/drivers/net/sfc/qt202x_phy.c index 560eb18280e1..05c0f9acedbd 100644 --- a/drivers/net/sfc/qt202x_phy.c +++ b/drivers/net/sfc/qt202x_phy.c | |||
@@ -228,9 +228,6 @@ static void qt202x_phy_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecm | |||
228 | 228 | ||
229 | static void qt202x_phy_fini(struct efx_nic *efx) | 229 | static void qt202x_phy_fini(struct efx_nic *efx) |
230 | { | 230 | { |
231 | /* Clobber the LED if it was blinking */ | ||
232 | efx->board_info.blink(efx, false); | ||
233 | |||
234 | /* Free the context block */ | 231 | /* Free the context block */ |
235 | kfree(efx->phy_data); | 232 | kfree(efx->phy_data); |
236 | efx->phy_data = NULL; | 233 | efx->phy_data = NULL; |
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index 19c78d281700..6a8e3ea03811 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c | |||
@@ -613,21 +613,29 @@ static void tenxpress_phy_fini(struct efx_nic *efx) | |||
613 | } | 613 | } |
614 | 614 | ||
615 | 615 | ||
616 | /* Set the RX and TX LEDs and Link LED flashing. The other LEDs | 616 | /* Override the RX, TX and link LEDs */ |
617 | * (which probably aren't wired anyway) are left in AUTO mode */ | 617 | void tenxpress_set_id_led(struct efx_nic *efx, enum efx_led_mode mode) |
618 | void tenxpress_phy_blink(struct efx_nic *efx, bool blink) | ||
619 | { | 618 | { |
620 | int reg; | 619 | int reg; |
621 | 620 | ||
622 | if (blink) | 621 | switch (mode) { |
623 | reg = (PMA_PMD_LED_FLASH << PMA_PMD_LED_TX_LBN) | | 622 | case EFX_LED_OFF: |
624 | (PMA_PMD_LED_FLASH << PMA_PMD_LED_RX_LBN) | | 623 | reg = (PMA_PMD_LED_OFF << PMA_PMD_LED_TX_LBN) | |
625 | (PMA_PMD_LED_FLASH << PMA_PMD_LED_LINK_LBN); | 624 | (PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN) | |
626 | else | 625 | (PMA_PMD_LED_OFF << PMA_PMD_LED_LINK_LBN); |
626 | break; | ||
627 | case EFX_LED_ON: | ||
628 | reg = (PMA_PMD_LED_ON << PMA_PMD_LED_TX_LBN) | | ||
629 | (PMA_PMD_LED_ON << PMA_PMD_LED_RX_LBN) | | ||
630 | (PMA_PMD_LED_ON << PMA_PMD_LED_LINK_LBN); | ||
631 | break; | ||
632 | default: | ||
627 | if (efx->phy_type == PHY_TYPE_SFX7101) | 633 | if (efx->phy_type == PHY_TYPE_SFX7101) |
628 | reg = SFX7101_PMA_PMD_LED_DEFAULT; | 634 | reg = SFX7101_PMA_PMD_LED_DEFAULT; |
629 | else | 635 | else |
630 | reg = SFT9001_PMA_PMD_LED_DEFAULT; | 636 | reg = SFT9001_PMA_PMD_LED_DEFAULT; |
637 | break; | ||
638 | } | ||
631 | 639 | ||
632 | efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG, reg); | 640 | efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG, reg); |
633 | } | 641 | } |