Ejemplo n.º 1
0
static void
chipdisablepme(struct bcm4xxx *ch)
{
	bcmenetregs_t *regs;

	regs = ch->regs;

	AND_REG(ch->osh, &regs->devcontrol, ~DC_PM);
	si_core_cflags(ch->sih, SICF_PME_EN, 0);
}
Ejemplo n.º 2
0
static bool
_dma32_addrext(osl_t *osh, dma32regs_t *dma32regs)
{
	uint32 w;

	OR_REG(osh, &dma32regs->control, XC_AE);
	w = R_REG(osh, &dma32regs->control);
	AND_REG(osh, &dma32regs->control, ~XC_AE);
	return ((w & XC_AE) == XC_AE);
}
Ejemplo n.º 3
0
static void
chipduplexupd(struct bcm4xxx *ch)
{
	uint32 txcontrol;

	txcontrol = R_REG(ch->osh, &ch->regs->txcontrol);
	if (ch->etc->duplex && !(txcontrol & EXC_FD))
		OR_REG(ch->osh, &ch->regs->txcontrol, EXC_FD);
	else if (!ch->etc->duplex && (txcontrol & EXC_FD))
		AND_REG(ch->osh, &ch->regs->txcontrol, ~EXC_FD);
}
Ejemplo n.º 4
0
/* initialize PMU */
void si_pmu_init(struct si_pub *sih)
{
	chipcregs_t *cc;
	uint origidx;

	/* Remember original core before switch to chipc */
	origidx = ai_coreidx(sih);
	cc = ai_setcoreidx(sih, SI_CC_IDX);

	if (sih->pmurev == 1)
		AND_REG(&cc->pmucontrol, ~PCTL_NOILP_ON_WAIT);
	else if (sih->pmurev >= 2)
		OR_REG(&cc->pmucontrol, PCTL_NOILP_ON_WAIT);

	/* Return to original core */
	ai_setcoreidx(sih, origidx);
}
Ejemplo n.º 5
0
int
sflash_write(si_t *sih, chipcregs_t *cc, uint offset, uint length, const uchar *buffer)
{
	struct sflash *sfl;
	uint off = offset, len = length;
	const uint8 *buf = buffer;
	uint8 data;
	int ret = 0, ntry = 0;
	bool is4712b0;
	uint32 page, byte, mask;
	osl_t *osh;

	ASSERT(sih);

	osh = si_osh(sih);

	if (!len)
		return 0;

	sfl = &sflash;
	if ((off + len) > sfl->size)
		return -22;

	switch (sfl->type) {
	case SFLASH_ST:
		is4712b0 = (CHIPID(sih->chip) == BCM4712_CHIP_ID) && (CHIPREV(sih->chiprev) == 3);
		/* Enable writes */
retry:		sflash_cmd(osh, cc, SFLASH_ST_WREN);
		off = offset;
		len = length;
		buf = buffer;
		ntry++;
		if (is4712b0) {
			mask = 1 << 14;
			W_REG(osh, &cc->flashaddress, off);
			data = GET_BYTE(buf);
			buf++;
			W_REG(osh, &cc->flashdata, data);
			/* Set chip select */
			OR_REG(osh, &cc->gpioout, mask);
			/* Issue a page program with the first byte */
			sflash_cmd(osh, cc, SFLASH_ST_PP);
			ret = 1;
			off++;
			len--;
			while (len > 0) {
				if ((off & 255) == 0) {
					/* Page boundary, drop cs and return */
					AND_REG(osh, &cc->gpioout, ~mask);
					OSL_DELAY(1);
					if (!sflash_poll(sih, cc, off)) {
						/* Flash rejected command */
						if (ntry <= ST_RETRIES)
							goto retry;
						else
							return -11;
					}
					return ret;
				} else {
					/* Write single byte */
					data = GET_BYTE(buf);
					buf++;
					sflash_cmd(osh, cc, data);
				}
				ret++;
				off++;
				len--;
			}
			/* All done, drop cs */
			AND_REG(osh, &cc->gpioout, ~mask);
			OSL_DELAY(1);
			if (!sflash_poll(sih, cc, off)) {
				/* Flash rejected command */
				if (ntry <= ST_RETRIES)
					goto retry;
				else
					return -12;
			}
		} else if (sih->ccrev >= 20) {
			W_REG(osh, &cc->flashaddress, off);
			data = GET_BYTE(buf);
			buf++;
			W_REG(osh, &cc->flashdata, data);
			/* Issue a page program with CSA bit set */
			sflash_cmd(osh, cc, SFLASH_ST_CSA | SFLASH_ST_PP);
			ret = 1;
			off++;
			len--;
			while (len > 0) {
				if ((off & 255) == 0) {
					/* Page boundary, poll droping cs and return */
					W_REG(NULL, &cc->flashcontrol, 0);
					OSL_DELAY(1);
					if (sflash_poll(sih, cc, off) == 0) {
						/* Flash rejected command */
						SFL_MSG(("sflash: pp rejected, ntry: %d,"
						         " off: %d/%d, len: %d/%d, ret:"
						         "%d\n", ntry, off, offset, len,
						         length, ret));
						if (ntry <= ST_RETRIES)
							goto retry;
						else
							return -11;
					}
					return ret;
				} else {
					/* Write single byte */
					data = GET_BYTE(buf);
					buf++;
					sflash_cmd(osh, cc, SFLASH_ST_CSA | data);
				}
				ret++;
				off++;
				len--;
			}
			/* All done, drop cs & poll */
			W_REG(NULL, &cc->flashcontrol, 0);
			OSL_DELAY(1);
			if (sflash_poll(sih, cc, off) == 0) {
				/* Flash rejected command */
				SFL_MSG(("sflash: pp rejected, ntry: %d, off: %d/%d,"
				         " len: %d/%d, ret: %d\n",
				         ntry, off, offset, len, length, ret));
				if (ntry <= ST_RETRIES)
					goto retry;
				else
					return -12;
			}
		} else {
			ret = 1;
			W_REG(osh, &cc->flashaddress, off);
			data = GET_BYTE(buf);
			buf++;
			W_REG(osh, &cc->flashdata, data);
			/* Page program */
			sflash_cmd(osh, cc, SFLASH_ST_PP);
		}
		break;
	case SFLASH_AT:
		mask = sfl->blocksize - 1;
		page = (off & ~mask) << 1;
		byte = off & mask;
		/* Read main memory page into buffer 1 */
		if (byte || (len < sfl->blocksize)) {
			W_REG(osh, &cc->flashaddress, page);
			sflash_cmd(osh, cc, SFLASH_AT_BUF1_LOAD);
			/* 250 us for AT45DB321B */
			SPINWAIT(sflash_poll(sih, cc, off), 1000);
			ASSERT(!sflash_poll(sih, cc, off));
		}
		/* Write into buffer 1 */
		for (ret = 0; (ret < (int)len) && (byte < sfl->blocksize); ret++) {
			W_REG(osh, &cc->flashaddress, byte++);
			W_REG(osh, &cc->flashdata, *buf++);
			sflash_cmd(osh, cc, SFLASH_AT_BUF1_WRITE);
		}
		/* Write buffer 1 into main memory page */
		W_REG(osh, &cc->flashaddress, page);
		sflash_cmd(osh, cc, SFLASH_AT_BUF1_PROGRAM);
		break;
	}

	return ret;
}
Ejemplo n.º 6
0
/* Write len bytes starting at offset into buf. Returns number of bytes
 * written. Caller should poll for completion.
 */
int
sflash_write(chipcregs_t *cc, uint offset, uint len, const uchar *buf)
{
	struct sflash *sfl;
	int ret = 0;
	bool is4712b0;
	uint32 page, byte, mask;

	if (!len)
		return 0;

	if ((offset + len) > sflash.size)
		return -22;

	sfl = &sflash;
	switch (sfl->type) {
	case SFLASH_ST:
		mask = R_REG(NULL, &cc->chipid);
		is4712b0 = (((mask & CID_ID_MASK) == BCM4712_CHIP_ID) &&
		            ((mask & CID_REV_MASK) == (3 << CID_REV_SHIFT)));
		/* Enable writes */
		sflash_cmd(cc, SFLASH_ST_WREN);
		if (is4712b0) {
			mask = 1 << 14;
			W_REG(NULL, &cc->flashaddress, offset);
			W_REG(NULL, &cc->flashdata, *buf++);
			/* Set chip select */
			OR_REG(NULL, &cc->gpioout, mask);
			/* Issue a page program with the first byte */
			sflash_cmd(cc, SFLASH_ST_PP);
			ret = 1;
			offset++;
			len--;
			while (len > 0) {
				if ((offset & 255) == 0) {
					/* Page boundary, drop cs and return */
					AND_REG(NULL, &cc->gpioout, ~mask);
					if (!sflash_poll(cc, offset)) {
						/* Flash rejected command */
						return -11;
					}
					return ret;
				} else {
					/* Write single byte */
					sflash_cmd(cc, *buf++);
				}
				ret++;
				offset++;
				len--;
			}
			/* All done, drop cs if needed */
			if ((offset & 255) != 1) {
				/* Drop cs */
				AND_REG(NULL, &cc->gpioout, ~mask);
				if (!sflash_poll(cc, offset)) {
					/* Flash rejected command */
					return -12;
				}
			}
		} else {
			ret = 1;
			W_REG(NULL, &cc->flashaddress, offset);
			W_REG(NULL, &cc->flashdata, *buf);
		/* Page program */
		sflash_cmd(cc, SFLASH_ST_PP);
		}
		break;
	case SFLASH_AT:
		mask = sfl->blocksize - 1;
		page = (offset & ~mask) << 1;
		byte = offset & mask;
		/* Read main memory page into buffer 1 */
		if (byte || (len < sfl->blocksize)) {
			W_REG(NULL, &cc->flashaddress, page);
			sflash_cmd(cc, SFLASH_AT_BUF1_LOAD);
			/* 250 us for AT45DB321B */
			SPINWAIT(sflash_poll(cc, offset), 1000);
			ASSERT(!sflash_poll(cc, offset));
		}
		/* Write into buffer 1 */
		for (ret = 0; (ret < (int)len) && (byte < sfl->blocksize); ret++) {
			W_REG(NULL, &cc->flashaddress, byte++);
			W_REG(NULL, &cc->flashdata, *buf++);
			sflash_cmd(cc, SFLASH_AT_BUF1_WRITE);
		}
		/* Write buffer 1 into main memory page */
		W_REG(NULL, &cc->flashaddress, page);
		sflash_cmd(cc, SFLASH_AT_BUF1_PROGRAM);
		break;
	}

	return ret;
}
Ejemplo n.º 7
0
/*
 * Initializes UART access. The callback function will be called once
 * per found UART.
 */
void
BCMATTACHFN(si_serial_init)(si_t *sih, si_serial_init_fn add)
{
	osl_t *osh;
	void *regs;
	chipcregs_t *cc;
	uint32 rev, cap, pll, baud_base, div;
	uint irq;
	int i, n;

	osh = si_osh(sih);

	cc = (chipcregs_t *)si_setcoreidx(sih, SI_CC_IDX);
	ASSERT(cc);

	/* Determine core revision and capabilities */
	rev = sih->ccrev;
	cap = sih->cccaps;
	pll = cap & CC_CAP_PLL_MASK;

	/* Determine IRQ */
	irq = si_irq(sih);

	if (CCPLL_ENAB(sih) && pll == PLL_TYPE1) {
		/* PLL clock */
		baud_base = si_clock_rate(pll,
		                          R_REG(osh, &cc->clockcontrol_n),
		                          R_REG(osh, &cc->clockcontrol_m2));
		div = 1;
	} else {
		/* Fixed ALP clock */
		if (rev >= 11 && rev != 15) {
			baud_base = si_alp_clock(sih);
			div = 1;
			/* Turn off UART clock before switching clock source */
			if (rev >= 21)
				AND_REG(osh, &cc->corecontrol, ~CC_UARTCLKEN);
			/* Set the override bit so we don't divide it */
			OR_REG(osh, &cc->corecontrol, CC_UARTCLKO);
			if (rev >= 21)
				OR_REG(osh, &cc->corecontrol, CC_UARTCLKEN);
		} else if (rev >= 3) {
			/* Internal backplane clock */
			baud_base = si_clock(sih);
			div = 2;	/* Minimum divisor */
			W_REG(osh, &cc->clkdiv,
			      ((R_REG(osh, &cc->clkdiv) & ~CLKD_UART) | div));
		} else {
			/* Fixed internal backplane clock */
			baud_base = 88000000;
			div = 48;
		}

		/* Clock source depends on strapping if UartClkOverride is unset */
		if ((R_REG(osh, &cc->corecontrol) & CC_UARTCLKO) == 0) {
			if ((cap & CC_CAP_UCLKSEL) == CC_CAP_UINTCLK) {
				/* Internal divided backplane clock */
				baud_base /= div;
			} else {
				/* Assume external clock of 1.8432 MHz */
				baud_base = 1843200;
			}
		}
	}

	/* Add internal UARTs */
	n = cap & CC_CAP_UARTS_MASK;
	for (i = 0; i < n; i++) {
		regs = (void *)((ulong) &cc->uart0data + (i * 256));
		if (add)
			add(regs, irq, baud_base, 0);
	}
}
Ejemplo n.º 8
0
/*
 * Initializes UART access. The callback function will be called once
 * per found UART.
 */
void BCMINITFN(sb_serial_init) (sb_t * sbh, sb_serial_init_fn add) {
	osl_t *osh;
	void *regs;
	chipcregs_t *cc;
	uint32 rev, cap, pll, baud_base, div;
	uint irq;
	int i, n;

	osh = sb_osh(sbh);

	regs = sb_setcore(sbh, SB_EXTIF, 0);
	if (regs) {
		sb_extif_serial_init(sbh, regs, add);
		return;
	}

	cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0);
	ASSERT(cc);

	/* Determine core revision and capabilities */
	rev = sbh->ccrev;
	cap = sbh->cccaps;
	pll = cap & CC_CAP_PLL_MASK;

	/* Determine IRQ */
	irq = sb_irq(sbh);

	if (pll == PLL_TYPE1) {
		/* PLL clock */
		baud_base = sb_clock_rate(pll,
					  R_REG(osh, &cc->clockcontrol_n),
					  R_REG(osh, &cc->clockcontrol_m2));
		div = 1;
	} else {
		/* 5354 chip common uart uses a constant clock
		 * frequency of 25MHz */
		if (sb_corerev(sbh) == 20) {
			/* Set the override bit so we don't divide it */
			W_REG(osh, &cc->corecontrol, CC_UARTCLKO);
			baud_base = 25000000;
		} else if (rev >= 11 && rev != 15) {
			/* Fixed ALP clock */
			baud_base = sb_alp_clock(sbh);
			div = 1;
			/* Turn off UART clock before switching clock source */
			if (rev >= 21)
				AND_REG(osh, &cc->corecontrol, ~CC_UARTCLKEN);
			/* Set the override bit so we don't divide it */
			OR_REG(osh, &cc->corecontrol, CC_UARTCLKO);
			if (rev >= 21)
				OR_REG(osh, &cc->corecontrol, CC_UARTCLKEN);
		} else if (rev >= 3) {
			/* Internal backplane clock */
			baud_base = sb_clock(sbh);
			div = 2;	/* Minimum divisor */
			W_REG(osh, &cc->clkdiv,
			      ((R_REG(osh, &cc->clkdiv) & ~CLKD_UART) | div));
		} else {
			/* Fixed internal backplane clock */
			baud_base = 88000000;
			div = 48;
		}

		/* Clock source depends on strapping if UartClkOverride is unset */
		if ((rev > 0)
		    && ((R_REG(osh, &cc->corecontrol) & CC_UARTCLKO) == 0)) {
			if ((cap & CC_CAP_UCLKSEL) == CC_CAP_UINTCLK) {
				/* Internal divided backplane clock */
				baud_base /= div;
			} else {
				/* Assume external clock of 1.8432 MHz */
				baud_base = 1843200;
			}
		}
	}

	/* Add internal UARTs */
	n = cap & CC_CAP_UARTS_MASK;
	for (i = 0; i < n; i++) {
		/* Register offset changed after revision 0 */
		if (rev)
			regs = (void *)((ulong) & cc->uart0data + (i * 256));
		else
			regs = (void *)((ulong) & cc->uart0data + (i * 8));

		if (add)
			add(regs, irq, baud_base, 0);
	}
}
Ejemplo n.º 9
0
/*
 * Initializes UART access. The callback function will be called once
 * per found UART.
 */
void
BCMINITFN(si_serial_init)(si_t *sih, si_serial_init_fn add, uint32 baudrate)
{
    osl_t *osh;
    void *regs;
    chipcregs_t *cc;
    uint32 rev, cap, pll, baud_base, div;
    uint irq;
    int i, n;

    osh = si_osh(sih);

    cc = (chipcregs_t *)si_setcoreidx(sih, SI_CC_IDX);
    ASSERT(cc);

    /* Determine core revision and capabilities */
    rev = sih->ccrev;
    cap = sih->cccaps;
    pll = cap & CC_CAP_PLL_MASK;

    /* Determine IRQ */
    irq = si_irq(sih);

    if (CCPLL_ENAB(sih) && pll == PLL_TYPE1) {
        /* PLL clock */
        baud_base = si_clock_rate(pll,
                                  R_REG(osh, &cc->clockcontrol_n),
                                  R_REG(osh, &cc->clockcontrol_m2));
        div = 1;
    } else {
        /* Fixed ALP clock */
        /* XXX rev. 15 in 4785 breaks the rule! */
        if (rev >= 11 && rev != 15) {
            baud_base = si_alp_clock(sih);
            div = 1;
            
            /*
             * If baudrate parameter is given with a non-zero value,
             * UART clock will be divided for the given baud rate before 
             * feeding into UART module.
             * Note: UART driver could also adjust UART module's divider for 
             *       clock fine tunning.
             */
            if (baudrate) {
                /* Turn off UART clock before switching clock source */
                if (rev >= 21)
                    AND_REG(osh, &cc->corecontrol, ~CC_UARTCLKEN);

                /* Don't set the override bit so we divide it */
                AND_REG(osh, &cc->corecontrol, ~CC_UARTCLKO);

                div = baud_base / (baudrate * 16); 
                div = (div + 1) & ~0x1;
                AND_REG(osh, &cc->clkdiv, ~CLKD_UART);
                OR_REG(osh, &cc->clkdiv, div);

                /* Turn back UART clock on */
                if (rev >= 21)
                    OR_REG(osh, &cc->corecontrol, CC_UARTCLKEN);
            } else {

                /* Turn off UART clock before switching clock source */
                if (rev >= 21)
                    AND_REG(osh, &cc->corecontrol, ~CC_UARTCLKEN);

                OR_REG(osh, &cc->corecontrol, CC_UARTCLKO);

                /* Turn back UART clock on */
                if (rev >= 21)
                    OR_REG(osh, &cc->corecontrol, CC_UARTCLKEN);
            }

            if (CONSOLE_TTY == 1) {
                /* Use UART1, enable "UART1 use GPIO" bit */
                OR_REG(osh, &cc->corecontrol, 0x80);
            }

        } else if (rev >= 3) {
            /* Internal backplane clock */
            baud_base = si_clock(sih);
            div = 2;    /* Minimum divisor */
            W_REG(osh, &cc->clkdiv,
                  ((R_REG(osh, &cc->clkdiv) & ~CLKD_UART) | div));
        } else {
            /* Fixed internal backplane clock */
            baud_base = 88000000;
            div = 48;
        }

        /* Clock source depends on strapping if UartClkOverride is unset */
        if ((rev > 0) &&
            ((R_REG(osh, &cc->corecontrol) & CC_UARTCLKO) == 0)) {
            if ((cap & CC_CAP_UCLKSEL) == CC_CAP_UINTCLK) {
                /* Internal divided backplane clock */
                baud_base /= div;
            } else {
                /* Assume external clock of 1.8432 MHz */
                baud_base = 1843200;
            }
        }
    }

    /* Add internal UARTs */
    n = cap & CC_CAP_UARTS_MASK;
    for (i = 0; i < n; i++) {
        /* Register offset changed after revision 0 */
        if (rev)
            regs = (void *)((ulong) &cc->uart0data + (i * 256));
        else
            regs = (void *)((ulong) &cc->uart0data + (i * 8));

        if (add)
            add(regs, irq, baud_base, 0);
    }
}
Ejemplo n.º 10
0
Archivo: hnddma.c Proyecto: ariavie/bcm
void
dma_txresume(dma_info_t *di)
{
	DMA_TRACE(("%s: dma_txresume\n", di->name));
	AND_REG(&di->regs->xmtcontrol, ~XC_SE);
}
Ejemplo n.º 11
0
static void
chipreset(struct bcm4xxx *ch)
{
	bcmenetregs_t *regs;
	uint32 clk, mdc;

	ET_TRACE(("et%d: chipreset\n", ch->etc->unit));

	regs = ch->regs;

	if (!si_iscoreup(ch->sih)) {
		if (!ch->etc->nicmode)
			si_pci_setup(ch->sih, (1 << si_coreidx(ch->sih)));
		/* power on reset: reset the enet core */
		si_core_reset(ch->sih, 0, 0);
		goto chipinreset;
	}

	/* read counters before resetting the chip */
	if (ch->mibgood)
		chipstatsupd(ch);

	/* reset the tx dma engine */
	if (ch->di)
		dma_txreset(ch->di);

	/* set emac into loopback mode to ensure no rx traffic */
	W_REG(ch->osh, &regs->rxconfig, ERC_LE);
	OSL_DELAY(1);

	/* reset the rx dma engine */
	if (ch->di)
		dma_rxreset(ch->di);

	/* reset core */
	si_core_reset(ch->sih, 0, 0);

chipinreset:

	/* must clear mib registers by hand */
	W_REG(ch->osh, &regs->mibcontrol, EMC_RZ);
	(void) R_REG(ch->osh, &regs->mib.tx_broadcast_pkts);
	(void) R_REG(ch->osh, &regs->mib.tx_multicast_pkts);
	(void) R_REG(ch->osh, &regs->mib.tx_len_64);
	(void) R_REG(ch->osh, &regs->mib.tx_len_65_to_127);
	(void) R_REG(ch->osh, &regs->mib.tx_len_128_to_255);
	(void) R_REG(ch->osh, &regs->mib.tx_len_256_to_511);
	(void) R_REG(ch->osh, &regs->mib.tx_len_512_to_1023);
	(void) R_REG(ch->osh, &regs->mib.tx_len_1024_to_max);
	(void) R_REG(ch->osh, &regs->mib.tx_jabber_pkts);
	(void) R_REG(ch->osh, &regs->mib.tx_oversize_pkts);
	(void) R_REG(ch->osh, &regs->mib.tx_fragment_pkts);
	(void) R_REG(ch->osh, &regs->mib.tx_underruns);
	(void) R_REG(ch->osh, &regs->mib.tx_total_cols);
	(void) R_REG(ch->osh, &regs->mib.tx_single_cols);
	(void) R_REG(ch->osh, &regs->mib.tx_multiple_cols);
	(void) R_REG(ch->osh, &regs->mib.tx_excessive_cols);
	(void) R_REG(ch->osh, &regs->mib.tx_late_cols);
	(void) R_REG(ch->osh, &regs->mib.tx_defered);
	(void) R_REG(ch->osh, &regs->mib.tx_carrier_lost);
	(void) R_REG(ch->osh, &regs->mib.tx_pause_pkts);
	(void) R_REG(ch->osh, &regs->mib.rx_broadcast_pkts);
	(void) R_REG(ch->osh, &regs->mib.rx_multicast_pkts);
	(void) R_REG(ch->osh, &regs->mib.rx_len_64);
	(void) R_REG(ch->osh, &regs->mib.rx_len_65_to_127);
	(void) R_REG(ch->osh, &regs->mib.rx_len_128_to_255);
	(void) R_REG(ch->osh, &regs->mib.rx_len_256_to_511);
	(void) R_REG(ch->osh, &regs->mib.rx_len_512_to_1023);
	(void) R_REG(ch->osh, &regs->mib.rx_len_1024_to_max);
	(void) R_REG(ch->osh, &regs->mib.rx_jabber_pkts);
	(void) R_REG(ch->osh, &regs->mib.rx_oversize_pkts);
	(void) R_REG(ch->osh, &regs->mib.rx_fragment_pkts);
	(void) R_REG(ch->osh, &regs->mib.rx_missed_pkts);
	(void) R_REG(ch->osh, &regs->mib.rx_crc_align_errs);
	(void) R_REG(ch->osh, &regs->mib.rx_undersize);
	(void) R_REG(ch->osh, &regs->mib.rx_crc_errs);
	(void) R_REG(ch->osh, &regs->mib.rx_align_errs);
	(void) R_REG(ch->osh, &regs->mib.rx_symbol_errs);
	(void) R_REG(ch->osh, &regs->mib.rx_pause_pkts);
	(void) R_REG(ch->osh, &regs->mib.rx_nonpause_pkts);
	ch->mibgood = TRUE;

	/*
	 * We want the phy registers to be accessible even when
	 * the driver is "downed" so initialize MDC preamble, frequency,
	 * and whether internal or external phy here.
	 */
	/* default:  100Mhz SI clock and external phy */
	W_REG(ch->osh, &regs->mdiocontrol, 0x94);
	if (ch->etc->deviceid == BCM47XX_ENET_ID) {
		/* 47xx chips: find out the clock */
		if ((clk = si_clock(ch->sih)) != 0) {
			mdc = 0x80 | ((clk + (MDC_RATIO / 2)) / MDC_RATIO);
			W_REG(ch->osh, &regs->mdiocontrol, mdc);
		} else {
			ET_ERROR(("et%d: chipreset: Could not figure out backplane clock, "
			          "using 100Mhz\n",
			          ch->etc->unit));
		}
	}

	/* some chips have internal phy, some don't */
	if (!(R_REG(ch->osh, &regs->devcontrol) & DC_IP)) {
		W_REG(ch->osh, &regs->enetcontrol, EC_EP);
	} else if (R_REG(ch->osh, &regs->devcontrol) & DC_ER) {
		AND_REG(ch->osh, &regs->devcontrol, ~DC_ER);
		OSL_DELAY(100);
		chipphyinit(ch, ch->etc->phyaddr);
	}

	/* clear persistent sw intstatus */
	ch->intstatus = 0;
}