Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6.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             cfg80211_put_bss(bss);
549             return;
550     }
551
552     A_MEMZERO(ieeemgmtbuf, size);
553     mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
554     mgmt->frame_control = (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
555     memcpy(mgmt->da, bcast_mac, ATH_MAC_LEN);
556     memcpy(mgmt->sa, source_mac, ATH_MAC_LEN);
557     memcpy(mgmt->bssid, bssid, ATH_MAC_LEN);
558     mgmt->u.beacon.beacon_int = beaconInterval;
559     mgmt->u.beacon.capab_info = capability;
560     memcpy(mgmt->u.beacon.variable, ptr_ie_buf, ie_buf_len);
561
562     ibss_channel = ieee80211_get_channel(ar->wdev->wiphy, (int)channel);
563
564     AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
565                     ("%s: inform bss with bssid %pM channel %d beaconInterval %d "
566                      "capability 0x%x\n", __func__, mgmt->bssid,
567                      ibss_channel->hw_value, beaconInterval, capability));
568
569     bss = cfg80211_inform_bss_frame(ar->wdev->wiphy,
570                                     ibss_channel, mgmt,
571                                     le16_to_cpu(size),
572                                     signal, GFP_KERNEL);
573     kfree(ieeemgmtbuf);
574     cfg80211_put_bss(bss);
575
576     if((ADHOC_NETWORK & networkType)) {
577         cfg80211_ibss_joined(ar->arNetDev, bssid, GFP_KERNEL);
578         return;
579     }
580
581     if (false == ar->arConnected) {
582         /* inform connect result to cfg80211 */
583         ar->smeState = SME_DISCONNECTED;
584         cfg80211_connect_result(ar->arNetDev, bssid,
585                                 assocReqIe, assocReqLen,
586                                 assocRespIe, assocRespLen,
587                                 WLAN_STATUS_SUCCESS, GFP_KERNEL);
588     } else {
589         /* inform roam event to cfg80211 */
590         cfg80211_roamed(ar->arNetDev, ibss_channel, bssid,
591                         assocReqIe, assocReqLen,
592                         assocRespIe, assocRespLen,
593                         GFP_KERNEL);
594     }
595 }
596
597 static int
598 ar6k_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
599                         u16 reason_code)
600 {
601     struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
602
603     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason_code));
604
605     if(ar->arWmiReady == false) {
606         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
607         return -EIO;
608     }
609
610     if(ar->arWlanState == WLAN_DISABLED) {
611         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
612         return -EIO;
613     }
614
615     if(ar->bIsDestroyProgress) {
616         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, destroy in progress\n", __func__));
617         return -EBUSY;
618     }
619
620     if(down_interruptible(&ar->arSem)) {
621         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__));
622         return -ERESTARTSYS;
623     }
624
625     reconnect_flag = 0;
626     ar6000_disconnect(ar);
627     A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
628     ar->arSsidLen = 0;
629
630     if (ar->arSkipScan == false) {
631         A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
632     }
633
634     up(&ar->arSem);
635
636     return 0;
637 }
638
639 void
640 ar6k_cfg80211_disconnect_event(struct ar6_softc *ar, u8 reason,
641                                u8 *bssid, u8 assocRespLen,
642                                u8 *assocInfo, u16 protocolReasonStatus)
643 {
644
645     u16 status;
646
647     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason));
648
649     if (ar->scan_request) {
650         cfg80211_scan_done(ar->scan_request, true);
651         ar->scan_request = NULL;
652     }
653     if((ADHOC_NETWORK & ar->arNetworkType)) {
654         if(NL80211_IFTYPE_ADHOC != ar->wdev->iftype) {
655             AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
656                             ("%s: ath6k not in ibss mode\n", __func__));
657             return;
658         }
659         A_MEMZERO(bssid, ETH_ALEN);
660         cfg80211_ibss_joined(ar->arNetDev, bssid, GFP_KERNEL);
661         return;
662     }
663
664     if((INFRA_NETWORK & ar->arNetworkType)) {
665         if(NL80211_IFTYPE_STATION != ar->wdev->iftype) {
666             AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
667                             ("%s: ath6k not in station mode\n", __func__));
668             return;
669         }
670     }
671
672     if(true == ar->arConnectPending) {
673         if(NO_NETWORK_AVAIL == reason) {
674             /* connect cmd failed */
675             wmi_disconnect_cmd(ar->arWmi);
676         } else if (reason == DISCONNECT_CMD) {
677                 if (ar->arAutoAuthStage) {
678                         /*
679                          * If the current auth algorithm is open try shared
680                          * and make autoAuthStage idle. We do not make it
681                          * leap for now being.
682                          */
683                         if (ar->arDot11AuthMode == OPEN_AUTH) {
684                                 struct ar_key *key = NULL;
685                                 key = &ar->keys[ar->arDefTxKeyIndex];
686                                 if (down_interruptible(&ar->arSem)) {
687                                         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__));
688                                         return;
689                                 }
690
691
692                                 ar->arDot11AuthMode = SHARED_AUTH;
693                                 ar->arAutoAuthStage = AUTH_IDLE;
694
695                                 wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex,
696                                                 ar->arPairwiseCrypto,
697                                                 GROUP_USAGE | TX_USAGE,
698                                                 key->key_len,
699                                                 NULL,
700                                                 key->key, KEY_OP_INIT_VAL, NULL,
701                                                 NO_SYNC_WMIFLAG);
702
703                                 status = wmi_connect_cmd(ar->arWmi,
704                                                          ar->arNetworkType,
705                                                          ar->arDot11AuthMode,
706                                                          ar->arAuthMode,
707                                                          ar->arPairwiseCrypto,
708                                                          ar->arPairwiseCryptoLen,
709                                                          ar->arGroupCrypto,
710                                                          ar->arGroupCryptoLen,
711                                                          ar->arSsidLen,
712                                                          ar->arSsid,
713                                                          ar->arReqBssid,
714                                                          ar->arChannelHint,
715                                                          ar->arConnectCtrlFlags);
716                                 up(&ar->arSem);
717
718                         } else if (ar->arDot11AuthMode == SHARED_AUTH) {
719                                 /* should not reach here */
720                         }
721                 } else {
722                         ar->arConnectPending = false;
723                         if (ar->smeState == SME_CONNECTING) {
724                                 cfg80211_connect_result(ar->arNetDev, bssid,
725                                                         NULL, 0,
726                                                         NULL, 0,
727                                                         WLAN_STATUS_UNSPECIFIED_FAILURE,
728                                                         GFP_KERNEL);
729                         } else {
730                                 cfg80211_disconnected(ar->arNetDev,
731                                                       reason,
732                                                       NULL, 0,
733                                                       GFP_KERNEL);
734                         }
735                         ar->smeState = SME_DISCONNECTED;
736                 }
737         }
738     } else {
739             if (reason != DISCONNECT_CMD)
740                     wmi_disconnect_cmd(ar->arWmi);
741     }
742 }
743
744 void
745 ar6k_cfg80211_scan_node(void *arg, bss_t *ni)
746 {
747     struct wiphy *wiphy = (struct wiphy *)arg;
748     u16 size;
749     unsigned char *ieeemgmtbuf = NULL;
750     struct ieee80211_mgmt *mgmt;
751     struct ieee80211_channel *channel;
752     struct ieee80211_supported_band *band;
753     struct ieee80211_common_ie  *cie;
754     s32 signal;
755     int freq;
756
757     cie = &ni->ni_cie;
758
759 #define CHAN_IS_11A(x)  (!((x >= 2412) && (x <= 2484)))
760     if(CHAN_IS_11A(cie->ie_chan)) {
761         /* 11a */
762         band = wiphy->bands[IEEE80211_BAND_5GHZ];
763     } else if((cie->ie_erp) || (cie->ie_xrates)) {
764         /* 11g */
765         band = wiphy->bands[IEEE80211_BAND_2GHZ];
766     } else {
767         /* 11b */
768         band = wiphy->bands[IEEE80211_BAND_2GHZ];
769     }
770
771     size = ni->ni_framelen + offsetof(struct ieee80211_mgmt, u);
772     ieeemgmtbuf = A_MALLOC_NOWAIT(size);
773     if(!ieeemgmtbuf)
774     {
775         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ieeeMgmtbuf alloc error\n", __func__));
776         return;
777     }
778
779     /* Note:
780        TODO: Update target to include 802.11 mac header while sending bss info.
781        Target removes 802.11 mac header while sending the bss info to host,
782        cfg80211 needs it, for time being just filling the da, sa and bssid fields alone.
783     */
784     mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
785     memcpy(mgmt->da, bcast_mac, ATH_MAC_LEN);
786     memcpy(mgmt->sa, ni->ni_macaddr, ATH_MAC_LEN);
787     memcpy(mgmt->bssid, ni->ni_macaddr, ATH_MAC_LEN);
788     memcpy(ieeemgmtbuf + offsetof(struct ieee80211_mgmt, u),
789              ni->ni_buf, ni->ni_framelen);
790
791     freq    = cie->ie_chan;
792     channel = ieee80211_get_channel(wiphy, freq);
793     signal  = ni->ni_snr * 100;
794
795         AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
796                 ("%s: bssid %pM channel %d freq %d size %d\n", __func__,
797                         mgmt->bssid, channel->hw_value, freq, size));
798     cfg80211_inform_bss_frame(wiphy, channel, mgmt,
799                               le16_to_cpu(size),
800                               signal, GFP_KERNEL);
801
802     kfree (ieeemgmtbuf);
803 }
804
805 static int
806 ar6k_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
807                    struct cfg80211_scan_request *request)
808 {
809     struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
810     int ret = 0;
811     u32 forceFgScan = 0;
812
813     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
814
815     if(ar->arWmiReady == false) {
816         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
817         return -EIO;
818     }
819
820     if(ar->arWlanState == WLAN_DISABLED) {
821         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
822         return -EIO;
823     }
824
825     if (!ar->arUserBssFilter) {
826         if (wmi_bssfilter_cmd(ar->arWmi,
827                              (ar->arConnected ? ALL_BUT_BSS_FILTER : ALL_BSS_FILTER),
828                              0) != 0) {
829             AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Couldn't set bss filtering\n", __func__));
830             return -EIO;
831         }
832     }
833
834     if(request->n_ssids &&
835        request->ssids[0].ssid_len) {
836         u8 i;
837
838         if(request->n_ssids > (MAX_PROBED_SSID_INDEX - 1)) {
839             request->n_ssids = MAX_PROBED_SSID_INDEX - 1;
840         }
841
842         for (i = 0; i < request->n_ssids; i++) {
843             wmi_probedSsid_cmd(ar->arWmi, i+1, SPECIFIC_SSID_FLAG,
844                                request->ssids[i].ssid_len,
845                                request->ssids[i].ssid);
846         }
847     }
848
849     if(ar->arConnected) {
850         forceFgScan = 1;
851     }
852
853     if(wmi_startscan_cmd(ar->arWmi, WMI_LONG_SCAN, forceFgScan, false, \
854                          0, 0, 0, NULL) != 0) {
855         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_startscan_cmd failed\n", __func__));
856         ret = -EIO;
857     }
858
859     ar->scan_request = request;
860
861     return ret;
862 }
863
864 void
865 ar6k_cfg80211_scanComplete_event(struct ar6_softc *ar, int status)
866 {
867
868     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: status %d\n", __func__, status));
869
870     if(ar->scan_request)
871     {
872         /* Translate data to cfg80211 mgmt format */
873         wmi_iterate_nodes(ar->arWmi, ar6k_cfg80211_scan_node, ar->wdev->wiphy);
874
875         cfg80211_scan_done(ar->scan_request,
876             ((status & A_ECANCELED) || (status & A_EBUSY)) ? true : false);
877
878         if(ar->scan_request->n_ssids &&
879            ar->scan_request->ssids[0].ssid_len) {
880             u8 i;
881
882             for (i = 0; i < ar->scan_request->n_ssids; i++) {
883                 wmi_probedSsid_cmd(ar->arWmi, i+1, DISABLE_SSID_FLAG,
884                                    0, NULL);
885             }
886         }
887         ar->scan_request = NULL;
888     }
889 }
890
891 static int
892 ar6k_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
893                       u8 key_index, bool pairwise, const u8 *mac_addr,
894                       struct key_params *params)
895 {
896     struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
897     struct ar_key *key = NULL;
898     u8 key_usage;
899     u8 key_type;
900     int status = 0;
901
902     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s:\n", __func__));
903
904     if(ar->arWmiReady == false) {
905         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
906         return -EIO;
907     }
908
909     if(ar->arWlanState == WLAN_DISABLED) {
910         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
911         return -EIO;
912     }
913
914     if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
915         AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
916                         ("%s: key index %d out of bounds\n", __func__, key_index));
917         return -ENOENT;
918     }
919
920     key = &ar->keys[key_index];
921     A_MEMZERO(key, sizeof(struct ar_key));
922
923     if(!mac_addr || is_broadcast_ether_addr(mac_addr)) {
924         key_usage = GROUP_USAGE;
925     } else {
926         key_usage = PAIRWISE_USAGE;
927     }
928
929     if(params) {
930         if(params->key_len > WLAN_MAX_KEY_LEN ||
931             params->seq_len > IW_ENCODE_SEQ_MAX_SIZE)
932             return -EINVAL;
933
934         key->key_len = params->key_len;
935         memcpy(key->key, params->key, key->key_len);
936         key->seq_len = params->seq_len;
937         memcpy(key->seq, params->seq, key->seq_len);
938         key->cipher = params->cipher;
939     }
940
941     switch (key->cipher) {
942     case WLAN_CIPHER_SUITE_WEP40:
943     case WLAN_CIPHER_SUITE_WEP104:
944         key_type = WEP_CRYPT;
945         break;
946
947     case WLAN_CIPHER_SUITE_TKIP:
948         key_type = TKIP_CRYPT;
949         break;
950
951     case WLAN_CIPHER_SUITE_CCMP:
952         key_type = AES_CRYPT;
953         break;
954
955     default:
956         return -ENOTSUPP;
957     }
958
959     if (((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)) &&
960         (GROUP_USAGE & key_usage))
961     {
962         A_UNTIMEOUT(&ar->disconnect_timer);
963     }
964
965     AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
966                     ("%s: index %d, key_len %d, key_type 0x%x,"\
967                     " key_usage 0x%x, seq_len %d\n",
968                     __func__, key_index, key->key_len, key_type,
969                     key_usage, key->seq_len));
970
971     ar->arDefTxKeyIndex = key_index;
972     status = wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex, key_type, key_usage,
973                     key->key_len, key->seq, key->key, KEY_OP_INIT_VAL,
974                     (u8 *)mac_addr, SYNC_BOTH_WMIFLAG);
975
976
977     if (status) {
978         return -EIO;
979     }
980
981     return 0;
982 }
983
984 static int
985 ar6k_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
986                       u8 key_index, bool pairwise, const u8 *mac_addr)
987 {
988     struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
989
990     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
991
992     if(ar->arWmiReady == false) {
993         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
994         return -EIO;
995     }
996
997     if(ar->arWlanState == WLAN_DISABLED) {
998         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
999         return -EIO;
1000     }
1001
1002     if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1003         AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
1004                         ("%s: key index %d out of bounds\n", __func__, key_index));
1005         return -ENOENT;
1006     }
1007
1008     if(!ar->keys[key_index].key_len) {
1009         AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d is empty\n", __func__, key_index));
1010         return 0;
1011     }
1012
1013     ar->keys[key_index].key_len = 0;
1014
1015     return wmi_deleteKey_cmd(ar->arWmi, key_index);
1016 }
1017
1018
1019 static int
1020 ar6k_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1021                       u8 key_index, bool pairwise, const u8 *mac_addr,
1022                       void *cookie,
1023                       void (*callback)(void *cookie, struct key_params*))
1024 {
1025     struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
1026     struct ar_key *key = NULL;
1027     struct key_params params;
1028
1029     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
1030
1031     if(ar->arWmiReady == false) {
1032         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1033         return -EIO;
1034     }
1035
1036     if(ar->arWlanState == WLAN_DISABLED) {
1037         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1038         return -EIO;
1039     }
1040
1041     if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1042         AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
1043                         ("%s: key index %d out of bounds\n", __func__, key_index));
1044         return -ENOENT;
1045     }
1046
1047     key = &ar->keys[key_index];
1048     A_MEMZERO(&params, sizeof(params));
1049     params.cipher = key->cipher;
1050     params.key_len = key->key_len;
1051     params.seq_len = key->seq_len;
1052     params.seq = key->seq;
1053     params.key = key->key;
1054
1055     callback(cookie, &params);
1056
1057     return key->key_len ? 0 : -ENOENT;
1058 }
1059
1060
1061 static int
1062 ar6k_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev,
1063                               u8 key_index, bool unicast, bool multicast)
1064 {
1065     struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
1066     struct ar_key *key = NULL;
1067     int status = 0;
1068     u8 key_usage;
1069
1070     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
1071
1072     if(ar->arWmiReady == false) {
1073         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1074         return -EIO;
1075     }
1076
1077     if(ar->arWlanState == WLAN_DISABLED) {
1078         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1079         return -EIO;
1080     }
1081
1082     if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1083         AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
1084                         ("%s: key index %d out of bounds\n",
1085                         __func__, key_index));
1086         return -ENOENT;
1087     }
1088
1089     if(!ar->keys[key_index].key_len) {
1090         AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: invalid key index %d\n",
1091                         __func__, key_index));
1092         return -EINVAL;
1093     }
1094
1095     ar->arDefTxKeyIndex = key_index;
1096     key = &ar->keys[ar->arDefTxKeyIndex];
1097     key_usage = GROUP_USAGE;
1098     if (WEP_CRYPT == ar->arPairwiseCrypto) {
1099         key_usage |= TX_USAGE;
1100     }
1101
1102     status = wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex,
1103                             ar->arPairwiseCrypto, key_usage,
1104                             key->key_len, key->seq, key->key, KEY_OP_INIT_VAL,
1105                             NULL, SYNC_BOTH_WMIFLAG);
1106     if (status) {
1107         return -EIO;
1108     }
1109
1110     return 0;
1111 }
1112
1113 static int
1114 ar6k_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *ndev,
1115                                    u8 key_index)
1116 {
1117     struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
1118
1119     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
1120
1121     if(ar->arWmiReady == false) {
1122         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1123         return -EIO;
1124     }
1125
1126     if(ar->arWlanState == WLAN_DISABLED) {
1127         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1128         return -EIO;
1129     }
1130
1131     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
1132     return -ENOTSUPP;
1133 }
1134
1135 void
1136 ar6k_cfg80211_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast)
1137 {
1138     AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
1139                     ("%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast));
1140
1141     cfg80211_michael_mic_failure(ar->arNetDev, ar->arBssid,
1142                                  (ismcast ? NL80211_KEYTYPE_GROUP : NL80211_KEYTYPE_PAIRWISE),
1143                                  keyid, NULL, GFP_KERNEL);
1144 }
1145
1146 static int
1147 ar6k_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1148 {
1149     struct ar6_softc *ar = (struct ar6_softc *)wiphy_priv(wiphy);
1150
1151     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: changed 0x%x\n", __func__, changed));
1152
1153     if(ar->arWmiReady == false) {
1154         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1155         return -EIO;
1156     }
1157
1158     if(ar->arWlanState == WLAN_DISABLED) {
1159         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1160         return -EIO;
1161     }
1162
1163     if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1164         if (wmi_set_rts_cmd(ar->arWmi,wiphy->rts_threshold) != 0){
1165             AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_set_rts_cmd failed\n", __func__));
1166             return -EIO;
1167         }
1168     }
1169
1170     return 0;
1171 }
1172
1173 static int
1174 ar6k_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
1175                                const u8 *peer,
1176                                const struct cfg80211_bitrate_mask *mask)
1177 {
1178     AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Setting rates: Not supported\n"));
1179     return -EIO;
1180 }
1181
1182 /* The type nl80211_tx_power_setting replaces the following data type from 2.6.36 onwards */
1183 static int
1184 ar6k_cfg80211_set_txpower(struct wiphy *wiphy, enum nl80211_tx_power_setting type, int dbm)
1185 {
1186     struct ar6_softc *ar = (struct ar6_softc *)wiphy_priv(wiphy);
1187     u8 ar_dbm;
1188
1189     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x, dbm %d\n", __func__, type, dbm));
1190
1191     if(ar->arWmiReady == false) {
1192         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1193         return -EIO;
1194     }
1195
1196     if(ar->arWlanState == WLAN_DISABLED) {
1197         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1198         return -EIO;
1199     }
1200
1201     ar->arTxPwrSet = false;
1202     switch(type) {
1203     case NL80211_TX_POWER_AUTOMATIC:
1204         return 0;
1205     case NL80211_TX_POWER_LIMITED:
1206         ar->arTxPwr = ar_dbm = dbm;
1207         ar->arTxPwrSet = true;
1208         break;
1209     default:
1210         AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x not supported\n", __func__, type));
1211         return -EOPNOTSUPP;
1212     }
1213
1214     wmi_set_txPwr_cmd(ar->arWmi, ar_dbm);
1215
1216     return 0;
1217 }
1218
1219 static int
1220 ar6k_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
1221 {
1222     struct ar6_softc *ar = (struct ar6_softc *)wiphy_priv(wiphy);
1223
1224     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1225
1226     if(ar->arWmiReady == false) {
1227         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1228         return -EIO;
1229     }
1230
1231     if(ar->arWlanState == WLAN_DISABLED) {
1232         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1233         return -EIO;
1234     }
1235
1236     if((ar->arConnected == true)) {
1237         ar->arTxPwr = 0;
1238
1239         if(wmi_get_txPwr_cmd(ar->arWmi) != 0) {
1240             AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_get_txPwr_cmd failed\n", __func__));
1241             return -EIO;
1242         }
1243
1244         wait_event_interruptible_timeout(arEvent, ar->arTxPwr != 0, 5 * HZ);
1245
1246         if(signal_pending(current)) {
1247             AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Target did not respond\n", __func__));
1248             return -EINTR;
1249         }
1250     }
1251
1252     *dbm = ar->arTxPwr;
1253     return 0;
1254 }
1255
1256 static int
1257 ar6k_cfg80211_set_power_mgmt(struct wiphy *wiphy,
1258                              struct net_device *dev,
1259                              bool pmgmt, int timeout)
1260 {
1261     struct ar6_softc *ar = ar6k_priv(dev);
1262     WMI_POWER_MODE_CMD pwrMode;
1263
1264     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: pmgmt %d, timeout %d\n", __func__, pmgmt, timeout));
1265
1266     if(ar->arWmiReady == false) {
1267         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1268         return -EIO;
1269     }
1270
1271     if(ar->arWlanState == WLAN_DISABLED) {
1272         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1273         return -EIO;
1274     }
1275
1276     if(pmgmt) {
1277         AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Max Perf\n", __func__));
1278         pwrMode.powerMode = REC_POWER;
1279     } else {
1280         AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Rec Power\n", __func__));
1281         pwrMode.powerMode = MAX_PERF_POWER;
1282     }
1283
1284     if(wmi_powermode_cmd(ar->arWmi, pwrMode.powerMode) != 0) {
1285         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_powermode_cmd failed\n", __func__));
1286         return -EIO;
1287     }
1288
1289     return 0;
1290 }
1291
1292 static struct net_device *
1293 ar6k_cfg80211_add_virtual_intf(struct wiphy *wiphy, char *name,
1294                                             enum nl80211_iftype type, u32 *flags,
1295                                             struct vif_params *params)
1296 {
1297
1298     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
1299
1300     /* Multiple virtual interface is not supported.
1301      * The default interface supports STA and IBSS type
1302      */
1303     return ERR_PTR(-EOPNOTSUPP);
1304 }
1305
1306 static int
1307 ar6k_cfg80211_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev)
1308 {
1309
1310     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
1311
1312     /* Multiple virtual interface is not supported.
1313      * The default interface supports STA and IBSS type
1314      */
1315     return -EOPNOTSUPP;
1316 }
1317
1318 static int
1319 ar6k_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
1320                            enum nl80211_iftype type, u32 *flags,
1321                            struct vif_params *params)
1322 {
1323     struct ar6_softc *ar = ar6k_priv(ndev);
1324     struct wireless_dev *wdev = ar->wdev;
1325
1326     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type %u\n", __func__, type));
1327
1328     if(ar->arWmiReady == false) {
1329         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1330         return -EIO;
1331     }
1332
1333     if(ar->arWlanState == WLAN_DISABLED) {
1334         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1335         return -EIO;
1336     }
1337
1338     switch (type) {
1339     case NL80211_IFTYPE_STATION:
1340         ar->arNextMode = INFRA_NETWORK;
1341         break;
1342     case NL80211_IFTYPE_ADHOC:
1343         ar->arNextMode = ADHOC_NETWORK;
1344         break;
1345     default:
1346         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: type %u\n", __func__, type));
1347         return -EOPNOTSUPP;
1348     }
1349
1350     wdev->iftype = type;
1351
1352     return 0;
1353 }
1354
1355 static int
1356 ar6k_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1357                         struct cfg80211_ibss_params *ibss_param)
1358 {
1359     struct ar6_softc *ar = ar6k_priv(dev);
1360     int status;
1361
1362     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1363
1364     if(ar->arWmiReady == false) {
1365         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1366         return -EIO;
1367     }
1368
1369     if(ar->arWlanState == WLAN_DISABLED) {
1370         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1371         return -EIO;
1372     }
1373
1374     if(!ibss_param->ssid_len || IEEE80211_MAX_SSID_LEN < ibss_param->ssid_len) {
1375         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ssid invalid\n", __func__));
1376         return -EINVAL;
1377     }
1378
1379     ar->arSsidLen = ibss_param->ssid_len;
1380     memcpy(ar->arSsid, ibss_param->ssid, ar->arSsidLen);
1381
1382     if(ibss_param->channel) {
1383         ar->arChannelHint = ibss_param->channel->center_freq;
1384     }
1385
1386     if(ibss_param->channel_fixed) {
1387         /* TODO: channel_fixed: The channel should be fixed, do not search for
1388          * IBSSs to join on other channels. Target firmware does not support this
1389          * feature, needs to be updated.*/
1390     }
1391
1392     A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
1393     if(ibss_param->bssid) {
1394         if(memcmp(&ibss_param->bssid, bcast_mac, AR6000_ETH_ADDR_LEN)) {
1395             memcpy(ar->arReqBssid, ibss_param->bssid, sizeof(ar->arReqBssid));
1396         }
1397     }
1398
1399     ar6k_set_wpa_version(ar, 0);
1400     ar6k_set_auth_type(ar, NL80211_AUTHTYPE_OPEN_SYSTEM);
1401
1402     if(ibss_param->privacy) {
1403         ar6k_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, true);
1404         ar6k_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, false);
1405     } else {
1406         ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, true);
1407         ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, false);
1408     }
1409
1410     ar->arNetworkType = ar->arNextMode;
1411
1412     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Connect called with authmode %d dot11 auth %d"\
1413                     " PW crypto %d PW crypto Len %d GRP crypto %d"\
1414                     " GRP crypto Len %d channel hint %u\n",
1415                     __func__, ar->arAuthMode, ar->arDot11AuthMode,
1416                     ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
1417                     ar->arGroupCrypto, ar->arGroupCryptoLen, ar->arChannelHint));
1418
1419     status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType,
1420                             ar->arDot11AuthMode, ar->arAuthMode,
1421                             ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
1422                             ar->arGroupCrypto,ar->arGroupCryptoLen,
1423                             ar->arSsidLen, ar->arSsid,
1424                             ar->arReqBssid, ar->arChannelHint,
1425                             ar->arConnectCtrlFlags);
1426     ar->arConnectPending = true;
1427
1428     return 0;
1429 }
1430
1431 static int
1432 ar6k_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1433 {
1434     struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
1435
1436     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1437
1438     if(ar->arWmiReady == false) {
1439         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1440         return -EIO;
1441     }
1442
1443     if(ar->arWlanState == WLAN_DISABLED) {
1444         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1445         return -EIO;
1446     }
1447
1448     ar6000_disconnect(ar);
1449     A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
1450     ar->arSsidLen = 0;
1451
1452     return 0;
1453 }
1454
1455
1456 static const
1457 u32 cipher_suites[] = {
1458     WLAN_CIPHER_SUITE_WEP40,
1459     WLAN_CIPHER_SUITE_WEP104,
1460     WLAN_CIPHER_SUITE_TKIP,
1461     WLAN_CIPHER_SUITE_CCMP,
1462 };
1463
1464 bool is_rate_legacy(s32 rate)
1465 {
1466         static const s32 legacy[] = { 1000, 2000, 5500, 11000,
1467                                       6000, 9000, 12000, 18000, 24000,
1468                                       36000, 48000, 54000 };
1469         u8 i;
1470
1471         for (i = 0; i < ARRAY_SIZE(legacy); i++) {
1472                 if (rate == legacy[i])
1473                         return true;
1474         }
1475
1476         return false;
1477 }
1478
1479 bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi)
1480 {
1481         static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000,
1482                                     52000, 58500, 65000, 72200 };
1483         u8 i;
1484
1485         for (i = 0; i < ARRAY_SIZE(ht20); i++) {
1486                 if (rate == ht20[i]) {
1487                         if (i == ARRAY_SIZE(ht20) - 1)
1488                                 /* last rate uses sgi */
1489                                 *sgi = true;
1490                         else
1491                                 *sgi = false;
1492
1493                         *mcs = i;
1494                         return true;
1495                 }
1496         }
1497         return false;
1498 }
1499
1500 bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi)
1501 {
1502         static const s32 ht40[] = { 13500, 27000, 40500, 54000,
1503                                     81000, 108000, 121500, 135000,
1504                                     150000 };
1505         u8 i;
1506
1507         for (i = 0; i < ARRAY_SIZE(ht40); i++) {
1508                 if (rate == ht40[i]) {
1509                         if (i == ARRAY_SIZE(ht40) - 1)
1510                                 /* last rate uses sgi */
1511                                 *sgi = true;
1512                         else
1513                                 *sgi = false;
1514
1515                         *mcs = i;
1516                         return true;
1517                 }
1518         }
1519
1520         return false;
1521 }
1522
1523 static int ar6k_get_station(struct wiphy *wiphy, struct net_device *dev,
1524                             u8 *mac, struct station_info *sinfo)
1525 {
1526         struct ar6_softc *ar = ar6k_priv(dev);
1527         long left;
1528         bool sgi;
1529         s32 rate;
1530         int ret;
1531         u8 mcs;
1532
1533         if (memcmp(mac, ar->arBssid, ETH_ALEN) != 0)
1534                 return -ENOENT;
1535
1536         if (down_interruptible(&ar->arSem))
1537                 return -EBUSY;
1538
1539         ar->statsUpdatePending = true;
1540
1541         ret = wmi_get_stats_cmd(ar->arWmi);
1542
1543         if (ret != 0) {
1544                 up(&ar->arSem);
1545                 return -EIO;
1546         }
1547
1548         left = wait_event_interruptible_timeout(arEvent,
1549                                                 ar->statsUpdatePending == false,
1550                                                 wmitimeout * HZ);
1551
1552         up(&ar->arSem);
1553
1554         if (left == 0)
1555                 return -ETIMEDOUT;
1556         else if (left < 0)
1557                 return left;
1558
1559         if (ar->arTargetStats.rx_bytes) {
1560                 sinfo->rx_bytes = ar->arTargetStats.rx_bytes;
1561                 sinfo->filled |= STATION_INFO_RX_BYTES;
1562                 sinfo->rx_packets = ar->arTargetStats.rx_packets;
1563                 sinfo->filled |= STATION_INFO_RX_PACKETS;
1564         }
1565
1566         if (ar->arTargetStats.tx_bytes) {
1567                 sinfo->tx_bytes = ar->arTargetStats.tx_bytes;
1568                 sinfo->filled |= STATION_INFO_TX_BYTES;
1569                 sinfo->tx_packets = ar->arTargetStats.tx_packets;
1570                 sinfo->filled |= STATION_INFO_TX_PACKETS;
1571         }
1572
1573         sinfo->signal = ar->arTargetStats.cs_rssi;
1574         sinfo->filled |= STATION_INFO_SIGNAL;
1575
1576         rate = ar->arTargetStats.tx_unicast_rate;
1577
1578         if (is_rate_legacy(rate)) {
1579                 sinfo->txrate.legacy = rate / 100;
1580         } else if (is_rate_ht20(rate, &mcs, &sgi)) {
1581                 if (sgi) {
1582                         sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1583                         sinfo->txrate.mcs = mcs - 1;
1584                 } else {
1585                         sinfo->txrate.mcs = mcs;
1586                 }
1587
1588                 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1589         } else if (is_rate_ht40(rate, &mcs, &sgi)) {
1590                 if (sgi) {
1591                         sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1592                         sinfo->txrate.mcs = mcs - 1;
1593                 } else {
1594                         sinfo->txrate.mcs = mcs;
1595                 }
1596
1597                 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
1598                 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1599         } else {
1600                 WARN(1, "invalid rate: %d", rate);
1601                 return 0;
1602         }
1603
1604         sinfo->filled |= STATION_INFO_TX_BITRATE;
1605
1606         return 0;
1607 }
1608
1609 static struct
1610 cfg80211_ops ar6k_cfg80211_ops = {
1611     .change_virtual_intf = ar6k_cfg80211_change_iface,
1612     .add_virtual_intf = ar6k_cfg80211_add_virtual_intf,
1613     .del_virtual_intf = ar6k_cfg80211_del_virtual_intf,
1614     .scan = ar6k_cfg80211_scan,
1615     .connect = ar6k_cfg80211_connect,
1616     .disconnect = ar6k_cfg80211_disconnect,
1617     .add_key = ar6k_cfg80211_add_key,
1618     .get_key = ar6k_cfg80211_get_key,
1619     .del_key = ar6k_cfg80211_del_key,
1620     .set_default_key = ar6k_cfg80211_set_default_key,
1621     .set_default_mgmt_key = ar6k_cfg80211_set_default_mgmt_key,
1622     .set_wiphy_params = ar6k_cfg80211_set_wiphy_params,
1623     .set_bitrate_mask = ar6k_cfg80211_set_bitrate_mask,
1624     .set_tx_power = ar6k_cfg80211_set_txpower,
1625     .get_tx_power = ar6k_cfg80211_get_txpower,
1626     .set_power_mgmt = ar6k_cfg80211_set_power_mgmt,
1627     .join_ibss = ar6k_cfg80211_join_ibss,
1628     .leave_ibss = ar6k_cfg80211_leave_ibss,
1629     .get_station = ar6k_get_station,
1630 };
1631
1632 struct wireless_dev *
1633 ar6k_cfg80211_init(struct device *dev)
1634 {
1635     int ret = 0;
1636     struct wireless_dev *wdev;
1637
1638     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1639
1640     wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
1641     if(!wdev) {
1642         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1643                         ("%s: Couldn't allocate wireless device\n", __func__));
1644         return ERR_PTR(-ENOMEM);
1645     }
1646
1647     /* create a new wiphy for use with cfg80211 */
1648     wdev->wiphy = wiphy_new(&ar6k_cfg80211_ops, sizeof(struct ar6_softc));
1649     if(!wdev->wiphy) {
1650         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1651                         ("%s: Couldn't allocate wiphy device\n", __func__));
1652         kfree(wdev);
1653         return ERR_PTR(-ENOMEM);
1654     }
1655
1656     /* set device pointer for wiphy */
1657     set_wiphy_dev(wdev->wiphy, dev);
1658
1659     wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1660                                    BIT(NL80211_IFTYPE_ADHOC);
1661     /* max num of ssids that can be probed during scanning */
1662     wdev->wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
1663     wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar6k_band_2ghz;
1664     wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar6k_band_5ghz;
1665     wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
1666
1667     wdev->wiphy->cipher_suites = cipher_suites;
1668     wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
1669
1670     ret = wiphy_register(wdev->wiphy);
1671     if(ret < 0) {
1672         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1673                         ("%s: Couldn't register wiphy device\n", __func__));
1674         wiphy_free(wdev->wiphy);
1675         return ERR_PTR(ret);
1676     }
1677
1678     return wdev;
1679 }
1680
1681 void
1682 ar6k_cfg80211_deinit(struct ar6_softc *ar)
1683 {
1684     struct wireless_dev *wdev = ar->wdev;
1685
1686     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1687
1688     if(ar->scan_request) {
1689         cfg80211_scan_done(ar->scan_request, true);
1690         ar->scan_request = NULL;
1691     }
1692
1693     if(!wdev)
1694         return;
1695
1696     wiphy_unregister(wdev->wiphy);
1697     wiphy_free(wdev->wiphy);
1698     kfree(wdev);
1699 }
1700
1701
1702
1703
1704
1705
1706