1 | /* |
2 | * Copyright (c) 2006 Damien Bergamini <damien.bergamini@free.fr> |
3 | * Copyright (c) 2006 Sam Leffler, Errno Consulting |
4 | * Copyright (c) 2007 Christoph Hellwig <hch@lst.de> |
5 | * Copyright (c) 2008-2009 Weongyo Jeong <weongyo@freebsd.org> |
6 | * Copyright (c) 2012 Pontus Fuchs <pontus.fuchs@gmail.com> |
7 | * |
8 | * Permission to use, copy, modify, and/or distribute this software for any |
9 | * purpose with or without fee is hereby granted, provided that the above |
10 | * copyright notice and this permission notice appear in all copies. |
11 | * |
12 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
13 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
14 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
15 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
16 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
17 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
18 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
19 | */ |
20 | |
21 | /* |
22 | * This driver is based on the uath driver written by Damien Bergamini for |
23 | * OpenBSD, who did black-box analysis of the Windows binary driver to find |
24 | * out how the hardware works. It contains a lot magic numbers because of |
25 | * that and only has minimal functionality. |
26 | */ |
27 | #include <linux/compiler.h> |
28 | #include <linux/kernel.h> |
29 | #include <linux/module.h> |
30 | #include <linux/list.h> |
31 | #include <linux/completion.h> |
32 | #include <linux/firmware.h> |
33 | #include <linux/skbuff.h> |
34 | #include <linux/usb.h> |
35 | #include <net/mac80211.h> |
36 | |
37 | #include "ar5523.h" |
38 | #include "ar5523_hw.h" |
39 | |
40 | /* |
41 | * Various supported device vendors/products. |
42 | * UB51: AR5005UG 802.11b/g, UB52: AR5005UX 802.11a/b/g |
43 | */ |
44 | |
45 | static int ar5523_submit_rx_cmd(struct ar5523 *ar); |
46 | static void ar5523_data_tx_pkt_put(struct ar5523 *ar); |
47 | |
48 | static void ar5523_read_reply(struct ar5523 *ar, struct ar5523_cmd_hdr *hdr, |
49 | struct ar5523_tx_cmd *cmd) |
50 | { |
51 | int dlen, olen; |
52 | __be32 *rp; |
53 | |
54 | dlen = be32_to_cpu(hdr->len) - sizeof(*hdr); |
55 | |
56 | if (dlen < 0) { |
57 | WARN_ON(1); |
58 | goto out; |
59 | } |
60 | |
61 | ar5523_dbg(ar, "Code = %d len = %d\n" , be32_to_cpu(hdr->code) & 0xff, |
62 | dlen); |
63 | |
64 | rp = (__be32 *)(hdr + 1); |
65 | if (dlen >= sizeof(u32)) { |
66 | olen = be32_to_cpu(rp[0]); |
67 | dlen -= sizeof(u32); |
68 | if (olen == 0) { |
69 | /* convention is 0 =>'s one word */ |
70 | olen = sizeof(u32); |
71 | } |
72 | } else |
73 | olen = 0; |
74 | |
75 | if (cmd->odata) { |
76 | if (cmd->olen < olen) { |
77 | ar5523_err(ar, "olen too small %d < %d\n" , |
78 | cmd->olen, olen); |
79 | cmd->olen = 0; |
80 | cmd->res = -EOVERFLOW; |
81 | } else { |
82 | cmd->olen = olen; |
83 | memcpy(cmd->odata, &rp[1], olen); |
84 | cmd->res = 0; |
85 | } |
86 | } |
87 | |
88 | out: |
89 | complete(&cmd->done); |
90 | } |
91 | |
92 | static void ar5523_cmd_rx_cb(struct urb *urb) |
93 | { |
94 | struct ar5523 *ar = urb->context; |
95 | struct ar5523_tx_cmd *cmd = &ar->tx_cmd; |
96 | struct ar5523_cmd_hdr *hdr = ar->rx_cmd_buf; |
97 | int dlen; |
98 | u32 code, hdrlen; |
99 | |
100 | if (urb->status) { |
101 | if (urb->status != -ESHUTDOWN) |
102 | ar5523_err(ar, "RX USB error %d.\n" , urb->status); |
103 | goto skip; |
104 | } |
105 | |
106 | if (urb->actual_length < sizeof(struct ar5523_cmd_hdr)) { |
107 | ar5523_err(ar, "RX USB too short.\n" ); |
108 | goto skip; |
109 | } |
110 | |
111 | ar5523_dbg(ar, "%s code %02x priv %d\n" , __func__, |
112 | be32_to_cpu(hdr->code) & 0xff, hdr->priv); |
113 | |
114 | code = be32_to_cpu(hdr->code); |
115 | hdrlen = be32_to_cpu(hdr->len); |
116 | |
117 | switch (code & 0xff) { |
118 | default: |
119 | /* reply to a read command */ |
120 | if (hdr->priv != AR5523_CMD_ID) { |
121 | ar5523_err(ar, "Unexpected command id: %02x\n" , |
122 | code & 0xff); |
123 | goto skip; |
124 | } |
125 | ar5523_read_reply(ar, hdr, cmd); |
126 | break; |
127 | |
128 | case WDCMSG_DEVICE_AVAIL: |
129 | ar5523_dbg(ar, "WDCMSG_DEVICE_AVAIL\n" ); |
130 | cmd->res = 0; |
131 | cmd->olen = 0; |
132 | complete(&cmd->done); |
133 | break; |
134 | |
135 | case WDCMSG_SEND_COMPLETE: |
136 | ar5523_dbg(ar, "WDCMSG_SEND_COMPLETE: %d pending\n" , |
137 | atomic_read(&ar->tx_nr_pending)); |
138 | if (!test_bit(AR5523_HW_UP, &ar->flags)) |
139 | ar5523_dbg(ar, "Unexpected WDCMSG_SEND_COMPLETE\n" ); |
140 | else { |
141 | mod_timer(timer: &ar->tx_wd_timer, |
142 | expires: jiffies + AR5523_TX_WD_TIMEOUT); |
143 | ar5523_data_tx_pkt_put(ar); |
144 | |
145 | } |
146 | break; |
147 | |
148 | case WDCMSG_TARGET_START: |
149 | /* This command returns a bogus id so it needs special |
150 | handling */ |
151 | dlen = hdrlen - sizeof(*hdr); |
152 | if (dlen != (int)sizeof(u32)) { |
153 | ar5523_err(ar, "Invalid reply to WDCMSG_TARGET_START" ); |
154 | return; |
155 | } |
156 | if (!cmd->odata) { |
157 | ar5523_err(ar, "Unexpected WDCMSG_TARGET_START reply" ); |
158 | return; |
159 | } |
160 | memcpy(cmd->odata, hdr + 1, sizeof(u32)); |
161 | cmd->olen = sizeof(u32); |
162 | cmd->res = 0; |
163 | complete(&cmd->done); |
164 | break; |
165 | |
166 | case WDCMSG_STATS_UPDATE: |
167 | ar5523_dbg(ar, "WDCMSG_STATS_UPDATE\n" ); |
168 | break; |
169 | } |
170 | |
171 | skip: |
172 | ar5523_submit_rx_cmd(ar); |
173 | } |
174 | |
175 | static int ar5523_alloc_rx_cmd(struct ar5523 *ar) |
176 | { |
177 | ar->rx_cmd_urb = usb_alloc_urb(iso_packets: 0, GFP_KERNEL); |
178 | if (!ar->rx_cmd_urb) |
179 | return -ENOMEM; |
180 | |
181 | ar->rx_cmd_buf = usb_alloc_coherent(dev: ar->dev, AR5523_MAX_RXCMDSZ, |
182 | GFP_KERNEL, |
183 | dma: &ar->rx_cmd_urb->transfer_dma); |
184 | if (!ar->rx_cmd_buf) { |
185 | usb_free_urb(urb: ar->rx_cmd_urb); |
186 | return -ENOMEM; |
187 | } |
188 | return 0; |
189 | } |
190 | |
191 | static void ar5523_cancel_rx_cmd(struct ar5523 *ar) |
192 | { |
193 | usb_kill_urb(urb: ar->rx_cmd_urb); |
194 | } |
195 | |
196 | static void ar5523_free_rx_cmd(struct ar5523 *ar) |
197 | { |
198 | usb_free_coherent(dev: ar->dev, AR5523_MAX_RXCMDSZ, |
199 | addr: ar->rx_cmd_buf, dma: ar->rx_cmd_urb->transfer_dma); |
200 | usb_free_urb(urb: ar->rx_cmd_urb); |
201 | } |
202 | |
203 | static int ar5523_submit_rx_cmd(struct ar5523 *ar) |
204 | { |
205 | int error; |
206 | |
207 | usb_fill_bulk_urb(urb: ar->rx_cmd_urb, dev: ar->dev, |
208 | ar5523_cmd_rx_pipe(ar->dev), transfer_buffer: ar->rx_cmd_buf, |
209 | AR5523_MAX_RXCMDSZ, complete_fn: ar5523_cmd_rx_cb, context: ar); |
210 | ar->rx_cmd_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
211 | |
212 | error = usb_submit_urb(urb: ar->rx_cmd_urb, GFP_ATOMIC); |
213 | if (error) { |
214 | if (error != -ENODEV) |
215 | ar5523_err(ar, "error %d when submitting rx urb\n" , |
216 | error); |
217 | return error; |
218 | } |
219 | return 0; |
220 | } |
221 | |
222 | /* |
223 | * Command submitted cb |
224 | */ |
225 | static void ar5523_cmd_tx_cb(struct urb *urb) |
226 | { |
227 | struct ar5523_tx_cmd *cmd = urb->context; |
228 | struct ar5523 *ar = cmd->ar; |
229 | |
230 | if (urb->status) { |
231 | ar5523_err(ar, "Failed to TX command. Status = %d\n" , |
232 | urb->status); |
233 | cmd->res = urb->status; |
234 | complete(&cmd->done); |
235 | return; |
236 | } |
237 | |
238 | if (!(cmd->flags & AR5523_CMD_FLAG_READ)) { |
239 | cmd->res = 0; |
240 | complete(&cmd->done); |
241 | } |
242 | } |
243 | |
244 | static void ar5523_cancel_tx_cmd(struct ar5523 *ar) |
245 | { |
246 | usb_kill_urb(urb: ar->tx_cmd.urb_tx); |
247 | } |
248 | |
249 | static int ar5523_cmd(struct ar5523 *ar, u32 code, const void *idata, |
250 | int ilen, void *odata, int olen, int flags) |
251 | { |
252 | struct ar5523_cmd_hdr *hdr; |
253 | struct ar5523_tx_cmd *cmd = &ar->tx_cmd; |
254 | int xferlen, error; |
255 | |
256 | /* always bulk-out a multiple of 4 bytes */ |
257 | xferlen = (sizeof(struct ar5523_cmd_hdr) + ilen + 3) & ~3; |
258 | |
259 | hdr = cmd->buf_tx; |
260 | memset(hdr, 0, sizeof(struct ar5523_cmd_hdr)); |
261 | hdr->len = cpu_to_be32(xferlen); |
262 | hdr->code = cpu_to_be32(code); |
263 | hdr->priv = AR5523_CMD_ID; |
264 | |
265 | if (flags & AR5523_CMD_FLAG_MAGIC) |
266 | hdr->magic = cpu_to_be32(1 << 24); |
267 | if (ilen) |
268 | memcpy(hdr + 1, idata, ilen); |
269 | |
270 | cmd->odata = odata; |
271 | cmd->olen = olen; |
272 | cmd->flags = flags; |
273 | |
274 | ar5523_dbg(ar, "do cmd %02x\n" , code); |
275 | |
276 | usb_fill_bulk_urb(urb: cmd->urb_tx, dev: ar->dev, ar5523_cmd_tx_pipe(ar->dev), |
277 | transfer_buffer: cmd->buf_tx, buffer_length: xferlen, complete_fn: ar5523_cmd_tx_cb, context: cmd); |
278 | cmd->urb_tx->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
279 | |
280 | error = usb_submit_urb(urb: cmd->urb_tx, GFP_KERNEL); |
281 | if (error) { |
282 | ar5523_err(ar, "could not send command 0x%x, error=%d\n" , |
283 | code, error); |
284 | return error; |
285 | } |
286 | |
287 | if (!wait_for_completion_timeout(x: &cmd->done, timeout: 2 * HZ)) { |
288 | ar5523_cancel_tx_cmd(ar); |
289 | cmd->odata = NULL; |
290 | ar5523_err(ar, "timeout waiting for command %02x reply\n" , |
291 | code); |
292 | cmd->res = -ETIMEDOUT; |
293 | } |
294 | return cmd->res; |
295 | } |
296 | |
297 | static int ar5523_cmd_write(struct ar5523 *ar, u32 code, const void *data, |
298 | int len, int flags) |
299 | { |
300 | flags &= ~AR5523_CMD_FLAG_READ; |
301 | return ar5523_cmd(ar, code, idata: data, ilen: len, NULL, olen: 0, flags); |
302 | } |
303 | |
304 | static int ar5523_cmd_read(struct ar5523 *ar, u32 code, const void *idata, |
305 | int ilen, void *odata, int olen, int flags) |
306 | { |
307 | flags |= AR5523_CMD_FLAG_READ; |
308 | return ar5523_cmd(ar, code, idata, ilen, odata, olen, flags); |
309 | } |
310 | |
311 | static int ar5523_config(struct ar5523 *ar, u32 reg, u32 val) |
312 | { |
313 | struct ar5523_write_mac write; |
314 | int error; |
315 | |
316 | write.reg = cpu_to_be32(reg); |
317 | write.len = cpu_to_be32(0); /* 0 = single write */ |
318 | *(__be32 *)write.data = cpu_to_be32(val); |
319 | |
320 | error = ar5523_cmd_write(ar, WDCMSG_TARGET_SET_CONFIG, data: &write, |
321 | len: 3 * sizeof(u32), flags: 0); |
322 | if (error != 0) |
323 | ar5523_err(ar, "could not write register 0x%02x\n" , reg); |
324 | return error; |
325 | } |
326 | |
327 | static int ar5523_config_multi(struct ar5523 *ar, u32 reg, const void *data, |
328 | int len) |
329 | { |
330 | struct ar5523_write_mac write; |
331 | int error; |
332 | |
333 | write.reg = cpu_to_be32(reg); |
334 | write.len = cpu_to_be32(len); |
335 | memcpy(write.data, data, len); |
336 | |
337 | /* properly handle the case where len is zero (reset) */ |
338 | error = ar5523_cmd_write(ar, WDCMSG_TARGET_SET_CONFIG, data: &write, |
339 | len: (len == 0) ? sizeof(u32) : 2 * sizeof(u32) + len, flags: 0); |
340 | if (error != 0) |
341 | ar5523_err(ar, "could not write %d bytes to register 0x%02x\n" , |
342 | len, reg); |
343 | return error; |
344 | } |
345 | |
346 | static int ar5523_get_status(struct ar5523 *ar, u32 which, void *odata, |
347 | int olen) |
348 | { |
349 | int error; |
350 | __be32 which_be; |
351 | |
352 | which_be = cpu_to_be32(which); |
353 | error = ar5523_cmd_read(ar, WDCMSG_TARGET_GET_STATUS, |
354 | idata: &which_be, ilen: sizeof(which_be), odata, olen, AR5523_CMD_FLAG_MAGIC); |
355 | if (error != 0) |
356 | ar5523_err(ar, "could not read EEPROM offset 0x%02x\n" , which); |
357 | return error; |
358 | } |
359 | |
360 | static int ar5523_get_capability(struct ar5523 *ar, u32 cap, u32 *val) |
361 | { |
362 | int error; |
363 | __be32 cap_be, val_be; |
364 | |
365 | cap_be = cpu_to_be32(cap); |
366 | error = ar5523_cmd_read(ar, WDCMSG_TARGET_GET_CAPABILITY, idata: &cap_be, |
367 | ilen: sizeof(cap_be), odata: &val_be, olen: sizeof(__be32), |
368 | AR5523_CMD_FLAG_MAGIC); |
369 | if (error != 0) { |
370 | ar5523_err(ar, "could not read capability %u\n" , cap); |
371 | return error; |
372 | } |
373 | *val = be32_to_cpu(val_be); |
374 | return error; |
375 | } |
376 | |
377 | static int ar5523_get_devcap(struct ar5523 *ar) |
378 | { |
379 | #define GETCAP(x) do { \ |
380 | error = ar5523_get_capability(ar, x, &cap); \ |
381 | if (error != 0) \ |
382 | return error; \ |
383 | ar5523_info(ar, "Cap: " \ |
384 | "%s=0x%08x\n", #x, cap); \ |
385 | } while (0) |
386 | int error; |
387 | u32 cap; |
388 | |
389 | /* collect device capabilities */ |
390 | GETCAP(CAP_TARGET_VERSION); |
391 | GETCAP(CAP_TARGET_REVISION); |
392 | GETCAP(CAP_MAC_VERSION); |
393 | GETCAP(CAP_MAC_REVISION); |
394 | GETCAP(CAP_PHY_REVISION); |
395 | GETCAP(CAP_ANALOG_5GHz_REVISION); |
396 | GETCAP(CAP_ANALOG_2GHz_REVISION); |
397 | |
398 | GETCAP(CAP_REG_DOMAIN); |
399 | GETCAP(CAP_REG_CAP_BITS); |
400 | GETCAP(CAP_WIRELESS_MODES); |
401 | GETCAP(CAP_CHAN_SPREAD_SUPPORT); |
402 | GETCAP(CAP_COMPRESS_SUPPORT); |
403 | GETCAP(CAP_BURST_SUPPORT); |
404 | GETCAP(CAP_FAST_FRAMES_SUPPORT); |
405 | GETCAP(CAP_CHAP_TUNING_SUPPORT); |
406 | GETCAP(CAP_TURBOG_SUPPORT); |
407 | GETCAP(CAP_TURBO_PRIME_SUPPORT); |
408 | GETCAP(CAP_DEVICE_TYPE); |
409 | GETCAP(CAP_WME_SUPPORT); |
410 | GETCAP(CAP_TOTAL_QUEUES); |
411 | GETCAP(CAP_CONNECTION_ID_MAX); |
412 | |
413 | GETCAP(CAP_LOW_5GHZ_CHAN); |
414 | GETCAP(CAP_HIGH_5GHZ_CHAN); |
415 | GETCAP(CAP_LOW_2GHZ_CHAN); |
416 | GETCAP(CAP_HIGH_2GHZ_CHAN); |
417 | GETCAP(CAP_TWICE_ANTENNAGAIN_5G); |
418 | GETCAP(CAP_TWICE_ANTENNAGAIN_2G); |
419 | |
420 | GETCAP(CAP_CIPHER_AES_CCM); |
421 | GETCAP(CAP_CIPHER_TKIP); |
422 | GETCAP(CAP_MIC_TKIP); |
423 | return 0; |
424 | } |
425 | |
426 | static int ar5523_set_ledsteady(struct ar5523 *ar, int lednum, int ledmode) |
427 | { |
428 | struct ar5523_cmd_ledsteady led; |
429 | |
430 | led.lednum = cpu_to_be32(lednum); |
431 | led.ledmode = cpu_to_be32(ledmode); |
432 | |
433 | ar5523_dbg(ar, "set %s led %s (steady)\n" , |
434 | (lednum == UATH_LED_LINK) ? "link" : "activity" , |
435 | ledmode ? "on" : "off" ); |
436 | return ar5523_cmd_write(ar, WDCMSG_SET_LED_STEADY, data: &led, len: sizeof(led), |
437 | flags: 0); |
438 | } |
439 | |
440 | static int ar5523_set_rxfilter(struct ar5523 *ar, u32 bits, u32 op) |
441 | { |
442 | struct ar5523_cmd_rx_filter rxfilter; |
443 | |
444 | rxfilter.bits = cpu_to_be32(bits); |
445 | rxfilter.op = cpu_to_be32(op); |
446 | |
447 | ar5523_dbg(ar, "setting Rx filter=0x%x flags=0x%x\n" , bits, op); |
448 | return ar5523_cmd_write(ar, WDCMSG_RX_FILTER, data: &rxfilter, |
449 | len: sizeof(rxfilter), flags: 0); |
450 | } |
451 | |
452 | static int ar5523_reset_tx_queues(struct ar5523 *ar) |
453 | { |
454 | __be32 qid = cpu_to_be32(0); |
455 | |
456 | ar5523_dbg(ar, "resetting Tx queue\n" ); |
457 | return ar5523_cmd_write(ar, WDCMSG_RELEASE_TX_QUEUE, |
458 | data: &qid, len: sizeof(qid), flags: 0); |
459 | } |
460 | |
461 | static int ar5523_set_chan(struct ar5523 *ar) |
462 | { |
463 | struct ieee80211_conf *conf = &ar->hw->conf; |
464 | |
465 | struct ar5523_cmd_reset reset; |
466 | |
467 | memset(&reset, 0, sizeof(reset)); |
468 | reset.flags |= cpu_to_be32(UATH_CHAN_2GHZ); |
469 | reset.flags |= cpu_to_be32(UATH_CHAN_OFDM); |
470 | reset.freq = cpu_to_be32(conf->chandef.chan->center_freq); |
471 | reset.maxrdpower = cpu_to_be32(50); /* XXX */ |
472 | reset.channelchange = cpu_to_be32(1); |
473 | reset.keeprccontent = cpu_to_be32(0); |
474 | |
475 | ar5523_dbg(ar, "set chan flags 0x%x freq %d\n" , |
476 | be32_to_cpu(reset.flags), |
477 | conf->chandef.chan->center_freq); |
478 | return ar5523_cmd_write(ar, WDCMSG_RESET, data: &reset, len: sizeof(reset), flags: 0); |
479 | } |
480 | |
481 | static int ar5523_queue_init(struct ar5523 *ar) |
482 | { |
483 | struct ar5523_cmd_txq_setup qinfo; |
484 | |
485 | ar5523_dbg(ar, "setting up Tx queue\n" ); |
486 | qinfo.qid = cpu_to_be32(0); |
487 | qinfo.len = cpu_to_be32(sizeof(qinfo.attr)); |
488 | qinfo.attr.priority = cpu_to_be32(0); /* XXX */ |
489 | qinfo.attr.aifs = cpu_to_be32(3); |
490 | qinfo.attr.logcwmin = cpu_to_be32(4); |
491 | qinfo.attr.logcwmax = cpu_to_be32(10); |
492 | qinfo.attr.bursttime = cpu_to_be32(0); |
493 | qinfo.attr.mode = cpu_to_be32(0); |
494 | qinfo.attr.qflags = cpu_to_be32(1); /* XXX? */ |
495 | return ar5523_cmd_write(ar, WDCMSG_SETUP_TX_QUEUE, data: &qinfo, |
496 | len: sizeof(qinfo), flags: 0); |
497 | } |
498 | |
499 | static int ar5523_switch_chan(struct ar5523 *ar) |
500 | { |
501 | int error; |
502 | |
503 | error = ar5523_set_chan(ar); |
504 | if (error) { |
505 | ar5523_err(ar, "could not set chan, error %d\n" , error); |
506 | goto out_err; |
507 | } |
508 | |
509 | /* reset Tx rings */ |
510 | error = ar5523_reset_tx_queues(ar); |
511 | if (error) { |
512 | ar5523_err(ar, "could not reset Tx queues, error %d\n" , |
513 | error); |
514 | goto out_err; |
515 | } |
516 | /* set Tx rings WME properties */ |
517 | error = ar5523_queue_init(ar); |
518 | if (error) |
519 | ar5523_err(ar, "could not init wme, error %d\n" , error); |
520 | |
521 | out_err: |
522 | return error; |
523 | } |
524 | |
525 | static void ar5523_rx_data_put(struct ar5523 *ar, |
526 | struct ar5523_rx_data *data) |
527 | { |
528 | unsigned long flags; |
529 | spin_lock_irqsave(&ar->rx_data_list_lock, flags); |
530 | list_move(list: &data->list, head: &ar->rx_data_free); |
531 | spin_unlock_irqrestore(lock: &ar->rx_data_list_lock, flags); |
532 | } |
533 | |
534 | static void ar5523_data_rx_cb(struct urb *urb) |
535 | { |
536 | struct ar5523_rx_data *data = urb->context; |
537 | struct ar5523 *ar = data->ar; |
538 | struct ar5523_rx_desc *desc; |
539 | struct ar5523_chunk *chunk; |
540 | struct ieee80211_hw *hw = ar->hw; |
541 | struct ieee80211_rx_status *rx_status; |
542 | u32 rxlen; |
543 | int usblen = urb->actual_length; |
544 | int hdrlen, pad; |
545 | |
546 | ar5523_dbg(ar, "%s\n" , __func__); |
547 | /* sync/async unlink faults aren't errors */ |
548 | if (urb->status) { |
549 | if (urb->status != -ESHUTDOWN) |
550 | ar5523_err(ar, "%s: USB err: %d\n" , __func__, |
551 | urb->status); |
552 | goto skip; |
553 | } |
554 | |
555 | if (usblen < AR5523_MIN_RXBUFSZ) { |
556 | ar5523_err(ar, "RX: wrong xfer size (usblen=%d)\n" , usblen); |
557 | goto skip; |
558 | } |
559 | |
560 | chunk = (struct ar5523_chunk *) data->skb->data; |
561 | |
562 | if (((chunk->flags & UATH_CFLAGS_FINAL) == 0) || |
563 | chunk->seqnum != 0) { |
564 | ar5523_dbg(ar, "RX: No final flag. s: %d f: %02x l: %d\n" , |
565 | chunk->seqnum, chunk->flags, |
566 | be16_to_cpu(chunk->length)); |
567 | goto skip; |
568 | } |
569 | |
570 | /* Rx descriptor is located at the end, 32-bit aligned */ |
571 | desc = (struct ar5523_rx_desc *) |
572 | (data->skb->data + usblen - sizeof(struct ar5523_rx_desc)); |
573 | |
574 | rxlen = be32_to_cpu(desc->len); |
575 | if (rxlen > ar->rxbufsz) { |
576 | ar5523_dbg(ar, "RX: Bad descriptor (len=%d)\n" , |
577 | be32_to_cpu(desc->len)); |
578 | goto skip; |
579 | } |
580 | |
581 | if (!rxlen) { |
582 | ar5523_dbg(ar, "RX: rxlen is 0\n" ); |
583 | goto skip; |
584 | } |
585 | |
586 | if (be32_to_cpu(desc->status) != 0) { |
587 | ar5523_dbg(ar, "Bad RX status (0x%x len = %d). Skip\n" , |
588 | be32_to_cpu(desc->status), be32_to_cpu(desc->len)); |
589 | goto skip; |
590 | } |
591 | |
592 | skb_reserve(skb: data->skb, len: sizeof(*chunk)); |
593 | skb_put(skb: data->skb, len: rxlen - sizeof(struct ar5523_rx_desc)); |
594 | |
595 | hdrlen = ieee80211_get_hdrlen_from_skb(skb: data->skb); |
596 | if (!IS_ALIGNED(hdrlen, 4)) { |
597 | ar5523_dbg(ar, "eek, alignment workaround activated\n" ); |
598 | pad = ALIGN(hdrlen, 4) - hdrlen; |
599 | memmove(data->skb->data + pad, data->skb->data, hdrlen); |
600 | skb_pull(skb: data->skb, len: pad); |
601 | skb_put(skb: data->skb, len: pad); |
602 | } |
603 | |
604 | rx_status = IEEE80211_SKB_RXCB(skb: data->skb); |
605 | memset(rx_status, 0, sizeof(*rx_status)); |
606 | rx_status->freq = be32_to_cpu(desc->channel); |
607 | rx_status->band = hw->conf.chandef.chan->band; |
608 | rx_status->signal = -95 + be32_to_cpu(desc->rssi); |
609 | |
610 | ieee80211_rx_irqsafe(hw, skb: data->skb); |
611 | data->skb = NULL; |
612 | |
613 | skip: |
614 | if (data->skb) { |
615 | dev_kfree_skb_irq(skb: data->skb); |
616 | data->skb = NULL; |
617 | } |
618 | |
619 | ar5523_rx_data_put(ar, data); |
620 | if (atomic_inc_return(v: &ar->rx_data_free_cnt) >= |
621 | AR5523_RX_DATA_REFILL_COUNT && |
622 | test_bit(AR5523_HW_UP, &ar->flags)) |
623 | queue_work(wq: ar->wq, work: &ar->rx_refill_work); |
624 | } |
625 | |
626 | static void ar5523_rx_refill_work(struct work_struct *work) |
627 | { |
628 | struct ar5523 *ar = container_of(work, struct ar5523, rx_refill_work); |
629 | struct ar5523_rx_data *data; |
630 | unsigned long flags; |
631 | int error; |
632 | |
633 | ar5523_dbg(ar, "%s\n" , __func__); |
634 | do { |
635 | spin_lock_irqsave(&ar->rx_data_list_lock, flags); |
636 | |
637 | if (!list_empty(head: &ar->rx_data_free)) |
638 | data = (struct ar5523_rx_data *) ar->rx_data_free.next; |
639 | else |
640 | data = NULL; |
641 | spin_unlock_irqrestore(lock: &ar->rx_data_list_lock, flags); |
642 | |
643 | if (!data) |
644 | goto done; |
645 | |
646 | data->skb = alloc_skb(size: ar->rxbufsz, GFP_KERNEL); |
647 | if (!data->skb) { |
648 | ar5523_err(ar, "could not allocate rx skbuff\n" ); |
649 | return; |
650 | } |
651 | |
652 | usb_fill_bulk_urb(urb: data->urb, dev: ar->dev, |
653 | ar5523_data_rx_pipe(ar->dev), transfer_buffer: data->skb->data, |
654 | buffer_length: ar->rxbufsz, complete_fn: ar5523_data_rx_cb, context: data); |
655 | |
656 | spin_lock_irqsave(&ar->rx_data_list_lock, flags); |
657 | list_move(list: &data->list, head: &ar->rx_data_used); |
658 | spin_unlock_irqrestore(lock: &ar->rx_data_list_lock, flags); |
659 | atomic_dec(v: &ar->rx_data_free_cnt); |
660 | |
661 | error = usb_submit_urb(urb: data->urb, GFP_KERNEL); |
662 | if (error) { |
663 | kfree_skb(skb: data->skb); |
664 | if (error != -ENODEV) |
665 | ar5523_err(ar, "Err sending rx data urb %d\n" , |
666 | error); |
667 | ar5523_rx_data_put(ar, data); |
668 | atomic_inc(v: &ar->rx_data_free_cnt); |
669 | return; |
670 | } |
671 | |
672 | } while (true); |
673 | done: |
674 | return; |
675 | } |
676 | |
677 | static void ar5523_cancel_rx_bufs(struct ar5523 *ar) |
678 | { |
679 | struct ar5523_rx_data *data; |
680 | unsigned long flags; |
681 | |
682 | do { |
683 | spin_lock_irqsave(&ar->rx_data_list_lock, flags); |
684 | if (!list_empty(head: &ar->rx_data_used)) |
685 | data = (struct ar5523_rx_data *) ar->rx_data_used.next; |
686 | else |
687 | data = NULL; |
688 | spin_unlock_irqrestore(lock: &ar->rx_data_list_lock, flags); |
689 | |
690 | if (!data) |
691 | break; |
692 | |
693 | usb_kill_urb(urb: data->urb); |
694 | list_move(list: &data->list, head: &ar->rx_data_free); |
695 | atomic_inc(v: &ar->rx_data_free_cnt); |
696 | } while (data); |
697 | } |
698 | |
699 | static void ar5523_free_rx_bufs(struct ar5523 *ar) |
700 | { |
701 | struct ar5523_rx_data *data; |
702 | |
703 | ar5523_cancel_rx_bufs(ar); |
704 | while (!list_empty(head: &ar->rx_data_free)) { |
705 | data = (struct ar5523_rx_data *) ar->rx_data_free.next; |
706 | list_del(entry: &data->list); |
707 | usb_free_urb(urb: data->urb); |
708 | } |
709 | } |
710 | |
711 | static int ar5523_alloc_rx_bufs(struct ar5523 *ar) |
712 | { |
713 | int i; |
714 | |
715 | for (i = 0; i < AR5523_RX_DATA_COUNT; i++) { |
716 | struct ar5523_rx_data *data = &ar->rx_data[i]; |
717 | |
718 | data->ar = ar; |
719 | data->urb = usb_alloc_urb(iso_packets: 0, GFP_KERNEL); |
720 | if (!data->urb) |
721 | goto err; |
722 | list_add_tail(new: &data->list, head: &ar->rx_data_free); |
723 | atomic_inc(v: &ar->rx_data_free_cnt); |
724 | } |
725 | return 0; |
726 | |
727 | err: |
728 | ar5523_free_rx_bufs(ar); |
729 | return -ENOMEM; |
730 | } |
731 | |
732 | static void ar5523_data_tx_pkt_put(struct ar5523 *ar) |
733 | { |
734 | atomic_dec(v: &ar->tx_nr_total); |
735 | if (!atomic_dec_return(v: &ar->tx_nr_pending)) { |
736 | del_timer(timer: &ar->tx_wd_timer); |
737 | wake_up(&ar->tx_flush_waitq); |
738 | } |
739 | |
740 | if (atomic_read(v: &ar->tx_nr_total) < AR5523_TX_DATA_RESTART_COUNT) { |
741 | ar5523_dbg(ar, "restart tx queue\n" ); |
742 | ieee80211_wake_queues(hw: ar->hw); |
743 | } |
744 | } |
745 | |
746 | static void ar5523_data_tx_cb(struct urb *urb) |
747 | { |
748 | struct sk_buff *skb = urb->context; |
749 | struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(skb); |
750 | struct ar5523_tx_data *data = (struct ar5523_tx_data *) |
751 | txi->driver_data; |
752 | struct ar5523 *ar = data->ar; |
753 | unsigned long flags; |
754 | |
755 | ar5523_dbg(ar, "data tx urb completed: %d\n" , urb->status); |
756 | |
757 | spin_lock_irqsave(&ar->tx_data_list_lock, flags); |
758 | list_del(entry: &data->list); |
759 | spin_unlock_irqrestore(lock: &ar->tx_data_list_lock, flags); |
760 | |
761 | if (urb->status) { |
762 | ar5523_dbg(ar, "%s: urb status: %d\n" , __func__, urb->status); |
763 | ar5523_data_tx_pkt_put(ar); |
764 | ieee80211_free_txskb(hw: ar->hw, skb); |
765 | } else { |
766 | skb_pull(skb, len: sizeof(struct ar5523_tx_desc) + sizeof(__be32)); |
767 | ieee80211_tx_status_irqsafe(hw: ar->hw, skb); |
768 | } |
769 | usb_free_urb(urb); |
770 | } |
771 | |
772 | static void ar5523_tx(struct ieee80211_hw *hw, |
773 | struct ieee80211_tx_control *control, |
774 | struct sk_buff *skb) |
775 | { |
776 | struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(skb); |
777 | struct ar5523_tx_data *data = (struct ar5523_tx_data *) |
778 | txi->driver_data; |
779 | struct ar5523 *ar = hw->priv; |
780 | unsigned long flags; |
781 | |
782 | ar5523_dbg(ar, "tx called\n" ); |
783 | if (atomic_inc_return(v: &ar->tx_nr_total) >= AR5523_TX_DATA_COUNT) { |
784 | ar5523_dbg(ar, "tx queue full\n" ); |
785 | ar5523_dbg(ar, "stop queues (tot %d pend %d)\n" , |
786 | atomic_read(&ar->tx_nr_total), |
787 | atomic_read(&ar->tx_nr_pending)); |
788 | ieee80211_stop_queues(hw); |
789 | } |
790 | |
791 | spin_lock_irqsave(&ar->tx_data_list_lock, flags); |
792 | list_add_tail(new: &data->list, head: &ar->tx_queue_pending); |
793 | spin_unlock_irqrestore(lock: &ar->tx_data_list_lock, flags); |
794 | |
795 | ieee80211_queue_work(hw: ar->hw, work: &ar->tx_work); |
796 | } |
797 | |
798 | static void ar5523_tx_work_locked(struct ar5523 *ar) |
799 | { |
800 | struct ar5523_tx_data *data; |
801 | struct ar5523_tx_desc *desc; |
802 | struct ar5523_chunk *chunk; |
803 | struct ieee80211_tx_info *txi; |
804 | struct urb *urb; |
805 | struct sk_buff *skb; |
806 | int error = 0, paylen; |
807 | u32 txqid; |
808 | unsigned long flags; |
809 | |
810 | BUILD_BUG_ON(sizeof(struct ar5523_tx_data) > |
811 | IEEE80211_TX_INFO_DRIVER_DATA_SIZE); |
812 | |
813 | ar5523_dbg(ar, "%s\n" , __func__); |
814 | do { |
815 | spin_lock_irqsave(&ar->tx_data_list_lock, flags); |
816 | if (!list_empty(head: &ar->tx_queue_pending)) { |
817 | data = (struct ar5523_tx_data *) |
818 | ar->tx_queue_pending.next; |
819 | list_del(entry: &data->list); |
820 | } else |
821 | data = NULL; |
822 | spin_unlock_irqrestore(lock: &ar->tx_data_list_lock, flags); |
823 | |
824 | if (!data) |
825 | break; |
826 | |
827 | txi = container_of((void *)data, struct ieee80211_tx_info, |
828 | driver_data); |
829 | txqid = 0; |
830 | |
831 | skb = container_of((void *)txi, struct sk_buff, cb); |
832 | paylen = skb->len; |
833 | |
834 | urb = usb_alloc_urb(iso_packets: 0, GFP_KERNEL); |
835 | if (!urb) { |
836 | ieee80211_free_txskb(hw: ar->hw, skb); |
837 | continue; |
838 | } |
839 | |
840 | data->ar = ar; |
841 | data->urb = urb; |
842 | |
843 | desc = skb_push(skb, len: sizeof(*desc)); |
844 | chunk = skb_push(skb, len: sizeof(*chunk)); |
845 | |
846 | chunk->seqnum = 0; |
847 | chunk->flags = UATH_CFLAGS_FINAL; |
848 | chunk->length = cpu_to_be16(skb->len); |
849 | |
850 | desc->msglen = cpu_to_be32(skb->len); |
851 | desc->msgid = AR5523_DATA_ID; |
852 | desc->buflen = cpu_to_be32(paylen); |
853 | desc->type = cpu_to_be32(WDCMSG_SEND); |
854 | desc->flags = cpu_to_be32(UATH_TX_NOTIFY); |
855 | |
856 | if (test_bit(AR5523_CONNECTED, &ar->flags)) |
857 | desc->connid = cpu_to_be32(AR5523_ID_BSS); |
858 | else |
859 | desc->connid = cpu_to_be32(AR5523_ID_BROADCAST); |
860 | |
861 | if (txi->flags & IEEE80211_TX_CTL_USE_MINRATE) |
862 | txqid |= UATH_TXQID_MINRATE; |
863 | |
864 | desc->txqid = cpu_to_be32(txqid); |
865 | |
866 | urb->transfer_flags = URB_ZERO_PACKET; |
867 | usb_fill_bulk_urb(urb, dev: ar->dev, ar5523_data_tx_pipe(ar->dev), |
868 | transfer_buffer: skb->data, buffer_length: skb->len, complete_fn: ar5523_data_tx_cb, context: skb); |
869 | |
870 | spin_lock_irqsave(&ar->tx_data_list_lock, flags); |
871 | list_add_tail(new: &data->list, head: &ar->tx_queue_submitted); |
872 | spin_unlock_irqrestore(lock: &ar->tx_data_list_lock, flags); |
873 | mod_timer(timer: &ar->tx_wd_timer, expires: jiffies + AR5523_TX_WD_TIMEOUT); |
874 | atomic_inc(v: &ar->tx_nr_pending); |
875 | |
876 | ar5523_dbg(ar, "TX Frame (%d pending)\n" , |
877 | atomic_read(&ar->tx_nr_pending)); |
878 | error = usb_submit_urb(urb, GFP_KERNEL); |
879 | if (error) { |
880 | ar5523_err(ar, "error %d when submitting tx urb\n" , |
881 | error); |
882 | spin_lock_irqsave(&ar->tx_data_list_lock, flags); |
883 | list_del(entry: &data->list); |
884 | spin_unlock_irqrestore(lock: &ar->tx_data_list_lock, flags); |
885 | atomic_dec(v: &ar->tx_nr_pending); |
886 | ar5523_data_tx_pkt_put(ar); |
887 | usb_free_urb(urb); |
888 | ieee80211_free_txskb(hw: ar->hw, skb); |
889 | } |
890 | } while (true); |
891 | } |
892 | |
893 | static void ar5523_tx_work(struct work_struct *work) |
894 | { |
895 | struct ar5523 *ar = container_of(work, struct ar5523, tx_work); |
896 | |
897 | ar5523_dbg(ar, "%s\n" , __func__); |
898 | mutex_lock(&ar->mutex); |
899 | ar5523_tx_work_locked(ar); |
900 | mutex_unlock(lock: &ar->mutex); |
901 | } |
902 | |
903 | static void ar5523_tx_wd_timer(struct timer_list *t) |
904 | { |
905 | struct ar5523 *ar = from_timer(ar, t, tx_wd_timer); |
906 | |
907 | ar5523_dbg(ar, "TX watchdog timer triggered\n" ); |
908 | ieee80211_queue_work(hw: ar->hw, work: &ar->tx_wd_work); |
909 | } |
910 | |
911 | static void ar5523_tx_wd_work(struct work_struct *work) |
912 | { |
913 | struct ar5523 *ar = container_of(work, struct ar5523, tx_wd_work); |
914 | |
915 | /* Occasionally the TX queues stop responding. The only way to |
916 | * recover seems to be to reset the dongle. |
917 | */ |
918 | |
919 | mutex_lock(&ar->mutex); |
920 | ar5523_err(ar, "TX queue stuck (tot %d pend %d)\n" , |
921 | atomic_read(&ar->tx_nr_total), |
922 | atomic_read(&ar->tx_nr_pending)); |
923 | |
924 | ar5523_err(ar, "Will restart dongle.\n" ); |
925 | ar5523_cmd_write(ar, WDCMSG_TARGET_RESET, NULL, len: 0, flags: 0); |
926 | mutex_unlock(lock: &ar->mutex); |
927 | } |
928 | |
929 | static void ar5523_flush_tx(struct ar5523 *ar) |
930 | { |
931 | ar5523_tx_work_locked(ar); |
932 | |
933 | /* Don't waste time trying to flush if USB is disconnected */ |
934 | if (test_bit(AR5523_USB_DISCONNECTED, &ar->flags)) |
935 | return; |
936 | if (!wait_event_timeout(ar->tx_flush_waitq, |
937 | !atomic_read(&ar->tx_nr_pending), AR5523_FLUSH_TIMEOUT)) |
938 | ar5523_err(ar, "flush timeout (tot %d pend %d)\n" , |
939 | atomic_read(&ar->tx_nr_total), |
940 | atomic_read(&ar->tx_nr_pending)); |
941 | } |
942 | |
943 | static void ar5523_free_tx_cmd(struct ar5523 *ar) |
944 | { |
945 | struct ar5523_tx_cmd *cmd = &ar->tx_cmd; |
946 | |
947 | usb_free_coherent(dev: ar->dev, AR5523_MAX_RXCMDSZ, addr: cmd->buf_tx, |
948 | dma: cmd->urb_tx->transfer_dma); |
949 | usb_free_urb(urb: cmd->urb_tx); |
950 | } |
951 | |
952 | static int ar5523_alloc_tx_cmd(struct ar5523 *ar) |
953 | { |
954 | struct ar5523_tx_cmd *cmd = &ar->tx_cmd; |
955 | |
956 | cmd->ar = ar; |
957 | init_completion(x: &cmd->done); |
958 | |
959 | cmd->urb_tx = usb_alloc_urb(iso_packets: 0, GFP_KERNEL); |
960 | if (!cmd->urb_tx) |
961 | return -ENOMEM; |
962 | cmd->buf_tx = usb_alloc_coherent(dev: ar->dev, AR5523_MAX_TXCMDSZ, |
963 | GFP_KERNEL, |
964 | dma: &cmd->urb_tx->transfer_dma); |
965 | if (!cmd->buf_tx) { |
966 | usb_free_urb(urb: cmd->urb_tx); |
967 | return -ENOMEM; |
968 | } |
969 | return 0; |
970 | } |
971 | |
972 | /* |
973 | * This function is called periodically (every second) when associated to |
974 | * query device statistics. |
975 | */ |
976 | static void ar5523_stat_work(struct work_struct *work) |
977 | { |
978 | struct ar5523 *ar = container_of(work, struct ar5523, stat_work.work); |
979 | int error; |
980 | |
981 | ar5523_dbg(ar, "%s\n" , __func__); |
982 | mutex_lock(&ar->mutex); |
983 | |
984 | /* |
985 | * Send request for statistics asynchronously once a second. This |
986 | * seems to be important. Throughput is a lot better if this is done. |
987 | */ |
988 | error = ar5523_cmd_write(ar, WDCMSG_TARGET_GET_STATS, NULL, len: 0, flags: 0); |
989 | if (error) |
990 | ar5523_err(ar, "could not query stats, error %d\n" , error); |
991 | mutex_unlock(lock: &ar->mutex); |
992 | ieee80211_queue_delayed_work(hw: ar->hw, dwork: &ar->stat_work, HZ); |
993 | } |
994 | |
995 | /* |
996 | * Interface routines to the mac80211 stack. |
997 | */ |
998 | static int ar5523_start(struct ieee80211_hw *hw) |
999 | { |
1000 | struct ar5523 *ar = hw->priv; |
1001 | int error; |
1002 | __be32 val; |
1003 | |
1004 | ar5523_dbg(ar, "start called\n" ); |
1005 | |
1006 | mutex_lock(&ar->mutex); |
1007 | val = cpu_to_be32(0); |
1008 | ar5523_cmd_write(ar, WDCMSG_BIND, data: &val, len: sizeof(val), flags: 0); |
1009 | |
1010 | /* set MAC address */ |
1011 | ar5523_config_multi(ar, reg: CFG_MAC_ADDR, data: &ar->hw->wiphy->perm_addr, |
1012 | ETH_ALEN); |
1013 | |
1014 | /* XXX honor net80211 state */ |
1015 | ar5523_config(ar, reg: CFG_RATE_CONTROL_ENABLE, val: 0x00000001); |
1016 | ar5523_config(ar, reg: CFG_DIVERSITY_CTL, val: 0x00000001); |
1017 | ar5523_config(ar, reg: CFG_ABOLT, val: 0x0000003f); |
1018 | ar5523_config(ar, reg: CFG_WME_ENABLED, val: 0x00000000); |
1019 | |
1020 | ar5523_config(ar, reg: CFG_SERVICE_TYPE, val: 1); |
1021 | ar5523_config(ar, reg: CFG_TP_SCALE, val: 0x00000000); |
1022 | ar5523_config(ar, reg: CFG_TPC_HALF_DBM5, val: 0x0000003c); |
1023 | ar5523_config(ar, reg: CFG_TPC_HALF_DBM2, val: 0x0000003c); |
1024 | ar5523_config(ar, reg: CFG_OVERRD_TX_POWER, val: 0x00000000); |
1025 | ar5523_config(ar, reg: CFG_GMODE_PROTECTION, val: 0x00000000); |
1026 | ar5523_config(ar, reg: CFG_GMODE_PROTECT_RATE_INDEX, val: 0x00000003); |
1027 | ar5523_config(ar, reg: CFG_PROTECTION_TYPE, val: 0x00000000); |
1028 | ar5523_config(ar, reg: CFG_MODE_CTS, val: 0x00000002); |
1029 | |
1030 | error = ar5523_cmd_read(ar, WDCMSG_TARGET_START, NULL, ilen: 0, |
1031 | odata: &val, olen: sizeof(val), AR5523_CMD_FLAG_MAGIC); |
1032 | if (error) { |
1033 | ar5523_dbg(ar, "could not start target, error %d\n" , error); |
1034 | goto err; |
1035 | } |
1036 | ar5523_dbg(ar, "WDCMSG_TARGET_START returns handle: 0x%x\n" , |
1037 | be32_to_cpu(val)); |
1038 | |
1039 | ar5523_switch_chan(ar); |
1040 | |
1041 | val = cpu_to_be32(TARGET_DEVICE_AWAKE); |
1042 | ar5523_cmd_write(ar, WDCMSG_SET_PWR_MODE, data: &val, len: sizeof(val), flags: 0); |
1043 | /* XXX? check */ |
1044 | ar5523_cmd_write(ar, WDCMSG_RESET_KEY_CACHE, NULL, len: 0, flags: 0); |
1045 | |
1046 | set_bit(nr: AR5523_HW_UP, addr: &ar->flags); |
1047 | queue_work(wq: ar->wq, work: &ar->rx_refill_work); |
1048 | |
1049 | /* enable Rx */ |
1050 | ar5523_set_rxfilter(ar, bits: 0, UATH_FILTER_OP_INIT); |
1051 | ar5523_set_rxfilter(ar, |
1052 | UATH_FILTER_RX_UCAST | UATH_FILTER_RX_MCAST | |
1053 | UATH_FILTER_RX_BCAST | UATH_FILTER_RX_BEACON, |
1054 | UATH_FILTER_OP_SET); |
1055 | |
1056 | ar5523_set_ledsteady(ar, UATH_LED_ACTIVITY, UATH_LED_ON); |
1057 | ar5523_dbg(ar, "start OK\n" ); |
1058 | |
1059 | err: |
1060 | mutex_unlock(lock: &ar->mutex); |
1061 | return error; |
1062 | } |
1063 | |
1064 | static void ar5523_stop(struct ieee80211_hw *hw) |
1065 | { |
1066 | struct ar5523 *ar = hw->priv; |
1067 | |
1068 | ar5523_dbg(ar, "stop called\n" ); |
1069 | |
1070 | cancel_delayed_work_sync(dwork: &ar->stat_work); |
1071 | mutex_lock(&ar->mutex); |
1072 | clear_bit(nr: AR5523_HW_UP, addr: &ar->flags); |
1073 | |
1074 | ar5523_set_ledsteady(ar, UATH_LED_LINK, UATH_LED_OFF); |
1075 | ar5523_set_ledsteady(ar, UATH_LED_ACTIVITY, UATH_LED_OFF); |
1076 | |
1077 | ar5523_cmd_write(ar, WDCMSG_TARGET_STOP, NULL, len: 0, flags: 0); |
1078 | |
1079 | del_timer_sync(timer: &ar->tx_wd_timer); |
1080 | cancel_work_sync(work: &ar->tx_wd_work); |
1081 | cancel_work_sync(work: &ar->rx_refill_work); |
1082 | ar5523_cancel_rx_bufs(ar); |
1083 | mutex_unlock(lock: &ar->mutex); |
1084 | } |
1085 | |
1086 | static int ar5523_set_rts_threshold(struct ieee80211_hw *hw, u32 value) |
1087 | { |
1088 | struct ar5523 *ar = hw->priv; |
1089 | int ret; |
1090 | |
1091 | ar5523_dbg(ar, "set_rts_threshold called\n" ); |
1092 | mutex_lock(&ar->mutex); |
1093 | |
1094 | ret = ar5523_config(ar, reg: CFG_USER_RTS_THRESHOLD, val: value); |
1095 | |
1096 | mutex_unlock(lock: &ar->mutex); |
1097 | return ret; |
1098 | } |
1099 | |
1100 | static void ar5523_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
1101 | u32 queues, bool drop) |
1102 | { |
1103 | struct ar5523 *ar = hw->priv; |
1104 | |
1105 | ar5523_dbg(ar, "flush called\n" ); |
1106 | ar5523_flush_tx(ar); |
1107 | } |
1108 | |
1109 | static int ar5523_add_interface(struct ieee80211_hw *hw, |
1110 | struct ieee80211_vif *vif) |
1111 | { |
1112 | struct ar5523 *ar = hw->priv; |
1113 | |
1114 | ar5523_dbg(ar, "add interface called\n" ); |
1115 | |
1116 | if (ar->vif) { |
1117 | ar5523_dbg(ar, "invalid add_interface\n" ); |
1118 | return -EOPNOTSUPP; |
1119 | } |
1120 | |
1121 | switch (vif->type) { |
1122 | case NL80211_IFTYPE_STATION: |
1123 | ar->vif = vif; |
1124 | break; |
1125 | default: |
1126 | return -EOPNOTSUPP; |
1127 | } |
1128 | return 0; |
1129 | } |
1130 | |
1131 | static void ar5523_remove_interface(struct ieee80211_hw *hw, |
1132 | struct ieee80211_vif *vif) |
1133 | { |
1134 | struct ar5523 *ar = hw->priv; |
1135 | |
1136 | ar5523_dbg(ar, "remove interface called\n" ); |
1137 | ar->vif = NULL; |
1138 | } |
1139 | |
1140 | static int ar5523_hwconfig(struct ieee80211_hw *hw, u32 changed) |
1141 | { |
1142 | struct ar5523 *ar = hw->priv; |
1143 | |
1144 | ar5523_dbg(ar, "config called\n" ); |
1145 | mutex_lock(&ar->mutex); |
1146 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { |
1147 | ar5523_dbg(ar, "Do channel switch\n" ); |
1148 | ar5523_flush_tx(ar); |
1149 | ar5523_switch_chan(ar); |
1150 | } |
1151 | mutex_unlock(lock: &ar->mutex); |
1152 | return 0; |
1153 | } |
1154 | |
1155 | static int ar5523_get_wlan_mode(struct ar5523 *ar, |
1156 | struct ieee80211_bss_conf *bss_conf) |
1157 | { |
1158 | struct ieee80211_supported_band *band; |
1159 | int bit; |
1160 | struct ieee80211_sta *sta; |
1161 | u32 sta_rate_set; |
1162 | |
1163 | band = ar->hw->wiphy->bands[ar->hw->conf.chandef.chan->band]; |
1164 | sta = ieee80211_find_sta(vif: ar->vif, addr: bss_conf->bssid); |
1165 | if (!sta) { |
1166 | ar5523_info(ar, "STA not found!\n" ); |
1167 | return WLAN_MODE_11b; |
1168 | } |
1169 | sta_rate_set = sta->deflink.supp_rates[ar->hw->conf.chandef.chan->band]; |
1170 | |
1171 | for (bit = 0; bit < band->n_bitrates; bit++) { |
1172 | if (sta_rate_set & 1) { |
1173 | int rate = band->bitrates[bit].bitrate; |
1174 | switch (rate) { |
1175 | case 60: |
1176 | case 90: |
1177 | case 120: |
1178 | case 180: |
1179 | case 240: |
1180 | case 360: |
1181 | case 480: |
1182 | case 540: |
1183 | return WLAN_MODE_11g; |
1184 | } |
1185 | } |
1186 | sta_rate_set >>= 1; |
1187 | } |
1188 | return WLAN_MODE_11b; |
1189 | } |
1190 | |
1191 | static void ar5523_create_rateset(struct ar5523 *ar, |
1192 | struct ieee80211_bss_conf *bss_conf, |
1193 | struct ar5523_cmd_rateset *rs, |
1194 | bool basic) |
1195 | { |
1196 | struct ieee80211_supported_band *band; |
1197 | struct ieee80211_sta *sta; |
1198 | int bit, i = 0; |
1199 | u32 sta_rate_set, basic_rate_set; |
1200 | |
1201 | sta = ieee80211_find_sta(vif: ar->vif, addr: bss_conf->bssid); |
1202 | basic_rate_set = bss_conf->basic_rates; |
1203 | if (!sta) { |
1204 | ar5523_info(ar, "STA not found. Cannot set rates\n" ); |
1205 | sta_rate_set = bss_conf->basic_rates; |
1206 | } else |
1207 | sta_rate_set = sta->deflink.supp_rates[ar->hw->conf.chandef.chan->band]; |
1208 | |
1209 | ar5523_dbg(ar, "sta rate_set = %08x\n" , sta_rate_set); |
1210 | |
1211 | band = ar->hw->wiphy->bands[ar->hw->conf.chandef.chan->band]; |
1212 | for (bit = 0; bit < band->n_bitrates; bit++) { |
1213 | BUG_ON(i >= AR5523_MAX_NRATES); |
1214 | ar5523_dbg(ar, "Considering rate %d : %d\n" , |
1215 | band->bitrates[bit].hw_value, sta_rate_set & 1); |
1216 | if (sta_rate_set & 1) { |
1217 | rs->set[i] = band->bitrates[bit].hw_value; |
1218 | if (basic_rate_set & 1 && basic) |
1219 | rs->set[i] |= 0x80; |
1220 | i++; |
1221 | } |
1222 | sta_rate_set >>= 1; |
1223 | basic_rate_set >>= 1; |
1224 | } |
1225 | |
1226 | rs->length = i; |
1227 | } |
1228 | |
1229 | static int ar5523_set_basic_rates(struct ar5523 *ar, |
1230 | struct ieee80211_bss_conf *bss) |
1231 | { |
1232 | struct ar5523_cmd_rates rates; |
1233 | |
1234 | memset(&rates, 0, sizeof(rates)); |
1235 | rates.connid = cpu_to_be32(2); /* XXX */ |
1236 | rates.size = cpu_to_be32(sizeof(struct ar5523_cmd_rateset)); |
1237 | ar5523_create_rateset(ar, bss_conf: bss, rs: &rates.rateset, basic: true); |
1238 | |
1239 | return ar5523_cmd_write(ar, WDCMSG_SET_BASIC_RATE, data: &rates, |
1240 | len: sizeof(rates), flags: 0); |
1241 | } |
1242 | |
1243 | static int ar5523_create_connection(struct ar5523 *ar, |
1244 | struct ieee80211_vif *vif, |
1245 | struct ieee80211_bss_conf *bss) |
1246 | { |
1247 | struct ar5523_cmd_create_connection create; |
1248 | int wlan_mode; |
1249 | |
1250 | memset(&create, 0, sizeof(create)); |
1251 | create.connid = cpu_to_be32(2); |
1252 | create.bssid = cpu_to_be32(0); |
1253 | /* XXX packed or not? */ |
1254 | create.size = cpu_to_be32(sizeof(struct ar5523_cmd_rateset)); |
1255 | |
1256 | ar5523_create_rateset(ar, bss_conf: bss, rs: &create.connattr.rateset, basic: false); |
1257 | |
1258 | wlan_mode = ar5523_get_wlan_mode(ar, bss_conf: bss); |
1259 | create.connattr.wlanmode = cpu_to_be32(wlan_mode); |
1260 | |
1261 | return ar5523_cmd_write(ar, WDCMSG_CREATE_CONNECTION, data: &create, |
1262 | len: sizeof(create), flags: 0); |
1263 | } |
1264 | |
1265 | static int ar5523_write_associd(struct ar5523 *ar, struct ieee80211_vif *vif) |
1266 | { |
1267 | struct ieee80211_bss_conf *bss = &vif->bss_conf; |
1268 | struct ar5523_cmd_set_associd associd; |
1269 | |
1270 | memset(&associd, 0, sizeof(associd)); |
1271 | associd.defaultrateix = cpu_to_be32(0); /* XXX */ |
1272 | associd.associd = cpu_to_be32(vif->cfg.aid); |
1273 | associd.timoffset = cpu_to_be32(0x3b); /* XXX */ |
1274 | memcpy(associd.bssid, bss->bssid, ETH_ALEN); |
1275 | return ar5523_cmd_write(ar, WDCMSG_WRITE_ASSOCID, data: &associd, |
1276 | len: sizeof(associd), flags: 0); |
1277 | } |
1278 | |
1279 | static void ar5523_bss_info_changed(struct ieee80211_hw *hw, |
1280 | struct ieee80211_vif *vif, |
1281 | struct ieee80211_bss_conf *bss, |
1282 | u64 changed) |
1283 | { |
1284 | struct ar5523 *ar = hw->priv; |
1285 | int error; |
1286 | |
1287 | ar5523_dbg(ar, "bss_info_changed called\n" ); |
1288 | mutex_lock(&ar->mutex); |
1289 | |
1290 | if (!(changed & BSS_CHANGED_ASSOC)) |
1291 | goto out_unlock; |
1292 | |
1293 | if (vif->cfg.assoc) { |
1294 | error = ar5523_create_connection(ar, vif, bss); |
1295 | if (error) { |
1296 | ar5523_err(ar, "could not create connection\n" ); |
1297 | goto out_unlock; |
1298 | } |
1299 | |
1300 | error = ar5523_set_basic_rates(ar, bss); |
1301 | if (error) { |
1302 | ar5523_err(ar, "could not set negotiated rate set\n" ); |
1303 | goto out_unlock; |
1304 | } |
1305 | |
1306 | error = ar5523_write_associd(ar, vif); |
1307 | if (error) { |
1308 | ar5523_err(ar, "could not set association\n" ); |
1309 | goto out_unlock; |
1310 | } |
1311 | |
1312 | /* turn link LED on */ |
1313 | ar5523_set_ledsteady(ar, UATH_LED_LINK, UATH_LED_ON); |
1314 | set_bit(nr: AR5523_CONNECTED, addr: &ar->flags); |
1315 | ieee80211_queue_delayed_work(hw, dwork: &ar->stat_work, HZ); |
1316 | |
1317 | } else { |
1318 | cancel_delayed_work(dwork: &ar->stat_work); |
1319 | clear_bit(nr: AR5523_CONNECTED, addr: &ar->flags); |
1320 | ar5523_set_ledsteady(ar, UATH_LED_LINK, UATH_LED_OFF); |
1321 | } |
1322 | |
1323 | out_unlock: |
1324 | mutex_unlock(lock: &ar->mutex); |
1325 | |
1326 | } |
1327 | |
1328 | #define AR5523_SUPPORTED_FILTERS (FIF_ALLMULTI | \ |
1329 | FIF_FCSFAIL | \ |
1330 | FIF_OTHER_BSS) |
1331 | |
1332 | static void ar5523_configure_filter(struct ieee80211_hw *hw, |
1333 | unsigned int changed_flags, |
1334 | unsigned int *total_flags, |
1335 | u64 multicast) |
1336 | { |
1337 | struct ar5523 *ar = hw->priv; |
1338 | u32 filter = 0; |
1339 | |
1340 | ar5523_dbg(ar, "configure_filter called\n" ); |
1341 | mutex_lock(&ar->mutex); |
1342 | ar5523_flush_tx(ar); |
1343 | |
1344 | *total_flags &= AR5523_SUPPORTED_FILTERS; |
1345 | |
1346 | /* The filters seems strange. UATH_FILTER_RX_BCAST and |
1347 | * UATH_FILTER_RX_MCAST does not result in those frames being RXed. |
1348 | * The only way I have found to get [mb]cast frames seems to be |
1349 | * to set UATH_FILTER_RX_PROM. */ |
1350 | filter |= UATH_FILTER_RX_UCAST | UATH_FILTER_RX_MCAST | |
1351 | UATH_FILTER_RX_BCAST | UATH_FILTER_RX_BEACON | |
1352 | UATH_FILTER_RX_PROM; |
1353 | |
1354 | ar5523_set_rxfilter(ar, bits: 0, UATH_FILTER_OP_INIT); |
1355 | ar5523_set_rxfilter(ar, bits: filter, UATH_FILTER_OP_SET); |
1356 | |
1357 | mutex_unlock(lock: &ar->mutex); |
1358 | } |
1359 | |
1360 | static const struct ieee80211_ops ar5523_ops = { |
1361 | .add_chanctx = ieee80211_emulate_add_chanctx, |
1362 | .remove_chanctx = ieee80211_emulate_remove_chanctx, |
1363 | .change_chanctx = ieee80211_emulate_change_chanctx, |
1364 | .switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx, |
1365 | .start = ar5523_start, |
1366 | .stop = ar5523_stop, |
1367 | .tx = ar5523_tx, |
1368 | .wake_tx_queue = ieee80211_handle_wake_tx_queue, |
1369 | .set_rts_threshold = ar5523_set_rts_threshold, |
1370 | .add_interface = ar5523_add_interface, |
1371 | .remove_interface = ar5523_remove_interface, |
1372 | .config = ar5523_hwconfig, |
1373 | .bss_info_changed = ar5523_bss_info_changed, |
1374 | .configure_filter = ar5523_configure_filter, |
1375 | .flush = ar5523_flush, |
1376 | }; |
1377 | |
1378 | static int ar5523_host_available(struct ar5523 *ar) |
1379 | { |
1380 | struct ar5523_cmd_host_available setup; |
1381 | |
1382 | /* inform target the host is available */ |
1383 | setup.sw_ver_major = cpu_to_be32(ATH_SW_VER_MAJOR); |
1384 | setup.sw_ver_minor = cpu_to_be32(ATH_SW_VER_MINOR); |
1385 | setup.sw_ver_patch = cpu_to_be32(ATH_SW_VER_PATCH); |
1386 | setup.sw_ver_build = cpu_to_be32(ATH_SW_VER_BUILD); |
1387 | return ar5523_cmd_read(ar, WDCMSG_HOST_AVAILABLE, |
1388 | idata: &setup, ilen: sizeof(setup), NULL, olen: 0, flags: 0); |
1389 | } |
1390 | |
1391 | static int ar5523_get_devstatus(struct ar5523 *ar) |
1392 | { |
1393 | u8 macaddr[ETH_ALEN]; |
1394 | int error; |
1395 | |
1396 | /* retrieve MAC address */ |
1397 | error = ar5523_get_status(ar, which: ST_MAC_ADDR, odata: macaddr, ETH_ALEN); |
1398 | if (error) { |
1399 | ar5523_err(ar, "could not read MAC address\n" ); |
1400 | return error; |
1401 | } |
1402 | |
1403 | SET_IEEE80211_PERM_ADDR(hw: ar->hw, addr: macaddr); |
1404 | |
1405 | error = ar5523_get_status(ar, which: ST_SERIAL_NUMBER, |
1406 | odata: &ar->serial[0], olen: sizeof(ar->serial)); |
1407 | if (error) { |
1408 | ar5523_err(ar, "could not read device serial number\n" ); |
1409 | return error; |
1410 | } |
1411 | return 0; |
1412 | } |
1413 | |
1414 | #define AR5523_SANE_RXBUFSZ 2000 |
1415 | |
1416 | static int ar5523_get_max_rxsz(struct ar5523 *ar) |
1417 | { |
1418 | int error; |
1419 | __be32 rxsize; |
1420 | |
1421 | /* Get max rx size */ |
1422 | error = ar5523_get_status(ar, which: ST_WDC_TRANSPORT_CHUNK_SIZE, odata: &rxsize, |
1423 | olen: sizeof(rxsize)); |
1424 | if (error != 0) { |
1425 | ar5523_err(ar, "could not read max RX size\n" ); |
1426 | return error; |
1427 | } |
1428 | |
1429 | ar->rxbufsz = be32_to_cpu(rxsize); |
1430 | |
1431 | if (!ar->rxbufsz || ar->rxbufsz > AR5523_SANE_RXBUFSZ) { |
1432 | ar5523_err(ar, "Bad rxbufsz from device. Using %d instead\n" , |
1433 | AR5523_SANE_RXBUFSZ); |
1434 | ar->rxbufsz = AR5523_SANE_RXBUFSZ; |
1435 | } |
1436 | |
1437 | ar5523_dbg(ar, "Max RX buf size: %d\n" , ar->rxbufsz); |
1438 | return 0; |
1439 | } |
1440 | |
1441 | /* |
1442 | * This is copied from rtl818x, but we should probably move this |
1443 | * to common code as in OpenBSD. |
1444 | */ |
1445 | static const struct ieee80211_rate ar5523_rates[] = { |
1446 | { .bitrate = 10, .hw_value = 2, }, |
1447 | { .bitrate = 20, .hw_value = 4 }, |
1448 | { .bitrate = 55, .hw_value = 11, }, |
1449 | { .bitrate = 110, .hw_value = 22, }, |
1450 | { .bitrate = 60, .hw_value = 12, }, |
1451 | { .bitrate = 90, .hw_value = 18, }, |
1452 | { .bitrate = 120, .hw_value = 24, }, |
1453 | { .bitrate = 180, .hw_value = 36, }, |
1454 | { .bitrate = 240, .hw_value = 48, }, |
1455 | { .bitrate = 360, .hw_value = 72, }, |
1456 | { .bitrate = 480, .hw_value = 96, }, |
1457 | { .bitrate = 540, .hw_value = 108, }, |
1458 | }; |
1459 | |
1460 | static const struct ieee80211_channel ar5523_channels[] = { |
1461 | { .center_freq = 2412 }, |
1462 | { .center_freq = 2417 }, |
1463 | { .center_freq = 2422 }, |
1464 | { .center_freq = 2427 }, |
1465 | { .center_freq = 2432 }, |
1466 | { .center_freq = 2437 }, |
1467 | { .center_freq = 2442 }, |
1468 | { .center_freq = 2447 }, |
1469 | { .center_freq = 2452 }, |
1470 | { .center_freq = 2457 }, |
1471 | { .center_freq = 2462 }, |
1472 | { .center_freq = 2467 }, |
1473 | { .center_freq = 2472 }, |
1474 | { .center_freq = 2484 }, |
1475 | }; |
1476 | |
1477 | static int ar5523_init_modes(struct ar5523 *ar) |
1478 | { |
1479 | BUILD_BUG_ON(sizeof(ar->channels) != sizeof(ar5523_channels)); |
1480 | BUILD_BUG_ON(sizeof(ar->rates) != sizeof(ar5523_rates)); |
1481 | |
1482 | memcpy(ar->channels, ar5523_channels, sizeof(ar5523_channels)); |
1483 | memcpy(ar->rates, ar5523_rates, sizeof(ar5523_rates)); |
1484 | |
1485 | ar->band.band = NL80211_BAND_2GHZ; |
1486 | ar->band.channels = ar->channels; |
1487 | ar->band.n_channels = ARRAY_SIZE(ar5523_channels); |
1488 | ar->band.bitrates = ar->rates; |
1489 | ar->band.n_bitrates = ARRAY_SIZE(ar5523_rates); |
1490 | ar->hw->wiphy->bands[NL80211_BAND_2GHZ] = &ar->band; |
1491 | return 0; |
1492 | } |
1493 | |
1494 | /* |
1495 | * Load the MIPS R4000 microcode into the device. Once the image is loaded, |
1496 | * the device will detach itself from the bus and reattach later with a new |
1497 | * product Id (a la ezusb). |
1498 | */ |
1499 | static int ar5523_load_firmware(struct usb_device *dev) |
1500 | { |
1501 | struct ar5523_fwblock *txblock, *rxblock; |
1502 | const struct firmware *fw; |
1503 | void *fwbuf; |
1504 | int len, offset; |
1505 | int foolen; /* XXX(hch): handle short transfers */ |
1506 | int error = -ENXIO; |
1507 | |
1508 | if (request_firmware(fw: &fw, AR5523_FIRMWARE_FILE, device: &dev->dev)) { |
1509 | dev_err(&dev->dev, "no firmware found: %s\n" , |
1510 | AR5523_FIRMWARE_FILE); |
1511 | return -ENOENT; |
1512 | } |
1513 | |
1514 | txblock = kzalloc(size: sizeof(*txblock), GFP_KERNEL); |
1515 | if (!txblock) |
1516 | goto out; |
1517 | |
1518 | rxblock = kmalloc(size: sizeof(*rxblock), GFP_KERNEL); |
1519 | if (!rxblock) |
1520 | goto out_free_txblock; |
1521 | |
1522 | fwbuf = kmalloc(AR5523_MAX_FWBLOCK_SIZE, GFP_KERNEL); |
1523 | if (!fwbuf) |
1524 | goto out_free_rxblock; |
1525 | |
1526 | txblock->flags = cpu_to_be32(AR5523_WRITE_BLOCK); |
1527 | txblock->total = cpu_to_be32(fw->size); |
1528 | |
1529 | offset = 0; |
1530 | len = fw->size; |
1531 | while (len > 0) { |
1532 | int mlen = min(len, AR5523_MAX_FWBLOCK_SIZE); |
1533 | |
1534 | txblock->remain = cpu_to_be32(len - mlen); |
1535 | txblock->len = cpu_to_be32(mlen); |
1536 | |
1537 | /* send firmware block meta-data */ |
1538 | error = usb_bulk_msg(usb_dev: dev, ar5523_cmd_tx_pipe(dev), |
1539 | data: txblock, len: sizeof(*txblock), actual_length: &foolen, |
1540 | AR5523_CMD_TIMEOUT); |
1541 | if (error) { |
1542 | dev_err(&dev->dev, |
1543 | "could not send firmware block info\n" ); |
1544 | goto out_free_fwbuf; |
1545 | } |
1546 | |
1547 | /* send firmware block data */ |
1548 | memcpy(fwbuf, fw->data + offset, mlen); |
1549 | error = usb_bulk_msg(usb_dev: dev, ar5523_data_tx_pipe(dev), |
1550 | data: fwbuf, len: mlen, actual_length: &foolen, |
1551 | AR5523_DATA_TIMEOUT); |
1552 | if (error) { |
1553 | dev_err(&dev->dev, |
1554 | "could not send firmware block data\n" ); |
1555 | goto out_free_fwbuf; |
1556 | } |
1557 | |
1558 | /* wait for ack from firmware */ |
1559 | error = usb_bulk_msg(usb_dev: dev, ar5523_cmd_rx_pipe(dev), |
1560 | data: rxblock, len: sizeof(*rxblock), actual_length: &foolen, |
1561 | AR5523_CMD_TIMEOUT); |
1562 | if (error) { |
1563 | dev_err(&dev->dev, |
1564 | "could not read firmware answer\n" ); |
1565 | goto out_free_fwbuf; |
1566 | } |
1567 | |
1568 | len -= mlen; |
1569 | offset += mlen; |
1570 | } |
1571 | |
1572 | /* |
1573 | * Set the error to -ENXIO to make sure we continue probing for |
1574 | * a driver. |
1575 | */ |
1576 | error = -ENXIO; |
1577 | |
1578 | out_free_fwbuf: |
1579 | kfree(objp: fwbuf); |
1580 | out_free_rxblock: |
1581 | kfree(objp: rxblock); |
1582 | out_free_txblock: |
1583 | kfree(objp: txblock); |
1584 | out: |
1585 | release_firmware(fw); |
1586 | return error; |
1587 | } |
1588 | |
1589 | static int ar5523_probe(struct usb_interface *intf, |
1590 | const struct usb_device_id *id) |
1591 | { |
1592 | struct usb_device *dev = interface_to_usbdev(intf); |
1593 | struct ieee80211_hw *hw; |
1594 | struct ar5523 *ar; |
1595 | int error = -ENOMEM; |
1596 | |
1597 | /* |
1598 | * Load firmware if the device requires it. This will return |
1599 | * -ENXIO on success and we'll get called back afer the usb |
1600 | * id changes to indicate that the firmware is present. |
1601 | */ |
1602 | if (id->driver_info & AR5523_FLAG_PRE_FIRMWARE) |
1603 | return ar5523_load_firmware(dev); |
1604 | |
1605 | |
1606 | hw = ieee80211_alloc_hw(priv_data_len: sizeof(*ar), ops: &ar5523_ops); |
1607 | if (!hw) |
1608 | goto out; |
1609 | SET_IEEE80211_DEV(hw, dev: &intf->dev); |
1610 | |
1611 | ar = hw->priv; |
1612 | ar->hw = hw; |
1613 | ar->dev = dev; |
1614 | mutex_init(&ar->mutex); |
1615 | |
1616 | INIT_DELAYED_WORK(&ar->stat_work, ar5523_stat_work); |
1617 | timer_setup(&ar->tx_wd_timer, ar5523_tx_wd_timer, 0); |
1618 | INIT_WORK(&ar->tx_wd_work, ar5523_tx_wd_work); |
1619 | INIT_WORK(&ar->tx_work, ar5523_tx_work); |
1620 | INIT_LIST_HEAD(list: &ar->tx_queue_pending); |
1621 | INIT_LIST_HEAD(list: &ar->tx_queue_submitted); |
1622 | spin_lock_init(&ar->tx_data_list_lock); |
1623 | atomic_set(v: &ar->tx_nr_total, i: 0); |
1624 | atomic_set(v: &ar->tx_nr_pending, i: 0); |
1625 | init_waitqueue_head(&ar->tx_flush_waitq); |
1626 | |
1627 | atomic_set(v: &ar->rx_data_free_cnt, i: 0); |
1628 | INIT_WORK(&ar->rx_refill_work, ar5523_rx_refill_work); |
1629 | INIT_LIST_HEAD(list: &ar->rx_data_free); |
1630 | INIT_LIST_HEAD(list: &ar->rx_data_used); |
1631 | spin_lock_init(&ar->rx_data_list_lock); |
1632 | |
1633 | ar->wq = create_singlethread_workqueue("ar5523" ); |
1634 | if (!ar->wq) { |
1635 | ar5523_err(ar, "Could not create wq\n" ); |
1636 | goto out_free_ar; |
1637 | } |
1638 | |
1639 | error = ar5523_alloc_rx_bufs(ar); |
1640 | if (error) { |
1641 | ar5523_err(ar, "Could not allocate rx buffers\n" ); |
1642 | goto out_free_wq; |
1643 | } |
1644 | |
1645 | error = ar5523_alloc_rx_cmd(ar); |
1646 | if (error) { |
1647 | ar5523_err(ar, "Could not allocate rx command buffers\n" ); |
1648 | goto out_free_rx_bufs; |
1649 | } |
1650 | |
1651 | error = ar5523_alloc_tx_cmd(ar); |
1652 | if (error) { |
1653 | ar5523_err(ar, "Could not allocate tx command buffers\n" ); |
1654 | goto out_free_rx_cmd; |
1655 | } |
1656 | |
1657 | error = ar5523_submit_rx_cmd(ar); |
1658 | if (error) { |
1659 | ar5523_err(ar, "Failed to submit rx cmd\n" ); |
1660 | goto out_free_tx_cmd; |
1661 | } |
1662 | |
1663 | /* |
1664 | * We're now ready to send/receive firmware commands. |
1665 | */ |
1666 | error = ar5523_host_available(ar); |
1667 | if (error) { |
1668 | ar5523_err(ar, "could not initialize adapter\n" ); |
1669 | goto out_cancel_rx_cmd; |
1670 | } |
1671 | |
1672 | error = ar5523_get_max_rxsz(ar); |
1673 | if (error) { |
1674 | ar5523_err(ar, "could not get caps from adapter\n" ); |
1675 | goto out_cancel_rx_cmd; |
1676 | } |
1677 | |
1678 | error = ar5523_get_devcap(ar); |
1679 | if (error) { |
1680 | ar5523_err(ar, "could not get caps from adapter\n" ); |
1681 | goto out_cancel_rx_cmd; |
1682 | } |
1683 | |
1684 | error = ar5523_get_devstatus(ar); |
1685 | if (error != 0) { |
1686 | ar5523_err(ar, "could not get device status\n" ); |
1687 | goto out_cancel_rx_cmd; |
1688 | } |
1689 | |
1690 | ar5523_info(ar, "MAC/BBP AR5523, RF AR%c112\n" , |
1691 | (id->driver_info & AR5523_FLAG_ABG) ? '5' : '2'); |
1692 | |
1693 | ar->vif = NULL; |
1694 | ieee80211_hw_set(hw, HAS_RATE_CONTROL); |
1695 | ieee80211_hw_set(hw, RX_INCLUDES_FCS); |
1696 | ieee80211_hw_set(hw, SIGNAL_DBM); |
1697 | hw->extra_tx_headroom = sizeof(struct ar5523_tx_desc) + |
1698 | sizeof(struct ar5523_chunk); |
1699 | hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); |
1700 | hw->queues = 1; |
1701 | |
1702 | error = ar5523_init_modes(ar); |
1703 | if (error) |
1704 | goto out_cancel_rx_cmd; |
1705 | |
1706 | wiphy_ext_feature_set(wiphy: hw->wiphy, ftidx: NL80211_EXT_FEATURE_CQM_RSSI_LIST); |
1707 | |
1708 | usb_set_intfdata(intf, data: hw); |
1709 | |
1710 | error = ieee80211_register_hw(hw); |
1711 | if (error) { |
1712 | ar5523_err(ar, "could not register device\n" ); |
1713 | goto out_cancel_rx_cmd; |
1714 | } |
1715 | |
1716 | ar5523_info(ar, "Found and initialized AR5523 device\n" ); |
1717 | return 0; |
1718 | |
1719 | out_cancel_rx_cmd: |
1720 | ar5523_cancel_rx_cmd(ar); |
1721 | out_free_tx_cmd: |
1722 | ar5523_free_tx_cmd(ar); |
1723 | out_free_rx_cmd: |
1724 | ar5523_free_rx_cmd(ar); |
1725 | out_free_rx_bufs: |
1726 | ar5523_free_rx_bufs(ar); |
1727 | out_free_wq: |
1728 | destroy_workqueue(wq: ar->wq); |
1729 | out_free_ar: |
1730 | ieee80211_free_hw(hw); |
1731 | out: |
1732 | return error; |
1733 | } |
1734 | |
1735 | static void ar5523_disconnect(struct usb_interface *intf) |
1736 | { |
1737 | struct ieee80211_hw *hw = usb_get_intfdata(intf); |
1738 | struct ar5523 *ar = hw->priv; |
1739 | |
1740 | ar5523_dbg(ar, "detaching\n" ); |
1741 | set_bit(nr: AR5523_USB_DISCONNECTED, addr: &ar->flags); |
1742 | |
1743 | ieee80211_unregister_hw(hw); |
1744 | |
1745 | ar5523_cancel_rx_cmd(ar); |
1746 | ar5523_free_tx_cmd(ar); |
1747 | ar5523_free_rx_cmd(ar); |
1748 | ar5523_free_rx_bufs(ar); |
1749 | |
1750 | destroy_workqueue(wq: ar->wq); |
1751 | |
1752 | ieee80211_free_hw(hw); |
1753 | usb_set_intfdata(intf, NULL); |
1754 | } |
1755 | |
1756 | #define AR5523_DEVICE_UG(vendor, device) \ |
1757 | { USB_DEVICE((vendor), (device)) }, \ |
1758 | { USB_DEVICE((vendor), (device) + 1), \ |
1759 | .driver_info = AR5523_FLAG_PRE_FIRMWARE } |
1760 | #define AR5523_DEVICE_UX(vendor, device) \ |
1761 | { USB_DEVICE((vendor), (device)), \ |
1762 | .driver_info = AR5523_FLAG_ABG }, \ |
1763 | { USB_DEVICE((vendor), (device) + 1), \ |
1764 | .driver_info = AR5523_FLAG_ABG|AR5523_FLAG_PRE_FIRMWARE } |
1765 | |
1766 | static const struct usb_device_id ar5523_id_table[] = { |
1767 | AR5523_DEVICE_UG(0x168c, 0x0001), /* Atheros / AR5523 */ |
1768 | AR5523_DEVICE_UG(0x0cf3, 0x0001), /* Atheros2 / AR5523_1 */ |
1769 | AR5523_DEVICE_UG(0x0cf3, 0x0003), /* Atheros2 / AR5523_2 */ |
1770 | AR5523_DEVICE_UX(0x0cf3, 0x0005), /* Atheros2 / AR5523_3 */ |
1771 | AR5523_DEVICE_UG(0x0d8e, 0x7801), /* Conceptronic / AR5523_1 */ |
1772 | AR5523_DEVICE_UX(0x0d8e, 0x7811), /* Conceptronic / AR5523_2 */ |
1773 | AR5523_DEVICE_UX(0x2001, 0x3a00), /* Dlink / DWLAG132 */ |
1774 | AR5523_DEVICE_UG(0x2001, 0x3a02), /* Dlink / DWLG132 */ |
1775 | AR5523_DEVICE_UX(0x2001, 0x3a04), /* Dlink / DWLAG122 */ |
1776 | AR5523_DEVICE_UG(0x07d1, 0x3a07), /* D-Link / WUA-2340 rev A1 */ |
1777 | AR5523_DEVICE_UG(0x1690, 0x0712), /* Gigaset / AR5523 */ |
1778 | AR5523_DEVICE_UG(0x1690, 0x0710), /* Gigaset / SMCWUSBTG */ |
1779 | AR5523_DEVICE_UG(0x129b, 0x160b), /* Gigaset / USB stick 108 |
1780 | (CyberTAN Technology) */ |
1781 | AR5523_DEVICE_UG(0x16ab, 0x7801), /* Globalsun / AR5523_1 */ |
1782 | AR5523_DEVICE_UX(0x16ab, 0x7811), /* Globalsun / AR5523_2 */ |
1783 | AR5523_DEVICE_UG(0x0d8e, 0x7802), /* Globalsun / AR5523_3 */ |
1784 | AR5523_DEVICE_UX(0x0846, 0x4300), /* Netgear / WG111U */ |
1785 | AR5523_DEVICE_UG(0x0846, 0x4250), /* Netgear / WG111T */ |
1786 | AR5523_DEVICE_UG(0x0846, 0x5f00), /* Netgear / WPN111 */ |
1787 | AR5523_DEVICE_UG(0x083a, 0x4506), /* SMC / EZ Connect |
1788 | SMCWUSBT-G2 */ |
1789 | AR5523_DEVICE_UG(0x157e, 0x3006), /* Umedia / AR5523_1, TEW444UBEU*/ |
1790 | AR5523_DEVICE_UX(0x157e, 0x3205), /* Umedia / AR5523_2 */ |
1791 | AR5523_DEVICE_UG(0x1435, 0x0826), /* Wistronneweb / AR5523_1 */ |
1792 | AR5523_DEVICE_UX(0x1435, 0x0828), /* Wistronneweb / AR5523_2 */ |
1793 | AR5523_DEVICE_UG(0x0cde, 0x0012), /* Zcom / AR5523 */ |
1794 | AR5523_DEVICE_UG(0x1385, 0x4250), /* Netgear3 / WG111T (2) */ |
1795 | AR5523_DEVICE_UG(0x1385, 0x5f00), /* Netgear / WPN111 */ |
1796 | AR5523_DEVICE_UG(0x1385, 0x5f02), /* Netgear / WPN111 */ |
1797 | { } |
1798 | }; |
1799 | MODULE_DEVICE_TABLE(usb, ar5523_id_table); |
1800 | |
1801 | static struct usb_driver ar5523_driver = { |
1802 | .name = "ar5523" , |
1803 | .id_table = ar5523_id_table, |
1804 | .probe = ar5523_probe, |
1805 | .disconnect = ar5523_disconnect, |
1806 | }; |
1807 | |
1808 | module_usb_driver(ar5523_driver); |
1809 | |
1810 | MODULE_DESCRIPTION("Atheros AR5523 wireless driver" ); |
1811 | MODULE_LICENSE("Dual BSD/GPL" ); |
1812 | MODULE_FIRMWARE(AR5523_FIRMWARE_FILE); |
1813 | |