diff --git a/target/linux/lantiq/files-3.2/arch/mips/lantiq/xway/dev-wifi-ath5k.c b/target/linux/lantiq/files-3.2/arch/mips/lantiq/xway/dev-wifi-athxk.c similarity index 63% rename from target/linux/lantiq/files-3.2/arch/mips/lantiq/xway/dev-wifi-ath5k.c rename to target/linux/lantiq/files-3.2/arch/mips/lantiq/xway/dev-wifi-athxk.c index 14fd5113d..882cd8cf7 100644 --- a/target/linux/lantiq/files-3.2/arch/mips/lantiq/xway/dev-wifi-ath5k.c +++ b/target/linux/lantiq/files-3.2/arch/mips/lantiq/xway/dev-wifi-athxk.c @@ -10,20 +10,31 @@ #include #include #include +#include #include -#include "dev-wifi-ath5k.h" +#include "dev-wifi-athxk.h" extern int (*ltqpci_plat_dev_init)(struct pci_dev *dev); struct ath5k_platform_data ath5k_pdata; +struct ath9k_platform_data ath9k_pdata = { + .led_pin = -1, +}; -static int +static int ath5k_pci_plat_dev_init(struct pci_dev *dev) { dev->dev.platform_data = &ath5k_pdata; return 0; } +static int +ath9k_pci_plat_dev_init(struct pci_dev *dev) +{ + dev->dev.platform_data = &ath9k_pdata; + return 0; +} + void __init ltq_register_ath5k(u16 *eeprom_data, u8 *macaddr) { @@ -31,3 +42,11 @@ ltq_register_ath5k(u16 *eeprom_data, u8 *macaddr) ath5k_pdata.macaddr = macaddr; ltqpci_plat_dev_init = ath5k_pci_plat_dev_init; } + +void __init +ltq_register_ath9k(u16 *eeprom_data, u8 *macaddr) +{ + memcpy(ath9k_pdata.eeprom_data, eeprom_data, sizeof(ath9k_pdata.eeprom_data)); + ath9k_pdata.macaddr = macaddr; + ltqpci_plat_dev_init = ath9k_pci_plat_dev_init; +} diff --git a/target/linux/lantiq/files-3.2/arch/mips/lantiq/xway/dev-wifi-ath5k.h b/target/linux/lantiq/files-3.2/arch/mips/lantiq/xway/dev-wifi-athxk.h similarity index 76% rename from target/linux/lantiq/files-3.2/arch/mips/lantiq/xway/dev-wifi-ath5k.h rename to target/linux/lantiq/files-3.2/arch/mips/lantiq/xway/dev-wifi-athxk.h index 37f6e411f..5fdb46b61 100644 --- a/target/linux/lantiq/files-3.2/arch/mips/lantiq/xway/dev-wifi-ath5k.h +++ b/target/linux/lantiq/files-3.2/arch/mips/lantiq/xway/dev-wifi-athxk.h @@ -7,9 +7,10 @@ * by the Free Software Foundation. */ -#ifndef _DEV_WIFI_ATH5K_H__ -#define _DEV_WIFI_ATH5K_H__ +#ifndef _DEV_WIFI_ATHXK_H__ +#define _DEV_WIFI_ATHXK_H__ extern void ltq_register_ath5k(u16 *eeprom_data, u8 *macaddr); +extern void ltq_register_ath9k(u16 *eeprom_data, u8 *macaddr); #endif diff --git a/target/linux/lantiq/files-3.2/arch/mips/lantiq/xway/pci-ath-fixup.c b/target/linux/lantiq/files-3.2/arch/mips/lantiq/xway/pci-ath-fixup.c new file mode 100644 index 000000000..c87ffb209 --- /dev/null +++ b/target/linux/lantiq/files-3.2/arch/mips/lantiq/xway/pci-ath-fixup.c @@ -0,0 +1,109 @@ +/* + * Atheros AP94 reference board PCI initialization + * + * Copyright (C) 2009-2010 Gabor Juhos + * + * 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 +#include +#include +#include + +#define LTQ_PCI_MEM_BASE 0x18000000 + +struct ath_fixup { + u16 *cal_data; + unsigned slot; +}; + +static int ath_num_fixups; +static struct ath_fixup ath_fixups[2]; + +static void ath_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 < ath_num_fixups; i++) { + if (ath_fixups[i].cal_data == NULL) + continue; + + if (ath_fixups[i].slot != PCI_SLOT(dev->devfn)) + continue; + + cal_data = ath_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; + + ltq_w32(swab32(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 */ + + pr_info("pci %s: fixup info: [%04x:%04x] revision %02x class %#08x\n", + pci_name(dev), dev->vendor, dev->device, dev->revision, dev->class); + + 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, ath_pci_fixup); + +void __init ltq_pci_ath_fixup(unsigned slot, u16 *cal_data) +{ + if (ath_num_fixups >= ARRAY_SIZE(ath_fixups)) + return; + + ath_fixups[ath_num_fixups].slot = slot; + ath_fixups[ath_num_fixups].cal_data = cal_data; + ath_num_fixups++; +} diff --git a/target/linux/lantiq/files-3.2/arch/mips/lantiq/xway/pci-ath-fixup.h b/target/linux/lantiq/files-3.2/arch/mips/lantiq/xway/pci-ath-fixup.h new file mode 100644 index 000000000..095d2619c --- /dev/null +++ b/target/linux/lantiq/files-3.2/arch/mips/lantiq/xway/pci-ath-fixup.h @@ -0,0 +1,6 @@ +#ifndef _PCI_ATH_FIXUP +#define _PCI_ATH_FIXUP + +void ltq_pci_ath_fixup(unsigned slot, u16 *cal_data) __init; + +#endif /* _PCI_ATH_FIXUP */