aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/libertas')
-rw-r--r--drivers/net/wireless/libertas/cfg.c62
-rw-r--r--drivers/net/wireless/libertas/decl.h13
-rw-r--r--drivers/net/wireless/libertas/if_cs.c130
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c161
-rw-r--r--drivers/net/wireless/libertas/if_sdio.h4
-rw-r--r--drivers/net/wireless/libertas/if_spi.c150
-rw-r--r--drivers/net/wireless/libertas/if_spi.h5
-rw-r--r--drivers/net/wireless/libertas/if_usb.c60
-rw-r--r--drivers/net/wireless/libertas/if_usb.h1
-rw-r--r--drivers/net/wireless/libertas/main.c105
10 files changed, 429 insertions, 262 deletions
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index 3e82f162720..317f086ced0 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -10,6 +10,7 @@
10#include <linux/wait.h> 10#include <linux/wait.h>
11#include <linux/slab.h> 11#include <linux/slab.h>
12#include <linux/sched.h> 12#include <linux/sched.h>
13#include <linux/wait.h>
13#include <linux/ieee80211.h> 14#include <linux/ieee80211.h>
14#include <net/cfg80211.h> 15#include <net/cfg80211.h>
15#include <asm/unaligned.h> 16#include <asm/unaligned.h>
@@ -526,20 +527,31 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
526 527
527 pos = scanresp->bssdesc_and_tlvbuffer; 528 pos = scanresp->bssdesc_and_tlvbuffer;
528 529
530 lbs_deb_hex(LBS_DEB_SCAN, "SCAN_RSP", scanresp->bssdesc_and_tlvbuffer,
531 scanresp->bssdescriptsize);
532
529 tsfdesc = pos + bsssize; 533 tsfdesc = pos + bsssize;
530 tsfsize = 4 + 8 * scanresp->nr_sets; 534 tsfsize = 4 + 8 * scanresp->nr_sets;
535 lbs_deb_hex(LBS_DEB_SCAN, "SCAN_TSF", (u8 *) tsfdesc, tsfsize);
531 536
532 /* Validity check: we expect a Marvell-Local TLV */ 537 /* Validity check: we expect a Marvell-Local TLV */
533 i = get_unaligned_le16(tsfdesc); 538 i = get_unaligned_le16(tsfdesc);
534 tsfdesc += 2; 539 tsfdesc += 2;
535 if (i != TLV_TYPE_TSFTIMESTAMP) 540 if (i != TLV_TYPE_TSFTIMESTAMP) {
541 lbs_deb_scan("scan response: invalid TSF Timestamp %d\n", i);
536 goto done; 542 goto done;
543 }
544
537 /* Validity check: the TLV holds TSF values with 8 bytes each, so 545 /* Validity check: the TLV holds TSF values with 8 bytes each, so
538 * the size in the TLV must match the nr_sets value */ 546 * the size in the TLV must match the nr_sets value */
539 i = get_unaligned_le16(tsfdesc); 547 i = get_unaligned_le16(tsfdesc);
540 tsfdesc += 2; 548 tsfdesc += 2;
541 if (i / 8 != scanresp->nr_sets) 549 if (i / 8 != scanresp->nr_sets) {
550 lbs_deb_scan("scan response: invalid number of TSF timestamp "
551 "sets (expected %d got %d)\n", scanresp->nr_sets,
552 i / 8);
542 goto done; 553 goto done;
554 }
543 555
544 for (i = 0; i < scanresp->nr_sets; i++) { 556 for (i = 0; i < scanresp->nr_sets; i++) {
545 const u8 *bssid; 557 const u8 *bssid;
@@ -581,8 +593,11 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
581 id = *pos++; 593 id = *pos++;
582 elen = *pos++; 594 elen = *pos++;
583 left -= 2; 595 left -= 2;
584 if (elen > left || elen == 0) 596 if (elen > left || elen == 0) {
597 lbs_deb_scan("scan response: invalid IE fmt\n");
585 goto done; 598 goto done;
599 }
600
586 if (id == WLAN_EID_DS_PARAMS) 601 if (id == WLAN_EID_DS_PARAMS)
587 chan_no = *pos; 602 chan_no = *pos;
588 if (id == WLAN_EID_SSID) { 603 if (id == WLAN_EID_SSID) {
@@ -613,7 +628,9 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
613 capa, intvl, ie, ielen, 628 capa, intvl, ie, ielen,
614 LBS_SCAN_RSSI_TO_MBM(rssi), 629 LBS_SCAN_RSSI_TO_MBM(rssi),
615 GFP_KERNEL); 630 GFP_KERNEL);
616 } 631 } else
632 lbs_deb_scan("scan response: missing BSS channel IE\n");
633
617 tsfdesc += 8; 634 tsfdesc += 8;
618 } 635 }
619 ret = 0; 636 ret = 0;
@@ -1103,7 +1120,7 @@ static int lbs_associate(struct lbs_private *priv,
1103 lbs_deb_hex(LBS_DEB_ASSOC, "Common Rates", tmp, pos - tmp); 1120 lbs_deb_hex(LBS_DEB_ASSOC, "Common Rates", tmp, pos - tmp);
1104 1121
1105 /* add auth type TLV */ 1122 /* add auth type TLV */
1106 if (priv->fwrelease >= 0x09000000) 1123 if (MRVL_FW_MAJOR_REV(priv->fwrelease) >= 9)
1107 pos += lbs_add_auth_type_tlv(pos, sme->auth_type); 1124 pos += lbs_add_auth_type_tlv(pos, sme->auth_type);
1108 1125
1109 /* add WPA/WPA2 TLV */ 1126 /* add WPA/WPA2 TLV */
@@ -1114,6 +1131,9 @@ static int lbs_associate(struct lbs_private *priv,
1114 (u16)(pos - (u8 *) &cmd->iebuf); 1131 (u16)(pos - (u8 *) &cmd->iebuf);
1115 cmd->hdr.size = cpu_to_le16(len); 1132 cmd->hdr.size = cpu_to_le16(len);
1116 1133
1134 lbs_deb_hex(LBS_DEB_ASSOC, "ASSOC_CMD", (u8 *) cmd,
1135 le16_to_cpu(cmd->hdr.size));
1136
1117 /* store for later use */ 1137 /* store for later use */
1118 memcpy(priv->assoc_bss, bss->bssid, ETH_ALEN); 1138 memcpy(priv->assoc_bss, bss->bssid, ETH_ALEN);
1119 1139
@@ -1121,14 +1141,28 @@ static int lbs_associate(struct lbs_private *priv,
1121 if (ret) 1141 if (ret)
1122 goto done; 1142 goto done;
1123 1143
1124
1125 /* generate connect message to cfg80211 */ 1144 /* generate connect message to cfg80211 */
1126 1145
1127 resp = (void *) cmd; /* recast for easier field access */ 1146 resp = (void *) cmd; /* recast for easier field access */
1128 status = le16_to_cpu(resp->statuscode); 1147 status = le16_to_cpu(resp->statuscode);
1129 1148
1130 /* Convert statis code of old firmware */ 1149 /* Older FW versions map the IEEE 802.11 Status Code in the association
1131 if (priv->fwrelease < 0x09000000) 1150 * response to the following values returned in resp->statuscode:
1151 *
1152 * IEEE Status Code Marvell Status Code
1153 * 0 -> 0x0000 ASSOC_RESULT_SUCCESS
1154 * 13 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
1155 * 14 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
1156 * 15 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
1157 * 16 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
1158 * others -> 0x0003 ASSOC_RESULT_REFUSED
1159 *
1160 * Other response codes:
1161 * 0x0001 -> ASSOC_RESULT_INVALID_PARAMETERS (unused)
1162 * 0x0002 -> ASSOC_RESULT_TIMEOUT (internal timer expired waiting for
1163 * association response from the AP)
1164 */
1165 if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) {
1132 switch (status) { 1166 switch (status) {
1133 case 0: 1167 case 0:
1134 break; 1168 break;
@@ -1150,11 +1184,16 @@ static int lbs_associate(struct lbs_private *priv,
1150 break; 1184 break;
1151 default: 1185 default:
1152 lbs_deb_assoc("association failure %d\n", status); 1186 lbs_deb_assoc("association failure %d\n", status);
1153 status = WLAN_STATUS_UNSPECIFIED_FAILURE; 1187 /* v5 OLPC firmware does return the AP status code if
1188 * it's not one of the values above. Let that through.
1189 */
1190 break;
1191 }
1154 } 1192 }
1155 1193
1156 lbs_deb_assoc("status %d, capability 0x%04x\n", status, 1194 lbs_deb_assoc("status %d, statuscode 0x%04x, capability 0x%04x, "
1157 le16_to_cpu(resp->capability)); 1195 "aid 0x%04x\n", status, le16_to_cpu(resp->statuscode),
1196 le16_to_cpu(resp->capability), le16_to_cpu(resp->aid));
1158 1197
1159 resp_ie_len = le16_to_cpu(resp->hdr.size) 1198 resp_ie_len = le16_to_cpu(resp->hdr.size)
1160 - sizeof(resp->hdr) 1199 - sizeof(resp->hdr)
@@ -1174,7 +1213,6 @@ static int lbs_associate(struct lbs_private *priv,
1174 netif_tx_wake_all_queues(priv->dev); 1213 netif_tx_wake_all_queues(priv->dev);
1175 } 1214 }
1176 1215
1177
1178done: 1216done:
1179 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); 1217 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
1180 return ret; 1218 return ret;
diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h
index 1d141fefd76..2ae752d1006 100644
--- a/drivers/net/wireless/libertas/decl.h
+++ b/drivers/net/wireless/libertas/decl.h
@@ -8,7 +8,14 @@
8#define _LBS_DECL_H_ 8#define _LBS_DECL_H_
9 9
10#include <linux/netdevice.h> 10#include <linux/netdevice.h>
11#include <linux/firmware.h>
11 12
13/* Should be terminated by a NULL entry */
14struct lbs_fw_table {
15 int model;
16 const char *helper;
17 const char *fwname;
18};
12 19
13struct lbs_private; 20struct lbs_private;
14struct sk_buff; 21struct sk_buff;
@@ -53,4 +60,10 @@ int lbs_exit_auto_deep_sleep(struct lbs_private *priv);
53u32 lbs_fw_index_to_data_rate(u8 index); 60u32 lbs_fw_index_to_data_rate(u8 index);
54u8 lbs_data_rate_to_fw_index(u32 rate); 61u8 lbs_data_rate_to_fw_index(u32 rate);
55 62
63int lbs_get_firmware(struct device *dev, const char *user_helper,
64 const char *user_mainfw, u32 card_model,
65 const struct lbs_fw_table *fw_table,
66 const struct firmware **helper,
67 const struct firmware **mainfw);
68
56#endif 69#endif
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index 9c298396be5..e213a5dc049 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -48,7 +48,6 @@
48MODULE_AUTHOR("Holger Schurig <hs4233@mail.mn-solutions.de>"); 48MODULE_AUTHOR("Holger Schurig <hs4233@mail.mn-solutions.de>");
49MODULE_DESCRIPTION("Driver for Marvell 83xx compact flash WLAN cards"); 49MODULE_DESCRIPTION("Driver for Marvell 83xx compact flash WLAN cards");
50MODULE_LICENSE("GPL"); 50MODULE_LICENSE("GPL");
51MODULE_FIRMWARE("libertas_cs_helper.fw");
52 51
53 52
54 53
@@ -61,9 +60,34 @@ struct if_cs_card {
61 struct lbs_private *priv; 60 struct lbs_private *priv;
62 void __iomem *iobase; 61 void __iomem *iobase;
63 bool align_regs; 62 bool align_regs;
63 u32 model;
64}; 64};
65 65
66 66
67enum {
68 MODEL_UNKNOWN = 0x00,
69 MODEL_8305 = 0x01,
70 MODEL_8381 = 0x02,
71 MODEL_8385 = 0x03
72};
73
74static const struct lbs_fw_table fw_table[] = {
75 { MODEL_8305, "libertas/cf8305.bin", NULL },
76 { MODEL_8305, "libertas_cs_helper.fw", NULL },
77 { MODEL_8381, "libertas/cf8381_helper.bin", "libertas/cf8381.bin" },
78 { MODEL_8381, "libertas_cs_helper.fw", "libertas_cs.fw" },
79 { MODEL_8385, "libertas/cf8385_helper.bin", "libertas/cf8385.bin" },
80 { MODEL_8385, "libertas_cs_helper.fw", "libertas_cs.fw" },
81 { 0, NULL, NULL }
82};
83MODULE_FIRMWARE("libertas/cf8305.bin");
84MODULE_FIRMWARE("libertas/cf8381_helper.bin");
85MODULE_FIRMWARE("libertas/cf8381.bin");
86MODULE_FIRMWARE("libertas/cf8385_helper.bin");
87MODULE_FIRMWARE("libertas/cf8385.bin");
88MODULE_FIRMWARE("libertas_cs_helper.fw");
89MODULE_FIRMWARE("libertas_cs.fw");
90
67 91
68/********************************************************************/ 92/********************************************************************/
69/* Hardware access */ 93/* Hardware access */
@@ -289,22 +313,19 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r
289#define CF8385_MANFID 0x02df 313#define CF8385_MANFID 0x02df
290#define CF8385_CARDID 0x8103 314#define CF8385_CARDID 0x8103
291 315
292static inline int if_cs_hw_is_cf8305(struct pcmcia_device *p_dev) 316/* FIXME: just use the 'driver_info' field of 'struct pcmcia_device_id' when
293{ 317 * that gets fixed. Currently there's no way to access it from the probe hook.
294 return (p_dev->manf_id == CF8305_MANFID && 318 */
295 p_dev->card_id == CF8305_CARDID); 319static inline u32 get_model(u16 manf_id, u16 card_id)
296}
297
298static inline int if_cs_hw_is_cf8381(struct pcmcia_device *p_dev)
299{
300 return (p_dev->manf_id == CF8381_MANFID &&
301 p_dev->card_id == CF8381_CARDID);
302}
303
304static inline int if_cs_hw_is_cf8385(struct pcmcia_device *p_dev)
305{ 320{
306 return (p_dev->manf_id == CF8385_MANFID && 321 /* NOTE: keep in sync with if_cs_ids */
307 p_dev->card_id == CF8385_CARDID); 322 if (manf_id == CF8305_MANFID && card_id == CF8305_CARDID)
323 return MODEL_8305;
324 else if (manf_id == CF8381_MANFID && card_id == CF8381_CARDID)
325 return MODEL_8381;
326 else if (manf_id == CF8385_MANFID && card_id == CF8385_CARDID)
327 return MODEL_8385;
328 return MODEL_UNKNOWN;
308} 329}
309 330
310/********************************************************************/ 331/********************************************************************/
@@ -558,12 +579,11 @@ static irqreturn_t if_cs_interrupt(int irq, void *data)
558 * 579 *
559 * Return 0 on success 580 * Return 0 on success
560 */ 581 */
561static int if_cs_prog_helper(struct if_cs_card *card) 582static int if_cs_prog_helper(struct if_cs_card *card, const struct firmware *fw)
562{ 583{
563 int ret = 0; 584 int ret = 0;
564 int sent = 0; 585 int sent = 0;
565 u8 scratch; 586 u8 scratch;
566 const struct firmware *fw;
567 587
568 lbs_deb_enter(LBS_DEB_CS); 588 lbs_deb_enter(LBS_DEB_CS);
569 589
@@ -589,14 +609,6 @@ static int if_cs_prog_helper(struct if_cs_card *card)
589 goto done; 609 goto done;
590 } 610 }
591 611
592 /* TODO: make firmware file configurable */
593 ret = request_firmware(&fw, "libertas_cs_helper.fw",
594 &card->p_dev->dev);
595 if (ret) {
596 lbs_pr_err("can't load helper firmware\n");
597 ret = -ENODEV;
598 goto done;
599 }
600 lbs_deb_cs("helper size %td\n", fw->size); 612 lbs_deb_cs("helper size %td\n", fw->size);
601 613
602 /* "Set the 5 bytes of the helper image to 0" */ 614 /* "Set the 5 bytes of the helper image to 0" */
@@ -635,7 +647,7 @@ static int if_cs_prog_helper(struct if_cs_card *card)
635 if (ret < 0) { 647 if (ret < 0) {
636 lbs_pr_err("can't download helper at 0x%x, ret %d\n", 648 lbs_pr_err("can't download helper at 0x%x, ret %d\n",
637 sent, ret); 649 sent, ret);
638 goto err_release; 650 goto done;
639 } 651 }
640 652
641 if (count == 0) 653 if (count == 0)
@@ -644,17 +656,14 @@ static int if_cs_prog_helper(struct if_cs_card *card)
644 sent += count; 656 sent += count;
645 } 657 }
646 658
647err_release:
648 release_firmware(fw);
649done: 659done:
650 lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); 660 lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
651 return ret; 661 return ret;
652} 662}
653 663
654 664
655static int if_cs_prog_real(struct if_cs_card *card) 665static int if_cs_prog_real(struct if_cs_card *card, const struct firmware *fw)
656{ 666{
657 const struct firmware *fw;
658 int ret = 0; 667 int ret = 0;
659 int retry = 0; 668 int retry = 0;
660 int len = 0; 669 int len = 0;
@@ -662,21 +671,13 @@ static int if_cs_prog_real(struct if_cs_card *card)
662 671
663 lbs_deb_enter(LBS_DEB_CS); 672 lbs_deb_enter(LBS_DEB_CS);
664 673
665 /* TODO: make firmware file configurable */
666 ret = request_firmware(&fw, "libertas_cs.fw",
667 &card->p_dev->dev);
668 if (ret) {
669 lbs_pr_err("can't load firmware\n");
670 ret = -ENODEV;
671 goto done;
672 }
673 lbs_deb_cs("fw size %td\n", fw->size); 674 lbs_deb_cs("fw size %td\n", fw->size);
674 675
675 ret = if_cs_poll_while_fw_download(card, IF_CS_SQ_READ_LOW, 676 ret = if_cs_poll_while_fw_download(card, IF_CS_SQ_READ_LOW,
676 IF_CS_SQ_HELPER_OK); 677 IF_CS_SQ_HELPER_OK);
677 if (ret < 0) { 678 if (ret < 0) {
678 lbs_pr_err("helper firmware doesn't answer\n"); 679 lbs_pr_err("helper firmware doesn't answer\n");
679 goto err_release; 680 goto done;
680 } 681 }
681 682
682 for (sent = 0; sent < fw->size; sent += len) { 683 for (sent = 0; sent < fw->size; sent += len) {
@@ -691,7 +692,7 @@ static int if_cs_prog_real(struct if_cs_card *card)
691 if (retry > 20) { 692 if (retry > 20) {
692 lbs_pr_err("could not download firmware\n"); 693 lbs_pr_err("could not download firmware\n");
693 ret = -ENODEV; 694 ret = -ENODEV;
694 goto err_release; 695 goto done;
695 } 696 }
696 if (retry) { 697 if (retry) {
697 sent -= len; 698 sent -= len;
@@ -710,7 +711,7 @@ static int if_cs_prog_real(struct if_cs_card *card)
710 IF_CS_BIT_COMMAND); 711 IF_CS_BIT_COMMAND);
711 if (ret < 0) { 712 if (ret < 0) {
712 lbs_pr_err("can't download firmware at 0x%x\n", sent); 713 lbs_pr_err("can't download firmware at 0x%x\n", sent);
713 goto err_release; 714 goto done;
714 } 715 }
715 } 716 }
716 717
@@ -718,9 +719,6 @@ static int if_cs_prog_real(struct if_cs_card *card)
718 if (ret < 0) 719 if (ret < 0)
719 lbs_pr_err("firmware download failed\n"); 720 lbs_pr_err("firmware download failed\n");
720 721
721err_release:
722 release_firmware(fw);
723
724done: 722done:
725 lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); 723 lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
726 return ret; 724 return ret;
@@ -824,6 +822,8 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
824 unsigned int prod_id; 822 unsigned int prod_id;
825 struct lbs_private *priv; 823 struct lbs_private *priv;
826 struct if_cs_card *card; 824 struct if_cs_card *card;
825 const struct firmware *helper = NULL;
826 const struct firmware *mainfw = NULL;
827 827
828 lbs_deb_enter(LBS_DEB_CS); 828 lbs_deb_enter(LBS_DEB_CS);
829 829
@@ -843,7 +843,6 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
843 goto out1; 843 goto out1;
844 } 844 }
845 845
846
847 /* 846 /*
848 * Allocate an interrupt line. Note that this does not assign 847 * Allocate an interrupt line. Note that this does not assign
849 * a handler to the interrupt, unless the 'Handler' member of 848 * a handler to the interrupt, unless the 'Handler' member of
@@ -881,34 +880,47 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
881 */ 880 */
882 card->align_regs = 0; 881 card->align_regs = 0;
883 882
883 card->model = get_model(p_dev->manf_id, p_dev->card_id);
884 if (card->model == MODEL_UNKNOWN) {
885 lbs_pr_err("unsupported manf_id 0x%04x / card_id 0x%04x\n",
886 p_dev->manf_id, p_dev->card_id);
887 goto out2;
888 }
889
884 /* Check if we have a current silicon */ 890 /* Check if we have a current silicon */
885 prod_id = if_cs_read8(card, IF_CS_PRODUCT_ID); 891 prod_id = if_cs_read8(card, IF_CS_PRODUCT_ID);
886 if (if_cs_hw_is_cf8305(p_dev)) { 892 if (card->model == MODEL_8305) {
887 card->align_regs = 1; 893 card->align_regs = 1;
888 if (prod_id < IF_CS_CF8305_B1_REV) { 894 if (prod_id < IF_CS_CF8305_B1_REV) {
889 lbs_pr_err("old chips like 8305 rev B3 " 895 lbs_pr_err("8305 rev B0 and older are not supported\n");
890 "aren't supported\n");
891 ret = -ENODEV; 896 ret = -ENODEV;
892 goto out2; 897 goto out2;
893 } 898 }
894 } 899 }
895 900
896 if (if_cs_hw_is_cf8381(p_dev) && prod_id < IF_CS_CF8381_B3_REV) { 901 if ((card->model == MODEL_8381) && prod_id < IF_CS_CF8381_B3_REV) {
897 lbs_pr_err("old chips like 8381 rev B3 aren't supported\n"); 902 lbs_pr_err("8381 rev B2 and older are not supported\n");
898 ret = -ENODEV; 903 ret = -ENODEV;
899 goto out2; 904 goto out2;
900 } 905 }
901 906
902 if (if_cs_hw_is_cf8385(p_dev) && prod_id < IF_CS_CF8385_B1_REV) { 907 if ((card->model == MODEL_8385) && prod_id < IF_CS_CF8385_B1_REV) {
903 lbs_pr_err("old chips like 8385 rev B1 aren't supported\n"); 908 lbs_pr_err("8385 rev B0 and older are not supported\n");
904 ret = -ENODEV; 909 ret = -ENODEV;
905 goto out2; 910 goto out2;
906 } 911 }
907 912
913 ret = lbs_get_firmware(&p_dev->dev, NULL, NULL, card->model,
914 &fw_table[0], &helper, &mainfw);
915 if (ret) {
916 lbs_pr_err("failed to find firmware (%d)\n", ret);
917 goto out2;
918 }
919
908 /* Load the firmware early, before calling into libertas.ko */ 920 /* Load the firmware early, before calling into libertas.ko */
909 ret = if_cs_prog_helper(card); 921 ret = if_cs_prog_helper(card, helper);
910 if (ret == 0 && !if_cs_hw_is_cf8305(p_dev)) 922 if (ret == 0 && (card->model != MODEL_8305))
911 ret = if_cs_prog_real(card); 923 ret = if_cs_prog_real(card, mainfw);
912 if (ret) 924 if (ret)
913 goto out2; 925 goto out2;
914 926
@@ -957,6 +969,11 @@ out2:
957out1: 969out1:
958 pcmcia_disable_device(p_dev); 970 pcmcia_disable_device(p_dev);
959out: 971out:
972 if (helper)
973 release_firmware(helper);
974 if (mainfw)
975 release_firmware(mainfw);
976
960 lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); 977 lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
961 return ret; 978 return ret;
962} 979}
@@ -993,6 +1010,7 @@ static struct pcmcia_device_id if_cs_ids[] = {
993 PCMCIA_DEVICE_MANF_CARD(CF8305_MANFID, CF8305_CARDID), 1010 PCMCIA_DEVICE_MANF_CARD(CF8305_MANFID, CF8305_CARDID),
994 PCMCIA_DEVICE_MANF_CARD(CF8381_MANFID, CF8381_CARDID), 1011 PCMCIA_DEVICE_MANF_CARD(CF8381_MANFID, CF8381_CARDID),
995 PCMCIA_DEVICE_MANF_CARD(CF8385_MANFID, CF8385_CARDID), 1012 PCMCIA_DEVICE_MANF_CARD(CF8385_MANFID, CF8385_CARDID),
1013 /* NOTE: keep in sync with get_model() */
996 PCMCIA_DEVICE_NULL, 1014 PCMCIA_DEVICE_NULL,
997}; 1015};
998MODULE_DEVICE_TABLE(pcmcia, if_cs_ids); 1016MODULE_DEVICE_TABLE(pcmcia, if_cs_ids);
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index ba854c70ab9..1bbaaa44d98 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -76,36 +76,32 @@ static const struct sdio_device_id if_sdio_ids[] = {
76 76
77MODULE_DEVICE_TABLE(sdio, if_sdio_ids); 77MODULE_DEVICE_TABLE(sdio, if_sdio_ids);
78 78
79struct if_sdio_model { 79#define MODEL_8385 0x04
80 int model; 80#define MODEL_8686 0x0b
81 const char *helper; 81#define MODEL_8688 0x10
82 const char *firmware; 82
83}; 83static const struct lbs_fw_table fw_table[] = {
84 84 { MODEL_8385, "libertas/sd8385_helper.bin", "libertas/sd8385.bin" },
85static struct if_sdio_model if_sdio_models[] = { 85 { MODEL_8385, "sd8385_helper.bin", "sd8385.bin" },
86 { 86 { MODEL_8686, "libertas/sd8686_v9_helper.bin", "libertas/sd8686_v9.bin" },
87 /* 8385 */ 87 { MODEL_8686, "libertas/sd8686_v8_helper.bin", "libertas/sd8686_v8.bin" },
88 .model = IF_SDIO_MODEL_8385, 88 { MODEL_8686, "sd8686_helper.bin", "sd8686.bin" },
89 .helper = "sd8385_helper.bin", 89 { MODEL_8688, "libertas/sd8688_helper.bin", "libertas/sd8688.bin" },
90 .firmware = "sd8385.bin", 90 { MODEL_8688, "sd8688_helper.bin", "sd8688.bin" },
91 }, 91 { 0, NULL, NULL }
92 {
93 /* 8686 */
94 .model = IF_SDIO_MODEL_8686,
95 .helper = "sd8686_helper.bin",
96 .firmware = "sd8686.bin",
97 },
98 {
99 /* 8688 */
100 .model = IF_SDIO_MODEL_8688,
101 .helper = "sd8688_helper.bin",
102 .firmware = "sd8688.bin",
103 },
104}; 92};
93MODULE_FIRMWARE("libertas/sd8385_helper.bin");
94MODULE_FIRMWARE("libertas/sd8385.bin");
105MODULE_FIRMWARE("sd8385_helper.bin"); 95MODULE_FIRMWARE("sd8385_helper.bin");
106MODULE_FIRMWARE("sd8385.bin"); 96MODULE_FIRMWARE("sd8385.bin");
97MODULE_FIRMWARE("libertas/sd8686_v9_helper.bin");
98MODULE_FIRMWARE("libertas/sd8686_v9.bin");
99MODULE_FIRMWARE("libertas/sd8686_v8_helper.bin");
100MODULE_FIRMWARE("libertas/sd8686_v8.bin");
107MODULE_FIRMWARE("sd8686_helper.bin"); 101MODULE_FIRMWARE("sd8686_helper.bin");
108MODULE_FIRMWARE("sd8686.bin"); 102MODULE_FIRMWARE("sd8686.bin");
103MODULE_FIRMWARE("libertas/sd8688_helper.bin");
104MODULE_FIRMWARE("libertas/sd8688.bin");
109MODULE_FIRMWARE("sd8688_helper.bin"); 105MODULE_FIRMWARE("sd8688_helper.bin");
110MODULE_FIRMWARE("sd8688.bin"); 106MODULE_FIRMWARE("sd8688.bin");
111 107
@@ -187,11 +183,11 @@ static u16 if_sdio_read_rx_len(struct if_sdio_card *card, int *err)
187 u16 rx_len; 183 u16 rx_len;
188 184
189 switch (card->model) { 185 switch (card->model) {
190 case IF_SDIO_MODEL_8385: 186 case MODEL_8385:
191 case IF_SDIO_MODEL_8686: 187 case MODEL_8686:
192 rx_len = if_sdio_read_scratch(card, &ret); 188 rx_len = if_sdio_read_scratch(card, &ret);
193 break; 189 break;
194 case IF_SDIO_MODEL_8688: 190 case MODEL_8688:
195 default: /* for newer chipsets */ 191 default: /* for newer chipsets */
196 rx_len = sdio_readb(card->func, IF_SDIO_RX_LEN, &ret); 192 rx_len = sdio_readb(card->func, IF_SDIO_RX_LEN, &ret);
197 if (!ret) 193 if (!ret)
@@ -288,7 +284,7 @@ static int if_sdio_handle_event(struct if_sdio_card *card,
288 284
289 lbs_deb_enter(LBS_DEB_SDIO); 285 lbs_deb_enter(LBS_DEB_SDIO);
290 286
291 if (card->model == IF_SDIO_MODEL_8385) { 287 if (card->model == MODEL_8385) {
292 event = sdio_readb(card->func, IF_SDIO_EVENT, &ret); 288 event = sdio_readb(card->func, IF_SDIO_EVENT, &ret);
293 if (ret) 289 if (ret)
294 goto out; 290 goto out;
@@ -466,10 +462,10 @@ static void if_sdio_host_to_card_worker(struct work_struct *work)
466 462
467#define FW_DL_READY_STATUS (IF_SDIO_IO_RDY | IF_SDIO_DL_RDY) 463#define FW_DL_READY_STATUS (IF_SDIO_IO_RDY | IF_SDIO_DL_RDY)
468 464
469static int if_sdio_prog_helper(struct if_sdio_card *card) 465static int if_sdio_prog_helper(struct if_sdio_card *card,
466 const struct firmware *fw)
470{ 467{
471 int ret; 468 int ret;
472 const struct firmware *fw;
473 unsigned long timeout; 469 unsigned long timeout;
474 u8 *chunk_buffer; 470 u8 *chunk_buffer;
475 u32 chunk_size; 471 u32 chunk_size;
@@ -478,16 +474,10 @@ static int if_sdio_prog_helper(struct if_sdio_card *card)
478 474
479 lbs_deb_enter(LBS_DEB_SDIO); 475 lbs_deb_enter(LBS_DEB_SDIO);
480 476
481 ret = request_firmware(&fw, card->helper, &card->func->dev);
482 if (ret) {
483 lbs_pr_err("can't load helper firmware\n");
484 goto out;
485 }
486
487 chunk_buffer = kzalloc(64, GFP_KERNEL); 477 chunk_buffer = kzalloc(64, GFP_KERNEL);
488 if (!chunk_buffer) { 478 if (!chunk_buffer) {
489 ret = -ENOMEM; 479 ret = -ENOMEM;
490 goto release_fw; 480 goto out;
491 } 481 }
492 482
493 sdio_claim_host(card->func); 483 sdio_claim_host(card->func);
@@ -562,22 +552,19 @@ static int if_sdio_prog_helper(struct if_sdio_card *card)
562release: 552release:
563 sdio_release_host(card->func); 553 sdio_release_host(card->func);
564 kfree(chunk_buffer); 554 kfree(chunk_buffer);
565release_fw:
566 release_firmware(fw);
567 555
568out: 556out:
569 if (ret) 557 if (ret)
570 lbs_pr_err("failed to load helper firmware\n"); 558 lbs_pr_err("failed to load helper firmware\n");
571 559
572 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); 560 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
573
574 return ret; 561 return ret;
575} 562}
576 563
577static int if_sdio_prog_real(struct if_sdio_card *card) 564static int if_sdio_prog_real(struct if_sdio_card *card,
565 const struct firmware *fw)
578{ 566{
579 int ret; 567 int ret;
580 const struct firmware *fw;
581 unsigned long timeout; 568 unsigned long timeout;
582 u8 *chunk_buffer; 569 u8 *chunk_buffer;
583 u32 chunk_size; 570 u32 chunk_size;
@@ -586,16 +573,10 @@ static int if_sdio_prog_real(struct if_sdio_card *card)
586 573
587 lbs_deb_enter(LBS_DEB_SDIO); 574 lbs_deb_enter(LBS_DEB_SDIO);
588 575
589 ret = request_firmware(&fw, card->firmware, &card->func->dev);
590 if (ret) {
591 lbs_pr_err("can't load firmware\n");
592 goto out;
593 }
594
595 chunk_buffer = kzalloc(512, GFP_KERNEL); 576 chunk_buffer = kzalloc(512, GFP_KERNEL);
596 if (!chunk_buffer) { 577 if (!chunk_buffer) {
597 ret = -ENOMEM; 578 ret = -ENOMEM;
598 goto release_fw; 579 goto out;
599 } 580 }
600 581
601 sdio_claim_host(card->func); 582 sdio_claim_host(card->func);
@@ -685,15 +666,12 @@ static int if_sdio_prog_real(struct if_sdio_card *card)
685release: 666release:
686 sdio_release_host(card->func); 667 sdio_release_host(card->func);
687 kfree(chunk_buffer); 668 kfree(chunk_buffer);
688release_fw:
689 release_firmware(fw);
690 669
691out: 670out:
692 if (ret) 671 if (ret)
693 lbs_pr_err("failed to load firmware\n"); 672 lbs_pr_err("failed to load firmware\n");
694 673
695 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); 674 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
696
697 return ret; 675 return ret;
698} 676}
699 677
@@ -701,6 +679,8 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card)
701{ 679{
702 int ret; 680 int ret;
703 u16 scratch; 681 u16 scratch;
682 const struct firmware *helper = NULL;
683 const struct firmware *mainfw = NULL;
704 684
705 lbs_deb_enter(LBS_DEB_SDIO); 685 lbs_deb_enter(LBS_DEB_SDIO);
706 686
@@ -718,11 +698,18 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card)
718 goto success; 698 goto success;
719 } 699 }
720 700
721 ret = if_sdio_prog_helper(card); 701 ret = lbs_get_firmware(&card->func->dev, lbs_helper_name, lbs_fw_name,
702 card->model, &fw_table[0], &helper, &mainfw);
703 if (ret) {
704 lbs_pr_err("failed to find firmware (%d)\n", ret);
705 goto out;
706 }
707
708 ret = if_sdio_prog_helper(card, helper);
722 if (ret) 709 if (ret)
723 goto out; 710 goto out;
724 711
725 ret = if_sdio_prog_real(card); 712 ret = if_sdio_prog_real(card, mainfw);
726 if (ret) 713 if (ret)
727 goto out; 714 goto out;
728 715
@@ -733,8 +720,12 @@ success:
733 ret = 0; 720 ret = 0;
734 721
735out: 722out:
736 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); 723 if (helper)
724 release_firmware(helper);
725 if (mainfw)
726 release_firmware(mainfw);
737 727
728 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
738 return ret; 729 return ret;
739} 730}
740 731
@@ -938,7 +929,7 @@ static int if_sdio_probe(struct sdio_func *func,
938 "ID: %x", &model) == 1) 929 "ID: %x", &model) == 1)
939 break; 930 break;
940 if (!strcmp(func->card->info[i], "IBIS Wireless SDIO Card")) { 931 if (!strcmp(func->card->info[i], "IBIS Wireless SDIO Card")) {
941 model = IF_SDIO_MODEL_8385; 932 model = MODEL_8385;
942 break; 933 break;
943 } 934 }
944 } 935 }
@@ -956,13 +947,13 @@ static int if_sdio_probe(struct sdio_func *func,
956 card->model = model; 947 card->model = model;
957 948
958 switch (card->model) { 949 switch (card->model) {
959 case IF_SDIO_MODEL_8385: 950 case MODEL_8385:
960 card->scratch_reg = IF_SDIO_SCRATCH_OLD; 951 card->scratch_reg = IF_SDIO_SCRATCH_OLD;
961 break; 952 break;
962 case IF_SDIO_MODEL_8686: 953 case MODEL_8686:
963 card->scratch_reg = IF_SDIO_SCRATCH; 954 card->scratch_reg = IF_SDIO_SCRATCH;
964 break; 955 break;
965 case IF_SDIO_MODEL_8688: 956 case MODEL_8688:
966 default: /* for newer chipsets */ 957 default: /* for newer chipsets */
967 card->scratch_reg = IF_SDIO_FW_STATUS; 958 card->scratch_reg = IF_SDIO_FW_STATUS;
968 break; 959 break;
@@ -972,49 +963,17 @@ static int if_sdio_probe(struct sdio_func *func,
972 card->workqueue = create_workqueue("libertas_sdio"); 963 card->workqueue = create_workqueue("libertas_sdio");
973 INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker); 964 INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker);
974 965
975 for (i = 0;i < ARRAY_SIZE(if_sdio_models);i++) { 966 /* Check if we support this card */
976 if (card->model == if_sdio_models[i].model) 967 for (i = 0; i < ARRAY_SIZE(fw_table); i++) {
968 if (card->model == fw_table[i].model)
977 break; 969 break;
978 } 970 }
979 971 if (i == ARRAY_SIZE(fw_table)) {
980 if (i == ARRAY_SIZE(if_sdio_models)) {
981 lbs_pr_err("unknown card model 0x%x\n", card->model); 972 lbs_pr_err("unknown card model 0x%x\n", card->model);
982 ret = -ENODEV; 973 ret = -ENODEV;
983 goto free; 974 goto free;
984 } 975 }
985 976
986 card->helper = if_sdio_models[i].helper;
987 card->firmware = if_sdio_models[i].firmware;
988
989 kparam_block_sysfs_write(helper_name);
990 if (lbs_helper_name) {
991 char *helper = kstrdup(lbs_helper_name, GFP_KERNEL);
992 if (!helper) {
993 kparam_unblock_sysfs_write(helper_name);
994 ret = -ENOMEM;
995 goto free;
996 }
997 lbs_deb_sdio("overriding helper firmware: %s\n",
998 lbs_helper_name);
999 card->helper = helper;
1000 card->helper_allocated = true;
1001 }
1002 kparam_unblock_sysfs_write(helper_name);
1003
1004 kparam_block_sysfs_write(fw_name);
1005 if (lbs_fw_name) {
1006 char *fw_name = kstrdup(lbs_fw_name, GFP_KERNEL);
1007 if (!fw_name) {
1008 kparam_unblock_sysfs_write(fw_name);
1009 ret = -ENOMEM;
1010 goto free;
1011 }
1012 lbs_deb_sdio("overriding firmware: %s\n", lbs_fw_name);
1013 card->firmware = fw_name;
1014 card->firmware_allocated = true;
1015 }
1016 kparam_unblock_sysfs_write(fw_name);
1017
1018 sdio_claim_host(func); 977 sdio_claim_host(func);
1019 978
1020 ret = sdio_enable_func(func); 979 ret = sdio_enable_func(func);
@@ -1028,7 +987,7 @@ static int if_sdio_probe(struct sdio_func *func,
1028 /* For 1-bit transfers to the 8686 model, we need to enable the 987 /* For 1-bit transfers to the 8686 model, we need to enable the
1029 * interrupt flag in the CCCR register. Set the MMC_QUIRK_LENIENT_FN0 988 * interrupt flag in the CCCR register. Set the MMC_QUIRK_LENIENT_FN0
1030 * bit to allow access to non-vendor registers. */ 989 * bit to allow access to non-vendor registers. */
1031 if ((card->model == IF_SDIO_MODEL_8686) && 990 if ((card->model == MODEL_8686) &&
1032 (host->caps & MMC_CAP_SDIO_IRQ) && 991 (host->caps & MMC_CAP_SDIO_IRQ) &&
1033 (host->ios.bus_width == MMC_BUS_WIDTH_1)) { 992 (host->ios.bus_width == MMC_BUS_WIDTH_1)) {
1034 u8 reg; 993 u8 reg;
@@ -1091,8 +1050,8 @@ static int if_sdio_probe(struct sdio_func *func,
1091 * Get rx_unit if the chip is SD8688 or newer. 1050 * Get rx_unit if the chip is SD8688 or newer.
1092 * SD8385 & SD8686 do not have rx_unit. 1051 * SD8385 & SD8686 do not have rx_unit.
1093 */ 1052 */
1094 if ((card->model != IF_SDIO_MODEL_8385) 1053 if ((card->model != MODEL_8385)
1095 && (card->model != IF_SDIO_MODEL_8686)) 1054 && (card->model != MODEL_8686))
1096 card->rx_unit = if_sdio_read_rx_unit(card); 1055 card->rx_unit = if_sdio_read_rx_unit(card);
1097 else 1056 else
1098 card->rx_unit = 0; 1057 card->rx_unit = 0;
@@ -1108,7 +1067,7 @@ static int if_sdio_probe(struct sdio_func *func,
1108 /* 1067 /*
1109 * FUNC_INIT is required for SD8688 WLAN/BT multiple functions 1068 * FUNC_INIT is required for SD8688 WLAN/BT multiple functions
1110 */ 1069 */
1111 if (card->model == IF_SDIO_MODEL_8688) { 1070 if (card->model == MODEL_8688) {
1112 struct cmd_header cmd; 1071 struct cmd_header cmd;
1113 1072
1114 memset(&cmd, 0, sizeof(cmd)); 1073 memset(&cmd, 0, sizeof(cmd));
@@ -1165,7 +1124,7 @@ static void if_sdio_remove(struct sdio_func *func)
1165 1124
1166 card = sdio_get_drvdata(func); 1125 card = sdio_get_drvdata(func);
1167 1126
1168 if (user_rmmod && (card->model == IF_SDIO_MODEL_8688)) { 1127 if (user_rmmod && (card->model == MODEL_8688)) {
1169 /* 1128 /*
1170 * FUNC_SHUTDOWN is required for SD8688 WLAN/BT 1129 * FUNC_SHUTDOWN is required for SD8688 WLAN/BT
1171 * multiple functions 1130 * multiple functions
diff --git a/drivers/net/wireless/libertas/if_sdio.h b/drivers/net/wireless/libertas/if_sdio.h
index 12179c1dc9c..62fda3592f6 100644
--- a/drivers/net/wireless/libertas/if_sdio.h
+++ b/drivers/net/wireless/libertas/if_sdio.h
@@ -12,10 +12,6 @@
12#ifndef _LBS_IF_SDIO_H 12#ifndef _LBS_IF_SDIO_H
13#define _LBS_IF_SDIO_H 13#define _LBS_IF_SDIO_H
14 14
15#define IF_SDIO_MODEL_8385 0x04
16#define IF_SDIO_MODEL_8686 0x0b
17#define IF_SDIO_MODEL_8688 0x10
18
19#define IF_SDIO_IOPORT 0x00 15#define IF_SDIO_IOPORT 0x00
20 16
21#define IF_SDIO_H_INT_MASK 0x04 17#define IF_SDIO_H_INT_MASK 0x04
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index fe3f08028eb..79bcb4e5d2c 100644
--- a/drivers/net/wireless/libertas/if_spi.c
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -39,9 +39,6 @@ struct if_spi_card {
39 struct lbs_private *priv; 39 struct lbs_private *priv;
40 struct libertas_spi_platform_data *pdata; 40 struct libertas_spi_platform_data *pdata;
41 41
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. */ 42 /* The card ID and card revision, as reported by the hardware. */
46 u16 card_id; 43 u16 card_id;
47 u8 card_rev; 44 u8 card_rev;
@@ -70,10 +67,28 @@ static void free_if_spi_card(struct if_spi_card *card)
70 kfree(card); 67 kfree(card);
71} 68}
72 69
73static struct chip_ident chip_id_to_device_name[] = { 70#define MODEL_8385 0x04
74 { .chip_id = 0x04, .name = 8385 }, 71#define MODEL_8686 0x0b
75 { .chip_id = 0x0b, .name = 8686 }, 72#define MODEL_8688 0x10
73
74static const struct lbs_fw_table fw_table[] = {
75 { MODEL_8385, "libertas/gspi8385_helper.bin", "libertas/gspi8385.bin" },
76 { MODEL_8385, "libertas/gspi8385_hlp.bin", "libertas/gspi8385.bin" },
77 { MODEL_8686, "libertas/gspi8686_v9_helper.bin", "libertas/gspi8686_v9.bin" },
78 { MODEL_8686, "libertas/gspi8686_hlp.bin", "libertas/gspi8686.bin" },
79 { MODEL_8688, "libertas/gspi8688_helper.bin", "libertas/gspi8688.bin" },
80 { 0, NULL, NULL }
76}; 81};
82MODULE_FIRMWARE("libertas/gspi8385_helper.bin");
83MODULE_FIRMWARE("libertas/gspi8385_hlp.bin");
84MODULE_FIRMWARE("libertas/gspi8385.bin");
85MODULE_FIRMWARE("libertas/gspi8686_v9_helper.bin");
86MODULE_FIRMWARE("libertas/gspi8686_v9.bin");
87MODULE_FIRMWARE("libertas/gspi8686_hlp.bin");
88MODULE_FIRMWARE("libertas/gspi8686.bin");
89MODULE_FIRMWARE("libertas/gspi8688_helper.bin");
90MODULE_FIRMWARE("libertas/gspi8688.bin");
91
77 92
78/* 93/*
79 * SPI Interface Unit Routines 94 * SPI Interface Unit Routines
@@ -399,26 +414,20 @@ static int spu_init(struct if_spi_card *card, int use_dummy_writes)
399 * Firmware Loading 414 * Firmware Loading
400 */ 415 */
401 416
402static int if_spi_prog_helper_firmware(struct if_spi_card *card) 417static int if_spi_prog_helper_firmware(struct if_spi_card *card,
418 const struct firmware *firmware)
403{ 419{
404 int err = 0; 420 int err = 0;
405 const struct firmware *firmware = NULL;
406 int bytes_remaining; 421 int bytes_remaining;
407 const u8 *fw; 422 const u8 *fw;
408 u8 temp[HELPER_FW_LOAD_CHUNK_SZ]; 423 u8 temp[HELPER_FW_LOAD_CHUNK_SZ];
409 struct spi_device *spi = card->spi;
410 424
411 lbs_deb_enter(LBS_DEB_SPI); 425 lbs_deb_enter(LBS_DEB_SPI);
412 426
413 err = spu_set_interrupt_mode(card, 1, 0); 427 err = spu_set_interrupt_mode(card, 1, 0);
414 if (err) 428 if (err)
415 goto out; 429 goto out;
416 /* Get helper firmware image */ 430
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; 431 bytes_remaining = firmware->size;
423 fw = firmware->data; 432 fw = firmware->data;
424 433
@@ -429,13 +438,13 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card)
429 err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG, 438 err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG,
430 HELPER_FW_LOAD_CHUNK_SZ); 439 HELPER_FW_LOAD_CHUNK_SZ);
431 if (err) 440 if (err)
432 goto release_firmware; 441 goto out;
433 442
434 err = spu_wait_for_u16(card, IF_SPI_HOST_INT_STATUS_REG, 443 err = spu_wait_for_u16(card, IF_SPI_HOST_INT_STATUS_REG,
435 IF_SPI_HIST_CMD_DOWNLOAD_RDY, 444 IF_SPI_HIST_CMD_DOWNLOAD_RDY,
436 IF_SPI_HIST_CMD_DOWNLOAD_RDY); 445 IF_SPI_HIST_CMD_DOWNLOAD_RDY);
437 if (err) 446 if (err)
438 goto release_firmware; 447 goto out;
439 448
440 /* Feed the data into the command read/write port reg 449 /* Feed the data into the command read/write port reg
441 * in chunks of 64 bytes */ 450 * in chunks of 64 bytes */
@@ -446,16 +455,16 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card)
446 err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG, 455 err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG,
447 temp, HELPER_FW_LOAD_CHUNK_SZ); 456 temp, HELPER_FW_LOAD_CHUNK_SZ);
448 if (err) 457 if (err)
449 goto release_firmware; 458 goto out;
450 459
451 /* Interrupt the boot code */ 460 /* Interrupt the boot code */
452 err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0); 461 err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0);
453 if (err) 462 if (err)
454 goto release_firmware; 463 goto out;
455 err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG, 464 err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG,
456 IF_SPI_CIC_CMD_DOWNLOAD_OVER); 465 IF_SPI_CIC_CMD_DOWNLOAD_OVER);
457 if (err) 466 if (err)
458 goto release_firmware; 467 goto out;
459 bytes_remaining -= HELPER_FW_LOAD_CHUNK_SZ; 468 bytes_remaining -= HELPER_FW_LOAD_CHUNK_SZ;
460 fw += HELPER_FW_LOAD_CHUNK_SZ; 469 fw += HELPER_FW_LOAD_CHUNK_SZ;
461 } 470 }
@@ -465,18 +474,16 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card)
465 * bootloader. This completes the helper download. */ 474 * bootloader. This completes the helper download. */
466 err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG, FIRMWARE_DNLD_OK); 475 err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG, FIRMWARE_DNLD_OK);
467 if (err) 476 if (err)
468 goto release_firmware; 477 goto out;
469 err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0); 478 err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0);
470 if (err) 479 if (err)
471 goto release_firmware; 480 goto out;
472 err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG, 481 err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG,
473 IF_SPI_CIC_CMD_DOWNLOAD_OVER); 482 IF_SPI_CIC_CMD_DOWNLOAD_OVER);
474 goto release_firmware; 483 goto out;
475 484
476 lbs_deb_spi("waiting for helper to boot...\n"); 485 lbs_deb_spi("waiting for helper to boot...\n");
477 486
478release_firmware:
479 release_firmware(firmware);
480out: 487out:
481 if (err) 488 if (err)
482 lbs_pr_err("failed to load helper firmware (err=%d)\n", err); 489 lbs_pr_err("failed to load helper firmware (err=%d)\n", err);
@@ -523,13 +530,12 @@ static int if_spi_prog_main_firmware_check_len(struct if_spi_card *card,
523 return len; 530 return len;
524} 531}
525 532
526static int if_spi_prog_main_firmware(struct if_spi_card *card) 533static int if_spi_prog_main_firmware(struct if_spi_card *card,
534 const struct firmware *firmware)
527{ 535{
528 int len, prev_len; 536 int len, prev_len;
529 int bytes, crc_err = 0, err = 0; 537 int bytes, crc_err = 0, err = 0;
530 const struct firmware *firmware = NULL;
531 const u8 *fw; 538 const u8 *fw;
532 struct spi_device *spi = card->spi;
533 u16 num_crc_errs; 539 u16 num_crc_errs;
534 540
535 lbs_deb_enter(LBS_DEB_SPI); 541 lbs_deb_enter(LBS_DEB_SPI);
@@ -538,19 +544,11 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card)
538 if (err) 544 if (err)
539 goto out; 545 goto out;
540 546
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); 547 err = spu_wait_for_u16(card, IF_SPI_SCRATCH_1_REG, 0, 0);
550 if (err) { 548 if (err) {
551 lbs_pr_err("%s: timed out waiting for initial " 549 lbs_pr_err("%s: timed out waiting for initial "
552 "scratch reg = 0\n", __func__); 550 "scratch reg = 0\n", __func__);
553 goto release_firmware; 551 goto out;
554 } 552 }
555 553
556 num_crc_errs = 0; 554 num_crc_errs = 0;
@@ -560,7 +558,7 @@ 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))) { 558 while ((len = if_spi_prog_main_firmware_check_len(card, &crc_err))) {
561 if (len < 0) { 559 if (len < 0) {
562 err = len; 560 err = len;
563 goto release_firmware; 561 goto out;
564 } 562 }
565 if (bytes < 0) { 563 if (bytes < 0) {
566 /* If there are no more bytes left, we would normally 564 /* If there are no more bytes left, we would normally
@@ -575,7 +573,7 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card)
575 lbs_pr_err("Too many CRC errors encountered " 573 lbs_pr_err("Too many CRC errors encountered "
576 "in firmware load.\n"); 574 "in firmware load.\n");
577 err = -EIO; 575 err = -EIO;
578 goto release_firmware; 576 goto out;
579 } 577 }
580 } else { 578 } else {
581 /* Previous transfer succeeded. Advance counters. */ 579 /* Previous transfer succeeded. Advance counters. */
@@ -590,15 +588,15 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card)
590 588
591 err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0); 589 err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0);
592 if (err) 590 if (err)
593 goto release_firmware; 591 goto out;
594 err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG, 592 err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG,
595 card->cmd_buffer, len); 593 card->cmd_buffer, len);
596 if (err) 594 if (err)
597 goto release_firmware; 595 goto out;
598 err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG , 596 err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG ,
599 IF_SPI_CIC_CMD_DOWNLOAD_OVER); 597 IF_SPI_CIC_CMD_DOWNLOAD_OVER);
600 if (err) 598 if (err)
601 goto release_firmware; 599 goto out;
602 prev_len = len; 600 prev_len = len;
603 } 601 }
604 if (bytes > prev_len) { 602 if (bytes > prev_len) {
@@ -611,12 +609,9 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card)
611 SUCCESSFUL_FW_DOWNLOAD_MAGIC); 609 SUCCESSFUL_FW_DOWNLOAD_MAGIC);
612 if (err) { 610 if (err) {
613 lbs_pr_err("failed to confirm the firmware download\n"); 611 lbs_pr_err("failed to confirm the firmware download\n");
614 goto release_firmware; 612 goto out;
615 } 613 }
616 614
617release_firmware:
618 release_firmware(firmware);
619
620out: 615out:
621 if (err) 616 if (err)
622 lbs_pr_err("failed to load firmware (err=%d)\n", err); 617 lbs_pr_err("failed to load firmware (err=%d)\n", err);
@@ -800,14 +795,16 @@ static int lbs_spi_thread(void *data)
800 goto err; 795 goto err;
801 } 796 }
802 797
803 if (hiStatus & IF_SPI_HIST_CMD_UPLOAD_RDY) 798 if (hiStatus & IF_SPI_HIST_CMD_UPLOAD_RDY) {
804 err = if_spi_c2h_cmd(card); 799 err = if_spi_c2h_cmd(card);
805 if (err) 800 if (err)
806 goto err; 801 goto err;
807 if (hiStatus & IF_SPI_HIST_RX_UPLOAD_RDY) 802 }
803 if (hiStatus & IF_SPI_HIST_RX_UPLOAD_RDY) {
808 err = if_spi_c2h_data(card); 804 err = if_spi_c2h_data(card);
809 if (err) 805 if (err)
810 goto err; 806 goto err;
807 }
811 808
812 /* workaround: in PS mode, the card does not set the Command 809 /* workaround: in PS mode, the card does not set the Command
813 * Download Ready bit, but it sets TX Download Ready. */ 810 * Download Ready bit, but it sets TX Download Ready. */
@@ -886,37 +883,16 @@ static irqreturn_t if_spi_host_interrupt(int irq, void *dev_id)
886 * SPI callbacks 883 * SPI callbacks
887 */ 884 */
888 885
889static int if_spi_calculate_fw_names(u16 card_id,
890 char *helper_fw, char *main_fw)
891{
892 int i;
893 for (i = 0; i < ARRAY_SIZE(chip_id_to_device_name); ++i) {
894 if (card_id == chip_id_to_device_name[i].chip_id)
895 break;
896 }
897 if (i == ARRAY_SIZE(chip_id_to_device_name)) {
898 lbs_pr_err("Unsupported chip_id: 0x%02x\n", card_id);
899 return -EAFNOSUPPORT;
900 }
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}
907MODULE_FIRMWARE("libertas/gspi8385_hlp.bin");
908MODULE_FIRMWARE("libertas/gspi8385.bin");
909MODULE_FIRMWARE("libertas/gspi8686_hlp.bin");
910MODULE_FIRMWARE("libertas/gspi8686.bin");
911
912static int __devinit if_spi_probe(struct spi_device *spi) 886static int __devinit if_spi_probe(struct spi_device *spi)
913{ 887{
914 struct if_spi_card *card; 888 struct if_spi_card *card;
915 struct lbs_private *priv = NULL; 889 struct lbs_private *priv = NULL;
916 struct libertas_spi_platform_data *pdata = spi->dev.platform_data; 890 struct libertas_spi_platform_data *pdata = spi->dev.platform_data;
917 int err = 0; 891 int err = 0, i;
918 u32 scratch; 892 u32 scratch;
919 struct sched_param param = { .sched_priority = 1 }; 893 struct sched_param param = { .sched_priority = 1 };
894 const struct firmware *helper = NULL;
895 const struct firmware *mainfw = NULL;
920 896
921 lbs_deb_enter(LBS_DEB_SPI); 897 lbs_deb_enter(LBS_DEB_SPI);
922 898
@@ -961,10 +937,25 @@ static int __devinit if_spi_probe(struct spi_device *spi)
961 lbs_deb_spi("Firmware is already loaded for " 937 lbs_deb_spi("Firmware is already loaded for "
962 "Marvell WLAN 802.11 adapter\n"); 938 "Marvell WLAN 802.11 adapter\n");
963 else { 939 else {
964 err = if_spi_calculate_fw_names(card->card_id, 940 /* Check if we support this card */
965 card->helper_fw_name, card->main_fw_name); 941 for (i = 0; i < ARRAY_SIZE(fw_table); i++) {
966 if (err) 942 if (card->card_id == fw_table[i].model)
943 break;
944 }
945 if (i == ARRAY_SIZE(fw_table)) {
946 lbs_pr_err("Unsupported chip_id: 0x%02x\n",
947 card->card_id);
948 err = -ENODEV;
967 goto free_card; 949 goto free_card;
950 }
951
952 err = lbs_get_firmware(&card->spi->dev, NULL, NULL,
953 card->card_id, &fw_table[0], &helper,
954 &mainfw);
955 if (err) {
956 lbs_pr_err("failed to find firmware (%d)\n", err);
957 goto free_card;
958 }
968 959
969 lbs_deb_spi("Initializing FW for Marvell WLAN 802.11 adapter " 960 lbs_deb_spi("Initializing FW for Marvell WLAN 802.11 adapter "
970 "(chip_id = 0x%04x, chip_rev = 0x%02x) " 961 "(chip_id = 0x%04x, chip_rev = 0x%02x) "
@@ -973,10 +964,10 @@ static int __devinit if_spi_probe(struct spi_device *spi)
973 card->card_id, card->card_rev, 964 card->card_id, card->card_rev,
974 spi->master->bus_num, spi->chip_select, 965 spi->master->bus_num, spi->chip_select,
975 spi->max_speed_hz); 966 spi->max_speed_hz);
976 err = if_spi_prog_helper_firmware(card); 967 err = if_spi_prog_helper_firmware(card, helper);
977 if (err) 968 if (err)
978 goto free_card; 969 goto free_card;
979 err = if_spi_prog_main_firmware(card); 970 err = if_spi_prog_main_firmware(card, mainfw);
980 if (err) 971 if (err)
981 goto free_card; 972 goto free_card;
982 lbs_deb_spi("loaded FW for Marvell WLAN 802.11 adapter\n"); 973 lbs_deb_spi("loaded FW for Marvell WLAN 802.11 adapter\n");
@@ -1044,6 +1035,11 @@ remove_card:
1044free_card: 1035free_card:
1045 free_if_spi_card(card); 1036 free_if_spi_card(card);
1046out: 1037out:
1038 if (helper)
1039 release_firmware(helper);
1040 if (mainfw)
1041 release_firmware(mainfw);
1042
1047 lbs_deb_leave_args(LBS_DEB_SPI, "err %d\n", err); 1043 lbs_deb_leave_args(LBS_DEB_SPI, "err %d\n", err);
1048 return err; 1044 return err;
1049} 1045}
diff --git a/drivers/net/wireless/libertas/if_spi.h b/drivers/net/wireless/libertas/if_spi.h
index f87eec41084..8b1417d3b71 100644
--- a/drivers/net/wireless/libertas/if_spi.h
+++ b/drivers/net/wireless/libertas/if_spi.h
@@ -25,11 +25,6 @@
25 25
26#define IF_SPI_FW_NAME_MAX 30 26#define IF_SPI_FW_NAME_MAX 30
27 27
28struct chip_ident {
29 u16 chip_id;
30 u16 name;
31};
32
33#define MAX_MAIN_FW_LOAD_CRC_ERR 10 28#define MAX_MAIN_FW_LOAD_CRC_ERR 10
34 29
35/* Chunk size when loading the helper firmware */ 30/* Chunk size when loading the helper firmware */
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index 3ff61063671..e906616232a 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -26,15 +26,25 @@
26 26
27#define MESSAGE_HEADER_LEN 4 27#define MESSAGE_HEADER_LEN 4
28 28
29static char *lbs_fw_name = "usb8388.bin"; 29static char *lbs_fw_name = NULL;
30module_param_named(fw_name, lbs_fw_name, charp, 0644); 30module_param_named(fw_name, lbs_fw_name, charp, 0644);
31 31
32MODULE_FIRMWARE("libertas/usb8388_v9.bin");
33MODULE_FIRMWARE("libertas/usb8388_v5.bin");
34MODULE_FIRMWARE("libertas/usb8388.bin");
35MODULE_FIRMWARE("libertas/usb8682.bin");
32MODULE_FIRMWARE("usb8388.bin"); 36MODULE_FIRMWARE("usb8388.bin");
33 37
38enum {
39 MODEL_UNKNOWN = 0x0,
40 MODEL_8388 = 0x1,
41 MODEL_8682 = 0x2
42};
43
34static struct usb_device_id if_usb_table[] = { 44static struct usb_device_id if_usb_table[] = {
35 /* Enter the device signature inside */ 45 /* Enter the device signature inside */
36 { USB_DEVICE(0x1286, 0x2001) }, 46 { USB_DEVICE(0x1286, 0x2001), .driver_info = MODEL_8388 },
37 { USB_DEVICE(0x05a3, 0x8388) }, 47 { USB_DEVICE(0x05a3, 0x8388), .driver_info = MODEL_8388 },
38 {} /* Terminating entry */ 48 {} /* Terminating entry */
39}; 49};
40 50
@@ -66,6 +76,8 @@ static ssize_t if_usb_firmware_set(struct device *dev,
66 struct if_usb_card *cardp = priv->card; 76 struct if_usb_card *cardp = priv->card;
67 int ret; 77 int ret;
68 78
79 BUG_ON(buf == NULL);
80
69 ret = if_usb_prog_firmware(cardp, buf, BOOT_CMD_UPDATE_FW); 81 ret = if_usb_prog_firmware(cardp, buf, BOOT_CMD_UPDATE_FW);
70 if (ret == 0) 82 if (ret == 0)
71 return count; 83 return count;
@@ -91,6 +103,8 @@ static ssize_t if_usb_boot2_set(struct device *dev,
91 struct if_usb_card *cardp = priv->card; 103 struct if_usb_card *cardp = priv->card;
92 int ret; 104 int ret;
93 105
106 BUG_ON(buf == NULL);
107
94 ret = if_usb_prog_firmware(cardp, buf, BOOT_CMD_UPDATE_BOOT2); 108 ret = if_usb_prog_firmware(cardp, buf, BOOT_CMD_UPDATE_BOOT2);
95 if (ret == 0) 109 if (ret == 0)
96 return count; 110 return count;
@@ -244,6 +258,7 @@ static int if_usb_probe(struct usb_interface *intf,
244 init_waitqueue_head(&cardp->fw_wq); 258 init_waitqueue_head(&cardp->fw_wq);
245 259
246 cardp->udev = udev; 260 cardp->udev = udev;
261 cardp->model = (uint32_t) id->driver_info;
247 iface_desc = intf->cur_altsetting; 262 iface_desc = intf->cur_altsetting;
248 263
249 lbs_deb_usbd(&udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X" 264 lbs_deb_usbd(&udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X"
@@ -924,6 +939,38 @@ static int if_usb_prog_firmware(struct if_usb_card *cardp,
924 return ret; 939 return ret;
925} 940}
926 941
942/* table of firmware file names */
943static const struct {
944 u32 model;
945 const char *fwname;
946} fw_table[] = {
947 { MODEL_8388, "libertas/usb8388_v9.bin" },
948 { MODEL_8388, "libertas/usb8388_v5.bin" },
949 { MODEL_8388, "libertas/usb8388.bin" },
950 { MODEL_8388, "usb8388.bin" },
951 { MODEL_8682, "libertas/usb8682.bin" }
952};
953
954static int get_fw(struct if_usb_card *cardp, const char *fwname)
955{
956 int i;
957
958 /* Try user-specified firmware first */
959 if (fwname)
960 return request_firmware(&cardp->fw, fwname, &cardp->udev->dev);
961
962 /* Otherwise search for firmware to use */
963 for (i = 0; i < ARRAY_SIZE(fw_table); i++) {
964 if (fw_table[i].model != cardp->model)
965 continue;
966 if (request_firmware(&cardp->fw, fw_table[i].fwname,
967 &cardp->udev->dev) == 0)
968 return 0;
969 }
970
971 return -ENOENT;
972}
973
927static int __if_usb_prog_firmware(struct if_usb_card *cardp, 974static int __if_usb_prog_firmware(struct if_usb_card *cardp,
928 const char *fwname, int cmd) 975 const char *fwname, int cmd)
929{ 976{
@@ -933,10 +980,9 @@ static int __if_usb_prog_firmware(struct if_usb_card *cardp,
933 980
934 lbs_deb_enter(LBS_DEB_USB); 981 lbs_deb_enter(LBS_DEB_USB);
935 982
936 ret = request_firmware(&cardp->fw, fwname, &cardp->udev->dev); 983 ret = get_fw(cardp, fwname);
937 if (ret < 0) { 984 if (ret) {
938 lbs_pr_err("request_firmware() failed with %#x\n", ret); 985 lbs_pr_err("failed to find firmware (%d)\n", ret);
939 lbs_pr_err("firmware %s not found\n", fwname);
940 goto done; 986 goto done;
941 } 987 }
942 988
diff --git a/drivers/net/wireless/libertas/if_usb.h b/drivers/net/wireless/libertas/if_usb.h
index 5ba0aee0eb2..d819e7e3c9a 100644
--- a/drivers/net/wireless/libertas/if_usb.h
+++ b/drivers/net/wireless/libertas/if_usb.h
@@ -43,6 +43,7 @@ struct bootcmdresp
43/** USB card description structure*/ 43/** USB card description structure*/
44struct if_usb_card { 44struct if_usb_card {
45 struct usb_device *udev; 45 struct usb_device *udev;
46 uint32_t model; /* MODEL_* */
46 struct urb *rx_urb, *tx_urb; 47 struct urb *rx_urb, *tx_urb;
47 struct lbs_private *priv; 48 struct lbs_private *priv;
48 49
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 24958a86747..47ce5a6ba12 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -1047,6 +1047,111 @@ void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx)
1047} 1047}
1048EXPORT_SYMBOL_GPL(lbs_notify_command_response); 1048EXPORT_SYMBOL_GPL(lbs_notify_command_response);
1049 1049
1050/**
1051 * @brief Retrieves two-stage firmware
1052 *
1053 * @param dev A pointer to device structure
1054 * @param user_helper User-defined helper firmware file
1055 * @param user_mainfw User-defined main firmware file
1056 * @param card_model Bus-specific card model ID used to filter firmware table
1057 * elements
1058 * @param fw_table Table of firmware file names and device model numbers
1059 * terminated by an entry with a NULL helper name
1060 * @param helper On success, the helper firmware; caller must free
1061 * @param mainfw On success, the main firmware; caller must free
1062 *
1063 * @return 0 on success, non-zero on failure
1064 */
1065int lbs_get_firmware(struct device *dev, const char *user_helper,
1066 const char *user_mainfw, u32 card_model,
1067 const struct lbs_fw_table *fw_table,
1068 const struct firmware **helper,
1069 const struct firmware **mainfw)
1070{
1071 const struct lbs_fw_table *iter;
1072 int ret;
1073
1074 BUG_ON(helper == NULL);
1075 BUG_ON(mainfw == NULL);
1076
1077 /* Try user-specified firmware first */
1078 if (user_helper) {
1079 ret = request_firmware(helper, user_helper, dev);
1080 if (ret) {
1081 lbs_pr_err("couldn't find helper firmware %s",
1082 user_helper);
1083 goto fail;
1084 }
1085 }
1086 if (user_mainfw) {
1087 ret = request_firmware(mainfw, user_mainfw, dev);
1088 if (ret) {
1089 lbs_pr_err("couldn't find main firmware %s",
1090 user_mainfw);
1091 goto fail;
1092 }
1093 }
1094
1095 if (*helper && *mainfw)
1096 return 0;
1097
1098 /* Otherwise search for firmware to use. If neither the helper or
1099 * the main firmware were specified by the user, then we need to
1100 * make sure that found helper & main are from the same entry in
1101 * fw_table.
1102 */
1103 iter = fw_table;
1104 while (iter && iter->helper) {
1105 if (iter->model != card_model)
1106 goto next;
1107
1108 if (*helper == NULL) {
1109 ret = request_firmware(helper, iter->helper, dev);
1110 if (ret)
1111 goto next;
1112
1113 /* If the device has one-stage firmware (ie cf8305) and
1114 * we've got it then we don't need to bother with the
1115 * main firmware.
1116 */
1117 if (iter->fwname == NULL)
1118 return 0;
1119 }
1120
1121 if (*mainfw == NULL) {
1122 ret = request_firmware(mainfw, iter->fwname, dev);
1123 if (ret && !user_helper) {
1124 /* Clear the helper if it wasn't user-specified
1125 * and the main firmware load failed, to ensure
1126 * we don't have mismatched firmware pairs.
1127 */
1128 release_firmware(*helper);
1129 *helper = NULL;
1130 }
1131 }
1132
1133 if (*helper && *mainfw)
1134 return 0;
1135
1136 next:
1137 iter++;
1138 }
1139
1140 fail:
1141 /* Failed */
1142 if (*helper) {
1143 release_firmware(*helper);
1144 *helper = NULL;
1145 }
1146 if (*mainfw) {
1147 release_firmware(*mainfw);
1148 *mainfw = NULL;
1149 }
1150
1151 return -ENOENT;
1152}
1153EXPORT_SYMBOL_GPL(lbs_get_firmware);
1154
1050static int __init lbs_init_module(void) 1155static int __init lbs_init_module(void)
1051{ 1156{
1052 lbs_deb_enter(LBS_DEB_MAIN); 1157 lbs_deb_enter(LBS_DEB_MAIN);