aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ssb/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ssb/pci.c')
-rw-r--r--drivers/ssb/pci.c120
1 files changed, 63 insertions, 57 deletions
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index e9d94968f394..a8dc95ebf2d6 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -56,7 +56,7 @@ int ssb_pci_switch_coreidx(struct ssb_bus *bus, u8 coreidx)
56 } 56 }
57 return 0; 57 return 0;
58error: 58error:
59 ssb_printk(KERN_ERR PFX "Failed to switch to core %u\n", coreidx); 59 ssb_err("Failed to switch to core %u\n", coreidx);
60 return -ENODEV; 60 return -ENODEV;
61} 61}
62 62
@@ -67,10 +67,9 @@ int ssb_pci_switch_core(struct ssb_bus *bus,
67 unsigned long flags; 67 unsigned long flags;
68 68
69#if SSB_VERBOSE_PCICORESWITCH_DEBUG 69#if SSB_VERBOSE_PCICORESWITCH_DEBUG
70 ssb_printk(KERN_INFO PFX 70 ssb_info("Switching to %s core, index %d\n",
71 "Switching to %s core, index %d\n", 71 ssb_core_name(dev->id.coreid),
72 ssb_core_name(dev->id.coreid), 72 dev->core_index);
73 dev->core_index);
74#endif 73#endif
75 74
76 spin_lock_irqsave(&bus->bar_lock, flags); 75 spin_lock_irqsave(&bus->bar_lock, flags);
@@ -231,6 +230,15 @@ static inline u8 ssb_crc8(u8 crc, u8 data)
231 return t[crc ^ data]; 230 return t[crc ^ data];
232} 231}
233 232
233static void sprom_get_mac(char *mac, const u16 *in)
234{
235 int i;
236 for (i = 0; i < 3; i++) {
237 *mac++ = in[i] >> 8;
238 *mac++ = in[i];
239 }
240}
241
234static u8 ssb_sprom_crc(const u16 *sprom, u16 size) 242static u8 ssb_sprom_crc(const u16 *sprom, u16 size)
235{ 243{
236 int word; 244 int word;
@@ -278,7 +286,7 @@ static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom)
278 u32 spromctl; 286 u32 spromctl;
279 u16 size = bus->sprom_size; 287 u16 size = bus->sprom_size;
280 288
281 ssb_printk(KERN_NOTICE PFX "Writing SPROM. Do NOT turn off the power! Please stand by...\n"); 289 ssb_notice("Writing SPROM. Do NOT turn off the power! Please stand by...\n");
282 err = pci_read_config_dword(pdev, SSB_SPROMCTL, &spromctl); 290 err = pci_read_config_dword(pdev, SSB_SPROMCTL, &spromctl);
283 if (err) 291 if (err)
284 goto err_ctlreg; 292 goto err_ctlreg;
@@ -286,17 +294,17 @@ static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom)
286 err = pci_write_config_dword(pdev, SSB_SPROMCTL, spromctl); 294 err = pci_write_config_dword(pdev, SSB_SPROMCTL, spromctl);
287 if (err) 295 if (err)
288 goto err_ctlreg; 296 goto err_ctlreg;
289 ssb_printk(KERN_NOTICE PFX "[ 0%%"); 297 ssb_notice("[ 0%%");
290 msleep(500); 298 msleep(500);
291 for (i = 0; i < size; i++) { 299 for (i = 0; i < size; i++) {
292 if (i == size / 4) 300 if (i == size / 4)
293 ssb_printk("25%%"); 301 ssb_cont("25%%");
294 else if (i == size / 2) 302 else if (i == size / 2)
295 ssb_printk("50%%"); 303 ssb_cont("50%%");
296 else if (i == (size * 3) / 4) 304 else if (i == (size * 3) / 4)
297 ssb_printk("75%%"); 305 ssb_cont("75%%");
298 else if (i % 2) 306 else if (i % 2)
299 ssb_printk("."); 307 ssb_cont(".");
300 writew(sprom[i], bus->mmio + bus->sprom_offset + (i * 2)); 308 writew(sprom[i], bus->mmio + bus->sprom_offset + (i * 2));
301 mmiowb(); 309 mmiowb();
302 msleep(20); 310 msleep(20);
@@ -309,12 +317,12 @@ static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom)
309 if (err) 317 if (err)
310 goto err_ctlreg; 318 goto err_ctlreg;
311 msleep(500); 319 msleep(500);
312 ssb_printk("100%% ]\n"); 320 ssb_cont("100%% ]\n");
313 ssb_printk(KERN_NOTICE PFX "SPROM written.\n"); 321 ssb_notice("SPROM written\n");
314 322
315 return 0; 323 return 0;
316err_ctlreg: 324err_ctlreg:
317 ssb_printk(KERN_ERR PFX "Could not access SPROM control register.\n"); 325 ssb_err("Could not access SPROM control register.\n");
318 return err; 326 return err;
319} 327}
320 328
@@ -339,10 +347,23 @@ static s8 r123_extract_antgain(u8 sprom_revision, const u16 *in,
339 return (s8)gain; 347 return (s8)gain;
340} 348}
341 349
350static void sprom_extract_r23(struct ssb_sprom *out, const u16 *in)
351{
352 SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0);
353 SPEX(opo, SSB_SPROM2_OPO, SSB_SPROM2_OPO_VALUE, 0);
354 SPEX(pa1lob0, SSB_SPROM2_PA1LOB0, 0xFFFF, 0);
355 SPEX(pa1lob1, SSB_SPROM2_PA1LOB1, 0xFFFF, 0);
356 SPEX(pa1lob2, SSB_SPROM2_PA1LOB2, 0xFFFF, 0);
357 SPEX(pa1hib0, SSB_SPROM2_PA1HIB0, 0xFFFF, 0);
358 SPEX(pa1hib1, SSB_SPROM2_PA1HIB1, 0xFFFF, 0);
359 SPEX(pa1hib2, SSB_SPROM2_PA1HIB2, 0xFFFF, 0);
360 SPEX(maxpwr_ah, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_HI, 0);
361 SPEX(maxpwr_al, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_LO,
362 SSB_SPROM2_MAXP_A_LO_SHIFT);
363}
364
342static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) 365static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
343{ 366{
344 int i;
345 u16 v;
346 u16 loc[3]; 367 u16 loc[3];
347 368
348 if (out->revision == 3) /* rev 3 moved MAC */ 369 if (out->revision == 3) /* rev 3 moved MAC */
@@ -352,19 +373,10 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
352 loc[1] = SSB_SPROM1_ET0MAC; 373 loc[1] = SSB_SPROM1_ET0MAC;
353 loc[2] = SSB_SPROM1_ET1MAC; 374 loc[2] = SSB_SPROM1_ET1MAC;
354 } 375 }
355 for (i = 0; i < 3; i++) { 376 sprom_get_mac(out->il0mac, &in[SPOFF(loc[0])]);
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 */ 377 if (out->revision < 3) { /* only rev 1-2 have et0, et1 */
360 for (i = 0; i < 3; i++) { 378 sprom_get_mac(out->et0mac, &in[SPOFF(loc[1])]);
361 v = in[SPOFF(loc[1]) + i]; 379 sprom_get_mac(out->et1mac, &in[SPOFF(loc[2])]);
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 } 380 }
369 SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0); 381 SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0);
370 SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A, 382 SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A,
@@ -372,6 +384,7 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
372 SPEX(et0mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0M, 14); 384 SPEX(et0mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0M, 14);
373 SPEX(et1mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1M, 15); 385 SPEX(et1mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1M, 15);
374 SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0); 386 SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0);
387 SPEX(board_type, SSB_SPROM1_SPID, 0xFFFF, 0);
375 if (out->revision == 1) 388 if (out->revision == 1)
376 SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE, 389 SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE,
377 SSB_SPROM1_BINF_CCODE_SHIFT); 390 SSB_SPROM1_BINF_CCODE_SHIFT);
@@ -398,8 +411,7 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
398 SSB_SPROM1_ITSSI_A_SHIFT); 411 SSB_SPROM1_ITSSI_A_SHIFT);
399 SPEX(itssi_bg, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_BG, 0); 412 SPEX(itssi_bg, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_BG, 0);
400 SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0); 413 SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0);
401 if (out->revision >= 2) 414
402 SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0);
403 SPEX(alpha2[0], SSB_SPROM1_CCODE, 0xff00, 8); 415 SPEX(alpha2[0], SSB_SPROM1_CCODE, 0xff00, 8);
404 SPEX(alpha2[1], SSB_SPROM1_CCODE, 0x00ff, 0); 416 SPEX(alpha2[1], SSB_SPROM1_CCODE, 0x00ff, 0);
405 417
@@ -410,6 +422,8 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
410 out->antenna_gain.a1 = r123_extract_antgain(out->revision, in, 422 out->antenna_gain.a1 = r123_extract_antgain(out->revision, in,
411 SSB_SPROM1_AGAIN_A, 423 SSB_SPROM1_AGAIN_A,
412 SSB_SPROM1_AGAIN_A_SHIFT); 424 SSB_SPROM1_AGAIN_A_SHIFT);
425 if (out->revision >= 2)
426 sprom_extract_r23(out, in);
413} 427}
414 428
415/* Revs 4 5 and 8 have partially shared layout */ 429/* Revs 4 5 and 8 have partially shared layout */
@@ -454,23 +468,20 @@ static void sprom_extract_r458(struct ssb_sprom *out, const u16 *in)
454 468
455static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in) 469static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
456{ 470{
457 int i;
458 u16 v;
459 u16 il0mac_offset; 471 u16 il0mac_offset;
460 472
461 if (out->revision == 4) 473 if (out->revision == 4)
462 il0mac_offset = SSB_SPROM4_IL0MAC; 474 il0mac_offset = SSB_SPROM4_IL0MAC;
463 else 475 else
464 il0mac_offset = SSB_SPROM5_IL0MAC; 476 il0mac_offset = SSB_SPROM5_IL0MAC;
465 /* extract the MAC address */ 477
466 for (i = 0; i < 3; i++) { 478 sprom_get_mac(out->il0mac, &in[SPOFF(il0mac_offset)]);
467 v = in[SPOFF(il0mac_offset) + i]; 479
468 *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
469 }
470 SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0); 480 SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0);
471 SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A, 481 SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A,
472 SSB_SPROM4_ETHPHY_ET1A_SHIFT); 482 SSB_SPROM4_ETHPHY_ET1A_SHIFT);
473 SPEX(board_rev, SSB_SPROM4_BOARDREV, 0xFFFF, 0); 483 SPEX(board_rev, SSB_SPROM4_BOARDREV, 0xFFFF, 0);
484 SPEX(board_type, SSB_SPROM1_SPID, 0xFFFF, 0);
474 if (out->revision == 4) { 485 if (out->revision == 4) {
475 SPEX(alpha2[0], SSB_SPROM4_CCODE, 0xff00, 8); 486 SPEX(alpha2[0], SSB_SPROM4_CCODE, 0xff00, 8);
476 SPEX(alpha2[1], SSB_SPROM4_CCODE, 0x00ff, 0); 487 SPEX(alpha2[1], SSB_SPROM4_CCODE, 0x00ff, 0);
@@ -530,7 +541,7 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
530static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in) 541static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
531{ 542{
532 int i; 543 int i;
533 u16 v, o; 544 u16 o;
534 u16 pwr_info_offset[] = { 545 u16 pwr_info_offset[] = {
535 SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1, 546 SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1,
536 SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3 547 SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3
@@ -539,11 +550,10 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
539 ARRAY_SIZE(out->core_pwr_info)); 550 ARRAY_SIZE(out->core_pwr_info));
540 551
541 /* extract the MAC address */ 552 /* extract the MAC address */
542 for (i = 0; i < 3; i++) { 553 sprom_get_mac(out->il0mac, &in[SPOFF(SSB_SPROM8_IL0MAC)]);
543 v = in[SPOFF(SSB_SPROM8_IL0MAC) + i]; 554
544 *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
545 }
546 SPEX(board_rev, SSB_SPROM8_BOARDREV, 0xFFFF, 0); 555 SPEX(board_rev, SSB_SPROM8_BOARDREV, 0xFFFF, 0);
556 SPEX(board_type, SSB_SPROM1_SPID, 0xFFFF, 0);
547 SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8); 557 SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8);
548 SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0); 558 SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0);
549 SPEX(boardflags_lo, SSB_SPROM8_BFLLO, 0xFFFF, 0); 559 SPEX(boardflags_lo, SSB_SPROM8_BFLLO, 0xFFFF, 0);
@@ -743,7 +753,7 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out,
743 memset(out, 0, sizeof(*out)); 753 memset(out, 0, sizeof(*out));
744 754
745 out->revision = in[size - 1] & 0x00FF; 755 out->revision = in[size - 1] & 0x00FF;
746 ssb_dprintk(KERN_DEBUG PFX "SPROM revision %d detected.\n", out->revision); 756 ssb_dbg("SPROM revision %d detected\n", out->revision);
747 memset(out->et0mac, 0xFF, 6); /* preset et0 and et1 mac */ 757 memset(out->et0mac, 0xFF, 6); /* preset et0 and et1 mac */
748 memset(out->et1mac, 0xFF, 6); 758 memset(out->et1mac, 0xFF, 6);
749 759
@@ -752,7 +762,7 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out,
752 * number stored in the SPROM. 762 * number stored in the SPROM.
753 * Always extract r1. */ 763 * Always extract r1. */
754 out->revision = 1; 764 out->revision = 1;
755 ssb_dprintk(KERN_DEBUG PFX "SPROM treated as revision %d\n", out->revision); 765 ssb_dbg("SPROM treated as revision %d\n", out->revision);
756 } 766 }
757 767
758 switch (out->revision) { 768 switch (out->revision) {
@@ -769,9 +779,8 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out,
769 sprom_extract_r8(out, in); 779 sprom_extract_r8(out, in);
770 break; 780 break;
771 default: 781 default:
772 ssb_printk(KERN_WARNING PFX "Unsupported SPROM" 782 ssb_warn("Unsupported SPROM revision %d detected. Will extract v1\n",
773 " revision %d detected. Will extract" 783 out->revision);
774 " v1\n", out->revision);
775 out->revision = 1; 784 out->revision = 1;
776 sprom_extract_r123(out, in); 785 sprom_extract_r123(out, in);
777 } 786 }
@@ -791,7 +800,7 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
791 u16 *buf; 800 u16 *buf;
792 801
793 if (!ssb_is_sprom_available(bus)) { 802 if (!ssb_is_sprom_available(bus)) {
794 ssb_printk(KERN_ERR PFX "No SPROM available!\n"); 803 ssb_err("No SPROM available!\n");
795 return -ENODEV; 804 return -ENODEV;
796 } 805 }
797 if (bus->chipco.dev) { /* can be unavailable! */ 806 if (bus->chipco.dev) { /* can be unavailable! */
@@ -810,7 +819,7 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
810 } else { 819 } else {
811 bus->sprom_offset = SSB_SPROM_BASE1; 820 bus->sprom_offset = SSB_SPROM_BASE1;
812 } 821 }
813 ssb_dprintk(KERN_INFO PFX "SPROM offset is 0x%x\n", bus->sprom_offset); 822 ssb_dbg("SPROM offset is 0x%x\n", bus->sprom_offset);
814 823
815 buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL); 824 buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL);
816 if (!buf) 825 if (!buf)
@@ -835,18 +844,15 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
835 * available for this device in some other storage */ 844 * available for this device in some other storage */
836 err = ssb_fill_sprom_with_fallback(bus, sprom); 845 err = ssb_fill_sprom_with_fallback(bus, sprom);
837 if (err) { 846 if (err) {
838 ssb_printk(KERN_WARNING PFX "WARNING: Using" 847 ssb_warn("WARNING: Using fallback SPROM failed (err %d)\n",
839 " fallback SPROM failed (err %d)\n", 848 err);
840 err);
841 } else { 849 } else {
842 ssb_dprintk(KERN_DEBUG PFX "Using SPROM" 850 ssb_dbg("Using SPROM revision %d provided by platform\n",
843 " revision %d provided by" 851 sprom->revision);
844 " platform.\n", sprom->revision);
845 err = 0; 852 err = 0;
846 goto out_free; 853 goto out_free;
847 } 854 }
848 ssb_printk(KERN_WARNING PFX "WARNING: Invalid" 855 ssb_warn("WARNING: Invalid SPROM CRC (corrupt SPROM)\n");
849 " SPROM CRC (corrupt SPROM)\n");
850 } 856 }
851 } 857 }
852 err = sprom_extract(bus, sprom, buf, bus->sprom_size); 858 err = sprom_extract(bus, sprom, buf, bus->sprom_size);