diff options
author | Arend van Spriel <arend@broadcom.com> | 2011-12-08 18:06:50 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-12-13 15:32:24 -0500 |
commit | 5204563ab841fbb5d6ef683635682e155a0a9e84 (patch) | |
tree | bee2e304f959cd434fbcdab0917d152def5d33da /drivers | |
parent | 28a5344261753fadb1731b82c5eeecca708a877c (diff) |
brcm80211: smac: remove enumeration rom parsing function
The core enumeration rom is already parsed by the bcma bus driver and
there is no need to repeat the exercise. The ai_scan() function still
exists but is targetted for removal as well.
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Alwin Beukers <alwin@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Franky Lin <frankyl@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmsmac/aiutils.c | 255 |
1 files changed, 18 insertions, 237 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c index c1e4f35f2955..989dd3ed5b88 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c | |||
@@ -481,247 +481,27 @@ struct aidmp { | |||
481 | u32 componentid3; /* 0xffc */ | 481 | u32 componentid3; /* 0xffc */ |
482 | }; | 482 | }; |
483 | 483 | ||
484 | /* EROM parsing */ | ||
485 | |||
486 | static u32 | ||
487 | get_erom_ent(struct si_pub *sih, u32 __iomem **eromptr, u32 mask, u32 match) | ||
488 | { | ||
489 | u32 ent; | ||
490 | uint inv = 0, nom = 0; | ||
491 | |||
492 | while (true) { | ||
493 | ent = R_REG(*eromptr); | ||
494 | (*eromptr)++; | ||
495 | |||
496 | if (mask == 0) | ||
497 | break; | ||
498 | |||
499 | if ((ent & ER_VALID) == 0) { | ||
500 | inv++; | ||
501 | continue; | ||
502 | } | ||
503 | |||
504 | if (ent == (ER_END | ER_VALID)) | ||
505 | break; | ||
506 | |||
507 | if ((ent & mask) == match) | ||
508 | break; | ||
509 | |||
510 | nom++; | ||
511 | } | ||
512 | |||
513 | return ent; | ||
514 | } | ||
515 | |||
516 | static u32 | ||
517 | get_asd(struct si_pub *sih, u32 __iomem **eromptr, uint sp, uint ad, uint st, | ||
518 | u32 *addrl, u32 *addrh, u32 *sizel, u32 *sizeh) | ||
519 | { | ||
520 | u32 asd, sz, szd; | ||
521 | |||
522 | asd = get_erom_ent(sih, eromptr, ER_VALID, ER_VALID); | ||
523 | if (((asd & ER_TAG1) != ER_ADD) || | ||
524 | (((asd & AD_SP_MASK) >> AD_SP_SHIFT) != sp) || | ||
525 | ((asd & AD_ST_MASK) != st)) { | ||
526 | /* This is not what we want, "push" it back */ | ||
527 | (*eromptr)--; | ||
528 | return 0; | ||
529 | } | ||
530 | *addrl = asd & AD_ADDR_MASK; | ||
531 | if (asd & AD_AG32) | ||
532 | *addrh = get_erom_ent(sih, eromptr, 0, 0); | ||
533 | else | ||
534 | *addrh = 0; | ||
535 | *sizeh = 0; | ||
536 | sz = asd & AD_SZ_MASK; | ||
537 | if (sz == AD_SZ_SZD) { | ||
538 | szd = get_erom_ent(sih, eromptr, 0, 0); | ||
539 | *sizel = szd & SD_SZ_MASK; | ||
540 | if (szd & SD_SG32) | ||
541 | *sizeh = get_erom_ent(sih, eromptr, 0, 0); | ||
542 | } else | ||
543 | *sizel = AD_SZ_BASE << (sz >> AD_SZ_SHIFT); | ||
544 | |||
545 | return asd; | ||
546 | } | ||
547 | |||
548 | static void ai_hwfixup(struct si_info *sii) | ||
549 | { | ||
550 | } | ||
551 | |||
552 | /* parse the enumeration rom to identify all cores */ | 484 | /* parse the enumeration rom to identify all cores */ |
553 | static void ai_scan(struct si_pub *sih, struct chipcregs __iomem *cc) | 485 | static void ai_scan(struct si_pub *sih, struct bcma_bus *bus) |
554 | { | 486 | { |
555 | struct si_info *sii = (struct si_info *)sih; | 487 | struct si_info *sii = (struct si_info *)sih; |
488 | struct bcma_device *core; | ||
489 | uint idx; | ||
556 | 490 | ||
557 | u32 erombase; | 491 | list_for_each_entry(core, &bus->cores, list) { |
558 | u32 __iomem *eromptr, *eromlim; | 492 | idx = core->core_index; |
559 | void __iomem *regs = cc; | 493 | sii->cia[idx] = core->id.manuf << CIA_MFG_SHIFT; |
560 | 494 | sii->cia[idx] |= core->id.id << CIA_CID_SHIFT; | |
561 | erombase = R_REG(&cc->eromptr); | 495 | sii->cia[idx] |= core->id.class << CIA_CCL_SHIFT; |
562 | 496 | sii->cib[idx] = core->id.rev << CIB_REV_SHIFT; | |
563 | /* Set wrappers address */ | 497 | sii->coreid[idx] = core->id.id; |
564 | sii->curwrap = (void *)((unsigned long)cc + SI_CORE_SIZE); | 498 | sii->coresba[idx] = core->addr; |
565 | 499 | sii->coresba_size[idx] = 0x1000; | |
566 | /* Now point the window at the erom */ | 500 | sii->coresba2[idx] = 0; |
567 | pci_write_config_dword(sii->pcibus, PCI_BAR0_WIN, erombase); | 501 | sii->coresba2_size[idx] = 0; |
568 | eromptr = regs; | 502 | sii->wrapba[idx] = core->wrap; |
569 | eromlim = eromptr + (ER_REMAPCONTROL / sizeof(u32)); | ||
570 | |||
571 | while (eromptr < eromlim) { | ||
572 | u32 cia, cib, cid, mfg, crev, nmw, nsw, nmp, nsp; | ||
573 | u32 mpd, asd, addrl, addrh, sizel, sizeh; | ||
574 | u32 __iomem *base; | ||
575 | uint i, j, idx; | ||
576 | bool br; | ||
577 | |||
578 | br = false; | ||
579 | |||
580 | /* Grok a component */ | ||
581 | cia = get_erom_ent(sih, &eromptr, ER_TAG, ER_CI); | ||
582 | if (cia == (ER_END | ER_VALID)) { | ||
583 | /* Found END of erom */ | ||
584 | ai_hwfixup(sii); | ||
585 | return; | ||
586 | } | ||
587 | base = eromptr - 1; | ||
588 | cib = get_erom_ent(sih, &eromptr, 0, 0); | ||
589 | |||
590 | if ((cib & ER_TAG) != ER_CI) { | ||
591 | /* CIA not followed by CIB */ | ||
592 | goto error; | ||
593 | } | ||
594 | |||
595 | cid = (cia & CIA_CID_MASK) >> CIA_CID_SHIFT; | ||
596 | mfg = (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT; | ||
597 | crev = (cib & CIB_REV_MASK) >> CIB_REV_SHIFT; | ||
598 | nmw = (cib & CIB_NMW_MASK) >> CIB_NMW_SHIFT; | ||
599 | nsw = (cib & CIB_NSW_MASK) >> CIB_NSW_SHIFT; | ||
600 | nmp = (cib & CIB_NMP_MASK) >> CIB_NMP_SHIFT; | ||
601 | nsp = (cib & CIB_NSP_MASK) >> CIB_NSP_SHIFT; | ||
602 | |||
603 | if (((mfg == MFGID_ARM) && (cid == DEF_AI_COMP)) || (nsp == 0)) | ||
604 | continue; | ||
605 | if ((nmw + nsw == 0)) { | ||
606 | /* A component which is not a core */ | ||
607 | if (cid == OOB_ROUTER_CORE_ID) { | ||
608 | asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, | ||
609 | &addrl, &addrh, &sizel, &sizeh); | ||
610 | if (asd != 0) | ||
611 | sii->oob_router = addrl; | ||
612 | } | ||
613 | continue; | ||
614 | } | ||
615 | |||
616 | idx = sii->numcores; | ||
617 | /* sii->eromptr[idx] = base; */ | ||
618 | sii->cia[idx] = cia; | ||
619 | sii->cib[idx] = cib; | ||
620 | sii->coreid[idx] = cid; | ||
621 | |||
622 | for (i = 0; i < nmp; i++) { | ||
623 | mpd = get_erom_ent(sih, &eromptr, ER_VALID, ER_VALID); | ||
624 | if ((mpd & ER_TAG) != ER_MP) { | ||
625 | /* Not enough MP entries for component */ | ||
626 | goto error; | ||
627 | } | ||
628 | } | ||
629 | |||
630 | /* First Slave Address Descriptor should be port 0: | ||
631 | * the main register space for the core | ||
632 | */ | ||
633 | asd = | ||
634 | get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, &addrl, &addrh, | ||
635 | &sizel, &sizeh); | ||
636 | if (asd == 0) { | ||
637 | /* Try again to see if it is a bridge */ | ||
638 | asd = | ||
639 | get_asd(sih, &eromptr, 0, 0, AD_ST_BRIDGE, &addrl, | ||
640 | &addrh, &sizel, &sizeh); | ||
641 | if (asd != 0) | ||
642 | br = true; | ||
643 | else if ((addrh != 0) || (sizeh != 0) | ||
644 | || (sizel != SI_CORE_SIZE)) { | ||
645 | /* First Slave ASD for core malformed */ | ||
646 | goto error; | ||
647 | } | ||
648 | } | ||
649 | sii->coresba[idx] = addrl; | ||
650 | sii->coresba_size[idx] = sizel; | ||
651 | /* Get any more ASDs in port 0 */ | ||
652 | j = 1; | ||
653 | do { | ||
654 | asd = | ||
655 | get_asd(sih, &eromptr, 0, j, AD_ST_SLAVE, &addrl, | ||
656 | &addrh, &sizel, &sizeh); | ||
657 | if ((asd != 0) && (j == 1) && (sizel == SI_CORE_SIZE)) { | ||
658 | sii->coresba2[idx] = addrl; | ||
659 | sii->coresba2_size[idx] = sizel; | ||
660 | } | ||
661 | j++; | ||
662 | } while (asd != 0); | ||
663 | |||
664 | /* Go through the ASDs for other slave ports */ | ||
665 | for (i = 1; i < nsp; i++) { | ||
666 | j = 0; | ||
667 | do { | ||
668 | asd = | ||
669 | get_asd(sih, &eromptr, i, j++, AD_ST_SLAVE, | ||
670 | &addrl, &addrh, &sizel, &sizeh); | ||
671 | } while (asd != 0); | ||
672 | if (j == 0) { | ||
673 | /* SP has no address descriptors */ | ||
674 | goto error; | ||
675 | } | ||
676 | } | ||
677 | |||
678 | /* Now get master wrappers */ | ||
679 | for (i = 0; i < nmw; i++) { | ||
680 | asd = | ||
681 | get_asd(sih, &eromptr, i, 0, AD_ST_MWRAP, &addrl, | ||
682 | &addrh, &sizel, &sizeh); | ||
683 | if (asd == 0) { | ||
684 | /* Missing descriptor for MW */ | ||
685 | goto error; | ||
686 | } | ||
687 | if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) { | ||
688 | /* Master wrapper %d is not 4KB */ | ||
689 | goto error; | ||
690 | } | ||
691 | if (i == 0) | ||
692 | sii->wrapba[idx] = addrl; | ||
693 | } | ||
694 | |||
695 | /* And finally slave wrappers */ | ||
696 | for (i = 0; i < nsw; i++) { | ||
697 | uint fwp = (nsp == 1) ? 0 : 1; | ||
698 | asd = | ||
699 | get_asd(sih, &eromptr, fwp + i, 0, AD_ST_SWRAP, | ||
700 | &addrl, &addrh, &sizel, &sizeh); | ||
701 | if (asd == 0) { | ||
702 | /* Missing descriptor for SW */ | ||
703 | goto error; | ||
704 | } | ||
705 | if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) { | ||
706 | /* Slave wrapper is not 4KB */ | ||
707 | goto error; | ||
708 | } | ||
709 | if ((nmw == 0) && (i == 0)) | ||
710 | sii->wrapba[idx] = addrl; | ||
711 | } | ||
712 | |||
713 | /* Don't record bridges */ | ||
714 | if (br) | ||
715 | continue; | ||
716 | |||
717 | /* Done with core */ | ||
718 | sii->numcores++; | 503 | sii->numcores++; |
719 | } | 504 | } |
720 | |||
721 | error: | ||
722 | /* Reached end of erom without finding END */ | ||
723 | sii->numcores = 0; | ||
724 | return; | ||
725 | } | 505 | } |
726 | 506 | ||
727 | /* | 507 | /* |
@@ -1039,8 +819,9 @@ static struct si_info *ai_doattach(struct si_info *sii, | |||
1039 | 819 | ||
1040 | sii->icbus = pbus; | 820 | sii->icbus = pbus; |
1041 | sii->buscoreidx = BADIDX; | 821 | sii->buscoreidx = BADIDX; |
1042 | sii->curmap = regs; | ||
1043 | sii->pcibus = pbus->host_pci; | 822 | sii->pcibus = pbus->host_pci; |
823 | sii->curmap = regs; | ||
824 | sii->curwrap = sii->curmap + SI_CORE_SIZE; | ||
1044 | 825 | ||
1045 | /* find Chipcommon address */ | 826 | /* find Chipcommon address */ |
1046 | pci_read_config_dword(sii->pcibus, PCI_BAR0_WIN, &savewin); | 827 | pci_read_config_dword(sii->pcibus, PCI_BAR0_WIN, &savewin); |
@@ -1073,7 +854,7 @@ static struct si_info *ai_doattach(struct si_info *sii, | |||
1073 | if (socitype == SOCI_AI) { | 854 | if (socitype == SOCI_AI) { |
1074 | SI_MSG("Found chip type AI (0x%08x)\n", w); | 855 | SI_MSG("Found chip type AI (0x%08x)\n", w); |
1075 | /* pass chipc address instead of original core base */ | 856 | /* pass chipc address instead of original core base */ |
1076 | ai_scan(&sii->pub, cc); | 857 | ai_scan(&sii->pub, pbus); |
1077 | } else { | 858 | } else { |
1078 | /* Found chip of unknown type */ | 859 | /* Found chip of unknown type */ |
1079 | return NULL; | 860 | return NULL; |