The following patch adds ath9k support to the arv7518 board.

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/arch/mips/ar71xx/pci-ath9k-fixup.c
https://dev.openwrt.org/browser/trunk/target/linux/ar71xx/files/arch/mips/ar71xx/pci-ath9k-fixup.h

with a couple of changes.

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.

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

--- 

Index: target/linux/lantiq/image/Makefile
===================================================================
--- target/linux/lantiq/image/Makefile  (revisión: 26437)
+++ target/linux/lantiq/image/Makefile  (copia de trabajo)
@@ -9,7 +9,7 @@
 
 JFFS2_BLOCKSIZE = 64k 128k 256k
 
-xway_cmdline=-console=ttyS1,115200 rootfstype=squashfs,jffs2
+xway_cmdline=console=ttyS1,115200 rootfstype=squashfs,jffs2
 falcon_cmdline=-console=ttyS0,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,257 @@
+--- a/arch/mips/lantiq/xway/Kconfig
++++ b/arch/mips/lantiq/xway/Kconfig
+@@ -16,8 +16,12 @@ config LANTIQ_MACH_EASY4010
+ 
+ config LANTIQ_MACH_ARV45XX
+       bool "ARV45XX"
++      select LANTIQ_PCI_ATH9K_FIXUP
+       default y
+ 
+ endmenu
+ 
++config LANTIQ_PCI_ATH9K_FIXUP
++      def_bool n
++
+ endif
+--- a/arch/mips/lantiq/xway/Makefile
++++ b/arch/mips/lantiq/xway/Makefile
+@@ -4,4 +4,5 @@ obj-$(CONFIG_LANTIQ_MACH_EASY50812) += m
+ obj-$(CONFIG_LANTIQ_MACH_EASY50712) += mach-easy50712.o
+ obj-$(CONFIG_LANTIQ_MACH_EASY4010) += mach-easy4010.o
+ obj-$(CONFIG_LANTIQ_MACH_ARV45XX) += mach-arv45xx.o
++obj-$(CONFIG_LANTIQ_PCI_ATH9K_FIXUP) += pci-ath9k-fixup.o
+ obj-y += dev-dwc_otg.o
+--- /dev/null
++++ b/arch/mips/lantiq/xway/pci-ath9k-fixup.c
+@@ -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 LQ_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(LQ_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, LQ_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++;
++}
+--- /dev/null
++++ b/arch/mips/lantiq/xway/pci-ath9k-fixup.h
+@@ -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 */
+--- a/arch/mips/lantiq/xway/mach-arv45xx.c
++++ b/arch/mips/lantiq/xway/mach-arv45xx.c
+@@ -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 <machine.h>
+@@ -26,6 +27,7 @@
+ 
+ #include "devices.h"
+ #include "dev-dwc_otg.h"
++#include "pci-ath9k-fixup.h"
+ 
+ #ifdef CONFIG_MTD_PARTITIONS
+ static struct mtd_partition arv4510_partitions[] =
+@@ -318,6 +320,49 @@ arv45xx_register_ath5k(void)
+       lqpci_plat_dev_init = arv45xx_pci_plat_dev_init;
+ }
+ 
++static struct ath9k_platform_data arv75xx_ath9k_platform_data = {
++      .led_pin = -1,
++      .check_endianness = 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(LQ_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;
++      lqpci_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)
+ {
+@@ -479,6 +524,24 @@ MIPS_MACHINE(LANTIQ_MACH_ARV4525PW,
+                       "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
+ arv7518pw_init(void)
+ {
+@@ -497,7 +560,7 @@ arv7518pw_init(void)
+       lq_register_tapi();
+       xway_register_dwc(ARV7518PW_USB);
+       arv75xx_register_ethernet();
+-      //arv7518_register_ath9k(mac);
++      arv75xx_register_ath9k(lq_eth_data.mac, ath9k_regdomain, ath9k_caps);
+ }
+ 
+ MIPS_MACHINE(LANTIQ_MACH_ARV7518PW,
+--- a/include/linux/ath9k_platform.h
++++ b/include/linux/ath9k_platform.h
+@@ -23,6 +23,12 @@
+ 
+ struct ath9k_platform_data {
+       u16 eeprom_data[ATH9K_PLAT_EEP_MAX_WORDS];
++      u8 *macaddr;
++
++      int led_pin;
++      u32 gpio_mask;
++      u32 gpio_val;
++      int check_endianness;
+ };
+ 
+ #endif /* _LINUX_ATH9K_PLATFORM_H */


_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to