diff options
author | Nathan Binkert <nate@cvs.openbsd.org> | 2002-12-04 17:32:31 +0000 |
---|---|---|
committer | Nathan Binkert <nate@cvs.openbsd.org> | 2002-12-04 17:32:31 +0000 |
commit | 5cd0bb5ed98fe0a56cc7f182cf640a322da3e076 (patch) | |
tree | d393d7f3cf026c8918401adf8c9fd4e64534e1a7 /sys/dev/pci | |
parent | 5608900a9420fb6c33121024ab7d6b9f8cab522a (diff) |
Make ti(4) use busdma and add all of the necessary stuff to support both
endian modes. This makes ti now work on macppc and sparc64.
While we're at ti, clean up a bit of the code:
Use SLIST instead of LIST
Remove register
Use bus_space instead of bcopy/bzero
Don't use bitfields since it makes dealing with endianness annoying.
ok jason@, deraadt@
Diffstat (limited to 'sys/dev/pci')
-rw-r--r-- | sys/dev/pci/if_ti.c | 455 | ||||
-rw-r--r-- | sys/dev/pci/if_tireg.h | 138 |
2 files changed, 353 insertions, 240 deletions
diff --git a/sys/dev/pci/if_ti.c b/sys/dev/pci/if_ti.c index 11f0fd7225c..37cae4b9025 100644 --- a/sys/dev/pci/if_ti.c +++ b/sys/dev/pci/if_ti.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ti.c,v 1.40 2002/11/26 06:01:28 nate Exp $ */ +/* $OpenBSD: if_ti.c,v 1.41 2002/12/04 17:32:30 nate Exp $ */ /* * Copyright (c) 1997, 1998, 1999 @@ -110,9 +110,6 @@ #include <net/bpf.h> #endif -#include <uvm/uvm_extern.h> /* for vtophys */ -#include <machine/bus.h> - #include <dev/pci/pcireg.h> #include <dev/pci/pcivar.h> #include <dev/pci/pcidevs.h> @@ -155,7 +152,7 @@ void ti_add_mcast(struct ti_softc *, struct ether_addr *); void ti_del_mcast(struct ti_softc *, struct ether_addr *); void ti_setmulti(struct ti_softc *); -void ti_mem(struct ti_softc *, u_int32_t, u_int32_t, const void *); +void ti_mem(struct ti_softc *, u_int32_t, u_int32_t, caddr_t); void ti_loadfw(struct ti_softc *); void ti_cmd(struct ti_softc *, struct ti_cmd_desc *); void ti_cmd_ext(struct ti_softc *, struct ti_cmd_desc *, @@ -164,8 +161,8 @@ void ti_handle_events(struct ti_softc *); int ti_alloc_jumbo_mem(struct ti_softc *); void *ti_jalloc(struct ti_softc *); void ti_jfree(caddr_t, u_int, void *); -int ti_newbuf_std(struct ti_softc *, int, struct mbuf *); -int ti_newbuf_mini(struct ti_softc *, int, struct mbuf *); +int ti_newbuf_std(struct ti_softc *, int, struct mbuf *, bus_dmamap_t); +int ti_newbuf_mini(struct ti_softc *, int, struct mbuf *, bus_dmamap_t); int ti_newbuf_jumbo(struct ti_softc *, int, struct mbuf *); int ti_init_rx_ring_std(struct ti_softc *); void ti_free_rx_ring_std(struct ti_softc *); @@ -187,7 +184,7 @@ u_int32_t ti_eeprom_putbyte(sc, byte) struct ti_softc *sc; int byte; { - register int i, ack = 0; + int i, ack = 0; /* * Make sure we're in TX mode. @@ -234,7 +231,7 @@ u_int8_t ti_eeprom_getbyte(sc, addr, dest) int addr; u_int8_t *dest; { - register int i; + int i; u_int8_t byte = 0; EEPROM_START; @@ -330,15 +327,13 @@ void ti_mem(sc, addr, len, buf) struct ti_softc *sc; u_int32_t addr, len; - const void * buf; + caddr_t buf; { int segptr, segsize, cnt; - caddr_t ti_winbase; - const void * ptr; + caddr_t ptr; segptr = addr; cnt = len; - ti_winbase = (caddr_t)(sc->ti_bhandle + TI_WINDOW); ptr = buf; while(cnt) { @@ -347,12 +342,14 @@ ti_mem(sc, addr, len, buf) else segsize = TI_WINLEN - (segptr % TI_WINLEN); CSR_WRITE_4(sc, TI_WINBASE, (segptr & ~(TI_WINLEN - 1))); - if (buf == NULL) - bzero(ti_winbase + (segptr & - (TI_WINLEN - 1)), segsize); - else { - bcopy(ptr, (char *)ti_winbase + - (segptr & (TI_WINLEN - 1)), segsize); + if (buf == NULL) { + bus_space_set_region_4(sc->ti_btag, sc->ti_bhandle, + TI_WINDOW + (segptr & (TI_WINLEN - 1)), 0, + segsize / 4); + } else { + 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; @@ -383,11 +380,11 @@ void ti_loadfw(sc) return; } ti_mem(sc, tigonFwTextAddr, tigonFwTextLen, - tigonFwText); + (caddr_t)tigonFwText); ti_mem(sc, tigonFwDataAddr, tigonFwDataLen, - tigonFwData); + (caddr_t)tigonFwData); ti_mem(sc, tigonFwRodataAddr, tigonFwRodataLen, - tigonFwRodata); + (caddr_t)tigonFwRodata); ti_mem(sc, tigonFwBssAddr, tigonFwBssLen, NULL); ti_mem(sc, tigonFwSbssAddr, tigonFwSbssLen, NULL); CSR_WRITE_4(sc, TI_CPU_PROGRAM_COUNTER, tigonFwStartAddr); @@ -404,11 +401,11 @@ void ti_loadfw(sc) return; } ti_mem(sc, tigon2FwTextAddr, tigon2FwTextLen, - tigon2FwText); + (caddr_t)tigon2FwText); ti_mem(sc, tigon2FwDataAddr, tigon2FwDataLen, - tigon2FwData); + (caddr_t)tigon2FwData); ti_mem(sc, tigon2FwRodataAddr, tigon2FwRodataLen, - tigon2FwRodata); + (caddr_t)tigon2FwRodata); ti_mem(sc, tigon2FwBssAddr, tigon2FwBssLen, NULL); ti_mem(sc, tigon2FwSbssAddr, tigon2FwSbssLen, NULL); CSR_WRITE_4(sc, TI_CPU_PROGRAM_COUNTER, tigon2FwStartAddr); @@ -431,7 +428,7 @@ void ti_cmd(sc, cmd) { u_int32_t index; - if (sc->ti_rdata->ti_cmd_ring == NULL) + if (sc->ti_cmd_ring == NULL) return; index = sc->ti_cmd_saved_prodidx; @@ -454,9 +451,9 @@ void ti_cmd_ext(sc, cmd, arg, len) int len; { u_int32_t index; - register int i; + int i; - if (sc->ti_rdata->ti_cmd_ring == NULL) + if (sc->ti_cmd_ring == NULL) return; index = sc->ti_cmd_saved_prodidx; @@ -486,18 +483,18 @@ void ti_handle_events(sc) 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; + sc->ti_linkstat = TI_EVENT_CODE(e); 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) printf("%s: invalid command\n", sc->sc_dv.dv_xname); - else if (e->ti_code == TI_EV_CODE_ERR_UNIMP_CMD) + else if (TI_EVENT_CODE(e) == TI_EV_CODE_ERR_UNIMP_CMD) printf("%s: unknown command\n", sc->sc_dv.dv_xname); - else if (e->ti_code == TI_EV_CODE_ERR_BADCFG) + else if (TI_EVENT_CODE(e) == TI_EV_CODE_ERR_BADCFG) printf("%s: bad config data\n", sc->sc_dv.dv_xname); break; @@ -512,8 +509,8 @@ void ti_handle_events(sc) /* Who cares. */ break; default: - printf("%s: unknown event: %d\n", - sc->sc_dv.dv_xname, e->ti_event); + printf("%s: unknown event: %d\n", sc->sc_dv.dv_xname, + TI_EVENT_EVENT(e)); break; } /* Advance the consumer index. */ @@ -552,7 +549,6 @@ int ti_alloc_jumbo_mem(sc) { caddr_t ptr, kva; bus_dma_segment_t seg; - bus_dmamap_t dmamap; int i, rseg; struct ti_jpool_entry *entry; @@ -569,25 +565,26 @@ int ti_alloc_jumbo_mem(sc) bus_dmamem_free(sc->sc_dmatag, &seg, rseg); return (ENOBUFS); } - if (bus_dmamap_create(sc->sc_dmatag, TI_JMEM, 1, - TI_JMEM, 0, BUS_DMA_NOWAIT, &dmamap)) { + if (bus_dmamap_create(sc->sc_dmatag, TI_JMEM, 1, TI_JMEM, 0, + BUS_DMA_NOWAIT, &sc->ti_cdata.ti_rx_jumbo_map)) { printf("%s: can't create dma map\n", sc->sc_dv.dv_xname); bus_dmamem_unmap(sc->sc_dmatag, kva, TI_JMEM); bus_dmamem_free(sc->sc_dmatag, &seg, rseg); return (ENOBUFS); } - if (bus_dmamap_load(sc->sc_dmatag, dmamap, kva, TI_JMEM, - NULL, BUS_DMA_NOWAIT)) { + if (bus_dmamap_load(sc->sc_dmatag, sc->ti_cdata.ti_rx_jumbo_map, kva, + TI_JMEM, NULL, BUS_DMA_NOWAIT)) { printf("%s: can't load dma map\n", sc->sc_dv.dv_xname); - bus_dmamap_destroy(sc->sc_dmatag, dmamap); + bus_dmamap_destroy(sc->sc_dmatag, + sc->ti_cdata.ti_rx_jumbo_map); bus_dmamem_unmap(sc->sc_dmatag, kva, TI_JMEM); bus_dmamem_free(sc->sc_dmatag, &seg, rseg); return (ENOBUFS); } sc->ti_cdata.ti_jumbo_buf = (caddr_t)kva; - LIST_INIT(&sc->ti_jfree_listhead); - LIST_INIT(&sc->ti_jinuse_listhead); + SLIST_INIT(&sc->ti_jfree_listhead); + SLIST_INIT(&sc->ti_jinuse_listhead); /* * Now divide it up into 9K pieces and save the addresses @@ -601,8 +598,10 @@ int ti_alloc_jumbo_mem(sc) entry = malloc(sizeof(struct ti_jpool_entry), M_DEVBUF, M_NOWAIT); if (entry == NULL) { - bus_dmamap_unload(sc->sc_dmatag, dmamap); - bus_dmamap_destroy(sc->sc_dmatag, dmamap); + bus_dmamap_unload(sc->sc_dmatag, + sc->ti_cdata.ti_rx_jumbo_map); + bus_dmamap_destroy(sc->sc_dmatag, + sc->ti_cdata.ti_rx_jumbo_map); bus_dmamem_unmap(sc->sc_dmatag, kva, TI_JMEM); bus_dmamem_free(sc->sc_dmatag, &seg, rseg); sc->ti_cdata.ti_jumbo_buf = NULL; @@ -611,7 +610,7 @@ int ti_alloc_jumbo_mem(sc) return(ENOBUFS); } entry->slot = i; - LIST_INSERT_HEAD(&sc->ti_jfree_listhead, entry, jpool_entries); + SLIST_INSERT_HEAD(&sc->ti_jfree_listhead, entry, jpool_entries); } return(0); @@ -625,15 +624,15 @@ void *ti_jalloc(sc) { struct ti_jpool_entry *entry; - entry = LIST_FIRST(&sc->ti_jfree_listhead); + entry = SLIST_FIRST(&sc->ti_jfree_listhead); if (entry == NULL) { printf("%s: no free jumbo buffers\n", sc->sc_dv.dv_xname); return(NULL); } - LIST_REMOVE(entry, jpool_entries); - LIST_INSERT_HEAD(&sc->ti_jinuse_listhead, entry, jpool_entries); + SLIST_REMOVE_HEAD(&sc->ti_jinuse_listhead, jpool_entries); + SLIST_INSERT_HEAD(&sc->ti_jinuse_listhead, entry, jpool_entries); sc->ti_cdata.ti_jslots[entry->slot].ti_inuse = 1; return(sc->ti_cdata.ti_jslots[entry->slot].ti_buf); } @@ -647,9 +646,9 @@ ti_jfree(buf, size, arg) u_int size; void *arg; { - struct ti_softc *sc; - int i; - struct ti_jpool_entry *entry; + struct ti_softc *sc; + int i; + struct ti_jpool_entry *entry; /* Extract the softc struct pointer. */ sc = (struct ti_softc *)arg; @@ -664,31 +663,45 @@ ti_jfree(buf, size, arg) panic("ti_jfree: asked to free buffer that we don't manage!"); else if (sc->ti_cdata.ti_jslots[i].ti_inuse == 0) panic("ti_jfree: buffer already free!"); - else { - sc->ti_cdata.ti_jslots[i].ti_inuse--; - if(sc->ti_cdata.ti_jslots[i].ti_inuse == 0) { - entry = LIST_FIRST(&sc->ti_jinuse_listhead); - if (entry == NULL) - panic("ti_jfree: buffer not in use!"); - entry->slot = i; - LIST_REMOVE(entry, jpool_entries); - LIST_INSERT_HEAD(&sc->ti_jfree_listhead, - entry, jpool_entries); - } + + sc->ti_cdata.ti_jslots[i].ti_inuse--; + if(sc->ti_cdata.ti_jslots[i].ti_inuse == 0) { + entry = SLIST_FIRST(&sc->ti_jinuse_listhead); + if (entry == NULL) + panic("ti_jfree: buffer not in use!"); + entry->slot = i; + SLIST_REMOVE_HEAD(&sc->ti_jinuse_listhead, jpool_entries); + SLIST_INSERT_HEAD(&sc->ti_jfree_listhead, + entry, jpool_entries); } } /* * Intialize a standard receive ring descriptor. */ -int ti_newbuf_std(sc, i, m) +int ti_newbuf_std(sc, i, m, dmamap) struct ti_softc *sc; int i; struct mbuf *m; + bus_dmamap_t dmamap; { struct mbuf *m_new = NULL; struct ti_rx_desc *r; + if (dmamap == NULL) { + /* if (m) panic() */ + + if (bus_dmamap_create(sc->sc_dmatag, MCLBYTES, 1, MCLBYTES, + 0, BUS_DMA_NOWAIT, &dmamap)) { + printf("%s: can't create recv map\n", + sc->sc_dv.dv_xname); + return(ENOMEM); + } + } else if (m == NULL) + bus_dmamap_unload(sc->sc_dmatag, dmamap); + + sc->ti_cdata.ti_rx_std_map[i] = dmamap; + if (m == NULL) { MGETHDR(m_new, M_DONTWAIT, MT_DATA); if (m_new == NULL) { @@ -705,21 +718,33 @@ int ti_newbuf_std(sc, i, m) return(ENOBUFS); } m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; + + m_adj(m_new, ETHER_ALIGN); + + if (bus_dmamap_load_mbuf(sc->sc_dmatag, dmamap, m_new, + BUS_DMA_NOWAIT)) + return(ENOBUFS); + } else { m_new = m; m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; m_new->m_data = m_new->m_ext.ext_buf; + m_adj(m_new, ETHER_ALIGN); } - m_adj(m_new, ETHER_ALIGN); sc->ti_cdata.ti_rx_std_chain[i] = m_new; r = &sc->ti_rdata->ti_rx_std_ring[i]; - TI_HOSTADDR(r->ti_addr) = vtophys(mtod(m_new, caddr_t)); + TI_HOSTADDR(r->ti_addr) = dmamap->dm_segs[0].ds_addr; r->ti_type = TI_BDTYPE_RECV_BD; r->ti_flags = TI_BDFLAG_IP_CKSUM; - r->ti_len = MCLBYTES; + r->ti_len = dmamap->dm_segs[0].ds_len; r->ti_idx = i; + if ((dmamap->dm_segs[0].ds_addr & ~(MCLBYTES - 1)) != + ((dmamap->dm_segs[0].ds_addr + dmamap->dm_segs[0].ds_len - 1) & + ~(MCLBYTES - 1))) + panic("overwritten!!!\n"); + return(0); } @@ -727,14 +752,29 @@ int ti_newbuf_std(sc, i, m) * Intialize a mini receive ring descriptor. This only applies to * the Tigon 2. */ -int ti_newbuf_mini(sc, i, m) +int ti_newbuf_mini(sc, i, m, dmamap) struct ti_softc *sc; int i; struct mbuf *m; + bus_dmamap_t dmamap; { struct mbuf *m_new = NULL; struct ti_rx_desc *r; + if (dmamap == NULL) { + /* if (m) panic() */ + + if (bus_dmamap_create(sc->sc_dmatag, MHLEN, 1, MHLEN, + 0, BUS_DMA_NOWAIT, &dmamap)) { + printf("%s: can't create recv map\n", + sc->sc_dv.dv_xname); + return(ENOMEM); + } + } else if (m == NULL) + bus_dmamap_unload(sc->sc_dmatag, dmamap); + + sc->ti_cdata.ti_rx_mini_map[i] = dmamap; + if (m == NULL) { MGETHDR(m_new, M_DONTWAIT, MT_DATA); if (m_new == NULL) { @@ -743,19 +783,24 @@ int ti_newbuf_mini(sc, i, m) return(ENOBUFS); } m_new->m_len = m_new->m_pkthdr.len = MHLEN; + m_adj(m_new, ETHER_ALIGN); + + if (bus_dmamap_load_mbuf(sc->sc_dmatag, dmamap, m_new, + BUS_DMA_NOWAIT)) + return(ENOBUFS); + } else { m_new = m; m_new->m_data = m_new->m_pktdat; m_new->m_len = m_new->m_pkthdr.len = MHLEN; } - m_adj(m_new, ETHER_ALIGN); r = &sc->ti_rdata->ti_rx_mini_ring[i]; sc->ti_cdata.ti_rx_mini_chain[i] = m_new; - TI_HOSTADDR(r->ti_addr) = vtophys(mtod(m_new, caddr_t)); + TI_HOSTADDR(r->ti_addr) = dmamap->dm_segs[0].ds_addr; r->ti_type = TI_BDTYPE_RECV_BD; r->ti_flags = TI_BDFLAG_MINI_RING | TI_BDFLAG_IP_CKSUM; - r->ti_len = m_new->m_len; + r->ti_len = dmamap->dm_segs[0].ds_len; r->ti_idx = i; return(0); @@ -811,7 +856,7 @@ int ti_newbuf_jumbo(sc, i, m) /* Set up the descriptor. */ r = &sc->ti_rdata->ti_rx_jumbo_ring[i]; sc->ti_cdata.ti_rx_jumbo_chain[i] = m_new; - TI_HOSTADDR(r->ti_addr) = vtophys(mtod(m_new, caddr_t)); + TI_HOSTADDR(r->ti_addr) = TI_JUMBO_DMA_ADDR(sc, m_new); r->ti_type = TI_BDTYPE_RECV_JUMBO_BD; r->ti_flags = TI_BDFLAG_JUMBO_RING | TI_BDFLAG_IP_CKSUM; r->ti_len = m_new->m_len; @@ -829,13 +874,13 @@ int ti_newbuf_jumbo(sc, i, m) int ti_init_rx_ring_std(sc) struct ti_softc *sc; { - register int i; + int i; struct ti_cmd_desc cmd; for (i = 0; i < TI_SSLOTS; i++) { - if (ti_newbuf_std(sc, i, NULL) == ENOBUFS) + if (ti_newbuf_std(sc, i, NULL, 0) == ENOBUFS) return(ENOBUFS); - }; + } TI_UPDATE_STDPROD(sc, i - 1); sc->ti_std = i - 1; @@ -846,12 +891,15 @@ int ti_init_rx_ring_std(sc) void ti_free_rx_ring_std(sc) struct ti_softc *sc; { - register int i; + int i; for (i = 0; i < TI_STD_RX_RING_CNT; i++) { if (sc->ti_cdata.ti_rx_std_chain[i] != NULL) { m_freem(sc->ti_cdata.ti_rx_std_chain[i]); sc->ti_cdata.ti_rx_std_chain[i] = NULL; + bus_dmamap_destroy(sc->sc_dmatag, + sc->ti_cdata.ti_rx_std_map[i]); + sc->ti_cdata.ti_rx_std_map[i] = 0; } bzero((char *)&sc->ti_rdata->ti_rx_std_ring[i], sizeof(struct ti_rx_desc)); @@ -863,7 +911,7 @@ void ti_free_rx_ring_std(sc) int ti_init_rx_ring_jumbo(sc) struct ti_softc *sc; { - register int i; + int i; struct ti_cmd_desc cmd; for (i = 0; i < TI_JUMBO_RX_RING_CNT; i++) { @@ -880,7 +928,7 @@ int ti_init_rx_ring_jumbo(sc) void ti_free_rx_ring_jumbo(sc) struct ti_softc *sc; { - register int i; + int i; for (i = 0; i < TI_JUMBO_RX_RING_CNT; i++) { if (sc->ti_cdata.ti_rx_jumbo_chain[i] != NULL) { @@ -897,10 +945,10 @@ void ti_free_rx_ring_jumbo(sc) int ti_init_rx_ring_mini(sc) struct ti_softc *sc; { - register int i; + int i; for (i = 0; i < TI_MSLOTS; i++) { - if (ti_newbuf_mini(sc, i, NULL) == ENOBUFS) + if (ti_newbuf_mini(sc, i, NULL, 0) == ENOBUFS) return(ENOBUFS); }; @@ -913,12 +961,15 @@ int ti_init_rx_ring_mini(sc) void ti_free_rx_ring_mini(sc) struct ti_softc *sc; { - register int i; + int i; for (i = 0; i < TI_MINI_RX_RING_CNT; i++) { if (sc->ti_cdata.ti_rx_mini_chain[i] != NULL) { m_freem(sc->ti_cdata.ti_rx_mini_chain[i]); sc->ti_cdata.ti_rx_mini_chain[i] = NULL; + bus_dmamap_destroy(sc->sc_dmatag, + sc->ti_cdata.ti_rx_mini_map[i]); + sc->ti_cdata.ti_rx_mini_map[i] = 0; } bzero((char *)&sc->ti_rdata->ti_rx_mini_ring[i], sizeof(struct ti_rx_desc)); @@ -930,7 +981,8 @@ void ti_free_rx_ring_mini(sc) void ti_free_tx_ring(sc) struct ti_softc *sc; { - register int i; + int i; + struct ti_txmap_entry *entry; if (sc->ti_rdata->ti_tx_ring == NULL) return; @@ -939,20 +991,49 @@ void ti_free_tx_ring(sc) if (sc->ti_cdata.ti_tx_chain[i] != NULL) { m_freem(sc->ti_cdata.ti_tx_chain[i]); sc->ti_cdata.ti_tx_chain[i] = NULL; + SLIST_INSERT_HEAD(&sc->ti_tx_map_listhead, + sc->ti_cdata.ti_tx_map[i], link); + sc->ti_cdata.ti_tx_map[i] = 0; } bzero((char *)&sc->ti_rdata->ti_tx_ring[i], sizeof(struct ti_tx_desc)); } + while ((entry = SLIST_FIRST(&sc->ti_tx_map_listhead))) { + SLIST_REMOVE_HEAD(&sc->ti_tx_map_listhead, link); + bus_dmamap_destroy(sc->sc_dmatag, entry->dmamap); + free(entry, M_DEVBUF); + } + return; } int ti_init_tx_ring(sc) struct ti_softc *sc; { + int i; + bus_dmamap_t dmamap; + struct ti_txmap_entry *entry; + sc->ti_txcnt = 0; sc->ti_tx_saved_considx = 0; CSR_WRITE_4(sc, TI_MB_SENDPROD_IDX, 0); + + SLIST_INIT(&sc->ti_tx_map_listhead); + for (i = 0; i < TI_TX_RING_CNT; i++) { + if (bus_dmamap_create(sc->sc_dmatag, MCLBYTES, TI_NTXSEG, + MCLBYTES, 0, BUS_DMA_NOWAIT, &dmamap)) + return(ENOBUFS); + + entry = malloc(sizeof(*entry), M_DEVBUF, M_NOWAIT); + if (!entry) { + bus_dmamap_destroy(sc->sc_dmatag, dmamap); + return (ENOBUFS); + } + entry->dmamap = dmamap; + SLIST_INSERT_HEAD(&sc->ti_tx_map_listhead, entry, link); + } + return(0); } @@ -1043,8 +1124,7 @@ void ti_setmulti(sc) struct ti_cmd_desc cmd; struct ti_mc_entry *mc; u_int32_t intrs; - struct ti_mc_entry *p; - + ifp = &sc->arpcom.ac_if; if (ifp->if_flags & IFF_ALLMULTI) { @@ -1059,13 +1139,10 @@ void ti_setmulti(sc) CSR_WRITE_4(sc, TI_MB_HOSTINTR, 1); /* First, zot all the existing filters. */ - p = LIST_FIRST(&sc->ti_mc_listhead); - while (p != NULL) { - mc = p; + while (SLIST_FIRST(&sc->ti_mc_listhead) != NULL) { + mc = SLIST_FIRST(&sc->ti_mc_listhead); ti_del_mcast(sc, &mc->mc_addr); - p = LIST_FIRST(&sc->ti_mc_listhead); - LIST_REMOVE(mc, mc_entries); - p = LIST_NEXT(p, mc_entries); + SLIST_REMOVE_HEAD(&sc->ti_mc_listhead, mc_entries); free(mc, M_DEVBUF); } @@ -1076,7 +1153,7 @@ void ti_setmulti(sc) if (mc == NULL) panic("ti_setmulti"); bcopy(enm->enm_addrlo, (char *)&mc->mc_addr, ETHER_ADDR_LEN); - LIST_INSERT_HEAD(&sc->ti_mc_listhead, mc, mc_entries); + SLIST_INSERT_HEAD(&sc->ti_mc_listhead, mc, mc_entries); ti_add_mcast(sc, &mc->mc_addr); ETHER_NEXT_MULTI(step, enm); } @@ -1128,7 +1205,7 @@ int ti_chipinit(sc) sc->ti_linkstat = TI_EV_CODE_LINK_DOWN; /* 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 @@ -1274,8 +1351,13 @@ int ti_gibinit(sc) CSR_WRITE_4(sc, TI_MB_HOSTINTR, 1); /* Tell the chip where to find the general information block. */ +#ifdef __64_bit_pci_addressing__ + CSR_WRITE_4(sc, TI_GCR_GENINFO_HI, TI_RING_DMA_ADDR(sc, ti_info)>>32); +#else CSR_WRITE_4(sc, TI_GCR_GENINFO_HI, 0); - CSR_WRITE_4(sc, TI_GCR_GENINFO_LO, vtophys(&sc->ti_rdata->ti_info)); +#endif + CSR_WRITE_4(sc, TI_GCR_GENINFO_LO, + TI_RING_DMA_ADDR(sc, ti_info) & 0xffffffff); /* Load the firmware into SRAM. */ ti_loadfw(sc); @@ -1285,10 +1367,10 @@ int ti_gibinit(sc) /* Set up the event ring and producer pointer. */ rcb = &sc->ti_rdata->ti_info.ti_ev_rcb; - TI_HOSTADDR(rcb->ti_hostaddr) = vtophys(&sc->ti_rdata->ti_event_ring); + TI_HOSTADDR(rcb->ti_hostaddr) = TI_RING_DMA_ADDR(sc, ti_event_ring); rcb->ti_flags = 0; TI_HOSTADDR(sc->ti_rdata->ti_info.ti_ev_prodidx_ptr) = - vtophys(&sc->ti_ev_prodidx); + TI_RING_DMA_ADDR(sc, ti_ev_prodidx_r); sc->ti_ev_prodidx.ti_idx = 0; CSR_WRITE_4(sc, TI_GCR_EVENTCONS_IDX, 0); sc->ti_ev_saved_considx = 0; @@ -1296,7 +1378,7 @@ int ti_gibinit(sc) /* Set up the command ring and producer mailbox. */ rcb = &sc->ti_rdata->ti_info.ti_cmd_rcb; - sc->ti_rdata->ti_cmd_ring = + sc->ti_cmd_ring = (struct ti_cmd_desc *)(sc->ti_bhandle + TI_GCR_CMDRING); TI_HOSTADDR(rcb->ti_hostaddr) = TI_GCR_NIC_ADDR(TI_GCR_CMDRING); rcb->ti_flags = 0; @@ -1314,12 +1396,13 @@ int ti_gibinit(sc) * conserve memory. */ TI_HOSTADDR(sc->ti_rdata->ti_info.ti_refresh_stats_ptr) = - vtophys(&sc->ti_rdata->ti_info.ti_stats); + TI_RING_DMA_ADDR(sc, ti_info.ti_stats); /* Set up the standard receive ring. */ rcb = &sc->ti_rdata->ti_info.ti_std_rx_rcb; - TI_HOSTADDR(rcb->ti_hostaddr) = vtophys(&sc->ti_rdata->ti_rx_std_ring); - rcb->ti_max_len = TI_FRAMELEN; + TI_HOSTADDR(rcb->ti_hostaddr) = + TI_RING_DMA_ADDR(sc, ti_rx_std_ring); + rcb->ti_max_len = ETHER_MAX_LEN; rcb->ti_flags = 0; rcb->ti_flags |= TI_RCB_FLAG_IP_CKSUM | TI_RCB_FLAG_NO_PHDR_CKSUM; #if NVLAN > 0 @@ -1328,8 +1411,7 @@ int ti_gibinit(sc) /* Set up the jumbo receive ring. */ rcb = &sc->ti_rdata->ti_info.ti_jumbo_rx_rcb; - TI_HOSTADDR(rcb->ti_hostaddr) = - vtophys(&sc->ti_rdata->ti_rx_jumbo_ring); + TI_HOSTADDR(rcb->ti_hostaddr) = TI_RING_DMA_ADDR(sc, ti_rx_jumbo_ring); rcb->ti_max_len = TI_JUMBO_FRAMELEN; rcb->ti_flags = 0; rcb->ti_flags |= TI_RCB_FLAG_IP_CKSUM | TI_RCB_FLAG_NO_PHDR_CKSUM; @@ -1343,8 +1425,7 @@ int ti_gibinit(sc) * still there on the Tigon 1. */ rcb = &sc->ti_rdata->ti_info.ti_mini_rx_rcb; - TI_HOSTADDR(rcb->ti_hostaddr) = - vtophys(&sc->ti_rdata->ti_rx_mini_ring); + TI_HOSTADDR(rcb->ti_hostaddr) = TI_RING_DMA_ADDR(sc, ti_rx_mini_ring); rcb->ti_max_len = MHLEN - ETHER_ALIGN; if (sc->ti_hwrev == TI_HWREV_TIGON) rcb->ti_flags = TI_RCB_FLAG_RING_DISABLED; @@ -1359,12 +1440,11 @@ int ti_gibinit(sc) * Set up the receive return ring. */ rcb = &sc->ti_rdata->ti_info.ti_return_rcb; - TI_HOSTADDR(rcb->ti_hostaddr) = - vtophys(&sc->ti_rdata->ti_rx_return_ring); + TI_HOSTADDR(rcb->ti_hostaddr) = TI_RING_DMA_ADDR(sc,ti_rx_return_ring); rcb->ti_flags = 0; rcb->ti_max_len = TI_RETURN_RING_CNT; TI_HOSTADDR(sc->ti_rdata->ti_info.ti_return_prodidx_ptr) = - vtophys(&sc->ti_return_prodidx); + TI_RING_DMA_ADDR(sc, ti_return_prodidx_r); /* * Set up the tx ring. Note: for the Tigon 2, we have the option @@ -1377,7 +1457,7 @@ int ti_gibinit(sc) */ CSR_WRITE_4(sc, TI_WINBASE, TI_TX_RING_BASE); if (sc->ti_hwrev == TI_HWREV_TIGON) { - sc->ti_rdata->ti_tx_ring_nic = + sc->ti_tx_ring_nic = (struct ti_tx_desc *)(sc->ti_bhandle + TI_WINDOW); } bzero((char *)sc->ti_rdata->ti_tx_ring, @@ -1396,9 +1476,11 @@ int ti_gibinit(sc) TI_HOSTADDR(rcb->ti_hostaddr) = TI_TX_RING_BASE; else TI_HOSTADDR(rcb->ti_hostaddr) = - vtophys(&sc->ti_rdata->ti_tx_ring); + TI_RING_DMA_ADDR(sc, ti_tx_ring); TI_HOSTADDR(sc->ti_rdata->ti_info.ti_tx_considx_ptr) = - vtophys(&sc->ti_tx_considx); + TI_RING_DMA_ADDR(sc, ti_tx_considx_r); + + TI_RING_DMASYNC(sc, ti_info, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); /* Set up tuneables */ if (ifp->if_mtu > (ETHERMTU + ETHER_HDR_LEN + ETHER_CRC_LEN)) @@ -1460,7 +1542,6 @@ ti_attach(parent, self, aux) bus_addr_t iobase; bus_size_t iosize; bus_dma_segment_t seg; - bus_dmamap_t dmamap; int s, rseg; u_int32_t command; struct ifnet *ifp; @@ -1557,16 +1638,17 @@ ti_attach(parent, self, aux) goto fail; } if (bus_dmamap_create(sc->sc_dmatag, sizeof(struct ti_ring_data), 1, - sizeof(struct ti_ring_data), 0, BUS_DMA_NOWAIT, &dmamap)) { + sizeof(struct ti_ring_data), 0, BUS_DMA_NOWAIT, + &sc->ti_ring_map)) { printf("%s: can't create dma map\n", sc->sc_dv.dv_xname); bus_dmamem_unmap(sc->sc_dmatag, kva, sizeof(struct ti_ring_data)); bus_dmamem_free(sc->sc_dmatag, &seg, rseg); goto fail; } - if (bus_dmamap_load(sc->sc_dmatag, dmamap, kva, + if (bus_dmamap_load(sc->sc_dmatag, sc->ti_ring_map, kva, sizeof(struct ti_ring_data), NULL, BUS_DMA_NOWAIT)) { - bus_dmamap_destroy(sc->sc_dmatag, dmamap); + bus_dmamap_destroy(sc->sc_dmatag, sc->ti_ring_map); bus_dmamem_unmap(sc->sc_dmatag, kva, sizeof(struct ti_ring_data)); bus_dmamem_free(sc->sc_dmatag, &seg, rseg); @@ -1692,6 +1774,7 @@ void ti_rxeof(sc) #ifdef TI_CSUM_OFFLOAD struct ip *ip; #endif + bus_dmamap_t dmamap; cur_rx = &sc->ti_rdata->ti_rx_return_ring[sc->ti_rx_saved_considx]; @@ -1723,28 +1806,34 @@ void ti_rxeof(sc) TI_INC(sc->ti_mini, TI_MINI_RX_RING_CNT); m = sc->ti_cdata.ti_rx_mini_chain[rxidx]; sc->ti_cdata.ti_rx_mini_chain[rxidx] = NULL; + dmamap = sc->ti_cdata.ti_rx_mini_map[rxidx]; + sc->ti_cdata.ti_rx_mini_map[rxidx] = 0; if (cur_rx->ti_flags & TI_BDFLAG_ERROR) { ifp->if_ierrors++; - ti_newbuf_mini(sc, sc->ti_mini, m); + ti_newbuf_mini(sc, sc->ti_mini, m, dmamap); continue; } - if (ti_newbuf_mini(sc, sc->ti_mini, NULL) == ENOBUFS) { + if (ti_newbuf_mini(sc, sc->ti_mini, NULL, dmamap) + == ENOBUFS) { ifp->if_ierrors++; - ti_newbuf_mini(sc, sc->ti_mini, m); + ti_newbuf_mini(sc, sc->ti_mini, m, dmamap); continue; } } else { TI_INC(sc->ti_std, TI_STD_RX_RING_CNT); m = sc->ti_cdata.ti_rx_std_chain[rxidx]; sc->ti_cdata.ti_rx_std_chain[rxidx] = NULL; + dmamap = sc->ti_cdata.ti_rx_std_map[rxidx]; + sc->ti_cdata.ti_rx_std_map[rxidx] = 0; if (cur_rx->ti_flags & TI_BDFLAG_ERROR) { ifp->if_ierrors++; - ti_newbuf_std(sc, sc->ti_std, m); + ti_newbuf_std(sc, sc->ti_std, m, dmamap); continue; } - if (ti_newbuf_std(sc, sc->ti_std, NULL) == ENOBUFS) { + if (ti_newbuf_std(sc, sc->ti_std, NULL, dmamap) + == ENOBUFS) { ifp->if_ierrors++; - ti_newbuf_std(sc, sc->ti_std, m); + ti_newbuf_std(sc, sc->ti_std, m, dmamap); continue; } } @@ -1800,6 +1889,7 @@ void ti_txeof(sc) { struct ti_tx_desc *cur_tx = NULL; struct ifnet *ifp; + struct ti_txmap_entry *entry; ifp = &sc->arpcom.ac_if; @@ -1824,7 +1914,7 @@ void ti_txeof(sc) else CSR_WRITE_4(sc, TI_WINBASE, TI_TX_RING_BASE); - cur_tx = &sc->ti_rdata->ti_tx_ring_nic[idx % 128]; + cur_tx = &sc->ti_tx_ring_nic[idx % 128]; } else cur_tx = &sc->ti_rdata->ti_tx_ring[idx]; if (cur_tx->ti_flags & TI_BDFLAG_END) @@ -1832,6 +1922,15 @@ void ti_txeof(sc) if (sc->ti_cdata.ti_tx_chain[idx] != NULL) { m_freem(sc->ti_cdata.ti_tx_chain[idx]); sc->ti_cdata.ti_tx_chain[idx] = NULL; + + entry = sc->ti_cdata.ti_tx_map[idx]; + bus_dmamap_sync(sc->sc_dmatag, entry->dmamap, 0, + entry->dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE); + + bus_dmamap_unload(sc->sc_dmatag, entry->dmamap); + SLIST_INSERT_HEAD(&sc->ti_tx_map_listhead, entry, link); + sc->ti_cdata.ti_tx_map[idx] = NULL; + } sc->ti_txcnt--; TI_INC(sc->ti_tx_saved_considx, TI_TX_RING_CNT); @@ -1884,17 +1983,19 @@ void ti_stats_update(sc) struct ti_softc *sc; { struct ifnet *ifp; + struct ti_stats *stats = &sc->ti_rdata->ti_info.ti_stats; ifp = &sc->arpcom.ac_if; - 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; + TI_RING_DMASYNC(sc, ti_info.ti_stats, BUS_DMASYNC_POSTREAD); - return; + ifp->if_collisions += stats->dot3StatsSingleCollisionFrames + + stats->dot3StatsMultipleCollisionFrames + + stats->dot3StatsExcessiveCollisions + + stats->dot3StatsLateCollisions - + ifp->if_collisions; + + TI_RING_DMASYNC(sc, ti_info.ti_stats, BUS_DMASYNC_PREREAD); } /* @@ -1907,8 +2008,10 @@ int ti_encap(sc, m_head, txidx) u_int32_t *txidx; { struct ti_tx_desc *f = NULL; - struct mbuf *m; u_int32_t frag, cur, cnt = 0; + struct ti_txmap_entry *entry; + bus_dmamap_t txmap; + int i = 0; #if NVLAN > 0 struct ifvlan *ifv = NULL; @@ -1917,7 +2020,11 @@ int ti_encap(sc, m_head, txidx) ifv = m_head->m_pkthdr.rcvif->if_softc; #endif - m = m_head; + entry = SLIST_FIRST(&sc->ti_tx_map_listhead); + if (entry == NULL) + return ENOBUFS; + txmap = entry->dmamap; + cur = frag = *txidx; /* @@ -1925,61 +2032,71 @@ int ti_encap(sc, m_head, txidx) * the fragment pointers. Stop when we run out * of fragments or hit the end of the mbuf chain. */ - for (m = m_head; m != NULL; m = m->m_next) { - if (m->m_len != 0) { - if (sc->ti_hwrev == TI_HWREV_TIGON) { - if (frag > 383) - CSR_WRITE_4(sc, TI_WINBASE, + if (bus_dmamap_load_mbuf(sc->sc_dmatag, txmap, m_head, + BUS_DMA_NOWAIT)) + return(ENOBUFS); + + for (i = 0; i < txmap->dm_nsegs; i++) { + 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, + 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, + else if (frag > 127) + CSR_WRITE_4(sc, TI_WINBASE, TI_TX_RING_BASE + 2048); - else - CSR_WRITE_4(sc, TI_WINBASE, + else + CSR_WRITE_4(sc, TI_WINBASE, TI_TX_RING_BASE); - f = &sc->ti_rdata->ti_tx_ring_nic[frag % 128]; - } else - f = &sc->ti_rdata->ti_tx_ring[frag]; - if (sc->ti_cdata.ti_tx_chain[frag] != NULL) - break; - TI_HOSTADDR(f->ti_addr) = vtophys(mtod(m, vm_offset_t)); - f->ti_len = m->m_len; - f->ti_flags = 0; + f = &sc->ti_tx_ring_nic[frag % 128]; + } else + f = &sc->ti_rdata->ti_tx_ring[frag]; + + if (sc->ti_cdata.ti_tx_chain[frag] != NULL) + break; + + TI_HOSTADDR(f->ti_addr) = txmap->dm_segs[i].ds_addr; + f->ti_len = txmap->dm_segs[i].ds_len & 0xffff; + f->ti_flags = 0; #if NVLAN > 0 - if (ifv != NULL) { - f->ti_flags |= TI_BDFLAG_VLAN_TAG; - f->ti_vlan_tag = ifv->ifv_tag & 0xfff; - } else { - f->ti_vlan_tag = 0; - } -#endif - /* - * Sanity check: avoid coming within 16 descriptors - * of the end of the ring. - */ - if ((TI_TX_RING_CNT - (sc->ti_txcnt + cnt)) < 16) - return(ENOBUFS); - cur = frag; - TI_INC(frag, TI_TX_RING_CNT); - cnt++; + if (ifv != NULL) { + f->ti_flags |= TI_BDFLAG_VLAN_TAG; + f->ti_vlan_tag = ifv->ifv_tag & 0xfff; + } else { + f->ti_vlan_tag = 0; } +#endif + /* + * Sanity check: avoid coming within 16 descriptors + * of the end of the ring. + */ + if ((TI_TX_RING_CNT - (sc->ti_txcnt + cnt)) < 16) + return(ENOBUFS); + cur = frag; + TI_INC(frag, TI_TX_RING_CNT); + cnt++; } - if (m != NULL) - return(ENOBUFS); - if (frag == sc->ti_tx_saved_considx) return(ENOBUFS); if (sc->ti_hwrev == TI_HWREV_TIGON) - sc->ti_rdata->ti_tx_ring_nic[cur % 128].ti_flags |= - TI_BDFLAG_END; + sc->ti_tx_ring_nic[cur % 128].ti_flags |= TI_BDFLAG_END; else sc->ti_rdata->ti_tx_ring[cur].ti_flags |= TI_BDFLAG_END; + + bus_dmamap_sync(sc->sc_dmatag, txmap, 0, txmap->dm_mapsize, + BUS_DMASYNC_PREWRITE); + + if (sc->ti_hwrev == TI_HWREV_TIGON_II) + TI_RING_DMASYNC(sc, ti_tx_ring[cur], BUS_DMASYNC_POSTREAD); + + sc->ti_cdata.ti_tx_chain[cur] = m_head; + SLIST_REMOVE_HEAD(&sc->ti_tx_map_listhead, link); + sc->ti_cdata.ti_tx_map[cur] = entry; sc->ti_txcnt += cnt; *txidx = frag; diff --git a/sys/dev/pci/if_tireg.h b/sys/dev/pci/if_tireg.h index 16d93abde87..bd29ce6ecb3 100644 --- a/sys/dev/pci/if_tireg.h +++ b/sys/dev/pci/if_tireg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_tireg.h,v 1.11 2002/10/04 01:25:21 jason Exp $ */ +/* $OpenBSD: if_tireg.h,v 1.12 2002/12/04 17:32:30 nate Exp $ */ /* * Copyright (c) 1997, 1998, 1999 @@ -54,39 +54,6 @@ #define TI_PCI_INT PCI_INTLINE /* - * Alteon AceNIC PCI vendor/device ID. - */ -#define ALT_VENDORID 0x12AE -#define ALT_DEVICEID_ACENIC 0x0001 -#define ALT_DEVICEID_ACENIC_COPPER 0x0002 - -/* - * 3Com 3c985 PCI vendor/device ID. - */ -#define TC_VENDORID 0x10B7 -#define TC_DEVICEID_3C985 0x0001 - -/* - * Netgear GA620 PCI vendor/device ID. - */ -#define NG_VENDORID 0x1385 -#define NG_DEVICEID_GA620 0x620A -#define NG_DEVICEID_GA620T 0x630A - -/* - * SGI device/vendor ID. - */ -#define SGI_VENDORID 0x10A9 -#define SGI_DEVICEID_TIGON 0x0009 - -/* - * DEC vendor ID, Farallon device ID. Apparently, Farallon used - * the DEC vendor ID in their cards by mistake. - */ -#define DEC_VENDORID 0x1011 -#define DEC_DEVICEID_FARALLON_PN9000SX 0x001a - -/* * Tigon configuration and control registers. */ #define TI_MISC_HOST_CTL 0x040 @@ -312,7 +279,7 @@ #define TI_GCR_RXRETURNCONS_IDX 0x680 #define TI_GCR_CMDRING 0x700 -#define TI_GCR_NIC_ADDR(x) (x - TI_GCR_BASE); +#define TI_GCR_NIC_ADDR(x) (x - TI_GCR_BASE) /* * Local memory window. The local memory window is a 2K shared @@ -880,17 +847,13 @@ struct ti_tx_desc { * 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 @@ -938,15 +901,11 @@ struct ti_cmd_desc { * 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); /* @@ -976,18 +935,14 @@ struct ti_cmd_desc { * 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. */ @@ -1015,15 +970,15 @@ struct ti_event_desc { */ #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 @@ -1036,7 +991,8 @@ struct ti_event_desc { #define TI_JSLOTS 384 #define TI_JRAWLEN (TI_JUMBO_FRAMELEN + ETHER_ALIGN) -#define TI_JLEN TI_JRAWLEN +#define TI_JLEN (TI_JRAWLEN + (sizeof(u_int64_t) - \ + (TI_JRAWLEN % sizeof(u_int64_t)))) #define TI_JPAGESZ PAGE_SIZE #define TI_RESID (TI_JPAGESZ - (TI_JLEN * TI_JSLOTS) % TI_JPAGESZ) #define TI_JMEM ((TI_JLEN * TI_JSLOTS) + TI_RESID) @@ -1059,6 +1015,7 @@ struct ti_ring_data { struct ti_rx_desc ti_rx_return_ring[TI_RETURN_RING_CNT]; struct ti_event_desc ti_event_ring[TI_EVENT_RING_CNT]; struct ti_tx_desc ti_tx_ring[TI_TX_RING_CNT]; + /* * Make sure producer structures are aligned on 32-byte cache * line boundaries. @@ -1069,11 +1026,36 @@ struct ti_ring_data { u_int32_t ti_pad1[6]; struct ti_producer ti_tx_considx_r; u_int32_t ti_pad2[6]; - struct ti_tx_desc *ti_tx_ring_nic;/* pointer to shared mem */ - struct ti_cmd_desc *ti_cmd_ring; /* pointer to shared mem */ struct ti_gib ti_info; }; +#define TI_RING_DMA_ADDR(sc, offset) \ + ((sc)->ti_ring_map->dm_segs[0].ds_addr + \ + offsetof(struct ti_ring_data, offset)) + +#define TI_RING_DMASYNC(sc, offset, op) \ + bus_dmamap_sync((sc)->sc_dmatag, (sc)->ti_ring_map, \ + offsetof(struct ti_ring_data, offset), \ + sizeof(((struct ti_ring_data *)0)->offset), (op)) + +/* + * Number of DMA segments in a TxCB. Note that this is carefully + * chosen to make the total struct size an even power of two. It's + * critical that no TxCB be split across a page boundry since + * no attempt is made to allocate physically contiguous memory. + * + */ +#ifdef __alpha__ /* XXX - should be conditional on pointer size */ +#define TI_NTXSEG 30 +#else +#define TI_NTXSEG 31 +#endif + +struct ti_txmap_entry { + bus_dmamap_t dmamap; + SLIST_ENTRY(ti_txmap_entry) link; +}; + /* * Mbuf pointers. We need these to keep track of the virtual addresses * of our mbuf chains since we can only convert from physical to virtual, @@ -1084,11 +1066,21 @@ struct ti_chain_data { struct mbuf *ti_rx_std_chain[TI_STD_RX_RING_CNT]; struct mbuf *ti_rx_jumbo_chain[TI_JUMBO_RX_RING_CNT]; struct mbuf *ti_rx_mini_chain[TI_MINI_RX_RING_CNT]; + + struct ti_txmap_entry *ti_tx_map[TI_TX_RING_CNT]; + bus_dmamap_t ti_rx_std_map[TI_STD_RX_RING_CNT]; + bus_dmamap_t ti_rx_jumbo_map; + bus_dmamap_t ti_rx_mini_map[TI_MINI_RX_RING_CNT]; + /* Stick the jumbo mem management stuff here too. */ struct ti_jslot ti_jslots[TI_JSLOTS]; void *ti_jumbo_buf; }; +#define TI_JUMBO_DMA_ADDR(sc, m) \ + ((sc)->ti_cdata.ti_rx_jumbo_map->dm_segs[0].ds_addr + \ + (mtod((m), char *) - (char *)(sc)->ti_cdata.ti_jumbo_buf)) + struct ti_type { u_int16_t ti_vid; u_int16_t ti_did; @@ -1102,12 +1094,12 @@ struct ti_type { struct ti_mc_entry { struct ether_addr mc_addr; - LIST_ENTRY(ti_mc_entry) mc_entries; + SLIST_ENTRY(ti_mc_entry) mc_entries; }; struct ti_jpool_entry { int slot; - LIST_ENTRY(ti_jpool_entry) jpool_entries; + SLIST_ENTRY(ti_jpool_entry) jpool_entries; }; struct ti_softc { @@ -1126,6 +1118,9 @@ struct ti_softc { #define ti_ev_prodidx ti_rdata->ti_ev_prodidx_r #define ti_return_prodidx ti_rdata->ti_return_prodidx_r #define ti_tx_considx ti_rdata->ti_tx_considx_r + struct ti_tx_desc *ti_tx_ring_nic;/* pointer to shared mem */ + struct ti_cmd_desc *ti_cmd_ring; /* pointer to shared mem */ + bus_dmamap_t ti_ring_map; u_int16_t ti_tx_saved_considx; u_int16_t ti_rx_saved_considx; u_int16_t ti_ev_saved_considx; @@ -1133,9 +1128,10 @@ struct ti_softc { u_int16_t ti_std; /* current std ring head */ u_int16_t ti_mini; /* current mini ring head */ u_int16_t ti_jumbo; /* current jumo ring head */ - LIST_HEAD(__ti_mchead, ti_mc_entry) ti_mc_listhead; - LIST_HEAD(__ti_jfreehead, ti_jpool_entry) ti_jfree_listhead; - LIST_HEAD(__ti_jinusehead, ti_jpool_entry) ti_jinuse_listhead; + SLIST_HEAD(__ti_mchead, ti_mc_entry) ti_mc_listhead; + SLIST_HEAD(__ti_jfreehead, ti_jpool_entry) ti_jfree_listhead; + SLIST_HEAD(__ti_jinusehead, ti_jpool_entry) ti_jinuse_listhead; + SLIST_HEAD(__ti_txmaphead, ti_txmap_entry) ti_tx_map_listhead; u_int32_t ti_stat_ticks; u_int32_t ti_rx_coal_ticks; u_int32_t ti_tx_coal_ticks; |