Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

libertas: mesh: misc cleanup

Remove unused blindlist code.

Mark a few items const and static where possible. Involved some
code re-ordering, but no code changes.

Signed-off-by: Daniel Drake <dsd@laptop.org>
Acked-by: Dan Williams <dcbw@redhat.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by

Daniel Drake and committed by
John W. Linville
3db4f989 037b559a

+388 -601
+388 -577
drivers/net/wireless/libertas/mesh.c
··· 14 14 #include "cmd.h" 15 15 16 16 17 + static int lbs_add_mesh(struct lbs_private *priv); 18 + 19 + /*************************************************************************** 20 + * Mesh command handling 21 + */ 22 + 23 + static int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action, 24 + struct cmd_ds_mesh_access *cmd) 25 + { 26 + int ret; 27 + 28 + lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action); 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 + lbs_deb_leave(LBS_DEB_CMD); 39 + return ret; 40 + } 41 + 42 + static int __lbs_mesh_config_send(struct lbs_private *priv, 43 + struct cmd_ds_mesh_config *cmd, 44 + uint16_t action, uint16_t type) 45 + { 46 + int ret; 47 + u16 command = CMD_MESH_CONFIG_OLD; 48 + 49 + lbs_deb_enter(LBS_DEB_CMD); 50 + 51 + /* 52 + * Command id is 0xac for v10 FW along with mesh interface 53 + * id in bits 14-13-12. 54 + */ 55 + if (priv->mesh_tlv == TLV_TYPE_MESH_ID) 56 + command = CMD_MESH_CONFIG | 57 + (MESH_IFACE_ID << MESH_IFACE_BIT_OFFSET); 58 + 59 + cmd->hdr.command = cpu_to_le16(command); 60 + cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_mesh_config)); 61 + cmd->hdr.result = 0; 62 + 63 + cmd->type = cpu_to_le16(type); 64 + cmd->action = cpu_to_le16(action); 65 + 66 + ret = lbs_cmd_with_response(priv, command, cmd); 67 + 68 + lbs_deb_leave(LBS_DEB_CMD); 69 + return ret; 70 + } 71 + 72 + static int lbs_mesh_config_send(struct lbs_private *priv, 73 + struct cmd_ds_mesh_config *cmd, 74 + uint16_t action, uint16_t type) 75 + { 76 + int ret; 77 + 78 + if (!(priv->fwcapinfo & FW_CAPINFO_PERSISTENT_CONFIG)) 79 + return -EOPNOTSUPP; 80 + 81 + ret = __lbs_mesh_config_send(priv, cmd, action, type); 82 + return ret; 83 + } 84 + 85 + /* This function is the CMD_MESH_CONFIG legacy function. It only handles the 86 + * START and STOP actions. The extended actions supported by CMD_MESH_CONFIG 87 + * are all handled by preparing a struct cmd_ds_mesh_config and passing it to 88 + * lbs_mesh_config_send. 89 + */ 90 + static int lbs_mesh_config(struct lbs_private *priv, uint16_t action, 91 + uint16_t chan) 92 + { 93 + struct cmd_ds_mesh_config cmd; 94 + struct mrvl_meshie *ie; 95 + DECLARE_SSID_BUF(ssid); 96 + 97 + memset(&cmd, 0, sizeof(cmd)); 98 + cmd.channel = cpu_to_le16(chan); 99 + ie = (struct mrvl_meshie *)cmd.data; 100 + 101 + switch (action) { 102 + case CMD_ACT_MESH_CONFIG_START: 103 + ie->id = WLAN_EID_GENERIC; 104 + ie->val.oui[0] = 0x00; 105 + ie->val.oui[1] = 0x50; 106 + ie->val.oui[2] = 0x43; 107 + ie->val.type = MARVELL_MESH_IE_TYPE; 108 + ie->val.subtype = MARVELL_MESH_IE_SUBTYPE; 109 + ie->val.version = MARVELL_MESH_IE_VERSION; 110 + ie->val.active_protocol_id = MARVELL_MESH_PROTO_ID_HWMP; 111 + ie->val.active_metric_id = MARVELL_MESH_METRIC_ID; 112 + ie->val.mesh_capability = MARVELL_MESH_CAPABILITY; 113 + ie->val.mesh_id_len = priv->mesh_ssid_len; 114 + memcpy(ie->val.mesh_id, priv->mesh_ssid, priv->mesh_ssid_len); 115 + ie->len = sizeof(struct mrvl_meshie_val) - 116 + IEEE80211_MAX_SSID_LEN + priv->mesh_ssid_len; 117 + cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie_val)); 118 + break; 119 + case CMD_ACT_MESH_CONFIG_STOP: 120 + break; 121 + default: 122 + return -1; 123 + } 124 + lbs_deb_cmd("mesh config action %d type %x channel %d SSID %s\n", 125 + action, priv->mesh_tlv, chan, 126 + print_ssid(ssid, priv->mesh_ssid, priv->mesh_ssid_len)); 127 + 128 + return __lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv); 129 + } 130 + 131 + 17 132 /*************************************************************************** 18 133 * Mesh sysfs support 19 134 */ ··· 314 199 NULL, 315 200 }; 316 201 317 - static struct attribute_group lbs_mesh_attr_group = { 202 + static const struct attribute_group lbs_mesh_attr_group = { 318 203 .attrs = lbs_mesh_sysfs_entries, 319 204 }; 320 - 321 - 322 - 323 - /*************************************************************************** 324 - * Initializing and starting, stopping mesh 325 - */ 326 - 327 - /* 328 - * Check mesh FW version and appropriately send the mesh start 329 - * command 330 - */ 331 - int lbs_init_mesh(struct lbs_private *priv) 332 - { 333 - struct net_device *dev = priv->dev; 334 - int ret = 0; 335 - 336 - lbs_deb_enter(LBS_DEB_MESH); 337 - 338 - priv->mesh_connect_status = LBS_DISCONNECTED; 339 - 340 - /* Determine mesh_fw_ver from fwrelease and fwcapinfo */ 341 - /* 5.0.16p0 9.0.0.p0 is known to NOT support any mesh */ 342 - /* 5.110.22 have mesh command with 0xa3 command id */ 343 - /* 10.0.0.p0 FW brings in mesh config command with different id */ 344 - /* Check FW version MSB and initialize mesh_fw_ver */ 345 - if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5) { 346 - /* Enable mesh, if supported, and work out which TLV it uses. 347 - 0x100 + 291 is an unofficial value used in 5.110.20.pXX 348 - 0x100 + 37 is the official value used in 5.110.21.pXX 349 - but we check them in that order because 20.pXX doesn't 350 - give an error -- it just silently fails. */ 351 - 352 - /* 5.110.20.pXX firmware will fail the command if the channel 353 - doesn't match the existing channel. But only if the TLV 354 - is correct. If the channel is wrong, _BOTH_ versions will 355 - give an error to 0x100+291, and allow 0x100+37 to succeed. 356 - It's just that 5.110.20.pXX will not have done anything 357 - useful */ 358 - 359 - priv->mesh_tlv = TLV_TYPE_OLD_MESH_ID; 360 - if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 361 - priv->channel)) { 362 - priv->mesh_tlv = TLV_TYPE_MESH_ID; 363 - if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 364 - priv->channel)) 365 - priv->mesh_tlv = 0; 366 - } 367 - } else 368 - if ((MRVL_FW_MAJOR_REV(priv->fwrelease) >= MRVL_FW_V10) && 369 - (priv->fwcapinfo & MESH_CAPINFO_ENABLE_MASK)) { 370 - /* 10.0.0.pXX new firmwares should succeed with TLV 371 - * 0x100+37; Do not invoke command with old TLV. 372 - */ 373 - priv->mesh_tlv = TLV_TYPE_MESH_ID; 374 - if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 375 - priv->channel)) 376 - priv->mesh_tlv = 0; 377 - } 378 - 379 - 380 - if (priv->mesh_tlv) { 381 - sprintf(priv->mesh_ssid, "mesh"); 382 - priv->mesh_ssid_len = 4; 383 - 384 - lbs_add_mesh(priv); 385 - 386 - if (device_create_file(&dev->dev, &dev_attr_lbs_mesh)) 387 - netdev_err(dev, "cannot register lbs_mesh attribute\n"); 388 - 389 - ret = 1; 390 - } 391 - 392 - lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret); 393 - return ret; 394 - } 395 - 396 - 397 - int lbs_deinit_mesh(struct lbs_private *priv) 398 - { 399 - struct net_device *dev = priv->dev; 400 - int ret = 0; 401 - 402 - lbs_deb_enter(LBS_DEB_MESH); 403 - 404 - if (priv->mesh_tlv) { 405 - device_remove_file(&dev->dev, &dev_attr_lbs_mesh); 406 - ret = 1; 407 - } 408 - 409 - lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret); 410 - return ret; 411 - } 412 - 413 - 414 - /** 415 - * lbs_mesh_stop - close the mshX interface 416 - * 417 - * @dev: A pointer to &net_device structure 418 - * returns: 0 419 - */ 420 - static int lbs_mesh_stop(struct net_device *dev) 421 - { 422 - struct lbs_private *priv = dev->ml_priv; 423 - 424 - lbs_deb_enter(LBS_DEB_MESH); 425 - spin_lock_irq(&priv->driver_lock); 426 - 427 - priv->mesh_open = 0; 428 - priv->mesh_connect_status = LBS_DISCONNECTED; 429 - 430 - netif_stop_queue(dev); 431 - netif_carrier_off(dev); 432 - 433 - spin_unlock_irq(&priv->driver_lock); 434 - 435 - schedule_work(&priv->mcast_work); 436 - 437 - lbs_deb_leave(LBS_DEB_MESH); 438 - return 0; 439 - } 440 - 441 - /** 442 - * lbs_mesh_dev_open - open the mshX interface 443 - * 444 - * @dev: A pointer to &net_device structure 445 - * returns: 0 or -EBUSY if monitor mode active 446 - */ 447 - static int lbs_mesh_dev_open(struct net_device *dev) 448 - { 449 - struct lbs_private *priv = dev->ml_priv; 450 - int ret = 0; 451 - 452 - lbs_deb_enter(LBS_DEB_NET); 453 - 454 - spin_lock_irq(&priv->driver_lock); 455 - 456 - if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) { 457 - ret = -EBUSY; 458 - goto out; 459 - } 460 - 461 - priv->mesh_open = 1; 462 - priv->mesh_connect_status = LBS_CONNECTED; 463 - netif_carrier_on(dev); 464 - 465 - if (!priv->tx_pending_len) 466 - netif_wake_queue(dev); 467 - out: 468 - 469 - spin_unlock_irq(&priv->driver_lock); 470 - lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret); 471 - return ret; 472 - } 473 - 474 - static const struct net_device_ops mesh_netdev_ops = { 475 - .ndo_open = lbs_mesh_dev_open, 476 - .ndo_stop = lbs_mesh_stop, 477 - .ndo_start_xmit = lbs_hard_start_xmit, 478 - .ndo_set_mac_address = lbs_set_mac_address, 479 - .ndo_set_multicast_list = lbs_set_multicast_list, 480 - }; 481 - 482 - /** 483 - * lbs_add_mesh - add mshX interface 484 - * 485 - * @priv: A pointer to the &struct lbs_private structure 486 - * returns: 0 if successful, -X otherwise 487 - */ 488 - int lbs_add_mesh(struct lbs_private *priv) 489 - { 490 - struct net_device *mesh_dev = NULL; 491 - int ret = 0; 492 - 493 - lbs_deb_enter(LBS_DEB_MESH); 494 - 495 - /* Allocate a virtual mesh device */ 496 - mesh_dev = alloc_netdev(0, "msh%d", ether_setup); 497 - if (!mesh_dev) { 498 - lbs_deb_mesh("init mshX device failed\n"); 499 - ret = -ENOMEM; 500 - goto done; 501 - } 502 - mesh_dev->ml_priv = priv; 503 - priv->mesh_dev = mesh_dev; 504 - 505 - mesh_dev->netdev_ops = &mesh_netdev_ops; 506 - mesh_dev->ethtool_ops = &lbs_ethtool_ops; 507 - memcpy(mesh_dev->dev_addr, priv->dev->dev_addr, ETH_ALEN); 508 - 509 - SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent); 510 - 511 - mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST; 512 - /* Register virtual mesh interface */ 513 - ret = register_netdev(mesh_dev); 514 - if (ret) { 515 - pr_err("cannot register mshX virtual interface\n"); 516 - goto err_free; 517 - } 518 - 519 - ret = sysfs_create_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group); 520 - if (ret) 521 - goto err_unregister; 522 - 523 - lbs_persist_config_init(mesh_dev); 524 - 525 - /* Everything successful */ 526 - ret = 0; 527 - goto done; 528 - 529 - err_unregister: 530 - unregister_netdev(mesh_dev); 531 - 532 - err_free: 533 - free_netdev(mesh_dev); 534 - 535 - done: 536 - lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret); 537 - return ret; 538 - } 539 - 540 - void lbs_remove_mesh(struct lbs_private *priv) 541 - { 542 - struct net_device *mesh_dev; 543 - 544 - mesh_dev = priv->mesh_dev; 545 - if (!mesh_dev) 546 - return; 547 - 548 - lbs_deb_enter(LBS_DEB_MESH); 549 - netif_stop_queue(mesh_dev); 550 - netif_carrier_off(mesh_dev); 551 - sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group); 552 - lbs_persist_config_remove(mesh_dev); 553 - unregister_netdev(mesh_dev); 554 - priv->mesh_dev = NULL; 555 - free_netdev(mesh_dev); 556 - lbs_deb_leave(LBS_DEB_MESH); 557 - } 558 - 559 - 560 - 561 - /*************************************************************************** 562 - * Sending and receiving 563 - */ 564 - struct net_device *lbs_mesh_set_dev(struct lbs_private *priv, 565 - struct net_device *dev, struct rxpd *rxpd) 566 - { 567 - if (priv->mesh_dev) { 568 - if (priv->mesh_tlv == TLV_TYPE_OLD_MESH_ID) { 569 - if (rxpd->rx_control & RxPD_MESH_FRAME) 570 - dev = priv->mesh_dev; 571 - } else if (priv->mesh_tlv == TLV_TYPE_MESH_ID) { 572 - if (rxpd->u.bss.bss_num == MESH_IFACE_ID) 573 - dev = priv->mesh_dev; 574 - } 575 - } 576 - return dev; 577 - } 578 - 579 - 580 - void lbs_mesh_set_txpd(struct lbs_private *priv, 581 - struct net_device *dev, struct txpd *txpd) 582 - { 583 - if (dev == priv->mesh_dev) { 584 - if (priv->mesh_tlv == TLV_TYPE_OLD_MESH_ID) 585 - txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME); 586 - else if (priv->mesh_tlv == TLV_TYPE_MESH_ID) 587 - txpd->u.bss.bss_num = MESH_IFACE_ID; 588 - } 589 - } 590 - 591 - 592 - /*************************************************************************** 593 - * Mesh command handling 594 - */ 595 - 596 - /** 597 - * lbs_mesh_bt_add_del - Add or delete Mesh Blinding Table entries 598 - * 599 - * @priv: A pointer to &struct lbs_private structure 600 - * @add: TRUE to add the entry, FALSE to delete it 601 - * @addr1: Destination address to blind or unblind 602 - * 603 - * returns: 0 on success, error on failure 604 - */ 605 - int lbs_mesh_bt_add_del(struct lbs_private *priv, bool add, u8 *addr1) 606 - { 607 - struct cmd_ds_bt_access cmd; 608 - int ret = 0; 609 - 610 - lbs_deb_enter(LBS_DEB_CMD); 611 - 612 - BUG_ON(addr1 == NULL); 613 - 614 - memset(&cmd, 0, sizeof(cmd)); 615 - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 616 - memcpy(cmd.addr1, addr1, ETH_ALEN); 617 - if (add) { 618 - cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_ADD); 619 - lbs_deb_hex(LBS_DEB_MESH, "BT_ADD: blinded MAC addr", 620 - addr1, ETH_ALEN); 621 - } else { 622 - cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_DEL); 623 - lbs_deb_hex(LBS_DEB_MESH, "BT_DEL: blinded MAC addr", 624 - addr1, ETH_ALEN); 625 - } 626 - 627 - ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd); 628 - 629 - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); 630 - return ret; 631 - } 632 - 633 - /** 634 - * lbs_mesh_bt_reset - Reset/clear the mesh blinding table 635 - * 636 - * @priv: A pointer to &struct lbs_private structure 637 - * 638 - * returns: 0 on success, error on failure 639 - */ 640 - int lbs_mesh_bt_reset(struct lbs_private *priv) 641 - { 642 - struct cmd_ds_bt_access cmd; 643 - int ret = 0; 644 - 645 - lbs_deb_enter(LBS_DEB_CMD); 646 - 647 - memset(&cmd, 0, sizeof(cmd)); 648 - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 649 - cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_RESET); 650 - 651 - ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd); 652 - 653 - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); 654 - return ret; 655 - } 656 - 657 - /** 658 - * lbs_mesh_bt_get_inverted - Gets the inverted status of the mesh 659 - * blinding table 660 - * 661 - * Normally the firmware "blinds" or ignores traffic from mesh nodes in the 662 - * table, but an inverted table allows *only* traffic from nodes listed in 663 - * the table. 664 - * 665 - * @priv: A pointer to &struct lbs_private structure 666 - * @inverted: On success, TRUE if the blinding table is inverted, 667 - * FALSE if it is not inverted 668 - * 669 - * returns: 0 on success, error on failure 670 - */ 671 - int lbs_mesh_bt_get_inverted(struct lbs_private *priv, bool *inverted) 672 - { 673 - struct cmd_ds_bt_access cmd; 674 - int ret = 0; 675 - 676 - lbs_deb_enter(LBS_DEB_CMD); 677 - 678 - BUG_ON(inverted == NULL); 679 - 680 - memset(&cmd, 0, sizeof(cmd)); 681 - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 682 - cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_GET_INVERT); 683 - 684 - ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd); 685 - if (ret == 0) 686 - *inverted = !!cmd.id; 687 - 688 - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); 689 - return ret; 690 - } 691 - 692 - /** 693 - * lbs_mesh_bt_set_inverted - Sets the inverted status of the mesh 694 - * blinding table 695 - * 696 - * Normally the firmware "blinds" or ignores traffic from mesh nodes in the 697 - * table, but an inverted table allows *only* traffic from nodes listed in 698 - * the table. 699 - * 700 - * @priv: A pointer to &struct lbs_private structure 701 - * @inverted: TRUE to invert the blinding table (only traffic from 702 - * listed nodes allowed), FALSE to return it 703 - * to normal state (listed nodes ignored) 704 - * 705 - * returns: 0 on success, error on failure 706 - */ 707 - int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted) 708 - { 709 - struct cmd_ds_bt_access cmd; 710 - int ret = 0; 711 - 712 - lbs_deb_enter(LBS_DEB_CMD); 713 - 714 - memset(&cmd, 0, sizeof(cmd)); 715 - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 716 - cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_SET_INVERT); 717 - cmd.id = cpu_to_le32(!!inverted); 718 - 719 - ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd); 720 - 721 - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); 722 - return ret; 723 - } 724 - 725 - /** 726 - * lbs_mesh_bt_get_entry - List an entry in the mesh blinding table 727 - * 728 - * @priv: A pointer to &struct lbs_private structure 729 - * @id: The ID of the entry to list 730 - * @addr1: MAC address associated with the table entry 731 - * 732 - * returns: 0 on success, error on failure 733 - */ 734 - int lbs_mesh_bt_get_entry(struct lbs_private *priv, u32 id, u8 *addr1) 735 - { 736 - struct cmd_ds_bt_access cmd; 737 - int ret = 0; 738 - 739 - lbs_deb_enter(LBS_DEB_CMD); 740 - 741 - BUG_ON(addr1 == NULL); 742 - 743 - memset(&cmd, 0, sizeof(cmd)); 744 - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 745 - cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_SET_INVERT); 746 - cmd.id = cpu_to_le32(id); 747 - 748 - ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd); 749 - if (ret == 0) 750 - memcpy(addr1, cmd.addr1, sizeof(cmd.addr1)); 751 - 752 - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); 753 - return ret; 754 - } 755 - 756 - /** 757 - * lbs_cmd_fwt_access - Access the mesh forwarding table 758 - * 759 - * @priv: A pointer to &struct lbs_private structure 760 - * @cmd_action: The forwarding table action to perform 761 - * @cmd: The pre-filled FWT_ACCESS command 762 - * 763 - * returns: 0 on success and 'cmd' will be filled with the 764 - * firmware's response 765 - */ 766 - int lbs_cmd_fwt_access(struct lbs_private *priv, u16 cmd_action, 767 - struct cmd_ds_fwt_access *cmd) 768 - { 769 - int ret; 770 - 771 - lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action); 772 - 773 - cmd->hdr.command = cpu_to_le16(CMD_FWT_ACCESS); 774 - cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_fwt_access)); 775 - cmd->hdr.result = 0; 776 - cmd->action = cpu_to_le16(cmd_action); 777 - 778 - ret = lbs_cmd_with_response(priv, CMD_FWT_ACCESS, cmd); 779 - 780 - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); 781 - return 0; 782 - } 783 - 784 - int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action, 785 - struct cmd_ds_mesh_access *cmd) 786 - { 787 - int ret; 788 - 789 - lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action); 790 - 791 - cmd->hdr.command = cpu_to_le16(CMD_MESH_ACCESS); 792 - cmd->hdr.size = cpu_to_le16(sizeof(*cmd)); 793 - cmd->hdr.result = 0; 794 - 795 - cmd->action = cpu_to_le16(cmd_action); 796 - 797 - ret = lbs_cmd_with_response(priv, CMD_MESH_ACCESS, cmd); 798 - 799 - lbs_deb_leave(LBS_DEB_CMD); 800 - return ret; 801 - } 802 - 803 - static int __lbs_mesh_config_send(struct lbs_private *priv, 804 - struct cmd_ds_mesh_config *cmd, 805 - uint16_t action, uint16_t type) 806 - { 807 - int ret; 808 - u16 command = CMD_MESH_CONFIG_OLD; 809 - 810 - lbs_deb_enter(LBS_DEB_CMD); 811 - 812 - /* 813 - * Command id is 0xac for v10 FW along with mesh interface 814 - * id in bits 14-13-12. 815 - */ 816 - if (priv->mesh_tlv == TLV_TYPE_MESH_ID) 817 - command = CMD_MESH_CONFIG | 818 - (MESH_IFACE_ID << MESH_IFACE_BIT_OFFSET); 819 - 820 - cmd->hdr.command = cpu_to_le16(command); 821 - cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_mesh_config)); 822 - cmd->hdr.result = 0; 823 - 824 - cmd->type = cpu_to_le16(type); 825 - cmd->action = cpu_to_le16(action); 826 - 827 - ret = lbs_cmd_with_response(priv, command, cmd); 828 - 829 - lbs_deb_leave(LBS_DEB_CMD); 830 - return ret; 831 - } 832 - 833 - int lbs_mesh_config_send(struct lbs_private *priv, 834 - struct cmd_ds_mesh_config *cmd, 835 - uint16_t action, uint16_t type) 836 - { 837 - int ret; 838 - 839 - if (!(priv->fwcapinfo & FW_CAPINFO_PERSISTENT_CONFIG)) 840 - return -EOPNOTSUPP; 841 - 842 - ret = __lbs_mesh_config_send(priv, cmd, action, type); 843 - return ret; 844 - } 845 - 846 - /* This function is the CMD_MESH_CONFIG legacy function. It only handles the 847 - * START and STOP actions. The extended actions supported by CMD_MESH_CONFIG 848 - * are all handled by preparing a struct cmd_ds_mesh_config and passing it to 849 - * lbs_mesh_config_send. 850 - */ 851 - int lbs_mesh_config(struct lbs_private *priv, uint16_t action, uint16_t chan) 852 - { 853 - struct cmd_ds_mesh_config cmd; 854 - struct mrvl_meshie *ie; 855 - DECLARE_SSID_BUF(ssid); 856 - 857 - memset(&cmd, 0, sizeof(cmd)); 858 - cmd.channel = cpu_to_le16(chan); 859 - ie = (struct mrvl_meshie *)cmd.data; 860 - 861 - switch (action) { 862 - case CMD_ACT_MESH_CONFIG_START: 863 - ie->id = WLAN_EID_GENERIC; 864 - ie->val.oui[0] = 0x00; 865 - ie->val.oui[1] = 0x50; 866 - ie->val.oui[2] = 0x43; 867 - ie->val.type = MARVELL_MESH_IE_TYPE; 868 - ie->val.subtype = MARVELL_MESH_IE_SUBTYPE; 869 - ie->val.version = MARVELL_MESH_IE_VERSION; 870 - ie->val.active_protocol_id = MARVELL_MESH_PROTO_ID_HWMP; 871 - ie->val.active_metric_id = MARVELL_MESH_METRIC_ID; 872 - ie->val.mesh_capability = MARVELL_MESH_CAPABILITY; 873 - ie->val.mesh_id_len = priv->mesh_ssid_len; 874 - memcpy(ie->val.mesh_id, priv->mesh_ssid, priv->mesh_ssid_len); 875 - ie->len = sizeof(struct mrvl_meshie_val) - 876 - IEEE80211_MAX_SSID_LEN + priv->mesh_ssid_len; 877 - cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie_val)); 878 - break; 879 - case CMD_ACT_MESH_CONFIG_STOP: 880 - break; 881 - default: 882 - return -1; 883 - } 884 - lbs_deb_cmd("mesh config action %d type %x channel %d SSID %s\n", 885 - action, priv->mesh_tlv, chan, 886 - print_ssid(ssid, priv->mesh_ssid, priv->mesh_ssid_len)); 887 - 888 - return __lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv); 889 - } 890 - 891 205 892 206 893 207 /*************************************************************************** ··· 775 1231 NULL 776 1232 }; 777 1233 778 - static struct attribute_group boot_opts_group = { 1234 + static const struct attribute_group boot_opts_group = { 779 1235 .name = "boot_options", 780 1236 .attrs = boot_opts_attrs, 781 1237 }; ··· 788 1244 NULL 789 1245 }; 790 1246 791 - static struct attribute_group mesh_ie_group = { 1247 + static const struct attribute_group mesh_ie_group = { 792 1248 .name = "mesh_ie", 793 1249 .attrs = mesh_ie_attrs, 794 1250 }; 795 1251 796 - void lbs_persist_config_init(struct net_device *dev) 1252 + static void lbs_persist_config_init(struct net_device *dev) 797 1253 { 798 1254 int ret; 799 1255 ret = sysfs_create_group(&(dev->dev.kobj), &boot_opts_group); 800 1256 ret = sysfs_create_group(&(dev->dev.kobj), &mesh_ie_group); 801 1257 } 802 1258 803 - void lbs_persist_config_remove(struct net_device *dev) 1259 + static void lbs_persist_config_remove(struct net_device *dev) 804 1260 { 805 1261 sysfs_remove_group(&(dev->dev.kobj), &boot_opts_group); 806 1262 sysfs_remove_group(&(dev->dev.kobj), &mesh_ie_group); 807 1263 } 808 1264 809 1265 1266 + /*************************************************************************** 1267 + * Initializing and starting, stopping mesh 1268 + */ 1269 + 1270 + /* 1271 + * Check mesh FW version and appropriately send the mesh start 1272 + * command 1273 + */ 1274 + int lbs_init_mesh(struct lbs_private *priv) 1275 + { 1276 + struct net_device *dev = priv->dev; 1277 + int ret = 0; 1278 + 1279 + lbs_deb_enter(LBS_DEB_MESH); 1280 + 1281 + priv->mesh_connect_status = LBS_DISCONNECTED; 1282 + 1283 + /* Determine mesh_fw_ver from fwrelease and fwcapinfo */ 1284 + /* 5.0.16p0 9.0.0.p0 is known to NOT support any mesh */ 1285 + /* 5.110.22 have mesh command with 0xa3 command id */ 1286 + /* 10.0.0.p0 FW brings in mesh config command with different id */ 1287 + /* Check FW version MSB and initialize mesh_fw_ver */ 1288 + if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5) { 1289 + /* Enable mesh, if supported, and work out which TLV it uses. 1290 + 0x100 + 291 is an unofficial value used in 5.110.20.pXX 1291 + 0x100 + 37 is the official value used in 5.110.21.pXX 1292 + but we check them in that order because 20.pXX doesn't 1293 + give an error -- it just silently fails. */ 1294 + 1295 + /* 5.110.20.pXX firmware will fail the command if the channel 1296 + doesn't match the existing channel. But only if the TLV 1297 + is correct. If the channel is wrong, _BOTH_ versions will 1298 + give an error to 0x100+291, and allow 0x100+37 to succeed. 1299 + It's just that 5.110.20.pXX will not have done anything 1300 + useful */ 1301 + 1302 + priv->mesh_tlv = TLV_TYPE_OLD_MESH_ID; 1303 + if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 1304 + priv->channel)) { 1305 + priv->mesh_tlv = TLV_TYPE_MESH_ID; 1306 + if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 1307 + priv->channel)) 1308 + priv->mesh_tlv = 0; 1309 + } 1310 + } else 1311 + if ((MRVL_FW_MAJOR_REV(priv->fwrelease) >= MRVL_FW_V10) && 1312 + (priv->fwcapinfo & MESH_CAPINFO_ENABLE_MASK)) { 1313 + /* 10.0.0.pXX new firmwares should succeed with TLV 1314 + * 0x100+37; Do not invoke command with old TLV. 1315 + */ 1316 + priv->mesh_tlv = TLV_TYPE_MESH_ID; 1317 + if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, 1318 + priv->channel)) 1319 + priv->mesh_tlv = 0; 1320 + } 1321 + 1322 + 1323 + if (priv->mesh_tlv) { 1324 + sprintf(priv->mesh_ssid, "mesh"); 1325 + priv->mesh_ssid_len = 4; 1326 + 1327 + lbs_add_mesh(priv); 1328 + 1329 + if (device_create_file(&dev->dev, &dev_attr_lbs_mesh)) 1330 + netdev_err(dev, "cannot register lbs_mesh attribute\n"); 1331 + 1332 + ret = 1; 1333 + } 1334 + 1335 + lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret); 1336 + return ret; 1337 + } 1338 + 1339 + 1340 + int lbs_deinit_mesh(struct lbs_private *priv) 1341 + { 1342 + struct net_device *dev = priv->dev; 1343 + int ret = 0; 1344 + 1345 + lbs_deb_enter(LBS_DEB_MESH); 1346 + 1347 + if (priv->mesh_tlv) { 1348 + device_remove_file(&dev->dev, &dev_attr_lbs_mesh); 1349 + ret = 1; 1350 + } 1351 + 1352 + lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret); 1353 + return ret; 1354 + } 1355 + 1356 + 1357 + /** 1358 + * lbs_mesh_stop - close the mshX interface 1359 + * 1360 + * @dev: A pointer to &net_device structure 1361 + * returns: 0 1362 + */ 1363 + static int lbs_mesh_stop(struct net_device *dev) 1364 + { 1365 + struct lbs_private *priv = dev->ml_priv; 1366 + 1367 + lbs_deb_enter(LBS_DEB_MESH); 1368 + spin_lock_irq(&priv->driver_lock); 1369 + 1370 + priv->mesh_open = 0; 1371 + priv->mesh_connect_status = LBS_DISCONNECTED; 1372 + 1373 + netif_stop_queue(dev); 1374 + netif_carrier_off(dev); 1375 + 1376 + spin_unlock_irq(&priv->driver_lock); 1377 + 1378 + schedule_work(&priv->mcast_work); 1379 + 1380 + lbs_deb_leave(LBS_DEB_MESH); 1381 + return 0; 1382 + } 1383 + 1384 + /** 1385 + * lbs_mesh_dev_open - open the mshX interface 1386 + * 1387 + * @dev: A pointer to &net_device structure 1388 + * returns: 0 or -EBUSY if monitor mode active 1389 + */ 1390 + static int lbs_mesh_dev_open(struct net_device *dev) 1391 + { 1392 + struct lbs_private *priv = dev->ml_priv; 1393 + int ret = 0; 1394 + 1395 + lbs_deb_enter(LBS_DEB_NET); 1396 + 1397 + spin_lock_irq(&priv->driver_lock); 1398 + 1399 + if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) { 1400 + ret = -EBUSY; 1401 + goto out; 1402 + } 1403 + 1404 + priv->mesh_open = 1; 1405 + priv->mesh_connect_status = LBS_CONNECTED; 1406 + netif_carrier_on(dev); 1407 + 1408 + if (!priv->tx_pending_len) 1409 + netif_wake_queue(dev); 1410 + out: 1411 + 1412 + spin_unlock_irq(&priv->driver_lock); 1413 + lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret); 1414 + return ret; 1415 + } 1416 + 1417 + static const struct net_device_ops mesh_netdev_ops = { 1418 + .ndo_open = lbs_mesh_dev_open, 1419 + .ndo_stop = lbs_mesh_stop, 1420 + .ndo_start_xmit = lbs_hard_start_xmit, 1421 + .ndo_set_mac_address = lbs_set_mac_address, 1422 + .ndo_set_multicast_list = lbs_set_multicast_list, 1423 + }; 1424 + 1425 + /** 1426 + * lbs_add_mesh - add mshX interface 1427 + * 1428 + * @priv: A pointer to the &struct lbs_private structure 1429 + * returns: 0 if successful, -X otherwise 1430 + */ 1431 + static int lbs_add_mesh(struct lbs_private *priv) 1432 + { 1433 + struct net_device *mesh_dev = NULL; 1434 + int ret = 0; 1435 + 1436 + lbs_deb_enter(LBS_DEB_MESH); 1437 + 1438 + /* Allocate a virtual mesh device */ 1439 + mesh_dev = alloc_netdev(0, "msh%d", ether_setup); 1440 + if (!mesh_dev) { 1441 + lbs_deb_mesh("init mshX device failed\n"); 1442 + ret = -ENOMEM; 1443 + goto done; 1444 + } 1445 + mesh_dev->ml_priv = priv; 1446 + priv->mesh_dev = mesh_dev; 1447 + 1448 + mesh_dev->netdev_ops = &mesh_netdev_ops; 1449 + mesh_dev->ethtool_ops = &lbs_ethtool_ops; 1450 + memcpy(mesh_dev->dev_addr, priv->dev->dev_addr, ETH_ALEN); 1451 + 1452 + SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent); 1453 + 1454 + mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST; 1455 + /* Register virtual mesh interface */ 1456 + ret = register_netdev(mesh_dev); 1457 + if (ret) { 1458 + pr_err("cannot register mshX virtual interface\n"); 1459 + goto err_free; 1460 + } 1461 + 1462 + ret = sysfs_create_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group); 1463 + if (ret) 1464 + goto err_unregister; 1465 + 1466 + lbs_persist_config_init(mesh_dev); 1467 + 1468 + /* Everything successful */ 1469 + ret = 0; 1470 + goto done; 1471 + 1472 + err_unregister: 1473 + unregister_netdev(mesh_dev); 1474 + 1475 + err_free: 1476 + free_netdev(mesh_dev); 1477 + 1478 + done: 1479 + lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret); 1480 + return ret; 1481 + } 1482 + 1483 + void lbs_remove_mesh(struct lbs_private *priv) 1484 + { 1485 + struct net_device *mesh_dev; 1486 + 1487 + mesh_dev = priv->mesh_dev; 1488 + if (!mesh_dev) 1489 + return; 1490 + 1491 + lbs_deb_enter(LBS_DEB_MESH); 1492 + netif_stop_queue(mesh_dev); 1493 + netif_carrier_off(mesh_dev); 1494 + sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group); 1495 + lbs_persist_config_remove(mesh_dev); 1496 + unregister_netdev(mesh_dev); 1497 + priv->mesh_dev = NULL; 1498 + free_netdev(mesh_dev); 1499 + lbs_deb_leave(LBS_DEB_MESH); 1500 + } 1501 + 1502 + 1503 + /*************************************************************************** 1504 + * Sending and receiving 1505 + */ 1506 + struct net_device *lbs_mesh_set_dev(struct lbs_private *priv, 1507 + struct net_device *dev, struct rxpd *rxpd) 1508 + { 1509 + if (priv->mesh_dev) { 1510 + if (priv->mesh_tlv == TLV_TYPE_OLD_MESH_ID) { 1511 + if (rxpd->rx_control & RxPD_MESH_FRAME) 1512 + dev = priv->mesh_dev; 1513 + } else if (priv->mesh_tlv == TLV_TYPE_MESH_ID) { 1514 + if (rxpd->u.bss.bss_num == MESH_IFACE_ID) 1515 + dev = priv->mesh_dev; 1516 + } 1517 + } 1518 + return dev; 1519 + } 1520 + 1521 + 1522 + void lbs_mesh_set_txpd(struct lbs_private *priv, 1523 + struct net_device *dev, struct txpd *txpd) 1524 + { 1525 + if (dev == priv->mesh_dev) { 1526 + if (priv->mesh_tlv == TLV_TYPE_OLD_MESH_ID) 1527 + txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME); 1528 + else if (priv->mesh_tlv == TLV_TYPE_MESH_ID) 1529 + txpd->u.bss.bss_num = MESH_IFACE_ID; 1530 + } 1531 + } 1532 + 810 1533 811 1534 /*************************************************************************** 812 1535 * Ethtool related 813 1536 */ 814 1537 815 - static const char *mesh_stat_strings[] = { 1538 + static const char * const mesh_stat_strings[] = { 816 1539 "drop_duplicate_bcast", 817 1540 "drop_ttl_zero", 818 1541 "drop_no_fwd_route",
-24
drivers/net/wireless/libertas/mesh.h
··· 31 31 int lbs_init_mesh(struct lbs_private *priv); 32 32 int lbs_deinit_mesh(struct lbs_private *priv); 33 33 34 - int lbs_add_mesh(struct lbs_private *priv); 35 34 void lbs_remove_mesh(struct lbs_private *priv); 36 35 37 36 ··· 50 51 struct cmd_ds_command; 51 52 struct cmd_ds_mesh_access; 52 53 struct cmd_ds_mesh_config; 53 - 54 - int lbs_mesh_bt_add_del(struct lbs_private *priv, bool add, u8 *addr1); 55 - int lbs_mesh_bt_reset(struct lbs_private *priv); 56 - int lbs_mesh_bt_get_inverted(struct lbs_private *priv, bool *inverted); 57 - int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted); 58 - int lbs_mesh_bt_get_entry(struct lbs_private *priv, u32 id, u8 *addr1); 59 - 60 - int lbs_cmd_fwt_access(struct lbs_private *priv, u16 cmd_action, 61 - struct cmd_ds_fwt_access *cmd); 62 - 63 - int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action, 64 - struct cmd_ds_mesh_access *cmd); 65 - int lbs_mesh_config_send(struct lbs_private *priv, 66 - struct cmd_ds_mesh_config *cmd, 67 - uint16_t action, uint16_t type); 68 - int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan); 69 - 70 - 71 - 72 - /* Persistent configuration */ 73 - 74 - void lbs_persist_config_init(struct net_device *net); 75 - void lbs_persist_config_remove(struct net_device *net); 76 54 77 55 78 56 /* Ethtool statistics */