driver: staging: wlan-ng: Fixed Alignment to match open parenthesis
[linux-2.6-block.git] / drivers / staging / wlan-ng / hfa384x_usb.c
CommitLineData
00b3ed16
GKH
1/* src/prism2/driver/hfa384x_usb.c
2*
3* Functions that talk to the USB variantof the Intersil hfa384x MAC
4*
5* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
6* --------------------------------------------------------------------
7*
8* linux-wlan
9*
10* The contents of this file are subject to the Mozilla Public
11* License Version 1.1 (the "License"); you may not use this file
12* except in compliance with the License. You may obtain a copy of
13* the License at http://www.mozilla.org/MPL/
14*
15* Software distributed under the License is distributed on an "AS
16* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
17* implied. See the License for the specific language governing
18* rights and limitations under the License.
19*
20* Alternatively, the contents of this file may be used under the
21* terms of the GNU Public License version 2 (the "GPL"), in which
22* case the provisions of the GPL are applicable instead of the
23* above. If you wish to allow the use of your version of this file
24* only under the terms of the GPL and not to allow others to use
25* your version of this file under the MPL, indicate your decision
26* by deleting the provisions above and replace them with the notice
27* and other provisions required by the GPL. If you do not delete
28* the provisions above, a recipient may use your version of this
29* file under either the MPL or the GPL.
30*
31* --------------------------------------------------------------------
32*
33* Inquiries regarding the linux-wlan Open Source project can be
34* made directly to:
35*
36* AbsoluteValue Systems Inc.
37* info@linux-wlan.com
38* http://www.linux-wlan.com
39*
40* --------------------------------------------------------------------
41*
42* Portions of the development of this software were funded by
43* Intersil Corporation as part of PRISM(R) chipset product development.
44*
45* --------------------------------------------------------------------
46*
47* This file implements functions that correspond to the prism2/hfa384x
48* 802.11 MAC hardware and firmware host interface.
49*
50* The functions can be considered to represent several levels of
51* abstraction. The lowest level functions are simply C-callable wrappers
52* around the register accesses. The next higher level represents C-callable
53* prism2 API functions that match the Intersil documentation as closely
54* as is reasonable. The next higher layer implements common sequences
3fc0d278 55* of invocations of the API layer (e.g. write to bap, followed by cmd).
00b3ed16
GKH
56*
57* Common sequences:
58* hfa384x_drvr_xxx Highest level abstractions provided by the
59* hfa384x code. They are driver defined wrappers
60* for common sequences. These functions generally
61* use the services of the lower levels.
62*
63* hfa384x_drvr_xxxconfig An example of the drvr level abstraction. These
64* functions are wrappers for the RID get/set
631c8dec
EH
65* sequence. They call copy_[to|from]_bap() and
66* cmd_access(). These functions operate on the
67* RIDs and buffers without validation. The caller
00b3ed16
GKH
68* is responsible for that.
69*
70* API wrapper functions:
71* hfa384x_cmd_xxx functions that provide access to the f/w commands.
72* The function arguments correspond to each command
73* argument, even command arguments that get packed
74* into single registers. These functions _just_
75* issue the command by setting the cmd/parm regs
76* & reading the status/resp regs. Additional
77* activities required to fully use a command
78* (read/write from/to bap, get/set int status etc.)
79* are implemented separately. Think of these as
80* C-callable prism2 commands.
81*
82* Lowest Layer Functions:
83* hfa384x_docmd_xxx These functions implement the sequence required
84* to issue any prism2 command. Primarily used by the
85* hfa384x_cmd_xxx functions.
86*
87* hfa384x_bap_xxx BAP read/write access functions.
88* Note: we usually use BAP0 for non-interrupt context
89* and BAP1 for interrupt context.
90*
91* hfa384x_dl_xxx download related functions.
92*
93* Driver State Issues:
94* Note that there are two pairs of functions that manage the
95* 'initialized' and 'running' states of the hw/MAC combo. The four
96* functions are create(), destroy(), start(), and stop(). create()
97* sets up the data structures required to support the hfa384x_*
98* functions and destroy() cleans them up. The start() function gets
99* the actual hardware running and enables the interrupts. The stop()
100* function shuts the hardware down. The sequence should be:
101* create()
102* start()
103* .
104* . Do interesting things w/ the hardware
105* .
106* stop()
107* destroy()
108*
109* Note that destroy() can be called without calling stop() first.
110* --------------------------------------------------------------------
111*/
112
00b3ed16
GKH
113#include <linux/module.h>
114#include <linux/kernel.h>
115#include <linux/sched.h>
116#include <linux/types.h>
117#include <linux/slab.h>
118#include <linux/wireless.h>
119#include <linux/netdevice.h>
120#include <linux/timer.h>
ef1a0ed7 121#include <linux/io.h>
00b3ed16
GKH
122#include <linux/delay.h>
123#include <asm/byteorder.h>
ef1a0ed7 124#include <linux/bitops.h>
00b3ed16
GKH
125#include <linux/list.h>
126#include <linux/usb.h>
ae26230b 127#include <linux/byteorder/generic.h>
00b3ed16 128
5dd8acc8 129#define SUBMIT_URB(u, f) usb_submit_urb(u, f)
00b3ed16 130
00b3ed16
GKH
131#include "p80211types.h"
132#include "p80211hdr.h"
133#include "p80211mgmt.h"
134#include "p80211conv.h"
135#include "p80211msg.h"
136#include "p80211netdev.h"
137#include "p80211req.h"
138#include "p80211metadef.h"
139#include "p80211metastruct.h"
140#include "hfa384x.h"
141#include "prism2mgmt.h"
142
21dc0f89
MM
143enum cmd_mode {
144 DOWAIT = 0,
145 DOASYNC
00b3ed16 146};
00b3ed16
GKH
147
148#define THROTTLE_JIFFIES (HZ/8)
2d200d9f
MM
149#define URB_ASYNC_UNLINK 0
150#define USB_QUEUE_BULK 0
00b3ed16 151
00b3ed16
GKH
152#define ROUNDUP64(a) (((a)+63)&~63)
153
00b3ed16 154#ifdef DEBUG_USB
21dc0f89 155static void dbprint_urb(struct urb *urb);
00b3ed16
GKH
156#endif
157
158static void
297f06ce 159hfa384x_int_rxmonitor(wlandevice_t *wlandev, hfa384x_usb_rxfrm_t *rxfrm);
00b3ed16 160
21dc0f89 161static void hfa384x_usb_defer(struct work_struct *data);
00b3ed16 162
297f06ce 163static int submit_rx_urb(hfa384x_t *hw, gfp_t flags);
00b3ed16 164
297f06ce 165static int submit_tx_urb(hfa384x_t *hw, struct urb *tx_urb, gfp_t flags);
00b3ed16
GKH
166
167/*---------------------------------------------------*/
168/* Callbacks */
21dc0f89
MM
169static void hfa384x_usbout_callback(struct urb *urb);
170static void hfa384x_ctlxout_callback(struct urb *urb);
171static void hfa384x_usbin_callback(struct urb *urb);
00b3ed16
GKH
172
173static void
32adf1e5 174hfa384x_usbin_txcompl(wlandevice_t *wlandev, hfa384x_usbin_t *usbin);
00b3ed16 175
297f06ce 176static void hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb);
00b3ed16 177
32adf1e5 178static void hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t *usbin);
00b3ed16
GKH
179
180static void
297f06ce 181hfa384x_usbout_tx(wlandevice_t *wlandev, hfa384x_usbout_t *usbout);
00b3ed16 182
297f06ce 183static void hfa384x_usbin_ctlx(hfa384x_t *hw, hfa384x_usbin_t *usbin,
00b3ed16
GKH
184 int urb_status);
185
186/*---------------------------------------------------*/
187/* Functions to support the prism2 usb command queue */
188
297f06ce 189static void hfa384x_usbctlxq_run(hfa384x_t *hw);
00b3ed16 190
21dc0f89 191static void hfa384x_usbctlx_reqtimerfn(unsigned long data);
00b3ed16 192
21dc0f89 193static void hfa384x_usbctlx_resptimerfn(unsigned long data);
00b3ed16 194
21dc0f89 195static void hfa384x_usb_throttlefn(unsigned long data);
00b3ed16 196
21dc0f89 197static void hfa384x_usbctlx_completion_task(unsigned long data);
00b3ed16 198
21dc0f89 199static void hfa384x_usbctlx_reaper_task(unsigned long data);
00b3ed16 200
297f06ce 201static int hfa384x_usbctlx_submit(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx);
00b3ed16 202
297f06ce 203static void unlocked_usbctlx_complete(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx);
00b3ed16 204
21dc0f89 205struct usbctlx_completor {
83f91687 206 int (*complete)(struct usbctlx_completor *);
00b3ed16 207};
00b3ed16
GKH
208
209static int
297f06ce
MT
210hfa384x_usbctlx_complete_sync(hfa384x_t *hw,
211 hfa384x_usbctlx_t *ctlx,
631c8dec 212 struct usbctlx_completor *completor);
00b3ed16
GKH
213
214static int
297f06ce 215unlocked_usbctlx_cancel_async(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx);
00b3ed16 216
297f06ce 217static void hfa384x_cb_status(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx);
00b3ed16 218
297f06ce 219static void hfa384x_cb_rrid(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx);
00b3ed16
GKH
220
221static int
297f06ce
MT
222usbctlx_get_status(const hfa384x_usb_cmdresp_t *cmdresp,
223 hfa384x_cmdresult_t *result);
00b3ed16
GKH
224
225static void
297f06ce
MT
226usbctlx_get_rridresult(const hfa384x_usb_rridresp_t *rridresp,
227 hfa384x_rridresult_t *result);
00b3ed16
GKH
228
229/*---------------------------------------------------*/
230/* Low level req/resp CTLX formatters and submitters */
231static int
297f06ce 232hfa384x_docmd(hfa384x_t *hw,
631c8dec 233 enum cmd_mode mode,
297f06ce 234 hfa384x_metacmd_t *cmd,
21dc0f89 235 ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data);
00b3ed16
GKH
236
237static int
297f06ce 238hfa384x_dorrid(hfa384x_t *hw,
631c8dec 239 enum cmd_mode mode,
21dc0f89
MM
240 u16 rid,
241 void *riddata,
242 unsigned int riddatalen,
243 ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data);
00b3ed16
GKH
244
245static int
297f06ce 246hfa384x_dowrid(hfa384x_t *hw,
631c8dec 247 enum cmd_mode mode,
21dc0f89
MM
248 u16 rid,
249 void *riddata,
250 unsigned int riddatalen,
251 ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data);
00b3ed16
GKH
252
253static int
297f06ce 254hfa384x_dormem(hfa384x_t *hw,
631c8dec 255 enum cmd_mode mode,
21dc0f89
MM
256 u16 page,
257 u16 offset,
258 void *data,
259 unsigned int len,
260 ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data);
00b3ed16
GKH
261
262static int
297f06ce 263hfa384x_dowmem(hfa384x_t *hw,
631c8dec 264 enum cmd_mode mode,
21dc0f89
MM
265 u16 page,
266 u16 offset,
267 void *data,
268 unsigned int len,
269 ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data);
00b3ed16 270
21dc0f89 271static int hfa384x_isgood_pdrcode(u16 pdrcode);
00b3ed16 272
21dc0f89 273static inline const char *ctlxstr(CTLX_STATE s)
00b3ed16 274{
d6ae4a99 275 static const char * const ctlx_str[] = {
00b3ed16
GKH
276 "Initial state",
277 "Complete",
278 "Request failed",
279 "Request pending",
280 "Request packet submitted",
281 "Request packet completed",
282 "Response packet completed"
283 };
284
285 return ctlx_str[s];
286};
287
32adf1e5 288static inline hfa384x_usbctlx_t *get_active_ctlx(hfa384x_t *hw)
00b3ed16
GKH
289{
290 return list_entry(hw->ctlxq.active.next, hfa384x_usbctlx_t, list);
291}
292
00b3ed16 293#ifdef DEBUG_USB
21dc0f89 294void dbprint_urb(struct urb *urb)
00b3ed16 295{
a7cf7bae
MM
296 pr_debug("urb->pipe=0x%08x\n", urb->pipe);
297 pr_debug("urb->status=0x%08x\n", urb->status);
298 pr_debug("urb->transfer_flags=0x%08x\n", urb->transfer_flags);
21dc0f89 299 pr_debug("urb->transfer_buffer=0x%08x\n",
75f49e07 300 (unsigned int)urb->transfer_buffer);
21dc0f89 301 pr_debug("urb->transfer_buffer_length=0x%08x\n",
75f49e07 302 urb->transfer_buffer_length);
a7cf7bae
MM
303 pr_debug("urb->actual_length=0x%08x\n", urb->actual_length);
304 pr_debug("urb->bandwidth=0x%08x\n", urb->bandwidth);
21dc0f89 305 pr_debug("urb->setup_packet(ctl)=0x%08x\n",
75f49e07
MT
306 (unsigned int)urb->setup_packet);
307 pr_debug("urb->start_frame(iso/irq)=0x%08x\n", urb->start_frame);
a7cf7bae
MM
308 pr_debug("urb->interval(irq)=0x%08x\n", urb->interval);
309 pr_debug("urb->error_count(iso)=0x%08x\n", urb->error_count);
310 pr_debug("urb->timeout=0x%08x\n", urb->timeout);
311 pr_debug("urb->context=0x%08x\n", (unsigned int)urb->context);
75f49e07 312 pr_debug("urb->complete=0x%08x\n", (unsigned int)urb->complete);
00b3ed16
GKH
313}
314#endif
315
00b3ed16
GKH
316/*----------------------------------------------------------------
317* submit_rx_urb
318*
319* Listen for input data on the BULK-IN pipe. If the pipe has
320* stalled then schedule it to be reset.
321*
322* Arguments:
323* hw device struct
324* memflags memory allocation flags
325*
326* Returns:
327* error code from submission
328*
329* Call context:
330* Any
331----------------------------------------------------------------*/
297f06ce 332static int submit_rx_urb(hfa384x_t *hw, gfp_t memflags)
00b3ed16
GKH
333{
334 struct sk_buff *skb;
335 int result;
336
00b3ed16
GKH
337 skb = dev_alloc_skb(sizeof(hfa384x_usbin_t));
338 if (skb == NULL) {
339 result = -ENOMEM;
340 goto done;
341 }
342
343 /* Post the IN urb */
344 usb_fill_bulk_urb(&hw->rx_urb, hw->usb,
21dc0f89
MM
345 hw->endp_in,
346 skb->data, sizeof(hfa384x_usbin_t),
347 hfa384x_usbin_callback, hw->wlandev);
00b3ed16
GKH
348
349 hw->rx_urb_skb = skb;
350
351 result = -ENOLINK;
631c8dec 352 if (!hw->wlandev->hwremoved &&
3f2d6564 353 !test_bit(WORK_RX_HALT, &hw->usb_flags)) {
00b3ed16
GKH
354 result = SUBMIT_URB(&hw->rx_urb, memflags);
355
356 /* Check whether we need to reset the RX pipe */
357 if (result == -EPIPE) {
263b8bb9 358 netdev_warn(hw->wlandev->netdev,
3f2d6564
SSA
359 "%s rx pipe stalled: requesting reset\n",
360 hw->wlandev->netdev->name);
21dc0f89 361 if (!test_and_set_bit(WORK_RX_HALT, &hw->usb_flags))
00b3ed16
GKH
362 schedule_work(&hw->usb_work);
363 }
364 }
365
366 /* Don't leak memory if anything should go wrong */
367 if (result != 0) {
368 dev_kfree_skb(skb);
369 hw->rx_urb_skb = NULL;
370 }
371
21dc0f89 372done:
00b3ed16
GKH
373 return result;
374}
375
376/*----------------------------------------------------------------
377* submit_tx_urb
378*
379* Prepares and submits the URB of transmitted data. If the
380* submission fails then it will schedule the output pipe to
381* be reset.
382*
383* Arguments:
384* hw device struct
385* tx_urb URB of data for tranmission
386* memflags memory allocation flags
387*
388* Returns:
389* error code from submission
390*
391* Call context:
392* Any
393----------------------------------------------------------------*/
297f06ce 394static int submit_tx_urb(hfa384x_t *hw, struct urb *tx_urb, gfp_t memflags)
00b3ed16
GKH
395{
396 struct net_device *netdev = hw->wlandev->netdev;
397 int result;
398
00b3ed16 399 result = -ENOLINK;
21dc0f89 400 if (netif_running(netdev)) {
00b3ed16 401
21dc0f89
MM
402 if (!hw->wlandev->hwremoved
403 && !test_bit(WORK_TX_HALT, &hw->usb_flags)) {
00b3ed16
GKH
404 result = SUBMIT_URB(tx_urb, memflags);
405
406 /* Test whether we need to reset the TX pipe */
407 if (result == -EPIPE) {
263b8bb9 408 netdev_warn(hw->wlandev->netdev,
3f2d6564
SSA
409 "%s tx pipe stalled: requesting reset\n",
410 netdev->name);
00b3ed16
GKH
411 set_bit(WORK_TX_HALT, &hw->usb_flags);
412 schedule_work(&hw->usb_work);
413 } else if (result == 0) {
414 netif_stop_queue(netdev);
415 }
416 }
417 }
418
00b3ed16
GKH
419 return result;
420}
421
422/*----------------------------------------------------------------
423* hfa394x_usb_defer
424*
425* There are some things that the USB stack cannot do while
426* in interrupt context, so we arrange this function to run
427* in process context.
428*
429* Arguments:
430* hw device structure
431*
432* Returns:
433* nothing
434*
435* Call context:
436* process (by design)
437----------------------------------------------------------------*/
21dc0f89 438static void hfa384x_usb_defer(struct work_struct *data)
00b3ed16
GKH
439{
440 hfa384x_t *hw = container_of(data, struct hfa384x, usb_work);
441 struct net_device *netdev = hw->wlandev->netdev;
442
00b3ed16
GKH
443 /* Don't bother trying to reset anything if the plug
444 * has been pulled ...
445 */
21dc0f89 446 if (hw->wlandev->hwremoved)
00b3ed16 447 return;
00b3ed16
GKH
448
449 /* Reception has stopped: try to reset the input pipe */
450 if (test_bit(WORK_RX_HALT, &hw->usb_flags)) {
451 int ret;
452
631c8dec 453 usb_kill_urb(&hw->rx_urb); /* Cannot be holding spinlock! */
00b3ed16
GKH
454
455 ret = usb_clear_halt(hw->usb, hw->endp_in);
456 if (ret != 0) {
263b8bb9 457 netdev_err(hw->wlandev->netdev,
3f2d6564
SSA
458 "Failed to clear rx pipe for %s: err=%d\n",
459 netdev->name, ret);
00b3ed16 460 } else {
263b8bb9 461 netdev_info(hw->wlandev->netdev, "%s rx pipe reset complete.\n",
3f2d6564 462 netdev->name);
00b3ed16
GKH
463 clear_bit(WORK_RX_HALT, &hw->usb_flags);
464 set_bit(WORK_RX_RESUME, &hw->usb_flags);
465 }
466 }
467
468 /* Resume receiving data back from the device. */
21dc0f89 469 if (test_bit(WORK_RX_RESUME, &hw->usb_flags)) {
00b3ed16
GKH
470 int ret;
471
472 ret = submit_rx_urb(hw, GFP_KERNEL);
473 if (ret != 0) {
263b8bb9 474 netdev_err(hw->wlandev->netdev,
3f2d6564
SSA
475 "Failed to resume %s rx pipe.\n",
476 netdev->name);
00b3ed16
GKH
477 } else {
478 clear_bit(WORK_RX_RESUME, &hw->usb_flags);
479 }
480 }
481
482 /* Transmission has stopped: try to reset the output pipe */
483 if (test_bit(WORK_TX_HALT, &hw->usb_flags)) {
484 int ret;
485
486 usb_kill_urb(&hw->tx_urb);
487 ret = usb_clear_halt(hw->usb, hw->endp_out);
488 if (ret != 0) {
263b8bb9 489 netdev_err(hw->wlandev->netdev,
3f2d6564
SSA
490 "Failed to clear tx pipe for %s: err=%d\n",
491 netdev->name, ret);
00b3ed16 492 } else {
263b8bb9 493 netdev_info(hw->wlandev->netdev, "%s tx pipe reset complete.\n",
3f2d6564 494 netdev->name);
00b3ed16
GKH
495 clear_bit(WORK_TX_HALT, &hw->usb_flags);
496 set_bit(WORK_TX_RESUME, &hw->usb_flags);
497
498 /* Stopping the BULK-OUT pipe also blocked
499 * us from sending any more CTLX URBs, so
500 * we need to re-run our queue ...
501 */
502 hfa384x_usbctlxq_run(hw);
503 }
504 }
505
506 /* Resume transmitting. */
21dc0f89 507 if (test_and_clear_bit(WORK_TX_RESUME, &hw->usb_flags))
cbec30c4 508 netif_wake_queue(hw->wlandev->netdev);
00b3ed16
GKH
509}
510
00b3ed16
GKH
511/*----------------------------------------------------------------
512* hfa384x_create
513*
514* Sets up the hfa384x_t data structure for use. Note this
9b0131cb 515* does _not_ initialize the actual hardware, just the data structures
00b3ed16
GKH
516* we use to keep track of its state.
517*
518* Arguments:
519* hw device structure
520* irq device irq number
521* iobase i/o base address for register access
522* membase memory base address for register access
523*
524* Returns:
525* nothing
526*
527* Side effects:
528*
529* Call context:
530* process
531----------------------------------------------------------------*/
297f06ce 532void hfa384x_create(hfa384x_t *hw, struct usb_device *usb)
00b3ed16 533{
00b3ed16
GKH
534 memset(hw, 0, sizeof(hfa384x_t));
535 hw->usb = usb;
536
537 /* set up the endpoints */
538 hw->endp_in = usb_rcvbulkpipe(usb, 1);
539 hw->endp_out = usb_sndbulkpipe(usb, 2);
540
541 /* Set up the waitq */
542 init_waitqueue_head(&hw->cmdq);
543
544 /* Initialize the command queue */
545 spin_lock_init(&hw->ctlxq.lock);
546 INIT_LIST_HEAD(&hw->ctlxq.pending);
547 INIT_LIST_HEAD(&hw->ctlxq.active);
548 INIT_LIST_HEAD(&hw->ctlxq.completing);
549 INIT_LIST_HEAD(&hw->ctlxq.reapable);
550
551 /* Initialize the authentication queue */
552 skb_queue_head_init(&hw->authq);
553
554 tasklet_init(&hw->reaper_bh,
21dc0f89 555 hfa384x_usbctlx_reaper_task, (unsigned long)hw);
00b3ed16 556 tasklet_init(&hw->completion_bh,
21dc0f89 557 hfa384x_usbctlx_completion_task, (unsigned long)hw);
575a8a5c
SP
558 INIT_WORK(&hw->link_bh, prism2sta_processing_defer);
559 INIT_WORK(&hw->usb_work, hfa384x_usb_defer);
00b3ed16
GKH
560
561 init_timer(&hw->throttle);
562 hw->throttle.function = hfa384x_usb_throttlefn;
563 hw->throttle.data = (unsigned long)hw;
564
565 init_timer(&hw->resptimer);
566 hw->resptimer.function = hfa384x_usbctlx_resptimerfn;
567 hw->resptimer.data = (unsigned long)hw;
568
569 init_timer(&hw->reqtimer);
570 hw->reqtimer.function = hfa384x_usbctlx_reqtimerfn;
571 hw->reqtimer.data = (unsigned long)hw;
572
573 usb_init_urb(&hw->rx_urb);
574 usb_init_urb(&hw->tx_urb);
575 usb_init_urb(&hw->ctlx_urb);
576
577 hw->link_status = HFA384x_LINK_NOTCONNECTED;
578 hw->state = HFA384x_STATE_INIT;
579
21dc0f89 580 INIT_WORK(&hw->commsqual_bh, prism2sta_commsqual_defer);
00b3ed16 581 init_timer(&hw->commsqual_timer);
21dc0f89 582 hw->commsqual_timer.data = (unsigned long)hw;
00b3ed16 583 hw->commsqual_timer.function = prism2sta_commsqual_timer;
00b3ed16
GKH
584}
585
00b3ed16
GKH
586/*----------------------------------------------------------------
587* hfa384x_destroy
588*
589* Partner to hfa384x_create(). This function cleans up the hw
590* structure so that it can be freed by the caller using a simple
591* kfree. Currently, this function is just a placeholder. If, at some
592* point in the future, an hw in the 'shutdown' state requires a 'deep'
593* kfree, this is where it should be done. Note that if this function
594* is called on a _running_ hw structure, the drvr_stop() function is
595* called.
596*
597* Arguments:
598* hw device structure
599*
600* Returns:
601* nothing, this function is not allowed to fail.
602*
603* Side effects:
604*
605* Call context:
606* process
607----------------------------------------------------------------*/
297f06ce 608void hfa384x_destroy(hfa384x_t *hw)
00b3ed16
GKH
609{
610 struct sk_buff *skb;
611
21dc0f89 612 if (hw->state == HFA384x_STATE_RUNNING)
00b3ed16 613 hfa384x_drvr_stop(hw);
00b3ed16
GKH
614 hw->state = HFA384x_STATE_PREINIT;
615
a6f9c48f
IM
616 kfree(hw->scanresults);
617 hw->scanresults = NULL;
00b3ed16
GKH
618
619 /* Now to clean out the auth queue */
21dc0f89
MM
620 while ((skb = skb_dequeue(&hw->authq)))
621 dev_kfree_skb(skb);
00b3ed16
GKH
622}
623
21dc0f89 624static hfa384x_usbctlx_t *usbctlx_alloc(void)
00b3ed16
GKH
625{
626 hfa384x_usbctlx_t *ctlx;
627
5dd8acc8 628 ctlx = kmalloc(sizeof(*ctlx), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
21dc0f89 629 if (ctlx != NULL) {
00b3ed16
GKH
630 memset(ctlx, 0, sizeof(*ctlx));
631 init_completion(&ctlx->done);
632 }
633
634 return ctlx;
635}
636
00b3ed16 637static int
297f06ce
MT
638usbctlx_get_status(const hfa384x_usb_cmdresp_t *cmdresp,
639 hfa384x_cmdresult_t *result)
00b3ed16 640{
18c7f792
MM
641 result->status = le16_to_cpu(cmdresp->status);
642 result->resp0 = le16_to_cpu(cmdresp->resp0);
643 result->resp1 = le16_to_cpu(cmdresp->resp1);
644 result->resp2 = le16_to_cpu(cmdresp->resp2);
00b3ed16 645
a2120136 646 pr_debug("cmdresult:status=0x%04x resp0=0x%04x resp1=0x%04x resp2=0x%04x\n",
75f49e07 647 result->status, result->resp0, result->resp1, result->resp2);
00b3ed16 648
21dc0f89 649 return result->status & HFA384x_STATUS_RESULT;
00b3ed16
GKH
650}
651
652static void
297f06ce
MT
653usbctlx_get_rridresult(const hfa384x_usb_rridresp_t *rridresp,
654 hfa384x_rridresult_t *result)
00b3ed16 655{
18c7f792 656 result->rid = le16_to_cpu(rridresp->rid);
00b3ed16 657 result->riddata = rridresp->data;
18c7f792 658 result->riddata_len = ((le16_to_cpu(rridresp->frmlen) - 1) * 2);
00b3ed16 659
00b3ed16
GKH
660}
661
00b3ed16
GKH
662/*----------------------------------------------------------------
663* Completor object:
664* This completor must be passed to hfa384x_usbctlx_complete_sync()
665* when processing a CTLX that returns a hfa384x_cmdresult_t structure.
666----------------------------------------------------------------*/
21dc0f89 667struct usbctlx_cmd_completor {
631c8dec 668 struct usbctlx_completor head;
00b3ed16 669
21dc0f89
MM
670 const hfa384x_usb_cmdresp_t *cmdresp;
671 hfa384x_cmdresult_t *result;
00b3ed16 672};
00b3ed16 673
631c8dec 674static inline int usbctlx_cmd_completor_fn(struct usbctlx_completor *head)
00b3ed16 675{
631c8dec
EH
676 struct usbctlx_cmd_completor *complete;
677
678 complete = (struct usbctlx_cmd_completor *) head;
00b3ed16
GKH
679 return usbctlx_get_status(complete->cmdresp, complete->result);
680}
681
631c8dec
EH
682static inline struct usbctlx_completor *init_cmd_completor(
683 struct usbctlx_cmd_completor
684 *completor,
685 const hfa384x_usb_cmdresp_t
686 *cmdresp,
687 hfa384x_cmdresult_t *result)
00b3ed16
GKH
688{
689 completor->head.complete = usbctlx_cmd_completor_fn;
690 completor->cmdresp = cmdresp;
691 completor->result = result;
692 return &(completor->head);
693}
694
695/*----------------------------------------------------------------
696* Completor object:
697* This completor must be passed to hfa384x_usbctlx_complete_sync()
698* when processing a CTLX that reads a RID.
699----------------------------------------------------------------*/
21dc0f89 700struct usbctlx_rrid_completor {
631c8dec 701 struct usbctlx_completor head;
00b3ed16 702
21dc0f89
MM
703 const hfa384x_usb_rridresp_t *rridresp;
704 void *riddata;
705 unsigned int riddatalen;
00b3ed16 706};
00b3ed16 707
631c8dec 708static int usbctlx_rrid_completor_fn(struct usbctlx_completor *head)
00b3ed16 709{
631c8dec 710 struct usbctlx_rrid_completor *complete;
00b3ed16
GKH
711 hfa384x_rridresult_t rridresult;
712
631c8dec 713 complete = (struct usbctlx_rrid_completor *) head;
00b3ed16
GKH
714 usbctlx_get_rridresult(complete->rridresp, &rridresult);
715
716 /* Validate the length, note body len calculation in bytes */
21dc0f89 717 if (rridresult.riddata_len != complete->riddatalen) {
baa8a6c0
SSA
718 pr_warn("RID len mismatch, rid=0x%04x hlen=%d fwlen=%d\n",
719 rridresult.rid,
720 complete->riddatalen, rridresult.riddata_len);
00b3ed16
GKH
721 return -ENODATA;
722 }
723
21dc0f89 724 memcpy(complete->riddata, rridresult.riddata, complete->riddatalen);
00b3ed16
GKH
725 return 0;
726}
727
631c8dec
EH
728static inline struct usbctlx_completor *init_rrid_completor(
729 struct usbctlx_rrid_completor
730 *completor,
731 const hfa384x_usb_rridresp_t
732 *rridresp,
733 void *riddata,
734 unsigned int riddatalen)
00b3ed16
GKH
735{
736 completor->head.complete = usbctlx_rrid_completor_fn;
737 completor->rridresp = rridresp;
738 completor->riddata = riddata;
739 completor->riddatalen = riddatalen;
740 return &(completor->head);
741}
742
743/*----------------------------------------------------------------
744* Completor object:
745* Interprets the results of a synchronous RID-write
746----------------------------------------------------------------*/
00b3ed16
GKH
747#define init_wrid_completor init_cmd_completor
748
749/*----------------------------------------------------------------
750* Completor object:
751* Interprets the results of a synchronous memory-write
752----------------------------------------------------------------*/
00b3ed16
GKH
753#define init_wmem_completor init_cmd_completor
754
755/*----------------------------------------------------------------
756* Completor object:
757* Interprets the results of a synchronous memory-read
758----------------------------------------------------------------*/
21dc0f89 759struct usbctlx_rmem_completor {
631c8dec 760 struct usbctlx_completor head;
00b3ed16 761
21dc0f89
MM
762 const hfa384x_usb_rmemresp_t *rmemresp;
763 void *data;
764 unsigned int len;
00b3ed16 765};
00b3ed16 766
631c8dec 767static int usbctlx_rmem_completor_fn(struct usbctlx_completor *head)
00b3ed16 768{
a03742ac
SSA
769 struct usbctlx_rmem_completor *complete =
770 (struct usbctlx_rmem_completor *)head;
00b3ed16 771
a7cf7bae 772 pr_debug("rmemresp:len=%d\n", complete->rmemresp->frmlen);
00b3ed16
GKH
773 memcpy(complete->data, complete->rmemresp->data, complete->len);
774 return 0;
775}
776
631c8dec 777static inline struct usbctlx_completor *init_rmem_completor(
a03742ac 778 struct usbctlx_rmem_completor
631c8dec
EH
779 *completor,
780 hfa384x_usb_rmemresp_t
781 *rmemresp,
782 void *data,
783 unsigned int len)
00b3ed16
GKH
784{
785 completor->head.complete = usbctlx_rmem_completor_fn;
786 completor->rmemresp = rmemresp;
787 completor->data = data;
788 completor->len = len;
789 return &(completor->head);
790}
791
792/*----------------------------------------------------------------
793* hfa384x_cb_status
794*
795* Ctlx_complete handler for async CMD type control exchanges.
796* mark the hw struct as such.
797*
798* Note: If the handling is changed here, it should probably be
799* changed in docmd as well.
800*
801* Arguments:
802* hw hw struct
803* ctlx completed CTLX
804*
805* Returns:
806* nothing
807*
808* Side effects:
809*
810* Call context:
811* interrupt
812----------------------------------------------------------------*/
297f06ce 813static void hfa384x_cb_status(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx)
00b3ed16 814{
21dc0f89 815 if (ctlx->usercb != NULL) {
00b3ed16
GKH
816 hfa384x_cmdresult_t cmdresult;
817
818 if (ctlx->state != CTLX_COMPLETE) {
819 memset(&cmdresult, 0, sizeof(cmdresult));
21dc0f89
MM
820 cmdresult.status =
821 HFA384x_STATUS_RESULT_SET(HFA384x_CMD_ERR);
00b3ed16
GKH
822 } else {
823 usbctlx_get_status(&ctlx->inbuf.cmdresp, &cmdresult);
824 }
825
826 ctlx->usercb(hw, &cmdresult, ctlx->usercb_data);
827 }
00b3ed16
GKH
828}
829
00b3ed16
GKH
830/*----------------------------------------------------------------
831* hfa384x_cb_rrid
832*
833* CTLX completion handler for async RRID type control exchanges.
834*
835* Note: If the handling is changed here, it should probably be
836* changed in dorrid as well.
837*
838* Arguments:
839* hw hw struct
840* ctlx completed CTLX
841*
842* Returns:
843* nothing
844*
845* Side effects:
846*
847* Call context:
848* interrupt
849----------------------------------------------------------------*/
297f06ce 850static void hfa384x_cb_rrid(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx)
00b3ed16 851{
21dc0f89 852 if (ctlx->usercb != NULL) {
00b3ed16
GKH
853 hfa384x_rridresult_t rridresult;
854
855 if (ctlx->state != CTLX_COMPLETE) {
856 memset(&rridresult, 0, sizeof(rridresult));
75f49e07 857 rridresult.rid = le16_to_cpu(ctlx->outbuf.rridreq.rid);
00b3ed16 858 } else {
21dc0f89
MM
859 usbctlx_get_rridresult(&ctlx->inbuf.rridresp,
860 &rridresult);
00b3ed16
GKH
861 }
862
863 ctlx->usercb(hw, &rridresult, ctlx->usercb_data);
864 }
00b3ed16
GKH
865}
866
297f06ce 867static inline int hfa384x_docmd_wait(hfa384x_t *hw, hfa384x_metacmd_t *cmd)
00b3ed16
GKH
868{
869 return hfa384x_docmd(hw, DOWAIT, cmd, NULL, NULL, NULL);
870}
871
872static inline int
297f06ce
MT
873hfa384x_docmd_async(hfa384x_t *hw,
874 hfa384x_metacmd_t *cmd,
21dc0f89 875 ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
00b3ed16 876{
21dc0f89 877 return hfa384x_docmd(hw, DOASYNC, cmd, cmdcb, usercb, usercb_data);
00b3ed16
GKH
878}
879
880static inline int
297f06ce 881hfa384x_dorrid_wait(hfa384x_t *hw, u16 rid, void *riddata,
21dc0f89 882 unsigned int riddatalen)
00b3ed16
GKH
883{
884 return hfa384x_dorrid(hw, DOWAIT,
21dc0f89 885 rid, riddata, riddatalen, NULL, NULL, NULL);
00b3ed16
GKH
886}
887
888static inline int
297f06ce 889hfa384x_dorrid_async(hfa384x_t *hw,
21dc0f89
MM
890 u16 rid, void *riddata, unsigned int riddatalen,
891 ctlx_cmdcb_t cmdcb,
892 ctlx_usercb_t usercb, void *usercb_data)
00b3ed16
GKH
893{
894 return hfa384x_dorrid(hw, DOASYNC,
21dc0f89
MM
895 rid, riddata, riddatalen,
896 cmdcb, usercb, usercb_data);
00b3ed16
GKH
897}
898
899static inline int
297f06ce 900hfa384x_dowrid_wait(hfa384x_t *hw, u16 rid, void *riddata,
21dc0f89 901 unsigned int riddatalen)
00b3ed16
GKH
902{
903 return hfa384x_dowrid(hw, DOWAIT,
21dc0f89 904 rid, riddata, riddatalen, NULL, NULL, NULL);
00b3ed16
GKH
905}
906
907static inline int
297f06ce 908hfa384x_dowrid_async(hfa384x_t *hw,
21dc0f89
MM
909 u16 rid, void *riddata, unsigned int riddatalen,
910 ctlx_cmdcb_t cmdcb,
911 ctlx_usercb_t usercb, void *usercb_data)
00b3ed16
GKH
912{
913 return hfa384x_dowrid(hw, DOASYNC,
21dc0f89
MM
914 rid, riddata, riddatalen,
915 cmdcb, usercb, usercb_data);
00b3ed16
GKH
916}
917
918static inline int
297f06ce 919hfa384x_dormem_wait(hfa384x_t *hw,
21dc0f89 920 u16 page, u16 offset, void *data, unsigned int len)
00b3ed16
GKH
921{
922 return hfa384x_dormem(hw, DOWAIT,
21dc0f89 923 page, offset, data, len, NULL, NULL, NULL);
00b3ed16
GKH
924}
925
926static inline int
297f06ce 927hfa384x_dormem_async(hfa384x_t *hw,
21dc0f89
MM
928 u16 page, u16 offset, void *data, unsigned int len,
929 ctlx_cmdcb_t cmdcb,
930 ctlx_usercb_t usercb, void *usercb_data)
00b3ed16
GKH
931{
932 return hfa384x_dormem(hw, DOASYNC,
21dc0f89
MM
933 page, offset, data, len,
934 cmdcb, usercb, usercb_data);
00b3ed16
GKH
935}
936
937static inline int
297f06ce 938hfa384x_dowmem_wait(hfa384x_t *hw,
21dc0f89 939 u16 page, u16 offset, void *data, unsigned int len)
00b3ed16
GKH
940{
941 return hfa384x_dowmem(hw, DOWAIT,
21dc0f89 942 page, offset, data, len, NULL, NULL, NULL);
00b3ed16
GKH
943}
944
945static inline int
297f06ce 946hfa384x_dowmem_async(hfa384x_t *hw,
21dc0f89
MM
947 u16 page,
948 u16 offset,
949 void *data,
950 unsigned int len,
951 ctlx_cmdcb_t cmdcb,
952 ctlx_usercb_t usercb, void *usercb_data)
00b3ed16
GKH
953{
954 return hfa384x_dowmem(hw, DOASYNC,
21dc0f89
MM
955 page, offset, data, len,
956 cmdcb, usercb, usercb_data);
00b3ed16
GKH
957}
958
959/*----------------------------------------------------------------
960* hfa384x_cmd_initialize
961*
962* Issues the initialize command and sets the hw->state based
963* on the result.
964*
965* Arguments:
966* hw device structure
967*
968* Returns:
969* 0 success
970* >0 f/w reported error - f/w status code
971* <0 driver reported error
972*
973* Side effects:
974*
975* Call context:
976* process
977----------------------------------------------------------------*/
297f06ce 978int hfa384x_cmd_initialize(hfa384x_t *hw)
00b3ed16 979{
21dc0f89
MM
980 int result = 0;
981 int i;
00b3ed16
GKH
982 hfa384x_metacmd_t cmd;
983
00b3ed16
GKH
984 cmd.cmd = HFA384x_CMDCODE_INIT;
985 cmd.parm0 = 0;
986 cmd.parm1 = 0;
987 cmd.parm2 = 0;
988
989 result = hfa384x_docmd_wait(hw, &cmd);
990
a2120136 991 pr_debug("cmdresp.init: status=0x%04x, resp0=0x%04x, resp1=0x%04x, resp2=0x%04x\n",
75f49e07
MT
992 cmd.result.status,
993 cmd.result.resp0, cmd.result.resp1, cmd.result.resp2);
21dc0f89
MM
994 if (result == 0) {
995 for (i = 0; i < HFA384x_NUMPORTS_MAX; i++)
00b3ed16 996 hw->port_enabled[i] = 0;
00b3ed16
GKH
997 }
998
21dc0f89 999 hw->link_status = HFA384x_LINK_NOTCONNECTED;
00b3ed16 1000
00b3ed16
GKH
1001 return result;
1002}
1003
00b3ed16
GKH
1004/*----------------------------------------------------------------
1005* hfa384x_cmd_disable
1006*
1007* Issues the disable command to stop communications on one of
1008* the MACs 'ports'.
1009*
1010* Arguments:
1011* hw device structure
1012* macport MAC port number (host order)
1013*
1014* Returns:
1015* 0 success
1016* >0 f/w reported failure - f/w status code
1017* <0 driver reported error (timeout|bad arg)
1018*
1019* Side effects:
1020*
1021* Call context:
1022* process
1023----------------------------------------------------------------*/
297f06ce 1024int hfa384x_cmd_disable(hfa384x_t *hw, u16 macport)
00b3ed16 1025{
21dc0f89 1026 int result = 0;
00b3ed16
GKH
1027 hfa384x_metacmd_t cmd;
1028
00b3ed16 1029 cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DISABLE) |
21dc0f89 1030 HFA384x_CMD_MACPORT_SET(macport);
00b3ed16
GKH
1031 cmd.parm0 = 0;
1032 cmd.parm1 = 0;
1033 cmd.parm2 = 0;
1034
1035 result = hfa384x_docmd_wait(hw, &cmd);
1036
00b3ed16
GKH
1037 return result;
1038}
1039
00b3ed16
GKH
1040/*----------------------------------------------------------------
1041* hfa384x_cmd_enable
1042*
1043* Issues the enable command to enable communications on one of
1044* the MACs 'ports'.
1045*
1046* Arguments:
1047* hw device structure
1048* macport MAC port number
1049*
1050* Returns:
1051* 0 success
1052* >0 f/w reported failure - f/w status code
1053* <0 driver reported error (timeout|bad arg)
1054*
1055* Side effects:
1056*
1057* Call context:
1058* process
1059----------------------------------------------------------------*/
297f06ce 1060int hfa384x_cmd_enable(hfa384x_t *hw, u16 macport)
00b3ed16 1061{
21dc0f89 1062 int result = 0;
00b3ed16
GKH
1063 hfa384x_metacmd_t cmd;
1064
00b3ed16 1065 cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ENABLE) |
21dc0f89 1066 HFA384x_CMD_MACPORT_SET(macport);
00b3ed16
GKH
1067 cmd.parm0 = 0;
1068 cmd.parm1 = 0;
1069 cmd.parm2 = 0;
1070
1071 result = hfa384x_docmd_wait(hw, &cmd);
1072
00b3ed16
GKH
1073 return result;
1074}
1075
00b3ed16
GKH
1076/*----------------------------------------------------------------
1077* hfa384x_cmd_monitor
1078*
1079* Enables the 'monitor mode' of the MAC. Here's the description of
1080* monitor mode that I've received thus far:
1081*
1082* "The "monitor mode" of operation is that the MAC passes all
1083* frames for which the PLCP checks are correct. All received
1084* MPDUs are passed to the host with MAC Port = 7, with a
1085* receive status of good, FCS error, or undecryptable. Passing
1086* certain MPDUs is a violation of the 802.11 standard, but useful
1087* for a debugging tool." Normal communication is not possible
1088* while monitor mode is enabled.
1089*
1090* Arguments:
1091* hw device structure
1092* enable a code (0x0b|0x0f) that enables/disables
1093* monitor mode. (host order)
1094*
1095* Returns:
1096* 0 success
1097* >0 f/w reported failure - f/w status code
1098* <0 driver reported error (timeout|bad arg)
1099*
1100* Side effects:
1101*
1102* Call context:
1103* process
1104----------------------------------------------------------------*/
297f06ce 1105int hfa384x_cmd_monitor(hfa384x_t *hw, u16 enable)
00b3ed16 1106{
21dc0f89 1107 int result = 0;
00b3ed16
GKH
1108 hfa384x_metacmd_t cmd;
1109
00b3ed16 1110 cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_MONITOR) |
21dc0f89 1111 HFA384x_CMD_AINFO_SET(enable);
00b3ed16
GKH
1112 cmd.parm0 = 0;
1113 cmd.parm1 = 0;
1114 cmd.parm2 = 0;
1115
1116 result = hfa384x_docmd_wait(hw, &cmd);
1117
00b3ed16
GKH
1118 return result;
1119}
1120
00b3ed16
GKH
1121/*----------------------------------------------------------------
1122* hfa384x_cmd_download
1123*
1124* Sets the controls for the MAC controller code/data download
1125* process. The arguments set the mode and address associated
1126* with a download. Note that the aux registers should be enabled
1127* prior to setting one of the download enable modes.
1128*
1129* Arguments:
1130* hw device structure
1131* mode 0 - Disable programming and begin code exec
1132* 1 - Enable volatile mem programming
1133* 2 - Enable non-volatile mem programming
1134* 3 - Program non-volatile section from NV download
1135* buffer.
1136* (host order)
1137* lowaddr
1138* highaddr For mode 1, sets the high & low order bits of
1139* the "destination address". This address will be
1140* the execution start address when download is
1141* subsequently disabled.
1142* For mode 2, sets the high & low order bits of
1143* the destination in NV ram.
1144* For modes 0 & 3, should be zero. (host order)
1145* NOTE: these are CMD format.
1146* codelen Length of the data to write in mode 2,
1147* zero otherwise. (host order)
1148*
1149* Returns:
1150* 0 success
1151* >0 f/w reported failure - f/w status code
1152* <0 driver reported error (timeout|bad arg)
1153*
1154* Side effects:
1155*
1156* Call context:
1157* process
1158----------------------------------------------------------------*/
297f06ce 1159int hfa384x_cmd_download(hfa384x_t *hw, u16 mode, u16 lowaddr,
21dc0f89 1160 u16 highaddr, u16 codelen)
00b3ed16 1161{
21dc0f89 1162 int result = 0;
00b3ed16
GKH
1163 hfa384x_metacmd_t cmd;
1164
75f49e07
MT
1165 pr_debug("mode=%d, lowaddr=0x%04x, highaddr=0x%04x, codelen=%d\n",
1166 mode, lowaddr, highaddr, codelen);
00b3ed16
GKH
1167
1168 cmd.cmd = (HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DOWNLD) |
1169 HFA384x_CMD_PROGMODE_SET(mode));
1170
1171 cmd.parm0 = lowaddr;
1172 cmd.parm1 = highaddr;
1173 cmd.parm2 = codelen;
1174
1175 result = hfa384x_docmd_wait(hw, &cmd);
1176
00b3ed16
GKH
1177 return result;
1178}
1179
00b3ed16
GKH
1180/*----------------------------------------------------------------
1181* hfa384x_corereset
1182*
1183* Perform a reset of the hfa38xx MAC core. We assume that the hw
1184* structure is in its "created" state. That is, it is initialized
1185* with proper values. Note that if a reset is done after the
1186* device has been active for awhile, the caller might have to clean
1187* up some leftover cruft in the hw structure.
1188*
1189* Arguments:
1190* hw device structure
1191* holdtime how long (in ms) to hold the reset
1192* settletime how long (in ms) to wait after releasing
1193* the reset
1194*
1195* Returns:
1196* nothing
1197*
1198* Side effects:
1199*
1200* Call context:
1201* process
1202----------------------------------------------------------------*/
297f06ce 1203int hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis)
00b3ed16 1204{
21dc0f89 1205 int result = 0;
00b3ed16 1206
21dc0f89
MM
1207 result = usb_reset_device(hw->usb);
1208 if (result < 0) {
263b8bb9 1209 netdev_err(hw->wlandev->netdev, "usb_reset_device() failed, result=%d.\n",
3f2d6564 1210 result);
00b3ed16
GKH
1211 }
1212
00b3ed16
GKH
1213 return result;
1214}
1215
00b3ed16
GKH
1216/*----------------------------------------------------------------
1217* hfa384x_usbctlx_complete_sync
1218*
1219* Waits for a synchronous CTLX object to complete,
1220* and then handles the response.
1221*
1222* Arguments:
1223* hw device structure
631c8dec 1224* ctlx CTLX ptr
00b3ed16
GKH
1225* completor functor object to decide what to
1226* do with the CTLX's result.
1227*
1228* Returns:
1229* 0 Success
1230* -ERESTARTSYS Interrupted by a signal
1231* -EIO CTLX failed
1232* -ENODEV Adapter was unplugged
1233* ??? Result from completor
1234*
1235* Side effects:
1236*
1237* Call context:
1238* process
1239----------------------------------------------------------------*/
297f06ce
MT
1240static int hfa384x_usbctlx_complete_sync(hfa384x_t *hw,
1241 hfa384x_usbctlx_t *ctlx,
631c8dec 1242 struct usbctlx_completor *completor)
00b3ed16
GKH
1243{
1244 unsigned long flags;
1245 int result;
1246
00b3ed16
GKH
1247 result = wait_for_completion_interruptible(&ctlx->done);
1248
1249 spin_lock_irqsave(&hw->ctlxq.lock, flags);
1250
1251 /*
1252 * We can only handle the CTLX if the USB disconnect
1253 * function has not run yet ...
1254 */
21dc0f89
MM
1255cleanup:
1256 if (hw->wlandev->hwremoved) {
00b3ed16
GKH
1257 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
1258 result = -ENODEV;
21dc0f89 1259 } else if (result != 0) {
00b3ed16
GKH
1260 int runqueue = 0;
1261
1262 /*
1263 * We were probably interrupted, so delete
1264 * this CTLX asynchronously, kill the timers
1265 * and the URB, and then start the next
1266 * pending CTLX.
1267 *
1268 * NOTE: We can only delete the timers and
1269 * the URB if this CTLX is active.
1270 */
21dc0f89 1271 if (ctlx == get_active_ctlx(hw)) {
00b3ed16
GKH
1272 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
1273
1274 del_singleshot_timer_sync(&hw->reqtimer);
1275 del_singleshot_timer_sync(&hw->resptimer);
1276 hw->req_timer_done = 1;
1277 hw->resp_timer_done = 1;
1278 usb_kill_urb(&hw->ctlx_urb);
1279
1280 spin_lock_irqsave(&hw->ctlxq.lock, flags);
1281
1282 runqueue = 1;
1283
1284 /*
1285 * This scenario is so unlikely that I'm
1286 * happy with a grubby "goto" solution ...
1287 */
21dc0f89 1288 if (hw->wlandev->hwremoved)
00b3ed16
GKH
1289 goto cleanup;
1290 }
1291
1292 /*
1293 * The completion task will send this CTLX
1294 * to the reaper the next time it runs. We
1295 * are no longer in a hurry.
1296 */
1297 ctlx->reapable = 1;
1298 ctlx->state = CTLX_REQ_FAILED;
1299 list_move_tail(&ctlx->list, &hw->ctlxq.completing);
1300
1301 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
1302
1303 if (runqueue)
1304 hfa384x_usbctlxq_run(hw);
1305 } else {
1306 if (ctlx->state == CTLX_COMPLETE) {
1307 result = completor->complete(completor);
1308 } else {
263b8bb9 1309 netdev_warn(hw->wlandev->netdev, "CTLX[%d] error: state(%s)\n",
3f2d6564
SSA
1310 le16_to_cpu(ctlx->outbuf.type),
1311 ctlxstr(ctlx->state));
00b3ed16
GKH
1312 result = -EIO;
1313 }
1314
1315 list_del(&ctlx->list);
1316 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
1317 kfree(ctlx);
1318 }
1319
00b3ed16
GKH
1320 return result;
1321}
1322
1323/*----------------------------------------------------------------
1324* hfa384x_docmd
1325*
1326* Constructs a command CTLX and submits it.
1327*
1328* NOTE: Any changes to the 'post-submit' code in this function
1329* need to be carried over to hfa384x_cbcmd() since the handling
1330* is virtually identical.
1331*
1332* Arguments:
1333* hw device structure
1334* mode DOWAIT or DOASYNC
1335* cmd cmd structure. Includes all arguments and result
1336* data points. All in host order. in host order
1337* cmdcb command-specific callback
1338* usercb user callback for async calls, NULL for DOWAIT calls
1339* usercb_data user supplied data pointer for async calls, NULL
1340* for DOASYNC calls
1341*
1342* Returns:
1343* 0 success
1344* -EIO CTLX failure
1345* -ERESTARTSYS Awakened on signal
1346* >0 command indicated error, Status and Resp0-2 are
1347* in hw structure.
1348*
1349* Side effects:
1350*
1351*
1352* Call context:
1353* process
1354----------------------------------------------------------------*/
1355static int
297f06ce 1356hfa384x_docmd(hfa384x_t *hw,
631c8dec 1357 enum cmd_mode mode,
297f06ce 1358 hfa384x_metacmd_t *cmd,
21dc0f89 1359 ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
00b3ed16 1360{
21dc0f89
MM
1361 int result;
1362 hfa384x_usbctlx_t *ctlx;
00b3ed16 1363
00b3ed16 1364 ctlx = usbctlx_alloc();
21dc0f89 1365 if (ctlx == NULL) {
00b3ed16
GKH
1366 result = -ENOMEM;
1367 goto done;
1368 }
1369
1370 /* Initialize the command */
18c7f792
MM
1371 ctlx->outbuf.cmdreq.type = cpu_to_le16(HFA384x_USB_CMDREQ);
1372 ctlx->outbuf.cmdreq.cmd = cpu_to_le16(cmd->cmd);
1373 ctlx->outbuf.cmdreq.parm0 = cpu_to_le16(cmd->parm0);
1374 ctlx->outbuf.cmdreq.parm1 = cpu_to_le16(cmd->parm1);
1375 ctlx->outbuf.cmdreq.parm2 = cpu_to_le16(cmd->parm2);
00b3ed16
GKH
1376
1377 ctlx->outbufsize = sizeof(ctlx->outbuf.cmdreq);
1378
a2120136 1379 pr_debug("cmdreq: cmd=0x%04x parm0=0x%04x parm1=0x%04x parm2=0x%04x\n",
75f49e07 1380 cmd->cmd, cmd->parm0, cmd->parm1, cmd->parm2);
00b3ed16
GKH
1381
1382 ctlx->reapable = mode;
1383 ctlx->cmdcb = cmdcb;
1384 ctlx->usercb = usercb;
1385 ctlx->usercb_data = usercb_data;
1386
1387 result = hfa384x_usbctlx_submit(hw, ctlx);
1388 if (result != 0) {
1389 kfree(ctlx);
1390 } else if (mode == DOWAIT) {
631c8dec 1391 struct usbctlx_cmd_completor completor;
00b3ed16 1392
21dc0f89
MM
1393 result =
1394 hfa384x_usbctlx_complete_sync(hw, ctlx,
1395 init_cmd_completor(&completor,
1396 &ctlx->
1397 inbuf.
1398 cmdresp,
1399 &cmd->
1400 result));
00b3ed16
GKH
1401 }
1402
1403done:
00b3ed16
GKH
1404 return result;
1405}
1406
00b3ed16
GKH
1407/*----------------------------------------------------------------
1408* hfa384x_dorrid
1409*
1410* Constructs a read rid CTLX and issues it.
1411*
1412* NOTE: Any changes to the 'post-submit' code in this function
1413* need to be carried over to hfa384x_cbrrid() since the handling
1414* is virtually identical.
1415*
1416* Arguments:
1417* hw device structure
1418* mode DOWAIT or DOASYNC
1419* rid Read RID number (host order)
1420* riddata Caller supplied buffer that MAC formatted RID.data
1421* record will be written to for DOWAIT calls. Should
1422* be NULL for DOASYNC calls.
1423* riddatalen Buffer length for DOWAIT calls. Zero for DOASYNC calls.
1424* cmdcb command callback for async calls, NULL for DOWAIT calls
1425* usercb user callback for async calls, NULL for DOWAIT calls
1426* usercb_data user supplied data pointer for async calls, NULL
1427* for DOWAIT calls
1428*
1429* Returns:
1430* 0 success
1431* -EIO CTLX failure
1432* -ERESTARTSYS Awakened on signal
1433* -ENODATA riddatalen != macdatalen
1434* >0 command indicated error, Status and Resp0-2 are
1435* in hw structure.
1436*
1437* Side effects:
1438*
1439* Call context:
1440* interrupt (DOASYNC)
1441* process (DOWAIT or DOASYNC)
1442----------------------------------------------------------------*/
1443static int
297f06ce 1444hfa384x_dorrid(hfa384x_t *hw,
631c8dec 1445 enum cmd_mode mode,
21dc0f89
MM
1446 u16 rid,
1447 void *riddata,
1448 unsigned int riddatalen,
1449 ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
00b3ed16 1450{
21dc0f89
MM
1451 int result;
1452 hfa384x_usbctlx_t *ctlx;
00b3ed16 1453
00b3ed16 1454 ctlx = usbctlx_alloc();
21dc0f89 1455 if (ctlx == NULL) {
00b3ed16
GKH
1456 result = -ENOMEM;
1457 goto done;
1458 }
1459
1460 /* Initialize the command */
18c7f792 1461 ctlx->outbuf.rridreq.type = cpu_to_le16(HFA384x_USB_RRIDREQ);
00b3ed16 1462 ctlx->outbuf.rridreq.frmlen =
18c7f792
MM
1463 cpu_to_le16(sizeof(ctlx->outbuf.rridreq.rid));
1464 ctlx->outbuf.rridreq.rid = cpu_to_le16(rid);
00b3ed16
GKH
1465
1466 ctlx->outbufsize = sizeof(ctlx->outbuf.rridreq);
1467
1468 ctlx->reapable = mode;
1469 ctlx->cmdcb = cmdcb;
1470 ctlx->usercb = usercb;
1471 ctlx->usercb_data = usercb_data;
1472
1473 /* Submit the CTLX */
1474 result = hfa384x_usbctlx_submit(hw, ctlx);
1475 if (result != 0) {
1476 kfree(ctlx);
1477 } else if (mode == DOWAIT) {
631c8dec 1478 struct usbctlx_rrid_completor completor;
00b3ed16 1479
21dc0f89
MM
1480 result =
1481 hfa384x_usbctlx_complete_sync(hw, ctlx,
1482 init_rrid_completor
1483 (&completor,
1484 &ctlx->inbuf.rridresp,
1485 riddata, riddatalen));
00b3ed16
GKH
1486 }
1487
1488done:
00b3ed16
GKH
1489 return result;
1490}
1491
00b3ed16
GKH
1492/*----------------------------------------------------------------
1493* hfa384x_dowrid
1494*
1495* Constructs a write rid CTLX and issues it.
1496*
1497* NOTE: Any changes to the 'post-submit' code in this function
1498* need to be carried over to hfa384x_cbwrid() since the handling
1499* is virtually identical.
1500*
1501* Arguments:
1502* hw device structure
631c8dec 1503* enum cmd_mode DOWAIT or DOASYNC
00b3ed16
GKH
1504* rid RID code
1505* riddata Data portion of RID formatted for MAC
1506* riddatalen Length of the data portion in bytes
1507* cmdcb command callback for async calls, NULL for DOWAIT calls
1508* usercb user callback for async calls, NULL for DOWAIT calls
1509* usercb_data user supplied data pointer for async calls
1510*
1511* Returns:
1512* 0 success
1513* -ETIMEDOUT timed out waiting for register ready or
1514* command completion
1515* >0 command indicated error, Status and Resp0-2 are
1516* in hw structure.
1517*
1518* Side effects:
1519*
1520* Call context:
1521* interrupt (DOASYNC)
1522* process (DOWAIT or DOASYNC)
1523----------------------------------------------------------------*/
1524static int
297f06ce 1525hfa384x_dowrid(hfa384x_t *hw,
631c8dec 1526 enum cmd_mode mode,
21dc0f89
MM
1527 u16 rid,
1528 void *riddata,
1529 unsigned int riddatalen,
1530 ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
00b3ed16 1531{
21dc0f89
MM
1532 int result;
1533 hfa384x_usbctlx_t *ctlx;
00b3ed16 1534
00b3ed16 1535 ctlx = usbctlx_alloc();
21dc0f89 1536 if (ctlx == NULL) {
00b3ed16
GKH
1537 result = -ENOMEM;
1538 goto done;
1539 }
1540
1541 /* Initialize the command */
18c7f792
MM
1542 ctlx->outbuf.wridreq.type = cpu_to_le16(HFA384x_USB_WRIDREQ);
1543 ctlx->outbuf.wridreq.frmlen = cpu_to_le16((sizeof
75f49e07
MT
1544 (ctlx->outbuf.wridreq.rid) +
1545 riddatalen + 1) / 2);
18c7f792 1546 ctlx->outbuf.wridreq.rid = cpu_to_le16(rid);
00b3ed16
GKH
1547 memcpy(ctlx->outbuf.wridreq.data, riddata, riddatalen);
1548
1549 ctlx->outbufsize = sizeof(ctlx->outbuf.wridreq.type) +
21dc0f89
MM
1550 sizeof(ctlx->outbuf.wridreq.frmlen) +
1551 sizeof(ctlx->outbuf.wridreq.rid) + riddatalen;
00b3ed16
GKH
1552
1553 ctlx->reapable = mode;
1554 ctlx->cmdcb = cmdcb;
1555 ctlx->usercb = usercb;
1556 ctlx->usercb_data = usercb_data;
1557
1558 /* Submit the CTLX */
1559 result = hfa384x_usbctlx_submit(hw, ctlx);
1560 if (result != 0) {
1561 kfree(ctlx);
1562 } else if (mode == DOWAIT) {
a03742ac 1563 struct usbctlx_cmd_completor completor;
00b3ed16
GKH
1564 hfa384x_cmdresult_t wridresult;
1565
21dc0f89
MM
1566 result = hfa384x_usbctlx_complete_sync(hw,
1567 ctlx,
1568 init_wrid_completor
1569 (&completor,
1570 &ctlx->inbuf.wridresp,
1571 &wridresult));
00b3ed16
GKH
1572 }
1573
1574done:
00b3ed16
GKH
1575 return result;
1576}
1577
1578/*----------------------------------------------------------------
1579* hfa384x_dormem
1580*
1581* Constructs a readmem CTLX and issues it.
1582*
1583* NOTE: Any changes to the 'post-submit' code in this function
1584* need to be carried over to hfa384x_cbrmem() since the handling
1585* is virtually identical.
1586*
1587* Arguments:
1588* hw device structure
1589* mode DOWAIT or DOASYNC
1590* page MAC address space page (CMD format)
1591* offset MAC address space offset
1592* data Ptr to data buffer to receive read
1593* len Length of the data to read (max == 2048)
1594* cmdcb command callback for async calls, NULL for DOWAIT calls
1595* usercb user callback for async calls, NULL for DOWAIT calls
1596* usercb_data user supplied data pointer for async calls
1597*
1598* Returns:
1599* 0 success
1600* -ETIMEDOUT timed out waiting for register ready or
1601* command completion
1602* >0 command indicated error, Status and Resp0-2 are
1603* in hw structure.
1604*
1605* Side effects:
1606*
1607* Call context:
1608* interrupt (DOASYNC)
1609* process (DOWAIT or DOASYNC)
1610----------------------------------------------------------------*/
1611static int
297f06ce 1612hfa384x_dormem(hfa384x_t *hw,
631c8dec 1613 enum cmd_mode mode,
21dc0f89
MM
1614 u16 page,
1615 u16 offset,
1616 void *data,
1617 unsigned int len,
1618 ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
00b3ed16 1619{
21dc0f89
MM
1620 int result;
1621 hfa384x_usbctlx_t *ctlx;
00b3ed16 1622
00b3ed16 1623 ctlx = usbctlx_alloc();
21dc0f89 1624 if (ctlx == NULL) {
00b3ed16
GKH
1625 result = -ENOMEM;
1626 goto done;
1627 }
1628
1629 /* Initialize the command */
18c7f792 1630 ctlx->outbuf.rmemreq.type = cpu_to_le16(HFA384x_USB_RMEMREQ);
21dc0f89 1631 ctlx->outbuf.rmemreq.frmlen =
18c7f792 1632 cpu_to_le16(sizeof(ctlx->outbuf.rmemreq.offset) +
75f49e07 1633 sizeof(ctlx->outbuf.rmemreq.page) + len);
18c7f792
MM
1634 ctlx->outbuf.rmemreq.offset = cpu_to_le16(offset);
1635 ctlx->outbuf.rmemreq.page = cpu_to_le16(page);
00b3ed16
GKH
1636
1637 ctlx->outbufsize = sizeof(ctlx->outbuf.rmemreq);
1638
75f49e07
MT
1639 pr_debug("type=0x%04x frmlen=%d offset=0x%04x page=0x%04x\n",
1640 ctlx->outbuf.rmemreq.type,
1641 ctlx->outbuf.rmemreq.frmlen,
1642 ctlx->outbuf.rmemreq.offset, ctlx->outbuf.rmemreq.page);
00b3ed16 1643
75f49e07 1644 pr_debug("pktsize=%zd\n", ROUNDUP64(sizeof(ctlx->outbuf.rmemreq)));
00b3ed16
GKH
1645
1646 ctlx->reapable = mode;
1647 ctlx->cmdcb = cmdcb;
1648 ctlx->usercb = usercb;
1649 ctlx->usercb_data = usercb_data;
1650
1651 result = hfa384x_usbctlx_submit(hw, ctlx);
1652 if (result != 0) {
1653 kfree(ctlx);
21dc0f89 1654 } else if (mode == DOWAIT) {
a03742ac 1655 struct usbctlx_rmem_completor completor;
21dc0f89
MM
1656
1657 result =
1658 hfa384x_usbctlx_complete_sync(hw, ctlx,
1659 init_rmem_completor
1660 (&completor,
1661 &ctlx->inbuf.rmemresp, data,
1662 len));
00b3ed16
GKH
1663 }
1664
1665done:
00b3ed16
GKH
1666 return result;
1667}
1668
00b3ed16
GKH
1669/*----------------------------------------------------------------
1670* hfa384x_dowmem
1671*
1672* Constructs a writemem CTLX and issues it.
1673*
1674* NOTE: Any changes to the 'post-submit' code in this function
1675* need to be carried over to hfa384x_cbwmem() since the handling
1676* is virtually identical.
1677*
1678* Arguments:
1679* hw device structure
1680* mode DOWAIT or DOASYNC
1681* page MAC address space page (CMD format)
1682* offset MAC address space offset
1683* data Ptr to data buffer containing write data
1684* len Length of the data to read (max == 2048)
1685* cmdcb command callback for async calls, NULL for DOWAIT calls
1686* usercb user callback for async calls, NULL for DOWAIT calls
1687* usercb_data user supplied data pointer for async calls.
1688*
1689* Returns:
1690* 0 success
1691* -ETIMEDOUT timed out waiting for register ready or
1692* command completion
1693* >0 command indicated error, Status and Resp0-2 are
1694* in hw structure.
1695*
1696* Side effects:
1697*
1698* Call context:
1699* interrupt (DOWAIT)
1700* process (DOWAIT or DOASYNC)
1701----------------------------------------------------------------*/
1702static int
297f06ce 1703hfa384x_dowmem(hfa384x_t *hw,
631c8dec 1704 enum cmd_mode mode,
21dc0f89
MM
1705 u16 page,
1706 u16 offset,
1707 void *data,
1708 unsigned int len,
1709 ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
00b3ed16 1710{
21dc0f89
MM
1711 int result;
1712 hfa384x_usbctlx_t *ctlx;
00b3ed16 1713
75f49e07 1714 pr_debug("page=0x%04x offset=0x%04x len=%d\n", page, offset, len);
00b3ed16
GKH
1715
1716 ctlx = usbctlx_alloc();
21dc0f89 1717 if (ctlx == NULL) {
00b3ed16
GKH
1718 result = -ENOMEM;
1719 goto done;
1720 }
1721
1722 /* Initialize the command */
18c7f792 1723 ctlx->outbuf.wmemreq.type = cpu_to_le16(HFA384x_USB_WMEMREQ);
21dc0f89 1724 ctlx->outbuf.wmemreq.frmlen =
18c7f792 1725 cpu_to_le16(sizeof(ctlx->outbuf.wmemreq.offset) +
75f49e07 1726 sizeof(ctlx->outbuf.wmemreq.page) + len);
18c7f792
MM
1727 ctlx->outbuf.wmemreq.offset = cpu_to_le16(offset);
1728 ctlx->outbuf.wmemreq.page = cpu_to_le16(page);
00b3ed16
GKH
1729 memcpy(ctlx->outbuf.wmemreq.data, data, len);
1730
1731 ctlx->outbufsize = sizeof(ctlx->outbuf.wmemreq.type) +
21dc0f89
MM
1732 sizeof(ctlx->outbuf.wmemreq.frmlen) +
1733 sizeof(ctlx->outbuf.wmemreq.offset) +
1734 sizeof(ctlx->outbuf.wmemreq.page) + len;
00b3ed16
GKH
1735
1736 ctlx->reapable = mode;
1737 ctlx->cmdcb = cmdcb;
1738 ctlx->usercb = usercb;
1739 ctlx->usercb_data = usercb_data;
1740
1741 result = hfa384x_usbctlx_submit(hw, ctlx);
1742 if (result != 0) {
1743 kfree(ctlx);
21dc0f89 1744 } else if (mode == DOWAIT) {
a03742ac 1745 struct usbctlx_cmd_completor completor;
21dc0f89
MM
1746 hfa384x_cmdresult_t wmemresult;
1747
1748 result = hfa384x_usbctlx_complete_sync(hw,
1749 ctlx,
1750 init_wmem_completor
1751 (&completor,
1752 &ctlx->inbuf.wmemresp,
1753 &wmemresult));
00b3ed16
GKH
1754 }
1755
1756done:
00b3ed16
GKH
1757 return result;
1758}
1759
00b3ed16
GKH
1760/*----------------------------------------------------------------
1761* hfa384x_drvr_commtallies
1762*
1763* Send a commtallies inquiry to the MAC. Note that this is an async
1764* call that will result in an info frame arriving sometime later.
1765*
1766* Arguments:
1767* hw device structure
1768*
1769* Returns:
1770* zero success.
1771*
1772* Side effects:
1773*
1774* Call context:
1775* process
1776----------------------------------------------------------------*/
297f06ce 1777int hfa384x_drvr_commtallies(hfa384x_t *hw)
00b3ed16
GKH
1778{
1779 hfa384x_metacmd_t cmd;
1780
00b3ed16
GKH
1781 cmd.cmd = HFA384x_CMDCODE_INQ;
1782 cmd.parm0 = HFA384x_IT_COMMTALLIES;
1783 cmd.parm1 = 0;
1784 cmd.parm2 = 0;
1785
1786 hfa384x_docmd_async(hw, &cmd, NULL, NULL, NULL);
1787
00b3ed16
GKH
1788 return 0;
1789}
1790
00b3ed16
GKH
1791/*----------------------------------------------------------------
1792* hfa384x_drvr_disable
1793*
1794* Issues the disable command to stop communications on one of
1795* the MACs 'ports'. Only macport 0 is valid for stations.
1796* APs may also disable macports 1-6. Only ports that have been
1797* previously enabled may be disabled.
1798*
1799* Arguments:
1800* hw device structure
1801* macport MAC port number (host order)
1802*
1803* Returns:
1804* 0 success
1805* >0 f/w reported failure - f/w status code
1806* <0 driver reported error (timeout|bad arg)
1807*
1808* Side effects:
1809*
1810* Call context:
1811* process
1812----------------------------------------------------------------*/
297f06ce 1813int hfa384x_drvr_disable(hfa384x_t *hw, u16 macport)
00b3ed16 1814{
21dc0f89 1815 int result = 0;
00b3ed16 1816
00b3ed16
GKH
1817 if ((!hw->isap && macport != 0) ||
1818 (hw->isap && !(macport <= HFA384x_PORTID_MAX)) ||
21dc0f89 1819 !(hw->port_enabled[macport])) {
00b3ed16
GKH
1820 result = -EINVAL;
1821 } else {
1822 result = hfa384x_cmd_disable(hw, macport);
21dc0f89 1823 if (result == 0)
00b3ed16 1824 hw->port_enabled[macport] = 0;
00b3ed16 1825 }
00b3ed16
GKH
1826 return result;
1827}
1828
00b3ed16
GKH
1829/*----------------------------------------------------------------
1830* hfa384x_drvr_enable
1831*
1832* Issues the enable command to enable communications on one of
1833* the MACs 'ports'. Only macport 0 is valid for stations.
1834* APs may also enable macports 1-6. Only ports that are currently
1835* disabled may be enabled.
1836*
1837* Arguments:
1838* hw device structure
1839* macport MAC port number
1840*
1841* Returns:
1842* 0 success
1843* >0 f/w reported failure - f/w status code
1844* <0 driver reported error (timeout|bad arg)
1845*
1846* Side effects:
1847*
1848* Call context:
1849* process
1850----------------------------------------------------------------*/
297f06ce 1851int hfa384x_drvr_enable(hfa384x_t *hw, u16 macport)
00b3ed16 1852{
21dc0f89 1853 int result = 0;
00b3ed16 1854
00b3ed16
GKH
1855 if ((!hw->isap && macport != 0) ||
1856 (hw->isap && !(macport <= HFA384x_PORTID_MAX)) ||
21dc0f89 1857 (hw->port_enabled[macport])) {
00b3ed16
GKH
1858 result = -EINVAL;
1859 } else {
1860 result = hfa384x_cmd_enable(hw, macport);
21dc0f89 1861 if (result == 0)
00b3ed16 1862 hw->port_enabled[macport] = 1;
00b3ed16 1863 }
00b3ed16
GKH
1864 return result;
1865}
1866
00b3ed16
GKH
1867/*----------------------------------------------------------------
1868* hfa384x_drvr_flashdl_enable
1869*
1870* Begins the flash download state. Checks to see that we're not
1871* already in a download state and that a port isn't enabled.
1872* Sets the download state and retrieves the flash download
1873* buffer location, buffer size, and timeout length.
1874*
1875* Arguments:
1876* hw device structure
1877*
1878* Returns:
1879* 0 success
1880* >0 f/w reported error - f/w status code
1881* <0 driver reported error
1882*
1883* Side effects:
1884*
1885* Call context:
1886* process
1887----------------------------------------------------------------*/
297f06ce 1888int hfa384x_drvr_flashdl_enable(hfa384x_t *hw)
00b3ed16 1889{
21dc0f89
MM
1890 int result = 0;
1891 int i;
00b3ed16 1892
00b3ed16 1893 /* Check that a port isn't active */
21dc0f89
MM
1894 for (i = 0; i < HFA384x_PORTID_MAX; i++) {
1895 if (hw->port_enabled[i]) {
a7cf7bae 1896 pr_debug("called when port enabled.\n");
00b3ed16
GKH
1897 return -EINVAL;
1898 }
1899 }
1900
1901 /* Check that we're not already in a download state */
21dc0f89 1902 if (hw->dlstate != HFA384x_DLSTATE_DISABLED)
00b3ed16 1903 return -EINVAL;
00b3ed16
GKH
1904
1905 /* Retrieve the buffer loc&size and timeout */
46800b22 1906 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER,
3f4b4e77
AE
1907 &(hw->bufinfo), sizeof(hw->bufinfo));
1908 if (result)
00b3ed16 1909 return result;
3f4b4e77 1910
18c7f792
MM
1911 hw->bufinfo.page = le16_to_cpu(hw->bufinfo.page);
1912 hw->bufinfo.offset = le16_to_cpu(hw->bufinfo.offset);
1913 hw->bufinfo.len = le16_to_cpu(hw->bufinfo.len);
46800b22 1914 result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME,
3f4b4e77
AE
1915 &(hw->dltimeout));
1916 if (result)
00b3ed16 1917 return result;
3f4b4e77 1918
18c7f792 1919 hw->dltimeout = le16_to_cpu(hw->dltimeout);
00b3ed16 1920
a7cf7bae 1921 pr_debug("flashdl_enable\n");
00b3ed16
GKH
1922
1923 hw->dlstate = HFA384x_DLSTATE_FLASHENABLED;
8a251b55 1924
00b3ed16
GKH
1925 return result;
1926}
1927
00b3ed16
GKH
1928/*----------------------------------------------------------------
1929* hfa384x_drvr_flashdl_disable
1930*
1931* Ends the flash download state. Note that this will cause the MAC
1932* firmware to restart.
1933*
1934* Arguments:
1935* hw device structure
1936*
1937* Returns:
1938* 0 success
1939* >0 f/w reported error - f/w status code
1940* <0 driver reported error
1941*
1942* Side effects:
1943*
1944* Call context:
1945* process
1946----------------------------------------------------------------*/
297f06ce 1947int hfa384x_drvr_flashdl_disable(hfa384x_t *hw)
00b3ed16 1948{
00b3ed16 1949 /* Check that we're already in the download state */
21dc0f89 1950 if (hw->dlstate != HFA384x_DLSTATE_FLASHENABLED)
00b3ed16 1951 return -EINVAL;
00b3ed16 1952
a7cf7bae 1953 pr_debug("flashdl_enable\n");
00b3ed16
GKH
1954
1955 /* There isn't much we can do at this point, so I don't */
1956 /* bother w/ the return value */
21dc0f89 1957 hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0, 0);
00b3ed16
GKH
1958 hw->dlstate = HFA384x_DLSTATE_DISABLED;
1959
00b3ed16
GKH
1960 return 0;
1961}
1962
00b3ed16
GKH
1963/*----------------------------------------------------------------
1964* hfa384x_drvr_flashdl_write
1965*
1966* Performs a FLASH download of a chunk of data. First checks to see
1967* that we're in the FLASH download state, then sets the download
1968* mode, uses the aux functions to 1) copy the data to the flash
1969* buffer, 2) sets the download 'write flash' mode, 3) readback and
1970* compare. Lather rinse, repeat as many times an necessary to get
1971* all the given data into flash.
1972* When all data has been written using this function (possibly
1973* repeatedly), call drvr_flashdl_disable() to end the download state
1974* and restart the MAC.
1975*
1976* Arguments:
1977* hw device structure
1978* daddr Card address to write to. (host order)
1979* buf Ptr to data to write.
1980* len Length of data (host order).
1981*
1982* Returns:
1983* 0 success
1984* >0 f/w reported error - f/w status code
1985* <0 driver reported error
1986*
1987* Side effects:
1988*
1989* Call context:
1990* process
1991----------------------------------------------------------------*/
297f06ce 1992int hfa384x_drvr_flashdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len)
00b3ed16 1993{
21dc0f89
MM
1994 int result = 0;
1995 u32 dlbufaddr;
1996 int nburns;
1997 u32 burnlen;
1998 u32 burndaddr;
1999 u16 burnlo;
2000 u16 burnhi;
2001 int nwrites;
2002 u8 *writebuf;
2003 u16 writepage;
2004 u16 writeoffset;
2005 u32 writelen;
2006 int i;
2007 int j;
00b3ed16 2008
a7cf7bae 2009 pr_debug("daddr=0x%08x len=%d\n", daddr, len);
00b3ed16
GKH
2010
2011 /* Check that we're in the flash download state */
21dc0f89 2012 if (hw->dlstate != HFA384x_DLSTATE_FLASHENABLED)
00b3ed16 2013 return -EINVAL;
00b3ed16 2014
a2120136
SSA
2015 netdev_info(hw->wlandev->netdev,
2016 "Download %d bytes to flash @0x%06x\n", len, daddr);
00b3ed16
GKH
2017
2018 /* Convert to flat address for arithmetic */
2019 /* NOTE: dlbuffer RID stores the address in AUX format */
21dc0f89
MM
2020 dlbufaddr =
2021 HFA384x_ADDR_AUX_MKFLAT(hw->bufinfo.page, hw->bufinfo.offset);
75f49e07
MT
2022 pr_debug("dlbuf.page=0x%04x dlbuf.offset=0x%04x dlbufaddr=0x%08x\n",
2023 hw->bufinfo.page, hw->bufinfo.offset, dlbufaddr);
00b3ed16
GKH
2024
2025#if 0
a2120136
SSA
2026 netdev_warn(hw->wlandev->netdev,
2027 "dlbuf@0x%06lx len=%d to=%d\n", dlbufaddr,
2028 hw->bufinfo.len, hw->dltimeout);
00b3ed16
GKH
2029#endif
2030 /* Calculations to determine how many fills of the dlbuffer to do
2031 * and how many USB wmemreq's to do for each fill. At this point
2032 * in time, the dlbuffer size and the wmemreq size are the same.
2033 * Therefore, nwrites should always be 1. The extra complexity
2034 * here is a hedge against future changes.
2035 */
2036
2037 /* Figure out how many times to do the flash programming */
2038 nburns = len / hw->bufinfo.len;
2039 nburns += (len % hw->bufinfo.len) ? 1 : 0;
2040
2041 /* For each flash program cycle, how many USB wmemreq's are needed? */
2042 nwrites = hw->bufinfo.len / HFA384x_USB_RWMEM_MAXLEN;
2043 nwrites += (hw->bufinfo.len % HFA384x_USB_RWMEM_MAXLEN) ? 1 : 0;
2044
2045 /* For each burn */
21dc0f89 2046 for (i = 0; i < nburns; i++) {
00b3ed16
GKH
2047 /* Get the dest address and len */
2048 burnlen = (len - (hw->bufinfo.len * i)) > hw->bufinfo.len ?
21dc0f89 2049 hw->bufinfo.len : (len - (hw->bufinfo.len * i));
00b3ed16
GKH
2050 burndaddr = daddr + (hw->bufinfo.len * i);
2051 burnlo = HFA384x_ADDR_CMD_MKOFF(burndaddr);
2052 burnhi = HFA384x_ADDR_CMD_MKPAGE(burndaddr);
2053
263b8bb9 2054 netdev_info(hw->wlandev->netdev, "Writing %d bytes to flash @0x%06x\n",
3f2d6564 2055 burnlen, burndaddr);
00b3ed16
GKH
2056
2057 /* Set the download mode */
2058 result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_NV,
21dc0f89
MM
2059 burnlo, burnhi, burnlen);
2060 if (result) {
a2120136
SSA
2061 netdev_err(hw->wlandev->netdev,
2062 "download(NV,lo=%x,hi=%x,len=%x) cmd failed, result=%d. Aborting d/l\n",
2063 burnlo, burnhi, burnlen, result);
00b3ed16
GKH
2064 goto exit_proc;
2065 }
2066
2067 /* copy the data to the flash download buffer */
21dc0f89 2068 for (j = 0; j < nwrites; j++) {
00b3ed16 2069 writebuf = buf +
21dc0f89
MM
2070 (i * hw->bufinfo.len) +
2071 (j * HFA384x_USB_RWMEM_MAXLEN);
2072
2073 writepage = HFA384x_ADDR_CMD_MKPAGE(dlbufaddr +
631c8dec
EH
2074 (j * HFA384x_USB_RWMEM_MAXLEN));
2075 writeoffset = HFA384x_ADDR_CMD_MKOFF(dlbufaddr +
2076 (j * HFA384x_USB_RWMEM_MAXLEN));
21dc0f89
MM
2077
2078 writelen = burnlen - (j * HFA384x_USB_RWMEM_MAXLEN);
2079 writelen = writelen > HFA384x_USB_RWMEM_MAXLEN ?
2080 HFA384x_USB_RWMEM_MAXLEN : writelen;
2081
2082 result = hfa384x_dowmem_wait(hw,
2083 writepage,
2084 writeoffset,
2085 writebuf, writelen);
00b3ed16
GKH
2086 }
2087
2088 /* set the download 'write flash' mode */
2089 result = hfa384x_cmd_download(hw,
21dc0f89
MM
2090 HFA384x_PROGMODE_NVWRITE,
2091 0, 0, 0);
2092 if (result) {
263b8bb9 2093 netdev_err(hw->wlandev->netdev,
3f2d6564
SSA
2094 "download(NVWRITE,lo=%x,hi=%x,len=%x) cmd failed, result=%d. Aborting d/l\n",
2095 burnlo, burnhi, burnlen, result);
00b3ed16
GKH
2096 goto exit_proc;
2097 }
2098
2099 /* TODO: We really should do a readback and compare. */
2100 }
2101
2102exit_proc:
2103
2104 /* Leave the firmware in the 'post-prog' mode. flashdl_disable will */
2105 /* actually disable programming mode. Remember, that will cause the */
2106 /* the firmware to effectively reset itself. */
2107
00b3ed16
GKH
2108 return result;
2109}
2110
00b3ed16
GKH
2111/*----------------------------------------------------------------
2112* hfa384x_drvr_getconfig
2113*
2114* Performs the sequence necessary to read a config/info item.
2115*
2116* Arguments:
2117* hw device structure
2118* rid config/info record id (host order)
2119* buf host side record buffer. Upon return it will
2120* contain the body portion of the record (minus the
2121* RID and len).
2122* len buffer length (in bytes, should match record length)
2123*
2124* Returns:
2125* 0 success
2126* >0 f/w reported error - f/w status code
2127* <0 driver reported error
631c8dec 2128* -ENODATA length mismatch between argument and retrieved
00b3ed16
GKH
2129* record.
2130*
2131* Side effects:
2132*
2133* Call context:
2134* process
2135----------------------------------------------------------------*/
297f06ce 2136int hfa384x_drvr_getconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len)
00b3ed16 2137{
102db1fc 2138 return hfa384x_dorrid_wait(hw, rid, buf, len);
00b3ed16
GKH
2139}
2140
2141/*----------------------------------------------------------------
2142 * hfa384x_drvr_getconfig_async
2143 *
2144 * Performs the sequence necessary to perform an async read of
2145 * of a config/info item.
2146 *
2147 * Arguments:
2148 * hw device structure
2149 * rid config/info record id (host order)
2150 * buf host side record buffer. Upon return it will
2151 * contain the body portion of the record (minus the
2152 * RID and len).
2153 * len buffer length (in bytes, should match record length)
2154 * cbfn caller supplied callback, called when the command
2155 * is done (successful or not).
2156 * cbfndata pointer to some caller supplied data that will be
2157 * passed in as an argument to the cbfn.
2158 *
2159 * Returns:
2160 * nothing the cbfn gets a status argument identifying if
2161 * any errors occur.
2162 * Side effects:
2163 * Queues an hfa384x_usbcmd_t for subsequent execution.
2164 *
2165 * Call context:
2166 * Any
2167 ----------------------------------------------------------------*/
2168int
297f06ce 2169hfa384x_drvr_getconfig_async(hfa384x_t *hw,
21dc0f89 2170 u16 rid, ctlx_usercb_t usercb, void *usercb_data)
00b3ed16 2171{
21dc0f89
MM
2172 return hfa384x_dorrid_async(hw, rid, NULL, 0,
2173 hfa384x_cb_rrid, usercb, usercb_data);
00b3ed16
GKH
2174}
2175
2176/*----------------------------------------------------------------
2177 * hfa384x_drvr_setconfig_async
2178 *
2179 * Performs the sequence necessary to write a config/info item.
2180 *
2181 * Arguments:
2182 * hw device structure
2183 * rid config/info record id (in host order)
2184 * buf host side record buffer
2185 * len buffer length (in bytes)
2186 * usercb completion callback
2187 * usercb_data completion callback argument
2188 *
2189 * Returns:
2190 * 0 success
2191 * >0 f/w reported error - f/w status code
2192 * <0 driver reported error
2193 *
2194 * Side effects:
2195 *
2196 * Call context:
2197 * process
2198 ----------------------------------------------------------------*/
2199int
297f06ce 2200hfa384x_drvr_setconfig_async(hfa384x_t *hw,
21dc0f89
MM
2201 u16 rid,
2202 void *buf,
2203 u16 len, ctlx_usercb_t usercb, void *usercb_data)
00b3ed16
GKH
2204{
2205 return hfa384x_dowrid_async(hw, rid, buf, len,
2206 hfa384x_cb_status, usercb, usercb_data);
2207}
2208
00b3ed16
GKH
2209/*----------------------------------------------------------------
2210* hfa384x_drvr_ramdl_disable
2211*
2212* Ends the ram download state.
2213*
2214* Arguments:
2215* hw device structure
2216*
2217* Returns:
2218* 0 success
2219* >0 f/w reported error - f/w status code
2220* <0 driver reported error
2221*
2222* Side effects:
2223*
2224* Call context:
2225* process
2226----------------------------------------------------------------*/
297f06ce 2227int hfa384x_drvr_ramdl_disable(hfa384x_t *hw)
00b3ed16 2228{
00b3ed16 2229 /* Check that we're already in the download state */
21dc0f89 2230 if (hw->dlstate != HFA384x_DLSTATE_RAMENABLED)
00b3ed16 2231 return -EINVAL;
00b3ed16 2232
a7cf7bae 2233 pr_debug("ramdl_disable()\n");
00b3ed16
GKH
2234
2235 /* There isn't much we can do at this point, so I don't */
2236 /* bother w/ the return value */
21dc0f89 2237 hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0, 0);
00b3ed16
GKH
2238 hw->dlstate = HFA384x_DLSTATE_DISABLED;
2239
00b3ed16
GKH
2240 return 0;
2241}
2242
00b3ed16
GKH
2243/*----------------------------------------------------------------
2244* hfa384x_drvr_ramdl_enable
2245*
2246* Begins the ram download state. Checks to see that we're not
2247* already in a download state and that a port isn't enabled.
2248* Sets the download state and calls cmd_download with the
2249* ENABLE_VOLATILE subcommand and the exeaddr argument.
2250*
2251* Arguments:
2252* hw device structure
2253* exeaddr the card execution address that will be
2254* jumped to when ramdl_disable() is called
2255* (host order).
2256*
2257* Returns:
2258* 0 success
2259* >0 f/w reported error - f/w status code
2260* <0 driver reported error
2261*
2262* Side effects:
2263*
2264* Call context:
2265* process
2266----------------------------------------------------------------*/
297f06ce 2267int hfa384x_drvr_ramdl_enable(hfa384x_t *hw, u32 exeaddr)
00b3ed16 2268{
21dc0f89
MM
2269 int result = 0;
2270 u16 lowaddr;
2271 u16 hiaddr;
2272 int i;
8a251b55 2273
00b3ed16 2274 /* Check that a port isn't active */
21dc0f89
MM
2275 for (i = 0; i < HFA384x_PORTID_MAX; i++) {
2276 if (hw->port_enabled[i]) {
263b8bb9 2277 netdev_err(hw->wlandev->netdev,
3f2d6564 2278 "Can't download with a macport enabled.\n");
00b3ed16
GKH
2279 return -EINVAL;
2280 }
2281 }
2282
2283 /* Check that we're not already in a download state */
21dc0f89 2284 if (hw->dlstate != HFA384x_DLSTATE_DISABLED) {
263b8bb9 2285 netdev_err(hw->wlandev->netdev, "Download state not disabled.\n");
00b3ed16
GKH
2286 return -EINVAL;
2287 }
2288
a7cf7bae 2289 pr_debug("ramdl_enable, exeaddr=0x%08x\n", exeaddr);
00b3ed16
GKH
2290
2291 /* Call the download(1,addr) function */
2292 lowaddr = HFA384x_ADDR_CMD_MKOFF(exeaddr);
21dc0f89 2293 hiaddr = HFA384x_ADDR_CMD_MKPAGE(exeaddr);
00b3ed16
GKH
2294
2295 result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_RAM,
21dc0f89 2296 lowaddr, hiaddr, 0);
00b3ed16 2297
21dc0f89 2298 if (result == 0) {
00b3ed16
GKH
2299 /* Set the download state */
2300 hw->dlstate = HFA384x_DLSTATE_RAMENABLED;
2301 } else {
75f49e07
MT
2302 pr_debug("cmd_download(0x%04x, 0x%04x) failed, result=%d.\n",
2303 lowaddr, hiaddr, result);
00b3ed16
GKH
2304 }
2305
00b3ed16
GKH
2306 return result;
2307}
2308
00b3ed16
GKH
2309/*----------------------------------------------------------------
2310* hfa384x_drvr_ramdl_write
2311*
2312* Performs a RAM download of a chunk of data. First checks to see
2313* that we're in the RAM download state, then uses the [read|write]mem USB
2314* commands to 1) copy the data, 2) readback and compare. The download
2315* state is unaffected. When all data has been written using
2316* this function, call drvr_ramdl_disable() to end the download state
2317* and restart the MAC.
2318*
2319* Arguments:
2320* hw device structure
2321* daddr Card address to write to. (host order)
2322* buf Ptr to data to write.
2323* len Length of data (host order).
2324*
2325* Returns:
2326* 0 success
2327* >0 f/w reported error - f/w status code
2328* <0 driver reported error
2329*
2330* Side effects:
2331*
2332* Call context:
2333* process
2334----------------------------------------------------------------*/
297f06ce 2335int hfa384x_drvr_ramdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len)
00b3ed16 2336{
21dc0f89
MM
2337 int result = 0;
2338 int nwrites;
2339 u8 *data = buf;
2340 int i;
2341 u32 curraddr;
2342 u16 currpage;
2343 u16 curroffset;
2344 u16 currlen;
8a251b55 2345
00b3ed16 2346 /* Check that we're in the ram download state */
21dc0f89 2347 if (hw->dlstate != HFA384x_DLSTATE_RAMENABLED)
00b3ed16 2348 return -EINVAL;
00b3ed16 2349
a2120136
SSA
2350 netdev_info(hw->wlandev->netdev, "Writing %d bytes to ram @0x%06x\n",
2351 len, daddr);
00b3ed16
GKH
2352
2353 /* How many dowmem calls? */
2354 nwrites = len / HFA384x_USB_RWMEM_MAXLEN;
2355 nwrites += len % HFA384x_USB_RWMEM_MAXLEN ? 1 : 0;
2356
2357 /* Do blocking wmem's */
21dc0f89 2358 for (i = 0; i < nwrites; i++) {
00b3ed16
GKH
2359 /* make address args */
2360 curraddr = daddr + (i * HFA384x_USB_RWMEM_MAXLEN);
2361 currpage = HFA384x_ADDR_CMD_MKPAGE(curraddr);
2362 curroffset = HFA384x_ADDR_CMD_MKOFF(curraddr);
2363 currlen = len - (i * HFA384x_USB_RWMEM_MAXLEN);
21dc0f89 2364 if (currlen > HFA384x_USB_RWMEM_MAXLEN)
00b3ed16 2365 currlen = HFA384x_USB_RWMEM_MAXLEN;
00b3ed16 2366
21dc0f89
MM
2367 /* Do blocking ctlx */
2368 result = hfa384x_dowmem_wait(hw,
2369 currpage,
2370 curroffset,
2371 data +
2372 (i * HFA384x_USB_RWMEM_MAXLEN),
2373 currlen);
00b3ed16 2374
21dc0f89
MM
2375 if (result)
2376 break;
00b3ed16
GKH
2377
2378 /* TODO: We really should have a readback. */
2379 }
2380
00b3ed16
GKH
2381 return result;
2382}
2383
00b3ed16
GKH
2384/*----------------------------------------------------------------
2385* hfa384x_drvr_readpda
2386*
2387* Performs the sequence to read the PDA space. Note there is no
2388* drvr_writepda() function. Writing a PDA is
2389* generally implemented by a calling component via calls to
2390* cmd_download and writing to the flash download buffer via the
2391* aux regs.
2392*
2393* Arguments:
2394* hw device structure
2395* buf buffer to store PDA in
2396* len buffer length
2397*
2398* Returns:
2399* 0 success
2400* >0 f/w reported error - f/w status code
2401* <0 driver reported error
3ac49a1c 2402* -ETIMEDOUT timout waiting for the cmd regs to become
00b3ed16
GKH
2403* available, or waiting for the control reg
2404* to indicate the Aux port is enabled.
2405* -ENODATA the buffer does NOT contain a valid PDA.
2406* Either the card PDA is bad, or the auxdata
2407* reads are giving us garbage.
2408
2409*
2410* Side effects:
2411*
2412* Call context:
2413* process or non-card interrupt.
2414----------------------------------------------------------------*/
297f06ce 2415int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, unsigned int len)
00b3ed16 2416{
21dc0f89
MM
2417 int result = 0;
2418 u16 *pda = buf;
2419 int pdaok = 0;
2420 int morepdrs = 1;
2421 int currpdr = 0; /* word offset of the current pdr */
2422 size_t i;
2423 u16 pdrlen; /* pdr length in bytes, host order */
2424 u16 pdrcode; /* pdr code, host order */
2425 u16 currpage;
2426 u16 curroffset;
00b3ed16 2427 struct pdaloc {
21dc0f89
MM
2428 u32 cardaddr;
2429 u16 auxctl;
2430 } pdaloc[] = {
2431 {
2432 HFA3842_PDA_BASE, 0}, {
2433 HFA3841_PDA_BASE, 0}, {
2434 HFA3841_PDA_BOGUS_BASE, 0}
00b3ed16
GKH
2435 };
2436
00b3ed16 2437 /* Read the pda from each known address. */
21dc0f89 2438 for (i = 0; i < ARRAY_SIZE(pdaloc); i++) {
00b3ed16
GKH
2439 /* Make address */
2440 currpage = HFA384x_ADDR_CMD_MKPAGE(pdaloc[i].cardaddr);
2441 curroffset = HFA384x_ADDR_CMD_MKOFF(pdaloc[i].cardaddr);
2442
631c8dec
EH
2443 /* units of bytes */
2444 result = hfa384x_dormem_wait(hw, currpage, curroffset, buf,
2445 len);
00b3ed16
GKH
2446
2447 if (result) {
263b8bb9 2448 netdev_warn(hw->wlandev->netdev,
3f2d6564
SSA
2449 "Read from index %zd failed, continuing\n",
2450 i);
00b3ed16
GKH
2451 continue;
2452 }
2453
2454 /* Test for garbage */
2455 pdaok = 1; /* initially assume good */
2456 morepdrs = 1;
21dc0f89 2457 while (pdaok && morepdrs) {
18c7f792
MM
2458 pdrlen = le16_to_cpu(pda[currpdr]) * 2;
2459 pdrcode = le16_to_cpu(pda[currpdr + 1]);
00b3ed16 2460 /* Test the record length */
21dc0f89 2461 if (pdrlen > HFA384x_PDR_LEN_MAX || pdrlen == 0) {
a2120136
SSA
2462 netdev_err(hw->wlandev->netdev,
2463 "pdrlen invalid=%d\n", pdrlen);
00b3ed16
GKH
2464 pdaok = 0;
2465 break;
2466 }
2467 /* Test the code */
21dc0f89 2468 if (!hfa384x_isgood_pdrcode(pdrcode)) {
263b8bb9 2469 netdev_err(hw->wlandev->netdev, "pdrcode invalid=%d\n",
3f2d6564 2470 pdrcode);
00b3ed16
GKH
2471 pdaok = 0;
2472 break;
2473 }
2474 /* Test for completion */
21dc0f89 2475 if (pdrcode == HFA384x_PDR_END_OF_PDA)
00b3ed16 2476 morepdrs = 0;
00b3ed16
GKH
2477
2478 /* Move to the next pdr (if necessary) */
21dc0f89 2479 if (morepdrs) {
00b3ed16 2480 /* note the access to pda[], need words here */
18c7f792 2481 currpdr += le16_to_cpu(pda[currpdr]) + 1;
00b3ed16
GKH
2482 }
2483 }
21dc0f89 2484 if (pdaok) {
263b8bb9 2485 netdev_info(hw->wlandev->netdev,
3f2d6564
SSA
2486 "PDA Read from 0x%08x in %s space.\n",
2487 pdaloc[i].cardaddr,
2488 pdaloc[i].auxctl == 0 ? "EXTDS" :
2489 pdaloc[i].auxctl == 1 ? "NV" :
2490 pdaloc[i].auxctl == 2 ? "PHY" :
2491 pdaloc[i].auxctl == 3 ? "ICSRAM" :
2492 "<bogus auxctl>");
00b3ed16
GKH
2493 break;
2494 }
2495 }
2496 result = pdaok ? 0 : -ENODATA;
2497
21dc0f89 2498 if (result)
a7cf7bae 2499 pr_debug("Failure: pda is not okay\n");
00b3ed16 2500
00b3ed16
GKH
2501 return result;
2502}
2503
00b3ed16
GKH
2504/*----------------------------------------------------------------
2505* hfa384x_drvr_setconfig
2506*
2507* Performs the sequence necessary to write a config/info item.
2508*
2509* Arguments:
2510* hw device structure
2511* rid config/info record id (in host order)
2512* buf host side record buffer
2513* len buffer length (in bytes)
2514*
2515* Returns:
2516* 0 success
2517* >0 f/w reported error - f/w status code
2518* <0 driver reported error
2519*
2520* Side effects:
2521*
2522* Call context:
2523* process
2524----------------------------------------------------------------*/
297f06ce 2525int hfa384x_drvr_setconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len)
00b3ed16
GKH
2526{
2527 return hfa384x_dowrid_wait(hw, rid, buf, len);
2528}
2529
2530/*----------------------------------------------------------------
2531* hfa384x_drvr_start
2532*
2533* Issues the MAC initialize command, sets up some data structures,
2534* and enables the interrupts. After this function completes, the
2535* low-level stuff should be ready for any/all commands.
2536*
2537* Arguments:
2538* hw device structure
2539* Returns:
2540* 0 success
2541* >0 f/w reported error - f/w status code
2542* <0 driver reported error
2543*
2544* Side effects:
2545*
2546* Call context:
2547* process
2548----------------------------------------------------------------*/
7b7e7e84 2549
297f06ce 2550int hfa384x_drvr_start(hfa384x_t *hw)
00b3ed16 2551{
21dc0f89
MM
2552 int result, result1, result2;
2553 u16 status;
00b3ed16
GKH
2554
2555 might_sleep();
2556
7b7e7e84
RK
2557 /* Clear endpoint stalls - but only do this if the endpoint
2558 * is showing a stall status. Some prism2 cards seem to behave
2559 * badly if a clear_halt is called when the endpoint is already
2560 * ok
2561 */
21dc0f89
MM
2562 result =
2563 usb_get_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_in, &status);
7b7e7e84 2564 if (result < 0) {
263b8bb9 2565 netdev_err(hw->wlandev->netdev, "Cannot get bulk in endpoint status.\n");
7b7e7e84
RK
2566 goto done;
2567 }
21dc0f89 2568 if ((status == 1) && usb_clear_halt(hw->usb, hw->endp_in))
263b8bb9 2569 netdev_err(hw->wlandev->netdev, "Failed to reset bulk in endpoint.\n");
00b3ed16 2570
21dc0f89
MM
2571 result =
2572 usb_get_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_out, &status);
7b7e7e84 2573 if (result < 0) {
263b8bb9 2574 netdev_err(hw->wlandev->netdev, "Cannot get bulk out endpoint status.\n");
7b7e7e84
RK
2575 goto done;
2576 }
21dc0f89 2577 if ((status == 1) && usb_clear_halt(hw->usb, hw->endp_out))
263b8bb9 2578 netdev_err(hw->wlandev->netdev, "Failed to reset bulk out endpoint.\n");
00b3ed16
GKH
2579
2580 /* Synchronous unlink, in case we're trying to restart the driver */
2581 usb_kill_urb(&hw->rx_urb);
2582
2583 /* Post the IN urb */
2584 result = submit_rx_urb(hw, GFP_KERNEL);
2585 if (result != 0) {
263b8bb9 2586 netdev_err(hw->wlandev->netdev,
3f2d6564
SSA
2587 "Fatal, failed to submit RX URB, result=%d\n",
2588 result);
00b3ed16
GKH
2589 goto done;
2590 }
2591
7b7e7e84
RK
2592 /* Call initialize twice, with a 1 second sleep in between.
2593 * This is a nasty work-around since many prism2 cards seem to
2594 * need time to settle after an init from cold. The second
2595 * call to initialize in theory is not necessary - but we call
2596 * it anyway as a double insurance policy:
2597 * 1) If the first init should fail, the second may well succeed
2598 * and the card can still be used
2599 * 2) It helps ensures all is well with the card after the first
2600 * init and settle time.
2601 */
2602 result1 = hfa384x_cmd_initialize(hw);
2603 msleep(1000);
2604 result = result2 = hfa384x_cmd_initialize(hw);
2605 if (result1 != 0) {
2606 if (result2 != 0) {
263b8bb9 2607 netdev_err(hw->wlandev->netdev,
3f2d6564
SSA
2608 "cmd_initialize() failed on two attempts, results %d and %d\n",
2609 result1, result2);
7b7e7e84
RK
2610 usb_kill_urb(&hw->rx_urb);
2611 goto done;
2612 } else {
75f49e07
MT
2613 pr_debug("First cmd_initialize() failed (result %d),\n",
2614 result1);
4ffab688 2615 pr_debug("but second attempt succeeded. All should be ok\n");
7b7e7e84
RK
2616 }
2617 } else if (result2 != 0) {
263b8bb9 2618 netdev_warn(hw->wlandev->netdev, "First cmd_initialize() succeeded, but second attempt failed (result=%d)\n",
3f2d6564 2619 result2);
263b8bb9 2620 netdev_warn(hw->wlandev->netdev,
3f2d6564 2621 "Most likely the card will be functional\n");
21dc0f89 2622 goto done;
00b3ed16
GKH
2623 }
2624
2625 hw->state = HFA384x_STATE_RUNNING;
2626
2627done:
00b3ed16
GKH
2628 return result;
2629}
2630
00b3ed16
GKH
2631/*----------------------------------------------------------------
2632* hfa384x_drvr_stop
2633*
2634* Shuts down the MAC to the point where it is safe to unload the
2635* driver. Any subsystem that may be holding a data or function
2636* ptr into the driver must be cleared/deinitialized.
2637*
2638* Arguments:
2639* hw device structure
2640* Returns:
2641* 0 success
2642* >0 f/w reported error - f/w status code
2643* <0 driver reported error
2644*
2645* Side effects:
2646*
2647* Call context:
2648* process
2649----------------------------------------------------------------*/
297f06ce 2650int hfa384x_drvr_stop(hfa384x_t *hw)
00b3ed16 2651{
21dc0f89
MM
2652 int result = 0;
2653 int i;
00b3ed16
GKH
2654
2655 might_sleep();
2656
2657 /* There's no need for spinlocks here. The USB "disconnect"
2658 * function sets this "removed" flag and then calls us.
2659 */
21dc0f89 2660 if (!hw->wlandev->hwremoved) {
00b3ed16
GKH
2661 /* Call initialize to leave the MAC in its 'reset' state */
2662 hfa384x_cmd_initialize(hw);
2663
2664 /* Cancel the rxurb */
2665 usb_kill_urb(&hw->rx_urb);
2666 }
2667
2668 hw->link_status = HFA384x_LINK_NOTCONNECTED;
2669 hw->state = HFA384x_STATE_INIT;
2670
2671 del_timer_sync(&hw->commsqual_timer);
2672
2673 /* Clear all the port status */
21dc0f89 2674 for (i = 0; i < HFA384x_NUMPORTS_MAX; i++)
00b3ed16 2675 hw->port_enabled[i] = 0;
00b3ed16 2676
00b3ed16
GKH
2677 return result;
2678}
2679
2680/*----------------------------------------------------------------
2681* hfa384x_drvr_txframe
2682*
2683* Takes a frame from prism2sta and queues it for transmission.
2684*
2685* Arguments:
2686* hw device structure
2687* skb packet buffer struct. Contains an 802.11
2688* data frame.
2689* p80211_hdr points to the 802.11 header for the packet.
2690* Returns:
2691* 0 Success and more buffs available
2692* 1 Success but no more buffs
2693* 2 Allocation failure
2694* 4 Buffer full or queue busy
2695*
2696* Side effects:
2697*
2698* Call context:
2699* interrupt
2700----------------------------------------------------------------*/
297f06ce 2701int hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb,
93df38e5 2702 union p80211_hdr *p80211_hdr,
51e4896a 2703 struct p80211_metawep *p80211_wep)
00b3ed16 2704{
21dc0f89
MM
2705 int usbpktlen = sizeof(hfa384x_tx_frame_t);
2706 int result;
2707 int ret;
2708 char *ptr;
00b3ed16 2709
00b3ed16 2710 if (hw->tx_urb.status == -EINPROGRESS) {
263b8bb9 2711 netdev_warn(hw->wlandev->netdev, "TX URB already in use\n");
00b3ed16
GKH
2712 result = 3;
2713 goto exit;
2714 }
2715
2716 /* Build Tx frame structure */
2717 /* Set up the control field */
2718 memset(&hw->txbuff.txfrm.desc, 0, sizeof(hw->txbuff.txfrm.desc));
2719
2720 /* Setup the usb type field */
18c7f792 2721 hw->txbuff.type = cpu_to_le16(HFA384x_USB_TXFRM);
00b3ed16
GKH
2722
2723 /* Set up the sw_support field to identify this frame */
2724 hw->txbuff.txfrm.desc.sw_support = 0x0123;
2725
2726/* Tx complete and Tx exception disable per dleach. Might be causing
2727 * buf depletion
2728 */
21dc0f89 2729/* #define DOEXC SLP -- doboth breaks horribly under load, doexc less so. */
00b3ed16
GKH
2730#if defined(DOBOTH)
2731 hw->txbuff.txfrm.desc.tx_control =
21dc0f89
MM
2732 HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
2733 HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(1);
00b3ed16
GKH
2734#elif defined(DOEXC)
2735 hw->txbuff.txfrm.desc.tx_control =
21dc0f89
MM
2736 HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
2737 HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(0);
00b3ed16
GKH
2738#else
2739 hw->txbuff.txfrm.desc.tx_control =
21dc0f89
MM
2740 HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
2741 HFA384x_TX_TXEX_SET(0) | HFA384x_TX_TXOK_SET(0);
00b3ed16
GKH
2742#endif
2743 hw->txbuff.txfrm.desc.tx_control =
18c7f792 2744 cpu_to_le16(hw->txbuff.txfrm.desc.tx_control);
00b3ed16
GKH
2745
2746 /* copy the header over to the txdesc */
21dc0f89 2747 memcpy(&(hw->txbuff.txfrm.desc.frame_control), p80211_hdr,
93df38e5 2748 sizeof(union p80211_hdr));
00b3ed16
GKH
2749
2750 /* if we're using host WEP, increase size by IV+ICV */
2751 if (p80211_wep->data) {
18c7f792 2752 hw->txbuff.txfrm.desc.data_len = cpu_to_le16(skb->len + 8);
21dc0f89 2753 usbpktlen += 8;
00b3ed16 2754 } else {
18c7f792 2755 hw->txbuff.txfrm.desc.data_len = cpu_to_le16(skb->len);
00b3ed16
GKH
2756 }
2757
2758 usbpktlen += skb->len;
2759
2760 /* copy over the WEP IV if we are using host WEP */
2761 ptr = hw->txbuff.txfrm.data;
2762 if (p80211_wep->data) {
2763 memcpy(ptr, p80211_wep->iv, sizeof(p80211_wep->iv));
21dc0f89 2764 ptr += sizeof(p80211_wep->iv);
00b3ed16
GKH
2765 memcpy(ptr, p80211_wep->data, skb->len);
2766 } else {
2767 memcpy(ptr, skb->data, skb->len);
2768 }
2769 /* copy over the packet data */
21dc0f89 2770 ptr += skb->len;
00b3ed16
GKH
2771
2772 /* copy over the WEP ICV if we are using host WEP */
21dc0f89 2773 if (p80211_wep->data)
00b3ed16 2774 memcpy(ptr, p80211_wep->icv, sizeof(p80211_wep->icv));
00b3ed16
GKH
2775
2776 /* Send the USB packet */
21dc0f89
MM
2777 usb_fill_bulk_urb(&(hw->tx_urb), hw->usb,
2778 hw->endp_out,
2779 &(hw->txbuff), ROUNDUP64(usbpktlen),
2780 hfa384x_usbout_callback, hw->wlandev);
00b3ed16
GKH
2781 hw->tx_urb.transfer_flags |= USB_QUEUE_BULK;
2782
2783 result = 1;
2784 ret = submit_tx_urb(hw, &hw->tx_urb, GFP_ATOMIC);
21dc0f89 2785 if (ret != 0) {
a2120136
SSA
2786 netdev_err(hw->wlandev->netdev,
2787 "submit_tx_urb() failed, error=%d\n", ret);
00b3ed16
GKH
2788 result = 3;
2789 }
2790
21dc0f89 2791exit:
00b3ed16
GKH
2792 return result;
2793}
2794
297f06ce 2795void hfa384x_tx_timeout(wlandevice_t *wlandev)
00b3ed16 2796{
21dc0f89 2797 hfa384x_t *hw = wlandev->priv;
00b3ed16
GKH
2798 unsigned long flags;
2799
00b3ed16
GKH
2800 spin_lock_irqsave(&hw->ctlxq.lock, flags);
2801
59457897
DC
2802 if (!hw->wlandev->hwremoved) {
2803 int sched;
2804
2805 sched = !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags);
2806 sched |= !test_and_set_bit(WORK_RX_HALT, &hw->usb_flags);
2807 if (sched)
2808 schedule_work(&hw->usb_work);
00b3ed16
GKH
2809 }
2810
2811 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
00b3ed16
GKH
2812}
2813
2814/*----------------------------------------------------------------
2815* hfa384x_usbctlx_reaper_task
2816*
2817* Tasklet to delete dead CTLX objects
2818*
2819* Arguments:
2820* data ptr to a hfa384x_t
2821*
2822* Returns:
2823*
2824* Call context:
2825* Interrupt
2826----------------------------------------------------------------*/
2827static void hfa384x_usbctlx_reaper_task(unsigned long data)
2828{
21dc0f89 2829 hfa384x_t *hw = (hfa384x_t *) data;
00b3ed16
GKH
2830 struct list_head *entry;
2831 struct list_head *temp;
21dc0f89 2832 unsigned long flags;
00b3ed16 2833
00b3ed16
GKH
2834 spin_lock_irqsave(&hw->ctlxq.lock, flags);
2835
2836 /* This list is guaranteed to be empty if someone
2837 * has unplugged the adapter.
2838 */
2839 list_for_each_safe(entry, temp, &hw->ctlxq.reapable) {
21dc0f89 2840 hfa384x_usbctlx_t *ctlx;
00b3ed16
GKH
2841
2842 ctlx = list_entry(entry, hfa384x_usbctlx_t, list);
2843 list_del(&ctlx->list);
2844 kfree(ctlx);
2845 }
2846
2847 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
2848
00b3ed16
GKH
2849}
2850
2851/*----------------------------------------------------------------
2852* hfa384x_usbctlx_completion_task
2853*
2854* Tasklet to call completion handlers for returned CTLXs
2855*
2856* Arguments:
2857* data ptr to hfa384x_t
2858*
2859* Returns:
2860* Nothing
2861*
2862* Call context:
2863* Interrupt
2864----------------------------------------------------------------*/
2865static void hfa384x_usbctlx_completion_task(unsigned long data)
2866{
21dc0f89 2867 hfa384x_t *hw = (hfa384x_t *) data;
00b3ed16
GKH
2868 struct list_head *entry;
2869 struct list_head *temp;
2870 unsigned long flags;
2871
2872 int reap = 0;
2873
00b3ed16
GKH
2874 spin_lock_irqsave(&hw->ctlxq.lock, flags);
2875
2876 /* This list is guaranteed to be empty if someone
2877 * has unplugged the adapter ...
2878 */
2879 list_for_each_safe(entry, temp, &hw->ctlxq.completing) {
2880 hfa384x_usbctlx_t *ctlx;
2881
2882 ctlx = list_entry(entry, hfa384x_usbctlx_t, list);
2883
2884 /* Call the completion function that this
2885 * command was assigned, assuming it has one.
2886 */
21dc0f89 2887 if (ctlx->cmdcb != NULL) {
00b3ed16
GKH
2888 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
2889 ctlx->cmdcb(hw, ctlx);
2890 spin_lock_irqsave(&hw->ctlxq.lock, flags);
2891
2892 /* Make sure we don't try and complete
2893 * this CTLX more than once!
2894 */
2895 ctlx->cmdcb = NULL;
2896
2897 /* Did someone yank the adapter out
2898 * while our list was (briefly) unlocked?
2899 */
21dc0f89 2900 if (hw->wlandev->hwremoved) {
00b3ed16
GKH
2901 reap = 0;
2902 break;
2903 }
2904 }
2905
2906 /*
2907 * "Reapable" CTLXs are ones which don't have any
2908 * threads waiting for them to die. Hence they must
2909 * be delivered to The Reaper!
2910 */
21dc0f89 2911 if (ctlx->reapable) {
00b3ed16
GKH
2912 /* Move the CTLX off the "completing" list (hopefully)
2913 * on to the "reapable" list where the reaper task
2914 * can find it. And "reapable" means that this CTLX
2915 * isn't sitting on a wait-queue somewhere.
2916 */
2917 list_move_tail(&ctlx->list, &hw->ctlxq.reapable);
2918 reap = 1;
2919 }
2920
2921 complete(&ctlx->done);
2922 }
2923 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
2924
2925 if (reap)
2926 tasklet_schedule(&hw->reaper_bh);
00b3ed16
GKH
2927}
2928
2929/*----------------------------------------------------------------
2930* unlocked_usbctlx_cancel_async
2931*
2932* Mark the CTLX dead asynchronously, and ensure that the
2933* next command on the queue is run afterwards.
2934*
2935* Arguments:
2936* hw ptr to the hfa384x_t structure
2937* ctlx ptr to a CTLX structure
2938*
2939* Returns:
2940* 0 the CTLX's URB is inactive
2941* -EINPROGRESS the URB is currently being unlinked
2942*
2943* Call context:
2944* Either process or interrupt, but presumably interrupt
2945----------------------------------------------------------------*/
297f06ce
MT
2946static int unlocked_usbctlx_cancel_async(hfa384x_t *hw,
2947 hfa384x_usbctlx_t *ctlx)
00b3ed16
GKH
2948{
2949 int ret;
2950
00b3ed16
GKH
2951 /*
2952 * Try to delete the URB containing our request packet.
2953 * If we succeed, then its completion handler will be
2954 * called with a status of -ECONNRESET.
2955 */
2956 hw->ctlx_urb.transfer_flags |= URB_ASYNC_UNLINK;
2957 ret = usb_unlink_urb(&hw->ctlx_urb);
2958
2959 if (ret != -EINPROGRESS) {
2960 /*
2961 * The OUT URB had either already completed
2962 * or was still in the pending queue, so the
2963 * URB's completion function will not be called.
2964 * We will have to complete the CTLX ourselves.
2965 */
2966 ctlx->state = CTLX_REQ_FAILED;
2967 unlocked_usbctlx_complete(hw, ctlx);
2968 ret = 0;
2969 }
2970
00b3ed16
GKH
2971 return ret;
2972}
2973
2974/*----------------------------------------------------------------
2975* unlocked_usbctlx_complete
2976*
2977* A CTLX has completed. It may have been successful, it may not
2978* have been. At this point, the CTLX should be quiescent. The URBs
2979* aren't active and the timers should have been stopped.
2980*
2981* The CTLX is migrated to the "completing" queue, and the completing
2982* tasklet is scheduled.
2983*
2984* Arguments:
2985* hw ptr to a hfa384x_t structure
2986* ctlx ptr to a ctlx structure
2987*
2988* Returns:
2989* nothing
2990*
2991* Side effects:
2992*
2993* Call context:
2994* Either, assume interrupt
2995----------------------------------------------------------------*/
297f06ce 2996static void unlocked_usbctlx_complete(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx)
00b3ed16 2997{
00b3ed16
GKH
2998 /* Timers have been stopped, and ctlx should be in
2999 * a terminal state. Retire it from the "active"
3000 * queue.
3001 */
3002 list_move_tail(&ctlx->list, &hw->ctlxq.completing);
3003 tasklet_schedule(&hw->completion_bh);
3004
3005 switch (ctlx->state) {
3006 case CTLX_COMPLETE:
3007 case CTLX_REQ_FAILED:
3008 /* This are the correct terminating states. */
3009 break;
3010
3011 default:
263b8bb9 3012 netdev_err(hw->wlandev->netdev, "CTLX[%d] not in a terminating state(%s)\n",
3f2d6564
SSA
3013 le16_to_cpu(ctlx->outbuf.type),
3014 ctlxstr(ctlx->state));
00b3ed16 3015 break;
21dc0f89 3016 } /* switch */
00b3ed16
GKH
3017}
3018
3019/*----------------------------------------------------------------
3020* hfa384x_usbctlxq_run
3021*
3022* Checks to see if the head item is running. If not, starts it.
3023*
3024* Arguments:
3025* hw ptr to hfa384x_t
3026*
3027* Returns:
3028* nothing
3029*
3030* Side effects:
3031*
3032* Call context:
3033* any
3034----------------------------------------------------------------*/
297f06ce 3035static void hfa384x_usbctlxq_run(hfa384x_t *hw)
00b3ed16 3036{
21dc0f89 3037 unsigned long flags;
00b3ed16
GKH
3038
3039 /* acquire lock */
3040 spin_lock_irqsave(&hw->ctlxq.lock, flags);
3041
3042 /* Only one active CTLX at any one time, because there's no
3043 * other (reliable) way to match the response URB to the
3044 * correct CTLX.
3045 *
3046 * Don't touch any of these CTLXs if the hardware
3047 * has been removed or the USB subsystem is stalled.
3048 */
21dc0f89
MM
3049 if (!list_empty(&hw->ctlxq.active) ||
3050 test_bit(WORK_TX_HALT, &hw->usb_flags) || hw->wlandev->hwremoved)
00b3ed16
GKH
3051 goto unlock;
3052
21dc0f89
MM
3053 while (!list_empty(&hw->ctlxq.pending)) {
3054 hfa384x_usbctlx_t *head;
3055 int result;
00b3ed16
GKH
3056
3057 /* This is the first pending command */
3058 head = list_entry(hw->ctlxq.pending.next,
21dc0f89 3059 hfa384x_usbctlx_t, list);
00b3ed16
GKH
3060
3061 /* We need to split this off to avoid a race condition */
3062 list_move_tail(&head->list, &hw->ctlxq.active);
3063
3064 /* Fill the out packet */
21dc0f89
MM
3065 usb_fill_bulk_urb(&(hw->ctlx_urb), hw->usb,
3066 hw->endp_out,
3067 &(head->outbuf), ROUNDUP64(head->outbufsize),
3068 hfa384x_ctlxout_callback, hw);
00b3ed16
GKH
3069 hw->ctlx_urb.transfer_flags |= USB_QUEUE_BULK;
3070
3f4b4e77 3071 /* Now submit the URB and update the CTLX's state */
46800b22
SK
3072 result = SUBMIT_URB(&hw->ctlx_urb, GFP_ATOMIC);
3073 if (result == 0) {
00b3ed16
GKH
3074 /* This CTLX is now running on the active queue */
3075 head->state = CTLX_REQ_SUBMITTED;
3076
3077 /* Start the OUT wait timer */
3078 hw->req_timer_done = 0;
3079 hw->reqtimer.expires = jiffies + HZ;
3080 add_timer(&hw->reqtimer);
3081
3082 /* Start the IN wait timer */
3083 hw->resp_timer_done = 0;
21dc0f89 3084 hw->resptimer.expires = jiffies + 2 * HZ;
00b3ed16
GKH
3085 add_timer(&hw->resptimer);
3086
3087 break;
3088 }
3089
3090 if (result == -EPIPE) {
3091 /* The OUT pipe needs resetting, so put
3092 * this CTLX back in the "pending" queue
3093 * and schedule a reset ...
3094 */
263b8bb9 3095 netdev_warn(hw->wlandev->netdev,
3f2d6564
SSA
3096 "%s tx pipe stalled: requesting reset\n",
3097 hw->wlandev->netdev->name);
00b3ed16
GKH
3098 list_move(&head->list, &hw->ctlxq.pending);
3099 set_bit(WORK_TX_HALT, &hw->usb_flags);
3100 schedule_work(&hw->usb_work);
3101 break;
3102 }
3103
3104 if (result == -ESHUTDOWN) {
263b8bb9 3105 netdev_warn(hw->wlandev->netdev, "%s urb shutdown!\n",
3f2d6564 3106 hw->wlandev->netdev->name);
00b3ed16
GKH
3107 break;
3108 }
3109
263b8bb9 3110 netdev_err(hw->wlandev->netdev, "Failed to submit CTLX[%d]: error=%d\n",
3f2d6564 3111 le16_to_cpu(head->outbuf.type), result);
00b3ed16 3112 unlocked_usbctlx_complete(hw, head);
21dc0f89 3113 } /* while */
00b3ed16 3114
21dc0f89 3115unlock:
00b3ed16 3116 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
00b3ed16
GKH
3117}
3118
00b3ed16
GKH
3119/*----------------------------------------------------------------
3120* hfa384x_usbin_callback
3121*
3122* Callback for URBs on the BULKIN endpoint.
3123*
3124* Arguments:
3125* urb ptr to the completed urb
3126*
3127* Returns:
3128* nothing
3129*
3130* Side effects:
3131*
3132* Call context:
3133* interrupt
3134----------------------------------------------------------------*/
00b3ed16 3135static void hfa384x_usbin_callback(struct urb *urb)
00b3ed16 3136{
21dc0f89
MM
3137 wlandevice_t *wlandev = urb->context;
3138 hfa384x_t *hw;
3139 hfa384x_usbin_t *usbin = (hfa384x_usbin_t *) urb->transfer_buffer;
3140 struct sk_buff *skb = NULL;
3141 int result;
3142 int urb_status;
3143 u16 type;
00b3ed16
GKH
3144
3145 enum USBIN_ACTION {
3146 HANDLE,
3147 RESUBMIT,
3148 ABORT
3149 } action;
3150
21dc0f89 3151 if (!wlandev || !wlandev->netdev || wlandev->hwremoved)
00b3ed16
GKH
3152 goto exit;
3153
3154 hw = wlandev->priv;
3155 if (!hw)
3156 goto exit;
3157
3158 skb = hw->rx_urb_skb;
2961f24f 3159 BUG_ON(!skb || (skb->data != urb->transfer_buffer));
21dc0f89 3160
00b3ed16
GKH
3161 hw->rx_urb_skb = NULL;
3162
3163 /* Check for error conditions within the URB */
3164 switch (urb->status) {
3165 case 0:
3166 action = HANDLE;
3167
3168 /* Check for short packet */
21dc0f89 3169 if (urb->actual_length == 0) {
00b3ed16
GKH
3170 ++(wlandev->linux_stats.rx_errors);
3171 ++(wlandev->linux_stats.rx_length_errors);
3172 action = RESUBMIT;
3173 }
3174 break;
3175
3176 case -EPIPE:
263b8bb9 3177 netdev_warn(hw->wlandev->netdev, "%s rx pipe stalled: requesting reset\n",
3f2d6564 3178 wlandev->netdev->name);
21dc0f89 3179 if (!test_and_set_bit(WORK_RX_HALT, &hw->usb_flags))
00b3ed16
GKH
3180 schedule_work(&hw->usb_work);
3181 ++(wlandev->linux_stats.rx_errors);
3182 action = ABORT;
3183 break;
3184
3185 case -EILSEQ:
3186 case -ETIMEDOUT:
3187 case -EPROTO:
21dc0f89
MM
3188 if (!test_and_set_bit(THROTTLE_RX, &hw->usb_flags) &&
3189 !timer_pending(&hw->throttle)) {
00b3ed16
GKH
3190 mod_timer(&hw->throttle, jiffies + THROTTLE_JIFFIES);
3191 }
3192 ++(wlandev->linux_stats.rx_errors);
3193 action = ABORT;
3194 break;
3195
3196 case -EOVERFLOW:
3197 ++(wlandev->linux_stats.rx_over_errors);
3198 action = RESUBMIT;
3199 break;
3200
3201 case -ENODEV:
3202 case -ESHUTDOWN:
a7cf7bae 3203 pr_debug("status=%d, device removed.\n", urb->status);
00b3ed16
GKH
3204 action = ABORT;
3205 break;
3206
3207 case -ENOENT:
3208 case -ECONNRESET:
75f49e07 3209 pr_debug("status=%d, urb explicitly unlinked.\n", urb->status);
00b3ed16
GKH
3210 action = ABORT;
3211 break;
3212
3213 default:
a7cf7bae 3214 pr_debug("urb status=%d, transfer flags=0x%x\n",
75f49e07 3215 urb->status, urb->transfer_flags);
00b3ed16
GKH
3216 ++(wlandev->linux_stats.rx_errors);
3217 action = RESUBMIT;
3218 break;
3219 }
3220
3221 urb_status = urb->status;
3222
3223 if (action != ABORT) {
3224 /* Repost the RX URB */
3225 result = submit_rx_urb(hw, GFP_ATOMIC);
3226
3227 if (result != 0) {
263b8bb9 3228 netdev_err(hw->wlandev->netdev,
3f2d6564
SSA
3229 "Fatal, failed to resubmit rx_urb. error=%d\n",
3230 result);
00b3ed16
GKH
3231 }
3232 }
3233
3234 /* Handle any USB-IN packet */
3235 /* Note: the check of the sw_support field, the type field doesn't
3236 * have bit 12 set like the docs suggest.
3237 */
18c7f792 3238 type = le16_to_cpu(usbin->type);
00b3ed16
GKH
3239 if (HFA384x_USB_ISRXFRM(type)) {
3240 if (action == HANDLE) {
3241 if (usbin->txfrm.desc.sw_support == 0x0123) {
3242 hfa384x_usbin_txcompl(wlandev, usbin);
3243 } else {
3244 skb_put(skb, sizeof(*usbin));
3245 hfa384x_usbin_rx(wlandev, skb);
3246 skb = NULL;
3247 }
3248 }
3249 goto exit;
3250 }
3251 if (HFA384x_USB_ISTXFRM(type)) {
3252 if (action == HANDLE)
3253 hfa384x_usbin_txcompl(wlandev, usbin);
3254 goto exit;
3255 }
3256 switch (type) {
3257 case HFA384x_USB_INFOFRM:
3258 if (action == ABORT)
3259 goto exit;
3260 if (action == HANDLE)
3261 hfa384x_usbin_info(wlandev, usbin);
3262 break;
3263
3264 case HFA384x_USB_CMDRESP:
3265 case HFA384x_USB_WRIDRESP:
3266 case HFA384x_USB_RRIDRESP:
3267 case HFA384x_USB_WMEMRESP:
3268 case HFA384x_USB_RMEMRESP:
3269 /* ALWAYS, ALWAYS, ALWAYS handle this CTLX!!!! */
3270 hfa384x_usbin_ctlx(hw, usbin, urb_status);
3271 break;
3272
3273 case HFA384x_USB_BUFAVAIL:
a7cf7bae 3274 pr_debug("Received BUFAVAIL packet, frmlen=%d\n",
75f49e07 3275 usbin->bufavail.frmlen);
00b3ed16
GKH
3276 break;
3277
3278 case HFA384x_USB_ERROR:
a7cf7bae 3279 pr_debug("Received USB_ERROR packet, errortype=%d\n",
75f49e07 3280 usbin->usberror.errortype);
00b3ed16
GKH
3281 break;
3282
3283 default:
75f49e07
MT
3284 pr_debug("Unrecognized USBIN packet, type=%x, status=%d\n",
3285 usbin->type, urb_status);
00b3ed16 3286 break;
21dc0f89 3287 } /* switch */
00b3ed16
GKH
3288
3289exit:
3290
3291 if (skb)
3292 dev_kfree_skb(skb);
00b3ed16
GKH
3293}
3294
00b3ed16
GKH
3295/*----------------------------------------------------------------
3296* hfa384x_usbin_ctlx
3297*
3298* We've received a URB containing a Prism2 "response" message.
3299* This message needs to be matched up with a CTLX on the active
3300* queue and our state updated accordingly.
3301*
3302* Arguments:
3303* hw ptr to hfa384x_t
3304* usbin ptr to USB IN packet
3305* urb_status status of this Bulk-In URB
3306*
3307* Returns:
3308* nothing
3309*
3310* Side effects:
3311*
3312* Call context:
3313* interrupt
3314----------------------------------------------------------------*/
297f06ce 3315static void hfa384x_usbin_ctlx(hfa384x_t *hw, hfa384x_usbin_t *usbin,
00b3ed16
GKH
3316 int urb_status)
3317{
21dc0f89
MM
3318 hfa384x_usbctlx_t *ctlx;
3319 int run_queue = 0;
3320 unsigned long flags;
00b3ed16 3321
00b3ed16
GKH
3322retry:
3323 spin_lock_irqsave(&hw->ctlxq.lock, flags);
3324
3325 /* There can be only one CTLX on the active queue
3326 * at any one time, and this is the CTLX that the
3327 * timers are waiting for.
3328 */
21dc0f89 3329 if (list_empty(&hw->ctlxq.active))
00b3ed16 3330 goto unlock;
00b3ed16
GKH
3331
3332 /* Remove the "response timeout". It's possible that
3333 * we are already too late, and that the timeout is
3334 * already running. And that's just too bad for us,
3335 * because we could lose our CTLX from the active
3336 * queue here ...
3337 */
3338 if (del_timer(&hw->resptimer) == 0) {
3339 if (hw->resp_timer_done == 0) {
3340 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
3341 goto retry;
3342 }
21dc0f89 3343 } else {
00b3ed16
GKH
3344 hw->resp_timer_done = 1;
3345 }
3346
3347 ctlx = get_active_ctlx(hw);
3348
3349 if (urb_status != 0) {
3350 /*
3351 * Bad CTLX, so get rid of it. But we only
3352 * remove it from the active queue if we're no
3353 * longer expecting the OUT URB to complete.
3354 */
3355 if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0)
3356 run_queue = 1;
3357 } else {
18c7f792 3358 const u16 intype = (usbin->type & ~cpu_to_le16(0x8000));
00b3ed16
GKH
3359
3360 /*
3361 * Check that our message is what we're expecting ...
3362 */
3363 if (ctlx->outbuf.type != intype) {
263b8bb9 3364 netdev_warn(hw->wlandev->netdev,
3f2d6564
SSA
3365 "Expected IN[%d], received IN[%d] - ignored.\n",
3366 le16_to_cpu(ctlx->outbuf.type),
3367 le16_to_cpu(intype));
00b3ed16
GKH
3368 goto unlock;
3369 }
3370
3371 /* This URB has succeeded, so grab the data ... */
3372 memcpy(&ctlx->inbuf, usbin, sizeof(ctlx->inbuf));
3373
3374 switch (ctlx->state) {
3375 case CTLX_REQ_SUBMITTED:
3376 /*
3377 * We have received our response URB before
3378 * our request has been acknowledged. Odd,
3379 * but our OUT URB is still alive...
3380 */
4ffab688 3381 pr_debug("Causality violation: please reboot Universe\n");
00b3ed16
GKH
3382 ctlx->state = CTLX_RESP_COMPLETE;
3383 break;
3384
3385 case CTLX_REQ_COMPLETE:
3386 /*
3387 * This is the usual path: our request
3388 * has already been acknowledged, and
3389 * now we have received the reply too.
3390 */
3391 ctlx->state = CTLX_COMPLETE;
3392 unlocked_usbctlx_complete(hw, ctlx);
3393 run_queue = 1;
3394 break;
3395
3396 default:
3397 /*
3398 * Throw this CTLX away ...
3399 */
263b8bb9 3400 netdev_err(hw->wlandev->netdev,
3f2d6564
SSA
3401 "Matched IN URB, CTLX[%d] in invalid state(%s). Discarded.\n",
3402 le16_to_cpu(ctlx->outbuf.type),
3403 ctlxstr(ctlx->state));
00b3ed16
GKH
3404 if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0)
3405 run_queue = 1;
3406 break;
21dc0f89 3407 } /* switch */
00b3ed16
GKH
3408 }
3409
3410unlock:
3411 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
3412
3413 if (run_queue)
3414 hfa384x_usbctlxq_run(hw);
00b3ed16
GKH
3415}
3416
00b3ed16
GKH
3417/*----------------------------------------------------------------
3418* hfa384x_usbin_txcompl
3419*
3420* At this point we have the results of a previous transmit.
3421*
3422* Arguments:
3423* wlandev wlan device
3424* usbin ptr to the usb transfer buffer
3425*
3426* Returns:
3427* nothing
3428*
3429* Side effects:
3430*
3431* Call context:
3432* interrupt
3433----------------------------------------------------------------*/
297f06ce
MT
3434static void hfa384x_usbin_txcompl(wlandevice_t *wlandev,
3435 hfa384x_usbin_t *usbin)
00b3ed16 3436{
21dc0f89 3437 u16 status;
00b3ed16 3438
631c8dec 3439 status = le16_to_cpu(usbin->type); /* yeah I know it says type... */
00b3ed16
GKH
3440
3441 /* Was there an error? */
21dc0f89 3442 if (HFA384x_TXSTATUS_ISERROR(status))
00b3ed16 3443 prism2sta_ev_txexc(wlandev, status);
21dc0f89 3444 else
00b3ed16 3445 prism2sta_ev_tx(wlandev, status);
00b3ed16
GKH
3446}
3447
00b3ed16
GKH
3448/*----------------------------------------------------------------
3449* hfa384x_usbin_rx
3450*
3451* At this point we have a successful received a rx frame packet.
3452*
3453* Arguments:
3454* wlandev wlan device
3455* usbin ptr to the usb transfer buffer
3456*
3457* Returns:
3458* nothing
3459*
3460* Side effects:
3461*
3462* Call context:
3463* interrupt
3464----------------------------------------------------------------*/
297f06ce 3465static void hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb)
00b3ed16 3466{
21dc0f89
MM
3467 hfa384x_usbin_t *usbin = (hfa384x_usbin_t *) skb->data;
3468 hfa384x_t *hw = wlandev->priv;
3469 int hdrlen;
51e4896a 3470 struct p80211_rxmeta *rxmeta;
21dc0f89
MM
3471 u16 data_len;
3472 u16 fc;
00b3ed16 3473
00b3ed16 3474 /* Byte order convert once up front. */
18c7f792
MM
3475 usbin->rxfrm.desc.status = le16_to_cpu(usbin->rxfrm.desc.status);
3476 usbin->rxfrm.desc.time = le32_to_cpu(usbin->rxfrm.desc.time);
00b3ed16
GKH
3477
3478 /* Now handle frame based on port# */
21dc0f89 3479 switch (HFA384x_RXSTATUS_MACPORT_GET(usbin->rxfrm.desc.status)) {
00b3ed16 3480 case 0:
ae26230b 3481 fc = le16_to_cpu(usbin->rxfrm.desc.frame_control);
00b3ed16
GKH
3482
3483 /* If exclude and we receive an unencrypted, drop it */
21dc0f89
MM
3484 if ((wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED) &&
3485 !WLAN_GET_FC_ISWEP(fc)) {
00b3ed16
GKH
3486 goto done;
3487 }
3488
18c7f792 3489 data_len = le16_to_cpu(usbin->rxfrm.desc.data_len);
00b3ed16
GKH
3490
3491 /* How much header data do we have? */
3492 hdrlen = p80211_headerlen(fc);
3493
3494 /* Pull off the descriptor */
3495 skb_pull(skb, sizeof(hfa384x_rx_frame_t));
3496
3497 /* Now shunt the header block up against the data block
3498 * with an "overlapping" copy
3499 */
3500 memmove(skb_push(skb, hdrlen),
21dc0f89 3501 &usbin->rxfrm.desc.frame_control, hdrlen);
00b3ed16
GKH
3502
3503 skb->dev = wlandev->netdev;
3504 skb->dev->last_rx = jiffies;
3505
3506 /* And set the frame length properly */
3507 skb_trim(skb, data_len + hdrlen);
3508
3509 /* The prism2 series does not return the CRC */
3510 memset(skb_put(skb, WLAN_CRC_LEN), 0xff, WLAN_CRC_LEN);
3511
3512 skb_reset_mac_header(skb);
3513
3514 /* Attach the rxmeta, set some stuff */
3515 p80211skb_rxmeta_attach(wlandev, skb);
3516 rxmeta = P80211SKB_RXMETA(skb);
3517 rxmeta->mactime = usbin->rxfrm.desc.time;
3518 rxmeta->rxrate = usbin->rxfrm.desc.rate;
3519 rxmeta->signal = usbin->rxfrm.desc.signal - hw->dbmadjust;
3520 rxmeta->noise = usbin->rxfrm.desc.silence - hw->dbmadjust;
3521
3522 prism2sta_ev_rx(wlandev, skb);
3523
3524 break;
3525
3526 case 7:
21dc0f89 3527 if (!HFA384x_RXSTATUS_ISFCSERR(usbin->rxfrm.desc.status)) {
00b3ed16 3528 /* Copy to wlansnif skb */
21dc0f89 3529 hfa384x_int_rxmonitor(wlandev, &usbin->rxfrm);
00b3ed16
GKH
3530 dev_kfree_skb(skb);
3531 } else {
75f49e07 3532 pr_debug("Received monitor frame: FCSerr set\n");
00b3ed16
GKH
3533 }
3534 break;
3535
3536 default:
263b8bb9 3537 netdev_warn(hw->wlandev->netdev, "Received frame on unsupported port=%d\n",
3f2d6564
SSA
3538 HFA384x_RXSTATUS_MACPORT_GET(
3539 usbin->rxfrm.desc.status));
00b3ed16
GKH
3540 goto done;
3541 break;
3542 }
3543
3544done:
00b3ed16
GKH
3545 return;
3546}
3547
3548/*----------------------------------------------------------------
3549* hfa384x_int_rxmonitor
3550*
3551* Helper function for int_rx. Handles monitor frames.
3552* Note that this function allocates space for the FCS and sets it
3553* to 0xffffffff. The hfa384x doesn't give us the FCS value but the
3554* higher layers expect it. 0xffffffff is used as a flag to indicate
3555* the FCS is bogus.
3556*
3557* Arguments:
3558* wlandev wlan device structure
3559* rxfrm rx descriptor read from card in int_rx
3560*
3561* Returns:
3562* nothing
3563*
3564* Side effects:
3565* Allocates an skb and passes it up via the PF_PACKET interface.
3566* Call context:
3567* interrupt
3568----------------------------------------------------------------*/
297f06ce
MT
3569static void hfa384x_int_rxmonitor(wlandevice_t *wlandev,
3570 hfa384x_usb_rxfrm_t *rxfrm)
00b3ed16 3571{
21dc0f89
MM
3572 hfa384x_rx_frame_t *rxdesc = &(rxfrm->desc);
3573 unsigned int hdrlen = 0;
3574 unsigned int datalen = 0;
3575 unsigned int skblen = 0;
3576 u8 *datap;
3577 u16 fc;
3578 struct sk_buff *skb;
3579 hfa384x_t *hw = wlandev->priv;
00b3ed16 3580
631c8dec 3581 /* Remember the status, time, and data_len fields are in host order */
00b3ed16 3582 /* Figure out how big the frame is */
ae26230b 3583 fc = le16_to_cpu(rxdesc->frame_control);
00b3ed16 3584 hdrlen = p80211_headerlen(fc);
18c7f792 3585 datalen = le16_to_cpu(rxdesc->data_len);
00b3ed16
GKH
3586
3587 /* Allocate an ind message+framesize skb */
51e4896a 3588 skblen = sizeof(struct p80211_caphdr) + hdrlen + datalen + WLAN_CRC_LEN;
00b3ed16
GKH
3589
3590 /* sanity check the length */
21dc0f89 3591 if (skblen >
51e4896a 3592 (sizeof(struct p80211_caphdr) +
21dc0f89 3593 WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN)) {
a7cf7bae 3594 pr_debug("overlen frm: len=%zd\n",
51e4896a 3595 skblen - sizeof(struct p80211_caphdr));
00b3ed16
GKH
3596 }
3597
46800b22
SK
3598 skb = dev_alloc_skb(skblen);
3599 if (skb == NULL) {
263b8bb9 3600 netdev_err(hw->wlandev->netdev,
3f2d6564
SSA
3601 "alloc_skb failed trying to allocate %d bytes\n",
3602 skblen);
00b3ed16
GKH
3603 return;
3604 }
3605
3606 /* only prepend the prism header if in the right mode */
3607 if ((wlandev->netdev->type == ARPHRD_IEEE80211_PRISM) &&
cbec30c4 3608 (hw->sniffhdr != 0)) {
51e4896a 3609 struct p80211_caphdr *caphdr;
00b3ed16 3610 /* The NEW header format! */
51e4896a
EH
3611 datap = skb_put(skb, sizeof(struct p80211_caphdr));
3612 caphdr = (struct p80211_caphdr *) datap;
21dc0f89
MM
3613
3614 caphdr->version = htonl(P80211CAPTURE_VERSION);
51e4896a 3615 caphdr->length = htonl(sizeof(struct p80211_caphdr));
21dc0f89
MM
3616 caphdr->mactime = __cpu_to_be64(rxdesc->time) * 1000;
3617 caphdr->hosttime = __cpu_to_be64(jiffies);
3618 caphdr->phytype = htonl(4); /* dss_dot11_b */
3619 caphdr->channel = htonl(hw->sniff_channel);
3620 caphdr->datarate = htonl(rxdesc->rate);
3621 caphdr->antenna = htonl(0); /* unknown */
3622 caphdr->priority = htonl(0); /* unknown */
3623 caphdr->ssi_type = htonl(3); /* rssi_raw */
3624 caphdr->ssi_signal = htonl(rxdesc->signal);
3625 caphdr->ssi_noise = htonl(rxdesc->silence);
3626 caphdr->preamble = htonl(0); /* unknown */
3627 caphdr->encoding = htonl(1); /* cck */
00b3ed16
GKH
3628 }
3629
631c8dec
EH
3630 /* Copy the 802.11 header to the skb
3631 (ctl frames may be less than a full header) */
00b3ed16 3632 datap = skb_put(skb, hdrlen);
21dc0f89 3633 memcpy(datap, &(rxdesc->frame_control), hdrlen);
00b3ed16
GKH
3634
3635 /* If any, copy the data from the card to the skb */
21dc0f89 3636 if (datalen > 0) {
00b3ed16
GKH
3637 datap = skb_put(skb, datalen);
3638 memcpy(datap, rxfrm->data, datalen);
3639
3640 /* check for unencrypted stuff if WEP bit set. */
21dc0f89
MM
3641 if (*(datap - hdrlen + 1) & 0x40) /* wep set */
3642 if ((*(datap) == 0xaa) && (*(datap + 1) == 0xaa))
631c8dec
EH
3643 /* clear wep; it's the 802.2 header! */
3644 *(datap - hdrlen + 1) &= 0xbf;
00b3ed16
GKH
3645 }
3646
3647 if (hw->sniff_fcs) {
3648 /* Set the FCS */
3649 datap = skb_put(skb, WLAN_CRC_LEN);
21dc0f89 3650 memset(datap, 0xff, WLAN_CRC_LEN);
00b3ed16
GKH
3651 }
3652
3653 /* pass it back up */
3654 prism2sta_ev_rx(wlandev, skb);
3655
00b3ed16
GKH
3656 return;
3657}
3658
00b3ed16
GKH
3659/*----------------------------------------------------------------
3660* hfa384x_usbin_info
3661*
3662* At this point we have a successful received a Prism2 info frame.
3663*
3664* Arguments:
3665* wlandev wlan device
3666* usbin ptr to the usb transfer buffer
3667*
3668* Returns:
3669* nothing
3670*
3671* Side effects:
3672*
3673* Call context:
3674* interrupt
3675----------------------------------------------------------------*/
297f06ce 3676static void hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t *usbin)
00b3ed16 3677{
21dc0f89 3678 usbin->infofrm.info.framelen =
18c7f792 3679 le16_to_cpu(usbin->infofrm.info.framelen);
00b3ed16 3680 prism2sta_ev_info(wlandev, &usbin->infofrm.info);
00b3ed16
GKH
3681}
3682
00b3ed16
GKH
3683/*----------------------------------------------------------------
3684* hfa384x_usbout_callback
3685*
3686* Callback for URBs on the BULKOUT endpoint.
3687*
3688* Arguments:
3689* urb ptr to the completed urb
3690*
3691* Returns:
3692* nothing
3693*
3694* Side effects:
3695*
3696* Call context:
3697* interrupt
3698----------------------------------------------------------------*/
00b3ed16 3699static void hfa384x_usbout_callback(struct urb *urb)
00b3ed16 3700{
21dc0f89
MM
3701 wlandevice_t *wlandev = urb->context;
3702 hfa384x_usbout_t *usbout = urb->transfer_buffer;
00b3ed16
GKH
3703
3704#ifdef DEBUG_USB
3705 dbprint_urb(urb);
3706#endif
3707
21dc0f89 3708 if (wlandev && wlandev->netdev) {
00b3ed16 3709
21dc0f89 3710 switch (urb->status) {
00b3ed16
GKH
3711 case 0:
3712 hfa384x_usbout_tx(wlandev, usbout);
3713 break;
3714
3715 case -EPIPE:
21dc0f89
MM
3716 {
3717 hfa384x_t *hw = wlandev->priv;
263b8bb9 3718 netdev_warn(hw->wlandev->netdev,
3f2d6564
SSA
3719 "%s tx pipe stalled: requesting reset\n",
3720 wlandev->netdev->name);
21dc0f89
MM
3721 if (!test_and_set_bit
3722 (WORK_TX_HALT, &hw->usb_flags))
3723 schedule_work(&hw->usb_work);
3724 ++(wlandev->linux_stats.tx_errors);
3725 break;
3726 }
00b3ed16
GKH
3727
3728 case -EPROTO:
3729 case -ETIMEDOUT:
3730 case -EILSEQ:
21dc0f89
MM
3731 {
3732 hfa384x_t *hw = wlandev->priv;
3733
3734 if (!test_and_set_bit
3735 (THROTTLE_TX, &hw->usb_flags)
3736 && !timer_pending(&hw->throttle)) {
3737 mod_timer(&hw->throttle,
3738 jiffies + THROTTLE_JIFFIES);
3739 }
3740 ++(wlandev->linux_stats.tx_errors);
3741 netif_stop_queue(wlandev->netdev);
3742 break;
00b3ed16 3743 }
00b3ed16
GKH
3744
3745 case -ENOENT:
3746 case -ESHUTDOWN:
3747 /* Ignorable errors */
3748 break;
3749
3750 default:
263b8bb9 3751 netdev_info(wlandev->netdev, "unknown urb->status=%d\n",
3f2d6564 3752 urb->status);
00b3ed16
GKH
3753 ++(wlandev->linux_stats.tx_errors);
3754 break;
21dc0f89 3755 } /* switch */
00b3ed16 3756 }
00b3ed16
GKH
3757}
3758
00b3ed16
GKH
3759/*----------------------------------------------------------------
3760* hfa384x_ctlxout_callback
3761*
3762* Callback for control data on the BULKOUT endpoint.
3763*
3764* Arguments:
3765* urb ptr to the completed urb
3766*
3767* Returns:
3768* nothing
3769*
3770* Side effects:
3771*
3772* Call context:
3773* interrupt
3774----------------------------------------------------------------*/
00b3ed16 3775static void hfa384x_ctlxout_callback(struct urb *urb)
00b3ed16 3776{
21dc0f89
MM
3777 hfa384x_t *hw = urb->context;
3778 int delete_resptimer = 0;
3779 int timer_ok = 1;
3780 int run_queue = 0;
3781 hfa384x_usbctlx_t *ctlx;
3782 unsigned long flags;
00b3ed16 3783
a7cf7bae 3784 pr_debug("urb->status=%d\n", urb->status);
00b3ed16
GKH
3785#ifdef DEBUG_USB
3786 dbprint_urb(urb);
3787#endif
21dc0f89
MM
3788 if ((urb->status == -ESHUTDOWN) ||
3789 (urb->status == -ENODEV) || (hw == NULL))
89e6302c 3790 return;
00b3ed16
GKH
3791
3792retry:
3793 spin_lock_irqsave(&hw->ctlxq.lock, flags);
3794
3795 /*
3796 * Only one CTLX at a time on the "active" list, and
3797 * none at all if we are unplugged. However, we can
3798 * rely on the disconnect function to clean everything
3799 * up if someone unplugged the adapter.
3800 */
21dc0f89 3801 if (list_empty(&hw->ctlxq.active)) {
00b3ed16 3802 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
89e6302c 3803 return;
00b3ed16
GKH
3804 }
3805
3806 /*
3807 * Having something on the "active" queue means
3808 * that we have timers to worry about ...
3809 */
3810 if (del_timer(&hw->reqtimer) == 0) {
3811 if (hw->req_timer_done == 0) {
3812 /*
3813 * This timer was actually running while we
3814 * were trying to delete it. Let it terminate
3815 * gracefully instead.
3816 */
3817 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
3818 goto retry;
3819 }
21dc0f89 3820 } else {
00b3ed16
GKH
3821 hw->req_timer_done = 1;
3822 }
3823
3824 ctlx = get_active_ctlx(hw);
3825
21dc0f89 3826 if (urb->status == 0) {
00b3ed16 3827 /* Request portion of a CTLX is successful */
21dc0f89 3828 switch (ctlx->state) {
00b3ed16
GKH
3829 case CTLX_REQ_SUBMITTED:
3830 /* This OUT-ACK received before IN */
3831 ctlx->state = CTLX_REQ_COMPLETE;
3832 break;
3833
3834 case CTLX_RESP_COMPLETE:
3835 /* IN already received before this OUT-ACK,
3836 * so this command must now be complete.
3837 */
3838 ctlx->state = CTLX_COMPLETE;
3839 unlocked_usbctlx_complete(hw, ctlx);
3840 run_queue = 1;
3841 break;
3842
3843 default:
3844 /* This is NOT a valid CTLX "success" state! */
263b8bb9 3845 netdev_err(hw->wlandev->netdev,
3f2d6564
SSA
3846 "Illegal CTLX[%d] success state(%s, %d) in OUT URB\n",
3847 le16_to_cpu(ctlx->outbuf.type),
3848 ctlxstr(ctlx->state), urb->status);
00b3ed16 3849 break;
21dc0f89 3850 } /* switch */
00b3ed16
GKH
3851 } else {
3852 /* If the pipe has stalled then we need to reset it */
21dc0f89
MM
3853 if ((urb->status == -EPIPE) &&
3854 !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags)) {
263b8bb9 3855 netdev_warn(hw->wlandev->netdev,
3f2d6564
SSA
3856 "%s tx pipe stalled: requesting reset\n",
3857 hw->wlandev->netdev->name);
00b3ed16
GKH
3858 schedule_work(&hw->usb_work);
3859 }
3860
3861 /* If someone cancels the OUT URB then its status
3862 * should be either -ECONNRESET or -ENOENT.
3863 */
3864 ctlx->state = CTLX_REQ_FAILED;
3865 unlocked_usbctlx_complete(hw, ctlx);
3866 delete_resptimer = 1;
3867 run_queue = 1;
3868 }
3869
21dc0f89 3870delresp:
00b3ed16 3871 if (delete_resptimer) {
46800b22 3872 timer_ok = del_timer(&hw->resptimer);
3f4b4e77 3873 if (timer_ok != 0)
00b3ed16 3874 hw->resp_timer_done = 1;
00b3ed16
GKH
3875 }
3876
3877 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
3878
21dc0f89 3879 if (!timer_ok && (hw->resp_timer_done == 0)) {
00b3ed16
GKH
3880 spin_lock_irqsave(&hw->ctlxq.lock, flags);
3881 goto delresp;
3882 }
3883
3884 if (run_queue)
3885 hfa384x_usbctlxq_run(hw);
00b3ed16
GKH
3886}
3887
00b3ed16
GKH
3888/*----------------------------------------------------------------
3889* hfa384x_usbctlx_reqtimerfn
3890*
3891* Timer response function for CTLX request timeouts. If this
3892* function is called, it means that the callback for the OUT
3893* URB containing a Prism2.x XXX_Request was never called.
3894*
3895* Arguments:
3896* data a ptr to the hfa384x_t
3897*
3898* Returns:
3899* nothing
3900*
3901* Side effects:
3902*
3903* Call context:
3904* interrupt
3905----------------------------------------------------------------*/
21dc0f89 3906static void hfa384x_usbctlx_reqtimerfn(unsigned long data)
00b3ed16 3907{
21dc0f89
MM
3908 hfa384x_t *hw = (hfa384x_t *) data;
3909 unsigned long flags;
00b3ed16
GKH
3910
3911 spin_lock_irqsave(&hw->ctlxq.lock, flags);
3912
3913 hw->req_timer_done = 1;
3914
3915 /* Removing the hardware automatically empties
3916 * the active list ...
3917 */
21dc0f89 3918 if (!list_empty(&hw->ctlxq.active)) {
00b3ed16
GKH
3919 /*
3920 * We must ensure that our URB is removed from
3921 * the system, if it hasn't already expired.
3922 */
3923 hw->ctlx_urb.transfer_flags |= URB_ASYNC_UNLINK;
21dc0f89 3924 if (usb_unlink_urb(&hw->ctlx_urb) == -EINPROGRESS) {
00b3ed16
GKH
3925 hfa384x_usbctlx_t *ctlx = get_active_ctlx(hw);
3926
3927 ctlx->state = CTLX_REQ_FAILED;
3928
3929 /* This URB was active, but has now been
3930 * cancelled. It will now have a status of
3931 * -ECONNRESET in the callback function.
3932 *
3933 * We are cancelling this CTLX, so we're
3934 * not going to need to wait for a response.
3935 * The URB's callback function will check
3936 * that this timer is truly dead.
3937 */
3938 if (del_timer(&hw->resptimer) != 0)
3939 hw->resp_timer_done = 1;
3940 }
3941 }
3942
3943 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
00b3ed16
GKH
3944}
3945
00b3ed16
GKH
3946/*----------------------------------------------------------------
3947* hfa384x_usbctlx_resptimerfn
3948*
3949* Timer response function for CTLX response timeouts. If this
3950* function is called, it means that the callback for the IN
3951* URB containing a Prism2.x XXX_Response was never called.
3952*
3953* Arguments:
3954* data a ptr to the hfa384x_t
3955*
3956* Returns:
3957* nothing
3958*
3959* Side effects:
3960*
3961* Call context:
3962* interrupt
3963----------------------------------------------------------------*/
21dc0f89 3964static void hfa384x_usbctlx_resptimerfn(unsigned long data)
00b3ed16 3965{
21dc0f89
MM
3966 hfa384x_t *hw = (hfa384x_t *) data;
3967 unsigned long flags;
00b3ed16 3968
00b3ed16
GKH
3969 spin_lock_irqsave(&hw->ctlxq.lock, flags);
3970
3971 hw->resp_timer_done = 1;
3972
3973 /* The active list will be empty if the
3974 * adapter has been unplugged ...
3975 */
21dc0f89 3976 if (!list_empty(&hw->ctlxq.active)) {
00b3ed16
GKH
3977 hfa384x_usbctlx_t *ctlx = get_active_ctlx(hw);
3978
21dc0f89 3979 if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0) {
00b3ed16
GKH
3980 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
3981 hfa384x_usbctlxq_run(hw);
3f514258 3982 return;
00b3ed16
GKH
3983 }
3984 }
00b3ed16 3985 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
00b3ed16
GKH
3986}
3987
3988/*----------------------------------------------------------------
3989* hfa384x_usb_throttlefn
3990*
3991*
3992* Arguments:
3993* data ptr to hw
3994*
3995* Returns:
3996* Nothing
3997*
3998* Side effects:
3999*
4000* Call context:
4001* Interrupt
4002----------------------------------------------------------------*/
21dc0f89 4003static void hfa384x_usb_throttlefn(unsigned long data)
00b3ed16 4004{
21dc0f89
MM
4005 hfa384x_t *hw = (hfa384x_t *) data;
4006 unsigned long flags;
00b3ed16 4007
00b3ed16
GKH
4008 spin_lock_irqsave(&hw->ctlxq.lock, flags);
4009
4010 /*
4011 * We need to check BOTH the RX and the TX throttle controls,
4012 * so we use the bitwise OR instead of the logical OR.
4013 */
a7cf7bae 4014 pr_debug("flags=0x%lx\n", hw->usb_flags);
21dc0f89
MM
4015 if (!hw->wlandev->hwremoved &&
4016 ((test_and_clear_bit(THROTTLE_RX, &hw->usb_flags) &&
4017 !test_and_set_bit(WORK_RX_RESUME, &hw->usb_flags))
4018 |
4019 (test_and_clear_bit(THROTTLE_TX, &hw->usb_flags) &&
4020 !test_and_set_bit(WORK_TX_RESUME, &hw->usb_flags))
4021 )) {
00b3ed16
GKH
4022 schedule_work(&hw->usb_work);
4023 }
4024
4025 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
00b3ed16
GKH
4026}
4027
00b3ed16
GKH
4028/*----------------------------------------------------------------
4029* hfa384x_usbctlx_submit
4030*
4031* Called from the doxxx functions to submit a CTLX to the queue
4032*
4033* Arguments:
4034* hw ptr to the hw struct
4035* ctlx ctlx structure to enqueue
4036*
4037* Returns:
4038* -ENODEV if the adapter is unplugged
4039* 0
4040*
4041* Side effects:
4042*
4043* Call context:
4044* process or interrupt
4045----------------------------------------------------------------*/
297f06ce 4046static int hfa384x_usbctlx_submit(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx)
00b3ed16
GKH
4047{
4048 unsigned long flags;
00b3ed16 4049
00b3ed16
GKH
4050 spin_lock_irqsave(&hw->ctlxq.lock, flags);
4051
4052 if (hw->wlandev->hwremoved) {
4053 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
675be12f 4054 return -ENODEV;
00b3ed16
GKH
4055 }
4056
675be12f
DN
4057 ctlx->state = CTLX_PENDING;
4058 list_add_tail(&ctlx->list, &hw->ctlxq.pending);
4059 spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
4060 hfa384x_usbctlxq_run(hw);
4061
4062 return 0;
00b3ed16
GKH
4063}
4064
00b3ed16
GKH
4065/*----------------------------------------------------------------
4066* hfa384x_usbout_tx
4067*
4068* At this point we have finished a send of a frame. Mark the URB
4069* as available and call ev_alloc to notify higher layers we're
4070* ready for more.
4071*
4072* Arguments:
4073* wlandev wlan device
4074* usbout ptr to the usb transfer buffer
4075*
4076* Returns:
4077* nothing
4078*
4079* Side effects:
4080*
4081* Call context:
4082* interrupt
4083----------------------------------------------------------------*/
297f06ce 4084static void hfa384x_usbout_tx(wlandevice_t *wlandev, hfa384x_usbout_t *usbout)
00b3ed16 4085{
00b3ed16 4086 prism2sta_ev_alloc(wlandev);
00b3ed16
GKH
4087}
4088
4089/*----------------------------------------------------------------
4090* hfa384x_isgood_pdrcore
4091*
4092* Quick check of PDR codes.
4093*
4094* Arguments:
4095* pdrcode PDR code number (host order)
4096*
4097* Returns:
4098* zero not good.
4099* one is good.
4100*
4101* Side effects:
4102*
4103* Call context:
4104----------------------------------------------------------------*/
21dc0f89 4105static int hfa384x_isgood_pdrcode(u16 pdrcode)
00b3ed16 4106{
21dc0f89 4107 switch (pdrcode) {
00b3ed16
GKH
4108 case HFA384x_PDR_END_OF_PDA:
4109 case HFA384x_PDR_PCB_PARTNUM:
4110 case HFA384x_PDR_PDAVER:
4111 case HFA384x_PDR_NIC_SERIAL:
4112 case HFA384x_PDR_MKK_MEASUREMENTS:
4113 case HFA384x_PDR_NIC_RAMSIZE:
4114 case HFA384x_PDR_MFISUPRANGE:
4115 case HFA384x_PDR_CFISUPRANGE:
4116 case HFA384x_PDR_NICID:
4117 case HFA384x_PDR_MAC_ADDRESS:
4118 case HFA384x_PDR_REGDOMAIN:
4119 case HFA384x_PDR_ALLOWED_CHANNEL:
4120 case HFA384x_PDR_DEFAULT_CHANNEL:
4121 case HFA384x_PDR_TEMPTYPE:
4122 case HFA384x_PDR_IFR_SETTING:
4123 case HFA384x_PDR_RFR_SETTING:
4124 case HFA384x_PDR_HFA3861_BASELINE:
4125 case HFA384x_PDR_HFA3861_SHADOW:
4126 case HFA384x_PDR_HFA3861_IFRF:
4127 case HFA384x_PDR_HFA3861_CHCALSP:
4128 case HFA384x_PDR_HFA3861_CHCALI:
4129 case HFA384x_PDR_3842_NIC_CONFIG:
4130 case HFA384x_PDR_USB_ID:
4131 case HFA384x_PDR_PCI_ID:
4132 case HFA384x_PDR_PCI_IFCONF:
4133 case HFA384x_PDR_PCI_PMCONF:
4134 case HFA384x_PDR_RFENRGY:
4135 case HFA384x_PDR_HFA3861_MANF_TESTSP:
4136 case HFA384x_PDR_HFA3861_MANF_TESTI:
4137 /* code is OK */
4138 return 1;
4139 break;
4140 default:
21dc0f89 4141 if (pdrcode < 0x1000) {
00b3ed16 4142 /* code is OK, but we don't know exactly what it is */
a2120136
SSA
4143 pr_debug("Encountered unknown PDR#=0x%04x, assuming it's ok.\n",
4144 pdrcode);
00b3ed16
GKH
4145 return 1;
4146 } else {
4147 /* bad code */
a2120136
SSA
4148 pr_debug("Encountered unknown PDR#=0x%04x, (>=0x1000), assuming it's bad.\n",
4149 pdrcode);
00b3ed16
GKH
4150 return 0;
4151 }
4152 break;
4153 }
21dc0f89 4154 return 0; /* avoid compiler warnings */
00b3ed16 4155}