aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wimax/i2400m/driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wimax/i2400m/driver.c')
-rw-r--r--drivers/net/wimax/i2400m/driver.c45
1 files changed, 30 insertions, 15 deletions
diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c
index 07a54bad237b..304f0443ca4b 100644
--- a/drivers/net/wimax/i2400m/driver.c
+++ b/drivers/net/wimax/i2400m/driver.c
@@ -62,6 +62,7 @@
62 * unregister_netdev() 62 * unregister_netdev()
63 */ 63 */
64#include "i2400m.h" 64#include "i2400m.h"
65#include <linux/etherdevice.h>
65#include <linux/wimax/i2400m.h> 66#include <linux/wimax/i2400m.h>
66#include <linux/module.h> 67#include <linux/module.h>
67#include <linux/moduleparam.h> 68#include <linux/moduleparam.h>
@@ -81,6 +82,14 @@ module_param_named(rx_reorder_disabled, i2400m_rx_reorder_disabled, int, 0644);
81MODULE_PARM_DESC(rx_reorder_disabled, 82MODULE_PARM_DESC(rx_reorder_disabled,
82 "If true, RX reordering will be disabled."); 83 "If true, RX reordering will be disabled.");
83 84
85int i2400m_power_save_disabled; /* 0 (power saving enabled) by default */
86module_param_named(power_save_disabled, i2400m_power_save_disabled, int, 0644);
87MODULE_PARM_DESC(power_save_disabled,
88 "If true, the driver will not tell the device to enter "
89 "power saving mode when it reports it is ready for it. "
90 "False by default (so the device is told to do power "
91 "saving).");
92
84/** 93/**
85 * i2400m_queue_work - schedule work on a i2400m's queue 94 * i2400m_queue_work - schedule work on a i2400m's queue
86 * 95 *
@@ -171,7 +180,6 @@ int i2400m_schedule_work(struct i2400m *i2400m,
171 int result; 180 int result;
172 struct i2400m_work *iw; 181 struct i2400m_work *iw;
173 182
174 BUG_ON(i2400m->work_queue == NULL);
175 result = -ENOMEM; 183 result = -ENOMEM;
176 iw = kzalloc(sizeof(*iw), gfp_flags); 184 iw = kzalloc(sizeof(*iw), gfp_flags);
177 if (iw == NULL) 185 if (iw == NULL)
@@ -234,9 +242,6 @@ int i2400m_op_msg_from_user(struct wimax_dev *wimax_dev,
234 result = PTR_ERR(ack_skb); 242 result = PTR_ERR(ack_skb);
235 if (IS_ERR(ack_skb)) 243 if (IS_ERR(ack_skb))
236 goto error_msg_to_dev; 244 goto error_msg_to_dev;
237 if (unlikely(i2400m->trace_msg_from_user))
238 wimax_msg(&i2400m->wimax_dev, "trace",
239 msg_buf, msg_len, GFP_KERNEL);
240 result = wimax_msg_send(&i2400m->wimax_dev, ack_skb); 245 result = wimax_msg_send(&i2400m->wimax_dev, ack_skb);
241error_msg_to_dev: 246error_msg_to_dev:
242 d_fnend(4, dev, "(wimax_dev %p [i2400m %p] msg_buf %p msg_len %zu " 247 d_fnend(4, dev, "(wimax_dev %p [i2400m %p] msg_buf %p msg_len %zu "
@@ -379,6 +384,11 @@ error:
379 * Uploads firmware and brings up all the resources needed to be able 384 * Uploads firmware and brings up all the resources needed to be able
380 * to communicate with the device. 385 * to communicate with the device.
381 * 386 *
387 * The workqueue has to be setup early, at least before RX handling
388 * (it's only real user for now) so it can process reports as they
389 * arrive. We also want to destroy it if we retry, to make sure it is
390 * flushed...easier like this.
391 *
382 * TX needs to be setup before the bus-specific code (otherwise on 392 * TX needs to be setup before the bus-specific code (otherwise on
383 * shutdown, the bus-tx code could try to access it). 393 * shutdown, the bus-tx code could try to access it).
384 */ 394 */
@@ -389,7 +399,7 @@ int __i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri flags)
389 struct wimax_dev *wimax_dev = &i2400m->wimax_dev; 399 struct wimax_dev *wimax_dev = &i2400m->wimax_dev;
390 struct net_device *net_dev = wimax_dev->net_dev; 400 struct net_device *net_dev = wimax_dev->net_dev;
391 struct device *dev = i2400m_dev(i2400m); 401 struct device *dev = i2400m_dev(i2400m);
392 int times = 3; 402 int times = i2400m->bus_bm_retries;
393 403
394 d_fnstart(3, dev, "(i2400m %p)\n", i2400m); 404 d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
395retry: 405retry:
@@ -404,15 +414,15 @@ retry:
404 result = i2400m_rx_setup(i2400m); 414 result = i2400m_rx_setup(i2400m);
405 if (result < 0) 415 if (result < 0)
406 goto error_rx_setup; 416 goto error_rx_setup;
407 result = i2400m->bus_dev_start(i2400m);
408 if (result < 0)
409 goto error_bus_dev_start;
410 i2400m->work_queue = create_singlethread_workqueue(wimax_dev->name); 417 i2400m->work_queue = create_singlethread_workqueue(wimax_dev->name);
411 if (i2400m->work_queue == NULL) { 418 if (i2400m->work_queue == NULL) {
412 result = -ENOMEM; 419 result = -ENOMEM;
413 dev_err(dev, "cannot create workqueue\n"); 420 dev_err(dev, "cannot create workqueue\n");
414 goto error_create_workqueue; 421 goto error_create_workqueue;
415 } 422 }
423 result = i2400m->bus_dev_start(i2400m);
424 if (result < 0)
425 goto error_bus_dev_start;
416 result = i2400m_firmware_check(i2400m); /* fw versions ok? */ 426 result = i2400m_firmware_check(i2400m); /* fw versions ok? */
417 if (result < 0) 427 if (result < 0)
418 goto error_fw_check; 428 goto error_fw_check;
@@ -434,17 +444,17 @@ retry:
434error_dev_initialize: 444error_dev_initialize:
435error_check_mac_addr: 445error_check_mac_addr:
436error_fw_check: 446error_fw_check:
437 destroy_workqueue(i2400m->work_queue);
438error_create_workqueue:
439 i2400m->bus_dev_stop(i2400m); 447 i2400m->bus_dev_stop(i2400m);
440error_bus_dev_start: 448error_bus_dev_start:
449 destroy_workqueue(i2400m->work_queue);
450error_create_workqueue:
441 i2400m_rx_release(i2400m); 451 i2400m_rx_release(i2400m);
442error_rx_setup: 452error_rx_setup:
443 i2400m_tx_release(i2400m); 453 i2400m_tx_release(i2400m);
444error_tx_setup: 454error_tx_setup:
445error_bootstrap: 455error_bootstrap:
446 if (result == -ERESTARTSYS && times-- > 0) { 456 if (result == -EL3RST && times-- > 0) {
447 flags = I2400M_BRI_SOFT; 457 flags = I2400M_BRI_SOFT|I2400M_BRI_MAC_REINIT;
448 goto retry; 458 goto retry;
449 } 459 }
450 d_fnend(3, dev, "(net_dev %p [i2400m %p]) = %d\n", 460 d_fnend(3, dev, "(net_dev %p [i2400m %p]) = %d\n",
@@ -473,7 +483,9 @@ int i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri bm_flags)
473 * 483 *
474 * Returns: 0 if ok, < 0 errno code on error. 484 * Returns: 0 if ok, < 0 errno code on error.
475 * 485 *
476 * Releases all the resources allocated to communicate with the device. 486 * Releases all the resources allocated to communicate with the
487 * device. Note we cannot destroy the workqueue earlier as until RX is
488 * fully destroyed, it could still try to schedule jobs.
477 */ 489 */
478static 490static
479void __i2400m_dev_stop(struct i2400m *i2400m) 491void __i2400m_dev_stop(struct i2400m *i2400m)
@@ -485,8 +497,8 @@ void __i2400m_dev_stop(struct i2400m *i2400m)
485 wimax_state_change(wimax_dev, __WIMAX_ST_QUIESCING); 497 wimax_state_change(wimax_dev, __WIMAX_ST_QUIESCING);
486 i2400m_dev_shutdown(i2400m); 498 i2400m_dev_shutdown(i2400m);
487 i2400m->ready = 0; 499 i2400m->ready = 0;
488 destroy_workqueue(i2400m->work_queue);
489 i2400m->bus_dev_stop(i2400m); 500 i2400m->bus_dev_stop(i2400m);
501 destroy_workqueue(i2400m->work_queue);
490 i2400m_rx_release(i2400m); 502 i2400m_rx_release(i2400m);
491 i2400m_tx_release(i2400m); 503 i2400m_tx_release(i2400m);
492 wimax_state_change(wimax_dev, WIMAX_ST_DOWN); 504 wimax_state_change(wimax_dev, WIMAX_ST_DOWN);
@@ -548,7 +560,7 @@ void __i2400m_dev_reset_handle(struct work_struct *ws)
548 * i2400m_dev_stop() [we are shutting down anyway, so 560 * i2400m_dev_stop() [we are shutting down anyway, so
549 * ignore it] or we are resetting somewhere else. */ 561 * ignore it] or we are resetting somewhere else. */
550 dev_err(dev, "device rebooted\n"); 562 dev_err(dev, "device rebooted\n");
551 i2400m_msg_to_dev_cancel_wait(i2400m, -ERESTARTSYS); 563 i2400m_msg_to_dev_cancel_wait(i2400m, -EL3RST);
552 complete(&i2400m->msg_completion); 564 complete(&i2400m->msg_completion);
553 goto out; 565 goto out;
554 } 566 }
@@ -598,6 +610,8 @@ out:
598 */ 610 */
599int i2400m_dev_reset_handle(struct i2400m *i2400m) 611int i2400m_dev_reset_handle(struct i2400m *i2400m)
600{ 612{
613 i2400m->boot_mode = 1;
614 wmb(); /* Make sure i2400m_msg_to_dev() sees boot_mode */
601 return i2400m_schedule_work(i2400m, __i2400m_dev_reset_handle, 615 return i2400m_schedule_work(i2400m, __i2400m_dev_reset_handle,
602 GFP_ATOMIC); 616 GFP_ATOMIC);
603} 617}
@@ -650,6 +664,7 @@ int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags)
650 result = i2400m_read_mac_addr(i2400m); 664 result = i2400m_read_mac_addr(i2400m);
651 if (result < 0) 665 if (result < 0)
652 goto error_read_mac_addr; 666 goto error_read_mac_addr;
667 random_ether_addr(i2400m->src_mac_addr);
653 668
654 result = register_netdev(net_dev); /* Okey dokey, bring it up */ 669 result = register_netdev(net_dev); /* Okey dokey, bring it up */
655 if (result < 0) { 670 if (result < 0) {