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