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.
This commit is contained in:
Pyun YongHyeon 2010-09-01 19:33:40 +00:00
parent 1d885b48c1
commit a629f2b183
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=212109
2 changed files with 500 additions and 423 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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_tag;
bus_dmamap_t sis_rx_dmamap;
bus_dma_tag_t sis_tx_tag;
bus_dmamap_t sis_tx_dmamap;
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_tag;
struct sis_desc *sis_rx_pdsc;
bus_dma_tag_t sis_rx_tag;
bus_dmamap_t sis_rx_sparemap;
bus_dma_tag_t sis_tx_tag;
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;