Example #1
0
uint
pcie_writereg(si_t *sih, sbpcieregs_t *pcieregs, uint addrtype, uint offset, uint val)
{
	osl_t   *osh = si_osh(sih);

	ASSERT(pcieregs != NULL);
	BCM_REFERENCE(osh);

	if ((BUSTYPE(sih->bustype) == SI_BUS) || PCIE_GEN1(sih)) {
		switch (addrtype) {
			case PCIE_CONFIGREGS:
				W_REG(osh, (&pcieregs->configaddr), offset);
				W_REG(osh, (&pcieregs->configdata), val);
				break;
			case PCIE_PCIEREGS:
				W_REG(osh, (&pcieregs->u.pcie1.pcieindaddr), offset);
				W_REG(osh, (&pcieregs->u.pcie1.pcieinddata), val);
				break;
			default:
				ASSERT(0);
				break;
		}
	}
	else if (PCIE_GEN2(sih)) {
		W_REG(osh, (&pcieregs->configaddr), offset);
		W_REG(osh, (&pcieregs->configdata), val);
	}
	return 0;
}
Example #2
0
/* ***** Support functions ***** */
static uint32
pcie_devcontrol_mrrs(void *pch, uint32 mask, uint32 val)
{
	pcicore_info_t *pi = (pcicore_info_t *)pch;
	uint32 reg_val;
	uint8 offset;

	offset = pi->pciecap_devctrl_offset;
	if (!offset)
		return 0;

	reg_val = OSL_PCI_READ_CONFIG(pi->osh, offset, sizeof(uint32));
	/* set operation */
	if (mask) {
		if (val > PCIE_CAP_DEVCTRL_MRRS_128B) {
			if (PCIE_GEN1(pi->sih) && (pi->sih->buscorerev < 18)) {
				PCI_ERROR(("%s pcie corerev %d doesn't support >128B MRRS",
					__FUNCTION__, pi->sih->buscorerev));
				val = PCIE_CAP_DEVCTRL_MRRS_128B;
			}
		}

		reg_val &= ~PCIE_CAP_DEVCTRL_MRRS_MASK;
		reg_val |= (val << PCIE_CAP_DEVCTRL_MRRS_SHIFT) & PCIE_CAP_DEVCTRL_MRRS_MASK;

		OSL_PCI_WRITE_CONFIG(pi->osh, offset, sizeof(uint32), reg_val);
		reg_val = OSL_PCI_READ_CONFIG(pi->osh, offset, sizeof(uint32));
	}
	return reg_val;
}
Example #3
0
void
pcicore_hwup(void *pch)
{
	pcicore_info_t *pi = (pcicore_info_t *)pch;

	if (!pi || !PCIE_GEN1(pi->sih))
		return;

	pcie_power_save_upd(pi, TRUE);

	if (pi->sih->boardtype == CB2_4321_BOARD || pi->sih->boardtype == CB2_4321_AG_BOARD)
		pcicore_fixlatencytimer(pch, 0x20);

	pcie_war_pci_setup(pi);

	/* Alter default TX drive strength setting */
	if (pi->sih->boardvendor == VENDOR_APPLE) {
		if (pi->sih->boardtype == 0x8d)
			/* change the TX drive strength to max */
			pcicore_pcieserdesreg(pch, MDIO_DEV_TXCTRL0, 0x18, 0xff, 0x7f);
		else if (PCIE_DRIVE_STRENGTH_OVERRIDE(pi->sih))
			/* change the drive strength to 700mv */
			pcicore_pcieserdesreg(pch, MDIO_DEV_TXCTRL0, 0x18, 0xff, 0x70);
	}
}
Example #4
0
uint32
pcie_ltr_reg(void *pch, uint32 reg, uint32 mask, uint32 val)
{
	pcicore_info_t *pi = (pcicore_info_t *)pch;
	uint32 reg_val;
	uint32 offset;

	if (PCIE_GEN1(pi->sih))
		return 0;

	if (reg == PCIE_CAP_LTR0_REG)
		offset = pi->pciecap_ltr0_reg_offset;
	else if (reg == PCIE_CAP_LTR1_REG)
		offset = pi->pciecap_ltr1_reg_offset;
	else if (reg == PCIE_CAP_LTR2_REG)
		offset = pi->pciecap_ltr2_reg_offset;
	else {
		PCI_ERROR(("pcie_ltr_reg: unsupported LTR register offset %d\n",
			reg));
		return 0;
	}

	if (!offset)
		return 0;

	if (mask) { /* set operation */
		reg_val = val;
		pcie_writereg(pi->sih, pi->regs.pcieregs, PCIE_CONFIGREGS, offset, reg_val);
	}
	else { /* get operation */
		reg_val = pcie_readreg(pi->sih, pi->regs.pcieregs, PCIE_CONFIGREGS, offset);
	}

	return reg_val;
}
Example #5
0
void
pcie_set_request_size(void *pch, uint16 size)
{
	pcicore_info_t *pi = (pcicore_info_t *)pch;
	si_t *sih;

	if (!pi)
		return;

	sih = pi->sih;

	if (size == 128)
		pi->pcie_reqsize = PCIE_CAP_DEVCTRL_MRRS_128B;
	else if (size == 256)
		pi->pcie_reqsize = PCIE_CAP_DEVCTRL_MRRS_256B;
	else if (size == 512)
		pi->pcie_reqsize = PCIE_CAP_DEVCTRL_MRRS_512B;
	else if (size == 1024)
		pi->pcie_reqsize = PCIE_CAP_DEVCTRL_MRRS_1024B;
	else
		return;

	if (PCIE_GEN1(sih)) {
		if (pi->sih->buscorerev == 18 || pi->sih->buscorerev == 19)
			pcie_devcontrol_mrrs(pi, PCIE_CAP_DEVCTRL_MRRS_MASK,
				(uint32)pi->pcie_reqsize);
	}
	else if (PCIE_GEN2(sih)) {
		pcie_devcontrol_mrrs(pi, PCIE_CAP_DEVCTRL_MRRS_MASK, (uint32)pi->pcie_reqsize);
	}
	else
		ASSERT(0);
}
Example #6
0
static int
pciegen1_mdioop(pcicore_info_t *pi, uint physmedia, uint regaddr, bool write, uint *val)
{
	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
	uint mdiodata;
	uint i = 0;
	uint pcie_serdes_spinwait = 10;

	if (!PCIE_GEN1(pi->sih))
		ASSERT(0);

	/* enable mdio access to SERDES */
	W_REG(pi->osh, (&pcieregs->u.pcie1.mdiocontrol), MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);

	if (pi->sih->buscorerev >= 10) {
		/* new serdes is slower in rw, using two layers of reg address mapping */
		if (!pcie_mdiosetblock(pi, physmedia))
			return 1;
		mdiodata = (MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
			(regaddr << MDIODATA_REGADDR_SHF);
		pcie_serdes_spinwait *= 20;
	} else {
		mdiodata = (physmedia << MDIODATA_DEVADDR_SHF_OLD) |
			(regaddr << MDIODATA_REGADDR_SHF_OLD);
	}

	if (!write)
		mdiodata |= (MDIODATA_START | MDIODATA_READ | MDIODATA_TA);
	else
		mdiodata |= (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA | *val);

	W_REG(pi->osh, &pcieregs->u.pcie1.mdiodata, mdiodata);

	PR28829_DELAY();

	/* retry till the transaction is complete */
	while (i < pcie_serdes_spinwait) {
		if (R_REG(pi->osh, &(pcieregs->u.pcie1.mdiocontrol)) & MDIOCTL_ACCESS_DONE) {
			if (!write) {
				PR28829_DELAY();
				*val = (R_REG(pi->osh, &(pcieregs->u.pcie1.mdiodata)) &
					MDIODATA_MASK);
			}
			/* Disable mdio access to SERDES */
			W_REG(pi->osh, (&pcieregs->u.pcie1.mdiocontrol), 0);
			return 0;
		}
		OSL_DELAY(1000);
		i++;
	}

	PCI_ERROR(("pcie_mdioop: timed out op: %d\n", write));
	/* Disable mdio access to SERDES */
	W_REG(pi->osh, (&pcieregs->u.pcie1.mdiocontrol), 0);
	return 1;
}
Example #7
0
static int
pcie_mdioop(pcicore_info_t *pi, uint physmedia, uint regaddr, bool write, uint *val)
{
	if (PCIE_GEN1(pi->sih))
		return (pciegen1_mdioop(pi, physmedia, regaddr, write, val));
	else if (PCIE_GEN2(pi->sih))
		return (pciegen2_mdioop(pi, physmedia, regaddr, write, val, 0));
	else
		return 0xFFFFFFFF;
}
Example #8
0
/* Dump PCIE Info */
int
pcicore_dump_pcieinfo(void *pch, struct bcmstrbuf *b)
{
	pcicore_info_t *pi = (pcicore_info_t *)pch;

	if (!PCIE_GEN1(pi->sih) && !PCIE_GEN2(pi->sih))
		return BCME_ERROR;

	bcm_bprintf(b, "PCIE link speed: %d\n", pcie_get_link_speed(pch));
	return 0;
}
Example #9
0
/* ***** Functions called during driver state changes ***** */
void
BCMATTACHFN(pcicore_attach)(void *pch, char *pvars, int state)
{
	pcicore_info_t *pi = (pcicore_info_t *)pch;
	si_t *sih = pi->sih;

	if (!PCIE_GEN1(sih)) {
		if ((BCM4360_CHIP_ID == CHIPID(sih->chip)) ||
		    (BCM43460_CHIP_ID == CHIPID(sih->chip)) ||
		    (BCM4350_CHIP_ID == CHIPID(sih->chip)) ||
		    (BCM4352_CHIP_ID == CHIPID(sih->chip)) ||
		    (BCM4335_CHIP_ID == CHIPID(sih->chip)))
			pi->pcie_reqsize = PCIE_CAP_DEVCTRL_MRRS_1024B;
		return;
	}

	if (PCIEGEN1_ASPM(sih)) {
		if (((sih->boardvendor == VENDOR_APPLE) &&
		     ((uint8)getintvar(pvars, "sromrev") == 4) &&
		     ((uint8)getintvar(pvars, "boardrev") <= 0x71)) ||
		    ((uint32)getintvar(pvars, "boardflags2") & BFL2_PCIEWAR_OVR)) {
			pi->pcie_war_aspm_ovr = PCIE_ASPM_DISAB;
		} else {
			pi->pcie_war_aspm_ovr = PCIE_ASPM_ENAB;
		}
	}

	pi->pcie_reqsize = PCIE_CAP_DEVCTRL_MRRS_128B;
	if (BCM4331_CHIP_ID == CHIPID(sih->chip))
	    pi->pcie_reqsize = PCIE_CAP_DEVCTRL_MRRS_512B;

	bzero(pi->pcie_configspace, PCI_CONFIG_SPACE_SIZE);

	/* These need to happen in this order only */
	pcie_war_polarity(pi);

	pcie_war_serdes(pi);

	pcie_war_aspm_clkreq(pi);

	pcie_clkreq_upd(pi, state);

	pcie_war_pmebits(pi);

	/* Alter default TX drive strength setting */
	if (sih->boardvendor == VENDOR_APPLE) {
		if (sih->boardtype == 0x8d)
			/* change the TX drive strength to max */
			pcicore_pcieserdesreg(pch, MDIO_DEV_TXCTRL0, 0x18, 0xff, 0x7f);
		else if (PCIE_DRIVE_STRENGTH_OVERRIDE(sih))
			/* change the drive strength to 700mv */
			pcicore_pcieserdesreg(pch, MDIO_DEV_TXCTRL0, 0x18, 0xff, 0x70);
	}
}
Example #10
0
void
pcie_disable_TL_clk_gating(void *pch)
{
	/* disable TL clk gating is located in bit 4 of PCIEControl (Offset 0x000) */
	pcicore_info_t *pi = (pcicore_info_t *)pch;
	si_t *sih = pi->sih;

	if (!PCIE_GEN1(sih) && !PCIE_GEN2(sih))
		return;

	si_corereg(sih, sih->buscoreidx, 0, 0x10, 0x10);
}
Example #11
0
void
pcicore_down(void *pch, int state)
{
	pcicore_info_t *pi = (pcicore_info_t *)pch;

	if (!pi || !PCIE_GEN1(pi->sih))
		return;

	pcie_clkreq_upd(pi, state);

	/* Reduce L1 timer for better power savings */
	pcie_extendL1timer(pi, FALSE);

	pcie_power_save_upd(pi, FALSE);
}
Example #12
0
void
pcie_set_L1_entry_time(void *pch, uint32 val)
{
	/* L1 entry time is located in bits [22:16] of register 0x1004 (pdl_control_1) */
	pcicore_info_t *pi = (pcicore_info_t *)pch;
	si_t *sih = pi->sih;
	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
	uint32 data;

	if (!PCIE_GEN1(sih) && !PCIE_GEN2(sih))
		return;

	if (val > 0x7F)
		return;

	data = pcie_readreg(sih, pcieregs, PCIE_CONFIGREGS, 0x1004);
	pcie_writereg(pch, pcieregs, PCIE_CONFIGREGS, 0x1004, (data & ~0x7F0000) | (val << 16));
}
Example #13
0
/* mode : 0 -- reset, 1 -- tx, 2 -- rx */
void
pcie_set_error_injection(void *pch, uint32 mode)
{
	/* through reg_phy_ctl_7 - 0x181c */
	pcicore_info_t *pi = (pcicore_info_t *)pch;
	si_t *sih = pi->sih;
	sbpcieregs_t *pcieregs = pi->regs.pcieregs;

	if (!PCIE_GEN1(sih) && !PCIE_GEN2(sih))
		return;

	if (mode == 0)
		pcie_writereg(pch, pcieregs, PCIE_CONFIGREGS, 0x181c, 0);
	else if (mode == 1)
		pcie_writereg(pch, pcieregs, PCIE_CONFIGREGS, 0x181c, 0x14031);
	else
		pcie_writereg(pch, pcieregs, PCIE_CONFIGREGS, 0x181c, 0x2c031);
}
Example #14
0
static void
pcie_extendL1timer(pcicore_info_t *pi, bool extend)
{
	uint32 w;
	si_t *sih = pi->sih;
	sbpcieregs_t *pcieregs = pi->regs.pcieregs;

	if (!PCIE_GEN1(sih))
		return;

	w = pcie_readreg(sih, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);

	if (extend && sih->buscorerev >= 7)
		w |= PCIE_ASPMTIMER_EXTEND;
	else
		w &= ~PCIE_ASPMTIMER_EXTEND;
	pcie_writereg(sih, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG, w);
	w = pcie_readreg(sih, pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
}
Example #15
0
void
pcie_war_ovr_aspm_update(void *pch, uint8 aspm)
{
	pcicore_info_t *pi = (pcicore_info_t *)pch;

	if (!PCIE_GEN1(pi->sih))
		return;

	if (!PCIEGEN1_ASPM(pi->sih))
		return;

	/* Validate */
	if (aspm > PCIE_ASPM_ENAB)
		return;

	pi->pcie_war_aspm_ovr = aspm;

	/* Update the current state */
	pcie_war_aspm_clkreq(pi);
}
Example #16
0
/* centralized clkreq control policy */
static void
pcie_clkreq_upd(pcicore_info_t *pi, uint state)
{
	si_t *sih = pi->sih;
	ASSERT(PCIE(sih));

	if (!PCIE_GEN1(sih))
		return;

	switch (state) {
	case SI_DOATTACH:
		if (PCIEGEN1_ASPM(sih))
			pcie_clkreq((void *)pi, 1, 0);
		break;
	case SI_PCIDOWN:
		if (sih->buscorerev == 6) {	/* turn on serdes PLL down */
			si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, chipcontrol_addr),
			           ~0, 0);
			si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, chipcontrol_data),
			           ~0x40, 0);
		} else if (pi->pcie_pr42767) {
			pcie_clkreq((void *)pi, 1, 1);
		}
		break;
	case SI_PCIUP:
		if (sih->buscorerev == 6) {	/* turn off serdes PLL down */
			si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, chipcontrol_addr),
			           ~0, 0);
			si_corereg(sih, SI_CC_IDX, OFFSETOF(chipcregs_t, chipcontrol_data),
			           ~0x40, 0x40);
		} else if (PCIEGEN1_ASPM(sih)) {		/* disable clkreq */
			pcie_clkreq((void *)pi, 1, 0);
		}
		break;
	default:
		ASSERT(0);
		break;
	}
}
Example #17
0
uint32
pcicore_pciereg(void *pch, uint32 offset, uint32 mask, uint32 val, uint type)
{
	uint32 reg_val = 0;
	pcicore_info_t *pi = (pcicore_info_t *)pch;
	sbpcieregs_t *pcieregs = pi->regs.pcieregs;

	if (mask) {
		PCI_ERROR(("PCIEREG: 0x%x writeval  0x%x\n", offset, val));
		pcie_writereg(pi->sih, pcieregs, type, offset, val);
	}

	/* Should not read register 0x154 */
	if (PCIE_GEN1(pi->sih) &&
		pi->sih->buscorerev <= 5 && offset == PCIE_DLLP_PCIE11 && type == PCIE_PCIEREGS)
		return reg_val;

	reg_val = pcie_readreg(pi->sih, pcieregs, type, offset);
	PCI_ERROR(("PCIEREG: 0x%x readval is 0x%x\n", offset, reg_val));

	return reg_val;
}
Example #18
0
uint32
pcieltrhysteresiscnt_reg(void *pch, uint32 mask, uint32 val)
{
	pcicore_info_t *pi = (pcicore_info_t *)pch;
	si_t *sih = pi->sih;
	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
	uint32 retval;

	if (PCIE_GEN1(sih))
		return 0;

	ASSERT(pcieregs != NULL);

	if (mask) { /* set operation */
		retval = val;
		W_REG(pi->osh, &(pcieregs->ltrhysteresiscnt), val);
	}
	else { /* get operation */
		retval = R_REG(pi->osh, &(pcieregs->ltrhysteresiscnt));
	}

	return retval;
}
Example #19
0
/* When the device is going to enter D3 state (or the system is going to enter S3/S4 states */
void
pcicore_sleep(void *pch)
{
	pcicore_info_t *pi = (pcicore_info_t *)pch;
	uint32 w;

	if (!pi || !PCIE_GEN1(pi->sih))
		return;

	pcie_power_save_upd(pi, FALSE);


	if (!PCIEGEN1_ASPM(pi->sih))
		return;


	w = OSL_PCI_READ_CONFIG(pi->osh, pi->pciecap_lcreg_offset, sizeof(uint32));
	w &= ~PCIE_CAP_LCREG_ASPML1;
	OSL_PCI_WRITE_CONFIG(pi->osh, pi->pciecap_lcreg_offset, sizeof(uint32), w);


	pi->pcie_pr42767 = FALSE;
}
Example #20
0
/* Dump PCIE PLP/DLLP/TLP  diagnostic registers */
int
pcicore_dump_pcieregs(void *pch, struct bcmstrbuf *b)
{
	pcicore_info_t *pi = (pcicore_info_t *)pch;
	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
	si_t *sih = pi->sih;
	uint reg_val = 0;
	char *bitfield_dump_buf;

	if (!PCIE_GEN1(pi->sih))
		return BCME_ERROR;

	if (!(bitfield_dump_buf = MALLOC(pi->osh, BITFIELD_DUMP_SIZE))) {
		printf("bitfield dump allocation failed\n");
		return BCME_NOMEM;
	}

	bcm_bprintf(b, "PLPRegs \t");
	bcmdumpfields(si_pcie_readreg, (void *)(uintptr)pi->sih, PCIE_PCIEREGS,
		(struct fielddesc *)(uintptr)pcie_plp_regdesc,
		bitfield_dump_buf, BITFIELD_DUMP_SIZE);
	bcm_bprintf(b, "%s", bitfield_dump_buf);
	bzero(bitfield_dump_buf, BITFIELD_DUMP_SIZE);
	bcm_bprintf(b, "\n");
	bcm_bprintf(b, "DLLPRegs \t");
	bcmdumpfields(si_pcie_readreg, (void *)(uintptr)pi->sih, PCIE_PCIEREGS,
		(struct fielddesc *)(uintptr)pcie_dllp_regdesc,
		bitfield_dump_buf, BITFIELD_DUMP_SIZE);
	bcm_bprintf(b, "%s", bitfield_dump_buf);
	bzero(bitfield_dump_buf, BITFIELD_DUMP_SIZE);
	bcm_bprintf(b, "\n");
	bcm_bprintf(b, "TLPRegs \t");
	bcmdumpfields(si_pcie_readreg, (void *)(uintptr)pi->sih, PCIE_PCIEREGS,
		(struct fielddesc *)(uintptr)pcie_tlp_regdesc,
		bitfield_dump_buf, BITFIELD_DUMP_SIZE);
	bcm_bprintf(b, "%s", bitfield_dump_buf);
	bzero(bitfield_dump_buf, BITFIELD_DUMP_SIZE);
	bcm_bprintf(b, "\n");

	/* enable mdio access to SERDES */
	W_REG(pi->osh, (&pcieregs->u.pcie1.mdiocontrol), MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);

	bcm_bprintf(b, "SERDES regs \n");
	if (sih->buscorerev >= 10) {
		pcie_mdioread(pi, MDIO_DEV_IEEE0, 0x2, &reg_val);
		bcm_bprintf(b, "block IEEE0, offset 2: 0x%x\n", reg_val);
		pcie_mdioread(pi, MDIO_DEV_IEEE0, 0x3, &reg_val);
		bcm_bprintf(b, "block IEEE0, offset 2: 0x%x\n", reg_val);
		pcie_mdioread(pi, MDIO_DEV_IEEE1, 0x08, &reg_val);
		bcm_bprintf(b, "block IEEE1, lanestatus: 0x%x\n", reg_val);
		pcie_mdioread(pi, MDIO_DEV_IEEE1, 0x0a, &reg_val);
		bcm_bprintf(b, "block IEEE1, lanestatus2: 0x%x\n", reg_val);
		pcie_mdioread(pi, MDIO_DEV_BLK4, 0x16, &reg_val);
		bcm_bprintf(b, "MDIO_DEV_BLK4, lanetest0: 0x%x\n", reg_val);
		pcie_mdioread(pi, MDIO_DEV_TXPLL, 0x11, &reg_val);
		bcm_bprintf(b, "MDIO_DEV_TXPLL, pllcontrol: 0x%x\n", reg_val);
		pcie_mdioread(pi, MDIO_DEV_TXPLL, 0x12, &reg_val);
		bcm_bprintf(b, "MDIO_DEV_TXPLL, plltimer1: 0x%x\n", reg_val);
		pcie_mdioread(pi, MDIO_DEV_TXPLL, 0x13, &reg_val);
		bcm_bprintf(b, "MDIO_DEV_TXPLL, plltimer2: 0x%x\n", reg_val);
		pcie_mdioread(pi, MDIO_DEV_TXPLL, 0x14, &reg_val);
		bcm_bprintf(b, "MDIO_DEV_TXPLL, plltimer3: 0x%x\n", reg_val);
		pcie_mdioread(pi, MDIO_DEV_TXPLL, 0x17, &reg_val);
		bcm_bprintf(b, "MDIO_DEV_TXPLL, freqdetcounter: 0x%x\n", reg_val);
	} else {
		pcie_mdioread(pi, MDIODATA_DEV_RX, SERDES_RX_TIMER1, &reg_val);
		bcm_bprintf(b, "rxtimer1 0x%x ", reg_val);
		pcie_mdioread(pi, MDIODATA_DEV_RX, SERDES_RX_CDR, &reg_val);
		bcm_bprintf(b, "rxCDR 0x%x ", reg_val);
		pcie_mdioread(pi, MDIODATA_DEV_RX, SERDES_RX_CDRBW, &reg_val);
		bcm_bprintf(b, "rxCDRBW 0x%x\n", reg_val);
	}

	/* disable mdio access to SERDES */
	W_REG(pi->osh, (&pcieregs->u.pcie1.mdiocontrol), 0);

	MFREE(pi->osh, bitfield_dump_buf, BITFIELD_DUMP_SIZE);

	return 0;
}