diff options
Diffstat (limited to 'drivers/net/wireless/libertas/if_spi.c')
-rw-r--r-- | drivers/net/wireless/libertas/if_spi.c | 143 |
1 files changed, 13 insertions, 130 deletions
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index 5b3672c4d0cc..bf4bfbae6227 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c | |||
@@ -32,12 +32,6 @@ | |||
32 | #include "dev.h" | 32 | #include "dev.h" |
33 | #include "if_spi.h" | 33 | #include "if_spi.h" |
34 | 34 | ||
35 | struct if_spi_packet { | ||
36 | struct list_head list; | ||
37 | u16 blen; | ||
38 | u8 buffer[0] __attribute__((aligned(4))); | ||
39 | }; | ||
40 | |||
41 | struct if_spi_card { | 35 | struct if_spi_card { |
42 | struct spi_device *spi; | 36 | struct spi_device *spi; |
43 | struct lbs_private *priv; | 37 | struct lbs_private *priv; |
@@ -66,33 +60,10 @@ struct if_spi_card { | |||
66 | struct semaphore spi_thread_terminated; | 60 | struct semaphore spi_thread_terminated; |
67 | 61 | ||
68 | u8 cmd_buffer[IF_SPI_CMD_BUF_SIZE]; | 62 | u8 cmd_buffer[IF_SPI_CMD_BUF_SIZE]; |
69 | |||
70 | /* A buffer of incoming packets from libertas core. | ||
71 | * Since we can't sleep in hw_host_to_card, we have to buffer | ||
72 | * them. */ | ||
73 | struct list_head cmd_packet_list; | ||
74 | struct list_head data_packet_list; | ||
75 | |||
76 | /* Protects cmd_packet_list and data_packet_list */ | ||
77 | spinlock_t buffer_lock; | ||
78 | }; | 63 | }; |
79 | 64 | ||
80 | static void free_if_spi_card(struct if_spi_card *card) | 65 | static void free_if_spi_card(struct if_spi_card *card) |
81 | { | 66 | { |
82 | struct list_head *cursor, *next; | ||
83 | struct if_spi_packet *packet; | ||
84 | |||
85 | BUG_ON(card->run_thread); | ||
86 | list_for_each_safe(cursor, next, &card->cmd_packet_list) { | ||
87 | packet = container_of(cursor, struct if_spi_packet, list); | ||
88 | list_del(&packet->list); | ||
89 | kfree(packet); | ||
90 | } | ||
91 | list_for_each_safe(cursor, next, &card->data_packet_list) { | ||
92 | packet = container_of(cursor, struct if_spi_packet, list); | ||
93 | list_del(&packet->list); | ||
94 | kfree(packet); | ||
95 | } | ||
96 | spi_set_drvdata(card->spi, NULL); | 67 | spi_set_drvdata(card->spi, NULL); |
97 | kfree(card); | 68 | kfree(card); |
98 | } | 69 | } |
@@ -774,40 +745,6 @@ out: | |||
774 | return err; | 745 | return err; |
775 | } | 746 | } |
776 | 747 | ||
777 | /* Move data or a command from the host to the card. */ | ||
778 | static void if_spi_h2c(struct if_spi_card *card, | ||
779 | struct if_spi_packet *packet, int type) | ||
780 | { | ||
781 | int err = 0; | ||
782 | u16 int_type, port_reg; | ||
783 | |||
784 | switch (type) { | ||
785 | case MVMS_DAT: | ||
786 | int_type = IF_SPI_CIC_TX_DOWNLOAD_OVER; | ||
787 | port_reg = IF_SPI_DATA_RDWRPORT_REG; | ||
788 | break; | ||
789 | case MVMS_CMD: | ||
790 | int_type = IF_SPI_CIC_CMD_DOWNLOAD_OVER; | ||
791 | port_reg = IF_SPI_CMD_RDWRPORT_REG; | ||
792 | break; | ||
793 | default: | ||
794 | lbs_pr_err("can't transfer buffer of type %d\n", type); | ||
795 | err = -EINVAL; | ||
796 | goto out; | ||
797 | } | ||
798 | |||
799 | /* Write the data to the card */ | ||
800 | err = spu_write(card, port_reg, packet->buffer, packet->blen); | ||
801 | if (err) | ||
802 | goto out; | ||
803 | |||
804 | out: | ||
805 | kfree(packet); | ||
806 | |||
807 | if (err) | ||
808 | lbs_pr_err("%s: error %d\n", __func__, err); | ||
809 | } | ||
810 | |||
811 | /* Inform the host about a card event */ | 748 | /* Inform the host about a card event */ |
812 | static void if_spi_e2h(struct if_spi_card *card) | 749 | static void if_spi_e2h(struct if_spi_card *card) |
813 | { | 750 | { |
@@ -837,8 +774,6 @@ static int lbs_spi_thread(void *data) | |||
837 | int err; | 774 | int err; |
838 | struct if_spi_card *card = data; | 775 | struct if_spi_card *card = data; |
839 | u16 hiStatus; | 776 | u16 hiStatus; |
840 | unsigned long flags; | ||
841 | struct if_spi_packet *packet; | ||
842 | 777 | ||
843 | while (1) { | 778 | while (1) { |
844 | /* Wait to be woken up by one of two things. First, our ISR | 779 | /* Wait to be woken up by one of two things. First, our ISR |
@@ -877,43 +812,9 @@ static int lbs_spi_thread(void *data) | |||
877 | if (hiStatus & IF_SPI_HIST_CMD_DOWNLOAD_RDY || | 812 | if (hiStatus & IF_SPI_HIST_CMD_DOWNLOAD_RDY || |
878 | (card->priv->psstate != PS_STATE_FULL_POWER && | 813 | (card->priv->psstate != PS_STATE_FULL_POWER && |
879 | (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY))) { | 814 | (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY))) { |
880 | /* This means two things. First of all, | ||
881 | * if there was a previous command sent, the card has | ||
882 | * successfully received it. | ||
883 | * Secondly, it is now ready to download another | ||
884 | * command. | ||
885 | */ | ||
886 | lbs_host_to_card_done(card->priv); | 815 | lbs_host_to_card_done(card->priv); |
887 | |||
888 | /* Do we have any command packets from the host to | ||
889 | * send? */ | ||
890 | packet = NULL; | ||
891 | spin_lock_irqsave(&card->buffer_lock, flags); | ||
892 | if (!list_empty(&card->cmd_packet_list)) { | ||
893 | packet = (struct if_spi_packet *)(card-> | ||
894 | cmd_packet_list.next); | ||
895 | list_del(&packet->list); | ||
896 | } | ||
897 | spin_unlock_irqrestore(&card->buffer_lock, flags); | ||
898 | |||
899 | if (packet) | ||
900 | if_spi_h2c(card, packet, MVMS_CMD); | ||
901 | } | 816 | } |
902 | if (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY) { | ||
903 | /* Do we have any data packets from the host to | ||
904 | * send? */ | ||
905 | packet = NULL; | ||
906 | spin_lock_irqsave(&card->buffer_lock, flags); | ||
907 | if (!list_empty(&card->data_packet_list)) { | ||
908 | packet = (struct if_spi_packet *)(card-> | ||
909 | data_packet_list.next); | ||
910 | list_del(&packet->list); | ||
911 | } | ||
912 | spin_unlock_irqrestore(&card->buffer_lock, flags); | ||
913 | 817 | ||
914 | if (packet) | ||
915 | if_spi_h2c(card, packet, MVMS_DAT); | ||
916 | } | ||
917 | if (hiStatus & IF_SPI_HIST_CARD_EVENT) | 818 | if (hiStatus & IF_SPI_HIST_CARD_EVENT) |
918 | if_spi_e2h(card); | 819 | if_spi_e2h(card); |
919 | 820 | ||
@@ -942,40 +843,18 @@ static int if_spi_host_to_card(struct lbs_private *priv, | |||
942 | u8 type, u8 *buf, u16 nb) | 843 | u8 type, u8 *buf, u16 nb) |
943 | { | 844 | { |
944 | int err = 0; | 845 | int err = 0; |
945 | unsigned long flags; | ||
946 | struct if_spi_card *card = priv->card; | 846 | struct if_spi_card *card = priv->card; |
947 | struct if_spi_packet *packet; | ||
948 | u16 blen; | ||
949 | 847 | ||
950 | lbs_deb_enter_args(LBS_DEB_SPI, "type %d, bytes %d", type, nb); | 848 | lbs_deb_enter_args(LBS_DEB_SPI, "type %d, bytes %d", type, nb); |
951 | 849 | ||
952 | if (nb == 0) { | 850 | nb = ALIGN(nb, 4); |
953 | lbs_pr_err("%s: invalid size requested: %d\n", __func__, nb); | ||
954 | err = -EINVAL; | ||
955 | goto out; | ||
956 | } | ||
957 | blen = ALIGN(nb, 4); | ||
958 | packet = kzalloc(sizeof(struct if_spi_packet) + blen, GFP_ATOMIC); | ||
959 | if (!packet) { | ||
960 | err = -ENOMEM; | ||
961 | goto out; | ||
962 | } | ||
963 | packet->blen = blen; | ||
964 | memcpy(packet->buffer, buf, nb); | ||
965 | memset(packet->buffer + nb, 0, blen - nb); | ||
966 | 851 | ||
967 | switch (type) { | 852 | switch (type) { |
968 | case MVMS_CMD: | 853 | case MVMS_CMD: |
969 | priv->dnld_sent = DNLD_CMD_SENT; | 854 | err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG, buf, nb); |
970 | spin_lock_irqsave(&card->buffer_lock, flags); | ||
971 | list_add_tail(&packet->list, &card->cmd_packet_list); | ||
972 | spin_unlock_irqrestore(&card->buffer_lock, flags); | ||
973 | break; | 855 | break; |
974 | case MVMS_DAT: | 856 | case MVMS_DAT: |
975 | priv->dnld_sent = DNLD_DATA_SENT; | 857 | err = spu_write(card, IF_SPI_DATA_RDWRPORT_REG, buf, nb); |
976 | spin_lock_irqsave(&card->buffer_lock, flags); | ||
977 | list_add_tail(&packet->list, &card->data_packet_list); | ||
978 | spin_unlock_irqrestore(&card->buffer_lock, flags); | ||
979 | break; | 858 | break; |
980 | default: | 859 | default: |
981 | lbs_pr_err("can't transfer buffer of type %d", type); | 860 | lbs_pr_err("can't transfer buffer of type %d", type); |
@@ -983,9 +862,6 @@ static int if_spi_host_to_card(struct lbs_private *priv, | |||
983 | break; | 862 | break; |
984 | } | 863 | } |
985 | 864 | ||
986 | /* Wake up the spi thread */ | ||
987 | up(&card->spi_ready); | ||
988 | out: | ||
989 | lbs_deb_leave_args(LBS_DEB_SPI, "err=%d", err); | 865 | lbs_deb_leave_args(LBS_DEB_SPI, "err=%d", err); |
990 | return err; | 866 | return err; |
991 | } | 867 | } |
@@ -1026,6 +902,10 @@ static int if_spi_calculate_fw_names(u16 card_id, | |||
1026 | chip_id_to_device_name[i].name); | 902 | chip_id_to_device_name[i].name); |
1027 | return 0; | 903 | return 0; |
1028 | } | 904 | } |
905 | MODULE_FIRMWARE("libertas/gspi8385_hlp.bin"); | ||
906 | MODULE_FIRMWARE("libertas/gspi8385.bin"); | ||
907 | MODULE_FIRMWARE("libertas/gspi8686_hlp.bin"); | ||
908 | MODULE_FIRMWARE("libertas/gspi8686.bin"); | ||
1029 | 909 | ||
1030 | static int __devinit if_spi_probe(struct spi_device *spi) | 910 | static int __devinit if_spi_probe(struct spi_device *spi) |
1031 | { | 911 | { |
@@ -1062,9 +942,6 @@ static int __devinit if_spi_probe(struct spi_device *spi) | |||
1062 | 942 | ||
1063 | sema_init(&card->spi_ready, 0); | 943 | sema_init(&card->spi_ready, 0); |
1064 | sema_init(&card->spi_thread_terminated, 0); | 944 | sema_init(&card->spi_thread_terminated, 0); |
1065 | INIT_LIST_HEAD(&card->cmd_packet_list); | ||
1066 | INIT_LIST_HEAD(&card->data_packet_list); | ||
1067 | spin_lock_init(&card->buffer_lock); | ||
1068 | 945 | ||
1069 | /* Initialize the SPI Interface Unit */ | 946 | /* Initialize the SPI Interface Unit */ |
1070 | err = spu_init(card, pdata->use_dummy_writes); | 947 | err = spu_init(card, pdata->use_dummy_writes); |
@@ -1117,6 +994,9 @@ static int __devinit if_spi_probe(struct spi_device *spi) | |||
1117 | card->priv = priv; | 994 | card->priv = priv; |
1118 | priv->card = card; | 995 | priv->card = card; |
1119 | priv->hw_host_to_card = if_spi_host_to_card; | 996 | priv->hw_host_to_card = if_spi_host_to_card; |
997 | priv->enter_deep_sleep = NULL; | ||
998 | priv->exit_deep_sleep = NULL; | ||
999 | priv->reset_deep_sleep_wakeup = NULL; | ||
1120 | priv->fw_ready = 1; | 1000 | priv->fw_ready = 1; |
1121 | 1001 | ||
1122 | /* Initialize interrupt handling stuff. */ | 1002 | /* Initialize interrupt handling stuff. */ |
@@ -1138,6 +1018,9 @@ static int __devinit if_spi_probe(struct spi_device *spi) | |||
1138 | goto terminate_thread; | 1018 | goto terminate_thread; |
1139 | } | 1019 | } |
1140 | 1020 | ||
1021 | /* poke the IRQ handler so that we don't miss the first interrupt */ | ||
1022 | up(&card->spi_ready); | ||
1023 | |||
1141 | /* Start the card. | 1024 | /* Start the card. |
1142 | * This will call register_netdev, and we'll start | 1025 | * This will call register_netdev, and we'll start |
1143 | * getting interrupts... */ | 1026 | * getting interrupts... */ |