On Tue, Mar 28, 2006 at 12:38:42PM -0800, Doug Ambrisko wrote: > Oleg Bulyzhin writes: > | On Tue, Mar 28, 2006 at 11:24:06AM -0600, Stephen P. Cravey wrote: > | > Does anyone have chip documentation on the broadcom BGE chips? I'm > having an ongoing issue with IPMI that I'd really like to get resolved. The > issue seems to be that during the driver start sequence, a flag is getting > set in the chip that's disabling the IPMI passthrough that I need in order > for data destined for a second mac address on the interface to recieve > packets. Or, a flag that this process needs isn't getting set. Not sure > which, but I could really use some help here. > | > > | > Or should I ask the frequent committers to the driver directly? > | > > | > Thank you. > | > > | > PR: > | > kern/79143 > | > kern/88741 > | > _______________________________________________ > | > | Could you please test attached patch (RELENG_6 version)? It's slightly > | modified version of Doug Ambrisko > | ([EMAIL PROTECTED]) patch (original version didnt work for me: > | bcm5721 @ hp proliant dl145g2 server). > > I don't see it attached. I'd like to see your changes and I'd like know > of your plans about getting it in. > > Thanks, > > Doug A.
Oops... my fault. Should be attached now. -- Oleg.
Index: if_bgereg.h =================================================================== RCS file: /home/ncvs/src/sys/dev/bge/if_bgereg.h,v retrieving revision 1.36.2.4 diff -u -r1.36.2.4 if_bgereg.h --- if_bgereg.h 5 Feb 2006 18:07:15 -0000 1.36.2.4 +++ if_bgereg.h 28 Mar 2006 20:18:15 -0000 @@ -74,6 +74,11 @@ #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 @@ -1627,6 +1632,7 @@ #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 @@ -2009,6 +2015,7 @@ #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 @@ -2385,6 +2392,10 @@ 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; @@ -2403,6 +2414,8 @@ u_int8_t bge_asicrev; u_int8_t bge_chiprev; u_int8_t bge_no_3_led; + u_int8_t bge_asf_mode; + u_int8_t bge_asf_count; u_int8_t bge_pcie; struct bge_ring_data bge_ldata; /* rings */ struct bge_chain_data bge_cdata; /* mbufs */ Index: if_bge.c =================================================================== RCS file: /home/ncvs/src/sys/dev/bge/if_bge.c,v retrieving revision 1.91.2.13 diff -u -r1.91.2.13 if_bge.c --- if_bge.c 4 Mar 2006 09:34:48 -0000 1.91.2.13 +++ if_bge.c 28 Mar 2006 20:18:21 -0000 @@ -209,6 +209,7 @@ 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 *); @@ -271,7 +272,12 @@ 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[] = { @@ -609,6 +615,18 @@ DELAY(40); } + if (sc->bge_asf_mode & ASF_STACKUP + && pci_get_device(sc->bge_dev) == BCOM_DEVICEID_BCM5721) { + switch (reg) { + case MII_BMSR: + val |= BMSR_100TXFDX | BMSR_100TXHDX | BMSR_10TFDX + | BMSR_10THDX | BMSR_EXTSTAT + | BMSR_MFPS + | BMSR_ANEG | BMSR_EXTCAP; + break; + } + } + if (val & BGE_MICOMM_READFAIL) return(0); @@ -660,10 +678,10 @@ { struct bge_softc *sc; struct mii_data *mii; - sc = device_get_softc(dev); mii = device_get_softc(sc->bge_miibus); + BGE_CLRBIT(sc, BGE_MAC_MODE, BGE_MACMODE_PORTMODE); if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T) { BGE_SETBIT(sc, BGE_MAC_MODE, BGE_PORTMODE_GMII); @@ -1007,6 +1025,80 @@ return; } +static void +bge_sig_pre_reset(sc, type) + struct bge_softc *sc; + int type; +{ + 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. @@ -1018,9 +1110,10 @@ int i; u_int32_t dma_rw_ctl; - /* 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); +#ifdef DJA /* * Check the 'ROM failed' bit on the RX CPU to see if * self-tests passed. @@ -1029,7 +1122,7 @@ device_printf(sc->bge_dev, "RX CPU self-diagnostics failed!\n"); return(ENODEV); } - +#endif /* Clear the MAC control register */ CSR_WRITE_4(sc, BGE_MAC_MODE, 0); @@ -1101,6 +1194,9 @@ 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. @@ -2054,6 +2150,7 @@ u_int32_t mac_tmp = 0; u_char eaddr[6]; int error = 0, rid; + int trys; sc = device_get_softc(dev); sc->bge_dev = dev; @@ -2121,8 +2218,35 @@ } } + sc->bge_asf_mode = 0; + /* Try to reset the chip. */ - bge_reset(sc); + 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; + } + + 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; + if (CSR_READ_4(sc, BGE_MODE_CTL) + & BGE_MODECTL_STACKUP ) { + sc->bge_asf_mode |= ASF_STACKUP; + } + if (sc->bge_asicrev == BGE_ASICREV_BCM5750) { + sc->bge_asf_mode |= ASF_NEW_HANDSHAKE; + } + } + } + + 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"); @@ -2252,13 +2376,26 @@ /* * 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); } /* @@ -2372,7 +2509,7 @@ return; } -static void +static int bge_reset(sc) struct bge_softc *sc; { @@ -2435,11 +2572,18 @@ sc->bge_asicrev != BGE_ASICREV_BCM5750) CSR_WRITE_4(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE); +#if DJA + DELAY(1000000); /* - * Prevent PXE restart: write a magic number to the - * general communications memory at 0xB50. + * Check the 'ROM failed' bit on the RX CPU to see if + * self-tests passed. */ - bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER); + if (CSR_READ_4(sc, BGE_RXCPU_MODE) & BGE_RXCPUMODE_ROMFAIL) { + device_printf(sc->bge_dev, "RX CPU self-diagnostics failed!\n"); + return(ENODEV); + } +#endif + /* * Poll the value location we just wrote until * we see the 1's complement of the magic number. @@ -2455,7 +2599,7 @@ if (i == BGE_TIMEOUT) { device_printf(sc->bge_dev, "firmware handshake timed out\n"); - return; + return(0); } /* @@ -2475,6 +2619,8 @@ /* 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); @@ -2499,7 +2645,7 @@ } DELAY(10000); - return; + return(0); } /* @@ -2680,6 +2826,7 @@ { struct bge_tx_bd *cur_tx = NULL; struct ifnet *ifp; + int acked = 0; BGE_LOCK_ASSERT(sc); @@ -2716,11 +2863,36 @@ } sc->bge_txcnt--; BGE_INC(sc->bge_tx_saved_considx, BGE_TX_RING_CNT); - ifp->if_timer = 0; + ifp->if_timer = (sc->bge_txcnt == 0) ? 0 : 5; + + acked = 1; } if (cur_tx != NULL) ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + + switch (sc->bge_chipid) { + case BGE_CHIPID_BCM5701_A0: + case BGE_CHIPID_BCM5701_B0: + case BGE_CHIPID_BCM5701_B2: + case BGE_CHIPID_BCM5701_B5: + /* + * Sometimes the RX engine never gets started. We detect + * this by checking to see if we have sent some packets and + * never got a packet. If we haven't got a packet reset. + * this is only triggered if we sent packets. + */ + + if (acked && ifp->if_opackets > 5 && !ifp->if_ipackets) { + device_printf(sc->bge_dev, "reset the card packets out %ld in %ld\n" + , ifp->if_opackets, + ifp->if_ipackets); + ifp->if_flags &=~ IFF_DRV_RUNNING; + bge_stop(sc); + bge_init(sc); + } + break; + } } #ifdef DEVICE_POLLING @@ -2728,7 +2900,7 @@ bge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) { struct bge_softc *sc = ifp->if_softc; - + BGE_LOCK(sc); if (ifp->if_drv_flags & IFF_DRV_RUNNING) bge_poll_locked(ifp, cmd, count); @@ -2834,6 +3006,26 @@ } static void +bge_asf_driver_up(sc) + 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(sc) struct bge_softc *sc; { @@ -2849,7 +3041,9 @@ if (!sc->bge_tbi) { 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 @@ -2866,6 +3060,8 @@ } } + bge_asf_driver_up(sc); + callout_reset(&sc->bge_stat_ch, hz, bge_tick, sc); } @@ -3215,7 +3411,13 @@ /* 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); /* @@ -3298,14 +3500,14 @@ 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); BGE_CLRBIT(sc, BGE_PCI_MISC_CTL, BGE_PCIMISCCTL_MASK_PCI_INTR); CSR_WRITE_4(sc, BGE_MBX_IRQ0_LO, 0); } - + bge_ifmedia_upd(ifp); ifp->if_drv_flags |= IFF_DRV_RUNNING; @@ -3646,7 +3848,16 @@ /* * 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); @@ -3670,6 +3881,7 @@ /* * If we are called from bge_detach(), mii is already NULL. */ + //if (mii != NULL && !(sc->bge_asf_mode & ASF_ENABLE)) { if (mii != NULL) { ifm = mii->mii_media.ifm_cur; mtmp = ifm->ifm_media;
pgpQmKEVZ8bXQ.pgp
Description: PGP signature