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