blob: de2ec1e7c9de1d1d5486fd2113eee0c09915ad7c [file] [log] [blame]
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -07001/* src/prism2/driver/prism2mgmt.c
2*
3* Management request handler functions.
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* The functions in this file handle management requests sent from
48* user mode.
49*
50* Most of these functions have two separate blocks of code that are
51* conditional on whether this is a station or an AP. This is used
52* to separate out the STA and AP responses to these management primitives.
53* It's a choice (good, bad, indifferent?) to have the code in the same
54* place so it's clear that the same primitive is implemented in both
55* cases but has different behavior.
56*
57* --------------------------------------------------------------------
58*/
59
60/*================================================================*/
61/* System Includes */
62#define WLAN_DBVAR prism2_debug
63
64#include "version.h"
65
66
67#include <linux/version.h>
68
69#include <linux/if_arp.h>
70#include <linux/module.h>
71#include <linux/kernel.h>
72#include <linux/wait.h>
73#include <linux/sched.h>
74#include <linux/types.h>
75#include <linux/slab.h>
76#include <linux/wireless.h>
77#include <linux/netdevice.h>
78#include <linux/delay.h>
79#include <asm/io.h>
80#include <asm/byteorder.h>
81#include <linux/random.h>
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -070082#include <linux/usb.h>
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -070083
84#include "wlan_compat.h"
85
86/*================================================================*/
87/* Project Includes */
88
89#include "p80211types.h"
90#include "p80211hdr.h"
91#include "p80211mgmt.h"
92#include "p80211conv.h"
93#include "p80211msg.h"
94#include "p80211netdev.h"
95#include "p80211metadef.h"
96#include "p80211metastruct.h"
97#include "hfa384x.h"
98#include "prism2mgmt.h"
99
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700100/* Converts 802.11 format rate specifications to prism2 */
101#define p80211rate_to_p2bit(n) ((((n)&~BIT7) == 2) ? BIT0 : \
102 (((n)&~BIT7) == 4) ? BIT1 : \
103 (((n)&~BIT7) == 11) ? BIT2 : \
104 (((n)&~BIT7) == 22) ? BIT3 : 0)
105
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700106/*----------------------------------------------------------------
107* prism2mgmt_scan
108*
109* Initiate a scan for BSSs.
110*
111* This function corresponds to MLME-scan.request and part of
112* MLME-scan.confirm. As far as I can tell in the standard, there
113* are no restrictions on when a scan.request may be issued. We have
114* to handle in whatever state the driver/MAC happen to be.
115*
116* Arguments:
117* wlandev wlan device structure
118* msgp ptr to msg buffer
119*
120* Returns:
121* 0 success and done
122* <0 success, but we're waiting for something to finish.
123* >0 an error occurred while handling the message.
124* Side effects:
125*
126* Call context:
127* process thread (usually)
128* interrupt
129----------------------------------------------------------------*/
130int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp)
131{
132 int result = 0;
133 hfa384x_t *hw = wlandev->priv;
134 p80211msg_dot11req_scan_t *msg = msgp;
135 UINT16 roamingmode, word;
136 int i, timeout;
137 int istmpenable = 0;
138
139 hfa384x_HostScanRequest_data_t scanreq;
140
141 DBFENTER;
142
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700143 /* gatekeeper check */
144 if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
145 hw->ident_sta_fw.minor,
146 hw->ident_sta_fw.variant) <
147 HFA384x_FIRMWARE_VERSION(1,3,2)) {
148 WLAN_LOG_ERROR("HostScan not supported with current firmware (<1.3.2).\n");
149 result = 1;
150 msg->resultcode.data = P80211ENUM_resultcode_not_supported;
151 goto exit;
152 }
153
154 memset(&scanreq, 0, sizeof(scanreq));
155
156 /* save current roaming mode */
157 result = hfa384x_drvr_getconfig16(hw,
158 HFA384x_RID_CNFROAMINGMODE, &roamingmode);
159 if ( result ) {
160 WLAN_LOG_ERROR("getconfig(ROAMMODE) failed. result=%d\n",
161 result);
162 msg->resultcode.data =
163 P80211ENUM_resultcode_implementation_failure;
164 goto exit;
165 }
166
167 /* drop into mode 3 for the scan */
168 result = hfa384x_drvr_setconfig16(hw,
169 HFA384x_RID_CNFROAMINGMODE,
170 HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM);
171 if ( result ) {
172 WLAN_LOG_ERROR("setconfig(ROAMINGMODE) failed. result=%d\n",
173 result);
174 msg->resultcode.data =
175 P80211ENUM_resultcode_implementation_failure;
176 goto exit;
177 }
178
179 /* active or passive? */
180 if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
181 hw->ident_sta_fw.minor,
182 hw->ident_sta_fw.variant) >
183 HFA384x_FIRMWARE_VERSION(1,5,0)) {
184 if (msg->scantype.data != P80211ENUM_scantype_active) {
185 word = host2hfa384x_16(msg->maxchanneltime.data);
186 } else {
187 word = 0;
188 }
189 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPASSIVESCANCTRL, word);
190 if ( result ) {
191 WLAN_LOG_WARNING("Passive scan not supported with "
192 "current firmware. (<1.5.1)\n");
193 }
194 }
195
196 /* set up the txrate to be 2MBPS. Should be fastest basicrate... */
197 word = HFA384x_RATEBIT_2;
198 scanreq.txRate = host2hfa384x_16(word);
199
200 /* set up the channel list */
201 word = 0;
202 for (i = 0; i < msg->channellist.data.len; i++) {
203 UINT8 channel = msg->channellist.data.data[i];
204 if (channel > 14) continue;
205 /* channel 1 is BIT0 ... channel 14 is BIT13 */
206 word |= (1 << (channel-1));
207 }
208 scanreq.channelList = host2hfa384x_16(word);
209
210 /* set up the ssid, if present. */
211 scanreq.ssid.len = host2hfa384x_16(msg->ssid.data.len);
212 memcpy(scanreq.ssid.data, msg->ssid.data.data, msg->ssid.data.len);
213
214 /* Enable the MAC port if it's not already enabled */
215 result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_PORTSTATUS, &word);
216 if ( result ) {
217 WLAN_LOG_ERROR("getconfig(PORTSTATUS) failed. "
218 "result=%d\n", result);
219 msg->resultcode.data =
220 P80211ENUM_resultcode_implementation_failure;
221 goto exit;
222 }
223 if (word == HFA384x_PORTSTATUS_DISABLED) {
224 UINT16 wordbuf[17];
225
226 result = hfa384x_drvr_setconfig16(hw,
227 HFA384x_RID_CNFROAMINGMODE,
228 HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM);
229 if ( result ) {
230 WLAN_LOG_ERROR("setconfig(ROAMINGMODE) failed. result=%d\n", result);
231 msg->resultcode.data =
232 P80211ENUM_resultcode_implementation_failure;
233 goto exit;
234 }
235 /* Construct a bogus SSID and assign it to OwnSSID and
236 * DesiredSSID
237 */
238 wordbuf[0] = host2hfa384x_16(WLAN_SSID_MAXLEN);
239 get_random_bytes(&wordbuf[1], WLAN_SSID_MAXLEN);
240 result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFOWNSSID,
241 wordbuf, HFA384x_RID_CNFOWNSSID_LEN);
242 if ( result ) {
243 WLAN_LOG_ERROR("Failed to set OwnSSID.\n");
244 msg->resultcode.data =
245 P80211ENUM_resultcode_implementation_failure;
246 goto exit;
247 }
248 result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFDESIREDSSID,
249 wordbuf, HFA384x_RID_CNFDESIREDSSID_LEN);
250 if ( result ) {
251 WLAN_LOG_ERROR("Failed to set DesiredSSID.\n");
252 msg->resultcode.data =
253 P80211ENUM_resultcode_implementation_failure;
254 goto exit;
255 }
256 /* bsstype */
257 result = hfa384x_drvr_setconfig16(hw,
258 HFA384x_RID_CNFPORTTYPE,
259 HFA384x_PORTTYPE_IBSS);
260 if ( result ) {
261 WLAN_LOG_ERROR("Failed to set CNFPORTTYPE.\n");
262 msg->resultcode.data =
263 P80211ENUM_resultcode_implementation_failure;
264 goto exit;
265 }
266 /* ibss options */
267 result = hfa384x_drvr_setconfig16(hw,
268 HFA384x_RID_CREATEIBSS,
269 HFA384x_CREATEIBSS_JOINCREATEIBSS);
270 if ( result ) {
271 WLAN_LOG_ERROR("Failed to set CREATEIBSS.\n");
272 msg->resultcode.data =
273 P80211ENUM_resultcode_implementation_failure;
274 goto exit;
275 }
276 result = hfa384x_drvr_enable(hw, 0);
277 if ( result ) {
278 WLAN_LOG_ERROR("drvr_enable(0) failed. "
279 "result=%d\n", result);
280 msg->resultcode.data =
281 P80211ENUM_resultcode_implementation_failure;
282 goto exit;
283 }
284 istmpenable = 1;
285 }
286
287 /* Figure out our timeout first Kus, then HZ */
288 timeout = msg->channellist.data.len * msg->maxchanneltime.data;
289 timeout = (timeout * HZ)/1000;
290
291 /* Issue the scan request */
292 hw->scanflag = 0;
293
294 WLAN_HEX_DUMP(5,"hscanreq", &scanreq, sizeof(scanreq));
295
296 result = hfa384x_drvr_setconfig( hw,
297 HFA384x_RID_HOSTSCAN, &scanreq,
298 sizeof(hfa384x_HostScanRequest_data_t));
299 if ( result ) {
300 WLAN_LOG_ERROR("setconfig(SCANREQUEST) failed. result=%d\n",
301 result);
302 msg->resultcode.data =
303 P80211ENUM_resultcode_implementation_failure;
304 goto exit;
305 }
306
307 /* sleep until info frame arrives */
308 wait_event_interruptible_timeout(hw->cmdq, hw->scanflag, timeout);
309
310 msg->numbss.status = P80211ENUM_msgitem_status_data_ok;
311 if (hw->scanflag == -1)
312 hw->scanflag = 0;
313
314 msg->numbss.data = hw->scanflag;
315
316 hw->scanflag = 0;
317
318 /* Disable port if we temporarily enabled it. */
319 if (istmpenable) {
320 result = hfa384x_drvr_disable(hw, 0);
321 if ( result ) {
322 WLAN_LOG_ERROR("drvr_disable(0) failed. "
323 "result=%d\n", result);
324 msg->resultcode.data =
325 P80211ENUM_resultcode_implementation_failure;
326 goto exit;
327 }
328 }
329
330 /* restore original roaming mode */
331 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFROAMINGMODE,
332 roamingmode);
333 if ( result ) {
334 WLAN_LOG_ERROR("setconfig(ROAMMODE) failed. result=%d\n",
335 result);
336 msg->resultcode.data =
337 P80211ENUM_resultcode_implementation_failure;
338 goto exit;
339 }
340
341 result = 0;
342 msg->resultcode.data = P80211ENUM_resultcode_success;
343
344 exit:
345 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
346
347 DBFEXIT;
348 return result;
349}
350
351
352/*----------------------------------------------------------------
353* prism2mgmt_scan_results
354*
355* Retrieve the BSS description for one of the BSSs identified in
356* a scan.
357*
358* Arguments:
359* wlandev wlan device structure
360* msgp ptr to msg buffer
361*
362* Returns:
363* 0 success and done
364* <0 success, but we're waiting for something to finish.
365* >0 an error occurred while handling the message.
366* Side effects:
367*
368* Call context:
369* process thread (usually)
370* interrupt
371----------------------------------------------------------------*/
372int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp)
373{
374 int result = 0;
375 p80211msg_dot11req_scan_results_t *req;
376 hfa384x_t *hw = wlandev->priv;
377 hfa384x_HScanResultSub_t *item = NULL;
378
379 int count;
380
381 DBFENTER;
382
383 req = (p80211msg_dot11req_scan_results_t *) msgp;
384
385 req->resultcode.status = P80211ENUM_msgitem_status_data_ok;
386
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700387 if (! hw->scanresults) {
388 WLAN_LOG_ERROR("dot11req_scan_results can only be used after a successful dot11req_scan.\n");
389 result = 2;
390 req->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
391 goto exit;
392 }
393
394 count = (hw->scanresults->framelen - 3) / 32;
395 if (count > 32) count = 32;
396
397 if (req->bssindex.data >= count) {
398 WLAN_LOG_DEBUG(0, "requested index (%d) out of range (%d)\n",
399 req->bssindex.data, count);
400 result = 2;
401 req->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
402 goto exit;
403 }
404
405 item = &(hw->scanresults->info.hscanresult.result[req->bssindex.data]);
406 /* signal and noise */
407 req->signal.status = P80211ENUM_msgitem_status_data_ok;
408 req->noise.status = P80211ENUM_msgitem_status_data_ok;
409 req->signal.data = hfa384x2host_16(item->sl);
410 req->noise.data = hfa384x2host_16(item->anl);
411
412 /* BSSID */
413 req->bssid.status = P80211ENUM_msgitem_status_data_ok;
414 req->bssid.data.len = WLAN_BSSID_LEN;
415 memcpy(req->bssid.data.data, item->bssid, WLAN_BSSID_LEN);
416
417 /* SSID */
418 req->ssid.status = P80211ENUM_msgitem_status_data_ok;
419 req->ssid.data.len = hfa384x2host_16(item->ssid.len);
420 memcpy(req->ssid.data.data, item->ssid.data, req->ssid.data.len);
421
422 /* supported rates */
423 for (count = 0; count < 10 ; count++)
424 if (item->supprates[count] == 0)
425 break;
426
427#define REQBASICRATE(N) \
428 if ((count >= N) && DOT11_RATE5_ISBASIC_GET(item->supprates[(N)-1])) { \
429 req->basicrate ## N .data = item->supprates[(N)-1]; \
430 req->basicrate ## N .status = P80211ENUM_msgitem_status_data_ok; \
431 }
432
433 REQBASICRATE(1);
434 REQBASICRATE(2);
435 REQBASICRATE(3);
436 REQBASICRATE(4);
437 REQBASICRATE(5);
438 REQBASICRATE(6);
439 REQBASICRATE(7);
440 REQBASICRATE(8);
441
442#define REQSUPPRATE(N) \
443 if (count >= N) { \
444 req->supprate ## N .data = item->supprates[(N)-1]; \
445 req->supprate ## N .status = P80211ENUM_msgitem_status_data_ok; \
446 }
447
448 REQSUPPRATE(1);
449 REQSUPPRATE(2);
450 REQSUPPRATE(3);
451 REQSUPPRATE(4);
452 REQSUPPRATE(5);
453 REQSUPPRATE(6);
454 REQSUPPRATE(7);
455 REQSUPPRATE(8);
456
457 /* beacon period */
458 req->beaconperiod.status = P80211ENUM_msgitem_status_data_ok;
459 req->beaconperiod.data = hfa384x2host_16(item->bcnint);
460
461 /* timestamps */
462 req->timestamp.status = P80211ENUM_msgitem_status_data_ok;
463 req->timestamp.data = jiffies;
464 req->localtime.status = P80211ENUM_msgitem_status_data_ok;
465 req->localtime.data = jiffies;
466
467 /* atim window */
468 req->ibssatimwindow.status = P80211ENUM_msgitem_status_data_ok;
469 req->ibssatimwindow.data = hfa384x2host_16(item->atim);
470
471 /* Channel */
472 req->dschannel.status = P80211ENUM_msgitem_status_data_ok;
473 req->dschannel.data = hfa384x2host_16(item->chid);
474
475 /* capinfo bits */
476 count = hfa384x2host_16(item->capinfo);
477
478 /* privacy flag */
479 req->privacy.status = P80211ENUM_msgitem_status_data_ok;
480 req->privacy.data = WLAN_GET_MGMT_CAP_INFO_PRIVACY(count);
481
482 /* cfpollable */
483 req->cfpollable.status = P80211ENUM_msgitem_status_data_ok;
484 req->cfpollable.data = WLAN_GET_MGMT_CAP_INFO_CFPOLLABLE(count);
485
486 /* cfpollreq */
487 req->cfpollreq.status = P80211ENUM_msgitem_status_data_ok;
488 req->cfpollreq.data = WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(count);
489
490 /* bsstype */
491 req->bsstype.status = P80211ENUM_msgitem_status_data_ok;
492 req->bsstype.data = (WLAN_GET_MGMT_CAP_INFO_ESS(count)) ?
493 P80211ENUM_bsstype_infrastructure :
494 P80211ENUM_bsstype_independent;
495
496 // item->proberesp_rate
497/*
498 req->fhdwelltime
499 req->fhhopset
500 req->fhhoppattern
501 req->fhhopindex
502 req->cfpdurremaining
503*/
504
505 result = 0;
506 req->resultcode.data = P80211ENUM_resultcode_success;
507
508 exit:
509 DBFEXIT;
510 return result;
511}
512
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700513/*----------------------------------------------------------------
514* prism2mgmt_p2_join
515*
516* Join a specific BSS
517*
518* Arguments:
519* wlandev wlan device structure
520* msgp ptr to msg buffer
521*
522* Returns:
523* 0 success and done
524* <0 success, but we're waiting for something to finish.
525* >0 an error occurred while handling the message.
526* Side effects:
527*
528* Call context:
529* process thread (usually)
530* interrupt
531----------------------------------------------------------------*/
532int prism2mgmt_p2_join(wlandevice_t *wlandev, void *msgp)
533{
534 int result = 0;
535 hfa384x_t *hw = wlandev->priv;
536 p80211msg_p2req_join_t *msg = msgp;
537 UINT16 reg;
538 p80211pstrd_t *pstr;
539 UINT8 bytebuf[256];
540 hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t*)bytebuf;
541 hfa384x_JoinRequest_data_t joinreq;
542 DBFENTER;
543
Solomon Peachy5db8dcc2008-10-27 11:14:02 -0400544 wlandev->macmode = WLAN_MACMODE_NONE;
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700545
Solomon Peachy5db8dcc2008-10-27 11:14:02 -0400546 /* Set the PortType */
547 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
548 msg->resultcode.data = P80211ENUM_resultcode_success;
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700549
Solomon Peachy5db8dcc2008-10-27 11:14:02 -0400550 /* ess port */
551 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, 1);
552 if ( result ) {
553 WLAN_LOG_ERROR("Failed to set Port Type\n");
554 goto failed;
555 }
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700556
Solomon Peachy5db8dcc2008-10-27 11:14:02 -0400557 /* Set the auth type */
558 if ( msg->authtype.data == P80211ENUM_authalg_sharedkey ) {
559 reg = HFA384x_CNFAUTHENTICATION_SHAREDKEY;
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700560 } else {
Solomon Peachy5db8dcc2008-10-27 11:14:02 -0400561 reg = HFA384x_CNFAUTHENTICATION_OPENSYSTEM;
562 }
563 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAUTHENTICATION, reg);
564 if ( result ) {
565 WLAN_LOG_ERROR("Failed to set Authentication\n");
566 goto failed;
567 }
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700568
Solomon Peachy5db8dcc2008-10-27 11:14:02 -0400569 /* Turn off all roaming */
570 hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFROAMINGMODE, 3);
571 if ( result ) {
572 WLAN_LOG_ERROR("Failed to Turn off Roaming\n");
573 goto failed;
574 }
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700575
Solomon Peachy5db8dcc2008-10-27 11:14:02 -0400576 /* Basic rates */
577 reg = 0;
578 if ( msg->basicrate1.status == P80211ENUM_msgitem_status_data_ok ) {
579 reg = p80211rate_to_p2bit(msg->basicrate1.data);
580 }
581 if ( msg->basicrate2.status == P80211ENUM_msgitem_status_data_ok ) {
582 reg |= p80211rate_to_p2bit(msg->basicrate2.data);
583 }
584 if ( msg->basicrate3.status == P80211ENUM_msgitem_status_data_ok ) {
585 reg |= p80211rate_to_p2bit(msg->basicrate3.data);
586 }
587 if ( msg->basicrate4.status == P80211ENUM_msgitem_status_data_ok ) {
588 reg |= p80211rate_to_p2bit(msg->basicrate4.data);
589 }
590 if ( msg->basicrate5.status == P80211ENUM_msgitem_status_data_ok ) {
591 reg |= p80211rate_to_p2bit(msg->basicrate5.data);
592 }
593 if ( msg->basicrate6.status == P80211ENUM_msgitem_status_data_ok ) {
594 reg |= p80211rate_to_p2bit(msg->basicrate6.data);
595 }
596 if ( msg->basicrate7.status == P80211ENUM_msgitem_status_data_ok ) {
597 reg |= p80211rate_to_p2bit(msg->basicrate7.data);
598 }
599 if ( msg->basicrate8.status == P80211ENUM_msgitem_status_data_ok ) {
600 reg |= p80211rate_to_p2bit(msg->basicrate8.data);
601 }
602 if( reg == 0)
603 reg = 0x03;
604 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFBASICRATES, reg);
605 if ( result ) {
606 WLAN_LOG_ERROR("Failed to set basicrates=%d.\n", reg);
607 goto failed;
608 }
609
610 /* Operational rates (supprates and txratecontrol) */
611 reg = 0;
612 if ( msg->operationalrate1.status == P80211ENUM_msgitem_status_data_ok ) {
613 reg = p80211rate_to_p2bit(msg->operationalrate1.data);
614 }
615 if ( msg->operationalrate2.status == P80211ENUM_msgitem_status_data_ok ) {
616 reg |= p80211rate_to_p2bit(msg->operationalrate2.data);
617 }
618 if ( msg->operationalrate3.status == P80211ENUM_msgitem_status_data_ok ) {
619 reg |= p80211rate_to_p2bit(msg->operationalrate3.data);
620 }
621 if ( msg->operationalrate4.status == P80211ENUM_msgitem_status_data_ok ) {
622 reg |= p80211rate_to_p2bit(msg->operationalrate4.data);
623 }
624 if ( msg->operationalrate5.status == P80211ENUM_msgitem_status_data_ok ) {
625 reg |= p80211rate_to_p2bit(msg->operationalrate5.data);
626 }
627 if ( msg->operationalrate6.status == P80211ENUM_msgitem_status_data_ok ) {
628 reg |= p80211rate_to_p2bit(msg->operationalrate6.data);
629 }
630 if ( msg->operationalrate7.status == P80211ENUM_msgitem_status_data_ok ) {
631 reg |= p80211rate_to_p2bit(msg->operationalrate7.data);
632 }
633 if ( msg->operationalrate8.status == P80211ENUM_msgitem_status_data_ok ) {
634 reg |= p80211rate_to_p2bit(msg->operationalrate8.data);
635 }
636 if( reg == 0)
637 reg = 0x0f;
638 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFSUPPRATES, reg);
639 if ( result ) {
640 WLAN_LOG_ERROR("Failed to set supprates=%d.\n", reg);
641 goto failed;
642 }
643
644 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, reg);
645 if ( result ) {
646 WLAN_LOG_ERROR("Failed to set txrates=%d.\n", reg);
647 goto failed;
648 }
649
650 /* Set the ssid */
651 memset(bytebuf, 0, 256);
652 pstr = (p80211pstrd_t*)&(msg->ssid.data);
653 prism2mgmt_pstr2bytestr(p2bytestr, pstr);
654 result = hfa384x_drvr_setconfig(
655 hw, HFA384x_RID_CNFDESIREDSSID,
656 bytebuf, HFA384x_RID_CNFDESIREDSSID_LEN);
657 if ( result ) {
658 WLAN_LOG_ERROR("Failed to set SSID\n");
659 goto failed;
660 }
661
662 /* Enable the Port */
663 result = hfa384x_cmd_enable(hw, 0);
664 if ( result ) {
665 WLAN_LOG_ERROR("Enable macport failed, result=%d.\n", result);
666 goto failed;
667 }
668
669 /* Fill in the join request */
670 joinreq.channel = msg->channel.data;
671 memcpy( joinreq.bssid, ((unsigned char *) &msg->bssid.data) + 1, WLAN_BSSID_LEN);
672 hw->joinreq = joinreq;
673 hw->join_ap = 1;
674
675 /* Send the join request */
676 result = hfa384x_drvr_setconfig( hw,
677 HFA384x_RID_JOINREQUEST,
678 &joinreq, HFA384x_RID_JOINREQUEST_LEN);
679 if(result != 0) {
680 WLAN_LOG_ERROR("Join request failed, result=%d.\n", result);
681 goto failed;
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700682 }
683
684 goto done;
685failed:
686 WLAN_LOG_DEBUG(1, "Failed to set a config option, result=%d\n", result);
687 msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
688
689done:
690 result = 0;
691
692 DBFEXIT;
693 return result;
694}
695
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700696/*----------------------------------------------------------------
697* prism2mgmt_associate
698*
699* Associate with an ESS.
700*
701* Arguments:
702* wlandev wlan device structure
703* msgp ptr to msg buffer
704*
705* Returns:
706* 0 success and done
707* <0 success, but we're waiting for something to finish.
708* >0 an error occurred while handling the message.
709* Side effects:
710*
711* Call context:
712* process thread (usually)
713* interrupt
714----------------------------------------------------------------*/
715int prism2mgmt_associate(wlandevice_t *wlandev, void *msgp)
716{
717 hfa384x_t *hw = wlandev->priv;
718 int result = 0;
719 p80211msg_dot11req_associate_t *msg = msgp;
720 DBFENTER;
721
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700722#if 0
Solomon Peachy5db8dcc2008-10-27 11:14:02 -0400723 /* Set the TxRates */
724 reg = 0x000f;
725 hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, reg);
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700726#endif
727
Solomon Peachy5db8dcc2008-10-27 11:14:02 -0400728 /* Set the PortType */
729 /* ess port */
730 hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, 1);
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700731
Solomon Peachy5db8dcc2008-10-27 11:14:02 -0400732 /* Enable the Port */
733 hfa384x_drvr_enable(hw, 0);
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700734
Solomon Peachy5db8dcc2008-10-27 11:14:02 -0400735 /* Set the resultcode */
736 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
737 msg->resultcode.data = P80211ENUM_resultcode_success;
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700738
739 DBFEXIT;
740 return result;
741}
742
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700743/*----------------------------------------------------------------
744* prism2mgmt_reset
745*
746* Reset the MAC and MSD. The p80211 layer has it's own handling
747* that should be done before and after this function.
748* Procedure:
749* - disable system interrupts ??
750* - disable MAC interrupts
751* - restore system interrupts
752* - issue the MAC initialize command
753* - clear any MSD level state (including timers, queued events,
754* etc.). Note that if we're removing timer'd/queue events, we may
755* need to have remained in the system interrupt disabled state.
756* We should be left in the same state that we're in following
757* driver initialization.
758*
759* Arguments:
760* wlandev wlan device structure
761* msgp ptr to msg buffer, MAY BE NULL! for a driver local
762* call.
763*
764* Returns:
765* 0 success and done
766* <0 success, but we're waiting for something to finish.
767* >0 an error occurred while handling the message.
768* Side effects:
769*
770* Call context:
771* process thread, commonly wlanctl, but might be rmmod/pci_close.
772----------------------------------------------------------------*/
773int prism2mgmt_reset(wlandevice_t *wlandev, void *msgp)
774{
775 int result = 0;
776 hfa384x_t *hw = wlandev->priv;
777 p80211msg_dot11req_reset_t *msg = msgp;
778 DBFENTER;
779
780 /*
781 * This is supported on both AP and STA and it's not allowed
782 * to fail.
783 */
784 if ( msgp ) {
785 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
786 msg->resultcode.data = P80211ENUM_resultcode_success;
787 WLAN_LOG_INFO("dot11req_reset: the macaddress and "
788 "setdefaultmib arguments are currently unsupported.\n");
789 }
790
791 /*
792 * If we got this far, the MSD must be in the MSDRUNNING state
793 * therefore, we must stop and then restart the hw/MAC combo.
794 */
795 hfa384x_drvr_stop(hw);
796 result = hfa384x_drvr_start(hw);
797 if (result != 0) {
798 WLAN_LOG_ERROR("dot11req_reset: Initialize command failed,"
799 " bad things will happen from here.\n");
800 return 0;
801 }
802
803 DBFEXIT;
804 return 0;
805}
806
807
808/*----------------------------------------------------------------
809* prism2mgmt_start
810*
811* Start a BSS. Any station can do this for IBSS, only AP for ESS.
812*
813* Arguments:
814* wlandev wlan device structure
815* msgp ptr to msg buffer
816*
817* Returns:
818* 0 success and done
819* <0 success, but we're waiting for something to finish.
820* >0 an error occurred while handling the message.
821* Side effects:
822*
823* Call context:
824* process thread (usually)
825* interrupt
826----------------------------------------------------------------*/
827int prism2mgmt_start(wlandevice_t *wlandev, void *msgp)
828{
829 int result = 0;
830 hfa384x_t *hw = wlandev->priv;
831 p80211msg_dot11req_start_t *msg = msgp;
832
833 p80211pstrd_t *pstr;
834 UINT8 bytebuf[80];
835 hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t*)bytebuf;
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700836 UINT16 word;
837 DBFENTER;
838
839 wlandev->macmode = WLAN_MACMODE_NONE;
840
841 /* Set the SSID */
842 memcpy(&wlandev->ssid, &msg->ssid.data, sizeof(msg->ssid.data));
843
Solomon Peachy5db8dcc2008-10-27 11:14:02 -0400844 /*** ADHOC IBSS ***/
845 /* see if current f/w is less than 8c3 */
846 if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
847 hw->ident_sta_fw.minor,
848 hw->ident_sta_fw.variant) <
849 HFA384x_FIRMWARE_VERSION(0,8,3)) {
850 /* Ad-Hoc not quite supported on Prism2 */
851 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
852 msg->resultcode.data = P80211ENUM_resultcode_not_supported;
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700853 goto done;
854 }
855
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700856 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
857
Solomon Peachy5db8dcc2008-10-27 11:14:02 -0400858 /*** STATION ***/
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700859 /* Set the REQUIRED config items */
860 /* SSID */
861 pstr = (p80211pstrd_t*)&(msg->ssid.data);
862 prism2mgmt_pstr2bytestr(p2bytestr, pstr);
863 result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFOWNSSID,
Solomon Peachy5db8dcc2008-10-27 11:14:02 -0400864 bytebuf, HFA384x_RID_CNFOWNSSID_LEN);
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700865 if ( result ) {
Solomon Peachy5db8dcc2008-10-27 11:14:02 -0400866 WLAN_LOG_ERROR("Failed to set CnfOwnSSID\n");
867 goto failed;
868 }
869 result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFDESIREDSSID,
870 bytebuf, HFA384x_RID_CNFDESIREDSSID_LEN);
871 if ( result ) {
872 WLAN_LOG_ERROR("Failed to set CnfDesiredSSID\n");
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700873 goto failed;
874 }
875
876 /* bsstype - we use the default in the ap firmware */
Solomon Peachy5db8dcc2008-10-27 11:14:02 -0400877 /* IBSS port */
878 hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, 0);
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700879
880 /* beacon period */
881 word = msg->beaconperiod.data;
882 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAPBCNINT, word);
883 if ( result ) {
884 WLAN_LOG_ERROR("Failed to set beacon period=%d.\n", word);
885 goto failed;
886 }
887
888 /* dschannel */
889 word = msg->dschannel.data;
890 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFOWNCHANNEL, word);
891 if ( result ) {
892 WLAN_LOG_ERROR("Failed to set channel=%d.\n", word);
893 goto failed;
894 }
895 /* Basic rates */
896 word = p80211rate_to_p2bit(msg->basicrate1.data);
897 if ( msg->basicrate2.status == P80211ENUM_msgitem_status_data_ok ) {
898 word |= p80211rate_to_p2bit(msg->basicrate2.data);
899 }
900 if ( msg->basicrate3.status == P80211ENUM_msgitem_status_data_ok ) {
901 word |= p80211rate_to_p2bit(msg->basicrate3.data);
902 }
903 if ( msg->basicrate4.status == P80211ENUM_msgitem_status_data_ok ) {
904 word |= p80211rate_to_p2bit(msg->basicrate4.data);
905 }
906 if ( msg->basicrate5.status == P80211ENUM_msgitem_status_data_ok ) {
907 word |= p80211rate_to_p2bit(msg->basicrate5.data);
908 }
909 if ( msg->basicrate6.status == P80211ENUM_msgitem_status_data_ok ) {
910 word |= p80211rate_to_p2bit(msg->basicrate6.data);
911 }
912 if ( msg->basicrate7.status == P80211ENUM_msgitem_status_data_ok ) {
913 word |= p80211rate_to_p2bit(msg->basicrate7.data);
914 }
915 if ( msg->basicrate8.status == P80211ENUM_msgitem_status_data_ok ) {
916 word |= p80211rate_to_p2bit(msg->basicrate8.data);
917 }
918 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFBASICRATES, word);
919 if ( result ) {
920 WLAN_LOG_ERROR("Failed to set basicrates=%d.\n", word);
921 goto failed;
922 }
923
924 /* Operational rates (supprates and txratecontrol) */
925 word = p80211rate_to_p2bit(msg->operationalrate1.data);
926 if ( msg->operationalrate2.status == P80211ENUM_msgitem_status_data_ok ) {
927 word |= p80211rate_to_p2bit(msg->operationalrate2.data);
928 }
929 if ( msg->operationalrate3.status == P80211ENUM_msgitem_status_data_ok ) {
930 word |= p80211rate_to_p2bit(msg->operationalrate3.data);
931 }
932 if ( msg->operationalrate4.status == P80211ENUM_msgitem_status_data_ok ) {
933 word |= p80211rate_to_p2bit(msg->operationalrate4.data);
934 }
935 if ( msg->operationalrate5.status == P80211ENUM_msgitem_status_data_ok ) {
936 word |= p80211rate_to_p2bit(msg->operationalrate5.data);
937 }
938 if ( msg->operationalrate6.status == P80211ENUM_msgitem_status_data_ok ) {
939 word |= p80211rate_to_p2bit(msg->operationalrate6.data);
940 }
941 if ( msg->operationalrate7.status == P80211ENUM_msgitem_status_data_ok ) {
942 word |= p80211rate_to_p2bit(msg->operationalrate7.data);
943 }
944 if ( msg->operationalrate8.status == P80211ENUM_msgitem_status_data_ok ) {
945 word |= p80211rate_to_p2bit(msg->operationalrate8.data);
946 }
947 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFSUPPRATES, word);
948 if ( result ) {
949 WLAN_LOG_ERROR("Failed to set supprates=%d.\n", word);
950 goto failed;
951 }
Solomon Peachy5db8dcc2008-10-27 11:14:02 -0400952
953 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, word);
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700954 if ( result ) {
955 WLAN_LOG_ERROR("Failed to set txrates=%d.\n", word);
956 goto failed;
957 }
958
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700959 /* Set the macmode so the frame setup code knows what to do */
Solomon Peachy5db8dcc2008-10-27 11:14:02 -0400960 if ( msg->bsstype.data == P80211ENUM_bsstype_independent ) {
961 wlandev->macmode = WLAN_MACMODE_IBSS_STA;
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700962 /* lets extend the data length a bit */
963 hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN, 2304);
964 }
965
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700966 /* Enable the Port */
967 result = hfa384x_drvr_enable(hw, 0);
968 if ( result ) {
969 WLAN_LOG_ERROR("Enable macport failed, result=%d.\n", result);
970 goto failed;
971 }
972
973 msg->resultcode.data = P80211ENUM_resultcode_success;
974
975 goto done;
976failed:
977 WLAN_LOG_DEBUG(1, "Failed to set a config option, result=%d\n", result);
978 msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
979
980done:
981 result = 0;
982
983 DBFEXIT;
984 return result;
985}
986
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -0700987/*----------------------------------------------------------------
988* prism2mgmt_readpda
989*
990* Collect the PDA data and put it in the message.
991*
992* Arguments:
993* wlandev wlan device structure
994* msgp ptr to msg buffer
995*
996* Returns:
997* 0 success and done
998* <0 success, but we're waiting for something to finish.
999* >0 an error occurred while handling the message.
1000* Side effects:
1001*
1002* Call context:
1003* process thread (usually)
1004----------------------------------------------------------------*/
1005int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp)
1006{
1007 hfa384x_t *hw = wlandev->priv;
1008 p80211msg_p2req_readpda_t *msg = msgp;
1009 int result;
1010 DBFENTER;
1011
1012 /* We only support collecting the PDA when in the FWLOAD
1013 * state.
1014 */
1015 if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
1016 WLAN_LOG_ERROR(
1017 "PDA may only be read "
1018 "in the fwload state.\n");
1019 msg->resultcode.data =
1020 P80211ENUM_resultcode_implementation_failure;
1021 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
1022 } else {
1023 /* Call drvr_readpda(), it handles the auxport enable
1024 * and validating the returned PDA.
1025 */
1026 result = hfa384x_drvr_readpda(
1027 hw,
1028 msg->pda.data,
1029 HFA384x_PDA_LEN_MAX);
1030 if (result) {
1031 WLAN_LOG_ERROR(
1032 "hfa384x_drvr_readpda() failed, "
1033 "result=%d\n",
1034 result);
1035
1036 msg->resultcode.data =
1037 P80211ENUM_resultcode_implementation_failure;
1038 msg->resultcode.status =
1039 P80211ENUM_msgitem_status_data_ok;
1040 DBFEXIT;
1041 return 0;
1042 }
1043 msg->pda.status = P80211ENUM_msgitem_status_data_ok;
1044 msg->resultcode.data = P80211ENUM_resultcode_success;
1045 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
1046 }
1047
1048 DBFEXIT;
1049 return 0;
1050}
1051
1052/*----------------------------------------------------------------
1053* prism2mgmt_readcis
1054*
1055* Collect the CIS data and put it in the message.
1056*
1057* Arguments:
1058* wlandev wlan device structure
1059* msgp ptr to msg buffer
1060*
1061* Returns:
1062* 0 success and done
1063* <0 success, but we're waiting for something to finish.
1064* >0 an error occurred while handling the message.
1065* Side effects:
1066*
1067* Call context:
1068* process thread (usually)
1069----------------------------------------------------------------*/
1070int prism2mgmt_readcis(wlandevice_t *wlandev, void *msgp)
1071{
1072 int result;
1073 hfa384x_t *hw = wlandev->priv;
1074 p80211msg_p2req_readcis_t *msg = msgp;
1075
1076 DBFENTER;
1077
1078 memset(msg->cis.data, 0, sizeof(msg->cis.data));
1079
1080 result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CIS,
1081 msg->cis.data, HFA384x_RID_CIS_LEN);
1082 if ( result ) {
1083 WLAN_LOG_INFO("prism2mgmt_readcis: read(cis) failed.\n");
1084 msg->cis.status = P80211ENUM_msgitem_status_no_value;
1085 msg->resultcode.data = P80211ENUM_resultcode_implementation_failure;
1086
1087 }
1088 else {
1089 msg->cis.status = P80211ENUM_msgitem_status_data_ok;
1090 msg->resultcode.data = P80211ENUM_resultcode_success;
1091 }
1092
1093 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
1094
1095 DBFEXIT;
1096 return 0;
1097}
1098
1099/*----------------------------------------------------------------
1100* prism2mgmt_auxport_state
1101*
1102* Enables/Disables the card's auxiliary port. Should be called
1103* before and after a sequence of auxport_read()/auxport_write()
1104* calls.
1105*
1106* Arguments:
1107* wlandev wlan device structure
1108* msgp ptr to msg buffer
1109*
1110* Returns:
1111* 0 success and done
1112* <0 success, but we're waiting for something to finish.
1113* >0 an error occurred while handling the message.
1114* Side effects:
1115*
1116* Call context:
1117* process thread (usually)
1118----------------------------------------------------------------*/
1119int prism2mgmt_auxport_state(wlandevice_t *wlandev, void *msgp)
1120{
1121 p80211msg_p2req_auxport_state_t *msg = msgp;
1122
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -07001123 DBFENTER;
1124
1125 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
1126 msg->resultcode.data = P80211ENUM_resultcode_not_supported;
1127
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -07001128 DBFEXIT;
1129 return 0;
1130}
1131
1132
1133/*----------------------------------------------------------------
1134* prism2mgmt_auxport_read
1135*
1136* Copies data from the card using the auxport. The auxport must
1137* have previously been enabled. Note: this is not the way to
1138* do downloads, see the [ram|flash]dl functions.
1139*
1140* Arguments:
1141* wlandev wlan device structure
1142* msgp ptr to msg buffer
1143*
1144* Returns:
1145* 0 success and done
1146* <0 success, but we're waiting for something to finish.
1147* >0 an error occurred while handling the message.
1148* Side effects:
1149*
1150* Call context:
1151* process thread (usually)
1152----------------------------------------------------------------*/
1153int prism2mgmt_auxport_read(wlandevice_t *wlandev, void *msgp)
1154{
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -07001155 DBFENTER;
1156
1157 WLAN_LOG_ERROR("prism2mgmt_auxport_read: Not supported on USB.\n");
1158
1159 DBFEXIT;
1160 return 0;
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -07001161}
1162
1163
1164/*----------------------------------------------------------------
1165* prism2mgmt_auxport_write
1166*
1167* Copies data to the card using the auxport. The auxport must
1168* have previously been enabled. Note: this is not the way to
1169* do downloads, see the [ram|flash]dl functions.
1170*
1171* Arguments:
1172* wlandev wlan device structure
1173* msgp ptr to msg buffer
1174*
1175* Returns:
1176* 0 success and done
1177* <0 success, but we're waiting for something to finish.
1178* >0 an error occurred while handling the message.
1179* Side effects:
1180*
1181* Call context:
1182* process thread (usually)
1183----------------------------------------------------------------*/
1184int prism2mgmt_auxport_write(wlandevice_t *wlandev, void *msgp)
1185{
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -07001186 DBFENTER;
1187 WLAN_LOG_ERROR("prism2mgmt_auxport_read: Not supported on USB.\n");
1188 DBFEXIT;
1189 return 0;
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -07001190}
1191
1192/*----------------------------------------------------------------
1193* prism2mgmt_low_level
1194*
1195* Puts the card into the desired test mode.
1196*
1197* Arguments:
1198* wlandev wlan device structure
1199* msgp ptr to msg buffer
1200*
1201* Returns:
1202* 0 success and done
1203* <0 success, but we're waiting for something to finish.
1204* >0 an error occurred while handling the message.
1205* Side effects:
1206*
1207* Call context:
1208* process thread (usually)
1209----------------------------------------------------------------*/
1210int prism2mgmt_low_level(wlandevice_t *wlandev, void *msgp)
1211{
1212 hfa384x_t *hw = wlandev->priv;
1213 p80211msg_p2req_low_level_t *msg = msgp;
1214 hfa384x_metacmd_t cmd;
1215 DBFENTER;
1216
1217 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
1218
1219 /* call some routine to execute the test command */
1220 cmd.cmd = (UINT16) msg->command.data;
1221 cmd.parm0 = (UINT16) msg->param0.data;
1222 cmd.parm1 = (UINT16) msg->param1.data;
1223 cmd.parm2 = (UINT16) msg->param2.data;
1224
1225 hfa384x_drvr_low_level(hw,&cmd);
1226
1227 msg->resp0.data = (UINT32) cmd.result.resp0;
1228 msg->resp1.data = (UINT32) cmd.result.resp1;
1229 msg->resp2.data = (UINT32) cmd.result.resp2;
1230
1231 msg->resultcode.data = P80211ENUM_resultcode_success;
1232
1233 DBFEXIT;
1234 return 0;
1235}
1236
1237/*----------------------------------------------------------------
1238* prism2mgmt_test_command
1239*
1240* Puts the card into the desired test mode.
1241*
1242* Arguments:
1243* wlandev wlan device structure
1244* msgp ptr to msg buffer
1245*
1246* Returns:
1247* 0 success and done
1248* <0 success, but we're waiting for something to finish.
1249* >0 an error occurred while handling the message.
1250* Side effects:
1251*
1252* Call context:
1253* process thread (usually)
1254----------------------------------------------------------------*/
1255int prism2mgmt_test_command(wlandevice_t *wlandev, void *msgp)
1256{
1257 hfa384x_t *hw = wlandev->priv;
1258 p80211msg_p2req_test_command_t *msg = msgp;
1259 hfa384x_metacmd_t cmd;
1260
1261 DBFENTER;
1262
1263 cmd.cmd = ((UINT16) msg->testcode.data) << 8 | 0x38;
1264 cmd.parm0 = (UINT16) msg->testparam.data;
1265 cmd.parm1 = 0;
1266 cmd.parm2 = 0;
1267
1268 /* call some routine to execute the test command */
1269
1270 hfa384x_drvr_low_level(hw,&cmd);
1271
1272 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
1273 msg->resultcode.data = P80211ENUM_resultcode_success;
1274
1275 msg->status.status = P80211ENUM_msgitem_status_data_ok;
1276 msg->status.data = cmd.result.status;
1277 msg->resp0.status = P80211ENUM_msgitem_status_data_ok;
1278 msg->resp0.data = cmd.result.resp0;
1279 msg->resp1.status = P80211ENUM_msgitem_status_data_ok;
1280 msg->resp1.data = cmd.result.resp1;
1281 msg->resp2.status = P80211ENUM_msgitem_status_data_ok;
1282 msg->resp2.data = cmd.result.resp2;
1283
1284 DBFEXIT;
1285 return 0;
1286}
1287
1288
1289/*----------------------------------------------------------------
1290* prism2mgmt_mmi_read
1291*
1292* Read from one of the MMI registers.
1293*
1294* Arguments:
1295* wlandev wlan device structure
1296* msgp ptr to msg buffer
1297*
1298* Returns:
1299* 0 success and done
1300* <0 success, but we're waiting for something to finish.
1301* >0 an error occurred while handling the message.
1302* Side effects:
1303*
1304* Call context:
1305* process thread (usually)
1306----------------------------------------------------------------*/
1307int prism2mgmt_mmi_read(wlandevice_t *wlandev, void *msgp)
1308{
1309 hfa384x_t *hw = wlandev->priv;
1310 p80211msg_p2req_mmi_read_t *msg = msgp;
1311 UINT32 resp = 0;
1312
1313 DBFENTER;
1314
1315 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
1316
1317 /* call some routine to execute the test command */
1318
1319 hfa384x_drvr_mmi_read(hw, msg->addr.data, &resp);
1320
1321 /* I'm not sure if this is "architecturally" correct, but it
1322 is expedient. */
1323
1324 msg->value.status = P80211ENUM_msgitem_status_data_ok;
1325 msg->value.data = resp;
1326 msg->resultcode.data = P80211ENUM_resultcode_success;
1327
1328 DBFEXIT;
1329 return 0;
1330}
1331
1332/*----------------------------------------------------------------
1333* prism2mgmt_mmi_write
1334*
1335* Write a data value to one of the MMI registers.
1336*
1337* Arguments:
1338* wlandev wlan device structure
1339* msgp ptr to msg buffer
1340*
1341* Returns:
1342* 0 success and done
1343* <0 success, but we're waiting for something to finish.
1344* >0 an error occurred while handling the message.
1345* Side effects:
1346*
1347* Call context:
1348* process thread (usually)
1349----------------------------------------------------------------*/
1350int prism2mgmt_mmi_write(wlandevice_t *wlandev, void *msgp)
1351{
1352 hfa384x_t *hw = wlandev->priv;
1353 p80211msg_p2req_mmi_write_t *msg = msgp;
1354 DBFENTER;
1355
1356 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
1357
1358 /* call some routine to execute the test command */
1359
1360 hfa384x_drvr_mmi_write(hw, msg->addr.data, msg->data.data);
1361
1362 msg->resultcode.data = P80211ENUM_resultcode_success;
1363
1364 DBFEXIT;
1365 return 0;
1366}
1367
1368/*----------------------------------------------------------------
1369* prism2mgmt_ramdl_state
1370*
1371* Establishes the beginning/end of a card RAM download session.
1372*
1373* It is expected that the ramdl_write() function will be called
1374* one or more times between the 'enable' and 'disable' calls to
1375* this function.
1376*
1377* Note: This function should not be called when a mac comm port
1378* is active.
1379*
1380* Arguments:
1381* wlandev wlan device structure
1382* msgp ptr to msg buffer
1383*
1384* Returns:
1385* 0 success and done
1386* <0 success, but we're waiting for something to finish.
1387* >0 an error occurred while handling the message.
1388* Side effects:
1389*
1390* Call context:
1391* process thread (usually)
1392----------------------------------------------------------------*/
1393int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp)
1394{
1395 hfa384x_t *hw = wlandev->priv;
1396 p80211msg_p2req_ramdl_state_t *msg = msgp;
1397 DBFENTER;
1398
1399 if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
1400 WLAN_LOG_ERROR(
1401 "ramdl_state(): may only be called "
1402 "in the fwload state.\n");
1403 msg->resultcode.data =
1404 P80211ENUM_resultcode_implementation_failure;
1405 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
1406 DBFEXIT;
1407 return 0;
1408 }
1409
1410 /*
1411 ** Note: Interrupts are locked out if this is an AP and are NOT
1412 ** locked out if this is a station.
1413 */
1414
1415 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
1416 if ( msg->enable.data == P80211ENUM_truth_true ) {
1417 if ( hfa384x_drvr_ramdl_enable(hw, msg->exeaddr.data) ) {
1418 msg->resultcode.data = P80211ENUM_resultcode_implementation_failure;
1419 } else {
1420 msg->resultcode.data = P80211ENUM_resultcode_success;
1421 }
1422 } else {
1423 hfa384x_drvr_ramdl_disable(hw);
1424 msg->resultcode.data = P80211ENUM_resultcode_success;
1425 }
1426
1427 DBFEXIT;
1428 return 0;
1429}
1430
1431
1432/*----------------------------------------------------------------
1433* prism2mgmt_ramdl_write
1434*
1435* Writes a buffer to the card RAM using the download state. This
1436* is for writing code to card RAM. To just read or write raw data
1437* use the aux functions.
1438*
1439* Arguments:
1440* wlandev wlan device structure
1441* msgp ptr to msg buffer
1442*
1443* Returns:
1444* 0 success and done
1445* <0 success, but we're waiting for something to finish.
1446* >0 an error occurred while handling the message.
1447* Side effects:
1448*
1449* Call context:
1450* process thread (usually)
1451----------------------------------------------------------------*/
1452int prism2mgmt_ramdl_write(wlandevice_t *wlandev, void *msgp)
1453{
1454 hfa384x_t *hw = wlandev->priv;
1455 p80211msg_p2req_ramdl_write_t *msg = msgp;
1456 UINT32 addr;
1457 UINT32 len;
1458 UINT8 *buf;
1459 DBFENTER;
1460
1461 if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
1462 WLAN_LOG_ERROR(
1463 "ramdl_write(): may only be called "
1464 "in the fwload state.\n");
1465 msg->resultcode.data =
1466 P80211ENUM_resultcode_implementation_failure;
1467 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
1468 DBFEXIT;
1469 return 0;
1470 }
1471
1472 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
1473 /* first validate the length */
1474 if ( msg->len.data > sizeof(msg->data.data) ) {
1475 msg->resultcode.status = P80211ENUM_resultcode_invalid_parameters;
1476 return 0;
1477 }
1478 /* call the hfa384x function to do the write */
1479 addr = msg->addr.data;
1480 len = msg->len.data;
1481 buf = msg->data.data;
1482 if ( hfa384x_drvr_ramdl_write(hw, addr, buf, len) ) {
1483 msg->resultcode.data = P80211ENUM_resultcode_refused;
1484
1485 }
1486 msg->resultcode.data = P80211ENUM_resultcode_success;
1487
1488 DBFEXIT;
1489 return 0;
1490}
1491
1492
1493/*----------------------------------------------------------------
1494* prism2mgmt_flashdl_state
1495*
1496* Establishes the beginning/end of a card Flash download session.
1497*
1498* It is expected that the flashdl_write() function will be called
1499* one or more times between the 'enable' and 'disable' calls to
1500* this function.
1501*
1502* Note: This function should not be called when a mac comm port
1503* is active.
1504*
1505* Arguments:
1506* wlandev wlan device structure
1507* msgp ptr to msg buffer
1508*
1509* Returns:
1510* 0 success and done
1511* <0 success, but we're waiting for something to finish.
1512* >0 an error occurred while handling the message.
1513* Side effects:
1514*
1515* Call context:
1516* process thread (usually)
1517----------------------------------------------------------------*/
1518int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp)
1519{
1520 int result = 0;
1521 hfa384x_t *hw = wlandev->priv;
1522 p80211msg_p2req_flashdl_state_t *msg = msgp;
1523 DBFENTER;
1524
1525 if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
1526 WLAN_LOG_ERROR(
1527 "flashdl_state(): may only be called "
1528 "in the fwload state.\n");
1529 msg->resultcode.data =
1530 P80211ENUM_resultcode_implementation_failure;
1531 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
1532 DBFEXIT;
1533 return 0;
1534 }
1535
1536 /*
1537 ** Note: Interrupts are locked out if this is an AP and are NOT
1538 ** locked out if this is a station.
1539 */
1540
1541 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
1542 if ( msg->enable.data == P80211ENUM_truth_true ) {
1543 if ( hfa384x_drvr_flashdl_enable(hw) ) {
1544 msg->resultcode.data = P80211ENUM_resultcode_implementation_failure;
1545 } else {
1546 msg->resultcode.data = P80211ENUM_resultcode_success;
1547 }
1548 } else {
1549 hfa384x_drvr_flashdl_disable(hw);
1550 msg->resultcode.data = P80211ENUM_resultcode_success;
1551 /* NOTE: At this point, the MAC is in the post-reset
1552 * state and the driver is in the fwload state.
1553 * We need to get the MAC back into the fwload
1554 * state. To do this, we set the nsdstate to HWPRESENT
1555 * and then call the ifstate function to redo everything
1556 * that got us into the fwload state.
1557 */
1558 wlandev->msdstate = WLAN_MSD_HWPRESENT;
1559 result = prism2sta_ifstate(wlandev, P80211ENUM_ifstate_fwload);
1560 if (result != P80211ENUM_resultcode_success) {
1561 WLAN_LOG_ERROR("prism2sta_ifstate(fwload) failed,"
1562 "P80211ENUM_resultcode=%d\n", result);
1563 msg->resultcode.data =
1564 P80211ENUM_resultcode_implementation_failure;
1565 result = -1;
1566 }
1567 }
1568
1569 DBFEXIT;
1570 return 0;
1571}
1572
1573
1574/*----------------------------------------------------------------
1575* prism2mgmt_flashdl_write
1576*
1577*
1578*
1579* Arguments:
1580* wlandev wlan device structure
1581* msgp ptr to msg buffer
1582*
1583* Returns:
1584* 0 success and done
1585* <0 success, but we're waiting for something to finish.
1586* >0 an error occurred while handling the message.
1587* Side effects:
1588*
1589* Call context:
1590* process thread (usually)
1591----------------------------------------------------------------*/
1592int prism2mgmt_flashdl_write(wlandevice_t *wlandev, void *msgp)
1593{
1594 hfa384x_t *hw = wlandev->priv;
1595 p80211msg_p2req_flashdl_write_t *msg = msgp;
1596 UINT32 addr;
1597 UINT32 len;
1598 UINT8 *buf;
1599 DBFENTER;
1600
1601 if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
1602 WLAN_LOG_ERROR(
1603 "flashdl_write(): may only be called "
1604 "in the fwload state.\n");
1605 msg->resultcode.data =
1606 P80211ENUM_resultcode_implementation_failure;
1607 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
1608 DBFEXIT;
1609 return 0;
1610 }
1611
1612 /*
1613 ** Note: Interrupts are locked out if this is an AP and are NOT
1614 ** locked out if this is a station.
1615 */
1616
1617 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
1618 /* first validate the length */
1619 if ( msg->len.data > sizeof(msg->data.data) ) {
1620 msg->resultcode.status =
1621 P80211ENUM_resultcode_invalid_parameters;
1622 return 0;
1623 }
1624 /* call the hfa384x function to do the write */
1625 addr = msg->addr.data;
1626 len = msg->len.data;
1627 buf = msg->data.data;
1628 if ( hfa384x_drvr_flashdl_write(hw, addr, buf, len) ) {
1629 msg->resultcode.data = P80211ENUM_resultcode_refused;
1630
1631 }
1632 msg->resultcode.data = P80211ENUM_resultcode_success;
1633
1634 DBFEXIT;
1635 return 0;
1636}
1637
1638
1639/*----------------------------------------------------------------
1640* prism2mgmt_dump_state
1641*
1642* Dumps the driver's and hardware's current state via the kernel
1643* log at KERN_NOTICE level.
1644*
1645* Arguments:
1646* wlandev wlan device structure
1647* msgp ptr to msg buffer
1648*
1649* Returns:
1650* 0 success and done
1651* <0 success, but we're waiting for something to finish.
1652* >0 an error occurred while handling the message.
1653* Side effects:
1654*
1655* Call context:
1656* process thread (usually)
1657----------------------------------------------------------------*/
1658int prism2mgmt_dump_state(wlandevice_t *wlandev, void *msgp)
1659{
1660 p80211msg_p2req_dump_state_t *msg = msgp;
1661 int result = 0;
1662
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -07001663 DBFENTER;
1664
1665 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
1666 msg->resultcode.data = P80211ENUM_resultcode_not_supported;
1667 goto failed;
1668
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -07001669failed:
1670 DBFEXIT;
1671 return result;
1672}
1673
1674/*----------------------------------------------------------------
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -07001675* prism2mgmt_autojoin
1676*
1677* Associate with an ESS.
1678*
1679* Arguments:
1680* wlandev wlan device structure
1681* msgp ptr to msg buffer
1682*
1683* Returns:
1684* 0 success and done
1685* <0 success, but we're waiting for something to finish.
1686* >0 an error occurred while handling the message.
1687* Side effects:
1688*
1689* Call context:
1690* process thread (usually)
1691* interrupt
1692----------------------------------------------------------------*/
1693int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp)
1694{
1695 hfa384x_t *hw = wlandev->priv;
1696 int result = 0;
1697 UINT16 reg;
1698 UINT16 port_type;
1699 p80211msg_lnxreq_autojoin_t *msg = msgp;
1700 p80211pstrd_t *pstr;
1701 UINT8 bytebuf[256];
1702 hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t*)bytebuf;
1703 DBFENTER;
1704
1705 wlandev->macmode = WLAN_MACMODE_NONE;
1706
1707 /* Set the SSID */
1708 memcpy(&wlandev->ssid, &msg->ssid.data, sizeof(msg->ssid.data));
1709
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -07001710 /* Disable the Port */
1711 hfa384x_drvr_disable(hw, 0);
1712
1713 /*** STATION ***/
1714 /* Set the TxRates */
1715 hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, 0x000f);
1716
1717 /* Set the auth type */
1718 if ( msg->authtype.data == P80211ENUM_authalg_sharedkey ) {
1719 reg = HFA384x_CNFAUTHENTICATION_SHAREDKEY;
1720 } else {
1721 reg = HFA384x_CNFAUTHENTICATION_OPENSYSTEM;
1722 }
1723 hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAUTHENTICATION, reg);
1724
1725 /* Set the ssid */
1726 memset(bytebuf, 0, 256);
1727 pstr = (p80211pstrd_t*)&(msg->ssid.data);
1728 prism2mgmt_pstr2bytestr(p2bytestr, pstr);
1729 result = hfa384x_drvr_setconfig(
1730 hw, HFA384x_RID_CNFDESIREDSSID,
1731 bytebuf, HFA384x_RID_CNFDESIREDSSID_LEN);
1732#if 0
1733 /* we can use the new-fangled auto-unknown mode if the firmware
1734 is 1.3.3 or newer */
1735 if (HFA384x_FIRMARE_VERSION(hw->ident_sta_fw.major,
1736 hw->ident_sta_fw.minor,
1737 hw->ident_sta_fw.variant) >=
1738 HFA384x_FIRMWARE_VERSION(1,3,3)) {
1739 /* Set up the IBSS options */
1740 reg = HFA384x_CREATEIBSS_JOINESS_JOINCREATEIBSS;
1741 hfa384x_drvr_setconfig16(hw, HFA384x_RID_CREATEIBSS, reg);
1742
1743 /* Set the PortType */
1744 port_type = HFA384x_PORTTYPE_IBSS;
1745 } else {
1746 port_type = HFA384x_PORTTYPE_BSS;
1747 }
1748#else
1749 port_type = HFA384x_PORTTYPE_BSS;
1750#endif
1751 /* Set the PortType */
1752 hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, port_type);
1753
1754 /* Enable the Port */
1755 hfa384x_drvr_enable(hw, 0);
1756
1757 /* Set the resultcode */
1758 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
1759 msg->resultcode.data = P80211ENUM_resultcode_success;
1760
Greg Kroah-Hartman00b3ed12008-10-02 11:29:28 -07001761 DBFEXIT;
1762 return result;
1763}
1764
1765
1766/*----------------------------------------------------------------
1767* prism2mgmt_wlansniff
1768*
1769* Start or stop sniffing.
1770*
1771* Arguments:
1772* wlandev wlan device structure
1773* msgp ptr to msg buffer
1774*
1775* Returns:
1776* 0 success and done
1777* <0 success, but we're waiting for something to finish.
1778* >0 an error occurred while handling the message.
1779* Side effects:
1780*
1781* Call context:
1782* process thread (usually)
1783* interrupt
1784----------------------------------------------------------------*/
1785int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
1786{
1787 int result = 0;
1788 p80211msg_lnxreq_wlansniff_t *msg = msgp;
1789
1790 hfa384x_t *hw = wlandev->priv;
1791 UINT16 word;
1792
1793 DBFENTER;
1794
1795 msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
1796 switch (msg->enable.data)
1797 {
1798 case P80211ENUM_truth_false:
1799 /* Confirm that we're in monitor mode */
1800 if ( wlandev->netdev->type == ARPHRD_ETHER ) {
1801 msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
1802 result = 0;
1803 goto exit;
1804 }
1805 /* Disable monitor mode */
1806 result = hfa384x_cmd_monitor(hw, HFA384x_MONITOR_DISABLE);
1807 if ( result ) {
1808 WLAN_LOG_DEBUG(1,
1809 "failed to disable monitor mode, result=%d\n",
1810 result);
1811 goto failed;
1812 }
1813 /* Disable port 0 */
1814 result = hfa384x_drvr_disable(hw, 0);
1815 if ( result ) {
1816 WLAN_LOG_DEBUG(1,
1817 "failed to disable port 0 after sniffing, result=%d\n",
1818 result);
1819 goto failed;
1820 }
1821 /* Clear the driver state */
1822 wlandev->netdev->type = ARPHRD_ETHER;
1823
1824 /* Restore the wepflags */
1825 result = hfa384x_drvr_setconfig16(hw,
1826 HFA384x_RID_CNFWEPFLAGS,
1827 hw->presniff_wepflags);
1828 if ( result ) {
1829 WLAN_LOG_DEBUG(1,
1830 "failed to restore wepflags=0x%04x, result=%d\n",
1831 hw->presniff_wepflags,
1832 result);
1833 goto failed;
1834 }
1835
1836 /* Set the port to its prior type and enable (if necessary) */
1837 if (hw->presniff_port_type != 0 ) {
1838 word = hw->presniff_port_type;
1839 result = hfa384x_drvr_setconfig16(hw,
1840 HFA384x_RID_CNFPORTTYPE, word);
1841 if ( result ) {
1842 WLAN_LOG_DEBUG(1,
1843 "failed to restore porttype, result=%d\n",
1844 result);
1845 goto failed;
1846 }
1847
1848 /* Enable the port */
1849 result = hfa384x_drvr_enable(hw, 0);
1850 if ( result ) {
1851 WLAN_LOG_DEBUG(1, "failed to enable port to presniff setting, result=%d\n", result);
1852 goto failed;
1853 }
1854 } else {
1855 result = hfa384x_drvr_disable(hw, 0);
1856
1857 }
1858
1859 WLAN_LOG_INFO("monitor mode disabled\n");
1860 msg->resultcode.data = P80211ENUM_resultcode_success;
1861 result = 0;
1862 goto exit;
1863 break;
1864 case P80211ENUM_truth_true:
1865 /* Disable the port (if enabled), only check Port 0 */
1866 if ( hw->port_enabled[0]) {
1867 if (wlandev->netdev->type == ARPHRD_ETHER) {
1868 /* Save macport 0 state */
1869 result = hfa384x_drvr_getconfig16(hw,
1870 HFA384x_RID_CNFPORTTYPE,
1871 &(hw->presniff_port_type));
1872 if ( result ) {
1873 WLAN_LOG_DEBUG(1,"failed to read porttype, result=%d\n", result);
1874 goto failed;
1875 }
1876 /* Save the wepflags state */
1877 result = hfa384x_drvr_getconfig16(hw,
1878 HFA384x_RID_CNFWEPFLAGS,
1879 &(hw->presniff_wepflags));
1880 if ( result ) {
1881 WLAN_LOG_DEBUG(1,"failed to read wepflags, result=%d\n", result);
1882 goto failed;
1883 }
1884 hfa384x_drvr_stop(hw);
1885 result = hfa384x_drvr_start(hw);
1886 if ( result ) {
1887 WLAN_LOG_DEBUG(1,
1888 "failed to restart the card for sniffing, result=%d\n",
1889 result);
1890 goto failed;
1891 }
1892 } else {
1893 /* Disable the port */
1894 result = hfa384x_drvr_disable(hw, 0);
1895 if ( result ) {
1896 WLAN_LOG_DEBUG(1,
1897 "failed to enable port for sniffing, result=%d\n",
1898 result);
1899 goto failed;
1900 }
1901 }
1902 } else {
1903 hw->presniff_port_type = 0;
1904 }
1905
1906 /* Set the channel we wish to sniff */
1907 word = msg->channel.data;
1908 result = hfa384x_drvr_setconfig16(hw,
1909 HFA384x_RID_CNFOWNCHANNEL, word);
1910 hw->sniff_channel=word;
1911
1912 if ( result ) {
1913 WLAN_LOG_DEBUG(1,
1914 "failed to set channel %d, result=%d\n",
1915 word,
1916 result);
1917 goto failed;
1918 }
1919
1920 /* Now if we're already sniffing, we can skip the rest */
1921 if (wlandev->netdev->type != ARPHRD_ETHER) {
1922 /* Set the port type to pIbss */
1923 word = HFA384x_PORTTYPE_PSUEDOIBSS;
1924 result = hfa384x_drvr_setconfig16(hw,
1925 HFA384x_RID_CNFPORTTYPE, word);
1926 if ( result ) {
1927 WLAN_LOG_DEBUG(1,
1928 "failed to set porttype %d, result=%d\n",
1929 word,
1930 result);
1931 goto failed;
1932 }
1933 if ((msg->keepwepflags.status == P80211ENUM_msgitem_status_data_ok) && (msg->keepwepflags.data != P80211ENUM_truth_true)) {
1934 /* Set the wepflags for no decryption */
1935 word = HFA384x_WEPFLAGS_DISABLE_TXCRYPT |
1936 HFA384x_WEPFLAGS_DISABLE_RXCRYPT;
1937 result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFWEPFLAGS, word);
1938 }
1939
1940 if ( result ) {
1941 WLAN_LOG_DEBUG(1,
1942 "failed to set wepflags=0x%04x, result=%d\n",
1943 word,
1944 result);
1945 goto failed;
1946 }
1947 }
1948
1949 /* Do we want to strip the FCS in monitor mode? */
1950 if ((msg->stripfcs.status == P80211ENUM_msgitem_status_data_ok) && (msg->stripfcs.data == P80211ENUM_truth_true)) {
1951 hw->sniff_fcs = 0;
1952 } else {
1953 hw->sniff_fcs = 1;
1954 }
1955
1956 /* Do we want to truncate the packets? */
1957 if (msg->packet_trunc.status == P80211ENUM_msgitem_status_data_ok) {
1958 hw->sniff_truncate = msg->packet_trunc.data;
1959 } else {
1960 hw->sniff_truncate = 0;
1961 }
1962
1963 /* Enable the port */
1964 result = hfa384x_drvr_enable(hw, 0);
1965 if ( result ) {
1966 WLAN_LOG_DEBUG(1,
1967 "failed to enable port for sniffing, result=%d\n",
1968 result);
1969 goto failed;
1970 }
1971 /* Enable monitor mode */
1972 result = hfa384x_cmd_monitor(hw, HFA384x_MONITOR_ENABLE);
1973 if ( result ) {
1974 WLAN_LOG_DEBUG(1,
1975 "failed to enable monitor mode, result=%d\n",
1976 result);
1977 goto failed;
1978 }
1979
1980 if (wlandev->netdev->type == ARPHRD_ETHER) {
1981 WLAN_LOG_INFO("monitor mode enabled\n");
1982 }
1983
1984 /* Set the driver state */
1985 /* Do we want the prism2 header? */
1986 if ((msg->prismheader.status == P80211ENUM_msgitem_status_data_ok) && (msg->prismheader.data == P80211ENUM_truth_true)) {
1987 hw->sniffhdr = 0;
1988 wlandev->netdev->type = ARPHRD_IEEE80211_PRISM;
1989 } else if ((msg->wlanheader.status == P80211ENUM_msgitem_status_data_ok) && (msg->wlanheader.data == P80211ENUM_truth_true)) {
1990 hw->sniffhdr = 1;
1991 wlandev->netdev->type = ARPHRD_IEEE80211_PRISM;
1992 } else {
1993 wlandev->netdev->type = ARPHRD_IEEE80211;
1994 }
1995
1996 msg->resultcode.data = P80211ENUM_resultcode_success;
1997 result = 0;
1998 goto exit;
1999 break;
2000 default:
2001 msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
2002 result = 0;
2003 goto exit;
2004 break;
2005 }
2006
2007failed:
2008 msg->resultcode.data = P80211ENUM_resultcode_refused;
2009 result = 0;
2010exit:
2011
2012 DBFEXIT;
2013 return result;
2014}