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/etherdevice.h>
27 #include <linux/wireless.h>
28 #include <linux/ieee80211.h>
29 #include <net/cfg80211.h>
36 #define RATETAB_ENT(_rate, _rateid, _flags) \
39 .hw_value = (_rateid), \
43 #define CHAN2G(_channel, _freq, _flags) { \
44 .band = IEEE80211_BAND_2GHZ, \
45 .center_freq = (_freq), \
46 .hw_value = (_channel), \
48 .max_antenna_gain = 0, \
52 #define CHAN5G(_channel, _flags) { \
53 .band = IEEE80211_BAND_5GHZ, \
54 .center_freq = 5000 + (5 * (_channel)), \
55 .hw_value = (_channel), \
57 .max_antenna_gain = 0, \
61 static struct ieee80211_rate iwm_rates[] = {
62 RATETAB_ENT(10, 0x1, 0),
63 RATETAB_ENT(20, 0x2, 0),
64 RATETAB_ENT(55, 0x4, 0),
65 RATETAB_ENT(110, 0x8, 0),
66 RATETAB_ENT(60, 0x10, 0),
67 RATETAB_ENT(90, 0x20, 0),
68 RATETAB_ENT(120, 0x40, 0),
69 RATETAB_ENT(180, 0x80, 0),
70 RATETAB_ENT(240, 0x100, 0),
71 RATETAB_ENT(360, 0x200, 0),
72 RATETAB_ENT(480, 0x400, 0),
73 RATETAB_ENT(540, 0x800, 0),
76 #define iwm_a_rates (iwm_rates + 4)
77 #define iwm_a_rates_size 8
78 #define iwm_g_rates (iwm_rates + 0)
79 #define iwm_g_rates_size 12
81 static struct ieee80211_channel iwm_2ghz_channels[] = {
98 static struct ieee80211_channel iwm_5ghz_a_channels[] = {
99 CHAN5G(34, 0), CHAN5G(36, 0),
100 CHAN5G(38, 0), CHAN5G(40, 0),
101 CHAN5G(42, 0), CHAN5G(44, 0),
102 CHAN5G(46, 0), CHAN5G(48, 0),
103 CHAN5G(52, 0), CHAN5G(56, 0),
104 CHAN5G(60, 0), CHAN5G(64, 0),
105 CHAN5G(100, 0), CHAN5G(104, 0),
106 CHAN5G(108, 0), CHAN5G(112, 0),
107 CHAN5G(116, 0), CHAN5G(120, 0),
108 CHAN5G(124, 0), CHAN5G(128, 0),
109 CHAN5G(132, 0), CHAN5G(136, 0),
110 CHAN5G(140, 0), CHAN5G(149, 0),
111 CHAN5G(153, 0), CHAN5G(157, 0),
112 CHAN5G(161, 0), CHAN5G(165, 0),
113 CHAN5G(184, 0), CHAN5G(188, 0),
114 CHAN5G(192, 0), CHAN5G(196, 0),
115 CHAN5G(200, 0), CHAN5G(204, 0),
116 CHAN5G(208, 0), CHAN5G(212, 0),
120 static struct ieee80211_supported_band iwm_band_2ghz = {
121 .channels = iwm_2ghz_channels,
122 .n_channels = ARRAY_SIZE(iwm_2ghz_channels),
123 .bitrates = iwm_g_rates,
124 .n_bitrates = iwm_g_rates_size,
127 static struct ieee80211_supported_band iwm_band_5ghz = {
128 .channels = iwm_5ghz_a_channels,
129 .n_channels = ARRAY_SIZE(iwm_5ghz_a_channels),
130 .bitrates = iwm_a_rates,
131 .n_bitrates = iwm_a_rates_size,
134 static int iwm_key_init(struct iwm_key *key, u8 key_index,
135 const u8 *mac_addr, struct key_params *params)
137 key->hdr.key_idx = key_index;
138 if (!mac_addr || is_broadcast_ether_addr(mac_addr)) {
139 key->hdr.multicast = 1;
140 memset(key->hdr.mac, 0xff, ETH_ALEN);
142 key->hdr.multicast = 0;
143 memcpy(key->hdr.mac, mac_addr, ETH_ALEN);
147 if (params->key_len > WLAN_MAX_KEY_LEN ||
148 params->seq_len > IW_ENCODE_SEQ_MAX_SIZE)
151 key->cipher = params->cipher;
152 key->key_len = params->key_len;
153 key->seq_len = params->seq_len;
154 memcpy(key->key, params->key, key->key_len);
155 memcpy(key->seq, params->seq, key->seq_len);
161 static int iwm_reset_profile(struct iwm_priv *iwm)
165 if (!iwm->umac_profile_active)
169 * If there is a current active profile, but no
170 * default key, it's not worth trying to associate again.
172 if (iwm->default_key < 0)
176 * Here we have an active profile, but a key setting changed.
177 * We thus have to invalidate the current profile, and push the
178 * new one. Keys will be pushed when association takes place.
180 ret = iwm_invalidate_mlme_profile(iwm);
182 IWM_ERR(iwm, "Couldn't invalidate profile\n");
186 return iwm_send_mlme_profile(iwm);
189 static int iwm_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
190 u8 key_index, const u8 *mac_addr,
191 struct key_params *params)
193 struct iwm_priv *iwm = ndev_to_iwm(ndev);
194 struct iwm_key *key = &iwm->keys[key_index];
197 IWM_DBG_WEXT(iwm, DBG, "Adding key for %pM\n", mac_addr);
199 memset(key, 0, sizeof(struct iwm_key));
200 ret = iwm_key_init(key, key_index, mac_addr, params);
202 IWM_ERR(iwm, "Invalid key_params\n");
207 * The WEP keys can be set before or after setting the essid.
208 * We need to handle both cases by simply pushing the keys after
209 * we send the profile.
210 * If the profile is not set yet (i.e. we're pushing keys before
211 * the essid), we set the cipher appropriately.
212 * If the profile is set, we havent associated yet because our
213 * cipher was incorrectly set. So we invalidate and send the
216 if (key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
217 key->cipher == WLAN_CIPHER_SUITE_WEP104) {
218 u8 *ucast_cipher = &iwm->umac_profile->sec.ucast_cipher;
219 u8 *mcast_cipher = &iwm->umac_profile->sec.mcast_cipher;
221 IWM_DBG_WEXT(iwm, DBG, "WEP key\n");
223 if (key->cipher == WLAN_CIPHER_SUITE_WEP40)
224 *ucast_cipher = *mcast_cipher = UMAC_CIPHER_TYPE_WEP_40;
225 if (key->cipher == WLAN_CIPHER_SUITE_WEP104)
226 *ucast_cipher = *mcast_cipher =
227 UMAC_CIPHER_TYPE_WEP_104;
229 return iwm_reset_profile(iwm);
232 return iwm_set_key(iwm, 0, key);
235 static int iwm_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
236 u8 key_index, const u8 *mac_addr, void *cookie,
237 void (*callback)(void *cookie,
240 struct iwm_priv *iwm = ndev_to_iwm(ndev);
241 struct iwm_key *key = &iwm->keys[key_index];
242 struct key_params params;
244 IWM_DBG_WEXT(iwm, DBG, "Getting key %d\n", key_index);
246 memset(¶ms, 0, sizeof(params));
248 params.cipher = key->cipher;
249 params.key_len = key->key_len;
250 params.seq_len = key->seq_len;
251 params.seq = key->seq;
252 params.key = key->key;
254 callback(cookie, ¶ms);
256 return key->key_len ? 0 : -ENOENT;
260 static int iwm_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
261 u8 key_index, const u8 *mac_addr)
263 struct iwm_priv *iwm = ndev_to_iwm(ndev);
264 struct iwm_key *key = &iwm->keys[key_index];
266 if (!iwm->keys[key_index].key_len) {
267 IWM_DBG_WEXT(iwm, DBG, "Key %d not used\n", key_index);
271 if (key_index == iwm->default_key)
272 iwm->default_key = -1;
274 return iwm_set_key(iwm, 1, key);
277 static int iwm_cfg80211_set_default_key(struct wiphy *wiphy,
278 struct net_device *ndev,
281 struct iwm_priv *iwm = ndev_to_iwm(ndev);
284 IWM_DBG_WEXT(iwm, DBG, "Default key index is: %d\n", key_index);
286 if (!iwm->keys[key_index].key_len) {
287 IWM_ERR(iwm, "Key %d not used\n", key_index);
291 ret = iwm_set_tx_key(iwm, key_index);
295 iwm->default_key = key_index;
297 return iwm_reset_profile(iwm);
301 int iwm_cfg80211_inform_bss(struct iwm_priv *iwm)
303 struct wiphy *wiphy = iwm_to_wiphy(iwm);
304 struct iwm_bss_info *bss, *next;
305 struct iwm_umac_notif_bss_info *umac_bss;
306 struct ieee80211_mgmt *mgmt;
307 struct ieee80211_channel *channel;
308 struct ieee80211_supported_band *band;
312 list_for_each_entry_safe(bss, next, &iwm->bss_list, node) {
314 mgmt = (struct ieee80211_mgmt *)(umac_bss->frame_buf);
316 if (umac_bss->band == UMAC_BAND_2GHZ)
317 band = wiphy->bands[IEEE80211_BAND_2GHZ];
318 else if (umac_bss->band == UMAC_BAND_5GHZ)
319 band = wiphy->bands[IEEE80211_BAND_5GHZ];
321 IWM_ERR(iwm, "Invalid band: %d\n", umac_bss->band);
325 freq = ieee80211_channel_to_frequency(umac_bss->channel);
326 channel = ieee80211_get_channel(wiphy, freq);
327 signal = umac_bss->rssi * 100;
329 if (!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
330 le16_to_cpu(umac_bss->frame_len),
338 static int iwm_cfg80211_change_iface(struct wiphy *wiphy,
339 struct net_device *ndev,
340 enum nl80211_iftype type, u32 *flags,
341 struct vif_params *params)
343 struct wireless_dev *wdev;
344 struct iwm_priv *iwm;
347 wdev = ndev->ieee80211_ptr;
348 iwm = ndev_to_iwm(ndev);
349 old_mode = iwm->conf.mode;
352 case NL80211_IFTYPE_STATION:
353 iwm->conf.mode = UMAC_MODE_BSS;
355 case NL80211_IFTYPE_ADHOC:
356 iwm->conf.mode = UMAC_MODE_IBSS;
364 if ((old_mode == iwm->conf.mode) || !iwm->umac_profile)
367 iwm->umac_profile->mode = cpu_to_le32(iwm->conf.mode);
369 if (iwm->umac_profile_active) {
370 int ret = iwm_invalidate_mlme_profile(iwm);
372 IWM_ERR(iwm, "Couldn't invalidate profile\n");
378 static int iwm_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
379 struct cfg80211_scan_request *request)
381 struct iwm_priv *iwm = ndev_to_iwm(ndev);
384 if (!test_bit(IWM_STATUS_READY, &iwm->status)) {
385 IWM_ERR(iwm, "Scan while device is not ready\n");
389 if (test_bit(IWM_STATUS_SCANNING, &iwm->status)) {
390 IWM_ERR(iwm, "Scanning already\n");
394 if (test_bit(IWM_STATUS_SCAN_ABORTING, &iwm->status)) {
395 IWM_ERR(iwm, "Scanning being aborted\n");
399 set_bit(IWM_STATUS_SCANNING, &iwm->status);
401 ret = iwm_scan_ssids(iwm, request->ssids, request->n_ssids);
403 clear_bit(IWM_STATUS_SCANNING, &iwm->status);
407 iwm->scan_request = request;
411 static int iwm_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
413 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
415 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
416 (iwm->conf.rts_threshold != wiphy->rts_threshold)) {
419 iwm->conf.rts_threshold = wiphy->rts_threshold;
421 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
423 iwm->conf.rts_threshold);
428 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
429 (iwm->conf.frag_threshold != wiphy->frag_threshold)) {
432 iwm->conf.frag_threshold = wiphy->frag_threshold;
434 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX,
436 iwm->conf.frag_threshold);
444 static int iwm_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
445 struct cfg80211_ibss_params *params)
447 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
448 struct ieee80211_channel *chan = params->channel;
449 struct cfg80211_bss *bss;
451 if (!test_bit(IWM_STATUS_READY, &iwm->status))
454 /* UMAC doesn't support creating IBSS network with specified bssid.
455 * This should be removed after we have join only mode supported. */
459 bss = cfg80211_get_ibss(iwm_to_wiphy(iwm), NULL,
460 params->ssid, params->ssid_len);
462 iwm_scan_one_ssid(iwm, params->ssid, params->ssid_len);
463 schedule_timeout_interruptible(2 * HZ);
464 bss = cfg80211_get_ibss(iwm_to_wiphy(iwm), NULL,
465 params->ssid, params->ssid_len);
467 /* IBSS join only mode is not supported by UMAC ATM */
469 cfg80211_put_bss(bss);
473 iwm->channel = ieee80211_frequency_to_channel(chan->center_freq);
474 iwm->umac_profile->ibss.band = chan->band;
475 iwm->umac_profile->ibss.channel = iwm->channel;
476 iwm->umac_profile->ssid.ssid_len = params->ssid_len;
477 memcpy(iwm->umac_profile->ssid.ssid, params->ssid, params->ssid_len);
480 memcpy(&iwm->umac_profile->bssid[0], params->bssid, ETH_ALEN);
482 return iwm_send_mlme_profile(iwm);
485 static int iwm_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
487 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
489 if (iwm->umac_profile_active)
490 return iwm_invalidate_mlme_profile(iwm);
495 static struct cfg80211_ops iwm_cfg80211_ops = {
496 .change_virtual_intf = iwm_cfg80211_change_iface,
497 .add_key = iwm_cfg80211_add_key,
498 .get_key = iwm_cfg80211_get_key,
499 .del_key = iwm_cfg80211_del_key,
500 .set_default_key = iwm_cfg80211_set_default_key,
501 .scan = iwm_cfg80211_scan,
502 .set_wiphy_params = iwm_cfg80211_set_wiphy_params,
503 .join_ibss = iwm_cfg80211_join_ibss,
504 .leave_ibss = iwm_cfg80211_leave_ibss,
507 struct wireless_dev *iwm_wdev_alloc(int sizeof_bus, struct device *dev)
510 struct wireless_dev *wdev;
513 * We're trying to have the following memory
516 * +-------------------------+
518 * +-------------------------+
519 * | struct iwm_priv |
520 * +-------------------------+
521 * | bus private data |
522 * | (e.g. iwm_priv_sdio) |
523 * +-------------------------+
527 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
529 dev_err(dev, "Couldn't allocate wireless device\n");
530 return ERR_PTR(-ENOMEM);
533 wdev->wiphy = wiphy_new(&iwm_cfg80211_ops,
534 sizeof(struct iwm_priv) + sizeof_bus);
536 dev_err(dev, "Couldn't allocate wiphy device\n");
541 set_wiphy_dev(wdev->wiphy, dev);
542 wdev->wiphy->max_scan_ssids = UMAC_WIFI_IF_PROBE_OPTION_MAX;
543 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
544 BIT(NL80211_IFTYPE_ADHOC);
545 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &iwm_band_2ghz;
546 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &iwm_band_5ghz;
547 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
549 ret = wiphy_register(wdev->wiphy);
551 dev_err(dev, "Couldn't register wiphy device\n");
552 goto out_err_register;
558 wiphy_free(wdev->wiphy);
566 void iwm_wdev_free(struct iwm_priv *iwm)
568 struct wireless_dev *wdev = iwm_to_wdev(iwm);
573 wiphy_unregister(wdev->wiphy);
574 wiphy_free(wdev->wiphy);