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