| .. | .. |
|---|
| 17 | 17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|---|
| 18 | 18 | */ |
|---|
| 19 | 19 | |
|---|
| 20 | | -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
|---|
| 21 | | - |
|---|
| 22 | 20 | #include <linux/delay.h> |
|---|
| 23 | 21 | #include <linux/export.h> |
|---|
| 24 | 22 | #include <linux/gpio.h> |
|---|
| .. | .. |
|---|
| 26 | 24 | #include <linux/module.h> |
|---|
| 27 | 25 | #include <linux/platform_data/b53.h> |
|---|
| 28 | 26 | #include <linux/phy.h> |
|---|
| 27 | +#include <linux/phylink.h> |
|---|
| 29 | 28 | #include <linux/etherdevice.h> |
|---|
| 30 | 29 | #include <linux/if_bridge.h> |
|---|
| 31 | 30 | #include <net/dsa.h> |
|---|
| .. | .. |
|---|
| 341 | 340 | b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_CTRL, &mgmt); |
|---|
| 342 | 341 | mgmt |= B53_MII_DUMB_FWDG_EN; |
|---|
| 343 | 342 | b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_CTRL, mgmt); |
|---|
| 343 | + |
|---|
| 344 | + /* Look at B53_UC_FWD_EN and B53_MC_FWD_EN to decide whether |
|---|
| 345 | + * frames should be flooded or not. |
|---|
| 346 | + */ |
|---|
| 347 | + b53_read8(dev, B53_CTRL_PAGE, B53_IP_MULTICAST_CTRL, &mgmt); |
|---|
| 348 | + mgmt |= B53_UC_FWD_EN | B53_MC_FWD_EN | B53_IPMC_FWD_EN; |
|---|
| 349 | + b53_write8(dev, B53_CTRL_PAGE, B53_IP_MULTICAST_CTRL, mgmt); |
|---|
| 344 | 350 | } |
|---|
| 345 | 351 | |
|---|
| 346 | 352 | static void b53_enable_vlan(struct b53_device *dev, bool enable, |
|---|
| .. | .. |
|---|
| 362 | 368 | b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL4, &vc4); |
|---|
| 363 | 369 | b53_read8(dev, B53_VLAN_PAGE, B53_VLAN_CTRL5, &vc5); |
|---|
| 364 | 370 | } |
|---|
| 365 | | - |
|---|
| 366 | | - mgmt &= ~SM_SW_FWD_MODE; |
|---|
| 367 | 371 | |
|---|
| 368 | 372 | if (enable) { |
|---|
| 369 | 373 | vc0 |= VC0_VLAN_EN | VC0_VID_CHK_EN | VC0_VID_HASH_VID; |
|---|
| .. | .. |
|---|
| 427 | 431 | b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, mgmt); |
|---|
| 428 | 432 | |
|---|
| 429 | 433 | dev->vlan_enabled = enable; |
|---|
| 430 | | - dev->vlan_filtering_enabled = enable_filtering; |
|---|
| 431 | 434 | } |
|---|
| 432 | 435 | |
|---|
| 433 | 436 | static int b53_set_jumbo(struct b53_device *dev, bool enable, bool allow_10_100) |
|---|
| .. | .. |
|---|
| 523 | 526 | int b53_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy) |
|---|
| 524 | 527 | { |
|---|
| 525 | 528 | struct b53_device *dev = ds->priv; |
|---|
| 526 | | - unsigned int cpu_port = ds->ports[port].cpu_dp->index; |
|---|
| 529 | + unsigned int cpu_port; |
|---|
| 530 | + int ret = 0; |
|---|
| 527 | 531 | u16 pvlan; |
|---|
| 528 | 532 | |
|---|
| 533 | + if (!dsa_is_user_port(ds, port)) |
|---|
| 534 | + return 0; |
|---|
| 535 | + |
|---|
| 536 | + cpu_port = dsa_to_port(ds, port)->cpu_dp->index; |
|---|
| 537 | + |
|---|
| 538 | + b53_br_egress_floods(ds, port, true, true); |
|---|
| 529 | 539 | b53_port_set_learning(dev, port, false); |
|---|
| 540 | + |
|---|
| 541 | + if (dev->ops->irq_enable) |
|---|
| 542 | + ret = dev->ops->irq_enable(dev, port); |
|---|
| 543 | + if (ret) |
|---|
| 544 | + return ret; |
|---|
| 530 | 545 | |
|---|
| 531 | 546 | /* Clear the Rx and Tx disable bits and set to no spanning tree */ |
|---|
| 532 | 547 | b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), 0); |
|---|
| .. | .. |
|---|
| 551 | 566 | } |
|---|
| 552 | 567 | EXPORT_SYMBOL(b53_enable_port); |
|---|
| 553 | 568 | |
|---|
| 554 | | -void b53_disable_port(struct dsa_switch *ds, int port, struct phy_device *phy) |
|---|
| 569 | +void b53_disable_port(struct dsa_switch *ds, int port) |
|---|
| 555 | 570 | { |
|---|
| 556 | 571 | struct b53_device *dev = ds->priv; |
|---|
| 557 | 572 | u8 reg; |
|---|
| .. | .. |
|---|
| 560 | 575 | b53_read8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), ®); |
|---|
| 561 | 576 | reg |= PORT_CTRL_RX_DISABLE | PORT_CTRL_TX_DISABLE; |
|---|
| 562 | 577 | b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), reg); |
|---|
| 578 | + |
|---|
| 579 | + if (dev->ops->irq_disable) |
|---|
| 580 | + dev->ops->irq_disable(dev, port); |
|---|
| 563 | 581 | } |
|---|
| 564 | 582 | EXPORT_SYMBOL(b53_disable_port); |
|---|
| 565 | 583 | |
|---|
| 566 | 584 | void b53_brcm_hdr_setup(struct dsa_switch *ds, int port) |
|---|
| 567 | 585 | { |
|---|
| 568 | | - bool tag_en = !(ds->ops->get_tag_protocol(ds, port) == |
|---|
| 569 | | - DSA_TAG_PROTO_NONE); |
|---|
| 570 | 586 | struct b53_device *dev = ds->priv; |
|---|
| 587 | + bool tag_en = !(dev->tag_protocol == DSA_TAG_PROTO_NONE); |
|---|
| 571 | 588 | u8 hdr_ctl, val; |
|---|
| 572 | 589 | u16 reg; |
|---|
| 573 | 590 | |
|---|
| .. | .. |
|---|
| 586 | 603 | val = 0; |
|---|
| 587 | 604 | break; |
|---|
| 588 | 605 | } |
|---|
| 606 | + |
|---|
| 607 | + /* Enable management mode if tagging is requested */ |
|---|
| 608 | + b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &hdr_ctl); |
|---|
| 609 | + if (tag_en) |
|---|
| 610 | + hdr_ctl |= SM_SW_FWD_MODE; |
|---|
| 611 | + else |
|---|
| 612 | + hdr_ctl &= ~SM_SW_FWD_MODE; |
|---|
| 613 | + b53_write8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, hdr_ctl); |
|---|
| 614 | + |
|---|
| 615 | + /* Configure the appropriate IMP port */ |
|---|
| 616 | + b53_read8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, &hdr_ctl); |
|---|
| 617 | + if (port == 8) |
|---|
| 618 | + hdr_ctl |= GC_FRM_MGMT_PORT_MII; |
|---|
| 619 | + else if (port == 5) |
|---|
| 620 | + hdr_ctl |= GC_FRM_MGMT_PORT_M; |
|---|
| 621 | + b53_write8(dev, B53_MGMT_PAGE, B53_GLOBAL_CONFIG, hdr_ctl); |
|---|
| 589 | 622 | |
|---|
| 590 | 623 | /* Enable Broadcom tags for IMP port */ |
|---|
| 591 | 624 | b53_read8(dev, B53_MGMT_PAGE, B53_BRCM_HDR, &hdr_ctl); |
|---|
| .. | .. |
|---|
| 635 | 668 | b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), port_ctrl); |
|---|
| 636 | 669 | |
|---|
| 637 | 670 | b53_brcm_hdr_setup(dev->ds, port); |
|---|
| 671 | + |
|---|
| 672 | + b53_br_egress_floods(dev->ds, port, true, true); |
|---|
| 638 | 673 | b53_port_set_learning(dev, port, false); |
|---|
| 639 | 674 | } |
|---|
| 640 | 675 | |
|---|
| .. | .. |
|---|
| 659 | 694 | { |
|---|
| 660 | 695 | struct b53_device *dev = ds->priv; |
|---|
| 661 | 696 | struct b53_vlan vl = { 0 }; |
|---|
| 697 | + struct b53_vlan *v; |
|---|
| 662 | 698 | int i, def_vid; |
|---|
| 699 | + u16 vid; |
|---|
| 663 | 700 | |
|---|
| 664 | 701 | def_vid = b53_default_pvid(dev); |
|---|
| 665 | 702 | |
|---|
| .. | .. |
|---|
| 671 | 708 | b53_do_vlan_op(dev, VTA_CMD_CLEAR); |
|---|
| 672 | 709 | } |
|---|
| 673 | 710 | |
|---|
| 674 | | - b53_enable_vlan(dev, dev->vlan_enabled, dev->vlan_filtering_enabled); |
|---|
| 711 | + b53_enable_vlan(dev, dev->vlan_enabled, ds->vlan_filtering); |
|---|
| 675 | 712 | |
|---|
| 676 | 713 | b53_for_each_port(dev, i) |
|---|
| 677 | 714 | b53_write16(dev, B53_VLAN_PAGE, |
|---|
| 678 | 715 | B53_VLAN_PORT_DEF_TAG(i), def_vid); |
|---|
| 679 | 716 | |
|---|
| 680 | | - if (!is5325(dev) && !is5365(dev)) |
|---|
| 681 | | - b53_set_jumbo(dev, dev->enable_jumbo, false); |
|---|
| 717 | + /* Upon initial call we have not set-up any VLANs, but upon |
|---|
| 718 | + * system resume, we need to restore all VLAN entries. |
|---|
| 719 | + */ |
|---|
| 720 | + for (vid = def_vid; vid < dev->num_vlans; vid++) { |
|---|
| 721 | + v = &dev->vlans[vid]; |
|---|
| 722 | + |
|---|
| 723 | + if (!v->members) |
|---|
| 724 | + continue; |
|---|
| 725 | + |
|---|
| 726 | + b53_set_vlan_entry(dev, vid, v); |
|---|
| 727 | + b53_fast_age_vlan(dev, vid); |
|---|
| 728 | + } |
|---|
| 682 | 729 | |
|---|
| 683 | 730 | return 0; |
|---|
| 684 | 731 | } |
|---|
| .. | .. |
|---|
| 733 | 780 | usleep_range(1000, 2000); |
|---|
| 734 | 781 | } while (timeout-- > 0); |
|---|
| 735 | 782 | |
|---|
| 736 | | - if (timeout == 0) |
|---|
| 783 | + if (timeout == 0) { |
|---|
| 784 | + dev_err(dev->dev, |
|---|
| 785 | + "Timeout waiting for SW_RST to clear!\n"); |
|---|
| 737 | 786 | return -ETIMEDOUT; |
|---|
| 787 | + } |
|---|
| 738 | 788 | } |
|---|
| 739 | 789 | |
|---|
| 740 | 790 | b53_read8(dev, B53_CTRL_PAGE, B53_SWITCH_MODE, &mgmt); |
|---|
| .. | .. |
|---|
| 785 | 835 | static int b53_reset_switch(struct b53_device *priv) |
|---|
| 786 | 836 | { |
|---|
| 787 | 837 | /* reset vlans */ |
|---|
| 788 | | - priv->enable_jumbo = false; |
|---|
| 789 | | - |
|---|
| 790 | 838 | memset(priv->vlans, 0, sizeof(*priv->vlans) * priv->num_vlans); |
|---|
| 791 | 839 | memset(priv->ports, 0, sizeof(*priv->ports) * priv->num_ports); |
|---|
| 840 | + |
|---|
| 841 | + priv->serdes_lane = B53_INVALID_LANE; |
|---|
| 792 | 842 | |
|---|
| 793 | 843 | return b53_switch_reset(priv); |
|---|
| 794 | 844 | } |
|---|
| .. | .. |
|---|
| 942 | 992 | } |
|---|
| 943 | 993 | EXPORT_SYMBOL(b53_get_sset_count); |
|---|
| 944 | 994 | |
|---|
| 995 | +enum b53_devlink_resource_id { |
|---|
| 996 | + B53_DEVLINK_PARAM_ID_VLAN_TABLE, |
|---|
| 997 | +}; |
|---|
| 998 | + |
|---|
| 999 | +static u64 b53_devlink_vlan_table_get(void *priv) |
|---|
| 1000 | +{ |
|---|
| 1001 | + struct b53_device *dev = priv; |
|---|
| 1002 | + struct b53_vlan *vl; |
|---|
| 1003 | + unsigned int i; |
|---|
| 1004 | + u64 count = 0; |
|---|
| 1005 | + |
|---|
| 1006 | + for (i = 0; i < dev->num_vlans; i++) { |
|---|
| 1007 | + vl = &dev->vlans[i]; |
|---|
| 1008 | + if (vl->members) |
|---|
| 1009 | + count++; |
|---|
| 1010 | + } |
|---|
| 1011 | + |
|---|
| 1012 | + return count; |
|---|
| 1013 | +} |
|---|
| 1014 | + |
|---|
| 1015 | +int b53_setup_devlink_resources(struct dsa_switch *ds) |
|---|
| 1016 | +{ |
|---|
| 1017 | + struct devlink_resource_size_params size_params; |
|---|
| 1018 | + struct b53_device *dev = ds->priv; |
|---|
| 1019 | + int err; |
|---|
| 1020 | + |
|---|
| 1021 | + devlink_resource_size_params_init(&size_params, dev->num_vlans, |
|---|
| 1022 | + dev->num_vlans, |
|---|
| 1023 | + 1, DEVLINK_RESOURCE_UNIT_ENTRY); |
|---|
| 1024 | + |
|---|
| 1025 | + err = dsa_devlink_resource_register(ds, "VLAN", dev->num_vlans, |
|---|
| 1026 | + B53_DEVLINK_PARAM_ID_VLAN_TABLE, |
|---|
| 1027 | + DEVLINK_RESOURCE_ID_PARENT_TOP, |
|---|
| 1028 | + &size_params); |
|---|
| 1029 | + if (err) |
|---|
| 1030 | + goto out; |
|---|
| 1031 | + |
|---|
| 1032 | + dsa_devlink_resource_occ_get_register(ds, |
|---|
| 1033 | + B53_DEVLINK_PARAM_ID_VLAN_TABLE, |
|---|
| 1034 | + b53_devlink_vlan_table_get, dev); |
|---|
| 1035 | + |
|---|
| 1036 | + return 0; |
|---|
| 1037 | +out: |
|---|
| 1038 | + dsa_devlink_resources_unregister(ds); |
|---|
| 1039 | + return err; |
|---|
| 1040 | +} |
|---|
| 1041 | +EXPORT_SYMBOL(b53_setup_devlink_resources); |
|---|
| 1042 | + |
|---|
| 945 | 1043 | static int b53_setup(struct dsa_switch *ds) |
|---|
| 946 | 1044 | { |
|---|
| 947 | 1045 | struct b53_device *dev = ds->priv; |
|---|
| .. | .. |
|---|
| 957 | 1055 | b53_reset_mib(dev); |
|---|
| 958 | 1056 | |
|---|
| 959 | 1057 | ret = b53_apply_config(dev); |
|---|
| 960 | | - if (ret) |
|---|
| 1058 | + if (ret) { |
|---|
| 961 | 1059 | dev_err(ds->dev, "failed to apply configuration\n"); |
|---|
| 1060 | + return ret; |
|---|
| 1061 | + } |
|---|
| 962 | 1062 | |
|---|
| 963 | | - /* Configure IMP/CPU port, disable unused ports. Enabled |
|---|
| 1063 | + /* Configure IMP/CPU port, disable all other ports. Enabled |
|---|
| 964 | 1064 | * ports will be configured with .port_enable |
|---|
| 965 | 1065 | */ |
|---|
| 966 | 1066 | for (port = 0; port < dev->num_ports; port++) { |
|---|
| 967 | 1067 | if (dsa_is_cpu_port(ds, port)) |
|---|
| 968 | 1068 | b53_enable_cpu_port(dev, port); |
|---|
| 969 | | - else if (dsa_is_unused_port(ds, port)) |
|---|
| 970 | | - b53_disable_port(ds, port, NULL); |
|---|
| 1069 | + else |
|---|
| 1070 | + b53_disable_port(ds, port); |
|---|
| 971 | 1071 | } |
|---|
| 972 | 1072 | |
|---|
| 973 | | - return ret; |
|---|
| 1073 | + return b53_setup_devlink_resources(ds); |
|---|
| 974 | 1074 | } |
|---|
| 975 | 1075 | |
|---|
| 976 | | -static void b53_adjust_link(struct dsa_switch *ds, int port, |
|---|
| 977 | | - struct phy_device *phydev) |
|---|
| 1076 | +static void b53_teardown(struct dsa_switch *ds) |
|---|
| 978 | 1077 | { |
|---|
| 979 | | - struct b53_device *dev = ds->priv; |
|---|
| 980 | | - struct ethtool_eee *p = &dev->ports[port].eee; |
|---|
| 981 | | - u8 rgmii_ctrl = 0, reg = 0, off; |
|---|
| 1078 | + dsa_devlink_resources_unregister(ds); |
|---|
| 1079 | +} |
|---|
| 982 | 1080 | |
|---|
| 983 | | - if (!phy_is_pseudo_fixed_link(phydev)) |
|---|
| 984 | | - return; |
|---|
| 1081 | +static void b53_force_link(struct b53_device *dev, int port, int link) |
|---|
| 1082 | +{ |
|---|
| 1083 | + u8 reg, val, off; |
|---|
| 985 | 1084 | |
|---|
| 986 | 1085 | /* Override the port settings */ |
|---|
| 987 | | - if (port == dev->cpu_port) { |
|---|
| 1086 | + if (port == dev->imp_port) { |
|---|
| 988 | 1087 | off = B53_PORT_OVERRIDE_CTRL; |
|---|
| 989 | | - reg = PORT_OVERRIDE_EN; |
|---|
| 1088 | + val = PORT_OVERRIDE_EN; |
|---|
| 990 | 1089 | } else { |
|---|
| 991 | 1090 | off = B53_GMII_PORT_OVERRIDE_CTRL(port); |
|---|
| 992 | | - reg = GMII_PO_EN; |
|---|
| 1091 | + val = GMII_PO_EN; |
|---|
| 993 | 1092 | } |
|---|
| 994 | 1093 | |
|---|
| 995 | | - /* Set the link UP */ |
|---|
| 996 | | - if (phydev->link) |
|---|
| 1094 | + b53_read8(dev, B53_CTRL_PAGE, off, ®); |
|---|
| 1095 | + reg |= val; |
|---|
| 1096 | + if (link) |
|---|
| 997 | 1097 | reg |= PORT_OVERRIDE_LINK; |
|---|
| 1098 | + else |
|---|
| 1099 | + reg &= ~PORT_OVERRIDE_LINK; |
|---|
| 1100 | + b53_write8(dev, B53_CTRL_PAGE, off, reg); |
|---|
| 1101 | +} |
|---|
| 998 | 1102 | |
|---|
| 999 | | - if (phydev->duplex == DUPLEX_FULL) |
|---|
| 1103 | +static void b53_force_port_config(struct b53_device *dev, int port, |
|---|
| 1104 | + int speed, int duplex, |
|---|
| 1105 | + bool tx_pause, bool rx_pause) |
|---|
| 1106 | +{ |
|---|
| 1107 | + u8 reg, val, off; |
|---|
| 1108 | + |
|---|
| 1109 | + /* Override the port settings */ |
|---|
| 1110 | + if (port == dev->imp_port) { |
|---|
| 1111 | + off = B53_PORT_OVERRIDE_CTRL; |
|---|
| 1112 | + val = PORT_OVERRIDE_EN; |
|---|
| 1113 | + } else { |
|---|
| 1114 | + off = B53_GMII_PORT_OVERRIDE_CTRL(port); |
|---|
| 1115 | + val = GMII_PO_EN; |
|---|
| 1116 | + } |
|---|
| 1117 | + |
|---|
| 1118 | + b53_read8(dev, B53_CTRL_PAGE, off, ®); |
|---|
| 1119 | + reg |= val; |
|---|
| 1120 | + if (duplex == DUPLEX_FULL) |
|---|
| 1000 | 1121 | reg |= PORT_OVERRIDE_FULL_DUPLEX; |
|---|
| 1122 | + else |
|---|
| 1123 | + reg &= ~PORT_OVERRIDE_FULL_DUPLEX; |
|---|
| 1001 | 1124 | |
|---|
| 1002 | | - switch (phydev->speed) { |
|---|
| 1125 | + switch (speed) { |
|---|
| 1003 | 1126 | case 2000: |
|---|
| 1004 | 1127 | reg |= PORT_OVERRIDE_SPEED_2000M; |
|---|
| 1005 | | - /* fallthrough */ |
|---|
| 1128 | + fallthrough; |
|---|
| 1006 | 1129 | case SPEED_1000: |
|---|
| 1007 | 1130 | reg |= PORT_OVERRIDE_SPEED_1000M; |
|---|
| 1008 | 1131 | break; |
|---|
| .. | .. |
|---|
| 1013 | 1136 | reg |= PORT_OVERRIDE_SPEED_10M; |
|---|
| 1014 | 1137 | break; |
|---|
| 1015 | 1138 | default: |
|---|
| 1016 | | - dev_err(ds->dev, "unknown speed: %d\n", phydev->speed); |
|---|
| 1139 | + dev_err(dev->dev, "unknown speed: %d\n", speed); |
|---|
| 1017 | 1140 | return; |
|---|
| 1018 | 1141 | } |
|---|
| 1019 | 1142 | |
|---|
| 1143 | + if (rx_pause) |
|---|
| 1144 | + reg |= PORT_OVERRIDE_RX_FLOW; |
|---|
| 1145 | + if (tx_pause) |
|---|
| 1146 | + reg |= PORT_OVERRIDE_TX_FLOW; |
|---|
| 1147 | + |
|---|
| 1148 | + b53_write8(dev, B53_CTRL_PAGE, off, reg); |
|---|
| 1149 | +} |
|---|
| 1150 | + |
|---|
| 1151 | +static void b53_adjust_link(struct dsa_switch *ds, int port, |
|---|
| 1152 | + struct phy_device *phydev) |
|---|
| 1153 | +{ |
|---|
| 1154 | + struct b53_device *dev = ds->priv; |
|---|
| 1155 | + struct ethtool_eee *p = &dev->ports[port].eee; |
|---|
| 1156 | + u8 rgmii_ctrl = 0, reg = 0, off; |
|---|
| 1157 | + bool tx_pause = false; |
|---|
| 1158 | + bool rx_pause = false; |
|---|
| 1159 | + |
|---|
| 1160 | + if (!phy_is_pseudo_fixed_link(phydev)) |
|---|
| 1161 | + return; |
|---|
| 1162 | + |
|---|
| 1020 | 1163 | /* Enable flow control on BCM5301x's CPU port */ |
|---|
| 1021 | 1164 | if (is5301x(dev) && port == dev->cpu_port) |
|---|
| 1022 | | - reg |= PORT_OVERRIDE_RX_FLOW | PORT_OVERRIDE_TX_FLOW; |
|---|
| 1165 | + tx_pause = rx_pause = true; |
|---|
| 1023 | 1166 | |
|---|
| 1024 | 1167 | if (phydev->pause) { |
|---|
| 1025 | 1168 | if (phydev->asym_pause) |
|---|
| 1026 | | - reg |= PORT_OVERRIDE_TX_FLOW; |
|---|
| 1027 | | - reg |= PORT_OVERRIDE_RX_FLOW; |
|---|
| 1169 | + tx_pause = true; |
|---|
| 1170 | + rx_pause = true; |
|---|
| 1028 | 1171 | } |
|---|
| 1029 | 1172 | |
|---|
| 1030 | | - b53_write8(dev, B53_CTRL_PAGE, off, reg); |
|---|
| 1173 | + b53_force_port_config(dev, port, phydev->speed, phydev->duplex, |
|---|
| 1174 | + tx_pause, rx_pause); |
|---|
| 1175 | + b53_force_link(dev, port, phydev->link); |
|---|
| 1031 | 1176 | |
|---|
| 1032 | 1177 | if (is531x5(dev) && phy_interface_is_rgmii(phydev)) { |
|---|
| 1033 | | - if (port == 8) |
|---|
| 1178 | + if (port == dev->imp_port) |
|---|
| 1034 | 1179 | off = B53_RGMII_CTRL_IMP; |
|---|
| 1035 | 1180 | else |
|---|
| 1036 | 1181 | off = B53_RGMII_CTRL_P(port); |
|---|
| .. | .. |
|---|
| 1087 | 1232 | } |
|---|
| 1088 | 1233 | } else if (is5301x(dev)) { |
|---|
| 1089 | 1234 | if (port != dev->cpu_port) { |
|---|
| 1090 | | - u8 po_reg = B53_GMII_PORT_OVERRIDE_CTRL(dev->cpu_port); |
|---|
| 1091 | | - u8 gmii_po; |
|---|
| 1092 | | - |
|---|
| 1093 | | - b53_read8(dev, B53_CTRL_PAGE, po_reg, &gmii_po); |
|---|
| 1094 | | - gmii_po |= GMII_PO_LINK | |
|---|
| 1095 | | - GMII_PO_RX_FLOW | |
|---|
| 1096 | | - GMII_PO_TX_FLOW | |
|---|
| 1097 | | - GMII_PO_EN | |
|---|
| 1098 | | - GMII_PO_SPEED_2000M; |
|---|
| 1099 | | - b53_write8(dev, B53_CTRL_PAGE, po_reg, gmii_po); |
|---|
| 1235 | + b53_force_port_config(dev, dev->cpu_port, 2000, |
|---|
| 1236 | + DUPLEX_FULL, true, true); |
|---|
| 1237 | + b53_force_link(dev, dev->cpu_port, 1); |
|---|
| 1100 | 1238 | } |
|---|
| 1101 | 1239 | } |
|---|
| 1102 | 1240 | |
|---|
| .. | .. |
|---|
| 1104 | 1242 | p->eee_enabled = b53_eee_init(ds, port, phydev); |
|---|
| 1105 | 1243 | } |
|---|
| 1106 | 1244 | |
|---|
| 1107 | | -int b53_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering) |
|---|
| 1245 | +void b53_port_event(struct dsa_switch *ds, int port) |
|---|
| 1108 | 1246 | { |
|---|
| 1109 | 1247 | struct b53_device *dev = ds->priv; |
|---|
| 1110 | | - struct net_device *bridge_dev; |
|---|
| 1111 | | - unsigned int i; |
|---|
| 1112 | | - u16 pvid, new_pvid; |
|---|
| 1248 | + bool link; |
|---|
| 1249 | + u16 sts; |
|---|
| 1113 | 1250 | |
|---|
| 1114 | | - /* Handle the case were multiple bridges span the same switch device |
|---|
| 1115 | | - * and one of them has a different setting than what is being requested |
|---|
| 1116 | | - * which would be breaking filtering semantics for any of the other |
|---|
| 1117 | | - * bridge devices. |
|---|
| 1251 | + b53_read16(dev, B53_STAT_PAGE, B53_LINK_STAT, &sts); |
|---|
| 1252 | + link = !!(sts & BIT(port)); |
|---|
| 1253 | + dsa_port_phylink_mac_change(ds, port, link); |
|---|
| 1254 | +} |
|---|
| 1255 | +EXPORT_SYMBOL(b53_port_event); |
|---|
| 1256 | + |
|---|
| 1257 | +void b53_phylink_validate(struct dsa_switch *ds, int port, |
|---|
| 1258 | + unsigned long *supported, |
|---|
| 1259 | + struct phylink_link_state *state) |
|---|
| 1260 | +{ |
|---|
| 1261 | + struct b53_device *dev = ds->priv; |
|---|
| 1262 | + __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; |
|---|
| 1263 | + |
|---|
| 1264 | + if (dev->ops->serdes_phylink_validate) |
|---|
| 1265 | + dev->ops->serdes_phylink_validate(dev, port, mask, state); |
|---|
| 1266 | + |
|---|
| 1267 | + /* Allow all the expected bits */ |
|---|
| 1268 | + phylink_set(mask, Autoneg); |
|---|
| 1269 | + phylink_set_port_modes(mask); |
|---|
| 1270 | + phylink_set(mask, Pause); |
|---|
| 1271 | + phylink_set(mask, Asym_Pause); |
|---|
| 1272 | + |
|---|
| 1273 | + /* With the exclusion of 5325/5365, MII, Reverse MII and 802.3z, we |
|---|
| 1274 | + * support Gigabit, including Half duplex. |
|---|
| 1118 | 1275 | */ |
|---|
| 1119 | | - b53_for_each_port(dev, i) { |
|---|
| 1120 | | - bridge_dev = dsa_to_port(ds, i)->bridge_dev; |
|---|
| 1121 | | - if (bridge_dev && |
|---|
| 1122 | | - bridge_dev != dsa_to_port(ds, port)->bridge_dev && |
|---|
| 1123 | | - br_vlan_enabled(bridge_dev) != vlan_filtering) { |
|---|
| 1124 | | - netdev_err(bridge_dev, |
|---|
| 1125 | | - "VLAN filtering is global to the switch!\n"); |
|---|
| 1126 | | - return -EINVAL; |
|---|
| 1127 | | - } |
|---|
| 1276 | + if (state->interface != PHY_INTERFACE_MODE_MII && |
|---|
| 1277 | + state->interface != PHY_INTERFACE_MODE_REVMII && |
|---|
| 1278 | + !phy_interface_mode_is_8023z(state->interface) && |
|---|
| 1279 | + !(is5325(dev) || is5365(dev))) { |
|---|
| 1280 | + phylink_set(mask, 1000baseT_Full); |
|---|
| 1281 | + phylink_set(mask, 1000baseT_Half); |
|---|
| 1128 | 1282 | } |
|---|
| 1129 | 1283 | |
|---|
| 1130 | | - b53_read16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port), &pvid); |
|---|
| 1131 | | - new_pvid = pvid; |
|---|
| 1132 | | - if (dev->vlan_filtering_enabled && !vlan_filtering) { |
|---|
| 1133 | | - /* Filtering is currently enabled, use the default PVID since |
|---|
| 1134 | | - * the bridge does not expect tagging anymore |
|---|
| 1135 | | - */ |
|---|
| 1136 | | - dev->ports[port].pvid = pvid; |
|---|
| 1137 | | - new_pvid = b53_default_pvid(dev); |
|---|
| 1138 | | - } else if (!dev->vlan_filtering_enabled && vlan_filtering) { |
|---|
| 1139 | | - /* Filtering is currently disabled, restore the previous PVID */ |
|---|
| 1140 | | - new_pvid = dev->ports[port].pvid; |
|---|
| 1284 | + if (!phy_interface_mode_is_8023z(state->interface)) { |
|---|
| 1285 | + phylink_set(mask, 10baseT_Half); |
|---|
| 1286 | + phylink_set(mask, 10baseT_Full); |
|---|
| 1287 | + phylink_set(mask, 100baseT_Half); |
|---|
| 1288 | + phylink_set(mask, 100baseT_Full); |
|---|
| 1141 | 1289 | } |
|---|
| 1142 | 1290 | |
|---|
| 1143 | | - if (pvid != new_pvid) |
|---|
| 1144 | | - b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port), |
|---|
| 1145 | | - new_pvid); |
|---|
| 1291 | + bitmap_and(supported, supported, mask, |
|---|
| 1292 | + __ETHTOOL_LINK_MODE_MASK_NBITS); |
|---|
| 1293 | + bitmap_and(state->advertising, state->advertising, mask, |
|---|
| 1294 | + __ETHTOOL_LINK_MODE_MASK_NBITS); |
|---|
| 1295 | + |
|---|
| 1296 | + phylink_helper_basex_speed(state); |
|---|
| 1297 | +} |
|---|
| 1298 | +EXPORT_SYMBOL(b53_phylink_validate); |
|---|
| 1299 | + |
|---|
| 1300 | +int b53_phylink_mac_link_state(struct dsa_switch *ds, int port, |
|---|
| 1301 | + struct phylink_link_state *state) |
|---|
| 1302 | +{ |
|---|
| 1303 | + struct b53_device *dev = ds->priv; |
|---|
| 1304 | + int ret = -EOPNOTSUPP; |
|---|
| 1305 | + |
|---|
| 1306 | + if ((phy_interface_mode_is_8023z(state->interface) || |
|---|
| 1307 | + state->interface == PHY_INTERFACE_MODE_SGMII) && |
|---|
| 1308 | + dev->ops->serdes_link_state) |
|---|
| 1309 | + ret = dev->ops->serdes_link_state(dev, port, state); |
|---|
| 1310 | + |
|---|
| 1311 | + return ret; |
|---|
| 1312 | +} |
|---|
| 1313 | +EXPORT_SYMBOL(b53_phylink_mac_link_state); |
|---|
| 1314 | + |
|---|
| 1315 | +void b53_phylink_mac_config(struct dsa_switch *ds, int port, |
|---|
| 1316 | + unsigned int mode, |
|---|
| 1317 | + const struct phylink_link_state *state) |
|---|
| 1318 | +{ |
|---|
| 1319 | + struct b53_device *dev = ds->priv; |
|---|
| 1320 | + |
|---|
| 1321 | + if (mode == MLO_AN_PHY || mode == MLO_AN_FIXED) |
|---|
| 1322 | + return; |
|---|
| 1323 | + |
|---|
| 1324 | + if ((phy_interface_mode_is_8023z(state->interface) || |
|---|
| 1325 | + state->interface == PHY_INTERFACE_MODE_SGMII) && |
|---|
| 1326 | + dev->ops->serdes_config) |
|---|
| 1327 | + dev->ops->serdes_config(dev, port, mode, state); |
|---|
| 1328 | +} |
|---|
| 1329 | +EXPORT_SYMBOL(b53_phylink_mac_config); |
|---|
| 1330 | + |
|---|
| 1331 | +void b53_phylink_mac_an_restart(struct dsa_switch *ds, int port) |
|---|
| 1332 | +{ |
|---|
| 1333 | + struct b53_device *dev = ds->priv; |
|---|
| 1334 | + |
|---|
| 1335 | + if (dev->ops->serdes_an_restart) |
|---|
| 1336 | + dev->ops->serdes_an_restart(dev, port); |
|---|
| 1337 | +} |
|---|
| 1338 | +EXPORT_SYMBOL(b53_phylink_mac_an_restart); |
|---|
| 1339 | + |
|---|
| 1340 | +void b53_phylink_mac_link_down(struct dsa_switch *ds, int port, |
|---|
| 1341 | + unsigned int mode, |
|---|
| 1342 | + phy_interface_t interface) |
|---|
| 1343 | +{ |
|---|
| 1344 | + struct b53_device *dev = ds->priv; |
|---|
| 1345 | + |
|---|
| 1346 | + if (mode == MLO_AN_PHY) |
|---|
| 1347 | + return; |
|---|
| 1348 | + |
|---|
| 1349 | + if (mode == MLO_AN_FIXED) { |
|---|
| 1350 | + b53_force_link(dev, port, false); |
|---|
| 1351 | + return; |
|---|
| 1352 | + } |
|---|
| 1353 | + |
|---|
| 1354 | + if (phy_interface_mode_is_8023z(interface) && |
|---|
| 1355 | + dev->ops->serdes_link_set) |
|---|
| 1356 | + dev->ops->serdes_link_set(dev, port, mode, interface, false); |
|---|
| 1357 | +} |
|---|
| 1358 | +EXPORT_SYMBOL(b53_phylink_mac_link_down); |
|---|
| 1359 | + |
|---|
| 1360 | +void b53_phylink_mac_link_up(struct dsa_switch *ds, int port, |
|---|
| 1361 | + unsigned int mode, |
|---|
| 1362 | + phy_interface_t interface, |
|---|
| 1363 | + struct phy_device *phydev, |
|---|
| 1364 | + int speed, int duplex, |
|---|
| 1365 | + bool tx_pause, bool rx_pause) |
|---|
| 1366 | +{ |
|---|
| 1367 | + struct b53_device *dev = ds->priv; |
|---|
| 1368 | + |
|---|
| 1369 | + if (mode == MLO_AN_PHY) |
|---|
| 1370 | + return; |
|---|
| 1371 | + |
|---|
| 1372 | + if (mode == MLO_AN_FIXED) { |
|---|
| 1373 | + b53_force_port_config(dev, port, speed, duplex, |
|---|
| 1374 | + tx_pause, rx_pause); |
|---|
| 1375 | + b53_force_link(dev, port, true); |
|---|
| 1376 | + return; |
|---|
| 1377 | + } |
|---|
| 1378 | + |
|---|
| 1379 | + if (phy_interface_mode_is_8023z(interface) && |
|---|
| 1380 | + dev->ops->serdes_link_set) |
|---|
| 1381 | + dev->ops->serdes_link_set(dev, port, mode, interface, true); |
|---|
| 1382 | +} |
|---|
| 1383 | +EXPORT_SYMBOL(b53_phylink_mac_link_up); |
|---|
| 1384 | + |
|---|
| 1385 | +int b53_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering, |
|---|
| 1386 | + struct switchdev_trans *trans) |
|---|
| 1387 | +{ |
|---|
| 1388 | + struct b53_device *dev = ds->priv; |
|---|
| 1389 | + |
|---|
| 1390 | + if (switchdev_trans_ph_prepare(trans)) |
|---|
| 1391 | + return 0; |
|---|
| 1146 | 1392 | |
|---|
| 1147 | 1393 | b53_enable_vlan(dev, dev->vlan_enabled, vlan_filtering); |
|---|
| 1148 | 1394 | |
|---|
| .. | .. |
|---|
| 1158 | 1404 | if ((is5325(dev) || is5365(dev)) && vlan->vid_begin == 0) |
|---|
| 1159 | 1405 | return -EOPNOTSUPP; |
|---|
| 1160 | 1406 | |
|---|
| 1407 | + /* Port 7 on 7278 connects to the ASP's UniMAC which is not capable of |
|---|
| 1408 | + * receiving VLAN tagged frames at all, we can still allow the port to |
|---|
| 1409 | + * be configured for egress untagged. |
|---|
| 1410 | + */ |
|---|
| 1411 | + if (dev->chip_id == BCM7278_DEVICE_ID && port == 7 && |
|---|
| 1412 | + !(vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED)) |
|---|
| 1413 | + return -EINVAL; |
|---|
| 1414 | + |
|---|
| 1161 | 1415 | if (vlan->vid_end >= dev->num_vlans) |
|---|
| 1162 | 1416 | return -ERANGE; |
|---|
| 1163 | 1417 | |
|---|
| 1164 | | - b53_enable_vlan(dev, true, dev->vlan_filtering_enabled); |
|---|
| 1418 | + b53_enable_vlan(dev, true, ds->vlan_filtering); |
|---|
| 1165 | 1419 | |
|---|
| 1166 | 1420 | return 0; |
|---|
| 1167 | 1421 | } |
|---|
| .. | .. |
|---|
| 1279 | 1533 | } |
|---|
| 1280 | 1534 | |
|---|
| 1281 | 1535 | static int b53_arl_read(struct b53_device *dev, u64 mac, |
|---|
| 1282 | | - u16 vid, struct b53_arl_entry *ent, u8 *idx, |
|---|
| 1283 | | - bool is_valid) |
|---|
| 1536 | + u16 vid, struct b53_arl_entry *ent, u8 *idx) |
|---|
| 1284 | 1537 | { |
|---|
| 1285 | 1538 | DECLARE_BITMAP(free_bins, B53_ARLTBL_MAX_BIN_ENTRIES); |
|---|
| 1286 | 1539 | unsigned int i; |
|---|
| .. | .. |
|---|
| 1290 | 1543 | if (ret) |
|---|
| 1291 | 1544 | return ret; |
|---|
| 1292 | 1545 | |
|---|
| 1293 | | - bitmap_zero(free_bins, dev->num_arl_entries); |
|---|
| 1546 | + bitmap_zero(free_bins, dev->num_arl_bins); |
|---|
| 1294 | 1547 | |
|---|
| 1295 | 1548 | /* Read the bins */ |
|---|
| 1296 | | - for (i = 0; i < dev->num_arl_entries; i++) { |
|---|
| 1549 | + for (i = 0; i < dev->num_arl_bins; i++) { |
|---|
| 1297 | 1550 | u64 mac_vid; |
|---|
| 1298 | 1551 | u32 fwd_entry; |
|---|
| 1299 | 1552 | |
|---|
| .. | .. |
|---|
| 1316 | 1569 | return 0; |
|---|
| 1317 | 1570 | } |
|---|
| 1318 | 1571 | |
|---|
| 1319 | | - if (bitmap_weight(free_bins, dev->num_arl_entries) == 0) |
|---|
| 1572 | + if (bitmap_weight(free_bins, dev->num_arl_bins) == 0) |
|---|
| 1320 | 1573 | return -ENOSPC; |
|---|
| 1321 | 1574 | |
|---|
| 1322 | | - *idx = find_first_bit(free_bins, dev->num_arl_entries); |
|---|
| 1575 | + *idx = find_first_bit(free_bins, dev->num_arl_bins); |
|---|
| 1323 | 1576 | |
|---|
| 1324 | 1577 | return -ENOENT; |
|---|
| 1325 | 1578 | } |
|---|
| .. | .. |
|---|
| 1345 | 1598 | if (ret) |
|---|
| 1346 | 1599 | return ret; |
|---|
| 1347 | 1600 | |
|---|
| 1348 | | - ret = b53_arl_read(dev, mac, vid, &ent, &idx, is_valid); |
|---|
| 1601 | + ret = b53_arl_read(dev, mac, vid, &ent, &idx); |
|---|
| 1602 | + |
|---|
| 1349 | 1603 | /* If this is a read, just finish now */ |
|---|
| 1350 | 1604 | if (op) |
|---|
| 1351 | 1605 | return ret; |
|---|
| .. | .. |
|---|
| 1369 | 1623 | break; |
|---|
| 1370 | 1624 | } |
|---|
| 1371 | 1625 | |
|---|
| 1372 | | - memset(&ent, 0, sizeof(ent)); |
|---|
| 1373 | | - ent.port = port; |
|---|
| 1374 | | - ent.is_valid = is_valid; |
|---|
| 1626 | + /* For multicast address, the port is a bitmask and the validity |
|---|
| 1627 | + * is determined by having at least one port being still active |
|---|
| 1628 | + */ |
|---|
| 1629 | + if (!is_multicast_ether_addr(addr)) { |
|---|
| 1630 | + ent.port = port; |
|---|
| 1631 | + ent.is_valid = is_valid; |
|---|
| 1632 | + } else { |
|---|
| 1633 | + if (is_valid) |
|---|
| 1634 | + ent.port |= BIT(port); |
|---|
| 1635 | + else |
|---|
| 1636 | + ent.port &= ~BIT(port); |
|---|
| 1637 | + |
|---|
| 1638 | + ent.is_valid = !!(ent.port); |
|---|
| 1639 | + } |
|---|
| 1640 | + |
|---|
| 1375 | 1641 | ent.vid = vid; |
|---|
| 1376 | 1642 | ent.is_static = true; |
|---|
| 1643 | + ent.is_age = false; |
|---|
| 1377 | 1644 | memcpy(ent.mac, addr, ETH_ALEN); |
|---|
| 1378 | 1645 | b53_arl_from_entry(&mac_vid, &fwd_entry, &ent); |
|---|
| 1379 | 1646 | |
|---|
| .. | .. |
|---|
| 1476 | 1743 | if (ret) |
|---|
| 1477 | 1744 | return ret; |
|---|
| 1478 | 1745 | |
|---|
| 1479 | | - if (priv->num_arl_entries > 2) { |
|---|
| 1746 | + if (priv->num_arl_bins > 2) { |
|---|
| 1480 | 1747 | b53_arl_search_rd(priv, 1, &results[1]); |
|---|
| 1481 | 1748 | ret = b53_fdb_copy(port, &results[1], cb, data); |
|---|
| 1482 | 1749 | if (ret) |
|---|
| .. | .. |
|---|
| 1486 | 1753 | break; |
|---|
| 1487 | 1754 | } |
|---|
| 1488 | 1755 | |
|---|
| 1489 | | - } while (count++ < 1024); |
|---|
| 1756 | + } while (count++ < b53_max_arl_entries(priv) / 2); |
|---|
| 1490 | 1757 | |
|---|
| 1491 | 1758 | return 0; |
|---|
| 1492 | 1759 | } |
|---|
| 1493 | 1760 | EXPORT_SYMBOL(b53_fdb_dump); |
|---|
| 1494 | 1761 | |
|---|
| 1762 | +int b53_mdb_prepare(struct dsa_switch *ds, int port, |
|---|
| 1763 | + const struct switchdev_obj_port_mdb *mdb) |
|---|
| 1764 | +{ |
|---|
| 1765 | + struct b53_device *priv = ds->priv; |
|---|
| 1766 | + |
|---|
| 1767 | + /* 5325 and 5365 require some more massaging, but could |
|---|
| 1768 | + * be supported eventually |
|---|
| 1769 | + */ |
|---|
| 1770 | + if (is5325(priv) || is5365(priv)) |
|---|
| 1771 | + return -EOPNOTSUPP; |
|---|
| 1772 | + |
|---|
| 1773 | + return 0; |
|---|
| 1774 | +} |
|---|
| 1775 | +EXPORT_SYMBOL(b53_mdb_prepare); |
|---|
| 1776 | + |
|---|
| 1777 | +void b53_mdb_add(struct dsa_switch *ds, int port, |
|---|
| 1778 | + const struct switchdev_obj_port_mdb *mdb) |
|---|
| 1779 | +{ |
|---|
| 1780 | + struct b53_device *priv = ds->priv; |
|---|
| 1781 | + int ret; |
|---|
| 1782 | + |
|---|
| 1783 | + ret = b53_arl_op(priv, 0, port, mdb->addr, mdb->vid, true); |
|---|
| 1784 | + if (ret) |
|---|
| 1785 | + dev_err(ds->dev, "failed to add MDB entry\n"); |
|---|
| 1786 | +} |
|---|
| 1787 | +EXPORT_SYMBOL(b53_mdb_add); |
|---|
| 1788 | + |
|---|
| 1789 | +int b53_mdb_del(struct dsa_switch *ds, int port, |
|---|
| 1790 | + const struct switchdev_obj_port_mdb *mdb) |
|---|
| 1791 | +{ |
|---|
| 1792 | + struct b53_device *priv = ds->priv; |
|---|
| 1793 | + int ret; |
|---|
| 1794 | + |
|---|
| 1795 | + ret = b53_arl_op(priv, 0, port, mdb->addr, mdb->vid, false); |
|---|
| 1796 | + if (ret) |
|---|
| 1797 | + dev_err(ds->dev, "failed to delete MDB entry\n"); |
|---|
| 1798 | + |
|---|
| 1799 | + return ret; |
|---|
| 1800 | +} |
|---|
| 1801 | +EXPORT_SYMBOL(b53_mdb_del); |
|---|
| 1802 | + |
|---|
| 1495 | 1803 | int b53_br_join(struct dsa_switch *ds, int port, struct net_device *br) |
|---|
| 1496 | 1804 | { |
|---|
| 1497 | 1805 | struct b53_device *dev = ds->priv; |
|---|
| 1498 | | - s8 cpu_port = ds->ports[port].cpu_dp->index; |
|---|
| 1806 | + s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index; |
|---|
| 1499 | 1807 | u16 pvlan, reg; |
|---|
| 1500 | 1808 | unsigned int i; |
|---|
| 1809 | + |
|---|
| 1810 | + /* On 7278, port 7 which connects to the ASP should only receive |
|---|
| 1811 | + * traffic from matching CFP rules. |
|---|
| 1812 | + */ |
|---|
| 1813 | + if (dev->chip_id == BCM7278_DEVICE_ID && port == 7) |
|---|
| 1814 | + return -EINVAL; |
|---|
| 1501 | 1815 | |
|---|
| 1502 | 1816 | /* Make this port leave the all VLANs join since we will have proper |
|---|
| 1503 | 1817 | * VLAN entries from now on |
|---|
| .. | .. |
|---|
| 1543 | 1857 | { |
|---|
| 1544 | 1858 | struct b53_device *dev = ds->priv; |
|---|
| 1545 | 1859 | struct b53_vlan *vl = &dev->vlans[0]; |
|---|
| 1546 | | - s8 cpu_port = ds->ports[port].cpu_dp->index; |
|---|
| 1860 | + s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index; |
|---|
| 1547 | 1861 | unsigned int i; |
|---|
| 1548 | 1862 | u16 pvlan, reg, pvid; |
|---|
| 1549 | 1863 | |
|---|
| .. | .. |
|---|
| 1629 | 1943 | } |
|---|
| 1630 | 1944 | EXPORT_SYMBOL(b53_br_fast_age); |
|---|
| 1631 | 1945 | |
|---|
| 1946 | +int b53_br_egress_floods(struct dsa_switch *ds, int port, |
|---|
| 1947 | + bool unicast, bool multicast) |
|---|
| 1948 | +{ |
|---|
| 1949 | + struct b53_device *dev = ds->priv; |
|---|
| 1950 | + u16 uc, mc; |
|---|
| 1951 | + |
|---|
| 1952 | + b53_read16(dev, B53_CTRL_PAGE, B53_UC_FLOOD_MASK, &uc); |
|---|
| 1953 | + if (unicast) |
|---|
| 1954 | + uc |= BIT(port); |
|---|
| 1955 | + else |
|---|
| 1956 | + uc &= ~BIT(port); |
|---|
| 1957 | + b53_write16(dev, B53_CTRL_PAGE, B53_UC_FLOOD_MASK, uc); |
|---|
| 1958 | + |
|---|
| 1959 | + b53_read16(dev, B53_CTRL_PAGE, B53_MC_FLOOD_MASK, &mc); |
|---|
| 1960 | + if (multicast) |
|---|
| 1961 | + mc |= BIT(port); |
|---|
| 1962 | + else |
|---|
| 1963 | + mc &= ~BIT(port); |
|---|
| 1964 | + b53_write16(dev, B53_CTRL_PAGE, B53_MC_FLOOD_MASK, mc); |
|---|
| 1965 | + |
|---|
| 1966 | + b53_read16(dev, B53_CTRL_PAGE, B53_IPMC_FLOOD_MASK, &mc); |
|---|
| 1967 | + if (multicast) |
|---|
| 1968 | + mc |= BIT(port); |
|---|
| 1969 | + else |
|---|
| 1970 | + mc &= ~BIT(port); |
|---|
| 1971 | + b53_write16(dev, B53_CTRL_PAGE, B53_IPMC_FLOOD_MASK, mc); |
|---|
| 1972 | + |
|---|
| 1973 | + return 0; |
|---|
| 1974 | + |
|---|
| 1975 | +} |
|---|
| 1976 | +EXPORT_SYMBOL(b53_br_egress_floods); |
|---|
| 1977 | + |
|---|
| 1632 | 1978 | static bool b53_possible_cpu_port(struct dsa_switch *ds, int port) |
|---|
| 1633 | 1979 | { |
|---|
| 1634 | 1980 | /* Broadcom switches will accept enabling Broadcom tags on the |
|---|
| .. | .. |
|---|
| 1644 | 1990 | return false; |
|---|
| 1645 | 1991 | } |
|---|
| 1646 | 1992 | |
|---|
| 1647 | | -static bool b53_can_enable_brcm_tags(struct dsa_switch *ds, int port) |
|---|
| 1993 | +static bool b53_can_enable_brcm_tags(struct dsa_switch *ds, int port, |
|---|
| 1994 | + enum dsa_tag_protocol tag_protocol) |
|---|
| 1648 | 1995 | { |
|---|
| 1649 | 1996 | bool ret = b53_possible_cpu_port(ds, port); |
|---|
| 1650 | 1997 | |
|---|
| 1651 | | - if (!ret) |
|---|
| 1998 | + if (!ret) { |
|---|
| 1652 | 1999 | dev_warn(ds->dev, "Port %d is not Broadcom tag capable\n", |
|---|
| 1653 | 2000 | port); |
|---|
| 2001 | + return ret; |
|---|
| 2002 | + } |
|---|
| 2003 | + |
|---|
| 2004 | + switch (tag_protocol) { |
|---|
| 2005 | + case DSA_TAG_PROTO_BRCM: |
|---|
| 2006 | + case DSA_TAG_PROTO_BRCM_PREPEND: |
|---|
| 2007 | + dev_warn(ds->dev, |
|---|
| 2008 | + "Port %d is stacked to Broadcom tag switch\n", port); |
|---|
| 2009 | + ret = false; |
|---|
| 2010 | + break; |
|---|
| 2011 | + default: |
|---|
| 2012 | + ret = true; |
|---|
| 2013 | + break; |
|---|
| 2014 | + } |
|---|
| 2015 | + |
|---|
| 1654 | 2016 | return ret; |
|---|
| 1655 | 2017 | } |
|---|
| 1656 | 2018 | |
|---|
| 1657 | | -enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port) |
|---|
| 2019 | +enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port, |
|---|
| 2020 | + enum dsa_tag_protocol mprot) |
|---|
| 1658 | 2021 | { |
|---|
| 1659 | 2022 | struct b53_device *dev = ds->priv; |
|---|
| 1660 | 2023 | |
|---|
| 1661 | 2024 | /* Older models (5325, 5365) support a different tag format that we do |
|---|
| 1662 | | - * not support in net/dsa/tag_brcm.c yet. 539x and 531x5 require managed |
|---|
| 1663 | | - * mode to be turned on which means we need to specifically manage ARL |
|---|
| 1664 | | - * misses on multicast addresses (TBD). |
|---|
| 2025 | + * not support in net/dsa/tag_brcm.c yet. |
|---|
| 1665 | 2026 | */ |
|---|
| 1666 | | - if (is5325(dev) || is5365(dev) || is539x(dev) || is531x5(dev) || |
|---|
| 1667 | | - !b53_can_enable_brcm_tags(ds, port)) |
|---|
| 1668 | | - return DSA_TAG_PROTO_NONE; |
|---|
| 2027 | + if (is5325(dev) || is5365(dev) || |
|---|
| 2028 | + !b53_can_enable_brcm_tags(ds, port, mprot)) { |
|---|
| 2029 | + dev->tag_protocol = DSA_TAG_PROTO_NONE; |
|---|
| 2030 | + goto out; |
|---|
| 2031 | + } |
|---|
| 1669 | 2032 | |
|---|
| 1670 | 2033 | /* Broadcom BCM58xx chips have a flow accelerator on Port 8 |
|---|
| 1671 | 2034 | * which requires us to use the prepended Broadcom tag type |
|---|
| 1672 | 2035 | */ |
|---|
| 1673 | | - if (dev->chip_id == BCM58XX_DEVICE_ID && port == B53_CPU_PORT) |
|---|
| 1674 | | - return DSA_TAG_PROTO_BRCM_PREPEND; |
|---|
| 2036 | + if (dev->chip_id == BCM58XX_DEVICE_ID && port == B53_CPU_PORT) { |
|---|
| 2037 | + dev->tag_protocol = DSA_TAG_PROTO_BRCM_PREPEND; |
|---|
| 2038 | + goto out; |
|---|
| 2039 | + } |
|---|
| 1675 | 2040 | |
|---|
| 1676 | | - return DSA_TAG_PROTO_BRCM; |
|---|
| 2041 | + dev->tag_protocol = DSA_TAG_PROTO_BRCM; |
|---|
| 2042 | +out: |
|---|
| 2043 | + return dev->tag_protocol; |
|---|
| 1677 | 2044 | } |
|---|
| 1678 | 2045 | EXPORT_SYMBOL(b53_get_tag_protocol); |
|---|
| 1679 | 2046 | |
|---|
| .. | .. |
|---|
| 1804 | 2171 | } |
|---|
| 1805 | 2172 | EXPORT_SYMBOL(b53_set_mac_eee); |
|---|
| 1806 | 2173 | |
|---|
| 2174 | +static int b53_change_mtu(struct dsa_switch *ds, int port, int mtu) |
|---|
| 2175 | +{ |
|---|
| 2176 | + struct b53_device *dev = ds->priv; |
|---|
| 2177 | + bool enable_jumbo; |
|---|
| 2178 | + bool allow_10_100; |
|---|
| 2179 | + |
|---|
| 2180 | + if (is5325(dev) || is5365(dev)) |
|---|
| 2181 | + return -EOPNOTSUPP; |
|---|
| 2182 | + |
|---|
| 2183 | + enable_jumbo = (mtu >= JMS_MIN_SIZE); |
|---|
| 2184 | + allow_10_100 = (dev->chip_id == BCM583XX_DEVICE_ID); |
|---|
| 2185 | + |
|---|
| 2186 | + return b53_set_jumbo(dev, enable_jumbo, allow_10_100); |
|---|
| 2187 | +} |
|---|
| 2188 | + |
|---|
| 2189 | +static int b53_get_max_mtu(struct dsa_switch *ds, int port) |
|---|
| 2190 | +{ |
|---|
| 2191 | + return JMS_MAX_SIZE; |
|---|
| 2192 | +} |
|---|
| 2193 | + |
|---|
| 1807 | 2194 | static const struct dsa_switch_ops b53_switch_ops = { |
|---|
| 1808 | 2195 | .get_tag_protocol = b53_get_tag_protocol, |
|---|
| 1809 | 2196 | .setup = b53_setup, |
|---|
| 2197 | + .teardown = b53_teardown, |
|---|
| 1810 | 2198 | .get_strings = b53_get_strings, |
|---|
| 1811 | 2199 | .get_ethtool_stats = b53_get_ethtool_stats, |
|---|
| 1812 | 2200 | .get_sset_count = b53_get_sset_count, |
|---|
| .. | .. |
|---|
| 1814 | 2202 | .phy_read = b53_phy_read16, |
|---|
| 1815 | 2203 | .phy_write = b53_phy_write16, |
|---|
| 1816 | 2204 | .adjust_link = b53_adjust_link, |
|---|
| 2205 | + .phylink_validate = b53_phylink_validate, |
|---|
| 2206 | + .phylink_mac_link_state = b53_phylink_mac_link_state, |
|---|
| 2207 | + .phylink_mac_config = b53_phylink_mac_config, |
|---|
| 2208 | + .phylink_mac_an_restart = b53_phylink_mac_an_restart, |
|---|
| 2209 | + .phylink_mac_link_down = b53_phylink_mac_link_down, |
|---|
| 2210 | + .phylink_mac_link_up = b53_phylink_mac_link_up, |
|---|
| 1817 | 2211 | .port_enable = b53_enable_port, |
|---|
| 1818 | 2212 | .port_disable = b53_disable_port, |
|---|
| 1819 | 2213 | .get_mac_eee = b53_get_mac_eee, |
|---|
| .. | .. |
|---|
| 1822 | 2216 | .port_bridge_leave = b53_br_leave, |
|---|
| 1823 | 2217 | .port_stp_state_set = b53_br_set_stp_state, |
|---|
| 1824 | 2218 | .port_fast_age = b53_br_fast_age, |
|---|
| 2219 | + .port_egress_floods = b53_br_egress_floods, |
|---|
| 1825 | 2220 | .port_vlan_filtering = b53_vlan_filtering, |
|---|
| 1826 | 2221 | .port_vlan_prepare = b53_vlan_prepare, |
|---|
| 1827 | 2222 | .port_vlan_add = b53_vlan_add, |
|---|
| .. | .. |
|---|
| 1831 | 2226 | .port_fdb_del = b53_fdb_del, |
|---|
| 1832 | 2227 | .port_mirror_add = b53_mirror_add, |
|---|
| 1833 | 2228 | .port_mirror_del = b53_mirror_del, |
|---|
| 2229 | + .port_mdb_prepare = b53_mdb_prepare, |
|---|
| 2230 | + .port_mdb_add = b53_mdb_add, |
|---|
| 2231 | + .port_mdb_del = b53_mdb_del, |
|---|
| 2232 | + .port_max_mtu = b53_get_max_mtu, |
|---|
| 2233 | + .port_change_mtu = b53_change_mtu, |
|---|
| 1834 | 2234 | }; |
|---|
| 1835 | 2235 | |
|---|
| 1836 | 2236 | struct b53_chip_data { |
|---|
| .. | .. |
|---|
| 1838 | 2238 | const char *dev_name; |
|---|
| 1839 | 2239 | u16 vlans; |
|---|
| 1840 | 2240 | u16 enabled_ports; |
|---|
| 2241 | + u8 imp_port; |
|---|
| 1841 | 2242 | u8 cpu_port; |
|---|
| 1842 | 2243 | u8 vta_regs[3]; |
|---|
| 1843 | | - u8 arl_entries; |
|---|
| 2244 | + u8 arl_bins; |
|---|
| 2245 | + u16 arl_buckets; |
|---|
| 1844 | 2246 | u8 duplex_reg; |
|---|
| 1845 | 2247 | u8 jumbo_pm_reg; |
|---|
| 1846 | 2248 | u8 jumbo_size_reg; |
|---|
| .. | .. |
|---|
| 1859 | 2261 | .dev_name = "BCM5325", |
|---|
| 1860 | 2262 | .vlans = 16, |
|---|
| 1861 | 2263 | .enabled_ports = 0x1f, |
|---|
| 1862 | | - .arl_entries = 2, |
|---|
| 2264 | + .arl_bins = 2, |
|---|
| 2265 | + .arl_buckets = 1024, |
|---|
| 2266 | + .imp_port = 5, |
|---|
| 1863 | 2267 | .cpu_port = B53_CPU_PORT_25, |
|---|
| 1864 | 2268 | .duplex_reg = B53_DUPLEX_STAT_FE, |
|---|
| 1865 | 2269 | }, |
|---|
| .. | .. |
|---|
| 1868 | 2272 | .dev_name = "BCM5365", |
|---|
| 1869 | 2273 | .vlans = 256, |
|---|
| 1870 | 2274 | .enabled_ports = 0x1f, |
|---|
| 1871 | | - .arl_entries = 2, |
|---|
| 2275 | + .arl_bins = 2, |
|---|
| 2276 | + .arl_buckets = 1024, |
|---|
| 2277 | + .imp_port = 5, |
|---|
| 1872 | 2278 | .cpu_port = B53_CPU_PORT_25, |
|---|
| 1873 | 2279 | .duplex_reg = B53_DUPLEX_STAT_FE, |
|---|
| 1874 | 2280 | }, |
|---|
| .. | .. |
|---|
| 1877 | 2283 | .dev_name = "BCM5389", |
|---|
| 1878 | 2284 | .vlans = 4096, |
|---|
| 1879 | 2285 | .enabled_ports = 0x1f, |
|---|
| 1880 | | - .arl_entries = 4, |
|---|
| 2286 | + .arl_bins = 4, |
|---|
| 2287 | + .arl_buckets = 1024, |
|---|
| 2288 | + .imp_port = 8, |
|---|
| 1881 | 2289 | .cpu_port = B53_CPU_PORT, |
|---|
| 1882 | 2290 | .vta_regs = B53_VTA_REGS, |
|---|
| 1883 | 2291 | .duplex_reg = B53_DUPLEX_STAT_GE, |
|---|
| .. | .. |
|---|
| 1889 | 2297 | .dev_name = "BCM5395", |
|---|
| 1890 | 2298 | .vlans = 4096, |
|---|
| 1891 | 2299 | .enabled_ports = 0x1f, |
|---|
| 1892 | | - .arl_entries = 4, |
|---|
| 2300 | + .arl_bins = 4, |
|---|
| 2301 | + .arl_buckets = 1024, |
|---|
| 2302 | + .imp_port = 8, |
|---|
| 1893 | 2303 | .cpu_port = B53_CPU_PORT, |
|---|
| 1894 | 2304 | .vta_regs = B53_VTA_REGS, |
|---|
| 1895 | 2305 | .duplex_reg = B53_DUPLEX_STAT_GE, |
|---|
| .. | .. |
|---|
| 1901 | 2311 | .dev_name = "BCM5397", |
|---|
| 1902 | 2312 | .vlans = 4096, |
|---|
| 1903 | 2313 | .enabled_ports = 0x1f, |
|---|
| 1904 | | - .arl_entries = 4, |
|---|
| 2314 | + .arl_bins = 4, |
|---|
| 2315 | + .arl_buckets = 1024, |
|---|
| 2316 | + .imp_port = 8, |
|---|
| 1905 | 2317 | .cpu_port = B53_CPU_PORT, |
|---|
| 1906 | 2318 | .vta_regs = B53_VTA_REGS_9798, |
|---|
| 1907 | 2319 | .duplex_reg = B53_DUPLEX_STAT_GE, |
|---|
| .. | .. |
|---|
| 1913 | 2325 | .dev_name = "BCM5398", |
|---|
| 1914 | 2326 | .vlans = 4096, |
|---|
| 1915 | 2327 | .enabled_ports = 0x7f, |
|---|
| 1916 | | - .arl_entries = 4, |
|---|
| 2328 | + .arl_bins = 4, |
|---|
| 2329 | + .arl_buckets = 1024, |
|---|
| 2330 | + .imp_port = 8, |
|---|
| 1917 | 2331 | .cpu_port = B53_CPU_PORT, |
|---|
| 1918 | 2332 | .vta_regs = B53_VTA_REGS_9798, |
|---|
| 1919 | 2333 | .duplex_reg = B53_DUPLEX_STAT_GE, |
|---|
| .. | .. |
|---|
| 1925 | 2339 | .dev_name = "BCM53115", |
|---|
| 1926 | 2340 | .vlans = 4096, |
|---|
| 1927 | 2341 | .enabled_ports = 0x1f, |
|---|
| 1928 | | - .arl_entries = 4, |
|---|
| 2342 | + .arl_bins = 4, |
|---|
| 2343 | + .arl_buckets = 1024, |
|---|
| 1929 | 2344 | .vta_regs = B53_VTA_REGS, |
|---|
| 2345 | + .imp_port = 8, |
|---|
| 1930 | 2346 | .cpu_port = B53_CPU_PORT, |
|---|
| 1931 | 2347 | .duplex_reg = B53_DUPLEX_STAT_GE, |
|---|
| 1932 | 2348 | .jumbo_pm_reg = B53_JUMBO_PORT_MASK, |
|---|
| .. | .. |
|---|
| 1937 | 2353 | .dev_name = "BCM53125", |
|---|
| 1938 | 2354 | .vlans = 4096, |
|---|
| 1939 | 2355 | .enabled_ports = 0xff, |
|---|
| 1940 | | - .arl_entries = 4, |
|---|
| 2356 | + .arl_bins = 4, |
|---|
| 2357 | + .arl_buckets = 1024, |
|---|
| 2358 | + .imp_port = 8, |
|---|
| 1941 | 2359 | .cpu_port = B53_CPU_PORT, |
|---|
| 1942 | 2360 | .vta_regs = B53_VTA_REGS, |
|---|
| 1943 | 2361 | .duplex_reg = B53_DUPLEX_STAT_GE, |
|---|
| .. | .. |
|---|
| 1949 | 2367 | .dev_name = "BCM53128", |
|---|
| 1950 | 2368 | .vlans = 4096, |
|---|
| 1951 | 2369 | .enabled_ports = 0x1ff, |
|---|
| 1952 | | - .arl_entries = 4, |
|---|
| 2370 | + .arl_bins = 4, |
|---|
| 2371 | + .arl_buckets = 1024, |
|---|
| 2372 | + .imp_port = 8, |
|---|
| 1953 | 2373 | .cpu_port = B53_CPU_PORT, |
|---|
| 1954 | 2374 | .vta_regs = B53_VTA_REGS, |
|---|
| 1955 | 2375 | .duplex_reg = B53_DUPLEX_STAT_GE, |
|---|
| .. | .. |
|---|
| 1961 | 2381 | .dev_name = "BCM63xx", |
|---|
| 1962 | 2382 | .vlans = 4096, |
|---|
| 1963 | 2383 | .enabled_ports = 0, /* pdata must provide them */ |
|---|
| 1964 | | - .arl_entries = 4, |
|---|
| 2384 | + .arl_bins = 4, |
|---|
| 2385 | + .arl_buckets = 1024, |
|---|
| 2386 | + .imp_port = 8, |
|---|
| 1965 | 2387 | .cpu_port = B53_CPU_PORT, |
|---|
| 1966 | 2388 | .vta_regs = B53_VTA_REGS_63XX, |
|---|
| 1967 | 2389 | .duplex_reg = B53_DUPLEX_STAT_63XX, |
|---|
| .. | .. |
|---|
| 1973 | 2395 | .dev_name = "BCM53010", |
|---|
| 1974 | 2396 | .vlans = 4096, |
|---|
| 1975 | 2397 | .enabled_ports = 0x1f, |
|---|
| 1976 | | - .arl_entries = 4, |
|---|
| 2398 | + .arl_bins = 4, |
|---|
| 2399 | + .arl_buckets = 1024, |
|---|
| 2400 | + .imp_port = 8, |
|---|
| 1977 | 2401 | .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */ |
|---|
| 1978 | 2402 | .vta_regs = B53_VTA_REGS, |
|---|
| 1979 | 2403 | .duplex_reg = B53_DUPLEX_STAT_GE, |
|---|
| .. | .. |
|---|
| 1985 | 2409 | .dev_name = "BCM53011", |
|---|
| 1986 | 2410 | .vlans = 4096, |
|---|
| 1987 | 2411 | .enabled_ports = 0x1bf, |
|---|
| 1988 | | - .arl_entries = 4, |
|---|
| 2412 | + .arl_bins = 4, |
|---|
| 2413 | + .arl_buckets = 1024, |
|---|
| 2414 | + .imp_port = 8, |
|---|
| 1989 | 2415 | .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */ |
|---|
| 1990 | 2416 | .vta_regs = B53_VTA_REGS, |
|---|
| 1991 | 2417 | .duplex_reg = B53_DUPLEX_STAT_GE, |
|---|
| .. | .. |
|---|
| 1997 | 2423 | .dev_name = "BCM53012", |
|---|
| 1998 | 2424 | .vlans = 4096, |
|---|
| 1999 | 2425 | .enabled_ports = 0x1bf, |
|---|
| 2000 | | - .arl_entries = 4, |
|---|
| 2426 | + .arl_bins = 4, |
|---|
| 2427 | + .arl_buckets = 1024, |
|---|
| 2428 | + .imp_port = 8, |
|---|
| 2001 | 2429 | .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */ |
|---|
| 2002 | 2430 | .vta_regs = B53_VTA_REGS, |
|---|
| 2003 | 2431 | .duplex_reg = B53_DUPLEX_STAT_GE, |
|---|
| .. | .. |
|---|
| 2009 | 2437 | .dev_name = "BCM53018", |
|---|
| 2010 | 2438 | .vlans = 4096, |
|---|
| 2011 | 2439 | .enabled_ports = 0x1f, |
|---|
| 2012 | | - .arl_entries = 4, |
|---|
| 2440 | + .arl_bins = 4, |
|---|
| 2441 | + .arl_buckets = 1024, |
|---|
| 2442 | + .imp_port = 8, |
|---|
| 2013 | 2443 | .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */ |
|---|
| 2014 | 2444 | .vta_regs = B53_VTA_REGS, |
|---|
| 2015 | 2445 | .duplex_reg = B53_DUPLEX_STAT_GE, |
|---|
| .. | .. |
|---|
| 2021 | 2451 | .dev_name = "BCM53019", |
|---|
| 2022 | 2452 | .vlans = 4096, |
|---|
| 2023 | 2453 | .enabled_ports = 0x1f, |
|---|
| 2024 | | - .arl_entries = 4, |
|---|
| 2454 | + .arl_bins = 4, |
|---|
| 2455 | + .arl_buckets = 1024, |
|---|
| 2456 | + .imp_port = 8, |
|---|
| 2025 | 2457 | .cpu_port = B53_CPU_PORT_25, /* TODO: auto detect */ |
|---|
| 2026 | 2458 | .vta_regs = B53_VTA_REGS, |
|---|
| 2027 | 2459 | .duplex_reg = B53_DUPLEX_STAT_GE, |
|---|
| .. | .. |
|---|
| 2033 | 2465 | .dev_name = "BCM585xx/586xx/88312", |
|---|
| 2034 | 2466 | .vlans = 4096, |
|---|
| 2035 | 2467 | .enabled_ports = 0x1ff, |
|---|
| 2036 | | - .arl_entries = 4, |
|---|
| 2468 | + .arl_bins = 4, |
|---|
| 2469 | + .arl_buckets = 1024, |
|---|
| 2470 | + .imp_port = 8, |
|---|
| 2037 | 2471 | .cpu_port = B53_CPU_PORT, |
|---|
| 2038 | 2472 | .vta_regs = B53_VTA_REGS, |
|---|
| 2039 | 2473 | .duplex_reg = B53_DUPLEX_STAT_GE, |
|---|
| .. | .. |
|---|
| 2045 | 2479 | .dev_name = "BCM583xx/11360", |
|---|
| 2046 | 2480 | .vlans = 4096, |
|---|
| 2047 | 2481 | .enabled_ports = 0x103, |
|---|
| 2048 | | - .arl_entries = 4, |
|---|
| 2482 | + .arl_bins = 4, |
|---|
| 2483 | + .arl_buckets = 1024, |
|---|
| 2484 | + .imp_port = 8, |
|---|
| 2049 | 2485 | .cpu_port = B53_CPU_PORT, |
|---|
| 2050 | 2486 | .vta_regs = B53_VTA_REGS, |
|---|
| 2051 | 2487 | .duplex_reg = B53_DUPLEX_STAT_GE, |
|---|
| .. | .. |
|---|
| 2057 | 2493 | .dev_name = "BCM7445", |
|---|
| 2058 | 2494 | .vlans = 4096, |
|---|
| 2059 | 2495 | .enabled_ports = 0x1ff, |
|---|
| 2060 | | - .arl_entries = 4, |
|---|
| 2496 | + .arl_bins = 4, |
|---|
| 2497 | + .arl_buckets = 1024, |
|---|
| 2498 | + .imp_port = 8, |
|---|
| 2061 | 2499 | .cpu_port = B53_CPU_PORT, |
|---|
| 2062 | 2500 | .vta_regs = B53_VTA_REGS, |
|---|
| 2063 | 2501 | .duplex_reg = B53_DUPLEX_STAT_GE, |
|---|
| .. | .. |
|---|
| 2069 | 2507 | .dev_name = "BCM7278", |
|---|
| 2070 | 2508 | .vlans = 4096, |
|---|
| 2071 | 2509 | .enabled_ports = 0x1ff, |
|---|
| 2072 | | - .arl_entries= 4, |
|---|
| 2510 | + .arl_bins = 4, |
|---|
| 2511 | + .arl_buckets = 256, |
|---|
| 2512 | + .imp_port = 8, |
|---|
| 2073 | 2513 | .cpu_port = B53_CPU_PORT, |
|---|
| 2074 | 2514 | .vta_regs = B53_VTA_REGS, |
|---|
| 2075 | 2515 | .duplex_reg = B53_DUPLEX_STAT_GE, |
|---|
| .. | .. |
|---|
| 2095 | 2535 | dev->vta_regs[1] = chip->vta_regs[1]; |
|---|
| 2096 | 2536 | dev->vta_regs[2] = chip->vta_regs[2]; |
|---|
| 2097 | 2537 | dev->jumbo_pm_reg = chip->jumbo_pm_reg; |
|---|
| 2538 | + dev->imp_port = chip->imp_port; |
|---|
| 2098 | 2539 | dev->cpu_port = chip->cpu_port; |
|---|
| 2099 | 2540 | dev->num_vlans = chip->vlans; |
|---|
| 2100 | | - dev->num_arl_entries = chip->arl_entries; |
|---|
| 2541 | + dev->num_arl_bins = chip->arl_bins; |
|---|
| 2542 | + dev->num_arl_buckets = chip->arl_buckets; |
|---|
| 2101 | 2543 | break; |
|---|
| 2102 | 2544 | } |
|---|
| 2103 | 2545 | } |
|---|
| .. | .. |
|---|
| 2138 | 2580 | dev->enabled_ports |= BIT(dev->cpu_port); |
|---|
| 2139 | 2581 | dev->num_ports = fls(dev->enabled_ports); |
|---|
| 2140 | 2582 | |
|---|
| 2583 | + dev->ds->num_ports = min_t(unsigned int, dev->num_ports, DSA_MAX_PORTS); |
|---|
| 2584 | + |
|---|
| 2141 | 2585 | /* Include non standard CPU port built-in PHYs to be probed */ |
|---|
| 2142 | 2586 | if (is539x(dev) || is531x5(dev)) { |
|---|
| 2143 | 2587 | for (i = 0; i < dev->num_ports; i++) { |
|---|
| .. | .. |
|---|
| 2177 | 2621 | struct dsa_switch *ds; |
|---|
| 2178 | 2622 | struct b53_device *dev; |
|---|
| 2179 | 2623 | |
|---|
| 2180 | | - ds = dsa_switch_alloc(base, DSA_MAX_PORTS); |
|---|
| 2624 | + ds = devm_kzalloc(base, sizeof(*ds), GFP_KERNEL); |
|---|
| 2181 | 2625 | if (!ds) |
|---|
| 2182 | 2626 | return NULL; |
|---|
| 2627 | + |
|---|
| 2628 | + ds->dev = base; |
|---|
| 2183 | 2629 | |
|---|
| 2184 | 2630 | dev = devm_kzalloc(base, sizeof(*dev), GFP_KERNEL); |
|---|
| 2185 | 2631 | if (!dev) |
|---|
| .. | .. |
|---|
| 2192 | 2638 | dev->priv = priv; |
|---|
| 2193 | 2639 | dev->ops = ops; |
|---|
| 2194 | 2640 | ds->ops = &b53_switch_ops; |
|---|
| 2641 | + ds->configure_vlan_while_not_filtering = true; |
|---|
| 2642 | + ds->untag_bridge_pvid = true; |
|---|
| 2643 | + dev->vlan_enabled = ds->configure_vlan_while_not_filtering; |
|---|
| 2644 | + /* Let DSA handle the case were multiple bridges span the same switch |
|---|
| 2645 | + * device and different VLAN awareness settings are requested, which |
|---|
| 2646 | + * would be breaking filtering semantics for any of the other bridge |
|---|
| 2647 | + * devices. (not hardware supported) |
|---|
| 2648 | + */ |
|---|
| 2649 | + ds->vlan_filtering_is_global = true; |
|---|
| 2650 | + |
|---|
| 2195 | 2651 | mutex_init(&dev->reg_mutex); |
|---|
| 2196 | 2652 | mutex_init(&dev->stats_mutex); |
|---|
| 2197 | 2653 | |
|---|
| .. | .. |
|---|
| 2250 | 2706 | dev->chip_id = id32; |
|---|
| 2251 | 2707 | break; |
|---|
| 2252 | 2708 | default: |
|---|
| 2253 | | - pr_err("unsupported switch detected (BCM53%02x/BCM%x)\n", |
|---|
| 2254 | | - id8, id32); |
|---|
| 2709 | + dev_err(dev->dev, |
|---|
| 2710 | + "unsupported switch detected (BCM53%02x/BCM%x)\n", |
|---|
| 2711 | + id8, id32); |
|---|
| 2255 | 2712 | return -ENODEV; |
|---|
| 2256 | 2713 | } |
|---|
| 2257 | 2714 | } |
|---|
| .. | .. |
|---|
| 2281 | 2738 | if (ret) |
|---|
| 2282 | 2739 | return ret; |
|---|
| 2283 | 2740 | |
|---|
| 2284 | | - pr_info("found switch: %s, rev %i\n", dev->name, dev->core_rev); |
|---|
| 2741 | + dev_info(dev->dev, "found switch: %s, rev %i\n", |
|---|
| 2742 | + dev->name, dev->core_rev); |
|---|
| 2285 | 2743 | |
|---|
| 2286 | 2744 | return dsa_register_switch(dev->ds); |
|---|
| 2287 | 2745 | } |
|---|