aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wimax
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wimax')
-rw-r--r--drivers/net/wimax/i2400m/control.c124
-rw-r--r--drivers/net/wimax/i2400m/driver.c45
-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.h48
-rw-r--r--drivers/net/wimax/i2400m/netdev.c4
-rw-r--r--drivers/net/wimax/i2400m/op-rfkill.c4
-rw-r--r--drivers/net/wimax/i2400m/rx.c10
-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.c68
-rw-r--r--drivers/net/wimax/i2400m/tx.c75
-rw-r--r--drivers/net/wimax/i2400m/usb.c5
13 files changed, 396 insertions, 210 deletions
diff --git a/drivers/net/wimax/i2400m/control.c b/drivers/net/wimax/i2400m/control.c
index b3cadb626fe0..07308686dbcf 100644
--- a/drivers/net/wimax/i2400m/control.c
+++ b/drivers/net/wimax/i2400m/control.c
@@ -292,8 +292,6 @@ void i2400m_report_tlv_system_state(struct i2400m *i2400m,
292 292
293 d_fnstart(3, dev, "(i2400m %p ss %p [%u])\n", i2400m, ss, i2400m_state); 293 d_fnstart(3, dev, "(i2400m %p ss %p [%u])\n", i2400m, ss, i2400m_state);
294 294
295 if (unlikely(i2400m->ready == 0)) /* act if up */
296 goto out;
297 if (i2400m->state != i2400m_state) { 295 if (i2400m->state != i2400m_state) {
298 i2400m->state = i2400m_state; 296 i2400m->state = i2400m_state;
299 wake_up_all(&i2400m->state_wq); 297 wake_up_all(&i2400m->state_wq);
@@ -341,7 +339,6 @@ void i2400m_report_tlv_system_state(struct i2400m *i2400m,
341 i2400m->bus_reset(i2400m, I2400M_RT_WARM); 339 i2400m->bus_reset(i2400m, I2400M_RT_WARM);
342 break; 340 break;
343 }; 341 };
344out:
345 d_fnend(3, dev, "(i2400m %p ss %p [%u]) = void\n", 342 d_fnend(3, dev, "(i2400m %p ss %p [%u]) = void\n",
346 i2400m, ss, i2400m_state); 343 i2400m, ss, i2400m_state);
347} 344}
@@ -372,8 +369,6 @@ void i2400m_report_tlv_media_status(struct i2400m *i2400m,
372 369
373 d_fnstart(3, dev, "(i2400m %p ms %p [%u])\n", i2400m, ms, status); 370 d_fnstart(3, dev, "(i2400m %p ms %p [%u])\n", i2400m, ms, status);
374 371
375 if (unlikely(i2400m->ready == 0)) /* act if up */
376 goto out;
377 switch (status) { 372 switch (status) {
378 case I2400M_MEDIA_STATUS_LINK_UP: 373 case I2400M_MEDIA_STATUS_LINK_UP:
379 netif_carrier_on(net_dev); 374 netif_carrier_on(net_dev);
@@ -393,14 +388,59 @@ void i2400m_report_tlv_media_status(struct i2400m *i2400m,
393 dev_err(dev, "HW BUG? unknown media status %u\n", 388 dev_err(dev, "HW BUG? unknown media status %u\n",
394 status); 389 status);
395 }; 390 };
396out:
397 d_fnend(3, dev, "(i2400m %p ms %p [%u]) = void\n", 391 d_fnend(3, dev, "(i2400m %p ms %p [%u]) = void\n",
398 i2400m, ms, status); 392 i2400m, ms, status);
399} 393}
400 394
401 395
402/* 396/*
403 * Parse a 'state report' and extract carrier on/off information 397 * Process a TLV from a 'state report'
398 *
399 * @i2400m: device descriptor
400 * @tlv: pointer to the TLV header; it has been already validated for
401 * consistent size.
402 * @tag: for error messages
403 *
404 * Act on the TLVs from a 'state report'.
405 */
406static
407void i2400m_report_state_parse_tlv(struct i2400m *i2400m,
408 const struct i2400m_tlv_hdr *tlv,
409 const char *tag)
410{
411 struct device *dev = i2400m_dev(i2400m);
412 const struct i2400m_tlv_media_status *ms;
413 const struct i2400m_tlv_system_state *ss;
414 const struct i2400m_tlv_rf_switches_status *rfss;
415
416 if (0 == i2400m_tlv_match(tlv, I2400M_TLV_SYSTEM_STATE, sizeof(*ss))) {
417 ss = container_of(tlv, typeof(*ss), hdr);
418 d_printf(2, dev, "%s: system state TLV "
419 "found (0x%04x), state 0x%08x\n",
420 tag, I2400M_TLV_SYSTEM_STATE,
421 le32_to_cpu(ss->state));
422 i2400m_report_tlv_system_state(i2400m, ss);
423 }
424 if (0 == i2400m_tlv_match(tlv, I2400M_TLV_RF_STATUS, sizeof(*rfss))) {
425 rfss = container_of(tlv, typeof(*rfss), hdr);
426 d_printf(2, dev, "%s: RF status TLV "
427 "found (0x%04x), sw 0x%02x hw 0x%02x\n",
428 tag, I2400M_TLV_RF_STATUS,
429 le32_to_cpu(rfss->sw_rf_switch),
430 le32_to_cpu(rfss->hw_rf_switch));
431 i2400m_report_tlv_rf_switches_status(i2400m, rfss);
432 }
433 if (0 == i2400m_tlv_match(tlv, I2400M_TLV_MEDIA_STATUS, sizeof(*ms))) {
434 ms = container_of(tlv, typeof(*ms), hdr);
435 d_printf(2, dev, "%s: Media Status TLV: %u\n",
436 tag, le32_to_cpu(ms->media_status));
437 i2400m_report_tlv_media_status(i2400m, ms);
438 }
439}
440
441
442/*
443 * Parse a 'state report' and extract information
404 * 444 *
405 * @i2400m: device descriptor 445 * @i2400m: device descriptor
406 * @l3l4_hdr: pointer to message; it has been already validated for 446 * @l3l4_hdr: pointer to message; it has been already validated for
@@ -409,13 +449,7 @@ out:
409 * declaration is assumed to be congruent with @size (as in 449 * declaration is assumed to be congruent with @size (as in
410 * sizeof(*l3l4_hdr) + l3l4_hdr->length == size) 450 * sizeof(*l3l4_hdr) + l3l4_hdr->length == size)
411 * 451 *
412 * Extract from the report state the system state TLV and infer from 452 * Walk over the TLVs in a report state and act on them.
413 * there if we have a carrier or not. Update our local state and tell
414 * netdev.
415 *
416 * When setting the carrier, it's fine to set OFF twice (for example),
417 * as netif_carrier_off() will not generate two OFF events (just on
418 * the transitions).
419 */ 453 */
420static 454static
421void i2400m_report_state_hook(struct i2400m *i2400m, 455void i2400m_report_state_hook(struct i2400m *i2400m,
@@ -424,9 +458,6 @@ void i2400m_report_state_hook(struct i2400m *i2400m,
424{ 458{
425 struct device *dev = i2400m_dev(i2400m); 459 struct device *dev = i2400m_dev(i2400m);
426 const struct i2400m_tlv_hdr *tlv; 460 const struct i2400m_tlv_hdr *tlv;
427 const struct i2400m_tlv_system_state *ss;
428 const struct i2400m_tlv_rf_switches_status *rfss;
429 const struct i2400m_tlv_media_status *ms;
430 size_t tlv_size = le16_to_cpu(l3l4_hdr->length); 461 size_t tlv_size = le16_to_cpu(l3l4_hdr->length);
431 462
432 d_fnstart(4, dev, "(i2400m %p, l3l4_hdr %p, size %zu, %s)\n", 463 d_fnstart(4, dev, "(i2400m %p, l3l4_hdr %p, size %zu, %s)\n",
@@ -434,34 +465,8 @@ void i2400m_report_state_hook(struct i2400m *i2400m,
434 tlv = NULL; 465 tlv = NULL;
435 466
436 while ((tlv = i2400m_tlv_buffer_walk(i2400m, &l3l4_hdr->pl, 467 while ((tlv = i2400m_tlv_buffer_walk(i2400m, &l3l4_hdr->pl,
437 tlv_size, tlv))) { 468 tlv_size, tlv)))
438 if (0 == i2400m_tlv_match(tlv, I2400M_TLV_SYSTEM_STATE, 469 i2400m_report_state_parse_tlv(i2400m, tlv, tag);
439 sizeof(*ss))) {
440 ss = container_of(tlv, typeof(*ss), hdr);
441 d_printf(2, dev, "%s: system state TLV "
442 "found (0x%04x), state 0x%08x\n",
443 tag, I2400M_TLV_SYSTEM_STATE,
444 le32_to_cpu(ss->state));
445 i2400m_report_tlv_system_state(i2400m, ss);
446 }
447 if (0 == i2400m_tlv_match(tlv, I2400M_TLV_RF_STATUS,
448 sizeof(*rfss))) {
449 rfss = container_of(tlv, typeof(*rfss), hdr);
450 d_printf(2, dev, "%s: RF status TLV "
451 "found (0x%04x), sw 0x%02x hw 0x%02x\n",
452 tag, I2400M_TLV_RF_STATUS,
453 le32_to_cpu(rfss->sw_rf_switch),
454 le32_to_cpu(rfss->hw_rf_switch));
455 i2400m_report_tlv_rf_switches_status(i2400m, rfss);
456 }
457 if (0 == i2400m_tlv_match(tlv, I2400M_TLV_MEDIA_STATUS,
458 sizeof(*ms))) {
459 ms = container_of(tlv, typeof(*ms), hdr);
460 d_printf(2, dev, "%s: Media Status TLV: %u\n",
461 tag, le32_to_cpu(ms->media_status));
462 i2400m_report_tlv_media_status(i2400m, ms);
463 }
464 }
465 d_fnend(4, dev, "(i2400m %p, l3l4_hdr %p, size %zu, %s) = void\n", 470 d_fnend(4, dev, "(i2400m %p, l3l4_hdr %p, size %zu, %s) = void\n",
466 i2400m, l3l4_hdr, size, tag); 471 i2400m, l3l4_hdr, size, tag);
467} 472}
@@ -500,8 +505,15 @@ void i2400m_report_hook(struct i2400m *i2400m,
500 * it. */ 505 * it. */
501 case I2400M_MT_REPORT_POWERSAVE_READY: /* zzzzz */ 506 case I2400M_MT_REPORT_POWERSAVE_READY: /* zzzzz */
502 if (l3l4_hdr->status == cpu_to_le16(I2400M_MS_DONE_OK)) { 507 if (l3l4_hdr->status == cpu_to_le16(I2400M_MS_DONE_OK)) {
503 d_printf(1, dev, "ready for powersave, requesting\n"); 508 if (i2400m_power_save_disabled)
504 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 }
505 } 517 }
506 break; 518 break;
507 }; 519 };
@@ -683,8 +695,9 @@ struct sk_buff *i2400m_msg_to_dev(struct i2400m *i2400m,
683 d_fnstart(3, dev, "(i2400m %p buf %p len %zu)\n", 695 d_fnstart(3, dev, "(i2400m %p buf %p len %zu)\n",
684 i2400m, buf, buf_len); 696 i2400m, buf, buf_len);
685 697
698 rmb(); /* Make sure we see what i2400m_dev_reset_handle() */
686 if (i2400m->boot_mode) 699 if (i2400m->boot_mode)
687 return ERR_PTR(-ENODEV); 700 return ERR_PTR(-EL3RST);
688 701
689 msg_l3l4_hdr = buf; 702 msg_l3l4_hdr = buf;
690 /* Check msg & payload consistency */ 703 /* Check msg & payload consistency */
@@ -721,6 +734,8 @@ struct sk_buff *i2400m_msg_to_dev(struct i2400m *i2400m,
721 ack_timeout = HZ; 734 ack_timeout = HZ;
722 }; 735 };
723 736
737 if (unlikely(i2400m->trace_msg_from_user))
738 wimax_msg(&i2400m->wimax_dev, "echo", buf, buf_len, GFP_KERNEL);
724 /* The RX path in rx.c will put any response for this message 739 /* The RX path in rx.c will put any response for this message
725 * in i2400m->ack_skb and wake us up. If we cancel the wait, 740 * in i2400m->ack_skb and wake us up. If we cancel the wait,
726 * we need to change the value of i2400m->ack_skb to something 741 * we need to change the value of i2400m->ack_skb to something
@@ -755,6 +770,9 @@ struct sk_buff *i2400m_msg_to_dev(struct i2400m *i2400m,
755 ack_l3l4_hdr = wimax_msg_data_len(ack_skb, &ack_len); 770 ack_l3l4_hdr = wimax_msg_data_len(ack_skb, &ack_len);
756 771
757 /* Check the ack and deliver it if it is ok */ 772 /* Check the ack and deliver it if it is ok */
773 if (unlikely(i2400m->trace_msg_from_user))
774 wimax_msg(&i2400m->wimax_dev, "echo",
775 ack_l3l4_hdr, ack_len, GFP_KERNEL);
758 result = i2400m_msg_size_check(i2400m, ack_l3l4_hdr, ack_len); 776 result = i2400m_msg_size_check(i2400m, ack_l3l4_hdr, ack_len);
759 if (result < 0) { 777 if (result < 0) {
760 dev_err(dev, "HW BUG? reply to message 0x%04x: %d\n", 778 dev_err(dev, "HW BUG? reply to message 0x%04x: %d\n",
@@ -1379,16 +1397,16 @@ error:
1379 * 1397 *
1380 * @i2400m: device descriptor 1398 * @i2400m: device descriptor
1381 * 1399 *
1382 * Gracefully stops the device, moving it to the lowest power 1400 * Release resources acquired during the running of the device; in
1383 * 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.
1384 */ 1404 */
1385void i2400m_dev_shutdown(struct i2400m *i2400m) 1405void i2400m_dev_shutdown(struct i2400m *i2400m)
1386{ 1406{
1387 int result = -ENODEV;
1388 struct device *dev = i2400m_dev(i2400m); 1407 struct device *dev = i2400m_dev(i2400m);
1389 1408
1390 d_fnstart(3, dev, "(i2400m %p)\n", i2400m); 1409 d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
1391 result = i2400m->bus_reset(i2400m, I2400M_RT_WARM); 1410 d_fnend(3, dev, "(i2400m %p) = void\n", i2400m);
1392 d_fnend(3, dev, "(i2400m %p) = void [%d]\n", i2400m, result);
1393 return; 1411 return;
1394} 1412}
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) {
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 3ae2df38b59a..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
@@ -323,6 +362,10 @@ struct i2400m_roq;
323 * delivered. Then the driver can release them to the host. See 362 * delivered. Then the driver can release them to the host. See
324 * drivers/net/i2400m/rx.c for details. 363 * drivers/net/i2400m/rx.c for details.
325 * 364 *
365 * @src_mac_addr: MAC address used to make ethernet packets be coming
366 * from. This is generated at i2400m_setup() time and used during
367 * the life cycle of the instance. See i2400m_fake_eth_header().
368 *
326 * @init_mutex: Mutex used for serializing the device bringup 369 * @init_mutex: Mutex used for serializing the device bringup
327 * sequence; this way if the device reboots in the middle, we 370 * sequence; this way if the device reboots in the middle, we
328 * don't try to do a bringup again while we are tearing down the 371 * don't try to do a bringup again while we are tearing down the
@@ -395,6 +438,8 @@ struct i2400m {
395 438
396 size_t bus_tx_block_size; 439 size_t bus_tx_block_size;
397 size_t bus_pl_size_max; 440 size_t bus_pl_size_max;
441 unsigned bus_bm_retries;
442
398 int (*bus_dev_start)(struct i2400m *); 443 int (*bus_dev_start)(struct i2400m *);
399 void (*bus_dev_stop)(struct i2400m *); 444 void (*bus_dev_stop)(struct i2400m *);
400 void (*bus_tx_kick)(struct i2400m *); 445 void (*bus_tx_kick)(struct i2400m *);
@@ -406,6 +451,7 @@ struct i2400m {
406 struct i2400m_bootrom_header *, size_t); 451 struct i2400m_bootrom_header *, size_t);
407 const char **bus_fw_names; 452 const char **bus_fw_names;
408 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;
409 455
410 spinlock_t tx_lock; /* protect TX state */ 456 spinlock_t tx_lock; /* protect TX state */
411 void *tx_buf; 457 void *tx_buf;
@@ -421,6 +467,7 @@ struct i2400m {
421 unsigned rx_pl_num, rx_pl_max, rx_pl_min, 467 unsigned rx_pl_num, rx_pl_max, rx_pl_min,
422 rx_num, rx_size_acc, rx_size_min, rx_size_max; 468 rx_num, rx_size_acc, rx_size_min, rx_size_max;
423 struct i2400m_roq *rx_roq; /* not under rx_lock! */ 469 struct i2400m_roq *rx_roq; /* not under rx_lock! */
470 u8 src_mac_addr[ETH_HLEN];
424 471
425 struct mutex msg_mutex; /* serialize command execution */ 472 struct mutex msg_mutex; /* serialize command execution */
426 struct completion msg_completion; 473 struct completion msg_completion;
@@ -704,6 +751,7 @@ static const __le32 i2400m_SBOOT_BARKER[4] = {
704 cpu_to_le32(I2400M_SBOOT_BARKER) 751 cpu_to_le32(I2400M_SBOOT_BARKER)
705}; 752};
706 753
754extern int i2400m_power_save_disabled;
707 755
708/* 756/*
709 * Utility functions 757 * Utility functions
diff --git a/drivers/net/wimax/i2400m/netdev.c b/drivers/net/wimax/i2400m/netdev.c
index 6b1fe7a81f25..9653f478b382 100644
--- a/drivers/net/wimax/i2400m/netdev.c
+++ b/drivers/net/wimax/i2400m/netdev.c
@@ -404,10 +404,12 @@ static
404void i2400m_rx_fake_eth_header(struct net_device *net_dev, 404void i2400m_rx_fake_eth_header(struct net_device *net_dev,
405 void *_eth_hdr, __be16 protocol) 405 void *_eth_hdr, __be16 protocol)
406{ 406{
407 struct i2400m *i2400m = net_dev_to_i2400m(net_dev);
407 struct ethhdr *eth_hdr = _eth_hdr; 408 struct ethhdr *eth_hdr = _eth_hdr;
408 409
409 memcpy(eth_hdr->h_dest, net_dev->dev_addr, sizeof(eth_hdr->h_dest)); 410 memcpy(eth_hdr->h_dest, net_dev->dev_addr, sizeof(eth_hdr->h_dest));
410 memset(eth_hdr->h_source, 0, sizeof(eth_hdr->h_dest)); 411 memcpy(eth_hdr->h_source, i2400m->src_mac_addr,
412 sizeof(eth_hdr->h_source));
411 eth_hdr->h_proto = protocol; 413 eth_hdr->h_proto = protocol;
412} 414}
413 415
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 f9fc38902322..07c32e68909f 100644
--- a/drivers/net/wimax/i2400m/rx.c
+++ b/drivers/net/wimax/i2400m/rx.c
@@ -177,7 +177,8 @@ void i2400m_report_hook_work(struct work_struct *ws)
177 struct i2400m_work *iw = 177 struct i2400m_work *iw =
178 container_of(ws, struct i2400m_work, ws); 178 container_of(ws, struct i2400m_work, ws);
179 struct i2400m_report_hook_args *args = (void *) iw->pl; 179 struct i2400m_report_hook_args *args = (void *) iw->pl;
180 i2400m_report_hook(iw->i2400m, args->l3l4_hdr, args->size); 180 if (iw->i2400m->ready)
181 i2400m_report_hook(iw->i2400m, args->l3l4_hdr, args->size);
181 kfree_skb(args->skb_rx); 182 kfree_skb(args->skb_rx);
182 i2400m_put(iw->i2400m); 183 i2400m_put(iw->i2400m);
183 kfree(iw); 184 kfree(iw);
@@ -309,6 +310,9 @@ void i2400m_rx_ctl(struct i2400m *i2400m, struct sk_buff *skb_rx,
309 skb_get(skb_rx); 310 skb_get(skb_rx);
310 i2400m_queue_work(i2400m, i2400m_report_hook_work, 311 i2400m_queue_work(i2400m, i2400m_report_hook_work,
311 GFP_KERNEL, &args, sizeof(args)); 312 GFP_KERNEL, &args, sizeof(args));
313 if (unlikely(i2400m->trace_msg_from_user))
314 wimax_msg(&i2400m->wimax_dev, "echo",
315 l3l4_hdr, size, GFP_KERNEL);
312 result = wimax_msg(&i2400m->wimax_dev, NULL, l3l4_hdr, size, 316 result = wimax_msg(&i2400m->wimax_dev, NULL, l3l4_hdr, size,
313 GFP_KERNEL); 317 GFP_KERNEL);
314 if (result < 0) 318 if (result < 0)
@@ -1144,7 +1148,7 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb)
1144 num_pls = le16_to_cpu(msg_hdr->num_pls); 1148 num_pls = le16_to_cpu(msg_hdr->num_pls);
1145 pl_itr = sizeof(*msg_hdr) + /* Check payload descriptor(s) */ 1149 pl_itr = sizeof(*msg_hdr) + /* Check payload descriptor(s) */
1146 num_pls * sizeof(msg_hdr->pld[0]); 1150 num_pls * sizeof(msg_hdr->pld[0]);
1147 pl_itr = ALIGN(pl_itr, I2400M_PL_PAD); 1151 pl_itr = ALIGN(pl_itr, I2400M_PL_ALIGN);
1148 if (pl_itr > skb->len) { /* got all the payload descriptors? */ 1152 if (pl_itr > skb->len) { /* got all the payload descriptors? */
1149 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 "
1150 "%u payload descriptors (%zu each, total %zu)\n", 1154 "%u payload descriptors (%zu each, total %zu)\n",
@@ -1162,7 +1166,7 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb)
1162 single_last = num_pls == 1 || i == num_pls - 1; 1166 single_last = num_pls == 1 || i == num_pls - 1;
1163 i2400m_rx_payload(i2400m, skb, single_last, &msg_hdr->pld[i], 1167 i2400m_rx_payload(i2400m, skb, single_last, &msg_hdr->pld[i],
1164 skb->data + pl_itr); 1168 skb->data + pl_itr);
1165 pl_itr += ALIGN(pl_size, I2400M_PL_PAD); 1169 pl_itr += ALIGN(pl_size, I2400M_PL_ALIGN);
1166 cond_resched(); /* Don't monopolize */ 1170 cond_resched(); /* Don't monopolize */
1167 } 1171 }
1168 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 5ac5e76701cd..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,24 +423,32 @@ 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;
411 433 i2400m->bus_bm_pokes_table = &i2400ms_pokes[0];
412 result = i2400ms_enable_function(i2400ms->func);
413 if (result < 0) {
414 dev_err(dev, "Cannot enable SDIO function: %d\n", result);
415 goto error_func_enable;
416 }
417 434
418 sdio_claim_host(func); 435 sdio_claim_host(func);
419 result = sdio_set_block_size(func, I2400MS_BLK_SIZE); 436 result = sdio_set_block_size(func, I2400MS_BLK_SIZE);
437 sdio_release_host(func);
420 if (result < 0) { 438 if (result < 0) {
421 dev_err(dev, "Failed to set block size: %d\n", result); 439 dev_err(dev, "Failed to set block size: %d\n", result);
422 goto error_set_blk_size; 440 goto error_set_blk_size;
423 } 441 }
424 sdio_release_host(func); 442
443 result = i2400ms_enable_function(i2400ms->func);
444 if (result < 0) {
445 dev_err(dev, "Cannot enable SDIO function: %d\n", result);
446 goto error_func_enable;
447 }
448
449 result = i2400ms_rx_setup(i2400ms);
450 if (result < 0)
451 goto error_rx_setup;
425 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) {
@@ -440,12 +467,14 @@ 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:
443 sdio_set_drvdata(func, NULL); 470 i2400ms_rx_release(i2400ms);
471error_rx_setup:
444 sdio_claim_host(func); 472 sdio_claim_host(func);
445error_set_blk_size:
446 sdio_disable_func(func); 473 sdio_disable_func(func);
447 sdio_release_host(func); 474 sdio_release_host(func);
448error_func_enable: 475error_func_enable:
476error_set_blk_size:
477 sdio_set_drvdata(func, NULL);
449 free_netdev(net_dev); 478 free_netdev(net_dev);
450error_alloc_netdev: 479error_alloc_netdev:
451 return result; 480 return result;
@@ -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;