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
);
171 IWM_DBG_WEXT(iwm
, DBG
, "Adding key for %pM\n", mac_addr
);
173 if (key_index
>= IWM_NUM_KEYS
)
176 key
= &iwm
->keys
[key_index
];
177 memset(key
, 0, sizeof(struct iwm_key
));
178 ret
= iwm_key_init(key
, key_index
, mac_addr
, params
);
180 IWM_ERR(iwm
, "Invalid key_params\n");
184 return iwm_set_key(iwm
, 0, key
);
187 static int iwm_cfg80211_get_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
188 u8 key_index
, bool pairwise
, const u8
*mac_addr
,
190 void (*callback
)(void *cookie
,
193 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
195 struct key_params params
;
197 IWM_DBG_WEXT(iwm
, DBG
, "Getting key %d\n", key_index
);
199 if (key_index
>= IWM_NUM_KEYS
)
202 memset(¶ms
, 0, sizeof(params
));
204 key
= &iwm
->keys
[key_index
];
205 params
.cipher
= key
->cipher
;
206 params
.key_len
= key
->key_len
;
207 params
.seq_len
= key
->seq_len
;
208 params
.seq
= key
->seq
;
209 params
.key
= key
->key
;
211 callback(cookie
, ¶ms
);
213 return key
->key_len
? 0 : -ENOENT
;
217 static int iwm_cfg80211_del_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
218 u8 key_index
, bool pairwise
, const u8
*mac_addr
)
220 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
223 if (key_index
>= IWM_NUM_KEYS
)
226 key
= &iwm
->keys
[key_index
];
227 if (!iwm
->keys
[key_index
].key_len
) {
228 IWM_DBG_WEXT(iwm
, DBG
, "Key %d not used\n", key_index
);
232 if (key_index
== iwm
->default_key
)
233 iwm
->default_key
= -1;
235 return iwm_set_key(iwm
, 1, key
);
238 static int iwm_cfg80211_set_default_key(struct wiphy
*wiphy
,
239 struct net_device
*ndev
,
240 u8 key_index
, bool unicast
,
243 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
245 IWM_DBG_WEXT(iwm
, DBG
, "Default key index is: %d\n", key_index
);
247 if (key_index
>= IWM_NUM_KEYS
)
250 if (!iwm
->keys
[key_index
].key_len
) {
251 IWM_ERR(iwm
, "Key %d not used\n", key_index
);
255 iwm
->default_key
= key_index
;
257 return iwm_set_tx_key(iwm
, key_index
);
260 static int iwm_cfg80211_get_station(struct wiphy
*wiphy
,
261 struct net_device
*ndev
,
262 u8
*mac
, struct station_info
*sinfo
)
264 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
266 if (memcmp(mac
, iwm
->bssid
, ETH_ALEN
))
269 sinfo
->filled
|= STATION_INFO_TX_BITRATE
;
270 sinfo
->txrate
.legacy
= iwm
->rate
* 10;
272 if (test_bit(IWM_STATUS_ASSOCIATED
, &iwm
->status
)) {
273 sinfo
->filled
|= STATION_INFO_SIGNAL
;
274 sinfo
->signal
= iwm
->wstats
.qual
.level
;
281 int iwm_cfg80211_inform_bss(struct iwm_priv
*iwm
)
283 struct wiphy
*wiphy
= iwm_to_wiphy(iwm
);
284 struct iwm_bss_info
*bss
;
285 struct iwm_umac_notif_bss_info
*umac_bss
;
286 struct ieee80211_mgmt
*mgmt
;
287 struct ieee80211_channel
*channel
;
288 struct ieee80211_supported_band
*band
;
292 list_for_each_entry(bss
, &iwm
->bss_list
, node
) {
294 mgmt
= (struct ieee80211_mgmt
*)(umac_bss
->frame_buf
);
296 if (umac_bss
->band
== UMAC_BAND_2GHZ
)
297 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
298 else if (umac_bss
->band
== UMAC_BAND_5GHZ
)
299 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
301 IWM_ERR(iwm
, "Invalid band: %d\n", umac_bss
->band
);
305 freq
= ieee80211_channel_to_frequency(umac_bss
->channel
,
307 channel
= ieee80211_get_channel(wiphy
, freq
);
308 signal
= umac_bss
->rssi
* 100;
310 if (!cfg80211_inform_bss_frame(wiphy
, channel
, mgmt
,
311 le16_to_cpu(umac_bss
->frame_len
),
319 static int iwm_cfg80211_change_iface(struct wiphy
*wiphy
,
320 struct net_device
*ndev
,
321 enum nl80211_iftype type
, u32
*flags
,
322 struct vif_params
*params
)
324 struct wireless_dev
*wdev
;
325 struct iwm_priv
*iwm
;
328 wdev
= ndev
->ieee80211_ptr
;
329 iwm
= ndev_to_iwm(ndev
);
330 old_mode
= iwm
->conf
.mode
;
333 case NL80211_IFTYPE_STATION
:
334 iwm
->conf
.mode
= UMAC_MODE_BSS
;
336 case NL80211_IFTYPE_ADHOC
:
337 iwm
->conf
.mode
= UMAC_MODE_IBSS
;
345 if ((old_mode
== iwm
->conf
.mode
) || !iwm
->umac_profile
)
348 iwm
->umac_profile
->mode
= cpu_to_le32(iwm
->conf
.mode
);
350 if (iwm
->umac_profile_active
)
351 iwm_invalidate_mlme_profile(iwm
);
356 static int iwm_cfg80211_scan(struct wiphy
*wiphy
,
357 struct cfg80211_scan_request
*request
)
359 struct net_device
*ndev
= request
->wdev
->netdev
;
360 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
363 if (!test_bit(IWM_STATUS_READY
, &iwm
->status
)) {
364 IWM_ERR(iwm
, "Scan while device is not ready\n");
368 if (test_bit(IWM_STATUS_SCANNING
, &iwm
->status
)) {
369 IWM_ERR(iwm
, "Scanning already\n");
373 if (test_bit(IWM_STATUS_SCAN_ABORTING
, &iwm
->status
)) {
374 IWM_ERR(iwm
, "Scanning being aborted\n");
378 set_bit(IWM_STATUS_SCANNING
, &iwm
->status
);
380 ret
= iwm_scan_ssids(iwm
, request
->ssids
, request
->n_ssids
);
382 clear_bit(IWM_STATUS_SCANNING
, &iwm
->status
);
386 iwm
->scan_request
= request
;
390 static int iwm_cfg80211_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
)
392 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
394 if (changed
& WIPHY_PARAM_RTS_THRESHOLD
&&
395 (iwm
->conf
.rts_threshold
!= wiphy
->rts_threshold
)) {
398 iwm
->conf
.rts_threshold
= wiphy
->rts_threshold
;
400 ret
= iwm_umac_set_config_fix(iwm
, UMAC_PARAM_TBL_CFG_FIX
,
402 iwm
->conf
.rts_threshold
);
407 if (changed
& WIPHY_PARAM_FRAG_THRESHOLD
&&
408 (iwm
->conf
.frag_threshold
!= wiphy
->frag_threshold
)) {
411 iwm
->conf
.frag_threshold
= wiphy
->frag_threshold
;
413 ret
= iwm_umac_set_config_fix(iwm
, UMAC_PARAM_TBL_FA_CFG_FIX
,
415 iwm
->conf
.frag_threshold
);
423 static int iwm_cfg80211_join_ibss(struct wiphy
*wiphy
, struct net_device
*dev
,
424 struct cfg80211_ibss_params
*params
)
426 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
427 struct ieee80211_channel
*chan
= params
->channel
;
429 if (!test_bit(IWM_STATUS_READY
, &iwm
->status
))
432 /* UMAC doesn't support creating or joining an IBSS network
433 * with specified bssid. */
437 iwm
->channel
= ieee80211_frequency_to_channel(chan
->center_freq
);
438 iwm
->umac_profile
->ibss
.band
= chan
->band
;
439 iwm
->umac_profile
->ibss
.channel
= iwm
->channel
;
440 iwm
->umac_profile
->ssid
.ssid_len
= params
->ssid_len
;
441 memcpy(iwm
->umac_profile
->ssid
.ssid
, params
->ssid
, params
->ssid_len
);
443 return iwm_send_mlme_profile(iwm
);
446 static int iwm_cfg80211_leave_ibss(struct wiphy
*wiphy
, struct net_device
*dev
)
448 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
450 if (iwm
->umac_profile_active
)
451 return iwm_invalidate_mlme_profile(iwm
);
456 static int iwm_set_auth_type(struct iwm_priv
*iwm
,
457 enum nl80211_auth_type sme_auth_type
)
459 u8
*auth_type
= &iwm
->umac_profile
->sec
.auth_type
;
461 switch (sme_auth_type
) {
462 case NL80211_AUTHTYPE_AUTOMATIC
:
463 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
464 IWM_DBG_WEXT(iwm
, DBG
, "OPEN auth\n");
465 *auth_type
= UMAC_AUTH_TYPE_OPEN
;
467 case NL80211_AUTHTYPE_SHARED_KEY
:
468 if (iwm
->umac_profile
->sec
.flags
&
469 (UMAC_SEC_FLG_WPA_ON_MSK
| UMAC_SEC_FLG_RSNA_ON_MSK
)) {
470 IWM_DBG_WEXT(iwm
, DBG
, "WPA auth alg\n");
471 *auth_type
= UMAC_AUTH_TYPE_RSNA_PSK
;
473 IWM_DBG_WEXT(iwm
, DBG
, "WEP shared key auth alg\n");
474 *auth_type
= UMAC_AUTH_TYPE_LEGACY_PSK
;
479 IWM_ERR(iwm
, "Unsupported auth alg: 0x%x\n", sme_auth_type
);
486 static int iwm_set_wpa_version(struct iwm_priv
*iwm
, u32 wpa_version
)
488 IWM_DBG_WEXT(iwm
, DBG
, "wpa_version: %d\n", wpa_version
);
491 iwm
->umac_profile
->sec
.flags
= UMAC_SEC_FLG_LEGACY_PROFILE
;
495 if (wpa_version
& NL80211_WPA_VERSION_1
)
496 iwm
->umac_profile
->sec
.flags
= UMAC_SEC_FLG_WPA_ON_MSK
;
498 if (wpa_version
& NL80211_WPA_VERSION_2
)
499 iwm
->umac_profile
->sec
.flags
= UMAC_SEC_FLG_RSNA_ON_MSK
;
504 static int iwm_set_cipher(struct iwm_priv
*iwm
, u32 cipher
, bool ucast
)
506 u8
*profile_cipher
= ucast
? &iwm
->umac_profile
->sec
.ucast_cipher
:
507 &iwm
->umac_profile
->sec
.mcast_cipher
;
510 *profile_cipher
= UMAC_CIPHER_TYPE_NONE
;
514 IWM_DBG_WEXT(iwm
, DBG
, "%ccast cipher is 0x%x\n", ucast
? 'u' : 'm',
518 case IW_AUTH_CIPHER_NONE
:
519 *profile_cipher
= UMAC_CIPHER_TYPE_NONE
;
521 case WLAN_CIPHER_SUITE_WEP40
:
522 *profile_cipher
= UMAC_CIPHER_TYPE_WEP_40
;
524 case WLAN_CIPHER_SUITE_WEP104
:
525 *profile_cipher
= UMAC_CIPHER_TYPE_WEP_104
;
527 case WLAN_CIPHER_SUITE_TKIP
:
528 *profile_cipher
= UMAC_CIPHER_TYPE_TKIP
;
530 case WLAN_CIPHER_SUITE_CCMP
:
531 *profile_cipher
= UMAC_CIPHER_TYPE_CCMP
;
534 IWM_ERR(iwm
, "Unsupported cipher: 0x%x\n", cipher
);
541 static int iwm_set_key_mgt(struct iwm_priv
*iwm
, u32 key_mgt
)
543 u8
*auth_type
= &iwm
->umac_profile
->sec
.auth_type
;
545 IWM_DBG_WEXT(iwm
, DBG
, "key_mgt: 0x%x\n", key_mgt
);
547 if (key_mgt
== WLAN_AKM_SUITE_8021X
)
548 *auth_type
= UMAC_AUTH_TYPE_8021X
;
549 else if (key_mgt
== WLAN_AKM_SUITE_PSK
) {
550 if (iwm
->umac_profile
->sec
.flags
&
551 (UMAC_SEC_FLG_WPA_ON_MSK
| UMAC_SEC_FLG_RSNA_ON_MSK
))
552 *auth_type
= UMAC_AUTH_TYPE_RSNA_PSK
;
554 *auth_type
= UMAC_AUTH_TYPE_LEGACY_PSK
;
556 IWM_ERR(iwm
, "Invalid key mgt: 0x%x\n", key_mgt
);
564 static int iwm_cfg80211_connect(struct wiphy
*wiphy
, struct net_device
*dev
,
565 struct cfg80211_connect_params
*sme
)
567 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
568 struct ieee80211_channel
*chan
= sme
->channel
;
569 struct key_params key_param
;
572 if (!test_bit(IWM_STATUS_READY
, &iwm
->status
))
578 if (iwm
->umac_profile_active
) {
579 ret
= iwm_invalidate_mlme_profile(iwm
);
581 IWM_ERR(iwm
, "Couldn't invalidate profile\n");
588 ieee80211_frequency_to_channel(chan
->center_freq
);
590 iwm
->umac_profile
->ssid
.ssid_len
= sme
->ssid_len
;
591 memcpy(iwm
->umac_profile
->ssid
.ssid
, sme
->ssid
, sme
->ssid_len
);
594 IWM_DBG_WEXT(iwm
, DBG
, "BSSID: %pM\n", sme
->bssid
);
595 memcpy(&iwm
->umac_profile
->bssid
[0], sme
->bssid
, ETH_ALEN
);
596 iwm
->umac_profile
->bss_num
= 1;
598 memset(&iwm
->umac_profile
->bssid
[0], 0, ETH_ALEN
);
599 iwm
->umac_profile
->bss_num
= 0;
602 ret
= iwm_set_wpa_version(iwm
, sme
->crypto
.wpa_versions
);
606 ret
= iwm_set_auth_type(iwm
, sme
->auth_type
);
610 if (sme
->crypto
.n_ciphers_pairwise
) {
611 ret
= iwm_set_cipher(iwm
, sme
->crypto
.ciphers_pairwise
[0],
617 ret
= iwm_set_cipher(iwm
, sme
->crypto
.cipher_group
, false);
621 if (sme
->crypto
.n_akm_suites
) {
622 ret
= iwm_set_key_mgt(iwm
, sme
->crypto
.akm_suites
[0]);
628 * We save the WEP key in case we want to do shared authentication.
629 * We have to do it so because UMAC will assert whenever it gets a
630 * key before a profile.
633 key_param
.key
= kmemdup(sme
->key
, sme
->key_len
, GFP_KERNEL
);
634 if (key_param
.key
== NULL
)
636 key_param
.key_len
= sme
->key_len
;
637 key_param
.seq_len
= 0;
638 key_param
.cipher
= sme
->crypto
.ciphers_pairwise
[0];
640 ret
= iwm_key_init(&iwm
->keys
[sme
->key_idx
], sme
->key_idx
,
642 kfree(key_param
.key
);
644 IWM_ERR(iwm
, "Invalid key_params\n");
648 iwm
->default_key
= sme
->key_idx
;
651 /* WPA and open AUTH type from wpa_s means WPS (a.k.a. WSC) */
652 if ((iwm
->umac_profile
->sec
.flags
&
653 (UMAC_SEC_FLG_WPA_ON_MSK
| UMAC_SEC_FLG_RSNA_ON_MSK
)) &&
654 iwm
->umac_profile
->sec
.auth_type
== UMAC_AUTH_TYPE_OPEN
) {
655 iwm
->umac_profile
->sec
.flags
= UMAC_SEC_FLG_WSC_ON_MSK
;
658 ret
= iwm_send_mlme_profile(iwm
);
660 if (iwm
->umac_profile
->sec
.auth_type
!= UMAC_AUTH_TYPE_LEGACY_PSK
||
665 * We want to do shared auth.
666 * We need to actually set the key we previously cached,
667 * and then tell the UMAC it's the default one.
668 * That will trigger the auth+assoc UMAC machinery, and again,
669 * this must be done after setting the profile.
671 ret
= iwm_set_key(iwm
, 0, &iwm
->keys
[sme
->key_idx
]);
675 return iwm_set_tx_key(iwm
, iwm
->default_key
);
678 static int iwm_cfg80211_disconnect(struct wiphy
*wiphy
, struct net_device
*dev
,
681 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
683 IWM_DBG_WEXT(iwm
, DBG
, "Active: %d\n", iwm
->umac_profile_active
);
685 if (iwm
->umac_profile_active
)
686 iwm_invalidate_mlme_profile(iwm
);
691 static int iwm_cfg80211_set_txpower(struct wiphy
*wiphy
,
692 enum nl80211_tx_power_setting type
, int mbm
)
694 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
698 case NL80211_TX_POWER_AUTOMATIC
:
700 case NL80211_TX_POWER_FIXED
:
701 if (mbm
< 0 || (mbm
% 100))
704 if (!test_bit(IWM_STATUS_READY
, &iwm
->status
))
707 ret
= iwm_umac_set_config_fix(iwm
, UMAC_PARAM_TBL_CFG_FIX
,
708 CFG_TX_PWR_LIMIT_USR
,
709 MBM_TO_DBM(mbm
) * 2);
713 return iwm_tx_power_trigger(iwm
);
715 IWM_ERR(iwm
, "Unsupported power type: %d\n", type
);
722 static int iwm_cfg80211_get_txpower(struct wiphy
*wiphy
, int *dbm
)
724 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
726 *dbm
= iwm
->txpower
>> 1;
731 static int iwm_cfg80211_set_power_mgmt(struct wiphy
*wiphy
,
732 struct net_device
*dev
,
733 bool enabled
, int timeout
)
735 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
739 power_index
= IWM_POWER_INDEX_DEFAULT
;
741 power_index
= IWM_POWER_INDEX_MIN
;
743 if (power_index
== iwm
->conf
.power_index
)
746 iwm
->conf
.power_index
= power_index
;
748 return iwm_umac_set_config_fix(iwm
, UMAC_PARAM_TBL_CFG_FIX
,
749 CFG_POWER_INDEX
, iwm
->conf
.power_index
);
752 static int iwm_cfg80211_set_pmksa(struct wiphy
*wiphy
,
753 struct net_device
*netdev
,
754 struct cfg80211_pmksa
*pmksa
)
756 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
758 return iwm_send_pmkid_update(iwm
, pmksa
, IWM_CMD_PMKID_ADD
);
761 static int iwm_cfg80211_del_pmksa(struct wiphy
*wiphy
,
762 struct net_device
*netdev
,
763 struct cfg80211_pmksa
*pmksa
)
765 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
767 return iwm_send_pmkid_update(iwm
, pmksa
, IWM_CMD_PMKID_DEL
);
770 static int iwm_cfg80211_flush_pmksa(struct wiphy
*wiphy
,
771 struct net_device
*netdev
)
773 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
774 struct cfg80211_pmksa pmksa
;
776 memset(&pmksa
, 0, sizeof(struct cfg80211_pmksa
));
778 return iwm_send_pmkid_update(iwm
, &pmksa
, IWM_CMD_PMKID_FLUSH
);
782 static struct cfg80211_ops iwm_cfg80211_ops
= {
783 .change_virtual_intf
= iwm_cfg80211_change_iface
,
784 .add_key
= iwm_cfg80211_add_key
,
785 .get_key
= iwm_cfg80211_get_key
,
786 .del_key
= iwm_cfg80211_del_key
,
787 .set_default_key
= iwm_cfg80211_set_default_key
,
788 .get_station
= iwm_cfg80211_get_station
,
789 .scan
= iwm_cfg80211_scan
,
790 .set_wiphy_params
= iwm_cfg80211_set_wiphy_params
,
791 .connect
= iwm_cfg80211_connect
,
792 .disconnect
= iwm_cfg80211_disconnect
,
793 .join_ibss
= iwm_cfg80211_join_ibss
,
794 .leave_ibss
= iwm_cfg80211_leave_ibss
,
795 .set_tx_power
= iwm_cfg80211_set_txpower
,
796 .get_tx_power
= iwm_cfg80211_get_txpower
,
797 .set_power_mgmt
= iwm_cfg80211_set_power_mgmt
,
798 .set_pmksa
= iwm_cfg80211_set_pmksa
,
799 .del_pmksa
= iwm_cfg80211_del_pmksa
,
800 .flush_pmksa
= iwm_cfg80211_flush_pmksa
,
803 static const u32 cipher_suites
[] = {
804 WLAN_CIPHER_SUITE_WEP40
,
805 WLAN_CIPHER_SUITE_WEP104
,
806 WLAN_CIPHER_SUITE_TKIP
,
807 WLAN_CIPHER_SUITE_CCMP
,
810 struct wireless_dev
*iwm_wdev_alloc(int sizeof_bus
, struct device
*dev
)
813 struct wireless_dev
*wdev
;
816 * We're trying to have the following memory
819 * +-------------------------+
821 * +-------------------------+
822 * | struct iwm_priv |
823 * +-------------------------+
824 * | bus private data |
825 * | (e.g. iwm_priv_sdio) |
826 * +-------------------------+
830 wdev
= kzalloc(sizeof(struct wireless_dev
), GFP_KERNEL
);
832 dev_err(dev
, "Couldn't allocate wireless device\n");
833 return ERR_PTR(-ENOMEM
);
836 wdev
->wiphy
= wiphy_new(&iwm_cfg80211_ops
,
837 sizeof(struct iwm_priv
) + sizeof_bus
);
839 dev_err(dev
, "Couldn't allocate wiphy device\n");
844 set_wiphy_dev(wdev
->wiphy
, dev
);
845 wdev
->wiphy
->max_scan_ssids
= UMAC_WIFI_IF_PROBE_OPTION_MAX
;
846 wdev
->wiphy
->max_num_pmkids
= UMAC_MAX_NUM_PMKIDS
;
847 wdev
->wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
) |
848 BIT(NL80211_IFTYPE_ADHOC
);
849 wdev
->wiphy
->bands
[IEEE80211_BAND_2GHZ
] = &iwm_band_2ghz
;
850 wdev
->wiphy
->bands
[IEEE80211_BAND_5GHZ
] = &iwm_band_5ghz
;
851 wdev
->wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
853 wdev
->wiphy
->cipher_suites
= cipher_suites
;
854 wdev
->wiphy
->n_cipher_suites
= ARRAY_SIZE(cipher_suites
);
856 ret
= wiphy_register(wdev
->wiphy
);
858 dev_err(dev
, "Couldn't register wiphy device\n");
859 goto out_err_register
;
865 wiphy_free(wdev
->wiphy
);
873 void iwm_wdev_free(struct iwm_priv
*iwm
)
875 struct wireless_dev
*wdev
= iwm_to_wdev(iwm
);
880 wiphy_unregister(wdev
->wiphy
);
881 wiphy_free(wdev
->wiphy
);