ath6kl: fix operations for power management
[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         kfree(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 (ar->scan_request) {
631         cfg80211_scan_done(ar->scan_request, true);
632         ar->scan_request = NULL;
633     }
634     if((ADHOC_NETWORK & ar->arNetworkType)) {
635         if(NL80211_IFTYPE_ADHOC != ar->wdev->iftype) {
636             AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
637                             ("%s: ath6k not in ibss mode\n", __func__));
638             return;
639         }
640         A_MEMZERO(bssid, ETH_ALEN);
641         cfg80211_ibss_joined(ar->arNetDev, bssid, GFP_KERNEL);
642         return;
643     }
644
645     if((INFRA_NETWORK & ar->arNetworkType)) {
646         if(NL80211_IFTYPE_STATION != ar->wdev->iftype) {
647             AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
648                             ("%s: ath6k not in station mode\n", __func__));
649             return;
650         }
651     }
652
653     if(true == ar->arConnectPending) {
654         if(NO_NETWORK_AVAIL == reason) {
655             /* connect cmd failed */
656             wmi_disconnect_cmd(ar->arWmi);
657         } else if (reason == DISCONNECT_CMD) {
658             /* connection loss due to disconnect cmd or low rssi */
659             ar->arConnectPending = false;   
660             if (ar->smeState == SME_CONNECTING) {
661                 cfg80211_connect_result(ar->arNetDev, bssid,
662                                         NULL, 0,
663                                         NULL, 0,
664                                         WLAN_STATUS_UNSPECIFIED_FAILURE,
665                                         GFP_KERNEL);
666             } else {
667                 cfg80211_disconnected(ar->arNetDev, reason, NULL, 0, GFP_KERNEL);
668             }
669             ar->smeState = SME_DISCONNECTED;
670         }
671     } else {
672         if (reason != DISCONNECT_CMD) {
673             wmi_disconnect_cmd(ar->arWmi);
674         }
675     }
676 }
677
678 void
679 ar6k_cfg80211_scan_node(void *arg, bss_t *ni)
680 {
681     struct wiphy *wiphy = (struct wiphy *)arg;
682     u16 size;
683     unsigned char *ieeemgmtbuf = NULL;
684     struct ieee80211_mgmt *mgmt;
685     struct ieee80211_channel *channel;
686     struct ieee80211_supported_band *band;
687     struct ieee80211_common_ie  *cie;
688     s32 signal;
689     int freq;
690
691     cie = &ni->ni_cie;
692
693 #define CHAN_IS_11A(x)  (!((x >= 2412) && (x <= 2484)))
694     if(CHAN_IS_11A(cie->ie_chan)) {
695         /* 11a */
696         band = wiphy->bands[IEEE80211_BAND_5GHZ];
697     } else if((cie->ie_erp) || (cie->ie_xrates)) {
698         /* 11g */
699         band = wiphy->bands[IEEE80211_BAND_2GHZ];
700     } else {
701         /* 11b */
702         band = wiphy->bands[IEEE80211_BAND_2GHZ];
703     }
704
705     size = ni->ni_framelen + offsetof(struct ieee80211_mgmt, u);
706     ieeemgmtbuf = A_MALLOC_NOWAIT(size);
707     if(!ieeemgmtbuf)
708     {
709         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ieeeMgmtbuf alloc error\n", __func__));
710         return;
711     }
712
713     /* Note:
714        TODO: Update target to include 802.11 mac header while sending bss info.
715        Target removes 802.11 mac header while sending the bss info to host,
716        cfg80211 needs it, for time being just filling the da, sa and bssid fields alone.
717     */
718     mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
719     memcpy(mgmt->da, bcast_mac, ATH_MAC_LEN);
720     memcpy(mgmt->sa, ni->ni_macaddr, ATH_MAC_LEN);
721     memcpy(mgmt->bssid, ni->ni_macaddr, ATH_MAC_LEN);
722     memcpy(ieeemgmtbuf + offsetof(struct ieee80211_mgmt, u),
723              ni->ni_buf, ni->ni_framelen);
724
725     freq    = cie->ie_chan;
726     channel = ieee80211_get_channel(wiphy, freq);
727     signal  = ni->ni_snr * 100;
728
729         AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
730                 ("%s: bssid %pM channel %d freq %d size %d\n", __func__,
731                         mgmt->bssid, channel->hw_value, freq, size));
732     cfg80211_inform_bss_frame(wiphy, channel, mgmt,
733                               le16_to_cpu(size),
734                               signal, GFP_KERNEL);
735
736     kfree (ieeemgmtbuf);
737 }
738
739 static int
740 ar6k_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
741                    struct cfg80211_scan_request *request)
742 {
743     struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
744     int ret = 0;
745     u32 forceFgScan = 0;
746
747     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
748
749     if(ar->arWmiReady == false) {
750         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
751         return -EIO;
752     }
753
754     if(ar->arWlanState == WLAN_DISABLED) {
755         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
756         return -EIO;
757     }
758
759     if (!ar->arUserBssFilter) {
760         if (wmi_bssfilter_cmd(ar->arWmi,
761                              (ar->arConnected ? ALL_BUT_BSS_FILTER : ALL_BSS_FILTER),
762                              0) != 0) {
763             AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Couldn't set bss filtering\n", __func__));
764             return -EIO;
765         }
766     }
767
768     if(request->n_ssids &&
769        request->ssids[0].ssid_len) {
770         u8 i;
771
772         if(request->n_ssids > (MAX_PROBED_SSID_INDEX - 1)) {
773             request->n_ssids = MAX_PROBED_SSID_INDEX - 1;
774         }
775
776         for (i = 0; i < request->n_ssids; i++) {
777             wmi_probedSsid_cmd(ar->arWmi, i+1, SPECIFIC_SSID_FLAG,
778                                request->ssids[i].ssid_len,
779                                request->ssids[i].ssid);
780         }
781     }
782
783     if(ar->arConnected) {
784         forceFgScan = 1;
785     }
786
787     if(wmi_startscan_cmd(ar->arWmi, WMI_LONG_SCAN, forceFgScan, false, \
788                          0, 0, 0, NULL) != 0) {
789         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_startscan_cmd failed\n", __func__));
790         ret = -EIO;
791     }
792
793     ar->scan_request = request;
794
795     return ret;
796 }
797
798 void
799 ar6k_cfg80211_scanComplete_event(struct ar6_softc *ar, int status)
800 {
801
802     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: status %d\n", __func__, status));
803
804     if(ar->scan_request)
805     {
806         /* Translate data to cfg80211 mgmt format */
807         wmi_iterate_nodes(ar->arWmi, ar6k_cfg80211_scan_node, ar->wdev->wiphy);
808
809         cfg80211_scan_done(ar->scan_request,
810             ((status & A_ECANCELED) || (status & A_EBUSY)) ? true : false);
811
812         if(ar->scan_request->n_ssids &&
813            ar->scan_request->ssids[0].ssid_len) {
814             u8 i;
815
816             for (i = 0; i < ar->scan_request->n_ssids; i++) {
817                 wmi_probedSsid_cmd(ar->arWmi, i+1, DISABLE_SSID_FLAG,
818                                    0, NULL);
819             }
820         }
821         ar->scan_request = NULL;
822     }
823 }
824
825 static int
826 ar6k_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
827                       u8 key_index, bool pairwise, const u8 *mac_addr,
828                       struct key_params *params)
829 {
830     struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
831     struct ar_key *key = NULL;
832     u8 key_usage;
833     u8 key_type;
834     int status = 0;
835
836     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s:\n", __func__));
837
838     if(ar->arWmiReady == false) {
839         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
840         return -EIO;
841     }
842
843     if(ar->arWlanState == WLAN_DISABLED) {
844         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
845         return -EIO;
846     }
847
848     if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
849         AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
850                         ("%s: key index %d out of bounds\n", __func__, key_index));
851         return -ENOENT;
852     }
853
854     key = &ar->keys[key_index];
855     A_MEMZERO(key, sizeof(struct ar_key));
856
857     if(!mac_addr || is_broadcast_ether_addr(mac_addr)) {
858         key_usage = GROUP_USAGE;
859     } else {
860         key_usage = PAIRWISE_USAGE;
861     }
862
863     if(params) {
864         if(params->key_len > WLAN_MAX_KEY_LEN ||
865             params->seq_len > IW_ENCODE_SEQ_MAX_SIZE)
866             return -EINVAL;
867
868         key->key_len = params->key_len;
869         memcpy(key->key, params->key, key->key_len);
870         key->seq_len = params->seq_len;
871         memcpy(key->seq, params->seq, key->seq_len);
872         key->cipher = params->cipher;
873     }
874
875     switch (key->cipher) {
876     case WLAN_CIPHER_SUITE_WEP40:
877     case WLAN_CIPHER_SUITE_WEP104:
878         key_type = WEP_CRYPT;
879         break;
880
881     case WLAN_CIPHER_SUITE_TKIP:
882         key_type = TKIP_CRYPT;
883         break;
884
885     case WLAN_CIPHER_SUITE_CCMP:
886         key_type = AES_CRYPT;
887         break;
888
889     default:
890         return -ENOTSUPP;
891     }
892
893     if (((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)) &&
894         (GROUP_USAGE & key_usage))
895     {
896         A_UNTIMEOUT(&ar->disconnect_timer);
897     }
898
899     AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
900                     ("%s: index %d, key_len %d, key_type 0x%x,"\
901                     " key_usage 0x%x, seq_len %d\n",
902                     __func__, key_index, key->key_len, key_type,
903                     key_usage, key->seq_len));
904
905     ar->arDefTxKeyIndex = key_index;
906     status = wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex, key_type, key_usage,
907                     key->key_len, key->seq, key->key, KEY_OP_INIT_VAL,
908                     (u8 *)mac_addr, SYNC_BOTH_WMIFLAG);
909
910
911     if (status) {
912         return -EIO;
913     }
914
915     return 0;
916 }
917
918 static int
919 ar6k_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
920                       u8 key_index, bool pairwise, const u8 *mac_addr)
921 {
922     struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
923
924     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
925
926     if(ar->arWmiReady == false) {
927         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
928         return -EIO;
929     }
930
931     if(ar->arWlanState == WLAN_DISABLED) {
932         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
933         return -EIO;
934     }
935
936     if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
937         AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
938                         ("%s: key index %d out of bounds\n", __func__, key_index));
939         return -ENOENT;
940     }
941
942     if(!ar->keys[key_index].key_len) {
943         AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d is empty\n", __func__, key_index));
944         return 0;
945     }
946
947     ar->keys[key_index].key_len = 0;
948
949     return wmi_deleteKey_cmd(ar->arWmi, key_index);
950 }
951
952
953 static int
954 ar6k_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
955                       u8 key_index, bool pairwise, const u8 *mac_addr,
956                       void *cookie,
957                       void (*callback)(void *cookie, struct key_params*))
958 {
959     struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
960     struct ar_key *key = NULL;
961     struct key_params params;
962
963     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
964
965     if(ar->arWmiReady == false) {
966         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
967         return -EIO;
968     }
969
970     if(ar->arWlanState == WLAN_DISABLED) {
971         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
972         return -EIO;
973     }
974
975     if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
976         AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
977                         ("%s: key index %d out of bounds\n", __func__, key_index));
978         return -ENOENT;
979     }
980
981     key = &ar->keys[key_index];
982     A_MEMZERO(&params, sizeof(params));
983     params.cipher = key->cipher;
984     params.key_len = key->key_len;
985     params.seq_len = key->seq_len;
986     params.seq = key->seq;
987     params.key = key->key;
988
989     callback(cookie, &params);
990
991     return key->key_len ? 0 : -ENOENT;
992 }
993
994
995 static int
996 ar6k_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev,
997                               u8 key_index, bool unicast, bool multicast)
998 {
999     struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
1000     struct ar_key *key = NULL;
1001     int status = 0;
1002     u8 key_usage;
1003
1004     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
1005
1006     if(ar->arWmiReady == false) {
1007         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1008         return -EIO;
1009     }
1010
1011     if(ar->arWlanState == WLAN_DISABLED) {
1012         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1013         return -EIO;
1014     }
1015
1016     if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1017         AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
1018                         ("%s: key index %d out of bounds\n",
1019                         __func__, key_index));
1020         return -ENOENT;
1021     }
1022
1023     if(!ar->keys[key_index].key_len) {
1024         AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: invalid key index %d\n",
1025                         __func__, key_index));
1026         return -EINVAL;
1027     }
1028
1029     ar->arDefTxKeyIndex = key_index;
1030     key = &ar->keys[ar->arDefTxKeyIndex];
1031     key_usage = GROUP_USAGE;
1032     if (WEP_CRYPT == ar->arPairwiseCrypto) {
1033         key_usage |= TX_USAGE;
1034     }
1035
1036     status = wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex,
1037                             ar->arPairwiseCrypto, key_usage,
1038                             key->key_len, key->seq, key->key, KEY_OP_INIT_VAL,
1039                             NULL, SYNC_BOTH_WMIFLAG);
1040     if (status) {
1041         return -EIO;
1042     }
1043
1044     return 0;
1045 }
1046
1047 static int
1048 ar6k_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *ndev,
1049                                    u8 key_index)
1050 {
1051     struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev);
1052
1053     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
1054
1055     if(ar->arWmiReady == false) {
1056         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1057         return -EIO;
1058     }
1059
1060     if(ar->arWlanState == WLAN_DISABLED) {
1061         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1062         return -EIO;
1063     }
1064
1065     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
1066     return -ENOTSUPP;
1067 }
1068
1069 void
1070 ar6k_cfg80211_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast)
1071 {
1072     AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
1073                     ("%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast));
1074
1075     cfg80211_michael_mic_failure(ar->arNetDev, ar->arBssid,
1076                                  (ismcast ? NL80211_KEYTYPE_GROUP : NL80211_KEYTYPE_PAIRWISE),
1077                                  keyid, NULL, GFP_KERNEL);
1078 }
1079
1080 static int
1081 ar6k_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1082 {
1083     struct ar6_softc *ar = (struct ar6_softc *)wiphy_priv(wiphy);
1084
1085     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: changed 0x%x\n", __func__, changed));
1086
1087     if(ar->arWmiReady == false) {
1088         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1089         return -EIO;
1090     }
1091
1092     if(ar->arWlanState == WLAN_DISABLED) {
1093         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1094         return -EIO;
1095     }
1096
1097     if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1098         if (wmi_set_rts_cmd(ar->arWmi,wiphy->rts_threshold) != 0){
1099             AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_set_rts_cmd failed\n", __func__));
1100             return -EIO;
1101         }
1102     }
1103
1104     return 0;
1105 }
1106
1107 static int
1108 ar6k_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
1109                                const u8 *peer,
1110                                const struct cfg80211_bitrate_mask *mask)
1111 {
1112     AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Setting rates: Not supported\n"));
1113     return -EIO;
1114 }
1115
1116 /* The type nl80211_tx_power_setting replaces the following data type from 2.6.36 onwards */
1117 static int
1118 ar6k_cfg80211_set_txpower(struct wiphy *wiphy, enum nl80211_tx_power_setting type, int dbm)
1119 {
1120     struct ar6_softc *ar = (struct ar6_softc *)wiphy_priv(wiphy);
1121     u8 ar_dbm;
1122
1123     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x, dbm %d\n", __func__, type, dbm));
1124
1125     if(ar->arWmiReady == false) {
1126         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1127         return -EIO;
1128     }
1129
1130     if(ar->arWlanState == WLAN_DISABLED) {
1131         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1132         return -EIO;
1133     }
1134
1135     ar->arTxPwrSet = false;
1136     switch(type) {
1137     case NL80211_TX_POWER_AUTOMATIC:
1138         return 0;
1139     case NL80211_TX_POWER_LIMITED:
1140         ar->arTxPwr = ar_dbm = dbm;
1141         ar->arTxPwrSet = true;
1142         break;
1143     default:
1144         AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x not supported\n", __func__, type));
1145         return -EOPNOTSUPP;
1146     }
1147
1148     wmi_set_txPwr_cmd(ar->arWmi, ar_dbm);
1149
1150     return 0;
1151 }
1152
1153 static int
1154 ar6k_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
1155 {
1156     struct ar6_softc *ar = (struct ar6_softc *)wiphy_priv(wiphy);
1157
1158     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1159
1160     if(ar->arWmiReady == false) {
1161         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1162         return -EIO;
1163     }
1164
1165     if(ar->arWlanState == WLAN_DISABLED) {
1166         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1167         return -EIO;
1168     }
1169
1170     if((ar->arConnected == true)) {
1171         ar->arTxPwr = 0;
1172
1173         if(wmi_get_txPwr_cmd(ar->arWmi) != 0) {
1174             AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_get_txPwr_cmd failed\n", __func__));
1175             return -EIO;
1176         }
1177
1178         wait_event_interruptible_timeout(arEvent, ar->arTxPwr != 0, 5 * HZ);
1179
1180         if(signal_pending(current)) {
1181             AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Target did not respond\n", __func__));
1182             return -EINTR;
1183         }
1184     }
1185
1186     *dbm = ar->arTxPwr;
1187     return 0;
1188 }
1189
1190 static int
1191 ar6k_cfg80211_set_power_mgmt(struct wiphy *wiphy,
1192                              struct net_device *dev,
1193                              bool pmgmt, int timeout)
1194 {
1195     struct ar6_softc *ar = ar6k_priv(dev);
1196     WMI_POWER_MODE_CMD pwrMode;
1197
1198     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: pmgmt %d, timeout %d\n", __func__, pmgmt, timeout));
1199
1200     if(ar->arWmiReady == false) {
1201         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1202         return -EIO;
1203     }
1204
1205     if(ar->arWlanState == WLAN_DISABLED) {
1206         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1207         return -EIO;
1208     }
1209
1210     if(pmgmt) {
1211         AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Max Perf\n", __func__));
1212         pwrMode.powerMode = REC_POWER;
1213     } else {
1214         AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Rec Power\n", __func__));
1215         pwrMode.powerMode = MAX_PERF_POWER;
1216     }
1217
1218     if(wmi_powermode_cmd(ar->arWmi, pwrMode.powerMode) != 0) {
1219         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_powermode_cmd failed\n", __func__));
1220         return -EIO;
1221     }
1222
1223     return 0;
1224 }
1225
1226 static struct net_device *
1227 ar6k_cfg80211_add_virtual_intf(struct wiphy *wiphy, char *name,
1228                                             enum nl80211_iftype type, u32 *flags,
1229                                             struct vif_params *params)
1230 {
1231
1232     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
1233
1234     /* Multiple virtual interface is not supported.
1235      * The default interface supports STA and IBSS type
1236      */
1237     return ERR_PTR(-EOPNOTSUPP);
1238 }
1239
1240 static int
1241 ar6k_cfg80211_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev)
1242 {
1243
1244     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
1245
1246     /* Multiple virtual interface is not supported.
1247      * The default interface supports STA and IBSS type
1248      */
1249     return -EOPNOTSUPP;
1250 }
1251
1252 static int
1253 ar6k_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
1254                            enum nl80211_iftype type, u32 *flags,
1255                            struct vif_params *params)
1256 {
1257     struct ar6_softc *ar = ar6k_priv(ndev);
1258     struct wireless_dev *wdev = ar->wdev;
1259
1260     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type %u\n", __func__, type));
1261
1262     if(ar->arWmiReady == false) {
1263         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1264         return -EIO;
1265     }
1266
1267     if(ar->arWlanState == WLAN_DISABLED) {
1268         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1269         return -EIO;
1270     }
1271
1272     switch (type) {
1273     case NL80211_IFTYPE_STATION:
1274         ar->arNextMode = INFRA_NETWORK;
1275         break;
1276     case NL80211_IFTYPE_ADHOC:
1277         ar->arNextMode = ADHOC_NETWORK;
1278         break;
1279     default:
1280         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: type %u\n", __func__, type));
1281         return -EOPNOTSUPP;
1282     }
1283
1284     wdev->iftype = type;
1285
1286     return 0;
1287 }
1288
1289 static int
1290 ar6k_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1291                         struct cfg80211_ibss_params *ibss_param)
1292 {
1293     struct ar6_softc *ar = ar6k_priv(dev);
1294     int status;
1295
1296     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1297
1298     if(ar->arWmiReady == false) {
1299         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1300         return -EIO;
1301     }
1302
1303     if(ar->arWlanState == WLAN_DISABLED) {
1304         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1305         return -EIO;
1306     }
1307
1308     if(!ibss_param->ssid_len || IEEE80211_MAX_SSID_LEN < ibss_param->ssid_len) {
1309         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ssid invalid\n", __func__));
1310         return -EINVAL;
1311     }
1312
1313     ar->arSsidLen = ibss_param->ssid_len;
1314     memcpy(ar->arSsid, ibss_param->ssid, ar->arSsidLen);
1315
1316     if(ibss_param->channel) {
1317         ar->arChannelHint = ibss_param->channel->center_freq;
1318     }
1319
1320     if(ibss_param->channel_fixed) {
1321         /* TODO: channel_fixed: The channel should be fixed, do not search for
1322          * IBSSs to join on other channels. Target firmware does not support this
1323          * feature, needs to be updated.*/
1324     }
1325
1326     A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
1327     if(ibss_param->bssid) {
1328         if(memcmp(&ibss_param->bssid, bcast_mac, AR6000_ETH_ADDR_LEN)) {
1329             memcpy(ar->arReqBssid, ibss_param->bssid, sizeof(ar->arReqBssid));
1330         }
1331     }
1332
1333     ar6k_set_wpa_version(ar, 0);
1334     ar6k_set_auth_type(ar, NL80211_AUTHTYPE_OPEN_SYSTEM);
1335
1336     if(ibss_param->privacy) {
1337         ar6k_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, true);
1338         ar6k_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, false);
1339     } else {
1340         ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, true);
1341         ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, false);
1342     }
1343
1344     ar->arNetworkType = ar->arNextMode;
1345
1346     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Connect called with authmode %d dot11 auth %d"\
1347                     " PW crypto %d PW crypto Len %d GRP crypto %d"\
1348                     " GRP crypto Len %d channel hint %u\n",
1349                     __func__, ar->arAuthMode, ar->arDot11AuthMode,
1350                     ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
1351                     ar->arGroupCrypto, ar->arGroupCryptoLen, ar->arChannelHint));
1352
1353     status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType,
1354                             ar->arDot11AuthMode, ar->arAuthMode,
1355                             ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
1356                             ar->arGroupCrypto,ar->arGroupCryptoLen,
1357                             ar->arSsidLen, ar->arSsid,
1358                             ar->arReqBssid, ar->arChannelHint,
1359                             ar->arConnectCtrlFlags);
1360     ar->arConnectPending = true;
1361
1362     return 0;
1363 }
1364
1365 static int
1366 ar6k_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1367 {
1368     struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
1369
1370     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1371
1372     if(ar->arWmiReady == false) {
1373         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1374         return -EIO;
1375     }
1376
1377     if(ar->arWlanState == WLAN_DISABLED) {
1378         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1379         return -EIO;
1380     }
1381
1382     ar6000_disconnect(ar);
1383     A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
1384     ar->arSsidLen = 0;
1385
1386     return 0;
1387 }
1388
1389
1390 static const
1391 u32 cipher_suites[] = {
1392     WLAN_CIPHER_SUITE_WEP40,
1393     WLAN_CIPHER_SUITE_WEP104,
1394     WLAN_CIPHER_SUITE_TKIP,
1395     WLAN_CIPHER_SUITE_CCMP,
1396 };
1397
1398 static struct
1399 cfg80211_ops ar6k_cfg80211_ops = {
1400     .change_virtual_intf = ar6k_cfg80211_change_iface,
1401     .add_virtual_intf = ar6k_cfg80211_add_virtual_intf,
1402     .del_virtual_intf = ar6k_cfg80211_del_virtual_intf,
1403     .scan = ar6k_cfg80211_scan,
1404     .connect = ar6k_cfg80211_connect,
1405     .disconnect = ar6k_cfg80211_disconnect,
1406     .add_key = ar6k_cfg80211_add_key,
1407     .get_key = ar6k_cfg80211_get_key,
1408     .del_key = ar6k_cfg80211_del_key,
1409     .set_default_key = ar6k_cfg80211_set_default_key,
1410     .set_default_mgmt_key = ar6k_cfg80211_set_default_mgmt_key,
1411     .set_wiphy_params = ar6k_cfg80211_set_wiphy_params,
1412     .set_bitrate_mask = ar6k_cfg80211_set_bitrate_mask,
1413     .set_tx_power = ar6k_cfg80211_set_txpower,
1414     .get_tx_power = ar6k_cfg80211_get_txpower,
1415     .set_power_mgmt = ar6k_cfg80211_set_power_mgmt,
1416     .join_ibss = ar6k_cfg80211_join_ibss,
1417     .leave_ibss = ar6k_cfg80211_leave_ibss,
1418 };
1419
1420 struct wireless_dev *
1421 ar6k_cfg80211_init(struct device *dev)
1422 {
1423     int ret = 0;
1424     struct wireless_dev *wdev;
1425
1426     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1427
1428     wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
1429     if(!wdev) {
1430         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1431                         ("%s: Couldn't allocate wireless device\n", __func__));
1432         return ERR_PTR(-ENOMEM);
1433     }
1434
1435     /* create a new wiphy for use with cfg80211 */
1436     wdev->wiphy = wiphy_new(&ar6k_cfg80211_ops, sizeof(struct ar6_softc));
1437     if(!wdev->wiphy) {
1438         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1439                         ("%s: Couldn't allocate wiphy device\n", __func__));
1440         kfree(wdev);
1441         return ERR_PTR(-ENOMEM);
1442     }
1443
1444     /* set device pointer for wiphy */
1445     set_wiphy_dev(wdev->wiphy, dev);
1446
1447     wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1448                                    BIT(NL80211_IFTYPE_ADHOC);
1449     /* max num of ssids that can be probed during scanning */
1450     wdev->wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
1451     wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar6k_band_2ghz;
1452     wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar6k_band_5ghz;
1453     wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
1454
1455     wdev->wiphy->cipher_suites = cipher_suites;
1456     wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
1457
1458     ret = wiphy_register(wdev->wiphy);
1459     if(ret < 0) {
1460         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1461                         ("%s: Couldn't register wiphy device\n", __func__));
1462         wiphy_free(wdev->wiphy);
1463         return ERR_PTR(ret);
1464     }
1465
1466     return wdev;
1467 }
1468
1469 void
1470 ar6k_cfg80211_deinit(struct ar6_softc *ar)
1471 {
1472     struct wireless_dev *wdev = ar->wdev;
1473
1474     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1475
1476     if(ar->scan_request) {
1477         cfg80211_scan_done(ar->scan_request, true);
1478         ar->scan_request = NULL;
1479     }
1480
1481     if(!wdev)
1482         return;
1483
1484     wiphy_unregister(wdev->wiphy);
1485     wiphy_free(wdev->wiphy);
1486     kfree(wdev);
1487 }
1488
1489
1490
1491
1492
1493
1494