diff options
Diffstat (limited to 'drivers/net/wireless/libertas/if_spi.c')
-rw-r--r-- | drivers/net/wireless/libertas/if_spi.c | 727 |
1 files changed, 473 insertions, 254 deletions
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index fe3f08028eb3..463352c890d7 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c | |||
@@ -17,13 +17,13 @@ | |||
17 | * (at your option) any later version. | 17 | * (at your option) any later version. |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
21 | |||
20 | #include <linux/moduleparam.h> | 22 | #include <linux/moduleparam.h> |
21 | #include <linux/firmware.h> | 23 | #include <linux/firmware.h> |
22 | #include <linux/jiffies.h> | 24 | #include <linux/jiffies.h> |
23 | #include <linux/kthread.h> | ||
24 | #include <linux/list.h> | 25 | #include <linux/list.h> |
25 | #include <linux/netdevice.h> | 26 | #include <linux/netdevice.h> |
26 | #include <linux/semaphore.h> | ||
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/spi/libertas_spi.h> | 28 | #include <linux/spi/libertas_spi.h> |
29 | #include <linux/spi/spi.h> | 29 | #include <linux/spi/spi.h> |
@@ -34,14 +34,17 @@ | |||
34 | #include "dev.h" | 34 | #include "dev.h" |
35 | #include "if_spi.h" | 35 | #include "if_spi.h" |
36 | 36 | ||
37 | struct if_spi_packet { | ||
38 | struct list_head list; | ||
39 | u16 blen; | ||
40 | u8 buffer[0] __attribute__((aligned(4))); | ||
41 | }; | ||
42 | |||
37 | struct if_spi_card { | 43 | struct if_spi_card { |
38 | struct spi_device *spi; | 44 | struct spi_device *spi; |
39 | struct lbs_private *priv; | 45 | struct lbs_private *priv; |
40 | struct libertas_spi_platform_data *pdata; | 46 | struct libertas_spi_platform_data *pdata; |
41 | 47 | ||
42 | char helper_fw_name[IF_SPI_FW_NAME_MAX]; | ||
43 | char main_fw_name[IF_SPI_FW_NAME_MAX]; | ||
44 | |||
45 | /* The card ID and card revision, as reported by the hardware. */ | 48 | /* The card ID and card revision, as reported by the hardware. */ |
46 | u16 card_id; | 49 | u16 card_id; |
47 | u8 card_rev; | 50 | u8 card_rev; |
@@ -54,26 +57,66 @@ struct if_spi_card { | |||
54 | unsigned long spu_reg_delay; | 57 | unsigned long spu_reg_delay; |
55 | 58 | ||
56 | /* Handles all SPI communication (except for FW load) */ | 59 | /* Handles all SPI communication (except for FW load) */ |
57 | struct task_struct *spi_thread; | 60 | struct workqueue_struct *workqueue; |
58 | int run_thread; | 61 | struct work_struct packet_work; |
59 | 62 | struct work_struct resume_work; | |
60 | /* Used to wake up the spi_thread */ | ||
61 | struct semaphore spi_ready; | ||
62 | struct semaphore spi_thread_terminated; | ||
63 | 63 | ||
64 | u8 cmd_buffer[IF_SPI_CMD_BUF_SIZE]; | 64 | u8 cmd_buffer[IF_SPI_CMD_BUF_SIZE]; |
65 | |||
66 | /* A buffer of incoming packets from libertas core. | ||
67 | * Since we can't sleep in hw_host_to_card, we have to buffer | ||
68 | * them. */ | ||
69 | struct list_head cmd_packet_list; | ||
70 | struct list_head data_packet_list; | ||
71 | |||
72 | /* Protects cmd_packet_list and data_packet_list */ | ||
73 | spinlock_t buffer_lock; | ||
74 | |||
75 | /* True is card suspended */ | ||
76 | u8 suspended; | ||
65 | }; | 77 | }; |
66 | 78 | ||
67 | static void free_if_spi_card(struct if_spi_card *card) | 79 | static void free_if_spi_card(struct if_spi_card *card) |
68 | { | 80 | { |
81 | struct list_head *cursor, *next; | ||
82 | struct if_spi_packet *packet; | ||
83 | |||
84 | list_for_each_safe(cursor, next, &card->cmd_packet_list) { | ||
85 | packet = container_of(cursor, struct if_spi_packet, list); | ||
86 | list_del(&packet->list); | ||
87 | kfree(packet); | ||
88 | } | ||
89 | list_for_each_safe(cursor, next, &card->data_packet_list) { | ||
90 | packet = container_of(cursor, struct if_spi_packet, list); | ||
91 | list_del(&packet->list); | ||
92 | kfree(packet); | ||
93 | } | ||
69 | spi_set_drvdata(card->spi, NULL); | 94 | spi_set_drvdata(card->spi, NULL); |
70 | kfree(card); | 95 | kfree(card); |
71 | } | 96 | } |
72 | 97 | ||
73 | static struct chip_ident chip_id_to_device_name[] = { | 98 | #define MODEL_8385 0x04 |
74 | { .chip_id = 0x04, .name = 8385 }, | 99 | #define MODEL_8686 0x0b |
75 | { .chip_id = 0x0b, .name = 8686 }, | 100 | #define MODEL_8688 0x10 |
101 | |||
102 | static const struct lbs_fw_table fw_table[] = { | ||
103 | { MODEL_8385, "libertas/gspi8385_helper.bin", "libertas/gspi8385.bin" }, | ||
104 | { MODEL_8385, "libertas/gspi8385_hlp.bin", "libertas/gspi8385.bin" }, | ||
105 | { MODEL_8686, "libertas/gspi8686_v9_helper.bin", "libertas/gspi8686_v9.bin" }, | ||
106 | { MODEL_8686, "libertas/gspi8686_hlp.bin", "libertas/gspi8686.bin" }, | ||
107 | { MODEL_8688, "libertas/gspi8688_helper.bin", "libertas/gspi8688.bin" }, | ||
108 | { 0, NULL, NULL } | ||
76 | }; | 109 | }; |
110 | MODULE_FIRMWARE("libertas/gspi8385_helper.bin"); | ||
111 | MODULE_FIRMWARE("libertas/gspi8385_hlp.bin"); | ||
112 | MODULE_FIRMWARE("libertas/gspi8385.bin"); | ||
113 | MODULE_FIRMWARE("libertas/gspi8686_v9_helper.bin"); | ||
114 | MODULE_FIRMWARE("libertas/gspi8686_v9.bin"); | ||
115 | MODULE_FIRMWARE("libertas/gspi8686_hlp.bin"); | ||
116 | MODULE_FIRMWARE("libertas/gspi8686.bin"); | ||
117 | MODULE_FIRMWARE("libertas/gspi8688_helper.bin"); | ||
118 | MODULE_FIRMWARE("libertas/gspi8688.bin"); | ||
119 | |||
77 | 120 | ||
78 | /* | 121 | /* |
79 | * SPI Interface Unit Routines | 122 | * SPI Interface Unit Routines |
@@ -102,8 +145,10 @@ static void spu_transaction_finish(struct if_spi_card *card) | |||
102 | card->prev_xfer_time = jiffies; | 145 | card->prev_xfer_time = jiffies; |
103 | } | 146 | } |
104 | 147 | ||
105 | /* Write out a byte buffer to an SPI register, | 148 | /* |
106 | * using a series of 16-bit transfers. */ | 149 | * Write out a byte buffer to an SPI register, |
150 | * using a series of 16-bit transfers. | ||
151 | */ | ||
107 | static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len) | 152 | static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len) |
108 | { | 153 | { |
109 | int err = 0; | 154 | int err = 0; |
@@ -167,8 +212,10 @@ static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len) | |||
167 | struct spi_transfer dummy_trans; | 212 | struct spi_transfer dummy_trans; |
168 | struct spi_transfer data_trans; | 213 | struct spi_transfer data_trans; |
169 | 214 | ||
170 | /* You must take an even number of bytes from the SPU, even if you | 215 | /* |
171 | * don't care about the last one. */ | 216 | * You must take an even number of bytes from the SPU, even if you |
217 | * don't care about the last one. | ||
218 | */ | ||
172 | BUG_ON(len & 0x1); | 219 | BUG_ON(len & 0x1); |
173 | 220 | ||
174 | spu_transaction_init(card); | 221 | spu_transaction_init(card); |
@@ -217,8 +264,10 @@ static inline int spu_read_u16(struct if_spi_card *card, u16 reg, u16 *val) | |||
217 | return ret; | 264 | return ret; |
218 | } | 265 | } |
219 | 266 | ||
220 | /* Read 32 bits from an SPI register. | 267 | /* |
221 | * The low 16 bits are read first. */ | 268 | * Read 32 bits from an SPI register. |
269 | * The low 16 bits are read first. | ||
270 | */ | ||
222 | static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val) | 271 | static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val) |
223 | { | 272 | { |
224 | __le32 buf; | 273 | __le32 buf; |
@@ -230,13 +279,15 @@ static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val) | |||
230 | return err; | 279 | return err; |
231 | } | 280 | } |
232 | 281 | ||
233 | /* Keep reading 16 bits from an SPI register until you get the correct result. | 282 | /* |
283 | * Keep reading 16 bits from an SPI register until you get the correct result. | ||
234 | * | 284 | * |
235 | * If mask = 0, the correct result is any non-zero number. | 285 | * If mask = 0, the correct result is any non-zero number. |
236 | * If mask != 0, the correct result is any number where | 286 | * If mask != 0, the correct result is any number where |
237 | * number & target_mask == target | 287 | * number & target_mask == target |
238 | * | 288 | * |
239 | * Returns -ETIMEDOUT if a second passes without the correct result. */ | 289 | * Returns -ETIMEDOUT if a second passes without the correct result. |
290 | */ | ||
240 | static int spu_wait_for_u16(struct if_spi_card *card, u16 reg, | 291 | static int spu_wait_for_u16(struct if_spi_card *card, u16 reg, |
241 | u16 target_mask, u16 target) | 292 | u16 target_mask, u16 target) |
242 | { | 293 | { |
@@ -256,16 +307,17 @@ static int spu_wait_for_u16(struct if_spi_card *card, u16 reg, | |||
256 | } | 307 | } |
257 | udelay(100); | 308 | udelay(100); |
258 | if (time_after(jiffies, timeout)) { | 309 | if (time_after(jiffies, timeout)) { |
259 | lbs_pr_err("%s: timeout with val=%02x, " | 310 | pr_err("%s: timeout with val=%02x, target_mask=%02x, target=%02x\n", |
260 | "target_mask=%02x, target=%02x\n", | ||
261 | __func__, val, target_mask, target); | 311 | __func__, val, target_mask, target); |
262 | return -ETIMEDOUT; | 312 | return -ETIMEDOUT; |
263 | } | 313 | } |
264 | } | 314 | } |
265 | } | 315 | } |
266 | 316 | ||
267 | /* Read 16 bits from an SPI register until you receive a specific value. | 317 | /* |
268 | * Returns -ETIMEDOUT if a 4 tries pass without success. */ | 318 | * Read 16 bits from an SPI register until you receive a specific value. |
319 | * Returns -ETIMEDOUT if a 4 tries pass without success. | ||
320 | */ | ||
269 | static int spu_wait_for_u32(struct if_spi_card *card, u32 reg, u32 target) | 321 | static int spu_wait_for_u32(struct if_spi_card *card, u32 reg, u32 target) |
270 | { | 322 | { |
271 | int err, try; | 323 | int err, try; |
@@ -287,8 +339,10 @@ static int spu_set_interrupt_mode(struct if_spi_card *card, | |||
287 | { | 339 | { |
288 | int err = 0; | 340 | int err = 0; |
289 | 341 | ||
290 | /* We can suppress a host interrupt by clearing the appropriate | 342 | /* |
291 | * bit in the "host interrupt status mask" register */ | 343 | * We can suppress a host interrupt by clearing the appropriate |
344 | * bit in the "host interrupt status mask" register | ||
345 | */ | ||
292 | if (suppress_host_int) { | 346 | if (suppress_host_int) { |
293 | err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_MASK_REG, 0); | 347 | err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_MASK_REG, 0); |
294 | if (err) | 348 | if (err) |
@@ -304,10 +358,12 @@ static int spu_set_interrupt_mode(struct if_spi_card *card, | |||
304 | return err; | 358 | return err; |
305 | } | 359 | } |
306 | 360 | ||
307 | /* If auto-interrupts are on, the completion of certain transactions | 361 | /* |
362 | * If auto-interrupts are on, the completion of certain transactions | ||
308 | * will trigger an interrupt automatically. If auto-interrupts | 363 | * will trigger an interrupt automatically. If auto-interrupts |
309 | * are off, we need to set the "Card Interrupt Cause" register to | 364 | * are off, we need to set the "Card Interrupt Cause" register to |
310 | * trigger a card interrupt. */ | 365 | * trigger a card interrupt. |
366 | */ | ||
311 | if (auto_int) { | 367 | if (auto_int) { |
312 | err = spu_write_u16(card, IF_SPI_HOST_INT_CTRL_REG, | 368 | err = spu_write_u16(card, IF_SPI_HOST_INT_CTRL_REG, |
313 | IF_SPI_HICT_TX_DOWNLOAD_OVER_AUTO | | 369 | IF_SPI_HICT_TX_DOWNLOAD_OVER_AUTO | |
@@ -350,7 +406,7 @@ static int spu_set_bus_mode(struct if_spi_card *card, u16 mode) | |||
350 | if (err) | 406 | if (err) |
351 | return err; | 407 | return err; |
352 | if ((rval & 0xF) != mode) { | 408 | if ((rval & 0xF) != mode) { |
353 | lbs_pr_err("Can't read bus mode register.\n"); | 409 | pr_err("Can't read bus mode register\n"); |
354 | return -EIO; | 410 | return -EIO; |
355 | } | 411 | } |
356 | return 0; | 412 | return 0; |
@@ -361,8 +417,10 @@ static int spu_init(struct if_spi_card *card, int use_dummy_writes) | |||
361 | int err = 0; | 417 | int err = 0; |
362 | u32 delay; | 418 | u32 delay; |
363 | 419 | ||
364 | /* We have to start up in timed delay mode so that we can safely | 420 | /* |
365 | * read the Delay Read Register. */ | 421 | * We have to start up in timed delay mode so that we can safely |
422 | * read the Delay Read Register. | ||
423 | */ | ||
366 | card->use_dummy_writes = 0; | 424 | card->use_dummy_writes = 0; |
367 | err = spu_set_bus_mode(card, | 425 | err = spu_set_bus_mode(card, |
368 | IF_SPI_BUS_MODE_SPI_CLOCK_PHASE_RISING | | 426 | IF_SPI_BUS_MODE_SPI_CLOCK_PHASE_RISING | |
@@ -399,46 +457,44 @@ static int spu_init(struct if_spi_card *card, int use_dummy_writes) | |||
399 | * Firmware Loading | 457 | * Firmware Loading |
400 | */ | 458 | */ |
401 | 459 | ||
402 | static int if_spi_prog_helper_firmware(struct if_spi_card *card) | 460 | static int if_spi_prog_helper_firmware(struct if_spi_card *card, |
461 | const struct firmware *firmware) | ||
403 | { | 462 | { |
404 | int err = 0; | 463 | int err = 0; |
405 | const struct firmware *firmware = NULL; | ||
406 | int bytes_remaining; | 464 | int bytes_remaining; |
407 | const u8 *fw; | 465 | const u8 *fw; |
408 | u8 temp[HELPER_FW_LOAD_CHUNK_SZ]; | 466 | u8 temp[HELPER_FW_LOAD_CHUNK_SZ]; |
409 | struct spi_device *spi = card->spi; | ||
410 | 467 | ||
411 | lbs_deb_enter(LBS_DEB_SPI); | 468 | lbs_deb_enter(LBS_DEB_SPI); |
412 | 469 | ||
413 | err = spu_set_interrupt_mode(card, 1, 0); | 470 | err = spu_set_interrupt_mode(card, 1, 0); |
414 | if (err) | 471 | if (err) |
415 | goto out; | 472 | goto out; |
416 | /* Get helper firmware image */ | 473 | |
417 | err = request_firmware(&firmware, card->helper_fw_name, &spi->dev); | ||
418 | if (err) { | ||
419 | lbs_pr_err("request_firmware failed with err = %d\n", err); | ||
420 | goto out; | ||
421 | } | ||
422 | bytes_remaining = firmware->size; | 474 | bytes_remaining = firmware->size; |
423 | fw = firmware->data; | 475 | fw = firmware->data; |
424 | 476 | ||
425 | /* Load helper firmware image */ | 477 | /* Load helper firmware image */ |
426 | while (bytes_remaining > 0) { | 478 | while (bytes_remaining > 0) { |
427 | /* Scratch pad 1 should contain the number of bytes we | 479 | /* |
428 | * want to download to the firmware */ | 480 | * Scratch pad 1 should contain the number of bytes we |
481 | * want to download to the firmware | ||
482 | */ | ||
429 | err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG, | 483 | err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG, |
430 | HELPER_FW_LOAD_CHUNK_SZ); | 484 | HELPER_FW_LOAD_CHUNK_SZ); |
431 | if (err) | 485 | if (err) |
432 | goto release_firmware; | 486 | goto out; |
433 | 487 | ||
434 | err = spu_wait_for_u16(card, IF_SPI_HOST_INT_STATUS_REG, | 488 | err = spu_wait_for_u16(card, IF_SPI_HOST_INT_STATUS_REG, |
435 | IF_SPI_HIST_CMD_DOWNLOAD_RDY, | 489 | IF_SPI_HIST_CMD_DOWNLOAD_RDY, |
436 | IF_SPI_HIST_CMD_DOWNLOAD_RDY); | 490 | IF_SPI_HIST_CMD_DOWNLOAD_RDY); |
437 | if (err) | 491 | if (err) |
438 | goto release_firmware; | 492 | goto out; |
439 | 493 | ||
440 | /* Feed the data into the command read/write port reg | 494 | /* |
441 | * in chunks of 64 bytes */ | 495 | * Feed the data into the command read/write port reg |
496 | * in chunks of 64 bytes | ||
497 | */ | ||
442 | memset(temp, 0, sizeof(temp)); | 498 | memset(temp, 0, sizeof(temp)); |
443 | memcpy(temp, fw, | 499 | memcpy(temp, fw, |
444 | min(bytes_remaining, HELPER_FW_LOAD_CHUNK_SZ)); | 500 | min(bytes_remaining, HELPER_FW_LOAD_CHUNK_SZ)); |
@@ -446,59 +502,63 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card) | |||
446 | err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG, | 502 | err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG, |
447 | temp, HELPER_FW_LOAD_CHUNK_SZ); | 503 | temp, HELPER_FW_LOAD_CHUNK_SZ); |
448 | if (err) | 504 | if (err) |
449 | goto release_firmware; | 505 | goto out; |
450 | 506 | ||
451 | /* Interrupt the boot code */ | 507 | /* Interrupt the boot code */ |
452 | err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0); | 508 | err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0); |
453 | if (err) | 509 | if (err) |
454 | goto release_firmware; | 510 | goto out; |
455 | err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG, | 511 | err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG, |
456 | IF_SPI_CIC_CMD_DOWNLOAD_OVER); | 512 | IF_SPI_CIC_CMD_DOWNLOAD_OVER); |
457 | if (err) | 513 | if (err) |
458 | goto release_firmware; | 514 | goto out; |
459 | bytes_remaining -= HELPER_FW_LOAD_CHUNK_SZ; | 515 | bytes_remaining -= HELPER_FW_LOAD_CHUNK_SZ; |
460 | fw += HELPER_FW_LOAD_CHUNK_SZ; | 516 | fw += HELPER_FW_LOAD_CHUNK_SZ; |
461 | } | 517 | } |
462 | 518 | ||
463 | /* Once the helper / single stage firmware download is complete, | 519 | /* |
520 | * Once the helper / single stage firmware download is complete, | ||
464 | * write 0 to scratch pad 1 and interrupt the | 521 | * write 0 to scratch pad 1 and interrupt the |
465 | * bootloader. This completes the helper download. */ | 522 | * bootloader. This completes the helper download. |
523 | */ | ||
466 | err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG, FIRMWARE_DNLD_OK); | 524 | err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG, FIRMWARE_DNLD_OK); |
467 | if (err) | 525 | if (err) |
468 | goto release_firmware; | 526 | goto out; |
469 | err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0); | 527 | err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0); |
470 | if (err) | 528 | if (err) |
471 | goto release_firmware; | 529 | goto out; |
472 | err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG, | 530 | err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG, |
473 | IF_SPI_CIC_CMD_DOWNLOAD_OVER); | 531 | IF_SPI_CIC_CMD_DOWNLOAD_OVER); |
474 | goto release_firmware; | 532 | goto out; |
475 | 533 | ||
476 | lbs_deb_spi("waiting for helper to boot...\n"); | 534 | lbs_deb_spi("waiting for helper to boot...\n"); |
477 | 535 | ||
478 | release_firmware: | ||
479 | release_firmware(firmware); | ||
480 | out: | 536 | out: |
481 | if (err) | 537 | if (err) |
482 | lbs_pr_err("failed to load helper firmware (err=%d)\n", err); | 538 | pr_err("failed to load helper firmware (err=%d)\n", err); |
483 | lbs_deb_leave_args(LBS_DEB_SPI, "err %d", err); | 539 | lbs_deb_leave_args(LBS_DEB_SPI, "err %d", err); |
484 | return err; | 540 | return err; |
485 | } | 541 | } |
486 | 542 | ||
487 | /* Returns the length of the next packet the firmware expects us to send | 543 | /* |
488 | * Sets crc_err if the previous transfer had a CRC error. */ | 544 | * Returns the length of the next packet the firmware expects us to send. |
545 | * Sets crc_err if the previous transfer had a CRC error. | ||
546 | */ | ||
489 | static int if_spi_prog_main_firmware_check_len(struct if_spi_card *card, | 547 | static int if_spi_prog_main_firmware_check_len(struct if_spi_card *card, |
490 | int *crc_err) | 548 | int *crc_err) |
491 | { | 549 | { |
492 | u16 len; | 550 | u16 len; |
493 | int err = 0; | 551 | int err = 0; |
494 | 552 | ||
495 | /* wait until the host interrupt status register indicates | 553 | /* |
496 | * that we are ready to download */ | 554 | * wait until the host interrupt status register indicates |
555 | * that we are ready to download | ||
556 | */ | ||
497 | err = spu_wait_for_u16(card, IF_SPI_HOST_INT_STATUS_REG, | 557 | err = spu_wait_for_u16(card, IF_SPI_HOST_INT_STATUS_REG, |
498 | IF_SPI_HIST_CMD_DOWNLOAD_RDY, | 558 | IF_SPI_HIST_CMD_DOWNLOAD_RDY, |
499 | IF_SPI_HIST_CMD_DOWNLOAD_RDY); | 559 | IF_SPI_HIST_CMD_DOWNLOAD_RDY); |
500 | if (err) { | 560 | if (err) { |
501 | lbs_pr_err("timed out waiting for host_int_status\n"); | 561 | pr_err("timed out waiting for host_int_status\n"); |
502 | return err; | 562 | return err; |
503 | } | 563 | } |
504 | 564 | ||
@@ -508,9 +568,8 @@ static int if_spi_prog_main_firmware_check_len(struct if_spi_card *card, | |||
508 | return err; | 568 | return err; |
509 | 569 | ||
510 | if (len > IF_SPI_CMD_BUF_SIZE) { | 570 | if (len > IF_SPI_CMD_BUF_SIZE) { |
511 | lbs_pr_err("firmware load device requested a larger " | 571 | pr_err("firmware load device requested a larger transfer than we are prepared to handle (len = %d)\n", |
512 | "tranfer than we are prepared to " | 572 | len); |
513 | "handle. (len = %d)\n", len); | ||
514 | return -EIO; | 573 | return -EIO; |
515 | } | 574 | } |
516 | if (len & 0x1) { | 575 | if (len & 0x1) { |
@@ -523,13 +582,13 @@ static int if_spi_prog_main_firmware_check_len(struct if_spi_card *card, | |||
523 | return len; | 582 | return len; |
524 | } | 583 | } |
525 | 584 | ||
526 | static int if_spi_prog_main_firmware(struct if_spi_card *card) | 585 | static int if_spi_prog_main_firmware(struct if_spi_card *card, |
586 | const struct firmware *firmware) | ||
527 | { | 587 | { |
588 | struct lbs_private *priv = card->priv; | ||
528 | int len, prev_len; | 589 | int len, prev_len; |
529 | int bytes, crc_err = 0, err = 0; | 590 | int bytes, crc_err = 0, err = 0; |
530 | const struct firmware *firmware = NULL; | ||
531 | const u8 *fw; | 591 | const u8 *fw; |
532 | struct spi_device *spi = card->spi; | ||
533 | u16 num_crc_errs; | 592 | u16 num_crc_errs; |
534 | 593 | ||
535 | lbs_deb_enter(LBS_DEB_SPI); | 594 | lbs_deb_enter(LBS_DEB_SPI); |
@@ -538,19 +597,12 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card) | |||
538 | if (err) | 597 | if (err) |
539 | goto out; | 598 | goto out; |
540 | 599 | ||
541 | /* Get firmware image */ | ||
542 | err = request_firmware(&firmware, card->main_fw_name, &spi->dev); | ||
543 | if (err) { | ||
544 | lbs_pr_err("%s: can't get firmware '%s' from kernel. " | ||
545 | "err = %d\n", __func__, card->main_fw_name, err); | ||
546 | goto out; | ||
547 | } | ||
548 | |||
549 | err = spu_wait_for_u16(card, IF_SPI_SCRATCH_1_REG, 0, 0); | 600 | err = spu_wait_for_u16(card, IF_SPI_SCRATCH_1_REG, 0, 0); |
550 | if (err) { | 601 | if (err) { |
551 | lbs_pr_err("%s: timed out waiting for initial " | 602 | netdev_err(priv->dev, |
552 | "scratch reg = 0\n", __func__); | 603 | "%s: timed out waiting for initial scratch reg = 0\n", |
553 | goto release_firmware; | 604 | __func__); |
605 | goto out; | ||
554 | } | 606 | } |
555 | 607 | ||
556 | num_crc_errs = 0; | 608 | num_crc_errs = 0; |
@@ -560,22 +612,23 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card) | |||
560 | while ((len = if_spi_prog_main_firmware_check_len(card, &crc_err))) { | 612 | while ((len = if_spi_prog_main_firmware_check_len(card, &crc_err))) { |
561 | if (len < 0) { | 613 | if (len < 0) { |
562 | err = len; | 614 | err = len; |
563 | goto release_firmware; | 615 | goto out; |
564 | } | 616 | } |
565 | if (bytes < 0) { | 617 | if (bytes < 0) { |
566 | /* If there are no more bytes left, we would normally | 618 | /* |
567 | * expect to have terminated with len = 0 */ | 619 | * If there are no more bytes left, we would normally |
568 | lbs_pr_err("Firmware load wants more bytes " | 620 | * expect to have terminated with len = 0 |
569 | "than we have to offer.\n"); | 621 | */ |
622 | netdev_err(priv->dev, | ||
623 | "Firmware load wants more bytes than we have to offer.\n"); | ||
570 | break; | 624 | break; |
571 | } | 625 | } |
572 | if (crc_err) { | 626 | if (crc_err) { |
573 | /* Previous transfer failed. */ | 627 | /* Previous transfer failed. */ |
574 | if (++num_crc_errs > MAX_MAIN_FW_LOAD_CRC_ERR) { | 628 | if (++num_crc_errs > MAX_MAIN_FW_LOAD_CRC_ERR) { |
575 | lbs_pr_err("Too many CRC errors encountered " | 629 | pr_err("Too many CRC errors encountered in firmware load.\n"); |
576 | "in firmware load.\n"); | ||
577 | err = -EIO; | 630 | err = -EIO; |
578 | goto release_firmware; | 631 | goto out; |
579 | } | 632 | } |
580 | } else { | 633 | } else { |
581 | /* Previous transfer succeeded. Advance counters. */ | 634 | /* Previous transfer succeeded. Advance counters. */ |
@@ -590,36 +643,32 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card) | |||
590 | 643 | ||
591 | err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0); | 644 | err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0); |
592 | if (err) | 645 | if (err) |
593 | goto release_firmware; | 646 | goto out; |
594 | err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG, | 647 | err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG, |
595 | card->cmd_buffer, len); | 648 | card->cmd_buffer, len); |
596 | if (err) | 649 | if (err) |
597 | goto release_firmware; | 650 | goto out; |
598 | err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG , | 651 | err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG , |
599 | IF_SPI_CIC_CMD_DOWNLOAD_OVER); | 652 | IF_SPI_CIC_CMD_DOWNLOAD_OVER); |
600 | if (err) | 653 | if (err) |
601 | goto release_firmware; | 654 | goto out; |
602 | prev_len = len; | 655 | prev_len = len; |
603 | } | 656 | } |
604 | if (bytes > prev_len) { | 657 | if (bytes > prev_len) { |
605 | lbs_pr_err("firmware load wants fewer bytes than " | 658 | pr_err("firmware load wants fewer bytes than we have to offer\n"); |
606 | "we have to offer.\n"); | ||
607 | } | 659 | } |
608 | 660 | ||
609 | /* Confirm firmware download */ | 661 | /* Confirm firmware download */ |
610 | err = spu_wait_for_u32(card, IF_SPI_SCRATCH_4_REG, | 662 | err = spu_wait_for_u32(card, IF_SPI_SCRATCH_4_REG, |
611 | SUCCESSFUL_FW_DOWNLOAD_MAGIC); | 663 | SUCCESSFUL_FW_DOWNLOAD_MAGIC); |
612 | if (err) { | 664 | if (err) { |
613 | lbs_pr_err("failed to confirm the firmware download\n"); | 665 | pr_err("failed to confirm the firmware download\n"); |
614 | goto release_firmware; | 666 | goto out; |
615 | } | 667 | } |
616 | 668 | ||
617 | release_firmware: | ||
618 | release_firmware(firmware); | ||
619 | |||
620 | out: | 669 | out: |
621 | if (err) | 670 | if (err) |
622 | lbs_pr_err("failed to load firmware (err=%d)\n", err); | 671 | pr_err("failed to load firmware (err=%d)\n", err); |
623 | lbs_deb_leave_args(LBS_DEB_SPI, "err %d", err); | 672 | lbs_deb_leave_args(LBS_DEB_SPI, "err %d", err); |
624 | return err; | 673 | return err; |
625 | } | 674 | } |
@@ -627,7 +676,7 @@ out: | |||
627 | /* | 676 | /* |
628 | * SPI Transfer Thread | 677 | * SPI Transfer Thread |
629 | * | 678 | * |
630 | * The SPI thread handles all SPI transfers, so there is no need for a lock. | 679 | * The SPI worker handles all SPI transfers, so there is no need for a lock. |
631 | */ | 680 | */ |
632 | 681 | ||
633 | /* Move a command from the card to the host */ | 682 | /* Move a command from the card to the host */ |
@@ -639,14 +688,18 @@ static int if_spi_c2h_cmd(struct if_spi_card *card) | |||
639 | u16 len; | 688 | u16 len; |
640 | u8 i; | 689 | u8 i; |
641 | 690 | ||
642 | /* We need a buffer big enough to handle whatever people send to | 691 | /* |
643 | * hw_host_to_card */ | 692 | * We need a buffer big enough to handle whatever people send to |
693 | * hw_host_to_card | ||
694 | */ | ||
644 | BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE < LBS_CMD_BUFFER_SIZE); | 695 | BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE < LBS_CMD_BUFFER_SIZE); |
645 | BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE < LBS_UPLD_SIZE); | 696 | BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE < LBS_UPLD_SIZE); |
646 | 697 | ||
647 | /* It's just annoying if the buffer size isn't a multiple of 4, because | 698 | /* |
648 | * then we might have len < IF_SPI_CMD_BUF_SIZE but | 699 | * It's just annoying if the buffer size isn't a multiple of 4, because |
649 | * ALIGN(len, 4) > IF_SPI_CMD_BUF_SIZE */ | 700 | * then we might have len < IF_SPI_CMD_BUF_SIZE but |
701 | * ALIGN(len, 4) > IF_SPI_CMD_BUF_SIZE | ||
702 | */ | ||
650 | BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE % 4 != 0); | 703 | BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE % 4 != 0); |
651 | 704 | ||
652 | lbs_deb_enter(LBS_DEB_SPI); | 705 | lbs_deb_enter(LBS_DEB_SPI); |
@@ -656,13 +709,13 @@ static int if_spi_c2h_cmd(struct if_spi_card *card) | |||
656 | if (err) | 709 | if (err) |
657 | goto out; | 710 | goto out; |
658 | if (!len) { | 711 | if (!len) { |
659 | lbs_pr_err("%s: error: card has no data for host\n", | 712 | netdev_err(priv->dev, "%s: error: card has no data for host\n", |
660 | __func__); | 713 | __func__); |
661 | err = -EINVAL; | 714 | err = -EINVAL; |
662 | goto out; | 715 | goto out; |
663 | } else if (len > IF_SPI_CMD_BUF_SIZE) { | 716 | } else if (len > IF_SPI_CMD_BUF_SIZE) { |
664 | lbs_pr_err("%s: error: response packet too large: " | 717 | netdev_err(priv->dev, |
665 | "%d bytes, but maximum is %d\n", | 718 | "%s: error: response packet too large: %d bytes, but maximum is %d\n", |
666 | __func__, len, IF_SPI_CMD_BUF_SIZE); | 719 | __func__, len, IF_SPI_CMD_BUF_SIZE); |
667 | err = -EINVAL; | 720 | err = -EINVAL; |
668 | goto out; | 721 | goto out; |
@@ -684,7 +737,7 @@ static int if_spi_c2h_cmd(struct if_spi_card *card) | |||
684 | 737 | ||
685 | out: | 738 | out: |
686 | if (err) | 739 | if (err) |
687 | lbs_pr_err("%s: err=%d\n", __func__, err); | 740 | netdev_err(priv->dev, "%s: err=%d\n", __func__, err); |
688 | lbs_deb_leave(LBS_DEB_SPI); | 741 | lbs_deb_leave(LBS_DEB_SPI); |
689 | return err; | 742 | return err; |
690 | } | 743 | } |
@@ -692,6 +745,7 @@ out: | |||
692 | /* Move data from the card to the host */ | 745 | /* Move data from the card to the host */ |
693 | static int if_spi_c2h_data(struct if_spi_card *card) | 746 | static int if_spi_c2h_data(struct if_spi_card *card) |
694 | { | 747 | { |
748 | struct lbs_private *priv = card->priv; | ||
695 | struct sk_buff *skb; | 749 | struct sk_buff *skb; |
696 | char *data; | 750 | char *data; |
697 | u16 len; | 751 | u16 len; |
@@ -704,13 +758,13 @@ static int if_spi_c2h_data(struct if_spi_card *card) | |||
704 | if (err) | 758 | if (err) |
705 | goto out; | 759 | goto out; |
706 | if (!len) { | 760 | if (!len) { |
707 | lbs_pr_err("%s: error: card has no data for host\n", | 761 | netdev_err(priv->dev, "%s: error: card has no data for host\n", |
708 | __func__); | 762 | __func__); |
709 | err = -EINVAL; | 763 | err = -EINVAL; |
710 | goto out; | 764 | goto out; |
711 | } else if (len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) { | 765 | } else if (len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) { |
712 | lbs_pr_err("%s: error: card has %d bytes of data, but " | 766 | netdev_err(priv->dev, |
713 | "our maximum skb size is %zu\n", | 767 | "%s: error: card has %d bytes of data, but our maximum skb size is %zu\n", |
714 | __func__, len, MRVDRV_ETH_RX_PACKET_BUFFER_SIZE); | 768 | __func__, len, MRVDRV_ETH_RX_PACKET_BUFFER_SIZE); |
715 | err = -EINVAL; | 769 | err = -EINVAL; |
716 | goto out; | 770 | goto out; |
@@ -742,11 +796,47 @@ free_skb: | |||
742 | dev_kfree_skb(skb); | 796 | dev_kfree_skb(skb); |
743 | out: | 797 | out: |
744 | if (err) | 798 | if (err) |
745 | lbs_pr_err("%s: err=%d\n", __func__, err); | 799 | netdev_err(priv->dev, "%s: err=%d\n", __func__, err); |
746 | lbs_deb_leave(LBS_DEB_SPI); | 800 | lbs_deb_leave(LBS_DEB_SPI); |
747 | return err; | 801 | return err; |
748 | } | 802 | } |
749 | 803 | ||
804 | /* Move data or a command from the host to the card. */ | ||
805 | static void if_spi_h2c(struct if_spi_card *card, | ||
806 | struct if_spi_packet *packet, int type) | ||
807 | { | ||
808 | struct lbs_private *priv = card->priv; | ||
809 | int err = 0; | ||
810 | u16 int_type, port_reg; | ||
811 | |||
812 | switch (type) { | ||
813 | case MVMS_DAT: | ||
814 | int_type = IF_SPI_CIC_TX_DOWNLOAD_OVER; | ||
815 | port_reg = IF_SPI_DATA_RDWRPORT_REG; | ||
816 | break; | ||
817 | case MVMS_CMD: | ||
818 | int_type = IF_SPI_CIC_CMD_DOWNLOAD_OVER; | ||
819 | port_reg = IF_SPI_CMD_RDWRPORT_REG; | ||
820 | break; | ||
821 | default: | ||
822 | netdev_err(priv->dev, "can't transfer buffer of type %d\n", | ||
823 | type); | ||
824 | err = -EINVAL; | ||
825 | goto out; | ||
826 | } | ||
827 | |||
828 | /* Write the data to the card */ | ||
829 | err = spu_write(card, port_reg, packet->buffer, packet->blen); | ||
830 | if (err) | ||
831 | goto out; | ||
832 | |||
833 | out: | ||
834 | kfree(packet); | ||
835 | |||
836 | if (err) | ||
837 | netdev_err(priv->dev, "%s: error %d\n", __func__, err); | ||
838 | } | ||
839 | |||
750 | /* Inform the host about a card event */ | 840 | /* Inform the host about a card event */ |
751 | static void if_spi_e2h(struct if_spi_card *card) | 841 | static void if_spi_e2h(struct if_spi_card *card) |
752 | { | 842 | { |
@@ -768,102 +858,154 @@ static void if_spi_e2h(struct if_spi_card *card) | |||
768 | lbs_queue_event(priv, cause & 0xff); | 858 | lbs_queue_event(priv, cause & 0xff); |
769 | out: | 859 | out: |
770 | if (err) | 860 | if (err) |
771 | lbs_pr_err("%s: error %d\n", __func__, err); | 861 | netdev_err(priv->dev, "%s: error %d\n", __func__, err); |
772 | } | 862 | } |
773 | 863 | ||
774 | static int lbs_spi_thread(void *data) | 864 | static void if_spi_host_to_card_worker(struct work_struct *work) |
775 | { | 865 | { |
776 | int err; | 866 | int err; |
777 | struct if_spi_card *card = data; | 867 | struct if_spi_card *card; |
778 | u16 hiStatus; | 868 | u16 hiStatus; |
869 | unsigned long flags; | ||
870 | struct if_spi_packet *packet; | ||
871 | struct lbs_private *priv; | ||
779 | 872 | ||
780 | while (1) { | 873 | card = container_of(work, struct if_spi_card, packet_work); |
781 | /* Wait to be woken up by one of two things. First, our ISR | 874 | priv = card->priv; |
782 | * could tell us that something happened on the WLAN. | ||
783 | * Secondly, libertas could call hw_host_to_card with more | ||
784 | * data, which we might be able to send. | ||
785 | */ | ||
786 | do { | ||
787 | err = down_interruptible(&card->spi_ready); | ||
788 | if (!card->run_thread) { | ||
789 | up(&card->spi_thread_terminated); | ||
790 | do_exit(0); | ||
791 | } | ||
792 | } while (err == EINTR); | ||
793 | 875 | ||
794 | /* Read the host interrupt status register to see what we | 876 | lbs_deb_enter(LBS_DEB_SPI); |
795 | * can do. */ | 877 | |
796 | err = spu_read_u16(card, IF_SPI_HOST_INT_STATUS_REG, | 878 | /* |
797 | &hiStatus); | 879 | * Read the host interrupt status register to see what we |
798 | if (err) { | 880 | * can do. |
799 | lbs_pr_err("I/O error\n"); | 881 | */ |
882 | err = spu_read_u16(card, IF_SPI_HOST_INT_STATUS_REG, | ||
883 | &hiStatus); | ||
884 | if (err) { | ||
885 | netdev_err(priv->dev, "I/O error\n"); | ||
886 | goto err; | ||
887 | } | ||
888 | |||
889 | if (hiStatus & IF_SPI_HIST_CMD_UPLOAD_RDY) { | ||
890 | err = if_spi_c2h_cmd(card); | ||
891 | if (err) | ||
800 | goto err; | 892 | goto err; |
893 | } | ||
894 | if (hiStatus & IF_SPI_HIST_RX_UPLOAD_RDY) { | ||
895 | err = if_spi_c2h_data(card); | ||
896 | if (err) | ||
897 | goto err; | ||
898 | } | ||
899 | |||
900 | /* | ||
901 | * workaround: in PS mode, the card does not set the Command | ||
902 | * Download Ready bit, but it sets TX Download Ready. | ||
903 | */ | ||
904 | if (hiStatus & IF_SPI_HIST_CMD_DOWNLOAD_RDY || | ||
905 | (card->priv->psstate != PS_STATE_FULL_POWER && | ||
906 | (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY))) { | ||
907 | /* | ||
908 | * This means two things. First of all, | ||
909 | * if there was a previous command sent, the card has | ||
910 | * successfully received it. | ||
911 | * Secondly, it is now ready to download another | ||
912 | * command. | ||
913 | */ | ||
914 | lbs_host_to_card_done(card->priv); | ||
915 | |||
916 | /* Do we have any command packets from the host to send? */ | ||
917 | packet = NULL; | ||
918 | spin_lock_irqsave(&card->buffer_lock, flags); | ||
919 | if (!list_empty(&card->cmd_packet_list)) { | ||
920 | packet = (struct if_spi_packet *)(card-> | ||
921 | cmd_packet_list.next); | ||
922 | list_del(&packet->list); | ||
801 | } | 923 | } |
924 | spin_unlock_irqrestore(&card->buffer_lock, flags); | ||
802 | 925 | ||
803 | if (hiStatus & IF_SPI_HIST_CMD_UPLOAD_RDY) | 926 | if (packet) |
804 | err = if_spi_c2h_cmd(card); | 927 | if_spi_h2c(card, packet, MVMS_CMD); |
805 | if (err) | 928 | } |
806 | goto err; | 929 | if (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY) { |
807 | if (hiStatus & IF_SPI_HIST_RX_UPLOAD_RDY) | 930 | /* Do we have any data packets from the host to send? */ |
808 | err = if_spi_c2h_data(card); | 931 | packet = NULL; |
809 | if (err) | 932 | spin_lock_irqsave(&card->buffer_lock, flags); |
810 | goto err; | 933 | if (!list_empty(&card->data_packet_list)) { |
811 | 934 | packet = (struct if_spi_packet *)(card-> | |
812 | /* workaround: in PS mode, the card does not set the Command | 935 | data_packet_list.next); |
813 | * Download Ready bit, but it sets TX Download Ready. */ | 936 | list_del(&packet->list); |
814 | if (hiStatus & IF_SPI_HIST_CMD_DOWNLOAD_RDY || | ||
815 | (card->priv->psstate != PS_STATE_FULL_POWER && | ||
816 | (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY))) { | ||
817 | lbs_host_to_card_done(card->priv); | ||
818 | } | 937 | } |
938 | spin_unlock_irqrestore(&card->buffer_lock, flags); | ||
819 | 939 | ||
820 | if (hiStatus & IF_SPI_HIST_CARD_EVENT) | 940 | if (packet) |
821 | if_spi_e2h(card); | 941 | if_spi_h2c(card, packet, MVMS_DAT); |
942 | } | ||
943 | if (hiStatus & IF_SPI_HIST_CARD_EVENT) | ||
944 | if_spi_e2h(card); | ||
822 | 945 | ||
823 | err: | 946 | err: |
824 | if (err) | 947 | if (err) |
825 | lbs_pr_err("%s: got error %d\n", __func__, err); | 948 | netdev_err(priv->dev, "%s: got error %d\n", __func__, err); |
826 | } | ||
827 | } | ||
828 | 949 | ||
829 | /* Block until lbs_spi_thread thread has terminated */ | 950 | lbs_deb_leave(LBS_DEB_SPI); |
830 | static void if_spi_terminate_spi_thread(struct if_spi_card *card) | ||
831 | { | ||
832 | /* It would be nice to use kthread_stop here, but that function | ||
833 | * can't wake threads waiting for a semaphore. */ | ||
834 | card->run_thread = 0; | ||
835 | up(&card->spi_ready); | ||
836 | down(&card->spi_thread_terminated); | ||
837 | } | 951 | } |
838 | 952 | ||
839 | /* | 953 | /* |
840 | * Host to Card | 954 | * Host to Card |
841 | * | 955 | * |
842 | * Called from Libertas to transfer some data to the WLAN device | 956 | * Called from Libertas to transfer some data to the WLAN device |
843 | * We can't sleep here. */ | 957 | * We can't sleep here. |
958 | */ | ||
844 | static int if_spi_host_to_card(struct lbs_private *priv, | 959 | static int if_spi_host_to_card(struct lbs_private *priv, |
845 | u8 type, u8 *buf, u16 nb) | 960 | u8 type, u8 *buf, u16 nb) |
846 | { | 961 | { |
847 | int err = 0; | 962 | int err = 0; |
963 | unsigned long flags; | ||
848 | struct if_spi_card *card = priv->card; | 964 | struct if_spi_card *card = priv->card; |
965 | struct if_spi_packet *packet; | ||
966 | u16 blen; | ||
849 | 967 | ||
850 | lbs_deb_enter_args(LBS_DEB_SPI, "type %d, bytes %d", type, nb); | 968 | lbs_deb_enter_args(LBS_DEB_SPI, "type %d, bytes %d", type, nb); |
851 | 969 | ||
852 | nb = ALIGN(nb, 4); | 970 | if (nb == 0) { |
971 | netdev_err(priv->dev, "%s: invalid size requested: %d\n", | ||
972 | __func__, nb); | ||
973 | err = -EINVAL; | ||
974 | goto out; | ||
975 | } | ||
976 | blen = ALIGN(nb, 4); | ||
977 | packet = kzalloc(sizeof(struct if_spi_packet) + blen, GFP_ATOMIC); | ||
978 | if (!packet) { | ||
979 | err = -ENOMEM; | ||
980 | goto out; | ||
981 | } | ||
982 | packet->blen = blen; | ||
983 | memcpy(packet->buffer, buf, nb); | ||
984 | memset(packet->buffer + nb, 0, blen - nb); | ||
853 | 985 | ||
854 | switch (type) { | 986 | switch (type) { |
855 | case MVMS_CMD: | 987 | case MVMS_CMD: |
856 | err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG, buf, nb); | 988 | priv->dnld_sent = DNLD_CMD_SENT; |
989 | spin_lock_irqsave(&card->buffer_lock, flags); | ||
990 | list_add_tail(&packet->list, &card->cmd_packet_list); | ||
991 | spin_unlock_irqrestore(&card->buffer_lock, flags); | ||
857 | break; | 992 | break; |
858 | case MVMS_DAT: | 993 | case MVMS_DAT: |
859 | err = spu_write(card, IF_SPI_DATA_RDWRPORT_REG, buf, nb); | 994 | priv->dnld_sent = DNLD_DATA_SENT; |
995 | spin_lock_irqsave(&card->buffer_lock, flags); | ||
996 | list_add_tail(&packet->list, &card->data_packet_list); | ||
997 | spin_unlock_irqrestore(&card->buffer_lock, flags); | ||
860 | break; | 998 | break; |
861 | default: | 999 | default: |
862 | lbs_pr_err("can't transfer buffer of type %d", type); | 1000 | netdev_err(priv->dev, "can't transfer buffer of type %d\n", |
1001 | type); | ||
863 | err = -EINVAL; | 1002 | err = -EINVAL; |
864 | break; | 1003 | break; |
865 | } | 1004 | } |
866 | 1005 | ||
1006 | /* Queue spi xfer work */ | ||
1007 | queue_work(card->workqueue, &card->packet_work); | ||
1008 | out: | ||
867 | lbs_deb_leave_args(LBS_DEB_SPI, "err=%d", err); | 1009 | lbs_deb_leave_args(LBS_DEB_SPI, "err=%d", err); |
868 | return err; | 1010 | return err; |
869 | } | 1011 | } |
@@ -872,13 +1014,14 @@ static int if_spi_host_to_card(struct lbs_private *priv, | |||
872 | * Host Interrupts | 1014 | * Host Interrupts |
873 | * | 1015 | * |
874 | * Service incoming interrupts from the WLAN device. We can't sleep here, so | 1016 | * Service incoming interrupts from the WLAN device. We can't sleep here, so |
875 | * don't try to talk on the SPI bus, just wake up the SPI thread. | 1017 | * don't try to talk on the SPI bus, just queue the SPI xfer work. |
876 | */ | 1018 | */ |
877 | static irqreturn_t if_spi_host_interrupt(int irq, void *dev_id) | 1019 | static irqreturn_t if_spi_host_interrupt(int irq, void *dev_id) |
878 | { | 1020 | { |
879 | struct if_spi_card *card = dev_id; | 1021 | struct if_spi_card *card = dev_id; |
880 | 1022 | ||
881 | up(&card->spi_ready); | 1023 | queue_work(card->workqueue, &card->packet_work); |
1024 | |||
882 | return IRQ_HANDLED; | 1025 | return IRQ_HANDLED; |
883 | } | 1026 | } |
884 | 1027 | ||
@@ -886,28 +1029,104 @@ static irqreturn_t if_spi_host_interrupt(int irq, void *dev_id) | |||
886 | * SPI callbacks | 1029 | * SPI callbacks |
887 | */ | 1030 | */ |
888 | 1031 | ||
889 | static int if_spi_calculate_fw_names(u16 card_id, | 1032 | static int if_spi_init_card(struct if_spi_card *card) |
890 | char *helper_fw, char *main_fw) | ||
891 | { | 1033 | { |
892 | int i; | 1034 | struct lbs_private *priv = card->priv; |
893 | for (i = 0; i < ARRAY_SIZE(chip_id_to_device_name); ++i) { | 1035 | struct spi_device *spi = card->spi; |
894 | if (card_id == chip_id_to_device_name[i].chip_id) | 1036 | int err, i; |
895 | break; | 1037 | u32 scratch; |
1038 | const struct firmware *helper = NULL; | ||
1039 | const struct firmware *mainfw = NULL; | ||
1040 | |||
1041 | lbs_deb_enter(LBS_DEB_SPI); | ||
1042 | |||
1043 | err = spu_init(card, card->pdata->use_dummy_writes); | ||
1044 | if (err) | ||
1045 | goto out; | ||
1046 | err = spu_get_chip_revision(card, &card->card_id, &card->card_rev); | ||
1047 | if (err) | ||
1048 | goto out; | ||
1049 | |||
1050 | err = spu_read_u32(card, IF_SPI_SCRATCH_4_REG, &scratch); | ||
1051 | if (err) | ||
1052 | goto out; | ||
1053 | if (scratch == SUCCESSFUL_FW_DOWNLOAD_MAGIC) | ||
1054 | lbs_deb_spi("Firmware is already loaded for " | ||
1055 | "Marvell WLAN 802.11 adapter\n"); | ||
1056 | else { | ||
1057 | /* Check if we support this card */ | ||
1058 | for (i = 0; i < ARRAY_SIZE(fw_table); i++) { | ||
1059 | if (card->card_id == fw_table[i].model) | ||
1060 | break; | ||
1061 | } | ||
1062 | if (i == ARRAY_SIZE(fw_table)) { | ||
1063 | netdev_err(priv->dev, "Unsupported chip_id: 0x%02x\n", | ||
1064 | card->card_id); | ||
1065 | err = -ENODEV; | ||
1066 | goto out; | ||
1067 | } | ||
1068 | |||
1069 | err = lbs_get_firmware(&card->spi->dev, NULL, NULL, | ||
1070 | card->card_id, &fw_table[0], &helper, | ||
1071 | &mainfw); | ||
1072 | if (err) { | ||
1073 | netdev_err(priv->dev, "failed to find firmware (%d)\n", | ||
1074 | err); | ||
1075 | goto out; | ||
1076 | } | ||
1077 | |||
1078 | lbs_deb_spi("Initializing FW for Marvell WLAN 802.11 adapter " | ||
1079 | "(chip_id = 0x%04x, chip_rev = 0x%02x) " | ||
1080 | "attached to SPI bus_num %d, chip_select %d. " | ||
1081 | "spi->max_speed_hz=%d\n", | ||
1082 | card->card_id, card->card_rev, | ||
1083 | spi->master->bus_num, spi->chip_select, | ||
1084 | spi->max_speed_hz); | ||
1085 | err = if_spi_prog_helper_firmware(card, helper); | ||
1086 | if (err) | ||
1087 | goto out; | ||
1088 | err = if_spi_prog_main_firmware(card, mainfw); | ||
1089 | if (err) | ||
1090 | goto out; | ||
1091 | lbs_deb_spi("loaded FW for Marvell WLAN 802.11 adapter\n"); | ||
896 | } | 1092 | } |
897 | if (i == ARRAY_SIZE(chip_id_to_device_name)) { | 1093 | |
898 | lbs_pr_err("Unsupported chip_id: 0x%02x\n", card_id); | 1094 | err = spu_set_interrupt_mode(card, 0, 1); |
899 | return -EAFNOSUPPORT; | 1095 | if (err) |
1096 | goto out; | ||
1097 | |||
1098 | out: | ||
1099 | if (helper) | ||
1100 | release_firmware(helper); | ||
1101 | if (mainfw) | ||
1102 | release_firmware(mainfw); | ||
1103 | |||
1104 | lbs_deb_leave_args(LBS_DEB_SPI, "err %d\n", err); | ||
1105 | |||
1106 | return err; | ||
1107 | } | ||
1108 | |||
1109 | static void if_spi_resume_worker(struct work_struct *work) | ||
1110 | { | ||
1111 | struct if_spi_card *card; | ||
1112 | |||
1113 | card = container_of(work, struct if_spi_card, resume_work); | ||
1114 | |||
1115 | if (card->suspended) { | ||
1116 | if (card->pdata->setup) | ||
1117 | card->pdata->setup(card->spi); | ||
1118 | |||
1119 | /* Init card ... */ | ||
1120 | if_spi_init_card(card); | ||
1121 | |||
1122 | enable_irq(card->spi->irq); | ||
1123 | |||
1124 | /* And resume it ... */ | ||
1125 | lbs_resume(card->priv); | ||
1126 | |||
1127 | card->suspended = 0; | ||
900 | } | 1128 | } |
901 | snprintf(helper_fw, IF_SPI_FW_NAME_MAX, "libertas/gspi%d_hlp.bin", | ||
902 | chip_id_to_device_name[i].name); | ||
903 | snprintf(main_fw, IF_SPI_FW_NAME_MAX, "libertas/gspi%d.bin", | ||
904 | chip_id_to_device_name[i].name); | ||
905 | return 0; | ||
906 | } | 1129 | } |
907 | MODULE_FIRMWARE("libertas/gspi8385_hlp.bin"); | ||
908 | MODULE_FIRMWARE("libertas/gspi8385.bin"); | ||
909 | MODULE_FIRMWARE("libertas/gspi8686_hlp.bin"); | ||
910 | MODULE_FIRMWARE("libertas/gspi8686.bin"); | ||
911 | 1130 | ||
912 | static int __devinit if_spi_probe(struct spi_device *spi) | 1131 | static int __devinit if_spi_probe(struct spi_device *spi) |
913 | { | 1132 | { |
@@ -915,8 +1134,6 @@ static int __devinit if_spi_probe(struct spi_device *spi) | |||
915 | struct lbs_private *priv = NULL; | 1134 | struct lbs_private *priv = NULL; |
916 | struct libertas_spi_platform_data *pdata = spi->dev.platform_data; | 1135 | struct libertas_spi_platform_data *pdata = spi->dev.platform_data; |
917 | int err = 0; | 1136 | int err = 0; |
918 | u32 scratch; | ||
919 | struct sched_param param = { .sched_priority = 1 }; | ||
920 | 1137 | ||
921 | lbs_deb_enter(LBS_DEB_SPI); | 1138 | lbs_deb_enter(LBS_DEB_SPI); |
922 | 1139 | ||
@@ -935,65 +1152,35 @@ static int __devinit if_spi_probe(struct spi_device *spi) | |||
935 | card = kzalloc(sizeof(struct if_spi_card), GFP_KERNEL); | 1152 | card = kzalloc(sizeof(struct if_spi_card), GFP_KERNEL); |
936 | if (!card) { | 1153 | if (!card) { |
937 | err = -ENOMEM; | 1154 | err = -ENOMEM; |
938 | goto out; | 1155 | goto teardown; |
939 | } | 1156 | } |
940 | spi_set_drvdata(spi, card); | 1157 | spi_set_drvdata(spi, card); |
941 | card->pdata = pdata; | 1158 | card->pdata = pdata; |
942 | card->spi = spi; | 1159 | card->spi = spi; |
943 | card->prev_xfer_time = jiffies; | 1160 | card->prev_xfer_time = jiffies; |
944 | 1161 | ||
945 | sema_init(&card->spi_ready, 0); | 1162 | INIT_LIST_HEAD(&card->cmd_packet_list); |
946 | sema_init(&card->spi_thread_terminated, 0); | 1163 | INIT_LIST_HEAD(&card->data_packet_list); |
1164 | spin_lock_init(&card->buffer_lock); | ||
947 | 1165 | ||
948 | /* Initialize the SPI Interface Unit */ | 1166 | /* Initialize the SPI Interface Unit */ |
949 | err = spu_init(card, pdata->use_dummy_writes); | ||
950 | if (err) | ||
951 | goto free_card; | ||
952 | err = spu_get_chip_revision(card, &card->card_id, &card->card_rev); | ||
953 | if (err) | ||
954 | goto free_card; | ||
955 | 1167 | ||
956 | /* Firmware load */ | 1168 | /* Firmware load */ |
957 | err = spu_read_u32(card, IF_SPI_SCRATCH_4_REG, &scratch); | 1169 | err = if_spi_init_card(card); |
958 | if (err) | 1170 | if (err) |
959 | goto free_card; | 1171 | goto free_card; |
960 | if (scratch == SUCCESSFUL_FW_DOWNLOAD_MAGIC) | ||
961 | lbs_deb_spi("Firmware is already loaded for " | ||
962 | "Marvell WLAN 802.11 adapter\n"); | ||
963 | else { | ||
964 | err = if_spi_calculate_fw_names(card->card_id, | ||
965 | card->helper_fw_name, card->main_fw_name); | ||
966 | if (err) | ||
967 | goto free_card; | ||
968 | 1172 | ||
969 | lbs_deb_spi("Initializing FW for Marvell WLAN 802.11 adapter " | 1173 | /* |
970 | "(chip_id = 0x%04x, chip_rev = 0x%02x) " | 1174 | * Register our card with libertas. |
971 | "attached to SPI bus_num %d, chip_select %d. " | 1175 | * This will call alloc_etherdev. |
972 | "spi->max_speed_hz=%d\n", | 1176 | */ |
973 | card->card_id, card->card_rev, | ||
974 | spi->master->bus_num, spi->chip_select, | ||
975 | spi->max_speed_hz); | ||
976 | err = if_spi_prog_helper_firmware(card); | ||
977 | if (err) | ||
978 | goto free_card; | ||
979 | err = if_spi_prog_main_firmware(card); | ||
980 | if (err) | ||
981 | goto free_card; | ||
982 | lbs_deb_spi("loaded FW for Marvell WLAN 802.11 adapter\n"); | ||
983 | } | ||
984 | |||
985 | err = spu_set_interrupt_mode(card, 0, 1); | ||
986 | if (err) | ||
987 | goto free_card; | ||
988 | |||
989 | /* Register our card with libertas. | ||
990 | * This will call alloc_etherdev */ | ||
991 | priv = lbs_add_card(card, &spi->dev); | 1177 | priv = lbs_add_card(card, &spi->dev); |
992 | if (!priv) { | 1178 | if (!priv) { |
993 | err = -ENOMEM; | 1179 | err = -ENOMEM; |
994 | goto free_card; | 1180 | goto free_card; |
995 | } | 1181 | } |
996 | card->priv = priv; | 1182 | card->priv = priv; |
1183 | priv->setup_fw_on_resume = 1; | ||
997 | priv->card = card; | 1184 | priv->card = card; |
998 | priv->hw_host_to_card = if_spi_host_to_card; | 1185 | priv->hw_host_to_card = if_spi_host_to_card; |
999 | priv->enter_deep_sleep = NULL; | 1186 | priv->enter_deep_sleep = NULL; |
@@ -1002,30 +1189,22 @@ static int __devinit if_spi_probe(struct spi_device *spi) | |||
1002 | priv->fw_ready = 1; | 1189 | priv->fw_ready = 1; |
1003 | 1190 | ||
1004 | /* Initialize interrupt handling stuff. */ | 1191 | /* Initialize interrupt handling stuff. */ |
1005 | card->run_thread = 1; | 1192 | card->workqueue = create_workqueue("libertas_spi"); |
1006 | card->spi_thread = kthread_run(lbs_spi_thread, card, "lbs_spi_thread"); | 1193 | INIT_WORK(&card->packet_work, if_spi_host_to_card_worker); |
1007 | if (IS_ERR(card->spi_thread)) { | 1194 | INIT_WORK(&card->resume_work, if_spi_resume_worker); |
1008 | card->run_thread = 0; | ||
1009 | err = PTR_ERR(card->spi_thread); | ||
1010 | lbs_pr_err("error creating SPI thread: err=%d\n", err); | ||
1011 | goto remove_card; | ||
1012 | } | ||
1013 | if (sched_setscheduler(card->spi_thread, SCHED_FIFO, ¶m)) | ||
1014 | lbs_pr_err("Error setting scheduler, using default.\n"); | ||
1015 | 1195 | ||
1016 | err = request_irq(spi->irq, if_spi_host_interrupt, | 1196 | err = request_irq(spi->irq, if_spi_host_interrupt, |
1017 | IRQF_TRIGGER_FALLING, "libertas_spi", card); | 1197 | IRQF_TRIGGER_FALLING, "libertas_spi", card); |
1018 | if (err) { | 1198 | if (err) { |
1019 | lbs_pr_err("can't get host irq line-- request_irq failed\n"); | 1199 | pr_err("can't get host irq line-- request_irq failed\n"); |
1020 | goto terminate_thread; | 1200 | goto terminate_workqueue; |
1021 | } | 1201 | } |
1022 | 1202 | ||
1023 | /* poke the IRQ handler so that we don't miss the first interrupt */ | 1203 | /* |
1024 | up(&card->spi_ready); | 1204 | * Start the card. |
1025 | |||
1026 | /* Start the card. | ||
1027 | * This will call register_netdev, and we'll start | 1205 | * This will call register_netdev, and we'll start |
1028 | * getting interrupts... */ | 1206 | * getting interrupts... |
1207 | */ | ||
1029 | err = lbs_start_card(priv); | 1208 | err = lbs_start_card(priv); |
1030 | if (err) | 1209 | if (err) |
1031 | goto release_irq; | 1210 | goto release_irq; |
@@ -1037,12 +1216,15 @@ static int __devinit if_spi_probe(struct spi_device *spi) | |||
1037 | 1216 | ||
1038 | release_irq: | 1217 | release_irq: |
1039 | free_irq(spi->irq, card); | 1218 | free_irq(spi->irq, card); |
1040 | terminate_thread: | 1219 | terminate_workqueue: |
1041 | if_spi_terminate_spi_thread(card); | 1220 | flush_workqueue(card->workqueue); |
1042 | remove_card: | 1221 | destroy_workqueue(card->workqueue); |
1043 | lbs_remove_card(priv); /* will call free_netdev */ | 1222 | lbs_remove_card(priv); /* will call free_netdev */ |
1044 | free_card: | 1223 | free_card: |
1045 | free_if_spi_card(card); | 1224 | free_if_spi_card(card); |
1225 | teardown: | ||
1226 | if (pdata->teardown) | ||
1227 | pdata->teardown(spi); | ||
1046 | out: | 1228 | out: |
1047 | lbs_deb_leave_args(LBS_DEB_SPI, "err %d\n", err); | 1229 | lbs_deb_leave_args(LBS_DEB_SPI, "err %d\n", err); |
1048 | return err; | 1230 | return err; |
@@ -1056,12 +1238,14 @@ static int __devexit libertas_spi_remove(struct spi_device *spi) | |||
1056 | lbs_deb_spi("libertas_spi_remove\n"); | 1238 | lbs_deb_spi("libertas_spi_remove\n"); |
1057 | lbs_deb_enter(LBS_DEB_SPI); | 1239 | lbs_deb_enter(LBS_DEB_SPI); |
1058 | 1240 | ||
1241 | cancel_work_sync(&card->resume_work); | ||
1242 | |||
1059 | lbs_stop_card(priv); | 1243 | lbs_stop_card(priv); |
1060 | lbs_remove_card(priv); /* will call free_netdev */ | 1244 | lbs_remove_card(priv); /* will call free_netdev */ |
1061 | 1245 | ||
1062 | priv->surpriseremoved = 1; | ||
1063 | free_irq(spi->irq, card); | 1246 | free_irq(spi->irq, card); |
1064 | if_spi_terminate_spi_thread(card); | 1247 | flush_workqueue(card->workqueue); |
1248 | destroy_workqueue(card->workqueue); | ||
1065 | if (card->pdata->teardown) | 1249 | if (card->pdata->teardown) |
1066 | card->pdata->teardown(spi); | 1250 | card->pdata->teardown(spi); |
1067 | free_if_spi_card(card); | 1251 | free_if_spi_card(card); |
@@ -1069,6 +1253,40 @@ static int __devexit libertas_spi_remove(struct spi_device *spi) | |||
1069 | return 0; | 1253 | return 0; |
1070 | } | 1254 | } |
1071 | 1255 | ||
1256 | static int if_spi_suspend(struct device *dev) | ||
1257 | { | ||
1258 | struct spi_device *spi = to_spi_device(dev); | ||
1259 | struct if_spi_card *card = spi_get_drvdata(spi); | ||
1260 | |||
1261 | if (!card->suspended) { | ||
1262 | lbs_suspend(card->priv); | ||
1263 | flush_workqueue(card->workqueue); | ||
1264 | disable_irq(spi->irq); | ||
1265 | |||
1266 | if (card->pdata->teardown) | ||
1267 | card->pdata->teardown(spi); | ||
1268 | card->suspended = 1; | ||
1269 | } | ||
1270 | |||
1271 | return 0; | ||
1272 | } | ||
1273 | |||
1274 | static int if_spi_resume(struct device *dev) | ||
1275 | { | ||
1276 | struct spi_device *spi = to_spi_device(dev); | ||
1277 | struct if_spi_card *card = spi_get_drvdata(spi); | ||
1278 | |||
1279 | /* Schedule delayed work */ | ||
1280 | schedule_work(&card->resume_work); | ||
1281 | |||
1282 | return 0; | ||
1283 | } | ||
1284 | |||
1285 | static const struct dev_pm_ops if_spi_pm_ops = { | ||
1286 | .suspend = if_spi_suspend, | ||
1287 | .resume = if_spi_resume, | ||
1288 | }; | ||
1289 | |||
1072 | static struct spi_driver libertas_spi_driver = { | 1290 | static struct spi_driver libertas_spi_driver = { |
1073 | .probe = if_spi_probe, | 1291 | .probe = if_spi_probe, |
1074 | .remove = __devexit_p(libertas_spi_remove), | 1292 | .remove = __devexit_p(libertas_spi_remove), |
@@ -1076,6 +1294,7 @@ static struct spi_driver libertas_spi_driver = { | |||
1076 | .name = "libertas_spi", | 1294 | .name = "libertas_spi", |
1077 | .bus = &spi_bus_type, | 1295 | .bus = &spi_bus_type, |
1078 | .owner = THIS_MODULE, | 1296 | .owner = THIS_MODULE, |
1297 | .pm = &if_spi_pm_ops, | ||
1079 | }, | 1298 | }, |
1080 | }; | 1299 | }; |
1081 | 1300 | ||