~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

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
 
 
26
 
#define IWE_STREAM_ADD_EVENT(p1, p2, p3, p4, p5) \
27
 
    iwe_stream_add_event((p1), (p2), (p3), (p4), (p5))
28
 
 
29
 
#define IWE_STREAM_ADD_POINT(p1, p2, p3, p4, p5) \
30
 
    iwe_stream_add_point((p1), (p2), (p3), (p4), (p5))
31
 
 
32
 
#define IWE_STREAM_ADD_VALUE(p1, p2, p3, p4, p5, p6) \
33
 
    iwe_stream_add_value((p1), (p2), (p3), (p4), (p5), (p6))
34
 
 
35
 
static void ar6000_set_quality(struct iw_quality *iq, A_INT8 rssi);
36
 
extern unsigned int wmitimeout;
37
 
extern A_WAITQUEUE_HEAD arEvent;
38
 
 
39
 
#if WIRELESS_EXT > 14
40
 
/*
41
 
 * Encode a WPA or RSN information element as a custom
42
 
 * element using the hostap format.
43
 
 */
44
 
static u_int
45
 
encode_ie(void *buf, size_t bufsize,
46
 
    const u_int8_t *ie, size_t ielen,
47
 
    const char *leader, size_t leader_len)
48
 
{
49
 
    u_int8_t *p;
50
 
    int i;
51
 
 
52
 
    if (bufsize < leader_len)
53
 
        return 0;
54
 
    p = buf;
55
 
    memcpy(p, leader, leader_len);
56
 
    bufsize -= leader_len;
57
 
    p += leader_len;
58
 
    for (i = 0; i < ielen && bufsize > 2; i++)
59
 
    {
60
 
        p += sprintf((char*)p, "%02x", ie[i]);
61
 
        bufsize -= 2;
62
 
    }
63
 
    return (i == ielen ? p - (u_int8_t *)buf : 0);
64
 
}
65
 
#endif /* WIRELESS_EXT > 14 */
66
 
 
67
 
static A_UINT8
68
 
get_bss_phy_capability(bss_t *bss)
69
 
{
70
 
    A_UINT8 capability = 0;
71
 
    struct ieee80211_common_ie *cie = &bss->ni_cie;
72
 
#define CHAN_IS_11A(x)              (!((x >= 2412) && (x <= 2484)))
73
 
    if (CHAN_IS_11A(cie->ie_chan)) {
74
 
        if (cie->ie_htcap) {
75
 
            capability = WMI_11NA_CAPABILITY;
76
 
        } else {
77
 
            capability = WMI_11A_CAPABILITY;
78
 
        }
79
 
    } else if ((cie->ie_erp) || (cie->ie_xrates)) {
80
 
        if (cie->ie_htcap) {
81
 
            capability = WMI_11NG_CAPABILITY;
82
 
        } else {
83
 
            capability = WMI_11G_CAPABILITY;
84
 
        }
85
 
    }
86
 
    return capability;
87
 
}
88
 
 
89
 
void
90
 
ar6000_scan_node(void *arg, bss_t *ni)
91
 
{
92
 
    struct iw_event iwe;
93
 
#if WIRELESS_EXT > 14
94
 
    char buf[256];
95
 
#endif
96
 
    struct ar_giwscan_param *param;
97
 
    A_CHAR *current_ev;
98
 
    A_CHAR *end_buf;
99
 
    struct ieee80211_common_ie  *cie;
100
 
    A_CHAR *current_val;
101
 
    A_INT32 j;
102
 
    A_UINT32 rate_len, data_len = 0;
103
 
 
104
 
    param = (struct ar_giwscan_param *)arg;
105
 
 
106
 
    current_ev = param->current_ev;
107
 
    end_buf = param->end_buf;
108
 
 
109
 
    cie = &ni->ni_cie;
110
 
 
111
 
    if ((end_buf - current_ev) > IW_EV_ADDR_LEN)
112
 
    {
113
 
        A_MEMZERO(&iwe, sizeof(iwe));
114
 
        iwe.cmd = SIOCGIWAP;
115
 
        iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
116
 
        A_MEMCPY(iwe.u.ap_addr.sa_data, ni->ni_macaddr, 6);
117
 
        current_ev = IWE_STREAM_ADD_EVENT(param->info, current_ev, end_buf,
118
 
                                          &iwe, IW_EV_ADDR_LEN);
119
 
    }
120
 
    param->bytes_needed += IW_EV_ADDR_LEN;
121
 
 
122
 
    data_len = cie->ie_ssid[1] + IW_EV_POINT_LEN;
123
 
    if ((end_buf - current_ev) > data_len)
124
 
    {
125
 
        A_MEMZERO(&iwe, sizeof(iwe));
126
 
        iwe.cmd = SIOCGIWESSID;
127
 
        iwe.u.data.flags = 1;
128
 
        iwe.u.data.length = cie->ie_ssid[1];
129
 
        current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, end_buf,
130
 
                                          &iwe, (char*)&cie->ie_ssid[2]);
131
 
    }
132
 
    param->bytes_needed += data_len;
133
 
 
134
 
    if (cie->ie_capInfo & (IEEE80211_CAPINFO_ESS|IEEE80211_CAPINFO_IBSS)) {
135
 
        if ((end_buf - current_ev) > IW_EV_UINT_LEN)
136
 
        {
137
 
            A_MEMZERO(&iwe, sizeof(iwe));
138
 
            iwe.cmd = SIOCGIWMODE;
139
 
            iwe.u.mode = cie->ie_capInfo & IEEE80211_CAPINFO_ESS ?
140
 
                         IW_MODE_MASTER : IW_MODE_ADHOC;
141
 
            current_ev = IWE_STREAM_ADD_EVENT(param->info, current_ev, end_buf,
142
 
                                              &iwe, IW_EV_UINT_LEN);
143
 
        }
144
 
        param->bytes_needed += IW_EV_UINT_LEN;
145
 
    }
146
 
 
147
 
    if ((end_buf - current_ev) > IW_EV_FREQ_LEN)
148
 
    {
149
 
        A_MEMZERO(&iwe, sizeof(iwe));
150
 
        iwe.cmd = SIOCGIWFREQ;
151
 
        iwe.u.freq.m = cie->ie_chan * 100000;
152
 
        iwe.u.freq.e = 1;
153
 
        current_ev = IWE_STREAM_ADD_EVENT(param->info, current_ev, end_buf,
154
 
                                          &iwe, IW_EV_FREQ_LEN);
155
 
    }
156
 
    param->bytes_needed += IW_EV_FREQ_LEN;
157
 
 
158
 
    if ((end_buf - current_ev) > IW_EV_QUAL_LEN)
159
 
    {
160
 
        A_MEMZERO(&iwe, sizeof(iwe));
161
 
        iwe.cmd = IWEVQUAL;
162
 
        ar6000_set_quality(&iwe.u.qual, ni->ni_snr);
163
 
        current_ev = IWE_STREAM_ADD_EVENT(param->info, current_ev, end_buf,
164
 
                                          &iwe, IW_EV_QUAL_LEN);
165
 
    }
166
 
    param->bytes_needed += IW_EV_QUAL_LEN;
167
 
 
168
 
    if ((end_buf - current_ev) > IW_EV_POINT_LEN)
169
 
    {
170
 
        A_MEMZERO(&iwe, sizeof(iwe));
171
 
        iwe.cmd = SIOCGIWENCODE;
172
 
        if (cie->ie_capInfo & IEEE80211_CAPINFO_PRIVACY) {
173
 
            iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
174
 
        } else {
175
 
            iwe.u.data.flags = IW_ENCODE_DISABLED;
176
 
        }
177
 
        iwe.u.data.length = 0;
178
 
        current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, end_buf,
179
 
                                          &iwe, "");
180
 
    }
181
 
    param->bytes_needed += IW_EV_POINT_LEN;
182
 
 
183
 
    /* supported bit rate */
184
 
    A_MEMZERO(&iwe, sizeof(iwe));
185
 
    iwe.cmd = SIOCGIWRATE;
186
 
    iwe.u.bitrate.fixed = 0;
187
 
    iwe.u.bitrate.disabled = 0;
188
 
    iwe.u.bitrate.value = 0;
189
 
    current_val = current_ev + IW_EV_LCP_LEN;
190
 
    param->bytes_needed += IW_EV_LCP_LEN;
191
 
 
192
 
    if (cie->ie_rates != NULL) {
193
 
        rate_len = cie->ie_rates[1];
194
 
        data_len = (rate_len * (IW_EV_PARAM_LEN - IW_EV_LCP_LEN));
195
 
        if ((end_buf - current_ev) > data_len)
196
 
        {
197
 
            for (j = 0; j < rate_len; j++) {
198
 
                    unsigned char val;
199
 
                    val = cie->ie_rates[2 + j];
200
 
                    iwe.u.bitrate.value =
201
 
                        (val >= 0x80)? ((val - 0x80) * 500000): (val * 500000);
202
 
                    current_val = IWE_STREAM_ADD_VALUE(param->info, current_ev,
203
 
                                                       current_val, end_buf,
204
 
                                                       &iwe, IW_EV_PARAM_LEN);
205
 
            }
206
 
        }
207
 
        param->bytes_needed += data_len;
208
 
    }
209
 
 
210
 
    if (cie->ie_xrates != NULL) {
211
 
        rate_len = cie->ie_xrates[1];
212
 
        data_len = (rate_len * (IW_EV_PARAM_LEN - IW_EV_LCP_LEN));
213
 
        if ((end_buf - current_ev) > data_len)
214
 
        {
215
 
            for (j = 0; j < rate_len; j++) {
216
 
                    unsigned char val;
217
 
                    val = cie->ie_xrates[2 + j];
218
 
                    iwe.u.bitrate.value =
219
 
                        (val >= 0x80)? ((val - 0x80) * 500000): (val * 500000);
220
 
                    current_val = IWE_STREAM_ADD_VALUE(param->info, current_ev,
221
 
                                                       current_val, end_buf,
222
 
                                                       &iwe, IW_EV_PARAM_LEN);
223
 
            }
224
 
        }
225
 
        param->bytes_needed += data_len;
226
 
    }
227
 
    /* remove fixed header if no rates were added */
228
 
    if ((current_val - current_ev) > IW_EV_LCP_LEN)
229
 
        current_ev = current_val;
230
 
 
231
 
#if WIRELESS_EXT >= 18
232
 
    /* IE */
233
 
    if (cie->ie_wpa != NULL) {
234
 
        data_len = cie->ie_wpa[1] + 2 + IW_EV_POINT_LEN;
235
 
        if ((end_buf - current_ev) > data_len)
236
 
        {
237
 
            A_MEMZERO(&iwe, sizeof(iwe));
238
 
            iwe.cmd = IWEVGENIE;
239
 
            iwe.u.data.length = cie->ie_wpa[1] + 2;
240
 
            current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, end_buf,
241
 
                                              &iwe, (char*)cie->ie_wpa);
242
 
        }
243
 
        param->bytes_needed += data_len;
244
 
    }
245
 
 
246
 
    if (cie->ie_rsn != NULL && cie->ie_rsn[0] == IEEE80211_ELEMID_RSN) {
247
 
        data_len = cie->ie_rsn[1] + 2 + IW_EV_POINT_LEN;
248
 
        if ((end_buf - current_ev) > data_len)
249
 
        {
250
 
            A_MEMZERO(&iwe, sizeof(iwe));
251
 
            iwe.cmd = IWEVGENIE;
252
 
            iwe.u.data.length = cie->ie_rsn[1] + 2;
253
 
            current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, end_buf,
254
 
                                              &iwe, (char*)cie->ie_rsn);
255
 
        }
256
 
        param->bytes_needed += data_len;
257
 
    }
258
 
 
259
 
#endif /* WIRELESS_EXT >= 18 */
260
 
 
261
 
    if ((end_buf - current_ev) > IW_EV_CHAR_LEN)
262
 
    {
263
 
        /* protocol */
264
 
        A_MEMZERO(&iwe, sizeof(iwe));
265
 
        iwe.cmd = SIOCGIWNAME;
266
 
        switch (get_bss_phy_capability(ni)) {
267
 
        case WMI_11A_CAPABILITY:
268
 
            snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11a");
269
 
            break;
270
 
        case WMI_11G_CAPABILITY:
271
 
            snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
272
 
            break;
273
 
        case WMI_11NA_CAPABILITY:
274
 
            snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11na");
275
 
            break;
276
 
        case WMI_11NG_CAPABILITY:
277
 
            snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11ng");
278
 
            break;
279
 
        default:
280
 
            snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
281
 
            break;
282
 
        }
283
 
        current_ev = IWE_STREAM_ADD_EVENT(param->info, current_ev, end_buf,
284
 
                                          &iwe, IW_EV_CHAR_LEN);
285
 
    }
286
 
    param->bytes_needed += IW_EV_CHAR_LEN;
287
 
 
288
 
#if WIRELESS_EXT > 14
289
 
    A_MEMZERO(&iwe, sizeof(iwe));
290
 
    iwe.cmd = IWEVCUSTOM;
291
 
    iwe.u.data.length = snprintf(buf, sizeof(buf), "bcn_int=%d", cie->ie_beaconInt);
292
 
    data_len = iwe.u.data.length + IW_EV_POINT_LEN;
293
 
    if ((end_buf - current_ev) > data_len)
294
 
    {
295
 
        current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, end_buf,
296
 
                                          &iwe, buf);
297
 
    }
298
 
    param->bytes_needed += data_len;
299
 
 
300
 
#if WIRELESS_EXT < 18
301
 
    if (cie->ie_wpa != NULL) {
302
 
        static const char wpa_leader[] = "wpa_ie=";
303
 
        data_len = (sizeof(wpa_leader) - 1) + ((cie->ie_wpa[1]+2) * 2) + IW_EV_POINT_LEN;
304
 
        if ((end_buf - current_ev) > data_len)
305
 
        {
306
 
            A_MEMZERO(&iwe, sizeof(iwe));
307
 
            iwe.cmd = IWEVCUSTOM;
308
 
            iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_wpa,
309
 
                                          cie->ie_wpa[1]+2,
310
 
                                          wpa_leader, sizeof(wpa_leader)-1);
311
 
 
312
 
            if (iwe.u.data.length != 0) {
313
 
                current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, 
314
 
                                                  end_buf, &iwe, buf);
315
 
            }
316
 
        }
317
 
        param->bytes_needed += data_len;
318
 
    }
319
 
 
320
 
    if (cie->ie_rsn != NULL && cie->ie_rsn[0] == IEEE80211_ELEMID_RSN) {
321
 
        static const char rsn_leader[] = "rsn_ie=";
322
 
        data_len = (sizeof(rsn_leader) - 1) + ((cie->ie_rsn[1]+2) * 2) + IW_EV_POINT_LEN;
323
 
        if ((end_buf - current_ev) > data_len)
324
 
        {
325
 
            A_MEMZERO(&iwe, sizeof(iwe));
326
 
            iwe.cmd = IWEVCUSTOM;
327
 
            iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_rsn,
328
 
                                          cie->ie_rsn[1]+2,
329
 
                                          rsn_leader, sizeof(rsn_leader)-1);
330
 
 
331
 
            if (iwe.u.data.length != 0) {
332
 
                current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, 
333
 
                                                  end_buf, &iwe, buf);
334
 
            }
335
 
        }
336
 
        param->bytes_needed += data_len;
337
 
    }
338
 
#endif /* WIRELESS_EXT < 18 */
339
 
 
340
 
    if (cie->ie_wmm != NULL) {
341
 
        static const char wmm_leader[] = "wmm_ie=";
342
 
        data_len = (sizeof(wmm_leader) - 1) + ((cie->ie_wmm[1]+2) * 2) + IW_EV_POINT_LEN;
343
 
        if ((end_buf - current_ev) > data_len)
344
 
        {
345
 
            A_MEMZERO(&iwe, sizeof(iwe));
346
 
            iwe.cmd = IWEVCUSTOM;
347
 
            iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_wmm,
348
 
                                          cie->ie_wmm[1]+2,
349
 
                                          wmm_leader, sizeof(wmm_leader)-1);
350
 
            if (iwe.u.data.length != 0) {
351
 
                current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev,
352
 
                                                  end_buf, &iwe, buf);
353
 
            }
354
 
        }
355
 
        param->bytes_needed += data_len;
356
 
    }
357
 
 
358
 
    if (cie->ie_ath != NULL) {
359
 
        static const char ath_leader[] = "ath_ie=";
360
 
        data_len = (sizeof(ath_leader) - 1) + ((cie->ie_ath[1]+2) * 2) + IW_EV_POINT_LEN;
361
 
        if ((end_buf - current_ev) > data_len)
362
 
        {
363
 
            A_MEMZERO(&iwe, sizeof(iwe));
364
 
            iwe.cmd = IWEVCUSTOM;
365
 
            iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_ath,
366
 
                                          cie->ie_ath[1]+2,
367
 
                                          ath_leader, sizeof(ath_leader)-1);
368
 
            if (iwe.u.data.length != 0) {
369
 
                current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev,
370
 
                                                  end_buf, &iwe, buf);
371
 
            }
372
 
        }
373
 
        param->bytes_needed += data_len;
374
 
    }
375
 
 
376
 
#ifdef WAPI_ENABLE
377
 
    if (cie->ie_wapi != NULL) {
378
 
        static const char wapi_leader[] = "wapi_ie=";
379
 
        data_len = (sizeof(wapi_leader) - 1) + ((cie->ie_wapi[1] + 2) * 2) + IW_EV_POINT_LEN;
380
 
        if ((end_buf - current_ev) > data_len) {
381
 
            A_MEMZERO(&iwe, sizeof(iwe));
382
 
            iwe.cmd = IWEVCUSTOM;
383
 
            iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_wapi,
384
 
                                      cie->ie_wapi[1] + 2,
385
 
                                      wapi_leader, sizeof(wapi_leader) - 1);
386
 
            if (iwe.u.data.length != 0) {
387
 
                current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev,
388
 
                                                  end_buf, &iwe, buf);
389
 
            }
390
 
        }
391
 
        param->bytes_needed += data_len;
392
 
    }
393
 
#endif /* WAPI_ENABLE */
394
 
 
395
 
#endif /* WIRELESS_EXT > 14 */
396
 
 
397
 
#if WIRELESS_EXT >= 18
398
 
    if (cie->ie_wsc != NULL) {
399
 
        data_len = (cie->ie_wsc[1] + 2) + IW_EV_POINT_LEN;
400
 
        if ((end_buf - current_ev) > data_len)
401
 
        {
402
 
            A_MEMZERO(&iwe, sizeof(iwe));
403
 
            iwe.cmd = IWEVGENIE;
404
 
            iwe.u.data.length = cie->ie_wsc[1] + 2;
405
 
            current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, end_buf,
406
 
                                              &iwe, (char*)cie->ie_wsc);
407
 
        }
408
 
        param->bytes_needed += data_len;
409
 
    }
410
 
#endif /* WIRELESS_EXT >= 18 */
411
 
 
412
 
    param->current_ev = current_ev;
413
 
}
414
 
 
415
 
int
416
 
ar6000_ioctl_giwscan(struct net_device *dev,
417
 
            struct iw_request_info *info,
418
 
            struct iw_point *data, char *extra)
419
 
{
420
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
421
 
    struct ar_giwscan_param param;
422
 
 
423
 
    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
424
 
        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
425
 
        return -EOPNOTSUPP;
426
 
    }
427
 
 
428
 
    if (ar->arWlanState == WLAN_DISABLED) {
429
 
        return -EIO;
430
 
    }
431
 
 
432
 
    if (ar->arWmiReady == FALSE) {
433
 
        return -EIO;
434
 
    }
435
 
 
436
 
    param.current_ev = extra;
437
 
    param.end_buf = extra + data->length;
438
 
    param.bytes_needed = 0;
439
 
    param.info = info;
440
 
 
441
 
    /* Translate data to WE format */
442
 
    wmi_iterate_nodes(ar->arWmi, ar6000_scan_node, &param);
443
 
 
444
 
    /* check if bytes needed is greater than bytes consumed */
445
 
    if (param.bytes_needed > (param.current_ev - extra))
446
 
    {
447
 
        /* Request one byte more than needed, because when "data->length" equals bytes_needed,
448
 
        it is not possible to add the last event data as all iwe_stream_add_xxxxx() functions
449
 
        checks whether (cur_ptr + ev_len) < end_ptr, due to this one more retry would happen*/
450
 
        data->length = param.bytes_needed + 1;
451
 
 
452
 
        return -E2BIG;
453
 
    }
454
 
 
455
 
    return 0;
456
 
}
457
 
 
458
 
extern int reconnect_flag;
459
 
/* SIOCSIWESSID */
460
 
static int
461
 
ar6000_ioctl_siwessid(struct net_device *dev,
462
 
                     struct iw_request_info *info,
463
 
                     struct iw_point *data, char *ssid)
464
 
{
465
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
466
 
    A_STATUS status;
467
 
    A_UINT8     arNetworkType;
468
 
    A_UINT8 prevMode = ar->arNetworkType;
469
 
 
470
 
    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
471
 
        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
472
 
        return -EOPNOTSUPP;
473
 
    }
474
 
 
475
 
    if (ar->bIsDestroyProgress) {
476
 
        return -EBUSY;
477
 
    }
478
 
 
479
 
    if (ar->arWlanState == WLAN_DISABLED) {
480
 
        return -EIO;
481
 
    }
482
 
 
483
 
    if (ar->arWmiReady == FALSE) {
484
 
        return -EIO;
485
 
    }
486
 
 
487
 
#if defined(WIRELESS_EXT)
488
 
    if (WIRELESS_EXT >= 20) {
489
 
        data->length += 1;
490
 
    }
491
 
#endif
492
 
 
493
 
    /*
494
 
     * iwconfig passes a null terminated string with length including this
495
 
     * so we need to account for this
496
 
     */
497
 
    if (data->flags && (!data->length || (data->length == 1) ||
498
 
        ((data->length - 1) > sizeof(ar->arSsid))))
499
 
    {
500
 
        /*
501
 
         * ssid is invalid
502
 
         */
503
 
        return -EINVAL;
504
 
    }
505
 
 
506
 
    if (ar->arNextMode == AP_NETWORK) {
507
 
        /* SSID change for AP network - Will take effect on commit */
508
 
        if(A_MEMCMP(ar->arSsid,ssid,32) != 0) {
509
 
             ar->arSsidLen = data->length - 1;
510
 
            A_MEMCPY(ar->arSsid, ssid, ar->arSsidLen);
511
 
            ar->ap_profile_flag = 1; /* There is a change in profile */
512
 
        }
513
 
        return 0;
514
 
    } else if(ar->arNetworkType == AP_NETWORK) {
515
 
        A_UINT8 ctr;
516
 
        struct sk_buff *skb;
517
 
 
518
 
        /* We are switching from AP to STA | IBSS mode, cleanup the AP state */
519
 
        for (ctr=0; ctr < AP_MAX_NUM_STA; ctr++) {
520
 
            remove_sta(ar, ar->sta_list[ctr].mac, 0);
521
 
        }
522
 
        A_MUTEX_LOCK(&ar->mcastpsqLock);
523
 
        while (!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) {
524
 
            skb = A_NETBUF_DEQUEUE(&ar->mcastpsq);
525
 
            A_NETBUF_FREE(skb);
526
 
        }
527
 
        A_MUTEX_UNLOCK(&ar->mcastpsqLock);
528
 
    }
529
 
 
530
 
    /* Added for bug 25178, return an IOCTL error instead of target returning
531
 
       Illegal parameter error when either the BSSID or channel is missing
532
 
       and we cannot scan during connect.
533
 
     */
534
 
    if (data->flags) {
535
 
        if (ar->arSkipScan == TRUE &&
536
 
            (ar->arChannelHint == 0 ||
537
 
             (!ar->arReqBssid[0] && !ar->arReqBssid[1] && !ar->arReqBssid[2] &&
538
 
              !ar->arReqBssid[3] && !ar->arReqBssid[4] && !ar->arReqBssid[5])))
539
 
        {
540
 
            return -EINVAL;
541
 
        }
542
 
    }
543
 
 
544
 
    if (down_interruptible(&ar->arSem)) {
545
 
        return -ERESTARTSYS;
546
 
    }
547
 
 
548
 
    if (ar->bIsDestroyProgress || ar->arWlanState == WLAN_DISABLED) {
549
 
        up(&ar->arSem);
550
 
        return -EBUSY;
551
 
    }
552
 
 
553
 
    if (ar->arTxPending[wmi_get_control_ep(ar->arWmi)]) {
554
 
        /*
555
 
         * sleep until the command queue drains
556
 
         */
557
 
        wait_event_interruptible_timeout(arEvent,
558
 
            ar->arTxPending[wmi_get_control_ep(ar->arWmi)] == 0, wmitimeout * HZ);
559
 
        if (signal_pending(current)) {
560
 
            return -EINTR;
561
 
        }
562
 
    }
563
 
 
564
 
    if (!data->flags) {
565
 
        arNetworkType = ar->arNetworkType;
566
 
#ifdef ATH6K_CONFIG_CFG80211
567
 
        if (ar->arConnected) {
568
 
#endif /* ATH6K_CONFIG_CFG80211 */
569
 
            ar6000_init_profile_info(ar);
570
 
#ifdef ATH6K_CONFIG_CFG80211
571
 
        }
572
 
#endif /* ATH6K_CONFIG_CFG80211 */
573
 
        ar->arNetworkType = arNetworkType;
574
 
    }
575
 
 
576
 
    /* Update the arNetworkType */
577
 
    ar->arNetworkType = ar->arNextMode;
578
 
 
579
 
 
580
 
    if ((prevMode != AP_NETWORK) &&
581
 
        ((ar->arSsidLen) || ((ar->arSsidLen == 0) && ar->arConnected) || (!data->flags)))
582
 
    {
583
 
        if ((!data->flags) ||
584
 
            (A_MEMCMP(ar->arSsid, ssid, ar->arSsidLen) != 0) ||
585
 
            (ar->arSsidLen != (data->length - 1)))
586
 
        {
587
 
            /*
588
 
             * SSID set previously or essid off has been issued.
589
 
             *
590
 
             * Disconnect Command is issued in two cases after wmi is ready
591
 
             * (1) ssid is different from the previous setting
592
 
             * (2) essid off has been issued
593
 
             *
594
 
             */
595
 
            if (ar->arWmiReady == TRUE) {
596
 
                reconnect_flag = 0;
597
 
                status = wmi_setPmkid_cmd(ar->arWmi, ar->arBssid, NULL, 0);
598
 
                status = wmi_disconnect_cmd(ar->arWmi);
599
 
                A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
600
 
                ar->arSsidLen = 0;
601
 
                if (ar->arSkipScan == FALSE) {
602
 
                    A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
603
 
                }
604
 
                if (!data->flags) {
605
 
                    up(&ar->arSem);
606
 
                    return 0;
607
 
                }
608
 
            } else {
609
 
                 up(&ar->arSem);
610
 
            }
611
 
        }
612
 
        else
613
 
        {
614
 
            /*
615
 
             * SSID is same, so we assume profile hasn't changed.
616
 
             * If the interface is up and wmi is ready, we issue
617
 
             * a reconnect cmd. Issue a reconnect only we are already
618
 
             * connected.
619
 
             */
620
 
            if((ar->arConnected == TRUE) && (ar->arWmiReady == TRUE))
621
 
            {
622
 
                reconnect_flag = TRUE;
623
 
                status = wmi_reconnect_cmd(ar->arWmi,ar->arReqBssid,
624
 
                                           ar->arChannelHint);
625
 
                up(&ar->arSem);
626
 
                if (status != A_OK) {
627
 
                    return -EIO;
628
 
                }
629
 
                return 0;
630
 
            }
631
 
            else{
632
 
                /*
633
 
                 * Dont return if connect is pending.
634
 
                 */
635
 
                if(!(ar->arConnectPending)) {
636
 
                    up(&ar->arSem);
637
 
                    return 0;
638
 
                }
639
 
            }
640
 
        }
641
 
    }
642
 
 
643
 
    ar->arSsidLen = data->length - 1;
644
 
    A_MEMCPY(ar->arSsid, ssid, ar->arSsidLen);
645
 
 
646
 
    if (ar6000_connect_to_ap(ar)!= A_OK) {
647
 
        up(&ar->arSem);
648
 
        return -EIO;
649
 
    }else{
650
 
      up(&ar->arSem);
651
 
    }
652
 
    return 0;
653
 
}
654
 
 
655
 
/* SIOCGIWESSID */
656
 
static int
657
 
ar6000_ioctl_giwessid(struct net_device *dev,
658
 
                     struct iw_request_info *info,
659
 
                     struct iw_point *data, char *essid)
660
 
{
661
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
662
 
 
663
 
    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
664
 
        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
665
 
        return -EOPNOTSUPP;
666
 
    }
667
 
 
668
 
    if (ar->arWlanState == WLAN_DISABLED) {
669
 
        return -EIO;
670
 
    }
671
 
 
672
 
    if (!ar->arSsidLen) {
673
 
        return -EINVAL;
674
 
    }
675
 
 
676
 
    data->flags = 1;
677
 
    data->length = ar->arSsidLen;
678
 
    A_MEMCPY(essid, ar->arSsid, ar->arSsidLen);
679
 
 
680
 
    return 0;
681
 
}
682
 
 
683
 
 
684
 
void ar6000_install_static_wep_keys(AR_SOFTC_T *ar)
685
 
{
686
 
    A_UINT8 index;
687
 
    A_UINT8 keyUsage;
688
 
 
689
 
    for (index = WMI_MIN_KEY_INDEX; index <= WMI_MAX_KEY_INDEX; index++) {
690
 
        if (ar->arWepKeyList[index].arKeyLen) {
691
 
            keyUsage = GROUP_USAGE;
692
 
            if (index == ar->arDefTxKeyIndex) {
693
 
                keyUsage |= TX_USAGE;
694
 
            }
695
 
            wmi_addKey_cmd(ar->arWmi,
696
 
                           index,
697
 
                           WEP_CRYPT,
698
 
                           keyUsage,
699
 
                           ar->arWepKeyList[index].arKeyLen,
700
 
                           NULL,
701
 
                           ar->arWepKeyList[index].arKey, KEY_OP_INIT_VAL, NULL,
702
 
                           NO_SYNC_WMIFLAG);
703
 
        }
704
 
    }
705
 
}
706
 
 
707
 
/*
708
 
 * SIOCSIWRATE
709
 
 */
710
 
int
711
 
ar6000_ioctl_siwrate(struct net_device *dev,
712
 
            struct iw_request_info *info,
713
 
            struct iw_param *rrq, char *extra)
714
 
{
715
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
716
 
    A_UINT32  kbps;
717
 
    A_INT8  rate_idx;
718
 
 
719
 
    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
720
 
        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
721
 
        return -EOPNOTSUPP;
722
 
    }
723
 
 
724
 
    if (rrq->fixed) {
725
 
        kbps = rrq->value / 1000;           /* rrq->value is in bps */
726
 
    } else {
727
 
        kbps = -1;                          /* -1 indicates auto rate */
728
 
    }
729
 
    if(kbps != -1 && wmi_validate_bitrate(ar->arWmi, kbps, &rate_idx) != A_OK)
730
 
    {
731
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BitRate is not Valid %d\n", kbps));
732
 
        return -EINVAL;
733
 
    }
734
 
    ar->arBitRate = kbps;
735
 
    if(ar->arWmiReady == TRUE)
736
 
    {
737
 
        if (wmi_set_bitrate_cmd(ar->arWmi, kbps, -1, -1) != A_OK) {
738
 
            return -EINVAL;
739
 
        }
740
 
    }
741
 
    return 0;
742
 
}
743
 
 
744
 
/*
745
 
 * SIOCGIWRATE
746
 
 */
747
 
int
748
 
ar6000_ioctl_giwrate(struct net_device *dev,
749
 
            struct iw_request_info *info,
750
 
            struct iw_param *rrq, char *extra)
751
 
{
752
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
753
 
    int ret = 0;
754
 
 
755
 
    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
756
 
        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
757
 
        return -EOPNOTSUPP;
758
 
    }
759
 
 
760
 
    if (ar->bIsDestroyProgress) {
761
 
        return -EBUSY;
762
 
    }
763
 
 
764
 
    if (ar->arWlanState == WLAN_DISABLED) {
765
 
        return -EIO;
766
 
    }
767
 
 
768
 
    if ((ar->arNextMode != AP_NETWORK && !ar->arConnected) || ar->arWmiReady == FALSE) {
769
 
        rrq->value = 1000 * 1000;       
770
 
        return 0;
771
 
    }
772
 
 
773
 
    if (down_interruptible(&ar->arSem)) {
774
 
        return -ERESTARTSYS;
775
 
    }
776
 
 
777
 
    if (ar->bIsDestroyProgress || ar->arWlanState == WLAN_DISABLED) {
778
 
        up(&ar->arSem);
779
 
        return -EBUSY;
780
 
    }
781
 
 
782
 
    ar->arBitRate = 0xFFFF;
783
 
    if (wmi_get_bitrate_cmd(ar->arWmi) != A_OK) {
784
 
        up(&ar->arSem);
785
 
        return -EIO;
786
 
    }
787
 
    wait_event_interruptible_timeout(arEvent, ar->arBitRate != 0xFFFF, wmitimeout * HZ);
788
 
    if (signal_pending(current)) {
789
 
        ret = -EINTR;
790
 
    }
791
 
    /* If the interface is down or wmi is not ready or the target is not
792
 
       connected - return the value stored in the device structure */
793
 
    if (!ret) {
794
 
        if (ar->arBitRate == -1) {
795
 
            rrq->fixed = TRUE;
796
 
            rrq->value = 0;
797
 
        } else {
798
 
            rrq->value = ar->arBitRate * 1000;
799
 
        }
800
 
    }
801
 
 
802
 
    up(&ar->arSem);
803
 
 
804
 
    return ret;
805
 
}
806
 
 
807
 
/*
808
 
 * SIOCSIWTXPOW
809
 
 */
810
 
static int
811
 
ar6000_ioctl_siwtxpow(struct net_device *dev,
812
 
             struct iw_request_info *info,
813
 
             struct iw_param *rrq, char *extra)
814
 
{
815
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
816
 
    A_UINT8 dbM;
817
 
 
818
 
    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
819
 
        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
820
 
        return -EOPNOTSUPP;
821
 
    }
822
 
 
823
 
    if (ar->arWlanState == WLAN_DISABLED) {
824
 
        return -EIO;
825
 
    }
826
 
 
827
 
    if (rrq->disabled) {
828
 
        return -EOPNOTSUPP;
829
 
    }
830
 
 
831
 
    if (rrq->fixed) {
832
 
        if (rrq->flags != IW_TXPOW_DBM) {
833
 
            return -EOPNOTSUPP;
834
 
        }
835
 
        ar->arTxPwr= dbM = rrq->value;
836
 
        ar->arTxPwrSet = TRUE;
837
 
    } else {
838
 
        ar->arTxPwr = dbM = 0;
839
 
        ar->arTxPwrSet = FALSE;
840
 
    }
841
 
    if(ar->arWmiReady == TRUE)
842
 
    {
843
 
        AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("Set tx pwr cmd %d dbM\n", dbM));
844
 
        wmi_set_txPwr_cmd(ar->arWmi, dbM);
845
 
    }
846
 
    return 0;
847
 
}
848
 
 
849
 
/*
850
 
 * SIOCGIWTXPOW
851
 
 */
852
 
int
853
 
ar6000_ioctl_giwtxpow(struct net_device *dev,
854
 
            struct iw_request_info *info,
855
 
            struct iw_param *rrq, char *extra)
856
 
{
857
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
858
 
    int ret = 0;
859
 
 
860
 
    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
861
 
        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
862
 
        return -EOPNOTSUPP;
863
 
    }
864
 
 
865
 
    if (ar->bIsDestroyProgress) {
866
 
        return -EBUSY;
867
 
    }
868
 
 
869
 
    if (ar->arWlanState == WLAN_DISABLED) {
870
 
        return -EIO;
871
 
    }
872
 
 
873
 
    if (down_interruptible(&ar->arSem)) {
874
 
        return -ERESTARTSYS;
875
 
    }
876
 
 
877
 
    if (ar->bIsDestroyProgress) {
878
 
        up(&ar->arSem);
879
 
        return -EBUSY;
880
 
    }
881
 
 
882
 
    if((ar->arWmiReady == TRUE) && (ar->arConnected == TRUE))
883
 
    {
884
 
        ar->arTxPwr = 0;
885
 
 
886
 
        if (wmi_get_txPwr_cmd(ar->arWmi) != A_OK) {
887
 
            up(&ar->arSem);
888
 
            return -EIO;
889
 
        }
890
 
 
891
 
        wait_event_interruptible_timeout(arEvent, ar->arTxPwr != 0, wmitimeout * HZ);
892
 
 
893
 
        if (signal_pending(current)) {
894
 
            ret = -EINTR;
895
 
         }
896
 
    }
897
 
   /* If the interace is down or wmi is not ready or target is not connected
898
 
      then return value stored in the device structure */
899
 
 
900
 
    if (!ret) {
901
 
         if (ar->arTxPwrSet == TRUE) {
902
 
            rrq->fixed = TRUE;
903
 
        }
904
 
        rrq->value = ar->arTxPwr;
905
 
        rrq->flags = IW_TXPOW_DBM;
906
 
        //
907
 
        // IWLIST need this flag to get TxPower
908
 
        //
909
 
        rrq->disabled = 0;
910
 
    }
911
 
 
912
 
    up(&ar->arSem);
913
 
 
914
 
    return ret;
915
 
}
916
 
 
917
 
/*
918
 
 * SIOCSIWRETRY
919
 
 * since iwconfig only provides us with one max retry value, we use it
920
 
 * to apply to data frames of the BE traffic class.
921
 
 */
922
 
static int
923
 
ar6000_ioctl_siwretry(struct net_device *dev,
924
 
             struct iw_request_info *info,
925
 
             struct iw_param *rrq, char *extra)
926
 
{
927
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
928
 
 
929
 
    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
930
 
        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
931
 
        return -EOPNOTSUPP;
932
 
    }
933
 
 
934
 
    if (ar->arWlanState == WLAN_DISABLED) {
935
 
        return -EIO;
936
 
    }
937
 
 
938
 
    if (rrq->disabled) {
939
 
        return -EOPNOTSUPP;
940
 
    }
941
 
 
942
 
    if ((rrq->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT) {
943
 
        return -EOPNOTSUPP;
944
 
    }
945
 
 
946
 
    if ( !(rrq->value >= WMI_MIN_RETRIES) || !(rrq->value <= WMI_MAX_RETRIES)) {
947
 
            return - EINVAL;
948
 
    }
949
 
    if(ar->arWmiReady == TRUE)
950
 
    {
951
 
        if (wmi_set_retry_limits_cmd(ar->arWmi, DATA_FRAMETYPE, WMM_AC_BE,
952
 
                                     rrq->value, 0) != A_OK){
953
 
            return -EINVAL;
954
 
        }
955
 
    }
956
 
    ar->arMaxRetries = rrq->value;
957
 
    return 0;
958
 
}
959
 
 
960
 
/*
961
 
 * SIOCGIWRETRY
962
 
 */
963
 
static int
964
 
ar6000_ioctl_giwretry(struct net_device *dev,
965
 
             struct iw_request_info *info,
966
 
             struct iw_param *rrq, char *extra)
967
 
{
968
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
969
 
 
970
 
    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
971
 
        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
972
 
        return -EOPNOTSUPP;
973
 
    }
974
 
 
975
 
    if (ar->arWlanState == WLAN_DISABLED) {
976
 
        return -EIO;
977
 
    }
978
 
 
979
 
    rrq->disabled = 0;
980
 
    switch (rrq->flags & IW_RETRY_TYPE) {
981
 
    case IW_RETRY_LIFETIME:
982
 
        return -EOPNOTSUPP;
983
 
        break;
984
 
    case IW_RETRY_LIMIT:
985
 
        rrq->flags = IW_RETRY_LIMIT;
986
 
        switch (rrq->flags & IW_RETRY_MODIFIER) {
987
 
        case IW_RETRY_MIN:
988
 
            rrq->flags |= IW_RETRY_MIN;
989
 
            rrq->value = WMI_MIN_RETRIES;
990
 
            break;
991
 
        case IW_RETRY_MAX:
992
 
            rrq->flags |= IW_RETRY_MAX;
993
 
            rrq->value = ar->arMaxRetries;
994
 
            break;
995
 
        }
996
 
        break;
997
 
    }
998
 
    return 0;
999
 
}
1000
 
 
1001
 
/*
1002
 
 * SIOCSIWENCODE
1003
 
 */
1004
 
static int
1005
 
ar6000_ioctl_siwencode(struct net_device *dev,
1006
 
              struct iw_request_info *info,
1007
 
              struct iw_point *erq, char *keybuf)
1008
 
{
1009
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1010
 
    int index;
1011
 
    A_INT32 auth = 0;
1012
 
 
1013
 
    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
1014
 
        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
1015
 
        return -EOPNOTSUPP;
1016
 
    }
1017
 
 
1018
 
    if(ar->arNextMode != AP_NETWORK) {
1019
 
    /*
1020
 
     *  Static WEP Keys should be configured before setting the SSID
1021
 
     */
1022
 
    if (ar->arSsid[0] && erq->length) {
1023
 
        return -EIO;
1024
 
    }
1025
 
    }
1026
 
 
1027
 
    if (ar->arWlanState == WLAN_DISABLED) {
1028
 
        return -EIO;
1029
 
    }
1030
 
 
1031
 
    index = erq->flags & IW_ENCODE_INDEX;
1032
 
 
1033
 
    if (index && (((index - 1) < WMI_MIN_KEY_INDEX) ||
1034
 
                  ((index - 1) > WMI_MAX_KEY_INDEX)))
1035
 
    {
1036
 
        return -EIO;
1037
 
    }
1038
 
 
1039
 
    if (erq->flags & IW_ENCODE_DISABLED) {
1040
 
        /*
1041
 
         * Encryption disabled
1042
 
         */
1043
 
        if (index) {
1044
 
            /*
1045
 
             * If key index was specified then clear the specified key
1046
 
             */
1047
 
            index--;
1048
 
            A_MEMZERO(ar->arWepKeyList[index].arKey,
1049
 
                      sizeof(ar->arWepKeyList[index].arKey));
1050
 
            ar->arWepKeyList[index].arKeyLen = 0;
1051
 
        }
1052
 
        ar->arDot11AuthMode       = OPEN_AUTH;
1053
 
        ar->arPairwiseCrypto      = NONE_CRYPT;
1054
 
        ar->arGroupCrypto         = NONE_CRYPT;
1055
 
        ar->arAuthMode            = NONE_AUTH;
1056
 
    } else {
1057
 
        /*
1058
 
         * Enabling WEP encryption
1059
 
         */
1060
 
        if (index) {
1061
 
            index--;                /* keyindex is off base 1 in iwconfig */
1062
 
        }
1063
 
 
1064
 
        if (erq->flags & IW_ENCODE_OPEN) {
1065
 
            auth |= OPEN_AUTH;
1066
 
            ar->arDefTxKeyIndex = index;
1067
 
        }
1068
 
        if (erq->flags & IW_ENCODE_RESTRICTED) {
1069
 
            auth |= SHARED_AUTH;
1070
 
        }
1071
 
 
1072
 
        if (!auth) {
1073
 
            auth = OPEN_AUTH;
1074
 
        }
1075
 
 
1076
 
        if (erq->length) {
1077
 
            if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(erq->length)) {
1078
 
                return -EIO;
1079
 
            }
1080
 
 
1081
 
            A_MEMZERO(ar->arWepKeyList[index].arKey,
1082
 
                      sizeof(ar->arWepKeyList[index].arKey));
1083
 
            A_MEMCPY(ar->arWepKeyList[index].arKey, keybuf, erq->length);
1084
 
            ar->arWepKeyList[index].arKeyLen = erq->length;
1085
 
            ar->arDot11AuthMode       = auth;
1086
 
        } else {
1087
 
            if (ar->arWepKeyList[index].arKeyLen == 0) {
1088
 
                return -EIO;
1089
 
            }
1090
 
            ar->arDefTxKeyIndex = index;
1091
 
 
1092
 
            if(ar->arSsidLen && ar->arWepKeyList[index].arKeyLen) {
1093
 
                wmi_addKey_cmd(ar->arWmi,
1094
 
                               index,
1095
 
                               WEP_CRYPT,
1096
 
                               GROUP_USAGE | TX_USAGE,
1097
 
                               ar->arWepKeyList[index].arKeyLen,
1098
 
                               NULL,
1099
 
                               ar->arWepKeyList[index].arKey, KEY_OP_INIT_VAL, NULL,
1100
 
                               NO_SYNC_WMIFLAG);
1101
 
            }
1102
 
        }
1103
 
 
1104
 
        ar->arPairwiseCrypto      = WEP_CRYPT;
1105
 
        ar->arGroupCrypto         = WEP_CRYPT;
1106
 
        ar->arAuthMode            = NONE_AUTH;
1107
 
    }
1108
 
 
1109
 
    if(ar->arNextMode != AP_NETWORK) {
1110
 
    /*
1111
 
     * profile has changed.  Erase ssid to signal change
1112
 
     */
1113
 
        A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
1114
 
        ar->arSsidLen = 0;
1115
 
    }
1116
 
    ar->ap_profile_flag = 1; /* There is a change in profile */
1117
 
    return 0;
1118
 
}
1119
 
 
1120
 
static int
1121
 
ar6000_ioctl_giwencode(struct net_device *dev,
1122
 
              struct iw_request_info *info,
1123
 
              struct iw_point *erq, char *key)
1124
 
{
1125
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1126
 
    A_UINT8 keyIndex;
1127
 
    struct ar_wep_key *wk;
1128
 
 
1129
 
    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
1130
 
        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
1131
 
        return -EOPNOTSUPP;
1132
 
    }
1133
 
 
1134
 
    if (ar->arWlanState == WLAN_DISABLED) {
1135
 
        return -EIO;
1136
 
    }
1137
 
 
1138
 
    if (ar->arPairwiseCrypto == NONE_CRYPT) {
1139
 
        erq->length = 0;
1140
 
        erq->flags = IW_ENCODE_DISABLED;
1141
 
    } else {
1142
 
        if (ar->arPairwiseCrypto == WEP_CRYPT) {
1143
 
            /* get the keyIndex */
1144
 
            keyIndex = erq->flags & IW_ENCODE_INDEX;
1145
 
            if (0 == keyIndex) {
1146
 
                keyIndex = ar->arDefTxKeyIndex;
1147
 
            } else if ((keyIndex - 1 < WMI_MIN_KEY_INDEX) ||
1148
 
                       (keyIndex - 1 > WMI_MAX_KEY_INDEX))
1149
 
            {
1150
 
                keyIndex = WMI_MIN_KEY_INDEX;
1151
 
            } else {
1152
 
                keyIndex--;
1153
 
            }
1154
 
            erq->flags = keyIndex + 1;
1155
 
            erq->flags &= ~IW_ENCODE_DISABLED;
1156
 
            wk = &ar->arWepKeyList[keyIndex];
1157
 
            if (erq->length > wk->arKeyLen) {
1158
 
                erq->length = wk->arKeyLen;
1159
 
            }
1160
 
            if (wk->arKeyLen) {
1161
 
                A_MEMCPY(key, wk->arKey, erq->length);
1162
 
            }
1163
 
        } else {
1164
 
            erq->flags &= ~IW_ENCODE_DISABLED;
1165
 
            if (ar->user_saved_keys.keyOk) {
1166
 
                erq->length = ar->user_saved_keys.ucast_ik.ik_keylen;
1167
 
                if (erq->length) {
1168
 
                    A_MEMCPY(key, ar->user_saved_keys.ucast_ik.ik_keydata, erq->length);
1169
 
                }
1170
 
            } else {
1171
 
                erq->length = 1;    // not really printing any key but let iwconfig know enc is on
1172
 
            }
1173
 
        }
1174
 
 
1175
 
        if (ar->arDot11AuthMode & OPEN_AUTH) {
1176
 
            erq->flags |= IW_ENCODE_OPEN;
1177
 
        }
1178
 
        if (ar->arDot11AuthMode & SHARED_AUTH) {
1179
 
            erq->flags |= IW_ENCODE_RESTRICTED;
1180
 
        }
1181
 
    }
1182
 
 
1183
 
    return 0;
1184
 
}
1185
 
 
1186
 
#if WIRELESS_EXT >= 18
1187
 
/*
1188
 
 * SIOCSIWGENIE
1189
 
 */
1190
 
static int
1191
 
ar6000_ioctl_siwgenie(struct net_device *dev,
1192
 
              struct iw_request_info *info,
1193
 
              struct iw_point *erq, char *extra)
1194
 
{
1195
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1196
 
 
1197
 
#ifdef WAPI_ENABLE
1198
 
    A_UINT8    *ie = erq->pointer;
1199
 
    A_UINT8    ie_type = ie[0];
1200
 
    A_UINT16   ie_length = erq->length;
1201
 
    A_UINT8    wapi_ie[128];
1202
 
#endif
1203
 
 
1204
 
    if (ar->arWmiReady == FALSE) {
1205
 
        return -EIO;
1206
 
    }
1207
 
#ifdef WAPI_ENABLE
1208
 
    if (ie_type == IEEE80211_ELEMID_WAPI) {
1209
 
        if (ie_length > 0) {
1210
 
            if (copy_from_user(wapi_ie, ie, ie_length)) {
1211
 
                return -EIO;
1212
 
            }
1213
 
        }
1214
 
        wmi_set_appie_cmd(ar->arWmi, WMI_FRAME_ASSOC_REQ, ie_length, wapi_ie);
1215
 
    } else if (ie_length == 0) {
1216
 
        wmi_set_appie_cmd(ar->arWmi, WMI_FRAME_ASSOC_REQ, ie_length, wapi_ie);
1217
 
    }
1218
 
#endif
1219
 
    return 0;
1220
 
}
1221
 
 
1222
 
 
1223
 
/*
1224
 
 * SIOCGIWGENIE
1225
 
 */
1226
 
static int
1227
 
ar6000_ioctl_giwgenie(struct net_device *dev,
1228
 
              struct iw_request_info *info,
1229
 
              struct iw_point *erq, char *extra)
1230
 
{
1231
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1232
 
 
1233
 
    if (ar->arWmiReady == FALSE) {
1234
 
        return -EIO;
1235
 
    }
1236
 
    erq->length = 0;
1237
 
    erq->flags = 0;
1238
 
 
1239
 
    return 0;
1240
 
}
1241
 
 
1242
 
/*
1243
 
 * SIOCSIWAUTH
1244
 
 */
1245
 
static int
1246
 
ar6000_ioctl_siwauth(struct net_device *dev,
1247
 
              struct iw_request_info *info,
1248
 
              struct iw_param *data, char *extra)
1249
 
{
1250
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1251
 
 
1252
 
    A_BOOL profChanged;
1253
 
    A_UINT16 param;
1254
 
    A_INT32 ret;
1255
 
    A_INT32 value;
1256
 
 
1257
 
    if (ar->arWmiReady == FALSE) {
1258
 
        return -EIO;
1259
 
    }
1260
 
 
1261
 
    if (ar->arWlanState == WLAN_DISABLED) {
1262
 
        return -EIO;
1263
 
    }
1264
 
 
1265
 
    param = data->flags & IW_AUTH_INDEX;
1266
 
    value = data->value;
1267
 
    profChanged = TRUE;
1268
 
    ret = 0;
1269
 
 
1270
 
    switch (param) {
1271
 
        case IW_AUTH_WPA_VERSION:
1272
 
            if (value & IW_AUTH_WPA_VERSION_DISABLED) {
1273
 
                ar->arAuthMode = NONE_AUTH;
1274
 
            } else if (value & IW_AUTH_WPA_VERSION_WPA) {
1275
 
                    ar->arAuthMode = WPA_AUTH;
1276
 
            } else if (value & IW_AUTH_WPA_VERSION_WPA2) {
1277
 
                    ar->arAuthMode = WPA2_AUTH;
1278
 
            } else {
1279
 
                ret = -1;
1280
 
                profChanged    = FALSE;
1281
 
            }
1282
 
            break;
1283
 
        case IW_AUTH_CIPHER_PAIRWISE:
1284
 
            if (value & IW_AUTH_CIPHER_NONE) {
1285
 
                ar->arPairwiseCrypto = NONE_CRYPT;
1286
 
                ar->arPairwiseCryptoLen = 0;
1287
 
            } else if (value & IW_AUTH_CIPHER_WEP40) {
1288
 
                ar->arPairwiseCrypto = WEP_CRYPT;
1289
 
                ar->arPairwiseCryptoLen = 5;
1290
 
            } else if (value & IW_AUTH_CIPHER_TKIP) {
1291
 
                ar->arPairwiseCrypto = TKIP_CRYPT;
1292
 
                ar->arPairwiseCryptoLen = 0;
1293
 
            } else if (value & IW_AUTH_CIPHER_CCMP) {
1294
 
                ar->arPairwiseCrypto = AES_CRYPT;
1295
 
                ar->arPairwiseCryptoLen = 0;
1296
 
            } else if (value & IW_AUTH_CIPHER_WEP104) {
1297
 
                ar->arPairwiseCrypto = WEP_CRYPT;
1298
 
                ar->arPairwiseCryptoLen = 13;
1299
 
            } else {
1300
 
                ret = -1;
1301
 
                profChanged    = FALSE;
1302
 
            }
1303
 
            break;
1304
 
        case IW_AUTH_CIPHER_GROUP:
1305
 
            if (value & IW_AUTH_CIPHER_NONE) {
1306
 
                ar->arGroupCrypto = NONE_CRYPT;
1307
 
                ar->arGroupCryptoLen = 0;
1308
 
            } else if (value & IW_AUTH_CIPHER_WEP40) {
1309
 
                ar->arGroupCrypto = WEP_CRYPT;
1310
 
                ar->arGroupCryptoLen = 5;
1311
 
            } else if (value & IW_AUTH_CIPHER_TKIP) {
1312
 
                ar->arGroupCrypto = TKIP_CRYPT;
1313
 
                ar->arGroupCryptoLen = 0;
1314
 
            } else if (value & IW_AUTH_CIPHER_CCMP) {
1315
 
                ar->arGroupCrypto = AES_CRYPT;
1316
 
                ar->arGroupCryptoLen = 0;
1317
 
            } else if (value & IW_AUTH_CIPHER_WEP104) {
1318
 
                ar->arGroupCrypto = WEP_CRYPT;
1319
 
                ar->arGroupCryptoLen = 13;
1320
 
            } else {
1321
 
                ret = -1;
1322
 
                profChanged    = FALSE;
1323
 
            }
1324
 
            break;
1325
 
        case IW_AUTH_KEY_MGMT:
1326
 
            if (value & IW_AUTH_KEY_MGMT_PSK) {
1327
 
                if (WPA_AUTH == ar->arAuthMode) {
1328
 
                    ar->arAuthMode = WPA_PSK_AUTH;
1329
 
                } else if (WPA2_AUTH == ar->arAuthMode) {
1330
 
                    ar->arAuthMode = WPA2_PSK_AUTH;
1331
 
                } else {
1332
 
                    ret = -1;
1333
 
                }
1334
 
            } else if (!(value & IW_AUTH_KEY_MGMT_802_1X)) {
1335
 
                ar->arAuthMode = NONE_AUTH;
1336
 
            }
1337
 
            break;
1338
 
        case IW_AUTH_TKIP_COUNTERMEASURES:
1339
 
            wmi_set_tkip_countermeasures_cmd(ar->arWmi, value);
1340
 
            profChanged    = FALSE;
1341
 
            break;
1342
 
        case IW_AUTH_DROP_UNENCRYPTED:
1343
 
            profChanged    = FALSE;
1344
 
            break;
1345
 
        case IW_AUTH_80211_AUTH_ALG:
1346
 
            ar->arDot11AuthMode = 0;
1347
 
            if (value & IW_AUTH_ALG_OPEN_SYSTEM) {
1348
 
                ar->arDot11AuthMode  |= OPEN_AUTH;
1349
 
            }
1350
 
            if (value & IW_AUTH_ALG_SHARED_KEY) {
1351
 
                ar->arDot11AuthMode  |= SHARED_AUTH;
1352
 
            }
1353
 
            if (value & IW_AUTH_ALG_LEAP) {
1354
 
                ar->arDot11AuthMode   = LEAP_AUTH;
1355
 
            }
1356
 
            if(ar->arDot11AuthMode == 0) {
1357
 
                ret = -1;
1358
 
                profChanged    = FALSE;
1359
 
            }
1360
 
            break;
1361
 
        case IW_AUTH_WPA_ENABLED:
1362
 
            if (!value) {
1363
 
                ar->arAuthMode = NONE_AUTH;
1364
 
                /* when the supplicant is stopped, it calls this
1365
 
                 * handler with value=0. The followings need to be
1366
 
                 * reset if the STA were to connect again
1367
 
                 * without security
1368
 
                 */
1369
 
                ar->arDot11AuthMode = OPEN_AUTH;
1370
 
                ar->arPairwiseCrypto = NONE_CRYPT;
1371
 
                ar->arPairwiseCryptoLen = 0;
1372
 
                ar->arGroupCrypto = NONE_CRYPT;
1373
 
                ar->arGroupCryptoLen = 0;
1374
 
            }
1375
 
            break;
1376
 
        case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1377
 
            profChanged    = FALSE;
1378
 
            break;
1379
 
        case IW_AUTH_ROAMING_CONTROL:
1380
 
            profChanged    = FALSE;
1381
 
            break;
1382
 
        case IW_AUTH_PRIVACY_INVOKED:
1383
 
            if (!value) {
1384
 
                ar->arPairwiseCrypto = NONE_CRYPT;
1385
 
                ar->arPairwiseCryptoLen = 0;
1386
 
                ar->arGroupCrypto = NONE_CRYPT;
1387
 
                ar->arGroupCryptoLen = 0;
1388
 
            }
1389
 
            break;
1390
 
#ifdef WAPI_ENABLE
1391
 
        case IW_AUTH_WAPI_ENABLED:
1392
 
            ar->arWapiEnable = value;
1393
 
            break;
1394
 
#endif
1395
 
        default:
1396
 
           ret = -1;
1397
 
           profChanged    = FALSE;
1398
 
           break;
1399
 
    }
1400
 
 
1401
 
    if (profChanged == TRUE) {
1402
 
        /*
1403
 
         * profile has changed.  Erase ssid to signal change
1404
 
         */
1405
 
        A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
1406
 
        ar->arSsidLen = 0;
1407
 
    }
1408
 
 
1409
 
    return ret;
1410
 
}
1411
 
 
1412
 
 
1413
 
/*
1414
 
 * SIOCGIWAUTH
1415
 
 */
1416
 
static int
1417
 
ar6000_ioctl_giwauth(struct net_device *dev,
1418
 
              struct iw_request_info *info,
1419
 
              struct iw_param *data, char *extra)
1420
 
{
1421
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1422
 
    A_UINT16 param;
1423
 
    A_INT32 ret;
1424
 
 
1425
 
    if (ar->arWmiReady == FALSE) {
1426
 
        return -EIO;
1427
 
    }
1428
 
 
1429
 
    if (ar->arWlanState == WLAN_DISABLED) {
1430
 
        return -EIO;
1431
 
    }
1432
 
 
1433
 
    param = data->flags & IW_AUTH_INDEX;
1434
 
    ret = 0;
1435
 
    data->value = 0;
1436
 
 
1437
 
 
1438
 
    switch (param) {
1439
 
        case IW_AUTH_WPA_VERSION:
1440
 
            if (ar->arAuthMode == NONE_AUTH) {
1441
 
                data->value |= IW_AUTH_WPA_VERSION_DISABLED;
1442
 
            } else if (ar->arAuthMode == WPA_AUTH) {
1443
 
                data->value |= IW_AUTH_WPA_VERSION_WPA;
1444
 
            } else if (ar->arAuthMode == WPA2_AUTH) {
1445
 
                data->value |= IW_AUTH_WPA_VERSION_WPA2;
1446
 
            } else {
1447
 
                ret = -1;
1448
 
            }
1449
 
            break;
1450
 
        case IW_AUTH_CIPHER_PAIRWISE:
1451
 
            if (ar->arPairwiseCrypto == NONE_CRYPT) {
1452
 
                data->value |= IW_AUTH_CIPHER_NONE;
1453
 
            } else if (ar->arPairwiseCrypto == WEP_CRYPT) {
1454
 
                if (ar->arPairwiseCryptoLen == 13) {
1455
 
                    data->value |= IW_AUTH_CIPHER_WEP104;
1456
 
                } else {
1457
 
                    data->value |= IW_AUTH_CIPHER_WEP40;
1458
 
                }
1459
 
            } else if (ar->arPairwiseCrypto == TKIP_CRYPT) {
1460
 
                data->value |= IW_AUTH_CIPHER_TKIP;
1461
 
            } else if (ar->arPairwiseCrypto == AES_CRYPT) {
1462
 
                data->value |= IW_AUTH_CIPHER_CCMP;
1463
 
            } else {
1464
 
                ret = -1;
1465
 
            }
1466
 
            break;
1467
 
        case IW_AUTH_CIPHER_GROUP:
1468
 
            if (ar->arGroupCrypto == NONE_CRYPT) {
1469
 
                    data->value |= IW_AUTH_CIPHER_NONE;
1470
 
            } else if (ar->arGroupCrypto == WEP_CRYPT) {
1471
 
                if (ar->arGroupCryptoLen == 13) {
1472
 
                    data->value |= IW_AUTH_CIPHER_WEP104;
1473
 
                } else {
1474
 
                    data->value |= IW_AUTH_CIPHER_WEP40;
1475
 
                }
1476
 
            } else if (ar->arGroupCrypto == TKIP_CRYPT) {
1477
 
                data->value |= IW_AUTH_CIPHER_TKIP;
1478
 
            } else if (ar->arGroupCrypto == AES_CRYPT) {
1479
 
                data->value |= IW_AUTH_CIPHER_CCMP;
1480
 
            } else {
1481
 
                ret = -1;
1482
 
            }
1483
 
            break;
1484
 
        case IW_AUTH_KEY_MGMT:
1485
 
            if ((ar->arAuthMode == WPA_PSK_AUTH) ||
1486
 
                (ar->arAuthMode == WPA2_PSK_AUTH)) {
1487
 
                data->value |= IW_AUTH_KEY_MGMT_PSK;
1488
 
            } else if ((ar->arAuthMode == WPA_AUTH) ||
1489
 
                       (ar->arAuthMode == WPA2_AUTH)) {
1490
 
                data->value |= IW_AUTH_KEY_MGMT_802_1X;
1491
 
            }
1492
 
            break;
1493
 
        case IW_AUTH_TKIP_COUNTERMEASURES:
1494
 
            // TODO. Save countermeassure enable/disable
1495
 
            data->value = 0;
1496
 
            break;
1497
 
        case IW_AUTH_DROP_UNENCRYPTED:
1498
 
            break;
1499
 
        case IW_AUTH_80211_AUTH_ALG:
1500
 
            if (ar->arDot11AuthMode == OPEN_AUTH) {
1501
 
                data->value |= IW_AUTH_ALG_OPEN_SYSTEM;
1502
 
            } else if (ar->arDot11AuthMode == SHARED_AUTH) {
1503
 
                data->value |= IW_AUTH_ALG_SHARED_KEY;
1504
 
            } else if (ar->arDot11AuthMode == LEAP_AUTH) {
1505
 
                data->value |= IW_AUTH_ALG_LEAP;
1506
 
            } else {
1507
 
                ret = -1;
1508
 
            }
1509
 
            break;
1510
 
        case IW_AUTH_WPA_ENABLED:
1511
 
            if (ar->arAuthMode == NONE_AUTH) {
1512
 
                data->value = 0;
1513
 
            } else {
1514
 
                data->value = 1;
1515
 
            }
1516
 
            break;
1517
 
        case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1518
 
            break;
1519
 
        case IW_AUTH_ROAMING_CONTROL:
1520
 
            break;
1521
 
        case IW_AUTH_PRIVACY_INVOKED:
1522
 
            if (ar->arPairwiseCrypto == NONE_CRYPT) {
1523
 
                data->value = 0;
1524
 
            } else {
1525
 
                data->value = 1;
1526
 
            }
1527
 
            break;
1528
 
#ifdef WAPI_ENABLE
1529
 
        case IW_AUTH_WAPI_ENABLED:
1530
 
            data->value = ar->arWapiEnable;
1531
 
            break;
1532
 
#endif
1533
 
        default:
1534
 
           ret = -1;
1535
 
           break;
1536
 
    }
1537
 
 
1538
 
    return 0;
1539
 
}
1540
 
 
1541
 
/*
1542
 
 * SIOCSIWPMKSA
1543
 
 */
1544
 
static int
1545
 
ar6000_ioctl_siwpmksa(struct net_device *dev,
1546
 
              struct iw_request_info *info,
1547
 
              struct iw_point *data, char *extra)
1548
 
{
1549
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1550
 
    A_INT32 ret;
1551
 
    A_STATUS status;
1552
 
    struct iw_pmksa *pmksa;
1553
 
 
1554
 
    pmksa = (struct iw_pmksa *)extra;
1555
 
 
1556
 
    if (ar->arWmiReady == FALSE) {
1557
 
        return -EIO;
1558
 
    }
1559
 
 
1560
 
    ret = 0;
1561
 
    status = A_OK;
1562
 
 
1563
 
    switch (pmksa->cmd) {
1564
 
        case IW_PMKSA_ADD:
1565
 
            status = wmi_setPmkid_cmd(ar->arWmi, (A_UINT8*)pmksa->bssid.sa_data, pmksa->pmkid, TRUE);
1566
 
            break;
1567
 
        case IW_PMKSA_REMOVE:
1568
 
            status = wmi_setPmkid_cmd(ar->arWmi, (A_UINT8*)pmksa->bssid.sa_data, pmksa->pmkid, FALSE);
1569
 
            break;
1570
 
        case IW_PMKSA_FLUSH:
1571
 
            if (ar->arConnected == TRUE) {
1572
 
                status = wmi_setPmkid_cmd(ar->arWmi, ar->arBssid, NULL, 0);
1573
 
            }
1574
 
            break;
1575
 
        default:
1576
 
            ret=-1;
1577
 
            break;
1578
 
    }
1579
 
    if (status != A_OK) {
1580
 
        ret = -1;
1581
 
    }
1582
 
 
1583
 
    return ret;
1584
 
}
1585
 
 
1586
 
#ifdef WAPI_ENABLE
1587
 
 
1588
 
#define PN_INIT 0x5c365c36
1589
 
 
1590
 
static int ar6000_set_wapi_key(struct net_device *dev,
1591
 
              struct iw_request_info *info,
1592
 
              struct iw_point *erq, char *extra)
1593
 
{
1594
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1595
 
    struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1596
 
    KEY_USAGE   keyUsage = 0;
1597
 
    A_INT32     keyLen;
1598
 
    A_UINT8     *keyData;
1599
 
    A_INT32     index;
1600
 
    A_UINT32    *PN;
1601
 
    A_INT32     i;
1602
 
    A_STATUS    status;
1603
 
    A_UINT8     wapiKeyRsc[16];
1604
 
    CRYPTO_TYPE keyType = WAPI_CRYPT;
1605
 
    const A_UINT8 broadcastMac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1606
 
 
1607
 
    index = erq->flags & IW_ENCODE_INDEX;
1608
 
    if (index && (((index - 1) < WMI_MIN_KEY_INDEX) ||
1609
 
                ((index - 1) > WMI_MAX_KEY_INDEX))) {
1610
 
        return -EIO;
1611
 
    }
1612
 
 
1613
 
    index--;
1614
 
    if (index < 0 || index > 4) {
1615
 
        return -EIO;
1616
 
    }
1617
 
    keyData = (A_UINT8 *)(ext + 1);
1618
 
    keyLen = erq->length - sizeof(struct iw_encode_ext);
1619
 
    A_MEMCPY(wapiKeyRsc, ext->tx_seq, sizeof(wapiKeyRsc));
1620
 
 
1621
 
    if (A_MEMCMP(ext->addr.sa_data, broadcastMac, sizeof(broadcastMac)) == 0) {
1622
 
        keyUsage |= GROUP_USAGE;
1623
 
        PN = (A_UINT32 *)wapiKeyRsc;
1624
 
        for (i = 0; i < 4; i++) {
1625
 
            PN[i] = PN_INIT;
1626
 
        }
1627
 
    } else {
1628
 
        keyUsage |= PAIRWISE_USAGE;
1629
 
    }
1630
 
    status = wmi_addKey_cmd(ar->arWmi,
1631
 
                            index,
1632
 
                            keyType,
1633
 
                            keyUsage,
1634
 
                            keyLen,
1635
 
                            wapiKeyRsc,
1636
 
                            keyData,
1637
 
                            KEY_OP_INIT_WAPIPN,
1638
 
                            NULL,
1639
 
                            SYNC_BEFORE_WMIFLAG);
1640
 
    if (A_OK != status) {
1641
 
        return -EIO;
1642
 
    }
1643
 
    return 0;
1644
 
}
1645
 
 
1646
 
#endif
1647
 
 
1648
 
/*
1649
 
 * SIOCSIWENCODEEXT
1650
 
 */
1651
 
static int
1652
 
ar6000_ioctl_siwencodeext(struct net_device *dev,
1653
 
              struct iw_request_info *info,
1654
 
              struct iw_point *erq, char *extra)
1655
 
{
1656
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1657
 
    A_INT32 index;
1658
 
    struct iw_encode_ext *ext;
1659
 
    KEY_USAGE keyUsage;
1660
 
    A_INT32 keyLen;
1661
 
    A_UINT8 *keyData;
1662
 
    A_UINT8 keyRsc[8];
1663
 
    A_STATUS status;
1664
 
    CRYPTO_TYPE keyType;
1665
 
#ifdef USER_KEYS
1666
 
    struct ieee80211req_key ik;
1667
 
#endif /* USER_KEYS */
1668
 
 
1669
 
    if (ar->arWlanState == WLAN_DISABLED) {
1670
 
        return -EIO;
1671
 
    }
1672
 
 
1673
 
#ifdef USER_KEYS
1674
 
    ar->user_saved_keys.keyOk = FALSE;
1675
 
#endif /* USER_KEYS */
1676
 
 
1677
 
    index = erq->flags & IW_ENCODE_INDEX;
1678
 
 
1679
 
    if (index && (((index - 1) < WMI_MIN_KEY_INDEX) ||
1680
 
                  ((index - 1) > WMI_MAX_KEY_INDEX)))
1681
 
    {
1682
 
        return -EIO;
1683
 
    }
1684
 
 
1685
 
    ext = (struct iw_encode_ext *)extra;
1686
 
    if (erq->flags & IW_ENCODE_DISABLED) {
1687
 
        /*
1688
 
         * Encryption disabled
1689
 
         */
1690
 
        if (index) {
1691
 
            /*
1692
 
             * If key index was specified then clear the specified key
1693
 
             */
1694
 
            index--;
1695
 
            A_MEMZERO(ar->arWepKeyList[index].arKey,
1696
 
                      sizeof(ar->arWepKeyList[index].arKey));
1697
 
            ar->arWepKeyList[index].arKeyLen = 0;
1698
 
        }
1699
 
    } else {
1700
 
        /*
1701
 
         * Enabling WEP encryption
1702
 
         */
1703
 
        if (index) {
1704
 
            index--;                /* keyindex is off base 1 in iwconfig */
1705
 
        }
1706
 
 
1707
 
        keyUsage = 0;
1708
 
        keyLen = erq->length - sizeof(struct iw_encode_ext);
1709
 
 
1710
 
        if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
1711
 
            keyUsage = TX_USAGE;
1712
 
            ar->arDefTxKeyIndex = index;
1713
 
            // Just setting the key index
1714
 
            if (keyLen == 0) {
1715
 
                return 0;
1716
 
            }
1717
 
        }
1718
 
 
1719
 
        if (keyLen <= 0) {
1720
 
            return -EIO;
1721
 
        }
1722
 
 
1723
 
        /* key follows iw_encode_ext */
1724
 
        keyData = (A_UINT8 *)(ext + 1);
1725
 
 
1726
 
        switch (ext->alg) {
1727
 
            case IW_ENCODE_ALG_WEP:
1728
 
                keyType = WEP_CRYPT;
1729
 
#ifdef USER_KEYS
1730
 
                ik.ik_type = IEEE80211_CIPHER_WEP;
1731
 
#endif /* USER_KEYS */
1732
 
                if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(keyLen)) {
1733
 
                    return -EIO;
1734
 
                }
1735
 
 
1736
 
                /* Check whether it is static wep. */
1737
 
                if (!ar->arConnected) {
1738
 
                    A_MEMZERO(ar->arWepKeyList[index].arKey,
1739
 
                          sizeof(ar->arWepKeyList[index].arKey));
1740
 
                    A_MEMCPY(ar->arWepKeyList[index].arKey, keyData, keyLen);
1741
 
                    ar->arWepKeyList[index].arKeyLen = keyLen;
1742
 
 
1743
 
                    return 0;
1744
 
                }
1745
 
                break;
1746
 
            case IW_ENCODE_ALG_TKIP:
1747
 
                keyType = TKIP_CRYPT;
1748
 
#ifdef USER_KEYS
1749
 
                ik.ik_type = IEEE80211_CIPHER_TKIP;
1750
 
#endif /* USER_KEYS */
1751
 
                break;
1752
 
            case IW_ENCODE_ALG_CCMP:
1753
 
                keyType = AES_CRYPT;
1754
 
#ifdef USER_KEYS
1755
 
                ik.ik_type = IEEE80211_CIPHER_AES_CCM;
1756
 
#endif /* USER_KEYS */
1757
 
                break;
1758
 
#ifdef WAPI_ENABLE
1759
 
            case IW_ENCODE_ALG_SM4:
1760
 
                if (ar->arWapiEnable) {
1761
 
                    return ar6000_set_wapi_key(dev, info, erq, extra);
1762
 
                } else {
1763
 
                    return -EIO;
1764
 
                }
1765
 
#endif
1766
 
            case IW_ENCODE_ALG_PMK:
1767
 
                ar->arConnectCtrlFlags |= CONNECT_DO_WPA_OFFLOAD;
1768
 
                return wmi_set_pmk_cmd(ar->arWmi, keyData);
1769
 
            default:
1770
 
                return -EIO;
1771
 
        }
1772
 
 
1773
 
 
1774
 
        if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
1775
 
            keyUsage |= GROUP_USAGE;
1776
 
        } else {
1777
 
            keyUsage |= PAIRWISE_USAGE;
1778
 
        }
1779
 
 
1780
 
        if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
1781
 
            A_MEMCPY(keyRsc, ext->rx_seq, sizeof(keyRsc));
1782
 
        } else {
1783
 
            A_MEMZERO(keyRsc, sizeof(keyRsc));
1784
 
        }
1785
 
 
1786
 
        if (((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)) &&
1787
 
            (GROUP_USAGE & keyUsage))
1788
 
        {
1789
 
            A_UNTIMEOUT(&ar->disconnect_timer);
1790
 
        }
1791
 
 
1792
 
         status = wmi_addKey_cmd(ar->arWmi, index, keyType, keyUsage,
1793
 
                            keyLen, keyRsc,
1794
 
                            keyData, KEY_OP_INIT_VAL,
1795
 
                            (A_UINT8*)ext->addr.sa_data,
1796
 
                            SYNC_BOTH_WMIFLAG);
1797
 
         if (status != A_OK) {
1798
 
            return -EIO;
1799
 
         }
1800
 
 
1801
 
#ifdef USER_KEYS
1802
 
        ik.ik_keyix = index;
1803
 
        ik.ik_keylen = keyLen;
1804
 
        memcpy(ik.ik_keydata, keyData, keyLen);
1805
 
        memcpy(&ik.ik_keyrsc, keyRsc, sizeof(keyRsc));
1806
 
        memcpy(ik.ik_macaddr, ext->addr.sa_data, ETH_ALEN);
1807
 
        if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
1808
 
            memcpy(&ar->user_saved_keys.bcast_ik, &ik,
1809
 
                       sizeof(struct ieee80211req_key));
1810
 
        } else {
1811
 
            memcpy(&ar->user_saved_keys.ucast_ik, &ik,
1812
 
                      sizeof(struct ieee80211req_key));
1813
 
        }
1814
 
        ar->user_saved_keys.keyOk = TRUE;
1815
 
#endif /* USER_KEYS */
1816
 
    }
1817
 
 
1818
 
 
1819
 
    return 0;
1820
 
}
1821
 
 
1822
 
/*
1823
 
 * SIOCGIWENCODEEXT
1824
 
 */
1825
 
static int
1826
 
ar6000_ioctl_giwencodeext(struct net_device *dev,
1827
 
              struct iw_request_info *info,
1828
 
              struct iw_point *erq, char *extra)
1829
 
{
1830
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1831
 
 
1832
 
    if (ar->arWlanState == WLAN_DISABLED) {
1833
 
        return -EIO;
1834
 
    }
1835
 
 
1836
 
    if (ar->arPairwiseCrypto == NONE_CRYPT) {
1837
 
        erq->length = 0;
1838
 
        erq->flags = IW_ENCODE_DISABLED;
1839
 
    } else {
1840
 
        erq->length = 0;
1841
 
    }
1842
 
 
1843
 
    return 0;
1844
 
}
1845
 
#endif // WIRELESS_EXT >= 18
1846
 
 
1847
 
#if WIRELESS_EXT > 20
1848
 
static int ar6000_ioctl_siwpower(struct net_device *dev,
1849
 
                 struct iw_request_info *info,
1850
 
                 union iwreq_data *wrqu, char *extra)
1851
 
{
1852
 
#ifndef ATH6K_CONFIG_OTA_MODE
1853
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1854
 
    WMI_POWER_MODE power_mode;
1855
 
 
1856
 
    if (ar->arWmiReady == FALSE) {
1857
 
        return -EIO;
1858
 
    }
1859
 
 
1860
 
    if (ar->arWlanState == WLAN_DISABLED) {
1861
 
        return -EIO;
1862
 
    }
1863
 
 
1864
 
    if (wrqu->power.disabled)
1865
 
        power_mode = MAX_PERF_POWER;
1866
 
    else
1867
 
        power_mode = REC_POWER;
1868
 
 
1869
 
    if (wmi_powermode_cmd(ar->arWmi, power_mode) < 0)
1870
 
        return -EIO;
1871
 
#endif
1872
 
    return 0;
1873
 
}
1874
 
 
1875
 
static int ar6000_ioctl_giwpower(struct net_device *dev,
1876
 
                 struct iw_request_info *info,
1877
 
                 union iwreq_data *wrqu, char *extra)
1878
 
{
1879
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1880
 
    WMI_POWER_MODE power_mode;
1881
 
 
1882
 
    if (ar->arWmiReady == FALSE) {
1883
 
        return -EIO;
1884
 
    }
1885
 
 
1886
 
    if (ar->arWlanState == WLAN_DISABLED) {
1887
 
        return -EIO;
1888
 
    }
1889
 
 
1890
 
    power_mode = wmi_get_power_mode_cmd(ar->arWmi);
1891
 
 
1892
 
    if (power_mode == MAX_PERF_POWER)
1893
 
        wrqu->power.disabled = 1;
1894
 
    else
1895
 
        wrqu->power.disabled = 0;
1896
 
 
1897
 
    return 0;
1898
 
}
1899
 
#endif // WIRELESS_EXT > 20
1900
 
 
1901
 
/*
1902
 
 * SIOCGIWNAME
1903
 
 */
1904
 
int
1905
 
ar6000_ioctl_giwname(struct net_device *dev,
1906
 
           struct iw_request_info *info,
1907
 
           char *name, char *extra)
1908
 
{
1909
 
    A_UINT8 capability;
1910
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1911
 
 
1912
 
    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
1913
 
        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
1914
 
        return -EOPNOTSUPP;
1915
 
    }
1916
 
 
1917
 
    if (ar->arWlanState == WLAN_DISABLED) {
1918
 
        return -EIO;
1919
 
    }
1920
 
 
1921
 
    capability = ar->arPhyCapability;
1922
 
    if(ar->arNetworkType == INFRA_NETWORK && ar->arConnected) {
1923
 
        bss_t *bss = wmi_find_node(ar->arWmi, ar->arBssid);
1924
 
        if (bss) {
1925
 
            capability = get_bss_phy_capability(bss);
1926
 
            wmi_node_return(ar->arWmi, bss);
1927
 
        }
1928
 
    }
1929
 
    switch (capability) {
1930
 
    case (WMI_11A_CAPABILITY):
1931
 
        strncpy(name, "AR6000 802.11a", IFNAMSIZ);
1932
 
        break;
1933
 
    case (WMI_11G_CAPABILITY):
1934
 
        strncpy(name, "AR6000 802.11g", IFNAMSIZ);
1935
 
        break;
1936
 
    case (WMI_11AG_CAPABILITY):
1937
 
        strncpy(name, "AR6000 802.11ag", IFNAMSIZ);
1938
 
        break;
1939
 
    case (WMI_11NA_CAPABILITY):
1940
 
        strncpy(name, "AR6000 802.11na", IFNAMSIZ);
1941
 
        break;
1942
 
    case (WMI_11NG_CAPABILITY):
1943
 
        strncpy(name, "AR6000 802.11ng", IFNAMSIZ);
1944
 
        break;
1945
 
    case (WMI_11NAG_CAPABILITY):
1946
 
        strncpy(name, "AR6000 802.11nag", IFNAMSIZ);
1947
 
        break;
1948
 
    default:
1949
 
        strncpy(name, "AR6000 802.11b", IFNAMSIZ);
1950
 
        break;
1951
 
    }
1952
 
 
1953
 
    return 0;
1954
 
}
1955
 
 
1956
 
/*
1957
 
 * SIOCSIWFREQ
1958
 
 */
1959
 
int
1960
 
ar6000_ioctl_siwfreq(struct net_device *dev,
1961
 
            struct iw_request_info *info,
1962
 
            struct iw_freq *freq, char *extra)
1963
 
{
1964
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1965
 
 
1966
 
    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
1967
 
        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
1968
 
        return -EOPNOTSUPP;
1969
 
    }
1970
 
 
1971
 
    if (ar->arWlanState == WLAN_DISABLED) {
1972
 
        return -EIO;
1973
 
    }
1974
 
 
1975
 
    /*
1976
 
     * We support limiting the channels via wmiconfig.
1977
 
     *
1978
 
     * We use this command to configure the channel hint for the connect cmd
1979
 
     * so it is possible the target will end up connecting to a different
1980
 
     * channel.
1981
 
     */
1982
 
    if (freq->e > 1) {
1983
 
        return -EINVAL;
1984
 
    } else if (freq->e == 1) {
1985
 
        ar->arChannelHint = freq->m / 100000;
1986
 
    } else {
1987
 
        if(freq->m) {
1988
 
            ar->arChannelHint = wlan_ieee2freq(freq->m);
1989
 
        } else {
1990
 
            /* Auto Channel Selection */
1991
 
            ar->arChannelHint = 0;
1992
 
        }
1993
 
    }
1994
 
 
1995
 
    ar->ap_profile_flag = 1; /* There is a change in profile */
1996
 
 
1997
 
    A_PRINTF("channel hint set to %d\n", ar->arChannelHint);
1998
 
    return 0;
1999
 
}
2000
 
 
2001
 
/*
2002
 
 * SIOCGIWFREQ
2003
 
 */
2004
 
int
2005
 
ar6000_ioctl_giwfreq(struct net_device *dev,
2006
 
                struct iw_request_info *info,
2007
 
                struct iw_freq *freq, char *extra)
2008
 
{
2009
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
2010
 
 
2011
 
    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
2012
 
        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
2013
 
        return -EOPNOTSUPP;
2014
 
    }
2015
 
 
2016
 
    if (ar->arWlanState == WLAN_DISABLED) {
2017
 
        return -EIO;
2018
 
    }
2019
 
 
2020
 
    if (ar->arNetworkType == AP_NETWORK) {
2021
 
        if(ar->arChannelHint) {
2022
 
            freq->m = ar->arChannelHint * 100000;
2023
 
        } else if(ar->arACS) {
2024
 
            freq->m = ar->arACS * 100000;
2025
 
        } else {
2026
 
            return -EINVAL;
2027
 
        }
2028
 
    } else {
2029
 
        if (ar->arConnected != TRUE) {
2030
 
            return -EINVAL;
2031
 
        } else {
2032
 
            freq->m = ar->arBssChannel * 100000;
2033
 
        }
2034
 
    }
2035
 
 
2036
 
    freq->e = 1;
2037
 
 
2038
 
    return 0;
2039
 
}
2040
 
 
2041
 
/*
2042
 
 * SIOCSIWMODE
2043
 
 */
2044
 
int
2045
 
ar6000_ioctl_siwmode(struct net_device *dev,
2046
 
            struct iw_request_info *info,
2047
 
            __u32 *mode, char *extra)
2048
 
{
2049
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
2050
 
 
2051
 
    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
2052
 
        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
2053
 
        return -EOPNOTSUPP;
2054
 
    }
2055
 
 
2056
 
    if (ar->arWlanState == WLAN_DISABLED) {
2057
 
        return -EIO;
2058
 
    }
2059
 
 
2060
 
    /*
2061
 
     * clear SSID during mode switch in connected state
2062
 
     */
2063
 
    if(!(ar->arNetworkType == (((*mode) == IW_MODE_INFRA) ? INFRA_NETWORK : ADHOC_NETWORK)) && (ar->arConnected == TRUE) ){
2064
 
        A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
2065
 
        ar->arSsidLen = 0;
2066
 
    }
2067
 
 
2068
 
    switch (*mode) {
2069
 
    case IW_MODE_INFRA:
2070
 
        ar->arNextMode = INFRA_NETWORK;
2071
 
        break;
2072
 
    case IW_MODE_ADHOC:
2073
 
        ar->arNextMode = ADHOC_NETWORK;
2074
 
        break;
2075
 
    case IW_MODE_MASTER:
2076
 
        ar->arNextMode = AP_NETWORK;
2077
 
        break;
2078
 
    default:
2079
 
        return -EINVAL;
2080
 
    }
2081
 
 
2082
 
    /* clear all shared parameters between AP and STA|IBSS modes when we
2083
 
     * switch between them. Switch between STA & IBSS modes does'nt clear
2084
 
     * the shared profile. This is as per the original design for switching
2085
 
     * between STA & IBSS.
2086
 
     */
2087
 
    if (ar->arNetworkType == AP_NETWORK || ar->arNextMode == AP_NETWORK) {
2088
 
        ar->arDot11AuthMode      = OPEN_AUTH;
2089
 
        ar->arAuthMode           = NONE_AUTH;
2090
 
        ar->arPairwiseCrypto     = NONE_CRYPT;
2091
 
        ar->arPairwiseCryptoLen  = 0;
2092
 
        ar->arGroupCrypto        = NONE_CRYPT;
2093
 
        ar->arGroupCryptoLen     = 0;
2094
 
        ar->arChannelHint        = 0;
2095
 
        ar->arBssChannel         = 0;
2096
 
        A_MEMZERO(ar->arBssid, sizeof(ar->arBssid));
2097
 
        A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
2098
 
        ar->arSsidLen = 0;
2099
 
    }
2100
 
 
2101
 
    /* SSID has to be cleared to trigger a profile change while switching
2102
 
     * between STA & IBSS modes having the same SSID
2103
 
     */
2104
 
    if (ar->arNetworkType != ar->arNextMode) {
2105
 
        A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
2106
 
        ar->arSsidLen = 0;
2107
 
    }
2108
 
 
2109
 
    return 0;
2110
 
}
2111
 
 
2112
 
/*
2113
 
 * SIOCGIWMODE
2114
 
 */
2115
 
int
2116
 
ar6000_ioctl_giwmode(struct net_device *dev,
2117
 
            struct iw_request_info *info,
2118
 
            __u32 *mode, char *extra)
2119
 
{
2120
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
2121
 
 
2122
 
    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
2123
 
        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
2124
 
        return -EOPNOTSUPP;
2125
 
    }
2126
 
 
2127
 
    if (ar->arWlanState == WLAN_DISABLED) {
2128
 
        return -EIO;
2129
 
    }
2130
 
 
2131
 
    switch (ar->arNetworkType) {
2132
 
    case INFRA_NETWORK:
2133
 
        *mode = IW_MODE_INFRA;
2134
 
        break;
2135
 
    case ADHOC_NETWORK:
2136
 
        *mode = IW_MODE_ADHOC;
2137
 
        break;
2138
 
    case AP_NETWORK:
2139
 
        *mode = IW_MODE_MASTER;
2140
 
        break;
2141
 
    default:
2142
 
        return -EIO;
2143
 
    }
2144
 
    return 0;
2145
 
}
2146
 
 
2147
 
/*
2148
 
 * SIOCSIWSENS
2149
 
 */
2150
 
int
2151
 
ar6000_ioctl_siwsens(struct net_device *dev,
2152
 
            struct iw_request_info *info,
2153
 
            struct iw_param *sens, char *extra)
2154
 
{
2155
 
    return 0;
2156
 
}
2157
 
 
2158
 
/*
2159
 
 * SIOCGIWSENS
2160
 
 */
2161
 
int
2162
 
ar6000_ioctl_giwsens(struct net_device *dev,
2163
 
            struct iw_request_info *info,
2164
 
            struct iw_param *sens, char *extra)
2165
 
{
2166
 
    sens->value = 0;
2167
 
    sens->fixed = 1;
2168
 
 
2169
 
    return 0;
2170
 
}
2171
 
 
2172
 
/*
2173
 
 * SIOCGIWRANGE
2174
 
 */
2175
 
int
2176
 
ar6000_ioctl_giwrange(struct net_device *dev,
2177
 
             struct iw_request_info *info,
2178
 
             struct iw_point *data, char *extra)
2179
 
{
2180
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
2181
 
    struct iw_range *range = (struct iw_range *) extra;
2182
 
    int i, ret = 0;
2183
 
 
2184
 
    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
2185
 
        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
2186
 
        return -EOPNOTSUPP;
2187
 
    }
2188
 
 
2189
 
    if (ar->bIsDestroyProgress) {
2190
 
        return -EBUSY;
2191
 
    }
2192
 
 
2193
 
    if (ar->arWmiReady == FALSE) {
2194
 
        return -EIO;
2195
 
    }
2196
 
 
2197
 
    if (down_interruptible(&ar->arSem)) {
2198
 
        return -ERESTARTSYS;
2199
 
    }
2200
 
 
2201
 
    if (ar->bIsDestroyProgress) {
2202
 
        up(&ar->arSem);
2203
 
        return -EBUSY;
2204
 
    }
2205
 
 
2206
 
    ar->arNumChannels = -1;
2207
 
    A_MEMZERO(ar->arChannelList, sizeof (ar->arChannelList));
2208
 
 
2209
 
    if (wmi_get_channelList_cmd(ar->arWmi) != A_OK) {
2210
 
        up(&ar->arSem);
2211
 
        return -EIO;
2212
 
    }
2213
 
 
2214
 
    wait_event_interruptible_timeout(arEvent, ar->arNumChannels != -1, wmitimeout * HZ);
2215
 
 
2216
 
    if (signal_pending(current)) {
2217
 
        up(&ar->arSem);
2218
 
        return -EINTR;
2219
 
    }
2220
 
 
2221
 
    data->length = sizeof(struct iw_range);
2222
 
    A_MEMZERO(range, sizeof(struct iw_range));
2223
 
 
2224
 
    range->txpower_capa = 0;
2225
 
 
2226
 
    range->min_pmp = 1 * 1024;
2227
 
    range->max_pmp = 65535 * 1024;
2228
 
    range->min_pmt = 1 * 1024;
2229
 
    range->max_pmt = 1000 * 1024;
2230
 
    range->pmp_flags = IW_POWER_PERIOD;
2231
 
    range->pmt_flags = IW_POWER_TIMEOUT;
2232
 
    range->pm_capa = 0;
2233
 
 
2234
 
    range->we_version_compiled = WIRELESS_EXT;
2235
 
    range->we_version_source = 13;
2236
 
 
2237
 
    range->retry_capa = IW_RETRY_LIMIT;
2238
 
    range->retry_flags = IW_RETRY_LIMIT;
2239
 
    range->min_retry = 0;
2240
 
    range->max_retry = 255;
2241
 
 
2242
 
    range->num_frequency = range->num_channels = ar->arNumChannels;
2243
 
    for (i = 0; i < ar->arNumChannels; i++) {
2244
 
        range->freq[i].i = wlan_freq2ieee(ar->arChannelList[i]);
2245
 
        range->freq[i].m = ar->arChannelList[i] * 100000;
2246
 
        range->freq[i].e = 1;
2247
 
         /*
2248
 
         * Linux supports max of 32 channels, bail out once you
2249
 
         * reach the max.
2250
 
         */
2251
 
        if (i == IW_MAX_FREQUENCIES) {
2252
 
            break;
2253
 
        }
2254
 
    }
2255
 
 
2256
 
    /* Max quality is max field value minus noise floor */
2257
 
    range->max_qual.qual  = 0xff - 161;
2258
 
 
2259
 
    /*
2260
 
     * In order to use dBm measurements, 'level' must be lower
2261
 
     * than any possible measurement (see iw_print_stats() in
2262
 
     * wireless tools).  It's unclear how this is meant to be
2263
 
     * done, but setting zero in these values forces dBm and
2264
 
     * the actual numbers are not used.
2265
 
     */
2266
 
    range->max_qual.level = 0;
2267
 
    range->max_qual.noise = 0;
2268
 
 
2269
 
    range->sensitivity = 3;
2270
 
 
2271
 
    range->max_encoding_tokens = 4;
2272
 
    /* XXX query driver to find out supported key sizes */
2273
 
    range->num_encoding_sizes = 3;
2274
 
    range->encoding_size[0] = 5;        /* 40-bit */
2275
 
    range->encoding_size[1] = 13;       /* 104-bit */
2276
 
    range->encoding_size[2] = 16;       /* 128-bit */
2277
 
 
2278
 
    range->num_bitrates = 0;
2279
 
 
2280
 
    /* estimated maximum TCP throughput values (bps) */
2281
 
    range->throughput = 22000000;
2282
 
 
2283
 
    range->min_rts = 0;
2284
 
    range->max_rts = 2347;
2285
 
    range->min_frag = 256;
2286
 
    range->max_frag = 2346;
2287
 
 
2288
 
    up(&ar->arSem);
2289
 
 
2290
 
    return ret;
2291
 
}
2292
 
 
2293
 
 
2294
 
/*
2295
 
 * SIOCSIWAP
2296
 
 * This ioctl is used to set the desired bssid for the connect command.
2297
 
 */
2298
 
int
2299
 
ar6000_ioctl_siwap(struct net_device *dev,
2300
 
              struct iw_request_info *info,
2301
 
              struct sockaddr *ap_addr, char *extra)
2302
 
{
2303
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
2304
 
 
2305
 
    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
2306
 
        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
2307
 
        return -EOPNOTSUPP;
2308
 
    }
2309
 
 
2310
 
    if (ar->arWlanState == WLAN_DISABLED) {
2311
 
        return -EIO;
2312
 
    }
2313
 
 
2314
 
    if (ap_addr->sa_family != ARPHRD_ETHER) {
2315
 
        return -EIO;
2316
 
    }
2317
 
 
2318
 
    if (A_MEMCMP(&ap_addr->sa_data, bcast_mac, AR6000_ETH_ADDR_LEN) == 0) {
2319
 
        A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
2320
 
    } else {
2321
 
        A_MEMCPY(ar->arReqBssid, &ap_addr->sa_data,  sizeof(ar->arReqBssid));
2322
 
    }
2323
 
 
2324
 
    return 0;
2325
 
}
2326
 
 
2327
 
/*
2328
 
 * SIOCGIWAP
2329
 
 */
2330
 
int
2331
 
ar6000_ioctl_giwap(struct net_device *dev,
2332
 
              struct iw_request_info *info,
2333
 
              struct sockaddr *ap_addr, char *extra)
2334
 
{
2335
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
2336
 
 
2337
 
    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
2338
 
        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
2339
 
        return -EOPNOTSUPP;
2340
 
    }
2341
 
 
2342
 
    if (ar->arWlanState == WLAN_DISABLED) {
2343
 
        return -EIO;
2344
 
    }
2345
 
 
2346
 
    if (ar->arNetworkType == AP_NETWORK) {
2347
 
        A_MEMCPY(&ap_addr->sa_data, dev->dev_addr, ATH_MAC_LEN);
2348
 
        ap_addr->sa_family = ARPHRD_ETHER;
2349
 
        return 0;
2350
 
    }
2351
 
 
2352
 
    if (ar->arConnected != TRUE) {
2353
 
        return -EINVAL;
2354
 
    }
2355
 
 
2356
 
    A_MEMCPY(&ap_addr->sa_data, ar->arBssid, sizeof(ar->arBssid));
2357
 
    ap_addr->sa_family = ARPHRD_ETHER;
2358
 
 
2359
 
    return 0;
2360
 
}
2361
 
 
2362
 
#if (WIRELESS_EXT >= 18)
2363
 
/*
2364
 
 * SIOCSIWMLME
2365
 
 */
2366
 
int
2367
 
ar6000_ioctl_siwmlme(struct net_device *dev,
2368
 
            struct iw_request_info *info,
2369
 
            struct iw_point *data, char *extra)
2370
 
{
2371
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
2372
 
 
2373
 
    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
2374
 
        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
2375
 
        return -EOPNOTSUPP;
2376
 
    }
2377
 
 
2378
 
    if (ar->bIsDestroyProgress) {
2379
 
        return -EBUSY;
2380
 
    }
2381
 
 
2382
 
    if (ar->arWlanState == WLAN_DISABLED) {
2383
 
        return -EIO;
2384
 
    }
2385
 
 
2386
 
    if (ar->arWmiReady == FALSE) {
2387
 
        return -EIO;
2388
 
    }
2389
 
 
2390
 
    if (down_interruptible(&ar->arSem)) {
2391
 
        return -ERESTARTSYS;
2392
 
    }
2393
 
 
2394
 
    if (data->pointer && data->length == sizeof(struct iw_mlme)) {
2395
 
 
2396
 
        A_UINT8 arNetworkType;
2397
 
        struct iw_mlme mlme;
2398
 
 
2399
 
        if (copy_from_user(&mlme, data->pointer, sizeof(struct iw_mlme)))
2400
 
            return -EIO;
2401
 
 
2402
 
        switch (mlme.cmd) {
2403
 
 
2404
 
            case IW_MLME_DEAUTH:
2405
 
                /* fall through */
2406
 
            case IW_MLME_DISASSOC:
2407
 
                if ((ar->arConnected != TRUE) ||
2408
 
                    (memcmp(ar->arBssid, mlme.addr.sa_data, 6) != 0)) {
2409
 
 
2410
 
                    up(&ar->arSem);
2411
 
                    return -EINVAL;
2412
 
                }
2413
 
                wmi_setPmkid_cmd(ar->arWmi, ar->arBssid, NULL, 0);
2414
 
                arNetworkType = ar->arNetworkType;
2415
 
                ar6000_init_profile_info(ar);
2416
 
                ar->arNetworkType = arNetworkType;
2417
 
                reconnect_flag = 0;
2418
 
                wmi_disconnect_cmd(ar->arWmi);
2419
 
                A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
2420
 
                ar->arSsidLen = 0;
2421
 
                if (ar->arSkipScan == FALSE) {
2422
 
                    A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
2423
 
                }
2424
 
                break;
2425
 
 
2426
 
            case IW_MLME_AUTH:
2427
 
                /* fall through */
2428
 
            case IW_MLME_ASSOC:
2429
 
                /* fall through */
2430
 
            default:
2431
 
                up(&ar->arSem);
2432
 
                return -EOPNOTSUPP;
2433
 
        }
2434
 
    }
2435
 
 
2436
 
    up(&ar->arSem);
2437
 
    return 0;
2438
 
}
2439
 
#endif /* WIRELESS_EXT >= 18 */
2440
 
 
2441
 
/*
2442
 
 * SIOCGIWAPLIST
2443
 
 */
2444
 
int
2445
 
ar6000_ioctl_iwaplist(struct net_device *dev,
2446
 
            struct iw_request_info *info,
2447
 
            struct iw_point *data, char *extra)
2448
 
{
2449
 
    return -EIO;            /* for now */
2450
 
}
2451
 
 
2452
 
/*
2453
 
 * SIOCSIWSCAN
2454
 
 */
2455
 
int
2456
 
ar6000_ioctl_siwscan(struct net_device *dev,
2457
 
                     struct iw_request_info *info,
2458
 
                     struct iw_point *data, char *extra)
2459
 
{
2460
 
#define ACT_DWELLTIME_DEFAULT   105
2461
 
#define HOME_TXDRAIN_TIME       100
2462
 
#define SCAN_INT                HOME_TXDRAIN_TIME + ACT_DWELLTIME_DEFAULT
2463
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
2464
 
    int ret = 0;
2465
 
 
2466
 
    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
2467
 
        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
2468
 
        return -EOPNOTSUPP;
2469
 
    }
2470
 
 
2471
 
    if (ar->arWmiReady == FALSE) {
2472
 
        return -EIO;
2473
 
    }
2474
 
 
2475
 
    if (ar->arWlanState == WLAN_DISABLED) {
2476
 
        return -EIO;
2477
 
    }
2478
 
 
2479
 
    /* If scan is issued in the middle of ongoing scan or connect,
2480
 
       dont issue another one */
2481
 
    if ( ar->scan_triggered > 0 ) {
2482
 
        ++ar->scan_triggered;
2483
 
        if (ar->scan_triggered < 5) {
2484
 
            return 0;
2485
 
        } else {
2486
 
            AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("Scan request is triggered over 5 times. Not scan complete event\n"));
2487
 
        }
2488
 
    } 
2489
 
 
2490
 
    if (!ar->arUserBssFilter) {
2491
 
        if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != A_OK) {
2492
 
            return -EIO;
2493
 
        }
2494
 
    }
2495
 
 
2496
 
    if (ar->arConnected) {
2497
 
        if  (wmi_get_stats_cmd(ar->arWmi) != A_OK) {
2498
 
            return -EIO;
2499
 
        }
2500
 
    }
2501
 
 
2502
 
#ifdef ANDROID_ENV
2503
 
#if WIRELESS_EXT >= 18
2504
 
    if (data->pointer && (data->length == sizeof(struct iw_scan_req)))
2505
 
    {
2506
 
        if ((data->flags & IW_SCAN_THIS_ESSID) == IW_SCAN_THIS_ESSID)
2507
 
        {
2508
 
            struct iw_scan_req req;
2509
 
            if (copy_from_user(&req, data->pointer, sizeof(struct iw_scan_req)))
2510
 
                return -EIO;
2511
 
            if (wmi_probedSsid_cmd(ar->arWmi, 1, SPECIFIC_SSID_FLAG, req.essid_len, req.essid) != A_OK)
2512
 
                return -EIO;
2513
 
            ar->scanSpecificSsid = 1;
2514
 
        }
2515
 
        else
2516
 
        {
2517
 
            if (ar->scanSpecificSsid) {
2518
 
                if (wmi_probedSsid_cmd(ar->arWmi, 1, DISABLE_SSID_FLAG, 0, NULL) != A_OK)
2519
 
                    return -EIO;
2520
 
                 ar->scanSpecificSsid = 0;
2521
 
            }
2522
 
        }
2523
 
    }
2524
 
    else
2525
 
    {
2526
 
        if (ar->scanSpecificSsid) {
2527
 
            if (wmi_probedSsid_cmd(ar->arWmi, 1, DISABLE_SSID_FLAG, 0, NULL) != A_OK)
2528
 
                return -EIO;
2529
 
             ar->scanSpecificSsid = 0;
2530
 
        }
2531
 
    }
2532
 
#endif
2533
 
#endif /* ANDROID_ENV */
2534
 
 
2535
 
    if (wmi_startscan_cmd(ar->arWmi, WMI_LONG_SCAN, FALSE, FALSE, \
2536
 
                          0, 0, 0, NULL) != A_OK) {
2537
 
        ret = -EIO;
2538
 
    }
2539
 
 
2540
 
    if (ret == 0) {
2541
 
        ar->scan_triggered = 1;
2542
 
    }
2543
 
 
2544
 
    return ret;
2545
 
#undef  ACT_DWELLTIME_DEFAULT
2546
 
#undef HOME_TXDRAIN_TIME
2547
 
#undef SCAN_INT
2548
 
}
2549
 
 
2550
 
 
2551
 
/*
2552
 
 * Units are in db above the noise floor. That means the
2553
 
 * rssi values reported in the tx/rx descriptors in the
2554
 
 * driver are the SNR expressed in db.
2555
 
 *
2556
 
 * If you assume that the noise floor is -95, which is an
2557
 
 * excellent assumption 99.5 % of the time, then you can
2558
 
 * derive the absolute signal level (i.e. -95 + rssi).
2559
 
 * There are some other slight factors to take into account
2560
 
 * depending on whether the rssi measurement is from 11b,
2561
 
 * 11g, or 11a.   These differences are at most 2db and
2562
 
 * can be documented.
2563
 
 *
2564
 
 * NB: various calculations are based on the orinoco/wavelan
2565
 
 *     drivers for compatibility
2566
 
 */
2567
 
static void
2568
 
ar6000_set_quality(struct iw_quality *iq, A_INT8 rssi)
2569
 
{
2570
 
    if (rssi < 0) {
2571
 
        iq->qual = 0;
2572
 
    } else {
2573
 
        iq->qual = rssi;
2574
 
    }
2575
 
 
2576
 
    /* NB: max is 94 because noise is hardcoded to 161 */
2577
 
    if (iq->qual > 94)
2578
 
        iq->qual = 94;
2579
 
 
2580
 
    iq->noise = 161;        /* -95dBm */
2581
 
    iq->level = iq->noise + iq->qual;
2582
 
    iq->updated = 7;
2583
 
}
2584
 
 
2585
 
 
2586
 
int
2587
 
ar6000_ioctl_siwcommit(struct net_device *dev,
2588
 
                     struct iw_request_info *info,
2589
 
                     struct iw_point *data, char *extra)
2590
 
{
2591
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
2592
 
 
2593
 
    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
2594
 
        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
2595
 
        return -EOPNOTSUPP;
2596
 
    }
2597
 
 
2598
 
    if (ar->arWmiReady == FALSE) {
2599
 
        return -EIO;
2600
 
    }
2601
 
 
2602
 
    if (ar->arWlanState == WLAN_DISABLED) {
2603
 
        return -EIO;
2604
 
    }
2605
 
 
2606
 
    AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("AP: SSID %s freq %d authmode %d dot11 auth %d"\
2607
 
                    " PW crypto %d GRP crypto %d\n",
2608
 
                    ar->arSsid, ar->arChannelHint,
2609
 
                    ar->arAuthMode, ar->arDot11AuthMode,
2610
 
                    ar->arPairwiseCrypto, ar->arGroupCrypto));
2611
 
 
2612
 
    ar6000_ap_mode_profile_commit(ar);
2613
 
 
2614
 
    /* if there is a profile switch from STA|IBSS mode to AP mode,
2615
 
     * update the host driver association state for the STA|IBSS mode.
2616
 
     */
2617
 
    if (ar->arNetworkType != AP_NETWORK && ar->arNextMode == AP_NETWORK) {
2618
 
        ar->arConnectPending = FALSE;
2619
 
        ar->arConnected = FALSE;
2620
 
        /* Stop getting pkts from upper stack */
2621
 
        netif_stop_queue(ar->arNetDev);
2622
 
        A_MEMZERO(ar->arBssid, sizeof(ar->arBssid));
2623
 
        ar->arBssChannel = 0;
2624
 
        ar->arBeaconInterval = 0;
2625
 
 
2626
 
        /* Flush the Tx queues */
2627
 
        ar6000_TxDataCleanup(ar);
2628
 
 
2629
 
        /* Start getting pkts from upper stack */
2630
 
        netif_wake_queue(ar->arNetDev);
2631
 
    }
2632
 
 
2633
 
    return 0;
2634
 
}
2635
 
 
2636
 
#define W_PROTO(_x) wait_ ## _x
2637
 
#define WAIT_HANDLER_IMPL(_x, type) \
2638
 
int wait_ ## _x (struct net_device *dev, struct iw_request_info *info, type wrqu, char *extra) {\
2639
 
    int ret; \
2640
 
    dev_hold(dev); \
2641
 
    rtnl_unlock(); \
2642
 
    ret = _x(dev, info, wrqu, extra); \
2643
 
    rtnl_lock(); \
2644
 
    dev_put(dev); \
2645
 
    return ret;\
2646
 
}
2647
 
 
2648
 
WAIT_HANDLER_IMPL(ar6000_ioctl_siwessid, struct iw_point *)
2649
 
WAIT_HANDLER_IMPL(ar6000_ioctl_giwrate, struct iw_param *)
2650
 
WAIT_HANDLER_IMPL(ar6000_ioctl_giwtxpow, struct iw_param *)
2651
 
WAIT_HANDLER_IMPL(ar6000_ioctl_giwrange, struct iw_point*)
2652
 
 
2653
 
/* Structures to export the Wireless Handlers */
2654
 
static const iw_handler ath_handlers[] = {
2655
 
    (iw_handler) ar6000_ioctl_siwcommit,        /* SIOCSIWCOMMIT */
2656
 
    (iw_handler) ar6000_ioctl_giwname,          /* SIOCGIWNAME */
2657
 
    (iw_handler) NULL,                          /* SIOCSIWNWID */
2658
 
    (iw_handler) NULL,                          /* SIOCGIWNWID */
2659
 
    (iw_handler) ar6000_ioctl_siwfreq,          /* SIOCSIWFREQ */
2660
 
    (iw_handler) ar6000_ioctl_giwfreq,          /* SIOCGIWFREQ */
2661
 
    (iw_handler) ar6000_ioctl_siwmode,          /* SIOCSIWMODE */
2662
 
    (iw_handler) ar6000_ioctl_giwmode,          /* SIOCGIWMODE */
2663
 
    (iw_handler) ar6000_ioctl_siwsens,          /* SIOCSIWSENS */
2664
 
    (iw_handler) ar6000_ioctl_giwsens,          /* SIOCGIWSENS */
2665
 
    (iw_handler) NULL /* not _used */,          /* SIOCSIWRANGE */
2666
 
    (iw_handler) W_PROTO(ar6000_ioctl_giwrange),/* SIOCGIWRANGE */
2667
 
    (iw_handler) NULL /* not used */,           /* SIOCSIWPRIV */
2668
 
    (iw_handler) NULL /* kernel code */,        /* SIOCGIWPRIV */
2669
 
    (iw_handler) NULL /* not used */,           /* SIOCSIWSTATS */
2670
 
    (iw_handler) NULL /* kernel code */,        /* SIOCGIWSTATS */
2671
 
    (iw_handler) NULL,                          /* SIOCSIWSPY */
2672
 
    (iw_handler) NULL,                          /* SIOCGIWSPY */
2673
 
    (iw_handler) NULL,                          /* SIOCSIWTHRSPY */
2674
 
    (iw_handler) NULL,                          /* SIOCGIWTHRSPY */
2675
 
    (iw_handler) ar6000_ioctl_siwap,            /* SIOCSIWAP */
2676
 
    (iw_handler) ar6000_ioctl_giwap,            /* SIOCGIWAP */
2677
 
#if (WIRELESS_EXT >= 18)
2678
 
    (iw_handler) ar6000_ioctl_siwmlme,          /* SIOCSIWMLME */
2679
 
#else
2680
 
    (iw_handler) NULL,                          /* -- hole -- */
2681
 
#endif  /* WIRELESS_EXT >= 18 */
2682
 
    (iw_handler) ar6000_ioctl_iwaplist,         /* SIOCGIWAPLIST */
2683
 
    (iw_handler) ar6000_ioctl_siwscan,          /* SIOCSIWSCAN */
2684
 
    (iw_handler) ar6000_ioctl_giwscan,          /* SIOCGIWSCAN */
2685
 
    (iw_handler) W_PROTO(ar6000_ioctl_siwessid),/* SIOCSIWESSID */
2686
 
    (iw_handler) ar6000_ioctl_giwessid,         /* SIOCGIWESSID */
2687
 
    (iw_handler) NULL,                          /* SIOCSIWNICKN */
2688
 
    (iw_handler) NULL,                          /* SIOCGIWNICKN */
2689
 
    (iw_handler) NULL,                          /* -- hole -- */
2690
 
    (iw_handler) NULL,                          /* -- hole -- */
2691
 
    (iw_handler) ar6000_ioctl_siwrate,          /* SIOCSIWRATE */
2692
 
    (iw_handler) W_PROTO(ar6000_ioctl_giwrate), /* SIOCGIWRATE */
2693
 
    (iw_handler) NULL,                          /* SIOCSIWRTS */
2694
 
    (iw_handler) NULL,                          /* SIOCGIWRTS */
2695
 
    (iw_handler) NULL,                          /* SIOCSIWFRAG */
2696
 
    (iw_handler) NULL,                          /* SIOCGIWFRAG */
2697
 
    (iw_handler) ar6000_ioctl_siwtxpow,         /* SIOCSIWTXPOW */
2698
 
    (iw_handler) W_PROTO(ar6000_ioctl_giwtxpow),/* SIOCGIWTXPOW */
2699
 
    (iw_handler) ar6000_ioctl_siwretry,         /* SIOCSIWRETRY */
2700
 
    (iw_handler) ar6000_ioctl_giwretry,         /* SIOCGIWRETRY */
2701
 
    (iw_handler) ar6000_ioctl_siwencode,        /* SIOCSIWENCODE */
2702
 
    (iw_handler) ar6000_ioctl_giwencode,        /* SIOCGIWENCODE */
2703
 
#if WIRELESS_EXT > 20
2704
 
    (iw_handler) ar6000_ioctl_siwpower,         /* SIOCSIWPOWER */
2705
 
    (iw_handler) ar6000_ioctl_giwpower,         /* SIOCGIWPOWER */
2706
 
#endif // WIRELESS_EXT > 20
2707
 
#if WIRELESS_EXT >= 18
2708
 
    (iw_handler) NULL,                          /* -- hole -- */
2709
 
    (iw_handler) NULL,                          /* -- hole -- */
2710
 
    (iw_handler) ar6000_ioctl_siwgenie,         /* SIOCSIWGENIE */
2711
 
    (iw_handler) ar6000_ioctl_giwgenie,         /* SIOCGIWGENIE */
2712
 
    (iw_handler) ar6000_ioctl_siwauth,          /* SIOCSIWAUTH */
2713
 
    (iw_handler) ar6000_ioctl_giwauth,          /* SIOCGIWAUTH */
2714
 
    (iw_handler) ar6000_ioctl_siwencodeext,     /* SIOCSIWENCODEEXT */
2715
 
    (iw_handler) ar6000_ioctl_giwencodeext,     /* SIOCGIWENCODEEXT */
2716
 
    (iw_handler) ar6000_ioctl_siwpmksa,         /* SIOCSIWPMKSA */
2717
 
#endif // WIRELESS_EXT >= 18
2718
 
};
2719
 
 
2720
 
struct iw_handler_def ath_iw_handler_def = {
2721
 
    .standard         = (iw_handler *)ath_handlers,
2722
 
    .num_standard     = ARRAY_SIZE(ath_handlers),
2723
 
    .private          = NULL,
2724
 
    .num_private      = 0,
2725
 
};