aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ssb
diff options
context:
space:
mode:
authorDavid Vrabel <david.vrabel@csr.com>2008-10-20 11:07:19 -0400
committerDavid Vrabel <david.vrabel@csr.com>2008-10-20 11:07:19 -0400
commit61e0e79ee3c609eb34edf2fe023708cba6a79b1f (patch)
tree663deacffd4071120dc9badb70428fe5f124c7b9 /drivers/ssb
parentc15895ef30c2c03e99802951787183039a349d32 (diff)
parent0cfd81031a26717fe14380d18275f8e217571615 (diff)
Merge branch 'master' into for-upstream
Conflicts: Documentation/ABI/testing/sysfs-bus-usb drivers/Makefile
Diffstat (limited to 'drivers/ssb')
-rw-r--r--drivers/ssb/pci.c84
-rw-r--r--drivers/ssb/pcmcia.c22
2 files changed, 60 insertions, 46 deletions
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index f883dcfffe06..d5cde051806b 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -327,11 +327,9 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
327 s8 gain; 327 s8 gain;
328 u16 loc[3]; 328 u16 loc[3];
329 329
330 if (out->revision == 3) { /* rev 3 moved MAC */ 330 if (out->revision == 3) /* rev 3 moved MAC */
331 loc[0] = SSB_SPROM3_IL0MAC; 331 loc[0] = SSB_SPROM3_IL0MAC;
332 loc[1] = SSB_SPROM3_ET0MAC; 332 else {
333 loc[2] = SSB_SPROM3_ET1MAC;
334 } else {
335 loc[0] = SSB_SPROM1_IL0MAC; 333 loc[0] = SSB_SPROM1_IL0MAC;
336 loc[1] = SSB_SPROM1_ET0MAC; 334 loc[1] = SSB_SPROM1_ET0MAC;
337 loc[2] = SSB_SPROM1_ET1MAC; 335 loc[2] = SSB_SPROM1_ET1MAC;
@@ -340,13 +338,15 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
340 v = in[SPOFF(loc[0]) + i]; 338 v = in[SPOFF(loc[0]) + i];
341 *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v); 339 *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
342 } 340 }
343 for (i = 0; i < 3; i++) { 341 if (out->revision < 3) { /* only rev 1-2 have et0, et1 */
344 v = in[SPOFF(loc[1]) + i]; 342 for (i = 0; i < 3; i++) {
345 *(((__be16 *)out->et0mac) + i) = cpu_to_be16(v); 343 v = in[SPOFF(loc[1]) + i];
346 } 344 *(((__be16 *)out->et0mac) + i) = cpu_to_be16(v);
347 for (i = 0; i < 3; i++) { 345 }
348 v = in[SPOFF(loc[2]) + i]; 346 for (i = 0; i < 3; i++) {
349 *(((__be16 *)out->et1mac) + i) = cpu_to_be16(v); 347 v = in[SPOFF(loc[2]) + i];
348 *(((__be16 *)out->et1mac) + i) = cpu_to_be16(v);
349 }
350 } 350 }
351 SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0); 351 SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0);
352 SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A, 352 SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A,
@@ -399,30 +399,33 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
399 out->antenna_gain.ghz5.a3 = gain; 399 out->antenna_gain.ghz5.a3 = gain;
400} 400}
401 401
402static void sprom_extract_r4(struct ssb_sprom *out, const u16 *in) 402static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
403{ 403{
404 int i; 404 int i;
405 u16 v; 405 u16 v;
406 u16 il0mac_offset;
406 407
407 /* extract the equivalent of the r1 variables */ 408 if (out->revision == 4)
409 il0mac_offset = SSB_SPROM4_IL0MAC;
410 else
411 il0mac_offset = SSB_SPROM5_IL0MAC;
412 /* extract the MAC address */
408 for (i = 0; i < 3; i++) { 413 for (i = 0; i < 3; i++) {
409 v = in[SPOFF(SSB_SPROM4_IL0MAC) + i]; 414 v = in[SPOFF(il0mac_offset) + i];
410 *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v); 415 *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
411 } 416 }
412 for (i = 0; i < 3; i++) {
413 v = in[SPOFF(SSB_SPROM4_ET0MAC) + i];
414 *(((__be16 *)out->et0mac) + i) = cpu_to_be16(v);
415 }
416 for (i = 0; i < 3; i++) {
417 v = in[SPOFF(SSB_SPROM4_ET1MAC) + i];
418 *(((__be16 *)out->et1mac) + i) = cpu_to_be16(v);
419 }
420 SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0); 417 SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0);
421 SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A, 418 SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A,
422 SSB_SPROM4_ETHPHY_ET1A_SHIFT); 419 SSB_SPROM4_ETHPHY_ET1A_SHIFT);
423 SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0); 420 if (out->revision == 4) {
424 SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0); 421 SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0);
425 SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0); 422 SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0);
423 SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0);
424 } else {
425 SPEX(country_code, SSB_SPROM5_CCODE, 0xFFFF, 0);
426 SPEX(boardflags_lo, SSB_SPROM5_BFLLO, 0xFFFF, 0);
427 SPEX(boardflags_hi, SSB_SPROM5_BFLHI, 0xFFFF, 0);
428 }
426 SPEX(ant_available_a, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_A, 429 SPEX(ant_available_a, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_A,
427 SSB_SPROM4_ANTAVAIL_A_SHIFT); 430 SSB_SPROM4_ANTAVAIL_A_SHIFT);
428 SPEX(ant_available_bg, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_BG, 431 SPEX(ant_available_bg, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_BG,
@@ -433,12 +436,21 @@ static void sprom_extract_r4(struct ssb_sprom *out, const u16 *in)
433 SPEX(maxpwr_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_MAXP_A_MASK, 0); 436 SPEX(maxpwr_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_MAXP_A_MASK, 0);
434 SPEX(itssi_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_ITSSI_A, 437 SPEX(itssi_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_ITSSI_A,
435 SSB_SPROM4_ITSSI_A_SHIFT); 438 SSB_SPROM4_ITSSI_A_SHIFT);
436 SPEX(gpio0, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P0, 0); 439 if (out->revision == 4) {
437 SPEX(gpio1, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P1, 440 SPEX(gpio0, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P0, 0);
438 SSB_SPROM4_GPIOA_P1_SHIFT); 441 SPEX(gpio1, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P1,
439 SPEX(gpio2, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P2, 0); 442 SSB_SPROM4_GPIOA_P1_SHIFT);
440 SPEX(gpio3, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P3, 443 SPEX(gpio2, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P2, 0);
441 SSB_SPROM4_GPIOB_P3_SHIFT); 444 SPEX(gpio3, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P3,
445 SSB_SPROM4_GPIOB_P3_SHIFT);
446 } else {
447 SPEX(gpio0, SSB_SPROM5_GPIOA, SSB_SPROM5_GPIOA_P0, 0);
448 SPEX(gpio1, SSB_SPROM5_GPIOA, SSB_SPROM5_GPIOA_P1,
449 SSB_SPROM5_GPIOA_P1_SHIFT);
450 SPEX(gpio2, SSB_SPROM5_GPIOB, SSB_SPROM5_GPIOB_P2, 0);
451 SPEX(gpio3, SSB_SPROM5_GPIOB, SSB_SPROM5_GPIOB_P3,
452 SSB_SPROM5_GPIOB_P3_SHIFT);
453 }
442 454
443 /* Extract the antenna gain values. */ 455 /* Extract the antenna gain values. */
444 SPEX(antenna_gain.ghz24.a0, SSB_SPROM4_AGAIN01, 456 SPEX(antenna_gain.ghz24.a0, SSB_SPROM4_AGAIN01,
@@ -462,6 +474,8 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out,
462 474
463 out->revision = in[size - 1] & 0x00FF; 475 out->revision = in[size - 1] & 0x00FF;
464 ssb_dprintk(KERN_DEBUG PFX "SPROM revision %d detected.\n", out->revision); 476 ssb_dprintk(KERN_DEBUG PFX "SPROM revision %d detected.\n", out->revision);
477 memset(out->et0mac, 0xFF, 6); /* preset et0 and et1 mac */
478 memset(out->et1mac, 0xFF, 6);
465 if ((bus->chip_id & 0xFF00) == 0x4400) { 479 if ((bus->chip_id & 0xFF00) == 0x4400) {
466 /* Workaround: The BCM44XX chip has a stupid revision 480 /* Workaround: The BCM44XX chip has a stupid revision
467 * number stored in the SPROM. 481 * number stored in the SPROM.
@@ -471,16 +485,16 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out,
471 } else if (bus->chip_id == 0x4321) { 485 } else if (bus->chip_id == 0x4321) {
472 /* the BCM4328 has a chipid == 0x4321 and a rev 4 SPROM */ 486 /* the BCM4328 has a chipid == 0x4321 and a rev 4 SPROM */
473 out->revision = 4; 487 out->revision = 4;
474 sprom_extract_r4(out, in); 488 sprom_extract_r45(out, in);
475 } else { 489 } else {
476 if (out->revision == 0) 490 if (out->revision == 0)
477 goto unsupported; 491 goto unsupported;
478 if (out->revision >= 1 && out->revision <= 3) { 492 if (out->revision >= 1 && out->revision <= 3) {
479 sprom_extract_r123(out, in); 493 sprom_extract_r123(out, in);
480 } 494 }
481 if (out->revision == 4) 495 if (out->revision == 4 || out->revision == 5)
482 sprom_extract_r4(out, in); 496 sprom_extract_r45(out, in);
483 if (out->revision >= 5) 497 if (out->revision > 5)
484 goto unsupported; 498 goto unsupported;
485 } 499 }
486 500
diff --git a/drivers/ssb/pcmcia.c b/drivers/ssb/pcmcia.c
index 24c2a46c1476..fbfadbac67e8 100644
--- a/drivers/ssb/pcmcia.c
+++ b/drivers/ssb/pcmcia.c
@@ -80,7 +80,7 @@ static int ssb_pcmcia_cfg_write(struct ssb_bus *bus, u8 offset, u8 value)
80 reg.Action = CS_WRITE; 80 reg.Action = CS_WRITE;
81 reg.Value = value; 81 reg.Value = value;
82 res = pcmcia_access_configuration_register(bus->host_pcmcia, &reg); 82 res = pcmcia_access_configuration_register(bus->host_pcmcia, &reg);
83 if (unlikely(res != CS_SUCCESS)) 83 if (unlikely(res != 0))
84 return -EBUSY; 84 return -EBUSY;
85 85
86 return 0; 86 return 0;
@@ -96,7 +96,7 @@ static int ssb_pcmcia_cfg_read(struct ssb_bus *bus, u8 offset, u8 *value)
96 reg.Offset = offset; 96 reg.Offset = offset;
97 reg.Action = CS_READ; 97 reg.Action = CS_READ;
98 res = pcmcia_access_configuration_register(bus->host_pcmcia, &reg); 98 res = pcmcia_access_configuration_register(bus->host_pcmcia, &reg);
99 if (unlikely(res != CS_SUCCESS)) 99 if (unlikely(res != 0))
100 return -EBUSY; 100 return -EBUSY;
101 *value = reg.Value; 101 *value = reg.Value;
102 102
@@ -638,17 +638,17 @@ int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
638 tuple.TupleData = buf; 638 tuple.TupleData = buf;
639 tuple.TupleDataMax = sizeof(buf); 639 tuple.TupleDataMax = sizeof(buf);
640 res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple); 640 res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple);
641 GOTO_ERROR_ON(res != CS_SUCCESS, "MAC first tpl"); 641 GOTO_ERROR_ON(res != 0, "MAC first tpl");
642 res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple); 642 res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
643 GOTO_ERROR_ON(res != CS_SUCCESS, "MAC first tpl data"); 643 GOTO_ERROR_ON(res != 0, "MAC first tpl data");
644 while (1) { 644 while (1) {
645 GOTO_ERROR_ON(tuple.TupleDataLen < 1, "MAC tpl < 1"); 645 GOTO_ERROR_ON(tuple.TupleDataLen < 1, "MAC tpl < 1");
646 if (tuple.TupleData[0] == CISTPL_FUNCE_LAN_NODE_ID) 646 if (tuple.TupleData[0] == CISTPL_FUNCE_LAN_NODE_ID)
647 break; 647 break;
648 res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple); 648 res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple);
649 GOTO_ERROR_ON(res != CS_SUCCESS, "MAC next tpl"); 649 GOTO_ERROR_ON(res != 0, "MAC next tpl");
650 res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple); 650 res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
651 GOTO_ERROR_ON(res != CS_SUCCESS, "MAC next tpl data"); 651 GOTO_ERROR_ON(res != 0, "MAC next tpl data");
652 } 652 }
653 GOTO_ERROR_ON(tuple.TupleDataLen != ETH_ALEN + 2, "MAC tpl size"); 653 GOTO_ERROR_ON(tuple.TupleDataLen != ETH_ALEN + 2, "MAC tpl size");
654 memcpy(sprom->il0mac, &tuple.TupleData[2], ETH_ALEN); 654 memcpy(sprom->il0mac, &tuple.TupleData[2], ETH_ALEN);
@@ -659,9 +659,9 @@ int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
659 tuple.TupleData = buf; 659 tuple.TupleData = buf;
660 tuple.TupleDataMax = sizeof(buf); 660 tuple.TupleDataMax = sizeof(buf);
661 res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple); 661 res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple);
662 GOTO_ERROR_ON(res != CS_SUCCESS, "VEN first tpl"); 662 GOTO_ERROR_ON(res != 0, "VEN first tpl");
663 res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple); 663 res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
664 GOTO_ERROR_ON(res != CS_SUCCESS, "VEN first tpl data"); 664 GOTO_ERROR_ON(res != 0, "VEN first tpl data");
665 while (1) { 665 while (1) {
666 GOTO_ERROR_ON(tuple.TupleDataLen < 1, "VEN tpl < 1"); 666 GOTO_ERROR_ON(tuple.TupleDataLen < 1, "VEN tpl < 1");
667 switch (tuple.TupleData[0]) { 667 switch (tuple.TupleData[0]) {
@@ -733,11 +733,11 @@ int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
733 break; 733 break;
734 } 734 }
735 res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple); 735 res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple);
736 if (res == CS_NO_MORE_ITEMS) 736 if (res == -ENOSPC)
737 break; 737 break;
738 GOTO_ERROR_ON(res != CS_SUCCESS, "VEN next tpl"); 738 GOTO_ERROR_ON(res != 0, "VEN next tpl");
739 res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple); 739 res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
740 GOTO_ERROR_ON(res != CS_SUCCESS, "VEN next tpl data"); 740 GOTO_ERROR_ON(res != 0, "VEN next tpl data");
741 } 741 }
742 742
743 return 0; 743 return 0;