Skip to content

Commit 3fcf734

Browse files
Ansueldavem330
authored andcommitted
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]>
1 parent 731d613 commit 3fcf734

File tree

2 files changed

+36
-17
lines changed

2 files changed

+36
-17
lines changed

drivers/net/dsa/qca8k.c

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -977,6 +977,22 @@ qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv)
977977
return ret;
978978
}
979979

980+
static int qca8k_find_cpu_port(struct dsa_switch *ds)
981+
{
982+
struct qca8k_priv *priv = ds->priv;
983+
984+
/* Find the connected cpu port. Valid port are 0 or 6 */
985+
if (dsa_is_cpu_port(ds, 0))
986+
return 0;
987+
988+
dev_dbg(priv->dev, "port 0 is not the CPU port. Checking port 6");
989+
990+
if (dsa_is_cpu_port(ds, 6))
991+
return 6;
992+
993+
return -EINVAL;
994+
}
995+
980996
static int
981997
qca8k_parse_port_config(struct qca8k_priv *priv)
982998
{
@@ -1017,13 +1033,13 @@ static int
10171033
qca8k_setup(struct dsa_switch *ds)
10181034
{
10191035
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
1020-
int ret, i;
1036+
int cpu_port, ret, i;
10211037
u32 mask;
10221038

1023-
/* Make sure that port 0 is the cpu port */
1024-
if (!dsa_is_cpu_port(ds, 0)) {
1025-
dev_err(priv->dev, "port 0 is not the CPU port");
1026-
return -EINVAL;
1039+
cpu_port = qca8k_find_cpu_port(ds);
1040+
if (cpu_port < 0) {
1041+
dev_err(priv->dev, "No cpu port configured in both cpu port0 and port6");
1042+
return cpu_port;
10271043
}
10281044

10291045
/* Parse CPU port config to be later used in phy_link mac_config */
@@ -1065,7 +1081,7 @@ qca8k_setup(struct dsa_switch *ds)
10651081
dev_warn(priv->dev, "mib init failed");
10661082

10671083
/* Enable QCA header mode on the cpu port */
1068-
ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(QCA8K_CPU_PORT),
1084+
ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(cpu_port),
10691085
QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_TX_S |
10701086
QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_RX_S);
10711087
if (ret) {
@@ -1087,18 +1103,18 @@ qca8k_setup(struct dsa_switch *ds)
10871103

10881104
/* Forward all unknown frames to CPU port for Linux processing */
10891105
ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,
1090-
BIT(0) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S |
1091-
BIT(0) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S |
1092-
BIT(0) << QCA8K_GLOBAL_FW_CTRL1_MC_DP_S |
1093-
BIT(0) << QCA8K_GLOBAL_FW_CTRL1_UC_DP_S);
1106+
BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S |
1107+
BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S |
1108+
BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_MC_DP_S |
1109+
BIT(cpu_port) << QCA8K_GLOBAL_FW_CTRL1_UC_DP_S);
10941110
if (ret)
10951111
return ret;
10961112

10971113
/* Setup connection between CPU port & user ports */
10981114
for (i = 0; i < QCA8K_NUM_PORTS; i++) {
10991115
/* CPU port gets connected to all user ports of the switch */
11001116
if (dsa_is_cpu_port(ds, i)) {
1101-
ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(QCA8K_CPU_PORT),
1117+
ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(cpu_port),
11021118
QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds));
11031119
if (ret)
11041120
return ret;
@@ -1110,7 +1126,7 @@ qca8k_setup(struct dsa_switch *ds)
11101126

11111127
ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
11121128
QCA8K_PORT_LOOKUP_MEMBER,
1113-
BIT(QCA8K_CPU_PORT));
1129+
BIT(cpu_port));
11141130
if (ret)
11151131
return ret;
11161132

@@ -1616,9 +1632,12 @@ static int
16161632
qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br)
16171633
{
16181634
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
1619-
int port_mask = BIT(QCA8K_CPU_PORT);
1635+
int port_mask, cpu_port;
16201636
int i, ret;
16211637

1638+
cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
1639+
port_mask = BIT(cpu_port);
1640+
16221641
for (i = 1; i < QCA8K_NUM_PORTS; i++) {
16231642
if (dsa_to_port(ds, i)->bridge_dev != br)
16241643
continue;
@@ -1645,7 +1664,9 @@ static void
16451664
qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br)
16461665
{
16471666
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
1648-
int i;
1667+
int cpu_port, i;
1668+
1669+
cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
16491670

16501671
for (i = 1; i < QCA8K_NUM_PORTS; i++) {
16511672
if (dsa_to_port(ds, i)->bridge_dev != br)
@@ -1662,7 +1683,7 @@ qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br)
16621683
* this port
16631684
*/
16641685
qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
1665-
QCA8K_PORT_LOOKUP_MEMBER, BIT(QCA8K_CPU_PORT));
1686+
QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port));
16661687
}
16671688

16681689
static int

drivers/net/dsa/qca8k.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424

2525
#define QCA8K_NUM_FDB_RECORDS 2048
2626

27-
#define QCA8K_CPU_PORT 0
28-
2927
#define QCA8K_PORT_VID_DEF 1
3028

3129
/* Global control registers */

0 commit comments

Comments
 (0)