Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[linux-btrfs-devel.git] / drivers / net / wireless / iwmc3200wifi / cfg80211.c
blobc42be81e979ebd700742154922acce4fcb6acde7
1 /*
2 * Intel Wireless Multicomm 3200 WiFi driver
4 * Copyright (C) 2009 Intel Corporation <ilw@linux.intel.com>
5 * Samuel Ortiz <samuel.ortiz@intel.com>
6 * Zhu Yi <yi.zhu@intel.com>
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.
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.
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.
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>
33 #include "iwm.h"
34 #include "commands.h"
35 #include "cfg80211.h"
36 #include "debug.h"
38 #define RATETAB_ENT(_rate, _rateid, _flags) \
39 { \
40 .bitrate = (_rate), \
41 .hw_value = (_rateid), \
42 .flags = (_flags), \
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, \
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, \
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),
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
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),
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),
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,
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,
136 static int iwm_key_init(struct iwm_key *key, u8 key_index,
137 const u8 *mac_addr, struct key_params *params)
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);
148 if (params) {
149 if (params->key_len > WLAN_MAX_KEY_LEN ||
150 params->seq_len > IW_ENCODE_SEQ_MAX_SIZE)
151 return -EINVAL;
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);
160 return 0;
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)
167 struct iwm_priv *iwm = ndev_to_iwm(ndev);
168 struct iwm_key *key = &iwm->keys[key_index];
169 int ret;
171 IWM_DBG_WEXT(iwm, DBG, "Adding key for %pM\n", mac_addr);
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;
180 return iwm_set_key(iwm, 0, key);
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*))
189 struct iwm_priv *iwm = ndev_to_iwm(ndev);
190 struct iwm_key *key;
191 struct key_params params;
193 IWM_DBG_WEXT(iwm, DBG, "Getting key %d\n", key_index);
195 if (key_index >= IWM_NUM_KEYS)
196 return -ENOENT;
198 memset(&params, 0, sizeof(params));
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;
207 callback(cookie, &params);
209 return key->key_len ? 0 : -ENOENT;
213 static int iwm_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
214 u8 key_index, bool pairwise, const u8 *mac_addr)
216 struct iwm_priv *iwm = ndev_to_iwm(ndev);
217 struct iwm_key *key = &iwm->keys[key_index];
219 if (!iwm->keys[key_index].key_len) {
220 IWM_DBG_WEXT(iwm, DBG, "Key %d not used\n", key_index);
221 return 0;
224 if (key_index == iwm->default_key)
225 iwm->default_key = -1;
227 return iwm_set_key(iwm, 1, key);
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)
235 struct iwm_priv *iwm = ndev_to_iwm(ndev);
237 IWM_DBG_WEXT(iwm, DBG, "Default key index is: %d\n", key_index);
239 if (!iwm->keys[key_index].key_len) {
240 IWM_ERR(iwm, "Key %d not used\n", key_index);
241 return -EINVAL;
244 iwm->default_key = key_index;
246 return iwm_set_tx_key(iwm, key_index);
249 static int iwm_cfg80211_get_station(struct wiphy *wiphy,
250 struct net_device *ndev,
251 u8 *mac, struct station_info *sinfo)
253 struct iwm_priv *iwm = ndev_to_iwm(ndev);
255 if (memcmp(mac, iwm->bssid, ETH_ALEN))
256 return -ENOENT;
258 sinfo->filled |= STATION_INFO_TX_BITRATE;
259 sinfo->txrate.legacy = iwm->rate * 10;
261 if (test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)) {
262 sinfo->filled |= STATION_INFO_SIGNAL;
263 sinfo->signal = iwm->wstats.qual.level;
266 return 0;
270 int iwm_cfg80211_inform_bss(struct iwm_priv *iwm)
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;
281 list_for_each_entry(bss, &iwm->bss_list, node) {
282 umac_bss = bss->bss;
283 mgmt = (struct ieee80211_mgmt *)(umac_bss->frame_buf);
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;
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;
299 if (!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
300 le16_to_cpu(umac_bss->frame_len),
301 signal, GFP_KERNEL))
302 return -EINVAL;
305 return 0;
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)
313 struct wireless_dev *wdev;
314 struct iwm_priv *iwm;
315 u32 old_mode;
317 wdev = ndev->ieee80211_ptr;
318 iwm = ndev_to_iwm(ndev);
319 old_mode = iwm->conf.mode;
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;
332 wdev->iftype = type;
334 if ((old_mode == iwm->conf.mode) || !iwm->umac_profile)
335 return 0;
337 iwm->umac_profile->mode = cpu_to_le32(iwm->conf.mode);
339 if (iwm->umac_profile_active)
340 iwm_invalidate_mlme_profile(iwm);
342 return 0;
345 static int iwm_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
346 struct cfg80211_scan_request *request)
348 struct iwm_priv *iwm = ndev_to_iwm(ndev);
349 int ret;
351 if (!test_bit(IWM_STATUS_READY, &iwm->status)) {
352 IWM_ERR(iwm, "Scan while device is not ready\n");
353 return -EIO;
356 if (test_bit(IWM_STATUS_SCANNING, &iwm->status)) {
357 IWM_ERR(iwm, "Scanning already\n");
358 return -EAGAIN;
361 if (test_bit(IWM_STATUS_SCAN_ABORTING, &iwm->status)) {
362 IWM_ERR(iwm, "Scanning being aborted\n");
363 return -EAGAIN;
366 set_bit(IWM_STATUS_SCANNING, &iwm->status);
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;
374 iwm->scan_request = request;
375 return 0;
378 static int iwm_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
380 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
382 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
383 (iwm->conf.rts_threshold != wiphy->rts_threshold)) {
384 int ret;
386 iwm->conf.rts_threshold = wiphy->rts_threshold;
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;
395 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
396 (iwm->conf.frag_threshold != wiphy->frag_threshold)) {
397 int ret;
399 iwm->conf.frag_threshold = wiphy->frag_threshold;
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;
408 return 0;
411 static int iwm_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
412 struct cfg80211_ibss_params *params)
414 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
415 struct ieee80211_channel *chan = params->channel;
417 if (!test_bit(IWM_STATUS_READY, &iwm->status))
418 return -EIO;
420 /* UMAC doesn't support creating or joining an IBSS network
421 * with specified bssid. */
422 if (params->bssid)
423 return -EOPNOTSUPP;
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);
431 return iwm_send_mlme_profile(iwm);
434 static int iwm_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
436 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
438 if (iwm->umac_profile_active)
439 return iwm_invalidate_mlme_profile(iwm);
441 return 0;
444 static int iwm_set_auth_type(struct iwm_priv *iwm,
445 enum nl80211_auth_type sme_auth_type)
447 u8 *auth_type = &iwm->umac_profile->sec.auth_type;
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;
465 break;
466 default:
467 IWM_ERR(iwm, "Unsupported auth alg: 0x%x\n", sme_auth_type);
468 return -ENOTSUPP;
471 return 0;
474 static int iwm_set_wpa_version(struct iwm_priv *iwm, u32 wpa_version)
476 IWM_DBG_WEXT(iwm, DBG, "wpa_version: %d\n", wpa_version);
478 if (!wpa_version) {
479 iwm->umac_profile->sec.flags = UMAC_SEC_FLG_LEGACY_PROFILE;
480 return 0;
483 if (wpa_version & NL80211_WPA_VERSION_1)
484 iwm->umac_profile->sec.flags = UMAC_SEC_FLG_WPA_ON_MSK;
486 if (wpa_version & NL80211_WPA_VERSION_2)
487 iwm->umac_profile->sec.flags = UMAC_SEC_FLG_RSNA_ON_MSK;
489 return 0;
492 static int iwm_set_cipher(struct iwm_priv *iwm, u32 cipher, bool ucast)
494 u8 *profile_cipher = ucast ? &iwm->umac_profile->sec.ucast_cipher :
495 &iwm->umac_profile->sec.mcast_cipher;
497 if (!cipher) {
498 *profile_cipher = UMAC_CIPHER_TYPE_NONE;
499 return 0;
502 IWM_DBG_WEXT(iwm, DBG, "%ccast cipher is 0x%x\n", ucast ? 'u' : 'm',
503 cipher);
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;
526 return 0;
529 static int iwm_set_key_mgt(struct iwm_priv *iwm, u32 key_mgt)
531 u8 *auth_type = &iwm->umac_profile->sec.auth_type;
533 IWM_DBG_WEXT(iwm, DBG, "key_mgt: 0x%x\n", key_mgt);
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;
548 return 0;
552 static int iwm_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
553 struct cfg80211_connect_params *sme)
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;
560 if (!test_bit(IWM_STATUS_READY, &iwm->status))
561 return -EIO;
563 if (!sme->ssid)
564 return -EINVAL;
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;
574 if (chan)
575 iwm->channel =
576 ieee80211_frequency_to_channel(chan->center_freq);
578 iwm->umac_profile->ssid.ssid_len = sme->ssid_len;
579 memcpy(iwm->umac_profile->ssid.ssid, sme->ssid, sme->ssid_len);
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;
590 ret = iwm_set_wpa_version(iwm, sme->crypto.wpa_versions);
591 if (ret < 0)
592 return ret;
594 ret = iwm_set_auth_type(iwm, sme->auth_type);
595 if (ret < 0)
596 return ret;
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;
605 ret = iwm_set_cipher(iwm, sme->crypto.cipher_group, false);
606 if (ret < 0)
607 return ret;
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;
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.
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];
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;
636 iwm->default_key = sme->key_idx;
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;
646 ret = iwm_send_mlme_profile(iwm);
648 if (iwm->umac_profile->sec.auth_type != UMAC_AUTH_TYPE_LEGACY_PSK ||
649 sme->key == NULL)
650 return ret;
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.
659 ret = iwm_set_key(iwm, 0, &iwm->keys[sme->key_idx]);
660 if (ret < 0)
661 return ret;
663 return iwm_set_tx_key(iwm, iwm->default_key);
666 static int iwm_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
667 u16 reason_code)
669 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
671 IWM_DBG_WEXT(iwm, DBG, "Active: %d\n", iwm->umac_profile_active);
673 if (iwm->umac_profile_active)
674 iwm_invalidate_mlme_profile(iwm);
676 return 0;
679 static int iwm_cfg80211_set_txpower(struct wiphy *wiphy,
680 enum nl80211_tx_power_setting type, int mbm)
682 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
683 int ret;
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;
692 if (!test_bit(IWM_STATUS_READY, &iwm->status))
693 return 0;
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;
701 return iwm_tx_power_trigger(iwm);
702 default:
703 IWM_ERR(iwm, "Unsupported power type: %d\n", type);
704 return -EOPNOTSUPP;
707 return 0;
710 static int iwm_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
712 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
714 *dbm = iwm->txpower >> 1;
716 return 0;
719 static int iwm_cfg80211_set_power_mgmt(struct wiphy *wiphy,
720 struct net_device *dev,
721 bool enabled, int timeout)
723 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
724 u32 power_index;
726 if (enabled)
727 power_index = IWM_POWER_INDEX_DEFAULT;
728 else
729 power_index = IWM_POWER_INDEX_MIN;
731 if (power_index == iwm->conf.power_index)
732 return 0;
734 iwm->conf.power_index = power_index;
736 return iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
737 CFG_POWER_INDEX, iwm->conf.power_index);
740 static int iwm_cfg80211_set_pmksa(struct wiphy *wiphy,
741 struct net_device *netdev,
742 struct cfg80211_pmksa *pmksa)
744 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
746 return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_ADD);
749 static int iwm_cfg80211_del_pmksa(struct wiphy *wiphy,
750 struct net_device *netdev,
751 struct cfg80211_pmksa *pmksa)
753 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
755 return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_DEL);
758 static int iwm_cfg80211_flush_pmksa(struct wiphy *wiphy,
759 struct net_device *netdev)
761 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
762 struct cfg80211_pmksa pmksa;
764 memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
766 return iwm_send_pmkid_update(iwm, &pmksa, IWM_CMD_PMKID_FLUSH);
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,
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,
798 struct wireless_dev *iwm_wdev_alloc(int sizeof_bus, struct device *dev)
800 int ret = 0;
801 struct wireless_dev *wdev;
804 * We're trying to have the following memory
805 * layout:
807 * +-------------------------+
808 * | struct wiphy |
809 * +-------------------------+
810 * | struct iwm_priv |
811 * +-------------------------+
812 * | bus private data |
813 * | (e.g. iwm_priv_sdio) |
814 * +-------------------------+
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);
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;
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;
841 wdev->wiphy->cipher_suites = cipher_suites;
842 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
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;
850 return wdev;
852 out_err_register:
853 wiphy_free(wdev->wiphy);
855 out_err_new:
856 kfree(wdev);
858 return ERR_PTR(ret);
861 void iwm_wdev_free(struct iwm_priv *iwm)
863 struct wireless_dev *wdev = iwm_to_wdev(iwm);
865 if (!wdev)
866 return;
868 wiphy_unregister(wdev->wiphy);
869 wiphy_free(wdev->wiphy);
870 kfree(wdev);