diff options
Diffstat (limited to 'drivers/net/wireless/libertas/if_cs.c')
-rw-r--r-- | drivers/net/wireless/libertas/if_cs.c | 265 |
1 files changed, 129 insertions, 136 deletions
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c index 9c298396be50..e26935179861 100644 --- a/drivers/net/wireless/libertas/if_cs.c +++ b/drivers/net/wireless/libertas/if_cs.c | |||
@@ -21,6 +21,8 @@ | |||
21 | 21 | ||
22 | */ | 22 | */ |
23 | 23 | ||
24 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
25 | |||
24 | #include <linux/module.h> | 26 | #include <linux/module.h> |
25 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
26 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
@@ -28,7 +30,6 @@ | |||
28 | #include <linux/firmware.h> | 30 | #include <linux/firmware.h> |
29 | #include <linux/netdevice.h> | 31 | #include <linux/netdevice.h> |
30 | 32 | ||
31 | #include <pcmcia/cs.h> | ||
32 | #include <pcmcia/cistpl.h> | 33 | #include <pcmcia/cistpl.h> |
33 | #include <pcmcia/ds.h> | 34 | #include <pcmcia/ds.h> |
34 | 35 | ||
@@ -48,7 +49,6 @@ | |||
48 | MODULE_AUTHOR("Holger Schurig <hs4233@mail.mn-solutions.de>"); | 49 | MODULE_AUTHOR("Holger Schurig <hs4233@mail.mn-solutions.de>"); |
49 | MODULE_DESCRIPTION("Driver for Marvell 83xx compact flash WLAN cards"); | 50 | MODULE_DESCRIPTION("Driver for Marvell 83xx compact flash WLAN cards"); |
50 | MODULE_LICENSE("GPL"); | 51 | MODULE_LICENSE("GPL"); |
51 | MODULE_FIRMWARE("libertas_cs_helper.fw"); | ||
52 | 52 | ||
53 | 53 | ||
54 | 54 | ||
@@ -61,9 +61,34 @@ struct if_cs_card { | |||
61 | struct lbs_private *priv; | 61 | struct lbs_private *priv; |
62 | void __iomem *iobase; | 62 | void __iomem *iobase; |
63 | bool align_regs; | 63 | bool align_regs; |
64 | u32 model; | ||
64 | }; | 65 | }; |
65 | 66 | ||
66 | 67 | ||
68 | enum { | ||
69 | MODEL_UNKNOWN = 0x00, | ||
70 | MODEL_8305 = 0x01, | ||
71 | MODEL_8381 = 0x02, | ||
72 | MODEL_8385 = 0x03 | ||
73 | }; | ||
74 | |||
75 | static 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 | }; | ||
84 | MODULE_FIRMWARE("libertas/cf8305.bin"); | ||
85 | MODULE_FIRMWARE("libertas/cf8381_helper.bin"); | ||
86 | MODULE_FIRMWARE("libertas/cf8381.bin"); | ||
87 | MODULE_FIRMWARE("libertas/cf8385_helper.bin"); | ||
88 | MODULE_FIRMWARE("libertas/cf8385.bin"); | ||
89 | MODULE_FIRMWARE("libertas_cs_helper.fw"); | ||
90 | MODULE_FIRMWARE("libertas_cs.fw"); | ||
91 | |||
67 | 92 | ||
68 | /********************************************************************/ | 93 | /********************************************************************/ |
69 | /* Hardware access */ | 94 | /* Hardware access */ |
@@ -289,22 +314,20 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r | |||
289 | #define CF8385_MANFID 0x02df | 314 | #define CF8385_MANFID 0x02df |
290 | #define CF8385_CARDID 0x8103 | 315 | #define CF8385_CARDID 0x8103 |
291 | 316 | ||
292 | static inline int if_cs_hw_is_cf8305(struct pcmcia_device *p_dev) | 317 | /* |
293 | { | 318 | * FIXME: just use the 'driver_info' field of 'struct pcmcia_device_id' when |
294 | return (p_dev->manf_id == CF8305_MANFID && | 319 | * that gets fixed. Currently there's no way to access it from the probe hook. |
295 | p_dev->card_id == CF8305_CARDID); | 320 | */ |
296 | } | 321 | static inline u32 get_model(u16 manf_id, u16 card_id) |
297 | |||
298 | static 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 | |||
304 | static inline int if_cs_hw_is_cf8385(struct pcmcia_device *p_dev) | ||
305 | { | 322 | { |
306 | return (p_dev->manf_id == CF8385_MANFID && | 323 | /* NOTE: keep in sync with if_cs_ids */ |
307 | p_dev->card_id == CF8385_CARDID); | 324 | if (manf_id == CF8305_MANFID && card_id == CF8305_CARDID) |
325 | return MODEL_8305; | ||
326 | else if (manf_id == CF8381_MANFID && card_id == CF8381_CARDID) | ||
327 | return MODEL_8381; | ||
328 | else if (manf_id == CF8385_MANFID && card_id == CF8385_CARDID) | ||
329 | return MODEL_8385; | ||
330 | return MODEL_UNKNOWN; | ||
308 | } | 331 | } |
309 | 332 | ||
310 | /********************************************************************/ | 333 | /********************************************************************/ |
@@ -341,7 +364,7 @@ static int if_cs_send_cmd(struct lbs_private *priv, u8 *buf, u16 nb) | |||
341 | if (status & IF_CS_BIT_COMMAND) | 364 | if (status & IF_CS_BIT_COMMAND) |
342 | break; | 365 | break; |
343 | if (++loops > 100) { | 366 | if (++loops > 100) { |
344 | lbs_pr_err("card not ready for commands\n"); | 367 | netdev_err(priv->dev, "card not ready for commands\n"); |
345 | goto done; | 368 | goto done; |
346 | } | 369 | } |
347 | mdelay(1); | 370 | mdelay(1); |
@@ -411,14 +434,16 @@ static int if_cs_receive_cmdres(struct lbs_private *priv, u8 *data, u32 *len) | |||
411 | /* is hardware ready? */ | 434 | /* is hardware ready? */ |
412 | status = if_cs_read16(priv->card, IF_CS_CARD_STATUS); | 435 | status = if_cs_read16(priv->card, IF_CS_CARD_STATUS); |
413 | if ((status & IF_CS_BIT_RESP) == 0) { | 436 | if ((status & IF_CS_BIT_RESP) == 0) { |
414 | lbs_pr_err("no cmd response in card\n"); | 437 | netdev_err(priv->dev, "no cmd response in card\n"); |
415 | *len = 0; | 438 | *len = 0; |
416 | goto out; | 439 | goto out; |
417 | } | 440 | } |
418 | 441 | ||
419 | *len = if_cs_read16(priv->card, IF_CS_RESP_LEN); | 442 | *len = if_cs_read16(priv->card, IF_CS_RESP_LEN); |
420 | if ((*len == 0) || (*len > LBS_CMD_BUFFER_SIZE)) { | 443 | if ((*len == 0) || (*len > LBS_CMD_BUFFER_SIZE)) { |
421 | lbs_pr_err("card cmd buffer has invalid # of bytes (%d)\n", *len); | 444 | netdev_err(priv->dev, |
445 | "card cmd buffer has invalid # of bytes (%d)\n", | ||
446 | *len); | ||
422 | goto out; | 447 | goto out; |
423 | } | 448 | } |
424 | 449 | ||
@@ -452,7 +477,9 @@ static struct sk_buff *if_cs_receive_data(struct lbs_private *priv) | |||
452 | 477 | ||
453 | len = if_cs_read16(priv->card, IF_CS_READ_LEN); | 478 | len = if_cs_read16(priv->card, IF_CS_READ_LEN); |
454 | if (len == 0 || len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) { | 479 | if (len == 0 || len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) { |
455 | lbs_pr_err("card data buffer has invalid # of bytes (%d)\n", len); | 480 | netdev_err(priv->dev, |
481 | "card data buffer has invalid # of bytes (%d)\n", | ||
482 | len); | ||
456 | priv->dev->stats.rx_dropped++; | 483 | priv->dev->stats.rx_dropped++; |
457 | goto dat_err; | 484 | goto dat_err; |
458 | } | 485 | } |
@@ -558,12 +585,11 @@ static irqreturn_t if_cs_interrupt(int irq, void *data) | |||
558 | * | 585 | * |
559 | * Return 0 on success | 586 | * Return 0 on success |
560 | */ | 587 | */ |
561 | static int if_cs_prog_helper(struct if_cs_card *card) | 588 | static int if_cs_prog_helper(struct if_cs_card *card, const struct firmware *fw) |
562 | { | 589 | { |
563 | int ret = 0; | 590 | int ret = 0; |
564 | int sent = 0; | 591 | int sent = 0; |
565 | u8 scratch; | 592 | u8 scratch; |
566 | const struct firmware *fw; | ||
567 | 593 | ||
568 | lbs_deb_enter(LBS_DEB_CS); | 594 | lbs_deb_enter(LBS_DEB_CS); |
569 | 595 | ||
@@ -589,14 +615,6 @@ static int if_cs_prog_helper(struct if_cs_card *card) | |||
589 | goto done; | 615 | goto done; |
590 | } | 616 | } |
591 | 617 | ||
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); | 618 | lbs_deb_cs("helper size %td\n", fw->size); |
601 | 619 | ||
602 | /* "Set the 5 bytes of the helper image to 0" */ | 620 | /* "Set the 5 bytes of the helper image to 0" */ |
@@ -610,8 +628,10 @@ static int if_cs_prog_helper(struct if_cs_card *card) | |||
610 | if (remain < count) | 628 | if (remain < count) |
611 | count = remain; | 629 | count = remain; |
612 | 630 | ||
613 | /* "write the number of bytes to be sent to the I/O Command | 631 | /* |
614 | * write length register" */ | 632 | * "write the number of bytes to be sent to the I/O Command |
633 | * write length register" | ||
634 | */ | ||
615 | if_cs_write16(card, IF_CS_CMD_LEN, count); | 635 | if_cs_write16(card, IF_CS_CMD_LEN, count); |
616 | 636 | ||
617 | /* "write this to I/O Command port register as 16 bit writes */ | 637 | /* "write this to I/O Command port register as 16 bit writes */ |
@@ -620,22 +640,28 @@ static int if_cs_prog_helper(struct if_cs_card *card) | |||
620 | &fw->data[sent], | 640 | &fw->data[sent], |
621 | count >> 1); | 641 | count >> 1); |
622 | 642 | ||
623 | /* "Assert the download over interrupt command in the Host | 643 | /* |
624 | * status register" */ | 644 | * "Assert the download over interrupt command in the Host |
645 | * status register" | ||
646 | */ | ||
625 | if_cs_write8(card, IF_CS_HOST_STATUS, IF_CS_BIT_COMMAND); | 647 | if_cs_write8(card, IF_CS_HOST_STATUS, IF_CS_BIT_COMMAND); |
626 | 648 | ||
627 | /* "Assert the download over interrupt command in the Card | 649 | /* |
628 | * interrupt case register" */ | 650 | * "Assert the download over interrupt command in the Card |
651 | * interrupt case register" | ||
652 | */ | ||
629 | if_cs_write16(card, IF_CS_HOST_INT_CAUSE, IF_CS_BIT_COMMAND); | 653 | if_cs_write16(card, IF_CS_HOST_INT_CAUSE, IF_CS_BIT_COMMAND); |
630 | 654 | ||
631 | /* "The host polls the Card Status register ... for 50 ms before | 655 | /* |
632 | declaring a failure */ | 656 | * "The host polls the Card Status register ... for 50 ms before |
657 | * declaring a failure" | ||
658 | */ | ||
633 | ret = if_cs_poll_while_fw_download(card, IF_CS_CARD_STATUS, | 659 | ret = if_cs_poll_while_fw_download(card, IF_CS_CARD_STATUS, |
634 | IF_CS_BIT_COMMAND); | 660 | IF_CS_BIT_COMMAND); |
635 | if (ret < 0) { | 661 | if (ret < 0) { |
636 | lbs_pr_err("can't download helper at 0x%x, ret %d\n", | 662 | pr_err("can't download helper at 0x%x, ret %d\n", |
637 | sent, ret); | 663 | sent, ret); |
638 | goto err_release; | 664 | goto done; |
639 | } | 665 | } |
640 | 666 | ||
641 | if (count == 0) | 667 | if (count == 0) |
@@ -644,17 +670,14 @@ static int if_cs_prog_helper(struct if_cs_card *card) | |||
644 | sent += count; | 670 | sent += count; |
645 | } | 671 | } |
646 | 672 | ||
647 | err_release: | ||
648 | release_firmware(fw); | ||
649 | done: | 673 | done: |
650 | lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); | 674 | lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); |
651 | return ret; | 675 | return ret; |
652 | } | 676 | } |
653 | 677 | ||
654 | 678 | ||
655 | static int if_cs_prog_real(struct if_cs_card *card) | 679 | static int if_cs_prog_real(struct if_cs_card *card, const struct firmware *fw) |
656 | { | 680 | { |
657 | const struct firmware *fw; | ||
658 | int ret = 0; | 681 | int ret = 0; |
659 | int retry = 0; | 682 | int retry = 0; |
660 | int len = 0; | 683 | int len = 0; |
@@ -662,36 +685,28 @@ static int if_cs_prog_real(struct if_cs_card *card) | |||
662 | 685 | ||
663 | lbs_deb_enter(LBS_DEB_CS); | 686 | lbs_deb_enter(LBS_DEB_CS); |
664 | 687 | ||
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); | 688 | lbs_deb_cs("fw size %td\n", fw->size); |
674 | 689 | ||
675 | ret = if_cs_poll_while_fw_download(card, IF_CS_SQ_READ_LOW, | 690 | ret = if_cs_poll_while_fw_download(card, IF_CS_SQ_READ_LOW, |
676 | IF_CS_SQ_HELPER_OK); | 691 | IF_CS_SQ_HELPER_OK); |
677 | if (ret < 0) { | 692 | if (ret < 0) { |
678 | lbs_pr_err("helper firmware doesn't answer\n"); | 693 | pr_err("helper firmware doesn't answer\n"); |
679 | goto err_release; | 694 | goto done; |
680 | } | 695 | } |
681 | 696 | ||
682 | for (sent = 0; sent < fw->size; sent += len) { | 697 | for (sent = 0; sent < fw->size; sent += len) { |
683 | len = if_cs_read16(card, IF_CS_SQ_READ_LOW); | 698 | len = if_cs_read16(card, IF_CS_SQ_READ_LOW); |
684 | if (len & 1) { | 699 | if (len & 1) { |
685 | retry++; | 700 | retry++; |
686 | lbs_pr_info("odd, need to retry this firmware block\n"); | 701 | pr_info("odd, need to retry this firmware block\n"); |
687 | } else { | 702 | } else { |
688 | retry = 0; | 703 | retry = 0; |
689 | } | 704 | } |
690 | 705 | ||
691 | if (retry > 20) { | 706 | if (retry > 20) { |
692 | lbs_pr_err("could not download firmware\n"); | 707 | pr_err("could not download firmware\n"); |
693 | ret = -ENODEV; | 708 | ret = -ENODEV; |
694 | goto err_release; | 709 | goto done; |
695 | } | 710 | } |
696 | if (retry) { | 711 | if (retry) { |
697 | sent -= len; | 712 | sent -= len; |
@@ -709,17 +724,14 @@ static int if_cs_prog_real(struct if_cs_card *card) | |||
709 | ret = if_cs_poll_while_fw_download(card, IF_CS_CARD_STATUS, | 724 | ret = if_cs_poll_while_fw_download(card, IF_CS_CARD_STATUS, |
710 | IF_CS_BIT_COMMAND); | 725 | IF_CS_BIT_COMMAND); |
711 | if (ret < 0) { | 726 | if (ret < 0) { |
712 | lbs_pr_err("can't download firmware at 0x%x\n", sent); | 727 | pr_err("can't download firmware at 0x%x\n", sent); |
713 | goto err_release; | 728 | goto done; |
714 | } | 729 | } |
715 | } | 730 | } |
716 | 731 | ||
717 | ret = if_cs_poll_while_fw_download(card, IF_CS_SCRATCH, 0x5a); | 732 | ret = if_cs_poll_while_fw_download(card, IF_CS_SCRATCH, 0x5a); |
718 | if (ret < 0) | 733 | if (ret < 0) |
719 | lbs_pr_err("firmware download failed\n"); | 734 | pr_err("firmware download failed\n"); |
720 | |||
721 | err_release: | ||
722 | release_firmware(fw); | ||
723 | 735 | ||
724 | done: | 736 | done: |
725 | lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); | 737 | lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); |
@@ -753,7 +765,8 @@ static int if_cs_host_to_card(struct lbs_private *priv, | |||
753 | ret = if_cs_send_cmd(priv, buf, nb); | 765 | ret = if_cs_send_cmd(priv, buf, nb); |
754 | break; | 766 | break; |
755 | default: | 767 | default: |
756 | lbs_pr_err("%s: unsupported type %d\n", __func__, type); | 768 | netdev_err(priv->dev, "%s: unsupported type %d\n", |
769 | __func__, type); | ||
757 | } | 770 | } |
758 | 771 | ||
759 | lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); | 772 | lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); |
@@ -761,15 +774,6 @@ static int if_cs_host_to_card(struct lbs_private *priv, | |||
761 | } | 774 | } |
762 | 775 | ||
763 | 776 | ||
764 | /********************************************************************/ | ||
765 | /* Card Services */ | ||
766 | /********************************************************************/ | ||
767 | |||
768 | /* | ||
769 | * After a card is removed, if_cs_release() will unregister the | ||
770 | * device, and release the PCMCIA configuration. If the device is | ||
771 | * still open, this will be postponed until it is closed. | ||
772 | */ | ||
773 | static void if_cs_release(struct pcmcia_device *p_dev) | 777 | static void if_cs_release(struct pcmcia_device *p_dev) |
774 | { | 778 | { |
775 | struct if_cs_card *card = p_dev->priv; | 779 | struct if_cs_card *card = p_dev->priv; |
@@ -785,32 +789,13 @@ static void if_cs_release(struct pcmcia_device *p_dev) | |||
785 | } | 789 | } |
786 | 790 | ||
787 | 791 | ||
788 | /* | 792 | static int if_cs_ioprobe(struct pcmcia_device *p_dev, void *priv_data) |
789 | * This creates an "instance" of the driver, allocating local data | ||
790 | * structures for one device. The device is registered with Card | ||
791 | * Services. | ||
792 | * | ||
793 | * The dev_link structure is initialized, but we don't actually | ||
794 | * configure the card at this point -- we wait until we receive a card | ||
795 | * insertion event. | ||
796 | */ | ||
797 | |||
798 | static int if_cs_ioprobe(struct pcmcia_device *p_dev, | ||
799 | cistpl_cftable_entry_t *cfg, | ||
800 | cistpl_cftable_entry_t *dflt, | ||
801 | unsigned int vcc, | ||
802 | void *priv_data) | ||
803 | { | 793 | { |
794 | p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; | ||
804 | p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; | 795 | p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; |
805 | p_dev->resource[0]->start = cfg->io.win[0].base; | ||
806 | p_dev->resource[0]->end = cfg->io.win[0].len; | ||
807 | 796 | ||
808 | /* Do we need to allocate an interrupt? */ | 797 | if (p_dev->resource[1]->end) { |
809 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; | 798 | pr_err("wrong CIS (check number of IO windows)\n"); |
810 | |||
811 | /* IO window settings */ | ||
812 | if (cfg->io.nwin != 1) { | ||
813 | lbs_pr_err("wrong CIS (check number of IO windows)\n"); | ||
814 | return -ENODEV; | 799 | return -ENODEV; |
815 | } | 800 | } |
816 | 801 | ||
@@ -824,26 +809,26 @@ static int if_cs_probe(struct pcmcia_device *p_dev) | |||
824 | unsigned int prod_id; | 809 | unsigned int prod_id; |
825 | struct lbs_private *priv; | 810 | struct lbs_private *priv; |
826 | struct if_cs_card *card; | 811 | struct if_cs_card *card; |
812 | const struct firmware *helper = NULL; | ||
813 | const struct firmware *mainfw = NULL; | ||
827 | 814 | ||
828 | lbs_deb_enter(LBS_DEB_CS); | 815 | lbs_deb_enter(LBS_DEB_CS); |
829 | 816 | ||
830 | card = kzalloc(sizeof(struct if_cs_card), GFP_KERNEL); | 817 | card = kzalloc(sizeof(struct if_cs_card), GFP_KERNEL); |
831 | if (!card) { | 818 | if (!card) { |
832 | lbs_pr_err("error in kzalloc\n"); | 819 | pr_err("error in kzalloc\n"); |
833 | goto out; | 820 | goto out; |
834 | } | 821 | } |
835 | card->p_dev = p_dev; | 822 | card->p_dev = p_dev; |
836 | p_dev->priv = card; | 823 | p_dev->priv = card; |
837 | 824 | ||
838 | p_dev->conf.Attributes = 0; | 825 | p_dev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; |
839 | p_dev->conf.IntType = INT_MEMORY_AND_IO; | ||
840 | 826 | ||
841 | if (pcmcia_loop_config(p_dev, if_cs_ioprobe, NULL)) { | 827 | if (pcmcia_loop_config(p_dev, if_cs_ioprobe, NULL)) { |
842 | lbs_pr_err("error in pcmcia_loop_config\n"); | 828 | pr_err("error in pcmcia_loop_config\n"); |
843 | goto out1; | 829 | goto out1; |
844 | } | 830 | } |
845 | 831 | ||
846 | |||
847 | /* | 832 | /* |
848 | * Allocate an interrupt line. Note that this does not assign | 833 | * Allocate an interrupt line. Note that this does not assign |
849 | * a handler to the interrupt, unless the 'Handler' member of | 834 | * a handler to the interrupt, unless the 'Handler' member of |
@@ -856,19 +841,14 @@ static int if_cs_probe(struct pcmcia_device *p_dev) | |||
856 | card->iobase = ioport_map(p_dev->resource[0]->start, | 841 | card->iobase = ioport_map(p_dev->resource[0]->start, |
857 | resource_size(p_dev->resource[0])); | 842 | resource_size(p_dev->resource[0])); |
858 | if (!card->iobase) { | 843 | if (!card->iobase) { |
859 | lbs_pr_err("error in ioport_map\n"); | 844 | pr_err("error in ioport_map\n"); |
860 | ret = -EIO; | 845 | ret = -EIO; |
861 | goto out1; | 846 | goto out1; |
862 | } | 847 | } |
863 | 848 | ||
864 | /* | 849 | ret = pcmcia_enable_device(p_dev); |
865 | * This actually configures the PCMCIA socket -- setting up | ||
866 | * the I/O windows and the interrupt mapping, and putting the | ||
867 | * card and host interface into "Memory and IO" mode. | ||
868 | */ | ||
869 | ret = pcmcia_request_configuration(p_dev, &p_dev->conf); | ||
870 | if (ret) { | 850 | if (ret) { |
871 | lbs_pr_err("error in pcmcia_request_configuration\n"); | 851 | pr_err("error in pcmcia_enable_device\n"); |
872 | goto out2; | 852 | goto out2; |
873 | } | 853 | } |
874 | 854 | ||
@@ -877,38 +857,51 @@ static int if_cs_probe(struct pcmcia_device *p_dev) | |||
877 | 857 | ||
878 | /* | 858 | /* |
879 | * Most of the libertas cards can do unaligned register access, but some | 859 | * Most of the libertas cards can do unaligned register access, but some |
880 | * weird ones can not. That's especially true for the CF8305 card. | 860 | * weird ones cannot. That's especially true for the CF8305 card. |
881 | */ | 861 | */ |
882 | card->align_regs = 0; | 862 | card->align_regs = 0; |
883 | 863 | ||
864 | card->model = get_model(p_dev->manf_id, p_dev->card_id); | ||
865 | if (card->model == MODEL_UNKNOWN) { | ||
866 | pr_err("unsupported manf_id 0x%04x / card_id 0x%04x\n", | ||
867 | p_dev->manf_id, p_dev->card_id); | ||
868 | goto out2; | ||
869 | } | ||
870 | |||
884 | /* Check if we have a current silicon */ | 871 | /* Check if we have a current silicon */ |
885 | prod_id = if_cs_read8(card, IF_CS_PRODUCT_ID); | 872 | prod_id = if_cs_read8(card, IF_CS_PRODUCT_ID); |
886 | if (if_cs_hw_is_cf8305(p_dev)) { | 873 | if (card->model == MODEL_8305) { |
887 | card->align_regs = 1; | 874 | card->align_regs = 1; |
888 | if (prod_id < IF_CS_CF8305_B1_REV) { | 875 | if (prod_id < IF_CS_CF8305_B1_REV) { |
889 | lbs_pr_err("old chips like 8305 rev B3 " | 876 | pr_err("8305 rev B0 and older are not supported\n"); |
890 | "aren't supported\n"); | ||
891 | ret = -ENODEV; | 877 | ret = -ENODEV; |
892 | goto out2; | 878 | goto out2; |
893 | } | 879 | } |
894 | } | 880 | } |
895 | 881 | ||
896 | if (if_cs_hw_is_cf8381(p_dev) && prod_id < IF_CS_CF8381_B3_REV) { | 882 | 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"); | 883 | pr_err("8381 rev B2 and older are not supported\n"); |
898 | ret = -ENODEV; | 884 | ret = -ENODEV; |
899 | goto out2; | 885 | goto out2; |
900 | } | 886 | } |
901 | 887 | ||
902 | if (if_cs_hw_is_cf8385(p_dev) && prod_id < IF_CS_CF8385_B1_REV) { | 888 | 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"); | 889 | pr_err("8385 rev B0 and older are not supported\n"); |
904 | ret = -ENODEV; | 890 | ret = -ENODEV; |
905 | goto out2; | 891 | goto out2; |
906 | } | 892 | } |
907 | 893 | ||
894 | ret = lbs_get_firmware(&p_dev->dev, NULL, NULL, card->model, | ||
895 | &fw_table[0], &helper, &mainfw); | ||
896 | if (ret) { | ||
897 | pr_err("failed to find firmware (%d)\n", ret); | ||
898 | goto out2; | ||
899 | } | ||
900 | |||
908 | /* Load the firmware early, before calling into libertas.ko */ | 901 | /* Load the firmware early, before calling into libertas.ko */ |
909 | ret = if_cs_prog_helper(card); | 902 | ret = if_cs_prog_helper(card, helper); |
910 | if (ret == 0 && !if_cs_hw_is_cf8305(p_dev)) | 903 | if (ret == 0 && (card->model != MODEL_8305)) |
911 | ret = if_cs_prog_real(card); | 904 | ret = if_cs_prog_real(card, mainfw); |
912 | if (ret) | 905 | if (ret) |
913 | goto out2; | 906 | goto out2; |
914 | 907 | ||
@@ -932,18 +925,20 @@ static int if_cs_probe(struct pcmcia_device *p_dev) | |||
932 | ret = request_irq(p_dev->irq, if_cs_interrupt, | 925 | ret = request_irq(p_dev->irq, if_cs_interrupt, |
933 | IRQF_SHARED, DRV_NAME, card); | 926 | IRQF_SHARED, DRV_NAME, card); |
934 | if (ret) { | 927 | if (ret) { |
935 | lbs_pr_err("error in request_irq\n"); | 928 | pr_err("error in request_irq\n"); |
936 | goto out3; | 929 | goto out3; |
937 | } | 930 | } |
938 | 931 | ||
939 | /* Clear any interrupt cause that happend while sending | 932 | /* |
940 | * firmware/initializing card */ | 933 | * Clear any interrupt cause that happened while sending |
934 | * firmware/initializing card | ||
935 | */ | ||
941 | if_cs_write16(card, IF_CS_CARD_INT_CAUSE, IF_CS_BIT_MASK); | 936 | if_cs_write16(card, IF_CS_CARD_INT_CAUSE, IF_CS_BIT_MASK); |
942 | if_cs_enable_ints(card); | 937 | if_cs_enable_ints(card); |
943 | 938 | ||
944 | /* And finally bring the card up */ | 939 | /* And finally bring the card up */ |
945 | if (lbs_start_card(priv) != 0) { | 940 | if (lbs_start_card(priv) != 0) { |
946 | lbs_pr_err("could not activate card\n"); | 941 | pr_err("could not activate card\n"); |
947 | goto out3; | 942 | goto out3; |
948 | } | 943 | } |
949 | 944 | ||
@@ -957,17 +952,16 @@ out2: | |||
957 | out1: | 952 | out1: |
958 | pcmcia_disable_device(p_dev); | 953 | pcmcia_disable_device(p_dev); |
959 | out: | 954 | out: |
955 | if (helper) | ||
956 | release_firmware(helper); | ||
957 | if (mainfw) | ||
958 | release_firmware(mainfw); | ||
959 | |||
960 | lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); | 960 | lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); |
961 | return ret; | 961 | return ret; |
962 | } | 962 | } |
963 | 963 | ||
964 | 964 | ||
965 | /* | ||
966 | * This deletes a driver "instance". The device is de-registered with | ||
967 | * Card Services. If it has been released, all local data structures | ||
968 | * are freed. Otherwise, the structures will be freed when the device | ||
969 | * is released. | ||
970 | */ | ||
971 | static void if_cs_detach(struct pcmcia_device *p_dev) | 965 | static void if_cs_detach(struct pcmcia_device *p_dev) |
972 | { | 966 | { |
973 | struct if_cs_card *card = p_dev->priv; | 967 | struct if_cs_card *card = p_dev->priv; |
@@ -989,10 +983,11 @@ static void if_cs_detach(struct pcmcia_device *p_dev) | |||
989 | /* Module initialization */ | 983 | /* Module initialization */ |
990 | /********************************************************************/ | 984 | /********************************************************************/ |
991 | 985 | ||
992 | static struct pcmcia_device_id if_cs_ids[] = { | 986 | static const struct pcmcia_device_id if_cs_ids[] = { |
993 | PCMCIA_DEVICE_MANF_CARD(CF8305_MANFID, CF8305_CARDID), | 987 | PCMCIA_DEVICE_MANF_CARD(CF8305_MANFID, CF8305_CARDID), |
994 | PCMCIA_DEVICE_MANF_CARD(CF8381_MANFID, CF8381_CARDID), | 988 | PCMCIA_DEVICE_MANF_CARD(CF8381_MANFID, CF8381_CARDID), |
995 | PCMCIA_DEVICE_MANF_CARD(CF8385_MANFID, CF8385_CARDID), | 989 | PCMCIA_DEVICE_MANF_CARD(CF8385_MANFID, CF8385_CARDID), |
990 | /* NOTE: keep in sync with get_model() */ | ||
996 | PCMCIA_DEVICE_NULL, | 991 | PCMCIA_DEVICE_NULL, |
997 | }; | 992 | }; |
998 | MODULE_DEVICE_TABLE(pcmcia, if_cs_ids); | 993 | MODULE_DEVICE_TABLE(pcmcia, if_cs_ids); |
@@ -1000,9 +995,7 @@ MODULE_DEVICE_TABLE(pcmcia, if_cs_ids); | |||
1000 | 995 | ||
1001 | static struct pcmcia_driver lbs_driver = { | 996 | static struct pcmcia_driver lbs_driver = { |
1002 | .owner = THIS_MODULE, | 997 | .owner = THIS_MODULE, |
1003 | .drv = { | 998 | .name = DRV_NAME, |
1004 | .name = DRV_NAME, | ||
1005 | }, | ||
1006 | .probe = if_cs_probe, | 999 | .probe = if_cs_probe, |
1007 | .remove = if_cs_detach, | 1000 | .remove = if_cs_detach, |
1008 | .id_table = if_cs_ids, | 1001 | .id_table = if_cs_ids, |