mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-01 02:32:49 -04:00
Merge branch 'dsa-mt7530-fixes'
Arınç ÜNAL says: ==================== net: dsa: mt7530: fix multiple CPU ports, BPDU and LLDP handling This patch series fixes all non-theoretical issues regarding multiple CPU ports and the handling of LLDP frames and BPDUs. I am adding me as a maintainer, I've got some code improvements on the way. I will keep an eye on this driver and the patches submitted for it in the future. Arınç v6: - Change a small portion of the comment in the diff on "net: dsa: mt7530: set all CPU ports in MT7531_CPU_PMAP" with Russell's suggestion. - Change the patch log of "net: dsa: mt7530: fix trapping frames on non-MT7621 SoC MT7530 switch" with Vladimir's suggestion. - Group the code for trapping frames into a common function and call that. - Add Vladimir and Russell's reviewed-by tags to where they're given. v5: - Change the comment in the diff on the first patch with Russell's words. - Change the patch log of the first patch to state that the patch is just preparatory work for change "net: dsa: introduce preferred_default_local_cpu_port and use on MT7530" and not a fix to an existing problem on the code base. - Remove the "net: dsa: mt7530: fix trapping frames with multiple CPU ports on MT7530" patch. It fixes a theoretical issue, therefore it is net-next material. - Remove unnecessary information from the patch logs. Remove the enum renaming change. - Strengthen the point of the "net: dsa: introduce preferred_default_local_cpu_port and use on MT7530" patch. v4: Make the patch logs and my comments in the code easier to understand. v3: Fix the from header on the patches. Write a cover letter. v2: Add patches to fix the handling of LLDP frames and BPDUs. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -13270,10 +13270,11 @@ F: drivers/memory/mtk-smi.c
|
||||
F: include/soc/mediatek/smi.h
|
||||
|
||||
MEDIATEK SWITCH DRIVER
|
||||
M: Sean Wang <sean.wang@mediatek.com>
|
||||
M: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
M: Daniel Golle <daniel@makrotopia.org>
|
||||
M: Landen Chao <Landen.Chao@mediatek.com>
|
||||
M: DENG Qingfang <dqfext@gmail.com>
|
||||
M: Daniel Golle <daniel@makrotopia.org>
|
||||
M: Sean Wang <sean.wang@mediatek.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/dsa/mt7530-mdio.c
|
||||
|
||||
@@ -399,6 +399,20 @@ static void mt7530_pll_setup(struct mt7530_priv *priv)
|
||||
core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
|
||||
}
|
||||
|
||||
/* If port 6 is available as a CPU port, always prefer that as the default,
|
||||
* otherwise don't care.
|
||||
*/
|
||||
static struct dsa_port *
|
||||
mt753x_preferred_default_local_cpu_port(struct dsa_switch *ds)
|
||||
{
|
||||
struct dsa_port *cpu_dp = dsa_to_port(ds, 6);
|
||||
|
||||
if (dsa_port_is_cpu(cpu_dp))
|
||||
return cpu_dp;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Setup port 6 interface mode and TRGMII TX circuit */
|
||||
static int
|
||||
mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
|
||||
@@ -985,6 +999,18 @@ static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface)
|
||||
mutex_unlock(&priv->reg_mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
mt753x_trap_frames(struct mt7530_priv *priv)
|
||||
{
|
||||
/* Trap BPDUs to the CPU port(s) */
|
||||
mt7530_rmw(priv, MT753X_BPC, MT753X_BPDU_PORT_FW_MASK,
|
||||
MT753X_BPDU_CPU_ONLY);
|
||||
|
||||
/* Trap LLDP frames with :0E MAC DA to the CPU port(s) */
|
||||
mt7530_rmw(priv, MT753X_RGAC2, MT753X_R0E_PORT_FW_MASK,
|
||||
MT753X_R0E_PORT_FW(MT753X_BPDU_CPU_ONLY));
|
||||
}
|
||||
|
||||
static int
|
||||
mt753x_cpu_port_enable(struct dsa_switch *ds, int port)
|
||||
{
|
||||
@@ -1007,9 +1033,16 @@ mt753x_cpu_port_enable(struct dsa_switch *ds, int port)
|
||||
UNU_FFP(BIT(port)));
|
||||
|
||||
/* Set CPU port number */
|
||||
if (priv->id == ID_MT7621)
|
||||
if (priv->id == ID_MT7530 || priv->id == ID_MT7621)
|
||||
mt7530_rmw(priv, MT7530_MFC, CPU_MASK, CPU_EN | CPU_PORT(port));
|
||||
|
||||
/* Add the CPU port to the CPU port bitmap for MT7531 and the switch on
|
||||
* the MT7988 SoC. Trapped frames will be forwarded to the CPU port that
|
||||
* is affine to the inbound user port.
|
||||
*/
|
||||
if (priv->id == ID_MT7531 || priv->id == ID_MT7988)
|
||||
mt7530_set(priv, MT7531_CFC, MT7531_CPU_PMAP(BIT(port)));
|
||||
|
||||
/* CPU port gets connected to all user ports of
|
||||
* the switch.
|
||||
*/
|
||||
@@ -2255,6 +2288,8 @@ mt7530_setup(struct dsa_switch *ds)
|
||||
|
||||
priv->p6_interface = PHY_INTERFACE_MODE_NA;
|
||||
|
||||
mt753x_trap_frames(priv);
|
||||
|
||||
/* Enable and reset MIB counters */
|
||||
mt7530_mib_reset(ds);
|
||||
|
||||
@@ -2352,17 +2387,9 @@ static int
|
||||
mt7531_setup_common(struct dsa_switch *ds)
|
||||
{
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
struct dsa_port *cpu_dp;
|
||||
int ret, i;
|
||||
|
||||
/* BPDU to CPU port */
|
||||
dsa_switch_for_each_cpu_port(cpu_dp, ds) {
|
||||
mt7530_rmw(priv, MT7531_CFC, MT7531_CPU_PMAP_MASK,
|
||||
BIT(cpu_dp->index));
|
||||
break;
|
||||
}
|
||||
mt7530_rmw(priv, MT753X_BPC, MT753X_BPDU_PORT_FW_MASK,
|
||||
MT753X_BPDU_CPU_ONLY);
|
||||
mt753x_trap_frames(priv);
|
||||
|
||||
/* Enable and reset MIB counters */
|
||||
mt7530_mib_reset(ds);
|
||||
@@ -3085,6 +3112,7 @@ static int mt7988_setup(struct dsa_switch *ds)
|
||||
const struct dsa_switch_ops mt7530_switch_ops = {
|
||||
.get_tag_protocol = mtk_get_tag_protocol,
|
||||
.setup = mt753x_setup,
|
||||
.preferred_default_local_cpu_port = mt753x_preferred_default_local_cpu_port,
|
||||
.get_strings = mt7530_get_strings,
|
||||
.get_ethtool_stats = mt7530_get_ethtool_stats,
|
||||
.get_sset_count = mt7530_get_sset_count,
|
||||
|
||||
@@ -54,6 +54,7 @@ enum mt753x_id {
|
||||
#define MT7531_MIRROR_PORT_GET(x) (((x) >> 16) & MIRROR_MASK)
|
||||
#define MT7531_MIRROR_PORT_SET(x) (((x) & MIRROR_MASK) << 16)
|
||||
#define MT7531_CPU_PMAP_MASK GENMASK(7, 0)
|
||||
#define MT7531_CPU_PMAP(x) FIELD_PREP(MT7531_CPU_PMAP_MASK, x)
|
||||
|
||||
#define MT753X_MIRROR_REG(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
|
||||
MT7531_CFC : MT7530_MFC)
|
||||
@@ -66,6 +67,11 @@ enum mt753x_id {
|
||||
#define MT753X_BPC 0x24
|
||||
#define MT753X_BPDU_PORT_FW_MASK GENMASK(2, 0)
|
||||
|
||||
/* Register for :03 and :0E MAC DA frame control */
|
||||
#define MT753X_RGAC2 0x2c
|
||||
#define MT753X_R0E_PORT_FW_MASK GENMASK(18, 16)
|
||||
#define MT753X_R0E_PORT_FW(x) FIELD_PREP(MT753X_R0E_PORT_FW_MASK, x)
|
||||
|
||||
enum mt753x_bpdu_port_fw {
|
||||
MT753X_BPDU_FOLLOW_MFC,
|
||||
MT753X_BPDU_CPU_EXCLUDE = 4,
|
||||
|
||||
@@ -958,6 +958,14 @@ struct dsa_switch_ops {
|
||||
struct phy_device *phy);
|
||||
void (*port_disable)(struct dsa_switch *ds, int port);
|
||||
|
||||
/*
|
||||
* Compatibility between device trees defining multiple CPU ports and
|
||||
* drivers which are not OK to use by default the numerically smallest
|
||||
* CPU port of a switch for its local ports. This can return NULL,
|
||||
* meaning "don't know/don't care".
|
||||
*/
|
||||
struct dsa_port *(*preferred_default_local_cpu_port)(struct dsa_switch *ds);
|
||||
|
||||
/*
|
||||
* Port's MAC EEE settings
|
||||
*/
|
||||
|
||||
@@ -403,6 +403,24 @@ static int dsa_tree_setup_default_cpu(struct dsa_switch_tree *dst)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dsa_port *
|
||||
dsa_switch_preferred_default_local_cpu_port(struct dsa_switch *ds)
|
||||
{
|
||||
struct dsa_port *cpu_dp;
|
||||
|
||||
if (!ds->ops->preferred_default_local_cpu_port)
|
||||
return NULL;
|
||||
|
||||
cpu_dp = ds->ops->preferred_default_local_cpu_port(ds);
|
||||
if (!cpu_dp)
|
||||
return NULL;
|
||||
|
||||
if (WARN_ON(!dsa_port_is_cpu(cpu_dp) || cpu_dp->ds != ds))
|
||||
return NULL;
|
||||
|
||||
return cpu_dp;
|
||||
}
|
||||
|
||||
/* Perform initial assignment of CPU ports to user ports and DSA links in the
|
||||
* fabric, giving preference to CPU ports local to each switch. Default to
|
||||
* using the first CPU port in the switch tree if the port does not have a CPU
|
||||
@@ -410,12 +428,16 @@ static int dsa_tree_setup_default_cpu(struct dsa_switch_tree *dst)
|
||||
*/
|
||||
static int dsa_tree_setup_cpu_ports(struct dsa_switch_tree *dst)
|
||||
{
|
||||
struct dsa_port *cpu_dp, *dp;
|
||||
struct dsa_port *preferred_cpu_dp, *cpu_dp, *dp;
|
||||
|
||||
list_for_each_entry(cpu_dp, &dst->ports, list) {
|
||||
if (!dsa_port_is_cpu(cpu_dp))
|
||||
continue;
|
||||
|
||||
preferred_cpu_dp = dsa_switch_preferred_default_local_cpu_port(cpu_dp->ds);
|
||||
if (preferred_cpu_dp && preferred_cpu_dp != cpu_dp)
|
||||
continue;
|
||||
|
||||
/* Prefer a local CPU port */
|
||||
dsa_switch_for_each_port(dp, cpu_dp->ds) {
|
||||
/* Prefer the first local CPU port found */
|
||||
|
||||
Reference in New Issue
Block a user