コード例 #1
0
ファイル: nicpci.c プロジェクト: 0xroot/Blackphone-BP1-Kernel
static int
pcie_mdioop(struct pcicore_info *pi, uint physmedia, uint regaddr, bool write,
	    uint *val)
{
	uint mdiodata;
	uint i = 0;
	uint pcie_serdes_spinwait = 10;

	/* enable mdio access to SERDES */
	bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol),
		     MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);

	if (ai_get_buscorerev(pi->sih) >= 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);

	bcma_write32(pi->core, PCIEREGOFFS(mdiodata), mdiodata);

	pr28829_delay();

	/* retry till the transaction is complete */
	while (i < pcie_serdes_spinwait) {
		if (bcma_read32(pi->core, PCIEREGOFFS(mdiocontrol)) &
		    MDIOCTL_ACCESS_DONE) {
			if (!write) {
				pr28829_delay();
				*val = (bcma_read32(pi->core,
						    PCIEREGOFFS(mdiodata)) &
					MDIODATA_MASK);
			}
			/* Disable mdio access to SERDES */
			bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol), 0);
			return 0;
		}
		udelay(1000);
		i++;
	}

	/* Timed out. Disable mdio access to SERDES. */
	bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol), 0);
	return 1;
}
コード例 #2
0
ファイル: nicpci.c プロジェクト: 3sOx/asuswrt-merlin
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;
}
コード例 #3
0
static int
pcie_mdioop(struct pcicore_info *pi, uint physmedia, uint regaddr, bool write,
            uint *val)
{
    uint mdiodata;
    uint i = 0;
    uint pcie_serdes_spinwait = 10;


    bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol),
                 MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);

    if (ai_get_buscorerev(pi->sih) >= 10) {
        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);

    bcma_write32(pi->core, PCIEREGOFFS(mdiodata), mdiodata);

    pr28829_delay();


    while (i < pcie_serdes_spinwait) {
        if (bcma_read32(pi->core, PCIEREGOFFS(mdiocontrol)) &
                MDIOCTL_ACCESS_DONE) {
            if (!write) {
                pr28829_delay();
                *val = (bcma_read32(pi->core,
                                    PCIEREGOFFS(mdiodata)) &
                        MDIODATA_MASK);
            }

            bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol), 0);
            return 0;
        }
        udelay(1000);
        i++;
    }


    bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol), 0);
    return 1;
}