aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2010-08-07 22:15:19 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-08-16 15:26:43 -0400
commit82222e9ba75298e5bcd89803b6a11e2d7dfae70e (patch)
tree5594a7c0ffa78489beff83fa98b9adeb269cee05
parent72f7a6671e8a1433467757e94c883d39eeccd4ba (diff)
libertas: [cs] 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. Signed-off-by: Dan Williams <dcbw@redhat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/libertas/if_cs.c130
1 files changed, 74 insertions, 56 deletions
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index 08e4e390800..a6fd70404c3 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -49,7 +49,6 @@
49MODULE_AUTHOR("Holger Schurig <hs4233@mail.mn-solutions.de>"); 49MODULE_AUTHOR("Holger Schurig <hs4233@mail.mn-solutions.de>");
50MODULE_DESCRIPTION("Driver for Marvell 83xx compact flash WLAN cards"); 50MODULE_DESCRIPTION("Driver for Marvell 83xx compact flash WLAN cards");
51MODULE_LICENSE("GPL"); 51MODULE_LICENSE("GPL");
52MODULE_FIRMWARE("libertas_cs_helper.fw");
53 52
54 53
55 54
@@ -62,9 +61,34 @@ struct if_cs_card {
62 struct lbs_private *priv; 61 struct lbs_private *priv;
63 void __iomem *iobase; 62 void __iomem *iobase;
64 bool align_regs; 63 bool align_regs;
64 u32 model;
65}; 65};
66 66
67 67
68enum {
69 MODEL_UNKNOWN = 0x00,
70 MODEL_8305 = 0x01,
71 MODEL_8381 = 0x02,
72 MODEL_8385 = 0x03
73};
74
75static const struct lbs_fw_table fw_table[] = {
76 { MODEL_8305, "libertas/cf8305.bin", NULL },
77 { MODEL_8305, "libertas_cs_helper.fw", NULL },
78 { MODEL_8381, "libertas/cf8381_helper.bin", "libertas/cf8381.bin" },
79 { MODEL_8381, "libertas_cs_helper.fw", "libertas_cs.fw" },
80 { MODEL_8385, "libertas/cf8385_helper.bin", "libertas/cf8385.bin" },
81 { MODEL_8385, "libertas_cs_helper.fw", "libertas_cs.fw" },
82 { 0, NULL, NULL }
83};
84MODULE_FIRMWARE("libertas/cf8305.bin");
85MODULE_FIRMWARE("libertas/cf8381_helper.bin");
86MODULE_FIRMWARE("libertas/cf8381.bin");
87MODULE_FIRMWARE("libertas/cf8385_helper.bin");
88MODULE_FIRMWARE("libertas/cf8385.bin");
89MODULE_FIRMWARE("libertas_cs_helper.fw");
90MODULE_FIRMWARE("libertas_cs.fw");
91
68 92
69/********************************************************************/ 93/********************************************************************/
70/* Hardware access */ 94/* Hardware access */
@@ -290,22 +314,19 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r
290#define CF8385_MANFID 0x02df 314#define CF8385_MANFID 0x02df
291#define CF8385_CARDID 0x8103 315#define CF8385_CARDID 0x8103
292 316
293static inline int if_cs_hw_is_cf8305(struct pcmcia_device *p_dev) 317/* FIXME: just use the 'driver_info' field of 'struct pcmcia_device_id' when
294{ 318 * that gets fixed. Currently there's no way to access it from the probe hook.
295 return (p_dev->manf_id == CF8305_MANFID && 319 */
296 p_dev->card_id == CF8305_CARDID); 320static inline u32 get_model(u16 manf_id, u16 card_id)
297}
298
299static inline int if_cs_hw_is_cf8381(struct pcmcia_device *p_dev)
300{
301 return (p_dev->manf_id == CF8381_MANFID &&
302 p_dev->card_id == CF8381_CARDID);
303}
304
305static inline int if_cs_hw_is_cf8385(struct pcmcia_device *p_dev)
306{ 321{
307 return (p_dev->manf_id == CF8385_MANFID && 322 /* NOTE: keep in sync with if_cs_ids */
308 p_dev->card_id == CF8385_CARDID); 323 if (manf_id == CF8305_MANFID && card_id == CF8305_CARDID)
324 return MODEL_8305;
325 else if (manf_id == CF8381_MANFID && card_id == CF8381_CARDID)
326 return MODEL_8381;
327 else if (manf_id == CF8385_MANFID && card_id == CF8385_CARDID)
328 return MODEL_8385;
329 return MODEL_UNKNOWN;
309} 330}
310 331
311/********************************************************************/ 332/********************************************************************/
@@ -559,12 +580,11 @@ static irqreturn_t if_cs_interrupt(int irq, void *data)
559 * 580 *
560 * Return 0 on success 581 * Return 0 on success
561 */ 582 */
562static int if_cs_prog_helper(struct if_cs_card *card) 583static int if_cs_prog_helper(struct if_cs_card *card, const struct firmware *fw)
563{ 584{
564 int ret = 0; 585 int ret = 0;
565 int sent = 0; 586 int sent = 0;
566 u8 scratch; 587 u8 scratch;
567 const struct firmware *fw;
568 588
569 lbs_deb_enter(LBS_DEB_CS); 589 lbs_deb_enter(LBS_DEB_CS);
570 590
@@ -590,14 +610,6 @@ static int if_cs_prog_helper(struct if_cs_card *card)
590 goto done; 610 goto done;
591 } 611 }
592 612
593 /* TODO: make firmware file configurable */
594 ret = request_firmware(&fw, "libertas_cs_helper.fw",
595 &card->p_dev->dev);
596 if (ret) {
597 lbs_pr_err("can't load helper firmware\n");
598 ret = -ENODEV;
599 goto done;
600 }
601 lbs_deb_cs("helper size %td\n", fw->size); 613 lbs_deb_cs("helper size %td\n", fw->size);
602 614
603 /* "Set the 5 bytes of the helper image to 0" */ 615 /* "Set the 5 bytes of the helper image to 0" */
@@ -636,7 +648,7 @@ static int if_cs_prog_helper(struct if_cs_card *card)
636 if (ret < 0) { 648 if (ret < 0) {
637 lbs_pr_err("can't download helper at 0x%x, ret %d\n", 649 lbs_pr_err("can't download helper at 0x%x, ret %d\n",
638 sent, ret); 650 sent, ret);
639 goto err_release; 651 goto done;
640 } 652 }
641 653
642 if (count == 0) 654 if (count == 0)
@@ -645,17 +657,14 @@ static int if_cs_prog_helper(struct if_cs_card *card)
645 sent += count; 657 sent += count;
646 } 658 }
647 659
648err_release:
649 release_firmware(fw);
650done: 660done:
651 lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); 661 lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
652 return ret; 662 return ret;
653} 663}
654 664
655 665
656static int if_cs_prog_real(struct if_cs_card *card) 666static int if_cs_prog_real(struct if_cs_card *card, const struct firmware *fw)
657{ 667{
658 const struct firmware *fw;
659 int ret = 0; 668 int ret = 0;
660 int retry = 0; 669 int retry = 0;
661 int len = 0; 670 int len = 0;
@@ -663,21 +672,13 @@ static int if_cs_prog_real(struct if_cs_card *card)
663 672
664 lbs_deb_enter(LBS_DEB_CS); 673 lbs_deb_enter(LBS_DEB_CS);
665 674
666 /* TODO: make firmware file configurable */
667 ret = request_firmware(&fw, "libertas_cs.fw",
668 &card->p_dev->dev);
669 if (ret) {
670 lbs_pr_err("can't load firmware\n");
671 ret = -ENODEV;
672 goto done;
673 }
674 lbs_deb_cs("fw size %td\n", fw->size); 675 lbs_deb_cs("fw size %td\n", fw->size);
675 676
676 ret = if_cs_poll_while_fw_download(card, IF_CS_SQ_READ_LOW, 677 ret = if_cs_poll_while_fw_download(card, IF_CS_SQ_READ_LOW,
677 IF_CS_SQ_HELPER_OK); 678 IF_CS_SQ_HELPER_OK);
678 if (ret < 0) { 679 if (ret < 0) {
679 lbs_pr_err("helper firmware doesn't answer\n"); 680 lbs_pr_err("helper firmware doesn't answer\n");
680 goto err_release; 681 goto done;
681 } 682 }
682 683
683 for (sent = 0; sent < fw->size; sent += len) { 684 for (sent = 0; sent < fw->size; sent += len) {
@@ -692,7 +693,7 @@ static int if_cs_prog_real(struct if_cs_card *card)
692 if (retry > 20) { 693 if (retry > 20) {
693 lbs_pr_err("could not download firmware\n"); 694 lbs_pr_err("could not download firmware\n");
694 ret = -ENODEV; 695 ret = -ENODEV;
695 goto err_release; 696 goto done;
696 } 697 }
697 if (retry) { 698 if (retry) {
698 sent -= len; 699 sent -= len;
@@ -711,7 +712,7 @@ static int if_cs_prog_real(struct if_cs_card *card)
711 IF_CS_BIT_COMMAND); 712 IF_CS_BIT_COMMAND);
712 if (ret < 0) { 713 if (ret < 0) {
713 lbs_pr_err("can't download firmware at 0x%x\n", sent); 714 lbs_pr_err("can't download firmware at 0x%x\n", sent);
714 goto err_release; 715 goto done;
715 } 716 }
716 } 717 }
717 718
@@ -719,9 +720,6 @@ static int if_cs_prog_real(struct if_cs_card *card)
719 if (ret < 0) 720 if (ret < 0)
720 lbs_pr_err("firmware download failed\n"); 721 lbs_pr_err("firmware download failed\n");
721 722
722err_release:
723 release_firmware(fw);
724
725done: 723done:
726 lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); 724 lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
727 return ret; 725 return ret;
@@ -825,6 +823,8 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
825 unsigned int prod_id; 823 unsigned int prod_id;
826 struct lbs_private *priv; 824 struct lbs_private *priv;
827 struct if_cs_card *card; 825 struct if_cs_card *card;
826 const struct firmware *helper = NULL;
827 const struct firmware *mainfw = NULL;
828 828
829 lbs_deb_enter(LBS_DEB_CS); 829 lbs_deb_enter(LBS_DEB_CS);
830 830
@@ -844,7 +844,6 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
844 goto out1; 844 goto out1;
845 } 845 }
846 846
847
848 /* 847 /*
849 * Allocate an interrupt line. Note that this does not assign 848 * Allocate an interrupt line. Note that this does not assign
850 * a handler to the interrupt, unless the 'Handler' member of 849 * a handler to the interrupt, unless the 'Handler' member of
@@ -883,34 +882,47 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
883 */ 882 */
884 card->align_regs = 0; 883 card->align_regs = 0;
885 884
885 card->model = get_model(p_dev->manf_id, p_dev->card_id);
886 if (card->model == MODEL_UNKNOWN) {
887 lbs_pr_err("unsupported manf_id 0x%04x / card_id 0x%04x\n",
888 p_dev->manf_id, p_dev->card_id);
889 goto out2;
890 }
891
886 /* Check if we have a current silicon */ 892 /* Check if we have a current silicon */
887 prod_id = if_cs_read8(card, IF_CS_PRODUCT_ID); 893 prod_id = if_cs_read8(card, IF_CS_PRODUCT_ID);
888 if (if_cs_hw_is_cf8305(p_dev)) { 894 if (card->model == MODEL_8305) {
889 card->align_regs = 1; 895 card->align_regs = 1;
890 if (prod_id < IF_CS_CF8305_B1_REV) { 896 if (prod_id < IF_CS_CF8305_B1_REV) {
891 lbs_pr_err("old chips like 8305 rev B3 " 897 lbs_pr_err("8305 rev B0 and older are not supported\n");
892 "aren't supported\n");
893 ret = -ENODEV; 898 ret = -ENODEV;
894 goto out2; 899 goto out2;
895 } 900 }
896 } 901 }
897 902
898 if (if_cs_hw_is_cf8381(p_dev) && prod_id < IF_CS_CF8381_B3_REV) { 903 if ((card->model == MODEL_8381) && prod_id < IF_CS_CF8381_B3_REV) {
899 lbs_pr_err("old chips like 8381 rev B3 aren't supported\n"); 904 lbs_pr_err("8381 rev B2 and older are not supported\n");
900 ret = -ENODEV; 905 ret = -ENODEV;
901 goto out2; 906 goto out2;
902 } 907 }
903 908
904 if (if_cs_hw_is_cf8385(p_dev) && prod_id < IF_CS_CF8385_B1_REV) { 909 if ((card->model == MODEL_8385) && prod_id < IF_CS_CF8385_B1_REV) {
905 lbs_pr_err("old chips like 8385 rev B1 aren't supported\n"); 910 lbs_pr_err("8385 rev B0 and older are not supported\n");
906 ret = -ENODEV; 911 ret = -ENODEV;
907 goto out2; 912 goto out2;
908 } 913 }
909 914
915 ret = lbs_get_firmware(&p_dev->dev, NULL, NULL, card->model,
916 &fw_table[0], &helper, &mainfw);
917 if (ret) {
918 lbs_pr_err("failed to find firmware (%d)\n", ret);
919 goto out2;
920 }
921
910 /* Load the firmware early, before calling into libertas.ko */ 922 /* Load the firmware early, before calling into libertas.ko */
911 ret = if_cs_prog_helper(card); 923 ret = if_cs_prog_helper(card, helper);
912 if (ret == 0 && !if_cs_hw_is_cf8305(p_dev)) 924 if (ret == 0 && (card->model != MODEL_8305))
913 ret = if_cs_prog_real(card); 925 ret = if_cs_prog_real(card, mainfw);
914 if (ret) 926 if (ret)
915 goto out2; 927 goto out2;
916 928
@@ -959,6 +971,11 @@ out2:
959out1: 971out1:
960 pcmcia_disable_device(p_dev); 972 pcmcia_disable_device(p_dev);
961out: 973out:
974 if (helper)
975 release_firmware(helper);
976 if (mainfw)
977 release_firmware(mainfw);
978
962 lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); 979 lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
963 return ret; 980 return ret;
964} 981}
@@ -995,6 +1012,7 @@ static struct pcmcia_device_id if_cs_ids[] = {
995 PCMCIA_DEVICE_MANF_CARD(CF8305_MANFID, CF8305_CARDID), 1012 PCMCIA_DEVICE_MANF_CARD(CF8305_MANFID, CF8305_CARDID),
996 PCMCIA_DEVICE_MANF_CARD(CF8381_MANFID, CF8381_CARDID), 1013 PCMCIA_DEVICE_MANF_CARD(CF8381_MANFID, CF8381_CARDID),
997 PCMCIA_DEVICE_MANF_CARD(CF8385_MANFID, CF8385_CARDID), 1014 PCMCIA_DEVICE_MANF_CARD(CF8385_MANFID, CF8385_CARDID),
1015 /* NOTE: keep in sync with get_model() */
998 PCMCIA_DEVICE_NULL, 1016 PCMCIA_DEVICE_NULL,
999}; 1017};
1000MODULE_DEVICE_TABLE(pcmcia, if_cs_ids); 1018MODULE_DEVICE_TABLE(pcmcia, if_cs_ids);