aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan, Bruce W <bruce.w.allan@intel.com>2011-04-13 09:09:10 -0400
committerDavid S. Miller <davem@davemloft.net>2011-04-15 00:15:49 -0400
commitfce55922f5299a04c0a56b170a141fab34f13465 (patch)
tree91c6eeea0957b41199641c43add0e8170ad65f89
parent21d8c49e01a0c1c6eb6c750cd04110db4a539284 (diff)
ethtool: allow custom interval for physical identification
When physical identification of an adapter is done by toggling the mechanism on and off through software utilizing the set_phys_id operation, it is done with a fixed duration for both on and off states. Some drivers may want to set a custom duration for the on/off intervals. This patch changes the API so the return code from the driver's entry point when it is called with ETHTOOL_ID_ACTIVE can specify the frequency at which to cycle the on/off states, and updates the drivers that have already been converted to use the new set_phys_id and use the synchronous method for identifying an adapter. The physical identification frequency set in the updated drivers is based on how it was done prior to the introduction of set_phys_id. Compile tested only. Also fixes a compiler warning in sfc. v2: drivers do not return -EINVAL for ETHOOL_ID_ACTIVE v3: fold patchset into single patch and cleanup per Ben's feedback Signed-off-by: Bruce Allan <bruce.w.allan@intel.com> Cc: Ben Hutchings <bhutchings@solarflare.com> Cc: Sathya Perla <sathya.perla@emulex.com> Cc: Subbu Seetharaman <subbu.seetharaman@emulex.com> Cc: Ajit Khaparde <ajit.khaparde@emulex.com> Cc: Michael Chan <mchan@broadcom.com> Cc: Eilon Greenstein <eilong@broadcom.com> Cc: Divy Le Ray <divy@chelsio.com> Cc: Don Fry <pcnet32@frontier.com> Cc: Jon Mason <jdmason@kudzu.us> Cc: Solarflare linux maintainers <linux-net-drivers@solarflare.com> Cc: Steve Hodgson <shodgson@solarflare.com> Cc: Stephen Hemminger <shemminger@linux-foundation.org> Cc: Matt Carlson <mcarlson@broadcom.com> Acked-by: Jon Mason <jdmason@kudzu.us> Acked-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/benet/be_ethtool.c2
-rw-r--r--drivers/net/bnx2.c2
-rw-r--r--drivers/net/bnx2x/bnx2x_ethtool.c2
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c2
-rw-r--r--drivers/net/ewrk3.c2
-rw-r--r--drivers/net/niu.c2
-rw-r--r--drivers/net/pcnet32.c2
-rw-r--r--drivers/net/s2io.c2
-rw-r--r--drivers/net/sfc/ethtool.c6
-rw-r--r--drivers/net/skge.c2
-rw-r--r--drivers/net/sky2.c2
-rw-r--r--drivers/net/tg3.c2
-rw-r--r--include/linux/ethtool.h6
-rw-r--r--net/core/ethtool.c31
14 files changed, 34 insertions, 31 deletions
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c
index 96f5502e0ef7..80226e4801f3 100644
--- a/drivers/net/benet/be_ethtool.c
+++ b/drivers/net/benet/be_ethtool.c
@@ -516,7 +516,7 @@ be_set_phys_id(struct net_device *netdev,
516 case ETHTOOL_ID_ACTIVE: 516 case ETHTOOL_ID_ACTIVE:
517 be_cmd_get_beacon_state(adapter, adapter->hba_port_num, 517 be_cmd_get_beacon_state(adapter, adapter->hba_port_num,
518 &adapter->beacon_state); 518 &adapter->beacon_state);
519 return -EINVAL; 519 return 1; /* cycle on/off once per second */
520 520
521 case ETHTOOL_ID_ON: 521 case ETHTOOL_ID_ON:
522 be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0, 522 be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0,
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 0a52079bafef..bf729ee6acbd 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -7473,7 +7473,7 @@ bnx2_set_phys_id(struct net_device *dev, enum ethtool_phys_id_state state)
7473 7473
7474 bp->leds_save = REG_RD(bp, BNX2_MISC_CFG); 7474 bp->leds_save = REG_RD(bp, BNX2_MISC_CFG);
7475 REG_WR(bp, BNX2_MISC_CFG, BNX2_MISC_CFG_LEDMODE_MAC); 7475 REG_WR(bp, BNX2_MISC_CFG, BNX2_MISC_CFG_LEDMODE_MAC);
7476 return -EINVAL; 7476 return 1; /* cycle on/off once per second */
7477 7477
7478 case ETHTOOL_ID_ON: 7478 case ETHTOOL_ID_ON:
7479 REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE | 7479 REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE |
diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c
index ad7d91e499f4..0a5e88d6ba2c 100644
--- a/drivers/net/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/bnx2x/bnx2x_ethtool.c
@@ -2025,7 +2025,7 @@ static int bnx2x_set_phys_id(struct net_device *dev,
2025 2025
2026 switch (state) { 2026 switch (state) {
2027 case ETHTOOL_ID_ACTIVE: 2027 case ETHTOOL_ID_ACTIVE:
2028 return -EINVAL; 2028 return 1; /* cycle on/off once per second */
2029 2029
2030 case ETHTOOL_ID_ON: 2030 case ETHTOOL_ID_ON:
2031 bnx2x_set_led(&bp->link_params, &bp->link_vars, 2031 bnx2x_set_led(&bp->link_params, &bp->link_vars,
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 802c7a7c3b25..a087e0691dce 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -1757,7 +1757,7 @@ static int set_phys_id(struct net_device *dev,
1757 1757
1758 switch (state) { 1758 switch (state) {
1759 case ETHTOOL_ID_ACTIVE: 1759 case ETHTOOL_ID_ACTIVE:
1760 return -EINVAL; 1760 return 1; /* cycle on/off once per second */
1761 1761
1762 case ETHTOOL_ID_OFF: 1762 case ETHTOOL_ID_OFF:
1763 t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, F_GPIO0_OUT_VAL, 0); 1763 t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, F_GPIO0_OUT_VAL, 0);
diff --git a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c
index c7ce4438e923..17b6027d8be8 100644
--- a/drivers/net/ewrk3.c
+++ b/drivers/net/ewrk3.c
@@ -1618,7 +1618,7 @@ static int ewrk3_set_phys_id(struct net_device *dev,
1618 /* Prevent ISR from twiddling the LED */ 1618 /* Prevent ISR from twiddling the LED */
1619 lp->led_mask = 0; 1619 lp->led_mask = 0;
1620 spin_unlock_irq(&lp->hw_lock); 1620 spin_unlock_irq(&lp->hw_lock);
1621 return -EINVAL; 1621 return 2; /* cycle on/off twice per second */
1622 1622
1623 case ETHTOOL_ID_ON: 1623 case ETHTOOL_ID_ON:
1624 cr = inb(EWRK3_CR); 1624 cr = inb(EWRK3_CR);
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index 3fa1e9cdb4a8..ea2272f0f37e 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -7896,7 +7896,7 @@ static int niu_set_phys_id(struct net_device *dev,
7896 switch (state) { 7896 switch (state) {
7897 case ETHTOOL_ID_ACTIVE: 7897 case ETHTOOL_ID_ACTIVE:
7898 np->orig_led_state = niu_led_state_save(np); 7898 np->orig_led_state = niu_led_state_save(np);
7899 return -EINVAL; 7899 return 1; /* cycle on/off once per second */
7900 7900
7901 case ETHTOOL_ID_ON: 7901 case ETHTOOL_ID_ON:
7902 niu_force_led(np, 1); 7902 niu_force_led(np, 1);
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index e89afb929740..0a1efbae1bc0 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -1038,7 +1038,7 @@ static int pcnet32_set_phys_id(struct net_device *dev,
1038 for (i = 4; i < 8; i++) 1038 for (i = 4; i < 8; i++)
1039 lp->save_regs[i - 4] = a->read_bcr(ioaddr, i); 1039 lp->save_regs[i - 4] = a->read_bcr(ioaddr, i);
1040 spin_unlock_irqrestore(&lp->lock, flags); 1040 spin_unlock_irqrestore(&lp->lock, flags);
1041 return -EINVAL; 1041 return 2; /* cycle on/off twice per second */
1042 1042
1043 case ETHTOOL_ID_ON: 1043 case ETHTOOL_ID_ON:
1044 case ETHTOOL_ID_OFF: 1044 case ETHTOOL_ID_OFF:
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 2d5cc6142c04..2302d9743744 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -5541,7 +5541,7 @@ static int s2io_ethtool_set_led(struct net_device *dev,
5541 switch (state) { 5541 switch (state) {
5542 case ETHTOOL_ID_ACTIVE: 5542 case ETHTOOL_ID_ACTIVE:
5543 sp->adapt_ctrl_org = readq(&bar0->gpio_control); 5543 sp->adapt_ctrl_org = readq(&bar0->gpio_control);
5544 return -EINVAL; 5544 return 1; /* cycle on/off once per second */
5545 5545
5546 case ETHTOOL_ID_ON: 5546 case ETHTOOL_ID_ON:
5547 s2io_set_led(sp, true); 5547 s2io_set_led(sp, true);
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index 644f7c1d6e7b..5d8468fc5804 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -182,7 +182,7 @@ static int efx_ethtool_phys_id(struct net_device *net_dev,
182 enum ethtool_phys_id_state state) 182 enum ethtool_phys_id_state state)
183{ 183{
184 struct efx_nic *efx = netdev_priv(net_dev); 184 struct efx_nic *efx = netdev_priv(net_dev);
185 enum efx_led_mode mode; 185 enum efx_led_mode mode = EFX_LED_DEFAULT;
186 186
187 switch (state) { 187 switch (state) {
188 case ETHTOOL_ID_ON: 188 case ETHTOOL_ID_ON:
@@ -194,8 +194,8 @@ static int efx_ethtool_phys_id(struct net_device *net_dev,
194 case ETHTOOL_ID_INACTIVE: 194 case ETHTOOL_ID_INACTIVE:
195 mode = EFX_LED_DEFAULT; 195 mode = EFX_LED_DEFAULT;
196 break; 196 break;
197 default: 197 case ETHTOOL_ID_ACTIVE:
198 return -EINVAL; 198 return 1; /* cycle on/off once per second */
199 } 199 }
200 200
201 efx->type->set_id_led(efx, mode); 201 efx->type->set_id_led(efx, mode);
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 310dcbce2519..176d784cbb54 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -753,7 +753,7 @@ static int skge_set_phys_id(struct net_device *dev,
753 753
754 switch (state) { 754 switch (state) {
755 case ETHTOOL_ID_ACTIVE: 755 case ETHTOOL_ID_ACTIVE:
756 return -EINVAL; 756 return 2; /* cycle on/off twice per second */
757 757
758 case ETHTOOL_ID_ON: 758 case ETHTOOL_ID_ON:
759 skge_led(skge, LED_MODE_TST); 759 skge_led(skge, LED_MODE_TST);
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index a4b8fe564eb0..c8d045114c66 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -3813,7 +3813,7 @@ static int sky2_set_phys_id(struct net_device *dev,
3813 3813
3814 switch (state) { 3814 switch (state) {
3815 case ETHTOOL_ID_ACTIVE: 3815 case ETHTOOL_ID_ACTIVE:
3816 return -EINVAL; 3816 return 1; /* cycle on/off once per second */
3817 case ETHTOOL_ID_INACTIVE: 3817 case ETHTOOL_ID_INACTIVE:
3818 sky2_led(sky2, MO_LED_NORM); 3818 sky2_led(sky2, MO_LED_NORM);
3819 break; 3819 break;
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 10fa476fede3..9915734ac3e9 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -10384,7 +10384,7 @@ static int tg3_set_phys_id(struct net_device *dev,
10384 10384
10385 switch (state) { 10385 switch (state) {
10386 case ETHTOOL_ID_ACTIVE: 10386 case ETHTOOL_ID_ACTIVE:
10387 return -EINVAL; 10387 return 1; /* cycle on/off once per second */
10388 10388
10389 case ETHTOOL_ID_ON: 10389 case ETHTOOL_ID_ON:
10390 tw32(MAC_LED_CTRL, LED_CTRL_LNKLED_OVERRIDE | 10390 tw32(MAC_LED_CTRL, LED_CTRL_LNKLED_OVERRIDE |
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index ad22a68c2e5d..9de31274341d 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -798,8 +798,10 @@ bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported);
798 * attached to it. The implementation may update the indicator 798 * attached to it. The implementation may update the indicator
799 * asynchronously or synchronously, but in either case it must return 799 * asynchronously or synchronously, but in either case it must return
800 * quickly. It is initially called with the argument %ETHTOOL_ID_ACTIVE, 800 * quickly. It is initially called with the argument %ETHTOOL_ID_ACTIVE,
801 * and must either activate asynchronous updates or return -%EINVAL. 801 * and must either activate asynchronous updates and return zero, return
802 * If it returns -%EINVAL then it will be called again at intervals with 802 * a negative error or return a positive frequency for synchronous
803 * indication (e.g. 1 for one on/off cycle per second). If it returns
804 * a frequency then it will be called again at intervals with the
803 * argument %ETHTOOL_ID_ON or %ETHTOOL_ID_OFF and should set the state of 805 * argument %ETHTOOL_ID_ON or %ETHTOOL_ID_OFF and should set the state of
804 * the indicator accordingly. Finally, it is called with the argument 806 * the indicator accordingly. Finally, it is called with the argument
805 * %ETHTOOL_ID_INACTIVE and must deactivate the indicator. Returns a 807 * %ETHTOOL_ID_INACTIVE and must deactivate the indicator. Returns a
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 41dee2de13ad..13d79f5a86e5 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -1669,7 +1669,7 @@ static int ethtool_phys_id(struct net_device *dev, void __user *useraddr)
1669 return dev->ethtool_ops->phys_id(dev, id.data); 1669 return dev->ethtool_ops->phys_id(dev, id.data);
1670 1670
1671 rc = dev->ethtool_ops->set_phys_id(dev, ETHTOOL_ID_ACTIVE); 1671 rc = dev->ethtool_ops->set_phys_id(dev, ETHTOOL_ID_ACTIVE);
1672 if (rc && rc != -EINVAL) 1672 if (rc < 0)
1673 return rc; 1673 return rc;
1674 1674
1675 /* Drop the RTNL lock while waiting, but prevent reentry or 1675 /* Drop the RTNL lock while waiting, but prevent reentry or
@@ -1684,21 +1684,22 @@ static int ethtool_phys_id(struct net_device *dev, void __user *useraddr)
1684 schedule_timeout_interruptible( 1684 schedule_timeout_interruptible(
1685 id.data ? (id.data * HZ) : MAX_SCHEDULE_TIMEOUT); 1685 id.data ? (id.data * HZ) : MAX_SCHEDULE_TIMEOUT);
1686 } else { 1686 } else {
1687 /* Driver expects to be called periodically */ 1687 /* Driver expects to be called at twice the frequency in rc */
1688 int n = rc * 2, i, interval = HZ / n;
1689
1690 /* Count down seconds */
1688 do { 1691 do {
1689 rtnl_lock(); 1692 /* Count down iterations per second */
1690 rc = dev->ethtool_ops->set_phys_id(dev, ETHTOOL_ID_ON); 1693 i = n;
1691 rtnl_unlock(); 1694 do {
1692 if (rc) 1695 rtnl_lock();
1693 break; 1696 rc = dev->ethtool_ops->set_phys_id(dev,
1694 schedule_timeout_interruptible(HZ / 2); 1697 (i & 1) ? ETHTOOL_ID_OFF : ETHTOOL_ID_ON);
1695 1698 rtnl_unlock();
1696 rtnl_lock(); 1699 if (rc)
1697 rc = dev->ethtool_ops->set_phys_id(dev, ETHTOOL_ID_OFF); 1700 break;
1698 rtnl_unlock(); 1701 schedule_timeout_interruptible(interval);
1699 if (rc) 1702 } while (!signal_pending(current) && --i != 0);
1700 break;
1701 schedule_timeout_interruptible(HZ / 2);
1702 } while (!signal_pending(current) && 1703 } while (!signal_pending(current) &&
1703 (id.data == 0 || --id.data != 0)); 1704 (id.data == 0 || --id.data != 0));
1704 } 1705 }