kernel: Import EtherType based priority override support

This commit is contained in:
Tobias Waldekranz
2024-03-25 15:00:22 +01:00
committed by Joachim Wiberg
parent 7574ad864d
commit 3a73ce3cfb
20 changed files with 512 additions and 18 deletions
@@ -1,7 +1,7 @@
From 79abf7872e35080ca5b519bb4ad2acc1fbd96e8c Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Thu, 25 Jan 2024 21:36:59 +0100
Subject: [PATCH 01/19] net: phy: add support for PHY LEDs polarity modes
Subject: [PATCH 01/21] net: phy: add support for PHY LEDs polarity modes
Organization: Addiva Elektronik
Add support for PHY LEDs polarity modes. Some PHY require LED to be set
@@ -1,7 +1,7 @@
From 424ddb5d5d8ce06c578cc08cbedf519c42dd8b69 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Mon, 4 Dec 2023 11:08:11 +0100
Subject: [PATCH 02/19] net: mvmdio: Support setting the MDC frequency on XSMI
Subject: [PATCH 02/21] net: mvmdio: Support setting the MDC frequency on XSMI
controllers
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From 337cf21833cef6ab456a8562338de88ab1a84ead Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 14 Dec 2023 14:50:23 +0100
Subject: [PATCH 03/19] net: dsa: mv88e6xxx: Create API to read a single stat
Subject: [PATCH 03/21] net: dsa: mv88e6xxx: Create API to read a single stat
counter
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From dbdbfd57998b4f8224146ac94cd5d0a577326087 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 14 Dec 2023 14:50:25 +0100
Subject: [PATCH 04/19] net: dsa: mv88e6xxx: Give each hw stat an ID
Subject: [PATCH 04/21] net: dsa: mv88e6xxx: Give each hw stat an ID
Organization: Addiva Elektronik
With the upcoming standard counter group support, we are no longer
@@ -1,7 +1,7 @@
From 26815572016d9851ec6362f23746035fb933acf3 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 14 Dec 2023 14:50:26 +0100
Subject: [PATCH 05/19] net: dsa: mv88e6xxx: Add "eth-mac" counter group
Subject: [PATCH 05/21] net: dsa: mv88e6xxx: Add "eth-mac" counter group
support
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From cc5badac76e76692eb516a5c086fcf54a5a93080 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 14 Dec 2023 14:50:27 +0100
Subject: [PATCH 06/19] net: dsa: mv88e6xxx: Limit histogram counters to
Subject: [PATCH 06/21] net: dsa: mv88e6xxx: Limit histogram counters to
ingress traffic
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From 35ecc84237bfccbe5b93c0aef6c07cc506d43070 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 14 Dec 2023 14:50:28 +0100
Subject: [PATCH 07/19] net: dsa: mv88e6xxx: Add "rmon" counter group support
Subject: [PATCH 07/21] net: dsa: mv88e6xxx: Add "rmon" counter group support
Organization: Addiva Elektronik
Report the applicable subset of an mv88e6xxx port's counters using
@@ -1,7 +1,7 @@
From 7750d0a5bfae46ab783e8e7087b70175860f808c Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 16 Nov 2023 19:44:32 +0100
Subject: [PATCH 09/19] net: dsa: mv88e6xxx: Add LED infrastructure
Subject: [PATCH 09/21] net: dsa: mv88e6xxx: Add LED infrastructure
Organization: Addiva Elektronik
Parse DT for LEDs and register them for devices that support it,
@@ -1,7 +1,7 @@
From 63fcd626fdb108d2ac07cb0aa16b91fc43894bff Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 16 Nov 2023 21:59:35 +0100
Subject: [PATCH 10/19] net: dsa: mv88e6xxx: Add LED support for 6393X
Subject: [PATCH 10/21] net: dsa: mv88e6xxx: Add LED support for 6393X
Organization: Addiva Elektronik
Trigger support:
@@ -1,7 +1,7 @@
From 0bc6f19d18d7c0e374c824bcc86433b04210a378 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 12 Mar 2024 10:27:24 +0100
Subject: [PATCH 11/19] net: dsa: mv88e6xxx: Fix timeout on waiting for PPU on
Subject: [PATCH 11/21] net: dsa: mv88e6xxx: Fix timeout on waiting for PPU on
6393X
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From fe60e3ad1e3b43a924c311658b15a1106e813661 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 16 Jan 2024 16:00:55 +0100
Subject: [PATCH 12/19] net: dsa: Support MDB memberships whose L2 addresses
Subject: [PATCH 12/21] net: dsa: Support MDB memberships whose L2 addresses
overlap
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From 5f5bf4a50e98c5aff05fe85994a981253ae85987 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 19 Sep 2023 18:38:10 +0200
Subject: [PATCH 13/19] net: phy: marvell10g: Support firmware loading on
Subject: [PATCH 13/21] net: phy: marvell10g: Support firmware loading on
88X3310
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From 27d5241d3ddf70d65af5f4dd029f99f0fea866a5 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 21 Nov 2023 20:15:24 +0100
Subject: [PATCH 14/19] net: phy: marvell10g: Fix power-up when strapped to
Subject: [PATCH 14/21] net: phy: marvell10g: Fix power-up when strapped to
start powered down
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From e389ee690ce56ef20863aeabdf389bed842d7f42 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Wed, 15 Nov 2023 20:58:42 +0100
Subject: [PATCH 15/19] net: phy: marvell10g: Add LED support for 88X3310
Subject: [PATCH 15/21] net: phy: marvell10g: Add LED support for 88X3310
Organization: Addiva Elektronik
Pickup the LEDs from the state in which the hardware reset or
@@ -1,7 +1,7 @@
From 3113b64290b5b7b20c294535c12ea4c732a02f51 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Tue, 12 Dec 2023 09:51:05 +0100
Subject: [PATCH 16/19] net: phy: marvell10g: Support LEDs tied to a single
Subject: [PATCH 16/21] net: phy: marvell10g: Support LEDs tied to a single
media side
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From 2570c2350d3d614a31e14dd87d0e99e8fcb5096b Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Fri, 24 Nov 2023 23:29:55 +0100
Subject: [PATCH 17/19] nvmem: layouts: onie-tlv: Let device probe even when
Subject: [PATCH 17/21] nvmem: layouts: onie-tlv: Let device probe even when
TLV is invalid
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From 681ce95c15bff94ac83eb26db3c718594f8dfa16 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Mon, 4 Mar 2024 16:47:28 +0100
Subject: [PATCH 18/19] net: bridge: avoid classifying unknown multicast as
Subject: [PATCH 18/21] net: bridge: avoid classifying unknown multicast as
mrouters_only
Organization: Addiva Elektronik
@@ -1,7 +1,7 @@
From 2482848726a5b8185a04d90891693a1713f894b5 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Tue, 5 Mar 2024 06:44:41 +0100
Subject: [PATCH 19/19] net: bridge: Ignore router ports when forwarding L2
Subject: [PATCH 19/21] net: bridge: Ignore router ports when forwarding L2
multicast
Organization: Addiva Elektronik
@@ -0,0 +1,118 @@
From 25efcdb13ae720ee662f4b6091b270e48ac4d375 Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Thu, 21 Mar 2024 19:12:15 +0100
Subject: [PATCH 20/21] net: dsa: Support EtherType based priority overrides
Organization: Addiva Elektronik
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
include/net/dsa.h | 4 ++++
net/dsa/slave.c | 56 +++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 58 insertions(+), 2 deletions(-)
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 0b9c6aa27047..6c1f2d70cf84 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -955,6 +955,10 @@ struct dsa_switch_ops {
u8 prio);
int (*port_del_dscp_prio)(struct dsa_switch *ds, int port, u8 dscp,
u8 prio);
+ int (*port_add_etype_prio)(struct dsa_switch *ds, int port, u16 etype,
+ u8 prio);
+ int (*port_del_etype_prio)(struct dsa_switch *ds, int port, u16 etype,
+ u8 prio);
/*
* Suspend and resume
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 48db91b33390..18d913bcd180 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -2213,6 +2213,34 @@ dsa_slave_dcbnl_add_dscp_prio(struct net_device *dev, struct dcb_app *app)
return 0;
}
+static int __maybe_unused
+dsa_slave_dcbnl_set_etype_prio(struct net_device *dev, struct dcb_app *app)
+{
+ struct dsa_port *dp = dsa_slave_to_port(dev);
+ struct dsa_switch *ds = dp->ds;
+ unsigned long mask, new_prio;
+ int err;
+
+ if (!ds->ops->port_add_etype_prio)
+ return -EOPNOTSUPP;
+
+ err = dcb_ieee_setapp(dev, app);
+ if (err)
+ return err;
+
+ mask = dcb_ieee_getapp_mask(dev, app);
+ new_prio = __fls(mask);
+
+ err = ds->ops->port_add_etype_prio(ds, dp->index,
+ app->protocol, new_prio);
+ if (err) {
+ dcb_ieee_delapp(dev, app);
+ return err;
+ }
+
+ return 0;
+}
+
static int __maybe_unused dsa_slave_dcbnl_ieee_setapp(struct net_device *dev,
struct dcb_app *app)
{
@@ -2222,7 +2250,7 @@ static int __maybe_unused dsa_slave_dcbnl_ieee_setapp(struct net_device *dev,
case 0:
return dsa_slave_dcbnl_set_default_prio(dev, app);
default:
- return -EOPNOTSUPP;
+ return dsa_slave_dcbnl_set_etype_prio(dev, app);
}
break;
case IEEE_8021QAZ_APP_SEL_DSCP:
@@ -2283,6 +2311,30 @@ dsa_slave_dcbnl_del_dscp_prio(struct net_device *dev, struct dcb_app *app)
return 0;
}
+static int __maybe_unused
+dsa_slave_dcbnl_del_etype_prio(struct net_device *dev, struct dcb_app *app)
+{
+ struct dsa_port *dp = dsa_slave_to_port(dev);
+ struct dsa_switch *ds = dp->ds;
+ int err;
+
+ if (!ds->ops->port_del_etype_prio)
+ return -EOPNOTSUPP;
+
+ err = dcb_ieee_delapp(dev, app);
+ if (err)
+ return err;
+
+ err = ds->ops->port_del_etype_prio(ds, dp->index,
+ app->protocol, app->priority);
+ if (err) {
+ dcb_ieee_setapp(dev, app);
+ return err;
+ }
+
+ return 0;
+}
+
static int __maybe_unused dsa_slave_dcbnl_ieee_delapp(struct net_device *dev,
struct dcb_app *app)
{
@@ -2292,7 +2344,7 @@ static int __maybe_unused dsa_slave_dcbnl_ieee_delapp(struct net_device *dev,
case 0:
return dsa_slave_dcbnl_del_default_prio(dev, app);
default:
- return -EOPNOTSUPP;
+ return dsa_slave_dcbnl_del_etype_prio(dev, app);
}
break;
case IEEE_8021QAZ_APP_SEL_DSCP:
--
2.34.1
@@ -0,0 +1,376 @@
From 213e9a1d9145723897fbba40fc4afc5b5f70c1de Mon Sep 17 00:00:00 2001
From: Tobias Waldekranz <tobias@waldekranz.com>
Date: Fri, 22 Mar 2024 16:15:43 +0100
Subject: [PATCH 21/21] net: dsa: mv88e6xxx: Support EtherType based priority
overrides
Organization: Addiva Elektronik
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 64 +++++++++++++++++++++++++++++
drivers/net/dsa/mv88e6xxx/chip.h | 21 ++++++++++
drivers/net/dsa/mv88e6xxx/global2.c | 56 ++++++++++++++++++++++++-
drivers/net/dsa/mv88e6xxx/global2.h | 4 ++
drivers/net/dsa/mv88e6xxx/port.c | 46 +++++++++++++++++++++
drivers/net/dsa/mv88e6xxx/port.h | 20 +++++++--
6 files changed, 207 insertions(+), 4 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index f9e78610a55e..5a422c9b533a 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -1626,6 +1626,11 @@ static int mv88e6xxx_rmu_setup(struct mv88e6xxx_chip *chip)
static int mv88e6xxx_pot_setup(struct mv88e6xxx_chip *chip)
{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(chip->qpri_po); i++)
+ refcount_set(&chip->qpri_po[i].refcnt, 0);
+
if (chip->info->ops->pot_clear)
return chip->info->ops->pot_clear(chip);
@@ -3287,6 +3292,7 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
chip->ports[port].chip = chip;
chip->ports[port].port = port;
+ refcount_set(&chip->ports[port].etype.refcnt, 0);
err = mv88e6xxx_port_setup_mac(chip, port, LINK_UNFORCED,
SPEED_UNFORCED, DUPLEX_UNFORCED,
@@ -6386,6 +6392,7 @@ static struct mv88e6xxx_chip *mv88e6xxx_alloc_chip(struct device *dev)
chip->dev = dev;
mutex_init(&chip->reg_lock);
+ mutex_init(&chip->arb_lock);
INIT_LIST_HEAD(&chip->mdios);
idr_init(&chip->policies);
INIT_LIST_HEAD(&chip->msts);
@@ -6918,6 +6925,61 @@ static int mv88e6xxx_crosschip_lag_leave(struct dsa_switch *ds, int sw_index,
return err_sync ? : err_pvt;
}
+int mv88e6xxx_port_add_etype_prio(struct dsa_switch *ds, int port, u16 etype,
+ u8 prio)
+{
+ struct mv88e6xxx_chip *chip = ds->priv;
+ int err;
+
+ mv88e6xxx_reg_lock(chip);
+ err = mv88e6xxx_port_claim_ether_type(chip, port, etype);
+ if (err)
+ goto err;
+
+ err = mv88e6xxx_g2_claim_qpri_po(chip,
+ MV88E6XXX_G2_PRIO_OVERRIDE_PTR_ETYPE,
+ prio);
+ if (err)
+ goto err_relinquish_etype;
+
+ mv88e6xxx_reg_unlock(chip);
+ return 0;
+
+err_relinquish_etype:
+ mv88e6xxx_port_relinquish_ether_type(chip, port);
+err:
+ mv88e6xxx_reg_unlock(chip);
+ return err;
+}
+
+int mv88e6xxx_port_del_etype_prio(struct dsa_switch *ds, int port, u16 etype,
+ u8 prio)
+{
+ struct mv88e6xxx_chip *chip = ds->priv;
+ int err;
+
+ mv88e6xxx_reg_lock(chip);
+ err = mv88e6xxx_g2_relinquish_qpri_po(chip,
+ MV88E6XXX_G2_PRIO_OVERRIDE_PTR_ETYPE);
+ if (err)
+ goto err;
+
+ err = mv88e6xxx_port_relinquish_ether_type(chip, port);
+ if (err)
+ goto err_claim_po;
+
+ mv88e6xxx_reg_unlock(chip);
+ return 0;
+
+err_claim_po:
+ mv88e6xxx_g2_claim_qpri_po(chip,
+ MV88E6XXX_G2_PRIO_OVERRIDE_PTR_ETYPE,
+ prio);
+err:
+ mv88e6xxx_reg_unlock(chip);
+ return err;
+}
+
static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
.get_tag_protocol = mv88e6xxx_get_tag_protocol,
.change_tag_protocol = mv88e6xxx_change_tag_protocol,
@@ -6984,6 +7046,8 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
.crosschip_lag_change = mv88e6xxx_crosschip_lag_change,
.crosschip_lag_join = mv88e6xxx_crosschip_lag_join,
.crosschip_lag_leave = mv88e6xxx_crosschip_lag_leave,
+ .port_add_etype_prio = mv88e6xxx_port_add_etype_prio,
+ .port_del_etype_prio = mv88e6xxx_port_del_etype_prio,
};
static int mv88e6xxx_register_switch(struct mv88e6xxx_chip *chip)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index d0dca152e714..b920df7aa4ff 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -292,6 +292,11 @@ struct mv88e6xxx_port {
/* MacAuth Bypass control flag */
bool mab;
+
+ struct {
+ refcount_t refcnt;
+ u16 proto;
+ } etype;
};
enum mv88e6xxx_region_id {
@@ -330,6 +335,11 @@ struct mv88e6xxx_hw_stat {
int type;
};
+struct mv88e6xxx_po {
+ refcount_t refcnt;
+ u8 pri;
+};
+
struct mv88e6xxx_led;
struct mv88e6xxx_chip {
@@ -347,6 +357,14 @@ struct mv88e6xxx_chip {
/* This mutex protects the access to the switch registers */
struct mutex reg_lock;
+ /* This mutex protects arbitration of hardware resources which
+ * may be allocated by multiple kernel consumers. As an
+ * example, the dcb(8) facility manages priority overrides
+ * independently per interface, whereas the hardware only
+ * supports a single priority per chip.
+ */
+ struct mutex arb_lock;
+
/* The MII bus and the address on the bus that is used to
* communication with the switch
*/
@@ -435,6 +453,9 @@ struct mv88e6xxx_chip {
/* Bridge MST to SID mappings */
struct list_head msts;
+
+ /* Queue priority overrides */
+ struct mv88e6xxx_po qpri_po[16];
};
struct mv88e6xxx_bus_ops {
diff --git a/drivers/net/dsa/mv88e6xxx/global2.c b/drivers/net/dsa/mv88e6xxx/global2.c
index b2b5f6ba438f..2c52903e8992 100644
--- a/drivers/net/dsa/mv88e6xxx/global2.c
+++ b/drivers/net/dsa/mv88e6xxx/global2.c
@@ -315,7 +315,7 @@ int mv88e6xxx_g2_atu_stats_get(struct mv88e6xxx_chip *chip, u16 *stats)
static int mv88e6xxx_g2_pot_write(struct mv88e6xxx_chip *chip, int pointer,
u8 data)
{
- u16 val = (pointer << 8) | (data & 0x7);
+ u16 val = (pointer << 8) | (data & 0xf);
return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_PRIO_OVERRIDE,
MV88E6XXX_G2_PRIO_OVERRIDE_UPDATE | val);
@@ -335,6 +335,60 @@ int mv88e6xxx_g2_pot_clear(struct mv88e6xxx_chip *chip)
return err;
}
+int mv88e6xxx_g2_claim_qpri_po(struct mv88e6xxx_chip *chip, u8 pointer,
+ u8 qpri)
+{
+ struct mv88e6xxx_po *po;
+ int err = 0;
+
+ if (pointer > ARRAY_SIZE(chip->qpri_po))
+ return -EINVAL;
+
+ if (qpri > 7)
+ return -ERANGE;
+
+ po = &chip->qpri_po[pointer];
+
+ mutex_lock(&chip->arb_lock);
+ if (refcount_read(&po->refcnt)) {
+ if (qpri == po->pri)
+ refcount_inc(&po->refcnt);
+ else
+ err = -EBUSY;
+ } else {
+ err = mv88e6xxx_g2_pot_write(chip, pointer,
+ MV88E6XXX_G2_PRIO_OVERRIDE_QFPRIEN | qpri);
+ if (!err) {
+ refcount_set(&po->refcnt, 1);
+ po->pri = qpri;
+ }
+ }
+ mutex_unlock(&chip->arb_lock);
+
+ return err;
+}
+
+int mv88e6xxx_g2_relinquish_qpri_po(struct mv88e6xxx_chip *chip, u8 pointer)
+{
+ struct mv88e6xxx_po *po;
+ int err = 0;
+
+ if (pointer > ARRAY_SIZE(chip->qpri_po))
+ return -EINVAL;
+
+ po = &chip->qpri_po[pointer];
+
+ mutex_lock(&chip->arb_lock);
+ if (refcount_dec_and_test(&po->refcnt)) {
+ err = mv88e6xxx_g2_pot_write(chip, pointer, 0);
+ if (err)
+ refcount_set(&po->refcnt, 1);
+ }
+ mutex_unlock(&chip->arb_lock);
+
+ return err;
+}
+
/* Offset 0x14: EEPROM Command
* Offset 0x15: EEPROM Data (for 16-bit data access)
* Offset 0x15: EEPROM Addr (for 8-bit data access)
diff --git a/drivers/net/dsa/mv88e6xxx/global2.h b/drivers/net/dsa/mv88e6xxx/global2.h
index d9434f7cae53..22a2583a31d9 100644
--- a/drivers/net/dsa/mv88e6xxx/global2.h
+++ b/drivers/net/dsa/mv88e6xxx/global2.h
@@ -138,6 +138,7 @@
#define MV88E6XXX_G2_PRIO_OVERRIDE_UPDATE 0x8000
#define MV88E6XXX_G2_PRIO_OVERRIDE_FPRISET 0x1000
#define MV88E6XXX_G2_PRIO_OVERRIDE_PTR_MASK 0x0f00
+#define MV88E6XXX_G2_PRIO_OVERRIDE_PTR_ETYPE 0xc
#define MV88E6352_G2_PRIO_OVERRIDE_QPRIAVBEN 0x0080
#define MV88E6352_G2_PRIO_OVERRIDE_DATAAVB_MASK 0x0030
#define MV88E6XXX_G2_PRIO_OVERRIDE_QFPRIEN 0x0008
@@ -356,6 +357,9 @@ int mv88e6185_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip);
int mv88e6352_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip);
int mv88e6xxx_g2_pot_clear(struct mv88e6xxx_chip *chip);
+int mv88e6xxx_g2_claim_qpri_po(struct mv88e6xxx_chip *chip, u8 pointer,
+ u8 qpri);
+int mv88e6xxx_g2_relinquish_qpri_po(struct mv88e6xxx_chip *chip, u8 pointer);
int mv88e6xxx_g2_trunk_mask_write(struct mv88e6xxx_chip *chip, int num,
bool hash, u16 mask);
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
index 66073a1ef260..aba78838171b 100644
--- a/drivers/net/dsa/mv88e6xxx/port.c
+++ b/drivers/net/dsa/mv88e6xxx/port.c
@@ -1539,6 +1539,52 @@ int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ETH_TYPE, etype);
}
+int mv88e6xxx_port_claim_ether_type(struct mv88e6xxx_chip *chip, int port,
+ u16 etype)
+{
+ struct mv88e6xxx_port *p = &chip->ports[port];
+ int err = 0;
+
+ if (!chip->info->ops->port_set_ether_type)
+ return -EOPNOTSUPP;
+
+ mutex_lock(&chip->arb_lock);
+ if (refcount_read(&p->etype.refcnt)) {
+ if (etype == p->etype.proto)
+ refcount_inc(&p->etype.refcnt);
+ else
+ err = -EBUSY;
+ } else {
+ err = chip->info->ops->port_set_ether_type(chip, port, etype);
+ if (!err) {
+ refcount_set(&p->etype.refcnt, 1);
+ p->etype.proto = etype;
+ }
+ }
+ mutex_unlock(&chip->arb_lock);
+
+ return err;
+}
+
+int mv88e6xxx_port_relinquish_ether_type(struct mv88e6xxx_chip *chip, int port)
+{
+ struct mv88e6xxx_port *p = &chip->ports[port];
+ int err = 0;
+
+ if (!chip->info->ops->port_set_ether_type)
+ return -EOPNOTSUPP;
+
+ mutex_lock(&chip->arb_lock);
+ if (refcount_dec_and_test(&p->etype.refcnt)) {
+ err = chip->info->ops->port_set_ether_type(chip, port,
+ MV88E6XXX_PORT_ETH_TYPE_DEFAULT);
+ if (err)
+ refcount_set(&p->etype.refcnt, 1);
+ }
+ mutex_unlock(&chip->arb_lock);
+ return err;
+}
+
/* Offset 0x16: LED Control Register */
int mv88e6393x_port_led_write(struct mv88e6xxx_chip *chip, int port,
diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h
index 3605a59d1399..72b015a105cf 100644
--- a/drivers/net/dsa/mv88e6xxx/port.h
+++ b/drivers/net/dsa/mv88e6xxx/port.h
@@ -271,7 +271,18 @@
/* Offset 0x0F: Port Special Ether Type */
#define MV88E6XXX_PORT_ETH_TYPE 0x0f
-#define MV88E6XXX_PORT_ETH_TYPE_DEFAULT 0x9100
+
+/* When MV88E6XXX_PORT_ETH_TYPE is used to override the queue priority
+ * of matching packets, the override applies to all the chip's
+ * ports. However, if the packet also matches a traffic class that the
+ * hardware classifies as being of higher priority, then that class's
+ * override configuration is used instead, even if that override is
+ * disabled. The class which is one level higher than EType is PPPoE,
+ * so by using that as the default value when no other value has been
+ * requested, we effectively disable the EType class for that port.
+ */
+#define MV88E6XXX_PORT_ETH_TYPE_DEFAULT ETH_P_PPP_DISC
+
/* Offset 0x10: InDiscards Low Counter */
#define MV88E6XXX_PORT_IN_DISCARD_LO 0x10
@@ -411,8 +422,13 @@ int mv88e6352_port_set_policy(struct mv88e6xxx_chip *chip, int port,
int mv88e6393x_port_set_policy(struct mv88e6xxx_chip *chip, int port,
enum mv88e6xxx_policy_mapping mapping,
enum mv88e6xxx_policy_action action);
+int mv88e6393x_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
+ u16 etype);
int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
u16 etype);
+int mv88e6xxx_port_claim_ether_type(struct mv88e6xxx_chip *chip, int port,
+ u16 etype);
+int mv88e6xxx_port_relinquish_ether_type(struct mv88e6xxx_chip *chip, int port);
int mv88e6393x_port_led_write(struct mv88e6xxx_chip *chip, int port,
unsigned int pointer, u16 data);
int mv88e6393x_port_led_read(struct mv88e6xxx_chip *chip, int port,
@@ -423,8 +439,6 @@ int mv88e6393x_set_egress_port(struct mv88e6xxx_chip *chip,
int mv88e6393x_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port,
int upstream_port);
int mv88e6393x_port_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip);
-int mv88e6393x_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
- u16 etype);
int mv88e6xxx_port_set_message_port(struct mv88e6xxx_chip *chip, int port,
bool message_port);
int mv88e6xxx_port_set_trunk(struct mv88e6xxx_chip *chip, int port,
--
2.34.1