aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2011-05-16 13:51:24 -0400
committerBen Hutchings <bhutchings@solarflare.com>2011-05-16 18:34:28 -0400
commite4abce8538496ba90cb89909894ea42e00f96a7d (patch)
tree738f4849e775c789efb3a6cb74d24125b752ee9d /drivers/net/sfc
parent602a5322a7a1b6b005cb50d423939bb7a8782838 (diff)
sfc: Use netif_device_{detach,attach}() around reset and self-test
We need to keep the TX queues stopped throughout a reset, without triggering the TX watchdog and regardless of the link state. The proper way to do this is to use netif_device_{detach,attach}() just as we do around suspend/resume, rather than the current bodge of faking link-down. Since we also need to do this during an offline self-test and we perform a reset during that, add these function calls outside of efx_reset_down() and efx_reset_up(). Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Diffstat (limited to 'drivers/net/sfc')
-rw-r--r--drivers/net/sfc/efx.c9
-rw-r--r--drivers/net/sfc/net_driver.h4
-rw-r--r--drivers/net/sfc/selftest.c11
-rw-r--r--drivers/net/sfc/tx.c9
4 files changed, 14 insertions, 19 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 796c47e03f65..05502b359b9e 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -798,11 +798,6 @@ void efx_link_status_changed(struct efx_nic *efx)
798 if (!netif_running(efx->net_dev)) 798 if (!netif_running(efx->net_dev))
799 return; 799 return;
800 800
801 if (efx->port_inhibited) {
802 netif_carrier_off(efx->net_dev);
803 return;
804 }
805
806 if (link_state->up != netif_carrier_ok(efx->net_dev)) { 801 if (link_state->up != netif_carrier_ok(efx->net_dev)) {
807 efx->n_link_state_changes++; 802 efx->n_link_state_changes++;
808 803
@@ -1450,7 +1445,7 @@ static void efx_start_all(struct efx_nic *efx)
1450 * restart the transmit interface early so the watchdog timer stops */ 1445 * restart the transmit interface early so the watchdog timer stops */
1451 efx_start_port(efx); 1446 efx_start_port(efx);
1452 1447
1453 if (efx_dev_registered(efx) && !efx->port_inhibited) 1448 if (efx_dev_registered(efx) && netif_device_present(efx->net_dev))
1454 netif_tx_wake_all_queues(efx->net_dev); 1449 netif_tx_wake_all_queues(efx->net_dev);
1455 1450
1456 efx_for_each_channel(channel, efx) 1451 efx_for_each_channel(channel, efx)
@@ -2114,6 +2109,7 @@ int efx_reset(struct efx_nic *efx, enum reset_type method)
2114 netif_info(efx, drv, efx->net_dev, "resetting (%s)\n", 2109 netif_info(efx, drv, efx->net_dev, "resetting (%s)\n",
2115 RESET_TYPE(method)); 2110 RESET_TYPE(method));
2116 2111
2112 netif_device_detach(efx->net_dev);
2117 efx_reset_down(efx, method); 2113 efx_reset_down(efx, method);
2118 2114
2119 rc = efx->type->reset(efx, method); 2115 rc = efx->type->reset(efx, method);
@@ -2147,6 +2143,7 @@ out:
2147 efx->state = STATE_DISABLED; 2143 efx->state = STATE_DISABLED;
2148 } else { 2144 } else {
2149 netif_dbg(efx, drv, efx->net_dev, "reset complete\n"); 2145 netif_dbg(efx, drv, efx->net_dev, "reset complete\n");
2146 netif_device_attach(efx->net_dev);
2150 } 2147 }
2151 return rc; 2148 return rc;
2152} 2149}
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 5718260298c4..ce9697bac1b9 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -670,13 +670,12 @@ struct efx_filter_state;
670 * @mtd_list: List of MTDs attached to the NIC 670 * @mtd_list: List of MTDs attached to the NIC
671 * @nic_data: Hardware dependent state 671 * @nic_data: Hardware dependent state
672 * @mac_lock: MAC access lock. Protects @port_enabled, @phy_mode, 672 * @mac_lock: MAC access lock. Protects @port_enabled, @phy_mode,
673 * @port_inhibited, efx_monitor() and efx_reconfigure_port() 673 * efx_monitor() and efx_reconfigure_port()
674 * @port_enabled: Port enabled indicator. 674 * @port_enabled: Port enabled indicator.
675 * Serialises efx_stop_all(), efx_start_all(), efx_monitor() and 675 * Serialises efx_stop_all(), efx_start_all(), efx_monitor() and
676 * efx_mac_work() with kernel interfaces. Safe to read under any 676 * efx_mac_work() with kernel interfaces. Safe to read under any
677 * one of the rtnl_lock, mac_lock, or netif_tx_lock, but all three must 677 * one of the rtnl_lock, mac_lock, or netif_tx_lock, but all three must
678 * be held to modify it. 678 * be held to modify it.
679 * @port_inhibited: If set, the netif_carrier is always off. Hold the mac_lock
680 * @port_initialized: Port initialized? 679 * @port_initialized: Port initialized?
681 * @net_dev: Operating system network device. Consider holding the rtnl lock 680 * @net_dev: Operating system network device. Consider holding the rtnl lock
682 * @stats_buffer: DMA buffer for statistics 681 * @stats_buffer: DMA buffer for statistics
@@ -764,7 +763,6 @@ struct efx_nic {
764 struct mutex mac_lock; 763 struct mutex mac_lock;
765 struct work_struct mac_work; 764 struct work_struct mac_work;
766 bool port_enabled; 765 bool port_enabled;
767 bool port_inhibited;
768 766
769 bool port_initialized; 767 bool port_initialized;
770 struct net_device *net_dev; 768 struct net_device *net_dev;
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c
index 50ad3bcaf68a..822f6c2a6a7c 100644
--- a/drivers/net/sfc/selftest.c
+++ b/drivers/net/sfc/selftest.c
@@ -695,12 +695,12 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
695 /* Offline (i.e. disruptive) testing 695 /* Offline (i.e. disruptive) testing
696 * This checks MAC and PHY loopback on the specified port. */ 696 * This checks MAC and PHY loopback on the specified port. */
697 697
698 /* force the carrier state off so the kernel doesn't transmit during 698 /* Detach the device so the kernel doesn't transmit during the
699 * the loopback test, and the watchdog timeout doesn't fire. Also put 699 * loopback test and the watchdog timeout doesn't fire.
700 * falcon into loopback for the register test.
701 */ 700 */
701 netif_device_detach(efx->net_dev);
702
702 mutex_lock(&efx->mac_lock); 703 mutex_lock(&efx->mac_lock);
703 efx->port_inhibited = true;
704 if (efx->loopback_modes) { 704 if (efx->loopback_modes) {
705 /* We need the 312 clock from the PHY to test the XMAC 705 /* We need the 312 clock from the PHY to test the XMAC
706 * registers, so move into XGMII loopback if available */ 706 * registers, so move into XGMII loopback if available */
@@ -750,12 +750,11 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
750 /* restore the PHY to the previous state */ 750 /* restore the PHY to the previous state */
751 mutex_lock(&efx->mac_lock); 751 mutex_lock(&efx->mac_lock);
752 efx->phy_mode = phy_mode; 752 efx->phy_mode = phy_mode;
753 efx->port_inhibited = false;
754 efx->loopback_mode = loopback_mode; 753 efx->loopback_mode = loopback_mode;
755 __efx_reconfigure_port(efx); 754 __efx_reconfigure_port(efx);
756 mutex_unlock(&efx->mac_lock); 755 mutex_unlock(&efx->mac_lock);
757 756
758 netif_tx_wake_all_queues(efx->net_dev); 757 netif_device_attach(efx->net_dev);
759 758
760 return rc_test; 759 return rc_test;
761} 760}
diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c
index d2c85dfdf3bf..84eb99e0f8d2 100644
--- a/drivers/net/sfc/tx.c
+++ b/drivers/net/sfc/tx.c
@@ -205,7 +205,9 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
205 goto unwind; 205 goto unwind;
206 } 206 }
207 smp_mb(); 207 smp_mb();
208 netif_tx_start_queue(tx_queue->core_txq); 208 if (likely(!efx->loopback_selftest))
209 netif_tx_start_queue(
210 tx_queue->core_txq);
209 } 211 }
210 212
211 insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask; 213 insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask;
@@ -338,8 +340,7 @@ netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb,
338 struct efx_tx_queue *tx_queue; 340 struct efx_tx_queue *tx_queue;
339 unsigned index, type; 341 unsigned index, type;
340 342
341 if (unlikely(efx->port_inhibited)) 343 EFX_WARN_ON_PARANOID(!netif_device_present(net_dev));
342 return NETDEV_TX_BUSY;
343 344
344 index = skb_get_queue_mapping(skb); 345 index = skb_get_queue_mapping(skb);
345 type = skb->ip_summed == CHECKSUM_PARTIAL ? EFX_TXQ_TYPE_OFFLOAD : 0; 346 type = skb->ip_summed == CHECKSUM_PARTIAL ? EFX_TXQ_TYPE_OFFLOAD : 0;
@@ -436,7 +437,7 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index)
436 smp_mb(); 437 smp_mb();
437 if (unlikely(netif_tx_queue_stopped(tx_queue->core_txq)) && 438 if (unlikely(netif_tx_queue_stopped(tx_queue->core_txq)) &&
438 likely(efx->port_enabled) && 439 likely(efx->port_enabled) &&
439 likely(!efx->port_inhibited)) { 440 likely(netif_device_present(efx->net_dev))) {
440 fill_level = tx_queue->insert_count - tx_queue->read_count; 441 fill_level = tx_queue->insert_count - tx_queue->read_count;
441 if (fill_level < EFX_TXQ_THRESHOLD(efx)) { 442 if (fill_level < EFX_TXQ_THRESHOLD(efx)) {
442 EFX_BUG_ON_PARANOID(!efx_dev_registered(efx)); 443 EFX_BUG_ON_PARANOID(!efx_dev_registered(efx));