Linux Audio

Check our new training course

Real-Time Linux with PREEMPT_RT training

Feb 18-20, 2025
Register
Loading...
v3.1
  1/*
  2 * Intel Wireless Multicomm 3200 WiFi driver
  3 *
  4 * Copyright (C) 2009 Intel Corporation <ilw@linux.intel.com>
  5 * Samuel Ortiz <samuel.ortiz@intel.com>
  6 * Zhu Yi <yi.zhu@intel.com>
  7 *
  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.
 11 *
 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.
 16 *
 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
 20 * 02110-1301, USA.
 21 *
 22 */
 23
 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>
 32
 33#include "iwm.h"
 34#include "commands.h"
 35#include "cfg80211.h"
 36#include "debug.h"
 37
 38#define RATETAB_ENT(_rate, _rateid, _flags) \
 39	{								\
 40		.bitrate	= (_rate),				\
 41		.hw_value	= (_rateid),				\
 42		.flags		= (_flags),				\
 43	}
 44
 45#define CHAN2G(_channel, _freq, _flags) {			\
 46	.band			= IEEE80211_BAND_2GHZ,		\
 47	.center_freq		= (_freq),			\
 48	.hw_value		= (_channel),			\
 49	.flags			= (_flags),			\
 50	.max_antenna_gain	= 0,				\
 51	.max_power		= 30,				\
 52}
 53
 54#define CHAN5G(_channel, _flags) {				\
 55	.band			= IEEE80211_BAND_5GHZ,		\
 56	.center_freq		= 5000 + (5 * (_channel)),	\
 57	.hw_value		= (_channel),			\
 58	.flags			= (_flags),			\
 59	.max_antenna_gain	= 0,				\
 60	.max_power		= 30,				\
 61}
 62
 63static 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),
 76};
 77
 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
 82
 83static struct ieee80211_channel iwm_2ghz_channels[] = {
 84	CHAN2G(1, 2412, 0),
 85	CHAN2G(2, 2417, 0),
 86	CHAN2G(3, 2422, 0),
 87	CHAN2G(4, 2427, 0),
 88	CHAN2G(5, 2432, 0),
 89	CHAN2G(6, 2437, 0),
 90	CHAN2G(7, 2442, 0),
 91	CHAN2G(8, 2447, 0),
 92	CHAN2G(9, 2452, 0),
 93	CHAN2G(10, 2457, 0),
 94	CHAN2G(11, 2462, 0),
 95	CHAN2G(12, 2467, 0),
 96	CHAN2G(13, 2472, 0),
 97	CHAN2G(14, 2484, 0),
 98};
 99
100static 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),
119	CHAN5G(216, 0),
120};
121
122static 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,
127};
128
129static 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,
134};
135
136static int iwm_key_init(struct iwm_key *key, u8 key_index,
137			const u8 *mac_addr, struct key_params *params)
138{
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);
143	} else {
144		key->hdr.multicast = 0;
145		memcpy(key->hdr.mac, mac_addr, ETH_ALEN);
146	}
147
148	if (params) {
149		if (params->key_len > WLAN_MAX_KEY_LEN ||
150		    params->seq_len > IW_ENCODE_SEQ_MAX_SIZE)
151			return -EINVAL;
152
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);
158	}
159
160	return 0;
161}
162
163static 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)
166{
167	struct iwm_priv *iwm = ndev_to_iwm(ndev);
168	struct iwm_key *key = &iwm->keys[key_index];
169	int ret;
170
171	IWM_DBG_WEXT(iwm, DBG, "Adding key for %pM\n", mac_addr);
172
 
 
 
 
173	memset(key, 0, sizeof(struct iwm_key));
174	ret = iwm_key_init(key, key_index, mac_addr, params);
175	if (ret < 0) {
176		IWM_ERR(iwm, "Invalid key_params\n");
177		return ret;
178	}
179
180	return iwm_set_key(iwm, 0, key);
181}
182
183static int iwm_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
184				u8 key_index, bool pairwise, const u8 *mac_addr,
185				void *cookie,
186				void (*callback)(void *cookie,
187						 struct key_params*))
188{
189	struct iwm_priv *iwm = ndev_to_iwm(ndev);
190	struct iwm_key *key = &iwm->keys[key_index];
191	struct key_params params;
192
193	IWM_DBG_WEXT(iwm, DBG, "Getting key %d\n", key_index);
194
 
 
 
195	memset(&params, 0, sizeof(params));
196
 
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;
202
203	callback(cookie, &params);
204
205	return key->key_len ? 0 : -ENOENT;
206}
207
208
209static int iwm_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
210				u8 key_index, bool pairwise, const u8 *mac_addr)
211{
212	struct iwm_priv *iwm = ndev_to_iwm(ndev);
213	struct iwm_key *key = &iwm->keys[key_index];
214
 
 
 
 
215	if (!iwm->keys[key_index].key_len) {
216		IWM_DBG_WEXT(iwm, DBG, "Key %d not used\n", key_index);
217		return 0;
218	}
219
220	if (key_index == iwm->default_key)
221		iwm->default_key = -1;
222
223	return iwm_set_key(iwm, 1, key);
224}
225
226static int iwm_cfg80211_set_default_key(struct wiphy *wiphy,
227					struct net_device *ndev,
228					u8 key_index, bool unicast,
229					bool multicast)
230{
231	struct iwm_priv *iwm = ndev_to_iwm(ndev);
232
233	IWM_DBG_WEXT(iwm, DBG, "Default key index is: %d\n", key_index);
 
 
 
234
235	if (!iwm->keys[key_index].key_len) {
236		IWM_ERR(iwm, "Key %d not used\n", key_index);
237		return -EINVAL;
238	}
239
240	iwm->default_key = key_index;
241
242	return iwm_set_tx_key(iwm, key_index);
243}
244
245static int iwm_cfg80211_get_station(struct wiphy *wiphy,
246				    struct net_device *ndev,
247				    u8 *mac, struct station_info *sinfo)
248{
249	struct iwm_priv *iwm = ndev_to_iwm(ndev);
250
251	if (memcmp(mac, iwm->bssid, ETH_ALEN))
252		return -ENOENT;
253
254	sinfo->filled |= STATION_INFO_TX_BITRATE;
255	sinfo->txrate.legacy = iwm->rate * 10;
256
257	if (test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)) {
258		sinfo->filled |= STATION_INFO_SIGNAL;
259		sinfo->signal = iwm->wstats.qual.level;
260	}
261
262	return 0;
263}
264
265
266int iwm_cfg80211_inform_bss(struct iwm_priv *iwm)
267{
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;
274	s32 signal;
275	int freq;
276
277	list_for_each_entry(bss, &iwm->bss_list, node) {
278		umac_bss = bss->bss;
279		mgmt = (struct ieee80211_mgmt *)(umac_bss->frame_buf);
280
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];
285		else {
286			IWM_ERR(iwm, "Invalid band: %d\n", umac_bss->band);
287			return -EINVAL;
288		}
289
290		freq = ieee80211_channel_to_frequency(umac_bss->channel,
291						      band->band);
292		channel = ieee80211_get_channel(wiphy, freq);
293		signal = umac_bss->rssi * 100;
294
295		if (!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
296					       le16_to_cpu(umac_bss->frame_len),
297					       signal, GFP_KERNEL))
298			return -EINVAL;
299	}
300
301	return 0;
302}
303
304static 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)
308{
309	struct wireless_dev *wdev;
310	struct iwm_priv *iwm;
311	u32 old_mode;
312
313	wdev = ndev->ieee80211_ptr;
314	iwm = ndev_to_iwm(ndev);
315	old_mode = iwm->conf.mode;
316
317	switch (type) {
318	case NL80211_IFTYPE_STATION:
319		iwm->conf.mode = UMAC_MODE_BSS;
320		break;
321	case NL80211_IFTYPE_ADHOC:
322		iwm->conf.mode = UMAC_MODE_IBSS;
323		break;
324	default:
325		return -EOPNOTSUPP;
326	}
327
328	wdev->iftype = type;
329
330	if ((old_mode == iwm->conf.mode) || !iwm->umac_profile)
331		return 0;
332
333	iwm->umac_profile->mode = cpu_to_le32(iwm->conf.mode);
334
335	if (iwm->umac_profile_active)
336		iwm_invalidate_mlme_profile(iwm);
337
338	return 0;
339}
340
341static int iwm_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
342			     struct cfg80211_scan_request *request)
343{
344	struct iwm_priv *iwm = ndev_to_iwm(ndev);
345	int ret;
346
347	if (!test_bit(IWM_STATUS_READY, &iwm->status)) {
348		IWM_ERR(iwm, "Scan while device is not ready\n");
349		return -EIO;
350	}
351
352	if (test_bit(IWM_STATUS_SCANNING, &iwm->status)) {
353		IWM_ERR(iwm, "Scanning already\n");
354		return -EAGAIN;
355	}
356
357	if (test_bit(IWM_STATUS_SCAN_ABORTING, &iwm->status)) {
358		IWM_ERR(iwm, "Scanning being aborted\n");
359		return -EAGAIN;
360	}
361
362	set_bit(IWM_STATUS_SCANNING, &iwm->status);
363
364	ret = iwm_scan_ssids(iwm, request->ssids, request->n_ssids);
365	if (ret) {
366		clear_bit(IWM_STATUS_SCANNING, &iwm->status);
367		return ret;
368	}
369
370	iwm->scan_request = request;
371	return 0;
372}
373
374static int iwm_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
375{
376	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
377
378	if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
379	    (iwm->conf.rts_threshold != wiphy->rts_threshold)) {
380		int ret;
381
382		iwm->conf.rts_threshold = wiphy->rts_threshold;
383
384		ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
385					     CFG_RTS_THRESHOLD,
386					     iwm->conf.rts_threshold);
387		if (ret < 0)
388			return ret;
389	}
390
391	if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
392	    (iwm->conf.frag_threshold != wiphy->frag_threshold)) {
393		int ret;
394
395		iwm->conf.frag_threshold = wiphy->frag_threshold;
396
397		ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX,
398					     CFG_FRAG_THRESHOLD,
399					     iwm->conf.frag_threshold);
400		if (ret < 0)
401			return ret;
402	}
403
404	return 0;
405}
406
407static int iwm_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
408				  struct cfg80211_ibss_params *params)
409{
410	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
411	struct ieee80211_channel *chan = params->channel;
412
413	if (!test_bit(IWM_STATUS_READY, &iwm->status))
414		return -EIO;
415
416	/* UMAC doesn't support creating or joining an IBSS network
417	 * with specified bssid. */
418	if (params->bssid)
419		return -EOPNOTSUPP;
420
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);
426
427	return iwm_send_mlme_profile(iwm);
428}
429
430static int iwm_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
431{
432	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
433
434	if (iwm->umac_profile_active)
435		return iwm_invalidate_mlme_profile(iwm);
436
437	return 0;
438}
439
440static int iwm_set_auth_type(struct iwm_priv *iwm,
441			     enum nl80211_auth_type sme_auth_type)
442{
443	u8 *auth_type = &iwm->umac_profile->sec.auth_type;
444
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;
450		break;
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;
456		} else {
457			IWM_DBG_WEXT(iwm, DBG, "WEP shared key auth alg\n");
458			*auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
459		}
460
461		break;
462	default:
463		IWM_ERR(iwm, "Unsupported auth alg: 0x%x\n", sme_auth_type);
464		return -ENOTSUPP;
465	}
466
467	return 0;
468}
469
470static int iwm_set_wpa_version(struct iwm_priv *iwm, u32 wpa_version)
471{
472	IWM_DBG_WEXT(iwm, DBG, "wpa_version: %d\n", wpa_version);
473
474	if (!wpa_version) {
475		iwm->umac_profile->sec.flags = UMAC_SEC_FLG_LEGACY_PROFILE;
476		return 0;
477	}
478
479	if (wpa_version & NL80211_WPA_VERSION_1)
480		iwm->umac_profile->sec.flags = UMAC_SEC_FLG_WPA_ON_MSK;
481
482	if (wpa_version & NL80211_WPA_VERSION_2)
483		iwm->umac_profile->sec.flags = UMAC_SEC_FLG_RSNA_ON_MSK;
484
485	return 0;
486}
487
488static int iwm_set_cipher(struct iwm_priv *iwm, u32 cipher, bool ucast)
489{
490	u8 *profile_cipher = ucast ? &iwm->umac_profile->sec.ucast_cipher :
491		&iwm->umac_profile->sec.mcast_cipher;
492
493	if (!cipher) {
494		*profile_cipher = UMAC_CIPHER_TYPE_NONE;
495		return 0;
496	}
497
498	IWM_DBG_WEXT(iwm, DBG, "%ccast cipher is 0x%x\n", ucast ? 'u' : 'm',
499		     cipher);
500
501	switch (cipher) {
502	case IW_AUTH_CIPHER_NONE:
503		*profile_cipher = UMAC_CIPHER_TYPE_NONE;
504		break;
505	case WLAN_CIPHER_SUITE_WEP40:
506		*profile_cipher = UMAC_CIPHER_TYPE_WEP_40;
507		break;
508	case WLAN_CIPHER_SUITE_WEP104:
509		*profile_cipher = UMAC_CIPHER_TYPE_WEP_104;
510		break;
511	case WLAN_CIPHER_SUITE_TKIP:
512		*profile_cipher = UMAC_CIPHER_TYPE_TKIP;
513		break;
514	case WLAN_CIPHER_SUITE_CCMP:
515		*profile_cipher = UMAC_CIPHER_TYPE_CCMP;
516		break;
517	default:
518		IWM_ERR(iwm, "Unsupported cipher: 0x%x\n", cipher);
519		return -ENOTSUPP;
520	}
521
522	return 0;
523}
524
525static int iwm_set_key_mgt(struct iwm_priv *iwm, u32 key_mgt)
526{
527	u8 *auth_type = &iwm->umac_profile->sec.auth_type;
528
529	IWM_DBG_WEXT(iwm, DBG, "key_mgt: 0x%x\n", key_mgt);
530
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;
537		else
538			*auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
539	} else {
540		IWM_ERR(iwm, "Invalid key mgt: 0x%x\n", key_mgt);
541		return -EINVAL;
542	}
543
544	return 0;
545}
546
547
548static int iwm_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
549				 struct cfg80211_connect_params *sme)
550{
551	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
552	struct ieee80211_channel *chan = sme->channel;
553	struct key_params key_param;
554	int ret;
555
556	if (!test_bit(IWM_STATUS_READY, &iwm->status))
557		return -EIO;
558
559	if (!sme->ssid)
560		return -EINVAL;
561
562	if (iwm->umac_profile_active) {
563		ret = iwm_invalidate_mlme_profile(iwm);
564		if (ret) {
565			IWM_ERR(iwm, "Couldn't invalidate profile\n");
566			return ret;
567		}
568	}
569
570	if (chan)
571		iwm->channel =
572			ieee80211_frequency_to_channel(chan->center_freq);
573
574	iwm->umac_profile->ssid.ssid_len = sme->ssid_len;
575	memcpy(iwm->umac_profile->ssid.ssid, sme->ssid, sme->ssid_len);
576
577	if (sme->bssid) {
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;
581	} else {
582		memset(&iwm->umac_profile->bssid[0], 0, ETH_ALEN);
583		iwm->umac_profile->bss_num = 0;
584	}
585
586	ret = iwm_set_wpa_version(iwm, sme->crypto.wpa_versions);
587	if (ret < 0)
588		return ret;
589
590	ret = iwm_set_auth_type(iwm, sme->auth_type);
591	if (ret < 0)
592		return ret;
593
594	if (sme->crypto.n_ciphers_pairwise) {
595		ret = iwm_set_cipher(iwm, sme->crypto.ciphers_pairwise[0],
596				     true);
597		if (ret < 0)
598			return ret;
599	}
600
601	ret = iwm_set_cipher(iwm, sme->crypto.cipher_group, false);
602	if (ret < 0)
603		return ret;
604
605	if (sme->crypto.n_akm_suites) {
606		ret = iwm_set_key_mgt(iwm, sme->crypto.akm_suites[0]);
607		if (ret < 0)
608			return ret;
609	}
610
611	/*
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.
615	 */
616	if (sme->key) {
617		key_param.key = kmemdup(sme->key, sme->key_len, GFP_KERNEL);
618		if (key_param.key == NULL)
619			return -ENOMEM;
620		key_param.key_len = sme->key_len;
621		key_param.seq_len = 0;
622		key_param.cipher = sme->crypto.ciphers_pairwise[0];
623
624		ret = iwm_key_init(&iwm->keys[sme->key_idx], sme->key_idx,
625				   NULL, &key_param);
626		kfree(key_param.key);
627		if (ret < 0) {
628			IWM_ERR(iwm, "Invalid key_params\n");
629			return ret;
630		}
631
632		iwm->default_key = sme->key_idx;
633	}
634
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;
640	}
641
642	ret = iwm_send_mlme_profile(iwm);
643
644	if (iwm->umac_profile->sec.auth_type != UMAC_AUTH_TYPE_LEGACY_PSK ||
645	    sme->key == NULL)
646		return ret;
647
648	/*
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.
654	 */
655	ret = iwm_set_key(iwm, 0, &iwm->keys[sme->key_idx]);
656	if (ret < 0)
657		return ret;
658
659	return iwm_set_tx_key(iwm, iwm->default_key);
660}
661
662static int iwm_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
663				   u16 reason_code)
664{
665	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
666
667	IWM_DBG_WEXT(iwm, DBG, "Active: %d\n", iwm->umac_profile_active);
668
669	if (iwm->umac_profile_active)
670		iwm_invalidate_mlme_profile(iwm);
671
672	return 0;
673}
674
675static int iwm_cfg80211_set_txpower(struct wiphy *wiphy,
676				    enum nl80211_tx_power_setting type, int mbm)
677{
678	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
679	int ret;
680
681	switch (type) {
682	case NL80211_TX_POWER_AUTOMATIC:
683		return 0;
684	case NL80211_TX_POWER_FIXED:
685		if (mbm < 0 || (mbm % 100))
686			return -EOPNOTSUPP;
687
688		if (!test_bit(IWM_STATUS_READY, &iwm->status))
689			return 0;
690
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);
694		if (ret < 0)
695			return ret;
696
697		return iwm_tx_power_trigger(iwm);
698	default:
699		IWM_ERR(iwm, "Unsupported power type: %d\n", type);
700		return -EOPNOTSUPP;
701	}
702
703	return 0;
704}
705
706static int iwm_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
707{
708	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
709
710	*dbm = iwm->txpower >> 1;
711
712	return 0;
713}
714
715static int iwm_cfg80211_set_power_mgmt(struct wiphy *wiphy,
716				       struct net_device *dev,
717				       bool enabled, int timeout)
718{
719	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
720	u32 power_index;
721
722	if (enabled)
723		power_index = IWM_POWER_INDEX_DEFAULT;
724	else
725		power_index = IWM_POWER_INDEX_MIN;
726
727	if (power_index == iwm->conf.power_index)
728		return 0;
729
730	iwm->conf.power_index = power_index;
731
732	return iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
733				       CFG_POWER_INDEX, iwm->conf.power_index);
734}
735
736static int iwm_cfg80211_set_pmksa(struct wiphy *wiphy,
737				  struct net_device *netdev,
738				  struct cfg80211_pmksa *pmksa)
739{
740	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
741
742	return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_ADD);
743}
744
745static int iwm_cfg80211_del_pmksa(struct wiphy *wiphy,
746				  struct net_device *netdev,
747				  struct cfg80211_pmksa *pmksa)
748{
749	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
750
751	return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_DEL);
752}
753
754static int iwm_cfg80211_flush_pmksa(struct wiphy *wiphy,
755				    struct net_device *netdev)
756{
757	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
758	struct cfg80211_pmksa pmksa;
759
760	memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
761
762	return iwm_send_pmkid_update(iwm, &pmksa, IWM_CMD_PMKID_FLUSH);
763}
764
765
766static 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,
785};
786
787static const u32 cipher_suites[] = {
788	WLAN_CIPHER_SUITE_WEP40,
789	WLAN_CIPHER_SUITE_WEP104,
790	WLAN_CIPHER_SUITE_TKIP,
791	WLAN_CIPHER_SUITE_CCMP,
792};
793
794struct wireless_dev *iwm_wdev_alloc(int sizeof_bus, struct device *dev)
795{
796	int ret = 0;
797	struct wireless_dev *wdev;
798
799	/*
800	 * We're trying to have the following memory
801	 * layout:
802	 *
803	 * +-------------------------+
804	 * | struct wiphy	     |
805	 * +-------------------------+
806	 * | struct iwm_priv         |
807	 * +-------------------------+
808	 * | bus private data        |
809	 * | (e.g. iwm_priv_sdio)    |
810	 * +-------------------------+
811	 *
812	 */
813
814	wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
815	if (!wdev) {
816		dev_err(dev, "Couldn't allocate wireless device\n");
817		return ERR_PTR(-ENOMEM);
818	}
819
820	wdev->wiphy = wiphy_new(&iwm_cfg80211_ops,
821				sizeof(struct iwm_priv) + sizeof_bus);
822	if (!wdev->wiphy) {
823		dev_err(dev, "Couldn't allocate wiphy device\n");
824		ret = -ENOMEM;
825		goto out_err_new;
826	}
827
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;
836
837	wdev->wiphy->cipher_suites = cipher_suites;
838	wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
839
840	ret = wiphy_register(wdev->wiphy);
841	if (ret < 0) {
842		dev_err(dev, "Couldn't register wiphy device\n");
843		goto out_err_register;
844	}
845
846	return wdev;
847
848 out_err_register:
849	wiphy_free(wdev->wiphy);
850
851 out_err_new:
852	kfree(wdev);
853
854	return ERR_PTR(ret);
855}
856
857void iwm_wdev_free(struct iwm_priv *iwm)
858{
859	struct wireless_dev *wdev = iwm_to_wdev(iwm);
860
861	if (!wdev)
862		return;
863
864	wiphy_unregister(wdev->wiphy);
865	wiphy_free(wdev->wiphy);
866	kfree(wdev);
867}
v3.5.6
  1/*
  2 * Intel Wireless Multicomm 3200 WiFi driver
  3 *
  4 * Copyright (C) 2009 Intel Corporation <ilw@linux.intel.com>
  5 * Samuel Ortiz <samuel.ortiz@intel.com>
  6 * Zhu Yi <yi.zhu@intel.com>
  7 *
  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.
 11 *
 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.
 16 *
 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
 20 * 02110-1301, USA.
 21 *
 22 */
 23
 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>
 32
 33#include "iwm.h"
 34#include "commands.h"
 35#include "cfg80211.h"
 36#include "debug.h"
 37
 38#define RATETAB_ENT(_rate, _rateid, _flags) \
 39	{								\
 40		.bitrate	= (_rate),				\
 41		.hw_value	= (_rateid),				\
 42		.flags		= (_flags),				\
 43	}
 44
 45#define CHAN2G(_channel, _freq, _flags) {			\
 46	.band			= IEEE80211_BAND_2GHZ,		\
 47	.center_freq		= (_freq),			\
 48	.hw_value		= (_channel),			\
 49	.flags			= (_flags),			\
 50	.max_antenna_gain	= 0,				\
 51	.max_power		= 30,				\
 52}
 53
 54#define CHAN5G(_channel, _flags) {				\
 55	.band			= IEEE80211_BAND_5GHZ,		\
 56	.center_freq		= 5000 + (5 * (_channel)),	\
 57	.hw_value		= (_channel),			\
 58	.flags			= (_flags),			\
 59	.max_antenna_gain	= 0,				\
 60	.max_power		= 30,				\
 61}
 62
 63static 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),
 76};
 77
 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
 82
 83static struct ieee80211_channel iwm_2ghz_channels[] = {
 84	CHAN2G(1, 2412, 0),
 85	CHAN2G(2, 2417, 0),
 86	CHAN2G(3, 2422, 0),
 87	CHAN2G(4, 2427, 0),
 88	CHAN2G(5, 2432, 0),
 89	CHAN2G(6, 2437, 0),
 90	CHAN2G(7, 2442, 0),
 91	CHAN2G(8, 2447, 0),
 92	CHAN2G(9, 2452, 0),
 93	CHAN2G(10, 2457, 0),
 94	CHAN2G(11, 2462, 0),
 95	CHAN2G(12, 2467, 0),
 96	CHAN2G(13, 2472, 0),
 97	CHAN2G(14, 2484, 0),
 98};
 99
100static 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),
119	CHAN5G(216, 0),
120};
121
122static 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,
127};
128
129static 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,
134};
135
136static int iwm_key_init(struct iwm_key *key, u8 key_index,
137			const u8 *mac_addr, struct key_params *params)
138{
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);
143	} else {
144		key->hdr.multicast = 0;
145		memcpy(key->hdr.mac, mac_addr, ETH_ALEN);
146	}
147
148	if (params) {
149		if (params->key_len > WLAN_MAX_KEY_LEN ||
150		    params->seq_len > IW_ENCODE_SEQ_MAX_SIZE)
151			return -EINVAL;
152
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);
158	}
159
160	return 0;
161}
162
163static 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)
166{
167	struct iwm_priv *iwm = ndev_to_iwm(ndev);
168	struct iwm_key *key;
169	int ret;
170
171	IWM_DBG_WEXT(iwm, DBG, "Adding key for %pM\n", mac_addr);
172
173	if (key_index >= IWM_NUM_KEYS)
174		return -ENOENT;
175
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);
179	if (ret < 0) {
180		IWM_ERR(iwm, "Invalid key_params\n");
181		return ret;
182	}
183
184	return iwm_set_key(iwm, 0, key);
185}
186
187static int iwm_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
188				u8 key_index, bool pairwise, const u8 *mac_addr,
189				void *cookie,
190				void (*callback)(void *cookie,
191						 struct key_params*))
192{
193	struct iwm_priv *iwm = ndev_to_iwm(ndev);
194	struct iwm_key *key;
195	struct key_params params;
196
197	IWM_DBG_WEXT(iwm, DBG, "Getting key %d\n", key_index);
198
199	if (key_index >= IWM_NUM_KEYS)
200		return -ENOENT;
201
202	memset(&params, 0, sizeof(params));
203
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;
210
211	callback(cookie, &params);
212
213	return key->key_len ? 0 : -ENOENT;
214}
215
216
217static int iwm_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
218				u8 key_index, bool pairwise, const u8 *mac_addr)
219{
220	struct iwm_priv *iwm = ndev_to_iwm(ndev);
221	struct iwm_key *key;
222
223	if (key_index >= IWM_NUM_KEYS)
224		return -ENOENT;
225
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);
229		return 0;
230	}
231
232	if (key_index == iwm->default_key)
233		iwm->default_key = -1;
234
235	return iwm_set_key(iwm, 1, key);
236}
237
238static int iwm_cfg80211_set_default_key(struct wiphy *wiphy,
239					struct net_device *ndev,
240					u8 key_index, bool unicast,
241					bool multicast)
242{
243	struct iwm_priv *iwm = ndev_to_iwm(ndev);
244
245	IWM_DBG_WEXT(iwm, DBG, "Default key index is: %d\n", key_index);
246
247	if (key_index >= IWM_NUM_KEYS)
248		return -ENOENT;
249
250	if (!iwm->keys[key_index].key_len) {
251		IWM_ERR(iwm, "Key %d not used\n", key_index);
252		return -EINVAL;
253	}
254
255	iwm->default_key = key_index;
256
257	return iwm_set_tx_key(iwm, key_index);
258}
259
260static int iwm_cfg80211_get_station(struct wiphy *wiphy,
261				    struct net_device *ndev,
262				    u8 *mac, struct station_info *sinfo)
263{
264	struct iwm_priv *iwm = ndev_to_iwm(ndev);
265
266	if (memcmp(mac, iwm->bssid, ETH_ALEN))
267		return -ENOENT;
268
269	sinfo->filled |= STATION_INFO_TX_BITRATE;
270	sinfo->txrate.legacy = iwm->rate * 10;
271
272	if (test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)) {
273		sinfo->filled |= STATION_INFO_SIGNAL;
274		sinfo->signal = iwm->wstats.qual.level;
275	}
276
277	return 0;
278}
279
280
281int iwm_cfg80211_inform_bss(struct iwm_priv *iwm)
282{
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;
289	s32 signal;
290	int freq;
291
292	list_for_each_entry(bss, &iwm->bss_list, node) {
293		umac_bss = bss->bss;
294		mgmt = (struct ieee80211_mgmt *)(umac_bss->frame_buf);
295
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];
300		else {
301			IWM_ERR(iwm, "Invalid band: %d\n", umac_bss->band);
302			return -EINVAL;
303		}
304
305		freq = ieee80211_channel_to_frequency(umac_bss->channel,
306						      band->band);
307		channel = ieee80211_get_channel(wiphy, freq);
308		signal = umac_bss->rssi * 100;
309
310		if (!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
311					       le16_to_cpu(umac_bss->frame_len),
312					       signal, GFP_KERNEL))
313			return -EINVAL;
314	}
315
316	return 0;
317}
318
319static 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)
323{
324	struct wireless_dev *wdev;
325	struct iwm_priv *iwm;
326	u32 old_mode;
327
328	wdev = ndev->ieee80211_ptr;
329	iwm = ndev_to_iwm(ndev);
330	old_mode = iwm->conf.mode;
331
332	switch (type) {
333	case NL80211_IFTYPE_STATION:
334		iwm->conf.mode = UMAC_MODE_BSS;
335		break;
336	case NL80211_IFTYPE_ADHOC:
337		iwm->conf.mode = UMAC_MODE_IBSS;
338		break;
339	default:
340		return -EOPNOTSUPP;
341	}
342
343	wdev->iftype = type;
344
345	if ((old_mode == iwm->conf.mode) || !iwm->umac_profile)
346		return 0;
347
348	iwm->umac_profile->mode = cpu_to_le32(iwm->conf.mode);
349
350	if (iwm->umac_profile_active)
351		iwm_invalidate_mlme_profile(iwm);
352
353	return 0;
354}
355
356static int iwm_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
357			     struct cfg80211_scan_request *request)
358{
359	struct iwm_priv *iwm = ndev_to_iwm(ndev);
360	int ret;
361
362	if (!test_bit(IWM_STATUS_READY, &iwm->status)) {
363		IWM_ERR(iwm, "Scan while device is not ready\n");
364		return -EIO;
365	}
366
367	if (test_bit(IWM_STATUS_SCANNING, &iwm->status)) {
368		IWM_ERR(iwm, "Scanning already\n");
369		return -EAGAIN;
370	}
371
372	if (test_bit(IWM_STATUS_SCAN_ABORTING, &iwm->status)) {
373		IWM_ERR(iwm, "Scanning being aborted\n");
374		return -EAGAIN;
375	}
376
377	set_bit(IWM_STATUS_SCANNING, &iwm->status);
378
379	ret = iwm_scan_ssids(iwm, request->ssids, request->n_ssids);
380	if (ret) {
381		clear_bit(IWM_STATUS_SCANNING, &iwm->status);
382		return ret;
383	}
384
385	iwm->scan_request = request;
386	return 0;
387}
388
389static int iwm_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
390{
391	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
392
393	if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
394	    (iwm->conf.rts_threshold != wiphy->rts_threshold)) {
395		int ret;
396
397		iwm->conf.rts_threshold = wiphy->rts_threshold;
398
399		ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
400					     CFG_RTS_THRESHOLD,
401					     iwm->conf.rts_threshold);
402		if (ret < 0)
403			return ret;
404	}
405
406	if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
407	    (iwm->conf.frag_threshold != wiphy->frag_threshold)) {
408		int ret;
409
410		iwm->conf.frag_threshold = wiphy->frag_threshold;
411
412		ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX,
413					     CFG_FRAG_THRESHOLD,
414					     iwm->conf.frag_threshold);
415		if (ret < 0)
416			return ret;
417	}
418
419	return 0;
420}
421
422static int iwm_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
423				  struct cfg80211_ibss_params *params)
424{
425	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
426	struct ieee80211_channel *chan = params->channel;
427
428	if (!test_bit(IWM_STATUS_READY, &iwm->status))
429		return -EIO;
430
431	/* UMAC doesn't support creating or joining an IBSS network
432	 * with specified bssid. */
433	if (params->bssid)
434		return -EOPNOTSUPP;
435
436	iwm->channel = ieee80211_frequency_to_channel(chan->center_freq);
437	iwm->umac_profile->ibss.band = chan->band;
438	iwm->umac_profile->ibss.channel = iwm->channel;
439	iwm->umac_profile->ssid.ssid_len = params->ssid_len;
440	memcpy(iwm->umac_profile->ssid.ssid, params->ssid, params->ssid_len);
441
442	return iwm_send_mlme_profile(iwm);
443}
444
445static int iwm_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
446{
447	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
448
449	if (iwm->umac_profile_active)
450		return iwm_invalidate_mlme_profile(iwm);
451
452	return 0;
453}
454
455static int iwm_set_auth_type(struct iwm_priv *iwm,
456			     enum nl80211_auth_type sme_auth_type)
457{
458	u8 *auth_type = &iwm->umac_profile->sec.auth_type;
459
460	switch (sme_auth_type) {
461	case NL80211_AUTHTYPE_AUTOMATIC:
462	case NL80211_AUTHTYPE_OPEN_SYSTEM:
463		IWM_DBG_WEXT(iwm, DBG, "OPEN auth\n");
464		*auth_type = UMAC_AUTH_TYPE_OPEN;
465		break;
466	case NL80211_AUTHTYPE_SHARED_KEY:
467		if (iwm->umac_profile->sec.flags &
468		    (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK)) {
469			IWM_DBG_WEXT(iwm, DBG, "WPA auth alg\n");
470			*auth_type = UMAC_AUTH_TYPE_RSNA_PSK;
471		} else {
472			IWM_DBG_WEXT(iwm, DBG, "WEP shared key auth alg\n");
473			*auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
474		}
475
476		break;
477	default:
478		IWM_ERR(iwm, "Unsupported auth alg: 0x%x\n", sme_auth_type);
479		return -ENOTSUPP;
480	}
481
482	return 0;
483}
484
485static int iwm_set_wpa_version(struct iwm_priv *iwm, u32 wpa_version)
486{
487	IWM_DBG_WEXT(iwm, DBG, "wpa_version: %d\n", wpa_version);
488
489	if (!wpa_version) {
490		iwm->umac_profile->sec.flags = UMAC_SEC_FLG_LEGACY_PROFILE;
491		return 0;
492	}
493
494	if (wpa_version & NL80211_WPA_VERSION_1)
495		iwm->umac_profile->sec.flags = UMAC_SEC_FLG_WPA_ON_MSK;
496
497	if (wpa_version & NL80211_WPA_VERSION_2)
498		iwm->umac_profile->sec.flags = UMAC_SEC_FLG_RSNA_ON_MSK;
499
500	return 0;
501}
502
503static int iwm_set_cipher(struct iwm_priv *iwm, u32 cipher, bool ucast)
504{
505	u8 *profile_cipher = ucast ? &iwm->umac_profile->sec.ucast_cipher :
506		&iwm->umac_profile->sec.mcast_cipher;
507
508	if (!cipher) {
509		*profile_cipher = UMAC_CIPHER_TYPE_NONE;
510		return 0;
511	}
512
513	IWM_DBG_WEXT(iwm, DBG, "%ccast cipher is 0x%x\n", ucast ? 'u' : 'm',
514		     cipher);
515
516	switch (cipher) {
517	case IW_AUTH_CIPHER_NONE:
518		*profile_cipher = UMAC_CIPHER_TYPE_NONE;
519		break;
520	case WLAN_CIPHER_SUITE_WEP40:
521		*profile_cipher = UMAC_CIPHER_TYPE_WEP_40;
522		break;
523	case WLAN_CIPHER_SUITE_WEP104:
524		*profile_cipher = UMAC_CIPHER_TYPE_WEP_104;
525		break;
526	case WLAN_CIPHER_SUITE_TKIP:
527		*profile_cipher = UMAC_CIPHER_TYPE_TKIP;
528		break;
529	case WLAN_CIPHER_SUITE_CCMP:
530		*profile_cipher = UMAC_CIPHER_TYPE_CCMP;
531		break;
532	default:
533		IWM_ERR(iwm, "Unsupported cipher: 0x%x\n", cipher);
534		return -ENOTSUPP;
535	}
536
537	return 0;
538}
539
540static int iwm_set_key_mgt(struct iwm_priv *iwm, u32 key_mgt)
541{
542	u8 *auth_type = &iwm->umac_profile->sec.auth_type;
543
544	IWM_DBG_WEXT(iwm, DBG, "key_mgt: 0x%x\n", key_mgt);
545
546	if (key_mgt == WLAN_AKM_SUITE_8021X)
547		*auth_type = UMAC_AUTH_TYPE_8021X;
548	else if (key_mgt == WLAN_AKM_SUITE_PSK) {
549		if (iwm->umac_profile->sec.flags &
550		    (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK))
551			*auth_type = UMAC_AUTH_TYPE_RSNA_PSK;
552		else
553			*auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
554	} else {
555		IWM_ERR(iwm, "Invalid key mgt: 0x%x\n", key_mgt);
556		return -EINVAL;
557	}
558
559	return 0;
560}
561
562
563static int iwm_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
564				 struct cfg80211_connect_params *sme)
565{
566	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
567	struct ieee80211_channel *chan = sme->channel;
568	struct key_params key_param;
569	int ret;
570
571	if (!test_bit(IWM_STATUS_READY, &iwm->status))
572		return -EIO;
573
574	if (!sme->ssid)
575		return -EINVAL;
576
577	if (iwm->umac_profile_active) {
578		ret = iwm_invalidate_mlme_profile(iwm);
579		if (ret) {
580			IWM_ERR(iwm, "Couldn't invalidate profile\n");
581			return ret;
582		}
583	}
584
585	if (chan)
586		iwm->channel =
587			ieee80211_frequency_to_channel(chan->center_freq);
588
589	iwm->umac_profile->ssid.ssid_len = sme->ssid_len;
590	memcpy(iwm->umac_profile->ssid.ssid, sme->ssid, sme->ssid_len);
591
592	if (sme->bssid) {
593		IWM_DBG_WEXT(iwm, DBG, "BSSID: %pM\n", sme->bssid);
594		memcpy(&iwm->umac_profile->bssid[0], sme->bssid, ETH_ALEN);
595		iwm->umac_profile->bss_num = 1;
596	} else {
597		memset(&iwm->umac_profile->bssid[0], 0, ETH_ALEN);
598		iwm->umac_profile->bss_num = 0;
599	}
600
601	ret = iwm_set_wpa_version(iwm, sme->crypto.wpa_versions);
602	if (ret < 0)
603		return ret;
604
605	ret = iwm_set_auth_type(iwm, sme->auth_type);
606	if (ret < 0)
607		return ret;
608
609	if (sme->crypto.n_ciphers_pairwise) {
610		ret = iwm_set_cipher(iwm, sme->crypto.ciphers_pairwise[0],
611				     true);
612		if (ret < 0)
613			return ret;
614	}
615
616	ret = iwm_set_cipher(iwm, sme->crypto.cipher_group, false);
617	if (ret < 0)
618		return ret;
619
620	if (sme->crypto.n_akm_suites) {
621		ret = iwm_set_key_mgt(iwm, sme->crypto.akm_suites[0]);
622		if (ret < 0)
623			return ret;
624	}
625
626	/*
627	 * We save the WEP key in case we want to do shared authentication.
628	 * We have to do it so because UMAC will assert whenever it gets a
629	 * key before a profile.
630	 */
631	if (sme->key) {
632		key_param.key = kmemdup(sme->key, sme->key_len, GFP_KERNEL);
633		if (key_param.key == NULL)
634			return -ENOMEM;
635		key_param.key_len = sme->key_len;
636		key_param.seq_len = 0;
637		key_param.cipher = sme->crypto.ciphers_pairwise[0];
638
639		ret = iwm_key_init(&iwm->keys[sme->key_idx], sme->key_idx,
640				   NULL, &key_param);
641		kfree(key_param.key);
642		if (ret < 0) {
643			IWM_ERR(iwm, "Invalid key_params\n");
644			return ret;
645		}
646
647		iwm->default_key = sme->key_idx;
648	}
649
650	/* WPA and open AUTH type from wpa_s means WPS (a.k.a. WSC) */
651	if ((iwm->umac_profile->sec.flags &
652	     (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK)) &&
653	    iwm->umac_profile->sec.auth_type == UMAC_AUTH_TYPE_OPEN) {
654			iwm->umac_profile->sec.flags = UMAC_SEC_FLG_WSC_ON_MSK;
655	}
656
657	ret = iwm_send_mlme_profile(iwm);
658
659	if (iwm->umac_profile->sec.auth_type != UMAC_AUTH_TYPE_LEGACY_PSK ||
660	    sme->key == NULL)
661		return ret;
662
663	/*
664	 * We want to do shared auth.
665	 * We need to actually set the key we previously cached,
666	 * and then tell the UMAC it's the default one.
667	 * That will trigger the auth+assoc UMAC machinery, and again,
668	 * this must be done after setting the profile.
669	 */
670	ret = iwm_set_key(iwm, 0, &iwm->keys[sme->key_idx]);
671	if (ret < 0)
672		return ret;
673
674	return iwm_set_tx_key(iwm, iwm->default_key);
675}
676
677static int iwm_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
678				   u16 reason_code)
679{
680	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
681
682	IWM_DBG_WEXT(iwm, DBG, "Active: %d\n", iwm->umac_profile_active);
683
684	if (iwm->umac_profile_active)
685		iwm_invalidate_mlme_profile(iwm);
686
687	return 0;
688}
689
690static int iwm_cfg80211_set_txpower(struct wiphy *wiphy,
691				    enum nl80211_tx_power_setting type, int mbm)
692{
693	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
694	int ret;
695
696	switch (type) {
697	case NL80211_TX_POWER_AUTOMATIC:
698		return 0;
699	case NL80211_TX_POWER_FIXED:
700		if (mbm < 0 || (mbm % 100))
701			return -EOPNOTSUPP;
702
703		if (!test_bit(IWM_STATUS_READY, &iwm->status))
704			return 0;
705
706		ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
707					      CFG_TX_PWR_LIMIT_USR,
708					      MBM_TO_DBM(mbm) * 2);
709		if (ret < 0)
710			return ret;
711
712		return iwm_tx_power_trigger(iwm);
713	default:
714		IWM_ERR(iwm, "Unsupported power type: %d\n", type);
715		return -EOPNOTSUPP;
716	}
717
718	return 0;
719}
720
721static int iwm_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
722{
723	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
724
725	*dbm = iwm->txpower >> 1;
726
727	return 0;
728}
729
730static int iwm_cfg80211_set_power_mgmt(struct wiphy *wiphy,
731				       struct net_device *dev,
732				       bool enabled, int timeout)
733{
734	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
735	u32 power_index;
736
737	if (enabled)
738		power_index = IWM_POWER_INDEX_DEFAULT;
739	else
740		power_index = IWM_POWER_INDEX_MIN;
741
742	if (power_index == iwm->conf.power_index)
743		return 0;
744
745	iwm->conf.power_index = power_index;
746
747	return iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
748				       CFG_POWER_INDEX, iwm->conf.power_index);
749}
750
751static int iwm_cfg80211_set_pmksa(struct wiphy *wiphy,
752				  struct net_device *netdev,
753				  struct cfg80211_pmksa *pmksa)
754{
755	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
756
757	return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_ADD);
758}
759
760static int iwm_cfg80211_del_pmksa(struct wiphy *wiphy,
761				  struct net_device *netdev,
762				  struct cfg80211_pmksa *pmksa)
763{
764	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
765
766	return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_DEL);
767}
768
769static int iwm_cfg80211_flush_pmksa(struct wiphy *wiphy,
770				    struct net_device *netdev)
771{
772	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
773	struct cfg80211_pmksa pmksa;
774
775	memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
776
777	return iwm_send_pmkid_update(iwm, &pmksa, IWM_CMD_PMKID_FLUSH);
778}
779
780
781static struct cfg80211_ops iwm_cfg80211_ops = {
782	.change_virtual_intf = iwm_cfg80211_change_iface,
783	.add_key = iwm_cfg80211_add_key,
784	.get_key = iwm_cfg80211_get_key,
785	.del_key = iwm_cfg80211_del_key,
786	.set_default_key = iwm_cfg80211_set_default_key,
787	.get_station = iwm_cfg80211_get_station,
788	.scan = iwm_cfg80211_scan,
789	.set_wiphy_params = iwm_cfg80211_set_wiphy_params,
790	.connect = iwm_cfg80211_connect,
791	.disconnect = iwm_cfg80211_disconnect,
792	.join_ibss = iwm_cfg80211_join_ibss,
793	.leave_ibss = iwm_cfg80211_leave_ibss,
794	.set_tx_power = iwm_cfg80211_set_txpower,
795	.get_tx_power = iwm_cfg80211_get_txpower,
796	.set_power_mgmt = iwm_cfg80211_set_power_mgmt,
797	.set_pmksa = iwm_cfg80211_set_pmksa,
798	.del_pmksa = iwm_cfg80211_del_pmksa,
799	.flush_pmksa = iwm_cfg80211_flush_pmksa,
800};
801
802static const u32 cipher_suites[] = {
803	WLAN_CIPHER_SUITE_WEP40,
804	WLAN_CIPHER_SUITE_WEP104,
805	WLAN_CIPHER_SUITE_TKIP,
806	WLAN_CIPHER_SUITE_CCMP,
807};
808
809struct wireless_dev *iwm_wdev_alloc(int sizeof_bus, struct device *dev)
810{
811	int ret = 0;
812	struct wireless_dev *wdev;
813
814	/*
815	 * We're trying to have the following memory
816	 * layout:
817	 *
818	 * +-------------------------+
819	 * | struct wiphy	     |
820	 * +-------------------------+
821	 * | struct iwm_priv         |
822	 * +-------------------------+
823	 * | bus private data        |
824	 * | (e.g. iwm_priv_sdio)    |
825	 * +-------------------------+
826	 *
827	 */
828
829	wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
830	if (!wdev) {
831		dev_err(dev, "Couldn't allocate wireless device\n");
832		return ERR_PTR(-ENOMEM);
833	}
834
835	wdev->wiphy = wiphy_new(&iwm_cfg80211_ops,
836				sizeof(struct iwm_priv) + sizeof_bus);
837	if (!wdev->wiphy) {
838		dev_err(dev, "Couldn't allocate wiphy device\n");
839		ret = -ENOMEM;
840		goto out_err_new;
841	}
842
843	set_wiphy_dev(wdev->wiphy, dev);
844	wdev->wiphy->max_scan_ssids = UMAC_WIFI_IF_PROBE_OPTION_MAX;
845	wdev->wiphy->max_num_pmkids = UMAC_MAX_NUM_PMKIDS;
846	wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
847				       BIT(NL80211_IFTYPE_ADHOC);
848	wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &iwm_band_2ghz;
849	wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &iwm_band_5ghz;
850	wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
851
852	wdev->wiphy->cipher_suites = cipher_suites;
853	wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
854
855	ret = wiphy_register(wdev->wiphy);
856	if (ret < 0) {
857		dev_err(dev, "Couldn't register wiphy device\n");
858		goto out_err_register;
859	}
860
861	return wdev;
862
863 out_err_register:
864	wiphy_free(wdev->wiphy);
865
866 out_err_new:
867	kfree(wdev);
868
869	return ERR_PTR(ret);
870}
871
872void iwm_wdev_free(struct iwm_priv *iwm)
873{
874	struct wireless_dev *wdev = iwm_to_wdev(iwm);
875
876	if (!wdev)
877		return;
878
879	wiphy_unregister(wdev->wiphy);
880	wiphy_free(wdev->wiphy);
881	kfree(wdev);
882}