]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/net/wireless/iwmc3200wifi/cfg80211.c
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[mv-sheeva.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, bool pairwise, 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, bool pairwise, const u8 *mac_addr,
185                                 void *cookie,
186                                 void (*callback)(void *cookie,
187                                                  struct key_params*))
188 {
189         struct iwm_priv *iwm = ndev_to_iwm(ndev);
190         struct iwm_key *key = &iwm->keys[key_index];
191         struct key_params params;
192
193         IWM_DBG_WEXT(iwm, DBG, "Getting key %d\n", key_index);
194
195         memset(&params, 0, sizeof(params));
196
197         params.cipher = key->cipher;
198         params.key_len = key->key_len;
199         params.seq_len = key->seq_len;
200         params.seq = key->seq;
201         params.key = key->key;
202
203         callback(cookie, &params);
204
205         return key->key_len ? 0 : -ENOENT;
206 }
207
208
209 static int iwm_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
210                                 u8 key_index, bool pairwise, const u8 *mac_addr)
211 {
212         struct iwm_priv *iwm = ndev_to_iwm(ndev);
213         struct iwm_key *key = &iwm->keys[key_index];
214
215         if (!iwm->keys[key_index].key_len) {
216                 IWM_DBG_WEXT(iwm, DBG, "Key %d not used\n", key_index);
217                 return 0;
218         }
219
220         if (key_index == iwm->default_key)
221                 iwm->default_key = -1;
222
223         return iwm_set_key(iwm, 1, key);
224 }
225
226 static int iwm_cfg80211_set_default_key(struct wiphy *wiphy,
227                                         struct net_device *ndev,
228                                         u8 key_index, bool unicast,
229                                         bool multicast)
230 {
231         struct iwm_priv *iwm = ndev_to_iwm(ndev);
232
233         IWM_DBG_WEXT(iwm, DBG, "Default key index is: %d\n", key_index);
234
235         if (!iwm->keys[key_index].key_len) {
236                 IWM_ERR(iwm, "Key %d not used\n", key_index);
237                 return -EINVAL;
238         }
239
240         iwm->default_key = key_index;
241
242         return iwm_set_tx_key(iwm, key_index);
243 }
244
245 static int iwm_cfg80211_get_station(struct wiphy *wiphy,
246                                     struct net_device *ndev,
247                                     u8 *mac, struct station_info *sinfo)
248 {
249         struct iwm_priv *iwm = ndev_to_iwm(ndev);
250
251         if (memcmp(mac, iwm->bssid, ETH_ALEN))
252                 return -ENOENT;
253
254         sinfo->filled |= STATION_INFO_TX_BITRATE;
255         sinfo->txrate.legacy = iwm->rate * 10;
256
257         if (test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)) {
258                 sinfo->filled |= STATION_INFO_SIGNAL;
259                 sinfo->signal = iwm->wstats.qual.level;
260         }
261
262         return 0;
263 }
264
265
266 int iwm_cfg80211_inform_bss(struct iwm_priv *iwm)
267 {
268         struct wiphy *wiphy = iwm_to_wiphy(iwm);
269         struct iwm_bss_info *bss;
270         struct iwm_umac_notif_bss_info *umac_bss;
271         struct ieee80211_mgmt *mgmt;
272         struct ieee80211_channel *channel;
273         struct ieee80211_supported_band *band;
274         s32 signal;
275         int freq;
276
277         list_for_each_entry(bss, &iwm->bss_list, node) {
278                 umac_bss = bss->bss;
279                 mgmt = (struct ieee80211_mgmt *)(umac_bss->frame_buf);
280
281                 if (umac_bss->band == UMAC_BAND_2GHZ)
282                         band = wiphy->bands[IEEE80211_BAND_2GHZ];
283                 else if (umac_bss->band == UMAC_BAND_5GHZ)
284                         band = wiphy->bands[IEEE80211_BAND_5GHZ];
285                 else {
286                         IWM_ERR(iwm, "Invalid band: %d\n", umac_bss->band);
287                         return -EINVAL;
288                 }
289
290                 freq = ieee80211_channel_to_frequency(umac_bss->channel);
291                 channel = ieee80211_get_channel(wiphy, freq);
292                 signal = umac_bss->rssi * 100;
293
294                 if (!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
295                                                le16_to_cpu(umac_bss->frame_len),
296                                                signal, GFP_KERNEL))
297                         return -EINVAL;
298         }
299
300         return 0;
301 }
302
303 static int iwm_cfg80211_change_iface(struct wiphy *wiphy,
304                                      struct net_device *ndev,
305                                      enum nl80211_iftype type, u32 *flags,
306                                      struct vif_params *params)
307 {
308         struct wireless_dev *wdev;
309         struct iwm_priv *iwm;
310         u32 old_mode;
311
312         wdev = ndev->ieee80211_ptr;
313         iwm = ndev_to_iwm(ndev);
314         old_mode = iwm->conf.mode;
315
316         switch (type) {
317         case NL80211_IFTYPE_STATION:
318                 iwm->conf.mode = UMAC_MODE_BSS;
319                 break;
320         case NL80211_IFTYPE_ADHOC:
321                 iwm->conf.mode = UMAC_MODE_IBSS;
322                 break;
323         default:
324                 return -EOPNOTSUPP;
325         }
326
327         wdev->iftype = type;
328
329         if ((old_mode == iwm->conf.mode) || !iwm->umac_profile)
330                 return 0;
331
332         iwm->umac_profile->mode = cpu_to_le32(iwm->conf.mode);
333
334         if (iwm->umac_profile_active)
335                 iwm_invalidate_mlme_profile(iwm);
336
337         return 0;
338 }
339
340 static int iwm_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
341                              struct cfg80211_scan_request *request)
342 {
343         struct iwm_priv *iwm = ndev_to_iwm(ndev);
344         int ret;
345
346         if (!test_bit(IWM_STATUS_READY, &iwm->status)) {
347                 IWM_ERR(iwm, "Scan while device is not ready\n");
348                 return -EIO;
349         }
350
351         if (test_bit(IWM_STATUS_SCANNING, &iwm->status)) {
352                 IWM_ERR(iwm, "Scanning already\n");
353                 return -EAGAIN;
354         }
355
356         if (test_bit(IWM_STATUS_SCAN_ABORTING, &iwm->status)) {
357                 IWM_ERR(iwm, "Scanning being aborted\n");
358                 return -EAGAIN;
359         }
360
361         set_bit(IWM_STATUS_SCANNING, &iwm->status);
362
363         ret = iwm_scan_ssids(iwm, request->ssids, request->n_ssids);
364         if (ret) {
365                 clear_bit(IWM_STATUS_SCANNING, &iwm->status);
366                 return ret;
367         }
368
369         iwm->scan_request = request;
370         return 0;
371 }
372
373 static int iwm_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
374 {
375         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
376
377         if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
378             (iwm->conf.rts_threshold != wiphy->rts_threshold)) {
379                 int ret;
380
381                 iwm->conf.rts_threshold = wiphy->rts_threshold;
382
383                 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
384                                              CFG_RTS_THRESHOLD,
385                                              iwm->conf.rts_threshold);
386                 if (ret < 0)
387                         return ret;
388         }
389
390         if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
391             (iwm->conf.frag_threshold != wiphy->frag_threshold)) {
392                 int ret;
393
394                 iwm->conf.frag_threshold = wiphy->frag_threshold;
395
396                 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX,
397                                              CFG_FRAG_THRESHOLD,
398                                              iwm->conf.frag_threshold);
399                 if (ret < 0)
400                         return ret;
401         }
402
403         return 0;
404 }
405
406 static int iwm_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
407                                   struct cfg80211_ibss_params *params)
408 {
409         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
410         struct ieee80211_channel *chan = params->channel;
411
412         if (!test_bit(IWM_STATUS_READY, &iwm->status))
413                 return -EIO;
414
415         /* UMAC doesn't support creating or joining an IBSS network
416          * with specified bssid. */
417         if (params->bssid)
418                 return -EOPNOTSUPP;
419
420         iwm->channel = ieee80211_frequency_to_channel(chan->center_freq);
421         iwm->umac_profile->ibss.band = chan->band;
422         iwm->umac_profile->ibss.channel = iwm->channel;
423         iwm->umac_profile->ssid.ssid_len = params->ssid_len;
424         memcpy(iwm->umac_profile->ssid.ssid, params->ssid, params->ssid_len);
425
426         return iwm_send_mlme_profile(iwm);
427 }
428
429 static int iwm_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
430 {
431         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
432
433         if (iwm->umac_profile_active)
434                 return iwm_invalidate_mlme_profile(iwm);
435
436         return 0;
437 }
438
439 static int iwm_set_auth_type(struct iwm_priv *iwm,
440                              enum nl80211_auth_type sme_auth_type)
441 {
442         u8 *auth_type = &iwm->umac_profile->sec.auth_type;
443
444         switch (sme_auth_type) {
445         case NL80211_AUTHTYPE_AUTOMATIC:
446         case NL80211_AUTHTYPE_OPEN_SYSTEM:
447                 IWM_DBG_WEXT(iwm, DBG, "OPEN auth\n");
448                 *auth_type = UMAC_AUTH_TYPE_OPEN;
449                 break;
450         case NL80211_AUTHTYPE_SHARED_KEY:
451                 if (iwm->umac_profile->sec.flags &
452                     (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK)) {
453                         IWM_DBG_WEXT(iwm, DBG, "WPA auth alg\n");
454                         *auth_type = UMAC_AUTH_TYPE_RSNA_PSK;
455                 } else {
456                         IWM_DBG_WEXT(iwm, DBG, "WEP shared key auth alg\n");
457                         *auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
458                 }
459
460                 break;
461         default:
462                 IWM_ERR(iwm, "Unsupported auth alg: 0x%x\n", sme_auth_type);
463                 return -ENOTSUPP;
464         }
465
466         return 0;
467 }
468
469 static int iwm_set_wpa_version(struct iwm_priv *iwm, u32 wpa_version)
470 {
471         IWM_DBG_WEXT(iwm, DBG, "wpa_version: %d\n", wpa_version);
472
473         if (!wpa_version) {
474                 iwm->umac_profile->sec.flags = UMAC_SEC_FLG_LEGACY_PROFILE;
475                 return 0;
476         }
477
478         if (wpa_version & NL80211_WPA_VERSION_1)
479                 iwm->umac_profile->sec.flags = UMAC_SEC_FLG_WPA_ON_MSK;
480
481         if (wpa_version & NL80211_WPA_VERSION_2)
482                 iwm->umac_profile->sec.flags = UMAC_SEC_FLG_RSNA_ON_MSK;
483
484         return 0;
485 }
486
487 static int iwm_set_cipher(struct iwm_priv *iwm, u32 cipher, bool ucast)
488 {
489         u8 *profile_cipher = ucast ? &iwm->umac_profile->sec.ucast_cipher :
490                 &iwm->umac_profile->sec.mcast_cipher;
491
492         if (!cipher) {
493                 *profile_cipher = UMAC_CIPHER_TYPE_NONE;
494                 return 0;
495         }
496
497         IWM_DBG_WEXT(iwm, DBG, "%ccast cipher is 0x%x\n", ucast ? 'u' : 'm',
498                      cipher);
499
500         switch (cipher) {
501         case IW_AUTH_CIPHER_NONE:
502                 *profile_cipher = UMAC_CIPHER_TYPE_NONE;
503                 break;
504         case WLAN_CIPHER_SUITE_WEP40:
505                 *profile_cipher = UMAC_CIPHER_TYPE_WEP_40;
506                 break;
507         case WLAN_CIPHER_SUITE_WEP104:
508                 *profile_cipher = UMAC_CIPHER_TYPE_WEP_104;
509                 break;
510         case WLAN_CIPHER_SUITE_TKIP:
511                 *profile_cipher = UMAC_CIPHER_TYPE_TKIP;
512                 break;
513         case WLAN_CIPHER_SUITE_CCMP:
514                 *profile_cipher = UMAC_CIPHER_TYPE_CCMP;
515                 break;
516         default:
517                 IWM_ERR(iwm, "Unsupported cipher: 0x%x\n", cipher);
518                 return -ENOTSUPP;
519         }
520
521         return 0;
522 }
523
524 static int iwm_set_key_mgt(struct iwm_priv *iwm, u32 key_mgt)
525 {
526         u8 *auth_type = &iwm->umac_profile->sec.auth_type;
527
528         IWM_DBG_WEXT(iwm, DBG, "key_mgt: 0x%x\n", key_mgt);
529
530         if (key_mgt == WLAN_AKM_SUITE_8021X)
531                 *auth_type = UMAC_AUTH_TYPE_8021X;
532         else if (key_mgt == WLAN_AKM_SUITE_PSK) {
533                 if (iwm->umac_profile->sec.flags &
534                     (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK))
535                         *auth_type = UMAC_AUTH_TYPE_RSNA_PSK;
536                 else
537                         *auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
538         } else {
539                 IWM_ERR(iwm, "Invalid key mgt: 0x%x\n", key_mgt);
540                 return -EINVAL;
541         }
542
543         return 0;
544 }
545
546
547 static int iwm_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
548                                  struct cfg80211_connect_params *sme)
549 {
550         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
551         struct ieee80211_channel *chan = sme->channel;
552         struct key_params key_param;
553         int ret;
554
555         if (!test_bit(IWM_STATUS_READY, &iwm->status))
556                 return -EIO;
557
558         if (!sme->ssid)
559                 return -EINVAL;
560
561         if (iwm->umac_profile_active) {
562                 ret = iwm_invalidate_mlme_profile(iwm);
563                 if (ret) {
564                         IWM_ERR(iwm, "Couldn't invalidate profile\n");
565                         return ret;
566                 }
567         }
568
569         if (chan)
570                 iwm->channel =
571                         ieee80211_frequency_to_channel(chan->center_freq);
572
573         iwm->umac_profile->ssid.ssid_len = sme->ssid_len;
574         memcpy(iwm->umac_profile->ssid.ssid, sme->ssid, sme->ssid_len);
575
576         if (sme->bssid) {
577                 IWM_DBG_WEXT(iwm, DBG, "BSSID: %pM\n", sme->bssid);
578                 memcpy(&iwm->umac_profile->bssid[0], sme->bssid, ETH_ALEN);
579                 iwm->umac_profile->bss_num = 1;
580         } else {
581                 memset(&iwm->umac_profile->bssid[0], 0, ETH_ALEN);
582                 iwm->umac_profile->bss_num = 0;
583         }
584
585         ret = iwm_set_wpa_version(iwm, sme->crypto.wpa_versions);
586         if (ret < 0)
587                 return ret;
588
589         ret = iwm_set_auth_type(iwm, sme->auth_type);
590         if (ret < 0)
591                 return ret;
592
593         if (sme->crypto.n_ciphers_pairwise) {
594                 ret = iwm_set_cipher(iwm, sme->crypto.ciphers_pairwise[0],
595                                      true);
596                 if (ret < 0)
597                         return ret;
598         }
599
600         ret = iwm_set_cipher(iwm, sme->crypto.cipher_group, false);
601         if (ret < 0)
602                 return ret;
603
604         if (sme->crypto.n_akm_suites) {
605                 ret = iwm_set_key_mgt(iwm, sme->crypto.akm_suites[0]);
606                 if (ret < 0)
607                         return ret;
608         }
609
610         /*
611          * We save the WEP key in case we want to do shared authentication.
612          * We have to do it so because UMAC will assert whenever it gets a
613          * key before a profile.
614          */
615         if (sme->key) {
616                 key_param.key = kmemdup(sme->key, sme->key_len, GFP_KERNEL);
617                 if (key_param.key == NULL)
618                         return -ENOMEM;
619                 key_param.key_len = sme->key_len;
620                 key_param.seq_len = 0;
621                 key_param.cipher = sme->crypto.ciphers_pairwise[0];
622
623                 ret = iwm_key_init(&iwm->keys[sme->key_idx], sme->key_idx,
624                                    NULL, &key_param);
625                 kfree(key_param.key);
626                 if (ret < 0) {
627                         IWM_ERR(iwm, "Invalid key_params\n");
628                         return ret;
629                 }
630
631                 iwm->default_key = sme->key_idx;
632         }
633
634         /* WPA and open AUTH type from wpa_s means WPS (a.k.a. WSC) */
635         if ((iwm->umac_profile->sec.flags &
636              (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK)) &&
637             iwm->umac_profile->sec.auth_type == UMAC_AUTH_TYPE_OPEN) {
638                         iwm->umac_profile->sec.flags = UMAC_SEC_FLG_WSC_ON_MSK;
639         }
640
641         ret = iwm_send_mlme_profile(iwm);
642
643         if (iwm->umac_profile->sec.auth_type != UMAC_AUTH_TYPE_LEGACY_PSK ||
644             sme->key == NULL)
645                 return ret;
646
647         /*
648          * We want to do shared auth.
649          * We need to actually set the key we previously cached,
650          * and then tell the UMAC it's the default one.
651          * That will trigger the auth+assoc UMAC machinery, and again,
652          * this must be done after setting the profile.
653          */
654         ret = iwm_set_key(iwm, 0, &iwm->keys[sme->key_idx]);
655         if (ret < 0)
656                 return ret;
657
658         return iwm_set_tx_key(iwm, iwm->default_key);
659 }
660
661 static int iwm_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
662                                    u16 reason_code)
663 {
664         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
665
666         IWM_DBG_WEXT(iwm, DBG, "Active: %d\n", iwm->umac_profile_active);
667
668         if (iwm->umac_profile_active)
669                 iwm_invalidate_mlme_profile(iwm);
670
671         return 0;
672 }
673
674 static int iwm_cfg80211_set_txpower(struct wiphy *wiphy,
675                                     enum nl80211_tx_power_setting type, int mbm)
676 {
677         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
678         int ret;
679
680         switch (type) {
681         case NL80211_TX_POWER_AUTOMATIC:
682                 return 0;
683         case NL80211_TX_POWER_FIXED:
684                 if (mbm < 0 || (mbm % 100))
685                         return -EOPNOTSUPP;
686
687                 if (!test_bit(IWM_STATUS_READY, &iwm->status))
688                         return 0;
689
690                 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
691                                               CFG_TX_PWR_LIMIT_USR,
692                                               MBM_TO_DBM(mbm) * 2);
693                 if (ret < 0)
694                         return ret;
695
696                 return iwm_tx_power_trigger(iwm);
697         default:
698                 IWM_ERR(iwm, "Unsupported power type: %d\n", type);
699                 return -EOPNOTSUPP;
700         }
701
702         return 0;
703 }
704
705 static int iwm_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
706 {
707         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
708
709         *dbm = iwm->txpower >> 1;
710
711         return 0;
712 }
713
714 static int iwm_cfg80211_set_power_mgmt(struct wiphy *wiphy,
715                                        struct net_device *dev,
716                                        bool enabled, int timeout)
717 {
718         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
719         u32 power_index;
720
721         if (enabled)
722                 power_index = IWM_POWER_INDEX_DEFAULT;
723         else
724                 power_index = IWM_POWER_INDEX_MIN;
725
726         if (power_index == iwm->conf.power_index)
727                 return 0;
728
729         iwm->conf.power_index = power_index;
730
731         return iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
732                                        CFG_POWER_INDEX, iwm->conf.power_index);
733 }
734
735 static int iwm_cfg80211_set_pmksa(struct wiphy *wiphy,
736                                   struct net_device *netdev,
737                                   struct cfg80211_pmksa *pmksa)
738 {
739         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
740
741         return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_ADD);
742 }
743
744 static int iwm_cfg80211_del_pmksa(struct wiphy *wiphy,
745                                   struct net_device *netdev,
746                                   struct cfg80211_pmksa *pmksa)
747 {
748         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
749
750         return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_DEL);
751 }
752
753 static int iwm_cfg80211_flush_pmksa(struct wiphy *wiphy,
754                                     struct net_device *netdev)
755 {
756         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
757         struct cfg80211_pmksa pmksa;
758
759         memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
760
761         return iwm_send_pmkid_update(iwm, &pmksa, IWM_CMD_PMKID_FLUSH);
762 }
763
764
765 static struct cfg80211_ops iwm_cfg80211_ops = {
766         .change_virtual_intf = iwm_cfg80211_change_iface,
767         .add_key = iwm_cfg80211_add_key,
768         .get_key = iwm_cfg80211_get_key,
769         .del_key = iwm_cfg80211_del_key,
770         .set_default_key = iwm_cfg80211_set_default_key,
771         .get_station = iwm_cfg80211_get_station,
772         .scan = iwm_cfg80211_scan,
773         .set_wiphy_params = iwm_cfg80211_set_wiphy_params,
774         .connect = iwm_cfg80211_connect,
775         .disconnect = iwm_cfg80211_disconnect,
776         .join_ibss = iwm_cfg80211_join_ibss,
777         .leave_ibss = iwm_cfg80211_leave_ibss,
778         .set_tx_power = iwm_cfg80211_set_txpower,
779         .get_tx_power = iwm_cfg80211_get_txpower,
780         .set_power_mgmt = iwm_cfg80211_set_power_mgmt,
781         .set_pmksa = iwm_cfg80211_set_pmksa,
782         .del_pmksa = iwm_cfg80211_del_pmksa,
783         .flush_pmksa = iwm_cfg80211_flush_pmksa,
784 };
785
786 static const u32 cipher_suites[] = {
787         WLAN_CIPHER_SUITE_WEP40,
788         WLAN_CIPHER_SUITE_WEP104,
789         WLAN_CIPHER_SUITE_TKIP,
790         WLAN_CIPHER_SUITE_CCMP,
791 };
792
793 struct wireless_dev *iwm_wdev_alloc(int sizeof_bus, struct device *dev)
794 {
795         int ret = 0;
796         struct wireless_dev *wdev;
797
798         /*
799          * We're trying to have the following memory
800          * layout:
801          *
802          * +-------------------------+
803          * | struct wiphy            |
804          * +-------------------------+
805          * | struct iwm_priv         |
806          * +-------------------------+
807          * | bus private data        |
808          * | (e.g. iwm_priv_sdio)    |
809          * +-------------------------+
810          *
811          */
812
813         wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
814         if (!wdev) {
815                 dev_err(dev, "Couldn't allocate wireless device\n");
816                 return ERR_PTR(-ENOMEM);
817         }
818
819         wdev->wiphy = wiphy_new(&iwm_cfg80211_ops,
820                                 sizeof(struct iwm_priv) + sizeof_bus);
821         if (!wdev->wiphy) {
822                 dev_err(dev, "Couldn't allocate wiphy device\n");
823                 ret = -ENOMEM;
824                 goto out_err_new;
825         }
826
827         set_wiphy_dev(wdev->wiphy, dev);
828         wdev->wiphy->max_scan_ssids = UMAC_WIFI_IF_PROBE_OPTION_MAX;
829         wdev->wiphy->max_num_pmkids = UMAC_MAX_NUM_PMKIDS;
830         wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
831                                        BIT(NL80211_IFTYPE_ADHOC);
832         wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &iwm_band_2ghz;
833         wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &iwm_band_5ghz;
834         wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
835
836         wdev->wiphy->cipher_suites = cipher_suites;
837         wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
838
839         ret = wiphy_register(wdev->wiphy);
840         if (ret < 0) {
841                 dev_err(dev, "Couldn't register wiphy device\n");
842                 goto out_err_register;
843         }
844
845         return wdev;
846
847  out_err_register:
848         wiphy_free(wdev->wiphy);
849
850  out_err_new:
851         kfree(wdev);
852
853         return ERR_PTR(ret);
854 }
855
856 void iwm_wdev_free(struct iwm_priv *iwm)
857 {
858         struct wireless_dev *wdev = iwm_to_wdev(iwm);
859
860         if (!wdev)
861                 return;
862
863         wiphy_unregister(wdev->wiphy);
864         wiphy_free(wdev->wiphy);
865         kfree(wdev);
866 }