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->mesh_id_up_len; 113 memcpy(ie->val.mesh_id, mesh_wdev->ssid, 114 mesh_wdev->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 memset(&mesh_access, 0, sizeof(mesh_access)); 192 sscanf(buf, "%x", &datum); 193 mesh_access.data[0] = cpu_to_le32(datum); 194 195 ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_ANYCAST, &mesh_access); 196 if (ret) 197 return ret; 198 199 return strlen(buf); 200 } 201 202 /** 203 * prb_rsp_limit_show - Get function for sysfs attribute prb_rsp_limit 204 * @dev: the &struct device 205 * @attr: device attributes 206 * @buf: buffer where data will be returned 207 */ 208 static ssize_t prb_rsp_limit_show(struct device *dev, 209 struct device_attribute *attr, char *buf) 210 { 211 struct lbs_private *priv = to_net_dev(dev)->ml_priv; 212 struct cmd_ds_mesh_access mesh_access; 213 int ret; 214 u32 retry_limit; 215 216 memset(&mesh_access, 0, sizeof(mesh_access)); 217 mesh_access.data[0] = cpu_to_le32(CMD_ACT_GET); 218 219 ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT, 220 &mesh_access); 221 if (ret) 222 return ret; 223 224 retry_limit = le32_to_cpu(mesh_access.data[1]); 225 return sysfs_emit(buf, "%d\n", retry_limit); 226 } 227 228 /** 229 * prb_rsp_limit_store - Set function for sysfs attribute prb_rsp_limit 230 * @dev: the &struct device 231 * @attr: device attributes 232 * @buf: buffer that contains new attribute value 233 * @count: size of buffer 234 */ 235 static ssize_t prb_rsp_limit_store(struct device *dev, 236 struct device_attribute *attr, 237 const char *buf, size_t count) 238 { 239 struct lbs_private *priv = to_net_dev(dev)->ml_priv; 240 struct cmd_ds_mesh_access mesh_access; 241 int ret; 242 unsigned long retry_limit; 243 244 memset(&mesh_access, 0, sizeof(mesh_access)); 245 mesh_access.data[0] = cpu_to_le32(CMD_ACT_SET); 246 247 ret = kstrtoul(buf, 10, &retry_limit); 248 if (ret) 249 return ret; 250 if (retry_limit > 15) 251 return -ENOTSUPP; 252 253 mesh_access.data[1] = cpu_to_le32(retry_limit); 254 255 ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT, 256 &mesh_access); 257 if (ret) 258 return ret; 259 260 return strlen(buf); 261 } 262 263 /** 264 * lbs_mesh_show - Get function for sysfs attribute mesh 265 * @dev: the &struct device 266 * @attr: device attributes 267 * @buf: buffer where data will be returned 268 */ 269 static ssize_t lbs_mesh_show(struct device *dev, 270 struct device_attribute *attr, char *buf) 271 { 272 struct lbs_private *priv = to_net_dev(dev)->ml_priv; 273 return sysfs_emit(buf, "0x%X\n", !!priv->mesh_dev); 274 } 275 276 /** 277 * lbs_mesh_store - Set function for sysfs attribute mesh 278 * @dev: the &struct device 279 * @attr: device attributes 280 * @buf: buffer that contains new attribute value 281 * @count: size of buffer 282 */ 283 static ssize_t lbs_mesh_store(struct device *dev, 284 struct device_attribute *attr, 285 const char *buf, size_t count) 286 { 287 struct lbs_private *priv = to_net_dev(dev)->ml_priv; 288 int enable; 289 290 sscanf(buf, "%x", &enable); 291 enable = !!enable; 292 if (enable == !!priv->mesh_dev) 293 return count; 294 295 if (enable) 296 lbs_add_mesh(priv); 297 else 298 lbs_remove_mesh(priv); 299 300 return count; 301 } 302 303 /* 304 * lbs_mesh attribute to be exported per ethX interface 305 * through sysfs (/sys/class/net/ethX/lbs_mesh) 306 */ 307 static DEVICE_ATTR_RW(lbs_mesh); 308 309 /* 310 * anycast_mask attribute to be exported per mshX interface 311 * through sysfs (/sys/class/net/mshX/anycast_mask) 312 */ 313 static DEVICE_ATTR_RW(anycast_mask); 314 315 /* 316 * prb_rsp_limit attribute to be exported per mshX interface 317 * through sysfs (/sys/class/net/mshX/prb_rsp_limit) 318 */ 319 static DEVICE_ATTR_RW(prb_rsp_limit); 320 321 static struct attribute *lbs_mesh_sysfs_entries[] = { 322 &dev_attr_anycast_mask.attr, 323 &dev_attr_prb_rsp_limit.attr, 324 NULL, 325 }; 326 327 static const struct attribute_group lbs_mesh_attr_group = { 328 .attrs = lbs_mesh_sysfs_entries, 329 }; 330 331 332 /*************************************************************************** 333 * Persistent configuration support 334 */ 335 336 static int mesh_get_default_parameters(struct device *dev, 337 struct mrvl_mesh_defaults *defs) 338 { 339 struct lbs_private *priv = to_net_dev(dev)->ml_priv; 340 struct cmd_ds_mesh_config cmd; 341 int ret; 342 343 memset(&cmd, 0, sizeof(struct cmd_ds_mesh_config)); 344 ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_GET, 345 CMD_TYPE_MESH_GET_DEFAULTS); 346 347 if (ret) 348 return -EOPNOTSUPP; 349 350 memcpy(defs, &cmd.data[0], sizeof(struct mrvl_mesh_defaults)); 351 352 return 0; 353 } 354 355 /** 356 * bootflag_show - Get function for sysfs attribute bootflag 357 * @dev: the &struct device 358 * @attr: device attributes 359 * @buf: buffer where data will be returned 360 */ 361 static ssize_t bootflag_show(struct device *dev, 362 struct device_attribute *attr, char *buf) 363 { 364 struct mrvl_mesh_defaults defs; 365 int ret; 366 367 ret = mesh_get_default_parameters(dev, &defs); 368 369 if (ret) 370 return ret; 371 372 return sysfs_emit(buf, "%d\n", le32_to_cpu(defs.bootflag)); 373 } 374 375 /** 376 * bootflag_store - Set function for sysfs attribute bootflag 377 * @dev: the &struct device 378 * @attr: device attributes 379 * @buf: buffer that contains new attribute value 380 * @count: size of buffer 381 */ 382 static ssize_t bootflag_store(struct device *dev, struct device_attribute *attr, 383 const char *buf, size_t count) 384 { 385 struct lbs_private *priv = to_net_dev(dev)->ml_priv; 386 struct cmd_ds_mesh_config cmd; 387 uint32_t datum; 388 int ret; 389 390 memset(&cmd, 0, sizeof(cmd)); 391 ret = sscanf(buf, "%d", &datum); 392 if ((ret != 1) || (datum > 1)) 393 return -EINVAL; 394 395 *((__le32 *)&cmd.data[0]) = cpu_to_le32(!!datum); 396 cmd.length = cpu_to_le16(sizeof(uint32_t)); 397 ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET, 398 CMD_TYPE_MESH_SET_BOOTFLAG); 399 if (ret) 400 return ret; 401 402 return strlen(buf); 403 } 404 405 /** 406 * boottime_show - Get function for sysfs attribute boottime 407 * @dev: the &struct device 408 * @attr: device attributes 409 * @buf: buffer where data will be returned 410 */ 411 static ssize_t boottime_show(struct device *dev, 412 struct device_attribute *attr, char *buf) 413 { 414 struct mrvl_mesh_defaults defs; 415 int ret; 416 417 ret = mesh_get_default_parameters(dev, &defs); 418 419 if (ret) 420 return ret; 421 422 return sysfs_emit(buf, "%d\n", defs.boottime); 423 } 424 425 /** 426 * boottime_store - Set function for sysfs attribute boottime 427 * @dev: the &struct device 428 * @attr: device attributes 429 * @buf: buffer that contains new attribute value 430 * @count: size of buffer 431 */ 432 static ssize_t boottime_store(struct device *dev, 433 struct device_attribute *attr, 434 const char *buf, size_t count) 435 { 436 struct lbs_private *priv = to_net_dev(dev)->ml_priv; 437 struct cmd_ds_mesh_config cmd; 438 uint32_t datum; 439 int ret; 440 441 memset(&cmd, 0, sizeof(cmd)); 442 ret = sscanf(buf, "%d", &datum); 443 if ((ret != 1) || (datum > 255)) 444 return -EINVAL; 445 446 /* A too small boot time will result in the device booting into 447 * standalone (no-host) mode before the host can take control of it, 448 * so the change will be hard to revert. This may be a desired 449 * feature (e.g to configure a very fast boot time for devices that 450 * will not be attached to a host), but dangerous. So I'm enforcing a 451 * lower limit of 20 seconds: remove and recompile the driver if this 452 * does not work for you. 453 */ 454 datum = (datum < 20) ? 20 : datum; 455 cmd.data[0] = datum; 456 cmd.length = cpu_to_le16(sizeof(uint8_t)); 457 ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET, 458 CMD_TYPE_MESH_SET_BOOTTIME); 459 if (ret) 460 return ret; 461 462 return strlen(buf); 463 } 464 465 /** 466 * channel_show - Get function for sysfs attribute channel 467 * @dev: the &struct device 468 * @attr: device attributes 469 * @buf: buffer where data will be returned 470 */ 471 static ssize_t channel_show(struct device *dev, 472 struct device_attribute *attr, char *buf) 473 { 474 struct mrvl_mesh_defaults defs; 475 int ret; 476 477 ret = mesh_get_default_parameters(dev, &defs); 478 479 if (ret) 480 return ret; 481 482 return sysfs_emit(buf, "%d\n", le16_to_cpu(defs.channel)); 483 } 484 485 /** 486 * channel_store - Set function for sysfs attribute channel 487 * @dev: the &struct device 488 * @attr: device attributes 489 * @buf: buffer that contains new attribute value 490 * @count: size of buffer 491 */ 492 static ssize_t channel_store(struct device *dev, struct device_attribute *attr, 493 const char *buf, size_t count) 494 { 495 struct lbs_private *priv = to_net_dev(dev)->ml_priv; 496 struct cmd_ds_mesh_config cmd; 497 uint32_t datum; 498 int ret; 499 500 memset(&cmd, 0, sizeof(cmd)); 501 ret = sscanf(buf, "%d", &datum); 502 if (ret != 1 || datum < 1 || datum > 11) 503 return -EINVAL; 504 505 *((__le16 *)&cmd.data[0]) = cpu_to_le16(datum); 506 cmd.length = cpu_to_le16(sizeof(uint16_t)); 507 ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET, 508 CMD_TYPE_MESH_SET_DEF_CHANNEL); 509 if (ret) 510 return ret; 511 512 return strlen(buf); 513 } 514 515 /** 516 * mesh_id_show - Get function for sysfs attribute mesh_id 517 * @dev: the &struct device 518 * @attr: device attributes 519 * @buf: buffer where data will be returned 520 */ 521 static ssize_t mesh_id_show(struct device *dev, struct device_attribute *attr, 522 char *buf) 523 { 524 struct mrvl_mesh_defaults defs; 525 int ret; 526 527 ret = mesh_get_default_parameters(dev, &defs); 528 529 if (ret) 530 return ret; 531 532 if (defs.meshie.val.mesh_id_len > IEEE80211_MAX_SSID_LEN) { 533 dev_err(dev, "inconsistent mesh ID length\n"); 534 defs.meshie.val.mesh_id_len = IEEE80211_MAX_SSID_LEN; 535 } 536 537 memcpy(buf, defs.meshie.val.mesh_id, defs.meshie.val.mesh_id_len); 538 buf[defs.meshie.val.mesh_id_len] = '\n'; 539 buf[defs.meshie.val.mesh_id_len + 1] = '\0'; 540 541 return defs.meshie.val.mesh_id_len + 1; 542 } 543 544 /** 545 * mesh_id_store - Set function for sysfs attribute mesh_id 546 * @dev: the &struct device 547 * @attr: device attributes 548 * @buf: buffer that contains new attribute value 549 * @count: size of buffer 550 */ 551 static ssize_t mesh_id_store(struct device *dev, struct device_attribute *attr, 552 const char *buf, size_t count) 553 { 554 struct cmd_ds_mesh_config cmd; 555 struct mrvl_mesh_defaults defs; 556 struct mrvl_meshie *ie; 557 struct lbs_private *priv = to_net_dev(dev)->ml_priv; 558 int len; 559 int ret; 560 561 if (count < 2 || count > IEEE80211_MAX_SSID_LEN + 1) 562 return -EINVAL; 563 564 memset(&cmd, 0, sizeof(struct cmd_ds_mesh_config)); 565 ie = (struct mrvl_meshie *) &cmd.data[0]; 566 567 /* fetch all other Information Element parameters */ 568 ret = mesh_get_default_parameters(dev, &defs); 569 570 cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie)); 571 572 /* transfer IE elements */ 573 memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie)); 574 575 len = count - 1; 576 memcpy(ie->val.mesh_id, buf, len); 577 /* SSID len */ 578 ie->val.mesh_id_len = len; 579 /* IE len */ 580 ie->len = sizeof(struct mrvl_meshie_val) - IEEE80211_MAX_SSID_LEN + len; 581 582 ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET, 583 CMD_TYPE_MESH_SET_MESH_IE); 584 if (ret) 585 return ret; 586 587 return strlen(buf); 588 } 589 590 /** 591 * protocol_id_show - Get function for sysfs attribute protocol_id 592 * @dev: the &struct device 593 * @attr: device attributes 594 * @buf: buffer where data will be returned 595 */ 596 static ssize_t protocol_id_show(struct device *dev, 597 struct device_attribute *attr, 598 char *buf) 599 { 600 struct mrvl_mesh_defaults defs; 601 int ret; 602 603 ret = mesh_get_default_parameters(dev, &defs); 604 605 if (ret) 606 return ret; 607 608 return sysfs_emit(buf, "%d\n", defs.meshie.val.active_protocol_id); 609 } 610 611 /** 612 * protocol_id_store - Set function for sysfs attribute protocol_id 613 * @dev: the &struct device 614 * @attr: device attributes 615 * @buf: buffer that contains new attribute value 616 * @count: size of buffer 617 */ 618 static ssize_t protocol_id_store(struct device *dev, 619 struct device_attribute *attr, 620 const char *buf, size_t count) 621 { 622 struct cmd_ds_mesh_config cmd; 623 struct mrvl_mesh_defaults defs; 624 struct mrvl_meshie *ie; 625 struct lbs_private *priv = to_net_dev(dev)->ml_priv; 626 uint32_t datum; 627 int ret; 628 629 memset(&cmd, 0, sizeof(cmd)); 630 ret = sscanf(buf, "%d", &datum); 631 if ((ret != 1) || (datum > 255)) 632 return -EINVAL; 633 634 /* fetch all other Information Element parameters */ 635 ret = mesh_get_default_parameters(dev, &defs); 636 637 cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie)); 638 639 /* transfer IE elements */ 640 ie = (struct mrvl_meshie *) &cmd.data[0]; 641 memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie)); 642 /* update protocol id */ 643 ie->val.active_protocol_id = datum; 644 645 ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET, 646 CMD_TYPE_MESH_SET_MESH_IE); 647 if (ret) 648 return ret; 649 650 return strlen(buf); 651 } 652 653 /** 654 * metric_id_show - Get function for sysfs attribute metric_id 655 * @dev: the &struct device 656 * @attr: device attributes 657 * @buf: buffer where data will be returned 658 */ 659 static ssize_t metric_id_show(struct device *dev, 660 struct device_attribute *attr, char *buf) 661 { 662 struct mrvl_mesh_defaults defs; 663 int ret; 664 665 ret = mesh_get_default_parameters(dev, &defs); 666 667 if (ret) 668 return ret; 669 670 return sysfs_emit(buf, "%d\n", defs.meshie.val.active_metric_id); 671 } 672 673 /** 674 * metric_id_store - Set function for sysfs attribute metric_id 675 * @dev: the &struct device 676 * @attr: device attributes 677 * @buf: buffer that contains new attribute value 678 * @count: size of buffer 679 */ 680 static ssize_t metric_id_store(struct device *dev, 681 struct device_attribute *attr, 682 const char *buf, size_t count) 683 { 684 struct cmd_ds_mesh_config cmd; 685 struct mrvl_mesh_defaults defs; 686 struct mrvl_meshie *ie; 687 struct lbs_private *priv = to_net_dev(dev)->ml_priv; 688 uint32_t datum; 689 int ret; 690 691 memset(&cmd, 0, sizeof(cmd)); 692 ret = sscanf(buf, "%d", &datum); 693 if ((ret != 1) || (datum > 255)) 694 return -EINVAL; 695 696 /* fetch all other Information Element parameters */ 697 ret = mesh_get_default_parameters(dev, &defs); 698 699 cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie)); 700 701 /* transfer IE elements */ 702 ie = (struct mrvl_meshie *) &cmd.data[0]; 703 memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie)); 704 /* update metric id */ 705 ie->val.active_metric_id = datum; 706 707 ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET, 708 CMD_TYPE_MESH_SET_MESH_IE); 709 if (ret) 710 return ret; 711 712 return strlen(buf); 713 } 714 715 /** 716 * capability_show - Get function for sysfs attribute capability 717 * @dev: the &struct device 718 * @attr: device attributes 719 * @buf: buffer where data will be returned 720 */ 721 static ssize_t capability_show(struct device *dev, 722 struct device_attribute *attr, char *buf) 723 { 724 struct mrvl_mesh_defaults defs; 725 int ret; 726 727 ret = mesh_get_default_parameters(dev, &defs); 728 729 if (ret) 730 return ret; 731 732 return sysfs_emit(buf, "%d\n", defs.meshie.val.mesh_capability); 733 } 734 735 /** 736 * capability_store - Set function for sysfs attribute capability 737 * @dev: the &struct device 738 * @attr: device attributes 739 * @buf: buffer that contains new attribute value 740 * @count: size of buffer 741 */ 742 static ssize_t capability_store(struct device *dev, 743 struct device_attribute *attr, 744 const char *buf, size_t count) 745 { 746 struct cmd_ds_mesh_config cmd; 747 struct mrvl_mesh_defaults defs; 748 struct mrvl_meshie *ie; 749 struct lbs_private *priv = to_net_dev(dev)->ml_priv; 750 uint32_t datum; 751 int ret; 752 753 memset(&cmd, 0, sizeof(cmd)); 754 ret = sscanf(buf, "%d", &datum); 755 if ((ret != 1) || (datum > 255)) 756 return -EINVAL; 757 758 /* fetch all other Information Element parameters */ 759 ret = mesh_get_default_parameters(dev, &defs); 760 761 cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie)); 762 763 /* transfer IE elements */ 764 ie = (struct mrvl_meshie *) &cmd.data[0]; 765 memcpy(ie, &defs.meshie, sizeof(struct mrvl_meshie)); 766 /* update value */ 767 ie->val.mesh_capability = datum; 768 769 ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET, 770 CMD_TYPE_MESH_SET_MESH_IE); 771 if (ret) 772 return ret; 773 774 return strlen(buf); 775 } 776 777 778 static DEVICE_ATTR_RW(bootflag); 779 static DEVICE_ATTR_RW(boottime); 780 static DEVICE_ATTR_RW(channel); 781 static DEVICE_ATTR_RW(mesh_id); 782 static DEVICE_ATTR_RW(protocol_id); 783 static DEVICE_ATTR_RW(metric_id); 784 static DEVICE_ATTR_RW(capability); 785 786 static struct attribute *boot_opts_attrs[] = { 787 &dev_attr_bootflag.attr, 788 &dev_attr_boottime.attr, 789 &dev_attr_channel.attr, 790 NULL 791 }; 792 793 static const struct attribute_group boot_opts_group = { 794 .name = "boot_options", 795 .attrs = boot_opts_attrs, 796 }; 797 798 static struct attribute *mesh_ie_attrs[] = { 799 &dev_attr_mesh_id.attr, 800 &dev_attr_protocol_id.attr, 801 &dev_attr_metric_id.attr, 802 &dev_attr_capability.attr, 803 NULL 804 }; 805 806 static const struct attribute_group mesh_ie_group = { 807 .name = "mesh_ie", 808 .attrs = mesh_ie_attrs, 809 }; 810 811 812 /*************************************************************************** 813 * Initializing and starting, stopping mesh 814 */ 815 816 /* 817 * Check mesh FW version and appropriately send the mesh start 818 * command 819 */ 820 void lbs_init_mesh(struct lbs_private *priv) 821 { 822 /* Determine mesh_fw_ver from fwrelease and fwcapinfo */ 823 /* 5.0.16p0 9.0.0.p0 is known to NOT support any mesh */ 824 /* 5.110.22 have mesh command with 0xa3 command id */ 825 /* 10.0.0.p0 FW brings in mesh config command with different id */ 826 /* Check FW version MSB and initialize mesh_fw_ver */ 827 if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5) { 828 /* Enable mesh, if supported, and work out which TLV it uses. 829 0x100 + 291 is an unofficial value used in 5.110.20.pXX 830 0x100 + 37 is the official value used in 5.110.21.pXX 831 but we check them in that order because 20.pXX doesn't 832 give an error -- it just silently fails. */ 833 834 /* 5.110.20.pXX firmware will fail the command if the channel 835 doesn't match the existing channel. But only if the TLV 836 is correct. If the channel is wrong, _BOTH_ versions will 837 give an error to 0x100+291, and allow 0x100+37 to succeed. 838 It's just that 5.110.20.pXX will not have done anything 839 useful */ 840 841 priv->mesh_tlv = TLV_TYPE_OLD_MESH_ID; 842 if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 1)) { 843 priv->mesh_tlv = TLV_TYPE_MESH_ID; 844 if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 1)) 845 priv->mesh_tlv = 0; 846 } 847 } else 848 if ((MRVL_FW_MAJOR_REV(priv->fwrelease) >= MRVL_FW_V10) && 849 (priv->fwcapinfo & MESH_CAPINFO_ENABLE_MASK)) { 850 /* 10.0.0.pXX new firmwares should succeed with TLV 851 * 0x100+37; Do not invoke command with old TLV. 852 */ 853 priv->mesh_tlv = TLV_TYPE_MESH_ID; 854 if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 1)) 855 priv->mesh_tlv = 0; 856 } 857 858 /* Stop meshing until interface is brought up */ 859 lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_STOP, 1); 860 } 861 862 void lbs_start_mesh(struct lbs_private *priv) 863 { 864 lbs_add_mesh(priv); 865 866 if (device_create_file(&priv->dev->dev, &dev_attr_lbs_mesh)) 867 netdev_err(priv->dev, "cannot register lbs_mesh attribute\n"); 868 } 869 870 int lbs_deinit_mesh(struct lbs_private *priv) 871 { 872 struct net_device *dev = priv->dev; 873 int ret = 0; 874 875 if (priv->mesh_tlv) { 876 device_remove_file(&dev->dev, &dev_attr_lbs_mesh); 877 ret = 1; 878 } 879 880 return ret; 881 } 882 883 884 /** 885 * lbs_mesh_stop - close the mshX interface 886 * 887 * @dev: A pointer to &net_device structure 888 * returns: 0 889 */ 890 static int lbs_mesh_stop(struct net_device *dev) 891 { 892 struct lbs_private *priv = dev->ml_priv; 893 894 lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_STOP, 895 lbs_mesh_get_channel(priv)); 896 897 spin_lock_irq(&priv->driver_lock); 898 899 netif_stop_queue(dev); 900 netif_carrier_off(dev); 901 902 spin_unlock_irq(&priv->driver_lock); 903 904 lbs_update_mcast(priv); 905 if (!lbs_iface_active(priv)) 906 lbs_stop_iface(priv); 907 908 return 0; 909 } 910 911 /** 912 * lbs_mesh_dev_open - open the mshX interface 913 * 914 * @dev: A pointer to &net_device structure 915 * returns: 0 or -EBUSY if monitor mode active 916 */ 917 static int lbs_mesh_dev_open(struct net_device *dev) 918 { 919 struct lbs_private *priv = dev->ml_priv; 920 int ret = 0; 921 922 if (!priv->iface_running) { 923 ret = lbs_start_iface(priv); 924 if (ret) 925 goto out; 926 } 927 928 spin_lock_irq(&priv->driver_lock); 929 930 if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) { 931 ret = -EBUSY; 932 spin_unlock_irq(&priv->driver_lock); 933 goto out; 934 } 935 936 netif_carrier_on(dev); 937 938 if (!priv->tx_pending_len) 939 netif_wake_queue(dev); 940 941 spin_unlock_irq(&priv->driver_lock); 942 943 ret = lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 944 lbs_mesh_get_channel(priv)); 945 946 out: 947 return ret; 948 } 949 950 static const struct net_device_ops mesh_netdev_ops = { 951 .ndo_open = lbs_mesh_dev_open, 952 .ndo_stop = lbs_mesh_stop, 953 .ndo_start_xmit = lbs_hard_start_xmit, 954 .ndo_set_mac_address = lbs_set_mac_address, 955 .ndo_set_rx_mode = lbs_set_multicast_list, 956 }; 957 958 /** 959 * lbs_add_mesh - add mshX interface 960 * 961 * @priv: A pointer to the &struct lbs_private structure 962 * returns: 0 if successful, -X otherwise 963 */ 964 static int lbs_add_mesh(struct lbs_private *priv) 965 { 966 struct net_device *mesh_dev = NULL; 967 struct wireless_dev *mesh_wdev; 968 int ret = 0; 969 970 /* Allocate a virtual mesh device */ 971 mesh_wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); 972 if (!mesh_wdev) { 973 lbs_deb_mesh("init mshX wireless device failed\n"); 974 ret = -ENOMEM; 975 goto done; 976 } 977 978 mesh_dev = alloc_netdev(0, "msh%d", NET_NAME_UNKNOWN, ether_setup); 979 if (!mesh_dev) { 980 lbs_deb_mesh("init mshX device failed\n"); 981 ret = -ENOMEM; 982 goto err_free_wdev; 983 } 984 985 mesh_wdev->iftype = NL80211_IFTYPE_MESH_POINT; 986 mesh_wdev->wiphy = priv->wdev->wiphy; 987 988 if (priv->mesh_tlv) { 989 sprintf(mesh_wdev->ssid, "mesh"); 990 mesh_wdev->mesh_id_up_len = 4; 991 } 992 993 mesh_wdev->netdev = mesh_dev; 994 995 mesh_dev->ml_priv = priv; 996 mesh_dev->ieee80211_ptr = mesh_wdev; 997 priv->mesh_dev = mesh_dev; 998 999 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 /* Register virtual mesh interface */ 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 /* Everything successful */ 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 * Sending and receiving 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 * Ethtool related 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 /* Get Mesh Statistics */ 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 } 1147