--- if_ti.c.orig Wed Dec 21 18:07:10 2005 +++ if_ti.c Wed Dec 21 19:55:26 2005 @@ -82,6 +82,7 @@ #include "opt_ti.h" #include +#include #include #include #include @@ -91,6 +92,8 @@ #include #include #include +#include +#include #include #include @@ -106,32 +109,16 @@ #include #include -#include /* for vtophys */ -#include /* for vtophys */ #include #include #include #include /* #define TI_PRIVATE_JUMBOS */ - -#if !defined(TI_PRIVATE_JUMBOS) -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#ifndef TI_PRIVATE_JUMBOS +#include #include -#include -#include -#include -#endif /* !TI_PRIVATE_JUMBOS */ +#endif #include #include @@ -207,8 +194,10 @@ static void ti_intr(void *); static void ti_start(struct ifnet *); +static void ti_start_locked(struct ifnet *); static int ti_ioctl(struct ifnet *, u_long, caddr_t); static void ti_init(void *); +static void ti_init_locked(void *); static void ti_init2(struct ti_softc *); static void ti_stop(struct ti_softc *); static void ti_watchdog(struct ifnet *); @@ -224,7 +213,9 @@ static void ti_del_mcast(struct ti_softc *, struct ether_addr *); static void ti_setmulti(struct ti_softc *); -static void ti_mem(struct ti_softc *, u_int32_t, u_int32_t, caddr_t); +static void ti_mem_read(struct ti_softc *, u_int32_t, u_int32_t, void *); +static void ti_mem_write(struct ti_softc *, u_int32_t, u_int32_t, void *); +static void ti_mem_zero(struct ti_softc *, u_int32_t, u_int32_t); static int ti_copy_mem(struct ti_softc *, u_int32_t, u_int32_t, caddr_t, int, int); static int ti_copy_scratch(struct ti_softc *, u_int32_t, u_int32_t, caddr_t, int, int, int); @@ -428,21 +419,20 @@ } /* - * NIC memory access function. Can be used to either clear a section - * of NIC local memory or (if buf is non-NULL) copy data into it. + * NIC memory read function. + * Can be used to copy data from NIC local memory. */ static void -ti_mem(sc, addr, len, buf) +ti_mem_read(sc, addr, len, buf) struct ti_softc *sc; u_int32_t addr, len; - caddr_t buf; + void *buf; { int segptr, segsize, cnt; - caddr_t ti_winbase, ptr; + char *ptr; segptr = addr; cnt = len; - ti_winbase = (caddr_t)(sc->ti_vhandle + TI_WINDOW); ptr = buf; while (cnt) { @@ -451,14 +441,70 @@ else segsize = TI_WINLEN - (segptr % TI_WINLEN); CSR_WRITE_4(sc, TI_WINBASE, (segptr & ~(TI_WINLEN - 1))); - if (buf == NULL) - bzero((char *)ti_winbase + (segptr & - (TI_WINLEN - 1)), segsize); - else { - bcopy((char *)ptr, (char *)ti_winbase + - (segptr & (TI_WINLEN - 1)), segsize); - ptr += segsize; - } + bus_space_read_region_4(sc->ti_btag, sc->ti_bhandle, + TI_WINDOW + (segptr & (TI_WINLEN - 1)), (u_int32_t *)ptr, + segsize / 4); + ptr += segsize; + segptr += segsize; + cnt -= segsize; + } +} + + +/* + * NIC memory write function. + * Can be used to copy data into NIC local memory. + */ +static void +ti_mem_write(sc, addr, len, buf) + struct ti_softc *sc; + u_int32_t addr, len; + void *buf; +{ + int segptr, segsize, cnt; + char *ptr; + + segptr = addr; + cnt = len; + ptr = buf; + + while (cnt) { + if (cnt < TI_WINLEN) + segsize = cnt; + else + segsize = TI_WINLEN - (segptr % TI_WINLEN); + CSR_WRITE_4(sc, TI_WINBASE, (segptr & ~(TI_WINLEN - 1))); + bus_space_write_region_4(sc->ti_btag, sc->ti_bhandle, + TI_WINDOW + (segptr & (TI_WINLEN - 1)), (u_int32_t *)ptr, + segsize / 4); + ptr += segsize; + segptr += segsize; + cnt -= segsize; + } +} + +/* + * NIC memory read function. + * Can be used to clear a section of NIC local memory. + */ +static void +ti_mem_zero(sc, addr, len) + struct ti_softc *sc; + u_int32_t addr, len; +{ + int segptr, segsize, cnt; + + segptr = addr; + cnt = len; + + while (cnt) { + if (cnt < TI_WINLEN) + segsize = cnt; + else + segsize = TI_WINLEN - (segptr % TI_WINLEN); + CSR_WRITE_4(sc, TI_WINBASE, (segptr & ~(TI_WINLEN - 1))); + bus_space_set_region_4(sc->ti_btag, sc->ti_bhandle, + TI_WINDOW + (segptr & (TI_WINLEN - 1)), 0, segsize / 4); segptr += segsize; cnt -= segsize; } @@ -803,6 +849,9 @@ ti_loadfw(sc) struct ti_softc *sc; { + + TI_LOCK_ASSERT(sc); + switch (sc->ti_hwrev) { case TI_HWREV_TIGON: if (tigonFwReleaseMajor != TI_FIRMWARE_MAJOR || @@ -815,14 +864,12 @@ tigonFwReleaseMinor, tigonFwReleaseFix); return; } - ti_mem(sc, tigonFwTextAddr, tigonFwTextLen, - (caddr_t)tigonFwText); - ti_mem(sc, tigonFwDataAddr, tigonFwDataLen, - (caddr_t)tigonFwData); - ti_mem(sc, tigonFwRodataAddr, tigonFwRodataLen, - (caddr_t)tigonFwRodata); - ti_mem(sc, tigonFwBssAddr, tigonFwBssLen, NULL); - ti_mem(sc, tigonFwSbssAddr, tigonFwSbssLen, NULL); + ti_mem_write(sc, tigonFwTextAddr, tigonFwTextLen, tigonFwText); + ti_mem_write(sc, tigonFwDataAddr, tigonFwDataLen, tigonFwData); + ti_mem_write(sc, tigonFwRodataAddr, tigonFwRodataLen, + tigonFwRodata); + ti_mem_zero(sc, tigonFwBssAddr, tigonFwBssLen); + ti_mem_zero(sc, tigonFwSbssAddr, tigonFwSbssLen); CSR_WRITE_4(sc, TI_CPU_PROGRAM_COUNTER, tigonFwStartAddr); break; case TI_HWREV_TIGON_II: @@ -836,14 +883,14 @@ tigon2FwReleaseMinor, tigon2FwReleaseFix); return; } - ti_mem(sc, tigon2FwTextAddr, tigon2FwTextLen, - (caddr_t)tigon2FwText); - ti_mem(sc, tigon2FwDataAddr, tigon2FwDataLen, - (caddr_t)tigon2FwData); - ti_mem(sc, tigon2FwRodataAddr, tigon2FwRodataLen, - (caddr_t)tigon2FwRodata); - ti_mem(sc, tigon2FwBssAddr, tigon2FwBssLen, NULL); - ti_mem(sc, tigon2FwSbssAddr, tigon2FwSbssLen, NULL); + ti_mem_write(sc, tigon2FwTextAddr, tigon2FwTextLen, + tigon2FwText); + ti_mem_write(sc, tigon2FwDataAddr, tigon2FwDataLen, + tigon2FwData); + ti_mem_write(sc, tigon2FwRodataAddr, tigon2FwRodataLen, + tigon2FwRodata); + ti_mem_zero(sc, tigon2FwBssAddr, tigon2FwBssLen); + ti_mem_zero(sc, tigon2FwSbssAddr, tigon2FwSbssLen); CSR_WRITE_4(sc, TI_CPU_PROGRAM_COUNTER, tigon2FwStartAddr); break; default: @@ -863,9 +910,6 @@ { u_int32_t index; - if (sc->ti_rdata->ti_cmd_ring == NULL) - return; - index = sc->ti_cmd_saved_prodidx; CSR_WRITE_4(sc, TI_GCR_CMDRING + (index * 4), *(u_int32_t *)(cmd)); TI_INC(index, TI_CMD_RING_CNT); @@ -885,10 +929,7 @@ int len; { u_int32_t index; - register int i; - - if (sc->ti_rdata->ti_cmd_ring == NULL) - return; + int i; index = sc->ti_cmd_saved_prodidx; CSR_WRITE_4(sc, TI_GCR_CMDRING + (index * 4), *(u_int32_t *)(cmd)); @@ -916,22 +957,22 @@ while (sc->ti_ev_saved_considx != sc->ti_ev_prodidx.ti_idx) { e = &sc->ti_rdata->ti_event_ring[sc->ti_ev_saved_considx]; - switch (e->ti_event) { + switch (TI_EVENT_EVENT(e)) { case TI_EV_LINKSTAT_CHANGED: - sc->ti_linkstat = e->ti_code; - if (e->ti_code == TI_EV_CODE_LINK_UP) + sc->ti_linkstat = TI_EVENT_CODE(e); + if (sc->ti_linkstat == TI_EV_CODE_LINK_UP) if_printf(sc->ti_ifp, "10/100 link up\n"); - else if (e->ti_code == TI_EV_CODE_GIG_LINK_UP) + else if (sc->ti_linkstat == TI_EV_CODE_GIG_LINK_UP) if_printf(sc->ti_ifp, "gigabit link up\n"); - else if (e->ti_code == TI_EV_CODE_LINK_DOWN) + else if (sc->ti_linkstat == TI_EV_CODE_LINK_DOWN) if_printf(sc->ti_ifp, "link down\n"); break; case TI_EV_ERROR: - if (e->ti_code == TI_EV_CODE_ERR_INVAL_CMD) + if (TI_EVENT_CODE(e) == TI_EV_CODE_ERR_INVAL_CMD) if_printf(sc->ti_ifp, "invalid command\n"); - else if (e->ti_code == TI_EV_CODE_ERR_UNIMP_CMD) + else if (TI_EVENT_CODE(e) == TI_EV_CODE_ERR_UNIMP_CMD) if_printf(sc->ti_ifp, "unknown command\n"); - else if (e->ti_code == TI_EV_CODE_ERR_BADCFG) + else if (TI_EVENT_CODE(e) == TI_EV_CODE_ERR_BADCFG) if_printf(sc->ti_ifp, "bad config data\n"); break; case TI_EV_FIRMWARE_UP: @@ -946,7 +987,7 @@ break; default: if_printf(sc->ti_ifp, "unknown event: %d\n", - e->ti_event); + TI_EVENT_EVENT(e)); break; } /* Advance the consumer index. */ @@ -990,21 +1031,36 @@ { int i; - for (i = 0; i < TI_TX_RING_CNT; i++) - bus_dmamap_destroy(sc->ti_mbuftx_dmat, - sc->ti_cdata.ti_tx_maps[i]); - - for (i = 0; i < TI_STD_RX_RING_CNT; i++) - bus_dmamap_destroy(sc->ti_mbufrx_dmat, - sc->ti_cdata.ti_rx_std_maps[i]); - - for (i = 0; i < TI_JUMBO_RX_RING_CNT; i++) - bus_dmamap_destroy(sc->ti_jumbo_dmat, - sc->ti_cdata.ti_rx_jumbo_maps[i]); - - for (i = 0; i < TI_MINI_RX_RING_CNT; i++) - bus_dmamap_destroy(sc->ti_mbufrx_dmat, - sc->ti_cdata.ti_rx_mini_maps[i]); + if (sc->ti_mbuftx_dmat) + for (i = 0; i < TI_TX_RING_CNT; i++) + if (sc->ti_cdata.ti_tx_maps[i]) { + bus_dmamap_destroy(sc->ti_mbuftx_dmat, + sc->ti_cdata.ti_tx_maps[i]); + sc->ti_cdata.ti_tx_maps[i] = 0; + } + + if (sc->ti_mbufrx_dmat) + for (i = 0; i < TI_STD_RX_RING_CNT; i++) + if (sc->ti_cdata.ti_rx_std_maps[i]) { + bus_dmamap_destroy(sc->ti_mbufrx_dmat, + sc->ti_cdata.ti_rx_std_maps[i]); + sc->ti_cdata.ti_rx_std_maps[i] = 0; + } + + if (sc->ti_jumbo_dmat) + for (i = 0; i < TI_JUMBO_RX_RING_CNT; i++) + if (sc->ti_cdata.ti_rx_jumbo_maps[i]) { + bus_dmamap_destroy(sc->ti_jumbo_dmat, + sc->ti_cdata.ti_rx_jumbo_maps[i]); + sc->ti_cdata.ti_rx_jumbo_maps[i] = 0; + } + if (sc->ti_mbufrx_dmat) + for (i = 0; i < TI_MINI_RX_RING_CNT; i++) + if (sc->ti_cdata.ti_rx_mini_maps[i]) { + bus_dmamap_destroy(sc->ti_mbufrx_dmat, + sc->ti_cdata.ti_rx_mini_maps[i]); + sc->ti_cdata.ti_rx_mini_maps[i] = 0; + } } #ifdef TI_PRIVATE_JUMBOS @@ -1350,7 +1406,6 @@ } #else -#include #if (PAGE_SIZE == 4096) #define NPAYLOAD 2 @@ -1548,10 +1603,15 @@ ti_free_rx_ring_std(sc) struct ti_softc *sc; { - register int i; + bus_dmamap_t map; + int i; for (i = 0; i < TI_STD_RX_RING_CNT; i++) { if (sc->ti_cdata.ti_rx_std_chain[i] != NULL) { + map = sc->ti_cdata.ti_rx_std_maps[i]; + bus_dmamap_sync(sc->ti_mbufrx_dmat, map, + BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(sc->ti_mbufrx_dmat, map); m_freem(sc->ti_cdata.ti_rx_std_chain[i]); sc->ti_cdata.ti_rx_std_chain[i] = NULL; } @@ -1582,10 +1642,15 @@ ti_free_rx_ring_jumbo(sc) struct ti_softc *sc; { - register int i; + bus_dmamap_t map; + int i; for (i = 0; i < TI_JUMBO_RX_RING_CNT; i++) { if (sc->ti_cdata.ti_rx_jumbo_chain[i] != NULL) { + map = sc->ti_cdata.ti_rx_jumbo_maps[i]; + bus_dmamap_sync(sc->ti_jumbo_dmat, map, + BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(sc->ti_jumbo_dmat, map); m_freem(sc->ti_cdata.ti_rx_jumbo_chain[i]); sc->ti_cdata.ti_rx_jumbo_chain[i] = NULL; } @@ -1615,10 +1680,15 @@ ti_free_rx_ring_mini(sc) struct ti_softc *sc; { + bus_dmamap_t map; register int i; for (i = 0; i < TI_MINI_RX_RING_CNT; i++) { if (sc->ti_cdata.ti_rx_mini_chain[i] != NULL) { + map = sc->ti_cdata.ti_rx_mini_maps[i]; + bus_dmamap_sync(sc->ti_mbufrx_dmat, map, + BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(sc->ti_mbufrx_dmat, map); m_freem(sc->ti_cdata.ti_rx_mini_chain[i]); sc->ti_cdata.ti_rx_mini_chain[i] = NULL; } @@ -1631,13 +1701,18 @@ ti_free_tx_ring(sc) struct ti_softc *sc; { - register int i; + bus_dmamap_t map; + int i; if (sc->ti_rdata->ti_tx_ring == NULL) return; for (i = 0; i < TI_TX_RING_CNT; i++) { if (sc->ti_cdata.ti_tx_chain[i] != NULL) { + map = sc->ti_cdata.ti_tx_maps[i]; + bus_dmamap_sync(sc->ti_mbuftx_dmat, map, + BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->ti_mbuftx_dmat, map); m_freem(sc->ti_cdata.ti_tx_chain[i]); sc->ti_cdata.ti_tx_chain[i] = NULL; } @@ -1741,6 +1816,8 @@ struct ti_mc_entry *mc; u_int32_t intrs; + TI_LOCK_ASSERT(sc); + ifp = sc->ti_ifp; if (ifp->if_flags & IFF_ALLMULTI) { @@ -1831,7 +1908,7 @@ sc->ti_ifp->if_hwassist = 0; /* Set endianness before we access any non-PCI registers. */ -#if BYTE_ORDER == BIG_ENDIAN +#if 0 && BYTE_ORDER == BIG_ENDIAN CSR_WRITE_4(sc, TI_MISC_HOST_CTL, TI_MHC_BIGENDIAN_INIT | (TI_MHC_BIGENDIAN_INIT << 24)); #else @@ -1990,6 +2067,8 @@ struct ifnet *ifp; uint32_t rdphys; + TI_LOCK_ASSERT(sc); + ifp = sc->ti_ifp; rdphys = sc->ti_rdata_phys; @@ -2024,8 +2103,6 @@ /* Set up the command ring and producer mailbox. */ rcb = &sc->ti_rdata->ti_info.ti_cmd_rcb; - sc->ti_rdata->ti_cmd_ring = - (struct ti_cmd_desc *)(sc->ti_vhandle + TI_GCR_CMDRING); TI_HOSTADDR(rcb->ti_hostaddr) = TI_GCR_NIC_ADDR(TI_GCR_CMDRING); rcb->ti_flags = 0; rcb->ti_max_len = 0; @@ -2107,10 +2184,6 @@ * a Tigon 1 chip. */ CSR_WRITE_4(sc, TI_WINBASE, TI_TX_RING_BASE); - if (sc->ti_hwrev == TI_HWREV_TIGON) { - sc->ti_rdata->ti_tx_ring_nic = - (struct ti_tx_desc *)(sc->ti_vhandle + TI_WINDOW); - } bzero((char *)sc->ti_rdata->ti_tx_ring, TI_TX_RING_CNT * sizeof(struct ti_tx_desc)); rcb = &sc->ti_rdata->ti_info.ti_tx_rcb; @@ -2130,6 +2203,9 @@ TI_HOSTADDR(sc->ti_rdata->ti_info.ti_tx_considx_ptr) = rdphys + TI_RD_OFF(ti_tx_considx_r); + bus_dmamap_sync(sc->ti_rdata_dmat, sc->ti_rdata_dmamap, + BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); + /* Set up tuneables */ #if 0 if (ifp->if_mtu > (ETHERMTU + ETHER_HDR_LEN + ETHER_CRC_LEN)) @@ -2167,7 +2243,7 @@ * All of the Tigon data structures need to live at <4GB. This * cast is fine since busdma was told about this constraint. */ - sc->ti_rdata_phys = (uint32_t)segs[0].ds_addr; + sc->ti_rdata_phys = segs[0].ds_addr; return; } @@ -2209,7 +2285,7 @@ sc->ti_dev = dev; mtx_init(&sc->ti_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, - MTX_DEF | MTX_RECURSE); + MTX_DEF); ifmedia_init(&sc->ifmedia, IFM_IMASK, ti_ifmedia_upd, ti_ifmedia_sts); ifp = sc->ti_ifp = if_alloc(IFT_ETHER); if (ifp == NULL) { @@ -2238,7 +2314,6 @@ sc->ti_btag = rman_get_bustag(sc->ti_res); sc->ti_bhandle = rman_get_bushandle(sc->ti_res); - sc->ti_vhandle = (vm_offset_t)rman_get_virtual(sc->ti_res); /* Allocate interrupt */ rid = 0; @@ -2259,7 +2334,7 @@ } /* Zero out the NIC's on-board SRAM. */ - ti_mem(sc, 0x2000, 0x100000 - 0x2000, NULL); + ti_mem_zero(sc, 0x2000, 0x100000 - 0x2000); /* Init again -- zeroing memory may have clobbered some registers. */ if (ti_chipinit(sc)) { @@ -2468,7 +2543,6 @@ if (error) { device_printf(dev, "couldn't set up irq\n"); - ether_ifdetach(ifp); goto fail; } @@ -2492,21 +2566,25 @@ { struct ti_softc *sc; struct ifnet *ifp; + int attached; sc = device_get_softc(dev); if (sc->dev) destroy_dev(sc->dev); KASSERT(mtx_initialized(&sc->ti_mtx), ("ti mutex not initialized")); + attached = device_is_attached(dev); TI_LOCK(sc); ifp = sc->ti_ifp; - - /* These should only be active if attach succeeded */ - if (device_is_attached(dev)) { + if (attached) ti_stop(sc); + TI_UNLOCK(sc); + if (attached) ether_ifdetach(ifp); + + /* These should only be active if attach succeeded */ + if (attached) bus_generic_detach(dev); - ti_free_dmamaps(sc); - } + ti_free_dmamaps(sc); ifmedia_removeall(&sc->ifmedia); #ifdef TI_PRIVATE_JUMBOS @@ -2538,7 +2616,6 @@ if (ifp) if_free(ifp); - TI_UNLOCK(sc); mtx_destroy(&sc->ti_mtx); return (0); @@ -2763,22 +2840,13 @@ */ while (sc->ti_tx_saved_considx != sc->ti_tx_considx.ti_idx) { u_int32_t idx = 0; + struct ti_tx_desc txdesc; idx = sc->ti_tx_saved_considx; if (sc->ti_hwrev == TI_HWREV_TIGON) { - if (idx > 383) - CSR_WRITE_4(sc, TI_WINBASE, - TI_TX_RING_BASE + 6144); - else if (idx > 255) - CSR_WRITE_4(sc, TI_WINBASE, - TI_TX_RING_BASE + 4096); - else if (idx > 127) - CSR_WRITE_4(sc, TI_WINBASE, - TI_TX_RING_BASE + 2048); - else - CSR_WRITE_4(sc, TI_WINBASE, - TI_TX_RING_BASE); - cur_tx = &sc->ti_rdata->ti_tx_ring_nic[idx % 128]; + ti_mem_read(sc, TI_TX_RING_BASE + idx * sizeof(txdesc), + sizeof(txdesc), &txdesc); + cur_tx = &txdesc; } else cur_tx = &sc->ti_rdata->ti_tx_ring[idx]; if (cur_tx->ti_flags & TI_BDFLAG_END) @@ -2838,7 +2906,7 @@ if (ifp->if_drv_flags & IFF_DRV_RUNNING && ifp->if_snd.ifq_head != NULL) - ti_start(ifp); + ti_start_locked(ifp); TI_UNLOCK(sc); } @@ -2851,12 +2919,18 @@ ifp = sc->ti_ifp; + bus_dmamap_sync(sc->ti_rdata_dmat, sc->ti_rdata_dmamap, + BUS_DMASYNC_POSTREAD); + ifp->if_collisions += (sc->ti_rdata->ti_info.ti_stats.dot3StatsSingleCollisionFrames + sc->ti_rdata->ti_info.ti_stats.dot3StatsMultipleCollisionFrames + sc->ti_rdata->ti_info.ti_stats.dot3StatsExcessiveCollisions + sc->ti_rdata->ti_info.ti_stats.dot3StatsLateCollisions) - ifp->if_collisions; + + bus_dmamap_sync(sc->ti_rdata_dmat, sc->ti_rdata_dmamap, + BUS_DMASYNC_PREREAD); } struct ti_dmamap_arg { @@ -2878,6 +2952,7 @@ struct ti_softc *sc; struct ti_dmamap_arg *ctx; struct ti_tx_desc *f = NULL; + struct ti_tx_desc txdesc; struct m_tag *mtag; u_int32_t frag, cur, cnt = 0; u_int16_t csum_flags; @@ -2898,19 +2973,8 @@ */ while (nseg-- > 0) { if (sc->ti_hwrev == TI_HWREV_TIGON) { - if (frag > 383) - CSR_WRITE_4(sc, TI_WINBASE, - TI_TX_RING_BASE + 6144); - else if (frag > 255) - CSR_WRITE_4(sc, TI_WINBASE, - TI_TX_RING_BASE + 4096); - else if (frag > 127) - CSR_WRITE_4(sc, TI_WINBASE, - TI_TX_RING_BASE + 2048); - else - CSR_WRITE_4(sc, TI_WINBASE, - TI_TX_RING_BASE); - f = &sc->ti_rdata->ti_tx_ring_nic[frag % 128]; + bzero(&txdesc, sizeof(txdesc)); + f = &txdesc; } else f = &sc->ti_rdata->ti_tx_ring[frag]; if (sc->ti_cdata.ti_tx_chain[frag] != NULL) @@ -2926,15 +2990,19 @@ f->ti_vlan_tag = 0; } + if (sc->ti_hwrev == TI_HWREV_TIGON) + ti_mem_write(sc, TI_TX_RING_BASE + frag * + sizeof(txdesc), sizeof(txdesc), &txdesc); cur = frag; TI_INC(frag, TI_TX_RING_CNT); cnt++; } - if (sc->ti_hwrev == TI_HWREV_TIGON) - sc->ti_rdata->ti_tx_ring_nic[cur % 128].ti_flags |= - TI_BDFLAG_END; - else + if (sc->ti_hwrev == TI_HWREV_TIGON) { + txdesc.ti_flags |= TI_BDFLAG_END; + ti_mem_write(sc, TI_TX_RING_BASE + cur * sizeof(txdesc), + sizeof(txdesc), &txdesc); + } else sc->ti_rdata->ti_tx_ring[cur].ti_flags |= TI_BDFLAG_END; sc->ti_cdata.ti_tx_chain[cur] = ctx->m_head; sc->ti_txcnt += cnt; @@ -2998,16 +3066,30 @@ } bus_dmamap_sync(sc->ti_mbuftx_dmat, map, BUS_DMASYNC_PREWRITE); + bus_dmamap_sync(sc->ti_rdata_dmat, sc->ti_rdata_dmamap, + BUS_DMASYNC_PREWRITE); *txidx = frag; return (0); } +static void +ti_start(ifp) + struct ifnet *ifp; +{ + struct ti_softc *sc; + + sc = ifp->if_softc; + TI_LOCK(sc); + ti_start_locked(ifp); + TI_UNLOCK(sc); +} + /* * Main transmit routine. To avoid having to do mbuf copies, we put pointers * to the mbuf data regions directly in the transmit descriptors. */ static void -ti_start(ifp) +ti_start_locked(ifp) struct ifnet *ifp; { struct ti_softc *sc; @@ -3015,7 +3097,6 @@ u_int32_t prodidx = 0; sc = ifp->if_softc; - TI_LOCK(sc); prodidx = CSR_READ_4(sc, TI_MB_SENDPROD_IDX); @@ -3067,27 +3148,34 @@ * Set a timeout in case the chip goes out to lunch. */ ifp->if_timer = 5; - TI_UNLOCK(sc); } static void ti_init(xsc) void *xsc; { + struct ti_softc *sc; + + sc = xsc; + TI_LOCK(sc); + ti_init_locked(sc); + TI_UNLOCK(sc); +} + +static void +ti_init_locked(xsc) + void *xsc; +{ struct ti_softc *sc = xsc; /* Cancel pending I/O and flush buffers. */ ti_stop(sc); - TI_LOCK(sc); /* Init the gen info block, ring control blocks and firmware. */ if (ti_gibinit(sc)) { if_printf(sc->ti_ifp, "initialization failure\n"); - TI_UNLOCK(sc); return; } - - TI_UNLOCK(sc); } static void ti_init2(sc) @@ -3095,7 +3183,7 @@ { struct ti_cmd_desc cmd; struct ifnet *ifp; - u_int16_t *m; + u_int8_t *ea; struct ifmedia *ifm; int tmp; @@ -3108,9 +3196,10 @@ TI_DO_CMD(TI_CMD_UPDATE_GENCOM, 0, 0); /* Load our MAC address. */ - m = (u_int16_t *)IF_LLADDR(sc->ti_ifp); - CSR_WRITE_4(sc, TI_GCR_PAR0, htons(m[0])); - CSR_WRITE_4(sc, TI_GCR_PAR1, (htons(m[1]) << 16) | htons(m[2])); + ea = IF_LLADDR(sc->ti_ifp); + CSR_WRITE_4(sc, TI_GCR_PAR0, (ea[0] << 8) | ea[1]); + CSR_WRITE_4(sc, TI_GCR_PAR1, + (ea[2] << 24) | (ea[3] << 16) | (ea[4] << 8) | ea[5]); TI_DO_CMD(TI_CMD_SET_MAC_ADDR, 0, 0); /* Enable or disable promiscuous mode as needed. */ @@ -3337,18 +3426,19 @@ int mask, error = 0; struct ti_cmd_desc cmd; - TI_LOCK(sc); - switch (command) { case SIOCSIFMTU: + TI_LOCK(sc); if (ifr->ifr_mtu > TI_JUMBO_MTU) error = EINVAL; else { ifp->if_mtu = ifr->ifr_mtu; - ti_init(sc); + ti_init_locked(sc); } + TI_UNLOCK(sc); break; case SIOCSIFFLAGS: + TI_LOCK(sc); if (ifp->if_flags & IFF_UP) { /* * If only the state of the PROMISC flag changed, @@ -3369,27 +3459,28 @@ TI_DO_CMD(TI_CMD_SET_PROMISC_MODE, TI_CMD_CODE_PROMISC_DIS, 0); } else - ti_init(sc); + ti_init_locked(sc); } else { if (ifp->if_drv_flags & IFF_DRV_RUNNING) { ti_stop(sc); } } sc->ti_if_flags = ifp->if_flags; - error = 0; + TI_UNLOCK(sc); break; case SIOCADDMULTI: case SIOCDELMULTI: - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + TI_LOCK(sc); + if (ifp->if_drv_flags & IFF_DRV_RUNNING) ti_setmulti(sc); - error = 0; - } + TI_UNLOCK(sc); break; case SIOCSIFMEDIA: case SIOCGIFMEDIA: error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command); break; case SIOCSIFCAP: + TI_LOCK(sc); mask = ifr->ifr_reqcap ^ ifp->if_capenable; if (mask & IFCAP_HWCSUM) { if (IFCAP_HWCSUM & ifp->if_capenable) @@ -3397,17 +3488,15 @@ else ifp->if_capenable |= IFCAP_HWCSUM; if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ti_init(sc); + ti_init_locked(sc); } - error = 0; + TI_UNLOCK(sc); break; default: error = ether_ioctl(ifp, command, data); break; } - TI_UNLOCK(sc); - return (error); } @@ -3740,7 +3829,7 @@ if_printf(ifp, "watchdog timeout -- resetting\n"); ti_stop(sc); - ti_init(sc); + ti_init_locked(sc); ifp->if_oerrors++; TI_UNLOCK(sc); @@ -3757,7 +3846,7 @@ struct ifnet *ifp; struct ti_cmd_desc cmd; - TI_LOCK(sc); + TI_LOCK_ASSERT(sc); ifp = sc->ti_ifp; @@ -3769,9 +3858,11 @@ TI_DO_CMD(TI_CMD_HOST_STATE, TI_CMD_CODE_STACK_DOWN, 0); /* Halt and reinitialize. */ - ti_chipinit(sc); - ti_mem(sc, 0x2000, 0x100000 - 0x2000, NULL); - ti_chipinit(sc); + if (ti_chipinit(sc) != 0) + return; + ti_mem_zero(sc, 0x2000, 0x100000 - 0x2000); + if (ti_chipinit(sc) != 0) + return; /* Free the RX lists. */ ti_free_rx_ring_std(sc); @@ -3791,7 +3882,6 @@ sc->ti_tx_saved_considx = TI_TXCONS_UNSET; ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - TI_UNLOCK(sc); } /* --- if_tireg.h.orig Wed Dec 14 17:03:07 2005 +++ if_tireg.h Wed Dec 21 16:09:57 2005 @@ -755,17 +755,13 @@ * Tigon command structure. */ struct ti_cmd_desc { -#if BYTE_ORDER == BIG_ENDIAN - u_int32_t ti_cmd:8; - u_int32_t ti_code:12; - u_int32_t ti_idx:12; -#else - u_int32_t ti_idx:12; - u_int32_t ti_code:12; - u_int32_t ti_cmd:8; -#endif + u_int32_t ti_cmdx; }; +#define TI_CMD_CMD(cmd) (((((cmd)->ti_cmdx)) >> 24) & 0xff) +#define TI_CMD_CODE(cmd) (((((cmd)->ti_cmdx)) >> 12) & 0xfff) +#define TI_CMD_IDX(cmd) ((((cmd)->ti_cmdx)) & 0xfff) + #define TI_CMD_HOST_STATE 0x01 #define TI_CMD_CODE_STACK_UP 0x01 #define TI_CMD_CODE_STACK_DOWN 0x02 @@ -813,15 +809,11 @@ * that 'sc' and 'cmd' are in local scope. */ #define TI_DO_CMD(x, y, z) \ - cmd.ti_cmd = (x); \ - cmd.ti_code = (y); \ - cmd.ti_idx = (z); \ + cmd.ti_cmdx = (((x) << 24) | ((y) << 12) | ((z))); \ ti_cmd(sc, &cmd); #define TI_DO_CMD_EXT(x, y, z, v, w) \ - cmd.ti_cmd = (x); \ - cmd.ti_code = (y); \ - cmd.ti_idx = (z); \ + cmd.ti_cmdx = (((x) << 24) | ((y) << 12) | ((z))); \ ti_cmd_ext(sc, &cmd, (v), (w)); /* @@ -851,18 +843,14 @@ * Tigon event structure. */ struct ti_event_desc { -#if BYTE_ORDER == BIG_ENDIAN - u_int32_t ti_event:8; - u_int32_t ti_code:12; - u_int32_t ti_idx:12; -#else - u_int32_t ti_idx:12; - u_int32_t ti_code:12; - u_int32_t ti_event:8; -#endif + u_int32_t ti_eventx; u_int32_t ti_rsvd; }; +#define TI_EVENT_EVENT(e) (((((e)->ti_eventx)) >> 24) & 0xff) +#define TI_EVENT_CODE(e) (((((e)->ti_eventx)) >> 12) & 0xfff) +#define TI_EVENT_IDX(e) (((((e)->ti_eventx))) & 0xfff) + /* * Tigon events. */ @@ -890,15 +878,15 @@ */ #define CSR_WRITE_4(sc, reg, val) \ - bus_space_write_4(sc->ti_btag, sc->ti_bhandle, reg, val) + bus_space_write_4(sc->ti_btag, sc->ti_bhandle, (reg), (val)) #define CSR_READ_4(sc, reg) \ - bus_space_read_4(sc->ti_btag, sc->ti_bhandle, reg) + bus_space_read_4(sc->ti_btag, sc->ti_bhandle, (reg)) #define TI_SETBIT(sc, reg, x) \ - CSR_WRITE_4(sc, reg, (CSR_READ_4(sc, reg) | x)) + CSR_WRITE_4(sc, (reg), (CSR_READ_4(sc, (reg)) | x)) #define TI_CLRBIT(sc, reg, x) \ - CSR_WRITE_4(sc, reg, (CSR_READ_4(sc, reg) & ~x)) + CSR_WRITE_4(sc, (reg), (CSR_READ_4(sc, (reg)) & ~x)) /* * Memory management stuff. Note: the SSLOTS, MSLOTS and JSLOTS @@ -1000,7 +988,6 @@ device_t ti_dev; struct ifnet *ti_ifp; bus_space_handle_t ti_bhandle; - vm_offset_t ti_vhandle; bus_space_tag_t ti_btag; void *ti_intrhand; struct resource *ti_irq; @@ -1018,7 +1005,7 @@ bus_dma_tag_t ti_mbufrx_dmat; bus_dma_tag_t ti_rdata_dmat; bus_dmamap_t ti_rdata_dmamap; - uint32_t ti_rdata_phys; + bus_addr_t ti_rdata_phys; struct ti_ring_data *ti_rdata; /* rings */ struct ti_chain_data ti_cdata; /* mbufs */ #define ti_ev_prodidx ti_rdata->ti_ev_prodidx_r