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