Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
prism2sta.c
Go to the documentation of this file.
1 /* src/prism2/driver/prism2sta.c
2 *
3 * Implements the station functionality for prism2
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.
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 the module and linux pcmcia routines for the
48 * prism2 driver.
49 *
50 * --------------------------------------------------------------------
51 */
52 
53 #include <linux/module.h>
54 #include <linux/moduleparam.h>
55 #include <linux/kernel.h>
56 #include <linux/sched.h>
57 #include <linux/types.h>
58 #include <linux/init.h>
59 #include <linux/slab.h>
60 #include <linux/wireless.h>
61 #include <linux/netdevice.h>
62 #include <linux/workqueue.h>
64 #include <linux/ctype.h>
65 
66 #include <linux/io.h>
67 #include <linux/delay.h>
68 #include <asm/byteorder.h>
69 #include <linux/if_arp.h>
70 #include <linux/if_ether.h>
71 #include <linux/bitops.h>
72 
73 #include "p80211types.h"
74 #include "p80211hdr.h"
75 #include "p80211mgmt.h"
76 #include "p80211conv.h"
77 #include "p80211msg.h"
78 #include "p80211netdev.h"
79 #include "p80211req.h"
80 #include "p80211metadef.h"
81 #include "p80211metastruct.h"
82 #include "hfa384x.h"
83 #include "prism2mgmt.h"
84 
85 /* Create a string of printable chars from something that might not be */
86 /* It's recommended that the str be 4*len + 1 bytes long */
87 #define wlan_mkprintstr(buf, buflen, str, strlen) \
88 { \
89  int i = 0; \
90  int j = 0; \
91  memset(str, 0, (strlen)); \
92  for (i = 0; i < (buflen); i++) { \
93  if (isprint((buf)[i])) { \
94  (str)[j] = (buf)[i]; \
95  j++; \
96  } else { \
97  (str)[j] = '\\'; \
98  (str)[j+1] = 'x'; \
99  (str)[j+2] = hex_asc_hi((buf)[i]); \
100  (str)[j+3] = hex_asc_lo((buf)[i]); \
101  j += 4; \
102  } \
103  } \
104 }
105 
106 static char *dev_info = "prism2_usb";
107 static wlandevice_t *create_wlan(void);
108 
109 int prism2_reset_holdtime = 30; /* Reset hold time in ms */
110 int prism2_reset_settletime = 100; /* Reset settle time in ms */
111 
112 static int prism2_doreset; /* Do a reset at init? */
113 
114 module_param(prism2_doreset, int, 0644);
115 MODULE_PARM_DESC(prism2_doreset, "Issue a reset on initialization");
116 
118 MODULE_PARM_DESC(prism2_reset_holdtime, "reset hold time in ms");
120 MODULE_PARM_DESC(prism2_reset_settletime, "reset settle time in ms");
121 
122 MODULE_LICENSE("Dual MPL/GPL");
123 
124 void prism2_connect_result(wlandevice_t *wlandev, u8 failed);
125 void prism2_disconnected(wlandevice_t *wlandev);
126 void prism2_roamed(wlandevice_t *wlandev);
127 
128 static int prism2sta_open(wlandevice_t *wlandev);
129 static int prism2sta_close(wlandevice_t *wlandev);
130 static void prism2sta_reset(wlandevice_t *wlandev);
131 static int prism2sta_txframe(wlandevice_t *wlandev, struct sk_buff *skb,
132  union p80211_hdr *p80211_hdr,
133  struct p80211_metawep *p80211_wep);
134 static int prism2sta_mlmerequest(wlandevice_t *wlandev, struct p80211msg *msg);
135 static int prism2sta_getcardinfo(wlandevice_t *wlandev);
136 static int prism2sta_globalsetup(wlandevice_t *wlandev);
137 static int prism2sta_setmulticast(wlandevice_t *wlandev, netdevice_t *dev);
138 
139 static void prism2sta_inf_handover(wlandevice_t *wlandev,
140  hfa384x_InfFrame_t *inf);
141 static void prism2sta_inf_tallies(wlandevice_t *wlandev,
142  hfa384x_InfFrame_t *inf);
143 static void prism2sta_inf_hostscanresults(wlandevice_t *wlandev,
144  hfa384x_InfFrame_t *inf);
145 static void prism2sta_inf_scanresults(wlandevice_t *wlandev,
146  hfa384x_InfFrame_t *inf);
147 static void prism2sta_inf_chinforesults(wlandevice_t *wlandev,
148  hfa384x_InfFrame_t *inf);
149 static void prism2sta_inf_linkstatus(wlandevice_t *wlandev,
150  hfa384x_InfFrame_t *inf);
151 static void prism2sta_inf_assocstatus(wlandevice_t *wlandev,
152  hfa384x_InfFrame_t *inf);
153 static void prism2sta_inf_authreq(wlandevice_t *wlandev,
154  hfa384x_InfFrame_t *inf);
155 static void prism2sta_inf_authreq_defer(wlandevice_t *wlandev,
156  hfa384x_InfFrame_t *inf);
157 static void prism2sta_inf_psusercnt(wlandevice_t *wlandev,
158  hfa384x_InfFrame_t *inf);
159 
160 /*----------------------------------------------------------------
161 * prism2sta_open
162 *
163 * WLAN device open method. Called from p80211netdev when kernel
164 * device open (start) method is called in response to the
165 * SIOCSIIFFLAGS ioctl changing the flags bit IFF_UP
166 * from clear to set.
167 *
168 * Arguments:
169 * wlandev wlan device structure
170 *
171 * Returns:
172 * 0 success
173 * >0 f/w reported error
174 * <0 driver reported error
175 *
176 * Side effects:
177 *
178 * Call context:
179 * process thread
180 ----------------------------------------------------------------*/
181 static int prism2sta_open(wlandevice_t *wlandev)
182 {
183  /* We don't currently have to do anything else.
184  * The setup of the MAC should be subsequently completed via
185  * the mlme commands.
186  * Higher layers know we're ready from dev->start==1 and
187  * dev->tbusy==0. Our rx path knows to pass up received/
188  * frames because of dev->flags&IFF_UP is true.
189  */
190 
191  return 0;
192 }
193 
194 /*----------------------------------------------------------------
195 * prism2sta_close
196 *
197 * WLAN device close method. Called from p80211netdev when kernel
198 * device close method is called in response to the
199 * SIOCSIIFFLAGS ioctl changing the flags bit IFF_UP
200 * from set to clear.
201 *
202 * Arguments:
203 * wlandev wlan device structure
204 *
205 * Returns:
206 * 0 success
207 * >0 f/w reported error
208 * <0 driver reported error
209 *
210 * Side effects:
211 *
212 * Call context:
213 * process thread
214 ----------------------------------------------------------------*/
215 static int prism2sta_close(wlandevice_t *wlandev)
216 {
217  /* We don't currently have to do anything else.
218  * Higher layers know we're not ready from dev->start==0 and
219  * dev->tbusy==1. Our rx path knows to not pass up received
220  * frames because of dev->flags&IFF_UP is false.
221  */
222 
223  return 0;
224 }
225 
226 /*----------------------------------------------------------------
227 * prism2sta_reset
228 *
229 * Not currently implented.
230 *
231 * Arguments:
232 * wlandev wlan device structure
233 * none
234 *
235 * Returns:
236 * nothing
237 *
238 * Side effects:
239 *
240 * Call context:
241 * process thread
242 ----------------------------------------------------------------*/
243 static void prism2sta_reset(wlandevice_t *wlandev)
244 {
245 }
246 
247 /*----------------------------------------------------------------
248 * prism2sta_txframe
249 *
250 * Takes a frame from p80211 and queues it for transmission.
251 *
252 * Arguments:
253 * wlandev wlan device structure
254 * pb packet buffer struct. Contains an 802.11
255 * data frame.
256 * p80211_hdr points to the 802.11 header for the packet.
257 * Returns:
258 * 0 Success and more buffs available
259 * 1 Success but no more buffs
260 * 2 Allocation failure
261 * 4 Buffer full or queue busy
262 *
263 * Side effects:
264 *
265 * Call context:
266 * process thread
267 ----------------------------------------------------------------*/
268 static int prism2sta_txframe(wlandevice_t *wlandev, struct sk_buff *skb,
269  union p80211_hdr *p80211_hdr,
270  struct p80211_metawep *p80211_wep)
271 {
272  hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
273  int result;
274 
275  /* If necessary, set the 802.11 WEP bit */
276  if ((wlandev->hostwep & (HOSTWEP_PRIVACYINVOKED | HOSTWEP_ENCRYPT)) ==
278  p80211_hdr->a3.fc |= cpu_to_le16(WLAN_SET_FC_ISWEP(1));
279  }
280 
281  result = hfa384x_drvr_txframe(hw, skb, p80211_hdr, p80211_wep);
282 
283  return result;
284 }
285 
286 /*----------------------------------------------------------------
287 * prism2sta_mlmerequest
288 *
289 * wlan command message handler. All we do here is pass the message
290 * over to the prism2sta_mgmt_handler.
291 *
292 * Arguments:
293 * wlandev wlan device structure
294 * msg wlan command message
295 * Returns:
296 * 0 success
297 * <0 successful acceptance of message, but we're
298 * waiting for an async process to finish before
299 * we're done with the msg. When the asynch
300 * process is done, we'll call the p80211
301 * function p80211req_confirm() .
302 * >0 An error occurred while we were handling
303 * the message.
304 *
305 * Side effects:
306 *
307 * Call context:
308 * process thread
309 ----------------------------------------------------------------*/
310 static int prism2sta_mlmerequest(wlandevice_t *wlandev, struct p80211msg *msg)
311 {
312  hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
313 
314  int result = 0;
315 
316  switch (msg->msgcode) {
318  pr_debug("Received mibget request\n");
319  result = prism2mgmt_mibset_mibget(wlandev, msg);
320  break;
322  pr_debug("Received mibset request\n");
323  result = prism2mgmt_mibset_mibget(wlandev, msg);
324  break;
326  pr_debug("Received scan request\n");
327  result = prism2mgmt_scan(wlandev, msg);
328  break;
330  pr_debug("Received scan_results request\n");
331  result = prism2mgmt_scan_results(wlandev, msg);
332  break;
334  pr_debug("Received mlme start request\n");
335  result = prism2mgmt_start(wlandev, msg);
336  break;
337  /*
338  * Prism2 specific messages
339  */
341  pr_debug("Received mlme readpda request\n");
342  result = prism2mgmt_readpda(wlandev, msg);
343  break;
345  pr_debug("Received mlme ramdl_state request\n");
346  result = prism2mgmt_ramdl_state(wlandev, msg);
347  break;
349  pr_debug("Received mlme ramdl_write request\n");
350  result = prism2mgmt_ramdl_write(wlandev, msg);
351  break;
353  pr_debug("Received mlme flashdl_state request\n");
354  result = prism2mgmt_flashdl_state(wlandev, msg);
355  break;
357  pr_debug("Received mlme flashdl_write request\n");
358  result = prism2mgmt_flashdl_write(wlandev, msg);
359  break;
360  /*
361  * Linux specific messages
362  */
364  break; /* ignore me. */
366  {
367  struct p80211msg_lnxreq_ifstate *ifstatemsg;
368  pr_debug("Received mlme ifstate request\n");
369  ifstatemsg = (struct p80211msg_lnxreq_ifstate *) msg;
370  result =
371  prism2sta_ifstate(wlandev,
372  ifstatemsg->ifstate.data);
373  ifstatemsg->resultcode.status =
375  ifstatemsg->resultcode.data = result;
376  result = 0;
377  }
378  break;
380  pr_debug("Received mlme wlansniff request\n");
381  result = prism2mgmt_wlansniff(wlandev, msg);
382  break;
384  pr_debug("Received mlme autojoin request\n");
385  result = prism2mgmt_autojoin(wlandev, msg);
386  break;
388  struct p80211msg_lnxreq_commsquality *qualmsg;
389 
390  pr_debug("Received commsquality request\n");
391 
392  qualmsg = (struct p80211msg_lnxreq_commsquality *) msg;
393 
394  qualmsg->link.status =
396  qualmsg->level.status =
398  qualmsg->noise.status =
400 
401  qualmsg->link.data = le16_to_cpu(hw->qual.CQ_currBSS);
402  qualmsg->level.data = le16_to_cpu(hw->qual.ASL_currBSS);
403  qualmsg->noise.data = le16_to_cpu(hw->qual.ANL_currFC);
404  qualmsg->txrate.data = hw->txrate;
405 
406  break;
407  }
408  default:
409  printk(KERN_WARNING "Unknown mgmt request message 0x%08x",
410  msg->msgcode);
411  break;
412  }
413 
414  return result;
415 }
416 
417 /*----------------------------------------------------------------
418 * prism2sta_ifstate
419 *
420 * Interface state. This is the primary WLAN interface enable/disable
421 * handler. Following the driver/load/deviceprobe sequence, this
422 * function must be called with a state of "enable" before any other
423 * commands will be accepted.
424 *
425 * Arguments:
426 * wlandev wlan device structure
427 * msgp ptr to msg buffer
428 *
429 * Returns:
430 * A p80211 message resultcode value.
431 *
432 * Side effects:
433 *
434 * Call context:
435 * process thread (usually)
436 * interrupt
437 ----------------------------------------------------------------*/
439 {
440  hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
441  u32 result;
442 
444 
445  pr_debug("Current MSD state(%d), requesting(%d)\n",
446  wlandev->msdstate, ifstate);
447  switch (ifstate) {
449  switch (wlandev->msdstate) {
450  case WLAN_MSD_HWPRESENT:
452  /*
453  * Initialize the device+driver sufficiently
454  * for firmware loading.
455  */
457  if (result) {
459  "hfa384x_drvr_start() failed,"
460  "result=%d\n", (int)result);
461  result =
463  wlandev->msdstate = WLAN_MSD_HWPRESENT;
464  break;
465  }
466  wlandev->msdstate = WLAN_MSD_FWLOAD;
468  break;
469  case WLAN_MSD_FWLOAD:
472  break;
473  case WLAN_MSD_RUNNING:
475  "Cannot enter fwload state from enable state,"
476  "you must disable first.\n");
478  break;
479  case WLAN_MSD_HWFAIL:
480  default:
481  /* probe() had a problem or the msdstate contains
482  * an unrecognized value, there's nothing we can do.
483  */
485  break;
486  }
487  break;
489  switch (wlandev->msdstate) {
490  case WLAN_MSD_HWPRESENT:
491  case WLAN_MSD_FWLOAD:
493  /* Initialize the device+driver for full
494  * operation. Note that this might me an FWLOAD to
495  * to RUNNING transition so we must not do a chip
496  * or board level reset. Note that on failure,
497  * the MSD state is set to HWPRESENT because we
498  * can't make any assumptions about the state
499  * of the hardware or a previous firmware load.
500  */
502  if (result) {
504  "hfa384x_drvr_start() failed,"
505  "result=%d\n", (int)result);
506  result =
508  wlandev->msdstate = WLAN_MSD_HWPRESENT;
509  break;
510  }
511 
512  result = prism2sta_getcardinfo(wlandev);
513  if (result) {
515  "prism2sta_getcardinfo() failed,"
516  "result=%d\n", (int)result);
517  result =
519  hfa384x_drvr_stop(hw);
520  wlandev->msdstate = WLAN_MSD_HWPRESENT;
521  break;
522  }
523  result = prism2sta_globalsetup(wlandev);
524  if (result) {
526  "prism2sta_globalsetup() failed,"
527  "result=%d\n", (int)result);
528  result =
530  hfa384x_drvr_stop(hw);
531  wlandev->msdstate = WLAN_MSD_HWPRESENT;
532  break;
533  }
534  wlandev->msdstate = WLAN_MSD_RUNNING;
535  hw->join_ap = 0;
536  hw->join_retries = 60;
538  break;
539  case WLAN_MSD_RUNNING:
540  /* Do nothing, we're already in this state. */
542  break;
543  case WLAN_MSD_HWFAIL:
544  default:
545  /* probe() had a problem or the msdstate contains
546  * an unrecognized value, there's nothing we can do.
547  */
549  break;
550  }
551  break;
553  switch (wlandev->msdstate) {
554  case WLAN_MSD_HWPRESENT:
555  /* Do nothing, we're already in this state. */
557  break;
558  case WLAN_MSD_FWLOAD:
559  case WLAN_MSD_RUNNING:
561  /*
562  * TODO: Shut down the MAC completely. Here a chip
563  * or board level reset is probably called for.
564  * After a "disable" _all_ results are lost, even
565  * those from a fwload.
566  */
567  if (!wlandev->hwremoved)
568  netif_carrier_off(wlandev->netdev);
569 
570  hfa384x_drvr_stop(hw);
571 
572  wlandev->macmode = WLAN_MACMODE_NONE;
573  wlandev->msdstate = WLAN_MSD_HWPRESENT;
575  break;
576  case WLAN_MSD_HWFAIL:
577  default:
578  /* probe() had a problem or the msdstate contains
579  * an unrecognized value, there's nothing we can do.
580  */
582  break;
583  }
584  break;
585  default:
587  break;
588  }
589 
590  return result;
591 }
592 
593 /*----------------------------------------------------------------
594 * prism2sta_getcardinfo
595 *
596 * Collect the NICID, firmware version and any other identifiers
597 * we'd like to have in host-side data structures.
598 *
599 * Arguments:
600 * wlandev wlan device structure
601 *
602 * Returns:
603 * 0 success
604 * >0 f/w reported error
605 * <0 driver reported error
606 *
607 * Side effects:
608 *
609 * Call context:
610 * Either.
611 ----------------------------------------------------------------*/
612 static int prism2sta_getcardinfo(wlandevice_t *wlandev)
613 {
614  int result = 0;
615  hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
616  u16 temp;
618  char pstr[(HFA384x_RID_NICSERIALNUMBER_LEN * 4) + 1];
619 
620  /* Collect version and compatibility info */
621  /* Some are critical, some are not */
622  /* NIC identity */
624  &hw->ident_nic,
625  sizeof(hfa384x_compident_t));
626  if (result) {
627  printk(KERN_ERR "Failed to retrieve NICIDENTITY\n");
628  goto failed;
629  }
630 
631  /* get all the nic id fields in host byte order */
632  hw->ident_nic.id = le16_to_cpu(hw->ident_nic.id);
633  hw->ident_nic.variant = le16_to_cpu(hw->ident_nic.variant);
634  hw->ident_nic.major = le16_to_cpu(hw->ident_nic.major);
635  hw->ident_nic.minor = le16_to_cpu(hw->ident_nic.minor);
636 
637  printk(KERN_INFO "ident: nic h/w: id=0x%02x %d.%d.%d\n",
638  hw->ident_nic.id, hw->ident_nic.major,
639  hw->ident_nic.minor, hw->ident_nic.variant);
640 
641  /* Primary f/w identity */
643  &hw->ident_pri_fw,
644  sizeof(hfa384x_compident_t));
645  if (result) {
646  printk(KERN_ERR "Failed to retrieve PRIIDENTITY\n");
647  goto failed;
648  }
649 
650  /* get all the private fw id fields in host byte order */
651  hw->ident_pri_fw.id = le16_to_cpu(hw->ident_pri_fw.id);
652  hw->ident_pri_fw.variant = le16_to_cpu(hw->ident_pri_fw.variant);
653  hw->ident_pri_fw.major = le16_to_cpu(hw->ident_pri_fw.major);
654  hw->ident_pri_fw.minor = le16_to_cpu(hw->ident_pri_fw.minor);
655 
656  printk(KERN_INFO "ident: pri f/w: id=0x%02x %d.%d.%d\n",
657  hw->ident_pri_fw.id, hw->ident_pri_fw.major,
658  hw->ident_pri_fw.minor, hw->ident_pri_fw.variant);
659 
660  /* Station (Secondary?) f/w identity */
662  &hw->ident_sta_fw,
663  sizeof(hfa384x_compident_t));
664  if (result) {
665  printk(KERN_ERR "Failed to retrieve STAIDENTITY\n");
666  goto failed;
667  }
668 
669  if (hw->ident_nic.id < 0x8000) {
671  "FATAL: Card is not an Intersil Prism2/2.5/3\n");
672  result = -1;
673  goto failed;
674  }
675 
676  /* get all the station fw id fields in host byte order */
677  hw->ident_sta_fw.id = le16_to_cpu(hw->ident_sta_fw.id);
678  hw->ident_sta_fw.variant = le16_to_cpu(hw->ident_sta_fw.variant);
679  hw->ident_sta_fw.major = le16_to_cpu(hw->ident_sta_fw.major);
680  hw->ident_sta_fw.minor = le16_to_cpu(hw->ident_sta_fw.minor);
681 
682  /* strip out the 'special' variant bits */
683  hw->mm_mods = hw->ident_sta_fw.variant & (BIT(14) | BIT(15));
684  hw->ident_sta_fw.variant &= ~((u16) (BIT(14) | BIT(15)));
685 
686  if (hw->ident_sta_fw.id == 0x1f) {
688  "ident: sta f/w: id=0x%02x %d.%d.%d\n",
689  hw->ident_sta_fw.id, hw->ident_sta_fw.major,
690  hw->ident_sta_fw.minor, hw->ident_sta_fw.variant);
691  } else {
693  "ident: ap f/w: id=0x%02x %d.%d.%d\n",
694  hw->ident_sta_fw.id, hw->ident_sta_fw.major,
695  hw->ident_sta_fw.minor, hw->ident_sta_fw.variant);
696  printk(KERN_ERR "Unsupported Tertiary AP firmeare loaded!\n");
697  goto failed;
698  }
699 
700  /* Compatibility range, Modem supplier */
702  &hw->cap_sup_mfi,
703  sizeof(hfa384x_caplevel_t));
704  if (result) {
705  printk(KERN_ERR "Failed to retrieve MFISUPRANGE\n");
706  goto failed;
707  }
708 
709  /* get all the Compatibility range, modem interface supplier
710  fields in byte order */
711  hw->cap_sup_mfi.role = le16_to_cpu(hw->cap_sup_mfi.role);
712  hw->cap_sup_mfi.id = le16_to_cpu(hw->cap_sup_mfi.id);
713  hw->cap_sup_mfi.variant = le16_to_cpu(hw->cap_sup_mfi.variant);
714  hw->cap_sup_mfi.bottom = le16_to_cpu(hw->cap_sup_mfi.bottom);
715  hw->cap_sup_mfi.top = le16_to_cpu(hw->cap_sup_mfi.top);
716 
718  "MFI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
719  hw->cap_sup_mfi.role, hw->cap_sup_mfi.id,
720  hw->cap_sup_mfi.variant, hw->cap_sup_mfi.bottom,
721  hw->cap_sup_mfi.top);
722 
723  /* Compatibility range, Controller supplier */
725  &hw->cap_sup_cfi,
726  sizeof(hfa384x_caplevel_t));
727  if (result) {
728  printk(KERN_ERR "Failed to retrieve CFISUPRANGE\n");
729  goto failed;
730  }
731 
732  /* get all the Compatibility range, controller interface supplier
733  fields in byte order */
734  hw->cap_sup_cfi.role = le16_to_cpu(hw->cap_sup_cfi.role);
735  hw->cap_sup_cfi.id = le16_to_cpu(hw->cap_sup_cfi.id);
736  hw->cap_sup_cfi.variant = le16_to_cpu(hw->cap_sup_cfi.variant);
737  hw->cap_sup_cfi.bottom = le16_to_cpu(hw->cap_sup_cfi.bottom);
738  hw->cap_sup_cfi.top = le16_to_cpu(hw->cap_sup_cfi.top);
739 
741  "CFI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
742  hw->cap_sup_cfi.role, hw->cap_sup_cfi.id,
743  hw->cap_sup_cfi.variant, hw->cap_sup_cfi.bottom,
744  hw->cap_sup_cfi.top);
745 
746  /* Compatibility range, Primary f/w supplier */
748  &hw->cap_sup_pri,
749  sizeof(hfa384x_caplevel_t));
750  if (result) {
751  printk(KERN_ERR "Failed to retrieve PRISUPRANGE\n");
752  goto failed;
753  }
754 
755  /* get all the Compatibility range, primary firmware supplier
756  fields in byte order */
757  hw->cap_sup_pri.role = le16_to_cpu(hw->cap_sup_pri.role);
758  hw->cap_sup_pri.id = le16_to_cpu(hw->cap_sup_pri.id);
759  hw->cap_sup_pri.variant = le16_to_cpu(hw->cap_sup_pri.variant);
760  hw->cap_sup_pri.bottom = le16_to_cpu(hw->cap_sup_pri.bottom);
761  hw->cap_sup_pri.top = le16_to_cpu(hw->cap_sup_pri.top);
762 
764  "PRI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
765  hw->cap_sup_pri.role, hw->cap_sup_pri.id,
766  hw->cap_sup_pri.variant, hw->cap_sup_pri.bottom,
767  hw->cap_sup_pri.top);
768 
769  /* Compatibility range, Station f/w supplier */
771  &hw->cap_sup_sta,
772  sizeof(hfa384x_caplevel_t));
773  if (result) {
774  printk(KERN_ERR "Failed to retrieve STASUPRANGE\n");
775  goto failed;
776  }
777 
778  /* get all the Compatibility range, station firmware supplier
779  fields in byte order */
780  hw->cap_sup_sta.role = le16_to_cpu(hw->cap_sup_sta.role);
781  hw->cap_sup_sta.id = le16_to_cpu(hw->cap_sup_sta.id);
782  hw->cap_sup_sta.variant = le16_to_cpu(hw->cap_sup_sta.variant);
783  hw->cap_sup_sta.bottom = le16_to_cpu(hw->cap_sup_sta.bottom);
784  hw->cap_sup_sta.top = le16_to_cpu(hw->cap_sup_sta.top);
785 
786  if (hw->cap_sup_sta.id == 0x04) {
788  "STA:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
789  hw->cap_sup_sta.role, hw->cap_sup_sta.id,
790  hw->cap_sup_sta.variant, hw->cap_sup_sta.bottom,
791  hw->cap_sup_sta.top);
792  } else {
794  "AP:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
795  hw->cap_sup_sta.role, hw->cap_sup_sta.id,
796  hw->cap_sup_sta.variant, hw->cap_sup_sta.bottom,
797  hw->cap_sup_sta.top);
798  }
799 
800  /* Compatibility range, primary f/w actor, CFI supplier */
802  &hw->cap_act_pri_cfi,
803  sizeof(hfa384x_caplevel_t));
804  if (result) {
805  printk(KERN_ERR "Failed to retrieve PRI_CFIACTRANGES\n");
806  goto failed;
807  }
808 
809  /* get all the Compatibility range, primary f/w actor, CFI supplier
810  fields in byte order */
811  hw->cap_act_pri_cfi.role = le16_to_cpu(hw->cap_act_pri_cfi.role);
812  hw->cap_act_pri_cfi.id = le16_to_cpu(hw->cap_act_pri_cfi.id);
813  hw->cap_act_pri_cfi.variant = le16_to_cpu(hw->cap_act_pri_cfi.variant);
814  hw->cap_act_pri_cfi.bottom = le16_to_cpu(hw->cap_act_pri_cfi.bottom);
815  hw->cap_act_pri_cfi.top = le16_to_cpu(hw->cap_act_pri_cfi.top);
816 
818  "PRI-CFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
819  hw->cap_act_pri_cfi.role, hw->cap_act_pri_cfi.id,
820  hw->cap_act_pri_cfi.variant, hw->cap_act_pri_cfi.bottom,
821  hw->cap_act_pri_cfi.top);
822 
823  /* Compatibility range, sta f/w actor, CFI supplier */
825  &hw->cap_act_sta_cfi,
826  sizeof(hfa384x_caplevel_t));
827  if (result) {
828  printk(KERN_ERR "Failed to retrieve STA_CFIACTRANGES\n");
829  goto failed;
830  }
831 
832  /* get all the Compatibility range, station f/w actor, CFI supplier
833  fields in byte order */
834  hw->cap_act_sta_cfi.role = le16_to_cpu(hw->cap_act_sta_cfi.role);
835  hw->cap_act_sta_cfi.id = le16_to_cpu(hw->cap_act_sta_cfi.id);
836  hw->cap_act_sta_cfi.variant = le16_to_cpu(hw->cap_act_sta_cfi.variant);
837  hw->cap_act_sta_cfi.bottom = le16_to_cpu(hw->cap_act_sta_cfi.bottom);
838  hw->cap_act_sta_cfi.top = le16_to_cpu(hw->cap_act_sta_cfi.top);
839 
841  "STA-CFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
842  hw->cap_act_sta_cfi.role, hw->cap_act_sta_cfi.id,
843  hw->cap_act_sta_cfi.variant, hw->cap_act_sta_cfi.bottom,
844  hw->cap_act_sta_cfi.top);
845 
846  /* Compatibility range, sta f/w actor, MFI supplier */
848  &hw->cap_act_sta_mfi,
849  sizeof(hfa384x_caplevel_t));
850  if (result) {
851  printk(KERN_ERR "Failed to retrieve STA_MFIACTRANGES\n");
852  goto failed;
853  }
854 
855  /* get all the Compatibility range, station f/w actor, MFI supplier
856  fields in byte order */
857  hw->cap_act_sta_mfi.role = le16_to_cpu(hw->cap_act_sta_mfi.role);
858  hw->cap_act_sta_mfi.id = le16_to_cpu(hw->cap_act_sta_mfi.id);
859  hw->cap_act_sta_mfi.variant = le16_to_cpu(hw->cap_act_sta_mfi.variant);
860  hw->cap_act_sta_mfi.bottom = le16_to_cpu(hw->cap_act_sta_mfi.bottom);
861  hw->cap_act_sta_mfi.top = le16_to_cpu(hw->cap_act_sta_mfi.top);
862 
864  "STA-MFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
865  hw->cap_act_sta_mfi.role, hw->cap_act_sta_mfi.id,
866  hw->cap_act_sta_mfi.variant, hw->cap_act_sta_mfi.bottom,
867  hw->cap_act_sta_mfi.top);
868 
869  /* Serial Number */
872  if (!result) {
874  pstr, sizeof(pstr));
875  printk(KERN_INFO "Prism2 card SN: %s\n", pstr);
876  } else {
877  printk(KERN_ERR "Failed to retrieve Prism2 Card SN\n");
878  goto failed;
879  }
880 
881  /* Collect the MAC address */
883  wlandev->netdev->dev_addr, ETH_ALEN);
884  if (result != 0) {
885  printk(KERN_ERR "Failed to retrieve mac address\n");
886  goto failed;
887  }
888 
889  /* short preamble is always implemented */
891 
892  /* find out if hardware wep is implemented */
893  hfa384x_drvr_getconfig16(hw, HFA384x_RID_PRIVACYOPTIMP, &temp);
894  if (temp)
896 
897  /* get the dBm Scaling constant */
898  hfa384x_drvr_getconfig16(hw, HFA384x_RID_CNFDBMADJUST, &temp);
899  hw->dbmadjust = temp;
900 
901  /* Only enable scan by default on newer firmware */
902  if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
903  hw->ident_sta_fw.minor,
904  hw->ident_sta_fw.variant) <
905  HFA384x_FIRMWARE_VERSION(1, 5, 5)) {
906  wlandev->nsdcaps |= P80211_NSDCAP_NOSCAN;
907  }
908 
909  /* TODO: Set any internally managed config items */
910 
911  goto done;
912 failed:
913  printk(KERN_ERR "Failed, result=%d\n", result);
914 done:
915  return result;
916 }
917 
918 /*----------------------------------------------------------------
919 * prism2sta_globalsetup
920 *
921 * Set any global RIDs that we want to set at device activation.
922 *
923 * Arguments:
924 * wlandev wlan device structure
925 *
926 * Returns:
927 * 0 success
928 * >0 f/w reported error
929 * <0 driver reported error
930 *
931 * Side effects:
932 *
933 * Call context:
934 * process thread
935 ----------------------------------------------------------------*/
936 static int prism2sta_globalsetup(wlandevice_t *wlandev)
937 {
938  hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
939 
940  /* Set the maximum frame size */
941  return hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN,
943 }
944 
945 static int prism2sta_setmulticast(wlandevice_t *wlandev, netdevice_t *dev)
946 {
947  int result = 0;
948  hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
949 
950  u16 promisc;
951 
952  /* If we're not ready, what's the point? */
953  if (hw->state != HFA384x_STATE_RUNNING)
954  goto exit;
955 
956  if ((dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0)
957  promisc = P80211ENUM_truth_true;
958  else
959  promisc = P80211ENUM_truth_false;
960 
961  result =
962  hfa384x_drvr_setconfig16_async(hw, HFA384x_RID_PROMISCMODE,
963  promisc);
964 exit:
965  return result;
966 }
967 
968 /*----------------------------------------------------------------
969 * prism2sta_inf_handover
970 *
971 * Handles the receipt of a Handover info frame. Should only be present
972 * in APs only.
973 *
974 * Arguments:
975 * wlandev wlan device structure
976 * inf ptr to info frame (contents in hfa384x order)
977 *
978 * Returns:
979 * nothing
980 *
981 * Side effects:
982 *
983 * Call context:
984 * interrupt
985 ----------------------------------------------------------------*/
986 static void prism2sta_inf_handover(wlandevice_t *wlandev,
987  hfa384x_InfFrame_t *inf)
988 {
989  pr_debug("received infoframe:HANDOVER (unhandled)\n");
990 }
991 
992 /*----------------------------------------------------------------
993 * prism2sta_inf_tallies
994 *
995 * Handles the receipt of a CommTallies info frame.
996 *
997 * Arguments:
998 * wlandev wlan device structure
999 * inf ptr to info frame (contents in hfa384x order)
1000 *
1001 * Returns:
1002 * nothing
1003 *
1004 * Side effects:
1005 *
1006 * Call context:
1007 * interrupt
1008 ----------------------------------------------------------------*/
1009 static void prism2sta_inf_tallies(wlandevice_t *wlandev,
1010  hfa384x_InfFrame_t *inf)
1011 {
1012  hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
1013  u16 *src16;
1014  u32 *dst;
1015  u32 *src32;
1016  int i;
1017  int cnt;
1018 
1019  /*
1020  ** Determine if these are 16-bit or 32-bit tallies, based on the
1021  ** record length of the info record.
1022  */
1023 
1024  cnt = sizeof(hfa384x_CommTallies32_t) / sizeof(u32);
1025  if (inf->framelen > 22) {
1026  dst = (u32 *) &hw->tallies;
1027  src32 = (u32 *) &inf->info.commtallies32;
1028  for (i = 0; i < cnt; i++, dst++, src32++)
1029  *dst += le32_to_cpu(*src32);
1030  } else {
1031  dst = (u32 *) &hw->tallies;
1032  src16 = (u16 *) &inf->info.commtallies16;
1033  for (i = 0; i < cnt; i++, dst++, src16++)
1034  *dst += le16_to_cpu(*src16);
1035  }
1036 }
1037 
1038 /*----------------------------------------------------------------
1039 * prism2sta_inf_scanresults
1040 *
1041 * Handles the receipt of a Scan Results info frame.
1042 *
1043 * Arguments:
1044 * wlandev wlan device structure
1045 * inf ptr to info frame (contents in hfa384x order)
1046 *
1047 * Returns:
1048 * nothing
1049 *
1050 * Side effects:
1051 *
1052 * Call context:
1053 * interrupt
1054 ----------------------------------------------------------------*/
1055 static void prism2sta_inf_scanresults(wlandevice_t *wlandev,
1056  hfa384x_InfFrame_t *inf)
1057 {
1058 
1059  hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
1060  int nbss;
1062  int i;
1064  int result;
1065 
1066  /* Get the number of results, first in bytes, then in results */
1067  nbss = (inf->framelen * sizeof(u16)) -
1068  sizeof(inf->infotype) - sizeof(inf->info.scanresult.scanreason);
1069  nbss /= sizeof(hfa384x_ScanResultSub_t);
1070 
1071  /* Print em */
1072  pr_debug("rx scanresults, reason=%d, nbss=%d:\n",
1073  inf->info.scanresult.scanreason, nbss);
1074  for (i = 0; i < nbss; i++) {
1075  pr_debug("chid=%d anl=%d sl=%d bcnint=%d\n",
1076  sr->result[i].chid,
1077  sr->result[i].anl,
1078  sr->result[i].sl, sr->result[i].bcnint);
1079  pr_debug(" capinfo=0x%04x proberesp_rate=%d\n",
1080  sr->result[i].capinfo, sr->result[i].proberesp_rate);
1081  }
1082  /* issue a join request */
1083  joinreq.channel = sr->result[0].chid;
1084  memcpy(joinreq.bssid, sr->result[0].bssid, WLAN_BSSID_LEN);
1085  result = hfa384x_drvr_setconfig(hw,
1087  &joinreq, HFA384x_RID_JOINREQUEST_LEN);
1088  if (result) {
1089  printk(KERN_ERR "setconfig(joinreq) failed, result=%d\n",
1090  result);
1091  }
1092 }
1093 
1094 /*----------------------------------------------------------------
1095 * prism2sta_inf_hostscanresults
1096 *
1097 * Handles the receipt of a Scan Results info frame.
1098 *
1099 * Arguments:
1100 * wlandev wlan device structure
1101 * inf ptr to info frame (contents in hfa384x order)
1102 *
1103 * Returns:
1104 * nothing
1105 *
1106 * Side effects:
1107 *
1108 * Call context:
1109 * interrupt
1110 ----------------------------------------------------------------*/
1111 static void prism2sta_inf_hostscanresults(wlandevice_t *wlandev,
1112  hfa384x_InfFrame_t *inf)
1113 {
1114  hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
1115  int nbss;
1116 
1117  nbss = (inf->framelen - 3) / 32;
1118  pr_debug("Received %d hostscan results\n", nbss);
1119 
1120  if (nbss > 32)
1121  nbss = 32;
1122 
1123  kfree(hw->scanresults);
1124 
1125  hw->scanresults = kmalloc(sizeof(hfa384x_InfFrame_t), GFP_ATOMIC);
1126  memcpy(hw->scanresults, inf, sizeof(hfa384x_InfFrame_t));
1127 
1128  if (nbss == 0)
1129  nbss = -1;
1130 
1131  /* Notify/wake the sleeping caller. */
1132  hw->scanflag = nbss;
1133  wake_up_interruptible(&hw->cmdq);
1134 };
1135 
1136 /*----------------------------------------------------------------
1137 * prism2sta_inf_chinforesults
1138 *
1139 * Handles the receipt of a Channel Info Results info frame.
1140 *
1141 * Arguments:
1142 * wlandev wlan device structure
1143 * inf ptr to info frame (contents in hfa384x order)
1144 *
1145 * Returns:
1146 * nothing
1147 *
1148 * Side effects:
1149 *
1150 * Call context:
1151 * interrupt
1152 ----------------------------------------------------------------*/
1153 static void prism2sta_inf_chinforesults(wlandevice_t *wlandev,
1154  hfa384x_InfFrame_t *inf)
1155 {
1156  hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
1157  unsigned int i, n;
1158 
1159  hw->channel_info.results.scanchannels =
1161 
1162  for (i = 0, n = 0; i < HFA384x_CHINFORESULT_MAX; i++) {
1163  if (hw->channel_info.results.scanchannels & (1 << i)) {
1164  int channel =
1166  1;
1167  hfa384x_ChInfoResultSub_t *chinforesult =
1168  &hw->channel_info.results.result[channel];
1169  chinforesult->chid = channel;
1170  chinforesult->anl =
1172  chinforesult->pnl =
1174  chinforesult->active =
1176  active);
1177  pr_debug
1178  ("chinfo: channel %d, %s level (avg/peak)=%d/%d dB, pcf %d\n",
1179  channel + 1,
1180  chinforesult->
1182  : "noise", chinforesult->anl, chinforesult->pnl,
1183  chinforesult->
1185  n++;
1186  }
1187  }
1188  atomic_set(&hw->channel_info.done, 2);
1189 
1190  hw->channel_info.count = n;
1191 }
1192 
1194 {
1195  hfa384x_t *hw = container_of(data, struct hfa384x, link_bh);
1196  wlandevice_t *wlandev = hw->wlandev;
1198  int result;
1199 
1200  /* First let's process the auth frames */
1201  {
1202  struct sk_buff *skb;
1203  hfa384x_InfFrame_t *inf;
1204 
1205  while ((skb = skb_dequeue(&hw->authq))) {
1206  inf = (hfa384x_InfFrame_t *) skb->data;
1207  prism2sta_inf_authreq_defer(wlandev, inf);
1208  }
1209 
1210  }
1211 
1212  /* Now let's handle the linkstatus stuff */
1213  if (hw->link_status == hw->link_status_new)
1214  return;
1215 
1216  hw->link_status = hw->link_status_new;
1217 
1218  switch (hw->link_status) {
1220  /* I'm currently assuming that this is the initial link
1221  * state. It should only be possible immediately
1222  * following an Enable command.
1223  * Response:
1224  * Block Transmits, Ignore receives of data frames
1225  */
1226  netif_carrier_off(wlandev->netdev);
1227 
1228  printk(KERN_INFO "linkstatus=NOTCONNECTED (unhandled)\n");
1229  break;
1230 
1232  /* This one indicates a successful scan/join/auth/assoc.
1233  * When we have the full MLME complement, this event will
1234  * signify successful completion of both mlme_authenticate
1235  * and mlme_associate. State management will get a little
1236  * ugly here.
1237  * Response:
1238  * Indicate authentication and/or association
1239  * Enable Transmits, Receives and pass up data frames
1240  */
1241 
1242  netif_carrier_on(wlandev->netdev);
1243 
1244  /* If we are joining a specific AP, set our
1245  * state and reset retries
1246  */
1247  if (hw->join_ap == 1)
1248  hw->join_ap = 2;
1249  hw->join_retries = 60;
1250 
1251  /* Don't call this in monitor mode */
1252  if (wlandev->netdev->type == ARPHRD_ETHER) {
1253  u16 portstatus;
1254 
1255  printk(KERN_INFO "linkstatus=CONNECTED\n");
1256 
1257  /* For non-usb devices, we can use the sync versions */
1258  /* Collect the BSSID, and set state to allow tx */
1259 
1260  result = hfa384x_drvr_getconfig(hw,
1262  wlandev->bssid,
1263  WLAN_BSSID_LEN);
1264  if (result) {
1265  pr_debug
1266  ("getconfig(0x%02x) failed, result = %d\n",
1267  HFA384x_RID_CURRENTBSSID, result);
1268  return;
1269  }
1270 
1271  result = hfa384x_drvr_getconfig(hw,
1273  &ssid, sizeof(ssid));
1274  if (result) {
1275  pr_debug
1276  ("getconfig(0x%02x) failed, result = %d\n",
1277  HFA384x_RID_CURRENTSSID, result);
1278  return;
1279  }
1281  (p80211pstrd_t *) &
1282  wlandev->ssid);
1283 
1284  /* Collect the port status */
1285  result = hfa384x_drvr_getconfig16(hw,
1287  &portstatus);
1288  if (result) {
1289  pr_debug
1290  ("getconfig(0x%02x) failed, result = %d\n",
1291  HFA384x_RID_PORTSTATUS, result);
1292  return;
1293  }
1294  wlandev->macmode =
1295  (portstatus == HFA384x_PSTATUS_CONN_IBSS) ?
1297 
1298  /* signal back up to cfg80211 layer */
1300 
1301  /* Get the ball rolling on the comms quality stuff */
1302  prism2sta_commsqual_defer(&hw->commsqual_bh);
1303  }
1304  break;
1305 
1307  /* This one indicates that our association is gone. We've
1308  * lost connection with the AP and/or been disassociated.
1309  * This indicates that the MAC has completely cleared it's
1310  * associated state. We * should send a deauth indication
1311  * (implying disassoc) up * to the MLME.
1312  * Response:
1313  * Indicate Deauthentication
1314  * Block Transmits, Ignore receives of data frames
1315  */
1316  if (wlandev->netdev->type == ARPHRD_ETHER)
1318  "linkstatus=DISCONNECTED (unhandled)\n");
1319  wlandev->macmode = WLAN_MACMODE_NONE;
1320 
1321  netif_carrier_off(wlandev->netdev);
1322 
1323  /* signal back up to cfg80211 layer */
1324  prism2_disconnected(wlandev);
1325 
1326  break;
1327 
1329  /* This one indicates that the MAC has decided to and
1330  * successfully completed a change to another AP. We
1331  * should probably implement a reassociation indication
1332  * in response to this one. I'm thinking that the the
1333  * p80211 layer needs to be notified in case of
1334  * buffering/queueing issues. User mode also needs to be
1335  * notified so that any BSS dependent elements can be
1336  * updated.
1337  * associated state. We * should send a deauth indication
1338  * (implying disassoc) up * to the MLME.
1339  * Response:
1340  * Indicate Reassociation
1341  * Enable Transmits, Receives and pass up data frames
1342  */
1343  printk(KERN_INFO "linkstatus=AP_CHANGE\n");
1344 
1345  result = hfa384x_drvr_getconfig(hw,
1347  wlandev->bssid, WLAN_BSSID_LEN);
1348  if (result) {
1349  pr_debug("getconfig(0x%02x) failed, result = %d\n",
1350  HFA384x_RID_CURRENTBSSID, result);
1351  return;
1352  }
1353 
1354  result = hfa384x_drvr_getconfig(hw,
1356  &ssid, sizeof(ssid));
1357  if (result) {
1358  pr_debug("getconfig(0x%02x) failed, result = %d\n",
1359  HFA384x_RID_CURRENTSSID, result);
1360  return;
1361  }
1363  (p80211pstrd_t *) &wlandev->ssid);
1364 
1365  hw->link_status = HFA384x_LINK_CONNECTED;
1366  netif_carrier_on(wlandev->netdev);
1367 
1368  /* signal back up to cfg80211 layer */
1369  prism2_roamed(wlandev);
1370 
1371  break;
1372 
1374  /* This one indicates that the MAC has decided that the
1375  * AP is out of range, but hasn't found a better candidate
1376  * so the MAC maintains its "associated" state in case
1377  * we get back in range. We should block transmits and
1378  * receives in this state. Do we need an indication here?
1379  * Probably not since a polling user-mode element would
1380  * get this status from from p2PortStatus(FD40). What about
1381  * p80211?
1382  * Response:
1383  * Block Transmits, Ignore receives of data frames
1384  */
1385  printk(KERN_INFO "linkstatus=AP_OUTOFRANGE (unhandled)\n");
1386 
1387  netif_carrier_off(wlandev->netdev);
1388 
1389  break;
1390 
1392  /* This one indicates that the MAC has decided that the
1393  * AP is back in range. We continue working with our
1394  * existing association.
1395  * Response:
1396  * Enable Transmits, Receives and pass up data frames
1397  */
1398  printk(KERN_INFO "linkstatus=AP_INRANGE\n");
1399 
1400  hw->link_status = HFA384x_LINK_CONNECTED;
1401  netif_carrier_on(wlandev->netdev);
1402 
1403  break;
1404 
1406  /* This one is actually a peer to CONNECTED. We've
1407  * requested a join for a given SSID and optionally BSSID.
1408  * We can use this one to indicate authentication and
1409  * association failures. The trick is going to be
1410  * 1) identifying the failure, and 2) state management.
1411  * Response:
1412  * Disable Transmits, Ignore receives of data frames
1413  */
1414  if (hw->join_ap && --hw->join_retries > 0) {
1416  joinreq = hw->joinreq;
1417  /* Send the join request */
1420  &joinreq,
1423  "linkstatus=ASSOCFAIL (re-submitting join)\n");
1424  } else {
1425  printk(KERN_INFO "linkstatus=ASSOCFAIL (unhandled)\n");
1426  }
1427 
1428  netif_carrier_off(wlandev->netdev);
1429 
1430  /* signal back up to cfg80211 layer */
1432 
1433  break;
1434 
1435  default:
1436  /* This is bad, IO port problems? */
1438  "unknown linkstatus=0x%02x\n", hw->link_status);
1439  return;
1440  }
1441 
1442  wlandev->linkstatus = (hw->link_status == HFA384x_LINK_CONNECTED);
1443 }
1444 
1445 /*----------------------------------------------------------------
1446 * prism2sta_inf_linkstatus
1447 *
1448 * Handles the receipt of a Link Status info frame.
1449 *
1450 * Arguments:
1451 * wlandev wlan device structure
1452 * inf ptr to info frame (contents in hfa384x order)
1453 *
1454 * Returns:
1455 * nothing
1456 *
1457 * Side effects:
1458 *
1459 * Call context:
1460 * interrupt
1461 ----------------------------------------------------------------*/
1462 static void prism2sta_inf_linkstatus(wlandevice_t *wlandev,
1463  hfa384x_InfFrame_t *inf)
1464 {
1465  hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
1466 
1467  hw->link_status_new = le16_to_cpu(inf->info.linkstatus.linkstatus);
1468 
1469  schedule_work(&hw->link_bh);
1470 }
1471 
1472 /*----------------------------------------------------------------
1473 * prism2sta_inf_assocstatus
1474 *
1475 * Handles the receipt of an Association Status info frame. Should
1476 * be present in APs only.
1477 *
1478 * Arguments:
1479 * wlandev wlan device structure
1480 * inf ptr to info frame (contents in hfa384x order)
1481 *
1482 * Returns:
1483 * nothing
1484 *
1485 * Side effects:
1486 *
1487 * Call context:
1488 * interrupt
1489 ----------------------------------------------------------------*/
1490 static void prism2sta_inf_assocstatus(wlandevice_t *wlandev,
1491  hfa384x_InfFrame_t *inf)
1492 {
1493  hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
1495  int i;
1496 
1497  memcpy(&rec, &inf->info.assocstatus, sizeof(rec));
1498  rec.assocstatus = le16_to_cpu(rec.assocstatus);
1499  rec.reason = le16_to_cpu(rec.reason);
1500 
1501  /*
1502  ** Find the address in the list of authenticated stations.
1503  ** If it wasn't found, then this address has not been previously
1504  ** authenticated and something weird has happened if this is
1505  ** anything other than an "authentication failed" message.
1506  ** If the address was found, then set the "associated" flag for
1507  ** that station, based on whether the station is associating or
1508  ** losing its association. Something weird has also happened
1509  ** if we find the address in the list of authenticated stations
1510  ** but we are getting an "authentication failed" message.
1511  */
1512 
1513  for (i = 0; i < hw->authlist.cnt; i++)
1514  if (memcmp(rec.sta_addr, hw->authlist.addr[i], ETH_ALEN) == 0)
1515  break;
1516 
1517  if (i >= hw->authlist.cnt) {
1518  if (rec.assocstatus != HFA384x_ASSOCSTATUS_AUTHFAIL)
1520  "assocstatus info frame received for non-authenticated station.\n");
1521  } else {
1522  hw->authlist.assoc[i] =
1523  (rec.assocstatus == HFA384x_ASSOCSTATUS_STAASSOC ||
1524  rec.assocstatus == HFA384x_ASSOCSTATUS_REASSOC);
1525 
1526  if (rec.assocstatus == HFA384x_ASSOCSTATUS_AUTHFAIL)
1528 "authfail assocstatus info frame received for authenticated station.\n");
1529  }
1530 }
1531 
1532 /*----------------------------------------------------------------
1533 * prism2sta_inf_authreq
1534 *
1535 * Handles the receipt of an Authentication Request info frame. Should
1536 * be present in APs only.
1537 *
1538 * Arguments:
1539 * wlandev wlan device structure
1540 * inf ptr to info frame (contents in hfa384x order)
1541 *
1542 * Returns:
1543 * nothing
1544 *
1545 * Side effects:
1546 *
1547 * Call context:
1548 * interrupt
1549 *
1550 ----------------------------------------------------------------*/
1551 static void prism2sta_inf_authreq(wlandevice_t *wlandev,
1552  hfa384x_InfFrame_t *inf)
1553 {
1554  hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
1555  struct sk_buff *skb;
1556 
1557  skb = dev_alloc_skb(sizeof(*inf));
1558  if (skb) {
1559  skb_put(skb, sizeof(*inf));
1560  memcpy(skb->data, inf, sizeof(*inf));
1561  skb_queue_tail(&hw->authq, skb);
1562  schedule_work(&hw->link_bh);
1563  }
1564 }
1565 
1566 static void prism2sta_inf_authreq_defer(wlandevice_t *wlandev,
1567  hfa384x_InfFrame_t *inf)
1568 {
1569  hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
1571 
1572  int i, added, result, cnt;
1573  u8 *addr;
1574 
1575  /*
1576  ** Build the AuthenticateStation record. Initialize it for denying
1577  ** authentication.
1578  */
1579 
1580  memcpy(rec.address, inf->info.authreq.sta_addr, ETH_ALEN);
1581  rec.status = P80211ENUM_status_unspec_failure;
1582 
1583  /*
1584  ** Authenticate based on the access mode.
1585  */
1586 
1587  switch (hw->accessmode) {
1588  case WLAN_ACCESS_NONE:
1589 
1590  /*
1591  ** Deny all new authentications. However, if a station
1592  ** is ALREADY authenticated, then accept it.
1593  */
1594 
1595  for (i = 0; i < hw->authlist.cnt; i++)
1596  if (memcmp(rec.address, hw->authlist.addr[i],
1597  ETH_ALEN) == 0) {
1598  rec.status = P80211ENUM_status_successful;
1599  break;
1600  }
1601 
1602  break;
1603 
1604  case WLAN_ACCESS_ALL:
1605 
1606  /*
1607  ** Allow all authentications.
1608  */
1609 
1610  rec.status = P80211ENUM_status_successful;
1611  break;
1612 
1613  case WLAN_ACCESS_ALLOW:
1614 
1615  /*
1616  ** Only allow the authentication if the MAC address
1617  ** is in the list of allowed addresses.
1618  **
1619  ** Since this is the interrupt handler, we may be here
1620  ** while the access list is in the middle of being
1621  ** updated. Choose the list which is currently okay.
1622  ** See "prism2mib_priv_accessallow()" for details.
1623  */
1624 
1625  if (hw->allow.modify == 0) {
1626  cnt = hw->allow.cnt;
1627  addr = hw->allow.addr[0];
1628  } else {
1629  cnt = hw->allow.cnt1;
1630  addr = hw->allow.addr1[0];
1631  }
1632 
1633  for (i = 0; i < cnt; i++, addr += ETH_ALEN)
1634  if (memcmp(rec.address, addr, ETH_ALEN) == 0) {
1635  rec.status = P80211ENUM_status_successful;
1636  break;
1637  }
1638 
1639  break;
1640 
1641  case WLAN_ACCESS_DENY:
1642 
1643  /*
1644  ** Allow the authentication UNLESS the MAC address is
1645  ** in the list of denied addresses.
1646  **
1647  ** Since this is the interrupt handler, we may be here
1648  ** while the access list is in the middle of being
1649  ** updated. Choose the list which is currently okay.
1650  ** See "prism2mib_priv_accessdeny()" for details.
1651  */
1652 
1653  if (hw->deny.modify == 0) {
1654  cnt = hw->deny.cnt;
1655  addr = hw->deny.addr[0];
1656  } else {
1657  cnt = hw->deny.cnt1;
1658  addr = hw->deny.addr1[0];
1659  }
1660 
1661  rec.status = P80211ENUM_status_successful;
1662 
1663  for (i = 0; i < cnt; i++, addr += ETH_ALEN)
1664  if (memcmp(rec.address, addr, ETH_ALEN) == 0) {
1665  rec.status = P80211ENUM_status_unspec_failure;
1666  break;
1667  }
1668 
1669  break;
1670  }
1671 
1672  /*
1673  ** If the authentication is okay, then add the MAC address to the
1674  ** list of authenticated stations. Don't add the address if it
1675  ** is already in the list. (802.11b does not seem to disallow
1676  ** a station from issuing an authentication request when the
1677  ** station is already authenticated. Does this sort of thing
1678  ** ever happen? We might as well do the check just in case.)
1679  */
1680 
1681  added = 0;
1682 
1683  if (rec.status == P80211ENUM_status_successful) {
1684  for (i = 0; i < hw->authlist.cnt; i++)
1685  if (memcmp(rec.address, hw->authlist.addr[i], ETH_ALEN)
1686  == 0)
1687  break;
1688 
1689  if (i >= hw->authlist.cnt) {
1690  if (hw->authlist.cnt >= WLAN_AUTH_MAX) {
1691  rec.status = P80211ENUM_status_ap_full;
1692  } else {
1693  memcpy(hw->authlist.addr[hw->authlist.cnt],
1694  rec.address, ETH_ALEN);
1695  hw->authlist.cnt++;
1696  added = 1;
1697  }
1698  }
1699  }
1700 
1701  /*
1702  ** Send back the results of the authentication. If this doesn't work,
1703  ** then make sure to remove the address from the authenticated list if
1704  ** it was added.
1705  */
1706 
1707  rec.status = cpu_to_le16(rec.status);
1708  rec.algorithm = inf->info.authreq.algorithm;
1709 
1711  &rec, sizeof(rec));
1712  if (result) {
1713  if (added)
1714  hw->authlist.cnt--;
1716  "setconfig(authenticatestation) failed, result=%d\n",
1717  result);
1718  }
1719 }
1720 
1721 /*----------------------------------------------------------------
1722 * prism2sta_inf_psusercnt
1723 *
1724 * Handles the receipt of a PowerSaveUserCount info frame. Should
1725 * be present in APs only.
1726 *
1727 * Arguments:
1728 * wlandev wlan device structure
1729 * inf ptr to info frame (contents in hfa384x order)
1730 *
1731 * Returns:
1732 * nothing
1733 *
1734 * Side effects:
1735 *
1736 * Call context:
1737 * interrupt
1738 ----------------------------------------------------------------*/
1739 static void prism2sta_inf_psusercnt(wlandevice_t *wlandev,
1740  hfa384x_InfFrame_t *inf)
1741 {
1742  hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
1743 
1744  hw->psusercount = le16_to_cpu(inf->info.psusercnt.usercnt);
1745 }
1746 
1747 /*----------------------------------------------------------------
1748 * prism2sta_ev_info
1749 *
1750 * Handles the Info event.
1751 *
1752 * Arguments:
1753 * wlandev wlan device structure
1754 * inf ptr to a generic info frame
1755 *
1756 * Returns:
1757 * nothing
1758 *
1759 * Side effects:
1760 *
1761 * Call context:
1762 * interrupt
1763 ----------------------------------------------------------------*/
1765 {
1766  inf->infotype = le16_to_cpu(inf->infotype);
1767  /* Dispatch */
1768  switch (inf->infotype) {
1770  prism2sta_inf_handover(wlandev, inf);
1771  break;
1773  prism2sta_inf_tallies(wlandev, inf);
1774  break;
1776  prism2sta_inf_hostscanresults(wlandev, inf);
1777  break;
1779  prism2sta_inf_scanresults(wlandev, inf);
1780  break;
1782  prism2sta_inf_chinforesults(wlandev, inf);
1783  break;
1784  case HFA384x_IT_LINKSTATUS:
1785  prism2sta_inf_linkstatus(wlandev, inf);
1786  break;
1788  prism2sta_inf_assocstatus(wlandev, inf);
1789  break;
1790  case HFA384x_IT_AUTHREQ:
1791  prism2sta_inf_authreq(wlandev, inf);
1792  break;
1793  case HFA384x_IT_PSUSERCNT:
1794  prism2sta_inf_psusercnt(wlandev, inf);
1795  break;
1797  printk(KERN_WARNING "Unhandled IT_KEYIDCHANGED\n");
1798  break;
1799  case HFA384x_IT_ASSOCREQ:
1800  printk(KERN_WARNING "Unhandled IT_ASSOCREQ\n");
1801  break;
1802  case HFA384x_IT_MICFAILURE:
1803  printk(KERN_WARNING "Unhandled IT_MICFAILURE\n");
1804  break;
1805  default:
1807  "Unknown info type=0x%02x\n", inf->infotype);
1808  break;
1809  }
1810 }
1811 
1812 /*----------------------------------------------------------------
1813 * prism2sta_ev_txexc
1814 *
1815 * Handles the TxExc event. A Transmit Exception event indicates
1816 * that the MAC's TX process was unsuccessful - so the packet did
1817 * not get transmitted.
1818 *
1819 * Arguments:
1820 * wlandev wlan device structure
1821 * status tx frame status word
1822 *
1823 * Returns:
1824 * nothing
1825 *
1826 * Side effects:
1827 *
1828 * Call context:
1829 * interrupt
1830 ----------------------------------------------------------------*/
1832 {
1833  pr_debug("TxExc status=0x%x.\n", status);
1834 }
1835 
1836 /*----------------------------------------------------------------
1837 * prism2sta_ev_tx
1838 *
1839 * Handles the Tx event.
1840 *
1841 * Arguments:
1842 * wlandev wlan device structure
1843 * status tx frame status word
1844 * Returns:
1845 * nothing
1846 *
1847 * Side effects:
1848 *
1849 * Call context:
1850 * interrupt
1851 ----------------------------------------------------------------*/
1853 {
1854  pr_debug("Tx Complete, status=0x%04x\n", status);
1855  /* update linux network stats */
1856  wlandev->linux_stats.tx_packets++;
1857 }
1858 
1859 /*----------------------------------------------------------------
1860 * prism2sta_ev_rx
1861 *
1862 * Handles the Rx event.
1863 *
1864 * Arguments:
1865 * wlandev wlan device structure
1866 *
1867 * Returns:
1868 * nothing
1869 *
1870 * Side effects:
1871 *
1872 * Call context:
1873 * interrupt
1874 ----------------------------------------------------------------*/
1875 void prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb)
1876 {
1877  p80211netdev_rx(wlandev, skb);
1878 }
1879 
1880 /*----------------------------------------------------------------
1881 * prism2sta_ev_alloc
1882 *
1883 * Handles the Alloc event.
1884 *
1885 * Arguments:
1886 * wlandev wlan device structure
1887 *
1888 * Returns:
1889 * nothing
1890 *
1891 * Side effects:
1892 *
1893 * Call context:
1894 * interrupt
1895 ----------------------------------------------------------------*/
1897 {
1898  netif_wake_queue(wlandev->netdev);
1899 }
1900 
1901 /*----------------------------------------------------------------
1902 * create_wlan
1903 *
1904 * Called at module init time. This creates the wlandevice_t structure
1905 * and initializes it with relevant bits.
1906 *
1907 * Arguments:
1908 * none
1909 *
1910 * Returns:
1911 * the created wlandevice_t structure.
1912 *
1913 * Side effects:
1914 * also allocates the priv/hw structures.
1915 *
1916 * Call context:
1917 * process thread
1918 *
1919 ----------------------------------------------------------------*/
1920 static wlandevice_t *create_wlan(void)
1921 {
1922  wlandevice_t *wlandev = NULL;
1923  hfa384x_t *hw = NULL;
1924 
1925  /* Alloc our structures */
1926  wlandev = kzalloc(sizeof(wlandevice_t), GFP_KERNEL);
1927  hw = kzalloc(sizeof(hfa384x_t), GFP_KERNEL);
1928 
1929  if (!wlandev || !hw) {
1930  printk(KERN_ERR "%s: Memory allocation failure.\n", dev_info);
1931  kfree(wlandev);
1932  kfree(hw);
1933  return NULL;
1934  }
1935 
1936  /* Initialize the network device object. */
1937  wlandev->nsdname = dev_info;
1939  wlandev->priv = hw;
1940  wlandev->open = prism2sta_open;
1941  wlandev->close = prism2sta_close;
1942  wlandev->reset = prism2sta_reset;
1943  wlandev->txframe = prism2sta_txframe;
1944  wlandev->mlmerequest = prism2sta_mlmerequest;
1945  wlandev->set_multicast_list = prism2sta_setmulticast;
1946  wlandev->tx_timeout = hfa384x_tx_timeout;
1947 
1949 
1950  /* Initialize the device private data structure. */
1951  hw->dot11_desired_bss_type = 1;
1952 
1953  return wlandev;
1954 }
1955 
1957 {
1958  hfa384x_t *hw = container_of(data, struct hfa384x, commsqual_bh);
1959  wlandevice_t *wlandev = hw->wlandev;
1961  struct p80211msg_dot11req_mibget msg;
1963  &msg.mibattribute.data;
1964  int result = 0;
1965 
1966  if (hw->wlandev->hwremoved)
1967  return;
1968 
1969  /* we don't care if we're in AP mode */
1970  if ((wlandev->macmode == WLAN_MACMODE_NONE) ||
1971  (wlandev->macmode == WLAN_MACMODE_ESS_AP)) {
1972  return;
1973  }
1974 
1975  /* It only makes sense to poll these in non-IBSS */
1976  if (wlandev->macmode != WLAN_MACMODE_IBSS_STA) {
1977  result = hfa384x_drvr_getconfig(
1979  &hw->qual, HFA384x_RID_DBMCOMMSQUALITY_LEN);
1980 
1981  if (result) {
1982  printk(KERN_ERR "error fetching commsqual\n");
1983  return;
1984  }
1985 
1986  pr_debug("commsqual %d %d %d\n",
1987  le16_to_cpu(hw->qual.CQ_currBSS),
1988  le16_to_cpu(hw->qual.ASL_currBSS),
1989  le16_to_cpu(hw->qual.ANL_currFC));
1990  }
1991 
1992  /* Get the signal rate */
1994  mibitem->did = DIDmib_p2_p2MAC_p2CurrentTxRate;
1995  result = p80211req_dorequest(wlandev, (u8 *) &msg);
1996 
1997  if (result) {
1998  pr_debug("get signal rate failed, result = %d\n",
1999  result);
2000  return;
2001  }
2002 
2003  switch (mibitem->data) {
2004  case HFA384x_RATEBIT_1:
2005  hw->txrate = 10;
2006  break;
2007  case HFA384x_RATEBIT_2:
2008  hw->txrate = 20;
2009  break;
2010  case HFA384x_RATEBIT_5dot5:
2011  hw->txrate = 55;
2012  break;
2013  case HFA384x_RATEBIT_11:
2014  hw->txrate = 110;
2015  break;
2016  default:
2017  pr_debug("Bad ratebit (%d)\n", mibitem->data);
2018  }
2019 
2020  /* Lastly, we need to make sure the BSSID didn't change on us */
2021  result = hfa384x_drvr_getconfig(hw,
2023  wlandev->bssid, WLAN_BSSID_LEN);
2024  if (result) {
2025  pr_debug("getconfig(0x%02x) failed, result = %d\n",
2026  HFA384x_RID_CURRENTBSSID, result);
2027  return;
2028  }
2029 
2030  result = hfa384x_drvr_getconfig(hw,
2032  &ssid, sizeof(ssid));
2033  if (result) {
2034  pr_debug("getconfig(0x%02x) failed, result = %d\n",
2035  HFA384x_RID_CURRENTSSID, result);
2036  return;
2037  }
2039  (p80211pstrd_t *) &wlandev->ssid);
2040 
2041  /* Reschedule timer */
2042  mod_timer(&hw->commsqual_timer, jiffies + HZ);
2043 }
2044 
2045 void prism2sta_commsqual_timer(unsigned long data)
2046 {
2047  hfa384x_t *hw = (hfa384x_t *) data;
2048 
2049  schedule_work(&hw->commsqual_bh);
2050 }