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/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>
38 #define RATETAB_ENT(_rate, _rateid, _flags) \
41 .hw_value = (_rateid), \
45 #define CHAN2G(_channel, _freq, _flags) { \
46 .band = IEEE80211_BAND_2GHZ, \
47 .center_freq = (_freq), \
48 .hw_value = (_channel), \
50 .max_antenna_gain = 0, \
54 #define CHAN5G(_channel, _flags) { \
55 .band = IEEE80211_BAND_5GHZ, \
56 .center_freq = 5000 + (5 * (_channel)), \
57 .hw_value = (_channel), \
59 .max_antenna_gain = 0, \
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[] = {
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),
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);
144 key->hdr.multicast = 0;
145 memcpy(key->hdr.mac, mac_addr, ETH_ALEN);
149 if (params->key_len > WLAN_MAX_KEY_LEN ||
150 params->seq_len > IW_ENCODE_SEQ_MAX_SIZE)
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);
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];
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);
176 IWM_ERR(iwm, "Invalid key_params\n");
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,
186 void (*callback)(void *cookie,
189 struct iwm_priv *iwm = ndev_to_iwm(ndev);
190 struct iwm_key *key = &iwm->keys[key_index];
191 struct key_params params;
193 IWM_DBG_WEXT(iwm, DBG, "Getting key %d\n", key_index);
195 memset(¶ms, 0, sizeof(params));
197 params.cipher = key->cipher;
198 params.key_len = key->key_len;
199 params.seq_len = key->seq_len;
200 params.seq = key->seq;
201 params.key = key->key;
203 callback(cookie, ¶ms);
205 return key->key_len ? 0 : -ENOENT;
209 static int iwm_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
210 u8 key_index, bool pairwise, const u8 *mac_addr)
212 struct iwm_priv *iwm = ndev_to_iwm(ndev);
213 struct iwm_key *key = &iwm->keys[key_index];
215 if (!iwm->keys[key_index].key_len) {
216 IWM_DBG_WEXT(iwm, DBG, "Key %d not used\n", key_index);
220 if (key_index == iwm->default_key)
221 iwm->default_key = -1;
223 return iwm_set_key(iwm, 1, key);
226 static int iwm_cfg80211_set_default_key(struct wiphy *wiphy,
227 struct net_device *ndev,
230 struct iwm_priv *iwm = ndev_to_iwm(ndev);
232 IWM_DBG_WEXT(iwm, DBG, "Default key index is: %d\n", key_index);
234 if (!iwm->keys[key_index].key_len) {
235 IWM_ERR(iwm, "Key %d not used\n", key_index);
239 iwm->default_key = key_index;
241 return iwm_set_tx_key(iwm, key_index);
244 static int iwm_cfg80211_get_station(struct wiphy *wiphy,
245 struct net_device *ndev,
246 u8 *mac, struct station_info *sinfo)
248 struct iwm_priv *iwm = ndev_to_iwm(ndev);
250 if (memcmp(mac, iwm->bssid, ETH_ALEN))
253 sinfo->filled |= STATION_INFO_TX_BITRATE;
254 sinfo->txrate.legacy = iwm->rate * 10;
256 if (test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)) {
257 sinfo->filled |= STATION_INFO_SIGNAL;
258 sinfo->signal = iwm->wstats.qual.level;
265 int iwm_cfg80211_inform_bss(struct iwm_priv *iwm)
267 struct wiphy *wiphy = iwm_to_wiphy(iwm);
268 struct iwm_bss_info *bss;
269 struct iwm_umac_notif_bss_info *umac_bss;
270 struct ieee80211_mgmt *mgmt;
271 struct ieee80211_channel *channel;
272 struct ieee80211_supported_band *band;
276 list_for_each_entry(bss, &iwm->bss_list, node) {
278 mgmt = (struct ieee80211_mgmt *)(umac_bss->frame_buf);
280 if (umac_bss->band == UMAC_BAND_2GHZ)
281 band = wiphy->bands[IEEE80211_BAND_2GHZ];
282 else if (umac_bss->band == UMAC_BAND_5GHZ)
283 band = wiphy->bands[IEEE80211_BAND_5GHZ];
285 IWM_ERR(iwm, "Invalid band: %d\n", umac_bss->band);
289 freq = ieee80211_channel_to_frequency(umac_bss->channel);
290 channel = ieee80211_get_channel(wiphy, freq);
291 signal = umac_bss->rssi * 100;
293 if (!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
294 le16_to_cpu(umac_bss->frame_len),
302 static int iwm_cfg80211_change_iface(struct wiphy *wiphy,
303 struct net_device *ndev,
304 enum nl80211_iftype type, u32 *flags,
305 struct vif_params *params)
307 struct wireless_dev *wdev;
308 struct iwm_priv *iwm;
311 wdev = ndev->ieee80211_ptr;
312 iwm = ndev_to_iwm(ndev);
313 old_mode = iwm->conf.mode;
316 case NL80211_IFTYPE_STATION:
317 iwm->conf.mode = UMAC_MODE_BSS;
319 case NL80211_IFTYPE_ADHOC:
320 iwm->conf.mode = UMAC_MODE_IBSS;
328 if ((old_mode == iwm->conf.mode) || !iwm->umac_profile)
331 iwm->umac_profile->mode = cpu_to_le32(iwm->conf.mode);
333 if (iwm->umac_profile_active)
334 iwm_invalidate_mlme_profile(iwm);
339 static int iwm_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
340 struct cfg80211_scan_request *request)
342 struct iwm_priv *iwm = ndev_to_iwm(ndev);
345 if (!test_bit(IWM_STATUS_READY, &iwm->status)) {
346 IWM_ERR(iwm, "Scan while device is not ready\n");
350 if (test_bit(IWM_STATUS_SCANNING, &iwm->status)) {
351 IWM_ERR(iwm, "Scanning already\n");
355 if (test_bit(IWM_STATUS_SCAN_ABORTING, &iwm->status)) {
356 IWM_ERR(iwm, "Scanning being aborted\n");
360 set_bit(IWM_STATUS_SCANNING, &iwm->status);
362 ret = iwm_scan_ssids(iwm, request->ssids, request->n_ssids);
364 clear_bit(IWM_STATUS_SCANNING, &iwm->status);
368 iwm->scan_request = request;
372 static int iwm_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
374 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
376 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
377 (iwm->conf.rts_threshold != wiphy->rts_threshold)) {
380 iwm->conf.rts_threshold = wiphy->rts_threshold;
382 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
384 iwm->conf.rts_threshold);
389 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
390 (iwm->conf.frag_threshold != wiphy->frag_threshold)) {
393 iwm->conf.frag_threshold = wiphy->frag_threshold;
395 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX,
397 iwm->conf.frag_threshold);
405 static int iwm_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
406 struct cfg80211_ibss_params *params)
408 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
409 struct ieee80211_channel *chan = params->channel;
411 if (!test_bit(IWM_STATUS_READY, &iwm->status))
414 /* UMAC doesn't support creating or joining an IBSS network
415 * with specified bssid. */
419 iwm->channel = ieee80211_frequency_to_channel(chan->center_freq);
420 iwm->umac_profile->ibss.band = chan->band;
421 iwm->umac_profile->ibss.channel = iwm->channel;
422 iwm->umac_profile->ssid.ssid_len = params->ssid_len;
423 memcpy(iwm->umac_profile->ssid.ssid, params->ssid, params->ssid_len);
425 return iwm_send_mlme_profile(iwm);
428 static int iwm_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
430 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
432 if (iwm->umac_profile_active)
433 return iwm_invalidate_mlme_profile(iwm);
438 static int iwm_set_auth_type(struct iwm_priv *iwm,
439 enum nl80211_auth_type sme_auth_type)
441 u8 *auth_type = &iwm->umac_profile->sec.auth_type;
443 switch (sme_auth_type) {
444 case NL80211_AUTHTYPE_AUTOMATIC:
445 case NL80211_AUTHTYPE_OPEN_SYSTEM:
446 IWM_DBG_WEXT(iwm, DBG, "OPEN auth\n");
447 *auth_type = UMAC_AUTH_TYPE_OPEN;
449 case NL80211_AUTHTYPE_SHARED_KEY:
450 if (iwm->umac_profile->sec.flags &
451 (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK)) {
452 IWM_DBG_WEXT(iwm, DBG, "WPA auth alg\n");
453 *auth_type = UMAC_AUTH_TYPE_RSNA_PSK;
455 IWM_DBG_WEXT(iwm, DBG, "WEP shared key auth alg\n");
456 *auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
461 IWM_ERR(iwm, "Unsupported auth alg: 0x%x\n", sme_auth_type);
468 static int iwm_set_wpa_version(struct iwm_priv *iwm, u32 wpa_version)
470 IWM_DBG_WEXT(iwm, DBG, "wpa_version: %d\n", wpa_version);
473 iwm->umac_profile->sec.flags = UMAC_SEC_FLG_LEGACY_PROFILE;
477 if (wpa_version & NL80211_WPA_VERSION_1)
478 iwm->umac_profile->sec.flags = UMAC_SEC_FLG_WPA_ON_MSK;
480 if (wpa_version & NL80211_WPA_VERSION_2)
481 iwm->umac_profile->sec.flags = UMAC_SEC_FLG_RSNA_ON_MSK;
486 static int iwm_set_cipher(struct iwm_priv *iwm, u32 cipher, bool ucast)
488 u8 *profile_cipher = ucast ? &iwm->umac_profile->sec.ucast_cipher :
489 &iwm->umac_profile->sec.mcast_cipher;
492 *profile_cipher = UMAC_CIPHER_TYPE_NONE;
496 IWM_DBG_WEXT(iwm, DBG, "%ccast cipher is 0x%x\n", ucast ? 'u' : 'm',
500 case IW_AUTH_CIPHER_NONE:
501 *profile_cipher = UMAC_CIPHER_TYPE_NONE;
503 case WLAN_CIPHER_SUITE_WEP40:
504 *profile_cipher = UMAC_CIPHER_TYPE_WEP_40;
506 case WLAN_CIPHER_SUITE_WEP104:
507 *profile_cipher = UMAC_CIPHER_TYPE_WEP_104;
509 case WLAN_CIPHER_SUITE_TKIP:
510 *profile_cipher = UMAC_CIPHER_TYPE_TKIP;
512 case WLAN_CIPHER_SUITE_CCMP:
513 *profile_cipher = UMAC_CIPHER_TYPE_CCMP;
516 IWM_ERR(iwm, "Unsupported cipher: 0x%x\n", cipher);
523 static int iwm_set_key_mgt(struct iwm_priv *iwm, u32 key_mgt)
525 u8 *auth_type = &iwm->umac_profile->sec.auth_type;
527 IWM_DBG_WEXT(iwm, DBG, "key_mgt: 0x%x\n", key_mgt);
529 if (key_mgt == WLAN_AKM_SUITE_8021X)
530 *auth_type = UMAC_AUTH_TYPE_8021X;
531 else if (key_mgt == WLAN_AKM_SUITE_PSK) {
532 if (iwm->umac_profile->sec.flags &
533 (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK))
534 *auth_type = UMAC_AUTH_TYPE_RSNA_PSK;
536 *auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
538 IWM_ERR(iwm, "Invalid key mgt: 0x%x\n", key_mgt);
546 static int iwm_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
547 struct cfg80211_connect_params *sme)
549 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
550 struct ieee80211_channel *chan = sme->channel;
551 struct key_params key_param;
554 if (!test_bit(IWM_STATUS_READY, &iwm->status))
560 if (iwm->umac_profile_active) {
561 ret = iwm_invalidate_mlme_profile(iwm);
563 IWM_ERR(iwm, "Couldn't invalidate profile\n");
570 ieee80211_frequency_to_channel(chan->center_freq);
572 iwm->umac_profile->ssid.ssid_len = sme->ssid_len;
573 memcpy(iwm->umac_profile->ssid.ssid, sme->ssid, sme->ssid_len);
576 IWM_DBG_WEXT(iwm, DBG, "BSSID: %pM\n", sme->bssid);
577 memcpy(&iwm->umac_profile->bssid[0], sme->bssid, ETH_ALEN);
578 iwm->umac_profile->bss_num = 1;
580 memset(&iwm->umac_profile->bssid[0], 0, ETH_ALEN);
581 iwm->umac_profile->bss_num = 0;
584 ret = iwm_set_wpa_version(iwm, sme->crypto.wpa_versions);
588 ret = iwm_set_auth_type(iwm, sme->auth_type);
592 if (sme->crypto.n_ciphers_pairwise) {
593 ret = iwm_set_cipher(iwm, sme->crypto.ciphers_pairwise[0],
599 ret = iwm_set_cipher(iwm, sme->crypto.cipher_group, false);
603 if (sme->crypto.n_akm_suites) {
604 ret = iwm_set_key_mgt(iwm, sme->crypto.akm_suites[0]);
610 * We save the WEP key in case we want to do shared authentication.
611 * We have to do it so because UMAC will assert whenever it gets a
612 * key before a profile.
615 key_param.key = kmemdup(sme->key, sme->key_len, GFP_KERNEL);
616 if (key_param.key == NULL)
618 key_param.key_len = sme->key_len;
619 key_param.seq_len = 0;
620 key_param.cipher = sme->crypto.ciphers_pairwise[0];
622 ret = iwm_key_init(&iwm->keys[sme->key_idx], sme->key_idx,
624 kfree(key_param.key);
626 IWM_ERR(iwm, "Invalid key_params\n");
630 iwm->default_key = sme->key_idx;
633 /* WPA and open AUTH type from wpa_s means WPS (a.k.a. WSC) */
634 if ((iwm->umac_profile->sec.flags &
635 (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK)) &&
636 iwm->umac_profile->sec.auth_type == UMAC_AUTH_TYPE_OPEN) {
637 iwm->umac_profile->sec.flags = UMAC_SEC_FLG_WSC_ON_MSK;
640 ret = iwm_send_mlme_profile(iwm);
642 if (iwm->umac_profile->sec.auth_type != UMAC_AUTH_TYPE_LEGACY_PSK ||
647 * We want to do shared auth.
648 * We need to actually set the key we previously cached,
649 * and then tell the UMAC it's the default one.
650 * That will trigger the auth+assoc UMAC machinery, and again,
651 * this must be done after setting the profile.
653 ret = iwm_set_key(iwm, 0, &iwm->keys[sme->key_idx]);
657 return iwm_set_tx_key(iwm, iwm->default_key);
660 static int iwm_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
663 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
665 IWM_DBG_WEXT(iwm, DBG, "Active: %d\n", iwm->umac_profile_active);
667 if (iwm->umac_profile_active)
668 iwm_invalidate_mlme_profile(iwm);
673 static int iwm_cfg80211_set_txpower(struct wiphy *wiphy,
674 enum nl80211_tx_power_setting type, int mbm)
676 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
680 case NL80211_TX_POWER_AUTOMATIC:
682 case NL80211_TX_POWER_FIXED:
683 if (mbm < 0 || (mbm % 100))
686 if (!test_bit(IWM_STATUS_READY, &iwm->status))
689 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
690 CFG_TX_PWR_LIMIT_USR,
691 MBM_TO_DBM(mbm) * 2);
695 return iwm_tx_power_trigger(iwm);
697 IWM_ERR(iwm, "Unsupported power type: %d\n", type);
704 static int iwm_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
706 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
708 *dbm = iwm->txpower >> 1;
713 static int iwm_cfg80211_set_power_mgmt(struct wiphy *wiphy,
714 struct net_device *dev,
715 bool enabled, int timeout)
717 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
721 power_index = IWM_POWER_INDEX_DEFAULT;
723 power_index = IWM_POWER_INDEX_MIN;
725 if (power_index == iwm->conf.power_index)
728 iwm->conf.power_index = power_index;
730 return iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
731 CFG_POWER_INDEX, iwm->conf.power_index);
734 static int iwm_cfg80211_set_pmksa(struct wiphy *wiphy,
735 struct net_device *netdev,
736 struct cfg80211_pmksa *pmksa)
738 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
740 return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_ADD);
743 static int iwm_cfg80211_del_pmksa(struct wiphy *wiphy,
744 struct net_device *netdev,
745 struct cfg80211_pmksa *pmksa)
747 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
749 return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_DEL);
752 static int iwm_cfg80211_flush_pmksa(struct wiphy *wiphy,
753 struct net_device *netdev)
755 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
756 struct cfg80211_pmksa pmksa;
758 memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
760 return iwm_send_pmkid_update(iwm, &pmksa, IWM_CMD_PMKID_FLUSH);
764 static struct cfg80211_ops iwm_cfg80211_ops = {
765 .change_virtual_intf = iwm_cfg80211_change_iface,
766 .add_key = iwm_cfg80211_add_key,
767 .get_key = iwm_cfg80211_get_key,
768 .del_key = iwm_cfg80211_del_key,
769 .set_default_key = iwm_cfg80211_set_default_key,
770 .get_station = iwm_cfg80211_get_station,
771 .scan = iwm_cfg80211_scan,
772 .set_wiphy_params = iwm_cfg80211_set_wiphy_params,
773 .connect = iwm_cfg80211_connect,
774 .disconnect = iwm_cfg80211_disconnect,
775 .join_ibss = iwm_cfg80211_join_ibss,
776 .leave_ibss = iwm_cfg80211_leave_ibss,
777 .set_tx_power = iwm_cfg80211_set_txpower,
778 .get_tx_power = iwm_cfg80211_get_txpower,
779 .set_power_mgmt = iwm_cfg80211_set_power_mgmt,
780 .set_pmksa = iwm_cfg80211_set_pmksa,
781 .del_pmksa = iwm_cfg80211_del_pmksa,
782 .flush_pmksa = iwm_cfg80211_flush_pmksa,
785 static const u32 cipher_suites[] = {
786 WLAN_CIPHER_SUITE_WEP40,
787 WLAN_CIPHER_SUITE_WEP104,
788 WLAN_CIPHER_SUITE_TKIP,
789 WLAN_CIPHER_SUITE_CCMP,
792 struct wireless_dev *iwm_wdev_alloc(int sizeof_bus, struct device *dev)
795 struct wireless_dev *wdev;
798 * We're trying to have the following memory
801 * +-------------------------+
803 * +-------------------------+
804 * | struct iwm_priv |
805 * +-------------------------+
806 * | bus private data |
807 * | (e.g. iwm_priv_sdio) |
808 * +-------------------------+
812 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
814 dev_err(dev, "Couldn't allocate wireless device\n");
815 return ERR_PTR(-ENOMEM);
818 wdev->wiphy = wiphy_new(&iwm_cfg80211_ops,
819 sizeof(struct iwm_priv) + sizeof_bus);
821 dev_err(dev, "Couldn't allocate wiphy device\n");
826 set_wiphy_dev(wdev->wiphy, dev);
827 wdev->wiphy->max_scan_ssids = UMAC_WIFI_IF_PROBE_OPTION_MAX;
828 wdev->wiphy->max_num_pmkids = UMAC_MAX_NUM_PMKIDS;
829 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
830 BIT(NL80211_IFTYPE_ADHOC);
831 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &iwm_band_2ghz;
832 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &iwm_band_5ghz;
833 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
835 wdev->wiphy->cipher_suites = cipher_suites;
836 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
838 ret = wiphy_register(wdev->wiphy);
840 dev_err(dev, "Couldn't register wiphy device\n");
841 goto out_err_register;
847 wiphy_free(wdev->wiphy);
855 void iwm_wdev_free(struct iwm_priv *iwm)
857 struct wireless_dev *wdev = iwm_to_wdev(iwm);
862 wiphy_unregister(wdev->wiphy);
863 wiphy_free(wdev->wiphy);