1/* 2 * Code to operate on PCI/E core, in NIC mode 3 * Implements pci_api.h 4 * Copyright (C) 2010, Broadcom Corporation. All Rights Reserved. 5 * 6 * Permission to use, copy, modify, and/or distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * 18 * $Id: nicpci.c,v 1.33.10.24 2011-02-03 01:11:15 Exp $ 19 */ 20 21#include <typedefs.h> 22#include <bcmdefs.h> 23#include <osl.h> 24#include <bcmutils.h> 25#include <siutils.h> 26#include <hndsoc.h> 27#include <bcmdevs.h> 28#include <sbchipc.h> 29#include <pci_core.h> 30#include <pcie_core.h> 31#include <nicpci.h> 32#include <pcicfg.h> 33 34typedef struct { 35 union { 36 sbpcieregs_t *pcieregs; 37 sbpciregs_t *pciregs; 38 } regs; /* Memory mapped register to the core */ 39 40 si_t *sih; /* System interconnect handle */ 41 osl_t *osh; /* OSL handle */ 42 uint8 pciecap_lcreg_offset; /* PCIE capability LCreg offset in the config space */ 43 uint8 pciecap_devctrl_offset; /* PCIE DevControl reg offset in the config space */ 44 bool pcie_pr42767; 45 uint8 pcie_polarity; 46 uint8 pcie_war_aspm_ovr; /* Override ASPM/Clkreq settings */ 47 uint8 pmecap_offset; /* PM Capability offset in the config space */ 48 bool pmecap; /* Capable of generating PME */ 49 bool pcie_power_save; 50 uint16 pmebits; 51 uint16 pcie_reqsize; 52} pcicore_info_t; 53 54/* debug/trace */ 55#define PCI_ERROR(args) 56 57/* routines to access mdio slave device registers */ 58static bool pcie_mdiosetblock(pcicore_info_t *pi, uint blk); 59static int pcie_mdioop(pcicore_info_t *pi, uint physmedia, uint regaddr, bool write, uint *val); 60static int pcie_mdiowrite(pcicore_info_t *pi, uint physmedia, uint readdr, uint val); 61static int pcie_mdioread(pcicore_info_t *pi, uint physmedia, uint readdr, uint *ret_val); 62 63static void pcie_extendL1timer(pcicore_info_t *pi, bool extend); 64static void pcie_clkreq_upd(pcicore_info_t *pi, uint state); 65 66static void pcie_war_aspm_clkreq(pcicore_info_t *pi); 67static void pcie_war_serdes(pcicore_info_t *pi); 68static void pcie_war_noplldown(pcicore_info_t *pi); 69static void pcie_war_polarity(pcicore_info_t *pi); 70static void pcie_war_pci_setup(pcicore_info_t *pi); 71static void pcie_power_save_upd(pcicore_info_t *pi, bool up); 72 73static bool pcicore_pmecap(pcicore_info_t *pi); 74static void pcicore_fixlatencytimer(pcicore_info_t* pch, uint8 timer_val); 75 76#define PCIE(sih) ((BUSTYPE((sih)->bustype) == PCI_BUS) && ((sih)->buscoretype == PCIE_CORE_ID)) 77#define PCIE_ASPM(sih) ((PCIE(sih)) && (((sih)->buscorerev >= 3) && ((sih)->buscorerev <= 5))) 78 79#define DWORD_ALIGN(x) (x & ~(0x03)) 80#define BYTE_POS(x) (x & 0x3) 81#define WORD_POS(x) (x & 0x1) 82 83#define BYTE_SHIFT(x) (8 * BYTE_POS(x)) 84#define WORD_SHIFT(x) (16 * WORD_POS(x)) 85 86#define BYTE_VAL(a, x) ((a >> BYTE_SHIFT(x)) & 0xFF) 87#define WORD_VAL(a, x) ((a >> WORD_SHIFT(x)) & 0xFFFF) 88 89#define read_pci_cfg_byte(a) \ 90 (BYTE_VAL(OSL_PCI_READ_CONFIG(osh, DWORD_ALIGN(a), 4), a) & 0xff) 91 92#define read_pci_cfg_word(a) \ 93 (WORD_VAL(OSL_PCI_READ_CONFIG(osh, DWORD_ALIGN(a), 4), a) & 0xffff) 94 95#define write_pci_cfg_byte(a, val) do { \ 96 uint32 tmpval; \ 97 tmpval = (OSL_PCI_READ_CONFIG(osh, DWORD_ALIGN(a), 4) & ~0xFF << BYTE_POS(a)) | \ 98 val << BYTE_POS(a); \ 99 OSL_PCI_WRITE_CONFIG(osh, DWORD_ALIGN(a), 4, tmpval); \ 100 } while (0) 101 102#define write_pci_cfg_word(a, val) do { \ 103 uint32 tmpval; \ 104 tmpval = (OSL_PCI_READ_CONFIG(osh, DWORD_ALIGN(a), 4) & ~0xFFFF << WORD_POS(a)) | \ 105 val << WORD_POS(a); \ 106 OSL_PCI_WRITE_CONFIG(osh, DWORD_ALIGN(a), 4, tmpval); \ 107 } while (0) 108 109/* delay needed between the mdio control/ mdiodata register data access */ 110#define PR28829_DELAY() OSL_DELAY(10) 111 112/* Initialize the PCI core. It's caller's responsibility to make sure that this is done 113 * only once 114 */ 115void * 116pcicore_init(si_t *sih, osl_t *osh, void *regs) 117{ 118 pcicore_info_t *pi; 119 120 ASSERT(sih->bustype == PCI_BUS); 121 122 /* alloc pcicore_info_t */ 123 if ((pi = MALLOC(osh, sizeof(pcicore_info_t))) == NULL) { 124 PCI_ERROR(("pci_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh))); 125 return (NULL); 126 } 127 128 bzero(pi, sizeof(pcicore_info_t)); 129 130 pi->sih = sih; 131 pi->osh = osh; 132 133 if (sih->buscoretype == PCIE_CORE_ID) { 134 uint8 cap_ptr; 135 pi->regs.pcieregs = (sbpcieregs_t*)regs; 136 cap_ptr = pcicore_find_pci_capability(pi->osh, PCI_CAP_PCIECAP_ID, NULL, NULL); 137 ASSERT(cap_ptr); 138 pi->pciecap_lcreg_offset = cap_ptr + PCIE_CAP_LINKCTRL_OFFSET; 139 pi->pciecap_devctrl_offset = cap_ptr + PCIE_CAP_DEVCTRL_OFFSET; 140 pi->pcie_power_save = TRUE; /* Enable pcie_power_save by default */ 141 } else 142 pi->regs.pciregs = (sbpciregs_t*)regs; 143 144 return pi; 145} 146 147void 148pcicore_deinit(void *pch) 149{ 150 pcicore_info_t *pi = (pcicore_info_t *)pch; 151 152 153 if (pi == NULL) 154 return; 155 MFREE(pi->osh, pi, sizeof(pcicore_info_t)); 156} 157 158/* return cap_offset if requested capability exists in the PCI config space */ 159/* Note that it's caller's responsibility to make sure it's a pci bus */ 160uint8 161pcicore_find_pci_capability(osl_t *osh, uint8 req_cap_id, uchar *buf, uint32 *buflen) 162{ 163 uint8 cap_id; 164 uint8 cap_ptr = 0; 165 uint32 bufsize; 166 uint8 byte_val; 167 168 /* check for Header type 0 */ 169 byte_val = read_pci_cfg_byte(PCI_CFG_HDR); 170 if ((byte_val & 0x7f) != PCI_HEADER_NORMAL) 171 goto end; 172 173 /* check if the capability pointer field exists */ 174 byte_val = read_pci_cfg_byte(PCI_CFG_STAT); 175 if (!(byte_val & PCI_CAPPTR_PRESENT)) 176 goto end; 177 178 cap_ptr = read_pci_cfg_byte(PCI_CFG_CAPPTR); 179 /* check if the capability pointer is 0x00 */ 180 if (cap_ptr == 0x00) 181 goto end; 182 183 /* loop thr'u the capability list and see if the pcie capabilty exists */ 184 185 cap_id = read_pci_cfg_byte(cap_ptr); 186 187 while (cap_id != req_cap_id) { 188 cap_ptr = read_pci_cfg_byte((cap_ptr+1)); 189 if (cap_ptr == 0x00) break; 190 cap_id = read_pci_cfg_byte(cap_ptr); 191 } 192 if (cap_id != req_cap_id) { 193 goto end; 194 } 195 /* found the caller requested capability */ 196 if ((buf != NULL) && (buflen != NULL)) { 197 uint8 cap_data; 198 199 bufsize = *buflen; 200 if (!bufsize) goto end; 201 *buflen = 0; 202 /* copy the cpability data excluding cap ID and next ptr */ 203 cap_data = cap_ptr + 2; 204 if ((bufsize + cap_data) > SZPCR) 205 bufsize = SZPCR - cap_data; 206 *buflen = bufsize; 207 while (bufsize--) { 208 *buf = read_pci_cfg_byte(cap_data); 209 cap_data++; 210 buf++; 211 } 212 } 213end: 214 return cap_ptr; 215} 216 217/* ***** Register Access API */ 218uint 219pcie_readreg(osl_t *osh, sbpcieregs_t *pcieregs, uint addrtype, uint offset) 220{ 221 uint retval = 0xFFFFFFFF; 222 223 ASSERT(pcieregs != NULL); 224 225 switch (addrtype) { 226 case PCIE_CONFIGREGS: 227 W_REG(osh, (&pcieregs->configaddr), offset); 228 (void)R_REG(osh, (&pcieregs->configaddr)); 229 retval = R_REG(osh, &(pcieregs->configdata)); 230 break; 231 case PCIE_PCIEREGS: 232 W_REG(osh, &(pcieregs->pcieindaddr), offset); 233 (void)R_REG(osh, (&pcieregs->pcieindaddr)); 234 retval = R_REG(osh, &(pcieregs->pcieinddata)); 235 break; 236 default: 237 ASSERT(0); 238 break; 239 } 240 241 return retval; 242} 243 244uint 245pcie_writereg(osl_t *osh, sbpcieregs_t *pcieregs, uint addrtype, uint offset, uint val) 246{ 247 ASSERT(pcieregs != NULL); 248 249 switch (addrtype) { 250 case PCIE_CONFIGREGS: 251 W_REG(osh, (&pcieregs->configaddr), offset); 252 W_REG(osh, (&pcieregs->configdata), val); 253 break; 254 case PCIE_PCIEREGS: 255 W_REG(osh, (&pcieregs->pcieindaddr), offset); 256 W_REG(osh, (&pcieregs->pcieinddata), val); 257 break; 258 default: 259 ASSERT(0); 260 break; 261 } 262 return 0; 263} 264 265static bool 266pcie_mdiosetblock(pcicore_info_t *pi, uint blk) 267{ 268 sbpcieregs_t *pcieregs = pi->regs.pcieregs; 269 uint mdiodata, i = 0; 270 uint pcie_serdes_spinwait = 200; 271 272 mdiodata = MDIODATA_START | MDIODATA_WRITE | (MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) | 273 (MDIODATA_BLK_ADDR << MDIODATA_REGADDR_SHF) | MDIODATA_TA | (blk << 4); 274 W_REG(pi->osh, &pcieregs->mdiodata, mdiodata); 275 276 PR28829_DELAY(); 277 /* retry till the transaction is complete */ 278 while (i < pcie_serdes_spinwait) { 279 if (R_REG(pi->osh, &(pcieregs->mdiocontrol)) & MDIOCTL_ACCESS_DONE) { 280 break; 281 } 282 OSL_DELAY(1000); 283 i++; 284 } 285 286 if (i >= pcie_serdes_spinwait) { 287 PCI_ERROR(("pcie_mdiosetblock: timed out\n")); 288 return FALSE; 289 } 290 291 return TRUE; 292} 293 294static int 295pcie_mdioop(pcicore_info_t *pi, uint physmedia, uint regaddr, bool write, uint *val) 296{ 297 sbpcieregs_t *pcieregs = pi->regs.pcieregs; 298 uint mdiodata; 299 uint i = 0; 300 uint pcie_serdes_spinwait = 10; 301 302 /* enable mdio access to SERDES */ 303 W_REG(pi->osh, (&pcieregs->mdiocontrol), MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL); 304 305 if (pi->sih->buscorerev >= 10) { 306 /* new serdes is slower in rw, using two layers of reg address mapping */ 307 if (!pcie_mdiosetblock(pi, physmedia)) 308 return 1; 309 mdiodata = (MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) | 310 (regaddr << MDIODATA_REGADDR_SHF); 311 pcie_serdes_spinwait *= 20; 312 } else { 313 mdiodata = (physmedia << MDIODATA_DEVADDR_SHF_OLD) | 314 (regaddr << MDIODATA_REGADDR_SHF_OLD); 315 } 316 317 if (!write) 318 mdiodata |= (MDIODATA_START | MDIODATA_READ | MDIODATA_TA); 319 else 320 mdiodata |= (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA | *val); 321 322 W_REG(pi->osh, &pcieregs->mdiodata, mdiodata); 323 324 PR28829_DELAY(); 325 326 /* retry till the transaction is complete */ 327 while (i < pcie_serdes_spinwait) { 328 if (R_REG(pi->osh, &(pcieregs->mdiocontrol)) & MDIOCTL_ACCESS_DONE) { 329 if (!write) { 330 PR28829_DELAY(); 331 *val = (R_REG(pi->osh, &(pcieregs->mdiodata)) & MDIODATA_MASK); 332 } 333 /* Disable mdio access to SERDES */ 334 W_REG(pi->osh, (&pcieregs->mdiocontrol), 0); 335 return 0; 336 } 337 OSL_DELAY(1000); 338 i++; 339 } 340 341 PCI_ERROR(("pcie_mdioop: timed out op: %d\n", write)); 342 /* Disable mdio access to SERDES */ 343 W_REG(pi->osh, (&pcieregs->mdiocontrol), 0); 344 return 1; 345} 346 347/* use the mdio interface to read from mdio slaves */ 348static int 349pcie_mdioread(pcicore_info_t *pi, uint physmedia, uint regaddr, uint *regval) 350{ 351 return pcie_mdioop(pi, physmedia, regaddr, FALSE, regval); 352} 353 354/* use the mdio interface to write to mdio slaves */ 355static int 356pcie_mdiowrite(pcicore_info_t *pi, uint physmedia, uint regaddr, uint val) 357{ 358 return pcie_mdioop(pi, physmedia, regaddr, TRUE, &val); 359} 360 361/* ***** Support functions ***** */ 362static uint32 363pcie_devcontrol_mrrs(void *pch, uint32 mask, uint32 val) 364{ 365 pcicore_info_t *pi = (pcicore_info_t *)pch; 366 uint32 reg_val; 367 uint8 offset; 368 369 offset = pi->pciecap_devctrl_offset; 370 if (!offset) 371 return 0; 372 373 reg_val = OSL_PCI_READ_CONFIG(pi->osh, offset, sizeof(uint32)); 374 /* set operation */ 375 if (mask) { 376 if (val > PCIE_CAP_DEVCTRL_MRRS_128B) { 377 if (pi->sih->buscorerev < 18) { 378 PCI_ERROR(("%s pcie corerev %d doesn't support >128B MRRS", 379 __FUNCTION__, pi->sih->buscorerev)); 380 val = PCIE_CAP_DEVCTRL_MRRS_128B; 381 } 382 } 383 384 reg_val &= ~PCIE_CAP_DEVCTRL_MRRS_MASK; 385 reg_val |= (val << PCIE_CAP_DEVCTRL_MRRS_SHIFT) & PCIE_CAP_DEVCTRL_MRRS_MASK; 386 387 OSL_PCI_WRITE_CONFIG(pi->osh, offset, sizeof(uint32), reg_val); 388 reg_val = OSL_PCI_READ_CONFIG(pi->osh, offset, sizeof(uint32)); 389 } 390 return reg_val; 391} 392 393uint8 394pcie_clkreq(void *pch, uint32 mask, uint32 val) 395{ 396 pcicore_info_t *pi = (pcicore_info_t *)pch; 397 uint32 reg_val; 398 uint8 offset; 399 400 offset = pi->pciecap_lcreg_offset; 401 if (!offset) 402 return 0; 403 404 reg_val = OSL_PCI_READ_CONFIG(pi->osh, offset, sizeof(uint32)); 405 /* set operation */ 406 if (mask) { 407 if (val) 408 reg_val |= PCIE_CLKREQ_ENAB; 409 else 410 reg_val &= ~PCIE_CLKREQ_ENAB; 411 OSL_PCI_WRITE_CONFIG(pi->osh, offset, sizeof(uint32), reg_val); 412 reg_val = OSL_PCI_READ_CONFIG(pi->osh, offset, sizeof(uint32)); 413 } 414 if (reg_val & PCIE_CLKREQ_ENAB) 415 return 1; 416 else 417 return 0; 418} 419 420static void 421pcie_extendL1timer(pcicore_info_t *pi, bool extend) 422{ 423 uint32 w; 424 si_t *sih = pi->sih; 425 osl_t *osh = pi->osh; 426 sbpcieregs_t *pcieregs = pi->regs.pcieregs; 427 428 if (!PCIE(sih)) 429 return; 430 431 w = pcie_readreg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG); 432 433 if (extend && sih->buscorerev >= 7) 434 w |= PCIE_ASPMTIMER_EXTEND; 435 else 436 w &= ~PCIE_ASPMTIMER_EXTEND; 437 pcie_writereg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG, w); 438 w = pcie_readreg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG); 439} 440 441/* centralized clkreq control policy */ 442static void 443pcie_clkreq_upd(pcicore_info_t *pi, uint state) 444{ 445 si_t *sih = pi->sih; 446 ASSERT(PCIE(sih)); 447 448 switch (state) { 449 case SI_DOATTACH: 450 if (PCIE_ASPM(sih)) 451 pcie_clkreq((void *)pi, 1, 0); 452 break; 453 case SI_PCIDOWN: 454 if (sih->buscorerev == 6) { /* turn on serdes PLL down */ 455 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, chipcontrol_addr), 456 ~0, 0); 457 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, chipcontrol_data), 458 ~0x40, 0); 459 } else if (pi->pcie_pr42767) { 460 pcie_clkreq((void *)pi, 1, 1); 461 } 462 break; 463 case SI_PCIUP: 464 if (sih->buscorerev == 6) { /* turn off serdes PLL down */ 465 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, chipcontrol_addr), 466 ~0, 0); 467 si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, chipcontrol_data), 468 ~0x40, 0x40); 469 } else if (PCIE_ASPM(sih)) { /* disable clkreq */ 470 pcie_clkreq((void *)pi, 1, 0); 471 } 472 break; 473 default: 474 ASSERT(0); 475 break; 476 } 477} 478 479/* ***** PCI core WARs ***** */ 480/* Done only once at attach time */ 481static void 482pcie_war_polarity(pcicore_info_t *pi) 483{ 484 uint32 w; 485 486 if (pi->pcie_polarity != 0) 487 return; 488 489 w = pcie_readreg(pi->osh, pi->regs.pcieregs, PCIE_PCIEREGS, PCIE_PLP_STATUSREG); 490 491 /* Detect the current polarity at attach and force that polarity and 492 * disable changing the polarity 493 */ 494 if ((w & PCIE_PLP_POLARITYINV_STAT) == 0) 495 pi->pcie_polarity = (SERDES_RX_CTRL_FORCE); 496 else 497 pi->pcie_polarity = (SERDES_RX_CTRL_FORCE | SERDES_RX_CTRL_POLARITY); 498} 499 500/* enable ASPM and CLKREQ if srom doesn't have it */ 501/* Needs to happen when update to shadow SROM is needed 502 * : Coming out of 'standby'/'hibernate' 503 * : If pcie_war_aspm_ovr state changed 504 */ 505static void 506pcie_war_aspm_clkreq(pcicore_info_t *pi) 507{ 508 sbpcieregs_t *pcieregs = pi->regs.pcieregs; 509 si_t *sih = pi->sih; 510 uint16 val16, *reg16; 511 uint32 w; 512 513 if (!PCIE_ASPM(sih)) 514 return; 515 516 /* bypass this on QT or VSIM */ 517 if (!ISSIM_ENAB(sih)) { 518 519 reg16 = &pcieregs->sprom[SRSH_ASPM_OFFSET]; 520 val16 = R_REG(pi->osh, reg16); 521 522 val16 &= ~SRSH_ASPM_ENB; 523 if (pi->pcie_war_aspm_ovr == PCIE_ASPM_ENAB) 524 val16 |= SRSH_ASPM_ENB; 525 else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L1_ENAB) 526 val16 |= SRSH_ASPM_L1_ENB; 527 else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L0s_ENAB) 528 val16 |= SRSH_ASPM_L0s_ENB; 529 530 W_REG(pi->osh, reg16, val16); 531 532 w = OSL_PCI_READ_CONFIG(pi->osh, pi->pciecap_lcreg_offset, sizeof(uint32)); 533 w &= ~PCIE_ASPM_ENAB; 534 w |= pi->pcie_war_aspm_ovr; 535 OSL_PCI_WRITE_CONFIG(pi->osh, pi->pciecap_lcreg_offset, sizeof(uint32), w); 536 } 537 538 reg16 = &pcieregs->sprom[SRSH_CLKREQ_OFFSET_REV5]; 539 val16 = R_REG(pi->osh, reg16); 540 541 if (pi->pcie_war_aspm_ovr != PCIE_ASPM_DISAB) { 542 val16 |= SRSH_CLKREQ_ENB; 543 pi->pcie_pr42767 = TRUE; 544 } else 545 val16 &= ~SRSH_CLKREQ_ENB; 546 547 W_REG(pi->osh, reg16, val16); 548} 549 550static void 551pcie_war_pmebits(pcicore_info_t *pi) 552{ 553 sbpcieregs_t *pcieregs = pi->regs.pcieregs; 554 uint16 val16, *reg16; 555 556 if (pi->sih->buscorerev != 18 && pi->sih->buscorerev != 19) 557 return; 558 559 reg16 = &pcieregs->sprom[SRSH_CLKREQ_OFFSET_REV8]; 560 val16 = R_REG(pi->osh, reg16); 561 if (val16 != pi->pmebits) { 562 PCI_ERROR(("pcie_war_pmebits: pmebits mismatch 0x%x (was 0x%x)\n", 563 val16, pi->pmebits)); 564 pi->pmebits = 0x1f30; 565 W_REG(pi->osh, reg16, pi->pmebits); 566 val16 = R_REG(pi->osh, reg16); 567 PCI_ERROR(("pcie_war_pmebits: update pmebits to 0x%x\n", val16)); 568 } 569} 570 571/* Apply the polarity determined at the start */ 572/* Needs to happen when coming out of 'standby'/'hibernate' */ 573static void 574pcie_war_serdes(pcicore_info_t *pi) 575{ 576 uint32 w = 0; 577 578 if (pi->pcie_polarity != 0) 579 pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CTRL, pi->pcie_polarity); 580 581 pcie_mdioread(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, &w); 582 if (w & PLL_CTRL_FREQDET_EN) { 583 w &= ~PLL_CTRL_FREQDET_EN; 584 pcie_mdiowrite(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, w); 585 } 586} 587 588/* Fix MISC config to allow coming out of L2/L3-Ready state w/o PRST */ 589/* Needs to happen when coming out of 'standby'/'hibernate' */ 590static void 591BCMINITFN(pcie_misc_config_fixup)(pcicore_info_t *pi) 592{ 593 sbpcieregs_t *pcieregs = pi->regs.pcieregs; 594 uint16 val16, *reg16; 595 596 reg16 = &pcieregs->sprom[SRSH_PCIE_MISC_CONFIG]; 597 val16 = R_REG(pi->osh, reg16); 598 599 if ((val16 & SRSH_L23READY_EXIT_NOPERST) == 0) { 600 val16 |= SRSH_L23READY_EXIT_NOPERST; 601 W_REG(pi->osh, reg16, val16); 602 } 603} 604 605/* quick hack for testing */ 606/* Needs to happen when coming out of 'standby'/'hibernate' */ 607static void 608pcie_war_noplldown(pcicore_info_t *pi) 609{ 610 sbpcieregs_t *pcieregs = pi->regs.pcieregs; 611 uint16 *reg16; 612 613 ASSERT(pi->sih->buscorerev == 7); 614 615 /* turn off serdes PLL down */ 616 si_corereg(pi->sih, SI_CC_IDX, OFFSETOF(chipcregs_t, chipcontrol), 617 CHIPCTRL_4321_PLL_DOWN, CHIPCTRL_4321_PLL_DOWN); 618 619 /* clear srom shadow backdoor */ 620 reg16 = &pcieregs->sprom[SRSH_BD_OFFSET]; 621 W_REG(pi->osh, reg16, 0); 622} 623 624/* Needs to happen when coming out of 'standby'/'hibernate' */ 625static void 626pcie_war_pci_setup(pcicore_info_t *pi) 627{ 628 si_t *sih = pi->sih; 629 osl_t *osh = pi->osh; 630 sbpcieregs_t *pcieregs = pi->regs.pcieregs; 631 uint32 w; 632 633 if ((sih->buscorerev == 0) || (sih->buscorerev == 1)) { 634 w = pcie_readreg(osh, pcieregs, PCIE_PCIEREGS, PCIE_TLP_WORKAROUNDSREG); 635 w |= 0x8; 636 pcie_writereg(osh, pcieregs, PCIE_PCIEREGS, PCIE_TLP_WORKAROUNDSREG, w); 637 } 638 639 if (sih->buscorerev == 1) { 640 w = pcie_readreg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG); 641 w |= (0x40); 642 pcie_writereg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG, w); 643 } 644 645 if (sih->buscorerev == 0) { 646 pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_TIMER1, 0x8128); 647 pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDR, 0x0100); 648 pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466); 649 } else if (PCIE_ASPM(sih)) { 650 /* Change the L1 threshold for better performance */ 651 w = pcie_readreg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG); 652 w &= ~(PCIE_L1THRESHOLDTIME_MASK); 653 w |= (PCIE_L1THRESHOLD_WARVAL << PCIE_L1THRESHOLDTIME_SHIFT); 654 pcie_writereg(osh, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG, w); 655 656 pcie_war_serdes(pi); 657 658 pcie_war_aspm_clkreq(pi); 659 } else if (pi->sih->buscorerev == 7) 660 pcie_war_noplldown(pi); 661 662 /* Note that the fix is actually in the SROM, that's why this is open-ended */ 663 if (pi->sih->buscorerev >= 6) 664 pcie_misc_config_fixup(pi); 665} 666 667void 668pcie_war_ovr_aspm_update(void *pch, uint8 aspm) 669{ 670 pcicore_info_t *pi = (pcicore_info_t *)pch; 671 672 if (!PCIE_ASPM(pi->sih)) 673 return; 674 675 /* Validate */ 676 if (aspm > PCIE_ASPM_ENAB) 677 return; 678 679 pi->pcie_war_aspm_ovr = aspm; 680 681 /* Update the current state */ 682 pcie_war_aspm_clkreq(pi); 683} 684 685 686void 687pcie_power_save_enable(void *pch, bool enable) 688{ 689 pcicore_info_t *pi = (pcicore_info_t *)pch; 690 691 692 if (!pi) 693 return; 694 695 pi->pcie_power_save = enable; 696} 697 698static void 699pcie_power_save_upd(pcicore_info_t *pi, bool up) 700{ 701 si_t *sih = pi->sih; 702 703 if (!pi->pcie_power_save) 704 return; 705 706 707 if ((sih->buscorerev >= 15) && (sih->buscorerev <= 20)) { 708 709 pcicore_pcieserdesreg(pi, MDIO_DEV_BLK1, BLK1_PWR_MGMT1, 1, 0x7F64); 710 711 if (up) 712 pcicore_pcieserdesreg(pi, MDIO_DEV_BLK1, BLK1_PWR_MGMT3, 1, 0x74); 713 else 714 pcicore_pcieserdesreg(pi, MDIO_DEV_BLK1, BLK1_PWR_MGMT3, 1, 0x7C); 715 } 716} 717 718void 719pcie_set_request_size(void *pch, uint16 size) 720{ 721 pcicore_info_t *pi = (pcicore_info_t *)pch; 722 723 if (!pi) 724 return; 725 if (size == 128) 726 pi->pcie_reqsize = PCIE_CAP_DEVCTRL_MRRS_128B; 727 else if (size == 256) 728 pi->pcie_reqsize = PCIE_CAP_DEVCTRL_MRRS_256B; 729 else if (size == 512) 730 pi->pcie_reqsize = PCIE_CAP_DEVCTRL_MRRS_512B; 731 else 732 return; 733 734 if (pi->sih->buscorerev == 18 || pi->sih->buscorerev == 19) 735 pcie_devcontrol_mrrs(pi, PCIE_CAP_DEVCTRL_MRRS_MASK, (uint32)pi->pcie_reqsize); 736} 737 738uint16 739pcie_get_request_size(void *pch) 740{ 741 pcicore_info_t *pi = (pcicore_info_t *)pch; 742 743 if (!pi) 744 return (0); 745 746 if (pi->pcie_reqsize == PCIE_CAP_DEVCTRL_MRRS_128B) 747 return (128); 748 else if (pi->pcie_reqsize == PCIE_CAP_DEVCTRL_MRRS_256B) 749 return (256); 750 else if (pi->pcie_reqsize == PCIE_CAP_DEVCTRL_MRRS_512B) 751 return (512); 752 return (0); 753} 754 755/* ***** Functions called during driver state changes ***** */ 756void 757BCMATTACHFN(pcicore_attach)(void *pch, char *pvars, int state) 758{ 759 pcicore_info_t *pi = (pcicore_info_t *)pch; 760 si_t *sih = pi->sih; 761 762 if (PCIE_ASPM(sih)) { 763 if (((sih->boardvendor == VENDOR_APPLE) && 764 ((uint8)getintvar(pvars, "sromrev") == 4) && 765 ((uint8)getintvar(pvars, "boardrev") <= 0x71)) || 766 ((uint32)getintvar(pvars, "boardflags2") & BFL2_PCIEWAR_OVR)) { 767 pi->pcie_war_aspm_ovr = PCIE_ASPM_DISAB; 768 } else { 769 pi->pcie_war_aspm_ovr = PCIE_ASPM_ENAB; 770 } 771 } 772 773 pi->pcie_reqsize = PCIE_CAP_DEVCTRL_MRRS_128B; 774 if (BCM4331_CHIP_ID == CHIPID(sih->chip)) 775 pi->pcie_reqsize = PCIE_CAP_DEVCTRL_MRRS_512B; 776 777 /* These need to happen in this order only */ 778 pcie_war_polarity(pi); 779 780 pcie_war_serdes(pi); 781 782 pcie_war_aspm_clkreq(pi); 783 784 pcie_clkreq_upd(pi, state); 785 786 /* Alter default TX drive strength setting */ 787 if (sih->boardvendor == VENDOR_APPLE) { 788 if (sih->boardtype == 0x8d) 789 /* change the TX drive strength to max */ 790 pcicore_pcieserdesreg(pch, MDIO_DEV_TXCTRL0, 0x18, 0xff, 0x7f); 791 else if (BCM4331_CHIP_ID == CHIPID(sih->chip)) 792 /* change the drive strength for X19b & X28 to 700mv */ 793 pcicore_pcieserdesreg(pch, MDIO_DEV_TXCTRL0, 0x18, 0xff, 0x70); 794 } 795} 796 797void 798pcicore_hwup(void *pch) 799{ 800 pcicore_info_t *pi = (pcicore_info_t *)pch; 801 802 if (!pi || !PCIE(pi->sih)) 803 return; 804 805 pcie_power_save_upd(pi, TRUE); 806 807 if (pi->sih->boardtype == CB2_4321_BOARD || pi->sih->boardtype == CB2_4321_AG_BOARD) 808 pcicore_fixlatencytimer(pch, 0x20); 809 810 pcie_war_pci_setup(pi); 811 812 /* Alter default TX drive strength setting */ 813 if (pi->sih->boardvendor == VENDOR_APPLE) { 814 if (pi->sih->boardtype == 0x8d) 815 /* change the TX drive strength to max */ 816 pcicore_pcieserdesreg(pch, MDIO_DEV_TXCTRL0, 0x18, 0xff, 0x7f); 817 else if (BCM4331_CHIP_ID == CHIPID(pi->sih->chip)) 818 /* change the drive strength for X19b & X28 to 700mv */ 819 pcicore_pcieserdesreg(pch, MDIO_DEV_TXCTRL0, 0x18, 0xff, 0x70); 820 } 821} 822 823void 824pcicore_up(void *pch, int state) 825{ 826 pcicore_info_t *pi = (pcicore_info_t *)pch; 827 bool is_x19_x28 = FALSE; 828 829 if (!pi || !PCIE(pi->sih)) 830 return; 831 832 pcie_power_save_upd(pi, TRUE); 833 834 /* Restore L1 timer for better performance */ 835 pcie_extendL1timer(pi, TRUE); 836 837 pcie_clkreq_upd(pi, state); 838 839 is_x19_x28 = ((pi->sih->boardvendor == VENDOR_APPLE) && 840 ((pi->sih->boardtype == BCM94331X19) || 841 (pi->sih->boardtype == BCM94331PCIEBT3Ax_SSID))); 842 843 if (pi->sih->buscorerev == 18 || 844 (pi->sih->buscorerev == 19 && !is_x19_x28)) 845 pi->pcie_reqsize = PCIE_CAP_DEVCTRL_MRRS_128B; 846 847 pcie_devcontrol_mrrs(pi, PCIE_CAP_DEVCTRL_MRRS_MASK, pi->pcie_reqsize); 848} 849 850/* When the device is going to enter D3 state (or the system is going to enter S3/S4 states */ 851void 852pcicore_sleep(void *pch) 853{ 854 pcicore_info_t *pi = (pcicore_info_t *)pch; 855 uint32 w; 856 857 if (!pi || !PCIE(pi->sih)) 858 return; 859 860 pcie_power_save_upd(pi, FALSE); 861 862 863 if (!PCIE_ASPM(pi->sih)) 864 return; 865 866 867 w = OSL_PCI_READ_CONFIG(pi->osh, pi->pciecap_lcreg_offset, sizeof(uint32)); 868 w &= ~PCIE_CAP_LCREG_ASPML1; 869 OSL_PCI_WRITE_CONFIG(pi->osh, pi->pciecap_lcreg_offset, sizeof(uint32), w); 870 871 872 pi->pcie_pr42767 = FALSE; 873} 874 875void 876pcicore_down(void *pch, int state) 877{ 878 pcicore_info_t *pi = (pcicore_info_t *)pch; 879 880 if (!pi || !PCIE(pi->sih)) 881 return; 882 883 pcie_clkreq_upd(pi, state); 884 885 /* Reduce L1 timer for better power savings */ 886 pcie_extendL1timer(pi, FALSE); 887 888 pcie_power_save_upd(pi, FALSE); 889} 890 891/* ***** Wake-on-wireless-LAN (WOWL) support functions ***** */ 892/* Just uses PCI config accesses to find out, when needed before sb_attach is done */ 893bool 894pcicore_pmecap_fast(osl_t *osh) 895{ 896 uint8 cap_ptr; 897 uint32 pmecap; 898 899 cap_ptr = pcicore_find_pci_capability(osh, PCI_CAP_POWERMGMTCAP_ID, NULL, NULL); 900 901 if (!cap_ptr) 902 return FALSE; 903 904 pmecap = OSL_PCI_READ_CONFIG(osh, cap_ptr, sizeof(uint32)); 905 906 return ((pmecap & PME_CAP_PM_STATES) != 0); 907} 908 909/* return TRUE if PM capability exists in the pci config space 910 * Uses and caches the information using core handle 911 */ 912static bool 913pcicore_pmecap(pcicore_info_t *pi) 914{ 915 uint8 cap_ptr; 916 uint32 pmecap; 917 sbpcieregs_t *pcieregs = pi->regs.pcieregs; 918 uint16*reg16; 919 920 if (!pi->pmecap_offset) { 921 cap_ptr = pcicore_find_pci_capability(pi->osh, PCI_CAP_POWERMGMTCAP_ID, NULL, NULL); 922 if (!cap_ptr) 923 return FALSE; 924 925 pi->pmecap_offset = cap_ptr; 926 927 reg16 = &pcieregs->sprom[SRSH_CLKREQ_OFFSET_REV8]; 928 pi->pmebits = R_REG(pi->osh, reg16); 929 930 pmecap = OSL_PCI_READ_CONFIG(pi->osh, pi->pmecap_offset, sizeof(uint32)); 931 932 /* At least one state can generate PME */ 933 pi->pmecap = (pmecap & PME_CAP_PM_STATES) != 0; 934 } 935 936 return (pi->pmecap); 937} 938 939/* Enable PME generation */ 940void 941pcicore_pmeen(void *pch) 942{ 943 pcicore_info_t *pi = (pcicore_info_t *)pch; 944 uint32 w; 945 946 /* if not pmecapable return */ 947 if (!pcicore_pmecap(pi)) 948 return; 949 950 pcie_war_pmebits(pi); 951 w = OSL_PCI_READ_CONFIG(pi->osh, pi->pmecap_offset + PME_CSR_OFFSET, sizeof(uint32)); 952 w |= (PME_CSR_PME_EN); 953 OSL_PCI_WRITE_CONFIG(pi->osh, pi->pmecap_offset + PME_CSR_OFFSET, sizeof(uint32), w); 954} 955 956/* 957 * Return TRUE if PME status set 958 */ 959bool 960pcicore_pmestat(void *pch) 961{ 962 pcicore_info_t *pi = (pcicore_info_t *)pch; 963 uint32 w; 964 965 if (!pcicore_pmecap(pi)) 966 return FALSE; 967 968 w = OSL_PCI_READ_CONFIG(pi->osh, pi->pmecap_offset + PME_CSR_OFFSET, sizeof(uint32)); 969 970 return (w & PME_CSR_PME_STAT) == PME_CSR_PME_STAT; 971} 972 973/* Disable PME generation, clear the PME status bit if set 974 */ 975void 976pcicore_pmeclr(void *pch) 977{ 978 pcicore_info_t *pi = (pcicore_info_t *)pch; 979 uint32 w; 980 981 if (!pcicore_pmecap(pi)) 982 return; 983 984 pcie_war_pmebits(pi); 985 w = OSL_PCI_READ_CONFIG(pi->osh, pi->pmecap_offset + PME_CSR_OFFSET, sizeof(uint32)); 986 987 PCI_ERROR(("pcicore_pci_pmeclr PMECSR : 0x%x\n", w)); 988 989 /* PMESTAT is cleared by writing 1 to it */ 990 w &= ~(PME_CSR_PME_EN); 991 992 OSL_PCI_WRITE_CONFIG(pi->osh, pi->pmecap_offset + PME_CSR_OFFSET, sizeof(uint32), w); 993} 994 995static void 996pcicore_fixlatencytimer(pcicore_info_t* pch, uint8 timer_val) 997{ 998 pcicore_info_t *pi = (pcicore_info_t *)pch; 999 osl_t *osh; 1000 uint8 lattim; 1001 1002 osh = pi->osh; 1003 lattim = read_pci_cfg_byte(PCI_CFG_LATTIM); 1004 1005 if (!lattim) { 1006 PCI_ERROR(("%s: Modifying PCI_CFG_LATTIM from 0x%x to 0x%x\n", 1007 __FUNCTION__, lattim, timer_val)); 1008 write_pci_cfg_byte(PCI_CFG_LATTIM, timer_val); 1009 } 1010} 1011 1012uint32 1013pcie_lcreg(void *pch, uint32 mask, uint32 val) 1014{ 1015 pcicore_info_t *pi = (pcicore_info_t *)pch; 1016 uint8 offset; 1017 1018 offset = pi->pciecap_lcreg_offset; 1019 if (!offset) 1020 return 0; 1021 1022 /* set operation */ 1023 if (mask) 1024 OSL_PCI_WRITE_CONFIG(pi->osh, offset, sizeof(uint32), val); 1025 1026 return OSL_PCI_READ_CONFIG(pi->osh, offset, sizeof(uint32)); 1027} 1028 1029 1030uint32 1031pcicore_pciereg(void *pch, uint32 offset, uint32 mask, uint32 val, uint type) 1032{ 1033 uint32 reg_val = 0; 1034 pcicore_info_t *pi = (pcicore_info_t *)pch; 1035 sbpcieregs_t *pcieregs = pi->regs.pcieregs; 1036 osl_t *osh = pi->osh; 1037 1038 if (mask) { 1039 PCI_ERROR(("PCIEREG: 0x%x writeval 0x%x\n", offset, val)); 1040 pcie_writereg(osh, pcieregs, type, offset, val); 1041 } 1042 1043 /* Should not read register 0x154 */ 1044 if (pi->sih->buscorerev <= 5 && offset == PCIE_DLLP_PCIE11 && type == PCIE_PCIEREGS) 1045 return reg_val; 1046 1047 reg_val = pcie_readreg(osh, pcieregs, type, offset); 1048 PCI_ERROR(("PCIEREG: 0x%x readval is 0x%x\n", offset, reg_val)); 1049 1050 return reg_val; 1051} 1052 1053uint32 1054pcicore_pcieserdesreg(void *pch, uint32 mdioslave, uint32 offset, uint32 mask, uint32 val) 1055{ 1056 uint32 reg_val = 0; 1057 pcicore_info_t *pi = (pcicore_info_t *)pch; 1058 1059 if (mask) { 1060 pcie_mdiowrite(pi, mdioslave, offset, val); 1061 } 1062 1063 if (pcie_mdioread(pi, mdioslave, offset, ®_val)) 1064 reg_val = 0xFFFFFFFF; 1065 1066 return reg_val; 1067} 1068 1069 1070#if defined(BCMDBG_DUMP) 1071 1072/* size that can take bitfielddump */ 1073#define BITFIELD_DUMP_SIZE 2048 1074 1075/* Dump PCIE PLP/DLLP/TLP diagnostic registers */ 1076int 1077pcicore_dump_pcieregs(void *pch, struct bcmstrbuf *b) 1078{ 1079 pcicore_info_t *pi = (pcicore_info_t *)pch; 1080 sbpcieregs_t *pcieregs = pi->regs.pcieregs; 1081 si_t *sih = pi->sih; 1082 uint reg_val = 0; 1083 char *bitfield_dump_buf; 1084 1085 if (!(bitfield_dump_buf = MALLOC(pi->osh, BITFIELD_DUMP_SIZE))) { 1086 printf("bitfield dump allocation failed\n"); 1087 return BCME_NOMEM; 1088 } 1089 1090 bcm_bprintf(b, "PLPRegs \t"); 1091 bcmdumpfields(si_pcie_readreg, (void *)(uintptr)pi->sih, PCIE_PCIEREGS, 1092 (struct fielddesc *)(uintptr)pcie_plp_regdesc, 1093 bitfield_dump_buf, BITFIELD_DUMP_SIZE); 1094 bcm_bprintf(b, "%s", bitfield_dump_buf); 1095 bzero(bitfield_dump_buf, BITFIELD_DUMP_SIZE); 1096 bcm_bprintf(b, "\n"); 1097 bcm_bprintf(b, "DLLPRegs \t"); 1098 bcmdumpfields(si_pcie_readreg, (void *)(uintptr)pi->sih, PCIE_PCIEREGS, 1099 (struct fielddesc *)(uintptr)pcie_dllp_regdesc, 1100 bitfield_dump_buf, BITFIELD_DUMP_SIZE); 1101 bcm_bprintf(b, "%s", bitfield_dump_buf); 1102 bzero(bitfield_dump_buf, BITFIELD_DUMP_SIZE); 1103 bcm_bprintf(b, "\n"); 1104 bcm_bprintf(b, "TLPRegs \t"); 1105 bcmdumpfields(si_pcie_readreg, (void *)(uintptr)pi->sih, PCIE_PCIEREGS, 1106 (struct fielddesc *)(uintptr)pcie_tlp_regdesc, 1107 bitfield_dump_buf, BITFIELD_DUMP_SIZE); 1108 bcm_bprintf(b, "%s", bitfield_dump_buf); 1109 bzero(bitfield_dump_buf, BITFIELD_DUMP_SIZE); 1110 bcm_bprintf(b, "\n"); 1111 1112 /* enable mdio access to SERDES */ 1113 W_REG(pi->osh, (&pcieregs->mdiocontrol), MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL); 1114 1115 bcm_bprintf(b, "SERDES regs \n"); 1116 if (sih->buscorerev >= 10) { 1117 pcie_mdioread(pi, MDIO_DEV_IEEE0, 0x2, ®_val); 1118 bcm_bprintf(b, "block IEEE0, offset 2: 0x%x\n", reg_val); 1119 pcie_mdioread(pi, MDIO_DEV_IEEE0, 0x3, ®_val); 1120 bcm_bprintf(b, "block IEEE0, offset 2: 0x%x\n", reg_val); 1121 pcie_mdioread(pi, MDIO_DEV_IEEE1, 0x08, ®_val); 1122 bcm_bprintf(b, "block IEEE1, lanestatus: 0x%x\n", reg_val); 1123 pcie_mdioread(pi, MDIO_DEV_IEEE1, 0x0a, ®_val); 1124 bcm_bprintf(b, "block IEEE1, lanestatus2: 0x%x\n", reg_val); 1125 pcie_mdioread(pi, MDIO_DEV_BLK4, 0x16, ®_val); 1126 bcm_bprintf(b, "MDIO_DEV_BLK4, lanetest0: 0x%x\n", reg_val); 1127 pcie_mdioread(pi, MDIO_DEV_TXPLL, 0x11, ®_val); 1128 bcm_bprintf(b, "MDIO_DEV_TXPLL, pllcontrol: 0x%x\n", reg_val); 1129 pcie_mdioread(pi, MDIO_DEV_TXPLL, 0x12, ®_val); 1130 bcm_bprintf(b, "MDIO_DEV_TXPLL, plltimer1: 0x%x\n", reg_val); 1131 pcie_mdioread(pi, MDIO_DEV_TXPLL, 0x13, ®_val); 1132 bcm_bprintf(b, "MDIO_DEV_TXPLL, plltimer2: 0x%x\n", reg_val); 1133 pcie_mdioread(pi, MDIO_DEV_TXPLL, 0x14, ®_val); 1134 bcm_bprintf(b, "MDIO_DEV_TXPLL, plltimer3: 0x%x\n", reg_val); 1135 pcie_mdioread(pi, MDIO_DEV_TXPLL, 0x17, ®_val); 1136 bcm_bprintf(b, "MDIO_DEV_TXPLL, freqdetcounter: 0x%x\n", reg_val); 1137 } else { 1138 pcie_mdioread(pi, MDIODATA_DEV_RX, SERDES_RX_TIMER1, ®_val); 1139 bcm_bprintf(b, "rxtimer1 0x%x ", reg_val); 1140 pcie_mdioread(pi, MDIODATA_DEV_RX, SERDES_RX_CDR, ®_val); 1141 bcm_bprintf(b, "rxCDR 0x%x ", reg_val); 1142 pcie_mdioread(pi, MDIODATA_DEV_RX, SERDES_RX_CDRBW, ®_val); 1143 bcm_bprintf(b, "rxCDRBW 0x%x\n", reg_val); 1144 } 1145 1146 /* disable mdio access to SERDES */ 1147 W_REG(pi->osh, (&pcieregs->mdiocontrol), 0); 1148 1149 MFREE(pi->osh, bitfield_dump_buf, BITFIELD_DUMP_SIZE); 1150 1151 return 0; 1152} 1153#endif 1154