~ubuntu-branches/ubuntu/quantal/linux-linaro-mx51/quantal

« back to all changes in this revision

Viewing changes to drivers/staging/ath6kl/os/linux/ioctl.c

  • Committer: Package Import Robot
  • Author(s): John Rigby, John Rigby
  • Date: 2011-09-26 10:44:23 UTC
  • Revision ID: package-import@ubuntu.com-20110926104423-3o58a3c1bj7x00rs
Tags: 3.0.0-1007.9
[ John Rigby ]

Enable crypto modules and remove crypto-modules from
exclude-module files
LP: #826021

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