diff options
author | Dan Williams <dcbw@redhat.com> | 2010-08-07 22:15:52 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-08-16 15:26:43 -0400 |
commit | 3d32a58b87cd251b50842f93b87d5458061c0cfc (patch) | |
tree | 983efdd808d72edefde2f54f3d938c40fb5e53fc /drivers/net/wireless/libertas/if_sdio.c | |
parent | 82222e9ba75298e5bcd89803b6a11e2d7dfae70e (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/wireless/libertas/if_sdio.c')
-rw-r--r-- | drivers/net/wireless/libertas/if_sdio.c | 143 |
1 files changed, 60 insertions, 83 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 | ||
77 | MODULE_DEVICE_TABLE(sdio, if_sdio_ids); | 77 | MODULE_DEVICE_TABLE(sdio, if_sdio_ids); |
78 | 78 | ||
79 | struct 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 | }; | 83 | static const struct lbs_fw_table fw_table[] = { |
84 | 84 | { MODEL_8385, "libertas/sd8385_helper.bin", "libertas/sd8385.bin" }, | |
85 | static 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 | }; |
93 | MODULE_FIRMWARE("libertas/sd8385_helper.bin"); | ||
94 | MODULE_FIRMWARE("libertas/sd8385.bin"); | ||
105 | MODULE_FIRMWARE("sd8385_helper.bin"); | 95 | MODULE_FIRMWARE("sd8385_helper.bin"); |
106 | MODULE_FIRMWARE("sd8385.bin"); | 96 | MODULE_FIRMWARE("sd8385.bin"); |
97 | MODULE_FIRMWARE("libertas/sd8686_v9_helper.bin"); | ||
98 | MODULE_FIRMWARE("libertas/sd8686_v9.bin"); | ||
99 | MODULE_FIRMWARE("libertas/sd8686_v8_helper.bin"); | ||
100 | MODULE_FIRMWARE("libertas/sd8686_v8.bin"); | ||
107 | MODULE_FIRMWARE("sd8686_helper.bin"); | 101 | MODULE_FIRMWARE("sd8686_helper.bin"); |
108 | MODULE_FIRMWARE("sd8686.bin"); | 102 | MODULE_FIRMWARE("sd8686.bin"); |
103 | MODULE_FIRMWARE("libertas/sd8688_helper.bin"); | ||
104 | MODULE_FIRMWARE("libertas/sd8688.bin"); | ||
109 | MODULE_FIRMWARE("sd8688_helper.bin"); | 105 | MODULE_FIRMWARE("sd8688_helper.bin"); |
110 | MODULE_FIRMWARE("sd8688.bin"); | 106 | MODULE_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 | ||
467 | static int if_sdio_prog_helper(struct if_sdio_card *card) | 463 | static 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) | |||
560 | release: | 550 | release: |
561 | sdio_release_host(card->func); | 551 | sdio_release_host(card->func); |
562 | kfree(chunk_buffer); | 552 | kfree(chunk_buffer); |
563 | release_fw: | ||
564 | release_firmware(fw); | ||
565 | 553 | ||
566 | out: | 554 | out: |
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 | ||
575 | static int if_sdio_prog_real(struct if_sdio_card *card) | 562 | static 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) | |||
683 | release: | 664 | release: |
684 | sdio_release_host(card->func); | 665 | sdio_release_host(card->func); |
685 | kfree(chunk_buffer); | 666 | kfree(chunk_buffer); |
686 | release_fw: | ||
687 | release_firmware(fw); | ||
688 | 667 | ||
689 | out: | 668 | out: |
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 | ||
733 | out: | 720 | out: |
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 |