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