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