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
,
228 u8 key_index
, bool unicast
,
231 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
233 IWM_DBG_WEXT(iwm
, DBG
, "Default key index is: %d\n", key_index
);
235 if (!iwm
->keys
[key_index
].key_len
) {
236 IWM_ERR(iwm
, "Key %d not used\n", key_index
);
240 iwm
->default_key
= key_index
;
242 return iwm_set_tx_key(iwm
, key_index
);
245 static int iwm_cfg80211_get_station(struct wiphy
*wiphy
,
246 struct net_device
*ndev
,
247 u8
*mac
, struct station_info
*sinfo
)
249 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
251 if (memcmp(mac
, iwm
->bssid
, ETH_ALEN
))
254 sinfo
->filled
|= STATION_INFO_TX_BITRATE
;
255 sinfo
->txrate
.legacy
= iwm
->rate
* 10;
257 if (test_bit(IWM_STATUS_ASSOCIATED
, &iwm
->status
)) {
258 sinfo
->filled
|= STATION_INFO_SIGNAL
;
259 sinfo
->signal
= iwm
->wstats
.qual
.level
;
266 int iwm_cfg80211_inform_bss(struct iwm_priv
*iwm
)
268 struct wiphy
*wiphy
= iwm_to_wiphy(iwm
);
269 struct iwm_bss_info
*bss
;
270 struct iwm_umac_notif_bss_info
*umac_bss
;
271 struct ieee80211_mgmt
*mgmt
;
272 struct ieee80211_channel
*channel
;
273 struct ieee80211_supported_band
*band
;
277 list_for_each_entry(bss
, &iwm
->bss_list
, node
) {
279 mgmt
= (struct ieee80211_mgmt
*)(umac_bss
->frame_buf
);
281 if (umac_bss
->band
== UMAC_BAND_2GHZ
)
282 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
283 else if (umac_bss
->band
== UMAC_BAND_5GHZ
)
284 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
286 IWM_ERR(iwm
, "Invalid band: %d\n", umac_bss
->band
);
290 freq
= ieee80211_channel_to_frequency(umac_bss
->channel
,
292 channel
= ieee80211_get_channel(wiphy
, freq
);
293 signal
= umac_bss
->rssi
* 100;
295 if (!cfg80211_inform_bss_frame(wiphy
, channel
, mgmt
,
296 le16_to_cpu(umac_bss
->frame_len
),
304 static int iwm_cfg80211_change_iface(struct wiphy
*wiphy
,
305 struct net_device
*ndev
,
306 enum nl80211_iftype type
, u32
*flags
,
307 struct vif_params
*params
)
309 struct wireless_dev
*wdev
;
310 struct iwm_priv
*iwm
;
313 wdev
= ndev
->ieee80211_ptr
;
314 iwm
= ndev_to_iwm(ndev
);
315 old_mode
= iwm
->conf
.mode
;
318 case NL80211_IFTYPE_STATION
:
319 iwm
->conf
.mode
= UMAC_MODE_BSS
;
321 case NL80211_IFTYPE_ADHOC
:
322 iwm
->conf
.mode
= UMAC_MODE_IBSS
;
330 if ((old_mode
== iwm
->conf
.mode
) || !iwm
->umac_profile
)
333 iwm
->umac_profile
->mode
= cpu_to_le32(iwm
->conf
.mode
);
335 if (iwm
->umac_profile_active
)
336 iwm_invalidate_mlme_profile(iwm
);
341 static int iwm_cfg80211_scan(struct wiphy
*wiphy
, struct net_device
*ndev
,
342 struct cfg80211_scan_request
*request
)
344 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
347 if (!test_bit(IWM_STATUS_READY
, &iwm
->status
)) {
348 IWM_ERR(iwm
, "Scan while device is not ready\n");
352 if (test_bit(IWM_STATUS_SCANNING
, &iwm
->status
)) {
353 IWM_ERR(iwm
, "Scanning already\n");
357 if (test_bit(IWM_STATUS_SCAN_ABORTING
, &iwm
->status
)) {
358 IWM_ERR(iwm
, "Scanning being aborted\n");
362 set_bit(IWM_STATUS_SCANNING
, &iwm
->status
);
364 ret
= iwm_scan_ssids(iwm
, request
->ssids
, request
->n_ssids
);
366 clear_bit(IWM_STATUS_SCANNING
, &iwm
->status
);
370 iwm
->scan_request
= request
;
374 static int iwm_cfg80211_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
)
376 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
378 if (changed
& WIPHY_PARAM_RTS_THRESHOLD
&&
379 (iwm
->conf
.rts_threshold
!= wiphy
->rts_threshold
)) {
382 iwm
->conf
.rts_threshold
= wiphy
->rts_threshold
;
384 ret
= iwm_umac_set_config_fix(iwm
, UMAC_PARAM_TBL_CFG_FIX
,
386 iwm
->conf
.rts_threshold
);
391 if (changed
& WIPHY_PARAM_FRAG_THRESHOLD
&&
392 (iwm
->conf
.frag_threshold
!= wiphy
->frag_threshold
)) {
395 iwm
->conf
.frag_threshold
= wiphy
->frag_threshold
;
397 ret
= iwm_umac_set_config_fix(iwm
, UMAC_PARAM_TBL_FA_CFG_FIX
,
399 iwm
->conf
.frag_threshold
);
407 static int iwm_cfg80211_join_ibss(struct wiphy
*wiphy
, struct net_device
*dev
,
408 struct cfg80211_ibss_params
*params
)
410 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
411 struct ieee80211_channel
*chan
= params
->channel
;
413 if (!test_bit(IWM_STATUS_READY
, &iwm
->status
))
416 /* UMAC doesn't support creating or joining an IBSS network
417 * with specified bssid. */
421 iwm
->channel
= ieee80211_frequency_to_channel(chan
->center_freq
);
422 iwm
->umac_profile
->ibss
.band
= chan
->band
;
423 iwm
->umac_profile
->ibss
.channel
= iwm
->channel
;
424 iwm
->umac_profile
->ssid
.ssid_len
= params
->ssid_len
;
425 memcpy(iwm
->umac_profile
->ssid
.ssid
, params
->ssid
, params
->ssid_len
);
427 return iwm_send_mlme_profile(iwm
);
430 static int iwm_cfg80211_leave_ibss(struct wiphy
*wiphy
, struct net_device
*dev
)
432 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
434 if (iwm
->umac_profile_active
)
435 return iwm_invalidate_mlme_profile(iwm
);
440 static int iwm_set_auth_type(struct iwm_priv
*iwm
,
441 enum nl80211_auth_type sme_auth_type
)
443 u8
*auth_type
= &iwm
->umac_profile
->sec
.auth_type
;
445 switch (sme_auth_type
) {
446 case NL80211_AUTHTYPE_AUTOMATIC
:
447 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
448 IWM_DBG_WEXT(iwm
, DBG
, "OPEN auth\n");
449 *auth_type
= UMAC_AUTH_TYPE_OPEN
;
451 case NL80211_AUTHTYPE_SHARED_KEY
:
452 if (iwm
->umac_profile
->sec
.flags
&
453 (UMAC_SEC_FLG_WPA_ON_MSK
| UMAC_SEC_FLG_RSNA_ON_MSK
)) {
454 IWM_DBG_WEXT(iwm
, DBG
, "WPA auth alg\n");
455 *auth_type
= UMAC_AUTH_TYPE_RSNA_PSK
;
457 IWM_DBG_WEXT(iwm
, DBG
, "WEP shared key auth alg\n");
458 *auth_type
= UMAC_AUTH_TYPE_LEGACY_PSK
;
463 IWM_ERR(iwm
, "Unsupported auth alg: 0x%x\n", sme_auth_type
);
470 static int iwm_set_wpa_version(struct iwm_priv
*iwm
, u32 wpa_version
)
472 IWM_DBG_WEXT(iwm
, DBG
, "wpa_version: %d\n", wpa_version
);
475 iwm
->umac_profile
->sec
.flags
= UMAC_SEC_FLG_LEGACY_PROFILE
;
479 if (wpa_version
& NL80211_WPA_VERSION_1
)
480 iwm
->umac_profile
->sec
.flags
= UMAC_SEC_FLG_WPA_ON_MSK
;
482 if (wpa_version
& NL80211_WPA_VERSION_2
)
483 iwm
->umac_profile
->sec
.flags
= UMAC_SEC_FLG_RSNA_ON_MSK
;
488 static int iwm_set_cipher(struct iwm_priv
*iwm
, u32 cipher
, bool ucast
)
490 u8
*profile_cipher
= ucast
? &iwm
->umac_profile
->sec
.ucast_cipher
:
491 &iwm
->umac_profile
->sec
.mcast_cipher
;
494 *profile_cipher
= UMAC_CIPHER_TYPE_NONE
;
498 IWM_DBG_WEXT(iwm
, DBG
, "%ccast cipher is 0x%x\n", ucast
? 'u' : 'm',
502 case IW_AUTH_CIPHER_NONE
:
503 *profile_cipher
= UMAC_CIPHER_TYPE_NONE
;
505 case WLAN_CIPHER_SUITE_WEP40
:
506 *profile_cipher
= UMAC_CIPHER_TYPE_WEP_40
;
508 case WLAN_CIPHER_SUITE_WEP104
:
509 *profile_cipher
= UMAC_CIPHER_TYPE_WEP_104
;
511 case WLAN_CIPHER_SUITE_TKIP
:
512 *profile_cipher
= UMAC_CIPHER_TYPE_TKIP
;
514 case WLAN_CIPHER_SUITE_CCMP
:
515 *profile_cipher
= UMAC_CIPHER_TYPE_CCMP
;
518 IWM_ERR(iwm
, "Unsupported cipher: 0x%x\n", cipher
);
525 static int iwm_set_key_mgt(struct iwm_priv
*iwm
, u32 key_mgt
)
527 u8
*auth_type
= &iwm
->umac_profile
->sec
.auth_type
;
529 IWM_DBG_WEXT(iwm
, DBG
, "key_mgt: 0x%x\n", key_mgt
);
531 if (key_mgt
== WLAN_AKM_SUITE_8021X
)
532 *auth_type
= UMAC_AUTH_TYPE_8021X
;
533 else if (key_mgt
== WLAN_AKM_SUITE_PSK
) {
534 if (iwm
->umac_profile
->sec
.flags
&
535 (UMAC_SEC_FLG_WPA_ON_MSK
| UMAC_SEC_FLG_RSNA_ON_MSK
))
536 *auth_type
= UMAC_AUTH_TYPE_RSNA_PSK
;
538 *auth_type
= UMAC_AUTH_TYPE_LEGACY_PSK
;
540 IWM_ERR(iwm
, "Invalid key mgt: 0x%x\n", key_mgt
);
548 static int iwm_cfg80211_connect(struct wiphy
*wiphy
, struct net_device
*dev
,
549 struct cfg80211_connect_params
*sme
)
551 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
552 struct ieee80211_channel
*chan
= sme
->channel
;
553 struct key_params key_param
;
556 if (!test_bit(IWM_STATUS_READY
, &iwm
->status
))
562 if (iwm
->umac_profile_active
) {
563 ret
= iwm_invalidate_mlme_profile(iwm
);
565 IWM_ERR(iwm
, "Couldn't invalidate profile\n");
572 ieee80211_frequency_to_channel(chan
->center_freq
);
574 iwm
->umac_profile
->ssid
.ssid_len
= sme
->ssid_len
;
575 memcpy(iwm
->umac_profile
->ssid
.ssid
, sme
->ssid
, sme
->ssid_len
);
578 IWM_DBG_WEXT(iwm
, DBG
, "BSSID: %pM\n", sme
->bssid
);
579 memcpy(&iwm
->umac_profile
->bssid
[0], sme
->bssid
, ETH_ALEN
);
580 iwm
->umac_profile
->bss_num
= 1;
582 memset(&iwm
->umac_profile
->bssid
[0], 0, ETH_ALEN
);
583 iwm
->umac_profile
->bss_num
= 0;
586 ret
= iwm_set_wpa_version(iwm
, sme
->crypto
.wpa_versions
);
590 ret
= iwm_set_auth_type(iwm
, sme
->auth_type
);
594 if (sme
->crypto
.n_ciphers_pairwise
) {
595 ret
= iwm_set_cipher(iwm
, sme
->crypto
.ciphers_pairwise
[0],
601 ret
= iwm_set_cipher(iwm
, sme
->crypto
.cipher_group
, false);
605 if (sme
->crypto
.n_akm_suites
) {
606 ret
= iwm_set_key_mgt(iwm
, sme
->crypto
.akm_suites
[0]);
612 * We save the WEP key in case we want to do shared authentication.
613 * We have to do it so because UMAC will assert whenever it gets a
614 * key before a profile.
617 key_param
.key
= kmemdup(sme
->key
, sme
->key_len
, GFP_KERNEL
);
618 if (key_param
.key
== NULL
)
620 key_param
.key_len
= sme
->key_len
;
621 key_param
.seq_len
= 0;
622 key_param
.cipher
= sme
->crypto
.ciphers_pairwise
[0];
624 ret
= iwm_key_init(&iwm
->keys
[sme
->key_idx
], sme
->key_idx
,
626 kfree(key_param
.key
);
628 IWM_ERR(iwm
, "Invalid key_params\n");
632 iwm
->default_key
= sme
->key_idx
;
635 /* WPA and open AUTH type from wpa_s means WPS (a.k.a. WSC) */
636 if ((iwm
->umac_profile
->sec
.flags
&
637 (UMAC_SEC_FLG_WPA_ON_MSK
| UMAC_SEC_FLG_RSNA_ON_MSK
)) &&
638 iwm
->umac_profile
->sec
.auth_type
== UMAC_AUTH_TYPE_OPEN
) {
639 iwm
->umac_profile
->sec
.flags
= UMAC_SEC_FLG_WSC_ON_MSK
;
642 ret
= iwm_send_mlme_profile(iwm
);
644 if (iwm
->umac_profile
->sec
.auth_type
!= UMAC_AUTH_TYPE_LEGACY_PSK
||
649 * We want to do shared auth.
650 * We need to actually set the key we previously cached,
651 * and then tell the UMAC it's the default one.
652 * That will trigger the auth+assoc UMAC machinery, and again,
653 * this must be done after setting the profile.
655 ret
= iwm_set_key(iwm
, 0, &iwm
->keys
[sme
->key_idx
]);
659 return iwm_set_tx_key(iwm
, iwm
->default_key
);
662 static int iwm_cfg80211_disconnect(struct wiphy
*wiphy
, struct net_device
*dev
,
665 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
667 IWM_DBG_WEXT(iwm
, DBG
, "Active: %d\n", iwm
->umac_profile_active
);
669 if (iwm
->umac_profile_active
)
670 iwm_invalidate_mlme_profile(iwm
);
675 static int iwm_cfg80211_set_txpower(struct wiphy
*wiphy
,
676 enum nl80211_tx_power_setting type
, int mbm
)
678 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
682 case NL80211_TX_POWER_AUTOMATIC
:
684 case NL80211_TX_POWER_FIXED
:
685 if (mbm
< 0 || (mbm
% 100))
688 if (!test_bit(IWM_STATUS_READY
, &iwm
->status
))
691 ret
= iwm_umac_set_config_fix(iwm
, UMAC_PARAM_TBL_CFG_FIX
,
692 CFG_TX_PWR_LIMIT_USR
,
693 MBM_TO_DBM(mbm
) * 2);
697 return iwm_tx_power_trigger(iwm
);
699 IWM_ERR(iwm
, "Unsupported power type: %d\n", type
);
706 static int iwm_cfg80211_get_txpower(struct wiphy
*wiphy
, int *dbm
)
708 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
710 *dbm
= iwm
->txpower
>> 1;
715 static int iwm_cfg80211_set_power_mgmt(struct wiphy
*wiphy
,
716 struct net_device
*dev
,
717 bool enabled
, int timeout
)
719 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
723 power_index
= IWM_POWER_INDEX_DEFAULT
;
725 power_index
= IWM_POWER_INDEX_MIN
;
727 if (power_index
== iwm
->conf
.power_index
)
730 iwm
->conf
.power_index
= power_index
;
732 return iwm_umac_set_config_fix(iwm
, UMAC_PARAM_TBL_CFG_FIX
,
733 CFG_POWER_INDEX
, iwm
->conf
.power_index
);
736 static int iwm_cfg80211_set_pmksa(struct wiphy
*wiphy
,
737 struct net_device
*netdev
,
738 struct cfg80211_pmksa
*pmksa
)
740 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
742 return iwm_send_pmkid_update(iwm
, pmksa
, IWM_CMD_PMKID_ADD
);
745 static int iwm_cfg80211_del_pmksa(struct wiphy
*wiphy
,
746 struct net_device
*netdev
,
747 struct cfg80211_pmksa
*pmksa
)
749 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
751 return iwm_send_pmkid_update(iwm
, pmksa
, IWM_CMD_PMKID_DEL
);
754 static int iwm_cfg80211_flush_pmksa(struct wiphy
*wiphy
,
755 struct net_device
*netdev
)
757 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
758 struct cfg80211_pmksa pmksa
;
760 memset(&pmksa
, 0, sizeof(struct cfg80211_pmksa
));
762 return iwm_send_pmkid_update(iwm
, &pmksa
, IWM_CMD_PMKID_FLUSH
);
766 static struct cfg80211_ops iwm_cfg80211_ops
= {
767 .change_virtual_intf
= iwm_cfg80211_change_iface
,
768 .add_key
= iwm_cfg80211_add_key
,
769 .get_key
= iwm_cfg80211_get_key
,
770 .del_key
= iwm_cfg80211_del_key
,
771 .set_default_key
= iwm_cfg80211_set_default_key
,
772 .get_station
= iwm_cfg80211_get_station
,
773 .scan
= iwm_cfg80211_scan
,
774 .set_wiphy_params
= iwm_cfg80211_set_wiphy_params
,
775 .connect
= iwm_cfg80211_connect
,
776 .disconnect
= iwm_cfg80211_disconnect
,
777 .join_ibss
= iwm_cfg80211_join_ibss
,
778 .leave_ibss
= iwm_cfg80211_leave_ibss
,
779 .set_tx_power
= iwm_cfg80211_set_txpower
,
780 .get_tx_power
= iwm_cfg80211_get_txpower
,
781 .set_power_mgmt
= iwm_cfg80211_set_power_mgmt
,
782 .set_pmksa
= iwm_cfg80211_set_pmksa
,
783 .del_pmksa
= iwm_cfg80211_del_pmksa
,
784 .flush_pmksa
= iwm_cfg80211_flush_pmksa
,
787 static const u32 cipher_suites
[] = {
788 WLAN_CIPHER_SUITE_WEP40
,
789 WLAN_CIPHER_SUITE_WEP104
,
790 WLAN_CIPHER_SUITE_TKIP
,
791 WLAN_CIPHER_SUITE_CCMP
,
794 struct wireless_dev
*iwm_wdev_alloc(int sizeof_bus
, struct device
*dev
)
797 struct wireless_dev
*wdev
;
800 * We're trying to have the following memory
803 * +-------------------------+
805 * +-------------------------+
806 * | struct iwm_priv |
807 * +-------------------------+
808 * | bus private data |
809 * | (e.g. iwm_priv_sdio) |
810 * +-------------------------+
814 wdev
= kzalloc(sizeof(struct wireless_dev
), GFP_KERNEL
);
816 dev_err(dev
, "Couldn't allocate wireless device\n");
817 return ERR_PTR(-ENOMEM
);
820 wdev
->wiphy
= wiphy_new(&iwm_cfg80211_ops
,
821 sizeof(struct iwm_priv
) + sizeof_bus
);
823 dev_err(dev
, "Couldn't allocate wiphy device\n");
828 set_wiphy_dev(wdev
->wiphy
, dev
);
829 wdev
->wiphy
->max_scan_ssids
= UMAC_WIFI_IF_PROBE_OPTION_MAX
;
830 wdev
->wiphy
->max_num_pmkids
= UMAC_MAX_NUM_PMKIDS
;
831 wdev
->wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
) |
832 BIT(NL80211_IFTYPE_ADHOC
);
833 wdev
->wiphy
->bands
[IEEE80211_BAND_2GHZ
] = &iwm_band_2ghz
;
834 wdev
->wiphy
->bands
[IEEE80211_BAND_5GHZ
] = &iwm_band_5ghz
;
835 wdev
->wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
837 wdev
->wiphy
->cipher_suites
= cipher_suites
;
838 wdev
->wiphy
->n_cipher_suites
= ARRAY_SIZE(cipher_suites
);
840 ret
= wiphy_register(wdev
->wiphy
);
842 dev_err(dev
, "Couldn't register wiphy device\n");
843 goto out_err_register
;
849 wiphy_free(wdev
->wiphy
);
857 void iwm_wdev_free(struct iwm_priv
*iwm
)
859 struct wireless_dev
*wdev
= iwm_to_wdev(iwm
);
864 wiphy_unregister(wdev
->wiphy
);
865 wiphy_free(wdev
->wiphy
);