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
24 #include <linux/kernel.h>
25 #include <linux/netdevice.h>
26 #include <linux/etherdevice.h>
27 #include <linux/wireless.h>
28 #include <linux/ieee80211.h>
29 #include <net/cfg80211.h>
36 #define RATETAB_ENT(_rate, _rateid, _flags) \
39 .hw_value = (_rateid), \
43 #define CHAN2G(_channel, _freq, _flags) { \
44 .band = IEEE80211_BAND_2GHZ, \
45 .center_freq = (_freq), \
46 .hw_value = (_channel), \
48 .max_antenna_gain = 0, \
52 #define CHAN5G(_channel, _flags) { \
53 .band = IEEE80211_BAND_5GHZ, \
54 .center_freq = 5000 + (5 * (_channel)), \
55 .hw_value = (_channel), \
57 .max_antenna_gain = 0, \
61 static struct ieee80211_rate iwm_rates[] = {
62 RATETAB_ENT(10, 0x1, 0),
63 RATETAB_ENT(20, 0x2, 0),
64 RATETAB_ENT(55, 0x4, 0),
65 RATETAB_ENT(110, 0x8, 0),
66 RATETAB_ENT(60, 0x10, 0),
67 RATETAB_ENT(90, 0x20, 0),
68 RATETAB_ENT(120, 0x40, 0),
69 RATETAB_ENT(180, 0x80, 0),
70 RATETAB_ENT(240, 0x100, 0),
71 RATETAB_ENT(360, 0x200, 0),
72 RATETAB_ENT(480, 0x400, 0),
73 RATETAB_ENT(540, 0x800, 0),
76 #define iwm_a_rates (iwm_rates + 4)
77 #define iwm_a_rates_size 8
78 #define iwm_g_rates (iwm_rates + 0)
79 #define iwm_g_rates_size 12
81 static struct ieee80211_channel iwm_2ghz_channels[] = {
98 static struct ieee80211_channel iwm_5ghz_a_channels[] = {
99 CHAN5G(34, 0), CHAN5G(36, 0),
100 CHAN5G(38, 0), CHAN5G(40, 0),
101 CHAN5G(42, 0), CHAN5G(44, 0),
102 CHAN5G(46, 0), CHAN5G(48, 0),
103 CHAN5G(52, 0), CHAN5G(56, 0),
104 CHAN5G(60, 0), CHAN5G(64, 0),
105 CHAN5G(100, 0), CHAN5G(104, 0),
106 CHAN5G(108, 0), CHAN5G(112, 0),
107 CHAN5G(116, 0), CHAN5G(120, 0),
108 CHAN5G(124, 0), CHAN5G(128, 0),
109 CHAN5G(132, 0), CHAN5G(136, 0),
110 CHAN5G(140, 0), CHAN5G(149, 0),
111 CHAN5G(153, 0), CHAN5G(157, 0),
112 CHAN5G(161, 0), CHAN5G(165, 0),
113 CHAN5G(184, 0), CHAN5G(188, 0),
114 CHAN5G(192, 0), CHAN5G(196, 0),
115 CHAN5G(200, 0), CHAN5G(204, 0),
116 CHAN5G(208, 0), CHAN5G(212, 0),
120 static struct ieee80211_supported_band iwm_band_2ghz = {
121 .channels = iwm_2ghz_channels,
122 .n_channels = ARRAY_SIZE(iwm_2ghz_channels),
123 .bitrates = iwm_g_rates,
124 .n_bitrates = iwm_g_rates_size,
127 static struct ieee80211_supported_band iwm_band_5ghz = {
128 .channels = iwm_5ghz_a_channels,
129 .n_channels = ARRAY_SIZE(iwm_5ghz_a_channels),
130 .bitrates = iwm_a_rates,
131 .n_bitrates = iwm_a_rates_size,
134 static int iwm_key_init(struct iwm_key *key, u8 key_index,
135 const u8 *mac_addr, struct key_params *params)
137 key->hdr.key_idx = key_index;
138 if (!mac_addr || is_broadcast_ether_addr(mac_addr)) {
139 key->hdr.multicast = 1;
140 memset(key->hdr.mac, 0xff, ETH_ALEN);
142 key->hdr.multicast = 0;
143 memcpy(key->hdr.mac, mac_addr, ETH_ALEN);
147 if (params->key_len > WLAN_MAX_KEY_LEN ||
148 params->seq_len > IW_ENCODE_SEQ_MAX_SIZE)
151 key->cipher = params->cipher;
152 key->key_len = params->key_len;
153 key->seq_len = params->seq_len;
154 memcpy(key->key, params->key, key->key_len);
155 memcpy(key->seq, params->seq, key->seq_len);
161 static int iwm_reset_profile(struct iwm_priv *iwm)
165 if (!iwm->umac_profile_active)
169 * If there is a current active profile, but no
170 * default key, it's not worth trying to associate again.
172 if (iwm->default_key < 0)
176 * Here we have an active profile, but a key setting changed.
177 * We thus have to invalidate the current profile, and push the
178 * new one. Keys will be pushed when association takes place.
180 ret = iwm_invalidate_mlme_profile(iwm);
182 IWM_ERR(iwm, "Couldn't invalidate profile\n");
186 return iwm_send_mlme_profile(iwm);
189 static int iwm_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
190 u8 key_index, const u8 *mac_addr,
191 struct key_params *params)
193 struct iwm_priv *iwm = ndev_to_iwm(ndev);
194 struct iwm_key *key = &iwm->keys[key_index];
197 IWM_DBG_WEXT(iwm, DBG, "Adding key for %pM\n", mac_addr);
199 memset(key, 0, sizeof(struct iwm_key));
200 ret = iwm_key_init(key, key_index, mac_addr, params);
202 IWM_ERR(iwm, "Invalid key_params\n");
207 * The WEP keys can be set before or after setting the essid.
208 * We need to handle both cases by simply pushing the keys after
209 * we send the profile.
210 * If the profile is not set yet (i.e. we're pushing keys before
211 * the essid), we set the cipher appropriately.
212 * If the profile is set, we havent associated yet because our
213 * cipher was incorrectly set. So we invalidate and send the
216 if (key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
217 key->cipher == WLAN_CIPHER_SUITE_WEP104) {
218 u8 *ucast_cipher = &iwm->umac_profile->sec.ucast_cipher;
219 u8 *mcast_cipher = &iwm->umac_profile->sec.mcast_cipher;
221 IWM_DBG_WEXT(iwm, DBG, "WEP key\n");
223 if (key->cipher == WLAN_CIPHER_SUITE_WEP40)
224 *ucast_cipher = *mcast_cipher = UMAC_CIPHER_TYPE_WEP_40;
225 if (key->cipher == WLAN_CIPHER_SUITE_WEP104)
226 *ucast_cipher = *mcast_cipher =
227 UMAC_CIPHER_TYPE_WEP_104;
229 return iwm_reset_profile(iwm);
232 return iwm_set_key(iwm, 0, key);
235 static int iwm_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
236 u8 key_index, const u8 *mac_addr, void *cookie,
237 void (*callback)(void *cookie,
240 struct iwm_priv *iwm = ndev_to_iwm(ndev);
241 struct iwm_key *key = &iwm->keys[key_index];
242 struct key_params params;
244 IWM_DBG_WEXT(iwm, DBG, "Getting key %d\n", key_index);
246 memset(¶ms, 0, sizeof(params));
248 params.cipher = key->cipher;
249 params.key_len = key->key_len;
250 params.seq_len = key->seq_len;
251 params.seq = key->seq;
252 params.key = key->key;
254 callback(cookie, ¶ms);
256 return key->key_len ? 0 : -ENOENT;
260 static int iwm_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
261 u8 key_index, const u8 *mac_addr)
263 struct iwm_priv *iwm = ndev_to_iwm(ndev);
264 struct iwm_key *key = &iwm->keys[key_index];
266 if (!iwm->keys[key_index].key_len) {
267 IWM_DBG_WEXT(iwm, DBG, "Key %d not used\n", key_index);
271 if (key_index == iwm->default_key)
272 iwm->default_key = -1;
274 /* If the interface is down, we just cache this */
275 if (!test_bit(IWM_STATUS_READY, &iwm->status))
278 return iwm_set_key(iwm, 1, key);
281 static int iwm_cfg80211_set_default_key(struct wiphy *wiphy,
282 struct net_device *ndev,
285 struct iwm_priv *iwm = ndev_to_iwm(ndev);
288 IWM_DBG_WEXT(iwm, DBG, "Default key index is: %d\n", key_index);
290 if (!iwm->keys[key_index].key_len) {
291 IWM_ERR(iwm, "Key %d not used\n", key_index);
295 iwm->default_key = key_index;
297 /* If the interface is down, we just cache this */
298 if (!test_bit(IWM_STATUS_READY, &iwm->status))
301 ret = iwm_set_tx_key(iwm, key_index);
305 return iwm_reset_profile(iwm);
308 int iwm_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
309 u8 *mac, struct station_info *sinfo)
311 struct iwm_priv *iwm = ndev_to_iwm(ndev);
313 if (memcmp(mac, iwm->bssid, ETH_ALEN))
316 sinfo->filled |= STATION_INFO_TX_BITRATE;
317 sinfo->txrate.legacy = iwm->rate * 10;
319 if (test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)) {
320 sinfo->filled |= STATION_INFO_SIGNAL;
321 sinfo->signal = iwm->wstats.qual.level;
328 int iwm_cfg80211_inform_bss(struct iwm_priv *iwm)
330 struct wiphy *wiphy = iwm_to_wiphy(iwm);
331 struct iwm_bss_info *bss, *next;
332 struct iwm_umac_notif_bss_info *umac_bss;
333 struct ieee80211_mgmt *mgmt;
334 struct ieee80211_channel *channel;
335 struct ieee80211_supported_band *band;
339 list_for_each_entry_safe(bss, next, &iwm->bss_list, node) {
341 mgmt = (struct ieee80211_mgmt *)(umac_bss->frame_buf);
343 if (umac_bss->band == UMAC_BAND_2GHZ)
344 band = wiphy->bands[IEEE80211_BAND_2GHZ];
345 else if (umac_bss->band == UMAC_BAND_5GHZ)
346 band = wiphy->bands[IEEE80211_BAND_5GHZ];
348 IWM_ERR(iwm, "Invalid band: %d\n", umac_bss->band);
352 freq = ieee80211_channel_to_frequency(umac_bss->channel);
353 channel = ieee80211_get_channel(wiphy, freq);
354 signal = umac_bss->rssi * 100;
356 if (!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
357 le16_to_cpu(umac_bss->frame_len),
365 static int iwm_cfg80211_change_iface(struct wiphy *wiphy,
366 struct net_device *ndev,
367 enum nl80211_iftype type, u32 *flags,
368 struct vif_params *params)
370 struct wireless_dev *wdev;
371 struct iwm_priv *iwm;
374 wdev = ndev->ieee80211_ptr;
375 iwm = ndev_to_iwm(ndev);
376 old_mode = iwm->conf.mode;
379 case NL80211_IFTYPE_STATION:
380 iwm->conf.mode = UMAC_MODE_BSS;
382 case NL80211_IFTYPE_ADHOC:
383 iwm->conf.mode = UMAC_MODE_IBSS;
391 if ((old_mode == iwm->conf.mode) || !iwm->umac_profile)
394 iwm->umac_profile->mode = cpu_to_le32(iwm->conf.mode);
396 if (iwm->umac_profile_active) {
397 int ret = iwm_invalidate_mlme_profile(iwm);
399 IWM_ERR(iwm, "Couldn't invalidate profile\n");
405 static int iwm_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
406 struct cfg80211_scan_request *request)
408 struct iwm_priv *iwm = ndev_to_iwm(ndev);
411 if (!test_bit(IWM_STATUS_READY, &iwm->status)) {
412 IWM_ERR(iwm, "Scan while device is not ready\n");
416 if (test_bit(IWM_STATUS_SCANNING, &iwm->status)) {
417 IWM_ERR(iwm, "Scanning already\n");
421 if (test_bit(IWM_STATUS_SCAN_ABORTING, &iwm->status)) {
422 IWM_ERR(iwm, "Scanning being aborted\n");
426 set_bit(IWM_STATUS_SCANNING, &iwm->status);
428 ret = iwm_scan_ssids(iwm, request->ssids, request->n_ssids);
430 clear_bit(IWM_STATUS_SCANNING, &iwm->status);
434 iwm->scan_request = request;
438 static int iwm_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
440 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
442 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
443 (iwm->conf.rts_threshold != wiphy->rts_threshold)) {
446 iwm->conf.rts_threshold = wiphy->rts_threshold;
448 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
450 iwm->conf.rts_threshold);
455 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
456 (iwm->conf.frag_threshold != wiphy->frag_threshold)) {
459 iwm->conf.frag_threshold = wiphy->frag_threshold;
461 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX,
463 iwm->conf.frag_threshold);
471 static int iwm_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
472 struct cfg80211_ibss_params *params)
474 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
475 struct ieee80211_channel *chan = params->channel;
476 struct cfg80211_bss *bss;
478 if (!test_bit(IWM_STATUS_READY, &iwm->status))
481 /* UMAC doesn't support creating IBSS network with specified bssid.
482 * This should be removed after we have join only mode supported. */
486 bss = cfg80211_get_ibss(iwm_to_wiphy(iwm), NULL,
487 params->ssid, params->ssid_len);
489 iwm_scan_one_ssid(iwm, params->ssid, params->ssid_len);
490 schedule_timeout_interruptible(2 * HZ);
491 bss = cfg80211_get_ibss(iwm_to_wiphy(iwm), NULL,
492 params->ssid, params->ssid_len);
494 /* IBSS join only mode is not supported by UMAC ATM */
496 cfg80211_put_bss(bss);
500 iwm->channel = ieee80211_frequency_to_channel(chan->center_freq);
501 iwm->umac_profile->ibss.band = chan->band;
502 iwm->umac_profile->ibss.channel = iwm->channel;
503 iwm->umac_profile->ssid.ssid_len = params->ssid_len;
504 memcpy(iwm->umac_profile->ssid.ssid, params->ssid, params->ssid_len);
507 memcpy(&iwm->umac_profile->bssid[0], params->bssid, ETH_ALEN);
509 return iwm_send_mlme_profile(iwm);
512 static int iwm_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
514 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
516 if (iwm->umac_profile_active)
517 return iwm_invalidate_mlme_profile(iwm);
522 static int iwm_set_auth_type(struct iwm_priv *iwm,
523 enum nl80211_auth_type sme_auth_type)
525 u8 *auth_type = &iwm->umac_profile->sec.auth_type;
527 switch (sme_auth_type) {
528 case NL80211_AUTHTYPE_AUTOMATIC:
529 case NL80211_AUTHTYPE_OPEN_SYSTEM:
530 IWM_DBG_WEXT(iwm, DBG, "OPEN auth\n");
531 *auth_type = UMAC_AUTH_TYPE_OPEN;
533 case NL80211_AUTHTYPE_SHARED_KEY:
534 if (iwm->umac_profile->sec.flags &
535 (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK)) {
536 IWM_DBG_WEXT(iwm, DBG, "WPA auth alg\n");
537 *auth_type = UMAC_AUTH_TYPE_RSNA_PSK;
539 IWM_DBG_WEXT(iwm, DBG, "WEP shared key auth alg\n");
540 *auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
545 IWM_ERR(iwm, "Unsupported auth alg: 0x%x\n", sme_auth_type);
552 static int iwm_set_wpa_version(struct iwm_priv *iwm, u32 wpa_version)
555 iwm->umac_profile->sec.flags = UMAC_SEC_FLG_LEGACY_PROFILE;
559 if (wpa_version & NL80211_WPA_VERSION_2)
560 iwm->umac_profile->sec.flags = UMAC_SEC_FLG_RSNA_ON_MSK;
562 if (wpa_version & NL80211_WPA_VERSION_1)
563 iwm->umac_profile->sec.flags |= UMAC_SEC_FLG_WPA_ON_MSK;
568 static int iwm_set_cipher(struct iwm_priv *iwm, u32 cipher, bool ucast)
570 u8 *profile_cipher = ucast ? &iwm->umac_profile->sec.ucast_cipher :
571 &iwm->umac_profile->sec.mcast_cipher;
574 *profile_cipher = UMAC_CIPHER_TYPE_NONE;
579 case IW_AUTH_CIPHER_NONE:
580 *profile_cipher = UMAC_CIPHER_TYPE_NONE;
582 case WLAN_CIPHER_SUITE_WEP40:
583 *profile_cipher = UMAC_CIPHER_TYPE_WEP_40;
585 case WLAN_CIPHER_SUITE_WEP104:
586 *profile_cipher = UMAC_CIPHER_TYPE_WEP_104;
588 case WLAN_CIPHER_SUITE_TKIP:
589 *profile_cipher = UMAC_CIPHER_TYPE_TKIP;
591 case WLAN_CIPHER_SUITE_CCMP:
592 *profile_cipher = UMAC_CIPHER_TYPE_CCMP;
595 IWM_ERR(iwm, "Unsupported cipher: 0x%x\n", cipher);
602 static int iwm_set_key_mgt(struct iwm_priv *iwm, u32 key_mgt)
604 u8 *auth_type = &iwm->umac_profile->sec.auth_type;
606 IWM_DBG_WEXT(iwm, DBG, "key_mgt: 0x%x\n", key_mgt);
608 if (key_mgt == WLAN_AKM_SUITE_8021X)
609 *auth_type = UMAC_AUTH_TYPE_8021X;
610 else if (key_mgt == WLAN_AKM_SUITE_PSK) {
611 if (iwm->umac_profile->sec.flags &
612 (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK))
613 *auth_type = UMAC_AUTH_TYPE_RSNA_PSK;
615 *auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
617 IWM_ERR(iwm, "Invalid key mgt: 0x%x\n", key_mgt);
625 static int iwm_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
626 struct cfg80211_connect_params *sme)
628 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
629 struct ieee80211_channel *chan = sme->channel;
632 if (!test_bit(IWM_STATUS_READY, &iwm->status))
640 ieee80211_frequency_to_channel(chan->center_freq);
642 iwm->umac_profile->ssid.ssid_len = sme->ssid_len;
643 memcpy(iwm->umac_profile->ssid.ssid, sme->ssid, sme->ssid_len);
646 IWM_DBG_WEXT(iwm, DBG, "BSSID: %pM\n", sme->bssid);
647 memcpy(&iwm->umac_profile->bssid[0], sme->bssid, ETH_ALEN);
648 iwm->umac_profile->bss_num = 1;
650 memset(&iwm->umac_profile->bssid[0], 0, ETH_ALEN);
651 iwm->umac_profile->bss_num = 0;
654 ret = iwm_set_auth_type(iwm, sme->auth_type);
658 ret = iwm_set_wpa_version(iwm, sme->crypto.wpa_versions);
662 if (sme->crypto.n_ciphers_pairwise) {
663 ret = iwm_set_cipher(iwm, sme->crypto.ciphers_pairwise[0],
669 ret = iwm_set_cipher(iwm, sme->crypto.cipher_group, false);
673 if (sme->crypto.n_akm_suites) {
674 ret = iwm_set_key_mgt(iwm, sme->crypto.akm_suites[0]);
679 return iwm_send_mlme_profile(iwm);
682 static int iwm_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
685 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
687 IWM_DBG_WEXT(iwm, DBG, "Active: %d\n", iwm->umac_profile_active);
689 if (iwm->umac_profile_active)
690 return iwm_invalidate_mlme_profile(iwm);
695 static int iwm_cfg80211_set_txpower(struct wiphy *wiphy,
696 enum tx_power_setting type, int dbm)
699 case TX_POWER_AUTOMATIC:
708 static int iwm_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
710 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
717 static int iwm_cfg80211_set_power_mgmt(struct wiphy *wiphy,
718 struct net_device *dev,
719 bool enabled, int timeout)
721 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
725 power_index = IWM_POWER_INDEX_DEFAULT;
727 power_index = IWM_POWER_INDEX_MIN;
729 if (power_index == iwm->conf.power_index)
732 iwm->conf.power_index = power_index;
734 return iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
735 CFG_POWER_INDEX, iwm->conf.power_index);
738 static struct cfg80211_ops iwm_cfg80211_ops = {
739 .change_virtual_intf = iwm_cfg80211_change_iface,
740 .add_key = iwm_cfg80211_add_key,
741 .get_key = iwm_cfg80211_get_key,
742 .del_key = iwm_cfg80211_del_key,
743 .set_default_key = iwm_cfg80211_set_default_key,
744 .get_station = iwm_cfg80211_get_station,
745 .scan = iwm_cfg80211_scan,
746 .set_wiphy_params = iwm_cfg80211_set_wiphy_params,
747 .connect = iwm_cfg80211_connect,
748 .disconnect = iwm_cfg80211_disconnect,
749 .join_ibss = iwm_cfg80211_join_ibss,
750 .leave_ibss = iwm_cfg80211_leave_ibss,
751 .set_tx_power = iwm_cfg80211_set_txpower,
752 .get_tx_power = iwm_cfg80211_get_txpower,
753 .set_power_mgmt = iwm_cfg80211_set_power_mgmt,
756 static const u32 cipher_suites[] = {
757 WLAN_CIPHER_SUITE_WEP40,
758 WLAN_CIPHER_SUITE_WEP104,
759 WLAN_CIPHER_SUITE_TKIP,
760 WLAN_CIPHER_SUITE_CCMP,
763 struct wireless_dev *iwm_wdev_alloc(int sizeof_bus, struct device *dev)
766 struct wireless_dev *wdev;
769 * We're trying to have the following memory
772 * +-------------------------+
774 * +-------------------------+
775 * | struct iwm_priv |
776 * +-------------------------+
777 * | bus private data |
778 * | (e.g. iwm_priv_sdio) |
779 * +-------------------------+
783 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
785 dev_err(dev, "Couldn't allocate wireless device\n");
786 return ERR_PTR(-ENOMEM);
789 wdev->wiphy = wiphy_new(&iwm_cfg80211_ops,
790 sizeof(struct iwm_priv) + sizeof_bus);
792 dev_err(dev, "Couldn't allocate wiphy device\n");
797 set_wiphy_dev(wdev->wiphy, dev);
798 wdev->wiphy->max_scan_ssids = UMAC_WIFI_IF_PROBE_OPTION_MAX;
799 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
800 BIT(NL80211_IFTYPE_ADHOC);
801 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &iwm_band_2ghz;
802 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &iwm_band_5ghz;
803 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
805 wdev->wiphy->cipher_suites = cipher_suites;
806 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
808 ret = wiphy_register(wdev->wiphy);
810 dev_err(dev, "Couldn't register wiphy device\n");
811 goto out_err_register;
817 wiphy_free(wdev->wiphy);
825 void iwm_wdev_free(struct iwm_priv *iwm)
827 struct wireless_dev *wdev = iwm_to_wdev(iwm);
832 wiphy_unregister(wdev->wiphy);
833 wiphy_free(wdev->wiphy);