f2acc686f9be84b99da6835750de846f3b85f249
[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
1492 static int
1493 ar6000_create_acl_data_osbuf(struct net_device *dev, u8 *userdata, void **p_osbuf)
1494 {
1495     void *osbuf = NULL;
1496     u8 tmp_space[8];
1497     HCI_ACL_DATA_PKT *acl;
1498     u8 hdr_size, *datap=NULL;
1499     int ret = 0;
1500
1501     /* ACL is in data path. There is a need to create pool
1502      * mechanism for allocating and freeing NETBUFs - ToDo later.
1503      */
1504
1505     *p_osbuf = NULL;
1506     acl = (HCI_ACL_DATA_PKT *)tmp_space;
1507     hdr_size = sizeof(acl->hdl_and_flags) + sizeof(acl->data_len);
1508
1509     do {
1510         if (a_copy_from_user(acl, userdata, hdr_size)) {
1511             ret = A_EFAULT;
1512             break;
1513         }
1514
1515         osbuf = A_NETBUF_ALLOC(hdr_size + acl->data_len);
1516         if (osbuf == NULL) {
1517            ret = A_NO_MEMORY;
1518            break;
1519         }
1520         A_NETBUF_PUT(osbuf, hdr_size + acl->data_len);
1521         datap = (u8 *)A_NETBUF_DATA(osbuf);
1522
1523         /* Real copy to osbuf */
1524         acl = (HCI_ACL_DATA_PKT *)(datap);
1525         memcpy(acl, tmp_space, hdr_size);
1526         if (a_copy_from_user(acl->data, userdata + hdr_size, acl->data_len)) {
1527             ret = A_EFAULT;
1528             break;
1529         }
1530     } while(false);
1531
1532     if (ret == 0) {
1533         *p_osbuf = osbuf;
1534     } else {
1535         A_NETBUF_FREE(osbuf);
1536     }
1537     return ret;
1538 }
1539
1540
1541
1542 int
1543 ar6000_ioctl_ap_setparam(struct ar6_softc *ar, int param, int value)
1544 {
1545     int ret=0;
1546
1547     switch(param) {
1548         case IEEE80211_PARAM_WPA:
1549             switch (value) {
1550                 case WPA_MODE_WPA1:
1551                     ar->arAuthMode = WPA_AUTH;
1552                     break;
1553                 case WPA_MODE_WPA2:
1554                     ar->arAuthMode = WPA2_AUTH;
1555                     break;
1556                 case WPA_MODE_AUTO:
1557                     ar->arAuthMode = WPA_AUTH | WPA2_AUTH;
1558                     break;
1559                 case WPA_MODE_NONE:
1560                     ar->arAuthMode = NONE_AUTH;
1561                     break;
1562             }
1563             break;
1564         case IEEE80211_PARAM_AUTHMODE:
1565             if(value == IEEE80211_AUTH_WPA_PSK) {
1566                 if (WPA_AUTH == ar->arAuthMode) {
1567                     ar->arAuthMode = WPA_PSK_AUTH;
1568                 } else if (WPA2_AUTH == ar->arAuthMode) {
1569                     ar->arAuthMode = WPA2_PSK_AUTH;
1570                 } else if ((WPA_AUTH | WPA2_AUTH) == ar->arAuthMode) {
1571                     ar->arAuthMode = WPA_PSK_AUTH | WPA2_PSK_AUTH;
1572                 } else {
1573                     AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Error -  Setting PSK "\
1574                         "mode when WPA param was set to %d\n",
1575                         ar->arAuthMode));
1576                     ret = -EIO;
1577                 }
1578             }
1579             break;
1580         case IEEE80211_PARAM_UCASTCIPHER:
1581             ar->arPairwiseCrypto = 0;
1582             if(value & (1<<IEEE80211_CIPHER_AES_CCM)) {
1583                 ar->arPairwiseCrypto |= AES_CRYPT;
1584             }
1585             if(value & (1<<IEEE80211_CIPHER_TKIP)) {
1586                 ar->arPairwiseCrypto |= TKIP_CRYPT;
1587             }
1588             if(!ar->arPairwiseCrypto) {
1589                 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1590                            ("Error - Invalid cipher in WPA \n"));
1591                 ret = -EIO;
1592             }
1593             break;
1594         case IEEE80211_PARAM_PRIVACY:
1595             if(value == 0) {
1596                 ar->arDot11AuthMode      = OPEN_AUTH;
1597                 ar->arAuthMode           = NONE_AUTH;
1598                 ar->arPairwiseCrypto     = NONE_CRYPT;
1599                 ar->arPairwiseCryptoLen  = 0;
1600                 ar->arGroupCrypto        = NONE_CRYPT;
1601                 ar->arGroupCryptoLen     = 0;
1602             }
1603             break;
1604 #ifdef WAPI_ENABLE
1605         case IEEE80211_PARAM_WAPI:
1606             A_PRINTF("WAPI Policy: %d\n", value);
1607             ar->arDot11AuthMode      = OPEN_AUTH;
1608             ar->arAuthMode           = NONE_AUTH;
1609             if(value & 0x1) {
1610                 ar->arPairwiseCrypto     = WAPI_CRYPT;
1611                 ar->arGroupCrypto        = WAPI_CRYPT;
1612             } else {
1613                 ar->arPairwiseCrypto     = NONE_CRYPT;
1614                 ar->arGroupCrypto        = NONE_CRYPT;
1615             }
1616             break;
1617 #endif
1618     }
1619     return ret;
1620 }
1621
1622 int
1623 ar6000_ioctl_setparam(struct ar6_softc *ar, int param, int value)
1624 {
1625     bool profChanged = false;
1626     int ret=0;
1627
1628     if(ar->arNextMode == AP_NETWORK) {
1629         ar->ap_profile_flag = 1; /* There is a change in profile */
1630         switch (param) {
1631             case IEEE80211_PARAM_WPA:
1632             case IEEE80211_PARAM_AUTHMODE:
1633             case IEEE80211_PARAM_UCASTCIPHER:
1634             case IEEE80211_PARAM_PRIVACY:
1635             case IEEE80211_PARAM_WAPI:
1636                 ret = ar6000_ioctl_ap_setparam(ar, param, value);
1637                 return ret;
1638         }
1639     }
1640
1641     switch (param) {
1642         case IEEE80211_PARAM_WPA:
1643             switch (value) {
1644                 case WPA_MODE_WPA1:
1645                     ar->arAuthMode = WPA_AUTH;
1646                     profChanged    = true;
1647                     break;
1648                 case WPA_MODE_WPA2:
1649                     ar->arAuthMode = WPA2_AUTH;
1650                     profChanged    = true;
1651                     break;
1652                 case WPA_MODE_NONE:
1653                     ar->arAuthMode = NONE_AUTH;
1654                     profChanged    = true;
1655                     break;
1656             }
1657             break;
1658         case IEEE80211_PARAM_AUTHMODE:
1659             switch(value) {
1660                 case IEEE80211_AUTH_WPA_PSK:
1661                     if (WPA_AUTH == ar->arAuthMode) {
1662                         ar->arAuthMode = WPA_PSK_AUTH;
1663                         profChanged    = true;
1664                     } else if (WPA2_AUTH == ar->arAuthMode) {
1665                         ar->arAuthMode = WPA2_PSK_AUTH;
1666                         profChanged    = true;
1667                     } else {
1668                         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Error -  Setting PSK "\
1669                             "mode when WPA param was set to %d\n",
1670                             ar->arAuthMode));
1671                         ret = -EIO;
1672                     }
1673                     break;
1674                 case IEEE80211_AUTH_WPA_CCKM:
1675                     if (WPA2_AUTH == ar->arAuthMode) {
1676                         ar->arAuthMode = WPA2_AUTH_CCKM;
1677                     } else {
1678                         ar->arAuthMode = WPA_AUTH_CCKM;
1679                     }
1680                     break;
1681                 default:
1682                     break;
1683             }
1684             break;
1685         case IEEE80211_PARAM_UCASTCIPHER:
1686             switch (value) {
1687                 case IEEE80211_CIPHER_AES_CCM:
1688                     ar->arPairwiseCrypto = AES_CRYPT;
1689                     profChanged          = true;
1690                     break;
1691                 case IEEE80211_CIPHER_TKIP:
1692                     ar->arPairwiseCrypto = TKIP_CRYPT;
1693                     profChanged          = true;
1694                     break;
1695                 case IEEE80211_CIPHER_WEP:
1696                     ar->arPairwiseCrypto = WEP_CRYPT;
1697                     profChanged          = true;
1698                     break;
1699                 case IEEE80211_CIPHER_NONE:
1700                     ar->arPairwiseCrypto = NONE_CRYPT;
1701                     profChanged          = true;
1702                     break;
1703             }
1704             break;
1705         case IEEE80211_PARAM_UCASTKEYLEN:
1706             if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(value)) {
1707                 ret = -EIO;
1708             } else {
1709                 ar->arPairwiseCryptoLen = value;
1710             }
1711             break;
1712         case IEEE80211_PARAM_MCASTCIPHER:
1713             switch (value) {
1714                 case IEEE80211_CIPHER_AES_CCM:
1715                     ar->arGroupCrypto = AES_CRYPT;
1716                     profChanged       = true;
1717                     break;
1718                 case IEEE80211_CIPHER_TKIP:
1719                     ar->arGroupCrypto = TKIP_CRYPT;
1720                     profChanged       = true;
1721                     break;
1722                 case IEEE80211_CIPHER_WEP:
1723                     ar->arGroupCrypto = WEP_CRYPT;
1724                     profChanged       = true;
1725                     break;
1726                 case IEEE80211_CIPHER_NONE:
1727                     ar->arGroupCrypto = NONE_CRYPT;
1728                     profChanged       = true;
1729                     break;
1730             }
1731             break;
1732         case IEEE80211_PARAM_MCASTKEYLEN:
1733             if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(value)) {
1734                 ret = -EIO;
1735             } else {
1736                 ar->arGroupCryptoLen = value;
1737             }
1738             break;
1739         case IEEE80211_PARAM_COUNTERMEASURES:
1740             if (ar->arWmiReady == false) {
1741                 return -EIO;
1742             }
1743             wmi_set_tkip_countermeasures_cmd(ar->arWmi, value);
1744             break;
1745         default:
1746             break;
1747     }
1748     if ((ar->arNextMode != AP_NETWORK) && (profChanged == true)) {
1749         /*
1750          * profile has changed.  Erase ssid to signal change
1751          */
1752         A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
1753     }
1754
1755     return ret;
1756 }
1757
1758 int
1759 ar6000_ioctl_setkey(struct ar6_softc *ar, struct ieee80211req_key *ik)
1760 {
1761     KEY_USAGE keyUsage;
1762     int status;
1763     CRYPTO_TYPE keyType = NONE_CRYPT;
1764
1765 #ifdef USER_KEYS
1766     ar->user_saved_keys.keyOk = false;
1767 #endif
1768     if ( (0 == memcmp(ik->ik_macaddr, null_mac, IEEE80211_ADDR_LEN)) ||
1769          (0 == memcmp(ik->ik_macaddr, bcast_mac, IEEE80211_ADDR_LEN)) ) {
1770         keyUsage = GROUP_USAGE;
1771         if(ar->arNextMode == AP_NETWORK) {
1772             memcpy(&ar->ap_mode_bkey, ik,
1773                      sizeof(struct ieee80211req_key));
1774 #ifdef WAPI_ENABLE
1775             if(ar->arPairwiseCrypto == WAPI_CRYPT) {
1776                 return ap_set_wapi_key(ar, ik);
1777             }
1778 #endif
1779         }
1780 #ifdef USER_KEYS
1781         memcpy(&ar->user_saved_keys.bcast_ik, ik,
1782                  sizeof(struct ieee80211req_key));
1783 #endif
1784     } else {
1785         keyUsage = PAIRWISE_USAGE;
1786 #ifdef USER_KEYS
1787         memcpy(&ar->user_saved_keys.ucast_ik, ik,
1788                  sizeof(struct ieee80211req_key));
1789 #endif
1790 #ifdef WAPI_ENABLE
1791         if(ar->arNextMode == AP_NETWORK) {
1792             if(ar->arPairwiseCrypto == WAPI_CRYPT) {
1793                 return ap_set_wapi_key(ar, ik);
1794             }
1795         }
1796 #endif
1797     }
1798
1799     switch (ik->ik_type) {
1800         case IEEE80211_CIPHER_WEP:
1801             keyType = WEP_CRYPT;
1802             break;
1803         case IEEE80211_CIPHER_TKIP:
1804             keyType = TKIP_CRYPT;
1805             break;
1806         case IEEE80211_CIPHER_AES_CCM:
1807             keyType = AES_CRYPT;
1808             break;
1809         default:
1810             break;
1811     }
1812 #ifdef USER_KEYS
1813     ar->user_saved_keys.keyType = keyType;
1814 #endif
1815     if (IEEE80211_CIPHER_CCKM_KRK != ik->ik_type) {
1816         if (NONE_CRYPT == keyType) {
1817             return -EIO;
1818         }
1819
1820         if ((WEP_CRYPT == keyType)&&(!ar->arConnected)) {
1821              int index = ik->ik_keyix;
1822
1823             if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(ik->ik_keylen)) {
1824                 return -EIO;
1825             }
1826
1827             A_MEMZERO(ar->arWepKeyList[index].arKey,
1828                             sizeof(ar->arWepKeyList[index].arKey));
1829             memcpy(ar->arWepKeyList[index].arKey, ik->ik_keydata, ik->ik_keylen);
1830             ar->arWepKeyList[index].arKeyLen = ik->ik_keylen;
1831
1832             if(ik->ik_flags & IEEE80211_KEY_DEFAULT){
1833                 ar->arDefTxKeyIndex = index;
1834             }
1835
1836             return 0;
1837         }
1838
1839         if (((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)) &&
1840             (GROUP_USAGE & keyUsage))
1841         {
1842             A_UNTIMEOUT(&ar->disconnect_timer);
1843         }
1844
1845         status = wmi_addKey_cmd(ar->arWmi, ik->ik_keyix, keyType, keyUsage,
1846                                 ik->ik_keylen, (u8 *)&ik->ik_keyrsc,
1847                                 ik->ik_keydata, KEY_OP_INIT_VAL, ik->ik_macaddr,
1848                                 SYNC_BOTH_WMIFLAG);
1849
1850         if (status) {
1851             return -EIO;
1852         }
1853     } else {
1854         status = wmi_add_krk_cmd(ar->arWmi, ik->ik_keydata);
1855     }
1856
1857 #ifdef USER_KEYS
1858     ar->user_saved_keys.keyOk = true;
1859 #endif
1860
1861     return 0;
1862 }
1863
1864 int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
1865 {
1866     struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
1867     struct hif_device *hifDevice = ar->arHifDevice;
1868     int ret = 0, param;
1869     unsigned int address = 0;
1870     unsigned int length = 0;
1871     unsigned char *buffer;
1872     char *userdata;
1873     u32 connectCtrlFlags;
1874
1875
1876     WMI_SET_AKMP_PARAMS_CMD  akmpParams;
1877     WMI_SET_PMKID_LIST_CMD   pmkidInfo;
1878
1879     WMI_SET_HT_CAP_CMD htCap;
1880     WMI_SET_HT_OP_CMD htOp;
1881
1882     /*
1883      * ioctl operations may have to wait for the Target, so we cannot hold rtnl.
1884      * Prevent the device from disappearing under us and release the lock during
1885      * the ioctl operation.
1886      */
1887     dev_hold(dev);
1888     rtnl_unlock();
1889
1890     if (cmd == AR6000_IOCTL_EXTENDED) {
1891         /*
1892          * This allows for many more wireless ioctls than would otherwise
1893          * be available.  Applications embed the actual ioctl command in
1894          * the first word of the parameter block, and use the command
1895          * AR6000_IOCTL_EXTENDED_CMD on the ioctl call.
1896          */
1897         if (get_user(cmd, (int *)rq->ifr_data)) {
1898             ret = -EFAULT;
1899             goto ioctl_done;
1900         }
1901         userdata = (char *)(((unsigned int *)rq->ifr_data)+1);
1902         if(is_xioctl_allowed(ar->arNextMode, cmd) != 0) {
1903             A_PRINTF("xioctl: cmd=%d not allowed in this mode\n",cmd);
1904             ret = -EOPNOTSUPP;
1905             goto ioctl_done;
1906     }
1907     } else {
1908         int ret = is_iwioctl_allowed(ar->arNextMode, cmd);
1909         if(ret == A_ENOTSUP) {
1910             A_PRINTF("iwioctl: cmd=0x%x not allowed in this mode\n", cmd);
1911             ret = -EOPNOTSUPP;
1912             goto ioctl_done;
1913         } else if (ret == A_ERROR) {
1914             /* It is not our ioctl (out of range ioctl) */
1915             ret = -EOPNOTSUPP;
1916             goto ioctl_done;
1917         }
1918         userdata = (char *)rq->ifr_data;
1919     }
1920
1921     if ((ar->arWlanState == WLAN_DISABLED) &&
1922         ((cmd != AR6000_XIOCTRL_WMI_SET_WLAN_STATE) &&
1923          (cmd != AR6000_XIOCTL_GET_WLAN_SLEEP_STATE) &&
1924          (cmd != AR6000_XIOCTL_DIAG_READ) &&
1925          (cmd != AR6000_XIOCTL_DIAG_WRITE) &&
1926          (cmd != AR6000_XIOCTL_SET_BT_HW_POWER_STATE) &&
1927          (cmd != AR6000_XIOCTL_GET_BT_HW_POWER_STATE) &&
1928          (cmd != AR6000_XIOCTL_ADD_AP_INTERFACE) &&
1929          (cmd != AR6000_XIOCTL_REMOVE_AP_INTERFACE) &&
1930          (cmd != AR6000_IOCTL_WMI_GETREV)))
1931     {
1932         ret = -EIO;
1933         goto ioctl_done;
1934     }
1935
1936     ret = 0;
1937     switch(cmd)
1938     {
1939         case IEEE80211_IOCTL_SETPARAM:
1940         {
1941             int param, value;
1942             int *ptr = (int *)rq->ifr_ifru.ifru_newname;
1943             if (ar->arWmiReady == false) {
1944                 ret = -EIO;
1945             } else {
1946                 param = *ptr++;
1947                 value = *ptr;
1948                 ret = ar6000_ioctl_setparam(ar,param,value);
1949             }
1950             break;
1951         }
1952         case IEEE80211_IOCTL_SETKEY:
1953         {
1954             struct ieee80211req_key keydata;
1955             if (ar->arWmiReady == false) {
1956                 ret = -EIO;
1957             } else if (copy_from_user(&keydata, userdata,
1958                             sizeof(struct ieee80211req_key))) {
1959                 ret = -EFAULT;
1960             } else {
1961                 ar6000_ioctl_setkey(ar, &keydata);
1962             }
1963             break;
1964         }
1965         case IEEE80211_IOCTL_DELKEY:
1966         case IEEE80211_IOCTL_SETOPTIE:
1967         {
1968             //ret = -EIO;
1969             break;
1970         }
1971         case IEEE80211_IOCTL_SETMLME:
1972         {
1973             struct ieee80211req_mlme mlme;
1974             if (ar->arWmiReady == false) {
1975                 ret = -EIO;
1976             } else if (copy_from_user(&mlme, userdata,
1977                             sizeof(struct ieee80211req_mlme))) {
1978                 ret = -EFAULT;
1979             } else {
1980                 switch (mlme.im_op) {
1981                     case IEEE80211_MLME_AUTHORIZE:
1982                         A_PRINTF("setmlme AUTHORIZE %02X:%02X\n",
1983                             mlme.im_macaddr[4], mlme.im_macaddr[5]);
1984                         break;
1985                     case IEEE80211_MLME_UNAUTHORIZE:
1986                         A_PRINTF("setmlme UNAUTHORIZE %02X:%02X\n",
1987                             mlme.im_macaddr[4], mlme.im_macaddr[5]);
1988                         break;
1989                     case IEEE80211_MLME_DEAUTH:
1990                         A_PRINTF("setmlme DEAUTH %02X:%02X\n",
1991                             mlme.im_macaddr[4], mlme.im_macaddr[5]);
1992                         //remove_sta(ar, mlme.im_macaddr);
1993                         break;
1994                     case IEEE80211_MLME_DISASSOC:
1995                         A_PRINTF("setmlme DISASSOC %02X:%02X\n",
1996                             mlme.im_macaddr[4], mlme.im_macaddr[5]);
1997                         //remove_sta(ar, mlme.im_macaddr);
1998                         break;
1999                     default:
2000                         ret = 0;
2001                         goto ioctl_done;
2002                 }
2003
2004                 wmi_ap_set_mlme(ar->arWmi, mlme.im_op, mlme.im_macaddr,
2005                                 mlme.im_reason);
2006             }
2007             break;
2008         }
2009         case IEEE80211_IOCTL_ADDPMKID:
2010         {
2011             struct ieee80211req_addpmkid  req;
2012             if (ar->arWmiReady == false) {
2013                 ret = -EIO;
2014             } else if (copy_from_user(&req, userdata, sizeof(struct ieee80211req_addpmkid))) {
2015                 ret = -EFAULT;
2016             } else {
2017                 int status;
2018
2019                 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",
2020                     req.pi_bssid[0], req.pi_bssid[1], req.pi_bssid[2],
2021                     req.pi_bssid[3], req.pi_bssid[4], req.pi_bssid[5],
2022                     req.pi_enable));
2023
2024                 status = wmi_setPmkid_cmd(ar->arWmi, req.pi_bssid, req.pi_pmkid,
2025                               req.pi_enable);
2026
2027                 if (status) {
2028                     ret = -EIO;
2029                     goto ioctl_done;
2030                 }
2031             }
2032             break;
2033         }
2034 #ifdef CONFIG_HOST_TCMD_SUPPORT
2035         case AR6000_XIOCTL_TCMD_CONT_TX:
2036             {
2037                 TCMD_CONT_TX txCmd;
2038
2039                 if ((ar->tcmdPm == TCMD_PM_SLEEP) ||
2040                     (ar->tcmdPm == TCMD_PM_DEEPSLEEP))
2041                 {
2042                     A_PRINTF("Can NOT send tx tcmd when target is asleep! \n");
2043                     ret = -EFAULT;
2044                     goto ioctl_done;
2045                 }
2046
2047                 if(copy_from_user(&txCmd, userdata, sizeof(TCMD_CONT_TX))) {
2048                     ret = -EFAULT;
2049                     goto ioctl_done;
2050                 } else {
2051                     wmi_test_cmd(ar->arWmi,(u8 *)&txCmd, sizeof(TCMD_CONT_TX));
2052                 }
2053             }
2054             break;
2055         case AR6000_XIOCTL_TCMD_CONT_RX:
2056             {
2057                 TCMD_CONT_RX rxCmd;
2058
2059                 if ((ar->tcmdPm == TCMD_PM_SLEEP) ||
2060                     (ar->tcmdPm == TCMD_PM_DEEPSLEEP))
2061                 {
2062                     A_PRINTF("Can NOT send rx tcmd when target is asleep! \n");
2063                     ret = -EFAULT;
2064                     goto ioctl_done;
2065                 }
2066                 if(copy_from_user(&rxCmd, userdata, sizeof(TCMD_CONT_RX))) {
2067                     ret = -EFAULT;
2068                     goto ioctl_done;
2069                 }
2070
2071                 switch(rxCmd.act)
2072                 {
2073                     case TCMD_CONT_RX_PROMIS:
2074                     case TCMD_CONT_RX_FILTER:
2075                     case TCMD_CONT_RX_SETMAC:
2076                     case TCMD_CONT_RX_SET_ANT_SWITCH_TABLE:
2077                          wmi_test_cmd(ar->arWmi,(u8 *)&rxCmd,
2078                                                 sizeof(TCMD_CONT_RX));
2079                          tcmdRxFreq = rxCmd.u.para.freq;
2080                          break;
2081                     case TCMD_CONT_RX_REPORT:
2082                          ar6000_ioctl_tcmd_get_rx_report(dev, rq,
2083                          (u8 *)&rxCmd, sizeof(TCMD_CONT_RX));
2084                          break;
2085                     default:
2086                          A_PRINTF("Unknown Cont Rx mode: %d\n",rxCmd.act);
2087                          ret = -EINVAL;
2088                          goto ioctl_done;
2089                 }
2090             }
2091             break;
2092         case AR6000_XIOCTL_TCMD_PM:
2093             {
2094                 TCMD_PM pmCmd;
2095
2096                 if(copy_from_user(&pmCmd, userdata, sizeof(TCMD_PM))) {
2097                     ret = -EFAULT;
2098                     goto ioctl_done;
2099                 }
2100                 ar->tcmdPm = pmCmd.mode;
2101                 wmi_test_cmd(ar->arWmi, (u8 *)&pmCmd, sizeof(TCMD_PM));
2102             }
2103             break;
2104 #endif /* CONFIG_HOST_TCMD_SUPPORT */
2105
2106         case AR6000_XIOCTL_BMI_DONE:
2107             rtnl_lock(); /* ar6000_init expects to be called holding rtnl lock */
2108             ret = ar6000_init(dev);
2109             rtnl_unlock();
2110             break;
2111
2112         case AR6000_XIOCTL_BMI_READ_MEMORY:
2113              if (get_user(address, (unsigned int *)userdata) ||
2114                 get_user(length, (unsigned int *)userdata + 1)) {
2115                 ret = -EFAULT;
2116                 break;
2117             }
2118
2119             AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Read Memory (address: 0x%x, length: %d)\n",
2120                              address, length));
2121             if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) {
2122                 A_MEMZERO(buffer, length);
2123                 ret = BMIReadMemory(hifDevice, address, buffer, length);
2124                 if (copy_to_user(rq->ifr_data, buffer, length)) {
2125                     ret = -EFAULT;
2126                 }
2127                 kfree(buffer);
2128             } else {
2129                 ret = -ENOMEM;
2130             }
2131             break;
2132
2133         case AR6000_XIOCTL_BMI_WRITE_MEMORY:
2134              if (get_user(address, (unsigned int *)userdata) ||
2135                 get_user(length, (unsigned int *)userdata + 1)) {
2136                 ret = -EFAULT;
2137                 break;
2138             }
2139             AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Write Memory (address: 0x%x, length: %d)\n",
2140                              address, length));
2141             if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) {
2142                 A_MEMZERO(buffer, length);
2143                 if (copy_from_user(buffer, &userdata[sizeof(address) +
2144                                    sizeof(length)], length))
2145                 {
2146                     ret = -EFAULT;
2147                 } else {
2148                     ret = BMIWriteMemory(hifDevice, address, buffer, length);
2149                 }
2150                 kfree(buffer);
2151             } else {
2152                 ret = -ENOMEM;
2153             }
2154             break;
2155
2156         case AR6000_XIOCTL_BMI_TEST:
2157            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("No longer supported\n"));
2158            ret = -EOPNOTSUPP;
2159            break;
2160
2161         case AR6000_XIOCTL_BMI_EXECUTE:
2162              if (get_user(address, (unsigned int *)userdata) ||
2163                 get_user(param, (unsigned int *)userdata + 1)) {
2164                 ret = -EFAULT;
2165                 break;
2166             }
2167             AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Execute (address: 0x%x, param: %d)\n",
2168                              address, param));
2169             ret = BMIExecute(hifDevice, address, (u32 *)&param);
2170             /* return value */
2171             if (put_user(param, (unsigned int *)rq->ifr_data)) {
2172                 ret = -EFAULT;
2173                 break;
2174             }
2175             break;
2176
2177         case AR6000_XIOCTL_BMI_SET_APP_START:
2178             if (get_user(address, (unsigned int *)userdata)) {
2179                 ret = -EFAULT;
2180                 break;
2181             }
2182             AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Set App Start (address: 0x%x)\n", address));
2183             ret = BMISetAppStart(hifDevice, address);
2184             break;
2185
2186         case AR6000_XIOCTL_BMI_READ_SOC_REGISTER:
2187             if (get_user(address, (unsigned int *)userdata)) {
2188                 ret = -EFAULT;
2189                 break;
2190             }
2191             ret = BMIReadSOCRegister(hifDevice, address, (u32 *)&param);
2192             /* return value */
2193             if (put_user(param, (unsigned int *)rq->ifr_data)) {
2194                 ret = -EFAULT;
2195                 break;
2196             }
2197             break;
2198
2199         case AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER:
2200             if (get_user(address, (unsigned int *)userdata) ||
2201                 get_user(param, (unsigned int *)userdata + 1)) {
2202                 ret = -EFAULT;
2203                 break;
2204             }
2205             ret = BMIWriteSOCRegister(hifDevice, address, param);
2206             break;
2207
2208 #ifdef HTC_RAW_INTERFACE
2209         case AR6000_XIOCTL_HTC_RAW_OPEN:
2210             ret = 0;
2211             if (!arRawIfEnabled(ar)) {
2212                 /* make sure block size is set in case the target was reset since last
2213                   * BMI phase (i.e. flashup downloads) */
2214                 ret = ar6000_set_htc_params(ar->arHifDevice,
2215                                             ar->arTargetType,
2216                                             0,  /* use default yield */
2217                                             0   /* use default number of HTC ctrl buffers */
2218                                             );
2219                 if (ret) {
2220                     break;
2221                 }
2222                 /* Terminate the BMI phase */
2223                 ret = BMIDone(hifDevice);
2224                 if (ret == 0) {
2225                     ret = ar6000_htc_raw_open(ar);
2226                 }
2227             }
2228             break;
2229
2230         case AR6000_XIOCTL_HTC_RAW_CLOSE:
2231             if (arRawIfEnabled(ar)) {
2232                 ret = ar6000_htc_raw_close(ar);
2233                 arRawIfEnabled(ar) = false;
2234             } else {
2235                 ret = A_ERROR;
2236             }
2237             break;
2238
2239         case AR6000_XIOCTL_HTC_RAW_READ:
2240             if (arRawIfEnabled(ar)) {
2241                 unsigned int streamID;
2242                 if (get_user(streamID, (unsigned int *)userdata) ||
2243                     get_user(length, (unsigned int *)userdata + 1)) {
2244                     ret = -EFAULT;
2245                     break;
2246                 }
2247                 buffer = (unsigned char*)rq->ifr_data + sizeof(length);
2248                 ret = ar6000_htc_raw_read(ar, (HTC_RAW_STREAM_ID)streamID,
2249                                           (char*)buffer, length);
2250                 if (put_user(ret, (unsigned int *)rq->ifr_data)) {
2251                     ret = -EFAULT;
2252                     break;
2253                 }
2254             } else {
2255                 ret = A_ERROR;
2256             }
2257             break;
2258
2259         case AR6000_XIOCTL_HTC_RAW_WRITE:
2260             if (arRawIfEnabled(ar)) {
2261                 unsigned int streamID;
2262                 if (get_user(streamID, (unsigned int *)userdata) ||
2263                     get_user(length, (unsigned int *)userdata + 1)) {
2264                     ret = -EFAULT;
2265                     break;
2266                 }
2267                 buffer = (unsigned char*)userdata + sizeof(streamID) + sizeof(length);
2268                 ret = ar6000_htc_raw_write(ar, (HTC_RAW_STREAM_ID)streamID,
2269                                            (char*)buffer, length);
2270                 if (put_user(ret, (unsigned int *)rq->ifr_data)) {
2271                     ret = -EFAULT;
2272                     break;
2273                 }
2274             } else {
2275                 ret = A_ERROR;
2276             }
2277             break;
2278 #endif /* HTC_RAW_INTERFACE */
2279
2280         case AR6000_XIOCTL_BMI_LZ_STREAM_START:
2281             if (get_user(address, (unsigned int *)userdata)) {
2282                 ret = -EFAULT;
2283                 break;
2284             }
2285             AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Start Compressed Stream (address: 0x%x)\n", address));
2286             ret = BMILZStreamStart(hifDevice, address);
2287             break;
2288
2289         case AR6000_XIOCTL_BMI_LZ_DATA:
2290             if (get_user(length, (unsigned int *)userdata)) {
2291                 ret = -EFAULT;
2292                 break;
2293             }
2294             AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Send Compressed Data (length: %d)\n", length));
2295             if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) {
2296                 A_MEMZERO(buffer, length);
2297                 if (copy_from_user(buffer, &userdata[sizeof(length)], length))
2298                 {
2299                     ret = -EFAULT;
2300                 } else {
2301                     ret = BMILZData(hifDevice, buffer, length);
2302                 }
2303                 kfree(buffer);
2304             } else {
2305                 ret = -ENOMEM;
2306             }
2307             break;
2308
2309 #if defined(CONFIG_TARGET_PROFILE_SUPPORT)
2310         /*
2311          * Optional support for Target-side profiling.
2312          * Not needed in production.
2313          */
2314
2315         /* Configure Target-side profiling */
2316         case AR6000_XIOCTL_PROF_CFG:
2317         {
2318             u32 period;
2319             u32 nbins;
2320             if (get_user(period, (unsigned int *)userdata) ||
2321                 get_user(nbins, (unsigned int *)userdata + 1)) {
2322                 ret = -EFAULT;
2323                 break;
2324             }
2325
2326             if (wmi_prof_cfg_cmd(ar->arWmi, period, nbins) != 0) {
2327                 ret = -EIO;
2328             }
2329
2330             break;
2331         }
2332
2333         /* Start a profiling bucket/bin at the specified address */
2334         case AR6000_XIOCTL_PROF_ADDR_SET:
2335         {
2336             u32 addr;
2337             if (get_user(addr, (unsigned int *)userdata)) {
2338                 ret = -EFAULT;
2339                 break;
2340             }
2341
2342             if (wmi_prof_addr_set_cmd(ar->arWmi, addr) != 0) {
2343                 ret = -EIO;
2344             }
2345
2346             break;
2347         }
2348
2349         /* START Target-side profiling */
2350         case AR6000_XIOCTL_PROF_START:
2351             wmi_prof_start_cmd(ar->arWmi);
2352             break;
2353
2354         /* STOP Target-side profiling */
2355         case AR6000_XIOCTL_PROF_STOP:
2356             wmi_prof_stop_cmd(ar->arWmi);
2357             break;
2358         case AR6000_XIOCTL_PROF_COUNT_GET:
2359         {
2360             if (ar->bIsDestroyProgress) {
2361                 ret = -EBUSY;
2362                 goto ioctl_done;
2363             }
2364             if (ar->arWmiReady == false) {
2365                 ret = -EIO;
2366                 goto ioctl_done;
2367             }
2368             if (down_interruptible(&ar->arSem)) {
2369                 ret = -ERESTARTSYS;
2370                 goto ioctl_done;
2371             }
2372             if (ar->bIsDestroyProgress) {
2373                 up(&ar->arSem);
2374                 ret = -EBUSY;
2375                 goto ioctl_done;
2376             }
2377
2378             prof_count_available = false;
2379             ret = prof_count_get(dev);
2380             if (ret != 0) {
2381                 up(&ar->arSem);
2382                 ret = -EIO;
2383                 goto ioctl_done;
2384             }
2385
2386             /* Wait for Target to respond. */
2387             wait_event_interruptible(arEvent, prof_count_available);
2388             if (signal_pending(current)) {
2389                 ret = -EINTR;
2390             } else {
2391                 if (copy_to_user(userdata, &prof_count_results,
2392                                  sizeof(prof_count_results)))
2393                 {
2394                     ret = -EFAULT;
2395                 }
2396             }
2397             up(&ar->arSem);
2398             break;
2399         }
2400 #endif /* CONFIG_TARGET_PROFILE_SUPPORT */
2401
2402         case AR6000_IOCTL_WMI_GETREV:
2403         {
2404             if (copy_to_user(rq->ifr_data, &ar->arVersion,
2405                              sizeof(ar->arVersion)))
2406             {
2407                 ret = -EFAULT;
2408             }
2409             break;
2410         }
2411         case AR6000_IOCTL_WMI_SETPWR:
2412         {
2413             WMI_POWER_MODE_CMD pwrModeCmd;
2414
2415             if (ar->arWmiReady == false) {
2416                 ret = -EIO;
2417             } else if (copy_from_user(&pwrModeCmd, userdata,
2418                                    sizeof(pwrModeCmd)))
2419             {
2420                 ret = -EFAULT;
2421             } else {
2422                 if (wmi_powermode_cmd(ar->arWmi, pwrModeCmd.powerMode)
2423                        != 0)
2424                 {
2425                     ret = -EIO;
2426                 }
2427             }
2428             break;
2429         }
2430         case AR6000_IOCTL_WMI_SET_IBSS_PM_CAPS:
2431         {
2432             WMI_IBSS_PM_CAPS_CMD ibssPmCaps;
2433
2434             if (ar->arWmiReady == false) {
2435                 ret = -EIO;
2436             } else if (copy_from_user(&ibssPmCaps, userdata,
2437                                    sizeof(ibssPmCaps)))
2438             {
2439                 ret = -EFAULT;
2440             } else {
2441                 if (wmi_ibsspmcaps_cmd(ar->arWmi, ibssPmCaps.power_saving, ibssPmCaps.ttl,
2442                     ibssPmCaps.atim_windows, ibssPmCaps.timeout_value) != 0)
2443                 {
2444                     ret = -EIO;
2445                 }
2446                 AR6000_SPIN_LOCK(&ar->arLock, 0);
2447                 ar->arIbssPsEnable = ibssPmCaps.power_saving;
2448                 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
2449             }
2450             break;
2451         }
2452         case AR6000_XIOCTL_WMI_SET_AP_PS:
2453         {
2454             WMI_AP_PS_CMD apPsCmd;
2455
2456             if (ar->arWmiReady == false) {
2457                 ret = -EIO;
2458             } else if (copy_from_user(&apPsCmd, userdata,
2459                                    sizeof(apPsCmd)))
2460             {
2461                 ret = -EFAULT;
2462             } else {
2463                 if (wmi_apps_cmd(ar->arWmi, apPsCmd.psType, apPsCmd.idle_time,
2464                     apPsCmd.ps_period, apPsCmd.sleep_period) != 0)
2465                 {
2466                     ret = -EIO;
2467                 }
2468             }
2469             break;
2470         }
2471         case AR6000_IOCTL_WMI_SET_PMPARAMS:
2472         {
2473             WMI_POWER_PARAMS_CMD pmParams;
2474
2475             if (ar->arWmiReady == false) {
2476                 ret = -EIO;
2477             } else if (copy_from_user(&pmParams, userdata,
2478                                       sizeof(pmParams)))
2479             {
2480                 ret = -EFAULT;
2481             } else {
2482                 if (wmi_pmparams_cmd(ar->arWmi, pmParams.idle_period,
2483                                      pmParams.pspoll_number,
2484                                      pmParams.dtim_policy,
2485                                      pmParams.tx_wakeup_policy,
2486                                      pmParams.num_tx_to_wakeup,
2487 #if WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN
2488                                      IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN 
2489 #else
2490                                      SEND_POWER_SAVE_FAIL_EVENT_ALWAYS
2491 #endif
2492                                      ) != 0)
2493                 {
2494                     ret = -EIO;
2495                 }
2496             }
2497             break;
2498         }
2499         case AR6000_IOCTL_WMI_SETSCAN:
2500         {
2501             if (ar->arWmiReady == false) {
2502                 ret = -EIO;
2503             } else if (copy_from_user(&ar->scParams, userdata,
2504                                       sizeof(ar->scParams)))
2505             {
2506                 ret = -EFAULT;
2507             } else {
2508                 if (CAN_SCAN_IN_CONNECT(ar->scParams.scanCtrlFlags)) {
2509                     ar->arSkipScan = false;
2510                 } else {
2511                     ar->arSkipScan = true;
2512                 }
2513
2514                 if (wmi_scanparams_cmd(ar->arWmi, ar->scParams.fg_start_period,
2515                                        ar->scParams.fg_end_period,
2516                                        ar->scParams.bg_period,
2517                                        ar->scParams.minact_chdwell_time,
2518                                        ar->scParams.maxact_chdwell_time,
2519                                        ar->scParams.pas_chdwell_time,
2520                                        ar->scParams.shortScanRatio,
2521                                        ar->scParams.scanCtrlFlags,
2522                                        ar->scParams.max_dfsch_act_time,
2523                                        ar->scParams.maxact_scan_per_ssid) != 0)
2524                 {
2525                     ret = -EIO;
2526                 }
2527             }
2528             break;
2529         }
2530         case AR6000_IOCTL_WMI_SETLISTENINT:
2531         {
2532             WMI_LISTEN_INT_CMD listenCmd;
2533
2534             if (ar->arWmiReady == false) {
2535                 ret = -EIO;
2536             } else if (copy_from_user(&listenCmd, userdata,
2537                                       sizeof(listenCmd)))
2538             {
2539                 ret = -EFAULT;
2540             } else {
2541                     if (wmi_listeninterval_cmd(ar->arWmi, listenCmd.listenInterval, listenCmd.numBeacons) != 0) {
2542                         ret = -EIO;
2543                     } else {
2544                         AR6000_SPIN_LOCK(&ar->arLock, 0);
2545                         ar->arListenIntervalT = listenCmd.listenInterval;
2546                         ar->arListenIntervalB = listenCmd.numBeacons;
2547                         AR6000_SPIN_UNLOCK(&ar->arLock, 0);
2548                     }
2549
2550                 }
2551             break;
2552         }
2553         case AR6000_IOCTL_WMI_SET_BMISS_TIME:
2554         {
2555             WMI_BMISS_TIME_CMD bmissCmd;
2556
2557             if (ar->arWmiReady == false) {
2558                 ret = -EIO;
2559             } else if (copy_from_user(&bmissCmd, userdata,
2560                                       sizeof(bmissCmd)))
2561             {
2562                 ret = -EFAULT;
2563             } else {
2564                 if (wmi_bmisstime_cmd(ar->arWmi, bmissCmd.bmissTime, bmissCmd.numBeacons) != 0) {
2565                     ret = -EIO;
2566                 }
2567             }
2568             break;
2569         }
2570         case AR6000_IOCTL_WMI_SETBSSFILTER:
2571         {
2572             WMI_BSS_FILTER_CMD filt;
2573
2574             if (ar->arWmiReady == false) {
2575                 ret = -EIO;
2576             } else if (copy_from_user(&filt, userdata,
2577                                    sizeof(filt)))
2578             {
2579                 ret = -EFAULT;
2580             } else {
2581                 if (wmi_bssfilter_cmd(ar->arWmi, filt.bssFilter, filt.ieMask)
2582                         != 0) {
2583                     ret = -EIO;
2584                 } else {
2585                     ar->arUserBssFilter = filt.bssFilter;
2586                 }
2587             }
2588             break;
2589         }
2590
2591         case AR6000_IOCTL_WMI_SET_SNRTHRESHOLD:
2592         {
2593             ret = ar6000_ioctl_set_snr_threshold(dev, rq);
2594             break;
2595         }
2596         case AR6000_XIOCTL_WMI_SET_RSSITHRESHOLD:
2597         {
2598             ret = ar6000_ioctl_set_rssi_threshold(dev, rq);
2599             break;
2600         }
2601         case AR6000_XIOCTL_WMI_CLR_RSSISNR:
2602         {
2603             if (ar->arWmiReady == false) {
2604                 ret = -EIO;
2605             }
2606             ret = wmi_clr_rssi_snr(ar->arWmi);
2607             break;
2608         }
2609         case AR6000_XIOCTL_WMI_SET_LQTHRESHOLD:
2610         {
2611             ret = ar6000_ioctl_set_lq_threshold(dev, rq);
2612             break;
2613         }
2614         case AR6000_XIOCTL_WMI_SET_LPREAMBLE:
2615         {
2616             WMI_SET_LPREAMBLE_CMD setLpreambleCmd;
2617
2618             if (ar->arWmiReady == false) {
2619                 ret = -EIO;
2620             } else if (copy_from_user(&setLpreambleCmd, userdata,
2621                                    sizeof(setLpreambleCmd)))
2622             {
2623                 ret = -EFAULT;
2624             } else {
2625                 if (wmi_set_lpreamble_cmd(ar->arWmi, setLpreambleCmd.status,
2626 #if WLAN_CONFIG_DONOT_IGNORE_BARKER_IN_ERP 
2627                            WMI_DONOT_IGNORE_BARKER_IN_ERP
2628 #else
2629                            WMI_IGNORE_BARKER_IN_ERP
2630 #endif
2631                 ) != 0)
2632                 {
2633                     ret = -EIO;
2634                 }
2635             }
2636
2637             break;
2638         }
2639         case AR6000_XIOCTL_WMI_SET_RTS:
2640         {
2641             WMI_SET_RTS_CMD rtsCmd;
2642             if (ar->arWmiReady == false) {
2643                 ret = -EIO;
2644             } else if (copy_from_user(&rtsCmd, userdata,
2645                                    sizeof(rtsCmd)))
2646             {
2647                 ret = -EFAULT;
2648             } else {
2649                 ar->arRTS = rtsCmd.threshold;
2650                 if (wmi_set_rts_cmd(ar->arWmi, rtsCmd.threshold)
2651                        != 0)
2652                 {
2653                     ret = -EIO;
2654                 }
2655             }
2656
2657             break;
2658         }
2659         case AR6000_XIOCTL_WMI_SET_WMM:
2660         {
2661             ret = ar6000_ioctl_set_wmm(dev, rq);
2662             break;
2663         }
2664        case AR6000_XIOCTL_WMI_SET_QOS_SUPP:
2665         {
2666             ret = ar6000_ioctl_set_qos_supp(dev, rq);
2667             break;
2668         }
2669         case AR6000_XIOCTL_WMI_SET_TXOP:
2670         {
2671             ret = ar6000_ioctl_set_txop(dev, rq);
2672             break;
2673         }
2674         case AR6000_XIOCTL_WMI_GET_RD:
2675         {
2676             ret = ar6000_ioctl_get_rd(dev, rq);
2677             break;
2678         }
2679         case AR6000_IOCTL_WMI_SET_CHANNELPARAMS:
2680         {
2681             ret = ar6000_ioctl_set_channelParams(dev, rq);
2682             break;
2683         }
2684         case AR6000_IOCTL_WMI_SET_PROBEDSSID:
2685         {
2686             ret = ar6000_ioctl_set_probedSsid(dev, rq);
2687             break;
2688         }
2689         case AR6000_IOCTL_WMI_SET_BADAP:
2690         {
2691             ret = ar6000_ioctl_set_badAp(dev, rq);
2692             break;
2693         }
2694         case AR6000_IOCTL_WMI_CREATE_QOS:
2695         {
2696             ret = ar6000_ioctl_create_qos(dev, rq);
2697             break;
2698         }
2699         case AR6000_IOCTL_WMI_DELETE_QOS:
2700         {
2701             ret = ar6000_ioctl_delete_qos(dev, rq);
2702             break;
2703         }
2704         case AR6000_IOCTL_WMI_GET_QOS_QUEUE:
2705         {
2706             ret = ar6000_ioctl_get_qos_queue(dev, rq);
2707             break;
2708         }
2709         case AR6000_IOCTL_WMI_GET_TARGET_STATS:
2710         {
2711             ret = ar6000_ioctl_get_target_stats(dev, rq);
2712             break;
2713         }
2714         case AR6000_IOCTL_WMI_SET_ERROR_REPORT_BITMASK:
2715         {
2716             ret = ar6000_ioctl_set_error_report_bitmask(dev, rq);
2717             break;
2718         }
2719         case AR6000_IOCTL_WMI_SET_ASSOC_INFO:
2720         {
2721             WMI_SET_ASSOC_INFO_CMD cmd;
2722             u8 assocInfo[WMI_MAX_ASSOC_INFO_LEN];
2723
2724             if (ar->arWmiReady == false) {
2725                 ret = -EIO;
2726                 break;
2727             }
2728
2729             if (get_user(cmd.ieType, userdata)) {
2730                 ret = -EFAULT;
2731                 break;
2732             }
2733             if (cmd.ieType >= WMI_MAX_ASSOC_INFO_TYPE) {
2734                 ret = -EIO;
2735                 break;
2736             }
2737
2738             if (get_user(cmd.bufferSize, userdata + 1) ||
2739                 (cmd.bufferSize > WMI_MAX_ASSOC_INFO_LEN) ||
2740                 copy_from_user(assocInfo, userdata + 2, cmd.bufferSize)) {
2741                 ret = -EFAULT;
2742                 break;
2743             }
2744             if (wmi_associnfo_cmd(ar->arWmi, cmd.ieType,
2745                                   cmd.bufferSize, assocInfo) != 0) {
2746                 ret = -EIO;
2747                 break;
2748             }
2749             break;
2750         }
2751         case AR6000_IOCTL_WMI_SET_ACCESS_PARAMS:
2752         {
2753             ret = ar6000_ioctl_set_access_params(dev, rq);
2754             break;
2755         }
2756         case AR6000_IOCTL_WMI_SET_DISC_TIMEOUT:
2757         {
2758             ret = ar6000_ioctl_set_disconnect_timeout(dev, rq);
2759             break;
2760         }
2761         case AR6000_XIOCTL_FORCE_TARGET_RESET:
2762         {
2763             if (ar->arHtcTarget)
2764             {
2765 //                HTCForceReset(htcTarget);
2766             }
2767             else
2768             {
2769                 AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("ar6000_ioctl cannot attempt reset.\n"));
2770             }
2771             break;
2772         }
2773         case AR6000_XIOCTL_TARGET_INFO:
2774         case AR6000_XIOCTL_CHECK_TARGET_READY: /* backwards compatibility */
2775         {
2776             /* If we made it to here, then the Target exists and is ready. */
2777
2778             if (cmd == AR6000_XIOCTL_TARGET_INFO) {
2779                 if (copy_to_user((u32 *)rq->ifr_data, &ar->arVersion.target_ver,
2780                                  sizeof(ar->arVersion.target_ver)))
2781                 {
2782                     ret = -EFAULT;
2783                 }
2784                 if (copy_to_user(((u32 *)rq->ifr_data)+1, &ar->arTargetType,
2785                                  sizeof(ar->arTargetType)))
2786                 {
2787                     ret = -EFAULT;
2788                 }
2789             }
2790             break;
2791         }
2792         case AR6000_XIOCTL_WMI_SET_HB_CHALLENGE_RESP_PARAMS:
2793         {
2794             WMI_SET_HB_CHALLENGE_RESP_PARAMS_CMD hbparam;
2795
2796             if (copy_from_user(&hbparam, userdata, sizeof(hbparam)))
2797             {
2798                 ret = -EFAULT;
2799             } else {
2800                 AR6000_SPIN_LOCK(&ar->arLock, 0);
2801                 /* Start a cyclic timer with the parameters provided. */
2802                 if (hbparam.frequency) {
2803                     ar->arHBChallengeResp.frequency = hbparam.frequency;
2804                 }
2805                 if (hbparam.threshold) {
2806                     ar->arHBChallengeResp.missThres = hbparam.threshold;
2807                 }
2808
2809                 /* Delete the pending timer and start a new one */
2810                 if (timer_pending(&ar->arHBChallengeResp.timer)) {
2811                     A_UNTIMEOUT(&ar->arHBChallengeResp.timer);
2812                 }
2813                 A_TIMEOUT_MS(&ar->arHBChallengeResp.timer, ar->arHBChallengeResp.frequency * 1000, 0);
2814                 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
2815             }
2816             break;
2817         }
2818         case AR6000_XIOCTL_WMI_GET_HB_CHALLENGE_RESP:
2819         {
2820             u32 cookie;
2821
2822             if (copy_from_user(&cookie, userdata, sizeof(cookie))) {
2823                 ret = -EFAULT;
2824                 goto ioctl_done;
2825             }
2826
2827             /* Send the challenge on the control channel */
2828             if (wmi_get_challenge_resp_cmd(ar->arWmi, cookie, APP_HB_CHALLENGE) != 0) {
2829                 ret = -EIO;
2830                 goto ioctl_done;
2831             }
2832             break;
2833         }
2834 #ifdef USER_KEYS
2835         case AR6000_XIOCTL_USER_SETKEYS:
2836         {
2837
2838             ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_RUN;
2839
2840             if (copy_from_user(&ar->user_key_ctrl, userdata,
2841                                sizeof(ar->user_key_ctrl)))
2842             {
2843                 ret = -EFAULT;
2844                 goto ioctl_done;
2845             }
2846
2847             A_PRINTF("ar6000 USER set key %x\n", ar->user_key_ctrl);
2848             break;
2849         }
2850 #endif /* USER_KEYS */
2851
2852 #ifdef CONFIG_HOST_GPIO_SUPPORT
2853         case AR6000_XIOCTL_GPIO_OUTPUT_SET:
2854         {
2855             struct ar6000_gpio_output_set_cmd_s gpio_output_set_cmd;
2856
2857             if (ar->bIsDestroyProgress) {
2858                 ret = -EBUSY;
2859                 goto ioctl_done;
2860             }
2861             if (ar->arWmiReady == false) {
2862                 ret = -EIO;
2863                 goto ioctl_done;
2864             }
2865             if (down_interruptible(&ar->arSem)) {
2866                 ret = -ERESTARTSYS;
2867                 goto ioctl_done;
2868             }
2869             if (ar->bIsDestroyProgress) {
2870                 up(&ar->arSem);
2871                 ret = -EBUSY;
2872                 goto ioctl_done;
2873             }
2874
2875             if (copy_from_user(&gpio_output_set_cmd, userdata,
2876                                 sizeof(gpio_output_set_cmd)))
2877             {
2878                 ret = -EFAULT;
2879             } else {
2880                 ret = ar6000_gpio_output_set(dev,
2881                                              gpio_output_set_cmd.set_mask,
2882                                              gpio_output_set_cmd.clear_mask,
2883                                              gpio_output_set_cmd.enable_mask,
2884                                              gpio_output_set_cmd.disable_mask);
2885                 if (ret != 0) {
2886                     ret = -EIO;
2887                 }
2888             }
2889             up(&ar->arSem);
2890             break;
2891         }
2892         case AR6000_XIOCTL_GPIO_INPUT_GET:
2893         {
2894             if (ar->bIsDestroyProgress) {
2895                 ret = -EBUSY;
2896                 goto ioctl_done;
2897             }
2898             if (ar->arWmiReady == false) {
2899                 ret = -EIO;
2900                 goto ioctl_done;
2901             }
2902             if (down_interruptible(&ar->arSem)) {
2903                 ret = -ERESTARTSYS;
2904                 goto ioctl_done;
2905             }
2906             if (ar->bIsDestroyProgress) {
2907                 up(&ar->arSem);
2908                 ret = -EBUSY;
2909                 goto ioctl_done;
2910             }
2911
2912             ret = ar6000_gpio_input_get(dev);
2913             if (ret != 0) {
2914                 up(&ar->arSem);
2915                 ret = -EIO;
2916                 goto ioctl_done;
2917             }
2918
2919             /* Wait for Target to respond. */
2920             wait_event_interruptible(arEvent, gpio_data_available);
2921             if (signal_pending(current)) {
2922                 ret = -EINTR;
2923             } else {
2924                 A_ASSERT(gpio_reg_results.gpioreg_id == GPIO_ID_NONE);
2925
2926                 if (copy_to_user(userdata, &gpio_reg_results.value,
2927                                  sizeof(gpio_reg_results.value)))
2928                 {
2929                     ret = -EFAULT;
2930                 }
2931             }
2932             up(&ar->arSem);
2933             break;
2934         }
2935         case AR6000_XIOCTL_GPIO_REGISTER_SET:
2936         {
2937             struct ar6000_gpio_register_cmd_s gpio_register_cmd;
2938
2939             if (ar->bIsDestroyProgress) {
2940                 ret = -EBUSY;
2941                 goto ioctl_done;
2942             }
2943             if (ar->arWmiReady == false) {
2944                 ret = -EIO;
2945                 goto ioctl_done;
2946             }
2947             if (down_interruptible(&ar->arSem)) {
2948                 ret = -ERESTARTSYS;
2949                 goto ioctl_done;
2950             }
2951             if (ar->bIsDestroyProgress) {
2952                 up(&ar->arSem);
2953                 ret = -EBUSY;
2954                 goto ioctl_done;
2955             }
2956
2957             if (copy_from_user(&gpio_register_cmd, userdata,
2958                                 sizeof(gpio_register_cmd)))
2959             {
2960                 ret = -EFAULT;
2961             } else {
2962                 ret = ar6000_gpio_register_set(dev,
2963                                                gpio_register_cmd.gpioreg_id,
2964                                                gpio_register_cmd.value);
2965                 if (ret != 0) {
2966                     ret = -EIO;
2967                 }
2968
2969                 /* Wait for acknowledgement from Target */
2970                 wait_event_interruptible(arEvent, gpio_ack_received);
2971                 if (signal_pending(current)) {
2972                     ret = -EINTR;
2973                 }
2974             }
2975             up(&ar->arSem);
2976             break;
2977         }
2978         case AR6000_XIOCTL_GPIO_REGISTER_GET:
2979         {
2980             struct ar6000_gpio_register_cmd_s gpio_register_cmd;
2981
2982             if (ar->bIsDestroyProgress) {
2983                 ret = -EBUSY;
2984                 goto ioctl_done;
2985             }
2986             if (ar->arWmiReady == false) {
2987                 ret = -EIO;
2988                 goto ioctl_done;
2989             }
2990             if (down_interruptible(&ar->arSem)) {
2991                 ret = -ERESTARTSYS;
2992                 goto ioctl_done;
2993             }
2994             if (ar->bIsDestroyProgress) {
2995                 up(&ar->arSem);
2996                 ret = -EBUSY;
2997                 goto ioctl_done;
2998             }
2999
3000             if (copy_from_user(&gpio_register_cmd, userdata,
3001                                 sizeof(gpio_register_cmd)))
3002             {
3003                 ret = -EFAULT;
3004             } else {
3005                 ret = ar6000_gpio_register_get(dev, gpio_register_cmd.gpioreg_id);
3006                 if (ret != 0) {
3007                     up(&ar->arSem);
3008                     ret = -EIO;
3009                     goto ioctl_done;
3010                 }
3011
3012                 /* Wait for Target to respond. */
3013                 wait_event_interruptible(arEvent, gpio_data_available);
3014                 if (signal_pending(current)) {
3015                     ret = -EINTR;
3016                 } else {
3017                     A_ASSERT(gpio_register_cmd.gpioreg_id == gpio_reg_results.gpioreg_id);
3018                     if (copy_to_user(userdata, &gpio_reg_results,
3019                                      sizeof(gpio_reg_results)))
3020                     {
3021                         ret = -EFAULT;
3022                     }
3023                 }
3024             }
3025             up(&ar->arSem);
3026             break;
3027         }
3028         case AR6000_XIOCTL_GPIO_INTR_ACK:
3029         {
3030             struct ar6000_gpio_intr_ack_cmd_s gpio_intr_ack_cmd;
3031
3032             if (ar->bIsDestroyProgress) {
3033                 ret = -EBUSY;
3034                 goto ioctl_done;
3035             }
3036             if (ar->arWmiReady == false) {
3037                 ret = -EIO;
3038                 goto ioctl_done;
3039             }
3040             if (down_interruptible(&ar->arSem)) {
3041                 ret = -ERESTARTSYS;
3042                 goto ioctl_done;
3043             }
3044             if (ar->bIsDestroyProgress) {
3045                 up(&ar->arSem);
3046                 ret = -EBUSY;
3047                 goto ioctl_done;
3048             }
3049
3050             if (copy_from_user(&gpio_intr_ack_cmd, userdata,
3051                                 sizeof(gpio_intr_ack_cmd)))
3052             {
3053                 ret = -EFAULT;
3054             } else {
3055                 ret = ar6000_gpio_intr_ack(dev, gpio_intr_ack_cmd.ack_mask);
3056                 if (ret != 0) {
3057                     ret = -EIO;
3058                 }
3059             }
3060             up(&ar->arSem);
3061             break;
3062         }
3063         case AR6000_XIOCTL_GPIO_INTR_WAIT:
3064         {
3065             /* Wait for Target to report an interrupt. */
3066             wait_event_interruptible(arEvent, gpio_intr_available);
3067
3068             if (signal_pending(current)) {
3069                 ret = -EINTR;
3070             } else {
3071                 if (copy_to_user(userdata, &gpio_intr_results,
3072                                  sizeof(gpio_intr_results)))
3073                 {
3074                     ret = -EFAULT;
3075                 }
3076             }
3077             break;
3078         }
3079 #endif /* CONFIG_HOST_GPIO_SUPPORT */
3080
3081         case AR6000_XIOCTL_DBGLOG_CFG_MODULE:
3082         {
3083             struct ar6000_dbglog_module_config_s config;
3084
3085             if (copy_from_user(&config, userdata, sizeof(config))) {
3086                 ret = -EFAULT;
3087                 goto ioctl_done;
3088             }
3089
3090             /* Send the challenge on the control channel */
3091             if (wmi_config_debug_module_cmd(ar->arWmi, config.mmask,
3092                                             config.tsr, config.rep,
3093                                             config.size, config.valid) != 0)
3094             {
3095                 ret = -EIO;
3096                 goto ioctl_done;
3097             }
3098             break;
3099         }
3100
3101         case AR6000_XIOCTL_DBGLOG_GET_DEBUG_LOGS:
3102         {
3103             /* Send the challenge on the control channel */
3104             if (ar6000_dbglog_get_debug_logs(ar) != 0)
3105             {
3106                 ret = -EIO;
3107                 goto ioctl_done;
3108             }
3109             break;
3110         }
3111
3112         case AR6000_XIOCTL_SET_ADHOC_BSSID:
3113         {
3114             WMI_SET_ADHOC_BSSID_CMD adhocBssid;
3115
3116             if (ar->arWmiReady == false) {
3117                 ret = -EIO;
3118             } else if (copy_from_user(&adhocBssid, userdata,
3119                                       sizeof(adhocBssid)))
3120             {
3121                 ret = -EFAULT;
3122             } else if (memcmp(adhocBssid.bssid, bcast_mac,
3123                                 AR6000_ETH_ADDR_LEN) == 0)
3124             {
3125                 ret = -EFAULT;
3126             } else {
3127
3128                 memcpy(ar->arReqBssid, adhocBssid.bssid, sizeof(ar->arReqBssid));
3129         }
3130             break;
3131         }
3132
3133         case AR6000_XIOCTL_SET_OPT_MODE:
3134         {
3135         WMI_SET_OPT_MODE_CMD optModeCmd;
3136             struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
3137
3138             if (ar->arWmiReady == false) {
3139                 ret = -EIO;
3140             } else if (copy_from_user(&optModeCmd, userdata,
3141                                       sizeof(optModeCmd)))
3142             {
3143                 ret = -EFAULT;
3144             } else if (ar->arConnected && optModeCmd.optMode == SPECIAL_ON) {
3145                 ret = -EFAULT;
3146
3147             } else if (wmi_set_opt_mode_cmd(ar->arWmi, optModeCmd.optMode)
3148                        != 0)
3149             {
3150                 ret = -EIO;
3151             }
3152             break;
3153         }
3154
3155         case AR6000_XIOCTL_OPT_SEND_FRAME:
3156         {
3157             WMI_OPT_TX_FRAME_CMD optTxFrmCmd;
3158             u8 data[MAX_OPT_DATA_LEN];
3159
3160             if (ar->arWmiReady == false) {
3161                 ret = -EIO;
3162                 break;
3163             }
3164
3165             if (copy_from_user(&optTxFrmCmd, userdata, sizeof(optTxFrmCmd))) {
3166                 ret = -EFAULT;
3167                 break;
3168             }
3169
3170             if (optTxFrmCmd.optIEDataLen > MAX_OPT_DATA_LEN) {
3171                 ret = -EINVAL;
3172                 break;
3173             }
3174
3175             if (copy_from_user(data, userdata+sizeof(WMI_OPT_TX_FRAME_CMD) - 1,
3176                                    optTxFrmCmd.optIEDataLen)) {
3177                 ret = -EFAULT;
3178                 break;
3179             }
3180
3181             ret = wmi_opt_tx_frame_cmd(ar->arWmi,
3182                                            optTxFrmCmd.frmType,
3183                                            optTxFrmCmd.dstAddr,
3184                                            optTxFrmCmd.bssid,
3185                                            optTxFrmCmd.optIEDataLen,
3186                                            data);
3187             break;
3188         }
3189         case AR6000_XIOCTL_WMI_SETRETRYLIMITS:
3190         {
3191             WMI_SET_RETRY_LIMITS_CMD setRetryParams;
3192
3193             if (ar->arWmiReady == false) {
3194                 ret = -EIO;
3195             } else if (copy_from_user(&setRetryParams, userdata,
3196                                       sizeof(setRetryParams)))
3197             {
3198                 ret = -EFAULT;
3199             } else {
3200                 if (wmi_set_retry_limits_cmd(ar->arWmi, setRetryParams.frameType,
3201                                           setRetryParams.trafficClass,
3202                                           setRetryParams.maxRetries,
3203                                           setRetryParams.enableNotify) != 0)
3204                 {
3205                     ret = -EIO;
3206                 }
3207                 AR6000_SPIN_LOCK(&ar->arLock, 0);
3208                 ar->arMaxRetries = setRetryParams.maxRetries;
3209                 AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3210             }
3211             break;
3212         }
3213
3214         case AR6000_XIOCTL_SET_BEACON_INTVAL:
3215         {
3216             WMI_BEACON_INT_CMD bIntvlCmd;
3217
3218             if (ar->arWmiReady == false) {
3219                 ret = -EIO;
3220             } else if (copy_from_user(&bIntvlCmd, userdata,
3221                        sizeof(bIntvlCmd)))
3222             {
3223                 ret = -EFAULT;
3224             } else if (wmi_set_adhoc_bconIntvl_cmd(ar->arWmi, bIntvlCmd.beaconInterval)
3225                         != 0)
3226             {
3227                 ret = -EIO;
3228             }
3229             if(ret == 0) {
3230                 ar->ap_beacon_interval = bIntvlCmd.beaconInterval;
3231                 ar->ap_profile_flag = 1; /* There is a change in profile */
3232             }
3233             break;
3234         }
3235         case IEEE80211_IOCTL_SETAUTHALG:
3236         {
3237             struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
3238             struct ieee80211req_authalg req;
3239
3240             if (ar->arWmiReady == false) {
3241                 ret = -EIO;
3242             } else if (copy_from_user(&req, userdata,
3243                        sizeof(struct ieee80211req_authalg)))
3244             {
3245                 ret = -EFAULT;
3246             } else {
3247                 if (req.auth_alg & AUTH_ALG_OPEN_SYSTEM) {
3248                     ar->arDot11AuthMode  |= OPEN_AUTH;
3249                     ar->arPairwiseCrypto  = NONE_CRYPT;
3250                     ar->arGroupCrypto     = NONE_CRYPT;
3251                 }
3252                 if (req.auth_alg & AUTH_ALG_SHARED_KEY) {
3253                     ar->arDot11AuthMode  |= SHARED_AUTH;
3254                     ar->arPairwiseCrypto  = WEP_CRYPT;
3255                     ar->arGroupCrypto     = WEP_CRYPT;
3256                     ar->arAuthMode        = NONE_AUTH;
3257                 }
3258                 if (req.auth_alg == AUTH_ALG_LEAP) {
3259                     ar->arDot11AuthMode   = LEAP_AUTH;
3260                 }
3261             }
3262             break;
3263         }
3264
3265         case AR6000_XIOCTL_SET_VOICE_PKT_SIZE:
3266             ret = ar6000_xioctl_set_voice_pkt_size(dev, userdata);
3267             break;
3268
3269         case AR6000_XIOCTL_SET_MAX_SP:
3270             ret = ar6000_xioctl_set_max_sp_len(dev, userdata);
3271             break;
3272
3273         case AR6000_XIOCTL_WMI_GET_ROAM_TBL:
3274             ret = ar6000_ioctl_get_roam_tbl(dev, rq);
3275             break;
3276         case AR6000_XIOCTL_WMI_SET_ROAM_CTRL:
3277             ret = ar6000_ioctl_set_roam_ctrl(dev, userdata);
3278             break;
3279         case AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS:
3280             ret = ar6000_ioctl_set_powersave_timers(dev, userdata);
3281             break;
3282         case AR6000_XIOCTRL_WMI_GET_POWER_MODE:
3283             ret = ar6000_ioctl_get_power_mode(dev, rq);
3284             break;
3285         case AR6000_XIOCTRL_WMI_SET_WLAN_STATE:
3286         {
3287             AR6000_WLAN_STATE state;
3288             if (get_user(state, (unsigned int *)userdata))
3289                 ret = -EFAULT;
3290             else if (ar6000_set_wlan_state(ar, state) != 0)
3291                 ret = -EIO;
3292             break;
3293         }
3294         case AR6000_XIOCTL_WMI_GET_ROAM_DATA:
3295             ret = ar6000_ioctl_get_roam_data(dev, rq);
3296             break;
3297
3298         case AR6000_XIOCTL_WMI_SET_BT_STATUS:
3299             ret = ar6000_xioctl_set_bt_status_cmd(dev, userdata);
3300             break;
3301
3302         case AR6000_XIOCTL_WMI_SET_BT_PARAMS:
3303             ret = ar6000_xioctl_set_bt_params_cmd(dev, userdata);
3304             break;
3305
3306                 case AR6000_XIOCTL_WMI_SET_BTCOEX_FE_ANT:
3307                         ret = ar6000_xioctl_set_btcoex_fe_ant_cmd(dev, userdata);
3308                         break;
3309
3310                 case AR6000_XIOCTL_WMI_SET_BTCOEX_COLOCATED_BT_DEV:
3311                         ret = ar6000_xioctl_set_btcoex_colocated_bt_dev_cmd(dev, userdata);
3312                         break;
3313
3314                 case AR6000_XIOCTL_WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG:
3315                         ret = ar6000_xioctl_set_btcoex_btinquiry_page_config_cmd(dev, userdata);
3316                         break;
3317
3318                 case AR6000_XIOCTL_WMI_SET_BTCOEX_SCO_CONFIG:
3319                         ret = ar6000_xioctl_set_btcoex_sco_config_cmd( dev, userdata);
3320                         break;
3321
3322                 case AR6000_XIOCTL_WMI_SET_BTCOEX_A2DP_CONFIG:
3323                         ret = ar6000_xioctl_set_btcoex_a2dp_config_cmd(dev, userdata);
3324                         break;
3325
3326                 case AR6000_XIOCTL_WMI_SET_BTCOEX_ACLCOEX_CONFIG:
3327                         ret = ar6000_xioctl_set_btcoex_aclcoex_config_cmd(dev, userdata);
3328                         break;
3329
3330                 case AR6000_XIOCTL_WMI_SET_BTCOEX_DEBUG:
3331                         ret = ar60000_xioctl_set_btcoex_debug_cmd(dev, userdata);
3332                         break;
3333
3334                 case AR6000_XIOCTL_WMI_SET_BT_OPERATING_STATUS:
3335                         ret = ar6000_xioctl_set_btcoex_bt_operating_status_cmd(dev, userdata);
3336                         break;
3337
3338                 case AR6000_XIOCTL_WMI_GET_BTCOEX_CONFIG:
3339                         ret = ar6000_xioctl_get_btcoex_config_cmd(dev, userdata, rq);
3340                         break;
3341
3342                 case AR6000_XIOCTL_WMI_GET_BTCOEX_STATS:
3343                         ret = ar6000_xioctl_get_btcoex_stats_cmd(dev, userdata, rq);
3344                         break;
3345
3346         case AR6000_XIOCTL_WMI_STARTSCAN:
3347         {
3348             WMI_START_SCAN_CMD setStartScanCmd, *cmdp;
3349
3350             if (ar->arWmiReady == false) {
3351                     ret = -EIO;
3352                 } else if (copy_from_user(&setStartScanCmd, userdata,
3353                                           sizeof(setStartScanCmd)))
3354                 {
3355                     ret = -EFAULT;
3356                 } else {
3357                     if (setStartScanCmd.numChannels > 1) {
3358                         cmdp = A_MALLOC(130);
3359                         if (copy_from_user(cmdp, userdata,
3360                                            sizeof (*cmdp) +
3361                                            ((setStartScanCmd.numChannels - 1) *
3362                                            sizeof(u16))))
3363                         {
3364                             kfree(cmdp);
3365                             ret = -EFAULT;
3366                             goto ioctl_done;
3367                         }
3368                     } else {
3369                         cmdp = &setStartScanCmd;
3370                     }
3371
3372                     if (wmi_startscan_cmd(ar->arWmi, cmdp->scanType,
3373                                           cmdp->forceFgScan,
3374                                           cmdp->isLegacy,
3375                                           cmdp->homeDwellTime,
3376                                           cmdp->forceScanInterval,
3377                                           cmdp->numChannels,
3378                                           cmdp->channelList) != 0)
3379                     {
3380                         ret = -EIO;
3381                     }
3382                 }
3383             break;
3384         }
3385         case AR6000_XIOCTL_WMI_SETFIXRATES:
3386         {
3387             WMI_FIX_RATES_CMD setFixRatesCmd;
3388             int returnStatus;
3389
3390             if (ar->arWmiReady == false) {
3391                     ret = -EIO;
3392                 } else if (copy_from_user(&setFixRatesCmd, userdata,
3393                                           sizeof(setFixRatesCmd)))
3394                 {
3395                     ret = -EFAULT;
3396                 } else {
3397                     returnStatus = wmi_set_fixrates_cmd(ar->arWmi, setFixRatesCmd.fixRateMask);
3398                     if (returnStatus == A_EINVAL) {
3399                         ret = -EINVAL;
3400                     } else if(returnStatus != 0) {
3401                         ret = -EIO;
3402                     } else {
3403                         ar->ap_profile_flag = 1; /* There is a change in profile */
3404                     }
3405                 }
3406             break;
3407         }
3408
3409         case AR6000_XIOCTL_WMI_GETFIXRATES:
3410         {
3411             WMI_FIX_RATES_CMD getFixRatesCmd;
3412             struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
3413             int ret = 0;
3414
3415             if (ar->bIsDestroyProgress) {
3416                 ret = -EBUSY;
3417                 goto ioctl_done;
3418             }
3419             if (ar->arWmiReady == false) {
3420                 ret = -EIO;
3421                 goto ioctl_done;
3422             }
3423
3424             if (down_interruptible(&ar->arSem)) {
3425                 ret = -ERESTARTSYS;
3426                 goto ioctl_done;
3427             }
3428             if (ar->bIsDestroyProgress) {
3429                 up(&ar->arSem);
3430                 ret = -EBUSY;
3431                 goto ioctl_done;
3432             }
3433             /* Used copy_from_user/copy_to_user to access user space data */
3434             if (copy_from_user(&getFixRatesCmd, userdata, sizeof(getFixRatesCmd))) {
3435                 ret = -EFAULT;
3436             } else {
3437                 ar->arRateMask = 0xFFFFFFFF;
3438
3439                 if (wmi_get_ratemask_cmd(ar->arWmi) != 0) {
3440                     up(&ar->arSem);
3441                     ret = -EIO;
3442                     goto ioctl_done;
3443                 }
3444
3445                 wait_event_interruptible_timeout(arEvent, ar->arRateMask != 0xFFFFFFFF, wmitimeout * HZ);
3446
3447                 if (signal_pending(current)) {
3448                     ret = -EINTR;
3449                 }
3450
3451                 if (!ret) {
3452                     getFixRatesCmd.fixRateMask = ar->arRateMask;
3453                 }
3454
3455                 if(copy_to_user(userdata, &getFixRatesCmd, sizeof(getFixRatesCmd))) {
3456                    ret = -EFAULT;
3457                 }
3458
3459                 up(&ar->arSem);
3460             }
3461             break;
3462         }
3463         case AR6000_XIOCTL_WMI_SET_AUTHMODE:
3464         {
3465             WMI_SET_AUTH_MODE_CMD setAuthMode;
3466
3467             if (ar->arWmiReady == false) {
3468                 ret = -EIO;
3469             } else if (copy_from_user(&setAuthMode, userdata,
3470                                       sizeof(setAuthMode)))
3471             {
3472                 ret = -EFAULT;
3473             } else {
3474                 if (wmi_set_authmode_cmd(ar->arWmi, setAuthMode.mode) != 0)
3475                 {
3476                     ret = -EIO;
3477                 }
3478             }
3479             break;
3480         }
3481         case AR6000_XIOCTL_WMI_SET_REASSOCMODE:
3482         {
3483             WMI_SET_REASSOC_MODE_CMD setReassocMode;
3484
3485             if (ar->arWmiReady == false) {
3486                 ret = -EIO;
3487             } else if (copy_from_user(&setReassocMode, userdata,
3488                                       sizeof(setReassocMode)))
3489             {
3490                 ret = -EFAULT;
3491             } else {
3492                 if (wmi_set_reassocmode_cmd(ar->arWmi, setReassocMode.mode) != 0)
3493                 {
3494                     ret = -EIO;
3495                 }
3496             }
3497             break;
3498         }
3499         case AR6000_XIOCTL_DIAG_READ:
3500         {
3501             u32 addr, data;
3502             if (get_user(addr, (unsigned int *)userdata)) {
3503                 ret = -EFAULT;
3504                 break;
3505             }
3506             addr = TARG_VTOP(ar->arTargetType, addr);
3507             if (ar6000_ReadRegDiag(ar->arHifDevice, &addr, &data) != 0) {
3508                 ret = -EIO;
3509             }
3510             if (put_user(data, (unsigned int *)userdata + 1)) {
3511                 ret = -EFAULT;
3512                 break;
3513             }
3514             break;
3515         }
3516         case AR6000_XIOCTL_DIAG_WRITE:
3517         {
3518             u32 addr, data;
3519             if (get_user(addr, (unsigned int *)userdata) ||
3520                 get_user(data, (unsigned int *)userdata + 1)) {
3521                 ret = -EFAULT;
3522                 break;
3523             }
3524             addr = TARG_VTOP(ar->arTargetType, addr);
3525             if (ar6000_WriteRegDiag(ar->arHifDevice, &addr, &data) != 0) {
3526                 ret = -EIO;
3527             }
3528             break;
3529         }
3530         case AR6000_XIOCTL_WMI_SET_KEEPALIVE:
3531         {
3532              WMI_SET_KEEPALIVE_CMD setKeepAlive;
3533              if (ar->arWmiReady == false) {
3534                  ret = -EIO;
3535                  goto ioctl_done;
3536              } else if (copy_from_user(&setKeepAlive, userdata,
3537                         sizeof(setKeepAlive))){
3538                  ret = -EFAULT;
3539              } else {
3540                  if (wmi_set_keepalive_cmd(ar->arWmi, setKeepAlive.keepaliveInterval) != 0) {
3541                      ret = -EIO;
3542                }
3543              }
3544              break;
3545         }
3546         case AR6000_XIOCTL_WMI_SET_PARAMS:
3547         {
3548              WMI_SET_PARAMS_CMD cmd;
3549              if (ar->arWmiReady == false) {
3550                  ret = -EIO;
3551                  goto ioctl_done;
3552              } else if (copy_from_user(&cmd, userdata,
3553                         sizeof(cmd))){
3554                  ret = -EFAULT;
3555              } else if (copy_from_user(&cmd, userdata,
3556                         sizeof(cmd) + cmd.length))
3557             {
3558                 ret = -EFAULT;
3559             } else {
3560                  if (wmi_set_params_cmd(ar->arWmi, cmd.opcode, cmd.length, cmd.buffer) != 0) {
3561                      ret = -EIO;
3562                }
3563              }
3564              break;
3565         }
3566         case AR6000_XIOCTL_WMI_SET_MCAST_FILTER:
3567         {
3568              WMI_SET_MCAST_FILTER_CMD cmd;
3569              if (ar->arWmiReady == false) {
3570                  ret = -EIO;
3571                  goto ioctl_done;
3572              } else if (copy_from_user(&cmd, userdata,
3573                         sizeof(cmd))){
3574                  ret = -EFAULT;
3575              } else {
3576                  if (wmi_set_mcast_filter_cmd(ar->arWmi, cmd.multicast_mac[0],
3577                                                                                      cmd.multicast_mac[1],
3578                                                                                      cmd.multicast_mac[2],
3579                                                                                      cmd.multicast_mac[3]) != 0) {
3580                      ret = -EIO;
3581                }
3582              }
3583              break;
3584         }
3585         case AR6000_XIOCTL_WMI_DEL_MCAST_FILTER:
3586         {
3587              WMI_SET_MCAST_FILTER_CMD cmd;
3588              if (ar->arWmiReady == false) {
3589                  ret = -EIO;
3590                  goto ioctl_done;
3591              } else if (copy_from_user(&cmd, userdata,
3592                         sizeof(cmd))){
3593                  ret = -EFAULT;
3594              } else {
3595                  if (wmi_del_mcast_filter_cmd(ar->arWmi, cmd.multicast_mac[0],
3596                                                                                      cmd.multicast_mac[1],
3597                                                                                      cmd.multicast_mac[2],
3598                                                                                      cmd.multicast_mac[3]) != 0) {
3599                      ret = -EIO;
3600                }
3601              }
3602              break;
3603         }
3604         case AR6000_XIOCTL_WMI_MCAST_FILTER:
3605         {
3606              WMI_MCAST_FILTER_CMD cmd;
3607              if (ar->arWmiReady == false) {
3608                  ret = -EIO;
3609                  goto ioctl_done;
3610              } else if (copy_from_user(&cmd, userdata,
3611                         sizeof(cmd))){
3612                  ret = -EFAULT;
3613              } else {
3614                  if (wmi_mcast_filter_cmd(ar->arWmi, cmd.enable)  != 0) {
3615                      ret = -EIO;
3616                }
3617              }
3618              break;
3619         }
3620         case AR6000_XIOCTL_WMI_GET_KEEPALIVE:
3621         {
3622             struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
3623             WMI_GET_KEEPALIVE_CMD getKeepAlive;
3624             int ret = 0;
3625             if (ar->bIsDestroyProgress) {
3626                 ret =-EBUSY;
3627                 goto ioctl_done;
3628             }
3629             if (ar->arWmiReady == false) {
3630                ret = -EIO;
3631                goto ioctl_done;
3632             }
3633             if (down_interruptible(&ar->arSem)) {
3634                 ret = -ERESTARTSYS;
3635                 goto ioctl_done;
3636             }
3637             if (ar->bIsDestroyProgress) {
3638                 up(&ar->arSem);
3639                 ret = -EBUSY;
3640                 goto ioctl_done;
3641             }
3642             if (copy_from_user(&getKeepAlive, userdata,sizeof(getKeepAlive))) {
3643                ret = -EFAULT;
3644             } else {
3645             getKeepAlive.keepaliveInterval = wmi_get_keepalive_cmd(ar->arWmi);
3646             ar->arKeepaliveConfigured = 0xFF;
3647             if (wmi_get_keepalive_configured(ar->arWmi) != 0){
3648                 up(&ar->arSem);
3649                 ret = -EIO;
3650                 goto ioctl_done;
3651             }
3652             wait_event_interruptible_timeout(arEvent, ar->arKeepaliveConfigured != 0xFF, wmitimeout * HZ);
3653             if (signal_pending(current)) {
3654                 ret = -EINTR;
3655             }
3656
3657             if (!ret) {
3658                 getKeepAlive.configured = ar->arKeepaliveConfigured;
3659             }
3660             if (copy_to_user(userdata, &getKeepAlive, sizeof(getKeepAlive))) {
3661                ret = -EFAULT;
3662             }
3663             up(&ar->arSem);
3664             }
3665             break;
3666         }
3667         case AR6000_XIOCTL_WMI_SET_APPIE:
3668         {
3669             WMI_SET_APPIE_CMD appIEcmd;
3670             u8 appIeInfo[IEEE80211_APPIE_FRAME_MAX_LEN];
3671             u32 fType,ieLen;
3672
3673             if (ar->arWmiReady == false) {
3674                 ret = -EIO;
3675                 goto ioctl_done;
3676             }
3677             if (get_user(fType, (u32 *)userdata)) {
3678                 ret = -EFAULT;
3679                 break;
3680             }
3681             appIEcmd.mgmtFrmType = fType;
3682             if (appIEcmd.mgmtFrmType >= IEEE80211_APPIE_NUM_OF_FRAME) {
3683                 ret = -EIO;
3684             } else {
3685                 if (get_user(ieLen, (u32 *)(userdata + 4))) {
3686                     ret = -EFAULT;
3687                     break;
3688                 }
3689                 appIEcmd.ieLen = ieLen;
3690                 A_PRINTF("WPSIE: Type-%d, Len-%d\n",appIEcmd.mgmtFrmType, appIEcmd.ieLen);
3691                 if (appIEcmd.ieLen > IEEE80211_APPIE_FRAME_MAX_LEN) {
3692                     ret = -EIO;
3693                     break;
3694                 }
3695                 if (copy_from_user(appIeInfo, userdata + 8, appIEcmd.ieLen)) {
3696                     ret = -EFAULT;
3697                 } else {
3698                     if (wmi_set_appie_cmd(ar->arWmi, appIEcmd.mgmtFrmType,
3699                                           appIEcmd.ieLen,  appIeInfo) != 0)
3700                     {
3701                         ret = -EIO;
3702                     }
3703                 }
3704             }
3705             break;
3706         }
3707         case AR6000_XIOCTL_WMI_SET_MGMT_FRM_RX_FILTER:
3708         {
3709             WMI_BSS_FILTER_CMD cmd;
3710             u32 filterType;
3711
3712             if (copy_from_user(&filterType, userdata, sizeof(u32)))
3713             {
3714                 ret = -EFAULT;
3715                 goto ioctl_done;
3716             }
3717             if (filterType & (IEEE80211_FILTER_TYPE_BEACON |
3718                                     IEEE80211_FILTER_TYPE_PROBE_RESP))
3719             {
3720                 cmd.bssFilter = ALL_BSS_FILTER;
3721             } else {
3722                 cmd.bssFilter = NONE_BSS_FILTER;
3723             }
3724             if (wmi_bssfilter_cmd(ar->arWmi, cmd.bssFilter, 0) != 0) {
3725                 ret = -EIO;
3726             } else {
3727                 ar->arUserBssFilter = cmd.bssFilter;
3728             }
3729
3730             AR6000_SPIN_LOCK(&ar->arLock, 0);
3731             ar->arMgmtFilter = filterType;
3732             AR6000_SPIN_UNLOCK(&ar->arLock, 0);
3733             break;
3734         }
3735         case AR6000_XIOCTL_WMI_SET_WSC_STATUS:
3736         {
3737             u32 wsc_status;
3738
3739             if (ar->arWmiReady == false) {
3740                 ret = -EIO;
3741                 goto ioctl_done;
3742             } else if (copy_from_user(&wsc_status, userdata, sizeof(u32)))
3743             {
3744                 ret = -EFAULT;
3745                 goto ioctl_done;
3746             }
3747             if (wmi_set_wsc_status_cmd(ar->arWmi, wsc_status) != 0) {
3748                 ret = -EIO;
3749             }
3750             break;
3751         }
3752         case AR6000_XIOCTL_BMI_ROMPATCH_INSTALL:
3753         {
3754             u32 ROM_addr;
3755             u32 RAM_addr;
3756             u32 nbytes;
3757             u32 do_activate;
3758             u32 rompatch_id;
3759
3760             if (get_user(ROM_addr, (u32 *)userdata) ||
3761                 get_user(RAM_addr, (u32 *)userdata + 1) ||
3762                 get_user(nbytes, (u32 *)userdata + 2) ||
3763                 get_user(do_activate, (u32 *)userdata + 3)) {
3764                 ret = -EFAULT;
3765                 break;
3766             }
3767             AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Install rompatch from ROM: 0x%x to RAM: 0x%x  length: %d\n",
3768                              ROM_addr, RAM_addr, nbytes));
3769             ret = BMIrompatchInstall(hifDevice, ROM_addr, RAM_addr,
3770                                         nbytes, do_activate, &rompatch_id);
3771             if (ret == 0) {
3772                 /* return value */
3773                 if (put_user(rompatch_id, (unsigned int *)rq->ifr_data)) {
3774                     ret = -EFAULT;
3775                     break;
3776                 }
3777             }
3778             break;
3779         }
3780
3781         case AR6000_XIOCTL_BMI_ROMPATCH_UNINSTALL:
3782         {
3783             u32 rompatch_id;
3784
3785             if (get_user(rompatch_id, (u32 *)userdata)) {
3786                 ret = -EFAULT;
3787                 break;
3788             }
3789             AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("UNinstall rompatch_id %d\n", rompatch_id));
3790             ret = BMIrompatchUninstall(hifDevice, rompatch_id);
3791             break;
3792         }
3793
3794         case AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE:
3795         case AR6000_XIOCTL_BMI_ROMPATCH_DEACTIVATE:
3796         {
3797             u32 rompatch_count;
3798
3799             if (get_user(rompatch_count, (u32 *)userdata)) {
3800                 ret = -EFAULT;
3801                 break;
3802             }
3803             AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Change rompatch activation count=%d\n", rompatch_count));
3804             length = sizeof(u32) * rompatch_count;
3805             if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) {
3806                 A_MEMZERO(buffer, length);
3807                 if (copy_from_user(buffer, &userdata[sizeof(rompatch_count)], length))
3808                 {
3809                     ret = -EFAULT;
3810                 } else {
3811                     if (cmd == AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE) {
3812                         ret = BMIrompatchActivate(hifDevice, rompatch_count, (u32 *)buffer);
3813                     } else {
3814                         ret = BMIrompatchDeactivate(hifDevice, rompatch_count, (u32 *)buffer);
3815                     }
3816                 }
3817                 kfree(buffer);
3818             } else {
3819                 ret = -ENOMEM;
3820             }
3821
3822             break;
3823         }
3824         case AR6000_XIOCTL_SET_IP:
3825         {
3826             WMI_SET_IP_CMD setIP;
3827
3828             if (ar->arWmiReady == false) {
3829                 ret = -EIO;
3830             } else if (copy_from_user(&setIP, userdata,
3831                                       sizeof(setIP)))
3832             {
3833                 ret = -EFAULT;
3834             } else {
3835                 if (wmi_set_ip_cmd(ar->arWmi,
3836                                 &setIP) != 0)
3837                 {
3838                     ret = -EIO;
3839                 }
3840             }
3841             break;
3842         }
3843
3844         case AR6000_XIOCTL_WMI_SET_HOST_SLEEP_MODE:
3845         {
3846             WMI_SET_HOST_SLEEP_MODE_CMD setHostSleepMode;
3847
3848             if (ar->arWmiReady == false) {
3849                 ret = -EIO;
3850             } else if (copy_from_user(&setHostSleepMode, userdata,
3851                                       sizeof(setHostSleepMode)))
3852             {
3853                 ret = -EFAULT;
3854             } else {
3855                 if (wmi_set_host_sleep_mode_cmd(ar->arWmi,
3856                                 &setHostSleepMode) != 0)
3857                 {
3858                     ret = -EIO;
3859                 }
3860             }
3861             break;
3862         }
3863         case AR6000_XIOCTL_WMI_SET_WOW_MODE:
3864         {
3865             WMI_SET_WOW_MODE_CMD setWowMode;
3866
3867             if (ar->arWmiReady == false) {
3868                 ret = -EIO;
3869             } else if (copy_from_user(&setWowMode, userdata,
3870                                       sizeof(setWowMode)))
3871             {
3872                 ret = -EFAULT;
3873             } else {
3874                 if (wmi_set_wow_mode_cmd(ar->arWmi,
3875                                 &setWowMode) != 0)
3876                 {
3877                     ret = -EIO;
3878                 }
3879             }
3880             break;
3881         }
3882         case AR6000_XIOCTL_WMI_GET_WOW_LIST:
3883         {
3884             WMI_GET_WOW_LIST_CMD getWowList;
3885
3886             if (ar->arWmiReady == false) {
3887                 ret = -EIO;
3888             } else if (copy_from_user(&getWowList, userdata,
3889                                       sizeof(getWowList)))
3890             {
3891                 ret = -EFAULT;
3892             } else {
3893                 if (wmi_get_wow_list_cmd(ar->arWmi,
3894                                 &getWowList) != 0)
3895                 {
3896                     ret = -EIO;
3897                 }
3898             }
3899             break;
3900         }
3901         case AR6000_XIOCTL_WMI_ADD_WOW_PATTERN:
3902         {
3903 #define WOW_PATTERN_SIZE 64
3904 #define WOW_MASK_SIZE 64
3905
3906             WMI_ADD_WOW_PATTERN_CMD cmd;
3907             u8 mask_data[WOW_PATTERN_SIZE]={0};
3908             u8 pattern_data[WOW_PATTERN_SIZE]={0};
3909
3910             do {
3911                 if (ar->arWmiReady == false) {
3912                     ret = -EIO;
3913                     break;        
3914                 } 
3915                 if(copy_from_user(&cmd, userdata,
3916                             sizeof(WMI_ADD_WOW_PATTERN_CMD))) 
3917                 {
3918                     ret = -EFAULT;
3919                     break;        
3920                 }
3921                 if (copy_from_user(pattern_data,
3922                                       userdata + 3,
3923                                       cmd.filter_size)) 
3924                 {
3925                     ret = -EFAULT;
3926                     break;        
3927                 }
3928                 if (copy_from_user(mask_data,
3929                                   (userdata + 3 + cmd.filter_size),
3930                                   cmd.filter_size))
3931                 {
3932                     ret = -EFAULT;
3933                     break;
3934                 }
3935                 if (wmi_add_wow_pattern_cmd(ar->arWmi,
3936                             &cmd, pattern_data, mask_data, cmd.filter_size) != 0)
3937                 {
3938                     ret = -EIO;
3939                 }
3940             } while(false);
3941 #undef WOW_PATTERN_SIZE
3942 #undef WOW_MASK_SIZE
3943             break;
3944         }
3945         case AR6000_XIOCTL_WMI_DEL_WOW_PATTERN:
3946         {
3947             WMI_DEL_WOW_PATTERN_CMD delWowPattern;
3948
3949             if (ar->arWmiReady == false) {
3950                 ret = -EIO;
3951             } else if (copy_from_user(&delWowPattern, userdata,
3952                                       sizeof(delWowPattern)))
3953             {
3954                 ret = -EFAULT;
3955             } else {
3956                 if (wmi_del_wow_pattern_cmd(ar->arWmi,
3957                                 &delWowPattern) != 0)
3958                 {
3959                     ret = -EIO;
3960                 }
3961             }
3962             break;
3963         }
3964         case AR6000_XIOCTL_DUMP_HTC_CREDIT_STATE:
3965             if (ar->arHtcTarget != NULL) {
3966 #ifdef ATH_DEBUG_MODULE
3967                 HTCDumpCreditStates(ar->arHtcTarget);
3968 #endif /* ATH_DEBUG_MODULE */
3969 #ifdef HTC_EP_STAT_PROFILING
3970                 {
3971                     struct htc_endpoint_stats stats;
3972                     int i;
3973
3974                     for (i = 0; i < 5; i++) {
3975                         if (HTCGetEndpointStatistics(ar->arHtcTarget,
3976                                                      i,
3977                                                      HTC_EP_STAT_SAMPLE_AND_CLEAR,
3978                                                      &stats)) {
3979                             A_PRINTF(KERN_ALERT"------- Profiling Endpoint : %d \n", i);
3980                             A_PRINTF(KERN_ALERT"TxCreditLowIndications : %d \n", stats.TxCreditLowIndications);
3981                             A_PRINTF(KERN_ALERT"TxIssued : %d \n", stats.TxIssued);
3982                             A_PRINTF(KERN_ALERT"TxDropped: %d \n", stats.TxDropped);
3983                             A_PRINTF(KERN_ALERT"TxPacketsBundled : %d \n", stats.TxPacketsBundled);
3984                             A_PRINTF(KERN_ALERT"TxBundles : %d \n", stats.TxBundles);
3985                             A_PRINTF(KERN_ALERT"TxCreditRpts : %d \n", stats.TxCreditRpts);
3986                             A_PRINTF(KERN_ALERT"TxCreditsRptsFromRx : %d \n", stats.TxCreditRptsFromRx);
3987                             A_PRINTF(KERN_ALERT"TxCreditsRptsFromOther : %d \n", stats.TxCreditRptsFromOther);
3988                             A_PRINTF(KERN_ALERT"TxCreditsRptsFromEp0 : %d \n", stats.TxCreditRptsFromEp0);
3989                             A_PRINTF(KERN_ALERT"TxCreditsFromRx : %d \n", stats.TxCreditsFromRx);
3990                             A_PRINTF(KERN_ALERT"TxCreditsFromOther : %d \n", stats.TxCreditsFromOther);
3991                             A_PRINTF(KERN_ALERT"TxCreditsFromEp0 : %d \n", stats.TxCreditsFromEp0);
3992                             A_PRINTF(KERN_ALERT"TxCreditsConsummed : %d \n", stats.TxCreditsConsummed);
3993                             A_PRINTF(KERN_ALERT"TxCreditsReturned : %d \n", stats.TxCreditsReturned);
3994                             A_PRINTF(KERN_ALERT"RxReceived : %d \n", stats.RxReceived);
3995                             A_PRINTF(KERN_ALERT"RxPacketsBundled : %d \n", stats.RxPacketsBundled);
3996                             A_PRINTF(KERN_ALERT"RxLookAheads : %d \n", stats.RxLookAheads);
3997                             A_PRINTF(KERN_ALERT"RxBundleLookAheads : %d \n", stats.RxBundleLookAheads);
3998                             A_PRINTF(KERN_ALERT"RxBundleIndFromHdr : %d \n", stats.RxBundleIndFromHdr);
3999                             A_PRINTF(KERN_ALERT"RxAllocThreshHit : %d \n", stats.RxAllocThreshHit);
4000                             A_PRINTF(KERN_ALERT"RxAllocThreshBytes : %d \n", stats.RxAllocThreshBytes);
4001                             A_PRINTF(KERN_ALERT"---- \n");
4002
4003                         }
4004             }
4005                 }
4006 #endif
4007             }
4008             break;
4009         case AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE:
4010             if (ar->arHtcTarget != NULL) {
4011                 struct ar6000_traffic_activity_change data;
4012
4013                 if (copy_from_user(&data, userdata, sizeof(data)))
4014                 {
4015                     ret = -EFAULT;
4016                     goto ioctl_done;
4017                 }
4018                     /* note, this is used for testing (mbox ping testing), indicate activity
4019                      * change using the stream ID as the traffic class */
4020                 ar6000_indicate_tx_activity(ar,
4021                                             (u8)data.StreamID,
4022                                             data.Active ? true : false);
4023             }
4024             break;
4025         case AR6000_XIOCTL_WMI_SET_CONNECT_CTRL_FLAGS:
4026             if (ar->arWmiReady == false) {
4027                 ret = -EIO;
4028             } else if (copy_from_user(&connectCtrlFlags, userdata,
4029                                       sizeof(connectCtrlFlags)))
4030             {
4031                 ret = -EFAULT;
4032             } else {
4033                 ar->arConnectCtrlFlags = connectCtrlFlags;
4034             }
4035             break;
4036         case AR6000_XIOCTL_WMI_SET_AKMP_PARAMS:
4037             if (ar->arWmiReady == false) {
4038                 ret = -EIO;
4039             } else if (copy_from_user(&akmpParams, userdata,
4040                                       sizeof(WMI_SET_AKMP_PARAMS_CMD)))
4041             {
4042                 ret = -EFAULT;
4043             } else {
4044                 if (wmi_set_akmp_params_cmd(ar->arWmi, &akmpParams) != 0) {
4045                     ret = -EIO;
4046                 }
4047             }
4048             break;
4049         case AR6000_XIOCTL_WMI_SET_PMKID_LIST:
4050             if (ar->arWmiReady == false) {
4051                 ret = -EIO;
4052             } else {
4053                 if (copy_from_user(&pmkidInfo.numPMKID, userdata,
4054                                       sizeof(pmkidInfo.numPMKID)))
4055                 {
4056                     ret = -EFAULT;
4057                     break;
4058                 }
4059                 if (copy_from_user(&pmkidInfo.pmkidList,
4060                                    userdata + sizeof(pmkidInfo.numPMKID),
4061                                    pmkidInfo.numPMKID * sizeof(WMI_PMKID)))
4062                 {
4063                     ret = -EFAULT;
4064                     break;
4065                 }
4066                 if (wmi_set_pmkid_list_cmd(ar->arWmi, &pmkidInfo) != 0) {
4067                     ret = -EIO;
4068                 }
4069             }
4070             break;
4071         case AR6000_XIOCTL_WMI_GET_PMKID_LIST:
4072             if (ar->arWmiReady == false) {
4073                 ret = -EIO;
4074             } else  {
4075                 if (wmi_get_pmkid_list_cmd(ar->arWmi) != 0) {
4076                     ret = -EIO;
4077                 }
4078             }
4079             break;
4080         case AR6000_XIOCTL_WMI_ABORT_SCAN:
4081             if (ar->arWmiReady == false) {
4082                 ret = -EIO;
4083             }
4084             ret = wmi_abort_scan_cmd(ar->arWmi);
4085             break;
4086         case AR6000_XIOCTL_AP_HIDDEN_SSID:
4087         {
4088             u8 hidden_ssid;
4089             if (ar->arWmiReady == false) {
4090                 ret = -EIO;
4091             } else if (copy_from_user(&hidden_ssid, userdata, sizeof(hidden_ssid))) {
4092                 ret = -EFAULT;
4093             } else {
4094                 wmi_ap_set_hidden_ssid(ar->arWmi, hidden_ssid);
4095                 ar->ap_hidden_ssid = hidden_ssid;
4096                 ar->ap_profile_flag = 1; /* There is a change in profile */
4097             }
4098             break;
4099         }
4100         case AR6000_XIOCTL_AP_GET_STA_LIST:
4101         {
4102             if (ar->arWmiReady == false) {
4103                 ret = -EIO;
4104             } else {
4105                 u8 i;
4106                 ap_get_sta_t temp;
4107                 A_MEMZERO(&temp, sizeof(temp));
4108                 for(i=0;i<AP_MAX_NUM_STA;i++) {
4109                     memcpy(temp.sta[i].mac, ar->sta_list[i].mac, ATH_MAC_LEN);
4110                     temp.sta[i].aid = ar->sta_list[i].aid;
4111                     temp.sta[i].keymgmt = ar->sta_list[i].keymgmt;
4112                     temp.sta[i].ucipher = ar->sta_list[i].ucipher;
4113                     temp.sta[i].auth = ar->sta_list[i].auth;
4114                 }
4115                 if(copy_to_user((ap_get_sta_t *)rq->ifr_data, &temp,
4116                                  sizeof(ar->sta_list))) {
4117                     ret = -EFAULT;
4118                 }
4119             }
4120             break;
4121         }
4122         case AR6000_XIOCTL_AP_SET_NUM_STA:
4123         {
4124             u8 num_sta;
4125             if (ar->arWmiReady == false) {
4126                 ret = -EIO;
4127             } else if (copy_from_user(&num_sta, userdata, sizeof(num_sta))) {
4128                 ret = -EFAULT;
4129             } else if(num_sta > AP_MAX_NUM_STA) {
4130                 /* value out of range */
4131                 ret = -EINVAL;
4132             } else {
4133                 wmi_ap_set_num_sta(ar->arWmi, num_sta);
4134             }
4135             break;
4136         }
4137         case AR6000_XIOCTL_AP_SET_ACL_POLICY:
4138         {
4139             u8 policy;
4140             if (ar->arWmiReady == false) {
4141                 ret = -EIO;
4142             } else if (copy_from_user(&policy, userdata, sizeof(policy))) {
4143                 ret = -EFAULT;
4144             } else if(policy == ar->g_acl.policy) {
4145                 /* No change in policy */
4146             } else {
4147                 if(!(policy & AP_ACL_RETAIN_LIST_MASK)) {
4148                     /* clear ACL list */
4149                     memset(&ar->g_acl,0,sizeof(WMI_AP_ACL));
4150                 }
4151                 ar->g_acl.policy = policy;
4152                 wmi_ap_set_acl_policy(ar->arWmi, policy);
4153             }
4154             break;
4155         }
4156         case AR6000_XIOCTL_AP_SET_ACL_MAC:
4157         {
4158             WMI_AP_ACL_MAC_CMD    acl;
4159             if (ar->arWmiReady == false) {
4160                 ret = -EIO;
4161             } else if (copy_from_user(&acl, userdata, sizeof(acl))) {
4162                 ret = -EFAULT;
4163             } else {
4164                 if(acl_add_del_mac(&ar->g_acl, &acl)) {
4165                     wmi_ap_acl_mac_list(ar->arWmi, &acl);
4166                 } else {
4167                     A_PRINTF("ACL list error\n");
4168                     ret = -EIO;
4169                 }
4170             }
4171             break;
4172         }
4173         case AR6000_XIOCTL_AP_GET_ACL_LIST:
4174         {
4175             if (ar->arWmiReady == false) {
4176                 ret = -EIO;
4177             } else if(copy_to_user((WMI_AP_ACL *)rq->ifr_data, &ar->g_acl,
4178                                  sizeof(WMI_AP_ACL))) {
4179                     ret = -EFAULT;
4180             }
4181             break;
4182         }
4183         case AR6000_XIOCTL_AP_COMMIT_CONFIG:
4184         {
4185             ret = ar6000_ap_mode_profile_commit(ar);
4186             break;
4187         }
4188         case IEEE80211_IOCTL_GETWPAIE:
4189         {
4190             struct ieee80211req_wpaie wpaie;
4191             if (ar->arWmiReady == false) {
4192                 ret = -EIO;
4193             } else if (copy_from_user(&wpaie, userdata, sizeof(wpaie))) {
4194                 ret = -EFAULT;
4195             } else if (ar6000_ap_mode_get_wpa_ie(ar, &wpaie)) {
4196                 ret = -EFAULT;
4197             } else if(copy_to_user(userdata, &wpaie, sizeof(wpaie))) {
4198                 ret = -EFAULT;
4199             }
4200             break;
4201         }
4202         case AR6000_XIOCTL_AP_CONN_INACT_TIME:
4203         {
4204             u32 period;
4205             if (ar->arWmiReady == false) {
4206                 ret = -EIO;
4207             } else if (copy_from_user(&period, userdata, sizeof(period))) {
4208                 ret = -EFAULT;
4209             } else {
4210                 wmi_ap_conn_inact_time(ar->arWmi, period);
4211             }
4212             break;
4213         }
4214         case AR6000_XIOCTL_AP_PROT_SCAN_TIME:
4215         {
4216             WMI_AP_PROT_SCAN_TIME_CMD  bgscan;
4217             if (ar->arWmiReady == false) {
4218                 ret = -EIO;
4219             } else if (copy_from_user(&bgscan, userdata, sizeof(bgscan))) {
4220                 ret = -EFAULT;
4221             } else {
4222                 wmi_ap_bgscan_time(ar->arWmi, bgscan.period_min, bgscan.dwell_ms);
4223             }
4224             break;
4225         }
4226         case AR6000_XIOCTL_AP_SET_COUNTRY:
4227         {
4228             ret = ar6000_ioctl_set_country(dev, rq);
4229             break;
4230         }
4231         case AR6000_XIOCTL_AP_SET_DTIM:
4232         {
4233             WMI_AP_SET_DTIM_CMD  d;
4234             if (ar->arWmiReady == false) {
4235                 ret = -EIO;
4236             } else if (copy_from_user(&d, userdata, sizeof(d))) {
4237                 ret = -EFAULT;
4238             } else {
4239                 if(d.dtim > 0 && d.dtim < 11) {
4240                     ar->ap_dtim_period = d.dtim;
4241                     wmi_ap_set_dtim(ar->arWmi, d.dtim);
4242                     ar->ap_profile_flag = 1; /* There is a change in profile */
4243                 } else {
4244                     A_PRINTF("DTIM out of range. Valid range is [1-10]\n");
4245                     ret = -EIO;
4246                 }
4247             }
4248             break;
4249         }
4250         case AR6000_XIOCTL_WMI_TARGET_EVENT_REPORT:
4251         {
4252             WMI_SET_TARGET_EVENT_REPORT_CMD evtCfgCmd;
4253
4254             if (ar->arWmiReady == false) {
4255                 ret = -EIO;
4256             }
4257             if (copy_from_user(&evtCfgCmd, userdata,
4258                                sizeof(evtCfgCmd))) {
4259                 ret = -EFAULT;
4260                 break;
4261             }
4262             ret = wmi_set_target_event_report_cmd(ar->arWmi, &evtCfgCmd);
4263             break;
4264         }
4265         case AR6000_XIOCTL_AP_INTRA_BSS_COMM:
4266         {
4267             u8 intra=0;
4268             if (ar->arWmiReady == false) {
4269                 ret = -EIO;
4270             } else if (copy_from_user(&intra, userdata, sizeof(intra))) {
4271                 ret = -EFAULT;
4272             } else {
4273                 ar->intra_bss = (intra?1:0);
4274             }
4275             break;
4276         }
4277         case AR6000_XIOCTL_DUMP_MODULE_DEBUG_INFO:
4278         {
4279             struct drv_debug_module_s moduleinfo;
4280
4281             if (copy_from_user(&moduleinfo, userdata, sizeof(moduleinfo))) {
4282                 ret = -EFAULT;
4283                 break;
4284             }
4285
4286             a_dump_module_debug_info_by_name(moduleinfo.modulename);
4287             ret = 0;
4288             break;
4289         }
4290         case AR6000_XIOCTL_MODULE_DEBUG_SET_MASK:
4291         {
4292             struct drv_debug_module_s moduleinfo;
4293
4294             if (copy_from_user(&moduleinfo, userdata, sizeof(moduleinfo))) {
4295                 ret = -EFAULT;
4296                 break;
4297             }
4298
4299             if (a_set_module_mask(moduleinfo.modulename, moduleinfo.mask)) {
4300                 ret = -EFAULT;
4301             }
4302
4303             break;
4304         }
4305         case AR6000_XIOCTL_MODULE_DEBUG_GET_MASK:
4306         {
4307             struct drv_debug_module_s moduleinfo;
4308
4309             if (copy_from_user(&moduleinfo, userdata, sizeof(moduleinfo))) {
4310                 ret = -EFAULT;
4311                 break;
4312             }
4313
4314             if (a_get_module_mask(moduleinfo.modulename, &moduleinfo.mask)) {
4315                 ret = -EFAULT;
4316                 break;
4317             }
4318
4319             if (copy_to_user(userdata, &moduleinfo, sizeof(moduleinfo))) {
4320                 ret = -EFAULT;
4321                 break;
4322             }
4323
4324             break;
4325         }
4326 #ifdef ATH_AR6K_11N_SUPPORT
4327         case AR6000_XIOCTL_DUMP_RCV_AGGR_STATS:
4328         {
4329             PACKET_LOG *copy_of_pkt_log;
4330
4331             aggr_dump_stats(ar->aggr_cntxt, &copy_of_pkt_log);
4332             if (copy_to_user(rq->ifr_data, copy_of_pkt_log, sizeof(PACKET_LOG))) {
4333                 ret = -EFAULT;
4334             }
4335             break;
4336         }
4337         case AR6000_XIOCTL_SETUP_AGGR:
4338         {
4339             WMI_ADDBA_REQ_CMD cmd;
4340
4341             if (ar->arWmiReady == false) {
4342                 ret = -EIO;
4343             } else if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
4344                 ret = -EFAULT;
4345             } else {
4346                 wmi_setup_aggr_cmd(ar->arWmi, cmd.tid);
4347             }
4348         }
4349         break;
4350
4351         case AR6000_XIOCTL_DELE_AGGR:
4352         {
4353             WMI_DELBA_REQ_CMD cmd;
4354
4355             if (ar->arWmiReady == false) {
4356                 ret = -EIO;
4357             } else if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
4358                 ret = -EFAULT;
4359             } else {
4360                 wmi_delete_aggr_cmd(ar->arWmi, cmd.tid, cmd.is_sender_initiator);
4361             }
4362         }
4363         break;
4364
4365         case AR6000_XIOCTL_ALLOW_AGGR:
4366         {
4367             WMI_ALLOW_AGGR_CMD cmd;
4368
4369             if (ar->arWmiReady == false) {
4370                 ret = -EIO;
4371             } else if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
4372                 ret = -EFAULT;
4373             } else {
4374                 wmi_allow_aggr_cmd(ar->arWmi, cmd.tx_allow_aggr, cmd.rx_allow_aggr);
4375             }
4376         }
4377         break;
4378
4379         case AR6000_XIOCTL_SET_HT_CAP:
4380         {
4381             if (ar->arWmiReady == false) {
4382                 ret = -EIO;
4383             } else if (copy_from_user(&htCap, userdata,
4384                                       sizeof(htCap)))
4385             {
4386                 ret = -EFAULT;
4387             } else {
4388
4389                 if (wmi_set_ht_cap_cmd(ar->arWmi, &htCap) != 0)
4390                 {
4391                     ret = -EIO;
4392                 }
4393             }
4394             break;
4395         }
4396         case AR6000_XIOCTL_SET_HT_OP:
4397         {
4398              if (ar->arWmiReady == false) {
4399                 ret = -EIO;
4400             } else if (copy_from_user(&htOp, userdata,
4401                                       sizeof(htOp)))
4402             {
4403                  ret = -EFAULT;
4404              } else {
4405
4406                 if (wmi_set_ht_op_cmd(ar->arWmi, htOp.sta_chan_width) != 0)
4407                 {
4408                      ret = -EIO;
4409                }
4410              }
4411              break;
4412         }
4413 #endif
4414         case AR6000_XIOCTL_ACL_DATA:
4415         {
4416             void *osbuf = NULL;
4417             if (ar->arWmiReady == false) {
4418                 ret = -EIO;
4419             } else if (ar6000_create_acl_data_osbuf(dev, (u8 *)userdata, &osbuf) != 0) {
4420                      ret = -EIO;
4421             } else {
4422                 if (wmi_data_hdr_add(ar->arWmi, osbuf, DATA_MSGTYPE, 0, WMI_DATA_HDR_DATA_TYPE_ACL,0,NULL) != 0) {
4423                     AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("XIOCTL_ACL_DATA - wmi_data_hdr_add failed\n"));
4424                 } else {
4425                     /* Send data buffer over HTC */
4426                     ar6000_acl_data_tx(osbuf, ar->arNetDev);
4427                 }
4428             }
4429             break;
4430         }
4431         case AR6000_XIOCTL_HCI_CMD:
4432         {
4433             char tmp_buf[512];
4434             s8 i;
4435             WMI_HCI_CMD *cmd = (WMI_HCI_CMD *)tmp_buf;
4436             u8 size;
4437
4438             size = sizeof(cmd->cmd_buf_sz);
4439             if (ar->arWmiReady == false) {
4440                 ret = -EIO;
4441             } else if (copy_from_user(cmd, userdata, size)) {
4442                  ret = -EFAULT;
4443             } else if(copy_from_user(cmd->buf, userdata + size, cmd->cmd_buf_sz)) {
4444                     ret = -EFAULT;
4445             } else {
4446                 if (wmi_send_hci_cmd(ar->arWmi, cmd->buf, cmd->cmd_buf_sz) != 0) {
4447                      ret = -EIO;
4448                 }else if(loghci) {
4449                     A_PRINTF_LOG("HCI Command To PAL --> \n");
4450                     for(i = 0; i < cmd->cmd_buf_sz; i++) {
4451                         A_PRINTF_LOG("0x%02x ",cmd->buf[i]);
4452                         if((i % 10) == 0) {
4453                             A_PRINTF_LOG("\n");
4454                         }
4455                     }
4456                     A_PRINTF_LOG("\n");
4457                     A_PRINTF_LOG("==================================\n");
4458                 }
4459             }
4460             break;
4461         }
4462         case AR6000_XIOCTL_WLAN_CONN_PRECEDENCE:
4463         {
4464             WMI_SET_BT_WLAN_CONN_PRECEDENCE cmd;
4465             if (ar->arWmiReady == false) {
4466                 ret = -EIO;
4467             } else if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
4468                 ret = -EFAULT;
4469             } else {
4470                 if (cmd.precedence == BT_WLAN_CONN_PRECDENCE_WLAN ||
4471                             cmd.precedence == BT_WLAN_CONN_PRECDENCE_PAL) {
4472                     if ( wmi_set_wlan_conn_precedence_cmd(ar->arWmi, cmd.precedence) != 0) {
4473                         ret = -EIO;
4474                     }
4475                 } else {
4476                     ret = -EINVAL;
4477                 }
4478             }
4479             break;
4480         }
4481         case AR6000_XIOCTL_AP_GET_STAT:
4482         {
4483             ret = ar6000_ioctl_get_ap_stats(dev, rq);
4484             break;
4485         }
4486         case AR6000_XIOCTL_SET_TX_SELECT_RATES:
4487         {
4488             WMI_SET_TX_SELECT_RATES_CMD masks;
4489
4490              if (ar->arWmiReady == false) {
4491                 ret = -EIO;
4492             } else if (copy_from_user(&masks, userdata,
4493                                       sizeof(masks)))
4494             {
4495                  ret = -EFAULT;
4496              } else {
4497
4498                 if (wmi_set_tx_select_rates_cmd(ar->arWmi, masks.rateMasks) != 0)
4499                 {
4500                      ret = -EIO;
4501                }
4502              }
4503              break;
4504         }
4505         case AR6000_XIOCTL_AP_GET_HIDDEN_SSID:
4506         {
4507             WMI_AP_HIDDEN_SSID_CMD ssid;
4508             ssid.hidden_ssid = ar->ap_hidden_ssid;
4509
4510             if (ar->arWmiReady == false) {
4511                 ret = -EIO;
4512             } else if(copy_to_user((WMI_AP_HIDDEN_SSID_CMD *)rq->ifr_data,
4513                                     &ssid, sizeof(WMI_AP_HIDDEN_SSID_CMD))) {
4514                     ret = -EFAULT;
4515             }
4516             break;
4517         }
4518         case AR6000_XIOCTL_AP_GET_COUNTRY:
4519         {
4520             WMI_AP_SET_COUNTRY_CMD cty;
4521             memcpy(cty.countryCode, ar->ap_country_code, 3);
4522
4523             if (ar->arWmiReady == false) {
4524                 ret = -EIO;
4525             } else if(copy_to_user((WMI_AP_SET_COUNTRY_CMD *)rq->ifr_data,
4526                                     &cty, sizeof(WMI_AP_SET_COUNTRY_CMD))) {
4527                     ret = -EFAULT;
4528             }
4529             break;
4530         }
4531         case AR6000_XIOCTL_AP_GET_WMODE:
4532         {
4533             if (ar->arWmiReady == false) {
4534                 ret = -EIO;
4535             } else if(copy_to_user((u8 *)rq->ifr_data,
4536                                     &ar->ap_wmode, sizeof(u8))) {
4537                     ret = -EFAULT;
4538             }
4539             break;
4540         }
4541         case AR6000_XIOCTL_AP_GET_DTIM:
4542         {
4543             WMI_AP_SET_DTIM_CMD dtim;
4544             dtim.dtim = ar->ap_dtim_period;
4545
4546             if (ar->arWmiReady == false) {
4547                 ret = -EIO;
4548             } else if(copy_to_user((WMI_AP_SET_DTIM_CMD *)rq->ifr_data,
4549                                     &dtim, sizeof(WMI_AP_SET_DTIM_CMD))) {
4550                     ret = -EFAULT;
4551             }
4552             break;
4553         }
4554         case AR6000_XIOCTL_AP_GET_BINTVL:
4555         {
4556             WMI_BEACON_INT_CMD bi;
4557             bi.beaconInterval = ar->ap_beacon_interval;
4558
4559             if (ar->arWmiReady == false) {
4560                 ret = -EIO;
4561             } else if(copy_to_user((WMI_BEACON_INT_CMD *)rq->ifr_data,
4562                                     &bi, sizeof(WMI_BEACON_INT_CMD))) {
4563                     ret = -EFAULT;
4564             }
4565             break;
4566         }
4567         case AR6000_XIOCTL_AP_GET_RTS:
4568         {
4569             WMI_SET_RTS_CMD rts;
4570             rts.threshold = ar->arRTS;
4571              
4572             if (ar->arWmiReady == false) {
4573                 ret = -EIO;
4574             } else if(copy_to_user((WMI_SET_RTS_CMD *)rq->ifr_data,
4575                                     &rts, sizeof(WMI_SET_RTS_CMD))) {
4576                     ret = -EFAULT;
4577             }
4578             break;
4579         }
4580         case AR6000_XIOCTL_FETCH_TARGET_REGS:
4581         {
4582             u32 targregs[AR6003_FETCH_TARG_REGS_COUNT];
4583
4584             if (ar->arTargetType == TARGET_TYPE_AR6003) {
4585                 ar6k_FetchTargetRegs(hifDevice, targregs);
4586                 if (copy_to_user((u32 *)rq->ifr_data, &targregs, sizeof(targregs)))
4587                 {
4588                     ret = -EFAULT;
4589                 }
4590             } else {
4591                 ret = -EOPNOTSUPP;
4592             }
4593             break;
4594         }
4595         case AR6000_XIOCTL_AP_SET_11BG_RATESET:
4596         {
4597             WMI_AP_SET_11BG_RATESET_CMD  rate;
4598             if (ar->arWmiReady == false) {
4599                 ret = -EIO;
4600             } else if (copy_from_user(&rate, userdata, sizeof(rate))) {
4601                 ret = -EFAULT;
4602             } else {
4603                 wmi_ap_set_rateset(ar->arWmi, rate.rateset);
4604             }
4605             break;
4606         }
4607         case AR6000_XIOCTL_GET_WLAN_SLEEP_STATE:
4608         {
4609             WMI_REPORT_SLEEP_STATE_EVENT  wmiSleepEvent ;
4610
4611             if (ar->arWlanState == WLAN_ENABLED) {
4612                 wmiSleepEvent.sleepState = WMI_REPORT_SLEEP_STATUS_IS_AWAKE;
4613             } else {
4614                 wmiSleepEvent.sleepState = WMI_REPORT_SLEEP_STATUS_IS_DEEP_SLEEP;
4615             }
4616             rq->ifr_ifru.ifru_ivalue = ar->arWlanState; /* return value */
4617
4618             ar6000_send_event_to_app(ar, WMI_REPORT_SLEEP_STATE_EVENTID, (u8 *)&wmiSleepEvent,
4619                                      sizeof(WMI_REPORT_SLEEP_STATE_EVENTID));
4620             break;
4621         }
4622 #ifdef CONFIG_PM
4623         case AR6000_XIOCTL_SET_BT_HW_POWER_STATE:
4624         {
4625             unsigned int state;
4626             if (get_user(state, (unsigned int *)userdata)) {
4627                 ret = -EFAULT;
4628                 break;
4629             }
4630             if (ar6000_set_bt_hw_state(ar, state)!= 0) {
4631                 ret = -EIO;
4632             }       
4633         }
4634             break;
4635         case AR6000_XIOCTL_GET_BT_HW_POWER_STATE:
4636             rq->ifr_ifru.ifru_ivalue = !ar->arBTOff; /* return value */
4637             break;
4638 #endif
4639
4640         case AR6000_XIOCTL_WMI_SET_TX_SGI_PARAM:
4641         {
4642              WMI_SET_TX_SGI_PARAM_CMD SGICmd;
4643
4644              if (ar->arWmiReady == false) {
4645                  ret = -EIO;
4646              } else if (copy_from_user(&SGICmd, userdata,
4647                                        sizeof(SGICmd))){
4648                  ret = -EFAULT;
4649              } else{
4650                      if (wmi_SGI_cmd(ar->arWmi, SGICmd.sgiMask, SGICmd.sgiPERThreshold) != 0) {
4651                          ret = -EIO;
4652                      }
4653
4654              }
4655              break;
4656         }
4657
4658         case AR6000_XIOCTL_ADD_AP_INTERFACE:
4659 #ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
4660         {
4661             char ap_ifname[IFNAMSIZ] = {0,};
4662             if (copy_from_user(ap_ifname, userdata, IFNAMSIZ)) {
4663                 ret = -EFAULT;
4664             } else {
4665                 if (ar6000_add_ap_interface(ar, ap_ifname) != 0) {
4666                     ret = -EIO;
4667                 } 
4668             }
4669         }
4670 #else
4671             ret = -EOPNOTSUPP;
4672 #endif
4673             break;
4674         case AR6000_XIOCTL_REMOVE_AP_INTERFACE:
4675 #ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
4676             if (ar6000_remove_ap_interface(ar) != 0) {
4677                 ret = -EIO;
4678             } 
4679 #else
4680             ret = -EOPNOTSUPP;
4681 #endif
4682             break;
4683
4684         case AR6000_XIOCTL_WMI_SET_EXCESS_TX_RETRY_THRES:
4685         {
4686             ret = ar6000_xioctl_set_excess_tx_retry_thres_cmd(dev, userdata);
4687             break;
4688         }
4689
4690         default:
4691             ret = -EOPNOTSUPP;
4692     }
4693
4694 ioctl_done:
4695     rtnl_lock(); /* restore rtnl state */
4696     dev_put(dev);
4697
4698     return ret;
4699 }
4700
4701 u8 mac_cmp_wild(u8 *mac, u8 *new_mac, u8 wild, u8 new_wild)
4702 {
4703     u8 i;
4704
4705     for(i=0;i<ATH_MAC_LEN;i++) {
4706         if((wild & 1<<i) && (new_wild & 1<<i)) continue;
4707         if(mac[i] != new_mac[i]) return 1;
4708     }
4709     if((memcmp(new_mac, null_mac, 6)==0) && new_wild &&
4710         (wild != new_wild)) {
4711         return 1;
4712     }
4713
4714     return 0;
4715 }
4716
4717 u8 acl_add_del_mac(WMI_AP_ACL *a, WMI_AP_ACL_MAC_CMD *acl)
4718 {
4719     s8 already_avail=-1, free_slot=-1, i;
4720
4721     /* To check whether this mac is already there in our list */
4722     for(i=AP_ACL_SIZE-1;i>=0;i--)
4723     {
4724         if(mac_cmp_wild(a->acl_mac[i], acl->mac, a->wildcard[i],
4725             acl->wildcard)==0)
4726                 already_avail = i;
4727
4728         if(!((1 << i) & a->index))
4729             free_slot = i;
4730     }
4731
4732     if(acl->action == ADD_MAC_ADDR)
4733     {
4734         /* Dont add mac if it is already available */
4735         if((already_avail >= 0) || (free_slot == -1))
4736             return 0;
4737
4738         memcpy(a->acl_mac[free_slot], acl->mac, ATH_MAC_LEN);
4739         a->index = a->index | (1 << free_slot);
4740         acl->index = free_slot;
4741         a->wildcard[free_slot] = acl->wildcard;
4742         return 1;
4743     }
4744     else if(acl->action == DEL_MAC_ADDR)
4745     {
4746         if(acl->index > AP_ACL_SIZE)
4747             return 0;
4748
4749         if(!(a->index & (1 << acl->index)))
4750             return 0;
4751
4752         A_MEMZERO(a->acl_mac[acl->index],ATH_MAC_LEN);
4753         a->index = a->index & ~(1 << acl->index);
4754         a->wildcard[acl->index] = 0;
4755         return 1;
4756     }
4757
4758     return 0;
4759 }