Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Side by Side Diff: chromeos/drivers/ath6kl/os/linux/ioctl.c

Issue 646055: Atheros AR600x driver + build glue (Closed)
Patch Set: Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 *
3 * Copyright (c) 2004-2010 Atheros Communications Inc.
4 * All rights reserved.
5 *
6 *
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License version 2 as
9 // published by the Free Software Foundation;
10 //
11 // Software distributed under the License is distributed on an "AS
12 // IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
13 // implied. See the License for the specific language governing
14 // rights and limitations under the License.
15 //
16 //
17 *
18 */
19
20 #include "ar6000_drv.h"
21 #include "ieee80211_ioctl.h"
22 #include "ar6kap_common.h"
23 #include "targaddrs.h"
24 #include "a_hci.h"
25
26 extern int enablerssicompensation;
27 A_UINT32 tcmdRxFreq;
28 extern unsigned int wmitimeout;
29 extern A_WAITQUEUE_HEAD arEvent;
30 extern int tspecCompliance;
31 extern int bmienable;
32 extern int bypasswmi;
33 extern int loghci;
34
35 static int
36 ar6000_ioctl_get_roam_tbl(struct net_device *dev, struct ifreq *rq)
37 {
38 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
39
40 if (ar->arWmiReady == FALSE) {
41 return -EIO;
42 }
43
44 if(wmi_get_roam_tbl_cmd(ar->arWmi) != A_OK) {
45 return -EIO;
46 }
47
48 return 0;
49 }
50
51 static int
52 ar6000_ioctl_get_roam_data(struct net_device *dev, struct ifreq *rq)
53 {
54 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
55
56 if (ar->arWmiReady == FALSE) {
57 return -EIO;
58 }
59
60
61 /* currently assume only roam times are required */
62 if(wmi_get_roam_data_cmd(ar->arWmi, ROAM_DATA_TIME) != A_OK) {
63 return -EIO;
64 }
65
66
67 return 0;
68 }
69
70 static int
71 ar6000_ioctl_set_roam_ctrl(struct net_device *dev, char *userdata)
72 {
73 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
74 WMI_SET_ROAM_CTRL_CMD cmd;
75 A_UINT8 size = sizeof(cmd);
76
77 if (ar->arWmiReady == FALSE) {
78 return -EIO;
79 }
80
81
82 if (copy_from_user(&cmd, userdata, size)) {
83 return -EFAULT;
84 }
85
86 if (cmd.roamCtrlType == WMI_SET_HOST_BIAS) {
87 if (cmd.info.bssBiasInfo.numBss > 1) {
88 size += (cmd.info.bssBiasInfo.numBss - 1) * sizeof(WMI_BSS_BIAS);
89 }
90 }
91
92 if (copy_from_user(&cmd, userdata, size)) {
93 return -EFAULT;
94 }
95
96 if(wmi_set_roam_ctrl_cmd(ar->arWmi, &cmd, size) != A_OK) {
97 return -EIO;
98 }
99
100 return 0;
101 }
102
103 static int
104 ar6000_ioctl_set_powersave_timers(struct net_device *dev, char *userdata)
105 {
106 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
107 WMI_POWERSAVE_TIMERS_POLICY_CMD cmd;
108 A_UINT8 size = sizeof(cmd);
109
110 if (ar->arWmiReady == FALSE) {
111 return -EIO;
112 }
113
114 if (copy_from_user(&cmd, userdata, size)) {
115 return -EFAULT;
116 }
117
118 if (copy_from_user(&cmd, userdata, size)) {
119 return -EFAULT;
120 }
121
122 if(wmi_set_powersave_timers_cmd(ar->arWmi, &cmd, size) != A_OK) {
123 return -EIO;
124 }
125
126 return 0;
127 }
128
129 static int
130 ar6000_ioctl_set_qos_supp(struct net_device *dev, struct ifreq *rq)
131 {
132 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
133 WMI_SET_QOS_SUPP_CMD cmd;
134 A_STATUS ret;
135
136 if ((dev->flags & IFF_UP) != IFF_UP) {
137 return -EIO;
138 }
139 if (ar->arWmiReady == FALSE) {
140 return -EIO;
141 }
142
143 if (copy_from_user(&cmd, (char *)((unsigned int*)rq->ifr_data + 1),
144 sizeof(cmd)))
145 {
146 return -EFAULT;
147 }
148
149 ret = wmi_set_qos_supp_cmd(ar->arWmi, cmd.status);
150
151 switch (ret) {
152 case A_OK:
153 return 0;
154 case A_EBUSY :
155 return -EBUSY;
156 case A_NO_MEMORY:
157 return -ENOMEM;
158 case A_EINVAL:
159 default:
160 return -EFAULT;
161 }
162 }
163
164 static int
165 ar6000_ioctl_set_wmm(struct net_device *dev, struct ifreq *rq)
166 {
167 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
168 WMI_SET_WMM_CMD cmd;
169 A_STATUS ret;
170
171 if ((dev->flags & IFF_UP) != IFF_UP) {
172 return -EIO;
173 }
174 if (ar->arWmiReady == FALSE) {
175 return -EIO;
176 }
177
178 if (copy_from_user(&cmd, (char *)((unsigned int*)rq->ifr_data + 1),
179 sizeof(cmd)))
180 {
181 return -EFAULT;
182 }
183
184 if (cmd.status == WMI_WMM_ENABLED) {
185 ar->arWmmEnabled = TRUE;
186 } else {
187 ar->arWmmEnabled = FALSE;
188 }
189
190 ret = wmi_set_wmm_cmd(ar->arWmi, cmd.status);
191
192 switch (ret) {
193 case A_OK:
194 return 0;
195 case A_EBUSY :
196 return -EBUSY;
197 case A_NO_MEMORY:
198 return -ENOMEM;
199 case A_EINVAL:
200 default:
201 return -EFAULT;
202 }
203 }
204
205 static int
206 ar6000_ioctl_set_txop(struct net_device *dev, struct ifreq *rq)
207 {
208 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
209 WMI_SET_WMM_TXOP_CMD cmd;
210 A_STATUS ret;
211
212 if ((dev->flags & IFF_UP) != IFF_UP) {
213 return -EIO;
214 }
215 if (ar->arWmiReady == FALSE) {
216 return -EIO;
217 }
218
219 if (copy_from_user(&cmd, (char *)((unsigned int*)rq->ifr_data + 1),
220 sizeof(cmd)))
221 {
222 return -EFAULT;
223 }
224
225 ret = wmi_set_wmm_txop(ar->arWmi, cmd.txopEnable);
226
227 switch (ret) {
228 case A_OK:
229 return 0;
230 case A_EBUSY :
231 return -EBUSY;
232 case A_NO_MEMORY:
233 return -ENOMEM;
234 case A_EINVAL:
235 default:
236 return -EFAULT;
237 }
238 }
239
240 static int
241 ar6000_ioctl_get_rd(struct net_device *dev, struct ifreq *rq)
242 {
243 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
244 A_STATUS ret = 0;
245
246 if ((dev->flags & IFF_UP) != IFF_UP || ar->arWmiReady == FALSE) {
247 return -EIO;
248 }
249
250 if(copy_to_user((char *)((unsigned int*)rq->ifr_data + 1),
251 &ar->arRegCode, sizeof(ar->arRegCode)))
252 ret = -EFAULT;
253
254 return ret;
255 }
256
257 static int
258 ar6000_ioctl_set_country(struct net_device *dev, struct ifreq *rq)
259 {
260 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
261 WMI_AP_SET_COUNTRY_CMD cmd;
262 A_STATUS ret;
263
264 if ((dev->flags & IFF_UP) != IFF_UP) {
265 return -EIO;
266 }
267 if (ar->arWmiReady == FALSE) {
268 return -EIO;
269 }
270
271 if (copy_from_user(&cmd, (char *)((unsigned int*)rq->ifr_data + 1),
272 sizeof(cmd)))
273 {
274 return -EFAULT;
275 }
276
277 ar->ap_profile_flag = 1; /* There is a change in profile */
278
279 ret = wmi_set_country(ar->arWmi, cmd.countryCode);
280 A_MEMCPY(ar->ap_country_code, cmd.countryCode, 3);
281
282 switch (ret) {
283 case A_OK:
284 return 0;
285 case A_EBUSY :
286 return -EBUSY;
287 case A_NO_MEMORY:
288 return -ENOMEM;
289 case A_EINVAL:
290 default:
291 return -EFAULT;
292 }
293 }
294
295
296 /* Get power mode command */
297 static int
298 ar6000_ioctl_get_power_mode(struct net_device *dev, struct ifreq *rq)
299 {
300 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
301 WMI_POWER_MODE_CMD power_mode;
302 int ret = 0;
303
304 if (ar->arWmiReady == FALSE) {
305 return -EIO;
306 }
307
308 power_mode.powerMode = wmi_get_power_mode_cmd(ar->arWmi);
309 if (copy_to_user(rq->ifr_data, &power_mode, sizeof(WMI_POWER_MODE_CMD))) {
310 ret = -EFAULT;
311 }
312
313 return ret;
314 }
315
316
317 static int
318 ar6000_ioctl_set_channelParams(struct net_device *dev, struct ifreq *rq)
319 {
320 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
321 WMI_CHANNEL_PARAMS_CMD cmd, *cmdp;
322 int ret = 0;
323
324 if (ar->arWmiReady == FALSE) {
325 return -EIO;
326 }
327
328
329 if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
330 return -EFAULT;
331 }
332
333 if( (ar->arNextMode == AP_NETWORK) && (cmd.numChannels || cmd.scanParam) ) {
334 A_PRINTF("ERROR: Only wmode is allowed in AP mode\n");
335 return -EIO;
336 }
337
338 if (cmd.numChannels > 1) {
339 cmdp = A_MALLOC(130);
340 if (copy_from_user(cmdp, rq->ifr_data,
341 sizeof (*cmdp) +
342 ((cmd.numChannels - 1) * sizeof(A_UINT16))))
343 {
344 kfree(cmdp);
345 return -EFAULT;
346 }
347 } else {
348 cmdp = &cmd;
349 }
350
351 if ((ar->arPhyCapability == WMI_11G_CAPABILITY) &&
352 ((cmdp->phyMode == WMI_11A_MODE) || (cmdp->phyMode == WMI_11AG_MODE)))
353 {
354 ret = -EINVAL;
355 }
356
357 if (!ret &&
358 (wmi_set_channelParams_cmd(ar->arWmi, cmdp->scanParam, cmdp->phyMode,
359 cmdp->numChannels, cmdp->channelList)
360 != A_OK))
361 {
362 ret = -EIO;
363 }
364
365 if (cmd.numChannels > 1) {
366 kfree(cmdp);
367 }
368
369 ar->ap_wmode = cmdp->phyMode;
370 /* Set the profile change flag to allow a commit cmd */
371 ar->ap_profile_flag = 1;
372
373 return ret;
374 }
375
376
377 static int
378 ar6000_ioctl_set_snr_threshold(struct net_device *dev, struct ifreq *rq)
379 {
380
381 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
382 WMI_SNR_THRESHOLD_PARAMS_CMD cmd;
383 int ret = 0;
384
385 if (ar->arWmiReady == FALSE) {
386 return -EIO;
387 }
388
389 if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
390 return -EFAULT;
391 }
392
393 if( wmi_set_snr_threshold_params(ar->arWmi, &cmd) != A_OK ) {
394 ret = -EIO;
395 }
396
397 return ret;
398 }
399
400 static int
401 ar6000_ioctl_set_rssi_threshold(struct net_device *dev, struct ifreq *rq)
402 {
403 #define SWAP_THOLD(thold1, thold2) do { \
404 USER_RSSI_THOLD tmpThold; \
405 tmpThold.tag = thold1.tag; \
406 tmpThold.rssi = thold1.rssi; \
407 thold1.tag = thold2.tag; \
408 thold1.rssi = thold2.rssi; \
409 thold2.tag = tmpThold.tag; \
410 thold2.rssi = tmpThold.rssi; \
411 } while (0)
412
413 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
414 WMI_RSSI_THRESHOLD_PARAMS_CMD cmd;
415 USER_RSSI_PARAMS rssiParams;
416 A_INT32 i, j;
417 int ret = 0;
418
419 if (ar->arWmiReady == FALSE) {
420 return -EIO;
421 }
422
423 if (copy_from_user((char *)&rssiParams, (char *)((unsigned int *)rq->ifr_dat a + 1), sizeof(USER_RSSI_PARAMS))) {
424 return -EFAULT;
425 }
426 cmd.weight = rssiParams.weight;
427 cmd.pollTime = rssiParams.pollTime;
428
429 A_MEMCPY(ar->rssi_map, &rssiParams.tholds, sizeof(ar->rssi_map));
430 /*
431 * only 6 elements, so use bubble sorting, in ascending order
432 */
433 for (i = 5; i > 0; i--) {
434 for (j = 0; j < i; j++) { /* above tholds */
435 if (ar->rssi_map[j+1].rssi < ar->rssi_map[j].rssi) {
436 SWAP_THOLD(ar->rssi_map[j+1], ar->rssi_map[j]);
437 } else if (ar->rssi_map[j+1].rssi == ar->rssi_map[j].rssi) {
438 return EFAULT;
439 }
440 }
441 }
442 for (i = 11; i > 6; i--) {
443 for (j = 6; j < i; j++) { /* below tholds */
444 if (ar->rssi_map[j+1].rssi < ar->rssi_map[j].rssi) {
445 SWAP_THOLD(ar->rssi_map[j+1], ar->rssi_map[j]);
446 } else if (ar->rssi_map[j+1].rssi == ar->rssi_map[j].rssi) {
447 return EFAULT;
448 }
449 }
450 }
451
452 #ifdef DEBUG
453 for (i = 0; i < 12; i++) {
454 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("thold[%d].tag: %d, thold[%d].rssi: %d \ n",
455 i, ar->rssi_map[i].tag, i, ar->rssi_map[i].rssi));
456 }
457 #endif
458
459 if (enablerssicompensation) {
460 for (i = 0; i < 6; i++)
461 ar->rssi_map[i].rssi = rssi_compensation_reverse_calc(ar, ar->rssi_m ap[i].rssi, TRUE);
462 for (i = 6; i < 12; i++)
463 ar->rssi_map[i].rssi = rssi_compensation_reverse_calc(ar, ar->rssi_m ap[i].rssi, FALSE);
464 }
465
466 cmd.thresholdAbove1_Val = ar->rssi_map[0].rssi;
467 cmd.thresholdAbove2_Val = ar->rssi_map[1].rssi;
468 cmd.thresholdAbove3_Val = ar->rssi_map[2].rssi;
469 cmd.thresholdAbove4_Val = ar->rssi_map[3].rssi;
470 cmd.thresholdAbove5_Val = ar->rssi_map[4].rssi;
471 cmd.thresholdAbove6_Val = ar->rssi_map[5].rssi;
472 cmd.thresholdBelow1_Val = ar->rssi_map[6].rssi;
473 cmd.thresholdBelow2_Val = ar->rssi_map[7].rssi;
474 cmd.thresholdBelow3_Val = ar->rssi_map[8].rssi;
475 cmd.thresholdBelow4_Val = ar->rssi_map[9].rssi;
476 cmd.thresholdBelow5_Val = ar->rssi_map[10].rssi;
477 cmd.thresholdBelow6_Val = ar->rssi_map[11].rssi;
478
479 if( wmi_set_rssi_threshold_params(ar->arWmi, &cmd) != A_OK ) {
480 ret = -EIO;
481 }
482
483 return ret;
484 }
485
486 static int
487 ar6000_ioctl_set_lq_threshold(struct net_device *dev, struct ifreq *rq)
488 {
489
490 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
491 WMI_LQ_THRESHOLD_PARAMS_CMD cmd;
492 int ret = 0;
493
494 if (ar->arWmiReady == FALSE) {
495 return -EIO;
496 }
497
498 if (copy_from_user(&cmd, (char *)((unsigned int *)rq->ifr_data + 1), sizeof( cmd))) {
499 return -EFAULT;
500 }
501
502 if( wmi_set_lq_threshold_params(ar->arWmi, &cmd) != A_OK ) {
503 ret = -EIO;
504 }
505
506 return ret;
507 }
508
509
510 static int
511 ar6000_ioctl_set_probedSsid(struct net_device *dev, struct ifreq *rq)
512 {
513 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
514 WMI_PROBED_SSID_CMD cmd;
515 int ret = 0;
516
517 if (ar->arWmiReady == FALSE) {
518 return -EIO;
519 }
520
521 if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
522 return -EFAULT;
523 }
524
525 if (wmi_probedSsid_cmd(ar->arWmi, cmd.entryIndex, cmd.flag, cmd.ssidLength,
526 cmd.ssid) != A_OK)
527 {
528 ret = -EIO;
529 }
530
531 return ret;
532 }
533
534 static int
535 ar6000_ioctl_set_badAp(struct net_device *dev, struct ifreq *rq)
536 {
537 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
538 WMI_ADD_BAD_AP_CMD cmd;
539 int ret = 0;
540
541 if (ar->arWmiReady == FALSE) {
542 return -EIO;
543 }
544
545
546 if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
547 return -EFAULT;
548 }
549
550 if (cmd.badApIndex > WMI_MAX_BAD_AP_INDEX) {
551 return -EIO;
552 }
553
554 if (A_MEMCMP(cmd.bssid, null_mac, AR6000_ETH_ADDR_LEN) == 0) {
555 /*
556 * This is a delete badAP.
557 */
558 if (wmi_deleteBadAp_cmd(ar->arWmi, cmd.badApIndex) != A_OK) {
559 ret = -EIO;
560 }
561 } else {
562 if (wmi_addBadAp_cmd(ar->arWmi, cmd.badApIndex, cmd.bssid) != A_OK) {
563 ret = -EIO;
564 }
565 }
566
567 return ret;
568 }
569
570 static int
571 ar6000_ioctl_create_qos(struct net_device *dev, struct ifreq *rq)
572 {
573 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
574 WMI_CREATE_PSTREAM_CMD cmd;
575 A_STATUS ret;
576
577 if (ar->arWmiReady == FALSE) {
578 return -EIO;
579 }
580
581
582 if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
583 return -EFAULT;
584 }
585
586 ret = wmi_verify_tspec_params(&cmd, tspecCompliance);
587 if (ret == A_OK)
588 ret = wmi_create_pstream_cmd(ar->arWmi, &cmd);
589
590 switch (ret) {
591 case A_OK:
592 return 0;
593 case A_EBUSY :
594 return -EBUSY;
595 case A_NO_MEMORY:
596 return -ENOMEM;
597 case A_EINVAL:
598 default:
599 return -EFAULT;
600 }
601 }
602
603 static int
604 ar6000_ioctl_delete_qos(struct net_device *dev, struct ifreq *rq)
605 {
606 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
607 WMI_DELETE_PSTREAM_CMD cmd;
608 int ret = 0;
609
610 if (ar->arWmiReady == FALSE) {
611 return -EIO;
612 }
613
614 if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
615 return -EFAULT;
616 }
617
618 ret = wmi_delete_pstream_cmd(ar->arWmi, cmd.trafficClass, cmd.tsid);
619
620 switch (ret) {
621 case A_OK:
622 return 0;
623 case A_EBUSY :
624 return -EBUSY;
625 case A_NO_MEMORY:
626 return -ENOMEM;
627 case A_EINVAL:
628 default:
629 return -EFAULT;
630 }
631 }
632
633 static int
634 ar6000_ioctl_get_qos_queue(struct net_device *dev, struct ifreq *rq)
635 {
636 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
637 struct ar6000_queuereq qreq;
638 int ret = 0;
639
640 if (ar->arWmiReady == FALSE) {
641 return -EIO;
642 }
643
644 if( copy_from_user(&qreq, rq->ifr_data,
645 sizeof(struct ar6000_queuereq)))
646 return -EFAULT;
647
648 qreq.activeTsids = wmi_get_mapped_qos_queue(ar->arWmi, qreq.trafficClass);
649
650 if (copy_to_user(rq->ifr_data, &qreq,
651 sizeof(struct ar6000_queuereq)))
652 {
653 ret = -EFAULT;
654 }
655
656 return ret;
657 }
658
659 #ifdef CONFIG_HOST_TCMD_SUPPORT
660 static A_STATUS
661 ar6000_ioctl_tcmd_get_rx_report(struct net_device *dev,
662 struct ifreq *rq, A_UINT8 *data, A_UINT32 len)
663 {
664 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
665 A_UINT32 buf[4+TCMD_MAX_RATES];
666 int ret = 0;
667
668 if (ar->bIsDestroyProgress) {
669 return -EBUSY;
670 }
671
672 if (ar->arWmiReady == FALSE) {
673 return -EIO;
674 }
675
676 if (down_interruptible(&ar->arSem)) {
677 return -ERESTARTSYS;
678 }
679
680 if (ar->bIsDestroyProgress) {
681 up(&ar->arSem);
682 return -EBUSY;
683 }
684
685 ar->tcmdRxReport = 0;
686 if (wmi_test_cmd(ar->arWmi, data, len) != A_OK) {
687 up(&ar->arSem);
688 return -EIO;
689 }
690
691 wait_event_interruptible_timeout(arEvent, ar->tcmdRxReport != 0, wmitimeout * HZ);
692
693 if (signal_pending(current)) {
694 ret = -EINTR;
695 }
696
697 buf[0] = ar->tcmdRxTotalPkt;
698 buf[1] = ar->tcmdRxRssi;
699 buf[2] = ar->tcmdRxcrcErrPkt;
700 buf[3] = ar->tcmdRxsecErrPkt;
701 A_MEMCPY(((A_UCHAR *)buf)+(4*sizeof(A_UINT32)), ar->tcmdRateCnt, sizeof(ar-> tcmdRateCnt));
702 A_MEMCPY(((A_UCHAR *)buf)+(4*sizeof(A_UINT32))+(TCMD_MAX_RATES *sizeof(A_UIN T16)), ar->tcmdRateCntShortGuard, sizeof(ar->tcmdRateCntShortGuard));
703
704 if (!ret && copy_to_user(rq->ifr_data, buf, sizeof(buf))) {
705 ret = -EFAULT;
706 }
707
708 up(&ar->arSem);
709
710 return ret;
711 }
712
713 void
714 ar6000_tcmd_rx_report_event(void *devt, A_UINT8 * results, int len)
715 {
716 AR_SOFTC_T *ar = (AR_SOFTC_T *)devt;
717 TCMD_CONT_RX * rx_rep = (TCMD_CONT_RX *)results;
718
719 if (enablerssicompensation) {
720 rx_rep->u.report.rssiInDBm = rssi_compensation_calc_tcmd(tcmdRxFreq, rx_ rep->u.report.rssiInDBm,rx_rep->u.report.totalPkt);
721 }
722
723
724 ar->tcmdRxTotalPkt = rx_rep->u.report.totalPkt;
725 ar->tcmdRxRssi = rx_rep->u.report.rssiInDBm;
726 ar->tcmdRxcrcErrPkt = rx_rep->u.report.crcErrPkt;
727 ar->tcmdRxsecErrPkt = rx_rep->u.report.secErrPkt;
728 ar->tcmdRxReport = 1;
729 A_MEMZERO(ar->tcmdRateCnt, sizeof(ar->tcmdRateCnt));
730 A_MEMZERO(ar->tcmdRateCntShortGuard, sizeof(ar->tcmdRateCntShortGuard));
731 A_MEMCPY(ar->tcmdRateCnt, rx_rep->u.report.rateCnt, sizeof(ar->tcmdRateCnt)) ;
732 A_MEMCPY(ar->tcmdRateCntShortGuard, rx_rep->u.report.rateCntShortGuard, size of(ar->tcmdRateCntShortGuard));
733
734 wake_up(&arEvent);
735 }
736 #endif /* CONFIG_HOST_TCMD_SUPPORT*/
737
738 static int
739 ar6000_ioctl_set_error_report_bitmask(struct net_device *dev, struct ifreq *rq)
740 {
741 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
742 WMI_TARGET_ERROR_REPORT_BITMASK cmd;
743 int ret = 0;
744
745 if (ar->arWmiReady == FALSE) {
746 return -EIO;
747 }
748
749 if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
750 return -EFAULT;
751 }
752
753 ret = wmi_set_error_report_bitmask(ar->arWmi, cmd.bitmask);
754
755 return (ret==0 ? ret : -EINVAL);
756 }
757
758 static int
759 ar6000_clear_target_stats(struct net_device *dev)
760 {
761 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
762 TARGET_STATS *pStats = &ar->arTargetStats;
763 int ret = 0;
764
765 if (ar->arWmiReady == FALSE) {
766 return -EIO;
767 }
768 AR6000_SPIN_LOCK(&ar->arLock, 0);
769 A_MEMZERO(pStats, sizeof(TARGET_STATS));
770 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
771 return ret;
772 }
773
774 static int
775 ar6000_ioctl_get_target_stats(struct net_device *dev, struct ifreq *rq)
776 {
777 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
778 TARGET_STATS_CMD cmd;
779 TARGET_STATS *pStats = &ar->arTargetStats;
780 int ret = 0;
781
782 if (ar->bIsDestroyProgress) {
783 return -EBUSY;
784 }
785 if (ar->arWmiReady == FALSE) {
786 return -EIO;
787 }
788 if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
789 return -EFAULT;
790 }
791 if (down_interruptible(&ar->arSem)) {
792 return -ERESTARTSYS;
793 }
794 if (ar->bIsDestroyProgress) {
795 up(&ar->arSem);
796 return -EBUSY;
797 }
798
799 ar->statsUpdatePending = TRUE;
800
801 if(wmi_get_stats_cmd(ar->arWmi) != A_OK) {
802 up(&ar->arSem);
803 return -EIO;
804 }
805
806 wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == FALSE, w mitimeout * HZ);
807
808 if (signal_pending(current)) {
809 ret = -EINTR;
810 }
811
812 if (!ret && copy_to_user(rq->ifr_data, pStats, sizeof(*pStats))) {
813 ret = -EFAULT;
814 }
815
816 if (cmd.clearStats == 1) {
817 ret = ar6000_clear_target_stats(dev);
818 }
819
820 up(&ar->arSem);
821
822 return ret;
823 }
824
825 static int
826 ar6000_ioctl_get_ap_stats(struct net_device *dev, struct ifreq *rq)
827 {
828 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
829 WMI_AP_MODE_STAT cmd;
830 WMI_AP_MODE_STAT *pStats = &ar->arAPStats;
831 int ret = 0;
832
833 if (ar->arWmiReady == FALSE) {
834 return -EIO;
835 }
836 if (copy_from_user(&cmd, (char *)((unsigned int*)rq->ifr_data + 1),
837 sizeof(cmd)))
838 {
839 return -EFAULT;
840 }
841 if (cmd.action == AP_CLEAR_STATS) {
842 A_UINT8 i;
843 AR6000_SPIN_LOCK(&ar->arLock, 0);
844 for(i = 0; i < AP_MAX_NUM_STA; i++) {
845 pStats->sta[i].tx_bytes = 0;
846 pStats->sta[i].tx_pkts = 0;
847 pStats->sta[i].tx_error = 0;
848 pStats->sta[i].tx_discard = 0;
849 pStats->sta[i].rx_bytes = 0;
850 pStats->sta[i].rx_pkts = 0;
851 pStats->sta[i].rx_error = 0;
852 pStats->sta[i].rx_discard = 0;
853 }
854 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
855 return ret;
856 }
857
858 if (down_interruptible(&ar->arSem)) {
859 return -ERESTARTSYS;
860 }
861
862 ar->statsUpdatePending = TRUE;
863
864 if(wmi_get_stats_cmd(ar->arWmi) != A_OK) {
865 up(&ar->arSem);
866 return -EIO;
867 }
868
869 wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == FALSE, w mitimeout * HZ);
870
871 if (signal_pending(current)) {
872 ret = -EINTR;
873 }
874
875 if (!ret && copy_to_user(rq->ifr_data, pStats, sizeof(*pStats))) {
876 ret = -EFAULT;
877 }
878
879 up(&ar->arSem);
880
881 return ret;
882 }
883
884 static int
885 ar6000_ioctl_set_access_params(struct net_device *dev, struct ifreq *rq)
886 {
887 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
888 WMI_SET_ACCESS_PARAMS_CMD cmd;
889 int ret = 0;
890
891 if (ar->arWmiReady == FALSE) {
892 return -EIO;
893 }
894
895 if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
896 return -EFAULT;
897 }
898
899 if (wmi_set_access_params_cmd(ar->arWmi, cmd.txop, cmd.eCWmin, cmd.eCWmax,
900 cmd.aifsn) == A_OK)
901 {
902 ret = 0;
903 } else {
904 ret = -EINVAL;
905 }
906
907 return (ret);
908 }
909
910 static int
911 ar6000_ioctl_set_disconnect_timeout(struct net_device *dev, struct ifreq *rq)
912 {
913 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
914 WMI_DISC_TIMEOUT_CMD cmd;
915 int ret = 0;
916
917 if (ar->arWmiReady == FALSE) {
918 return -EIO;
919 }
920
921 if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
922 return -EFAULT;
923 }
924
925 if (wmi_disctimeout_cmd(ar->arWmi, cmd.disconnectTimeout) == A_OK)
926 {
927 ret = 0;
928 } else {
929 ret = -EINVAL;
930 }
931
932 return (ret);
933 }
934
935 static int
936 ar6000_xioctl_set_voice_pkt_size(struct net_device *dev, char * userdata)
937 {
938 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
939 WMI_SET_VOICE_PKT_SIZE_CMD cmd;
940 int ret = 0;
941
942 if (ar->arWmiReady == FALSE) {
943 return -EIO;
944 }
945
946 if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
947 return -EFAULT;
948 }
949
950 if (wmi_set_voice_pkt_size_cmd(ar->arWmi, cmd.voicePktSize) == A_OK)
951 {
952 ret = 0;
953 } else {
954 ret = -EINVAL;
955 }
956
957
958 return (ret);
959 }
960
961 static int
962 ar6000_xioctl_set_max_sp_len(struct net_device *dev, char * userdata)
963 {
964 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
965 WMI_SET_MAX_SP_LEN_CMD cmd;
966 int ret = 0;
967
968 if (ar->arWmiReady == FALSE) {
969 return -EIO;
970 }
971
972 if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
973 return -EFAULT;
974 }
975
976 if (wmi_set_max_sp_len_cmd(ar->arWmi, cmd.maxSPLen) == A_OK)
977 {
978 ret = 0;
979 } else {
980 ret = -EINVAL;
981 }
982
983 return (ret);
984 }
985
986
987 static int
988 ar6000_xioctl_set_bt_status_cmd(struct net_device *dev, char * userdata)
989 {
990 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
991 WMI_SET_BT_STATUS_CMD cmd;
992 int ret = 0;
993
994 if (ar->arWmiReady == FALSE) {
995 return -EIO;
996 }
997
998 if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
999 return -EFAULT;
1000 }
1001
1002 if (wmi_set_bt_status_cmd(ar->arWmi, cmd.streamType, cmd.status) == A_OK)
1003 {
1004 ret = 0;
1005 } else {
1006 ret = -EINVAL;
1007 }
1008
1009 return (ret);
1010 }
1011
1012 static int
1013 ar6000_xioctl_set_bt_params_cmd(struct net_device *dev, char * userdata)
1014 {
1015 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1016 WMI_SET_BT_PARAMS_CMD cmd;
1017 int ret = 0;
1018
1019 if (ar->arWmiReady == FALSE) {
1020 return -EIO;
1021 }
1022
1023 if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
1024 return -EFAULT;
1025 }
1026
1027 if (wmi_set_bt_params_cmd(ar->arWmi, &cmd) == A_OK)
1028 {
1029 ret = 0;
1030 } else {
1031 ret = -EINVAL;
1032 }
1033
1034 return (ret);
1035 }
1036
1037 static int
1038 ar6000_xioctl_set_btcoex_fe_ant_cmd(struct net_device * dev, char * userdata)
1039 {
1040 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1041 WMI_SET_BTCOEX_FE_ANT_CMD cmd;
1042 int ret = 0;
1043
1044 if (ar->arWmiReady == FALSE) {
1045 return -EIO;
1046 }
1047 if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
1048 return -EFAULT;
1049 }
1050
1051 if (wmi_set_btcoex_fe_ant_cmd(ar->arWmi, &cmd) == A_OK)
1052 {
1053 ret = 0;
1054 } else {
1055 ret = -EINVAL;
1056 }
1057
1058 return(ret);
1059 }
1060
1061 static int
1062 ar6000_xioctl_set_btcoex_colocated_bt_dev_cmd(struct net_device * dev, char * us erdata)
1063 {
1064 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1065 WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD cmd;
1066 int ret = 0;
1067
1068 if (ar->arWmiReady == FALSE) {
1069 return -EIO;
1070 }
1071
1072 if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
1073 return -EFAULT;
1074 }
1075
1076 if (wmi_set_btcoex_colocated_bt_dev_cmd(ar->arWmi, &cmd) == A_OK)
1077 {
1078 ret = 0;
1079 } else {
1080 ret = -EINVAL;
1081 }
1082
1083 return(ret);
1084 }
1085
1086 static int
1087 ar6000_xioctl_set_btcoex_btinquiry_page_config_cmd(struct net_device * dev, cha r * userdata)
1088 {
1089 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1090 WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD cmd;
1091 int ret = 0;
1092
1093 if (ar->arWmiReady == FALSE) {
1094 return -EIO;
1095 }
1096
1097 if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
1098 return -EFAULT;
1099 }
1100
1101 if (wmi_set_btcoex_btinquiry_page_config_cmd(ar->arWmi, &cmd) == A_OK)
1102 {
1103 ret = 0;
1104 } else {
1105 ret = -EINVAL;
1106 }
1107
1108 return(ret);
1109 }
1110
1111 static int
1112 ar6000_xioctl_set_btcoex_sco_config_cmd(struct net_device * dev, char * userdata )
1113 {
1114 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1115 WMI_SET_BTCOEX_SCO_CONFIG_CMD cmd;
1116 int ret = 0;
1117
1118 if (ar->arWmiReady == FALSE) {
1119 return -EIO;
1120 }
1121
1122 if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
1123 return -EFAULT;
1124 }
1125
1126 if (wmi_set_btcoex_sco_config_cmd(ar->arWmi, &cmd) == A_OK)
1127 {
1128 ret = 0;
1129 } else {
1130 ret = -EINVAL;
1131 }
1132
1133 return(ret);
1134 }
1135
1136 static int
1137 ar6000_xioctl_set_btcoex_a2dp_config_cmd(struct net_device * dev,
1138 char * userdata)
1139 {
1140 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1141 WMI_SET_BTCOEX_A2DP_CONFIG_CMD cmd;
1142 int ret = 0;
1143
1144 if (ar->arWmiReady == FALSE) {
1145 return -EIO;
1146 }
1147
1148 if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
1149 return -EFAULT;
1150 }
1151
1152 if (wmi_set_btcoex_a2dp_config_cmd(ar->arWmi, &cmd) == A_OK)
1153 {
1154 ret = 0;
1155 } else {
1156 ret = -EINVAL;
1157 }
1158
1159 return(ret);
1160 }
1161
1162 static int
1163 ar6000_xioctl_set_btcoex_aclcoex_config_cmd(struct net_device * dev, char * user data)
1164 {
1165 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1166 WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD cmd;
1167 int ret = 0;
1168
1169 if (ar->arWmiReady == FALSE) {
1170 return -EIO;
1171 }
1172
1173 if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
1174 return -EFAULT;
1175 }
1176
1177 if (wmi_set_btcoex_aclcoex_config_cmd(ar->arWmi, &cmd) == A_OK)
1178 {
1179 ret = 0;
1180 } else {
1181 ret = -EINVAL;
1182 }
1183
1184 return(ret);
1185 }
1186
1187 static int
1188 ar60000_xioctl_set_btcoex_debug_cmd(struct net_device * dev, char * userdata)
1189 {
1190 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1191 WMI_SET_BTCOEX_DEBUG_CMD cmd;
1192 int ret = 0;
1193
1194 if (ar->arWmiReady == FALSE) {
1195 return -EIO;
1196 }
1197
1198 if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
1199 return -EFAULT;
1200 }
1201
1202 if (wmi_set_btcoex_debug_cmd(ar->arWmi, &cmd) == A_OK)
1203 {
1204 ret = 0;
1205 } else {
1206 ret = -EINVAL;
1207 }
1208
1209 return(ret);
1210 }
1211
1212 static int
1213 ar6000_xioctl_set_btcoex_bt_operating_status_cmd(struct net_device * dev, char * userdata)
1214 {
1215 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1216 WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD cmd;
1217 int ret = 0;
1218
1219 if (ar->arWmiReady == FALSE) {
1220 return -EIO;
1221 }
1222
1223 if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
1224 return -EFAULT;
1225 }
1226
1227 if (wmi_set_btcoex_bt_operating_status_cmd(ar->arWmi, &cmd) == A_OK)
1228 {
1229 ret = 0;
1230 } else {
1231 ret = -EINVAL;
1232 }
1233 return(ret);
1234 }
1235
1236 static int
1237 ar6000_xioctl_get_btcoex_config_cmd(struct net_device * dev, char * userdata,
1238 struct ifreq *rq)
1239 {
1240
1241 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1242 AR6000_BTCOEX_CONFIG btcoexConfig;
1243 WMI_BTCOEX_CONFIG_EVENT *pbtcoexConfigEv = &ar->arBtcoexConfig;
1244
1245 int ret = 0;
1246
1247 if (ar->bIsDestroyProgress) {
1248 return -EBUSY;
1249 }
1250 if (ar->arWmiReady == FALSE) {
1251 return -EIO;
1252 }
1253 if (copy_from_user(&btcoexConfig.configCmd, userdata, sizeof(AR6000_BTCO EX_CONFIG))) {
1254 return -EFAULT;
1255 }
1256 if (down_interruptible(&ar->arSem)) {
1257 return -ERESTARTSYS;
1258 }
1259
1260 if (wmi_get_btcoex_config_cmd(ar->arWmi, (WMI_GET_BTCOEX_CONFIG_CMD *)&btcoe xConfig.configCmd) != A_OK)
1261 {
1262 up(&ar->arSem);
1263 return -EIO;
1264 }
1265
1266 ar->statsUpdatePending = TRUE;
1267
1268 wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == FALSE, w mitimeout * HZ);
1269
1270 if (signal_pending(current)) {
1271 ret = -EINTR;
1272 }
1273
1274 if (!ret && copy_to_user(btcoexConfig.configEvent, pbtcoexConfigEv, sizeof(W MI_BTCOEX_CONFIG_EVENT))) {
1275 ret = -EFAULT;
1276 }
1277 up(&ar->arSem);
1278 return ret;
1279 }
1280
1281 static int
1282 ar6000_xioctl_get_btcoex_stats_cmd(struct net_device * dev, char * userdata, str uct ifreq *rq)
1283 {
1284 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1285 AR6000_BTCOEX_STATS btcoexStats;
1286 WMI_BTCOEX_STATS_EVENT *pbtcoexStats = &ar->arBtcoexStats;
1287 int ret = 0;
1288
1289 if (ar->bIsDestroyProgress) {
1290 return -EBUSY;
1291 }
1292 if (ar->arWmiReady == FALSE) {
1293 return -EIO;
1294 }
1295
1296 if (down_interruptible(&ar->arSem)) {
1297 return -ERESTARTSYS;
1298 }
1299
1300 if (copy_from_user(&btcoexStats.statsEvent, userdata, sizeof(AR6000_BTCO EX_CONFIG))) {
1301 return -EFAULT;
1302 }
1303
1304 if (wmi_get_btcoex_stats_cmd(ar->arWmi) != A_OK)
1305 {
1306 up(&ar->arSem);
1307 return -EIO;
1308 }
1309
1310 ar->statsUpdatePending = TRUE;
1311
1312 wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == FALSE, w mitimeout * HZ);
1313
1314 if (signal_pending(current)) {
1315 ret = -EINTR;
1316 }
1317
1318 if (!ret && copy_to_user(btcoexStats.statsEvent, pbtcoexStats, sizeof(WMI_BT COEX_STATS_EVENT))) {
1319 ret = -EFAULT;
1320 }
1321
1322
1323 up(&ar->arSem);
1324
1325 return(ret);
1326 }
1327
1328
1329 #ifdef CONFIG_HOST_GPIO_SUPPORT
1330 struct ar6000_gpio_intr_wait_cmd_s gpio_intr_results;
1331 /* gpio_reg_results and gpio_data_available are protected by arSem */
1332 static struct ar6000_gpio_register_cmd_s gpio_reg_results;
1333 static A_BOOL gpio_data_available; /* Requested GPIO data available */
1334 static A_BOOL gpio_intr_available; /* GPIO interrupt info available */
1335 static A_BOOL gpio_ack_received; /* GPIO ack was received */
1336
1337 /* Host-side initialization for General Purpose I/O support */
1338 void ar6000_gpio_init(void)
1339 {
1340 gpio_intr_available = FALSE;
1341 gpio_data_available = FALSE;
1342 gpio_ack_received = FALSE;
1343 }
1344
1345 /*
1346 * Called when a GPIO interrupt is received from the Target.
1347 * intr_values shows which GPIO pins have interrupted.
1348 * input_values shows a recent value of GPIO pins.
1349 */
1350 void
1351 ar6000_gpio_intr_rx(A_UINT32 intr_mask, A_UINT32 input_values)
1352 {
1353 gpio_intr_results.intr_mask = intr_mask;
1354 gpio_intr_results.input_values = input_values;
1355 *((volatile A_BOOL *)&gpio_intr_available) = TRUE;
1356 wake_up(&arEvent);
1357 }
1358
1359 /*
1360 * This is called when a response is received from the Target
1361 * for a previous or ar6000_gpio_input_get or ar6000_gpio_register_get
1362 * call.
1363 */
1364 void
1365 ar6000_gpio_data_rx(A_UINT32 reg_id, A_UINT32 value)
1366 {
1367 gpio_reg_results.gpioreg_id = reg_id;
1368 gpio_reg_results.value = value;
1369 *((volatile A_BOOL *)&gpio_data_available) = TRUE;
1370 wake_up(&arEvent);
1371 }
1372
1373 /*
1374 * This is called when an acknowledgement is received from the Target
1375 * for a previous or ar6000_gpio_output_set or ar6000_gpio_register_set
1376 * call.
1377 */
1378 void
1379 ar6000_gpio_ack_rx(void)
1380 {
1381 gpio_ack_received = TRUE;
1382 wake_up(&arEvent);
1383 }
1384
1385 A_STATUS
1386 ar6000_gpio_output_set(struct net_device *dev,
1387 A_UINT32 set_mask,
1388 A_UINT32 clear_mask,
1389 A_UINT32 enable_mask,
1390 A_UINT32 disable_mask)
1391 {
1392 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1393
1394 gpio_ack_received = FALSE;
1395 return wmi_gpio_output_set(ar->arWmi,
1396 set_mask, clear_mask, enable_mask, disable_mask);
1397 }
1398
1399 static A_STATUS
1400 ar6000_gpio_input_get(struct net_device *dev)
1401 {
1402 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1403
1404 *((volatile A_BOOL *)&gpio_data_available) = FALSE;
1405 return wmi_gpio_input_get(ar->arWmi);
1406 }
1407
1408 static A_STATUS
1409 ar6000_gpio_register_set(struct net_device *dev,
1410 A_UINT32 gpioreg_id,
1411 A_UINT32 value)
1412 {
1413 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1414
1415 gpio_ack_received = FALSE;
1416 return wmi_gpio_register_set(ar->arWmi, gpioreg_id, value);
1417 }
1418
1419 static A_STATUS
1420 ar6000_gpio_register_get(struct net_device *dev,
1421 A_UINT32 gpioreg_id)
1422 {
1423 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1424
1425 *((volatile A_BOOL *)&gpio_data_available) = FALSE;
1426 return wmi_gpio_register_get(ar->arWmi, gpioreg_id);
1427 }
1428
1429 static A_STATUS
1430 ar6000_gpio_intr_ack(struct net_device *dev,
1431 A_UINT32 ack_mask)
1432 {
1433 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1434
1435 gpio_intr_available = FALSE;
1436 return wmi_gpio_intr_ack(ar->arWmi, ack_mask);
1437 }
1438 #endif /* CONFIG_HOST_GPIO_SUPPORT */
1439
1440 #if defined(CONFIG_TARGET_PROFILE_SUPPORT)
1441 static struct prof_count_s prof_count_results;
1442 static A_BOOL prof_count_available; /* Requested GPIO data available */
1443
1444 static A_STATUS
1445 prof_count_get(struct net_device *dev)
1446 {
1447 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1448
1449 *((volatile A_BOOL *)&prof_count_available) = FALSE;
1450 return wmi_prof_count_get_cmd(ar->arWmi);
1451 }
1452
1453 /*
1454 * This is called when a response is received from the Target
1455 * for a previous prof_count_get call.
1456 */
1457 void
1458 prof_count_rx(A_UINT32 addr, A_UINT32 count)
1459 {
1460 prof_count_results.addr = addr;
1461 prof_count_results.count = count;
1462 *((volatile A_BOOL *)&prof_count_available) = TRUE;
1463 wake_up(&arEvent);
1464 }
1465 #endif /* CONFIG_TARGET_PROFILE_SUPPORT */
1466
1467
1468 static A_STATUS
1469 ar6000_create_acl_data_osbuf(struct net_device *dev, A_UINT8 *userdata, void **p _osbuf)
1470 {
1471 void *osbuf = NULL;
1472 A_UINT8 tmp_space[8];
1473 HCI_ACL_DATA_PKT *acl;
1474 A_UINT8 hdr_size, *datap=NULL;
1475 A_STATUS ret = A_OK;
1476
1477 /* ACL is in data path. There is a need to create pool
1478 * mechanism for allocating and freeing NETBUFs - ToDo later.
1479 */
1480
1481 *p_osbuf = NULL;
1482 acl = (HCI_ACL_DATA_PKT *)tmp_space;
1483 hdr_size = sizeof(acl->hdl_and_flags) + sizeof(acl->data_len);
1484
1485 do {
1486 if (a_copy_from_user(acl, userdata, hdr_size)) {
1487 ret = A_EFAULT;
1488 break;
1489 }
1490
1491 osbuf = A_NETBUF_ALLOC(hdr_size + acl->data_len);
1492 if (osbuf == NULL) {
1493 ret = A_NO_MEMORY;
1494 break;
1495 }
1496 A_NETBUF_PUT(osbuf, hdr_size + acl->data_len);
1497 datap = (A_UINT8 *)A_NETBUF_DATA(osbuf);
1498
1499 /* Real copy to osbuf */
1500 acl = (HCI_ACL_DATA_PKT *)(datap);
1501 A_MEMCPY(acl, tmp_space, hdr_size);
1502 if (a_copy_from_user(acl->data, userdata + hdr_size, acl->data_len)) {
1503 ret = A_EFAULT;
1504 break;
1505 }
1506 } while(FALSE);
1507
1508 if (ret == A_OK) {
1509 *p_osbuf = osbuf;
1510 } else {
1511 A_NETBUF_FREE(osbuf);
1512 }
1513 return ret;
1514 }
1515
1516
1517
1518 int
1519 ar6000_ioctl_ap_setparam(AR_SOFTC_T *ar, int param, int value)
1520 {
1521 int ret=0;
1522
1523 switch(param) {
1524 case IEEE80211_PARAM_WPA:
1525 switch (value) {
1526 case WPA_MODE_WPA1:
1527 ar->arAuthMode = WPA_AUTH;
1528 break;
1529 case WPA_MODE_WPA2:
1530 ar->arAuthMode = WPA2_AUTH;
1531 break;
1532 case WPA_MODE_AUTO:
1533 ar->arAuthMode = WPA_AUTH | WPA2_AUTH;
1534 break;
1535 case WPA_MODE_NONE:
1536 ar->arAuthMode = NONE_AUTH;
1537 break;
1538 }
1539 break;
1540 case IEEE80211_PARAM_AUTHMODE:
1541 if(value == IEEE80211_AUTH_WPA_PSK) {
1542 if (WPA_AUTH == ar->arAuthMode) {
1543 ar->arAuthMode = WPA_PSK_AUTH;
1544 } else if (WPA2_AUTH == ar->arAuthMode) {
1545 ar->arAuthMode = WPA2_PSK_AUTH;
1546 } else if ((WPA_AUTH | WPA2_AUTH) == ar->arAuthMode) {
1547 ar->arAuthMode = WPA_PSK_AUTH | WPA2_PSK_AUTH;
1548 } else {
1549 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Error - Setting PSK "\
1550 "mode when WPA param was set to %d\n",
1551 ar->arAuthMode));
1552 ret = -EIO;
1553 }
1554 }
1555 break;
1556 case IEEE80211_PARAM_UCASTCIPHER:
1557 ar->arPairwiseCrypto = 0;
1558 if(value & (1<<IEEE80211_CIPHER_AES_CCM)) {
1559 ar->arPairwiseCrypto |= AES_CRYPT;
1560 }
1561 if(value & (1<<IEEE80211_CIPHER_TKIP)) {
1562 ar->arPairwiseCrypto |= TKIP_CRYPT;
1563 }
1564 if(!ar->arPairwiseCrypto) {
1565 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1566 ("Error - Invalid cipher in WPA \n"));
1567 ret = -EIO;
1568 }
1569 break;
1570 case IEEE80211_PARAM_PRIVACY:
1571 if(value == 0) {
1572 ar->arDot11AuthMode = OPEN_AUTH;
1573 ar->arAuthMode = NONE_AUTH;
1574 ar->arPairwiseCrypto = NONE_CRYPT;
1575 ar->arPairwiseCryptoLen = 0;
1576 ar->arGroupCrypto = NONE_CRYPT;
1577 ar->arGroupCryptoLen = 0;
1578 }
1579 break;
1580 #ifdef WAPI_ENABLE
1581 case IEEE80211_PARAM_WAPI:
1582 A_PRINTF("WAPI Policy: %d\n", value);
1583 ar->arDot11AuthMode = OPEN_AUTH;
1584 ar->arAuthMode = NONE_AUTH;
1585 if(value & 0x1) {
1586 ar->arPairwiseCrypto = WAPI_CRYPT;
1587 ar->arGroupCrypto = WAPI_CRYPT;
1588 } else {
1589 ar->arPairwiseCrypto = NONE_CRYPT;
1590 ar->arGroupCrypto = NONE_CRYPT;
1591 }
1592 break;
1593 #endif
1594 }
1595 return ret;
1596 }
1597
1598 int
1599 ar6000_ioctl_setparam(AR_SOFTC_T *ar, int param, int value)
1600 {
1601 A_BOOL profChanged = FALSE;
1602 int ret=0;
1603
1604 if(ar->arNextMode == AP_NETWORK) {
1605 ar->ap_profile_flag = 1; /* There is a change in profile */
1606 switch (param) {
1607 case IEEE80211_PARAM_WPA:
1608 case IEEE80211_PARAM_AUTHMODE:
1609 case IEEE80211_PARAM_UCASTCIPHER:
1610 case IEEE80211_PARAM_PRIVACY:
1611 case IEEE80211_PARAM_WAPI:
1612 ret = ar6000_ioctl_ap_setparam(ar, param, value);
1613 return ret;
1614 }
1615 }
1616
1617 switch (param) {
1618 case IEEE80211_PARAM_WPA:
1619 switch (value) {
1620 case WPA_MODE_WPA1:
1621 ar->arAuthMode = WPA_AUTH;
1622 profChanged = TRUE;
1623 break;
1624 case WPA_MODE_WPA2:
1625 ar->arAuthMode = WPA2_AUTH;
1626 profChanged = TRUE;
1627 break;
1628 case WPA_MODE_NONE:
1629 ar->arAuthMode = NONE_AUTH;
1630 profChanged = TRUE;
1631 break;
1632 }
1633 break;
1634 case IEEE80211_PARAM_AUTHMODE:
1635 switch(value) {
1636 case IEEE80211_AUTH_WPA_PSK:
1637 if (WPA_AUTH == ar->arAuthMode) {
1638 ar->arAuthMode = WPA_PSK_AUTH;
1639 profChanged = TRUE;
1640 } else if (WPA2_AUTH == ar->arAuthMode) {
1641 ar->arAuthMode = WPA2_PSK_AUTH;
1642 profChanged = TRUE;
1643 } else {
1644 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Error - Setting PSK "\
1645 "mode when WPA param was set to %d\n",
1646 ar->arAuthMode));
1647 ret = -EIO;
1648 }
1649 break;
1650 case IEEE80211_AUTH_WPA_CCKM:
1651 if (WPA2_AUTH == ar->arAuthMode) {
1652 ar->arAuthMode = WPA2_AUTH_CCKM;
1653 } else {
1654 ar->arAuthMode = WPA_AUTH_CCKM;
1655 }
1656 break;
1657 default:
1658 break;
1659 }
1660 break;
1661 case IEEE80211_PARAM_UCASTCIPHER:
1662 switch (value) {
1663 case IEEE80211_CIPHER_AES_CCM:
1664 ar->arPairwiseCrypto = AES_CRYPT;
1665 profChanged = TRUE;
1666 break;
1667 case IEEE80211_CIPHER_TKIP:
1668 ar->arPairwiseCrypto = TKIP_CRYPT;
1669 profChanged = TRUE;
1670 break;
1671 case IEEE80211_CIPHER_WEP:
1672 ar->arPairwiseCrypto = WEP_CRYPT;
1673 profChanged = TRUE;
1674 break;
1675 case IEEE80211_CIPHER_NONE:
1676 ar->arPairwiseCrypto = NONE_CRYPT;
1677 profChanged = TRUE;
1678 break;
1679 }
1680 break;
1681 case IEEE80211_PARAM_UCASTKEYLEN:
1682 if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(value)) {
1683 ret = -EIO;
1684 } else {
1685 ar->arPairwiseCryptoLen = value;
1686 }
1687 break;
1688 case IEEE80211_PARAM_MCASTCIPHER:
1689 switch (value) {
1690 case IEEE80211_CIPHER_AES_CCM:
1691 ar->arGroupCrypto = AES_CRYPT;
1692 profChanged = TRUE;
1693 break;
1694 case IEEE80211_CIPHER_TKIP:
1695 ar->arGroupCrypto = TKIP_CRYPT;
1696 profChanged = TRUE;
1697 break;
1698 case IEEE80211_CIPHER_WEP:
1699 ar->arGroupCrypto = WEP_CRYPT;
1700 profChanged = TRUE;
1701 break;
1702 case IEEE80211_CIPHER_NONE:
1703 ar->arGroupCrypto = NONE_CRYPT;
1704 profChanged = TRUE;
1705 break;
1706 }
1707 break;
1708 case IEEE80211_PARAM_MCASTKEYLEN:
1709 if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(value)) {
1710 ret = -EIO;
1711 } else {
1712 ar->arGroupCryptoLen = value;
1713 }
1714 break;
1715 case IEEE80211_PARAM_COUNTERMEASURES:
1716 if (ar->arWmiReady == FALSE) {
1717 return -EIO;
1718 }
1719 wmi_set_tkip_countermeasures_cmd(ar->arWmi, value);
1720 break;
1721 default:
1722 break;
1723 }
1724 if ((ar->arNextMode != AP_NETWORK) && (profChanged == TRUE)) {
1725 /*
1726 * profile has changed. Erase ssid to signal change
1727 */
1728 A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
1729 }
1730
1731 return ret;
1732 }
1733
1734 int
1735 ar6000_ioctl_setkey(AR_SOFTC_T *ar, struct ieee80211req_key *ik)
1736 {
1737 KEY_USAGE keyUsage;
1738 A_STATUS status;
1739 CRYPTO_TYPE keyType = NONE_CRYPT;
1740
1741 #ifdef USER_KEYS
1742 ar->user_saved_keys.keyOk = FALSE;
1743 #endif
1744 if ( (0 == memcmp(ik->ik_macaddr, null_mac, IEEE80211_ADDR_LEN)) ||
1745 (0 == memcmp(ik->ik_macaddr, bcast_mac, IEEE80211_ADDR_LEN)) ) {
1746 keyUsage = GROUP_USAGE;
1747 if(ar->arNextMode == AP_NETWORK) {
1748 A_MEMCPY(&ar->ap_mode_bkey, ik,
1749 sizeof(struct ieee80211req_key));
1750 #ifdef WAPI_ENABLE
1751 if(ar->arPairwiseCrypto == WAPI_CRYPT) {
1752 return ap_set_wapi_key(ar, ik);
1753 }
1754 #endif
1755 }
1756 #ifdef USER_KEYS
1757 A_MEMCPY(&ar->user_saved_keys.bcast_ik, ik,
1758 sizeof(struct ieee80211req_key));
1759 #endif
1760 } else {
1761 keyUsage = PAIRWISE_USAGE;
1762 #ifdef USER_KEYS
1763 A_MEMCPY(&ar->user_saved_keys.ucast_ik, ik,
1764 sizeof(struct ieee80211req_key));
1765 #endif
1766 #ifdef WAPI_ENABLE
1767 if(ar->arNextMode == AP_NETWORK) {
1768 if(ar->arPairwiseCrypto == WAPI_CRYPT) {
1769 return ap_set_wapi_key(ar, ik);
1770 }
1771 }
1772 #endif
1773 }
1774
1775 switch (ik->ik_type) {
1776 case IEEE80211_CIPHER_WEP:
1777 keyType = WEP_CRYPT;
1778 break;
1779 case IEEE80211_CIPHER_TKIP:
1780 keyType = TKIP_CRYPT;
1781 break;
1782 case IEEE80211_CIPHER_AES_CCM:
1783 keyType = AES_CRYPT;
1784 break;
1785 default:
1786 break;
1787 }
1788 #ifdef USER_KEYS
1789 ar->user_saved_keys.keyType = keyType;
1790 #endif
1791 if (IEEE80211_CIPHER_CCKM_KRK != ik->ik_type) {
1792 if (NONE_CRYPT == keyType) {
1793 return -EIO;
1794 }
1795
1796 if (WEP_CRYPT == keyType) {
1797 int index = ik->ik_keyix;
1798
1799 if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(ik->ik_keylen)) {
1800 return -EIO;
1801 }
1802
1803 A_MEMZERO(ar->arWepKeyList[index].arKey,
1804 sizeof(ar->arWepKeyList[index].arKey));
1805 A_MEMCPY(ar->arWepKeyList[index].arKey, ik->ik_keydata, ik->ik_keyle n);
1806 ar->arWepKeyList[index].arKeyLen = ik->ik_keylen;
1807
1808 if(ik->ik_flags & IEEE80211_KEY_DEFAULT){
1809 ar->arDefTxKeyIndex = index;
1810 }
1811
1812 return 0;
1813 }
1814
1815 if (((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMod e)) &&
1816 (GROUP_USAGE & keyUsage))
1817 {
1818 A_UNTIMEOUT(&ar->disconnect_timer);
1819 }
1820
1821 status = wmi_addKey_cmd(ar->arWmi, ik->ik_keyix, keyType, keyUsage,
1822 ik->ik_keylen, (A_UINT8 *)&ik->ik_keyrsc,
1823 ik->ik_keydata, KEY_OP_INIT_VAL, ik->ik_macaddr,
1824 SYNC_BOTH_WMIFLAG);
1825
1826 if (status != A_OK) {
1827 return -EIO;
1828 }
1829 } else {
1830 status = wmi_add_krk_cmd(ar->arWmi, ik->ik_keydata);
1831 }
1832
1833 #ifdef USER_KEYS
1834 ar->user_saved_keys.keyOk = TRUE;
1835 #endif
1836
1837 return 0;
1838 }
1839
1840 int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
1841 {
1842 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1843 HIF_DEVICE *hifDevice = ar->arHifDevice;
1844 int ret, param;
1845 unsigned int address = 0;
1846 unsigned int length = 0;
1847 unsigned char *buffer;
1848 char *userdata;
1849 A_UINT32 connectCtrlFlags;
1850
1851
1852 static WMI_SCAN_PARAMS_CMD scParams = {0, 0, 0, 0, 0,
1853 WMI_SHORTSCANRATIO_DEFAULT,
1854 DEFAULT_SCAN_CTRL_FLAGS,
1855 0};
1856 WMI_SET_AKMP_PARAMS_CMD akmpParams;
1857 WMI_SET_PMKID_LIST_CMD pmkidInfo;
1858
1859 static WMI_SET_HT_CAP_CMD htCap;
1860 static WMI_SET_HT_OP_CMD htOp;
1861
1862 if (cmd == AR6000_IOCTL_EXTENDED) {
1863 /*
1864 * This allows for many more wireless ioctls than would otherwise
1865 * be available. Applications embed the actual ioctl command in
1866 * the first word of the parameter block, and use the command
1867 * AR6000_IOCTL_EXTENDED_CMD on the ioctl call.
1868 */
1869 get_user(cmd, (int *)rq->ifr_data);
1870 userdata = (char *)(((unsigned int *)rq->ifr_data)+1);
1871 if(is_xioctl_allowed(ar->arNextMode, cmd) != A_OK) {
1872 A_PRINTF("xioctl: cmd=%d not allowed in this mode\n",cmd);
1873 return -EOPNOTSUPP;
1874 }
1875 } else {
1876 A_STATUS ret = is_iwioctl_allowed(ar->arNextMode, cmd);
1877 if(ret == A_ENOTSUP) {
1878 A_PRINTF("iwioctl: cmd=0x%x not allowed in this mode\n", cmd);
1879 return -EOPNOTSUPP;
1880 } else if (ret == A_ERROR) {
1881 /* It is not our ioctl (out of range ioctl) */
1882 return -EOPNOTSUPP;
1883 }
1884 userdata = (char *)rq->ifr_data;
1885 }
1886
1887 if ((ar->arWlanState == WLAN_DISABLED) &&
1888 ((cmd != AR6000_XIOCTRL_WMI_SET_WLAN_STATE) &&
1889 (cmd != AR6000_XIOCTL_DIAG_READ) &&
1890 (cmd != AR6000_XIOCTL_DIAG_WRITE)))
1891 {
1892 return -EIO;
1893 }
1894
1895 ret = 0;
1896 switch(cmd)
1897 {
1898 case IEEE80211_IOCTL_SETPARAM:
1899 {
1900 int param, value;
1901 int *ptr = (int *)rq->ifr_ifru.ifru_newname;
1902 if (ar->arWmiReady == FALSE) {
1903 ret = -EIO;
1904 } else {
1905 param = *ptr++;
1906 value = *ptr;
1907 ret = ar6000_ioctl_setparam(ar,param,value);
1908 }
1909 break;
1910 }
1911 case IEEE80211_IOCTL_SETKEY:
1912 {
1913 struct ieee80211req_key keydata;
1914 if (ar->arWmiReady == FALSE) {
1915 ret = -EIO;
1916 } else if (copy_from_user(&keydata, userdata,
1917 sizeof(struct ieee80211req_key))) {
1918 ret = -EFAULT;
1919 } else {
1920 ar6000_ioctl_setkey(ar, &keydata);
1921 }
1922 break;
1923 }
1924 case IEEE80211_IOCTL_DELKEY:
1925 case IEEE80211_IOCTL_SETOPTIE:
1926 {
1927 //ret = -EIO;
1928 break;
1929 }
1930 case IEEE80211_IOCTL_SETMLME:
1931 {
1932 struct ieee80211req_mlme mlme;
1933 if (ar->arWmiReady == FALSE) {
1934 ret = -EIO;
1935 } else if (copy_from_user(&mlme, userdata,
1936 sizeof(struct ieee80211req_mlme))) {
1937 ret = -EFAULT;
1938 } else {
1939 switch (mlme.im_op) {
1940 case IEEE80211_MLME_AUTHORIZE:
1941 A_PRINTF("setmlme AUTHORIZE %02X:%02X\n",
1942 mlme.im_macaddr[4], mlme.im_macaddr[5]);
1943 break;
1944 case IEEE80211_MLME_UNAUTHORIZE:
1945 A_PRINTF("setmlme UNAUTHORIZE %02X:%02X\n",
1946 mlme.im_macaddr[4], mlme.im_macaddr[5]);
1947 break;
1948 case IEEE80211_MLME_DEAUTH:
1949 A_PRINTF("setmlme DEAUTH %02X:%02X\n",
1950 mlme.im_macaddr[4], mlme.im_macaddr[5]);
1951 //remove_sta(ar, mlme.im_macaddr);
1952 break;
1953 case IEEE80211_MLME_DISASSOC:
1954 A_PRINTF("setmlme DISASSOC %02X:%02X\n",
1955 mlme.im_macaddr[4], mlme.im_macaddr[5]);
1956 //remove_sta(ar, mlme.im_macaddr);
1957 break;
1958 default:
1959 return 0;
1960 }
1961
1962 wmi_ap_set_mlme(ar->arWmi, mlme.im_op, mlme.im_macaddr,
1963 mlme.im_reason);
1964 }
1965 break;
1966 }
1967 case IEEE80211_IOCTL_ADDPMKID:
1968 {
1969 struct ieee80211req_addpmkid req;
1970 if (ar->arWmiReady == FALSE) {
1971 ret = -EIO;
1972 } else if (copy_from_user(&req, userdata, sizeof(struct ieee80211req _addpmkid))) {
1973 ret = -EFAULT;
1974 } else {
1975 A_STATUS status;
1976
1977 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("Add pmkid for %2.2x:%2. 2x:%2.2x:%2.2x:%2.2x:%2.2x en=%d\n",
1978 req.pi_bssid[0], req.pi_bssid[1], req.pi_bssid[2],
1979 req.pi_bssid[3], req.pi_bssid[4], req.pi_bssid[5],
1980 req.pi_enable));
1981
1982 status = wmi_setPmkid_cmd(ar->arWmi, req.pi_bssid, req.pi_pmkid,
1983 req.pi_enable);
1984
1985 if (status != A_OK) {
1986 return -EIO;
1987 }
1988 }
1989 break;
1990 }
1991 #ifdef CONFIG_HOST_TCMD_SUPPORT
1992 case AR6000_XIOCTL_TCMD_CONT_TX:
1993 {
1994 TCMD_CONT_TX txCmd;
1995
1996 if (ar->tcmdPm == TCMD_PM_SLEEP) {
1997 A_PRINTF("Can NOT send tx tcmd when target is asleep! \n");
1998 return -EFAULT;
1999 }
2000
2001 if(copy_from_user(&txCmd, userdata, sizeof(TCMD_CONT_TX)))
2002 return -EFAULT;
2003 wmi_test_cmd(ar->arWmi,(A_UINT8 *)&txCmd, sizeof(TCMD_CONT_TX));
2004 }
2005 break;
2006 case AR6000_XIOCTL_TCMD_CONT_RX:
2007 {
2008 TCMD_CONT_RX rxCmd;
2009
2010 if (ar->tcmdPm == TCMD_PM_SLEEP) {
2011 A_PRINTF("Can NOT send rx tcmd when target is asleep! \n");
2012 return -EFAULT;
2013 }
2014 if(copy_from_user(&rxCmd, userdata, sizeof(TCMD_CONT_RX)))
2015 return -EFAULT;
2016 switch(rxCmd.act)
2017 {
2018 case TCMD_CONT_RX_PROMIS:
2019 case TCMD_CONT_RX_FILTER:
2020 case TCMD_CONT_RX_SETMAC:
2021 case TCMD_CONT_RX_SET_ANT_SWITCH_TABLE:
2022 wmi_test_cmd(ar->arWmi,(A_UINT8 *)&rxCmd,
2023 sizeof(TCMD_CONT_RX));
2024 tcmdRxFreq = rxCmd.u.para.freq;
2025 break;
2026 case TCMD_CONT_RX_REPORT:
2027 ar6000_ioctl_tcmd_get_rx_report(dev, rq,
2028 (A_UINT8 *)&rxCmd, sizeof(TCMD_CONT_RX));
2029 break;
2030 default:
2031 A_PRINTF("Unknown Cont Rx mode: %d\n",rxCmd.act);
2032 return -EINVAL;
2033 }
2034 }
2035 break;
2036 case AR6000_XIOCTL_TCMD_PM:
2037 {
2038 TCMD_PM pmCmd;
2039
2040 if(copy_from_user(&pmCmd, userdata, sizeof(TCMD_PM)))
2041 return -EFAULT;
2042 ar->tcmdPm = pmCmd.mode;
2043 wmi_test_cmd(ar->arWmi, (A_UINT8*)&pmCmd, sizeof(TCMD_PM));
2044 }
2045 break;
2046 #endif /* CONFIG_HOST_TCMD_SUPPORT */
2047
2048 case AR6000_XIOCTL_BMI_DONE:
2049 if(bmienable)
2050 {
2051 ret = ar6000_init(dev);
2052 }
2053 else
2054 {
2055 ret = BMIDone(hifDevice);
2056 }
2057 break;
2058
2059 case AR6000_XIOCTL_BMI_READ_MEMORY:
2060 get_user(address, (unsigned int *)userdata);
2061 get_user(length, (unsigned int *)userdata + 1);
2062 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Read Memory (address: 0x%x, length: %d)\n",
2063 address, length));
2064 if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) {
2065 A_MEMZERO(buffer, length);
2066 ret = BMIReadMemory(hifDevice, address, buffer, length);
2067 if (copy_to_user(rq->ifr_data, buffer, length)) {
2068 ret = -EFAULT;
2069 }
2070 A_FREE(buffer);
2071 } else {
2072 ret = -ENOMEM;
2073 }
2074 break;
2075
2076 case AR6000_XIOCTL_BMI_WRITE_MEMORY:
2077 get_user(address, (unsigned int *)userdata);
2078 get_user(length, (unsigned int *)userdata + 1);
2079 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Write Memory (address: 0x%x, length : %d)\n",
2080 address, length));
2081 if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) {
2082 A_MEMZERO(buffer, length);
2083 if (copy_from_user(buffer, &userdata[sizeof(address) +
2084 sizeof(length)], length))
2085 {
2086 ret = -EFAULT;
2087 } else {
2088 ret = BMIWriteMemory(hifDevice, address, buffer, length);
2089 }
2090 A_FREE(buffer);
2091 } else {
2092 ret = -ENOMEM;
2093 }
2094 break;
2095
2096 case AR6000_XIOCTL_BMI_TEST:
2097 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("No longer supported\n"));
2098 ret = -EOPNOTSUPP;
2099 break;
2100
2101 case AR6000_XIOCTL_BMI_EXECUTE:
2102 get_user(address, (unsigned int *)userdata);
2103 get_user(param, (unsigned int *)userdata + 1);
2104 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Execute (address: 0x%x, param: %d)\ n",
2105 address, param));
2106 ret = BMIExecute(hifDevice, address, &param);
2107 put_user(param, (unsigned int *)rq->ifr_data); /* return value */
2108 break;
2109
2110 case AR6000_XIOCTL_BMI_SET_APP_START:
2111 get_user(address, (unsigned int *)userdata);
2112 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Set App Start (address: 0x%x)\n", a ddress));
2113 ret = BMISetAppStart(hifDevice, address);
2114 break;
2115
2116 case AR6000_XIOCTL_BMI_READ_SOC_REGISTER:
2117 get_user(address, (unsigned int *)userdata);
2118 ret = BMIReadSOCRegister(hifDevice, address, &param);
2119 put_user(param, (unsigned int *)rq->ifr_data); /* return value */
2120 break;
2121
2122 case AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER:
2123 get_user(address, (unsigned int *)userdata);
2124 get_user(param, (unsigned int *)userdata + 1);
2125 ret = BMIWriteSOCRegister(hifDevice, address, param);
2126 break;
2127
2128 #ifdef HTC_RAW_INTERFACE
2129 case AR6000_XIOCTL_HTC_RAW_OPEN:
2130 ret = A_OK;
2131 if (!arRawIfEnabled(ar)) {
2132 /* make sure block size is set in case the target was reset sinc e last
2133 * BMI phase (i.e. flashup downloads) */
2134 ret = ar6000_set_htc_params(ar->arHifDevice,
2135 ar->arTargetType,
2136 0, /* use default yield */
2137 0 /* use default number of HTC ctr l buffers */
2138 );
2139 if (A_FAILED(ret)) {
2140 break;
2141 }
2142 /* Terminate the BMI phase */
2143 ret = BMIDone(hifDevice);
2144 if (ret == A_OK) {
2145 ret = ar6000_htc_raw_open(ar);
2146 }
2147 }
2148 break;
2149
2150 case AR6000_XIOCTL_HTC_RAW_CLOSE:
2151 if (arRawIfEnabled(ar)) {
2152 ret = ar6000_htc_raw_close(ar);
2153 arRawIfEnabled(ar) = FALSE;
2154 } else {
2155 ret = A_ERROR;
2156 }
2157 break;
2158
2159 case AR6000_XIOCTL_HTC_RAW_READ:
2160 if (arRawIfEnabled(ar)) {
2161 unsigned int streamID;
2162 get_user(streamID, (unsigned int *)userdata);
2163 get_user(length, (unsigned int *)userdata + 1);
2164 buffer = rq->ifr_data + sizeof(length);
2165 ret = ar6000_htc_raw_read(ar, (HTC_RAW_STREAM_ID)streamID,
2166 buffer, length);
2167 put_user(ret, (unsigned int *)rq->ifr_data);
2168 } else {
2169 ret = A_ERROR;
2170 }
2171 break;
2172
2173 case AR6000_XIOCTL_HTC_RAW_WRITE:
2174 if (arRawIfEnabled(ar)) {
2175 unsigned int streamID;
2176 get_user(streamID, (unsigned int *)userdata);
2177 get_user(length, (unsigned int *)userdata + 1);
2178 buffer = userdata + sizeof(streamID) + sizeof(length);
2179 ret = ar6000_htc_raw_write(ar, (HTC_RAW_STREAM_ID)streamID,
2180 buffer, length);
2181 put_user(ret, (unsigned int *)rq->ifr_data);
2182 } else {
2183 ret = A_ERROR;
2184 }
2185 break;
2186 #endif /* HTC_RAW_INTERFACE */
2187
2188 case AR6000_XIOCTL_BMI_LZ_STREAM_START:
2189 get_user(address, (unsigned int *)userdata);
2190 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Start Compressed Stream (address: 0 x%x)\n", address));
2191 ret = BMILZStreamStart(hifDevice, address);
2192 break;
2193
2194 case AR6000_XIOCTL_BMI_LZ_DATA:
2195 get_user(length, (unsigned int *)userdata);
2196 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Send Compressed Data (length: %d)\n ", length));
2197 if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) {
2198 A_MEMZERO(buffer, length);
2199 if (copy_from_user(buffer, &userdata[sizeof(length)], length))
2200 {
2201 ret = -EFAULT;
2202 } else {
2203 ret = BMILZData(hifDevice, buffer, length);
2204 }
2205 A_FREE(buffer);
2206 } else {
2207 ret = -ENOMEM;
2208 }
2209 break;
2210
2211 #if defined(CONFIG_TARGET_PROFILE_SUPPORT)
2212 /*
2213 * Optional support for Target-side profiling.
2214 * Not needed in production.
2215 */
2216
2217 /* Configure Target-side profiling */
2218 case AR6000_XIOCTL_PROF_CFG:
2219 {
2220 A_UINT32 period;
2221 A_UINT32 nbins;
2222 get_user(period, (unsigned int *)userdata);
2223 get_user(nbins, (unsigned int *)userdata + 1);
2224
2225 if (wmi_prof_cfg_cmd(ar->arWmi, period, nbins) != A_OK) {
2226 ret = -EIO;
2227 }
2228
2229 break;
2230 }
2231
2232 /* Start a profiling bucket/bin at the specified address */
2233 case AR6000_XIOCTL_PROF_ADDR_SET:
2234 {
2235 A_UINT32 addr;
2236 get_user(addr, (unsigned int *)userdata);
2237
2238 if (wmi_prof_addr_set_cmd(ar->arWmi, addr) != A_OK) {
2239 ret = -EIO;
2240 }
2241
2242 break;
2243 }
2244
2245 /* START Target-side profiling */
2246 case AR6000_XIOCTL_PROF_START:
2247 wmi_prof_start_cmd(ar->arWmi);
2248 break;
2249
2250 /* STOP Target-side profiling */
2251 case AR6000_XIOCTL_PROF_STOP:
2252 wmi_prof_stop_cmd(ar->arWmi);
2253 break;
2254 case AR6000_XIOCTL_PROF_COUNT_GET:
2255 {
2256 if (ar->bIsDestroyProgress) {
2257 return -EBUSY;
2258 }
2259 if (ar->arWmiReady == FALSE) {
2260 return -EIO;
2261 }
2262 if (down_interruptible(&ar->arSem)) {
2263 return -ERESTARTSYS;
2264 }
2265 if (ar->bIsDestroyProgress) {
2266 up(&ar->arSem);
2267 return -EBUSY;
2268 }
2269
2270 prof_count_available = FALSE;
2271 ret = prof_count_get(dev);
2272 if (ret != A_OK) {
2273 up(&ar->arSem);
2274 return -EIO;
2275 }
2276
2277 /* Wait for Target to respond. */
2278 wait_event_interruptible(arEvent, prof_count_available);
2279 if (signal_pending(current)) {
2280 ret = -EINTR;
2281 } else {
2282 if (copy_to_user(userdata, &prof_count_results,
2283 sizeof(prof_count_results)))
2284 {
2285 ret = -EFAULT;
2286 }
2287 }
2288 up(&ar->arSem);
2289 break;
2290 }
2291 #endif /* CONFIG_TARGET_PROFILE_SUPPORT */
2292
2293 case AR6000_IOCTL_WMI_GETREV:
2294 {
2295 if (copy_to_user(rq->ifr_data, &ar->arVersion,
2296 sizeof(ar->arVersion)))
2297 {
2298 ret = -EFAULT;
2299 }
2300 break;
2301 }
2302 case AR6000_IOCTL_WMI_SETPWR:
2303 {
2304 WMI_POWER_MODE_CMD pwrModeCmd;
2305
2306 if (ar->arWmiReady == FALSE) {
2307 ret = -EIO;
2308 } else if (copy_from_user(&pwrModeCmd, userdata,
2309 sizeof(pwrModeCmd)))
2310 {
2311 ret = -EFAULT;
2312 } else {
2313 if (wmi_powermode_cmd(ar->arWmi, pwrModeCmd.powerMode)
2314 != A_OK)
2315 {
2316 ret = -EIO;
2317 }
2318 }
2319 break;
2320 }
2321 case AR6000_IOCTL_WMI_SET_IBSS_PM_CAPS:
2322 {
2323 WMI_IBSS_PM_CAPS_CMD ibssPmCaps;
2324
2325 if (ar->arWmiReady == FALSE) {
2326 ret = -EIO;
2327 } else if (copy_from_user(&ibssPmCaps, userdata,
2328 sizeof(ibssPmCaps)))
2329 {
2330 ret = -EFAULT;
2331 } else {
2332 if (wmi_ibsspmcaps_cmd(ar->arWmi, ibssPmCaps.power_saving, ibssP mCaps.ttl,
2333 ibssPmCaps.atim_windows, ibssPmCaps.timeout_value) != A_OK)
2334 {
2335 ret = -EIO;
2336 }
2337 AR6000_SPIN_LOCK(&ar->arLock, 0);
2338 ar->arIbssPsEnable = ibssPmCaps.power_saving;
2339 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
2340 }
2341 break;
2342 }
2343 case AR6000_XIOCTL_WMI_SET_AP_PS:
2344 {
2345 WMI_AP_PS_CMD apPsCmd;
2346
2347 if (ar->arWmiReady == FALSE) {
2348 ret = -EIO;
2349 } else if (copy_from_user(&apPsCmd, userdata,
2350 sizeof(apPsCmd)))
2351 {
2352 ret = -EFAULT;
2353 } else {
2354 if (wmi_apps_cmd(ar->arWmi, apPsCmd.psType, apPsCmd.idle_time,
2355 apPsCmd.ps_period, apPsCmd.sleep_period) != A_OK)
2356 {
2357 ret = -EIO;
2358 }
2359 }
2360 break;
2361 }
2362 case AR6000_IOCTL_WMI_SET_PMPARAMS:
2363 {
2364 WMI_POWER_PARAMS_CMD pmParams;
2365
2366 if (ar->arWmiReady == FALSE) {
2367 ret = -EIO;
2368 } else if (copy_from_user(&pmParams, userdata,
2369 sizeof(pmParams)))
2370 {
2371 ret = -EFAULT;
2372 } else {
2373 if (wmi_pmparams_cmd(ar->arWmi, pmParams.idle_period,
2374 pmParams.pspoll_number,
2375 pmParams.dtim_policy,
2376 pmParams.tx_wakeup_policy,
2377 pmParams.num_tx_to_wakeup,
2378 SEND_POWER_SAVE_FAIL_EVENT_ALWAYS
2379 ) != A_OK)
2380 {
2381 ret = -EIO;
2382 }
2383 }
2384 break;
2385 }
2386 case AR6000_IOCTL_WMI_SETSCAN:
2387 {
2388 if (ar->arWmiReady == FALSE) {
2389 ret = -EIO;
2390 } else if (copy_from_user(&scParams, userdata,
2391 sizeof(scParams)))
2392 {
2393 ret = -EFAULT;
2394 } else {
2395 if (CAN_SCAN_IN_CONNECT(scParams.scanCtrlFlags)) {
2396 ar->arSkipScan = FALSE;
2397 } else {
2398 ar->arSkipScan = TRUE;
2399 }
2400
2401 if (wmi_scanparams_cmd(ar->arWmi, scParams.fg_start_period,
2402 scParams.fg_end_period,
2403 scParams.bg_period,
2404 scParams.minact_chdwell_time,
2405 scParams.maxact_chdwell_time,
2406 scParams.pas_chdwell_time,
2407 scParams.shortScanRatio,
2408 scParams.scanCtrlFlags,
2409 scParams.max_dfsch_act_time,
2410 scParams.maxact_scan_per_ssid) != A_OK)
2411 {
2412 ret = -EIO;
2413 }
2414 }
2415 break;
2416 }
2417 case AR6000_IOCTL_WMI_SETLISTENINT:
2418 {
2419 WMI_LISTEN_INT_CMD listenCmd;
2420
2421 if (ar->arWmiReady == FALSE) {
2422 ret = -EIO;
2423 } else if (copy_from_user(&listenCmd, userdata,
2424 sizeof(listenCmd)))
2425 {
2426 ret = -EFAULT;
2427 } else {
2428 if (wmi_listeninterval_cmd(ar->arWmi, listenCmd.listenInterv al, listenCmd.numBeacons) != A_OK) {
2429 ret = -EIO;
2430 } else {
2431 AR6000_SPIN_LOCK(&ar->arLock, 0);
2432 ar->arListenInterval = param;
2433 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
2434 }
2435
2436 }
2437 break;
2438 }
2439 case AR6000_IOCTL_WMI_SET_BMISS_TIME:
2440 {
2441 WMI_BMISS_TIME_CMD bmissCmd;
2442
2443 if (ar->arWmiReady == FALSE) {
2444 ret = -EIO;
2445 } else if (copy_from_user(&bmissCmd, userdata,
2446 sizeof(bmissCmd)))
2447 {
2448 ret = -EFAULT;
2449 } else {
2450 if (wmi_bmisstime_cmd(ar->arWmi, bmissCmd.bmissTime, bmissCmd.nu mBeacons) != A_OK) {
2451 ret = -EIO;
2452 }
2453 }
2454 break;
2455 }
2456 case AR6000_IOCTL_WMI_SETBSSFILTER:
2457 {
2458 WMI_BSS_FILTER_CMD filt;
2459
2460 if (ar->arWmiReady == FALSE) {
2461 ret = -EIO;
2462 } else if (copy_from_user(&filt, userdata,
2463 sizeof(filt)))
2464 {
2465 ret = -EFAULT;
2466 } else {
2467 if (wmi_bssfilter_cmd(ar->arWmi, filt.bssFilter, filt.ieMask)
2468 != A_OK) {
2469 ret = -EIO;
2470 } else {
2471 ar->arUserBssFilter = param;
2472 }
2473 }
2474 break;
2475 }
2476 case AR6000_IOCTL_WMI_SET_SNRTHRESHOLD:
2477 {
2478 ret = ar6000_ioctl_set_snr_threshold(dev, rq);
2479 break;
2480 }
2481 case AR6000_XIOCTL_WMI_SET_RSSITHRESHOLD:
2482 {
2483 ret = ar6000_ioctl_set_rssi_threshold(dev, rq);
2484 break;
2485 }
2486 case AR6000_XIOCTL_WMI_CLR_RSSISNR:
2487 {
2488 if (ar->arWmiReady == FALSE) {
2489 ret = -EIO;
2490 }
2491 ret = wmi_clr_rssi_snr(ar->arWmi);
2492 break;
2493 }
2494 case AR6000_XIOCTL_WMI_SET_LQTHRESHOLD:
2495 {
2496 ret = ar6000_ioctl_set_lq_threshold(dev, rq);
2497 break;
2498 }
2499 case AR6000_XIOCTL_WMI_SET_LPREAMBLE:
2500 {
2501 WMI_SET_LPREAMBLE_CMD setLpreambleCmd;
2502
2503 if (ar->arWmiReady == FALSE) {
2504 ret = -EIO;
2505 } else if (copy_from_user(&setLpreambleCmd, userdata,
2506 sizeof(setLpreambleCmd)))
2507 {
2508 ret = -EFAULT;
2509 } else {
2510 if (wmi_set_lpreamble_cmd(ar->arWmi, setLpreambleCmd.status,
2511 WMI_IGNORE_BARKER_IN_ERP) != A_OK)
2512 {
2513 ret = -EIO;
2514 }
2515 }
2516
2517 break;
2518 }
2519 case AR6000_XIOCTL_WMI_SET_RTS:
2520 {
2521 WMI_SET_RTS_CMD rtsCmd;
2522
2523 if (ar->arWmiReady == FALSE) {
2524 ret = -EIO;
2525 } else if (copy_from_user(&rtsCmd, userdata,
2526 sizeof(rtsCmd)))
2527 {
2528 ret = -EFAULT;
2529 } else {
2530 ar->arRTS = rtsCmd.threshold;
2531 if (wmi_set_rts_cmd(ar->arWmi, rtsCmd.threshold)
2532 != A_OK)
2533 {
2534 ret = -EIO;
2535 }
2536 }
2537
2538 break;
2539 }
2540 case AR6000_XIOCTL_WMI_SET_WMM:
2541 {
2542 ret = ar6000_ioctl_set_wmm(dev, rq);
2543 break;
2544 }
2545 case AR6000_XIOCTL_WMI_SET_QOS_SUPP:
2546 {
2547 ret = ar6000_ioctl_set_qos_supp(dev, rq);
2548 break;
2549 }
2550 case AR6000_XIOCTL_WMI_SET_TXOP:
2551 {
2552 ret = ar6000_ioctl_set_txop(dev, rq);
2553 break;
2554 }
2555 case AR6000_XIOCTL_WMI_GET_RD:
2556 {
2557 ret = ar6000_ioctl_get_rd(dev, rq);
2558 break;
2559 }
2560 case AR6000_IOCTL_WMI_SET_CHANNELPARAMS:
2561 {
2562 ret = ar6000_ioctl_set_channelParams(dev, rq);
2563 break;
2564 }
2565 case AR6000_IOCTL_WMI_SET_PROBEDSSID:
2566 {
2567 ret = ar6000_ioctl_set_probedSsid(dev, rq);
2568 break;
2569 }
2570 case AR6000_IOCTL_WMI_SET_BADAP:
2571 {
2572 ret = ar6000_ioctl_set_badAp(dev, rq);
2573 break;
2574 }
2575 case AR6000_IOCTL_WMI_CREATE_QOS:
2576 {
2577 ret = ar6000_ioctl_create_qos(dev, rq);
2578 break;
2579 }
2580 case AR6000_IOCTL_WMI_DELETE_QOS:
2581 {
2582 ret = ar6000_ioctl_delete_qos(dev, rq);
2583 break;
2584 }
2585 case AR6000_IOCTL_WMI_GET_QOS_QUEUE:
2586 {
2587 ret = ar6000_ioctl_get_qos_queue(dev, rq);
2588 break;
2589 }
2590 case AR6000_IOCTL_WMI_GET_TARGET_STATS:
2591 {
2592 ret = ar6000_ioctl_get_target_stats(dev, rq);
2593 break;
2594 }
2595 case AR6000_IOCTL_WMI_SET_ERROR_REPORT_BITMASK:
2596 {
2597 ret = ar6000_ioctl_set_error_report_bitmask(dev, rq);
2598 break;
2599 }
2600 case AR6000_IOCTL_WMI_SET_ASSOC_INFO:
2601 {
2602 WMI_SET_ASSOC_INFO_CMD cmd;
2603 A_UINT8 assocInfo[WMI_MAX_ASSOC_INFO_LEN];
2604
2605 if (ar->arWmiReady == FALSE) {
2606 ret = -EIO;
2607 } else {
2608 get_user(cmd.ieType, userdata);
2609 if (cmd.ieType >= WMI_MAX_ASSOC_INFO_TYPE) {
2610 ret = -EIO;
2611 } else {
2612 get_user(cmd.bufferSize, userdata + 1);
2613 if (cmd.bufferSize > WMI_MAX_ASSOC_INFO_LEN) {
2614 ret = -EFAULT;
2615 break;
2616 }
2617 if (copy_from_user(assocInfo, userdata + 2,
2618 cmd.bufferSize))
2619 {
2620 ret = -EFAULT;
2621 } else {
2622 if (wmi_associnfo_cmd(ar->arWmi, cmd.ieType,
2623 cmd.bufferSize,
2624 assocInfo) != A_OK)
2625 {
2626 ret = -EIO;
2627 }
2628 }
2629 }
2630 }
2631 break;
2632 }
2633 case AR6000_IOCTL_WMI_SET_ACCESS_PARAMS:
2634 {
2635 ret = ar6000_ioctl_set_access_params(dev, rq);
2636 break;
2637 }
2638 case AR6000_IOCTL_WMI_SET_DISC_TIMEOUT:
2639 {
2640 ret = ar6000_ioctl_set_disconnect_timeout(dev, rq);
2641 break;
2642 }
2643 case AR6000_XIOCTL_FORCE_TARGET_RESET:
2644 {
2645 if (ar->arHtcTarget)
2646 {
2647 // HTCForceReset(htcTarget);
2648 }
2649 else
2650 {
2651 AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("ar6000_ioctl cannot attempt res et.\n"));
2652 }
2653 break;
2654 }
2655 case AR6000_XIOCTL_TARGET_INFO:
2656 case AR6000_XIOCTL_CHECK_TARGET_READY: /* backwards compatibility */
2657 {
2658 /* If we made it to here, then the Target exists and is ready. */
2659
2660 if (cmd == AR6000_XIOCTL_TARGET_INFO) {
2661 if (copy_to_user((A_UINT32 *)rq->ifr_data, &ar->arVersion.target _ver,
2662 sizeof(ar->arVersion.target_ver)))
2663 {
2664 ret = -EFAULT;
2665 }
2666 if (copy_to_user(((A_UINT32 *)rq->ifr_data)+1, &ar->arTargetType ,
2667 sizeof(ar->arTargetType)))
2668 {
2669 ret = -EFAULT;
2670 }
2671 }
2672 break;
2673 }
2674 case AR6000_XIOCTL_WMI_SET_HB_CHALLENGE_RESP_PARAMS:
2675 {
2676 WMI_SET_HB_CHALLENGE_RESP_PARAMS_CMD hbparam;
2677
2678 if (copy_from_user(&hbparam, userdata, sizeof(hbparam)))
2679 {
2680 ret = -EFAULT;
2681 } else {
2682 AR6000_SPIN_LOCK(&ar->arLock, 0);
2683 /* Start a cyclic timer with the parameters provided. */
2684 if (hbparam.frequency) {
2685 ar->arHBChallengeResp.frequency = hbparam.frequency;
2686 }
2687 if (hbparam.threshold) {
2688 ar->arHBChallengeResp.missThres = hbparam.threshold;
2689 }
2690
2691 /* Delete the pending timer and start a new one */
2692 if (timer_pending(&ar->arHBChallengeResp.timer)) {
2693 A_UNTIMEOUT(&ar->arHBChallengeResp.timer);
2694 }
2695 A_TIMEOUT_MS(&ar->arHBChallengeResp.timer, ar->arHBChallengeResp .frequency * 1000, 0);
2696 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
2697 }
2698 break;
2699 }
2700 case AR6000_XIOCTL_WMI_GET_HB_CHALLENGE_RESP:
2701 {
2702 A_UINT32 cookie;
2703
2704 if (copy_from_user(&cookie, userdata, sizeof(cookie))) {
2705 return -EFAULT;
2706 }
2707
2708 /* Send the challenge on the control channel */
2709 if (wmi_get_challenge_resp_cmd(ar->arWmi, cookie, APP_HB_CHALLENGE) != A_OK) {
2710 return -EIO;
2711 }
2712 break;
2713 }
2714 #ifdef USER_KEYS
2715 case AR6000_XIOCTL_USER_SETKEYS:
2716 {
2717
2718 ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_RUN;
2719
2720 if (copy_from_user(&ar->user_key_ctrl, userdata,
2721 sizeof(ar->user_key_ctrl)))
2722 {
2723 return -EFAULT;
2724 }
2725
2726 A_PRINTF("ar6000 USER set key %x\n", ar->user_key_ctrl);
2727 break;
2728 }
2729 #endif /* USER_KEYS */
2730
2731 #ifdef CONFIG_HOST_GPIO_SUPPORT
2732 case AR6000_XIOCTL_GPIO_OUTPUT_SET:
2733 {
2734 struct ar6000_gpio_output_set_cmd_s gpio_output_set_cmd;
2735
2736 if (ar->bIsDestroyProgress) {
2737 return -EBUSY;
2738 }
2739 if (ar->arWmiReady == FALSE) {
2740 return -EIO;
2741 }
2742 if (down_interruptible(&ar->arSem)) {
2743 return -ERESTARTSYS;
2744 }
2745 if (ar->bIsDestroyProgress) {
2746 up(&ar->arSem);
2747 return -EBUSY;
2748 }
2749
2750 if (copy_from_user(&gpio_output_set_cmd, userdata,
2751 sizeof(gpio_output_set_cmd)))
2752 {
2753 ret = -EFAULT;
2754 } else {
2755 ret = ar6000_gpio_output_set(dev,
2756 gpio_output_set_cmd.set_mask,
2757 gpio_output_set_cmd.clear_mask,
2758 gpio_output_set_cmd.enable_mask,
2759 gpio_output_set_cmd.disable_mask);
2760 if (ret != A_OK) {
2761 ret = EIO;
2762 }
2763 }
2764 up(&ar->arSem);
2765 break;
2766 }
2767 case AR6000_XIOCTL_GPIO_INPUT_GET:
2768 {
2769 if (ar->bIsDestroyProgress) {
2770 return -EBUSY;
2771 }
2772 if (ar->arWmiReady == FALSE) {
2773 return -EIO;
2774 }
2775 if (down_interruptible(&ar->arSem)) {
2776 return -ERESTARTSYS;
2777 }
2778 if (ar->bIsDestroyProgress) {
2779 up(&ar->arSem);
2780 return -EBUSY;
2781 }
2782
2783 ret = ar6000_gpio_input_get(dev);
2784 if (ret != A_OK) {
2785 up(&ar->arSem);
2786 return -EIO;
2787 }
2788
2789 /* Wait for Target to respond. */
2790 wait_event_interruptible(arEvent, gpio_data_available);
2791 if (signal_pending(current)) {
2792 ret = -EINTR;
2793 } else {
2794 A_ASSERT(gpio_reg_results.gpioreg_id == GPIO_ID_NONE);
2795
2796 if (copy_to_user(userdata, &gpio_reg_results.value,
2797 sizeof(gpio_reg_results.value)))
2798 {
2799 ret = -EFAULT;
2800 }
2801 }
2802 up(&ar->arSem);
2803 break;
2804 }
2805 case AR6000_XIOCTL_GPIO_REGISTER_SET:
2806 {
2807 struct ar6000_gpio_register_cmd_s gpio_register_cmd;
2808
2809 if (ar->bIsDestroyProgress) {
2810 return -EBUSY;
2811 }
2812 if (ar->arWmiReady == FALSE) {
2813 return -EIO;
2814 }
2815 if (down_interruptible(&ar->arSem)) {
2816 return -ERESTARTSYS;
2817 }
2818 if (ar->bIsDestroyProgress) {
2819 up(&ar->arSem);
2820 return -EBUSY;
2821 }
2822
2823 if (copy_from_user(&gpio_register_cmd, userdata,
2824 sizeof(gpio_register_cmd)))
2825 {
2826 ret = -EFAULT;
2827 } else {
2828 ret = ar6000_gpio_register_set(dev,
2829 gpio_register_cmd.gpioreg_id,
2830 gpio_register_cmd.value);
2831 if (ret != A_OK) {
2832 ret = EIO;
2833 }
2834
2835 /* Wait for acknowledgement from Target */
2836 wait_event_interruptible(arEvent, gpio_ack_received);
2837 if (signal_pending(current)) {
2838 ret = -EINTR;
2839 }
2840 }
2841 up(&ar->arSem);
2842 break;
2843 }
2844 case AR6000_XIOCTL_GPIO_REGISTER_GET:
2845 {
2846 struct ar6000_gpio_register_cmd_s gpio_register_cmd;
2847
2848 if (ar->bIsDestroyProgress) {
2849 return -EBUSY;
2850 }
2851 if (ar->arWmiReady == FALSE) {
2852 return -EIO;
2853 }
2854 if (down_interruptible(&ar->arSem)) {
2855 return -ERESTARTSYS;
2856 }
2857 if (ar->bIsDestroyProgress) {
2858 up(&ar->arSem);
2859 return -EBUSY;
2860 }
2861
2862 if (copy_from_user(&gpio_register_cmd, userdata,
2863 sizeof(gpio_register_cmd)))
2864 {
2865 ret = -EFAULT;
2866 } else {
2867 ret = ar6000_gpio_register_get(dev, gpio_register_cmd.gpioreg_id );
2868 if (ret != A_OK) {
2869 up(&ar->arSem);
2870 return -EIO;
2871 }
2872
2873 /* Wait for Target to respond. */
2874 wait_event_interruptible(arEvent, gpio_data_available);
2875 if (signal_pending(current)) {
2876 ret = -EINTR;
2877 } else {
2878 A_ASSERT(gpio_register_cmd.gpioreg_id == gpio_reg_results.gp ioreg_id);
2879 if (copy_to_user(userdata, &gpio_reg_results,
2880 sizeof(gpio_reg_results)))
2881 {
2882 ret = -EFAULT;
2883 }
2884 }
2885 }
2886 up(&ar->arSem);
2887 break;
2888 }
2889 case AR6000_XIOCTL_GPIO_INTR_ACK:
2890 {
2891 struct ar6000_gpio_intr_ack_cmd_s gpio_intr_ack_cmd;
2892
2893 if (ar->bIsDestroyProgress) {
2894 return -EBUSY;
2895 }
2896 if (ar->arWmiReady == FALSE) {
2897 return -EIO;
2898 }
2899 if (down_interruptible(&ar->arSem)) {
2900 return -ERESTARTSYS;
2901 }
2902 if (ar->bIsDestroyProgress) {
2903 up(&ar->arSem);
2904 return -EBUSY;
2905 }
2906
2907 if (copy_from_user(&gpio_intr_ack_cmd, userdata,
2908 sizeof(gpio_intr_ack_cmd)))
2909 {
2910 ret = -EFAULT;
2911 } else {
2912 ret = ar6000_gpio_intr_ack(dev, gpio_intr_ack_cmd.ack_mask);
2913 if (ret != A_OK) {
2914 ret = EIO;
2915 }
2916 }
2917 up(&ar->arSem);
2918 break;
2919 }
2920 case AR6000_XIOCTL_GPIO_INTR_WAIT:
2921 {
2922 /* Wait for Target to report an interrupt. */
2923 dev_hold(dev);
2924 rtnl_unlock();
2925 wait_event_interruptible(arEvent, gpio_intr_available);
2926 rtnl_lock();
2927 __dev_put(dev);
2928
2929 if (signal_pending(current)) {
2930 ret = -EINTR;
2931 } else {
2932 if (copy_to_user(userdata, &gpio_intr_results,
2933 sizeof(gpio_intr_results)))
2934 {
2935 ret = -EFAULT;
2936 }
2937 }
2938 break;
2939 }
2940 #endif /* CONFIG_HOST_GPIO_SUPPORT */
2941
2942 case AR6000_XIOCTL_DBGLOG_CFG_MODULE:
2943 {
2944 struct ar6000_dbglog_module_config_s config;
2945
2946 if (copy_from_user(&config, userdata, sizeof(config))) {
2947 return -EFAULT;
2948 }
2949
2950 /* Send the challenge on the control channel */
2951 if (wmi_config_debug_module_cmd(ar->arWmi, config.mmask,
2952 config.tsr, config.rep,
2953 config.size, config.valid) != A_OK)
2954 {
2955 return -EIO;
2956 }
2957 break;
2958 }
2959
2960 case AR6000_XIOCTL_DBGLOG_GET_DEBUG_LOGS:
2961 {
2962 /* Send the challenge on the control channel */
2963 if (ar6000_dbglog_get_debug_logs(ar) != A_OK)
2964 {
2965 return -EIO;
2966 }
2967 break;
2968 }
2969
2970 case AR6000_XIOCTL_SET_ADHOC_BSSID:
2971 {
2972 WMI_SET_ADHOC_BSSID_CMD adhocBssid;
2973
2974 if (ar->arWmiReady == FALSE) {
2975 ret = -EIO;
2976 } else if (copy_from_user(&adhocBssid, userdata,
2977 sizeof(adhocBssid)))
2978 {
2979 ret = -EFAULT;
2980 } else if (A_MEMCMP(adhocBssid.bssid, bcast_mac,
2981 AR6000_ETH_ADDR_LEN) == 0)
2982 {
2983 ret = -EFAULT;
2984 } else {
2985
2986 A_MEMCPY(ar->arReqBssid, adhocBssid.bssid, sizeof(ar->arReqBssid ));
2987 }
2988 break;
2989 }
2990
2991 case AR6000_XIOCTL_SET_OPT_MODE:
2992 {
2993 WMI_SET_OPT_MODE_CMD optModeCmd;
2994 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
2995
2996 if (ar->arWmiReady == FALSE) {
2997 ret = -EIO;
2998 } else if (copy_from_user(&optModeCmd, userdata,
2999 sizeof(optModeCmd)))
3000 {
3001 ret = -EFAULT;
3002 } else if (ar->arConnected && optModeCmd.optMode == SPECIAL_ON) {
3003 ret = -EFAULT;
3004
3005 } else if (wmi_set_opt_mode_cmd(ar->arWmi, optModeCmd.optMode)
3006 != A_OK)
3007 {
3008 ret = -EIO;
3009 }
3010 break;
3011 }
3012
3013 case AR6000_XIOCTL_OPT_SEND_FRAME:
3014 {
3015 WMI_OPT_TX_FRAME_CMD optTxFrmCmd;
3016 A_UINT8 data[MAX_OPT_DATA_LEN];
3017
3018 if (ar->arWmiReady == FALSE) {
3019 ret = -EIO;
3020 } else if (copy_from_user(&optTxFrmCmd, userdata,
3021 sizeof(optTxFrmCmd)))
3022 {
3023 ret = -EFAULT;
3024 } else if (copy_from_user(data,
3025 userdata+sizeof(WMI_OPT_TX_FRAME_CMD)-1,
3026 optTxFrmCmd.optIEDataLen))
3027 {
3028 ret = -EFAULT;
3029 } else {
3030 ret = wmi_opt_tx_frame_cmd(ar->arWmi,
3031 optTxFrmCmd.frmType,
3032 optTxFrmCmd.dstAddr,
3033 optTxFrmCmd.bssid,
3034 optTxFrmCmd.optIEDataLen,
3035 data);
3036 }
3037
3038 break;
3039 }
3040 case AR6000_XIOCTL_WMI_SETRETRYLIMITS:
3041 {
3042 WMI_SET_RETRY_LIMITS_CMD setRetryParams;
3043
3044 if (ar->arWmiReady == FALSE) {
3045 ret = -EIO;
3046 } else if (copy_from_user(&setRetryParams, userdata,
3047 sizeof(setRetryParams)))
3048 {
3049 ret = -EFAULT;
3050 } else {
3051 if (wmi_set_retry_limits_cmd(ar->arWmi, setRetryParams.frameType ,
3052 setRetryParams.trafficClass,
3053 setRetryParams.maxRetries,
3054 setRetryParams.enableNotify) != A_OK)
3055 {
3056 ret = -EIO;
3057 }
3058 AR6000_SPIN_LOCK(&ar->arLock, 0);
3059 ar->arMaxRetries = setRetryParams.maxRetries;
3060 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3061 }
3062 break;
3063 }
3064
3065 case AR6000_XIOCTL_SET_BEACON_INTVAL:
3066 {
3067 WMI_BEACON_INT_CMD bIntvlCmd;
3068
3069 if (ar->arWmiReady == FALSE) {
3070 ret = -EIO;
3071 } else if (copy_from_user(&bIntvlCmd, userdata,
3072 sizeof(bIntvlCmd)))
3073 {
3074 ret = -EFAULT;
3075 } else if (wmi_set_adhoc_bconIntvl_cmd(ar->arWmi, bIntvlCmd.beaconIn terval)
3076 != A_OK)
3077 {
3078 ret = -EIO;
3079 }
3080 if(ret == 0) {
3081 ar->ap_beacon_interval = bIntvlCmd.beaconInterval;
3082 ar->ap_profile_flag = 1; /* There is a change in profile */
3083 }
3084 break;
3085 }
3086 case IEEE80211_IOCTL_SETAUTHALG:
3087 {
3088 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
3089 struct ieee80211req_authalg req;
3090
3091 if (ar->arWmiReady == FALSE) {
3092 ret = -EIO;
3093 } else if (copy_from_user(&req, userdata,
3094 sizeof(struct ieee80211req_authalg)))
3095 {
3096 ret = -EFAULT;
3097 } else {
3098 if (req.auth_alg & AUTH_ALG_OPEN_SYSTEM) {
3099 ar->arDot11AuthMode |= OPEN_AUTH;
3100 ar->arPairwiseCrypto = NONE_CRYPT;
3101 ar->arGroupCrypto = NONE_CRYPT;
3102 }
3103 if (req.auth_alg & AUTH_ALG_SHARED_KEY) {
3104 ar->arDot11AuthMode |= SHARED_AUTH;
3105 ar->arPairwiseCrypto = WEP_CRYPT;
3106 ar->arGroupCrypto = WEP_CRYPT;
3107 ar->arAuthMode = NONE_AUTH;
3108 }
3109 if (req.auth_alg == AUTH_ALG_LEAP) {
3110 ar->arDot11AuthMode = LEAP_AUTH;
3111 }
3112 }
3113 break;
3114 }
3115
3116 case AR6000_XIOCTL_SET_VOICE_PKT_SIZE:
3117 ret = ar6000_xioctl_set_voice_pkt_size(dev, userdata);
3118 break;
3119
3120 case AR6000_XIOCTL_SET_MAX_SP:
3121 ret = ar6000_xioctl_set_max_sp_len(dev, userdata);
3122 break;
3123
3124 case AR6000_XIOCTL_WMI_GET_ROAM_TBL:
3125 ret = ar6000_ioctl_get_roam_tbl(dev, rq);
3126 break;
3127 case AR6000_XIOCTL_WMI_SET_ROAM_CTRL:
3128 ret = ar6000_ioctl_set_roam_ctrl(dev, userdata);
3129 break;
3130 case AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS:
3131 ret = ar6000_ioctl_set_powersave_timers(dev, userdata);
3132 break;
3133 case AR6000_XIOCTRL_WMI_GET_POWER_MODE:
3134 ret = ar6000_ioctl_get_power_mode(dev, rq);
3135 break;
3136 case AR6000_XIOCTRL_WMI_SET_WLAN_STATE:
3137 get_user(ar->arWlanState, (unsigned int *)userdata);
3138 if (ar->arWmiReady == FALSE) {
3139 ret = -EIO;
3140 break;
3141 }
3142
3143 if (ar->arWlanState == WLAN_ENABLED) {
3144 /* Enable foreground scanning */
3145 if (wmi_scanparams_cmd(ar->arWmi, scParams.fg_start_period,
3146 scParams.fg_end_period,
3147 scParams.bg_period,
3148 scParams.minact_chdwell_time,
3149 scParams.maxact_chdwell_time,
3150 scParams.pas_chdwell_time,
3151 scParams.shortScanRatio,
3152 scParams.scanCtrlFlags,
3153 scParams.max_dfsch_act_time,
3154 scParams.maxact_scan_per_ssid) != A_OK)
3155 {
3156 ret = -EIO;
3157 }
3158 if (ar->arSsidLen) {
3159 ar->arConnectPending = TRUE;
3160 if ((ar->arNetworkType & INFRA_NETWORK) &&
3161 (ar->arAuthMode == NONE_AUTH) &&
3162 (ar->arPairwiseCrypto == WEP_CRYPT)) {
3163 /* set WEP keys again as it may have been cleared from
3164 * previous disconnect command to target
3165 */
3166 ar6000_install_static_wep_keys(ar);
3167 }
3168 if (wmi_connect_cmd(ar->arWmi, ar->arNetworkType,
3169 ar->arDot11AuthMode, ar->arAuthMode,
3170 ar->arPairwiseCrypto,
3171 ar->arPairwiseCryptoLen,
3172 ar->arGroupCrypto, ar->arGroupCryptoLen,
3173 ar->arSsidLen, ar->arSsid,
3174 ar->arReqBssid, ar->arChannelHint,
3175 ar->arConnectCtrlFlags) != A_OK)
3176 {
3177 ret = -EIO;
3178 ar->arConnectPending = FALSE;
3179 }
3180 }
3181 } else {
3182 /* Disconnect from the AP and disable foreground scanning */
3183 AR6000_SPIN_LOCK(&ar->arLock, 0);
3184 if (ar->arConnected == TRUE || ar->arConnectPending == TRUE) {
3185 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3186 wmi_disconnect_cmd(ar->arWmi);
3187 } else {
3188 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3189 }
3190
3191 if (wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0, 0, 0, 0, 0, 0, 0xFF , 0, 0) != A_OK)
3192 {
3193 ret = -EIO;
3194 }
3195 }
3196 break;
3197 case AR6000_XIOCTL_WMI_GET_ROAM_DATA:
3198 ret = ar6000_ioctl_get_roam_data(dev, rq);
3199 break;
3200
3201 case AR6000_XIOCTL_WMI_SET_BT_STATUS:
3202 ret = ar6000_xioctl_set_bt_status_cmd(dev, userdata);
3203 break;
3204
3205 case AR6000_XIOCTL_WMI_SET_BT_PARAMS:
3206 ret = ar6000_xioctl_set_bt_params_cmd(dev, userdata);
3207 break;
3208
3209 case AR6000_XIOCTL_WMI_SET_BTCOEX_FE_ANT:
3210 ret = ar6000_xioctl_set_btcoex_fe_ant_cmd(dev, userdata) ;
3211 break;
3212
3213 case AR6000_XIOCTL_WMI_SET_BTCOEX_COLOCATED_BT_DEV:
3214 ret = ar6000_xioctl_set_btcoex_colocated_bt_dev_cmd(dev, userdata);
3215 break;
3216
3217 case AR6000_XIOCTL_WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG:
3218 ret = ar6000_xioctl_set_btcoex_btinquiry_page_config_cmd (dev, userdata);
3219 break;
3220
3221 case AR6000_XIOCTL_WMI_SET_BTCOEX_SCO_CONFIG:
3222 ret = ar6000_xioctl_set_btcoex_sco_config_cmd( dev, user data);
3223 break;
3224
3225 case AR6000_XIOCTL_WMI_SET_BTCOEX_A2DP_CONFIG:
3226 ret = ar6000_xioctl_set_btcoex_a2dp_config_cmd(dev, user data);
3227 break;
3228
3229 case AR6000_XIOCTL_WMI_SET_BTCOEX_ACLCOEX_CONFIG:
3230 ret = ar6000_xioctl_set_btcoex_aclcoex_config_cmd(dev, u serdata);
3231 break;
3232
3233 case AR6000_XIOCTL_WMI_SET_BTCOEX_DEBUG:
3234 ret = ar60000_xioctl_set_btcoex_debug_cmd(dev, userdata) ;
3235 break;
3236
3237 case AR6000_XIOCTL_WMI_SET_BT_OPERATING_STATUS:
3238 ret = ar6000_xioctl_set_btcoex_bt_operating_status_cmd(d ev, userdata);
3239 break;
3240
3241 case AR6000_XIOCTL_WMI_GET_BTCOEX_CONFIG:
3242 ret = ar6000_xioctl_get_btcoex_config_cmd(dev, userdata, rq);
3243 break;
3244
3245 case AR6000_XIOCTL_WMI_GET_BTCOEX_STATS:
3246 ret = ar6000_xioctl_get_btcoex_stats_cmd(dev, userdata, rq);
3247 break;
3248
3249 case AR6000_XIOCTL_WMI_STARTSCAN:
3250 {
3251 WMI_START_SCAN_CMD setStartScanCmd, *cmdp;
3252
3253 if (ar->arWmiReady == FALSE) {
3254 ret = -EIO;
3255 } else if (copy_from_user(&setStartScanCmd, userdata,
3256 sizeof(setStartScanCmd)))
3257 {
3258 ret = -EFAULT;
3259 } else {
3260 if (setStartScanCmd.numChannels > 1) {
3261 cmdp = A_MALLOC(130);
3262 if (copy_from_user(cmdp, userdata,
3263 sizeof (*cmdp) +
3264 ((setStartScanCmd.numChannels - 1) *
3265 sizeof(A_UINT16))))
3266 {
3267 kfree(cmdp);
3268 return -EFAULT;
3269 }
3270 } else {
3271 cmdp = &setStartScanCmd;
3272 }
3273
3274 if (wmi_startscan_cmd(ar->arWmi, cmdp->scanType,
3275 cmdp->forceFgScan,
3276 cmdp->isLegacy,
3277 cmdp->homeDwellTime,
3278 cmdp->forceScanInterval,
3279 cmdp->numChannels,
3280 cmdp->channelList) != A_OK)
3281 {
3282 ret = -EIO;
3283 }
3284 }
3285 break;
3286 }
3287 case AR6000_XIOCTL_WMI_SETFIXRATES:
3288 {
3289 WMI_FIX_RATES_CMD setFixRatesCmd;
3290 A_STATUS returnStatus;
3291
3292 if (ar->arWmiReady == FALSE) {
3293 ret = -EIO;
3294 } else if (copy_from_user(&setFixRatesCmd, userdata,
3295 sizeof(setFixRatesCmd)))
3296 {
3297 ret = -EFAULT;
3298 } else {
3299 returnStatus = wmi_set_fixrates_cmd(ar->arWmi, setFixRatesCm d.fixRateMask);
3300 if (returnStatus == A_EINVAL) {
3301 ret = -EINVAL;
3302 } else if(returnStatus != A_OK) {
3303 ret = -EIO;
3304 } else {
3305 ar->ap_profile_flag = 1; /* There is a change in profile */
3306 }
3307 }
3308 break;
3309 }
3310
3311 case AR6000_XIOCTL_WMI_GETFIXRATES:
3312 {
3313 WMI_FIX_RATES_CMD getFixRatesCmd;
3314 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
3315 int ret = 0;
3316
3317 if (ar->bIsDestroyProgress) {
3318 return -EBUSY;
3319 }
3320 if (ar->arWmiReady == FALSE) {
3321 return -EIO;
3322 }
3323
3324 if (down_interruptible(&ar->arSem)) {
3325 return -ERESTARTSYS;
3326 }
3327 if (ar->bIsDestroyProgress) {
3328 up(&ar->arSem);
3329 return -EBUSY;
3330 }
3331 /* Used copy_from_user/copy_to_user to access user space data */
3332 if (copy_from_user(&getFixRatesCmd, userdata, sizeof(getFixRatesCmd) )) {
3333 ret = -EFAULT;
3334 } else {
3335 ar->arRateMask = 0xFFFFFFFF;
3336
3337 if (wmi_get_ratemask_cmd(ar->arWmi) != A_OK) {
3338 up(&ar->arSem);
3339 return -EIO;
3340 }
3341
3342 wait_event_interruptible_timeout(arEvent, ar->arRateMask != 0xFF FFFFFF, wmitimeout * HZ);
3343
3344 if (signal_pending(current)) {
3345 ret = -EINTR;
3346 }
3347
3348 if (!ret) {
3349 getFixRatesCmd.fixRateMask = ar->arRateMask;
3350 }
3351
3352 if(copy_to_user(userdata, &getFixRatesCmd, sizeof(getFixRatesCmd ))) {
3353 ret = -EFAULT;
3354 }
3355
3356 up(&ar->arSem);
3357 }
3358 break;
3359 }
3360 case AR6000_XIOCTL_WMI_SET_AUTHMODE:
3361 {
3362 WMI_SET_AUTH_MODE_CMD setAuthMode;
3363
3364 if (ar->arWmiReady == FALSE) {
3365 ret = -EIO;
3366 } else if (copy_from_user(&setAuthMode, userdata,
3367 sizeof(setAuthMode)))
3368 {
3369 ret = -EFAULT;
3370 } else {
3371 if (wmi_set_authmode_cmd(ar->arWmi, setAuthMode.mode) != A_OK)
3372 {
3373 ret = -EIO;
3374 }
3375 }
3376 break;
3377 }
3378 case AR6000_XIOCTL_WMI_SET_REASSOCMODE:
3379 {
3380 WMI_SET_REASSOC_MODE_CMD setReassocMode;
3381
3382 if (ar->arWmiReady == FALSE) {
3383 ret = -EIO;
3384 } else if (copy_from_user(&setReassocMode, userdata,
3385 sizeof(setReassocMode)))
3386 {
3387 ret = -EFAULT;
3388 } else {
3389 if (wmi_set_reassocmode_cmd(ar->arWmi, setReassocMode.mode) != A _OK)
3390 {
3391 ret = -EIO;
3392 }
3393 }
3394 break;
3395 }
3396 case AR6000_XIOCTL_DIAG_READ:
3397 {
3398 A_UINT32 addr, data;
3399 get_user(addr, (unsigned int *)userdata);
3400 addr = TARG_VTOP(ar->arTargetType, addr);
3401 if (ar6000_ReadRegDiag(ar->arHifDevice, &addr, &data) != A_OK) {
3402 ret = -EIO;
3403 }
3404 put_user(data, (unsigned int *)userdata + 1);
3405 break;
3406 }
3407 case AR6000_XIOCTL_DIAG_WRITE:
3408 {
3409 A_UINT32 addr, data;
3410 get_user(addr, (unsigned int *)userdata);
3411 get_user(data, (unsigned int *)userdata + 1);
3412 addr = TARG_VTOP(ar->arTargetType, addr);
3413 if (ar6000_WriteRegDiag(ar->arHifDevice, &addr, &data) != A_OK) {
3414 ret = -EIO;
3415 }
3416 break;
3417 }
3418 case AR6000_XIOCTL_WMI_SET_KEEPALIVE:
3419 {
3420 WMI_SET_KEEPALIVE_CMD setKeepAlive;
3421 if (ar->arWmiReady == FALSE) {
3422 return -EIO;
3423 } else if (copy_from_user(&setKeepAlive, userdata,
3424 sizeof(setKeepAlive))){
3425 ret = -EFAULT;
3426 } else {
3427 if (wmi_set_keepalive_cmd(ar->arWmi, setKeepAlive.keepaliveInte rval) != A_OK) {
3428 ret = -EIO;
3429 }
3430 }
3431 break;
3432 }
3433 case AR6000_XIOCTL_WMI_SET_PARAMS:
3434 {
3435 WMI_SET_PARAMS_CMD cmd;
3436 if (ar->arWmiReady == FALSE) {
3437 return -EIO;
3438 } else if (copy_from_user(&cmd, userdata,
3439 sizeof(cmd))){
3440 ret = -EFAULT;
3441 } else if (copy_from_user(&cmd, userdata,
3442 sizeof(cmd) + cmd.length))
3443 {
3444 ret = -EFAULT;
3445 } else {
3446 if (wmi_set_params_cmd(ar->arWmi, cmd.opcode, cmd.length, cmd.b uffer) != A_OK) {
3447 ret = -EIO;
3448 }
3449 }
3450 break;
3451 }
3452 case AR6000_XIOCTL_WMI_SET_MCAST_FILTER:
3453 {
3454 WMI_SET_MCAST_FILTER_CMD cmd;
3455 if (ar->arWmiReady == FALSE) {
3456 return -EIO;
3457 } else if (copy_from_user(&cmd, userdata,
3458 sizeof(cmd))){
3459 ret = -EFAULT;
3460 } else {
3461 if (wmi_set_mcast_filter_cmd(ar->arWmi, cmd.multicast_mac[0],
3462 cmd.multicast_mac[1],
3463 cmd.multicast_mac[2],
3464 cmd.multicast_mac[3]) != A_OK) {
3465 ret = -EIO;
3466 }
3467 }
3468 break;
3469 }
3470 case AR6000_XIOCTL_WMI_DEL_MCAST_FILTER:
3471 {
3472 WMI_SET_MCAST_FILTER_CMD cmd;
3473 if (ar->arWmiReady == FALSE) {
3474 return -EIO;
3475 } else if (copy_from_user(&cmd, userdata,
3476 sizeof(cmd))){
3477 ret = -EFAULT;
3478 } else {
3479 if (wmi_del_mcast_filter_cmd(ar->arWmi, cmd.multicast_mac[0],
3480 cmd.multicast_mac[1],
3481 cmd.multicast_mac[2],
3482 cmd.multicast_mac[3]) != A_OK) {
3483 ret = -EIO;
3484 }
3485 }
3486 break;
3487 }
3488 case AR6000_XIOCTL_WMI_MCAST_FILTER:
3489 {
3490 WMI_MCAST_FILTER_CMD cmd;
3491 if (ar->arWmiReady == FALSE) {
3492 return -EIO;
3493 } else if (copy_from_user(&cmd, userdata,
3494 sizeof(cmd))){
3495 ret = -EFAULT;
3496 } else {
3497 if (wmi_mcast_filter_cmd(ar->arWmi, cmd.enable) != A_OK) {
3498 ret = -EIO;
3499 }
3500 }
3501 break;
3502 }
3503 case AR6000_XIOCTL_WMI_GET_KEEPALIVE:
3504 {
3505 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
3506 WMI_GET_KEEPALIVE_CMD getKeepAlive;
3507 int ret = 0;
3508 if (ar->bIsDestroyProgress) {
3509 return -EBUSY;
3510 }
3511 if (ar->arWmiReady == FALSE) {
3512 return -EIO;
3513 }
3514 if (down_interruptible(&ar->arSem)) {
3515 return -ERESTARTSYS;
3516 }
3517 if (ar->bIsDestroyProgress) {
3518 up(&ar->arSem);
3519 return -EBUSY;
3520 }
3521 if (copy_from_user(&getKeepAlive, userdata,sizeof(getKeepAlive))) {
3522 ret = -EFAULT;
3523 } else {
3524 getKeepAlive.keepaliveInterval = wmi_get_keepalive_cmd(ar->arWmi);
3525 ar->arKeepaliveConfigured = 0xFF;
3526 if (wmi_get_keepalive_configured(ar->arWmi) != A_OK){
3527 up(&ar->arSem);
3528 return -EIO;
3529 }
3530 wait_event_interruptible_timeout(arEvent, ar->arKeepaliveConfigured != 0xFF, wmitimeout * HZ);
3531 if (signal_pending(current)) {
3532 ret = -EINTR;
3533 }
3534
3535 if (!ret) {
3536 getKeepAlive.configured = ar->arKeepaliveConfigured;
3537 }
3538 if (copy_to_user(userdata, &getKeepAlive, sizeof(getKeepAlive))) {
3539 ret = -EFAULT;
3540 }
3541 up(&ar->arSem);
3542 }
3543 break;
3544 }
3545 case AR6000_XIOCTL_WMI_SET_APPIE:
3546 {
3547 WMI_SET_APPIE_CMD appIEcmd;
3548 A_UINT8 appIeInfo[IEEE80211_APPIE_FRAME_MAX_LEN];
3549 A_UINT32 fType,ieLen;
3550
3551 if (ar->arWmiReady == FALSE) {
3552 return -EIO;
3553 }
3554 get_user(fType, (A_UINT32 *)userdata);
3555 appIEcmd.mgmtFrmType = fType;
3556 if (appIEcmd.mgmtFrmType >= IEEE80211_APPIE_NUM_OF_FRAME) {
3557 ret = -EIO;
3558 } else {
3559 get_user(ieLen, (A_UINT32 *)(userdata + 4));
3560 appIEcmd.ieLen = ieLen;
3561 A_PRINTF("WPSIE: Type-%d, Len-%d\n",appIEcmd.mgmtFrmType, appIEc md.ieLen);
3562 if (appIEcmd.ieLen > IEEE80211_APPIE_FRAME_MAX_LEN) {
3563 ret = -EIO;
3564 break;
3565 }
3566 if (copy_from_user(appIeInfo, userdata + 8, appIEcmd.ieLen)) {
3567 ret = -EFAULT;
3568 } else {
3569 if (wmi_set_appie_cmd(ar->arWmi, appIEcmd.mgmtFrmType,
3570 appIEcmd.ieLen, appIeInfo) != A_OK)
3571 {
3572 ret = -EIO;
3573 }
3574 }
3575 }
3576 break;
3577 }
3578 case AR6000_XIOCTL_WMI_SET_MGMT_FRM_RX_FILTER:
3579 {
3580 WMI_BSS_FILTER_CMD cmd;
3581 A_UINT32 filterType;
3582
3583 if (copy_from_user(&filterType, userdata, sizeof(A_UINT32)))
3584 {
3585 return -EFAULT;
3586 }
3587 if (filterType & (IEEE80211_FILTER_TYPE_BEACON |
3588 IEEE80211_FILTER_TYPE_PROBE_RESP))
3589 {
3590 cmd.bssFilter = ALL_BSS_FILTER;
3591 } else {
3592 cmd.bssFilter = NONE_BSS_FILTER;
3593 }
3594 if (wmi_bssfilter_cmd(ar->arWmi, cmd.bssFilter, 0) != A_OK) {
3595 ret = -EIO;
3596 } else {
3597 ar->arUserBssFilter = cmd.bssFilter;
3598 }
3599
3600 AR6000_SPIN_LOCK(&ar->arLock, 0);
3601 ar->arMgmtFilter = filterType;
3602 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3603 break;
3604 }
3605 case AR6000_XIOCTL_WMI_SET_WSC_STATUS:
3606 {
3607 A_UINT32 wsc_status;
3608
3609 if (ar->arWmiReady == FALSE) {
3610 return -EIO;
3611 } else if (copy_from_user(&wsc_status, userdata, sizeof(A_UINT32)))
3612 {
3613 return -EFAULT;
3614 }
3615 if (wmi_set_wsc_status_cmd(ar->arWmi, wsc_status) != A_OK) {
3616 ret = -EIO;
3617 }
3618 break;
3619 }
3620 case AR6000_XIOCTL_BMI_ROMPATCH_INSTALL:
3621 {
3622 A_UINT32 ROM_addr;
3623 A_UINT32 RAM_addr;
3624 A_UINT32 nbytes;
3625 A_UINT32 do_activate;
3626 A_UINT32 rompatch_id;
3627
3628 get_user(ROM_addr, (A_UINT32 *)userdata);
3629 get_user(RAM_addr, (A_UINT32 *)userdata + 1);
3630 get_user(nbytes, (A_UINT32 *)userdata + 2);
3631 get_user(do_activate, (A_UINT32 *)userdata + 3);
3632 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Install rompatch from ROM: 0x%x to RAM: 0x%x length: %d\n",
3633 ROM_addr, RAM_addr, nbytes));
3634 ret = BMIrompatchInstall(hifDevice, ROM_addr, RAM_addr,
3635 nbytes, do_activate, &rompatch_id);
3636 if (ret == A_OK) {
3637 put_user(rompatch_id, (unsigned int *)rq->ifr_data); /* return v alue */
3638 }
3639 break;
3640 }
3641
3642 case AR6000_XIOCTL_BMI_ROMPATCH_UNINSTALL:
3643 {
3644 A_UINT32 rompatch_id;
3645
3646 get_user(rompatch_id, (A_UINT32 *)userdata);
3647 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("UNinstall rompatch_id %d\n", rompat ch_id));
3648 ret = BMIrompatchUninstall(hifDevice, rompatch_id);
3649 break;
3650 }
3651
3652 case AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE:
3653 case AR6000_XIOCTL_BMI_ROMPATCH_DEACTIVATE:
3654 {
3655 A_UINT32 rompatch_count;
3656
3657 get_user(rompatch_count, (A_UINT32 *)userdata);
3658 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Change rompatch activation count=%d \n", rompatch_count));
3659 length = sizeof(A_UINT32) * rompatch_count;
3660 if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) {
3661 A_MEMZERO(buffer, length);
3662 if (copy_from_user(buffer, &userdata[sizeof(rompatch_count)], le ngth))
3663 {
3664 ret = -EFAULT;
3665 } else {
3666 if (cmd == AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE) {
3667 ret = BMIrompatchActivate(hifDevice, rompatch_count, (A_ UINT32 *)buffer);
3668 } else {
3669 ret = BMIrompatchDeactivate(hifDevice, rompatch_count, ( A_UINT32 *)buffer);
3670 }
3671 }
3672 A_FREE(buffer);
3673 } else {
3674 ret = -ENOMEM;
3675 }
3676
3677 break;
3678 }
3679 case AR6000_XIOCTL_SET_IP:
3680 {
3681 WMI_SET_IP_CMD setIP;
3682
3683 if (ar->arWmiReady == FALSE) {
3684 ret = -EIO;
3685 } else if (copy_from_user(&setIP, userdata,
3686 sizeof(setIP)))
3687 {
3688 ret = -EFAULT;
3689 } else {
3690 if (wmi_set_ip_cmd(ar->arWmi,
3691 &setIP) != A_OK)
3692 {
3693 ret = -EIO;
3694 }
3695 }
3696 break;
3697 }
3698
3699 case AR6000_XIOCTL_WMI_SET_HOST_SLEEP_MODE:
3700 {
3701 WMI_SET_HOST_SLEEP_MODE_CMD setHostSleepMode;
3702
3703 if (ar->arWmiReady == FALSE) {
3704 ret = -EIO;
3705 } else if (copy_from_user(&setHostSleepMode, userdata,
3706 sizeof(setHostSleepMode)))
3707 {
3708 ret = -EFAULT;
3709 } else {
3710 if (wmi_set_host_sleep_mode_cmd(ar->arWmi,
3711 &setHostSleepMode) != A_OK)
3712 {
3713 ret = -EIO;
3714 }
3715 }
3716 break;
3717 }
3718 case AR6000_XIOCTL_WMI_SET_WOW_MODE:
3719 {
3720 WMI_SET_WOW_MODE_CMD setWowMode;
3721
3722 if (ar->arWmiReady == FALSE) {
3723 ret = -EIO;
3724 } else if (copy_from_user(&setWowMode, userdata,
3725 sizeof(setWowMode)))
3726 {
3727 ret = -EFAULT;
3728 } else {
3729 if (wmi_set_wow_mode_cmd(ar->arWmi,
3730 &setWowMode) != A_OK)
3731 {
3732 ret = -EIO;
3733 }
3734 }
3735 break;
3736 }
3737 case AR6000_XIOCTL_WMI_GET_WOW_LIST:
3738 {
3739 WMI_GET_WOW_LIST_CMD getWowList;
3740
3741 if (ar->arWmiReady == FALSE) {
3742 ret = -EIO;
3743 } else if (copy_from_user(&getWowList, userdata,
3744 sizeof(getWowList)))
3745 {
3746 ret = -EFAULT;
3747 } else {
3748 if (wmi_get_wow_list_cmd(ar->arWmi,
3749 &getWowList) != A_OK)
3750 {
3751 ret = -EIO;
3752 }
3753 }
3754 break;
3755 }
3756 case AR6000_XIOCTL_WMI_ADD_WOW_PATTERN:
3757 {
3758 #define WOW_PATTERN_SIZE 64
3759 #define WOW_MASK_SIZE 64
3760
3761 WMI_ADD_WOW_PATTERN_CMD cmd;
3762 A_UINT8 mask_data[WOW_PATTERN_SIZE]={0};
3763 A_UINT8 pattern_data[WOW_PATTERN_SIZE]={0};
3764
3765 if (ar->arWmiReady == FALSE) {
3766 ret = -EIO;
3767 } else {
3768
3769 if(copy_from_user(&cmd, userdata,
3770 sizeof(WMI_ADD_WOW_PATTERN_CMD)))
3771 return -EFAULT;
3772 if (copy_from_user(pattern_data,
3773 userdata + 3,
3774 cmd.filter_size)){
3775 ret = -EFAULT;
3776 break;
3777 }
3778 if (copy_from_user(mask_data,
3779 (userdata + 3 + cmd.filter_size),
3780 cmd.filter_size)){
3781 ret = -EFAULT;
3782 break;
3783 } else {
3784 if (wmi_add_wow_pattern_cmd(ar->arWmi,
3785 &cmd, pattern_data, mask_data, cmd.filter_size) != A_OK){
3786 ret = -EIO;
3787 }
3788 }
3789 }
3790 #undef WOW_PATTERN_SIZE
3791 #undef WOW_MASK_SIZE
3792 break;
3793 }
3794 case AR6000_XIOCTL_WMI_DEL_WOW_PATTERN:
3795 {
3796 WMI_DEL_WOW_PATTERN_CMD delWowPattern;
3797
3798 if (ar->arWmiReady == FALSE) {
3799 ret = -EIO;
3800 } else if (copy_from_user(&delWowPattern, userdata,
3801 sizeof(delWowPattern)))
3802 {
3803 ret = -EFAULT;
3804 } else {
3805 if (wmi_del_wow_pattern_cmd(ar->arWmi,
3806 &delWowPattern) != A_OK)
3807 {
3808 ret = -EIO;
3809 }
3810 }
3811 break;
3812 }
3813 case AR6000_XIOCTL_DUMP_HTC_CREDIT_STATE:
3814 if (ar->arHtcTarget != NULL) {
3815 HTCDumpCreditStates(ar->arHtcTarget);
3816 #ifdef HTC_EP_STAT_PROFILING
3817 {
3818 HTC_ENDPOINT_STATS stats;
3819 int i;
3820
3821 for (i = 0; i < 5; i++) {
3822 if (HTCGetEndpointStatistics(ar->arHtcTarget,
3823 i,
3824 HTC_EP_STAT_SAMPLE_AND_CLEA R,
3825 &stats)) {
3826 A_PRINTF(KERN_ALERT"------- Profiling Endpoint : %d \n", i);
3827 A_PRINTF(KERN_ALERT"TxCreditLowIndications : %d \n", stats.TxCreditLowIndications);
3828 A_PRINTF(KERN_ALERT"TxIssued : %d \n", stats.TxIssue d);
3829 A_PRINTF(KERN_ALERT"TxDropped: %d \n", stats.TxDropp ed);
3830 A_PRINTF(KERN_ALERT"TxPacketsBundled : %d \n", stats .TxPacketsBundled);
3831 A_PRINTF(KERN_ALERT"TxBundles : %d \n", stats.TxBund les);
3832 A_PRINTF(KERN_ALERT"TxCreditRpts : %d \n", stats.TxC reditRpts);
3833 A_PRINTF(KERN_ALERT"TxCreditsRptsFromRx : %d \n", st ats.TxCreditRptsFromRx);
3834 A_PRINTF(KERN_ALERT"TxCreditsRptsFromOther : %d \n", stats.TxCreditRptsFromOther);
3835 A_PRINTF(KERN_ALERT"TxCreditsRptsFromEp0 : %d \n", s tats.TxCreditRptsFromEp0);
3836 A_PRINTF(KERN_ALERT"TxCreditsFromRx : %d \n", stats. TxCreditsFromRx);
3837 A_PRINTF(KERN_ALERT"TxCreditsFromOther : %d \n", sta ts.TxCreditsFromOther);
3838 A_PRINTF(KERN_ALERT"TxCreditsFromEp0 : %d \n", stats .TxCreditsFromEp0);
3839 A_PRINTF(KERN_ALERT"TxCreditsConsummed : %d \n", sta ts.TxCreditsConsummed);
3840 A_PRINTF(KERN_ALERT"TxCreditsReturned : %d \n", stat s.TxCreditsReturned);
3841 A_PRINTF(KERN_ALERT"RxReceived : %d \n", stats.RxRec eived);
3842 A_PRINTF(KERN_ALERT"RxPacketsBundled : %d \n", stats .RxPacketsBundled);
3843 A_PRINTF(KERN_ALERT"RxLookAheads : %d \n", stats.RxL ookAheads);
3844 A_PRINTF(KERN_ALERT"RxBundleLookAheads : %d \n", sta ts.RxBundleLookAheads);
3845 A_PRINTF(KERN_ALERT"RxBundleIndFromHdr : %d \n", sta ts.RxBundleIndFromHdr);
3846 A_PRINTF(KERN_ALERT"RxAllocThreshHit : %d \n", stats .RxAllocThreshHit);
3847 A_PRINTF(KERN_ALERT"RxAllocThreshBytes : %d \n", sta ts.RxAllocThreshBytes);
3848 A_PRINTF(KERN_ALERT"---- \n");
3849
3850 }
3851 }
3852 }
3853 #endif
3854 }
3855 break;
3856 case AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE:
3857 if (ar->arHtcTarget != NULL) {
3858 struct ar6000_traffic_activity_change data;
3859
3860 if (copy_from_user(&data, userdata, sizeof(data)))
3861 {
3862 return -EFAULT;
3863 }
3864 /* note, this is used for testing (mbox ping testing), indic ate activity
3865 * change using the stream ID as the traffic class */
3866 ar6000_indicate_tx_activity(ar,
3867 (A_UINT8)data.StreamID,
3868 data.Active ? TRUE : FALSE);
3869 }
3870 break;
3871 case AR6000_XIOCTL_WMI_SET_CONNECT_CTRL_FLAGS:
3872 if (ar->arWmiReady == FALSE) {
3873 ret = -EIO;
3874 } else if (copy_from_user(&connectCtrlFlags, userdata,
3875 sizeof(connectCtrlFlags)))
3876 {
3877 ret = -EFAULT;
3878 } else {
3879 ar->arConnectCtrlFlags = connectCtrlFlags;
3880 }
3881 break;
3882 case AR6000_XIOCTL_WMI_SET_AKMP_PARAMS:
3883 if (ar->arWmiReady == FALSE) {
3884 ret = -EIO;
3885 } else if (copy_from_user(&akmpParams, userdata,
3886 sizeof(WMI_SET_AKMP_PARAMS_CMD)))
3887 {
3888 ret = -EFAULT;
3889 } else {
3890 if (wmi_set_akmp_params_cmd(ar->arWmi, &akmpParams) != A_OK) {
3891 ret = -EIO;
3892 }
3893 }
3894 break;
3895 case AR6000_XIOCTL_WMI_SET_PMKID_LIST:
3896 if (ar->arWmiReady == FALSE) {
3897 ret = -EIO;
3898 } else {
3899 if (copy_from_user(&pmkidInfo.numPMKID, userdata,
3900 sizeof(pmkidInfo.numPMKID)))
3901 {
3902 ret = -EFAULT;
3903 break;
3904 }
3905 if (copy_from_user(&pmkidInfo.pmkidList,
3906 userdata + sizeof(pmkidInfo.numPMKID),
3907 pmkidInfo.numPMKID * sizeof(WMI_PMKID)))
3908 {
3909 ret = -EFAULT;
3910 break;
3911 }
3912 if (wmi_set_pmkid_list_cmd(ar->arWmi, &pmkidInfo) != A_OK) {
3913 ret = -EIO;
3914 }
3915 }
3916 break;
3917 case AR6000_XIOCTL_WMI_GET_PMKID_LIST:
3918 if (ar->arWmiReady == FALSE) {
3919 ret = -EIO;
3920 } else {
3921 if (wmi_get_pmkid_list_cmd(ar->arWmi) != A_OK) {
3922 ret = -EIO;
3923 }
3924 }
3925 break;
3926 case AR6000_XIOCTL_WMI_ABORT_SCAN:
3927 if (ar->arWmiReady == FALSE) {
3928 ret = -EIO;
3929 }
3930 ret = wmi_abort_scan_cmd(ar->arWmi);
3931 break;
3932 case AR6000_XIOCTL_AP_HIDDEN_SSID:
3933 {
3934 A_UINT8 hidden_ssid;
3935 if (ar->arWmiReady == FALSE) {
3936 ret = -EIO;
3937 } else if (copy_from_user(&hidden_ssid, userdata, sizeof(hidden_ssid ))) {
3938 ret = -EFAULT;
3939 } else {
3940 wmi_ap_set_hidden_ssid(ar->arWmi, hidden_ssid);
3941 ar->ap_hidden_ssid = hidden_ssid;
3942 ar->ap_profile_flag = 1; /* There is a change in profile */
3943 }
3944 break;
3945 }
3946 case AR6000_XIOCTL_AP_GET_STA_LIST:
3947 {
3948 if (ar->arWmiReady == FALSE) {
3949 ret = -EIO;
3950 } else {
3951 A_UINT8 i;
3952 ap_get_sta_t temp;
3953 A_MEMZERO(&temp, sizeof(temp));
3954 for(i=0;i<AP_MAX_NUM_STA;i++) {
3955 A_MEMCPY(temp.sta[i].mac, ar->sta_list[i].mac, ATH_MAC_LEN);
3956 temp.sta[i].aid = ar->sta_list[i].aid;
3957 temp.sta[i].keymgmt = ar->sta_list[i].keymgmt;
3958 temp.sta[i].ucipher = ar->sta_list[i].ucipher;
3959 temp.sta[i].auth = ar->sta_list[i].auth;
3960 }
3961 if(copy_to_user((ap_get_sta_t *)rq->ifr_data, &temp,
3962 sizeof(ar->sta_list))) {
3963 ret = -EFAULT;
3964 }
3965 }
3966 break;
3967 }
3968 case AR6000_XIOCTL_AP_SET_NUM_STA:
3969 {
3970 A_UINT8 num_sta;
3971 if (ar->arWmiReady == FALSE) {
3972 ret = -EIO;
3973 } else if (copy_from_user(&num_sta, userdata, sizeof(num_sta))) {
3974 ret = -EFAULT;
3975 } else if(num_sta > AP_MAX_NUM_STA) {
3976 /* value out of range */
3977 ret = -EINVAL;
3978 } else {
3979 wmi_ap_set_num_sta(ar->arWmi, num_sta);
3980 }
3981 break;
3982 }
3983 case AR6000_XIOCTL_AP_SET_ACL_POLICY:
3984 {
3985 A_UINT8 policy;
3986 if (ar->arWmiReady == FALSE) {
3987 ret = -EIO;
3988 } else if (copy_from_user(&policy, userdata, sizeof(policy))) {
3989 ret = -EFAULT;
3990 } else if(policy == ar->g_acl.policy) {
3991 /* No change in policy */
3992 } else {
3993 if(!(policy & AP_ACL_RETAIN_LIST_MASK)) {
3994 /* clear ACL list */
3995 memset(&ar->g_acl,0,sizeof(WMI_AP_ACL));
3996 }
3997 ar->g_acl.policy = policy;
3998 wmi_ap_set_acl_policy(ar->arWmi, policy);
3999 }
4000 break;
4001 }
4002 case AR6000_XIOCTL_AP_SET_ACL_MAC:
4003 {
4004 WMI_AP_ACL_MAC_CMD acl;
4005 if (ar->arWmiReady == FALSE) {
4006 ret = -EIO;
4007 } else if (copy_from_user(&acl, userdata, sizeof(acl))) {
4008 ret = -EFAULT;
4009 } else {
4010 if(acl_add_del_mac(&ar->g_acl, &acl)) {
4011 wmi_ap_acl_mac_list(ar->arWmi, &acl);
4012 } else {
4013 A_PRINTF("ACL list error\n");
4014 ret = -EIO;
4015 }
4016 }
4017 break;
4018 }
4019 case AR6000_XIOCTL_AP_GET_ACL_LIST:
4020 {
4021 if (ar->arWmiReady == FALSE) {
4022 ret = -EIO;
4023 } else if(copy_to_user((WMI_AP_ACL *)rq->ifr_data, &ar->g_acl,
4024 sizeof(WMI_AP_ACL))) {
4025 ret = -EFAULT;
4026 }
4027 break;
4028 }
4029 case AR6000_XIOCTL_AP_COMMIT_CONFIG:
4030 {
4031 ret = ar6000_ap_mode_profile_commit(ar);
4032 break;
4033 }
4034 case IEEE80211_IOCTL_GETWPAIE:
4035 {
4036 struct ieee80211req_wpaie wpaie;
4037 if (ar->arWmiReady == FALSE) {
4038 ret = -EIO;
4039 } else if (copy_from_user(&wpaie, userdata, sizeof(wpaie))) {
4040 ret = -EFAULT;
4041 } else if (ar6000_ap_mode_get_wpa_ie(ar, &wpaie)) {
4042 ret = -EFAULT;
4043 } else if(copy_to_user(userdata, &wpaie, sizeof(wpaie))) {
4044 ret = -EFAULT;
4045 }
4046 break;
4047 }
4048 case AR6000_XIOCTL_AP_CONN_INACT_TIME:
4049 {
4050 A_UINT32 period;
4051 if (ar->arWmiReady == FALSE) {
4052 ret = -EIO;
4053 } else if (copy_from_user(&period, userdata, sizeof(period))) {
4054 ret = -EFAULT;
4055 } else {
4056 wmi_ap_conn_inact_time(ar->arWmi, period);
4057 }
4058 break;
4059 }
4060 case AR6000_XIOCTL_AP_PROT_SCAN_TIME:
4061 {
4062 WMI_AP_PROT_SCAN_TIME_CMD bgscan;
4063 if (ar->arWmiReady == FALSE) {
4064 ret = -EIO;
4065 } else if (copy_from_user(&bgscan, userdata, sizeof(bgscan))) {
4066 ret = -EFAULT;
4067 } else {
4068 wmi_ap_bgscan_time(ar->arWmi, bgscan.period_min, bgscan.dwell_ms );
4069 }
4070 break;
4071 }
4072 case AR6000_XIOCTL_AP_SET_COUNTRY:
4073 {
4074 ret = ar6000_ioctl_set_country(dev, rq);
4075 break;
4076 }
4077 case AR6000_XIOCTL_AP_SET_DTIM:
4078 {
4079 WMI_AP_SET_DTIM_CMD d;
4080 if (ar->arWmiReady == FALSE) {
4081 ret = -EIO;
4082 } else if (copy_from_user(&d, userdata, sizeof(d))) {
4083 ret = -EFAULT;
4084 } else {
4085 if(d.dtim > 0 && d.dtim < 11) {
4086 ar->ap_dtim_period = d.dtim;
4087 wmi_ap_set_dtim(ar->arWmi, d.dtim);
4088 ar->ap_profile_flag = 1; /* There is a change in profile */
4089 } else {
4090 A_PRINTF("DTIM out of range. Valid range is [1-10]\n");
4091 ret = -EIO;
4092 }
4093 }
4094 break;
4095 }
4096 case AR6000_XIOCTL_WMI_TARGET_EVENT_REPORT:
4097 {
4098 WMI_SET_TARGET_EVENT_REPORT_CMD evtCfgCmd;
4099
4100 if (ar->arWmiReady == FALSE) {
4101 ret = -EIO;
4102 }
4103 if (copy_from_user(&evtCfgCmd, userdata,
4104 sizeof(evtCfgCmd))) {
4105 ret = -EFAULT;
4106 break;
4107 }
4108 ret = wmi_set_target_event_report_cmd(ar->arWmi, &evtCfgCmd);
4109 break;
4110 }
4111 case AR6000_XIOCTL_AP_INTRA_BSS_COMM:
4112 {
4113 A_UINT8 intra=0;
4114 if (ar->arWmiReady == FALSE) {
4115 ret = -EIO;
4116 } else if (copy_from_user(&intra, userdata, sizeof(intra))) {
4117 ret = -EFAULT;
4118 } else {
4119 ar->intra_bss = (intra?1:0);
4120 }
4121 break;
4122 }
4123 case AR6000_XIOCTL_DUMP_MODULE_DEBUG_INFO:
4124 {
4125 struct drv_debug_module_s moduleinfo;
4126
4127 if (copy_from_user(&moduleinfo, userdata, sizeof(moduleinfo))) {
4128 ret = -EFAULT;
4129 break;
4130 }
4131
4132 a_dump_module_debug_info_by_name(moduleinfo.modulename);
4133 ret = 0;
4134 break;
4135 }
4136 case AR6000_XIOCTL_MODULE_DEBUG_SET_MASK:
4137 {
4138 struct drv_debug_module_s moduleinfo;
4139
4140 if (copy_from_user(&moduleinfo, userdata, sizeof(moduleinfo))) {
4141 ret = -EFAULT;
4142 break;
4143 }
4144
4145 if (A_FAILED(a_set_module_mask(moduleinfo.modulename, moduleinfo.mas k))) {
4146 ret = -EFAULT;
4147 }
4148
4149 break;
4150 }
4151 case AR6000_XIOCTL_MODULE_DEBUG_GET_MASK:
4152 {
4153 struct drv_debug_module_s moduleinfo;
4154
4155 if (copy_from_user(&moduleinfo, userdata, sizeof(moduleinfo))) {
4156 ret = -EFAULT;
4157 break;
4158 }
4159
4160 if (A_FAILED(a_get_module_mask(moduleinfo.modulename, &moduleinfo.ma sk))) {
4161 ret = -EFAULT;
4162 break;
4163 }
4164
4165 if (copy_to_user(userdata, &moduleinfo, sizeof(moduleinfo))) {
4166 ret = -EFAULT;
4167 break;
4168 }
4169
4170 break;
4171 }
4172 #ifdef ATH_AR6K_11N_SUPPORT
4173 case AR6000_XIOCTL_DUMP_RCV_AGGR_STATS:
4174 {
4175 PACKET_LOG *copy_of_pkt_log;
4176
4177 aggr_dump_stats(ar->aggr_cntxt, &copy_of_pkt_log);
4178 if (copy_to_user(rq->ifr_data, copy_of_pkt_log, sizeof(PACKET_LOG))) {
4179 ret = -EFAULT;
4180 }
4181 break;
4182 }
4183 case AR6000_XIOCTL_SETUP_AGGR:
4184 {
4185 WMI_ADDBA_REQ_CMD cmd;
4186
4187 if (ar->arWmiReady == FALSE) {
4188 ret = -EIO;
4189 } else if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
4190 ret = -EFAULT;
4191 } else {
4192 wmi_setup_aggr_cmd(ar->arWmi, cmd.tid);
4193 }
4194 }
4195 break;
4196
4197 case AR6000_XIOCTL_DELE_AGGR:
4198 {
4199 WMI_DELBA_REQ_CMD cmd;
4200
4201 if (ar->arWmiReady == FALSE) {
4202 ret = -EIO;
4203 } else if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
4204 ret = -EFAULT;
4205 } else {
4206 wmi_delete_aggr_cmd(ar->arWmi, cmd.tid, cmd.is_sender_initiator) ;
4207 }
4208 }
4209 break;
4210
4211 case AR6000_XIOCTL_ALLOW_AGGR:
4212 {
4213 WMI_ALLOW_AGGR_CMD cmd;
4214
4215 if (ar->arWmiReady == FALSE) {
4216 ret = -EIO;
4217 } else if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
4218 ret = -EFAULT;
4219 } else {
4220 wmi_allow_aggr_cmd(ar->arWmi, cmd.tx_allow_aggr, cmd.rx_allow_ag gr);
4221 }
4222 }
4223 break;
4224
4225 case AR6000_XIOCTL_SET_HT_CAP:
4226 {
4227 if (ar->arWmiReady == FALSE) {
4228 ret = -EIO;
4229 } else if (copy_from_user(&htCap, userdata,
4230 sizeof(htCap)))
4231 {
4232 ret = -EFAULT;
4233 } else {
4234
4235 if (wmi_set_ht_cap_cmd(ar->arWmi,
4236 htCap.chan_width_40M_supported,
4237 htCap.short_GI_20MHz,
4238 htCap.short_GI_40MHz,
4239 htCap.intolerance_40MHz,
4240 htCap.max_ampdu_len_exp) != A_OK)
4241 {
4242 ret = -EIO;
4243 }
4244 }
4245 break;
4246 }
4247 case AR6000_XIOCTL_SET_HT_OP:
4248 {
4249 if (ar->arWmiReady == FALSE) {
4250 ret = -EIO;
4251 } else if (copy_from_user(&htOp, userdata,
4252 sizeof(htOp)))
4253 {
4254 ret = -EFAULT;
4255 } else {
4256
4257 if (wmi_set_ht_op_cmd(ar->arWmi, htOp.sta_chan_width) != A_OK)
4258 {
4259 ret = -EIO;
4260 }
4261 }
4262 break;
4263 }
4264 #endif
4265 case AR6000_XIOCTL_ACL_DATA:
4266 {
4267 void *osbuf = NULL;
4268 if (ar->arWmiReady == FALSE) {
4269 ret = -EIO;
4270 } else if (ar6000_create_acl_data_osbuf(dev, userdata, &osbuf) != A_ OK) {
4271 ret = -EIO;
4272 } else {
4273 if (wmi_data_hdr_add(ar->arWmi, osbuf, DATA_MSGTYPE, 0, WMI_DATA _HDR_DATA_TYPE_ACL,0,NULL) != A_OK) {
4274 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("XIOCTL_ACL_DATA - wmi_data_h dr_add failed\n"));
4275 } else {
4276 /* Send data buffer over HTC */
4277 ar6000_acl_data_tx(osbuf, ar->arNetDev);
4278 }
4279 }
4280 break;
4281 }
4282 case AR6000_XIOCTL_HCI_CMD:
4283 {
4284 char tmp_buf[512];
4285 A_INT8 i;
4286 WMI_HCI_CMD *cmd = (WMI_HCI_CMD *)tmp_buf;
4287 A_UINT8 size;
4288
4289 size = sizeof(cmd->cmd_buf_sz);
4290 if (ar->arWmiReady == FALSE) {
4291 ret = -EIO;
4292 } else if (copy_from_user(cmd, userdata, size)) {
4293 ret = -EFAULT;
4294 } else if(copy_from_user(cmd->buf, userdata + size, cmd->cmd_buf_sz) ) {
4295 ret = -EFAULT;
4296 } else {
4297 if (wmi_send_hci_cmd(ar->arWmi, cmd->buf, cmd->cmd_buf_sz) != A_ OK) {
4298 ret = -EIO;
4299 }else if(loghci) {
4300 A_PRINTF_LOG("HCI Command To PAL --> \n");
4301 for(i = 0; i < cmd->cmd_buf_sz; i++) {
4302 A_PRINTF_LOG("0x%02x ",cmd->buf[i]);
4303 if((i % 10) == 0) {
4304 A_PRINTF_LOG("\n");
4305 }
4306 }
4307 A_PRINTF_LOG("\n");
4308 A_PRINTF_LOG("==================================\n");
4309 }
4310 }
4311 break;
4312 }
4313 case AR6000_XIOCTL_WLAN_CONN_PRECEDENCE:
4314 {
4315 WMI_SET_BT_WLAN_CONN_PRECEDENCE cmd;
4316 if (ar->arWmiReady == FALSE) {
4317 ret = -EIO;
4318 } else if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
4319 ret = -EFAULT;
4320 } else {
4321 if (cmd.precedence == BT_WLAN_CONN_PRECDENCE_WLAN ||
4322 cmd.precedence == BT_WLAN_CONN_PRECDENCE_PAL) {
4323 if ( wmi_set_wlan_conn_precedence_cmd(ar->arWmi, cmd.precede nce) != A_OK) {
4324 ret = -EIO;
4325 }
4326 } else {
4327 ret = -EINVAL;
4328 }
4329 }
4330 break;
4331 }
4332 case AR6000_XIOCTL_AP_GET_STAT:
4333 {
4334 ret = ar6000_ioctl_get_ap_stats(dev, rq);
4335 break;
4336 }
4337 case AR6000_XIOCTL_SET_TX_SELECT_RATES:
4338 {
4339 WMI_SET_TX_SELECT_RATES_CMD masks;
4340
4341 if (ar->arWmiReady == FALSE) {
4342 ret = -EIO;
4343 } else if (copy_from_user(&masks, userdata,
4344 sizeof(masks)))
4345 {
4346 ret = -EFAULT;
4347 } else {
4348
4349 if (wmi_set_tx_select_rates_cmd(ar->arWmi, masks.rateMasks) != A _OK)
4350 {
4351 ret = -EIO;
4352 }
4353 }
4354 break;
4355 }
4356 case AR6000_XIOCTL_AP_GET_HIDDEN_SSID:
4357 {
4358 WMI_AP_HIDDEN_SSID_CMD ssid;
4359 ssid.hidden_ssid = ar->ap_hidden_ssid;
4360
4361 if (ar->arWmiReady == FALSE) {
4362 ret = -EIO;
4363 } else if(copy_to_user((WMI_AP_HIDDEN_SSID_CMD *)rq->ifr_data,
4364 &ssid, sizeof(WMI_AP_HIDDEN_SSID_CMD))) {
4365 ret = -EFAULT;
4366 }
4367 break;
4368 }
4369 case AR6000_XIOCTL_AP_GET_COUNTRY:
4370 {
4371 WMI_AP_SET_COUNTRY_CMD cty;
4372 A_MEMCPY(cty.countryCode, ar->ap_country_code, 3);
4373
4374 if (ar->arWmiReady == FALSE) {
4375 ret = -EIO;
4376 } else if(copy_to_user((WMI_AP_SET_COUNTRY_CMD *)rq->ifr_data,
4377 &cty, sizeof(WMI_AP_SET_COUNTRY_CMD))) {
4378 ret = -EFAULT;
4379 }
4380 break;
4381 }
4382 case AR6000_XIOCTL_AP_GET_WMODE:
4383 {
4384 if (ar->arWmiReady == FALSE) {
4385 ret = -EIO;
4386 } else if(copy_to_user((A_UINT8 *)rq->ifr_data,
4387 &ar->ap_wmode, sizeof(A_UINT8))) {
4388 ret = -EFAULT;
4389 }
4390 break;
4391 }
4392 case AR6000_XIOCTL_AP_GET_DTIM:
4393 {
4394 WMI_AP_SET_DTIM_CMD dtim;
4395 dtim.dtim = ar->ap_dtim_period;
4396
4397 if (ar->arWmiReady == FALSE) {
4398 ret = -EIO;
4399 } else if(copy_to_user((WMI_AP_SET_DTIM_CMD *)rq->ifr_data,
4400 &dtim, sizeof(WMI_AP_SET_DTIM_CMD))) {
4401 ret = -EFAULT;
4402 }
4403 break;
4404 }
4405 case AR6000_XIOCTL_AP_GET_BINTVL:
4406 {
4407 WMI_BEACON_INT_CMD bi;
4408 bi.beaconInterval = ar->ap_beacon_interval;
4409
4410 if (ar->arWmiReady == FALSE) {
4411 ret = -EIO;
4412 } else if(copy_to_user((WMI_BEACON_INT_CMD *)rq->ifr_data,
4413 &bi, sizeof(WMI_BEACON_INT_CMD))) {
4414 ret = -EFAULT;
4415 }
4416 break;
4417 }
4418 case AR6000_XIOCTL_AP_GET_RTS:
4419 {
4420 WMI_SET_RTS_CMD rts;
4421 rts.threshold = ar->arRTS;
4422
4423 if (ar->arWmiReady == FALSE) {
4424 ret = -EIO;
4425 } else if(copy_to_user((WMI_SET_RTS_CMD *)rq->ifr_data,
4426 &rts, sizeof(WMI_SET_RTS_CMD))) {
4427 ret = -EFAULT;
4428 }
4429 break;
4430 }
4431 case AR6000_XIOCTL_FETCH_TARGET_REGS:
4432 {
4433 A_UINT32 targregs[AR6003_FETCH_TARG_REGS_COUNT];
4434
4435 if (ar->arTargetType == TARGET_TYPE_AR6003) {
4436 ar6k_FetchTargetRegs(hifDevice, targregs);
4437 if (copy_to_user((A_UINT32 *)rq->ifr_data, &targregs, sizeof(tar gregs)))
4438 {
4439 ret = -EFAULT;
4440 }
4441 } else {
4442 ret = -EOPNOTSUPP;
4443 }
4444 break;
4445 }
4446 case AR6000_XIOCTL_AP_SET_11BG_RATESET:
4447 {
4448 WMI_AP_SET_11BG_RATESET_CMD rate;
4449 if (ar->arWmiReady == FALSE) {
4450 ret = -EIO;
4451 } else if (copy_from_user(&rate, userdata, sizeof(rate))) {
4452 ret = -EFAULT;
4453 } else {
4454 wmi_ap_set_rateset(ar->arWmi, rate.rateset);
4455 }
4456 break;
4457 }
4458 default:
4459 ret = -EOPNOTSUPP;
4460 }
4461 return ret;
4462 }
4463
4464 A_UINT8 mac_cmp_wild(A_UINT8 *mac, A_UINT8 *new_mac, A_UINT8 wild, A_UINT8 new_w ild)
4465 {
4466 A_UINT8 i;
4467
4468 for(i=0;i<ATH_MAC_LEN;i++) {
4469 if((wild & 1<<i) && (new_wild & 1<<i)) continue;
4470 if(mac[i] != new_mac[i]) return 1;
4471 }
4472 if((A_MEMCMP(new_mac, null_mac, 6)==0) && new_wild &&
4473 (wild != new_wild)) {
4474 return 1;
4475 }
4476
4477 return 0;
4478 }
4479
4480 A_UINT8 acl_add_del_mac(WMI_AP_ACL *a, WMI_AP_ACL_MAC_CMD *acl)
4481 {
4482 A_INT8 already_avail=-1, free_slot=-1, i;
4483
4484 /* To check whether this mac is already there in our list */
4485 for(i=AP_ACL_SIZE-1;i>=0;i--)
4486 {
4487 if(mac_cmp_wild(a->acl_mac[i], acl->mac, a->wildcard[i],
4488 acl->wildcard)==0)
4489 already_avail = i;
4490
4491 if(!((1 << i) & a->index))
4492 free_slot = i;
4493 }
4494
4495 if(acl->action == ADD_MAC_ADDR)
4496 {
4497 /* Dont add mac if it is already available */
4498 if((already_avail >= 0) || (free_slot == -1))
4499 return 0;
4500
4501 A_MEMCPY(a->acl_mac[free_slot], acl->mac, ATH_MAC_LEN);
4502 a->index = a->index | (1 << free_slot);
4503 acl->index = free_slot;
4504 a->wildcard[free_slot] = acl->wildcard;
4505 return 1;
4506 }
4507 else if(acl->action == DEL_MAC_ADDR)
4508 {
4509 if(acl->index > AP_ACL_SIZE)
4510 return 0;
4511
4512 if(!(a->index & (1 << acl->index)))
4513 return 0;
4514
4515 A_MEMZERO(a->acl_mac[acl->index],ATH_MAC_LEN);
4516 a->index = a->index & ~(1 << acl->index);
4517 a->wildcard[acl->index] = 0;
4518 return 1;
4519 }
4520
4521 return 0;
4522 }
OLDNEW
« no previous file with comments | « chromeos/drivers/ath6kl/os/linux/include/wmi_filter_linux.h ('k') | chromeos/drivers/ath6kl/os/linux/netbuf.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698