Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6
[linux-2.6] / drivers / staging / wlan-ng / hfa384x.c
1 /* src/prism2/driver/hfa384x.c
2 *
3 * Implements the functions of 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 *  .
103 *  .  Self contained test routines can run here, particularly
104 *  .  corereset() and test_hostif().
105 *  .
106 * start()
107 *  .
108 *  .  Do interesting things w/ the hardware
109 *  .
110 * stop()
111 * destroy()
112 *
113 * Note that destroy() can be called without calling stop() first.
114 * --------------------------------------------------------------------
115 */
116
117 /*================================================================*/
118
119 /* System Includes */
120 #define WLAN_DBVAR      prism2_debug
121 #include "version.h"
122
123
124 #include <linux/version.h>
125
126 #include <linux/module.h>
127 #include <linux/kernel.h>
128 #include <linux/sched.h>
129 #include <linux/types.h>
130 #include <linux/slab.h>
131 #include <linux/wireless.h>
132 #include <linux/netdevice.h>
133 #include <linux/timer.h>
134 #include <asm/semaphore.h>
135 #include <asm/io.h>
136 #include <linux/delay.h>
137 #include <asm/byteorder.h>
138 #include <linux/list.h>
139
140 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
141 #include <linux/tqueue.h>
142 #else
143 #include <linux/workqueue.h>
144 #endif
145
146 #if (WLAN_HOSTIF == WLAN_PCMCIA)
147 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) )
148 #include <pcmcia/version.h>
149 #endif
150 #include <pcmcia/cs_types.h>
151 #include <pcmcia/cs.h>
152 #include <pcmcia/cistpl.h>
153 #include <pcmcia/ds.h>
154 #include <pcmcia/cisreg.h>
155 #endif
156
157 #if ((WLAN_HOSTIF == WLAN_PLX) || (WLAN_HOSTIF == WLAN_PCI))
158 #include <linux/ioport.h>
159 #include <linux/pci.h>
160 #endif
161
162 #include "wlan_compat.h"
163
164 // XXXX #define CMD_IRQ
165
166 /*================================================================*/
167 /* Project Includes */
168
169 #include "p80211types.h"
170 #include "p80211hdr.h"
171 #include "p80211mgmt.h"
172 #include "p80211conv.h"
173 #include "p80211msg.h"
174 #include "p80211netdev.h"
175 #include "p80211req.h"
176 #include "p80211metadef.h"
177 #include "p80211metastruct.h"
178 #include "hfa384x.h"
179 #include "prism2mgmt.h"
180
181 /*================================================================*/
182 /* Local Constants */
183
184 static const UINT16 crc16tab[256] =
185 {
186         0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
187         0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
188         0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
189         0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
190         0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
191         0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
192         0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
193         0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
194         0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
195         0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
196         0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
197         0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
198         0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
199         0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
200         0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
201         0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
202         0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
203         0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
204         0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
205         0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
206         0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
207         0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
208         0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
209         0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
210         0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
211         0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
212         0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
213         0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
214         0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
215         0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
216         0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
217         0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040
218 };
219
220 /*================================================================*/
221 /* Local Macros */
222
223 /*================================================================*/
224 /* Local Types */
225
226 /*================================================================*/
227 /* Local Static Definitions */
228 extern int prism2_debug;
229
230 /*================================================================*/
231 /* Local Function Declarations */
232
233 static void     hfa384x_int_dtim(wlandevice_t *wlandev);
234 static void     hfa384x_int_infdrop(wlandevice_t *wlandev);
235
236 static void     hfa384x_bap_tasklet(unsigned long data);
237
238 static void     hfa384x_int_info(wlandevice_t *wlandev);
239 static void     hfa384x_int_txexc(wlandevice_t *wlandev);
240 static void     hfa384x_int_tx(wlandevice_t *wlandev);
241 static void     hfa384x_int_rx(wlandevice_t *wlandev);
242
243 #ifdef CMD_IRQ
244 static void     hfa384x_int_cmd(wlandevice_t *wlandev);
245 #endif
246 static void     hfa384x_int_rxmonitor( wlandevice_t *wlandev,
247                         UINT16 rxfid, hfa384x_rx_frame_t *rxdesc);
248 static void     hfa384x_int_alloc(wlandevice_t *wlandev);
249
250 static int hfa384x_docmd_wait( hfa384x_t *hw, hfa384x_metacmd_t *cmd);
251
252 static int hfa384x_dl_docmd_wait( hfa384x_t *hw, hfa384x_metacmd_t *cmd);
253
254 static UINT16
255 hfa384x_mkcrc16(UINT8 *p, int len);
256
257 int hfa384x_copy_to_bap4(hfa384x_t *hw, UINT16 bap, UINT16 id, UINT16 offset,
258                          void *buf, UINT len, void* buf2, UINT len2,
259                          void *buf3, UINT len3, void* buf4, UINT len4);
260
261 /*================================================================*/
262 /* Function Definitions */
263
264 static UINT16
265 txfid_queue_empty(hfa384x_t *hw)
266 {
267         return (hw->txfid_head == hw->txfid_tail) ? 1 : 0;
268 }
269
270 static UINT16
271 txfid_queue_remove(hfa384x_t *hw)
272 {
273         UINT16 result= 0;
274
275         if (txfid_queue_empty(hw)) {
276                 WLAN_LOG_DEBUG(3,"queue empty.\n");
277         } else {
278                 result = hw->txfid_queue[hw->txfid_head];
279                 hw->txfid_head = (hw->txfid_head + 1) % hw->txfid_N;
280         }
281
282         return (UINT16)result;
283 }
284
285 static INT16
286 txfid_queue_add(hfa384x_t *hw, UINT16 val)
287 {
288         INT16 result = 0;
289
290         if (hw->txfid_head == ((hw->txfid_tail + 1) % hw->txfid_N)) {
291                 result = -1;
292                 WLAN_LOG_DEBUG(3,"queue full.\n");
293         } else {
294                 hw->txfid_queue[hw->txfid_tail] = val;
295                 result = hw->txfid_tail;
296                 hw->txfid_tail = (hw->txfid_tail + 1) % hw->txfid_N;
297         }
298
299         return result;
300 }
301
302 /*----------------------------------------------------------------
303 * hfa384x_create
304 *
305 * Initializes the hfa384x_t data structure for use.  Note this
306 * does _not_ intialize the actual hardware, just the data structures
307 * we use to keep track of its state.
308 *
309 * Arguments:
310 *       hw              device structure
311 *       irq             device irq number
312 *       iobase          [pcmcia] i/o base address for register access
313 *                       [pci] zero
314 *                       [plx] i/o base address for register access
315 *       membase         [pcmcia] pcmcia_cs "link" pointer
316 *                       [pci] memory base address for register access
317 *                       [plx] memory base address for card attribute memory
318 *
319 * Returns:
320 *       nothing
321 *
322 * Side effects:
323 *
324 * Call context:
325 *       process thread
326 ----------------------------------------------------------------*/
327 void hfa384x_create(hfa384x_t *hw, UINT irq, UINT32 iobase,
328                     UINT8 __iomem *membase)
329 {
330         DBFENTER;
331         memset(hw, 0, sizeof(hfa384x_t));
332         hw->irq = irq;
333         hw->iobase = iobase;
334         hw->membase = membase;
335         spin_lock_init(&(hw->cmdlock));
336
337         /* BAP setup */
338         spin_lock_init(&(hw->baplock));
339         tasklet_init(&hw->bap_tasklet,
340                      hfa384x_bap_tasklet,
341                      (unsigned long) hw);
342
343         init_waitqueue_head(&hw->cmdq);
344         sema_init(&hw->infofid_sem, 1);
345
346         hw->txfid_head = 0;
347         hw->txfid_tail = 0;
348         hw->txfid_N = HFA384x_DRVR_FIDSTACKLEN_MAX;
349         memset(hw->txfid_queue, 0, sizeof(hw->txfid_queue));
350
351         hw->isram16 = 1;
352
353         /* Init the auth queue head */
354         skb_queue_head_init(&hw->authq);
355
356         INIT_WORK2(&hw->link_bh, prism2sta_processing_defer);
357
358         INIT_WORK2(&hw->commsqual_bh, prism2sta_commsqual_defer);
359
360         init_timer(&hw->commsqual_timer);
361         hw->commsqual_timer.data = (unsigned long) hw;
362         hw->commsqual_timer.function = prism2sta_commsqual_timer;
363
364         hw->link_status = HFA384x_LINK_NOTCONNECTED;
365         hw->state = HFA384x_STATE_INIT;
366
367         DBFEXIT;
368 }
369
370 /*----------------------------------------------------------------
371 * hfa384x_destroy
372 *
373 * Partner to hfa384x_create().  This function cleans up the hw
374 * structure so that it can be freed by the caller using a simple
375 * kfree.  Currently, this function is just a placeholder.  If, at some
376 * point in the future, an hw in the 'shutdown' state requires a 'deep'
377 * kfree, this is where it should be done.  Note that if this function
378 * is called on a _running_ hw structure, the drvr_stop() function is
379 * called.
380 *
381 * Arguments:
382 *       hw              device structure
383 *
384 * Returns:
385 *       nothing, this function is not allowed to fail.
386 *
387 * Side effects:
388 *
389 * Call context:
390 *       process
391 ----------------------------------------------------------------*/
392 void
393 hfa384x_destroy( hfa384x_t *hw)
394 {
395         struct sk_buff *skb;
396
397         DBFENTER;
398
399         if ( hw->state == HFA384x_STATE_RUNNING ) {
400                 hfa384x_drvr_stop(hw);
401         }
402         hw->state = HFA384x_STATE_PREINIT;
403
404         if (hw->scanresults) {
405                 kfree(hw->scanresults);
406                 hw->scanresults = NULL;
407         }
408
409         /* Now to clean out the auth queue */
410         while ( (skb = skb_dequeue(&hw->authq)) ) {
411                 dev_kfree_skb(skb);
412         }
413
414         DBFEXIT;
415         return;
416 }
417
418 /*----------------------------------------------------------------
419 * hfa384x_drvr_getconfig
420 *
421 * Performs the sequence necessary to read a config/info item.
422 *
423 * Arguments:
424 *       hw              device structure
425 *       rid             config/info record id (host order)
426 *       buf             host side record buffer.  Upon return it will
427 *                       contain the body portion of the record (minus the
428 *                       RID and len).
429 *       len             buffer length (in bytes, should match record length)
430 *
431 * Returns:
432 *       0               success
433 *       >0              f/w reported error - f/w status code
434 *       <0              driver reported error
435 *       -ENODATA        length mismatch between argument and retrieved
436 *                       record.
437 *
438 * Side effects:
439 *
440 * Call context:
441 *       process thread
442 ----------------------------------------------------------------*/
443 int hfa384x_drvr_getconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len)
444 {
445         int             result = 0;
446         DBFENTER;
447
448         result = hfa384x_cmd_access( hw, 0, rid, buf, len);
449
450         DBFEXIT;
451         return result;
452 }
453
454
455 /*----------------------------------------------------------------
456 * hfa384x_drvr_setconfig
457 *
458 * Performs the sequence necessary to write a config/info item.
459 *
460 * Arguments:
461 *       hw              device structure
462 *       rid             config/info record id (in host order)
463 *       buf             host side record buffer
464 *       len             buffer length (in bytes)
465 *
466 * Returns:
467 *       0               success
468 *       >0              f/w reported error - f/w status code
469 *       <0              driver reported error
470 *
471 * Side effects:
472 *
473 * Call context:
474 *       process thread
475 ----------------------------------------------------------------*/
476 int hfa384x_drvr_setconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len)
477 {
478         int             result = 0;
479         DBFENTER;
480
481         result = hfa384x_cmd_access( hw, 1, rid, buf, len);
482
483         DBFEXIT;
484         return result;
485 }
486
487
488 /*----------------------------------------------------------------
489 * hfa384x_drvr_readpda
490 *
491 * Performs the sequence to read the PDA space.  Note there is no
492 * drvr_writepda() function.  Writing a PDA is
493 * generally implemented by a calling component via calls to
494 * cmd_download and writing to the flash download buffer via the
495 * aux regs.
496 *
497 * Arguments:
498 *       hw              device structure
499 *       buf             buffer to store PDA in
500 *       len             buffer length
501 *
502 * Returns:
503 *       0               success
504 *       >0              f/w reported error - f/w status code
505 *       <0              driver reported error
506 *       -ETIMEOUT       timout waiting for the cmd regs to become
507 *                       available, or waiting for the control reg
508 *                       to indicate the Aux port is enabled.
509 *       -ENODATA        the buffer does NOT contain a valid PDA.
510 *                       Either the card PDA is bad, or the auxdata
511 *                       reads are giving us garbage.
512
513 *
514 * Side effects:
515 *
516 * Call context:
517 *       process thread or non-card interrupt.
518 ----------------------------------------------------------------*/
519 int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, UINT len)
520 {
521         int             result = 0;
522         UINT16          *pda = buf;
523         int             pdaok = 0;
524         int             morepdrs = 1;
525         int             currpdr = 0;    /* word offset of the current pdr */
526         int             i;
527         UINT16          pdrlen;         /* pdr length in bytes, host order */
528         UINT16          pdrcode;        /* pdr code, host order */
529         UINT16          crc;
530         UINT16          pdacrc;
531         struct pdaloc {
532                 UINT32  cardaddr;
533                 UINT16  auxctl;
534         } pdaloc[] =
535         {
536                 { HFA3842_PDA_BASE,             HFA384x_AUX_CTL_NV},
537                 { HFA3842_PDA_BASE,             HFA384x_AUX_CTL_EXTDS},
538                 { HFA3841_PDA_BASE,             HFA384x_AUX_CTL_NV},
539                 { HFA3841_PDA_BASE,             HFA384x_AUX_CTL_EXTDS},
540                 { HFA3841_PDA_BOGUS_BASE,       HFA384x_AUX_CTL_NV}
541         };
542
543         DBFENTER;
544         /* Check for aux available */
545         result = hfa384x_cmd_aux_enable(hw, 0);
546         if ( result ) {
547                 WLAN_LOG_DEBUG(1,"aux_enable() failed. result=%d\n", result);
548                 goto failed;
549         }
550
551         /* Read the pda from each known address.  */
552         for ( i = 0; i < (sizeof(pdaloc)/sizeof(pdaloc[0])); i++) {
553                 WLAN_LOG_DEBUG( 3, "Checking PDA@(0x%08x,%s)\n",
554                         pdaloc[i].cardaddr,
555                         pdaloc[i].auxctl == HFA384x_AUX_CTL_NV ?
556                         "CTL_NV" : "CTL_EXTDS");
557
558                 /* Copy bufsize bytes from our current pdaloc */
559                 hfa384x_copy_from_aux(hw,
560                         pdaloc[i].cardaddr,
561                         pdaloc[i].auxctl,
562                         buf,
563                         len);
564
565                 /* Test for garbage */
566                 /* Traverse the PDR list Looking for PDA-END */
567                 pdaok = 1;      /* intially assume good */
568                 morepdrs = 1;
569                 currpdr = 0;
570                 while ( pdaok && morepdrs ) {
571                         pdrlen = hfa384x2host_16(pda[currpdr]) * 2;
572                         pdrcode = hfa384x2host_16(pda[currpdr+1]);
573
574                         /* Test for completion at END record */
575                         if ( pdrcode == HFA384x_PDR_END_OF_PDA ) {
576                                 if ( pdrlen == 4 ) {
577                                         morepdrs = 0;
578                                         /* Calculate CRC-16 and compare to PDA
579                                          * value.  Note the addition of 2 words
580                                          * for ENDREC.len and ENDREC.code
581                                          * fields.
582                                          */
583                                         crc = hfa384x_mkcrc16( (UINT8*)pda,
584                                                 (currpdr + 2) * sizeof(UINT16));
585                                         pdacrc =hfa384x2host_16(pda[currpdr+2]);
586                                         if ( crc != pdacrc ) {
587                                                 WLAN_LOG_DEBUG(3,
588                                                 "PDA crc failed:"
589                                                 "calc_crc=0x%04x,"
590                                                 "pdr_crc=0x%04x.\n",
591                                                 crc, pdacrc);
592                                                 pdaok = 0;
593                                         }
594                                 } else {
595                                         WLAN_LOG_DEBUG(3,
596                                         "END record detected w/ "
597                                         "len(%d) != 2, assuming bad PDA\n",
598                                         pdrlen);
599                                         pdaok = 0;
600
601                                 }
602                                 break;
603                         }
604
605                         /* Test the record length */
606                         if ( pdrlen > HFA384x_PDR_LEN_MAX || pdrlen == 0) {
607                                 WLAN_LOG_DEBUG(3,
608                                         "pdrlen for address #%d "
609                                         "at %#x:%#x:%d\n",
610                                         i, pdaloc[i].cardaddr,
611                                         pdaloc[i].auxctl, pdrlen);
612                                 WLAN_LOG_DEBUG(3,"pdrlen invalid=%d\n",
613                                         pdrlen);
614                                 pdaok = 0;
615                                 break;
616                         }
617
618                         /* Move to the next pdr */
619                         if ( morepdrs ) {
620                                 /* note the access to pda[], we need words */
621                                 currpdr += hfa384x2host_16(pda[currpdr]) + 1;
622                                 if (currpdr*sizeof(UINT16) > len) {
623                                         WLAN_LOG_DEBUG(3,
624                                         "Didn't find PDA_END in buffer, "
625                                         "trying next location.\n");
626                                         pdaok = 0;
627                                         break;
628                                 }
629                         }
630                 }
631                 if ( pdaok ) {
632                         WLAN_LOG_INFO(
633                                 "PDA Read from 0x%08x in %s space.\n",
634                                 pdaloc[i].cardaddr,
635                                 pdaloc[i].auxctl == 0 ? "EXTDS" :
636                                 pdaloc[i].auxctl == 1 ? "NV" :
637                                 pdaloc[i].auxctl == 2 ? "PHY" :
638                                 pdaloc[i].auxctl == 3 ? "ICSRAM" :
639                                 "<bogus auxctl>");
640                         break;
641                 }
642         }
643         result = pdaok ? 0 : -ENODATA;
644
645         if ( result ) {
646                 WLAN_LOG_DEBUG(3,"Failure: pda is not okay\n");
647         }
648
649         hfa384x_cmd_aux_disable(hw);
650 failed:
651         DBFEXIT;
652         return result;
653 }
654
655
656
657 /*----------------------------------------------------------------
658 * mkpda_crc
659 *
660 * Calculates the CRC16 for the given PDA and inserts the value
661 * into the end record.
662 *
663 * Arguments:
664 *       pda     ptr to the PDA data structure.
665 *
666 * Returns:
667 *       0       - success
668 *       ~0      - failure (probably an errno)
669 ----------------------------------------------------------------*/
670 static UINT16
671 hfa384x_mkcrc16(UINT8 *p, int len)
672 {
673         UINT16  crc = 0;
674         UINT8   *lim = p + len;
675
676         while (p < lim) {
677                 crc = (crc >> 8 ) ^ crc16tab[(crc & 0xff) ^ *p++];
678         }
679
680         return crc;
681 }
682
683
684 /*----------------------------------------------------------------
685 * hfa384x_drvr_ramdl_enable
686 *
687 * Begins the ram download state.  Checks to see that we're not
688 * already in a download state and that a port isn't enabled.
689 * Sets the download state and calls cmd_download with the
690 * ENABLE_VOLATILE subcommand and the exeaddr argument.
691 *
692 * Arguments:
693 *       hw              device structure
694 *       exeaddr         the card execution address that will be
695 *                       jumped to when ramdl_disable() is called
696 *                       (host order).
697 *
698 * Returns:
699 *       0               success
700 *       >0              f/w reported error - f/w status code
701 *       <0              driver reported error
702 *
703 * Side effects:
704 *
705 * Call context:
706 *       process thread
707 ----------------------------------------------------------------*/
708 int hfa384x_drvr_ramdl_enable(hfa384x_t *hw, UINT32 exeaddr)
709 {
710         int             result = 0;
711         UINT16          lowaddr;
712         UINT16          hiaddr;
713         int             i;
714         DBFENTER;
715         /* Check that a port isn't active */
716         for ( i = 0; i < HFA384x_PORTID_MAX; i++) {
717                 if ( hw->port_enabled[i] ) {
718                         WLAN_LOG_DEBUG(1,"Can't download with a port enabled.\n");
719                         result = -EINVAL;
720                         goto done;
721                 }
722         }
723
724         /* Check that we're not already in a download state */
725         if ( hw->dlstate != HFA384x_DLSTATE_DISABLED ) {
726                 WLAN_LOG_DEBUG(1,"Download state not disabled.\n");
727                 result = -EINVAL;
728                 goto done;
729         }
730
731         /* Are we supposed to go into genesis mode? */
732         if (exeaddr == 0x3f0000) {
733                 UINT16 initseq[2] = { 0xe100, 0xffa1 };
734                 UINT16 readbuf[2];
735                 UINT8 hcr = 0x0f; /* Default to x16 SRAM */
736                 hw->isram16 = 1;
737
738                 WLAN_LOG_DEBUG(1, "Dropping into Genesis mode\n");
739
740                 /* Issue card reset and enable aux port */
741                 hfa384x_corereset(hw, prism2_reset_holdtime,
742                                   prism2_reset_settletime, 0);
743                 hfa384x_cmd_aux_enable(hw, 1);
744
745                 /* Genesis set */
746                 hfa384x_copy_to_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS,
747                                     initseq, sizeof(initseq));
748
749                 hfa384x_corereset(hw, prism2_reset_holdtime,
750                                   prism2_reset_settletime, hcr);
751
752                 /* Validate memory config */
753                 hfa384x_copy_to_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS,
754                                     initseq, sizeof(initseq));
755                 hfa384x_copy_from_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS,
756                                     readbuf, sizeof(initseq));
757                 WLAN_HEX_DUMP(3, "readback", readbuf, sizeof(readbuf));
758
759                 if (memcmp(initseq, readbuf, sizeof(readbuf))) {
760                         hcr = 0x1f; /* x8 SRAM */
761                         hw->isram16 = 0;
762
763                         hfa384x_copy_to_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS,
764                                             initseq, sizeof(initseq));
765                         hfa384x_corereset(hw, prism2_reset_holdtime,
766                                           prism2_reset_settletime, hcr);
767
768                         hfa384x_copy_to_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS,
769                                             initseq, sizeof(initseq));
770                         hfa384x_copy_from_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS,
771                                             readbuf, sizeof(initseq));
772                         WLAN_HEX_DUMP(2, "readback", readbuf, sizeof(readbuf));
773
774                         if (memcmp(initseq, readbuf, sizeof(readbuf))) {
775                                 WLAN_LOG_ERROR("Genesis mode failed\n");
776                                 result = -1;
777                                 goto done;
778                         }
779                 }
780
781                 /* Now we're in genesis mode */
782                 hw->dlstate = HFA384x_DLSTATE_GENESIS;
783                 goto done;
784         }
785
786         /* Retrieve the buffer loc&size and timeout */
787         if ( (result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER,
788                                 &(hw->bufinfo), sizeof(hw->bufinfo))) ) {
789                 goto done;
790         }
791         hw->bufinfo.page = hfa384x2host_16(hw->bufinfo.page);
792         hw->bufinfo.offset = hfa384x2host_16(hw->bufinfo.offset);
793         hw->bufinfo.len = hfa384x2host_16(hw->bufinfo.len);
794         if ( (result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME,
795                                 &(hw->dltimeout))) ) {
796                 goto done;
797         }
798         hw->dltimeout = hfa384x2host_16(hw->dltimeout);
799
800         /* Enable the aux port */
801         if ( (result = hfa384x_cmd_aux_enable(hw, 0)) ) {
802                 WLAN_LOG_DEBUG(1,"Aux enable failed, result=%d.\n", result);
803                 goto done;
804         }
805
806         /* Call the download(1,addr) function */
807         lowaddr = HFA384x_ADDR_CMD_MKOFF(exeaddr);
808         hiaddr =  HFA384x_ADDR_CMD_MKPAGE(exeaddr);
809
810         result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_RAM,
811                         lowaddr, hiaddr, 0);
812         if ( result == 0) {
813                 /* Set the download state */
814                 hw->dlstate = HFA384x_DLSTATE_RAMENABLED;
815         } else {
816                 WLAN_LOG_DEBUG(1,"cmd_download(0x%04x, 0x%04x) failed, result=%d.\n",
817                                 lowaddr,hiaddr, result);
818                 /* Disable  the aux port */
819                 hfa384x_cmd_aux_disable(hw);
820         }
821
822  done:
823         DBFEXIT;
824         return result;
825 }
826
827
828 /*----------------------------------------------------------------
829 * hfa384x_drvr_ramdl_disable
830 *
831 * Ends the ram download state.
832 *
833 * Arguments:
834 *       hw              device structure
835 *
836 * Returns:
837 *       0               success
838 *       >0              f/w reported error - f/w status code
839 *       <0              driver reported error
840 *
841 * Side effects:
842 *
843 * Call context:
844 *       process thread
845 ----------------------------------------------------------------*/
846 int hfa384x_drvr_ramdl_disable(hfa384x_t *hw)
847 {
848         DBFENTER;
849         /* Check that we're already in the download state */
850         if ( ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) &&
851              ( hw->dlstate != HFA384x_DLSTATE_GENESIS ) ) {
852                 return -EINVAL;
853         }
854
855         if (hw->dlstate == HFA384x_DLSTATE_GENESIS) {
856                 hfa384x_corereset(hw, prism2_reset_holdtime,
857                                   prism2_reset_settletime,
858                                   hw->isram16 ? 0x07: 0x17);
859                 goto done;
860         }
861
862         /* Disable the aux port */
863         hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0 , 0);
864
865  done:
866         hw->dlstate = HFA384x_DLSTATE_DISABLED;
867         hfa384x_cmd_aux_disable(hw);
868
869         DBFEXIT;
870         return 0;
871 }
872
873
874 /*----------------------------------------------------------------
875 * hfa384x_drvr_ramdl_write
876 *
877 * Performs a RAM download of a chunk of data. First checks to see
878 * that we're in the RAM download state, then uses the aux functions
879 * to 1) copy the data, 2) readback and compare.  The download
880 * state is unaffected.  When all data has been written using
881 * this function, call drvr_ramdl_disable() to end the download state
882 * and restart the MAC.
883 *
884 * Arguments:
885 *       hw              device structure
886 *       daddr           Card address to write to. (host order)
887 *       buf             Ptr to data to write.
888 *       len             Length of data (host order).
889 *
890 * Returns:
891 *       0               success
892 *       >0              f/w reported error - f/w status code
893 *       <0              driver reported error
894 *
895 * Side effects:
896 *
897 * Call context:
898 *       process thread
899 ----------------------------------------------------------------*/
900 int hfa384x_drvr_ramdl_write(hfa384x_t *hw, UINT32 daddr, void* buf, UINT32 len)
901 {
902         int             result = 0;
903         UINT8           *verbuf;
904         DBFENTER;
905         /* Check that we're in the ram download state */
906         if ( ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) &&
907              ( hw->dlstate != HFA384x_DLSTATE_GENESIS ) ) {
908                 return -EINVAL;
909         }
910
911         WLAN_LOG_INFO("Writing %d bytes to ram @0x%06x\n", len, daddr);
912 #if 0
913 WLAN_HEX_DUMP(1, "dldata", buf, len);
914 #endif
915         /* Copy the data via the aux port */
916         hfa384x_copy_to_aux(hw, daddr, HFA384x_AUX_CTL_EXTDS, buf, len);
917
918         /* Create a buffer for the verify */
919         verbuf = kmalloc(len, GFP_KERNEL);
920         if (verbuf == NULL ) return 1;
921
922         /* Read back and compare */
923         hfa384x_copy_from_aux(hw, daddr, HFA384x_AUX_CTL_EXTDS, verbuf, len);
924
925         if ( memcmp(buf, verbuf, len) ) {
926                 WLAN_LOG_DEBUG(1,"ramdl verify failed!\n");
927                 result = -EINVAL;
928         }
929
930         kfree_s(verbuf, len);
931         DBFEXIT;
932         return result;
933 }
934
935
936 /*----------------------------------------------------------------
937 * hfa384x_drvr_flashdl_enable
938 *
939 * Begins the flash download state.  Checks to see that we're not
940 * already in a download state and that a port isn't enabled.
941 * Sets the download state and retrieves the flash download
942 * buffer location, buffer size, and timeout length.
943 *
944 * Arguments:
945 *       hw              device structure
946 *
947 * Returns:
948 *       0               success
949 *       >0              f/w reported error - f/w status code
950 *       <0              driver reported error
951 *
952 * Side effects:
953 *
954 * Call context:
955 *       process thread
956 ----------------------------------------------------------------*/
957 int hfa384x_drvr_flashdl_enable(hfa384x_t *hw)
958 {
959         int             result = 0;
960         int             i;
961
962         DBFENTER;
963         /* Check that a port isn't active */
964         for ( i = 0; i < HFA384x_PORTID_MAX; i++) {
965                 if ( hw->port_enabled[i] ) {
966                         WLAN_LOG_DEBUG(1,"called when port enabled.\n");
967                         return -EINVAL;
968                 }
969         }
970
971         /* Check that we're not already in a download state */
972         if ( hw->dlstate != HFA384x_DLSTATE_DISABLED ) {
973                 return -EINVAL;
974         }
975
976         /* Retrieve the buffer loc&size and timeout */
977         if ( (result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER,
978                                 &(hw->bufinfo), sizeof(hw->bufinfo))) ) {
979                 return result;
980         }
981         hw->bufinfo.page = hfa384x2host_16(hw->bufinfo.page);
982         hw->bufinfo.offset = hfa384x2host_16(hw->bufinfo.offset);
983         hw->bufinfo.len = hfa384x2host_16(hw->bufinfo.len);
984         if ( (result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME,
985                                 &(hw->dltimeout))) ) {
986                 return result;
987         }
988         hw->dltimeout = hfa384x2host_16(hw->dltimeout);
989
990         /* Enable the aux port */
991         if ( (result = hfa384x_cmd_aux_enable(hw, 0)) ) {
992                 return result;
993         }
994
995         hw->dlstate = HFA384x_DLSTATE_FLASHENABLED;
996         DBFEXIT;
997         return result;
998 }
999
1000
1001 /*----------------------------------------------------------------
1002 * hfa384x_drvr_flashdl_disable
1003 *
1004 * Ends the flash download state.  Note that this will cause the MAC
1005 * firmware to restart.
1006 *
1007 * Arguments:
1008 *       hw              device structure
1009 *
1010 * Returns:
1011 *       0               success
1012 *       >0              f/w reported error - f/w status code
1013 *       <0              driver reported error
1014 *
1015 * Side effects:
1016 *
1017 * Call context:
1018 *       process thread
1019 ----------------------------------------------------------------*/
1020 int hfa384x_drvr_flashdl_disable(hfa384x_t *hw)
1021 {
1022         DBFENTER;
1023         /* Check that we're already in the download state */
1024         if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) {
1025                 return -EINVAL;
1026         }
1027
1028         /* There isn't much we can do at this point, so I don't */
1029         /*  bother  w/ the return value */
1030         hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0 , 0);
1031         hw->dlstate = HFA384x_DLSTATE_DISABLED;
1032
1033         /* Disable the aux port */
1034         hfa384x_cmd_aux_disable(hw);
1035
1036         DBFEXIT;
1037         return 0;
1038 }
1039
1040
1041 /*----------------------------------------------------------------
1042 * hfa384x_drvr_flashdl_write
1043 *
1044 * Performs a FLASH download of a chunk of data. First checks to see
1045 * that we're in the FLASH download state, then sets the download
1046 * mode, uses the aux functions to 1) copy the data to the flash
1047 * buffer, 2) sets the download 'write flash' mode, 3) readback and
1048 * compare.  Lather rinse, repeat as many times an necessary to get
1049 * all the given data into flash.
1050 * When all data has been written using this function (possibly
1051 * repeatedly), call drvr_flashdl_disable() to end the download state
1052 * and restart the MAC.
1053 *
1054 * Arguments:
1055 *       hw              device structure
1056 *       daddr           Card address to write to. (host order)
1057 *       buf             Ptr to data to write.
1058 *       len             Length of data (host order).
1059 *
1060 * Returns:
1061 *       0               success
1062 *       >0              f/w reported error - f/w status code
1063 *       <0              driver reported error
1064 *
1065 * Side effects:
1066 *
1067 * Call context:
1068 *       process thread
1069 ----------------------------------------------------------------*/
1070 int hfa384x_drvr_flashdl_write(hfa384x_t *hw, UINT32 daddr, void* buf, UINT32 len)
1071 {
1072         int             result = 0;
1073         UINT8           *verbuf;
1074         UINT32          dlbufaddr;
1075         UINT32          currlen;
1076         UINT32          currdaddr;
1077         UINT16          destlo;
1078         UINT16          desthi;
1079         int             nwrites;
1080         int             i;
1081
1082         DBFENTER;
1083         /* Check that we're in the flash download state */
1084         if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) {
1085                 return -EINVAL;
1086         }
1087
1088         WLAN_LOG_INFO("Download %d bytes to flash @0x%06x\n", len, daddr);
1089
1090         /* Need a flat address for arithmetic */
1091         dlbufaddr = HFA384x_ADDR_AUX_MKFLAT(
1092                         hw->bufinfo.page,
1093                         hw->bufinfo.offset);
1094         verbuf = kmalloc(hw->bufinfo.len, GFP_KERNEL);
1095
1096 #if 0
1097 WLAN_LOG_WARNING("dlbuf@0x%06lx len=%d to=%d\n", dlbufaddr, hw->bufinfo.len, hw->dltimeout);
1098 #endif
1099         /* Figure out how many times to to the flash prog */
1100         nwrites = len / hw->bufinfo.len;
1101         nwrites += (len % hw->bufinfo.len) ? 1 : 0;
1102
1103         if ( verbuf == NULL ) {
1104                 WLAN_LOG_ERROR("Failed to allocate flash verify buffer\n");
1105                 return 1;
1106         }
1107         /* For each */
1108         for ( i = 0; i < nwrites; i++) {
1109                 /* Get the dest address and len */
1110                 currlen = (len - (hw->bufinfo.len * i)) > hw->bufinfo.len ?
1111                                 hw->bufinfo.len :
1112                                 (len - (hw->bufinfo.len * i));
1113                 currdaddr = daddr + (hw->bufinfo.len * i);
1114                 destlo = HFA384x_ADDR_CMD_MKOFF(currdaddr);
1115                 desthi = HFA384x_ADDR_CMD_MKPAGE(currdaddr);
1116                 WLAN_LOG_INFO("Writing %d bytes to flash @0x%06x\n", currlen, currdaddr);
1117 #if 0
1118 WLAN_HEX_DUMP(1, "dldata", buf+(hw->bufinfo.len*i), currlen);
1119 #endif
1120                 /* Set the download mode */
1121                 result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_NV,
1122                                 destlo, desthi, currlen);
1123                 if ( result ) {
1124                         WLAN_LOG_ERROR("download(NV,lo=%x,hi=%x,len=%x) "
1125                                 "cmd failed, result=%d. Aborting d/l\n",
1126                                 destlo, desthi, currlen, result);
1127                         goto exit_proc;
1128                 }
1129                 /* copy the data to the flash buffer */
1130                 hfa384x_copy_to_aux(hw, dlbufaddr, HFA384x_AUX_CTL_EXTDS,
1131                                         buf+(hw->bufinfo.len*i), currlen);
1132                 /* set the download 'write flash' mode */
1133                 result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_NVWRITE, 0,0,0);
1134                 if ( result ) {
1135                         WLAN_LOG_ERROR(
1136                                 "download(NVWRITE,lo=%x,hi=%x,len=%x) "
1137                                 "cmd failed, result=%d. Aborting d/l\n",
1138                                 destlo, desthi, currlen, result);
1139                         goto exit_proc;
1140                 }
1141                 /* readback and compare, if fail...bail */
1142                 hfa384x_copy_from_aux(hw,
1143                                 currdaddr, HFA384x_AUX_CTL_NV,
1144                                 verbuf, currlen);
1145
1146                 if ( memcmp(buf+(hw->bufinfo.len*i), verbuf, currlen) ) {
1147                         return -EINVAL;
1148                 }
1149         }
1150
1151 exit_proc:
1152          /* DOH! This kfree's for you Mark :-) My forehead hurts... */
1153          kfree(verbuf);
1154
1155         /* Leave the firmware in the 'post-prog' mode.  flashdl_disable will */
1156         /*  actually disable programming mode.  Remember, that will cause the */
1157         /*  the firmware to effectively reset itself. */
1158
1159         DBFEXIT;
1160         return result;
1161 }
1162
1163
1164 /*----------------------------------------------------------------
1165 * hfa384x_cmd_initialize
1166 *
1167 * Issues the initialize command and sets the hw->state based
1168 * on the result.
1169 *
1170 * Arguments:
1171 *       hw              device structure
1172 *
1173 * Returns:
1174 *       0               success
1175 *       >0              f/w reported error - f/w status code
1176 *       <0              driver reported error
1177 *
1178 * Side effects:
1179 *
1180 * Call context:
1181 *       process thread
1182 ----------------------------------------------------------------*/
1183 int hfa384x_cmd_initialize(hfa384x_t *hw)
1184 {
1185         int result = 0;
1186         int i;
1187         hfa384x_metacmd_t cmd;
1188
1189         DBFENTER;
1190
1191         /* we don't want to be interrupted during the reset */
1192         hfa384x_setreg(hw, 0, HFA384x_INTEN);
1193         hfa384x_setreg(hw, 0xffff, HFA384x_EVACK);
1194
1195         cmd.cmd = HFA384x_CMDCODE_INIT;
1196         cmd.parm0 = 0;
1197         cmd.parm1 = 0;
1198         cmd.parm2 = 0;
1199
1200         spin_lock_bh(&hw->cmdlock);
1201         result = hfa384x_docmd_wait(hw, &cmd);
1202         spin_unlock_bh(&hw->cmdlock);
1203
1204         if ( result == 0 ) {
1205                 for ( i = 0; i < HFA384x_NUMPORTS_MAX; i++) {
1206                         hw->port_enabled[i] = 0;
1207                 }
1208         }
1209
1210         hw->link_status = HFA384x_LINK_NOTCONNECTED;
1211
1212         DBFEXIT;
1213         return result;
1214 }
1215
1216
1217 /*----------------------------------------------------------------
1218 * hfa384x_drvr_commtallies
1219 *
1220 * Send a commtallies inquiry to the MAC.  Note that this is an async
1221 * call that will result in an info frame arriving sometime later.
1222 *
1223 * Arguments:
1224 *       hw              device structure
1225 *
1226 * Returns:
1227 *       zero            success.
1228 *
1229 * Side effects:
1230 *
1231 * Call context:
1232 *       process
1233 ----------------------------------------------------------------*/
1234 int hfa384x_drvr_commtallies( hfa384x_t *hw )
1235 {
1236         hfa384x_metacmd_t cmd;
1237         int result;
1238
1239         DBFENTER;
1240
1241         cmd.cmd = HFA384x_CMDCODE_INQ;
1242         cmd.parm0 = HFA384x_IT_COMMTALLIES;
1243         cmd.parm1 = 0;
1244         cmd.parm2 = 0;
1245
1246         spin_lock_bh(&hw->cmdlock);
1247         result = hfa384x_docmd_wait(hw, &cmd);
1248         spin_unlock_bh(&hw->cmdlock);
1249
1250         DBFEXIT;
1251         return result;
1252 }
1253
1254
1255 /*----------------------------------------------------------------
1256 * hfa384x_drvr_enable
1257 *
1258 * Issues the enable command to enable communications on one of
1259 * the MACs 'ports'.  Only macport 0 is valid  for stations.
1260 * APs may also enable macports 1-6.  Only ports that are currently
1261 * disabled may be enabled.
1262 *
1263 * Arguments:
1264 *       hw              device structure
1265 *       macport         MAC port number
1266 *
1267 * Returns:
1268 *       0               success
1269 *       >0              f/w reported failure - f/w status code
1270 *       <0              driver reported error (timeout|bad arg)
1271 *
1272 * Side effects:
1273 *
1274 * Call context:
1275 *       process thread
1276 ----------------------------------------------------------------*/
1277 int hfa384x_drvr_enable(hfa384x_t *hw, UINT16 macport)
1278 {
1279         int     result = 0;
1280
1281         DBFENTER;
1282         if ((!hw->isap && macport != 0) ||
1283             (hw->isap && !(macport <= HFA384x_PORTID_MAX)) ||
1284             (hw->port_enabled[macport]) ){
1285                 result = -EINVAL;
1286         } else {
1287                 result = hfa384x_cmd_enable(hw, macport);
1288                 if ( result == 0 ) {
1289                         hw->port_enabled[macport] = 1;
1290                 }
1291         }
1292         DBFEXIT;
1293         return result;
1294 }
1295
1296
1297 /*----------------------------------------------------------------
1298 * hfa384x_cmd_enable
1299 *
1300 * Issues the the enable command to enable communications on one of the
1301 * MACs 'ports'.
1302 *
1303 * Arguments:
1304 *       hw              device structure
1305 *       macport         MAC port number
1306 *
1307 * Returns:
1308 *       0               success
1309 *       >0              f/w reported failure - f/w status code
1310 *       <0              driver reported error (timeout|bad arg)
1311 *
1312 * Side effects:
1313 *
1314 * Call context:
1315 *       process thread
1316 ----------------------------------------------------------------*/
1317 int hfa384x_cmd_enable(hfa384x_t *hw, UINT16 macport)
1318 {
1319         int     result = 0;
1320         hfa384x_metacmd_t cmd;
1321
1322         DBFENTER;
1323
1324         cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ENABLE) |
1325                   HFA384x_CMD_MACPORT_SET(macport);
1326         cmd.parm0 = 0;
1327         cmd.parm1 = 0;
1328         cmd.parm2 = 0;
1329
1330         spin_lock_bh(&hw->cmdlock);
1331         result = hfa384x_docmd_wait(hw, &cmd);
1332         spin_unlock_bh(&hw->cmdlock);
1333
1334         DBFEXIT;
1335         return result;
1336 }
1337
1338
1339 /*----------------------------------------------------------------
1340 * hfa384x_drvr_disable
1341 *
1342 * Issues the disable command to stop communications on one of
1343 * the MACs 'ports'.  Only macport 0 is valid  for stations.
1344 * APs may also disable macports 1-6.  Only ports that have been
1345 * previously enabled may be disabled.
1346 *
1347 * Arguments:
1348 *       hw              device structure
1349 *       macport         MAC port number (host order)
1350 *
1351 * Returns:
1352 *       0               success
1353 *       >0              f/w reported failure - f/w status code
1354 *       <0              driver reported error (timeout|bad arg)
1355 *
1356 * Side effects:
1357 *
1358 * Call context:
1359 *       process thread
1360 ----------------------------------------------------------------*/
1361 int hfa384x_drvr_disable(hfa384x_t *hw, UINT16 macport)
1362 {
1363         int     result = 0;
1364
1365         DBFENTER;
1366         if ((!hw->isap && macport != 0) ||
1367             (hw->isap && !(macport <= HFA384x_PORTID_MAX)) ||
1368             !(hw->port_enabled[macport]) ){
1369                 result = -EINVAL;
1370         } else {
1371                 result = hfa384x_cmd_disable(hw, macport);
1372                 if ( result == 0 ) {
1373                         hw->port_enabled[macport] = 0;
1374                 }
1375         }
1376         DBFEXIT;
1377         return result;
1378 }
1379
1380
1381 /*----------------------------------------------------------------
1382 * hfa384x_cmd_disable
1383 *
1384 * Issues the command to disable a port.
1385 *
1386 * Arguments:
1387 *       hw              device structure
1388 *       macport         MAC port number (host order)
1389 *
1390 * Returns:
1391 *       0               success
1392 *       >0              f/w reported failure - f/w status code
1393 *       <0              driver reported error (timeout|bad arg)
1394 *
1395 * Side effects:
1396 *
1397 * Call context:
1398 *       process thread
1399 ----------------------------------------------------------------*/
1400 int hfa384x_cmd_disable(hfa384x_t *hw, UINT16 macport)
1401 {
1402         int     result = 0;
1403         hfa384x_metacmd_t cmd;
1404
1405         DBFENTER;
1406
1407         cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DISABLE) |
1408                   HFA384x_CMD_MACPORT_SET(macport);
1409         cmd.parm0 = 0;
1410         cmd.parm1 = 0;
1411         cmd.parm2 = 0;
1412
1413         spin_lock_bh(&hw->cmdlock);
1414         result = hfa384x_docmd_wait(hw, &cmd);
1415         spin_unlock_bh(&hw->cmdlock);
1416
1417         DBFEXIT;
1418         return result;
1419 }
1420
1421
1422 /*----------------------------------------------------------------
1423 * hfa384x_cmd_diagnose
1424 *
1425 * Issues the diagnose command to test the: register interface,
1426 * MAC controller (including loopback), External RAM, Non-volatile
1427 * memory integrity, and synthesizers.  Following execution of this
1428 * command, MAC/firmware are in the 'initial state'.  Therefore,
1429 * the Initialize command should be issued after successful
1430 * completion of this command.  This function may only be called
1431 * when the MAC is in the 'communication disabled' state.
1432 *
1433 * Arguments:
1434 *       hw              device structure
1435 *
1436 * Returns:
1437 *       0               success
1438 *       >0              f/w reported failure - f/w status code
1439 *       <0              driver reported error (timeout|bad arg)
1440 *
1441 * Side effects:
1442 *
1443 * Call context:
1444 *       process thread
1445 ----------------------------------------------------------------*/
1446 #define DIAG_PATTERNA ((UINT16)0xaaaa)
1447 #define DIAG_PATTERNB ((UINT16)0x5555)
1448
1449 int hfa384x_cmd_diagnose(hfa384x_t *hw)
1450 {
1451         int     result = 0;
1452         hfa384x_metacmd_t cmd;
1453
1454         DBFENTER;
1455
1456         cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DIAG);
1457         cmd.parm0 = DIAG_PATTERNA;
1458         cmd.parm1 = DIAG_PATTERNB;
1459         cmd.parm2 = 0;
1460
1461         spin_lock_bh(&hw->cmdlock);
1462         result = hfa384x_docmd_wait(hw, &cmd);
1463         spin_unlock_bh(&hw->cmdlock);
1464
1465         DBFEXIT;
1466         return result;
1467 }
1468
1469
1470 /*----------------------------------------------------------------
1471 * hfa384x_cmd_allocate
1472 *
1473 * Issues the allocate command instructing the firmware to allocate
1474 * a 'frame structure buffer' in MAC controller RAM.  This command
1475 * does not provide the result, it only initiates one of the f/w's
1476 * asynchronous processes to construct the buffer.  When the
1477 * allocation is complete, it will be indicated via the Alloc
1478 * bit in the EvStat register and the FID identifying the allocated
1479 * space will be available from the AllocFID register.  Some care
1480 * should be taken when waiting for the Alloc event.  If a Tx or
1481 * Notify command w/ Reclaim has been previously executed, it's
1482 * possible the first Alloc event after execution of this command
1483 * will be for the reclaimed buffer and not the one you asked for.
1484 * This case must be handled in the Alloc event handler.
1485 *
1486 * Arguments:
1487 *       hw              device structure
1488 *       len             allocation length, must be an even value
1489 *                       in the range [4-2400]. (host order)
1490 *
1491 * Returns:
1492 *       0               success
1493 *       >0              f/w reported failure - f/w status code
1494 *       <0              driver reported error (timeout|bad arg)
1495 *
1496 * Side effects:
1497 *
1498 * Call context:
1499 *       process thread
1500 ----------------------------------------------------------------*/
1501 int hfa384x_cmd_allocate(hfa384x_t *hw, UINT16 len)
1502 {
1503         int     result = 0;
1504         hfa384x_metacmd_t cmd;
1505
1506         DBFENTER;
1507
1508         if ( (len % 2) ||
1509              len < HFA384x_CMD_ALLOC_LEN_MIN ||
1510              len > HFA384x_CMD_ALLOC_LEN_MAX ) {
1511                 result = -EINVAL;
1512         } else {
1513                 cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ALLOC);
1514                 cmd.parm0 = len;
1515                 cmd.parm1 = 0;
1516                 cmd.parm2 = 0;
1517
1518                 spin_lock_bh(&hw->cmdlock);
1519                 result = hfa384x_docmd_wait(hw, &cmd);
1520                 spin_unlock_bh(&hw->cmdlock);
1521         }
1522         DBFEXIT;
1523         return result;
1524 }
1525
1526
1527 /*----------------------------------------------------------------
1528 * hfa384x_cmd_transmit
1529 *
1530 * Instructs the firmware to transmit a frame previously copied
1531 * to a given buffer.  This function returns immediately, the Tx
1532 * results are available via the Tx or TxExc events (if the frame
1533 * control bits are set).  The reclaim argument specifies if the
1534 * FID passed will be used by the f/w tx process or returned for
1535 * use w/ another transmit command.  If reclaim is set, expect an
1536 * Alloc event signalling the availibility of the FID for reuse.
1537 *
1538 * NOTE: hw->cmdlock MUST BE HELD before calling this function!
1539 *
1540 * Arguments:
1541 *       hw              device structure
1542 *       reclaim         [0|1] indicates whether the given FID will
1543 *                       be handed back (via Alloc event) for reuse.
1544 *                       (host order)
1545 *       qos             [0-3] Value to put in the QoS field of the
1546 *                       tx command, identifies a queue to place the
1547 *                       outgoing frame in.
1548 *                       (host order)
1549 *       fid             FID of buffer containing the frame that was
1550 *                       previously copied to MAC memory via the bap.
1551 *                       (host order)
1552 *
1553 * Returns:
1554 *       0               success
1555 *       >0              f/w reported failure - f/w status code
1556 *       <0              driver reported error (timeout|bad arg)
1557 *
1558 * Side effects:
1559 *       hw->resp0 will contain the FID being used by async tx
1560 *       process.  If reclaim==0, resp0 will be the same as the fid
1561 *       argument.  If reclaim==1, resp0 will be the different and
1562 *       is the value to watch for in the Tx|TxExc to indicate completion
1563 *       of the frame passed in fid.
1564 *
1565 * Call context:
1566 *       process thread
1567 ----------------------------------------------------------------*/
1568 int hfa384x_cmd_transmit(hfa384x_t *hw, UINT16 reclaim, UINT16 qos, UINT16 fid)
1569 {
1570         int     result = 0;
1571         hfa384x_metacmd_t cmd;
1572
1573         DBFENTER;
1574         cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_TX) |
1575                 HFA384x_CMD_RECL_SET(reclaim) |
1576                 HFA384x_CMD_QOS_SET(qos);
1577         cmd.parm0 = fid;
1578         cmd.parm1 = 0;
1579         cmd.parm2 = 0;
1580
1581         result = hfa384x_docmd_wait(hw, &cmd);
1582
1583         DBFEXIT;
1584         return result;
1585 }
1586
1587
1588 /*----------------------------------------------------------------
1589 * hfa384x_cmd_clearpersist
1590 *
1591 * Instructs the firmware to clear the persistence bit in a given
1592 * FID.  This has the effect of telling the firmware to drop the
1593 * persistent frame.  The FID must be one that was previously used
1594 * to transmit a PRST frame.
1595 *
1596 * Arguments:
1597 *       hw              device structure
1598 *       fid             FID of the persistent frame (host order)
1599 *
1600 * Returns:
1601 *       0               success
1602 *       >0              f/w reported failure - f/w status code
1603 *       <0              driver reported error (timeout|bad arg)
1604 *
1605 * Side effects:
1606 *
1607 * Call context:
1608 *       process thread
1609 ----------------------------------------------------------------*/
1610 int hfa384x_cmd_clearpersist(hfa384x_t *hw, UINT16 fid)
1611 {
1612         int     result = 0;
1613         hfa384x_metacmd_t cmd;
1614
1615         DBFENTER;
1616
1617         cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_CLRPRST);
1618         cmd.parm0 = fid;
1619         cmd.parm1 = 0;
1620         cmd.parm2 = 0;
1621
1622         spin_lock_bh(&hw->cmdlock);
1623         result = hfa384x_docmd_wait(hw, &cmd);
1624         spin_unlock_bh(&hw->cmdlock);
1625
1626         DBFEXIT;
1627         return result;
1628 }
1629
1630 /*----------------------------------------------------------------
1631 * hfa384x_cmd_notify
1632 *
1633 * Sends an info frame to the firmware to alter the behavior
1634 * of the f/w asynch processes.  Can only be called when the MAC
1635 * is in the enabled state.
1636 *
1637 * Arguments:
1638 *       hw              device structure
1639 *       reclaim         [0|1] indicates whether the given FID will
1640 *                       be handed back (via Alloc event) for reuse.
1641 *                       (host order)
1642 *       fid             FID of buffer containing the frame that was
1643 *                       previously copied to MAC memory via the bap.
1644 *                       (host order)
1645 *
1646 * Returns:
1647 *       0               success
1648 *       >0              f/w reported failure - f/w status code
1649 *       <0              driver reported error (timeout|bad arg)
1650 *
1651 * Side effects:
1652 *       hw->resp0 will contain the FID being used by async notify
1653 *       process.  If reclaim==0, resp0 will be the same as the fid
1654 *       argument.  If reclaim==1, resp0 will be the different.
1655 *
1656 * Call context:
1657 *       process thread
1658 ----------------------------------------------------------------*/
1659 int hfa384x_cmd_notify(hfa384x_t *hw, UINT16 reclaim, UINT16 fid,
1660                        void *buf, UINT16 len)
1661 {
1662         int     result = 0;
1663         hfa384x_metacmd_t cmd;
1664
1665         DBFENTER;
1666         cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_NOTIFY) |
1667                 HFA384x_CMD_RECL_SET(reclaim);
1668         cmd.parm0 = fid;
1669         cmd.parm1 = 0;
1670         cmd.parm2 = 0;
1671
1672         spin_lock_bh(&hw->cmdlock);
1673
1674         /* Copy the record to FID */
1675         result = hfa384x_copy_to_bap(hw, HFA384x_BAP_PROC, hw->infofid, 0, buf, len);
1676         if ( result ) {
1677                 WLAN_LOG_DEBUG(1,
1678                         "copy_to_bap(%04x, 0, %d) failed, result=0x%x\n",
1679                         hw->infofid, len, result);
1680                 result = -EIO;
1681                 goto failed;
1682         }
1683
1684         result = hfa384x_docmd_wait(hw, &cmd);
1685
1686  failed:
1687         spin_unlock_bh(&hw->cmdlock);
1688
1689         DBFEXIT;
1690         return result;
1691 }
1692
1693
1694 #if 0
1695 /*----------------------------------------------------------------
1696 * hfa384x_cmd_inquiry
1697 *
1698 * Requests an info frame from the firmware.  The info frame will
1699 * be delivered asynchronously via the Info event.
1700 *
1701 * Arguments:
1702 *       hw              device structure
1703 *       fid             FID of the info frame requested. (host order)
1704 *
1705 * Returns:
1706 *       0               success
1707 *       >0              f/w reported failure - f/w status code
1708 *       <0              driver reported error (timeout|bad arg)
1709 *
1710 * Side effects:
1711 *
1712 * Call context:
1713 *       process thread
1714 ----------------------------------------------------------------*/
1715 static int hfa384x_cmd_inquiry(hfa384x_t *hw, UINT16 fid)
1716 {
1717         int     result = 0;
1718         hfa384x_metacmd_t cmd;
1719
1720         DBFENTER;
1721
1722         cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_INQ);
1723         cmd.parm0 = fid;
1724         cmd.parm1 = 0;
1725         cmd.parm2 = 0;
1726
1727         spin_lock_bh(&hw->cmdlock);
1728         result = hfa384x_docmd_wait(hw, &cmd);
1729         spin_unlock_bh(&hw->cmdlock);
1730
1731         DBFEXIT;
1732         return result;
1733 }
1734 #endif
1735
1736
1737 /*----------------------------------------------------------------
1738 * hfa384x_cmd_access
1739 *
1740 * Requests that a given record be copied to/from the record
1741 * buffer.  If we're writing from the record buffer, the contents
1742 * must previously have been written to the record buffer via the
1743 * bap.  If we're reading into the record buffer, the record can
1744 * be read out of the record buffer after this call.
1745 *
1746 * Arguments:
1747 *       hw              device structure
1748 *       write           [0|1] copy the record buffer to the given
1749 *                       configuration record. (host order)
1750 *       rid             RID of the record to read/write. (host order)
1751 *       buf             host side record buffer.  Upon return it will
1752 *                       contain the body portion of the record (minus the
1753 *                       RID and len).
1754 *       len             buffer length (in bytes, should match record length)
1755 *
1756 * Returns:
1757 *       0               success
1758 *       >0              f/w reported failure - f/w status code
1759 *       <0              driver reported error (timeout|bad arg)
1760 *
1761 * Side effects:
1762 *
1763 * Call context:
1764 *       process thread
1765 ----------------------------------------------------------------*/
1766 int hfa384x_cmd_access(hfa384x_t *hw, UINT16 write, UINT16 rid,
1767                        void* buf, UINT16 len)
1768 {
1769         int     result = 0;
1770         hfa384x_metacmd_t cmd;
1771         hfa384x_rec_t   rec;
1772
1773         DBFENTER;
1774
1775 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0))
1776         /* This should NOT be called in interrupt context! */
1777         if (in_irq()) {
1778                 WLAN_LOG_ERROR("Krap, in Interrupt context!");
1779 #ifdef WLAN_INCLUDE_DEBUG
1780                 BUG();
1781 #endif
1782         }
1783 #endif
1784         spin_lock_bh(&hw->cmdlock);
1785
1786         if (write) {
1787                 rec.rid = host2hfa384x_16(rid);
1788                 rec.reclen = host2hfa384x_16((len/2) + 1); /* note conversion to words, +1 for rid field */
1789                 /* write the record */
1790                 result = hfa384x_copy_to_bap4( hw, HFA384x_BAP_PROC, rid, 0,
1791                                                &rec, sizeof(rec),
1792                                                buf, len,
1793                                                NULL, 0, NULL, 0);
1794                 if ( result ) {
1795                         WLAN_LOG_DEBUG(3,"Failure writing record header+data\n");
1796                         goto fail;
1797                 }
1798
1799         }
1800
1801         cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ACCESS) |
1802                 HFA384x_CMD_WRITE_SET(write);
1803         cmd.parm0 = rid;
1804         cmd.parm1 = 0;
1805         cmd.parm2 = 0;
1806
1807         result = hfa384x_docmd_wait(hw, &cmd);
1808         if ( result ) {
1809                 WLAN_LOG_ERROR("Call to hfa384x_docmd_wait failed (%d %d)\n",
1810                                 result, cmd.result.resp0);
1811                 goto fail;
1812         }
1813
1814         if (!write) {
1815                 result = hfa384x_copy_from_bap( hw, HFA384x_BAP_PROC, rid, 0, &rec, sizeof(rec));
1816                 if ( result ) {
1817                         WLAN_LOG_DEBUG(3,"Call to hfa384x_copy_from_bap failed\n");
1818                         goto fail;
1819                 }
1820
1821                 /* Validate the record length */
1822                 if ( ((hfa384x2host_16(rec.reclen)-1)*2) != len ) {  /* note body len calculation in bytes */
1823                         WLAN_LOG_DEBUG(1, "RID len mismatch, rid=0x%04x hlen=%d fwlen=%d\n",
1824                                         rid, len, (hfa384x2host_16(rec.reclen)-1)*2);
1825                         result = -ENODATA;
1826                         goto fail;
1827                 }
1828
1829                 result = hfa384x_copy_from_bap( hw, HFA384x_BAP_PROC, rid, sizeof(rec), buf, len);
1830
1831         }
1832
1833  fail:
1834         spin_unlock_bh(&hw->cmdlock);
1835         DBFEXIT;
1836         return result;
1837 }
1838
1839
1840 /*----------------------------------------------------------------
1841 * hfa384x_cmd_monitor
1842 *
1843 * Enables the 'monitor mode' of the MAC.  Here's the description of
1844 * monitor mode that I've received thus far:
1845 *
1846 *  "The "monitor mode" of operation is that the MAC passes all
1847 *  frames for which the PLCP checks are correct. All received
1848 *  MPDUs are passed to the host with MAC Port = 7, with a
1849 *  receive status of good, FCS error, or undecryptable. Passing
1850 *  certain MPDUs is a violation of the 802.11 standard, but useful
1851 *  for a debugging tool."  Normal communication is not possible
1852 *  while monitor mode is enabled.
1853 *
1854 * Arguments:
1855 *       hw              device structure
1856 *       enable          a code (0x0b|0x0f) that enables/disables
1857 *                       monitor mode. (host order)
1858 *
1859 * Returns:
1860 *       0               success
1861 *       >0              f/w reported failure - f/w status code
1862 *       <0              driver reported error (timeout|bad arg)
1863 *
1864 * Side effects:
1865 *
1866 * Call context:
1867 *       process thread
1868 ----------------------------------------------------------------*/
1869 int hfa384x_cmd_monitor(hfa384x_t *hw, UINT16 enable)
1870 {
1871         int     result = 0;
1872         hfa384x_metacmd_t cmd;
1873
1874         DBFENTER;
1875
1876         cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_MONITOR) |
1877                 HFA384x_CMD_AINFO_SET(enable);
1878         cmd.parm0 = 0;
1879         cmd.parm1 = 0;
1880         cmd.parm2 = 0;
1881
1882         spin_lock_bh(&hw->cmdlock);
1883         result = hfa384x_docmd_wait(hw, &cmd);
1884         spin_unlock_bh(&hw->cmdlock);
1885
1886         DBFEXIT;
1887         return result;
1888 }
1889
1890
1891 /*----------------------------------------------------------------
1892 * hfa384x_cmd_download
1893 *
1894 * Sets the controls for the MAC controller code/data download
1895 * process.  The arguments set the mode and address associated
1896 * with a download.  Note that the aux registers should be enabled
1897 * prior to setting one of the download enable modes.
1898 *
1899 * Arguments:
1900 *       hw              device structure
1901 *       mode            0 - Disable programming and begin code exec
1902 *                       1 - Enable volatile mem programming
1903 *                       2 - Enable non-volatile mem programming
1904 *                       3 - Program non-volatile section from NV download
1905 *                           buffer.
1906 *                       (host order)
1907 *       lowaddr
1908 *       highaddr        For mode 1, sets the high & low order bits of
1909 *                       the "destination address".  This address will be
1910 *                       the execution start address when download is
1911 *                       subsequently disabled.
1912 *                       For mode 2, sets the high & low order bits of
1913 *                       the destination in NV ram.
1914 *                       For modes 0 & 3, should be zero. (host order)
1915 *                       NOTE: these address args are in CMD format
1916 *       codelen         Length of the data to write in mode 2,
1917 *                       zero otherwise. (host order)
1918 *
1919 * Returns:
1920 *       0               success
1921 *       >0              f/w reported failure - f/w status code
1922 *       <0              driver reported error (timeout|bad arg)
1923 *
1924 * Side effects:
1925 *
1926 * Call context:
1927 *       process thread
1928 ----------------------------------------------------------------*/
1929 int hfa384x_cmd_download(hfa384x_t *hw, UINT16 mode, UINT16 lowaddr,
1930                                 UINT16 highaddr, UINT16 codelen)
1931 {
1932         int     result = 0;
1933         hfa384x_metacmd_t cmd;
1934
1935         DBFENTER;
1936
1937         cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DOWNLD) |
1938                 HFA384x_CMD_PROGMODE_SET(mode);
1939         cmd.parm0 = lowaddr;
1940         cmd.parm1 = highaddr;
1941         cmd.parm2 = codelen;
1942
1943         spin_lock_bh(&hw->cmdlock);
1944         result = hfa384x_dl_docmd_wait(hw, &cmd);
1945         spin_unlock_bh(&hw->cmdlock);
1946
1947         DBFEXIT;
1948         return result;
1949 }
1950
1951
1952 /*----------------------------------------------------------------
1953 * hfa384x_cmd_aux_enable
1954 *
1955 * Goes through the process of enabling the auxilary port.  This
1956 * is necessary prior to raw reads/writes to card data space.
1957 * Direct access to the card data space is only used for downloading
1958 * code and debugging.
1959 * Note that a call to this function is required before attempting
1960 * a download.
1961 *
1962 * Arguments:
1963 *       hw              device structure
1964 *
1965 * Returns:
1966 *       0               success
1967 *       >0              f/w reported failure - f/w status code
1968 *       <0              driver reported error (timeout)
1969 *
1970 * Side effects:
1971 *
1972 * Call context:
1973 *       process thread
1974 ----------------------------------------------------------------*/
1975 int hfa384x_cmd_aux_enable(hfa384x_t *hw, int force)
1976 {
1977         int             result = -ETIMEDOUT;
1978         unsigned long   flags;
1979         UINT32          retries_remaining;
1980         UINT16          reg;
1981         UINT            auxen_mirror = hw->auxen;
1982
1983         DBFENTER;
1984
1985         /* Check for existing enable */
1986         if ( hw->auxen ) {
1987                 hw->auxen++;
1988                 return 0;
1989         }
1990
1991         /* acquire the lock */
1992         spin_lock_irqsave( &(hw->cmdlock), flags);
1993         /* wait for cmd register busy bit to clear */
1994         retries_remaining = 100000;
1995         do {
1996                 reg = hfa384x_getreg(hw, HFA384x_CMD);
1997                 udelay(10);
1998         }
1999         while (HFA384x_CMD_ISBUSY(reg) && --retries_remaining);
2000         if (retries_remaining != 0) {
2001                 /* busy bit clear, it's OK to write to ParamX regs */
2002                 hfa384x_setreg(hw, HFA384x_AUXPW0,
2003                         HFA384x_PARAM0);
2004                 hfa384x_setreg(hw, HFA384x_AUXPW1,
2005                         HFA384x_PARAM1);
2006                 hfa384x_setreg(hw, HFA384x_AUXPW2,
2007                         HFA384x_PARAM2);
2008
2009                 /* Set the aux enable in the Control register */
2010                 hfa384x_setreg(hw, HFA384x_CONTROL_AUX_DOENABLE,
2011                         HFA384x_CONTROL);
2012
2013                 /* Now wait for completion */
2014                 retries_remaining = 100000;
2015                 do {
2016                         reg = hfa384x_getreg(hw, HFA384x_CONTROL);
2017                         udelay(10);
2018                 }
2019                 while ( ((reg & (BIT14|BIT15)) != HFA384x_CONTROL_AUX_ISENABLED) &&
2020                         --retries_remaining );
2021                 if (retries_remaining != 0) {
2022                         result = 0;
2023                         hw->auxen++;
2024                 }
2025         }
2026
2027         /* Force it enabled even if the command failed, if told.. */
2028         if ((hw->auxen == auxen_mirror) && force)
2029                 hw->auxen++;
2030
2031         spin_unlock_irqrestore( &(hw->cmdlock), flags);
2032         DBFEXIT;
2033         return result;
2034 }
2035
2036
2037 /*----------------------------------------------------------------
2038 * hfa384x_cmd_aux_disable
2039 *
2040 * Goes through the process of disabling the auxilary port
2041 * enabled with aux_enable().
2042 *
2043 * Arguments:
2044 *       hw              device structure
2045 *
2046 * Returns:
2047 *       0               success
2048 *       >0              f/w reported failure - f/w status code
2049 *       <0              driver reported error (timeout)
2050 *
2051 * Side effects:
2052 *
2053 * Call context:
2054 *       process thread
2055 ----------------------------------------------------------------*/
2056 int hfa384x_cmd_aux_disable(hfa384x_t *hw)
2057 {
2058         int             result = -ETIMEDOUT;
2059         unsigned long   timeout;
2060         UINT16          reg = 0;
2061
2062         DBFENTER;
2063
2064         /* See if there's more than one enable */
2065         if (hw->auxen) hw->auxen--;
2066         if (hw->auxen) return 0;
2067
2068         /* Clear the aux enable in the Control register */
2069         hfa384x_setreg(hw, 0, HFA384x_PARAM0);
2070         hfa384x_setreg(hw, 0, HFA384x_PARAM1);
2071         hfa384x_setreg(hw, 0, HFA384x_PARAM2);
2072         hfa384x_setreg(hw, HFA384x_CONTROL_AUX_DODISABLE,
2073                 HFA384x_CONTROL);
2074
2075         /* Now wait for completion */
2076         timeout = jiffies + 1*HZ;
2077         reg = hfa384x_getreg(hw, HFA384x_CONTROL);
2078         while ( ((reg & (BIT14|BIT15)) != HFA384x_CONTROL_AUX_ISDISABLED) &&
2079                 time_before(jiffies,timeout) ){
2080                 udelay(10);
2081                 reg = hfa384x_getreg(hw, HFA384x_CONTROL);
2082         }
2083         if ((reg & (BIT14|BIT15)) == HFA384x_CONTROL_AUX_ISDISABLED ) {
2084                 result = 0;
2085         }
2086         DBFEXIT;
2087         return result;
2088 }
2089
2090 /*----------------------------------------------------------------
2091 * hfa384x_drvr_low_level
2092 *
2093 * Write test commands to the card.  Some test commands don't make
2094 * sense without prior set-up.  For example, continous TX isn't very
2095 * useful until you set the channel.  That functionality should be
2096 *
2097 * Side effects:
2098 *
2099 * Call context:
2100 *      process thread
2101 * -----------------------------------------------------------------*/
2102 int hfa384x_drvr_low_level(hfa384x_t *hw, hfa384x_metacmd_t *cmd)
2103 {
2104         int             result = 0;
2105         DBFENTER;
2106
2107         /* Do i need a host2hfa... conversion ? */
2108 #if 0
2109         printk(KERN_INFO "%#x %#x %#x %#x\n", cmd->cmd, cmd->parm0, cmd->parm1, cmd->parm2);
2110 #endif
2111         spin_lock_bh(&hw->cmdlock);
2112         result = hfa384x_docmd_wait(hw, cmd);
2113         spin_unlock_bh(&hw->cmdlock);
2114
2115         DBFEXIT;
2116         return result;
2117 }
2118
2119
2120 /* TODO: determine if these will ever be needed */
2121 #if 0
2122 int hfa384x_cmd_readmif(hfa384x_t *hw)
2123 {
2124         DBFENTER;
2125         DBFEXIT;
2126         return 0;
2127 }
2128
2129
2130 int hfa384x_cmd_writemif(hfa384x_t *hw)
2131 {
2132         DBFENTER;
2133         DBFEXIT;
2134         return 0;
2135 }
2136 #endif
2137
2138 /*----------------------------------------------------------------
2139 * hfa384x_drvr_mmi_read
2140 *
2141 * Read mmi registers.  mmi is intersil-speak for the baseband
2142 * processor registers.
2143 *
2144 * Arguments:
2145 *       hw              device structure
2146 *       register        The test register to be accessed (must be even #).
2147 *
2148 * Returns:
2149 *       0               success
2150 *       >0              f/w reported error - f/w status code
2151 *       <0              driver reported error
2152 *
2153 * Side effects:
2154 *
2155 * Call context:
2156 *       process thread
2157 ----------------------------------------------------------------*/
2158 int hfa384x_drvr_mmi_read(hfa384x_t *hw, UINT32 addr, UINT32 *resp)
2159 {
2160         int             result = 0;
2161         hfa384x_metacmd_t cmd;
2162
2163         DBFENTER;
2164         cmd.cmd = (UINT16) 0x30;
2165         cmd.parm0 = (UINT16) addr;
2166         cmd.parm1 = 0;
2167         cmd.parm2 = 0;
2168
2169         /* Do i need a host2hfa... conversion ? */
2170         spin_lock_bh(&hw->cmdlock);
2171         result = hfa384x_docmd_wait(hw, &cmd);
2172         spin_unlock_bh(&hw->cmdlock);
2173
2174         *resp = (UINT32) cmd.result.resp0;
2175
2176         DBFEXIT;
2177         return result;
2178 }
2179
2180 /*----------------------------------------------------------------
2181 * hfa384x_drvr_mmi_write
2182 *
2183 * Read mmi registers.  mmi is intersil-speak for the baseband
2184 * processor registers.
2185 *
2186 * Arguments:
2187 *       hw              device structure
2188 *       addr            The test register to be accessed (must be even #).
2189 *       data            The data value to write to the register.
2190 *
2191 * Returns:
2192 *       0               success
2193 *       >0              f/w reported error - f/w status code
2194 *       <0              driver reported error
2195 *
2196 * Side effects:
2197 *
2198 * Call context:
2199 *       process thread
2200 ----------------------------------------------------------------*/
2201
2202 int
2203 hfa384x_drvr_mmi_write(hfa384x_t *hw, UINT32 addr, UINT32 data)
2204 {
2205         int             result = 0;
2206         hfa384x_metacmd_t cmd;
2207
2208         DBFENTER;
2209         cmd.cmd = (UINT16) 0x31;
2210         cmd.parm0 = (UINT16) addr;
2211         cmd.parm1 = (UINT16) data;
2212         cmd.parm2 = 0;
2213
2214         WLAN_LOG_DEBUG(1,"mmi write : addr = 0x%08x\n", addr);
2215         WLAN_LOG_DEBUG(1,"mmi write : data = 0x%08x\n", data);
2216
2217         /* Do i need a host2hfa... conversion ? */
2218         spin_lock_bh(&hw->cmdlock);
2219         result = hfa384x_docmd_wait(hw, &cmd);
2220         spin_unlock_bh(&hw->cmdlock);
2221
2222         DBFEXIT;
2223         return result;
2224 }
2225
2226
2227 /* TODO: determine if these will ever be needed */
2228 #if 0
2229 int hfa384x_cmd_readmif(hfa384x_t *hw)
2230 {
2231         DBFENTER;
2232         DBFEXIT;
2233         return 0;
2234 }
2235
2236
2237 int hfa384x_cmd_writemif(hfa384x_t *hw)
2238 {
2239         DBFENTER;
2240         DBFEXIT;
2241         return 0;
2242 }
2243 #endif
2244
2245
2246
2247 /*----------------------------------------------------------------
2248 * hfa384x_copy_from_bap
2249 *
2250 * Copies a collection of bytes from the MAC controller memory via
2251 * one set of BAP registers.
2252 *
2253 * Arguments:
2254 *       hw              device structure
2255 *       bap             [0|1] which BAP to use
2256 *       id              FID or RID, destined for the select register (host order)
2257 *       offset          An _even_ offset into the buffer for the given
2258 *                       FID/RID.  We haven't the means to validate this,
2259 *                       so be careful. (host order)
2260 *       buf             ptr to array of bytes
2261 *       len             length of data to transfer in bytes
2262 *
2263 * Returns:
2264 *       0               success
2265 *       >0              f/w reported failure - value of offset reg.
2266 *       <0              driver reported error (timeout|bad arg)
2267 *
2268 * Side effects:
2269 *
2270 * Call context:
2271 *       process thread
2272 *       interrupt
2273 ----------------------------------------------------------------*/
2274 int hfa384x_copy_from_bap(hfa384x_t *hw, UINT16 bap, UINT16 id, UINT16 offset,
2275                                 void *buf, UINT len)
2276 {
2277         int             result = 0;
2278         unsigned long   flags = 0;
2279         UINT8           *d = (UINT8*)buf;
2280         UINT            selectreg;
2281         UINT            offsetreg;
2282         UINT            datareg;
2283         UINT            i;
2284         UINT16          reg = 0;
2285
2286         DBFENTER;
2287
2288         /* Validate bap, offset, buf, and len */
2289         if ( (bap > 1) ||
2290              (offset > HFA384x_BAP_OFFSET_MAX) ||
2291              (offset % 2) ||
2292              (buf == NULL) ||
2293              (len > HFA384x_BAP_DATALEN_MAX) ){
2294                 result = -EINVAL;
2295         } else {
2296                 selectreg = (bap == 1) ?  HFA384x_SELECT1 : HFA384x_SELECT0 ;
2297                 offsetreg = (bap == 1) ?  HFA384x_OFFSET1 : HFA384x_OFFSET0 ;
2298                 datareg =   (bap == 1) ?  HFA384x_DATA1 : HFA384x_DATA0 ;
2299
2300                 /* Obtain lock */
2301                 spin_lock_irqsave( &(hw->baplock), flags);
2302
2303                 /* Write id to select reg */
2304                 hfa384x_setreg(hw, id, selectreg);
2305                 /* Write offset to offset reg */
2306                 hfa384x_setreg(hw, offset, offsetreg);
2307                 /* Wait for offset[busy] to clear (see BAP_TIMEOUT) */
2308                 i = 0;
2309                 do {
2310                         reg = hfa384x_getreg(hw, offsetreg);
2311                         if ( i > 0 ) udelay(10);
2312                         i++;
2313                 } while ( i < prism2_bap_timeout && HFA384x_OFFSET_ISBUSY(reg));
2314 #if (WLAN_HOSTIF != WLAN_PCI)
2315                 /* Release lock */
2316                 spin_unlock_irqrestore( &(hw->baplock), flags);
2317 #endif
2318
2319                 if ( HFA384x_OFFSET_ISBUSY(reg) ){
2320                         /* If timeout, return -ETIMEDOUT */
2321                         result = reg;
2322                 } else if ( HFA384x_OFFSET_ISERR(reg) ){
2323                         /* If offset[err] == 1, return -EINVAL */
2324                         result = reg;
2325                 } else {
2326                         /* Read even(len) buf contents from data reg */
2327                         for ( i = 0; i < (len & 0xfffe); i+=2 ) {
2328                                 *(UINT16*)(&(d[i])) =
2329                                         hfa384x_getreg_noswap(hw, datareg);
2330                         }
2331                         /* If len odd, handle last byte */
2332                         if ( len % 2 ){
2333                                 reg = hfa384x_getreg_noswap(hw, datareg);
2334                                 d[len-1] = ((UINT8*)(&reg))[0];
2335                         }
2336                 }
2337
2338                 /* According to Intersil errata dated 9/16/02:
2339
2340                 "In PRISM PCI MAC host interface, if both BAPs are concurrently
2341                  requesing memory access, both will accept the Ack.   There is no
2342                  firmware workaround possible.  To prevent BAP access failures or
2343                  hang conditions the host MUST NOT access both BAPs in sucession
2344                  unless at least 5us elapses between accesses.  The safest choice
2345                  is to USE ONLY ONE BAP for all data movement operations."
2346
2347                  What this means:
2348
2349                  We have to serialize ALL BAP accesses, and furthermore, add a 5us
2350                  delay after access if we're using a PCI platform.
2351
2352                  Unfortunately, this means we have to lock out interrupts througout
2353                  the entire BAP copy.
2354
2355                  It remains to be seen if "BAP access" means "BAP setup" or the more
2356                  literal definition of "copying data back and forth"  I'm erring for
2357                  the latter, safer definition.  -- SLP.
2358
2359                 */
2360
2361 #if (WLAN_HOSTIF == WLAN_PCI)
2362                 udelay(5);
2363                 /* Release lock */
2364                 spin_unlock_irqrestore( &(hw->baplock), flags);
2365 #endif
2366
2367         }
2368
2369         if (result) {
2370           WLAN_LOG_DEBUG(1,
2371                           "copy_from_bap(0x%04x, 0, %d) failed, result=0x%x\n",
2372                           reg, len, result);
2373         }
2374         DBFEXIT;
2375         return result;
2376 }
2377
2378
2379 /*----------------------------------------------------------------
2380 * hfa384x_copy_to_bap
2381 *
2382 * Copies a collection of bytes to the MAC controller memory via
2383 * one set of BAP registers.
2384 *
2385 * Arguments:
2386 *       hw              device structure
2387 *       bap             [0|1] which BAP to use
2388 *       id              FID or RID, destined for the select register (host order)
2389 *       offset          An _even_ offset into the buffer for the given
2390 *                       FID/RID.  We haven't the means to validate this,
2391 *                       so be careful. (host order)
2392 *       buf             ptr to array of bytes
2393 *       len             length of data to transfer (in bytes)
2394 *
2395 * Returns:
2396 *       0               success
2397 *       >0              f/w reported failure - value of offset reg.
2398 *       <0              driver reported error (timeout|bad arg)
2399 *
2400 * Side effects:
2401 *
2402 * Call context:
2403 *       process thread
2404 *       interrupt
2405 ----------------------------------------------------------------*/
2406 int hfa384x_copy_to_bap(hfa384x_t *hw, UINT16 bap, UINT16 id, UINT16 offset,
2407                                 void *buf, UINT len)
2408 {
2409         return hfa384x_copy_to_bap4(hw, bap, id, offset, buf, len, NULL, 0, NULL, 0, NULL, 0);
2410 }
2411
2412 int hfa384x_copy_to_bap4(hfa384x_t *hw, UINT16 bap, UINT16 id, UINT16 offset,
2413                          void *buf, UINT len1, void* buf2, UINT len2,
2414                          void *buf3, UINT len3, void *buf4, UINT len4)
2415 {
2416         int             result = 0;
2417         unsigned long   flags = 0;
2418         UINT8           *d;
2419         UINT            selectreg;
2420         UINT            offsetreg;
2421         UINT            datareg;
2422         UINT            i;
2423         UINT16          reg;
2424
2425         DBFENTER;
2426
2427 //      printk(KERN_DEBUG "ctb1 %d id %04x o %d %d %d %d %d\n", bap, id, offset, len1, len2, len3, len4);
2428
2429         /* Validate bap, offset, buf, and len */
2430         if ( (bap > 1) ||
2431              (offset > HFA384x_BAP_OFFSET_MAX) ||
2432              (offset % 2) ||
2433              (buf == NULL) ||
2434              (len1+len2+len3+len4 > HFA384x_BAP_DATALEN_MAX) ){
2435                 result = -EINVAL;
2436         } else {
2437                 selectreg = (bap == 1) ? HFA384x_SELECT1 : HFA384x_SELECT0;
2438                 offsetreg = (bap == 1) ? HFA384x_OFFSET1 : HFA384x_OFFSET0;
2439                 datareg =   (bap == 1) ? HFA384x_DATA1   : HFA384x_DATA0;
2440                 /* Obtain lock */
2441                 spin_lock_irqsave( &(hw->baplock), flags);
2442
2443                 /* Write id to select reg */
2444                 hfa384x_setreg(hw, id, selectreg);
2445                 udelay(10);
2446                 /* Write offset to offset reg */
2447                 hfa384x_setreg(hw, offset, offsetreg);
2448                 /* Wait for offset[busy] to clear (see BAP_TIMEOUT) */
2449                 i = 0;
2450                 do {
2451                         reg = hfa384x_getreg(hw, offsetreg);
2452                         if ( i > 0 ) udelay(10);
2453                         i++;
2454                 } while ( i < prism2_bap_timeout && HFA384x_OFFSET_ISBUSY(reg));
2455
2456 #if (WLAN_HOSTIF != WLAN_PCI)
2457                 /* Release lock */
2458                 spin_unlock_irqrestore( &(hw->baplock), flags);
2459 #endif
2460
2461                 if ( HFA384x_OFFSET_ISBUSY(reg) ){
2462                         /* If timeout, return reg */
2463                         result = reg;
2464                 } else if ( HFA384x_OFFSET_ISERR(reg) ){
2465                         /* If offset[err] == 1, return reg */
2466                         result = reg;
2467                 } else {
2468                         d = (UINT8*)buf;
2469                         /* Write even(len1) buf contents to data reg */
2470                         for ( i = 0; i < (len1 & 0xfffe); i+=2 ) {
2471                                 hfa384x_setreg_noswap(hw,
2472                                         *(UINT16*)(&(d[i])), datareg);
2473                         }
2474                         if (len1 & 1) {
2475                                 UINT16 data;
2476                                 UINT8 *b = (UINT8 *) &data;
2477                                 b[0] = d[len1-1];
2478                                 if (buf2 != NULL) {
2479                                         d = (UINT8*)buf2;
2480                                         b[1] = d[0];
2481                                         len2--;
2482                                         buf2++;
2483                                 }
2484                                 hfa384x_setreg_noswap(hw, data, datareg);
2485                         }
2486                         if ((buf2 != NULL) && (len2 > 0)) {
2487                                 /* Write even(len2) buf contents to data reg */
2488                                 d = (UINT8*)buf2;
2489                                 for ( i = 0; i < (len2 & 0xfffe); i+=2 ) {
2490                                         hfa384x_setreg_noswap(hw, *(UINT16*)(&(d[i])), datareg);
2491                                 }
2492                                 if (len2 & 1) {
2493                                         UINT16 data;
2494                                         UINT8 *b = (UINT8 *) &data;
2495                                         b[0] = d[len2-1];
2496                                         if (buf3 != NULL) {
2497                                                 d = (UINT8*)buf3;
2498                                                 b[1] = d[0];
2499                                                 len3--;
2500                                                 buf3++;
2501                                         }
2502                                         hfa384x_setreg_noswap(hw, data, datareg);
2503                                 }
2504                         }
2505
2506                         if ((buf3 != NULL) && (len3 > 0)) {
2507                                 /* Write even(len3) buf contents to data reg */
2508                                 d = (UINT8*)buf3;
2509                                 for ( i = 0; i < (len3 & 0xfffe); i+=2 ) {
2510                                         hfa384x_setreg_noswap(hw, *(UINT16*)(&(d[i])), datareg);
2511                                 }
2512                                 if (len3 & 1) {
2513                                         UINT16 data;
2514                                         UINT8 *b = (UINT8 *) &data;
2515                                         b[0] = d[len3-1];
2516                                         if (buf4 != NULL) {
2517                                                 d = (UINT8*)buf4;
2518                                                 b[1] = d[0];
2519                                                 len4--;
2520                                                 buf4++;
2521                                         }
2522                                         hfa384x_setreg_noswap(hw, data, datareg);
2523                                 }
2524                         }
2525                         if ((buf4 != NULL) && (len4 > 0)) {
2526                                 /* Write even(len4) buf contents to data reg */
2527                                 d = (UINT8*)buf4;
2528                                 for ( i = 0; i < (len4 & 0xfffe); i+=2 ) {
2529                                         hfa384x_setreg_noswap(hw, *(UINT16*)(&(d[i])), datareg);
2530                                 }
2531                                 if (len4 & 1) {
2532                                         UINT16 data;
2533                                         UINT8 *b = (UINT8 *) &data;
2534                                         b[0] = d[len4-1];
2535                                         b[1] = 0;
2536
2537                                         hfa384x_setreg_noswap(hw, data, datareg);
2538                                 }
2539                         }
2540 //                      printk(KERN_DEBUG "ctb2 %d id %04x o %d %d %d %d %d\n", bap, id, offset, len1, len2, len3, len4);
2541
2542                 }
2543
2544 #if (WLAN_HOSTIF == WLAN_PCI)
2545                 udelay(5);
2546                 /* Release lock */
2547                 spin_unlock_irqrestore( &(hw->baplock), flags);
2548 #endif
2549
2550         }
2551
2552         if (result)
2553                 WLAN_LOG_ERROR("copy_to_bap() failed.\n");
2554
2555         DBFEXIT;
2556         return result;
2557 }
2558
2559
2560 /*----------------------------------------------------------------
2561 * hfa384x_copy_from_aux
2562 *
2563 * Copies a collection of bytes from the controller memory.  The
2564 * Auxiliary port MUST be enabled prior to calling this function.
2565 * We _might_ be in a download state.
2566 *
2567 * Arguments:
2568 *       hw              device structure
2569 *       cardaddr        address in hfa384x data space to read
2570 *       auxctl          address space select
2571 *       buf             ptr to destination host buffer
2572 *       len             length of data to transfer (in bytes)
2573 *
2574 * Returns:
2575 *       nothing
2576 *
2577 * Side effects:
2578 *       buf contains the data copied
2579 *
2580 * Call context:
2581 *       process thread
2582 *       interrupt
2583 ----------------------------------------------------------------*/
2584 void
2585 hfa384x_copy_from_aux(
2586         hfa384x_t *hw, UINT32 cardaddr, UINT32 auxctl, void *buf, UINT len)
2587 {
2588         UINT16          currpage;
2589         UINT16          curroffset;
2590         UINT            i = 0;
2591
2592         DBFENTER;
2593
2594         if ( !(hw->auxen) ) {
2595                 WLAN_LOG_DEBUG(1,
2596                         "Attempt to read 0x%04x when aux not enabled\n",
2597                         cardaddr);
2598                 return;
2599
2600         }
2601         /* Build appropriate aux page and offset */
2602         currpage = HFA384x_AUX_MKPAGE(cardaddr);
2603         curroffset = HFA384x_AUX_MKOFF(cardaddr, auxctl);
2604         hfa384x_setreg(hw, currpage, HFA384x_AUXPAGE);
2605         hfa384x_setreg(hw, curroffset, HFA384x_AUXOFFSET);
2606         udelay(5);      /* beat */
2607
2608         /* read the data */
2609         while ( i < len) {
2610                 *((UINT16*)(buf+i)) = hfa384x_getreg_noswap(hw, HFA384x_AUXDATA);
2611                 i+=2;
2612                 curroffset+=2;
2613                 if ( (curroffset&HFA384x_ADDR_AUX_OFF_MASK) >
2614                         HFA384x_ADDR_AUX_OFF_MAX ) {
2615                         currpage++;
2616                         curroffset = 0;
2617                         curroffset = HFA384x_AUX_MKOFF(curroffset, auxctl);
2618                         hfa384x_setreg(hw, currpage, HFA384x_AUXPAGE);
2619                         hfa384x_setreg(hw, curroffset, HFA384x_AUXOFFSET);
2620                         udelay(5);      /* beat */
2621                 }
2622         }
2623         /* Make sure the auxctl bits are clear */
2624         hfa384x_setreg(hw, 0, HFA384x_AUXOFFSET);
2625         DBFEXIT;
2626 }
2627
2628
2629 /*----------------------------------------------------------------
2630 * hfa384x_copy_to_aux
2631 *
2632 * Copies a collection of bytes to the controller memory.  The
2633 * Auxiliary port MUST be enabled prior to calling this function.
2634 * We _might_ be in a download state.
2635 *
2636 * Arguments:
2637 *       hw              device structure
2638 *       cardaddr        address in hfa384x data space to read
2639 *       auxctl          address space select
2640 *       buf             ptr to destination host buffer
2641 *       len             length of data to transfer (in bytes)
2642 *
2643 * Returns:
2644 *       nothing
2645 *
2646 * Side effects:
2647 *       Controller memory now contains a copy of buf
2648 *
2649 * Call context:
2650 *       process thread
2651 *       interrupt
2652 ----------------------------------------------------------------*/
2653 void
2654 hfa384x_copy_to_aux(
2655         hfa384x_t *hw, UINT32 cardaddr, UINT32 auxctl, void *buf, UINT len)
2656 {
2657         UINT16          currpage;
2658         UINT16          curroffset;
2659         UINT            i = 0;
2660
2661         DBFENTER;
2662
2663         if ( !(hw->auxen) ) {
2664                 WLAN_LOG_DEBUG(1,
2665                         "Attempt to read 0x%04x when aux not enabled\n",
2666                         cardaddr);
2667                 return;
2668
2669         }
2670         /* Build appropriate aux page and offset */
2671         currpage = HFA384x_AUX_MKPAGE(cardaddr);
2672         curroffset = HFA384x_AUX_MKOFF(cardaddr, auxctl);
2673         hfa384x_setreg(hw, currpage, HFA384x_AUXPAGE);
2674         hfa384x_setreg(hw, curroffset, HFA384x_AUXOFFSET);
2675         udelay(5);      /* beat */
2676
2677         /* write the data */
2678         while ( i < len) {
2679                 hfa384x_setreg_noswap(hw,
2680                         *((UINT16*)(buf+i)), HFA384x_AUXDATA);
2681                 i+=2;
2682                 curroffset+=2;
2683                 if ( curroffset > HFA384x_ADDR_AUX_OFF_MAX ) {
2684                         currpage++;
2685                         curroffset = 0;
2686                         hfa384x_setreg(hw, currpage, HFA384x_AUXPAGE);
2687                         hfa384x_setreg(hw, curroffset, HFA384x_AUXOFFSET);
2688                         udelay(5);      /* beat */
2689                 }
2690         }
2691         DBFEXIT;
2692 }
2693
2694
2695 /*----------------------------------------------------------------
2696 * hfa384x_cmd_wait
2697 *
2698 * Waits for availability of the Command register, then
2699 * issues the given command.  Then polls the Evstat register
2700 * waiting for command completion.  Timeouts shouldn't be
2701 * possible since we're preventing overlapping commands and all
2702 * commands should be cleared and acknowledged.
2703 *
2704 * Arguments:
2705 *       wlandev         device structure
2706 *       cmd             cmd structure.  Includes all arguments and result
2707 *                       data points.  All in host order.
2708 *
2709 * Returns:
2710 *       0               success
2711 *       -ETIMEDOUT      timed out waiting for register ready or
2712 *                       command completion
2713 *       >0              command indicated error, Status and Resp0-2 are
2714 *                       in hw structure.
2715 *
2716 * Side effects:
2717 *
2718 *
2719 * Call context:
2720 *       process thread
2721 ----------------------------------------------------------------*/
2722 static int hfa384x_docmd_wait( hfa384x_t *hw, hfa384x_metacmd_t *cmd)
2723 {
2724         int             result = -ETIMEDOUT;
2725         UINT16          reg = 0;
2726         UINT16          counter;
2727
2728         DBFENTER;
2729
2730         hw->cmdflag = 0;
2731         hw->cmddata = cmd;
2732
2733         /* wait for the busy bit to clear */
2734         counter = 0;
2735         reg = hfa384x_getreg(hw, HFA384x_CMD);
2736         while ( HFA384x_CMD_ISBUSY(reg) &&
2737                 (counter < 10)) {
2738                 reg = hfa384x_getreg(hw, HFA384x_CMD);
2739                 counter++;
2740                 udelay(10);
2741         }
2742
2743         if (HFA384x_CMD_ISBUSY(reg)) {
2744                 WLAN_LOG_ERROR("hfa384x_cmd timeout(1), reg=0x%0hx.\n", reg);
2745                 goto failed;
2746         }
2747         if (!HFA384x_CMD_ISBUSY(reg)) {
2748                 /* busy bit clear, write command */
2749                 hfa384x_setreg(hw, cmd->parm0, HFA384x_PARAM0);
2750                 hfa384x_setreg(hw, cmd->parm1, HFA384x_PARAM1);
2751                 hfa384x_setreg(hw, cmd->parm2, HFA384x_PARAM2);
2752                 hfa384x_setreg(hw, cmd->cmd, HFA384x_CMD);
2753
2754 #ifdef CMD_IRQ
2755
2756 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,2,0))
2757                 while (! hw->cmdflag)
2758                         interruptible_sleep_on(&hw->cmdq);
2759 #else
2760                 wait_event_interruptible(hw->cmdq, hw->cmdflag);
2761 #endif
2762                 result = HFA384x_STATUS_RESULT_GET(cmd->status);
2763 #else // CMD_IRQ
2764                 /* Now wait for completion */
2765                 counter = 0;
2766                 reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
2767                 /* Initialization is the problem.  It takes about
2768                    100ms. "normal" commands are typically is about
2769                    200-400 us (I've never seen less than 200).  Longer
2770                    is better so that we're not hammering the bus. */
2771                 while ( !HFA384x_EVSTAT_ISCMD(reg) &&
2772                         (counter < 5000)) {
2773                         reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
2774                         counter++;
2775                         udelay(200);
2776                 }
2777
2778                 if ( HFA384x_EVSTAT_ISCMD(reg) ) {
2779                         result = 0;
2780                         cmd->result.status = hfa384x_getreg(hw, HFA384x_STATUS);
2781                         cmd->result.resp0 = hfa384x_getreg(hw, HFA384x_RESP0);
2782                         cmd->result.resp1 = hfa384x_getreg(hw, HFA384x_RESP1);
2783                         cmd->result.resp2 = hfa384x_getreg(hw, HFA384x_RESP2);
2784                         hfa384x_setreg(hw, HFA384x_EVACK_CMD,
2785                                 HFA384x_EVACK);
2786                         result = HFA384x_STATUS_RESULT_GET(cmd->result.status);
2787                 } else {
2788                         WLAN_LOG_ERROR("hfa384x_cmd timeout(2), reg=0x%0hx.\n", reg);
2789                 }
2790 #endif  /* CMD_IRQ */
2791         }
2792
2793  failed:
2794         hw->cmdflag = 0;
2795         hw->cmddata = NULL;
2796
2797         DBFEXIT;
2798         return result;
2799 }
2800
2801
2802 /*----------------------------------------------------------------
2803 * hfa384x_dl_docmd_wait
2804 *
2805 * Waits for availability of the Command register, then
2806 * issues the given command.  Then polls the Evstat register
2807 * waiting for command completion.  Timeouts shouldn't be
2808 * possible since we're preventing overlapping commands and all
2809 * commands should be cleared and acknowledged.
2810 *
2811 * This routine is only used for downloads.  Since it doesn't lock out
2812 * interrupts the system response is much better.
2813 *
2814 * Arguments:
2815 *       wlandev         device structure
2816 *       cmd             cmd structure.  Includes all arguments and result
2817 *                       data points.  All in host order.
2818 *
2819 * Returns:
2820 *       0               success
2821 *       -ETIMEDOUT      timed out waiting for register ready or
2822 *                       command completion
2823 *       >0              command indicated error, Status and Resp0-2 are
2824 *                       in hw structure.
2825 *
2826 * Side effects:
2827 *
2828 *
2829 * Call context:
2830 *       process thread
2831 ----------------------------------------------------------------*/
2832 static int hfa384x_dl_docmd_wait( hfa384x_t *hw, hfa384x_metacmd_t *cmd)
2833 {
2834         int             result = -ETIMEDOUT;
2835         unsigned long   timeout;
2836         UINT16          reg = 0;
2837
2838         DBFENTER;
2839         /* wait for the busy bit to clear */
2840         timeout = jiffies + 1*HZ;
2841         reg = hfa384x_getreg(hw, HFA384x_CMD);
2842         while ( HFA384x_CMD_ISBUSY(reg) && time_before( jiffies, timeout) ) {
2843                 reg = hfa384x_getreg(hw, HFA384x_CMD);
2844                 udelay(10);
2845         }
2846         if (HFA384x_CMD_ISBUSY(reg)) {
2847                 WLAN_LOG_WARNING("Timed out waiting for cmd register.\n");
2848                 goto failed;
2849         }
2850
2851         if (!HFA384x_CMD_ISBUSY(reg)) {
2852                 /* busy bit clear, write command */
2853                 hfa384x_setreg(hw, cmd->parm0, HFA384x_PARAM0);
2854                 hfa384x_setreg(hw, cmd->parm1, HFA384x_PARAM1);
2855                 hfa384x_setreg(hw, cmd->parm2, HFA384x_PARAM2);
2856                 hfa384x_setreg(hw, cmd->cmd, HFA384x_CMD);
2857
2858                 /* Now wait for completion */
2859                 if ( (HFA384x_CMD_CMDCODE_GET(cmd->cmd) == HFA384x_CMDCODE_DOWNLD) ) {
2860                         /* dltimeout is in ms */
2861                         timeout = (((UINT32)hw->dltimeout) / 1000UL) * HZ;
2862                         if ( timeout > 0 ) {
2863                                 timeout += jiffies;
2864                         } else {
2865                                 timeout = jiffies + 1*HZ;
2866                         }
2867                 } else {
2868                         timeout = jiffies + 1*HZ;
2869                 }
2870                 reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
2871                 while ( !HFA384x_EVSTAT_ISCMD(reg) && time_before(jiffies,timeout) ) {
2872                         udelay(100);
2873                         reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
2874                 }
2875                 if ( HFA384x_EVSTAT_ISCMD(reg) ) {
2876                         result = 0;
2877                         cmd->result.status = hfa384x_getreg(hw, HFA384x_STATUS);
2878                         cmd->result.resp0 = hfa384x_getreg(hw, HFA384x_RESP0);
2879                         cmd->result.resp1 = hfa384x_getreg(hw, HFA384x_RESP1);
2880                         cmd->result.resp2 = hfa384x_getreg(hw, HFA384x_RESP2);
2881                         hfa384x_setreg(hw, HFA384x_EVACK_CMD, HFA384x_EVACK);
2882                         result = HFA384x_STATUS_RESULT_GET(cmd->result.status);
2883                 }
2884         }
2885
2886 failed:
2887         DBFEXIT;
2888         return result;
2889 }
2890
2891 /*----------------------------------------------------------------
2892 * hfa384x_drvr_start
2893 *
2894 * Issues the MAC initialize command, sets up some data structures,
2895 * and enables the interrupts.  After this function completes, the
2896 * low-level stuff should be ready for any/all commands.
2897 *
2898 * Arguments:
2899 *       hw              device structure
2900 * Returns:
2901 *       0               success
2902 *       >0              f/w reported error - f/w status code
2903 *       <0              driver reported error
2904 *
2905 * Side effects:
2906 *
2907 * Call context:
2908 *       process thread
2909 ----------------------------------------------------------------*/
2910 int hfa384x_drvr_start(hfa384x_t *hw)
2911 {
2912         int     result = 0;
2913         UINT16                  reg;
2914         int                     i;
2915         int                     j;
2916         DBFENTER;
2917
2918         /* call initialize */
2919         result = hfa384x_cmd_initialize(hw);
2920         if (result != 0) {
2921                 WLAN_LOG_ERROR("Initialize command failed.\n");
2922                 goto failed;
2923         }
2924
2925         /* make sure interrupts are disabled and any layabout events cleared */
2926         hfa384x_setreg(hw, 0, HFA384x_INTEN);
2927         hfa384x_setreg(hw, 0xffff, HFA384x_EVACK);
2928
2929         hw->txfid_head = 0;
2930         hw->txfid_tail = 0;
2931         hw->txfid_N = HFA384x_DRVR_FIDSTACKLEN_MAX;
2932         memset(hw->txfid_queue, 0, sizeof(hw->txfid_queue));
2933
2934         /* Allocate tx and notify FIDs */
2935         /* First, tx */
2936         for ( i = 0; i < HFA384x_DRVR_FIDSTACKLEN_MAX-1; i++) {
2937                 result = hfa384x_cmd_allocate(hw, HFA384x_DRVR_TXBUF_MAX);
2938                 if (result != 0) {
2939                         WLAN_LOG_ERROR("Allocate(tx) command failed.\n");
2940                         goto failed;
2941                 }
2942                 j = 0;
2943                 do {
2944                         reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
2945                         udelay(10);
2946                         j++;
2947                 } while ( !HFA384x_EVSTAT_ISALLOC(reg) && j < 50); /* 50 is timeout */
2948                 if ( j >= 50 ) {
2949                         WLAN_LOG_ERROR("Timed out waiting for evalloc(tx).\n");
2950                         result = -ETIMEDOUT;
2951                         goto failed;
2952                 }
2953                 reg = hfa384x_getreg(hw, HFA384x_ALLOCFID);
2954
2955                 txfid_queue_add(hw, reg);
2956
2957                 WLAN_LOG_DEBUG(4,"hw->txfid_queue[%d]=0x%04x\n",i,reg);
2958
2959                 reg = HFA384x_EVACK_ALLOC_SET(1);
2960                 hfa384x_setreg(hw, reg, HFA384x_EVACK);
2961
2962         }
2963
2964         /* Now, the info frame fid */
2965         result = hfa384x_cmd_allocate(hw, HFA384x_INFOFRM_MAXLEN);
2966         if (result != 0) {
2967                 WLAN_LOG_ERROR("Allocate(tx) command failed.\n");
2968                 goto failed;
2969         }
2970         i = 0;
2971         do {
2972                 reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
2973                 udelay(10);
2974                 i++;
2975         } while ( !HFA384x_EVSTAT_ISALLOC(reg) && i < 50); /* 50 is timeout */
2976         if ( i >= 50 ) {
2977                 WLAN_LOG_ERROR("Timed out waiting for evalloc(info).\n");
2978                 result = -ETIMEDOUT;
2979                 goto failed;
2980         }
2981         hw->infofid = hfa384x_getreg(hw, HFA384x_ALLOCFID);
2982         reg = HFA384x_EVACK_ALLOC_SET(1);
2983         hfa384x_setreg(hw, reg, HFA384x_EVACK);
2984         WLAN_LOG_DEBUG(4,"hw->infofid=0x%04x\n", hw->infofid);
2985
2986         /* Set swsupport regs to magic # for card presence detection */
2987         hfa384x_setreg(hw, HFA384x_DRVR_MAGIC, HFA384x_SWSUPPORT0);
2988
2989         /* Now enable the interrupts and set the running state */
2990         hfa384x_setreg(hw, 0xffff, HFA384x_EVSTAT);
2991         hfa384x_events_all(hw);
2992
2993         hw->state = HFA384x_STATE_RUNNING;
2994
2995         goto done;
2996 failed:
2997         WLAN_LOG_ERROR("Failed, result=%d\n", result);
2998 done:
2999         DBFEXIT;
3000         return result;
3001 }
3002
3003
3004 /*----------------------------------------------------------------
3005 * hfa384x_drvr_stop
3006 *
3007 * Issues the initialize command to leave us in the 'reset' state.
3008 *
3009 * Arguments:
3010 *       hw              device structure
3011 * Returns:
3012 *       0               success
3013 *       >0              f/w reported error - f/w status code
3014 *       <0              driver reported error
3015 *
3016 * Side effects:
3017 *
3018 * Call context:
3019 *       process thread
3020 ----------------------------------------------------------------*/
3021 int hfa384x_drvr_stop(hfa384x_t *hw)
3022 {
3023         int     result = 0;
3024         int i;
3025         DBFENTER;
3026
3027         del_timer_sync(&hw->commsqual_timer);
3028
3029         if ( hw->wlandev->hwremoved ) {
3030                 /* only flush when we're shutting down for good */
3031                 flush_scheduled_work();
3032         }
3033
3034         if (hw->state == HFA384x_STATE_RUNNING) {
3035                 /*
3036                  * Send the MAC initialize cmd.
3037                  */
3038                 hfa384x_cmd_initialize(hw);
3039
3040                 /*
3041                  * Make absolutely sure interrupts are disabled and any
3042                  * layabout events cleared
3043                  */
3044                 hfa384x_setreg(hw, 0, HFA384x_INTEN);
3045                 hfa384x_setreg(hw, 0xffff, HFA384x_EVACK);
3046         }
3047
3048         tasklet_kill(&hw->bap_tasklet);
3049
3050         hw->link_status = HFA384x_LINK_NOTCONNECTED;
3051         hw->state = HFA384x_STATE_INIT;
3052
3053         /* Clear all the port status */
3054         for ( i = 0; i < HFA384x_NUMPORTS_MAX; i++) {
3055                 hw->port_enabled[i] = 0;
3056         }
3057
3058         DBFEXIT;
3059         return result;
3060 }
3061
3062
3063 /*----------------------------------------------------------------
3064 * hfa384x_drvr_txframe
3065 *
3066 * Takes a frame from prism2sta and queues it for transmission.
3067 *
3068 * Arguments:
3069 *       hw              device structure
3070 *       skb             packet buffer struct.  Contains an 802.11
3071 *                       data frame.
3072 *       p80211_hdr      points to the 802.11 header for the packet.
3073 * Returns:
3074 *       0               Success and more buffs available
3075 *       1               Success but no more buffs
3076 *       2               Allocation failure
3077 *       3               MAC Tx command failed
3078 *       4               Buffer full or queue busy
3079 *
3080 * Side effects:
3081 *
3082 * Call context:
3083 *       process thread
3084 ----------------------------------------------------------------*/
3085 int hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep)
3086 {
3087         hfa384x_tx_frame_t      txdesc;
3088         UINT16                  macq = 0;
3089         UINT16                  fid;
3090         int                     result;
3091
3092         DBFENTER;
3093
3094         /* Build Tx frame structure */
3095         /* Set up the control field */
3096         memset(&txdesc, 0, sizeof(txdesc));
3097
3098 /* Tx complete and Tx exception disable per dleach.  Might be causing
3099  * buf depletion
3100  */
3101 #define DOBOTH 1
3102 #if DOBOTH
3103         txdesc.tx_control =
3104                 HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
3105                 HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(1);
3106 #elif DOEXC
3107         txdesc.tx_control =
3108                 HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
3109                 HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(0);
3110 #else
3111         txdesc.tx_control =
3112                 HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
3113                 HFA384x_TX_TXEX_SET(0) | HFA384x_TX_TXOK_SET(0);
3114 #endif
3115
3116         /* if we're using host WEP, increase size by IV+ICV */
3117         if (p80211_wep->data) {
3118                 txdesc.data_len = host2hfa384x_16(skb->len+8);
3119                 //              txdesc.tx_control |= HFA384x_TX_NOENCRYPT_SET(1);
3120         } else {
3121                 txdesc.data_len =  host2hfa384x_16(skb->len);
3122         }
3123
3124         txdesc.tx_control = host2hfa384x_16(txdesc.tx_control);
3125         /* copy the header over to the txdesc */
3126         memcpy(&(txdesc.frame_control), p80211_hdr, sizeof(p80211_hdr_t));
3127
3128         /* Since tbusy is set whenever the stack is empty, there should
3129          * always be something on the stack if we get to this point.
3130          * [MSM]: NOT TRUE!!!!! so I added the test of fid below.
3131          */
3132
3133         /* Allocate FID */
3134
3135         fid = txfid_queue_remove(hw);
3136
3137         if ( fid == 0 ) { /* stack or queue was empty */
3138                 return 4;
3139         }
3140
3141         /* now let's get the cmdlock */
3142         spin_lock(&hw->cmdlock);
3143
3144         /* Copy descriptor+payload to FID */
3145         if (p80211_wep->data) {
3146                 result = hfa384x_copy_to_bap4(hw, HFA384x_BAP_PROC, fid, 0,
3147                                               &txdesc, sizeof(txdesc),
3148                                               p80211_wep->iv, sizeof(p80211_wep->iv),
3149                                               p80211_wep->data, skb->len,
3150                                               p80211_wep->icv, sizeof(p80211_wep->icv));
3151         } else {
3152                 result = hfa384x_copy_to_bap4(hw, HFA384x_BAP_PROC, fid, 0,
3153                                               &txdesc, sizeof(txdesc),
3154                                               skb->data, skb->len,
3155                                               NULL, 0, NULL, 0);
3156         }
3157
3158         if ( result ) {
3159                 WLAN_LOG_DEBUG(1,
3160                         "copy_to_bap(%04x, %d, %d) failed, result=0x%x\n",
3161                         fid,
3162                         sizeof(txdesc),
3163                         skb->len,
3164                         result);
3165
3166                 /* put the fid back in the queue */
3167                 txfid_queue_add(hw, fid);
3168
3169                 result = 3;
3170                 goto failed;
3171         }
3172
3173         /* Issue Tx command */
3174         result = hfa384x_cmd_transmit(hw, HFA384x_TXCMD_RECL, macq, fid);
3175
3176         if ( result != 0 ) {
3177                 txfid_queue_add(hw, fid);
3178
3179                 WLAN_LOG_DEBUG(1,"cmd_tx(%04x) failed, result=%d\n",
3180                         fid, result);
3181                 result = 3;
3182                 goto failed;
3183         }
3184
3185         /* indicate we haven't any buffers, int_alloc will clear */
3186         result = txfid_queue_empty(hw);
3187 failed:
3188
3189         spin_unlock(&hw->cmdlock);
3190
3191         DBFEXIT;
3192         return result;
3193 }
3194
3195 /*----------------------------------------------------------------
3196 * hfa384x_interrupt
3197 *
3198 * Driver interrupt handler.
3199 *
3200 * Arguments:
3201 *       irq             irq number
3202 *       dev_id          pointer to the device
3203 *       regs            registers
3204 *
3205 * Returns:
3206 *       nothing
3207 *
3208 * Side effects:
3209 *       May result in a frame being passed up the stack or an info
3210 *       frame being handled.
3211 *
3212 * Call context:
3213 *       Ummm, could it be interrupt?
3214 ----------------------------------------------------------------*/
3215 irqreturn_t hfa384x_interrupt(int irq, void *dev_id PT_REGS)
3216 {
3217         int                     reg;
3218         wlandevice_t            *wlandev = (wlandevice_t*)dev_id;
3219         hfa384x_t               *hw = wlandev->priv;
3220         int                     ev_read = 0;
3221         DBFENTER;
3222
3223         if (!wlandev || wlandev->hwremoved)
3224                 return IRQ_NONE;  /* Not much we can do w/o hardware */
3225 #if (WLAN_HOSTIF == WLAN_PCMCIA)
3226         if (hw->iobase == 0)  /* XXX FIXME Properly */
3227                 return IRQ_NONE;
3228 #endif
3229
3230         for (;;ev_read++) {
3231                 if (ev_read >= prism2_irq_evread_max)
3232                         break;
3233
3234                 /* Check swsupport reg magic # for card presence */
3235                 reg = hfa384x_getreg(hw, HFA384x_SWSUPPORT0);
3236                 if ( reg != HFA384x_DRVR_MAGIC) {
3237                         WLAN_LOG_DEBUG(2, "irq=%d, no magic.  Card removed?.\n", irq);
3238                         break;
3239                 }
3240
3241                 /* read the EvStat register for interrupt enabled events */
3242                 reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
3243
3244                 /* AND with the enabled interrupts */
3245                 reg &= hfa384x_getreg(hw, HFA384x_INTEN);
3246
3247                 /* Handle the events */
3248                 if ( HFA384x_EVSTAT_ISWTERR(reg) ){
3249                         WLAN_LOG_ERROR(
3250                         "Error: WTERR interrupt received (unhandled).\n");
3251                         hfa384x_setreg(hw, HFA384x_EVACK_WTERR_SET(1),
3252                                 HFA384x_EVACK);
3253                 }
3254
3255                 if ( HFA384x_EVSTAT_ISINFDROP(reg) ){
3256                         hfa384x_int_infdrop(wlandev);
3257                         hfa384x_setreg(hw, HFA384x_EVACK_INFDROP_SET(1),
3258                                 HFA384x_EVACK);
3259                 }
3260
3261                 if (HFA384x_EVSTAT_ISBAP_OP(reg)) {
3262                         /* Disable the BAP interrupts */
3263                         hfa384x_events_nobap(hw);
3264                         tasklet_schedule(&hw->bap_tasklet);
3265                 }
3266
3267                 if ( HFA384x_EVSTAT_ISALLOC(reg) ){
3268                         hfa384x_int_alloc(wlandev);
3269                         hfa384x_setreg(hw, HFA384x_EVACK_ALLOC_SET(1),
3270                                 HFA384x_EVACK);
3271                 }
3272
3273                 if ( HFA384x_EVSTAT_ISDTIM(reg) ){
3274                         hfa384x_int_dtim(wlandev);
3275                         hfa384x_setreg(hw, HFA384x_EVACK_DTIM_SET(1),
3276                                 HFA384x_EVACK);
3277                 }
3278 #ifdef CMD_IRQ
3279                 if ( HFA384x_EVSTAT_ISCMD(reg) ){
3280                         hfa384x_int_cmd(wlandev);
3281                         hfa384x_setreg(hw, HFA384x_EVACK_CMD_SET(1),
3282                                        HFA384x_EVACK);
3283                 }
3284 #endif
3285
3286                 /* allow the evstat to be updated after the evack */
3287                 udelay(20);
3288         }
3289
3290         DBFEXIT;
3291         return IRQ_HANDLED;
3292 }
3293
3294 #ifdef CMD_IRQ
3295 /*----------------------------------------------------------------
3296 * hfa384x_int_cmd
3297 *
3298 * Handles command completion event.
3299 *
3300 * Arguments:
3301 *       wlandev         wlan device structure
3302 *
3303 * Returns:
3304 *       nothing
3305 *
3306 * Side effects:
3307 *
3308 * Call context:
3309 *       interrupt
3310 ----------------------------------------------------------------*/
3311 void hfa384x_int_cmd(wlandevice_t *wlandev)
3312 {
3313         hfa384x_t               *hw = wlandev->priv;
3314         DBFENTER;
3315
3316         // check to make sure it's the right command?
3317         if (hw->cmddata) {
3318                 hw->cmddata->status = hfa384x_getreg(hw, HFA384x_STATUS);
3319                 hw->cmddata->resp0 = hfa384x_getreg(hw, HFA384x_RESP0);
3320                 hw->cmddata->resp1 = hfa384x_getreg(hw, HFA384x_RESP1);
3321                 hw->cmddata->resp2 = hfa384x_getreg(hw, HFA384x_RESP2);
3322         }
3323         hw->cmdflag = 1;
3324
3325         printk(KERN_INFO "um. int_cmd\n");
3326
3327         wake_up_interruptible(&hw->cmdq);
3328
3329         // XXXX perform a bap copy too?
3330
3331         DBFEXIT;
3332         return;
3333 }
3334 #endif
3335
3336 /*----------------------------------------------------------------
3337 * hfa384x_int_dtim
3338 *
3339 * Handles the DTIM early warning event.
3340 *
3341 * Arguments:
3342 *       wlandev         wlan device structure
3343 *
3344 * Returns:
3345 *       nothing
3346 *
3347 * Side effects:
3348 *
3349 * Call context:
3350 *       interrupt
3351 ----------------------------------------------------------------*/
3352 static void hfa384x_int_dtim(wlandevice_t *wlandev)
3353 {
3354 #if 0
3355         hfa384x_t               *hw = wlandev->priv;
3356 #endif
3357         DBFENTER;
3358         prism2sta_ev_dtim(wlandev);
3359         DBFEXIT;
3360         return;
3361 }
3362
3363
3364 /*----------------------------------------------------------------
3365 * hfa384x_int_infdrop
3366 *
3367 * Handles the InfDrop event.
3368 *
3369 * Arguments:
3370 *       wlandev         wlan device structure
3371 *
3372 * Returns:
3373 *       nothing
3374 *
3375 * Side effects:
3376 *
3377 * Call context:
3378 *       interrupt
3379 ----------------------------------------------------------------*/
3380 static void hfa384x_int_infdrop(wlandevice_t *wlandev)
3381 {
3382 #if 0
3383         hfa384x_t               *hw = wlandev->priv;
3384 #endif
3385         DBFENTER;
3386         prism2sta_ev_infdrop(wlandev);
3387         DBFEXIT;
3388         return;
3389 }
3390
3391
3392 /*----------------------------------------------------------------
3393 * hfa384x_int_info
3394 *
3395 * Handles the Info event.
3396 *
3397 * Arguments:
3398 *       wlandev         wlan device structure
3399 *
3400 * Returns:
3401 *       nothing
3402 *
3403 * Side effects:
3404 *
3405 * Call context:
3406 *       tasklet
3407 ----------------------------------------------------------------*/
3408 static void hfa384x_int_info(wlandevice_t *wlandev)
3409 {
3410         hfa384x_t               *hw = wlandev->priv;
3411         UINT16                  reg;
3412         hfa384x_InfFrame_t      inf;
3413         int                     result;
3414         DBFENTER;
3415         /* Retrieve the FID */
3416         reg = hfa384x_getreg(hw, HFA384x_INFOFID);
3417
3418         /* Retrieve the length */
3419         result = hfa384x_copy_from_bap( hw,
3420                 HFA384x_BAP_INT, reg, 0, &inf.framelen, sizeof(UINT16));
3421         if ( result ) {
3422                 WLAN_LOG_DEBUG(1,
3423                         "copy_from_bap(0x%04x, 0, %d) failed, result=0x%x\n",
3424                         reg, sizeof(inf), result);
3425                 goto failed;
3426         }
3427         inf.framelen = hfa384x2host_16(inf.framelen);
3428
3429         /* Retrieve the rest */
3430         result = hfa384x_copy_from_bap( hw,
3431                 HFA384x_BAP_INT, reg, sizeof(UINT16),
3432                 &(inf.infotype), inf.framelen * sizeof(UINT16));
3433         if ( result ) {
3434                 WLAN_LOG_DEBUG(1,
3435                         "copy_from_bap(0x%04x, 0, %d) failed, result=0x%x\n",
3436                         reg, sizeof(inf), result);
3437                 goto failed;
3438         }
3439
3440         prism2sta_ev_info(wlandev, &inf);
3441 failed:
3442         DBFEXIT;
3443         return;
3444 }
3445
3446
3447 /*----------------------------------------------------------------
3448 * hfa384x_int_txexc
3449 *
3450 * Handles the TxExc event.  A Transmit Exception event indicates
3451 * that the MAC's TX process was unsuccessful - so the packet did
3452 * not get transmitted.
3453 *
3454 * Arguments:
3455 *       wlandev         wlan device structure
3456 *
3457 * Returns:
3458 *       nothing
3459 *
3460 * Side effects:
3461 *
3462 * Call context:
3463 *       tasklet
3464 ----------------------------------------------------------------*/
3465 static void hfa384x_int_txexc(wlandevice_t *wlandev)
3466 {
3467         hfa384x_t               *hw = wlandev->priv;
3468         UINT16                  status;
3469         UINT16                  fid;
3470         int                     result = 0;
3471         DBFENTER;
3472         /* Collect the status and display */
3473         fid = hfa384x_getreg(hw, HFA384x_TXCOMPLFID);
3474         result = hfa384x_copy_from_bap(hw, HFA384x_BAP_INT, fid, 0, &status, sizeof(status));
3475         if ( result ) {
3476                 WLAN_LOG_DEBUG(1,
3477                         "copy_from_bap(0x%04x, 0, %d) failed, result=0x%x\n",
3478                         fid, sizeof(status), result);
3479                 goto failed;
3480         }
3481         status = hfa384x2host_16(status);
3482         prism2sta_ev_txexc(wlandev, status);
3483 failed:
3484         DBFEXIT;
3485         return;
3486 }
3487
3488
3489 /*----------------------------------------------------------------
3490 * hfa384x_int_tx
3491 *
3492 * Handles the Tx event.
3493 *
3494 * Arguments:
3495 *       wlandev         wlan device structure
3496 *
3497 * Returns:
3498 *       nothing
3499 *
3500 * Side effects:
3501 *
3502 * Call context:
3503 *       tasklet
3504 ----------------------------------------------------------------*/
3505 static void hfa384x_int_tx(wlandevice_t *wlandev)
3506 {
3507         hfa384x_t               *hw = wlandev->priv;
3508         UINT16                  fid;
3509         UINT16                  status;
3510         int                     result = 0;
3511         DBFENTER;
3512         fid = hfa384x_getreg(hw, HFA384x_TXCOMPLFID);
3513         result = hfa384x_copy_from_bap(hw, HFA384x_BAP_INT, fid, 0, &status, sizeof(status));
3514         if ( result ) {
3515                 WLAN_LOG_DEBUG(1,
3516                         "copy_from_bap(0x%04x, 0, %d) failed, result=0x%x\n",
3517                         fid, sizeof(status), result);
3518                 goto failed;
3519         }
3520         status = hfa384x2host_16(status);
3521         prism2sta_ev_tx(wlandev, status);
3522 failed:
3523         DBFEXIT;
3524         return;
3525 }
3526
3527 /*----------------------------------------------------------------
3528 * hfa384x_int_rx
3529 *
3530 * Handles the Rx event.
3531 *
3532 * Arguments:
3533 *       wlandev         wlan device structure
3534 *
3535 * Returns:
3536 *       nothing
3537 *
3538 * Side effects:
3539 *
3540 * Call context:
3541 *       tasklet
3542 ----------------------------------------------------------------*/
3543 static void hfa384x_int_rx(wlandevice_t *wlandev)
3544 {
3545         hfa384x_t               *hw = wlandev->priv;
3546         UINT16                  rxfid;
3547         hfa384x_rx_frame_t      rxdesc;
3548         int                     result;
3549         int                     hdrlen;
3550         UINT16                  fc;
3551         p80211_rxmeta_t *rxmeta;
3552         struct sk_buff          *skb = NULL;
3553         UINT8 *datap;
3554
3555         DBFENTER;
3556
3557         /* Get the FID */
3558         rxfid = hfa384x_getreg(hw, HFA384x_RXFID);
3559         /* Get the descriptor (including headers) */
3560         result = hfa384x_copy_from_bap(hw,
3561                         HFA384x_BAP_INT,
3562                         rxfid,
3563                         0,
3564                         &rxdesc,
3565                         sizeof(rxdesc));
3566         if ( result ) {
3567                 WLAN_LOG_DEBUG(1,
3568                         "copy_from_bap(0x%04x, %d, %d) failed, result=0x%x\n",
3569                         rxfid,
3570                         0,
3571                         sizeof(rxdesc),
3572                         result);
3573                 goto done;
3574         }
3575
3576         /* Byte order convert once up front. */
3577         rxdesc.status = hfa384x2host_16(rxdesc.status);
3578         rxdesc.time =   hfa384x2host_32(rxdesc.time);
3579
3580         /* drop errors and whatnot in promisc mode */
3581         if (( wlandev->netdev->flags & IFF_PROMISC ) &&
3582             (HFA384x_RXSTATUS_ISFCSERR(rxdesc.status) ||
3583              HFA384x_RXSTATUS_ISUNDECR(rxdesc.status)))
3584           goto done;
3585
3586         /* Now handle frame based on port# */
3587         switch( HFA384x_RXSTATUS_MACPORT_GET(rxdesc.status) )
3588         {
3589         case 0:
3590
3591                 fc = ieee2host16(rxdesc.frame_control);
3592
3593                 /* If exclude and we receive an unencrypted, drop it */
3594                 if ( (wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED) &&
3595                      !WLAN_GET_FC_ISWEP(fc)) {
3596                         goto done;
3597                 }
3598
3599                 hdrlen = p80211_headerlen(fc);
3600
3601                 /* Allocate the buffer, note CRC (aka FCS). pballoc */
3602                 /* assumes there needs to be space for one */
3603                 skb = dev_alloc_skb(hfa384x2host_16(rxdesc.data_len) + hdrlen + WLAN_CRC_LEN + 2); /* a little extra */
3604
3605                 if ( ! skb ) {
3606                         WLAN_LOG_ERROR("alloc_skb failed.\n");
3607                         goto done;
3608                 }
3609
3610                 skb->dev = wlandev->netdev;
3611
3612                 /* theoretically align the IP header on a 32-bit word. */
3613                 if ( hdrlen == WLAN_HDR_A4_LEN )
3614                         skb_reserve(skb, 2);
3615
3616                 /* Copy the 802.11 hdr to the buffer */
3617                 datap = skb_put(skb, WLAN_HDR_A3_LEN);
3618                 memcpy(datap, &rxdesc.frame_control, WLAN_HDR_A3_LEN);
3619
3620                 /* Snag the A4 address if present */
3621                 if (hdrlen == WLAN_HDR_A4_LEN) {
3622                         datap = skb_put(skb, WLAN_ADDR_LEN);
3623                         memcpy(datap, &rxdesc.address4, WLAN_HDR_A3_LEN);
3624                 }
3625
3626                 /* we can convert the data_len as we passed the original on */
3627                 rxdesc.data_len = hfa384x2host_16(rxdesc.data_len);
3628
3629                 /* Copy the payload data to the buffer */
3630                 if ( rxdesc.data_len > 0 ) {
3631                         datap = skb_put(skb, rxdesc.data_len);
3632                         result = hfa384x_copy_from_bap(hw,
3633                                 HFA384x_BAP_INT, rxfid, HFA384x_RX_DATA_OFF,
3634                                 datap, rxdesc.data_len);
3635                         if ( result ) {
3636                                 WLAN_LOG_DEBUG(1,
3637                                         "copy_from_bap(0x%04x, %d, %d) failed, result=0x%x\n",
3638                                         rxfid,
3639                                         HFA384x_RX_DATA_OFF,
3640                                         rxdesc.data_len,
3641                                         result);
3642                                 goto failed;
3643                         }
3644                 }
3645                 /* the prism2 cards don't return the FCS */
3646                 datap = skb_put(skb, WLAN_CRC_LEN);
3647                 memset (datap, 0xff, WLAN_CRC_LEN);
3648                 skb_reset_mac_header(skb);
3649
3650                 /* Attach the rxmeta, set some stuff */
3651                 p80211skb_rxmeta_attach(wlandev, skb);
3652                 rxmeta = P80211SKB_RXMETA(skb);
3653                 rxmeta->mactime = rxdesc.time;
3654                 rxmeta->rxrate = rxdesc.rate;
3655                 rxmeta->signal = rxdesc.signal - hw->dbmadjust;
3656                 rxmeta->noise = rxdesc.silence - hw->dbmadjust;
3657
3658                 prism2sta_ev_rx(wlandev, skb);
3659                 goto done;
3660         case 7:
3661
3662                 if ( ! HFA384x_RXSTATUS_ISFCSERR(rxdesc.status) ) {
3663                         hfa384x_int_rxmonitor( wlandev, rxfid, &rxdesc);
3664                 } else {
3665                         WLAN_LOG_DEBUG(3,"Received monitor frame: FCSerr set\n");
3666                 }
3667                 goto done;
3668
3669         default:
3670
3671                 WLAN_LOG_WARNING("Received frame on unsupported port=%d\n",
3672                         HFA384x_RXSTATUS_MACPORT_GET(rxdesc.status) );
3673                 goto done;
3674         }
3675
3676  failed:
3677         dev_kfree_skb(skb);
3678
3679  done:
3680         DBFEXIT;
3681         return;
3682 }
3683
3684
3685 /*----------------------------------------------------------------
3686 * hfa384x_int_rxmonitor
3687 *
3688 * Helper function for int_rx.  Handles monitor frames.
3689 * Note that this function allocates space for the FCS and sets it
3690 * to 0xffffffff.  The hfa384x doesn't give us the FCS value but the
3691 * higher layers expect it.  0xffffffff is used as a flag to indicate
3692 * the FCS is bogus.
3693 *
3694 * Arguments:
3695 *       wlandev         wlan device structure
3696 *       rxfid           received FID
3697 *       rxdesc          rx descriptor read from card in int_rx
3698 *
3699 * Returns:
3700 *       nothing
3701 *
3702 * Side effects:
3703 *       Allocates an skb and passes it up via the PF_PACKET interface.
3704 * Call context:
3705 *       interrupt
3706 ----------------------------------------------------------------*/
3707 static void hfa384x_int_rxmonitor( wlandevice_t *wlandev, UINT16 rxfid,
3708                                    hfa384x_rx_frame_t *rxdesc)
3709 {
3710         hfa384x_t                       *hw = wlandev->priv;
3711         UINT                            hdrlen = 0;
3712         UINT                            datalen = 0;
3713         UINT                            skblen = 0;
3714         UINT                            truncated = 0;
3715         UINT8                           *datap;
3716         UINT16                          fc;
3717         struct sk_buff                  *skb;
3718
3719         DBFENTER;
3720         /* Don't forget the status, time, and data_len fields are in host order */
3721         /* Figure out how big the frame is */
3722         fc = ieee2host16(rxdesc->frame_control);
3723         hdrlen = p80211_headerlen(fc);
3724         datalen = hfa384x2host_16(rxdesc->data_len);
3725
3726         /* Allocate an ind message+framesize skb */
3727         skblen = sizeof(p80211msg_lnxind_wlansniffrm_t) +
3728                 hdrlen + datalen + WLAN_CRC_LEN;
3729
3730         /* sanity check the length */
3731         if ( skblen >
3732                 (sizeof(p80211msg_lnxind_wlansniffrm_t) +
3733                 WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN) ) {
3734                 WLAN_LOG_DEBUG(1, "overlen frm: len=%d\n",
3735                         skblen - sizeof(p80211msg_lnxind_wlansniffrm_t));
3736         }
3737
3738         if ( (skb = dev_alloc_skb(skblen)) == NULL ) {
3739                 WLAN_LOG_ERROR("alloc_skb failed trying to allocate %d bytes\n", skblen);
3740                 return;
3741         }
3742
3743         /* only prepend the prism header if in the right mode */
3744         if ((wlandev->netdev->type == ARPHRD_IEEE80211_PRISM) &&
3745             (hw->sniffhdr == 0)) {
3746                 p80211msg_lnxind_wlansniffrm_t  *msg;
3747                 datap = skb_put(skb, sizeof(p80211msg_lnxind_wlansniffrm_t));
3748                 msg = (p80211msg_lnxind_wlansniffrm_t*) datap;
3749
3750                 /* Initialize the message members */
3751                 msg->msgcode = DIDmsg_lnxind_wlansniffrm;
3752                 msg->msglen = sizeof(p80211msg_lnxind_wlansniffrm_t);
3753                 strcpy(msg->devname, wlandev->name);
3754
3755                 msg->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
3756                 msg->hosttime.status = 0;
3757                 msg->hosttime.len = 4;
3758                 msg->hosttime.data = jiffies;
3759
3760                 msg->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
3761                 msg->mactime.status = 0;
3762                 msg->mactime.len = 4;
3763                 msg->mactime.data = rxdesc->time * 1000;
3764
3765                 msg->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
3766                 msg->channel.status = 0;
3767                 msg->channel.len = 4;
3768                 msg->channel.data = hw->sniff_channel;
3769
3770                 msg->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
3771                 msg->rssi.status = P80211ENUM_msgitem_status_no_value;
3772                 msg->rssi.len = 4;
3773                 msg->rssi.data = 0;
3774
3775                 msg->sq.did = DIDmsg_lnxind_wlansniffrm_sq;
3776                 msg->sq.status = P80211ENUM_msgitem_status_no_value;
3777                 msg->sq.len = 4;
3778                 msg->sq.data = 0;
3779
3780                 msg->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
3781                 msg->signal.status = 0;
3782                 msg->signal.len = 4;
3783                 msg->signal.data = rxdesc->signal;
3784
3785                 msg->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
3786                 msg->noise.status = 0;
3787                 msg->noise.len = 4;
3788                 msg->noise.data = rxdesc->silence;
3789
3790                 msg->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
3791                 msg->rate.status = 0;
3792                 msg->rate.len = 4;
3793                 msg->rate.data = rxdesc->rate / 5; /* set to 802.11 units */
3794
3795                 msg->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
3796                 msg->istx.status = 0;
3797                 msg->istx.len = 4;
3798                 msg->istx.data = P80211ENUM_truth_false;
3799
3800                 msg->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
3801                 msg->frmlen.status = 0;
3802                 msg->frmlen.len = 4;
3803                 msg->frmlen.data = hdrlen + datalen + WLAN_CRC_LEN;
3804         } else if ((wlandev->netdev->type == ARPHRD_IEEE80211_PRISM) &&
3805                    (hw->sniffhdr != 0)) {
3806                 p80211_caphdr_t         *caphdr;
3807                 /* The NEW header format! */
3808                 datap = skb_put(skb, sizeof(p80211_caphdr_t));
3809                 caphdr = (p80211_caphdr_t*) datap;
3810
3811                 caphdr->version =       htonl(P80211CAPTURE_VERSION);
3812                 caphdr->length =        htonl(sizeof(p80211_caphdr_t));
3813                 caphdr->mactime =       __cpu_to_be64(rxdesc->time);
3814                 caphdr->hosttime =      __cpu_to_be64(jiffies);
3815                 caphdr->phytype =       htonl(4); /* dss_dot11_b */
3816                 caphdr->channel =       htonl(hw->sniff_channel);
3817                 caphdr->datarate =      htonl(rxdesc->rate);
3818                 caphdr->antenna =       htonl(0); /* unknown */
3819                 caphdr->priority =      htonl(0); /* unknown */
3820                 caphdr->ssi_type =      htonl(3); /* rssi_raw */
3821                 caphdr->ssi_signal =    htonl(rxdesc->signal);
3822                 caphdr->ssi_noise =     htonl(rxdesc->silence);
3823                 caphdr->preamble =      htonl(0); /* unknown */
3824                 caphdr->encoding =      htonl(1); /* cck */
3825         }
3826         /* Copy the 802.11 header to the skb (ctl frames may be less than a full header) */
3827         datap = skb_put(skb, hdrlen);
3828         memcpy( datap, &(rxdesc->frame_control), hdrlen);
3829
3830         /* If any, copy the data from the card to the skb */
3831         if ( datalen > 0 )
3832         {
3833                 /* Truncate the packet if the user wants us to */
3834                 UINT    dataread = datalen;
3835                 if(hw->sniff_truncate > 0 && dataread > hw->sniff_truncate) {
3836                         dataread = hw->sniff_truncate;
3837                         truncated = 1;
3838                 }
3839
3840                 datap = skb_put(skb, dataread);
3841                 hfa384x_copy_from_bap(hw,
3842                         HFA384x_BAP_INT, rxfid, HFA384x_RX_DATA_OFF,
3843                         datap, dataread);
3844
3845                 /* check for unencrypted stuff if WEP bit set. */
3846                 if (*(datap - hdrlen + 1) & 0x40) // wep set
3847                   if ((*(datap) == 0xaa) && (*(datap+1) == 0xaa))
3848                     *(datap - hdrlen + 1) &= 0xbf; // clear wep; it's the 802.2 header!
3849         }
3850
3851         if (!truncated && hw->sniff_fcs) {
3852                 /* Set the FCS */
3853                 datap = skb_put(skb, WLAN_CRC_LEN);
3854                 memset( datap, 0xff, WLAN_CRC_LEN);
3855         }
3856
3857         /* pass it back up */
3858         prism2sta_ev_rx(wlandev, skb);
3859
3860         DBFEXIT;
3861         return;
3862 }
3863
3864 /*----------------------------------------------------------------
3865 * hfa384x_int_alloc
3866 *
3867 * Handles the Alloc event.
3868 *
3869 * Arguments:
3870 *       wlandev         wlan device structure
3871 *
3872 * Returns:
3873 *       nothing
3874 *
3875 * Side effects:
3876 *
3877 * Call context:
3878 *       interrupt
3879 ----------------------------------------------------------------*/
3880 static void hfa384x_int_alloc(wlandevice_t *wlandev)
3881 {
3882         hfa384x_t               *hw = wlandev->priv;
3883         UINT16                  fid;
3884         INT16                   result;
3885
3886         DBFENTER;
3887
3888         /* Handle the reclaimed FID */
3889         /*   collect the FID and push it onto the stack */
3890         fid = hfa384x_getreg(hw, HFA384x_ALLOCFID);
3891
3892         if ( fid != hw->infofid ) { /* It's a transmit fid */
3893                 WLAN_LOG_DEBUG(5, "int_alloc(%#x)\n", fid);
3894                 result = txfid_queue_add(hw, fid);
3895                 if (result != -1) {
3896                         prism2sta_ev_alloc(wlandev);
3897                         WLAN_LOG_DEBUG(5, "q_add.\n");
3898                 } else {
3899                         WLAN_LOG_DEBUG(5, "q_full.\n");
3900                 }
3901         } else {
3902                 /* unlock the info fid */
3903                 up(&hw->infofid_sem);
3904         }
3905
3906         DBFEXIT;
3907         return;
3908 }
3909
3910
3911 /*----------------------------------------------------------------
3912 * hfa384x_drvr_handover
3913 *
3914 * Sends a handover notification to the MAC.
3915 *
3916 * Arguments:
3917 *       hw              device structure
3918 *       addr            address of station that's left
3919 *
3920 * Returns:
3921 *       zero            success.
3922 *       -ERESTARTSYS    received signal while waiting for semaphore.
3923 *       -EIO            failed to write to bap, or failed in cmd.
3924 *
3925 * Side effects:
3926 *
3927 * Call context:
3928 *       process thread, NOTE: this call may block on a semaphore!
3929 ----------------------------------------------------------------*/
3930 int hfa384x_drvr_handover( hfa384x_t *hw, UINT8 *addr)
3931 {
3932         int                     result = 0;
3933         hfa384x_HandoverAddr_t  rec;
3934         UINT                    len;
3935         DBFENTER;
3936
3937         /* Acquire the infofid */
3938         if ( down_interruptible(&hw->infofid_sem) ) {
3939                 result = -ERESTARTSYS;
3940                 goto failed;
3941         }
3942
3943         /* Set up the record */
3944         len = sizeof(hfa384x_HandoverAddr_t);
3945         rec.framelen = host2hfa384x_16(len/2 - 1);
3946         rec.infotype = host2hfa384x_16(HFA384x_IT_HANDOVERADDR);
3947         memcpy(rec.handover_addr, addr, sizeof(rec.handover_addr));
3948
3949         /* Issue the command */
3950         result = hfa384x_cmd_notify(hw, 1, hw->infofid, &rec, len);
3951
3952         if ( result != 0 ) {
3953                 WLAN_LOG_DEBUG(1,"cmd_notify(%04x) failed, result=%d",
3954                         hw->infofid, result);
3955                 result = -EIO;
3956                 goto failed;
3957         }
3958
3959 failed:
3960         DBFEXIT;
3961         return result;
3962 }
3963
3964 void hfa384x_tx_timeout(wlandevice_t *wlandev)
3965 {
3966         DBFENTER;
3967
3968         WLAN_LOG_WARNING("Implement me.\n");
3969
3970         DBFEXIT;
3971 }
3972
3973 /* Handles all "rx" BAP operations */
3974 static void     hfa384x_bap_tasklet(unsigned long data)
3975 {
3976         hfa384x_t *hw = (hfa384x_t *) data;
3977         wlandevice_t *wlandev = hw->wlandev;
3978         int counter = prism2_irq_evread_max;
3979         int                     reg;
3980
3981         DBFENTER;
3982
3983         while (counter-- > 0) {
3984                 /* Get interrupt register */
3985                 reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
3986
3987                 if ((reg == 0xffff) ||
3988                     !(reg & HFA384x_INT_BAP_OP)) {
3989                         break;
3990                 }
3991
3992                 if ( HFA384x_EVSTAT_ISINFO(reg) ){
3993                         hfa384x_int_info(wlandev);
3994                         hfa384x_setreg(hw, HFA384x_EVACK_INFO_SET(1),
3995                                 HFA384x_EVACK);
3996                 }
3997                 if ( HFA384x_EVSTAT_ISTXEXC(reg) ){
3998                         hfa384x_int_txexc(wlandev);
3999                         hfa384x_setreg(hw, HFA384x_EVACK_TXEXC_SET(1),
4000                                 HFA384x_EVACK);
4001                 }
4002                 if ( HFA384x_EVSTAT_ISTX(reg) ){
4003                         hfa384x_int_tx(wlandev);
4004                         hfa384x_setreg(hw, HFA384x_EVACK_TX_SET(1),
4005                                 HFA384x_EVACK);
4006                 }
4007                 if ( HFA384x_EVSTAT_ISRX(reg) ){
4008                         hfa384x_int_rx(wlandev);
4009                         hfa384x_setreg(hw, HFA384x_EVACK_RX_SET(1),
4010                                 HFA384x_EVACK);
4011                 }
4012         }
4013
4014         /* re-enable interrupts */
4015         hfa384x_events_all(hw);
4016
4017         DBFEXIT;
4018 }