2
0

702-03-v6.7-net-phy-aquantia-add-firmware-load-support.patch 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. From e93984ebc1c82bd34f7a1b3391efaceee0a8ae96 Mon Sep 17 00:00:00 2001
  2. From: Robert Marko <[email protected]>
  3. Date: Tue, 14 Nov 2023 15:08:43 +0100
  4. Subject: [PATCH 3/3] net: phy: aquantia: add firmware load support
  5. Aquantia PHY-s require firmware to be loaded before they start operating.
  6. It can be automatically loaded in case when there is a SPI-NOR connected
  7. to Aquantia PHY-s or can be loaded from the host via MDIO.
  8. This patch adds support for loading the firmware via MDIO as in most cases
  9. there is no SPI-NOR being used to save on cost.
  10. Firmware loading code itself is ported from mainline U-boot with cleanups.
  11. The firmware has mixed values both in big and little endian.
  12. PHY core itself is big-endian but it expects values to be in little-endian.
  13. The firmware is little-endian but CRC-16 value for it is stored at the end
  14. of firmware in big-endian.
  15. It seems the PHY does the conversion internally from firmware that is
  16. little-endian to the PHY that is big-endian on using the mailbox
  17. but mailbox returns a big-endian CRC-16 to verify the written data
  18. integrity.
  19. Co-developed-by: Christian Marangi <[email protected]>
  20. Signed-off-by: Robert Marko <[email protected]>
  21. Signed-off-by: Christian Marangi <[email protected]>
  22. Reviewed-by: Andrew Lunn <[email protected]>
  23. Signed-off-by: David S. Miller <[email protected]>
  24. ---
  25. drivers/net/phy/aquantia/Kconfig | 1 +
  26. drivers/net/phy/aquantia/Makefile | 2 +-
  27. drivers/net/phy/aquantia/aquantia.h | 32 ++
  28. drivers/net/phy/aquantia/aquantia_firmware.c | 370 +++++++++++++++++++
  29. drivers/net/phy/aquantia/aquantia_main.c | 6 +
  30. 5 files changed, 410 insertions(+), 1 deletion(-)
  31. create mode 100644 drivers/net/phy/aquantia/aquantia_firmware.c
  32. --- a/drivers/net/phy/aquantia/Kconfig
  33. +++ b/drivers/net/phy/aquantia/Kconfig
  34. @@ -1,5 +1,6 @@
  35. # SPDX-License-Identifier: GPL-2.0-only
  36. config AQUANTIA_PHY
  37. tristate "Aquantia PHYs"
  38. + select CRC_CCITT
  39. help
  40. Currently supports the Aquantia AQ1202, AQ2104, AQR105, AQR405
  41. --- a/drivers/net/phy/aquantia/Makefile
  42. +++ b/drivers/net/phy/aquantia/Makefile
  43. @@ -1,5 +1,5 @@
  44. # SPDX-License-Identifier: GPL-2.0
  45. -aquantia-objs += aquantia_main.o
  46. +aquantia-objs += aquantia_main.o aquantia_firmware.o
  47. ifdef CONFIG_HWMON
  48. aquantia-objs += aquantia_hwmon.o
  49. endif
  50. --- a/drivers/net/phy/aquantia/aquantia.h
  51. +++ b/drivers/net/phy/aquantia/aquantia.h
  52. @@ -10,10 +10,35 @@
  53. #include <linux/phy.h>
  54. /* Vendor specific 1, MDIO_MMD_VEND1 */
  55. +#define VEND1_GLOBAL_SC 0x0
  56. +#define VEND1_GLOBAL_SC_SOFT_RESET BIT(15)
  57. +#define VEND1_GLOBAL_SC_LOW_POWER BIT(11)
  58. +
  59. #define VEND1_GLOBAL_FW_ID 0x0020
  60. #define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8)
  61. #define VEND1_GLOBAL_FW_ID_MINOR GENMASK(7, 0)
  62. +#define VEND1_GLOBAL_MAILBOX_INTERFACE1 0x0200
  63. +#define VEND1_GLOBAL_MAILBOX_INTERFACE1_EXECUTE BIT(15)
  64. +#define VEND1_GLOBAL_MAILBOX_INTERFACE1_WRITE BIT(14)
  65. +#define VEND1_GLOBAL_MAILBOX_INTERFACE1_CRC_RESET BIT(12)
  66. +#define VEND1_GLOBAL_MAILBOX_INTERFACE1_BUSY BIT(8)
  67. +
  68. +#define VEND1_GLOBAL_MAILBOX_INTERFACE2 0x0201
  69. +#define VEND1_GLOBAL_MAILBOX_INTERFACE3 0x0202
  70. +#define VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR_MASK GENMASK(15, 0)
  71. +#define VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR_MASK, (u16)((x) >> 16))
  72. +#define VEND1_GLOBAL_MAILBOX_INTERFACE4 0x0203
  73. +#define VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR_MASK GENMASK(15, 2)
  74. +#define VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR_MASK, (u16)(x))
  75. +
  76. +#define VEND1_GLOBAL_MAILBOX_INTERFACE5 0x0204
  77. +#define VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA_MASK GENMASK(15, 0)
  78. +#define VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA_MASK, (u16)((x) >> 16))
  79. +#define VEND1_GLOBAL_MAILBOX_INTERFACE6 0x0205
  80. +#define VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA_MASK GENMASK(15, 0)
  81. +#define VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA(x) FIELD_PREP(VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA_MASK, (u16)(x))
  82. +
  83. /* The following registers all have similar layouts; first the registers... */
  84. #define VEND1_GLOBAL_CFG_10M 0x0310
  85. #define VEND1_GLOBAL_CFG_100M 0x031b
  86. @@ -28,6 +53,11 @@
  87. #define VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE 2
  88. /* Vendor specific 1, MDIO_MMD_VEND2 */
  89. +#define VEND1_GLOBAL_CONTROL2 0xc001
  90. +#define VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_RST BIT(15)
  91. +#define VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD BIT(6)
  92. +#define VEND1_GLOBAL_CONTROL2_UP_RUN_STALL BIT(0)
  93. +
  94. #define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL 0xc421
  95. #define VEND1_THERMAL_PROV_LOW_TEMP_FAIL 0xc422
  96. #define VEND1_THERMAL_PROV_HIGH_TEMP_WARN 0xc423
  97. @@ -83,3 +113,5 @@ int aqr_hwmon_probe(struct phy_device *p
  98. #else
  99. static inline int aqr_hwmon_probe(struct phy_device *phydev) { return 0; }
  100. #endif
  101. +
  102. +int aqr_firmware_load(struct phy_device *phydev);
  103. --- /dev/null
  104. +++ b/drivers/net/phy/aquantia/aquantia_firmware.c
  105. @@ -0,0 +1,370 @@
  106. +// SPDX-License-Identifier: GPL-2.0
  107. +
  108. +#include <linux/bitfield.h>
  109. +#include <linux/of.h>
  110. +#include <linux/firmware.h>
  111. +#include <linux/crc-ccitt.h>
  112. +#include <linux/nvmem-consumer.h>
  113. +
  114. +#include <asm/unaligned.h>
  115. +
  116. +#include "aquantia.h"
  117. +
  118. +#define UP_RESET_SLEEP 100
  119. +
  120. +/* addresses of memory segments in the phy */
  121. +#define DRAM_BASE_ADDR 0x3FFE0000
  122. +#define IRAM_BASE_ADDR 0x40000000
  123. +
  124. +/* firmware image format constants */
  125. +#define VERSION_STRING_SIZE 0x40
  126. +#define VERSION_STRING_OFFSET 0x0200
  127. +/* primary offset is written at an offset from the start of the fw blob */
  128. +#define PRIMARY_OFFSET_OFFSET 0x8
  129. +/* primary offset needs to be then added to a base offset */
  130. +#define PRIMARY_OFFSET_SHIFT 12
  131. +#define PRIMARY_OFFSET(x) ((x) << PRIMARY_OFFSET_SHIFT)
  132. +#define HEADER_OFFSET 0x300
  133. +
  134. +struct aqr_fw_header {
  135. + u32 padding;
  136. + u8 iram_offset[3];
  137. + u8 iram_size[3];
  138. + u8 dram_offset[3];
  139. + u8 dram_size[3];
  140. +} __packed;
  141. +
  142. +enum aqr_fw_src {
  143. + AQR_FW_SRC_NVMEM = 0,
  144. + AQR_FW_SRC_FS,
  145. +};
  146. +
  147. +static const char * const aqr_fw_src_string[] = {
  148. + [AQR_FW_SRC_NVMEM] = "NVMEM",
  149. + [AQR_FW_SRC_FS] = "FS",
  150. +};
  151. +
  152. +/* AQR firmware doesn't have fixed offsets for iram and dram section
  153. + * but instead provide an header with the offset to use on reading
  154. + * and parsing the firmware.
  155. + *
  156. + * AQR firmware can't be trusted and each offset is validated to be
  157. + * not negative and be in the size of the firmware itself.
  158. + */
  159. +static bool aqr_fw_validate_get(size_t size, size_t offset, size_t get_size)
  160. +{
  161. + return offset + get_size <= size;
  162. +}
  163. +
  164. +static int aqr_fw_get_be16(const u8 *data, size_t offset, size_t size, u16 *value)
  165. +{
  166. + if (!aqr_fw_validate_get(size, offset, sizeof(u16)))
  167. + return -EINVAL;
  168. +
  169. + *value = get_unaligned_be16(data + offset);
  170. +
  171. + return 0;
  172. +}
  173. +
  174. +static int aqr_fw_get_le16(const u8 *data, size_t offset, size_t size, u16 *value)
  175. +{
  176. + if (!aqr_fw_validate_get(size, offset, sizeof(u16)))
  177. + return -EINVAL;
  178. +
  179. + *value = get_unaligned_le16(data + offset);
  180. +
  181. + return 0;
  182. +}
  183. +
  184. +static int aqr_fw_get_le24(const u8 *data, size_t offset, size_t size, u32 *value)
  185. +{
  186. + if (!aqr_fw_validate_get(size, offset, sizeof(u8) * 3))
  187. + return -EINVAL;
  188. +
  189. + *value = get_unaligned_le24(data + offset);
  190. +
  191. + return 0;
  192. +}
  193. +
  194. +/* load data into the phy's memory */
  195. +static int aqr_fw_load_memory(struct phy_device *phydev, u32 addr,
  196. + const u8 *data, size_t len)
  197. +{
  198. + u16 crc = 0, up_crc;
  199. + size_t pos;
  200. +
  201. + /* PHY expect addr in LE */
  202. + addr = (__force u32)cpu_to_le32(addr);
  203. +
  204. + phy_write_mmd(phydev, MDIO_MMD_VEND1,
  205. + VEND1_GLOBAL_MAILBOX_INTERFACE1,
  206. + VEND1_GLOBAL_MAILBOX_INTERFACE1_CRC_RESET);
  207. + phy_write_mmd(phydev, MDIO_MMD_VEND1,
  208. + VEND1_GLOBAL_MAILBOX_INTERFACE3,
  209. + VEND1_GLOBAL_MAILBOX_INTERFACE3_MSW_ADDR(addr));
  210. + phy_write_mmd(phydev, MDIO_MMD_VEND1,
  211. + VEND1_GLOBAL_MAILBOX_INTERFACE4,
  212. + VEND1_GLOBAL_MAILBOX_INTERFACE4_LSW_ADDR(addr));
  213. +
  214. + /* We assume and enforce the size to be word aligned.
  215. + * If a firmware that is not word aligned is found, please report upstream.
  216. + */
  217. + for (pos = 0; pos < len; pos += sizeof(u32)) {
  218. + u32 word;
  219. +
  220. + /* FW data is always stored in little-endian */
  221. + word = get_unaligned((const u32 *)(data + pos));
  222. +
  223. + phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE5,
  224. + VEND1_GLOBAL_MAILBOX_INTERFACE5_MSW_DATA(word));
  225. + phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE6,
  226. + VEND1_GLOBAL_MAILBOX_INTERFACE6_LSW_DATA(word));
  227. +
  228. + phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE1,
  229. + VEND1_GLOBAL_MAILBOX_INTERFACE1_EXECUTE |
  230. + VEND1_GLOBAL_MAILBOX_INTERFACE1_WRITE);
  231. +
  232. + /* calculate CRC as we load data to the mailbox.
  233. + * We convert word to big-endian as PHY is BE and mailbox will
  234. + * return a BE CRC.
  235. + */
  236. + word = (__force u32)cpu_to_be32(word);
  237. + crc = crc_ccitt_false(crc, (u8 *)&word, sizeof(word));
  238. + }
  239. +
  240. + up_crc = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_MAILBOX_INTERFACE2);
  241. + if (crc != up_crc) {
  242. + phydev_err(phydev, "CRC mismatch: calculated 0x%04x PHY 0x%04x\n",
  243. + crc, up_crc);
  244. + return -EINVAL;
  245. + }
  246. +
  247. + return 0;
  248. +}
  249. +
  250. +static int aqr_fw_boot(struct phy_device *phydev, const u8 *data, size_t size,
  251. + enum aqr_fw_src fw_src)
  252. +{
  253. + u16 calculated_crc, read_crc, read_primary_offset;
  254. + u32 iram_offset = 0, iram_size = 0;
  255. + u32 dram_offset = 0, dram_size = 0;
  256. + char version[VERSION_STRING_SIZE];
  257. + u32 primary_offset = 0;
  258. + int ret;
  259. +
  260. + /* extract saved CRC at the end of the fw
  261. + * CRC is saved in big-endian as PHY is BE
  262. + */
  263. + ret = aqr_fw_get_be16(data, size - sizeof(u16), size, &read_crc);
  264. + if (ret) {
  265. + phydev_err(phydev, "bad firmware CRC in firmware\n");
  266. + return ret;
  267. + }
  268. + calculated_crc = crc_ccitt_false(0, data, size - sizeof(u16));
  269. + if (read_crc != calculated_crc) {
  270. + phydev_err(phydev, "bad firmware CRC: file 0x%04x calculated 0x%04x\n",
  271. + read_crc, calculated_crc);
  272. + return -EINVAL;
  273. + }
  274. +
  275. + /* Get the primary offset to extract DRAM and IRAM sections. */
  276. + ret = aqr_fw_get_le16(data, PRIMARY_OFFSET_OFFSET, size, &read_primary_offset);
  277. + if (ret) {
  278. + phydev_err(phydev, "bad primary offset in firmware\n");
  279. + return ret;
  280. + }
  281. + primary_offset = PRIMARY_OFFSET(read_primary_offset);
  282. +
  283. + /* Find the DRAM and IRAM sections within the firmware file.
  284. + * Make sure the fw_header is correctly in the firmware.
  285. + */
  286. + if (!aqr_fw_validate_get(size, primary_offset + HEADER_OFFSET,
  287. + sizeof(struct aqr_fw_header))) {
  288. + phydev_err(phydev, "bad fw_header in firmware\n");
  289. + return -EINVAL;
  290. + }
  291. +
  292. + /* offset are in LE and values needs to be converted to cpu endian */
  293. + ret = aqr_fw_get_le24(data, primary_offset + HEADER_OFFSET +
  294. + offsetof(struct aqr_fw_header, iram_offset),
  295. + size, &iram_offset);
  296. + if (ret) {
  297. + phydev_err(phydev, "bad iram offset in firmware\n");
  298. + return ret;
  299. + }
  300. + ret = aqr_fw_get_le24(data, primary_offset + HEADER_OFFSET +
  301. + offsetof(struct aqr_fw_header, iram_size),
  302. + size, &iram_size);
  303. + if (ret) {
  304. + phydev_err(phydev, "invalid iram size in firmware\n");
  305. + return ret;
  306. + }
  307. + ret = aqr_fw_get_le24(data, primary_offset + HEADER_OFFSET +
  308. + offsetof(struct aqr_fw_header, dram_offset),
  309. + size, &dram_offset);
  310. + if (ret) {
  311. + phydev_err(phydev, "bad dram offset in firmware\n");
  312. + return ret;
  313. + }
  314. + ret = aqr_fw_get_le24(data, primary_offset + HEADER_OFFSET +
  315. + offsetof(struct aqr_fw_header, dram_size),
  316. + size, &dram_size);
  317. + if (ret) {
  318. + phydev_err(phydev, "invalid dram size in firmware\n");
  319. + return ret;
  320. + }
  321. +
  322. + /* Increment the offset with the primary offset.
  323. + * Validate iram/dram offset and size.
  324. + */
  325. + iram_offset += primary_offset;
  326. + if (iram_size % sizeof(u32)) {
  327. + phydev_err(phydev, "iram size if not aligned to word size. Please report this upstream!\n");
  328. + return -EINVAL;
  329. + }
  330. + if (!aqr_fw_validate_get(size, iram_offset, iram_size)) {
  331. + phydev_err(phydev, "invalid iram offset for iram size\n");
  332. + return -EINVAL;
  333. + }
  334. +
  335. + dram_offset += primary_offset;
  336. + if (dram_size % sizeof(u32)) {
  337. + phydev_err(phydev, "dram size if not aligned to word size. Please report this upstream!\n");
  338. + return -EINVAL;
  339. + }
  340. + if (!aqr_fw_validate_get(size, dram_offset, dram_size)) {
  341. + phydev_err(phydev, "invalid iram offset for iram size\n");
  342. + return -EINVAL;
  343. + }
  344. +
  345. + phydev_dbg(phydev, "primary %d IRAM offset=%d size=%d DRAM offset=%d size=%d\n",
  346. + primary_offset, iram_offset, iram_size, dram_offset, dram_size);
  347. +
  348. + if (!aqr_fw_validate_get(size, dram_offset + VERSION_STRING_OFFSET,
  349. + VERSION_STRING_SIZE)) {
  350. + phydev_err(phydev, "invalid version in firmware\n");
  351. + return -EINVAL;
  352. + }
  353. + strscpy(version, (char *)data + dram_offset + VERSION_STRING_OFFSET,
  354. + VERSION_STRING_SIZE);
  355. + if (version[0] == '\0') {
  356. + phydev_err(phydev, "invalid version in firmware\n");
  357. + return -EINVAL;
  358. + }
  359. + phydev_info(phydev, "loading firmware version '%s' from '%s'\n", version,
  360. + aqr_fw_src_string[fw_src]);
  361. +
  362. + /* stall the microcprocessor */
  363. + phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_CONTROL2,
  364. + VEND1_GLOBAL_CONTROL2_UP_RUN_STALL | VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD);
  365. +
  366. + phydev_dbg(phydev, "loading DRAM 0x%08x from offset=%d size=%d\n",
  367. + DRAM_BASE_ADDR, dram_offset, dram_size);
  368. + ret = aqr_fw_load_memory(phydev, DRAM_BASE_ADDR, data + dram_offset,
  369. + dram_size);
  370. + if (ret)
  371. + return ret;
  372. +
  373. + phydev_dbg(phydev, "loading IRAM 0x%08x from offset=%d size=%d\n",
  374. + IRAM_BASE_ADDR, iram_offset, iram_size);
  375. + ret = aqr_fw_load_memory(phydev, IRAM_BASE_ADDR, data + iram_offset,
  376. + iram_size);
  377. + if (ret)
  378. + return ret;
  379. +
  380. + /* make sure soft reset and low power mode are clear */
  381. + phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_SC,
  382. + VEND1_GLOBAL_SC_SOFT_RESET | VEND1_GLOBAL_SC_LOW_POWER);
  383. +
  384. + /* Release the microprocessor. UP_RESET must be held for 100 usec. */
  385. + phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_CONTROL2,
  386. + VEND1_GLOBAL_CONTROL2_UP_RUN_STALL |
  387. + VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD |
  388. + VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_RST);
  389. + usleep_range(UP_RESET_SLEEP, UP_RESET_SLEEP * 2);
  390. +
  391. + phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_CONTROL2,
  392. + VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD);
  393. +
  394. + return 0;
  395. +}
  396. +
  397. +static int aqr_firmware_load_nvmem(struct phy_device *phydev)
  398. +{
  399. + struct nvmem_cell *cell;
  400. + size_t size;
  401. + u8 *buf;
  402. + int ret;
  403. +
  404. + cell = nvmem_cell_get(&phydev->mdio.dev, "firmware");
  405. + if (IS_ERR(cell))
  406. + return PTR_ERR(cell);
  407. +
  408. + buf = nvmem_cell_read(cell, &size);
  409. + if (IS_ERR(buf)) {
  410. + ret = PTR_ERR(buf);
  411. + goto exit;
  412. + }
  413. +
  414. + ret = aqr_fw_boot(phydev, buf, size, AQR_FW_SRC_NVMEM);
  415. + if (ret)
  416. + phydev_err(phydev, "firmware loading failed: %d\n", ret);
  417. +
  418. + kfree(buf);
  419. +exit:
  420. + nvmem_cell_put(cell);
  421. +
  422. + return ret;
  423. +}
  424. +
  425. +static int aqr_firmware_load_fs(struct phy_device *phydev)
  426. +{
  427. + struct device *dev = &phydev->mdio.dev;
  428. + const struct firmware *fw;
  429. + const char *fw_name;
  430. + int ret;
  431. +
  432. + ret = of_property_read_string(dev->of_node, "firmware-name",
  433. + &fw_name);
  434. + if (ret)
  435. + return ret;
  436. +
  437. + ret = request_firmware(&fw, fw_name, dev);
  438. + if (ret) {
  439. + phydev_err(phydev, "failed to find FW file %s (%d)\n",
  440. + fw_name, ret);
  441. + return ret;
  442. + }
  443. +
  444. + ret = aqr_fw_boot(phydev, fw->data, fw->size, AQR_FW_SRC_FS);
  445. + if (ret)
  446. + phydev_err(phydev, "firmware loading failed: %d\n", ret);
  447. +
  448. + release_firmware(fw);
  449. +
  450. + return ret;
  451. +}
  452. +
  453. +int aqr_firmware_load(struct phy_device *phydev)
  454. +{
  455. + int ret;
  456. +
  457. + /* Check if the firmware is not already loaded by pooling
  458. + * the current version returned by the PHY. If 0 is returned,
  459. + * no firmware is loaded.
  460. + */
  461. + ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_FW_ID);
  462. + if (ret > 0)
  463. + goto exit;
  464. +
  465. + ret = aqr_firmware_load_nvmem(phydev);
  466. + if (!ret)
  467. + goto exit;
  468. +
  469. + ret = aqr_firmware_load_fs(phydev);
  470. + if (ret)
  471. + return ret;
  472. +
  473. +exit:
  474. + return 0;
  475. +}
  476. --- a/drivers/net/phy/aquantia/aquantia_main.c
  477. +++ b/drivers/net/phy/aquantia/aquantia_main.c
  478. @@ -658,11 +658,17 @@ static int aqr107_resume(struct phy_devi
  479. static int aqr107_probe(struct phy_device *phydev)
  480. {
  481. + int ret;
  482. +
  483. phydev->priv = devm_kzalloc(&phydev->mdio.dev,
  484. sizeof(struct aqr107_priv), GFP_KERNEL);
  485. if (!phydev->priv)
  486. return -ENOMEM;
  487. + ret = aqr_firmware_load(phydev);
  488. + if (ret)
  489. + return ret;
  490. +
  491. return aqr_hwmon_probe(phydev);
  492. }