From 8bdbf41791d19c921d00132cfb25ea946dfcfd21 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Mon, 4 Jul 2016 13:34:25 +0200 Subject: kernel: update to version 4.4.14 Changelog: https://cdn.kernel.org/pub/linux/kernel/v4.x/ChangeLog-4.4.14 Some manual changes to target/linux/generic/patches-4.4/610- netfilter_match_bypass_default_checks.patch were needed. Signed-off-by: Hauke Mehrtens --- .../ipq806x/patches-4.4/400-dsa-add-qca.patch | 1111 ++++++-------------- 1 file changed, 329 insertions(+), 782 deletions(-) (limited to 'target/linux/ipq806x/patches-4.4/400-dsa-add-qca.patch') diff --git a/target/linux/ipq806x/patches-4.4/400-dsa-add-qca.patch b/target/linux/ipq806x/patches-4.4/400-dsa-add-qca.patch index f1bdf1aa6f..00659c104b 100644 --- a/target/linux/ipq806x/patches-4.4/400-dsa-add-qca.patch +++ b/target/linux/ipq806x/patches-4.4/400-dsa-add-qca.patch @@ -40,24 +40,22 @@ Signed-off-by: Mathieu Olivari create mode 100644 drivers/net/dsa/ar8xxx.c create mode 100644 drivers/net/dsa/ar8xxx.h -diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig -index 7ad0a4d..2aae541 100644 --- a/drivers/net/dsa/Kconfig +++ b/drivers/net/dsa/Kconfig -@@ -65,4 +65,11 @@ config NET_DSA_BCM_SF2 +@@ -65,4 +65,13 @@ config NET_DSA_BCM_SF2 This enables support for the Broadcom Starfighter 2 Ethernet switch chips. +config NET_DSA_AR8XXX + tristate "Qualcomm Atheros AR8XXX Ethernet switch family support" + depends on NET_DSA ++ select NET_DSA_TAG_QCA ++ select REGMAP + ---help--- + This enables support for the Qualcomm Atheros AR8XXX Ethernet + switch chips. + endmenu -diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile -index e2d51c4..7647687 100644 --- a/drivers/net/dsa/Makefile +++ b/drivers/net/dsa/Makefile @@ -14,3 +14,4 @@ ifdef CONFIG_NET_DSA_MV88E6171 @@ -65,12 +63,9 @@ index e2d51c4..7647687 100644 endif obj-$(CONFIG_NET_DSA_BCM_SF2) += bcm_sf2.o +obj-$(CONFIG_NET_DSA_AR8XXX) += ar8xxx.o -diff --git a/drivers/net/dsa/ar8xxx.c b/drivers/net/dsa/ar8xxx.c -new file mode 100644 -index 0000000..4ce3ffc --- /dev/null +++ b/drivers/net/dsa/ar8xxx.c -@@ -0,0 +1,303 @@ +@@ -0,0 +1,529 @@ +/* + * Copyright (C) 2009 Felix Fietkau + * Copyright (C) 2011-2012 Gabor Juhos @@ -92,9 +87,59 @@ index 0000000..4ce3ffc +#include +#include +#include ++#include + +#include "ar8xxx.h" + ++#define MIB_DESC(_s, _o, _n) \ ++ { \ ++ .size = (_s), \ ++ .offset = (_o), \ ++ .name = (_n), \ ++ } ++ ++static const struct ar8xxx_mib_desc ar8327_mib[] = { ++ MIB_DESC(1, 0x00, "RxBroad"), ++ MIB_DESC(1, 0x04, "RxPause"), ++ MIB_DESC(1, 0x08, "RxMulti"), ++ MIB_DESC(1, 0x0c, "RxFcsErr"), ++ MIB_DESC(1, 0x10, "RxAlignErr"), ++ MIB_DESC(1, 0x14, "RxRunt"), ++ MIB_DESC(1, 0x18, "RxFragment"), ++ MIB_DESC(1, 0x1c, "Rx64Byte"), ++ MIB_DESC(1, 0x20, "Rx128Byte"), ++ MIB_DESC(1, 0x24, "Rx256Byte"), ++ MIB_DESC(1, 0x28, "Rx512Byte"), ++ MIB_DESC(1, 0x2c, "Rx1024Byte"), ++ MIB_DESC(1, 0x30, "Rx1518Byte"), ++ MIB_DESC(1, 0x34, "RxMaxByte"), ++ MIB_DESC(1, 0x38, "RxTooLong"), ++ MIB_DESC(2, 0x3c, "RxGoodByte"), ++ MIB_DESC(2, 0x44, "RxBadByte"), ++ MIB_DESC(1, 0x4c, "RxOverFlow"), ++ MIB_DESC(1, 0x50, "Filtered"), ++ MIB_DESC(1, 0x54, "TxBroad"), ++ MIB_DESC(1, 0x58, "TxPause"), ++ MIB_DESC(1, 0x5c, "TxMulti"), ++ MIB_DESC(1, 0x60, "TxUnderRun"), ++ MIB_DESC(1, 0x64, "Tx64Byte"), ++ MIB_DESC(1, 0x68, "Tx128Byte"), ++ MIB_DESC(1, 0x6c, "Tx256Byte"), ++ MIB_DESC(1, 0x70, "Tx512Byte"), ++ MIB_DESC(1, 0x74, "Tx1024Byte"), ++ MIB_DESC(1, 0x78, "Tx1518Byte"), ++ MIB_DESC(1, 0x7c, "TxMaxByte"), ++ MIB_DESC(1, 0x80, "TxOverSize"), ++ MIB_DESC(2, 0x84, "TxByte"), ++ MIB_DESC(1, 0x8c, "TxCollision"), ++ MIB_DESC(1, 0x90, "TxAbortCol"), ++ MIB_DESC(1, 0x94, "TxMultiCol"), ++ MIB_DESC(1, 0x98, "TxSingleCol"), ++ MIB_DESC(1, 0x9c, "TxExcDefer"), ++ MIB_DESC(1, 0xa0, "TxDefer"), ++ MIB_DESC(1, 0xa4, "TxLateCol"), ++}; ++ +u32 +ar8xxx_mii_read32(struct mii_bus *bus, int phy_id, int regnum) +{ @@ -200,6 +245,57 @@ index 0000000..4ce3ffc + } +} + ++static int ar8xxx_regmap_read(void *ctx, uint32_t reg, uint32_t *val) ++{ ++ struct dsa_switch *ds = (struct dsa_switch *)ctx; ++ ++ *val = ar8xxx_read(ds, reg); ++ ++ return 0; ++} ++ ++static int ar8xxx_regmap_write(void *ctx, uint32_t reg, uint32_t val) ++{ ++ struct dsa_switch *ds = (struct dsa_switch *)ctx; ++ ++ ar8xxx_write(ds, reg, val); ++ ++ return 0; ++} ++ ++static const struct regmap_range ar8xxx_readable_ranges[] = { ++ regmap_reg_range(0x0000, 0x00e4), /* Global control */ ++ regmap_reg_range(0x0100, 0x0168), /* EEE control */ ++ regmap_reg_range(0x0200, 0x0270), /* Parser control */ ++ regmap_reg_range(0x0400, 0x0454), /* ACL */ ++ regmap_reg_range(0x0600, 0x0718), /* Lookup */ ++ regmap_reg_range(0x0800, 0x0b70), /* QM */ ++ regmap_reg_range(0x0C00, 0x0c80), /* PKT */ ++ regmap_reg_range(0x1000, 0x10ac), /* MIB - Port0 */ ++ regmap_reg_range(0x1100, 0x11ac), /* MIB - Port1 */ ++ regmap_reg_range(0x1200, 0x12ac), /* MIB - Port2 */ ++ regmap_reg_range(0x1300, 0x13ac), /* MIB - Port3 */ ++ regmap_reg_range(0x1400, 0x14ac), /* MIB - Port4 */ ++ regmap_reg_range(0x1500, 0x15ac), /* MIB - Port5 */ ++ regmap_reg_range(0x1600, 0x16ac), /* MIB - Port6 */ ++ ++}; ++ ++static struct regmap_access_table ar8xxx_readable_table = { ++ .yes_ranges = ar8xxx_readable_ranges, ++ .n_yes_ranges = ARRAY_SIZE(ar8xxx_readable_ranges), ++}; ++ ++struct regmap_config ar8xxx_regmap_config = { ++ .reg_bits = 16, ++ .val_bits = 32, ++ .reg_stride = 4, ++ .max_register = 0x16ac, /* end MIB - Port6 range */ ++ .reg_read = ar8xxx_regmap_read, ++ .reg_write = ar8xxx_regmap_write, ++ .rd_table = &ar8xxx_readable_table, ++}; ++ +static int ar8xxx_set_pad_ctrl(struct dsa_switch *ds, int port, int mode) +{ + int reg; @@ -233,6 +329,9 @@ index 0000000..4ce3ffc + ar8xxx_write(ds, AR8327_REG_PORT5_PAD_CTRL, + AR8327_PORT_PAD_RGMII_RX_DELAY_EN); + break; ++ case PHY_INTERFACE_MODE_SGMII: ++ ar8xxx_write(ds, reg, AR8327_PORT_PAD_SGMII_EN); ++ break; + default: + pr_err("xMII mode %d not supported\n", mode); + return -EINVAL; @@ -241,11 +340,61 @@ index 0000000..4ce3ffc + return 0; +} + ++static int ar8xxx_of_setup(struct dsa_switch *ds) ++{ ++ struct device_node *dn = ds->pd->of_node; ++ const char *s_phymode; ++ int ret, mode; ++ u32 phy_id, ctrl; ++ ++ /* If port6-phy-mode property exists, configure it accordingly */ ++ if (!of_property_read_string(dn, "qca,port6-phy-mode", &s_phymode)) { ++ for (mode = 0; mode < PHY_INTERFACE_MODE_MAX; mode++) ++ if (!strcasecmp(s_phymode, phy_modes(mode))) ++ break; ++ ++ if (mode == PHY_INTERFACE_MODE_MAX) ++ pr_err("Unknown phy-mode: \"%s\"\n", s_phymode); ++ ++ ret = ar8xxx_set_pad_ctrl(ds, 6, mode); ++ if (ret < 0) ++ return ret; ++ } ++ ++ /* If a phy ID is specified for PORT6 mac, connect them together */ ++ if (!of_property_read_u32(dn, "qca,port6-phy-id", &phy_id)) { ++ ar8xxx_rmw(ds, AR8327_PORT_LOOKUP_CTRL(6), ++ AR8327_PORT_LOOKUP_MEMBER, BIT(phy_to_port(phy_id))); ++ ar8xxx_rmw(ds, AR8327_PORT_LOOKUP_CTRL(phy_to_port(phy_id)), ++ AR8327_PORT_LOOKUP_MEMBER, BIT(6)); ++ ++ /* We want the switch to be pass-through and act like a PHY on ++ * these ports. So BC/MC/UC & IGMP frames need to be accepted ++ */ ++ ctrl = BIT(phy_to_port(phy_id)) | BIT(6); ++ ar8xxx_reg_set(ds, AR8327_REG_GLOBAL_FW_CTRL1, ++ ctrl << AR8327_GLOBAL_FW_CTRL1_IGMP_DP_S | ++ ctrl << AR8327_GLOBAL_FW_CTRL1_BC_DP_S | ++ ctrl << AR8327_GLOBAL_FW_CTRL1_MC_DP_S | ++ ctrl << AR8327_GLOBAL_FW_CTRL1_UC_DP_S); ++ } ++ ++ return 0; ++} ++ +static int ar8xxx_setup(struct dsa_switch *ds) +{ ++ struct ar8xxx_priv *priv = ds_to_priv(ds); + struct net_device *netdev = ds->dst->pd->of_netdev; + int ret, i, phy_mode; + ++ /* Start by setting up the register mapping */ ++ priv->regmap = devm_regmap_init(ds->master_dev, NULL, ds, ++ &ar8xxx_regmap_config); ++ ++ if (IS_ERR(priv->regmap)) ++ pr_warn("regmap initialization failed"); ++ + /* Initialize CPU port pad mode (xMII type, delays...) */ + phy_mode = of_get_phy_mode(netdev->dev.parent->of_node); + if (phy_mode < 0) { @@ -257,11 +406,31 @@ index 0000000..4ce3ffc + if (ret < 0) + return ret; + ++ /* Enable CPU Port */ ++ ar8xxx_reg_set(ds, AR8327_REG_GLOBAL_FW_CTRL0, ++ AR8327_GLOBAL_FW_CTRL0_CPU_PORT_EN); ++ ++ /* Enable MIB counters */ ++ ar8xxx_reg_set(ds, AR8327_REG_MIB, AR8327_MIB_CPU_KEEP); ++ ar8xxx_write(ds, AR8327_REG_MODULE_EN, AR8327_MODULE_EN_MIB); ++ ++ /* Enable QCA header mode on Port 0 */ ++ ar8xxx_write(ds, AR8327_REG_PORT_HDR_CTRL(0), ++ AR8327_PORT_HDR_CTRL_ALL << AR8327_PORT_HDR_CTRL_TX_S | ++ AR8327_PORT_HDR_CTRL_ALL << AR8327_PORT_HDR_CTRL_RX_S); ++ + /* Disable forwarding by default on all ports */ + for (i = 0; i < AR8327_NUM_PORTS; i++) + ar8xxx_rmw(ds, AR8327_PORT_LOOKUP_CTRL(i), + AR8327_PORT_LOOKUP_MEMBER, 0); + ++ /* Forward all unknown frames to CPU port for Linux processing */ ++ ar8xxx_write(ds, AR8327_REG_GLOBAL_FW_CTRL1, ++ BIT(0) << AR8327_GLOBAL_FW_CTRL1_IGMP_DP_S | ++ BIT(0) << AR8327_GLOBAL_FW_CTRL1_BC_DP_S | ++ BIT(0) << AR8327_GLOBAL_FW_CTRL1_MC_DP_S | ++ BIT(0) << AR8327_GLOBAL_FW_CTRL1_UC_DP_S); ++ + /* Setup connection between CPU ports & PHYs */ + for (i = 0; i < DSA_MAX_PORTS; i++) { + /* CPU port gets connected to all PHYs in the switch */ @@ -273,11 +442,23 @@ index 0000000..4ce3ffc + + /* Invividual PHYs gets connected to CPU port only */ + if (ds->phys_port_mask & BIT(i)) { -+ ar8xxx_rmw(ds, AR8327_PORT_LOOKUP_CTRL(phy_to_port(i)), ++ int phy = phy_to_port(i); ++ ++ ar8xxx_rmw(ds, AR8327_PORT_LOOKUP_CTRL(phy), + AR8327_PORT_LOOKUP_MEMBER, BIT(0)); ++ ++ /* Disable Auto-learning by default so the switch ++ * doesn't try to forward the frame to another port ++ */ ++ ar8xxx_reg_clear(ds, AR8327_PORT_LOOKUP_CTRL(phy), ++ AR8327_PORT_LOOKUP_LEARN); + } + } + ++ ret = ar8xxx_of_setup(ds); ++ if (ret < 0) ++ return ret; ++ + return 0; +} + @@ -301,6 +482,42 @@ index 0000000..4ce3ffc + return mdiobus_write(bus, phy, regnum, val); +} + ++static void ar8xxx_get_strings(struct dsa_switch *ds, int phy, uint8_t *data) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(ar8327_mib); i++) { ++ strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name, ++ ETH_GSTRING_LEN); ++ } ++} ++ ++static void ar8xxx_get_ethtool_stats(struct dsa_switch *ds, int phy, ++ uint64_t *data) ++{ ++ const struct ar8xxx_mib_desc *mib; ++ uint32_t reg, i, port; ++ u64 hi; ++ ++ port = phy_to_port(phy); ++ ++ for (i = 0; i < ARRAY_SIZE(ar8327_mib); i++) { ++ mib = &ar8327_mib[i]; ++ reg = AR8327_PORT_MIB_COUNTER(port) + mib->offset; ++ ++ data[i] = ar8xxx_read(ds, reg); ++ if (mib->size == 2) { ++ hi = ar8xxx_read(ds, reg + 4); ++ data[i] |= hi << 32; ++ } ++ } ++} ++ ++static int ar8xxx_get_sset_count(struct dsa_switch *ds) ++{ ++ return ARRAY_SIZE(ar8327_mib); ++} ++ +static void ar8xxx_poll_link(struct dsa_switch *ds) +{ + int i = 0; @@ -348,13 +565,17 @@ index 0000000..4ce3ffc +} + +static struct dsa_switch_driver ar8xxx_switch_driver = { -+ .tag_protocol = DSA_TAG_PROTO_NONE, -+ .probe = ar8xxx_probe, -+ .setup = ar8xxx_setup, -+ .set_addr = ar8xxx_set_addr, -+ .poll_link = ar8xxx_poll_link, -+ .phy_read = ar8xxx_phy_read, -+ .phy_write = ar8xxx_phy_write, ++ .tag_protocol = DSA_TAG_PROTO_QCA, ++ .priv_size = sizeof(struct ar8xxx_priv), ++ .probe = ar8xxx_probe, ++ .setup = ar8xxx_setup, ++ .set_addr = ar8xxx_set_addr, ++ .poll_link = ar8xxx_poll_link, ++ .phy_read = ar8xxx_phy_read, ++ .phy_write = ar8xxx_phy_write, ++ .get_strings = ar8xxx_get_strings, ++ .get_ethtool_stats = ar8xxx_get_ethtool_stats, ++ .get_sset_count = ar8xxx_get_sset_count, +}; + +static int __init ar8xxx_init(void) @@ -374,12 +595,9 @@ index 0000000..4ce3ffc +MODULE_DESCRIPTION("Driver for AR8XXX ethernet switch family"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:ar8xxx"); -diff --git a/drivers/net/dsa/ar8xxx.h b/drivers/net/dsa/ar8xxx.h -new file mode 100644 -index 0000000..a29b6d3 --- /dev/null +++ b/drivers/net/dsa/ar8xxx.h -@@ -0,0 +1,82 @@ +@@ -0,0 +1,156 @@ +/* + * Copyright (C) 2009 Felix Fietkau + * Copyright (C) 2011-2012 Gabor Juhos @@ -399,6 +617,17 @@ index 0000000..a29b6d3 +#define __AR8XXX_H + +#include ++#include ++ ++struct ar8xxx_priv { ++ struct regmap *regmap; ++}; ++ ++struct ar8xxx_mib_desc { ++ unsigned int size; ++ unsigned int offset; ++ const char *name; ++}; + +#define AR8327_NUM_PORTS 7 + @@ -413,6 +642,14 @@ index 0000000..a29b6d3 +#define AR8327_PORT_PAD_RGMII_RX_DELAY_EN BIT(24) +#define AR8327_PORT_PAD_SGMII_EN BIT(7) + ++#define AR8327_REG_MODULE_EN 0x030 ++#define AR8327_MODULE_EN_MIB BIT(0) ++#define AR8327_MODULE_EN_ACL BIT(1) ++#define AR8327_MODULE_EN_L3 BIT(2) ++ ++#define AR8327_REG_MIB 0x034 ++#define AR8327_MIB_CPU_KEEP BIT(20) ++ +#define AR8327_REG_PORT_STATUS(_i) (0x07c + (_i) * 4) +#define AR8XXX_PORT_STATUS_SPEED GENMASK(2, 0) +#define AR8XXX_PORT_STATUS_SPEED_S 0 @@ -425,7 +662,29 @@ index 0000000..a29b6d3 +#define AR8XXX_PORT_STATUS_LINK_AUTO BIT(9) +#define AR8XXX_PORT_STATUS_LINK_PAUSE BIT(10) + -+#define AR8327_PORT_LOOKUP_CTRL(_i) (0x660 + (_i) * 0xc) ++#define AR8327_REG_PORT_HDR_CTRL(_i) (0x9c + (_i * 4)) ++#define AR8327_PORT_HDR_CTRL_RX_MASK GENMASK(3, 2) ++#define AR8327_PORT_HDR_CTRL_RX_S 2 ++#define AR8327_PORT_HDR_CTRL_TX_MASK GENMASK(1, 0) ++#define AR8327_PORT_HDR_CTRL_TX_S 0 ++#define AR8327_PORT_HDR_CTRL_ALL 2 ++#define AR8327_PORT_HDR_CTRL_MGMT 1 ++#define AR8327_PORT_HDR_CTRL_NONE 0 ++ ++#define AR8327_REG_GLOBAL_FW_CTRL0 0x620 ++#define AR8327_GLOBAL_FW_CTRL0_CPU_PORT_EN BIT(10) ++ ++#define AR8327_REG_GLOBAL_FW_CTRL1 0x624 ++#define AR8327_GLOBAL_FW_CTRL1_IGMP_DP_MASK GENMASK(30, 24) ++#define AR8327_GLOBAL_FW_CTRL1_IGMP_DP_S 24 ++#define AR8327_GLOBAL_FW_CTRL1_BC_DP_MASK GENMASK(22, 16) ++#define AR8327_GLOBAL_FW_CTRL1_BC_DP_S 16 ++#define AR8327_GLOBAL_FW_CTRL1_MC_DP_MASK GENMASK(14, 8) ++#define AR8327_GLOBAL_FW_CTRL1_MC_DP_S 8 ++#define AR8327_GLOBAL_FW_CTRL1_UC_DP_MASK GENMASK(6, 0) ++#define AR8327_GLOBAL_FW_CTRL1_UC_DP_S 0 ++ ++#define AR8327_PORT_LOOKUP_CTRL(_i) (0x660 + (_i) * 0xc) +#define AR8327_PORT_LOOKUP_MEMBER GENMASK(6, 0) +#define AR8327_PORT_LOOKUP_IN_MODE GENMASK(9, 8) +#define AR8327_PORT_LOOKUP_IN_MODE_S 8 @@ -434,6 +693,8 @@ index 0000000..a29b6d3 +#define AR8327_PORT_LOOKUP_LEARN BIT(20) +#define AR8327_PORT_LOOKUP_ING_MIRROR_EN BIT(25) + ++#define AR8327_PORT_MIB_COUNTER(_i) (0x1000 + (_i) * 0x100) ++ +/* port speed */ +enum { + AR8XXX_PORT_SPEED_10M = 0, @@ -442,251 +703,6 @@ index 0000000..a29b6d3 + AR8XXX_PORT_SPEED_ERR = 3, +}; + -+static inline void -+split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page) -+{ -+ regaddr >>= 1; -+ *r1 = regaddr & 0x1e; -+ -+ regaddr >>= 5; -+ *r2 = regaddr & 0x7; -+ -+ regaddr >>= 3; -+ *page = regaddr & 0x1ff; -+} -+ -+static inline void -+wait_for_page_switch(void) -+{ -+ udelay(5); -+} -+ -+#endif /* __AR8XXX_H */ -diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c -index e6f6cc3..fffb9aa 100644 ---- a/net/dsa/dsa.c -+++ b/net/dsa/dsa.c -@@ -893,6 +893,7 @@ static SIMPLE_DEV_PM_OPS(dsa_pm_ops, dsa_suspend, dsa_resume); - - static const struct of_device_id dsa_of_match_table[] = { - { .compatible = "brcm,bcm7445-switch-v4.0" }, -+ { .compatible = "qca,ar8xxx", }, - { .compatible = "marvell,dsa", }, - {} - }; - -From patchwork Fri May 29 01:42:17 2015 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [2/7] net: dsa: ar8xxx: add ethtool hw statistics support -From: Mathieu Olivari -X-Patchwork-Id: 477524 -X-Patchwork-Delegate: davem@davemloft.net -Message-Id: <1432863742-18427-3-git-send-email-mathieu@codeaurora.org> -To: robh+dt@kernel.org, pawel.moll@arm.com, mark.rutland@arm.com, - ijc+devicetree@hellion.org.uk, galak@codeaurora.org, - davem@davemloft.net, mathieu@codeaurora.org, andrew@lunn.ch, - f.fainelli@gmail.com, linux@roeck-us.net, gang.chen.5i5j@gmail.com, - jiri@resnulli.us, leitec@staticky.com, fabf@skynet.be, - alexander.h.duyck@intel.com, pavel.nakonechny@skitlab.ru, - joe@perches.com, sfeldma@gmail.com, nbd@openwrt.org, juhosg@openwrt.org -Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, - netdev@vger.kernel.org -Date: Thu, 28 May 2015 18:42:17 -0700 - -MIB counters can now be reported through each switch port by using -"ethtool -S". - -Signed-off-by: Mathieu Olivari ---- - drivers/net/dsa/ar8xxx.c | 106 +++++++++++++++++++++++++++++++++++++++++++---- - drivers/net/dsa/ar8xxx.h | 47 +++++++++++++++++++++ - 2 files changed, 146 insertions(+), 7 deletions(-) - -diff --git a/drivers/net/dsa/ar8xxx.c b/drivers/net/dsa/ar8xxx.c -index 4ce3ffc..2f0fa4d 100644 ---- a/drivers/net/dsa/ar8xxx.c -+++ b/drivers/net/dsa/ar8xxx.c -@@ -22,6 +22,55 @@ - - #include "ar8xxx.h" - -+#define MIB_DESC(_s, _o, _n) \ -+ { \ -+ .size = (_s), \ -+ .offset = (_o), \ -+ .name = (_n), \ -+ } -+ -+static const struct ar8xxx_mib_desc ar8327_mib[] = { -+ MIB_DESC(1, 0x00, "RxBroad"), -+ MIB_DESC(1, 0x04, "RxPause"), -+ MIB_DESC(1, 0x08, "RxMulti"), -+ MIB_DESC(1, 0x0c, "RxFcsErr"), -+ MIB_DESC(1, 0x10, "RxAlignErr"), -+ MIB_DESC(1, 0x14, "RxRunt"), -+ MIB_DESC(1, 0x18, "RxFragment"), -+ MIB_DESC(1, 0x1c, "Rx64Byte"), -+ MIB_DESC(1, 0x20, "Rx128Byte"), -+ MIB_DESC(1, 0x24, "Rx256Byte"), -+ MIB_DESC(1, 0x28, "Rx512Byte"), -+ MIB_DESC(1, 0x2c, "Rx1024Byte"), -+ MIB_DESC(1, 0x30, "Rx1518Byte"), -+ MIB_DESC(1, 0x34, "RxMaxByte"), -+ MIB_DESC(1, 0x38, "RxTooLong"), -+ MIB_DESC(2, 0x3c, "RxGoodByte"), -+ MIB_DESC(2, 0x44, "RxBadByte"), -+ MIB_DESC(1, 0x4c, "RxOverFlow"), -+ MIB_DESC(1, 0x50, "Filtered"), -+ MIB_DESC(1, 0x54, "TxBroad"), -+ MIB_DESC(1, 0x58, "TxPause"), -+ MIB_DESC(1, 0x5c, "TxMulti"), -+ MIB_DESC(1, 0x60, "TxUnderRun"), -+ MIB_DESC(1, 0x64, "Tx64Byte"), -+ MIB_DESC(1, 0x68, "Tx128Byte"), -+ MIB_DESC(1, 0x6c, "Tx256Byte"), -+ MIB_DESC(1, 0x70, "Tx512Byte"), -+ MIB_DESC(1, 0x74, "Tx1024Byte"), -+ MIB_DESC(1, 0x78, "Tx1518Byte"), -+ MIB_DESC(1, 0x7c, "TxMaxByte"), -+ MIB_DESC(1, 0x80, "TxOverSize"), -+ MIB_DESC(2, 0x84, "TxByte"), -+ MIB_DESC(1, 0x8c, "TxCollision"), -+ MIB_DESC(1, 0x90, "TxAbortCol"), -+ MIB_DESC(1, 0x94, "TxMultiCol"), -+ MIB_DESC(1, 0x98, "TxSingleCol"), -+ MIB_DESC(1, 0x9c, "TxExcDefer"), -+ MIB_DESC(1, 0xa0, "TxDefer"), -+ MIB_DESC(1, 0xa4, "TxLateCol"), -+}; -+ - u32 - ar8xxx_mii_read32(struct mii_bus *bus, int phy_id, int regnum) - { -@@ -184,6 +233,10 @@ static int ar8xxx_setup(struct dsa_switch *ds) - if (ret < 0) - return ret; - -+ /* Enable MIB counters */ -+ ar8xxx_reg_set(ds, AR8327_REG_MIB, AR8327_MIB_CPU_KEEP); -+ ar8xxx_write(ds, AR8327_REG_MODULE_EN, AR8327_MODULE_EN_MIB); -+ - /* Disable forwarding by default on all ports */ - for (i = 0; i < AR8327_NUM_PORTS; i++) - ar8xxx_rmw(ds, AR8327_PORT_LOOKUP_CTRL(i), -@@ -228,6 +281,42 @@ ar8xxx_phy_write(struct dsa_switch *ds, int phy, int regnum, u16 val) - return mdiobus_write(bus, phy, regnum, val); - } - -+static void ar8xxx_get_strings(struct dsa_switch *ds, int phy, uint8_t *data) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(ar8327_mib); i++) { -+ strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name, -+ ETH_GSTRING_LEN); -+ } -+} -+ -+static void ar8xxx_get_ethtool_stats(struct dsa_switch *ds, int phy, -+ uint64_t *data) -+{ -+ const struct ar8xxx_mib_desc *mib; -+ uint32_t reg, i, port; -+ u64 hi; -+ -+ port = phy_to_port(phy); -+ -+ for (i = 0; i < ARRAY_SIZE(ar8327_mib); i++) { -+ mib = &ar8327_mib[i]; -+ reg = AR8327_PORT_MIB_COUNTER(port) + mib->offset; -+ -+ data[i] = ar8xxx_read(ds, reg); -+ if (mib->size == 2) { -+ hi = ar8xxx_read(ds, reg + 4); -+ data[i] |= hi << 32; -+ } -+ } -+} -+ -+static int ar8xxx_get_sset_count(struct dsa_switch *ds) -+{ -+ return ARRAY_SIZE(ar8327_mib); -+} -+ - static void ar8xxx_poll_link(struct dsa_switch *ds) - { - int i = 0; -@@ -275,13 +364,16 @@ static void ar8xxx_poll_link(struct dsa_switch *ds) - } - - static struct dsa_switch_driver ar8xxx_switch_driver = { -- .tag_protocol = DSA_TAG_PROTO_NONE, -- .probe = ar8xxx_probe, -- .setup = ar8xxx_setup, -- .set_addr = ar8xxx_set_addr, -- .poll_link = ar8xxx_poll_link, -- .phy_read = ar8xxx_phy_read, -- .phy_write = ar8xxx_phy_write, -+ .tag_protocol = DSA_TAG_PROTO_NONE, -+ .probe = ar8xxx_probe, -+ .setup = ar8xxx_setup, -+ .set_addr = ar8xxx_set_addr, -+ .poll_link = ar8xxx_poll_link, -+ .phy_read = ar8xxx_phy_read, -+ .phy_write = ar8xxx_phy_write, -+ .get_strings = ar8xxx_get_strings, -+ .get_ethtool_stats = ar8xxx_get_ethtool_stats, -+ .get_sset_count = ar8xxx_get_sset_count, - }; - - static int __init ar8xxx_init(void) -diff --git a/drivers/net/dsa/ar8xxx.h b/drivers/net/dsa/ar8xxx.h -index a29b6d3..7c7a125 100644 ---- a/drivers/net/dsa/ar8xxx.h -+++ b/drivers/net/dsa/ar8xxx.h -@@ -18,6 +18,12 @@ - - #include - -+struct ar8xxx_mib_desc { -+ unsigned int size; -+ unsigned int offset; -+ const char *name; -+}; -+ - #define AR8327_NUM_PORTS 7 - - #define PHY_ID_QCA8337 0x004dd036 -@@ -31,6 +37,14 @@ - #define AR8327_PORT_PAD_RGMII_RX_DELAY_EN BIT(24) - #define AR8327_PORT_PAD_SGMII_EN BIT(7) - -+#define AR8327_REG_MODULE_EN 0x030 -+#define AR8327_MODULE_EN_MIB BIT(0) -+#define AR8327_MODULE_EN_ACL BIT(1) -+#define AR8327_MODULE_EN_L3 BIT(2) -+ -+#define AR8327_REG_MIB 0x034 -+#define AR8327_MIB_CPU_KEEP BIT(20) -+ - #define AR8327_REG_PORT_STATUS(_i) (0x07c + (_i) * 4) - #define AR8XXX_PORT_STATUS_SPEED GENMASK(2, 0) - #define AR8XXX_PORT_STATUS_SPEED_S 0 -@@ -52,6 +66,8 @@ - #define AR8327_PORT_LOOKUP_LEARN BIT(20) - #define AR8327_PORT_LOOKUP_ING_MIRROR_EN BIT(25) - -+#define AR8327_PORT_MIB_COUNTER(_i) (0x1000 + (_i) * 0x100) -+ - /* port speed */ - enum { - AR8XXX_PORT_SPEED_10M = 0, -@@ -60,6 +76,25 @@ enum { - AR8XXX_PORT_SPEED_ERR = 3, - }; - +static inline int port_to_phy(int port) +{ + if (port >= 1 && port <= 6) @@ -705,216 +721,61 @@ index a29b6d3..7c7a125 100644 + +u32 +ar8xxx_rmw(struct dsa_switch *ds, int reg, u32 mask, u32 val); -+ - static inline void - split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page) - { -@@ -79,4 +114,16 @@ wait_for_page_switch(void) - udelay(5); - } - -+static inline void -+ar8xxx_reg_set(struct dsa_switch *ds, int reg, u32 val) -+{ -+ ar8xxx_rmw(ds, reg, 0, val); -+} + +static inline void -+ar8xxx_reg_clear(struct dsa_switch *ds, int reg, u32 val) -+{ -+ ar8xxx_rmw(ds, reg, val, 0); -+} -+ - #endif /* __AR8XXX_H */ - -From patchwork Fri May 29 01:42:18 2015 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [3/7] net: dsa: ar8xxx: add regmap support -From: Mathieu Olivari -X-Patchwork-Id: 477522 -X-Patchwork-Delegate: davem@davemloft.net -Message-Id: <1432863742-18427-4-git-send-email-mathieu@codeaurora.org> -To: robh+dt@kernel.org, pawel.moll@arm.com, mark.rutland@arm.com, - ijc+devicetree@hellion.org.uk, galak@codeaurora.org, - davem@davemloft.net, mathieu@codeaurora.org, andrew@lunn.ch, - f.fainelli@gmail.com, linux@roeck-us.net, gang.chen.5i5j@gmail.com, - jiri@resnulli.us, leitec@staticky.com, fabf@skynet.be, - alexander.h.duyck@intel.com, pavel.nakonechny@skitlab.ru, - joe@perches.com, sfeldma@gmail.com, nbd@openwrt.org, juhosg@openwrt.org -Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, - netdev@vger.kernel.org -Date: Thu, 28 May 2015 18:42:18 -0700 - -All switch registers can now be dumped using regmap/debugfs. - -\# cat /sys/kernel/debug/regmap//registers -0000: 00001302 -0004: ... -... - -Signed-off-by: Mathieu Olivari ---- - drivers/net/dsa/Kconfig | 1 + - drivers/net/dsa/ar8xxx.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ - drivers/net/dsa/ar8xxx.h | 5 ++++ - 3 files changed, 66 insertions(+) - -diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig -index 2aae541..17fb296 100644 ---- a/drivers/net/dsa/Kconfig -+++ b/drivers/net/dsa/Kconfig -@@ -68,6 +68,7 @@ config NET_DSA_BCM_SF2 - config NET_DSA_AR8XXX - tristate "Qualcomm Atheros AR8XXX Ethernet switch family support" - depends on NET_DSA -+ select REGMAP - ---help--- - This enables support for the Qualcomm Atheros AR8XXX Ethernet - switch chips. -diff --git a/drivers/net/dsa/ar8xxx.c b/drivers/net/dsa/ar8xxx.c -index 2f0fa4d..327abd4 100644 ---- a/drivers/net/dsa/ar8xxx.c -+++ b/drivers/net/dsa/ar8xxx.c -@@ -176,6 +176,57 @@ static char *ar8xxx_probe(struct device *host_dev, int sw_addr) - } - } - -+static int ar8xxx_regmap_read(void *ctx, uint32_t reg, uint32_t *val) -+{ -+ struct dsa_switch *ds = (struct dsa_switch *)ctx; -+ -+ *val = ar8xxx_read(ds, reg); -+ -+ return 0; -+} -+ -+static int ar8xxx_regmap_write(void *ctx, uint32_t reg, uint32_t val) ++split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page) +{ -+ struct dsa_switch *ds = (struct dsa_switch *)ctx; ++ regaddr >>= 1; ++ *r1 = regaddr & 0x1e; + -+ ar8xxx_write(ds, reg, val); ++ regaddr >>= 5; ++ *r2 = regaddr & 0x7; + -+ return 0; ++ regaddr >>= 3; ++ *page = regaddr & 0x1ff; +} + -+static const struct regmap_range ar8xxx_readable_ranges[] = { -+ regmap_reg_range(0x0000, 0x00e4), /* Global control */ -+ regmap_reg_range(0x0100, 0x0168), /* EEE control */ -+ regmap_reg_range(0x0200, 0x0270), /* Parser control */ -+ regmap_reg_range(0x0400, 0x0454), /* ACL */ -+ regmap_reg_range(0x0600, 0x0718), /* Lookup */ -+ regmap_reg_range(0x0800, 0x0b70), /* QM */ -+ regmap_reg_range(0x0C00, 0x0c80), /* PKT */ -+ regmap_reg_range(0x1000, 0x10ac), /* MIB - Port0 */ -+ regmap_reg_range(0x1100, 0x11ac), /* MIB - Port1 */ -+ regmap_reg_range(0x1200, 0x12ac), /* MIB - Port2 */ -+ regmap_reg_range(0x1300, 0x13ac), /* MIB - Port3 */ -+ regmap_reg_range(0x1400, 0x14ac), /* MIB - Port4 */ -+ regmap_reg_range(0x1500, 0x15ac), /* MIB - Port5 */ -+ regmap_reg_range(0x1600, 0x16ac), /* MIB - Port6 */ -+ -+}; -+ -+static struct regmap_access_table ar8xxx_readable_table = { -+ .yes_ranges = ar8xxx_readable_ranges, -+ .n_yes_ranges = ARRAY_SIZE(ar8xxx_readable_ranges), -+}; -+ -+struct regmap_config ar8xxx_regmap_config = { -+ .reg_bits = 16, -+ .val_bits = 32, -+ .reg_stride = 4, -+ .max_register = 0x16ac, /* end MIB - Port6 range */ -+ .reg_read = ar8xxx_regmap_read, -+ .reg_write = ar8xxx_regmap_write, -+ .rd_table = &ar8xxx_readable_table, -+}; -+ - static int ar8xxx_set_pad_ctrl(struct dsa_switch *ds, int port, int mode) - { - int reg; -@@ -219,9 +270,17 @@ static int ar8xxx_set_pad_ctrl(struct dsa_switch *ds, int port, int mode) - - static int ar8xxx_setup(struct dsa_switch *ds) - { -+ struct ar8xxx_priv *priv = ds_to_priv(ds); - struct net_device *netdev = ds->dst->pd->of_netdev; - int ret, i, phy_mode; - -+ /* Start by setting up the register mapping */ -+ priv->regmap = devm_regmap_init(ds->master_dev, NULL, ds, -+ &ar8xxx_regmap_config); ++static inline void ++wait_for_page_switch(void) ++{ ++ udelay(5); ++} + -+ if (IS_ERR(priv->regmap)) -+ pr_warn("regmap initialization failed"); ++static inline void ++ar8xxx_reg_set(struct dsa_switch *ds, int reg, u32 val) ++{ ++ ar8xxx_rmw(ds, reg, 0, val); ++} + - /* Initialize CPU port pad mode (xMII type, delays...) */ - phy_mode = of_get_phy_mode(netdev->dev.parent->of_node); - if (phy_mode < 0) { -@@ -365,6 +424,7 @@ static void ar8xxx_poll_link(struct dsa_switch *ds) - - static struct dsa_switch_driver ar8xxx_switch_driver = { - .tag_protocol = DSA_TAG_PROTO_NONE, -+ .priv_size = sizeof(struct ar8xxx_priv), - .probe = ar8xxx_probe, - .setup = ar8xxx_setup, - .set_addr = ar8xxx_set_addr, -diff --git a/drivers/net/dsa/ar8xxx.h b/drivers/net/dsa/ar8xxx.h -index 7c7a125..98cc7ed 100644 ---- a/drivers/net/dsa/ar8xxx.h -+++ b/drivers/net/dsa/ar8xxx.h -@@ -17,6 +17,11 @@ - #define __AR8XXX_H - - #include -+#include ++static inline void ++ar8xxx_reg_clear(struct dsa_switch *ds, int reg, u32 val) ++{ ++ ar8xxx_rmw(ds, reg, val, 0); ++} + -+struct ar8xxx_priv { -+ struct regmap *regmap; -+}; ++#endif /* __AR8XXX_H */ +--- a/net/dsa/dsa.c ++++ b/net/dsa/dsa.c +@@ -285,6 +285,11 @@ static int dsa_switch_setup_one(struct d + dst->rcv = brcm_netdev_ops.rcv; + break; + #endif ++#ifdef CONFIG_NET_DSA_TAG_QCA ++ case DSA_TAG_PROTO_QCA: ++ dst->rcv = qca_netdev_ops.rcv; ++ break; ++#endif + case DSA_TAG_PROTO_NONE: + break; + default: +@@ -1041,6 +1046,7 @@ static SIMPLE_DEV_PM_OPS(dsa_pm_ops, dsa - struct ar8xxx_mib_desc { - unsigned int size; - -From patchwork Fri May 29 01:42:19 2015 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [4/7] net: dsa: add QCA tag support -From: Mathieu Olivari -X-Patchwork-Id: 477521 -X-Patchwork-Delegate: davem@davemloft.net -Message-Id: <1432863742-18427-5-git-send-email-mathieu@codeaurora.org> -To: robh+dt@kernel.org, pawel.moll@arm.com, mark.rutland@arm.com, - ijc+devicetree@hellion.org.uk, galak@codeaurora.org, - davem@davemloft.net, mathieu@codeaurora.org, andrew@lunn.ch, - f.fainelli@gmail.com, linux@roeck-us.net, gang.chen.5i5j@gmail.com, - jiri@resnulli.us, leitec@staticky.com, fabf@skynet.be, - alexander.h.duyck@intel.com, pavel.nakonechny@skitlab.ru, - joe@perches.com, sfeldma@gmail.com, nbd@openwrt.org, juhosg@openwrt.org -Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, - netdev@vger.kernel.org -Date: Thu, 28 May 2015 18:42:19 -0700 - -QCA tags are used on QCA ar8xxx switch family. This change adds support -for encap/decap using 2 bytes header mode. - -Signed-off-by: Mathieu Olivari ---- - include/net/dsa.h | 1 + - net/dsa/Kconfig | 3 + - net/dsa/Makefile | 1 + - net/dsa/dsa.c | 5 ++ - net/dsa/dsa_priv.h | 2 + - net/dsa/slave.c | 5 ++ - net/dsa/tag_qca.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++++ - 7 files changed, 175 insertions(+) - create mode 100644 net/dsa/tag_qca.c - -diff --git a/include/net/dsa.h b/include/net/dsa.h -index fbca63b..64ddf6f 100644 + static const struct of_device_id dsa_of_match_table[] = { + { .compatible = "brcm,bcm7445-switch-v4.0" }, ++ { .compatible = "qca,ar8xxx", }, + { .compatible = "marvell,dsa", }, + {} + }; --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -26,6 +26,7 @@ enum dsa_tag_protocol { @@ -925,8 +786,6 @@ index fbca63b..64ddf6f 100644 }; #define DSA_MAX_SWITCHES 4 -diff --git a/net/dsa/Kconfig b/net/dsa/Kconfig -index ff7736f..4f3cce1 100644 --- a/net/dsa/Kconfig +++ b/net/dsa/Kconfig @@ -26,6 +26,9 @@ config NET_DSA_HWMON @@ -939,8 +798,6 @@ index ff7736f..4f3cce1 100644 config NET_DSA_TAG_BRCM bool -diff --git a/net/dsa/Makefile b/net/dsa/Makefile -index da06ed1..9feb86c 100644 --- a/net/dsa/Makefile +++ b/net/dsa/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_NET_DSA) += dsa_core.o @@ -951,27 +808,9 @@ index da06ed1..9feb86c 100644 dsa_core-$(CONFIG_NET_DSA_TAG_BRCM) += tag_brcm.o dsa_core-$(CONFIG_NET_DSA_TAG_DSA) += tag_dsa.o dsa_core-$(CONFIG_NET_DSA_TAG_EDSA) += tag_edsa.o -diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c -index fffb9aa..6010a7d 100644 ---- a/net/dsa/dsa.c -+++ b/net/dsa/dsa.c -@@ -249,6 +249,11 @@ static int dsa_switch_setup_one(struct dsa_switch *ds, struct device *parent) - dst->rcv = brcm_netdev_ops.rcv; - break; - #endif -+#ifdef CONFIG_NET_DSA_TAG_QCA -+ case DSA_TAG_PROTO_QCA: -+ dst->rcv = qca_netdev_ops.rcv; -+ break; -+#endif - case DSA_TAG_PROTO_NONE: - break; - default: -diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h -index d5f1f9b..350c94b 100644 --- a/net/dsa/dsa_priv.h +++ b/net/dsa/dsa_priv.h -@@ -74,5 +74,7 @@ extern const struct dsa_device_ops trailer_netdev_ops; +@@ -78,5 +78,7 @@ extern const struct dsa_device_ops trail /* tag_brcm.c */ extern const struct dsa_device_ops brcm_netdev_ops; @@ -979,11 +818,9 @@ index d5f1f9b..350c94b 100644 +extern const struct dsa_device_ops qca_netdev_ops; #endif -diff --git a/net/dsa/slave.c b/net/dsa/slave.c -index 04ffad3..cd8f552 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c -@@ -925,6 +925,11 @@ int dsa_slave_create(struct dsa_switch *ds, struct device *parent, +@@ -1180,6 +1180,11 @@ int dsa_slave_create(struct dsa_switch * p->xmit = brcm_netdev_ops.xmit; break; #endif @@ -995,9 +832,6 @@ index 04ffad3..cd8f552 100644 default: p->xmit = dsa_slave_notag_xmit; break; -diff --git a/net/dsa/tag_qca.c b/net/dsa/tag_qca.c -new file mode 100644 -index 0000000..8f02196 --- /dev/null +++ b/net/dsa/tag_qca.c @@ -0,0 +1,158 @@ @@ -1159,293 +993,6 @@ index 0000000..8f02196 + .xmit = qca_tag_xmit, + .rcv = qca_tag_rcv, +}; - -From patchwork Fri May 29 01:42:20 2015 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [5/7] net: dsa: ar8xxx: enable QCA header support on AR8xxx -From: Mathieu Olivari -X-Patchwork-Id: 477527 -X-Patchwork-Delegate: davem@davemloft.net -Message-Id: <1432863742-18427-6-git-send-email-mathieu@codeaurora.org> -To: robh+dt@kernel.org, pawel.moll@arm.com, mark.rutland@arm.com, - ijc+devicetree@hellion.org.uk, galak@codeaurora.org, - davem@davemloft.net, mathieu@codeaurora.org, andrew@lunn.ch, - f.fainelli@gmail.com, linux@roeck-us.net, gang.chen.5i5j@gmail.com, - jiri@resnulli.us, leitec@staticky.com, fabf@skynet.be, - alexander.h.duyck@intel.com, pavel.nakonechny@skitlab.ru, - joe@perches.com, sfeldma@gmail.com, nbd@openwrt.org, juhosg@openwrt.org -Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, - netdev@vger.kernel.org -Date: Thu, 28 May 2015 18:42:20 -0700 - -This change enable support for the QCA headers in QCA83337 driver. -A 2 bytes header will be added by the switch on every incoming packet -to identify the ingress port, and the DSA tagging code will add a -similar 2 bytes header to control which port is used to send a -particular packet. - -Signed-off-by: Mathieu Olivari ---- - drivers/net/dsa/Kconfig | 1 + - drivers/net/dsa/ar8xxx.c | 28 ++++++++++++++++++++++++++-- - drivers/net/dsa/ar8xxx.h | 22 ++++++++++++++++++++++ - 3 files changed, 49 insertions(+), 2 deletions(-) - -diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig -index 17fb296..fa8b484 100644 ---- a/drivers/net/dsa/Kconfig -+++ b/drivers/net/dsa/Kconfig -@@ -68,6 +68,7 @@ config NET_DSA_BCM_SF2 - config NET_DSA_AR8XXX - tristate "Qualcomm Atheros AR8XXX Ethernet switch family support" - depends on NET_DSA -+ select NET_DSA_TAG_QCA - select REGMAP - ---help--- - This enables support for the Qualcomm Atheros AR8XXX Ethernet -diff --git a/drivers/net/dsa/ar8xxx.c b/drivers/net/dsa/ar8xxx.c -index 327abd4..4044614 100644 ---- a/drivers/net/dsa/ar8xxx.c -+++ b/drivers/net/dsa/ar8xxx.c -@@ -292,15 +292,31 @@ static int ar8xxx_setup(struct dsa_switch *ds) - if (ret < 0) - return ret; - -+ /* Enable CPU Port */ -+ ar8xxx_reg_set(ds, AR8327_REG_GLOBAL_FW_CTRL0, -+ AR8327_GLOBAL_FW_CTRL0_CPU_PORT_EN); -+ - /* Enable MIB counters */ - ar8xxx_reg_set(ds, AR8327_REG_MIB, AR8327_MIB_CPU_KEEP); - ar8xxx_write(ds, AR8327_REG_MODULE_EN, AR8327_MODULE_EN_MIB); - -+ /* Enable QCA header mode on Port 0 */ -+ ar8xxx_write(ds, AR8327_REG_PORT_HDR_CTRL(0), -+ AR8327_PORT_HDR_CTRL_ALL << AR8327_PORT_HDR_CTRL_TX_S | -+ AR8327_PORT_HDR_CTRL_ALL << AR8327_PORT_HDR_CTRL_RX_S); -+ - /* Disable forwarding by default on all ports */ - for (i = 0; i < AR8327_NUM_PORTS; i++) - ar8xxx_rmw(ds, AR8327_PORT_LOOKUP_CTRL(i), - AR8327_PORT_LOOKUP_MEMBER, 0); - -+ /* Forward all unknown frames to CPU port for Linux processing */ -+ ar8xxx_write(ds, AR8327_REG_GLOBAL_FW_CTRL1, -+ BIT(0) << AR8327_GLOBAL_FW_CTRL1_IGMP_DP_S | -+ BIT(0) << AR8327_GLOBAL_FW_CTRL1_BC_DP_S | -+ BIT(0) << AR8327_GLOBAL_FW_CTRL1_MC_DP_S | -+ BIT(0) << AR8327_GLOBAL_FW_CTRL1_UC_DP_S); -+ - /* Setup connection between CPU ports & PHYs */ - for (i = 0; i < DSA_MAX_PORTS; i++) { - /* CPU port gets connected to all PHYs in the switch */ -@@ -312,8 +328,16 @@ static int ar8xxx_setup(struct dsa_switch *ds) - - /* Invividual PHYs gets connected to CPU port only */ - if (ds->phys_port_mask & BIT(i)) { -- ar8xxx_rmw(ds, AR8327_PORT_LOOKUP_CTRL(phy_to_port(i)), -+ int phy = phy_to_port(i); -+ -+ ar8xxx_rmw(ds, AR8327_PORT_LOOKUP_CTRL(phy), - AR8327_PORT_LOOKUP_MEMBER, BIT(0)); -+ -+ /* Disable Auto-learning by default so the switch -+ * doesn't try to forward the frame to another port -+ */ -+ ar8xxx_reg_clear(ds, AR8327_PORT_LOOKUP_CTRL(phy), -+ AR8327_PORT_LOOKUP_LEARN); - } - } - -@@ -423,7 +447,7 @@ static void ar8xxx_poll_link(struct dsa_switch *ds) - } - - static struct dsa_switch_driver ar8xxx_switch_driver = { -- .tag_protocol = DSA_TAG_PROTO_NONE, -+ .tag_protocol = DSA_TAG_PROTO_QCA, - .priv_size = sizeof(struct ar8xxx_priv), - .probe = ar8xxx_probe, - .setup = ar8xxx_setup, -diff --git a/drivers/net/dsa/ar8xxx.h b/drivers/net/dsa/ar8xxx.h -index 98cc7ed..e68b92a 100644 ---- a/drivers/net/dsa/ar8xxx.h -+++ b/drivers/net/dsa/ar8xxx.h -@@ -62,6 +62,28 @@ struct ar8xxx_mib_desc { - #define AR8XXX_PORT_STATUS_LINK_AUTO BIT(9) - #define AR8XXX_PORT_STATUS_LINK_PAUSE BIT(10) - -+#define AR8327_REG_PORT_HDR_CTRL(_i) (0x9c + (_i * 4)) -+#define AR8327_PORT_HDR_CTRL_RX_MASK GENMASK(3, 2) -+#define AR8327_PORT_HDR_CTRL_RX_S 2 -+#define AR8327_PORT_HDR_CTRL_TX_MASK GENMASK(1, 0) -+#define AR8327_PORT_HDR_CTRL_TX_S 0 -+#define AR8327_PORT_HDR_CTRL_ALL 2 -+#define AR8327_PORT_HDR_CTRL_MGMT 1 -+#define AR8327_PORT_HDR_CTRL_NONE 0 -+ -+#define AR8327_REG_GLOBAL_FW_CTRL0 0x620 -+#define AR8327_GLOBAL_FW_CTRL0_CPU_PORT_EN BIT(10) -+ -+#define AR8327_REG_GLOBAL_FW_CTRL1 0x624 -+#define AR8327_GLOBAL_FW_CTRL1_IGMP_DP_MASK GENMASK(30, 24) -+#define AR8327_GLOBAL_FW_CTRL1_IGMP_DP_S 24 -+#define AR8327_GLOBAL_FW_CTRL1_BC_DP_MASK GENMASK(22, 16) -+#define AR8327_GLOBAL_FW_CTRL1_BC_DP_S 16 -+#define AR8327_GLOBAL_FW_CTRL1_MC_DP_MASK GENMASK(14, 8) -+#define AR8327_GLOBAL_FW_CTRL1_MC_DP_S 8 -+#define AR8327_GLOBAL_FW_CTRL1_UC_DP_MASK GENMASK(6, 0) -+#define AR8327_GLOBAL_FW_CTRL1_UC_DP_S 0 -+ - #define AR8327_PORT_LOOKUP_CTRL(_i) (0x660 + (_i) * 0xc) - #define AR8327_PORT_LOOKUP_MEMBER GENMASK(6, 0) - #define AR8327_PORT_LOOKUP_IN_MODE GENMASK(9, 8) - -From patchwork Fri May 29 01:42:21 2015 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [6/7] net: dsa: ar8xxx: add support for second xMII interfaces - through DT -From: Mathieu Olivari -X-Patchwork-Id: 477525 -X-Patchwork-Delegate: davem@davemloft.net -Message-Id: <1432863742-18427-7-git-send-email-mathieu@codeaurora.org> -To: robh+dt@kernel.org, pawel.moll@arm.com, mark.rutland@arm.com, - ijc+devicetree@hellion.org.uk, galak@codeaurora.org, - davem@davemloft.net, mathieu@codeaurora.org, andrew@lunn.ch, - f.fainelli@gmail.com, linux@roeck-us.net, gang.chen.5i5j@gmail.com, - jiri@resnulli.us, leitec@staticky.com, fabf@skynet.be, - alexander.h.duyck@intel.com, pavel.nakonechny@skitlab.ru, - joe@perches.com, sfeldma@gmail.com, nbd@openwrt.org, juhosg@openwrt.org -Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, - netdev@vger.kernel.org -Date: Thu, 28 May 2015 18:42:21 -0700 - -This patch is adding support for port6 specific options to device tree. -They can be used to setup the second xMII interface, and connect it to -one of the switch port. - -Signed-off-by: Mathieu Olivari ---- - drivers/net/dsa/ar8xxx.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 50 insertions(+) - -diff --git a/drivers/net/dsa/ar8xxx.c b/drivers/net/dsa/ar8xxx.c -index 4044614..7559249 100644 ---- a/drivers/net/dsa/ar8xxx.c -+++ b/drivers/net/dsa/ar8xxx.c -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - - #include "ar8xxx.h" - -@@ -260,6 +261,9 @@ static int ar8xxx_set_pad_ctrl(struct dsa_switch *ds, int port, int mode) - ar8xxx_write(ds, AR8327_REG_PORT5_PAD_CTRL, - AR8327_PORT_PAD_RGMII_RX_DELAY_EN); - break; -+ case PHY_INTERFACE_MODE_SGMII: -+ ar8xxx_write(ds, reg, AR8327_PORT_PAD_SGMII_EN); -+ break; - default: - pr_err("xMII mode %d not supported\n", mode); - return -EINVAL; -@@ -268,6 +272,48 @@ static int ar8xxx_set_pad_ctrl(struct dsa_switch *ds, int port, int mode) - return 0; - } - -+static int ar8xxx_of_setup(struct dsa_switch *ds) -+{ -+ struct device_node *dn = ds->pd->of_node; -+ const char *s_phymode; -+ int ret, mode; -+ u32 phy_id, ctrl; -+ -+ /* If port6-phy-mode property exists, configure it accordingly */ -+ if (!of_property_read_string(dn, "qca,port6-phy-mode", &s_phymode)) { -+ for (mode = 0; mode < PHY_INTERFACE_MODE_MAX; mode++) -+ if (!strcasecmp(s_phymode, phy_modes(mode))) -+ break; -+ -+ if (mode == PHY_INTERFACE_MODE_MAX) -+ pr_err("Unknown phy-mode: \"%s\"\n", s_phymode); -+ -+ ret = ar8xxx_set_pad_ctrl(ds, 6, mode); -+ if (ret < 0) -+ return ret; -+ } -+ -+ /* If a phy ID is specified for PORT6 mac, connect them together */ -+ if (!of_property_read_u32(dn, "qca,port6-phy-id", &phy_id)) { -+ ar8xxx_rmw(ds, AR8327_PORT_LOOKUP_CTRL(6), -+ AR8327_PORT_LOOKUP_MEMBER, BIT(phy_to_port(phy_id))); -+ ar8xxx_rmw(ds, AR8327_PORT_LOOKUP_CTRL(phy_to_port(phy_id)), -+ AR8327_PORT_LOOKUP_MEMBER, BIT(6)); -+ -+ /* We want the switch to be pass-through and act like a PHY on -+ * these ports. So BC/MC/UC & IGMP frames need to be accepted -+ */ -+ ctrl = BIT(phy_to_port(phy_id)) | BIT(6); -+ ar8xxx_reg_set(ds, AR8327_REG_GLOBAL_FW_CTRL1, -+ ctrl << AR8327_GLOBAL_FW_CTRL1_IGMP_DP_S | -+ ctrl << AR8327_GLOBAL_FW_CTRL1_BC_DP_S | -+ ctrl << AR8327_GLOBAL_FW_CTRL1_MC_DP_S | -+ ctrl << AR8327_GLOBAL_FW_CTRL1_UC_DP_S); -+ } -+ -+ return 0; -+} -+ - static int ar8xxx_setup(struct dsa_switch *ds) - { - struct ar8xxx_priv *priv = ds_to_priv(ds); -@@ -341,6 +387,10 @@ static int ar8xxx_setup(struct dsa_switch *ds) - } - } - -+ ret = ar8xxx_of_setup(ds); -+ if (ret < 0) -+ return ret; -+ - return 0; - } - - -From patchwork Fri May 29 01:42:22 2015 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [7/7] Documentation: devicetree: add ar8xxx binding -From: Mathieu Olivari -X-Patchwork-Id: 477528 -X-Patchwork-Delegate: davem@davemloft.net -Message-Id: <1432863742-18427-8-git-send-email-mathieu@codeaurora.org> -To: robh+dt@kernel.org, pawel.moll@arm.com, mark.rutland@arm.com, - ijc+devicetree@hellion.org.uk, galak@codeaurora.org, - davem@davemloft.net, mathieu@codeaurora.org, andrew@lunn.ch, - f.fainelli@gmail.com, linux@roeck-us.net, gang.chen.5i5j@gmail.com, - jiri@resnulli.us, leitec@staticky.com, fabf@skynet.be, - alexander.h.duyck@intel.com, pavel.nakonechny@skitlab.ru, - joe@perches.com, sfeldma@gmail.com, nbd@openwrt.org, juhosg@openwrt.org -Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, - netdev@vger.kernel.org -Date: Thu, 28 May 2015 18:42:22 -0700 - -Add device-tree binding for ar8xxx switch families. - -Signed-off-by: Mathieu Olivari ---- - .../devicetree/bindings/net/dsa/qca-ar8xxx.txt | 70 ++++++++++++++++++++++ - 1 file changed, 70 insertions(+) - create mode 100644 Documentation/devicetree/bindings/net/dsa/qca-ar8xxx.txt - -diff --git a/Documentation/devicetree/bindings/net/dsa/qca-ar8xxx.txt b/Documentation/devicetree/bindings/net/dsa/qca-ar8xxx.txt -new file mode 100644 -index 0000000..f4fd3f1 --- /dev/null +++ b/Documentation/devicetree/bindings/net/dsa/qca-ar8xxx.txt @@ -0,0 +1,70 @@ -- cgit v1.2.3