staging: ath6kl: open/shared auth implementation
[pandora-kernel.git] / drivers / staging / ath6kl / os / linux / cfg80211.c
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(struct ar6_softc *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 0;
157 }
158
159 static int
160 ar6k_set_auth_type(struct ar6_softc *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
176     case NL80211_AUTHTYPE_AUTOMATIC:
177         ar->arDot11AuthMode = OPEN_AUTH;
178         ar->arAutoAuthStage = AUTH_OPEN_IN_PROGRESS;
179         break;
180
181     default:
182         ar->arDot11AuthMode = OPEN_AUTH;
183         AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
184                         ("%s: 0x%x not spported\n", __func__, auth_type));
185         return -ENOTSUPP;
186     }
187
188     return 0;
189 }
190
191 static int
192 ar6k_set_cipher(struct ar6_softc *ar, u32 cipher, bool ucast)
193 {
194     u8 *ar_cipher = ucast ? &ar->arPairwiseCrypto :
195                                 &ar->arGroupCrypto;
196     u8 *ar_cipher_len = ucast ? &ar->arPairwiseCryptoLen :
197                                     &ar->arGroupCryptoLen;
198
199     AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
200                     ("%s: cipher 0x%x, ucast %u\n", __func__, cipher, ucast));
201
202     switch (cipher) {
203     case 0:
204     case IW_AUTH_CIPHER_NONE:
205         *ar_cipher = NONE_CRYPT;
206         *ar_cipher_len = 0;
207         break;
208     case WLAN_CIPHER_SUITE_WEP40:
209         *ar_cipher = WEP_CRYPT;
210         *ar_cipher_len = 5;
211         break;
212     case WLAN_CIPHER_SUITE_WEP104:
213         *ar_cipher = WEP_CRYPT;
214         *ar_cipher_len = 13;
215         break;
216     case WLAN_CIPHER_SUITE_TKIP:
217         *ar_cipher = TKIP_CRYPT;
218         *ar_cipher_len = 0;
219         break;
220     case WLAN_CIPHER_SUITE_CCMP:
221         *ar_cipher = AES_CRYPT;
222         *ar_cipher_len = 0;
223         break;
224     default:
225         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
226                         ("%s: cipher 0x%x not supported\n", __func__, cipher));
227         return -ENOTSUPP;
228     }
229
230     return 0;
231 }
232
233 static void
234 ar6k_set_key_mgmt(struct ar6_softc *ar, u32 key_mgmt)
235 {
236     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: 0x%x\n", __func__, key_mgmt));
237
238     if (WLAN_AKM_SUITE_PSK == key_mgmt) {
239         if (WPA_AUTH == ar->arAuthMode) {
240             ar->arAuthMode = WPA_PSK_AUTH;
241         } else if (WPA2_AUTH == ar->arAuthMode) {
242             ar->arAuthMode = WPA2_PSK_AUTH;
243         }
244     } else if (WLAN_AKM_SUITE_8021X != key_mgmt) {
245         ar->arAuthMode = NONE_AUTH;
246     }
247 }
248
249 static int
250 ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
251                       struct cfg80211_connect_params *sme)
252 {
253     struct ar6_softc *ar = ar6k_priv(dev);
254     int status;
255
256     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
257     ar->smeState = SME_CONNECTING;
258
259     if(ar->arWmiReady == false) {
260         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready yet\n", __func__));
261         return -EIO;
262     }
263
264     if(ar->arWlanState == WLAN_DISABLED) {
265         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
266         return -EIO;
267     }
268
269     if(ar->bIsDestroyProgress) {
270         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: destroy in progress\n", __func__));
271         return -EBUSY;
272     }
273
274     if(!sme->ssid_len || IEEE80211_MAX_SSID_LEN < sme->ssid_len) {
275         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ssid invalid\n", __func__));
276         return -EINVAL;
277     }
278
279     if(ar->arSkipScan == true &&
280        ((sme->channel && sme->channel->center_freq == 0) ||
281         (sme->bssid && !sme->bssid[0] && !sme->bssid[1] && !sme->bssid[2] &&
282          !sme->bssid[3] && !sme->bssid[4] && !sme->bssid[5])))
283     {
284         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s:SkipScan: channel or bssid invalid\n", __func__));
285         return -EINVAL;
286     }
287
288     if(down_interruptible(&ar->arSem)) {
289         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__));
290         return -ERESTARTSYS;
291     }
292
293     if(ar->bIsDestroyProgress) {
294         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, destroy in progress\n", __func__));
295         up(&ar->arSem);
296         return -EBUSY;
297     }
298
299     if(ar->arTxPending[wmi_get_control_ep(ar->arWmi)]) {
300         /*
301         * sleep until the command queue drains
302         */
303         wait_event_interruptible_timeout(arEvent,
304         ar->arTxPending[wmi_get_control_ep(ar->arWmi)] == 0, wmitimeout * HZ);
305         if (signal_pending(current)) {
306             AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: cmd queue drain timeout\n", __func__));
307             up(&ar->arSem);
308             return -EINTR;
309         }
310     }
311
312     if(ar->arConnected == true &&
313        ar->arSsidLen == sme->ssid_len &&
314        !memcmp(ar->arSsid, sme->ssid, ar->arSsidLen)) {
315         reconnect_flag = true;
316         status = wmi_reconnect_cmd(ar->arWmi,
317                                    ar->arReqBssid,
318                                    ar->arChannelHint);
319
320         up(&ar->arSem);
321         if (status) {
322             AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_reconnect_cmd failed\n", __func__));
323             return -EIO;
324         }
325         return 0;
326     } else if(ar->arSsidLen == sme->ssid_len &&
327               !memcmp(ar->arSsid, sme->ssid, ar->arSsidLen)) {
328             ar6000_disconnect(ar);
329     }
330
331     A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
332     ar->arSsidLen = sme->ssid_len;
333     memcpy(ar->arSsid, sme->ssid, sme->ssid_len);
334
335     if(sme->channel){
336         ar->arChannelHint = sme->channel->center_freq;
337     }
338
339     A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
340     if(sme->bssid){
341         if(memcmp(&sme->bssid, bcast_mac, AR6000_ETH_ADDR_LEN)) {
342             memcpy(ar->arReqBssid, sme->bssid, sizeof(ar->arReqBssid));
343         }
344     }
345
346     ar6k_set_wpa_version(ar, sme->crypto.wpa_versions);
347     ar6k_set_auth_type(ar, sme->auth_type);
348
349     if(sme->crypto.n_ciphers_pairwise) {
350         ar6k_set_cipher(ar, sme->crypto.ciphers_pairwise[0], true);
351     } else {
352         ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, true);
353     }
354     ar6k_set_cipher(ar, sme->crypto.cipher_group, false);
355
356     if(sme->crypto.n_akm_suites) {
357         ar6k_set_key_mgmt(ar, sme->crypto.akm_suites[0]);
358     }
359
360     if((sme->key_len) &&
361        (NONE_AUTH == ar->arAuthMode) &&
362         (WEP_CRYPT == ar->arPairwiseCrypto)) {
363         struct ar_key *key = NULL;
364
365         if(sme->key_idx < WMI_MIN_KEY_INDEX || sme->key_idx > WMI_MAX_KEY_INDEX) {
366             AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
367                             ("%s: key index %d out of bounds\n", __func__, sme->key_idx));
368             up(&ar->arSem);
369             return -ENOENT;
370         }
371
372         key = &ar->keys[sme->key_idx];
373         key->key_len = sme->key_len;
374         memcpy(key->key, sme->key, key->key_len);
375         key->cipher = ar->arPairwiseCrypto;
376         ar->arDefTxKeyIndex = sme->key_idx;
377
378         wmi_addKey_cmd(ar->arWmi, sme->key_idx,
379                     ar->arPairwiseCrypto,
380                     GROUP_USAGE | TX_USAGE,
381                     key->key_len,
382                     NULL,
383                     key->key, KEY_OP_INIT_VAL, NULL,
384                     NO_SYNC_WMIFLAG);
385     }
386
387     if (!ar->arUserBssFilter) {
388         if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != 0) {
389             AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Couldn't set bss filtering\n", __func__));
390             up(&ar->arSem);
391             return -EIO;
392         }
393     }
394
395     ar->arNetworkType = ar->arNextMode;
396
397     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Connect called with authmode %d dot11 auth %d"\
398                     " PW crypto %d PW crypto Len %d GRP crypto %d"\
399                     " GRP crypto Len %d channel hint %u\n",
400                     __func__, ar->arAuthMode, ar->arDot11AuthMode,
401                     ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
402                     ar->arGroupCrypto, ar->arGroupCryptoLen, ar->arChannelHint));
403
404     reconnect_flag = 0;
405     status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType,
406                             ar->arDot11AuthMode, ar->arAuthMode,
407                             ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
408                             ar->arGroupCrypto,ar->arGroupCryptoLen,
409                             ar->arSsidLen, ar->arSsid,
410                             ar->arReqBssid, ar->arChannelHint,
411                             ar->arConnectCtrlFlags);
412
413     up(&ar->arSem);
414
415     if (A_EINVAL == status) {
416         A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
417         ar->arSsidLen = 0;
418         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Invalid request\n", __func__));
419         return -ENOENT;
420     } else if (status) {
421         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_connect_cmd failed\n", __func__));
422         return -EIO;
423     }
424
425     if ((!(ar->arConnectCtrlFlags & CONNECT_DO_WPA_OFFLOAD)) &&
426         ((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)))
427     {
428         A_TIMEOUT_MS(&ar->disconnect_timer, A_DISCONNECT_TIMER_INTERVAL, 0);
429     }
430
431     ar->arConnectCtrlFlags &= ~CONNECT_DO_WPA_OFFLOAD;
432     ar->arConnectPending = true;
433
434     return 0;
435 }
436
437 void
438 ar6k_cfg80211_connect_event(struct ar6_softc *ar, u16 channel,
439                 u8 *bssid, u16 listenInterval,
440                 u16 beaconInterval,NETWORK_TYPE networkType,
441                 u8 beaconIeLen, u8 assocReqLen,
442                 u8 assocRespLen, u8 *assocInfo)
443 {
444     u16 size = 0;
445     u16 capability = 0;
446     struct cfg80211_bss *bss = NULL;
447     struct ieee80211_mgmt *mgmt = NULL;
448     struct ieee80211_channel *ibss_channel = NULL;
449     s32 signal = 50 * 100;
450     u8 ie_buf_len = 0;
451     unsigned char ie_buf[256];
452     unsigned char *ptr_ie_buf = ie_buf;
453     unsigned char *ieeemgmtbuf = NULL;
454     u8 source_mac[ATH_MAC_LEN];
455
456     u8 assocReqIeOffset = sizeof(u16)  +  /* capinfo*/
457                                sizeof(u16);    /* listen interval */
458     u8 assocRespIeOffset = sizeof(u16) +  /* capinfo*/
459                                 sizeof(u16) +  /* status Code */
460                                 sizeof(u16);   /* associd */
461     u8 *assocReqIe = assocInfo + beaconIeLen + assocReqIeOffset;
462     u8 *assocRespIe = assocInfo + beaconIeLen + assocReqLen + assocRespIeOffset;
463
464     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
465
466     assocReqLen -= assocReqIeOffset;
467     assocRespLen -= assocRespIeOffset;
468
469     ar->arAutoAuthStage = AUTH_IDLE;
470
471     if((ADHOC_NETWORK & networkType)) {
472         if(NL80211_IFTYPE_ADHOC != ar->wdev->iftype) {
473             AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
474                             ("%s: ath6k not in ibss mode\n", __func__));
475             return;
476         }
477     }
478
479     if((INFRA_NETWORK & networkType)) {
480         if(NL80211_IFTYPE_STATION != ar->wdev->iftype) {
481             AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
482                             ("%s: ath6k not in station mode\n", __func__));
483             return;
484         }
485     }
486
487     /* Before informing the join/connect event, make sure that
488      * bss entry is present in scan list, if it not present
489      * construct and insert into scan list, otherwise that
490      * event will be dropped on the way by cfg80211, due to
491      * this keys will not be plumbed in case of WEP and
492      * application will not be aware of join/connect status. */
493     bss = cfg80211_get_bss(ar->wdev->wiphy, NULL, bssid,
494                            ar->wdev->ssid, ar->wdev->ssid_len,
495                            ((ADHOC_NETWORK & networkType) ? WLAN_CAPABILITY_IBSS : WLAN_CAPABILITY_ESS),
496                            ((ADHOC_NETWORK & networkType) ? WLAN_CAPABILITY_IBSS : WLAN_CAPABILITY_ESS));
497
498     /*
499      * Earlier we were updating the cfg about bss by making a beacon frame
500      * only if the entry for bss is not there. This can have some issue if
501      * ROAM event is generated and a heavy traffic is ongoing. The ROAM
502      * event is handled through a work queue and by the time it really gets
503      * handled, BSS would have been aged out. So it is better to update the
504      * cfg about BSS irrespective of its entry being present right now or
505      * not.
506      */
507
508     if (ADHOC_NETWORK & networkType) {
509             /* construct 802.11 mgmt beacon */
510             if(ptr_ie_buf) {
511                     *ptr_ie_buf++ = WLAN_EID_SSID;
512                     *ptr_ie_buf++ = ar->arSsidLen;
513                     memcpy(ptr_ie_buf, ar->arSsid, ar->arSsidLen);
514                     ptr_ie_buf +=ar->arSsidLen;
515
516                     *ptr_ie_buf++ = WLAN_EID_IBSS_PARAMS;
517                     *ptr_ie_buf++ = 2; /* length */
518                     *ptr_ie_buf++ = 0; /* ATIM window */
519                     *ptr_ie_buf++ = 0; /* ATIM window */
520
521                     /* TODO: update ibss params and include supported rates,
522                      * DS param set, extened support rates, wmm. */
523
524                     ie_buf_len = ptr_ie_buf - ie_buf;
525             }
526
527             capability |= IEEE80211_CAPINFO_IBSS;
528             if(WEP_CRYPT == ar->arPairwiseCrypto) {
529                     capability |= IEEE80211_CAPINFO_PRIVACY;
530             }
531             memcpy(source_mac, ar->arNetDev->dev_addr, ATH_MAC_LEN);
532             ptr_ie_buf = ie_buf;
533     } else {
534             capability = *(u16 *)(&assocInfo[beaconIeLen]);
535             memcpy(source_mac, bssid, ATH_MAC_LEN);
536             ptr_ie_buf = assocReqIe;
537             ie_buf_len = assocReqLen;
538     }
539
540     size = offsetof(struct ieee80211_mgmt, u)
541             + sizeof(mgmt->u.beacon)
542             + ie_buf_len;
543
544     ieeemgmtbuf = A_MALLOC_NOWAIT(size);
545     if(!ieeemgmtbuf) {
546             AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
547                             ("%s: ieeeMgmtbuf alloc error\n", __func__));
548             return;
549     }
550
551     A_MEMZERO(ieeemgmtbuf, size);
552     mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
553     mgmt->frame_control = (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
554     memcpy(mgmt->da, bcast_mac, ATH_MAC_LEN);
555     memcpy(mgmt->sa, source_mac, ATH_MAC_LEN);
556     memcpy(mgmt->bssid, bssid, ATH_MAC_LEN);
557     mgmt->u.beacon.beacon_int = beaconInterval;
558     mgmt->u.beacon.capab_info = capability;
559     memcpy(mgmt->u.beacon.variable, ptr_ie_buf, ie_buf_len);
560
561     ibss_channel = ieee80211_get_channel(ar->wdev->wiphy, (int)channel);
562
563     AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
564                     ("%s: inform bss with bssid %pM channel %d beaconInterval %d "
565                      "capability 0x%x\n", __func__, mgmt->bssid,
566                      ibss_channel->hw_value, beaconInterval, capability));
567
568     bss = cfg80211_inform_bss_frame(ar->wdev->wiphy,
569                                     ibss_channel, mgmt,
570                                     le16_to_cpu(size),
571                                     signal, GFP_KERNEL);
572     kfree(ieeemgmtbuf);
573     cfg80211_put_bss(bss);
574
575     if((ADHOC_NETWORK & networkType)) {
576         cfg80211_ibss_joined(ar->arNetDev, bssid, GFP_KERNEL);
577         return;
578     }
579
580     if (false == ar->arConnected) {
581         /* inform connect result to cfg80211 */
582         ar->smeState = SME_DISCONNECTED;
583         cfg80211_connect_result(ar->arNetDev, bssid,
584                                 assocReqIe, assocReqLen,
585                                 assocRespIe, assocRespLen,
586                                 WLAN_STATUS_SUCCESS, GFP_KERNEL);
587     } else {
588         /* inform roam event to cfg80211 */
589         cfg80211_roamed(ar->arNetDev, bssid,
590                         assocReqIe, assocReqLen,
591                         assocRespIe, assocRespLen,
592                         GFP_KERNEL);
593     }
594 }
595
596 static int
597 ar6k_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
598                         u16 reason_code)
599 {
600     struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
601
602     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason_code));
603
604     if(ar->arWmiReady == false) {
605         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
606         return -EIO;
607     }
608
609     if(ar->arWlanState == WLAN_DISABLED) {
610         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
611         return -EIO;
612     }
613
614     if(ar->bIsDestroyProgress) {
615         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, destroy in progress\n", __func__));
616         return -EBUSY;
617     }
618
619     if(down_interruptible(&ar->arSem)) {
620         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__));
621         return -ERESTARTSYS;
622     }
623
624     reconnect_flag = 0;
625     ar6000_disconnect(ar);
626     A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
627     ar->arSsidLen = 0;
628
629     if (ar->arSkipScan == false) {
630         A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
631     }
632
633     up(&ar->arSem);
634
635     return 0;
636 }
637
638 void
639 ar6k_cfg80211_disconnect_event(struct ar6_softc *ar, u8 reason,
640                                u8 *bssid, u8 assocRespLen,
641                                u8 *assocInfo, u16 protocolReasonStatus)
642 {
643
644     u16 status;
645
646     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason));
647
648     if (ar->scan_request) {
649         cfg80211_scan_done(ar->scan_request, true);
650         ar->scan_request = NULL;
651     }
652     if((ADHOC_NETWORK & ar->arNetworkType)) {
653         if(NL80211_IFTYPE_ADHOC != ar->wdev->iftype) {
654             AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
655                             ("%s: ath6k not in ibss mode\n", __func__));
656             return;
657         }
658         A_MEMZERO(bssid, ETH_ALEN);
659         cfg80211_ibss_joined(ar->arNetDev, bssid, GFP_KERNEL);
660         return;
661     }
662
663     if((INFRA_NETWORK & ar->arNetworkType)) {
664         if(NL80211_IFTYPE_STATION != ar->wdev->iftype) {
665             AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
666                             ("%s: ath6k not in station mode\n", __func__));
667             return;
668         }
669     }
670
671     if(true == ar->arConnectPending) {
672         if(NO_NETWORK_AVAIL == reason) {
673             /* connect cmd failed */
674             wmi_disconnect_cmd(ar->arWmi);
675         } else if (reason == DISCONNECT_CMD) {
676                 if (ar->arAutoAuthStage) {
677                         /*
678                          * If the current auth algorithm is open try shared
679                          * and make autoAuthStage idle. We do not make it
680                          * leap for now being.
681                          */
682                         if (ar->arDot11AuthMode == OPEN_AUTH) {
683                                 struct ar_key *key = NULL;
684                                 key = &ar->keys[ar->arDefTxKeyIndex];
685                                 if (down_interruptible(&ar->arSem)) {
686                                         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__));
687                                         return;
688                                 }
689
690
691                                 ar->arDot11AuthMode = SHARED_AUTH;
692                                 ar->arAutoAuthStage = AUTH_IDLE;
693
694                                 wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex,
695                                                 ar->arPairwiseCrypto,
696                                                 GROUP_USAGE | TX_USAGE,
697                                                 key->key_len,
698                                                 NULL,
699                                                 key->key, KEY_OP_INIT_VAL, NULL,
700                                                 NO_SYNC_WMIFLAG);
701
702                                 status = wmi_connect_cmd(ar->arWmi,
703                                                          ar->arNetworkType,
704                                                          ar->arDot11AuthMode,
705                                                          ar->arAuthMode,
706                                                          ar->arPairwiseCrypto,
707                                                          ar->arPairwiseCryptoLen,
708                                                          ar->arGroupCrypto,
709                                                          ar->arGroupCryptoLen,
710                                                          ar->arSsidLen,
711                                                          ar->arSsid,
712                                                          ar->arReqBssid,
713                                                          ar->arChannelHint,
714                                                          ar->arConnectCtrlFlags);
715                                 up(&ar->arSem);
716
717                         } else if (ar->arDot11AuthMode == SHARED_AUTH) {
718                                 /* should not reach here */
719                         }
720                 } else {
721                         ar->arConnectPending = false;
722                         if (ar->smeState == SME_CONNECTING) {
723                                 cfg80211_connect_result(ar->arNetDev, bssid,
724                                                         NULL, 0,
725                                                         NULL, 0,
726                                                         WLAN_STATUS_UNSPECIFIED_FAILURE,
727                                                         GFP_KERNEL);
728                         } else {
729                                 cfg80211_disconnected(ar->arNetDev,
730                                                       reason,
731                                                       NULL, 0,
732                                                       GFP_KERNEL);
733                         }
734                         ar->smeState = SME_DISCONNECTED;
735                 }
736         }
737     } else {
738             if (reason != DISCONNECT_CMD)
739                     wmi_disconnect_cmd(ar->arWmi);
740     }
741 }
742
743 void
744 ar6k_cfg80211_scan_node(void *arg, bss_t *ni)
745 {
746     struct wiphy *wiphy = (struct wiphy *)arg;
747     u16 size;
748     unsigned char *ieeemgmtbuf = NULL;
749     struct ieee80211_mgmt *mgmt;
750     struct ieee80211_channel *channel;
751     struct ieee80211_supported_band *band;
752     struct ieee80211_common_ie  *cie;
753     s32 signal;
754     int freq;
755
756     cie = &ni->ni_cie;
757
758 #define CHAN_IS_11A(x)  (!((x >= 2412) && (x <= 2484)))
759     if(CHAN_IS_11A(cie->ie_chan)) {
760         /* 11a */
761         band = wiphy->bands[IEEE80211_BAND_5GHZ];
762     } else if((cie->ie_erp) || (cie->ie_xrates)) {
763         /* 11g */
764         band = wiphy->bands[IEEE80211_BAND_2GHZ];
765     } else {
766         /* 11b */
767         band = wiphy->bands[IEEE80211_BAND_2GHZ];
768     }
769
770     size = ni->ni_framelen + offsetof(struct ieee80211_mgmt, u);
771     ieeemgmtbuf = A_MALLOC_NOWAIT(size);
772     if(!ieeemgmtbuf)
773     {
774         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ieeeMgmtbuf alloc error\n", __func__));
775         return;
776     }
777
778     /* Note:
779        TODO: Update target to include 802.11 mac header while sending bss info.
780        Target removes 802.11 mac header while sending the bss info to host,
781        cfg80211 needs it, for time being just filling the da, sa and bssid fields alone.
782     */
783     mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
784     memcpy(mgmt->da, bcast_mac, ATH_MAC_LEN);
785     memcpy(mgmt->sa, ni->ni_macaddr, ATH_MAC_LEN);
786     memcpy(mgmt->bssid, ni->ni_macaddr, ATH_MAC_LEN);
787     memcpy(ieeemgmtbuf + offsetof(struct ieee80211_mgmt, u),
788              ni->ni_buf, ni->ni_framelen);
789
790     freq    = cie->ie_chan;
791     channel = ieee80211_get_channel(wiphy, freq);
792     signal  = ni->ni_snr * 100;
793
794         AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
795                 ("%s: bssid %pM channel %d freq %d size %d\n", __func__,
796                         mgmt->bssid, channel->hw_value, freq, size));
797     cfg80211_inform_bss_frame(wiphy, channel, mgmt,
798                               le16_to_cpu(size),
799                               signal, GFP_KERNEL);
800
801     kfree (ieeemgmtbuf);
802 }
803
804 static int
805 ar6k_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
806                    struct cfg80211_scan_request *request)
807 {
808     struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
809     int ret = 0;
810     u32 forceFgScan = 0;
811
812     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
813
814     if(ar->arWmiReady == false) {
815         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
816         return -EIO;
817     }
818
819     if(ar->arWlanState == WLAN_DISABLED) {
820         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
821         return -EIO;
822     }
823
824     if (!ar->arUserBssFilter) {
825         if (wmi_bssfilter_cmd(ar->arWmi,
826                              (ar->arConnected ? ALL_BUT_BSS_FILTER : ALL_BSS_FILTER),
827                              0) != 0) {
828             AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Couldn't set bss filtering\n", __func__));
829             return -EIO;
830         }
831     }
832
833     if(request->n_ssids &&
834        request->ssids[0].ssid_len) {
835         u8 i;
836
837         if(request->n_ssids > (MAX_PROBED_SSID_INDEX - 1)) {
838             request->n_ssids = MAX_PROBED_SSID_INDEX - 1;
839         }
840
841         for (i = 0; i < request->n_ssids; i++) {
842             wmi_probedSsid_cmd(ar->arWmi, i+1, SPECIFIC_SSID_FLAG,
843                                request->ssids[i].ssid_len,
844                                request->ssids[i].ssid);
845         }
846     }
847
848     if(ar->arConnected) {
849         forceFgScan = 1;
850     }
851
852     if(wmi_startscan_cmd(ar->arWmi, WMI_LONG_SCAN, forceFgScan, false, \
853                          0, 0, 0, NULL) != 0) {
854         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_startscan_cmd failed\n", __func__));
855         ret = -EIO;
856     }
857
858     ar->scan_request = request;
859
860     return ret;
861 }
862
863 void
864 ar6k_cfg80211_scanComplete_event(struct ar6_softc *ar, int status)
865 {
866
867     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: status %d\n", __func__, status));
868
869     if(ar->scan_request)
870     {
871         /* Translate data to cfg80211 mgmt format */
872         wmi_iterate_nodes(ar->arWmi, ar6k_cfg80211_scan_node, ar->wdev->wiphy);
873
874         cfg80211_scan_done(ar->scan_request,
875             ((status & A_ECANCELED) || (status & A_EBUSY)) ? true : false);
876
877         if(ar->scan_request->n_ssids &&
878            ar->scan_request->ssids[0].ssid_len) {
879             u8 i;
880
881             for (i = 0; i < ar->scan_request->n_ssids; i++) {
882                 wmi_probedSsid_cmd(ar->arWmi, i+1, DISABLE_SSID_FLAG,
883                                    0, NULL);
884             }
885         }
886         ar->scan_request = NULL;
887     }
888 }
889
890 static int
891 ar6k_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
892                       u8 key_index, bool pairwise, const u8 *mac_addr,
893                       struct key_params *params)
894 {
895     struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
896     struct ar_key *key = NULL;
897     u8 key_usage;
898     u8 key_type;
899     int status = 0;
900
901     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s:\n", __func__));
902
903     if(ar->arWmiReady == false) {
904         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
905         return -EIO;
906     }
907
908     if(ar->arWlanState == WLAN_DISABLED) {
909         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
910         return -EIO;
911     }
912
913     if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
914         AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
915                         ("%s: key index %d out of bounds\n", __func__, key_index));
916         return -ENOENT;
917     }
918
919     key = &ar->keys[key_index];
920     A_MEMZERO(key, sizeof(struct ar_key));
921
922     if(!mac_addr || is_broadcast_ether_addr(mac_addr)) {
923         key_usage = GROUP_USAGE;
924     } else {
925         key_usage = PAIRWISE_USAGE;
926     }
927
928     if(params) {
929         if(params->key_len > WLAN_MAX_KEY_LEN ||
930             params->seq_len > IW_ENCODE_SEQ_MAX_SIZE)
931             return -EINVAL;
932
933         key->key_len = params->key_len;
934         memcpy(key->key, params->key, key->key_len);
935         key->seq_len = params->seq_len;
936         memcpy(key->seq, params->seq, key->seq_len);
937         key->cipher = params->cipher;
938     }
939
940     switch (key->cipher) {
941     case WLAN_CIPHER_SUITE_WEP40:
942     case WLAN_CIPHER_SUITE_WEP104:
943         key_type = WEP_CRYPT;
944         break;
945
946     case WLAN_CIPHER_SUITE_TKIP:
947         key_type = TKIP_CRYPT;
948         break;
949
950     case WLAN_CIPHER_SUITE_CCMP:
951         key_type = AES_CRYPT;
952         break;
953
954     default:
955         return -ENOTSUPP;
956     }
957
958     if (((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)) &&
959         (GROUP_USAGE & key_usage))
960     {
961         A_UNTIMEOUT(&ar->disconnect_timer);
962     }
963
964     AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
965                     ("%s: index %d, key_len %d, key_type 0x%x,"\
966                     " key_usage 0x%x, seq_len %d\n",
967                     __func__, key_index, key->key_len, key_type,
968                     key_usage, key->seq_len));
969
970     ar->arDefTxKeyIndex = key_index;
971     status = wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex, key_type, key_usage,
972                     key->key_len, key->seq, key->key, KEY_OP_INIT_VAL,
973                     (u8 *)mac_addr, SYNC_BOTH_WMIFLAG);
974
975
976     if (status) {
977         return -EIO;
978     }
979
980     return 0;
981 }
982
983 static int
984 ar6k_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
985                       u8 key_index, bool pairwise, const u8 *mac_addr)
986 {
987     struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
988
989     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
990
991     if(ar->arWmiReady == false) {
992         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
993         return -EIO;
994     }
995
996     if(ar->arWlanState == WLAN_DISABLED) {
997         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
998         return -EIO;
999     }
1000
1001     if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1002         AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
1003                         ("%s: key index %d out of bounds\n", __func__, key_index));
1004         return -ENOENT;
1005     }
1006
1007     if(!ar->keys[key_index].key_len) {
1008         AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d is empty\n", __func__, key_index));
1009         return 0;
1010     }
1011
1012     ar->keys[key_index].key_len = 0;
1013
1014     return wmi_deleteKey_cmd(ar->arWmi, key_index);
1015 }
1016
1017
1018 static int
1019 ar6k_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1020                       u8 key_index, bool pairwise, const u8 *mac_addr,
1021                       void *cookie,
1022                       void (*callback)(void *cookie, struct key_params*))
1023 {
1024     struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
1025     struct ar_key *key = NULL;
1026     struct key_params params;
1027
1028     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
1029
1030     if(ar->arWmiReady == false) {
1031         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1032         return -EIO;
1033     }
1034
1035     if(ar->arWlanState == WLAN_DISABLED) {
1036         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1037         return -EIO;
1038     }
1039
1040     if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1041         AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
1042                         ("%s: key index %d out of bounds\n", __func__, key_index));
1043         return -ENOENT;
1044     }
1045
1046     key = &ar->keys[key_index];
1047     A_MEMZERO(&params, sizeof(params));
1048     params.cipher = key->cipher;
1049     params.key_len = key->key_len;
1050     params.seq_len = key->seq_len;
1051     params.seq = key->seq;
1052     params.key = key->key;
1053
1054     callback(cookie, &params);
1055
1056     return key->key_len ? 0 : -ENOENT;
1057 }
1058
1059
1060 static int
1061 ar6k_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev,
1062                               u8 key_index, bool unicast, bool multicast)
1063 {
1064     struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
1065     struct ar_key *key = NULL;
1066     int status = 0;
1067     u8 key_usage;
1068
1069     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
1070
1071     if(ar->arWmiReady == false) {
1072         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1073         return -EIO;
1074     }
1075
1076     if(ar->arWlanState == WLAN_DISABLED) {
1077         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1078         return -EIO;
1079     }
1080
1081     if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1082         AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
1083                         ("%s: key index %d out of bounds\n",
1084                         __func__, key_index));
1085         return -ENOENT;
1086     }
1087
1088     if(!ar->keys[key_index].key_len) {
1089         AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: invalid key index %d\n",
1090                         __func__, key_index));
1091         return -EINVAL;
1092     }
1093
1094     ar->arDefTxKeyIndex = key_index;
1095     key = &ar->keys[ar->arDefTxKeyIndex];
1096     key_usage = GROUP_USAGE;
1097     if (WEP_CRYPT == ar->arPairwiseCrypto) {
1098         key_usage |= TX_USAGE;
1099     }
1100
1101     status = wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex,
1102                             ar->arPairwiseCrypto, key_usage,
1103                             key->key_len, key->seq, key->key, KEY_OP_INIT_VAL,
1104                             NULL, SYNC_BOTH_WMIFLAG);
1105     if (status) {
1106         return -EIO;
1107     }
1108
1109     return 0;
1110 }
1111
1112 static int
1113 ar6k_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *ndev,
1114                                    u8 key_index)
1115 {
1116     struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
1117
1118     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
1119
1120     if(ar->arWmiReady == false) {
1121         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1122         return -EIO;
1123     }
1124
1125     if(ar->arWlanState == WLAN_DISABLED) {
1126         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1127         return -EIO;
1128     }
1129
1130     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
1131     return -ENOTSUPP;
1132 }
1133
1134 void
1135 ar6k_cfg80211_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast)
1136 {
1137     AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
1138                     ("%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast));
1139
1140     cfg80211_michael_mic_failure(ar->arNetDev, ar->arBssid,
1141                                  (ismcast ? NL80211_KEYTYPE_GROUP : NL80211_KEYTYPE_PAIRWISE),
1142                                  keyid, NULL, GFP_KERNEL);
1143 }
1144
1145 static int
1146 ar6k_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1147 {
1148     struct ar6_softc *ar = (struct ar6_softc *)wiphy_priv(wiphy);
1149
1150     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: changed 0x%x\n", __func__, changed));
1151
1152     if(ar->arWmiReady == false) {
1153         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1154         return -EIO;
1155     }
1156
1157     if(ar->arWlanState == WLAN_DISABLED) {
1158         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1159         return -EIO;
1160     }
1161
1162     if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1163         if (wmi_set_rts_cmd(ar->arWmi,wiphy->rts_threshold) != 0){
1164             AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_set_rts_cmd failed\n", __func__));
1165             return -EIO;
1166         }
1167     }
1168
1169     return 0;
1170 }
1171
1172 static int
1173 ar6k_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
1174                                const u8 *peer,
1175                                const struct cfg80211_bitrate_mask *mask)
1176 {
1177     AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Setting rates: Not supported\n"));
1178     return -EIO;
1179 }
1180
1181 /* The type nl80211_tx_power_setting replaces the following data type from 2.6.36 onwards */
1182 static int
1183 ar6k_cfg80211_set_txpower(struct wiphy *wiphy, enum nl80211_tx_power_setting type, int dbm)
1184 {
1185     struct ar6_softc *ar = (struct ar6_softc *)wiphy_priv(wiphy);
1186     u8 ar_dbm;
1187
1188     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x, dbm %d\n", __func__, type, dbm));
1189
1190     if(ar->arWmiReady == false) {
1191         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1192         return -EIO;
1193     }
1194
1195     if(ar->arWlanState == WLAN_DISABLED) {
1196         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1197         return -EIO;
1198     }
1199
1200     ar->arTxPwrSet = false;
1201     switch(type) {
1202     case NL80211_TX_POWER_AUTOMATIC:
1203         return 0;
1204     case NL80211_TX_POWER_LIMITED:
1205         ar->arTxPwr = ar_dbm = dbm;
1206         ar->arTxPwrSet = true;
1207         break;
1208     default:
1209         AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x not supported\n", __func__, type));
1210         return -EOPNOTSUPP;
1211     }
1212
1213     wmi_set_txPwr_cmd(ar->arWmi, ar_dbm);
1214
1215     return 0;
1216 }
1217
1218 static int
1219 ar6k_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
1220 {
1221     struct ar6_softc *ar = (struct ar6_softc *)wiphy_priv(wiphy);
1222
1223     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1224
1225     if(ar->arWmiReady == false) {
1226         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1227         return -EIO;
1228     }
1229
1230     if(ar->arWlanState == WLAN_DISABLED) {
1231         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1232         return -EIO;
1233     }
1234
1235     if((ar->arConnected == true)) {
1236         ar->arTxPwr = 0;
1237
1238         if(wmi_get_txPwr_cmd(ar->arWmi) != 0) {
1239             AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_get_txPwr_cmd failed\n", __func__));
1240             return -EIO;
1241         }
1242
1243         wait_event_interruptible_timeout(arEvent, ar->arTxPwr != 0, 5 * HZ);
1244
1245         if(signal_pending(current)) {
1246             AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Target did not respond\n", __func__));
1247             return -EINTR;
1248         }
1249     }
1250
1251     *dbm = ar->arTxPwr;
1252     return 0;
1253 }
1254
1255 static int
1256 ar6k_cfg80211_set_power_mgmt(struct wiphy *wiphy,
1257                              struct net_device *dev,
1258                              bool pmgmt, int timeout)
1259 {
1260     struct ar6_softc *ar = ar6k_priv(dev);
1261     WMI_POWER_MODE_CMD pwrMode;
1262
1263     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: pmgmt %d, timeout %d\n", __func__, pmgmt, timeout));
1264
1265     if(ar->arWmiReady == false) {
1266         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1267         return -EIO;
1268     }
1269
1270     if(ar->arWlanState == WLAN_DISABLED) {
1271         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1272         return -EIO;
1273     }
1274
1275     if(pmgmt) {
1276         AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Max Perf\n", __func__));
1277         pwrMode.powerMode = REC_POWER;
1278     } else {
1279         AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Rec Power\n", __func__));
1280         pwrMode.powerMode = MAX_PERF_POWER;
1281     }
1282
1283     if(wmi_powermode_cmd(ar->arWmi, pwrMode.powerMode) != 0) {
1284         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_powermode_cmd failed\n", __func__));
1285         return -EIO;
1286     }
1287
1288     return 0;
1289 }
1290
1291 static struct net_device *
1292 ar6k_cfg80211_add_virtual_intf(struct wiphy *wiphy, char *name,
1293                                             enum nl80211_iftype type, u32 *flags,
1294                                             struct vif_params *params)
1295 {
1296
1297     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
1298
1299     /* Multiple virtual interface is not supported.
1300      * The default interface supports STA and IBSS type
1301      */
1302     return ERR_PTR(-EOPNOTSUPP);
1303 }
1304
1305 static int
1306 ar6k_cfg80211_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev)
1307 {
1308
1309     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
1310
1311     /* Multiple virtual interface is not supported.
1312      * The default interface supports STA and IBSS type
1313      */
1314     return -EOPNOTSUPP;
1315 }
1316
1317 static int
1318 ar6k_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
1319                            enum nl80211_iftype type, u32 *flags,
1320                            struct vif_params *params)
1321 {
1322     struct ar6_softc *ar = ar6k_priv(ndev);
1323     struct wireless_dev *wdev = ar->wdev;
1324
1325     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type %u\n", __func__, type));
1326
1327     if(ar->arWmiReady == false) {
1328         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1329         return -EIO;
1330     }
1331
1332     if(ar->arWlanState == WLAN_DISABLED) {
1333         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1334         return -EIO;
1335     }
1336
1337     switch (type) {
1338     case NL80211_IFTYPE_STATION:
1339         ar->arNextMode = INFRA_NETWORK;
1340         break;
1341     case NL80211_IFTYPE_ADHOC:
1342         ar->arNextMode = ADHOC_NETWORK;
1343         break;
1344     default:
1345         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: type %u\n", __func__, type));
1346         return -EOPNOTSUPP;
1347     }
1348
1349     wdev->iftype = type;
1350
1351     return 0;
1352 }
1353
1354 static int
1355 ar6k_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1356                         struct cfg80211_ibss_params *ibss_param)
1357 {
1358     struct ar6_softc *ar = ar6k_priv(dev);
1359     int status;
1360
1361     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1362
1363     if(ar->arWmiReady == false) {
1364         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1365         return -EIO;
1366     }
1367
1368     if(ar->arWlanState == WLAN_DISABLED) {
1369         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1370         return -EIO;
1371     }
1372
1373     if(!ibss_param->ssid_len || IEEE80211_MAX_SSID_LEN < ibss_param->ssid_len) {
1374         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ssid invalid\n", __func__));
1375         return -EINVAL;
1376     }
1377
1378     ar->arSsidLen = ibss_param->ssid_len;
1379     memcpy(ar->arSsid, ibss_param->ssid, ar->arSsidLen);
1380
1381     if(ibss_param->channel) {
1382         ar->arChannelHint = ibss_param->channel->center_freq;
1383     }
1384
1385     if(ibss_param->channel_fixed) {
1386         /* TODO: channel_fixed: The channel should be fixed, do not search for
1387          * IBSSs to join on other channels. Target firmware does not support this
1388          * feature, needs to be updated.*/
1389     }
1390
1391     A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
1392     if(ibss_param->bssid) {
1393         if(memcmp(&ibss_param->bssid, bcast_mac, AR6000_ETH_ADDR_LEN)) {
1394             memcpy(ar->arReqBssid, ibss_param->bssid, sizeof(ar->arReqBssid));
1395         }
1396     }
1397
1398     ar6k_set_wpa_version(ar, 0);
1399     ar6k_set_auth_type(ar, NL80211_AUTHTYPE_OPEN_SYSTEM);
1400
1401     if(ibss_param->privacy) {
1402         ar6k_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, true);
1403         ar6k_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, false);
1404     } else {
1405         ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, true);
1406         ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, false);
1407     }
1408
1409     ar->arNetworkType = ar->arNextMode;
1410
1411     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Connect called with authmode %d dot11 auth %d"\
1412                     " PW crypto %d PW crypto Len %d GRP crypto %d"\
1413                     " GRP crypto Len %d channel hint %u\n",
1414                     __func__, ar->arAuthMode, ar->arDot11AuthMode,
1415                     ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
1416                     ar->arGroupCrypto, ar->arGroupCryptoLen, ar->arChannelHint));
1417
1418     status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType,
1419                             ar->arDot11AuthMode, ar->arAuthMode,
1420                             ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
1421                             ar->arGroupCrypto,ar->arGroupCryptoLen,
1422                             ar->arSsidLen, ar->arSsid,
1423                             ar->arReqBssid, ar->arChannelHint,
1424                             ar->arConnectCtrlFlags);
1425     ar->arConnectPending = true;
1426
1427     return 0;
1428 }
1429
1430 static int
1431 ar6k_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1432 {
1433     struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
1434
1435     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1436
1437     if(ar->arWmiReady == false) {
1438         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1439         return -EIO;
1440     }
1441
1442     if(ar->arWlanState == WLAN_DISABLED) {
1443         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1444         return -EIO;
1445     }
1446
1447     ar6000_disconnect(ar);
1448     A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
1449     ar->arSsidLen = 0;
1450
1451     return 0;
1452 }
1453
1454
1455 static const
1456 u32 cipher_suites[] = {
1457     WLAN_CIPHER_SUITE_WEP40,
1458     WLAN_CIPHER_SUITE_WEP104,
1459     WLAN_CIPHER_SUITE_TKIP,
1460     WLAN_CIPHER_SUITE_CCMP,
1461 };
1462
1463 static struct
1464 cfg80211_ops ar6k_cfg80211_ops = {
1465     .change_virtual_intf = ar6k_cfg80211_change_iface,
1466     .add_virtual_intf = ar6k_cfg80211_add_virtual_intf,
1467     .del_virtual_intf = ar6k_cfg80211_del_virtual_intf,
1468     .scan = ar6k_cfg80211_scan,
1469     .connect = ar6k_cfg80211_connect,
1470     .disconnect = ar6k_cfg80211_disconnect,
1471     .add_key = ar6k_cfg80211_add_key,
1472     .get_key = ar6k_cfg80211_get_key,
1473     .del_key = ar6k_cfg80211_del_key,
1474     .set_default_key = ar6k_cfg80211_set_default_key,
1475     .set_default_mgmt_key = ar6k_cfg80211_set_default_mgmt_key,
1476     .set_wiphy_params = ar6k_cfg80211_set_wiphy_params,
1477     .set_bitrate_mask = ar6k_cfg80211_set_bitrate_mask,
1478     .set_tx_power = ar6k_cfg80211_set_txpower,
1479     .get_tx_power = ar6k_cfg80211_get_txpower,
1480     .set_power_mgmt = ar6k_cfg80211_set_power_mgmt,
1481     .join_ibss = ar6k_cfg80211_join_ibss,
1482     .leave_ibss = ar6k_cfg80211_leave_ibss,
1483 };
1484
1485 struct wireless_dev *
1486 ar6k_cfg80211_init(struct device *dev)
1487 {
1488     int ret = 0;
1489     struct wireless_dev *wdev;
1490
1491     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1492
1493     wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
1494     if(!wdev) {
1495         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1496                         ("%s: Couldn't allocate wireless device\n", __func__));
1497         return ERR_PTR(-ENOMEM);
1498     }
1499
1500     /* create a new wiphy for use with cfg80211 */
1501     wdev->wiphy = wiphy_new(&ar6k_cfg80211_ops, sizeof(struct ar6_softc));
1502     if(!wdev->wiphy) {
1503         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1504                         ("%s: Couldn't allocate wiphy device\n", __func__));
1505         kfree(wdev);
1506         return ERR_PTR(-ENOMEM);
1507     }
1508
1509     /* set device pointer for wiphy */
1510     set_wiphy_dev(wdev->wiphy, dev);
1511
1512     wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1513                                    BIT(NL80211_IFTYPE_ADHOC);
1514     /* max num of ssids that can be probed during scanning */
1515     wdev->wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
1516     wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar6k_band_2ghz;
1517     wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar6k_band_5ghz;
1518     wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
1519
1520     wdev->wiphy->cipher_suites = cipher_suites;
1521     wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
1522
1523     ret = wiphy_register(wdev->wiphy);
1524     if(ret < 0) {
1525         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1526                         ("%s: Couldn't register wiphy device\n", __func__));
1527         wiphy_free(wdev->wiphy);
1528         return ERR_PTR(ret);
1529     }
1530
1531     return wdev;
1532 }
1533
1534 void
1535 ar6k_cfg80211_deinit(struct ar6_softc *ar)
1536 {
1537     struct wireless_dev *wdev = ar->wdev;
1538
1539     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1540
1541     if(ar->scan_request) {
1542         cfg80211_scan_done(ar->scan_request, true);
1543         ar->scan_request = NULL;
1544     }
1545
1546     if(!wdev)
1547         return;
1548
1549     wiphy_unregister(wdev->wiphy);
1550     wiphy_free(wdev->wiphy);
1551     kfree(wdev);
1552 }
1553
1554
1555
1556
1557
1558
1559