openwrtv3/package/kernel/mac80211/patches/605-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch
Mathias Kresin 4f7a0601e6 mac80211: rt2x00: add mtd-eeprom swab function
Most of the lantiq devices with ralink wifi have the EEPROM stored
in big endian byte order in flash, but the driver expects the EEPROM to
be in little endian.

Signed-off-by: Mathias Kresin <dev@kresin.me>
2016-11-08 11:17:11 +01:00

108 lines
3.1 KiB
Diff

From 339fe73f340161a624cc08e738d2244814852c3e Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Sun, 17 Mar 2013 00:55:04 +0100
Subject: [PATCH] rt2x00: load eeprom on SoC from a mtd device defines inside
OF
Signed-off-by: John Crispin <blogic@openwrt.org>
---
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
@@ -219,6 +219,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,73 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
#include <linux/of.h>
#include "rt2x00.h"
#include "rt2x00lib.h"
+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.size = len;
+ mtd_fw.data = (const u8 *) rt2x00dev->eeprom;
+
+ dev_info(rt2x00dev->dev, "loaded eeprom from mtd device \"%s\"\n", part);
+#endif
+
+ return ret;
+}
+
static const char *
rt2x00lib_get_eeprom_file_name(struct rt2x00_dev *rt2x00dev)
{
@@ -58,6 +120,9 @@ static int rt2x00lib_request_eeprom_file
const char *ee_name;
int retval;
+ if (!rt2800lib_read_eeprom_mtd(rt2x00dev))
+ return 0;
+
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.");