Staging: add wlan-ng prism2 usb driver
[deliverable/linux.git] / 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 }
This page took 0.177604 seconds and 5 git commands to generate.