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