aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2009-11-23 11:03:45 -0500
committerDavid S. Miller <davem@davemloft.net>2009-11-24 13:58:39 -0500
commit398468ed1b5c61fe8bcbc8cc1ed323e3c23b58ef (patch)
tree2c9f8932143b91d8affe388bd21d98beab7c7488 /drivers/net
parentdcf477b2d205abb8ccdb3b1cb668a0db2de202c0 (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.c7
-rw-r--r--drivers/net/sfc/efx.h3
-rw-r--r--drivers/net/sfc/ethtool.c16
-rw-r--r--drivers/net/sfc/falcon_boards.c66
-rw-r--r--drivers/net/sfc/net_driver.h18
-rw-r--r--drivers/net/sfc/phy.h2
-rw-r--r--drivers/net/sfc/qt202x_phy.c3
-rw-r--r--drivers/net/sfc/tenxpress.c24
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}
1892void efx_port_dummy_op_void(struct efx_nic *efx) {} 1892void efx_port_dummy_op_void(struct efx_nic *efx) {}
1893void efx_port_dummy_op_blink(struct efx_nic *efx, bool blink) {} 1893void efx_port_dummy_op_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
1894{
1895}
1894 1896
1895static struct efx_mac_operations efx_dummy_mac_operations = { 1897static 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 = {
1909static struct efx_board efx_dummy_board_info = { 1911static 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 */
70extern int efx_port_dummy_op_int(struct efx_nic *efx); 70extern int efx_port_dummy_op_int(struct efx_nic *efx);
71extern void efx_port_dummy_op_void(struct efx_nic *efx); 71extern void efx_port_dummy_op_void(struct efx_nic *efx);
72extern void efx_port_dummy_op_blink(struct efx_nic *efx, bool blink); 72extern void
73efx_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
35static 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
46static 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
622static void sfe4002_set_id_led(struct efx_nic *efx, bool state) 588static 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
628static int sfe4002_check_hw(struct efx_nic *efx) 595static 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
686static void sfn4112f_set_id_led(struct efx_nic *efx, bool state) 652static 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
692static int sfn4112f_check_hw(struct efx_nic *efx) 671static 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
391enum 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 @@
16extern struct efx_phy_operations falcon_sfx7101_phy_ops; 16extern struct efx_phy_operations falcon_sfx7101_phy_ops;
17extern struct efx_phy_operations falcon_sft9001_phy_ops; 17extern struct efx_phy_operations falcon_sft9001_phy_ops;
18 18
19extern void tenxpress_phy_blink(struct efx_nic *efx, bool blink); 19extern 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
229static void qt202x_phy_fini(struct efx_nic *efx) 229static 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 */ 617void tenxpress_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
618void 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}