Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pci.c
Go to the documentation of this file.
1 /*
2  * Sonics Silicon Backplane PCI-Hostbus related functions.
3  *
4  * Copyright (C) 2005-2006 Michael Buesch <[email protected]>
5  * Copyright (C) 2005 Martin Langer <[email protected]>
6  * Copyright (C) 2005 Stefano Brivio <[email protected]>
7  * Copyright (C) 2005 Danny van Dyk <[email protected]>
8  * Copyright (C) 2005 Andreas Jaggi <[email protected]>
9  *
10  * Derived from the Broadcom 4400 device driver.
11  * Copyright (C) 2002 David S. Miller ([email protected])
12  * Fixed by Pekka Pietikainen ([email protected])
13  * Copyright (C) 2006 Broadcom Corporation.
14  *
15  * Licensed under the GNU/GPL. See COPYING for details.
16  */
17 
18 #include <linux/ssb/ssb.h>
19 #include <linux/ssb/ssb_regs.h>
20 #include <linux/slab.h>
21 #include <linux/pci.h>
22 #include <linux/delay.h>
23 
24 #include "ssb_private.h"
25 
26 
27 /* Define the following to 1 to enable a printk on each coreswitch. */
28 #define SSB_VERBOSE_PCICORESWITCH_DEBUG 0
29 
30 
31 /* Lowlevel coreswitching */
32 int ssb_pci_switch_coreidx(struct ssb_bus *bus, u8 coreidx)
33 {
34  int err;
35  int attempts = 0;
36  u32 cur_core;
37 
38  while (1) {
39  err = pci_write_config_dword(bus->host_pci, SSB_BAR0_WIN,
40  (coreidx * SSB_CORE_SIZE)
41  + SSB_ENUM_BASE);
42  if (err)
43  goto error;
44  err = pci_read_config_dword(bus->host_pci, SSB_BAR0_WIN,
45  &cur_core);
46  if (err)
47  goto error;
48  cur_core = (cur_core - SSB_ENUM_BASE)
49  / SSB_CORE_SIZE;
50  if (cur_core == coreidx)
51  break;
52 
53  if (attempts++ > SSB_BAR0_MAX_RETRIES)
54  goto error;
55  udelay(10);
56  }
57  return 0;
58 error:
59  ssb_printk(KERN_ERR PFX "Failed to switch to core %u\n", coreidx);
60  return -ENODEV;
61 }
62 
64  struct ssb_device *dev)
65 {
66  int err;
67  unsigned long flags;
68 
69 #if SSB_VERBOSE_PCICORESWITCH_DEBUG
71  "Switching to %s core, index %d\n",
72  ssb_core_name(dev->id.coreid),
73  dev->core_index);
74 #endif
75 
76  spin_lock_irqsave(&bus->bar_lock, flags);
77  err = ssb_pci_switch_coreidx(bus, dev->core_index);
78  if (!err)
79  bus->mapped_device = dev;
80  spin_unlock_irqrestore(&bus->bar_lock, flags);
81 
82  return err;
83 }
84 
85 /* Enable/disable the on board crystal oscillator and/or PLL. */
86 int ssb_pci_xtal(struct ssb_bus *bus, u32 what, int turn_on)
87 {
88  int err;
89  u32 in, out, outenable;
90  u16 pci_status;
91 
92  if (bus->bustype != SSB_BUSTYPE_PCI)
93  return 0;
94 
95  err = pci_read_config_dword(bus->host_pci, SSB_GPIO_IN, &in);
96  if (err)
97  goto err_pci;
98  err = pci_read_config_dword(bus->host_pci, SSB_GPIO_OUT, &out);
99  if (err)
100  goto err_pci;
101  err = pci_read_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE, &outenable);
102  if (err)
103  goto err_pci;
104 
105  outenable |= what;
106 
107  if (turn_on) {
108  /* Avoid glitching the clock if GPRS is already using it.
109  * We can't actually read the state of the PLLPD so we infer it
110  * by the value of XTAL_PU which *is* readable via gpioin.
111  */
112  if (!(in & SSB_GPIO_XTAL)) {
113  if (what & SSB_GPIO_XTAL) {
114  /* Turn the crystal on */
115  out |= SSB_GPIO_XTAL;
116  if (what & SSB_GPIO_PLL)
117  out |= SSB_GPIO_PLL;
118  err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out);
119  if (err)
120  goto err_pci;
121  err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE,
122  outenable);
123  if (err)
124  goto err_pci;
125  msleep(1);
126  }
127  if (what & SSB_GPIO_PLL) {
128  /* Turn the PLL on */
129  out &= ~SSB_GPIO_PLL;
130  err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out);
131  if (err)
132  goto err_pci;
133  msleep(5);
134  }
135  }
136 
137  err = pci_read_config_word(bus->host_pci, PCI_STATUS, &pci_status);
138  if (err)
139  goto err_pci;
140  pci_status &= ~PCI_STATUS_SIG_TARGET_ABORT;
141  err = pci_write_config_word(bus->host_pci, PCI_STATUS, pci_status);
142  if (err)
143  goto err_pci;
144  } else {
145  if (what & SSB_GPIO_XTAL) {
146  /* Turn the crystal off */
147  out &= ~SSB_GPIO_XTAL;
148  }
149  if (what & SSB_GPIO_PLL) {
150  /* Turn the PLL off */
151  out |= SSB_GPIO_PLL;
152  }
153  err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out);
154  if (err)
155  goto err_pci;
156  err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE, outenable);
157  if (err)
158  goto err_pci;
159  }
160 
161 out:
162  return err;
163 
164 err_pci:
165  printk(KERN_ERR PFX "Error: ssb_pci_xtal() could not access PCI config space!\n");
166  err = -EBUSY;
167  goto out;
168 }
169 
170 /* Get the word-offset for a SSB_SPROM_XXX define. */
171 #define SPOFF(offset) ((offset) / sizeof(u16))
172 /* Helper to extract some _offset, which is one of the SSB_SPROM_XXX defines. */
173 #define SPEX16(_outvar, _offset, _mask, _shift) \
174  out->_outvar = ((in[SPOFF(_offset)] & (_mask)) >> (_shift))
175 #define SPEX32(_outvar, _offset, _mask, _shift) \
176  out->_outvar = ((((u32)in[SPOFF((_offset)+2)] << 16 | \
177  in[SPOFF(_offset)]) & (_mask)) >> (_shift))
178 #define SPEX(_outvar, _offset, _mask, _shift) \
179  SPEX16(_outvar, _offset, _mask, _shift)
180 
181 #define SPEX_ARRAY8(_field, _offset, _mask, _shift) \
182  do { \
183  SPEX(_field[0], _offset + 0, _mask, _shift); \
184  SPEX(_field[1], _offset + 2, _mask, _shift); \
185  SPEX(_field[2], _offset + 4, _mask, _shift); \
186  SPEX(_field[3], _offset + 6, _mask, _shift); \
187  SPEX(_field[4], _offset + 8, _mask, _shift); \
188  SPEX(_field[5], _offset + 10, _mask, _shift); \
189  SPEX(_field[6], _offset + 12, _mask, _shift); \
190  SPEX(_field[7], _offset + 14, _mask, _shift); \
191  } while (0)
192 
193 
194 static inline u8 ssb_crc8(u8 crc, u8 data)
195 {
196  /* Polynomial: x^8 + x^7 + x^6 + x^4 + x^2 + 1 */
197  static const u8 t[] = {
198  0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
199  0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
200  0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
201  0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
202  0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
203  0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
204  0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
205  0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
206  0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
207  0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
208  0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
209  0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
210  0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
211  0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
212  0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
213  0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
214  0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
215  0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
216  0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
217  0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
218  0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
219  0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
220  0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
221  0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
222  0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
223  0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
224  0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
225  0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
226  0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
227  0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
228  0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
229  0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F,
230  };
231  return t[crc ^ data];
232 }
233 
234 static u8 ssb_sprom_crc(const u16 *sprom, u16 size)
235 {
236  int word;
237  u8 crc = 0xFF;
238 
239  for (word = 0; word < size - 1; word++) {
240  crc = ssb_crc8(crc, sprom[word] & 0x00FF);
241  crc = ssb_crc8(crc, (sprom[word] & 0xFF00) >> 8);
242  }
243  crc = ssb_crc8(crc, sprom[size - 1] & 0x00FF);
244  crc ^= 0xFF;
245 
246  return crc;
247 }
248 
249 static int sprom_check_crc(const u16 *sprom, size_t size)
250 {
251  u8 crc;
252  u8 expected_crc;
253  u16 tmp;
254 
255  crc = ssb_sprom_crc(sprom, size);
256  tmp = sprom[size - 1] & SSB_SPROM_REVISION_CRC;
257  expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT;
258  if (crc != expected_crc)
259  return -EPROTO;
260 
261  return 0;
262 }
263 
264 static int sprom_do_read(struct ssb_bus *bus, u16 *sprom)
265 {
266  int i;
267 
268  for (i = 0; i < bus->sprom_size; i++)
269  sprom[i] = ioread16(bus->mmio + bus->sprom_offset + (i * 2));
270 
271  return 0;
272 }
273 
274 static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom)
275 {
276  struct pci_dev *pdev = bus->host_pci;
277  int i, err;
278  u32 spromctl;
279  u16 size = bus->sprom_size;
280 
281  ssb_printk(KERN_NOTICE PFX "Writing SPROM. Do NOT turn off the power! Please stand by...\n");
282  err = pci_read_config_dword(pdev, SSB_SPROMCTL, &spromctl);
283  if (err)
284  goto err_ctlreg;
285  spromctl |= SSB_SPROMCTL_WE;
286  err = pci_write_config_dword(pdev, SSB_SPROMCTL, spromctl);
287  if (err)
288  goto err_ctlreg;
289  ssb_printk(KERN_NOTICE PFX "[ 0%%");
290  msleep(500);
291  for (i = 0; i < size; i++) {
292  if (i == size / 4)
293  ssb_printk("25%%");
294  else if (i == size / 2)
295  ssb_printk("50%%");
296  else if (i == (size * 3) / 4)
297  ssb_printk("75%%");
298  else if (i % 2)
299  ssb_printk(".");
300  writew(sprom[i], bus->mmio + bus->sprom_offset + (i * 2));
301  mmiowb();
302  msleep(20);
303  }
304  err = pci_read_config_dword(pdev, SSB_SPROMCTL, &spromctl);
305  if (err)
306  goto err_ctlreg;
307  spromctl &= ~SSB_SPROMCTL_WE;
308  err = pci_write_config_dword(pdev, SSB_SPROMCTL, spromctl);
309  if (err)
310  goto err_ctlreg;
311  msleep(500);
312  ssb_printk("100%% ]\n");
313  ssb_printk(KERN_NOTICE PFX "SPROM written.\n");
314 
315  return 0;
316 err_ctlreg:
317  ssb_printk(KERN_ERR PFX "Could not access SPROM control register.\n");
318  return err;
319 }
320 
321 static s8 r123_extract_antgain(u8 sprom_revision, const u16 *in,
322  u16 mask, u16 shift)
323 {
324  u16 v;
325  u8 gain;
326 
327  v = in[SPOFF(SSB_SPROM1_AGAIN)];
328  gain = (v & mask) >> shift;
329  if (gain == 0xFF)
330  gain = 2; /* If unset use 2dBm */
331  if (sprom_revision == 1) {
332  /* Convert to Q5.2 */
333  gain <<= 2;
334  } else {
335  /* Q5.2 Fractional part is stored in 0xC0 */
336  gain = ((gain & 0xC0) >> 6) | ((gain & 0x3F) << 2);
337  }
338 
339  return (s8)gain;
340 }
341 
342 static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
343 {
344  int i;
345  u16 v;
346  u16 loc[3];
347 
348  if (out->revision == 3) /* rev 3 moved MAC */
349  loc[0] = SSB_SPROM3_IL0MAC;
350  else {
351  loc[0] = SSB_SPROM1_IL0MAC;
352  loc[1] = SSB_SPROM1_ET0MAC;
353  loc[2] = SSB_SPROM1_ET1MAC;
354  }
355  for (i = 0; i < 3; i++) {
356  v = in[SPOFF(loc[0]) + i];
357  *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
358  }
359  if (out->revision < 3) { /* only rev 1-2 have et0, et1 */
360  for (i = 0; i < 3; i++) {
361  v = in[SPOFF(loc[1]) + i];
362  *(((__be16 *)out->et0mac) + i) = cpu_to_be16(v);
363  }
364  for (i = 0; i < 3; i++) {
365  v = in[SPOFF(loc[2]) + i];
366  *(((__be16 *)out->et1mac) + i) = cpu_to_be16(v);
367  }
368  }
374  SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0);
375  if (out->revision == 1)
378  SPEX(ant_available_a, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTA,
380  SPEX(ant_available_bg, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTBG,
382  SPEX(pa0b0, SSB_SPROM1_PA0B0, 0xFFFF, 0);
383  SPEX(pa0b1, SSB_SPROM1_PA0B1, 0xFFFF, 0);
384  SPEX(pa0b2, SSB_SPROM1_PA0B2, 0xFFFF, 0);
385  SPEX(pa1b0, SSB_SPROM1_PA1B0, 0xFFFF, 0);
386  SPEX(pa1b1, SSB_SPROM1_PA1B1, 0xFFFF, 0);
387  SPEX(pa1b2, SSB_SPROM1_PA1B2, 0xFFFF, 0);
400  SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0);
401  if (out->revision >= 2)
402  SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0);
403  SPEX(alpha2[0], SSB_SPROM1_CCODE, 0xff00, 8);
404  SPEX(alpha2[1], SSB_SPROM1_CCODE, 0x00ff, 0);
405 
406  /* Extract the antenna gain values. */
407  out->antenna_gain.a0 = r123_extract_antgain(out->revision, in,
410  out->antenna_gain.a1 = r123_extract_antgain(out->revision, in,
413 }
414 
415 /* Revs 4 5 and 8 have partially shared layout */
416 static void sprom_extract_r458(struct ssb_sprom *out, const u16 *in)
417 {
418  SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01,
420  SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01,
422  SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23,
424  SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23,
426 
427  SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01,
429  SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01,
431  SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23,
433  SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23,
435 
436  SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01,
438  SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01,
440  SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23,
442  SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23,
444 
445  SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01,
447  SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01,
449  SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23,
451  SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23,
453 }
454 
455 static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
456 {
457  int i;
458  u16 v;
459  u16 il0mac_offset;
460 
461  if (out->revision == 4)
462  il0mac_offset = SSB_SPROM4_IL0MAC;
463  else
464  il0mac_offset = SSB_SPROM5_IL0MAC;
465  /* extract the MAC address */
466  for (i = 0; i < 3; i++) {
467  v = in[SPOFF(il0mac_offset) + i];
468  *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
469  }
473  SPEX(board_rev, SSB_SPROM4_BOARDREV, 0xFFFF, 0);
474  if (out->revision == 4) {
475  SPEX(alpha2[0], SSB_SPROM4_CCODE, 0xff00, 8);
476  SPEX(alpha2[1], SSB_SPROM4_CCODE, 0x00ff, 0);
477  SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0);
478  SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0);
479  SPEX(boardflags2_lo, SSB_SPROM4_BFL2LO, 0xFFFF, 0);
480  SPEX(boardflags2_hi, SSB_SPROM4_BFL2HI, 0xFFFF, 0);
481  } else {
482  SPEX(alpha2[0], SSB_SPROM5_CCODE, 0xff00, 8);
483  SPEX(alpha2[1], SSB_SPROM5_CCODE, 0x00ff, 0);
484  SPEX(boardflags_lo, SSB_SPROM5_BFLLO, 0xFFFF, 0);
485  SPEX(boardflags_hi, SSB_SPROM5_BFLHI, 0xFFFF, 0);
486  SPEX(boardflags2_lo, SSB_SPROM5_BFL2LO, 0xFFFF, 0);
487  SPEX(boardflags2_hi, SSB_SPROM5_BFL2HI, 0xFFFF, 0);
488  }
499  if (out->revision == 4) {
506  } else {
513  }
514 
515  /* Extract the antenna gain values. */
516  SPEX(antenna_gain.a0, SSB_SPROM4_AGAIN01,
518  SPEX(antenna_gain.a1, SSB_SPROM4_AGAIN01,
520  SPEX(antenna_gain.a2, SSB_SPROM4_AGAIN23,
522  SPEX(antenna_gain.a3, SSB_SPROM4_AGAIN23,
524 
525  sprom_extract_r458(out, in);
526 
527  /* TODO - get remaining rev 4 stuff needed */
528 }
529 
530 static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
531 {
532  int i;
533  u16 v, o;
534  u16 pwr_info_offset[] = {
537  };
538  BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
539  ARRAY_SIZE(out->core_pwr_info));
540 
541  /* extract the MAC address */
542  for (i = 0; i < 3; i++) {
543  v = in[SPOFF(SSB_SPROM8_IL0MAC) + i];
544  *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
545  }
546  SPEX(board_rev, SSB_SPROM8_BOARDREV, 0xFFFF, 0);
547  SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8);
548  SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0);
549  SPEX(boardflags_lo, SSB_SPROM8_BFLLO, 0xFFFF, 0);
550  SPEX(boardflags_hi, SSB_SPROM8_BFLHI, 0xFFFF, 0);
551  SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, 0xFFFF, 0);
552  SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, 0xFFFF, 0);
595  SPEX(pa0b0, SSB_SPROM8_PA0B0, 0xFFFF, 0);
596  SPEX(pa0b1, SSB_SPROM8_PA0B1, 0xFFFF, 0);
597  SPEX(pa0b2, SSB_SPROM8_PA0B2, 0xFFFF, 0);
598  SPEX(pa1b0, SSB_SPROM8_PA1B0, 0xFFFF, 0);
599  SPEX(pa1b1, SSB_SPROM8_PA1B1, 0xFFFF, 0);
600  SPEX(pa1b2, SSB_SPROM8_PA1B2, 0xFFFF, 0);
601  SPEX(pa1lob0, SSB_SPROM8_PA1LOB0, 0xFFFF, 0);
602  SPEX(pa1lob1, SSB_SPROM8_PA1LOB1, 0xFFFF, 0);
603  SPEX(pa1lob2, SSB_SPROM8_PA1LOB2, 0xFFFF, 0);
604  SPEX(pa1hib0, SSB_SPROM8_PA1HIB0, 0xFFFF, 0);
605  SPEX(pa1hib1, SSB_SPROM8_PA1HIB1, 0xFFFF, 0);
606  SPEX(pa1hib2, SSB_SPROM8_PA1HIB2, 0xFFFF, 0);
607  SPEX(cck2gpo, SSB_SPROM8_CCK2GPO, 0xFFFF, 0);
608  SPEX32(ofdm2gpo, SSB_SPROM8_OFDM2GPO, 0xFFFFFFFF, 0);
609  SPEX32(ofdm5glpo, SSB_SPROM8_OFDM5GLPO, 0xFFFFFFFF, 0);
610  SPEX32(ofdm5gpo, SSB_SPROM8_OFDM5GPO, 0xFFFFFFFF, 0);
611  SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0);
612 
613  /* Extract the antenna gain values. */
614  SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01,
616  SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01,
618  SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23,
620  SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23,
622 
623  /* Extract cores power info info */
624  for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
625  o = pwr_info_offset[i];
626  SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
628  SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
629  SSB_SPROM8_2G_MAXP, 0);
630 
631  SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0);
632  SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0);
633  SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0);
634 
635  SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
637  SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
638  SSB_SPROM8_5G_MAXP, 0);
639  SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP,
641  SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP,
643 
644  SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0);
645  SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0);
646  SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0);
647  SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0);
648  SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0);
649  SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0);
650  SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0);
651  SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0);
652  SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0);
653  }
654 
655  /* Extract FEM info */
656  SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G,
658  SPEX(fem.ghz2.extpa_gain, SSB_SPROM8_FEM2G,
660  SPEX(fem.ghz2.pdet_range, SSB_SPROM8_FEM2G,
662  SPEX(fem.ghz2.tr_iso, SSB_SPROM8_FEM2G,
664  SPEX(fem.ghz2.antswlut, SSB_SPROM8_FEM2G,
666 
667  SPEX(fem.ghz5.tssipos, SSB_SPROM8_FEM5G,
669  SPEX(fem.ghz5.extpa_gain, SSB_SPROM8_FEM5G,
671  SPEX(fem.ghz5.pdet_range, SSB_SPROM8_FEM5G,
673  SPEX(fem.ghz5.tr_iso, SSB_SPROM8_FEM5G,
675  SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G,
677 
678  SPEX(leddc_on_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_ON,
680  SPEX(leddc_off_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_OFF,
682 
689 
690  SPEX(opo, SSB_SPROM8_OFDM2GPO, 0x00ff, 0);
691 
692  SPEX_ARRAY8(mcs2gpo, SSB_SPROM8_2G_MCSPO, ~0, 0);
693  SPEX_ARRAY8(mcs5gpo, SSB_SPROM8_5G_MCSPO, ~0, 0);
694  SPEX_ARRAY8(mcs5glpo, SSB_SPROM8_5GL_MCSPO, ~0, 0);
695  SPEX_ARRAY8(mcs5ghpo, SSB_SPROM8_5GH_MCSPO, ~0, 0);
696 
701  SPEX(tempsense_slope, SSB_SPROM8_OPT_CORRX,
706  SPEX(tempsense_option, SSB_SPROM8_OPT_CORRX,
709  SPEX(freqoffset_corr, SSB_SPROM8_HWIQ_IQSWP,
712  SPEX(iqcal_swp_dis, SSB_SPROM8_HWIQ_IQSWP,
717 
718  SPEX(bw40po, SSB_SPROM8_BW40PO, ~0, 0);
719  SPEX(cddpo, SSB_SPROM8_CDDPO, ~0, 0);
720  SPEX(stbcpo, SSB_SPROM8_STBCPO, ~0, 0);
721  SPEX(bwduppo, SSB_SPROM8_BWDUPPO, ~0, 0);
722 
727  SPEX(phycal_tempdelta, SSB_SPROM8_TEMPDELTA,
732  SPEX(temps_hysteresis, SSB_SPROM8_TEMPDELTA,
735  sprom_extract_r458(out, in);
736 
737  /* TODO - get remaining rev 8 stuff needed */
738 }
739 
740 static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out,
741  const u16 *in, u16 size)
742 {
743  memset(out, 0, sizeof(*out));
744 
745  out->revision = in[size - 1] & 0x00FF;
746  ssb_dprintk(KERN_DEBUG PFX "SPROM revision %d detected.\n", out->revision);
747  memset(out->et0mac, 0xFF, 6); /* preset et0 and et1 mac */
748  memset(out->et1mac, 0xFF, 6);
749 
750  if ((bus->chip_id & 0xFF00) == 0x4400) {
751  /* Workaround: The BCM44XX chip has a stupid revision
752  * number stored in the SPROM.
753  * Always extract r1. */
754  out->revision = 1;
755  ssb_dprintk(KERN_DEBUG PFX "SPROM treated as revision %d\n", out->revision);
756  }
757 
758  switch (out->revision) {
759  case 1:
760  case 2:
761  case 3:
762  sprom_extract_r123(out, in);
763  break;
764  case 4:
765  case 5:
766  sprom_extract_r45(out, in);
767  break;
768  case 8:
769  sprom_extract_r8(out, in);
770  break;
771  default:
772  ssb_printk(KERN_WARNING PFX "Unsupported SPROM"
773  " revision %d detected. Will extract"
774  " v1\n", out->revision);
775  out->revision = 1;
776  sprom_extract_r123(out, in);
777  }
778 
779  if (out->boardflags_lo == 0xFFFF)
780  out->boardflags_lo = 0; /* per specs */
781  if (out->boardflags_hi == 0xFFFF)
782  out->boardflags_hi = 0; /* per specs */
783 
784  return 0;
785 }
786 
787 static int ssb_pci_sprom_get(struct ssb_bus *bus,
788  struct ssb_sprom *sprom)
789 {
790  int err;
791  u16 *buf;
792 
793  if (!ssb_is_sprom_available(bus)) {
794  ssb_printk(KERN_ERR PFX "No SPROM available!\n");
795  return -ENODEV;
796  }
797  if (bus->chipco.dev) { /* can be unavailable! */
798  /*
799  * get SPROM offset: SSB_SPROM_BASE1 except for
800  * chipcommon rev >= 31 or chip ID is 0x4312 and
801  * chipcommon status & 3 == 2
802  */
803  if (bus->chipco.dev->id.revision >= 31)
805  else if (bus->chip_id == 0x4312 &&
806  (bus->chipco.status & 0x03) == 2)
808  else
810  } else {
812  }
813  ssb_dprintk(KERN_INFO PFX "SPROM offset is 0x%x\n", bus->sprom_offset);
814 
815  buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL);
816  if (!buf)
817  return -ENOMEM;
819  sprom_do_read(bus, buf);
820  err = sprom_check_crc(buf, bus->sprom_size);
821  if (err) {
822  /* try for a 440 byte SPROM - revision 4 and higher */
823  kfree(buf);
824  buf = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
825  GFP_KERNEL);
826  if (!buf)
827  return -ENOMEM;
829  sprom_do_read(bus, buf);
830  err = sprom_check_crc(buf, bus->sprom_size);
831  if (err) {
832  /* All CRC attempts failed.
833  * Maybe there is no SPROM on the device?
834  * Now we ask the arch code if there is some sprom
835  * available for this device in some other storage */
836  err = ssb_fill_sprom_with_fallback(bus, sprom);
837  if (err) {
838  ssb_printk(KERN_WARNING PFX "WARNING: Using"
839  " fallback SPROM failed (err %d)\n",
840  err);
841  } else {
842  ssb_dprintk(KERN_DEBUG PFX "Using SPROM"
843  " revision %d provided by"
844  " platform.\n", sprom->revision);
845  err = 0;
846  goto out_free;
847  }
848  ssb_printk(KERN_WARNING PFX "WARNING: Invalid"
849  " SPROM CRC (corrupt SPROM)\n");
850  }
851  }
852  err = sprom_extract(bus, sprom, buf, bus->sprom_size);
853 
854 out_free:
855  kfree(buf);
856  return err;
857 }
858 
859 static void ssb_pci_get_boardinfo(struct ssb_bus *bus,
860  struct ssb_boardinfo *bi)
861 {
862  bi->vendor = bus->host_pci->subsystem_vendor;
863  bi->type = bus->host_pci->subsystem_device;
864 }
865 
867  struct ssb_init_invariants *iv)
868 {
869  int err;
870 
871  err = ssb_pci_sprom_get(bus, &iv->sprom);
872  if (err)
873  goto out;
874  ssb_pci_get_boardinfo(bus, &iv->boardinfo);
875 
876 out:
877  return err;
878 }
879 
880 #ifdef CONFIG_SSB_DEBUG
881 static int ssb_pci_assert_buspower(struct ssb_bus *bus)
882 {
883  if (likely(bus->powered_up))
884  return 0;
885 
886  printk(KERN_ERR PFX "FATAL ERROR: Bus powered down "
887  "while accessing PCI MMIO space\n");
888  if (bus->power_warn_count <= 10) {
889  bus->power_warn_count++;
890  dump_stack();
891  }
892 
893  return -ENODEV;
894 }
895 #else /* DEBUG */
896 static inline int ssb_pci_assert_buspower(struct ssb_bus *bus)
897 {
898  return 0;
899 }
900 #endif /* DEBUG */
901 
902 static u8 ssb_pci_read8(struct ssb_device *dev, u16 offset)
903 {
904  struct ssb_bus *bus = dev->bus;
905 
906  if (unlikely(ssb_pci_assert_buspower(bus)))
907  return 0xFF;
908  if (unlikely(bus->mapped_device != dev)) {
909  if (unlikely(ssb_pci_switch_core(bus, dev)))
910  return 0xFF;
911  }
912  return ioread8(bus->mmio + offset);
913 }
914 
915 static u16 ssb_pci_read16(struct ssb_device *dev, u16 offset)
916 {
917  struct ssb_bus *bus = dev->bus;
918 
919  if (unlikely(ssb_pci_assert_buspower(bus)))
920  return 0xFFFF;
921  if (unlikely(bus->mapped_device != dev)) {
922  if (unlikely(ssb_pci_switch_core(bus, dev)))
923  return 0xFFFF;
924  }
925  return ioread16(bus->mmio + offset);
926 }
927 
928 static u32 ssb_pci_read32(struct ssb_device *dev, u16 offset)
929 {
930  struct ssb_bus *bus = dev->bus;
931 
932  if (unlikely(ssb_pci_assert_buspower(bus)))
933  return 0xFFFFFFFF;
934  if (unlikely(bus->mapped_device != dev)) {
935  if (unlikely(ssb_pci_switch_core(bus, dev)))
936  return 0xFFFFFFFF;
937  }
938  return ioread32(bus->mmio + offset);
939 }
940 
941 #ifdef CONFIG_SSB_BLOCKIO
942 static void ssb_pci_block_read(struct ssb_device *dev, void *buffer,
943  size_t count, u16 offset, u8 reg_width)
944 {
945  struct ssb_bus *bus = dev->bus;
946  void __iomem *addr = bus->mmio + offset;
947 
948  if (unlikely(ssb_pci_assert_buspower(bus)))
949  goto error;
950  if (unlikely(bus->mapped_device != dev)) {
951  if (unlikely(ssb_pci_switch_core(bus, dev)))
952  goto error;
953  }
954  switch (reg_width) {
955  case sizeof(u8):
956  ioread8_rep(addr, buffer, count);
957  break;
958  case sizeof(u16):
959  SSB_WARN_ON(count & 1);
960  ioread16_rep(addr, buffer, count >> 1);
961  break;
962  case sizeof(u32):
963  SSB_WARN_ON(count & 3);
964  ioread32_rep(addr, buffer, count >> 2);
965  break;
966  default:
967  SSB_WARN_ON(1);
968  }
969 
970  return;
971 error:
972  memset(buffer, 0xFF, count);
973 }
974 #endif /* CONFIG_SSB_BLOCKIO */
975 
976 static void ssb_pci_write8(struct ssb_device *dev, u16 offset, u8 value)
977 {
978  struct ssb_bus *bus = dev->bus;
979 
980  if (unlikely(ssb_pci_assert_buspower(bus)))
981  return;
982  if (unlikely(bus->mapped_device != dev)) {
983  if (unlikely(ssb_pci_switch_core(bus, dev)))
984  return;
985  }
986  iowrite8(value, bus->mmio + offset);
987 }
988 
989 static void ssb_pci_write16(struct ssb_device *dev, u16 offset, u16 value)
990 {
991  struct ssb_bus *bus = dev->bus;
992 
993  if (unlikely(ssb_pci_assert_buspower(bus)))
994  return;
995  if (unlikely(bus->mapped_device != dev)) {
996  if (unlikely(ssb_pci_switch_core(bus, dev)))
997  return;
998  }
999  iowrite16(value, bus->mmio + offset);
1000 }
1001 
1002 static void ssb_pci_write32(struct ssb_device *dev, u16 offset, u32 value)
1003 {
1004  struct ssb_bus *bus = dev->bus;
1005 
1006  if (unlikely(ssb_pci_assert_buspower(bus)))
1007  return;
1008  if (unlikely(bus->mapped_device != dev)) {
1009  if (unlikely(ssb_pci_switch_core(bus, dev)))
1010  return;
1011  }
1012  iowrite32(value, bus->mmio + offset);
1013 }
1014 
1015 #ifdef CONFIG_SSB_BLOCKIO
1016 static void ssb_pci_block_write(struct ssb_device *dev, const void *buffer,
1017  size_t count, u16 offset, u8 reg_width)
1018 {
1019  struct ssb_bus *bus = dev->bus;
1020  void __iomem *addr = bus->mmio + offset;
1021 
1022  if (unlikely(ssb_pci_assert_buspower(bus)))
1023  return;
1024  if (unlikely(bus->mapped_device != dev)) {
1025  if (unlikely(ssb_pci_switch_core(bus, dev)))
1026  return;
1027  }
1028  switch (reg_width) {
1029  case sizeof(u8):
1030  iowrite8_rep(addr, buffer, count);
1031  break;
1032  case sizeof(u16):
1033  SSB_WARN_ON(count & 1);
1034  iowrite16_rep(addr, buffer, count >> 1);
1035  break;
1036  case sizeof(u32):
1037  SSB_WARN_ON(count & 3);
1038  iowrite32_rep(addr, buffer, count >> 2);
1039  break;
1040  default:
1041  SSB_WARN_ON(1);
1042  }
1043 }
1044 #endif /* CONFIG_SSB_BLOCKIO */
1045 
1046 /* Not "static", as it's used in main.c */
1047 const struct ssb_bus_ops ssb_pci_ops = {
1048  .read8 = ssb_pci_read8,
1049  .read16 = ssb_pci_read16,
1050  .read32 = ssb_pci_read32,
1051  .write8 = ssb_pci_write8,
1052  .write16 = ssb_pci_write16,
1053  .write32 = ssb_pci_write32,
1054 #ifdef CONFIG_SSB_BLOCKIO
1055  .block_read = ssb_pci_block_read,
1056  .block_write = ssb_pci_block_write,
1057 #endif
1058 };
1059 
1060 static ssize_t ssb_pci_attr_sprom_show(struct device *pcidev,
1061  struct device_attribute *attr,
1062  char *buf)
1063 {
1064  struct pci_dev *pdev = container_of(pcidev, struct pci_dev, dev);
1065  struct ssb_bus *bus;
1066 
1067  bus = ssb_pci_dev_to_bus(pdev);
1068  if (!bus)
1069  return -ENODEV;
1070 
1071  return ssb_attr_sprom_show(bus, buf, sprom_do_read);
1072 }
1073 
1074 static ssize_t ssb_pci_attr_sprom_store(struct device *pcidev,
1075  struct device_attribute *attr,
1076  const char *buf, size_t count)
1077 {
1078  struct pci_dev *pdev = container_of(pcidev, struct pci_dev, dev);
1079  struct ssb_bus *bus;
1080 
1081  bus = ssb_pci_dev_to_bus(pdev);
1082  if (!bus)
1083  return -ENODEV;
1084 
1085  return ssb_attr_sprom_store(bus, buf, count,
1086  sprom_check_crc, sprom_do_write);
1087 }
1088 
1089 static DEVICE_ATTR(ssb_sprom, 0600,
1090  ssb_pci_attr_sprom_show,
1091  ssb_pci_attr_sprom_store);
1092 
1093 void ssb_pci_exit(struct ssb_bus *bus)
1094 {
1095  struct pci_dev *pdev;
1096 
1097  if (bus->bustype != SSB_BUSTYPE_PCI)
1098  return;
1099 
1100  pdev = bus->host_pci;
1101  device_remove_file(&pdev->dev, &dev_attr_ssb_sprom);
1102 }
1103 
1104 int ssb_pci_init(struct ssb_bus *bus)
1105 {
1106  struct pci_dev *pdev;
1107  int err;
1108 
1109  if (bus->bustype != SSB_BUSTYPE_PCI)
1110  return 0;
1111 
1112  pdev = bus->host_pci;
1113  mutex_init(&bus->sprom_mutex);
1114  err = device_create_file(&pdev->dev, &dev_attr_ssb_sprom);
1115  if (err)
1116  goto out;
1117 
1118 out:
1119  return err;
1120 }