--- /dev/null
+From 1046fc9e98936991aeb0b0656c84833d96a63c0f Mon Sep 17 00:00:00 2001
+Date: Sun, 15 Oct 2023 14:22:49 +0200
+Subject: [PATCH 1/5] wifi: rt2x00: Add support for loading EEPROM from
+ userspace
+
+Add support for loading EEPROM from userspace.
+
+---
+ drivers/net/wireless/ralink/rt2x00/Kconfig | 5 ++
+ drivers/net/wireless/ralink/rt2x00/Makefile | 1 +
+ .../net/wireless/ralink/rt2x00/rt2800soc.c | 15 +---
+ drivers/net/wireless/ralink/rt2x00/rt2x00.h | 1 +
+ .../net/wireless/ralink/rt2x00/rt2x00dev.c | 9 +++
+ .../net/wireless/ralink/rt2x00/rt2x00eeprom.c | 75 +++++++++++++++++++
+ .../net/wireless/ralink/rt2x00/rt2x00soc.c | 1 +
+ .../net/wireless/ralink/rt2x00/rt2x00soc.h | 9 +++
+ 8 files changed, 102 insertions(+), 14 deletions(-)
+ create mode 100644 drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c
+
+--- a/local-symbols
++++ b/local-symbols
+@@ -350,6 +350,7 @@ RT2X00_LIB_FIRMWARE=
+ RT2X00_LIB_CRYPTO=
+ RT2X00_LIB_LEDS=
+ RT2X00_LIB_DEBUGFS=
++RT2X00_LIB_EEPROM=
+ RT2X00_DEBUG=
+ WLAN_VENDOR_REALTEK=
+ RTL8180=
+--- a/drivers/net/wireless/ralink/rt2x00/Kconfig
++++ b/drivers/net/wireless/ralink/rt2x00/Kconfig
+@@ -70,6 +70,7 @@ config RT2800PCI
+ select RT2X00_LIB_MMIO
+ select RT2X00_LIB_PCI
+ select RT2X00_LIB_FIRMWARE
++ select RT2X00_LIB_EEPROM
+ select RT2X00_LIB_CRYPTO
+ depends on CRC_CCITT
+ depends on EEPROM_93CX6
+@@ -216,6 +217,7 @@ config RT2800SOC
+ select RT2X00_LIB_MMIO
+ select RT2X00_LIB_CRYPTO
+ select RT2X00_LIB_FIRMWARE
++ select RT2X00_LIB_EEPROM
+ select RT2800_LIB
+ select RT2800_LIB_MMIO
+ help
+@@ -266,6 +268,9 @@ config RT2X00_LIB_FIRMWARE
+ config RT2X00_LIB_CRYPTO
+ bool
+
++config RT2X00_LIB_EEPROM
++ bool
++
+ config RT2X00_LIB_LEDS
+ bool
+ default y if (RT2X00_LIB=y && LEDS_CLASS=y) || (RT2X00_LIB=m && LEDS_CLASS!=n)
+--- a/drivers/net/wireless/ralink/rt2x00/Makefile
++++ b/drivers/net/wireless/ralink/rt2x00/Makefile
+@@ -8,6 +8,7 @@ rt2x00lib-$(CPTCFG_RT2X00_LIB_DEBUGFS) +
+ rt2x00lib-$(CPTCFG_RT2X00_LIB_CRYPTO) += rt2x00crypto.o
+ rt2x00lib-$(CPTCFG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o
+ rt2x00lib-$(CPTCFG_RT2X00_LIB_LEDS) += rt2x00leds.o
++rt2x00lib-$(CPTCFG_RT2X00_LIB_EEPROM) += rt2x00eeprom.o
+
+ obj-$(CPTCFG_RT2X00_LIB) += rt2x00lib.o
+ obj-$(CPTCFG_RT2X00_LIB_MMIO) += rt2x00mmio.o
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
+@@ -90,19 +90,6 @@ static int rt2800soc_set_device_state(st
+ return retval;
+ }
+
+-static int rt2800soc_read_eeprom(struct rt2x00_dev *rt2x00dev)
+-{
+- void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE);
+-
+- if (!base_addr)
+- return -ENOMEM;
+-
+- memcpy_fromio(rt2x00dev->eeprom, base_addr, EEPROM_SIZE);
+-
+- iounmap(base_addr);
+- return 0;
+-}
+-
+ /* Firmware functions */
+ static char *rt2800soc_get_firmware_name(struct rt2x00_dev *rt2x00dev)
+ {
+@@ -168,7 +155,7 @@ static const struct rt2800_ops rt2800soc
+ .register_multiread = rt2x00mmio_register_multiread,
+ .register_multiwrite = rt2x00mmio_register_multiwrite,
+ .regbusy_read = rt2x00mmio_regbusy_read,
+- .read_eeprom = rt2800soc_read_eeprom,
++ .read_eeprom = rt2x00lib_read_eeprom,
+ .hwcrypt_disabled = rt2800soc_hwcrypt_disabled,
+ .drv_write_firmware = rt2800soc_write_firmware,
+ .drv_init_registers = rt2800mmio_init_registers,
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+@@ -703,6 +703,7 @@ enum rt2x00_capability_flags {
+ REQUIRE_HT_TX_DESC,
+ REQUIRE_PS_AUTOWAKE,
+ REQUIRE_DELAYED_RFKILL,
++ REQUIRE_EEPROM_FILE,
+
+ /*
+ * Capabilities
+--- /dev/null
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c
+@@ -0,0 +1,77 @@
++// SPDX-License-Identifier: GPL-2.0-or-later
++ * <http://rt2x00.serialmonkey.com>
++ */
++
++/* Module: rt2x00lib
++ * Abstract: rt2x00 eeprom file loading routines.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++
++#include "rt2x00.h"
++#include "rt2x00soc.h"
++
++static const char *
++rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev)
++{
++ struct rt2x00_platform_data *pdata = rt2x00dev->dev->platform_data;
++
++ if (pdata && pdata->eeprom_file_name)
++ return pdata->eeprom_file_name;
++
++ return NULL;
++}
++
++static int rt2x00lib_read_eeprom_file(struct rt2x00_dev *rt2x00dev)
++{
++ const struct firmware *ee;
++ const char *ee_name;
++ int retval;
++
++ ee_name = rt2x00lib_get_eeprom_file_name(rt2x00dev);
++ if (!ee_name && test_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags)) {
++ rt2x00_err(rt2x00dev, "Required EEPROM name is missing.");
++ return -EINVAL;
++ }
++
++ if (!ee_name)
++ return 0;
++
++ rt2x00_info(rt2x00dev, "Loading EEPROM data from '%s'.\n", ee_name);
++
++ retval = request_firmware(&ee, ee_name, rt2x00dev->dev);
++ if (retval) {
++ rt2x00_err(rt2x00dev, "Failed to request EEPROM.\n");
++ return retval;
++ }
++
++ if (!ee || !ee->size || !ee->data) {
++ rt2x00_err(rt2x00dev, "Failed to read EEPROM file.\n");
++ retval = -ENOENT;
++ goto err_exit;
++ }
++
++ if (ee->size != rt2x00dev->ops->eeprom_size) {
++ rt2x00_err(rt2x00dev,
++ "EEPROM file size is invalid, it should be %d bytes\n",
++ rt2x00dev->ops->eeprom_size);
++ retval = -EINVAL;
++ goto err_release_ee;
++ }
++
++ memcpy(rt2x00dev->eeprom, ee->data, rt2x00dev->ops->eeprom_size);
++
++err_release_ee:
++ release_firmware(ee);
++err_exit:
++ return retval;
++}
++
++int rt2x00lib_read_eeprom(struct rt2x00_dev *rt2x00dev)
++{
++ return rt2x00lib_read_eeprom_file(rt2x00dev);
++}
++EXPORT_SYMBOL_GPL(rt2x00lib_read_eeprom);
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c
+@@ -86,6 +86,7 @@ int rt2x00soc_probe(struct platform_devi
+ if (IS_ERR(rt2x00dev->clk))
+ rt2x00dev->clk = NULL;
+
++ set_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags);
+ rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_SOC);
+
+ retval = rt2x00soc_alloc_reg(rt2x00dev);
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00soc.h
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00soc.h
+@@ -26,4 +26,13 @@ int rt2x00soc_resume(struct platform_dev
+ #define rt2x00soc_resume NULL
+ #endif /* CONFIG_PM */
+
++/*
++ * EEPROM file handlers.
++ */
++#ifdef CPTCFG_RT2X00_LIB_EEPROM
++int rt2x00lib_read_eeprom(struct rt2x00_dev *rt2x00dev);
++#else
++#define rt2x00lib_read_eeprom NULL
++#endif /* CPTCFG_RT2X00_LIB_EEPROM */
++
+ #endif /* RT2X00SOC_H */
--- /dev/null
+From 15329d8b206d9c04ffad49aecd37f5d0bfb85768 Mon Sep 17 00:00:00 2001
+Date: Sun, 15 Oct 2023 14:23:19 +0200
+Subject: [PATCH 2/5] wifi: rt2x00: Add option to pass EEPROM file name from DT
+
+Add option to pass EEPROM file name from DT using ralink,eeprom binding.
+
+---
+ drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c
+@@ -10,6 +10,7 @@
+
+ #include <linux/kernel.h>
+ #include <linux/module.h>
++#include <linux/of.h>
+
+ #include "rt2x00.h"
+ #include "rt2x00soc.h"
+@@ -18,10 +19,20 @@ static const char *
+ rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev)
+ {
+ struct rt2x00_platform_data *pdata = rt2x00dev->dev->platform_data;
++#ifdef CONFIG_OF
++ struct device_node *np;
++ const char *eep;
++#endif
+
+ if (pdata && pdata->eeprom_file_name)
+ return pdata->eeprom_file_name;
+
++#ifdef CONFIG_OF
++ np = rt2x00dev->dev->of_node;
++ if (np && !of_property_read_string(np, "ralink,eeprom", &eep))
++ return eep;
++#endif
++
+ return NULL;
+ }
+
--- /dev/null
+From 71261ca81b491a4c3b08690347c12e96a75ad0d0 Mon Sep 17 00:00:00 2001
+Date: Sun, 17 Mar 2013 00:55:04 +0100
+Subject: [PATCH 3/5] wifi: rt2x00: Add support for loading EEPROM from MTD
+
+Add support for loading EEPROM from MTD.
+
+---
+ drivers/net/wireless/ralink/rt2x00/Kconfig | 1 +
+ .../net/wireless/ralink/rt2x00/rt2x00eeprom.c | 66 +++++++++++++++++++
+ 2 files changed, 67 insertions(+)
+
+--- a/drivers/net/wireless/ralink/rt2x00/Kconfig
++++ b/drivers/net/wireless/ralink/rt2x00/Kconfig
+@@ -220,6 +220,7 @@ config RT2800SOC
+ select RT2X00_LIB_EEPROM
+ select RT2800_LIB
+ select RT2800_LIB_MMIO
++ select MTD if SOC_RT288X || SOC_RT305X
+ help
+ This adds support for Ralink WiSoC devices.
+ Supported chips: RT2880, RT3050, RT3052, RT3350, RT3352.
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c
+@@ -10,11 +10,69 @@
+
+ #include <linux/kernel.h>
+ #include <linux/module.h>
++#if IS_ENABLED(CONFIG_MTD)
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/partitions.h>
++#endif
+ #include <linux/of.h>
+
+ #include "rt2x00.h"
+ #include "rt2x00soc.h"
+
++#if IS_ENABLED(CONFIG_MTD)
++static int rt2800lib_read_eeprom_mtd(struct rt2x00_dev *rt2x00dev)
++{
++ int ret = -EINVAL;
++#ifdef CONFIG_OF
++ struct device_node *np = rt2x00dev->dev->of_node, *mtd_np = NULL;
++ int size, offset = 0;
++ struct mtd_info *mtd;
++ const char *part;
++ const __be32 *list;
++ phandle phandle;
++ size_t retlen;
++
++ list = of_get_property(np, "ralink,mtd-eeprom", &size);
++ if (!list)
++ return -ENOENT;
++
++ phandle = be32_to_cpup(list++);
++ if (phandle)
++ mtd_np = of_find_node_by_phandle(phandle);
++ if (!mtd_np) {
++ dev_err(rt2x00dev->dev, "failed to load mtd phandle\n");
++ return -EINVAL;
++ }
++
++ part = of_get_property(mtd_np, "label", NULL);
++ if (!part)
++ part = mtd_np->name;
++
++ mtd = get_mtd_device_nm(part);
++ if (IS_ERR(mtd)) {
++ dev_err(rt2x00dev->dev, "failed to get mtd device \"%s\"\n", part);
++ return PTR_ERR(mtd);
++ }
++
++ if (size > sizeof(*list))
++ offset = be32_to_cpup(list);
++
++ ret = mtd_read(mtd, offset, rt2x00dev->ops->eeprom_size,
++ &retlen, (u_char *)rt2x00dev->eeprom);
++ put_mtd_device(mtd);
++
++ if (retlen != rt2x00dev->ops->eeprom_size || ret) {
++ dev_err(rt2x00dev->dev, "failed to load eeprom from device \"%s\"\n", part);
++ return ret;
++ }
++
++ dev_info(rt2x00dev->dev, "loaded eeprom from mtd device \"%s\"\n", part);
++#endif
++
++ return ret;
++}
++#endif
++
+ static const char *
+ rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev)
+ {
+@@ -83,5 +141,13 @@ err_exit:
+
+ int rt2x00lib_read_eeprom(struct rt2x00_dev *rt2x00dev)
+ {
++ int ret;
++
++#if IS_ENABLED(CONFIG_MTD)
++ ret = rt2800lib_read_eeprom_mtd(rt2x00dev);
++ if (!ret)
++ return 0;
++#endif
++
+ return rt2x00lib_read_eeprom_file(rt2x00dev);
+ }
--- /dev/null
+From 9c9a3c27b96e057f3c3f47151d7a170d84e3bb5f Mon Sep 17 00:00:00 2001
+Date: Sun, 15 Oct 2023 15:31:47 +0200
+Subject: [PATCH 4/5] wifi: rt2x00: Support EEPROM swap binding
+
+Add binding "ralink,eeprom-swap" to swap bytes of EEPROM before using
+it.
+
+---
+ drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c
+@@ -20,6 +20,19 @@
+ #include "rt2x00soc.h"
+
+ #if IS_ENABLED(CONFIG_MTD)
++static void rt2800lib_eeprom_swap(struct rt2x00_dev *rt2x00dev)
++{
++ struct device_node *np = rt2x00dev->dev->of_node;
++ size_t len = rt2x00dev->ops->eeprom_size;
++ int i;
++
++ if (!of_find_property(np, "ralink,eeprom-swap", NULL))
++ return;
++
++ for (i = 0; i < len / sizeof(u16); i++)
++ rt2x00dev->eeprom[i] = swab16(rt2x00dev->eeprom[i]);
++}
++
+ static int rt2800lib_read_eeprom_mtd(struct rt2x00_dev *rt2x00dev)
+ {
+ int ret = -EINVAL;
+@@ -66,6 +79,8 @@ static int rt2800lib_read_eeprom_mtd(str
+ return ret;
+ }
+
++ rt2800lib_eeprom_swap(rt2x00dev);
++
+ dev_info(rt2x00dev->dev, "loaded eeprom from mtd device \"%s\"\n", part);
+ #endif
+
--- /dev/null
+From 9008cdacdc41f8233f4444b86cf3a17201686e2d Mon Sep 17 00:00:00 2001
+Date: Tue, 18 Jul 2023 20:18:16 +0800
+Subject: [PATCH 5/5] wifi: rt2x00: support loading eeprom from NVMEM cells
+
+This patch allows rt2x00 to load eeprom from "eeprom" NVMEM cell.
+
+Example:
+
+/* load eeprom from NVMEM provider 'eep' */
+&wmac {
+ nvmem-cells = <&eep>;
+ nvmem-cell-names = "eeprom";
+};
+
+---
+ .../net/wireless/ralink/rt2x00/rt2x00eeprom.c | 41 ++++++++++++++++++-
+ 1 file changed, 40 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c
+@@ -14,12 +14,12 @@
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/partitions.h>
+ #endif
++#include <linux/nvmem-consumer.h>
+ #include <linux/of.h>
+
+ #include "rt2x00.h"
+ #include "rt2x00soc.h"
+
+-#if IS_ENABLED(CONFIG_MTD)
+ static void rt2800lib_eeprom_swap(struct rt2x00_dev *rt2x00dev)
+ {
+ struct device_node *np = rt2x00dev->dev->of_node;
+@@ -33,6 +33,7 @@ static void rt2800lib_eeprom_swap(struct
+ rt2x00dev->eeprom[i] = swab16(rt2x00dev->eeprom[i]);
+ }
+
++#if IS_ENABLED(CONFIG_MTD)
+ static int rt2800lib_read_eeprom_mtd(struct rt2x00_dev *rt2x00dev)
+ {
+ int ret = -EINVAL;
+@@ -88,6 +89,40 @@ static int rt2800lib_read_eeprom_mtd(str
+ }
+ #endif
+
++static int rt2800lib_read_eeprom_nvmem(struct rt2x00_dev *rt2x00dev)
++{
++ struct device_node *np = rt2x00dev->dev->of_node;
++ unsigned int len = rt2x00dev->ops->eeprom_size;
++ struct nvmem_cell *cell;
++ const void *data;
++ size_t retlen;
++ int ret = 0;
++
++ cell = of_nvmem_cell_get(np, "eeprom");
++ if (IS_ERR(cell))
++ return PTR_ERR(cell);
++
++ data = nvmem_cell_read(cell, &retlen);
++ nvmem_cell_put(cell);
++
++ if (IS_ERR(data))
++ return PTR_ERR(data);
++
++ if (retlen != len) {
++ dev_err(rt2x00dev->dev, "invalid eeprom size, required: 0x%04x\n", len);
++ ret = -EINVAL;
++ goto exit;
++ }
++
++ memcpy(rt2x00dev->eeprom, data, len);
++
++ rt2800lib_eeprom_swap(rt2x00dev);
++
++exit:
++ kfree(data);
++ return ret;
++}
++
+ static const char *
+ rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev)
+ {
+@@ -164,5 +199,9 @@ int rt2x00lib_read_eeprom(struct rt2x00_
+ return 0;
+ #endif
+
++ ret = rt2800lib_read_eeprom_nvmem(rt2x00dev);
++ if (!ret)
++ return 0;
++
+ return rt2x00lib_read_eeprom_file(rt2x00dev);
+ }
+++ /dev/null
---- a/local-symbols
-+++ b/local-symbols
-@@ -350,6 +350,7 @@ RT2X00_LIB_FIRMWARE=
- RT2X00_LIB_CRYPTO=
- RT2X00_LIB_LEDS=
- RT2X00_LIB_DEBUGFS=
-+RT2X00_LIB_EEPROM=
- RT2X00_DEBUG=
- WLAN_VENDOR_REALTEK=
- RTL8180=
---- a/drivers/net/wireless/ralink/rt2x00/Kconfig
-+++ b/drivers/net/wireless/ralink/rt2x00/Kconfig
-@@ -70,6 +70,7 @@ config RT2800PCI
- select RT2X00_LIB_MMIO
- select RT2X00_LIB_PCI
- select RT2X00_LIB_FIRMWARE
-+ select RT2X00_LIB_EEPROM
- select RT2X00_LIB_CRYPTO
- depends on CRC_CCITT
- depends on EEPROM_93CX6
-@@ -216,6 +217,7 @@ config RT2800SOC
- select RT2X00_LIB_MMIO
- select RT2X00_LIB_CRYPTO
- select RT2X00_LIB_FIRMWARE
-+ select RT2X00_LIB_EEPROM
- select RT2800_LIB
- select RT2800_LIB_MMIO
- help
-@@ -266,6 +268,9 @@ config RT2X00_LIB_FIRMWARE
- config RT2X00_LIB_CRYPTO
- bool
-
-+config RT2X00_LIB_EEPROM
-+ bool
-+
- config RT2X00_LIB_LEDS
- bool
- default y if (RT2X00_LIB=y && LEDS_CLASS=y) || (RT2X00_LIB=m && LEDS_CLASS!=n)
---- a/drivers/net/wireless/ralink/rt2x00/Makefile
-+++ b/drivers/net/wireless/ralink/rt2x00/Makefile
-@@ -8,6 +8,7 @@ rt2x00lib-$(CPTCFG_RT2X00_LIB_DEBUGFS) +
- rt2x00lib-$(CPTCFG_RT2X00_LIB_CRYPTO) += rt2x00crypto.o
- rt2x00lib-$(CPTCFG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o
- rt2x00lib-$(CPTCFG_RT2X00_LIB_LEDS) += rt2x00leds.o
-+rt2x00lib-$(CPTCFG_RT2X00_LIB_EEPROM) += rt2x00eeprom.o
-
- obj-$(CPTCFG_RT2X00_LIB) += rt2x00lib.o
- obj-$(CPTCFG_RT2X00_LIB_MMIO) += rt2x00mmio.o
---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
-@@ -47,6 +47,8 @@ struct rt2800_drv_data {
- struct ieee80211_sta *wcid_to_sta[STA_IDS_SIZE];
- };
-
-+#include "rt2800.h"
-+
- struct rt2800_ops {
- u32 (*register_read)(struct rt2x00_dev *rt2x00dev,
- const unsigned int offset);
-@@ -145,6 +147,15 @@ static inline int rt2800_read_eeprom(str
- {
- const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
-
-+ if (rt2x00dev->eeprom_file) {
-+ memcpy(rt2x00dev->eeprom, rt2x00dev->eeprom_file->data,
-+ EEPROM_SIZE);
-+ return 0;
-+ }
-+
-+ if (!rt2800ops->read_eeprom)
-+ return -EINVAL;
-+
- return rt2800ops->read_eeprom(rt2x00dev);
- }
-
---- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
-@@ -90,19 +90,6 @@ static int rt2800soc_set_device_state(st
- return retval;
- }
-
--static int rt2800soc_read_eeprom(struct rt2x00_dev *rt2x00dev)
--{
-- void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE);
--
-- if (!base_addr)
-- return -ENOMEM;
--
-- memcpy_fromio(rt2x00dev->eeprom, base_addr, EEPROM_SIZE);
--
-- iounmap(base_addr);
-- return 0;
--}
--
- /* Firmware functions */
- static char *rt2800soc_get_firmware_name(struct rt2x00_dev *rt2x00dev)
- {
-@@ -168,7 +155,6 @@ static const struct rt2800_ops rt2800soc
- .register_multiread = rt2x00mmio_register_multiread,
- .register_multiwrite = rt2x00mmio_register_multiwrite,
- .regbusy_read = rt2x00mmio_regbusy_read,
-- .read_eeprom = rt2800soc_read_eeprom,
- .hwcrypt_disabled = rt2800soc_hwcrypt_disabled,
- .drv_write_firmware = rt2800soc_write_firmware,
- .drv_init_registers = rt2800mmio_init_registers,
---- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
-@@ -703,6 +703,7 @@ enum rt2x00_capability_flags {
- REQUIRE_HT_TX_DESC,
- REQUIRE_PS_AUTOWAKE,
- REQUIRE_DELAYED_RFKILL,
-+ REQUIRE_EEPROM_FILE,
-
- /*
- * Capabilities
-@@ -980,6 +981,11 @@ struct rt2x00_dev {
- const struct firmware *fw;
-
- /*
-+ * EEPROM image.
-+ */
-+ const struct firmware *eeprom_file;
-+
-+ /*
- * FIFO for storing tx status reports between isr and tasklet.
- */
- DECLARE_KFIFO_PTR(txstatus_fifo, u32);
---- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
-@@ -1420,6 +1420,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de
- INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup);
- INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep);
-
-+ retval = rt2x00lib_load_eeprom_file(rt2x00dev);
-+ if (retval)
-+ goto exit;
-+
- /*
- * Let the driver probe the device to detect the capabilities.
- */
-@@ -1560,6 +1564,11 @@ void rt2x00lib_remove_dev(struct rt2x00_
- * Free the driver data.
- */
- kfree(rt2x00dev->drv_data);
-+
-+ /*
-+ * Free EEPROM image.
-+ */
-+ rt2x00lib_free_eeprom_file(rt2x00dev);
- }
- EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev);
-
---- /dev/null
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c
-@@ -0,0 +1,106 @@
-+/*
-+ <http://rt2x00.serialmonkey.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; either version 2 of the License, or
-+ (at your option) any later version.
-+
-+ This program is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ GNU General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this program; if not, write to the
-+ Free Software Foundation, Inc.,
-+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+ */
-+
-+/*
-+ Module: rt2x00lib
-+ Abstract: rt2x00 eeprom file loading routines.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+
-+#include "rt2x00.h"
-+#include "rt2x00lib.h"
-+
-+static const char *
-+rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev)
-+{
-+ struct rt2x00_platform_data *pdata = rt2x00dev->dev->platform_data;
-+
-+ if (pdata && pdata->eeprom_file_name)
-+ return pdata->eeprom_file_name;
-+
-+ return NULL;
-+}
-+
-+static int rt2x00lib_request_eeprom_file(struct rt2x00_dev *rt2x00dev)
-+{
-+ const struct firmware *ee;
-+ const char *ee_name;
-+ int retval;
-+
-+ ee_name = rt2x00lib_get_eeprom_file_name(rt2x00dev);
-+ if (!ee_name && test_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags)) {
-+ rt2x00_err(rt2x00dev, "Required EEPROM name is missing.");
-+ return -EINVAL;
-+ }
-+
-+ if (!ee_name)
-+ return 0;
-+
-+ rt2x00_info(rt2x00dev, "Loading EEPROM data from '%s'.\n", ee_name);
-+
-+ retval = request_firmware(&ee, ee_name, rt2x00dev->dev);
-+ if (retval) {
-+ rt2x00_err(rt2x00dev, "Failed to request EEPROM.\n");
-+ return retval;
-+ }
-+
-+ if (!ee || !ee->size || !ee->data) {
-+ rt2x00_err(rt2x00dev, "Failed to read EEPROM file.\n");
-+ retval = -ENOENT;
-+ goto err_exit;
-+ }
-+
-+ if (ee->size != rt2x00dev->ops->eeprom_size) {
-+ rt2x00_err(rt2x00dev,
-+ "EEPROM file size is invalid, it should be %d bytes\n",
-+ rt2x00dev->ops->eeprom_size);
-+ retval = -EINVAL;
-+ goto err_release_ee;
-+ }
-+
-+ rt2x00dev->eeprom_file = ee;
-+ return 0;
-+
-+err_release_ee:
-+ release_firmware(ee);
-+err_exit:
-+ return retval;
-+}
-+
-+int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev)
-+{
-+ int retval;
-+
-+ retval = rt2x00lib_request_eeprom_file(rt2x00dev);
-+ if (retval)
-+ return retval;
-+
-+ return 0;
-+}
-+
-+void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev)
-+{
-+ if (rt2x00dev->eeprom_file && rt2x00dev->eeprom_file->size)
-+ release_firmware(rt2x00dev->eeprom_file);
-+ rt2x00dev->eeprom_file = NULL;
-+}
---- a/drivers/net/wireless/ralink/rt2x00/rt2x00lib.h
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00lib.h
-@@ -286,6 +286,22 @@ static inline void rt2x00lib_free_firmwa
- #endif /* CPTCFG_RT2X00_LIB_FIRMWARE */
-
- /*
-+ * EEPROM file handlers.
-+ */
-+#ifdef CPTCFG_RT2X00_LIB_EEPROM
-+int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev);
-+void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev);
-+#else
-+static inline int rt2x00lib_load_eeprom_file(struct rt2x00_dev *rt2x00dev)
-+{
-+ return 0;
-+}
-+static inline void rt2x00lib_free_eeprom_file(struct rt2x00_dev *rt2x00dev)
-+{
-+}
-+#endif /* CPTCFG_RT2X00_LIB_EEPROM */
-+
-+/*
- * Debugfs handlers.
- */
- #ifdef CPTCFG_RT2X00_LIB_DEBUGFS
---- a/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c
-@@ -86,6 +86,7 @@ int rt2x00soc_probe(struct platform_devi
- if (IS_ERR(rt2x00dev->clk))
- rt2x00dev->clk = NULL;
-
-+ set_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags);
- rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_SOC);
-
- retval = rt2x00soc_alloc_reg(rt2x00dev);
+++ /dev/null
---- a/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c
-@@ -26,6 +26,7 @@
-
- #include <linux/kernel.h>
- #include <linux/module.h>
-+#include <linux/of.h>
-
- #include "rt2x00.h"
- #include "rt2x00lib.h"
-@@ -34,10 +35,20 @@ static const char *
- rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev)
- {
- struct rt2x00_platform_data *pdata = rt2x00dev->dev->platform_data;
-+#ifdef CONFIG_OF
-+ struct device_node *np;
-+ const char *eep;
-+#endif
-
- if (pdata && pdata->eeprom_file_name)
- return pdata->eeprom_file_name;
-
-+#ifdef CONFIG_OF
-+ np = rt2x00dev->dev->of_node;
-+ if (np && of_property_read_string(np, "ralink,eeprom", &eep) == 0)
-+ return eep;
-+#endif
-+
- return NULL;
- }
-
+++ /dev/null
-From 339fe73f340161a624cc08e738d2244814852c3e Mon Sep 17 00:00:00 2001
-Date: Sun, 17 Mar 2013 00:55:04 +0100
-Subject: [PATCH] rt2x00: load eeprom on SoC from a mtd device defines inside
- OF
-
----
- drivers/net/wireless/ralink/rt2x00/Kconfig | 1 +
- drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c | 65 +++++++++++++++++++++++
- 2 files changed, 66 insertions(+)
-
---- a/drivers/net/wireless/ralink/rt2x00/Kconfig
-+++ b/drivers/net/wireless/ralink/rt2x00/Kconfig
-@@ -220,6 +220,7 @@ config RT2800SOC
- select RT2X00_LIB_EEPROM
- select RT2800_LIB
- select RT2800_LIB_MMIO
-+ select MTD if SOC_RT288X || SOC_RT305X
- help
- This adds support for Ralink WiSoC devices.
- Supported chips: RT2880, RT3050, RT3052, RT3350, RT3352.
---- a/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c
-+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00eeprom.c
-@@ -26,11 +26,76 @@
-
- #include <linux/kernel.h>
- #include <linux/module.h>
-+#if IS_ENABLED(CONFIG_MTD)
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/partitions.h>
-+#endif
- #include <linux/of.h>
-
- #include "rt2x00.h"
- #include "rt2x00lib.h"
-
-+#if IS_ENABLED(CONFIG_MTD)
-+static int rt2800lib_read_eeprom_mtd(struct rt2x00_dev *rt2x00dev)
-+{
-+ int ret = -EINVAL;
-+#ifdef CONFIG_OF
-+ static struct firmware mtd_fw;
-+ struct device_node *np = rt2x00dev->dev->of_node, *mtd_np = NULL;
-+ size_t retlen, len = rt2x00dev->ops->eeprom_size;
-+ int i, size, offset = 0;
-+ struct mtd_info *mtd;
-+ const char *part;
-+ const __be32 *list;
-+ phandle phandle;
-+
-+ list = of_get_property(np, "ralink,mtd-eeprom", &size);
-+ if (!list)
-+ return -ENOENT;
-+
-+ phandle = be32_to_cpup(list++);
-+ if (phandle)
-+ mtd_np = of_find_node_by_phandle(phandle);
-+ if (!mtd_np) {
-+ dev_err(rt2x00dev->dev, "failed to load mtd phandle\n");
-+ return -EINVAL;
-+ }
-+
-+ part = of_get_property(mtd_np, "label", NULL);
-+ if (!part)
-+ part = mtd_np->name;
-+
-+ mtd = get_mtd_device_nm(part);
-+ if (IS_ERR(mtd)) {
-+ dev_err(rt2x00dev->dev, "failed to get mtd device \"%s\"\n", part);
-+ return PTR_ERR(mtd);
-+ }
-+
-+ if (size > sizeof(*list))
-+ offset = be32_to_cpup(list);
-+
-+ ret = mtd_read(mtd, offset, len, &retlen, (u_char *) rt2x00dev->eeprom);
-+ put_mtd_device(mtd);
-+
-+ if ((retlen != rt2x00dev->ops->eeprom_size) || ret) {
-+ dev_err(rt2x00dev->dev, "failed to load eeprom from device \"%s\"\n", part);
-+ return ret;
-+ }
-+
-+ if (of_find_property(np, "ralink,mtd-eeprom-swap", NULL))
-+ for (i = 0; i < len/sizeof(u16); i++)
-+ rt2x00dev->eeprom[i] = swab16(rt2x00dev->eeprom[i]);
-+
-+ rt2x00dev->eeprom_file = &mtd_fw;
-+ mtd_fw.data = (const u8 *) rt2x00dev->eeprom;
-+
-+ dev_info(rt2x00dev->dev, "loaded eeprom from mtd device \"%s\"\n", part);
-+#endif
-+
-+ return ret;
-+}
-+#endif
-+
- static const char *
- rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev)
- {
-@@ -58,6 +123,11 @@ static int rt2x00lib_request_eeprom_file
- const char *ee_name;
- int retval;
-
-+#if IS_ENABLED(CONFIG_MTD)
-+ if (!rt2800lib_read_eeprom_mtd(rt2x00dev))
-+ return 0;
-+#endif
-+
- ee_name = rt2x00lib_get_eeprom_file_name(rt2x00dev);
- if (!ee_name && test_bit(REQUIRE_EEPROM_FILE, &rt2x00dev->cap_flags)) {
- rt2x00_err(rt2x00dev, "Required EEPROM name is missing.");
--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
-@@ -225,10 +225,17 @@ static int rt2800soc_probe(struct platfo
+@@ -226,10 +226,17 @@ static int rt2800soc_probe(struct platfo
return rt2x00soc_probe(pdev, &rt2800soc_ops);
}
#include <linux/rt2x00_platform.h>
#include <net/mac80211.h>
-@@ -1029,6 +1030,11 @@ struct rt2x00_dev {
+@@ -1024,6 +1025,11 @@ struct rt2x00_dev {
/* Clock for System On Chip devices. */
struct clk *clk;
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
-@@ -78,6 +78,9 @@ struct rt2800_ops {
+@@ -76,6 +76,9 @@ struct rt2800_ops {
int (*drv_init_registers)(struct rt2x00_dev *rt2x00dev);
__le32 *(*drv_get_txwi)(struct queue_entry *entry);
unsigned int (*drv_get_dma_done)(struct data_queue *queue);
};
static inline u32 rt2800_register_read(struct rt2x00_dev *rt2x00dev,
-@@ -195,6 +198,27 @@ static inline unsigned int rt2800_drv_ge
+@@ -184,6 +187,27 @@ static inline unsigned int rt2800_drv_ge
return rt2800ops->drv_get_dma_done(queue);
}
static const struct ieee80211_ops rt2800soc_mac80211_ops = {
.tx = rt2x00mac_tx,
.wake_tx_queue = ieee80211_handle_wake_tx_queue,
-@@ -160,6 +187,9 @@ static const struct rt2800_ops rt2800soc
+@@ -161,6 +188,9 @@ static const struct rt2800_ops rt2800soc
.drv_init_registers = rt2800mmio_init_registers,
.drv_get_txwi = rt2800mmio_get_txwi,
.drv_get_dma_done = rt2800mmio_get_dma_done,
rt2x00_rt(rt2x00dev, RT3071) ||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
-@@ -1277,6 +1277,12 @@ rt2x00_has_cap_external_lna_bg(struct rt
+@@ -1272,6 +1272,12 @@ rt2x00_has_cap_external_lna_bg(struct rt
}
static inline bool