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