aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorInaky Perez-Gonzalez <inaky@linux.intel.com>2009-10-19 03:24:56 -0400
committerInaky Perez-Gonzalez <inaky@linux.intel.com>2009-11-03 15:49:36 -0500
commitc931ceeb780560ff652a8f9875f88778439ee87e (patch)
treeca754722967ff1b9a4660ef38b0eae3d36f38a58 /drivers
parent55a662d6468005ec3cd799fbd8d0ad03dfae6d2a (diff)
wimax/i2400m: introduce i2400m_reset(), stopping TX and carrier
Currently the i2400m driver was resetting by just calling i2400m->bus_reset(). However, this was missing stopping the TX queue and downing the carrier. This was causing, for the corner case of the driver reseting a device that refuses to go out of idle mode, that a few packets would be queued and more than one reset would go through, making the recovery a wee bit messy. To avoid introducing the same cleanup in all the bus-specific driver, introduced a i2400m_reset() function that takes care of house cleaning and then calling the bus-level reset implementation. The bulk of the changes in all files are just to rename the call from i2400m->bus_reset() to i2400m_reset(). Signed-off-by: Inaky Perez-Gonzalez <inaky@linux.intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wimax/i2400m/control.c4
-rw-r--r--drivers/net/wimax/i2400m/debugfs.c2
-rw-r--r--drivers/net/wimax/i2400m/driver.c22
-rw-r--r--drivers/net/wimax/i2400m/fw.c4
-rw-r--r--drivers/net/wimax/i2400m/i2400m.h1
-rw-r--r--drivers/net/wimax/i2400m/netdev.c8
-rw-r--r--drivers/net/wimax/i2400m/rx.c4
-rw-r--r--drivers/net/wimax/i2400m/sdio.c9
-rw-r--r--drivers/net/wimax/i2400m/usb.c2
9 files changed, 35 insertions, 21 deletions
diff --git a/drivers/net/wimax/i2400m/control.c b/drivers/net/wimax/i2400m/control.c
index b69fd8834c78..944945540391 100644
--- a/drivers/net/wimax/i2400m/control.c
+++ b/drivers/net/wimax/i2400m/control.c
@@ -54,7 +54,7 @@
54 * i2400m_set_init_config() 54 * i2400m_set_init_config()
55 * i2400m_cmd_get_state() 55 * i2400m_cmd_get_state()
56 * i2400m_dev_shutdown() Called by i2400m_dev_stop() 56 * i2400m_dev_shutdown() Called by i2400m_dev_stop()
57 * i2400m->bus_reset() 57 * i2400m_reset()
58 * 58 *
59 * i2400m_{cmd,get,set}_*() 59 * i2400m_{cmd,get,set}_*()
60 * i2400m_msg_to_dev() 60 * i2400m_msg_to_dev()
@@ -343,7 +343,7 @@ void i2400m_report_tlv_system_state(struct i2400m *i2400m,
343 /* Huh? just in case, shut it down */ 343 /* Huh? just in case, shut it down */
344 dev_err(dev, "HW BUG? unknown state %u: shutting down\n", 344 dev_err(dev, "HW BUG? unknown state %u: shutting down\n",
345 i2400m_state); 345 i2400m_state);
346 i2400m->bus_reset(i2400m, I2400M_RT_WARM); 346 i2400m_reset(i2400m, I2400M_RT_WARM);
347 break; 347 break;
348 }; 348 };
349 d_fnend(3, dev, "(i2400m %p ss %p [%u]) = void\n", 349 d_fnend(3, dev, "(i2400m %p ss %p [%u]) = void\n",
diff --git a/drivers/net/wimax/i2400m/debugfs.c b/drivers/net/wimax/i2400m/debugfs.c
index 9b81af3f80a9..b1aec3e1892f 100644
--- a/drivers/net/wimax/i2400m/debugfs.c
+++ b/drivers/net/wimax/i2400m/debugfs.c
@@ -214,7 +214,7 @@ int debugfs_i2400m_reset_set(void *data, u64 val)
214 case I2400M_RT_WARM: 214 case I2400M_RT_WARM:
215 case I2400M_RT_COLD: 215 case I2400M_RT_COLD:
216 case I2400M_RT_BUS: 216 case I2400M_RT_BUS:
217 result = i2400m->bus_reset(i2400m, rt); 217 result = i2400m_reset(i2400m, rt);
218 if (result >= 0) 218 if (result >= 0)
219 result = 0; 219 result = 0;
220 default: 220 default:
diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c
index cc58a864bd06..96a615fe09de 100644
--- a/drivers/net/wimax/i2400m/driver.c
+++ b/drivers/net/wimax/i2400m/driver.c
@@ -255,7 +255,7 @@ int i2400m_op_reset(struct wimax_dev *wimax_dev)
255 mutex_lock(&i2400m->init_mutex); 255 mutex_lock(&i2400m->init_mutex);
256 i2400m->reset_ctx = &ctx; 256 i2400m->reset_ctx = &ctx;
257 mutex_unlock(&i2400m->init_mutex); 257 mutex_unlock(&i2400m->init_mutex);
258 result = i2400m->bus_reset(i2400m, I2400M_RT_WARM); 258 result = i2400m_reset(i2400m, I2400M_RT_WARM);
259 if (result < 0) 259 if (result < 0)
260 goto out; 260 goto out;
261 result = wait_for_completion_timeout(&ctx.completion, 4*HZ); 261 result = wait_for_completion_timeout(&ctx.completion, 4*HZ);
@@ -710,7 +710,7 @@ out_unlock:
710 mutex_unlock(&i2400m->init_mutex); 710 mutex_unlock(&i2400m->init_mutex);
711 if (result == -EUCLEAN) { 711 if (result == -EUCLEAN) {
712 /* ops, need to clean up [w/ init_mutex not held] */ 712 /* ops, need to clean up [w/ init_mutex not held] */
713 result = i2400m->bus_reset(i2400m, I2400M_RT_BUS); 713 result = i2400m_reset(i2400m, I2400M_RT_BUS);
714 if (result >= 0) 714 if (result >= 0)
715 result = -ENODEV; 715 result = -ENODEV;
716 } 716 }
@@ -815,6 +815,24 @@ void i2400m_init(struct i2400m *i2400m)
815EXPORT_SYMBOL_GPL(i2400m_init); 815EXPORT_SYMBOL_GPL(i2400m_init);
816 816
817 817
818int i2400m_reset(struct i2400m *i2400m, enum i2400m_reset_type rt)
819{
820 struct net_device *net_dev = i2400m->wimax_dev.net_dev;
821
822 /*
823 * Make sure we stop TXs and down the carrier before
824 * resetting; this is needed to avoid things like
825 * i2400m_wake_tx() scheduling stuff in parallel.
826 */
827 if (net_dev->reg_state == NETREG_REGISTERED) {
828 netif_tx_disable(net_dev);
829 netif_carrier_off(net_dev);
830 }
831 return i2400m->bus_reset(i2400m, rt);
832}
833EXPORT_SYMBOL_GPL(i2400m_reset);
834
835
818/** 836/**
819 * i2400m_setup - bus-generic setup function for the i2400m device 837 * i2400m_setup - bus-generic setup function for the i2400m device
820 * 838 *
diff --git a/drivers/net/wimax/i2400m/fw.c b/drivers/net/wimax/i2400m/fw.c
index fda54bfdf70e..64cdfeb299ca 100644
--- a/drivers/net/wimax/i2400m/fw.c
+++ b/drivers/net/wimax/i2400m/fw.c
@@ -130,7 +130,7 @@
130 * i2400m_fw_dnload 130 * i2400m_fw_dnload
131 * i2400m_bootrom_init 131 * i2400m_bootrom_init
132 * i2400m_bm_cmd 132 * i2400m_bm_cmd
133 * i2400m->bus_reset 133 * i2400m_reset
134 * i2400m_dnload_init 134 * i2400m_dnload_init
135 * i2400m_dnload_init_signed 135 * i2400m_dnload_init_signed
136 * i2400m_dnload_init_nonsigned 136 * i2400m_dnload_init_nonsigned
@@ -902,7 +902,7 @@ do_reboot:
902 d_printf(4, dev, "device reboot: reboot command [%d # left]\n", 902 d_printf(4, dev, "device reboot: reboot command [%d # left]\n",
903 count); 903 count);
904 if ((flags & I2400M_BRI_NO_REBOOT) == 0) 904 if ((flags & I2400M_BRI_NO_REBOOT) == 0)
905 i2400m->bus_reset(i2400m, I2400M_RT_WARM); 905 i2400m_reset(i2400m, I2400M_RT_WARM);
906 result = i2400m_bm_cmd(i2400m, NULL, 0, &ack, sizeof(ack), 906 result = i2400m_bm_cmd(i2400m, NULL, 0, &ack, sizeof(ack),
907 I2400M_BM_CMD_RAW); 907 I2400M_BM_CMD_RAW);
908 flags &= ~I2400M_BRI_NO_REBOOT; 908 flags &= ~I2400M_BRI_NO_REBOOT;
diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h
index 5eee985f2926..04df9bbe340f 100644
--- a/drivers/net/wimax/i2400m/i2400m.h
+++ b/drivers/net/wimax/i2400m/i2400m.h
@@ -717,6 +717,7 @@ unsigned i2400m_brh_get_signature(const struct i2400m_bootrom_header *hdr)
717 * Driver / device setup and internal functions 717 * Driver / device setup and internal functions
718 */ 718 */
719extern void i2400m_init(struct i2400m *); 719extern void i2400m_init(struct i2400m *);
720extern int i2400m_reset(struct i2400m *, enum i2400m_reset_type);
720extern void i2400m_netdev_setup(struct net_device *net_dev); 721extern void i2400m_netdev_setup(struct net_device *net_dev);
721extern int i2400m_sysfs_setup(struct device_driver *); 722extern int i2400m_sysfs_setup(struct device_driver *);
722extern void i2400m_sysfs_release(struct device_driver *); 723extern void i2400m_sysfs_release(struct device_driver *);
diff --git a/drivers/net/wimax/i2400m/netdev.c b/drivers/net/wimax/i2400m/netdev.c
index e7d1a51ee3fe..f67af4291f8c 100644
--- a/drivers/net/wimax/i2400m/netdev.c
+++ b/drivers/net/wimax/i2400m/netdev.c
@@ -171,8 +171,9 @@ void i2400m_wake_tx_work(struct work_struct *ws)
171 result = 0; 171 result = 0;
172 if (result < 0) { 172 if (result < 0) {
173 dev_err(dev, "WAKE&TX: device didn't get out of idle: " 173 dev_err(dev, "WAKE&TX: device didn't get out of idle: "
174 "%d\n", result); 174 "%d - resetting\n", result);
175 goto error; 175 i2400m_reset(i2400m, I2400M_RT_BUS);
176 goto error;
176 } 177 }
177 result = wait_event_timeout(i2400m->state_wq, 178 result = wait_event_timeout(i2400m->state_wq,
178 i2400m->state != I2400M_SS_IDLE, 5 * HZ); 179 i2400m->state != I2400M_SS_IDLE, 5 * HZ);
@@ -180,7 +181,8 @@ void i2400m_wake_tx_work(struct work_struct *ws)
180 result = -ETIMEDOUT; 181 result = -ETIMEDOUT;
181 if (result < 0) { 182 if (result < 0) {
182 dev_err(dev, "WAKE&TX: error waiting for device to exit IDLE: " 183 dev_err(dev, "WAKE&TX: error waiting for device to exit IDLE: "
183 "%d\n", result); 184 "%d - resetting\n", result);
185 i2400m_reset(i2400m, I2400M_RT_BUS);
184 goto error; 186 goto error;
185 } 187 }
186 msleep(20); /* device still needs some time or it drops it */ 188 msleep(20); /* device still needs some time or it drops it */
diff --git a/drivers/net/wimax/i2400m/rx.c b/drivers/net/wimax/i2400m/rx.c
index 64a44ca00675..e3d2a9de023c 100644
--- a/drivers/net/wimax/i2400m/rx.c
+++ b/drivers/net/wimax/i2400m/rx.c
@@ -828,7 +828,7 @@ void i2400m_roq_queue(struct i2400m *i2400m, struct i2400m_roq *roq,
828 dev_err(dev, "SW BUG? queue nsn %d (lbn %u ws %u)\n", 828 dev_err(dev, "SW BUG? queue nsn %d (lbn %u ws %u)\n",
829 nsn, lbn, roq->ws); 829 nsn, lbn, roq->ws);
830 i2400m_roq_log_dump(i2400m, roq); 830 i2400m_roq_log_dump(i2400m, roq);
831 i2400m->bus_reset(i2400m, I2400M_RT_WARM); 831 i2400m_reset(i2400m, I2400M_RT_WARM);
832 } else { 832 } else {
833 __i2400m_roq_queue(i2400m, roq, skb, lbn, nsn); 833 __i2400m_roq_queue(i2400m, roq, skb, lbn, nsn);
834 i2400m_roq_log_add(i2400m, roq, I2400M_RO_TYPE_PACKET, 834 i2400m_roq_log_add(i2400m, roq, I2400M_RO_TYPE_PACKET,
@@ -894,7 +894,7 @@ void i2400m_roq_queue_update_ws(struct i2400m *i2400m, struct i2400m_roq *roq,
894 dev_err(dev, "SW BUG? queue_update_ws nsn %u (sn %u ws %u)\n", 894 dev_err(dev, "SW BUG? queue_update_ws nsn %u (sn %u ws %u)\n",
895 nsn, sn, roq->ws); 895 nsn, sn, roq->ws);
896 i2400m_roq_log_dump(i2400m, roq); 896 i2400m_roq_log_dump(i2400m, roq);
897 i2400m->bus_reset(i2400m, I2400M_RT_WARM); 897 i2400m_reset(i2400m, I2400M_RT_WARM);
898 } else { 898 } else {
899 /* if the queue is empty, don't bother as we'd queue 899 /* if the queue is empty, don't bother as we'd queue
900 * it and inmediately unqueue it -- just deliver it */ 900 * it and inmediately unqueue it -- just deliver it */
diff --git a/drivers/net/wimax/i2400m/sdio.c b/drivers/net/wimax/i2400m/sdio.c
index ec178928914e..20ab22ec291b 100644
--- a/drivers/net/wimax/i2400m/sdio.c
+++ b/drivers/net/wimax/i2400m/sdio.c
@@ -43,7 +43,7 @@
43 * i2400m_release() 43 * i2400m_release()
44 * free_netdev(net_dev) 44 * free_netdev(net_dev)
45 * 45 *
46 * i2400ms_bus_reset() Called by i2400m->bus_reset 46 * i2400ms_bus_reset() Called by i2400m_reset
47 * __i2400ms_reset() 47 * __i2400ms_reset()
48 * __i2400ms_send_barker() 48 * __i2400ms_send_barker()
49 */ 49 */
@@ -342,13 +342,6 @@ int i2400ms_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt)
342 sizeof(i2400m_COLD_BOOT_BARKER)); 342 sizeof(i2400m_COLD_BOOT_BARKER));
343 else if (rt == I2400M_RT_BUS) { 343 else if (rt == I2400M_RT_BUS) {
344do_bus_reset: 344do_bus_reset:
345 /* call netif_tx_disable() before sending IOE disable,
346 * so that all the tx from network layer are stopped
347 * while IOE is being reset. Make sure it is called
348 * only after register_netdev() was issued.
349 */
350 if (i2400m->wimax_dev.net_dev->reg_state == NETREG_REGISTERED)
351 netif_tx_disable(i2400m->wimax_dev.net_dev);
352 345
353 i2400ms_bus_release(i2400m); 346 i2400ms_bus_release(i2400m);
354 347
diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c
index 418db12b0cd7..5e079408f16e 100644
--- a/drivers/net/wimax/i2400m/usb.c
+++ b/drivers/net/wimax/i2400m/usb.c
@@ -58,7 +58,7 @@
58 * i2400mu_rx_release() 58 * i2400mu_rx_release()
59 * i2400mu_tx_release() 59 * i2400mu_tx_release()
60 * 60 *
61 * i2400mu_bus_reset() Called by i2400m->bus_reset 61 * i2400mu_bus_reset() Called by i2400m_reset
62 * __i2400mu_reset() 62 * __i2400mu_reset()
63 * __i2400mu_send_barker() 63 * __i2400mu_send_barker()
64 * usb_reset_device() 64 * usb_reset_device()