1
2
3
4
5
6
7
8
9#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
10
11#include <linux/hardirq.h>
12#include <linux/sched.h>
13#include <linux/wait.h>
14#include <linux/slab.h>
15#include <linux/ieee80211.h>
16#include <net/cfg80211.h>
17#include <asm/unaligned.h>
18
19#include "decl.h"
20#include "cfg.h"
21#include "cmd.h"
22#include "mesh.h"
23
24
25#define CHAN2G(_channel, _freq, _flags) { \
26 .band = IEEE80211_BAND_2GHZ, \
27 .center_freq = (_freq), \
28 .hw_value = (_channel), \
29 .flags = (_flags), \
30 .max_antenna_gain = 0, \
31 .max_power = 30, \
32}
33
34static struct ieee80211_channel lbs_2ghz_channels[] = {
35 CHAN2G(1, 2412, 0),
36 CHAN2G(2, 2417, 0),
37 CHAN2G(3, 2422, 0),
38 CHAN2G(4, 2427, 0),
39 CHAN2G(5, 2432, 0),
40 CHAN2G(6, 2437, 0),
41 CHAN2G(7, 2442, 0),
42 CHAN2G(8, 2447, 0),
43 CHAN2G(9, 2452, 0),
44 CHAN2G(10, 2457, 0),
45 CHAN2G(11, 2462, 0),
46 CHAN2G(12, 2467, 0),
47 CHAN2G(13, 2472, 0),
48 CHAN2G(14, 2484, 0),
49};
50
51#define RATETAB_ENT(_rate, _hw_value, _flags) { \
52 .bitrate = (_rate), \
53 .hw_value = (_hw_value), \
54 .flags = (_flags), \
55}
56
57
58
59static struct ieee80211_rate lbs_rates[] = {
60 RATETAB_ENT(10, 0, 0),
61 RATETAB_ENT(20, 1, 0),
62 RATETAB_ENT(55, 2, 0),
63 RATETAB_ENT(110, 3, 0),
64 RATETAB_ENT(60, 9, 0),
65 RATETAB_ENT(90, 6, 0),
66 RATETAB_ENT(120, 7, 0),
67 RATETAB_ENT(180, 8, 0),
68 RATETAB_ENT(240, 9, 0),
69 RATETAB_ENT(360, 10, 0),
70 RATETAB_ENT(480, 11, 0),
71 RATETAB_ENT(540, 12, 0),
72};
73
74static struct ieee80211_supported_band lbs_band_2ghz = {
75 .channels = lbs_2ghz_channels,
76 .n_channels = ARRAY_SIZE(lbs_2ghz_channels),
77 .bitrates = lbs_rates,
78 .n_bitrates = ARRAY_SIZE(lbs_rates),
79};
80
81
82static const u32 cipher_suites[] = {
83 WLAN_CIPHER_SUITE_WEP40,
84 WLAN_CIPHER_SUITE_WEP104,
85 WLAN_CIPHER_SUITE_TKIP,
86 WLAN_CIPHER_SUITE_CCMP,
87};
88
89
90#define LBS_DWELL_PASSIVE 100
91#define LBS_DWELL_ACTIVE 40
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106static int lbs_auth_to_authtype(enum nl80211_auth_type auth_type)
107{
108 int ret = -ENOTSUPP;
109
110 switch (auth_type) {
111 case NL80211_AUTHTYPE_OPEN_SYSTEM:
112 case NL80211_AUTHTYPE_SHARED_KEY:
113 ret = auth_type;
114 break;
115 case NL80211_AUTHTYPE_AUTOMATIC:
116 ret = NL80211_AUTHTYPE_OPEN_SYSTEM;
117 break;
118 case NL80211_AUTHTYPE_NETWORK_EAP:
119 ret = 0x80;
120 break;
121 default:
122
123 break;
124 }
125 return ret;
126}
127
128
129
130
131
132
133static int lbs_add_rates(u8 *rates)
134{
135 size_t i;
136
137 for (i = 0; i < ARRAY_SIZE(lbs_rates); i++) {
138 u8 rate = lbs_rates[i].bitrate / 5;
139 if (rate == 0x02 || rate == 0x04 ||
140 rate == 0x0b || rate == 0x16)
141 rate |= 0x80;
142 rates[i] = rate;
143 }
144 return ARRAY_SIZE(lbs_rates);
145}
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160#define LBS_MAX_SSID_TLV_SIZE \
161 (sizeof(struct mrvl_ie_header) \
162 + IEEE80211_MAX_SSID_LEN)
163
164static int lbs_add_ssid_tlv(u8 *tlv, const u8 *ssid, int ssid_len)
165{
166 struct mrvl_ie_ssid_param_set *ssid_tlv = (void *)tlv;
167
168
169
170
171
172
173 ssid_tlv->header.type = cpu_to_le16(TLV_TYPE_SSID);
174 ssid_tlv->header.len = cpu_to_le16(ssid_len);
175 memcpy(ssid_tlv->ssid, ssid, ssid_len);
176 return sizeof(ssid_tlv->header) + ssid_len;
177}
178
179
180
181
182
183
184
185#define LBS_MAX_CHANNEL_LIST_TLV_SIZE \
186 (sizeof(struct mrvl_ie_header) \
187 + (LBS_SCAN_BEFORE_NAP * sizeof(struct chanscanparamset)))
188
189static int lbs_add_channel_list_tlv(struct lbs_private *priv, u8 *tlv,
190 int last_channel, int active_scan)
191{
192 int chanscanparamsize = sizeof(struct chanscanparamset) *
193 (last_channel - priv->scan_channel);
194
195 struct mrvl_ie_header *header = (void *) tlv;
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210 header->type = cpu_to_le16(TLV_TYPE_CHANLIST);
211 header->len = cpu_to_le16(chanscanparamsize);
212 tlv += sizeof(struct mrvl_ie_header);
213
214
215
216 memset(tlv, 0, chanscanparamsize);
217
218 while (priv->scan_channel < last_channel) {
219 struct chanscanparamset *param = (void *) tlv;
220
221 param->radiotype = CMD_SCAN_RADIO_TYPE_BG;
222 param->channumber =
223 priv->scan_req->channels[priv->scan_channel]->hw_value;
224 if (active_scan) {
225 param->maxscantime = cpu_to_le16(LBS_DWELL_ACTIVE);
226 } else {
227 param->chanscanmode.passivescan = 1;
228 param->maxscantime = cpu_to_le16(LBS_DWELL_PASSIVE);
229 }
230 tlv += sizeof(struct chanscanparamset);
231 priv->scan_channel++;
232 }
233 return sizeof(struct mrvl_ie_header) + chanscanparamsize;
234}
235
236
237
238
239
240
241
242
243
244
245#define LBS_MAX_RATES_TLV_SIZE \
246 (sizeof(struct mrvl_ie_header) \
247 + (ARRAY_SIZE(lbs_rates)))
248
249
250static int lbs_add_supported_rates_tlv(u8 *tlv)
251{
252 size_t i;
253 struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv;
254
255
256
257
258
259
260 rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES);
261 tlv += sizeof(rate_tlv->header);
262 i = lbs_add_rates(tlv);
263 tlv += i;
264 rate_tlv->header.len = cpu_to_le16(i);
265 return sizeof(rate_tlv->header) + i;
266}
267
268
269static u8 *
270add_ie_rates(u8 *tlv, const u8 *ie, int *nrates)
271{
272 int hw, ap, ap_max = ie[1];
273 u8 hw_rate;
274
275
276 ie += 2;
277
278 lbs_deb_hex(LBS_DEB_ASSOC, "AP IE Rates", (u8 *) ie, ap_max);
279
280 for (hw = 0; hw < ARRAY_SIZE(lbs_rates); hw++) {
281 hw_rate = lbs_rates[hw].bitrate / 5;
282 for (ap = 0; ap < ap_max; ap++) {
283 if (hw_rate == (ie[ap] & 0x7f)) {
284 *tlv++ = ie[ap];
285 *nrates = *nrates + 1;
286 }
287 }
288 }
289 return tlv;
290}
291
292
293
294
295static int lbs_add_common_rates_tlv(u8 *tlv, struct cfg80211_bss *bss)
296{
297 struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv;
298 const u8 *rates_eid, *ext_rates_eid;
299 int n = 0;
300
301 rcu_read_lock();
302 rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES);
303 ext_rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_EXT_SUPP_RATES);
304
305
306
307
308
309
310 rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES);
311 tlv += sizeof(rate_tlv->header);
312
313
314 if (rates_eid) {
315 tlv = add_ie_rates(tlv, rates_eid, &n);
316
317
318 if (ext_rates_eid)
319 tlv = add_ie_rates(tlv, ext_rates_eid, &n);
320 } else {
321 lbs_deb_assoc("assoc: bss had no basic rate IE\n");
322
323 *tlv++ = 0x82;
324 *tlv++ = 0x84;
325 *tlv++ = 0x8b;
326 *tlv++ = 0x96;
327 n = 4;
328 }
329 rcu_read_unlock();
330
331 rate_tlv->header.len = cpu_to_le16(n);
332 return sizeof(rate_tlv->header) + n;
333}
334
335
336
337
338
339
340
341#define LBS_MAX_AUTH_TYPE_TLV_SIZE \
342 sizeof(struct mrvl_ie_auth_type)
343
344static int lbs_add_auth_type_tlv(u8 *tlv, enum nl80211_auth_type auth_type)
345{
346 struct mrvl_ie_auth_type *auth = (void *) tlv;
347
348
349
350
351
352
353 auth->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE);
354 auth->header.len = cpu_to_le16(sizeof(*auth)-sizeof(auth->header));
355 auth->auth = cpu_to_le16(lbs_auth_to_authtype(auth_type));
356 return sizeof(*auth);
357}
358
359
360
361
362
363#define LBS_MAX_CHANNEL_TLV_SIZE \
364 sizeof(struct mrvl_ie_header)
365
366static int lbs_add_channel_tlv(u8 *tlv, u8 channel)
367{
368 struct mrvl_ie_ds_param_set *ds = (void *) tlv;
369
370
371
372
373
374
375 ds->header.type = cpu_to_le16(TLV_TYPE_PHY_DS);
376 ds->header.len = cpu_to_le16(sizeof(*ds)-sizeof(ds->header));
377 ds->channel = channel;
378 return sizeof(*ds);
379}
380
381
382
383
384
385#define LBS_MAX_CF_PARAM_TLV_SIZE \
386 sizeof(struct mrvl_ie_header)
387
388static int lbs_add_cf_param_tlv(u8 *tlv)
389{
390 struct mrvl_ie_cf_param_set *cf = (void *)tlv;
391
392
393
394
395
396
397
398
399
400 cf->header.type = cpu_to_le16(TLV_TYPE_CF);
401 cf->header.len = cpu_to_le16(sizeof(*cf)-sizeof(cf->header));
402 return sizeof(*cf);
403}
404
405
406
407
408#define LBS_MAX_WPA_TLV_SIZE \
409 (sizeof(struct mrvl_ie_header) \
410 + 128 )
411
412static int lbs_add_wpa_tlv(u8 *tlv, const u8 *ie, u8 ie_len)
413{
414 size_t tlv_len;
415
416
417
418
419
420
421
422
423
424
425
426 *tlv++ = *ie++;
427 *tlv++ = 0;
428 tlv_len = *tlv++ = *ie++;
429 *tlv++ = 0;
430 while (tlv_len--)
431 *tlv++ = *ie++;
432
433 return ie_len + 2;
434}
435
436
437
438
439
440static int lbs_cfg_set_monitor_channel(struct wiphy *wiphy,
441 struct cfg80211_chan_def *chandef)
442{
443 struct lbs_private *priv = wiphy_priv(wiphy);
444 int ret = -ENOTSUPP;
445
446 lbs_deb_enter_args(LBS_DEB_CFG80211, "freq %d, type %d",
447 chandef->chan->center_freq,
448 cfg80211_get_chandef_type(chandef));
449
450 if (cfg80211_get_chandef_type(chandef) != NL80211_CHAN_NO_HT)
451 goto out;
452
453 ret = lbs_set_channel(priv, chandef->chan->hw_value);
454
455 out:
456 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
457 return ret;
458}
459
460static int lbs_cfg_set_mesh_channel(struct wiphy *wiphy,
461 struct net_device *netdev,
462 struct ieee80211_channel *channel)
463{
464 struct lbs_private *priv = wiphy_priv(wiphy);
465 int ret = -ENOTSUPP;
466
467 lbs_deb_enter_args(LBS_DEB_CFG80211, "iface %s freq %d",
468 netdev_name(netdev), channel->center_freq);
469
470 if (netdev != priv->mesh_dev)
471 goto out;
472
473 ret = lbs_mesh_set_channel(priv, channel->hw_value);
474
475 out:
476 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
477 return ret;
478}
479
480
481
482
483
484
485
486
487
488
489
490
491
492#define LBS_SCAN_BEFORE_NAP 4
493
494
495
496
497
498
499
500#define LBS_SCAN_RSSI_TO_MBM(rssi) \
501 ((-(int)rssi + 3)*100)
502
503static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
504 struct cmd_header *resp)
505{
506 struct cfg80211_bss *bss;
507 struct cmd_ds_802_11_scan_rsp *scanresp = (void *)resp;
508 int bsssize;
509 const u8 *pos;
510 const u8 *tsfdesc;
511 int tsfsize;
512 int i;
513 int ret = -EILSEQ;
514
515 lbs_deb_enter(LBS_DEB_CFG80211);
516
517 bsssize = get_unaligned_le16(&scanresp->bssdescriptsize);
518
519 lbs_deb_scan("scan response: %d BSSs (%d bytes); resp size %d bytes\n",
520 scanresp->nr_sets, bsssize, le16_to_cpu(resp->size));
521
522 if (scanresp->nr_sets == 0) {
523 ret = 0;
524 goto done;
525 }
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552 pos = scanresp->bssdesc_and_tlvbuffer;
553
554 lbs_deb_hex(LBS_DEB_SCAN, "SCAN_RSP", scanresp->bssdesc_and_tlvbuffer,
555 scanresp->bssdescriptsize);
556
557 tsfdesc = pos + bsssize;
558 tsfsize = 4 + 8 * scanresp->nr_sets;
559 lbs_deb_hex(LBS_DEB_SCAN, "SCAN_TSF", (u8 *) tsfdesc, tsfsize);
560
561
562 i = get_unaligned_le16(tsfdesc);
563 tsfdesc += 2;
564 if (i != TLV_TYPE_TSFTIMESTAMP) {
565 lbs_deb_scan("scan response: invalid TSF Timestamp %d\n", i);
566 goto done;
567 }
568
569
570
571
572
573 i = get_unaligned_le16(tsfdesc);
574 tsfdesc += 2;
575 if (i / 8 != scanresp->nr_sets) {
576 lbs_deb_scan("scan response: invalid number of TSF timestamp "
577 "sets (expected %d got %d)\n", scanresp->nr_sets,
578 i / 8);
579 goto done;
580 }
581
582 for (i = 0; i < scanresp->nr_sets; i++) {
583 const u8 *bssid;
584 const u8 *ie;
585 int left;
586 int ielen;
587 int rssi;
588 u16 intvl;
589 u16 capa;
590 int chan_no = -1;
591 const u8 *ssid = NULL;
592 u8 ssid_len = 0;
593 DECLARE_SSID_BUF(ssid_buf);
594
595 int len = get_unaligned_le16(pos);
596 pos += 2;
597
598
599 bssid = pos;
600 pos += ETH_ALEN;
601
602 rssi = *pos++;
603
604 pos += 8;
605
606 intvl = get_unaligned_le16(pos);
607 pos += 2;
608
609 capa = get_unaligned_le16(pos);
610 pos += 2;
611
612
613 ie = pos;
614
615
616
617
618 ielen = left = len - (6 + 1 + 8 + 2 + 2);
619 while (left >= 2) {
620 u8 id, elen;
621 id = *pos++;
622 elen = *pos++;
623 left -= 2;
624 if (elen > left || elen == 0) {
625 lbs_deb_scan("scan response: invalid IE fmt\n");
626 goto done;
627 }
628
629 if (id == WLAN_EID_DS_PARAMS)
630 chan_no = *pos;
631 if (id == WLAN_EID_SSID) {
632 ssid = pos;
633 ssid_len = elen;
634 }
635 left -= elen;
636 pos += elen;
637 }
638
639
640 if (chan_no != -1) {
641 struct wiphy *wiphy = priv->wdev->wiphy;
642 int freq = ieee80211_channel_to_frequency(chan_no,
643 IEEE80211_BAND_2GHZ);
644 struct ieee80211_channel *channel =
645 ieee80211_get_channel(wiphy, freq);
646
647 lbs_deb_scan("scan: %pM, capa %04x, chan %2d, %s, "
648 "%d dBm\n",
649 bssid, capa, chan_no,
650 print_ssid(ssid_buf, ssid, ssid_len),
651 LBS_SCAN_RSSI_TO_MBM(rssi)/100);
652
653 if (channel &&
654 !(channel->flags & IEEE80211_CHAN_DISABLED)) {
655 bss = cfg80211_inform_bss(wiphy, channel,
656 bssid, get_unaligned_le64(tsfdesc),
657 capa, intvl, ie, ielen,
658 LBS_SCAN_RSSI_TO_MBM(rssi),
659 GFP_KERNEL);
660 cfg80211_put_bss(wiphy, bss);
661 }
662 } else
663 lbs_deb_scan("scan response: missing BSS channel IE\n");
664
665 tsfdesc += 8;
666 }
667 ret = 0;
668
669 done:
670 lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
671 return ret;
672}
673
674
675
676
677
678
679#define LBS_SCAN_MAX_CMD_SIZE \
680 (sizeof(struct cmd_ds_802_11_scan) \
681 + LBS_MAX_SSID_TLV_SIZE \
682 + LBS_MAX_CHANNEL_LIST_TLV_SIZE \
683 + LBS_MAX_RATES_TLV_SIZE)
684
685
686
687
688
689static void lbs_scan_worker(struct work_struct *work)
690{
691 struct lbs_private *priv =
692 container_of(work, struct lbs_private, scan_work.work);
693 struct cmd_ds_802_11_scan *scan_cmd;
694 u8 *tlv;
695 int last_channel;
696 int running, carrier;
697
698 lbs_deb_enter(LBS_DEB_SCAN);
699
700 scan_cmd = kzalloc(LBS_SCAN_MAX_CMD_SIZE, GFP_KERNEL);
701 if (scan_cmd == NULL)
702 goto out_no_scan_cmd;
703
704
705 scan_cmd->bsstype = CMD_BSS_TYPE_ANY;
706
707
708 running = !netif_queue_stopped(priv->dev);
709 carrier = netif_carrier_ok(priv->dev);
710 if (running)
711 netif_stop_queue(priv->dev);
712 if (carrier)
713 netif_carrier_off(priv->dev);
714
715
716 tlv = scan_cmd->tlvbuffer;
717
718
719 if (priv->scan_req->n_ssids && priv->scan_req->ssids[0].ssid_len > 0)
720 tlv += lbs_add_ssid_tlv(tlv,
721 priv->scan_req->ssids[0].ssid,
722 priv->scan_req->ssids[0].ssid_len);
723
724
725 last_channel = priv->scan_channel + LBS_SCAN_BEFORE_NAP;
726 if (last_channel > priv->scan_req->n_channels)
727 last_channel = priv->scan_req->n_channels;
728 tlv += lbs_add_channel_list_tlv(priv, tlv, last_channel,
729 priv->scan_req->n_ssids);
730
731
732 tlv += lbs_add_supported_rates_tlv(tlv);
733
734 if (priv->scan_channel < priv->scan_req->n_channels) {
735 cancel_delayed_work(&priv->scan_work);
736 if (netif_running(priv->dev))
737 queue_delayed_work(priv->work_thread, &priv->scan_work,
738 msecs_to_jiffies(300));
739 }
740
741
742 scan_cmd->hdr.size = cpu_to_le16(tlv - (u8 *)scan_cmd);
743 lbs_deb_hex(LBS_DEB_SCAN, "SCAN_CMD", (void *)scan_cmd,
744 sizeof(*scan_cmd));
745 lbs_deb_hex(LBS_DEB_SCAN, "SCAN_TLV", scan_cmd->tlvbuffer,
746 tlv - scan_cmd->tlvbuffer);
747
748 __lbs_cmd(priv, CMD_802_11_SCAN, &scan_cmd->hdr,
749 le16_to_cpu(scan_cmd->hdr.size),
750 lbs_ret_scan, 0);
751
752 if (priv->scan_channel >= priv->scan_req->n_channels) {
753
754 cancel_delayed_work(&priv->scan_work);
755 lbs_scan_done(priv);
756 }
757
758
759 if (carrier)
760 netif_carrier_on(priv->dev);
761 if (running && !priv->tx_pending_len)
762 netif_wake_queue(priv->dev);
763
764 kfree(scan_cmd);
765
766
767 if (priv->scan_req == NULL) {
768 lbs_deb_scan("scan: waking up waiters\n");
769 wake_up_all(&priv->scan_q);
770 }
771
772 out_no_scan_cmd:
773 lbs_deb_leave(LBS_DEB_SCAN);
774}
775
776static void _internal_start_scan(struct lbs_private *priv, bool internal,
777 struct cfg80211_scan_request *request)
778{
779 lbs_deb_enter(LBS_DEB_CFG80211);
780
781 lbs_deb_scan("scan: ssids %d, channels %d, ie_len %zd\n",
782 request->n_ssids, request->n_channels, request->ie_len);
783
784 priv->scan_channel = 0;
785 priv->scan_req = request;
786 priv->internal_scan = internal;
787
788 queue_delayed_work(priv->work_thread, &priv->scan_work,
789 msecs_to_jiffies(50));
790
791 lbs_deb_leave(LBS_DEB_CFG80211);
792}
793
794
795
796
797void lbs_scan_done(struct lbs_private *priv)
798{
799 WARN_ON(!priv->scan_req);
800
801 if (priv->internal_scan)
802 kfree(priv->scan_req);
803 else
804 cfg80211_scan_done(priv->scan_req, false);
805
806 priv->scan_req = NULL;
807}
808
809static int lbs_cfg_scan(struct wiphy *wiphy,
810 struct cfg80211_scan_request *request)
811{
812 struct lbs_private *priv = wiphy_priv(wiphy);
813 int ret = 0;
814
815 lbs_deb_enter(LBS_DEB_CFG80211);
816
817 if (priv->scan_req || delayed_work_pending(&priv->scan_work)) {
818
819 ret = -EAGAIN;
820 goto out;
821 }
822
823 _internal_start_scan(priv, false, request);
824
825 if (priv->surpriseremoved)
826 ret = -EIO;
827
828 out:
829 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
830 return ret;
831}
832
833
834
835
836
837
838
839
840void lbs_send_disconnect_notification(struct lbs_private *priv)
841{
842 lbs_deb_enter(LBS_DEB_CFG80211);
843
844 cfg80211_disconnected(priv->dev,
845 0,
846 NULL, 0,
847 GFP_KERNEL);
848
849 lbs_deb_leave(LBS_DEB_CFG80211);
850}
851
852void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event)
853{
854 lbs_deb_enter(LBS_DEB_CFG80211);
855
856 cfg80211_michael_mic_failure(priv->dev,
857 priv->assoc_bss,
858 event == MACREG_INT_CODE_MIC_ERR_MULTICAST ?
859 NL80211_KEYTYPE_GROUP :
860 NL80211_KEYTYPE_PAIRWISE,
861 -1,
862 NULL,
863 GFP_KERNEL);
864
865 lbs_deb_leave(LBS_DEB_CFG80211);
866}
867
868
869
870
871
872
873
874
875
876
877
878
879static int lbs_remove_wep_keys(struct lbs_private *priv)
880{
881 struct cmd_ds_802_11_set_wep cmd;
882 int ret;
883
884 lbs_deb_enter(LBS_DEB_CFG80211);
885
886 memset(&cmd, 0, sizeof(cmd));
887 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
888 cmd.keyindex = cpu_to_le16(priv->wep_tx_key);
889 cmd.action = cpu_to_le16(CMD_ACT_REMOVE);
890
891 ret = lbs_cmd_with_response(priv, CMD_802_11_SET_WEP, &cmd);
892
893 lbs_deb_leave(LBS_DEB_CFG80211);
894 return ret;
895}
896
897
898
899
900static int lbs_set_wep_keys(struct lbs_private *priv)
901{
902 struct cmd_ds_802_11_set_wep cmd;
903 int i;
904 int ret;
905
906 lbs_deb_enter(LBS_DEB_CFG80211);
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927 if (priv->wep_key_len[0] || priv->wep_key_len[1] ||
928 priv->wep_key_len[2] || priv->wep_key_len[3]) {
929
930 memset(&cmd, 0, sizeof(cmd));
931 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
932 cmd.keyindex = cpu_to_le16(priv->wep_tx_key);
933 cmd.action = cpu_to_le16(CMD_ACT_ADD);
934
935 for (i = 0; i < 4; i++) {
936 switch (priv->wep_key_len[i]) {
937 case WLAN_KEY_LEN_WEP40:
938 cmd.keytype[i] = CMD_TYPE_WEP_40_BIT;
939 break;
940 case WLAN_KEY_LEN_WEP104:
941 cmd.keytype[i] = CMD_TYPE_WEP_104_BIT;
942 break;
943 default:
944 cmd.keytype[i] = 0;
945 break;
946 }
947 memcpy(cmd.keymaterial[i], priv->wep_key[i],
948 priv->wep_key_len[i]);
949 }
950
951 ret = lbs_cmd_with_response(priv, CMD_802_11_SET_WEP, &cmd);
952 } else {
953
954 ret = lbs_remove_wep_keys(priv);
955 }
956
957 lbs_deb_leave(LBS_DEB_CFG80211);
958 return ret;
959}
960
961
962
963
964
965static int lbs_enable_rsn(struct lbs_private *priv, int enable)
966{
967 struct cmd_ds_802_11_enable_rsn cmd;
968 int ret;
969
970 lbs_deb_enter_args(LBS_DEB_CFG80211, "%d", enable);
971
972
973
974
975
976
977
978
979
980 memset(&cmd, 0, sizeof(cmd));
981 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
982 cmd.action = cpu_to_le16(CMD_ACT_SET);
983 cmd.enable = cpu_to_le16(enable);
984
985 ret = lbs_cmd_with_response(priv, CMD_802_11_ENABLE_RSN, &cmd);
986
987 lbs_deb_leave(LBS_DEB_CFG80211);
988 return ret;
989}
990
991
992
993
994
995
996
997
998
999
1000
1001struct cmd_key_material {
1002 struct cmd_header hdr;
1003
1004 __le16 action;
1005 struct MrvlIEtype_keyParamSet param;
1006} __packed;
1007
1008static int lbs_set_key_material(struct lbs_private *priv,
1009 int key_type,
1010 int key_info,
1011 u8 *key, u16 key_len)
1012{
1013 struct cmd_key_material cmd;
1014 int ret;
1015
1016 lbs_deb_enter(LBS_DEB_CFG80211);
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033 memset(&cmd, 0, sizeof(cmd));
1034 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1035 cmd.action = cpu_to_le16(CMD_ACT_SET);
1036 cmd.param.type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
1037 cmd.param.length = cpu_to_le16(sizeof(cmd.param) - 4);
1038 cmd.param.keytypeid = cpu_to_le16(key_type);
1039 cmd.param.keyinfo = cpu_to_le16(key_info);
1040 cmd.param.keylen = cpu_to_le16(key_len);
1041 if (key && key_len)
1042 memcpy(cmd.param.key, key, key_len);
1043
1044 ret = lbs_cmd_with_response(priv, CMD_802_11_KEY_MATERIAL, &cmd);
1045
1046 lbs_deb_leave(LBS_DEB_CFG80211);
1047 return ret;
1048}
1049
1050
1051
1052
1053
1054
1055
1056
1057static int lbs_set_authtype(struct lbs_private *priv,
1058 struct cfg80211_connect_params *sme)
1059{
1060 struct cmd_ds_802_11_authenticate cmd;
1061 int ret;
1062
1063 lbs_deb_enter_args(LBS_DEB_CFG80211, "%d", sme->auth_type);
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074 memset(&cmd, 0, sizeof(cmd));
1075 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1076 if (sme->bssid)
1077 memcpy(cmd.bssid, sme->bssid, ETH_ALEN);
1078
1079 ret = lbs_auth_to_authtype(sme->auth_type);
1080 if (ret < 0)
1081 goto done;
1082
1083 cmd.authtype = ret;
1084 ret = lbs_cmd_with_response(priv, CMD_802_11_AUTHENTICATE, &cmd);
1085
1086 done:
1087 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
1088 return ret;
1089}
1090
1091
1092
1093
1094
1095#define LBS_ASSOC_MAX_CMD_SIZE \
1096 (sizeof(struct cmd_ds_802_11_associate) \
1097 - 512 \
1098 + LBS_MAX_SSID_TLV_SIZE \
1099 + LBS_MAX_CHANNEL_TLV_SIZE \
1100 + LBS_MAX_CF_PARAM_TLV_SIZE \
1101 + LBS_MAX_AUTH_TYPE_TLV_SIZE \
1102 + LBS_MAX_WPA_TLV_SIZE)
1103
1104static int lbs_associate(struct lbs_private *priv,
1105 struct cfg80211_bss *bss,
1106 struct cfg80211_connect_params *sme)
1107{
1108 struct cmd_ds_802_11_associate_response *resp;
1109 struct cmd_ds_802_11_associate *cmd = kzalloc(LBS_ASSOC_MAX_CMD_SIZE,
1110 GFP_KERNEL);
1111 const u8 *ssid_eid;
1112 size_t len, resp_ie_len;
1113 int status;
1114 int ret;
1115 u8 *pos = &(cmd->iebuf[0]);
1116 u8 *tmp;
1117
1118 lbs_deb_enter(LBS_DEB_CFG80211);
1119
1120 if (!cmd) {
1121 ret = -ENOMEM;
1122 goto done;
1123 }
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137 cmd->hdr.command = cpu_to_le16(CMD_802_11_ASSOCIATE);
1138
1139
1140 memcpy(cmd->bssid, bss->bssid, ETH_ALEN);
1141 cmd->listeninterval = cpu_to_le16(MRVDRV_DEFAULT_LISTEN_INTERVAL);
1142 cmd->capability = cpu_to_le16(bss->capability);
1143
1144
1145 rcu_read_lock();
1146 ssid_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SSID);
1147 if (ssid_eid)
1148 pos += lbs_add_ssid_tlv(pos, ssid_eid + 2, ssid_eid[1]);
1149 else
1150 lbs_deb_assoc("no SSID\n");
1151 rcu_read_unlock();
1152
1153
1154 if (bss->channel)
1155 pos += lbs_add_channel_tlv(pos, bss->channel->hw_value);
1156 else
1157 lbs_deb_assoc("no channel\n");
1158
1159
1160 pos += lbs_add_cf_param_tlv(pos);
1161
1162
1163 tmp = pos + 4;
1164 pos += lbs_add_common_rates_tlv(pos, bss);
1165 lbs_deb_hex(LBS_DEB_ASSOC, "Common Rates", tmp, pos - tmp);
1166
1167
1168 if (MRVL_FW_MAJOR_REV(priv->fwrelease) >= 9)
1169 pos += lbs_add_auth_type_tlv(pos, sme->auth_type);
1170
1171
1172 if (sme->ie && sme->ie_len)
1173 pos += lbs_add_wpa_tlv(pos, sme->ie, sme->ie_len);
1174
1175 len = (sizeof(*cmd) - sizeof(cmd->iebuf)) +
1176 (u16)(pos - (u8 *) &cmd->iebuf);
1177 cmd->hdr.size = cpu_to_le16(len);
1178
1179 lbs_deb_hex(LBS_DEB_ASSOC, "ASSOC_CMD", (u8 *) cmd,
1180 le16_to_cpu(cmd->hdr.size));
1181
1182
1183 memcpy(priv->assoc_bss, bss->bssid, ETH_ALEN);
1184
1185 ret = lbs_cmd_with_response(priv, CMD_802_11_ASSOCIATE, cmd);
1186 if (ret)
1187 goto done;
1188
1189
1190
1191 resp = (void *) cmd;
1192 status = le16_to_cpu(resp->statuscode);
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210 if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) {
1211 switch (status) {
1212 case 0:
1213 break;
1214 case 1:
1215 lbs_deb_assoc("invalid association parameters\n");
1216 status = WLAN_STATUS_CAPS_UNSUPPORTED;
1217 break;
1218 case 2:
1219 lbs_deb_assoc("timer expired while waiting for AP\n");
1220 status = WLAN_STATUS_AUTH_TIMEOUT;
1221 break;
1222 case 3:
1223 lbs_deb_assoc("association refused by AP\n");
1224 status = WLAN_STATUS_ASSOC_DENIED_UNSPEC;
1225 break;
1226 case 4:
1227 lbs_deb_assoc("authentication refused by AP\n");
1228 status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
1229 break;
1230 default:
1231 lbs_deb_assoc("association failure %d\n", status);
1232
1233
1234
1235 break;
1236 }
1237 }
1238
1239 lbs_deb_assoc("status %d, statuscode 0x%04x, capability 0x%04x, "
1240 "aid 0x%04x\n", status, le16_to_cpu(resp->statuscode),
1241 le16_to_cpu(resp->capability), le16_to_cpu(resp->aid));
1242
1243 resp_ie_len = le16_to_cpu(resp->hdr.size)
1244 - sizeof(resp->hdr)
1245 - 6;
1246 cfg80211_connect_result(priv->dev,
1247 priv->assoc_bss,
1248 sme->ie, sme->ie_len,
1249 resp->iebuf, resp_ie_len,
1250 status,
1251 GFP_KERNEL);
1252
1253 if (status == 0) {
1254
1255 priv->connect_status = LBS_CONNECTED;
1256 netif_carrier_on(priv->dev);
1257 if (!priv->tx_pending_len)
1258 netif_tx_wake_all_queues(priv->dev);
1259 }
1260
1261 kfree(cmd);
1262done:
1263 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
1264 return ret;
1265}
1266
1267static struct cfg80211_scan_request *
1268_new_connect_scan_req(struct wiphy *wiphy, struct cfg80211_connect_params *sme)
1269{
1270 struct cfg80211_scan_request *creq = NULL;
1271 int i, n_channels = 0;
1272 enum ieee80211_band band;
1273
1274 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
1275 if (wiphy->bands[band])
1276 n_channels += wiphy->bands[band]->n_channels;
1277 }
1278
1279 creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) +
1280 n_channels * sizeof(void *),
1281 GFP_ATOMIC);
1282 if (!creq)
1283 return NULL;
1284
1285
1286 creq->ssids = (void *)&creq->channels[n_channels];
1287 creq->n_channels = n_channels;
1288 creq->n_ssids = 1;
1289
1290
1291 i = 0;
1292 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
1293 int j;
1294
1295 if (!wiphy->bands[band])
1296 continue;
1297
1298 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
1299
1300 if (wiphy->bands[band]->channels[j].flags &
1301 IEEE80211_CHAN_DISABLED)
1302 continue;
1303
1304 creq->channels[i] = &wiphy->bands[band]->channels[j];
1305 i++;
1306 }
1307 }
1308 if (i) {
1309
1310 creq->n_channels = i;
1311
1312
1313 memcpy(creq->ssids[0].ssid, sme->ssid, sme->ssid_len);
1314 creq->ssids[0].ssid_len = sme->ssid_len;
1315 } else {
1316
1317 kfree(creq);
1318 creq = NULL;
1319 }
1320
1321 return creq;
1322}
1323
1324static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,
1325 struct cfg80211_connect_params *sme)
1326{
1327 struct lbs_private *priv = wiphy_priv(wiphy);
1328 struct cfg80211_bss *bss = NULL;
1329 int ret = 0;
1330 u8 preamble = RADIO_PREAMBLE_SHORT;
1331
1332 if (dev == priv->mesh_dev)
1333 return -EOPNOTSUPP;
1334
1335 lbs_deb_enter(LBS_DEB_CFG80211);
1336
1337 if (!sme->bssid) {
1338 struct cfg80211_scan_request *creq;
1339
1340
1341
1342
1343
1344 lbs_deb_assoc("assoc: waiting for existing scans\n");
1345 wait_event_interruptible_timeout(priv->scan_q,
1346 (priv->scan_req == NULL),
1347 (15 * HZ));
1348
1349 creq = _new_connect_scan_req(wiphy, sme);
1350 if (!creq) {
1351 ret = -EINVAL;
1352 goto done;
1353 }
1354
1355 lbs_deb_assoc("assoc: scanning for compatible AP\n");
1356 _internal_start_scan(priv, true, creq);
1357
1358 lbs_deb_assoc("assoc: waiting for scan to complete\n");
1359 wait_event_interruptible_timeout(priv->scan_q,
1360 (priv->scan_req == NULL),
1361 (15 * HZ));
1362 lbs_deb_assoc("assoc: scanning competed\n");
1363 }
1364
1365
1366 bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid,
1367 sme->ssid, sme->ssid_len,
1368 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
1369 if (!bss) {
1370 wiphy_err(wiphy, "assoc: bss %pM not in scan results\n",
1371 sme->bssid);
1372 ret = -ENOENT;
1373 goto done;
1374 }
1375 lbs_deb_assoc("trying %pM\n", bss->bssid);
1376 lbs_deb_assoc("cipher 0x%x, key index %d, key len %d\n",
1377 sme->crypto.cipher_group,
1378 sme->key_idx, sme->key_len);
1379
1380
1381 priv->wep_tx_key = 0;
1382 memset(priv->wep_key, 0, sizeof(priv->wep_key));
1383 memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len));
1384
1385
1386 switch (sme->crypto.cipher_group) {
1387 case WLAN_CIPHER_SUITE_WEP40:
1388 case WLAN_CIPHER_SUITE_WEP104:
1389
1390 priv->wep_tx_key = sme->key_idx;
1391 priv->wep_key_len[sme->key_idx] = sme->key_len;
1392 memcpy(priv->wep_key[sme->key_idx], sme->key, sme->key_len);
1393
1394 lbs_set_wep_keys(priv);
1395 priv->mac_control |= CMD_ACT_MAC_WEP_ENABLE;
1396 lbs_set_mac_control(priv);
1397
1398 lbs_enable_rsn(priv, 0);
1399 break;
1400 case 0:
1401
1402
1403
1404
1405
1406
1407
1408 case WLAN_CIPHER_SUITE_TKIP:
1409 case WLAN_CIPHER_SUITE_CCMP:
1410
1411 lbs_remove_wep_keys(priv);
1412 priv->mac_control &= ~CMD_ACT_MAC_WEP_ENABLE;
1413 lbs_set_mac_control(priv);
1414
1415
1416 lbs_set_key_material(priv,
1417 KEY_TYPE_ID_WEP,
1418 KEY_INFO_WPA_UNICAST,
1419 NULL, 0);
1420 lbs_set_key_material(priv,
1421 KEY_TYPE_ID_WEP,
1422 KEY_INFO_WPA_MCAST,
1423 NULL, 0);
1424
1425 lbs_enable_rsn(priv, sme->crypto.cipher_group != 0);
1426 break;
1427 default:
1428 wiphy_err(wiphy, "unsupported cipher group 0x%x\n",
1429 sme->crypto.cipher_group);
1430 ret = -ENOTSUPP;
1431 goto done;
1432 }
1433
1434 ret = lbs_set_authtype(priv, sme);
1435 if (ret == -ENOTSUPP) {
1436 wiphy_err(wiphy, "unsupported authtype 0x%x\n", sme->auth_type);
1437 goto done;
1438 }
1439
1440 lbs_set_radio(priv, preamble, 1);
1441
1442
1443 ret = lbs_associate(priv, bss, sme);
1444
1445 done:
1446 if (bss)
1447 cfg80211_put_bss(wiphy, bss);
1448 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
1449 return ret;
1450}
1451
1452int lbs_disconnect(struct lbs_private *priv, u16 reason)
1453{
1454 struct cmd_ds_802_11_deauthenticate cmd;
1455 int ret;
1456
1457 memset(&cmd, 0, sizeof(cmd));
1458 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1459
1460 memcpy(cmd.macaddr, &priv->assoc_bss, ETH_ALEN);
1461 cmd.reasoncode = cpu_to_le16(reason);
1462
1463 ret = lbs_cmd_with_response(priv, CMD_802_11_DEAUTHENTICATE, &cmd);
1464 if (ret)
1465 return ret;
1466
1467 cfg80211_disconnected(priv->dev,
1468 reason,
1469 NULL, 0,
1470 GFP_KERNEL);
1471 priv->connect_status = LBS_DISCONNECTED;
1472
1473 return 0;
1474}
1475
1476static int lbs_cfg_disconnect(struct wiphy *wiphy, struct net_device *dev,
1477 u16 reason_code)
1478{
1479 struct lbs_private *priv = wiphy_priv(wiphy);
1480
1481 if (dev == priv->mesh_dev)
1482 return -EOPNOTSUPP;
1483
1484 lbs_deb_enter_args(LBS_DEB_CFG80211, "reason_code %d", reason_code);
1485
1486
1487 priv->disassoc_reason = reason_code;
1488
1489 return lbs_disconnect(priv, reason_code);
1490}
1491
1492static int lbs_cfg_set_default_key(struct wiphy *wiphy,
1493 struct net_device *netdev,
1494 u8 key_index, bool unicast,
1495 bool multicast)
1496{
1497 struct lbs_private *priv = wiphy_priv(wiphy);
1498
1499 if (netdev == priv->mesh_dev)
1500 return -EOPNOTSUPP;
1501
1502 lbs_deb_enter(LBS_DEB_CFG80211);
1503
1504 if (key_index != priv->wep_tx_key) {
1505 lbs_deb_assoc("set_default_key: to %d\n", key_index);
1506 priv->wep_tx_key = key_index;
1507 lbs_set_wep_keys(priv);
1508 }
1509
1510 return 0;
1511}
1512
1513
1514static int lbs_cfg_add_key(struct wiphy *wiphy, struct net_device *netdev,
1515 u8 idx, bool pairwise, const u8 *mac_addr,
1516 struct key_params *params)
1517{
1518 struct lbs_private *priv = wiphy_priv(wiphy);
1519 u16 key_info;
1520 u16 key_type;
1521 int ret = 0;
1522
1523 if (netdev == priv->mesh_dev)
1524 return -EOPNOTSUPP;
1525
1526 lbs_deb_enter(LBS_DEB_CFG80211);
1527
1528 lbs_deb_assoc("add_key: cipher 0x%x, mac_addr %pM\n",
1529 params->cipher, mac_addr);
1530 lbs_deb_assoc("add_key: key index %d, key len %d\n",
1531 idx, params->key_len);
1532 if (params->key_len)
1533 lbs_deb_hex(LBS_DEB_CFG80211, "KEY",
1534 params->key, params->key_len);
1535
1536 lbs_deb_assoc("add_key: seq len %d\n", params->seq_len);
1537 if (params->seq_len)
1538 lbs_deb_hex(LBS_DEB_CFG80211, "SEQ",
1539 params->seq, params->seq_len);
1540
1541 switch (params->cipher) {
1542 case WLAN_CIPHER_SUITE_WEP40:
1543 case WLAN_CIPHER_SUITE_WEP104:
1544
1545 if ((priv->wep_key_len[idx] != params->key_len) ||
1546 memcmp(priv->wep_key[idx],
1547 params->key, params->key_len) != 0) {
1548 priv->wep_key_len[idx] = params->key_len;
1549 memcpy(priv->wep_key[idx],
1550 params->key, params->key_len);
1551 lbs_set_wep_keys(priv);
1552 }
1553 break;
1554 case WLAN_CIPHER_SUITE_TKIP:
1555 case WLAN_CIPHER_SUITE_CCMP:
1556 key_info = KEY_INFO_WPA_ENABLED | ((idx == 0)
1557 ? KEY_INFO_WPA_UNICAST
1558 : KEY_INFO_WPA_MCAST);
1559 key_type = (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1560 ? KEY_TYPE_ID_TKIP
1561 : KEY_TYPE_ID_AES;
1562 lbs_set_key_material(priv,
1563 key_type,
1564 key_info,
1565 params->key, params->key_len);
1566 break;
1567 default:
1568 wiphy_err(wiphy, "unhandled cipher 0x%x\n", params->cipher);
1569 ret = -ENOTSUPP;
1570 break;
1571 }
1572
1573 return ret;
1574}
1575
1576
1577static int lbs_cfg_del_key(struct wiphy *wiphy, struct net_device *netdev,
1578 u8 key_index, bool pairwise, const u8 *mac_addr)
1579{
1580
1581 lbs_deb_enter(LBS_DEB_CFG80211);
1582
1583 lbs_deb_assoc("del_key: key_idx %d, mac_addr %pM\n",
1584 key_index, mac_addr);
1585
1586#ifdef TODO
1587 struct lbs_private *priv = wiphy_priv(wiphy);
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603 if (key_index < 3 && priv->wep_key_len[key_index]) {
1604 priv->wep_key_len[key_index] = 0;
1605 lbs_set_wep_keys(priv);
1606 }
1607#endif
1608
1609 return 0;
1610}
1611
1612
1613
1614
1615
1616
1617static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev,
1618 u8 *mac, struct station_info *sinfo)
1619{
1620 struct lbs_private *priv = wiphy_priv(wiphy);
1621 s8 signal, noise;
1622 int ret;
1623 size_t i;
1624
1625 lbs_deb_enter(LBS_DEB_CFG80211);
1626
1627 sinfo->filled |= STATION_INFO_TX_BYTES |
1628 STATION_INFO_TX_PACKETS |
1629 STATION_INFO_RX_BYTES |
1630 STATION_INFO_RX_PACKETS;
1631 sinfo->tx_bytes = priv->dev->stats.tx_bytes;
1632 sinfo->tx_packets = priv->dev->stats.tx_packets;
1633 sinfo->rx_bytes = priv->dev->stats.rx_bytes;
1634 sinfo->rx_packets = priv->dev->stats.rx_packets;
1635
1636
1637 ret = lbs_get_rssi(priv, &signal, &noise);
1638 if (ret == 0) {
1639 sinfo->signal = signal;
1640 sinfo->filled |= STATION_INFO_SIGNAL;
1641 }
1642
1643
1644 for (i = 0; i < ARRAY_SIZE(lbs_rates); i++) {
1645 if (priv->cur_rate == lbs_rates[i].hw_value) {
1646 sinfo->txrate.legacy = lbs_rates[i].bitrate;
1647 sinfo->filled |= STATION_INFO_TX_BITRATE;
1648 break;
1649 }
1650 }
1651
1652 return 0;
1653}
1654
1655
1656
1657
1658
1659
1660
1661
1662static int lbs_change_intf(struct wiphy *wiphy, struct net_device *dev,
1663 enum nl80211_iftype type, u32 *flags,
1664 struct vif_params *params)
1665{
1666 struct lbs_private *priv = wiphy_priv(wiphy);
1667 int ret = 0;
1668
1669 if (dev == priv->mesh_dev)
1670 return -EOPNOTSUPP;
1671
1672 switch (type) {
1673 case NL80211_IFTYPE_MONITOR:
1674 case NL80211_IFTYPE_STATION:
1675 case NL80211_IFTYPE_ADHOC:
1676 break;
1677 default:
1678 return -EOPNOTSUPP;
1679 }
1680
1681 lbs_deb_enter(LBS_DEB_CFG80211);
1682
1683 if (priv->iface_running)
1684 ret = lbs_set_iface_type(priv, type);
1685
1686 if (!ret)
1687 priv->wdev->iftype = type;
1688
1689 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
1690 return ret;
1691}
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704#define CAPINFO_MASK (~(0xda00))
1705
1706
1707static void lbs_join_post(struct lbs_private *priv,
1708 struct cfg80211_ibss_params *params,
1709 u8 *bssid, u16 capability)
1710{
1711 u8 fake_ie[2 + IEEE80211_MAX_SSID_LEN +
1712 2 + 4 +
1713 2 + 1 +
1714 2 + 2 +
1715 2 + 8];
1716 u8 *fake = fake_ie;
1717 struct cfg80211_bss *bss;
1718
1719 lbs_deb_enter(LBS_DEB_CFG80211);
1720
1721
1722
1723
1724
1725
1726
1727 *fake++ = WLAN_EID_SSID;
1728 *fake++ = params->ssid_len;
1729 memcpy(fake, params->ssid, params->ssid_len);
1730 fake += params->ssid_len;
1731
1732 *fake++ = WLAN_EID_SUPP_RATES;
1733 *fake++ = 4;
1734 *fake++ = 0x82;
1735 *fake++ = 0x84;
1736 *fake++ = 0x8b;
1737 *fake++ = 0x96;
1738
1739 *fake++ = WLAN_EID_DS_PARAMS;
1740 *fake++ = 1;
1741 *fake++ = params->chandef.chan->hw_value;
1742
1743 *fake++ = WLAN_EID_IBSS_PARAMS;
1744 *fake++ = 2;
1745 *fake++ = 0;
1746 *fake++ = 0;
1747
1748
1749 *fake++ = WLAN_EID_EXT_SUPP_RATES;
1750 *fake++ = 8;
1751 *fake++ = 0x0c;
1752 *fake++ = 0x12;
1753 *fake++ = 0x18;
1754 *fake++ = 0x24;
1755 *fake++ = 0x30;
1756 *fake++ = 0x48;
1757 *fake++ = 0x60;
1758 *fake++ = 0x6c;
1759 lbs_deb_hex(LBS_DEB_CFG80211, "IE", fake_ie, fake - fake_ie);
1760
1761 bss = cfg80211_inform_bss(priv->wdev->wiphy,
1762 params->chandef.chan,
1763 bssid,
1764 0,
1765 capability,
1766 params->beacon_interval,
1767 fake_ie, fake - fake_ie,
1768 0, GFP_KERNEL);
1769 cfg80211_put_bss(priv->wdev->wiphy, bss);
1770
1771 memcpy(priv->wdev->ssid, params->ssid, params->ssid_len);
1772 priv->wdev->ssid_len = params->ssid_len;
1773
1774 cfg80211_ibss_joined(priv->dev, bssid, GFP_KERNEL);
1775
1776
1777 priv->connect_status = LBS_CONNECTED;
1778 netif_carrier_on(priv->dev);
1779 if (!priv->tx_pending_len)
1780 netif_wake_queue(priv->dev);
1781
1782 lbs_deb_leave(LBS_DEB_CFG80211);
1783}
1784
1785static int lbs_ibss_join_existing(struct lbs_private *priv,
1786 struct cfg80211_ibss_params *params,
1787 struct cfg80211_bss *bss)
1788{
1789 const u8 *rates_eid;
1790 struct cmd_ds_802_11_ad_hoc_join cmd;
1791 u8 preamble = RADIO_PREAMBLE_SHORT;
1792 int ret = 0;
1793
1794 lbs_deb_enter(LBS_DEB_CFG80211);
1795
1796
1797 ret = lbs_set_radio(priv, preamble, 1);
1798 if (ret)
1799 goto out;
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831 memset(&cmd, 0, sizeof(cmd));
1832 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1833
1834 memcpy(cmd.bss.bssid, bss->bssid, ETH_ALEN);
1835 memcpy(cmd.bss.ssid, params->ssid, params->ssid_len);
1836 cmd.bss.type = CMD_BSS_TYPE_IBSS;
1837 cmd.bss.beaconperiod = cpu_to_le16(params->beacon_interval);
1838 cmd.bss.ds.header.id = WLAN_EID_DS_PARAMS;
1839 cmd.bss.ds.header.len = 1;
1840 cmd.bss.ds.channel = params->chandef.chan->hw_value;
1841 cmd.bss.ibss.header.id = WLAN_EID_IBSS_PARAMS;
1842 cmd.bss.ibss.header.len = 2;
1843 cmd.bss.ibss.atimwindow = 0;
1844 cmd.bss.capability = cpu_to_le16(bss->capability & CAPINFO_MASK);
1845
1846
1847
1848 rcu_read_lock();
1849 rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES);
1850 if (!rates_eid) {
1851 lbs_add_rates(cmd.bss.rates);
1852 } else {
1853 int hw, i;
1854 u8 rates_max = rates_eid[1];
1855 u8 *rates = cmd.bss.rates;
1856 for (hw = 0; hw < ARRAY_SIZE(lbs_rates); hw++) {
1857 u8 hw_rate = lbs_rates[hw].bitrate / 5;
1858 for (i = 0; i < rates_max; i++) {
1859 if (hw_rate == (rates_eid[i+2] & 0x7f)) {
1860 u8 rate = rates_eid[i+2];
1861 if (rate == 0x02 || rate == 0x04 ||
1862 rate == 0x0b || rate == 0x16)
1863 rate |= 0x80;
1864 *rates++ = rate;
1865 }
1866 }
1867 }
1868 }
1869 rcu_read_unlock();
1870
1871
1872 if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) {
1873 cmd.failtimeout = cpu_to_le16(MRVDRV_ASSOCIATION_TIME_OUT);
1874 cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
1875 }
1876 ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_JOIN, &cmd);
1877 if (ret)
1878 goto out;
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889 lbs_join_post(priv, params, bss->bssid, bss->capability);
1890
1891 out:
1892 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
1893 return ret;
1894}
1895
1896
1897
1898static int lbs_ibss_start_new(struct lbs_private *priv,
1899 struct cfg80211_ibss_params *params)
1900{
1901 struct cmd_ds_802_11_ad_hoc_start cmd;
1902 struct cmd_ds_802_11_ad_hoc_result *resp =
1903 (struct cmd_ds_802_11_ad_hoc_result *) &cmd;
1904 u8 preamble = RADIO_PREAMBLE_SHORT;
1905 int ret = 0;
1906 u16 capability;
1907
1908 lbs_deb_enter(LBS_DEB_CFG80211);
1909
1910 ret = lbs_set_radio(priv, preamble, 1);
1911 if (ret)
1912 goto out;
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942 memset(&cmd, 0, sizeof(cmd));
1943 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1944 memcpy(cmd.ssid, params->ssid, params->ssid_len);
1945 cmd.bsstype = CMD_BSS_TYPE_IBSS;
1946 cmd.beaconperiod = cpu_to_le16(params->beacon_interval);
1947 cmd.ibss.header.id = WLAN_EID_IBSS_PARAMS;
1948 cmd.ibss.header.len = 2;
1949 cmd.ibss.atimwindow = 0;
1950 cmd.ds.header.id = WLAN_EID_DS_PARAMS;
1951 cmd.ds.header.len = 1;
1952 cmd.ds.channel = params->chandef.chan->hw_value;
1953
1954 if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8)
1955 cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
1956
1957 capability = WLAN_CAPABILITY_IBSS;
1958 cmd.capability = cpu_to_le16(capability);
1959 lbs_add_rates(cmd.rates);
1960
1961
1962 ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_START, &cmd);
1963 if (ret)
1964 goto out;
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976 lbs_join_post(priv, params, resp->bssid, capability);
1977
1978 out:
1979 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
1980 return ret;
1981}
1982
1983
1984static int lbs_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1985 struct cfg80211_ibss_params *params)
1986{
1987 struct lbs_private *priv = wiphy_priv(wiphy);
1988 int ret = 0;
1989 struct cfg80211_bss *bss;
1990 DECLARE_SSID_BUF(ssid_buf);
1991
1992 if (dev == priv->mesh_dev)
1993 return -EOPNOTSUPP;
1994
1995 lbs_deb_enter(LBS_DEB_CFG80211);
1996
1997 if (!params->chandef.chan) {
1998 ret = -ENOTSUPP;
1999 goto out;
2000 }
2001
2002 ret = lbs_set_channel(priv, params->chandef.chan->hw_value);
2003 if (ret)
2004 goto out;
2005
2006
2007
2008 bss = cfg80211_get_bss(wiphy, params->chandef.chan, params->bssid,
2009 params->ssid, params->ssid_len,
2010 WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS);
2011
2012 if (bss) {
2013 ret = lbs_ibss_join_existing(priv, params, bss);
2014 cfg80211_put_bss(wiphy, bss);
2015 } else
2016 ret = lbs_ibss_start_new(priv, params);
2017
2018
2019 out:
2020 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
2021 return ret;
2022}
2023
2024
2025static int lbs_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
2026{
2027 struct lbs_private *priv = wiphy_priv(wiphy);
2028 struct cmd_ds_802_11_ad_hoc_stop cmd;
2029 int ret = 0;
2030
2031 if (dev == priv->mesh_dev)
2032 return -EOPNOTSUPP;
2033
2034 lbs_deb_enter(LBS_DEB_CFG80211);
2035
2036 memset(&cmd, 0, sizeof(cmd));
2037 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
2038 ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_STOP, &cmd);
2039
2040
2041 lbs_mac_event_disconnected(priv);
2042
2043 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
2044 return ret;
2045}
2046
2047
2048
2049
2050
2051
2052
2053
2054static struct cfg80211_ops lbs_cfg80211_ops = {
2055 .set_monitor_channel = lbs_cfg_set_monitor_channel,
2056 .libertas_set_mesh_channel = lbs_cfg_set_mesh_channel,
2057 .scan = lbs_cfg_scan,
2058 .connect = lbs_cfg_connect,
2059 .disconnect = lbs_cfg_disconnect,
2060 .add_key = lbs_cfg_add_key,
2061 .del_key = lbs_cfg_del_key,
2062 .set_default_key = lbs_cfg_set_default_key,
2063 .get_station = lbs_cfg_get_station,
2064 .change_virtual_intf = lbs_change_intf,
2065 .join_ibss = lbs_join_ibss,
2066 .leave_ibss = lbs_leave_ibss,
2067};
2068
2069
2070
2071
2072
2073
2074
2075
2076struct wireless_dev *lbs_cfg_alloc(struct device *dev)
2077{
2078 int ret = 0;
2079 struct wireless_dev *wdev;
2080
2081 lbs_deb_enter(LBS_DEB_CFG80211);
2082
2083 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2084 if (!wdev)
2085 return ERR_PTR(-ENOMEM);
2086
2087 wdev->wiphy = wiphy_new(&lbs_cfg80211_ops, sizeof(struct lbs_private));
2088 if (!wdev->wiphy) {
2089 dev_err(dev, "cannot allocate wiphy\n");
2090 ret = -ENOMEM;
2091 goto err_wiphy_new;
2092 }
2093
2094 lbs_deb_leave(LBS_DEB_CFG80211);
2095 return wdev;
2096
2097 err_wiphy_new:
2098 kfree(wdev);
2099 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
2100 return ERR_PTR(ret);
2101}
2102
2103
2104static void lbs_cfg_set_regulatory_hint(struct lbs_private *priv)
2105{
2106 struct region_code_mapping {
2107 const char *cn;
2108 int code;
2109 };
2110
2111
2112 static const struct region_code_mapping regmap[] = {
2113 {"US ", 0x10},
2114 {"CA ", 0x20},
2115 {"EU ", 0x30},
2116 {"ES ", 0x31},
2117 {"FR ", 0x32},
2118 {"JP ", 0x40},
2119 };
2120 size_t i;
2121
2122 lbs_deb_enter(LBS_DEB_CFG80211);
2123
2124 for (i = 0; i < ARRAY_SIZE(regmap); i++)
2125 if (regmap[i].code == priv->regioncode) {
2126 regulatory_hint(priv->wdev->wiphy, regmap[i].cn);
2127 break;
2128 }
2129
2130 lbs_deb_leave(LBS_DEB_CFG80211);
2131}
2132
2133static void lbs_reg_notifier(struct wiphy *wiphy,
2134 struct regulatory_request *request)
2135{
2136 struct lbs_private *priv = wiphy_priv(wiphy);
2137
2138 lbs_deb_enter_args(LBS_DEB_CFG80211, "cfg80211 regulatory domain "
2139 "callback for domain %c%c\n", request->alpha2[0],
2140 request->alpha2[1]);
2141
2142 memcpy(priv->country_code, request->alpha2, sizeof(request->alpha2));
2143 if (lbs_iface_active(priv))
2144 lbs_set_11d_domain_info(priv);
2145
2146 lbs_deb_leave(LBS_DEB_CFG80211);
2147}
2148
2149
2150
2151
2152
2153
2154int lbs_cfg_register(struct lbs_private *priv)
2155{
2156 struct wireless_dev *wdev = priv->wdev;
2157 int ret;
2158
2159 lbs_deb_enter(LBS_DEB_CFG80211);
2160
2161 wdev->wiphy->max_scan_ssids = 1;
2162 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2163
2164 wdev->wiphy->interface_modes =
2165 BIT(NL80211_IFTYPE_STATION) |
2166 BIT(NL80211_IFTYPE_ADHOC);
2167 if (lbs_rtap_supported(priv))
2168 wdev->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
2169 if (lbs_mesh_activated(priv))
2170 wdev->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MESH_POINT);
2171
2172 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &lbs_band_2ghz;
2173
2174
2175
2176
2177
2178 wdev->wiphy->cipher_suites = cipher_suites;
2179 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
2180 wdev->wiphy->reg_notifier = lbs_reg_notifier;
2181
2182 ret = wiphy_register(wdev->wiphy);
2183 if (ret < 0)
2184 pr_err("cannot register wiphy device\n");
2185
2186 priv->wiphy_registered = true;
2187
2188 ret = register_netdev(priv->dev);
2189 if (ret)
2190 pr_err("cannot register network device\n");
2191
2192 INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker);
2193
2194 lbs_cfg_set_regulatory_hint(priv);
2195
2196 lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
2197 return ret;
2198}
2199
2200void lbs_scan_deinit(struct lbs_private *priv)
2201{
2202 lbs_deb_enter(LBS_DEB_CFG80211);
2203 cancel_delayed_work_sync(&priv->scan_work);
2204}
2205
2206
2207void lbs_cfg_free(struct lbs_private *priv)
2208{
2209 struct wireless_dev *wdev = priv->wdev;
2210
2211 lbs_deb_enter(LBS_DEB_CFG80211);
2212
2213 if (!wdev)
2214 return;
2215
2216 if (priv->wiphy_registered)
2217 wiphy_unregister(wdev->wiphy);
2218
2219 if (wdev->wiphy)
2220 wiphy_free(wdev->wiphy);
2221
2222 kfree(wdev);
2223}
2224