aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorJuuso Oikarinen <juuso.oikarinen@nokia.com>2010-03-26 06:53:18 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-03-31 14:39:13 -0400
commit259da430b198fc7e6f21e33be3a2d6dd27200953 (patch)
tree439f01e2e0a803e8f702f45869ac0ca0310e900b /drivers/net/wireless
parent1b00f2b560028a68cdbc57a0352163afd79822dd (diff)
wl1271: Update busyword checking mechanism
After the busy-words, if the firmware did not complete by the end of the first (fixed) busy-word, a flip of the CS line is required to enable clocking out the actual read data. This patch changes the mechanism such that the CS line is flipped after each busyword. Also, the busy-word mechanism is finally enabled, and the number of fixed busywords reduced to the minimum. Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com> Reviewed-by: Teemu Paasikivi <ext-teemu.3.paasikivi@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')
-rw-r--r--drivers/net/wireless/wl12xx/wl1271.h9
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_spi.c67
2 files changed, 24 insertions, 52 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h
index 8f11506f8310..c93968092fc1 100644
--- a/drivers/net/wireless/wl12xx/wl1271.h
+++ b/drivers/net/wireless/wl12xx/wl1271.h
@@ -147,14 +147,7 @@ struct wl1271_nvs_file {
147 */ 147 */
148#undef WL1271_80211A_ENABLED 148#undef WL1271_80211A_ENABLED
149 149
150/* 150#define WL1271_BUSY_WORD_CNT 1
151 * FIXME: for the wl1271, a busy word count of 1 here will result in a more
152 * optimal SPI interface. There is some SPI bug however, causing RXS time outs
153 * with this mode occasionally on boot, so lets have three for now. A value of
154 * three should make sure, that the chipset will always be ready, though this
155 * will impact throughput and latencies slightly.
156 */
157#define WL1271_BUSY_WORD_CNT 3
158#define WL1271_BUSY_WORD_LEN (WL1271_BUSY_WORD_CNT * sizeof(u32)) 151#define WL1271_BUSY_WORD_LEN (WL1271_BUSY_WORD_CNT * sizeof(u32))
159 152
160#define WL1271_ELP_HW_STATE_ASLEEP 0 153#define WL1271_ELP_HW_STATE_ASLEEP 0
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c
index 39b7dea6358e..7a7db011a797 100644
--- a/drivers/net/wireless/wl12xx/wl1271_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1271_spi.c
@@ -166,41 +166,17 @@ static void wl1271_spi_init(struct wl1271 *wl)
166 166
167#define WL1271_BUSY_WORD_TIMEOUT 1000 167#define WL1271_BUSY_WORD_TIMEOUT 1000
168 168
169/* FIXME: Check busy words, removed due to SPI bug */ 169static int wl1271_spi_read_busy(struct wl1271 *wl)
170#if 0
171static void wl1271_spi_read_busy(struct wl1271 *wl, void *buf, size_t len)
172{ 170{
173 struct spi_transfer t[1]; 171 struct spi_transfer t[1];
174 struct spi_message m; 172 struct spi_message m;
175 u32 *busy_buf; 173 u32 *busy_buf;
176 int num_busy_bytes = 0; 174 int num_busy_bytes = 0;
177 175
178 wl1271_info("spi read BUSY!");
179
180 /*
181 * Look for the non-busy word in the read buffer, and if found,
182 * read in the remaining data into the buffer.
183 */
184 busy_buf = (u32 *)buf;
185 for (; (u32)busy_buf < (u32)buf + len; busy_buf++) {
186 num_busy_bytes += sizeof(u32);
187 if (*busy_buf & 0x1) {
188 spi_message_init(&m);
189 memset(t, 0, sizeof(t));
190 memmove(buf, busy_buf, len - num_busy_bytes);
191 t[0].rx_buf = buf + (len - num_busy_bytes);
192 t[0].len = num_busy_bytes;
193 spi_message_add_tail(&t[0], &m);
194 spi_sync(wl_to_spi(wl), &m);
195 return;
196 }
197 }
198
199 /* 176 /*
200 * Read further busy words from SPI until a non-busy word is 177 * Read further busy words from SPI until a non-busy word is
201 * encountered, then read the data itself into the buffer. 178 * encountered, then read the data itself into the buffer.
202 */ 179 */
203 wl1271_info("spi read BUSY-polling needed!");
204 180
205 num_busy_bytes = WL1271_BUSY_WORD_TIMEOUT; 181 num_busy_bytes = WL1271_BUSY_WORD_TIMEOUT;
206 busy_buf = wl->buffer_busyword; 182 busy_buf = wl->buffer_busyword;
@@ -210,28 +186,21 @@ static void wl1271_spi_read_busy(struct wl1271 *wl, void *buf, size_t len)
210 memset(t, 0, sizeof(t)); 186 memset(t, 0, sizeof(t));
211 t[0].rx_buf = busy_buf; 187 t[0].rx_buf = busy_buf;
212 t[0].len = sizeof(u32); 188 t[0].len = sizeof(u32);
189 t[0].cs_change = true;
213 spi_message_add_tail(&t[0], &m); 190 spi_message_add_tail(&t[0], &m);
214 spi_sync(wl_to_spi(wl), &m); 191 spi_sync(wl_to_spi(wl), &m);
215 192
216 if (*busy_buf & 0x1) { 193 if (*busy_buf & 0x1)
217 spi_message_init(&m); 194 return 0;
218 memset(t, 0, sizeof(t));
219 t[0].rx_buf = buf;
220 t[0].len = len;
221 spi_message_add_tail(&t[0], &m);
222 spi_sync(wl_to_spi(wl), &m);
223 return;
224 }
225 } 195 }
226 196
227 /* The SPI bus is unresponsive, the read failed. */ 197 /* The SPI bus is unresponsive, the read failed. */
228 memset(buf, 0, len);
229 wl1271_error("SPI read busy-word timeout!\n"); 198 wl1271_error("SPI read busy-word timeout!\n");
199 return -ETIMEDOUT;
230} 200}
231#endif
232 201
233static void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf, 202static void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf,
234 size_t len, bool fixed) 203 size_t len, bool fixed)
235{ 204{
236 struct spi_transfer t[3]; 205 struct spi_transfer t[3];
237 struct spi_message m; 206 struct spi_message m;
@@ -254,22 +223,32 @@ static void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf,
254 223
255 t[0].tx_buf = cmd; 224 t[0].tx_buf = cmd;
256 t[0].len = 4; 225 t[0].len = 4;
226 t[0].cs_change = true;
257 spi_message_add_tail(&t[0], &m); 227 spi_message_add_tail(&t[0], &m);
258 228
259 /* Busy and non busy words read */ 229 /* Busy and non busy words read */
260 t[1].rx_buf = busy_buf; 230 t[1].rx_buf = busy_buf;
261 t[1].len = WL1271_BUSY_WORD_LEN; 231 t[1].len = WL1271_BUSY_WORD_LEN;
232 t[1].cs_change = true;
262 spi_message_add_tail(&t[1], &m); 233 spi_message_add_tail(&t[1], &m);
263 234
264 t[2].rx_buf = buf;
265 t[2].len = len;
266 spi_message_add_tail(&t[2], &m);
267
268 spi_sync(wl_to_spi(wl), &m); 235 spi_sync(wl_to_spi(wl), &m);
269 236
270 /* FIXME: Check busy words, removed due to SPI bug */ 237 if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1) &&
271 /* if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1)) 238 wl1271_spi_read_busy(wl)) {
272 wl1271_spi_read_busy(wl, buf, len); */ 239 memset(buf, 0, len);
240 return;
241 }
242
243 spi_message_init(&m);
244 memset(t, 0, sizeof(t));
245
246 t[0].rx_buf = buf;
247 t[0].len = len;
248 t[0].cs_change = true;
249 spi_message_add_tail(&t[0], &m);
250
251 spi_sync(wl_to_spi(wl), &m);
273 252
274 wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd)); 253 wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd));
275 wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, len); 254 wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, len);