Merge branch 'for-linus' of git://git.open-osd.org/linux-open-osd
[pandora-kernel.git] / drivers / net / wireless / iwmc3200wifi / cfg80211.c
1 /*
2  * Intel Wireless Multicomm 3200 WiFi driver
3  *
4  * Copyright (C) 2009 Intel Corporation <ilw@linux.intel.com>
5  * Samuel Ortiz <samuel.ortiz@intel.com>
6  * Zhu Yi <yi.zhu@intel.com>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License version
10  * 2 as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20  * 02110-1301, USA.
21  *
22  */
23
24 #include <linux/kernel.h>
25 #include <linux/netdevice.h>
26 #include <linux/sched.h>
27 #include <linux/etherdevice.h>
28 #include <linux/wireless.h>
29 #include <linux/ieee80211.h>
30 #include <linux/slab.h>
31 #include <net/cfg80211.h>
32
33 #include "iwm.h"
34 #include "commands.h"
35 #include "cfg80211.h"
36 #include "debug.h"
37
38 #define RATETAB_ENT(_rate, _rateid, _flags) \
39         {                                                               \
40                 .bitrate        = (_rate),                              \
41                 .hw_value       = (_rateid),                            \
42                 .flags          = (_flags),                             \
43         }
44
45 #define CHAN2G(_channel, _freq, _flags) {                       \
46         .band                   = IEEE80211_BAND_2GHZ,          \
47         .center_freq            = (_freq),                      \
48         .hw_value               = (_channel),                   \
49         .flags                  = (_flags),                     \
50         .max_antenna_gain       = 0,                            \
51         .max_power              = 30,                           \
52 }
53
54 #define CHAN5G(_channel, _flags) {                              \
55         .band                   = IEEE80211_BAND_5GHZ,          \
56         .center_freq            = 5000 + (5 * (_channel)),      \
57         .hw_value               = (_channel),                   \
58         .flags                  = (_flags),                     \
59         .max_antenna_gain       = 0,                            \
60         .max_power              = 30,                           \
61 }
62
63 static struct ieee80211_rate iwm_rates[] = {
64         RATETAB_ENT(10,  0x1,   0),
65         RATETAB_ENT(20,  0x2,   0),
66         RATETAB_ENT(55,  0x4,   0),
67         RATETAB_ENT(110, 0x8,   0),
68         RATETAB_ENT(60,  0x10,  0),
69         RATETAB_ENT(90,  0x20,  0),
70         RATETAB_ENT(120, 0x40,  0),
71         RATETAB_ENT(180, 0x80,  0),
72         RATETAB_ENT(240, 0x100, 0),
73         RATETAB_ENT(360, 0x200, 0),
74         RATETAB_ENT(480, 0x400, 0),
75         RATETAB_ENT(540, 0x800, 0),
76 };
77
78 #define iwm_a_rates             (iwm_rates + 4)
79 #define iwm_a_rates_size        8
80 #define iwm_g_rates             (iwm_rates + 0)
81 #define iwm_g_rates_size        12
82
83 static struct ieee80211_channel iwm_2ghz_channels[] = {
84         CHAN2G(1, 2412, 0),
85         CHAN2G(2, 2417, 0),
86         CHAN2G(3, 2422, 0),
87         CHAN2G(4, 2427, 0),
88         CHAN2G(5, 2432, 0),
89         CHAN2G(6, 2437, 0),
90         CHAN2G(7, 2442, 0),
91         CHAN2G(8, 2447, 0),
92         CHAN2G(9, 2452, 0),
93         CHAN2G(10, 2457, 0),
94         CHAN2G(11, 2462, 0),
95         CHAN2G(12, 2467, 0),
96         CHAN2G(13, 2472, 0),
97         CHAN2G(14, 2484, 0),
98 };
99
100 static struct ieee80211_channel iwm_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 ieee80211_supported_band iwm_band_2ghz = {
123         .channels = iwm_2ghz_channels,
124         .n_channels = ARRAY_SIZE(iwm_2ghz_channels),
125         .bitrates = iwm_g_rates,
126         .n_bitrates = iwm_g_rates_size,
127 };
128
129 static struct ieee80211_supported_band iwm_band_5ghz = {
130         .channels = iwm_5ghz_a_channels,
131         .n_channels = ARRAY_SIZE(iwm_5ghz_a_channels),
132         .bitrates = iwm_a_rates,
133         .n_bitrates = iwm_a_rates_size,
134 };
135
136 static int iwm_key_init(struct iwm_key *key, u8 key_index,
137                         const u8 *mac_addr, struct key_params *params)
138 {
139         key->hdr.key_idx = key_index;
140         if (!mac_addr || is_broadcast_ether_addr(mac_addr)) {
141                 key->hdr.multicast = 1;
142                 memset(key->hdr.mac, 0xff, ETH_ALEN);
143         } else {
144                 key->hdr.multicast = 0;
145                 memcpy(key->hdr.mac, mac_addr, ETH_ALEN);
146         }
147
148         if (params) {
149                 if (params->key_len > WLAN_MAX_KEY_LEN ||
150                     params->seq_len > IW_ENCODE_SEQ_MAX_SIZE)
151                         return -EINVAL;
152
153                 key->cipher = params->cipher;
154                 key->key_len = params->key_len;
155                 key->seq_len = params->seq_len;
156                 memcpy(key->key, params->key, key->key_len);
157                 memcpy(key->seq, params->seq, key->seq_len);
158         }
159
160         return 0;
161 }
162
163 static int iwm_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
164                                 u8 key_index, const u8 *mac_addr,
165                                 struct key_params *params)
166 {
167         struct iwm_priv *iwm = ndev_to_iwm(ndev);
168         struct iwm_key *key = &iwm->keys[key_index];
169         int ret;
170
171         IWM_DBG_WEXT(iwm, DBG, "Adding key for %pM\n", mac_addr);
172
173         memset(key, 0, sizeof(struct iwm_key));
174         ret = iwm_key_init(key, key_index, mac_addr, params);
175         if (ret < 0) {
176                 IWM_ERR(iwm, "Invalid key_params\n");
177                 return ret;
178         }
179
180         return iwm_set_key(iwm, 0, key);
181 }
182
183 static int iwm_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
184                                 u8 key_index, const u8 *mac_addr, void *cookie,
185                                 void (*callback)(void *cookie,
186                                                  struct key_params*))
187 {
188         struct iwm_priv *iwm = ndev_to_iwm(ndev);
189         struct iwm_key *key = &iwm->keys[key_index];
190         struct key_params params;
191
192         IWM_DBG_WEXT(iwm, DBG, "Getting key %d\n", key_index);
193
194         memset(&params, 0, sizeof(params));
195
196         params.cipher = key->cipher;
197         params.key_len = key->key_len;
198         params.seq_len = key->seq_len;
199         params.seq = key->seq;
200         params.key = key->key;
201
202         callback(cookie, &params);
203
204         return key->key_len ? 0 : -ENOENT;
205 }
206
207
208 static int iwm_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
209                                 u8 key_index, const u8 *mac_addr)
210 {
211         struct iwm_priv *iwm = ndev_to_iwm(ndev);
212         struct iwm_key *key = &iwm->keys[key_index];
213
214         if (!iwm->keys[key_index].key_len) {
215                 IWM_DBG_WEXT(iwm, DBG, "Key %d not used\n", key_index);
216                 return 0;
217         }
218
219         if (key_index == iwm->default_key)
220                 iwm->default_key = -1;
221
222         return iwm_set_key(iwm, 1, key);
223 }
224
225 static int iwm_cfg80211_set_default_key(struct wiphy *wiphy,
226                                         struct net_device *ndev,
227                                         u8 key_index)
228 {
229         struct iwm_priv *iwm = ndev_to_iwm(ndev);
230
231         IWM_DBG_WEXT(iwm, DBG, "Default key index is: %d\n", key_index);
232
233         if (!iwm->keys[key_index].key_len) {
234                 IWM_ERR(iwm, "Key %d not used\n", key_index);
235                 return -EINVAL;
236         }
237
238         iwm->default_key = key_index;
239
240         return iwm_set_tx_key(iwm, key_index);
241 }
242
243 static int iwm_cfg80211_get_station(struct wiphy *wiphy,
244                                     struct net_device *ndev,
245                                     u8 *mac, struct station_info *sinfo)
246 {
247         struct iwm_priv *iwm = ndev_to_iwm(ndev);
248
249         if (memcmp(mac, iwm->bssid, ETH_ALEN))
250                 return -ENOENT;
251
252         sinfo->filled |= STATION_INFO_TX_BITRATE;
253         sinfo->txrate.legacy = iwm->rate * 10;
254
255         if (test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)) {
256                 sinfo->filled |= STATION_INFO_SIGNAL;
257                 sinfo->signal = iwm->wstats.qual.level;
258         }
259
260         return 0;
261 }
262
263
264 int iwm_cfg80211_inform_bss(struct iwm_priv *iwm)
265 {
266         struct wiphy *wiphy = iwm_to_wiphy(iwm);
267         struct iwm_bss_info *bss;
268         struct iwm_umac_notif_bss_info *umac_bss;
269         struct ieee80211_mgmt *mgmt;
270         struct ieee80211_channel *channel;
271         struct ieee80211_supported_band *band;
272         s32 signal;
273         int freq;
274
275         list_for_each_entry(bss, &iwm->bss_list, node) {
276                 umac_bss = bss->bss;
277                 mgmt = (struct ieee80211_mgmt *)(umac_bss->frame_buf);
278
279                 if (umac_bss->band == UMAC_BAND_2GHZ)
280                         band = wiphy->bands[IEEE80211_BAND_2GHZ];
281                 else if (umac_bss->band == UMAC_BAND_5GHZ)
282                         band = wiphy->bands[IEEE80211_BAND_5GHZ];
283                 else {
284                         IWM_ERR(iwm, "Invalid band: %d\n", umac_bss->band);
285                         return -EINVAL;
286                 }
287
288                 freq = ieee80211_channel_to_frequency(umac_bss->channel);
289                 channel = ieee80211_get_channel(wiphy, freq);
290                 signal = umac_bss->rssi * 100;
291
292                 if (!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
293                                                le16_to_cpu(umac_bss->frame_len),
294                                                signal, GFP_KERNEL))
295                         return -EINVAL;
296         }
297
298         return 0;
299 }
300
301 static int iwm_cfg80211_change_iface(struct wiphy *wiphy,
302                                      struct net_device *ndev,
303                                      enum nl80211_iftype type, u32 *flags,
304                                      struct vif_params *params)
305 {
306         struct wireless_dev *wdev;
307         struct iwm_priv *iwm;
308         u32 old_mode;
309
310         wdev = ndev->ieee80211_ptr;
311         iwm = ndev_to_iwm(ndev);
312         old_mode = iwm->conf.mode;
313
314         switch (type) {
315         case NL80211_IFTYPE_STATION:
316                 iwm->conf.mode = UMAC_MODE_BSS;
317                 break;
318         case NL80211_IFTYPE_ADHOC:
319                 iwm->conf.mode = UMAC_MODE_IBSS;
320                 break;
321         default:
322                 return -EOPNOTSUPP;
323         }
324
325         wdev->iftype = type;
326
327         if ((old_mode == iwm->conf.mode) || !iwm->umac_profile)
328                 return 0;
329
330         iwm->umac_profile->mode = cpu_to_le32(iwm->conf.mode);
331
332         if (iwm->umac_profile_active)
333                 iwm_invalidate_mlme_profile(iwm);
334
335         return 0;
336 }
337
338 static int iwm_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
339                              struct cfg80211_scan_request *request)
340 {
341         struct iwm_priv *iwm = ndev_to_iwm(ndev);
342         int ret;
343
344         if (!test_bit(IWM_STATUS_READY, &iwm->status)) {
345                 IWM_ERR(iwm, "Scan while device is not ready\n");
346                 return -EIO;
347         }
348
349         if (test_bit(IWM_STATUS_SCANNING, &iwm->status)) {
350                 IWM_ERR(iwm, "Scanning already\n");
351                 return -EAGAIN;
352         }
353
354         if (test_bit(IWM_STATUS_SCAN_ABORTING, &iwm->status)) {
355                 IWM_ERR(iwm, "Scanning being aborted\n");
356                 return -EAGAIN;
357         }
358
359         set_bit(IWM_STATUS_SCANNING, &iwm->status);
360
361         ret = iwm_scan_ssids(iwm, request->ssids, request->n_ssids);
362         if (ret) {
363                 clear_bit(IWM_STATUS_SCANNING, &iwm->status);
364                 return ret;
365         }
366
367         iwm->scan_request = request;
368         return 0;
369 }
370
371 static int iwm_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
372 {
373         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
374
375         if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
376             (iwm->conf.rts_threshold != wiphy->rts_threshold)) {
377                 int ret;
378
379                 iwm->conf.rts_threshold = wiphy->rts_threshold;
380
381                 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
382                                              CFG_RTS_THRESHOLD,
383                                              iwm->conf.rts_threshold);
384                 if (ret < 0)
385                         return ret;
386         }
387
388         if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
389             (iwm->conf.frag_threshold != wiphy->frag_threshold)) {
390                 int ret;
391
392                 iwm->conf.frag_threshold = wiphy->frag_threshold;
393
394                 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX,
395                                              CFG_FRAG_THRESHOLD,
396                                              iwm->conf.frag_threshold);
397                 if (ret < 0)
398                         return ret;
399         }
400
401         return 0;
402 }
403
404 static int iwm_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
405                                   struct cfg80211_ibss_params *params)
406 {
407         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
408         struct ieee80211_channel *chan = params->channel;
409
410         if (!test_bit(IWM_STATUS_READY, &iwm->status))
411                 return -EIO;
412
413         /* UMAC doesn't support creating or joining an IBSS network
414          * with specified bssid. */
415         if (params->bssid)
416                 return -EOPNOTSUPP;
417
418         iwm->channel = ieee80211_frequency_to_channel(chan->center_freq);
419         iwm->umac_profile->ibss.band = chan->band;
420         iwm->umac_profile->ibss.channel = iwm->channel;
421         iwm->umac_profile->ssid.ssid_len = params->ssid_len;
422         memcpy(iwm->umac_profile->ssid.ssid, params->ssid, params->ssid_len);
423
424         return iwm_send_mlme_profile(iwm);
425 }
426
427 static int iwm_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
428 {
429         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
430
431         if (iwm->umac_profile_active)
432                 return iwm_invalidate_mlme_profile(iwm);
433
434         return 0;
435 }
436
437 static int iwm_set_auth_type(struct iwm_priv *iwm,
438                              enum nl80211_auth_type sme_auth_type)
439 {
440         u8 *auth_type = &iwm->umac_profile->sec.auth_type;
441
442         switch (sme_auth_type) {
443         case NL80211_AUTHTYPE_AUTOMATIC:
444         case NL80211_AUTHTYPE_OPEN_SYSTEM:
445                 IWM_DBG_WEXT(iwm, DBG, "OPEN auth\n");
446                 *auth_type = UMAC_AUTH_TYPE_OPEN;
447                 break;
448         case NL80211_AUTHTYPE_SHARED_KEY:
449                 if (iwm->umac_profile->sec.flags &
450                     (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK)) {
451                         IWM_DBG_WEXT(iwm, DBG, "WPA auth alg\n");
452                         *auth_type = UMAC_AUTH_TYPE_RSNA_PSK;
453                 } else {
454                         IWM_DBG_WEXT(iwm, DBG, "WEP shared key auth alg\n");
455                         *auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
456                 }
457
458                 break;
459         default:
460                 IWM_ERR(iwm, "Unsupported auth alg: 0x%x\n", sme_auth_type);
461                 return -ENOTSUPP;
462         }
463
464         return 0;
465 }
466
467 static int iwm_set_wpa_version(struct iwm_priv *iwm, u32 wpa_version)
468 {
469         IWM_DBG_WEXT(iwm, DBG, "wpa_version: %d\n", wpa_version);
470
471         if (!wpa_version) {
472                 iwm->umac_profile->sec.flags = UMAC_SEC_FLG_LEGACY_PROFILE;
473                 return 0;
474         }
475
476         if (wpa_version & NL80211_WPA_VERSION_1)
477                 iwm->umac_profile->sec.flags = UMAC_SEC_FLG_WPA_ON_MSK;
478
479         if (wpa_version & NL80211_WPA_VERSION_2)
480                 iwm->umac_profile->sec.flags = UMAC_SEC_FLG_RSNA_ON_MSK;
481
482         return 0;
483 }
484
485 static int iwm_set_cipher(struct iwm_priv *iwm, u32 cipher, bool ucast)
486 {
487         u8 *profile_cipher = ucast ? &iwm->umac_profile->sec.ucast_cipher :
488                 &iwm->umac_profile->sec.mcast_cipher;
489
490         if (!cipher) {
491                 *profile_cipher = UMAC_CIPHER_TYPE_NONE;
492                 return 0;
493         }
494
495         IWM_DBG_WEXT(iwm, DBG, "%ccast cipher is 0x%x\n", ucast ? 'u' : 'm',
496                      cipher);
497
498         switch (cipher) {
499         case IW_AUTH_CIPHER_NONE:
500                 *profile_cipher = UMAC_CIPHER_TYPE_NONE;
501                 break;
502         case WLAN_CIPHER_SUITE_WEP40:
503                 *profile_cipher = UMAC_CIPHER_TYPE_WEP_40;
504                 break;
505         case WLAN_CIPHER_SUITE_WEP104:
506                 *profile_cipher = UMAC_CIPHER_TYPE_WEP_104;
507                 break;
508         case WLAN_CIPHER_SUITE_TKIP:
509                 *profile_cipher = UMAC_CIPHER_TYPE_TKIP;
510                 break;
511         case WLAN_CIPHER_SUITE_CCMP:
512                 *profile_cipher = UMAC_CIPHER_TYPE_CCMP;
513                 break;
514         default:
515                 IWM_ERR(iwm, "Unsupported cipher: 0x%x\n", cipher);
516                 return -ENOTSUPP;
517         }
518
519         return 0;
520 }
521
522 static int iwm_set_key_mgt(struct iwm_priv *iwm, u32 key_mgt)
523 {
524         u8 *auth_type = &iwm->umac_profile->sec.auth_type;
525
526         IWM_DBG_WEXT(iwm, DBG, "key_mgt: 0x%x\n", key_mgt);
527
528         if (key_mgt == WLAN_AKM_SUITE_8021X)
529                 *auth_type = UMAC_AUTH_TYPE_8021X;
530         else if (key_mgt == WLAN_AKM_SUITE_PSK) {
531                 if (iwm->umac_profile->sec.flags &
532                     (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK))
533                         *auth_type = UMAC_AUTH_TYPE_RSNA_PSK;
534                 else
535                         *auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
536         } else {
537                 IWM_ERR(iwm, "Invalid key mgt: 0x%x\n", key_mgt);
538                 return -EINVAL;
539         }
540
541         return 0;
542 }
543
544
545 static int iwm_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
546                                  struct cfg80211_connect_params *sme)
547 {
548         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
549         struct ieee80211_channel *chan = sme->channel;
550         struct key_params key_param;
551         int ret;
552
553         if (!test_bit(IWM_STATUS_READY, &iwm->status))
554                 return -EIO;
555
556         if (!sme->ssid)
557                 return -EINVAL;
558
559         if (iwm->umac_profile_active) {
560                 ret = iwm_invalidate_mlme_profile(iwm);
561                 if (ret) {
562                         IWM_ERR(iwm, "Couldn't invalidate profile\n");
563                         return ret;
564                 }
565         }
566
567         if (chan)
568                 iwm->channel =
569                         ieee80211_frequency_to_channel(chan->center_freq);
570
571         iwm->umac_profile->ssid.ssid_len = sme->ssid_len;
572         memcpy(iwm->umac_profile->ssid.ssid, sme->ssid, sme->ssid_len);
573
574         if (sme->bssid) {
575                 IWM_DBG_WEXT(iwm, DBG, "BSSID: %pM\n", sme->bssid);
576                 memcpy(&iwm->umac_profile->bssid[0], sme->bssid, ETH_ALEN);
577                 iwm->umac_profile->bss_num = 1;
578         } else {
579                 memset(&iwm->umac_profile->bssid[0], 0, ETH_ALEN);
580                 iwm->umac_profile->bss_num = 0;
581         }
582
583         ret = iwm_set_wpa_version(iwm, sme->crypto.wpa_versions);
584         if (ret < 0)
585                 return ret;
586
587         ret = iwm_set_auth_type(iwm, sme->auth_type);
588         if (ret < 0)
589                 return ret;
590
591         if (sme->crypto.n_ciphers_pairwise) {
592                 ret = iwm_set_cipher(iwm, sme->crypto.ciphers_pairwise[0],
593                                      true);
594                 if (ret < 0)
595                         return ret;
596         }
597
598         ret = iwm_set_cipher(iwm, sme->crypto.cipher_group, false);
599         if (ret < 0)
600                 return ret;
601
602         if (sme->crypto.n_akm_suites) {
603                 ret = iwm_set_key_mgt(iwm, sme->crypto.akm_suites[0]);
604                 if (ret < 0)
605                         return ret;
606         }
607
608         /*
609          * We save the WEP key in case we want to do shared authentication.
610          * We have to do it so because UMAC will assert whenever it gets a
611          * key before a profile.
612          */
613         if (sme->key) {
614                 key_param.key = kmemdup(sme->key, sme->key_len, GFP_KERNEL);
615                 if (key_param.key == NULL)
616                         return -ENOMEM;
617                 key_param.key_len = sme->key_len;
618                 key_param.seq_len = 0;
619                 key_param.cipher = sme->crypto.ciphers_pairwise[0];
620
621                 ret = iwm_key_init(&iwm->keys[sme->key_idx], sme->key_idx,
622                                    NULL, &key_param);
623                 kfree(key_param.key);
624                 if (ret < 0) {
625                         IWM_ERR(iwm, "Invalid key_params\n");
626                         return ret;
627                 }
628
629                 iwm->default_key = sme->key_idx;
630         }
631
632         /* WPA and open AUTH type from wpa_s means WPS (a.k.a. WSC) */
633         if ((iwm->umac_profile->sec.flags &
634              (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK)) &&
635             iwm->umac_profile->sec.auth_type == UMAC_AUTH_TYPE_OPEN) {
636                         iwm->umac_profile->sec.flags = UMAC_SEC_FLG_WSC_ON_MSK;
637         }
638
639         ret = iwm_send_mlme_profile(iwm);
640
641         if (iwm->umac_profile->sec.auth_type != UMAC_AUTH_TYPE_LEGACY_PSK ||
642             sme->key == NULL)
643                 return ret;
644
645         /*
646          * We want to do shared auth.
647          * We need to actually set the key we previously cached,
648          * and then tell the UMAC it's the default one.
649          * That will trigger the auth+assoc UMAC machinery, and again,
650          * this must be done after setting the profile.
651          */
652         ret = iwm_set_key(iwm, 0, &iwm->keys[sme->key_idx]);
653         if (ret < 0)
654                 return ret;
655
656         return iwm_set_tx_key(iwm, iwm->default_key);
657 }
658
659 static int iwm_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
660                                    u16 reason_code)
661 {
662         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
663
664         IWM_DBG_WEXT(iwm, DBG, "Active: %d\n", iwm->umac_profile_active);
665
666         if (iwm->umac_profile_active)
667                 iwm_invalidate_mlme_profile(iwm);
668
669         return 0;
670 }
671
672 static int iwm_cfg80211_set_txpower(struct wiphy *wiphy,
673                                     enum tx_power_setting type, int dbm)
674 {
675         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
676         int ret;
677
678         switch (type) {
679         case TX_POWER_AUTOMATIC:
680                 return 0;
681         case TX_POWER_FIXED:
682                 if (!test_bit(IWM_STATUS_READY, &iwm->status))
683                         return 0;
684
685                 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
686                                               CFG_TX_PWR_LIMIT_USR, dbm * 2);
687                 if (ret < 0)
688                         return ret;
689
690                 return iwm_tx_power_trigger(iwm);
691         default:
692                 IWM_ERR(iwm, "Unsupported power type: %d\n", type);
693                 return -EOPNOTSUPP;
694         }
695
696         return 0;
697 }
698
699 static int iwm_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
700 {
701         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
702
703         *dbm = iwm->txpower >> 1;
704
705         return 0;
706 }
707
708 static int iwm_cfg80211_set_power_mgmt(struct wiphy *wiphy,
709                                        struct net_device *dev,
710                                        bool enabled, int timeout)
711 {
712         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
713         u32 power_index;
714
715         if (enabled)
716                 power_index = IWM_POWER_INDEX_DEFAULT;
717         else
718                 power_index = IWM_POWER_INDEX_MIN;
719
720         if (power_index == iwm->conf.power_index)
721                 return 0;
722
723         iwm->conf.power_index = power_index;
724
725         return iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
726                                        CFG_POWER_INDEX, iwm->conf.power_index);
727 }
728
729 static int iwm_cfg80211_set_pmksa(struct wiphy *wiphy,
730                                   struct net_device *netdev,
731                                   struct cfg80211_pmksa *pmksa)
732 {
733         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
734
735         return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_ADD);
736 }
737
738 static int iwm_cfg80211_del_pmksa(struct wiphy *wiphy,
739                                   struct net_device *netdev,
740                                   struct cfg80211_pmksa *pmksa)
741 {
742         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
743
744         return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_DEL);
745 }
746
747 static int iwm_cfg80211_flush_pmksa(struct wiphy *wiphy,
748                                     struct net_device *netdev)
749 {
750         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
751         struct cfg80211_pmksa pmksa;
752
753         memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
754
755         return iwm_send_pmkid_update(iwm, &pmksa, IWM_CMD_PMKID_FLUSH);
756 }
757
758
759 static struct cfg80211_ops iwm_cfg80211_ops = {
760         .change_virtual_intf = iwm_cfg80211_change_iface,
761         .add_key = iwm_cfg80211_add_key,
762         .get_key = iwm_cfg80211_get_key,
763         .del_key = iwm_cfg80211_del_key,
764         .set_default_key = iwm_cfg80211_set_default_key,
765         .get_station = iwm_cfg80211_get_station,
766         .scan = iwm_cfg80211_scan,
767         .set_wiphy_params = iwm_cfg80211_set_wiphy_params,
768         .connect = iwm_cfg80211_connect,
769         .disconnect = iwm_cfg80211_disconnect,
770         .join_ibss = iwm_cfg80211_join_ibss,
771         .leave_ibss = iwm_cfg80211_leave_ibss,
772         .set_tx_power = iwm_cfg80211_set_txpower,
773         .get_tx_power = iwm_cfg80211_get_txpower,
774         .set_power_mgmt = iwm_cfg80211_set_power_mgmt,
775         .set_pmksa = iwm_cfg80211_set_pmksa,
776         .del_pmksa = iwm_cfg80211_del_pmksa,
777         .flush_pmksa = iwm_cfg80211_flush_pmksa,
778 };
779
780 static const u32 cipher_suites[] = {
781         WLAN_CIPHER_SUITE_WEP40,
782         WLAN_CIPHER_SUITE_WEP104,
783         WLAN_CIPHER_SUITE_TKIP,
784         WLAN_CIPHER_SUITE_CCMP,
785 };
786
787 struct wireless_dev *iwm_wdev_alloc(int sizeof_bus, struct device *dev)
788 {
789         int ret = 0;
790         struct wireless_dev *wdev;
791
792         /*
793          * We're trying to have the following memory
794          * layout:
795          *
796          * +-------------------------+
797          * | struct wiphy            |
798          * +-------------------------+
799          * | struct iwm_priv         |
800          * +-------------------------+
801          * | bus private data        |
802          * | (e.g. iwm_priv_sdio)    |
803          * +-------------------------+
804          *
805          */
806
807         wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
808         if (!wdev) {
809                 dev_err(dev, "Couldn't allocate wireless device\n");
810                 return ERR_PTR(-ENOMEM);
811         }
812
813         wdev->wiphy = wiphy_new(&iwm_cfg80211_ops,
814                                 sizeof(struct iwm_priv) + sizeof_bus);
815         if (!wdev->wiphy) {
816                 dev_err(dev, "Couldn't allocate wiphy device\n");
817                 ret = -ENOMEM;
818                 goto out_err_new;
819         }
820
821         set_wiphy_dev(wdev->wiphy, dev);
822         wdev->wiphy->max_scan_ssids = UMAC_WIFI_IF_PROBE_OPTION_MAX;
823         wdev->wiphy->max_num_pmkids = UMAC_MAX_NUM_PMKIDS;
824         wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
825                                        BIT(NL80211_IFTYPE_ADHOC);
826         wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &iwm_band_2ghz;
827         wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &iwm_band_5ghz;
828         wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
829
830         wdev->wiphy->cipher_suites = cipher_suites;
831         wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
832
833         ret = wiphy_register(wdev->wiphy);
834         if (ret < 0) {
835                 dev_err(dev, "Couldn't register wiphy device\n");
836                 goto out_err_register;
837         }
838
839         return wdev;
840
841  out_err_register:
842         wiphy_free(wdev->wiphy);
843
844  out_err_new:
845         kfree(wdev);
846
847         return ERR_PTR(ret);
848 }
849
850 void iwm_wdev_free(struct iwm_priv *iwm)
851 {
852         struct wireless_dev *wdev = iwm_to_wdev(iwm);
853
854         if (!wdev)
855                 return;
856
857         wiphy_unregister(wdev->wiphy);
858         wiphy_free(wdev->wiphy);
859         kfree(wdev);
860 }