aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas
diff options
context:
space:
mode:
authorDaniel Drake <dsd@laptop.org>2012-04-16 18:52:42 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-04-17 14:57:13 -0400
commit370803c25dd77332ee4ca97884c3a5e1e1eafbca (patch)
tree1ed72c00356fe54b913fa4ec26a837c7014eb1e0 /drivers/net/wireless/libertas
parentbe03d4a45c09ee5100d3aaaedd087f19bc20d01f (diff)
libertas: Firmware loading simplifications
Remove the ability to pass module parameters with firmware filenames for USB and SDIO interfaces. Remove the ability to pass custom "user" filenames to lbs_get_firmware(). Remove the ability to reprogram internal device memory with a different firmware from the USB driver (we don't know of any users), and simplify the OLPC firmware loading quirk to simply placing the OLPC firmware at the top of the list (we don't know of any users other than OLPC). Move lbs_get_firmware() into its own file. These simplifications should have no real-life effect but make the upcoming transition to asynchronous firmware loading considerably less painful. Signed-off-by: Daniel Drake <dsd@laptop.org> Acked-by: Dan Williams <dcbw@redhat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/libertas')
-rw-r--r--drivers/net/wireless/libertas/Makefile1
-rw-r--r--drivers/net/wireless/libertas/decl.h3
-rw-r--r--drivers/net/wireless/libertas/firmware.c79
-rw-r--r--drivers/net/wireless/libertas/if_cs.c4
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c25
-rw-r--r--drivers/net/wireless/libertas/if_spi.c5
-rw-r--r--drivers/net/wireless/libertas/if_usb.c169
-rw-r--r--drivers/net/wireless/libertas/main.c101
8 files changed, 94 insertions, 293 deletions
diff --git a/drivers/net/wireless/libertas/Makefile b/drivers/net/wireless/libertas/Makefile
index f7d01bfa2e4..eac72f7bd34 100644
--- a/drivers/net/wireless/libertas/Makefile
+++ b/drivers/net/wireless/libertas/Makefile
@@ -6,6 +6,7 @@ libertas-y += ethtool.o
6libertas-y += main.o 6libertas-y += main.o
7libertas-y += rx.o 7libertas-y += rx.o
8libertas-y += tx.o 8libertas-y += tx.o
9libertas-y += firmware.o
9libertas-$(CONFIG_LIBERTAS_MESH) += mesh.o 10libertas-$(CONFIG_LIBERTAS_MESH) += mesh.o
10 11
11usb8xxx-objs += if_usb.o 12usb8xxx-objs += if_usb.o
diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h
index bc951ab4b68..2fb2e31733e 100644
--- a/drivers/net/wireless/libertas/decl.h
+++ b/drivers/net/wireless/libertas/decl.h
@@ -66,8 +66,7 @@ int lbs_exit_auto_deep_sleep(struct lbs_private *priv);
66u32 lbs_fw_index_to_data_rate(u8 index); 66u32 lbs_fw_index_to_data_rate(u8 index);
67u8 lbs_data_rate_to_fw_index(u32 rate); 67u8 lbs_data_rate_to_fw_index(u32 rate);
68 68
69int lbs_get_firmware(struct device *dev, const char *user_helper, 69int lbs_get_firmware(struct device *dev, u32 card_model,
70 const char *user_mainfw, u32 card_model,
71 const struct lbs_fw_table *fw_table, 70 const struct lbs_fw_table *fw_table,
72 const struct firmware **helper, 71 const struct firmware **helper,
73 const struct firmware **mainfw); 72 const struct firmware **mainfw);
diff --git a/drivers/net/wireless/libertas/firmware.c b/drivers/net/wireless/libertas/firmware.c
new file mode 100644
index 00000000000..0c8c845b490
--- /dev/null
+++ b/drivers/net/wireless/libertas/firmware.c
@@ -0,0 +1,79 @@
1/*
2 * Firmware loading and handling functions.
3 */
4
5#include <linux/firmware.h>
6#include <linux/module.h>
7
8#include "decl.h"
9
10/**
11 * lbs_get_firmware - Retrieves two-stage firmware
12 *
13 * @dev: A pointer to &device structure
14 * @card_model: Bus-specific card model ID used to filter firmware table
15 * elements
16 * @fw_table: Table of firmware file names and device model numbers
17 * terminated by an entry with a NULL helper name
18 * @helper: On success, the helper firmware; caller must free
19 * @mainfw: On success, the main firmware; caller must free
20 *
21 * returns: 0 on success, non-zero on failure
22 */
23int lbs_get_firmware(struct device *dev, u32 card_model,
24 const struct lbs_fw_table *fw_table,
25 const struct firmware **helper,
26 const struct firmware **mainfw)
27{
28 const struct lbs_fw_table *iter;
29 int ret;
30
31 BUG_ON(helper == NULL);
32 BUG_ON(mainfw == NULL);
33
34 /* Search for firmware to use from the table. */
35 iter = fw_table;
36 while (iter && iter->helper) {
37 if (iter->model != card_model)
38 goto next;
39
40 if (*helper == NULL) {
41 ret = request_firmware(helper, iter->helper, dev);
42 if (ret)
43 goto next;
44
45 /* If the device has one-stage firmware (ie cf8305) and
46 * we've got it then we don't need to bother with the
47 * main firmware.
48 */
49 if (iter->fwname == NULL)
50 return 0;
51 }
52
53 if (*mainfw == NULL) {
54 ret = request_firmware(mainfw, iter->fwname, dev);
55 if (ret) {
56 /* Clear the helper to ensure we don't have
57 * mismatched firmware pairs.
58 */
59 release_firmware(*helper);
60 *helper = NULL;
61 }
62 }
63
64 if (*helper && *mainfw)
65 return 0;
66
67 next:
68 iter++;
69 }
70
71 /* Failed */
72 release_firmware(*helper);
73 *helper = NULL;
74 release_firmware(*mainfw);
75 *mainfw = NULL;
76
77 return -ENOENT;
78}
79EXPORT_SYMBOL_GPL(lbs_get_firmware);
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index 171a06b8879..cee50528522 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -890,8 +890,8 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
890 goto out2; 890 goto out2;
891 } 891 }
892 892
893 ret = lbs_get_firmware(&p_dev->dev, NULL, NULL, card->model, 893 ret = lbs_get_firmware(&p_dev->dev, card->model, &fw_table[0],
894 &fw_table[0], &helper, &mainfw); 894 &helper, &mainfw);
895 if (ret) { 895 if (ret) {
896 pr_err("failed to find firmware (%d)\n", ret); 896 pr_err("failed to find firmware (%d)\n", ret);
897 goto out2; 897 goto out2;
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 15bfe2f589f..6590febb366 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -65,12 +65,6 @@ static void if_sdio_interrupt(struct sdio_func *func);
65 */ 65 */
66static u8 user_rmmod; 66static u8 user_rmmod;
67 67
68static char *lbs_helper_name = NULL;
69module_param_named(helper_name, lbs_helper_name, charp, 0644);
70
71static char *lbs_fw_name = NULL;
72module_param_named(fw_name, lbs_fw_name, charp, 0644);
73
74static const struct sdio_device_id if_sdio_ids[] = { 68static const struct sdio_device_id if_sdio_ids[] = {
75 { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 69 { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL,
76 SDIO_DEVICE_ID_MARVELL_LIBERTAS) }, 70 SDIO_DEVICE_ID_MARVELL_LIBERTAS) },
@@ -124,11 +118,6 @@ struct if_sdio_card {
124 unsigned long ioport; 118 unsigned long ioport;
125 unsigned int scratch_reg; 119 unsigned int scratch_reg;
126 120
127 const char *helper;
128 const char *firmware;
129 bool helper_allocated;
130 bool firmware_allocated;
131
132 u8 buffer[65536] __attribute__((aligned(4))); 121 u8 buffer[65536] __attribute__((aligned(4)));
133 122
134 spinlock_t lock; 123 spinlock_t lock;
@@ -725,8 +714,8 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card)
725 goto success; 714 goto success;
726 } 715 }
727 716
728 ret = lbs_get_firmware(&card->func->dev, lbs_helper_name, lbs_fw_name, 717 ret = lbs_get_firmware(&card->func->dev, card->model, &fw_table[0],
729 card->model, &fw_table[0], &helper, &mainfw); 718 &helper, &mainfw);
730 if (ret) { 719 if (ret) {
731 pr_err("failed to find firmware (%d)\n", ret); 720 pr_err("failed to find firmware (%d)\n", ret);
732 goto out; 721 goto out;
@@ -1242,10 +1231,6 @@ free:
1242 kfree(packet); 1231 kfree(packet);
1243 } 1232 }
1244 1233
1245 if (card->helper_allocated)
1246 kfree(card->helper);
1247 if (card->firmware_allocated)
1248 kfree(card->firmware);
1249 kfree(card); 1234 kfree(card);
1250 1235
1251 goto out; 1236 goto out;
@@ -1293,12 +1278,6 @@ static void if_sdio_remove(struct sdio_func *func)
1293 kfree(packet); 1278 kfree(packet);
1294 } 1279 }
1295 1280
1296 if (card->helper_allocated)
1297 kfree(card->helper);
1298 if (card->firmware_allocated)
1299 kfree(card->firmware);
1300 kfree(card);
1301
1302 lbs_deb_leave(LBS_DEB_SDIO); 1281 lbs_deb_leave(LBS_DEB_SDIO);
1303} 1282}
1304 1283
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index 7a5df4f4cb7..9604a1c4a74 100644
--- a/drivers/net/wireless/libertas/if_spi.c
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -1064,9 +1064,8 @@ static int if_spi_init_card(struct if_spi_card *card)
1064 goto out; 1064 goto out;
1065 } 1065 }
1066 1066
1067 err = lbs_get_firmware(&card->spi->dev, NULL, NULL, 1067 err = lbs_get_firmware(&card->spi->dev, card->card_id,
1068 card->card_id, &fw_table[0], &helper, 1068 &fw_table[0], &helper, &mainfw);
1069 &mainfw);
1070 if (err) { 1069 if (err) {
1071 netdev_err(priv->dev, "failed to find firmware (%d)\n", 1070 netdev_err(priv->dev, "failed to find firmware (%d)\n",
1072 err); 1071 err);
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index ce4938dec2c..f29471b8060 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -29,9 +29,6 @@
29 29
30#define MESSAGE_HEADER_LEN 4 30#define MESSAGE_HEADER_LEN 4
31 31
32static char *lbs_fw_name = NULL;
33module_param_named(fw_name, lbs_fw_name, charp, 0644);
34
35MODULE_FIRMWARE("libertas/usb8388_v9.bin"); 32MODULE_FIRMWARE("libertas/usb8388_v9.bin");
36MODULE_FIRMWARE("libertas/usb8388_v5.bin"); 33MODULE_FIRMWARE("libertas/usb8388_v5.bin");
37MODULE_FIRMWARE("libertas/usb8388.bin"); 34MODULE_FIRMWARE("libertas/usb8388.bin");
@@ -55,10 +52,7 @@ MODULE_DEVICE_TABLE(usb, if_usb_table);
55 52
56static void if_usb_receive(struct urb *urb); 53static void if_usb_receive(struct urb *urb);
57static void if_usb_receive_fwload(struct urb *urb); 54static void if_usb_receive_fwload(struct urb *urb);
58static int __if_usb_prog_firmware(struct if_usb_card *cardp, 55static int if_usb_prog_firmware(struct if_usb_card *cardp);
59 const char *fwname, int cmd);
60static int if_usb_prog_firmware(struct if_usb_card *cardp,
61 const char *fwname, int cmd);
62static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type, 56static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type,
63 uint8_t *payload, uint16_t nb); 57 uint8_t *payload, uint16_t nb);
64static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, 58static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload,
@@ -67,69 +61,6 @@ static void if_usb_free(struct if_usb_card *cardp);
67static int if_usb_submit_rx_urb(struct if_usb_card *cardp); 61static int if_usb_submit_rx_urb(struct if_usb_card *cardp);
68static int if_usb_reset_device(struct if_usb_card *cardp); 62static int if_usb_reset_device(struct if_usb_card *cardp);
69 63
70/* sysfs hooks */
71
72/*
73 * Set function to write firmware to device's persistent memory
74 */
75static ssize_t if_usb_firmware_set(struct device *dev,
76 struct device_attribute *attr, const char *buf, size_t count)
77{
78 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
79 struct if_usb_card *cardp = priv->card;
80 int ret;
81
82 BUG_ON(buf == NULL);
83
84 ret = if_usb_prog_firmware(cardp, buf, BOOT_CMD_UPDATE_FW);
85 if (ret == 0)
86 return count;
87
88 return ret;
89}
90
91/*
92 * lbs_flash_fw attribute to be exported per ethX interface through sysfs
93 * (/sys/class/net/ethX/lbs_flash_fw). Use this like so to write firmware to
94 * the device's persistent memory:
95 * echo usb8388-5.126.0.p5.bin > /sys/class/net/ethX/lbs_flash_fw
96 */
97static DEVICE_ATTR(lbs_flash_fw, 0200, NULL, if_usb_firmware_set);
98
99/**
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
108 */
109static ssize_t if_usb_boot2_set(struct device *dev,
110 struct device_attribute *attr, const char *buf, size_t count)
111{
112 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
113 struct if_usb_card *cardp = priv->card;
114 int ret;
115
116 BUG_ON(buf == NULL);
117
118 ret = if_usb_prog_firmware(cardp, buf, BOOT_CMD_UPDATE_BOOT2);
119 if (ret == 0)
120 return count;
121
122 return ret;
123}
124
125/*
126 * lbs_flash_boot2 attribute to be exported per ethX interface through sysfs
127 * (/sys/class/net/ethX/lbs_flash_boot2). Use this like so to write firmware
128 * to the device's persistent memory:
129 * echo usb8388-5.126.0.p5.bin > /sys/class/net/ethX/lbs_flash_boot2
130 */
131static DEVICE_ATTR(lbs_flash_boot2, 0200, NULL, if_usb_boot2_set);
132
133/** 64/**
134 * if_usb_write_bulk_callback - callback function to handle the status 65 * if_usb_write_bulk_callback - callback function to handle the status
135 * of the URB 66 * of the URB
@@ -314,13 +245,10 @@ static int if_usb_probe(struct usb_interface *intf,
314 } 245 }
315 246
316 /* Upload firmware */ 247 /* Upload firmware */
317 kparam_block_sysfs_write(fw_name); 248 if (if_usb_prog_firmware(cardp)) {
318 if (__if_usb_prog_firmware(cardp, lbs_fw_name, BOOT_CMD_FW_BY_USB)) {
319 kparam_unblock_sysfs_write(fw_name);
320 lbs_deb_usbd(&udev->dev, "FW upload failed\n"); 249 lbs_deb_usbd(&udev->dev, "FW upload failed\n");
321 goto err_prog_firmware; 250 goto err_prog_firmware;
322 } 251 }
323 kparam_unblock_sysfs_write(fw_name);
324 252
325 if (!(priv = lbs_add_card(cardp, &intf->dev))) 253 if (!(priv = lbs_add_card(cardp, &intf->dev)))
326 goto err_prog_firmware; 254 goto err_prog_firmware;
@@ -349,14 +277,6 @@ static int if_usb_probe(struct usb_interface *intf,
349 usb_get_dev(udev); 277 usb_get_dev(udev);
350 usb_set_intfdata(intf, cardp); 278 usb_set_intfdata(intf, cardp);
351 279
352 if (device_create_file(&priv->dev->dev, &dev_attr_lbs_flash_fw))
353 netdev_err(priv->dev,
354 "cannot register lbs_flash_fw attribute\n");
355
356 if (device_create_file(&priv->dev->dev, &dev_attr_lbs_flash_boot2))
357 netdev_err(priv->dev,
358 "cannot register lbs_flash_boot2 attribute\n");
359
360 /* 280 /*
361 * EHS_REMOVE_WAKEUP is not supported on all versions of the firmware. 281 * EHS_REMOVE_WAKEUP is not supported on all versions of the firmware.
362 */ 282 */
@@ -389,9 +309,6 @@ static void if_usb_disconnect(struct usb_interface *intf)
389 309
390 lbs_deb_enter(LBS_DEB_MAIN); 310 lbs_deb_enter(LBS_DEB_MAIN);
391 311
392 device_remove_file(&priv->dev->dev, &dev_attr_lbs_flash_boot2);
393 device_remove_file(&priv->dev->dev, &dev_attr_lbs_flash_fw);
394
395 cardp->surprise_removed = 1; 312 cardp->surprise_removed = 1;
396 313
397 if (priv) { 314 if (priv) {
@@ -912,58 +829,12 @@ static int check_fwfile_format(const uint8_t *data, uint32_t totlen)
912 return ret; 829 return ret;
913} 830}
914 831
915
916/**
917* if_usb_prog_firmware - programs the firmware subject to cmd
918*
919* @cardp: the if_usb_card descriptor
920* @fwname: firmware or boot2 image file name
921* @cmd: either BOOT_CMD_FW_BY_USB, BOOT_CMD_UPDATE_FW,
922* or BOOT_CMD_UPDATE_BOOT2.
923* returns: 0 or error code
924*/
925static int if_usb_prog_firmware(struct if_usb_card *cardp,
926 const char *fwname, int cmd)
927{
928 struct lbs_private *priv = cardp->priv;
929 unsigned long flags, caps;
930 int ret;
931
932 caps = priv->fwcapinfo;
933 if (((cmd == BOOT_CMD_UPDATE_FW) && !(caps & FW_CAPINFO_FIRMWARE_UPGRADE)) ||
934 ((cmd == BOOT_CMD_UPDATE_BOOT2) && !(caps & FW_CAPINFO_BOOT2_UPGRADE)))
935 return -EOPNOTSUPP;
936
937 /* Ensure main thread is idle. */
938 spin_lock_irqsave(&priv->driver_lock, flags);
939 while (priv->cur_cmd != NULL || priv->dnld_sent != DNLD_RES_RECEIVED) {
940 spin_unlock_irqrestore(&priv->driver_lock, flags);
941 if (wait_event_interruptible(priv->waitq,
942 (priv->cur_cmd == NULL &&
943 priv->dnld_sent == DNLD_RES_RECEIVED))) {
944 return -ERESTARTSYS;
945 }
946 spin_lock_irqsave(&priv->driver_lock, flags);
947 }
948 priv->dnld_sent = DNLD_BOOTCMD_SENT;
949 spin_unlock_irqrestore(&priv->driver_lock, flags);
950
951 ret = __if_usb_prog_firmware(cardp, fwname, cmd);
952
953 spin_lock_irqsave(&priv->driver_lock, flags);
954 priv->dnld_sent = DNLD_RES_RECEIVED;
955 spin_unlock_irqrestore(&priv->driver_lock, flags);
956
957 wake_up(&priv->waitq);
958
959 return ret;
960}
961
962/* table of firmware file names */ 832/* table of firmware file names */
963static const struct { 833static const struct {
964 u32 model; 834 u32 model;
965 const char *fwname; 835 const char *fwname;
966} fw_table[] = { 836} fw_table[] = {
837 { MODEL_8388, "libertas/usb8388_olpc.bin" },
967 { MODEL_8388, "libertas/usb8388_v9.bin" }, 838 { MODEL_8388, "libertas/usb8388_v9.bin" },
968 { MODEL_8388, "libertas/usb8388_v5.bin" }, 839 { MODEL_8388, "libertas/usb8388_v5.bin" },
969 { MODEL_8388, "libertas/usb8388.bin" }, 840 { MODEL_8388, "libertas/usb8388.bin" },
@@ -971,35 +842,10 @@ static const struct {
971 { MODEL_8682, "libertas/usb8682.bin" } 842 { MODEL_8682, "libertas/usb8682.bin" }
972}; 843};
973 844
974#ifdef CONFIG_OLPC 845static int get_fw(struct if_usb_card *cardp)
975
976static int try_olpc_fw(struct if_usb_card *cardp)
977{
978 int retval = -ENOENT;
979
980 /* try the OLPC firmware first; fall back to fw_table list */
981 if (machine_is_olpc() && cardp->model == MODEL_8388)
982 retval = request_firmware(&cardp->fw,
983 "libertas/usb8388_olpc.bin", &cardp->udev->dev);
984 return retval;
985}
986
987#else
988static int try_olpc_fw(struct if_usb_card *cardp) { return -ENOENT; }
989#endif /* !CONFIG_OLPC */
990
991static int get_fw(struct if_usb_card *cardp, const char *fwname)
992{ 846{
993 int i; 847 int i;
994 848
995 /* Try user-specified firmware first */
996 if (fwname)
997 return request_firmware(&cardp->fw, fwname, &cardp->udev->dev);
998
999 /* Handle OLPC firmware */
1000 if (try_olpc_fw(cardp) == 0)
1001 return 0;
1002
1003 /* Otherwise search for firmware to use */ 849 /* Otherwise search for firmware to use */
1004 for (i = 0; i < ARRAY_SIZE(fw_table); i++) { 850 for (i = 0; i < ARRAY_SIZE(fw_table); i++) {
1005 if (fw_table[i].model != cardp->model) 851 if (fw_table[i].model != cardp->model)
@@ -1012,8 +858,7 @@ static int get_fw(struct if_usb_card *cardp, const char *fwname)
1012 return -ENOENT; 858 return -ENOENT;
1013} 859}
1014 860
1015static int __if_usb_prog_firmware(struct if_usb_card *cardp, 861static int if_usb_prog_firmware(struct if_usb_card *cardp)
1016 const char *fwname, int cmd)
1017{ 862{
1018 int i = 0; 863 int i = 0;
1019 static int reset_count = 10; 864 static int reset_count = 10;
@@ -1021,7 +866,7 @@ static int __if_usb_prog_firmware(struct if_usb_card *cardp,
1021 866
1022 lbs_deb_enter(LBS_DEB_USB); 867 lbs_deb_enter(LBS_DEB_USB);
1023 868
1024 ret = get_fw(cardp, fwname); 869 ret = get_fw(cardp);
1025 if (ret) { 870 if (ret) {
1026 pr_err("failed to find firmware (%d)\n", ret); 871 pr_err("failed to find firmware (%d)\n", ret);
1027 goto done; 872 goto done;
@@ -1053,7 +898,7 @@ restart:
1053 do { 898 do {
1054 int j = 0; 899 int j = 0;
1055 i++; 900 i++;
1056 if_usb_issue_boot_command(cardp, cmd); 901 if_usb_issue_boot_command(cardp, BOOT_CMD_FW_BY_USB);
1057 /* wait for command response */ 902 /* wait for command response */
1058 do { 903 do {
1059 j++; 904 j++;
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 3b81b709bf9..fa095851f21 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -1177,107 +1177,6 @@ void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx)
1177} 1177}
1178EXPORT_SYMBOL_GPL(lbs_notify_command_response); 1178EXPORT_SYMBOL_GPL(lbs_notify_command_response);
1179 1179
1180/**
1181 * lbs_get_firmware - Retrieves two-stage firmware
1182 *
1183 * @dev: A pointer to &device structure
1184 * @user_helper: User-defined helper firmware file
1185 * @user_mainfw: User-defined main firmware file
1186 * @card_model: Bus-specific card model ID used to filter firmware table
1187 * elements
1188 * @fw_table: Table of firmware file names and device model numbers
1189 * terminated by an entry with a NULL helper name
1190 * @helper: On success, the helper firmware; caller must free
1191 * @mainfw: On success, the main firmware; caller must free
1192 *
1193 * returns: 0 on success, non-zero on failure
1194 */
1195int lbs_get_firmware(struct device *dev, const char *user_helper,
1196 const char *user_mainfw, u32 card_model,
1197 const struct lbs_fw_table *fw_table,
1198 const struct firmware **helper,
1199 const struct firmware **mainfw)
1200{
1201 const struct lbs_fw_table *iter;
1202 int ret;
1203
1204 BUG_ON(helper == NULL);
1205 BUG_ON(mainfw == NULL);
1206
1207 /* Try user-specified firmware first */
1208 if (user_helper) {
1209 ret = request_firmware(helper, user_helper, dev);
1210 if (ret) {
1211 dev_err(dev, "couldn't find helper firmware %s\n",
1212 user_helper);
1213 goto fail;
1214 }
1215 }
1216 if (user_mainfw) {
1217 ret = request_firmware(mainfw, user_mainfw, dev);
1218 if (ret) {
1219 dev_err(dev, "couldn't find main firmware %s\n",
1220 user_mainfw);
1221 goto fail;
1222 }
1223 }
1224
1225 if (*helper && *mainfw)
1226 return 0;
1227
1228 /* Otherwise search for firmware to use. If neither the helper or
1229 * the main firmware were specified by the user, then we need to
1230 * make sure that found helper & main are from the same entry in
1231 * fw_table.
1232 */
1233 iter = fw_table;
1234 while (iter && iter->helper) {
1235 if (iter->model != card_model)
1236 goto next;
1237
1238 if (*helper == NULL) {
1239 ret = request_firmware(helper, iter->helper, dev);
1240 if (ret)
1241 goto next;
1242
1243 /* If the device has one-stage firmware (ie cf8305) and
1244 * we've got it then we don't need to bother with the
1245 * main firmware.
1246 */
1247 if (iter->fwname == NULL)
1248 return 0;
1249 }
1250
1251 if (*mainfw == NULL) {
1252 ret = request_firmware(mainfw, iter->fwname, dev);
1253 if (ret && !user_helper) {
1254 /* Clear the helper if it wasn't user-specified
1255 * and the main firmware load failed, to ensure
1256 * we don't have mismatched firmware pairs.
1257 */
1258 release_firmware(*helper);
1259 *helper = NULL;
1260 }
1261 }
1262
1263 if (*helper && *mainfw)
1264 return 0;
1265
1266 next:
1267 iter++;
1268 }
1269
1270 fail:
1271 /* Failed */
1272 release_firmware(*helper);
1273 *helper = NULL;
1274 release_firmware(*mainfw);
1275 *mainfw = NULL;
1276
1277 return -ENOENT;
1278}
1279EXPORT_SYMBOL_GPL(lbs_get_firmware);
1280
1281static int __init lbs_init_module(void) 1180static int __init lbs_init_module(void)
1282{ 1181{
1283 lbs_deb_enter(LBS_DEB_MAIN); 1182 lbs_deb_enter(LBS_DEB_MAIN);