summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/dsa/mv88e6171.c2
-rw-r--r--drivers/net/dsa/mv88e6352.c2
-rw-r--r--drivers/net/dsa/mv88e6xxx.c215
-rw-r--r--drivers/net/dsa/mv88e6xxx.h8
-rw-r--r--net/dsa/slave.c2
5 files changed, 26 insertions, 203 deletions
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index ca3330aec740..dfca352e78e3 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -113,8 +113,6 @@ struct dsa_switch_driver mv88e6171_switch_driver = {
113#endif 113#endif
114 .get_regs_len = mv88e6xxx_get_regs_len, 114 .get_regs_len = mv88e6xxx_get_regs_len,
115 .get_regs = mv88e6xxx_get_regs, 115 .get_regs = mv88e6xxx_get_regs,
116 .port_join_bridge = mv88e6xxx_join_bridge,
117 .port_leave_bridge = mv88e6xxx_leave_bridge,
118 .port_stp_update = mv88e6xxx_port_stp_update, 116 .port_stp_update = mv88e6xxx_port_stp_update,
119 .port_pvid_get = mv88e6xxx_port_pvid_get, 117 .port_pvid_get = mv88e6xxx_port_pvid_get,
120 .port_pvid_set = mv88e6xxx_port_pvid_set, 118 .port_pvid_set = mv88e6xxx_port_pvid_set,
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index 078a358c1b83..796fdcbe3c6e 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -340,8 +340,6 @@ struct dsa_switch_driver mv88e6352_switch_driver = {
340 .set_eeprom = mv88e6352_set_eeprom, 340 .set_eeprom = mv88e6352_set_eeprom,
341 .get_regs_len = mv88e6xxx_get_regs_len, 341 .get_regs_len = mv88e6xxx_get_regs_len,
342 .get_regs = mv88e6xxx_get_regs, 342 .get_regs = mv88e6xxx_get_regs,
343 .port_join_bridge = mv88e6xxx_join_bridge,
344 .port_leave_bridge = mv88e6xxx_leave_bridge,
345 .port_stp_update = mv88e6xxx_port_stp_update, 343 .port_stp_update = mv88e6xxx_port_stp_update,
346 .port_pvid_get = mv88e6xxx_port_pvid_get, 344 .port_pvid_get = mv88e6xxx_port_pvid_get,
347 .port_pvid_set = mv88e6xxx_port_pvid_set, 345 .port_pvid_set = mv88e6xxx_port_pvid_set,
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 87b405e4f9f6..4591240eb795 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -1046,11 +1046,6 @@ static int _mv88e6xxx_atu_flush(struct dsa_switch *ds, u16 fid, bool static_too)
1046 return _mv88e6xxx_atu_flush_move(ds, &entry, static_too); 1046 return _mv88e6xxx_atu_flush_move(ds, &entry, static_too);
1047} 1047}
1048 1048
1049static int _mv88e6xxx_flush_fid(struct dsa_switch *ds, int fid)
1050{
1051 return _mv88e6xxx_atu_flush(ds, fid, false);
1052}
1053
1054static int _mv88e6xxx_atu_move(struct dsa_switch *ds, u16 fid, int from_port, 1049static int _mv88e6xxx_atu_move(struct dsa_switch *ds, u16 fid, int from_port,
1055 int to_port, bool static_too) 1050 int to_port, bool static_too)
1056{ 1051{
@@ -1112,130 +1107,21 @@ abort:
1112 return ret; 1107 return ret;
1113} 1108}
1114 1109
1115/* Must be called with smi lock held */ 1110static int _mv88e6xxx_port_vlan_map_set(struct dsa_switch *ds, int port,
1116static int _mv88e6xxx_update_port_config(struct dsa_switch *ds, int port) 1111 u16 output_ports)
1117{
1118 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1119 u8 fid = ps->fid[port];
1120 u16 reg = fid << 12;
1121
1122 if (dsa_is_cpu_port(ds, port))
1123 reg |= ds->phys_port_mask;
1124 else
1125 reg |= (ps->bridge_mask[fid] |
1126 (1 << dsa_upstream_port(ds))) & ~(1 << port);
1127
1128 return _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_BASE_VLAN, reg);
1129}
1130
1131/* Must be called with smi lock held */
1132static int _mv88e6xxx_update_bridge_config(struct dsa_switch *ds, int fid)
1133{ 1112{
1134 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 1113 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1135 int port; 1114 const u16 mask = (1 << ps->num_ports) - 1;
1136 u32 mask; 1115 int reg;
1137 int ret;
1138
1139 mask = ds->phys_port_mask;
1140 while (mask) {
1141 port = __ffs(mask);
1142 mask &= ~(1 << port);
1143 if (ps->fid[port] != fid)
1144 continue;
1145
1146 ret = _mv88e6xxx_update_port_config(ds, port);
1147 if (ret)
1148 return ret;
1149 }
1150
1151 return _mv88e6xxx_flush_fid(ds, fid);
1152}
1153
1154/* Bridge handling functions */
1155
1156int mv88e6xxx_join_bridge(struct dsa_switch *ds, int port, u32 br_port_mask)
1157{
1158 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1159 int ret = 0;
1160 u32 nmask;
1161 int fid;
1162
1163 /* If the bridge group is not empty, join that group.
1164 * Otherwise create a new group.
1165 */
1166 fid = ps->fid[port];
1167 nmask = br_port_mask & ~(1 << port);
1168 if (nmask)
1169 fid = ps->fid[__ffs(nmask)];
1170
1171 nmask = ps->bridge_mask[fid] | (1 << port);
1172 if (nmask != br_port_mask) {
1173 netdev_err(ds->ports[port],
1174 "join: Bridge port mask mismatch fid=%d mask=0x%x expected 0x%x\n",
1175 fid, br_port_mask, nmask);
1176 return -EINVAL;
1177 }
1178
1179 mutex_lock(&ps->smi_mutex);
1180
1181 ps->bridge_mask[fid] = br_port_mask;
1182
1183 if (fid != ps->fid[port]) {
1184 clear_bit(ps->fid[port], ps->fid_bitmap);
1185 ps->fid[port] = fid;
1186 ret = _mv88e6xxx_update_bridge_config(ds, fid);
1187 }
1188
1189 mutex_unlock(&ps->smi_mutex);
1190
1191 return ret;
1192}
1193
1194int mv88e6xxx_leave_bridge(struct dsa_switch *ds, int port, u32 br_port_mask)
1195{
1196 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1197 u8 fid, newfid;
1198 int ret;
1199
1200 fid = ps->fid[port];
1201
1202 if (ps->bridge_mask[fid] != br_port_mask) {
1203 netdev_err(ds->ports[port],
1204 "leave: Bridge port mask mismatch fid=%d mask=0x%x expected 0x%x\n",
1205 fid, br_port_mask, ps->bridge_mask[fid]);
1206 return -EINVAL;
1207 }
1208
1209 /* If the port was the last port of a bridge, we are done.
1210 * Otherwise assign a new fid to the port, and fix up
1211 * the bridge configuration.
1212 */
1213 if (br_port_mask == (1 << port))
1214 return 0;
1215
1216 mutex_lock(&ps->smi_mutex);
1217
1218 newfid = find_next_zero_bit(ps->fid_bitmap, VLAN_N_VID, 1);
1219 if (unlikely(newfid > ps->num_ports)) {
1220 netdev_err(ds->ports[port], "all first %d FIDs are used\n",
1221 ps->num_ports);
1222 ret = -ENOSPC;
1223 goto unlock;
1224 }
1225
1226 ps->fid[port] = newfid;
1227 set_bit(newfid, ps->fid_bitmap);
1228 ps->bridge_mask[fid] &= ~(1 << port);
1229 ps->bridge_mask[newfid] = 1 << port;
1230 1116
1231 ret = _mv88e6xxx_update_bridge_config(ds, fid); 1117 reg = _mv88e6xxx_reg_read(ds, REG_PORT(port), PORT_BASE_VLAN);
1232 if (!ret) 1118 if (reg < 0)
1233 ret = _mv88e6xxx_update_bridge_config(ds, newfid); 1119 return reg;
1234 1120
1235unlock: 1121 reg &= ~mask;
1236 mutex_unlock(&ps->smi_mutex); 1122 reg |= output_ports & mask;
1237 1123
1238 return ret; 1124 return _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_BASE_VLAN, reg);
1239} 1125}
1240 1126
1241int mv88e6xxx_port_stp_update(struct dsa_switch *ds, int port, u8 state) 1127int mv88e6xxx_port_stp_update(struct dsa_switch *ds, int port, u8 state)
@@ -1547,6 +1433,7 @@ static int _mv88e6xxx_vlan_init(struct dsa_switch *ds, u16 vid,
1547 struct mv88e6xxx_vtu_stu_entry vlan = { 1433 struct mv88e6xxx_vtu_stu_entry vlan = {
1548 .valid = true, 1434 .valid = true,
1549 .vid = vid, 1435 .vid = vid,
1436 .fid = vid, /* We use one FID per VLAN */
1550 }; 1437 };
1551 int i; 1438 int i;
1552 1439
@@ -1580,22 +1467,10 @@ static int _mv88e6xxx_vlan_init(struct dsa_switch *ds, u16 vid,
1580 return err; 1467 return err;
1581 } 1468 }
1582 1469
1583 /* Non-bridged ports and bridge groups use FIDs from 1 to
1584 * num_ports; VLANs use FIDs from num_ports+1 to 4095.
1585 */
1586 vlan.fid = find_next_zero_bit(ps->fid_bitmap, VLAN_N_VID,
1587 ps->num_ports + 1);
1588 if (unlikely(vlan.fid == VLAN_N_VID)) {
1589 pr_err("no more FID available for VLAN %d\n", vid);
1590 return -ENOSPC;
1591 }
1592
1593 /* Clear all MAC addresses from the new database */ 1470 /* Clear all MAC addresses from the new database */
1594 err = _mv88e6xxx_atu_flush(ds, vlan.fid, true); 1471 err = _mv88e6xxx_atu_flush(ds, vlan.fid, true);
1595 if (err) 1472 if (err)
1596 return err; 1473 return err;
1597
1598 set_bit(vlan.fid, ps->fid_bitmap);
1599 } 1474 }
1600 1475
1601 *entry = vlan; 1476 *entry = vlan;
@@ -1635,7 +1510,6 @@ int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, u16 vid)
1635{ 1510{
1636 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 1511 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1637 struct mv88e6xxx_vtu_stu_entry vlan; 1512 struct mv88e6xxx_vtu_stu_entry vlan;
1638 bool keep = false;
1639 int i, err; 1513 int i, err;
1640 1514
1641 mutex_lock(&ps->smi_mutex); 1515 mutex_lock(&ps->smi_mutex);
@@ -1653,28 +1527,22 @@ int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, u16 vid)
1653 vlan.data[port] = GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER; 1527 vlan.data[port] = GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER;
1654 1528
1655 /* keep the VLAN unless all ports are excluded */ 1529 /* keep the VLAN unless all ports are excluded */
1530 vlan.valid = false;
1656 for (i = 0; i < ps->num_ports; ++i) { 1531 for (i = 0; i < ps->num_ports; ++i) {
1657 if (dsa_is_cpu_port(ds, i)) 1532 if (dsa_is_cpu_port(ds, i))
1658 continue; 1533 continue;
1659 1534
1660 if (vlan.data[i] != GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER) { 1535 if (vlan.data[i] != GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER) {
1661 keep = true; 1536 vlan.valid = true;
1662 break; 1537 break;
1663 } 1538 }
1664 } 1539 }
1665 1540
1666 vlan.valid = keep;
1667 err = _mv88e6xxx_vtu_loadpurge(ds, &vlan); 1541 err = _mv88e6xxx_vtu_loadpurge(ds, &vlan);
1668 if (err) 1542 if (err)
1669 goto unlock; 1543 goto unlock;
1670 1544
1671 err = _mv88e6xxx_atu_remove(ds, vlan.fid, port, false); 1545 err = _mv88e6xxx_atu_remove(ds, vlan.fid, port, false);
1672 if (err)
1673 goto unlock;
1674
1675 if (!keep)
1676 clear_bit(vlan.fid, ps->fid_bitmap);
1677
1678unlock: 1546unlock:
1679 mutex_unlock(&ps->smi_mutex); 1547 mutex_unlock(&ps->smi_mutex);
1680 1548
@@ -1801,37 +1669,13 @@ static int _mv88e6xxx_atu_load(struct dsa_switch *ds,
1801 return _mv88e6xxx_atu_cmd(ds, GLOBAL_ATU_OP_LOAD_DB); 1669 return _mv88e6xxx_atu_cmd(ds, GLOBAL_ATU_OP_LOAD_DB);
1802} 1670}
1803 1671
1804static int _mv88e6xxx_port_vid_to_fid(struct dsa_switch *ds, int port, u16 vid)
1805{
1806 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1807 struct mv88e6xxx_vtu_stu_entry vlan;
1808 int err;
1809
1810 if (vid == 0)
1811 return ps->fid[port];
1812
1813 err = _mv88e6xxx_port_vtu_getnext(ds, port, vid - 1, &vlan);
1814 if (err)
1815 return err;
1816
1817 if (vlan.vid == vid)
1818 return vlan.fid;
1819
1820 return -ENOENT;
1821}
1822
1823static int _mv88e6xxx_port_fdb_load(struct dsa_switch *ds, int port, 1672static int _mv88e6xxx_port_fdb_load(struct dsa_switch *ds, int port,
1824 const unsigned char *addr, u16 vid, 1673 const unsigned char *addr, u16 vid,
1825 u8 state) 1674 u8 state)
1826{ 1675{
1827 struct mv88e6xxx_atu_entry entry = { 0 }; 1676 struct mv88e6xxx_atu_entry entry = { 0 };
1828 int ret;
1829 1677
1830 ret = _mv88e6xxx_port_vid_to_fid(ds, port, vid); 1678 entry.fid = vid; /* We use one FID per VLAN */
1831 if (ret < 0)
1832 return ret;
1833
1834 entry.fid = ret;
1835 entry.state = state; 1679 entry.state = state;
1836 ether_addr_copy(entry.mac, addr); 1680 ether_addr_copy(entry.mac, addr);
1837 if (state != GLOBAL_ATU_DATA_STATE_UNUSED) { 1681 if (state != GLOBAL_ATU_DATA_STATE_UNUSED) {
@@ -1846,6 +1690,10 @@ int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port,
1846 const struct switchdev_obj_port_fdb *fdb, 1690 const struct switchdev_obj_port_fdb *fdb,
1847 struct switchdev_trans *trans) 1691 struct switchdev_trans *trans)
1848{ 1692{
1693 /* We don't use per-port FDB */
1694 if (fdb->vid == 0)
1695 return -EOPNOTSUPP;
1696
1849 /* We don't need any dynamic resource from the kernel (yet), 1697 /* We don't need any dynamic resource from the kernel (yet),
1850 * so skip the prepare phase. 1698 * so skip the prepare phase.
1851 */ 1699 */
@@ -1943,16 +1791,11 @@ int mv88e6xxx_port_fdb_getnext(struct dsa_switch *ds, int port,
1943{ 1791{
1944 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 1792 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
1945 struct mv88e6xxx_atu_entry next; 1793 struct mv88e6xxx_atu_entry next;
1946 u16 fid; 1794 u16 fid = *vid; /* We use one FID per VLAN */
1947 int ret; 1795 int ret;
1948 1796
1949 mutex_lock(&ps->smi_mutex); 1797 mutex_lock(&ps->smi_mutex);
1950 1798
1951 ret = _mv88e6xxx_port_vid_to_fid(ds, port, *vid);
1952 if (ret < 0)
1953 goto unlock;
1954 fid = ret;
1955
1956 do { 1799 do {
1957 if (is_broadcast_ether_addr(addr)) { 1800 if (is_broadcast_ether_addr(addr)) {
1958 struct mv88e6xxx_vtu_stu_entry vtu; 1801 struct mv88e6xxx_vtu_stu_entry vtu;
@@ -2003,7 +1846,7 @@ static void mv88e6xxx_bridge_work(struct work_struct *work)
2003static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port) 1846static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port)
2004{ 1847{
2005 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 1848 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
2006 int ret, fid; 1849 int ret;
2007 u16 reg; 1850 u16 reg;
2008 1851
2009 mutex_lock(&ps->smi_mutex); 1852 mutex_lock(&ps->smi_mutex);
@@ -2129,7 +1972,7 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port)
2129 reg |= PORT_CONTROL_2_FORWARD_UNKNOWN; 1972 reg |= PORT_CONTROL_2_FORWARD_UNKNOWN;
2130 } 1973 }
2131 1974
2132 reg |= PORT_CONTROL_2_8021Q_FALLBACK; 1975 reg |= PORT_CONTROL_2_8021Q_SECURE;
2133 1976
2134 if (reg) { 1977 if (reg) {
2135 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), 1978 ret = _mv88e6xxx_reg_write(ds, REG_PORT(port),
@@ -2222,19 +2065,11 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port)
2222 if (ret) 2065 if (ret)
2223 goto abort; 2066 goto abort;
2224 2067
2225 /* Port based VLAN map: give each port its own address 2068 /* Port based VLAN map: do not give each port its own address
2226 * database, allow the CPU port to talk to each of the 'real' 2069 * database, and allow every port to egress frames on all other ports.
2227 * ports, and allow each of the 'real' ports to only talk to
2228 * the upstream port.
2229 */ 2070 */
2230 fid = port + 1; 2071 reg = BIT(ps->num_ports) - 1; /* all ports */
2231 ps->fid[port] = fid; 2072 ret = _mv88e6xxx_port_vlan_map_set(ds, port, reg & ~port);
2232 set_bit(fid, ps->fid_bitmap);
2233
2234 if (!dsa_is_cpu_port(ds, port))
2235 ps->bridge_mask[fid] = 1 << port;
2236
2237 ret = _mv88e6xxx_update_port_config(ds, port);
2238 if (ret) 2073 if (ret)
2239 goto abort; 2074 goto abort;
2240 2075
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 8325c11b9be2..4ba69f339bfe 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -402,12 +402,6 @@ struct mv88e6xxx_priv_state {
402 int id; /* switch product id */ 402 int id; /* switch product id */
403 int num_ports; /* number of switch ports */ 403 int num_ports; /* number of switch ports */
404 404
405 /* hw bridging */
406
407 DECLARE_BITMAP(fid_bitmap, VLAN_N_VID); /* FIDs 1 to 4095 available */
408 u16 fid[DSA_MAX_PORTS]; /* per (non-bridged) port FID */
409 u16 bridge_mask[DSA_MAX_PORTS]; /* br groups (indexed by FID) */
410
411 unsigned long port_state_update_mask; 405 unsigned long port_state_update_mask;
412 u8 port_state[DSA_MAX_PORTS]; 406 u8 port_state[DSA_MAX_PORTS];
413 407
@@ -464,8 +458,6 @@ int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int addr, int regnum,
464int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e); 458int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e);
465int mv88e6xxx_set_eee(struct dsa_switch *ds, int port, 459int mv88e6xxx_set_eee(struct dsa_switch *ds, int port,
466 struct phy_device *phydev, struct ethtool_eee *e); 460 struct phy_device *phydev, struct ethtool_eee *e);
467int mv88e6xxx_join_bridge(struct dsa_switch *ds, int port, u32 br_port_mask);
468int mv88e6xxx_leave_bridge(struct dsa_switch *ds, int port, u32 br_port_mask);
469int mv88e6xxx_port_stp_update(struct dsa_switch *ds, int port, u8 state); 461int mv88e6xxx_port_stp_update(struct dsa_switch *ds, int port, u8 state);
470int mv88e6xxx_port_pvid_get(struct dsa_switch *ds, int port, u16 *vid); 462int mv88e6xxx_port_pvid_get(struct dsa_switch *ds, int port, u16 *vid);
471int mv88e6xxx_port_pvid_set(struct dsa_switch *ds, int port, u16 vid); 463int mv88e6xxx_port_pvid_set(struct dsa_switch *ds, int port, u16 vid);
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index bb2bd3b56b16..43d7342e7527 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -1276,7 +1276,7 @@ int dsa_slave_netdevice_event(struct notifier_block *unused,
1276 goto out; 1276 goto out;
1277 1277
1278 err = dsa_slave_master_changed(dev); 1278 err = dsa_slave_master_changed(dev);
1279 if (err) 1279 if (err && err != -EOPNOTSUPP)
1280 netdev_warn(dev, "failed to reflect master change\n"); 1280 netdev_warn(dev, "failed to reflect master change\n");
1281 1281
1282 break; 1282 break;