* [PATCH net-next v2 00/10] net: dsa: lan9303: unicast offload, fdb,mdb,STP
From: Egil Hjelmeland @ 2017-07-25 16:15 UTC (permalink / raw)
To: corbet, andrew, vivien.didelot, f.fainelli, davem, kernel,
linux-doc, linux-kernel, netdev
Cc: Egil Hjelmeland
This series extends the LAN9303 3 port switch DSA driver. Highlights:
- Make the MDIO interface work
- Bridging: Unicast offload
- Bridging: Added fdb/mdb handling
- Bridging: STP support
- Documentation
Changes v1 -> v2:
- sorted out emailing issues, threading and date. And sent from private
account in order to avoid company disclaimer in emails.
- Removed the three last "work around" patches. But first moved one doc
paragraph to the document patch.
Egil Hjelmeland (10):
net: dsa: lan9303: Fixed MDIO interface
net: dsa: lan9303: Do not disable/enable switch fabric port 0 at
startup
net: dsa: lan9303: Refactor lan9303_enable_packet_processing()
net: dsa: lan9303: Added adjust_link() method
net: dsa: added dsa_net_device_to_dsa_port()
net: dsa: lan9303: added sysfs node swe_bcst_throt
net: dsa: lan9303: Added basic offloading of unicast traffic
net: dsa: lan9303: Added ALR/fdb/mdb handling
net: dsa: lan9303: Added Documentation/networking/dsa/lan9303.txt
net: dsa: lan9303: Only allocate 3 ports
Documentation/networking/dsa/lan9303.txt | 63 +++
drivers/net/dsa/lan9303-core.c | 709 ++++++++++++++++++++++++++++---
drivers/net/dsa/lan9303.h | 23 +
drivers/net/dsa/lan9303_i2c.c | 2 +
drivers/net/dsa/lan9303_mdio.c | 34 ++
include/net/dsa.h | 1 +
net/dsa/slave.c | 10 +
7 files changed, 772 insertions(+), 70 deletions(-)
create mode 100644 Documentation/networking/dsa/lan9303.txt
--
2.11.0
^ permalink raw reply
* [PATCH net-next v2 01/10] net: dsa: lan9303: Fixed MDIO interface
From: Egil Hjelmeland @ 2017-07-25 16:15 UTC (permalink / raw)
To: corbet, andrew, vivien.didelot, f.fainelli, davem, kernel,
linux-doc, linux-kernel, netdev
Cc: Egil Hjelmeland
In-Reply-To: <20170725161553.30147-1-privat@egil-hjelmeland.no>
Fixes after testing on actual HW:
- lan9303_mdio_write()/_read() must multiply register number
by 4 to get offset
- Indirect access (PMI) to phy register only work in I2C mode. In
MDIO mode phy registers must be accessed directly. Introduced
struct lan9303_phy_ops to handle the two modes. Renamed functions
to clarify.
- lan9303_detect_phy_setup() : Failed MDIO read return 0xffff.
Handle that.
Signed-off-by: Egil Hjelmeland <privat@egil-hjelmeland.no>
---
drivers/net/dsa/lan9303-core.c | 42 +++++++++++++++++++++++++++---------------
drivers/net/dsa/lan9303.h | 11 +++++++++++
drivers/net/dsa/lan9303_i2c.c | 2 ++
drivers/net/dsa/lan9303_mdio.c | 34 ++++++++++++++++++++++++++++++++++
4 files changed, 74 insertions(+), 15 deletions(-)
diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
index cd76e61f1fca..e622db586c3d 100644
--- a/drivers/net/dsa/lan9303-core.c
+++ b/drivers/net/dsa/lan9303-core.c
@@ -20,6 +20,9 @@
#include "lan9303.h"
+/* 13.2 System Control and Status Registers
+ * Multiply register number by 4 to get address offset.
+ */
#define LAN9303_CHIP_REV 0x14
# define LAN9303_CHIP_ID 0x9303
#define LAN9303_IRQ_CFG 0x15
@@ -53,6 +56,9 @@
#define LAN9303_VIRT_PHY_BASE 0x70
#define LAN9303_VIRT_SPECIAL_CTRL 0x77
+/*13.4 Switch Fabric Control and Status Registers
+ * Accessed indirectly via SWITCH_CSR_CMD, SWITCH_CSR_DATA.
+ */
#define LAN9303_SW_DEV_ID 0x0000
#define LAN9303_SW_RESET 0x0001
#define LAN9303_SW_RESET_RESET BIT(0)
@@ -242,7 +248,7 @@ static int lan9303_virt_phy_reg_write(struct lan9303 *chip, int regnum, u16 val)
return regmap_write(chip->regmap, LAN9303_VIRT_PHY_BASE + regnum, val);
}
-static int lan9303_port_phy_reg_wait_for_completion(struct lan9303 *chip)
+static int lan9303_indirect_phy_wait_for_completion(struct lan9303 *chip)
{
int ret, i;
u32 reg;
@@ -262,7 +268,7 @@ static int lan9303_port_phy_reg_wait_for_completion(struct lan9303 *chip)
return -EIO;
}
-static int lan9303_port_phy_reg_read(struct lan9303 *chip, int addr, int regnum)
+static int lan9303_indirect_phy_read(struct lan9303 *chip, int addr, int regnum)
{
int ret;
u32 val;
@@ -272,7 +278,7 @@ static int lan9303_port_phy_reg_read(struct lan9303 *chip, int addr, int regnum)
mutex_lock(&chip->indirect_mutex);
- ret = lan9303_port_phy_reg_wait_for_completion(chip);
+ ret = lan9303_indirect_phy_wait_for_completion(chip);
if (ret)
goto on_error;
@@ -281,7 +287,7 @@ static int lan9303_port_phy_reg_read(struct lan9303 *chip, int addr, int regnum)
if (ret)
goto on_error;
- ret = lan9303_port_phy_reg_wait_for_completion(chip);
+ ret = lan9303_indirect_phy_wait_for_completion(chip);
if (ret)
goto on_error;
@@ -299,8 +305,8 @@ static int lan9303_port_phy_reg_read(struct lan9303 *chip, int addr, int regnum)
return ret;
}
-static int lan9303_phy_reg_write(struct lan9303 *chip, int addr, int regnum,
- unsigned int val)
+static int lan9303_indirect_phy_write(struct lan9303 *chip, int addr,
+ int regnum, u16 val)
{
int ret;
u32 reg;
@@ -311,7 +317,7 @@ static int lan9303_phy_reg_write(struct lan9303 *chip, int addr, int regnum,
mutex_lock(&chip->indirect_mutex);
- ret = lan9303_port_phy_reg_wait_for_completion(chip);
+ ret = lan9303_indirect_phy_wait_for_completion(chip);
if (ret)
goto on_error;
@@ -328,6 +334,11 @@ static int lan9303_phy_reg_write(struct lan9303 *chip, int addr, int regnum,
return ret;
}
+const struct lan9303_phy_ops lan9303_indirect_phy_ops = {
+ .phy_read = lan9303_indirect_phy_read,
+ .phy_write = lan9303_indirect_phy_write,
+};
+
static int lan9303_switch_wait_for_completion(struct lan9303 *chip)
{
int ret, i;
@@ -427,14 +438,15 @@ static int lan9303_detect_phy_setup(struct lan9303 *chip)
* Special reg 18 of phy 3 reads as 0x0000, if 'phy_addr_sel_strap' is 0
* and the IDs are 0-1-2, else it contains something different from
* 0x0000, which means 'phy_addr_sel_strap' is 1 and the IDs are 1-2-3.
+ * 0xffff is returned for failed MDIO access.
*/
- reg = lan9303_port_phy_reg_read(chip, 3, MII_LAN911X_SPECIAL_MODES);
+ reg = chip->ops->phy_read(chip, 3, MII_LAN911X_SPECIAL_MODES);
if (reg < 0) {
dev_err(chip->dev, "Failed to detect phy config: %d\n", reg);
return reg;
}
- if (reg != 0)
+ if ((reg != 0) && (reg != 0xffff))
chip->phy_addr_sel_strap = 1;
else
chip->phy_addr_sel_strap = 0;
@@ -719,7 +731,7 @@ static int lan9303_phy_read(struct dsa_switch *ds, int phy, int regnum)
if (phy > phy_base + 2)
return -ENODEV;
- return lan9303_port_phy_reg_read(chip, phy, regnum);
+ return chip->ops->phy_read(chip, phy, regnum);
}
static int lan9303_phy_write(struct dsa_switch *ds, int phy, int regnum,
@@ -733,7 +745,7 @@ static int lan9303_phy_write(struct dsa_switch *ds, int phy, int regnum,
if (phy > phy_base + 2)
return -ENODEV;
- return lan9303_phy_reg_write(chip, phy, regnum, val);
+ return chip->ops->phy_write(chip, phy, regnum, val);
}
static int lan9303_port_enable(struct dsa_switch *ds, int port,
@@ -766,13 +778,13 @@ static void lan9303_port_disable(struct dsa_switch *ds, int port,
switch (port) {
case 1:
lan9303_disable_packet_processing(chip, LAN9303_PORT_1_OFFSET);
- lan9303_phy_reg_write(chip, chip->phy_addr_sel_strap + 1,
- MII_BMCR, BMCR_PDOWN);
+ lan9303_phy_write(ds, chip->phy_addr_sel_strap + 1,
+ MII_BMCR, BMCR_PDOWN);
break;
case 2:
lan9303_disable_packet_processing(chip, LAN9303_PORT_2_OFFSET);
- lan9303_phy_reg_write(chip, chip->phy_addr_sel_strap + 2,
- MII_BMCR, BMCR_PDOWN);
+ lan9303_phy_write(ds, chip->phy_addr_sel_strap + 2,
+ MII_BMCR, BMCR_PDOWN);
break;
default:
dev_dbg(chip->dev,
diff --git a/drivers/net/dsa/lan9303.h b/drivers/net/dsa/lan9303.h
index d1512dad2d90..444d00b460e1 100644
--- a/drivers/net/dsa/lan9303.h
+++ b/drivers/net/dsa/lan9303.h
@@ -2,6 +2,15 @@
#include <linux/device.h>
#include <net/dsa.h>
+struct lan9303;
+
+struct lan9303_phy_ops {
+ /* PHY 1 &2 access*/
+ int (*phy_read)(struct lan9303 *chip, int port, int regnum);
+ int (*phy_write)(struct lan9303 *chip, int port,
+ int regnum, u16 val);
+};
+
struct lan9303 {
struct device *dev;
struct regmap *regmap;
@@ -11,9 +20,11 @@ struct lan9303 {
bool phy_addr_sel_strap;
struct dsa_switch *ds;
struct mutex indirect_mutex; /* protect indexed register access */
+ const struct lan9303_phy_ops *ops;
};
extern const struct regmap_access_table lan9303_register_set;
+extern const struct lan9303_phy_ops lan9303_indirect_phy_ops;
int lan9303_probe(struct lan9303 *chip, struct device_node *np);
int lan9303_remove(struct lan9303 *chip);
diff --git a/drivers/net/dsa/lan9303_i2c.c b/drivers/net/dsa/lan9303_i2c.c
index ab3ce0da5071..24ec20f7f444 100644
--- a/drivers/net/dsa/lan9303_i2c.c
+++ b/drivers/net/dsa/lan9303_i2c.c
@@ -63,6 +63,8 @@ static int lan9303_i2c_probe(struct i2c_client *client,
i2c_set_clientdata(client, sw_dev);
sw_dev->chip.dev = &client->dev;
+ sw_dev->chip.ops = &lan9303_indirect_phy_ops;
+
ret = lan9303_probe(&sw_dev->chip, client->dev.of_node);
if (ret != 0)
return ret;
diff --git a/drivers/net/dsa/lan9303_mdio.c b/drivers/net/dsa/lan9303_mdio.c
index 93c36c0541cf..94df12c5362f 100644
--- a/drivers/net/dsa/lan9303_mdio.c
+++ b/drivers/net/dsa/lan9303_mdio.c
@@ -39,6 +39,7 @@ static void lan9303_mdio_real_write(struct mdio_device *mdio, int reg, u16 val)
static int lan9303_mdio_write(void *ctx, uint32_t reg, uint32_t val)
{
struct lan9303_mdio *sw_dev = (struct lan9303_mdio *)ctx;
+ reg <<= 2; /* reg num to offset */
mutex_lock(&sw_dev->device->bus->mdio_lock);
lan9303_mdio_real_write(sw_dev->device, reg, val & 0xffff);
@@ -56,6 +57,7 @@ static u16 lan9303_mdio_real_read(struct mdio_device *mdio, int reg)
static int lan9303_mdio_read(void *ctx, uint32_t reg, uint32_t *val)
{
struct lan9303_mdio *sw_dev = (struct lan9303_mdio *)ctx;
+ reg <<= 2; /* reg num to offset */
mutex_lock(&sw_dev->device->bus->mdio_lock);
*val = lan9303_mdio_real_read(sw_dev->device, reg);
@@ -65,6 +67,36 @@ static int lan9303_mdio_read(void *ctx, uint32_t reg, uint32_t *val)
return 0;
}
+int lan9303_mdio_phy_write(struct lan9303 *chip, int phy, int regnum, u16 val)
+{
+ struct lan9303_mdio *sw_dev = dev_get_drvdata(chip->dev);
+ struct mdio_device *mdio = sw_dev->device;
+
+ mutex_lock(&mdio->bus->mdio_lock);
+ mdio->bus->write(mdio->bus, phy, regnum, val);
+ mutex_unlock(&mdio->bus->mdio_lock);
+
+ return 0;
+}
+
+int lan9303_mdio_phy_read(struct lan9303 *chip, int phy, int reg)
+{
+ struct lan9303_mdio *sw_dev = dev_get_drvdata(chip->dev);
+ struct mdio_device *mdio = sw_dev->device;
+ int val;
+
+ mutex_lock(&mdio->bus->mdio_lock);
+ val = mdio->bus->read(mdio->bus, phy, reg);
+ mutex_unlock(&mdio->bus->mdio_lock);
+
+ return val;
+}
+
+static const struct lan9303_phy_ops lan9303_mdio_phy_ops = {
+ .phy_read = lan9303_mdio_phy_read,
+ .phy_write = lan9303_mdio_phy_write,
+};
+
static const struct regmap_config lan9303_mdio_regmap_config = {
.reg_bits = 8,
.val_bits = 32,
@@ -106,6 +138,8 @@ static int lan9303_mdio_probe(struct mdio_device *mdiodev)
dev_set_drvdata(&mdiodev->dev, sw_dev);
sw_dev->chip.dev = &mdiodev->dev;
+ sw_dev->chip.ops = &lan9303_mdio_phy_ops;
+
ret = lan9303_probe(&sw_dev->chip, mdiodev->dev.of_node);
if (ret != 0)
return ret;
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v2 02/10] net: dsa: lan9303: Do not disable/enable switch fabric port 0 at startup
From: Egil Hjelmeland @ 2017-07-25 16:15 UTC (permalink / raw)
To: corbet, andrew, vivien.didelot, f.fainelli, davem, kernel,
linux-doc, linux-kernel, netdev
Cc: Egil Hjelmeland
In-Reply-To: <20170725161553.30147-1-privat@egil-hjelmeland.no>
For some mysterious reason enable switch fabric port 0 TX fails to
work, when the TX has previous been disabled. Resolved by not
disable/enable switch fabric port 0 at startup. Port 1 and 2 are
still disabled in early init.
Signed-off-by: Egil Hjelmeland <privat@egil-hjelmeland.no>
---
drivers/net/dsa/lan9303-core.c | 7 -------
1 file changed, 7 deletions(-)
diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
index e622db586c3d..c2b53659f58f 100644
--- a/drivers/net/dsa/lan9303-core.c
+++ b/drivers/net/dsa/lan9303-core.c
@@ -557,9 +557,6 @@ static int lan9303_disable_processing(struct lan9303 *chip)
{
int ret;
- ret = lan9303_disable_packet_processing(chip, LAN9303_PORT_0_OFFSET);
- if (ret)
- return ret;
ret = lan9303_disable_packet_processing(chip, LAN9303_PORT_1_OFFSET);
if (ret)
return ret;
@@ -633,10 +630,6 @@ static int lan9303_setup(struct dsa_switch *ds)
if (ret)
dev_err(chip->dev, "failed to separate ports %d\n", ret);
- ret = lan9303_enable_packet_processing(chip, LAN9303_PORT_0_OFFSET);
- if (ret)
- dev_err(chip->dev, "failed to re-enable switching %d\n", ret);
-
return 0;
}
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v2 03/10] net: dsa: lan9303: Refactor lan9303_enable_packet_processing()
From: Egil Hjelmeland @ 2017-07-25 16:15 UTC (permalink / raw)
To: corbet, andrew, vivien.didelot, f.fainelli, davem, kernel,
linux-doc, linux-kernel, netdev
Cc: Egil Hjelmeland
In-Reply-To: <20170725161553.30147-1-privat@egil-hjelmeland.no>
lan9303_enable_packet_processing, lan9303_disable_packet_processing()
Pass port number (0,1,2) as parameter instead of port offset.
Simplify accordingly.
Signed-off-by: Egil Hjelmeland <privat@egil-hjelmeland.no>
---
drivers/net/dsa/lan9303-core.c | 66 ++++++++++++++++++++----------------------
1 file changed, 32 insertions(+), 34 deletions(-)
diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
index c2b53659f58f..0806a0684d55 100644
--- a/drivers/net/dsa/lan9303-core.c
+++ b/drivers/net/dsa/lan9303-core.c
@@ -159,9 +159,7 @@
# define LAN9303_BM_EGRSS_PORT_TYPE_SPECIAL_TAG_PORT1 (BIT(9) | BIT(8))
# define LAN9303_BM_EGRSS_PORT_TYPE_SPECIAL_TAG_PORT0 (BIT(1) | BIT(0))
-#define LAN9303_PORT_0_OFFSET 0x400
-#define LAN9303_PORT_1_OFFSET 0x800
-#define LAN9303_PORT_2_OFFSET 0xc00
+#define LAN9303_SWITCH_PORT_REG(port, reg0) (0x400 * (port) + (reg0))
/* the built-in PHYs are of type LAN911X */
#define MII_LAN911X_SPECIAL_MODES 0x12
@@ -457,24 +455,25 @@ static int lan9303_detect_phy_setup(struct lan9303 *chip)
return 0;
}
-#define LAN9303_MAC_RX_CFG_OFFS (LAN9303_MAC_RX_CFG_0 - LAN9303_PORT_0_OFFSET)
-#define LAN9303_MAC_TX_CFG_OFFS (LAN9303_MAC_TX_CFG_0 - LAN9303_PORT_0_OFFSET)
-
static int lan9303_disable_packet_processing(struct lan9303 *chip,
unsigned int port)
{
int ret;
/* disable RX, but keep register reset default values else */
- ret = lan9303_write_switch_reg(chip, LAN9303_MAC_RX_CFG_OFFS + port,
- LAN9303_MAC_RX_CFG_X_REJECT_MAC_TYPES);
+ ret = lan9303_write_switch_reg(
+ chip,
+ LAN9303_SWITCH_PORT_REG(port, LAN9303_MAC_RX_CFG_0),
+ LAN9303_MAC_RX_CFG_X_REJECT_MAC_TYPES);
if (ret)
return ret;
/* disable TX, but keep register reset default values else */
- return lan9303_write_switch_reg(chip, LAN9303_MAC_TX_CFG_OFFS + port,
- LAN9303_MAC_TX_CFG_X_TX_IFG_CONFIG_DEFAULT |
- LAN9303_MAC_TX_CFG_X_TX_PAD_ENABLE);
+ return lan9303_write_switch_reg(
+ chip,
+ LAN9303_SWITCH_PORT_REG(port, LAN9303_MAC_TX_CFG_0),
+ LAN9303_MAC_TX_CFG_X_TX_IFG_CONFIG_DEFAULT |
+ LAN9303_MAC_TX_CFG_X_TX_PAD_ENABLE);
}
static int lan9303_enable_packet_processing(struct lan9303 *chip,
@@ -483,17 +482,21 @@ static int lan9303_enable_packet_processing(struct lan9303 *chip,
int ret;
/* enable RX and keep register reset default values else */
- ret = lan9303_write_switch_reg(chip, LAN9303_MAC_RX_CFG_OFFS + port,
- LAN9303_MAC_RX_CFG_X_REJECT_MAC_TYPES |
- LAN9303_MAC_RX_CFG_X_RX_ENABLE);
+ ret = lan9303_write_switch_reg(
+ chip,
+ LAN9303_SWITCH_PORT_REG(port, LAN9303_MAC_RX_CFG_0),
+ LAN9303_MAC_RX_CFG_X_REJECT_MAC_TYPES |
+ LAN9303_MAC_RX_CFG_X_RX_ENABLE);
if (ret)
return ret;
/* enable TX and keep register reset default values else */
- return lan9303_write_switch_reg(chip, LAN9303_MAC_TX_CFG_OFFS + port,
- LAN9303_MAC_TX_CFG_X_TX_IFG_CONFIG_DEFAULT |
- LAN9303_MAC_TX_CFG_X_TX_PAD_ENABLE |
- LAN9303_MAC_TX_CFG_X_TX_ENABLE);
+ return lan9303_write_switch_reg(
+ chip,
+ LAN9303_SWITCH_PORT_REG(port, LAN9303_MAC_TX_CFG_0),
+ LAN9303_MAC_TX_CFG_X_TX_IFG_CONFIG_DEFAULT |
+ LAN9303_MAC_TX_CFG_X_TX_PAD_ENABLE |
+ LAN9303_MAC_TX_CFG_X_TX_ENABLE);
}
/* We want a special working switch:
@@ -555,12 +558,14 @@ static int lan9303_handle_reset(struct lan9303 *chip)
/* stop processing packets for all ports */
static int lan9303_disable_processing(struct lan9303 *chip)
{
- int ret;
+ int ret, p;
- ret = lan9303_disable_packet_processing(chip, LAN9303_PORT_1_OFFSET);
- if (ret)
- return ret;
- return lan9303_disable_packet_processing(chip, LAN9303_PORT_2_OFFSET);
+ for (p = 1; p <= 2; p++) {
+ ret = lan9303_disable_packet_processing(chip, p);
+ if (ret)
+ return ret;
+ }
+ return 0;
}
static int lan9303_check_device(struct lan9303 *chip)
@@ -696,7 +701,7 @@ static void lan9303_get_ethtool_stats(struct dsa_switch *ds, int port,
unsigned int u, poff;
int ret;
- poff = port * 0x400;
+ poff = LAN9303_SWITCH_PORT_REG(port, 0);
for (u = 0; u < ARRAY_SIZE(lan9303_mib); u++) {
ret = lan9303_read_switch_reg(chip,
@@ -749,11 +754,8 @@ static int lan9303_port_enable(struct dsa_switch *ds, int port,
/* enable internal packet processing */
switch (port) {
case 1:
- return lan9303_enable_packet_processing(chip,
- LAN9303_PORT_1_OFFSET);
case 2:
- return lan9303_enable_packet_processing(chip,
- LAN9303_PORT_2_OFFSET);
+ return lan9303_enable_packet_processing(chip, port);
default:
dev_dbg(chip->dev,
"Error: request to power up invalid port %d\n", port);
@@ -770,13 +772,9 @@ static void lan9303_port_disable(struct dsa_switch *ds, int port,
/* disable internal packet processing */
switch (port) {
case 1:
- lan9303_disable_packet_processing(chip, LAN9303_PORT_1_OFFSET);
- lan9303_phy_write(ds, chip->phy_addr_sel_strap + 1,
- MII_BMCR, BMCR_PDOWN);
- break;
case 2:
- lan9303_disable_packet_processing(chip, LAN9303_PORT_2_OFFSET);
- lan9303_phy_write(ds, chip->phy_addr_sel_strap + 2,
+ lan9303_disable_packet_processing(chip, port);
+ lan9303_phy_write(ds, chip->phy_addr_sel_strap + port,
MII_BMCR, BMCR_PDOWN);
break;
default:
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v2 04/10] net: dsa: lan9303: Added adjust_link() method
From: Egil Hjelmeland @ 2017-07-25 16:15 UTC (permalink / raw)
To: corbet, andrew, vivien.didelot, f.fainelli, davem, kernel,
linux-doc, linux-kernel, netdev
Cc: Egil Hjelmeland
In-Reply-To: <20170725161553.30147-1-privat@egil-hjelmeland.no>
This makes the driver react to device tree "fixed-link" declaration
on CPU port.
- turn off autonegotiation
- force speed 10 or 100 mb/s
- force duplex mode
Signed-off-by: Egil Hjelmeland <privat@egil-hjelmeland.no>
---
drivers/net/dsa/lan9303-core.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
index 0806a0684d55..be6d78f45a5f 100644
--- a/drivers/net/dsa/lan9303-core.c
+++ b/drivers/net/dsa/lan9303-core.c
@@ -17,6 +17,7 @@
#include <linux/regmap.h>
#include <linux/mutex.h>
#include <linux/mii.h>
+#include <linux/phy.h>
#include "lan9303.h"
@@ -746,6 +747,37 @@ static int lan9303_phy_write(struct dsa_switch *ds, int phy, int regnum,
return chip->ops->phy_write(chip, phy, regnum, val);
}
+static void lan9303_adjust_link(struct dsa_switch *ds, int port,
+ struct phy_device *phydev)
+{
+ struct lan9303 *chip = ds->priv;
+
+ int ctl, res;
+
+ ctl = lan9303_phy_read(ds, port, MII_BMCR);
+
+ if (!phy_is_pseudo_fixed_link(phydev))
+ return;
+
+ ctl &= ~BMCR_ANENABLE;
+ if (phydev->speed == SPEED_100)
+ ctl |= BMCR_SPEED100;
+
+ if (phydev->duplex == DUPLEX_FULL)
+ ctl |= BMCR_FULLDPLX;
+
+ res = lan9303_phy_write(ds, port, MII_BMCR, ctl);
+
+ if (port == chip->phy_addr_sel_strap) {
+ /* Virtual Phy: Remove Turbo 200Mbit mode */
+ lan9303_read(chip->regmap, LAN9303_VIRT_SPECIAL_CTRL, &ctl);
+
+ ctl &= ~(1 << 10); // TURBO BIT
+ res = regmap_write(chip->regmap,
+ LAN9303_VIRT_SPECIAL_CTRL, ctl);
+ }
+}
+
static int lan9303_port_enable(struct dsa_switch *ds, int port,
struct phy_device *phy)
{
@@ -789,6 +821,7 @@ static struct dsa_switch_ops lan9303_switch_ops = {
.get_strings = lan9303_get_strings,
.phy_read = lan9303_phy_read,
.phy_write = lan9303_phy_write,
+ .adjust_link = lan9303_adjust_link,
.get_ethtool_stats = lan9303_get_ethtool_stats,
.get_sset_count = lan9303_get_sset_count,
.port_enable = lan9303_port_enable,
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v2 05/10] net: dsa: added dsa_net_device_to_dsa_port()
From: Egil Hjelmeland @ 2017-07-25 16:15 UTC (permalink / raw)
To: corbet, andrew, vivien.didelot, f.fainelli, davem, kernel,
linux-doc, linux-kernel, netdev
Cc: Egil Hjelmeland
In-Reply-To: <20170725161553.30147-1-privat@egil-hjelmeland.no>
Allowing dsa drivers to attach sysfs nodes.
Signed-off-by: Egil Hjelmeland <privat@egil-hjelmeland.no>
---
include/net/dsa.h | 1 +
net/dsa/slave.c | 10 ++++++++++
2 files changed, 11 insertions(+)
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 88da272d20d0..a71c0a2401ee 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -450,6 +450,7 @@ void unregister_switch_driver(struct dsa_switch_driver *type);
struct mii_bus *dsa_host_dev_to_mii_bus(struct device *dev);
struct net_device *dsa_dev_to_net_device(struct device *dev);
+struct dsa_port *dsa_net_device_to_dsa_port(struct net_device *dev);
/* Keep inline for faster access in hot path */
static inline bool netdev_uses_dsa(struct net_device *dev)
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 9507bd38cf04..40410f1740de 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -209,6 +209,16 @@ static int dsa_slave_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return -EOPNOTSUPP;
}
+struct dsa_port *dsa_net_device_to_dsa_port(struct net_device *dev)
+{
+ struct dsa_slave_priv *p = netdev_priv(dev);
+
+ if (!dsa_slave_dev_check(dev))
+ return NULL;
+ return p->dp;
+}
+EXPORT_SYMBOL_GPL(dsa_net_device_to_dsa_port);
+
static int dsa_slave_port_attr_set(struct net_device *dev,
const struct switchdev_attr *attr,
struct switchdev_trans *trans)
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v2 06/10] net: dsa: lan9303: added sysfs node swe_bcst_throt
From: Egil Hjelmeland @ 2017-07-25 16:15 UTC (permalink / raw)
To: corbet, andrew, vivien.didelot, f.fainelli, davem, kernel,
linux-doc, linux-kernel, netdev
Cc: Egil Hjelmeland
In-Reply-To: <20170725161553.30147-1-privat@egil-hjelmeland.no>
Allowing per-port access to Switch Engine Broadcast Throttling Register
Also added lan9303_write_switch_reg_mask()
Signed-off-by: Egil Hjelmeland <privat@egil-hjelmeland.no>
---
drivers/net/dsa/lan9303-core.c | 83 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 83 insertions(+)
diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
index be6d78f45a5f..b70acb73aad6 100644
--- a/drivers/net/dsa/lan9303-core.c
+++ b/drivers/net/dsa/lan9303-core.c
@@ -154,6 +154,7 @@
# define LAN9303_SWE_PORT_MIRROR_ENABLE_RX_MIRRORING BIT(1)
# define LAN9303_SWE_PORT_MIRROR_ENABLE_TX_MIRRORING BIT(0)
#define LAN9303_SWE_INGRESS_PORT_TYPE 0x1847
+#define LAN9303_SWE_BCST_THROT 0x1848
#define LAN9303_BM_CFG 0x1c00
#define LAN9303_BM_EGRSS_PORT_TYPE 0x1c0c
# define LAN9303_BM_EGRSS_PORT_TYPE_SPECIAL_TAG_PORT2 (BIT(17) | BIT(16))
@@ -426,6 +427,20 @@ static int lan9303_read_switch_reg(struct lan9303 *chip, u16 regnum, u32 *val)
return ret;
}
+static int lan9303_write_switch_reg_mask(
+ struct lan9303 *chip, u16 regnum, u32 val, u32 mask)
+{
+ int ret;
+ u32 reg;
+
+ ret = lan9303_read_switch_reg(chip, regnum, ®);
+ if (ret)
+ return ret;
+ reg = (reg & ~mask) | val;
+
+ return lan9303_write_switch_reg(chip, regnum, reg);
+}
+
static int lan9303_detect_phy_setup(struct lan9303 *chip)
{
int reg;
@@ -614,6 +629,66 @@ static int lan9303_check_device(struct lan9303 *chip)
return 0;
}
+/* ---------------------- Sysfs on slave port --------------------------*/
+/*13.4.3.23 Switch Engine Broadcast Throttling Register (SWE_BCST_THROT)*/
+static ssize_t
+swe_bcst_throt_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct dsa_port *dp = dsa_net_device_to_dsa_port(to_net_dev(dev));
+ struct lan9303 *chip = dp->ds->priv;
+ int port = dp->index;
+ int reg;
+
+ if (lan9303_read_switch_reg(chip, LAN9303_SWE_BCST_THROT, ®))
+ return 0;
+
+ reg = (reg >> (9 * port)) & 0x1ff; /*extract port N*/
+ if (reg & 0x100)
+ reg &= 0xff; /* remove enable bit */
+ else
+ reg = 0; /* not enabled*/
+
+ return scnprintf(buf, PAGE_SIZE, "%d\n", reg);
+}
+
+static ssize_t
+swe_bcst_throt_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t len)
+{
+ struct dsa_port *dp = dsa_net_device_to_dsa_port(to_net_dev(dev));
+ struct lan9303 *chip = dp->ds->priv;
+ int port = dp->index;
+ int ret;
+ unsigned long level;
+
+ ret = kstrtoul(buf, 0, &level);
+ if (ret)
+ return ret;
+ level &= 0xff; /* ensure valid range */
+ if (level)
+ level |= 0x100; /* Set enable bit */
+
+ ret = lan9303_write_switch_reg_mask(chip, LAN9303_SWE_BCST_THROT,
+ level << (9 * port),
+ 0x1ff << (9 * port));
+ if (ret)
+ return ret;
+ return len;
+}
+
+static DEVICE_ATTR_RW(swe_bcst_throt);
+
+static struct attribute *lan9303_attrs[] = {
+ &dev_attr_swe_bcst_throt.attr,
+ NULL
+};
+
+static struct attribute_group lan9303_group = {
+ .name = "lan9303",
+ .attrs = lan9303_attrs,
+};
+
/* ---------------------------- DSA -----------------------------------*/
static enum dsa_tag_protocol lan9303_get_tag_protocol(struct dsa_switch *ds)
@@ -787,6 +862,11 @@ static int lan9303_port_enable(struct dsa_switch *ds, int port,
switch (port) {
case 1:
case 2:
+ /* lan9303_setup is too early to attach sysfs nodes... */
+ if (sysfs_create_group(
+ &ds->ports[port].netdev->dev.kobj,
+ &lan9303_group))
+ dev_dbg(chip->dev, "cannot create sysfs group\n");
return lan9303_enable_packet_processing(chip, port);
default:
dev_dbg(chip->dev,
@@ -805,6 +885,9 @@ static void lan9303_port_disable(struct dsa_switch *ds, int port,
switch (port) {
case 1:
case 2:
+ sysfs_remove_group(&ds->ports[port].netdev->dev.kobj,
+ &lan9303_group);
+
lan9303_disable_packet_processing(chip, port);
lan9303_phy_write(ds, chip->phy_addr_sel_strap + port,
MII_BMCR, BMCR_PDOWN);
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v2 07/10] net: dsa: lan9303: Added basic offloading of unicast traffic
From: Egil Hjelmeland @ 2017-07-25 16:15 UTC (permalink / raw)
To: corbet, andrew, vivien.didelot, f.fainelli, davem, kernel,
linux-doc, linux-kernel, netdev
Cc: Egil Hjelmeland
In-Reply-To: <20170725161553.30147-1-privat@egil-hjelmeland.no>
When both user ports are joined to the same bridge, the normal
HW MAC learning is enabled. This means that unicast traffic is forwarded
in HW. Support for STP is also added.
If one of the user ports leave the bridge,
the ports goes back to the initial separated operation.
Added brigde methods port_bridge_join, port_bridge_leave and
port_stp_state_set.
Signed-off-by: Egil Hjelmeland <privat@egil-hjelmeland.no>
---
drivers/net/dsa/lan9303-core.c | 115 ++++++++++++++++++++++++++++++++++-------
drivers/net/dsa/lan9303.h | 1 +
2 files changed, 98 insertions(+), 18 deletions(-)
diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
index b70acb73aad6..426a75bd89f4 100644
--- a/drivers/net/dsa/lan9303-core.c
+++ b/drivers/net/dsa/lan9303-core.c
@@ -18,6 +18,7 @@
#include <linux/mutex.h>
#include <linux/mii.h>
#include <linux/phy.h>
+#include <linux/if_bridge.h>
#include "lan9303.h"
@@ -143,6 +144,7 @@
# define LAN9303_SWE_PORT_STATE_FORWARDING_PORT0 (0)
# define LAN9303_SWE_PORT_STATE_LEARNING_PORT0 BIT(1)
# define LAN9303_SWE_PORT_STATE_BLOCKING_PORT0 BIT(0)
+# define LAN9303_SWE_PORT_STATE_DISABLED_PORT0 (3)
#define LAN9303_SWE_PORT_MIRROR 0x1846
# define LAN9303_SWE_PORT_MIRROR_SNIFF_ALL BIT(8)
# define LAN9303_SWE_PORT_MIRROR_SNIFFER_PORT2 BIT(7)
@@ -515,11 +517,30 @@ static int lan9303_enable_packet_processing(struct lan9303 *chip,
LAN9303_MAC_TX_CFG_X_TX_ENABLE);
}
+/* forward special tagged packets from port 0 to port 1 *or* port 2 */
+static int lan9303_setup_tagging(struct lan9303 *chip)
+{
+ int ret;
+ /* enable defining the destination port via special VLAN tagging
+ * for port 0
+ */
+ ret = lan9303_write_switch_reg(chip, LAN9303_SWE_INGRESS_PORT_TYPE,
+ 0x03);
+ if (ret)
+ return ret;
+
+ /* tag incoming packets at port 1 and 2 on their way to port 0 to be
+ * able to discover their source port
+ */
+ return lan9303_write_switch_reg(
+ chip, LAN9303_BM_EGRSS_PORT_TYPE,
+ LAN9303_BM_EGRSS_PORT_TYPE_SPECIAL_TAG_PORT0);
+}
+
/* We want a special working switch:
* - do not forward packets between port 1 and 2
* - forward everything from port 1 to port 0
* - forward everything from port 2 to port 0
- * - forward special tagged packets from port 0 to port 1 *or* port 2
*/
static int lan9303_separate_ports(struct lan9303 *chip)
{
@@ -534,22 +555,6 @@ static int lan9303_separate_ports(struct lan9303 *chip)
if (ret)
return ret;
- /* enable defining the destination port via special VLAN tagging
- * for port 0
- */
- ret = lan9303_write_switch_reg(chip, LAN9303_SWE_INGRESS_PORT_TYPE,
- 0x03);
- if (ret)
- return ret;
-
- /* tag incoming packets at port 1 and 2 on their way to port 0 to be
- * able to discover their source port
- */
- ret = lan9303_write_switch_reg(chip, LAN9303_BM_EGRSS_PORT_TYPE,
- LAN9303_BM_EGRSS_PORT_TYPE_SPECIAL_TAG_PORT0);
- if (ret)
- return ret;
-
/* prevent port 1 and 2 from forwarding packets by their own */
return lan9303_write_switch_reg(chip, LAN9303_SWE_PORT_STATE,
LAN9303_SWE_PORT_STATE_FORWARDING_PORT0 |
@@ -557,6 +562,12 @@ static int lan9303_separate_ports(struct lan9303 *chip)
LAN9303_SWE_PORT_STATE_BLOCKING_PORT2);
}
+static void lan9303_bridge_ports(struct lan9303 *chip)
+{
+ /* ports bridged: remove mirroring */
+ lan9303_write_switch_reg(chip, LAN9303_SWE_PORT_MIRROR, 0);
+}
+
static int lan9303_handle_reset(struct lan9303 *chip)
{
if (!chip->reset_gpio)
@@ -707,6 +718,10 @@ static int lan9303_setup(struct dsa_switch *ds)
return -EINVAL;
}
+ ret = lan9303_setup_tagging(chip);
+ if (ret)
+ dev_err(chip->dev, "failed to setup port tagging %d\n", ret);
+
ret = lan9303_separate_ports(chip);
if (ret)
dev_err(chip->dev, "failed to separate ports %d\n", ret);
@@ -898,17 +913,81 @@ static void lan9303_port_disable(struct dsa_switch *ds, int port,
}
}
+static int lan9303_port_bridge_join(struct dsa_switch *ds, int port,
+ struct net_device *br)
+{
+ struct lan9303 *chip = ds->priv;
+
+ dev_dbg(chip->dev, "%s(port %d)\n", __func__, port);
+ if (ds->ports[1].bridge_dev == ds->ports[2].bridge_dev) {
+ lan9303_bridge_ports(chip);
+ chip->is_bridged = true; /* unleash stp_state_set() */
+ }
+
+ return 0;
+}
+
+static void lan9303_port_bridge_leave(struct dsa_switch *ds, int port,
+ struct net_device *br)
+{
+ struct lan9303 *chip = ds->priv;
+
+ dev_dbg(chip->dev, "%s(port %d)\n", __func__, port);
+ if (chip->is_bridged) {
+ lan9303_separate_ports(chip);
+ chip->is_bridged = false;
+ }
+}
+
+static void lan9303_port_stp_state_set(struct dsa_switch *ds, int port,
+ u8 state)
+{
+ int portmask, portstate;
+ struct lan9303 *chip = ds->priv;
+
+ dev_dbg(chip->dev, "%s(port %d, state %d)\n",
+ __func__, port, state);
+ if (!chip->is_bridged)
+ return;
+
+ switch (state) {
+ case BR_STATE_DISABLED:
+ portstate = LAN9303_SWE_PORT_STATE_DISABLED_PORT0;
+ break;
+ case BR_STATE_BLOCKING:
+ case BR_STATE_LISTENING:
+ portstate = LAN9303_SWE_PORT_STATE_BLOCKING_PORT0;
+ break;
+ case BR_STATE_LEARNING:
+ portstate = LAN9303_SWE_PORT_STATE_LEARNING_PORT0;
+ break;
+ case BR_STATE_FORWARDING:
+ portstate = LAN9303_SWE_PORT_STATE_FORWARDING_PORT0;
+ break;
+ default:
+ dev_err(chip->dev, "%s(port %d, state %d)\n",
+ __func__, port, state);
+ }
+ portmask = 0x3 << (port * 2);
+ portstate <<= (port * 2);
+ lan9303_write_switch_reg_mask(chip, LAN9303_SWE_PORT_STATE,
+ portstate, portmask);
+}
+
static struct dsa_switch_ops lan9303_switch_ops = {
.get_tag_protocol = lan9303_get_tag_protocol,
.setup = lan9303_setup,
- .get_strings = lan9303_get_strings,
.phy_read = lan9303_phy_read,
.phy_write = lan9303_phy_write,
.adjust_link = lan9303_adjust_link,
+ .get_strings = lan9303_get_strings,
.get_ethtool_stats = lan9303_get_ethtool_stats,
.get_sset_count = lan9303_get_sset_count,
.port_enable = lan9303_port_enable,
.port_disable = lan9303_port_disable,
+ .port_bridge_join = lan9303_port_bridge_join,
+ .port_bridge_leave = lan9303_port_bridge_leave,
+ .port_stp_state_set = lan9303_port_stp_state_set,
};
static int lan9303_register_switch(struct lan9303 *chip)
diff --git a/drivers/net/dsa/lan9303.h b/drivers/net/dsa/lan9303.h
index 444d00b460e1..2d74d02c9cef 100644
--- a/drivers/net/dsa/lan9303.h
+++ b/drivers/net/dsa/lan9303.h
@@ -21,6 +21,7 @@ struct lan9303 {
struct dsa_switch *ds;
struct mutex indirect_mutex; /* protect indexed register access */
const struct lan9303_phy_ops *ops;
+ bool is_bridged; /* true if port 1 and 2 is bridged */
};
extern const struct regmap_access_table lan9303_register_set;
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v2 08/10] net: dsa: lan9303: Added ALR/fdb/mdb handling
From: Egil Hjelmeland @ 2017-07-25 16:15 UTC (permalink / raw)
To: corbet, andrew, vivien.didelot, f.fainelli, davem, kernel,
linux-doc, linux-kernel, netdev
Cc: Egil Hjelmeland
In-Reply-To: <20170725161553.30147-1-privat@egil-hjelmeland.no>
Added functions for accessing / managing the lan9303 ALR (Address Logic
Resolution).
Implemented DSA methods: set_addr, port_fast_age, port_fdb_prepare,
port_fdb_add, port_fdb_del, port_fdb_dump, port_mdb_prepare,
port_mdb_add and port_mdb_del.
Since the lan9303 do not offer reading specific ALR entry, the driver
caches all static entries - in a flat table.
Signed-off-by: Egil Hjelmeland <privat@egil-hjelmeland.no>
---
drivers/net/dsa/lan9303-core.c | 369 +++++++++++++++++++++++++++++++++++++++++
drivers/net/dsa/lan9303.h | 11 ++
2 files changed, 380 insertions(+)
diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
index 426a75bd89f4..dc95973d62ed 100644
--- a/drivers/net/dsa/lan9303-core.c
+++ b/drivers/net/dsa/lan9303-core.c
@@ -19,6 +19,7 @@
#include <linux/mii.h>
#include <linux/phy.h>
#include <linux/if_bridge.h>
+#include <linux/etherdevice.h>
#include "lan9303.h"
@@ -121,6 +122,21 @@
#define LAN9303_MAC_RX_CFG_2 0x0c01
#define LAN9303_MAC_TX_CFG_2 0x0c40
#define LAN9303_SWE_ALR_CMD 0x1800
+# define ALR_CMD_MAKE_ENTRY BIT(2)
+# define ALR_CMD_GET_FIRST BIT(1)
+# define ALR_CMD_GET_NEXT BIT(0)
+#define LAN9303_SWE_ALR_WR_DAT_0 0x1801
+#define LAN9303_SWE_ALR_WR_DAT_1 0x1802
+# define ALR_DAT1_VALID BIT(26)
+# define ALR_DAT1_END_OF_TABL BIT(25)
+# define ALR_DAT1_AGE_OVERRID BIT(25)
+# define ALR_DAT1_STATIC BIT(24)
+# define ALR_DAT1_PORT_BITOFFS 16
+# define ALR_DAT1_PORT_MASK (7 << ALR_DAT1_PORT_BITOFFS)
+#define LAN9303_SWE_ALR_RD_DAT_0 0x1805
+#define LAN9303_SWE_ALR_RD_DAT_1 0x1806
+#define LAN9303_SWE_ALR_CMD_STS 0x1808
+# define ALR_STS_MAKE_PEND BIT(0)
#define LAN9303_SWE_VLAN_CMD 0x180b
# define LAN9303_SWE_VLAN_CMD_RNW BIT(5)
# define LAN9303_SWE_VLAN_CMD_PVIDNVLAN BIT(4)
@@ -473,6 +489,229 @@ static int lan9303_detect_phy_setup(struct lan9303 *chip)
return 0;
}
+/* ----------------- Address Logic Resolution (ALR)------------------*/
+
+/* Map ALR-port bits to port bitmap, and back*/
+static const int alrport_2_portmap[] = {1, 2, 4, 0, 3, 5, 6, 7 };
+static const int portmap_2_alrport[] = {3, 0, 1, 4, 2, 5, 6, 7 };
+
+/* ALR: Cache static entries: mac address + port bitmap */
+
+/* Return pointer to first free ALR cache entry, return NULL if none */
+static struct lan9303_alr_cache_entry *lan9303_alr_cache_find_free(
+ struct lan9303 *chip)
+{
+ int i;
+ struct lan9303_alr_cache_entry *entr = chip->alr_cache;
+
+ for (i = 0; i < LAN9303_NUM_ALR_RECORDS; i++, entr++)
+ if (entr->port_map == 0)
+ return entr;
+ return NULL;
+}
+
+/* Return pointer to ALR cache entry matching MAC address */
+static struct lan9303_alr_cache_entry *lan9303_alr_cache_find_mac(
+ struct lan9303 *chip,
+ const u8 *mac_addr)
+{
+ int i;
+ struct lan9303_alr_cache_entry *entr = chip->alr_cache;
+
+ BUILD_BUG_ON_MSG(sizeof(struct lan9303_alr_cache_entry) & 1,
+ "ether_addr_equal require u16 alignment");
+
+ for (i = 0; i < LAN9303_NUM_ALR_RECORDS; i++, entr++)
+ if (ether_addr_equal(entr->mac_addr, mac_addr))
+ return entr;
+ return NULL;
+}
+
+/* ALR: Actual register access functions */
+
+/* This function will wait a while until mask & reg == value */
+/* Otherwise, return timeout */
+static int lan9303_csr_reg_wait(struct lan9303 *chip, int regno,
+ int mask, char value)
+{
+ int i;
+
+ for (i = 0; i < 0x1000; i++) {
+ u32 reg;
+
+ lan9303_read_switch_reg(chip, regno, ®);
+ if ((reg & mask) == value)
+ return 0;
+ }
+ return -ETIMEDOUT;
+}
+
+static int _lan9303_alr_make_entry_raw(struct lan9303 *chip, u32 dat0, u32 dat1)
+{
+ lan9303_write_switch_reg(
+ chip, LAN9303_SWE_ALR_WR_DAT_0, dat0);
+ lan9303_write_switch_reg(
+ chip, LAN9303_SWE_ALR_WR_DAT_1, dat1);
+ lan9303_write_switch_reg(
+ chip, LAN9303_SWE_ALR_CMD, ALR_CMD_MAKE_ENTRY);
+ lan9303_csr_reg_wait(
+ chip, LAN9303_SWE_ALR_CMD_STS, ALR_STS_MAKE_PEND, 0);
+ lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_CMD, 0);
+ return 0;
+}
+
+typedef void alr_loop_cb_t(
+ struct lan9303 *chip, u32 dat0, u32 dat1, int portmap, void *ctx);
+
+static void lan9303_alr_loop(struct lan9303 *chip, alr_loop_cb_t *cb, void *ctx)
+{
+ int i;
+
+ lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_CMD, ALR_CMD_GET_FIRST);
+ lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_CMD, 0);
+
+ for (i = 1; i < LAN9303_NUM_ALR_RECORDS; i++) {
+ u32 dat0, dat1;
+ int alrport, portmap;
+
+ lan9303_read_switch_reg(chip, LAN9303_SWE_ALR_RD_DAT_0, &dat0);
+ lan9303_read_switch_reg(chip, LAN9303_SWE_ALR_RD_DAT_1, &dat1);
+ if (dat1 & ALR_DAT1_END_OF_TABL)
+ break;
+
+ alrport = (dat1 & ALR_DAT1_PORT_MASK) >> ALR_DAT1_PORT_BITOFFS;
+ portmap = alrport_2_portmap[alrport];
+
+ cb(chip, dat0, dat1, portmap, ctx);
+
+ lan9303_write_switch_reg(
+ chip, LAN9303_SWE_ALR_CMD, ALR_CMD_GET_NEXT);
+ lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_CMD, 0);
+ }
+}
+
+/* ALR: lan9303_alr_loop callback functions */
+
+static void _alr_reg_to_mac(u32 dat0, u32 dat1, u8 mac[6])
+{
+ mac[0] = (dat0 >> 0) & 0xff;
+ mac[1] = (dat0 >> 8) & 0xff;
+ mac[2] = (dat0 >> 16) & 0xff;
+ mac[3] = (dat0 >> 24) & 0xff;
+ mac[4] = (dat1 >> 0) & 0xff;
+ mac[5] = (dat1 >> 8) & 0xff;
+}
+
+/* Clear learned (non-static) entry on given port */
+static void alr_loop_cb_del_port_learned(
+ struct lan9303 *chip, u32 dat0, u32 dat1, int portmap, void *ctx)
+{
+ int *port = ctx;
+
+ if (((BIT(*port) & portmap) == 0) || (dat1 & ALR_DAT1_STATIC))
+ return;
+
+ /* learned entries has only one port, we can just delete */
+ dat1 &= ~ALR_DAT1_VALID; /* delete entry */
+ _lan9303_alr_make_entry_raw(chip, dat0, dat1);
+}
+
+struct port_fdb_dump_ctx {
+ int port;
+ struct switchdev_obj_port_fdb *fdb;
+ switchdev_obj_dump_cb_t *cb;
+};
+
+static void alr_loop_cb_fdb_port_dump(
+ struct lan9303 *chip, u32 dat0, u32 dat1, int portmap, void *ctx)
+{
+ struct port_fdb_dump_ctx *dump_ctx = ctx;
+ struct switchdev_obj_port_fdb *fdb = dump_ctx->fdb;
+ u8 mac[ETH_ALEN];
+
+ if ((BIT(dump_ctx->port) & portmap) == 0)
+ return;
+
+ _alr_reg_to_mac(dat0, dat1, mac);
+ ether_addr_copy(fdb->addr, mac);
+ fdb->vid = 0;
+ fdb->ndm_state = (dat1 & ALR_DAT1_STATIC) ?
+ NUD_NOARP : NUD_REACHABLE;
+ dump_ctx->cb(&fdb->obj);
+}
+
+/* ALR: Add/modify/delete ALR entries */
+
+/* Set a static ALR entry. Delete entry if port_map is zero */
+static void _lan9303_alr_set_entry(struct lan9303 *chip, const u8 *mac,
+ u8 port_map, bool stp_override)
+{
+ u32 dat0, dat1, alr_port;
+
+ dat1 = ALR_DAT1_STATIC;
+ if (port_map)
+ dat1 |= ALR_DAT1_VALID; /* otherwise no ports: delete entry */
+ if (stp_override)
+ dat1 |= ALR_DAT1_AGE_OVERRID;
+
+ alr_port = portmap_2_alrport[port_map & 7];
+ dat1 &= ~ALR_DAT1_PORT_MASK;
+ dat1 |= alr_port << ALR_DAT1_PORT_BITOFFS;
+
+ dat0 = 0;
+ dat0 |= (mac[0] << 0);
+ dat0 |= (mac[1] << 8);
+ dat0 |= (mac[2] << 16);
+ dat0 |= (mac[3] << 24);
+
+ dat1 |= (mac[4] << 0);
+ dat1 |= (mac[5] << 8);
+
+ dev_dbg(chip->dev, "%s %pM %d %08x %08x\n",
+ __func__, mac, port_map, dat0, dat1);
+ _lan9303_alr_make_entry_raw(chip, dat0, dat1);
+}
+
+/* Add port to static ALR entry, create new static entry if needed */
+static int lan9303_alr_add_port(struct lan9303 *chip, const u8 *mac,
+ int port, bool stp_override)
+{
+ struct lan9303_alr_cache_entry *entr = lan9303_alr_cache_find_mac(
+ chip, mac);
+
+ if (!entr) { /*New entry */
+ entr = lan9303_alr_cache_find_free(chip);
+ if (!entr)
+ return -ENOSPC;
+ ether_addr_copy(entr->mac_addr, mac);
+ }
+ entr->port_map |= BIT(port);
+ entr->stp_override = stp_override;
+ _lan9303_alr_set_entry(chip, mac, entr->port_map, stp_override);
+ return 0;
+}
+
+/* Delete static port from ALR entry, delete entry if last port */
+static int lan9303_alr_del_port(struct lan9303 *chip, const u8 *mac,
+ int port)
+{
+ struct lan9303_alr_cache_entry *entr = lan9303_alr_cache_find_mac(
+ chip, mac);
+
+ if (!entr) { /* no static entry found */
+ /* Should we delete any learned entry?
+ * _lan9303_alr_set_entry(chip, mac, 0, false);
+ */
+ return 0;
+ }
+ entr->port_map &= ~BIT(port); /* zero means its free again */
+ if (entr->port_map == 0)
+ eth_zero_addr(&entr->port_map);
+ _lan9303_alr_set_entry(chip, mac, entr->port_map, entr->stp_override);
+ return 0;
+}
+
+/* --------------------- Various chip setup ----------------------*/
static int lan9303_disable_packet_processing(struct lan9303 *chip,
unsigned int port)
{
@@ -729,6 +968,14 @@ static int lan9303_setup(struct dsa_switch *ds)
return 0;
}
+static int lan9303_set_addr(struct dsa_switch *ds, u8 *addr)
+{
+ struct lan9303 *chip = ds->priv;
+
+ lan9303_alr_add_port(chip, addr, 0, false);
+ return 0;
+}
+
struct lan9303_mib_desc {
unsigned int offset; /* offset of first MAC */
const char *name;
@@ -974,9 +1221,123 @@ static void lan9303_port_stp_state_set(struct dsa_switch *ds, int port,
portstate, portmask);
}
+static void lan9303_port_fast_age(struct dsa_switch *ds, int port)
+{
+ struct lan9303 *chip = ds->priv;
+
+ dev_dbg(chip->dev, "%s(%d)\n", __func__, port);
+ lan9303_alr_loop(chip, alr_loop_cb_del_port_learned, &port);
+}
+
+static int _lan9303_port_fdb_check(
+ struct lan9303 *chip, const u8 *mac, int vid)
+{
+ if (vid)
+ return -EOPNOTSUPP;
+ if (lan9303_alr_cache_find_mac(chip, mac))
+ return 0;
+ if (!lan9303_alr_cache_find_free(chip))
+ return -ENOSPC;
+ return 0;
+}
+
+static int lan9303_port_fdb_prepare(
+ struct dsa_switch *ds, int port,
+ const struct switchdev_obj_port_fdb *fdb,
+ struct switchdev_trans *trans)
+{
+ struct lan9303 *chip = ds->priv;
+
+ dev_dbg(chip->dev, "%s(port %d, vid %d, %pM)\n",
+ __func__, port, fdb->vid, fdb->addr);
+ return _lan9303_port_fdb_check(chip, fdb->addr, fdb->vid);
+}
+
+static void lan9303_port_fdb_add(
+ struct dsa_switch *ds, int port,
+ const struct switchdev_obj_port_fdb *fdb,
+ struct switchdev_trans *trans)
+{
+ struct lan9303 *chip = ds->priv;
+
+ dev_dbg(chip->dev, "%s(port %d, vid %d, %pM)\n",
+ __func__, port, fdb->vid, fdb->addr);
+ lan9303_alr_add_port(chip, fdb->addr, port, false);
+}
+
+static int lan9303_port_fdb_del(
+ struct dsa_switch *ds, int port,
+ const struct switchdev_obj_port_fdb *fdb)
+{
+ struct lan9303 *chip = ds->priv;
+
+ dev_dbg(chip->dev, "%s(port %d, vid %d, %pM)\n",
+ __func__, port, fdb->vid, fdb->addr);
+ if (fdb->vid)
+ return -EOPNOTSUPP;
+ lan9303_alr_del_port(chip, fdb->addr, port);
+ return 0;
+}
+
+static int lan9303_port_fdb_dump(
+ struct dsa_switch *ds, int port,
+ struct switchdev_obj_port_fdb *fdb,
+ switchdev_obj_dump_cb_t *cb)
+{
+ struct lan9303 *chip = ds->priv;
+ struct port_fdb_dump_ctx dump_ctx = {
+ .port = port,
+ .fdb = fdb,
+ .cb = cb,
+ };
+
+ dev_dbg(chip->dev, "%s(%d)\n", __func__, port);
+ lan9303_alr_loop(chip, alr_loop_cb_fdb_port_dump, &dump_ctx);
+ return 0;
+}
+
+static int lan9303_port_mdb_prepare(
+ struct dsa_switch *ds, int port,
+ const struct switchdev_obj_port_mdb *mdb,
+ struct switchdev_trans *trans)
+{
+ struct lan9303 *chip = ds->priv;
+
+ dev_dbg(chip->dev, "%s(port %d, vid %d, %pM)\n",
+ __func__, port, mdb->vid, mdb->addr);
+ return _lan9303_port_fdb_check(chip, mdb->addr, mdb->vid);
+}
+
+static void lan9303_port_mdb_add(
+ struct dsa_switch *ds, int port,
+ const struct switchdev_obj_port_mdb *mdb,
+ struct switchdev_trans *trans)
+{
+ struct lan9303 *chip = ds->priv;
+
+ dev_dbg(chip->dev, "%s(port %d, vid %d, %pM)\n",
+ __func__, port, mdb->vid, mdb->addr);
+ lan9303_alr_add_port(chip, mdb->addr, port, false);
+}
+
+static int lan9303_port_mdb_del(
+ struct dsa_switch *ds, int port,
+ const struct switchdev_obj_port_mdb *mdb)
+{
+ struct lan9303 *chip = ds->priv;
+
+ dev_dbg(chip->dev, "%s(port %d, vid %d, %pM)\n",
+ __func__, port, mdb->vid, mdb->addr);
+ if (mdb->vid)
+ return -EOPNOTSUPP;
+ lan9303_alr_del_port(chip, mdb->addr, port);
+ return 0;
+}
+
static struct dsa_switch_ops lan9303_switch_ops = {
.get_tag_protocol = lan9303_get_tag_protocol,
.setup = lan9303_setup,
+ .set_addr = lan9303_set_addr,
.phy_read = lan9303_phy_read,
.phy_write = lan9303_phy_write,
.adjust_link = lan9303_adjust_link,
@@ -988,6 +1349,14 @@ static struct dsa_switch_ops lan9303_switch_ops = {
.port_bridge_join = lan9303_port_bridge_join,
.port_bridge_leave = lan9303_port_bridge_leave,
.port_stp_state_set = lan9303_port_stp_state_set,
+ .port_fast_age = lan9303_port_fast_age,
+ .port_fdb_prepare = lan9303_port_fdb_prepare,
+ .port_fdb_add = lan9303_port_fdb_add,
+ .port_fdb_del = lan9303_port_fdb_del,
+ .port_fdb_dump = lan9303_port_fdb_dump,
+ .port_mdb_prepare = lan9303_port_mdb_prepare,
+ .port_mdb_add = lan9303_port_mdb_add,
+ .port_mdb_del = lan9303_port_mdb_del,
};
static int lan9303_register_switch(struct lan9303 *chip)
diff --git a/drivers/net/dsa/lan9303.h b/drivers/net/dsa/lan9303.h
index 2d74d02c9cef..f714addbf1e2 100644
--- a/drivers/net/dsa/lan9303.h
+++ b/drivers/net/dsa/lan9303.h
@@ -11,6 +11,13 @@ struct lan9303_phy_ops {
int regnum, u16 val);
};
+#define LAN9303_NUM_ALR_RECORDS 512
+struct lan9303_alr_cache_entry {
+ u8 mac_addr[ETH_ALEN];
+ u8 port_map; /* Bitmap of ports. Zero if unused entry */
+ u8 stp_override; /* non zero if set ALR_DAT1_AGE_OVERRID */
+};
+
struct lan9303 {
struct device *dev;
struct regmap *regmap;
@@ -22,6 +29,10 @@ struct lan9303 {
struct mutex indirect_mutex; /* protect indexed register access */
const struct lan9303_phy_ops *ops;
bool is_bridged; /* true if port 1 and 2 is bridged */
+ /* LAN9303 do not offer reading specific ALR entry. Cache all
+ * static entries in a flat table
+ **/
+ struct lan9303_alr_cache_entry alr_cache[LAN9303_NUM_ALR_RECORDS];
};
extern const struct regmap_access_table lan9303_register_set;
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v2 09/10] net: dsa: lan9303: Added Documentation/networking/dsa/lan9303.txt
From: Egil Hjelmeland @ 2017-07-25 16:15 UTC (permalink / raw)
To: corbet, andrew, vivien.didelot, f.fainelli, davem, kernel,
linux-doc, linux-kernel, netdev
Cc: Egil Hjelmeland
In-Reply-To: <20170725161553.30147-1-privat@egil-hjelmeland.no>
Signed-off-by: Egil Hjelmeland <privat@egil-hjelmeland.no>
---
Documentation/networking/dsa/lan9303.txt | 63 ++++++++++++++++++++++++++++++++
1 file changed, 63 insertions(+)
create mode 100644 Documentation/networking/dsa/lan9303.txt
diff --git a/Documentation/networking/dsa/lan9303.txt b/Documentation/networking/dsa/lan9303.txt
new file mode 100644
index 000000000000..ef5b3ca12a29
--- /dev/null
+++ b/Documentation/networking/dsa/lan9303.txt
@@ -0,0 +1,63 @@
+LAN9303 Ethernet switch driver
+==============================
+
+The LAN9303 is a three port 10/100 ethernet switch with integrated phys
+for the two external ethernet ports. The third port is an RMII/MII
+interface to a host master network interface (e.g. fixed link).
+
+
+Driver details
+==============
+
+The driver is implemented as a DSA driver, see
+Documentation/networking/dsa/dsa.txt.
+
+See Documentation/devicetree/bindings/net/dsa/lan9303.txt for device
+tree binding.
+
+The LAN9303 can be managed both via MDIO and I2C, both supported by this
+driver.
+
+At startup the driver configures the device to provide two separate
+network interfaces (which is the default state of a DSA device).
+
+When both user ports are joined to the same bridge, the normal
+HW MAC learning is enabled. This means that unicast traffic is forwarded
+in HW. STP is also supported in this mode.
+
+If one of the user ports leave the bridge,
+the ports goes back to the initial separated operation.
+
+The driver implements the port_fdb_xxx/port_mdb_xxx methods.
+
+
+Sysfs nodes
+===========
+
+When a user port is enabled, the driver creates sysfs directory
+/sys/class/net/xxx/lan9303 with the following files:
+
+ - swe_bcst_throt (RW): Set/get 6.4.7 Broadcast Storm Control
+ Throttle Level for the port. Accesses the corresponding bits of
+ the SWE_BCST_THROT register (13.4.3.23).
+
+
+Driver limitations
+==================
+
+ - No support for VLAN
+
+
+Bridging notes
+==============
+When the user ports are bridged, broadcasts, multicasts and unknown
+frames with unknown destination are flooded by the chip. Therefore SW
+flooding must be disabled by:
+
+ echo 0 > /sys/class/net/p1/brport/broadcast_flood
+ echo 0 > /sys/class/net/p1/brport/multicast_flood
+ echo 0 > /sys/class/net/p1/brport/unicast_flood
+ echo 0 > /sys/class/net/p2/brport/broadcast_flood
+ echo 0 > /sys/class/net/p2/brport/multicast_flood
+ echo 0 > /sys/class/net/p2/brport/unicast_flood
+
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v2 10/10] net: dsa: lan9303: Only allocate 3 ports
From: Egil Hjelmeland @ 2017-07-25 16:15 UTC (permalink / raw)
To: corbet, andrew, vivien.didelot, f.fainelli, davem, kernel,
linux-doc, linux-kernel, netdev
Cc: Egil Hjelmeland
In-Reply-To: <20170725161553.30147-1-privat@egil-hjelmeland.no>
Saving 2628 bytes.
Signed-off-by: Egil Hjelmeland <privat@egil-hjelmeland.no>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/dsa/lan9303-core.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
index dc95973d62ed..ad7a4c72e1fb 100644
--- a/drivers/net/dsa/lan9303-core.c
+++ b/drivers/net/dsa/lan9303-core.c
@@ -23,6 +23,8 @@
#include "lan9303.h"
+#define LAN9303_NUM_PORTS 3
+
/* 13.2 System Control and Status Registers
* Multiply register number by 4 to get address offset.
*/
@@ -1361,7 +1363,7 @@ static struct dsa_switch_ops lan9303_switch_ops = {
static int lan9303_register_switch(struct lan9303 *chip)
{
- chip->ds = dsa_switch_alloc(chip->dev, DSA_MAX_PORTS);
+ chip->ds = dsa_switch_alloc(chip->dev, LAN9303_NUM_PORTS);
if (!chip->ds)
return -ENOMEM;
--
2.11.0
^ permalink raw reply related
* Re: [PATCH v2 2/4] can: fixed-transceiver: Add documentation for CAN fixed transceiver bindings
From: Oliver Hartkopp @ 2017-07-25 16:32 UTC (permalink / raw)
To: Franklin S Cooper Jr, linux-kernel, devicetree, netdev, linux-can,
wg, mkl, robh+dt, quentin.schulz, dev.kurt, andrew,
sergei.shtylyov
In-Reply-To: <20170724230521.1436-3-fcooper@ti.com>
> + max-data-speed: a positive non 0 value that determines the max data rate
> + that can be used in CAN-FD mode. A value of -1 implies
> + CAN-FD is not supported by the transceiver.
> +
> +Examples:
(..)
> + fixed-transceiver {
> + max-data-speed = <(-1)>;
Looks ugly IMHO.
Why didn't you stay on '0' for 'not supported'??
Regards,
Oliver
^ permalink raw reply
* Re: [PATCH net-next 1/3] bnxt_en: include bnxt_vfr.c code under CONFIG_BNXT_SRIOV switch
From: Michael Chan @ 2017-07-25 16:34 UTC (permalink / raw)
To: Sathya Perla; +Cc: Netdev
In-Reply-To: <20170725104933.9633-1-sathya.perla@broadcom.com>
On Tue, Jul 25, 2017 at 3:49 AM, Sathya Perla <sathya.perla@broadcom.com> wrote:
> This fixes build error when CONFIG_BNXT_SRIOV is switched off:
>>> drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c:165:16: error: 'struct
>>> bnxt' has no member named 'sriov_lock'
>
> Reported-by: kbuild test robot <lkp@intel.com>
> Fixes: 4ab0c6a8ffd7 ("bnxt_en: add support to enable VF-representors")
> Signed-off-by: Sathya Perla <sathya.perla@broadcom.com>
> ---
> drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c
> index 83478e9..86850ae 100644
> --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c
> +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c
> @@ -16,6 +16,8 @@
> #include "bnxt.h"
> #include "bnxt_vfr.h"
>
> +#ifdef CONFIG_BNXT_SRIOV
> +
> #define CFA_HANDLE_INVALID 0xffff
> #define VF_IDX_INVALID 0xffff
>
> @@ -487,3 +489,5 @@ void bnxt_dl_unregister(struct bnxt *bp)
> devlink_unregister(dl);
> devlink_free(dl);
> }
> +
> +#endif /* CONFIG_BNXT_SRIOV */
This won't work. It will cause undefined symbols if CONFIG_BNXT_SRIOV
is not defined. I will fix everything up and resend all 3 patches.
^ permalink raw reply
* Re: [PATCH net-next 2/2] bnxt_en: define sriov_lock unconditionally
From: Michael Chan @ 2017-07-25 16:36 UTC (permalink / raw)
To: Arnd Bergmann
Cc: David S. Miller, Sathya Perla, Somnath Kotur, Deepak Khungar,
Netdev, open list
In-Reply-To: <20170725153046.44726-2-arnd@arndb.de>
On Tue, Jul 25, 2017 at 8:29 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> The sriov_lock is used to serialize the sriov code with the vfr code.
> However, when SRIOV is disabled, the lock is not there at all, leading
> to a build error:
>
> drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c: In function 'bnxt_dl_eswitch_mode_set':
> drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c:410:16: error: 'struct bnxt' has no member named 'sriov_lock'
>
> We can either provide the mutex in this configuration, too, or
> disable both SRIOV and VFR together. This implements the first
> approach, since it seems like a reasonable configuration for
> guest kernels to have, and the extra lock will be harmless when
> there is no contention.
>
> Fixes: 4ab0c6a8ffd7 ("bnxt_en: add support to enable VF-representors")
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Sathya already sent 3 patches to fix some of these issues. But I need
to rework one of his patch and resend.
Thanks.
^ permalink raw reply
* Re: [PATCH net-next] bpf: add helper capable of reading out instructions
From: Daniel Borkmann @ 2017-07-25 16:40 UTC (permalink / raw)
To: Jakub Kicinski, netdev; +Cc: alexei.starovoitov, oss-drivers, kafai
In-Reply-To: <20170724212236.21903-2-jakub.kicinski@netronome.com>
[ +Martin ]
On 07/24/2017 11:22 PM, Jakub Kicinski wrote:
> To read translated and jited instructions from the kernel,
> one has to set certain pointers of struct bpf_prog_info to
> pre-allocated user buffers. Unfortunately, the existing
> bpf_obj_get_info_by_fd() helper zeros struct bpf_prog_info
> before passing it to the kernel.
>
> Keeping the zeroing seems like a good idea in general, since
> kernel will check if the structure was zeroed. Add a new
> helper for those more advanced users who can be trusted to
> take care of zeroing themselves.
>
> Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
> ---
> I'm happy to change the name of the new function.
>
> tools/lib/bpf/bpf.c | 10 ++++++++--
> tools/lib/bpf/bpf.h | 2 ++
> 2 files changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
> index 412a7c82995a..2703fa282b65 100644
> --- a/tools/lib/bpf/bpf.c
> +++ b/tools/lib/bpf/bpf.c
> @@ -308,13 +308,12 @@ int bpf_map_get_fd_by_id(__u32 id)
> return sys_bpf(BPF_MAP_GET_FD_BY_ID, &attr, sizeof(attr));
> }
>
> -int bpf_obj_get_info_by_fd(int prog_fd, void *info, __u32 *info_len)
> +int __bpf_obj_get_info_by_fd(int prog_fd, void *info, __u32 *info_len)
> {
> union bpf_attr attr;
> int err;
>
> bzero(&attr, sizeof(attr));
> - bzero(info, *info_len);
Looks a bit unintentional to me, e.g. 95b9afd3987f ("bpf: Test for bpf
ID") did set up pointers in test_bpf_obj_id(), but later only checked
for the {jited,xlated}_prog_len.
Clearing out the pointers looks not to useful. Lets just push the need
for bzero() to call-sites in general in this case.
> attr.info.bpf_fd = prog_fd;
> attr.info.info_len = *info_len;
> attr.info.info = ptr_to_u64(info);
> @@ -325,3 +324,10 @@ int bpf_obj_get_info_by_fd(int prog_fd, void *info, __u32 *info_len)
>
> return err;
> }
> +
> +int bpf_obj_get_info_by_fd(int prog_fd, void *info, __u32 *info_len)
> +{
> + bzero(info, *info_len);
> +
> + return __bpf_obj_get_info_by_fd(prog_fd, info, info_len);
> +}
> diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
> index 418c86e69bcb..e44b423ac07e 100644
> --- a/tools/lib/bpf/bpf.h
> +++ b/tools/lib/bpf/bpf.h
> @@ -58,6 +58,8 @@ int bpf_prog_get_next_id(__u32 start_id, __u32 *next_id);
> int bpf_map_get_next_id(__u32 start_id, __u32 *next_id);
> int bpf_prog_get_fd_by_id(__u32 id);
> int bpf_map_get_fd_by_id(__u32 id);
> +/* Note: bpf_obj_get_info_by_fd() will init info to zeroes */
> int bpf_obj_get_info_by_fd(int prog_fd, void *info, __u32 *info_len);
> +int __bpf_obj_get_info_by_fd(int prog_fd, void *info, __u32 *info_len);
>
> #endif
>
^ permalink raw reply
* [Patch net] bonding: commit link status change after propose
From: Cong Wang @ 2017-07-25 16:44 UTC (permalink / raw)
To: netdev; +Cc: benjamin.gilbert, Cong Wang, Mahesh Bandewar
Commit de77ecd4ef02 ("bonding: improve link-status update in mii-monitoring")
moves link status commitment into bond_mii_monitor(), but it still relies
on the return value of bond_miimon_inspect() as the hint. We need to return
non-zero as long as we propose a link status change.
Fixes: de77ecd4ef02 ("bonding: improve link-status update in mii-monitoring")
Reported-by: Benjamin Gilbert <benjamin.gilbert@coreos.com>
Tested-by: Benjamin Gilbert <benjamin.gilbert@coreos.com>
Cc: Mahesh Bandewar <maheshb@google.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
drivers/net/bonding/bond_main.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 181839d6fbea..9bee6c1c70cc 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2050,6 +2050,7 @@ static int bond_miimon_inspect(struct bonding *bond)
continue;
bond_propose_link_state(slave, BOND_LINK_FAIL);
+ commit++;
slave->delay = bond->params.downdelay;
if (slave->delay) {
netdev_info(bond->dev, "link status down for %sinterface %s, disabling it in %d ms\n",
@@ -2088,6 +2089,7 @@ static int bond_miimon_inspect(struct bonding *bond)
continue;
bond_propose_link_state(slave, BOND_LINK_BACK);
+ commit++;
slave->delay = bond->params.updelay;
if (slave->delay) {
--
2.13.0
^ permalink raw reply related
* Re: [PATCH net-next] bpf: install libbpf headers on 'make install'
From: Daniel Borkmann @ 2017-07-25 16:51 UTC (permalink / raw)
To: Jakub Kicinski, netdev; +Cc: alexei.starovoitov, oss-drivers
In-Reply-To: <20170724212236.21903-1-jakub.kicinski@netronome.com>
On 07/24/2017 11:22 PM, Jakub Kicinski wrote:
> Install the bpf.h header to $(prefix)/include/bpf/ directory.
> This is necessary to build standalone applications using libbpf,
> without the need to clone the kernel sources and point to them.
>
> Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
> ---
> I'm not 100% sure if it's OK to export the header file and which
> directory it should end up in (bpf/? libbpf/?).
Given the Makefile is heavily derived from tools/lib/traceevent/,
we should probably have a similar install_headers target instead,
in order to keep semantics similar. /include/bpf/ should be good.
> tools/lib/bpf/Makefile | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile
> index 1f5300e56b44..22dad416e0bd 100644
> --- a/tools/lib/bpf/Makefile
> +++ b/tools/lib/bpf/Makefile
> @@ -46,6 +46,7 @@ else
> endif
>
> prefix ?= /usr/local
> +headerdir = $(prefix)/include/bpf/
> libdir = $(prefix)/$(libdir_relative)
> man_dir = $(prefix)/share/man
> man_dir_SQ = '$(subst ','\'',$(man_dir))'
> @@ -90,11 +91,13 @@ endif
> export prefix libdir src obj
>
> # Shell quotes
> +headerdir_SQ = $(subst ','\'',$(headerdir))
> libdir_SQ = $(subst ','\'',$(libdir))
> libdir_relative_SQ = $(subst ','\'',$(libdir_relative))
> plugin_dir_SQ = $(subst ','\'',$(plugin_dir))
>
> LIB_FILE = libbpf.a libbpf.so
> +HEADER_FILE = bpf.h
>
> VERSION = $(BPF_VERSION)
> PATCHLEVEL = $(BPF_PATCHLEVEL)
> @@ -189,7 +192,11 @@ install_lib: all_cmd
> $(call QUIET_INSTALL, $(LIB_FILE)) \
> $(call do_install,$(LIB_FILE),$(libdir_SQ))
>
> -install: install_lib
> +install_hdr: all_cmd
> + $(call QUIET_INSTALL, $(HEADER_FILE)) \
> + $(call do_install,$(HEADER_FILE),$(headerdir_SQ))
> +
> +install: install_lib install_hdr
>
> ### Cleaning rules
>
>
^ permalink raw reply
* Re: ARM GLX Khadas VIM Pro - Ethernet detected as only 10Mbps and stalled after some traffic
From: crow @ 2017-07-25 16:56 UTC (permalink / raw)
To: Andrew Lunn; +Cc: netdev, open list:ARM/Amlogic Meson...
In-Reply-To: <CAG_g8w4MXgP2P3NcEZAi2zu8Diazirjbf=e4+r17vOE=kwXFSA@mail.gmail.com>
Hi,
Today I did test on ArchLinuxArm the Kernel v4.13-rc2. On downloading
the linux git source the network will eventually get stalled. Here are
the information
Over SSH (network works).
[root@alarm ~]# uname -a
Linux alarm 4.13.0-rc2-1-ARCH #1 SMP Mon Jul 24 20:02:50 MDT 2017
aarch64 GNU/Linux
[root@alarm ~]# mii-tool -vvv eth0
Using SIOCGMIIPHY=0x8947
eth0: negotiated 1000baseT-HD flow-control, link ok
registers for MII PHY 8:
1000 782d 0181 4400 01e1 c1e1 000f 2001
ffff ffff ffff ffff ffff ffff ffff ffff
0040 0002 40e8 5400 1c1c 0000 0000 aaaa
fff0 ffff 0000 000a 1407 004a 0000 105a
product info: vendor 00:60:51, model 0 rev 0
basic mode: autonegotiation enabled
basic status: autonegotiation complete, link ok
capabilities: 1000baseT-HD 1000baseT-FD 100baseTx-FD 100baseTx-HD
10baseT-FD 10baseT-HD
advertising: 1000baseT-HD 1000baseT-FD 100baseTx-FD 100baseTx-HD
10baseT-FD 10baseT-HD
link partner: 1000baseT-HD 1000baseT-FD 100baseTx-FD 100baseTx-HD
10baseT-FD 10baseT-HD
[root@alarm ~]# ethtool -S eth0
NIC statistics:
mmc_tx_octetcount_gb: 0
mmc_tx_framecount_gb: 0
mmc_tx_broadcastframe_g: 0
mmc_tx_multicastframe_g: 0
mmc_tx_64_octets_gb: 0
mmc_tx_65_to_127_octets_gb: 0
mmc_tx_128_to_255_octets_gb: 0
mmc_tx_256_to_511_octets_gb: 0
mmc_tx_512_to_1023_octets_gb: 0
mmc_tx_1024_to_max_octets_gb: 0
mmc_tx_unicast_gb: 0
mmc_tx_multicast_gb: 0
mmc_tx_broadcast_gb: 0
mmc_tx_underflow_error: 0
mmc_tx_singlecol_g: 0
mmc_tx_multicol_g: 0
mmc_tx_deferred: 0
mmc_tx_latecol: 0
mmc_tx_exesscol: 0
mmc_tx_carrier_error: 0
mmc_tx_octetcount_g: 0
mmc_tx_framecount_g: 0
mmc_tx_excessdef: 0
mmc_tx_pause_frame: 0
mmc_tx_vlan_frame_g: 0
mmc_rx_framecount_gb: 133
mmc_rx_octetcount_gb: 16646
mmc_rx_octetcount_g: 16646
mmc_rx_broadcastframe_g: 9
mmc_rx_multicastframe_g: 22
mmc_rx_crc_error: 0
mmc_rx_align_error: 0
mmc_rx_run_error: 0
mmc_rx_jabber_error: 0
mmc_rx_undersize_g: 0
mmc_rx_oversize_g: 0
mmc_rx_64_octets_gb: 45
mmc_rx_65_to_127_octets_gb: 64
mmc_rx_128_to_255_octets_gb: 13
mmc_rx_256_to_511_octets_gb: 7
mmc_rx_512_to_1023_octets_gb: 4
mmc_rx_1024_to_max_octets_gb: 0
mmc_rx_unicast_g: 102
mmc_rx_length_error: 0
mmc_rx_autofrangetype: 0
mmc_rx_pause_frames: 0
mmc_rx_fifo_overflow: 0
mmc_rx_vlan_frames_gb: 0
mmc_rx_watchdog_error: 0
mmc_rx_ipc_intr_mask: 1073692671
mmc_rx_ipc_intr: 0
mmc_rx_ipv4_gd: 117
mmc_rx_ipv4_hderr: 0
mmc_rx_ipv4_nopay: 0
mmc_rx_ipv4_frag: 0
mmc_rx_ipv4_udsbl: 0
mmc_rx_ipv4_gd_octets: 12585
mmc_rx_ipv4_hderr_octets: 0
mmc_rx_ipv4_nopay_octets: 0
mmc_rx_ipv4_frag_octets: 0
mmc_rx_ipv4_udsbl_octets: 0
mmc_rx_ipv6_gd_octets: 104
mmc_rx_ipv6_hderr_octets: 0
mmc_rx_ipv6_nopay_octets: 0
mmc_rx_ipv6_gd: 1
mmc_rx_ipv6_hderr: 0
mmc_rx_ipv6_nopay: 0
mmc_rx_udp_gd: 31
mmc_rx_udp_err: 0
mmc_rx_tcp_gd: 85
mmc_rx_tcp_err: 0
mmc_rx_icmp_gd: 2
mmc_rx_icmp_err: 0
mmc_rx_udp_gd_octets: 2963
mmc_rx_udp_err_octets: 0
mmc_rx_tcp_gd_octets: 7254
mmc_rx_tcp_err_octets: 0
mmc_rx_icmp_gd_octets: 92
mmc_rx_icmp_err_octets: 0
tx_underflow: 0
tx_carrier: 0
tx_losscarrier: 0
vlan_tag: 0
tx_deferred: 0
tx_vlan: 0
tx_jabber: 0
tx_frame_flushed: 0
tx_payload_error: 0
tx_ip_header_error: 0
rx_desc: 0
sa_filter_fail: 0
overflow_error: 0
ipc_csum_error: 0
rx_collision: 0
rx_crc_errors: 0
dribbling_bit: 0
rx_length: 0
rx_mii: 0
rx_multicast: 0
rx_gmac_overflow: 0
rx_watchdog: 0
da_rx_filter_fail: 0
sa_rx_filter_fail: 0
rx_missed_cntr: 0
rx_overflow_cntr: 0
rx_vlan: 0
tx_undeflow_irq: 0
tx_process_stopped_irq: 0
tx_jabber_irq: 0
rx_overflow_irq: 0
rx_buf_unav_irq: 0
rx_process_stopped_irq: 0
rx_watchdog_irq: 0
tx_early_irq: 0
fatal_bus_error_irq: 0
rx_early_irq: 0
threshold: 1
tx_pkt_n: 83
rx_pkt_n: 133
normal_irq_n: 130
rx_normal_irq_n: 129
napi_poll: 130
tx_normal_irq_n: 1
tx_clean: 192
tx_set_ic_bit: 1
irq_receive_pmt_irq_n: 0
mmc_tx_irq_n: 0
mmc_rx_irq_n: 0
mmc_rx_csum_offload_irq_n: 0
irq_tx_path_in_lpi_mode_n: 72
irq_tx_path_exit_lpi_mode_n: 72
irq_rx_path_in_lpi_mode_n: 0
irq_rx_path_exit_lpi_mode_n: 0
phy_eee_wakeup_error_n: 65535
ip_hdr_err: 0
ip_payload_err: 0
ip_csum_bypassed: 0
ipv4_pkt_rcvd: 0
ipv6_pkt_rcvd: 0
no_ptp_rx_msg_type_ext: 0
ptp_rx_msg_type_sync: 0
ptp_rx_msg_type_follow_up: 0
ptp_rx_msg_type_delay_req: 0
ptp_rx_msg_type_delay_resp: 0
ptp_rx_msg_type_pdelay_req: 0
ptp_rx_msg_type_pdelay_resp: 0
ptp_rx_msg_type_pdelay_follow_up: 0
ptp_rx_msg_type_announce: 0
ptp_rx_msg_type_management: 0
ptp_rx_msg_pkt_reserved_type: 0
ptp_frame_type: 0
ptp_ver: 0
timestamp_dropped: 0
av_pkt_rcvd: 0
av_tagged_pkt_rcvd: 0
vlan_tag_priority_val: 0
l3_filter_match: 0
l4_filter_match: 0
l3_l4_filter_no_match: 0
irq_pcs_ane_n: 0
irq_pcs_link_n: 0
irq_rgmii_n: 0
mtl_tx_status_fifo_full: 0
mtl_tx_fifo_not_empty: 0
mmtl_fifo_ctrl: 0
mtl_tx_fifo_read_ctrl_write: 0
mtl_tx_fifo_read_ctrl_wait: 0
mtl_tx_fifo_read_ctrl_read: 0
mtl_tx_fifo_read_ctrl_idle: 0
mac_tx_in_pause: 0
mac_tx_frame_ctrl_xfer: 0
mac_tx_frame_ctrl_idle: 0
mac_tx_frame_ctrl_wait: 0
mac_tx_frame_ctrl_pause: 0
mac_gmii_tx_proto_engine: 0
mtl_rx_fifo_fill_level_full: 0
mtl_rx_fifo_fill_above_thresh: 0
mtl_rx_fifo_fill_below_thresh: 0
mtl_rx_fifo_fill_level_empty: 0
mtl_rx_fifo_read_ctrl_flush: 0
mtl_rx_fifo_read_ctrl_read_data: 0
mtl_rx_fifo_read_ctrl_status: 0
mtl_rx_fifo_read_ctrl_idle: 0
mtl_rx_fifo_ctrl_active: 0
mac_rx_frame_ctrl_fifo: 0
mac_gmii_rx_proto_engine: 0
tx_tso_frames: 0
tx_tso_nfrags: 0
[root@alarm ~]#
[root@alarm opt]# git clone
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
Cloning into 'linux-stable'...
remote: Counting objects: 6071472, done.
remote: Compressing objects: 100% (961861/961861), done.
Receiving objects: 0% (22798/6071472), 9.12 MiB | 3.47 MiB/s
Over serial console:
journalctl -f
alarm systemd-timesyncd[256]: Timed out waiting for reply from
144.76.197.108:123 (2.arch.pool.ntp.org).
[root@alarm ~]# ping -c3 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
>From 10.8.8.6 icmp_seq=1 Destination Host Unreachable
>From 10.8.8.6 icmp_seq=2 Destination Host Unreachable
>From 10.8.8.6 icmp_seq=3 Destination Host Unreachable
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 0 received, +3 errors, 100% packet loss, time 2047ms
pipe 3
[root@alarm ~]#
[root@alarm ~]# mii-tool -vvv eth0
Using SIOCGMIIPHY=0x8947
eth0: negotiated 1000baseT-HD flow-control, link ok
registers for MII PHY 8:
1000 782d 0181 4400 01e1 c1e1 000d 2001
ffff ffff ffff ffff ffff ffff ffff ffff
0040 0002 40e8 5400 1c1c 0000 0000 aaaa
fff0 ffff 0000 000a 1407 0000 0000 105a
product info: vendor 00:60:51, model 0 rev 0
basic mode: autonegotiation enabled
basic status: autonegotiation complete, link ok
capabilities: 1000baseT-HD 1000baseT-FD 100baseTx-FD 100baseTx-HD
10baseT-FD 10baseT-HD
advertising: 1000baseT-HD 1000baseT-FD 100baseTx-FD 100baseTx-HD
10baseT-FD 10baseT-HD
link partner: 1000baseT-HD 1000baseT-FD 100baseTx-FD 100baseTx-HD
10baseT-FD 10baseT-HD
[root@alarm ~]# ethtool -S eth0
NIC statistics:
mmc_tx_octetcount_gb: 0
mmc_tx_framecount_gb: 0
mmc_tx_broadcastframe_g: 0
mmc_tx_multicastframe_g: 0
mmc_tx_64_octets_gb: 0
mmc_tx_65_to_127_octets_gb: 0
mmc_tx_128_to_255_octets_gb: 0
mmc_tx_256_to_511_octets_gb: 0
mmc_tx_512_to_1023_octets_gb: 0
mmc_tx_1024_to_max_octets_gb: 0
mmc_tx_unicast_gb: 0
mmc_tx_multicast_gb: 0
mmc_tx_broadcast_gb: 0
mmc_tx_underflow_error: 0
mmc_tx_singlecol_g: 0
mmc_tx_multicol_g: 0
mmc_tx_deferred: 0
mmc_tx_latecol: 0
mmc_tx_exesscol: 0
mmc_tx_carrier_error: 0
mmc_tx_octetcount_g: 0
mmc_tx_framecount_g: 0
mmc_tx_excessdef: 0
mmc_tx_pause_frame: 0
mmc_tx_vlan_frame_g: 0
mmc_rx_framecount_gb: 14959
mmc_rx_octetcount_gb: 20761536
mmc_rx_octetcount_g: 20761536
mmc_rx_broadcastframe_g: 22
mmc_rx_multicastframe_g: 64
mmc_rx_crc_error: 0
mmc_rx_align_error: 0
mmc_rx_run_error: 0
mmc_rx_jabber_error: 0
mmc_rx_undersize_g: 0
mmc_rx_oversize_g: 0
mmc_rx_64_octets_gb: 495
mmc_rx_65_to_127_octets_gb: 658
mmc_rx_128_to_255_octets_gb: 73
mmc_rx_256_to_511_octets_gb: 63
mmc_rx_512_to_1023_octets_gb: 124
mmc_rx_1024_to_max_octets_gb: 13546
mmc_rx_unicast_g: 14873
mmc_rx_length_error: 0
mmc_rx_autofrangetype: 0
mmc_rx_pause_frames: 0
mmc_rx_fifo_overflow: 0
mmc_rx_vlan_frames_gb: 0
mmc_rx_watchdog_error: 0
mmc_rx_ipc_intr_mask: 2147385342
mmc_rx_ipc_intr: 0
mmc_rx_ipv4_gd: 14725
mmc_rx_ipv4_hderr: 0
mmc_rx_ipv4_nopay: 0
mmc_rx_ipv4_frag: 0
mmc_rx_ipv4_udsbl: 0
mmc_rx_ipv4_gd_octets: 20476749
mmc_rx_ipv4_hderr_octets: 0
mmc_rx_ipv4_nopay_octets: 0
mmc_rx_ipv4_frag_octets: 0
mmc_rx_ipv4_udsbl_octets: 0
mmc_rx_ipv6_gd_octets: 312
mmc_rx_ipv6_hderr_octets: 0
mmc_rx_ipv6_nopay_octets: 0
mmc_rx_ipv6_gd: 3
mmc_rx_ipv6_hderr: 0
mmc_rx_ipv6_nopay: 0
mmc_rx_udp_gd: 51
mmc_rx_udp_err: 0
mmc_rx_tcp_gd: 14673
mmc_rx_tcp_err: 0
mmc_rx_icmp_gd: 4
mmc_rx_icmp_err: 0
mmc_rx_udp_gd_octets: 3924
mmc_rx_udp_err_octets: 0
mmc_rx_tcp_gd_octets: 20178297
mmc_rx_tcp_err_octets: 0
mmc_rx_icmp_gd_octets: 220
mmc_rx_icmp_err_octets: 0
tx_underflow: 0
tx_carrier: 0
tx_losscarrier: 0
vlan_tag: 0
tx_deferred: 0
tx_vlan: 0
tx_jabber: 0
tx_frame_flushed: 0
tx_payload_error: 0
tx_ip_header_error: 0
rx_desc: 0
sa_filter_fail: 0
overflow_error: 0
ipc_csum_error: 0
rx_collision: 0
rx_crc_errors: 0
dribbling_bit: 0
rx_length: 0
rx_mii: 0
rx_multicast: 0
rx_gmac_overflow: 0
rx_watchdog: 0
da_rx_filter_fail: 0
sa_rx_filter_fail: 0
rx_missed_cntr: 0
rx_overflow_cntr: 0
rx_vlan: 0
tx_undeflow_irq: 0
tx_process_stopped_irq: 0
tx_jabber_irq: 0
rx_overflow_irq: 0
rx_buf_unav_irq: 0
rx_process_stopped_irq: 0
rx_watchdog_irq: 0
tx_early_irq: 0
fatal_bus_error_irq: 0
rx_early_irq: 6
threshold: 1
tx_pkt_n: 3709
rx_pkt_n: 12926
normal_irq_n: 4594
rx_normal_irq_n: 4537
napi_poll: 4597
tx_normal_irq_n: 57
tx_clean: 5109
tx_set_ic_bit: 59
irq_receive_pmt_irq_n: 0
mmc_tx_irq_n: 0
mmc_rx_irq_n: 0
mmc_rx_csum_offload_irq_n: 0
irq_tx_path_in_lpi_mode_n: 2921
irq_tx_path_exit_lpi_mode_n: 2920
irq_rx_path_in_lpi_mode_n: 0
irq_rx_path_exit_lpi_mode_n: 0
phy_eee_wakeup_error_n: 65535
ip_hdr_err: 0
ip_payload_err: 0
ip_csum_bypassed: 0
ipv4_pkt_rcvd: 0
ipv6_pkt_rcvd: 0
no_ptp_rx_msg_type_ext: 0
ptp_rx_msg_type_sync: 0
ptp_rx_msg_type_follow_up: 0
ptp_rx_msg_type_delay_req: 0
ptp_rx_msg_type_delay_resp: 0
ptp_rx_msg_type_pdelay_req: 0
ptp_rx_msg_type_pdelay_resp: 0
ptp_rx_msg_type_pdelay_follow_up: 0
ptp_rx_msg_type_announce: 0
ptp_rx_msg_type_management: 0
ptp_rx_msg_pkt_reserved_type: 0
ptp_frame_type: 0
ptp_ver: 0
timestamp_dropped: 0
av_pkt_rcvd: 0
av_tagged_pkt_rcvd: 0
vlan_tag_priority_val: 0
l3_filter_match: 0
l4_filter_match: 0
l3_l4_filter_no_match: 0
irq_pcs_ane_n: 0
irq_pcs_link_n: 0
irq_rgmii_n: 0
mtl_tx_status_fifo_full: 0
mtl_tx_fifo_not_empty: 0
mmtl_fifo_ctrl: 0
mtl_tx_fifo_read_ctrl_write: 0
mtl_tx_fifo_read_ctrl_wait: 0
mtl_tx_fifo_read_ctrl_read: 0
mtl_tx_fifo_read_ctrl_idle: 0
mac_tx_in_pause: 0
mac_tx_frame_ctrl_xfer: 0
mac_tx_frame_ctrl_idle: 0
mac_tx_frame_ctrl_wait: 0
mac_tx_frame_ctrl_pause: 0
mac_gmii_tx_proto_engine: 0
mtl_rx_fifo_fill_level_full: 0
mtl_rx_fifo_fill_above_thresh: 0
mtl_rx_fifo_fill_below_thresh: 0
mtl_rx_fifo_fill_level_empty: 0
mtl_rx_fifo_read_ctrl_flush: 0
mtl_rx_fifo_read_ctrl_read_data: 0
mtl_rx_fifo_read_ctrl_status: 0
mtl_rx_fifo_read_ctrl_idle: 0
mtl_rx_fifo_ctrl_active: 0
mac_rx_frame_ctrl_fifo: 0
mac_gmii_rx_proto_engine: 0
tx_tso_frames: 0
tx_tso_nfrags: 0
[root@alarm ~]#
[root@alarm ~]# ifconfig eth0 down && ifconfig eth0 up
Meson GXL Internal PHY 0.e40908ff:08: attached PHY driver [Meson GXL
Internal PHY] (mii_bus:phy_addr=0.e40908ff:08, irq=-1)
meson8b-dwmac c9410000.ethernet eth0: PTP not supported by HW
meson8b-dwmac c9410000.ethernet eth0: Link is Up - 100Mbps/Full - flow
control off
[root@alarm ~]#
whole dmesg [1]. there are some messages like: mdio-mux-mmioreg
c883455c.eth-phy-mux: failed to register mdio-mux bus
/soc/periphs@c8834000/eth-phy-mux
[1] https://defuse.ca/b/s2NpyJlw
Regards,
On Tue, Jun 27, 2017 at 7:14 PM, crow <crow@linux.org.ba> wrote:
> Hi,
> There are other user reporting same issue while using mainline kernel
> but using Ubuntu, so this is for sure not Distribution related. For me
> see the [0]. I hope someone would get time after 4.12 release to try
> fix this issue.
>
> Regards,
>
> [0] http://forum.khadas.com/t/ubuntu-server-rom-linux-mainline-v170624-pre-alpha-version-emmc-installation/803/12
>
> On Thu, Jun 15, 2017 at 4:40 PM, crow <crow@linux.org.ba> wrote:
>> Hi,
>>
>> On Sun, Jun 11, 2017 at 7:03 PM, crow <crow@linux.org.ba> wrote:
>>> Hi Andrew,
>>>
>>> On Sun, Jun 11, 2017 at 5:21 PM, Andrew Lunn <andrew@lunn.ch> wrote:
>>>>> Thank your for the suggestion, and thanks Martin to explaining me over
>>>>> IRC what actually I should do.
>>>>>
>>>>> I recompiled mainline kernel 4.12-rc4 with the Amlogic driver:
>>>>> replaced drivers/net/phy/meson-gxl.c with
>>>>> https://github.com/khadas/linux/blob/ubuntu-4.9/drivers/amlogic/ethernet/phy/amlogic.c
>>>>>
>>>>> But this did not solve the issue. As soon as i start git clone i lose
>>>>> network connection to device (no session timeout/disconnect this time,
>>>>> but I am unable to reconnect over SSH or to get OK ping replay back).
>>>>
>>>
>>> 1) First problem reported I can't reproduce anymore, every reboot/cold
>>> boot with mainline kernel the Ethernet speed is detected as
>>> "100Mbps/Full" , but as seen in first post there was this issue.
>>
>> Once I did setup u-boot to have network in u-boot and did just an ping
>> to activate network. And after boot Ethernet was detected as 10Mbps.
>> But again was not able to reproduce it. I double check that I have 5E
>> cable.
>>
>> in u-boot Ethernet is detected as below
>> kvim#ping x.x.x.x
>> Speed: 100, full duplex
>> Using dwmac.c9410000 device
>> host x.x.x.x is alive
>> kvim#
>>
>> then I let ArchLinuxArm to boot and found out I can't connect to
>> device over SSH. Check over serial console and found:
>>
>> # dmesg | tail -n 10
>> [ 8.334790] meson8b-dwmac c9410000.ethernet eth0: device MAC
>> address 00:15:18:01:81:31
>> [ 8.436668] Meson GXL Internal PHY 0.e40908ff:08: attached PHY
>> driver [Meson GXL Internal PHY] (mii_bus:phy_addr=0.e40908ff:08,
>> irq=-1)
>> [ 8.535171] meson8b-dwmac c9410000.ethernet eth0: PTP not supported by HW
>> [ 10.225264] brcmfmac: brcmf_c_preinit_dcmds: Firmware version =
>> wl0: Mar 1 2015 07:29:38 version 7.45.18 (r538002) FWID 01-6a2c8ad4
>> [ 10.635703] meson8b-dwmac c9410000.ethernet eth0: Link is Up -
>> 10Mbps/Half - flow control off
>> # uname -a
>> Linux khadasvimpro 4.12.0-rc4-3-ARCH #1 SMP Thu Jun 8 00:17:20 CEST
>> 2017 aarch64 GNU/Linux
>> #
>> # mii-tool -vvv eth0
>> Using SIOCGMIIPHY=0x8947
>> eth0: no autonegotiation,, link ok
>> registers for MII PHY 8:
>> 1000 782d 0181 4400 01e1 0001 0005 2001
>> ffff ffff ffff ffff ffff ffff ffff ffff
>> 0040 0002 40e8 5400 1c1c 0000 0000 aaaa
>> fff0 ffff 0000 000a 1407 0040 0000 105a
>> product info: vendor 00:60:51, model 0 rev 0
>> basic mode: autonegotiation enabled
>> basic status: autonegotiation complete, link ok
>> capabilities: 1000baseT-HD 1000baseT-FD 100baseTx-FD 100baseTx-HD
>> 10baseT-FD 10baseT-HD
>> advertising: 1000baseT-HD 1000baseT-FD 100baseTx-FD 100baseTx-HD
>> 10baseT-FD 10baseT-HD
>> #
>> # ifconfig eth0 down && ifconfig eth0 up
>> [ 1972.596690] Meson GXL Internal PHY 0.e40908ff:08: attached PHY
>> driver [Meson GXL Internal PHY] (mii_bus:phy_addr=0.e40908ff:08,
>> irq=-1)
>> [ 1972.704156] meson8b-dwmac c9410000.ethernet eth0: PTP not supported by HW
>> [ 1974.795698] meson8b-dwmac c9410000.ethernet eth0: Link is Up -
>> 100Mbps/Full - flow control off
>> #
>> # mii-tool -vvv eth0
>> Using SIOCGMIIPHY=0x8947
>> eth0: negotiated 1000baseT-HD flow-control, link ok
>> registers for MII PHY 8:
>> 1000 782d 0181 4400 01e1 c1e1 000f 2001
>> ffff ffff ffff ffff ffff ffff ffff ffff
>> 0040 0002 40e8 5400 1c1c 0000 0000 aaaa
>> fff0 ffff 0000 020a 1407 00ca 0000 105a
>> product info: vendor 00:60:51, model 0 rev 0
>> basic mode: autonegotiation enabled
>> basic status: autonegotiation complete, link ok
>> capabilities: 1000baseT-HD 1000baseT-FD 100baseTx-FD 100baseTx-HD
>> 10baseT-FD 10baseT-HD
>> advertising: 1000baseT-HD 1000baseT-FD 100baseTx-FD 100baseTx-HD
>> 10baseT-FD 10baseT-HD
>> link partner: 1000baseT-HD 1000baseT-FD 100baseTx-FD 100baseTx-HD
>> 10baseT-FD 10baseT-HD
>> #
>>
>> 2) see below
>>> 2) see below
>>>
>>>> So this shows it is more than a PHY problem. The Ethernet MAC driver
>>>> is probably also part of the problem.
>>>
>>> There are some stmmac fixes [1] in soon to be rc5, compiled current
>>> master (without amlogic.c) with the fixes but for me the issue still
>>> persist. I will compile once released rc5 with amlogic.c and report
>>> back.
>>>
>>>> Are there any mainline kernels which work O.K?
>>>
>>> Khadas VIM support was added in 4.12-rc1. And I did test all four rc's
>>> but without success.
>>
>> I did test many Kernel builds but all test have failed when
>> downloading bigger files / doing git clone.
>> As Martin Blumenstingl suggested I start with first commit where
>> Khadas VIM support was added [0]. Then also Neil Armstrong suggested
>> [1]. Then all 4.12-rc1 - rc5.
>> Martin Blumenstingl have also found himself that: "I can reproduce the
>> Ethernet problem (tried downloading a 1GiB test file from leaseweb,
>> network got stuck after downloading ~70 MiB)". He suggested that I
>> should "play with the settings on your switch (disable jumbo frames,
>> etc.) to rule out the "exotic" stuff?". Well other device (x86_64)
>> connected on this same Switch port does not have any problem
>> downloading big files or doing git clone, as well as Khadas VIM with
>> Amlogic kernel. Also jumbo frames are not enabled, switch does have
>> only standard settings.
>>
>> I also get questioned which qdisc I use:
>> And it seems I am already using fq_codel (ArchLinuxArm uses systemd):
>> $ tc -s -p qdisc
>> qdisc noqueue 0: dev lo root refcnt 2
>> Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
>> backlog 0b 0p requeues 0
>> qdisc mq 0: dev eth0 root
>> Sent 7382956 bytes 60703 pkt (dropped 0, overlimits 0 requeues 18)
>> backlog 0b 0p requeues 18
>> qdisc fq_codel 0: dev eth0 parent :1 limit 10240p flows 1024 quantum
>> 1514 target 5.0ms interval 100.0ms memory_limit 32Mb ecn
>> Sent 7382956 bytes 60703 pkt (dropped 0, overlimits 0 requeues 18)
>> backlog 0b 0p requeues 18
>> maxpacket 54 drop_overlimit 0 new_flow_count 14 ecn_mark 0
>> new_flows_len 0 old_flows_len 0
>> $ pacman -Qi systemd
>> Name : systemd
>> Version : 232-8
>> Description : system and service manager
>> Architecture : aarch64
>> ...
>> $
>>
>>
>> Regards,
>>
>>>> Andrew
>>>
>>> [1] https://github.com/torvalds/linux/commit/426849e6611f2092553f8d53372ae310818a6292
>>
>> [0] https://github.com/torvalds/linux/commit/e15d2774b8c096f116bf7192b37e8652da71369e
>> [1] https://kernel.googlesource.com/pub/scm/linux/kernel/git/khilman/linux-amlogic/+/v4.12/integ
^ permalink raw reply
* Re: [PATCH net] udp: preserve head state for IP_CMSG_PASSSEC
From: David Miller @ 2017-07-25 17:01 UTC (permalink / raw)
To: pabeni; +Cc: netdev, edumazet, paul
In-Reply-To: <0bd907843b74bc2112ad960f7d11e75ca095eee3.1500998196.git.pabeni@redhat.com>
From: Paolo Abeni <pabeni@redhat.com>
Date: Tue, 25 Jul 2017 17:57:47 +0200
> Paul Moore reported a SELinux/IP_PASSSEC regression
> caused by missing skb->sp at recvmsg() time. We need to
> preserve the skb head state to process the IP_CMSG_PASSSEC
> cmsg.
>
> With this commit we avoid releasing the skb head state in the
> BH even if a secpath is attached to the current skb, and stores
> the skb status (with/without head states) in the scratch area,
> so that we can access it at skb deallocation time, without
> incurring in cache-miss penalties.
>
> This also avoids misusing the skb CB for ipv6 packets,
> as introduced by the commit 0ddf3fb2c43d ("udp: preserve
> skb->dst if required for IP options processing").
>
> Clean a bit the scratch area helpers implementation, to
> reduce the code differences between 32 and 64 bits build.
>
> Reported-by: Paul Moore <paul@paul-moore.com>
> Fixes: 0a463c78d25b ("udp: avoid a cache miss on dequeue")
> Fixes: 0ddf3fb2c43d ("udp: preserve skb->dst if required for IP options processing")
> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
> Tested-by: Paul Moore <paul@paul-moore.com>
Applied, thanks for tracking this down and fixing it.
^ permalink raw reply
* [PATCH net-next 0/3] bnxt_en: Fix kbuild errors and rename phys_port_name.
From: Michael Chan @ 2017-07-25 17:28 UTC (permalink / raw)
To: davem; +Cc: netdev
Fix 2 more kbuild errors (the first one already fixed by DaveM), and rename
the physical port name.
Sathya Perla (3):
bnxt_en: include bnxt_vfr.c code under CONFIG_BNXT_SRIOV switch
bnxt_en: use SWITCHDEV_SET_OPS() for setting vf_rep_switchdev_ops
bnxt_en: fix switchdev port naming for external-port-rep and vf-reps
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 6 +-----
drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c | 10 +++++++--
drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.h | 30 +++++++++++++++++++++++++++
3 files changed, 39 insertions(+), 7 deletions(-)
--
1.8.3.1
^ permalink raw reply
* [PATCH net-next 1/3] bnxt_en: include bnxt_vfr.c code under CONFIG_BNXT_SRIOV switch
From: Michael Chan @ 2017-07-25 17:28 UTC (permalink / raw)
To: davem; +Cc: netdev, Sathya Perla
In-Reply-To: <1501003721-12407-1-git-send-email-michael.chan@broadcom.com>
From: Sathya Perla <sathya.perla@broadcom.com>
And define empty functions in bnxt_vfr.h when CONFIG_BNXT_SRIOV is not
defined.
This fixes build error when CONFIG_BNXT_SRIOV is switched off:
>> drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c:165:16: error: 'struct
>> bnxt' has no member named 'sriov_lock'
Reported-by: kbuild test robot <lkp@intel.com>
Fixes: 4ab0c6a8ffd7 ("bnxt_en: add support to enable VF-representors")
Signed-off-by: Sathya Perla <sathya.perla@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
---
drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c | 4 ++++
drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.h | 30 +++++++++++++++++++++++++++
2 files changed, 34 insertions(+)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c
index 83478e9..a52e292 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c
@@ -16,6 +16,8 @@
#include "bnxt.h"
#include "bnxt_vfr.h"
+#ifdef CONFIG_BNXT_SRIOV
+
#define CFA_HANDLE_INVALID 0xffff
#define VF_IDX_INVALID 0xffff
@@ -487,3 +489,5 @@ void bnxt_dl_unregister(struct bnxt *bp)
devlink_unregister(dl);
devlink_free(dl);
}
+
+#endif
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.h
index c6cd55a..e55a3b6 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.h
@@ -10,6 +10,8 @@
#ifndef BNXT_VFR_H
#define BNXT_VFR_H
+#ifdef CONFIG_BNXT_SRIOV
+
#define MAX_CFA_CODE 65536
/* Struct to hold housekeeping info needed by devlink interface */
@@ -39,4 +41,32 @@ static inline void bnxt_link_bp_to_dl(struct devlink *dl, struct bnxt *bp)
void bnxt_vf_rep_rx(struct bnxt *bp, struct sk_buff *skb);
struct net_device *bnxt_get_vf_rep(struct bnxt *bp, u16 cfa_code);
+#else
+
+static inline int bnxt_dl_register(struct bnxt *bp)
+{
+ return 0;
+}
+
+static inline void bnxt_dl_unregister(struct bnxt *bp)
+{
+}
+
+static inline void bnxt_vf_reps_close(struct bnxt *bp)
+{
+}
+
+static inline void bnxt_vf_reps_open(struct bnxt *bp)
+{
+}
+
+static inline void bnxt_vf_rep_rx(struct bnxt *bp, struct sk_buff *skb)
+{
+}
+
+static inline struct net_device *bnxt_get_vf_rep(struct bnxt *bp, u16 cfa_code)
+{
+ return NULL;
+}
+#endif /* CONFIG_BNXT_SRIOV */
#endif /* BNXT_VFR_H */
--
1.8.3.1
^ permalink raw reply related
* [PATCH net-next 2/3] bnxt_en: use SWITCHDEV_SET_OPS() for setting vf_rep_switchdev_ops
From: Michael Chan @ 2017-07-25 17:28 UTC (permalink / raw)
To: davem; +Cc: netdev, Sathya Perla
In-Reply-To: <1501003721-12407-1-git-send-email-michael.chan@broadcom.com>
From: Sathya Perla <sathya.perla@broadcom.com>
This fixes the build error:
‘struct net_device’ has no member named ‘switchdev_ops’
Reported-by: kbuild test robot <lkp@intel.com>
Fixes: c124a62ff2dd ("bnxt_en: add support for port_attr_get and and get_phys_port_name")
Signed-off-by: Sathya Perla <sathya.perla@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
---
drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c
index a52e292..c00352a 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c
@@ -304,7 +304,7 @@ static void bnxt_vf_rep_netdev_init(struct bnxt *bp, struct bnxt_vf_rep *vf_rep,
dev->netdev_ops = &bnxt_vf_rep_netdev_ops;
dev->ethtool_ops = &bnxt_vf_rep_ethtool_ops;
- dev->switchdev_ops = &bnxt_vf_rep_switchdev_ops;
+ SWITCHDEV_SET_OPS(dev, &bnxt_vf_rep_switchdev_ops);
/* Just inherit all the featues of the parent PF as the VF-R
* uses the RX/TX rings of the parent PF
*/
--
1.8.3.1
^ permalink raw reply related
* [PATCH net-next 3/3] bnxt_en: fix switchdev port naming for external-port-rep and vf-reps
From: Michael Chan @ 2017-07-25 17:28 UTC (permalink / raw)
To: davem; +Cc: netdev, Sathya Perla
In-Reply-To: <1501003721-12407-1-git-send-email-michael.chan@broadcom.com>
From: Sathya Perla <sathya.perla@broadcom.com>
Fix the phys_port_name for the external physical port to be in
"pA" format and that of VF-rep to be in "pCvfD" format as
suggested by Jakub Kicinski.
Fixes: c124a62ff2dd ("bnxt_en: add support for port_attr_get and get_phys_port_name")
Signed-off-by: Sathya Perla <sathya.perla@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 6 +-----
drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c | 4 +++-
2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index badbc35..4b32cf0 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -7556,11 +7556,7 @@ static int bnxt_get_phys_port_name(struct net_device *dev, char *buf,
if (!BNXT_PF(bp))
return -EOPNOTSUPP;
- /* The switch-id that the pf belongs to is exported by
- * the switchdev ndo. This name is just to distinguish from the
- * vf-rep ports.
- */
- rc = snprintf(buf, len, "pf%d", bp->pf.port_id);
+ rc = snprintf(buf, len, "p%d", bp->pf.port_id);
if (rc >= len)
return -EOPNOTSUPP;
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c
index c00352a..b05c5d0 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c
@@ -141,9 +141,11 @@ static int bnxt_vf_rep_get_phys_port_name(struct net_device *dev, char *buf,
size_t len)
{
struct bnxt_vf_rep *vf_rep = netdev_priv(dev);
+ struct pci_dev *pf_pdev = vf_rep->bp->pdev;
int rc;
- rc = snprintf(buf, len, "vfr%d", vf_rep->vf_idx);
+ rc = snprintf(buf, len, "pf%dvf%d", PCI_FUNC(pf_pdev->devfn),
+ vf_rep->vf_idx);
if (rc >= len)
return -EOPNOTSUPP;
return 0;
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH net] ipv6: no need to return rt->dst.error if it is not null entry.
From: Cong Wang @ 2017-07-25 17:49 UTC (permalink / raw)
To: Hangbin Liu; +Cc: network dev, Roopa Prabhu
In-Reply-To: <20170725000849.GD2938@leo.usersys.redhat.com>
On Mon, Jul 24, 2017 at 5:08 PM, Hangbin Liu <liuhangbin@gmail.com> wrote:
> But what we want in inet6_rtm_getroute() and rt6_dump_route() is to
> get/dump the route info. So we should get the info even it's unreachable or
> prohibit.
If you want to dump prohibit/blackhole entry, then you have to check
for null_entry, and rt->dst.error check is still needed because we
could return error on other normal entries too, IOW, your v2 is correct
if dumping prohibit/blackhole is expected.
I thought we don't dump them. I am not sure about the behavior either.
^ permalink raw reply
* Re: Problem with PHY state machine when using interrupts
From: Florian Fainelli @ 2017-07-25 17:55 UTC (permalink / raw)
To: Mason, Andrew Lunn, Mans Rullgard; +Cc: netdev, Linux ARM
In-Reply-To: <e2f4ef4a-c667-3bdf-e4ea-2767dc6a4922@free.fr>
On July 25, 2017 4:41:32 AM PDT, Mason <slash.tmp@free.fr> wrote:
>On 25/07/2017 12:51, Mason wrote:
>
>> Moving the call to phy_stop() down after all the MAC tear down
>> avoids the hang.
>>
>> As far as I understand, when we are shutting everything down,
>> we don't need the phy_state_machine to run asynchronously.
>> We can run it synchronously one last time after the delayed
>> stuff has been disabled.
>
>Below is my current WIP diff. (It conflates the two issues
>I've been discussing. Splitting the diff required.)
>
>Tested in interrupt mode:
>
># ip link set eth0 up
>[ 11.107547] Atheros 8035 ethernet 26000.nb8800-mii:04: PHY state
>change UP -> AN
>[ 14.530329] nb8800 26000.ethernet eth0: Link is Up - 1Gbps/Full -
>flow control rx/tx
>[ 14.538136] Atheros 8035 ethernet 26000.nb8800-mii:04: PHY state
>change AN -> RUNNING
># ip link set eth0 down
>[ 23.801018] nb8800 26000.ethernet eth0: Link is Down
># ip link set eth0 up
>[ 28.740870] Atheros 8035 ethernet UP26000.nb8800-mii:04: PHY state
>change UP -> AN
>[ 31.431528] nb8800 26000.ethernet eth0: Link is Up - 1Gbps/Full -
>flow control rx/tx
>[ 31.439350] Atheros 8035 ethernet 26000.nb8800-mii:04: PHY state
>change AN -> RUNNING
>
>Works as expected.
It does indeed, although this probably also contains your change that only logs the PHY state machine transitions, which makes me wonder why the UP -> HALTED state is not logged?
>
>Tested in polling mode:
>
># ip link set eth0 up
>[ 23.001199] Atheros 8035 ethernet 26000.nb8800-mii:04: PHY state
>change UP -> AN
>[ 24.024315] Atheros 8035 ethernet 26000.nb8800-mii:04: PHY state
>change AN -> NOLINK
>[ 27.064355] nb8800 26000.ethernet eth0: Link is Up - 1Gbps/Full -
>flow control rx/tx
>[ 27.072156] Atheros 8035 ethernet 26000.nb8800-mii:04: PHY state
>change NOLINK -> RUNNING
># ip link set eth0 down
>[ 42.134617] nb8800 26000.ethernet eth0: Link is Down
># ip link set eth0 up
>[ 48.381185] Atheros 8035 ethernet 26000.nb8800-mii:04: PHY state
>change UP -> AN
>[ 49.410976] Atheros 8035 ethernet 26000.nb8800-mii:04: PHY state
>change AN -> NOLINK
>[ 51.437686] nb8800 26000.ethernet eth0: Link is Up - 1Gbps/Full -
>flow control rx/tx
>[ 51.445486] Atheros 8035 ethernet 26000.nb8800-mii:04: PHY state
>change NOLINK -> RUNNING
>
>Works as expected.
>
>Also tested on my old board, no regression seen.
>
>Can you confirm that the changes to drivers/net/phy/phy.c
>look reasonable?
The flush is correct, but I am not sure about the explicit state change, in two ways:
- in polling mode, we should already be reaching that state with the flush call AFAICT
- in interrupt driven mode (phy_interrupt_is_valid or PHY_IGNORE_INTERRUPT) we do indeed need to make sure the HALTED state is reached
Not sure why I did not see the interrupt imbalance problem with phy_mac_interrupt...
I am out today but will follow up tomorrow. thanks!
--
Florian
^ 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