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