* [PATCH net-next 05/10] net: dsa: mv88e6xxx: implement mv88e6352_serdes_get_lane
From: Vivien Didelot @ 2019-08-31 20:18 UTC (permalink / raw)
To: netdev; +Cc: davem, Marek Behún, f.fainelli, andrew, Vivien Didelot
In-Reply-To: <20190831201836.19957-1-vivien.didelot@gmail.com>
Even though 88E6352 has no dedicated lane for SERDES interfaces, it
uses a similar code as the other .serdes_get_lane implementations to
check the port's CMODE and ensure that SERDES operations are doable.
For consistency, implement mv88e6352_serdes_get_lane for the 88E6352
and similar switches which simply returns an unused 0xff lane address.
Signed-off-by: Vivien Didelot <vivien.didelot@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 4 ++++
drivers/net/dsa/mv88e6xxx/serdes.c | 11 ++++++++++-
drivers/net/dsa/mv88e6xxx/serdes.h | 1 +
3 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 0ab4ce86eda7..3962e7368ae5 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -3093,6 +3093,7 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
.rmu_disable = mv88e6352_g1_rmu_disable,
.vtu_getnext = mv88e6352_g1_vtu_getnext,
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
+ .serdes_get_lane = mv88e6352_serdes_get_lane,
.serdes_power = mv88e6352_serdes_power,
.gpio_ops = &mv88e6352_gpio_ops,
.phylink_validate = mv88e6352_phylink_validate,
@@ -3178,6 +3179,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
.rmu_disable = mv88e6352_g1_rmu_disable,
.vtu_getnext = mv88e6352_g1_vtu_getnext,
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
+ .serdes_get_lane = mv88e6352_serdes_get_lane,
.serdes_power = mv88e6352_serdes_power,
.serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
.serdes_irq_setup = mv88e6352_serdes_irq_setup,
@@ -3407,6 +3409,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
.rmu_disable = mv88e6352_g1_rmu_disable,
.vtu_getnext = mv88e6352_g1_vtu_getnext,
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
+ .serdes_get_lane = mv88e6352_serdes_get_lane,
.serdes_power = mv88e6352_serdes_power,
.serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
.serdes_irq_setup = mv88e6352_serdes_irq_setup,
@@ -3767,6 +3770,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
.rmu_disable = mv88e6352_g1_rmu_disable,
.vtu_getnext = mv88e6352_g1_vtu_getnext,
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
+ .serdes_get_lane = mv88e6352_serdes_get_lane,
.serdes_power = mv88e6352_serdes_power,
.serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
.serdes_irq_setup = mv88e6352_serdes_irq_setup,
diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c
index ce6d97e5caf8..9fb2773a3eb5 100644
--- a/drivers/net/dsa/mv88e6xxx/serdes.c
+++ b/drivers/net/dsa/mv88e6xxx/serdes.c
@@ -69,13 +69,22 @@ static int mv88e6352_serdes_power_set(struct mv88e6xxx_chip *chip, bool on)
return err;
}
-static bool mv88e6352_port_has_serdes(struct mv88e6xxx_chip *chip, int port)
+u8 mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
{
u8 cmode = chip->ports[port].cmode;
+ u8 lane = 0;
if ((cmode == MV88E6XXX_PORT_STS_CMODE_100BASEX) ||
(cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX) ||
(cmode == MV88E6XXX_PORT_STS_CMODE_SGMII))
+ lane = 0xff; /* Unused */
+
+ return lane;
+}
+
+static bool mv88e6352_port_has_serdes(struct mv88e6xxx_chip *chip, int port)
+{
+ if (mv88e6xxx_serdes_get_lane(chip, port))
return true;
return false;
diff --git a/drivers/net/dsa/mv88e6xxx/serdes.h b/drivers/net/dsa/mv88e6xxx/serdes.h
index 4718dcca6b3c..7df27a0de9aa 100644
--- a/drivers/net/dsa/mv88e6xxx/serdes.h
+++ b/drivers/net/dsa/mv88e6xxx/serdes.h
@@ -75,6 +75,7 @@
#define MV88E6390_SGMII_PHY_STATUS_LINK BIT(10)
u8 mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
+u8 mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
u8 mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
u8 mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip,
--
2.23.0
^ permalink raw reply related
* [PATCH net-next 09/10] net: dsa: mv88e6xxx: introduce .serdes_irq_status
From: Vivien Didelot @ 2019-08-31 20:18 UTC (permalink / raw)
To: netdev; +Cc: davem, Marek Behún, f.fainelli, andrew, Vivien Didelot
In-Reply-To: <20190831201836.19957-1-vivien.didelot@gmail.com>
Introduce a new .serdes_irq_status operation to prepare the abstraction
of IRQ thread from the SERDES IRQ setup code.
Signed-off-by: Vivien Didelot <vivien.didelot@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 11 ++++++
drivers/net/dsa/mv88e6xxx/chip.h | 2 +
drivers/net/dsa/mv88e6xxx/serdes.c | 59 +++++++++++++++++++-----------
drivers/net/dsa/mv88e6xxx/serdes.h | 13 +++++++
4 files changed, 64 insertions(+), 21 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 258174634bb2..c2061e20bb32 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2935,6 +2935,7 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
.serdes_get_lane = mv88e6341_serdes_get_lane,
.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
.serdes_irq_enable = mv88e6390_serdes_irq_enable,
+ .serdes_irq_status = mv88e6390_serdes_irq_status,
.serdes_irq_setup = mv88e6390_serdes_irq_setup,
.serdes_irq_free = mv88e6390_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
@@ -3186,6 +3187,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
.serdes_power = mv88e6352_serdes_power,
.serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
.serdes_irq_enable = mv88e6352_serdes_irq_enable,
+ .serdes_irq_status = mv88e6352_serdes_irq_status,
.serdes_irq_setup = mv88e6352_serdes_irq_setup,
.serdes_irq_free = mv88e6352_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
@@ -3271,6 +3273,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
.serdes_get_lane = mv88e6390_serdes_get_lane,
.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
.serdes_irq_enable = mv88e6390_serdes_irq_enable,
+ .serdes_irq_status = mv88e6390_serdes_irq_status,
.serdes_irq_setup = mv88e6390_serdes_irq_setup,
.serdes_irq_free = mv88e6390_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
@@ -3320,6 +3323,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
.serdes_get_lane = mv88e6390x_serdes_get_lane,
.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
.serdes_irq_enable = mv88e6390_serdes_irq_enable,
+ .serdes_irq_status = mv88e6390_serdes_irq_status,
.serdes_irq_setup = mv88e6390_serdes_irq_setup,
.serdes_irq_free = mv88e6390_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
@@ -3369,6 +3373,7 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
.serdes_get_lane = mv88e6390_serdes_get_lane,
.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
.serdes_irq_enable = mv88e6390_serdes_irq_enable,
+ .serdes_irq_status = mv88e6390_serdes_irq_status,
.serdes_irq_setup = mv88e6390_serdes_irq_setup,
.serdes_irq_free = mv88e6390_serdes_irq_free,
.avb_ops = &mv88e6390_avb_ops,
@@ -3420,6 +3425,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
.serdes_power = mv88e6352_serdes_power,
.serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
.serdes_irq_enable = mv88e6352_serdes_irq_enable,
+ .serdes_irq_status = mv88e6352_serdes_irq_status,
.serdes_irq_setup = mv88e6352_serdes_irq_setup,
.serdes_irq_free = mv88e6352_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
@@ -3511,6 +3517,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
.serdes_get_lane = mv88e6390_serdes_get_lane,
.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
.serdes_irq_enable = mv88e6390_serdes_irq_enable,
+ .serdes_irq_status = mv88e6390_serdes_irq_status,
.serdes_irq_setup = mv88e6390_serdes_irq_setup,
.serdes_irq_free = mv88e6390_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
@@ -3650,6 +3657,7 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
.serdes_get_lane = mv88e6341_serdes_get_lane,
.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
.serdes_irq_enable = mv88e6390_serdes_irq_enable,
+ .serdes_irq_status = mv88e6390_serdes_irq_status,
.serdes_irq_setup = mv88e6390_serdes_irq_setup,
.serdes_irq_free = mv88e6390_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
@@ -3784,6 +3792,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
.serdes_power = mv88e6352_serdes_power,
.serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
.serdes_irq_enable = mv88e6352_serdes_irq_enable,
+ .serdes_irq_status = mv88e6352_serdes_irq_status,
.serdes_irq_setup = mv88e6352_serdes_irq_setup,
.serdes_irq_free = mv88e6352_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
@@ -3840,6 +3849,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
.serdes_get_lane = mv88e6390_serdes_get_lane,
.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
.serdes_irq_enable = mv88e6390_serdes_irq_enable,
+ .serdes_irq_status = mv88e6390_serdes_irq_status,
.serdes_irq_setup = mv88e6390_serdes_irq_setup,
.serdes_irq_free = mv88e6390_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
@@ -3893,6 +3903,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
.serdes_get_lane = mv88e6390x_serdes_get_lane,
.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
.serdes_irq_enable = mv88e6390_serdes_irq_enable,
+ .serdes_irq_status = mv88e6390_serdes_irq_status,
.serdes_irq_setup = mv88e6390_serdes_irq_setup,
.serdes_irq_free = mv88e6390_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index 0c7b0f6053d8..9a73fd1d643b 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -454,6 +454,8 @@ struct mv88e6xxx_ops {
void (*serdes_irq_free)(struct mv88e6xxx_chip *chip, int port);
int (*serdes_irq_enable)(struct mv88e6xxx_chip *chip, int port, u8 lane,
bool enable);
+ irqreturn_t (*serdes_irq_status)(struct mv88e6xxx_chip *chip, int port,
+ u8 lane);
/* Statistics from the SERDES interface */
int (*serdes_get_sset_count)(struct mv88e6xxx_chip *chip, int port);
diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c
index 3562ef03ae55..d37419ba26ab 100644
--- a/drivers/net/dsa/mv88e6xxx/serdes.c
+++ b/drivers/net/dsa/mv88e6xxx/serdes.c
@@ -202,25 +202,33 @@ static void mv88e6352_serdes_irq_link(struct mv88e6xxx_chip *chip, int port)
dsa_port_phylink_mac_change(ds, port, up);
}
-static irqreturn_t mv88e6352_serdes_thread_fn(int irq, void *dev_id)
+irqreturn_t mv88e6352_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
+ u8 lane)
{
- struct mv88e6xxx_port *port = dev_id;
- struct mv88e6xxx_chip *chip = port->chip;
irqreturn_t ret = IRQ_NONE;
u16 status;
int err;
- mv88e6xxx_reg_lock(chip);
-
err = mv88e6352_serdes_read(chip, MV88E6352_SERDES_INT_STATUS, &status);
if (err)
- goto out;
+ return ret;
if (status & MV88E6352_SERDES_INT_LINK_CHANGE) {
ret = IRQ_HANDLED;
- mv88e6352_serdes_irq_link(chip, port->port);
+ mv88e6352_serdes_irq_link(chip, port);
}
-out:
+
+ return ret;
+}
+
+static irqreturn_t mv88e6352_serdes_thread_fn(int irq, void *dev_id)
+{
+ struct mv88e6xxx_port *port = dev_id;
+ struct mv88e6xxx_chip *chip = port->chip;
+ irqreturn_t ret = IRQ_NONE;
+
+ mv88e6xxx_reg_lock(chip);
+ ret = mv88e6xxx_serdes_irq_status(chip, port->port, 0);
mv88e6xxx_reg_unlock(chip);
return ret;
@@ -589,21 +597,13 @@ static int mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip *chip,
return err;
}
-static irqreturn_t mv88e6390_serdes_thread_fn(int irq, void *dev_id)
+irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
+ u8 lane)
{
- struct mv88e6xxx_port *port = dev_id;
- struct mv88e6xxx_chip *chip = port->chip;
+ u8 cmode = chip->ports[port].cmode;
irqreturn_t ret = IRQ_NONE;
- u8 cmode = port->cmode;
u16 status;
int err;
- u8 lane;
-
- mv88e6xxx_reg_lock(chip);
-
- lane = mv88e6xxx_serdes_get_lane(chip, port->port);
- if (!lane)
- goto out;
switch (cmode) {
case MV88E6XXX_PORT_STS_CMODE_SGMII:
@@ -611,13 +611,30 @@ static irqreturn_t mv88e6390_serdes_thread_fn(int irq, void *dev_id)
case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status);
if (err)
- goto out;
+ return ret;
if (status & (MV88E6390_SGMII_INT_LINK_DOWN |
MV88E6390_SGMII_INT_LINK_UP)) {
ret = IRQ_HANDLED;
- mv88e6390_serdes_irq_link_sgmii(chip, port->port, lane);
+ mv88e6390_serdes_irq_link_sgmii(chip, port, lane);
}
}
+
+ return ret;
+}
+
+static irqreturn_t mv88e6390_serdes_thread_fn(int irq, void *dev_id)
+{
+ struct mv88e6xxx_port *port = dev_id;
+ struct mv88e6xxx_chip *chip = port->chip;
+ irqreturn_t ret = IRQ_NONE;
+ u8 lane;
+
+ mv88e6xxx_reg_lock(chip);
+ lane = mv88e6xxx_serdes_get_lane(chip, port->port);
+ if (!lane)
+ goto out;
+
+ ret = mv88e6xxx_serdes_irq_status(chip, port->port, lane);
out:
mv88e6xxx_reg_unlock(chip);
diff --git a/drivers/net/dsa/mv88e6xxx/serdes.h b/drivers/net/dsa/mv88e6xxx/serdes.h
index e2d38b5d4222..52f937347a36 100644
--- a/drivers/net/dsa/mv88e6xxx/serdes.h
+++ b/drivers/net/dsa/mv88e6xxx/serdes.h
@@ -92,6 +92,10 @@ int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
bool enable);
int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
bool enable);
+irqreturn_t mv88e6352_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
+ u8 lane);
+irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
+ u8 lane);
int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port);
int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip,
int port, uint8_t *data);
@@ -155,4 +159,13 @@ static inline int mv88e6xxx_serdes_irq_disable(struct mv88e6xxx_chip *chip,
return chip->info->ops->serdes_irq_enable(chip, port, lane, false);
}
+static inline irqreturn_t
+mv88e6xxx_serdes_irq_status(struct mv88e6xxx_chip *chip, int port, u8 lane)
+{
+ if (!chip->info->ops->serdes_irq_status)
+ return IRQ_NONE;
+
+ return chip->info->ops->serdes_irq_status(chip, port, lane);
+}
+
#endif
--
2.23.0
^ permalink raw reply related
* [PATCH net-next 10/10] net: dsa: mv88e6xxx: centralize SERDES IRQ handling
From: Vivien Didelot @ 2019-08-31 20:18 UTC (permalink / raw)
To: netdev; +Cc: davem, Marek Behún, f.fainelli, andrew, Vivien Didelot
In-Reply-To: <20190831201836.19957-1-vivien.didelot@gmail.com>
The .serdes_irq_setup are all following the same steps: get the SERDES
lane, get the IRQ mapping, request the IRQ, then enable it. So do
the .serdes_irq_free implementations: get the SERDES lane, disable
the IRQ, then free it.
This patch removes these operations in favor of generic functions.
Signed-off-by: Vivien Didelot <vivien.didelot@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 96 +++++++++++++------
drivers/net/dsa/mv88e6xxx/chip.h | 2 -
drivers/net/dsa/mv88e6xxx/serdes.c | 142 -----------------------------
drivers/net/dsa/mv88e6xxx/serdes.h | 4 -
4 files changed, 69 insertions(+), 175 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index c2061e20bb32..30365a54c31b 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2054,6 +2054,71 @@ static int mv88e6xxx_setup_egress_floods(struct mv88e6xxx_chip *chip, int port)
return 0;
}
+static irqreturn_t mv88e6xxx_serdes_irq_thread_fn(int irq, void *dev_id)
+{
+ struct mv88e6xxx_port *mvp = dev_id;
+ struct mv88e6xxx_chip *chip = mvp->chip;
+ irqreturn_t ret = IRQ_NONE;
+ int port = mvp->port;
+ u8 lane;
+
+ mv88e6xxx_reg_lock(chip);
+ lane = mv88e6xxx_serdes_get_lane(chip, port);
+ if (lane)
+ ret = mv88e6xxx_serdes_irq_status(chip, port, lane);
+ mv88e6xxx_reg_unlock(chip);
+
+ return ret;
+}
+
+static int mv88e6xxx_serdes_irq_request(struct mv88e6xxx_chip *chip, int port,
+ u8 lane)
+{
+ struct mv88e6xxx_port *dev_id = &chip->ports[port];
+ unsigned int irq;
+ int err;
+
+ /* Nothing to request if this SERDES port has no IRQ */
+ irq = mv88e6xxx_serdes_irq_mapping(chip, port);
+ if (!irq)
+ return 0;
+
+ /* Requesting the IRQ will trigger IRQ callbacks, so release the lock */
+ mv88e6xxx_reg_unlock(chip);
+ err = request_threaded_irq(irq, NULL, mv88e6xxx_serdes_irq_thread_fn,
+ IRQF_ONESHOT, "mv88e6xxx-serdes", dev_id);
+ mv88e6xxx_reg_lock(chip);
+ if (err)
+ return err;
+
+ dev_id->serdes_irq = irq;
+
+ return mv88e6xxx_serdes_irq_enable(chip, port, lane);
+}
+
+static int mv88e6xxx_serdes_irq_free(struct mv88e6xxx_chip *chip, int port,
+ u8 lane)
+{
+ struct mv88e6xxx_port *dev_id = &chip->ports[port];
+ unsigned int irq = dev_id->serdes_irq;
+ int err;
+
+ /* Nothing to free if no IRQ has been requested */
+ if (!irq)
+ return 0;
+
+ err = mv88e6xxx_serdes_irq_disable(chip, port, lane);
+
+ /* Freeing the IRQ will trigger IRQ callbacks, so release the lock */
+ mv88e6xxx_reg_unlock(chip);
+ free_irq(irq, dev_id);
+ mv88e6xxx_reg_lock(chip);
+
+ dev_id->serdes_irq = 0;
+
+ return err;
+}
+
static int mv88e6xxx_serdes_power(struct mv88e6xxx_chip *chip, int port,
bool on)
{
@@ -2069,12 +2134,11 @@ static int mv88e6xxx_serdes_power(struct mv88e6xxx_chip *chip, int port,
if (err)
return err;
- if (chip->info->ops->serdes_irq_setup)
- err = chip->info->ops->serdes_irq_setup(chip, port);
+ err = mv88e6xxx_serdes_irq_request(chip, port, lane);
} else {
- if (chip->info->ops->serdes_irq_free &&
- chip->ports[port].serdes_irq)
- chip->info->ops->serdes_irq_free(chip, port);
+ err = mv88e6xxx_serdes_irq_free(chip, port, lane);
+ if (err)
+ return err;
err = mv88e6xxx_serdes_power_down(chip, port, lane);
}
@@ -2936,8 +3000,6 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
.serdes_irq_enable = mv88e6390_serdes_irq_enable,
.serdes_irq_status = mv88e6390_serdes_irq_status,
- .serdes_irq_setup = mv88e6390_serdes_irq_setup,
- .serdes_irq_free = mv88e6390_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
.phylink_validate = mv88e6341_phylink_validate,
};
@@ -3188,8 +3250,6 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
.serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
.serdes_irq_enable = mv88e6352_serdes_irq_enable,
.serdes_irq_status = mv88e6352_serdes_irq_status,
- .serdes_irq_setup = mv88e6352_serdes_irq_setup,
- .serdes_irq_free = mv88e6352_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
.phylink_validate = mv88e6352_phylink_validate,
};
@@ -3274,8 +3334,6 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
.serdes_irq_enable = mv88e6390_serdes_irq_enable,
.serdes_irq_status = mv88e6390_serdes_irq_status,
- .serdes_irq_setup = mv88e6390_serdes_irq_setup,
- .serdes_irq_free = mv88e6390_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
.phylink_validate = mv88e6390_phylink_validate,
};
@@ -3324,8 +3382,6 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
.serdes_irq_enable = mv88e6390_serdes_irq_enable,
.serdes_irq_status = mv88e6390_serdes_irq_status,
- .serdes_irq_setup = mv88e6390_serdes_irq_setup,
- .serdes_irq_free = mv88e6390_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
.phylink_validate = mv88e6390x_phylink_validate,
};
@@ -3374,8 +3430,6 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
.serdes_irq_enable = mv88e6390_serdes_irq_enable,
.serdes_irq_status = mv88e6390_serdes_irq_status,
- .serdes_irq_setup = mv88e6390_serdes_irq_setup,
- .serdes_irq_free = mv88e6390_serdes_irq_free,
.avb_ops = &mv88e6390_avb_ops,
.ptp_ops = &mv88e6352_ptp_ops,
.phylink_validate = mv88e6390_phylink_validate,
@@ -3426,8 +3480,6 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
.serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
.serdes_irq_enable = mv88e6352_serdes_irq_enable,
.serdes_irq_status = mv88e6352_serdes_irq_status,
- .serdes_irq_setup = mv88e6352_serdes_irq_setup,
- .serdes_irq_free = mv88e6352_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
.avb_ops = &mv88e6352_avb_ops,
.ptp_ops = &mv88e6352_ptp_ops,
@@ -3518,8 +3570,6 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
.serdes_irq_enable = mv88e6390_serdes_irq_enable,
.serdes_irq_status = mv88e6390_serdes_irq_status,
- .serdes_irq_setup = mv88e6390_serdes_irq_setup,
- .serdes_irq_free = mv88e6390_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
.avb_ops = &mv88e6390_avb_ops,
.ptp_ops = &mv88e6352_ptp_ops,
@@ -3658,8 +3708,6 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
.serdes_irq_enable = mv88e6390_serdes_irq_enable,
.serdes_irq_status = mv88e6390_serdes_irq_status,
- .serdes_irq_setup = mv88e6390_serdes_irq_setup,
- .serdes_irq_free = mv88e6390_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
.avb_ops = &mv88e6390_avb_ops,
.ptp_ops = &mv88e6352_ptp_ops,
@@ -3793,8 +3841,6 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
.serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
.serdes_irq_enable = mv88e6352_serdes_irq_enable,
.serdes_irq_status = mv88e6352_serdes_irq_status,
- .serdes_irq_setup = mv88e6352_serdes_irq_setup,
- .serdes_irq_free = mv88e6352_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
.avb_ops = &mv88e6352_avb_ops,
.ptp_ops = &mv88e6352_ptp_ops,
@@ -3850,8 +3896,6 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
.serdes_irq_enable = mv88e6390_serdes_irq_enable,
.serdes_irq_status = mv88e6390_serdes_irq_status,
- .serdes_irq_setup = mv88e6390_serdes_irq_setup,
- .serdes_irq_free = mv88e6390_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
.avb_ops = &mv88e6390_avb_ops,
.ptp_ops = &mv88e6352_ptp_ops,
@@ -3904,8 +3948,6 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
.serdes_irq_enable = mv88e6390_serdes_irq_enable,
.serdes_irq_status = mv88e6390_serdes_irq_status,
- .serdes_irq_setup = mv88e6390_serdes_irq_setup,
- .serdes_irq_free = mv88e6390_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
.avb_ops = &mv88e6390_avb_ops,
.ptp_ops = &mv88e6352_ptp_ops,
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index 9a73fd1d643b..6bc0a4e4fe7b 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -450,8 +450,6 @@ struct mv88e6xxx_ops {
/* SERDES interrupt handling */
unsigned int (*serdes_irq_mapping)(struct mv88e6xxx_chip *chip,
int port);
- int (*serdes_irq_setup)(struct mv88e6xxx_chip *chip, int port);
- void (*serdes_irq_free)(struct mv88e6xxx_chip *chip, int port);
int (*serdes_irq_enable)(struct mv88e6xxx_chip *chip, int port, u8 lane,
bool enable);
irqreturn_t (*serdes_irq_status)(struct mv88e6xxx_chip *chip, int port,
diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c
index d37419ba26ab..902feb398746 100644
--- a/drivers/net/dsa/mv88e6xxx/serdes.c
+++ b/drivers/net/dsa/mv88e6xxx/serdes.c
@@ -221,19 +221,6 @@ irqreturn_t mv88e6352_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
return ret;
}
-static irqreturn_t mv88e6352_serdes_thread_fn(int irq, void *dev_id)
-{
- struct mv88e6xxx_port *port = dev_id;
- struct mv88e6xxx_chip *chip = port->chip;
- irqreturn_t ret = IRQ_NONE;
-
- mv88e6xxx_reg_lock(chip);
- ret = mv88e6xxx_serdes_irq_status(chip, port->port, 0);
- mv88e6xxx_reg_unlock(chip);
-
- return ret;
-}
-
int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
bool enable)
{
@@ -250,61 +237,6 @@ unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
return irq_find_mapping(chip->g2_irq.domain, MV88E6352_SERDES_IRQ);
}
-int mv88e6352_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port)
-{
- unsigned int irq;
- u8 lane;
- int err;
-
- lane = mv88e6xxx_serdes_get_lane(chip, port);
- if (!lane)
- return 0;
-
- irq = mv88e6xxx_serdes_irq_mapping(chip, port);
- if (!irq)
- return 0;
-
- chip->ports[port].serdes_irq = irq;
-
- /* Requesting the IRQ will trigger irq callbacks. So we cannot
- * hold the reg_lock.
- */
- mv88e6xxx_reg_unlock(chip);
- err = request_threaded_irq(chip->ports[port].serdes_irq, NULL,
- mv88e6352_serdes_thread_fn,
- IRQF_ONESHOT, "mv88e6xxx-serdes",
- &chip->ports[port]);
- mv88e6xxx_reg_lock(chip);
-
- if (err) {
- dev_err(chip->dev, "Unable to request SERDES interrupt: %d\n",
- err);
- return err;
- }
-
- return mv88e6xxx_serdes_irq_enable(chip, port, lane);
-}
-
-void mv88e6352_serdes_irq_free(struct mv88e6xxx_chip *chip, int port)
-{
- u8 lane;
-
- lane = mv88e6xxx_serdes_get_lane(chip, port);
- if (!lane)
- return;
-
- mv88e6xxx_serdes_irq_disable(chip, port, lane);
-
- /* Freeing the IRQ will trigger irq callbacks. So we cannot
- * hold the reg_lock.
- */
- mv88e6xxx_reg_unlock(chip);
- free_irq(chip->ports[port].serdes_irq, &chip->ports[port]);
- mv88e6xxx_reg_lock(chip);
-
- chip->ports[port].serdes_irq = 0;
-}
-
u8 mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
{
u8 cmode = chip->ports[port].cmode;
@@ -622,81 +554,7 @@ irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
return ret;
}
-static irqreturn_t mv88e6390_serdes_thread_fn(int irq, void *dev_id)
-{
- struct mv88e6xxx_port *port = dev_id;
- struct mv88e6xxx_chip *chip = port->chip;
- irqreturn_t ret = IRQ_NONE;
- u8 lane;
-
- mv88e6xxx_reg_lock(chip);
- lane = mv88e6xxx_serdes_get_lane(chip, port->port);
- if (!lane)
- goto out;
-
- ret = mv88e6xxx_serdes_irq_status(chip, port->port, lane);
-out:
- mv88e6xxx_reg_unlock(chip);
-
- return ret;
-}
-
unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
{
return irq_find_mapping(chip->g2_irq.domain, port);
}
-
-int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port)
-{
- unsigned int irq;
- int err;
- u8 lane;
-
- lane = mv88e6xxx_serdes_get_lane(chip, port);
- if (!lane)
- return 0;
-
- irq = mv88e6xxx_serdes_irq_mapping(chip, port);
- if (!irq)
- return 0;
-
- chip->ports[port].serdes_irq = irq;
-
- /* Requesting the IRQ will trigger irq callbacks. So we cannot
- * hold the reg_lock.
- */
- mv88e6xxx_reg_unlock(chip);
- err = request_threaded_irq(chip->ports[port].serdes_irq, NULL,
- mv88e6390_serdes_thread_fn,
- IRQF_ONESHOT, "mv88e6xxx-serdes",
- &chip->ports[port]);
- mv88e6xxx_reg_lock(chip);
-
- if (err) {
- dev_err(chip->dev, "Unable to request SERDES interrupt: %d\n",
- err);
- return err;
- }
-
- return mv88e6xxx_serdes_irq_enable(chip, port, lane);
-}
-
-void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port)
-{
- u8 lane;
-
- lane = mv88e6xxx_serdes_get_lane(chip, port);
- if (!lane)
- return;
-
- mv88e6xxx_serdes_irq_disable(chip, port, lane);
-
- /* Freeing the IRQ will trigger irq callbacks. So we cannot
- * hold the reg_lock.
- */
- mv88e6xxx_reg_unlock(chip);
- free_irq(chip->ports[port].serdes_irq, &chip->ports[port]);
- mv88e6xxx_reg_lock(chip);
-
- chip->ports[port].serdes_irq = 0;
-}
diff --git a/drivers/net/dsa/mv88e6xxx/serdes.h b/drivers/net/dsa/mv88e6xxx/serdes.h
index 52f937347a36..bd8df36ab537 100644
--- a/drivers/net/dsa/mv88e6xxx/serdes.h
+++ b/drivers/net/dsa/mv88e6xxx/serdes.h
@@ -86,8 +86,6 @@ int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
bool on);
int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
bool on);
-int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port);
-void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port);
int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
bool enable);
int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
@@ -101,8 +99,6 @@ int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip,
int port, uint8_t *data);
int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
uint64_t *data);
-int mv88e6352_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port);
-void mv88e6352_serdes_irq_free(struct mv88e6xxx_chip *chip, int port);
/* Return the (first) SERDES lane address a port is using, 0 otherwise. */
static inline u8 mv88e6xxx_serdes_get_lane(struct mv88e6xxx_chip *chip,
--
2.23.0
^ permalink raw reply related
* [PATCH net-next 08/10] net: dsa: mv88e6xxx: introduce .serdes_irq_enable
From: Vivien Didelot @ 2019-08-31 20:18 UTC (permalink / raw)
To: netdev; +Cc: davem, Marek Behún, f.fainelli, andrew, Vivien Didelot
In-Reply-To: <20190831201836.19957-1-vivien.didelot@gmail.com>
Introduce a new .serdes_irq_enable operation to prepare the abstraction
of IRQ enabling from the SERDES IRQ setup code.
Signed-off-by: Vivien Didelot <vivien.didelot@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 11 +++++
drivers/net/dsa/mv88e6xxx/chip.h | 2 +
drivers/net/dsa/mv88e6xxx/port.c | 4 +-
drivers/net/dsa/mv88e6xxx/serdes.c | 73 ++++++++++++------------------
drivers/net/dsa/mv88e6xxx/serdes.h | 26 +++++++++--
5 files changed, 66 insertions(+), 50 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 3522b11d5566..258174634bb2 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2934,6 +2934,7 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
.serdes_power = mv88e6390_serdes_power,
.serdes_get_lane = mv88e6341_serdes_get_lane,
.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
+ .serdes_irq_enable = mv88e6390_serdes_irq_enable,
.serdes_irq_setup = mv88e6390_serdes_irq_setup,
.serdes_irq_free = mv88e6390_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
@@ -3184,6 +3185,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
.serdes_get_lane = mv88e6352_serdes_get_lane,
.serdes_power = mv88e6352_serdes_power,
.serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
+ .serdes_irq_enable = mv88e6352_serdes_irq_enable,
.serdes_irq_setup = mv88e6352_serdes_irq_setup,
.serdes_irq_free = mv88e6352_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
@@ -3268,6 +3270,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
.serdes_power = mv88e6390_serdes_power,
.serdes_get_lane = mv88e6390_serdes_get_lane,
.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
+ .serdes_irq_enable = mv88e6390_serdes_irq_enable,
.serdes_irq_setup = mv88e6390_serdes_irq_setup,
.serdes_irq_free = mv88e6390_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
@@ -3316,6 +3319,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
.serdes_power = mv88e6390_serdes_power,
.serdes_get_lane = mv88e6390x_serdes_get_lane,
.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
+ .serdes_irq_enable = mv88e6390_serdes_irq_enable,
.serdes_irq_setup = mv88e6390_serdes_irq_setup,
.serdes_irq_free = mv88e6390_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
@@ -3364,6 +3368,7 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
.serdes_power = mv88e6390_serdes_power,
.serdes_get_lane = mv88e6390_serdes_get_lane,
.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
+ .serdes_irq_enable = mv88e6390_serdes_irq_enable,
.serdes_irq_setup = mv88e6390_serdes_irq_setup,
.serdes_irq_free = mv88e6390_serdes_irq_free,
.avb_ops = &mv88e6390_avb_ops,
@@ -3414,6 +3419,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
.serdes_get_lane = mv88e6352_serdes_get_lane,
.serdes_power = mv88e6352_serdes_power,
.serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
+ .serdes_irq_enable = mv88e6352_serdes_irq_enable,
.serdes_irq_setup = mv88e6352_serdes_irq_setup,
.serdes_irq_free = mv88e6352_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
@@ -3504,6 +3510,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
.serdes_power = mv88e6390_serdes_power,
.serdes_get_lane = mv88e6390_serdes_get_lane,
.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
+ .serdes_irq_enable = mv88e6390_serdes_irq_enable,
.serdes_irq_setup = mv88e6390_serdes_irq_setup,
.serdes_irq_free = mv88e6390_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
@@ -3642,6 +3649,7 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
.serdes_power = mv88e6390_serdes_power,
.serdes_get_lane = mv88e6341_serdes_get_lane,
.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
+ .serdes_irq_enable = mv88e6390_serdes_irq_enable,
.serdes_irq_setup = mv88e6390_serdes_irq_setup,
.serdes_irq_free = mv88e6390_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
@@ -3775,6 +3783,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
.serdes_get_lane = mv88e6352_serdes_get_lane,
.serdes_power = mv88e6352_serdes_power,
.serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
+ .serdes_irq_enable = mv88e6352_serdes_irq_enable,
.serdes_irq_setup = mv88e6352_serdes_irq_setup,
.serdes_irq_free = mv88e6352_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
@@ -3830,6 +3839,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
.serdes_power = mv88e6390_serdes_power,
.serdes_get_lane = mv88e6390_serdes_get_lane,
.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
+ .serdes_irq_enable = mv88e6390_serdes_irq_enable,
.serdes_irq_setup = mv88e6390_serdes_irq_setup,
.serdes_irq_free = mv88e6390_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
@@ -3882,6 +3892,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
.serdes_power = mv88e6390_serdes_power,
.serdes_get_lane = mv88e6390x_serdes_get_lane,
.serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
+ .serdes_irq_enable = mv88e6390_serdes_irq_enable,
.serdes_irq_setup = mv88e6390_serdes_irq_setup,
.serdes_irq_free = mv88e6390_serdes_irq_free,
.gpio_ops = &mv88e6352_gpio_ops,
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index 724ce2bf8258..0c7b0f6053d8 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -452,6 +452,8 @@ struct mv88e6xxx_ops {
int port);
int (*serdes_irq_setup)(struct mv88e6xxx_chip *chip, int port);
void (*serdes_irq_free)(struct mv88e6xxx_chip *chip, int port);
+ int (*serdes_irq_enable)(struct mv88e6xxx_chip *chip, int port, u8 lane,
+ bool enable);
/* Statistics from the SERDES interface */
int (*serdes_get_sset_count)(struct mv88e6xxx_chip *chip, int port);
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
index df71c08eda35..04006344adb2 100644
--- a/drivers/net/dsa/mv88e6xxx/port.c
+++ b/drivers/net/dsa/mv88e6xxx/port.c
@@ -434,7 +434,7 @@ static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
lane = mv88e6xxx_serdes_get_lane(chip, port);
if (lane) {
if (chip->ports[port].serdes_irq) {
- err = mv88e6390_serdes_irq_disable(chip, port, lane);
+ err = mv88e6xxx_serdes_irq_disable(chip, port, lane);
if (err)
return err;
}
@@ -469,7 +469,7 @@ static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
return err;
if (chip->ports[port].serdes_irq) {
- err = mv88e6390_serdes_irq_enable(chip, port, lane);
+ err = mv88e6xxx_serdes_irq_enable(chip, port, lane);
if (err)
return err;
}
diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c
index e3ea8cca85b0..3562ef03ae55 100644
--- a/drivers/net/dsa/mv88e6xxx/serdes.c
+++ b/drivers/net/dsa/mv88e6xxx/serdes.c
@@ -226,15 +226,15 @@ static irqreturn_t mv88e6352_serdes_thread_fn(int irq, void *dev_id)
return ret;
}
-static int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip)
+int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
+ bool enable)
{
- return mv88e6352_serdes_write(chip, MV88E6352_SERDES_INT_ENABLE,
- MV88E6352_SERDES_INT_LINK_CHANGE);
-}
+ u16 val = 0;
-static int mv88e6352_serdes_irq_disable(struct mv88e6xxx_chip *chip)
-{
- return mv88e6352_serdes_write(chip, MV88E6352_SERDES_INT_ENABLE, 0);
+ if (enable)
+ val |= MV88E6352_SERDES_INT_LINK_CHANGE;
+
+ return mv88e6352_serdes_write(chip, MV88E6352_SERDES_INT_ENABLE, val);
}
unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
@@ -245,9 +245,11 @@ unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
int mv88e6352_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port)
{
unsigned int irq;
+ u8 lane;
int err;
- if (!mv88e6352_port_has_serdes(chip, port))
+ lane = mv88e6xxx_serdes_get_lane(chip, port);
+ if (!lane)
return 0;
irq = mv88e6xxx_serdes_irq_mapping(chip, port);
@@ -272,15 +274,18 @@ int mv88e6352_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port)
return err;
}
- return mv88e6352_serdes_irq_enable(chip);
+ return mv88e6xxx_serdes_irq_enable(chip, port, lane);
}
void mv88e6352_serdes_irq_free(struct mv88e6xxx_chip *chip, int port)
{
- if (!mv88e6352_port_has_serdes(chip, port))
+ u8 lane;
+
+ lane = mv88e6xxx_serdes_get_lane(chip, port);
+ if (!lane)
return;
- mv88e6352_serdes_irq_disable(chip);
+ mv88e6xxx_serdes_irq_disable(chip, port, lane);
/* Freeing the IRQ will trigger irq callbacks. So we cannot
* hold the reg_lock.
@@ -546,51 +551,31 @@ static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip *chip,
}
static int mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip *chip,
- u8 lane)
-{
- return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
- MV88E6390_SGMII_INT_ENABLE,
- MV88E6390_SGMII_INT_LINK_DOWN |
- MV88E6390_SGMII_INT_LINK_UP);
-}
-
-static int mv88e6390_serdes_irq_disable_sgmii(struct mv88e6xxx_chip *chip,
- u8 lane)
+ u8 lane, bool enable)
{
- return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
- MV88E6390_SGMII_INT_ENABLE, 0);
-}
+ u16 val = 0;
-int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port,
- u8 lane)
-{
- u8 cmode = chip->ports[port].cmode;
- int err = 0;
+ if (enable)
+ val |= MV88E6390_SGMII_INT_LINK_DOWN |
+ MV88E6390_SGMII_INT_LINK_UP;
- switch (cmode) {
- case MV88E6XXX_PORT_STS_CMODE_SGMII:
- case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
- case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
- err = mv88e6390_serdes_irq_enable_sgmii(chip, lane);
- }
-
- return err;
+ return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
+ MV88E6390_SGMII_INT_ENABLE, val);
}
-int mv88e6390_serdes_irq_disable(struct mv88e6xxx_chip *chip, int port,
- u8 lane)
+int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
+ bool enable)
{
u8 cmode = chip->ports[port].cmode;
- int err = 0;
switch (cmode) {
case MV88E6XXX_PORT_STS_CMODE_SGMII:
case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
- err = mv88e6390_serdes_irq_disable_sgmii(chip, lane);
+ return mv88e6390_serdes_irq_enable_sgmii(chip, lane, enable);
}
- return err;
+ return 0;
}
static int mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip *chip,
@@ -676,7 +661,7 @@ int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port)
return err;
}
- return mv88e6390_serdes_irq_enable(chip, port, lane);
+ return mv88e6xxx_serdes_irq_enable(chip, port, lane);
}
void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port)
@@ -687,7 +672,7 @@ void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port)
if (!lane)
return;
- mv88e6390_serdes_irq_disable(chip, port, lane);
+ mv88e6xxx_serdes_irq_disable(chip, port, lane);
/* Freeing the IRQ will trigger irq callbacks. So we cannot
* hold the reg_lock.
diff --git a/drivers/net/dsa/mv88e6xxx/serdes.h b/drivers/net/dsa/mv88e6xxx/serdes.h
index c70023f57090..e2d38b5d4222 100644
--- a/drivers/net/dsa/mv88e6xxx/serdes.h
+++ b/drivers/net/dsa/mv88e6xxx/serdes.h
@@ -88,15 +88,15 @@ int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
bool on);
int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port);
void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port);
+int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
+ bool enable);
+int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
+ bool enable);
int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port);
int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip,
int port, uint8_t *data);
int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
uint64_t *data);
-int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port,
- u8 lane);
-int mv88e6390_serdes_irq_disable(struct mv88e6xxx_chip *chip, int port,
- u8 lane);
int mv88e6352_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port);
void mv88e6352_serdes_irq_free(struct mv88e6xxx_chip *chip, int port);
@@ -137,4 +137,22 @@ mv88e6xxx_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
return chip->info->ops->serdes_irq_mapping(chip, port);
}
+static inline int mv88e6xxx_serdes_irq_enable(struct mv88e6xxx_chip *chip,
+ int port, u8 lane)
+{
+ if (!chip->info->ops->serdes_irq_enable)
+ return -EOPNOTSUPP;
+
+ return chip->info->ops->serdes_irq_enable(chip, port, lane, true);
+}
+
+static inline int mv88e6xxx_serdes_irq_disable(struct mv88e6xxx_chip *chip,
+ int port, u8 lane)
+{
+ if (!chip->info->ops->serdes_irq_enable)
+ return -EOPNOTSUPP;
+
+ return chip->info->ops->serdes_irq_enable(chip, port, lane, false);
+}
+
#endif
--
2.23.0
^ permalink raw reply related
* Re: [PATCH] net: dsa: microchip: fill regmap_config name
From: David Miller @ 2019-08-31 20:19 UTC (permalink / raw)
To: george.mccollister
Cc: netdev, woojung.huh, andrew, f.fainelli, Tristram.Ha, marex,
linux-kernel
In-Reply-To: <20190829141441.70063-1-george.mccollister@gmail.com>
From: George McCollister <george.mccollister@gmail.com>
Date: Thu, 29 Aug 2019 09:14:41 -0500
> Use the register value width as the regmap_config name to prevent the
> following error when the second and third regmap_configs are
> initialized.
> "debugfs: Directory '${bus-id}' with parent 'regmap' already present!"
>
> Signed-off-by: George McCollister <george.mccollister@gmail.com>
Applied.
^ permalink raw reply
* Re: [PATCH v3 net-next 0/2] Dynamic toggling of vlan_filtering for SJA1105 DSA
From: David Miller @ 2019-08-31 20:21 UTC (permalink / raw)
To: olteanv; +Cc: f.fainelli, vivien.didelot, andrew, idosch, roopa, nikolay,
netdev
In-Reply-To: <20190830005325.26526-1-olteanv@gmail.com>
From: Vladimir Oltean <olteanv@gmail.com>
Date: Fri, 30 Aug 2019 03:53:23 +0300
> This patchset addresses a limitation in dsa_8021q where this sequence of
> commands was causing the switch to stop forwarding traffic:
>
> ip link add name br0 type bridge vlan_filtering 0
> ip link set dev swp2 master br0
> echo 1 > /sys/class/net/br0/bridge/vlan_filtering
> echo 0 > /sys/class/net/br0/bridge/vlan_filtering
>
> The issue has to do with the VLAN table manipulations that dsa_8021q
> does without notifying the bridge layer. The solution is to always
> restore the VLANs that the bridge knows about, when disabling tagging.
Series applied, thank you.
^ permalink raw reply
* Re: [PATCH net-next 0/4] qed*: Enhancements.
From: David Miller @ 2019-08-31 20:32 UTC (permalink / raw)
To: skalluru; +Cc: netdev, mkalderon, aelior
In-Reply-To: <20190830074206.8836-1-skalluru@marvell.com>
From: Sudarsana Reddy Kalluru <skalluru@marvell.com>
Date: Fri, 30 Aug 2019 00:42:02 -0700
> The patch series adds couple of enhancements to qed/qede drivers.
> - Support for dumping the config id attributes via ethtool -w/W.
> - Support for dumping the GRC data of required memory regions using
> ethtool -w/W interfaces.
>
> Patch (1) adds driver APIs for reading the config id attributes.
> Patch (2) adds ethtool support for dumping the config id attributes.
> Patch (3) adds support for configuring the GRC dump config flags.
> Patch (4) adds ethtool support for dumping the grc dump.
>
> Please consider applying it to net-next.
Series applied, thanks.
^ permalink raw reply
* Re: [PATCH net 0/5] net: aquantia: fixes on vlan filters and other conditions
From: David Miller @ 2019-08-31 20:36 UTC (permalink / raw)
To: jakub.kicinski; +Cc: Igor.Russkikh, netdev
In-Reply-To: <20190830232856.6200abd2@cakuba.netronome.com>
From: Jakub Kicinski <jakub.kicinski@netronome.com>
Date: Fri, 30 Aug 2019 23:28:56 -0700
> On Fri, 30 Aug 2019 12:08:28 +0000, Igor Russkikh wrote:
>> Here is a set of various bug fixes related to vlan filter offload and
>> two other rare cases.
>
> LGTM, Fixes tag should had been first there on patch 4.
Series applied with fixes tag ordering fixed in patch 4.
^ permalink raw reply
* Re: [PATCH v3 1/2] net: core: Notify on changes to dev->promiscuity.
From: Ido Schimmel @ 2019-08-31 20:47 UTC (permalink / raw)
To: Andrew Lunn
Cc: David Miller, jiri, horatiu.vultur, alexandre.belloni,
UNGLinuxDriver, allan.nielsen, ivecera, f.fainelli, netdev,
linux-kernel
In-Reply-To: <20190831193556.GB2647@lunn.ch>
On Sat, Aug 31, 2019 at 09:35:56PM +0200, Andrew Lunn wrote:
> > Also, what happens when I'm running these application without putting
> > the interface in promisc mode? On an offloaded interface I would not be
> > able to even capture packets addressed to my interface's MAC address.
>
> Sorry for rejoining the discussion late. I've been travelling and i'm
> now 3/4 of the way to Lisbon.
Hi Andrew,
Have fun!
> That statement i don't get.
What about the other statements?
> If the frame has the MAC address of the interface, it has to be
> delivered to the CPU.
So every packet that needs to be routed should be delivered to the CPU?
Definitely not.
> And so pcap will see it when running on the interface. I can pretty
> much guarantee every DSA driver does that.
I assume because you currently only consider L2 forwarding.
> But to address the bigger picture. My understanding is that we want to
> model offloading as a mechanism to accelerate what Linux can already
> do. The user should not have to care about these accelerators. The
> interface should work like a normal Linux interface. I can put an IP
> address on it and ping a peer. I can run a dhcp client and get an IP
> address from a dhcp server. I can add the interface to a bridge, and
> packets will get bridged. I as a user should not need to care if this
> is done in software, or accelerated by offloading it. I can add a
> route, and if the accelerate knows about L3, it can accelerate that as
> well. If not, the kernel will route it.
Yep, and this is how it's all working today.
> So if i run wireshark on an interface, i expect the interface will be
> put into promisc mode and i see all packets ingressing the interface.
> What the accelerator needs to do to achieve this, i as a user don't
> care.
>
> I can follow the argument that i won't necessarily see every
> packet. But that is always true. For many embedded systems, the CPU is
> too slow to receive at line rate, even when we are talking about 1G
> links. Packets do get dropped. And i hope tcpdump users understand
> that.
>
> For me, having tcpdump use tc trap is just wrong. It breaks the model
> that the user should not care about the accelerator. If anything, i
> think the driver needs to translate cBPF which pcap passes to the
> kernel to whatever internal format the accelerator can process. That
> is just another example of using hardware acceleration.
Look, this again boils down to what promisc mode means with regards to
hardware offload. You want it to mean punt all traffic to the CPU? Fine.
Does not seem like anyone will be switching sides anyway, so lets move
forward. But the current approach is not good. Each driver needs to have
this special case logic and the semantics of promisc mode change not
only with regards to the value of the promisc counter, but also with
regards to the interface's uppers. This is highly fragile and confusing.
The approach taken in v2 makes much more sense. Add a new flag to
accelerators and have the networking stack check it before putting the
interface in promisc mode. Then the only thing drivers need to do is to
instruct the accelerator to trap all traffic to the CPU.
^ permalink raw reply
* Re: [PATCH 2/2] Fix a NULL-ptr-deref bug in ath10k_usb_alloc_urb_from_pipe
From: Guenter Roeck @ 2019-08-31 21:31 UTC (permalink / raw)
To: Hui Peng
Cc: kvalo, davem, Mathias Payer, ath10k, linux-wireless, netdev,
linux-kernel
In-Reply-To: <20190804003101.11541-1-benquike@gmail.com>
Hi,
On Sat, Aug 03, 2019 at 08:31:01PM -0400, Hui Peng wrote:
> The `ar_usb` field of `ath10k_usb_pipe_usb_pipe` objects
> are initialized to point to the containing `ath10k_usb` object
> according to endpoint descriptors read from the device side, as shown
> below in `ath10k_usb_setup_pipe_resources`:
>
> for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
> endpoint = &iface_desc->endpoint[i].desc;
>
> // get the address from endpoint descriptor
> pipe_num = ath10k_usb_get_logical_pipe_num(ar_usb,
> endpoint->bEndpointAddress,
> &urbcount);
> ......
> // select the pipe object
> pipe = &ar_usb->pipes[pipe_num];
>
> // initialize the ar_usb field
> pipe->ar_usb = ar_usb;
> }
>
> The driver assumes that the addresses reported in endpoint
> descriptors from device side to be complete. If a device is
> malicious and does not report complete addresses, it may trigger
> NULL-ptr-deref `ath10k_usb_alloc_urb_from_pipe` and
> `ath10k_usb_free_urb_to_pipe`.
>
> This patch fixes the bug by preventing potential NULL-ptr-deref.
>
> Signed-off-by: Hui Peng <benquike@gmail.com>
> Reported-by: Hui Peng <benquike@gmail.com>
> Reported-by: Mathias Payer <mathias.payer@nebelwelt.net>
This patch fixes CVE-2019-15099, which has CVSS scores of 7.5 (CVSS 3.0)
and 7.8 (CVSS 2.0). Yet, I don't find it in the upstream kernel or in Linux
next.
Is the patch going to be applied to the upstream kernel anytime soon ? If
not, is there reason to believe that its severity may not be as high as the
CVSS score indicates ?
Thanks,
Guenter
> ---
> drivers/net/wireless/ath/ath10k/usb.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/drivers/net/wireless/ath/ath10k/usb.c b/drivers/net/wireless/ath/ath10k/usb.c
> index e1420f67f776..14d86627b47f 100644
> --- a/drivers/net/wireless/ath/ath10k/usb.c
> +++ b/drivers/net/wireless/ath/ath10k/usb.c
> @@ -38,6 +38,10 @@ ath10k_usb_alloc_urb_from_pipe(struct ath10k_usb_pipe *pipe)
> struct ath10k_urb_context *urb_context = NULL;
> unsigned long flags;
>
> + /* bail if this pipe is not initialized */
> + if (!pipe->ar_usb)
> + return NULL;
> +
> spin_lock_irqsave(&pipe->ar_usb->cs_lock, flags);
> if (!list_empty(&pipe->urb_list_head)) {
> urb_context = list_first_entry(&pipe->urb_list_head,
> @@ -55,6 +59,10 @@ static void ath10k_usb_free_urb_to_pipe(struct ath10k_usb_pipe *pipe,
> {
> unsigned long flags;
>
> + /* bail if this pipe is not initialized */
> + if (!pipe->ar_usb)
> + return NULL;
> +
> spin_lock_irqsave(&pipe->ar_usb->cs_lock, flags);
>
> pipe->urb_cnt++;
> --
> 2.22.0
>
^ permalink raw reply
* [PATCH] iwlwifi: mvm: Move static keyword to the front of declarations
From: Krzysztof Wilczynski @ 2019-08-31 22:01 UTC (permalink / raw)
To: Kalle Valo
Cc: Johannes Berg, Emmanuel Grumbach, Luca Coelho,
Intel Linux Wireless, David S. Miller, Sara Sharon,
Shaul Triebitz, Liad Kaufman, linux-wireless, netdev,
linux-kernel
Move the static keyword to the front of declarations of
he_if_types_ext_capa_sta and he_iftypes_ext_capa, and
resolve the following compiler warnings that can be seen
when building with warnings enabled (W=1):
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c:427:1: warning:
‘static’ is not at beginning of declaration [-Wold-style-declaration]
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c:434:1: warning:
‘static’ is not at beginning of declaration [-Wold-style-declaration]
Signed-off-by: Krzysztof Wilczynski <kw@linux.com>
---
Related: https://lore.kernel.org/r/20190827233017.GK9987@google.com
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index d6499763f0dd..937a843fed56 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -424,14 +424,14 @@ int iwl_mvm_init_fw_regd(struct iwl_mvm *mvm)
return ret;
}
-const static u8 he_if_types_ext_capa_sta[] = {
+static const u8 he_if_types_ext_capa_sta[] = {
[0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING,
[2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT,
[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF,
[9] = WLAN_EXT_CAPA10_TWT_REQUESTER_SUPPORT,
};
-const static struct wiphy_iftype_ext_capab he_iftypes_ext_capa[] = {
+static const struct wiphy_iftype_ext_capab he_iftypes_ext_capa[] = {
{
.iftype = NL80211_IFTYPE_STATION,
.extended_capabilities = he_if_types_ext_capa_sta,
--
2.22.1
^ permalink raw reply related
* Re: KASAN: use-after-free Read in rxrpc_put_peer
From: syzbot @ 2019-08-31 23:28 UTC (permalink / raw)
To: davem, dhowells, linux-afs, linux-kernel, netdev, syzkaller-bugs
In-Reply-To: <21753.1567081045@warthog.procyon.org.uk>
Hello,
syzbot has tested the proposed patch and the reproducer did not trigger
crash:
Reported-and-tested-by:
syzbot+b9be979c55f2bea8ed30@syzkaller.appspotmail.com
Tested on:
commit: 48b9e92a rxrpc: Fix lack of conn cleanup when local endpoi..
git tree:
git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git
kernel config: https://syzkaller.appspot.com/x/.config?x=230542aa16bfc4b0
dashboard link: https://syzkaller.appspot.com/bug?extid=b9be979c55f2bea8ed30
compiler: gcc (GCC) 9.0.0 20181231 (experimental)
Note: testing is done by a robot and is best-effort only.
^ permalink raw reply
* Re: [PATCH 4.14] tcp: fix tcp_rtx_queue_tail in case of empty retransmit queue
From: Sasha Levin @ 2019-09-01 0:07 UTC (permalink / raw)
To: Matthieu Baerts
Cc: Tim Froidcoeur, aprout, cpaasch, davem, edumazet, gregkh,
jonathan.lemon, jtl, linux-kernel, mkubecek, ncardwell, stable,
ycheng, netdev
In-Reply-To: <35cd974b-2b31-4f86-d53d-8e9516d4077e@tessares.net>
On Sat, Aug 31, 2019 at 03:14:35PM +0200, Matthieu Baerts wrote:
>Hi Sasha,
>
>Thank you for your reply!
>
>On 31/08/2019 14:20, Sasha Levin wrote:
>> On Sat, Aug 24, 2019 at 08:03:51AM +0200, Tim Froidcoeur wrote:
>>> Commit 8c3088f895a0 ("tcp: be more careful in tcp_fragment()")
>>> triggers following stack trace:
>>>
>>> [25244.848046] kernel BUG at ./include/linux/skbuff.h:1406!
>>> [25244.859335] RIP: 0010:skb_queue_prev+0x9/0xc
>>> [25244.888167] Call Trace:
>>> [25244.889182] <IRQ>
>>> [25244.890001] tcp_fragment+0x9c/0x2cf
>>> [25244.891295] tcp_write_xmit+0x68f/0x988
>>> [25244.892732] __tcp_push_pending_frames+0x3b/0xa0
>>> [25244.894347] tcp_data_snd_check+0x2a/0xc8
>>> [25244.895775] tcp_rcv_established+0x2a8/0x30d
>>> [25244.897282] tcp_v4_do_rcv+0xb2/0x158
>>> [25244.898666] tcp_v4_rcv+0x692/0x956
>>> [25244.899959] ip_local_deliver_finish+0xeb/0x169
>>> [25244.901547] __netif_receive_skb_core+0x51c/0x582
>>> [25244.903193] ? inet_gro_receive+0x239/0x247
>>> [25244.904756] netif_receive_skb_internal+0xab/0xc6
>>> [25244.906395] napi_gro_receive+0x8a/0xc0
>>> [25244.907760] receive_buf+0x9a1/0x9cd
>>> [25244.909160] ? load_balance+0x17a/0x7b7
>>> [25244.910536] ? vring_unmap_one+0x18/0x61
>>> [25244.911932] ? detach_buf+0x60/0xfa
>>> [25244.913234] virtnet_poll+0x128/0x1e1
>>> [25244.914607] net_rx_action+0x12a/0x2b1
>>> [25244.915953] __do_softirq+0x11c/0x26b
>>> [25244.917269] ? handle_irq_event+0x44/0x56
>>> [25244.918695] irq_exit+0x61/0xa0
>>> [25244.919947] do_IRQ+0x9d/0xbb
>>> [25244.921065] common_interrupt+0x85/0x85
>>> [25244.922479] </IRQ>
>>>
>>> tcp_rtx_queue_tail() (called by tcp_fragment()) can call
>>> tcp_write_queue_prev() on the first packet in the queue, which will
>>> trigger
>>> the BUG in tcp_write_queue_prev(), because there is no previous packet.
>>>
>>> This happens when the retransmit queue is empty, for example in case of a
>>> zero window.
>>>
>>> Patch is needed for 4.4, 4.9 and 4.14 stable branches.
>>
>> There needs to be a better explanation of why it's not needed
>> upstream...
>
>Commit 8c3088f895a0 ("tcp: be more careful in tcp_fragment()") was not a
>simple cherry-pick of the original one from master (b617158dc096)
>because there is a specific TCP rtx queue only since v4.15. For more
>details, please see the commit message of b617158dc096 ("tcp: be more
>careful in tcp_fragment()").
>
>The BUG() is hit due to the specific code added to versions older than
>v4.15. The comment in skb_queue_prev() (include/linux/skbuff.h:1406),
>just before the BUG_ON() somehow suggests to add a check before using
>it, what Tim did.
>
>In master, this code path causing the issue will not be taken because
>the implementation of tcp_rtx_queue_tail() is different:
>
> tcp_fragment() → tcp_rtx_queue_tail() → tcp_write_queue_prev() →
>skb_queue_prev() → BUG_ON()
>
>Because this patch is specific to versions older than the two last
>stable ones but still linked to the network architecture, who can review
>and approve it? :)
Thanks for the explanation. I've changed the commit message to include
this explanation and queued it for 4.4, 4.9 and 4.14.
--
Thanks,
Sasha
^ permalink raw reply
* Re: [PATCH v2 net 0/3] Fix issues in tc-taprio and tc-cbs
From: David Miller @ 2019-09-01 1:46 UTC (permalink / raw)
To: olteanv
Cc: xiyou.wangcong, jiri, vinicius.gomes, vedang.patel,
leandro.maciel.dorileo, netdev
In-Reply-To: <20190830010723.32096-1-olteanv@gmail.com>
From: Vladimir Oltean <olteanv@gmail.com>
Date: Fri, 30 Aug 2019 04:07:20 +0300
> This series fixes one panic and one WARN_ON found in the tc-taprio
> qdisc, while trying to apply it:
>
> - On an interface which is not multi-queue
> - On an interface which has no carrier
>
> The tc-cbs was also visually found to suffer of the same issue as
> tc-taprio, and the fix was only compile-tested in that case.
Series applied, thanks.
^ permalink raw reply
* Re: [PATCH v2 net] net: Properly update v4 routes with v6 nexthop
From: David Ahern @ 2019-09-01 2:21 UTC (permalink / raw)
To: Donald Sharp, netdev, David Miller, sworley
In-Reply-To: <20190831122254.29928-1-sharpd@cumulusnetworks.com>
On 8/31/19 6:22 AM, Donald Sharp wrote:
> When creating a v4 route that uses a v6 nexthop from a nexthop group.
> Allow the kernel to properly send the nexthop as v6 via the RTA_VIA
> attribute.
>
Dave: I am on PTO with little time through Monday. I will review/test on
Tuesday.
^ permalink raw reply
* Re: [PATCH v2 0/2] net: dsa: microchip: add KSZ8563 support
From: David Miller @ 2019-09-01 6:36 UTC (permalink / raw)
To: razvan.stefanescu
Cc: woojung.huh, UNGLinuxDriver, andrew, vivien.didelot, f.fainelli,
netdev, linux-kernel
In-Reply-To: <20190830075202.20740-1-razvan.stefanescu@microchip.com>
From: Razvan Stefanescu <razvan.stefanescu@microchip.com>
Date: Fri, 30 Aug 2019 10:52:00 +0300
> This patchset adds compatibility string for the KSZ8563 switch.
Series applied, thank you.
^ permalink raw reply
* Re: [PATCH net-next v3 0/3] net: tls: add socket diag
From: David Miller @ 2019-09-01 6:44 UTC (permalink / raw)
To: dcaratti
Cc: borisp, jakub.kicinski, eric.dumazet, aviadye, davejwatson,
john.fastabend, matthieu.baerts, netdev
In-Reply-To: <cover.1567158431.git.dcaratti@redhat.com>
From: Davide Caratti <dcaratti@redhat.com>
Date: Fri, 30 Aug 2019 12:25:46 +0200
> The current kernel does not provide any diagnostic tool, except
> getsockopt(TCP_ULP), to know more about TCP sockets that have an upper
> layer protocol (ULP) on top of them. This series extends the set of
> information exported by INET_DIAG_INFO, to include data that are
> specific to the ULP (and that might be meaningful for debug/testing
> purposes).
...
Series applied, thanks Davide.
^ permalink raw reply
* Re: [PATCH net-next 0/3] dpaa2-eth: Add new statistics counters
From: David Miller @ 2019-09-01 6:42 UTC (permalink / raw)
To: jakub.kicinski; +Cc: ruxandra.radulescu, netdev, ioana.ciornei
In-Reply-To: <20190830231219.2363758a@cakuba.netronome.com>
From: Jakub Kicinski <jakub.kicinski@netronome.com>
Date: Fri, 30 Aug 2019 23:12:19 -0700
> On Fri, 30 Aug 2019 13:20:40 +0300, Ioana Radulescu wrote:
>> Recent firmware versions offer access to more DPNI statistics
>> counters. Add the relevant ones to ethtool interface stats.
>>
>> Also we can now make use of a new counter for in flight egress frames
>> to avoid sleeping an arbitrary amount of time in the ndo_stop routine.
>
> A little messy there in the comment of patch 2, and IMHO if you're
> expecting particular errors to be ignored it's better to write:
>
> if (err == -EOPNOTSUPP)
> /* still fine*/;
> else if (err)
> /* real err */
>
> than assume any error is for unsupported and add a extra comment
> explaining that things may be not supported.
Ioana, please address this feedback and respin your patchset.
Thank you.
^ permalink raw reply
* Re: [PATCH] net: bcmgenet: use ethtool_op_get_ts_info()
From: David Miller @ 2019-09-01 6:51 UTC (permalink / raw)
To: rmc032; +Cc: opendmb, f.fainelli, bcm-kernel-feedback-list, netdev,
linux-kernel
In-Reply-To: <20190830184955.GA27521@pop-os.localdomain>
From: "Ryan M. Collins" <rmc032@bucknell.edu>
Date: Fri, 30 Aug 2019 14:49:55 -0400
> This change enables the use of SW timestamping on the Raspberry Pi 4.
>
> bcmgenet's transmit function bcmgenet_xmit() implements software
> timestamping. However the SOF_TIMESTAMPING_TX_SOFTWARE capability was
> missing and only SOF_TIMESTAMPING_RX_SOFTWARE was announced. By using
> ethtool_ops bcmgenet_ethtool_ops() as get_ts_info(), the
> SOF_TIMESTAMPING_TX_SOFTWARE capability is announced.
>
> Similar to commit a8f5cb9e7991 ("smsc95xx: use ethtool_op_get_ts_info()")
>
> Signed-off-by: Ryan M. Collins <rmc032@bucknell.edu>
Applied.
^ permalink raw reply
* Re: [PATCH] enetc: Add missing call to 'pci_free_irq_vectors()' in probe and remove functions
From: David Miller @ 2019-09-01 6:53 UTC (permalink / raw)
To: christophe.jaillet
Cc: yangbo.lu, claudiu.manoil, netdev, linux-kernel, kernel-janitors
In-Reply-To: <20190830202312.21287-1-christophe.jaillet@wanadoo.fr>
From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Date: Fri, 30 Aug 2019 22:23:12 +0200
> Call to 'pci_free_irq_vectors()' are missing both in the error handling
> path of the probe function, and in the remove function.
> Add them.
>
> Fixes: 19971f5ea0ab ("enetc: add PTP clock driver")
> Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH v2 net-next] net/ncsi: add response handlers for PLDM over NC-SI
From: David Miller @ 2019-09-01 6:54 UTC (permalink / raw)
To: benwei; +Cc: sam, netdev, linux-kernel, openbmc
In-Reply-To: <CH2PR15MB3686A26D4BB64D8959B519B6A3BD0@CH2PR15MB3686.namprd15.prod.outlook.com>
From: Ben Wei <benwei@fb.com>
Date: Fri, 30 Aug 2019 20:50:51 +0000
> This patch adds handlers for PLDM over NC-SI command response.
>
> This enables NC-SI driver recognizes the packet type so the responses
> don't get dropped as unknown packet type.
>
> PLDM over NC-SI are not handled in kernel driver for now, but can be
> passed back to user space via Netlink for further handling.
>
> Signed-off-by: Ben Wei <benwei@fb.com>
> ---
> Changes in v2
> - fix function definition spacing
Applied.
^ permalink raw reply
* Re: [PATCH v3 1/2] net: core: Notify on changes to dev->promiscuity.
From: Jiri Pirko @ 2019-09-01 6:54 UTC (permalink / raw)
To: Andrew Lunn
Cc: Ido Schimmel, David Miller, horatiu.vultur, alexandre.belloni,
UNGLinuxDriver, allan.nielsen, ivecera, f.fainelli, netdev,
linux-kernel
In-Reply-To: <20190831193556.GB2647@lunn.ch>
Sat, Aug 31, 2019 at 09:35:56PM CEST, andrew@lunn.ch wrote:
>> Also, what happens when I'm running these application without putting
>> the interface in promisc mode? On an offloaded interface I would not be
>> able to even capture packets addressed to my interface's MAC address.
>
>Sorry for rejoining the discussion late. I've been travelling and i'm
>now 3/4 of the way to Lisbon.
>
>That statement i don't get. If the frame has the MAC address of the
>interface, it has to be delivered to the CPU. And so pcap will see it
1) you cannot go to slowpath for all such packets (route)
2) you might be interested to examine packets with other dest mac too.
>when running on the interface. I can pretty much guarantee every DSA
>driver does that.
>
>But to address the bigger picture. My understanding is that we want to
>model offloading as a mechanism to accelerate what Linux can already
>do. The user should not have to care about these accelerators. The
>interface should work like a normal Linux interface. I can put an IP
>address on it and ping a peer. I can run a dhcp client and get an IP
>address from a dhcp server. I can add the interface to a bridge, and
>packets will get bridged. I as a user should not need to care if this
>is done in software, or accelerated by offloading it. I can add a
>route, and if the accelerate knows about L3, it can accelerate that as
>well. If not, the kernel will route it.
>
>So if i run wireshark on an interface, i expect the interface will be
>put into promisc mode and i see all packets ingressing the interface.
Again, you are merging 2 things together:
1) rx filter - this is needed for bridge, ovs, others (tc)
this is promisc setting
2) cpu trap - here one may be interested in:
a) only packets ASIC traps to CPU by default (ARPs, STP, BGP, etc)
b) all packets ingressing the port (note that those are only those
passed by rx filter)
Clearly 1) and 2) need separate knobs. In 2), there are valid usecases
for both a) and b). Only the user is the one who can tell which is he
interested in. This can't happen automagically.
Can we just have a knob for 2)?
>What the accelerator needs to do to achieve this, i as a user don't
>care.
>
>I can follow the argument that i won't necessarily see every
>packet. But that is always true. For many embedded systems, the CPU is
>too slow to receive at line rate, even when we are talking about 1G
>links. Packets do get dropped. And i hope tcpdump users understand
>that.
>
>For me, having tcpdump use tc trap is just wrong. It breaks the model
>that the user should not care about the accelerator. If anything, i
>think the driver needs to translate cBPF which pcap passes to the
>kernel to whatever internal format the accelerator can process. That
>is just another example of using hardware acceleration.
>
> Andrew
^ permalink raw reply
* Re: [PATCH net-next 0/2] Minor cleanup in devlink
From: David Miller @ 2019-09-01 6:46 UTC (permalink / raw)
To: jakub.kicinski; +Cc: parav, netdev, jiri
In-Reply-To: <20190830231436.34f221b2@cakuba.netronome.com>
From: Jakub Kicinski <jakub.kicinski@netronome.com>
Date: Fri, 30 Aug 2019 23:14:36 -0700
> On Fri, 30 Aug 2019 05:39:43 -0500, Parav Pandit wrote:
>> Two minor cleanup in devlink.
>>
>> Patch-1 Explicitly defines devlink port index as unsigned int
>> Patch-2 Uses switch-case to handle different port flavours attributes
>
> Always nice to see one's comment addressed, even if it takes a while :)
>
> Acked-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Series applied.
^ permalink raw reply
* Re: [PATCH net] tc-testing: don't hardcode 'ip' in nsPlugin.py
From: David Miller @ 2019-09-01 6:47 UTC (permalink / raw)
To: dcaratti
Cc: liuhangbin, mrv, vladbu, lucasb, nicolas.dichtel, netdev,
marcelo.leitner
In-Reply-To: <8ade839e21c5231d2d6b8690b39587f802642306.1567180765.git.dcaratti@redhat.com>
From: Davide Caratti <dcaratti@redhat.com>
Date: Fri, 30 Aug 2019 18:51:47 +0200
> the following tdc test fails on Fedora:
>
> # ./tdc.py -e 2638
> -- ns/SubPlugin.__init__
> Test 2638: Add matchall and try to get it
> -----> prepare stage *** Could not execute: "$TC qdisc add dev $DEV1 clsact"
> -----> prepare stage *** Error message: "/bin/sh: ip: command not found"
> returncode 127; expected [0]
> -----> prepare stage *** Aborting test run.
>
> Let nsPlugin.py use the 'IP' variable introduced with commit 92c1a19e2fb9
> ("tc-tests: added path to ip command in tdc"), so that the path to 'ip' is
> correctly resolved to the value we have in tdc_config.py.
>
> # ./tdc.py -e 2638
> -- ns/SubPlugin.__init__
> Test 2638: Add matchall and try to get it
> All test results:
> 1..1
> ok 1 2638 - Add matchall and try to get it
>
> Fixes: 489ce2f42514 ("tc-testing: Restore original behaviour for namespaces in tdc")
> Reported-by: Hangbin Liu <liuhangbin@gmail.com>
> Signed-off-by: Davide Caratti <dcaratti@redhat.com>
Applied.
^ permalink raw reply
* Re: [PATCH v4 1/5] vsock/virtio: limit the memory used per-socket
From: Michael S. Tsirkin @ 2019-09-01 6:56 UTC (permalink / raw)
To: Stefano Garzarella
Cc: Stefan Hajnoczi, netdev, linux-kernel, David S. Miller,
virtualization, Jason Wang, kvm
In-Reply-To: <20190830094059.c7qo5cxrp2nkrncd@steredhat>
On Fri, Aug 30, 2019 at 11:40:59AM +0200, Stefano Garzarella wrote:
> On Mon, Jul 29, 2019 at 10:04:29AM -0400, Michael S. Tsirkin wrote:
> > On Wed, Jul 17, 2019 at 01:30:26PM +0200, Stefano Garzarella wrote:
> > > Since virtio-vsock was introduced, the buffers filled by the host
> > > and pushed to the guest using the vring, are directly queued in
> > > a per-socket list. These buffers are preallocated by the guest
> > > with a fixed size (4 KB).
> > >
> > > The maximum amount of memory used by each socket should be
> > > controlled by the credit mechanism.
> > > The default credit available per-socket is 256 KB, but if we use
> > > only 1 byte per packet, the guest can queue up to 262144 of 4 KB
> > > buffers, using up to 1 GB of memory per-socket. In addition, the
> > > guest will continue to fill the vring with new 4 KB free buffers
> > > to avoid starvation of other sockets.
> > >
> > > This patch mitigates this issue copying the payload of small
> > > packets (< 128 bytes) into the buffer of last packet queued, in
> > > order to avoid wasting memory.
> > >
> > > Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
> > > Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
> >
> > This is good enough for net-next, but for net I think we
> > should figure out how to address the issue completely.
> > Can we make the accounting precise? What happens to
> > performance if we do?
> >
>
> Since I'm back from holidays, I'm restarting this thread to figure out
> how to address the issue completely.
>
> I did a better analysis of the credit mechanism that we implemented in
> virtio-vsock to get a clearer view and I'd share it with you:
>
> This issue affect only the "host->guest" path. In this case, when the
> host wants to send a packet to the guest, it uses a "free" buffer
> allocated by the guest (4KB).
> The "free" buffers available for the host are shared between all
> sockets, instead, the credit mechanism is per-socket, I think to
> avoid the starvation of others sockets.
> The guests re-fill the "free" queue when the available buffers are
> less than half.
>
> Each peer have these variables in the per-socket state:
> /* local vars */
> buf_alloc /* max bytes usable by this socket
> [exposed to the other peer] */
> fwd_cnt /* increased when RX packet is consumed by the
> user space [exposed to the other peer] */
> tx_cnt /* increased when TX packet is sent to the other peer */
>
> /* remote vars */
> peer_buf_alloc /* peer's buf_alloc */
> peer_fwd_cnt /* peer's fwd_cnt */
>
> When a peer sends a packet, it increases the 'tx_cnt'; when the
> receiver consumes the packet (copy it to the user-space buffer), it
> increases the 'fwd_cnt'.
> Note: increments are made considering the payload length and not the
> buffer length.
>
> The value of 'buf_alloc' and 'fwd_cnt' are sent to the other peer in
> all packet headers or with an explicit CREDIT_UPDATE packet.
>
> The local 'buf_alloc' value can be modified by the user space using
> setsockopt() with optname=SO_VM_SOCKETS_BUFFER_SIZE.
>
> Before to send a packet, the peer checks the space available:
> credit_available = peer_buf_alloc - (tx_cnt - peer_fwd_cnt)
> and it will send up to credit_available bytes to the other peer.
>
> Possible solutions considering Michael's advice:
> 1. Use the buffer length instead of the payload length when we increment
> the counters:
> - This approach will account precisely the memory used per socket.
> - This requires changes in both guest and host.
> - It is not compatible with old drivers, so a feature should be negotiated.
> 2. Decrease the advertised 'buf_alloc' taking count of bytes queued in
> the socket queue but not used. (e.g. 256 byte used on 4K available in
> the buffer)
> - pkt->hdr.buf_alloc = buf_alloc - bytes_not_used.
> - This should be compatible also with old drivers.
>
> Maybe the second is less invasive, but will it be too tricky?
> Any other advice or suggestions?
>
> Thanks in advance,
> Stefano
OK let me try to clarify. The idea is this:
Let's say we queue a buffer of 4K, and we copy if len < 128 bytes. This
means that in the worst case (128 byte packets), each byte of credit in
the socket uses up 4K/128 = 16 bytes of kernel memory. In fact we need
to also account for the virtio_vsock_pkt since I think it's kept around
until userspace consumes it.
Thus given X buf alloc allowed in the socket, we should publish X/16
credits to the other side. This will ensure the other side does not send
more than X/16 bytes for a given socket and thus we won't need to
allocate more than X bytes to hold the data.
We can play with the copy break value to tweak this.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox