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
, 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
, const u8
*mac_addr
, void *cookie
,
185 void (*callback
)(void *cookie
,
188 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
189 struct iwm_key
*key
= &iwm
->keys
[key_index
];
190 struct key_params params
;
192 IWM_DBG_WEXT(iwm
, DBG
, "Getting key %d\n", key_index
);
194 memset(¶ms
, 0, sizeof(params
));
196 params
.cipher
= key
->cipher
;
197 params
.key_len
= key
->key_len
;
198 params
.seq_len
= key
->seq_len
;
199 params
.seq
= key
->seq
;
200 params
.key
= key
->key
;
202 callback(cookie
, ¶ms
);
204 return key
->key_len
? 0 : -ENOENT
;
208 static int iwm_cfg80211_del_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
209 u8 key_index
, const u8
*mac_addr
)
211 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
212 struct iwm_key
*key
= &iwm
->keys
[key_index
];
214 if (!iwm
->keys
[key_index
].key_len
) {
215 IWM_DBG_WEXT(iwm
, DBG
, "Key %d not used\n", key_index
);
219 if (key_index
== iwm
->default_key
)
220 iwm
->default_key
= -1;
222 return iwm_set_key(iwm
, 1, key
);
225 static int iwm_cfg80211_set_default_key(struct wiphy
*wiphy
,
226 struct net_device
*ndev
,
229 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
231 IWM_DBG_WEXT(iwm
, DBG
, "Default key index is: %d\n", key_index
);
233 if (!iwm
->keys
[key_index
].key_len
) {
234 IWM_ERR(iwm
, "Key %d not used\n", key_index
);
238 iwm
->default_key
= key_index
;
240 return iwm_set_tx_key(iwm
, key_index
);
243 static int iwm_cfg80211_get_station(struct wiphy
*wiphy
,
244 struct net_device
*ndev
,
245 u8
*mac
, struct station_info
*sinfo
)
247 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
249 if (memcmp(mac
, iwm
->bssid
, ETH_ALEN
))
252 sinfo
->filled
|= STATION_INFO_TX_BITRATE
;
253 sinfo
->txrate
.legacy
= iwm
->rate
* 10;
255 if (test_bit(IWM_STATUS_ASSOCIATED
, &iwm
->status
)) {
256 sinfo
->filled
|= STATION_INFO_SIGNAL
;
257 sinfo
->signal
= iwm
->wstats
.qual
.level
;
264 int iwm_cfg80211_inform_bss(struct iwm_priv
*iwm
)
266 struct wiphy
*wiphy
= iwm_to_wiphy(iwm
);
267 struct iwm_bss_info
*bss
;
268 struct iwm_umac_notif_bss_info
*umac_bss
;
269 struct ieee80211_mgmt
*mgmt
;
270 struct ieee80211_channel
*channel
;
271 struct ieee80211_supported_band
*band
;
275 list_for_each_entry(bss
, &iwm
->bss_list
, node
) {
277 mgmt
= (struct ieee80211_mgmt
*)(umac_bss
->frame_buf
);
279 if (umac_bss
->band
== UMAC_BAND_2GHZ
)
280 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
281 else if (umac_bss
->band
== UMAC_BAND_5GHZ
)
282 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
284 IWM_ERR(iwm
, "Invalid band: %d\n", umac_bss
->band
);
288 freq
= ieee80211_channel_to_frequency(umac_bss
->channel
);
289 channel
= ieee80211_get_channel(wiphy
, freq
);
290 signal
= umac_bss
->rssi
* 100;
292 if (!cfg80211_inform_bss_frame(wiphy
, channel
, mgmt
,
293 le16_to_cpu(umac_bss
->frame_len
),
301 static int iwm_cfg80211_change_iface(struct wiphy
*wiphy
,
302 struct net_device
*ndev
,
303 enum nl80211_iftype type
, u32
*flags
,
304 struct vif_params
*params
)
306 struct wireless_dev
*wdev
;
307 struct iwm_priv
*iwm
;
310 wdev
= ndev
->ieee80211_ptr
;
311 iwm
= ndev_to_iwm(ndev
);
312 old_mode
= iwm
->conf
.mode
;
315 case NL80211_IFTYPE_STATION
:
316 iwm
->conf
.mode
= UMAC_MODE_BSS
;
318 case NL80211_IFTYPE_ADHOC
:
319 iwm
->conf
.mode
= UMAC_MODE_IBSS
;
327 if ((old_mode
== iwm
->conf
.mode
) || !iwm
->umac_profile
)
330 iwm
->umac_profile
->mode
= cpu_to_le32(iwm
->conf
.mode
);
332 if (iwm
->umac_profile_active
)
333 iwm_invalidate_mlme_profile(iwm
);
338 static int iwm_cfg80211_scan(struct wiphy
*wiphy
, struct net_device
*ndev
,
339 struct cfg80211_scan_request
*request
)
341 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
344 if (!test_bit(IWM_STATUS_READY
, &iwm
->status
)) {
345 IWM_ERR(iwm
, "Scan while device is not ready\n");
349 if (test_bit(IWM_STATUS_SCANNING
, &iwm
->status
)) {
350 IWM_ERR(iwm
, "Scanning already\n");
354 if (test_bit(IWM_STATUS_SCAN_ABORTING
, &iwm
->status
)) {
355 IWM_ERR(iwm
, "Scanning being aborted\n");
359 set_bit(IWM_STATUS_SCANNING
, &iwm
->status
);
361 ret
= iwm_scan_ssids(iwm
, request
->ssids
, request
->n_ssids
);
363 clear_bit(IWM_STATUS_SCANNING
, &iwm
->status
);
367 iwm
->scan_request
= request
;
371 static int iwm_cfg80211_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
)
373 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
375 if (changed
& WIPHY_PARAM_RTS_THRESHOLD
&&
376 (iwm
->conf
.rts_threshold
!= wiphy
->rts_threshold
)) {
379 iwm
->conf
.rts_threshold
= wiphy
->rts_threshold
;
381 ret
= iwm_umac_set_config_fix(iwm
, UMAC_PARAM_TBL_CFG_FIX
,
383 iwm
->conf
.rts_threshold
);
388 if (changed
& WIPHY_PARAM_FRAG_THRESHOLD
&&
389 (iwm
->conf
.frag_threshold
!= wiphy
->frag_threshold
)) {
392 iwm
->conf
.frag_threshold
= wiphy
->frag_threshold
;
394 ret
= iwm_umac_set_config_fix(iwm
, UMAC_PARAM_TBL_FA_CFG_FIX
,
396 iwm
->conf
.frag_threshold
);
404 static int iwm_cfg80211_join_ibss(struct wiphy
*wiphy
, struct net_device
*dev
,
405 struct cfg80211_ibss_params
*params
)
407 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
408 struct ieee80211_channel
*chan
= params
->channel
;
410 if (!test_bit(IWM_STATUS_READY
, &iwm
->status
))
413 /* UMAC doesn't support creating or joining an IBSS network
414 * with specified bssid. */
418 iwm
->channel
= ieee80211_frequency_to_channel(chan
->center_freq
);
419 iwm
->umac_profile
->ibss
.band
= chan
->band
;
420 iwm
->umac_profile
->ibss
.channel
= iwm
->channel
;
421 iwm
->umac_profile
->ssid
.ssid_len
= params
->ssid_len
;
422 memcpy(iwm
->umac_profile
->ssid
.ssid
, params
->ssid
, params
->ssid_len
);
424 return iwm_send_mlme_profile(iwm
);
427 static int iwm_cfg80211_leave_ibss(struct wiphy
*wiphy
, struct net_device
*dev
)
429 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
431 if (iwm
->umac_profile_active
)
432 return iwm_invalidate_mlme_profile(iwm
);
437 static int iwm_set_auth_type(struct iwm_priv
*iwm
,
438 enum nl80211_auth_type sme_auth_type
)
440 u8
*auth_type
= &iwm
->umac_profile
->sec
.auth_type
;
442 switch (sme_auth_type
) {
443 case NL80211_AUTHTYPE_AUTOMATIC
:
444 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
445 IWM_DBG_WEXT(iwm
, DBG
, "OPEN auth\n");
446 *auth_type
= UMAC_AUTH_TYPE_OPEN
;
448 case NL80211_AUTHTYPE_SHARED_KEY
:
449 if (iwm
->umac_profile
->sec
.flags
&
450 (UMAC_SEC_FLG_WPA_ON_MSK
| UMAC_SEC_FLG_RSNA_ON_MSK
)) {
451 IWM_DBG_WEXT(iwm
, DBG
, "WPA auth alg\n");
452 *auth_type
= UMAC_AUTH_TYPE_RSNA_PSK
;
454 IWM_DBG_WEXT(iwm
, DBG
, "WEP shared key auth alg\n");
455 *auth_type
= UMAC_AUTH_TYPE_LEGACY_PSK
;
460 IWM_ERR(iwm
, "Unsupported auth alg: 0x%x\n", sme_auth_type
);
467 static int iwm_set_wpa_version(struct iwm_priv
*iwm
, u32 wpa_version
)
469 IWM_DBG_WEXT(iwm
, DBG
, "wpa_version: %d\n", wpa_version
);
472 iwm
->umac_profile
->sec
.flags
= UMAC_SEC_FLG_LEGACY_PROFILE
;
476 if (wpa_version
& NL80211_WPA_VERSION_1
)
477 iwm
->umac_profile
->sec
.flags
= UMAC_SEC_FLG_WPA_ON_MSK
;
479 if (wpa_version
& NL80211_WPA_VERSION_2
)
480 iwm
->umac_profile
->sec
.flags
= UMAC_SEC_FLG_RSNA_ON_MSK
;
485 static int iwm_set_cipher(struct iwm_priv
*iwm
, u32 cipher
, bool ucast
)
487 u8
*profile_cipher
= ucast
? &iwm
->umac_profile
->sec
.ucast_cipher
:
488 &iwm
->umac_profile
->sec
.mcast_cipher
;
491 *profile_cipher
= UMAC_CIPHER_TYPE_NONE
;
495 IWM_DBG_WEXT(iwm
, DBG
, "%ccast cipher is 0x%x\n", ucast
? 'u' : 'm',
499 case IW_AUTH_CIPHER_NONE
:
500 *profile_cipher
= UMAC_CIPHER_TYPE_NONE
;
502 case WLAN_CIPHER_SUITE_WEP40
:
503 *profile_cipher
= UMAC_CIPHER_TYPE_WEP_40
;
505 case WLAN_CIPHER_SUITE_WEP104
:
506 *profile_cipher
= UMAC_CIPHER_TYPE_WEP_104
;
508 case WLAN_CIPHER_SUITE_TKIP
:
509 *profile_cipher
= UMAC_CIPHER_TYPE_TKIP
;
511 case WLAN_CIPHER_SUITE_CCMP
:
512 *profile_cipher
= UMAC_CIPHER_TYPE_CCMP
;
515 IWM_ERR(iwm
, "Unsupported cipher: 0x%x\n", cipher
);
522 static int iwm_set_key_mgt(struct iwm_priv
*iwm
, u32 key_mgt
)
524 u8
*auth_type
= &iwm
->umac_profile
->sec
.auth_type
;
526 IWM_DBG_WEXT(iwm
, DBG
, "key_mgt: 0x%x\n", key_mgt
);
528 if (key_mgt
== WLAN_AKM_SUITE_8021X
)
529 *auth_type
= UMAC_AUTH_TYPE_8021X
;
530 else if (key_mgt
== WLAN_AKM_SUITE_PSK
) {
531 if (iwm
->umac_profile
->sec
.flags
&
532 (UMAC_SEC_FLG_WPA_ON_MSK
| UMAC_SEC_FLG_RSNA_ON_MSK
))
533 *auth_type
= UMAC_AUTH_TYPE_RSNA_PSK
;
535 *auth_type
= UMAC_AUTH_TYPE_LEGACY_PSK
;
537 IWM_ERR(iwm
, "Invalid key mgt: 0x%x\n", key_mgt
);
545 static int iwm_cfg80211_connect(struct wiphy
*wiphy
, struct net_device
*dev
,
546 struct cfg80211_connect_params
*sme
)
548 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
549 struct ieee80211_channel
*chan
= sme
->channel
;
550 struct key_params key_param
;
553 if (!test_bit(IWM_STATUS_READY
, &iwm
->status
))
559 if (iwm
->umac_profile_active
) {
560 ret
= iwm_invalidate_mlme_profile(iwm
);
562 IWM_ERR(iwm
, "Couldn't invalidate profile\n");
569 ieee80211_frequency_to_channel(chan
->center_freq
);
571 iwm
->umac_profile
->ssid
.ssid_len
= sme
->ssid_len
;
572 memcpy(iwm
->umac_profile
->ssid
.ssid
, sme
->ssid
, sme
->ssid_len
);
575 IWM_DBG_WEXT(iwm
, DBG
, "BSSID: %pM\n", sme
->bssid
);
576 memcpy(&iwm
->umac_profile
->bssid
[0], sme
->bssid
, ETH_ALEN
);
577 iwm
->umac_profile
->bss_num
= 1;
579 memset(&iwm
->umac_profile
->bssid
[0], 0, ETH_ALEN
);
580 iwm
->umac_profile
->bss_num
= 0;
583 ret
= iwm_set_wpa_version(iwm
, sme
->crypto
.wpa_versions
);
587 ret
= iwm_set_auth_type(iwm
, sme
->auth_type
);
591 if (sme
->crypto
.n_ciphers_pairwise
) {
592 ret
= iwm_set_cipher(iwm
, sme
->crypto
.ciphers_pairwise
[0],
598 ret
= iwm_set_cipher(iwm
, sme
->crypto
.cipher_group
, false);
602 if (sme
->crypto
.n_akm_suites
) {
603 ret
= iwm_set_key_mgt(iwm
, sme
->crypto
.akm_suites
[0]);
609 * We save the WEP key in case we want to do shared authentication.
610 * We have to do it so because UMAC will assert whenever it gets a
611 * key before a profile.
614 key_param
.key
= kmemdup(sme
->key
, sme
->key_len
, GFP_KERNEL
);
615 if (key_param
.key
== NULL
)
617 key_param
.key_len
= sme
->key_len
;
618 key_param
.seq_len
= 0;
619 key_param
.cipher
= sme
->crypto
.ciphers_pairwise
[0];
621 ret
= iwm_key_init(&iwm
->keys
[sme
->key_idx
], sme
->key_idx
,
623 kfree(key_param
.key
);
625 IWM_ERR(iwm
, "Invalid key_params\n");
629 iwm
->default_key
= sme
->key_idx
;
632 /* WPA and open AUTH type from wpa_s means WPS (a.k.a. WSC) */
633 if ((iwm
->umac_profile
->sec
.flags
&
634 (UMAC_SEC_FLG_WPA_ON_MSK
| UMAC_SEC_FLG_RSNA_ON_MSK
)) &&
635 iwm
->umac_profile
->sec
.auth_type
== UMAC_AUTH_TYPE_OPEN
) {
636 iwm
->umac_profile
->sec
.flags
= UMAC_SEC_FLG_WSC_ON_MSK
;
639 ret
= iwm_send_mlme_profile(iwm
);
641 if (iwm
->umac_profile
->sec
.auth_type
!= UMAC_AUTH_TYPE_LEGACY_PSK
||
646 * We want to do shared auth.
647 * We need to actually set the key we previously cached,
648 * and then tell the UMAC it's the default one.
649 * That will trigger the auth+assoc UMAC machinery, and again,
650 * this must be done after setting the profile.
652 ret
= iwm_set_key(iwm
, 0, &iwm
->keys
[sme
->key_idx
]);
656 return iwm_set_tx_key(iwm
, iwm
->default_key
);
659 static int iwm_cfg80211_disconnect(struct wiphy
*wiphy
, struct net_device
*dev
,
662 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
664 IWM_DBG_WEXT(iwm
, DBG
, "Active: %d\n", iwm
->umac_profile_active
);
666 if (iwm
->umac_profile_active
)
667 iwm_invalidate_mlme_profile(iwm
);
672 static int iwm_cfg80211_set_txpower(struct wiphy
*wiphy
,
673 enum tx_power_setting type
, int dbm
)
675 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
679 case TX_POWER_AUTOMATIC
:
682 if (!test_bit(IWM_STATUS_READY
, &iwm
->status
))
685 ret
= iwm_umac_set_config_fix(iwm
, UMAC_PARAM_TBL_CFG_FIX
,
686 CFG_TX_PWR_LIMIT_USR
, dbm
* 2);
690 return iwm_tx_power_trigger(iwm
);
692 IWM_ERR(iwm
, "Unsupported power type: %d\n", type
);
699 static int iwm_cfg80211_get_txpower(struct wiphy
*wiphy
, int *dbm
)
701 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
703 *dbm
= iwm
->txpower
>> 1;
708 static int iwm_cfg80211_set_power_mgmt(struct wiphy
*wiphy
,
709 struct net_device
*dev
,
710 bool enabled
, int timeout
)
712 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
716 power_index
= IWM_POWER_INDEX_DEFAULT
;
718 power_index
= IWM_POWER_INDEX_MIN
;
720 if (power_index
== iwm
->conf
.power_index
)
723 iwm
->conf
.power_index
= power_index
;
725 return iwm_umac_set_config_fix(iwm
, UMAC_PARAM_TBL_CFG_FIX
,
726 CFG_POWER_INDEX
, iwm
->conf
.power_index
);
729 static int iwm_cfg80211_set_pmksa(struct wiphy
*wiphy
,
730 struct net_device
*netdev
,
731 struct cfg80211_pmksa
*pmksa
)
733 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
735 return iwm_send_pmkid_update(iwm
, pmksa
, IWM_CMD_PMKID_ADD
);
738 static int iwm_cfg80211_del_pmksa(struct wiphy
*wiphy
,
739 struct net_device
*netdev
,
740 struct cfg80211_pmksa
*pmksa
)
742 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
744 return iwm_send_pmkid_update(iwm
, pmksa
, IWM_CMD_PMKID_DEL
);
747 static int iwm_cfg80211_flush_pmksa(struct wiphy
*wiphy
,
748 struct net_device
*netdev
)
750 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
751 struct cfg80211_pmksa pmksa
;
753 memset(&pmksa
, 0, sizeof(struct cfg80211_pmksa
));
755 return iwm_send_pmkid_update(iwm
, &pmksa
, IWM_CMD_PMKID_FLUSH
);
759 static struct cfg80211_ops iwm_cfg80211_ops
= {
760 .change_virtual_intf
= iwm_cfg80211_change_iface
,
761 .add_key
= iwm_cfg80211_add_key
,
762 .get_key
= iwm_cfg80211_get_key
,
763 .del_key
= iwm_cfg80211_del_key
,
764 .set_default_key
= iwm_cfg80211_set_default_key
,
765 .get_station
= iwm_cfg80211_get_station
,
766 .scan
= iwm_cfg80211_scan
,
767 .set_wiphy_params
= iwm_cfg80211_set_wiphy_params
,
768 .connect
= iwm_cfg80211_connect
,
769 .disconnect
= iwm_cfg80211_disconnect
,
770 .join_ibss
= iwm_cfg80211_join_ibss
,
771 .leave_ibss
= iwm_cfg80211_leave_ibss
,
772 .set_tx_power
= iwm_cfg80211_set_txpower
,
773 .get_tx_power
= iwm_cfg80211_get_txpower
,
774 .set_power_mgmt
= iwm_cfg80211_set_power_mgmt
,
775 .set_pmksa
= iwm_cfg80211_set_pmksa
,
776 .del_pmksa
= iwm_cfg80211_del_pmksa
,
777 .flush_pmksa
= iwm_cfg80211_flush_pmksa
,
780 static const u32 cipher_suites
[] = {
781 WLAN_CIPHER_SUITE_WEP40
,
782 WLAN_CIPHER_SUITE_WEP104
,
783 WLAN_CIPHER_SUITE_TKIP
,
784 WLAN_CIPHER_SUITE_CCMP
,
787 struct wireless_dev
*iwm_wdev_alloc(int sizeof_bus
, struct device
*dev
)
790 struct wireless_dev
*wdev
;
793 * We're trying to have the following memory
796 * +-------------------------+
798 * +-------------------------+
799 * | struct iwm_priv |
800 * +-------------------------+
801 * | bus private data |
802 * | (e.g. iwm_priv_sdio) |
803 * +-------------------------+
807 wdev
= kzalloc(sizeof(struct wireless_dev
), GFP_KERNEL
);
809 dev_err(dev
, "Couldn't allocate wireless device\n");
810 return ERR_PTR(-ENOMEM
);
813 wdev
->wiphy
= wiphy_new(&iwm_cfg80211_ops
,
814 sizeof(struct iwm_priv
) + sizeof_bus
);
816 dev_err(dev
, "Couldn't allocate wiphy device\n");
821 set_wiphy_dev(wdev
->wiphy
, dev
);
822 wdev
->wiphy
->max_scan_ssids
= UMAC_WIFI_IF_PROBE_OPTION_MAX
;
823 wdev
->wiphy
->max_num_pmkids
= UMAC_MAX_NUM_PMKIDS
;
824 wdev
->wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
) |
825 BIT(NL80211_IFTYPE_ADHOC
);
826 wdev
->wiphy
->bands
[IEEE80211_BAND_2GHZ
] = &iwm_band_2ghz
;
827 wdev
->wiphy
->bands
[IEEE80211_BAND_5GHZ
] = &iwm_band_5ghz
;
828 wdev
->wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
830 wdev
->wiphy
->cipher_suites
= cipher_suites
;
831 wdev
->wiphy
->n_cipher_suites
= ARRAY_SIZE(cipher_suites
);
833 ret
= wiphy_register(wdev
->wiphy
);
835 dev_err(dev
, "Couldn't register wiphy device\n");
836 goto out_err_register
;
842 wiphy_free(wdev
->wiphy
);
850 void iwm_wdev_free(struct iwm_priv
*iwm
)
852 struct wireless_dev
*wdev
= iwm_to_wdev(iwm
);
857 wiphy_unregister(wdev
->wiphy
);
858 wiphy_free(wdev
->wiphy
);