aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/wl1271_spi.c
diff options
context:
space:
mode:
authorJuuso Oikarinen <juuso.oikarinen@nokia.com>2009-10-08 14:56:23 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-10-27 16:47:49 -0400
commit545f1da8ef0f20923feb500bcfaf0e2fb6068fb4 (patch)
treeb245ba9ed9abffa9f53de1cd33f7c3108eb8fa6a /drivers/net/wireless/wl12xx/wl1271_spi.c
parentc3fea1994ac34dafa3ebb40d4f95354b2782af31 (diff)
wl1271: Implementation for SPI busy word checking
This patch adds implementation for checking for SPI busy words - i.e. honoring a delay request from the WLAN chipset upon reading registers/memory. To optimized the average SPI ready by 32 bits, also configure the number of busywords to one to disable the "fixed-busy-word" functionality. Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com> Reviewed-by: Vidhya Govindan <vidhya.govindan@nokia.com> Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx/wl1271_spi.c')
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_spi.c69
1 files changed, 67 insertions, 2 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c
index 4a12880c16a8..504991acb052 100644
--- a/drivers/net/wireless/wl12xx/wl1271_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1271_spi.c
@@ -244,12 +244,75 @@ int wl1271_set_partition(struct wl1271 *wl,
244 return 0; 244 return 0;
245} 245}
246 246
247#define WL1271_BUSY_WORD_TIMEOUT 1000
248
249void wl1271_spi_read_busy(struct wl1271 *wl, void *buf, size_t len)
250{
251 struct spi_transfer t[1];
252 struct spi_message m;
253 u32 *busy_buf;
254 int num_busy_bytes = 0;
255
256 wl1271_info("spi read BUSY!");
257
258 /*
259 * Look for the non-busy word in the read buffer, and if found,
260 * read in the remaining data into the buffer.
261 */
262 busy_buf = (u32 *)buf;
263 for (; (u32)busy_buf < (u32)buf + len; busy_buf++) {
264 num_busy_bytes += sizeof(u32);
265 if (*busy_buf & 0x1) {
266 spi_message_init(&m);
267 memset(t, 0, sizeof(t));
268 memmove(buf, busy_buf, len - num_busy_bytes);
269 t[0].rx_buf = buf + (len - num_busy_bytes);
270 t[0].len = num_busy_bytes;
271 spi_message_add_tail(&t[0], &m);
272 spi_sync(wl->spi, &m);
273 return;
274 }
275 }
276
277 /*
278 * Read further busy words from SPI until a non-busy word is
279 * encountered, then read the data itself into the buffer.
280 */
281 wl1271_info("spi read BUSY-polling needed!");
282
283 num_busy_bytes = WL1271_BUSY_WORD_TIMEOUT;
284 busy_buf = wl->buffer_busyword;
285 while (num_busy_bytes) {
286 num_busy_bytes--;
287 spi_message_init(&m);
288 memset(t, 0, sizeof(t));
289 t[0].rx_buf = busy_buf;
290 t[0].len = sizeof(u32);
291 spi_message_add_tail(&t[0], &m);
292 spi_sync(wl->spi, &m);
293
294 if (*busy_buf & 0x1) {
295 spi_message_init(&m);
296 memset(t, 0, sizeof(t));
297 t[0].rx_buf = buf;
298 t[0].len = len;
299 spi_message_add_tail(&t[0], &m);
300 spi_sync(wl->spi, &m);
301 return;
302 }
303 }
304
305 /* The SPI bus is unresponsive, the read failed. */
306 memset(buf, 0, len);
307 wl1271_error("SPI read busy-word timeout!\n");
308}
309
247void wl1271_spi_read(struct wl1271 *wl, int addr, void *buf, 310void wl1271_spi_read(struct wl1271 *wl, int addr, void *buf,
248 size_t len, bool fixed) 311 size_t len, bool fixed)
249{ 312{
250 struct spi_transfer t[3]; 313 struct spi_transfer t[3];
251 struct spi_message m; 314 struct spi_message m;
252 u8 *busy_buf; 315 u32 *busy_buf;
253 u32 *cmd; 316 u32 *cmd;
254 317
255 cmd = &wl->buffer_cmd; 318 cmd = &wl->buffer_cmd;
@@ -281,7 +344,9 @@ void wl1271_spi_read(struct wl1271 *wl, int addr, void *buf,
281 344
282 spi_sync(wl->spi, &m); 345 spi_sync(wl->spi, &m);
283 346
284 /* FIXME: check busy words */ 347 /* Check busy words */
348 if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1))
349 wl1271_spi_read_busy(wl, buf, len);
285 350
286 wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd)); 351 wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd));
287 wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, len); 352 wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, len);