~ubuntu-branches/ubuntu/karmic/linux-ports/karmic

« back to all changes in this revision

Viewing changes to ubuntu/misc/wireless/prism2_usb/hfa384x_usb.c

  • Committer: Bazaar Package Importer
  • Author(s): Luke Yelavich, Luke Yelavich, Michael Casadevall, Tim Gardner, Upstream Kernel Changes
  • Date: 2009-05-06 18:18:55 UTC
  • Revision ID: james.westby@ubuntu.com-20090506181855-t00baeevpnvd9o7a
Tags: 2.6.30-1.1
[ Luke Yelavich ]
* initial release for karmic
* SAUCE: rebase-ports - adjust for the karmic ports kernel
* SAUCE: rebase-ports - also remove abi dirs/files on rebase
* Update configs after rebase against mainline Jaunty tree
* [Config] Disable CONFIG_BLK_DEV_UB and CONFIG_USB_LIBUSUAL as per
  mainline jaunty
* forward-port patch to drbd for powerpc compilation
* [Config] disable CONFIG_LENOVO_SL_LAPTOP for i386 due to FTBFS
* add .o files found in arch/powerpc/lib to all powerpc kernel header
  packages
* [Config] enable CONFIG_DRM_I915_KMS for i386 as per karmic mainline

[ Michael Casadevall ]

* Disable kgdb on sparc64
* [sparc] [Config] Disable GPIO LEDS
* [ia64] Rename -ia64-generic to -ia64 in line with other architectures
* Correct kernel image path for sparc builds
* [hppa] Fix HPPA config files to build modules for all udebian

Rebase on top of karmic mainline 2.6.30-1.1

[ Tim Gardner ]

* [Config] armel: disable staging drivers, fixes FTBS
* [Config] armel imx51: Disable CONFIG_MTD_NAND_MXC, fixes FTBS

[ Upstream Kernel Changes ]

* mpt2sas: Change reset_type enum to avoid namespace collision.
  Submitted upstream.

* Initial release after rebasing against v2.6.30-rc3

Show diffs side-by-side

added added

removed removed

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