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