iwmc3200wifi: Fix sparse warning
[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         struct cfg80211_bss *bss;
408
409         if (!test_bit(IWM_STATUS_READY, &iwm->status))
410                 return -EIO;
411
412         /* UMAC doesn't support creating IBSS network with specified bssid.
413          * This should be removed after we have join only mode supported. */
414         if (params->bssid)
415                 return -EOPNOTSUPP;
416
417         bss = cfg80211_get_ibss(iwm_to_wiphy(iwm), NULL,
418                                 params->ssid, params->ssid_len);
419         if (!bss) {
420                 iwm_scan_one_ssid(iwm, params->ssid, params->ssid_len);
421                 schedule_timeout_interruptible(2 * HZ);
422                 bss = cfg80211_get_ibss(iwm_to_wiphy(iwm), NULL,
423                                         params->ssid, params->ssid_len);
424         }
425         /* IBSS join only mode is not supported by UMAC ATM */
426         if (bss) {
427                 cfg80211_put_bss(bss);
428                 return -EOPNOTSUPP;
429         }
430
431         iwm->channel = ieee80211_frequency_to_channel(chan->center_freq);
432         iwm->umac_profile->ibss.band = chan->band;
433         iwm->umac_profile->ibss.channel = iwm->channel;
434         iwm->umac_profile->ssid.ssid_len = params->ssid_len;
435         memcpy(iwm->umac_profile->ssid.ssid, params->ssid, params->ssid_len);
436
437         if (params->bssid)
438                 memcpy(&iwm->umac_profile->bssid[0], params->bssid, ETH_ALEN);
439
440         return iwm_send_mlme_profile(iwm);
441 }
442
443 static int iwm_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
444 {
445         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
446
447         if (iwm->umac_profile_active)
448                 return iwm_invalidate_mlme_profile(iwm);
449
450         return 0;
451 }
452
453 static int iwm_set_auth_type(struct iwm_priv *iwm,
454                              enum nl80211_auth_type sme_auth_type)
455 {
456         u8 *auth_type = &iwm->umac_profile->sec.auth_type;
457
458         switch (sme_auth_type) {
459         case NL80211_AUTHTYPE_AUTOMATIC:
460         case NL80211_AUTHTYPE_OPEN_SYSTEM:
461                 IWM_DBG_WEXT(iwm, DBG, "OPEN auth\n");
462                 *auth_type = UMAC_AUTH_TYPE_OPEN;
463                 break;
464         case NL80211_AUTHTYPE_SHARED_KEY:
465                 if (iwm->umac_profile->sec.flags &
466                     (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK)) {
467                         IWM_DBG_WEXT(iwm, DBG, "WPA auth alg\n");
468                         *auth_type = UMAC_AUTH_TYPE_RSNA_PSK;
469                 } else {
470                         IWM_DBG_WEXT(iwm, DBG, "WEP shared key auth alg\n");
471                         *auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
472                 }
473
474                 break;
475         default:
476                 IWM_ERR(iwm, "Unsupported auth alg: 0x%x\n", sme_auth_type);
477                 return -ENOTSUPP;
478         }
479
480         return 0;
481 }
482
483 static int iwm_set_wpa_version(struct iwm_priv *iwm, u32 wpa_version)
484 {
485         IWM_DBG_WEXT(iwm, DBG, "wpa_version: %d\n", wpa_version);
486
487         if (!wpa_version) {
488                 iwm->umac_profile->sec.flags = UMAC_SEC_FLG_LEGACY_PROFILE;
489                 return 0;
490         }
491
492         if (wpa_version & NL80211_WPA_VERSION_2)
493                 iwm->umac_profile->sec.flags = UMAC_SEC_FLG_RSNA_ON_MSK;
494
495         if (wpa_version & NL80211_WPA_VERSION_1)
496                 iwm->umac_profile->sec.flags |= UMAC_SEC_FLG_WPA_ON_MSK;
497
498         return 0;
499 }
500
501 static int iwm_set_cipher(struct iwm_priv *iwm, u32 cipher, bool ucast)
502 {
503         u8 *profile_cipher = ucast ? &iwm->umac_profile->sec.ucast_cipher :
504                 &iwm->umac_profile->sec.mcast_cipher;
505
506         if (!cipher) {
507                 *profile_cipher = UMAC_CIPHER_TYPE_NONE;
508                 return 0;
509         }
510
511         IWM_DBG_WEXT(iwm, DBG, "%ccast cipher is 0x%x\n", ucast ? 'u' : 'm',
512                      cipher);
513
514         switch (cipher) {
515         case IW_AUTH_CIPHER_NONE:
516                 *profile_cipher = UMAC_CIPHER_TYPE_NONE;
517                 break;
518         case WLAN_CIPHER_SUITE_WEP40:
519                 *profile_cipher = UMAC_CIPHER_TYPE_WEP_40;
520                 break;
521         case WLAN_CIPHER_SUITE_WEP104:
522                 *profile_cipher = UMAC_CIPHER_TYPE_WEP_104;
523                 break;
524         case WLAN_CIPHER_SUITE_TKIP:
525                 *profile_cipher = UMAC_CIPHER_TYPE_TKIP;
526                 break;
527         case WLAN_CIPHER_SUITE_CCMP:
528                 *profile_cipher = UMAC_CIPHER_TYPE_CCMP;
529                 break;
530         default:
531                 IWM_ERR(iwm, "Unsupported cipher: 0x%x\n", cipher);
532                 return -ENOTSUPP;
533         }
534
535         return 0;
536 }
537
538 static int iwm_set_key_mgt(struct iwm_priv *iwm, u32 key_mgt)
539 {
540         u8 *auth_type = &iwm->umac_profile->sec.auth_type;
541
542         IWM_DBG_WEXT(iwm, DBG, "key_mgt: 0x%x\n", key_mgt);
543
544         if (key_mgt == WLAN_AKM_SUITE_8021X)
545                 *auth_type = UMAC_AUTH_TYPE_8021X;
546         else if (key_mgt == WLAN_AKM_SUITE_PSK) {
547                 if (iwm->umac_profile->sec.flags &
548                     (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK))
549                         *auth_type = UMAC_AUTH_TYPE_RSNA_PSK;
550                 else
551                         *auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
552         } else {
553                 IWM_ERR(iwm, "Invalid key mgt: 0x%x\n", key_mgt);
554                 return -EINVAL;
555         }
556
557         return 0;
558 }
559
560
561 static int iwm_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
562                                  struct cfg80211_connect_params *sme)
563 {
564         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
565         struct ieee80211_channel *chan = sme->channel;
566         struct key_params key_param;
567         int ret;
568
569         if (!test_bit(IWM_STATUS_READY, &iwm->status))
570                 return -EIO;
571
572         if (!sme->ssid)
573                 return -EINVAL;
574
575         if (iwm->umac_profile_active) {
576                 ret = iwm_invalidate_mlme_profile(iwm);
577                 if (ret) {
578                         IWM_ERR(iwm, "Couldn't invalidate profile\n");
579                         return ret;
580                 }
581         }
582
583         if (chan)
584                 iwm->channel =
585                         ieee80211_frequency_to_channel(chan->center_freq);
586
587         iwm->umac_profile->ssid.ssid_len = sme->ssid_len;
588         memcpy(iwm->umac_profile->ssid.ssid, sme->ssid, sme->ssid_len);
589
590         if (sme->bssid) {
591                 IWM_DBG_WEXT(iwm, DBG, "BSSID: %pM\n", sme->bssid);
592                 memcpy(&iwm->umac_profile->bssid[0], sme->bssid, ETH_ALEN);
593                 iwm->umac_profile->bss_num = 1;
594         } else {
595                 memset(&iwm->umac_profile->bssid[0], 0, ETH_ALEN);
596                 iwm->umac_profile->bss_num = 0;
597         }
598
599         ret = iwm_set_wpa_version(iwm, sme->crypto.wpa_versions);
600         if (ret < 0)
601                 return ret;
602
603         ret = iwm_set_auth_type(iwm, sme->auth_type);
604         if (ret < 0)
605                 return ret;
606
607         if (sme->crypto.n_ciphers_pairwise) {
608                 ret = iwm_set_cipher(iwm, sme->crypto.ciphers_pairwise[0],
609                                      true);
610                 if (ret < 0)
611                         return ret;
612         }
613
614         ret = iwm_set_cipher(iwm, sme->crypto.cipher_group, false);
615         if (ret < 0)
616                 return ret;
617
618         if (sme->crypto.n_akm_suites) {
619                 ret = iwm_set_key_mgt(iwm, sme->crypto.akm_suites[0]);
620                 if (ret < 0)
621                         return ret;
622         }
623
624         /*
625          * We save the WEP key in case we want to do shared authentication.
626          * We have to do it so because UMAC will assert whenever it gets a
627          * key before a profile.
628          */
629         if (sme->key) {
630                 key_param.key = kmemdup(sme->key, sme->key_len, GFP_KERNEL);
631                 if (key_param.key == NULL)
632                         return -ENOMEM;
633                 key_param.key_len = sme->key_len;
634                 key_param.seq_len = 0;
635                 key_param.cipher = sme->crypto.ciphers_pairwise[0];
636
637                 ret = iwm_key_init(&iwm->keys[sme->key_idx], sme->key_idx,
638                                    NULL, &key_param);
639                 kfree(key_param.key);
640                 if (ret < 0) {
641                         IWM_ERR(iwm, "Invalid key_params\n");
642                         return ret;
643                 }
644
645                 iwm->default_key = sme->key_idx;
646         }
647
648         ret = iwm_send_mlme_profile(iwm);
649
650         if (iwm->umac_profile->sec.auth_type != UMAC_AUTH_TYPE_LEGACY_PSK ||
651             sme->key == NULL)
652                 return ret;
653
654         /*
655          * We want to do shared auth.
656          * We need to actually set the key we previously cached,
657          * and then tell the UMAC it's the default one.
658          * That will trigger the auth+assoc UMAC machinery, and again,
659          * this must be done after setting the profile.
660          */
661         ret = iwm_set_key(iwm, 0, &iwm->keys[sme->key_idx]);
662         if (ret < 0)
663                 return ret;
664
665         return iwm_set_tx_key(iwm, iwm->default_key);
666 }
667
668 static int iwm_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
669                                    u16 reason_code)
670 {
671         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
672
673         IWM_DBG_WEXT(iwm, DBG, "Active: %d\n", iwm->umac_profile_active);
674
675         if (iwm->umac_profile_active)
676                 return iwm_invalidate_mlme_profile(iwm);
677
678         return 0;
679 }
680
681 static int iwm_cfg80211_set_txpower(struct wiphy *wiphy,
682                                     enum tx_power_setting type, int dbm)
683 {
684         switch (type) {
685         case TX_POWER_AUTOMATIC:
686                 return 0;
687         default:
688                 return -EOPNOTSUPP;
689         }
690
691         return 0;
692 }
693
694 static int iwm_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
695 {
696         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
697
698         *dbm = iwm->txpower;
699
700         return 0;
701 }
702
703 static int iwm_cfg80211_set_power_mgmt(struct wiphy *wiphy,
704                                        struct net_device *dev,
705                                        bool enabled, int timeout)
706 {
707         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
708         u32 power_index;
709
710         if (enabled)
711                 power_index = IWM_POWER_INDEX_DEFAULT;
712         else
713                 power_index = IWM_POWER_INDEX_MIN;
714
715         if (power_index == iwm->conf.power_index)
716                 return 0;
717
718         iwm->conf.power_index = power_index;
719
720         return iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
721                                        CFG_POWER_INDEX, iwm->conf.power_index);
722 }
723
724 static struct cfg80211_ops iwm_cfg80211_ops = {
725         .change_virtual_intf = iwm_cfg80211_change_iface,
726         .add_key = iwm_cfg80211_add_key,
727         .get_key = iwm_cfg80211_get_key,
728         .del_key = iwm_cfg80211_del_key,
729         .set_default_key = iwm_cfg80211_set_default_key,
730         .get_station = iwm_cfg80211_get_station,
731         .scan = iwm_cfg80211_scan,
732         .set_wiphy_params = iwm_cfg80211_set_wiphy_params,
733         .connect = iwm_cfg80211_connect,
734         .disconnect = iwm_cfg80211_disconnect,
735         .join_ibss = iwm_cfg80211_join_ibss,
736         .leave_ibss = iwm_cfg80211_leave_ibss,
737         .set_tx_power = iwm_cfg80211_set_txpower,
738         .get_tx_power = iwm_cfg80211_get_txpower,
739         .set_power_mgmt = iwm_cfg80211_set_power_mgmt,
740 };
741
742 static const u32 cipher_suites[] = {
743         WLAN_CIPHER_SUITE_WEP40,
744         WLAN_CIPHER_SUITE_WEP104,
745         WLAN_CIPHER_SUITE_TKIP,
746         WLAN_CIPHER_SUITE_CCMP,
747 };
748
749 struct wireless_dev *iwm_wdev_alloc(int sizeof_bus, struct device *dev)
750 {
751         int ret = 0;
752         struct wireless_dev *wdev;
753
754         /*
755          * We're trying to have the following memory
756          * layout:
757          *
758          * +-------------------------+
759          * | struct wiphy            |
760          * +-------------------------+
761          * | struct iwm_priv         |
762          * +-------------------------+
763          * | bus private data        |
764          * | (e.g. iwm_priv_sdio)    |
765          * +-------------------------+
766          *
767          */
768
769         wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
770         if (!wdev) {
771                 dev_err(dev, "Couldn't allocate wireless device\n");
772                 return ERR_PTR(-ENOMEM);
773         }
774
775         wdev->wiphy = wiphy_new(&iwm_cfg80211_ops,
776                                 sizeof(struct iwm_priv) + sizeof_bus);
777         if (!wdev->wiphy) {
778                 dev_err(dev, "Couldn't allocate wiphy device\n");
779                 ret = -ENOMEM;
780                 goto out_err_new;
781         }
782
783         set_wiphy_dev(wdev->wiphy, dev);
784         wdev->wiphy->max_scan_ssids = UMAC_WIFI_IF_PROBE_OPTION_MAX;
785         wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
786                                        BIT(NL80211_IFTYPE_ADHOC);
787         wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &iwm_band_2ghz;
788         wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &iwm_band_5ghz;
789         wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
790
791         wdev->wiphy->cipher_suites = cipher_suites;
792         wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
793
794         ret = wiphy_register(wdev->wiphy);
795         if (ret < 0) {
796                 dev_err(dev, "Couldn't register wiphy device\n");
797                 goto out_err_register;
798         }
799
800         return wdev;
801
802  out_err_register:
803         wiphy_free(wdev->wiphy);
804
805  out_err_new:
806         kfree(wdev);
807
808         return ERR_PTR(ret);
809 }
810
811 void iwm_wdev_free(struct iwm_priv *iwm)
812 {
813         struct wireless_dev *wdev = iwm_to_wdev(iwm);
814
815         if (!wdev)
816                 return;
817
818         wiphy_unregister(wdev->wiphy);
819         wiphy_free(wdev->wiphy);
820         kfree(wdev);
821 }