sbutils.c
上传用户:yuanda199
上传日期:2022-06-26
资源大小:412k
文件大小:46k
源码类别:

VxWorks

开发平台:

C/C++

  1. /*
  2.  * Misc utility routines for accessing chip-specific features
  3.  * of the SiliconBackplane-based Broadcom chips.
  4.  *
  5.  * Copyright(c) 2001 Broadcom Corp.
  6.  * $Id: sbutils.c,v 1.1 Broadcom SDK $
  7.  */
  8. #include <hnbutypedefs.h>
  9. #include <osl.h>
  10. #include <bcmutils.h>
  11. #include <bcmdevs.h>
  12. #include <sbconfig.h>
  13. #include <sbchipc.h>
  14. #include <sbpci.h>
  15. #include <sbpcmcia.h>
  16. #include <sbextif.h>
  17. #include <sbutils.h>
  18. #include <bcmendian.h>
  19. #ifndef BROADCOM_BSP
  20. #include <bcmnvram.h>
  21. #endif
  22. /* debug/trace */
  23. #ifdef BCMDBG
  24. #define SB_ERROR(args) printf args
  25. #else
  26. #define SB_ERROR(args)
  27. #endif
  28. /* misc sb info needed by some of the routines */
  29. typedef struct sb_info {
  30. uint chip; /* chip number */
  31. uint chiprev; /* chip revision */
  32. uint16 board; /* board id */
  33. uint16 boardvendor; /* board vendor id */
  34. uint bus; /* what bus type we are going through */
  35. void *osh; /* osl os handle */
  36. void *curmap; /* current regs va */
  37. void *origregs; /* initial core registers va */
  38. uint origcoreidx; /* initial core index */
  39. uint pciidx; /* pci core index */
  40. uint pcirev; /* pci core rev */
  41. uint gpioidx; /* gpio control core index */
  42. uint gpioid; /* gpio control coretype */
  43. uint numcores; /* # discovered cores */
  44. uint coreid[SB_MAXCORES]; /* id of each core */
  45. } sb_info_t;
  46. /* local prototypes */
  47. static void sb_scan(sb_info_t *si);
  48. static uint sb_corereg(void *sbh, uint coreidx, uint regoff, uint mask, uint val);
  49. static uint sb_findcoreidx(void *sbh, uint coreid, uint coreunit);
  50. static uint sb_pcidev2chip(uint pcidev);
  51. static int sb_initvars(sb_info_t *si, char **vars, int *count);
  52. static int srominitvars(sb_info_t *si, char **vars, int *count);
  53. static int cisinitvars(sb_info_t *si, char **vars, int *count);
  54. /* A cis parsing routine that can be called externally */
  55. int parsecis(uint8 *cis, char **vars, int *count);
  56. static void msecs(uint ms);
  57. #define SB_INFO(sbh) (sb_info_t*)sbh
  58. #define SET_SBREG(sbh, r, mask, val) W_SBREG((sbh), (r), ((R_SBREG(r) & ~(mask)) | (val)));
  59. #define GOODCOREADDR(x) (((x) >= SB_ENUM_BASE) && ((x) <= SB_ENUM_LIM) 
  60. && ISALIGNED((x), SB_CORE_SIZE))
  61. #define GOODREGS(regs) (regs && ISALIGNED(regs, SB_CORE_SIZE))
  62. #define REGS2SB(va) (sbconfig_t*) ((uint)(va) + SBCONFIGOFF)
  63. #define GOODIDX(idx) (((uint)idx) < SB_MAXCORES)
  64. #define BADIDX (SB_MAXCORES+1)
  65. /*
  66.  * Macros to read/write sbconfig registers. On the PCMCIA core rev 0
  67.  * we need to treat them differently from other registers. See PR 3863.
  68.  */
  69. #define R_SBREG(sbr) R_REG(sbr)
  70. #define W_SBREG(sbh, sbr, v) sb_write_sbreg((sbh), (sbr), (v))
  71. #define AND_SBREG(sbh, sbr, v) W_SBREG((sbh), (sbr), (R_SBREG(sbr) & (v)))
  72. #define OR_SBREG(sbh, sbr, v) W_SBREG((sbh), (sbr), (R_SBREG(sbr) | (v)))
  73. /* implement PR3863 workaround for the PCMCIA core rev 0 */
  74. static void
  75. sb_write_sbreg(void *sbh, volatile uint32 *sbr, uint32 v)
  76. {
  77. sb_info_t *si;
  78. volatile uint32 dummy;
  79. si = SB_INFO(sbh);
  80. if ((si->bus == PCMCIA_BUS) && (sb_corerev(sbh) == 0)) {
  81. #ifdef IL_BIGENDIAN
  82. dummy = R_REG(sbr);
  83. W_REG((volatile uint16 *)((uint32)sbr + 2), (uint16)((v >> 16) & 0xffff));
  84. dummy = R_REG(sbr);
  85. W_REG((volatile uint16 *)sbr, (uint16)(v & 0xffff));
  86. #else
  87. dummy = R_REG(sbr);
  88. W_REG((volatile uint16 *)sbr, (uint16)(v & 0xffff));
  89. dummy = R_REG(sbr);
  90. W_REG((volatile uint16 *)((uint32)sbr + 2), (uint16)((v >> 16) & 0xffff));
  91. #endif
  92. } else
  93. W_REG(sbr, v);
  94. }
  95. /*
  96.  * Allocate a sb handle.
  97.  * devid - pci device id (used to determine chip#)
  98.  * osh - opaque OS handle
  99.  * regs - virtual address of initial core registers
  100.  * vars - pointer to a pointer area for "environment" variables
  101.  * varsz - pointer to int to return the size of the vars
  102.  */
  103. void*
  104. sb_attach(uint devid, void *osh, void *regs, char **vars, int *varsz)
  105. {
  106. sb_info_t *si;
  107. uint ccidx;
  108. uint chipid;
  109. uint32 w;
  110. ASSERT(GOODREGS(regs));
  111. /* alloc sb_info_t */
  112. if ((si = MALLOC(sizeof (sb_info_t))) == NULL) {
  113. SB_ERROR(("sb_attach: malloc failed!n"));
  114. return (NULL);
  115. }
  116. bzero((uchar*)si, sizeof (sb_info_t));
  117. si->pciidx = si->gpioidx = BADIDX;
  118. si->osh = osh;
  119. si->origregs = si->curmap = regs;
  120. /* determine bus type we're operating over */
  121. if (sb_coreid((void *)si) == SB_PCMCIA) {
  122. si->bus = PCMCIA_BUS;
  123. } else {
  124.         if (osh == NULL) {
  125. si->bus = SB_BUS;
  126.         } else {
  127. /* check to see if we are a sb core mimic'ing a pci core */
  128. if (OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof (uint32)) == 0xffffffff)
  129. si->bus = SB_BUS;
  130. else
  131. si->bus = PCI_BUS;
  132.         }
  133. }
  134. /* keep and reuse the initial register mapping */
  135. si->origcoreidx = sb_coreidx((void*)si);
  136. /* scan for cores */
  137. sb_scan(si);
  138. /* pci core is required */
  139. if (!GOODIDX(si->pciidx)) {
  140. SB_ERROR(("sb_attach: pci core not foundn"));
  141. goto bad;
  142. }
  143. /* gpio control core is required */
  144. if (!GOODIDX(si->gpioidx)) {
  145. SB_ERROR(("sb_attach: gpio control core not foundn"));
  146. goto bad;
  147. }
  148. /* initialize the vars */
  149. if (sb_initvars(si, vars, varsz) != 0) {
  150. SB_ERROR(("sb_attach: sb_initvars failedn"));
  151. goto bad;
  152. }
  153. /* determine chip id and rev */
  154. ccidx = sb_findcoreidx((void*)si, SB_CC, 0);
  155. if (GOODIDX(ccidx)) {
  156. /* easy - found chipcommon core */
  157. chipid = sb_corereg((void*)si, ccidx, OFFSETOF(chipcregs_t, chipid), 0, 0);
  158. si->chip = chipid & CID_ID_MASK;
  159. si->chiprev = (chipid & CID_REV_MASK) >> CID_REV_SHIFT;
  160. /* PR10654: The chipid register on 4306a1 lies */
  161. if ((si->chip == 0x4306) && (si->chiprev == 0))
  162. goto bad4306;
  163. } else {
  164. /* hard - no chipcommon core - must convert device id to chip id */
  165. if ((si->chip = sb_pcidev2chip(devid)) == 0) {
  166. SB_ERROR(("sb_attach: unrecognized device id 0x%04xn", devid));
  167. goto bad;
  168. }
  169. /*
  170.  * The chip revision number is hardwired into all
  171.  * of the pci function config rev fields and is
  172.  * independent from the individual core revision numbers.
  173.  * For example, the "A0" silicon of each chip is chip rev 0.
  174.  * For PCMCIA we get it from the CIS instead.
  175.  */
  176. if (si->bus == PCMCIA_BUS)
  177. #ifndef BROADCOM_BSP  /* we don't use PCMCIA */
  178. si->chiprev = (uint)getintvar(*vars, "chiprev");
  179. #else
  180.                         ;
  181. #endif
  182. else {
  183. bad4306: w = OSL_PCI_READ_CONFIG(osh, 8, sizeof (uint32));
  184. si->chiprev = w & 0xff;
  185. }
  186. }
  187. /* sanity checks */
  188. ASSERT(si->chip);
  189. ASSERT(si->chiprev < 8);
  190. /* get boardtype and boardrev */
  191. if (si->bus == PCMCIA_BUS) {
  192. #ifndef BROADCOM_BSP
  193. si->board = (uint16)getintvar(*vars, "prodid");
  194. si->boardvendor = (uint16)getintvar(*vars, "manfid");
  195. #endif
  196. } else {
  197. /* do a pci config read to get subsystem id and subvendor id */
  198. w = OSL_PCI_READ_CONFIG(osh, 0x2c, sizeof (uint32));
  199. si->board = (w >> 16) & 0xffff;
  200. si->boardvendor = w & 0xffff;
  201. }
  202. /* XXX temp d11 kludge */
  203. if (si->bus == PCMCIA_BUS) {
  204. /* set the d11 core instead of pcmcia */
  205. regs = sb_setcore((void *)si, SB_D11, 0);
  206. /* reset origregs, curmap and origcoreidx */
  207. si->origregs = si->curmap = regs;
  208. si->origcoreidx = sb_coreidx((void*)si);
  209. }
  210. return ((void*)si);
  211. bad:
  212. MFREE(si, sizeof (sb_info_t));
  213. return (NULL);
  214. }
  215. /* kernel caller variant of sb_attach() */
  216. void*
  217. sb_kattach(uint chip, uint chiprev)
  218. {
  219. sb_info_t *si;
  220. uint ccidx, chipid;
  221. /* alloc sb_info_t */
  222. if ((si = MALLOC(sizeof (sb_info_t))) == NULL) {
  223. SB_ERROR(("sb_kattach: malloc failed!n"));
  224. return (NULL);
  225. }
  226. bzero((uchar*)si, sizeof (sb_info_t));
  227. si->pciidx = si->gpioidx = BADIDX;
  228. si->bus = SB_BUS;
  229. /* core0 is default */
  230. si->origcoreidx = 0;
  231. si->origregs = si->curmap = (void*)REG_MAP(SB_ENUM_BASE, SB_CORE_SIZE);
  232. /* scan for cores */
  233. sb_scan(si);
  234. /* pci core is required */
  235. if (!GOODIDX(si->pciidx)) {
  236. SB_ERROR(("sb_attach: pci core not foundn"));
  237. goto bad;
  238. }
  239. /* gpio control core is required */
  240. if (!GOODIDX(si->gpioidx)) {
  241. SB_ERROR(("sb_attach: gpio control core not foundn"));
  242. goto bad;
  243. }
  244. /* determine chip id and rev */
  245. ccidx = sb_findcoreidx((void*)si, SB_CC, 0);
  246. if (GOODIDX(ccidx)) {
  247. /* easy - chipcommon core exists */
  248. chipid = sb_corereg((void*)si, ccidx, OFFSETOF(chipcregs_t, chipid), 0, 0);
  249. si->chip = chipid & CID_ID_MASK;
  250. si->chiprev = (chipid & CID_REV_MASK) >> CID_REV_SHIFT;
  251. }
  252. else {
  253. /* no chipcommon core - just use what we're told */
  254. si->chip = chip;
  255. si->chiprev = chiprev;
  256. }
  257. /* sanity checks */
  258. ASSERT(chip);
  259. ASSERT(chiprev < 8);
  260. return ((void*)si);
  261. bad:
  262. MFREE(si, sizeof (sb_info_t));
  263. return (NULL);
  264. }
  265. uint
  266. sb_coreid(void *sbh)
  267. {
  268. sb_info_t *si;
  269. sbconfig_t *sb;
  270. si = SB_INFO(sbh);
  271. sb = REGS2SB(si->curmap);
  272. return ((R_SBREG(&(sb)->sbidhigh) & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT);
  273. }
  274. /* return current index of core */
  275. uint
  276. sb_coreidx(void *sbh)
  277. {
  278. sb_info_t *si;
  279. sbconfig_t *sb;
  280. uint32 sbaddr = 0;
  281. si = SB_INFO(sbh);
  282. ASSERT(si);
  283. switch (si->bus) {
  284. case SB_BUS:
  285. sb = REGS2SB(si->curmap);
  286. sbaddr = sb_base(R_SBREG(&sb->sbadmatch0));
  287. break;
  288. case PCI_BUS:
  289. sbaddr = OSL_PCI_READ_CONFIG(si->osh, PCI_BAR0_WIN, sizeof (uint32));
  290. break;
  291. case PCMCIA_BUS: {
  292. uint8 tmp;
  293. OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR0, &tmp, 1);
  294. sbaddr  = (uint)tmp << 12;
  295. OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR1, &tmp, 1);
  296. sbaddr |= (uint)tmp << 16;
  297. OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR2, &tmp, 1);
  298. sbaddr |= (uint)tmp << 24;
  299. break;
  300. }
  301. default:
  302. ASSERT(0);
  303. }
  304. ASSERT(GOODCOREADDR(sbaddr));
  305. return ((sbaddr - SB_ENUM_BASE)/SB_CORE_SIZE);
  306. }
  307. uint
  308. sb_corevendor(void *sbh)
  309. {
  310. sb_info_t *si;
  311. sbconfig_t *sb;
  312. si = SB_INFO(sbh);
  313. sb = REGS2SB(si->curmap);
  314. return ((R_SBREG(&(sb)->sbidhigh) & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT);
  315. }
  316. uint
  317. sb_corerev(void *sbh)
  318. {
  319. sb_info_t *si;
  320. sbconfig_t *sb;
  321. si = SB_INFO(sbh);
  322. sb = REGS2SB(si->curmap);
  323. return (R_SBREG(&(sb)->sbidhigh) & SBIDH_RC_MASK);
  324. }
  325. #define SBTML_ALLOW (SBTML_PE | SBTML_FGC | SBTML_FL_MASK)
  326. /* set/clear one or more sbtmstatelow core-specific flag or pme bits */
  327. uint32
  328. sb_coreflags(void *sbh, uint32 mask, uint32 val)
  329. {
  330. sb_info_t *si;
  331. sbconfig_t *sb;
  332. uint32 w;
  333. si = SB_INFO(sbh);
  334. sb = REGS2SB(si->curmap);
  335. ASSERT((val & ~mask) == 0);
  336. ASSERT((mask & ~SBTML_ALLOW) == 0);
  337. /* mask and set */
  338. if (mask || val) {
  339. w = (R_SBREG(&sb->sbtmstatelow) & ~mask) | val;
  340. W_SBREG(sbh, &sb->sbtmstatelow, w);
  341. }
  342. /* return the new value */
  343. return (R_SBREG(&sb->sbtmstatelow) & SBTML_ALLOW);
  344. }
  345. bool
  346. sb_iscoreup(void *sbh)
  347. {
  348. sb_info_t *si;
  349. sbconfig_t *sb;
  350. si = SB_INFO(sbh);
  351. sb = REGS2SB(si->curmap);
  352. return ((R_SBREG(&(sb)->sbtmstatelow) & (SBTML_RESET | SBTML_REJ | SBTML_CLK)) == SBTML_CLK);
  353. }
  354. /*
  355.  * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation,
  356.  * switch back to the original core, and return the new value.
  357.  */
  358. static uint
  359. sb_corereg(void *sbh, uint coreidx, uint regoff, uint mask, uint val)
  360. {
  361. sb_info_t *si;
  362. uint origidx;
  363. uint32 *r;
  364. uint w;
  365. ASSERT(GOODIDX(coreidx));
  366. ASSERT(regoff < SB_CORE_SIZE);
  367. ASSERT((val & ~mask) == 0);
  368. si = SB_INFO(sbh);
  369. /* save current core index */
  370. origidx = sb_coreidx(sbh);
  371. /* switch core */
  372. if (origidx != coreidx)
  373. r = (uint32*) ((uint) sb_setcoreidx(sbh, coreidx) + regoff);
  374. else
  375. r = (uint32*) ((uint) si->curmap + regoff);
  376. /* mask and set */
  377. if (mask || val) {
  378. w = (R_SBREG(r) & ~mask) | val;
  379. W_SBREG(sbh, r, w);
  380. }
  381. /* readback */
  382. w = R_SBREG(r);
  383. /* restore core index */
  384. if (origidx != coreidx)
  385. sb_setcoreidx(sbh, origidx);
  386. return (w);
  387. }
  388. /* scan the sb enumerated space to find all cores */
  389. static void
  390. sb_scan(sb_info_t *si)
  391. {
  392. void *sbh;
  393. sbconfig_t *sb;
  394. uint32 sbidhigh;
  395. void *regs;
  396. uint busidx;
  397. uint idx;
  398. uint id;
  399. int i;
  400. sbh = (void*) si;
  401. /* busidx is the index of our "active" pci or pcmcia core */
  402. busidx = BADIDX;
  403. /* required by sb_setcoreidx() */
  404. si->numcores = SB_MAXCORES;
  405. /* save current core index */
  406. idx = sb_coreidx(sbh);
  407. for (i = 0; i < SB_MAXCORES; i++) {
  408. regs = sb_setcoreidx(sbh, i);
  409. sb = REGS2SB(regs);
  410. /* target abort at end of enumerated cores */
  411. sbidhigh = 0;
  412. BUSPROBE(sbidhigh, (&sb->sbidhigh));
  413. if ((sbidhigh == 0xffffffff) || (sbidhigh == 0))
  414. break;
  415. /*
  416.  * Some PC chipsets don't return all ones or all zeros on target abort.
  417.  * Check pci/pcmcia for sbimstate.inbanderror.
  418.  */
  419. if (GOODIDX(busidx) && (sb_corereg(sbh, busidx,
  420. (SBCONFIGOFF + SBIMSTATE), 0, 0) & SBIM_IBE))
  421. break;
  422. /* found a core */
  423. id = sb_coreid(sbh);
  424. si->coreid[i] = id;
  425. /* locate our bus adapter core and clear sbimstate.inbanderror */
  426. if (((si->bus == PCI_BUS) && (id == SB_PCI))
  427. || ((si->bus == PCMCIA_BUS) && (id == SB_PCMCIA))) {
  428. busidx = i;
  429. SET_SBREG(sbh, &sb->sbimstate, SBIM_IBE, 0);
  430. }
  431. /* save pci core rev */
  432. if (id == SB_PCI)
  433. si->pcirev = sb_corerev(sbh);
  434. }
  435. si->numcores = i;
  436. /* find pci core */
  437. si->pciidx = sb_findcoreidx(sbh, SB_PCI, 0);
  438. /*
  439.  * Find the gpio "controlling core" type and index.
  440.  * Precedence:
  441.  * - if there's a chip common core - use that
  442.  * - else if there's a pci core (rev >= 2) - use that
  443.  * - else there had better be an extif core (4710 only)
  444.  */
  445. if (GOODIDX(sb_findcoreidx(sbh, SB_CC, 0))) {
  446. si->gpioidx = sb_findcoreidx(sbh, SB_CC, 0);
  447. si->gpioid = SB_CC;
  448. } else if (GOODIDX(si->pciidx) && (si->pcirev >= 2)) {
  449. si->gpioidx = si->pciidx;
  450. si->gpioid = SB_PCI;
  451. } else if (sb_findcoreidx(sbh, SB_EXTIF, 0)) {
  452. si->gpioidx = sb_findcoreidx(sbh, SB_EXTIF, 0);
  453. si->gpioid = SB_EXTIF;
  454. }
  455. /* restore core index */
  456. sb_setcoreidx(sbh, idx);
  457. }
  458. void
  459. sb_detach(void *sbh)
  460. {
  461. sb_info_t *si;
  462. si = SB_INFO(sbh);
  463. if (si == NULL)
  464. return;
  465. if ((si->bus == SB_BUS) && si->curmap && (si->curmap != si->origregs)) {
  466. ASSERT(GOODREGS(si->curmap));
  467. REG_UNMAP(si->curmap);
  468. si->curmap = NULL;
  469. }
  470. MFREE(si, sizeof (sb_info_t));
  471. }
  472. /* use pci dev id to determine chip id for chips not having a chipcommon core */
  473. static uint
  474. sb_pcidev2chip(uint pcidev)
  475. {
  476. if ((pcidev >= BCM4710_DEVICE_ID) && (pcidev <= BCM47XX_USB_ID))
  477. return (BCM4710_DEVICE_ID);
  478. if ((pcidev >= BCM4610_DEVICE_ID) && (pcidev <= BCM4610_USB_ID))
  479. return (BCM4610_DEVICE_ID);
  480. if ((pcidev >= BCM4402_DEVICE_ID) && (pcidev <= BCM4402_V90_ID))
  481. return (BCM4402_DEVICE_ID);
  482. if ((pcidev >= BCM4307_V90_ID) && (pcidev <= BCM4307_D11B_ID))
  483. return (BCM4307_DEVICE_ID);
  484. if (pcidev == BCM4301_DEVICE_ID)
  485. return (BCM4301_DEVICE_ID);
  486. if ((pcidev >= BCM4309_DEVICE_ID) && (pcidev <= BCM4309_D11DUAL_ID))
  487. return (BCM4309_DEVICE_ID);
  488. return (0);
  489. }
  490. /* return index of coreid or BADIDX if not found */
  491. static uint
  492. sb_findcoreidx(void *sbh, uint coreid, uint coreunit)
  493. {
  494. sb_info_t *si;
  495. uint found;
  496. uint i;
  497. si = SB_INFO(sbh);
  498. found = 0;
  499. for (i = 0; i < si->numcores; i++)
  500. if (si->coreid[i] == coreid) {
  501. if (found == coreunit)
  502. return (i);
  503. found++;
  504. }
  505. return (BADIDX);
  506. }
  507. /* change logical "focus" to the indiciated core */
  508. void*
  509. sb_setcoreidx(void *sbh, uint coreidx)
  510. {
  511. sb_info_t *si;
  512. uint32 sbaddr;
  513. uint8 tmp;
  514. si = SB_INFO(sbh);
  515. if (coreidx >= si->numcores)
  516. return (NULL);
  517. sbaddr = SB_ENUM_BASE + (coreidx * SB_CORE_SIZE);
  518. switch (si->bus) {
  519. case SB_BUS:
  520. /* unmap any previous one */
  521. if (si->curmap && (si->curmap != si->origregs)) {
  522. ASSERT(GOODREGS(si->curmap));
  523. REG_UNMAP(si->curmap);
  524. si->curmap = NULL;
  525. }
  526. /* keep and reuse the initial register mapping */
  527. if (coreidx == si->origcoreidx) {
  528. si->curmap = si->origregs;
  529. return (si->curmap);
  530. }
  531. /* map new one */
  532. si->curmap = (void*)REG_MAP(sbaddr, SB_CORE_SIZE);
  533. ASSERT(GOODREGS(si->curmap));
  534. break;
  535. case PCI_BUS:
  536. /* point bar0 window */
  537. OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, 4, sbaddr);
  538. break;
  539. case PCMCIA_BUS:
  540. tmp = (sbaddr >> 12) & 0x0f;
  541. OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR0, &tmp, 1);
  542. tmp = (sbaddr >> 16) & 0xff;
  543. OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR1, &tmp, 1);
  544. tmp = (sbaddr >> 24) & 0xff;
  545. OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR2, &tmp, 1);
  546. break;
  547. }
  548. return (si->curmap);
  549. }
  550. /* change logical "focus" to the indicated core */
  551. void*
  552. sb_setcore(void *sbh, uint coreid, uint coreunit)
  553. {
  554. sb_info_t *si;
  555. uint idx;
  556. si = SB_INFO(sbh);
  557. idx = sb_findcoreidx(sbh, coreid, coreunit);
  558. if (!GOODIDX(idx))
  559. return (NULL);
  560. return (sb_setcoreidx(sbh, idx));
  561. }
  562. /* return chip number */
  563. uint
  564. sb_chip(void *sbh)
  565. {
  566. sb_info_t *si;
  567. si = SB_INFO(sbh);
  568. return (si->chip);
  569. }
  570. /* return chip revision number */
  571. uint
  572. sb_chiprev(void *sbh)
  573. {
  574. sb_info_t *si;
  575. si = SB_INFO(sbh);
  576. return (si->chiprev);
  577. }
  578. /* return board type */
  579. uint16
  580. sb_board(void *sbh)
  581. {
  582. sb_info_t *si;
  583. si = SB_INFO(sbh);
  584. return (si->board);
  585. }
  586. /* return board vendor id */
  587. uint16
  588. sb_boardvendor(void *sbh)
  589. {
  590. sb_info_t *si;
  591. si = SB_INFO(sbh);
  592. return (si->boardvendor);
  593. }
  594. /* return boolean if sbh device is in pci hostmode or client mode */
  595. uint
  596. sb_bus(void *sbh)
  597. {
  598. sb_info_t *si;
  599. si = SB_INFO(sbh);
  600. return (si->bus);
  601. }
  602. /* return list of found cores */
  603. uint
  604. sb_corelist(void *sbh, uint coreid[])
  605. {
  606. sb_info_t *si;
  607. si = SB_INFO(sbh);
  608. bcopy((uchar*)si->coreid, (uchar*)coreid, (si->numcores * sizeof (uint)));
  609. return (si->numcores);
  610. }
  611. /* do buffered registers update */
  612. void
  613. sb_commit(void *sbh)
  614. {
  615. sb_info_t *si;
  616. sbpciregs_t *pciregs;
  617. uint idx;
  618. si = SB_INFO(sbh);
  619. idx = BADIDX;
  620. /* switch over to the pci core if necessary */
  621. if (sb_coreid(sbh) == SB_PCI)
  622. pciregs = (sbpciregs_t*) si->curmap;
  623. else {
  624. /* save current core index */
  625. idx = sb_coreidx(sbh);
  626. ASSERT(GOODIDX(idx));
  627. /* switch over to pci core */
  628. pciregs = (sbpciregs_t*) sb_setcore(sbh, SB_PCI, 0);
  629. }
  630. /* do the buffer registers update */
  631. W_REG(&pciregs->bcastaddr, SB_COMMIT);
  632. W_REG(&pciregs->bcastdata, 0x0);
  633. /* restore core index */
  634. if (GOODIDX(idx))
  635. sb_setcoreidx(sbh, idx);
  636. }
  637. /* reset and re-enable a core */
  638. void
  639. sb_core_reset(void *sbh, uint32 bits)
  640. {
  641. sb_info_t *si;
  642. sbconfig_t *sb;
  643. volatile uint32 dummy;
  644. si = SB_INFO(sbh);
  645. ASSERT(GOODREGS(si->curmap));
  646. sb = REGS2SB(si->curmap);
  647. /*
  648.  * Must do the disable sequence first to work for arbitrary current core state.
  649.  */
  650. sb_core_disable(sbh, bits);
  651. /*
  652.  * Now do the initialization sequence.
  653.  */
  654. /* set reset while enabling the clock and forcing them on throughout the core */
  655. W_SBREG(sbh, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | SBTML_RESET | bits));
  656. dummy = R_SBREG(&sb->sbtmstatelow);
  657. /*
  658.  * PR6594 - 4610 iline100 overloads the clock enable bit with the
  659.  * oscillator/pll power up function which needs a much longer delay.
  660.  */
  661. if (sb_coreid(sbh) == SB_ILINE100) {
  662. msecs(50);
  663. } else {
  664. OSL_DELAY(1);
  665. }
  666. /* PR3158 - clear any serror */
  667. if (R_SBREG(&sb->sbtmstatehigh) & SBTMH_SERR) {
  668. W_SBREG(sbh, &sb->sbtmstatehigh, 0);
  669. }
  670. if ((dummy = R_SBREG(&sb->sbimstate)) & (SBIM_IBE | SBIM_TO)) {
  671. AND_SBREG(sbh, &sb->sbimstate, ~(SBIM_IBE | SBIM_TO));
  672. }
  673. /* clear reset and allow it to propagate throughout the core */
  674. W_SBREG(sbh, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | bits));
  675. dummy = R_SBREG(&sb->sbtmstatelow);
  676. OSL_DELAY(1);
  677. /* leave clock enabled */
  678. W_SBREG(sbh, &sb->sbtmstatelow, (SBTML_CLK | bits));
  679. dummy = R_SBREG(&sb->sbtmstatelow);
  680. OSL_DELAY(1);
  681. }
  682. /*
  683.  * Do the PR4755 workaround which require a call
  684.  * to sb_commit. sb_commit needs to access PCI
  685.  * configuration space which is not allowed in some
  686.  * versions of windows when going down. That is why
  687.  * this is not part of sb_core_reset above.
  688.  */
  689. void
  690. sb_core_tofixup(void *sbh)
  691. {
  692. sb_info_t *si;
  693. sbconfig_t *sb;
  694. si = SB_INFO(sbh);
  695. ASSERT(GOODREGS(si->curmap));
  696. sb = REGS2SB(si->curmap);
  697. /* PR 9962/4708: Set initiator timeouts. */
  698. if (si->bus == SB_BUS) {
  699. SET_SBREG(sbh, &sb->sbimconfiglow,
  700.   SBIMCL_RTO_MASK | SBIMCL_STO_MASK,
  701.   (0x5 << SBIMCL_RTO_SHIFT) | 0x3);
  702. } else {
  703. if (sb_coreid(sbh) == SB_PCI) {
  704. SET_SBREG(sbh, &sb->sbimconfiglow,
  705.   SBIMCL_RTO_MASK | SBIMCL_STO_MASK,
  706.   (0x3 << SBIMCL_RTO_SHIFT) | 0x2);
  707. } else {
  708. SET_SBREG(sbh, &sb->sbimconfiglow, (SBIMCL_RTO_MASK | SBIMCL_STO_MASK), 0);
  709. }
  710. }
  711. sb_commit(sbh);
  712. }
  713. void
  714. sb_core_disable(void *sbh, uint32 bits)
  715. {
  716. sb_info_t *si;
  717. volatile uint32 dummy;
  718. sbconfig_t *sb;
  719. si = SB_INFO(sbh);
  720. ASSERT(GOODREGS(si->curmap));
  721. sb = REGS2SB(si->curmap);
  722. /* must return if core is already in reset */
  723. if (R_SBREG(&sb->sbtmstatelow) & SBTML_RESET)
  724. return;
  725. /* set the reject bit */
  726. W_SBREG(sbh, &sb->sbtmstatelow, (SBTML_CLK | SBTML_REJ));
  727. /* spin until reject is set */
  728. while ((R_SBREG(&sb->sbtmstatelow) & SBTML_REJ) == 0)
  729. OSL_DELAY(1);
  730. /* spin until sbtmstatehigh.busy is clear */
  731. while (R_SBREG(&sb->sbtmstatehigh) & SBTMH_BUSY)
  732. OSL_DELAY(1);
  733. /* set reset and reject while enabling the clocks */
  734. W_SBREG(sbh, &sb->sbtmstatelow, (bits | SBTML_FGC | SBTML_CLK | SBTML_REJ | SBTML_RESET));
  735. dummy = R_SBREG(&sb->sbtmstatelow);
  736. OSL_DELAY(10);
  737. /* leave reset and reject asserted */
  738. W_SBREG(sbh, &sb->sbtmstatelow, (bits | SBTML_REJ | SBTML_RESET));
  739. OSL_DELAY(1);
  740. }
  741. void
  742. sb_chip_reset(void *sbh)
  743. {
  744. sb_info_t *si = SB_INFO(sbh);
  745. /* instant NMI */
  746. switch (si->gpioid) {
  747. case SB_CC:
  748. sb_corereg(sbh, si->gpioidx, OFFSETOF(chipcregs_t, watchdog), ~0, 1);
  749. break;
  750. case SB_EXTIF:
  751. sb_corereg(sbh, si->gpioidx, OFFSETOF(extifregs_t, watchdog), ~0, 1);
  752. break;
  753. }
  754. }
  755. /* initialize the pcmcia core */
  756. void
  757. sb_pcmcia_init(void *sbh)
  758. {
  759. sb_info_t *si;
  760. void *regs;
  761. uint8 cor;
  762. si = SB_INFO(sbh);
  763. /* Set the d11 core instead of pcmcia */
  764. regs = sb_setcore(sbh, SB_D11, 0);
  765. /* Reset origregs, curmap and origcoreidx */
  766. si->origregs = si->curmap = regs;
  767. si->origcoreidx = sb_coreidx((void*)si);
  768. /* Enable interrupts via function 2 FCR */
  769. OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_FCR0 + PCMCIA_COR, &cor, 1);
  770. OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_FCR2 + PCMCIA_COR, &cor, 1);
  771. cor |= COR_IRQEN | COR_FUNEN;
  772. OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_FCR2 + PCMCIA_COR, &cor, 1);
  773. /* XXX What else */
  774. }
  775. /*
  776.  * Configure the pci core for pci client (NIC) action
  777.  * and get appropriate dma offset value.
  778.  * coremask is the bitvec of cores by index to be enabled.
  779.  */
  780. void
  781. sb_pci_setup(void *sbh, uint32 *dmaoffset, uint coremask)
  782. {
  783. sb_info_t *si;
  784. sbconfig_t *sb;
  785. sbpciregs_t *pciregs;
  786. uint32 sbflag;
  787. uint32 w;
  788. uint idx;
  789. ASSERT(coremask);
  790. si = SB_INFO(sbh);
  791. if (dmaoffset)
  792. *dmaoffset = 0;
  793. /* if not pci bus, we're done */
  794. if (si->bus != PCI_BUS)
  795. return;
  796. ASSERT(si->pciidx);
  797. /* get current core index */
  798. idx = sb_coreidx(sbh);
  799. /* we interrupt on this backplane flag number */
  800. ASSERT(GOODREGS(si->curmap));
  801. sb = REGS2SB(si->curmap);
  802. sbflag = R_SBREG(&sb->sbtpsflag) & SBTPS_NUM0_MASK;
  803. /* switch over to pci core */
  804. pciregs = (sbpciregs_t*) sb_setcoreidx(sbh, si->pciidx);
  805. sb = REGS2SB(pciregs);
  806. /*
  807.  * Enable sb->pci interrupts.  Assume
  808.  * PCI rev 2.3 support was added in pci core rev 6 and things changed..
  809.  */
  810. if (si->pcirev < 6) {
  811. /* set sbintvec bit for our flag number */
  812. /* PR6075 - both d11 cores on the 4309 use the same flag */
  813. OR_SBREG(sbh, &sb->sbintvec, (1 << sbflag));
  814. } else {
  815. /* pci config write to set this core bit in PCIIntMask */
  816. w = OSL_PCI_READ_CONFIG(si->osh, PCI_INT_MASK, sizeof(uint32));
  817. w |= (coremask << SBIM_SHIFT);
  818. OSL_PCI_WRITE_CONFIG(si->osh, PCI_INT_MASK, sizeof(uint32), w);
  819. }
  820. /* enable prefetch and bursts for sonics-to-pci translation 2 */
  821. OR_REG(&pciregs->sbtopci2, (SBTOPCI_PREF|SBTOPCI_BURST));
  822. /* PR 9962/4708: Set initiator timeouts. */
  823. SET_SBREG(sbh, &sb->sbimconfiglow, SBIMCL_RTO_MASK | SBIMCL_STO_MASK,
  824.   (0x3 << SBIMCL_RTO_SHIFT) | 0x2);
  825. sb_commit(sbh);
  826. /* switch back to previous core */
  827. sb_setcoreidx(sbh, idx);
  828. /* use large sb pci dma window */
  829. if (dmaoffset)
  830. *dmaoffset = SB_PCI_DMA;
  831. }
  832. uint32
  833. sb_base(uint32 admatch)
  834. {
  835. uint32 base;
  836. uint type;
  837. type = admatch & SBAM_TYPE_MASK;
  838. ASSERT(type < 3);
  839. base = 0;
  840. if (type == 0) {
  841. base = admatch & SBAM_BASE0_MASK;
  842. } else if (type == 1) {
  843. ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */
  844. base = admatch & SBAM_BASE1_MASK;
  845. } else if (type == 2) {
  846. ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */
  847. base = admatch & SBAM_BASE2_MASK;
  848. }
  849. return (base);
  850. }
  851. uint32
  852. sb_size(uint32 admatch)
  853. {
  854. uint32 size;
  855. uint type;
  856. type = admatch & SBAM_TYPE_MASK;
  857. ASSERT(type < 3);
  858. size = 0;
  859. if (type == 0) {
  860. size = 1 << (((admatch & SBAM_ADINT0_MASK) >> SBAM_ADINT0_SHIFT) + 1);
  861. } else if (type == 1) {
  862. ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */
  863. size = 1 << (((admatch & SBAM_ADINT1_MASK) >> SBAM_ADINT1_SHIFT) + 1);
  864. } else if (type == 2) {
  865. ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */
  866. size = 1 << (((admatch & SBAM_ADINT2_MASK) >> SBAM_ADINT2_SHIFT) + 1);
  867. }
  868. return (size);
  869. }
  870. /* return the core-type instantiation # of the current core */
  871. uint
  872. sb_coreunit(void *sbh)
  873. {
  874. sb_info_t *si;
  875. uint idx;
  876. uint coreid;
  877. uint coreunit;
  878. uint i;
  879. si = SB_INFO(sbh);
  880. coreunit = 0;
  881. idx = sb_coreidx(sbh);
  882. ASSERT(GOODREGS(si->curmap));
  883. coreid = sb_coreid(sbh);
  884. /* count the cores of our type */
  885. for (i = 0; i < idx; i++)
  886. if (si->coreid[i] == coreid)
  887. coreunit++;
  888. return (coreunit);
  889. }
  890. static INLINE uint32
  891. factor6(uint32 x)
  892. {
  893. switch (x) {
  894. case CC_F6_2: return 2;
  895. case CC_F6_3: return 3;
  896. case CC_F6_4: return 4;
  897. case CC_F6_5: return 5;
  898. case CC_F6_6: return 6;
  899. case CC_F6_7: return 7;
  900. default: return 0;
  901. }
  902. }
  903. /* calculate the speed the SB would run at given a set of clockcontrol values */
  904. uint32
  905. sb_clock_rate(uint32 n, uint32 m)
  906. {
  907. uint32 n1, n2, fastclock, m1, m2, m3;
  908. n1 = factor6(n & CN_N1_MASK);
  909. n2 = ((n & CN_N2_MASK) >> CN_N2_SHIFT) + CC_F5_BIAS;
  910. fastclock = CC_CLOCK_BASE * n1 * n2;
  911. if (fastclock == 0)
  912. return 0;
  913. m1 = factor6(m & CC_M1_MASK);
  914. m2 = ((m & CC_M2_MASK) >> CC_M2_SHIFT) + CC_F5_BIAS;
  915. m3 = factor6((m & CC_M3_MASK) >> CC_M3_SHIFT);
  916. switch ((m & CC_MC_MASK) >> CC_MC_SHIFT) {
  917. case CC_MC_BYPASS: return (fastclock);
  918. case CC_MC_M1: return (fastclock / m1);
  919. case CC_MC_M1M2: return (fastclock / (m1 * m2));
  920. case CC_MC_M1M2M3: return (fastclock / (m1 * m2 * m3));
  921. case CC_MC_M1M3: return (fastclock / (m1 * m3));
  922. default: return (0);
  923. }
  924. }
  925. /* returns the current speed the SB is running at */
  926. uint32
  927. sb_clock(void *sbh)
  928. {
  929. extifregs_t *eir;
  930. chipcregs_t *cc;
  931. volatile uint32 *clockcontrol_n, *clockcontrol_sb;
  932. uint idx;
  933. uint32 rate;
  934. /* get index of the current core */
  935. idx = sb_coreidx(sbh);
  936. /* switch to extif or chipc core */
  937. if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) {
  938. clockcontrol_n = &eir->clockcontrol_n;
  939. clockcontrol_sb = &eir->clockcontrol_sb;
  940. } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) {
  941. clockcontrol_n = &cc->clockcontrol_n;
  942. clockcontrol_sb = &cc->clockcontrol_sb;
  943. } else
  944. return 0;
  945. /* calculate rate */
  946. rate = sb_clock_rate(R_REG(clockcontrol_n), R_REG(clockcontrol_sb));
  947. /* switch back to previous core */
  948. sb_setcoreidx(sbh, idx);
  949. return rate;
  950. }
  951. /* set the current speed of the SB to the desired rate (as closely as possible) */
  952. bool
  953. sb_setclock(void *sbh, uint32 sb, uint32 pci)
  954. {
  955. extifregs_t *eir;
  956. chipcregs_t *cc;
  957. volatile uint32 *clockcontrol_n, *clockcontrol_sb, *clockcontrol_pci;
  958. uint32 orig_n, orig_pci, orig_sb, pci_clock=0;
  959. uint idx, i;
  960. struct {
  961. uint32 clock;
  962. uint16 n;
  963. uint32 sb;
  964. uint32 pci33;
  965. uint32 pci25;
  966. } sb_clock_table[] = {
  967. {  96000000, 0x0303, 0x04020011, 0x11030011, 0x11050011 }, /*  96.000 32.000 24.000 */
  968. { 100000000, 0x0009, 0x04020011, 0x11030011, 0x11050011 }, /* 100.000 33.333 25.000 */
  969. { 104000000, 0x0802, 0x04020011, 0x11050009, 0x11090009 }, /* 104.000 31.200 24.960 */
  970. { 108000000, 0x0403, 0x04020011, 0x11050009, 0x02000802 }, /* 108.000 32.400 24.923 */
  971. { 112000000, 0x0205, 0x04020011, 0x11030021, 0x02000403 }, /* 112.000 32.000 24.889 */
  972. { 115200000, 0x0303, 0x04020009, 0x11030011, 0x11050011 }, /* 115.200 32.000 24.000 */
  973. { 120000000, 0x0011, 0x04020011, 0x11050011, 0x11090011 }, /* 120.000 30.000 24.000 */
  974. { 124800000, 0x0802, 0x04020009, 0x11050009, 0x11090009 }, /* 124.800 31.200 24.960 */
  975. { 128000000, 0x0305, 0x04020011, 0x11050011, 0x02000305 }, /* 128.000 32.000 24.000 */
  976. { 132000000, 0x0603, 0x04020011, 0x11050011, 0x02000305 }, /* 132.000 33.000 24.750 */
  977. { 136000000, 0x0c02, 0x04020011, 0x11090009, 0x02000603 }, /* 136.000 32.640 24.727 */
  978. { 140000000, 0x0021, 0x04020011, 0x11050021, 0x02000c02 }, /* 140.000 30.000 24.706 */
  979. { 144000000, 0x0405, 0x04020011, 0x01020202, 0x11090021 }, /* 144.000 30.857 24.686 */
  980. { 150857142, 0x0605, 0x04020021, 0x02000305, 0x02000605 }, /* 150.857 33.000 24.000 */
  981. { 152000000, 0x0e02, 0x04020011, 0x11050021, 0x02000e02 }, /* 152.000 32.571 24.000 */
  982. { 156000000, 0x0802, 0x04020005, 0x11050009, 0x11090009 }, /* 156.000 31.200 24.960 */
  983. { 160000000, 0x0309, 0x04020011, 0x11090011, 0x02000309 }, /* 160.000 32.000 24.000 */
  984. { 163200000, 0x0c02, 0x04020009, 0x11090009, 0x02000603 }, /* 163.200 32.640 24.727 */
  985. { 168000000, 0x0205, 0x04020005, 0x11030021, 0x02000403 }, /* 168.000 32.000 24.889 */
  986. { 176000000, 0x0602, 0x04020003, 0x11050005, 0x02000602 }, /* 176.000 33.000 24.000 */
  987. };
  988. /* get index of the current core */
  989. idx = sb_coreidx(sbh);
  990. /* switch to extif or chipc core */
  991. if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) {
  992. clockcontrol_n = &eir->clockcontrol_n;
  993. clockcontrol_sb = &eir->clockcontrol_sb;
  994. clockcontrol_pci = &eir->clockcontrol_pci;
  995. } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) {
  996. clockcontrol_n = &cc->clockcontrol_n;
  997. clockcontrol_sb = &cc->clockcontrol_sb;
  998. clockcontrol_pci = &cc->clockcontrol_pci;
  999. } else
  1000. return 0;
  1001. /* Store the current clock reg values */
  1002. orig_n = R_REG(clockcontrol_n);
  1003. orig_sb = R_REG(clockcontrol_sb);
  1004. orig_pci = R_REG(clockcontrol_pci);
  1005. /* keep current pci clock if not specified */
  1006. if (!pci) {
  1007. pci = sb_clock_rate(R_REG(clockcontrol_n), R_REG(clockcontrol_pci));
  1008. pci = (pci <= 25000000) ? 25000000 : 33000000;
  1009. }
  1010. for (i = 1; i < (sizeof(sb_clock_table)/sizeof(sb_clock_table[0])); i++) {
  1011. if ((sb >= sb_clock_table[i-1].clock) && (sb < sb_clock_table[i].clock)) {
  1012. ASSERT(sb_clock_table[i-1].clock ==
  1013. sb_clock_rate(sb_clock_table[i-1].n, sb_clock_table[i-1].sb));
  1014. W_REG(clockcontrol_n, sb_clock_table[i-1].n);
  1015. W_REG(clockcontrol_sb, sb_clock_table[i-1].sb);
  1016. if (pci == 25000000)
  1017. pci_clock = sb_clock_table[i-1].pci25;
  1018. else
  1019. pci_clock = sb_clock_table[i-1].pci33;
  1020. W_REG(clockcontrol_pci, pci_clock);
  1021. break;
  1022. }
  1023. }
  1024. /* switch back to previous core */
  1025. sb_setcoreidx(sbh, idx);
  1026. /* Were the clock rates in the table */
  1027. if (i < (sizeof(sb_clock_table)/sizeof(sb_clock_table[0]))) {
  1028. /* reset if any clocks changed */
  1029. if ((orig_n != sb_clock_table[i-1].n) ||
  1030. (orig_sb != sb_clock_table[i-1].sb) ||
  1031. (orig_pci != pci_clock))
  1032. sb_chip_reset(sbh);
  1033. else
  1034. return TRUE;
  1035. }
  1036. return FALSE;
  1037. }
  1038. #include <ethernet.h> /* for sprom content groking */
  1039. /*
  1040.  * Read in and validate sprom.
  1041.  * Return 0 on success, nonzero on error.
  1042.  */
  1043. static int
  1044. spromread(uint16 *sprom, uint byteoff, uint16 *buf, uint nbytes, bool check_crc)
  1045. {
  1046. int off, nw;
  1047. uint8 chk8;
  1048. int i;
  1049. off = byteoff / 2;
  1050. nw = ROUNDUP(nbytes, 2) / 2;
  1051. /* read the sprom */
  1052. for (i = 0; i < nw; i++)
  1053. buf[i] = R_REG(&sprom[off + i]);
  1054. if (check_crc) {
  1055. /* fixup the endianness so crc8 will pass */
  1056. htol16_buf(buf, nw * 2);
  1057. if ((chk8 = crc8((uchar*)buf, nbytes, CRC8_INIT_VALUE)) != CRC8_GOOD_VALUE)
  1058. return (1);
  1059. /* now correct the endianness of the byte array */
  1060. ltoh16_buf(buf, nw * 2);
  1061. }
  1062. return (0);
  1063. }
  1064. #define VARS_MAX 4096
  1065. /*
  1066.  * Initialize nonvolatile variable table from sprom.
  1067.  * Return 0 on success, nonzero on error.
  1068.  */
  1069. static int
  1070. srominitvars(sb_info_t *si, char **vars, int *count)
  1071. {
  1072. uint16 w, b[64];
  1073. uint8 spromversion;
  1074. struct ether_addr ea;
  1075. char eabuf[32];
  1076. int c, woff, i;
  1077. char *vp, *base;
  1078. if (spromread((void *)((uint)si->curmap + PCI_BAR0_SPROM_OFFSET), 0, b, sizeof (b), TRUE))
  1079. return (-1);
  1080. /* top word of sprom contains version and crc8 */
  1081. spromversion = b[63] & 0xff;
  1082. if (spromversion != 1) {
  1083. return (-2);
  1084. }
  1085. ASSERT(vars);
  1086. ASSERT(count);
  1087. base = vp = MALLOC(VARS_MAX);
  1088. ASSERT(vp);
  1089. /* parameter section of sprom starts at byte offset 72 */
  1090. woff = 72/2;
  1091. /* first 6 bytes are il0macaddr */
  1092. ea.octet[0] = (b[woff] >> 8) & 0xff;
  1093. ea.octet[1] = b[woff] & 0xff;
  1094. ea.octet[2] = (b[woff+1] >> 8) & 0xff;
  1095. ea.octet[3] = b[woff+1] & 0xff;
  1096. ea.octet[4] = (b[woff+2] >> 8) & 0xff;
  1097. ea.octet[5] = b[woff+2] & 0xff;
  1098. woff += ETHER_ADDR_LEN/2 ;
  1099. bcm_ether_ntoa((uchar*)&ea, eabuf);
  1100. vp += sprintf(vp, "il0macaddr=%s", eabuf);
  1101. vp++;
  1102. /* next 6 bytes are et0macaddr */
  1103. ea.octet[0] = (b[woff] >> 8) & 0xff;
  1104. ea.octet[1] = b[woff] & 0xff;
  1105. ea.octet[2] = (b[woff+1] >> 8) & 0xff;
  1106. ea.octet[3] = b[woff+1] & 0xff;
  1107. ea.octet[4] = (b[woff+2] >> 8) & 0xff;
  1108. ea.octet[5] = b[woff+2] & 0xff;
  1109. woff += ETHER_ADDR_LEN/2 ;
  1110. bcm_ether_ntoa((uchar*)&ea, eabuf);
  1111. vp += sprintf(vp, "et0macaddr=%s", eabuf);
  1112. vp++;
  1113. /* next 6 bytes are et1macaddr */
  1114. ea.octet[0] = (b[woff] >> 8) & 0xff;
  1115. ea.octet[1] = b[woff] & 0xff;
  1116. ea.octet[2] = (b[woff+1] >> 8) & 0xff;
  1117. ea.octet[3] = b[woff+1] & 0xff;
  1118. ea.octet[4] = (b[woff+2] >> 8) & 0xff;
  1119. ea.octet[5] = b[woff+2] & 0xff;
  1120. woff += ETHER_ADDR_LEN/2 ;
  1121. bcm_ether_ntoa((uchar*)&ea, eabuf);
  1122. vp += sprintf(vp, "et1macaddr=%s", eabuf);
  1123. vp++;
  1124. /*
  1125.  * Enet phy settings one or two singles or a dual
  1126.  * Bits 4-0 : MII address for enet0 (0x1f for not there)
  1127.  * Bits 9-5 : MII address for enet1 (0x1f for not there)
  1128.  * Bit 14   : Mdio for enet0
  1129.  * Bit 15   : Mdio for enet1
  1130.  */
  1131. w = b[woff];
  1132. vp += sprintf(vp, "et0phyaddr=%d", (w & 0x1f));
  1133. vp++;
  1134. vp += sprintf(vp, "et1phyaddr=%d", ((w >> 5) & 0x1f));
  1135. vp++;
  1136. vp += sprintf(vp, "et0mdcport=%d", ((w >> 14) & 0x1));
  1137. vp++;
  1138. vp += sprintf(vp, "et1mdcport=%d", ((w >> 15) & 0x1));
  1139. vp++;
  1140. /* Word 46 has board rev, antennas 0/1 & Country code */
  1141. w = b[46];
  1142. vp += sprintf(vp, "boardrev=%d", w & 0xff);
  1143. vp++;
  1144. vp += sprintf(vp, "cc=%d", (w >> 8) & 0xf);
  1145. vp++;
  1146. vp += sprintf(vp, "aa0=%d", (w >> 12) & 0x3);
  1147. vp++;
  1148. vp += sprintf(vp, "aa1=%d", (w >> 14) & 0x3);
  1149. vp++;
  1150. /* Word 52 is max power 0/1 */
  1151. w = b[52];
  1152. vp += sprintf(vp, "pa0maxpwr=%d", w & 0xff);
  1153. vp++;
  1154. vp += sprintf(vp, "pa1maxpwr=%d", (w >> 8) & 0xff);
  1155. vp++;
  1156. /* set the (wl) pa settings */
  1157. woff = 47; /* start of pa param's section */
  1158. for (i = 0; i < 5; i++) {
  1159. vp += sprintf(vp, "pa0b%d=%d", i, b[woff+i]);
  1160. vp++;
  1161. vp += sprintf(vp, "pa1b%d=%d", i, b[woff+i+6]);
  1162. vp++;
  1163. }
  1164. /* Word 58 is antenna gain 0/1 */
  1165. w = b[58];
  1166. vp += sprintf(vp, "ag0=%d", w & 0xff);
  1167. vp++;
  1168. vp += sprintf(vp, "ag1=%d", (w >> 8) & 0xff);
  1169. vp++;
  1170. /* set the oem string */
  1171. vp += sprintf(vp, "oem=%02x%02x%02x%02x%02x%02x%02x%02x",
  1172. ((b[woff] >> 8) & 0xff), (b[woff] & 0xff),
  1173. ((b[woff+1] >> 8) & 0xff), (b[woff+1] & 0xff),
  1174. ((b[woff+2] >> 8) & 0xff), (b[woff+2] & 0xff),
  1175. ((b[woff+3] >> 8) & 0xff), (b[woff+3] & 0xff));
  1176. vp++;
  1177. /* final nullbyte terminator */
  1178. *vp++ = '';
  1179. c = vp - base;
  1180. ASSERT(c <= VARS_MAX);
  1181. if (c == VARS_MAX) {
  1182. *vars = base;
  1183. } else {
  1184. vp = MALLOC(c);
  1185. ASSERT(vp);
  1186. bcopy(base, vp, c);
  1187. MFREE(base, VARS_MAX);
  1188. *vars = vp;
  1189. }
  1190. *count = c;
  1191. return (0);
  1192. }
  1193. /* set PCMCIA sprom command register */
  1194. static int
  1195. pcsr_cmd(sb_info_t *si, uint8 cmd)
  1196. {
  1197. uint8 status;
  1198. uint wait_cnt = 1000;
  1199. /* write sprom command register */
  1200. OSL_PCMCIA_WRITE_ATTR(si->osh, SROM_CS, &cmd, 1);
  1201. /* wait status */
  1202. while (wait_cnt--) {
  1203. OSL_PCMCIA_READ_ATTR(si->osh, SROM_CS, &status, 1);
  1204. if (status & SROM_DONE)
  1205. return 0;
  1206. }
  1207. return 1;
  1208. }
  1209. /* read a word from the PCMCIA srom */
  1210. static int
  1211. pcsr_read(sb_info_t *si, uint16 addr, uint16 *data)
  1212. {
  1213. uint8 addr_l, addr_h, data_l, data_h;
  1214. addr_l = (uint8)((addr * 2) & 0xff);
  1215. addr_h = (uint8)(((addr * 2) >> 8) & 0xff);
  1216. /* set address */
  1217. OSL_PCMCIA_WRITE_ATTR(si->osh, SROM_ADDRH, &addr_h, 1);
  1218. OSL_PCMCIA_WRITE_ATTR(si->osh, SROM_ADDRL, &addr_l, 1);
  1219. /* do read */
  1220. if (pcsr_cmd(si, SROM_READ))
  1221. return 1;
  1222. /* read data */
  1223. OSL_PCMCIA_READ_ATTR(si->osh, SROM_DATAH, &data_h, 1);
  1224. OSL_PCMCIA_READ_ATTR(si->osh, SROM_DATAL, &data_l, 1);
  1225. *data = (data_h << 8) | data_l;
  1226. return 0;
  1227. }
  1228. /* write a word to the PCMCIA srom */
  1229. static int
  1230. pcsr_write(sb_info_t *si, uint16 addr, uint16 data)
  1231. {
  1232. uint8 addr_l, addr_h, data_l, data_h;
  1233. addr_l = (uint8)((addr * 2) & 0xff);
  1234. addr_h = (uint8)(((addr * 2) >> 8) & 0xff);
  1235. data_l = (uint8)(data & 0xff);
  1236. data_h = (uint8)((data >> 8) & 0xff);
  1237. /* set address */
  1238. OSL_PCMCIA_WRITE_ATTR(si->osh, SROM_ADDRH, &addr_h, 1);
  1239. OSL_PCMCIA_WRITE_ATTR(si->osh, SROM_ADDRL, &addr_l, 1);
  1240. /* write data */
  1241. OSL_PCMCIA_WRITE_ATTR(si->osh, SROM_DATAH, &data_h, 1);
  1242. OSL_PCMCIA_WRITE_ATTR(si->osh, SROM_DATAL, &data_l, 1);
  1243. /* do write */
  1244. return pcsr_cmd(si, SROM_WRITE);
  1245. }
  1246. /* support only 16-bit word read from srom */
  1247. int
  1248. sromread(void *sbh, uint byteoff, uint nbytes, uint16 *buf)
  1249. {
  1250. void *srom;
  1251. uint i, off, nw;
  1252. sb_info_t *si = SB_INFO(sbh);
  1253. /* check input - 16-bit access only */
  1254. if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > (SPROM_SIZE * 2))
  1255. return 1;
  1256. if (si->bus == PCI_BUS) {
  1257. srom = (void *)((uint)si->curmap + PCI_BAR0_SPROM_OFFSET);
  1258. if (spromread(srom, byteoff, buf, nbytes, FALSE))
  1259. return 1;
  1260. } else if (si->bus == PCMCIA_BUS) {
  1261. off = byteoff / 2;
  1262. nw = nbytes / 2;
  1263. for (i = 0; i < nw; i++) {
  1264. if (pcsr_read(si, off + i, buf + i))
  1265. return 1;
  1266. }
  1267. } else {
  1268. return 1;
  1269. }
  1270. return 0;
  1271. }
  1272. /* support only 16-bit word write into srom */
  1273. int
  1274. sromwrite(void *sbh, uint byteoff, uint nbytes, uint16 *buf)
  1275. {
  1276. uint16 *srom;
  1277. sb_info_t *si = SB_INFO(sbh);
  1278. uint i, off, nw, crc_range;
  1279. uint16 image[SPROM_SIZE], *p;
  1280. uint8 crc;
  1281. volatile uint32 val32;
  1282. /* check input - 16-bit access only */
  1283. if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > (SPROM_SIZE * 2))
  1284. return 1;
  1285. crc_range = ((si->bus == PCMCIA_BUS) ? SPROM_SIZE : SPROM_CRC_RANGE) * 2;
  1286. /* if changes made inside crc cover range */
  1287. if (byteoff < crc_range) {
  1288. nw = (((byteoff + nbytes) > crc_range) ? byteoff + nbytes : crc_range) / 2;
  1289. /* read data including entire first 64 words from srom */
  1290. if (sromread(sbh, 0, nw * 2, image))
  1291. return 1;
  1292. /* make changes */
  1293. bcopy((void*)buf, (void*)&image[byteoff / 2], nbytes);
  1294. /* calculate crc */
  1295. htol16_buf(image, crc_range);
  1296. crc = ~crc8((uint8 *)image, crc_range - 1, CRC8_INIT_VALUE);
  1297. ltoh16_buf(image, crc_range);
  1298. image[(crc_range / 2) - 1] = (crc << 8) | (image[(crc_range / 2) - 1] & 0xff);
  1299. p = image;
  1300. off = 0;
  1301. } else {
  1302. p = buf;
  1303. off = byteoff / 2;
  1304. nw = nbytes / 2;
  1305. }
  1306. if (si->bus == PCI_BUS) {
  1307. srom = (uint16*)((uint)si->curmap + PCI_BAR0_SPROM_OFFSET);
  1308. /* enable writes to the SPROM */
  1309. val32 = OSL_PCI_READ_CONFIG(si->osh, PCI_SPROM_CONTROL, sizeof(uint32));
  1310. val32 |= SPROM_WRITEEN;
  1311. OSL_PCI_WRITE_CONFIG(si->osh, PCI_SPROM_CONTROL, sizeof(uint32), val32);
  1312. msecs(500);
  1313. /* write srom */
  1314. for (i = 0; i < nw; i++) {
  1315. W_REG(&srom[off + i], p[i]);
  1316. msecs(20);
  1317. }
  1318. /* disable writes to the SPROM */
  1319. OSL_PCI_WRITE_CONFIG(si->osh, PCI_SPROM_CONTROL, sizeof(uint32), val32 & ~SPROM_WRITEEN);
  1320. } else if (si->bus == PCMCIA_BUS) {
  1321. /* enable writes to the SPROM */
  1322. if (pcsr_cmd(si, SROM_WEN))
  1323. return 1;
  1324. msecs(500);
  1325. /* write srom */
  1326. for (i = 0; i < nw; i++) {
  1327. pcsr_write(si, off + i, p[i]);
  1328. msecs(20);
  1329. }
  1330. /* disable writes to the SPROM */
  1331. if (pcsr_cmd(si, SROM_WDS))
  1332. return 1;
  1333. } else {
  1334. return 1;
  1335. }
  1336. msecs(500);
  1337. return 0;
  1338. }
  1339. /*
  1340.  * "The sprom" in PCMCIA cards is simply the standard PCMCIA
  1341.  * CIS (Card Information Structure); so we have to parse the
  1342.  * CIS and extract from it into name=value pairs the information
  1343.  * we need: the mac address is a standard tuple; plus we add
  1344.  * vendor specific tuples for chip/revision ids, board revision,
  1345.  * country code lock, PA parameters and OEM space.
  1346.  * XXX: Should check a crc (there is a crc tuple that we could add).
  1347.  *
  1348.  * Return 0 on success, nonzero on error.
  1349.  */
  1350. int
  1351. parsecis(uint8 *cis, char **vars, int *count)
  1352. {
  1353. char eabuf[32];
  1354. char *vp, *base;
  1355. uint8 tup, tlen;
  1356. int i, j;
  1357. uint varsize;
  1358. bool ag_init = FALSE;
  1359. ASSERT(vars);
  1360. ASSERT(count);
  1361. base = vp = MALLOC(VARS_MAX);
  1362. ASSERT(vp);
  1363. i = 0;
  1364. do {
  1365. tup = cis[i++];
  1366. tlen = cis[i++];
  1367. switch (tup) {
  1368. case CISTPL_MANFID:
  1369. vp += sprintf(vp, "manfid=%d", (cis[i + 1] << 8) + cis[i]);
  1370. vp++;
  1371. vp += sprintf(vp, "prodid=%d", (cis[i + 3] << 8) + cis[i + 2]);
  1372. vp++;
  1373. break;
  1374. case CISTPL_FUNCE:
  1375. if (cis[i] == LAN_NID) {
  1376. ASSERT(cis[i + 1] == ETHER_ADDR_LEN);
  1377. bcm_ether_ntoa((uchar*)&cis[i + 2], eabuf);
  1378. vp += sprintf(vp, "il0macaddr=%s", eabuf);
  1379. vp++;
  1380. }
  1381. break;
  1382. case CISTPL_BRCM_HNBU:
  1383. switch (cis[i]) {
  1384. case HNBU_CHIPID:
  1385. vp += sprintf(vp, "vendid=%d", (cis[i + 2] << 8) + cis[i + 1]);
  1386. vp++;
  1387. vp += sprintf(vp, "devid=%d", (cis[i + 4] << 8) + cis[i + 3]);
  1388. vp++;
  1389. vp += sprintf(vp, "chiprev=%d", (cis[i + 6] << 8) + cis[i + 5]);
  1390. vp++;
  1391. break;
  1392. case HNBU_BOARDREV:
  1393. vp += sprintf(vp, "boardrev=%d", cis[i + 1]);
  1394. vp++;
  1395. break;
  1396. case HNBU_AA:
  1397. vp += sprintf(vp, "aa0=%d", cis[i + 1]);
  1398. vp++;
  1399. break;
  1400. case HNBU_AG:
  1401. vp += sprintf(vp, "ag0=%d", cis[i + 1]);
  1402. vp++;
  1403. ag_init = TRUE;
  1404. break;
  1405. case HNBU_CC:
  1406. vp += sprintf(vp, "cc=%d", cis[i + 1]);
  1407. vp++;
  1408. break;
  1409. case HNBU_PAPARMS:
  1410. for (j = 0; j < 5; j++) {
  1411. vp += sprintf(vp, "pa0b%d=%d", j,
  1412. (cis[i + (j * 2) + 2] << 8) + cis[i + (j * 2) + 1]);
  1413. vp++;
  1414. }
  1415. vp += sprintf(vp, "pa0maxpwr=%d", cis[i + 11]);
  1416. vp++;
  1417. break;
  1418. case HNBU_OEM:
  1419. vp += sprintf(vp, "oem=%02x%02x%02x%02x%02x%02x%02x%02x",
  1420. cis[i + 1], cis[i + 2], cis[i + 3], cis[i + 4],
  1421. cis[i + 5], cis[i + 6], cis[i + 7], cis[i + 8]);
  1422. vp++;
  1423. break;
  1424. }
  1425. break;
  1426. }
  1427. i += tlen;
  1428. } while (tup != 0xff);
  1429. /* if there is no antenna gain field, set default */
  1430. if (ag_init == FALSE) {
  1431. vp += sprintf(vp, "ag0=%d", 0xff);
  1432. vp++;
  1433. }
  1434. /* final nullbyte terminator */
  1435. *vp++ = '';
  1436. varsize = (uint)vp - (uint)base;
  1437. ASSERT(varsize < VARS_MAX);
  1438. if (varsize == VARS_MAX) {
  1439. *vars = base;
  1440. } else {
  1441. vp = MALLOC(varsize);
  1442. ASSERT(vp);
  1443. bcopy(base, vp, varsize);
  1444. MFREE(base, VARS_MAX);
  1445. *vars = vp;
  1446. }
  1447. *count = varsize;
  1448. return (0);
  1449. }
  1450. /*
  1451.  * Read the cis and call parsecis to initialize the vars.
  1452.  * Return 0 on success, nonzero on error.
  1453.  */
  1454. static int
  1455. cisinitvars(sb_info_t *si, char **vars, int *count)
  1456. {
  1457. uint8 *cis = NULL;
  1458. int rc;
  1459. if ((cis = MALLOC(CIS_SIZE)) == NULL)
  1460. return (-1);
  1461. OSL_PCMCIA_READ_ATTR(si->osh, 0, cis, CIS_SIZE);
  1462. rc = parsecis(cis, vars, count);
  1463. MFREE(cis, CIS_SIZE);
  1464. return (rc);
  1465. }
  1466. /*
  1467.  * Initialize the vars from the right source for this platform.
  1468.  * Return 0 on success, nonzero on error.
  1469.  */
  1470. static int
  1471. sb_initvars(sb_info_t *si, char **vars, int *count)
  1472. {
  1473. if (vars == NULL)
  1474. return (0);
  1475. switch (si->bus) {
  1476. case SB_BUS:
  1477. /* These two could be asserts ... */
  1478. *vars = NULL;
  1479. *count = 0;
  1480. return(0);
  1481. case PCI_BUS:
  1482. return(srominitvars(si, vars, count));
  1483. case PCMCIA_BUS:
  1484. return(cisinitvars(si, vars, count));
  1485. default:
  1486. ASSERT(0);
  1487. }
  1488. return (-1);
  1489. }
  1490. #ifndef BROADCOM_BSP
  1491. /*
  1492.  * Search the vars for a specific one and return its value.
  1493.  * Returns NULL if not found.
  1494.  */
  1495. char*
  1496. getvar(char *vars, char *name)
  1497. {
  1498. char *s;
  1499. int len;
  1500. len = strlen(name);
  1501. if (vars == NULL)
  1502. return(nvram_get(name));
  1503. for (s = vars; s && *s; ) {
  1504. if ((bcmp(s, name, len) == 0) && (s[len] == '='))
  1505. return (&s[len+1]);
  1506. while (*s++)
  1507. ;
  1508. }
  1509. return (NULL);
  1510. }
  1511. /*
  1512.  * Search the vars for a specific one and return its value as
  1513.  * an integer. Returns 0 if not found.
  1514.  */
  1515. int
  1516. getintvar(char *vars, char *name)
  1517. {
  1518. char *val;
  1519. if ((val = getvar(vars, name)) == NULL)
  1520. return (0);
  1521. return (bcm_strtoul(val, NULL, 0));
  1522. }
  1523. #endif
  1524. /* change logical "focus" to the gpio core for optimized access */
  1525. void*
  1526. sb_gpiosetcore(void *sbh)
  1527. {
  1528. sb_info_t *si;
  1529. si = SB_INFO(sbh);
  1530. return (sb_setcoreidx(sbh, si->gpioidx));
  1531. }
  1532. /* mask&set gpiocontrol bits */
  1533. uint32
  1534. sb_gpiocontrol(void *sbh, uint32 mask, uint32 val)
  1535. {
  1536. sb_info_t *si;
  1537. uint regoff;
  1538. si = SB_INFO(sbh);
  1539. regoff = 0;
  1540. switch (si->gpioid) {
  1541. case SB_CC:
  1542. regoff = OFFSETOF(chipcregs_t, gpiocontrol);
  1543. break;
  1544. case SB_PCI:
  1545. regoff = OFFSETOF(sbpciregs_t, gpiocontrol);
  1546. break;
  1547. case SB_EXTIF:
  1548. return (0);
  1549. }
  1550. return (sb_corereg(sbh, si->gpioidx, regoff, mask, val));
  1551. }
  1552. /* mask&set gpio output enable bits */
  1553. uint32
  1554. sb_gpioouten(void *sbh, uint32 mask, uint32 val)
  1555. {
  1556. sb_info_t *si;
  1557. uint regoff;
  1558. si = SB_INFO(sbh);
  1559. regoff = 0;
  1560. switch (si->gpioid) {
  1561. case SB_CC:
  1562. regoff = OFFSETOF(chipcregs_t, gpioouten);
  1563. break;
  1564. case SB_PCI:
  1565. regoff = OFFSETOF(sbpciregs_t, gpioouten);
  1566. break;
  1567. case SB_EXTIF:
  1568. regoff = OFFSETOF(extifregs_t, gpio[0].outen);
  1569. break;
  1570. }
  1571. return (sb_corereg(sbh, si->gpioidx, regoff, mask, val));
  1572. }
  1573. /* mask&set gpio output bits */
  1574. uint32
  1575. sb_gpioout(void *sbh, uint32 mask, uint32 val)
  1576. {
  1577. sb_info_t *si;
  1578. uint regoff;
  1579. si = SB_INFO(sbh);
  1580. regoff = 0;
  1581. switch (si->gpioid) {
  1582. case SB_CC:
  1583. regoff = OFFSETOF(chipcregs_t, gpioout);
  1584. break;
  1585. case SB_PCI:
  1586. regoff = OFFSETOF(sbpciregs_t, gpioout);
  1587. break;
  1588. case SB_EXTIF:
  1589. regoff = OFFSETOF(extifregs_t, gpio[0].out);
  1590. break;
  1591. }
  1592. return (sb_corereg(sbh, si->gpioidx, regoff, mask, val));
  1593. }
  1594. /* return the current gpioin register value */
  1595. uint32
  1596. sb_gpioin(void *sbh)
  1597. {
  1598. sb_info_t *si;
  1599. uint regoff;
  1600. si = SB_INFO(sbh);
  1601. regoff = 0;
  1602. switch (si->gpioid) {
  1603. case SB_CC:
  1604. regoff = OFFSETOF(chipcregs_t, gpioin);
  1605. break;
  1606. case SB_PCI:
  1607. regoff = OFFSETOF(sbpciregs_t, gpioin);
  1608. break;
  1609. case SB_EXTIF:
  1610. regoff = OFFSETOF(extifregs_t, gpioin);
  1611. break;
  1612. }
  1613. return (sb_corereg(sbh, si->gpioidx, regoff, 0, 0));
  1614. }
  1615. void
  1616. sb_dump(void *sbh, char *buf)
  1617. {
  1618. sb_info_t *si;
  1619. uint i;
  1620. si = SB_INFO(sbh);
  1621. buf += sprintf(buf, "si 0x%x chip 0x%x chiprev 0x%x board 0x%x boardvendor 0x%x bus %dn",
  1622. (uint)si, si->chip, si->chiprev, si->board, si->boardvendor, si->bus);
  1623. buf += sprintf(buf, "osh 0x%x curmap 0x%x origregs 0x%x origcoreidx %dn",
  1624. (uint)si->osh, (uint)si->curmap, (uint)si->origregs, si->origcoreidx);
  1625. buf += sprintf(buf, "pciidx %d gpioidx %d gpioid 0x%xn",
  1626. si->pciidx, si->gpioidx, si->gpioid);
  1627. buf += sprintf(buf, "cores:  ");
  1628. for (i = 0; i < si->numcores; i++)
  1629. buf += sprintf(buf, "0x%x ", si->coreid[i]);
  1630. buf += sprintf(buf, "n");
  1631. }
  1632. /* Doing really long delays with DELAY breaks Linux:
  1633.  * it claims they would not be accurate on fast machines.
  1634.  */
  1635. static void
  1636. msecs(uint ms)
  1637. {
  1638. uint i;
  1639. for (i = 0; i < ms; i++) {
  1640. OSL_DELAY(1000);
  1641. }
  1642. }
  1643. #ifdef BROADCOM_BSP
  1644. void
  1645. gpioIntInit(void)
  1646. {
  1647.     extifregs_t *eir;
  1648.     void *sbh;
  1649.     sbh = sb_kattach (BCM4710_DEVICE_ID, 0);
  1650.     ASSERT (sbh);
  1651.     eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0);
  1652.     W_REG(&eir->gpio[0].out, 0);
  1653.     W_REG(&eir->gpio[0].outen, 0x44);
  1654.     OSL_DELAY(2000);
  1655.     W_REG(&eir->gpio[0].out, 0x44);
  1656.     W_REG(&eir->gpio[0].outen, 0);
  1657.     /* Setup gpio bit 1 to be the external uart interrupt */
  1658.     W_REG(&eir->gpiointpolarity, 0);    /* UART int is active high */
  1659.     W_REG(&eir->gpiointmask, 2);        /* bit 1 */
  1660.     sb_detach (sbh);
  1661. }
  1662. #endif
  1663. /* ROBO stuff */
  1664. #ifdef ROBO
  1665. #include "if_robo.h"
  1666. #include "if_robo.c"
  1667. #endif