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