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
);
191 struct key_params params
;
193 IWM_DBG_WEXT(iwm
, DBG
, "Getting key %d\n", key_index
);
195 if (key_index
>= IWM_NUM_KEYS
)
198 memset(¶ms
, 0, sizeof(params
));
200 key
= &iwm
->keys
[key_index
];
201 params
.cipher
= key
->cipher
;
202 params
.key_len
= key
->key_len
;
203 params
.seq_len
= key
->seq_len
;
204 params
.seq
= key
->seq
;
205 params
.key
= key
->key
;
207 callback(cookie
, ¶ms
);
209 return key
->key_len
? 0 : -ENOENT
;
213 static int iwm_cfg80211_del_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
214 u8 key_index
, bool pairwise
, const u8
*mac_addr
)
216 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
217 struct iwm_key
*key
= &iwm
->keys
[key_index
];
219 if (!iwm
->keys
[key_index
].key_len
) {
220 IWM_DBG_WEXT(iwm
, DBG
, "Key %d not used\n", key_index
);
224 if (key_index
== iwm
->default_key
)
225 iwm
->default_key
= -1;
227 return iwm_set_key(iwm
, 1, key
);
230 static int iwm_cfg80211_set_default_key(struct wiphy
*wiphy
,
231 struct net_device
*ndev
,
232 u8 key_index
, bool unicast
,
235 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
237 IWM_DBG_WEXT(iwm
, DBG
, "Default key index is: %d\n", key_index
);
239 if (!iwm
->keys
[key_index
].key_len
) {
240 IWM_ERR(iwm
, "Key %d not used\n", key_index
);
244 iwm
->default_key
= key_index
;
246 return iwm_set_tx_key(iwm
, key_index
);
249 static int iwm_cfg80211_get_station(struct wiphy
*wiphy
,
250 struct net_device
*ndev
,
251 u8
*mac
, struct station_info
*sinfo
)
253 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
255 if (memcmp(mac
, iwm
->bssid
, ETH_ALEN
))
258 sinfo
->filled
|= STATION_INFO_TX_BITRATE
;
259 sinfo
->txrate
.legacy
= iwm
->rate
* 10;
261 if (test_bit(IWM_STATUS_ASSOCIATED
, &iwm
->status
)) {
262 sinfo
->filled
|= STATION_INFO_SIGNAL
;
263 sinfo
->signal
= iwm
->wstats
.qual
.level
;
270 int iwm_cfg80211_inform_bss(struct iwm_priv
*iwm
)
272 struct wiphy
*wiphy
= iwm_to_wiphy(iwm
);
273 struct iwm_bss_info
*bss
;
274 struct iwm_umac_notif_bss_info
*umac_bss
;
275 struct ieee80211_mgmt
*mgmt
;
276 struct ieee80211_channel
*channel
;
277 struct ieee80211_supported_band
*band
;
281 list_for_each_entry(bss
, &iwm
->bss_list
, node
) {
283 mgmt
= (struct ieee80211_mgmt
*)(umac_bss
->frame_buf
);
285 if (umac_bss
->band
== UMAC_BAND_2GHZ
)
286 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
287 else if (umac_bss
->band
== UMAC_BAND_5GHZ
)
288 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
290 IWM_ERR(iwm
, "Invalid band: %d\n", umac_bss
->band
);
294 freq
= ieee80211_channel_to_frequency(umac_bss
->channel
,
296 channel
= ieee80211_get_channel(wiphy
, freq
);
297 signal
= umac_bss
->rssi
* 100;
299 if (!cfg80211_inform_bss_frame(wiphy
, channel
, mgmt
,
300 le16_to_cpu(umac_bss
->frame_len
),
308 static int iwm_cfg80211_change_iface(struct wiphy
*wiphy
,
309 struct net_device
*ndev
,
310 enum nl80211_iftype type
, u32
*flags
,
311 struct vif_params
*params
)
313 struct wireless_dev
*wdev
;
314 struct iwm_priv
*iwm
;
317 wdev
= ndev
->ieee80211_ptr
;
318 iwm
= ndev_to_iwm(ndev
);
319 old_mode
= iwm
->conf
.mode
;
322 case NL80211_IFTYPE_STATION
:
323 iwm
->conf
.mode
= UMAC_MODE_BSS
;
325 case NL80211_IFTYPE_ADHOC
:
326 iwm
->conf
.mode
= UMAC_MODE_IBSS
;
334 if ((old_mode
== iwm
->conf
.mode
) || !iwm
->umac_profile
)
337 iwm
->umac_profile
->mode
= cpu_to_le32(iwm
->conf
.mode
);
339 if (iwm
->umac_profile_active
)
340 iwm_invalidate_mlme_profile(iwm
);
345 static int iwm_cfg80211_scan(struct wiphy
*wiphy
, struct net_device
*ndev
,
346 struct cfg80211_scan_request
*request
)
348 struct iwm_priv
*iwm
= ndev_to_iwm(ndev
);
351 if (!test_bit(IWM_STATUS_READY
, &iwm
->status
)) {
352 IWM_ERR(iwm
, "Scan while device is not ready\n");
356 if (test_bit(IWM_STATUS_SCANNING
, &iwm
->status
)) {
357 IWM_ERR(iwm
, "Scanning already\n");
361 if (test_bit(IWM_STATUS_SCAN_ABORTING
, &iwm
->status
)) {
362 IWM_ERR(iwm
, "Scanning being aborted\n");
366 set_bit(IWM_STATUS_SCANNING
, &iwm
->status
);
368 ret
= iwm_scan_ssids(iwm
, request
->ssids
, request
->n_ssids
);
370 clear_bit(IWM_STATUS_SCANNING
, &iwm
->status
);
374 iwm
->scan_request
= request
;
378 static int iwm_cfg80211_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
)
380 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
382 if (changed
& WIPHY_PARAM_RTS_THRESHOLD
&&
383 (iwm
->conf
.rts_threshold
!= wiphy
->rts_threshold
)) {
386 iwm
->conf
.rts_threshold
= wiphy
->rts_threshold
;
388 ret
= iwm_umac_set_config_fix(iwm
, UMAC_PARAM_TBL_CFG_FIX
,
390 iwm
->conf
.rts_threshold
);
395 if (changed
& WIPHY_PARAM_FRAG_THRESHOLD
&&
396 (iwm
->conf
.frag_threshold
!= wiphy
->frag_threshold
)) {
399 iwm
->conf
.frag_threshold
= wiphy
->frag_threshold
;
401 ret
= iwm_umac_set_config_fix(iwm
, UMAC_PARAM_TBL_FA_CFG_FIX
,
403 iwm
->conf
.frag_threshold
);
411 static int iwm_cfg80211_join_ibss(struct wiphy
*wiphy
, struct net_device
*dev
,
412 struct cfg80211_ibss_params
*params
)
414 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
415 struct ieee80211_channel
*chan
= params
->channel
;
417 if (!test_bit(IWM_STATUS_READY
, &iwm
->status
))
420 /* UMAC doesn't support creating or joining an IBSS network
421 * with specified bssid. */
425 iwm
->channel
= ieee80211_frequency_to_channel(chan
->center_freq
);
426 iwm
->umac_profile
->ibss
.band
= chan
->band
;
427 iwm
->umac_profile
->ibss
.channel
= iwm
->channel
;
428 iwm
->umac_profile
->ssid
.ssid_len
= params
->ssid_len
;
429 memcpy(iwm
->umac_profile
->ssid
.ssid
, params
->ssid
, params
->ssid_len
);
431 return iwm_send_mlme_profile(iwm
);
434 static int iwm_cfg80211_leave_ibss(struct wiphy
*wiphy
, struct net_device
*dev
)
436 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
438 if (iwm
->umac_profile_active
)
439 return iwm_invalidate_mlme_profile(iwm
);
444 static int iwm_set_auth_type(struct iwm_priv
*iwm
,
445 enum nl80211_auth_type sme_auth_type
)
447 u8
*auth_type
= &iwm
->umac_profile
->sec
.auth_type
;
449 switch (sme_auth_type
) {
450 case NL80211_AUTHTYPE_AUTOMATIC
:
451 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
452 IWM_DBG_WEXT(iwm
, DBG
, "OPEN auth\n");
453 *auth_type
= UMAC_AUTH_TYPE_OPEN
;
455 case NL80211_AUTHTYPE_SHARED_KEY
:
456 if (iwm
->umac_profile
->sec
.flags
&
457 (UMAC_SEC_FLG_WPA_ON_MSK
| UMAC_SEC_FLG_RSNA_ON_MSK
)) {
458 IWM_DBG_WEXT(iwm
, DBG
, "WPA auth alg\n");
459 *auth_type
= UMAC_AUTH_TYPE_RSNA_PSK
;
461 IWM_DBG_WEXT(iwm
, DBG
, "WEP shared key auth alg\n");
462 *auth_type
= UMAC_AUTH_TYPE_LEGACY_PSK
;
467 IWM_ERR(iwm
, "Unsupported auth alg: 0x%x\n", sme_auth_type
);
474 static int iwm_set_wpa_version(struct iwm_priv
*iwm
, u32 wpa_version
)
476 IWM_DBG_WEXT(iwm
, DBG
, "wpa_version: %d\n", wpa_version
);
479 iwm
->umac_profile
->sec
.flags
= UMAC_SEC_FLG_LEGACY_PROFILE
;
483 if (wpa_version
& NL80211_WPA_VERSION_1
)
484 iwm
->umac_profile
->sec
.flags
= UMAC_SEC_FLG_WPA_ON_MSK
;
486 if (wpa_version
& NL80211_WPA_VERSION_2
)
487 iwm
->umac_profile
->sec
.flags
= UMAC_SEC_FLG_RSNA_ON_MSK
;
492 static int iwm_set_cipher(struct iwm_priv
*iwm
, u32 cipher
, bool ucast
)
494 u8
*profile_cipher
= ucast
? &iwm
->umac_profile
->sec
.ucast_cipher
:
495 &iwm
->umac_profile
->sec
.mcast_cipher
;
498 *profile_cipher
= UMAC_CIPHER_TYPE_NONE
;
502 IWM_DBG_WEXT(iwm
, DBG
, "%ccast cipher is 0x%x\n", ucast
? 'u' : 'm',
506 case IW_AUTH_CIPHER_NONE
:
507 *profile_cipher
= UMAC_CIPHER_TYPE_NONE
;
509 case WLAN_CIPHER_SUITE_WEP40
:
510 *profile_cipher
= UMAC_CIPHER_TYPE_WEP_40
;
512 case WLAN_CIPHER_SUITE_WEP104
:
513 *profile_cipher
= UMAC_CIPHER_TYPE_WEP_104
;
515 case WLAN_CIPHER_SUITE_TKIP
:
516 *profile_cipher
= UMAC_CIPHER_TYPE_TKIP
;
518 case WLAN_CIPHER_SUITE_CCMP
:
519 *profile_cipher
= UMAC_CIPHER_TYPE_CCMP
;
522 IWM_ERR(iwm
, "Unsupported cipher: 0x%x\n", cipher
);
529 static int iwm_set_key_mgt(struct iwm_priv
*iwm
, u32 key_mgt
)
531 u8
*auth_type
= &iwm
->umac_profile
->sec
.auth_type
;
533 IWM_DBG_WEXT(iwm
, DBG
, "key_mgt: 0x%x\n", key_mgt
);
535 if (key_mgt
== WLAN_AKM_SUITE_8021X
)
536 *auth_type
= UMAC_AUTH_TYPE_8021X
;
537 else if (key_mgt
== WLAN_AKM_SUITE_PSK
) {
538 if (iwm
->umac_profile
->sec
.flags
&
539 (UMAC_SEC_FLG_WPA_ON_MSK
| UMAC_SEC_FLG_RSNA_ON_MSK
))
540 *auth_type
= UMAC_AUTH_TYPE_RSNA_PSK
;
542 *auth_type
= UMAC_AUTH_TYPE_LEGACY_PSK
;
544 IWM_ERR(iwm
, "Invalid key mgt: 0x%x\n", key_mgt
);
552 static int iwm_cfg80211_connect(struct wiphy
*wiphy
, struct net_device
*dev
,
553 struct cfg80211_connect_params
*sme
)
555 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
556 struct ieee80211_channel
*chan
= sme
->channel
;
557 struct key_params key_param
;
560 if (!test_bit(IWM_STATUS_READY
, &iwm
->status
))
566 if (iwm
->umac_profile_active
) {
567 ret
= iwm_invalidate_mlme_profile(iwm
);
569 IWM_ERR(iwm
, "Couldn't invalidate profile\n");
576 ieee80211_frequency_to_channel(chan
->center_freq
);
578 iwm
->umac_profile
->ssid
.ssid_len
= sme
->ssid_len
;
579 memcpy(iwm
->umac_profile
->ssid
.ssid
, sme
->ssid
, sme
->ssid_len
);
582 IWM_DBG_WEXT(iwm
, DBG
, "BSSID: %pM\n", sme
->bssid
);
583 memcpy(&iwm
->umac_profile
->bssid
[0], sme
->bssid
, ETH_ALEN
);
584 iwm
->umac_profile
->bss_num
= 1;
586 memset(&iwm
->umac_profile
->bssid
[0], 0, ETH_ALEN
);
587 iwm
->umac_profile
->bss_num
= 0;
590 ret
= iwm_set_wpa_version(iwm
, sme
->crypto
.wpa_versions
);
594 ret
= iwm_set_auth_type(iwm
, sme
->auth_type
);
598 if (sme
->crypto
.n_ciphers_pairwise
) {
599 ret
= iwm_set_cipher(iwm
, sme
->crypto
.ciphers_pairwise
[0],
605 ret
= iwm_set_cipher(iwm
, sme
->crypto
.cipher_group
, false);
609 if (sme
->crypto
.n_akm_suites
) {
610 ret
= iwm_set_key_mgt(iwm
, sme
->crypto
.akm_suites
[0]);
616 * We save the WEP key in case we want to do shared authentication.
617 * We have to do it so because UMAC will assert whenever it gets a
618 * key before a profile.
621 key_param
.key
= kmemdup(sme
->key
, sme
->key_len
, GFP_KERNEL
);
622 if (key_param
.key
== NULL
)
624 key_param
.key_len
= sme
->key_len
;
625 key_param
.seq_len
= 0;
626 key_param
.cipher
= sme
->crypto
.ciphers_pairwise
[0];
628 ret
= iwm_key_init(&iwm
->keys
[sme
->key_idx
], sme
->key_idx
,
630 kfree(key_param
.key
);
632 IWM_ERR(iwm
, "Invalid key_params\n");
636 iwm
->default_key
= sme
->key_idx
;
639 /* WPA and open AUTH type from wpa_s means WPS (a.k.a. WSC) */
640 if ((iwm
->umac_profile
->sec
.flags
&
641 (UMAC_SEC_FLG_WPA_ON_MSK
| UMAC_SEC_FLG_RSNA_ON_MSK
)) &&
642 iwm
->umac_profile
->sec
.auth_type
== UMAC_AUTH_TYPE_OPEN
) {
643 iwm
->umac_profile
->sec
.flags
= UMAC_SEC_FLG_WSC_ON_MSK
;
646 ret
= iwm_send_mlme_profile(iwm
);
648 if (iwm
->umac_profile
->sec
.auth_type
!= UMAC_AUTH_TYPE_LEGACY_PSK
||
653 * We want to do shared auth.
654 * We need to actually set the key we previously cached,
655 * and then tell the UMAC it's the default one.
656 * That will trigger the auth+assoc UMAC machinery, and again,
657 * this must be done after setting the profile.
659 ret
= iwm_set_key(iwm
, 0, &iwm
->keys
[sme
->key_idx
]);
663 return iwm_set_tx_key(iwm
, iwm
->default_key
);
666 static int iwm_cfg80211_disconnect(struct wiphy
*wiphy
, struct net_device
*dev
,
669 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
671 IWM_DBG_WEXT(iwm
, DBG
, "Active: %d\n", iwm
->umac_profile_active
);
673 if (iwm
->umac_profile_active
)
674 iwm_invalidate_mlme_profile(iwm
);
679 static int iwm_cfg80211_set_txpower(struct wiphy
*wiphy
,
680 enum nl80211_tx_power_setting type
, int mbm
)
682 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
686 case NL80211_TX_POWER_AUTOMATIC
:
688 case NL80211_TX_POWER_FIXED
:
689 if (mbm
< 0 || (mbm
% 100))
692 if (!test_bit(IWM_STATUS_READY
, &iwm
->status
))
695 ret
= iwm_umac_set_config_fix(iwm
, UMAC_PARAM_TBL_CFG_FIX
,
696 CFG_TX_PWR_LIMIT_USR
,
697 MBM_TO_DBM(mbm
) * 2);
701 return iwm_tx_power_trigger(iwm
);
703 IWM_ERR(iwm
, "Unsupported power type: %d\n", type
);
710 static int iwm_cfg80211_get_txpower(struct wiphy
*wiphy
, int *dbm
)
712 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
714 *dbm
= iwm
->txpower
>> 1;
719 static int iwm_cfg80211_set_power_mgmt(struct wiphy
*wiphy
,
720 struct net_device
*dev
,
721 bool enabled
, int timeout
)
723 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
727 power_index
= IWM_POWER_INDEX_DEFAULT
;
729 power_index
= IWM_POWER_INDEX_MIN
;
731 if (power_index
== iwm
->conf
.power_index
)
734 iwm
->conf
.power_index
= power_index
;
736 return iwm_umac_set_config_fix(iwm
, UMAC_PARAM_TBL_CFG_FIX
,
737 CFG_POWER_INDEX
, iwm
->conf
.power_index
);
740 static int iwm_cfg80211_set_pmksa(struct wiphy
*wiphy
,
741 struct net_device
*netdev
,
742 struct cfg80211_pmksa
*pmksa
)
744 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
746 return iwm_send_pmkid_update(iwm
, pmksa
, IWM_CMD_PMKID_ADD
);
749 static int iwm_cfg80211_del_pmksa(struct wiphy
*wiphy
,
750 struct net_device
*netdev
,
751 struct cfg80211_pmksa
*pmksa
)
753 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
755 return iwm_send_pmkid_update(iwm
, pmksa
, IWM_CMD_PMKID_DEL
);
758 static int iwm_cfg80211_flush_pmksa(struct wiphy
*wiphy
,
759 struct net_device
*netdev
)
761 struct iwm_priv
*iwm
= wiphy_to_iwm(wiphy
);
762 struct cfg80211_pmksa pmksa
;
764 memset(&pmksa
, 0, sizeof(struct cfg80211_pmksa
));
766 return iwm_send_pmkid_update(iwm
, &pmksa
, IWM_CMD_PMKID_FLUSH
);
770 static struct cfg80211_ops iwm_cfg80211_ops
= {
771 .change_virtual_intf
= iwm_cfg80211_change_iface
,
772 .add_key
= iwm_cfg80211_add_key
,
773 .get_key
= iwm_cfg80211_get_key
,
774 .del_key
= iwm_cfg80211_del_key
,
775 .set_default_key
= iwm_cfg80211_set_default_key
,
776 .get_station
= iwm_cfg80211_get_station
,
777 .scan
= iwm_cfg80211_scan
,
778 .set_wiphy_params
= iwm_cfg80211_set_wiphy_params
,
779 .connect
= iwm_cfg80211_connect
,
780 .disconnect
= iwm_cfg80211_disconnect
,
781 .join_ibss
= iwm_cfg80211_join_ibss
,
782 .leave_ibss
= iwm_cfg80211_leave_ibss
,
783 .set_tx_power
= iwm_cfg80211_set_txpower
,
784 .get_tx_power
= iwm_cfg80211_get_txpower
,
785 .set_power_mgmt
= iwm_cfg80211_set_power_mgmt
,
786 .set_pmksa
= iwm_cfg80211_set_pmksa
,
787 .del_pmksa
= iwm_cfg80211_del_pmksa
,
788 .flush_pmksa
= iwm_cfg80211_flush_pmksa
,
791 static const u32 cipher_suites
[] = {
792 WLAN_CIPHER_SUITE_WEP40
,
793 WLAN_CIPHER_SUITE_WEP104
,
794 WLAN_CIPHER_SUITE_TKIP
,
795 WLAN_CIPHER_SUITE_CCMP
,
798 struct wireless_dev
*iwm_wdev_alloc(int sizeof_bus
, struct device
*dev
)
801 struct wireless_dev
*wdev
;
804 * We're trying to have the following memory
807 * +-------------------------+
809 * +-------------------------+
810 * | struct iwm_priv |
811 * +-------------------------+
812 * | bus private data |
813 * | (e.g. iwm_priv_sdio) |
814 * +-------------------------+
818 wdev
= kzalloc(sizeof(struct wireless_dev
), GFP_KERNEL
);
820 dev_err(dev
, "Couldn't allocate wireless device\n");
821 return ERR_PTR(-ENOMEM
);
824 wdev
->wiphy
= wiphy_new(&iwm_cfg80211_ops
,
825 sizeof(struct iwm_priv
) + sizeof_bus
);
827 dev_err(dev
, "Couldn't allocate wiphy device\n");
832 set_wiphy_dev(wdev
->wiphy
, dev
);
833 wdev
->wiphy
->max_scan_ssids
= UMAC_WIFI_IF_PROBE_OPTION_MAX
;
834 wdev
->wiphy
->max_num_pmkids
= UMAC_MAX_NUM_PMKIDS
;
835 wdev
->wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
) |
836 BIT(NL80211_IFTYPE_ADHOC
);
837 wdev
->wiphy
->bands
[IEEE80211_BAND_2GHZ
] = &iwm_band_2ghz
;
838 wdev
->wiphy
->bands
[IEEE80211_BAND_5GHZ
] = &iwm_band_5ghz
;
839 wdev
->wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
841 wdev
->wiphy
->cipher_suites
= cipher_suites
;
842 wdev
->wiphy
->n_cipher_suites
= ARRAY_SIZE(cipher_suites
);
844 ret
= wiphy_register(wdev
->wiphy
);
846 dev_err(dev
, "Couldn't register wiphy device\n");
847 goto out_err_register
;
853 wiphy_free(wdev
->wiphy
);
861 void iwm_wdev_free(struct iwm_priv
*iwm
)
863 struct wireless_dev
*wdev
= iwm_to_wdev(iwm
);
868 wiphy_unregister(wdev
->wiphy
);
869 wiphy_free(wdev
->wiphy
);