Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
[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) - 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 }