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_cfg80211_add_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
162 u8 key_index
, const u8
*mac_addr
,
163 struct key_params
*params
)
165 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
166 struct iwm_key
*key
= &iwm
->keys
[key_index
];
169 IWM_DBG_WEXT(iwm
, DBG
, "Adding key for %pM\n", mac_addr
);
171 memset(key
, 0, sizeof(struct iwm_key
));
172 ret
= iwm_key_init(key
, key_index
, mac_addr
, params
);
174 IWM_ERR(iwm
, "Invalid key_params\n");
178 return iwm_set_key(iwm
, 0, key
);
181 static int iwm_cfg80211_get_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
182 u8 key_index
, const u8
*mac_addr
, void *cookie
,
183 void (*callback
)(void *cookie
,
186 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
187 struct iwm_key
*key
= &iwm
->keys
[key_index
];
188 struct key_params params
;
190 IWM_DBG_WEXT(iwm
, DBG
, "Getting key %d\n", key_index
);
192 memset(¶ms
, 0, sizeof(params
));
194 params
.cipher
= key
->cipher
;
195 params
.key_len
= key
->key_len
;
196 params
.seq_len
= key
->seq_len
;
197 params
.seq
= key
->seq
;
198 params
.key
= key
->key
;
200 callback(cookie
, ¶ms
);
202 return key
->key_len
? 0 : -ENOENT
;
206 static int iwm_cfg80211_del_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
207 u8 key_index
, const u8
*mac_addr
)
209 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
210 struct iwm_key
*key
= &iwm
->keys
[key_index
];
212 if (!iwm
->keys
[key_index
].key_len
) {
213 IWM_DBG_WEXT(iwm
, DBG
, "Key %d not used\n", key_index
);
217 if (key_index
== iwm
->default_key
)
218 iwm
->default_key
= -1;
220 return iwm_set_key(iwm
, 1, key
);
223 static int iwm_cfg80211_set_default_key(struct wiphy
*wiphy
,
224 struct net_device
*ndev
,
227 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
229 IWM_DBG_WEXT(iwm
, DBG
, "Default key index is: %d\n", key_index
);
231 if (!iwm
->keys
[key_index
].key_len
) {
232 IWM_ERR(iwm
, "Key %d not used\n", key_index
);
236 iwm
->default_key
= key_index
;
238 return iwm_set_tx_key(iwm
, key_index
);
241 static int iwm_cfg80211_get_station(struct wiphy
*wiphy
,
242 struct net_device
*ndev
,
243 u8
*mac
, struct station_info
*sinfo
)
245 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
247 if (memcmp(mac
, iwm
->bssid
, ETH_ALEN
))
250 sinfo
->filled
|= STATION_INFO_TX_BITRATE
;
251 sinfo
->txrate
.legacy
= iwm
->rate
* 10;
253 if (test_bit(IWM_STATUS_ASSOCIATED
, &iwm
->status
)) {
254 sinfo
->filled
|= STATION_INFO_SIGNAL
;
255 sinfo
->signal
= iwm
->wstats
.qual
.level
;
262 int iwm_cfg80211_inform_bss(struct iwm_priv
*iwm
)
264 struct wiphy
*wiphy
= iwm_to_wiphy(iwm
);
265 struct iwm_bss_info
*bss
, *next
;
266 struct iwm_umac_notif_bss_info
*umac_bss
;
267 struct ieee80211_mgmt
*mgmt
;
268 struct ieee80211_channel
*channel
;
269 struct ieee80211_supported_band
*band
;
273 list_for_each_entry_safe(bss
, next
, &iwm
->bss_list
, node
) {
275 mgmt
= (struct ieee80211_mgmt
*)(umac_bss
->frame_buf
);
277 if (umac_bss
->band
== UMAC_BAND_2GHZ
)
278 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
279 else if (umac_bss
->band
== UMAC_BAND_5GHZ
)
280 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
282 IWM_ERR(iwm
, "Invalid band: %d\n", umac_bss
->band
);
286 freq
= ieee80211_channel_to_frequency(umac_bss
->channel
);
287 channel
= ieee80211_get_channel(wiphy
, freq
);
288 signal
= umac_bss
->rssi
* 100;
290 if (!cfg80211_inform_bss_frame(wiphy
, channel
, mgmt
,
291 le16_to_cpu(umac_bss
->frame_len
),
299 static int iwm_cfg80211_change_iface(struct wiphy
*wiphy
,
300 struct net_device
*ndev
,
301 enum nl80211_iftype type
, u32
*flags
,
302 struct vif_params
*params
)
304 struct wireless_dev
*wdev
;
305 struct iwm_priv
*iwm
;
308 wdev
= ndev
->ieee80211_ptr
;
309 iwm
= ndev_to_iwm(ndev
);
310 old_mode
= iwm
->conf
.mode
;
313 case NL80211_IFTYPE_STATION
:
314 iwm
->conf
.mode
= UMAC_MODE_BSS
;
316 case NL80211_IFTYPE_ADHOC
:
317 iwm
->conf
.mode
= UMAC_MODE_IBSS
;
325 if ((old_mode
== iwm
->conf
.mode
) || !iwm
->umac_profile
)
328 iwm
->umac_profile
->mode
= cpu_to_le32(iwm
->conf
.mode
);
330 if (iwm
->umac_profile_active
)
331 iwm_invalidate_mlme_profile(iwm
);
336 static int iwm_cfg80211_scan(struct wiphy
*wiphy
, struct net_device
*ndev
,
337 struct cfg80211_scan_request
*request
)
339 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
342 if (!test_bit(IWM_STATUS_READY
, &iwm
->status
)) {
343 IWM_ERR(iwm
, "Scan while device is not ready\n");
347 if (test_bit(IWM_STATUS_SCANNING
, &iwm
->status
)) {
348 IWM_ERR(iwm
, "Scanning already\n");
352 if (test_bit(IWM_STATUS_SCAN_ABORTING
, &iwm
->status
)) {
353 IWM_ERR(iwm
, "Scanning being aborted\n");
357 set_bit(IWM_STATUS_SCANNING
, &iwm
->status
);
359 ret
= iwm_scan_ssids(iwm
, request
->ssids
, request
->n_ssids
);
361 clear_bit(IWM_STATUS_SCANNING
, &iwm
->status
);
365 iwm
->scan_request
= request
;
369 static int iwm_cfg80211_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
)
371 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
373 if (changed
& WIPHY_PARAM_RTS_THRESHOLD
&&
374 (iwm
->conf
.rts_threshold
!= wiphy
->rts_threshold
)) {
377 iwm
->conf
.rts_threshold
= wiphy
->rts_threshold
;
379 ret
= iwm_umac_set_config_fix(iwm
, UMAC_PARAM_TBL_CFG_FIX
,
381 iwm
->conf
.rts_threshold
);
386 if (changed
& WIPHY_PARAM_FRAG_THRESHOLD
&&
387 (iwm
->conf
.frag_threshold
!= wiphy
->frag_threshold
)) {
390 iwm
->conf
.frag_threshold
= wiphy
->frag_threshold
;
392 ret
= iwm_umac_set_config_fix(iwm
, UMAC_PARAM_TBL_FA_CFG_FIX
,
394 iwm
->conf
.frag_threshold
);
402 static int iwm_cfg80211_join_ibss(struct wiphy
*wiphy
, struct net_device
*dev
,
403 struct cfg80211_ibss_params
*params
)
405 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
406 struct ieee80211_channel
*chan
= params
->channel
;
407 struct cfg80211_bss
*bss
;
409 if (!test_bit(IWM_STATUS_READY
, &iwm
->status
))
412 /* UMAC doesn't support creating IBSS network with specified bssid.
413 * This should be removed after we have join only mode supported. */
417 bss
= cfg80211_get_ibss(iwm_to_wiphy(iwm
), NULL
,
418 params
->ssid
, params
->ssid_len
);
420 iwm_scan_one_ssid(iwm
, params
->ssid
, params
->ssid_len
);
421 schedule_timeout_interruptible(2 * HZ
);
422 bss
= cfg80211_get_ibss(iwm_to_wiphy(iwm
), NULL
,
423 params
->ssid
, params
->ssid_len
);
425 /* IBSS join only mode is not supported by UMAC ATM */
427 cfg80211_put_bss(bss
);
431 iwm
->channel
= ieee80211_frequency_to_channel(chan
->center_freq
);
432 iwm
->umac_profile
->ibss
.band
= chan
->band
;
433 iwm
->umac_profile
->ibss
.channel
= iwm
->channel
;
434 iwm
->umac_profile
->ssid
.ssid_len
= params
->ssid_len
;
435 memcpy(iwm
->umac_profile
->ssid
.ssid
, params
->ssid
, params
->ssid_len
);
438 memcpy(&iwm
->umac_profile
->bssid
[0], params
->bssid
, ETH_ALEN
);
440 return iwm_send_mlme_profile(iwm
);
443 static int iwm_cfg80211_leave_ibss(struct wiphy
*wiphy
, struct net_device
*dev
)
445 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
447 if (iwm
->umac_profile_active
)
448 return iwm_invalidate_mlme_profile(iwm
);
453 static int iwm_set_auth_type(struct iwm_priv
*iwm
,
454 enum nl80211_auth_type sme_auth_type
)
456 u8
*auth_type
= &iwm
->umac_profile
->sec
.auth_type
;
458 switch (sme_auth_type
) {
459 case NL80211_AUTHTYPE_AUTOMATIC
:
460 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
461 IWM_DBG_WEXT(iwm
, DBG
, "OPEN auth\n");
462 *auth_type
= UMAC_AUTH_TYPE_OPEN
;
464 case NL80211_AUTHTYPE_SHARED_KEY
:
465 if (iwm
->umac_profile
->sec
.flags
&
466 (UMAC_SEC_FLG_WPA_ON_MSK
| UMAC_SEC_FLG_RSNA_ON_MSK
)) {
467 IWM_DBG_WEXT(iwm
, DBG
, "WPA auth alg\n");
468 *auth_type
= UMAC_AUTH_TYPE_RSNA_PSK
;
470 IWM_DBG_WEXT(iwm
, DBG
, "WEP shared key auth alg\n");
471 *auth_type
= UMAC_AUTH_TYPE_LEGACY_PSK
;
476 IWM_ERR(iwm
, "Unsupported auth alg: 0x%x\n", sme_auth_type
);
483 static int iwm_set_wpa_version(struct iwm_priv
*iwm
, u32 wpa_version
)
485 IWM_DBG_WEXT(iwm
, DBG
, "wpa_version: %d\n", wpa_version
);
488 iwm
->umac_profile
->sec
.flags
= UMAC_SEC_FLG_LEGACY_PROFILE
;
492 if (wpa_version
& NL80211_WPA_VERSION_2
)
493 iwm
->umac_profile
->sec
.flags
= UMAC_SEC_FLG_RSNA_ON_MSK
;
495 if (wpa_version
& NL80211_WPA_VERSION_1
)
496 iwm
->umac_profile
->sec
.flags
|= UMAC_SEC_FLG_WPA_ON_MSK
;
501 static int iwm_set_cipher(struct iwm_priv
*iwm
, u32 cipher
, bool ucast
)
503 u8
*profile_cipher
= ucast
? &iwm
->umac_profile
->sec
.ucast_cipher
:
504 &iwm
->umac_profile
->sec
.mcast_cipher
;
507 *profile_cipher
= UMAC_CIPHER_TYPE_NONE
;
511 IWM_DBG_WEXT(iwm
, DBG
, "%ccast cipher is 0x%x\n", ucast
? 'u' : 'm',
515 case IW_AUTH_CIPHER_NONE
:
516 *profile_cipher
= UMAC_CIPHER_TYPE_NONE
;
518 case WLAN_CIPHER_SUITE_WEP40
:
519 *profile_cipher
= UMAC_CIPHER_TYPE_WEP_40
;
521 case WLAN_CIPHER_SUITE_WEP104
:
522 *profile_cipher
= UMAC_CIPHER_TYPE_WEP_104
;
524 case WLAN_CIPHER_SUITE_TKIP
:
525 *profile_cipher
= UMAC_CIPHER_TYPE_TKIP
;
527 case WLAN_CIPHER_SUITE_CCMP
:
528 *profile_cipher
= UMAC_CIPHER_TYPE_CCMP
;
531 IWM_ERR(iwm
, "Unsupported cipher: 0x%x\n", cipher
);
538 static int iwm_set_key_mgt(struct iwm_priv
*iwm
, u32 key_mgt
)
540 u8
*auth_type
= &iwm
->umac_profile
->sec
.auth_type
;
542 IWM_DBG_WEXT(iwm
, DBG
, "key_mgt: 0x%x\n", key_mgt
);
544 if (key_mgt
== WLAN_AKM_SUITE_8021X
)
545 *auth_type
= UMAC_AUTH_TYPE_8021X
;
546 else if (key_mgt
== WLAN_AKM_SUITE_PSK
) {
547 if (iwm
->umac_profile
->sec
.flags
&
548 (UMAC_SEC_FLG_WPA_ON_MSK
| UMAC_SEC_FLG_RSNA_ON_MSK
))
549 *auth_type
= UMAC_AUTH_TYPE_RSNA_PSK
;
551 *auth_type
= UMAC_AUTH_TYPE_LEGACY_PSK
;
553 IWM_ERR(iwm
, "Invalid key mgt: 0x%x\n", key_mgt
);
561 static int iwm_cfg80211_connect(struct wiphy
*wiphy
, struct net_device
*dev
,
562 struct cfg80211_connect_params
*sme
)
564 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
565 struct ieee80211_channel
*chan
= sme
->channel
;
566 struct key_params key_param
;
569 if (!test_bit(IWM_STATUS_READY
, &iwm
->status
))
575 if (iwm
->umac_profile_active
) {
576 ret
= iwm_invalidate_mlme_profile(iwm
);
578 IWM_ERR(iwm
, "Couldn't invalidate profile\n");
585 ieee80211_frequency_to_channel(chan
->center_freq
);
587 iwm
->umac_profile
->ssid
.ssid_len
= sme
->ssid_len
;
588 memcpy(iwm
->umac_profile
->ssid
.ssid
, sme
->ssid
, sme
->ssid_len
);
591 IWM_DBG_WEXT(iwm
, DBG
, "BSSID: %pM\n", sme
->bssid
);
592 memcpy(&iwm
->umac_profile
->bssid
[0], sme
->bssid
, ETH_ALEN
);
593 iwm
->umac_profile
->bss_num
= 1;
595 memset(&iwm
->umac_profile
->bssid
[0], 0, ETH_ALEN
);
596 iwm
->umac_profile
->bss_num
= 0;
599 ret
= iwm_set_wpa_version(iwm
, sme
->crypto
.wpa_versions
);
603 ret
= iwm_set_auth_type(iwm
, sme
->auth_type
);
607 if (sme
->crypto
.n_ciphers_pairwise
) {
608 ret
= iwm_set_cipher(iwm
, sme
->crypto
.ciphers_pairwise
[0],
614 ret
= iwm_set_cipher(iwm
, sme
->crypto
.cipher_group
, false);
618 if (sme
->crypto
.n_akm_suites
) {
619 ret
= iwm_set_key_mgt(iwm
, sme
->crypto
.akm_suites
[0]);
625 * We save the WEP key in case we want to do shared authentication.
626 * We have to do it so because UMAC will assert whenever it gets a
627 * key before a profile.
630 key_param
.key
= kmemdup(sme
->key
, sme
->key_len
, GFP_KERNEL
);
631 if (key_param
.key
== NULL
)
633 key_param
.key_len
= sme
->key_len
;
634 key_param
.seq_len
= 0;
635 key_param
.cipher
= sme
->crypto
.ciphers_pairwise
[0];
637 ret
= iwm_key_init(&iwm
->keys
[sme
->key_idx
], sme
->key_idx
,
639 kfree(key_param
.key
);
641 IWM_ERR(iwm
, "Invalid key_params\n");
645 iwm
->default_key
= sme
->key_idx
;
648 ret
= iwm_send_mlme_profile(iwm
);
650 if (iwm
->umac_profile
->sec
.auth_type
!= UMAC_AUTH_TYPE_LEGACY_PSK
||
655 * We want to do shared auth.
656 * We need to actually set the key we previously cached,
657 * and then tell the UMAC it's the default one.
658 * That will trigger the auth+assoc UMAC machinery, and again,
659 * this must be done after setting the profile.
661 ret
= iwm_set_key(iwm
, 0, &iwm
->keys
[sme
->key_idx
]);
665 return iwm_set_tx_key(iwm
, iwm
->default_key
);
668 static int iwm_cfg80211_disconnect(struct wiphy
*wiphy
, struct net_device
*dev
,
671 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
673 IWM_DBG_WEXT(iwm
, DBG
, "Active: %d\n", iwm
->umac_profile_active
);
675 if (iwm
->umac_profile_active
)
676 iwm_invalidate_mlme_profile(iwm
);
681 static int iwm_cfg80211_set_txpower(struct wiphy
*wiphy
,
682 enum tx_power_setting type
, int dbm
)
685 case TX_POWER_AUTOMATIC
:
694 static int iwm_cfg80211_get_txpower(struct wiphy
*wiphy
, int *dbm
)
696 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
703 static int iwm_cfg80211_set_power_mgmt(struct wiphy
*wiphy
,
704 struct net_device
*dev
,
705 bool enabled
, int timeout
)
707 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
711 power_index
= IWM_POWER_INDEX_DEFAULT
;
713 power_index
= IWM_POWER_INDEX_MIN
;
715 if (power_index
== iwm
->conf
.power_index
)
718 iwm
->conf
.power_index
= power_index
;
720 return iwm_umac_set_config_fix(iwm
, UMAC_PARAM_TBL_CFG_FIX
,
721 CFG_POWER_INDEX
, iwm
->conf
.power_index
);
724 static struct cfg80211_ops iwm_cfg80211_ops
= {
725 .change_virtual_intf
= iwm_cfg80211_change_iface
,
726 .add_key
= iwm_cfg80211_add_key
,
727 .get_key
= iwm_cfg80211_get_key
,
728 .del_key
= iwm_cfg80211_del_key
,
729 .set_default_key
= iwm_cfg80211_set_default_key
,
730 .get_station
= iwm_cfg80211_get_station
,
731 .scan
= iwm_cfg80211_scan
,
732 .set_wiphy_params
= iwm_cfg80211_set_wiphy_params
,
733 .connect
= iwm_cfg80211_connect
,
734 .disconnect
= iwm_cfg80211_disconnect
,
735 .join_ibss
= iwm_cfg80211_join_ibss
,
736 .leave_ibss
= iwm_cfg80211_leave_ibss
,
737 .set_tx_power
= iwm_cfg80211_set_txpower
,
738 .get_tx_power
= iwm_cfg80211_get_txpower
,
739 .set_power_mgmt
= iwm_cfg80211_set_power_mgmt
,
742 static const u32 cipher_suites
[] = {
743 WLAN_CIPHER_SUITE_WEP40
,
744 WLAN_CIPHER_SUITE_WEP104
,
745 WLAN_CIPHER_SUITE_TKIP
,
746 WLAN_CIPHER_SUITE_CCMP
,
749 struct wireless_dev
*iwm_wdev_alloc(int sizeof_bus
, struct device
*dev
)
752 struct wireless_dev
*wdev
;
755 * We're trying to have the following memory
758 * +-------------------------+
760 * +-------------------------+
761 * | struct iwm_priv |
762 * +-------------------------+
763 * | bus private data |
764 * | (e.g. iwm_priv_sdio) |
765 * +-------------------------+
769 wdev
= kzalloc(sizeof(struct wireless_dev
), GFP_KERNEL
);
771 dev_err(dev
, "Couldn't allocate wireless device\n");
772 return ERR_PTR(-ENOMEM
);
775 wdev
->wiphy
= wiphy_new(&iwm_cfg80211_ops
,
776 sizeof(struct iwm_priv
) + sizeof_bus
);
778 dev_err(dev
, "Couldn't allocate wiphy device\n");
783 set_wiphy_dev(wdev
->wiphy
, dev
);
784 wdev
->wiphy
->max_scan_ssids
= UMAC_WIFI_IF_PROBE_OPTION_MAX
;
785 wdev
->wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
) |
786 BIT(NL80211_IFTYPE_ADHOC
);
787 wdev
->wiphy
->bands
[IEEE80211_BAND_2GHZ
] = &iwm_band_2ghz
;
788 wdev
->wiphy
->bands
[IEEE80211_BAND_5GHZ
] = &iwm_band_5ghz
;
789 wdev
->wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
791 wdev
->wiphy
->cipher_suites
= cipher_suites
;
792 wdev
->wiphy
->n_cipher_suites
= ARRAY_SIZE(cipher_suites
);
794 ret
= wiphy_register(wdev
->wiphy
);
796 dev_err(dev
, "Couldn't register wiphy device\n");
797 goto out_err_register
;
803 wiphy_free(wdev
->wiphy
);
811 void iwm_wdev_free(struct iwm_priv
*iwm
)
813 struct wireless_dev
*wdev
= iwm_to_wdev(iwm
);
818 wiphy_unregister(wdev
->wiphy
);
819 wiphy_free(wdev
->wiphy
);