Overhaul bus_dma(9) usage in driver:

- Don't use a single big DMA block for all rings. Create separate
   DMA area for each ring instead.  Currently the following DMA
   areas are created:
	Event ring, standard RX ring, jumbo RX ring, RX return ring,
	hardware MAC statistics and producer/consumer status area.
   For Tigon II, mini RX ring and TX ring are additionally created.
 - Added missing bus_dmamap_sync(9) in various TX/RX paths.
 - TX ring is no longer created for Tigon 1 such that it saves more
   resources on Tigon 1.
 - Data sheet is not clear about alignment requirement of each ring
   so use 32 bytes alignment for normal DMA area but use 64 bytes
   alignment for jumbo RX ring where the extended RX descriptor
   size is 64 bytes.
 - For each TX/RX buffers use separate DMA tag(e.g. the size of a
   DMA segment, total size of DMA segments etc).
 - Tigon allows separate DMA area for event producer, RX return
   producer and TX consumer which is really cool feature.  This
   means TX and RX path could be independently run in parallel.
   However ti(4) uses a single driver lock so it's meaningless
   to have separate DMA area for these producer/consumer such that
   this change creates a single status DMA area.
 - It seems Tigon has no limits on DMA address space and I also
   don't see any problem with that but old comments in driver
   indicates there could be issues on descriptors being located in
   64bit region.  Introduce a tunable, dev.ti.%d.dac, to disable
   using 64bit DMA in driver. The default is 0 which means it would
   use full 64bit DMA.  If there are DMA issues, users can disable
   it by setting the tunable to 0.
 - Do not increase watchdog timer in ti_txeof(). Previously driver
   increased the watchdog timer whenever there are queued TX frames.
 - When stat ticks is set to 0, skip processing ti_stats_update(),
   avoiding bus_dmamap_sync(9) and updating if_collisions counter.
 - MTU does not include FCS bytes, replace it with
   ETHER_VLAN_ENCAP_LEN.

With these changes, ti(4) should work on PAE environments.
Many thanks to Jay Borkenhagen for remote hardware access.
This commit is contained in:
yongari 2011-11-14 20:38:14 +00:00
parent 698932b695
commit 296e094bd8
2 changed files with 605 additions and 404 deletions

File diff suppressed because it is too large Load Diff

View File

@ -400,6 +400,8 @@
#define TI_RETURN_RING_CNT 2048
#define TI_MAXTXSEGS 32
#define TI_RING_ALIGN 32
#define TI_JUMBO_RING_ALIGN 64
/*
* Possible TX ring sizes.
@ -602,6 +604,10 @@ struct ti_rx_desc {
uint32_t ti_opaque;
};
#define TI_STD_RX_RING_SZ (sizeof(struct ti_rx_desc) * TI_STD_RX_RING_CNT)
#define TI_MINI_RX_RING_SZ (sizeof(struct ti_rx_desc) * TI_MINI_RX_RING_CNT)
#define TI_RX_RETURN_RING_SZ (sizeof(struct ti_rx_desc) * TI_RETURN_RING_CNT)
struct ti_rx_desc_ext {
ti_hostaddr ti_addr1;
ti_hostaddr ti_addr2;
@ -653,6 +659,14 @@ struct ti_rx_desc_ext {
uint32_t ti_opaque;
};
#ifdef TI_SF_BUF_JUMBO
#define TI_JUMBO_RX_RING_SZ \
(sizeof(struct ti_rx_desc_ext) * TI_JUMBO_RX_RING_CNT)
#else
#define TI_JUMBO_RX_RING_SZ \
(sizeof(struct ti_rx_desc) * TI_JUMBO_RX_RING_CNT)
#endif
/*
* Transmit descriptors are, mercifully, very small.
*/
@ -674,6 +688,8 @@ struct ti_tx_desc {
#endif
};
#define TI_TX_RING_SZ (sizeof(struct ti_tx_desc) * TI_TX_RING_CNT)
/*
* NOTE! On the Alpha, we have an alignment constraint.
* The first thing in the packet is a 14-byte Ethernet header.
@ -845,6 +861,7 @@ struct ti_event_desc {
uint32_t ti_eventx;
uint32_t ti_rsvd;
};
#define TI_EVENT_RING_SZ (sizeof(struct ti_event_desc) * TI_EVENT_RING_CNT)
#define TI_EVENT_EVENT(e) (((((e)->ti_eventx)) >> 24) & 0xff)
#define TI_EVENT_CODE(e) (((((e)->ti_eventx)) >> 12) & 0xfff)
@ -895,26 +912,12 @@ struct ti_txdesc {
STAILQ_HEAD(ti_txdq, ti_txdesc);
/*
* Ring structures. Most of these reside in host memory and we tell
* the NIC where they are via the ring control blocks. The exceptions
* are the tx and command rings, which live in NIC memory and which
* we access via the shared memory window.
*/
struct ti_ring_data {
struct ti_rx_desc ti_rx_std_ring[TI_STD_RX_RING_CNT];
#ifndef TI_SF_BUF_JUMBO
struct ti_rx_desc ti_rx_jumbo_ring[TI_JUMBO_RX_RING_CNT];
#else
struct ti_rx_desc_ext ti_rx_jumbo_ring[TI_JUMBO_RX_RING_CNT];
#endif
struct ti_rx_desc ti_rx_mini_ring[TI_MINI_RX_RING_CNT];
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];
struct ti_status {
/*
* Make sure producer structures are aligned on 32-byte cache
* line boundaries.
* line boundaries. We can create separate DMA area for each
* producer/consumer area but it wouldn't get much benefit
* since driver use a global driver lock.
*/
struct ti_producer ti_ev_prodidx_r;
uint32_t ti_pad0[6];
@ -922,10 +925,36 @@ struct ti_ring_data {
uint32_t ti_pad1[6];
struct ti_producer ti_tx_considx_r;
uint32_t ti_pad2[6];
struct ti_gib ti_info;
};
#define TI_RD_OFF(x) offsetof(struct ti_ring_data, x)
/*
* Ring structures. Most of these reside in host memory and we tell
* the NIC where they are via the ring control blocks. The exceptions
* are the tx and command rings, which live in NIC memory and which
* we access via the shared memory window.
*/
struct ti_ring_data {
struct ti_gib *ti_info;
bus_addr_t ti_info_paddr;
struct ti_status *ti_status;
bus_addr_t ti_status_paddr;
struct ti_rx_desc *ti_rx_std_ring;
bus_addr_t ti_rx_std_ring_paddr;
#ifdef TI_SF_BUF_JUMBO
struct ti_rx_desc_ext *ti_rx_jumbo_ring;
#else
struct ti_rx_desc *ti_rx_jumbo_ring;
#endif
bus_addr_t ti_rx_jumbo_ring_paddr;
struct ti_rx_desc *ti_rx_mini_ring;
bus_addr_t ti_rx_mini_ring_paddr;
struct ti_rx_desc *ti_rx_return_ring;
bus_addr_t ti_rx_return_ring_paddr;
struct ti_event_desc *ti_event_ring;
bus_addr_t ti_event_ring_paddr;
struct ti_tx_desc *ti_tx_ring;
bus_addr_t ti_tx_ring_paddr;
};
/*
* Mbuf pointers. We need these to keep track of the virtual addresses
@ -933,15 +962,36 @@ struct ti_ring_data {
* not the other way around.
*/
struct ti_chain_data {
bus_dma_tag_t ti_parent_tag;
bus_dma_tag_t ti_gib_tag;
bus_dmamap_t ti_gib_map;
bus_dma_tag_t ti_event_ring_tag;
bus_dmamap_t ti_event_ring_map;
bus_dma_tag_t ti_status_tag;
bus_dmamap_t ti_status_map;
bus_dma_tag_t ti_tx_ring_tag;
bus_dmamap_t ti_tx_ring_map;
bus_dma_tag_t ti_tx_tag;
struct ti_txdesc ti_txdesc[TI_TX_RING_CNT];
struct ti_txdq ti_txfreeq;
struct ti_txdq ti_txbusyq;
bus_dma_tag_t ti_rx_return_ring_tag;
bus_dmamap_t ti_rx_return_ring_map;
bus_dma_tag_t ti_rx_std_ring_tag;
bus_dmamap_t ti_rx_std_ring_map;
bus_dma_tag_t ti_rx_std_tag;
struct mbuf *ti_rx_std_chain[TI_STD_RX_RING_CNT];
bus_dmamap_t ti_rx_std_maps[TI_STD_RX_RING_CNT];
bus_dmamap_t ti_rx_std_sparemap;
bus_dma_tag_t ti_rx_jumbo_ring_tag;
bus_dmamap_t ti_rx_jumbo_ring_map;
bus_dma_tag_t ti_rx_jumbo_tag;
struct mbuf *ti_rx_jumbo_chain[TI_JUMBO_RX_RING_CNT];
bus_dmamap_t ti_rx_jumbo_maps[TI_JUMBO_RX_RING_CNT];
bus_dmamap_t ti_rx_jumbo_sparemap;
bus_dma_tag_t ti_rx_mini_ring_tag;
bus_dmamap_t ti_rx_mini_ring_map;
bus_dma_tag_t ti_rx_mini_tag;
struct mbuf *ti_rx_mini_chain[TI_MINI_RX_RING_CNT];
bus_dmamap_t ti_rx_mini_maps[TI_MINI_RX_RING_CNT];
bus_dmamap_t ti_rx_mini_sparemap;
@ -982,18 +1032,12 @@ struct ti_softc {
uint8_t ti_copper; /* 1000baseTX card */
uint8_t ti_linkstat; /* Link state */
int ti_hdrsplit; /* enable header splitting */
bus_dma_tag_t ti_parent_dmat;
bus_dma_tag_t ti_jumbo_dmat;
bus_dma_tag_t ti_mbuftx_dmat;
bus_dma_tag_t ti_mbufrx_dmat;
bus_dma_tag_t ti_rdata_dmat;
bus_dmamap_t ti_rdata_dmamap;
bus_addr_t ti_rdata_phys;
struct ti_ring_data *ti_rdata; /* rings */
int ti_dac;
struct ti_ring_data ti_rdata; /* rings */
struct ti_chain_data ti_cdata; /* mbufs */
#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
#define ti_ev_prodidx ti_rdata.ti_status->ti_ev_prodidx_r
#define ti_return_prodidx ti_rdata.ti_status->ti_return_prodidx_r
#define ti_tx_considx ti_rdata.ti_status->ti_tx_considx_r
int ti_tx_saved_prodidx;
int ti_tx_saved_considx;
int ti_rx_saved_considx;