* [net-next RFC PATCH v3 1/4] net: phy: aquantia: move to separate directory
@ 2023-11-02 15:00 Christian Marangi
2023-11-02 15:00 ` [net-next RFC PATCH v3 2/4] net: phy: aquantia: move MMD_VEND define to header Christian Marangi
` (3 more replies)
0 siblings, 4 replies; 12+ messages in thread
From: Christian Marangi @ 2023-11-02 15:00 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Andrew Lunn,
Heiner Kallweit, Russell King, Christian Marangi, Robert Marko,
Vladimir Oltean, netdev, devicetree, linux-kernel
Move aquantia PHY driver to separate driectory in preparation for
firmware loading support to keep things tidy.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
Changes v3:
- Add this patch
drivers/net/phy/Kconfig | 7 ++-----
drivers/net/phy/Makefile | 6 +-----
drivers/net/phy/aquantia/Kconfig | 5 +++++
drivers/net/phy/aquantia/Makefile | 6 ++++++
drivers/net/phy/{ => aquantia}/aquantia.h | 0
drivers/net/phy/{ => aquantia}/aquantia_hwmon.c | 0
drivers/net/phy/{ => aquantia}/aquantia_main.c | 0
7 files changed, 14 insertions(+), 10 deletions(-)
create mode 100644 drivers/net/phy/aquantia/Kconfig
create mode 100644 drivers/net/phy/aquantia/Makefile
rename drivers/net/phy/{ => aquantia}/aquantia.h (100%)
rename drivers/net/phy/{ => aquantia}/aquantia_hwmon.c (100%)
rename drivers/net/phy/{ => aquantia}/aquantia_main.c (100%)
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 421d2b62918f..4b2451dd6c45 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -68,6 +68,8 @@ config SFP
comment "MII PHY device drivers"
+source "drivers/net/phy/aquantia/Kconfig"
+
config AMD_PHY
tristate "AMD and Altima PHYs"
help
@@ -96,11 +98,6 @@ config ADIN1100_PHY
Currently supports the:
- ADIN1100 - Robust,Industrial, Low Power 10BASE-T1L Ethernet PHY
-config AQUANTIA_PHY
- tristate "Aquantia PHYs"
- help
- Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405
-
config AX88796B_PHY
tristate "Asix PHYs"
help
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index c945ed9bd14b..f65e85c91fc1 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -35,11 +35,7 @@ obj-y += $(sfp-obj-y) $(sfp-obj-m)
obj-$(CONFIG_ADIN_PHY) += adin.o
obj-$(CONFIG_ADIN1100_PHY) += adin1100.o
obj-$(CONFIG_AMD_PHY) += amd.o
-aquantia-objs += aquantia_main.o
-ifdef CONFIG_HWMON
-aquantia-objs += aquantia_hwmon.o
-endif
-obj-$(CONFIG_AQUANTIA_PHY) += aquantia.o
+obj-$(CONFIG_AQUANTIA_PHY) += aquantia/
obj-$(CONFIG_AT803X_PHY) += at803x.o
obj-$(CONFIG_AX88796B_PHY) += ax88796b.o
obj-$(CONFIG_BCM54140_PHY) += bcm54140.o
diff --git a/drivers/net/phy/aquantia/Kconfig b/drivers/net/phy/aquantia/Kconfig
new file mode 100644
index 000000000000..226146417a6a
--- /dev/null
+++ b/drivers/net/phy/aquantia/Kconfig
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config AQUANTIA_PHY
+ tristate "Aquantia PHYs"
+ help
+ Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405
diff --git a/drivers/net/phy/aquantia/Makefile b/drivers/net/phy/aquantia/Makefile
new file mode 100644
index 000000000000..346f350bc084
--- /dev/null
+++ b/drivers/net/phy/aquantia/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+aquantia-objs += aquantia_main.o
+ifdef CONFIG_HWMON
+aquantia-objs += aquantia_hwmon.o
+endif
+obj-$(CONFIG_AQUANTIA_PHY) += aquantia.o
diff --git a/drivers/net/phy/aquantia.h b/drivers/net/phy/aquantia/aquantia.h
similarity index 100%
rename from drivers/net/phy/aquantia.h
rename to drivers/net/phy/aquantia/aquantia.h
diff --git a/drivers/net/phy/aquantia_hwmon.c b/drivers/net/phy/aquantia/aquantia_hwmon.c
similarity index 100%
rename from drivers/net/phy/aquantia_hwmon.c
rename to drivers/net/phy/aquantia/aquantia_hwmon.c
diff --git a/drivers/net/phy/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c
similarity index 100%
rename from drivers/net/phy/aquantia_main.c
rename to drivers/net/phy/aquantia/aquantia_main.c
--
2.40.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [net-next RFC PATCH v3 2/4] net: phy: aquantia: move MMD_VEND define to header
2023-11-02 15:00 [net-next RFC PATCH v3 1/4] net: phy: aquantia: move to separate directory Christian Marangi
@ 2023-11-02 15:00 ` Christian Marangi
2023-11-02 17:19 ` Andrew Lunn
2023-11-02 15:00 ` [net-next RFC PATCH v3 3/4] net: phy: aquantia: add firmware load support Christian Marangi
` (2 subsequent siblings)
3 siblings, 1 reply; 12+ messages in thread
From: Christian Marangi @ 2023-11-02 15:00 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Andrew Lunn,
Heiner Kallweit, Russell King, Christian Marangi, Robert Marko,
Vladimir Oltean, netdev, devicetree, linux-kernel
Move MMD_VEND define to header to clean things up and in preparation for
firmware loading support that require some define placed in
aquantia_main.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
Changes v3:
- Add this patch
drivers/net/phy/aquantia/aquantia.h | 69 +++++++++++++++++++++++
drivers/net/phy/aquantia/aquantia_hwmon.c | 14 -----
drivers/net/phy/aquantia/aquantia_main.c | 55 ------------------
3 files changed, 69 insertions(+), 69 deletions(-)
diff --git a/drivers/net/phy/aquantia/aquantia.h b/drivers/net/phy/aquantia/aquantia.h
index c684b65c642c..f0c767c4fad1 100644
--- a/drivers/net/phy/aquantia/aquantia.h
+++ b/drivers/net/phy/aquantia/aquantia.h
@@ -9,6 +9,75 @@
#include <linux/device.h>
#include <linux/phy.h>
+/* Vendor specific 1, MDIO_MMD_VEND1 */
+#define VEND1_GLOBAL_FW_ID 0x0020
+#define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8)
+#define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0)
+
+/* The following registers all have similar layouts; first the registers... */
+#define VEND1_GLOBAL_CFG_10M 0x0310
+#define VEND1_GLOBAL_CFG_100M 0x031b
+#define VEND1_GLOBAL_CFG_1G 0x031c
+#define VEND1_GLOBAL_CFG_2_5G 0x031d
+#define VEND1_GLOBAL_CFG_5G 0x031e
+#define VEND1_GLOBAL_CFG_10G 0x031f
+/* ...and now the fields */
+#define VEND1_GLOBAL_CFG_RATE_ADAPT GENMASK(8, 7)
+#define VEND1_GLOBAL_CFG_RATE_ADAPT_NONE 0
+#define VEND1_GLOBAL_CFG_RATE_ADAPT_USX 1
+#define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2
+
+/* Vendor specific 1, MDIO_MMD_VEND2 */
+#define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421
+#define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422
+#define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423
+#define VEND1_THERMAL_PROV_LOW_TEMP_WARN 0xc424
+#define VEND1_THERMAL_STAT1 0xc820
+#define VEND1_THERMAL_STAT2 0xc821
+#define VEND1_THERMAL_STAT2_VALID BIT(0)
+#define VEND1_GENERAL_STAT1 0xc830
+#define VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL BIT(14)
+#define VEND1_GENERAL_STAT1_LOW_TEMP_FAIL BIT(13)
+#define VEND1_GENERAL_STAT1_HIGH_TEMP_WARN BIT(12)
+#define VEND1_GENERAL_STAT1_LOW_TEMP_WARN BIT(11)
+
+#define VEND1_GLOBAL_GEN_STAT2 0xc831
+#define VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG BIT(15)
+
+#define VEND1_GLOBAL_RSVD_STAT1 0xc885
+#define VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID GENMASK(7, 4)
+#define VEND1_GLOBAL_RSVD_STAT1_PROV_ID GENMASK(3, 0)
+
+#define VEND1_GLOBAL_RSVD_STAT9 0xc88d
+#define VEND1_GLOBAL_RSVD_STAT9_MODE GENMASK(7, 0)
+#define VEND1_GLOBAL_RSVD_STAT9_1000BT2 0x23
+
+#define VEND1_GLOBAL_INT_STD_STATUS 0xfc00
+#define VEND1_GLOBAL_INT_VEND_STATUS 0xfc01
+
+#define VEND1_GLOBAL_INT_STD_MASK 0xff00
+#define VEND1_GLOBAL_INT_STD_MASK_PMA1 BIT(15)
+#define VEND1_GLOBAL_INT_STD_MASK_PMA2 BIT(14)
+#define VEND1_GLOBAL_INT_STD_MASK_PCS1 BIT(13)
+#define VEND1_GLOBAL_INT_STD_MASK_PCS2 BIT(12)
+#define VEND1_GLOBAL_INT_STD_MASK_PCS3 BIT(11)
+#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS1 BIT(10)
+#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS2 BIT(9)
+#define VEND1_GLOBAL_INT_STD_MASK_AN1 BIT(8)
+#define VEND1_GLOBAL_INT_STD_MASK_AN2 BIT(7)
+#define VEND1_GLOBAL_INT_STD_MASK_GBE BIT(6)
+#define VEND1_GLOBAL_INT_STD_MASK_ALL BIT(0)
+
+#define VEND1_GLOBAL_INT_VEND_MASK 0xff01
+#define VEND1_GLOBAL_INT_VEND_MASK_PMA BIT(15)
+#define VEND1_GLOBAL_INT_VEND_MASK_PCS BIT(14)
+#define VEND1_GLOBAL_INT_VEND_MASK_PHY_XS BIT(13)
+#define VEND1_GLOBAL_INT_VEND_MASK_AN BIT(12)
+#define VEND1_GLOBAL_INT_VEND_MASK_GBE BIT(11)
+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL1 BIT(2)
+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2 BIT(1)
+#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 BIT(0)
+
#if IS_REACHABLE(CONFIG_HWMON)
int aqr_hwmon_probe(struct phy_device *phydev);
#else
diff --git a/drivers/net/phy/aquantia/aquantia_hwmon.c b/drivers/net/phy/aquantia/aquantia_hwmon.c
index 0da451e46f69..7b3c49c3bf49 100644
--- a/drivers/net/phy/aquantia/aquantia_hwmon.c
+++ b/drivers/net/phy/aquantia/aquantia_hwmon.c
@@ -13,20 +13,6 @@
#include "aquantia.h"
-/* Vendor specific 1, MDIO_MMD_VEND2 */
-#define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421
-#define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422
-#define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423
-#define VEND1_THERMAL_PROV_LOW_TEMP_WARN 0xc424
-#define VEND1_THERMAL_STAT1 0xc820
-#define VEND1_THERMAL_STAT2 0xc821
-#define VEND1_THERMAL_STAT2_VALID BIT(0)
-#define VEND1_GENERAL_STAT1 0xc830
-#define VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL BIT(14)
-#define VEND1_GENERAL_STAT1_LOW_TEMP_FAIL BIT(13)
-#define VEND1_GENERAL_STAT1_HIGH_TEMP_WARN BIT(12)
-#define VEND1_GENERAL_STAT1_LOW_TEMP_WARN BIT(11)
-
#if IS_REACHABLE(CONFIG_HWMON)
static umode_t aqr_hwmon_is_visible(const void *data,
diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c
index 334a6904ca5a..4498426e9a52 100644
--- a/drivers/net/phy/aquantia/aquantia_main.c
+++ b/drivers/net/phy/aquantia/aquantia_main.c
@@ -91,61 +91,6 @@
#define MDIO_C22EXT_STAT_SGMII_TX_FRAME_ALIGN_ERR 0xd31a
#define MDIO_C22EXT_STAT_SGMII_TX_RUNT_FRAMES 0xd31b
-/* Vendor specific 1, MDIO_MMD_VEND1 */
-#define VEND1_GLOBAL_FW_ID 0x0020
-#define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8)
-#define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0)
-
-#define VEND1_GLOBAL_GEN_STAT2 0xc831
-#define VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG BIT(15)
-
-/* The following registers all have similar layouts; first the registers... */
-#define VEND1_GLOBAL_CFG_10M 0x0310
-#define VEND1_GLOBAL_CFG_100M 0x031b
-#define VEND1_GLOBAL_CFG_1G 0x031c
-#define VEND1_GLOBAL_CFG_2_5G 0x031d
-#define VEND1_GLOBAL_CFG_5G 0x031e
-#define VEND1_GLOBAL_CFG_10G 0x031f
-/* ...and now the fields */
-#define VEND1_GLOBAL_CFG_RATE_ADAPT GENMASK(8, 7)
-#define VEND1_GLOBAL_CFG_RATE_ADAPT_NONE 0
-#define VEND1_GLOBAL_CFG_RATE_ADAPT_USX 1
-#define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2
-
-#define VEND1_GLOBAL_RSVD_STAT1 0xc885
-#define VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID GENMASK(7, 4)
-#define VEND1_GLOBAL_RSVD_STAT1_PROV_ID GENMASK(3, 0)
-
-#define VEND1_GLOBAL_RSVD_STAT9 0xc88d
-#define VEND1_GLOBAL_RSVD_STAT9_MODE GENMASK(7, 0)
-#define VEND1_GLOBAL_RSVD_STAT9_1000BT2 0x23
-
-#define VEND1_GLOBAL_INT_STD_STATUS 0xfc00
-#define VEND1_GLOBAL_INT_VEND_STATUS 0xfc01
-
-#define VEND1_GLOBAL_INT_STD_MASK 0xff00
-#define VEND1_GLOBAL_INT_STD_MASK_PMA1 BIT(15)
-#define VEND1_GLOBAL_INT_STD_MASK_PMA2 BIT(14)
-#define VEND1_GLOBAL_INT_STD_MASK_PCS1 BIT(13)
-#define VEND1_GLOBAL_INT_STD_MASK_PCS2 BIT(12)
-#define VEND1_GLOBAL_INT_STD_MASK_PCS3 BIT(11)
-#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS1 BIT(10)
-#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS2 BIT(9)
-#define VEND1_GLOBAL_INT_STD_MASK_AN1 BIT(8)
-#define VEND1_GLOBAL_INT_STD_MASK_AN2 BIT(7)
-#define VEND1_GLOBAL_INT_STD_MASK_GBE BIT(6)
-#define VEND1_GLOBAL_INT_STD_MASK_ALL BIT(0)
-
-#define VEND1_GLOBAL_INT_VEND_MASK 0xff01
-#define VEND1_GLOBAL_INT_VEND_MASK_PMA BIT(15)
-#define VEND1_GLOBAL_INT_VEND_MASK_PCS BIT(14)
-#define VEND1_GLOBAL_INT_VEND_MASK_PHY_XS BIT(13)
-#define VEND1_GLOBAL_INT_VEND_MASK_AN BIT(12)
-#define VEND1_GLOBAL_INT_VEND_MASK_GBE BIT(11)
-#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL1 BIT(2)
-#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2 BIT(1)
-#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 BIT(0)
-
/* Sleep and timeout for checking if the Processor-Intensive
* MDIO operation is finished
*/
--
2.40.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [net-next RFC PATCH v3 3/4] net: phy: aquantia: add firmware load support
2023-11-02 15:00 [net-next RFC PATCH v3 1/4] net: phy: aquantia: move to separate directory Christian Marangi
2023-11-02 15:00 ` [net-next RFC PATCH v3 2/4] net: phy: aquantia: move MMD_VEND define to header Christian Marangi
@ 2023-11-02 15:00 ` Christian Marangi
2023-11-02 17:37 ` Andrew Lunn
2023-11-02 15:00 ` [net-next RFC PATCH v3 4/4] dt-bindings: Document bindings for Marvell Aquantia PHY Christian Marangi
2023-11-02 15:03 ` [net-next RFC PATCH v3 1/4] net: phy: aquantia: move to separate directory Andrew Lunn
3 siblings, 1 reply; 12+ messages in thread
From: Christian Marangi @ 2023-11-02 15:00 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Andrew Lunn,
Heiner Kallweit, Russell King, Christian Marangi, Robert Marko,
Vladimir Oltean, netdev, devicetree, linux-kernel
From: Robert Marko <robimarko@gmail.com>
Aquantia PHY-s require firmware to be loaded before they start operating.
It can be automatically loaded in case when there is a SPI-NOR connected
to Aquantia PHY-s or can be loaded from the host via MDIO.
This patch adds support for loading the firmware via MDIO as in most cases
there is no SPI-NOR being used to save on cost.
Firmware loading code itself is ported from mainline U-boot with cleanups.
The firmware has mixed values both in big and little endian.
PHY core itself is big-endian but it expects values to be in little-endian.
The firmware is little-endian but CRC-16 value for it is stored at the end
of firmware in big-endian.
It seems the PHY does the conversion internally from firmware that is
little-endian to the PHY that is big-endian on using the mailbox
but mailbox returns a big-endian CRC-16 to verify the written data
integrity.
Co-developed-by: Christian Marangi <ansuelsmth@gmail.com>
Signed-off-by: Robert Marko <robimarko@gmail.com>
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
Changes v3:
- Back to RFC due to merge window
- Use unaligned macro instead of memcpy
- Spam sanity check as firmware is evil
- Add print to signal the user the source of the fw (FS or NVMEM)
Changes v2:
- Move out of RFC
- Address sanity check for offsets
- Add additional comments on firmware load check
- Fix some typo
- Capitalize CRC in comments
- Rename load_sysfs to load_fs
drivers/net/phy/aquantia/Kconfig | 1 +
drivers/net/phy/aquantia/Makefile | 2 +-
drivers/net/phy/aquantia/aquantia.h | 32 ++
drivers/net/phy/aquantia/aquantia_firmware.c | 367 +++++++++++++++++++
drivers/net/phy/aquantia/aquantia_main.c | 6 +
5 files changed, 407 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/phy/aquantia/aquantia_firmware.c
diff --git a/drivers/net/phy/aquantia/Kconfig b/drivers/net/phy/aquantia/Kconfig
index 226146417a6a..a35de4b9b554 100644
--- a/drivers/net/phy/aquantia/Kconfig
+++ b/drivers/net/phy/aquantia/Kconfig
@@ -1,5 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
config AQUANTIA_PHY
tristate "Aquantia PHYs"
+ select CRC_CCITT
help
Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405
diff --git a/drivers/net/phy/aquantia/Makefile b/drivers/net/phy/aquantia/Makefile
index 346f350bc084..aa77fb63c8ec 100644
--- a/drivers/net/phy/aquantia/Makefile
+++ b/drivers/net/phy/aquantia/Makefile
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
-aquantia-objs += aquantia_main.o
+aquantia-objs += aquantia_main.o aquantia_firmware.o
ifdef CONFIG_HWMON
aquantia-objs += aquantia_hwmon.o
endif
diff --git a/drivers/net/phy/aquantia/aquantia.h b/drivers/net/phy/aquantia/aquantia.h
index f0c767c4fad1..9ed38972abdb 100644
--- a/drivers/net/phy/aquantia/aquantia.h
+++ b/drivers/net/phy/aquantia/aquantia.h
@@ -10,10 +10,35 @@
#include <linux/phy.h>
/* Vendor specific 1, MDIO_MMD_VEND1 */
+#define VEND1_GLOBAL_SC 0x0
+#define VEND1_GLOBAL_SC_SOFT_RESET BIT(15)
+#define VEND1_GLOBAL_SC_LOW_POWER BIT(11)
+
#define VEND1_GLOBAL_FW_ID 0x0020
#define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8)
#define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0)
+#define VEND1_GLOBAL_MAILBOX_INTERFACE1 0x0200
+#define VEND1_GLOBAL_MAILBOX_INTERFACE1_EXECUTE BIT(15)
+#define VEND1_GLOBAL_MAILBOX_INTERFACE1_WRITE BIT(14)
+#define VEND1_GLOBAL_MAILBOX_INTERFACE1_CRC_RESET BIT(12)
+#define VEND1_GLOBAL_MAILBOX_INTERFACE1_BUSY BIT(8)
+
+#define VEND1_GLOBAL_MAILBOX_INTERFACE2 0x0201
+#define VEND1_GLOBAL_MAILBOX_INTERFACE3 0x0202
+#define VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR_MASK GENMASK(15, 0)
+#define VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR_MASK, (u16)((x) >> 16))
+#define VEND1_GLOBAL_MAILBOX_INTERFACE4 0x0203
+#define VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR_MASK GENMASK(15, 2)
+#define VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR_MASK, (u16)(x))
+
+#define VEND1_GLOBAL_MAILBOX_INTERFACE5 0x0204
+#define VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA_MASK GENMASK(15, 0)
+#define VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA_MASK, (u16)((x) >> 16))
+#define VEND1_GLOBAL_MAILBOX_INTERFACE6 0x0205
+#define VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA_MASK GENMASK(15, 0)
+#define VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA_MASK, (u16)(x))
+
/* The following registers all have similar layouts; first the registers... */
#define VEND1_GLOBAL_CFG_10M 0x0310
#define VEND1_GLOBAL_CFG_100M 0x031b
@@ -28,6 +53,11 @@
#define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2
/* Vendor specific 1, MDIO_MMD_VEND2 */
+#define VEND1_GLOBAL_CONTROL2 0xc001
+#define VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_RST BIT(15)
+#define VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD BIT(6)
+#define VEND1_GLOBAL_CONTROL2_UP_RUN_STALL BIT(0)
+
#define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421
#define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422
#define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423
@@ -83,3 +113,5 @@ int aqr_hwmon_probe(struct phy_device *phydev);
#else
static inline int aqr_hwmon_probe(struct phy_device *phydev) { return 0; }
#endif
+
+int aqr_firmware_load(struct phy_device *phydev);
diff --git a/drivers/net/phy/aquantia/aquantia_firmware.c b/drivers/net/phy/aquantia/aquantia_firmware.c
new file mode 100644
index 000000000000..93a0338a7d14
--- /dev/null
+++ b/drivers/net/phy/aquantia/aquantia_firmware.c
@@ -0,0 +1,367 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/bitfield.h>
+#include <linux/of.h>
+#include <linux/firmware.h>
+#include <linux/crc-ccitt.h>
+#include <linux/nvmem-consumer.h>
+
+#include <asm/unaligned.h>
+
+#include "aquantia.h"
+
+#define UP_RESET_SLEEP 100
+
+/* addresses of memory segments in the phy */
+#define DRAM_BASE_ADDR 0x3FFE0000
+#define IRAM_BASE_ADDR 0x40000000
+
+/* firmware image format constants */
+#define VERSION_STRING_SIZE 0x40
+#define VERSION_STRING_OFFSET 0x0200
+/* primary offset is written at an offset from the start of the fw blob */
+#define PRIMARY_OFFSET_OFFSET 0x8
+/* primary offset needs to be then added to a base offset */
+#define PRIMARY_OFFSET_SHIFT 12
+#define PRIMARY_OFFSET(x) ((x) << PRIMARY_OFFSET_SHIFT)
+#define HEADER_OFFSET 0x300
+
+struct aqr_fw_header {
+ u32 padding;
+ u8 iram_offset[3];
+ u8 iram_size[3];
+ u8 dram_offset[3];
+ u8 dram_size[3];
+} __packed;
+
+enum aqr_fw_src {
+ AQR_FW_SRC_NVMEM = 0,
+ AQR_FW_SRC_FS,
+};
+
+static const char * const aqr_fw_src_string[] = {
+ [AQR_FW_SRC_NVMEM] = "NVMEM",
+ [AQR_FW_SRC_FS] = "FS",
+};
+
+/* AQR firmware doesn't have fixed offsets for iram and dram section
+ * but instead provide an header with the offset to use on reading
+ * and parsing the firmware.
+ *
+ * AQR firmware can't be trusted and each offset is validated to be
+ * not negative and be in the size of the firmware itself.
+ */
+static inline bool aqr_fw_validate_get(size_t size, size_t offset, size_t get_size)
+{
+ return size + offset > 0 && offset + get_size <= size;
+}
+
+static int aqr_fw_get_be16(const u8 *data, size_t offset, size_t size, u16 *value)
+{
+ if (!aqr_fw_validate_get(size, offset, sizeof(u16)))
+ return -EINVAL;
+
+ *value = get_unaligned_be16(data + offset);
+
+ return 0;
+}
+
+static int aqr_fw_get_le16(const u8 *data, size_t offset, size_t size, u16 *value)
+{
+ if (!aqr_fw_validate_get(size, offset, sizeof(u16)))
+ return -EINVAL;
+
+ *value = get_unaligned_le16(data + offset);
+
+ return 0;
+}
+
+static int aqr_fw_get_le24(const u8 *data, size_t offset, size_t size, u32 *value)
+{
+ if (!aqr_fw_validate_get(size, offset, sizeof(u8) * 3))
+ return -EINVAL;
+
+ *value = get_unaligned_le24(data + offset);
+
+ return 0;
+}
+
+/* load data into the phy's memory */
+static int aqr_fw_load_memory(struct phy_device *phydev, u32 addr,
+ const u8 *data, size_t len)
+{
+ u16 crc = 0, up_crc;
+ size_t pos;
+
+ /* PHY expect addr in LE */
+ addr = cpu_to_le32(addr);
+
+ phy_write_mmd(phydev, MDIO_MMD_VEND1,
+ VEND1_GLOBAL_MAILBOX_INTERFACE1,
+ VEND1_GLOBAL_MAILBOX_INTERFACE1_CRC_RESET);
+ phy_write_mmd(phydev, MDIO_MMD_VEND1,
+ VEND1_GLOBAL_MAILBOX_INTERFACE3,
+ VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR(addr));
+ phy_write_mmd(phydev, MDIO_MMD_VEND1,
+ VEND1_GLOBAL_MAILBOX_INTERFACE4,
+ VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR(addr));
+
+ /* We assume and enforce the size to be word aligned.
+ * If a firmware that is not word aligned is found, please report upstream.
+ */
+ for (pos = 0; pos < len; pos += sizeof(u32)) {
+ u32 word = get_unaligned((const u32 *)(data + pos));
+
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE5,
+ VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA(word));
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE6,
+ VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA(word));
+
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE1,
+ VEND1_GLOBAL_MAILBOX_INTERFACE1_EXECUTE |
+ VEND1_GLOBAL_MAILBOX_INTERFACE1_WRITE);
+
+ /* calculate CRC as we load data to the mailbox.
+ * We convert word to big-endiang as PHY is BE and mailbox will
+ * return a BE CRC.
+ */
+ word = cpu_to_be32(word);
+ crc = crc_ccitt_false(crc, (u8 *)&word, sizeof(word));
+ }
+
+ up_crc = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE2);
+ if (crc != up_crc) {
+ phydev_err(phydev, "CRC mismatch: calculated 0x%04x PHY 0x%04x\n",
+ crc, up_crc);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int aqr_fw_boot(struct phy_device *phydev, const u8 *data, size_t size,
+ enum aqr_fw_src fw_src)
+{
+ u16 calculated_crc, read_crc, read_primary_offset;
+ u32 iram_offset = 0, iram_size = 0;
+ u32 dram_offset = 0, dram_size = 0;
+ char version[VERSION_STRING_SIZE];
+ u32 primary_offset = 0;
+ int ret;
+
+ /* extract saved CRC at the end of the fw
+ * CRC is saved in big-endian as PHY is BE
+ */
+ ret = aqr_fw_get_be16(data, size - sizeof(u16), size, &read_crc);
+ if (ret) {
+ phydev_err(phydev, "bad firmware CRC in firmware\n");
+ return ret;
+ }
+ calculated_crc = crc_ccitt_false(0, data, size - sizeof(u16));
+ if (read_crc != calculated_crc) {
+ phydev_err(phydev, "bad firmware CRC: file 0x%04x calculated 0x%04x\n",
+ read_crc, calculated_crc);
+ return -EINVAL;
+ }
+
+ /* Get the primary offset to extract DRAM and IRAM sections. */
+ ret = aqr_fw_get_le16(data, PRIMARY_OFFSET_OFFSET, size, &read_primary_offset);
+ if (ret) {
+ phydev_err(phydev, "bad primary offset in firmware\n");
+ return ret;
+ }
+ primary_offset = PRIMARY_OFFSET(read_primary_offset);
+
+ /* Find the DRAM and IRAM sections within the firmware file.
+ * Make sure the fw_header is correctly in the firmware.
+ */
+ if (!aqr_fw_validate_get(size, primary_offset + HEADER_OFFSET,
+ sizeof(struct aqr_fw_header))) {
+ phydev_err(phydev, "bad fw_header in firmware\n");
+ return -EINVAL;
+ }
+
+ /* offset are in LE and values needs to be converted to cpu endian */
+ ret = aqr_fw_get_le24(data, primary_offset + HEADER_OFFSET +
+ offsetof(struct aqr_fw_header, iram_offset),
+ size, &iram_offset);
+ if (ret) {
+ phydev_err(phydev, "bad iram offset in firmware\n");
+ return ret;
+ }
+ ret = aqr_fw_get_le24(data, primary_offset + HEADER_OFFSET +
+ offsetof(struct aqr_fw_header, iram_size),
+ size, &iram_size);
+ if (ret) {
+ phydev_err(phydev, "invalid iram size in firmware\n");
+ return ret;
+ }
+ ret = aqr_fw_get_le24(data, primary_offset + HEADER_OFFSET +
+ offsetof(struct aqr_fw_header, dram_offset),
+ size, &dram_offset);
+ if (ret) {
+ phydev_err(phydev, "bad dram offset in firmware\n");
+ return ret;
+ }
+ ret = aqr_fw_get_le24(data, primary_offset + HEADER_OFFSET +
+ offsetof(struct aqr_fw_header, dram_size),
+ size, &dram_size);
+ if (ret) {
+ phydev_err(phydev, "invalid dram size in firmware\n");
+ return ret;
+ }
+
+ /* Increment the offset with the primary offset.
+ * Validate iram/dram offset and size.
+ */
+ iram_offset += primary_offset;
+ if (iram_size % sizeof(u32)) {
+ phydev_err(phydev, "iram size if not aligned to word size. Please report this upstream!\n");
+ return -EINVAL;
+ }
+ if (!aqr_fw_validate_get(size, iram_offset, iram_size)) {
+ phydev_err(phydev, "invalid iram offset for iram size\n");
+ return -EINVAL;
+ }
+
+ dram_offset += primary_offset;
+ if (dram_size % sizeof(u32)) {
+ phydev_err(phydev, "dram size if not aligned to word size. Please report this upstream!\n");
+ return -EINVAL;
+ }
+ if (!aqr_fw_validate_get(size, dram_offset, dram_size)) {
+ phydev_err(phydev, "invalid iram offset for iram size\n");
+ return -EINVAL;
+ }
+
+ phydev_dbg(phydev, "primary %d IRAM offset=%d size=%d DRAM offset=%d size=%d\n",
+ primary_offset, iram_offset, iram_size, dram_offset, dram_size);
+
+ if (!aqr_fw_validate_get(size, dram_offset + VERSION_STRING_OFFSET,
+ VERSION_STRING_SIZE)) {
+ phydev_err(phydev, "invalid version in firmware\n");
+ return -EINVAL;
+ }
+ strscpy(version, (char *)data + dram_offset + VERSION_STRING_OFFSET,
+ VERSION_STRING_SIZE);
+ if (version[0] == '\0') {
+ phydev_err(phydev, "invalid version in firmware\n");
+ return -EINVAL;
+ }
+ phydev_info(phydev, "loading firmware version '%s' from '%s'\n", version,
+ aqr_fw_src_string[fw_src]);
+
+ /* stall the microcprocessor */
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_CONTROL2,
+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL | VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD);
+
+ phydev_dbg(phydev, "loading DRAM 0x%08x from offset=%d size=%d\n",
+ DRAM_BASE_ADDR, dram_offset, dram_size);
+ ret = aqr_fw_load_memory(phydev, DRAM_BASE_ADDR, data + dram_offset,
+ dram_size);
+ if (ret)
+ return ret;
+
+ phydev_dbg(phydev, "loading IRAM 0x%08x from offset=%d size=%d\n",
+ IRAM_BASE_ADDR, iram_offset, iram_size);
+ ret = aqr_fw_load_memory(phydev, IRAM_BASE_ADDR, data + iram_offset,
+ iram_size);
+ if (ret)
+ return ret;
+
+ /* make sure soft reset and low power mode are clear */
+ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_SC,
+ VEND1_GLOBAL_SC_SOFT_RESET | VEND1_GLOBAL_SC_LOW_POWER);
+
+ /* Release the microprocessor. UP_RESET must be held for 100 usec. */
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_CONTROL2,
+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL |
+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD |
+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_RST);
+ usleep_range(UP_RESET_SLEEP, UP_RESET_SLEEP * 2);
+
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_CONTROL2,
+ VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD);
+
+ return 0;
+}
+
+static int aqr_firmware_load_nvmem(struct phy_device *phydev)
+{
+ struct nvmem_cell *cell;
+ size_t size;
+ u8 *buf;
+ int ret;
+
+ cell = nvmem_cell_get(&phydev->mdio.dev, "firmware");
+ if (IS_ERR(cell))
+ return PTR_ERR(cell);
+
+ buf = nvmem_cell_read(cell, &size);
+ if (IS_ERR(buf)) {
+ ret = PTR_ERR(buf);
+ goto exit;
+ }
+
+ ret = aqr_fw_boot(phydev, buf, size, AQR_FW_SRC_NVMEM);
+ if (ret)
+ phydev_err(phydev, "firmware loading failed: %d\n", ret);
+
+exit:
+ nvmem_cell_put(cell);
+
+ return ret;
+}
+
+static int aqr_firmware_load_fs(struct phy_device *phydev)
+{
+ struct device *dev = &phydev->mdio.dev;
+ const struct firmware *fw;
+ const char *fw_name;
+ int ret;
+
+ ret = of_property_read_string(dev->of_node, "firmware-name",
+ &fw_name);
+ if (ret)
+ return ret;
+
+ ret = request_firmware(&fw, fw_name, dev);
+ if (ret) {
+ phydev_err(phydev, "failed to find FW file %s (%d)\n",
+ fw_name, ret);
+ goto exit;
+ }
+
+ ret = aqr_fw_boot(phydev, fw->data, fw->size, AQR_FW_SRC_FS);
+ if (ret)
+ phydev_err(phydev, "firmware loading failed: %d\n", ret);
+
+exit:
+ release_firmware(fw);
+
+ return ret;
+}
+
+int aqr_firmware_load(struct phy_device *phydev)
+{
+ int ret;
+
+ /* Check if the firmware is not already loaded by pooling
+ * the current version returned by the PHY. If 0 is returned,
+ * no firmware is loaded.
+ */
+ ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_FW_ID);
+ if (ret > 0)
+ goto exit;
+
+ ret = aqr_firmware_load_nvmem(phydev);
+ if (!ret)
+ goto exit;
+
+ ret = aqr_firmware_load_fs(phydev);
+ if (ret)
+ return ret;
+
+exit:
+ return 0;
+}
diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c
index 4498426e9a52..cc4a97741c4a 100644
--- a/drivers/net/phy/aquantia/aquantia_main.c
+++ b/drivers/net/phy/aquantia/aquantia_main.c
@@ -658,11 +658,17 @@ static int aqr107_resume(struct phy_device *phydev)
static int aqr107_probe(struct phy_device *phydev)
{
+ int ret;
+
phydev->priv = devm_kzalloc(&phydev->mdio.dev,
sizeof(struct aqr107_priv), GFP_KERNEL);
if (!phydev->priv)
return -ENOMEM;
+ ret = aqr_firmware_load(phydev);
+ if (ret)
+ return ret;
+
return aqr_hwmon_probe(phydev);
}
--
2.40.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [net-next RFC PATCH v3 4/4] dt-bindings: Document bindings for Marvell Aquantia PHY
2023-11-02 15:00 [net-next RFC PATCH v3 1/4] net: phy: aquantia: move to separate directory Christian Marangi
2023-11-02 15:00 ` [net-next RFC PATCH v3 2/4] net: phy: aquantia: move MMD_VEND define to header Christian Marangi
2023-11-02 15:00 ` [net-next RFC PATCH v3 3/4] net: phy: aquantia: add firmware load support Christian Marangi
@ 2023-11-02 15:00 ` Christian Marangi
2023-11-03 13:08 ` Conor Dooley
2023-11-02 15:03 ` [net-next RFC PATCH v3 1/4] net: phy: aquantia: move to separate directory Andrew Lunn
3 siblings, 1 reply; 12+ messages in thread
From: Christian Marangi @ 2023-11-02 15:00 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Andrew Lunn,
Heiner Kallweit, Russell King, Christian Marangi, Robert Marko,
Vladimir Oltean, netdev, devicetree, linux-kernel
Document bindings for Marvell Aquantia PHY.
The Marvell Aquantia PHY require a firmware to work correctly and there
at least 3 way to load this firmware.
Describe all the different way and document the binding "firmware-name"
to load the PHY firmware from userspace.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
Changes v3:
- Make DT description more OS agnostic
- Use custom select to fix dtbs checks
Changes v2:
- Add DT patch
.../bindings/net/marvell,aquantia.yaml | 126 ++++++++++++++++++
1 file changed, 126 insertions(+)
create mode 100644 Documentation/devicetree/bindings/net/marvell,aquantia.yaml
diff --git a/Documentation/devicetree/bindings/net/marvell,aquantia.yaml b/Documentation/devicetree/bindings/net/marvell,aquantia.yaml
new file mode 100644
index 000000000000..d43cf28a4d61
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/marvell,aquantia.yaml
@@ -0,0 +1,126 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/marvell,aquantia.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Marvell Aquantia Ethernet PHY
+
+maintainers:
+ - Christian Marangi <ansuelsmth@gmail.com>
+
+description: |
+ Marvell Aquantia Ethernet PHY require a firmware to be loaded to actually
+ work.
+
+ This can be done and is implemented by OEM in 3 different way:
+ - Attached SPI directly to the PHY with the firmware. The PHY will
+ self load the firmware in the presence of this configuration.
+ - Dedicated partition on system NAND with firmware in it. NVMEM
+ subsystem will be used and the declared NVMEM cell will load
+ the firmware to the PHY using the PHY mailbox interface.
+ - Manually provided firmware loaded from a file in the filesystem.
+
+ If declared, NVMEM will always take priority over filesystem provided
+ firmware.
+
+allOf:
+ - $ref: ethernet-phy.yaml#
+
+select:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - ethernet-phy-id03a1.b445
+ - ethernet-phy-id03a1.b460
+ - ethernet-phy-id03a1.b4a2
+ - ethernet-phy-id03a1.b4d0
+ - ethernet-phy-id03a1.b4e0
+ - ethernet-phy-id03a1.b5c2
+ - ethernet-phy-id03a1.b4b0
+ - ethernet-phy-id03a1.b662
+ - ethernet-phy-id03a1.b712
+ - ethernet-phy-id31c3.1c12
+ required:
+ - compatible
+
+properties:
+ reg:
+ maxItems: 1
+
+ firmware-name:
+ description: specify the name of PHY firmware to load
+
+ nvmem-cells:
+ description: phandle to the firmware nvmem cell
+ maxItems: 1
+
+ nvmem-cell-names:
+ const: firmware
+
+required:
+ - compatible
+ - reg
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethernet-phy@0 {
+ /* Only needed to make DT lint tools work. Do not copy/paste
+ * into real DTS files.
+ */
+ compatible = "ethernet-phy-id31c3.1c12",
+ "ethernet-phy-ieee802.3-c45";
+
+ reg = <0>;
+ firmware-name = "AQR-G4_v5.4.C-AQR_CIG_WF-1945_0x8_ID44776_VER1630.cld";
+ };
+
+ ethernet-phy@1 {
+ /* Only needed to make DT lint tools work. Do not copy/paste
+ * into real DTS files.
+ */
+ compatible = "ethernet-phy-id31c3.1c12",
+ "ethernet-phy-ieee802.3-c45";
+
+ reg = <0>;
+ nvmem-cells = <&aqr_fw>;
+ nvmem-cell-names = "firmware";
+ };
+ };
+
+ flash {
+ compatible = "jedec,spi-nor";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ /* ... */
+
+ partition@650000 {
+ compatible = "nvmem-cells";
+ label = "0:ethphyfw";
+ reg = <0x650000 0x80000>;
+ read-only;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aqr_fw: aqr_fw@0 {
+ reg = <0x0 0x5f42a>;
+ };
+ };
+
+ /* ... */
+
+ };
+ };
--
2.40.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [net-next RFC PATCH v3 1/4] net: phy: aquantia: move to separate directory
2023-11-02 15:00 [net-next RFC PATCH v3 1/4] net: phy: aquantia: move to separate directory Christian Marangi
` (2 preceding siblings ...)
2023-11-02 15:00 ` [net-next RFC PATCH v3 4/4] dt-bindings: Document bindings for Marvell Aquantia PHY Christian Marangi
@ 2023-11-02 15:03 ` Andrew Lunn
2023-11-02 15:07 ` Christian Marangi
3 siblings, 1 reply; 12+ messages in thread
From: Andrew Lunn @ 2023-11-02 15:03 UTC (permalink / raw)
To: Christian Marangi
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiner Kallweit,
Russell King, Robert Marko, Vladimir Oltean, netdev, devicetree,
linux-kernel
> diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
> index 421d2b62918f..4b2451dd6c45 100644
> --- a/drivers/net/phy/Kconfig
> +++ b/drivers/net/phy/Kconfig
> @@ -68,6 +68,8 @@ config SFP
>
> comment "MII PHY device drivers"
>
> +source "drivers/net/phy/aquantia/Kconfig"
> +
> config AMD_PHY
> tristate "AMD and Altima PHYs"
> help
> @@ -96,11 +98,6 @@ config ADIN1100_PHY
> Currently supports the:
> - ADIN1100 - Robust,Industrial, Low Power 10BASE-T1L Ethernet PHY
>
> -config AQUANTIA_PHY
> - tristate "Aquantia PHYs"
> - help
> - Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405
> -
Does this move the PHY in the make menuconfig menu? We try to keep it
sorted based on the tristate string.
Andrew
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [net-next RFC PATCH v3 1/4] net: phy: aquantia: move to separate directory
2023-11-02 15:03 ` [net-next RFC PATCH v3 1/4] net: phy: aquantia: move to separate directory Andrew Lunn
@ 2023-11-02 15:07 ` Christian Marangi
2023-11-02 15:49 ` Andrew Lunn
0 siblings, 1 reply; 12+ messages in thread
From: Christian Marangi @ 2023-11-02 15:07 UTC (permalink / raw)
To: Andrew Lunn
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiner Kallweit,
Russell King, Robert Marko, Vladimir Oltean, netdev, devicetree,
linux-kernel
On Thu, Nov 02, 2023 at 04:03:33PM +0100, Andrew Lunn wrote:
> > diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
> > index 421d2b62918f..4b2451dd6c45 100644
> > --- a/drivers/net/phy/Kconfig
> > +++ b/drivers/net/phy/Kconfig
> > @@ -68,6 +68,8 @@ config SFP
> >
> > comment "MII PHY device drivers"
> >
> > +source "drivers/net/phy/aquantia/Kconfig"
> > +
> > config AMD_PHY
> > tristate "AMD and Altima PHYs"
> > help
> > @@ -96,11 +98,6 @@ config ADIN1100_PHY
> > Currently supports the:
> > - ADIN1100 - Robust,Industrial, Low Power 10BASE-T1L Ethernet PHY
> >
> > -config AQUANTIA_PHY
> > - tristate "Aquantia PHYs"
> > - help
> > - Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405
> > -
>
> Does this move the PHY in the make menuconfig menu? We try to keep it
> sorted based on the tristate string.
>
Oh wasn't aware... Yes it does move it to the top of the list... I can
just move the source entry where AQUANTIA_PHY was... Or if we really
want, not create a dedicated Kconfig for it and keep everything in PHY.
--
Ansuel
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [net-next RFC PATCH v3 1/4] net: phy: aquantia: move to separate directory
2023-11-02 15:07 ` Christian Marangi
@ 2023-11-02 15:49 ` Andrew Lunn
0 siblings, 0 replies; 12+ messages in thread
From: Andrew Lunn @ 2023-11-02 15:49 UTC (permalink / raw)
To: Christian Marangi
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiner Kallweit,
Russell King, Robert Marko, Vladimir Oltean, netdev, devicetree,
linux-kernel
On Thu, Nov 02, 2023 at 04:07:41PM +0100, Christian Marangi wrote:
> On Thu, Nov 02, 2023 at 04:03:33PM +0100, Andrew Lunn wrote:
> > > diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
> > > index 421d2b62918f..4b2451dd6c45 100644
> > > --- a/drivers/net/phy/Kconfig
> > > +++ b/drivers/net/phy/Kconfig
> > > @@ -68,6 +68,8 @@ config SFP
> > >
> > > comment "MII PHY device drivers"
> > >
> > > +source "drivers/net/phy/aquantia/Kconfig"
> > > +
> > > config AMD_PHY
> > > tristate "AMD and Altima PHYs"
> > > help
> > > @@ -96,11 +98,6 @@ config ADIN1100_PHY
> > > Currently supports the:
> > > - ADIN1100 - Robust,Industrial, Low Power 10BASE-T1L Ethernet PHY
> > >
> > > -config AQUANTIA_PHY
> > > - tristate "Aquantia PHYs"
> > > - help
> > > - Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405
> > > -
> >
> > Does this move the PHY in the make menuconfig menu? We try to keep it
> > sorted based on the tristate string.
> >
>
> Oh wasn't aware... Yes it does move it to the top of the list... I can
> just move the source entry where AQUANTIA_PHY was...
Yes, that would be best.
Thanks
Andrew
---
pw-bot: cr
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [net-next RFC PATCH v3 2/4] net: phy: aquantia: move MMD_VEND define to header
2023-11-02 15:00 ` [net-next RFC PATCH v3 2/4] net: phy: aquantia: move MMD_VEND define to header Christian Marangi
@ 2023-11-02 17:19 ` Andrew Lunn
0 siblings, 0 replies; 12+ messages in thread
From: Andrew Lunn @ 2023-11-02 17:19 UTC (permalink / raw)
To: Christian Marangi
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiner Kallweit,
Russell King, Robert Marko, Vladimir Oltean, netdev, devicetree,
linux-kernel
On Thu, Nov 02, 2023 at 04:00:30PM +0100, Christian Marangi wrote:
> Move MMD_VEND define to header to clean things up and in preparation for
> firmware loading support that require some define placed in
> aquantia_main.
>
> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [net-next RFC PATCH v3 3/4] net: phy: aquantia: add firmware load support
2023-11-02 15:00 ` [net-next RFC PATCH v3 3/4] net: phy: aquantia: add firmware load support Christian Marangi
@ 2023-11-02 17:37 ` Andrew Lunn
2023-11-02 17:41 ` Christian Marangi
0 siblings, 1 reply; 12+ messages in thread
From: Andrew Lunn @ 2023-11-02 17:37 UTC (permalink / raw)
To: Christian Marangi
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiner Kallweit,
Russell King, Robert Marko, Vladimir Oltean, netdev, devicetree,
linux-kernel
> +/* AQR firmware doesn't have fixed offsets for iram and dram section
> + * but instead provide an header with the offset to use on reading
> + * and parsing the firmware.
> + *
> + * AQR firmware can't be trusted and each offset is validated to be
> + * not negative and be in the size of the firmware itself.
> + */
> +static inline bool aqr_fw_validate_get(size_t size, size_t offset, size_t get_size)
> +{
> + return size + offset > 0 && offset + get_size <= size;
> +}
Please don't user inline in .c files. The compiler is better at
deciding than we are.
Also, i wounder about size + offset > 0. size_t is unsigned. So they
cannot be negative. So does this test make sense?
> +static int aqr_fw_boot(struct phy_device *phydev, const u8 *data, size_t size,
> + enum aqr_fw_src fw_src)
> +{
> + u16 calculated_crc, read_crc, read_primary_offset;
> + u32 iram_offset = 0, iram_size = 0;
> + u32 dram_offset = 0, dram_size = 0;
> + char version[VERSION_STRING_SIZE];
> + u32 primary_offset = 0;
> + int ret;
> +
> + /* extract saved CRC at the end of the fw
> + * CRC is saved in big-endian as PHY is BE
> + */
> + ret = aqr_fw_get_be16(data, size - sizeof(u16), size, &read_crc);
> + if (ret) {
> + phydev_err(phydev, "bad firmware CRC in firmware\n");
> + return ret;
> + }
So if size < sizeof(u16), we get a very big positive number. The > 0
test does nothing for you here, but the other half of the test does
trap the issue.
So i think you can remove the > 0 test.
Andrew
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [net-next RFC PATCH v3 3/4] net: phy: aquantia: add firmware load support
2023-11-02 17:37 ` Andrew Lunn
@ 2023-11-02 17:41 ` Christian Marangi
0 siblings, 0 replies; 12+ messages in thread
From: Christian Marangi @ 2023-11-02 17:41 UTC (permalink / raw)
To: Andrew Lunn
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiner Kallweit,
Russell King, Robert Marko, Vladimir Oltean, netdev, devicetree,
linux-kernel
On Thu, Nov 02, 2023 at 06:37:40PM +0100, Andrew Lunn wrote:
> > +/* AQR firmware doesn't have fixed offsets for iram and dram section
> > + * but instead provide an header with the offset to use on reading
> > + * and parsing the firmware.
> > + *
> > + * AQR firmware can't be trusted and each offset is validated to be
> > + * not negative and be in the size of the firmware itself.
> > + */
> > +static inline bool aqr_fw_validate_get(size_t size, size_t offset, size_t get_size)
> > +{
> > + return size + offset > 0 && offset + get_size <= size;
> > +}
>
> Please don't user inline in .c files. The compiler is better at
> deciding than we are.
>
OK.
> Also, i wounder about size + offset > 0. size_t is unsigned. So they
> cannot be negative. So does this test make sense?
>
The idea was to check case where it's subtracted too much. (example
where we check the CRC at the end of the fw) but since it's unsigned i
guess it will always be zero. I will drop. (or should i use ssize_t?)
> > +static int aqr_fw_boot(struct phy_device *phydev, const u8 *data, size_t size,
> > + enum aqr_fw_src fw_src)
> > +{
> > + u16 calculated_crc, read_crc, read_primary_offset;
> > + u32 iram_offset = 0, iram_size = 0;
> > + u32 dram_offset = 0, dram_size = 0;
> > + char version[VERSION_STRING_SIZE];
> > + u32 primary_offset = 0;
> > + int ret;
> > +
> > + /* extract saved CRC at the end of the fw
> > + * CRC is saved in big-endian as PHY is BE
> > + */
> > + ret = aqr_fw_get_be16(data, size - sizeof(u16), size, &read_crc);
> > + if (ret) {
> > + phydev_err(phydev, "bad firmware CRC in firmware\n");
> > + return ret;
> > + }
>
> So if size < sizeof(u16), we get a very big positive number. The > 0
> test does nothing for you here, but the other half of the test does
> trap the issue.
>
> So i think you can remove the > 0 test.
>
Yes that single check was done because of this, but didn't notice size_t
is unsigned and it won't ever fall in negative cases.
--
Ansuel
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [net-next RFC PATCH v3 4/4] dt-bindings: Document bindings for Marvell Aquantia PHY
2023-11-02 15:00 ` [net-next RFC PATCH v3 4/4] dt-bindings: Document bindings for Marvell Aquantia PHY Christian Marangi
@ 2023-11-03 13:08 ` Conor Dooley
2023-11-06 16:47 ` Christian Marangi
0 siblings, 1 reply; 12+ messages in thread
From: Conor Dooley @ 2023-11-03 13:08 UTC (permalink / raw)
To: Christian Marangi
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Andrew Lunn,
Heiner Kallweit, Russell King, Robert Marko, Vladimir Oltean,
netdev, devicetree, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 2726 bytes --]
Yo,
On Thu, Nov 02, 2023 at 04:00:32PM +0100, Christian Marangi wrote:
> Document bindings for Marvell Aquantia PHY.
>
> The Marvell Aquantia PHY require a firmware to work correctly and there
> at least 3 way to load this firmware.
>
> Describe all the different way and document the binding "firmware-name"
> to load the PHY firmware from userspace.
>
> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> ---
> Changes v3:
> - Make DT description more OS agnostic
> - Use custom select to fix dtbs checks
> Changes v2:
> - Add DT patch
>
> .../bindings/net/marvell,aquantia.yaml | 126 ++++++++++++++++++
> 1 file changed, 126 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/net/marvell,aquantia.yaml
>
> diff --git a/Documentation/devicetree/bindings/net/marvell,aquantia.yaml b/Documentation/devicetree/bindings/net/marvell,aquantia.yaml
> new file mode 100644
> index 000000000000..d43cf28a4d61
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/marvell,aquantia.yaml
> @@ -0,0 +1,126 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/net/marvell,aquantia.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Marvell Aquantia Ethernet PHY
> +
> +maintainers:
> + - Christian Marangi <ansuelsmth@gmail.com>
> +
> +description: |
> + Marvell Aquantia Ethernet PHY require a firmware to be loaded to actually
> + work.
> +
> + This can be done and is implemented by OEM in 3 different way:
> + - Attached SPI directly to the PHY with the firmware. The PHY will
You a word here? Should that not be "SPI flash"?
> + self load the firmware in the presence of this configuration.
> + - Dedicated partition on system NAND with firmware in it. NVMEM
> + subsystem will be used and the declared NVMEM cell will load
> + the firmware to the PHY using the PHY mailbox interface.
> + - Manually provided firmware loaded from a file in the filesystem.
> +
> + If declared, NVMEM will always take priority over filesystem provided
> + firmware.
This section here reads entirely like "software policy". The first
bullet in your list is fine - as that is what the PHY will do itself.
The second and third bullets here seem like two different ways that
someone could integrate their system, and I am not objecting to either
of those ways of doing things.
The priority system that you mention however I don't think is suitable
for a description of the hardware - the PHY itself doesn't require that
an external-to-it flash device take priority over something in the
filesystem, right?
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [net-next RFC PATCH v3 4/4] dt-bindings: Document bindings for Marvell Aquantia PHY
2023-11-03 13:08 ` Conor Dooley
@ 2023-11-06 16:47 ` Christian Marangi
0 siblings, 0 replies; 12+ messages in thread
From: Christian Marangi @ 2023-11-06 16:47 UTC (permalink / raw)
To: Conor Dooley
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Andrew Lunn,
Heiner Kallweit, Russell King, Robert Marko, Vladimir Oltean,
netdev, devicetree, linux-kernel
On Fri, Nov 03, 2023 at 01:08:45PM +0000, Conor Dooley wrote:
> Yo,
>
> On Thu, Nov 02, 2023 at 04:00:32PM +0100, Christian Marangi wrote:
> > Document bindings for Marvell Aquantia PHY.
> >
> > The Marvell Aquantia PHY require a firmware to work correctly and there
> > at least 3 way to load this firmware.
> >
> > Describe all the different way and document the binding "firmware-name"
> > to load the PHY firmware from userspace.
> >
> > Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> > ---
> > Changes v3:
> > - Make DT description more OS agnostic
> > - Use custom select to fix dtbs checks
> > Changes v2:
> > - Add DT patch
> >
> > .../bindings/net/marvell,aquantia.yaml | 126 ++++++++++++++++++
> > 1 file changed, 126 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/net/marvell,aquantia.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/net/marvell,aquantia.yaml b/Documentation/devicetree/bindings/net/marvell,aquantia.yaml
> > new file mode 100644
> > index 000000000000..d43cf28a4d61
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/net/marvell,aquantia.yaml
> > @@ -0,0 +1,126 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/net/marvell,aquantia.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Marvell Aquantia Ethernet PHY
> > +
> > +maintainers:
> > + - Christian Marangi <ansuelsmth@gmail.com>
> > +
> > +description: |
> > + Marvell Aquantia Ethernet PHY require a firmware to be loaded to actually
> > + work.
> > +
> > + This can be done and is implemented by OEM in 3 different way:
> > + - Attached SPI directly to the PHY with the firmware. The PHY will
>
> You a word here? Should that not be "SPI flash"?
>
Added!
> > + self load the firmware in the presence of this configuration.
>
> > + - Dedicated partition on system NAND with firmware in it. NVMEM
> > + subsystem will be used and the declared NVMEM cell will load
> > + the firmware to the PHY using the PHY mailbox interface.
> > + - Manually provided firmware loaded from a file in the filesystem.
> > +
> > + If declared, NVMEM will always take priority over filesystem provided
> > + firmware.
>
> This section here reads entirely like "software policy". The first
> bullet in your list is fine - as that is what the PHY will do itself.
> The second and third bullets here seem like two different ways that
> someone could integrate their system, and I am not objecting to either
> of those ways of doing things.
> The priority system that you mention however I don't think is suitable
> for a description of the hardware - the PHY itself doesn't require that
> an external-to-it flash device take priority over something in the
> filesystem, right?
>
Yes the priority system is just something in software and nothing about
hardware. I dropped in v5. Thanks for the review!
--
Ansuel
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2023-11-06 16:47 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-02 15:00 [net-next RFC PATCH v3 1/4] net: phy: aquantia: move to separate directory Christian Marangi
2023-11-02 15:00 ` [net-next RFC PATCH v3 2/4] net: phy: aquantia: move MMD_VEND define to header Christian Marangi
2023-11-02 17:19 ` Andrew Lunn
2023-11-02 15:00 ` [net-next RFC PATCH v3 3/4] net: phy: aquantia: add firmware load support Christian Marangi
2023-11-02 17:37 ` Andrew Lunn
2023-11-02 17:41 ` Christian Marangi
2023-11-02 15:00 ` [net-next RFC PATCH v3 4/4] dt-bindings: Document bindings for Marvell Aquantia PHY Christian Marangi
2023-11-03 13:08 ` Conor Dooley
2023-11-06 16:47 ` Christian Marangi
2023-11-02 15:03 ` [net-next RFC PATCH v3 1/4] net: phy: aquantia: move to separate directory Andrew Lunn
2023-11-02 15:07 ` Christian Marangi
2023-11-02 15:49 ` Andrew Lunn
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.