Skip to content

Commit e93984e

Browse files
robimarkodavem330
authored andcommitted
net: phy: aquantia: add firmware load support
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> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent e1fbfa4 commit e93984e

File tree

5 files changed

+410
-1
lines changed

5 files changed

+410
-1
lines changed

drivers/net/phy/aquantia/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# SPDX-License-Identifier: GPL-2.0-only
22
config AQUANTIA_PHY
33
tristate "Aquantia PHYs"
4+
select CRC_CCITT
45
help
56
Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405

drivers/net/phy/aquantia/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# SPDX-License-Identifier: GPL-2.0
2-
aquantia-objs += aquantia_main.o
2+
aquantia-objs += aquantia_main.o aquantia_firmware.o
33
ifdef CONFIG_HWMON
44
aquantia-objs += aquantia_hwmon.o
55
endif

drivers/net/phy/aquantia/aquantia.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,35 @@
1010
#include <linux/phy.h>
1111

1212
/* Vendor specific 1, MDIO_MMD_VEND1 */
13+
#define VEND1_GLOBAL_SC 0x0
14+
#define VEND1_GLOBAL_SC_SOFT_RESET BIT(15)
15+
#define VEND1_GLOBAL_SC_LOW_POWER BIT(11)
16+
1317
#define VEND1_GLOBAL_FW_ID 0x0020
1418
#define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8)
1519
#define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0)
1620

21+
#define VEND1_GLOBAL_MAILBOX_INTERFACE1 0x0200
22+
#define VEND1_GLOBAL_MAILBOX_INTERFACE1_EXECUTE BIT(15)
23+
#define VEND1_GLOBAL_MAILBOX_INTERFACE1_WRITE BIT(14)
24+
#define VEND1_GLOBAL_MAILBOX_INTERFACE1_CRC_RESET BIT(12)
25+
#define VEND1_GLOBAL_MAILBOX_INTERFACE1_BUSY BIT(8)
26+
27+
#define VEND1_GLOBAL_MAILBOX_INTERFACE2 0x0201
28+
#define VEND1_GLOBAL_MAILBOX_INTERFACE3 0x0202
29+
#define VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR_MASK GENMASK(15, 0)
30+
#define VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR_MASK, (u16)((x) >> 16))
31+
#define VEND1_GLOBAL_MAILBOX_INTERFACE4 0x0203
32+
#define VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR_MASK GENMASK(15, 2)
33+
#define VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR_MASK, (u16)(x))
34+
35+
#define VEND1_GLOBAL_MAILBOX_INTERFACE5 0x0204
36+
#define VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA_MASK GENMASK(15, 0)
37+
#define VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA_MASK, (u16)((x) >> 16))
38+
#define VEND1_GLOBAL_MAILBOX_INTERFACE6 0x0205
39+
#define VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA_MASK GENMASK(15, 0)
40+
#define VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA_MASK, (u16)(x))
41+
1742
/* The following registers all have similar layouts; first the registers... */
1843
#define VEND1_GLOBAL_CFG_10M 0x0310
1944
#define VEND1_GLOBAL_CFG_100M 0x031b
@@ -28,6 +53,11 @@
2853
#define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2
2954

3055
/* Vendor specific 1, MDIO_MMD_VEND2 */
56+
#define VEND1_GLOBAL_CONTROL2 0xc001
57+
#define VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_RST BIT(15)
58+
#define VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD BIT(6)
59+
#define VEND1_GLOBAL_CONTROL2_UP_RUN_STALL BIT(0)
60+
3161
#define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421
3262
#define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422
3363
#define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423
@@ -83,3 +113,5 @@ int aqr_hwmon_probe(struct phy_device *phydev);
83113
#else
84114
static inline int aqr_hwmon_probe(struct phy_device *phydev) { return 0; }
85115
#endif
116+
117+
int aqr_firmware_load(struct phy_device *phydev);

0 commit comments

Comments
 (0)