I've got an operational 762SX router running Barrier Breaker (14.07) with the following patches in place. Note I'm not using the ADSL port so I haven't bothered to include the ADSL fixes from Delboy, but I did include his LED patch. Also I'm using wvdakker's method to read the MAC address from flash insetad of hardcoding it in the code.
==== diff --git a/target/linux/lantiq/dts/GIGASX76X.dts b/target/linux/lantiq/dts/GIGASX76X.dts ====
--- a/arch/mips/lantiq/Makefile
+++ b/arch/mips/lantiq/Makefile
@@ -4,8 +4,9 @@
# under the terms of the GNU General Public License version 2 as published
# by the Free Software Foundation.
-obj-y := irq.o clk.o prom.o softdog_vpe.o
+obj-y := irq.o clk.o prom.o
+obj=$(CONFIG_MIPS_VPE_LOADER) += softdog_vpe.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_SOC_TYPE_XWAY) += xway/
--- a/arch/mips/lantiq/xway/ath_eep.c
+++ b/arch/mips/lantiq/xway/ath_eep.c
@@ -21,6 +21,7 @@
#include <linux/mtd/mtd.h>
#include <pci-ath-fixup.h>
#include <lantiq_soc.h>
+#include <linux/of_net.h>
extern int (*ltq_pci_plat_dev_init)(struct pci_dev *dev);
struct ath5k_platform_data ath5k_pdata;
@@ -36,11 +37,10 @@ static int ath9k_pci_plat_dev_init(struc
}
static int ath9k_eep_load;
+
int __init of_ath9k_eeprom_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node, *mtd_np;
- struct resource *eep_res, *mac_res = NULL;
- void __iomem *eep, *mac;
int mac_offset, led_pin;
u32 mac_inc = 0, pci_slot = 0;
int i;
@@ -50,41 +50,41 @@ int __init of_ath9k_eeprom_probe(struct
const char *part;
phandle phandle;
- if ((list = of_get_property(np, "ath,eep-flash", &i)) && i == 2 *
- sizeof(*list) && (phandle = be32_to_cpup(list++)) &&
- (mtd_np = of_find_node_by_phandle(phandle)) && ((part =
- of_get_property(mtd_np, "label", NULL)) || (part =
- mtd_np->name)) && (the_mtd = get_mtd_device_nm(part))
- != ERR_PTR(-ENODEV)) {
- i = mtd_read(the_mtd, be32_to_cpup(list),
- ATH9K_PLAT_EEP_MAX_WORDS << 1, &flash_readlen,
- (void *) ath9k_pdata.eeprom_data);
- if (!of_property_read_u32(np, "ath,mac-offset", &mac_offset)) {
- size_t mac_readlen;
- mtd_read(the_mtd, mac_offset, 6, &mac_readlen,
- (void *) athxk_eeprom_mac);
- }
- put_mtd_device(the_mtd);
- if ((sizeof(ath9k_pdata.eeprom_data) != flash_readlen) || i) {
- dev_err(&pdev->dev, "failed to load eeprom from mtd\n");
- return -ENODEV;
- }
- } else {
- eep_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- mac_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ list = of_get_property(np, "ath,eep-flash", &i);
+ if (!list || (i != (2 * sizeof(*list)))) {
+ dev_err(&pdev->dev, "failed to find ath,eep-flash\n");
+ return -ENODEV;
+ }
- if (!eep_res) {
- dev_err(&pdev->dev, "failed to load eeprom address\n");
- return -ENODEV;
- }
- if (resource_size(eep_res) != ATH9K_PLAT_EEP_MAX_WORDS << 1) {
- dev_err(&pdev->dev, "eeprom has an invalid size\n");
- return -EINVAL;
- }
+ phandle = be32_to_cpup(list++);
+ if (!phandle) {
+ dev_err(&pdev->dev, "failed to find phandle\n");
+ return -ENODEV;
+ }
- eep = ioremap(eep_res->start, resource_size(eep_res));
- memcpy_fromio(ath9k_pdata.eeprom_data, eep,
- ATH9K_PLAT_EEP_MAX_WORDS << 1);
+ mtd_np = of_find_node_by_phandle(phandle);
+ if (!mtd_np) {
+ dev_err(&pdev->dev, "failed to find mtd node\n");
+ return -ENODEV;
+ }
+
+ part = of_get_property(mtd_np, "label", NULL);
+ if (!part)
+ part = mtd_np->name;
+
+ the_mtd = get_mtd_device_nm(part);
+ if (the_mtd == ERR_PTR(-ENODEV)) {
+ dev_err(&pdev->dev, "failed to find mtd device\n");
+ return -ENODEV;
+ }
+
+ i = mtd_read(the_mtd, be32_to_cpup(list),
+ ATH9K_PLAT_EEP_MAX_WORDS << 1, &flash_readlen,
+ (void *) ath9k_pdata.eeprom_data);
+ put_mtd_device(the_mtd);
+ if ((sizeof(ath9k_pdata.eeprom_data) != flash_readlen) || i) {
+ dev_err(&pdev->dev, "failed to load eeprom from mtd\n");
+ return -ENODEV;
}
if (of_find_property(np, "ath,eep-swap", NULL))
@@ -97,21 +97,12 @@ int __init of_ath9k_eeprom_probe(struct
dev_info(&pdev->dev, "endian check enabled.\n");
}
- if (!is_valid_ether_addr(athxk_eeprom_mac)) {
- if (mac_res) {
- if (resource_size(mac_res) != 6) {
- dev_err(&pdev->dev, "mac has an invalid size\n");
- return -EINVAL;
- }
- mac = ioremap(mac_res->start, resource_size(mac_res));
- memcpy_fromio(athxk_eeprom_mac, mac, 6);
- } else if (ltq_get_eth_mac()) {
- memcpy(athxk_eeprom_mac, ltq_get_eth_mac(), 6);
- }
- }
- if (!is_valid_ether_addr(athxk_eeprom_mac)) {
- dev_warn(&pdev->dev, "using random mac\n");
+ if (!of_property_read_u32(np, "ath,mac-offset", &mac_offset)) {
+ memcpy_fromio(athxk_eeprom_mac, (void*) ath9k_pdata.eeprom_data + mac_offset, 6);
+ } else {
random_ether_addr(athxk_eeprom_mac);
+ if (of_get_mac_address_mtd(np, athxk_eeprom_mac))
+ dev_warn(&pdev->dev, "using random mac\n");
}
if (!of_property_read_u32(np, "ath,mac-increment", &mac_inc))
@@ -122,19 +113,18 @@ int __init of_ath9k_eeprom_probe(struct
if (!of_property_read_u32(np, "ath,pci-slot", &pci_slot)) {
ltq_pci_ath_fixup(pci_slot, ath9k_pdata.eeprom_data);
-
dev_info(&pdev->dev, "pci slot: %u\n", pci_slot);
- if (ath9k_eep_load) {
- struct pci_dev *d = NULL;
- while ((d = pci_get_device(PCI_VENDOR_ID_ATHEROS,
- PCI_ANY_ID, d)) != NULL)
- pci_fixup_device(pci_fixup_early, d);
- }
-
+ if (ath9k_eep_load) {
+ struct pci_dev *d = NULL;
+ while ((d = pci_get_device(PCI_VENDOR_ID_ATHEROS,
+ PCI_ANY_ID, d)) != NULL)
+ pci_fixup_device(pci_fixup_early, d);
+ }
}
if (!of_property_read_u32(np, "ath,led-pin", &led_pin)) {
ath9k_pdata.led_pin = led_pin;
+
dev_info(&pdev->dev, "using led pin %d.\n", led_pin);
}
@@ -158,24 +148,25 @@ static struct platform_driver ath9k_eepr
static int __init of_ath9k_eeprom_init(void)
{
- int ret = platform_driver_probe(&ath9k_eeprom_driver, of_ath9k_eeprom_probe);
+ int ret = 0;
+
+ ret = platform_driver_probe(&ath9k_eeprom_driver, of_ath9k_eeprom_probe);
- if (ret)
- ath9k_eep_load = 1;
+ if (ret)
+ ath9k_eep_load = 1;
- return ret;
+ return ret;
}
static int __init of_ath9k_eeprom_init_late(void)
{
- if (!ath9k_eep_load)
- return 0;
- return platform_driver_probe(&ath9k_eeprom_driver, of_ath9k_eeprom_probe);
+ if (!ath9k_eep_load)
+ return 0;
+ return platform_driver_probe(&ath9k_eeprom_driver, of_ath9k_eeprom_probe);
}
late_initcall(of_ath9k_eeprom_init_late);
subsys_initcall(of_ath9k_eeprom_init);
-
static int ath5k_pci_plat_dev_init(struct pci_dev *dev)
{
dev->dev.platform_data = &ath5k_pdata;
@@ -185,77 +176,146 @@ static int ath5k_pci_plat_dev_init(struc
int __init of_ath5k_eeprom_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node, *mtd_np;
- struct resource *eep_res, *mac_res = NULL;
+ struct resource *eep_res, *mac_res;
void __iomem *eep, *mac;
int mac_offset;
- u32 mac_inc = 0;
+ u32 mac_inc = 0, pci_slot = 0;
int i;
+ u16 *eepdata, sum, el;
struct mtd_info *the_mtd;
size_t flash_readlen;
const __be32 *list;
const char *part;
phandle phandle;
- if ((list = of_get_property(np, "ath,eep-flash", &i)) && i == 2 *
- sizeof(*list) && (phandle = be32_to_cpup(list++)) &&
- (mtd_np = of_find_node_by_phandle(phandle)) && ((part =
- of_get_property(mtd_np, "label", NULL)) || (part =
- mtd_np->name)) && (the_mtd = get_mtd_device_nm(part))
- != ERR_PTR(-ENODEV)) {
+ if (!of_find_property(np,"ath,arv-ath5k-fix",NULL)) {
+
+ list = of_get_property(np, "ath,eep-flash", &i);
+ if (!list || (i != (2 * sizeof(*list)))) {
+ dev_err(&pdev->dev, "failed to find ath,eep-flash\n");
+ return -ENODEV;
+ }
+
+ phandle = be32_to_cpup(list++);
+ if (!phandle) {
+ dev_err(&pdev->dev, "failed to find phandle\n");
+ return -ENODEV;
+ }
+
+ mtd_np = of_find_node_by_phandle(phandle);
+ if (!mtd_np) {
+ dev_err(&pdev->dev, "failed to find mtd node\n");
+ return -ENODEV;
+ }
+
+ part = of_get_property(mtd_np, "label", NULL);
+ if (!part)
+ part = mtd_np->name;
+
+ the_mtd = get_mtd_device_nm(part);
+ if (the_mtd == ERR_PTR(-ENODEV)) {
+ dev_err(&pdev->dev, "failed to find mtd device\n");
+ return -ENODEV;
+ }
+
i = mtd_read(the_mtd, be32_to_cpup(list),
- ATH5K_PLAT_EEP_MAX_WORDS << 1, &flash_readlen,
- (void *) ath5k_pdata.eeprom_data);
+ ATH5K_PLAT_EEP_MAX_WORDS << 1, &flash_readlen,
+ (void *) ath5k_pdata.eeprom_data);
put_mtd_device(the_mtd);
- if ((sizeof(ATH5K_PLAT_EEP_MAX_WORDS << 1) != flash_readlen)
- || i) {
+ if ((sizeof(ath5k_pdata.eeprom_data) != flash_readlen) || i) {
dev_err(&pdev->dev, "failed to load eeprom from mtd\n");
return -ENODEV;
}
+
+ if (of_find_property(np, "ath,eep-swap", NULL))
+ for (i = 0; i < ATH5K_PLAT_EEP_MAX_WORDS; i++)
+ ath5k_pdata.eeprom_data[i] = swab16(ath5k_pdata.eeprom_data[i]);
+
+ if (!of_property_read_u32(np, "ath,mac-offset", &mac_offset)) {
+ memcpy_fromio(athxk_eeprom_mac, (void*) ath5k_pdata.eeprom_data + mac_offset, 6);
+ } else {
+ random_ether_addr(athxk_eeprom_mac);
+ if (of_get_mac_address_mtd(np, athxk_eeprom_mac))
+ dev_warn(&pdev->dev, "using random mac\n");
+ }
+
+ if (!of_property_read_u32(np, "ath,mac-increment", &mac_inc))
+ athxk_eeprom_mac[5] += mac_inc;
+
+ ath5k_pdata.macaddr = athxk_eeprom_mac;
+ ltq_pci_plat_dev_init = ath5k_pci_plat_dev_init;
} else {
+ // Noltari patch for ath5k arv4518pw. Applicable for other ath5k lantiqs.
+
eep_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mac_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ dev_info(&pdev->dev,"eeprom expected size : %u\n",ATH5K_PLAT_EEP_MAX_WORDS<<1);
+ dev_info(&pdev->dev,"mac expected size : %u\n",6);
+ dev_info(&pdev->dev,"eeprom read size : %u\n",resource_size(eep_res));
+ dev_info(&pdev->dev,"mac address size : %u\n",resource_size(mac_res));
+
if (!eep_res) {
- dev_err(&pdev->dev, "failed to load eeprom address\n");
+ dev_err(&pdev->dev, "failed to load eeprom addres\n");
return -ENODEV;
}
- if (resource_size(eep_res) != ATH5K_PLAT_EEP_MAX_WORDS << 1) {
- dev_err(&pdev->dev, "eeprom has an invalid size\n");
+
+ if (resource_size(eep_res) != ATH5K_PLAT_EEP_MAX_WORDS<<1) {
+ dev_err(&pdev->dev, "eeprom size mismatch\n");
return -EINVAL;
}
eep = ioremap(eep_res->start, resource_size(eep_res));
- ath5k_pdata.eeprom_data = kmalloc(ATH5K_PLAT_EEP_MAX_WORDS<<1,
- GFP_KERNEL);
- memcpy_fromio(ath5k_pdata.eeprom_data, eep,
- ATH5K_PLAT_EEP_MAX_WORDS << 1);
- }
- if (of_find_property(np, "ath,eep-swap", NULL))
- for (i = 0; i < ATH5K_PLAT_EEP_MAX_WORDS; i++)
- ath5k_pdata.eeprom_data[i] = swab16(ath5k_pdata.eeprom_data[i]);
+ ath5k_pdata.eeprom_data=kmalloc(ATH5K_PLAT_EEP_MAX_WORDS<<1,GFP_KERNEL);
+ memcpy_fromio(ath5k_pdata.eeprom_data, eep,ATH5K_PLAT_EEP_MAX_WORDS<<1);
- if (!of_property_read_u32(np, "ath,mac-offset", &mac_offset)) {
- memcpy_fromio(athxk_eeprom_mac, (void*) ath5k_pdata.eeprom_data + mac_offset, 6);
- } else if (mac_res) {
- if (resource_size(mac_res) != 6) {
- dev_err(&pdev->dev, "mac has an invalid size\n");
- return -EINVAL;
+ if (of_find_property(np, "ath,eep-swap",NULL)) {
+ for (i=0; i<ATH5K_PLAT_EEP_MAX_WORDS; i++)
+ ath5k_pdata.eeprom_data[i]=swab16(ath5k_pdata.eeprom_data[i]);
}
- mac = ioremap(mac_res->start, resource_size(mac_res));
- memcpy_fromio(athxk_eeprom_mac, mac, 6);
- } else if (ltq_get_eth_mac())
- memcpy(athxk_eeprom_mac, ltq_get_eth_mac(), 6);
- else {
- dev_warn(&pdev->dev, "using random mac\n");
- random_ether_addr(athxk_eeprom_mac);
- }
- if (!of_property_read_u32(np, "ath,mac-increment", &mac_inc))
- athxk_eeprom_mac[5] += mac_inc;
+ if (of_find_property(np, "ath,eep-csum", NULL)) {
+ sum=ath5k_pdata.eeprom_data[0x200>>1];
+ el=sum/sizeof(u16)-2; // skip length and old cheksum
+ eepdata=(u16 *)(&ath5k_pdata.eeprom_data[0x204>>1]); // after cheksum
+ for (i=0; i<el; i++)
+ sum^=*eepdata++;
+ sum^=0xffff;
+ ath5k_pdata.eeprom_data[0x202>>1]=sum;
+ dev_info(&pdev->dev,"checksum fixed.\n");
+ }
- ath5k_pdata.macaddr = athxk_eeprom_mac;
- ltq_pci_plat_dev_init = ath5k_pci_plat_dev_init;
+ if (!of_property_read_u32(np,"ath,mac-offset",&mac_offset)) {
+ memcpy_fromio(athxk_eeprom_mac, (void*) ath5k_pdata.eeprom_data +mac_offset, 6);
+ } else {
+ if (mac_res) {
+ if (resource_size(mac_res)!=6) {
+ dev_err(&pdev->dev, "mac has an invalid size.\n");
+ return -EINVAL;
+ }
+ dev_info(&pdev->dev,"loading MAC.\n");
+ mac=ioremap(mac_res->start, resource_size(mac_res));
+ memcpy_fromio(athxk_eeprom_mac, mac, 6);
+ dev_info(&pdev->dev,"loaded MAC.\n");
+ } else {
+ dev_warn(&pdev->dev,"using random mac.\n");
+ random_ether_addr(athxk_eeprom_mac);
+ }
+ }
+
+ if (!of_property_read_u32(np, "ath,mac-increment", &mac_inc))
+ athxk_eeprom_mac[5]+=mac_inc;
+
+ ath5k_pdata.macaddr=athxk_eeprom_mac;
+ ltq_pci_plat_dev_init=ath5k_pci_plat_dev_init;
+
+ if (!of_property_read_u32(np,"ath,pci-slot", &pci_slot)) {
+ ltq_pci_ath_fixup(pci_slot, ath5k_pdata.eeprom_data);
+ dev_info(&pdev->dev,"pci slot: %u.\n",pci_slot);
+ }
+ dev_info(&pdev->dev,"eeprom init finished.\n");
+ }
dev_info(&pdev->dev, "loaded ath5k eeprom\n");
@@ -279,4 +339,6 @@ static int __init of_ath5k_eeprom_init(v
{
return platform_driver_probe(&ath5k_eeprom_driver, of_ath5k_eeprom_probe);
}
-device_initcall(of_ath5k_eeprom_init);
+
+subsys_initcall(of_ath5k_eeprom_init);
+