} if ((new_pcistate & ~BGE_PCISTATE_RESERVED) != (pcistate & ~BGE_PCISTATE_RESERVED)) { printf("%s: pcistate failed to revert\n", sc->bge_dev.dv_xname);
bge_reset(sc)	struct bge_softc *sc;{	struct pci_attach_args *pa = &sc->bge_pa;	u_int32_t cachesize, command, pcistate, reset;	int i, val = 0;	/* Save some important PCI state. */	cachesize = pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_CACHESZ);	command = pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_CMD);	pcistate = pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_PCISTATE);	pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_MISC_CTL,	    BGE_PCIMISCCTL_INDIRECT_ACCESS|BGE_PCIMISCCTL_MASK_PCI_INTR|	    BGE_PCIMISCCTL_ENDIAN_WORDSWAP|BGE_PCIMISCCTL_PCISTATE_RW);	reset = BGE_MISCCFG_RESET_CORE_CLOCKS|(65<<1);	/* XXX: Broadcom Linux driver. */	if (sc->bge_pcie) {		if (CSR_READ_4(sc, 0x7e2c) == 0x60)	/* PCIE 1.0 */			CSR_WRITE_4(sc, 0x7e2c, 0x20);		if (sc->bge_chipid != BGE_CHIPID_BCM5750_A0) {			/* Prevent PCIE link training during global reset */			CSR_WRITE_4(sc, BGE_MISC_CFG, (1<<29));			reset |= (1<<29);		}	}	/* Issue global reset */	bge_writereg_ind(sc, BGE_MISC_CFG, reset);	DELAY(1000);	/* XXX: Broadcom Linux driver. */	if (sc->bge_pcie) {		if (sc->bge_chipid == BGE_CHIPID_BCM5750_A0) {			uint32_t v;			DELAY(500000); /* wait for link training to complete */			v = pci_conf_read(pa->pa_pc, pa->pa_tag, 0xc4);			pci_conf_write(pa->pa_pc, pa->pa_tag, 0xc4, v | (1<<15));		}		/* Set PCIE max payload size and clear error status. */		pci_conf_write(pa->pa_pc, pa->pa_tag, 0xd8, 0xf5000);	}	/* Reset some of the PCI state that got zapped by reset */	pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_MISC_CTL,	    BGE_PCIMISCCTL_INDIRECT_ACCESS|BGE_PCIMISCCTL_MASK_PCI_INTR|	    BGE_PCIMISCCTL_ENDIAN_WORDSWAP|BGE_PCIMISCCTL_PCISTATE_RW);	pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_CACHESZ, cachesize);	pci_conf_write(pa->pa_pc, pa->pa_tag, BGE_PCI_CMD, command);	bge_writereg_ind(sc, BGE_MISC_CFG, (65 << 1));	/* Enable memory arbiter. */	if ((sc->bge_quirks & BGE_QUIRK_5705_CORE) == 0)		CSR_WRITE_4(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE);	/*	 * Prevent PXE restart: write a magic number to the	 * general communications memory at 0xB50.	 */	bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER);	/*	 * Poll the value location we just wrote until	 * we see the 1's complement of the magic number.	 * This indicates that the firmware initialization	 * is complete.	 */	for (i = 0; i < BGE_TIMEOUT; i++) {		val = bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM);		if (val == ~BGE_MAGIC_NUMBER)			break;		DELAY(10);	}	if (i == BGE_TIMEOUT) {		printf("%s: firmware handshake timed out\n",		    sc->bge_dev.dv_xname);		return;	}	/*	 * XXX Wait for the value of the PCISTATE register to	 * return to its original pre-reset state. This is a	 * fairly good indicator of reset completion. If we don't	 * wait for the reset to fully complete, trying to read	 * from the device's non-PCI registers may yield garbage	 * results.	 */	for (i = 0; i < BGE_TIMEOUT; i++) {		if (pci_conf_read(pa->pa_pc, pa->pa_tag, BGE_PCI_PCISTATE) ==		    pcistate)			break;		DELAY(10);	}	/* Fix up byte swapping */	CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_MODECTL_BYTESWAP_NONFRAME|	    BGE_MODECTL_BYTESWAP_DATA);	CSR_WRITE_4(sc, BGE_MAC_MODE, 0);	/*	 * The 5704 in TBI mode apparently needs some special	 * adjustment to insure the SERDES drive level is set	 * to 1.2V.	 */	if (BGE_ASICREV(sc->bge_chipid) == BGE_ASICREV_BCM5704 && sc->bge_tbi) {		uint32_t serdescfg;		serdescfg = CSR_READ_4(sc, BGE_SERDES_CFG);		serdescfg = (serdescfg & ~0xFFF) | 0x880;		CSR_WRITE_4(sc, BGE_SERDES_CFG, serdescfg);	}	/* XXX: Broadcom Linux driver. */	if (sc->bge_pcie && sc->bge_chipid != BGE_CHIPID_BCM5750_A0) {		uint32_t v;		v = CSR_READ_4(sc, 0x7c00);		CSR_WRITE_4(sc, 0x7c00, v | (1<<25));	}	DELAY(10000);}