mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-30 10:39:04 +00:00
4f7a0601e6
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>
109 lines
3.1 KiB
Diff
109 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.");
|