~ubuntu-branches/ubuntu/natty/linux-backports-modules-2.6.38/natty-updates

« back to all changes in this revision

Viewing changes to updates/compat-wireless-2.6.37/drivers/staging/ath6kl/os/linux/ioctl.c

  • Committer: Bazaar Package Importer
  • Author(s): Tim Gardner, Tim Gardner
  • Date: 2011-06-08 10:44:09 UTC
  • Revision ID: james.westby@ubuntu.com-20110608104409-fnl8carkdo15bwsz
Tags: 2.6.38-10.6
[ Tim Gardner ]

Shorten compat-wireless package name to cw to accomodate
CDROM file name length restrictions.

Show diffs side-by-side

added added

removed removed

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