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