Commit 282d47de authored by Ioana Ciornei's avatar Ioana Ciornei Committed by David S. Miller

staging: dpaa2-switch: fix up initial forwarding configuration done by firmware

By default, the DPSW object is configured with VLAN ID 1 in the VLAN
table, which all ports are member of. This entry in the VLAN table
selects the same FDB ID for all ports, meaning that forwarding between
ports is permitted. This is unlike the switchdev model, where each port
should operate as standalone by default.

To make the switch operate in standalone ports mode, we need the VLAN
table to select a unique FDB ID for each port. In order to do that, we
need to simply delete the VLAN 1 created automatically by firmware, and
let dpaa2_switch_port_init take over, by readding VLAN ID 1, but
pointing towards a unique FDB ID.
Signed-off-by: default avatarIoana Ciornei <ioana.ciornei@nxp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 93a4d0ab
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* DPAA2 Ethernet Switch driver * DPAA2 Ethernet Switch driver
* *
* Copyright 2014-2016 Freescale Semiconductor Inc. * Copyright 2014-2016 Freescale Semiconductor Inc.
* Copyright 2017-2018 NXP * Copyright 2017-2021 NXP
* *
*/ */
...@@ -1365,6 +1365,8 @@ static int dpaa2_switch_init(struct fsl_mc_device *sw_dev) ...@@ -1365,6 +1365,8 @@ static int dpaa2_switch_init(struct fsl_mc_device *sw_dev)
{ {
struct device *dev = &sw_dev->dev; struct device *dev = &sw_dev->dev;
struct ethsw_core *ethsw = dev_get_drvdata(dev); struct ethsw_core *ethsw = dev_get_drvdata(dev);
struct dpsw_vlan_if_cfg vcfg = {0};
struct dpsw_tci_cfg tci_cfg = {0};
struct dpsw_stp_cfg stp_cfg; struct dpsw_stp_cfg stp_cfg;
int err; int err;
u16 i; u16 i;
...@@ -1416,6 +1418,12 @@ static int dpaa2_switch_init(struct fsl_mc_device *sw_dev) ...@@ -1416,6 +1418,12 @@ static int dpaa2_switch_init(struct fsl_mc_device *sw_dev)
stp_cfg.state = DPSW_STP_STATE_FORWARDING; stp_cfg.state = DPSW_STP_STATE_FORWARDING;
for (i = 0; i < ethsw->sw_attr.num_ifs; i++) { for (i = 0; i < ethsw->sw_attr.num_ifs; i++) {
err = dpsw_if_disable(ethsw->mc_io, 0, ethsw->dpsw_handle, i);
if (err) {
dev_err(dev, "dpsw_if_disable err %d\n", err);
goto err_close;
}
err = dpsw_if_set_stp(ethsw->mc_io, 0, ethsw->dpsw_handle, i, err = dpsw_if_set_stp(ethsw->mc_io, 0, ethsw->dpsw_handle, i,
&stp_cfg); &stp_cfg);
if (err) { if (err) {
...@@ -1423,6 +1431,39 @@ static int dpaa2_switch_init(struct fsl_mc_device *sw_dev) ...@@ -1423,6 +1431,39 @@ static int dpaa2_switch_init(struct fsl_mc_device *sw_dev)
err, i); err, i);
goto err_close; goto err_close;
} }
/* Switch starts with all ports configured to VLAN 1. Need to
* remove this setting to allow configuration at bridge join
*/
vcfg.num_ifs = 1;
vcfg.if_id[0] = i;
err = dpsw_vlan_remove_if_untagged(ethsw->mc_io, 0, ethsw->dpsw_handle,
DEFAULT_VLAN_ID, &vcfg);
if (err) {
dev_err(dev, "dpsw_vlan_remove_if_untagged err %d\n",
err);
goto err_close;
}
tci_cfg.vlan_id = 4095;
err = dpsw_if_set_tci(ethsw->mc_io, 0, ethsw->dpsw_handle, i, &tci_cfg);
if (err) {
dev_err(dev, "dpsw_if_set_tci err %d\n", err);
goto err_close;
}
err = dpsw_vlan_remove_if(ethsw->mc_io, 0, ethsw->dpsw_handle,
DEFAULT_VLAN_ID, &vcfg);
if (err) {
dev_err(dev, "dpsw_vlan_remove_if err %d\n", err);
goto err_close;
}
}
err = dpsw_vlan_remove(ethsw->mc_io, 0, ethsw->dpsw_handle, DEFAULT_VLAN_ID);
if (err) {
dev_err(dev, "dpsw_vlan_remove err %d\n", err);
goto err_close;
} }
ethsw->workqueue = alloc_ordered_workqueue("%s_%d_ordered", ethsw->workqueue = alloc_ordered_workqueue("%s_%d_ordered",
...@@ -1449,34 +1490,22 @@ static int dpaa2_switch_init(struct fsl_mc_device *sw_dev) ...@@ -1449,34 +1490,22 @@ static int dpaa2_switch_init(struct fsl_mc_device *sw_dev)
static int dpaa2_switch_port_init(struct ethsw_port_priv *port_priv, u16 port) static int dpaa2_switch_port_init(struct ethsw_port_priv *port_priv, u16 port)
{ {
struct switchdev_obj_port_vlan vlan = {
.obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN,
.vid = DEFAULT_VLAN_ID,
.flags = BRIDGE_VLAN_INFO_UNTAGGED | BRIDGE_VLAN_INFO_PVID,
};
struct net_device *netdev = port_priv->netdev; struct net_device *netdev = port_priv->netdev;
struct ethsw_core *ethsw = port_priv->ethsw_data;
struct dpsw_vlan_if_cfg vcfg;
int err; int err;
/* Switch starts with all ports configured to VLAN 1. Need to /* We need to add VLAN 1 as the PVID on this port until it is under a
* remove this setting to allow configuration at bridge join * bridge since the DPAA2 switch is not able to handle the traffic in a
* VLAN unaware fashion
*/ */
vcfg.num_ifs = 1; err = dpaa2_switch_port_vlans_add(netdev, &vlan);
vcfg.if_id[0] = port_priv->idx;
err = dpsw_vlan_remove_if_untagged(ethsw->mc_io, 0, ethsw->dpsw_handle,
DEFAULT_VLAN_ID, &vcfg);
if (err) {
netdev_err(netdev, "dpsw_vlan_remove_if_untagged err %d\n",
err);
return err;
}
err = dpaa2_switch_port_set_pvid(port_priv, 0);
if (err) if (err)
return err; return err;
err = dpsw_vlan_remove_if(ethsw->mc_io, 0, ethsw->dpsw_handle,
DEFAULT_VLAN_ID, &vcfg);
if (err)
netdev_err(netdev, "dpsw_vlan_remove_if err %d\n", err);
return err; return err;
} }
...@@ -1633,9 +1662,6 @@ static int dpaa2_switch_probe(struct fsl_mc_device *sw_dev) ...@@ -1633,9 +1662,6 @@ static int dpaa2_switch_probe(struct fsl_mc_device *sw_dev)
if (err) if (err)
goto err_free_cmdport; goto err_free_cmdport;
/* DEFAULT_VLAN_ID is implicitly configured on the switch */
ethsw->vlans[DEFAULT_VLAN_ID] = ETHSW_VLAN_MEMBER;
ethsw->ports = kcalloc(ethsw->sw_attr.num_ifs, sizeof(*ethsw->ports), ethsw->ports = kcalloc(ethsw->sw_attr.num_ifs, sizeof(*ethsw->ports),
GFP_KERNEL); GFP_KERNEL);
if (!(ethsw->ports)) { if (!(ethsw->ports)) {
...@@ -1655,10 +1681,6 @@ static int dpaa2_switch_probe(struct fsl_mc_device *sw_dev) ...@@ -1655,10 +1681,6 @@ static int dpaa2_switch_probe(struct fsl_mc_device *sw_dev)
goto err_free_ports; goto err_free_ports;
} }
/* Make sure the switch ports are disabled at probe time */
for (i = 0; i < ethsw->sw_attr.num_ifs; i++)
dpsw_if_disable(ethsw->mc_io, 0, ethsw->dpsw_handle, i);
/* Setup IRQs */ /* Setup IRQs */
err = dpaa2_switch_setup_irqs(sw_dev); err = dpaa2_switch_setup_irqs(sw_dev);
if (err) if (err)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment