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