aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-06-11 20:11:33 -0400
committerDavid S. Miller <davem@davemloft.net>2009-06-11 20:11:33 -0400
commit3ee40c376ad3252d13946141588db7e2f435f958 (patch)
tree65bd16c024edab1ff74ad165779443edfaa26467 /drivers
parent670025478c2a687453cd1bac697d7d765843f59d (diff)
parent98eb0f53e2fc66482e2ea8033c58b20a079e5260 (diff)
Merge branch 'linux-2.6.31.y' of git://git.kernel.org/pub/scm/linux/kernel/git/inaky/wimax
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wimax/i2400m/control.c24
-rw-r--r--drivers/net/wimax/i2400m/driver.c40
-rw-r--r--drivers/net/wimax/i2400m/fw.c58
-rw-r--r--drivers/net/wimax/i2400m/i2400m-sdio.h9
-rw-r--r--drivers/net/wimax/i2400m/i2400m.h43
-rw-r--r--drivers/net/wimax/i2400m/op-rfkill.c4
-rw-r--r--drivers/net/wimax/i2400m/rx.c4
-rw-r--r--drivers/net/wimax/i2400m/sdio-fw.c109
-rw-r--r--drivers/net/wimax/i2400m/sdio-rx.c47
-rw-r--r--drivers/net/wimax/i2400m/sdio.c50
-rw-r--r--drivers/net/wimax/i2400m/tx.c75
-rw-r--r--drivers/net/wimax/i2400m/usb.c5
12 files changed, 317 insertions, 151 deletions
diff --git a/drivers/net/wimax/i2400m/control.c b/drivers/net/wimax/i2400m/control.c
index bd193ae2178b..07308686dbcf 100644
--- a/drivers/net/wimax/i2400m/control.c
+++ b/drivers/net/wimax/i2400m/control.c
@@ -505,8 +505,15 @@ void i2400m_report_hook(struct i2400m *i2400m,
505 * it. */ 505 * it. */
506 case I2400M_MT_REPORT_POWERSAVE_READY: /* zzzzz */ 506 case I2400M_MT_REPORT_POWERSAVE_READY: /* zzzzz */
507 if (l3l4_hdr->status == cpu_to_le16(I2400M_MS_DONE_OK)) { 507 if (l3l4_hdr->status == cpu_to_le16(I2400M_MS_DONE_OK)) {
508 d_printf(1, dev, "ready for powersave, requesting\n"); 508 if (i2400m_power_save_disabled)
509 i2400m_cmd_enter_powersave(i2400m); 509 d_printf(1, dev, "ready for powersave, "
510 "not requesting (disabled by module "
511 "parameter)\n");
512 else {
513 d_printf(1, dev, "ready for powersave, "
514 "requesting\n");
515 i2400m_cmd_enter_powersave(i2400m);
516 }
510 } 517 }
511 break; 518 break;
512 }; 519 };
@@ -688,8 +695,9 @@ struct sk_buff *i2400m_msg_to_dev(struct i2400m *i2400m,
688 d_fnstart(3, dev, "(i2400m %p buf %p len %zu)\n", 695 d_fnstart(3, dev, "(i2400m %p buf %p len %zu)\n",
689 i2400m, buf, buf_len); 696 i2400m, buf, buf_len);
690 697
698 rmb(); /* Make sure we see what i2400m_dev_reset_handle() */
691 if (i2400m->boot_mode) 699 if (i2400m->boot_mode)
692 return ERR_PTR(-ENODEV); 700 return ERR_PTR(-EL3RST);
693 701
694 msg_l3l4_hdr = buf; 702 msg_l3l4_hdr = buf;
695 /* Check msg & payload consistency */ 703 /* Check msg & payload consistency */
@@ -1389,16 +1397,16 @@ error:
1389 * 1397 *
1390 * @i2400m: device descriptor 1398 * @i2400m: device descriptor
1391 * 1399 *
1392 * Gracefully stops the device, moving it to the lowest power 1400 * Release resources acquired during the running of the device; in
1393 * consumption state possible. 1401 * theory, should also tell the device to go to sleep, switch off the
1402 * radio, all that, but at this point, in most cases (driver
1403 * disconnection, reset handling) we can't even talk to the device.
1394 */ 1404 */
1395void i2400m_dev_shutdown(struct i2400m *i2400m) 1405void i2400m_dev_shutdown(struct i2400m *i2400m)
1396{ 1406{
1397 int result = -ENODEV;
1398 struct device *dev = i2400m_dev(i2400m); 1407 struct device *dev = i2400m_dev(i2400m);
1399 1408
1400 d_fnstart(3, dev, "(i2400m %p)\n", i2400m); 1409 d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
1401 result = i2400m->bus_reset(i2400m, I2400M_RT_WARM); 1410 d_fnend(3, dev, "(i2400m %p) = void\n", i2400m);
1402 d_fnend(3, dev, "(i2400m %p) = void [%d]\n", i2400m, result);
1403 return; 1411 return;
1404} 1412}
diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c
index ef16c573bb22..304f0443ca4b 100644
--- a/drivers/net/wimax/i2400m/driver.c
+++ b/drivers/net/wimax/i2400m/driver.c
@@ -82,6 +82,14 @@ module_param_named(rx_reorder_disabled, i2400m_rx_reorder_disabled, int, 0644);
82MODULE_PARM_DESC(rx_reorder_disabled, 82MODULE_PARM_DESC(rx_reorder_disabled,
83 "If true, RX reordering will be disabled."); 83 "If true, RX reordering will be disabled.");
84 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
85/** 93/**
86 * i2400m_queue_work - schedule work on a i2400m's queue 94 * i2400m_queue_work - schedule work on a i2400m's queue
87 * 95 *
@@ -172,7 +180,6 @@ int i2400m_schedule_work(struct i2400m *i2400m,
172 int result; 180 int result;
173 struct i2400m_work *iw; 181 struct i2400m_work *iw;
174 182
175 BUG_ON(i2400m->work_queue == NULL);
176 result = -ENOMEM; 183 result = -ENOMEM;
177 iw = kzalloc(sizeof(*iw), gfp_flags); 184 iw = kzalloc(sizeof(*iw), gfp_flags);
178 if (iw == NULL) 185 if (iw == NULL)
@@ -377,6 +384,11 @@ error:
377 * 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
378 * to communicate with the device. 385 * to communicate with the device.
379 * 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 *
380 * 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
381 * shutdown, the bus-tx code could try to access it). 393 * shutdown, the bus-tx code could try to access it).
382 */ 394 */
@@ -387,7 +399,7 @@ int __i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri flags)
387 struct wimax_dev *wimax_dev = &i2400m->wimax_dev; 399 struct wimax_dev *wimax_dev = &i2400m->wimax_dev;
388 struct net_device *net_dev = wimax_dev->net_dev; 400 struct net_device *net_dev = wimax_dev->net_dev;
389 struct device *dev = i2400m_dev(i2400m); 401 struct device *dev = i2400m_dev(i2400m);
390 int times = 3; 402 int times = i2400m->bus_bm_retries;
391 403
392 d_fnstart(3, dev, "(i2400m %p)\n", i2400m); 404 d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
393retry: 405retry:
@@ -402,15 +414,15 @@ retry:
402 result = i2400m_rx_setup(i2400m); 414 result = i2400m_rx_setup(i2400m);
403 if (result < 0) 415 if (result < 0)
404 goto error_rx_setup; 416 goto error_rx_setup;
405 result = i2400m->bus_dev_start(i2400m);
406 if (result < 0)
407 goto error_bus_dev_start;
408 i2400m->work_queue = create_singlethread_workqueue(wimax_dev->name); 417 i2400m->work_queue = create_singlethread_workqueue(wimax_dev->name);
409 if (i2400m->work_queue == NULL) { 418 if (i2400m->work_queue == NULL) {
410 result = -ENOMEM; 419 result = -ENOMEM;
411 dev_err(dev, "cannot create workqueue\n"); 420 dev_err(dev, "cannot create workqueue\n");
412 goto error_create_workqueue; 421 goto error_create_workqueue;
413 } 422 }
423 result = i2400m->bus_dev_start(i2400m);
424 if (result < 0)
425 goto error_bus_dev_start;
414 result = i2400m_firmware_check(i2400m); /* fw versions ok? */ 426 result = i2400m_firmware_check(i2400m); /* fw versions ok? */
415 if (result < 0) 427 if (result < 0)
416 goto error_fw_check; 428 goto error_fw_check;
@@ -432,17 +444,17 @@ retry:
432error_dev_initialize: 444error_dev_initialize:
433error_check_mac_addr: 445error_check_mac_addr:
434error_fw_check: 446error_fw_check:
435 destroy_workqueue(i2400m->work_queue);
436error_create_workqueue:
437 i2400m->bus_dev_stop(i2400m); 447 i2400m->bus_dev_stop(i2400m);
438error_bus_dev_start: 448error_bus_dev_start:
449 destroy_workqueue(i2400m->work_queue);
450error_create_workqueue:
439 i2400m_rx_release(i2400m); 451 i2400m_rx_release(i2400m);
440error_rx_setup: 452error_rx_setup:
441 i2400m_tx_release(i2400m); 453 i2400m_tx_release(i2400m);
442error_tx_setup: 454error_tx_setup:
443error_bootstrap: 455error_bootstrap:
444 if (result == -ERESTARTSYS && times-- > 0) { 456 if (result == -EL3RST && times-- > 0) {
445 flags = I2400M_BRI_SOFT; 457 flags = I2400M_BRI_SOFT|I2400M_BRI_MAC_REINIT;
446 goto retry; 458 goto retry;
447 } 459 }
448 d_fnend(3, dev, "(net_dev %p [i2400m %p]) = %d\n", 460 d_fnend(3, dev, "(net_dev %p [i2400m %p]) = %d\n",
@@ -471,7 +483,9 @@ int i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri bm_flags)
471 * 483 *
472 * Returns: 0 if ok, < 0 errno code on error. 484 * Returns: 0 if ok, < 0 errno code on error.
473 * 485 *
474 * 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.
475 */ 489 */
476static 490static
477void __i2400m_dev_stop(struct i2400m *i2400m) 491void __i2400m_dev_stop(struct i2400m *i2400m)
@@ -483,8 +497,8 @@ void __i2400m_dev_stop(struct i2400m *i2400m)
483 wimax_state_change(wimax_dev, __WIMAX_ST_QUIESCING); 497 wimax_state_change(wimax_dev, __WIMAX_ST_QUIESCING);
484 i2400m_dev_shutdown(i2400m); 498 i2400m_dev_shutdown(i2400m);
485 i2400m->ready = 0; 499 i2400m->ready = 0;
486 destroy_workqueue(i2400m->work_queue);
487 i2400m->bus_dev_stop(i2400m); 500 i2400m->bus_dev_stop(i2400m);
501 destroy_workqueue(i2400m->work_queue);
488 i2400m_rx_release(i2400m); 502 i2400m_rx_release(i2400m);
489 i2400m_tx_release(i2400m); 503 i2400m_tx_release(i2400m);
490 wimax_state_change(wimax_dev, WIMAX_ST_DOWN); 504 wimax_state_change(wimax_dev, WIMAX_ST_DOWN);
@@ -546,7 +560,7 @@ void __i2400m_dev_reset_handle(struct work_struct *ws)
546 * i2400m_dev_stop() [we are shutting down anyway, so 560 * i2400m_dev_stop() [we are shutting down anyway, so
547 * ignore it] or we are resetting somewhere else. */ 561 * ignore it] or we are resetting somewhere else. */
548 dev_err(dev, "device rebooted\n"); 562 dev_err(dev, "device rebooted\n");
549 i2400m_msg_to_dev_cancel_wait(i2400m, -ERESTARTSYS); 563 i2400m_msg_to_dev_cancel_wait(i2400m, -EL3RST);
550 complete(&i2400m->msg_completion); 564 complete(&i2400m->msg_completion);
551 goto out; 565 goto out;
552 } 566 }
@@ -596,6 +610,8 @@ out:
596 */ 610 */
597int i2400m_dev_reset_handle(struct i2400m *i2400m) 611int i2400m_dev_reset_handle(struct i2400m *i2400m)
598{ 612{
613 i2400m->boot_mode = 1;
614 wmb(); /* Make sure i2400m_msg_to_dev() sees boot_mode */
599 return i2400m_schedule_work(i2400m, __i2400m_dev_reset_handle, 615 return i2400m_schedule_work(i2400m, __i2400m_dev_reset_handle,
600 GFP_ATOMIC); 616 GFP_ATOMIC);
601} 617}
diff --git a/drivers/net/wimax/i2400m/fw.c b/drivers/net/wimax/i2400m/fw.c
index 675c6ce810c0..e81750e54452 100644
--- a/drivers/net/wimax/i2400m/fw.c
+++ b/drivers/net/wimax/i2400m/fw.c
@@ -397,7 +397,7 @@ static int i2400m_download_chunk(struct i2400m *i2400m, const void *chunk,
397 unsigned int direct, unsigned int do_csum) 397 unsigned int direct, unsigned int do_csum)
398{ 398{
399 int ret; 399 int ret;
400 size_t chunk_len = ALIGN(__chunk_len, I2400M_PL_PAD); 400 size_t chunk_len = ALIGN(__chunk_len, I2400M_PL_ALIGN);
401 struct device *dev = i2400m_dev(i2400m); 401 struct device *dev = i2400m_dev(i2400m);
402 struct { 402 struct {
403 struct i2400m_bootrom_header cmd; 403 struct i2400m_bootrom_header cmd;
@@ -532,14 +532,14 @@ int i2400m_dnload_finalize(struct i2400m *i2400m,
532 cmd = (void *) bcf + offset; 532 cmd = (void *) bcf + offset;
533 if (i2400m->sboot == 0) { 533 if (i2400m->sboot == 0) {
534 struct i2400m_bootrom_header jump_ack; 534 struct i2400m_bootrom_header jump_ack;
535 d_printf(3, dev, "unsecure boot, jumping to 0x%08x\n", 535 d_printf(1, dev, "unsecure boot, jumping to 0x%08x\n",
536 le32_to_cpu(cmd->target_addr)); 536 le32_to_cpu(cmd->target_addr));
537 i2400m_brh_set_opcode(cmd, I2400M_BRH_JUMP); 537 i2400m_brh_set_opcode(cmd, I2400M_BRH_JUMP);
538 cmd->data_size = 0; 538 cmd->data_size = 0;
539 ret = i2400m_bm_cmd(i2400m, cmd, sizeof(*cmd), 539 ret = i2400m_bm_cmd(i2400m, cmd, sizeof(*cmd),
540 &jump_ack, sizeof(jump_ack), 0); 540 &jump_ack, sizeof(jump_ack), 0);
541 } else { 541 } else {
542 d_printf(3, dev, "secure boot, jumping to 0x%08x\n", 542 d_printf(1, dev, "secure boot, jumping to 0x%08x\n",
543 le32_to_cpu(cmd->target_addr)); 543 le32_to_cpu(cmd->target_addr));
544 cmd_buf = i2400m->bm_cmd_buf; 544 cmd_buf = i2400m->bm_cmd_buf;
545 memcpy(&cmd_buf->cmd, cmd, sizeof(*cmd)); 545 memcpy(&cmd_buf->cmd, cmd, sizeof(*cmd));
@@ -696,8 +696,7 @@ error_dev_gone:
696 return result; 696 return result;
697 697
698error_timeout: 698error_timeout:
699 dev_err(dev, "Timed out waiting for reboot ack, resetting\n"); 699 dev_err(dev, "Timed out waiting for reboot ack\n");
700 i2400m->bus_reset(i2400m, I2400M_RT_BUS);
701 result = -ETIMEDOUT; 700 result = -ETIMEDOUT;
702 goto exit_timeout; 701 goto exit_timeout;
703} 702}
@@ -770,40 +769,21 @@ error_read_mac:
770static 769static
771int i2400m_dnload_init_nonsigned(struct i2400m *i2400m) 770int i2400m_dnload_init_nonsigned(struct i2400m *i2400m)
772{ 771{
773#define POKE(a, d) { \ 772 unsigned i = 0;
774 .address = cpu_to_le32(a), \ 773 int ret = 0;
775 .data = cpu_to_le32(d) \
776}
777 static const struct {
778 __le32 address;
779 __le32 data;
780 } i2400m_pokes[] = {
781 POKE(0x081A58, 0xA7810230),
782 POKE(0x080040, 0x00000000),
783 POKE(0x080048, 0x00000082),
784 POKE(0x08004C, 0x0000081F),
785 POKE(0x080054, 0x00000085),
786 POKE(0x080058, 0x00000180),
787 POKE(0x08005C, 0x00000018),
788 POKE(0x080060, 0x00000010),
789 POKE(0x080574, 0x00000001),
790 POKE(0x080550, 0x00000005),
791 POKE(0xAE0000, 0x00000000),
792 };
793#undef POKE
794 unsigned i;
795 int ret;
796 struct device *dev = i2400m_dev(i2400m); 774 struct device *dev = i2400m_dev(i2400m);
797
798 dev_warn(dev, "WARNING!!! non-signed boot UNTESTED PATH!\n");
799
800 d_fnstart(5, dev, "(i2400m %p)\n", i2400m); 775 d_fnstart(5, dev, "(i2400m %p)\n", i2400m);
801 for (i = 0; i < ARRAY_SIZE(i2400m_pokes); i++) { 776 if (i2400m->bus_bm_pokes_table) {
802 ret = i2400m_download_chunk(i2400m, &i2400m_pokes[i].data, 777 while (i2400m->bus_bm_pokes_table[i].address) {
803 sizeof(i2400m_pokes[i].data), 778 ret = i2400m_download_chunk(
804 i2400m_pokes[i].address, 1, 1); 779 i2400m,
805 if (ret < 0) 780 &i2400m->bus_bm_pokes_table[i].data,
806 break; 781 sizeof(i2400m->bus_bm_pokes_table[i].data),
782 i2400m->bus_bm_pokes_table[i].address, 1, 1);
783 if (ret < 0)
784 break;
785 i++;
786 }
807 } 787 }
808 d_fnend(5, dev, "(i2400m %p) = %d\n", i2400m, ret); 788 d_fnend(5, dev, "(i2400m %p) = %d\n", i2400m, ret);
809 return ret; 789 return ret;
@@ -980,11 +960,12 @@ int i2400m_fw_dnload(struct i2400m *i2400m, const struct i2400m_bcf_hdr *bcf,
980{ 960{
981 int ret = 0; 961 int ret = 0;
982 struct device *dev = i2400m_dev(i2400m); 962 struct device *dev = i2400m_dev(i2400m);
983 int count = I2400M_BOOT_RETRIES; 963 int count = i2400m->bus_bm_retries;
984 964
985 d_fnstart(5, dev, "(i2400m %p bcf %p size %zu)\n", 965 d_fnstart(5, dev, "(i2400m %p bcf %p size %zu)\n",
986 i2400m, bcf, bcf_size); 966 i2400m, bcf, bcf_size);
987 i2400m->boot_mode = 1; 967 i2400m->boot_mode = 1;
968 wmb(); /* Make sure other readers see it */
988hw_reboot: 969hw_reboot:
989 if (count-- == 0) { 970 if (count-- == 0) {
990 ret = -ERESTARTSYS; 971 ret = -ERESTARTSYS;
@@ -1033,6 +1014,7 @@ hw_reboot:
1033 d_printf(2, dev, "fw %s successfully uploaded\n", 1014 d_printf(2, dev, "fw %s successfully uploaded\n",
1034 i2400m->fw_name); 1015 i2400m->fw_name);
1035 i2400m->boot_mode = 0; 1016 i2400m->boot_mode = 0;
1017 wmb(); /* Make sure i2400m_msg_to_dev() sees boot_mode */
1036error_dnload_finalize: 1018error_dnload_finalize:
1037error_dnload_bcf: 1019error_dnload_bcf:
1038error_dnload_init: 1020error_dnload_init:
diff --git a/drivers/net/wimax/i2400m/i2400m-sdio.h b/drivers/net/wimax/i2400m/i2400m-sdio.h
index 08c2fb739234..9c4e3189f7b5 100644
--- a/drivers/net/wimax/i2400m/i2400m-sdio.h
+++ b/drivers/net/wimax/i2400m/i2400m-sdio.h
@@ -78,6 +78,8 @@ enum {
78 /* The number of ticks to wait for the device to signal that 78 /* The number of ticks to wait for the device to signal that
79 * it is ready */ 79 * it is ready */
80 I2400MS_INIT_SLEEP_INTERVAL = 10, 80 I2400MS_INIT_SLEEP_INTERVAL = 10,
81 /* How long to wait for the device to settle after reset */
82 I2400MS_SETTLE_TIME = 40,
81}; 83};
82 84
83 85
@@ -105,6 +107,10 @@ struct i2400ms {
105 char tx_wq_name[32]; 107 char tx_wq_name[32];
106 108
107 struct dentry *debugfs_dentry; 109 struct dentry *debugfs_dentry;
110
111 wait_queue_head_t bm_wfa_wq;
112 int bm_wait_result;
113 size_t bm_ack_size;
108}; 114};
109 115
110 116
@@ -129,4 +135,7 @@ extern ssize_t i2400ms_bus_bm_cmd_send(struct i2400m *,
129extern ssize_t i2400ms_bus_bm_wait_for_ack(struct i2400m *, 135extern ssize_t i2400ms_bus_bm_wait_for_ack(struct i2400m *,
130 struct i2400m_bootrom_header *, 136 struct i2400m_bootrom_header *,
131 size_t); 137 size_t);
138extern void i2400ms_bus_bm_release(struct i2400m *);
139extern int i2400ms_bus_bm_setup(struct i2400m *);
140
132#endif /* #ifndef __I2400M_SDIO_H__ */ 141#endif /* #ifndef __I2400M_SDIO_H__ */
diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h
index 434ba310c2fe..1fe5da4cf0a0 100644
--- a/drivers/net/wimax/i2400m/i2400m.h
+++ b/drivers/net/wimax/i2400m/i2400m.h
@@ -150,11 +150,33 @@
150enum { 150enum {
151 /* Firmware uploading */ 151 /* Firmware uploading */
152 I2400M_BOOT_RETRIES = 3, 152 I2400M_BOOT_RETRIES = 3,
153 I3200_BOOT_RETRIES = 3,
153 /* Size of the Boot Mode Command buffer */ 154 /* Size of the Boot Mode Command buffer */
154 I2400M_BM_CMD_BUF_SIZE = 16 * 1024, 155 I2400M_BM_CMD_BUF_SIZE = 16 * 1024,
155 I2400M_BM_ACK_BUF_SIZE = 256, 156 I2400M_BM_ACK_BUF_SIZE = 256,
156}; 157};
157 158
159/**
160 * struct i2400m_poke_table - Hardware poke table for the Intel 2400m
161 *
162 * This structure will be used to create a device specific poke table
163 * to put the device in a consistant state at boot time.
164 *
165 * @address: The device address to poke
166 *
167 * @data: The data value to poke to the device address
168 *
169 */
170struct i2400m_poke_table{
171 __le32 address;
172 __le32 data;
173};
174
175#define I2400M_FW_POKE(a, d) { \
176 .address = cpu_to_le32(a), \
177 .data = cpu_to_le32(d) \
178}
179
158 180
159/** 181/**
160 * i2400m_reset_type - methods to reset a device 182 * i2400m_reset_type - methods to reset a device
@@ -224,6 +246,17 @@ struct i2400m_roq;
224 * process, so it cannot rely on common infrastructure being laid 246 * process, so it cannot rely on common infrastructure being laid
225 * out. 247 * out.
226 * 248 *
249 * @bus_bm_retries: [fill] How many times shall a firmware upload /
250 * device initialization be retried? Different models of the same
251 * device might need different values, hence it is set by the
252 * bus-specific driver. Note this value is used in two places,
253 * i2400m_fw_dnload() and __i2400m_dev_start(); they won't become
254 * multiplicative (__i2400m_dev_start() calling N times
255 * i2400m_fw_dnload() and this trying N times to download the
256 * firmware), as if __i2400m_dev_start() only retries if the
257 * firmware crashed while initializing the device (not in a
258 * general case).
259 *
227 * @bus_bm_cmd_send: [fill] Function called to send a boot-mode 260 * @bus_bm_cmd_send: [fill] Function called to send a boot-mode
228 * command. Flags are defined in 'enum i2400m_bm_cmd_flags'. This 261 * command. Flags are defined in 'enum i2400m_bm_cmd_flags'. This
229 * is synchronous and has to return 0 if ok or < 0 errno code in 262 * is synchronous and has to return 0 if ok or < 0 errno code in
@@ -252,6 +285,12 @@ struct i2400m_roq;
252 * address provided in boot mode is kind of broken and needs to 285 * address provided in boot mode is kind of broken and needs to
253 * be re-read later on. 286 * be re-read later on.
254 * 287 *
288 * @bus_bm_pokes_table: [fill/optional] A table of device addresses
289 * and values that will be poked at device init time to move the
290 * device to the correct state for the type of boot/firmware being
291 * used. This table MUST be terminated with (0x000000,
292 * 0x00000000) or bad things will happen.
293 *
255 * 294 *
256 * @wimax_dev: WiMAX generic device for linkage into the kernel WiMAX 295 * @wimax_dev: WiMAX generic device for linkage into the kernel WiMAX
257 * stack. Due to the way a net_device is allocated, we need to 296 * stack. Due to the way a net_device is allocated, we need to
@@ -399,6 +438,8 @@ struct i2400m {
399 438
400 size_t bus_tx_block_size; 439 size_t bus_tx_block_size;
401 size_t bus_pl_size_max; 440 size_t bus_pl_size_max;
441 unsigned bus_bm_retries;
442
402 int (*bus_dev_start)(struct i2400m *); 443 int (*bus_dev_start)(struct i2400m *);
403 void (*bus_dev_stop)(struct i2400m *); 444 void (*bus_dev_stop)(struct i2400m *);
404 void (*bus_tx_kick)(struct i2400m *); 445 void (*bus_tx_kick)(struct i2400m *);
@@ -410,6 +451,7 @@ struct i2400m {
410 struct i2400m_bootrom_header *, size_t); 451 struct i2400m_bootrom_header *, size_t);
411 const char **bus_fw_names; 452 const char **bus_fw_names;
412 unsigned bus_bm_mac_addr_impaired:1; 453 unsigned bus_bm_mac_addr_impaired:1;
454 const struct i2400m_poke_table *bus_bm_pokes_table;
413 455
414 spinlock_t tx_lock; /* protect TX state */ 456 spinlock_t tx_lock; /* protect TX state */
415 void *tx_buf; 457 void *tx_buf;
@@ -709,6 +751,7 @@ static const __le32 i2400m_SBOOT_BARKER[4] = {
709 cpu_to_le32(I2400M_SBOOT_BARKER) 751 cpu_to_le32(I2400M_SBOOT_BARKER)
710}; 752};
711 753
754extern int i2400m_power_save_disabled;
712 755
713/* 756/*
714 * Utility functions 757 * Utility functions
diff --git a/drivers/net/wimax/i2400m/op-rfkill.c b/drivers/net/wimax/i2400m/op-rfkill.c
index 487ec58cea46..43927b5d7ad6 100644
--- a/drivers/net/wimax/i2400m/op-rfkill.c
+++ b/drivers/net/wimax/i2400m/op-rfkill.c
@@ -54,8 +54,10 @@ int i2400m_radio_is(struct i2400m *i2400m, enum wimax_rf_state state)
54 /* state == WIMAX_RF_ON */ 54 /* state == WIMAX_RF_ON */
55 return i2400m->state != I2400M_SS_RF_OFF 55 return i2400m->state != I2400M_SS_RF_OFF
56 && i2400m->state != I2400M_SS_RF_SHUTDOWN; 56 && i2400m->state != I2400M_SS_RF_SHUTDOWN;
57 else 57 else {
58 BUG(); 58 BUG();
59 return -EINVAL; /* shut gcc warnings on certain arches */
60 }
59} 61}
60 62
61 63
diff --git a/drivers/net/wimax/i2400m/rx.c b/drivers/net/wimax/i2400m/rx.c
index 7643850a6fb8..07c32e68909f 100644
--- a/drivers/net/wimax/i2400m/rx.c
+++ b/drivers/net/wimax/i2400m/rx.c
@@ -1148,7 +1148,7 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb)
1148 num_pls = le16_to_cpu(msg_hdr->num_pls); 1148 num_pls = le16_to_cpu(msg_hdr->num_pls);
1149 pl_itr = sizeof(*msg_hdr) + /* Check payload descriptor(s) */ 1149 pl_itr = sizeof(*msg_hdr) + /* Check payload descriptor(s) */
1150 num_pls * sizeof(msg_hdr->pld[0]); 1150 num_pls * sizeof(msg_hdr->pld[0]);
1151 pl_itr = ALIGN(pl_itr, I2400M_PL_PAD); 1151 pl_itr = ALIGN(pl_itr, I2400M_PL_ALIGN);
1152 if (pl_itr > skb->len) { /* got all the payload descriptors? */ 1152 if (pl_itr > skb->len) { /* got all the payload descriptors? */
1153 dev_err(dev, "RX: HW BUG? message too short (%u bytes) for " 1153 dev_err(dev, "RX: HW BUG? message too short (%u bytes) for "
1154 "%u payload descriptors (%zu each, total %zu)\n", 1154 "%u payload descriptors (%zu each, total %zu)\n",
@@ -1166,7 +1166,7 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb)
1166 single_last = num_pls == 1 || i == num_pls - 1; 1166 single_last = num_pls == 1 || i == num_pls - 1;
1167 i2400m_rx_payload(i2400m, skb, single_last, &msg_hdr->pld[i], 1167 i2400m_rx_payload(i2400m, skb, single_last, &msg_hdr->pld[i],
1168 skb->data + pl_itr); 1168 skb->data + pl_itr);
1169 pl_itr += ALIGN(pl_size, I2400M_PL_PAD); 1169 pl_itr += ALIGN(pl_size, I2400M_PL_ALIGN);
1170 cond_resched(); /* Don't monopolize */ 1170 cond_resched(); /* Don't monopolize */
1171 } 1171 }
1172 kfree_skb(skb); 1172 kfree_skb(skb);
diff --git a/drivers/net/wimax/i2400m/sdio-fw.c b/drivers/net/wimax/i2400m/sdio-fw.c
index 3487205d8f50..7d6ec0f475f8 100644
--- a/drivers/net/wimax/i2400m/sdio-fw.c
+++ b/drivers/net/wimax/i2400m/sdio-fw.c
@@ -46,17 +46,24 @@
46 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> 46 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
47 * - SDIO rehash for changes in the bus-driver model 47 * - SDIO rehash for changes in the bus-driver model
48 * 48 *
49 * Dirk Brandewie <dirk.j.brandewie@intel.com>
50 * - Make it IRQ based, not polling
51 *
49 * THE PROCEDURE 52 * THE PROCEDURE
50 * 53 *
51 * See fw.c for the generic description of this procedure. 54 * See fw.c for the generic description of this procedure.
52 * 55 *
53 * This file implements only the SDIO specifics. It boils down to how 56 * This file implements only the SDIO specifics. It boils down to how
54 * to send a command and waiting for an acknowledgement from the 57 * to send a command and waiting for an acknowledgement from the
55 * device. We do polled reads. 58 * device.
59 *
60 * All this code is sequential -- all i2400ms_bus_bm_*() functions are
61 * executed in the same thread, except i2400ms_bm_irq() [on its own by
62 * the SDIO driver]. This makes it possible to avoid locking.
56 * 63 *
57 * COMMAND EXECUTION 64 * COMMAND EXECUTION
58 * 65 *
59 * THe generic firmware upload code will call i2400m_bus_bm_cmd_send() 66 * The generic firmware upload code will call i2400m_bus_bm_cmd_send()
60 * to send commands. 67 * to send commands.
61 * 68 *
62 * The SDIO devices expects things in 256 byte blocks, so it will pad 69 * The SDIO devices expects things in 256 byte blocks, so it will pad
@@ -64,12 +71,15 @@
64 * 71 *
65 * ACK RECEPTION 72 * ACK RECEPTION
66 * 73 *
67 * This works in polling mode -- the fw loader says when to wait for 74 * This works in IRQ mode -- the fw loader says when to wait for data
68 * data and for that it calls i2400ms_bus_bm_wait_for_ack(). 75 * and for that it calls i2400ms_bus_bm_wait_for_ack().
69 * 76 *
70 * This will poll the device for data until it is received. We need to 77 * This checks if there is any data available (RX size > 0); if not,
71 * receive at least as much bytes as where asked for (although it'll 78 * waits for the IRQ handler to notify about it. Once there is data,
72 * always be a multiple of 256 bytes). 79 * it is read and passed to the caller. Doing it this way we don't
80 * need much coordination/locking, and it makes it much more difficult
81 * for an interrupt to be lost and the wait_for_ack() function getting
82 * stuck even when data is pending.
73 */ 83 */
74#include <linux/mmc/sdio_func.h> 84#include <linux/mmc/sdio_func.h>
75#include "i2400m-sdio.h" 85#include "i2400m-sdio.h"
@@ -78,6 +88,7 @@
78#define D_SUBMODULE fw 88#define D_SUBMODULE fw
79#include "sdio-debug-levels.h" 89#include "sdio-debug-levels.h"
80 90
91
81/* 92/*
82 * Send a boot-mode command to the SDIO function 93 * Send a boot-mode command to the SDIO function
83 * 94 *
@@ -139,7 +150,7 @@ error_too_big:
139 150
140 151
141/* 152/*
142 * Read an ack from the device's boot-mode (polling) 153 * Read an ack from the device's boot-mode
143 * 154 *
144 * @i2400m: 155 * @i2400m:
145 * @_ack: pointer to where to store the read data 156 * @_ack: pointer to where to store the read data
@@ -150,75 +161,49 @@ error_too_big:
150 * The ACK for a BM command is always at least sizeof(*ack) bytes, so 161 * The ACK for a BM command is always at least sizeof(*ack) bytes, so
151 * check for that. We don't need to check for device reboots 162 * check for that. We don't need to check for device reboots
152 * 163 *
153 * NOTE: We do an artificial timeout of 1 sec over the SDIO timeout;
154 * this way we have control over it...there is no way that I know
155 * of setting an SDIO transaction timeout.
156 */ 164 */
157ssize_t i2400ms_bus_bm_wait_for_ack(struct i2400m *i2400m, 165ssize_t i2400ms_bus_bm_wait_for_ack(struct i2400m *i2400m,
158 struct i2400m_bootrom_header *ack, 166 struct i2400m_bootrom_header *ack,
159 size_t ack_size) 167 size_t ack_size)
160{ 168{
161 int result; 169 ssize_t result;
162 ssize_t rx_size;
163 u64 timeout;
164 struct i2400ms *i2400ms = container_of(i2400m, struct i2400ms, i2400m); 170 struct i2400ms *i2400ms = container_of(i2400m, struct i2400ms, i2400m);
165 struct sdio_func *func = i2400ms->func; 171 struct sdio_func *func = i2400ms->func;
166 struct device *dev = &func->dev; 172 struct device *dev = &func->dev;
173 int size;
167 174
168 BUG_ON(sizeof(*ack) > ack_size); 175 BUG_ON(sizeof(*ack) > ack_size);
169 176
170 d_fnstart(5, dev, "(i2400m %p ack %p size %zu)\n", 177 d_fnstart(5, dev, "(i2400m %p ack %p size %zu)\n",
171 i2400m, ack, ack_size); 178 i2400m, ack, ack_size);
172 179
173 timeout = get_jiffies_64() + 2 * HZ; 180 spin_lock(&i2400m->rx_lock);
174 sdio_claim_host(func); 181 i2400ms->bm_ack_size = -EINPROGRESS;
175 while (1) { 182 spin_unlock(&i2400m->rx_lock);
176 if (time_after64(get_jiffies_64(), timeout)) {
177 rx_size = -ETIMEDOUT;
178 dev_err(dev, "timeout waiting for ack data\n");
179 goto error_timedout;
180 }
181 183
182 /* Find the RX size, check if it fits or not -- it if 184 result = wait_event_timeout(i2400ms->bm_wfa_wq,
183 * doesn't fit, fail, as we have no way to dispose of 185 i2400ms->bm_ack_size != -EINPROGRESS,
184 * the extra data. */ 186 2 * HZ);
185 rx_size = __i2400ms_rx_get_size(i2400ms); 187 if (result == 0) {
186 if (rx_size < 0) 188 result = -ETIMEDOUT;
187 goto error_rx_get_size; 189 dev_err(dev, "BM: error waiting for an ack\n");
188 result = -ENOSPC; /* Check it fits */ 190 goto error_timeout;
189 if (rx_size < sizeof(*ack)) { 191 }
190 rx_size = -EIO;
191 dev_err(dev, "HW BUG? received is too small (%zu vs "
192 "%zu needed)\n", sizeof(*ack), rx_size);
193 goto error_too_small;
194 }
195 if (rx_size > I2400M_BM_ACK_BUF_SIZE) {
196 dev_err(dev, "SW BUG? BM_ACK_BUF is too small (%u vs "
197 "%zu needed)\n", I2400M_BM_ACK_BUF_SIZE,
198 rx_size);
199 goto error_too_small;
200 }
201 192
202 /* Read it */ 193 spin_lock(&i2400m->rx_lock);
203 result = sdio_memcpy_fromio(func, i2400m->bm_ack_buf, 194 result = i2400ms->bm_ack_size;
204 I2400MS_DATA_ADDR, rx_size); 195 BUG_ON(result == -EINPROGRESS);
205 if (result == -ETIMEDOUT || result == -ETIME) 196 if (result < 0) /* so we exit when rx_release() is called */
206 continue; 197 dev_err(dev, "BM: %s failed: %zd\n", __func__, result);
207 if (result < 0) { 198 else {
208 dev_err(dev, "BM SDIO receive (%zu B) failed: %d\n", 199 size = min(ack_size, i2400ms->bm_ack_size);
209 rx_size, result); 200 memcpy(ack, i2400m->bm_ack_buf, size);
210 goto error_read;
211 } else
212 break;
213 } 201 }
214 rx_size = min((ssize_t)ack_size, rx_size); 202 i2400ms->bm_ack_size = -EINPROGRESS;
215 memcpy(ack, i2400m->bm_ack_buf, rx_size); 203 spin_unlock(&i2400m->rx_lock);
216error_read: 204
217error_too_small: 205error_timeout:
218error_rx_get_size: 206 d_fnend(5, dev, "(i2400m %p ack %p size %zu) = %zd\n",
219error_timedout: 207 i2400m, ack, ack_size, result);
220 sdio_release_host(func); 208 return result;
221 d_fnend(5, dev, "(i2400m %p ack %p size %zu) = %ld\n",
222 i2400m, ack, ack_size, (long) rx_size);
223 return rx_size;
224} 209}
diff --git a/drivers/net/wimax/i2400m/sdio-rx.c b/drivers/net/wimax/i2400m/sdio-rx.c
index a3008b904f7d..321beadf6e47 100644
--- a/drivers/net/wimax/i2400m/sdio-rx.c
+++ b/drivers/net/wimax/i2400m/sdio-rx.c
@@ -69,6 +69,13 @@
69#define D_SUBMODULE rx 69#define D_SUBMODULE rx
70#include "sdio-debug-levels.h" 70#include "sdio-debug-levels.h"
71 71
72static const __le32 i2400m_ACK_BARKER[4] = {
73 __constant_cpu_to_le32(I2400M_ACK_BARKER),
74 __constant_cpu_to_le32(I2400M_ACK_BARKER),
75 __constant_cpu_to_le32(I2400M_ACK_BARKER),
76 __constant_cpu_to_le32(I2400M_ACK_BARKER)
77};
78
72 79
73/* 80/*
74 * Read and return the amount of bytes available for RX 81 * Read and return the amount of bytes available for RX
@@ -131,25 +138,35 @@ void i2400ms_rx(struct i2400ms *i2400ms)
131 ret = rx_size; 138 ret = rx_size;
132 goto error_get_size; 139 goto error_get_size;
133 } 140 }
141
134 ret = -ENOMEM; 142 ret = -ENOMEM;
135 skb = alloc_skb(rx_size, GFP_ATOMIC); 143 skb = alloc_skb(rx_size, GFP_ATOMIC);
136 if (NULL == skb) { 144 if (NULL == skb) {
137 dev_err(dev, "RX: unable to alloc skb\n"); 145 dev_err(dev, "RX: unable to alloc skb\n");
138 goto error_alloc_skb; 146 goto error_alloc_skb;
139 } 147 }
140
141 ret = sdio_memcpy_fromio(func, skb->data, 148 ret = sdio_memcpy_fromio(func, skb->data,
142 I2400MS_DATA_ADDR, rx_size); 149 I2400MS_DATA_ADDR, rx_size);
143 if (ret < 0) { 150 if (ret < 0) {
144 dev_err(dev, "RX: SDIO data read failed: %d\n", ret); 151 dev_err(dev, "RX: SDIO data read failed: %d\n", ret);
145 goto error_memcpy_fromio; 152 goto error_memcpy_fromio;
146 } 153 }
147 /* Check if device has reset */ 154
148 if (!memcmp(skb->data, i2400m_NBOOT_BARKER, 155 rmb(); /* make sure we get boot_mode from dev_reset_handle */
149 sizeof(i2400m_NBOOT_BARKER)) 156 if (i2400m->boot_mode == 1) {
150 || !memcmp(skb->data, i2400m_SBOOT_BARKER, 157 spin_lock(&i2400m->rx_lock);
151 sizeof(i2400m_SBOOT_BARKER))) { 158 i2400ms->bm_ack_size = rx_size;
159 spin_unlock(&i2400m->rx_lock);
160 memcpy(i2400m->bm_ack_buf, skb->data, rx_size);
161 wake_up(&i2400ms->bm_wfa_wq);
162 dev_err(dev, "RX: SDIO boot mode message\n");
163 kfree_skb(skb);
164 } else if (unlikely(!memcmp(skb->data, i2400m_NBOOT_BARKER,
165 sizeof(i2400m_NBOOT_BARKER))
166 || !memcmp(skb->data, i2400m_SBOOT_BARKER,
167 sizeof(i2400m_SBOOT_BARKER)))) {
152 ret = i2400m_dev_reset_handle(i2400m); 168 ret = i2400m_dev_reset_handle(i2400m);
169 dev_err(dev, "RX: SDIO reboot barker\n");
153 kfree_skb(skb); 170 kfree_skb(skb);
154 } else { 171 } else {
155 skb_put(skb, rx_size); 172 skb_put(skb, rx_size);
@@ -179,7 +196,6 @@ void i2400ms_irq(struct sdio_func *func)
179{ 196{
180 int ret; 197 int ret;
181 struct i2400ms *i2400ms = sdio_get_drvdata(func); 198 struct i2400ms *i2400ms = sdio_get_drvdata(func);
182 struct i2400m *i2400m = &i2400ms->i2400m;
183 struct device *dev = &func->dev; 199 struct device *dev = &func->dev;
184 int val; 200 int val;
185 201
@@ -194,10 +210,7 @@ void i2400ms_irq(struct sdio_func *func)
194 goto error_no_irq; 210 goto error_no_irq;
195 } 211 }
196 sdio_writeb(func, 1, I2400MS_INTR_CLEAR_ADDR, &ret); 212 sdio_writeb(func, 1, I2400MS_INTR_CLEAR_ADDR, &ret);
197 if (WARN_ON(i2400m->boot_mode != 0)) 213 i2400ms_rx(i2400ms);
198 dev_err(dev, "RX: SW BUG? boot mode and IRQ is up?\n");
199 else
200 i2400ms_rx(i2400ms);
201error_no_irq: 214error_no_irq:
202 d_fnend(6, dev, "(i2400ms %p) = void\n", i2400ms); 215 d_fnend(6, dev, "(i2400ms %p) = void\n", i2400ms);
203 return; 216 return;
@@ -214,8 +227,15 @@ int i2400ms_rx_setup(struct i2400ms *i2400ms)
214 int result; 227 int result;
215 struct sdio_func *func = i2400ms->func; 228 struct sdio_func *func = i2400ms->func;
216 struct device *dev = &func->dev; 229 struct device *dev = &func->dev;
230 struct i2400m *i2400m = &i2400ms->i2400m;
217 231
218 d_fnstart(5, dev, "(i2400ms %p)\n", i2400ms); 232 d_fnstart(5, dev, "(i2400ms %p)\n", i2400ms);
233
234 init_waitqueue_head(&i2400ms->bm_wfa_wq);
235 spin_lock(&i2400m->rx_lock);
236 i2400ms->bm_wait_result = -EINPROGRESS;
237 spin_unlock(&i2400m->rx_lock);
238
219 sdio_claim_host(func); 239 sdio_claim_host(func);
220 result = sdio_claim_irq(func, i2400ms_irq); 240 result = sdio_claim_irq(func, i2400ms_irq);
221 if (result < 0) { 241 if (result < 0) {
@@ -245,8 +265,13 @@ void i2400ms_rx_release(struct i2400ms *i2400ms)
245 int result; 265 int result;
246 struct sdio_func *func = i2400ms->func; 266 struct sdio_func *func = i2400ms->func;
247 struct device *dev = &func->dev; 267 struct device *dev = &func->dev;
268 struct i2400m *i2400m = &i2400ms->i2400m;
248 269
249 d_fnstart(5, dev, "(i2400ms %p)\n", i2400ms); 270 d_fnstart(5, dev, "(i2400ms %p)\n", i2400ms);
271 spin_lock(&i2400m->rx_lock);
272 i2400ms->bm_ack_size = -EINTR;
273 spin_unlock(&i2400m->rx_lock);
274 wake_up_all(&i2400ms->bm_wfa_wq);
250 sdio_claim_host(func); 275 sdio_claim_host(func);
251 sdio_writeb(func, 0, I2400MS_INTR_ENABLE_ADDR, &result); 276 sdio_writeb(func, 0, I2400MS_INTR_ENABLE_ADDR, &result);
252 sdio_release_irq(func); 277 sdio_release_irq(func);
diff --git a/drivers/net/wimax/i2400m/sdio.c b/drivers/net/wimax/i2400m/sdio.c
index 777c981676fc..2538825d1c66 100644
--- a/drivers/net/wimax/i2400m/sdio.c
+++ b/drivers/net/wimax/i2400m/sdio.c
@@ -78,6 +78,14 @@ static const char *i2400ms_bus_fw_names[] = {
78}; 78};
79 79
80 80
81static const struct i2400m_poke_table i2400ms_pokes[] = {
82 I2400M_FW_POKE(0x6BE260, 0x00000088),
83 I2400M_FW_POKE(0x080550, 0x00000005),
84 I2400M_FW_POKE(0xAE0000, 0x00000000),
85 I2400M_FW_POKE(0x000000, 0x00000000), /* MUST be 0 terminated or bad
86 * things will happen */
87};
88
81/* 89/*
82 * Enable the SDIO function 90 * Enable the SDIO function
83 * 91 *
@@ -148,19 +156,14 @@ int i2400ms_bus_dev_start(struct i2400m *i2400m)
148 156
149 d_fnstart(3, dev, "(i2400m %p)\n", i2400m); 157 d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
150 msleep(200); 158 msleep(200);
151 result = i2400ms_rx_setup(i2400ms);
152 if (result < 0)
153 goto error_rx_setup;
154 result = i2400ms_tx_setup(i2400ms); 159 result = i2400ms_tx_setup(i2400ms);
155 if (result < 0) 160 if (result < 0)
156 goto error_tx_setup; 161 goto error_tx_setup;
157 d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result); 162 d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result);
158 return result; 163 return result;
159 164
160 i2400ms_tx_release(i2400ms);
161error_tx_setup: 165error_tx_setup:
162 i2400ms_rx_release(i2400ms); 166 i2400ms_tx_release(i2400ms);
163error_rx_setup:
164 d_fnend(3, dev, "(i2400m %p) = void\n", i2400m); 167 d_fnend(3, dev, "(i2400m %p) = void\n", i2400m);
165 return result; 168 return result;
166} 169}
@@ -174,7 +177,6 @@ void i2400ms_bus_dev_stop(struct i2400m *i2400m)
174 struct device *dev = &func->dev; 177 struct device *dev = &func->dev;
175 178
176 d_fnstart(3, dev, "(i2400m %p)\n", i2400m); 179 d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
177 i2400ms_rx_release(i2400ms);
178 i2400ms_tx_release(i2400ms); 180 i2400ms_tx_release(i2400ms);
179 d_fnend(3, dev, "(i2400m %p) = void\n", i2400m); 181 d_fnend(3, dev, "(i2400m %p) = void\n", i2400m);
180} 182}
@@ -255,7 +257,7 @@ error_kzalloc:
255static 257static
256int i2400ms_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt) 258int i2400ms_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt)
257{ 259{
258 int result; 260 int result = 0;
259 struct i2400ms *i2400ms = 261 struct i2400ms *i2400ms =
260 container_of(i2400m, struct i2400ms, i2400m); 262 container_of(i2400m, struct i2400ms, i2400m);
261 struct device *dev = i2400m_dev(i2400m); 263 struct device *dev = i2400m_dev(i2400m);
@@ -280,8 +282,25 @@ int i2400ms_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt)
280 sizeof(i2400m_COLD_BOOT_BARKER)); 282 sizeof(i2400m_COLD_BOOT_BARKER));
281 else if (rt == I2400M_RT_BUS) { 283 else if (rt == I2400M_RT_BUS) {
282do_bus_reset: 284do_bus_reset:
283 dev_err(dev, "FIXME: SDIO bus reset not implemented\n"); 285 /* call netif_tx_disable() before sending IOE disable,
284 result = rt == I2400M_RT_WARM ? -ENODEV : -ENOSYS; 286 * so that all the tx from network layer are stopped
287 * while IOE is being reset. Make sure it is called
288 * only after register_netdev() was issued.
289 */
290 if (i2400m->wimax_dev.net_dev->reg_state == NETREG_REGISTERED)
291 netif_tx_disable(i2400m->wimax_dev.net_dev);
292
293 i2400ms_rx_release(i2400ms);
294 sdio_claim_host(i2400ms->func);
295 sdio_disable_func(i2400ms->func);
296 sdio_release_host(i2400ms->func);
297
298 /* Wait for the device to settle */
299 msleep(40);
300
301 result = i2400ms_enable_function(i2400ms->func);
302 if (result >= 0)
303 i2400ms_rx_setup(i2400ms);
285 } else 304 } else
286 BUG(); 305 BUG();
287 if (result < 0 && rt != I2400M_RT_BUS) { 306 if (result < 0 && rt != I2400M_RT_BUS) {
@@ -404,10 +423,14 @@ int i2400ms_probe(struct sdio_func *func,
404 i2400m->bus_dev_stop = i2400ms_bus_dev_stop; 423 i2400m->bus_dev_stop = i2400ms_bus_dev_stop;
405 i2400m->bus_tx_kick = i2400ms_bus_tx_kick; 424 i2400m->bus_tx_kick = i2400ms_bus_tx_kick;
406 i2400m->bus_reset = i2400ms_bus_reset; 425 i2400m->bus_reset = i2400ms_bus_reset;
426 /* The iwmc3200-wimax sometimes requires the driver to try
427 * hard when we paint it into a corner. */
428 i2400m->bus_bm_retries = I3200_BOOT_RETRIES;
407 i2400m->bus_bm_cmd_send = i2400ms_bus_bm_cmd_send; 429 i2400m->bus_bm_cmd_send = i2400ms_bus_bm_cmd_send;
408 i2400m->bus_bm_wait_for_ack = i2400ms_bus_bm_wait_for_ack; 430 i2400m->bus_bm_wait_for_ack = i2400ms_bus_bm_wait_for_ack;
409 i2400m->bus_fw_names = i2400ms_bus_fw_names; 431 i2400m->bus_fw_names = i2400ms_bus_fw_names;
410 i2400m->bus_bm_mac_addr_impaired = 1; 432 i2400m->bus_bm_mac_addr_impaired = 1;
433 i2400m->bus_bm_pokes_table = &i2400ms_pokes[0];
411 434
412 sdio_claim_host(func); 435 sdio_claim_host(func);
413 result = sdio_set_block_size(func, I2400MS_BLK_SIZE); 436 result = sdio_set_block_size(func, I2400MS_BLK_SIZE);
@@ -423,6 +446,10 @@ int i2400ms_probe(struct sdio_func *func,
423 goto error_func_enable; 446 goto error_func_enable;
424 } 447 }
425 448
449 result = i2400ms_rx_setup(i2400ms);
450 if (result < 0)
451 goto error_rx_setup;
452
426 result = i2400m_setup(i2400m, I2400M_BRI_NO_REBOOT); 453 result = i2400m_setup(i2400m, I2400M_BRI_NO_REBOOT);
427 if (result < 0) { 454 if (result < 0) {
428 dev_err(dev, "cannot setup device: %d\n", result); 455 dev_err(dev, "cannot setup device: %d\n", result);
@@ -440,6 +467,8 @@ int i2400ms_probe(struct sdio_func *func,
440error_debugfs_add: 467error_debugfs_add:
441 i2400m_release(i2400m); 468 i2400m_release(i2400m);
442error_setup: 469error_setup:
470 i2400ms_rx_release(i2400ms);
471error_rx_setup:
443 sdio_claim_host(func); 472 sdio_claim_host(func);
444 sdio_disable_func(func); 473 sdio_disable_func(func);
445 sdio_release_host(func); 474 sdio_release_host(func);
@@ -462,6 +491,7 @@ void i2400ms_remove(struct sdio_func *func)
462 491
463 d_fnstart(3, dev, "SDIO func %p\n", func); 492 d_fnstart(3, dev, "SDIO func %p\n", func);
464 debugfs_remove_recursive(i2400ms->debugfs_dentry); 493 debugfs_remove_recursive(i2400ms->debugfs_dentry);
494 i2400ms_rx_release(i2400ms);
465 i2400m_release(i2400m); 495 i2400m_release(i2400m);
466 sdio_set_drvdata(func, NULL); 496 sdio_set_drvdata(func, NULL);
467 sdio_claim_host(func); 497 sdio_claim_host(func);
diff --git a/drivers/net/wimax/i2400m/tx.c b/drivers/net/wimax/i2400m/tx.c
index 613a88ffd651..fa16ccf8e26a 100644
--- a/drivers/net/wimax/i2400m/tx.c
+++ b/drivers/net/wimax/i2400m/tx.c
@@ -278,6 +278,48 @@ enum {
278#define TAIL_FULL ((void *)~(unsigned long)NULL) 278#define TAIL_FULL ((void *)~(unsigned long)NULL)
279 279
280/* 280/*
281 * Calculate how much tail room is available
282 *
283 * Note the trick here. This path is ONLY caleed for Case A (see
284 * i2400m_tx_fifo_push() below), where we have:
285 *
286 * Case A
287 * N ___________
288 * | tail room |
289 * | |
290 * |<- IN ->|
291 * | |
292 * | data |
293 * | |
294 * |<- OUT ->|
295 * | |
296 * | head room |
297 * 0 -----------
298 *
299 * When calculating the tail_room, tx_in might get to be zero if
300 * i2400m->tx_in is right at the end of the buffer (really full
301 * buffer) if there is no head room. In this case, tail_room would be
302 * I2400M_TX_BUF_SIZE, although it is actually zero. Hence the final
303 * mod (%) operation. However, when doing this kind of optimization,
304 * i2400m->tx_in being zero would fail, so we treat is an a special
305 * case.
306 */
307static inline
308size_t __i2400m_tx_tail_room(struct i2400m *i2400m)
309{
310 size_t tail_room;
311 size_t tx_in;
312
313 if (unlikely(i2400m->tx_in) == 0)
314 return I2400M_TX_BUF_SIZE;
315 tx_in = i2400m->tx_in % I2400M_TX_BUF_SIZE;
316 tail_room = I2400M_TX_BUF_SIZE - tx_in;
317 tail_room %= I2400M_TX_BUF_SIZE;
318 return tail_room;
319}
320
321
322/*
281 * Allocate @size bytes in the TX fifo, return a pointer to it 323 * Allocate @size bytes in the TX fifo, return a pointer to it
282 * 324 *
283 * @i2400m: device descriptor 325 * @i2400m: device descriptor
@@ -338,7 +380,7 @@ void *i2400m_tx_fifo_push(struct i2400m *i2400m, size_t size, size_t padding)
338 return NULL; 380 return NULL;
339 } 381 }
340 /* Is there space at the tail? */ 382 /* Is there space at the tail? */
341 tail_room = I2400M_TX_BUF_SIZE - i2400m->tx_in % I2400M_TX_BUF_SIZE; 383 tail_room = __i2400m_tx_tail_room(i2400m);
342 if (tail_room < needed_size) { 384 if (tail_room < needed_size) {
343 if (i2400m->tx_out % I2400M_TX_BUF_SIZE 385 if (i2400m->tx_out % I2400M_TX_BUF_SIZE
344 < i2400m->tx_in % I2400M_TX_BUF_SIZE) { 386 < i2400m->tx_in % I2400M_TX_BUF_SIZE) {
@@ -367,17 +409,29 @@ void *i2400m_tx_fifo_push(struct i2400m *i2400m, size_t size, size_t padding)
367 * (I2400M_PL_PAD for the payloads, I2400M_TX_PLD_SIZE for the 409 * (I2400M_PL_PAD for the payloads, I2400M_TX_PLD_SIZE for the
368 * header). 410 * header).
369 * 411 *
412 * Tail room can get to be zero if a message was opened when there was
413 * space only for a header. _tx_close() will mark it as to-skip (as it
414 * will have no payloads) and there will be no more space to flush, so
415 * nothing has to be done here. This is probably cheaper than ensuring
416 * in _tx_new() that there is some space for payloads...as we could
417 * always possibly hit the same problem if the payload wouldn't fit.
418 *
370 * Note: 419 * Note:
371 * 420 *
372 * Assumes i2400m->tx_lock is taken, and we use that as a barrier 421 * Assumes i2400m->tx_lock is taken, and we use that as a barrier
422 *
423 * This path is only taken for Case A FIFO situations [see
424 * i2400m_tx_fifo_push()]
373 */ 425 */
374static 426static
375void i2400m_tx_skip_tail(struct i2400m *i2400m) 427void i2400m_tx_skip_tail(struct i2400m *i2400m)
376{ 428{
377 struct device *dev = i2400m_dev(i2400m); 429 struct device *dev = i2400m_dev(i2400m);
378 size_t tx_in = i2400m->tx_in % I2400M_TX_BUF_SIZE; 430 size_t tx_in = i2400m->tx_in % I2400M_TX_BUF_SIZE;
379 size_t tail_room = I2400M_TX_BUF_SIZE - tx_in; 431 size_t tail_room = __i2400m_tx_tail_room(i2400m);
380 struct i2400m_msg_hdr *msg = i2400m->tx_buf + tx_in; 432 struct i2400m_msg_hdr *msg = i2400m->tx_buf + tx_in;
433 if (unlikely(tail_room == 0))
434 return;
381 BUG_ON(tail_room < sizeof(*msg)); 435 BUG_ON(tail_room < sizeof(*msg));
382 msg->size = tail_room | I2400M_TX_SKIP; 436 msg->size = tail_room | I2400M_TX_SKIP;
383 d_printf(2, dev, "skip tail: skipping %zu bytes @%zu\n", 437 d_printf(2, dev, "skip tail: skipping %zu bytes @%zu\n",
@@ -474,10 +528,18 @@ void i2400m_tx_close(struct i2400m *i2400m)
474 struct i2400m_msg_hdr *tx_msg_moved; 528 struct i2400m_msg_hdr *tx_msg_moved;
475 size_t aligned_size, padding, hdr_size; 529 size_t aligned_size, padding, hdr_size;
476 void *pad_buf; 530 void *pad_buf;
531 unsigned num_pls;
477 532
478 if (tx_msg->size & I2400M_TX_SKIP) /* a skipper? nothing to do */ 533 if (tx_msg->size & I2400M_TX_SKIP) /* a skipper? nothing to do */
479 goto out; 534 goto out;
480 535 num_pls = le16_to_cpu(tx_msg->num_pls);
536 /* We can get this situation when a new message was started
537 * and there was no space to add payloads before hitting the
538 tail (and taking padding into consideration). */
539 if (num_pls == 0) {
540 tx_msg->size |= I2400M_TX_SKIP;
541 goto out;
542 }
481 /* Relocate the message header 543 /* Relocate the message header
482 * 544 *
483 * Find the current header size, align it to 16 and if we need 545 * Find the current header size, align it to 16 and if we need
@@ -491,7 +553,7 @@ void i2400m_tx_close(struct i2400m *i2400m)
491 */ 553 */
492 hdr_size = sizeof(*tx_msg) 554 hdr_size = sizeof(*tx_msg)
493 + le16_to_cpu(tx_msg->num_pls) * sizeof(tx_msg->pld[0]); 555 + le16_to_cpu(tx_msg->num_pls) * sizeof(tx_msg->pld[0]);
494 hdr_size = ALIGN(hdr_size, I2400M_PL_PAD); 556 hdr_size = ALIGN(hdr_size, I2400M_PL_ALIGN);
495 tx_msg->offset = I2400M_TX_PLD_SIZE - hdr_size; 557 tx_msg->offset = I2400M_TX_PLD_SIZE - hdr_size;
496 tx_msg_moved = (void *) tx_msg + tx_msg->offset; 558 tx_msg_moved = (void *) tx_msg + tx_msg->offset;
497 memmove(tx_msg_moved, tx_msg, hdr_size); 559 memmove(tx_msg_moved, tx_msg, hdr_size);
@@ -574,7 +636,7 @@ int i2400m_tx(struct i2400m *i2400m, const void *buf, size_t buf_len,
574 636
575 d_fnstart(3, dev, "(i2400m %p skb %p [%zu bytes] pt %u)\n", 637 d_fnstart(3, dev, "(i2400m %p skb %p [%zu bytes] pt %u)\n",
576 i2400m, buf, buf_len, pl_type); 638 i2400m, buf, buf_len, pl_type);
577 padded_len = ALIGN(buf_len, I2400M_PL_PAD); 639 padded_len = ALIGN(buf_len, I2400M_PL_ALIGN);
578 d_printf(5, dev, "padded_len %zd buf_len %zd\n", padded_len, buf_len); 640 d_printf(5, dev, "padded_len %zd buf_len %zd\n", padded_len, buf_len);
579 /* If there is no current TX message, create one; if the 641 /* If there is no current TX message, create one; if the
580 * current one is out of payload slots or we have a singleton, 642 * current one is out of payload slots or we have a singleton,
@@ -591,6 +653,8 @@ try_new:
591 i2400m_tx_close(i2400m); 653 i2400m_tx_close(i2400m);
592 i2400m_tx_new(i2400m); 654 i2400m_tx_new(i2400m);
593 } 655 }
656 if (i2400m->tx_msg == NULL)
657 goto error_tx_new;
594 if (i2400m->tx_msg->size + padded_len > I2400M_TX_BUF_SIZE / 2) { 658 if (i2400m->tx_msg->size + padded_len > I2400M_TX_BUF_SIZE / 2) {
595 d_printf(2, dev, "TX: message too big, going new\n"); 659 d_printf(2, dev, "TX: message too big, going new\n");
596 i2400m_tx_close(i2400m); 660 i2400m_tx_close(i2400m);
@@ -773,7 +837,6 @@ void i2400m_tx_msg_sent(struct i2400m *i2400m)
773 n = i2400m->tx_out / I2400M_TX_BUF_SIZE; 837 n = i2400m->tx_out / I2400M_TX_BUF_SIZE;
774 i2400m->tx_out %= I2400M_TX_BUF_SIZE; 838 i2400m->tx_out %= I2400M_TX_BUF_SIZE;
775 i2400m->tx_in -= n * I2400M_TX_BUF_SIZE; 839 i2400m->tx_in -= n * I2400M_TX_BUF_SIZE;
776 netif_start_queue(i2400m->wimax_dev.net_dev);
777 spin_unlock_irqrestore(&i2400m->tx_lock, flags); 840 spin_unlock_irqrestore(&i2400m->tx_lock, flags);
778 d_fnend(3, dev, "(i2400m %p) = void\n", i2400m); 841 d_fnend(3, dev, "(i2400m %p) = void\n", i2400m);
779} 842}
diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c
index 17851321b7fd..cfdaf69da9d1 100644
--- a/drivers/net/wimax/i2400m/usb.c
+++ b/drivers/net/wimax/i2400m/usb.c
@@ -254,8 +254,10 @@ do_bus_reset:
254 dev_err(dev, "USB reset failed (%d), giving up!\n", 254 dev_err(dev, "USB reset failed (%d), giving up!\n",
255 result); 255 result);
256 } 256 }
257 } else 257 } else {
258 result = -EINVAL; /* shut gcc up in certain arches */
258 BUG(); 259 BUG();
260 }
259 if (result < 0 261 if (result < 0
260 && result != -EINVAL /* device is gone */ 262 && result != -EINVAL /* device is gone */
261 && rt != I2400M_RT_BUS) { 263 && rt != I2400M_RT_BUS) {
@@ -399,6 +401,7 @@ int i2400mu_probe(struct usb_interface *iface,
399 i2400m->bus_dev_stop = i2400mu_bus_dev_stop; 401 i2400m->bus_dev_stop = i2400mu_bus_dev_stop;
400 i2400m->bus_tx_kick = i2400mu_bus_tx_kick; 402 i2400m->bus_tx_kick = i2400mu_bus_tx_kick;
401 i2400m->bus_reset = i2400mu_bus_reset; 403 i2400m->bus_reset = i2400mu_bus_reset;
404 i2400m->bus_bm_retries = I2400M_BOOT_RETRIES;
402 i2400m->bus_bm_cmd_send = i2400mu_bus_bm_cmd_send; 405 i2400m->bus_bm_cmd_send = i2400mu_bus_bm_cmd_send;
403 i2400m->bus_bm_wait_for_ack = i2400mu_bus_bm_wait_for_ack; 406 i2400m->bus_bm_wait_for_ack = i2400mu_bus_bm_wait_for_ack;
404 i2400m->bus_fw_names = i2400mu_bus_fw_names; 407 i2400m->bus_fw_names = i2400mu_bus_fw_names;