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

« back to all changes in this revision

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

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

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

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//------------------------------------------------------------------------------
2
 
// Copyright (c) 2004-2010 Atheros Communications Inc.
3
 
// All rights reserved.
4
 
//
5
 
// 
6
 
//
7
 
// Permission to use, copy, modify, and/or distribute this software for any
8
 
// purpose with or without fee is hereby granted, provided that the above
9
 
// copyright notice and this permission notice appear in all copies.
10
 
//
11
 
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 
//
19
 
//
20
 
//
21
 
// Author(s): ="Atheros"
22
 
//------------------------------------------------------------------------------
23
 
 
24
 
#include <linux/wireless.h>
25
 
#include <linux/ieee80211.h>
26
 
#include <net/cfg80211.h>
27
 
 
28
 
#include "ar6000_drv.h"
29
 
 
30
 
 
31
 
extern A_WAITQUEUE_HEAD arEvent;
32
 
extern unsigned int wmitimeout;
33
 
extern int reconnect_flag;
34
 
 
35
 
 
36
 
#define RATETAB_ENT(_rate, _rateid, _flags) {   \
37
 
    .bitrate    = (_rate),                  \
38
 
    .flags      = (_flags),                 \
39
 
    .hw_value   = (_rateid),                \
40
 
}
41
 
 
42
 
#define CHAN2G(_channel, _freq, _flags) {   \
43
 
    .band           = IEEE80211_BAND_2GHZ,  \
44
 
    .hw_value       = (_channel),           \
45
 
    .center_freq    = (_freq),              \
46
 
    .flags          = (_flags),             \
47
 
    .max_antenna_gain   = 0,                \
48
 
    .max_power      = 30,                   \
49
 
}
50
 
 
51
 
#define CHAN5G(_channel, _flags) {              \
52
 
    .band           = IEEE80211_BAND_5GHZ,      \
53
 
    .hw_value       = (_channel),               \
54
 
    .center_freq    = 5000 + (5 * (_channel)),  \
55
 
    .flags          = (_flags),                 \
56
 
    .max_antenna_gain   = 0,                    \
57
 
    .max_power      = 30,                       \
58
 
}
59
 
 
60
 
static struct
61
 
ieee80211_rate ar6k_rates[] = {
62
 
    RATETAB_ENT(10,  0x1,   0),
63
 
    RATETAB_ENT(20,  0x2,   0),
64
 
    RATETAB_ENT(55,  0x4,   0),
65
 
    RATETAB_ENT(110, 0x8,   0),
66
 
    RATETAB_ENT(60,  0x10,  0),
67
 
    RATETAB_ENT(90,  0x20,  0),
68
 
    RATETAB_ENT(120, 0x40,  0),
69
 
    RATETAB_ENT(180, 0x80,  0),
70
 
    RATETAB_ENT(240, 0x100, 0),
71
 
    RATETAB_ENT(360, 0x200, 0),
72
 
    RATETAB_ENT(480, 0x400, 0),
73
 
    RATETAB_ENT(540, 0x800, 0),
74
 
};
75
 
 
76
 
#define ar6k_a_rates     (ar6k_rates + 4)
77
 
#define ar6k_a_rates_size    8
78
 
#define ar6k_g_rates     (ar6k_rates + 0)
79
 
#define ar6k_g_rates_size    12
80
 
 
81
 
static struct
82
 
ieee80211_channel ar6k_2ghz_channels[] = {
83
 
    CHAN2G(1, 2412, 0),
84
 
    CHAN2G(2, 2417, 0),
85
 
    CHAN2G(3, 2422, 0),
86
 
    CHAN2G(4, 2427, 0),
87
 
    CHAN2G(5, 2432, 0),
88
 
    CHAN2G(6, 2437, 0),
89
 
    CHAN2G(7, 2442, 0),
90
 
    CHAN2G(8, 2447, 0),
91
 
    CHAN2G(9, 2452, 0),
92
 
    CHAN2G(10, 2457, 0),
93
 
    CHAN2G(11, 2462, 0),
94
 
    CHAN2G(12, 2467, 0),
95
 
    CHAN2G(13, 2472, 0),
96
 
    CHAN2G(14, 2484, 0),
97
 
};
98
 
 
99
 
static struct
100
 
ieee80211_channel ar6k_5ghz_a_channels[] = {
101
 
    CHAN5G(34, 0),      CHAN5G(36, 0),
102
 
    CHAN5G(38, 0),      CHAN5G(40, 0),
103
 
    CHAN5G(42, 0),      CHAN5G(44, 0),
104
 
    CHAN5G(46, 0),      CHAN5G(48, 0),
105
 
    CHAN5G(52, 0),      CHAN5G(56, 0),
106
 
    CHAN5G(60, 0),      CHAN5G(64, 0),
107
 
    CHAN5G(100, 0),     CHAN5G(104, 0),
108
 
    CHAN5G(108, 0),     CHAN5G(112, 0),
109
 
    CHAN5G(116, 0),     CHAN5G(120, 0),
110
 
    CHAN5G(124, 0),     CHAN5G(128, 0),
111
 
    CHAN5G(132, 0),     CHAN5G(136, 0),
112
 
    CHAN5G(140, 0),     CHAN5G(149, 0),
113
 
    CHAN5G(153, 0),     CHAN5G(157, 0),
114
 
    CHAN5G(161, 0),     CHAN5G(165, 0),
115
 
    CHAN5G(184, 0),     CHAN5G(188, 0),
116
 
    CHAN5G(192, 0),     CHAN5G(196, 0),
117
 
    CHAN5G(200, 0),     CHAN5G(204, 0),
118
 
    CHAN5G(208, 0),     CHAN5G(212, 0),
119
 
    CHAN5G(216, 0),
120
 
};
121
 
 
122
 
static struct
123
 
ieee80211_supported_band ar6k_band_2ghz = {
124
 
    .n_channels = ARRAY_SIZE(ar6k_2ghz_channels),
125
 
    .channels = ar6k_2ghz_channels,
126
 
    .n_bitrates = ar6k_g_rates_size,
127
 
    .bitrates = ar6k_g_rates,
128
 
};
129
 
 
130
 
static struct
131
 
ieee80211_supported_band ar6k_band_5ghz = {
132
 
    .n_channels = ARRAY_SIZE(ar6k_5ghz_a_channels),
133
 
    .channels = ar6k_5ghz_a_channels,
134
 
    .n_bitrates = ar6k_a_rates_size,
135
 
    .bitrates = ar6k_a_rates,
136
 
};
137
 
 
138
 
static int
139
 
ar6k_set_wpa_version(AR_SOFTC_T *ar, enum nl80211_wpa_versions wpa_version)
140
 
{
141
 
 
142
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: %u\n", __func__, wpa_version));
143
 
 
144
 
    if (!wpa_version) {
145
 
        ar->arAuthMode = NONE_AUTH;
146
 
    } else if (wpa_version & NL80211_WPA_VERSION_1) {
147
 
        ar->arAuthMode = WPA_AUTH;
148
 
    } else if (wpa_version & NL80211_WPA_VERSION_2) {
149
 
        ar->arAuthMode = WPA2_AUTH;
150
 
    } else {
151
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
152
 
                        ("%s: %u not spported\n", __func__, wpa_version));
153
 
        return -ENOTSUPP;
154
 
    }
155
 
 
156
 
    return A_OK;
157
 
}
158
 
 
159
 
static int
160
 
ar6k_set_auth_type(AR_SOFTC_T *ar, enum nl80211_auth_type auth_type)
161
 
{
162
 
 
163
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: 0x%x\n", __func__, auth_type));
164
 
 
165
 
    switch (auth_type) {
166
 
    case NL80211_AUTHTYPE_OPEN_SYSTEM:
167
 
        ar->arDot11AuthMode = OPEN_AUTH;
168
 
        break;
169
 
    case NL80211_AUTHTYPE_SHARED_KEY:
170
 
        ar->arDot11AuthMode = SHARED_AUTH;
171
 
        break;
172
 
    case NL80211_AUTHTYPE_NETWORK_EAP:
173
 
        ar->arDot11AuthMode = LEAP_AUTH;
174
 
        break;
175
 
    default:
176
 
        ar->arDot11AuthMode = OPEN_AUTH;
177
 
        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
178
 
                        ("%s: 0x%x not spported\n", __func__, auth_type));
179
 
        return -ENOTSUPP;
180
 
    }
181
 
 
182
 
    return A_OK;
183
 
}
184
 
 
185
 
static int
186
 
ar6k_set_cipher(AR_SOFTC_T *ar, A_UINT32 cipher, A_BOOL ucast)
187
 
{
188
 
    A_UINT8  *ar_cipher = ucast ? &ar->arPairwiseCrypto :
189
 
                                &ar->arGroupCrypto;
190
 
    A_UINT8  *ar_cipher_len = ucast ? &ar->arPairwiseCryptoLen :
191
 
                                    &ar->arGroupCryptoLen;
192
 
 
193
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
194
 
                    ("%s: cipher 0x%x, ucast %u\n", __func__, cipher, ucast));
195
 
 
196
 
    switch (cipher) {
197
 
    case 0:
198
 
    case IW_AUTH_CIPHER_NONE:
199
 
        *ar_cipher = NONE_CRYPT;
200
 
        *ar_cipher_len = 0;
201
 
        break;
202
 
    case WLAN_CIPHER_SUITE_WEP40:
203
 
        *ar_cipher = WEP_CRYPT;
204
 
        *ar_cipher_len = 5;
205
 
        break;
206
 
    case WLAN_CIPHER_SUITE_WEP104:
207
 
        *ar_cipher = WEP_CRYPT;
208
 
        *ar_cipher_len = 13;
209
 
        break;
210
 
    case WLAN_CIPHER_SUITE_TKIP:
211
 
        *ar_cipher = TKIP_CRYPT;
212
 
        *ar_cipher_len = 0;
213
 
        break;
214
 
    case WLAN_CIPHER_SUITE_CCMP:
215
 
        *ar_cipher = AES_CRYPT;
216
 
        *ar_cipher_len = 0;
217
 
        break;
218
 
    default:
219
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
220
 
                        ("%s: cipher 0x%x not supported\n", __func__, cipher));
221
 
        return -ENOTSUPP;
222
 
    }
223
 
 
224
 
    return A_OK;
225
 
}
226
 
 
227
 
static void
228
 
ar6k_set_key_mgmt(AR_SOFTC_T *ar, A_UINT32 key_mgmt)
229
 
{
230
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: 0x%x\n", __func__, key_mgmt));
231
 
 
232
 
    if (WLAN_AKM_SUITE_PSK == key_mgmt) {
233
 
        if (WPA_AUTH == ar->arAuthMode) {
234
 
            ar->arAuthMode = WPA_PSK_AUTH;
235
 
        } else if (WPA2_AUTH == ar->arAuthMode) {
236
 
            ar->arAuthMode = WPA2_PSK_AUTH;
237
 
        }
238
 
    } else if (WLAN_AKM_SUITE_8021X != key_mgmt) {
239
 
        ar->arAuthMode = NONE_AUTH;
240
 
    }
241
 
}
242
 
 
243
 
static int
244
 
ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
245
 
                      struct cfg80211_connect_params *sme)
246
 
{
247
 
    AR_SOFTC_T *ar = ar6k_priv(dev);
248
 
    A_STATUS status;
249
 
 
250
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
251
 
 
252
 
    if(ar->arWmiReady == FALSE) {
253
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready yet\n", __func__));
254
 
        return -EIO;
255
 
    }
256
 
 
257
 
    if(ar->arWlanState == WLAN_DISABLED) {
258
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
259
 
        return -EIO;
260
 
    }
261
 
 
262
 
    if(ar->bIsDestroyProgress) {
263
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: destroy in progress\n", __func__));
264
 
        return -EBUSY;
265
 
    }
266
 
 
267
 
    if(!sme->ssid_len || IEEE80211_MAX_SSID_LEN < sme->ssid_len) {
268
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ssid invalid\n", __func__));
269
 
        return -EINVAL;
270
 
    }
271
 
 
272
 
    if(ar->arSkipScan == TRUE &&
273
 
       ((sme->channel && sme->channel->center_freq == 0) ||
274
 
        (sme->bssid && !sme->bssid[0] && !sme->bssid[1] && !sme->bssid[2] &&
275
 
         !sme->bssid[3] && !sme->bssid[4] && !sme->bssid[5])))
276
 
    {
277
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s:SkipScan: channel or bssid invalid\n", __func__));
278
 
        return -EINVAL;
279
 
    }
280
 
 
281
 
    if(down_interruptible(&ar->arSem)) {
282
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__));
283
 
        return -ERESTARTSYS;
284
 
    }
285
 
 
286
 
    if(ar->bIsDestroyProgress) {
287
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, destroy in progress\n", __func__));
288
 
        up(&ar->arSem);
289
 
        return -EBUSY;
290
 
    }
291
 
 
292
 
    if(ar->arTxPending[wmi_get_control_ep(ar->arWmi)]) {
293
 
        /*
294
 
        * sleep until the command queue drains
295
 
        */
296
 
        wait_event_interruptible_timeout(arEvent,
297
 
        ar->arTxPending[wmi_get_control_ep(ar->arWmi)] == 0, wmitimeout * HZ);
298
 
        if (signal_pending(current)) {
299
 
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: cmd queue drain timeout\n", __func__));
300
 
            up(&ar->arSem);
301
 
            return -EINTR;
302
 
        }
303
 
    }
304
 
 
305
 
    if(ar->arConnected == TRUE &&
306
 
       ar->arSsidLen == sme->ssid_len &&
307
 
       !A_MEMCMP(ar->arSsid, sme->ssid, ar->arSsidLen)) {
308
 
        reconnect_flag = TRUE;
309
 
        status = wmi_reconnect_cmd(ar->arWmi,
310
 
                                   ar->arReqBssid,
311
 
                                   ar->arChannelHint);
312
 
 
313
 
        up(&ar->arSem);
314
 
        if (status != A_OK) {
315
 
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_reconnect_cmd failed\n", __func__));
316
 
            return -EIO;
317
 
        }
318
 
        return 0;
319
 
    } else if(ar->arSsidLen == sme->ssid_len &&
320
 
              !A_MEMCMP(ar->arSsid, sme->ssid, ar->arSsidLen)) {
321
 
            wmi_disconnect_cmd(ar->arWmi);
322
 
    }
323
 
 
324
 
    A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
325
 
    ar->arSsidLen = sme->ssid_len;
326
 
    A_MEMCPY(ar->arSsid, sme->ssid, sme->ssid_len);
327
 
 
328
 
    if(sme->channel){
329
 
        ar->arChannelHint = sme->channel->center_freq;
330
 
    }
331
 
 
332
 
    A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
333
 
    if(sme->bssid){
334
 
        if(A_MEMCMP(&sme->bssid, bcast_mac, AR6000_ETH_ADDR_LEN)) {
335
 
            A_MEMCPY(ar->arReqBssid, sme->bssid, sizeof(ar->arReqBssid));
336
 
        }
337
 
    }
338
 
 
339
 
    ar6k_set_wpa_version(ar, sme->crypto.wpa_versions);
340
 
    ar6k_set_auth_type(ar, sme->auth_type);
341
 
 
342
 
    if(sme->crypto.n_ciphers_pairwise) {
343
 
        ar6k_set_cipher(ar, sme->crypto.ciphers_pairwise[0], true);
344
 
    } else {
345
 
        ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, true);
346
 
    }
347
 
    ar6k_set_cipher(ar, sme->crypto.cipher_group, false);
348
 
 
349
 
    if(sme->crypto.n_akm_suites) {
350
 
        ar6k_set_key_mgmt(ar, sme->crypto.akm_suites[0]);
351
 
    }
352
 
 
353
 
    if((sme->key_len) &&
354
 
       (NONE_AUTH == ar->arAuthMode) &&
355
 
        (WEP_CRYPT == ar->arPairwiseCrypto)) {
356
 
        struct ar_key *key = NULL;
357
 
 
358
 
        if(sme->key_idx < WMI_MIN_KEY_INDEX || sme->key_idx > WMI_MAX_KEY_INDEX) {
359
 
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
360
 
                            ("%s: key index %d out of bounds\n", __func__, sme->key_idx));
361
 
            up(&ar->arSem);
362
 
            return -ENOENT;
363
 
        }
364
 
 
365
 
        key = &ar->keys[sme->key_idx];
366
 
        key->key_len = sme->key_len;
367
 
        A_MEMCPY(key->key, sme->key, key->key_len);
368
 
        key->cipher = ar->arPairwiseCrypto;
369
 
        ar->arDefTxKeyIndex = sme->key_idx;
370
 
 
371
 
        wmi_addKey_cmd(ar->arWmi, sme->key_idx,
372
 
                    ar->arPairwiseCrypto,
373
 
                    GROUP_USAGE | TX_USAGE,
374
 
                    key->key_len,
375
 
                    NULL,
376
 
                    key->key, KEY_OP_INIT_VAL, NULL,
377
 
                    NO_SYNC_WMIFLAG);
378
 
    }
379
 
 
380
 
    if (!ar->arUserBssFilter) {
381
 
        if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != A_OK) {
382
 
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Couldn't set bss filtering\n", __func__));
383
 
            up(&ar->arSem);
384
 
            return -EIO;
385
 
        }
386
 
    }
387
 
 
388
 
    ar->arNetworkType = ar->arNextMode;
389
 
 
390
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Connect called with authmode %d dot11 auth %d"\
391
 
                    " PW crypto %d PW crypto Len %d GRP crypto %d"\
392
 
                    " GRP crypto Len %d channel hint %u\n",
393
 
                    __func__, ar->arAuthMode, ar->arDot11AuthMode,
394
 
                    ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
395
 
                    ar->arGroupCrypto, ar->arGroupCryptoLen, ar->arChannelHint));
396
 
 
397
 
    reconnect_flag = 0;
398
 
    status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType,
399
 
                            ar->arDot11AuthMode, ar->arAuthMode,
400
 
                            ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
401
 
                            ar->arGroupCrypto,ar->arGroupCryptoLen,
402
 
                            ar->arSsidLen, ar->arSsid,
403
 
                            ar->arReqBssid, ar->arChannelHint,
404
 
                            ar->arConnectCtrlFlags);
405
 
 
406
 
    up(&ar->arSem);
407
 
 
408
 
    if (A_EINVAL == status) {
409
 
        A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
410
 
        ar->arSsidLen = 0;
411
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Invalid request\n", __func__));
412
 
        return -ENOENT;
413
 
    } else if (status != A_OK) {
414
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_connect_cmd failed\n", __func__));
415
 
        return -EIO;
416
 
    }
417
 
 
418
 
    if ((!(ar->arConnectCtrlFlags & CONNECT_DO_WPA_OFFLOAD)) &&
419
 
        ((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)))
420
 
    {
421
 
        A_TIMEOUT_MS(&ar->disconnect_timer, A_DISCONNECT_TIMER_INTERVAL, 0);
422
 
    }
423
 
 
424
 
    ar->arConnectCtrlFlags &= ~CONNECT_DO_WPA_OFFLOAD;
425
 
    ar->arConnectPending = TRUE;
426
 
 
427
 
    return 0;
428
 
}
429
 
 
430
 
void
431
 
ar6k_cfg80211_connect_event(AR_SOFTC_T *ar, A_UINT16 channel,
432
 
                A_UINT8 *bssid, A_UINT16 listenInterval,
433
 
                A_UINT16 beaconInterval,NETWORK_TYPE networkType,
434
 
                A_UINT8 beaconIeLen, A_UINT8 assocReqLen,
435
 
                A_UINT8 assocRespLen, A_UINT8 *assocInfo)
436
 
{
437
 
    A_UINT16 size = 0;
438
 
    A_UINT16 capability = 0;
439
 
    struct cfg80211_bss *bss = NULL;
440
 
    struct ieee80211_mgmt *mgmt = NULL;
441
 
    struct ieee80211_channel *ibss_channel = NULL;
442
 
    s32 signal = 50 * 100;
443
 
    A_UINT8 ie_buf_len = 0;
444
 
    unsigned char ie_buf[256];
445
 
    unsigned char *ptr_ie_buf = ie_buf;
446
 
    unsigned char *ieeemgmtbuf = NULL;
447
 
    A_UINT8 source_mac[ATH_MAC_LEN];
448
 
 
449
 
    A_UINT8 assocReqIeOffset = sizeof(A_UINT16)  +  /* capinfo*/
450
 
                               sizeof(A_UINT16);    /* listen interval */
451
 
    A_UINT8 assocRespIeOffset = sizeof(A_UINT16) +  /* capinfo*/
452
 
                                sizeof(A_UINT16) +  /* status Code */
453
 
                                sizeof(A_UINT16);   /* associd */
454
 
    A_UINT8 *assocReqIe = assocInfo + beaconIeLen + assocReqIeOffset;
455
 
    A_UINT8 *assocRespIe = assocInfo + beaconIeLen + assocReqLen + assocRespIeOffset;
456
 
 
457
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
458
 
 
459
 
    assocReqLen -= assocReqIeOffset;
460
 
    assocRespLen -= assocRespIeOffset;
461
 
 
462
 
    if((ADHOC_NETWORK & networkType)) {
463
 
        if(NL80211_IFTYPE_ADHOC != ar->wdev->iftype) {
464
 
            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
465
 
                            ("%s: ath6k not in ibss mode\n", __func__));
466
 
            return;
467
 
        }
468
 
    }
469
 
 
470
 
    if((INFRA_NETWORK & networkType)) {
471
 
        if(NL80211_IFTYPE_STATION != ar->wdev->iftype) {
472
 
            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
473
 
                            ("%s: ath6k not in station mode\n", __func__));
474
 
            return;
475
 
        }
476
 
    }
477
 
 
478
 
    /* Before informing the join/connect event, make sure that
479
 
     * bss entry is present in scan list, if it not present
480
 
     * construct and insert into scan list, otherwise that
481
 
     * event will be dropped on the way by cfg80211, due to
482
 
     * this keys will not be plumbed in case of WEP and
483
 
     * application will not be aware of join/connect status. */
484
 
    bss = cfg80211_get_bss(ar->wdev->wiphy, NULL, bssid,
485
 
                           ar->wdev->ssid, ar->wdev->ssid_len,
486
 
                           ((ADHOC_NETWORK & networkType) ? WLAN_CAPABILITY_IBSS : WLAN_CAPABILITY_ESS),
487
 
                           ((ADHOC_NETWORK & networkType) ? WLAN_CAPABILITY_IBSS : WLAN_CAPABILITY_ESS));
488
 
 
489
 
    if(!bss) {
490
 
        if (ADHOC_NETWORK & networkType) {
491
 
            /* construct 802.11 mgmt beacon */
492
 
            if(ptr_ie_buf) {
493
 
                *ptr_ie_buf++ = WLAN_EID_SSID;
494
 
                *ptr_ie_buf++ = ar->arSsidLen;
495
 
                A_MEMCPY(ptr_ie_buf, ar->arSsid, ar->arSsidLen);
496
 
                ptr_ie_buf +=ar->arSsidLen;
497
 
 
498
 
                *ptr_ie_buf++ = WLAN_EID_IBSS_PARAMS;
499
 
                *ptr_ie_buf++ = 2; /* length */
500
 
                *ptr_ie_buf++ = 0; /* ATIM window */
501
 
                *ptr_ie_buf++ = 0; /* ATIM window */
502
 
 
503
 
                /* TODO: update ibss params and include supported rates,
504
 
                 * DS param set, extened support rates, wmm. */
505
 
 
506
 
                ie_buf_len = ptr_ie_buf - ie_buf;
507
 
            }
508
 
 
509
 
            capability |= IEEE80211_CAPINFO_IBSS;
510
 
            if(WEP_CRYPT == ar->arPairwiseCrypto) {
511
 
                capability |= IEEE80211_CAPINFO_PRIVACY;
512
 
            }
513
 
            A_MEMCPY(source_mac, ar->arNetDev->dev_addr, ATH_MAC_LEN);
514
 
            ptr_ie_buf = ie_buf;
515
 
        } else {
516
 
            capability = *(A_UINT16 *)(&assocInfo[beaconIeLen]);
517
 
            A_MEMCPY(source_mac, bssid, ATH_MAC_LEN);
518
 
            ptr_ie_buf = assocReqIe;
519
 
            ie_buf_len = assocReqLen;
520
 
        }
521
 
 
522
 
        size = offsetof(struct ieee80211_mgmt, u)
523
 
             + sizeof(mgmt->u.beacon)
524
 
             + ie_buf_len;
525
 
 
526
 
        ieeemgmtbuf = A_MALLOC_NOWAIT(size);
527
 
        if(!ieeemgmtbuf) {
528
 
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
529
 
                            ("%s: ieeeMgmtbuf alloc error\n", __func__));
530
 
            return;
531
 
        }
532
 
 
533
 
        A_MEMZERO(ieeemgmtbuf, size);
534
 
        mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
535
 
        mgmt->frame_control = (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
536
 
        A_MEMCPY(mgmt->da, bcast_mac, ATH_MAC_LEN);
537
 
        A_MEMCPY(mgmt->sa, source_mac, ATH_MAC_LEN);
538
 
        A_MEMCPY(mgmt->bssid, bssid, ATH_MAC_LEN);
539
 
        mgmt->u.beacon.beacon_int = beaconInterval;
540
 
        mgmt->u.beacon.capab_info = capability;
541
 
        A_MEMCPY(mgmt->u.beacon.variable, ptr_ie_buf, ie_buf_len);
542
 
 
543
 
        ibss_channel = ieee80211_get_channel(ar->wdev->wiphy, (int)channel);
544
 
 
545
 
        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
546
 
                ("%s: inform bss with bssid %pM channel %d beaconInterval %d "
547
 
                        "capability 0x%x\n", __func__, mgmt->bssid,
548
 
                        ibss_channel->hw_value, beaconInterval, capability));
549
 
 
550
 
        bss = cfg80211_inform_bss_frame(ar->wdev->wiphy,
551
 
                                        ibss_channel, mgmt,
552
 
                                        le16_to_cpu(size),
553
 
                                        signal, GFP_KERNEL);
554
 
        A_FREE(ieeemgmtbuf);
555
 
        cfg80211_put_bss(bss);
556
 
    }
557
 
 
558
 
    if((ADHOC_NETWORK & networkType)) {
559
 
        cfg80211_ibss_joined(ar->arNetDev, bssid, GFP_KERNEL);
560
 
        return;
561
 
    }
562
 
 
563
 
    if (FALSE == ar->arConnected) {
564
 
        /* inform connect result to cfg80211 */
565
 
        cfg80211_connect_result(ar->arNetDev, bssid,
566
 
                                assocReqIe, assocReqLen,
567
 
                                assocRespIe, assocRespLen,
568
 
                                WLAN_STATUS_SUCCESS, GFP_KERNEL);
569
 
    } else {
570
 
        /* inform roam event to cfg80211 */
571
 
        cfg80211_roamed(ar->arNetDev, bssid,
572
 
                        assocReqIe, assocReqLen,
573
 
                        assocRespIe, assocRespLen,
574
 
                        GFP_KERNEL);
575
 
    }
576
 
}
577
 
 
578
 
static int
579
 
ar6k_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
580
 
                        A_UINT16 reason_code)
581
 
{
582
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
583
 
 
584
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason_code));
585
 
 
586
 
    if(ar->arWmiReady == FALSE) {
587
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
588
 
        return -EIO;
589
 
    }
590
 
 
591
 
    if(ar->arWlanState == WLAN_DISABLED) {
592
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
593
 
        return -EIO;
594
 
    }
595
 
 
596
 
    if(ar->bIsDestroyProgress) {
597
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, destroy in progress\n", __func__));
598
 
        return -EBUSY;
599
 
    }
600
 
 
601
 
    if(down_interruptible(&ar->arSem)) {
602
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__));
603
 
        return -ERESTARTSYS;
604
 
    }
605
 
 
606
 
    reconnect_flag = 0;
607
 
    wmi_disconnect_cmd(ar->arWmi);
608
 
    A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
609
 
    ar->arSsidLen = 0;
610
 
 
611
 
    if (ar->arSkipScan == FALSE) {
612
 
        A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
613
 
    }
614
 
 
615
 
    up(&ar->arSem);
616
 
 
617
 
    return 0;
618
 
}
619
 
 
620
 
void
621
 
ar6k_cfg80211_disconnect_event(AR_SOFTC_T *ar, A_UINT8 reason,
622
 
                               A_UINT8 *bssid, A_UINT8 assocRespLen,
623
 
                               A_UINT8 *assocInfo, A_UINT16 protocolReasonStatus)
624
 
{
625
 
 
626
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason));
627
 
 
628
 
    if((ADHOC_NETWORK & ar->arNetworkType)) {
629
 
        if(NL80211_IFTYPE_ADHOC != ar->wdev->iftype) {
630
 
            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
631
 
                            ("%s: ath6k not in ibss mode\n", __func__));
632
 
            return;
633
 
        }
634
 
        A_MEMZERO(bssid, ETH_ALEN);
635
 
        cfg80211_ibss_joined(ar->arNetDev, bssid, GFP_KERNEL);
636
 
        return;
637
 
    }
638
 
 
639
 
    if((INFRA_NETWORK & ar->arNetworkType)) {
640
 
        if(NL80211_IFTYPE_STATION != ar->wdev->iftype) {
641
 
            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
642
 
                            ("%s: ath6k not in station mode\n", __func__));
643
 
            return;
644
 
        }
645
 
    }
646
 
 
647
 
    if(FALSE == ar->arConnected) {
648
 
        if(NO_NETWORK_AVAIL == reason) {
649
 
            /* connect cmd failed */
650
 
            cfg80211_connect_result(ar->arNetDev, bssid,
651
 
                                    NULL, 0,
652
 
                                    NULL, 0,
653
 
                                    WLAN_STATUS_UNSPECIFIED_FAILURE,
654
 
                                    GFP_KERNEL);
655
 
        }
656
 
    } else {
657
 
        /* connection loss due to disconnect cmd or low rssi */
658
 
        cfg80211_disconnected(ar->arNetDev, reason, NULL, 0, GFP_KERNEL);
659
 
    }
660
 
}
661
 
 
662
 
void
663
 
ar6k_cfg80211_scan_node(void *arg, bss_t *ni)
664
 
{
665
 
    struct wiphy *wiphy = (struct wiphy *)arg;
666
 
    A_UINT16 size;
667
 
    unsigned char *ieeemgmtbuf = NULL;
668
 
    struct ieee80211_mgmt *mgmt;
669
 
    struct ieee80211_channel *channel;
670
 
    struct ieee80211_supported_band *band;
671
 
    struct ieee80211_common_ie  *cie;
672
 
    s32 signal;
673
 
    int freq;
674
 
 
675
 
    cie = &ni->ni_cie;
676
 
 
677
 
#define CHAN_IS_11A(x)  (!((x >= 2412) && (x <= 2484)))
678
 
    if(CHAN_IS_11A(cie->ie_chan)) {
679
 
        /* 11a */
680
 
        band = wiphy->bands[IEEE80211_BAND_5GHZ];
681
 
    } else if((cie->ie_erp) || (cie->ie_xrates)) {
682
 
        /* 11g */
683
 
        band = wiphy->bands[IEEE80211_BAND_2GHZ];
684
 
    } else {
685
 
        /* 11b */
686
 
        band = wiphy->bands[IEEE80211_BAND_2GHZ];
687
 
    }
688
 
 
689
 
    size = ni->ni_framelen + offsetof(struct ieee80211_mgmt, u);
690
 
    ieeemgmtbuf = A_MALLOC_NOWAIT(size);
691
 
    if(!ieeemgmtbuf)
692
 
    {
693
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ieeeMgmtbuf alloc error\n", __func__));
694
 
        return;
695
 
    }
696
 
 
697
 
    /* Note:
698
 
       TODO: Update target to include 802.11 mac header while sending bss info.
699
 
       Target removes 802.11 mac header while sending the bss info to host,
700
 
       cfg80211 needs it, for time being just filling the da, sa and bssid fields alone.
701
 
    */
702
 
    mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
703
 
    A_MEMCPY(mgmt->da, bcast_mac, ATH_MAC_LEN);
704
 
    A_MEMCPY(mgmt->sa, ni->ni_macaddr, ATH_MAC_LEN);
705
 
    A_MEMCPY(mgmt->bssid, ni->ni_macaddr, ATH_MAC_LEN);
706
 
    A_MEMCPY(ieeemgmtbuf + offsetof(struct ieee80211_mgmt, u),
707
 
             ni->ni_buf, ni->ni_framelen);
708
 
 
709
 
    freq    = cie->ie_chan;
710
 
    channel = ieee80211_get_channel(wiphy, freq);
711
 
    signal  = ni->ni_snr * 100;
712
 
 
713
 
        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
714
 
                ("%s: bssid %pM channel %d freq %d size %d\n", __func__,
715
 
                        mgmt->bssid, channel->hw_value, freq, size));
716
 
    cfg80211_inform_bss_frame(wiphy, channel, mgmt,
717
 
                              le16_to_cpu(size),
718
 
                              signal, GFP_KERNEL);
719
 
 
720
 
    A_FREE (ieeemgmtbuf);
721
 
}
722
 
 
723
 
static int
724
 
ar6k_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
725
 
                   struct cfg80211_scan_request *request)
726
 
{
727
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev);
728
 
    int ret = 0;
729
 
    A_BOOL forceFgScan = FALSE;
730
 
 
731
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
732
 
 
733
 
    if(ar->arWmiReady == FALSE) {
734
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
735
 
        return -EIO;
736
 
    }
737
 
 
738
 
    if(ar->arWlanState == WLAN_DISABLED) {
739
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
740
 
        return -EIO;
741
 
    }
742
 
 
743
 
    if (!ar->arUserBssFilter) {
744
 
        if (wmi_bssfilter_cmd(ar->arWmi,
745
 
                             (ar->arConnected ? ALL_BUT_BSS_FILTER : ALL_BSS_FILTER),
746
 
                             0) != A_OK) {
747
 
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Couldn't set bss filtering\n", __func__));
748
 
            return -EIO;
749
 
        }
750
 
    }
751
 
 
752
 
    if(request->n_ssids &&
753
 
       request->ssids[0].ssid_len) {
754
 
        A_UINT8 i;
755
 
 
756
 
        if(request->n_ssids > MAX_PROBED_SSID_INDEX) {
757
 
            request->n_ssids = MAX_PROBED_SSID_INDEX;
758
 
        }
759
 
 
760
 
        for (i = 0; i < request->n_ssids; i++) {
761
 
            wmi_probedSsid_cmd(ar->arWmi, i, SPECIFIC_SSID_FLAG,
762
 
                               request->ssids[i].ssid_len,
763
 
                               request->ssids[i].ssid);
764
 
        }
765
 
    }
766
 
 
767
 
    if(ar->arConnected) {
768
 
        forceFgScan = TRUE;
769
 
    }
770
 
 
771
 
    if(wmi_startscan_cmd(ar->arWmi, WMI_LONG_SCAN, forceFgScan, FALSE, \
772
 
                         0, 0, 0, NULL) != A_OK) {
773
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_startscan_cmd failed\n", __func__));
774
 
        ret = -EIO;
775
 
    }
776
 
 
777
 
    ar->scan_request = request;
778
 
 
779
 
    return ret;
780
 
}
781
 
 
782
 
void
783
 
ar6k_cfg80211_scanComplete_event(AR_SOFTC_T *ar, A_STATUS status)
784
 
{
785
 
 
786
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: status %d\n", __func__, status));
787
 
 
788
 
    if(ar->scan_request)
789
 
    {
790
 
        /* Translate data to cfg80211 mgmt format */
791
 
        wmi_iterate_nodes(ar->arWmi, ar6k_cfg80211_scan_node, ar->wdev->wiphy);
792
 
 
793
 
        cfg80211_scan_done(ar->scan_request,
794
 
                          (status & A_ECANCELED) ? true : false);
795
 
 
796
 
        if(ar->scan_request->n_ssids &&
797
 
           ar->scan_request->ssids[0].ssid_len) {
798
 
            A_UINT8 i;
799
 
 
800
 
            for (i = 0; i < ar->scan_request->n_ssids; i++) {
801
 
                wmi_probedSsid_cmd(ar->arWmi, i, DISABLE_SSID_FLAG,
802
 
                                   0, NULL);
803
 
            }
804
 
        }
805
 
        ar->scan_request = NULL;
806
 
    }
807
 
}
808
 
 
809
 
static int
810
 
ar6k_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
811
 
                      A_UINT8 key_index, bool pairwise, const A_UINT8 *mac_addr,
812
 
                      struct key_params *params)
813
 
{
814
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev);
815
 
    struct ar_key *key = NULL;
816
 
    A_UINT8 key_usage;
817
 
    A_UINT8 key_type;
818
 
    A_STATUS status = 0;
819
 
 
820
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s:\n", __func__));
821
 
 
822
 
    if(ar->arWmiReady == FALSE) {
823
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
824
 
        return -EIO;
825
 
    }
826
 
 
827
 
    if(ar->arWlanState == WLAN_DISABLED) {
828
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
829
 
        return -EIO;
830
 
    }
831
 
 
832
 
    if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
833
 
        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
834
 
                        ("%s: key index %d out of bounds\n", __func__, key_index));
835
 
        return -ENOENT;
836
 
    }
837
 
 
838
 
    key = &ar->keys[key_index];
839
 
    A_MEMZERO(key, sizeof(struct ar_key));
840
 
 
841
 
    if(!mac_addr || is_broadcast_ether_addr(mac_addr)) {
842
 
        key_usage = GROUP_USAGE;
843
 
    } else {
844
 
        key_usage = PAIRWISE_USAGE;
845
 
    }
846
 
 
847
 
    if(params) {
848
 
        if(params->key_len > WLAN_MAX_KEY_LEN ||
849
 
            params->seq_len > IW_ENCODE_SEQ_MAX_SIZE)
850
 
            return -EINVAL;
851
 
 
852
 
        key->key_len = params->key_len;
853
 
        A_MEMCPY(key->key, params->key, key->key_len);
854
 
        key->seq_len = params->seq_len;
855
 
        A_MEMCPY(key->seq, params->seq, key->seq_len);
856
 
        key->cipher = params->cipher;
857
 
    }
858
 
 
859
 
    switch (key->cipher) {
860
 
    case WLAN_CIPHER_SUITE_WEP40:
861
 
    case WLAN_CIPHER_SUITE_WEP104:
862
 
        key_type = WEP_CRYPT;
863
 
        break;
864
 
 
865
 
    case WLAN_CIPHER_SUITE_TKIP:
866
 
        key_type = TKIP_CRYPT;
867
 
        break;
868
 
 
869
 
    case WLAN_CIPHER_SUITE_CCMP:
870
 
        key_type = AES_CRYPT;
871
 
        break;
872
 
 
873
 
    default:
874
 
        return -ENOTSUPP;
875
 
    }
876
 
 
877
 
    if (((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)) &&
878
 
        (GROUP_USAGE & key_usage))
879
 
    {
880
 
        A_UNTIMEOUT(&ar->disconnect_timer);
881
 
    }
882
 
 
883
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
884
 
                    ("%s: index %d, key_len %d, key_type 0x%x,"\
885
 
                    " key_usage 0x%x, seq_len %d\n",
886
 
                    __func__, key_index, key->key_len, key_type,
887
 
                    key_usage, key->seq_len));
888
 
 
889
 
    ar->arDefTxKeyIndex = key_index;
890
 
    status = wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex, key_type, key_usage,
891
 
                    key->key_len, key->seq, key->key, KEY_OP_INIT_VAL,
892
 
                    (A_UINT8*)mac_addr, SYNC_BOTH_WMIFLAG);
893
 
 
894
 
 
895
 
    if(status != A_OK) {
896
 
        return -EIO;
897
 
    }
898
 
 
899
 
    return 0;
900
 
}
901
 
 
902
 
static int
903
 
ar6k_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
904
 
                      A_UINT8 key_index, bool pairwise, const A_UINT8 *mac_addr)
905
 
{
906
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev);
907
 
 
908
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
909
 
 
910
 
    if(ar->arWmiReady == FALSE) {
911
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
912
 
        return -EIO;
913
 
    }
914
 
 
915
 
    if(ar->arWlanState == WLAN_DISABLED) {
916
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
917
 
        return -EIO;
918
 
    }
919
 
 
920
 
    if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
921
 
        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
922
 
                        ("%s: key index %d out of bounds\n", __func__, key_index));
923
 
        return -ENOENT;
924
 
    }
925
 
 
926
 
    if(!ar->keys[key_index].key_len) {
927
 
        AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d is empty\n", __func__, key_index));
928
 
        return 0;
929
 
    }
930
 
 
931
 
    ar->keys[key_index].key_len = 0;
932
 
 
933
 
    return wmi_deleteKey_cmd(ar->arWmi, key_index);
934
 
}
935
 
 
936
 
 
937
 
static int
938
 
ar6k_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
939
 
                      A_UINT8 key_index, bool pairwise, const A_UINT8 *mac_addr,
940
 
                      void *cookie,
941
 
                      void (*callback)(void *cookie, struct key_params*))
942
 
{
943
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev);
944
 
    struct ar_key *key = NULL;
945
 
    struct key_params params;
946
 
 
947
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
948
 
 
949
 
    if(ar->arWmiReady == FALSE) {
950
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
951
 
        return -EIO;
952
 
    }
953
 
 
954
 
    if(ar->arWlanState == WLAN_DISABLED) {
955
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
956
 
        return -EIO;
957
 
    }
958
 
 
959
 
    if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
960
 
        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
961
 
                        ("%s: key index %d out of bounds\n", __func__, key_index));
962
 
        return -ENOENT;
963
 
    }
964
 
 
965
 
    key = &ar->keys[key_index];
966
 
    A_MEMZERO(&params, sizeof(params));
967
 
    params.cipher = key->cipher;
968
 
    params.key_len = key->key_len;
969
 
    params.seq_len = key->seq_len;
970
 
    params.seq = key->seq;
971
 
    params.key = key->key;
972
 
 
973
 
    callback(cookie, &params);
974
 
 
975
 
    return key->key_len ? 0 : -ENOENT;
976
 
}
977
 
 
978
 
 
979
 
static int
980
 
ar6k_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev,
981
 
                              A_UINT8 key_index)
982
 
{
983
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev);
984
 
    struct ar_key *key = NULL;
985
 
    A_STATUS status = A_OK;
986
 
 
987
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
988
 
 
989
 
    if(ar->arWmiReady == FALSE) {
990
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
991
 
        return -EIO;
992
 
    }
993
 
 
994
 
    if(ar->arWlanState == WLAN_DISABLED) {
995
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
996
 
        return -EIO;
997
 
    }
998
 
 
999
 
    if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1000
 
        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
1001
 
                        ("%s: key index %d out of bounds\n",
1002
 
                        __func__, key_index));
1003
 
        return -ENOENT;
1004
 
    }
1005
 
 
1006
 
    if(!ar->keys[key_index].key_len) {
1007
 
        AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: invalid key index %d\n",
1008
 
                        __func__, key_index));
1009
 
        return -EINVAL;
1010
 
    }
1011
 
 
1012
 
    ar->arDefTxKeyIndex = key_index;
1013
 
    key = &ar->keys[ar->arDefTxKeyIndex];
1014
 
    status = wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex,
1015
 
                            ar->arPairwiseCrypto, GROUP_USAGE | TX_USAGE,
1016
 
                            key->key_len, key->seq, key->key, KEY_OP_INIT_VAL,
1017
 
                            NULL, SYNC_BOTH_WMIFLAG);
1018
 
    if (status != A_OK) {
1019
 
        return -EIO;
1020
 
    }
1021
 
 
1022
 
    return 0;
1023
 
}
1024
 
 
1025
 
static int
1026
 
ar6k_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *ndev,
1027
 
                                   A_UINT8 key_index)
1028
 
{
1029
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev);
1030
 
 
1031
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
1032
 
 
1033
 
    if(ar->arWmiReady == FALSE) {
1034
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1035
 
        return -EIO;
1036
 
    }
1037
 
 
1038
 
    if(ar->arWlanState == WLAN_DISABLED) {
1039
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1040
 
        return -EIO;
1041
 
    }
1042
 
 
1043
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
1044
 
    return -ENOTSUPP;
1045
 
}
1046
 
 
1047
 
void
1048
 
ar6k_cfg80211_tkip_micerr_event(AR_SOFTC_T *ar, A_UINT8 keyid, A_BOOL ismcast)
1049
 
{
1050
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
1051
 
                    ("%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast));
1052
 
 
1053
 
    cfg80211_michael_mic_failure(ar->arNetDev, ar->arBssid,
1054
 
                                 (ismcast ? NL80211_KEYTYPE_GROUP : NL80211_KEYTYPE_PAIRWISE),
1055
 
                                 keyid, NULL, GFP_KERNEL);
1056
 
}
1057
 
 
1058
 
static int
1059
 
ar6k_cfg80211_set_wiphy_params(struct wiphy *wiphy, A_UINT32 changed)
1060
 
{
1061
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)wiphy_priv(wiphy);
1062
 
 
1063
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: changed 0x%x\n", __func__, changed));
1064
 
 
1065
 
    if(ar->arWmiReady == FALSE) {
1066
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1067
 
        return -EIO;
1068
 
    }
1069
 
 
1070
 
    if(ar->arWlanState == WLAN_DISABLED) {
1071
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1072
 
        return -EIO;
1073
 
    }
1074
 
 
1075
 
    if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1076
 
        if (wmi_set_rts_cmd(ar->arWmi,wiphy->rts_threshold) != A_OK){
1077
 
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_set_rts_cmd failed\n", __func__));
1078
 
            return -EIO;
1079
 
        }
1080
 
    }
1081
 
 
1082
 
    return 0;
1083
 
}
1084
 
 
1085
 
static int
1086
 
ar6k_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
1087
 
                               const A_UINT8 *peer,
1088
 
                               const struct cfg80211_bitrate_mask *mask)
1089
 
{
1090
 
    AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Setting rates: Not supported\n"));
1091
 
    return -EIO;
1092
 
}
1093
 
 
1094
 
/* The type nl80211_tx_power_setting replaces the following data type from 2.6.36 onwards */
1095
 
static int
1096
 
ar6k_cfg80211_set_txpower(struct wiphy *wiphy, enum nl80211_tx_power_setting type, int dbm)
1097
 
{
1098
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)wiphy_priv(wiphy);
1099
 
    A_UINT8 ar_dbm;
1100
 
 
1101
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x, dbm %d\n", __func__, type, dbm));
1102
 
 
1103
 
    if(ar->arWmiReady == FALSE) {
1104
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1105
 
        return -EIO;
1106
 
    }
1107
 
 
1108
 
    if(ar->arWlanState == WLAN_DISABLED) {
1109
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1110
 
        return -EIO;
1111
 
    }
1112
 
 
1113
 
    ar->arTxPwrSet = FALSE;
1114
 
    switch(type) {
1115
 
    case NL80211_TX_POWER_AUTOMATIC:
1116
 
        return 0;
1117
 
    case NL80211_TX_POWER_LIMITED:
1118
 
        ar->arTxPwr = ar_dbm = dbm;
1119
 
        ar->arTxPwrSet = TRUE;
1120
 
        break;
1121
 
    default:
1122
 
        AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x not supported\n", __func__, type));
1123
 
        return -EOPNOTSUPP;
1124
 
    }
1125
 
 
1126
 
    wmi_set_txPwr_cmd(ar->arWmi, ar_dbm);
1127
 
 
1128
 
    return 0;
1129
 
}
1130
 
 
1131
 
static int
1132
 
ar6k_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
1133
 
{
1134
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)wiphy_priv(wiphy);
1135
 
 
1136
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1137
 
 
1138
 
    if(ar->arWmiReady == FALSE) {
1139
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1140
 
        return -EIO;
1141
 
    }
1142
 
 
1143
 
    if(ar->arWlanState == WLAN_DISABLED) {
1144
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1145
 
        return -EIO;
1146
 
    }
1147
 
 
1148
 
    if((ar->arConnected == TRUE)) {
1149
 
        ar->arTxPwr = 0;
1150
 
 
1151
 
        if(wmi_get_txPwr_cmd(ar->arWmi) != A_OK) {
1152
 
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_get_txPwr_cmd failed\n", __func__));
1153
 
            return -EIO;
1154
 
        }
1155
 
 
1156
 
        wait_event_interruptible_timeout(arEvent, ar->arTxPwr != 0, 5 * HZ);
1157
 
 
1158
 
        if(signal_pending(current)) {
1159
 
            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Target did not respond\n", __func__));
1160
 
            return -EINTR;
1161
 
        }
1162
 
    }
1163
 
 
1164
 
    *dbm = ar->arTxPwr;
1165
 
    return 0;
1166
 
}
1167
 
 
1168
 
static int
1169
 
ar6k_cfg80211_set_power_mgmt(struct wiphy *wiphy,
1170
 
                             struct net_device *dev,
1171
 
                             bool pmgmt, int timeout)
1172
 
{
1173
 
    AR_SOFTC_T *ar = ar6k_priv(dev);
1174
 
    WMI_POWER_MODE_CMD pwrMode;
1175
 
 
1176
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: pmgmt %d, timeout %d\n", __func__, pmgmt, timeout));
1177
 
 
1178
 
    if(ar->arWmiReady == FALSE) {
1179
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1180
 
        return -EIO;
1181
 
    }
1182
 
 
1183
 
    if(ar->arWlanState == WLAN_DISABLED) {
1184
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1185
 
        return -EIO;
1186
 
    }
1187
 
 
1188
 
    if(pmgmt) {
1189
 
        AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Max Perf\n", __func__));
1190
 
        pwrMode.powerMode = MAX_PERF_POWER;
1191
 
    } else {
1192
 
        AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Rec Power\n", __func__));
1193
 
        pwrMode.powerMode = REC_POWER;
1194
 
    }
1195
 
 
1196
 
    if(wmi_powermode_cmd(ar->arWmi, pwrMode.powerMode) != A_OK) {
1197
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_powermode_cmd failed\n", __func__));
1198
 
        return -EIO;
1199
 
    }
1200
 
 
1201
 
    return 0;
1202
 
}
1203
 
 
1204
 
static int
1205
 
ar6k_cfg80211_add_virtual_intf(struct wiphy *wiphy, char *name,
1206
 
                                            enum nl80211_iftype type, u32 *flags,
1207
 
                                            struct vif_params *params)
1208
 
{
1209
 
 
1210
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
1211
 
 
1212
 
    /* Multiple virtual interface is not supported.
1213
 
     * The default interface supports STA and IBSS type
1214
 
     */
1215
 
    return -EOPNOTSUPP;
1216
 
}
1217
 
 
1218
 
static int
1219
 
ar6k_cfg80211_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev)
1220
 
{
1221
 
 
1222
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
1223
 
 
1224
 
    /* Multiple virtual interface is not supported.
1225
 
     * The default interface supports STA and IBSS type
1226
 
     */
1227
 
    return -EOPNOTSUPP;
1228
 
}
1229
 
 
1230
 
static int
1231
 
ar6k_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
1232
 
                           enum nl80211_iftype type, u32 *flags,
1233
 
                           struct vif_params *params)
1234
 
{
1235
 
    AR_SOFTC_T *ar = ar6k_priv(ndev);
1236
 
    struct wireless_dev *wdev = ar->wdev;
1237
 
 
1238
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type %u\n", __func__, type));
1239
 
 
1240
 
    if(ar->arWmiReady == FALSE) {
1241
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1242
 
        return -EIO;
1243
 
    }
1244
 
 
1245
 
    if(ar->arWlanState == WLAN_DISABLED) {
1246
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1247
 
        return -EIO;
1248
 
    }
1249
 
 
1250
 
    switch (type) {
1251
 
    case NL80211_IFTYPE_STATION:
1252
 
        ar->arNextMode = INFRA_NETWORK;
1253
 
        break;
1254
 
    case NL80211_IFTYPE_ADHOC:
1255
 
        ar->arNextMode = ADHOC_NETWORK;
1256
 
        break;
1257
 
    default:
1258
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: type %u\n", __func__, type));
1259
 
        return -EOPNOTSUPP;
1260
 
    }
1261
 
 
1262
 
    wdev->iftype = type;
1263
 
 
1264
 
    return 0;
1265
 
}
1266
 
 
1267
 
static int
1268
 
ar6k_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1269
 
                        struct cfg80211_ibss_params *ibss_param)
1270
 
{
1271
 
    AR_SOFTC_T *ar = ar6k_priv(dev);
1272
 
    A_STATUS status;
1273
 
 
1274
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1275
 
 
1276
 
    if(ar->arWmiReady == FALSE) {
1277
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1278
 
        return -EIO;
1279
 
    }
1280
 
 
1281
 
    if(ar->arWlanState == WLAN_DISABLED) {
1282
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1283
 
        return -EIO;
1284
 
    }
1285
 
 
1286
 
    if(!ibss_param->ssid_len || IEEE80211_MAX_SSID_LEN < ibss_param->ssid_len) {
1287
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ssid invalid\n", __func__));
1288
 
        return -EINVAL;
1289
 
    }
1290
 
 
1291
 
    ar->arSsidLen = ibss_param->ssid_len;
1292
 
    A_MEMCPY(ar->arSsid, ibss_param->ssid, ar->arSsidLen);
1293
 
 
1294
 
    if(ibss_param->channel) {
1295
 
        ar->arChannelHint = ibss_param->channel->center_freq;
1296
 
    }
1297
 
 
1298
 
    if(ibss_param->channel_fixed) {
1299
 
        /* TODO: channel_fixed: The channel should be fixed, do not search for
1300
 
         * IBSSs to join on other channels. Target firmware does not support this
1301
 
         * feature, needs to be updated.*/
1302
 
    }
1303
 
 
1304
 
    A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
1305
 
    if(ibss_param->bssid) {
1306
 
        if(A_MEMCMP(&ibss_param->bssid, bcast_mac, AR6000_ETH_ADDR_LEN)) {
1307
 
            A_MEMCPY(ar->arReqBssid, ibss_param->bssid, sizeof(ar->arReqBssid));
1308
 
        }
1309
 
    }
1310
 
 
1311
 
    ar6k_set_wpa_version(ar, 0);
1312
 
    ar6k_set_auth_type(ar, NL80211_AUTHTYPE_OPEN_SYSTEM);
1313
 
 
1314
 
    if(ibss_param->privacy) {
1315
 
        ar6k_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, true);
1316
 
        ar6k_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, false);
1317
 
    } else {
1318
 
        ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, true);
1319
 
        ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, false);
1320
 
    }
1321
 
 
1322
 
    ar->arNetworkType = ar->arNextMode;
1323
 
 
1324
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Connect called with authmode %d dot11 auth %d"\
1325
 
                    " PW crypto %d PW crypto Len %d GRP crypto %d"\
1326
 
                    " GRP crypto Len %d channel hint %u\n",
1327
 
                    __func__, ar->arAuthMode, ar->arDot11AuthMode,
1328
 
                    ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
1329
 
                    ar->arGroupCrypto, ar->arGroupCryptoLen, ar->arChannelHint));
1330
 
 
1331
 
    status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType,
1332
 
                            ar->arDot11AuthMode, ar->arAuthMode,
1333
 
                            ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
1334
 
                            ar->arGroupCrypto,ar->arGroupCryptoLen,
1335
 
                            ar->arSsidLen, ar->arSsid,
1336
 
                            ar->arReqBssid, ar->arChannelHint,
1337
 
                            ar->arConnectCtrlFlags);
1338
 
 
1339
 
    return 0;
1340
 
}
1341
 
 
1342
 
static int
1343
 
ar6k_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1344
 
{
1345
 
    AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1346
 
 
1347
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1348
 
 
1349
 
    if(ar->arWmiReady == FALSE) {
1350
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1351
 
        return -EIO;
1352
 
    }
1353
 
 
1354
 
    if(ar->arWlanState == WLAN_DISABLED) {
1355
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1356
 
        return -EIO;
1357
 
    }
1358
 
 
1359
 
    wmi_disconnect_cmd(ar->arWmi);
1360
 
    A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
1361
 
    ar->arSsidLen = 0;
1362
 
 
1363
 
    return 0;
1364
 
}
1365
 
 
1366
 
 
1367
 
static const
1368
 
A_UINT32 cipher_suites[] = {
1369
 
    WLAN_CIPHER_SUITE_WEP40,
1370
 
    WLAN_CIPHER_SUITE_WEP104,
1371
 
    WLAN_CIPHER_SUITE_TKIP,
1372
 
    WLAN_CIPHER_SUITE_CCMP,
1373
 
};
1374
 
 
1375
 
static struct
1376
 
cfg80211_ops ar6k_cfg80211_ops = {
1377
 
    .change_virtual_intf = ar6k_cfg80211_change_iface,
1378
 
    .add_virtual_intf = ar6k_cfg80211_add_virtual_intf,
1379
 
    .del_virtual_intf = ar6k_cfg80211_del_virtual_intf,
1380
 
    .scan = ar6k_cfg80211_scan,
1381
 
    .connect = ar6k_cfg80211_connect,
1382
 
    .disconnect = ar6k_cfg80211_disconnect,
1383
 
    .add_key = ar6k_cfg80211_add_key,
1384
 
    .get_key = ar6k_cfg80211_get_key,
1385
 
    .del_key = ar6k_cfg80211_del_key,
1386
 
    .set_default_key = ar6k_cfg80211_set_default_key,
1387
 
    .set_default_mgmt_key = ar6k_cfg80211_set_default_mgmt_key,
1388
 
    .set_wiphy_params = ar6k_cfg80211_set_wiphy_params,
1389
 
    .set_bitrate_mask = ar6k_cfg80211_set_bitrate_mask,
1390
 
    .set_tx_power = ar6k_cfg80211_set_txpower,
1391
 
    .get_tx_power = ar6k_cfg80211_get_txpower,
1392
 
    .set_power_mgmt = ar6k_cfg80211_set_power_mgmt,
1393
 
    .join_ibss = ar6k_cfg80211_join_ibss,
1394
 
    .leave_ibss = ar6k_cfg80211_leave_ibss,
1395
 
};
1396
 
 
1397
 
struct wireless_dev *
1398
 
ar6k_cfg80211_init(struct device *dev)
1399
 
{
1400
 
    int ret = 0;
1401
 
    struct wireless_dev *wdev;
1402
 
 
1403
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1404
 
 
1405
 
    wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
1406
 
    if(!wdev) {
1407
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1408
 
                        ("%s: Couldn't allocate wireless device\n", __func__));
1409
 
        return ERR_PTR(-ENOMEM);
1410
 
    }
1411
 
 
1412
 
    /* create a new wiphy for use with cfg80211 */
1413
 
    wdev->wiphy = wiphy_new(&ar6k_cfg80211_ops, sizeof(AR_SOFTC_T));
1414
 
    if(!wdev->wiphy) {
1415
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1416
 
                        ("%s: Couldn't allocate wiphy device\n", __func__));
1417
 
        kfree(wdev);
1418
 
        return ERR_PTR(-ENOMEM);
1419
 
    }
1420
 
 
1421
 
    /* set device pointer for wiphy */
1422
 
    set_wiphy_dev(wdev->wiphy, dev);
1423
 
 
1424
 
    wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1425
 
                                   BIT(NL80211_IFTYPE_ADHOC);
1426
 
    /* max num of ssids that can be probed during scanning */
1427
 
    wdev->wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
1428
 
    wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar6k_band_2ghz;
1429
 
    wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar6k_band_5ghz;
1430
 
    wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
1431
 
 
1432
 
    wdev->wiphy->cipher_suites = cipher_suites;
1433
 
    wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
1434
 
 
1435
 
    ret = wiphy_register(wdev->wiphy);
1436
 
    if(ret < 0) {
1437
 
        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1438
 
                        ("%s: Couldn't register wiphy device\n", __func__));
1439
 
        wiphy_free(wdev->wiphy);
1440
 
        return ERR_PTR(ret);
1441
 
    }
1442
 
 
1443
 
    return wdev;
1444
 
}
1445
 
 
1446
 
void
1447
 
ar6k_cfg80211_deinit(AR_SOFTC_T *ar)
1448
 
{
1449
 
    struct wireless_dev *wdev = ar->wdev;
1450
 
 
1451
 
    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1452
 
 
1453
 
    if(ar->scan_request) {
1454
 
        cfg80211_scan_done(ar->scan_request, true);
1455
 
        ar->scan_request = NULL;
1456
 
    }
1457
 
 
1458
 
    if(!wdev)
1459
 
        return;
1460
 
 
1461
 
    wiphy_unregister(wdev->wiphy);
1462
 
    wiphy_free(wdev->wiphy);
1463
 
    kfree(wdev);
1464
 
}
1465
 
 
1466
 
 
1467
 
 
1468
 
 
1469
 
 
1470
 
 
1471