* Re: [PATCH 6/7] MIPS: mscc: add DT for Ocelot PCB120
From: Alexandre Belloni @ 2018-09-14 14:58 UTC (permalink / raw)
To: Quentin Schulz
Cc: ralf, paul.burton, jhogan, robh+dt, mark.rutland, davem, andrew,
f.fainelli, allan.nielsen, linux-mips, devicetree, linux-kernel,
netdev, thomas.petazzoni, antoine.tenart
In-Reply-To: <f2ef1137991cabde5e9529403982d84b5b0fe0a6.1536916714.git-series.quentin.schulz@bootlin.com>
On 14/09/2018 11:44:27+0200, Quentin Schulz wrote:
> The Ocelot PCB120 evaluation board is different from the PCB123 in that
> it has 4 external VSC8584 (or VSC8574) PHYs.
>
> It uses the SoC's second MDIO bus for external PHYs which have a
> reversed address on the bus (i.e. PHY4 is on address 3, PHY5 is on
> address 2, PHY6 on 1 and PHY7 on 0).
>
> Here is how the PHYs are connected to the switch ports:
> port 0: phy0 (internal)
> port 1: phy1 (internal)
> port 2: phy2 (internal)
> port 3: phy3 (internal)
> port 4: phy7
> port 5: phy4
> port 6: phy6
> port 9: phy5
>
> Signed-off-by: Quentin Schulz <quentin.schulz@bootlin.com>
Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
> ---
> arch/mips/boot/dts/mscc/Makefile | 2 +-
> arch/mips/boot/dts/mscc/ocelot_pcb120.dts | 100 +++++++++++++++++++++++-
> 2 files changed, 101 insertions(+), 1 deletion(-)
> create mode 100644 arch/mips/boot/dts/mscc/ocelot_pcb120.dts
>
> diff --git a/arch/mips/boot/dts/mscc/Makefile b/arch/mips/boot/dts/mscc/Makefile
> index 9a9bb7e..ec6f5b2 100644
> --- a/arch/mips/boot/dts/mscc/Makefile
> +++ b/arch/mips/boot/dts/mscc/Makefile
> @@ -1,3 +1,3 @@
> -dtb-$(CONFIG_MSCC_OCELOT) += ocelot_pcb123.dtb
> +dtb-$(CONFIG_MSCC_OCELOT) += ocelot_pcb123.dtb ocelot_pcb120.dtb
>
> obj-$(CONFIG_BUILTIN_DTB) += $(addsuffix .o, $(dtb-y))
> diff --git a/arch/mips/boot/dts/mscc/ocelot_pcb120.dts b/arch/mips/boot/dts/mscc/ocelot_pcb120.dts
> new file mode 100644
> index 0000000..8eb03a5
> --- /dev/null
> +++ b/arch/mips/boot/dts/mscc/ocelot_pcb120.dts
> @@ -0,0 +1,100 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/* Copyright (c) 2017 Microsemi Corporation */
> +
> +/dts-v1/;
> +
> +#include <dt-bindings/interrupt-controller/irq.h>
> +#include <dt-bindings/phy/phy-ocelot-serdes.h>
> +#include "ocelot.dtsi"
> +
> +/ {
> + compatible = "mscc,ocelot-pcb120", "mscc,ocelot";
> +
> + chosen {
> + stdout-path = "serial0:115200n8";
> + };
> +
> + memory@0 {
> + device_type = "memory";
> + reg = <0x0 0x0e000000>;
> + };
> +};
> +
> +&mdio0 {
> + status = "okay";
> +};
> +
> +&mdio1 {
> + status = "okay";
> + pinctrl-names = "default";
> + pinctrl-0 = <&miim1>, <&gpio4>;
> +
> + phy7: ethernet-phy@0 {
> + reg = <0>;
> + interrupts = <4 IRQ_TYPE_LEVEL_HIGH>;
> + interrupt-parent = <&gpio>;
> + };
> + phy6: ethernet-phy@1 {
> + reg = <1>;
> + interrupts = <4 IRQ_TYPE_LEVEL_HIGH>;
> + interrupt-parent = <&gpio>;
> + };
> + phy5: ethernet-phy@2 {
> + reg = <2>;
> + interrupts = <4 IRQ_TYPE_LEVEL_HIGH>;
> + interrupt-parent = <&gpio>;
> + };
> + phy4: ethernet-phy@3 {
> + reg = <3>;
> + interrupts = <4 IRQ_TYPE_LEVEL_HIGH>;
> + interrupt-parent = <&gpio>;
> + };
> +};
> +
> +&port0 {
> + phy-handle = <&phy0>;
> +};
> +
> +&port1 {
> + phy-handle = <&phy1>;
> +};
> +
> +&port2 {
> + phy-handle = <&phy2>;
> +};
> +
> +&port3 {
> + phy-handle = <&phy3>;
> +};
> +
> +&port4 {
> + phy-handle = <&phy7>;
> + phy-mode = "sgmii";
> + phys = <&serdes 4 SERDES1G_2>;
> +};
> +
> +&port5 {
> + phy-handle = <&phy4>;
> + phy-mode = "sgmii";
> + phys = <&serdes 5 SERDES1G_5>;
> +};
> +
> +&port6 {
> + phy-handle = <&phy6>;
> + phy-mode = "sgmii";
> + phys = <&serdes 6 SERDES1G_3>;
> +};
> +
> +&port9 {
> + phy-handle = <&phy5>;
> + phy-mode = "sgmii";
> + phys = <&serdes 9 SERDES1G_4>;
> +};
> +
> +&uart0 {
> + status = "okay";
> +};
> +
> +&uart2 {
> + status = "okay";
> +};
> --
> git-series 0.9.1
--
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* [PATCH net-next 2/7] net: phy: mscc: add support for VSC8584 PHY
From: Quentin Schulz @ 2018-09-14 9:44 UTC (permalink / raw)
To: alexandre.belloni, ralf, paul.burton, jhogan, robh+dt,
mark.rutland, davem, andrew, f.fainelli
Cc: allan.nielsen, linux-mips, devicetree, linux-kernel, netdev,
thomas.petazzoni, antoine.tenart, Quentin Schulz
In-Reply-To: <cover.b921b010b6d6bde1c11e69551ae38f3b2818645b.1536916714.git-series.quentin.schulz@bootlin.com>
The VSC8584 PHY is a 4-ports PHY that is 10/100/1000BASE-T, 100BASE-FX,
1000BASE-X and triple-speed copper SFP capable, can communicate with the
MAC via SGMII, QSGMII or 1000BASE-X, supports downshifting and can set
the blinking pattern of each of its 4 LEDs, supports hardware offloading
of MACsec and supports SyncE as well as HP Auto-MDIX detection.
This adds support for 10/100/1000BASE-T, SGMII/QSGMII link with the MAC,
downshifting, HP Auto-MDIX detection and blinking pattern for its 4
LEDs.
The VSC8584 has also an internal Intel 8051 microcontroller whose
firmware needs to be patched when the PHY is reset. If the 8051's
firmware has the expected CRC, its patching can be skipped. The
microcontroller can be accessed from any port of the PHY, though the CRC
function can only be done through the PHY that is the base PHY of the
package (internal address 0) due to a limitation of the firmware.
The GPIO register bank is a set of registers that are common to all PHYs
in the package. So any modification in any register of this bank affects
all PHYs of the package.
If the PHYs haven't been reset before booting the Linux kernel and were
configured to use interrupts for e.g. link status updates, it is
required to clear the interrupts mask register of all PHYs before being
able to use interrupts with any PHY. The first PHY of the package that
will be init will take care of clearing all PHYs interrupts mask
registers. Thus, we need to keep track of the init sequence in the
package, if it's already been done or if it's to be done.
Most of the init sequence of a PHY of the package is common to all PHYs
in the package, thus we use the SMI broadcast feature which enables us
to propagate a write in one register of one PHY to all PHYs in the
package.
The revA of the VSC8584 PHY (which is not and will not be publicly
released) should NOT patch the firmware of the microcontroller or it'll
make things worse, the easiest way is just to not support it.
Signed-off-by: Quentin Schulz <quentin.schulz@bootlin.com>
---
drivers/net/phy/mscc.c | 714 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 714 insertions(+)
diff --git a/drivers/net/phy/mscc.c b/drivers/net/phy/mscc.c
index 24f4754..b450489 100644
--- a/drivers/net/phy/mscc.c
+++ b/drivers/net/phy/mscc.c
@@ -6,6 +6,8 @@
* Copyright (c) 2016 Microsemi Corporation
*/
+#include <linux/firmware.h>
+#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mdio.h>
@@ -32,6 +34,10 @@ enum rgmii_rx_clock_delay {
#define DISABLE_HP_AUTO_MDIX_MASK 0x0080
#define DISABLE_PAIR_SWAP_CORR_MASK 0x0020
#define DISABLE_POLARITY_CORR_MASK 0x0010
+#define PARALLEL_DET_IGNORE_ADVERTISED 0x0008
+
+#define MSCC_PHY_EXT_CNTL_STATUS 22
+#define SMI_BROADCAST_WR_EN 0x0001
#define MSCC_PHY_ERR_RX_CNT 19
#define MSCC_PHY_ERR_FALSE_CARRIER_CNT 20
@@ -44,7 +50,20 @@ enum rgmii_rx_clock_delay {
#define MAC_IF_SELECTION_RMII 1
#define MAC_IF_SELECTION_RGMII 2
#define MAC_IF_SELECTION_POS 11
+#define VSC8584_MAC_IF_SELECTION_MASK 0x1000
+#define VSC8584_MAC_IF_SELECTION_SGMII 0
+#define VSC8584_MAC_IF_SELECTION_1000BASEX 1
+#define VSC8584_MAC_IF_SELECTION_POS 12
#define FAR_END_LOOPBACK_MODE_MASK 0x0008
+#define MEDIA_OP_MODE_MASK 0x0700
+#define MEDIA_OP_MODE_COPPER 0
+#define MEDIA_OP_MODE_SERDES 1
+#define MEDIA_OP_MODE_1000BASEX 2
+#define MEDIA_OP_MODE_100BASEFX 3
+#define MEDIA_OP_MODE_AMS_COPPER_SERDES 5
+#define MEDIA_OP_MODE_AMS_COPPER_1000BASEX 6
+#define MEDIA_OP_MODE_AMS_COPPER_100BASEFX 7
+#define MEDIA_OP_MODE_POS 8
#define MII_VSC85XX_INT_MASK 25
#define MII_VSC85XX_INT_MASK_MASK 0xa000
@@ -67,6 +86,13 @@ enum rgmii_rx_clock_delay {
#define MSCC_PHY_PAGE_STANDARD 0x0000 /* Standard registers */
#define MSCC_PHY_PAGE_EXTENDED 0x0001 /* Extended registers */
#define MSCC_PHY_PAGE_EXTENDED_2 0x0002 /* Extended reg - page 2 */
+#define MSCC_PHY_PAGE_EXTENDED_3 0x0003 /* Extended reg - page 3 */
+#define MSCC_PHY_PAGE_EXTENDED_4 0x0004 /* Extended reg - page 4 */
+/* Extended reg - GPIO; this is a bank of registers that are shared for all PHYs
+ * in the same package.
+ */
+#define MSCC_PHY_PAGE_EXTENDED_GPIO 0x0010 /* Extended reg - GPIO */
+#define MSCC_PHY_PAGE_TEST 0x2a30 /* Test reg */
#define MSCC_PHY_PAGE_TR 0x52b5 /* Token ring registers */
/* Extended Page 1 Registers */
@@ -79,13 +105,21 @@ enum rgmii_rx_clock_delay {
#define FORCE_MDI_CROSSOVER_MDI 0x0008
#define MSCC_PHY_ACTIPHY_CNTL 20
+#define PHY_ADDR_REVERSED 0x0200
#define DOWNSHIFT_CNTL_MASK 0x001C
#define DOWNSHIFT_EN 0x0010
#define DOWNSHIFT_CNTL_POS 2
#define MSCC_PHY_EXT_PHY_CNTL_4 23
+#define PHY_CNTL_4_ADDR_POS 11
+
+#define MSCC_PHY_VERIPHY_CNTL_2 25
+
+#define MSCC_PHY_VERIPHY_CNTL_3 26
/* Extended Page 2 Registers */
+#define MSCC_PHY_CU_PMD_TX_CNTL 16
+
#define MSCC_PHY_RGMII_CNTL 20
#define RGMII_RX_CLK_DELAY_MASK 0x0070
#define RGMII_RX_CLK_DELAY_POS 4
@@ -101,6 +135,70 @@ enum rgmii_rx_clock_delay {
#define SECURE_ON_ENABLE 0x8000
#define SECURE_ON_PASSWD_LEN_4 0x4000
+/* Extended Page 3 Registers */
+#define MSCC_PHY_SERDES_TX_VALID_CNT 21
+#define MSCC_PHY_SERDES_TX_CRC_ERR_CNT 22
+#define MSCC_PHY_SERDES_RX_VALID_CNT 28
+#define MSCC_PHY_SERDES_RX_CRC_ERR_CNT 29
+
+/* Extended page GPIO Registers */
+#define MSCC_DW8051_CNTL_STATUS 0
+#define MICRO_NSOFT_RESET 0x8000
+#define RUN_FROM_INT_ROM 0x4000
+#define AUTOINC_ADDR 0x2000
+#define PATCH_RAM_CLK 0x1000
+#define MICRO_PATCH_EN 0x0080
+#define DW8051_CLK_EN 0x0010
+#define MICRO_CLK_EN 0x0008
+#define MICRO_CLK_DIVIDE(x) ((x) >> 1)
+
+/* x Address in range 1-4 */
+#define MSCC_TRAP_ROM_ADDR(x) ((x) * 2 + 1)
+#define MSCC_PATCH_RAM_ADDR(x) (((x) + 1) * 2)
+#define MSCC_INT_MEM_ADDR 11
+
+#define MSCC_INT_MEM_CNTL 12
+#define READ_SFR 0x6000
+#define READ_PRAM 0x4000
+#define READ_ROM 0x2000
+#define READ_RAM 0x0000
+#define INT_MEM_WRITE_EN 0x1000
+#define EN_PATCH_RAM_TRAP_ADDR(x) (0x0100 << ((x) - 1))
+#define INT_MEM_DATA_M 0x00ff
+#define INT_MEM_DATA(x) (INT_MEM_DATA_M & (x))
+
+#define MSCC_PHY_PROC_CMD 18
+#define PROC_CMD_NCOMPLETED 0x8000
+#define PROC_CMD_FAILED 0x4000
+#define PROC_CMD_SGMII_PORT(x) ((x) << 8)
+#define PROC_CMD_FIBER_PORT(x) (0x0100 << (x) % 4)
+#define PROC_CMD_QSGMII_PORT 0x0c00
+#define PROC_CMD_RST_CONF_PORT 0x0080
+#define PROC_CMD_RECONF_PORT 0x0000
+#define PROC_CMD_READ_MOD_WRITE_PORT 0x0040
+#define PROC_CMD_WRITE 0x0040
+#define PROC_CMD_READ 0x0000
+#define PROC_CMD_FIBER_DISABLE 0x0020
+#define PROC_CMD_FIBER_100BASE_FX 0x0010
+#define PROC_CMD_FIBER_1000BASE_X 0x0000
+#define PROC_CMD_SGMII_MAC 0x0030
+#define PROC_CMD_QSGMII_MAC 0x0020
+#define PROC_CMD_NO_MAC_CONF 0x0000
+#define PROC_CMD_NOP 0x000f
+#define PROC_CMD_CRC16 0x0008
+#define PROC_CMD_FIBER_MEDIA_CONF 0x0001
+#define PROC_CMD_MCB_ACCESS_MAC_CONF 0x0000
+#define PROC_CMD_NCOMPLETED_TIMEOUT_MS 500
+
+#define MSCC_PHY_MAC_CFG_FASTLINK 19
+#define MAC_CFG_MASK 0xc000
+#define MAC_CFG_SGMII 0x0000
+#define MAC_CFG_QSGMII 0x4000
+
+/* Test page Registers */
+#define MSCC_PHY_TEST_PAGE_5 5
+#define MSCC_PHY_TEST_PAGE_8 8
+
/* Token ring page Registers */
#define MSCC_PHY_TR_CNTL 16
#define TR_WRITE 0x8000
@@ -113,6 +211,7 @@ enum rgmii_rx_clock_delay {
#define PHY_ID_VSC8531 0x00070570
#define PHY_ID_VSC8540 0x00070760
#define PHY_ID_VSC8541 0x00070770
+#define PHY_ID_VSC8584 0x000707c0
#define MSCC_VDDMAC_1500 1500
#define MSCC_VDDMAC_1800 1800
@@ -122,6 +221,24 @@ enum rgmii_rx_clock_delay {
#define DOWNSHIFT_COUNT_MAX 5
#define MAX_LEDS 4
+
+#define VSC8584_SUPP_LED_MODES (BIT(VSC8531_LINK_ACTIVITY) | \
+ BIT(VSC8531_LINK_1000_ACTIVITY) | \
+ BIT(VSC8531_LINK_100_ACTIVITY) | \
+ BIT(VSC8531_LINK_10_ACTIVITY) | \
+ BIT(VSC8531_LINK_100_1000_ACTIVITY) | \
+ BIT(VSC8531_LINK_10_1000_ACTIVITY) | \
+ BIT(VSC8531_LINK_10_100_ACTIVITY) | \
+ BIT(VSC8584_LINK_100FX_1000X_ACTIVITY) | \
+ BIT(VSC8531_DUPLEX_COLLISION) | \
+ BIT(VSC8531_COLLISION) | \
+ BIT(VSC8531_ACTIVITY) | \
+ BIT(VSC8584_100FX_1000X_ACTIVITY) | \
+ BIT(VSC8531_AUTONEG_FAULT) | \
+ BIT(VSC8531_SERIAL_MODE) | \
+ BIT(VSC8531_FORCE_LED_OFF) | \
+ BIT(VSC8531_FORCE_LED_ON))
+
#define VSC85XX_SUPP_LED_MODES (BIT(VSC8531_LINK_ACTIVITY) | \
BIT(VSC8531_LINK_1000_ACTIVITY) | \
BIT(VSC8531_LINK_100_ACTIVITY) | \
@@ -137,6 +254,13 @@ enum rgmii_rx_clock_delay {
BIT(VSC8531_FORCE_LED_OFF) | \
BIT(VSC8531_FORCE_LED_ON))
+#define MSCC_VSC8584_REVB_INT8051_FW "mscc_vsc8584_revb_int8051_fb48.bin"
+#define MSCC_VSC8584_REVB_INT8051_FW_START_ADDR 0xe800
+#define MSCC_VSC8584_REVB_INT8051_FW_CRC 0xfb48
+
+#define VSC8584_REVB 0x0001
+#define MSCC_DEV_REV_MASK GENMASK(3, 0)
+
struct vsc85xx_hw_stat {
const char *string;
u8 reg;
@@ -173,6 +297,55 @@ static struct vsc85xx_hw_stat vsc85xx_hw_stats[] = {
},
};
+static struct vsc85xx_hw_stat vsc8584_hw_stats[] = {
+ {
+ .string = "phy_receive_errors",
+ .reg = MSCC_PHY_ERR_RX_CNT,
+ .page = MSCC_PHY_PAGE_STANDARD,
+ .mask = ERR_CNT_MASK,
+ }, {
+ .string = "phy_false_carrier",
+ .reg = MSCC_PHY_ERR_FALSE_CARRIER_CNT,
+ .page = MSCC_PHY_PAGE_STANDARD,
+ .mask = ERR_CNT_MASK,
+ }, {
+ .string = "phy_cu_media_link_disconnect",
+ .reg = MSCC_PHY_ERR_LINK_DISCONNECT_CNT,
+ .page = MSCC_PHY_PAGE_STANDARD,
+ .mask = ERR_CNT_MASK,
+ }, {
+ .string = "phy_cu_media_crc_good_count",
+ .reg = MSCC_PHY_CU_MEDIA_CRC_VALID_CNT,
+ .page = MSCC_PHY_PAGE_EXTENDED,
+ .mask = VALID_CRC_CNT_CRC_MASK,
+ }, {
+ .string = "phy_cu_media_crc_error_count",
+ .reg = MSCC_PHY_EXT_PHY_CNTL_4,
+ .page = MSCC_PHY_PAGE_EXTENDED,
+ .mask = ERR_CNT_MASK,
+ }, {
+ .string = "phy_serdes_tx_good_pkt_count",
+ .reg = MSCC_PHY_SERDES_TX_VALID_CNT,
+ .page = MSCC_PHY_PAGE_EXTENDED_3,
+ .mask = VALID_CRC_CNT_CRC_MASK,
+ }, {
+ .string = "phy_serdes_tx_bad_crc_count",
+ .reg = MSCC_PHY_SERDES_TX_CRC_ERR_CNT,
+ .page = MSCC_PHY_PAGE_EXTENDED_3,
+ .mask = ERR_CNT_MASK,
+ }, {
+ .string = "phy_serdes_rx_good_pkt_count",
+ .reg = MSCC_PHY_SERDES_RX_VALID_CNT,
+ .page = MSCC_PHY_PAGE_EXTENDED_3,
+ .mask = VALID_CRC_CNT_CRC_MASK,
+ }, {
+ .string = "phy_serdes_rx_bad_crc_count",
+ .reg = MSCC_PHY_SERDES_RX_CRC_ERR_CNT,
+ .page = MSCC_PHY_PAGE_EXTENDED_3,
+ .mask = ERR_CNT_MASK,
+ },
+};
+
struct vsc8531_private {
int rate_magic;
u16 supp_led_modes;
@@ -181,6 +354,7 @@ struct vsc8531_private {
struct vsc85xx_hw_stat *hw_stats;
u64 *stats;
int nstats;
+ bool pkg_init;
};
#ifdef CONFIG_OF_MDIO
@@ -730,6 +904,481 @@ static int vsc85xx_eee_init_seq_set(struct phy_device *phydev)
return rc;
}
+/* bus->mdio_lock should be locked when using this function */
+static void vsc8584_csr_write(struct mii_bus *bus, int phy, u16 addr, u32 val)
+{
+ __mdiobus_write(bus, phy, MSCC_PHY_TR_MSB, val >> 16);
+ __mdiobus_write(bus, phy, MSCC_PHY_TR_LSB, val & GENMASK(15, 0));
+ __mdiobus_write(bus, phy, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(addr));
+}
+
+/* bus->mdio_lock should be locked when using this function */
+static int vsc8584_cmd(struct mii_bus *bus, int phy, u16 val)
+{
+ unsigned long deadline;
+ u16 reg_val;
+
+ __mdiobus_write(bus, phy, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_EXTENDED_GPIO);
+
+ __mdiobus_write(bus, phy, MSCC_PHY_PROC_CMD, PROC_CMD_NCOMPLETED | val);
+
+ deadline = jiffies + msecs_to_jiffies(PROC_CMD_NCOMPLETED_TIMEOUT_MS);
+ do {
+ reg_val = __mdiobus_read(bus, phy, MSCC_PHY_PROC_CMD);
+ } while (time_before(jiffies, deadline) &&
+ (reg_val & PROC_CMD_NCOMPLETED) &&
+ !(reg_val & PROC_CMD_FAILED));
+
+ __mdiobus_write(bus, phy, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
+
+ if (reg_val & PROC_CMD_FAILED)
+ return -EIO;
+
+ if (reg_val & PROC_CMD_NCOMPLETED)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+/* bus->mdio_lock should be locked when using this function */
+static int vsc8584_micro_deassert_reset(struct mii_bus *bus, int phy,
+ bool patch_en)
+{
+ u32 enable, release;
+
+ __mdiobus_write(bus, phy, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_EXTENDED_GPIO);
+
+ enable = RUN_FROM_INT_ROM | MICRO_CLK_EN | DW8051_CLK_EN;
+ release = MICRO_NSOFT_RESET | RUN_FROM_INT_ROM | DW8051_CLK_EN |
+ MICRO_CLK_EN;
+
+ if (patch_en) {
+ enable |= MICRO_PATCH_EN;
+ release |= MICRO_PATCH_EN;
+
+ /* Clear all patches */
+ __mdiobus_write(bus, phy, MSCC_INT_MEM_CNTL, READ_RAM);
+ }
+
+ /* Enable 8051 Micro clock; CLEAR/SET patch present; disable PRAM clock
+ * override and addr. auto-incr; operate at 125 MHz
+ */
+ __mdiobus_write(bus, phy, MSCC_DW8051_CNTL_STATUS, enable);
+ /* Release 8051 Micro SW reset */
+ __mdiobus_write(bus, phy, MSCC_DW8051_CNTL_STATUS, release);
+
+ __mdiobus_write(bus, phy, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
+
+ return 0;
+}
+
+/* bus->mdio_lock should be locked when using this function */
+static int vsc8584_micro_assert_reset(struct mii_bus *bus, int phy)
+{
+ int ret;
+ u16 reg;
+
+ ret = vsc8584_cmd(bus, phy, PROC_CMD_NOP);
+ if (ret)
+ return ret;
+
+ __mdiobus_write(bus, phy, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_EXTENDED_GPIO);
+
+ reg = __mdiobus_read(bus, phy, MSCC_INT_MEM_CNTL);
+ reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
+ __mdiobus_write(bus, phy, MSCC_INT_MEM_CNTL, reg);
+
+ __mdiobus_write(bus, phy, MSCC_TRAP_ROM_ADDR(4), 0x005b);
+ __mdiobus_write(bus, phy, MSCC_PATCH_RAM_ADDR(4), 0x005b);
+
+ reg = __mdiobus_read(bus, phy, MSCC_INT_MEM_CNTL);
+ reg |= EN_PATCH_RAM_TRAP_ADDR(4);
+ __mdiobus_write(bus, phy, MSCC_INT_MEM_CNTL, reg);
+
+ __mdiobus_write(bus, phy, MSCC_PHY_PROC_CMD, PROC_CMD_NOP);
+
+ reg = __mdiobus_read(bus, phy, MSCC_DW8051_CNTL_STATUS);
+ reg &= ~MICRO_NSOFT_RESET;
+ __mdiobus_write(bus, phy, MSCC_DW8051_CNTL_STATUS, reg);
+
+ __mdiobus_write(bus, phy, MSCC_PHY_PROC_CMD,
+ PROC_CMD_MCB_ACCESS_MAC_CONF |
+ PROC_CMD_SGMII_PORT(0) | PROC_CMD_NO_MAC_CONF |
+ PROC_CMD_READ);
+
+ reg = __mdiobus_read(bus, phy, MSCC_INT_MEM_CNTL);
+ reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
+ __mdiobus_write(bus, phy, MSCC_INT_MEM_CNTL, reg);
+
+ __mdiobus_write(bus, phy, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
+
+ return 0;
+}
+
+/* bus->mdio_lock should be locked when using this function */
+static int vsc8584_get_fw_crc(struct mii_bus *bus, int phy, u16 start,
+ u16 size, u16 *crc)
+{
+ int ret;
+
+ __mdiobus_write(bus, phy, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
+
+ __mdiobus_write(bus, phy, MSCC_PHY_VERIPHY_CNTL_2, start);
+ __mdiobus_write(bus, phy, MSCC_PHY_VERIPHY_CNTL_3, size);
+
+ /* Start Micro command */
+ ret = vsc8584_cmd(bus, phy, PROC_CMD_CRC16);
+ if (ret)
+ goto out;
+
+ __mdiobus_write(bus, phy, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
+
+ *crc = __mdiobus_read(bus, phy, MSCC_PHY_VERIPHY_CNTL_2);
+
+out:
+ __mdiobus_write(bus, phy, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
+
+ return ret;
+}
+
+/* bus->mdio_lock should be locked when using this function */
+static int vsc8584_patch_fw(struct mii_bus *bus, int phy,
+ const struct firmware *fw)
+{
+ int i, ret;
+
+ ret = vsc8584_micro_assert_reset(bus, phy);
+ if (ret) {
+ dev_err(&bus->mdio_map[phy]->dev,
+ "%s: failed to assert reset of micro\n", __func__);
+ return ret;
+ }
+
+ __mdiobus_write(bus, phy, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_EXTENDED_GPIO);
+
+ /* Hold 8051 Micro in SW Reset, Enable auto incr address and patch clock
+ * Disable the 8051 Micro clock
+ */
+ __mdiobus_write(bus, phy, MSCC_DW8051_CNTL_STATUS, RUN_FROM_INT_ROM |
+ AUTOINC_ADDR | PATCH_RAM_CLK | MICRO_CLK_EN |
+ MICRO_CLK_DIVIDE(2));
+ __mdiobus_write(bus, phy, MSCC_INT_MEM_CNTL, READ_PRAM |
+ INT_MEM_WRITE_EN | INT_MEM_DATA(2));
+ __mdiobus_write(bus, phy, MSCC_INT_MEM_ADDR, 0x0000);
+
+ for (i = 0; i < fw->size; i++)
+ __mdiobus_write(bus, phy, MSCC_INT_MEM_CNTL, READ_PRAM |
+ INT_MEM_WRITE_EN | fw->data[i]);
+
+ /* Clear internal memory access */
+ __mdiobus_write(bus, phy, MSCC_INT_MEM_CNTL, READ_RAM);
+
+ __mdiobus_write(bus, phy, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
+
+ return 0;
+}
+
+/* bus->mdio_lock should be locked when using this function */
+static int vsc8584_config_pre_init(struct mii_bus *bus, int phy)
+{
+ struct device *dev = &bus->mdio_map[phy]->dev;
+ const struct firmware *fw;
+ u16 crc, reg;
+ int ret;
+
+ __mdiobus_write(bus, phy, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
+
+ /* all writes below this line are broadcasted to all PHYs */
+ reg = __mdiobus_read(bus, phy, MSCC_PHY_EXT_CNTL_STATUS);
+ reg |= SMI_BROADCAST_WR_EN;
+ __mdiobus_write(bus, phy, MSCC_PHY_EXT_CNTL_STATUS, reg);
+
+ __mdiobus_write(bus, phy, MII_VSC85XX_INT_MASK, 0);
+
+ reg = __mdiobus_read(bus, phy, MSCC_PHY_BYPASS_CONTROL);
+ reg |= PARALLEL_DET_IGNORE_ADVERTISED;
+ __mdiobus_write(bus, phy, MSCC_PHY_BYPASS_CONTROL, reg);
+
+ /* The below register writes are tweaking analog and electrical
+ * configuration that were determined through characterization by PHY
+ * engineers. These don't mean anything more than "these are the best
+ * values".
+ */
+ __mdiobus_write(bus, phy, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_EXTENDED_3);
+
+ __mdiobus_write(bus, phy, MSCC_PHY_SERDES_TX_CRC_ERR_CNT, 0x2000);
+
+ __mdiobus_write(bus, phy, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
+
+ __mdiobus_write(bus, phy, MSCC_PHY_TEST_PAGE_5, 0x1f20);
+
+ reg = __mdiobus_read(bus, phy, MSCC_PHY_TEST_PAGE_8);
+ reg |= 0x8000;
+ __mdiobus_write(bus, phy, MSCC_PHY_TEST_PAGE_8, reg);
+
+ __mdiobus_write(bus, phy, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
+
+ __mdiobus_write(bus, phy, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(0x2fa4));
+
+ reg = __mdiobus_read(bus, phy, MSCC_PHY_TR_MSB);
+ reg &= ~0x007f;
+ reg |= 0x0019;
+ __mdiobus_write(bus, phy, MSCC_PHY_TR_MSB, reg);
+
+ __mdiobus_write(bus, phy, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(0x0fa4));
+
+ vsc8584_csr_write(bus, phy, 0x07fa, 0x0050100f);
+ vsc8584_csr_write(bus, phy, 0x1688, 0x00049f81);
+ vsc8584_csr_write(bus, phy, 0x0f90, 0x00688980);
+ vsc8584_csr_write(bus, phy, 0x03a4, 0x0000d8f0);
+ vsc8584_csr_write(bus, phy, 0x0fc0, 0x00000400);
+ vsc8584_csr_write(bus, phy, 0x0f82, 0x0012b002);
+ vsc8584_csr_write(bus, phy, 0x1686, 0x00000004);
+ vsc8584_csr_write(bus, phy, 0x168c, 0x00d2c46f);
+ vsc8584_csr_write(bus, phy, 0x17a2, 0x00000620);
+ vsc8584_csr_write(bus, phy, 0x16a0, 0x00eeffdd);
+ vsc8584_csr_write(bus, phy, 0x16a6, 0x00071448);
+ vsc8584_csr_write(bus, phy, 0x16a4, 0x0013132f);
+ vsc8584_csr_write(bus, phy, 0x16a8, 0x00000000);
+ vsc8584_csr_write(bus, phy, 0x0ffc, 0x00c0a028);
+ vsc8584_csr_write(bus, phy, 0x0fe8, 0x0091b06c);
+ vsc8584_csr_write(bus, phy, 0x0fea, 0x00041600);
+ vsc8584_csr_write(bus, phy, 0x0f80, 0x00fffaff);
+ vsc8584_csr_write(bus, phy, 0x0fec, 0x00901809);
+ vsc8584_csr_write(bus, phy, 0x0ffe, 0x00b01007);
+ vsc8584_csr_write(bus, phy, 0x16b0, 0x00eeff00);
+ vsc8584_csr_write(bus, phy, 0x16b2, 0x00007000);
+ vsc8584_csr_write(bus, phy, 0x16b4, 0x00000814);
+
+ __mdiobus_write(bus, phy, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_EXTENDED_2);
+
+ __mdiobus_write(bus, phy, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
+
+ __mdiobus_write(bus, phy, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
+
+ vsc8584_csr_write(bus, phy, 0x0486, 0x0008a518);
+ vsc8584_csr_write(bus, phy, 0x0488, 0x006dc696);
+ vsc8584_csr_write(bus, phy, 0x048a, 0x00000912);
+
+ __mdiobus_write(bus, phy, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TEST);
+
+ reg = __mdiobus_read(bus, phy, MSCC_PHY_TEST_PAGE_8);
+ reg &= ~0x8000;
+ __mdiobus_write(bus, phy, MSCC_PHY_TEST_PAGE_8, reg);
+
+ __mdiobus_write(bus, phy, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
+
+ /* end of write broadcasting */
+ reg = __mdiobus_read(bus, phy, MSCC_PHY_EXT_CNTL_STATUS);
+ reg &= ~SMI_BROADCAST_WR_EN;
+ __mdiobus_write(bus, phy, MSCC_PHY_EXT_CNTL_STATUS, reg);
+
+ ret = request_firmware(&fw, MSCC_VSC8584_REVB_INT8051_FW, dev);
+ if (ret) {
+ dev_err(dev, "failed to load firmware %s, ret: %d\n",
+ MSCC_VSC8584_REVB_INT8051_FW, ret);
+ return ret;
+ }
+
+ /* Add one byte to size for the one added by the patch_fw function */
+ ret = vsc8584_get_fw_crc(bus, phy,
+ MSCC_VSC8584_REVB_INT8051_FW_START_ADDR,
+ fw->size + 1, &crc);
+ if (ret)
+ goto out;
+
+ if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC) {
+ dev_dbg(dev, "FW CRC is not the expected one, patching FW\n");
+ if (vsc8584_patch_fw(bus, phy, fw))
+ dev_warn(dev,
+ "failed to patch FW, expect non-optimal device\n");
+ }
+
+ vsc8584_micro_deassert_reset(bus, phy, false);
+
+ /* Add one byte to size for the one added by the patch_fw function */
+ ret = vsc8584_get_fw_crc(bus, phy,
+ MSCC_VSC8584_REVB_INT8051_FW_START_ADDR,
+ fw->size + 1, &crc);
+ if (ret)
+ goto out;
+
+ if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC)
+ dev_warn(dev,
+ "FW CRC after patching is not the expected one, expect non-optimal device\n");
+
+ ret = vsc8584_micro_assert_reset(bus, phy);
+ if (ret)
+ goto out;
+
+ vsc8584_micro_deassert_reset(bus, phy, true);
+
+out:
+ __mdiobus_write(bus, phy, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
+
+ release_firmware(fw);
+
+ return ret;
+}
+
+/* Check if one PHY has already done the init of the parts common to all PHYs
+ * in the Quad PHY package.
+ */
+static bool vsc8584_is_pkg_init(struct phy_device *phydev, int phy0,
+ bool reversed)
+{
+ struct mdio_device **map = phydev->mdio.bus->mdio_map;
+ struct vsc8531_private *vsc8531;
+ struct phy_device *phy;
+ int i, addr;
+
+ /* VSC8584 is a Quad PHY */
+ for (i = 0; i < 4; i++) {
+ if (reversed)
+ addr = phy0 - i;
+ else
+ addr = phy0 + i;
+
+ phy = container_of(map[addr], struct phy_device, mdio);
+
+ if ((phy->phy_id & phydev->drv->phy_id_mask) !=
+ (phydev->drv->phy_id & phydev->drv->phy_id_mask))
+ continue;
+
+ vsc8531 = phy->priv;
+
+ if (vsc8531 && vsc8531->pkg_init)
+ return true;
+ }
+
+ return false;
+}
+
+static int vsc8584_config_init(struct phy_device *phydev)
+{
+ struct vsc8531_private *vsc8531 = phydev->priv;
+ u16 addr, val, base_addr;
+ int ret, i;
+
+ phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
+
+ mutex_lock(&phydev->mdio.bus->mdio_lock);
+
+ __mdiobus_write(phydev->mdio.bus, phydev->mdio.addr,
+ MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED);
+ addr = __mdiobus_read(phydev->mdio.bus, phydev->mdio.addr,
+ MSCC_PHY_EXT_PHY_CNTL_4);
+ addr >>= PHY_CNTL_4_ADDR_POS;
+
+ val = __mdiobus_read(phydev->mdio.bus, phydev->mdio.addr,
+ MSCC_PHY_ACTIPHY_CNTL);
+ if (val & PHY_ADDR_REVERSED)
+ base_addr = phydev->mdio.addr + addr;
+ else
+ base_addr = phydev->mdio.addr - addr;
+
+ /* Some parts of the init sequence are identical for every PHY in the
+ * package. Some parts are modifying the GPIO register bank which is a
+ * set of registers that are affecting all PHYs, a few resetting the
+ * microprocessor common to all PHYs. The CRC check responsible of the
+ * checking the firmware within the 8051 microprocessor can only be
+ * accessed via the PHY whose internal address in the package is 0.
+ * All PHYs' interrupts mask register has to be zeroed before enabling
+ * any PHY's interrupt in this register.
+ * For all these reasons, we need to do the init sequence once and only
+ * once whatever is the first PHY in the package that is initialized and
+ * do the correct init sequence for all PHYs that are package-critical
+ * in this pre-init function.
+ */
+ if (!vsc8584_is_pkg_init(phydev, base_addr,
+ val & PHY_ADDR_REVERSED ? 1 : 0)) {
+ ret = vsc8584_config_pre_init(phydev->mdio.bus, base_addr);
+ if (ret)
+ goto err;
+ }
+
+ vsc8531->pkg_init = true;
+
+ __mdiobus_write(phydev->mdio.bus, base_addr, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_EXTENDED_GPIO);
+
+ val = __mdiobus_read(phydev->mdio.bus, base_addr,
+ MSCC_PHY_MAC_CFG_FASTLINK);
+ val &= ~MAC_CFG_MASK;
+ if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
+ val |= MAC_CFG_QSGMII;
+ else
+ val |= MAC_CFG_SGMII;
+
+ ret = __mdiobus_write(phydev->mdio.bus, base_addr,
+ MSCC_PHY_MAC_CFG_FASTLINK, val);
+ if (ret)
+ goto err;
+
+ val = PROC_CMD_MCB_ACCESS_MAC_CONF | PROC_CMD_RST_CONF_PORT |
+ PROC_CMD_READ_MOD_WRITE_PORT;
+ if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
+ val |= PROC_CMD_QSGMII_MAC;
+ else
+ val |= PROC_CMD_SGMII_MAC;
+
+ ret = vsc8584_cmd(phydev->mdio.bus, base_addr, val);
+ if (ret)
+ goto err;
+
+ usleep_range(10000, 20000);
+
+ /* Disable SerDes for 100Base-FX */
+ ret = vsc8584_cmd(phydev->mdio.bus, base_addr,
+ PROC_CMD_FIBER_MEDIA_CONF |
+ PROC_CMD_FIBER_PORT(addr) | PROC_CMD_FIBER_DISABLE |
+ PROC_CMD_READ_MOD_WRITE_PORT |
+ PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_100BASE_FX);
+ if (ret)
+ goto err;
+
+ /* Disable SerDes for 1000Base-X */
+ ret = vsc8584_cmd(phydev->mdio.bus, base_addr,
+ PROC_CMD_FIBER_MEDIA_CONF |
+ PROC_CMD_FIBER_PORT(addr) | PROC_CMD_FIBER_DISABLE |
+ PROC_CMD_READ_MOD_WRITE_PORT |
+ PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_1000BASE_X);
+ if (ret)
+ goto err;
+
+ mutex_unlock(&phydev->mdio.bus->mdio_lock);
+
+ phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD);
+
+ val = phy_read(phydev, MSCC_PHY_EXT_PHY_CNTL_1);
+ val &= ~(MEDIA_OP_MODE_MASK | VSC8584_MAC_IF_SELECTION_MASK);
+ val |= MEDIA_OP_MODE_COPPER | (VSC8584_MAC_IF_SELECTION_SGMII <<
+ VSC8584_MAC_IF_SELECTION_POS);
+ ret = phy_write(phydev, MSCC_PHY_EXT_PHY_CNTL_1, val);
+
+ ret = genphy_soft_reset(phydev);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < vsc8531->nleds; i++) {
+ ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
+ if (ret)
+ return ret;
+ }
+
+ return genphy_config_init(phydev);
+
+err:
+ mutex_unlock(&phydev->mdio.bus->mdio_lock);
+ return ret;
+}
+
static int vsc85xx_config_init(struct phy_device *phydev)
{
int rc, i;
@@ -760,6 +1409,16 @@ static int vsc85xx_config_init(struct phy_device *phydev)
return genphy_config_init(phydev);
}
+static int vsc8584_did_interrupt(struct phy_device *phydev)
+{
+ int rc = 0;
+
+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
+ rc = phy_read(phydev, MII_VSC85XX_INT_STATUS);
+
+ return (rc < 0) ? 0 : rc & MII_VSC85XX_INT_MASK_MASK;
+}
+
static int vsc85xx_ack_interrupt(struct phy_device *phydev)
{
int rc = 0;
@@ -809,6 +1468,37 @@ static int vsc85xx_read_status(struct phy_device *phydev)
return genphy_read_status(phydev);
}
+static int vsc8584_probe(struct phy_device *phydev)
+{
+ struct vsc8531_private *vsc8531;
+ u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY,
+ VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY,
+ VSC8531_DUPLEX_COLLISION};
+
+ if ((phydev->phy_id & MSCC_DEV_REV_MASK) != VSC8584_REVB) {
+ dev_err(&phydev->mdio.dev, "Only VSC8584 revB is supported.\n");
+ return -ENOTSUPP;
+ }
+
+ vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL);
+ if (!vsc8531)
+ return -ENOMEM;
+
+ phydev->priv = vsc8531;
+
+ vsc8531->nleds = 4;
+ vsc8531->supp_led_modes = VSC8584_SUPP_LED_MODES;
+ vsc8531->hw_stats = vsc8584_hw_stats;
+ vsc8531->nstats = ARRAY_SIZE(vsc8584_hw_stats);
+ vsc8531->stats = devm_kzalloc(&phydev->mdio.dev,
+ sizeof(u64) * vsc8531->nstats,
+ GFP_KERNEL);
+ if (!vsc8531->stats)
+ return -ENOMEM;
+
+ return vsc85xx_dt_led_modes_get(phydev, default_mode);
+}
+
static int vsc85xx_probe(struct phy_device *phydev)
{
struct vsc8531_private *vsc8531;
@@ -937,6 +1627,29 @@ static struct phy_driver vsc85xx_driver[] = {
.get_sset_count = &vsc85xx_get_sset_count,
.get_strings = &vsc85xx_get_strings,
.get_stats = &vsc85xx_get_stats,
+},
+{
+ .phy_id = PHY_ID_VSC8584,
+ .name = "Microsemi GE VSC8584 SyncE",
+ .phy_id_mask = 0xfffffff0,
+ .features = PHY_GBIT_FEATURES,
+ .flags = PHY_HAS_INTERRUPT,
+ .soft_reset = &genphy_soft_reset,
+ .config_init = &vsc8584_config_init,
+ .config_aneg = &vsc85xx_config_aneg,
+ .aneg_done = &genphy_aneg_done,
+ .read_status = &vsc85xx_read_status,
+ .ack_interrupt = &vsc85xx_ack_interrupt,
+ .config_intr = &vsc85xx_config_intr,
+ .did_interrupt = &vsc8584_did_interrupt,
+ .suspend = &genphy_suspend,
+ .resume = &genphy_resume,
+ .probe = &vsc8584_probe,
+ .get_tunable = &vsc85xx_get_tunable,
+ .set_tunable = &vsc85xx_set_tunable,
+ .get_sset_count = &vsc85xx_get_sset_count,
+ .get_strings = &vsc85xx_get_strings,
+ .get_stats = &vsc85xx_get_stats,
}
};
@@ -948,6 +1661,7 @@ static struct mdio_device_id __maybe_unused vsc85xx_tbl[] = {
{ PHY_ID_VSC8531, 0xfffffff0, },
{ PHY_ID_VSC8540, 0xfffffff0, },
{ PHY_ID_VSC8541, 0xfffffff0, },
+ { PHY_ID_VSC8584, 0xfffffff0, },
{ }
};
--
git-series 0.9.1
^ permalink raw reply related
* [PATCH net] net: mvpp2: let phylink manage the carrier state
From: Antoine Tenart @ 2018-09-14 14:56 UTC (permalink / raw)
To: davem, linux
Cc: Antoine Tenart, netdev, linux-kernel, thomas.petazzoni,
maxime.chevallier, gregory.clement, miquel.raynal, nadavh,
stefanc, ymarkman, mw
Net drivers using phylink shouldn't mess with the link carrier
themselves and should let phylink manage it. The mvpp2 driver wasn't
following this best practice as the mac_config() function made calls to
change the link carrier state. This led to wrongly reported carrier link
state which then triggered other issues. This patch fixes this
behaviour.
But the PPv2 driver relied on this misbehaviour in two cases: for fixed
links and when not using phylink (ACPI mode). The later was fixed by
adding an explicit call to link_up(), which when the ACPI mode will use
phylink should be removed.
The fixed link case was relying on the mac_config() function to set the
link up, as we found an issue in phylink_start() which assumes the
carrier is off. If not, the link_up() function is never called. To fix
this, a call to netif_carrier_off() is added just before phylink_start()
so that we do not introduce a regression in the driver.
Fixes: 4bb043262878 ("net: mvpp2: phylink support")
Reported-by: Russell King <linux@armlinux.org.uk>
Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
---
Hi all,
The plan to fix this properly is to send this fix patch first, which can
go into the stable trees. Then once net will be merged into net-next,
I'll send other patches to fix the phylink_start() function directly and
to remove those explicit netif_carrier_off() calls in drivers using
phylink.
This way the stable trees can be fixed, and newer kernels will have a
proper solution.
Thanks,
Antoine
.../net/ethernet/marvell/mvpp2/mvpp2_main.c | 21 ++++++-------------
1 file changed, 6 insertions(+), 15 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
index 28500417843e..702fec82d806 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -58,6 +58,8 @@ static struct {
*/
static void mvpp2_mac_config(struct net_device *dev, unsigned int mode,
const struct phylink_link_state *state);
+static void mvpp2_mac_link_up(struct net_device *dev, unsigned int mode,
+ phy_interface_t interface, struct phy_device *phy);
/* Queue modes */
#define MVPP2_QDIST_SINGLE_MODE 0
@@ -3142,6 +3144,7 @@ static void mvpp2_start_dev(struct mvpp2_port *port)
mvpp22_mode_reconfigure(port);
if (port->phylink) {
+ netif_carrier_off(port->dev);
phylink_start(port->phylink);
} else {
/* Phylink isn't used as of now for ACPI, so the MAC has to be
@@ -3150,9 +3153,10 @@ static void mvpp2_start_dev(struct mvpp2_port *port)
*/
struct phylink_link_state state = {
.interface = port->phy_interface,
- .link = 1,
};
mvpp2_mac_config(port->dev, MLO_AN_INBAND, &state);
+ mvpp2_mac_link_up(port->dev, MLO_AN_INBAND, port->phy_interface,
+ NULL);
}
netif_tx_start_all_queues(port->dev);
@@ -4495,10 +4499,6 @@ static void mvpp2_mac_config(struct net_device *dev, unsigned int mode,
return;
}
- netif_tx_stop_all_queues(port->dev);
- if (!port->has_phy)
- netif_carrier_off(port->dev);
-
/* Make sure the port is disabled when reconfiguring the mode */
mvpp2_port_disable(port);
@@ -4523,16 +4523,7 @@ static void mvpp2_mac_config(struct net_device *dev, unsigned int mode,
if (port->priv->hw_version == MVPP21 && port->flags & MVPP2_F_LOOPBACK)
mvpp2_port_loopback_set(port, state);
- /* If the port already was up, make sure it's still in the same state */
- if (state->link || !port->has_phy) {
- mvpp2_port_enable(port);
-
- mvpp2_egress_enable(port);
- mvpp2_ingress_enable(port);
- if (!port->has_phy)
- netif_carrier_on(dev);
- netif_tx_wake_all_queues(dev);
- }
+ mvpp2_port_enable(port);
}
static void mvpp2_mac_link_up(struct net_device *dev, unsigned int mode,
--
2.17.1
^ permalink raw reply related
* Re: [PATCH 5/7] MIPS: mscc: ocelot: add GPIO4 pinmuxing DT node
From: Alexandre Belloni @ 2018-09-14 14:54 UTC (permalink / raw)
To: Quentin Schulz
Cc: ralf, paul.burton, jhogan, robh+dt, mark.rutland, davem, andrew,
f.fainelli, allan.nielsen, linux-mips, devicetree, linux-kernel,
netdev, thomas.petazzoni, antoine.tenart
In-Reply-To: <92e37a04e77003f01a67ac5e49e66ae83f87c591.1536916714.git-series.quentin.schulz@bootlin.com>
Hi,
On 14/09/2018 11:44:26+0200, Quentin Schulz wrote:
> In order to use GPIO4 as a GPIO, we need to mux it in this mode so let's
> declare a new pinctrl DT node for it.
>
> Signed-off-by: Quentin Schulz <quentin.schulz@bootlin.com>
> ---
> arch/mips/boot/dts/mscc/ocelot.dtsi | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/arch/mips/boot/dts/mscc/ocelot.dtsi b/arch/mips/boot/dts/mscc/ocelot.dtsi
> index 8ce317c..b5c4c74 100644
> --- a/arch/mips/boot/dts/mscc/ocelot.dtsi
> +++ b/arch/mips/boot/dts/mscc/ocelot.dtsi
> @@ -182,6 +182,11 @@
> interrupts = <13>;
> #interrupt-cells = <2>;
>
> + gpio4: gpio4 {
> + pins = "GPIO_4";
> + function = "gpio";
> + };
> +
For a GPIO, I would do that in the board dts because it is not used
directly in the dtsi.
> uart_pins: uart-pins {
> pins = "GPIO_6", "GPIO_7";
> function = "uart";
> --
> git-series 0.9.1
--
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* [PATCH net-next] cxgb4: add per rx-queue counter for packet errors
From: Ganesh Goudar @ 2018-09-14 9:16 UTC (permalink / raw)
To: netdev, davem; +Cc: nirranjan, indranil, dt, Ganesh Goudar, Casey Leedom
print per rx-queue packet errors in sge_qinfo
Signed-off-by: Casey Leedom <leedom@chelsio.com>
Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>
---
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 1 +
drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c | 1 +
drivers/net/ethernet/chelsio/cxgb4/sge.c | 4 ++++
3 files changed, 6 insertions(+)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index 298701ed..b5010bd 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -692,6 +692,7 @@ struct sge_eth_stats { /* Ethernet queue statistics */
unsigned long rx_cso; /* # of Rx checksum offloads */
unsigned long vlan_ex; /* # of Rx VLAN extractions */
unsigned long rx_drops; /* # of packets dropped due to no mem */
+ unsigned long bad_rx_pkts; /* # of packets with err_vec!=0 */
};
struct sge_eth_rxq { /* SW Ethernet Rx queue */
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
index 0f72f9c..cab492e 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
@@ -2784,6 +2784,7 @@ do { \
RL("LROmerged:", stats.lro_merged);
RL("LROpackets:", stats.lro_pkts);
RL("RxDrops:", stats.rx_drops);
+ RL("RxBadPkts:", stats.bad_rx_pkts);
TL("TSO:", tso);
TL("TxCSO:", tx_cso);
TL("VLANins:", vlan_ins);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c
index 6807bc3..b901884 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c
@@ -2830,6 +2830,10 @@ int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp,
csum_ok = pkt->csum_calc && !err_vec &&
(q->netdev->features & NETIF_F_RXCSUM);
+
+ if (err_vec)
+ rxq->stats.bad_rx_pkts++;
+
if (((pkt->l2info & htonl(RXF_TCP_F)) ||
tnl_hdr_len) &&
(q->netdev->features & NETIF_F_GRO) && csum_ok && !pkt->ip_frag) {
--
2.1.0
^ permalink raw reply related
* Re: [RFC PATCH net-next v1 00/14] rename and shrink i40evf
From: Or Gerlitz @ 2018-09-14 9:10 UTC (permalink / raw)
To: Jesse Brandeburg
Cc: Linux Netdev List, intel-wired-lan, Jeff Kirsher, Saeed Mahameed
In-Reply-To: <20180913223144.75823-1-jesse.brandeburg@intel.com>
On Fri, Sep 14, 2018 at 1:31 AM, Jesse Brandeburg
<jesse.brandeburg@intel.com> wrote:
Hi Jesse,
> This series contains changes to i40evf so that it becomes a more
> generic virtual function driver for current and future silicon.
>
> While doing the rename of i40evf to a more generic name of iavf,
> we also put the driver on a severe diet due to how much of the
> code was unneeded or was unused. The outcome is a lean and mean
> virtual function driver that continues to work on existing 40GbE
> (i40e) virtual devices and prepped for future supported devices,
> like the 100GbE (ice) virtual devices.
on what HW ring format do you standardize? do i40e/Fortville and
ice/what's-the-intel-code-name? HWs can/use the same posting/completion
descriptor?
> This solves 2 issues we saw coming or were already present, the
> first was constant code duplication happening with i40e/i40evf,
> when much of the duplicate code in the i40evf was not used or was
> not needed.
could you spare few words on the origin/nature of these duplicates? were them
just developer C&P mistakes for functionality which is irrelevant for
a VF? like what?
if not, what was there?
> The second was to remove the future confusion of why
> future VF devices that were not considered "40GbE" only devices
> were supported by i40evf.
can elaborate further?
> The thought is that iavf will be the virtual function driver for
> all future devices, so it should have a "generic" name to propery
> represent that it is the VF driver for multiple generations of
> devices.
for that end, as I think was explained @ the netdev Tokyo AVF session,
you would need a mechanism for feature negotiation, is it here or coming up?
> 41 files changed, 3436 insertions(+), 7581 deletions(-)
code diet is cool!
^ permalink raw reply
* Re: [PATCH v2 05/17] compat_ioctl: move more drivers to generic_compat_ioctl_ptrarg
From: David Sterba @ 2018-09-14 14:23 UTC (permalink / raw)
To: Arnd Bergmann
Cc: linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
linux-iio-u79uwXL29TY76Z2rM5mHXA,
linux-pci-u79uwXL29TY76Z2rM5mHXA,
linux-remoteproc-u79uwXL29TY76Z2rM5mHXA,
linux-nvme-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
platform-driver-x86-u79uwXL29TY76Z2rM5mHXA,
sparclinux-u79uwXL29TY76Z2rM5mHXA,
devel-gWbeCf7V1WCQmaza687I9mD2FQJk+8+b,
linux-scsi-u79uwXL29TY76Z2rM5mHXA,
linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw,
linux-rdma-u79uwXL29TY76Z2rM5mHXA,
qat-linux-ral2JQCrhuEAvxtiuMwx3w,
amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
linux-input-u79uwXL29TY76Z2rM5mHXA,
linux-media-u79uwXL29TY76Z2rM5mHXA,
linaro-mm-sig-cunTk1MwBs8s++Sfvej+rw,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
ceph-devel-u79uwXL29TY76Z2rM5mHXA, Greg Kroah-Hartman,
linux-usb-u79uwXL29TY76Z2rM5mHXA,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-crypto-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ, David S. Miller,
linux-btrfs-u79uwXL29TY76Z2rM5mHXA,
viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn
In-Reply-To: <20180912151134.436719-1-arnd-r2nGTMty4D4@public.gmane.org>
On Wed, Sep 12, 2018 at 05:08:52PM +0200, Arnd Bergmann wrote:
> The .ioctl and .compat_ioctl file operations have the same prototype so
> they can both point to the same function, which works great almost all
> the time when all the commands are compatible.
>
> One exception is the s390 architecture, where a compat pointer is only
> 31 bit wide, and converting it into a 64-bit pointer requires calling
> compat_ptr(). Most drivers here will ever run in s390, but since we now
> have a generic helper for it, it's easy enough to use it consistently.
>
> I double-checked all these drivers to ensure that all ioctl arguments
> are used as pointers or are ignored, but are not interpreted as integer
> values.
>
> Signed-off-by: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
> ---
> fs/btrfs/super.c | 2 +-
Acked-by: David Sterba <dsterba-IBi9RG/b67k@public.gmane.org>
^ permalink raw reply
* [PATCH net-next] cxgb4: Fix endianness issue in t4_fwcache()
From: Ganesh Goudar @ 2018-09-14 9:06 UTC (permalink / raw)
To: netdev, davem; +Cc: viro, nirranjan, indranil, dt, Ganesh Goudar
Do not put host-endian 0 or 1 into big endian feild.
Reported-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>
---
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index c28a1d8..f85eab5 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -3889,7 +3889,7 @@ int t4_fwcache(struct adapter *adap, enum fw_params_param_dev_fwcache op)
c.param[0].mnem =
cpu_to_be32(FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) |
FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_FWCACHE));
- c.param[0].val = (__force __be32)op;
+ c.param[0].val = cpu_to_be32(op);
return t4_wr_mbox(adap, adap->mbox, &c, sizeof(c), NULL);
}
--
2.1.0
^ permalink raw reply related
* Re: [PATCH net-next 5/8] bnxt_en: Use hw_tc_offload and ignore_ari devlink parameters
From: kbuild test robot @ 2018-09-14 8:58 UTC (permalink / raw)
To: Vasundhara Volam; +Cc: kbuild-all, davem, michael.chan, netdev
In-Reply-To: <1536655505-14387-6-git-send-email-vasundhara-v.volam@broadcom.com>
[-- Attachment #1: Type: text/plain, Size: 7214 bytes --]
Hi Vasundhara,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on net-next/master]
url: https://github.com/0day-ci/linux/commits/Vasundhara-Volam/bnxt_en-devlink-param-updates/20180914-141937
config: powerpc-allyesconfig (attached as .config)
compiler: powerpc64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=7.2.0 make.cross ARCH=powerpc
Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings
All warnings (new ones prefixed by >>):
drivers/net//ethernet/broadcom/bnxt/bnxt_devlink.c: In function 'bnxt_hwrm_nvm_req.constprop':
drivers/net//ethernet/broadcom/bnxt/bnxt_devlink.c:38:27: warning: 'nvm_param.num_bits' may be used uninitialized in this function [-Wmaybe-uninitialized]
struct bnxt_dl_nvm_param nvm_param;
^~~~~~~~~
drivers/net//ethernet/broadcom/bnxt/bnxt_devlink.c:53:5: warning: 'nvm_param.dir_type' may be used uninitialized in this function [-Wmaybe-uninitialized]
if (nvm_param.dir_type == BNXT_NVM_PORT_CFG)
^
In file included from include/linux/byteorder/big_endian.h:5:0,
from arch/powerpc/include/uapi/asm/byteorder.h:14,
from include/asm-generic/bitops/le.h:6,
from arch/powerpc/include/asm/bitops.h:247,
from include/linux/bitops.h:19,
from include/linux/kernel.h:11,
from include/linux/list.h:9,
from include/linux/pci.h:26,
from drivers/net//ethernet/broadcom/bnxt/bnxt_devlink.c:10:
>> include/uapi/linux/byteorder/big_endian.h:35:27: warning: 'nvm_param.offset' may be used uninitialized in this function [-Wmaybe-uninitialized]
#define __cpu_to_le16(x) ((__force __le16)__swab16((x)))
^
drivers/net//ethernet/broadcom/bnxt/bnxt_devlink.c:38:27: note: 'nvm_param.offset' was declared here
struct bnxt_dl_nvm_param nvm_param;
^~~~~~~~~
--
drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c: In function 'bnxt_hwrm_nvm_req.constprop':
drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c:38:27: warning: 'nvm_param.num_bits' may be used uninitialized in this function [-Wmaybe-uninitialized]
struct bnxt_dl_nvm_param nvm_param;
^~~~~~~~~
drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c:53:5: warning: 'nvm_param.dir_type' may be used uninitialized in this function [-Wmaybe-uninitialized]
if (nvm_param.dir_type == BNXT_NVM_PORT_CFG)
^
In file included from include/linux/byteorder/big_endian.h:5:0,
from arch/powerpc/include/uapi/asm/byteorder.h:14,
from include/asm-generic/bitops/le.h:6,
from arch/powerpc/include/asm/bitops.h:247,
from include/linux/bitops.h:19,
from include/linux/kernel.h:11,
from include/linux/list.h:9,
from include/linux/pci.h:26,
from drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c:10:
>> include/uapi/linux/byteorder/big_endian.h:35:27: warning: 'nvm_param.offset' may be used uninitialized in this function [-Wmaybe-uninitialized]
#define __cpu_to_le16(x) ((__force __le16)__swab16((x)))
^
drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c:38:27: note: 'nvm_param.offset' was declared here
struct bnxt_dl_nvm_param nvm_param;
^~~~~~~~~
vim +35 include/uapi/linux/byteorder/big_endian.h
5921e6f8 David Howells 2012-10-13 14
5921e6f8 David Howells 2012-10-13 15 #define __constant_htonl(x) ((__force __be32)(__u32)(x))
5921e6f8 David Howells 2012-10-13 16 #define __constant_ntohl(x) ((__force __u32)(__be32)(x))
5921e6f8 David Howells 2012-10-13 17 #define __constant_htons(x) ((__force __be16)(__u16)(x))
5921e6f8 David Howells 2012-10-13 18 #define __constant_ntohs(x) ((__force __u16)(__be16)(x))
5921e6f8 David Howells 2012-10-13 19 #define __constant_cpu_to_le64(x) ((__force __le64)___constant_swab64((x)))
5921e6f8 David Howells 2012-10-13 20 #define __constant_le64_to_cpu(x) ___constant_swab64((__force __u64)(__le64)(x))
5921e6f8 David Howells 2012-10-13 21 #define __constant_cpu_to_le32(x) ((__force __le32)___constant_swab32((x)))
5921e6f8 David Howells 2012-10-13 22 #define __constant_le32_to_cpu(x) ___constant_swab32((__force __u32)(__le32)(x))
5921e6f8 David Howells 2012-10-13 23 #define __constant_cpu_to_le16(x) ((__force __le16)___constant_swab16((x)))
5921e6f8 David Howells 2012-10-13 24 #define __constant_le16_to_cpu(x) ___constant_swab16((__force __u16)(__le16)(x))
5921e6f8 David Howells 2012-10-13 25 #define __constant_cpu_to_be64(x) ((__force __be64)(__u64)(x))
5921e6f8 David Howells 2012-10-13 26 #define __constant_be64_to_cpu(x) ((__force __u64)(__be64)(x))
5921e6f8 David Howells 2012-10-13 27 #define __constant_cpu_to_be32(x) ((__force __be32)(__u32)(x))
5921e6f8 David Howells 2012-10-13 28 #define __constant_be32_to_cpu(x) ((__force __u32)(__be32)(x))
5921e6f8 David Howells 2012-10-13 29 #define __constant_cpu_to_be16(x) ((__force __be16)(__u16)(x))
5921e6f8 David Howells 2012-10-13 30 #define __constant_be16_to_cpu(x) ((__force __u16)(__be16)(x))
5921e6f8 David Howells 2012-10-13 31 #define __cpu_to_le64(x) ((__force __le64)__swab64((x)))
5921e6f8 David Howells 2012-10-13 32 #define __le64_to_cpu(x) __swab64((__force __u64)(__le64)(x))
5921e6f8 David Howells 2012-10-13 33 #define __cpu_to_le32(x) ((__force __le32)__swab32((x)))
5921e6f8 David Howells 2012-10-13 34 #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
5921e6f8 David Howells 2012-10-13 @35 #define __cpu_to_le16(x) ((__force __le16)__swab16((x)))
5921e6f8 David Howells 2012-10-13 36 #define __le16_to_cpu(x) __swab16((__force __u16)(__le16)(x))
5921e6f8 David Howells 2012-10-13 37 #define __cpu_to_be64(x) ((__force __be64)(__u64)(x))
5921e6f8 David Howells 2012-10-13 38 #define __be64_to_cpu(x) ((__force __u64)(__be64)(x))
5921e6f8 David Howells 2012-10-13 39 #define __cpu_to_be32(x) ((__force __be32)(__u32)(x))
5921e6f8 David Howells 2012-10-13 40 #define __be32_to_cpu(x) ((__force __u32)(__be32)(x))
5921e6f8 David Howells 2012-10-13 41 #define __cpu_to_be16(x) ((__force __be16)(__u16)(x))
5921e6f8 David Howells 2012-10-13 42 #define __be16_to_cpu(x) ((__force __u16)(__be16)(x))
5921e6f8 David Howells 2012-10-13 43
:::::: The code at line 35 was first introduced by commit
:::::: 5921e6f8809b1616932ca4afd40fe449faa8fd88 UAPI: (Scripted) Disintegrate include/linux/byteorder
:::::: TO: David Howells <dhowells@redhat.com>
:::::: CC: David Howells <dhowells@redhat.com>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 58692 bytes --]
^ permalink raw reply
* Re: mlx5 driver loading failing on v4.19 / net-next / bpf-next
From: Jesper Dangaard Brouer @ 2018-09-14 8:52 UTC (permalink / raw)
To: Saeed Mahameed
Cc: Alexei Starovoitov, Moshe Shemesh, Eli Cohen, Or Gerlitz,
Tariq Toukan, Saeed Mahameed, netdev@vger.kernel.org,
Eran Ben Elisha, brouer
In-Reply-To: <CALzJLG-t3ytoE1d8PeA9aUDiENAAmQJpX3LgT1YOhKLMnL=s7g@mail.gmail.com>
On Fri, 14 Sep 2018 01:22:15 -0700
Saeed Mahameed <saeedm@dev.mellanox.co.il> wrote:
> On Thu, Sep 13, 2018 at 11:36 PM, Jesper Dangaard Brouer
> <brouer@redhat.com> wrote:
> > On Thu, 13 Sep 2018 15:55:29 -0700
> > Alexei Starovoitov <alexei.starovoitov@gmail.com> wrote:
> >
> >> On Thu, Aug 30, 2018 at 1:35 AM, Tariq Toukan <tariqt@mellanox.com> wrote:
> >> >
> >> >
> >> > On 29/08/2018 6:05 PM, Jesper Dangaard Brouer wrote:
> >> >>
> >> >> Hi Saeed,
> >> >>
> >> >> I'm having issues loading mlx5 driver on v4.19 kernels (tested both
> >> >> net-next and bpf-next), while kernel v4.18 seems to work. It happens
> >> >> with a Mellanox ConnectX-5 NIC (and also a CX4-Lx but I removed that
> >> >> from the system now).
> >> >>
> >> >
> >> > Hi Jesper,
> >> >
> >> > Thanks for your report!
> >> >
> >> > We are working to analyze and debug the issue.
> >>
> >> looks like serious issue to me... while no news in 2 weeks.
> >> any update?
> >
> > Mellanox took it offlist, and Sep 6th found that this is a regression
> > introduced by commit 269d26f47f6f ("net/mlx5: Reduce command polling
> > interval"), but only if CONFIG_PREEMPT is on.
> >
> > I can confirm that reverting this commit fixed the issue (and not the
> > firmware upgrade I also did).
> >
> > I think Moshe (Cc) is responsible for this case, and I expect to soon
> > see a revert or alternative solution to this!?
> >
> > Thanks for the kick Alexei :-)
>
> Thanks you Alexei and Jesper for following up,
> the fix is already being tested [1] and will be submitted tomorrow,
> as Jesper pointed out the issue happens only with 269d26f47f6f
> ("net/mlx5: Reduce command polling
> interval"), and only if CONFIG_PREEMPT is on.
> the only affected kernel is 4.19 which is not GA yet.
>
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux.git/commit/?h=net-mlx5
Sound good.
I will appreciate if you add a:
Reported-by: Jesper Dangaard Brouer <brouer@redhat.com>
--
Best regards,
Jesper Dangaard Brouer
MSc.CS, Principal Kernel Engineer at Red Hat
LinkedIn: http://www.linkedin.com/in/brouer
^ permalink raw reply
* [PATCH 1/1] net: rds: use memset to optimize the recv
From: Zhu Yanjun @ 2018-09-14 8:45 UTC (permalink / raw)
To: santosh.shilimkar, davem, netdev, linux-rdma, rds-devel
The function rds_inc_init is in recv process. To use memset can optimize
the function rds_inc_init.
The test result:
Before:
1) + 24.950 us | rds_inc_init [rds]();
After:
1) + 10.990 us | rds_inc_init [rds]();
Signed-off-by: Zhu Yanjun <yanjun.zhu@oracle.com>
---
net/rds/recv.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/net/rds/recv.c b/net/rds/recv.c
index 504cd6bcc54c..a9399ddbb7bf 100644
--- a/net/rds/recv.c
+++ b/net/rds/recv.c
@@ -43,8 +43,6 @@
void rds_inc_init(struct rds_incoming *inc, struct rds_connection *conn,
struct in6_addr *saddr)
{
- int i;
-
refcount_set(&inc->i_refcount, 1);
INIT_LIST_HEAD(&inc->i_item);
inc->i_conn = conn;
@@ -53,8 +51,7 @@ void rds_inc_init(struct rds_incoming *inc, struct rds_connection *conn,
inc->i_rx_tstamp.tv_sec = 0;
inc->i_rx_tstamp.tv_usec = 0;
- for (i = 0; i < RDS_RX_MAX_TRACES; i++)
- inc->i_rx_lat_trace[i] = 0;
+ memset(inc->i_rx_lat_trace, 0, sizeof(inc->i_rx_lat_trace));
}
EXPORT_SYMBOL_GPL(rds_inc_init);
--
2.17.1
^ permalink raw reply related
* [PATCH net-next 2/5] net: phy: mscc: Add EEE init sequence
From: Quentin Schulz @ 2018-09-14 8:33 UTC (permalink / raw)
To: davem, andrew, f.fainelli
Cc: allan.nielsen, linux-kernel, netdev, thomas.petazzoni,
Quentin Schulz, Raju Lakkaraju
In-Reply-To: <cover.616d15610d44a0e3d463acd8119859f243163ad2.1536913944.git-series.quentin.schulz@bootlin.com>
From: Raju Lakkaraju <Raju.Lakkaraju@microchip.com>
Microsemi PHYs (VSC 8530/31/40/41) need to update the Energy Efficient
Ethernet initialization sequence.
In order to avoid certain link state errors that could result in link
drops and packet loss, the physical coding sublayer (PCS) must be
updated with settings related to EEE in order to improve performance.
Signed-off-by: Raju Lakkaraju <Raju.Lakkaraju@microchip.com>
Signed-off-by: Quentin Schulz <quentin.schulz@bootlin.com>
---
drivers/net/phy/mscc.c | 54 +++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 54 insertions(+)
diff --git a/drivers/net/phy/mscc.c b/drivers/net/phy/mscc.c
index 62d6e0a..c0a9ea9 100644
--- a/drivers/net/phy/mscc.c
+++ b/drivers/net/phy/mscc.c
@@ -67,6 +67,7 @@ enum rgmii_rx_clock_delay {
#define MSCC_PHY_PAGE_STANDARD 0x0000 /* Standard registers */
#define MSCC_PHY_PAGE_EXTENDED 0x0001 /* Extended registers */
#define MSCC_PHY_PAGE_EXTENDED_2 0x0002 /* Extended reg - page 2 */
+#define MSCC_PHY_PAGE_TR 0x52b5 /* Token ring registers */
/* Extended Page 1 Registers */
#define MSCC_PHY_CU_MEDIA_CRC_VALID_CNT 18
@@ -100,6 +101,13 @@ enum rgmii_rx_clock_delay {
#define SECURE_ON_ENABLE 0x8000
#define SECURE_ON_PASSWD_LEN_4 0x4000
+/* Token ring page Registers */
+#define MSCC_PHY_TR_CNTL 16
+#define TR_WRITE 0x8000
+#define TR_ADDR(x) (0x7fff & (x))
+#define MSCC_PHY_TR_LSB 17
+#define MSCC_PHY_TR_MSB 18
+
/* Microsemi PHY ID's */
#define PHY_ID_VSC8530 0x00070560
#define PHY_ID_VSC8531 0x00070570
@@ -685,6 +693,48 @@ static int vsc85xx_set_tunable(struct phy_device *phydev,
}
}
+static void vsc85xx_tr_write(struct phy_device *phydev, u16 addr, u32 val)
+{
+ phy_write(phydev, MSCC_PHY_TR_MSB, val >> 16);
+ phy_write(phydev, MSCC_PHY_TR_LSB, val & GENMASK(15, 0));
+ phy_write(phydev, MSCC_PHY_TR_CNTL, TR_WRITE | TR_ADDR(addr));
+}
+
+static int vsc85xx_eee_init_seq_set(struct phy_device *phydev)
+{
+ int rc;
+
+ mutex_lock(&phydev->lock);
+ rc = vsc85xx_phy_page_set(phydev, MSCC_PHY_PAGE_TR);
+ if (rc)
+ goto out_unlock;
+
+ vsc85xx_tr_write(phydev, 0x0f82, 0x0012b00a);
+ vsc85xx_tr_write(phydev, 0x1686, 0x00000004);
+ vsc85xx_tr_write(phydev, 0x168c, 0x00d2c46f);
+ vsc85xx_tr_write(phydev, 0x17a2, 0x00000620);
+ vsc85xx_tr_write(phydev, 0x16a0, 0x00eeffdd);
+ vsc85xx_tr_write(phydev, 0x16a6, 0x00071448);
+ vsc85xx_tr_write(phydev, 0x16a4, 0x0013132f);
+ vsc85xx_tr_write(phydev, 0x16a8, 0x00000000);
+ vsc85xx_tr_write(phydev, 0x0ffc, 0x00c0a028);
+ vsc85xx_tr_write(phydev, 0x0fe8, 0x0091b06c);
+ vsc85xx_tr_write(phydev, 0x0fea, 0x00041600);
+ vsc85xx_tr_write(phydev, 0x0f80, 0x00000af4);
+ vsc85xx_tr_write(phydev, 0x0fec, 0x00901809);
+ vsc85xx_tr_write(phydev, 0x0fee, 0x0000a6a1);
+ vsc85xx_tr_write(phydev, 0x0ffe, 0x00b01007);
+ vsc85xx_tr_write(phydev, 0x16b0, 0x00eeff00);
+ vsc85xx_tr_write(phydev, 0x16b2, 0x00007000);
+ vsc85xx_tr_write(phydev, 0x16b4, 0x00000814);
+
+out_unlock:
+ rc = vsc85xx_phy_page_set(phydev, MSCC_PHY_PAGE_STANDARD);
+ mutex_unlock(&phydev->lock);
+
+ return rc;
+}
+
static int vsc85xx_config_init(struct phy_device *phydev)
{
int rc, i;
@@ -702,6 +752,10 @@ static int vsc85xx_config_init(struct phy_device *phydev)
if (rc)
return rc;
+ rc = vsc85xx_eee_init_seq_set(phydev);
+ if (rc)
+ return rc;
+
for (i = 0; i < vsc8531->nleds; i++) {
rc = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
if (rc)
--
git-series 0.9.1
^ permalink raw reply related
* Re: mlx5 driver loading failing on v4.19 / net-next / bpf-next
From: Saeed Mahameed @ 2018-09-14 8:22 UTC (permalink / raw)
To: Jesper Dangaard Brouer
Cc: Alexei Starovoitov, Moshe Shemesh, Eli Cohen, Or Gerlitz,
Tariq Toukan, Saeed Mahameed, netdev@vger.kernel.org,
Eran Ben Elisha
In-Reply-To: <20180914083618.08fe816e@redhat.com>
On Thu, Sep 13, 2018 at 11:36 PM, Jesper Dangaard Brouer
<brouer@redhat.com> wrote:
> On Thu, 13 Sep 2018 15:55:29 -0700
> Alexei Starovoitov <alexei.starovoitov@gmail.com> wrote:
>
>> On Thu, Aug 30, 2018 at 1:35 AM, Tariq Toukan <tariqt@mellanox.com> wrote:
>> >
>> >
>> > On 29/08/2018 6:05 PM, Jesper Dangaard Brouer wrote:
>> >>
>> >> Hi Saeed,
>> >>
>> >> I'm having issues loading mlx5 driver on v4.19 kernels (tested both
>> >> net-next and bpf-next), while kernel v4.18 seems to work. It happens
>> >> with a Mellanox ConnectX-5 NIC (and also a CX4-Lx but I removed that
>> >> from the system now).
>> >>
>> >
>> > Hi Jesper,
>> >
>> > Thanks for your report!
>> >
>> > We are working to analyze and debug the issue.
>>
>> looks like serious issue to me... while no news in 2 weeks.
>> any update?
>
> Mellanox took it offlist, and Sep 6th found that this is a regression
> introduced by commit 269d26f47f6f ("net/mlx5: Reduce command polling
> interval"), but only if CONFIG_PREEMPT is on.
>
> I can confirm that reverting this commit fixed the issue (and not the
> firmware upgrade I also did).
>
> I think Moshe (Cc) is responsible for this case, and I expect to soon
> see a revert or alternative solution to this!?
>
> Thanks for the kick Alexei :-)
Thanks you Alexei and Jesper for following up,
the fix is already being tested [1] and will be submitted tomorrow,
as Jesper pointed out the issue happens only with 269d26f47f6f
("net/mlx5: Reduce command polling
interval"), and only if CONFIG_PREEMPT is on.
the only affected kernel is 4.19 which is not GA yet.
[1] https://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux.git/commit/?h=net-mlx5
> --
> Best regards,
> Jesper Dangaard Brouer
> MSc.CS, Principal Kernel Engineer at Red Hat
> LinkedIn: http://www.linkedin.com/in/brouer
^ permalink raw reply
* Re: [PATCH net-next 1/5] net: phy: mscc: add ethtool statistics counters
From: Andrew Lunn @ 2018-09-14 13:29 UTC (permalink / raw)
To: Quentin Schulz
Cc: davem, f.fainelli, allan.nielsen, linux-kernel, netdev,
thomas.petazzoni, Raju Lakkaraju
In-Reply-To: <20180914131645.64k4w4h7ir3u5yuk@qschulz>
> When you change a page, you basically can access only the registers in
> this page so if there are two functions requesting different pages at
> the same time or registers of different pages, it won't work well
> indeed.
>
> > phy_read_page() and phy_write_page() will do the needed locking if
> > this is an issue.
> >
>
> That's awesome! Didn't know it existed. Thanks a ton!
>
> Well, that means I should migrate the whole driver to use
> phy_read/write_paged instead of the phy_read/write that is currently in
> use.
>
> That's impacting performance though as per phy_read/write_paged we read
> the current page, set the desired page, read/write the register, set the
> old page back. That's 4 times more operations.
You can use the lower level locking primatives. See m88e1318_set_wol()
for example.
> Couldn't we use the
> phy_device mutex instead (as it's currently done in the whole driver)?
> Or is it worse/comparable in performance to the suggested solution?
Russell King found a race condition where this breaks. You cannot hold
the phy_device mutex everywhere.
Andrew
^ permalink raw reply
* Re: [PATCH net-next 2/7] net: phy: mscc: add support for VSC8584 PHY
From: Quentin Schulz @ 2018-09-14 13:29 UTC (permalink / raw)
To: Andrew Lunn
Cc: alexandre.belloni, ralf, paul.burton, jhogan, robh+dt,
mark.rutland, davem, f.fainelli, allan.nielsen, linux-mips,
devicetree, linux-kernel, netdev, thomas.petazzoni,
antoine.tenart
In-Reply-To: <20180914131846.GG14865@lunn.ch>
[-- Attachment #1: Type: text/plain, Size: 881 bytes --]
Hi Andrew,
On Fri, Sep 14, 2018 at 03:18:46PM +0200, Andrew Lunn wrote:
> > Most of the init sequence of a PHY of the package is common to all PHYs
> > in the package, thus we use the SMI broadcast feature which enables us
> > to propagate a write in one register of one PHY to all PHYs in the
> > package.
>
> Hi Quinten
>
> Could you say a bit more about the broadcast. Does the SMI broadcast
> go to all PHY everywhere on an MDIO bus, or only all PHYs within one
> package? I'm just thinking about the case you need two of these
> packages to cover 8 switch ports.
>
Ah sorry, that wasn't very explicit. That's a feature on the PHY side so
my wildest guess is that it wouldn't impact any other PHY outside of
this package. Affecting any other PHY on the bus is counter-intuitive to
me but I'll ask the HW engineers for confirmation.
Thanks,
Quentin
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCH net-next] virtio_net: ethtool tx napi configuration
From: Jason Wang @ 2018-09-14 8:08 UTC (permalink / raw)
To: Willem de Bruijn
Cc: Florian Fainelli, Network Development, David Miller, caleb.raitto,
Michael S. Tsirkin, Jon Olson (Google Drive), Willem de Bruijn
In-Reply-To: <CAF=yD-KEcWuYrSofugYBc3kwWvQdFDsv3z_yWx5-JDzyMga1qw@mail.gmail.com>
On 2018年09月14日 12:46, Willem de Bruijn wrote:
> On Thu, Sep 13, 2018 at 11:53 PM Jason Wang <jasowang@redhat.com> wrote:
>>
>>
>> On 2018年09月14日 11:40, Willem de Bruijn wrote:
>>> On Thu, Sep 13, 2018 at 11:27 PM Jason Wang <jasowang@redhat.com> wrote:
>>>>
>>>> On 2018年09月13日 22:58, Willem de Bruijn wrote:
>>>>> On Thu, Sep 13, 2018 at 5:02 AM Jason Wang <jasowang@redhat.com> wrote:
>>>>>> On 2018年09月13日 07:27, Willem de Bruijn wrote:
>>>>>>> On Wed, Sep 12, 2018 at 3:11 PM Willem de Bruijn
>>>>>>> <willemdebruijn.kernel@gmail.com> wrote:
>>>>>>>> On Wed, Sep 12, 2018 at 2:16 PM Florian Fainelli <f.fainelli@gmail.com> wrote:
>>>>>>>>> On 9/12/2018 11:07 AM, Willem de Bruijn wrote:
>>>>>>>>>> On Wed, Sep 12, 2018 at 1:42 PM Florian Fainelli <f.fainelli@gmail.com> wrote:
>>>>>>>>>>> On 9/9/2018 3:44 PM, Willem de Bruijn wrote:
>>>>>>>>>>>> From: Willem de Bruijn <willemb@google.com>
>>>>>>>>>>>>
>>>>>>>>>>>> Implement ethtool .set_coalesce (-C) and .get_coalesce (-c) handlers.
>>>>>>>>>>>> Interrupt moderation is currently not supported, so these accept and
>>>>>>>>>>>> display the default settings of 0 usec and 1 frame.
>>>>>>>>>>>>
>>>>>>>>>>>> Toggle tx napi through a bit in tx-frames. So as to not interfere
>>>>>>>>>>>> with possible future interrupt moderation, use bit 10, well outside
>>>>>>>>>>>> the reasonable range of real interrupt moderation values.
>>>>>>>>>>>>
>>>>>>>>>>>> Changes are not atomic. The tx IRQ, napi BH and transmit path must
>>>>>>>>>>>> be quiesced when switching modes. Only allow changing this setting
>>>>>>>>>>>> when the device is down.
>>>>>>>>>>> Humm, would not a private ethtool flag to switch TX NAPI on/off be more
>>>>>>>>>>> appropriate rather than use the coalescing configuration API here?
>>>>>>>>>> What do you mean by private ethtool flag? A new field in ethtool
>>>>>>>>>> --features (-k)?
>>>>>>>>> I meant using ethtool_drvinfo::n_priv_flags, ETH_SS_PRIV_FLAGS and then
>>>>>>>>> ETHTOOL_GFPFLAGS and ETHTOOL_SPFLAGS to control the toggling of that
>>>>>>>>> private flag. mlx5 has a number of privates flags for instance.
>>>>>>>> Interesting, thanks! I was not at all aware of those ethtool flags.
>>>>>>>> Am having a look. It definitely looks promising.
>>>>>>> Okay, I made that change. That is indeed much cleaner, thanks.
>>>>>>> Let me send the patch, initially as RFC.
>>>>>>>
>>>>>>> I've observed one issue where if we toggle the flag before bringing
>>>>>>> up the device, it hits a kernel BUG at include/linux/netdevice.h:515
>>>>>>>
>>>>>>> BUG_ON(!test_bit(NAPI_STATE_SCHED, &n->state));
>>>>>> This reminds me that we need to check netif_running() before trying to
>>>>>> enable and disable tx napi in ethtool_set_coalesce().
>>>>> The first iteration of my patch checked IFF_UP and effectively
>>>>> only allowed the change when not running. What do you mean
>>>>> by need to check?
>>>> I mean if device is not up, there's no need to toggle napi state and tx
>>>> lock.
>>>>
>>>>> And to respond to the other follow-up notes at once:
>>>>>
>>>>>> Consider we may have interrupt moderation in the future, I tend to use
>>>>>> set_coalesce. Otherwise we may need two steps to enable moderation:
>>>>>>
>>>>>> - tx-napi on
>>>>>> - set_coalesce
>>>>> FWIW, I don't care strongly whether we do this through coalesce or priv_flags.
>>>> Ok.
>>> Since you prefer coalesce, let's go with that (and a revision of your
>>> latest patch).
>> Good to know this.
>>
>>>>>>> + if (!napi_weight)
>>>>>>> + virtqueue_enable_cb(vi->sq[i].vq);
>>>>>> I don't get why we need to disable enable cb here.
>>>>> To avoid entering no-napi mode with too few descriptors to
>>>>> make progress and no way to get out of that state. This is a
>>>>> pretty crude attempt at handling that, admittedly.
>>>> But in this case, we will call enable_cb_delayed() and we will finally
>>>> get a interrupt?
>>> Right. It's a bit of a roundabout way to ensure that
>>> netif_tx_wake_queue and thus eventually free_old_xmit_skbs are called.
>>> It might make more sense to just wake the device without going through
>>> an interrupt.
>> I'm not sure I get this. If we don't enable tx napi, we tend to delay TX
>> interrupt if we found the ring is about to full to avoid interrupt
>> storm, so we're probably ok in this case.
> I'm only concerned about the transition state when converting from
> napi to no-napi when the queue is stopped and tx interrupt disabled.
>
> With napi mode the interrupt is only disabled if napi is scheduled,
> in which case it will eventually reenable the interrupt. But when
> switching to no-napi mode in this state no progress will be made.
>
> But it seems this cannot happen. When converting to no-napi
> mode, set_coalesce waits for napi to complete in napi_disable.
> So the interrupt should always start enabled when transitioning
> into no-napi mode.
Yes, I see.
Thanks
^ permalink raw reply
* Re: [PATCH net-next 2/7] net: phy: mscc: add support for VSC8584 PHY
From: Andrew Lunn @ 2018-09-14 13:18 UTC (permalink / raw)
To: Quentin Schulz
Cc: alexandre.belloni, ralf, paul.burton, jhogan, robh+dt,
mark.rutland, davem, f.fainelli, allan.nielsen, linux-mips,
devicetree, linux-kernel, netdev, thomas.petazzoni,
antoine.tenart
In-Reply-To: <a61d9affd3f1ec9deb60c882cce1daf37fbe2427.1536916714.git-series.quentin.schulz@bootlin.com>
> Most of the init sequence of a PHY of the package is common to all PHYs
> in the package, thus we use the SMI broadcast feature which enables us
> to propagate a write in one register of one PHY to all PHYs in the
> package.
Hi Quinten
Could you say a bit more about the broadcast. Does the SMI broadcast
go to all PHY everywhere on an MDIO bus, or only all PHYs within one
package? I'm just thinking about the case you need two of these
packages to cover 8 switch ports.
Thanks
Andrew
^ permalink raw reply
* Re: [PATCH net-next 1/5] net: phy: mscc: add ethtool statistics counters
From: Quentin Schulz @ 2018-09-14 13:16 UTC (permalink / raw)
To: Andrew Lunn
Cc: davem, f.fainelli, allan.nielsen, linux-kernel, netdev,
thomas.petazzoni, Raju Lakkaraju
In-Reply-To: <20180914130156.GB14865@lunn.ch>
[-- Attachment #1: Type: text/plain, Size: 3042 bytes --]
Hi Andrew,
On Fri, Sep 14, 2018 at 03:01:56PM +0200, Andrew Lunn wrote:
> Hi Quentin
>
> > +static struct vsc85xx_hw_stat vsc85xx_hw_stats[] = {
>
> You could add a const to that.
>
ACK.
> > + {
> > + .string = "phy_receive_errors",
> > + .reg = MSCC_PHY_ERR_RX_CNT,
> > + .page = MSCC_PHY_PAGE_STANDARD,
> > + .mask = ERR_CNT_MASK,
> > + }, {
> > + .string = "phy_false_carrier",
> > + .reg = MSCC_PHY_ERR_FALSE_CARRIER_CNT,
> > + .page = MSCC_PHY_PAGE_STANDARD,
> > + .mask = ERR_CNT_MASK,
> > + }, {
> > + .string = "phy_cu_media_link_disconnect",
> > + .reg = MSCC_PHY_ERR_LINK_DISCONNECT_CNT,
> > + .page = MSCC_PHY_PAGE_STANDARD,
> > + .mask = ERR_CNT_MASK,
> > + }, {
> > + .string = "phy_cu_media_crc_good_count",
> > + .reg = MSCC_PHY_CU_MEDIA_CRC_VALID_CNT,
> > + .page = MSCC_PHY_PAGE_EXTENDED,
> > + .mask = VALID_CRC_CNT_CRC_MASK,
> > + }, {
> > + .string = "phy_cu_media_crc_error_count",
> > + .reg = MSCC_PHY_EXT_PHY_CNTL_4,
> > + .page = MSCC_PHY_PAGE_EXTENDED,
> > + .mask = ERR_CNT_MASK,
> > + },
> > +};
>
> > +static u64 vsc85xx_get_stat(struct phy_device *phydev, int i)
> > +{
> > + struct vsc8531_private *priv = phydev->priv;
> > + int val;
> > + u64 ret;
> > +
> > + vsc85xx_phy_page_set(phydev, priv->hw_stats[i].page);
>
> I might of asked this before...
>
> Does changing the page effect registers in the lower range? It is
> possible for other operations to happen at the same time, and you
> don't want for example a status read to happen from some other
> extended page register because a statistics read is happening.
>
When you change a page, you basically can access only the registers in
this page so if there are two functions requesting different pages at
the same time or registers of different pages, it won't work well
indeed.
> phy_read_page() and phy_write_page() will do the needed locking if
> this is an issue.
>
That's awesome! Didn't know it existed. Thanks a ton!
Well, that means I should migrate the whole driver to use
phy_read/write_paged instead of the phy_read/write that is currently in
use.
That's impacting performance though as per phy_read/write_paged we read
the current page, set the desired page, read/write the register, set the
old page back. That's 4 times more operations. Couldn't we use the
phy_device mutex instead (as it's currently done in the whole driver)?
Or is it worse/comparable in performance to the suggested solution?
> > @@ -673,6 +782,13 @@ static int vsc85xx_probe(struct phy_device *phydev)
> > vsc8531->rate_magic = rate_magic;
> > vsc8531->nleds = 2;
> > vsc8531->supp_led_modes = VSC85XX_SUPP_LED_MODES;
> > + vsc8531->hw_stats = vsc85xx_hw_stats;
> > + vsc8531->nstats = ARRAY_SIZE(vsc85xx_hw_stats);
> > + vsc8531->stats = devm_kzalloc(&phydev->mdio.dev,
> > + sizeof(u64) * vsc8531->nstats,
> > + GFP_KERNEL);
>
> devm_kmalloc_array()? The security people prefer that.
>
ACK.
Thanks,
Quentin
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: Regression: kernel 4.14 an later very slow with many ipsec tunnels
From: Christophe Gouault @ 2018-09-14 8:01 UTC (permalink / raw)
To: Steffen Klassert
Cc: fw, David S. Miller, linux, netdev, linux-kernel, torvalds
In-Reply-To: <20180914060132.GE23674@gauss3.secunet.de>
Le ven. 14 sept. 2018 à 08:01, Steffen Klassert
<steffen.klassert@secunet.com> a écrit :
> > > The hash threshold can be configured like this:
> > >
> > > ip x p set hthresh4 0 0
> > >
> > > This sets the hash threshold to local /0 and remote /0 netmasks.
> > > With this configuration, all policies should go to the hashtable.
> >
> > Yes, but won't they all be hashed to same bucket?
> >
> > [ jhash(addr & 0, addr & 0) ] ?
>
> Hm, yes. Maybe something between /0 and /32 makes more sense.
Indeed, hash thresholds not only determine which policies will be
hashed, but also the number of bits of the local and remote address
that will be used to calculate the hash key. Big thresholds mean
potentially fewer hashed policies, but better distribution in the hash
table, and vice versa.
A good trade off must be found depending on the prefix lengths used in
your policies.
Best regards,
Christophe
^ permalink raw reply
* [PATCH][net-next] net: move definition of pcpu_lstats to header file
From: Li RongQing @ 2018-09-14 8:00 UTC (permalink / raw)
To: netdev
pcpu_lstats is defined in several files, so unify them as one
and move to header file
Signed-off-by: Zhang Yu <zhangyu31@baidu.com>
Signed-off-by: Li RongQing <lirongqing@baidu.com>
---
drivers/net/loopback.c | 6 ------
drivers/net/nlmon.c | 6 ------
drivers/net/vsockmon.c | 14 ++++----------
include/linux/netdevice.h | 6 ++++++
4 files changed, 10 insertions(+), 22 deletions(-)
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index 30612497643c..a7207fa7e451 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -59,12 +59,6 @@
#include <net/net_namespace.h>
#include <linux/u64_stats_sync.h>
-struct pcpu_lstats {
- u64 packets;
- u64 bytes;
- struct u64_stats_sync syncp;
-};
-
/* The higher levels take care of making this non-reentrant (it's
* called with bh's disabled).
*/
diff --git a/drivers/net/nlmon.c b/drivers/net/nlmon.c
index 4b22955de191..dd0db7534cb3 100644
--- a/drivers/net/nlmon.c
+++ b/drivers/net/nlmon.c
@@ -6,12 +6,6 @@
#include <linux/if_arp.h>
#include <net/rtnetlink.h>
-struct pcpu_lstats {
- u64 packets;
- u64 bytes;
- struct u64_stats_sync syncp;
-};
-
static netdev_tx_t nlmon_xmit(struct sk_buff *skb, struct net_device *dev)
{
int len = skb->len;
diff --git a/drivers/net/vsockmon.c b/drivers/net/vsockmon.c
index c28bdce14fd5..7bad5c95551f 100644
--- a/drivers/net/vsockmon.c
+++ b/drivers/net/vsockmon.c
@@ -11,12 +11,6 @@
#define DEFAULT_MTU (VIRTIO_VSOCK_MAX_PKT_BUF_SIZE + \
sizeof(struct af_vsockmon_hdr))
-struct pcpu_lstats {
- u64 rx_packets;
- u64 rx_bytes;
- struct u64_stats_sync syncp;
-};
-
static int vsockmon_dev_init(struct net_device *dev)
{
dev->lstats = netdev_alloc_pcpu_stats(struct pcpu_lstats);
@@ -56,8 +50,8 @@ static netdev_tx_t vsockmon_xmit(struct sk_buff *skb, struct net_device *dev)
struct pcpu_lstats *stats = this_cpu_ptr(dev->lstats);
u64_stats_update_begin(&stats->syncp);
- stats->rx_bytes += len;
- stats->rx_packets++;
+ stats->bytes += len;
+ stats->packets++;
u64_stats_update_end(&stats->syncp);
dev_kfree_skb(skb);
@@ -80,8 +74,8 @@ vsockmon_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
do {
start = u64_stats_fetch_begin_irq(&vstats->syncp);
- tbytes = vstats->rx_bytes;
- tpackets = vstats->rx_packets;
+ tbytes = vstats->bytes;
+ tpackets = vstats->packets;
} while (u64_stats_fetch_retry_irq(&vstats->syncp, start));
packets += tpackets;
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index e2b3bd750c98..baed5d5088c5 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2382,6 +2382,12 @@ struct pcpu_sw_netstats {
struct u64_stats_sync syncp;
};
+struct pcpu_lstats {
+ u64 packets;
+ u64 bytes;
+ struct u64_stats_sync syncp;
+};
+
#define __netdev_alloc_pcpu_stats(type, gfp) \
({ \
typeof(type) __percpu *pcpu_stats = alloc_percpu_gfp(type, gfp);\
--
2.16.2
^ permalink raw reply related
* Re: [PATCH net-next 1/7] dt-bindings: net: vsc8531: add two additional LED modes for VSC8584
From: Andrew Lunn @ 2018-09-14 13:11 UTC (permalink / raw)
To: Quentin Schulz
Cc: alexandre.belloni, ralf, paul.burton, jhogan, robh+dt,
mark.rutland, davem, f.fainelli, allan.nielsen, linux-mips,
devicetree, linux-kernel, netdev, thomas.petazzoni,
antoine.tenart
In-Reply-To: <f54f6cda7f505d99531e33626f8d4e6f1dc084ec.1536916714.git-series.quentin.schulz@bootlin.com>
On Fri, Sep 14, 2018 at 11:44:22AM +0200, Quentin Schulz wrote:
> The VSC8584 (and most likely other PHYs in the same generation) has two
> additional LED modes that can be picked, so let's add them.
>
> Signed-off-by: Quentin Schulz <quentin.schulz@bootlin.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply
* Re: [PATCH net-next 5/5] net: phy: mscc: remove unneeded temporary variable
From: Andrew Lunn @ 2018-09-14 13:06 UTC (permalink / raw)
To: Quentin Schulz
Cc: davem, f.fainelli, allan.nielsen, linux-kernel, netdev,
thomas.petazzoni
In-Reply-To: <d9cca8eef36bb8918c9ed28574b79b7674fd36f6.1536913944.git-series.quentin.schulz@bootlin.com>
On Fri, Sep 14, 2018 at 10:33:47AM +0200, Quentin Schulz wrote:
> Here, the rc variable is either used only for the condition right after
> the assignment or right before being used as the return value of the
> function it's being used in.
>
> So let's remove this unneeded temporary variable whenever possible.
>
> Signed-off-by: Quentin Schulz <quentin.schulz@bootlin.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply
* Re: [PATCH net-next 4/5] net: phy: mscc: shorten `x != 0` condition to `x`
From: Andrew Lunn @ 2018-09-14 13:05 UTC (permalink / raw)
To: Quentin Schulz
Cc: davem, f.fainelli, allan.nielsen, linux-kernel, netdev,
thomas.petazzoni
In-Reply-To: <2efac3971c41837fec6001018c1275d81286512a.1536913944.git-series.quentin.schulz@bootlin.com>
On Fri, Sep 14, 2018 at 10:33:46AM +0200, Quentin Schulz wrote:
> `if (x != 0)` is basically a more verbose version of `if (x)` so let's
> use the latter so it's consistent throughout the whole driver.
>
> Signed-off-by: Quentin Schulz <quentin.schulz@bootlin.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply
* Re: [PATCH net-next 3/5] net: phy: mscc: remove unneeded parenthesis
From: Andrew Lunn @ 2018-09-14 13:04 UTC (permalink / raw)
To: Quentin Schulz
Cc: davem, f.fainelli, allan.nielsen, linux-kernel, netdev,
thomas.petazzoni
In-Reply-To: <e3a1a9940e18c69ecf9aaecc3e2d9bf2a180a939.1536913944.git-series.quentin.schulz@bootlin.com>
On Fri, Sep 14, 2018 at 10:33:45AM +0200, Quentin Schulz wrote:
> The == operator precedes the || operator, so we can remove the
> parenthesis around (a == b) || (c == d).
>
> The condition is rather explicit and short so removing the parenthesis
> definitely does not make it harder to read.
>
> Signed-off-by: Quentin Schulz <quentin.schulz@bootlin.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply
* Re: [PATCH net-next 1/5] net: phy: mscc: add ethtool statistics counters
From: Andrew Lunn @ 2018-09-14 13:01 UTC (permalink / raw)
To: Quentin Schulz
Cc: davem, f.fainelli, allan.nielsen, linux-kernel, netdev,
thomas.petazzoni, Raju Lakkaraju
In-Reply-To: <e220fe75053e200f91554b752905d84b14b76eb6.1536913944.git-series.quentin.schulz@bootlin.com>
Hi Quentin
> +static struct vsc85xx_hw_stat vsc85xx_hw_stats[] = {
You could add a const to that.
> + {
> + .string = "phy_receive_errors",
> + .reg = MSCC_PHY_ERR_RX_CNT,
> + .page = MSCC_PHY_PAGE_STANDARD,
> + .mask = ERR_CNT_MASK,
> + }, {
> + .string = "phy_false_carrier",
> + .reg = MSCC_PHY_ERR_FALSE_CARRIER_CNT,
> + .page = MSCC_PHY_PAGE_STANDARD,
> + .mask = ERR_CNT_MASK,
> + }, {
> + .string = "phy_cu_media_link_disconnect",
> + .reg = MSCC_PHY_ERR_LINK_DISCONNECT_CNT,
> + .page = MSCC_PHY_PAGE_STANDARD,
> + .mask = ERR_CNT_MASK,
> + }, {
> + .string = "phy_cu_media_crc_good_count",
> + .reg = MSCC_PHY_CU_MEDIA_CRC_VALID_CNT,
> + .page = MSCC_PHY_PAGE_EXTENDED,
> + .mask = VALID_CRC_CNT_CRC_MASK,
> + }, {
> + .string = "phy_cu_media_crc_error_count",
> + .reg = MSCC_PHY_EXT_PHY_CNTL_4,
> + .page = MSCC_PHY_PAGE_EXTENDED,
> + .mask = ERR_CNT_MASK,
> + },
> +};
> +static u64 vsc85xx_get_stat(struct phy_device *phydev, int i)
> +{
> + struct vsc8531_private *priv = phydev->priv;
> + int val;
> + u64 ret;
> +
> + vsc85xx_phy_page_set(phydev, priv->hw_stats[i].page);
I might of asked this before...
Does changing the page effect registers in the lower range? It is
possible for other operations to happen at the same time, and you
don't want for example a status read to happen from some other
extended page register because a statistics read is happening.
phy_read_page() and phy_write_page() will do the needed locking if
this is an issue.
> @@ -673,6 +782,13 @@ static int vsc85xx_probe(struct phy_device *phydev)
> vsc8531->rate_magic = rate_magic;
> vsc8531->nleds = 2;
> vsc8531->supp_led_modes = VSC85XX_SUPP_LED_MODES;
> + vsc8531->hw_stats = vsc85xx_hw_stats;
> + vsc8531->nstats = ARRAY_SIZE(vsc85xx_hw_stats);
> + vsc8531->stats = devm_kzalloc(&phydev->mdio.dev,
> + sizeof(u64) * vsc8531->nstats,
> + GFP_KERNEL);
devm_kmalloc_array()? The security people prefer that.
> + if (!vsc8531->stats)
> + return -ENOMEM;
>
> return vsc85xx_dt_led_modes_get(phydev, default_mode);
> }
Andrew
^ 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