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