The following patch adds ath9k support to the arv7518 board.

It supersedes 
http://patchwork.openwrt.org/patch/849/
http://patchwork.openwrt.org/patch/1169/
(there are no modifications in the code but the patch bitrotted since then).
The pci fixup routine (needed since the ar9223 has no onboard
eeprom) is taken from the ar71xx:

https://dev.openwrt.org/browser/trunk/target/linux/ar71xx/files-3.2/arch/mips/ath79/pci-ath9k-fixup.c
https://dev.openwrt.org/browser/trunk/target/linux/ar71xx/files-3.2/arch/mips/ath79/pci-ath9k-fixup.h

with a couple of changes (removed the switch on the soc, added a "cpu_to_le32" 
in the call to __raw_writel).

As I said, the ar9223 has no onboard eeprom, so it uses the system
flash, which holds the fixup data as well as the calibration data,
however the regdomain in the system flash is set at 0, and it will
setup the card to the most restrictive mode (i.e. channels 12 and 
13 aren't available).
The original firmware overrides the regdomain and the device capabilities
(I suppose that arcadyan uses the same caldata all over the world and then
customizes the firmware instead of properly set the regdomain).
The patch does the same only if in the kernel command line the parameter
"ath9k_regdomain" and/or "ath9k_caps" are specified, hence the
xway_cmdline parameter in image/Makefile has to be changed not
to clobber the command line set in u-boot.

It also modifies ath9k in mac80211 to unconditionally check (and fix) the 
endianness of the emulated eeprom.
To be on the safe side this modification (the last hunk of the patch) should be 
applied only for this device (I don't think it should cause any harm anyway) 
but I don't know how to do it. 

While at the time of the previous patches I only got 5Mbps, now I get 25Mbps 
with no encryption and 23Mbps with wpa-psk2.
I did not change anything in the fixup code, so the difference in performance 
is either due to changes in mac80211 or in my methodology to measure it (then I 
used wget with the router in station mode, now I used iperf with the router in 
ap mode).

Signed-off-by: Luca Olivetti <l...@ventoso.org>

--- 

Index: target/linux/lantiq/image/Makefile
===================================================================
--- target/linux/lantiq/image/Makefile  (revisión: 29937)
+++ target/linux/lantiq/image/Makefile  (copia de trabajo)
@@ -10,7 +10,7 @@
 JFFS2_BLOCKSIZE = 64k 128k 256k
 
 ase_cmdline=-console=ttyLTQ0,115200 rootfstype=squashfs,jffs2
-xway_cmdline=-console=ttyLTQ1,115200 rootfstype=squashfs,jffs2
+xway_cmdline=console=ttyLTQ1,115200 rootfstype=squashfs,jffs2
 falcon_cmdline=-console=ttyLTQ0,115200 rootfstype=squashfs,jffs2
 
 define CompressLzma
Index: target/linux/lantiq/patches/750-arv75xx-ath9k.patch
===================================================================
--- target/linux/lantiq/patches/750-arv75xx-ath9k.patch (revisión: 0)
+++ target/linux/lantiq/patches/750-arv75xx-ath9k.patch (revisión: 0)
@@ -0,0 +1,28 @@
+--- a/arch/mips/lantiq/xway/Kconfig
++++ b/arch/mips/lantiq/xway/Kconfig
+@@ -8,6 +8,7 @@ config LANTIQ_MACH_EASY50712
+ 
+ config LANTIQ_MACH_ARV45XX
+       bool "ARV45XX"
++      select LANTIQ_PCI_ATH9K_FIXUP
+       default y
+ 
+ config LANTIQ_MACH_NETGEAR
+@@ -24,6 +25,9 @@ config LANTIQ_MACH_WBMR
+ 
+ endmenu
+ 
++config LANTIQ_PCI_ATH9K_FIXUP
++      def_bool n
++
+ endif
+ 
+ if SOC_AMAZON_SE
+--- a/arch/mips/lantiq/xway/Makefile
++++ b/arch/mips/lantiq/xway/Makefile
+@@ -12,4 +12,5 @@ obj-$(CONFIG_LANTIQ_MACH_FRITZ3370) += m
+ obj-$(CONFIG_LANTIQ_MACH_ARV45XX) += mach-arv45xx.o
+ obj-$(CONFIG_LANTIQ_MACH_NETGEAR) += mach-netgear.o
+ obj-$(CONFIG_LANTIQ_MACH_GIGASX76X) += mach-gigasx76x.o
++obj-$(CONFIG_LANTIQ_PCI_ATH9K_FIXUP) += pci-ath9k-fixup.o
+ obj-$(CONFIG_LANTIQ_MACH_WBMR) += mach-wbmr.o
Index: target/linux/lantiq/files-3.1/arch/mips/lantiq/xway/pci-ath9k-fixup.c
===================================================================
--- target/linux/lantiq/files-3.1/arch/mips/lantiq/xway/pci-ath9k-fixup.c       
(revisión: 0)
+++ target/linux/lantiq/files-3.1/arch/mips/lantiq/xway/pci-ath9k-fixup.c       
(revisión: 0)
@@ -0,0 +1,105 @@
+/*
+ *  Adapted from: Atheros AP94 reference board PCI initialization
+ *
+ *  Copyright (C) 2009-2010 Gabor Juhos <juh...@openwrt.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/pci.h>
+#include <linux/delay.h>
+
+/* this is ugly but this constant isn't available in an header file */
+#define LTQ_PCI_MEM_BASE               0x18000000
+
+struct ath9k_fixup {
+       u16             *cal_data;
+       unsigned        slot;
+};
+
+static int ath9k_num_fixups;
+static struct ath9k_fixup ath9k_fixups[2];
+
+static void ath9k_pci_fixup(struct pci_dev *dev)
+{
+       void __iomem *mem;
+       u16 *cal_data = NULL;
+       u16 cmd;
+       u32 bar0;
+       u32 val;
+       unsigned i;
+
+       for (i = 0; i < ath9k_num_fixups; i++) {
+               if (ath9k_fixups[i].cal_data == NULL)
+                       continue;
+
+               if (ath9k_fixups[i].slot != PCI_SLOT(dev->devfn))
+                       continue;
+
+               cal_data = ath9k_fixups[i].cal_data;
+               break;
+       }
+
+       if (cal_data == NULL)
+               return;
+
+       if (*cal_data != 0xa55a) {
+               pr_err("pci %s: invalid calibration data\n", pci_name(dev));
+               return;
+       }
+
+       pr_info("pci %s: fixup device configuration\n", pci_name(dev));
+
+       mem = ioremap(LTQ_PCI_MEM_BASE, 0x10000);
+       if (!mem) {
+               pr_err("pci %s: ioremap error\n", pci_name(dev));
+               return;
+       }
+
+       pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0);
+       pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, LTQ_PCI_MEM_BASE);
+       pci_read_config_word(dev, PCI_COMMAND, &cmd);
+       cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+       pci_write_config_word(dev, PCI_COMMAND, cmd);
+
+       /* set pointer to first reg address */
+       cal_data += 3;
+       while (*cal_data != 0xffff) {
+               u32 reg;
+               reg = *cal_data++;
+               val = *cal_data++;
+               val |= (*cal_data++) << 16;
+
+               __raw_writel(cpu_to_le32(val), mem + reg);
+               udelay(100);
+       }
+
+       pci_read_config_dword(dev, PCI_VENDOR_ID, &val);
+       dev->vendor = val & 0xffff;
+       dev->device = (val >> 16) & 0xffff;
+
+       pci_read_config_dword(dev, PCI_CLASS_REVISION, &val);
+       dev->revision = val & 0xff;
+       dev->class = val >> 8; /* upper 3 bytes */
+
+       pci_read_config_word(dev, PCI_COMMAND, &cmd);
+       cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
+       pci_write_config_word(dev, PCI_COMMAND, cmd);
+
+       pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, bar0);
+
+       iounmap(mem);
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ath9k_pci_fixup);
+
+void __init pci_enable_ath9k_fixup(unsigned slot, u16 *cal_data)
+{
+       if (ath9k_num_fixups >= ARRAY_SIZE(ath9k_fixups))
+               return;
+
+       ath9k_fixups[ath9k_num_fixups].slot = slot;
+       ath9k_fixups[ath9k_num_fixups].cal_data = cal_data;
+       ath9k_num_fixups++;
+}

Cambios de propiedades en 
target/linux/lantiq/files-3.1/arch/mips/lantiq/xway/pci-ath9k-fixup.c
___________________________________________________________________
Añadido: svn:eol-style
   + native

Index: target/linux/lantiq/files-3.1/arch/mips/lantiq/xway/pci-ath9k-fixup.h
===================================================================
--- target/linux/lantiq/files-3.1/arch/mips/lantiq/xway/pci-ath9k-fixup.h       
(revisión: 0)
+++ target/linux/lantiq/files-3.1/arch/mips/lantiq/xway/pci-ath9k-fixup.h       
(revisión: 0)
@@ -0,0 +1,6 @@
+#ifndef _PCI_ATH9K_FIXUP
+#define _PCI_ATH9K_FIXUP
+
+void pci_enable_ath9k_fixup(unsigned slot, u16 *cal_data) __init;
+
+#endif /* _PCI_ATH9K_FIXUP */

Cambios de propiedades en 
target/linux/lantiq/files-3.1/arch/mips/lantiq/xway/pci-ath9k-fixup.h
___________________________________________________________________
Añadido: svn:eol-style
   + native

Index: target/linux/lantiq/files-3.1/arch/mips/lantiq/xway/mach-arv45xx.c
===================================================================
--- target/linux/lantiq/files-3.1/arch/mips/lantiq/xway/mach-arv45xx.c  
(revisión: 29891)
+++ target/linux/lantiq/files-3.1/arch/mips/lantiq/xway/mach-arv45xx.c  (copia 
de trabajo)
@@ -17,6 +17,7 @@
 #include <linux/input.h>
 #include <linux/etherdevice.h>
 #include <linux/ath5k_platform.h>
+#include <linux/ath9k_platform.h>
 #include <linux/pci.h>
 
 #include <lantiq_soc.h>
@@ -29,7 +30,10 @@
 #include "dev-wifi-ath5k.h"
 #include "devices.h"
 #include "dev-dwc_otg.h"
+#include "pci-ath9k-fixup.h"
 
+extern int (*ltqpci_plat_dev_init)(struct pci_dev *dev);
+
 static struct mtd_partition arv4510_partitions[] =
 {
        {
@@ -398,6 +402,48 @@
        }
 }
 
+static struct ath9k_platform_data arv75xx_ath9k_platform_data = {
+       .led_pin = -1,
+};
+
+static int arv75xx_pci_plat_dev_init(struct pci_dev *dev)
+{
+       dev->dev.platform_data = &arv75xx_ath9k_platform_data;
+       return 0;
+}
+
+void __init
+arv75xx_register_ath9k(unsigned char *mac, u16 regdomain, u16 caps)
+{
+#define ARV75XX_BRN_ATH                0xa07f0400
+       int i;
+       u16 *eepdata, sum, el;
+
+       memcpy_fromio(arv75xx_ath9k_platform_data.eeprom_data,
+               (void *)KSEG1ADDR(LTQ_FLASH_START + ARV75XX_BRN_ATH 
),sizeof(arv75xx_ath9k_platform_data.eeprom_data));
+       if (regdomain) {
+               arv75xx_ath9k_platform_data.eeprom_data[0x208>>1]=regdomain;
+               printk("changed ath9k regdomain to 0x%x\n", regdomain);
+       }
+       if (caps) {
+               arv75xx_ath9k_platform_data.eeprom_data[0x20a>>1]=caps;
+               printk("changed ath9k caps to 0x%x\n", caps);
+       }
+       if (regdomain | caps) {
+               /* recalc checksum for new regdomain */
+               sum = arv75xx_ath9k_platform_data.eeprom_data[0x200>>1];
+               el = sum / sizeof(u16) - 2;  /* skip length and (old) checksum 
*/
+               eepdata = (u16 *) 
(&arv75xx_ath9k_platform_data.eeprom_data[0x204>>1]); /* after checksum */
+               for (i = 0; i < el; i++)
+                       sum ^= *eepdata++;
+               sum ^= 0xffff;
+               arv75xx_ath9k_platform_data.eeprom_data[0x202>>1]=sum;
+       }
+       arv75xx_ath9k_platform_data.macaddr = mac;
+       ltqpci_plat_dev_init = arv75xx_pci_plat_dev_init;
+       pci_enable_ath9k_fixup(14, arv75xx_ath9k_platform_data.eeprom_data);
+}
+
 static void __init
 arv3527p_init(void)
 {
@@ -540,6 +586,24 @@
                        "ARV4525PW - Speedport W502V",
                        arv4525pw_init);
 
+static int ath9k_regdomain;
+static int __init
+ath9k_regdomain_setup(char *str)
+{
+       ath9k_regdomain = simple_strtoul(str, NULL, 0);
+       return 1;
+}
+__setup("ath9k_regdomain=", ath9k_regdomain_setup);
+
+static u16 ath9k_caps;
+static int __init
+ath9k_caps_setup(char *str)
+{
+       ath9k_caps = simple_strtoul(str, NULL, 0);
+       return 1;
+}
+__setup("ath9k_caps=", ath9k_caps_setup);
+
 static void __init
 arv7525pw_init(void)
 {
@@ -577,7 +641,7 @@
        ltq_register_tapi();
        xway_register_dwc(ARV7518PW_USB);
        arv75xx_register_ethernet();
-       //arv7518_register_ath9k(mac);
+       arv75xx_register_ath9k(ltq_eth_data.mac.sa_data, ath9k_regdomain, 
ath9k_caps);
 }
 
 MIPS_MACHINE(LANTIQ_MACH_ARV7518PW,
Index: package/mac80211/patches/412-ath9k-force-check-endianness.patch
===================================================================
--- package/mac80211/patches/412-ath9k-force-check-endianness.patch     
(revisión: 0)
+++ package/mac80211/patches/412-ath9k-force-check-endianness.patch     
(revisión: 0)
@@ -0,0 +1,11 @@
+--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c      2011-02-08 
17:33:42.000000000 +0100
++++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c      2011-02-20 
17:51:47.000000000 +0100
+@@ -147,7 +152,7 @@
+               return false;
+       }
+ 
+-      if (!ath9k_hw_use_flash(ah)) {
++      if (1) {
+               ath_dbg(common, ATH_DBG_EEPROM,
+                       "Read Magic = 0x%04X\n", magic);
+ 
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to