I'd like to commit my final bge version of the IPMI patch to keep IPMI working when FreeBSD attaches and also when the NIC is downed. I also have patches for the bce to do the same that I sent to David. This has various reviews and testing in the wild. I want to give a heads up since there have been changes in the bge driver recently. I'd like to not hold off on this anymore. Thanks, Doug A. Index: if_bge.c =================================================================== RCS file: /cvs/src/sys/dev/bge/if_bge.c,v retrieving revision 1.140 diff -u -p -r1.140 if_bge.c --- if_bge.c 24 Aug 2006 14:41:16 -0000 1.140 +++ if_bge.c 7 Sep 2006 18:31:59 -0000 _at__at_ -326,6 +326,7 _at__at_ static void bge_dma_free(struct bge_soft static void bge_txeof(struct bge_softc *); static void bge_rxeof(struct bge_softc *); +static void bge_asf_driver_up (struct bge_softc *); static void bge_tick_locked(struct bge_softc *); static void bge_tick(void *); static void bge_stats_update(struct bge_softc *); _at__at_ -376,7 +377,12 _at__at_ static void bge_miibus_statchg(device_t) static void bge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count); #endif -static void bge_reset(struct bge_softc *); +#define BGE_RESET_START 1 +#define BGE_RESET_STOP 2 +static void bge_sig_post_reset(struct bge_softc *, int); +static void bge_sig_legacy(struct bge_softc *, int); +static void bge_sig_pre_reset(struct bge_softc *, int); +static int bge_reset(struct bge_softc *); static void bge_link_upd(struct bge_softc *); static device_method_t bge_methods[] = { _at__at_ -646,7 +652,6 _at__at_ bge_miibus_statchg(device_t dev) { struct bge_softc *sc; struct mii_data *mii; - sc = device_get_softc(dev); mii = device_get_softc(sc->bge_miibus); _at__at_ -968,6 +973,81 _at__at_ bge_setmulti(struct bge_softc *sc) CSR_WRITE_4(sc, BGE_MAR0 + (i * 4), hashes[i]); } +static void +bge_sig_pre_reset(sc, type) + struct bge_softc *sc; + int type; +{ + if (sc->bge_asf_mode) + bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER); + + if (sc->bge_asf_mode & ASF_NEW_HANDSHAKE) { + switch (type) { + case BGE_RESET_START: + bge_writemem_ind(sc, BGE_SDI_STATUS, 0x1); /* START */ + break; + case BGE_RESET_STOP: + bge_writemem_ind(sc, BGE_SDI_STATUS, 0x2); /* UNLOAD */ + break; + } + } +} + +static void +bge_sig_post_reset(sc, type) + struct bge_softc *sc; + int type; +{ + if (sc->bge_asf_mode & ASF_NEW_HANDSHAKE) { + switch (type) { + case BGE_RESET_START: + bge_writemem_ind(sc, BGE_SDI_STATUS, 0x80000001); + /* START DONE */ + break; + case BGE_RESET_STOP: + bge_writemem_ind(sc, BGE_SDI_STATUS, 0x80000002); + break; + } + } +} + +static void +bge_sig_legacy(sc, type) + struct bge_softc *sc; + int type; +{ + if (sc->bge_asf_mode) { + switch (type) { + case BGE_RESET_START: + bge_writemem_ind(sc, BGE_SDI_STATUS, 0x1); /* START */ + break; + case BGE_RESET_STOP: + bge_writemem_ind(sc, BGE_SDI_STATUS, 0x2); /* UNLOAD */ + break; + } + } +} + +void bge_stop_fw(struct bge_softc *); +void +bge_stop_fw(sc) + struct bge_softc *sc; +{ + int i; + + if (sc->bge_asf_mode) { + bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM_FW, BGE_FW_PAUSE); + CSR_WRITE_4(sc, BGE_CPU_EVENT, + CSR_READ_4(sc, BGE_CPU_EVENT) != (1 << 14)); + + for (i = 0; i < 100; i++ ) { + if (!(CSR_READ_4(sc, BGE_CPU_EVENT) & (1 << 14))) + break; + DELAY(10); + } + } +} + /* * Do endian, PCI and DMA initialization. Also check the on-board ROM * self-test results. _at__at_ -978,7 +1058,7 _at__at_ bge_chipinit(struct bge_softc *sc) uint32_t dma_rw_ctl; int i; - /* Set endian type before we access any non-PCI registers. */ + /* Set endianness before we access any non-PCI registers. */ pci_write_config(sc->bge_dev, BGE_PCI_MISC_CTL, BGE_INIT, 4); /* _at__at_ -1069,6 +1149,9 _at__at_ bge_chipinit(struct bge_softc *sc) BGE_MODECTL_MAC_ATTN_INTR|BGE_MODECTL_HOST_SEND_BDS| BGE_MODECTL_TX_NO_PHDR_CSUM); + if (sc->bge_asf_mode & ASF_STACKUP) + BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP); + /* * Disable memory write invalidate. Apparently it is not supported * properly by these devices. _at__at_ -1992,6 +2075,7 _at__at_ bge_attach(device_t dev) uint32_t mac_tmp = 0; u_char eaddr[6]; int error = 0, rid; + int trys; sc = device_get_softc(dev); sc->bge_dev = dev; _at__at_ -2059,7 +2143,38 _at__at_ bge_attach(device_t dev) sc->bge_flags |= BGE_FLAG_PCIX; /* Try to reset the chip. */ - bge_reset(sc); + if (bge_reset(sc)) { + device_printf(sc->bge_dev, "chip reset failed\n"); + bge_release_resources(sc); + error = ENXIO; + goto fail; + } + + sc->bge_asf_mode = 0; + if (bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_SIG) + == BGE_MAGIC_NUMBER) { + if (bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_NICCFG) + & BGE_HWCFG_ASF) { + sc->bge_asf_mode |= ASF_ENABLE; + sc->bge_asf_mode |= ASF_STACKUP; + if (sc->bge_asicrev == BGE_ASICREV_BCM5750) { + sc->bge_asf_mode |= ASF_NEW_HANDSHAKE; + } + } + } + + /* Try to reset the chip again the nice way. */ + bge_stop_fw(sc); + bge_sig_pre_reset(sc, BGE_RESET_STOP); + if (bge_reset(sc)) { + device_printf(sc->bge_dev, "chip reset failed\n"); + bge_release_resources(sc); + error = ENXIO; + goto fail; + } + + bge_sig_legacy(sc, BGE_RESET_STOP); + bge_sig_post_reset(sc, BGE_RESET_STOP); if (bge_chipinit(sc)) { device_printf(sc->bge_dev, "chip initialization failed\n"); _at__at_ -2188,13 +2303,26 _at__at_ bge_attach(device_t dev) /* * Do transceiver setup. */ + BGE_CLRBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP); +again: + bge_asf_driver_up(sc); + + trys = 0; if (mii_phy_probe(dev, &sc->bge_miibus, bge_ifmedia_upd, bge_ifmedia_sts)) { + if (trys++ < 4) { + device_printf(sc->bge_dev, "Try again\n"); + bge_miibus_writereg(sc->bge_dev, 1, MII_BMCR, BMCR_RESET); + goto again; + } + device_printf(sc->bge_dev, "MII without any PHY!\n"); bge_release_resources(sc); error = ENXIO; goto fail; } + if (sc->bge_asf_mode & ASF_STACKUP) + BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP); } /* _at__at_ -2295,7 +2423,7 _at__at_ bge_release_resources(struct bge_softc * BGE_LOCK_DESTROY(sc); } -static void +static int bge_reset(struct bge_softc *sc) { device_t dev; _at__at_ -2381,7 +2509,7 _at__at_ bge_reset(struct bge_softc *sc) if (i == BGE_TIMEOUT) { device_printf(sc->bge_dev, "firmware handshake timed out\n"); - return; + return(0); } /* _at__at_ -2401,6 +2529,8 _at__at_ bge_reset(struct bge_softc *sc) /* Fix up byte swapping. */ CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_DMA_SWAP_OPTIONS| BGE_MODECTL_BYTESWAP_DATA); + if (sc->bge_asf_mode & ASF_STACKUP) + BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP); CSR_WRITE_4(sc, BGE_MAC_MODE, 0); _at__at_ -2427,6 +2557,8 _at__at_ bge_reset(struct bge_softc *sc) CSR_WRITE_4(sc, 0x7c00, v | (1<<25)); } DELAY(10000); + + return(0); } /* _at__at_ -2740,6 +2872,25 _at__at_ bge_intr(void *xsc) } static void +bge_asf_driver_up(struct bge_softc *sc) +{ + if (sc->bge_asf_mode & ASF_STACKUP) { + /* Send ASF heartbeat aprox. every 2s */ + if (sc->bge_asf_count) + sc->bge_asf_count --; + else { + sc->bge_asf_count = 5; + bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM_FW, + BGE_FW_DRV_ALIVE); + bge_writemem_ind(sc, BGE_SOFTWARE_GENNCOMM_FW_LEN, 4); + bge_writemem_ind(sc, BGE_SOFTWARE_GENNCOMM_FW_DATA, 3); + CSR_WRITE_4(sc, BGE_CPU_EVENT, + CSR_READ_4(sc, BGE_CPU_EVENT) != (1 << 14)); + } + } +} + +static void bge_tick_locked(struct bge_softc *sc) { struct mii_data *mii = NULL; _at__at_ -2753,7 +2904,9 _at__at_ bge_tick_locked(struct bge_softc *sc) if ((sc->bge_flags & BGE_FLAG_TBI) == 0) { mii = device_get_softc(sc->bge_miibus); - mii_tick(mii); + /* Don't mess with the PHY in IPMI/ASF mode */ + if (!((sc->bge_asf_mode & ASF_STACKUP) && (sc->bge_link))) + mii_tick(mii); } else { /* * Since in TBI mode auto-polling can't be used we should poll _at__at_ -2770,6 +2923,8 _at__at_ bge_tick_locked(struct bge_softc *sc) } } + bge_asf_driver_up(sc); + callout_reset(&sc->bge_stat_ch, hz, bge_tick, sc); } _at__at_ -3116,7 +3271,13 _at__at_ bge_init_locked(struct bge_softc *sc) /* Cancel pending I/O and flush buffers. */ bge_stop(sc); + + bge_stop_fw(sc); + bge_sig_pre_reset(sc, BGE_RESET_START); bge_reset(sc); + bge_sig_legacy(sc, BGE_RESET_START); + bge_sig_post_reset(sc, BGE_RESET_START); + bge_chipinit(sc); /* _at__at_ -3199,7 +3360,7 _at__at_ bge_init_locked(struct bge_softc *sc) CSR_WRITE_4(sc, BGE_HCC_TX_MAX_COAL_BDS_INT, 1); } else #endif - + /* Enable host interrupts. */ { BGE_SETBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_CLEAR_INTA); _at__at_ -3551,7 +3712,16 _at__at_ bge_stop(struct bge_softc *sc) /* * Tell firmware we're shutting down. */ - BGE_CLRBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP); + + bge_stop_fw(sc); + bge_sig_pre_reset(sc, BGE_RESET_STOP); + bge_reset(sc); + bge_sig_legacy(sc, BGE_RESET_STOP); + bge_sig_post_reset(sc, BGE_RESET_STOP); + if (sc->bge_asf_mode & ASF_STACKUP) + BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP); + else + BGE_CLRBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP); /* Free the RX lists. */ bge_free_rx_ring_std(sc); Index: if_bgereg.h =================================================================== RCS file: /cvs/src/sys/dev/bge/if_bgereg.h,v retrieving revision 1.52 diff -u -p -r1.52 if_bgereg.h --- if_bgereg.h 23 Aug 2006 11:32:54 -0000 1.52 +++ if_bgereg.h 7 Sep 2006 18:31:59 -0000 _at__at_ -74,6 +74,11 _at__at_ #define BGE_SOFTWARE_GENCOMM 0x00000B50 #define BGE_SOFTWARE_GENCOMM_SIG 0x00000B54 #define BGE_SOFTWARE_GENCOMM_NICCFG 0x00000B58 +#define BGE_SOFTWARE_GENCOMM_FW 0x00000B78 +#define BGE_FW_DRV_ALIVE 0x00000001 +#define BGE_FW_PAUSE 0x00000002 +#define BGE_SOFTWARE_GENNCOMM_FW_LEN 0x00000B7C +#define BGE_SOFTWARE_GENNCOMM_FW_DATA 0x00000B80 #define BGE_SOFTWARE_GENCOMM_END 0x00000FFF #define BGE_UNMAPPED 0x00001000 #define BGE_UNMAPPED_END 0x00001FFF _at__at_ -1651,6 +1656,7 _at__at_ #define BGE_MODE_CTL 0x6800 #define BGE_MISC_CFG 0x6804 #define BGE_MISC_LOCAL_CTL 0x6808 +#define BGE_CPU_EVENT 0x6810 #define BGE_EE_ADDR 0x6838 #define BGE_EE_DATA 0x683C #define BGE_EE_CTL 0x6840 _at__at_ -2063,6 +2069,7 _at__at_ struct bge_status_block { #define BGE_HWCFG_VOLTAGE 0x00000003 #define BGE_HWCFG_PHYLED_MODE 0x0000000C #define BGE_HWCFG_MEDIA 0x00000030 +#define BGE_HWCFG_ASF 0x00000080 #define BGE_VOLTAGE_1POINT3 0x00000000 #define BGE_VOLTAGE_1POINT8 0x00000001 _at__at_ -2433,6 +2440,10 _at__at_ struct bge_bcom_hack { int val; }; +#define ASF_ENABLE 1 +#define ASF_NEW_HANDSHAKE 2 +#define ASF_STACKUP 4 + struct bge_softc { struct ifnet *bge_ifp; /* interface info */ device_t bge_dev; _at__at_ -2452,8 +2463,10 _at__at_ struct bge_softc { #define BGE_FLAG_PCIX 0x00000010 #define BGE_FLAG_PCIE 0x00000020 uint32_t bge_chipid; - uint8_t bge_asicrev; - uint8_t bge_chiprev; + uint8_t bge_asicrev; + uint8_t bge_chiprev; + uint8_t bge_asf_mode; + uint8_t bge_asf_count; struct bge_ring_data bge_ldata; /* rings */ struct bge_chain_data bge_cdata; /* mbufs */ uint16_t bge_tx_saved_considx;Received on Thu Sep 07 2006 - 16:35:59 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:00 UTC