0001
0002 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0003
0004 #include <linux/delay.h>
0005 #include <linux/etherdevice.h>
0006 #include <linux/hardirq.h>
0007 #include <linux/netdevice.h>
0008 #include <linux/if_ether.h>
0009 #include <linux/if_arp.h>
0010 #include <linux/kthread.h>
0011 #include <linux/kfifo.h>
0012 #include <net/cfg80211.h>
0013
0014 #include "mesh.h"
0015 #include "decl.h"
0016 #include "cmd.h"
0017
0018
0019 static int lbs_add_mesh(struct lbs_private *priv);
0020
0021
0022
0023
0024
0025 static int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
0026 struct cmd_ds_mesh_access *cmd)
0027 {
0028 int ret;
0029
0030 cmd->hdr.command = cpu_to_le16(CMD_MESH_ACCESS);
0031 cmd->hdr.size = cpu_to_le16(sizeof(*cmd));
0032 cmd->hdr.result = 0;
0033
0034 cmd->action = cpu_to_le16(cmd_action);
0035
0036 ret = lbs_cmd_with_response(priv, CMD_MESH_ACCESS, cmd);
0037
0038 return ret;
0039 }
0040
0041 static int __lbs_mesh_config_send(struct lbs_private *priv,
0042 struct cmd_ds_mesh_config *cmd,
0043 uint16_t action, uint16_t type)
0044 {
0045 int ret;
0046 u16 command = CMD_MESH_CONFIG_OLD;
0047
0048
0049
0050
0051
0052 if (priv->mesh_tlv == TLV_TYPE_MESH_ID)
0053 command = CMD_MESH_CONFIG |
0054 (MESH_IFACE_ID << MESH_IFACE_BIT_OFFSET);
0055
0056 cmd->hdr.command = cpu_to_le16(command);
0057 cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_mesh_config));
0058 cmd->hdr.result = 0;
0059
0060 cmd->type = cpu_to_le16(type);
0061 cmd->action = cpu_to_le16(action);
0062
0063 ret = lbs_cmd_with_response(priv, command, cmd);
0064
0065 return ret;
0066 }
0067
0068 static int lbs_mesh_config_send(struct lbs_private *priv,
0069 struct cmd_ds_mesh_config *cmd,
0070 uint16_t action, uint16_t type)
0071 {
0072 int ret;
0073
0074 if (!(priv->fwcapinfo & FW_CAPINFO_PERSISTENT_CONFIG))
0075 return -EOPNOTSUPP;
0076
0077 ret = __lbs_mesh_config_send(priv, cmd, action, type);
0078 return ret;
0079 }
0080
0081
0082
0083
0084
0085
0086 static int lbs_mesh_config(struct lbs_private *priv, uint16_t action,
0087 uint16_t chan)
0088 {
0089 struct wireless_dev *mesh_wdev;
0090 struct cmd_ds_mesh_config cmd;
0091 struct mrvl_meshie *ie;
0092
0093 memset(&cmd, 0, sizeof(cmd));
0094 cmd.channel = cpu_to_le16(chan);
0095 ie = (struct mrvl_meshie *)cmd.data;
0096
0097 switch (action) {
0098 case CMD_ACT_MESH_CONFIG_START:
0099 ie->id = WLAN_EID_VENDOR_SPECIFIC;
0100 ie->val.oui[0] = 0x00;
0101 ie->val.oui[1] = 0x50;
0102 ie->val.oui[2] = 0x43;
0103 ie->val.type = MARVELL_MESH_IE_TYPE;
0104 ie->val.subtype = MARVELL_MESH_IE_SUBTYPE;
0105 ie->val.version = MARVELL_MESH_IE_VERSION;
0106 ie->val.active_protocol_id = MARVELL_MESH_PROTO_ID_HWMP;
0107 ie->val.active_metric_id = MARVELL_MESH_METRIC_ID;
0108 ie->val.mesh_capability = MARVELL_MESH_CAPABILITY;
0109
0110 if (priv->mesh_dev) {
0111 mesh_wdev = priv->mesh_dev->ieee80211_ptr;
0112 ie->val.mesh_id_len = mesh_wdev->u.mesh.id_up_len;
0113 memcpy(ie->val.mesh_id, mesh_wdev->u.mesh.id,
0114 mesh_wdev->u.mesh.id_up_len);
0115 }
0116
0117 ie->len = sizeof(struct mrvl_meshie_val) -
0118 IEEE80211_MAX_SSID_LEN + ie->val.mesh_id_len;
0119
0120 cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie_val));
0121 break;
0122 case CMD_ACT_MESH_CONFIG_STOP:
0123 break;
0124 default:
0125 return -1;
0126 }
0127 lbs_deb_cmd("mesh config action %d type %x channel %d SSID %*pE\n",
0128 action, priv->mesh_tlv, chan, ie->val.mesh_id_len,
0129 ie->val.mesh_id);
0130
0131 return __lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv);
0132 }
0133
0134 int lbs_mesh_set_channel(struct lbs_private *priv, u8 channel)
0135 {
0136 priv->mesh_channel = channel;
0137 return lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, channel);
0138 }
0139
0140 static uint16_t lbs_mesh_get_channel(struct lbs_private *priv)
0141 {
0142 return priv->mesh_channel ?: 1;
0143 }
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159 static ssize_t anycast_mask_show(struct device *dev,
0160 struct device_attribute *attr, char *buf)
0161 {
0162 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
0163 struct cmd_ds_mesh_access mesh_access;
0164 int ret;
0165
0166 memset(&mesh_access, 0, sizeof(mesh_access));
0167
0168 ret = lbs_mesh_access(priv, CMD_ACT_MESH_GET_ANYCAST, &mesh_access);
0169 if (ret)
0170 return ret;
0171
0172 return sysfs_emit(buf, "0x%X\n", le32_to_cpu(mesh_access.data[0]));
0173 }
0174
0175
0176
0177
0178
0179
0180
0181
0182 static ssize_t anycast_mask_store(struct device *dev,
0183 struct device_attribute *attr,
0184 const char *buf, size_t count)
0185 {
0186 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
0187 struct cmd_ds_mesh_access mesh_access;
0188 uint32_t datum;
0189 int ret;
0190
0191 memset(&mesh_access, 0, sizeof(mesh_access));
0192 sscanf(buf, "%x", &datum);
0193 mesh_access.data[0] = cpu_to_le32(datum);
0194
0195 ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_ANYCAST, &mesh_access);
0196 if (ret)
0197 return ret;
0198
0199 return strlen(buf);
0200 }
0201
0202
0203
0204
0205
0206
0207
0208 static ssize_t prb_rsp_limit_show(struct device *dev,
0209 struct device_attribute *attr, char *buf)
0210 {
0211 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
0212 struct cmd_ds_mesh_access mesh_access;
0213 int ret;
0214 u32 retry_limit;
0215
0216 memset(&mesh_access, 0, sizeof(mesh_access));
0217 mesh_access.data[0] = cpu_to_le32(CMD_ACT_GET);
0218
0219 ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT,
0220 &mesh_access);
0221 if (ret)
0222 return ret;
0223
0224 retry_limit = le32_to_cpu(mesh_access.data[1]);
0225 return sysfs_emit(buf, "%d\n", retry_limit);
0226 }
0227
0228
0229
0230
0231
0232
0233
0234
0235 static ssize_t prb_rsp_limit_store(struct device *dev,
0236 struct device_attribute *attr,
0237 const char *buf, size_t count)
0238 {
0239 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
0240 struct cmd_ds_mesh_access mesh_access;
0241 int ret;
0242 unsigned long retry_limit;
0243
0244 memset(&mesh_access, 0, sizeof(mesh_access));
0245 mesh_access.data[0] = cpu_to_le32(CMD_ACT_SET);
0246
0247 ret = kstrtoul(buf, 10, &retry_limit);
0248 if (ret)
0249 return ret;
0250 if (retry_limit > 15)
0251 return -ENOTSUPP;
0252
0253 mesh_access.data[1] = cpu_to_le32(retry_limit);
0254
0255 ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT,
0256 &mesh_access);
0257 if (ret)
0258 return ret;
0259
0260 return strlen(buf);
0261 }
0262
0263
0264
0265
0266
0267
0268
0269 static ssize_t lbs_mesh_show(struct device *dev,
0270 struct device_attribute *attr, char *buf)
0271 {
0272 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
0273 return sysfs_emit(buf, "0x%X\n", !!priv->mesh_dev);
0274 }
0275
0276
0277
0278
0279
0280
0281
0282
0283 static ssize_t lbs_mesh_store(struct device *dev,
0284 struct device_attribute *attr,
0285 const char *buf, size_t count)
0286 {
0287 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
0288 int enable;
0289
0290 sscanf(buf, "%x", &enable);
0291 enable = !!enable;
0292 if (enable == !!priv->mesh_dev)
0293 return count;
0294
0295 if (enable)
0296 lbs_add_mesh(priv);
0297 else
0298 lbs_remove_mesh(priv);
0299
0300 return count;
0301 }
0302
0303
0304
0305
0306
0307 static DEVICE_ATTR_RW(lbs_mesh);
0308
0309
0310
0311
0312
0313 static DEVICE_ATTR_RW(anycast_mask);
0314
0315
0316
0317
0318
0319 static DEVICE_ATTR_RW(prb_rsp_limit);
0320
0321 static struct attribute *lbs_mesh_sysfs_entries[] = {
0322 &dev_attr_anycast_mask.attr,
0323 &dev_attr_prb_rsp_limit.attr,
0324 NULL,
0325 };
0326
0327 static const struct attribute_group lbs_mesh_attr_group = {
0328 .attrs = lbs_mesh_sysfs_entries,
0329 };
0330
0331
0332
0333
0334
0335
0336 static int mesh_get_default_parameters(struct device *dev,
0337 struct mrvl_mesh_defaults *defs)
0338 {
0339 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
0340 struct cmd_ds_mesh_config cmd;
0341 int ret;
0342
0343 memset(&cmd, 0, sizeof(struct cmd_ds_mesh_config));
0344 ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_GET,
0345 CMD_TYPE_MESH_GET_DEFAULTS);
0346
0347 if (ret)
0348 return -EOPNOTSUPP;
0349
0350 memcpy(defs, &cmd.data[0], sizeof(struct mrvl_mesh_defaults));
0351
0352 return 0;
0353 }
0354
0355
0356
0357
0358
0359
0360
0361 static ssize_t bootflag_show(struct device *dev,
0362 struct device_attribute *attr, char *buf)
0363 {
0364 struct mrvl_mesh_defaults defs;
0365 int ret;
0366
0367 ret = mesh_get_default_parameters(dev, &defs);
0368
0369 if (ret)
0370 return ret;
0371
0372 return sysfs_emit(buf, "%d\n", le32_to_cpu(defs.bootflag));
0373 }
0374
0375
0376
0377
0378
0379
0380
0381
0382 static ssize_t bootflag_store(struct device *dev, struct device_attribute *attr,
0383 const char *buf, size_t count)
0384 {
0385 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
0386 struct cmd_ds_mesh_config cmd;
0387 uint32_t datum;
0388 int ret;
0389
0390 memset(&cmd, 0, sizeof(cmd));
0391 ret = sscanf(buf, "%d", &datum);
0392 if ((ret != 1) || (datum > 1))
0393 return -EINVAL;
0394
0395 *((__le32 *)&cmd.data[0]) = cpu_to_le32(!!datum);
0396 cmd.length = cpu_to_le16(sizeof(uint32_t));
0397 ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
0398 CMD_TYPE_MESH_SET_BOOTFLAG);
0399 if (ret)
0400 return ret;
0401
0402 return strlen(buf);
0403 }
0404
0405
0406
0407
0408
0409
0410
0411 static ssize_t boottime_show(struct device *dev,
0412 struct device_attribute *attr, char *buf)
0413 {
0414 struct mrvl_mesh_defaults defs;
0415 int ret;
0416
0417 ret = mesh_get_default_parameters(dev, &defs);
0418
0419 if (ret)
0420 return ret;
0421
0422 return sysfs_emit(buf, "%d\n", defs.boottime);
0423 }
0424
0425
0426
0427
0428
0429
0430
0431
0432 static ssize_t boottime_store(struct device *dev,
0433 struct device_attribute *attr,
0434 const char *buf, size_t count)
0435 {
0436 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
0437 struct cmd_ds_mesh_config cmd;
0438 uint32_t datum;
0439 int ret;
0440
0441 memset(&cmd, 0, sizeof(cmd));
0442 ret = sscanf(buf, "%d", &datum);
0443 if ((ret != 1) || (datum > 255))
0444 return -EINVAL;
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454 datum = (datum < 20) ? 20 : datum;
0455 cmd.data[0] = datum;
0456 cmd.length = cpu_to_le16(sizeof(uint8_t));
0457 ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
0458 CMD_TYPE_MESH_SET_BOOTTIME);
0459 if (ret)
0460 return ret;
0461
0462 return strlen(buf);
0463 }
0464
0465
0466
0467
0468
0469
0470
0471 static ssize_t channel_show(struct device *dev,
0472 struct device_attribute *attr, char *buf)
0473 {
0474 struct mrvl_mesh_defaults defs;
0475 int ret;
0476
0477 ret = mesh_get_default_parameters(dev, &defs);
0478
0479 if (ret)
0480 return ret;
0481
0482 return sysfs_emit(buf, "%d\n", le16_to_cpu(defs.channel));
0483 }
0484
0485
0486
0487
0488
0489
0490
0491
0492 static ssize_t channel_store(struct device *dev, struct device_attribute *attr,
0493 const char *buf, size_t count)
0494 {
0495 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
0496 struct cmd_ds_mesh_config cmd;
0497 uint32_t datum;
0498 int ret;
0499
0500 memset(&cmd, 0, sizeof(cmd));
0501 ret = sscanf(buf, "%d", &datum);
0502 if (ret != 1 || datum < 1 || datum > 11)
0503 return -EINVAL;
0504
0505 *((__le16 *)&cmd.data[0]) = cpu_to_le16(datum);
0506 cmd.length = cpu_to_le16(sizeof(uint16_t));
0507 ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
0508 CMD_TYPE_MESH_SET_DEF_CHANNEL);
0509 if (ret)
0510 return ret;
0511
0512 return strlen(buf);
0513 }
0514
0515
0516
0517
0518
0519
0520
0521 static ssize_t mesh_id_show(struct device *dev, struct device_attribute *attr,
0522 char *buf)
0523 {
0524 struct mrvl_mesh_defaults defs;
0525 int ret;
0526
0527 ret = mesh_get_default_parameters(dev, &defs);
0528
0529 if (ret)
0530 return ret;
0531
0532 if (defs.meshie.val.mesh_id_len > IEEE80211_MAX_SSID_LEN) {
0533 dev_err(dev, "inconsistent mesh ID length\n");
0534 defs.meshie.val.mesh_id_len = IEEE80211_MAX_SSID_LEN;
0535 }
0536
0537 memcpy(buf, defs.meshie.val.mesh_id, defs.meshie.val.mesh_id_len);
0538 buf[defs.meshie.val.mesh_id_len] = '\n';
0539 buf[defs.meshie.val.mesh_id_len + 1] = '\0';
0540
0541 return defs.meshie.val.mesh_id_len + 1;
0542 }
0543
0544
0545
0546
0547
0548
0549
0550
0551 static ssize_t mesh_id_store(struct device *dev, struct device_attribute *attr,
0552 const char *buf, size_t count)
0553 {
0554 struct cmd_ds_mesh_config cmd;
0555 struct mrvl_mesh_defaults defs;
0556 struct mrvl_meshie *ie;
0557 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
0558 int len;
0559 int ret;
0560
0561 if (count < 2 || count > IEEE80211_MAX_SSID_LEN + 1)
0562 return -EINVAL;
0563
0564 memset(&cmd, 0, sizeof(struct cmd_ds_mesh_config));
0565 ie = (struct mrvl_meshie *) &cmd.data[0];
0566
0567
0568 ret = mesh_get_default_parameters(dev, &defs);
0569
0570 cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
0571
0572
0573 memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
0574
0575 len = count - 1;
0576 memcpy(ie->val.mesh_id, buf, len);
0577
0578 ie->val.mesh_id_len = len;
0579
0580 ie->len = sizeof(struct mrvl_meshie_val) - IEEE80211_MAX_SSID_LEN + len;
0581
0582 ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
0583 CMD_TYPE_MESH_SET_MESH_IE);
0584 if (ret)
0585 return ret;
0586
0587 return strlen(buf);
0588 }
0589
0590
0591
0592
0593
0594
0595
0596 static ssize_t protocol_id_show(struct device *dev,
0597 struct device_attribute *attr,
0598 char *buf)
0599 {
0600 struct mrvl_mesh_defaults defs;
0601 int ret;
0602
0603 ret = mesh_get_default_parameters(dev, &defs);
0604
0605 if (ret)
0606 return ret;
0607
0608 return sysfs_emit(buf, "%d\n", defs.meshie.val.active_protocol_id);
0609 }
0610
0611
0612
0613
0614
0615
0616
0617
0618 static ssize_t protocol_id_store(struct device *dev,
0619 struct device_attribute *attr,
0620 const char *buf, size_t count)
0621 {
0622 struct cmd_ds_mesh_config cmd;
0623 struct mrvl_mesh_defaults defs;
0624 struct mrvl_meshie *ie;
0625 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
0626 uint32_t datum;
0627 int ret;
0628
0629 memset(&cmd, 0, sizeof(cmd));
0630 ret = sscanf(buf, "%d", &datum);
0631 if ((ret != 1) || (datum > 255))
0632 return -EINVAL;
0633
0634
0635 ret = mesh_get_default_parameters(dev, &defs);
0636
0637 cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
0638
0639
0640 ie = (struct mrvl_meshie *) &cmd.data[0];
0641 memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
0642
0643 ie->val.active_protocol_id = datum;
0644
0645 ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
0646 CMD_TYPE_MESH_SET_MESH_IE);
0647 if (ret)
0648 return ret;
0649
0650 return strlen(buf);
0651 }
0652
0653
0654
0655
0656
0657
0658
0659 static ssize_t metric_id_show(struct device *dev,
0660 struct device_attribute *attr, char *buf)
0661 {
0662 struct mrvl_mesh_defaults defs;
0663 int ret;
0664
0665 ret = mesh_get_default_parameters(dev, &defs);
0666
0667 if (ret)
0668 return ret;
0669
0670 return sysfs_emit(buf, "%d\n", defs.meshie.val.active_metric_id);
0671 }
0672
0673
0674
0675
0676
0677
0678
0679
0680 static ssize_t metric_id_store(struct device *dev,
0681 struct device_attribute *attr,
0682 const char *buf, size_t count)
0683 {
0684 struct cmd_ds_mesh_config cmd;
0685 struct mrvl_mesh_defaults defs;
0686 struct mrvl_meshie *ie;
0687 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
0688 uint32_t datum;
0689 int ret;
0690
0691 memset(&cmd, 0, sizeof(cmd));
0692 ret = sscanf(buf, "%d", &datum);
0693 if ((ret != 1) || (datum > 255))
0694 return -EINVAL;
0695
0696
0697 ret = mesh_get_default_parameters(dev, &defs);
0698
0699 cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
0700
0701
0702 ie = (struct mrvl_meshie *) &cmd.data[0];
0703 memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
0704
0705 ie->val.active_metric_id = datum;
0706
0707 ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
0708 CMD_TYPE_MESH_SET_MESH_IE);
0709 if (ret)
0710 return ret;
0711
0712 return strlen(buf);
0713 }
0714
0715
0716
0717
0718
0719
0720
0721 static ssize_t capability_show(struct device *dev,
0722 struct device_attribute *attr, char *buf)
0723 {
0724 struct mrvl_mesh_defaults defs;
0725 int ret;
0726
0727 ret = mesh_get_default_parameters(dev, &defs);
0728
0729 if (ret)
0730 return ret;
0731
0732 return sysfs_emit(buf, "%d\n", defs.meshie.val.mesh_capability);
0733 }
0734
0735
0736
0737
0738
0739
0740
0741
0742 static ssize_t capability_store(struct device *dev,
0743 struct device_attribute *attr,
0744 const char *buf, size_t count)
0745 {
0746 struct cmd_ds_mesh_config cmd;
0747 struct mrvl_mesh_defaults defs;
0748 struct mrvl_meshie *ie;
0749 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
0750 uint32_t datum;
0751 int ret;
0752
0753 memset(&cmd, 0, sizeof(cmd));
0754 ret = sscanf(buf, "%d", &datum);
0755 if ((ret != 1) || (datum > 255))
0756 return -EINVAL;
0757
0758
0759 ret = mesh_get_default_parameters(dev, &defs);
0760
0761 cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie));
0762
0763
0764 ie = (struct mrvl_meshie *) &cmd.data[0];
0765 memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie));
0766
0767 ie->val.mesh_capability = datum;
0768
0769 ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
0770 CMD_TYPE_MESH_SET_MESH_IE);
0771 if (ret)
0772 return ret;
0773
0774 return strlen(buf);
0775 }
0776
0777
0778 static DEVICE_ATTR_RW(bootflag);
0779 static DEVICE_ATTR_RW(boottime);
0780 static DEVICE_ATTR_RW(channel);
0781 static DEVICE_ATTR_RW(mesh_id);
0782 static DEVICE_ATTR_RW(protocol_id);
0783 static DEVICE_ATTR_RW(metric_id);
0784 static DEVICE_ATTR_RW(capability);
0785
0786 static struct attribute *boot_opts_attrs[] = {
0787 &dev_attr_bootflag.attr,
0788 &dev_attr_boottime.attr,
0789 &dev_attr_channel.attr,
0790 NULL
0791 };
0792
0793 static const struct attribute_group boot_opts_group = {
0794 .name = "boot_options",
0795 .attrs = boot_opts_attrs,
0796 };
0797
0798 static struct attribute *mesh_ie_attrs[] = {
0799 &dev_attr_mesh_id.attr,
0800 &dev_attr_protocol_id.attr,
0801 &dev_attr_metric_id.attr,
0802 &dev_attr_capability.attr,
0803 NULL
0804 };
0805
0806 static const struct attribute_group mesh_ie_group = {
0807 .name = "mesh_ie",
0808 .attrs = mesh_ie_attrs,
0809 };
0810
0811
0812
0813
0814
0815
0816
0817
0818
0819
0820 void lbs_init_mesh(struct lbs_private *priv)
0821 {
0822
0823
0824
0825
0826
0827 if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5) {
0828
0829
0830
0831
0832
0833
0834
0835
0836
0837
0838
0839
0840
0841 priv->mesh_tlv = TLV_TYPE_OLD_MESH_ID;
0842 if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 1)) {
0843 priv->mesh_tlv = TLV_TYPE_MESH_ID;
0844 if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 1))
0845 priv->mesh_tlv = 0;
0846 }
0847 } else
0848 if ((MRVL_FW_MAJOR_REV(priv->fwrelease) >= MRVL_FW_V10) &&
0849 (priv->fwcapinfo & MESH_CAPINFO_ENABLE_MASK)) {
0850
0851
0852
0853 priv->mesh_tlv = TLV_TYPE_MESH_ID;
0854 if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 1))
0855 priv->mesh_tlv = 0;
0856 }
0857
0858
0859 lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_STOP, 1);
0860 }
0861
0862 void lbs_start_mesh(struct lbs_private *priv)
0863 {
0864 lbs_add_mesh(priv);
0865
0866 if (device_create_file(&priv->dev->dev, &dev_attr_lbs_mesh))
0867 netdev_err(priv->dev, "cannot register lbs_mesh attribute\n");
0868 }
0869
0870 int lbs_deinit_mesh(struct lbs_private *priv)
0871 {
0872 struct net_device *dev = priv->dev;
0873 int ret = 0;
0874
0875 if (priv->mesh_tlv) {
0876 device_remove_file(&dev->dev, &dev_attr_lbs_mesh);
0877 ret = 1;
0878 }
0879
0880 return ret;
0881 }
0882
0883
0884
0885
0886
0887
0888
0889
0890 static int lbs_mesh_stop(struct net_device *dev)
0891 {
0892 struct lbs_private *priv = dev->ml_priv;
0893
0894 lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_STOP,
0895 lbs_mesh_get_channel(priv));
0896
0897 spin_lock_irq(&priv->driver_lock);
0898
0899 netif_stop_queue(dev);
0900 netif_carrier_off(dev);
0901
0902 spin_unlock_irq(&priv->driver_lock);
0903
0904 lbs_update_mcast(priv);
0905 if (!lbs_iface_active(priv))
0906 lbs_stop_iface(priv);
0907
0908 return 0;
0909 }
0910
0911
0912
0913
0914
0915
0916
0917 static int lbs_mesh_dev_open(struct net_device *dev)
0918 {
0919 struct lbs_private *priv = dev->ml_priv;
0920 int ret = 0;
0921
0922 if (!priv->iface_running) {
0923 ret = lbs_start_iface(priv);
0924 if (ret)
0925 goto out;
0926 }
0927
0928 spin_lock_irq(&priv->driver_lock);
0929
0930 if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) {
0931 ret = -EBUSY;
0932 spin_unlock_irq(&priv->driver_lock);
0933 goto out;
0934 }
0935
0936 netif_carrier_on(dev);
0937
0938 if (!priv->tx_pending_len)
0939 netif_wake_queue(dev);
0940
0941 spin_unlock_irq(&priv->driver_lock);
0942
0943 ret = lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
0944 lbs_mesh_get_channel(priv));
0945
0946 out:
0947 return ret;
0948 }
0949
0950 static const struct net_device_ops mesh_netdev_ops = {
0951 .ndo_open = lbs_mesh_dev_open,
0952 .ndo_stop = lbs_mesh_stop,
0953 .ndo_start_xmit = lbs_hard_start_xmit,
0954 .ndo_set_mac_address = lbs_set_mac_address,
0955 .ndo_set_rx_mode = lbs_set_multicast_list,
0956 };
0957
0958
0959
0960
0961
0962
0963
0964 static int lbs_add_mesh(struct lbs_private *priv)
0965 {
0966 struct net_device *mesh_dev = NULL;
0967 struct wireless_dev *mesh_wdev;
0968 int ret = 0;
0969
0970
0971 mesh_wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
0972 if (!mesh_wdev) {
0973 lbs_deb_mesh("init mshX wireless device failed\n");
0974 ret = -ENOMEM;
0975 goto done;
0976 }
0977
0978 mesh_dev = alloc_netdev(0, "msh%d", NET_NAME_UNKNOWN, ether_setup);
0979 if (!mesh_dev) {
0980 lbs_deb_mesh("init mshX device failed\n");
0981 ret = -ENOMEM;
0982 goto err_free_wdev;
0983 }
0984
0985 mesh_wdev->iftype = NL80211_IFTYPE_MESH_POINT;
0986 mesh_wdev->wiphy = priv->wdev->wiphy;
0987
0988 if (priv->mesh_tlv) {
0989 sprintf(mesh_wdev->u.mesh.id, "mesh");
0990 mesh_wdev->u.mesh.id_up_len = 4;
0991 }
0992
0993 mesh_wdev->netdev = mesh_dev;
0994
0995 mesh_dev->ml_priv = priv;
0996 mesh_dev->ieee80211_ptr = mesh_wdev;
0997 priv->mesh_dev = mesh_dev;
0998
0999 mesh_dev->netdev_ops = &mesh_netdev_ops;
1000 mesh_dev->ethtool_ops = &lbs_ethtool_ops;
1001 eth_hw_addr_inherit(mesh_dev, priv->dev);
1002
1003 SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent);
1004
1005 mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
1006 mesh_dev->sysfs_groups[0] = &lbs_mesh_attr_group;
1007 mesh_dev->sysfs_groups[1] = &boot_opts_group;
1008 mesh_dev->sysfs_groups[2] = &mesh_ie_group;
1009
1010
1011 ret = register_netdev(mesh_dev);
1012 if (ret) {
1013 pr_err("cannot register mshX virtual interface\n");
1014 goto err_free_netdev;
1015 }
1016
1017
1018 ret = 0;
1019 goto done;
1020
1021 err_free_netdev:
1022 free_netdev(mesh_dev);
1023
1024 err_free_wdev:
1025 kfree(mesh_wdev);
1026
1027 done:
1028 return ret;
1029 }
1030
1031 void lbs_remove_mesh(struct lbs_private *priv)
1032 {
1033 struct net_device *mesh_dev;
1034
1035 mesh_dev = priv->mesh_dev;
1036 if (!mesh_dev)
1037 return;
1038
1039 netif_stop_queue(mesh_dev);
1040 netif_carrier_off(mesh_dev);
1041 unregister_netdev(mesh_dev);
1042 priv->mesh_dev = NULL;
1043 kfree(mesh_dev->ieee80211_ptr);
1044 free_netdev(mesh_dev);
1045 }
1046
1047
1048
1049
1050
1051 struct net_device *lbs_mesh_set_dev(struct lbs_private *priv,
1052 struct net_device *dev, struct rxpd *rxpd)
1053 {
1054 if (priv->mesh_dev) {
1055 if (priv->mesh_tlv == TLV_TYPE_OLD_MESH_ID) {
1056 if (rxpd->rx_control & RxPD_MESH_FRAME)
1057 dev = priv->mesh_dev;
1058 } else if (priv->mesh_tlv == TLV_TYPE_MESH_ID) {
1059 if (rxpd->u.bss.bss_num == MESH_IFACE_ID)
1060 dev = priv->mesh_dev;
1061 }
1062 }
1063 return dev;
1064 }
1065
1066
1067 void lbs_mesh_set_txpd(struct lbs_private *priv,
1068 struct net_device *dev, struct txpd *txpd)
1069 {
1070 if (dev == priv->mesh_dev) {
1071 if (priv->mesh_tlv == TLV_TYPE_OLD_MESH_ID)
1072 txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME);
1073 else if (priv->mesh_tlv == TLV_TYPE_MESH_ID)
1074 txpd->u.bss.bss_num = MESH_IFACE_ID;
1075 }
1076 }
1077
1078
1079
1080
1081
1082
1083 static const char mesh_stat_strings[MESH_STATS_NUM][ETH_GSTRING_LEN] = {
1084 "drop_duplicate_bcast",
1085 "drop_ttl_zero",
1086 "drop_no_fwd_route",
1087 "drop_no_buffers",
1088 "fwded_unicast_cnt",
1089 "fwded_bcast_cnt",
1090 "drop_blind_table",
1091 "tx_failed_cnt"
1092 };
1093
1094 void lbs_mesh_ethtool_get_stats(struct net_device *dev,
1095 struct ethtool_stats *stats, uint64_t *data)
1096 {
1097 struct lbs_private *priv = dev->ml_priv;
1098 struct cmd_ds_mesh_access mesh_access;
1099 int ret;
1100
1101
1102 ret = lbs_mesh_access(priv, CMD_ACT_MESH_GET_STATS, &mesh_access);
1103
1104 if (ret) {
1105 memset(data, 0, MESH_STATS_NUM*(sizeof(uint64_t)));
1106 return;
1107 }
1108
1109 priv->mstats.fwd_drop_rbt = le32_to_cpu(mesh_access.data[0]);
1110 priv->mstats.fwd_drop_ttl = le32_to_cpu(mesh_access.data[1]);
1111 priv->mstats.fwd_drop_noroute = le32_to_cpu(mesh_access.data[2]);
1112 priv->mstats.fwd_drop_nobuf = le32_to_cpu(mesh_access.data[3]);
1113 priv->mstats.fwd_unicast_cnt = le32_to_cpu(mesh_access.data[4]);
1114 priv->mstats.fwd_bcast_cnt = le32_to_cpu(mesh_access.data[5]);
1115 priv->mstats.drop_blind = le32_to_cpu(mesh_access.data[6]);
1116 priv->mstats.tx_failed_cnt = le32_to_cpu(mesh_access.data[7]);
1117
1118 data[0] = priv->mstats.fwd_drop_rbt;
1119 data[1] = priv->mstats.fwd_drop_ttl;
1120 data[2] = priv->mstats.fwd_drop_noroute;
1121 data[3] = priv->mstats.fwd_drop_nobuf;
1122 data[4] = priv->mstats.fwd_unicast_cnt;
1123 data[5] = priv->mstats.fwd_bcast_cnt;
1124 data[6] = priv->mstats.drop_blind;
1125 data[7] = priv->mstats.tx_failed_cnt;
1126 }
1127
1128 int lbs_mesh_ethtool_get_sset_count(struct net_device *dev, int sset)
1129 {
1130 struct lbs_private *priv = dev->ml_priv;
1131
1132 if (sset == ETH_SS_STATS && dev == priv->mesh_dev)
1133 return MESH_STATS_NUM;
1134
1135 return -EOPNOTSUPP;
1136 }
1137
1138 void lbs_mesh_ethtool_get_strings(struct net_device *dev,
1139 uint32_t stringset, uint8_t *s)
1140 {
1141 switch (stringset) {
1142 case ETH_SS_STATS:
1143 memcpy(s, mesh_stat_strings, sizeof(mesh_stat_strings));
1144 break;
1145 }
1146 }