pci.c revision e79c1ba84c68de9161d541bd2bcc8ea65c89955c
1/*
2 * Sonics Silicon Backplane PCI-Hostbus related functions.
3 *
4 * Copyright (C) 2005-2006 Michael Buesch <mb@bu3sch.de>
5 * Copyright (C) 2005 Martin Langer <martin-langer@gmx.de>
6 * Copyright (C) 2005 Stefano Brivio <st3@riseup.net>
7 * Copyright (C) 2005 Danny van Dyk <kugelfang@gentoo.org>
8 * Copyright (C) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
9 *
10 * Derived from the Broadcom 4400 device driver.
11 * Copyright (C) 2002 David S. Miller (davem@redhat.com)
12 * Fixed by Pekka Pietikainen (pp@ee.oulu.fi)
13 * Copyright (C) 2006 Broadcom Corporation.
14 *
15 * Licensed under the GNU/GPL. See COPYING for details.
16 */
17
18#include <linux/ssb/ssb.h>
19#include <linux/ssb/ssb_regs.h>
20#include <linux/pci.h>
21#include <linux/delay.h>
22
23#include "ssb_private.h"
24
25
26/* Define the following to 1 to enable a printk on each coreswitch. */
27#define SSB_VERBOSE_PCICORESWITCH_DEBUG		0
28
29
30/* Lowlevel coreswitching */
31int ssb_pci_switch_coreidx(struct ssb_bus *bus, u8 coreidx)
32{
33	int err;
34	int attempts = 0;
35	u32 cur_core;
36
37	while (1) {
38		err = pci_write_config_dword(bus->host_pci, SSB_BAR0_WIN,
39					     (coreidx * SSB_CORE_SIZE)
40					     + SSB_ENUM_BASE);
41		if (err)
42			goto error;
43		err = pci_read_config_dword(bus->host_pci, SSB_BAR0_WIN,
44					    &cur_core);
45		if (err)
46			goto error;
47		cur_core = (cur_core - SSB_ENUM_BASE)
48			   / SSB_CORE_SIZE;
49		if (cur_core == coreidx)
50			break;
51
52		if (attempts++ > SSB_BAR0_MAX_RETRIES)
53			goto error;
54		udelay(10);
55	}
56	return 0;
57error:
58	ssb_printk(KERN_ERR PFX "Failed to switch to core %u\n", coreidx);
59	return -ENODEV;
60}
61
62int ssb_pci_switch_core(struct ssb_bus *bus,
63			struct ssb_device *dev)
64{
65	int err;
66	unsigned long flags;
67
68#if SSB_VERBOSE_PCICORESWITCH_DEBUG
69	ssb_printk(KERN_INFO PFX
70		   "Switching to %s core, index %d\n",
71		   ssb_core_name(dev->id.coreid),
72		   dev->core_index);
73#endif
74
75	spin_lock_irqsave(&bus->bar_lock, flags);
76	err = ssb_pci_switch_coreidx(bus, dev->core_index);
77	if (!err)
78		bus->mapped_device = dev;
79	spin_unlock_irqrestore(&bus->bar_lock, flags);
80
81	return err;
82}
83
84/* Enable/disable the on board crystal oscillator and/or PLL. */
85int ssb_pci_xtal(struct ssb_bus *bus, u32 what, int turn_on)
86{
87	int err;
88	u32 in, out, outenable;
89	u16 pci_status;
90
91	if (bus->bustype != SSB_BUSTYPE_PCI)
92		return 0;
93
94	err = pci_read_config_dword(bus->host_pci, SSB_GPIO_IN, &in);
95	if (err)
96		goto err_pci;
97	err = pci_read_config_dword(bus->host_pci, SSB_GPIO_OUT, &out);
98	if (err)
99		goto err_pci;
100	err = pci_read_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE, &outenable);
101	if (err)
102		goto err_pci;
103
104	outenable |= what;
105
106	if (turn_on) {
107		/* Avoid glitching the clock if GPRS is already using it.
108		 * We can't actually read the state of the PLLPD so we infer it
109		 * by the value of XTAL_PU which *is* readable via gpioin.
110		 */
111		if (!(in & SSB_GPIO_XTAL)) {
112			if (what & SSB_GPIO_XTAL) {
113				/* Turn the crystal on */
114				out |= SSB_GPIO_XTAL;
115				if (what & SSB_GPIO_PLL)
116					out |= SSB_GPIO_PLL;
117				err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out);
118				if (err)
119					goto err_pci;
120				err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE,
121							     outenable);
122				if (err)
123					goto err_pci;
124				msleep(1);
125			}
126			if (what & SSB_GPIO_PLL) {
127				/* Turn the PLL on */
128				out &= ~SSB_GPIO_PLL;
129				err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out);
130				if (err)
131					goto err_pci;
132				msleep(5);
133			}
134		}
135
136		err = pci_read_config_word(bus->host_pci, PCI_STATUS, &pci_status);
137		if (err)
138			goto err_pci;
139		pci_status &= ~PCI_STATUS_SIG_TARGET_ABORT;
140		err = pci_write_config_word(bus->host_pci, PCI_STATUS, pci_status);
141		if (err)
142			goto err_pci;
143	} else {
144		if (what & SSB_GPIO_XTAL) {
145			/* Turn the crystal off */
146			out &= ~SSB_GPIO_XTAL;
147		}
148		if (what & SSB_GPIO_PLL) {
149			/* Turn the PLL off */
150			out |= SSB_GPIO_PLL;
151		}
152		err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out);
153		if (err)
154			goto err_pci;
155		err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE, outenable);
156		if (err)
157			goto err_pci;
158	}
159
160out:
161	return err;
162
163err_pci:
164	printk(KERN_ERR PFX "Error: ssb_pci_xtal() could not access PCI config space!\n");
165	err = -EBUSY;
166	goto out;
167}
168
169/* Get the word-offset for a SSB_SPROM_XXX define. */
170#define SPOFF(offset)	(((offset) - SSB_SPROM_BASE) / sizeof(u16))
171/* Helper to extract some _offset, which is one of the SSB_SPROM_XXX defines. */
172#define SPEX(_outvar, _offset, _mask, _shift)	\
173	out->_outvar = ((in[SPOFF(_offset)] & (_mask)) >> (_shift))
174
175static inline u8 ssb_crc8(u8 crc, u8 data)
176{
177	/* Polynomial:   x^8 + x^7 + x^6 + x^4 + x^2 + 1   */
178	static const u8 t[] = {
179		0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
180		0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
181		0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
182		0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
183		0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
184		0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
185		0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
186		0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
187		0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
188		0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
189		0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
190		0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
191		0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
192		0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
193		0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
194		0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
195		0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
196		0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
197		0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
198		0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
199		0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
200		0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
201		0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
202		0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
203		0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
204		0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
205		0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
206		0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
207		0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
208		0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
209		0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
210		0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F,
211	};
212	return t[crc ^ data];
213}
214
215static u8 ssb_sprom_crc(const u16 *sprom, u16 size)
216{
217	int word;
218	u8 crc = 0xFF;
219
220	for (word = 0; word < size - 1; word++) {
221		crc = ssb_crc8(crc, sprom[word] & 0x00FF);
222		crc = ssb_crc8(crc, (sprom[word] & 0xFF00) >> 8);
223	}
224	crc = ssb_crc8(crc, sprom[size - 1] & 0x00FF);
225	crc ^= 0xFF;
226
227	return crc;
228}
229
230static int sprom_check_crc(const u16 *sprom, size_t size)
231{
232	u8 crc;
233	u8 expected_crc;
234	u16 tmp;
235
236	crc = ssb_sprom_crc(sprom, size);
237	tmp = sprom[size - 1] & SSB_SPROM_REVISION_CRC;
238	expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT;
239	if (crc != expected_crc)
240		return -EPROTO;
241
242	return 0;
243}
244
245static int sprom_do_read(struct ssb_bus *bus, u16 *sprom)
246{
247	int i;
248
249	for (i = 0; i < bus->sprom_size; i++)
250		sprom[i] = ioread16(bus->mmio + SSB_SPROM_BASE + (i * 2));
251
252	return 0;
253}
254
255static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom)
256{
257	struct pci_dev *pdev = bus->host_pci;
258	int i, err;
259	u32 spromctl;
260	u16 size = bus->sprom_size;
261
262	ssb_printk(KERN_NOTICE PFX "Writing SPROM. Do NOT turn off the power! Please stand by...\n");
263	err = pci_read_config_dword(pdev, SSB_SPROMCTL, &spromctl);
264	if (err)
265		goto err_ctlreg;
266	spromctl |= SSB_SPROMCTL_WE;
267	err = pci_write_config_dword(pdev, SSB_SPROMCTL, spromctl);
268	if (err)
269		goto err_ctlreg;
270	ssb_printk(KERN_NOTICE PFX "[ 0%%");
271	msleep(500);
272	for (i = 0; i < size; i++) {
273		if (i == size / 4)
274			ssb_printk("25%%");
275		else if (i == size / 2)
276			ssb_printk("50%%");
277		else if (i == (size * 3) / 4)
278			ssb_printk("75%%");
279		else if (i % 2)
280			ssb_printk(".");
281		writew(sprom[i], bus->mmio + SSB_SPROM_BASE + (i * 2));
282		mmiowb();
283		msleep(20);
284	}
285	err = pci_read_config_dword(pdev, SSB_SPROMCTL, &spromctl);
286	if (err)
287		goto err_ctlreg;
288	spromctl &= ~SSB_SPROMCTL_WE;
289	err = pci_write_config_dword(pdev, SSB_SPROMCTL, spromctl);
290	if (err)
291		goto err_ctlreg;
292	msleep(500);
293	ssb_printk("100%% ]\n");
294	ssb_printk(KERN_NOTICE PFX "SPROM written.\n");
295
296	return 0;
297err_ctlreg:
298	ssb_printk(KERN_ERR PFX "Could not access SPROM control register.\n");
299	return err;
300}
301
302static s8 r123_extract_antgain(u8 sprom_revision, const u16 *in,
303			       u16 mask, u16 shift)
304{
305	u16 v;
306	u8 gain;
307
308	v = in[SPOFF(SSB_SPROM1_AGAIN)];
309	gain = (v & mask) >> shift;
310	if (gain == 0xFF)
311		gain = 2; /* If unset use 2dBm */
312	if (sprom_revision == 1) {
313		/* Convert to Q5.2 */
314		gain <<= 2;
315	} else {
316		/* Q5.2 Fractional part is stored in 0xC0 */
317		gain = ((gain & 0xC0) >> 6) | ((gain & 0x3F) << 2);
318	}
319
320	return (s8)gain;
321}
322
323static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
324{
325	int i;
326	u16 v;
327	s8 gain;
328	u16 loc[3];
329
330	if (out->revision == 3)			/* rev 3 moved MAC */
331		loc[0] = SSB_SPROM3_IL0MAC;
332	else {
333		loc[0] = SSB_SPROM1_IL0MAC;
334		loc[1] = SSB_SPROM1_ET0MAC;
335		loc[2] = SSB_SPROM1_ET1MAC;
336	}
337	for (i = 0; i < 3; i++) {
338		v = in[SPOFF(loc[0]) + i];
339		*(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
340	}
341	if (out->revision < 3) { 	/* only rev 1-2 have et0, et1 */
342		for (i = 0; i < 3; i++) {
343			v = in[SPOFF(loc[1]) + i];
344			*(((__be16 *)out->et0mac) + i) = cpu_to_be16(v);
345		}
346		for (i = 0; i < 3; i++) {
347			v = in[SPOFF(loc[2]) + i];
348			*(((__be16 *)out->et1mac) + i) = cpu_to_be16(v);
349		}
350	}
351	SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0);
352	SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A,
353	     SSB_SPROM1_ETHPHY_ET1A_SHIFT);
354	SPEX(et0mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0M, 14);
355	SPEX(et1mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1M, 15);
356	SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0);
357	SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE,
358	     SSB_SPROM1_BINF_CCODE_SHIFT);
359	SPEX(ant_available_a, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTA,
360	     SSB_SPROM1_BINF_ANTA_SHIFT);
361	SPEX(ant_available_bg, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTBG,
362	     SSB_SPROM1_BINF_ANTBG_SHIFT);
363	SPEX(pa0b0, SSB_SPROM1_PA0B0, 0xFFFF, 0);
364	SPEX(pa0b1, SSB_SPROM1_PA0B1, 0xFFFF, 0);
365	SPEX(pa0b2, SSB_SPROM1_PA0B2, 0xFFFF, 0);
366	SPEX(pa1b0, SSB_SPROM1_PA1B0, 0xFFFF, 0);
367	SPEX(pa1b1, SSB_SPROM1_PA1B1, 0xFFFF, 0);
368	SPEX(pa1b2, SSB_SPROM1_PA1B2, 0xFFFF, 0);
369	SPEX(gpio0, SSB_SPROM1_GPIOA, SSB_SPROM1_GPIOA_P0, 0);
370	SPEX(gpio1, SSB_SPROM1_GPIOA, SSB_SPROM1_GPIOA_P1,
371	     SSB_SPROM1_GPIOA_P1_SHIFT);
372	SPEX(gpio2, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P2, 0);
373	SPEX(gpio3, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P3,
374	     SSB_SPROM1_GPIOB_P3_SHIFT);
375	SPEX(maxpwr_a, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_A,
376	     SSB_SPROM1_MAXPWR_A_SHIFT);
377	SPEX(maxpwr_bg, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_BG, 0);
378	SPEX(itssi_a, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_A,
379	     SSB_SPROM1_ITSSI_A_SHIFT);
380	SPEX(itssi_bg, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_BG, 0);
381	SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0);
382	if (out->revision >= 2)
383		SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0);
384
385	/* Extract the antenna gain values. */
386	gain = r123_extract_antgain(out->revision, in,
387				    SSB_SPROM1_AGAIN_BG,
388				    SSB_SPROM1_AGAIN_BG_SHIFT);
389	out->antenna_gain.ghz24.a0 = gain;
390	out->antenna_gain.ghz24.a1 = gain;
391	out->antenna_gain.ghz24.a2 = gain;
392	out->antenna_gain.ghz24.a3 = gain;
393	gain = r123_extract_antgain(out->revision, in,
394				    SSB_SPROM1_AGAIN_A,
395				    SSB_SPROM1_AGAIN_A_SHIFT);
396	out->antenna_gain.ghz5.a0 = gain;
397	out->antenna_gain.ghz5.a1 = gain;
398	out->antenna_gain.ghz5.a2 = gain;
399	out->antenna_gain.ghz5.a3 = gain;
400}
401
402static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
403{
404	int i;
405	u16 v;
406	u16 il0mac_offset;
407
408	if (out->revision == 4)
409		il0mac_offset = SSB_SPROM4_IL0MAC;
410	else
411		il0mac_offset = SSB_SPROM5_IL0MAC;
412	/* extract the MAC address */
413	for (i = 0; i < 3; i++) {
414		v = in[SPOFF(il0mac_offset) + i];
415		*(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
416	}
417	SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0);
418	SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A,
419	     SSB_SPROM4_ETHPHY_ET1A_SHIFT);
420	if (out->revision == 4) {
421		SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0);
422		SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0);
423		SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0);
424	} else {
425		SPEX(country_code, SSB_SPROM5_CCODE, 0xFFFF, 0);
426		SPEX(boardflags_lo, SSB_SPROM5_BFLLO, 0xFFFF, 0);
427		SPEX(boardflags_hi, SSB_SPROM5_BFLHI, 0xFFFF, 0);
428	}
429	SPEX(ant_available_a, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_A,
430	     SSB_SPROM4_ANTAVAIL_A_SHIFT);
431	SPEX(ant_available_bg, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_BG,
432	     SSB_SPROM4_ANTAVAIL_BG_SHIFT);
433	SPEX(maxpwr_bg, SSB_SPROM4_MAXP_BG, SSB_SPROM4_MAXP_BG_MASK, 0);
434	SPEX(itssi_bg, SSB_SPROM4_MAXP_BG, SSB_SPROM4_ITSSI_BG,
435	     SSB_SPROM4_ITSSI_BG_SHIFT);
436	SPEX(maxpwr_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_MAXP_A_MASK, 0);
437	SPEX(itssi_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_ITSSI_A,
438	     SSB_SPROM4_ITSSI_A_SHIFT);
439	if (out->revision == 4) {
440		SPEX(gpio0, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P0, 0);
441		SPEX(gpio1, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P1,
442		     SSB_SPROM4_GPIOA_P1_SHIFT);
443		SPEX(gpio2, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P2, 0);
444		SPEX(gpio3, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P3,
445		     SSB_SPROM4_GPIOB_P3_SHIFT);
446	} else {
447		SPEX(gpio0, SSB_SPROM5_GPIOA, SSB_SPROM5_GPIOA_P0, 0);
448		SPEX(gpio1, SSB_SPROM5_GPIOA, SSB_SPROM5_GPIOA_P1,
449		     SSB_SPROM5_GPIOA_P1_SHIFT);
450		SPEX(gpio2, SSB_SPROM5_GPIOB, SSB_SPROM5_GPIOB_P2, 0);
451		SPEX(gpio3, SSB_SPROM5_GPIOB, SSB_SPROM5_GPIOB_P3,
452		     SSB_SPROM5_GPIOB_P3_SHIFT);
453	}
454
455	/* Extract the antenna gain values. */
456	SPEX(antenna_gain.ghz24.a0, SSB_SPROM4_AGAIN01,
457	     SSB_SPROM4_AGAIN0, SSB_SPROM4_AGAIN0_SHIFT);
458	SPEX(antenna_gain.ghz24.a1, SSB_SPROM4_AGAIN01,
459	     SSB_SPROM4_AGAIN1, SSB_SPROM4_AGAIN1_SHIFT);
460	SPEX(antenna_gain.ghz24.a2, SSB_SPROM4_AGAIN23,
461	     SSB_SPROM4_AGAIN2, SSB_SPROM4_AGAIN2_SHIFT);
462	SPEX(antenna_gain.ghz24.a3, SSB_SPROM4_AGAIN23,
463	     SSB_SPROM4_AGAIN3, SSB_SPROM4_AGAIN3_SHIFT);
464	memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
465	       sizeof(out->antenna_gain.ghz5));
466
467	/* TODO - get remaining rev 4 stuff needed */
468}
469
470static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
471{
472	int i;
473	u16 v;
474
475	/* extract the MAC address */
476	for (i = 0; i < 3; i++) {
477		v = in[SPOFF(SSB_SPROM1_IL0MAC) + i];
478		*(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
479	}
480	SPEX(country_code, SSB_SPROM8_CCODE, 0xFFFF, 0);
481	SPEX(boardflags_lo, SSB_SPROM8_BFLLO, 0xFFFF, 0);
482	SPEX(boardflags_hi, SSB_SPROM8_BFLHI, 0xFFFF, 0);
483	SPEX(ant_available_a, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_A,
484	     SSB_SPROM8_ANTAVAIL_A_SHIFT);
485	SPEX(ant_available_bg, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_BG,
486	     SSB_SPROM8_ANTAVAIL_BG_SHIFT);
487	SPEX(maxpwr_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_MAXP_BG_MASK, 0);
488	SPEX(itssi_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_ITSSI_BG,
489	     SSB_SPROM8_ITSSI_BG_SHIFT);
490	SPEX(maxpwr_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_MAXP_A_MASK, 0);
491	SPEX(itssi_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_ITSSI_A,
492	     SSB_SPROM8_ITSSI_A_SHIFT);
493	SPEX(gpio0, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P0, 0);
494	SPEX(gpio1, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P1,
495	     SSB_SPROM8_GPIOA_P1_SHIFT);
496	SPEX(gpio2, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P2, 0);
497	SPEX(gpio3, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P3,
498	     SSB_SPROM8_GPIOB_P3_SHIFT);
499
500	/* Extract the antenna gain values. */
501	SPEX(antenna_gain.ghz24.a0, SSB_SPROM8_AGAIN01,
502	     SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT);
503	SPEX(antenna_gain.ghz24.a1, SSB_SPROM8_AGAIN01,
504	     SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT);
505	SPEX(antenna_gain.ghz24.a2, SSB_SPROM8_AGAIN23,
506	     SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT);
507	SPEX(antenna_gain.ghz24.a3, SSB_SPROM8_AGAIN23,
508	     SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT);
509	memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
510	       sizeof(out->antenna_gain.ghz5));
511
512	/* TODO - get remaining rev 8 stuff needed */
513}
514
515static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out,
516			 const u16 *in, u16 size)
517{
518	memset(out, 0, sizeof(*out));
519
520	out->revision = in[size - 1] & 0x00FF;
521	ssb_dprintk(KERN_DEBUG PFX "SPROM revision %d detected.\n", out->revision);
522	memset(out->et0mac, 0xFF, 6);		/* preset et0 and et1 mac */
523	memset(out->et1mac, 0xFF, 6);
524	if ((bus->chip_id & 0xFF00) == 0x4400) {
525		/* Workaround: The BCM44XX chip has a stupid revision
526		 * number stored in the SPROM.
527		 * Always extract r1. */
528		out->revision = 1;
529		sprom_extract_r123(out, in);
530	} else if (bus->chip_id == 0x4321) {
531		/* the BCM4328 has a chipid == 0x4321 and a rev 4 SPROM */
532		out->revision = 4;
533		sprom_extract_r45(out, in);
534	} else {
535		switch (out->revision) {
536		case 1:
537		case 2:
538		case 3:
539			sprom_extract_r123(out, in);
540			break;
541		case 4:
542		case 5:
543			sprom_extract_r45(out, in);
544			break;
545		case 8:
546			sprom_extract_r8(out, in);
547			break;
548		default:
549			ssb_printk(KERN_WARNING PFX "Unsupported SPROM"
550				   "  revision %d detected. Will extract"
551				   " v1\n", out->revision);
552			sprom_extract_r123(out, in);
553		}
554	}
555
556	if (out->boardflags_lo == 0xFFFF)
557		out->boardflags_lo = 0;  /* per specs */
558	if (out->boardflags_hi == 0xFFFF)
559		out->boardflags_hi = 0;  /* per specs */
560
561	return 0;
562}
563
564static int ssb_pci_sprom_get(struct ssb_bus *bus,
565			     struct ssb_sprom *sprom)
566{
567	const struct ssb_sprom *fallback;
568	int err = -ENOMEM;
569	u16 *buf;
570
571	buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL);
572	if (!buf)
573		goto out;
574	bus->sprom_size = SSB_SPROMSIZE_WORDS_R123;
575	sprom_do_read(bus, buf);
576	err = sprom_check_crc(buf, bus->sprom_size);
577	if (err) {
578		/* try for a 440 byte SPROM - revision 4 and higher */
579		kfree(buf);
580		buf = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
581			      GFP_KERNEL);
582		if (!buf)
583			goto out;
584		bus->sprom_size = SSB_SPROMSIZE_WORDS_R4;
585		sprom_do_read(bus, buf);
586		err = sprom_check_crc(buf, bus->sprom_size);
587		if (err) {
588			/* All CRC attempts failed.
589			 * Maybe there is no SPROM on the device?
590			 * If we have a fallback, use that. */
591			fallback = ssb_get_fallback_sprom();
592			if (fallback) {
593				memcpy(sprom, fallback, sizeof(*sprom));
594				err = 0;
595				goto out_free;
596			}
597			ssb_printk(KERN_WARNING PFX "WARNING: Invalid"
598				   " SPROM CRC (corrupt SPROM)\n");
599		}
600	}
601	err = sprom_extract(bus, sprom, buf, bus->sprom_size);
602
603out_free:
604	kfree(buf);
605out:
606	return err;
607}
608
609static void ssb_pci_get_boardinfo(struct ssb_bus *bus,
610				  struct ssb_boardinfo *bi)
611{
612	pci_read_config_word(bus->host_pci, PCI_SUBSYSTEM_VENDOR_ID,
613			     &bi->vendor);
614	pci_read_config_word(bus->host_pci, PCI_SUBSYSTEM_ID,
615			     &bi->type);
616	pci_read_config_word(bus->host_pci, PCI_REVISION_ID,
617			     &bi->rev);
618}
619
620int ssb_pci_get_invariants(struct ssb_bus *bus,
621			   struct ssb_init_invariants *iv)
622{
623	int err;
624
625	err = ssb_pci_sprom_get(bus, &iv->sprom);
626	if (err)
627		goto out;
628	ssb_pci_get_boardinfo(bus, &iv->boardinfo);
629
630out:
631	return err;
632}
633
634#ifdef CONFIG_SSB_DEBUG
635static int ssb_pci_assert_buspower(struct ssb_bus *bus)
636{
637	if (likely(bus->powered_up))
638		return 0;
639
640	printk(KERN_ERR PFX "FATAL ERROR: Bus powered down "
641	       "while accessing PCI MMIO space\n");
642	if (bus->power_warn_count <= 10) {
643		bus->power_warn_count++;
644		dump_stack();
645	}
646
647	return -ENODEV;
648}
649#else /* DEBUG */
650static inline int ssb_pci_assert_buspower(struct ssb_bus *bus)
651{
652	return 0;
653}
654#endif /* DEBUG */
655
656static u8 ssb_pci_read8(struct ssb_device *dev, u16 offset)
657{
658	struct ssb_bus *bus = dev->bus;
659
660	if (unlikely(ssb_pci_assert_buspower(bus)))
661		return 0xFF;
662	if (unlikely(bus->mapped_device != dev)) {
663		if (unlikely(ssb_pci_switch_core(bus, dev)))
664			return 0xFF;
665	}
666	return ioread8(bus->mmio + offset);
667}
668
669static u16 ssb_pci_read16(struct ssb_device *dev, u16 offset)
670{
671	struct ssb_bus *bus = dev->bus;
672
673	if (unlikely(ssb_pci_assert_buspower(bus)))
674		return 0xFFFF;
675	if (unlikely(bus->mapped_device != dev)) {
676		if (unlikely(ssb_pci_switch_core(bus, dev)))
677			return 0xFFFF;
678	}
679	return ioread16(bus->mmio + offset);
680}
681
682static u32 ssb_pci_read32(struct ssb_device *dev, u16 offset)
683{
684	struct ssb_bus *bus = dev->bus;
685
686	if (unlikely(ssb_pci_assert_buspower(bus)))
687		return 0xFFFFFFFF;
688	if (unlikely(bus->mapped_device != dev)) {
689		if (unlikely(ssb_pci_switch_core(bus, dev)))
690			return 0xFFFFFFFF;
691	}
692	return ioread32(bus->mmio + offset);
693}
694
695#ifdef CONFIG_SSB_BLOCKIO
696static void ssb_pci_block_read(struct ssb_device *dev, void *buffer,
697			       size_t count, u16 offset, u8 reg_width)
698{
699	struct ssb_bus *bus = dev->bus;
700	void __iomem *addr = bus->mmio + offset;
701
702	if (unlikely(ssb_pci_assert_buspower(bus)))
703		goto error;
704	if (unlikely(bus->mapped_device != dev)) {
705		if (unlikely(ssb_pci_switch_core(bus, dev)))
706			goto error;
707	}
708	switch (reg_width) {
709	case sizeof(u8):
710		ioread8_rep(addr, buffer, count);
711		break;
712	case sizeof(u16):
713		SSB_WARN_ON(count & 1);
714		ioread16_rep(addr, buffer, count >> 1);
715		break;
716	case sizeof(u32):
717		SSB_WARN_ON(count & 3);
718		ioread32_rep(addr, buffer, count >> 2);
719		break;
720	default:
721		SSB_WARN_ON(1);
722	}
723
724	return;
725error:
726	memset(buffer, 0xFF, count);
727}
728#endif /* CONFIG_SSB_BLOCKIO */
729
730static void ssb_pci_write8(struct ssb_device *dev, u16 offset, u8 value)
731{
732	struct ssb_bus *bus = dev->bus;
733
734	if (unlikely(ssb_pci_assert_buspower(bus)))
735		return;
736	if (unlikely(bus->mapped_device != dev)) {
737		if (unlikely(ssb_pci_switch_core(bus, dev)))
738			return;
739	}
740	iowrite8(value, bus->mmio + offset);
741}
742
743static void ssb_pci_write16(struct ssb_device *dev, u16 offset, u16 value)
744{
745	struct ssb_bus *bus = dev->bus;
746
747	if (unlikely(ssb_pci_assert_buspower(bus)))
748		return;
749	if (unlikely(bus->mapped_device != dev)) {
750		if (unlikely(ssb_pci_switch_core(bus, dev)))
751			return;
752	}
753	iowrite16(value, bus->mmio + offset);
754}
755
756static void ssb_pci_write32(struct ssb_device *dev, u16 offset, u32 value)
757{
758	struct ssb_bus *bus = dev->bus;
759
760	if (unlikely(ssb_pci_assert_buspower(bus)))
761		return;
762	if (unlikely(bus->mapped_device != dev)) {
763		if (unlikely(ssb_pci_switch_core(bus, dev)))
764			return;
765	}
766	iowrite32(value, bus->mmio + offset);
767}
768
769#ifdef CONFIG_SSB_BLOCKIO
770static void ssb_pci_block_write(struct ssb_device *dev, const void *buffer,
771				size_t count, u16 offset, u8 reg_width)
772{
773	struct ssb_bus *bus = dev->bus;
774	void __iomem *addr = bus->mmio + offset;
775
776	if (unlikely(ssb_pci_assert_buspower(bus)))
777		return;
778	if (unlikely(bus->mapped_device != dev)) {
779		if (unlikely(ssb_pci_switch_core(bus, dev)))
780			return;
781	}
782	switch (reg_width) {
783	case sizeof(u8):
784		iowrite8_rep(addr, buffer, count);
785		break;
786	case sizeof(u16):
787		SSB_WARN_ON(count & 1);
788		iowrite16_rep(addr, buffer, count >> 1);
789		break;
790	case sizeof(u32):
791		SSB_WARN_ON(count & 3);
792		iowrite32_rep(addr, buffer, count >> 2);
793		break;
794	default:
795		SSB_WARN_ON(1);
796	}
797}
798#endif /* CONFIG_SSB_BLOCKIO */
799
800/* Not "static", as it's used in main.c */
801const struct ssb_bus_ops ssb_pci_ops = {
802	.read8		= ssb_pci_read8,
803	.read16		= ssb_pci_read16,
804	.read32		= ssb_pci_read32,
805	.write8		= ssb_pci_write8,
806	.write16	= ssb_pci_write16,
807	.write32	= ssb_pci_write32,
808#ifdef CONFIG_SSB_BLOCKIO
809	.block_read	= ssb_pci_block_read,
810	.block_write	= ssb_pci_block_write,
811#endif
812};
813
814static ssize_t ssb_pci_attr_sprom_show(struct device *pcidev,
815				       struct device_attribute *attr,
816				       char *buf)
817{
818	struct pci_dev *pdev = container_of(pcidev, struct pci_dev, dev);
819	struct ssb_bus *bus;
820
821	bus = ssb_pci_dev_to_bus(pdev);
822	if (!bus)
823		return -ENODEV;
824
825	return ssb_attr_sprom_show(bus, buf, sprom_do_read);
826}
827
828static ssize_t ssb_pci_attr_sprom_store(struct device *pcidev,
829					struct device_attribute *attr,
830					const char *buf, size_t count)
831{
832	struct pci_dev *pdev = container_of(pcidev, struct pci_dev, dev);
833	struct ssb_bus *bus;
834
835	bus = ssb_pci_dev_to_bus(pdev);
836	if (!bus)
837		return -ENODEV;
838
839	return ssb_attr_sprom_store(bus, buf, count,
840				    sprom_check_crc, sprom_do_write);
841}
842
843static DEVICE_ATTR(ssb_sprom, 0600,
844		   ssb_pci_attr_sprom_show,
845		   ssb_pci_attr_sprom_store);
846
847void ssb_pci_exit(struct ssb_bus *bus)
848{
849	struct pci_dev *pdev;
850
851	if (bus->bustype != SSB_BUSTYPE_PCI)
852		return;
853
854	pdev = bus->host_pci;
855	device_remove_file(&pdev->dev, &dev_attr_ssb_sprom);
856}
857
858int ssb_pci_init(struct ssb_bus *bus)
859{
860	struct pci_dev *pdev;
861	int err;
862
863	if (bus->bustype != SSB_BUSTYPE_PCI)
864		return 0;
865
866	pdev = bus->host_pci;
867	mutex_init(&bus->sprom_mutex);
868	err = device_create_file(&pdev->dev, &dev_attr_ssb_sprom);
869	if (err)
870		goto out;
871
872out:
873	return err;
874}
875