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