ocelot.c (6d5a763c303bc9d78b17361d30b692ba2facf9b4) ocelot.c (97bb69e1e36e960b0ecfa2be5ea75ec357a61c3f)
1// SPDX-License-Identifier: (GPL-2.0 OR MIT)
2/*
3 * Microsemi Ocelot Switch driver
4 *
5 * Copyright (c) 2017 Microsemi Corporation
6 */
7#include <linux/etherdevice.h>
8#include <linux/ethtool.h>

--- 171 unchanged lines hidden (view full) ---

180 val = ocelot_read(ocelot, ANA_VLANMASK);
181 if (features & NETIF_F_HW_VLAN_CTAG_FILTER)
182 val |= BIT(p);
183 else
184 val &= ~BIT(p);
185 ocelot_write(ocelot, val, ANA_VLANMASK);
186}
187
1// SPDX-License-Identifier: (GPL-2.0 OR MIT)
2/*
3 * Microsemi Ocelot Switch driver
4 *
5 * Copyright (c) 2017 Microsemi Corporation
6 */
7#include <linux/etherdevice.h>
8#include <linux/ethtool.h>

--- 171 unchanged lines hidden (view full) ---

180 val = ocelot_read(ocelot, ANA_VLANMASK);
181 if (features & NETIF_F_HW_VLAN_CTAG_FILTER)
182 val |= BIT(p);
183 else
184 val &= ~BIT(p);
185 ocelot_write(ocelot, val, ANA_VLANMASK);
186}
187
188static void ocelot_vlan_port_apply(struct ocelot *ocelot,
189 struct ocelot_port *port)
188static void ocelot_port_vlan_filtering(struct ocelot *ocelot, int port,
189 bool vlan_aware)
190{
190{
191 struct ocelot_port *ocelot_port = ocelot->ports[port];
191 u32 val;
192
192 u32 val;
193
193 /* Ingress clasification (ANA_PORT_VLAN_CFG) */
194 /* Default vlan to clasify for untagged frames (may be zero) */
195 val = ANA_PORT_VLAN_CFG_VLAN_VID(port->pvid);
196 if (port->vlan_aware)
197 val |= ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA |
198 ANA_PORT_VLAN_CFG_VLAN_POP_CNT(1);
199
194 if (vlan_aware)
195 val = ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA |
196 ANA_PORT_VLAN_CFG_VLAN_POP_CNT(1);
197 else
198 val = 0;
200 ocelot_rmw_gix(ocelot, val,
199 ocelot_rmw_gix(ocelot, val,
201 ANA_PORT_VLAN_CFG_VLAN_VID_M |
202 ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA |
203 ANA_PORT_VLAN_CFG_VLAN_POP_CNT_M,
200 ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA |
201 ANA_PORT_VLAN_CFG_VLAN_POP_CNT_M,
204 ANA_PORT_VLAN_CFG, port->chip_port);
202 ANA_PORT_VLAN_CFG, port);
205
203
206 /* Drop frames with multicast source address */
207 val = ANA_PORT_DROP_CFG_DROP_MC_SMAC_ENA;
208 if (port->vlan_aware && !port->vid)
204 if (vlan_aware && !ocelot_port->vid)
209 /* If port is vlan-aware and tagged, drop untagged and priority
210 * tagged frames.
211 */
205 /* If port is vlan-aware and tagged, drop untagged and priority
206 * tagged frames.
207 */
212 val |= ANA_PORT_DROP_CFG_DROP_UNTAGGED_ENA |
208 val = ANA_PORT_DROP_CFG_DROP_UNTAGGED_ENA |
209 ANA_PORT_DROP_CFG_DROP_PRIO_S_TAGGED_ENA |
210 ANA_PORT_DROP_CFG_DROP_PRIO_C_TAGGED_ENA;
211 else
212 val = 0;
213 ocelot_rmw_gix(ocelot, val,
214 ANA_PORT_DROP_CFG_DROP_UNTAGGED_ENA |
213 ANA_PORT_DROP_CFG_DROP_PRIO_S_TAGGED_ENA |
215 ANA_PORT_DROP_CFG_DROP_PRIO_S_TAGGED_ENA |
214 ANA_PORT_DROP_CFG_DROP_PRIO_C_TAGGED_ENA;
215 ocelot_write_gix(ocelot, val, ANA_PORT_DROP_CFG, port->chip_port);
216 ANA_PORT_DROP_CFG_DROP_PRIO_C_TAGGED_ENA,
217 ANA_PORT_DROP_CFG, port);
216
218
217 /* Egress configuration (REW_TAG_CFG): VLAN tag type to 8021Q. */
218 val = REW_TAG_CFG_TAG_TPID_CFG(0);
219
220 if (port->vlan_aware) {
221 if (port->vid)
219 if (vlan_aware) {
220 if (ocelot_port->vid)
222 /* Tag all frames except when VID == DEFAULT_VLAN */
223 val |= REW_TAG_CFG_TAG_CFG(1);
224 else
225 /* Tag all frames */
226 val |= REW_TAG_CFG_TAG_CFG(3);
221 /* Tag all frames except when VID == DEFAULT_VLAN */
222 val |= REW_TAG_CFG_TAG_CFG(1);
223 else
224 /* Tag all frames */
225 val |= REW_TAG_CFG_TAG_CFG(3);
226 } else {
227 /* Port tagging disabled. */
228 val = REW_TAG_CFG_TAG_CFG(0);
227 }
228 ocelot_rmw_gix(ocelot, val,
229 }
230 ocelot_rmw_gix(ocelot, val,
229 REW_TAG_CFG_TAG_TPID_CFG_M |
230 REW_TAG_CFG_TAG_CFG_M,
231 REW_TAG_CFG_TAG_CFG_M,
231 REW_TAG_CFG, port->chip_port);
232 REW_TAG_CFG, port);
232
233
233 /* Set default VLAN and tag type to 8021Q. */
234 val = REW_PORT_VLAN_CFG_PORT_TPID(ETH_P_8021Q) |
235 REW_PORT_VLAN_CFG_PORT_VID(port->vid);
236 ocelot_rmw_gix(ocelot, val,
237 REW_PORT_VLAN_CFG_PORT_TPID_M |
234 ocelot_port->vlan_aware = vlan_aware;
235}
236
237static int ocelot_port_set_native_vlan(struct ocelot *ocelot, int port,
238 u16 vid)
239{
240 struct ocelot_port *ocelot_port = ocelot->ports[port];
241
242 if (ocelot_port->vid != vid) {
243 /* Always permit deleting the native VLAN (vid = 0) */
244 if (ocelot_port->vid && vid) {
245 dev_err(ocelot->dev,
246 "Port already has a native VLAN: %d\n",
247 ocelot_port->vid);
248 return -EBUSY;
249 }
250 ocelot_port->vid = vid;
251 }
252
253 ocelot_rmw_gix(ocelot, REW_PORT_VLAN_CFG_PORT_VID(vid),
238 REW_PORT_VLAN_CFG_PORT_VID_M,
254 REW_PORT_VLAN_CFG_PORT_VID_M,
239 REW_PORT_VLAN_CFG, port->chip_port);
255 REW_PORT_VLAN_CFG, port);
256
257 return 0;
240}
241
258}
259
260/* Default vlan to clasify for untagged frames (may be zero) */
261static void ocelot_port_set_pvid(struct ocelot *ocelot, int port, u16 pvid)
262{
263 struct ocelot_port *ocelot_port = ocelot->ports[port];
264
265 ocelot_rmw_gix(ocelot,
266 ANA_PORT_VLAN_CFG_VLAN_VID(pvid),
267 ANA_PORT_VLAN_CFG_VLAN_VID_M,
268 ANA_PORT_VLAN_CFG, port);
269
270 ocelot_port->pvid = pvid;
271}
272
242static int ocelot_vlan_vid_add(struct net_device *dev, u16 vid, bool pvid,
243 bool untagged)
244{
273static int ocelot_vlan_vid_add(struct net_device *dev, u16 vid, bool pvid,
274 bool untagged)
275{
245 struct ocelot_port *port = netdev_priv(dev);
246 struct ocelot *ocelot = port->ocelot;
276 struct ocelot_port *ocelot_port = netdev_priv(dev);
277 struct ocelot *ocelot = ocelot_port->ocelot;
278 int port = ocelot_port->chip_port;
247 int ret;
248
249 /* Add the port MAC address to with the right VLAN information */
250 ocelot_mact_learn(ocelot, PGID_CPU, dev->dev_addr, vid,
251 ENTRYTYPE_LOCKED);
252
253 /* Make the port a member of the VLAN */
279 int ret;
280
281 /* Add the port MAC address to with the right VLAN information */
282 ocelot_mact_learn(ocelot, PGID_CPU, dev->dev_addr, vid,
283 ENTRYTYPE_LOCKED);
284
285 /* Make the port a member of the VLAN */
254 ocelot->vlan_mask[vid] |= BIT(port->chip_port);
286 ocelot->vlan_mask[vid] |= BIT(port);
255 ret = ocelot_vlant_set_mask(ocelot, vid, ocelot->vlan_mask[vid]);
256 if (ret)
257 return ret;
258
259 /* Default ingress vlan classification */
260 if (pvid)
287 ret = ocelot_vlant_set_mask(ocelot, vid, ocelot->vlan_mask[vid]);
288 if (ret)
289 return ret;
290
291 /* Default ingress vlan classification */
292 if (pvid)
261 port->pvid = vid;
293 ocelot_port_set_pvid(ocelot, port, vid);
262
263 /* Untagged egress vlan clasification */
294
295 /* Untagged egress vlan clasification */
264 if (untagged && port->vid != vid) {
265 if (port->vid) {
266 dev_err(ocelot->dev,
267 "Port already has a native VLAN: %d\n",
268 port->vid);
269 return -EBUSY;
270 }
271 port->vid = vid;
296 if (untagged) {
297 ret = ocelot_port_set_native_vlan(ocelot, port, vid);
298 if (ret)
299 return ret;
272 }
273
300 }
301
274 ocelot_vlan_port_apply(ocelot, port);
275
276 return 0;
277}
278
279static int ocelot_vlan_vid_del(struct net_device *dev, u16 vid)
280{
302 return 0;
303}
304
305static int ocelot_vlan_vid_del(struct net_device *dev, u16 vid)
306{
281 struct ocelot_port *port = netdev_priv(dev);
282 struct ocelot *ocelot = port->ocelot;
307 struct ocelot_port *ocelot_port = netdev_priv(dev);
308 struct ocelot *ocelot = ocelot_port->ocelot;
309 int port = ocelot_port->chip_port;
283 int ret;
284
285 /* 8021q removes VID 0 on module unload for all interfaces
286 * with VLAN filtering feature. We need to keep it to receive
287 * untagged traffic.
288 */
289 if (vid == 0)
290 return 0;
291
292 /* Del the port MAC address to with the right VLAN information */
293 ocelot_mact_forget(ocelot, dev->dev_addr, vid);
294
295 /* Stop the port from being a member of the vlan */
310 int ret;
311
312 /* 8021q removes VID 0 on module unload for all interfaces
313 * with VLAN filtering feature. We need to keep it to receive
314 * untagged traffic.
315 */
316 if (vid == 0)
317 return 0;
318
319 /* Del the port MAC address to with the right VLAN information */
320 ocelot_mact_forget(ocelot, dev->dev_addr, vid);
321
322 /* Stop the port from being a member of the vlan */
296 ocelot->vlan_mask[vid] &= ~BIT(port->chip_port);
323 ocelot->vlan_mask[vid] &= ~BIT(port);
297 ret = ocelot_vlant_set_mask(ocelot, vid, ocelot->vlan_mask[vid]);
298 if (ret)
299 return ret;
300
301 /* Ingress */
324 ret = ocelot_vlant_set_mask(ocelot, vid, ocelot->vlan_mask[vid]);
325 if (ret)
326 return ret;
327
328 /* Ingress */
302 if (port->pvid == vid)
303 port->pvid = 0;
329 if (ocelot_port->pvid == vid)
330 ocelot_port_set_pvid(ocelot, port, 0);
304
305 /* Egress */
331
332 /* Egress */
306 if (port->vid == vid)
307 port->vid = 0;
333 if (ocelot_port->vid == vid)
334 ocelot_port_set_native_vlan(ocelot, port, 0);
308
335
309 ocelot_vlan_port_apply(ocelot, port);
310
311 return 0;
312}
313
314static void ocelot_vlan_init(struct ocelot *ocelot)
315{
316 u16 port, vid;
317
318 /* Clear VLAN table, by default all ports are members of all VLANs */

--- 982 unchanged lines hidden (view full) ---

1301 ocelot_write_gix(ocelot, val, ANA_PORT_CPU_FWD_CFG, port->chip_port);
1302}
1303
1304static int ocelot_port_attr_set(struct net_device *dev,
1305 const struct switchdev_attr *attr,
1306 struct switchdev_trans *trans)
1307{
1308 struct ocelot_port *ocelot_port = netdev_priv(dev);
336 return 0;
337}
338
339static void ocelot_vlan_init(struct ocelot *ocelot)
340{
341 u16 port, vid;
342
343 /* Clear VLAN table, by default all ports are members of all VLANs */

--- 982 unchanged lines hidden (view full) ---

1326 ocelot_write_gix(ocelot, val, ANA_PORT_CPU_FWD_CFG, port->chip_port);
1327}
1328
1329static int ocelot_port_attr_set(struct net_device *dev,
1330 const struct switchdev_attr *attr,
1331 struct switchdev_trans *trans)
1332{
1333 struct ocelot_port *ocelot_port = netdev_priv(dev);
1334 struct ocelot *ocelot = ocelot_port->ocelot;
1309 int err = 0;
1310
1311 switch (attr->id) {
1312 case SWITCHDEV_ATTR_ID_PORT_STP_STATE:
1313 ocelot_port_attr_stp_state_set(ocelot_port, trans,
1314 attr->u.stp_state);
1315 break;
1316 case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME:
1317 ocelot_port_attr_ageing_set(ocelot_port, attr->u.ageing_time);
1318 break;
1319 case SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING:
1335 int err = 0;
1336
1337 switch (attr->id) {
1338 case SWITCHDEV_ATTR_ID_PORT_STP_STATE:
1339 ocelot_port_attr_stp_state_set(ocelot_port, trans,
1340 attr->u.stp_state);
1341 break;
1342 case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME:
1343 ocelot_port_attr_ageing_set(ocelot_port, attr->u.ageing_time);
1344 break;
1345 case SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING:
1320 ocelot_port->vlan_aware = attr->u.vlan_filtering;
1321 ocelot_vlan_port_apply(ocelot_port->ocelot, ocelot_port);
1346 ocelot_port_vlan_filtering(ocelot, ocelot_port->chip_port,
1347 attr->u.vlan_filtering);
1322 break;
1323 case SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED:
1324 ocelot_port_attr_mc_set(ocelot_port, !attr->u.mc_disabled);
1325 break;
1326 default:
1327 err = -EOPNOTSUPP;
1328 break;
1329 }

--- 185 unchanged lines hidden (view full) ---

1515 return -ENODEV;
1516 }
1517
1518 ocelot->bridge_mask |= BIT(ocelot_port->chip_port);
1519
1520 return 0;
1521}
1522
1348 break;
1349 case SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED:
1350 ocelot_port_attr_mc_set(ocelot_port, !attr->u.mc_disabled);
1351 break;
1352 default:
1353 err = -EOPNOTSUPP;
1354 break;
1355 }

--- 185 unchanged lines hidden (view full) ---

1541 return -ENODEV;
1542 }
1543
1544 ocelot->bridge_mask |= BIT(ocelot_port->chip_port);
1545
1546 return 0;
1547}
1548
1523static void ocelot_port_bridge_leave(struct ocelot_port *ocelot_port,
1524 struct net_device *bridge)
1549static int ocelot_port_bridge_leave(struct ocelot_port *ocelot_port,
1550 struct net_device *bridge)
1525{
1526 struct ocelot *ocelot = ocelot_port->ocelot;
1551{
1552 struct ocelot *ocelot = ocelot_port->ocelot;
1553 int port = ocelot_port->chip_port;
1527
1554
1528 ocelot->bridge_mask &= ~BIT(ocelot_port->chip_port);
1555 ocelot->bridge_mask &= ~BIT(port);
1529
1530 if (!ocelot->bridge_mask)
1531 ocelot->hw_bridge_dev = NULL;
1532
1556
1557 if (!ocelot->bridge_mask)
1558 ocelot->hw_bridge_dev = NULL;
1559
1533 /* Clear bridge vlan settings before calling ocelot_vlan_port_apply */
1534 ocelot_port->vlan_aware = 0;
1535 ocelot_port->pvid = 0;
1536 ocelot_port->vid = 0;
1560 ocelot_port_vlan_filtering(ocelot, port, 0);
1561 ocelot_port_set_pvid(ocelot, port, 0);
1562 return ocelot_port_set_native_vlan(ocelot, port, 0);
1537}
1538
1539static void ocelot_set_aggr_pgids(struct ocelot *ocelot)
1540{
1541 int i, port, lag;
1542
1543 /* Reset destination and aggregation PGIDS */
1544 for (port = 0; port < ocelot->num_phys_ports; port++)

--- 137 unchanged lines hidden (view full) ---

1682
1683 switch (event) {
1684 case NETDEV_CHANGEUPPER:
1685 if (netif_is_bridge_master(info->upper_dev)) {
1686 if (info->linking)
1687 err = ocelot_port_bridge_join(ocelot_port,
1688 info->upper_dev);
1689 else
1563}
1564
1565static void ocelot_set_aggr_pgids(struct ocelot *ocelot)
1566{
1567 int i, port, lag;
1568
1569 /* Reset destination and aggregation PGIDS */
1570 for (port = 0; port < ocelot->num_phys_ports; port++)

--- 137 unchanged lines hidden (view full) ---

1708
1709 switch (event) {
1710 case NETDEV_CHANGEUPPER:
1711 if (netif_is_bridge_master(info->upper_dev)) {
1712 if (info->linking)
1713 err = ocelot_port_bridge_join(ocelot_port,
1714 info->upper_dev);
1715 else
1690 ocelot_port_bridge_leave(ocelot_port,
1691 info->upper_dev);
1692
1693 ocelot_vlan_port_apply(ocelot_port->ocelot,
1694 ocelot_port);
1716 err = ocelot_port_bridge_leave(ocelot_port,
1717 info->upper_dev);
1695 }
1696 if (netif_is_lag_master(info->upper_dev)) {
1697 if (info->linking)
1698 err = ocelot_port_lag_join(ocelot_port,
1699 info->upper_dev);
1700 else
1701 ocelot_port_lag_leave(ocelot_port,
1702 info->upper_dev);

--- 299 unchanged lines hidden (view full) ---

2002}
2003
2004int ocelot_probe_port(struct ocelot *ocelot, u8 port,
2005 void __iomem *regs,
2006 struct phy_device *phy)
2007{
2008 struct ocelot_port *ocelot_port;
2009 struct net_device *dev;
1718 }
1719 if (netif_is_lag_master(info->upper_dev)) {
1720 if (info->linking)
1721 err = ocelot_port_lag_join(ocelot_port,
1722 info->upper_dev);
1723 else
1724 ocelot_port_lag_leave(ocelot_port,
1725 info->upper_dev);

--- 299 unchanged lines hidden (view full) ---

2025}
2026
2027int ocelot_probe_port(struct ocelot *ocelot, u8 port,
2028 void __iomem *regs,
2029 struct phy_device *phy)
2030{
2031 struct ocelot_port *ocelot_port;
2032 struct net_device *dev;
2033 u32 val;
2010 int err;
2011
2012 dev = alloc_etherdev(sizeof(struct ocelot_port));
2013 if (!dev)
2014 return -ENOMEM;
2015 SET_NETDEV_DEV(dev, ocelot->dev);
2016 ocelot_port = netdev_priv(dev);
2017 ocelot_port->dev = dev;

--- 19 unchanged lines hidden (view full) ---

2037
2038 err = register_netdev(dev);
2039 if (err) {
2040 dev_err(ocelot->dev, "register_netdev failed\n");
2041 goto err_register_netdev;
2042 }
2043
2044 /* Basic L2 initialization */
2034 int err;
2035
2036 dev = alloc_etherdev(sizeof(struct ocelot_port));
2037 if (!dev)
2038 return -ENOMEM;
2039 SET_NETDEV_DEV(dev, ocelot->dev);
2040 ocelot_port = netdev_priv(dev);
2041 ocelot_port->dev = dev;

--- 19 unchanged lines hidden (view full) ---

2061
2062 err = register_netdev(dev);
2063 if (err) {
2064 dev_err(ocelot->dev, "register_netdev failed\n");
2065 goto err_register_netdev;
2066 }
2067
2068 /* Basic L2 initialization */
2045 ocelot_vlan_port_apply(ocelot, ocelot_port);
2046
2069
2070 /* Drop frames with multicast source address */
2071 val = ANA_PORT_DROP_CFG_DROP_MC_SMAC_ENA;
2072 ocelot_rmw_gix(ocelot, val, val, ANA_PORT_DROP_CFG, port);
2073
2074 /* Set default VLAN and tag type to 8021Q. */
2075 ocelot_rmw_gix(ocelot, REW_PORT_VLAN_CFG_PORT_TPID(ETH_P_8021Q),
2076 REW_PORT_VLAN_CFG_PORT_TPID_M,
2077 REW_PORT_VLAN_CFG, port);
2078
2047 /* Enable vcap lookups */
2048 ocelot_vcap_enable(ocelot, ocelot_port);
2049
2050 return 0;
2051
2052err_register_netdev:
2053 free_netdev(dev);
2054 return err;

--- 177 unchanged lines hidden ---
2079 /* Enable vcap lookups */
2080 ocelot_vcap_enable(ocelot, ocelot_port);
2081
2082 return 0;
2083
2084err_register_netdev:
2085 free_netdev(dev);
2086 return err;

--- 177 unchanged lines hidden ---