diff options
Diffstat (limited to 'drivers/net/wireless/libertas/if_usb.c')
-rw-r--r-- | drivers/net/wireless/libertas/if_usb.c | 232 |
1 files changed, 147 insertions, 85 deletions
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index 3ff61063671a..b5acc393a65a 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c | |||
@@ -1,6 +1,9 @@ | |||
1 | /** | 1 | /* |
2 | * This file contains functions used in USB interface module. | 2 | * This file contains functions used in USB interface module. |
3 | */ | 3 | */ |
4 | |||
5 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
6 | |||
4 | #include <linux/delay.h> | 7 | #include <linux/delay.h> |
5 | #include <linux/moduleparam.h> | 8 | #include <linux/moduleparam.h> |
6 | #include <linux/firmware.h> | 9 | #include <linux/firmware.h> |
@@ -26,15 +29,25 @@ | |||
26 | 29 | ||
27 | #define MESSAGE_HEADER_LEN 4 | 30 | #define MESSAGE_HEADER_LEN 4 |
28 | 31 | ||
29 | static char *lbs_fw_name = "usb8388.bin"; | 32 | static char *lbs_fw_name = NULL; |
30 | module_param_named(fw_name, lbs_fw_name, charp, 0644); | 33 | module_param_named(fw_name, lbs_fw_name, charp, 0644); |
31 | 34 | ||
35 | MODULE_FIRMWARE("libertas/usb8388_v9.bin"); | ||
36 | MODULE_FIRMWARE("libertas/usb8388_v5.bin"); | ||
37 | MODULE_FIRMWARE("libertas/usb8388.bin"); | ||
38 | MODULE_FIRMWARE("libertas/usb8682.bin"); | ||
32 | MODULE_FIRMWARE("usb8388.bin"); | 39 | MODULE_FIRMWARE("usb8388.bin"); |
33 | 40 | ||
41 | enum { | ||
42 | MODEL_UNKNOWN = 0x0, | ||
43 | MODEL_8388 = 0x1, | ||
44 | MODEL_8682 = 0x2 | ||
45 | }; | ||
46 | |||
34 | static struct usb_device_id if_usb_table[] = { | 47 | static struct usb_device_id if_usb_table[] = { |
35 | /* Enter the device signature inside */ | 48 | /* Enter the device signature inside */ |
36 | { USB_DEVICE(0x1286, 0x2001) }, | 49 | { USB_DEVICE(0x1286, 0x2001), .driver_info = MODEL_8388 }, |
37 | { USB_DEVICE(0x05a3, 0x8388) }, | 50 | { USB_DEVICE(0x05a3, 0x8388), .driver_info = MODEL_8388 }, |
38 | {} /* Terminating entry */ | 51 | {} /* Terminating entry */ |
39 | }; | 52 | }; |
40 | 53 | ||
@@ -56,7 +69,7 @@ static int if_usb_reset_device(struct if_usb_card *cardp); | |||
56 | 69 | ||
57 | /* sysfs hooks */ | 70 | /* sysfs hooks */ |
58 | 71 | ||
59 | /** | 72 | /* |
60 | * Set function to write firmware to device's persistent memory | 73 | * Set function to write firmware to device's persistent memory |
61 | */ | 74 | */ |
62 | static ssize_t if_usb_firmware_set(struct device *dev, | 75 | static ssize_t if_usb_firmware_set(struct device *dev, |
@@ -66,6 +79,8 @@ static ssize_t if_usb_firmware_set(struct device *dev, | |||
66 | struct if_usb_card *cardp = priv->card; | 79 | struct if_usb_card *cardp = priv->card; |
67 | int ret; | 80 | int ret; |
68 | 81 | ||
82 | BUG_ON(buf == NULL); | ||
83 | |||
69 | ret = if_usb_prog_firmware(cardp, buf, BOOT_CMD_UPDATE_FW); | 84 | ret = if_usb_prog_firmware(cardp, buf, BOOT_CMD_UPDATE_FW); |
70 | if (ret == 0) | 85 | if (ret == 0) |
71 | return count; | 86 | return count; |
@@ -73,7 +88,7 @@ static ssize_t if_usb_firmware_set(struct device *dev, | |||
73 | return ret; | 88 | return ret; |
74 | } | 89 | } |
75 | 90 | ||
76 | /** | 91 | /* |
77 | * lbs_flash_fw attribute to be exported per ethX interface through sysfs | 92 | * lbs_flash_fw attribute to be exported per ethX interface through sysfs |
78 | * (/sys/class/net/ethX/lbs_flash_fw). Use this like so to write firmware to | 93 | * (/sys/class/net/ethX/lbs_flash_fw). Use this like so to write firmware to |
79 | * the device's persistent memory: | 94 | * the device's persistent memory: |
@@ -82,7 +97,14 @@ static ssize_t if_usb_firmware_set(struct device *dev, | |||
82 | static DEVICE_ATTR(lbs_flash_fw, 0200, NULL, if_usb_firmware_set); | 97 | static DEVICE_ATTR(lbs_flash_fw, 0200, NULL, if_usb_firmware_set); |
83 | 98 | ||
84 | /** | 99 | /** |
85 | * Set function to write firmware to device's persistent memory | 100 | * if_usb_boot2_set - write firmware to device's persistent memory |
101 | * | ||
102 | * @dev: target device | ||
103 | * @attr: device attributes | ||
104 | * @buf: firmware buffer to write | ||
105 | * @count: number of bytes to write | ||
106 | * | ||
107 | * returns: number of bytes written or negative error code | ||
86 | */ | 108 | */ |
87 | static ssize_t if_usb_boot2_set(struct device *dev, | 109 | static ssize_t if_usb_boot2_set(struct device *dev, |
88 | struct device_attribute *attr, const char *buf, size_t count) | 110 | struct device_attribute *attr, const char *buf, size_t count) |
@@ -91,6 +113,8 @@ static ssize_t if_usb_boot2_set(struct device *dev, | |||
91 | struct if_usb_card *cardp = priv->card; | 113 | struct if_usb_card *cardp = priv->card; |
92 | int ret; | 114 | int ret; |
93 | 115 | ||
116 | BUG_ON(buf == NULL); | ||
117 | |||
94 | ret = if_usb_prog_firmware(cardp, buf, BOOT_CMD_UPDATE_BOOT2); | 118 | ret = if_usb_prog_firmware(cardp, buf, BOOT_CMD_UPDATE_BOOT2); |
95 | if (ret == 0) | 119 | if (ret == 0) |
96 | return count; | 120 | return count; |
@@ -98,7 +122,7 @@ static ssize_t if_usb_boot2_set(struct device *dev, | |||
98 | return ret; | 122 | return ret; |
99 | } | 123 | } |
100 | 124 | ||
101 | /** | 125 | /* |
102 | * lbs_flash_boot2 attribute to be exported per ethX interface through sysfs | 126 | * lbs_flash_boot2 attribute to be exported per ethX interface through sysfs |
103 | * (/sys/class/net/ethX/lbs_flash_boot2). Use this like so to write firmware | 127 | * (/sys/class/net/ethX/lbs_flash_boot2). Use this like so to write firmware |
104 | * to the device's persistent memory: | 128 | * to the device's persistent memory: |
@@ -107,9 +131,10 @@ static ssize_t if_usb_boot2_set(struct device *dev, | |||
107 | static DEVICE_ATTR(lbs_flash_boot2, 0200, NULL, if_usb_boot2_set); | 131 | static DEVICE_ATTR(lbs_flash_boot2, 0200, NULL, if_usb_boot2_set); |
108 | 132 | ||
109 | /** | 133 | /** |
110 | * @brief call back function to handle the status of the URB | 134 | * if_usb_write_bulk_callback - callback function to handle the status |
111 | * @param urb pointer to urb structure | 135 | * of the URB |
112 | * @return N/A | 136 | * @urb: pointer to &urb structure |
137 | * returns: N/A | ||
113 | */ | 138 | */ |
114 | static void if_usb_write_bulk_callback(struct urb *urb) | 139 | static void if_usb_write_bulk_callback(struct urb *urb) |
115 | { | 140 | { |
@@ -131,14 +156,14 @@ static void if_usb_write_bulk_callback(struct urb *urb) | |||
131 | lbs_host_to_card_done(priv); | 156 | lbs_host_to_card_done(priv); |
132 | } else { | 157 | } else { |
133 | /* print the failure status number for debug */ | 158 | /* print the failure status number for debug */ |
134 | lbs_pr_info("URB in failure status: %d\n", urb->status); | 159 | pr_info("URB in failure status: %d\n", urb->status); |
135 | } | 160 | } |
136 | } | 161 | } |
137 | 162 | ||
138 | /** | 163 | /** |
139 | * @brief free tx/rx urb, skb and rx buffer | 164 | * if_usb_free - free tx/rx urb, skb and rx buffer |
140 | * @param cardp pointer if_usb_card | 165 | * @cardp: pointer to &if_usb_card |
141 | * @return N/A | 166 | * returns: N/A |
142 | */ | 167 | */ |
143 | static void if_usb_free(struct if_usb_card *cardp) | 168 | static void if_usb_free(struct if_usb_card *cardp) |
144 | { | 169 | { |
@@ -181,7 +206,7 @@ static void if_usb_setup_firmware(struct lbs_private *priv) | |||
181 | wake_method.hdr.size = cpu_to_le16(sizeof(wake_method)); | 206 | wake_method.hdr.size = cpu_to_le16(sizeof(wake_method)); |
182 | wake_method.action = cpu_to_le16(CMD_ACT_GET); | 207 | wake_method.action = cpu_to_le16(CMD_ACT_GET); |
183 | if (lbs_cmd_with_response(priv, CMD_802_11_FW_WAKE_METHOD, &wake_method)) { | 208 | if (lbs_cmd_with_response(priv, CMD_802_11_FW_WAKE_METHOD, &wake_method)) { |
184 | lbs_pr_info("Firmware does not seem to support PS mode\n"); | 209 | netdev_info(priv->dev, "Firmware does not seem to support PS mode\n"); |
185 | priv->fwcapinfo &= ~FW_CAPINFO_PS; | 210 | priv->fwcapinfo &= ~FW_CAPINFO_PS; |
186 | } else { | 211 | } else { |
187 | if (le16_to_cpu(wake_method.method) == CMD_WAKE_METHOD_COMMAND_INT) { | 212 | if (le16_to_cpu(wake_method.method) == CMD_WAKE_METHOD_COMMAND_INT) { |
@@ -190,7 +215,8 @@ static void if_usb_setup_firmware(struct lbs_private *priv) | |||
190 | /* The versions which boot up this way don't seem to | 215 | /* The versions which boot up this way don't seem to |
191 | work even if we set it to the command interrupt */ | 216 | work even if we set it to the command interrupt */ |
192 | priv->fwcapinfo &= ~FW_CAPINFO_PS; | 217 | priv->fwcapinfo &= ~FW_CAPINFO_PS; |
193 | lbs_pr_info("Firmware doesn't wake via command interrupt; disabling PS mode\n"); | 218 | netdev_info(priv->dev, |
219 | "Firmware doesn't wake via command interrupt; disabling PS mode\n"); | ||
194 | } | 220 | } |
195 | } | 221 | } |
196 | } | 222 | } |
@@ -202,7 +228,7 @@ static void if_usb_fw_timeo(unsigned long priv) | |||
202 | if (cardp->fwdnldover) { | 228 | if (cardp->fwdnldover) { |
203 | lbs_deb_usb("Download complete, no event. Assuming success\n"); | 229 | lbs_deb_usb("Download complete, no event. Assuming success\n"); |
204 | } else { | 230 | } else { |
205 | lbs_pr_err("Download timed out\n"); | 231 | pr_err("Download timed out\n"); |
206 | cardp->surprise_removed = 1; | 232 | cardp->surprise_removed = 1; |
207 | } | 233 | } |
208 | wake_up(&cardp->fw_wq); | 234 | wake_up(&cardp->fw_wq); |
@@ -217,10 +243,10 @@ static void if_usb_reset_olpc_card(struct lbs_private *priv) | |||
217 | #endif | 243 | #endif |
218 | 244 | ||
219 | /** | 245 | /** |
220 | * @brief sets the configuration values | 246 | * if_usb_probe - sets the configuration values |
221 | * @param ifnum interface number | 247 | * @intf: &usb_interface pointer |
222 | * @param id pointer to usb_device_id | 248 | * @id: pointer to usb_device_id |
223 | * @return 0 on success, error code on failure | 249 | * returns: 0 on success, error code on failure |
224 | */ | 250 | */ |
225 | static int if_usb_probe(struct usb_interface *intf, | 251 | static int if_usb_probe(struct usb_interface *intf, |
226 | const struct usb_device_id *id) | 252 | const struct usb_device_id *id) |
@@ -236,7 +262,7 @@ static int if_usb_probe(struct usb_interface *intf, | |||
236 | 262 | ||
237 | cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL); | 263 | cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL); |
238 | if (!cardp) { | 264 | if (!cardp) { |
239 | lbs_pr_err("Out of memory allocating private data.\n"); | 265 | pr_err("Out of memory allocating private data\n"); |
240 | goto error; | 266 | goto error; |
241 | } | 267 | } |
242 | 268 | ||
@@ -244,6 +270,7 @@ static int if_usb_probe(struct usb_interface *intf, | |||
244 | init_waitqueue_head(&cardp->fw_wq); | 270 | init_waitqueue_head(&cardp->fw_wq); |
245 | 271 | ||
246 | cardp->udev = udev; | 272 | cardp->udev = udev; |
273 | cardp->model = (uint32_t) id->driver_info; | ||
247 | iface_desc = intf->cur_altsetting; | 274 | iface_desc = intf->cur_altsetting; |
248 | 275 | ||
249 | lbs_deb_usbd(&udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X" | 276 | lbs_deb_usbd(&udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X" |
@@ -325,10 +352,19 @@ static int if_usb_probe(struct usb_interface *intf, | |||
325 | usb_set_intfdata(intf, cardp); | 352 | usb_set_intfdata(intf, cardp); |
326 | 353 | ||
327 | if (device_create_file(&priv->dev->dev, &dev_attr_lbs_flash_fw)) | 354 | if (device_create_file(&priv->dev->dev, &dev_attr_lbs_flash_fw)) |
328 | lbs_pr_err("cannot register lbs_flash_fw attribute\n"); | 355 | netdev_err(priv->dev, |
356 | "cannot register lbs_flash_fw attribute\n"); | ||
329 | 357 | ||
330 | if (device_create_file(&priv->dev->dev, &dev_attr_lbs_flash_boot2)) | 358 | if (device_create_file(&priv->dev->dev, &dev_attr_lbs_flash_boot2)) |
331 | lbs_pr_err("cannot register lbs_flash_boot2 attribute\n"); | 359 | netdev_err(priv->dev, |
360 | "cannot register lbs_flash_boot2 attribute\n"); | ||
361 | |||
362 | /* | ||
363 | * EHS_REMOVE_WAKEUP is not supported on all versions of the firmware. | ||
364 | */ | ||
365 | priv->wol_criteria = EHS_REMOVE_WAKEUP; | ||
366 | if (lbs_host_sleep_cfg(priv, priv->wol_criteria, NULL)) | ||
367 | priv->ehs_remove_supported = false; | ||
332 | 368 | ||
333 | return 0; | 369 | return 0; |
334 | 370 | ||
@@ -344,9 +380,9 @@ error: | |||
344 | } | 380 | } |
345 | 381 | ||
346 | /** | 382 | /** |
347 | * @brief free resource and cleanup | 383 | * if_usb_disconnect - free resource and cleanup |
348 | * @param intf USB interface structure | 384 | * @intf: USB interface structure |
349 | * @return N/A | 385 | * returns: N/A |
350 | */ | 386 | */ |
351 | static void if_usb_disconnect(struct usb_interface *intf) | 387 | static void if_usb_disconnect(struct usb_interface *intf) |
352 | { | 388 | { |
@@ -376,9 +412,9 @@ static void if_usb_disconnect(struct usb_interface *intf) | |||
376 | } | 412 | } |
377 | 413 | ||
378 | /** | 414 | /** |
379 | * @brief This function download FW | 415 | * if_usb_send_fw_pkt - download FW |
380 | * @param priv pointer to struct lbs_private | 416 | * @cardp: pointer to &struct if_usb_card |
381 | * @return 0 | 417 | * returns: 0 |
382 | */ | 418 | */ |
383 | static int if_usb_send_fw_pkt(struct if_usb_card *cardp) | 419 | static int if_usb_send_fw_pkt(struct if_usb_card *cardp) |
384 | { | 420 | { |
@@ -464,19 +500,20 @@ static int if_usb_reset_device(struct if_usb_card *cardp) | |||
464 | } | 500 | } |
465 | 501 | ||
466 | /** | 502 | /** |
467 | * @brief This function transfer the data to the device. | 503 | * usb_tx_block - transfer the data to the device |
468 | * @param priv pointer to struct lbs_private | 504 | * @cardp: pointer to &struct if_usb_card |
469 | * @param payload pointer to payload data | 505 | * @payload: pointer to payload data |
470 | * @param nb data length | 506 | * @nb: data length |
471 | * @return 0 or -1 | 507 | * returns: 0 for success or negative error code |
472 | */ | 508 | */ |
473 | static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb) | 509 | static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb) |
474 | { | 510 | { |
475 | int ret = -1; | 511 | int ret; |
476 | 512 | ||
477 | /* check if device is removed */ | 513 | /* check if device is removed */ |
478 | if (cardp->surprise_removed) { | 514 | if (cardp->surprise_removed) { |
479 | lbs_deb_usbd(&cardp->udev->dev, "Device removed\n"); | 515 | lbs_deb_usbd(&cardp->udev->dev, "Device removed\n"); |
516 | ret = -ENODEV; | ||
480 | goto tx_ret; | 517 | goto tx_ret; |
481 | } | 518 | } |
482 | 519 | ||
@@ -489,7 +526,6 @@ static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb | |||
489 | 526 | ||
490 | if ((ret = usb_submit_urb(cardp->tx_urb, GFP_ATOMIC))) { | 527 | if ((ret = usb_submit_urb(cardp->tx_urb, GFP_ATOMIC))) { |
491 | lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed: %d\n", ret); | 528 | lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed: %d\n", ret); |
492 | ret = -1; | ||
493 | } else { | 529 | } else { |
494 | lbs_deb_usb2(&cardp->udev->dev, "usb_submit_urb success\n"); | 530 | lbs_deb_usb2(&cardp->udev->dev, "usb_submit_urb success\n"); |
495 | ret = 0; | 531 | ret = 0; |
@@ -506,7 +542,7 @@ static int __if_usb_submit_rx_urb(struct if_usb_card *cardp, | |||
506 | int ret = -1; | 542 | int ret = -1; |
507 | 543 | ||
508 | if (!(skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE))) { | 544 | if (!(skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE))) { |
509 | lbs_pr_err("No free skb\n"); | 545 | pr_err("No free skb\n"); |
510 | goto rx_ret; | 546 | goto rx_ret; |
511 | } | 547 | } |
512 | 548 | ||
@@ -565,7 +601,7 @@ static void if_usb_receive_fwload(struct urb *urb) | |||
565 | 601 | ||
566 | if (tmp[0] == cpu_to_le32(CMD_TYPE_INDICATION) && | 602 | if (tmp[0] == cpu_to_le32(CMD_TYPE_INDICATION) && |
567 | tmp[1] == cpu_to_le32(MACREG_INT_CODE_FIRMWARE_READY)) { | 603 | tmp[1] == cpu_to_le32(MACREG_INT_CODE_FIRMWARE_READY)) { |
568 | lbs_pr_info("Firmware ready event received\n"); | 604 | pr_info("Firmware ready event received\n"); |
569 | wake_up(&cardp->fw_wq); | 605 | wake_up(&cardp->fw_wq); |
570 | } else { | 606 | } else { |
571 | lbs_deb_usb("Waiting for confirmation; got %x %x\n", | 607 | lbs_deb_usb("Waiting for confirmation; got %x %x\n", |
@@ -592,20 +628,20 @@ static void if_usb_receive_fwload(struct urb *urb) | |||
592 | bootcmdresp.magic == cpu_to_le32(CMD_TYPE_DATA) || | 628 | bootcmdresp.magic == cpu_to_le32(CMD_TYPE_DATA) || |
593 | bootcmdresp.magic == cpu_to_le32(CMD_TYPE_INDICATION)) { | 629 | bootcmdresp.magic == cpu_to_le32(CMD_TYPE_INDICATION)) { |
594 | if (!cardp->bootcmdresp) | 630 | if (!cardp->bootcmdresp) |
595 | lbs_pr_info("Firmware already seems alive; resetting\n"); | 631 | pr_info("Firmware already seems alive; resetting\n"); |
596 | cardp->bootcmdresp = -1; | 632 | cardp->bootcmdresp = -1; |
597 | } else { | 633 | } else { |
598 | lbs_pr_info("boot cmd response wrong magic number (0x%x)\n", | 634 | pr_info("boot cmd response wrong magic number (0x%x)\n", |
599 | le32_to_cpu(bootcmdresp.magic)); | 635 | le32_to_cpu(bootcmdresp.magic)); |
600 | } | 636 | } |
601 | } else if ((bootcmdresp.cmd != BOOT_CMD_FW_BY_USB) && | 637 | } else if ((bootcmdresp.cmd != BOOT_CMD_FW_BY_USB) && |
602 | (bootcmdresp.cmd != BOOT_CMD_UPDATE_FW) && | 638 | (bootcmdresp.cmd != BOOT_CMD_UPDATE_FW) && |
603 | (bootcmdresp.cmd != BOOT_CMD_UPDATE_BOOT2)) { | 639 | (bootcmdresp.cmd != BOOT_CMD_UPDATE_BOOT2)) { |
604 | lbs_pr_info("boot cmd response cmd_tag error (%d)\n", | 640 | pr_info("boot cmd response cmd_tag error (%d)\n", |
605 | bootcmdresp.cmd); | 641 | bootcmdresp.cmd); |
606 | } else if (bootcmdresp.result != BOOT_CMD_RESP_OK) { | 642 | } else if (bootcmdresp.result != BOOT_CMD_RESP_OK) { |
607 | lbs_pr_info("boot cmd response result error (%d)\n", | 643 | pr_info("boot cmd response result error (%d)\n", |
608 | bootcmdresp.result); | 644 | bootcmdresp.result); |
609 | } else { | 645 | } else { |
610 | cardp->bootcmdresp = 1; | 646 | cardp->bootcmdresp = 1; |
611 | lbs_deb_usbd(&cardp->udev->dev, | 647 | lbs_deb_usbd(&cardp->udev->dev, |
@@ -705,11 +741,11 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff, | |||
705 | } | 741 | } |
706 | 742 | ||
707 | /** | 743 | /** |
708 | * @brief This function reads of the packet into the upload buff, | 744 | * if_usb_receive - read the packet into the upload buffer, |
709 | * wake up the main thread and initialise the Rx callack. | 745 | * wake up the main thread and initialise the Rx callack |
710 | * | 746 | * |
711 | * @param urb pointer to struct urb | 747 | * @urb: pointer to &struct urb |
712 | * @return N/A | 748 | * returns: N/A |
713 | */ | 749 | */ |
714 | static void if_usb_receive(struct urb *urb) | 750 | static void if_usb_receive(struct urb *urb) |
715 | { | 751 | { |
@@ -780,12 +816,12 @@ rx_exit: | |||
780 | } | 816 | } |
781 | 817 | ||
782 | /** | 818 | /** |
783 | * @brief This function downloads data to FW | 819 | * if_usb_host_to_card - downloads data to FW |
784 | * @param priv pointer to struct lbs_private structure | 820 | * @priv: pointer to &struct lbs_private structure |
785 | * @param type type of data | 821 | * @type: type of data |
786 | * @param buf pointer to data buffer | 822 | * @payload: pointer to data buffer |
787 | * @param len number of bytes | 823 | * @nb: number of bytes |
788 | * @return 0 or -1 | 824 | * returns: 0 for success or negative error code |
789 | */ | 825 | */ |
790 | static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type, | 826 | static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type, |
791 | uint8_t *payload, uint16_t nb) | 827 | uint8_t *payload, uint16_t nb) |
@@ -809,10 +845,11 @@ static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type, | |||
809 | } | 845 | } |
810 | 846 | ||
811 | /** | 847 | /** |
812 | * @brief This function issues Boot command to the Boot2 code | 848 | * if_usb_issue_boot_command - issues Boot command to the Boot2 code |
813 | * @param ivalue 1:Boot from FW by USB-Download | 849 | * @cardp: pointer to &if_usb_card |
814 | * 2:Boot from FW in EEPROM | 850 | * @ivalue: 1:Boot from FW by USB-Download |
815 | * @return 0 | 851 | * 2:Boot from FW in EEPROM |
852 | * returns: 0 for success or negative error code | ||
816 | */ | 853 | */ |
817 | static int if_usb_issue_boot_command(struct if_usb_card *cardp, int ivalue) | 854 | static int if_usb_issue_boot_command(struct if_usb_card *cardp, int ivalue) |
818 | { | 855 | { |
@@ -831,11 +868,11 @@ static int if_usb_issue_boot_command(struct if_usb_card *cardp, int ivalue) | |||
831 | 868 | ||
832 | 869 | ||
833 | /** | 870 | /** |
834 | * @brief This function checks the validity of Boot2/FW image. | 871 | * check_fwfile_format - check the validity of Boot2/FW image |
835 | * | 872 | * |
836 | * @param data pointer to image | 873 | * @data: pointer to image |
837 | * len image length | 874 | * @totlen: image length |
838 | * @return 0 or -1 | 875 | * returns: 0 (good) or 1 (failure) |
839 | */ | 876 | */ |
840 | static int check_fwfile_format(const uint8_t *data, uint32_t totlen) | 877 | static int check_fwfile_format(const uint8_t *data, uint32_t totlen) |
841 | { | 878 | { |
@@ -870,7 +907,7 @@ static int check_fwfile_format(const uint8_t *data, uint32_t totlen) | |||
870 | } while (!exit); | 907 | } while (!exit); |
871 | 908 | ||
872 | if (ret) | 909 | if (ret) |
873 | lbs_pr_err("firmware file format check FAIL\n"); | 910 | pr_err("firmware file format check FAIL\n"); |
874 | else | 911 | else |
875 | lbs_deb_fw("firmware file format check PASS\n"); | 912 | lbs_deb_fw("firmware file format check PASS\n"); |
876 | 913 | ||
@@ -879,13 +916,13 @@ static int check_fwfile_format(const uint8_t *data, uint32_t totlen) | |||
879 | 916 | ||
880 | 917 | ||
881 | /** | 918 | /** |
882 | * @brief This function programs the firmware subject to cmd | 919 | * if_usb_prog_firmware - programs the firmware subject to cmd |
883 | * | 920 | * |
884 | * @param cardp the if_usb_card descriptor | 921 | * @cardp: the if_usb_card descriptor |
885 | * fwname firmware or boot2 image file name | 922 | * @fwname: firmware or boot2 image file name |
886 | * cmd either BOOT_CMD_FW_BY_USB, BOOT_CMD_UPDATE_FW, | 923 | * @cmd: either BOOT_CMD_FW_BY_USB, BOOT_CMD_UPDATE_FW, |
887 | * or BOOT_CMD_UPDATE_BOOT2. | 924 | * or BOOT_CMD_UPDATE_BOOT2. |
888 | * @return 0 or error code | 925 | * returns: 0 or error code |
889 | */ | 926 | */ |
890 | static int if_usb_prog_firmware(struct if_usb_card *cardp, | 927 | static int if_usb_prog_firmware(struct if_usb_card *cardp, |
891 | const char *fwname, int cmd) | 928 | const char *fwname, int cmd) |
@@ -924,6 +961,38 @@ static int if_usb_prog_firmware(struct if_usb_card *cardp, | |||
924 | return ret; | 961 | return ret; |
925 | } | 962 | } |
926 | 963 | ||
964 | /* table of firmware file names */ | ||
965 | static const struct { | ||
966 | u32 model; | ||
967 | const char *fwname; | ||
968 | } fw_table[] = { | ||
969 | { MODEL_8388, "libertas/usb8388_v9.bin" }, | ||
970 | { MODEL_8388, "libertas/usb8388_v5.bin" }, | ||
971 | { MODEL_8388, "libertas/usb8388.bin" }, | ||
972 | { MODEL_8388, "usb8388.bin" }, | ||
973 | { MODEL_8682, "libertas/usb8682.bin" } | ||
974 | }; | ||
975 | |||
976 | static int get_fw(struct if_usb_card *cardp, const char *fwname) | ||
977 | { | ||
978 | int i; | ||
979 | |||
980 | /* Try user-specified firmware first */ | ||
981 | if (fwname) | ||
982 | return request_firmware(&cardp->fw, fwname, &cardp->udev->dev); | ||
983 | |||
984 | /* Otherwise search for firmware to use */ | ||
985 | for (i = 0; i < ARRAY_SIZE(fw_table); i++) { | ||
986 | if (fw_table[i].model != cardp->model) | ||
987 | continue; | ||
988 | if (request_firmware(&cardp->fw, fw_table[i].fwname, | ||
989 | &cardp->udev->dev) == 0) | ||
990 | return 0; | ||
991 | } | ||
992 | |||
993 | return -ENOENT; | ||
994 | } | ||
995 | |||
927 | static int __if_usb_prog_firmware(struct if_usb_card *cardp, | 996 | static int __if_usb_prog_firmware(struct if_usb_card *cardp, |
928 | const char *fwname, int cmd) | 997 | const char *fwname, int cmd) |
929 | { | 998 | { |
@@ -933,10 +1002,9 @@ static int __if_usb_prog_firmware(struct if_usb_card *cardp, | |||
933 | 1002 | ||
934 | lbs_deb_enter(LBS_DEB_USB); | 1003 | lbs_deb_enter(LBS_DEB_USB); |
935 | 1004 | ||
936 | ret = request_firmware(&cardp->fw, fwname, &cardp->udev->dev); | 1005 | ret = get_fw(cardp, fwname); |
937 | if (ret < 0) { | 1006 | if (ret) { |
938 | lbs_pr_err("request_firmware() failed with %#x\n", ret); | 1007 | pr_err("failed to find firmware (%d)\n", ret); |
939 | lbs_pr_err("firmware %s not found\n", fwname); | ||
940 | goto done; | 1008 | goto done; |
941 | } | 1009 | } |
942 | 1010 | ||
@@ -1011,13 +1079,13 @@ restart: | |||
1011 | usb_kill_urb(cardp->rx_urb); | 1079 | usb_kill_urb(cardp->rx_urb); |
1012 | 1080 | ||
1013 | if (!cardp->fwdnldover) { | 1081 | if (!cardp->fwdnldover) { |
1014 | lbs_pr_info("failed to load fw, resetting device!\n"); | 1082 | pr_info("failed to load fw, resetting device!\n"); |
1015 | if (--reset_count >= 0) { | 1083 | if (--reset_count >= 0) { |
1016 | if_usb_reset_device(cardp); | 1084 | if_usb_reset_device(cardp); |
1017 | goto restart; | 1085 | goto restart; |
1018 | } | 1086 | } |
1019 | 1087 | ||
1020 | lbs_pr_info("FW download failure, time = %d ms\n", i * 100); | 1088 | pr_info("FW download failure, time = %d ms\n", i * 100); |
1021 | ret = -EIO; | 1089 | ret = -EIO; |
1022 | goto release_fw; | 1090 | goto release_fw; |
1023 | } | 1091 | } |
@@ -1044,12 +1112,6 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message) | |||
1044 | if (priv->psstate != PS_STATE_FULL_POWER) | 1112 | if (priv->psstate != PS_STATE_FULL_POWER) |
1045 | return -1; | 1113 | return -1; |
1046 | 1114 | ||
1047 | if (priv->wol_criteria == EHS_REMOVE_WAKEUP) { | ||
1048 | lbs_pr_info("Suspend attempt without " | ||
1049 | "configuring wake params!\n"); | ||
1050 | return -ENOSYS; | ||
1051 | } | ||
1052 | |||
1053 | ret = lbs_suspend(priv); | 1115 | ret = lbs_suspend(priv); |
1054 | if (ret) | 1116 | if (ret) |
1055 | goto out; | 1117 | goto out; |