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