diff options
author | yongari <yongari@FreeBSD.org> | 2010-09-01 19:33:40 +0000 |
---|---|---|
committer | yongari <yongari@FreeBSD.org> | 2010-09-01 19:33:40 +0000 |
commit | 0b65f62811c036da9558dd96e4d6cfe2b0eaf4a3 (patch) | |
tree | be2f826e05ba54db57d123f4b9a7a4fc7c5f80ac /sys/dev/sis/if_sisreg.h | |
parent | 7c4a1c6ffa87ae5de930013b66531289fbb45818 (diff) | |
download | FreeBSD-src-0b65f62811c036da9558dd96e4d6cfe2b0eaf4a3.zip FreeBSD-src-0b65f62811c036da9558dd96e4d6cfe2b0eaf4a3.tar.gz |
bus_dma(9) cleanup.
o Enforce TX/RX descriptor ring alignment. NS data sheet says the
controller needs 4 bytes alignment but use 16 to cover both SiS
and NS controllers. I don't have SiS data sheet so I'm not sure
what is alignment restriction of SiS controller but 16 would be
enough because it's larger than the size of a TX/RX descriptor.
Previously sis(4) ignored the alignment restriction.
o Enforce RX buffer alignment, 4.
Previously sis(4) ignored RX buffer alignment restriction.
o Limit number of TX DMA segment to be used to 16. It seems
controller has no restriction on number of DMA segments but
using more than 16 looks resource waste.
o Collapse long mbuf chains with m_collapse(9) instead of calling
expensive m_defrag(9).
o TX/RX side bus_dmamap_load_mbuf_sg(9) support and remove
unnecessary callbacks.
o Initial endianness support.
o Prefer local alignment fixup code to m_devget(9).
o Pre-allocate TX/RX mbuf DMA maps instead of creating/destroying
these maps in fast TX/RX path. On non-x86 architectures, this is
very expensive operation and there is no need to do that.
o Add missing bus_dmamap_sync(9) in TX/RX path.
o watchdog is now unarmed only when there are no pending frames
on controller. Previously sis(4) blindly unarmed watchdog
without checking the number of queued frames.
o For efficiency, loaded DMA map is reused for error frames.
o DMA map loading failure is now gracefully handled. Previously
sis(4) ignored any DMA map loading errors.
o Nuke unused macros which are not appropriate for endianness
operation.
o Stop embedding driver maintained structures into descriptor
rings. Because TX/RX descriptor structures are shared between
host and controller, frequent bus_dmamap_sync(9) operations are
required in fast path. Embedding driver structures will increase
the size of DMA map which in turn will slow down performance.
Diffstat (limited to 'sys/dev/sis/if_sisreg.h')
-rw-r--r-- | sys/dev/sis/if_sisreg.h | 61 |
1 files changed, 36 insertions, 25 deletions
diff --git a/sys/dev/sis/if_sisreg.h b/sys/dev/sis/if_sisreg.h index 455c598..2f23304 100644 --- a/sys/dev/sis/if_sisreg.h +++ b/sys/dev/sis/if_sisreg.h @@ -304,25 +304,13 @@ #define NS_FILTADDR_FMEM_HI 0x000003FE /* - * DMA descriptor structures. The first part of the descriptor - * is the hardware descriptor format, which is just three longwords. - * After this, we include some additional structure members for - * use by the driver. Note that for this structure will be a different - * size on the alpha, but that's okay as long as it's a multiple of 4 - * bytes in size. + * TX/RX DMA descriptor structures. */ struct sis_desc { /* SiS hardware descriptor section */ u_int32_t sis_next; u_int32_t sis_cmdsts; -#define sis_rxstat sis_cmdsts -#define sis_txstat sis_cmdsts -#define sis_ctl sis_cmdsts u_int32_t sis_ptr; - /* Driver software section */ - struct mbuf *sis_mbuf; - struct sis_desc *sis_nextdesc; - bus_dmamap_t sis_map; }; #define SIS_CMDSTS_BUFLEN 0x00000FFF @@ -332,11 +320,6 @@ struct sis_desc { #define SIS_CMDSTS_MORE 0x40000000 #define SIS_CMDSTS_OWN 0x80000000 -#define SIS_LASTDESC(x) (!((x)->sis_ctl & SIS_CMDSTS_MORE)) -#define SIS_OWNDESC(x) ((x)->sis_ctl & SIS_CMDSTS_OWN) -#define SIS_INC(x, y) (x) = ((x) == ((y)-1)) ? 0 : (x)+1 -#define SIS_RXBYTES(x) (((x)->sis_ctl & SIS_CMDSTS_BUFLEN) - ETHER_CRC_LEN) - #define SIS_RXSTAT_COLL 0x00010000 #define SIS_RXSTAT_LOOPBK 0x00020000 #define SIS_RXSTAT_ALIGNERR 0x00040000 @@ -367,12 +350,25 @@ struct sis_desc { #define SIS_TXSTAT_UNDERRUN 0x02000000 #define SIS_TXSTAT_TX_ABORT 0x04000000 +#define SIS_DESC_ALIGN 16 +#define SIS_RX_BUF_ALIGN 4 +#define SIS_MAXTXSEGS 16 #define SIS_RX_LIST_CNT 64 #define SIS_TX_LIST_CNT 128 #define SIS_RX_LIST_SZ SIS_RX_LIST_CNT * sizeof(struct sis_desc) #define SIS_TX_LIST_SZ SIS_TX_LIST_CNT * sizeof(struct sis_desc) +#define SIS_ADDR_LO(x) ((uint64_t) (x) & 0xffffffff) +#define SIS_ADDR_HI(x) ((uint64_t) (x) >> 32) + +#define SIS_RX_RING_ADDR(sc, i) \ + ((sc)->sis_rx_paddr + sizeof(struct sis_desc) * (i)) +#define SIS_TX_RING_ADDR(sc, i) \ + ((sc)->sis_tx_paddr + sizeof(struct sis_desc) * (i)) + +#define SIS_INC(x, y) (x) = (x + 1) % (y) + /* * SiS PCI vendor ID. */ @@ -434,6 +430,17 @@ struct sis_mii_frame { #define SIS_TYPE_83815 3 #define SIS_TYPE_83816 4 +struct sis_txdesc { + struct mbuf *tx_m; + bus_dmamap_t tx_dmamap; +}; + +struct sis_rxdesc { + struct mbuf *rx_m; + bus_dmamap_t rx_dmamap; + struct sis_desc *rx_desc; +}; + struct sis_softc { struct ifnet *sis_ifp; /* interface info */ struct resource *sis_res[2]; @@ -446,18 +453,22 @@ struct sis_softc { u_int sis_srr; struct sis_desc *sis_rx_list; struct sis_desc *sis_tx_list; + bus_dma_tag_t sis_rx_list_tag; + bus_dmamap_t sis_rx_list_map; + bus_dma_tag_t sis_tx_list_tag; + bus_dmamap_t sis_tx_list_map; + bus_dma_tag_t sis_parent_tag; bus_dma_tag_t sis_rx_tag; - bus_dmamap_t sis_rx_dmamap; + bus_dmamap_t sis_rx_sparemap; bus_dma_tag_t sis_tx_tag; - bus_dmamap_t sis_tx_dmamap; - bus_dma_tag_t sis_parent_tag; - bus_dma_tag_t sis_tag; - struct sis_desc *sis_rx_pdsc; + struct sis_rxdesc sis_rxdesc[SIS_RX_LIST_CNT]; + struct sis_txdesc sis_txdesc[SIS_TX_LIST_CNT]; int sis_tx_prod; int sis_tx_cons; int sis_tx_cnt; - u_int32_t sis_rx_paddr; - u_int32_t sis_tx_paddr; + int sis_rx_cons;; + bus_addr_t sis_rx_paddr; + bus_addr_t sis_tx_paddr; struct callout sis_stat_ch; int sis_watchdog_timer; int sis_stopped; |