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