aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2010-08-07 22:15:52 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-08-16 15:26:43 -0400
commit3d32a58b87cd251b50842f93b87d5458061c0cfc (patch)
tree983efdd808d72edefde2f54f3d938c40fb5e53fc /drivers/net
parent82222e9ba75298e5bcd89803b6a11e2d7dfae70e (diff)
libertas: [sdio] use common firmware request helper and new firmware locations
linux-firmware puts libertas firmware in /libertas. Fix the driver to look there first, but fall back to the old firmware names if the new ones don't exist. Add preference for newer firmware versions too. Signed-off-by: Dan Williams <dcbw@redhat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c143
-rw-r--r--drivers/net/wireless/libertas/if_sdio.h4
2 files changed, 60 insertions, 87 deletions
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 6e71346a7550..024e5ca7b7f3 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
@@ -185,11 +181,11 @@ static u16 if_sdio_read_rx_len(struct if_sdio_card *card, int *err)
185 u16 rx_len; 181 u16 rx_len;
186 182
187 switch (card->model) { 183 switch (card->model) {
188 case IF_SDIO_MODEL_8385: 184 case MODEL_8385:
189 case IF_SDIO_MODEL_8686: 185 case MODEL_8686:
190 rx_len = if_sdio_read_scratch(card, &ret); 186 rx_len = if_sdio_read_scratch(card, &ret);
191 break; 187 break;
192 case IF_SDIO_MODEL_8688: 188 case MODEL_8688:
193 default: /* for newer chipsets */ 189 default: /* for newer chipsets */
194 rx_len = sdio_readb(card->func, IF_SDIO_RX_LEN, &ret); 190 rx_len = sdio_readb(card->func, IF_SDIO_RX_LEN, &ret);
195 if (!ret) 191 if (!ret)
@@ -286,7 +282,7 @@ static int if_sdio_handle_event(struct if_sdio_card *card,
286 282
287 lbs_deb_enter(LBS_DEB_SDIO); 283 lbs_deb_enter(LBS_DEB_SDIO);
288 284
289 if (card->model == IF_SDIO_MODEL_8385) { 285 if (card->model == MODEL_8385) {
290 event = sdio_readb(card->func, IF_SDIO_EVENT, &ret); 286 event = sdio_readb(card->func, IF_SDIO_EVENT, &ret);
291 if (ret) 287 if (ret)
292 goto out; 288 goto out;
@@ -464,10 +460,10 @@ static void if_sdio_host_to_card_worker(struct work_struct *work)
464 460
465#define FW_DL_READY_STATUS (IF_SDIO_IO_RDY | IF_SDIO_DL_RDY) 461#define FW_DL_READY_STATUS (IF_SDIO_IO_RDY | IF_SDIO_DL_RDY)
466 462
467static int if_sdio_prog_helper(struct if_sdio_card *card) 463static int if_sdio_prog_helper(struct if_sdio_card *card,
464 const struct firmware *fw)
468{ 465{
469 int ret; 466 int ret;
470 const struct firmware *fw;
471 unsigned long timeout; 467 unsigned long timeout;
472 u8 *chunk_buffer; 468 u8 *chunk_buffer;
473 u32 chunk_size; 469 u32 chunk_size;
@@ -476,16 +472,10 @@ static int if_sdio_prog_helper(struct if_sdio_card *card)
476 472
477 lbs_deb_enter(LBS_DEB_SDIO); 473 lbs_deb_enter(LBS_DEB_SDIO);
478 474
479 ret = request_firmware(&fw, card->helper, &card->func->dev);
480 if (ret) {
481 lbs_pr_err("can't load helper firmware\n");
482 goto out;
483 }
484
485 chunk_buffer = kzalloc(64, GFP_KERNEL); 475 chunk_buffer = kzalloc(64, GFP_KERNEL);
486 if (!chunk_buffer) { 476 if (!chunk_buffer) {
487 ret = -ENOMEM; 477 ret = -ENOMEM;
488 goto release_fw; 478 goto out;
489 } 479 }
490 480
491 sdio_claim_host(card->func); 481 sdio_claim_host(card->func);
@@ -560,22 +550,19 @@ static int if_sdio_prog_helper(struct if_sdio_card *card)
560release: 550release:
561 sdio_release_host(card->func); 551 sdio_release_host(card->func);
562 kfree(chunk_buffer); 552 kfree(chunk_buffer);
563release_fw:
564 release_firmware(fw);
565 553
566out: 554out:
567 if (ret) 555 if (ret)
568 lbs_pr_err("failed to load helper firmware\n"); 556 lbs_pr_err("failed to load helper firmware\n");
569 557
570 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); 558 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
571
572 return ret; 559 return ret;
573} 560}
574 561
575static int if_sdio_prog_real(struct if_sdio_card *card) 562static int if_sdio_prog_real(struct if_sdio_card *card,
563 const struct firmware *fw)
576{ 564{
577 int ret; 565 int ret;
578 const struct firmware *fw;
579 unsigned long timeout; 566 unsigned long timeout;
580 u8 *chunk_buffer; 567 u8 *chunk_buffer;
581 u32 chunk_size; 568 u32 chunk_size;
@@ -584,16 +571,10 @@ static int if_sdio_prog_real(struct if_sdio_card *card)
584 571
585 lbs_deb_enter(LBS_DEB_SDIO); 572 lbs_deb_enter(LBS_DEB_SDIO);
586 573
587 ret = request_firmware(&fw, card->firmware, &card->func->dev);
588 if (ret) {
589 lbs_pr_err("can't load firmware\n");
590 goto out;
591 }
592
593 chunk_buffer = kzalloc(512, GFP_KERNEL); 574 chunk_buffer = kzalloc(512, GFP_KERNEL);
594 if (!chunk_buffer) { 575 if (!chunk_buffer) {
595 ret = -ENOMEM; 576 ret = -ENOMEM;
596 goto release_fw; 577 goto out;
597 } 578 }
598 579
599 sdio_claim_host(card->func); 580 sdio_claim_host(card->func);
@@ -683,15 +664,12 @@ static int if_sdio_prog_real(struct if_sdio_card *card)
683release: 664release:
684 sdio_release_host(card->func); 665 sdio_release_host(card->func);
685 kfree(chunk_buffer); 666 kfree(chunk_buffer);
686release_fw:
687 release_firmware(fw);
688 667
689out: 668out:
690 if (ret) 669 if (ret)
691 lbs_pr_err("failed to load firmware\n"); 670 lbs_pr_err("failed to load firmware\n");
692 671
693 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); 672 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
694
695 return ret; 673 return ret;
696} 674}
697 675
@@ -699,6 +677,8 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card)
699{ 677{
700 int ret; 678 int ret;
701 u16 scratch; 679 u16 scratch;
680 const struct firmware *helper = NULL;
681 const struct firmware *mainfw = NULL;
702 682
703 lbs_deb_enter(LBS_DEB_SDIO); 683 lbs_deb_enter(LBS_DEB_SDIO);
704 684
@@ -716,11 +696,18 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card)
716 goto success; 696 goto success;
717 } 697 }
718 698
719 ret = if_sdio_prog_helper(card); 699 ret = lbs_get_firmware(&card->func->dev, lbs_helper_name, lbs_fw_name,
700 card->model, &fw_table[0], &helper, &mainfw);
701 if (ret) {
702 lbs_pr_err("failed to find firmware (%d)\n", ret);
703 goto out;
704 }
705
706 ret = if_sdio_prog_helper(card, helper);
720 if (ret) 707 if (ret)
721 goto out; 708 goto out;
722 709
723 ret = if_sdio_prog_real(card); 710 ret = if_sdio_prog_real(card, mainfw);
724 if (ret) 711 if (ret)
725 goto out; 712 goto out;
726 713
@@ -731,8 +718,12 @@ success:
731 ret = 0; 718 ret = 0;
732 719
733out: 720out:
734 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); 721 if (helper)
722 release_firmware(helper);
723 if (mainfw)
724 release_firmware(mainfw);
735 725
726 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
736 return ret; 727 return ret;
737} 728}
738 729
@@ -936,7 +927,7 @@ static int if_sdio_probe(struct sdio_func *func,
936 "ID: %x", &model) == 1) 927 "ID: %x", &model) == 1)
937 break; 928 break;
938 if (!strcmp(func->card->info[i], "IBIS Wireless SDIO Card")) { 929 if (!strcmp(func->card->info[i], "IBIS Wireless SDIO Card")) {
939 model = IF_SDIO_MODEL_8385; 930 model = MODEL_8385;
940 break; 931 break;
941 } 932 }
942 } 933 }
@@ -954,13 +945,13 @@ static int if_sdio_probe(struct sdio_func *func,
954 card->model = model; 945 card->model = model;
955 946
956 switch (card->model) { 947 switch (card->model) {
957 case IF_SDIO_MODEL_8385: 948 case MODEL_8385:
958 card->scratch_reg = IF_SDIO_SCRATCH_OLD; 949 card->scratch_reg = IF_SDIO_SCRATCH_OLD;
959 break; 950 break;
960 case IF_SDIO_MODEL_8686: 951 case MODEL_8686:
961 card->scratch_reg = IF_SDIO_SCRATCH; 952 card->scratch_reg = IF_SDIO_SCRATCH;
962 break; 953 break;
963 case IF_SDIO_MODEL_8688: 954 case MODEL_8688:
964 default: /* for newer chipsets */ 955 default: /* for newer chipsets */
965 card->scratch_reg = IF_SDIO_FW_STATUS; 956 card->scratch_reg = IF_SDIO_FW_STATUS;
966 break; 957 break;
@@ -970,31 +961,17 @@ static int if_sdio_probe(struct sdio_func *func,
970 card->workqueue = create_workqueue("libertas_sdio"); 961 card->workqueue = create_workqueue("libertas_sdio");
971 INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker); 962 INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker);
972 963
973 for (i = 0;i < ARRAY_SIZE(if_sdio_models);i++) { 964 /* Check if we support this card */
974 if (card->model == if_sdio_models[i].model) 965 for (i = 0; i < ARRAY_SIZE(fw_table); i++) {
966 if (card->model == fw_table[i].model)
975 break; 967 break;
976 } 968 }
977 969 if (i == ARRAY_SIZE(fw_table)) {
978 if (i == ARRAY_SIZE(if_sdio_models)) {
979 lbs_pr_err("unknown card model 0x%x\n", card->model); 970 lbs_pr_err("unknown card model 0x%x\n", card->model);
980 ret = -ENODEV; 971 ret = -ENODEV;
981 goto free; 972 goto free;
982 } 973 }
983 974
984 card->helper = if_sdio_models[i].helper;
985 card->firmware = if_sdio_models[i].firmware;
986
987 if (lbs_helper_name) {
988 lbs_deb_sdio("overriding helper firmware: %s\n",
989 lbs_helper_name);
990 card->helper = lbs_helper_name;
991 }
992
993 if (lbs_fw_name) {
994 lbs_deb_sdio("overriding firmware: %s\n", lbs_fw_name);
995 card->firmware = lbs_fw_name;
996 }
997
998 sdio_claim_host(func); 975 sdio_claim_host(func);
999 976
1000 ret = sdio_enable_func(func); 977 ret = sdio_enable_func(func);
@@ -1008,7 +985,7 @@ static int if_sdio_probe(struct sdio_func *func,
1008 /* For 1-bit transfers to the 8686 model, we need to enable the 985 /* For 1-bit transfers to the 8686 model, we need to enable the
1009 * interrupt flag in the CCCR register. Set the MMC_QUIRK_LENIENT_FN0 986 * interrupt flag in the CCCR register. Set the MMC_QUIRK_LENIENT_FN0
1010 * bit to allow access to non-vendor registers. */ 987 * bit to allow access to non-vendor registers. */
1011 if ((card->model == IF_SDIO_MODEL_8686) && 988 if ((card->model == MODEL_8686) &&
1012 (host->caps & MMC_CAP_SDIO_IRQ) && 989 (host->caps & MMC_CAP_SDIO_IRQ) &&
1013 (host->ios.bus_width == MMC_BUS_WIDTH_1)) { 990 (host->ios.bus_width == MMC_BUS_WIDTH_1)) {
1014 u8 reg; 991 u8 reg;
@@ -1071,8 +1048,8 @@ static int if_sdio_probe(struct sdio_func *func,
1071 * Get rx_unit if the chip is SD8688 or newer. 1048 * Get rx_unit if the chip is SD8688 or newer.
1072 * SD8385 & SD8686 do not have rx_unit. 1049 * SD8385 & SD8686 do not have rx_unit.
1073 */ 1050 */
1074 if ((card->model != IF_SDIO_MODEL_8385) 1051 if ((card->model != MODEL_8385)
1075 && (card->model != IF_SDIO_MODEL_8686)) 1052 && (card->model != MODEL_8686))
1076 card->rx_unit = if_sdio_read_rx_unit(card); 1053 card->rx_unit = if_sdio_read_rx_unit(card);
1077 else 1054 else
1078 card->rx_unit = 0; 1055 card->rx_unit = 0;
@@ -1088,7 +1065,7 @@ static int if_sdio_probe(struct sdio_func *func,
1088 /* 1065 /*
1089 * FUNC_INIT is required for SD8688 WLAN/BT multiple functions 1066 * FUNC_INIT is required for SD8688 WLAN/BT multiple functions
1090 */ 1067 */
1091 if (card->model == IF_SDIO_MODEL_8688) { 1068 if (card->model == MODEL_8688) {
1092 struct cmd_header cmd; 1069 struct cmd_header cmd;
1093 1070
1094 memset(&cmd, 0, sizeof(cmd)); 1071 memset(&cmd, 0, sizeof(cmd));
@@ -1141,7 +1118,7 @@ static void if_sdio_remove(struct sdio_func *func)
1141 1118
1142 card = sdio_get_drvdata(func); 1119 card = sdio_get_drvdata(func);
1143 1120
1144 if (user_rmmod && (card->model == IF_SDIO_MODEL_8688)) { 1121 if (user_rmmod && (card->model == MODEL_8688)) {
1145 /* 1122 /*
1146 * FUNC_SHUTDOWN is required for SD8688 WLAN/BT 1123 * FUNC_SHUTDOWN is required for SD8688 WLAN/BT
1147 * multiple functions 1124 * multiple functions
diff --git a/drivers/net/wireless/libertas/if_sdio.h b/drivers/net/wireless/libertas/if_sdio.h
index 12179c1dc9c9..62fda3592f67 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