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 <net/cfg80211.h>
37 #define RATETAB_ENT(_rate, _rateid, _flags) \
40 .hw_value = (_rateid), \
44 #define CHAN2G(_channel, _freq, _flags) { \
45 .band = IEEE80211_BAND_2GHZ, \
46 .center_freq = (_freq), \
47 .hw_value = (_channel), \
49 .max_antenna_gain = 0, \
53 #define CHAN5G(_channel, _flags) { \
54 .band = IEEE80211_BAND_5GHZ, \
55 .center_freq = 5000 + (5 * (_channel)), \
56 .hw_value = (_channel), \
58 .max_antenna_gain = 0, \
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),
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
82 static struct ieee80211_channel iwm_2ghz_channels
[] = {
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),
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
,
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
,
135 static int iwm_key_init(struct iwm_key
*key
, u8 key_index
,
136 const u8
*mac_addr
, struct key_params
*params
)
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
);
143 key
->hdr
.multicast
= 0;
144 memcpy(key
->hdr
.mac
, mac_addr
, ETH_ALEN
);
148 if (params
->key_len
> WLAN_MAX_KEY_LEN
||
149 params
->seq_len
> IW_ENCODE_SEQ_MAX_SIZE
)
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
);
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
)
166 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
167 struct iwm_key
*key
= &iwm
->keys
[key_index
];
170 IWM_DBG_WEXT(iwm
, DBG
, "Adding key for %pM\n", mac_addr
);
172 memset(key
, 0, sizeof(struct iwm_key
));
173 ret
= iwm_key_init(key
, key_index
, mac_addr
, params
);
175 IWM_ERR(iwm
, "Invalid key_params\n");
179 return iwm_set_key(iwm
, 0, key
);
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
,
187 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
188 struct iwm_key
*key
= &iwm
->keys
[key_index
];
189 struct key_params params
;
191 IWM_DBG_WEXT(iwm
, DBG
, "Getting key %d\n", key_index
);
193 memset(¶ms
, 0, sizeof(params
));
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
;
201 callback(cookie
, ¶ms
);
203 return key
->key_len
? 0 : -ENOENT
;
207 static int iwm_cfg80211_del_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
208 u8 key_index
, const u8
*mac_addr
)
210 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
211 struct iwm_key
*key
= &iwm
->keys
[key_index
];
213 if (!iwm
->keys
[key_index
].key_len
) {
214 IWM_DBG_WEXT(iwm
, DBG
, "Key %d not used\n", key_index
);
218 if (key_index
== iwm
->default_key
)
219 iwm
->default_key
= -1;
221 return iwm_set_key(iwm
, 1, key
);
224 static int iwm_cfg80211_set_default_key(struct wiphy
*wiphy
,
225 struct net_device
*ndev
,
228 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
230 IWM_DBG_WEXT(iwm
, DBG
, "Default key index is: %d\n", key_index
);
232 if (!iwm
->keys
[key_index
].key_len
) {
233 IWM_ERR(iwm
, "Key %d not used\n", key_index
);
237 iwm
->default_key
= key_index
;
239 return iwm_set_tx_key(iwm
, key_index
);
242 static int iwm_cfg80211_get_station(struct wiphy
*wiphy
,
243 struct net_device
*ndev
,
244 u8
*mac
, struct station_info
*sinfo
)
246 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
248 if (memcmp(mac
, iwm
->bssid
, ETH_ALEN
))
251 sinfo
->filled
|= STATION_INFO_TX_BITRATE
;
252 sinfo
->txrate
.legacy
= iwm
->rate
* 10;
254 if (test_bit(IWM_STATUS_ASSOCIATED
, &iwm
->status
)) {
255 sinfo
->filled
|= STATION_INFO_SIGNAL
;
256 sinfo
->signal
= iwm
->wstats
.qual
.level
;
263 int iwm_cfg80211_inform_bss(struct iwm_priv
*iwm
)
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
;
274 list_for_each_entry_safe(bss
, next
, &iwm
->bss_list
, node
) {
276 mgmt
= (struct ieee80211_mgmt
*)(umac_bss
->frame_buf
);
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
];
283 IWM_ERR(iwm
, "Invalid band: %d\n", umac_bss
->band
);
287 freq
= ieee80211_channel_to_frequency(umac_bss
->channel
);
288 channel
= ieee80211_get_channel(wiphy
, freq
);
289 signal
= umac_bss
->rssi
* 100;
291 if (!cfg80211_inform_bss_frame(wiphy
, channel
, mgmt
,
292 le16_to_cpu(umac_bss
->frame_len
),
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
)
305 struct wireless_dev
*wdev
;
306 struct iwm_priv
*iwm
;
309 wdev
= ndev
->ieee80211_ptr
;
310 iwm
= ndev_to_iwm(ndev
);
311 old_mode
= iwm
->conf
.mode
;
314 case NL80211_IFTYPE_STATION
:
315 iwm
->conf
.mode
= UMAC_MODE_BSS
;
317 case NL80211_IFTYPE_ADHOC
:
318 iwm
->conf
.mode
= UMAC_MODE_IBSS
;
326 if ((old_mode
== iwm
->conf
.mode
) || !iwm
->umac_profile
)
329 iwm
->umac_profile
->mode
= cpu_to_le32(iwm
->conf
.mode
);
331 if (iwm
->umac_profile_active
)
332 iwm_invalidate_mlme_profile(iwm
);
337 static int iwm_cfg80211_scan(struct wiphy
*wiphy
, struct net_device
*ndev
,
338 struct cfg80211_scan_request
*request
)
340 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
343 if (!test_bit(IWM_STATUS_READY
, &iwm
->status
)) {
344 IWM_ERR(iwm
, "Scan while device is not ready\n");
348 if (test_bit(IWM_STATUS_SCANNING
, &iwm
->status
)) {
349 IWM_ERR(iwm
, "Scanning already\n");
353 if (test_bit(IWM_STATUS_SCAN_ABORTING
, &iwm
->status
)) {
354 IWM_ERR(iwm
, "Scanning being aborted\n");
358 set_bit(IWM_STATUS_SCANNING
, &iwm
->status
);
360 ret
= iwm_scan_ssids(iwm
, request
->ssids
, request
->n_ssids
);
362 clear_bit(IWM_STATUS_SCANNING
, &iwm
->status
);
366 iwm
->scan_request
= request
;
370 static int iwm_cfg80211_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
)
372 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
374 if (changed
& WIPHY_PARAM_RTS_THRESHOLD
&&
375 (iwm
->conf
.rts_threshold
!= wiphy
->rts_threshold
)) {
378 iwm
->conf
.rts_threshold
= wiphy
->rts_threshold
;
380 ret
= iwm_umac_set_config_fix(iwm
, UMAC_PARAM_TBL_CFG_FIX
,
382 iwm
->conf
.rts_threshold
);
387 if (changed
& WIPHY_PARAM_FRAG_THRESHOLD
&&
388 (iwm
->conf
.frag_threshold
!= wiphy
->frag_threshold
)) {
391 iwm
->conf
.frag_threshold
= wiphy
->frag_threshold
;
393 ret
= iwm_umac_set_config_fix(iwm
, UMAC_PARAM_TBL_FA_CFG_FIX
,
395 iwm
->conf
.frag_threshold
);
403 static int iwm_cfg80211_join_ibss(struct wiphy
*wiphy
, struct net_device
*dev
,
404 struct cfg80211_ibss_params
*params
)
406 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
407 struct ieee80211_channel
*chan
= params
->channel
;
408 struct cfg80211_bss
*bss
;
410 if (!test_bit(IWM_STATUS_READY
, &iwm
->status
))
413 /* UMAC doesn't support creating IBSS network with specified bssid.
414 * This should be removed after we have join only mode supported. */
418 bss
= cfg80211_get_ibss(iwm_to_wiphy(iwm
), NULL
,
419 params
->ssid
, params
->ssid_len
);
421 iwm_scan_one_ssid(iwm
, params
->ssid
, params
->ssid_len
);
422 schedule_timeout_interruptible(2 * HZ
);
423 bss
= cfg80211_get_ibss(iwm_to_wiphy(iwm
), NULL
,
424 params
->ssid
, params
->ssid_len
);
426 /* IBSS join only mode is not supported by UMAC ATM */
428 cfg80211_put_bss(bss
);
432 iwm
->channel
= ieee80211_frequency_to_channel(chan
->center_freq
);
433 iwm
->umac_profile
->ibss
.band
= chan
->band
;
434 iwm
->umac_profile
->ibss
.channel
= iwm
->channel
;
435 iwm
->umac_profile
->ssid
.ssid_len
= params
->ssid_len
;
436 memcpy(iwm
->umac_profile
->ssid
.ssid
, params
->ssid
, params
->ssid_len
);
439 memcpy(&iwm
->umac_profile
->bssid
[0], params
->bssid
, ETH_ALEN
);
441 return iwm_send_mlme_profile(iwm
);
444 static int iwm_cfg80211_leave_ibss(struct wiphy
*wiphy
, struct net_device
*dev
)
446 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
448 if (iwm
->umac_profile_active
)
449 return iwm_invalidate_mlme_profile(iwm
);
454 static int iwm_set_auth_type(struct iwm_priv
*iwm
,
455 enum nl80211_auth_type sme_auth_type
)
457 u8
*auth_type
= &iwm
->umac_profile
->sec
.auth_type
;
459 switch (sme_auth_type
) {
460 case NL80211_AUTHTYPE_AUTOMATIC
:
461 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
462 IWM_DBG_WEXT(iwm
, DBG
, "OPEN auth\n");
463 *auth_type
= UMAC_AUTH_TYPE_OPEN
;
465 case NL80211_AUTHTYPE_SHARED_KEY
:
466 if (iwm
->umac_profile
->sec
.flags
&
467 (UMAC_SEC_FLG_WPA_ON_MSK
| UMAC_SEC_FLG_RSNA_ON_MSK
)) {
468 IWM_DBG_WEXT(iwm
, DBG
, "WPA auth alg\n");
469 *auth_type
= UMAC_AUTH_TYPE_RSNA_PSK
;
471 IWM_DBG_WEXT(iwm
, DBG
, "WEP shared key auth alg\n");
472 *auth_type
= UMAC_AUTH_TYPE_LEGACY_PSK
;
477 IWM_ERR(iwm
, "Unsupported auth alg: 0x%x\n", sme_auth_type
);
484 static int iwm_set_wpa_version(struct iwm_priv
*iwm
, u32 wpa_version
)
486 IWM_DBG_WEXT(iwm
, DBG
, "wpa_version: %d\n", wpa_version
);
489 iwm
->umac_profile
->sec
.flags
= UMAC_SEC_FLG_LEGACY_PROFILE
;
493 if (wpa_version
& NL80211_WPA_VERSION_2
)
494 iwm
->umac_profile
->sec
.flags
= UMAC_SEC_FLG_RSNA_ON_MSK
;
496 if (wpa_version
& NL80211_WPA_VERSION_1
)
497 iwm
->umac_profile
->sec
.flags
|= UMAC_SEC_FLG_WPA_ON_MSK
;
502 static int iwm_set_cipher(struct iwm_priv
*iwm
, u32 cipher
, bool ucast
)
504 u8
*profile_cipher
= ucast
? &iwm
->umac_profile
->sec
.ucast_cipher
:
505 &iwm
->umac_profile
->sec
.mcast_cipher
;
508 *profile_cipher
= UMAC_CIPHER_TYPE_NONE
;
512 IWM_DBG_WEXT(iwm
, DBG
, "%ccast cipher is 0x%x\n", ucast
? 'u' : 'm',
516 case IW_AUTH_CIPHER_NONE
:
517 *profile_cipher
= UMAC_CIPHER_TYPE_NONE
;
519 case WLAN_CIPHER_SUITE_WEP40
:
520 *profile_cipher
= UMAC_CIPHER_TYPE_WEP_40
;
522 case WLAN_CIPHER_SUITE_WEP104
:
523 *profile_cipher
= UMAC_CIPHER_TYPE_WEP_104
;
525 case WLAN_CIPHER_SUITE_TKIP
:
526 *profile_cipher
= UMAC_CIPHER_TYPE_TKIP
;
528 case WLAN_CIPHER_SUITE_CCMP
:
529 *profile_cipher
= UMAC_CIPHER_TYPE_CCMP
;
532 IWM_ERR(iwm
, "Unsupported cipher: 0x%x\n", cipher
);
539 static int iwm_set_key_mgt(struct iwm_priv
*iwm
, u32 key_mgt
)
541 u8
*auth_type
= &iwm
->umac_profile
->sec
.auth_type
;
543 IWM_DBG_WEXT(iwm
, DBG
, "key_mgt: 0x%x\n", key_mgt
);
545 if (key_mgt
== WLAN_AKM_SUITE_8021X
)
546 *auth_type
= UMAC_AUTH_TYPE_8021X
;
547 else if (key_mgt
== WLAN_AKM_SUITE_PSK
) {
548 if (iwm
->umac_profile
->sec
.flags
&
549 (UMAC_SEC_FLG_WPA_ON_MSK
| UMAC_SEC_FLG_RSNA_ON_MSK
))
550 *auth_type
= UMAC_AUTH_TYPE_RSNA_PSK
;
552 *auth_type
= UMAC_AUTH_TYPE_LEGACY_PSK
;
554 IWM_ERR(iwm
, "Invalid key mgt: 0x%x\n", key_mgt
);
562 static int iwm_cfg80211_connect(struct wiphy
*wiphy
, struct net_device
*dev
,
563 struct cfg80211_connect_params
*sme
)
565 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
566 struct ieee80211_channel
*chan
= sme
->channel
;
567 struct key_params key_param
;
570 if (!test_bit(IWM_STATUS_READY
, &iwm
->status
))
576 if (iwm
->umac_profile_active
) {
577 ret
= iwm_invalidate_mlme_profile(iwm
);
579 IWM_ERR(iwm
, "Couldn't invalidate profile\n");
586 ieee80211_frequency_to_channel(chan
->center_freq
);
588 iwm
->umac_profile
->ssid
.ssid_len
= sme
->ssid_len
;
589 memcpy(iwm
->umac_profile
->ssid
.ssid
, sme
->ssid
, sme
->ssid_len
);
592 IWM_DBG_WEXT(iwm
, DBG
, "BSSID: %pM\n", sme
->bssid
);
593 memcpy(&iwm
->umac_profile
->bssid
[0], sme
->bssid
, ETH_ALEN
);
594 iwm
->umac_profile
->bss_num
= 1;
596 memset(&iwm
->umac_profile
->bssid
[0], 0, ETH_ALEN
);
597 iwm
->umac_profile
->bss_num
= 0;
600 ret
= iwm_set_wpa_version(iwm
, sme
->crypto
.wpa_versions
);
604 ret
= iwm_set_auth_type(iwm
, sme
->auth_type
);
608 if (sme
->crypto
.n_ciphers_pairwise
) {
609 ret
= iwm_set_cipher(iwm
, sme
->crypto
.ciphers_pairwise
[0],
615 ret
= iwm_set_cipher(iwm
, sme
->crypto
.cipher_group
, false);
619 if (sme
->crypto
.n_akm_suites
) {
620 ret
= iwm_set_key_mgt(iwm
, sme
->crypto
.akm_suites
[0]);
626 * We save the WEP key in case we want to do shared authentication.
627 * We have to do it so because UMAC will assert whenever it gets a
628 * key before a profile.
631 key_param
.key
= kmemdup(sme
->key
, sme
->key_len
, GFP_KERNEL
);
632 if (key_param
.key
== NULL
)
634 key_param
.key_len
= sme
->key_len
;
635 key_param
.seq_len
= 0;
636 key_param
.cipher
= sme
->crypto
.ciphers_pairwise
[0];
638 ret
= iwm_key_init(&iwm
->keys
[sme
->key_idx
], sme
->key_idx
,
640 kfree(key_param
.key
);
642 IWM_ERR(iwm
, "Invalid key_params\n");
646 iwm
->default_key
= sme
->key_idx
;
649 ret
= iwm_send_mlme_profile(iwm
);
651 if (iwm
->umac_profile
->sec
.auth_type
!= UMAC_AUTH_TYPE_LEGACY_PSK
||
656 * We want to do shared auth.
657 * We need to actually set the key we previously cached,
658 * and then tell the UMAC it's the default one.
659 * That will trigger the auth+assoc UMAC machinery, and again,
660 * this must be done after setting the profile.
662 ret
= iwm_set_key(iwm
, 0, &iwm
->keys
[sme
->key_idx
]);
666 return iwm_set_tx_key(iwm
, iwm
->default_key
);
669 static int iwm_cfg80211_disconnect(struct wiphy
*wiphy
, struct net_device
*dev
,
672 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
674 IWM_DBG_WEXT(iwm
, DBG
, "Active: %d\n", iwm
->umac_profile_active
);
676 if (iwm
->umac_profile_active
)
677 iwm_invalidate_mlme_profile(iwm
);
682 static int iwm_cfg80211_set_txpower(struct wiphy
*wiphy
,
683 enum tx_power_setting type
, int dbm
)
686 case TX_POWER_AUTOMATIC
:
695 static int iwm_cfg80211_get_txpower(struct wiphy
*wiphy
, int *dbm
)
697 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
704 static int iwm_cfg80211_set_power_mgmt(struct wiphy
*wiphy
,
705 struct net_device
*dev
,
706 bool enabled
, int timeout
)
708 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
712 power_index
= IWM_POWER_INDEX_DEFAULT
;
714 power_index
= IWM_POWER_INDEX_MIN
;
716 if (power_index
== iwm
->conf
.power_index
)
719 iwm
->conf
.power_index
= power_index
;
721 return iwm_umac_set_config_fix(iwm
, UMAC_PARAM_TBL_CFG_FIX
,
722 CFG_POWER_INDEX
, iwm
->conf
.power_index
);
725 static struct cfg80211_ops iwm_cfg80211_ops
= {
726 .change_virtual_intf
= iwm_cfg80211_change_iface
,
727 .add_key
= iwm_cfg80211_add_key
,
728 .get_key
= iwm_cfg80211_get_key
,
729 .del_key
= iwm_cfg80211_del_key
,
730 .set_default_key
= iwm_cfg80211_set_default_key
,
731 .get_station
= iwm_cfg80211_get_station
,
732 .scan
= iwm_cfg80211_scan
,
733 .set_wiphy_params
= iwm_cfg80211_set_wiphy_params
,
734 .connect
= iwm_cfg80211_connect
,
735 .disconnect
= iwm_cfg80211_disconnect
,
736 .join_ibss
= iwm_cfg80211_join_ibss
,
737 .leave_ibss
= iwm_cfg80211_leave_ibss
,
738 .set_tx_power
= iwm_cfg80211_set_txpower
,
739 .get_tx_power
= iwm_cfg80211_get_txpower
,
740 .set_power_mgmt
= iwm_cfg80211_set_power_mgmt
,
743 static const u32 cipher_suites
[] = {
744 WLAN_CIPHER_SUITE_WEP40
,
745 WLAN_CIPHER_SUITE_WEP104
,
746 WLAN_CIPHER_SUITE_TKIP
,
747 WLAN_CIPHER_SUITE_CCMP
,
750 struct wireless_dev
*iwm_wdev_alloc(int sizeof_bus
, struct device
*dev
)
753 struct wireless_dev
*wdev
;
756 * We're trying to have the following memory
759 * +-------------------------+
761 * +-------------------------+
762 * | struct iwm_priv |
763 * +-------------------------+
764 * | bus private data |
765 * | (e.g. iwm_priv_sdio) |
766 * +-------------------------+
770 wdev
= kzalloc(sizeof(struct wireless_dev
), GFP_KERNEL
);
772 dev_err(dev
, "Couldn't allocate wireless device\n");
773 return ERR_PTR(-ENOMEM
);
776 wdev
->wiphy
= wiphy_new(&iwm_cfg80211_ops
,
777 sizeof(struct iwm_priv
) + sizeof_bus
);
779 dev_err(dev
, "Couldn't allocate wiphy device\n");
784 set_wiphy_dev(wdev
->wiphy
, dev
);
785 wdev
->wiphy
->max_scan_ssids
= UMAC_WIFI_IF_PROBE_OPTION_MAX
;
786 wdev
->wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
) |
787 BIT(NL80211_IFTYPE_ADHOC
);
788 wdev
->wiphy
->bands
[IEEE80211_BAND_2GHZ
] = &iwm_band_2ghz
;
789 wdev
->wiphy
->bands
[IEEE80211_BAND_5GHZ
] = &iwm_band_5ghz
;
790 wdev
->wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
792 wdev
->wiphy
->cipher_suites
= cipher_suites
;
793 wdev
->wiphy
->n_cipher_suites
= ARRAY_SIZE(cipher_suites
);
795 ret
= wiphy_register(wdev
->wiphy
);
797 dev_err(dev
, "Couldn't register wiphy device\n");
798 goto out_err_register
;
804 wiphy_free(wdev
->wiphy
);
812 void iwm_wdev_free(struct iwm_priv
*iwm
)
814 struct wireless_dev
*wdev
= iwm_to_wdev(iwm
);
819 wiphy_unregister(wdev
->wiphy
);
820 wiphy_free(wdev
->wiphy
);