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