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