diff options
author | Bing Zhao <bzhao@marvell.com> | 2009-05-19 22:48:19 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-05-22 14:06:00 -0400 |
commit | b136a1414c94b4bda1057b4ffde26253d2527628 (patch) | |
tree | 0a534b4665d2b9478f2372473587b1d881e783e7 /drivers/net/wireless/libertas/if_sdio.c | |
parent | e70a5ac5d27166cfe5bfbe8f63017af3b09d72ce (diff) |
libertas: get SD8688 rx length with one CMD52
Usually, the 16-bit rx length is read from scratch pad registers
with two CMD52 transactions:
SD8385: IF_SDIO_SCRATCH_OLD (0x80fe/0x80ff)
SD8686/SD8688: IF_SDIO_SCRATCH (0x34/0x35)
Alternatively, SD8688 firmware offers an enhanced method for driver
to read an 8-bit rx length (in units) with a single CMD52:
IF_SDIO_RX_UNIT 0x43 is read one time after firmware is ready.
IF_SDIO_RX_LEN 0x42 is read every time when rx interrupt is received.
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Acked-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 | 57 |
1 files changed, 55 insertions, 2 deletions
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index 69d7fd31319a..e998c123e0c5 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c | |||
@@ -107,6 +107,8 @@ struct if_sdio_card { | |||
107 | 107 | ||
108 | struct workqueue_struct *workqueue; | 108 | struct workqueue_struct *workqueue; |
109 | struct work_struct packet_worker; | 109 | struct work_struct packet_worker; |
110 | |||
111 | u8 rx_unit; | ||
110 | }; | 112 | }; |
111 | 113 | ||
112 | /********************************************************************/ | 114 | /********************************************************************/ |
@@ -136,6 +138,46 @@ static u16 if_sdio_read_scratch(struct if_sdio_card *card, int *err) | |||
136 | return scratch; | 138 | return scratch; |
137 | } | 139 | } |
138 | 140 | ||
141 | static u8 if_sdio_read_rx_unit(struct if_sdio_card *card) | ||
142 | { | ||
143 | int ret; | ||
144 | u8 rx_unit; | ||
145 | |||
146 | rx_unit = sdio_readb(card->func, IF_SDIO_RX_UNIT, &ret); | ||
147 | |||
148 | if (ret) | ||
149 | rx_unit = 0; | ||
150 | |||
151 | return rx_unit; | ||
152 | } | ||
153 | |||
154 | static u16 if_sdio_read_rx_len(struct if_sdio_card *card, int *err) | ||
155 | { | ||
156 | int ret; | ||
157 | u16 rx_len; | ||
158 | |||
159 | switch (card->model) { | ||
160 | case IF_SDIO_MODEL_8385: | ||
161 | case IF_SDIO_MODEL_8686: | ||
162 | rx_len = if_sdio_read_scratch(card, &ret); | ||
163 | break; | ||
164 | case IF_SDIO_MODEL_8688: | ||
165 | default: /* for newer chipsets */ | ||
166 | rx_len = sdio_readb(card->func, IF_SDIO_RX_LEN, &ret); | ||
167 | if (!ret) | ||
168 | rx_len <<= card->rx_unit; | ||
169 | else | ||
170 | rx_len = 0xffff; /* invalid length */ | ||
171 | |||
172 | break; | ||
173 | } | ||
174 | |||
175 | if (err) | ||
176 | *err = ret; | ||
177 | |||
178 | return rx_len; | ||
179 | } | ||
180 | |||
139 | static int if_sdio_handle_cmd(struct if_sdio_card *card, | 181 | static int if_sdio_handle_cmd(struct if_sdio_card *card, |
140 | u8 *buffer, unsigned size) | 182 | u8 *buffer, unsigned size) |
141 | { | 183 | { |
@@ -254,7 +296,7 @@ static int if_sdio_card_to_host(struct if_sdio_card *card) | |||
254 | 296 | ||
255 | lbs_deb_enter(LBS_DEB_SDIO); | 297 | lbs_deb_enter(LBS_DEB_SDIO); |
256 | 298 | ||
257 | size = if_sdio_read_scratch(card, &ret); | 299 | size = if_sdio_read_rx_len(card, &ret); |
258 | if (ret) | 300 | if (ret) |
259 | goto out; | 301 | goto out; |
260 | 302 | ||
@@ -923,10 +965,21 @@ static int if_sdio_probe(struct sdio_func *func, | |||
923 | 965 | ||
924 | priv->fw_ready = 1; | 966 | priv->fw_ready = 1; |
925 | 967 | ||
968 | sdio_claim_host(func); | ||
969 | |||
970 | /* | ||
971 | * Get rx_unit if the chip is SD8688 or newer. | ||
972 | * SD8385 & SD8686 do not have rx_unit. | ||
973 | */ | ||
974 | if ((card->model != IF_SDIO_MODEL_8385) | ||
975 | && (card->model != IF_SDIO_MODEL_8686)) | ||
976 | card->rx_unit = if_sdio_read_rx_unit(card); | ||
977 | else | ||
978 | card->rx_unit = 0; | ||
979 | |||
926 | /* | 980 | /* |
927 | * Enable interrupts now that everything is set up | 981 | * Enable interrupts now that everything is set up |
928 | */ | 982 | */ |
929 | sdio_claim_host(func); | ||
930 | sdio_writeb(func, 0x0f, IF_SDIO_H_INT_MASK, &ret); | 983 | sdio_writeb(func, 0x0f, IF_SDIO_H_INT_MASK, &ret); |
931 | sdio_release_host(func); | 984 | sdio_release_host(func); |
932 | if (ret) | 985 | if (ret) |