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