2
* Sonics Silicon Backplane PCI-Hostbus related functions.
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>
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.
15
* Licensed under the GNU/GPL. See COPYING for details.
18
#include <linux/ssb/ssb.h>
19
#include <linux/ssb/ssb_regs.h>
20
#include <linux/slab.h>
21
#include <linux/pci.h>
22
#include <linux/delay.h>
24
#include "ssb_private.h"
27
/* Define the following to 1 to enable a printk on each coreswitch. */
28
#define SSB_VERBOSE_PCICORESWITCH_DEBUG 0
31
/* Lowlevel coreswitching */
32
int ssb_pci_switch_coreidx(struct ssb_bus *bus, u8 coreidx)
39
err = pci_write_config_dword(bus->host_pci, SSB_BAR0_WIN,
40
(coreidx * SSB_CORE_SIZE)
44
err = pci_read_config_dword(bus->host_pci, SSB_BAR0_WIN,
48
cur_core = (cur_core - SSB_ENUM_BASE)
50
if (cur_core == coreidx)
53
if (attempts++ > SSB_BAR0_MAX_RETRIES)
59
ssb_printk(KERN_ERR PFX "Failed to switch to core %u\n", coreidx);
63
int ssb_pci_switch_core(struct ssb_bus *bus,
64
struct ssb_device *dev)
69
#if SSB_VERBOSE_PCICORESWITCH_DEBUG
70
ssb_printk(KERN_INFO PFX
71
"Switching to %s core, index %d\n",
72
ssb_core_name(dev->id.coreid),
76
spin_lock_irqsave(&bus->bar_lock, flags);
77
err = ssb_pci_switch_coreidx(bus, dev->core_index);
79
bus->mapped_device = dev;
80
spin_unlock_irqrestore(&bus->bar_lock, flags);
85
/* Enable/disable the on board crystal oscillator and/or PLL. */
86
int ssb_pci_xtal(struct ssb_bus *bus, u32 what, int turn_on)
89
u32 in, out, outenable;
92
if (bus->bustype != SSB_BUSTYPE_PCI)
95
err = pci_read_config_dword(bus->host_pci, SSB_GPIO_IN, &in);
98
err = pci_read_config_dword(bus->host_pci, SSB_GPIO_OUT, &out);
101
err = pci_read_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE, &outenable);
108
/* Avoid glitching the clock if GPRS is already using it.
109
* We can't actually read the state of the PLLPD so we infer it
110
* by the value of XTAL_PU which *is* readable via gpioin.
112
if (!(in & SSB_GPIO_XTAL)) {
113
if (what & SSB_GPIO_XTAL) {
114
/* Turn the crystal on */
115
out |= SSB_GPIO_XTAL;
116
if (what & SSB_GPIO_PLL)
118
err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out);
121
err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE,
127
if (what & SSB_GPIO_PLL) {
128
/* Turn the PLL on */
129
out &= ~SSB_GPIO_PLL;
130
err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out);
137
err = pci_read_config_word(bus->host_pci, PCI_STATUS, &pci_status);
140
pci_status &= ~PCI_STATUS_SIG_TARGET_ABORT;
141
err = pci_write_config_word(bus->host_pci, PCI_STATUS, pci_status);
145
if (what & SSB_GPIO_XTAL) {
146
/* Turn the crystal off */
147
out &= ~SSB_GPIO_XTAL;
149
if (what & SSB_GPIO_PLL) {
150
/* Turn the PLL off */
153
err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out);
156
err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE, outenable);
165
printk(KERN_ERR PFX "Error: ssb_pci_xtal() could not access PCI config space!\n");
170
/* Get the word-offset for a SSB_SPROM_XXX define. */
171
#define SPOFF(offset) ((offset) / sizeof(u16))
172
/* Helper to extract some _offset, which is one of the SSB_SPROM_XXX defines. */
173
#define SPEX16(_outvar, _offset, _mask, _shift) \
174
out->_outvar = ((in[SPOFF(_offset)] & (_mask)) >> (_shift))
175
#define SPEX32(_outvar, _offset, _mask, _shift) \
176
out->_outvar = ((((u32)in[SPOFF((_offset)+2)] << 16 | \
177
in[SPOFF(_offset)]) & (_mask)) >> (_shift))
178
#define SPEX(_outvar, _offset, _mask, _shift) \
179
SPEX16(_outvar, _offset, _mask, _shift)
182
static inline u8 ssb_crc8(u8 crc, u8 data)
184
/* Polynomial: x^8 + x^7 + x^6 + x^4 + x^2 + 1 */
185
static const u8 t[] = {
186
0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
187
0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
188
0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
189
0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
190
0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
191
0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
192
0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
193
0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
194
0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
195
0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
196
0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
197
0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
198
0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
199
0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
200
0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
201
0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
202
0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
203
0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
204
0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
205
0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
206
0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
207
0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
208
0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
209
0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
210
0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
211
0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
212
0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
213
0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
214
0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
215
0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
216
0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
217
0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F,
219
return t[crc ^ data];
222
static u8 ssb_sprom_crc(const u16 *sprom, u16 size)
227
for (word = 0; word < size - 1; word++) {
228
crc = ssb_crc8(crc, sprom[word] & 0x00FF);
229
crc = ssb_crc8(crc, (sprom[word] & 0xFF00) >> 8);
231
crc = ssb_crc8(crc, sprom[size - 1] & 0x00FF);
237
static int sprom_check_crc(const u16 *sprom, size_t size)
243
crc = ssb_sprom_crc(sprom, size);
244
tmp = sprom[size - 1] & SSB_SPROM_REVISION_CRC;
245
expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT;
246
if (crc != expected_crc)
252
static int sprom_do_read(struct ssb_bus *bus, u16 *sprom)
256
for (i = 0; i < bus->sprom_size; i++)
257
sprom[i] = ioread16(bus->mmio + bus->sprom_offset + (i * 2));
262
static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom)
264
struct pci_dev *pdev = bus->host_pci;
267
u16 size = bus->sprom_size;
269
ssb_printk(KERN_NOTICE PFX "Writing SPROM. Do NOT turn off the power! Please stand by...\n");
270
err = pci_read_config_dword(pdev, SSB_SPROMCTL, &spromctl);
273
spromctl |= SSB_SPROMCTL_WE;
274
err = pci_write_config_dword(pdev, SSB_SPROMCTL, spromctl);
277
ssb_printk(KERN_NOTICE PFX "[ 0%%");
279
for (i = 0; i < size; i++) {
282
else if (i == size / 2)
284
else if (i == (size * 3) / 4)
288
writew(sprom[i], bus->mmio + bus->sprom_offset + (i * 2));
292
err = pci_read_config_dword(pdev, SSB_SPROMCTL, &spromctl);
295
spromctl &= ~SSB_SPROMCTL_WE;
296
err = pci_write_config_dword(pdev, SSB_SPROMCTL, spromctl);
300
ssb_printk("100%% ]\n");
301
ssb_printk(KERN_NOTICE PFX "SPROM written.\n");
305
ssb_printk(KERN_ERR PFX "Could not access SPROM control register.\n");
309
static s8 r123_extract_antgain(u8 sprom_revision, const u16 *in,
315
v = in[SPOFF(SSB_SPROM1_AGAIN)];
316
gain = (v & mask) >> shift;
318
gain = 2; /* If unset use 2dBm */
319
if (sprom_revision == 1) {
320
/* Convert to Q5.2 */
323
/* Q5.2 Fractional part is stored in 0xC0 */
324
gain = ((gain & 0xC0) >> 6) | ((gain & 0x3F) << 2);
330
static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
337
if (out->revision == 3) /* rev 3 moved MAC */
338
loc[0] = SSB_SPROM3_IL0MAC;
340
loc[0] = SSB_SPROM1_IL0MAC;
341
loc[1] = SSB_SPROM1_ET0MAC;
342
loc[2] = SSB_SPROM1_ET1MAC;
344
for (i = 0; i < 3; i++) {
345
v = in[SPOFF(loc[0]) + i];
346
*(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
348
if (out->revision < 3) { /* only rev 1-2 have et0, et1 */
349
for (i = 0; i < 3; i++) {
350
v = in[SPOFF(loc[1]) + i];
351
*(((__be16 *)out->et0mac) + i) = cpu_to_be16(v);
353
for (i = 0; i < 3; i++) {
354
v = in[SPOFF(loc[2]) + i];
355
*(((__be16 *)out->et1mac) + i) = cpu_to_be16(v);
358
SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0);
359
SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A,
360
SSB_SPROM1_ETHPHY_ET1A_SHIFT);
361
SPEX(et0mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0M, 14);
362
SPEX(et1mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1M, 15);
363
SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0);
364
SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE,
365
SSB_SPROM1_BINF_CCODE_SHIFT);
366
SPEX(ant_available_a, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTA,
367
SSB_SPROM1_BINF_ANTA_SHIFT);
368
SPEX(ant_available_bg, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTBG,
369
SSB_SPROM1_BINF_ANTBG_SHIFT);
370
SPEX(pa0b0, SSB_SPROM1_PA0B0, 0xFFFF, 0);
371
SPEX(pa0b1, SSB_SPROM1_PA0B1, 0xFFFF, 0);
372
SPEX(pa0b2, SSB_SPROM1_PA0B2, 0xFFFF, 0);
373
SPEX(pa1b0, SSB_SPROM1_PA1B0, 0xFFFF, 0);
374
SPEX(pa1b1, SSB_SPROM1_PA1B1, 0xFFFF, 0);
375
SPEX(pa1b2, SSB_SPROM1_PA1B2, 0xFFFF, 0);
376
SPEX(gpio0, SSB_SPROM1_GPIOA, SSB_SPROM1_GPIOA_P0, 0);
377
SPEX(gpio1, SSB_SPROM1_GPIOA, SSB_SPROM1_GPIOA_P1,
378
SSB_SPROM1_GPIOA_P1_SHIFT);
379
SPEX(gpio2, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P2, 0);
380
SPEX(gpio3, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P3,
381
SSB_SPROM1_GPIOB_P3_SHIFT);
382
SPEX(maxpwr_a, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_A,
383
SSB_SPROM1_MAXPWR_A_SHIFT);
384
SPEX(maxpwr_bg, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_BG, 0);
385
SPEX(itssi_a, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_A,
386
SSB_SPROM1_ITSSI_A_SHIFT);
387
SPEX(itssi_bg, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_BG, 0);
388
SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0);
389
if (out->revision >= 2)
390
SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0);
392
/* Extract the antenna gain values. */
393
gain = r123_extract_antgain(out->revision, in,
395
SSB_SPROM1_AGAIN_BG_SHIFT);
396
out->antenna_gain.ghz24.a0 = gain;
397
out->antenna_gain.ghz24.a1 = gain;
398
out->antenna_gain.ghz24.a2 = gain;
399
out->antenna_gain.ghz24.a3 = gain;
400
gain = r123_extract_antgain(out->revision, in,
402
SSB_SPROM1_AGAIN_A_SHIFT);
403
out->antenna_gain.ghz5.a0 = gain;
404
out->antenna_gain.ghz5.a1 = gain;
405
out->antenna_gain.ghz5.a2 = gain;
406
out->antenna_gain.ghz5.a3 = gain;
409
/* Revs 4 5 and 8 have partially shared layout */
410
static void sprom_extract_r458(struct ssb_sprom *out, const u16 *in)
412
SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01,
413
SSB_SPROM4_TXPID2G0, SSB_SPROM4_TXPID2G0_SHIFT);
414
SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01,
415
SSB_SPROM4_TXPID2G1, SSB_SPROM4_TXPID2G1_SHIFT);
416
SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23,
417
SSB_SPROM4_TXPID2G2, SSB_SPROM4_TXPID2G2_SHIFT);
418
SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23,
419
SSB_SPROM4_TXPID2G3, SSB_SPROM4_TXPID2G3_SHIFT);
421
SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01,
422
SSB_SPROM4_TXPID5GL0, SSB_SPROM4_TXPID5GL0_SHIFT);
423
SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01,
424
SSB_SPROM4_TXPID5GL1, SSB_SPROM4_TXPID5GL1_SHIFT);
425
SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23,
426
SSB_SPROM4_TXPID5GL2, SSB_SPROM4_TXPID5GL2_SHIFT);
427
SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23,
428
SSB_SPROM4_TXPID5GL3, SSB_SPROM4_TXPID5GL3_SHIFT);
430
SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01,
431
SSB_SPROM4_TXPID5G0, SSB_SPROM4_TXPID5G0_SHIFT);
432
SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01,
433
SSB_SPROM4_TXPID5G1, SSB_SPROM4_TXPID5G1_SHIFT);
434
SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23,
435
SSB_SPROM4_TXPID5G2, SSB_SPROM4_TXPID5G2_SHIFT);
436
SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23,
437
SSB_SPROM4_TXPID5G3, SSB_SPROM4_TXPID5G3_SHIFT);
439
SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01,
440
SSB_SPROM4_TXPID5GH0, SSB_SPROM4_TXPID5GH0_SHIFT);
441
SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01,
442
SSB_SPROM4_TXPID5GH1, SSB_SPROM4_TXPID5GH1_SHIFT);
443
SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23,
444
SSB_SPROM4_TXPID5GH2, SSB_SPROM4_TXPID5GH2_SHIFT);
445
SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23,
446
SSB_SPROM4_TXPID5GH3, SSB_SPROM4_TXPID5GH3_SHIFT);
449
static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
455
if (out->revision == 4)
456
il0mac_offset = SSB_SPROM4_IL0MAC;
458
il0mac_offset = SSB_SPROM5_IL0MAC;
459
/* extract the MAC address */
460
for (i = 0; i < 3; i++) {
461
v = in[SPOFF(il0mac_offset) + i];
462
*(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
464
SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0);
465
SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A,
466
SSB_SPROM4_ETHPHY_ET1A_SHIFT);
467
if (out->revision == 4) {
468
SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0);
469
SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0);
470
SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0);
471
SPEX(boardflags2_lo, SSB_SPROM4_BFL2LO, 0xFFFF, 0);
472
SPEX(boardflags2_hi, SSB_SPROM4_BFL2HI, 0xFFFF, 0);
474
SPEX(country_code, SSB_SPROM5_CCODE, 0xFFFF, 0);
475
SPEX(boardflags_lo, SSB_SPROM5_BFLLO, 0xFFFF, 0);
476
SPEX(boardflags_hi, SSB_SPROM5_BFLHI, 0xFFFF, 0);
477
SPEX(boardflags2_lo, SSB_SPROM5_BFL2LO, 0xFFFF, 0);
478
SPEX(boardflags2_hi, SSB_SPROM5_BFL2HI, 0xFFFF, 0);
480
SPEX(ant_available_a, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_A,
481
SSB_SPROM4_ANTAVAIL_A_SHIFT);
482
SPEX(ant_available_bg, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_BG,
483
SSB_SPROM4_ANTAVAIL_BG_SHIFT);
484
SPEX(maxpwr_bg, SSB_SPROM4_MAXP_BG, SSB_SPROM4_MAXP_BG_MASK, 0);
485
SPEX(itssi_bg, SSB_SPROM4_MAXP_BG, SSB_SPROM4_ITSSI_BG,
486
SSB_SPROM4_ITSSI_BG_SHIFT);
487
SPEX(maxpwr_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_MAXP_A_MASK, 0);
488
SPEX(itssi_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_ITSSI_A,
489
SSB_SPROM4_ITSSI_A_SHIFT);
490
if (out->revision == 4) {
491
SPEX(gpio0, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P0, 0);
492
SPEX(gpio1, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P1,
493
SSB_SPROM4_GPIOA_P1_SHIFT);
494
SPEX(gpio2, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P2, 0);
495
SPEX(gpio3, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P3,
496
SSB_SPROM4_GPIOB_P3_SHIFT);
498
SPEX(gpio0, SSB_SPROM5_GPIOA, SSB_SPROM5_GPIOA_P0, 0);
499
SPEX(gpio1, SSB_SPROM5_GPIOA, SSB_SPROM5_GPIOA_P1,
500
SSB_SPROM5_GPIOA_P1_SHIFT);
501
SPEX(gpio2, SSB_SPROM5_GPIOB, SSB_SPROM5_GPIOB_P2, 0);
502
SPEX(gpio3, SSB_SPROM5_GPIOB, SSB_SPROM5_GPIOB_P3,
503
SSB_SPROM5_GPIOB_P3_SHIFT);
506
/* Extract the antenna gain values. */
507
SPEX(antenna_gain.ghz24.a0, SSB_SPROM4_AGAIN01,
508
SSB_SPROM4_AGAIN0, SSB_SPROM4_AGAIN0_SHIFT);
509
SPEX(antenna_gain.ghz24.a1, SSB_SPROM4_AGAIN01,
510
SSB_SPROM4_AGAIN1, SSB_SPROM4_AGAIN1_SHIFT);
511
SPEX(antenna_gain.ghz24.a2, SSB_SPROM4_AGAIN23,
512
SSB_SPROM4_AGAIN2, SSB_SPROM4_AGAIN2_SHIFT);
513
SPEX(antenna_gain.ghz24.a3, SSB_SPROM4_AGAIN23,
514
SSB_SPROM4_AGAIN3, SSB_SPROM4_AGAIN3_SHIFT);
515
memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
516
sizeof(out->antenna_gain.ghz5));
518
sprom_extract_r458(out, in);
520
/* TODO - get remaining rev 4 stuff needed */
523
static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
528
/* extract the MAC address */
529
for (i = 0; i < 3; i++) {
530
v = in[SPOFF(SSB_SPROM8_IL0MAC) + i];
531
*(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
533
SPEX(country_code, SSB_SPROM8_CCODE, 0xFFFF, 0);
534
SPEX(boardflags_lo, SSB_SPROM8_BFLLO, 0xFFFF, 0);
535
SPEX(boardflags_hi, SSB_SPROM8_BFLHI, 0xFFFF, 0);
536
SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, 0xFFFF, 0);
537
SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, 0xFFFF, 0);
538
SPEX(ant_available_a, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_A,
539
SSB_SPROM8_ANTAVAIL_A_SHIFT);
540
SPEX(ant_available_bg, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_BG,
541
SSB_SPROM8_ANTAVAIL_BG_SHIFT);
542
SPEX(maxpwr_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_MAXP_BG_MASK, 0);
543
SPEX(itssi_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_ITSSI_BG,
544
SSB_SPROM8_ITSSI_BG_SHIFT);
545
SPEX(maxpwr_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_MAXP_A_MASK, 0);
546
SPEX(itssi_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_ITSSI_A,
547
SSB_SPROM8_ITSSI_A_SHIFT);
548
SPEX(maxpwr_ah, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AH_MASK, 0);
549
SPEX(maxpwr_al, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AL_MASK,
550
SSB_SPROM8_MAXP_AL_SHIFT);
551
SPEX(gpio0, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P0, 0);
552
SPEX(gpio1, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P1,
553
SSB_SPROM8_GPIOA_P1_SHIFT);
554
SPEX(gpio2, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P2, 0);
555
SPEX(gpio3, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P3,
556
SSB_SPROM8_GPIOB_P3_SHIFT);
557
SPEX(tri2g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI2G, 0);
558
SPEX(tri5g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI5G,
559
SSB_SPROM8_TRI5G_SHIFT);
560
SPEX(tri5gl, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GL, 0);
561
SPEX(tri5gh, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GH,
562
SSB_SPROM8_TRI5GH_SHIFT);
563
SPEX(rxpo2g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO2G, 0);
564
SPEX(rxpo5g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO5G,
565
SSB_SPROM8_RXPO5G_SHIFT);
566
SPEX(rssismf2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMF2G, 0);
567
SPEX(rssismc2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMC2G,
568
SSB_SPROM8_RSSISMC2G_SHIFT);
569
SPEX(rssisav2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISAV2G,
570
SSB_SPROM8_RSSISAV2G_SHIFT);
571
SPEX(bxa2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_BXA2G,
572
SSB_SPROM8_BXA2G_SHIFT);
573
SPEX(rssismf5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMF5G, 0);
574
SPEX(rssismc5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMC5G,
575
SSB_SPROM8_RSSISMC5G_SHIFT);
576
SPEX(rssisav5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISAV5G,
577
SSB_SPROM8_RSSISAV5G_SHIFT);
578
SPEX(bxa5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_BXA5G,
579
SSB_SPROM8_BXA5G_SHIFT);
580
SPEX(pa0b0, SSB_SPROM8_PA0B0, 0xFFFF, 0);
581
SPEX(pa0b1, SSB_SPROM8_PA0B1, 0xFFFF, 0);
582
SPEX(pa0b2, SSB_SPROM8_PA0B2, 0xFFFF, 0);
583
SPEX(pa1b0, SSB_SPROM8_PA1B0, 0xFFFF, 0);
584
SPEX(pa1b1, SSB_SPROM8_PA1B1, 0xFFFF, 0);
585
SPEX(pa1b2, SSB_SPROM8_PA1B2, 0xFFFF, 0);
586
SPEX(pa1lob0, SSB_SPROM8_PA1LOB0, 0xFFFF, 0);
587
SPEX(pa1lob1, SSB_SPROM8_PA1LOB1, 0xFFFF, 0);
588
SPEX(pa1lob2, SSB_SPROM8_PA1LOB2, 0xFFFF, 0);
589
SPEX(pa1hib0, SSB_SPROM8_PA1HIB0, 0xFFFF, 0);
590
SPEX(pa1hib1, SSB_SPROM8_PA1HIB1, 0xFFFF, 0);
591
SPEX(pa1hib2, SSB_SPROM8_PA1HIB2, 0xFFFF, 0);
592
SPEX(cck2gpo, SSB_SPROM8_CCK2GPO, 0xFFFF, 0);
593
SPEX32(ofdm2gpo, SSB_SPROM8_OFDM2GPO, 0xFFFFFFFF, 0);
594
SPEX32(ofdm5glpo, SSB_SPROM8_OFDM5GLPO, 0xFFFFFFFF, 0);
595
SPEX32(ofdm5gpo, SSB_SPROM8_OFDM5GPO, 0xFFFFFFFF, 0);
596
SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0);
598
/* Extract the antenna gain values. */
599
SPEX(antenna_gain.ghz24.a0, SSB_SPROM8_AGAIN01,
600
SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT);
601
SPEX(antenna_gain.ghz24.a1, SSB_SPROM8_AGAIN01,
602
SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT);
603
SPEX(antenna_gain.ghz24.a2, SSB_SPROM8_AGAIN23,
604
SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT);
605
SPEX(antenna_gain.ghz24.a3, SSB_SPROM8_AGAIN23,
606
SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT);
607
memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
608
sizeof(out->antenna_gain.ghz5));
610
sprom_extract_r458(out, in);
612
/* TODO - get remaining rev 8 stuff needed */
615
static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out,
616
const u16 *in, u16 size)
618
memset(out, 0, sizeof(*out));
620
out->revision = in[size - 1] & 0x00FF;
621
ssb_dprintk(KERN_DEBUG PFX "SPROM revision %d detected.\n", out->revision);
622
memset(out->et0mac, 0xFF, 6); /* preset et0 and et1 mac */
623
memset(out->et1mac, 0xFF, 6);
625
if ((bus->chip_id & 0xFF00) == 0x4400) {
626
/* Workaround: The BCM44XX chip has a stupid revision
627
* number stored in the SPROM.
628
* Always extract r1. */
630
ssb_dprintk(KERN_DEBUG PFX "SPROM treated as revision %d\n", out->revision);
633
switch (out->revision) {
637
sprom_extract_r123(out, in);
641
sprom_extract_r45(out, in);
644
sprom_extract_r8(out, in);
647
ssb_printk(KERN_WARNING PFX "Unsupported SPROM"
648
" revision %d detected. Will extract"
649
" v1\n", out->revision);
651
sprom_extract_r123(out, in);
654
if (out->boardflags_lo == 0xFFFF)
655
out->boardflags_lo = 0; /* per specs */
656
if (out->boardflags_hi == 0xFFFF)
657
out->boardflags_hi = 0; /* per specs */
662
static int ssb_pci_sprom_get(struct ssb_bus *bus,
663
struct ssb_sprom *sprom)
668
if (!ssb_is_sprom_available(bus)) {
669
ssb_printk(KERN_ERR PFX "No SPROM available!\n");
672
if (bus->chipco.dev) { /* can be unavailable! */
674
* get SPROM offset: SSB_SPROM_BASE1 except for
675
* chipcommon rev >= 31 or chip ID is 0x4312 and
676
* chipcommon status & 3 == 2
678
if (bus->chipco.dev->id.revision >= 31)
679
bus->sprom_offset = SSB_SPROM_BASE31;
680
else if (bus->chip_id == 0x4312 &&
681
(bus->chipco.status & 0x03) == 2)
682
bus->sprom_offset = SSB_SPROM_BASE31;
684
bus->sprom_offset = SSB_SPROM_BASE1;
686
bus->sprom_offset = SSB_SPROM_BASE1;
688
ssb_dprintk(KERN_INFO PFX "SPROM offset is 0x%x\n", bus->sprom_offset);
690
buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL);
693
bus->sprom_size = SSB_SPROMSIZE_WORDS_R123;
694
sprom_do_read(bus, buf);
695
err = sprom_check_crc(buf, bus->sprom_size);
697
/* try for a 440 byte SPROM - revision 4 and higher */
699
buf = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
703
bus->sprom_size = SSB_SPROMSIZE_WORDS_R4;
704
sprom_do_read(bus, buf);
705
err = sprom_check_crc(buf, bus->sprom_size);
707
/* All CRC attempts failed.
708
* Maybe there is no SPROM on the device?
709
* Now we ask the arch code if there is some sprom
710
* available for this device in some other storage */
711
err = ssb_fill_sprom_with_fallback(bus, sprom);
713
ssb_printk(KERN_WARNING PFX "WARNING: Using"
714
" fallback SPROM failed (err %d)\n",
717
ssb_dprintk(KERN_DEBUG PFX "Using SPROM"
718
" revision %d provided by"
719
" platform.\n", sprom->revision);
723
ssb_printk(KERN_WARNING PFX "WARNING: Invalid"
724
" SPROM CRC (corrupt SPROM)\n");
727
err = sprom_extract(bus, sprom, buf, bus->sprom_size);
734
static void ssb_pci_get_boardinfo(struct ssb_bus *bus,
735
struct ssb_boardinfo *bi)
737
bi->vendor = bus->host_pci->subsystem_vendor;
738
bi->type = bus->host_pci->subsystem_device;
739
bi->rev = bus->host_pci->revision;
742
int ssb_pci_get_invariants(struct ssb_bus *bus,
743
struct ssb_init_invariants *iv)
747
err = ssb_pci_sprom_get(bus, &iv->sprom);
750
ssb_pci_get_boardinfo(bus, &iv->boardinfo);
756
#ifdef CONFIG_SSB_DEBUG
757
static int ssb_pci_assert_buspower(struct ssb_bus *bus)
759
if (likely(bus->powered_up))
762
printk(KERN_ERR PFX "FATAL ERROR: Bus powered down "
763
"while accessing PCI MMIO space\n");
764
if (bus->power_warn_count <= 10) {
765
bus->power_warn_count++;
772
static inline int ssb_pci_assert_buspower(struct ssb_bus *bus)
778
static u8 ssb_pci_read8(struct ssb_device *dev, u16 offset)
780
struct ssb_bus *bus = dev->bus;
782
if (unlikely(ssb_pci_assert_buspower(bus)))
784
if (unlikely(bus->mapped_device != dev)) {
785
if (unlikely(ssb_pci_switch_core(bus, dev)))
788
return ioread8(bus->mmio + offset);
791
static u16 ssb_pci_read16(struct ssb_device *dev, u16 offset)
793
struct ssb_bus *bus = dev->bus;
795
if (unlikely(ssb_pci_assert_buspower(bus)))
797
if (unlikely(bus->mapped_device != dev)) {
798
if (unlikely(ssb_pci_switch_core(bus, dev)))
801
return ioread16(bus->mmio + offset);
804
static u32 ssb_pci_read32(struct ssb_device *dev, u16 offset)
806
struct ssb_bus *bus = dev->bus;
808
if (unlikely(ssb_pci_assert_buspower(bus)))
810
if (unlikely(bus->mapped_device != dev)) {
811
if (unlikely(ssb_pci_switch_core(bus, dev)))
814
return ioread32(bus->mmio + offset);
817
#ifdef CONFIG_SSB_BLOCKIO
818
static void ssb_pci_block_read(struct ssb_device *dev, void *buffer,
819
size_t count, u16 offset, u8 reg_width)
821
struct ssb_bus *bus = dev->bus;
822
void __iomem *addr = bus->mmio + offset;
824
if (unlikely(ssb_pci_assert_buspower(bus)))
826
if (unlikely(bus->mapped_device != dev)) {
827
if (unlikely(ssb_pci_switch_core(bus, dev)))
832
ioread8_rep(addr, buffer, count);
835
SSB_WARN_ON(count & 1);
836
ioread16_rep(addr, buffer, count >> 1);
839
SSB_WARN_ON(count & 3);
840
ioread32_rep(addr, buffer, count >> 2);
848
memset(buffer, 0xFF, count);
850
#endif /* CONFIG_SSB_BLOCKIO */
852
static void ssb_pci_write8(struct ssb_device *dev, u16 offset, u8 value)
854
struct ssb_bus *bus = dev->bus;
856
if (unlikely(ssb_pci_assert_buspower(bus)))
858
if (unlikely(bus->mapped_device != dev)) {
859
if (unlikely(ssb_pci_switch_core(bus, dev)))
862
iowrite8(value, bus->mmio + offset);
865
static void ssb_pci_write16(struct ssb_device *dev, u16 offset, u16 value)
867
struct ssb_bus *bus = dev->bus;
869
if (unlikely(ssb_pci_assert_buspower(bus)))
871
if (unlikely(bus->mapped_device != dev)) {
872
if (unlikely(ssb_pci_switch_core(bus, dev)))
875
iowrite16(value, bus->mmio + offset);
878
static void ssb_pci_write32(struct ssb_device *dev, u16 offset, u32 value)
880
struct ssb_bus *bus = dev->bus;
882
if (unlikely(ssb_pci_assert_buspower(bus)))
884
if (unlikely(bus->mapped_device != dev)) {
885
if (unlikely(ssb_pci_switch_core(bus, dev)))
888
iowrite32(value, bus->mmio + offset);
891
#ifdef CONFIG_SSB_BLOCKIO
892
static void ssb_pci_block_write(struct ssb_device *dev, const void *buffer,
893
size_t count, u16 offset, u8 reg_width)
895
struct ssb_bus *bus = dev->bus;
896
void __iomem *addr = bus->mmio + offset;
898
if (unlikely(ssb_pci_assert_buspower(bus)))
900
if (unlikely(bus->mapped_device != dev)) {
901
if (unlikely(ssb_pci_switch_core(bus, dev)))
906
iowrite8_rep(addr, buffer, count);
909
SSB_WARN_ON(count & 1);
910
iowrite16_rep(addr, buffer, count >> 1);
913
SSB_WARN_ON(count & 3);
914
iowrite32_rep(addr, buffer, count >> 2);
920
#endif /* CONFIG_SSB_BLOCKIO */
922
/* Not "static", as it's used in main.c */
923
const struct ssb_bus_ops ssb_pci_ops = {
924
.read8 = ssb_pci_read8,
925
.read16 = ssb_pci_read16,
926
.read32 = ssb_pci_read32,
927
.write8 = ssb_pci_write8,
928
.write16 = ssb_pci_write16,
929
.write32 = ssb_pci_write32,
930
#ifdef CONFIG_SSB_BLOCKIO
931
.block_read = ssb_pci_block_read,
932
.block_write = ssb_pci_block_write,
936
static ssize_t ssb_pci_attr_sprom_show(struct device *pcidev,
937
struct device_attribute *attr,
940
struct pci_dev *pdev = container_of(pcidev, struct pci_dev, dev);
943
bus = ssb_pci_dev_to_bus(pdev);
947
return ssb_attr_sprom_show(bus, buf, sprom_do_read);
950
static ssize_t ssb_pci_attr_sprom_store(struct device *pcidev,
951
struct device_attribute *attr,
952
const char *buf, size_t count)
954
struct pci_dev *pdev = container_of(pcidev, struct pci_dev, dev);
957
bus = ssb_pci_dev_to_bus(pdev);
961
return ssb_attr_sprom_store(bus, buf, count,
962
sprom_check_crc, sprom_do_write);
965
static DEVICE_ATTR(ssb_sprom, 0600,
966
ssb_pci_attr_sprom_show,
967
ssb_pci_attr_sprom_store);
969
void ssb_pci_exit(struct ssb_bus *bus)
971
struct pci_dev *pdev;
973
if (bus->bustype != SSB_BUSTYPE_PCI)
976
pdev = bus->host_pci;
977
device_remove_file(&pdev->dev, &dev_attr_ssb_sprom);
980
int ssb_pci_init(struct ssb_bus *bus)
982
struct pci_dev *pdev;
985
if (bus->bustype != SSB_BUSTYPE_PCI)
988
pdev = bus->host_pci;
989
mutex_init(&bus->sprom_mutex);
990
err = device_create_file(&pdev->dev, &dev_attr_ssb_sprom);