xref: /openbmc/linux/drivers/ssb/pci.c (revision ce932d0c5589e9766e089c22c66890dfc48fbd94)
1 /*
2  * Sonics Silicon Backplane PCI-Hostbus related functions.
3  *
4  * Copyright (C) 2005-2006 Michael Buesch <m@bues.ch>
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/slab.h>
21 #include <linux/pci.h>
22 #include <linux/delay.h>
23 
24 #include "ssb_private.h"
25 
26 
27 /* Define the following to 1 to enable a printk on each coreswitch. */
28 #define SSB_VERBOSE_PCICORESWITCH_DEBUG		0
29 
30 
31 /* Lowlevel coreswitching */
32 int ssb_pci_switch_coreidx(struct ssb_bus *bus, u8 coreidx)
33 {
34 	int err;
35 	int attempts = 0;
36 	u32 cur_core;
37 
38 	while (1) {
39 		err = pci_write_config_dword(bus->host_pci, SSB_BAR0_WIN,
40 					     (coreidx * SSB_CORE_SIZE)
41 					     + SSB_ENUM_BASE);
42 		if (err)
43 			goto error;
44 		err = pci_read_config_dword(bus->host_pci, SSB_BAR0_WIN,
45 					    &cur_core);
46 		if (err)
47 			goto error;
48 		cur_core = (cur_core - SSB_ENUM_BASE)
49 			   / SSB_CORE_SIZE;
50 		if (cur_core == coreidx)
51 			break;
52 
53 		if (attempts++ > SSB_BAR0_MAX_RETRIES)
54 			goto error;
55 		udelay(10);
56 	}
57 	return 0;
58 error:
59 	ssb_printk(KERN_ERR PFX "Failed to switch to core %u\n", coreidx);
60 	return -ENODEV;
61 }
62 
63 int ssb_pci_switch_core(struct ssb_bus *bus,
64 			struct ssb_device *dev)
65 {
66 	int err;
67 	unsigned long flags;
68 
69 #if SSB_VERBOSE_PCICORESWITCH_DEBUG
70 	ssb_printk(KERN_INFO PFX
71 		   "Switching to %s core, index %d\n",
72 		   ssb_core_name(dev->id.coreid),
73 		   dev->core_index);
74 #endif
75 
76 	spin_lock_irqsave(&bus->bar_lock, flags);
77 	err = ssb_pci_switch_coreidx(bus, dev->core_index);
78 	if (!err)
79 		bus->mapped_device = dev;
80 	spin_unlock_irqrestore(&bus->bar_lock, flags);
81 
82 	return err;
83 }
84 
85 /* Enable/disable the on board crystal oscillator and/or PLL. */
86 int ssb_pci_xtal(struct ssb_bus *bus, u32 what, int turn_on)
87 {
88 	int err;
89 	u32 in, out, outenable;
90 	u16 pci_status;
91 
92 	if (bus->bustype != SSB_BUSTYPE_PCI)
93 		return 0;
94 
95 	err = pci_read_config_dword(bus->host_pci, SSB_GPIO_IN, &in);
96 	if (err)
97 		goto err_pci;
98 	err = pci_read_config_dword(bus->host_pci, SSB_GPIO_OUT, &out);
99 	if (err)
100 		goto err_pci;
101 	err = pci_read_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE, &outenable);
102 	if (err)
103 		goto err_pci;
104 
105 	outenable |= what;
106 
107 	if (turn_on) {
108 		/* Avoid glitching the clock if GPRS is already using it.
109 		 * We can't actually read the state of the PLLPD so we infer it
110 		 * by the value of XTAL_PU which *is* readable via gpioin.
111 		 */
112 		if (!(in & SSB_GPIO_XTAL)) {
113 			if (what & SSB_GPIO_XTAL) {
114 				/* Turn the crystal on */
115 				out |= SSB_GPIO_XTAL;
116 				if (what & SSB_GPIO_PLL)
117 					out |= SSB_GPIO_PLL;
118 				err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out);
119 				if (err)
120 					goto err_pci;
121 				err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE,
122 							     outenable);
123 				if (err)
124 					goto err_pci;
125 				msleep(1);
126 			}
127 			if (what & SSB_GPIO_PLL) {
128 				/* Turn the PLL on */
129 				out &= ~SSB_GPIO_PLL;
130 				err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out);
131 				if (err)
132 					goto err_pci;
133 				msleep(5);
134 			}
135 		}
136 
137 		err = pci_read_config_word(bus->host_pci, PCI_STATUS, &pci_status);
138 		if (err)
139 			goto err_pci;
140 		pci_status &= ~PCI_STATUS_SIG_TARGET_ABORT;
141 		err = pci_write_config_word(bus->host_pci, PCI_STATUS, pci_status);
142 		if (err)
143 			goto err_pci;
144 	} else {
145 		if (what & SSB_GPIO_XTAL) {
146 			/* Turn the crystal off */
147 			out &= ~SSB_GPIO_XTAL;
148 		}
149 		if (what & SSB_GPIO_PLL) {
150 			/* Turn the PLL off */
151 			out |= SSB_GPIO_PLL;
152 		}
153 		err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out);
154 		if (err)
155 			goto err_pci;
156 		err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE, outenable);
157 		if (err)
158 			goto err_pci;
159 	}
160 
161 out:
162 	return err;
163 
164 err_pci:
165 	printk(KERN_ERR PFX "Error: ssb_pci_xtal() could not access PCI config space!\n");
166 	err = -EBUSY;
167 	goto out;
168 }
169 
170 /* Get the word-offset for a SSB_SPROM_XXX define. */
171 #define SPOFF(offset)	((offset) / sizeof(u16))
172 /* Helper to extract some _offset, which is one of the SSB_SPROM_XXX defines. */
173 #define SPEX16(_outvar, _offset, _mask, _shift)	\
174 	out->_outvar = ((in[SPOFF(_offset)] & (_mask)) >> (_shift))
175 #define SPEX32(_outvar, _offset, _mask, _shift)	\
176 	out->_outvar = ((((u32)in[SPOFF((_offset)+2)] << 16 | \
177 			   in[SPOFF(_offset)]) & (_mask)) >> (_shift))
178 #define SPEX(_outvar, _offset, _mask, _shift) \
179 	SPEX16(_outvar, _offset, _mask, _shift)
180 
181 
182 static inline u8 ssb_crc8(u8 crc, u8 data)
183 {
184 	/* Polynomial:   x^8 + x^7 + x^6 + x^4 + x^2 + 1   */
185 	static const u8 t[] = {
186 		0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
187 		0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
188 		0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
189 		0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
190 		0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
191 		0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
192 		0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
193 		0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
194 		0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
195 		0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
196 		0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
197 		0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
198 		0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
199 		0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
200 		0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
201 		0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
202 		0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
203 		0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
204 		0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
205 		0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
206 		0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
207 		0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
208 		0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
209 		0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
210 		0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
211 		0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
212 		0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
213 		0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
214 		0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
215 		0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
216 		0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
217 		0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F,
218 	};
219 	return t[crc ^ data];
220 }
221 
222 static u8 ssb_sprom_crc(const u16 *sprom, u16 size)
223 {
224 	int word;
225 	u8 crc = 0xFF;
226 
227 	for (word = 0; word < size - 1; word++) {
228 		crc = ssb_crc8(crc, sprom[word] & 0x00FF);
229 		crc = ssb_crc8(crc, (sprom[word] & 0xFF00) >> 8);
230 	}
231 	crc = ssb_crc8(crc, sprom[size - 1] & 0x00FF);
232 	crc ^= 0xFF;
233 
234 	return crc;
235 }
236 
237 static int sprom_check_crc(const u16 *sprom, size_t size)
238 {
239 	u8 crc;
240 	u8 expected_crc;
241 	u16 tmp;
242 
243 	crc = ssb_sprom_crc(sprom, size);
244 	tmp = sprom[size - 1] & SSB_SPROM_REVISION_CRC;
245 	expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT;
246 	if (crc != expected_crc)
247 		return -EPROTO;
248 
249 	return 0;
250 }
251 
252 static int sprom_do_read(struct ssb_bus *bus, u16 *sprom)
253 {
254 	int i;
255 
256 	for (i = 0; i < bus->sprom_size; i++)
257 		sprom[i] = ioread16(bus->mmio + bus->sprom_offset + (i * 2));
258 
259 	return 0;
260 }
261 
262 static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom)
263 {
264 	struct pci_dev *pdev = bus->host_pci;
265 	int i, err;
266 	u32 spromctl;
267 	u16 size = bus->sprom_size;
268 
269 	ssb_printk(KERN_NOTICE PFX "Writing SPROM. Do NOT turn off the power! Please stand by...\n");
270 	err = pci_read_config_dword(pdev, SSB_SPROMCTL, &spromctl);
271 	if (err)
272 		goto err_ctlreg;
273 	spromctl |= SSB_SPROMCTL_WE;
274 	err = pci_write_config_dword(pdev, SSB_SPROMCTL, spromctl);
275 	if (err)
276 		goto err_ctlreg;
277 	ssb_printk(KERN_NOTICE PFX "[ 0%%");
278 	msleep(500);
279 	for (i = 0; i < size; i++) {
280 		if (i == size / 4)
281 			ssb_printk("25%%");
282 		else if (i == size / 2)
283 			ssb_printk("50%%");
284 		else if (i == (size * 3) / 4)
285 			ssb_printk("75%%");
286 		else if (i % 2)
287 			ssb_printk(".");
288 		writew(sprom[i], bus->mmio + bus->sprom_offset + (i * 2));
289 		mmiowb();
290 		msleep(20);
291 	}
292 	err = pci_read_config_dword(pdev, SSB_SPROMCTL, &spromctl);
293 	if (err)
294 		goto err_ctlreg;
295 	spromctl &= ~SSB_SPROMCTL_WE;
296 	err = pci_write_config_dword(pdev, SSB_SPROMCTL, spromctl);
297 	if (err)
298 		goto err_ctlreg;
299 	msleep(500);
300 	ssb_printk("100%% ]\n");
301 	ssb_printk(KERN_NOTICE PFX "SPROM written.\n");
302 
303 	return 0;
304 err_ctlreg:
305 	ssb_printk(KERN_ERR PFX "Could not access SPROM control register.\n");
306 	return err;
307 }
308 
309 static s8 r123_extract_antgain(u8 sprom_revision, const u16 *in,
310 			       u16 mask, u16 shift)
311 {
312 	u16 v;
313 	u8 gain;
314 
315 	v = in[SPOFF(SSB_SPROM1_AGAIN)];
316 	gain = (v & mask) >> shift;
317 	if (gain == 0xFF)
318 		gain = 2; /* If unset use 2dBm */
319 	if (sprom_revision == 1) {
320 		/* Convert to Q5.2 */
321 		gain <<= 2;
322 	} else {
323 		/* Q5.2 Fractional part is stored in 0xC0 */
324 		gain = ((gain & 0xC0) >> 6) | ((gain & 0x3F) << 2);
325 	}
326 
327 	return (s8)gain;
328 }
329 
330 static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
331 {
332 	int i;
333 	u16 v;
334 	u16 loc[3];
335 
336 	if (out->revision == 3)			/* rev 3 moved MAC */
337 		loc[0] = SSB_SPROM3_IL0MAC;
338 	else {
339 		loc[0] = SSB_SPROM1_IL0MAC;
340 		loc[1] = SSB_SPROM1_ET0MAC;
341 		loc[2] = SSB_SPROM1_ET1MAC;
342 	}
343 	for (i = 0; i < 3; i++) {
344 		v = in[SPOFF(loc[0]) + i];
345 		*(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
346 	}
347 	if (out->revision < 3) { 	/* only rev 1-2 have et0, et1 */
348 		for (i = 0; i < 3; i++) {
349 			v = in[SPOFF(loc[1]) + i];
350 			*(((__be16 *)out->et0mac) + i) = cpu_to_be16(v);
351 		}
352 		for (i = 0; i < 3; i++) {
353 			v = in[SPOFF(loc[2]) + i];
354 			*(((__be16 *)out->et1mac) + i) = cpu_to_be16(v);
355 		}
356 	}
357 	SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0);
358 	SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A,
359 	     SSB_SPROM1_ETHPHY_ET1A_SHIFT);
360 	SPEX(et0mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0M, 14);
361 	SPEX(et1mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1M, 15);
362 	SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0);
363 	SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE,
364 	     SSB_SPROM1_BINF_CCODE_SHIFT);
365 	SPEX(ant_available_a, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTA,
366 	     SSB_SPROM1_BINF_ANTA_SHIFT);
367 	SPEX(ant_available_bg, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTBG,
368 	     SSB_SPROM1_BINF_ANTBG_SHIFT);
369 	SPEX(pa0b0, SSB_SPROM1_PA0B0, 0xFFFF, 0);
370 	SPEX(pa0b1, SSB_SPROM1_PA0B1, 0xFFFF, 0);
371 	SPEX(pa0b2, SSB_SPROM1_PA0B2, 0xFFFF, 0);
372 	SPEX(pa1b0, SSB_SPROM1_PA1B0, 0xFFFF, 0);
373 	SPEX(pa1b1, SSB_SPROM1_PA1B1, 0xFFFF, 0);
374 	SPEX(pa1b2, SSB_SPROM1_PA1B2, 0xFFFF, 0);
375 	SPEX(gpio0, SSB_SPROM1_GPIOA, SSB_SPROM1_GPIOA_P0, 0);
376 	SPEX(gpio1, SSB_SPROM1_GPIOA, SSB_SPROM1_GPIOA_P1,
377 	     SSB_SPROM1_GPIOA_P1_SHIFT);
378 	SPEX(gpio2, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P2, 0);
379 	SPEX(gpio3, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P3,
380 	     SSB_SPROM1_GPIOB_P3_SHIFT);
381 	SPEX(maxpwr_a, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_A,
382 	     SSB_SPROM1_MAXPWR_A_SHIFT);
383 	SPEX(maxpwr_bg, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_BG, 0);
384 	SPEX(itssi_a, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_A,
385 	     SSB_SPROM1_ITSSI_A_SHIFT);
386 	SPEX(itssi_bg, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_BG, 0);
387 	SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0);
388 	if (out->revision >= 2)
389 		SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0);
390 
391 	/* Extract the antenna gain values. */
392 	out->antenna_gain.a0 = r123_extract_antgain(out->revision, in,
393 						    SSB_SPROM1_AGAIN_BG,
394 						    SSB_SPROM1_AGAIN_BG_SHIFT);
395 	out->antenna_gain.a1 = r123_extract_antgain(out->revision, in,
396 						    SSB_SPROM1_AGAIN_A,
397 						    SSB_SPROM1_AGAIN_A_SHIFT);
398 }
399 
400 /* Revs 4 5 and 8 have partially shared layout */
401 static void sprom_extract_r458(struct ssb_sprom *out, const u16 *in)
402 {
403 	SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01,
404 	     SSB_SPROM4_TXPID2G0, SSB_SPROM4_TXPID2G0_SHIFT);
405 	SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01,
406 	     SSB_SPROM4_TXPID2G1, SSB_SPROM4_TXPID2G1_SHIFT);
407 	SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23,
408 	     SSB_SPROM4_TXPID2G2, SSB_SPROM4_TXPID2G2_SHIFT);
409 	SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23,
410 	     SSB_SPROM4_TXPID2G3, SSB_SPROM4_TXPID2G3_SHIFT);
411 
412 	SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01,
413 	     SSB_SPROM4_TXPID5GL0, SSB_SPROM4_TXPID5GL0_SHIFT);
414 	SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01,
415 	     SSB_SPROM4_TXPID5GL1, SSB_SPROM4_TXPID5GL1_SHIFT);
416 	SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23,
417 	     SSB_SPROM4_TXPID5GL2, SSB_SPROM4_TXPID5GL2_SHIFT);
418 	SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23,
419 	     SSB_SPROM4_TXPID5GL3, SSB_SPROM4_TXPID5GL3_SHIFT);
420 
421 	SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01,
422 	     SSB_SPROM4_TXPID5G0, SSB_SPROM4_TXPID5G0_SHIFT);
423 	SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01,
424 	     SSB_SPROM4_TXPID5G1, SSB_SPROM4_TXPID5G1_SHIFT);
425 	SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23,
426 	     SSB_SPROM4_TXPID5G2, SSB_SPROM4_TXPID5G2_SHIFT);
427 	SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23,
428 	     SSB_SPROM4_TXPID5G3, SSB_SPROM4_TXPID5G3_SHIFT);
429 
430 	SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01,
431 	     SSB_SPROM4_TXPID5GH0, SSB_SPROM4_TXPID5GH0_SHIFT);
432 	SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01,
433 	     SSB_SPROM4_TXPID5GH1, SSB_SPROM4_TXPID5GH1_SHIFT);
434 	SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23,
435 	     SSB_SPROM4_TXPID5GH2, SSB_SPROM4_TXPID5GH2_SHIFT);
436 	SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23,
437 	     SSB_SPROM4_TXPID5GH3, SSB_SPROM4_TXPID5GH3_SHIFT);
438 }
439 
440 static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
441 {
442 	int i;
443 	u16 v;
444 	u16 il0mac_offset;
445 
446 	if (out->revision == 4)
447 		il0mac_offset = SSB_SPROM4_IL0MAC;
448 	else
449 		il0mac_offset = SSB_SPROM5_IL0MAC;
450 	/* extract the MAC address */
451 	for (i = 0; i < 3; i++) {
452 		v = in[SPOFF(il0mac_offset) + i];
453 		*(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
454 	}
455 	SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0);
456 	SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A,
457 	     SSB_SPROM4_ETHPHY_ET1A_SHIFT);
458 	if (out->revision == 4) {
459 		SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0);
460 		SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0);
461 		SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0);
462 		SPEX(boardflags2_lo, SSB_SPROM4_BFL2LO, 0xFFFF, 0);
463 		SPEX(boardflags2_hi, SSB_SPROM4_BFL2HI, 0xFFFF, 0);
464 	} else {
465 		SPEX(country_code, SSB_SPROM5_CCODE, 0xFFFF, 0);
466 		SPEX(boardflags_lo, SSB_SPROM5_BFLLO, 0xFFFF, 0);
467 		SPEX(boardflags_hi, SSB_SPROM5_BFLHI, 0xFFFF, 0);
468 		SPEX(boardflags2_lo, SSB_SPROM5_BFL2LO, 0xFFFF, 0);
469 		SPEX(boardflags2_hi, SSB_SPROM5_BFL2HI, 0xFFFF, 0);
470 	}
471 	SPEX(ant_available_a, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_A,
472 	     SSB_SPROM4_ANTAVAIL_A_SHIFT);
473 	SPEX(ant_available_bg, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_BG,
474 	     SSB_SPROM4_ANTAVAIL_BG_SHIFT);
475 	SPEX(maxpwr_bg, SSB_SPROM4_MAXP_BG, SSB_SPROM4_MAXP_BG_MASK, 0);
476 	SPEX(itssi_bg, SSB_SPROM4_MAXP_BG, SSB_SPROM4_ITSSI_BG,
477 	     SSB_SPROM4_ITSSI_BG_SHIFT);
478 	SPEX(maxpwr_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_MAXP_A_MASK, 0);
479 	SPEX(itssi_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_ITSSI_A,
480 	     SSB_SPROM4_ITSSI_A_SHIFT);
481 	if (out->revision == 4) {
482 		SPEX(gpio0, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P0, 0);
483 		SPEX(gpio1, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P1,
484 		     SSB_SPROM4_GPIOA_P1_SHIFT);
485 		SPEX(gpio2, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P2, 0);
486 		SPEX(gpio3, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P3,
487 		     SSB_SPROM4_GPIOB_P3_SHIFT);
488 	} else {
489 		SPEX(gpio0, SSB_SPROM5_GPIOA, SSB_SPROM5_GPIOA_P0, 0);
490 		SPEX(gpio1, SSB_SPROM5_GPIOA, SSB_SPROM5_GPIOA_P1,
491 		     SSB_SPROM5_GPIOA_P1_SHIFT);
492 		SPEX(gpio2, SSB_SPROM5_GPIOB, SSB_SPROM5_GPIOB_P2, 0);
493 		SPEX(gpio3, SSB_SPROM5_GPIOB, SSB_SPROM5_GPIOB_P3,
494 		     SSB_SPROM5_GPIOB_P3_SHIFT);
495 	}
496 
497 	/* Extract the antenna gain values. */
498 	SPEX(antenna_gain.a0, SSB_SPROM4_AGAIN01,
499 	     SSB_SPROM4_AGAIN0, SSB_SPROM4_AGAIN0_SHIFT);
500 	SPEX(antenna_gain.a1, SSB_SPROM4_AGAIN01,
501 	     SSB_SPROM4_AGAIN1, SSB_SPROM4_AGAIN1_SHIFT);
502 	SPEX(antenna_gain.a2, SSB_SPROM4_AGAIN23,
503 	     SSB_SPROM4_AGAIN2, SSB_SPROM4_AGAIN2_SHIFT);
504 	SPEX(antenna_gain.a3, SSB_SPROM4_AGAIN23,
505 	     SSB_SPROM4_AGAIN3, SSB_SPROM4_AGAIN3_SHIFT);
506 
507 	sprom_extract_r458(out, in);
508 
509 	/* TODO - get remaining rev 4 stuff needed */
510 }
511 
512 static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
513 {
514 	int i;
515 	u16 v, o;
516 	u16 pwr_info_offset[] = {
517 		SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1,
518 		SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3
519 	};
520 	BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
521 			ARRAY_SIZE(out->core_pwr_info));
522 
523 	/* extract the MAC address */
524 	for (i = 0; i < 3; i++) {
525 		v = in[SPOFF(SSB_SPROM8_IL0MAC) + i];
526 		*(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
527 	}
528 	SPEX(country_code, SSB_SPROM8_CCODE, 0xFFFF, 0);
529 	SPEX(boardflags_lo, SSB_SPROM8_BFLLO, 0xFFFF, 0);
530 	SPEX(boardflags_hi, SSB_SPROM8_BFLHI, 0xFFFF, 0);
531 	SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, 0xFFFF, 0);
532 	SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, 0xFFFF, 0);
533 	SPEX(ant_available_a, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_A,
534 	     SSB_SPROM8_ANTAVAIL_A_SHIFT);
535 	SPEX(ant_available_bg, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_BG,
536 	     SSB_SPROM8_ANTAVAIL_BG_SHIFT);
537 	SPEX(maxpwr_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_MAXP_BG_MASK, 0);
538 	SPEX(itssi_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_ITSSI_BG,
539 	     SSB_SPROM8_ITSSI_BG_SHIFT);
540 	SPEX(maxpwr_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_MAXP_A_MASK, 0);
541 	SPEX(itssi_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_ITSSI_A,
542 	     SSB_SPROM8_ITSSI_A_SHIFT);
543 	SPEX(maxpwr_ah, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AH_MASK, 0);
544 	SPEX(maxpwr_al, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AL_MASK,
545 	     SSB_SPROM8_MAXP_AL_SHIFT);
546 	SPEX(gpio0, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P0, 0);
547 	SPEX(gpio1, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P1,
548 	     SSB_SPROM8_GPIOA_P1_SHIFT);
549 	SPEX(gpio2, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P2, 0);
550 	SPEX(gpio3, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P3,
551 	     SSB_SPROM8_GPIOB_P3_SHIFT);
552 	SPEX(tri2g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI2G, 0);
553 	SPEX(tri5g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI5G,
554 	     SSB_SPROM8_TRI5G_SHIFT);
555 	SPEX(tri5gl, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GL, 0);
556 	SPEX(tri5gh, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GH,
557 	     SSB_SPROM8_TRI5GH_SHIFT);
558 	SPEX(rxpo2g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO2G, 0);
559 	SPEX(rxpo5g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO5G,
560 	     SSB_SPROM8_RXPO5G_SHIFT);
561 	SPEX(rssismf2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMF2G, 0);
562 	SPEX(rssismc2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMC2G,
563 	     SSB_SPROM8_RSSISMC2G_SHIFT);
564 	SPEX(rssisav2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISAV2G,
565 	     SSB_SPROM8_RSSISAV2G_SHIFT);
566 	SPEX(bxa2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_BXA2G,
567 	     SSB_SPROM8_BXA2G_SHIFT);
568 	SPEX(rssismf5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMF5G, 0);
569 	SPEX(rssismc5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMC5G,
570 	     SSB_SPROM8_RSSISMC5G_SHIFT);
571 	SPEX(rssisav5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISAV5G,
572 	     SSB_SPROM8_RSSISAV5G_SHIFT);
573 	SPEX(bxa5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_BXA5G,
574 	     SSB_SPROM8_BXA5G_SHIFT);
575 	SPEX(pa0b0, SSB_SPROM8_PA0B0, 0xFFFF, 0);
576 	SPEX(pa0b1, SSB_SPROM8_PA0B1, 0xFFFF, 0);
577 	SPEX(pa0b2, SSB_SPROM8_PA0B2, 0xFFFF, 0);
578 	SPEX(pa1b0, SSB_SPROM8_PA1B0, 0xFFFF, 0);
579 	SPEX(pa1b1, SSB_SPROM8_PA1B1, 0xFFFF, 0);
580 	SPEX(pa1b2, SSB_SPROM8_PA1B2, 0xFFFF, 0);
581 	SPEX(pa1lob0, SSB_SPROM8_PA1LOB0, 0xFFFF, 0);
582 	SPEX(pa1lob1, SSB_SPROM8_PA1LOB1, 0xFFFF, 0);
583 	SPEX(pa1lob2, SSB_SPROM8_PA1LOB2, 0xFFFF, 0);
584 	SPEX(pa1hib0, SSB_SPROM8_PA1HIB0, 0xFFFF, 0);
585 	SPEX(pa1hib1, SSB_SPROM8_PA1HIB1, 0xFFFF, 0);
586 	SPEX(pa1hib2, SSB_SPROM8_PA1HIB2, 0xFFFF, 0);
587 	SPEX(cck2gpo, SSB_SPROM8_CCK2GPO, 0xFFFF, 0);
588 	SPEX32(ofdm2gpo, SSB_SPROM8_OFDM2GPO, 0xFFFFFFFF, 0);
589 	SPEX32(ofdm5glpo, SSB_SPROM8_OFDM5GLPO, 0xFFFFFFFF, 0);
590 	SPEX32(ofdm5gpo, SSB_SPROM8_OFDM5GPO, 0xFFFFFFFF, 0);
591 	SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0);
592 
593 	/* Extract the antenna gain values. */
594 	SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01,
595 	     SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT);
596 	SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01,
597 	     SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT);
598 	SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23,
599 	     SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT);
600 	SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23,
601 	     SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT);
602 
603 	/* Extract cores power info info */
604 	for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
605 		o = pwr_info_offset[i];
606 		SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
607 			SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT);
608 		SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
609 			SSB_SPROM8_2G_MAXP, 0);
610 
611 		SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0);
612 		SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0);
613 		SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0);
614 
615 		SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
616 			SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT);
617 		SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
618 			SSB_SPROM8_5G_MAXP, 0);
619 		SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP,
620 			SSB_SPROM8_5GH_MAXP, 0);
621 		SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP,
622 			SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT);
623 
624 		SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0);
625 		SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0);
626 		SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0);
627 		SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0);
628 		SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0);
629 		SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0);
630 		SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0);
631 		SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0);
632 		SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0);
633 	}
634 
635 	/* Extract FEM info */
636 	SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G,
637 		SSB_SROM8_FEM_TSSIPOS, SSB_SROM8_FEM_TSSIPOS_SHIFT);
638 	SPEX(fem.ghz2.extpa_gain, SSB_SPROM8_FEM2G,
639 		SSB_SROM8_FEM_EXTPA_GAIN, SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
640 	SPEX(fem.ghz2.pdet_range, SSB_SPROM8_FEM2G,
641 		SSB_SROM8_FEM_PDET_RANGE, SSB_SROM8_FEM_PDET_RANGE_SHIFT);
642 	SPEX(fem.ghz2.tr_iso, SSB_SPROM8_FEM2G,
643 		SSB_SROM8_FEM_TR_ISO, SSB_SROM8_FEM_TR_ISO_SHIFT);
644 	SPEX(fem.ghz2.antswlut, SSB_SPROM8_FEM2G,
645 		SSB_SROM8_FEM_ANTSWLUT, SSB_SROM8_FEM_ANTSWLUT_SHIFT);
646 
647 	SPEX(fem.ghz5.tssipos, SSB_SPROM8_FEM5G,
648 		SSB_SROM8_FEM_TSSIPOS, SSB_SROM8_FEM_TSSIPOS_SHIFT);
649 	SPEX(fem.ghz5.extpa_gain, SSB_SPROM8_FEM5G,
650 		SSB_SROM8_FEM_EXTPA_GAIN, SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
651 	SPEX(fem.ghz5.pdet_range, SSB_SPROM8_FEM5G,
652 		SSB_SROM8_FEM_PDET_RANGE, SSB_SROM8_FEM_PDET_RANGE_SHIFT);
653 	SPEX(fem.ghz5.tr_iso, SSB_SPROM8_FEM5G,
654 		SSB_SROM8_FEM_TR_ISO, SSB_SROM8_FEM_TR_ISO_SHIFT);
655 	SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G,
656 		SSB_SROM8_FEM_ANTSWLUT, SSB_SROM8_FEM_ANTSWLUT_SHIFT);
657 
658 	sprom_extract_r458(out, in);
659 
660 	/* TODO - get remaining rev 8 stuff needed */
661 }
662 
663 static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out,
664 			 const u16 *in, u16 size)
665 {
666 	memset(out, 0, sizeof(*out));
667 
668 	out->revision = in[size - 1] & 0x00FF;
669 	ssb_dprintk(KERN_DEBUG PFX "SPROM revision %d detected.\n", out->revision);
670 	memset(out->et0mac, 0xFF, 6);		/* preset et0 and et1 mac */
671 	memset(out->et1mac, 0xFF, 6);
672 
673 	if ((bus->chip_id & 0xFF00) == 0x4400) {
674 		/* Workaround: The BCM44XX chip has a stupid revision
675 		 * number stored in the SPROM.
676 		 * Always extract r1. */
677 		out->revision = 1;
678 		ssb_dprintk(KERN_DEBUG PFX "SPROM treated as revision %d\n", out->revision);
679 	}
680 
681 	switch (out->revision) {
682 	case 1:
683 	case 2:
684 	case 3:
685 		sprom_extract_r123(out, in);
686 		break;
687 	case 4:
688 	case 5:
689 		sprom_extract_r45(out, in);
690 		break;
691 	case 8:
692 		sprom_extract_r8(out, in);
693 		break;
694 	default:
695 		ssb_printk(KERN_WARNING PFX "Unsupported SPROM"
696 			   " revision %d detected. Will extract"
697 			   " v1\n", out->revision);
698 		out->revision = 1;
699 		sprom_extract_r123(out, in);
700 	}
701 
702 	if (out->boardflags_lo == 0xFFFF)
703 		out->boardflags_lo = 0;  /* per specs */
704 	if (out->boardflags_hi == 0xFFFF)
705 		out->boardflags_hi = 0;  /* per specs */
706 
707 	return 0;
708 }
709 
710 static int ssb_pci_sprom_get(struct ssb_bus *bus,
711 			     struct ssb_sprom *sprom)
712 {
713 	int err;
714 	u16 *buf;
715 
716 	if (!ssb_is_sprom_available(bus)) {
717 		ssb_printk(KERN_ERR PFX "No SPROM available!\n");
718 		return -ENODEV;
719 	}
720 	if (bus->chipco.dev) {	/* can be unavailable! */
721 		/*
722 		 * get SPROM offset: SSB_SPROM_BASE1 except for
723 		 * chipcommon rev >= 31 or chip ID is 0x4312 and
724 		 * chipcommon status & 3 == 2
725 		 */
726 		if (bus->chipco.dev->id.revision >= 31)
727 			bus->sprom_offset = SSB_SPROM_BASE31;
728 		else if (bus->chip_id == 0x4312 &&
729 			 (bus->chipco.status & 0x03) == 2)
730 			bus->sprom_offset = SSB_SPROM_BASE31;
731 		else
732 			bus->sprom_offset = SSB_SPROM_BASE1;
733 	} else {
734 		bus->sprom_offset = SSB_SPROM_BASE1;
735 	}
736 	ssb_dprintk(KERN_INFO PFX "SPROM offset is 0x%x\n", bus->sprom_offset);
737 
738 	buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL);
739 	if (!buf)
740 		return -ENOMEM;
741 	bus->sprom_size = SSB_SPROMSIZE_WORDS_R123;
742 	sprom_do_read(bus, buf);
743 	err = sprom_check_crc(buf, bus->sprom_size);
744 	if (err) {
745 		/* try for a 440 byte SPROM - revision 4 and higher */
746 		kfree(buf);
747 		buf = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
748 			      GFP_KERNEL);
749 		if (!buf)
750 			return -ENOMEM;
751 		bus->sprom_size = SSB_SPROMSIZE_WORDS_R4;
752 		sprom_do_read(bus, buf);
753 		err = sprom_check_crc(buf, bus->sprom_size);
754 		if (err) {
755 			/* All CRC attempts failed.
756 			 * Maybe there is no SPROM on the device?
757 			 * Now we ask the arch code if there is some sprom
758 			 * available for this device in some other storage */
759 			err = ssb_fill_sprom_with_fallback(bus, sprom);
760 			if (err) {
761 				ssb_printk(KERN_WARNING PFX "WARNING: Using"
762 					   " fallback SPROM failed (err %d)\n",
763 					   err);
764 			} else {
765 				ssb_dprintk(KERN_DEBUG PFX "Using SPROM"
766 					    " revision %d provided by"
767 					    " platform.\n", sprom->revision);
768 				err = 0;
769 				goto out_free;
770 			}
771 			ssb_printk(KERN_WARNING PFX "WARNING: Invalid"
772 				   " SPROM CRC (corrupt SPROM)\n");
773 		}
774 	}
775 	err = sprom_extract(bus, sprom, buf, bus->sprom_size);
776 
777 out_free:
778 	kfree(buf);
779 	return err;
780 }
781 
782 static void ssb_pci_get_boardinfo(struct ssb_bus *bus,
783 				  struct ssb_boardinfo *bi)
784 {
785 	bi->vendor = bus->host_pci->subsystem_vendor;
786 	bi->type = bus->host_pci->subsystem_device;
787 	bi->rev = bus->host_pci->revision;
788 }
789 
790 int ssb_pci_get_invariants(struct ssb_bus *bus,
791 			   struct ssb_init_invariants *iv)
792 {
793 	int err;
794 
795 	err = ssb_pci_sprom_get(bus, &iv->sprom);
796 	if (err)
797 		goto out;
798 	ssb_pci_get_boardinfo(bus, &iv->boardinfo);
799 
800 out:
801 	return err;
802 }
803 
804 #ifdef CONFIG_SSB_DEBUG
805 static int ssb_pci_assert_buspower(struct ssb_bus *bus)
806 {
807 	if (likely(bus->powered_up))
808 		return 0;
809 
810 	printk(KERN_ERR PFX "FATAL ERROR: Bus powered down "
811 	       "while accessing PCI MMIO space\n");
812 	if (bus->power_warn_count <= 10) {
813 		bus->power_warn_count++;
814 		dump_stack();
815 	}
816 
817 	return -ENODEV;
818 }
819 #else /* DEBUG */
820 static inline int ssb_pci_assert_buspower(struct ssb_bus *bus)
821 {
822 	return 0;
823 }
824 #endif /* DEBUG */
825 
826 static u8 ssb_pci_read8(struct ssb_device *dev, u16 offset)
827 {
828 	struct ssb_bus *bus = dev->bus;
829 
830 	if (unlikely(ssb_pci_assert_buspower(bus)))
831 		return 0xFF;
832 	if (unlikely(bus->mapped_device != dev)) {
833 		if (unlikely(ssb_pci_switch_core(bus, dev)))
834 			return 0xFF;
835 	}
836 	return ioread8(bus->mmio + offset);
837 }
838 
839 static u16 ssb_pci_read16(struct ssb_device *dev, u16 offset)
840 {
841 	struct ssb_bus *bus = dev->bus;
842 
843 	if (unlikely(ssb_pci_assert_buspower(bus)))
844 		return 0xFFFF;
845 	if (unlikely(bus->mapped_device != dev)) {
846 		if (unlikely(ssb_pci_switch_core(bus, dev)))
847 			return 0xFFFF;
848 	}
849 	return ioread16(bus->mmio + offset);
850 }
851 
852 static u32 ssb_pci_read32(struct ssb_device *dev, u16 offset)
853 {
854 	struct ssb_bus *bus = dev->bus;
855 
856 	if (unlikely(ssb_pci_assert_buspower(bus)))
857 		return 0xFFFFFFFF;
858 	if (unlikely(bus->mapped_device != dev)) {
859 		if (unlikely(ssb_pci_switch_core(bus, dev)))
860 			return 0xFFFFFFFF;
861 	}
862 	return ioread32(bus->mmio + offset);
863 }
864 
865 #ifdef CONFIG_SSB_BLOCKIO
866 static void ssb_pci_block_read(struct ssb_device *dev, void *buffer,
867 			       size_t count, u16 offset, u8 reg_width)
868 {
869 	struct ssb_bus *bus = dev->bus;
870 	void __iomem *addr = bus->mmio + offset;
871 
872 	if (unlikely(ssb_pci_assert_buspower(bus)))
873 		goto error;
874 	if (unlikely(bus->mapped_device != dev)) {
875 		if (unlikely(ssb_pci_switch_core(bus, dev)))
876 			goto error;
877 	}
878 	switch (reg_width) {
879 	case sizeof(u8):
880 		ioread8_rep(addr, buffer, count);
881 		break;
882 	case sizeof(u16):
883 		SSB_WARN_ON(count & 1);
884 		ioread16_rep(addr, buffer, count >> 1);
885 		break;
886 	case sizeof(u32):
887 		SSB_WARN_ON(count & 3);
888 		ioread32_rep(addr, buffer, count >> 2);
889 		break;
890 	default:
891 		SSB_WARN_ON(1);
892 	}
893 
894 	return;
895 error:
896 	memset(buffer, 0xFF, count);
897 }
898 #endif /* CONFIG_SSB_BLOCKIO */
899 
900 static void ssb_pci_write8(struct ssb_device *dev, u16 offset, u8 value)
901 {
902 	struct ssb_bus *bus = dev->bus;
903 
904 	if (unlikely(ssb_pci_assert_buspower(bus)))
905 		return;
906 	if (unlikely(bus->mapped_device != dev)) {
907 		if (unlikely(ssb_pci_switch_core(bus, dev)))
908 			return;
909 	}
910 	iowrite8(value, bus->mmio + offset);
911 }
912 
913 static void ssb_pci_write16(struct ssb_device *dev, u16 offset, u16 value)
914 {
915 	struct ssb_bus *bus = dev->bus;
916 
917 	if (unlikely(ssb_pci_assert_buspower(bus)))
918 		return;
919 	if (unlikely(bus->mapped_device != dev)) {
920 		if (unlikely(ssb_pci_switch_core(bus, dev)))
921 			return;
922 	}
923 	iowrite16(value, bus->mmio + offset);
924 }
925 
926 static void ssb_pci_write32(struct ssb_device *dev, u16 offset, u32 value)
927 {
928 	struct ssb_bus *bus = dev->bus;
929 
930 	if (unlikely(ssb_pci_assert_buspower(bus)))
931 		return;
932 	if (unlikely(bus->mapped_device != dev)) {
933 		if (unlikely(ssb_pci_switch_core(bus, dev)))
934 			return;
935 	}
936 	iowrite32(value, bus->mmio + offset);
937 }
938 
939 #ifdef CONFIG_SSB_BLOCKIO
940 static void ssb_pci_block_write(struct ssb_device *dev, const void *buffer,
941 				size_t count, u16 offset, u8 reg_width)
942 {
943 	struct ssb_bus *bus = dev->bus;
944 	void __iomem *addr = bus->mmio + offset;
945 
946 	if (unlikely(ssb_pci_assert_buspower(bus)))
947 		return;
948 	if (unlikely(bus->mapped_device != dev)) {
949 		if (unlikely(ssb_pci_switch_core(bus, dev)))
950 			return;
951 	}
952 	switch (reg_width) {
953 	case sizeof(u8):
954 		iowrite8_rep(addr, buffer, count);
955 		break;
956 	case sizeof(u16):
957 		SSB_WARN_ON(count & 1);
958 		iowrite16_rep(addr, buffer, count >> 1);
959 		break;
960 	case sizeof(u32):
961 		SSB_WARN_ON(count & 3);
962 		iowrite32_rep(addr, buffer, count >> 2);
963 		break;
964 	default:
965 		SSB_WARN_ON(1);
966 	}
967 }
968 #endif /* CONFIG_SSB_BLOCKIO */
969 
970 /* Not "static", as it's used in main.c */
971 const struct ssb_bus_ops ssb_pci_ops = {
972 	.read8		= ssb_pci_read8,
973 	.read16		= ssb_pci_read16,
974 	.read32		= ssb_pci_read32,
975 	.write8		= ssb_pci_write8,
976 	.write16	= ssb_pci_write16,
977 	.write32	= ssb_pci_write32,
978 #ifdef CONFIG_SSB_BLOCKIO
979 	.block_read	= ssb_pci_block_read,
980 	.block_write	= ssb_pci_block_write,
981 #endif
982 };
983 
984 static ssize_t ssb_pci_attr_sprom_show(struct device *pcidev,
985 				       struct device_attribute *attr,
986 				       char *buf)
987 {
988 	struct pci_dev *pdev = container_of(pcidev, struct pci_dev, dev);
989 	struct ssb_bus *bus;
990 
991 	bus = ssb_pci_dev_to_bus(pdev);
992 	if (!bus)
993 		return -ENODEV;
994 
995 	return ssb_attr_sprom_show(bus, buf, sprom_do_read);
996 }
997 
998 static ssize_t ssb_pci_attr_sprom_store(struct device *pcidev,
999 					struct device_attribute *attr,
1000 					const char *buf, size_t count)
1001 {
1002 	struct pci_dev *pdev = container_of(pcidev, struct pci_dev, dev);
1003 	struct ssb_bus *bus;
1004 
1005 	bus = ssb_pci_dev_to_bus(pdev);
1006 	if (!bus)
1007 		return -ENODEV;
1008 
1009 	return ssb_attr_sprom_store(bus, buf, count,
1010 				    sprom_check_crc, sprom_do_write);
1011 }
1012 
1013 static DEVICE_ATTR(ssb_sprom, 0600,
1014 		   ssb_pci_attr_sprom_show,
1015 		   ssb_pci_attr_sprom_store);
1016 
1017 void ssb_pci_exit(struct ssb_bus *bus)
1018 {
1019 	struct pci_dev *pdev;
1020 
1021 	if (bus->bustype != SSB_BUSTYPE_PCI)
1022 		return;
1023 
1024 	pdev = bus->host_pci;
1025 	device_remove_file(&pdev->dev, &dev_attr_ssb_sprom);
1026 }
1027 
1028 int ssb_pci_init(struct ssb_bus *bus)
1029 {
1030 	struct pci_dev *pdev;
1031 	int err;
1032 
1033 	if (bus->bustype != SSB_BUSTYPE_PCI)
1034 		return 0;
1035 
1036 	pdev = bus->host_pci;
1037 	mutex_init(&bus->sprom_mutex);
1038 	err = device_create_file(&pdev->dev, &dev_attr_ssb_sprom);
1039 	if (err)
1040 		goto out;
1041 
1042 out:
1043 	return err;
1044 }
1045