1#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
2
3#include <linux/delay.h>
4#include <linux/etherdevice.h>
5#include <linux/hardirq.h>
6#include <linux/netdevice.h>
7#include <linux/if_ether.h>
8#include <linux/if_arp.h>
9#include <linux/kthread.h>
10#include <linux/kfifo.h>
11#include <net/cfg80211.h>
12
13#include "mesh.h"
14#include "decl.h"
15#include "cmd.h"
16
17
18static int lbs_add_mesh(struct lbs_private *priv);
19
20
21
22
23
24static int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
25 struct cmd_ds_mesh_access *cmd)
26{
27 int ret;
28
29 lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
30
31 cmd->hdr.command = cpu_to_le16(CMD_MESH_ACCESS);
32 cmd->hdr.size = cpu_to_le16(sizeof(*cmd));
33 cmd->hdr.result = 0;
34
35 cmd->action = cpu_to_le16(cmd_action);
36
37 ret = lbs_cmd_with_response(priv, CMD_MESH_ACCESS, cmd);
38
39 lbs_deb_leave(LBS_DEB_CMD);
40 return ret;
41}
42
43static int __lbs_mesh_config_send(struct lbs_private *priv,
44 struct cmd_ds_mesh_config *cmd,
45 uint16_t action, uint16_t type)
46{
47 int ret;
48 u16 command = CMD_MESH_CONFIG_OLD;
49
50 lbs_deb_enter(LBS_DEB_CMD);
51
52
53
54
55
56 if (priv->mesh_tlv == TLV_TYPE_MESH_ID)
57 command = CMD_MESH_CONFIG |
58 (MESH_IFACE_ID << MESH_IFACE_BIT_OFFSET);
59
60 cmd->hdr.command = cpu_to_le16(command);
61 cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_mesh_config));
62 cmd->hdr.result = 0;
63
64 cmd->type = cpu_to_le16(type);
65 cmd->action = cpu_to_le16(action);
66
67 ret = lbs_cmd_with_response(priv, command, cmd);
68
69 lbs_deb_leave(LBS_DEB_CMD);
70 return ret;
71}
72
73static int lbs_mesh_config_send(struct lbs_private *priv,
74 struct cmd_ds_mesh_config *cmd,
75 uint16_t action, uint16_t type)
76{
77 int ret;
78
79 if (!(priv->fwcapinfo & FW_CAPINFO_PERSISTENT_CONFIG))
80 return -EOPNOTSUPP;
81
82 ret = __lbs_mesh_config_send(priv, cmd, action, type);
83 return ret;
84}
85
86
87
88
89
90
91static int lbs_mesh_config(struct lbs_private *priv, uint16_t action,
92 uint16_t chan)
93{
94 struct cmd_ds_mesh_config cmd;
95 struct mrvl_meshie *ie;
96 DECLARE_SSID_BUF(ssid);
97
98 memset(&cmd, 0, sizeof(cmd));
99 cmd.channel = cpu_to_le16(chan);
100 ie = (struct mrvl_meshie *)cmd.data;
101
102 switch (action) {
103 case CMD_ACT_MESH_CONFIG_START:
104 ie->id = WLAN_EID_VENDOR_SPECIFIC;
105 ie->val.oui[0] = 0x00;
106 ie->val.oui[1] = 0x50;
107 ie->val.oui[2] = 0x43;
108 ie->val.type = MARVELL_MESH_IE_TYPE;
109 ie->val.subtype = MARVELL_MESH_IE_SUBTYPE;
110 ie->val.version = MARVELL_MESH_IE_VERSION;
111 ie->val.active_protocol_id = MARVELL_MESH_PROTO_ID_HWMP;
112 ie->val.active_metric_id = MARVELL_MESH_METRIC_ID;
113 ie->val.mesh_capability = MARVELL_MESH_CAPABILITY;
114 ie->val.mesh_id_len = priv->mesh_ssid_len;
115 memcpy(ie->val.mesh_id, priv->mesh_ssid, priv->mesh_ssid_len);
116 ie->len = sizeof(struct mrvl_meshie_val) -
117 IEEE80211_MAX_SSID_LEN + priv->mesh_ssid_len;
118 cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie_val));
119 break;
120 case CMD_ACT_MESH_CONFIG_STOP:
121 break;
122 default:
123 return -1;
124 }
125 lbs_deb_cmd("mesh config action %d type %x channel %d SSID %s\n",
126 action, priv->mesh_tlv, chan,
127 print_ssid(ssid, priv->mesh_ssid, priv->mesh_ssid_len));
128
129 return __lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv);
130}
131
132int lbs_mesh_set_channel(struct lbs_private *priv, u8 channel)
133{
134 priv->mesh_channel = channel;
135 return lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, channel);
136}
137
138static uint16_t lbs_mesh_get_channel(struct lbs_private *priv)
139{
140 return priv->mesh_channel ?: 1;
141}
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157static ssize_t lbs_anycast_get(struct device *dev,
158 struct device_attribute *attr, char * buf)
159{
160 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
161 struct cmd_ds_mesh_access mesh_access;
162 int ret;
163
164 memset(&mesh_access, 0, sizeof(mesh_access));
165
166 ret = lbs_mesh_access(priv, CMD_ACT_MESH_GET_ANYCAST, &mesh_access);
167 if (ret)
168 return ret;
169
170 return snprintf(buf, 12, "0x%X\n", le32_to_cpu(mesh_access.data[0]));
171}
172
173
174
175
176
177
178
179
180static ssize_t lbs_anycast_set(struct device *dev,
181 struct device_attribute *attr, const char * buf, size_t count)
182{
183 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
184 struct cmd_ds_mesh_access mesh_access;
185 uint32_t datum;
186 int ret;
187
188 memset(&mesh_access, 0, sizeof(mesh_access));
189 sscanf(buf, "%x", &datum);
190 mesh_access.data[0] = cpu_to_le32(datum);
191
192 ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_ANYCAST, &mesh_access);
193 if (ret)
194 return ret;
195
196 return strlen(buf);
197}
198
199
200
201
202
203
204
205static ssize_t lbs_prb_rsp_limit_get(struct device *dev,
206 struct device_attribute *attr, char *buf)
207{
208 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
209 struct cmd_ds_mesh_access mesh_access;
210 int ret;
211 u32 retry_limit;
212
213 memset(&mesh_access, 0, sizeof(mesh_access));
214 mesh_access.data[0] = cpu_to_le32(CMD_ACT_GET);
215
216 ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT,
217 &mesh_access);
218 if (ret)
219 return ret;
220
221 retry_limit = le32_to_cpu(mesh_access.data[1]);
222 return snprintf(buf, 10, "%d\n", retry_limit);
223}
224
225
226
227
228
229
230
231
232static ssize_t lbs_prb_rsp_limit_set(struct device *dev,
233 struct device_attribute *attr, const char *buf, size_t count)
234{
235 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
236 struct cmd_ds_mesh_access mesh_access;
237 int ret;
238 unsigned long retry_limit;
239
240 memset(&mesh_access, 0, sizeof(mesh_access));
241 mesh_access.data[0] = cpu_to_le32(CMD_ACT_SET);
242
243 if (!strict_strtoul(buf, 10, &retry_limit))
244 return -ENOTSUPP;
245 if (retry_limit > 15)
246 return -ENOTSUPP;
247
248 mesh_access.data[1] = cpu_to_le32(retry_limit);
249
250 ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT,
251 &mesh_access);
252 if (ret)
253 return ret;
254
255 return strlen(buf);
256}
257
258
259
260
261
262
263
264static ssize_t lbs_mesh_get(struct device *dev,
265 struct device_attribute *attr, char * buf)
266{
267 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
268 return snprintf(buf, 5, "0x%X\n", !!priv->mesh_dev);
269}
270
271
272
273
274
275
276
277
278static ssize_t lbs_mesh_set(struct device *dev,
279 struct device_attribute *attr, const char * buf, size_t count)
280{
281 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
282 int enable;
283
284 sscanf(buf, "%x", &enable);
285 enable = !!enable;
286 if (enable == !!priv->mesh_dev)
287 return count;
288
289 if (enable)
290 lbs_add_mesh(priv);
291 else
292 lbs_remove_mesh(priv);
293
294 return count;
295}
296
297
298
299
300
301static DEVICE_ATTR(lbs_mesh, 0644, lbs_mesh_get, lbs_mesh_set);
302
303
304
305
306
307static DEVICE_ATTR(anycast_mask, 0644, lbs_anycast_get, lbs_anycast_set);
308
309
310
311
312
313static DEVICE_ATTR(prb_rsp_limit, 0644, lbs_prb_rsp_limit_get,
314 lbs_prb_rsp_limit_set);
315
316static struct attribute *lbs_mesh_sysfs_entries[] = {
317 &dev_attr_anycast_mask.attr,
318 &dev_attr_prb_rsp_limit.attr,
319 NULL,
320};
321
322static const struct attribute_group lbs_mesh_attr_group = {
323 .attrs = lbs_mesh_sysfs_entries,
324};
325
326
327
328
329
330
331static int mesh_get_default_parameters(struct device *dev,
332 struct mrvl_mesh_defaults *defs)
333{
334 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
335 struct cmd_ds_mesh_config cmd;
336 int ret;
337
338 memset(&cmd, 0, sizeof(struct cmd_ds_mesh_config));
339 ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_GET,
340 CMD_TYPE_MESH_GET_DEFAULTS);
341
342 if (ret)
343 return -EOPNOTSUPP;
344
345 memcpy(defs, &cmd.data[0], sizeof(struct mrvl_mesh_defaults));
346
347 return 0;
348}
349
350
351
352
353
354
355
356static ssize_t bootflag_get(struct device *dev,
357 struct device_attribute *attr, char *buf)
358{
359 struct mrvl_mesh_defaults defs;
360 int ret;
361
362 ret = mesh_get_default_parameters(dev, &defs);
363
364 if (ret)
365 return ret;
366
367 return snprintf(buf, 12, "%d\n", le32_to_cpu(defs.bootflag));
368}
369
370
371
372
373
374
375
376
377static ssize_t bootflag_set(struct device *dev, struct device_attribute *attr,
378 const char *buf, size_t count)
379{
380 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
381 struct cmd_ds_mesh_config cmd;
382 uint32_t datum;
383 int ret;
384
385 memset(&cmd, 0, sizeof(cmd));
386 ret = sscanf(buf, "%d", &datum);
387 if ((ret != 1) || (datum > 1))
388 return -EINVAL;
389
390 *((__le32 *)&cmd.data[0]) = cpu_to_le32(!!datum);
391 cmd.length = cpu_to_le16(sizeof(uint32_t));
392 ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
393 CMD_TYPE_MESH_SET_BOOTFLAG);
394 if (ret)
395 return ret;
396
397 return strlen(buf);
398}
399
400
401
402
403
404
405
406static ssize_t boottime_get(struct device *dev,
407 struct device_attribute *attr, char *buf)
408{
409 struct mrvl_mesh_defaults defs;
410 int ret;
411
412 ret = mesh_get_default_parameters(dev, &defs);
413
414 if (ret)
415 return ret;
416
417 return snprintf(buf, 12, "%d\n", defs.boottime);
418}
419
420
421
422
423
424
425
426
427static ssize_t boottime_set(struct device *dev,
428 struct device_attribute *attr, const char *buf, size_t count)
429{
430 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
431 struct cmd_ds_mesh_config cmd;
432 uint32_t datum;
433 int ret;
434
435 memset(&cmd, 0, sizeof(cmd));
436 ret = sscanf(buf, "%d", &datum);
437 if ((ret != 1) || (datum > 255))
438 return -EINVAL;
439
440
441
442
443
444
445
446
447
448 datum = (datum < 20) ? 20 : datum;
449 cmd.data[0] = datum;
450 cmd.length = cpu_to_le16(sizeof(uint8_t));
451 ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
452 CMD_TYPE_MESH_SET_BOOTTIME);
453 if (ret)
454 return ret;
455
456 return strlen(buf);
457}
458
459
460
461
462
463
464
465static ssize_t channel_get(struct device *dev,
466 struct device_attribute *attr, char *buf)
467{
468 struct mrvl_mesh_defaults defs;
469 int ret;
470
471 ret = mesh_get_default_parameters(dev, &defs);
472
473 if (ret)
474 return ret;
475
476 return snprintf(buf, 12, "%d\n", le16_to_cpu(defs.channel));
477}
478
479
480
481
482
483
484
485
486static ssize_t channel_set(struct device *dev, struct device_attribute *attr,
487 const char *buf, size_t count)
488{
489 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
490 struct cmd_ds_mesh_config cmd;
491 uint32_t datum;
492 int ret;
493
494 memset(&cmd, 0, sizeof(cmd));
495 ret = sscanf(buf, "%d", &datum);
496 if (ret != 1 || datum < 1 || datum > 11)
497 return -EINVAL;
498
499 *((__le16 *)&cmd.data[0]) = cpu_to_le16(datum);
500 cmd.length = cpu_to_le16(sizeof(uint16_t));
501 ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
502 CMD_TYPE_MESH_SET_DEF_CHANNEL);
503 if (ret)
504 return ret;
505
506 return strlen(buf);
507}
508
509
510
511
512
513
514
515static ssize_t mesh_id_get(struct device *dev, struct device_attribute *attr,
516 char *buf)
517{
518 struct mrvl_mesh_defaults defs;
519 int ret;
520
521 ret = mesh_get_default_parameters(dev, &defs);
522
523 if (ret)
524 return ret;
525
526 if (defs.meshie.val.mesh_id_len > IEEE80211_MAX_SSID_LEN) {
527 dev_err(dev, "inconsistent mesh ID length\n");
528 defs.meshie.val.mesh_id_len = IEEE80211_MAX_SSID_LEN;
529 }
530
531 memcpy(buf, defs.meshie.val.mesh_id, defs.meshie.val.mesh_id_len);
532 buf[defs.meshie.val.mesh_id_len] = '\n';
533 buf[defs.meshie.val.mesh_id_len + 1] = '\0';
534
535 return defs.meshie.val.mesh_id_len + 1;
536}
537
538
539
540
541
542
543
544
545static ssize_t mesh_id_set(struct device *dev, struct device_attribute *attr,
546 const char *buf, size_t count)
547{
548 struct cmd_ds_mesh_config cmd;
549 struct mrvl_mesh_defaults defs;
550 struct mrvl_meshie *ie;
551 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
552 int len;
553 int ret;
554
555 if (count < 2 || count > IEEE80211_MAX_SSID_LEN + 1)
556 return -EINVAL;
557
558 memset(&cmd, 0, sizeof(struct cmd_ds_mesh_config));
559 ie = (struct mrvl_meshie *) &cmd.data[0];
560
561
562 ret = mesh_get_default_parameters(dev, &defs);
563
564 cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
565
566
567 memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
568
569 len = count - 1;
570 memcpy(ie->val.mesh_id, buf, len);
571
572 ie->val.mesh_id_len = len;
573
574 ie->len = sizeof(struct mrvl_meshie_val) - IEEE80211_MAX_SSID_LEN + len;
575
576 ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
577 CMD_TYPE_MESH_SET_MESH_IE);
578 if (ret)
579 return ret;
580
581 return strlen(buf);
582}
583
584
585
586
587
588
589
590static ssize_t protocol_id_get(struct device *dev,
591 struct device_attribute *attr, char *buf)
592{
593 struct mrvl_mesh_defaults defs;
594 int ret;
595
596 ret = mesh_get_default_parameters(dev, &defs);
597
598 if (ret)
599 return ret;
600
601 return snprintf(buf, 5, "%d\n", defs.meshie.val.active_protocol_id);
602}
603
604
605
606
607
608
609
610
611static ssize_t protocol_id_set(struct device *dev,
612 struct device_attribute *attr, const char *buf, size_t count)
613{
614 struct cmd_ds_mesh_config cmd;
615 struct mrvl_mesh_defaults defs;
616 struct mrvl_meshie *ie;
617 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
618 uint32_t datum;
619 int ret;
620
621 memset(&cmd, 0, sizeof(cmd));
622 ret = sscanf(buf, "%d", &datum);
623 if ((ret != 1) || (datum > 255))
624 return -EINVAL;
625
626
627 ret = mesh_get_default_parameters(dev, &defs);
628
629 cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
630
631
632 ie = (struct mrvl_meshie *) &cmd.data[0];
633 memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
634
635 ie->val.active_protocol_id = datum;
636
637 ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
638 CMD_TYPE_MESH_SET_MESH_IE);
639 if (ret)
640 return ret;
641
642 return strlen(buf);
643}
644
645
646
647
648
649
650
651static ssize_t metric_id_get(struct device *dev,
652 struct device_attribute *attr, char *buf)
653{
654 struct mrvl_mesh_defaults defs;
655 int ret;
656
657 ret = mesh_get_default_parameters(dev, &defs);
658
659 if (ret)
660 return ret;
661
662 return snprintf(buf, 5, "%d\n", defs.meshie.val.active_metric_id);
663}
664
665
666
667
668
669
670
671
672static ssize_t metric_id_set(struct device *dev, struct device_attribute *attr,
673 const char *buf, size_t count)
674{
675 struct cmd_ds_mesh_config cmd;
676 struct mrvl_mesh_defaults defs;
677 struct mrvl_meshie *ie;
678 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
679 uint32_t datum;
680 int ret;
681
682 memset(&cmd, 0, sizeof(cmd));
683 ret = sscanf(buf, "%d", &datum);
684 if ((ret != 1) || (datum > 255))
685 return -EINVAL;
686
687
688 ret = mesh_get_default_parameters(dev, &defs);
689
690 cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
691
692
693 ie = (struct mrvl_meshie *) &cmd.data[0];
694 memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
695
696 ie->val.active_metric_id = datum;
697
698 ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
699 CMD_TYPE_MESH_SET_MESH_IE);
700 if (ret)
701 return ret;
702
703 return strlen(buf);
704}
705
706
707
708
709
710
711
712static ssize_t capability_get(struct device *dev,
713 struct device_attribute *attr, char *buf)
714{
715 struct mrvl_mesh_defaults defs;
716 int ret;
717
718 ret = mesh_get_default_parameters(dev, &defs);
719
720 if (ret)
721 return ret;
722
723 return snprintf(buf, 5, "%d\n", defs.meshie.val.mesh_capability);
724}
725
726
727
728
729
730
731
732
733static ssize_t capability_set(struct device *dev, struct device_attribute *attr,
734 const char *buf, size_t count)
735{
736 struct cmd_ds_mesh_config cmd;
737 struct mrvl_mesh_defaults defs;
738 struct mrvl_meshie *ie;
739 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
740 uint32_t datum;
741 int ret;
742
743 memset(&cmd, 0, sizeof(cmd));
744 ret = sscanf(buf, "%d", &datum);
745 if ((ret != 1) || (datum > 255))
746 return -EINVAL;
747
748
749 ret = mesh_get_default_parameters(dev, &defs);
750
751 cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
752
753
754 ie = (struct mrvl_meshie *) &cmd.data[0];
755 memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
756
757 ie->val.mesh_capability = datum;
758
759 ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
760 CMD_TYPE_MESH_SET_MESH_IE);
761 if (ret)
762 return ret;
763
764 return strlen(buf);
765}
766
767
768static DEVICE_ATTR(bootflag, 0644, bootflag_get, bootflag_set);
769static DEVICE_ATTR(boottime, 0644, boottime_get, boottime_set);
770static DEVICE_ATTR(channel, 0644, channel_get, channel_set);
771static DEVICE_ATTR(mesh_id, 0644, mesh_id_get, mesh_id_set);
772static DEVICE_ATTR(protocol_id, 0644, protocol_id_get, protocol_id_set);
773static DEVICE_ATTR(metric_id, 0644, metric_id_get, metric_id_set);
774static DEVICE_ATTR(capability, 0644, capability_get, capability_set);
775
776static struct attribute *boot_opts_attrs[] = {
777 &dev_attr_bootflag.attr,
778 &dev_attr_boottime.attr,
779 &dev_attr_channel.attr,
780 NULL
781};
782
783static const struct attribute_group boot_opts_group = {
784 .name = "boot_options",
785 .attrs = boot_opts_attrs,
786};
787
788static struct attribute *mesh_ie_attrs[] = {
789 &dev_attr_mesh_id.attr,
790 &dev_attr_protocol_id.attr,
791 &dev_attr_metric_id.attr,
792 &dev_attr_capability.attr,
793 NULL
794};
795
796static const struct attribute_group mesh_ie_group = {
797 .name = "mesh_ie",
798 .attrs = mesh_ie_attrs,
799};
800
801static void lbs_persist_config_init(struct net_device *dev)
802{
803 int ret;
804 ret = sysfs_create_group(&(dev->dev.kobj), &boot_opts_group);
805 ret = sysfs_create_group(&(dev->dev.kobj), &mesh_ie_group);
806}
807
808static void lbs_persist_config_remove(struct net_device *dev)
809{
810 sysfs_remove_group(&(dev->dev.kobj), &boot_opts_group);
811 sysfs_remove_group(&(dev->dev.kobj), &mesh_ie_group);
812}
813
814
815
816
817
818
819
820
821
822
823int lbs_init_mesh(struct lbs_private *priv)
824{
825 int ret = 0;
826
827 lbs_deb_enter(LBS_DEB_MESH);
828
829
830
831
832
833
834 if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5) {
835
836
837
838
839
840
841
842
843
844
845
846
847
848 priv->mesh_tlv = TLV_TYPE_OLD_MESH_ID;
849 if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 1)) {
850 priv->mesh_tlv = TLV_TYPE_MESH_ID;
851 if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 1))
852 priv->mesh_tlv = 0;
853 }
854 } else
855 if ((MRVL_FW_MAJOR_REV(priv->fwrelease) >= MRVL_FW_V10) &&
856 (priv->fwcapinfo & MESH_CAPINFO_ENABLE_MASK)) {
857
858
859
860 priv->mesh_tlv = TLV_TYPE_MESH_ID;
861 if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 1))
862 priv->mesh_tlv = 0;
863 }
864
865
866 lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_STOP, 1);
867
868 if (priv->mesh_tlv) {
869 sprintf(priv->mesh_ssid, "mesh");
870 priv->mesh_ssid_len = 4;
871 ret = 1;
872 }
873
874 lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
875 return ret;
876}
877
878void lbs_start_mesh(struct lbs_private *priv)
879{
880 lbs_add_mesh(priv);
881
882 if (device_create_file(&priv->dev->dev, &dev_attr_lbs_mesh))
883 netdev_err(priv->dev, "cannot register lbs_mesh attribute\n");
884}
885
886int lbs_deinit_mesh(struct lbs_private *priv)
887{
888 struct net_device *dev = priv->dev;
889 int ret = 0;
890
891 lbs_deb_enter(LBS_DEB_MESH);
892
893 if (priv->mesh_tlv) {
894 device_remove_file(&dev->dev, &dev_attr_lbs_mesh);
895 ret = 1;
896 }
897
898 lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
899 return ret;
900}
901
902
903
904
905
906
907
908
909static int lbs_mesh_stop(struct net_device *dev)
910{
911 struct lbs_private *priv = dev->ml_priv;
912
913 lbs_deb_enter(LBS_DEB_MESH);
914 lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_STOP,
915 lbs_mesh_get_channel(priv));
916
917 spin_lock_irq(&priv->driver_lock);
918
919 netif_stop_queue(dev);
920 netif_carrier_off(dev);
921
922 spin_unlock_irq(&priv->driver_lock);
923
924 lbs_update_mcast(priv);
925 if (!lbs_iface_active(priv))
926 lbs_stop_iface(priv);
927
928 lbs_deb_leave(LBS_DEB_MESH);
929 return 0;
930}
931
932
933
934
935
936
937
938static int lbs_mesh_dev_open(struct net_device *dev)
939{
940 struct lbs_private *priv = dev->ml_priv;
941 int ret = 0;
942
943 lbs_deb_enter(LBS_DEB_NET);
944 if (!priv->iface_running) {
945 ret = lbs_start_iface(priv);
946 if (ret)
947 goto out;
948 }
949
950 spin_lock_irq(&priv->driver_lock);
951
952 if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) {
953 ret = -EBUSY;
954 spin_unlock_irq(&priv->driver_lock);
955 goto out;
956 }
957
958 netif_carrier_on(dev);
959
960 if (!priv->tx_pending_len)
961 netif_wake_queue(dev);
962
963 spin_unlock_irq(&priv->driver_lock);
964
965 ret = lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
966 lbs_mesh_get_channel(priv));
967
968out:
969 lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
970 return ret;
971}
972
973static const struct net_device_ops mesh_netdev_ops = {
974 .ndo_open = lbs_mesh_dev_open,
975 .ndo_stop = lbs_mesh_stop,
976 .ndo_start_xmit = lbs_hard_start_xmit,
977 .ndo_set_mac_address = lbs_set_mac_address,
978 .ndo_set_rx_mode = lbs_set_multicast_list,
979};
980
981
982
983
984
985
986
987static int lbs_add_mesh(struct lbs_private *priv)
988{
989 struct net_device *mesh_dev = NULL;
990 struct wireless_dev *mesh_wdev;
991 int ret = 0;
992
993 lbs_deb_enter(LBS_DEB_MESH);
994
995
996 mesh_wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
997 if (!mesh_wdev) {
998 lbs_deb_mesh("init mshX wireless device failed\n");
999 ret = -ENOMEM;
1000 goto done;
1001 }
1002
1003 mesh_dev = alloc_netdev(0, "msh%d", ether_setup);
1004 if (!mesh_dev) {
1005 lbs_deb_mesh("init mshX device failed\n");
1006 ret = -ENOMEM;
1007 goto err_free_wdev;
1008 }
1009
1010 mesh_wdev->iftype = NL80211_IFTYPE_MESH_POINT;
1011 mesh_wdev->wiphy = priv->wdev->wiphy;
1012 mesh_wdev->netdev = mesh_dev;
1013
1014 mesh_dev->ml_priv = priv;
1015 mesh_dev->ieee80211_ptr = mesh_wdev;
1016 priv->mesh_dev = mesh_dev;
1017
1018 mesh_dev->netdev_ops = &mesh_netdev_ops;
1019 mesh_dev->ethtool_ops = &lbs_ethtool_ops;
1020 memcpy(mesh_dev->dev_addr, priv->dev->dev_addr, ETH_ALEN);
1021
1022 SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent);
1023
1024 mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
1025
1026 ret = register_netdev(mesh_dev);
1027 if (ret) {
1028 pr_err("cannot register mshX virtual interface\n");
1029 goto err_free_netdev;
1030 }
1031
1032 ret = sysfs_create_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
1033 if (ret)
1034 goto err_unregister;
1035
1036 lbs_persist_config_init(mesh_dev);
1037
1038
1039 ret = 0;
1040 goto done;
1041
1042err_unregister:
1043 unregister_netdev(mesh_dev);
1044
1045err_free_netdev:
1046 free_netdev(mesh_dev);
1047
1048err_free_wdev:
1049 kfree(mesh_wdev);
1050
1051done:
1052 lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
1053 return ret;
1054}
1055
1056void lbs_remove_mesh(struct lbs_private *priv)
1057{
1058 struct net_device *mesh_dev;
1059
1060 mesh_dev = priv->mesh_dev;
1061 if (!mesh_dev)
1062 return;
1063
1064 lbs_deb_enter(LBS_DEB_MESH);
1065 netif_stop_queue(mesh_dev);
1066 netif_carrier_off(mesh_dev);
1067 sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
1068 lbs_persist_config_remove(mesh_dev);
1069 unregister_netdev(mesh_dev);
1070 priv->mesh_dev = NULL;
1071 kfree(mesh_dev->ieee80211_ptr);
1072 free_netdev(mesh_dev);
1073 lbs_deb_leave(LBS_DEB_MESH);
1074}
1075
1076
1077
1078
1079
1080struct net_device *lbs_mesh_set_dev(struct lbs_private *priv,
1081 struct net_device *dev, struct rxpd *rxpd)
1082{
1083 if (priv->mesh_dev) {
1084 if (priv->mesh_tlv == TLV_TYPE_OLD_MESH_ID) {
1085 if (rxpd->rx_control & RxPD_MESH_FRAME)
1086 dev = priv->mesh_dev;
1087 } else if (priv->mesh_tlv == TLV_TYPE_MESH_ID) {
1088 if (rxpd->u.bss.bss_num == MESH_IFACE_ID)
1089 dev = priv->mesh_dev;
1090 }
1091 }
1092 return dev;
1093}
1094
1095
1096void lbs_mesh_set_txpd(struct lbs_private *priv,
1097 struct net_device *dev, struct txpd *txpd)
1098{
1099 if (dev == priv->mesh_dev) {
1100 if (priv->mesh_tlv == TLV_TYPE_OLD_MESH_ID)
1101 txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME);
1102 else if (priv->mesh_tlv == TLV_TYPE_MESH_ID)
1103 txpd->u.bss.bss_num = MESH_IFACE_ID;
1104 }
1105}
1106
1107
1108
1109
1110
1111
1112static const char * const mesh_stat_strings[] = {
1113 "drop_duplicate_bcast",
1114 "drop_ttl_zero",
1115 "drop_no_fwd_route",
1116 "drop_no_buffers",
1117 "fwded_unicast_cnt",
1118 "fwded_bcast_cnt",
1119 "drop_blind_table",
1120 "tx_failed_cnt"
1121};
1122
1123void lbs_mesh_ethtool_get_stats(struct net_device *dev,
1124 struct ethtool_stats *stats, uint64_t *data)
1125{
1126 struct lbs_private *priv = dev->ml_priv;
1127 struct cmd_ds_mesh_access mesh_access;
1128 int ret;
1129
1130 lbs_deb_enter(LBS_DEB_ETHTOOL);
1131
1132
1133 ret = lbs_mesh_access(priv, CMD_ACT_MESH_GET_STATS, &mesh_access);
1134
1135 if (ret) {
1136 memset(data, 0, MESH_STATS_NUM*(sizeof(uint64_t)));
1137 return;
1138 }
1139
1140 priv->mstats.fwd_drop_rbt = le32_to_cpu(mesh_access.data[0]);
1141 priv->mstats.fwd_drop_ttl = le32_to_cpu(mesh_access.data[1]);
1142 priv->mstats.fwd_drop_noroute = le32_to_cpu(mesh_access.data[2]);
1143 priv->mstats.fwd_drop_nobuf = le32_to_cpu(mesh_access.data[3]);
1144 priv->mstats.fwd_unicast_cnt = le32_to_cpu(mesh_access.data[4]);
1145 priv->mstats.fwd_bcast_cnt = le32_to_cpu(mesh_access.data[5]);
1146 priv->mstats.drop_blind = le32_to_cpu(mesh_access.data[6]);
1147 priv->mstats.tx_failed_cnt = le32_to_cpu(mesh_access.data[7]);
1148
1149 data[0] = priv->mstats.fwd_drop_rbt;
1150 data[1] = priv->mstats.fwd_drop_ttl;
1151 data[2] = priv->mstats.fwd_drop_noroute;
1152 data[3] = priv->mstats.fwd_drop_nobuf;
1153 data[4] = priv->mstats.fwd_unicast_cnt;
1154 data[5] = priv->mstats.fwd_bcast_cnt;
1155 data[6] = priv->mstats.drop_blind;
1156 data[7] = priv->mstats.tx_failed_cnt;
1157
1158 lbs_deb_enter(LBS_DEB_ETHTOOL);
1159}
1160
1161int lbs_mesh_ethtool_get_sset_count(struct net_device *dev, int sset)
1162{
1163 struct lbs_private *priv = dev->ml_priv;
1164
1165 if (sset == ETH_SS_STATS && dev == priv->mesh_dev)
1166 return MESH_STATS_NUM;
1167
1168 return -EOPNOTSUPP;
1169}
1170
1171void lbs_mesh_ethtool_get_strings(struct net_device *dev,
1172 uint32_t stringset, uint8_t *s)
1173{
1174 int i;
1175
1176 lbs_deb_enter(LBS_DEB_ETHTOOL);
1177
1178 switch (stringset) {
1179 case ETH_SS_STATS:
1180 for (i = 0; i < MESH_STATS_NUM; i++) {
1181 memcpy(s + i * ETH_GSTRING_LEN,
1182 mesh_stat_strings[i],
1183 ETH_GSTRING_LEN);
1184 }
1185 break;
1186 }
1187 lbs_deb_enter(LBS_DEB_ETHTOOL);
1188}
1189