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