summaryrefslogtreecommitdiffstats
path: root/sys/dev/ste/if_stereg.h
diff options
context:
space:
mode:
authoryongari <yongari@FreeBSD.org>2009-12-22 18:57:07 +0000
committeryongari <yongari@FreeBSD.org>2009-12-22 18:57:07 +0000
commita9158a088f06d0cb2559e534b4a69eb52ef67a16 (patch)
tree845edfbb0f2b5a2852a9b0e8d80a796f14d323ab /sys/dev/ste/if_stereg.h
parent0b6e1af80169a0913b1faa4fa4c0454d5e803ec3 (diff)
downloadFreeBSD-src-a9158a088f06d0cb2559e534b4a69eb52ef67a16.zip
FreeBSD-src-a9158a088f06d0cb2559e534b4a69eb52ef67a16.tar.gz
Add bus_dma(9) and endianness support to ste(4).
o Sorted includes and added missing header files. o Added basic endianness support. In theory ste(4) should work on any architectures. o Remove the use of contigmalloc(9), contigfree(9) and vtophys(9). o Added 8 byte alignment limitation of TX/RX descriptor. o Added 1 byte alignment requirement for TX/RX buffers. o ste(4) controllers does not support DAC. Limit DMA address space to be within 32bit address. o Added spare DMA map to gracefully recover from DMA map failure. o Removed dead code for checking STE_RXSTAT_DMADONE bit. The bit was already checked in each iteration of loop so it can't be true. o Added second argument count to ste_rxeof(). It is used to limit number of iterations done in RX handler. ATM polling is the only consumer. o Removed ste_rxeoc() which was added to address RX stuck issue (cvs rev 1.66). Unlike TX descriptors, ST201 supports chaining descriptors to form a ring for RX descriptors. If RX descriptor chaining is not supported it's possible for controller to stop receiving incoming frames once controller pass the end of RX descriptor which in turn requires driver post new RX descriptors to receive more frames. For TX descriptors which does not support chaning, we exactly do manual chaining in driver by concatenating new descriptors to the end of previous TX chain. Maybe the workaround was borrowed from other drivers that does not support RX descriptor chaining, which is not valid for ST201 controllers. I still have no idea how this address RX stuck issue and I can't reproduce the RX stuck issue on DFE-550TX controller. o Removed hw.ste_rxsyncs sysctl as the workaround was removed. o TX/RX side bus_dmamap_load_mbuf_sg(9) support. o Reimplemented optimized ste_encap(). o Simplified TX logic of ste_start_locked(). o Added comments for TFD/RFD requirements. o Increased number of RX descriptors to 128 from 64. 128 gave much better performance than 64 under high network loads.
Diffstat (limited to 'sys/dev/ste/if_stereg.h')
-rw-r--r--sys/dev/ste/if_stereg.h59
1 files changed, 47 insertions, 12 deletions
diff --git a/sys/dev/ste/if_stereg.h b/sys/dev/ste/if_stereg.h
index 8de1961..49c52aa 100644
--- a/sys/dev/ste/if_stereg.h
+++ b/sys/dev/ste/if_stereg.h
@@ -412,6 +412,14 @@ struct ste_frag {
#define STE_FRAG_LAST 0x80000000
#define STE_FRAG_LEN 0x00001FFF
+/*
+ * A TFD is 16 to 512 bytes in length which means it can have up to 126
+ * fragments for a single Tx frame. Since most frames used in stack have
+ * 3-4 fragments supporting 8 fragments would be enough for normal
+ * operation. If we encounter more than 8 fragments we'll collapse them
+ * into a frame that has less than or equal to 8 fragments. Each buffer
+ * address of a fragment has no alignment limitation.
+ */
#define STE_MAXFRAGS 8
struct ste_desc {
@@ -420,6 +428,12 @@ struct ste_desc {
struct ste_frag ste_frags[STE_MAXFRAGS];
};
+/*
+ * A RFD has the same structure of TFD which in turn means hardware
+ * supports scatter operation in Rx buffer. Since we just allocate Rx
+ * buffer with m_getcl(9) there is no fragmentation at all so use
+ * single fragment for RFD.
+ */
struct ste_desc_onefrag {
uint32_t ste_next;
uint32_t ste_status;
@@ -427,6 +441,7 @@ struct ste_desc_onefrag {
};
#define STE_TXCTL_WORDALIGN 0x00000003
+#define STE_TXCTL_ALIGN_DIS 0x00000001
#define STE_TXCTL_FRAMEID 0x000003FC
#define STE_TXCTL_NOCRC 0x00002000
#define STE_TXCTL_TXINTR 0x00008000
@@ -445,6 +460,8 @@ struct ste_desc_onefrag {
#define STE_RXSTAT_DMA_OFLOW 0x01000000
#define STE_RXATAT_ONEBUF 0x10000000
+#define STE_RX_BYTES(x) ((x) & STE_RXSTAT_FRAMELEN)
+
/*
* register space access macros
*/
@@ -462,13 +479,22 @@ struct ste_desc_onefrag {
#define CSR_READ_1(sc, reg) \
bus_space_read_1(sc->ste_btag, sc->ste_bhandle, reg)
+#define STE_DESC_ALIGN 8
+#define STE_RX_LIST_CNT 128
+#define STE_TX_LIST_CNT 128
+#define STE_RX_LIST_SZ \
+ (sizeof(struct ste_desc_onefrag) * STE_RX_LIST_CNT)
+#define STE_TX_LIST_SZ \
+ (sizeof(struct ste_desc) * STE_TX_LIST_CNT)
+#define STE_ADDR_LO(x) ((uint64_t)(x) & 0xFFFFFFFF)
+#define STE_ADDR_HI(x) ((uint64_t)(x) >> 32)
+
+#define STE_TX_TIMEOUT 5
#define STE_TIMEOUT 1000
#define STE_MIN_FRAMELEN 60
#define STE_PACKET_SIZE 1536
-#define ETHER_ALIGN 2
-#define STE_RX_LIST_CNT 64
-#define STE_TX_LIST_CNT 128
#define STE_INC(x, y) (x) = (x + 1) % y
+#define STE_DEC(x, y) (x) = ((x) + ((y) - 1)) % (y)
#define STE_NEXT(x, y) (x + 1) % y
struct ste_type {
@@ -478,8 +504,10 @@ struct ste_type {
};
struct ste_list_data {
- struct ste_desc_onefrag ste_rx_list[STE_RX_LIST_CNT];
- struct ste_desc ste_tx_list[STE_TX_LIST_CNT];
+ struct ste_desc_onefrag *ste_rx_list;
+ bus_addr_t ste_rx_list_paddr;
+ struct ste_desc *ste_tx_list;
+ bus_addr_t ste_tx_list_paddr;
};
struct ste_chain {
@@ -487,21 +515,32 @@ struct ste_chain {
struct mbuf *ste_mbuf;
struct ste_chain *ste_next;
uint32_t ste_phys;
+ bus_dmamap_t ste_map;
};
struct ste_chain_onefrag {
struct ste_desc_onefrag *ste_ptr;
struct mbuf *ste_mbuf;
struct ste_chain_onefrag *ste_next;
+ bus_dmamap_t ste_map;
};
struct ste_chain_data {
+ bus_dma_tag_t ste_parent_tag;
+ bus_dma_tag_t ste_rx_tag;
+ bus_dma_tag_t ste_tx_tag;
+ bus_dma_tag_t ste_rx_list_tag;
+ bus_dmamap_t ste_rx_list_map;
+ bus_dma_tag_t ste_tx_list_tag;
+ bus_dmamap_t ste_tx_list_map;
+ bus_dmamap_t ste_rx_sparemap;
struct ste_chain_onefrag ste_rx_chain[STE_RX_LIST_CNT];
- struct ste_chain ste_tx_chain[STE_TX_LIST_CNT];
+ struct ste_chain ste_tx_chain[STE_TX_LIST_CNT];
struct ste_chain_onefrag *ste_rx_head;
-
+ struct ste_chain *ste_last_tx;
int ste_tx_prod;
int ste_tx_cons;
+ int ste_tx_cnt;
};
struct ste_softc {
@@ -518,15 +557,11 @@ struct ste_softc {
uint8_t ste_link;
int ste_if_flags;
int ste_timer;
- struct ste_chain *ste_tx_prev;
- struct ste_list_data *ste_ldata;
+ struct ste_list_data ste_ldata;
struct ste_chain_data ste_cdata;
struct callout ste_stat_callout;
struct mtx ste_mtx;
uint8_t ste_one_phy;
-#ifdef DEVICE_POLLING
- int rxcycles;
-#endif
};
#define STE_LOCK(_sc) mtx_lock(&(_sc)->ste_mtx)
OpenPOWER on IntegriCloud