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