iwmc3200wifi: cache keys when interface is down
[safe/jmp/linux-2.6] / drivers / net / wireless / iwmc3200wifi / cfg80211.c
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/etherdevice.h>
27 #include <linux/wireless.h>
28 #include <linux/ieee80211.h>
29 #include <net/cfg80211.h>
30
31 #include "iwm.h"
32 #include "commands.h"
33 #include "cfg80211.h"
34 #include "debug.h"
35
36 #define RATETAB_ENT(_rate, _rateid, _flags) \
37         {                                                               \
38                 .bitrate        = (_rate),                              \
39                 .hw_value       = (_rateid),                            \
40                 .flags          = (_flags),                             \
41         }
42
43 #define CHAN2G(_channel, _freq, _flags) {                       \
44         .band                   = IEEE80211_BAND_2GHZ,          \
45         .center_freq            = (_freq),                      \
46         .hw_value               = (_channel),                   \
47         .flags                  = (_flags),                     \
48         .max_antenna_gain       = 0,                            \
49         .max_power              = 30,                           \
50 }
51
52 #define CHAN5G(_channel, _flags) {                              \
53         .band                   = IEEE80211_BAND_5GHZ,          \
54         .center_freq            = 5000 + (5 * (_channel)),      \
55         .hw_value               = (_channel),                   \
56         .flags                  = (_flags),                     \
57         .max_antenna_gain       = 0,                            \
58         .max_power              = 30,                           \
59 }
60
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),
74 };
75
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
80
81 static struct ieee80211_channel iwm_2ghz_channels[] = {
82         CHAN2G(1, 2412, 0),
83         CHAN2G(2, 2417, 0),
84         CHAN2G(3, 2422, 0),
85         CHAN2G(4, 2427, 0),
86         CHAN2G(5, 2432, 0),
87         CHAN2G(6, 2437, 0),
88         CHAN2G(7, 2442, 0),
89         CHAN2G(8, 2447, 0),
90         CHAN2G(9, 2452, 0),
91         CHAN2G(10, 2457, 0),
92         CHAN2G(11, 2462, 0),
93         CHAN2G(12, 2467, 0),
94         CHAN2G(13, 2472, 0),
95         CHAN2G(14, 2484, 0),
96 };
97
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),
117         CHAN5G(216, 0),
118 };
119
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,
125 };
126
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,
132 };
133
134 static int iwm_key_init(struct iwm_key *key, u8 key_index,
135                         const u8 *mac_addr, struct key_params *params)
136 {
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);
141         } else {
142                 key->hdr.multicast = 0;
143                 memcpy(key->hdr.mac, mac_addr, ETH_ALEN);
144         }
145
146         if (params) {
147                 if (params->key_len > WLAN_MAX_KEY_LEN ||
148                     params->seq_len > IW_ENCODE_SEQ_MAX_SIZE)
149                         return -EINVAL;
150
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);
156         }
157
158         return 0;
159 }
160
161 static int iwm_reset_profile(struct iwm_priv *iwm)
162 {
163         int ret;
164
165         if (!iwm->umac_profile_active)
166                 return 0;
167
168         /*
169          * If there is a current active profile, but no
170          * default key, it's not worth trying to associate again.
171          */
172         if (iwm->default_key < 0)
173                 return 0;
174
175         /*
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.
179          */
180         ret = iwm_invalidate_mlme_profile(iwm);
181         if (ret < 0) {
182                 IWM_ERR(iwm, "Couldn't invalidate profile\n");
183                 return ret;
184         }
185
186         return iwm_send_mlme_profile(iwm);
187 }
188
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)
192 {
193         struct iwm_priv *iwm = ndev_to_iwm(ndev);
194         struct iwm_key *key = &iwm->keys[key_index];
195         int ret;
196
197         IWM_DBG_WEXT(iwm, DBG, "Adding key for %pM\n", mac_addr);
198
199         memset(key, 0, sizeof(struct iwm_key));
200         ret = iwm_key_init(key, key_index, mac_addr, params);
201         if (ret < 0) {
202                 IWM_ERR(iwm, "Invalid key_params\n");
203                 return ret;
204         }
205
206         /*
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
214          * profile again.
215          */
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;
220
221                 IWM_DBG_WEXT(iwm, DBG, "WEP key\n");
222
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;
228
229                 return iwm_reset_profile(iwm);
230         }
231
232         return iwm_set_key(iwm, 0, key);
233 }
234
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,
238                                                  struct key_params*))
239 {
240         struct iwm_priv *iwm = ndev_to_iwm(ndev);
241         struct iwm_key *key = &iwm->keys[key_index];
242         struct key_params params;
243
244         IWM_DBG_WEXT(iwm, DBG, "Getting key %d\n", key_index);
245
246         memset(&params, 0, sizeof(params));
247
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;
253
254         callback(cookie, &params);
255
256         return key->key_len ? 0 : -ENOENT;
257 }
258
259
260 static int iwm_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
261                                 u8 key_index, const u8 *mac_addr)
262 {
263         struct iwm_priv *iwm = ndev_to_iwm(ndev);
264         struct iwm_key *key = &iwm->keys[key_index];
265
266         if (!iwm->keys[key_index].key_len) {
267                 IWM_DBG_WEXT(iwm, DBG, "Key %d not used\n", key_index);
268                 return 0;
269         }
270
271         if (key_index == iwm->default_key)
272                 iwm->default_key = -1;
273
274         /* If the interface is down, we just cache this */
275         if (!test_bit(IWM_STATUS_READY, &iwm->status))
276                 return 0;
277
278         return iwm_set_key(iwm, 1, key);
279 }
280
281 static int iwm_cfg80211_set_default_key(struct wiphy *wiphy,
282                                         struct net_device *ndev,
283                                         u8 key_index)
284 {
285         struct iwm_priv *iwm = ndev_to_iwm(ndev);
286         int ret;
287
288         IWM_DBG_WEXT(iwm, DBG, "Default key index is: %d\n", key_index);
289
290         if (!iwm->keys[key_index].key_len) {
291                 IWM_ERR(iwm, "Key %d not used\n", key_index);
292                 return -EINVAL;
293         }
294
295         iwm->default_key = key_index;
296
297         /* If the interface is down, we just cache this */
298         if (!test_bit(IWM_STATUS_READY, &iwm->status))
299                 return 0;
300
301         ret = iwm_set_tx_key(iwm, key_index);
302         if (ret < 0)
303                 return ret;
304
305         return iwm_reset_profile(iwm);
306 }
307
308
309 int iwm_cfg80211_inform_bss(struct iwm_priv *iwm)
310 {
311         struct wiphy *wiphy = iwm_to_wiphy(iwm);
312         struct iwm_bss_info *bss, *next;
313         struct iwm_umac_notif_bss_info *umac_bss;
314         struct ieee80211_mgmt *mgmt;
315         struct ieee80211_channel *channel;
316         struct ieee80211_supported_band *band;
317         s32 signal;
318         int freq;
319
320         list_for_each_entry_safe(bss, next, &iwm->bss_list, node) {
321                 umac_bss = bss->bss;
322                 mgmt = (struct ieee80211_mgmt *)(umac_bss->frame_buf);
323
324                 if (umac_bss->band == UMAC_BAND_2GHZ)
325                         band = wiphy->bands[IEEE80211_BAND_2GHZ];
326                 else if (umac_bss->band == UMAC_BAND_5GHZ)
327                         band = wiphy->bands[IEEE80211_BAND_5GHZ];
328                 else {
329                         IWM_ERR(iwm, "Invalid band: %d\n", umac_bss->band);
330                         return -EINVAL;
331                 }
332
333                 freq = ieee80211_channel_to_frequency(umac_bss->channel);
334                 channel = ieee80211_get_channel(wiphy, freq);
335                 signal = umac_bss->rssi * 100;
336
337                 if (!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
338                                                le16_to_cpu(umac_bss->frame_len),
339                                                signal, GFP_KERNEL))
340                         return -EINVAL;
341         }
342
343         return 0;
344 }
345
346 static int iwm_cfg80211_change_iface(struct wiphy *wiphy,
347                                      struct net_device *ndev,
348                                      enum nl80211_iftype type, u32 *flags,
349                                      struct vif_params *params)
350 {
351         struct wireless_dev *wdev;
352         struct iwm_priv *iwm;
353         u32 old_mode;
354
355         wdev = ndev->ieee80211_ptr;
356         iwm = ndev_to_iwm(ndev);
357         old_mode = iwm->conf.mode;
358
359         switch (type) {
360         case NL80211_IFTYPE_STATION:
361                 iwm->conf.mode = UMAC_MODE_BSS;
362                 break;
363         case NL80211_IFTYPE_ADHOC:
364                 iwm->conf.mode = UMAC_MODE_IBSS;
365                 break;
366         default:
367                 return -EOPNOTSUPP;
368         }
369
370         wdev->iftype = type;
371
372         if ((old_mode == iwm->conf.mode) || !iwm->umac_profile)
373                 return 0;
374
375         iwm->umac_profile->mode = cpu_to_le32(iwm->conf.mode);
376
377         if (iwm->umac_profile_active) {
378                 int ret = iwm_invalidate_mlme_profile(iwm);
379                 if (ret < 0)
380                         IWM_ERR(iwm, "Couldn't invalidate profile\n");
381         }
382
383         return 0;
384 }
385
386 static int iwm_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
387                              struct cfg80211_scan_request *request)
388 {
389         struct iwm_priv *iwm = ndev_to_iwm(ndev);
390         int ret;
391
392         if (!test_bit(IWM_STATUS_READY, &iwm->status)) {
393                 IWM_ERR(iwm, "Scan while device is not ready\n");
394                 return -EIO;
395         }
396
397         if (test_bit(IWM_STATUS_SCANNING, &iwm->status)) {
398                 IWM_ERR(iwm, "Scanning already\n");
399                 return -EAGAIN;
400         }
401
402         if (test_bit(IWM_STATUS_SCAN_ABORTING, &iwm->status)) {
403                 IWM_ERR(iwm, "Scanning being aborted\n");
404                 return -EAGAIN;
405         }
406
407         set_bit(IWM_STATUS_SCANNING, &iwm->status);
408
409         ret = iwm_scan_ssids(iwm, request->ssids, request->n_ssids);
410         if (ret) {
411                 clear_bit(IWM_STATUS_SCANNING, &iwm->status);
412                 return ret;
413         }
414
415         iwm->scan_request = request;
416         return 0;
417 }
418
419 static int iwm_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
420 {
421         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
422
423         if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
424             (iwm->conf.rts_threshold != wiphy->rts_threshold)) {
425                 int ret;
426
427                 iwm->conf.rts_threshold = wiphy->rts_threshold;
428
429                 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
430                                              CFG_RTS_THRESHOLD,
431                                              iwm->conf.rts_threshold);
432                 if (ret < 0)
433                         return ret;
434         }
435
436         if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
437             (iwm->conf.frag_threshold != wiphy->frag_threshold)) {
438                 int ret;
439
440                 iwm->conf.frag_threshold = wiphy->frag_threshold;
441
442                 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX,
443                                              CFG_FRAG_THRESHOLD,
444                                              iwm->conf.frag_threshold);
445                 if (ret < 0)
446                         return ret;
447         }
448
449         return 0;
450 }
451
452 static int iwm_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
453                                   struct cfg80211_ibss_params *params)
454 {
455         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
456         struct ieee80211_channel *chan = params->channel;
457         struct cfg80211_bss *bss;
458
459         if (!test_bit(IWM_STATUS_READY, &iwm->status))
460                 return -EIO;
461
462         /* UMAC doesn't support creating IBSS network with specified bssid.
463          * This should be removed after we have join only mode supported. */
464         if (params->bssid)
465                 return -EOPNOTSUPP;
466
467         bss = cfg80211_get_ibss(iwm_to_wiphy(iwm), NULL,
468                                 params->ssid, params->ssid_len);
469         if (!bss) {
470                 iwm_scan_one_ssid(iwm, params->ssid, params->ssid_len);
471                 schedule_timeout_interruptible(2 * HZ);
472                 bss = cfg80211_get_ibss(iwm_to_wiphy(iwm), NULL,
473                                         params->ssid, params->ssid_len);
474         }
475         /* IBSS join only mode is not supported by UMAC ATM */
476         if (bss) {
477                 cfg80211_put_bss(bss);
478                 return -EOPNOTSUPP;
479         }
480
481         iwm->channel = ieee80211_frequency_to_channel(chan->center_freq);
482         iwm->umac_profile->ibss.band = chan->band;
483         iwm->umac_profile->ibss.channel = iwm->channel;
484         iwm->umac_profile->ssid.ssid_len = params->ssid_len;
485         memcpy(iwm->umac_profile->ssid.ssid, params->ssid, params->ssid_len);
486
487         if (params->bssid)
488                 memcpy(&iwm->umac_profile->bssid[0], params->bssid, ETH_ALEN);
489
490         return iwm_send_mlme_profile(iwm);
491 }
492
493 static int iwm_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
494 {
495         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
496
497         if (iwm->umac_profile_active)
498                 return iwm_invalidate_mlme_profile(iwm);
499
500         return 0;
501 }
502
503 static struct cfg80211_ops iwm_cfg80211_ops = {
504         .change_virtual_intf = iwm_cfg80211_change_iface,
505         .add_key = iwm_cfg80211_add_key,
506         .get_key = iwm_cfg80211_get_key,
507         .del_key = iwm_cfg80211_del_key,
508         .set_default_key = iwm_cfg80211_set_default_key,
509         .scan = iwm_cfg80211_scan,
510         .set_wiphy_params = iwm_cfg80211_set_wiphy_params,
511         .join_ibss = iwm_cfg80211_join_ibss,
512         .leave_ibss = iwm_cfg80211_leave_ibss,
513 };
514
515 struct wireless_dev *iwm_wdev_alloc(int sizeof_bus, struct device *dev)
516 {
517         int ret = 0;
518         struct wireless_dev *wdev;
519
520         /*
521          * We're trying to have the following memory
522          * layout:
523          *
524          * +-------------------------+
525          * | struct wiphy            |
526          * +-------------------------+
527          * | struct iwm_priv         |
528          * +-------------------------+
529          * | bus private data        |
530          * | (e.g. iwm_priv_sdio)    |
531          * +-------------------------+
532          *
533          */
534
535         wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
536         if (!wdev) {
537                 dev_err(dev, "Couldn't allocate wireless device\n");
538                 return ERR_PTR(-ENOMEM);
539         }
540
541         wdev->wiphy = wiphy_new(&iwm_cfg80211_ops,
542                                 sizeof(struct iwm_priv) + sizeof_bus);
543         if (!wdev->wiphy) {
544                 dev_err(dev, "Couldn't allocate wiphy device\n");
545                 ret = -ENOMEM;
546                 goto out_err_new;
547         }
548
549         set_wiphy_dev(wdev->wiphy, dev);
550         wdev->wiphy->max_scan_ssids = UMAC_WIFI_IF_PROBE_OPTION_MAX;
551         wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
552                                        BIT(NL80211_IFTYPE_ADHOC);
553         wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &iwm_band_2ghz;
554         wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &iwm_band_5ghz;
555         wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
556
557         ret = wiphy_register(wdev->wiphy);
558         if (ret < 0) {
559                 dev_err(dev, "Couldn't register wiphy device\n");
560                 goto out_err_register;
561         }
562
563         return wdev;
564
565  out_err_register:
566         wiphy_free(wdev->wiphy);
567
568  out_err_new:
569         kfree(wdev);
570
571         return ERR_PTR(ret);
572 }
573
574 void iwm_wdev_free(struct iwm_priv *iwm)
575 {
576         struct wireless_dev *wdev = iwm_to_wdev(iwm);
577
578         if (!wdev)
579                 return;
580
581         wiphy_unregister(wdev->wiphy);
582         wiphy_free(wdev->wiphy);
583         kfree(wdev);
584 }