123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- From 3fcf734aa482487df83cf8f18608438fcf59127f Mon Sep 17 00:00:00 2001
- From: Ansuel Smith <[email protected]>
- Date: Thu, 14 Oct 2021 00:39:10 +0200
- Subject: net: dsa: qca8k: add support for cpu port 6
- Currently CPU port is always hardcoded to port 0. This switch have 2 CPU
- ports. The original intention of this driver seems to be use the
- mac06_exchange bit to swap MAC0 with MAC6 in the strange configuration
- where device have connected only the CPU port 6. To skip the
- introduction of a new binding, rework the driver to address the
- secondary CPU port as primary and drop any reference of hardcoded port.
- With configuration of mac06 exchange, just skip the definition of port0
- and define the CPU port as a secondary. The driver will autoconfigure
- the switch to use that as the primary CPU port.
- Signed-off-by: Ansuel Smith <[email protected]>
- Signed-off-by: David S. Miller <[email protected]>
- ---
- drivers/net/dsa/qca8k.c | 51 ++++++++++++++++++++++++++++++++++---------------
- drivers/net/dsa/qca8k.h | 2 --
- 2 files changed, 36 insertions(+), 17 deletions(-)
- --- a/drivers/net/dsa/qca8k.c
- +++ b/drivers/net/dsa/qca8k.c
- @@ -977,6 +977,22 @@ qca8k_setup_mac_pwr_sel(struct qca8k_pri
- return ret;
- }
-
- +static int qca8k_find_cpu_port(struct dsa_switch *ds)
- +{
- + struct qca8k_priv *priv = ds->priv;
- +
- + /* Find the connected cpu port. Valid port are 0 or 6 */
- + if (dsa_is_cpu_port(ds, 0))
- + return 0;
- +
- + dev_dbg(priv->dev, "port 0 is not the CPU port. Checking port 6");
- +
- + if (dsa_is_cpu_port(ds, 6))
- + return 6;
- +
- + return -EINVAL;
- +}
- +
- static int
- qca8k_parse_port_config(struct qca8k_priv *priv)
- {
- @@ -1017,13 +1033,13 @@ static int
- qca8k_setup(struct dsa_switch *ds)
- {
- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
- - int ret, i;
- + int cpu_port, ret, i;
- u32 mask;
-
- - /* Make sure that port 0 is the cpu port */
- - if (!dsa_is_cpu_port(ds, 0)) {
- - dev_err(priv->dev, "port 0 is not the CPU port");
- - return -EINVAL;
- + cpu_port = qca8k_find_cpu_port(ds);
- + if (cpu_port < 0) {
- + dev_err(priv->dev, "No cpu port configured in both cpu port0 and port6");
- + return cpu_port;
- }
-
- /* Parse CPU port config to be later used in phy_link mac_config */
- @@ -1065,7 +1081,7 @@ qca8k_setup(struct dsa_switch *ds)
- dev_warn(priv->dev, "mib init failed");
-
- /* Enable QCA header mode on the cpu port */
- - ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(QCA8K_CPU_PORT),
- + ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(cpu_port),
- QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_TX_S |
- QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_RX_S);
- if (ret) {
- @@ -1087,10 +1103,10 @@ qca8k_setup(struct dsa_switch *ds)
-
- /* Forward all unknown frames to CPU port for Linux processing */
- ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,
- - BIT(0) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S |
- - BIT(0) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S |
- - BIT(0) << QCA8K_GLOBAL_FW_CTRL1_MC_DP_S |
- - BIT(0) << QCA8K_GLOBAL_FW_CTRL1_UC_DP_S);
- + BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S |
- + BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S |
- + BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_MC_DP_S |
- + BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_UC_DP_S);
- if (ret)
- return ret;
-
- @@ -1098,7 +1114,7 @@ qca8k_setup(struct dsa_switch *ds)
- for (i = 0; i < QCA8K_NUM_PORTS; i++) {
- /* CPU port gets connected to all user ports of the switch */
- if (dsa_is_cpu_port(ds, i)) {
- - ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(QCA8K_CPU_PORT),
- + ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(cpu_port),
- QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds));
- if (ret)
- return ret;
- @@ -1110,7 +1126,7 @@ qca8k_setup(struct dsa_switch *ds)
-
- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
- QCA8K_PORT_LOOKUP_MEMBER,
- - BIT(QCA8K_CPU_PORT));
- + BIT(cpu_port));
- if (ret)
- return ret;
-
- @@ -1616,9 +1632,12 @@ static int
- qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br)
- {
- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
- - int port_mask = BIT(QCA8K_CPU_PORT);
- + int port_mask, cpu_port;
- int i, ret;
-
- + cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
- + port_mask = BIT(cpu_port);
- +
- for (i = 1; i < QCA8K_NUM_PORTS; i++) {
- if (dsa_to_port(ds, i)->bridge_dev != br)
- continue;
- @@ -1645,7 +1664,9 @@ static void
- qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br)
- {
- struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
- - int i;
- + int cpu_port, i;
- +
- + cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
-
- for (i = 1; i < QCA8K_NUM_PORTS; i++) {
- if (dsa_to_port(ds, i)->bridge_dev != br)
- @@ -1662,7 +1683,7 @@ qca8k_port_bridge_leave(struct dsa_switc
- * this port
- */
- qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
- - QCA8K_PORT_LOOKUP_MEMBER, BIT(QCA8K_CPU_PORT));
- + QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port));
- }
-
- static int
- --- a/drivers/net/dsa/qca8k.h
- +++ b/drivers/net/dsa/qca8k.h
- @@ -24,8 +24,6 @@
-
- #define QCA8K_NUM_FDB_RECORDS 2048
-
- -#define QCA8K_CPU_PORT 0
- -
- #define QCA8K_PORT_VID_DEF 1
-
- /* Global control registers */
|