Root/target/linux/brcm63xx/patches-3.6/435-BCM63XX-add-a-fixup-for-ath9k-devices.patch

1From fb6f6f58db9ae9cf27ab01f5f09cfbc5c078a7b8 Mon Sep 17 00:00:00 2001
2From: Jonas Gorski <jonas.gorski@gmail.com>
3Date: Thu, 3 May 2012 14:36:11 +0200
4Subject: [PATCH 66/80] BCM63XX: add a fixup for ath9k devices
5
6---
7 arch/mips/bcm63xx/Makefile | 2 +-
8 arch/mips/bcm63xx/pci-ath9k-fixup.c | 190 ++++++++++++++++++++
9 .../include/asm/mach-bcm63xx/pci_ath9k_fixup.h | 7 +
10 3 files changed, 198 insertions(+), 1 deletion(-)
11 create mode 100644 arch/mips/bcm63xx/pci-ath9k-fixup.c
12 create mode 100644 arch/mips/include/asm/mach-bcm63xx/pci_ath9k_fixup.h
13
14--- a/arch/mips/bcm63xx/Makefile
15+++ b/arch/mips/bcm63xx/Makefile
16@@ -1,7 +1,7 @@
17 obj-y += clk.o cpu.o cs.o gpio.o irq.o nvram.o prom.o setup.o \
18            timer.o dev-dsp.o dev-enet.o dev-flash.o dev-hsspi.o \
19            dev-pcmcia.o dev-rng.o dev-spi.o dev-uart.o dev-usb-ehci.o \
20- dev-usb-ohci.o dev-wdt.o
21+ dev-usb-ohci.o dev-wdt.o pci-ath9k-fixup.o
22 obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
23 
24 obj-y += boards/
25--- /dev/null
26+++ b/arch/mips/bcm63xx/pci-ath9k-fixup.c
27@@ -0,0 +1,190 @@
28+/*
29+ * Broadcom BCM63XX Ath9k EEPROM fixup helper.
30+ *
31+ * Copytight (C) 2012 Jonas Gorski <jonas.gorski@gmail.com>
32+ *
33+ * Based on
34+ *
35+ * Atheros AP94 reference board PCI initialization
36+ *
37+ * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
38+ *
39+ * This program is free software; you can redistribute it and/or modify it
40+ * under the terms of the GNU General Public License version 2 as published
41+ * by the Free Software Foundation.
42+ */
43+
44+#include <linux/pci.h>
45+#include <linux/delay.h>
46+#include <linux/ath9k_platform.h>
47+
48+#include <bcm63xx_cpu.h>
49+#include <bcm63xx_io.h>
50+#include <bcm63xx_nvram.h>
51+#include <bcm63xx_dev_pci.h>
52+#include <bcm63xx_dev_flash.h>
53+#include <bcm63xx_dev_hsspi.h>
54+#include <pci_ath9k_fixup.h>
55+
56+struct ath9k_fixup {
57+ unsigned slot;
58+ u8 mac[ETH_ALEN];
59+ struct ath9k_platform_data pdata;
60+};
61+
62+static int ath9k_num_fixups;
63+static struct ath9k_fixup ath9k_fixups[2] = {
64+ {
65+ .slot = 255,
66+ .pdata = {
67+ .led_pin = -1,
68+ },
69+ },
70+ {
71+ .slot = 255,
72+ .pdata = {
73+ .led_pin = -1,
74+ },
75+ },
76+};
77+
78+static u16 *bcm63xx_read_eeprom(u16 *eeprom, u32 offset)
79+{
80+ u32 addr;
81+
82+ if (BCMCPU_IS_6328()) {
83+ addr = 0x18000000;
84+ } else {
85+ addr = bcm_mpi_readl(MPI_CSBASE_REG(0));
86+ addr &= MPI_CSBASE_BASE_MASK;
87+ }
88+
89+ switch (bcm63xx_attached_flash) {
90+ case BCM63XX_FLASH_TYPE_PARALLEL:
91+ memcpy(eeprom, (void *)KSEG1ADDR(addr + offset), ATH9K_PLAT_EEP_MAX_WORDS * sizeof(u16));
92+ return eeprom;
93+ case BCM63XX_FLASH_TYPE_SERIAL:
94+ /* the first megabyte is memory mapped */
95+ if (offset < 0x100000) {
96+ memcpy(eeprom, (void *)KSEG1ADDR(addr + offset), ATH9K_PLAT_EEP_MAX_WORDS * sizeof(u16));
97+ return eeprom;
98+ }
99+
100+ if (BCMCPU_IS_6328()) {
101+ /* we can change the memory mapped megabyte */
102+ bcm_hsspi_writel(offset & 0xf00000, 0x18);
103+ memcpy(eeprom, (void *)KSEG1ADDR(addr + (offset & 0xfffff)), ATH9K_PLAT_EEP_MAX_WORDS * sizeof(u16));
104+ bcm_hsspi_writel(0, 0x18);
105+ return eeprom;
106+ }
107+ /* can't do anything here without talking to the SPI controller. */
108+ case BCM63XX_FLASH_TYPE_NAND:
109+ default:
110+ return NULL;
111+ }
112+}
113+
114+static void ath9k_pci_fixup(struct pci_dev *dev)
115+{
116+ void __iomem *mem;
117+ struct ath9k_platform_data *pdata = NULL;
118+ u16 *cal_data = NULL;
119+ u16 cmd;
120+ u32 bar0;
121+ u32 val;
122+ unsigned i;
123+
124+ for (i = 0; i < ath9k_num_fixups; i++) {
125+ if (ath9k_fixups[i].slot != PCI_SLOT(dev->devfn))
126+ continue;
127+
128+ cal_data = ath9k_fixups[i].pdata.eeprom_data;
129+ pdata = &ath9k_fixups[i].pdata;
130+ break;
131+ }
132+
133+ if (cal_data == NULL)
134+ return;
135+
136+ if (*cal_data != 0xa55a) {
137+ pr_err("pci %s: invalid calibration data\n", pci_name(dev));
138+ return;
139+ }
140+
141+ pr_info("pci %s: fixup device configuration\n", pci_name(dev));
142+
143+ switch (bcm63xx_get_cpu_id()) {
144+ case BCM6328_CPU_ID:
145+ val = BCM_PCIE_MEM_BASE_PA;
146+ break;
147+ case BCM6348_CPU_ID:
148+ case BCM6358_CPU_ID:
149+ case BCM6368_CPU_ID:
150+ val = BCM_PCI_MEM_BASE_PA;
151+ break;
152+ default:
153+ BUG();
154+ }
155+
156+ mem = ioremap(val, 0x10000);
157+ if (!mem) {
158+ pr_err("pci %s: ioremap error\n", pci_name(dev));
159+ return;
160+ }
161+
162+ pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0);
163+ pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0);
164+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, val);
165+
166+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
167+ cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
168+ pci_write_config_word(dev, PCI_COMMAND, cmd);
169+
170+ /* set offset to first reg address */
171+ cal_data += 3;
172+ while(*cal_data != 0xffff) {
173+ u32 reg;
174+ reg = *cal_data++;
175+ val = *cal_data++;
176+ val |= (*cal_data++) << 16;
177+
178+ writel(val, mem + reg);
179+ udelay(100);
180+ }
181+
182+ pci_read_config_dword(dev, PCI_VENDOR_ID, &val);
183+ dev->vendor = val & 0xffff;
184+ dev->device = (val >> 16) & 0xffff;
185+
186+ pci_read_config_dword(dev, PCI_CLASS_REVISION, &val);
187+ dev->revision = val & 0xff;
188+ dev->class = val >> 8; /* upper 3 bytes */
189+
190+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
191+ cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
192+ pci_write_config_word(dev, PCI_COMMAND, cmd);
193+
194+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, bar0);
195+
196+ iounmap(mem);
197+
198+ dev->dev.platform_data = pdata;
199+}
200+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ath9k_pci_fixup);
201+
202+void __init pci_enable_ath9k_fixup(unsigned slot, u32 offset)
203+{
204+ if (ath9k_num_fixups >= ARRAY_SIZE(ath9k_fixups))
205+ return;
206+
207+ ath9k_fixups[ath9k_num_fixups].slot = slot;
208+
209+ if (!bcm63xx_read_eeprom(ath9k_fixups[ath9k_num_fixups].pdata.eeprom_data, offset))
210+ return;
211+
212+ if (bcm63xx_nvram_get_mac_address(ath9k_fixups[ath9k_num_fixups].mac))
213+ return;
214+
215+ ath9k_fixups[ath9k_num_fixups].pdata.macaddr = ath9k_fixups[ath9k_num_fixups].mac;
216+ ath9k_num_fixups++;
217+}
218--- /dev/null
219+++ b/arch/mips/include/asm/mach-bcm63xx/pci_ath9k_fixup.h
220@@ -0,0 +1,7 @@
221+#ifndef _PCI_ATH9K_FIXUP
222+#define _PCI_ATH9K_FIXUP
223+
224+
225+void pci_enable_ath9k_fixup(unsigned slot, u32 offset) __init;
226+
227+#endif /* _PCI_ATH9K_FIXUP */
228

Archive Download this file



interactive