xref: /openbmc/linux/drivers/ssb/pci.c (revision 6daf4321)
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 sprom_extract_antgain(u8 sprom_revision, const u16 *in, u16 offset,
330 				u16 mask, u16 shift)
331 {
332 	u16 v;
333 	u8 gain;
334 
335 	v = in[SPOFF(offset)];
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 = sprom_extract_antgain(out->revision, in,
420 						     SSB_SPROM1_AGAIN,
421 						     SSB_SPROM1_AGAIN_BG,
422 						     SSB_SPROM1_AGAIN_BG_SHIFT);
423 	out->antenna_gain.a1 = sprom_extract_antgain(out->revision, in,
424 						     SSB_SPROM1_AGAIN,
425 						     SSB_SPROM1_AGAIN_A,
426 						     SSB_SPROM1_AGAIN_A_SHIFT);
427 	if (out->revision >= 2)
428 		sprom_extract_r23(out, in);
429 }
430 
431 /* Revs 4 5 and 8 have partially shared layout */
432 static void sprom_extract_r458(struct ssb_sprom *out, const u16 *in)
433 {
434 	SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01,
435 	     SSB_SPROM4_TXPID2G0, SSB_SPROM4_TXPID2G0_SHIFT);
436 	SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01,
437 	     SSB_SPROM4_TXPID2G1, SSB_SPROM4_TXPID2G1_SHIFT);
438 	SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23,
439 	     SSB_SPROM4_TXPID2G2, SSB_SPROM4_TXPID2G2_SHIFT);
440 	SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23,
441 	     SSB_SPROM4_TXPID2G3, SSB_SPROM4_TXPID2G3_SHIFT);
442 
443 	SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01,
444 	     SSB_SPROM4_TXPID5GL0, SSB_SPROM4_TXPID5GL0_SHIFT);
445 	SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01,
446 	     SSB_SPROM4_TXPID5GL1, SSB_SPROM4_TXPID5GL1_SHIFT);
447 	SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23,
448 	     SSB_SPROM4_TXPID5GL2, SSB_SPROM4_TXPID5GL2_SHIFT);
449 	SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23,
450 	     SSB_SPROM4_TXPID5GL3, SSB_SPROM4_TXPID5GL3_SHIFT);
451 
452 	SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01,
453 	     SSB_SPROM4_TXPID5G0, SSB_SPROM4_TXPID5G0_SHIFT);
454 	SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01,
455 	     SSB_SPROM4_TXPID5G1, SSB_SPROM4_TXPID5G1_SHIFT);
456 	SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23,
457 	     SSB_SPROM4_TXPID5G2, SSB_SPROM4_TXPID5G2_SHIFT);
458 	SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23,
459 	     SSB_SPROM4_TXPID5G3, SSB_SPROM4_TXPID5G3_SHIFT);
460 
461 	SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01,
462 	     SSB_SPROM4_TXPID5GH0, SSB_SPROM4_TXPID5GH0_SHIFT);
463 	SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01,
464 	     SSB_SPROM4_TXPID5GH1, SSB_SPROM4_TXPID5GH1_SHIFT);
465 	SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23,
466 	     SSB_SPROM4_TXPID5GH2, SSB_SPROM4_TXPID5GH2_SHIFT);
467 	SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23,
468 	     SSB_SPROM4_TXPID5GH3, SSB_SPROM4_TXPID5GH3_SHIFT);
469 }
470 
471 static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
472 {
473 	u16 il0mac_offset;
474 
475 	if (out->revision == 4)
476 		il0mac_offset = SSB_SPROM4_IL0MAC;
477 	else
478 		il0mac_offset = SSB_SPROM5_IL0MAC;
479 
480 	sprom_get_mac(out->il0mac, &in[SPOFF(il0mac_offset)]);
481 
482 	SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0);
483 	SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A,
484 	     SSB_SPROM4_ETHPHY_ET1A_SHIFT);
485 	SPEX(board_rev, SSB_SPROM4_BOARDREV, 0xFFFF, 0);
486 	SPEX(board_type, SSB_SPROM1_SPID, 0xFFFF, 0);
487 	if (out->revision == 4) {
488 		SPEX(alpha2[0], SSB_SPROM4_CCODE, 0xff00, 8);
489 		SPEX(alpha2[1], SSB_SPROM4_CCODE, 0x00ff, 0);
490 		SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0);
491 		SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0);
492 		SPEX(boardflags2_lo, SSB_SPROM4_BFL2LO, 0xFFFF, 0);
493 		SPEX(boardflags2_hi, SSB_SPROM4_BFL2HI, 0xFFFF, 0);
494 	} else {
495 		SPEX(alpha2[0], SSB_SPROM5_CCODE, 0xff00, 8);
496 		SPEX(alpha2[1], SSB_SPROM5_CCODE, 0x00ff, 0);
497 		SPEX(boardflags_lo, SSB_SPROM5_BFLLO, 0xFFFF, 0);
498 		SPEX(boardflags_hi, SSB_SPROM5_BFLHI, 0xFFFF, 0);
499 		SPEX(boardflags2_lo, SSB_SPROM5_BFL2LO, 0xFFFF, 0);
500 		SPEX(boardflags2_hi, SSB_SPROM5_BFL2HI, 0xFFFF, 0);
501 	}
502 	SPEX(ant_available_a, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_A,
503 	     SSB_SPROM4_ANTAVAIL_A_SHIFT);
504 	SPEX(ant_available_bg, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_BG,
505 	     SSB_SPROM4_ANTAVAIL_BG_SHIFT);
506 	SPEX(maxpwr_bg, SSB_SPROM4_MAXP_BG, SSB_SPROM4_MAXP_BG_MASK, 0);
507 	SPEX(itssi_bg, SSB_SPROM4_MAXP_BG, SSB_SPROM4_ITSSI_BG,
508 	     SSB_SPROM4_ITSSI_BG_SHIFT);
509 	SPEX(maxpwr_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_MAXP_A_MASK, 0);
510 	SPEX(itssi_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_ITSSI_A,
511 	     SSB_SPROM4_ITSSI_A_SHIFT);
512 	if (out->revision == 4) {
513 		SPEX(gpio0, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P0, 0);
514 		SPEX(gpio1, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P1,
515 		     SSB_SPROM4_GPIOA_P1_SHIFT);
516 		SPEX(gpio2, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P2, 0);
517 		SPEX(gpio3, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P3,
518 		     SSB_SPROM4_GPIOB_P3_SHIFT);
519 	} else {
520 		SPEX(gpio0, SSB_SPROM5_GPIOA, SSB_SPROM5_GPIOA_P0, 0);
521 		SPEX(gpio1, SSB_SPROM5_GPIOA, SSB_SPROM5_GPIOA_P1,
522 		     SSB_SPROM5_GPIOA_P1_SHIFT);
523 		SPEX(gpio2, SSB_SPROM5_GPIOB, SSB_SPROM5_GPIOB_P2, 0);
524 		SPEX(gpio3, SSB_SPROM5_GPIOB, SSB_SPROM5_GPIOB_P3,
525 		     SSB_SPROM5_GPIOB_P3_SHIFT);
526 	}
527 
528 	/* Extract the antenna gain values. */
529 	out->antenna_gain.a0 = sprom_extract_antgain(out->revision, in,
530 						     SSB_SPROM4_AGAIN01,
531 						     SSB_SPROM4_AGAIN0,
532 						     SSB_SPROM4_AGAIN0_SHIFT);
533 	out->antenna_gain.a1 = sprom_extract_antgain(out->revision, in,
534 						     SSB_SPROM4_AGAIN01,
535 						     SSB_SPROM4_AGAIN1,
536 						     SSB_SPROM4_AGAIN1_SHIFT);
537 	out->antenna_gain.a2 = sprom_extract_antgain(out->revision, in,
538 						     SSB_SPROM4_AGAIN23,
539 						     SSB_SPROM4_AGAIN2,
540 						     SSB_SPROM4_AGAIN2_SHIFT);
541 	out->antenna_gain.a3 = sprom_extract_antgain(out->revision, in,
542 						     SSB_SPROM4_AGAIN23,
543 						     SSB_SPROM4_AGAIN3,
544 						     SSB_SPROM4_AGAIN3_SHIFT);
545 
546 	sprom_extract_r458(out, in);
547 
548 	/* TODO - get remaining rev 4 stuff needed */
549 }
550 
551 static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
552 {
553 	int i;
554 	u16 o;
555 	u16 pwr_info_offset[] = {
556 		SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1,
557 		SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3
558 	};
559 	BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
560 			ARRAY_SIZE(out->core_pwr_info));
561 
562 	/* extract the MAC address */
563 	sprom_get_mac(out->il0mac, &in[SPOFF(SSB_SPROM8_IL0MAC)]);
564 
565 	SPEX(board_rev, SSB_SPROM8_BOARDREV, 0xFFFF, 0);
566 	SPEX(board_type, SSB_SPROM1_SPID, 0xFFFF, 0);
567 	SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8);
568 	SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0);
569 	SPEX(boardflags_lo, SSB_SPROM8_BFLLO, 0xFFFF, 0);
570 	SPEX(boardflags_hi, SSB_SPROM8_BFLHI, 0xFFFF, 0);
571 	SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, 0xFFFF, 0);
572 	SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, 0xFFFF, 0);
573 	SPEX(ant_available_a, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_A,
574 	     SSB_SPROM8_ANTAVAIL_A_SHIFT);
575 	SPEX(ant_available_bg, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_BG,
576 	     SSB_SPROM8_ANTAVAIL_BG_SHIFT);
577 	SPEX(maxpwr_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_MAXP_BG_MASK, 0);
578 	SPEX(itssi_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_ITSSI_BG,
579 	     SSB_SPROM8_ITSSI_BG_SHIFT);
580 	SPEX(maxpwr_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_MAXP_A_MASK, 0);
581 	SPEX(itssi_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_ITSSI_A,
582 	     SSB_SPROM8_ITSSI_A_SHIFT);
583 	SPEX(maxpwr_ah, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AH_MASK, 0);
584 	SPEX(maxpwr_al, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AL_MASK,
585 	     SSB_SPROM8_MAXP_AL_SHIFT);
586 	SPEX(gpio0, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P0, 0);
587 	SPEX(gpio1, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P1,
588 	     SSB_SPROM8_GPIOA_P1_SHIFT);
589 	SPEX(gpio2, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P2, 0);
590 	SPEX(gpio3, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P3,
591 	     SSB_SPROM8_GPIOB_P3_SHIFT);
592 	SPEX(tri2g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI2G, 0);
593 	SPEX(tri5g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI5G,
594 	     SSB_SPROM8_TRI5G_SHIFT);
595 	SPEX(tri5gl, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GL, 0);
596 	SPEX(tri5gh, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GH,
597 	     SSB_SPROM8_TRI5GH_SHIFT);
598 	SPEX(rxpo2g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO2G, 0);
599 	SPEX(rxpo5g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO5G,
600 	     SSB_SPROM8_RXPO5G_SHIFT);
601 	SPEX(rssismf2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMF2G, 0);
602 	SPEX(rssismc2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMC2G,
603 	     SSB_SPROM8_RSSISMC2G_SHIFT);
604 	SPEX(rssisav2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISAV2G,
605 	     SSB_SPROM8_RSSISAV2G_SHIFT);
606 	SPEX(bxa2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_BXA2G,
607 	     SSB_SPROM8_BXA2G_SHIFT);
608 	SPEX(rssismf5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMF5G, 0);
609 	SPEX(rssismc5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMC5G,
610 	     SSB_SPROM8_RSSISMC5G_SHIFT);
611 	SPEX(rssisav5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISAV5G,
612 	     SSB_SPROM8_RSSISAV5G_SHIFT);
613 	SPEX(bxa5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_BXA5G,
614 	     SSB_SPROM8_BXA5G_SHIFT);
615 	SPEX(pa0b0, SSB_SPROM8_PA0B0, 0xFFFF, 0);
616 	SPEX(pa0b1, SSB_SPROM8_PA0B1, 0xFFFF, 0);
617 	SPEX(pa0b2, SSB_SPROM8_PA0B2, 0xFFFF, 0);
618 	SPEX(pa1b0, SSB_SPROM8_PA1B0, 0xFFFF, 0);
619 	SPEX(pa1b1, SSB_SPROM8_PA1B1, 0xFFFF, 0);
620 	SPEX(pa1b2, SSB_SPROM8_PA1B2, 0xFFFF, 0);
621 	SPEX(pa1lob0, SSB_SPROM8_PA1LOB0, 0xFFFF, 0);
622 	SPEX(pa1lob1, SSB_SPROM8_PA1LOB1, 0xFFFF, 0);
623 	SPEX(pa1lob2, SSB_SPROM8_PA1LOB2, 0xFFFF, 0);
624 	SPEX(pa1hib0, SSB_SPROM8_PA1HIB0, 0xFFFF, 0);
625 	SPEX(pa1hib1, SSB_SPROM8_PA1HIB1, 0xFFFF, 0);
626 	SPEX(pa1hib2, SSB_SPROM8_PA1HIB2, 0xFFFF, 0);
627 	SPEX(cck2gpo, SSB_SPROM8_CCK2GPO, 0xFFFF, 0);
628 	SPEX32(ofdm2gpo, SSB_SPROM8_OFDM2GPO, 0xFFFFFFFF, 0);
629 	SPEX32(ofdm5glpo, SSB_SPROM8_OFDM5GLPO, 0xFFFFFFFF, 0);
630 	SPEX32(ofdm5gpo, SSB_SPROM8_OFDM5GPO, 0xFFFFFFFF, 0);
631 	SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0);
632 
633 	/* Extract the antenna gain values. */
634 	out->antenna_gain.a0 = sprom_extract_antgain(out->revision, in,
635 						     SSB_SPROM8_AGAIN01,
636 						     SSB_SPROM8_AGAIN0,
637 						     SSB_SPROM8_AGAIN0_SHIFT);
638 	out->antenna_gain.a1 = sprom_extract_antgain(out->revision, in,
639 						     SSB_SPROM8_AGAIN01,
640 						     SSB_SPROM8_AGAIN1,
641 						     SSB_SPROM8_AGAIN1_SHIFT);
642 	out->antenna_gain.a2 = sprom_extract_antgain(out->revision, in,
643 						     SSB_SPROM8_AGAIN23,
644 						     SSB_SPROM8_AGAIN2,
645 						     SSB_SPROM8_AGAIN2_SHIFT);
646 	out->antenna_gain.a3 = sprom_extract_antgain(out->revision, in,
647 						     SSB_SPROM8_AGAIN23,
648 						     SSB_SPROM8_AGAIN3,
649 						     SSB_SPROM8_AGAIN3_SHIFT);
650 
651 	/* Extract cores power info info */
652 	for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
653 		o = pwr_info_offset[i];
654 		SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
655 			SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT);
656 		SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
657 			SSB_SPROM8_2G_MAXP, 0);
658 
659 		SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0);
660 		SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0);
661 		SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0);
662 
663 		SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
664 			SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT);
665 		SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
666 			SSB_SPROM8_5G_MAXP, 0);
667 		SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP,
668 			SSB_SPROM8_5GH_MAXP, 0);
669 		SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP,
670 			SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT);
671 
672 		SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0);
673 		SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0);
674 		SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0);
675 		SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0);
676 		SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0);
677 		SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0);
678 		SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0);
679 		SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0);
680 		SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0);
681 	}
682 
683 	/* Extract FEM info */
684 	SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G,
685 		SSB_SROM8_FEM_TSSIPOS, SSB_SROM8_FEM_TSSIPOS_SHIFT);
686 	SPEX(fem.ghz2.extpa_gain, SSB_SPROM8_FEM2G,
687 		SSB_SROM8_FEM_EXTPA_GAIN, SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
688 	SPEX(fem.ghz2.pdet_range, SSB_SPROM8_FEM2G,
689 		SSB_SROM8_FEM_PDET_RANGE, SSB_SROM8_FEM_PDET_RANGE_SHIFT);
690 	SPEX(fem.ghz2.tr_iso, SSB_SPROM8_FEM2G,
691 		SSB_SROM8_FEM_TR_ISO, SSB_SROM8_FEM_TR_ISO_SHIFT);
692 	SPEX(fem.ghz2.antswlut, SSB_SPROM8_FEM2G,
693 		SSB_SROM8_FEM_ANTSWLUT, SSB_SROM8_FEM_ANTSWLUT_SHIFT);
694 
695 	SPEX(fem.ghz5.tssipos, SSB_SPROM8_FEM5G,
696 		SSB_SROM8_FEM_TSSIPOS, SSB_SROM8_FEM_TSSIPOS_SHIFT);
697 	SPEX(fem.ghz5.extpa_gain, SSB_SPROM8_FEM5G,
698 		SSB_SROM8_FEM_EXTPA_GAIN, SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
699 	SPEX(fem.ghz5.pdet_range, SSB_SPROM8_FEM5G,
700 		SSB_SROM8_FEM_PDET_RANGE, SSB_SROM8_FEM_PDET_RANGE_SHIFT);
701 	SPEX(fem.ghz5.tr_iso, SSB_SPROM8_FEM5G,
702 		SSB_SROM8_FEM_TR_ISO, SSB_SROM8_FEM_TR_ISO_SHIFT);
703 	SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G,
704 		SSB_SROM8_FEM_ANTSWLUT, SSB_SROM8_FEM_ANTSWLUT_SHIFT);
705 
706 	SPEX(leddc_on_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_ON,
707 	     SSB_SPROM8_LEDDC_ON_SHIFT);
708 	SPEX(leddc_off_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_OFF,
709 	     SSB_SPROM8_LEDDC_OFF_SHIFT);
710 
711 	SPEX(txchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_TXCHAIN,
712 	     SSB_SPROM8_TXRXC_TXCHAIN_SHIFT);
713 	SPEX(rxchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_RXCHAIN,
714 	     SSB_SPROM8_TXRXC_RXCHAIN_SHIFT);
715 	SPEX(antswitch, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_SWITCH,
716 	     SSB_SPROM8_TXRXC_SWITCH_SHIFT);
717 
718 	SPEX(opo, SSB_SPROM8_OFDM2GPO, 0x00ff, 0);
719 
720 	SPEX_ARRAY8(mcs2gpo, SSB_SPROM8_2G_MCSPO, ~0, 0);
721 	SPEX_ARRAY8(mcs5gpo, SSB_SPROM8_5G_MCSPO, ~0, 0);
722 	SPEX_ARRAY8(mcs5glpo, SSB_SPROM8_5GL_MCSPO, ~0, 0);
723 	SPEX_ARRAY8(mcs5ghpo, SSB_SPROM8_5GH_MCSPO, ~0, 0);
724 
725 	SPEX(rawtempsense, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_RAWTEMP,
726 	     SSB_SPROM8_RAWTS_RAWTEMP_SHIFT);
727 	SPEX(measpower, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_MEASPOWER,
728 	     SSB_SPROM8_RAWTS_MEASPOWER_SHIFT);
729 	SPEX(tempsense_slope, SSB_SPROM8_OPT_CORRX,
730 	     SSB_SPROM8_OPT_CORRX_TEMP_SLOPE,
731 	     SSB_SPROM8_OPT_CORRX_TEMP_SLOPE_SHIFT);
732 	SPEX(tempcorrx, SSB_SPROM8_OPT_CORRX, SSB_SPROM8_OPT_CORRX_TEMPCORRX,
733 	     SSB_SPROM8_OPT_CORRX_TEMPCORRX_SHIFT);
734 	SPEX(tempsense_option, SSB_SPROM8_OPT_CORRX,
735 	     SSB_SPROM8_OPT_CORRX_TEMP_OPTION,
736 	     SSB_SPROM8_OPT_CORRX_TEMP_OPTION_SHIFT);
737 	SPEX(freqoffset_corr, SSB_SPROM8_HWIQ_IQSWP,
738 	     SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR,
739 	     SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR_SHIFT);
740 	SPEX(iqcal_swp_dis, SSB_SPROM8_HWIQ_IQSWP,
741 	     SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP,
742 	     SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP_SHIFT);
743 	SPEX(hw_iqcal_en, SSB_SPROM8_HWIQ_IQSWP, SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL,
744 	     SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL_SHIFT);
745 
746 	SPEX(bw40po, SSB_SPROM8_BW40PO, ~0, 0);
747 	SPEX(cddpo, SSB_SPROM8_CDDPO, ~0, 0);
748 	SPEX(stbcpo, SSB_SPROM8_STBCPO, ~0, 0);
749 	SPEX(bwduppo, SSB_SPROM8_BWDUPPO, ~0, 0);
750 
751 	SPEX(tempthresh, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_TRESH,
752 	     SSB_SPROM8_THERMAL_TRESH_SHIFT);
753 	SPEX(tempoffset, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_OFFSET,
754 	     SSB_SPROM8_THERMAL_OFFSET_SHIFT);
755 	SPEX(phycal_tempdelta, SSB_SPROM8_TEMPDELTA,
756 	     SSB_SPROM8_TEMPDELTA_PHYCAL,
757 	     SSB_SPROM8_TEMPDELTA_PHYCAL_SHIFT);
758 	SPEX(temps_period, SSB_SPROM8_TEMPDELTA, SSB_SPROM8_TEMPDELTA_PERIOD,
759 	     SSB_SPROM8_TEMPDELTA_PERIOD_SHIFT);
760 	SPEX(temps_hysteresis, SSB_SPROM8_TEMPDELTA,
761 	     SSB_SPROM8_TEMPDELTA_HYSTERESIS,
762 	     SSB_SPROM8_TEMPDELTA_HYSTERESIS_SHIFT);
763 	sprom_extract_r458(out, in);
764 
765 	/* TODO - get remaining rev 8 stuff needed */
766 }
767 
768 static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out,
769 			 const u16 *in, u16 size)
770 {
771 	memset(out, 0, sizeof(*out));
772 
773 	out->revision = in[size - 1] & 0x00FF;
774 	ssb_dbg("SPROM revision %d detected\n", out->revision);
775 	memset(out->et0mac, 0xFF, 6);		/* preset et0 and et1 mac */
776 	memset(out->et1mac, 0xFF, 6);
777 
778 	if ((bus->chip_id & 0xFF00) == 0x4400) {
779 		/* Workaround: The BCM44XX chip has a stupid revision
780 		 * number stored in the SPROM.
781 		 * Always extract r1. */
782 		out->revision = 1;
783 		ssb_dbg("SPROM treated as revision %d\n", out->revision);
784 	}
785 
786 	switch (out->revision) {
787 	case 1:
788 	case 2:
789 	case 3:
790 		sprom_extract_r123(out, in);
791 		break;
792 	case 4:
793 	case 5:
794 		sprom_extract_r45(out, in);
795 		break;
796 	case 8:
797 		sprom_extract_r8(out, in);
798 		break;
799 	default:
800 		ssb_warn("Unsupported SPROM revision %d detected. Will extract v1\n",
801 			 out->revision);
802 		out->revision = 1;
803 		sprom_extract_r123(out, in);
804 	}
805 
806 	if (out->boardflags_lo == 0xFFFF)
807 		out->boardflags_lo = 0;  /* per specs */
808 	if (out->boardflags_hi == 0xFFFF)
809 		out->boardflags_hi = 0;  /* per specs */
810 
811 	return 0;
812 }
813 
814 static int ssb_pci_sprom_get(struct ssb_bus *bus,
815 			     struct ssb_sprom *sprom)
816 {
817 	int err;
818 	u16 *buf;
819 
820 	if (!ssb_is_sprom_available(bus)) {
821 		ssb_err("No SPROM available!\n");
822 		return -ENODEV;
823 	}
824 	if (bus->chipco.dev) {	/* can be unavailable! */
825 		/*
826 		 * get SPROM offset: SSB_SPROM_BASE1 except for
827 		 * chipcommon rev >= 31 or chip ID is 0x4312 and
828 		 * chipcommon status & 3 == 2
829 		 */
830 		if (bus->chipco.dev->id.revision >= 31)
831 			bus->sprom_offset = SSB_SPROM_BASE31;
832 		else if (bus->chip_id == 0x4312 &&
833 			 (bus->chipco.status & 0x03) == 2)
834 			bus->sprom_offset = SSB_SPROM_BASE31;
835 		else
836 			bus->sprom_offset = SSB_SPROM_BASE1;
837 	} else {
838 		bus->sprom_offset = SSB_SPROM_BASE1;
839 	}
840 	ssb_dbg("SPROM offset is 0x%x\n", bus->sprom_offset);
841 
842 	buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL);
843 	if (!buf)
844 		return -ENOMEM;
845 	bus->sprom_size = SSB_SPROMSIZE_WORDS_R123;
846 	sprom_do_read(bus, buf);
847 	err = sprom_check_crc(buf, bus->sprom_size);
848 	if (err) {
849 		/* try for a 440 byte SPROM - revision 4 and higher */
850 		kfree(buf);
851 		buf = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
852 			      GFP_KERNEL);
853 		if (!buf)
854 			return -ENOMEM;
855 		bus->sprom_size = SSB_SPROMSIZE_WORDS_R4;
856 		sprom_do_read(bus, buf);
857 		err = sprom_check_crc(buf, bus->sprom_size);
858 		if (err) {
859 			/* All CRC attempts failed.
860 			 * Maybe there is no SPROM on the device?
861 			 * Now we ask the arch code if there is some sprom
862 			 * available for this device in some other storage */
863 			err = ssb_fill_sprom_with_fallback(bus, sprom);
864 			if (err) {
865 				ssb_warn("WARNING: Using fallback SPROM failed (err %d)\n",
866 					 err);
867 			} else {
868 				ssb_dbg("Using SPROM revision %d provided by platform\n",
869 					sprom->revision);
870 				err = 0;
871 				goto out_free;
872 			}
873 			ssb_warn("WARNING: Invalid SPROM CRC (corrupt SPROM)\n");
874 		}
875 	}
876 	err = sprom_extract(bus, sprom, buf, bus->sprom_size);
877 
878 out_free:
879 	kfree(buf);
880 	return err;
881 }
882 
883 static void ssb_pci_get_boardinfo(struct ssb_bus *bus,
884 				  struct ssb_boardinfo *bi)
885 {
886 	bi->vendor = bus->host_pci->subsystem_vendor;
887 	bi->type = bus->host_pci->subsystem_device;
888 }
889 
890 int ssb_pci_get_invariants(struct ssb_bus *bus,
891 			   struct ssb_init_invariants *iv)
892 {
893 	int err;
894 
895 	err = ssb_pci_sprom_get(bus, &iv->sprom);
896 	if (err)
897 		goto out;
898 	ssb_pci_get_boardinfo(bus, &iv->boardinfo);
899 
900 out:
901 	return err;
902 }
903 
904 #ifdef CONFIG_SSB_DEBUG
905 static int ssb_pci_assert_buspower(struct ssb_bus *bus)
906 {
907 	if (likely(bus->powered_up))
908 		return 0;
909 
910 	printk(KERN_ERR PFX "FATAL ERROR: Bus powered down "
911 	       "while accessing PCI MMIO space\n");
912 	if (bus->power_warn_count <= 10) {
913 		bus->power_warn_count++;
914 		dump_stack();
915 	}
916 
917 	return -ENODEV;
918 }
919 #else /* DEBUG */
920 static inline int ssb_pci_assert_buspower(struct ssb_bus *bus)
921 {
922 	return 0;
923 }
924 #endif /* DEBUG */
925 
926 static u8 ssb_pci_read8(struct ssb_device *dev, u16 offset)
927 {
928 	struct ssb_bus *bus = dev->bus;
929 
930 	if (unlikely(ssb_pci_assert_buspower(bus)))
931 		return 0xFF;
932 	if (unlikely(bus->mapped_device != dev)) {
933 		if (unlikely(ssb_pci_switch_core(bus, dev)))
934 			return 0xFF;
935 	}
936 	return ioread8(bus->mmio + offset);
937 }
938 
939 static u16 ssb_pci_read16(struct ssb_device *dev, u16 offset)
940 {
941 	struct ssb_bus *bus = dev->bus;
942 
943 	if (unlikely(ssb_pci_assert_buspower(bus)))
944 		return 0xFFFF;
945 	if (unlikely(bus->mapped_device != dev)) {
946 		if (unlikely(ssb_pci_switch_core(bus, dev)))
947 			return 0xFFFF;
948 	}
949 	return ioread16(bus->mmio + offset);
950 }
951 
952 static u32 ssb_pci_read32(struct ssb_device *dev, u16 offset)
953 {
954 	struct ssb_bus *bus = dev->bus;
955 
956 	if (unlikely(ssb_pci_assert_buspower(bus)))
957 		return 0xFFFFFFFF;
958 	if (unlikely(bus->mapped_device != dev)) {
959 		if (unlikely(ssb_pci_switch_core(bus, dev)))
960 			return 0xFFFFFFFF;
961 	}
962 	return ioread32(bus->mmio + offset);
963 }
964 
965 #ifdef CONFIG_SSB_BLOCKIO
966 static void ssb_pci_block_read(struct ssb_device *dev, void *buffer,
967 			       size_t count, u16 offset, u8 reg_width)
968 {
969 	struct ssb_bus *bus = dev->bus;
970 	void __iomem *addr = bus->mmio + offset;
971 
972 	if (unlikely(ssb_pci_assert_buspower(bus)))
973 		goto error;
974 	if (unlikely(bus->mapped_device != dev)) {
975 		if (unlikely(ssb_pci_switch_core(bus, dev)))
976 			goto error;
977 	}
978 	switch (reg_width) {
979 	case sizeof(u8):
980 		ioread8_rep(addr, buffer, count);
981 		break;
982 	case sizeof(u16):
983 		SSB_WARN_ON(count & 1);
984 		ioread16_rep(addr, buffer, count >> 1);
985 		break;
986 	case sizeof(u32):
987 		SSB_WARN_ON(count & 3);
988 		ioread32_rep(addr, buffer, count >> 2);
989 		break;
990 	default:
991 		SSB_WARN_ON(1);
992 	}
993 
994 	return;
995 error:
996 	memset(buffer, 0xFF, count);
997 }
998 #endif /* CONFIG_SSB_BLOCKIO */
999 
1000 static void ssb_pci_write8(struct ssb_device *dev, u16 offset, u8 value)
1001 {
1002 	struct ssb_bus *bus = dev->bus;
1003 
1004 	if (unlikely(ssb_pci_assert_buspower(bus)))
1005 		return;
1006 	if (unlikely(bus->mapped_device != dev)) {
1007 		if (unlikely(ssb_pci_switch_core(bus, dev)))
1008 			return;
1009 	}
1010 	iowrite8(value, bus->mmio + offset);
1011 }
1012 
1013 static void ssb_pci_write16(struct ssb_device *dev, u16 offset, u16 value)
1014 {
1015 	struct ssb_bus *bus = dev->bus;
1016 
1017 	if (unlikely(ssb_pci_assert_buspower(bus)))
1018 		return;
1019 	if (unlikely(bus->mapped_device != dev)) {
1020 		if (unlikely(ssb_pci_switch_core(bus, dev)))
1021 			return;
1022 	}
1023 	iowrite16(value, bus->mmio + offset);
1024 }
1025 
1026 static void ssb_pci_write32(struct ssb_device *dev, u16 offset, u32 value)
1027 {
1028 	struct ssb_bus *bus = dev->bus;
1029 
1030 	if (unlikely(ssb_pci_assert_buspower(bus)))
1031 		return;
1032 	if (unlikely(bus->mapped_device != dev)) {
1033 		if (unlikely(ssb_pci_switch_core(bus, dev)))
1034 			return;
1035 	}
1036 	iowrite32(value, bus->mmio + offset);
1037 }
1038 
1039 #ifdef CONFIG_SSB_BLOCKIO
1040 static void ssb_pci_block_write(struct ssb_device *dev, const void *buffer,
1041 				size_t count, u16 offset, u8 reg_width)
1042 {
1043 	struct ssb_bus *bus = dev->bus;
1044 	void __iomem *addr = bus->mmio + offset;
1045 
1046 	if (unlikely(ssb_pci_assert_buspower(bus)))
1047 		return;
1048 	if (unlikely(bus->mapped_device != dev)) {
1049 		if (unlikely(ssb_pci_switch_core(bus, dev)))
1050 			return;
1051 	}
1052 	switch (reg_width) {
1053 	case sizeof(u8):
1054 		iowrite8_rep(addr, buffer, count);
1055 		break;
1056 	case sizeof(u16):
1057 		SSB_WARN_ON(count & 1);
1058 		iowrite16_rep(addr, buffer, count >> 1);
1059 		break;
1060 	case sizeof(u32):
1061 		SSB_WARN_ON(count & 3);
1062 		iowrite32_rep(addr, buffer, count >> 2);
1063 		break;
1064 	default:
1065 		SSB_WARN_ON(1);
1066 	}
1067 }
1068 #endif /* CONFIG_SSB_BLOCKIO */
1069 
1070 /* Not "static", as it's used in main.c */
1071 const struct ssb_bus_ops ssb_pci_ops = {
1072 	.read8		= ssb_pci_read8,
1073 	.read16		= ssb_pci_read16,
1074 	.read32		= ssb_pci_read32,
1075 	.write8		= ssb_pci_write8,
1076 	.write16	= ssb_pci_write16,
1077 	.write32	= ssb_pci_write32,
1078 #ifdef CONFIG_SSB_BLOCKIO
1079 	.block_read	= ssb_pci_block_read,
1080 	.block_write	= ssb_pci_block_write,
1081 #endif
1082 };
1083 
1084 static ssize_t ssb_pci_attr_sprom_show(struct device *pcidev,
1085 				       struct device_attribute *attr,
1086 				       char *buf)
1087 {
1088 	struct pci_dev *pdev = container_of(pcidev, struct pci_dev, dev);
1089 	struct ssb_bus *bus;
1090 
1091 	bus = ssb_pci_dev_to_bus(pdev);
1092 	if (!bus)
1093 		return -ENODEV;
1094 
1095 	return ssb_attr_sprom_show(bus, buf, sprom_do_read);
1096 }
1097 
1098 static ssize_t ssb_pci_attr_sprom_store(struct device *pcidev,
1099 					struct device_attribute *attr,
1100 					const char *buf, size_t count)
1101 {
1102 	struct pci_dev *pdev = container_of(pcidev, struct pci_dev, dev);
1103 	struct ssb_bus *bus;
1104 
1105 	bus = ssb_pci_dev_to_bus(pdev);
1106 	if (!bus)
1107 		return -ENODEV;
1108 
1109 	return ssb_attr_sprom_store(bus, buf, count,
1110 				    sprom_check_crc, sprom_do_write);
1111 }
1112 
1113 static DEVICE_ATTR(ssb_sprom, 0600,
1114 		   ssb_pci_attr_sprom_show,
1115 		   ssb_pci_attr_sprom_store);
1116 
1117 void ssb_pci_exit(struct ssb_bus *bus)
1118 {
1119 	struct pci_dev *pdev;
1120 
1121 	if (bus->bustype != SSB_BUSTYPE_PCI)
1122 		return;
1123 
1124 	pdev = bus->host_pci;
1125 	device_remove_file(&pdev->dev, &dev_attr_ssb_sprom);
1126 }
1127 
1128 int ssb_pci_init(struct ssb_bus *bus)
1129 {
1130 	struct pci_dev *pdev;
1131 	int err;
1132 
1133 	if (bus->bustype != SSB_BUSTYPE_PCI)
1134 		return 0;
1135 
1136 	pdev = bus->host_pci;
1137 	mutex_init(&bus->sprom_mutex);
1138 	err = device_create_file(&pdev->dev, &dev_attr_ssb_sprom);
1139 	if (err)
1140 		goto out;
1141 
1142 out:
1143 	return err;
1144 }
1145