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