summaryrefslogtreecommitdiffstats
path: root/sys/pci
diff options
context:
space:
mode:
authoryongari <yongari@FreeBSD.org>2008-01-15 01:10:31 +0000
committeryongari <yongari@FreeBSD.org>2008-01-15 01:10:31 +0000
commit58dd567f36d3ec5b1a668bf7b21f447d1a0912ae (patch)
treeaa4ab8e7e3ccbce064954c51b59656f4f1dfce12 /sys/pci
parentdb1781cf23171042e8c97bf1e3707d9094c0c2a4 (diff)
downloadFreeBSD-src-58dd567f36d3ec5b1a668bf7b21f447d1a0912ae.zip
FreeBSD-src-58dd567f36d3ec5b1a668bf7b21f447d1a0912ae.tar.gz
Overhaul re(4).
o Increased number of Rx/Tx descriptors to 256 for 8169 GigEs because it's hard to push the hardware to the limit with default 64 descriptors. TSO requires large number of Tx descriptors to pass a full sized TCP segment(65535 bytes IP packet) to hardware. Previously it consumed 32 Tx descriptors, assuming MCLBYTES DMA segment size, to send the TCP segment which means re(4) couldn't queue more than two full sized IP packets. For 8139C+ it still uses 64 Rx/Tx descriptors due to its hardware limitations. With this changes there are (very) small waste of memory for 8139C+ users but I don't think it would affect 8139C+ users for most cases. o Various bus_dma(9) fixes. - The hardware supports DAC so allow 64bit DMA operations. - Removed BUS_DMA_ALLOC_NOW flag. - Increased DMA segment size to 4096 from MCLBYTES because TSO consumes too many descriptors with MCLBYTES DMA segment size. - Tx/Rx side bus_dmamap_load_mbuf_sg(9) support. With these changes the code is more readable than previous one and got a (slightly) better performance as it doesn't need to pass/ decode arguments to/from callback function. - Removed unnecessary callback function re_dmamap_desc() and nuked rl_dmaload_arg structure which was used in the callback. - Additional protection for DMA map load failure. In case of failure reuse current map instead of returning a bogus DMA map. - Deferred DMA map unloading/sync operation for maximum performance until we really need to load new DMA map. If we happen to reuse current map(e.g. input error) there is no need to sync/unload/load again. - The number of allowable Tx DMA segments for a mbuf chains are now 32 instead of magic nseg value. If the number of available Tx descriptors are short enough to send highly fragmented mbuf chains an optimized re_defrag() is called to collapse mbuf chains which is supposed to be much faster than m_defrag(9). re_defrag() was borrowed from ath(4). - Separated Rx/Tx DMA tag from a common DMA tag such that Rx DMA tag correctly uses DMA maps that were created with DMA alignment restriction(8bytes alignments). Tx DMA tag does not have such alignment limitation. - Added additional sanity checks for DMA ring map load failure. - Added additional spare Rx DMA map for graceful handling of Rx DMA map load failure. - Fixed misused bus_dmamap_sync(9) and added missing bus_dmamap_sync(9) in re_encap()/re_txeof()/re_rxeof(). o Enabled TSO again as re(4) have reasonable number of Tx descriptors. o Don't touch DMA address of a Tx descriptor in re_txeof(). It's not needed. o Fix incorrect update of if_ierrors counter. For Rx buffer shortage it should update if_qdrops as the buffer is reused. o Added checks for unsupported H/W revisions and return ENXIO for these hardwares. This is required to remove resource allocation code in re_probe as other drivers do in device probe routine. o Modified descriptor index manipulation macros as it's now possible to have different number of descriptors for Rx/Tx. o In re_start, to save a lock operation, use IFQ_DRV_IS_EMPTY before trying to invoke IFQ_DRV_DEQUEUE. Also don't blindly call re_encap since we already know the number of available Tx descriptors in advance. o Removed RL_TX_DESC_THLD which was used to reserve RL_TX_DESC_THLD descriptors in Tx path. There is no such a limitation mentioned in 8139C+/8169/8110/8168/8101/8111 datasheet and it seems to work ok without reserving RL_TX_DESC_THLD descriptors. o Fix a comment for RL_GTXSTART. The register is 8bits register. o Added comments for 8169/8139C+ hardware restrictions on descriptors. o Removed forward declaration for "struct rl_softc", it's not needed. o Added a new structure rl_txdesc for Tx descriptor managements and a structure rl_rxdesc for Rx descriptor managements. o Removed unused member variable rl_intlock in driver softc. There are still several unused member variables which are supposed to be used to access hardware statistics counters. But it seems that accessing hardware counters were not implemented yet.
Diffstat (limited to 'sys/pci')
-rw-r--r--sys/pci/if_rlreg.h60
1 files changed, 37 insertions, 23 deletions
diff --git a/sys/pci/if_rlreg.h b/sys/pci/if_rlreg.h
index fbfb65b..5b63290 100644
--- a/sys/pci/if_rlreg.h
+++ b/sys/pci/if_rlreg.h
@@ -128,7 +128,7 @@
#define RL_TBI_LPAR 0x006A
#define RL_GMEDIASTAT 0x006C /* 8 bits */
#define RL_MAXRXPKTLEN 0x00DA /* 16 bits, chip multiplies by 8 */
-#define RL_GTXSTART 0x0038 /* 16 bits */
+#define RL_GTXSTART 0x0038 /* 8 bits */
/*
* TX config register bits
@@ -636,24 +636,35 @@ struct rl_stats {
/*
* Rx/Tx descriptor parameters (8139C+ and 8169 only)
*
- * Tx/Rx count must be equal. Shared code like re_dma_map_desc assumes this.
- * Buffers must be a multiple of 8 bytes. Currently limit to 64 descriptors
- * due to the 8139C+. We need to put the number of descriptors in the ring
- * structure and use that value instead.
+ * 8139C+
+ * Number of descriptors supported : up to 64
+ * Descriptor alignment : 256 bytes
+ * Tx buffer : At least 4 bytes in length.
+ * Rx buffer : At least 8 bytes in length and 8 bytes alignment required.
+ *
+ * 8169
+ * Number of descriptors supported : up to 1024
+ * Descriptor alignment : 256 bytes
+ * Tx buffer : At least 4 bytes in length.
+ * Rx buffer : At least 8 bytes in length and 8 bytes alignment required.
*/
#ifndef __NO_STRICT_ALIGNMENT
#define RE_FIXUP_RX 1
#endif
-#define RL_TX_DESC_CNT 64
-#define RL_TX_DESC_THLD 4
-#define RL_RX_DESC_CNT RL_TX_DESC_CNT
+#define RL_8169_TX_DESC_CNT 256
+#define RL_8169_RX_DESC_CNT 256
+#define RL_8139_TX_DESC_CNT 64
+#define RL_8139_RX_DESC_CNT 64
+#define RL_TX_DESC_CNT RL_8169_TX_DESC_CNT
+#define RL_RX_DESC_CNT RL_8169_RX_DESC_CNT
+#define RL_NTXSEGS 32
-#define RL_RX_LIST_SZ (RL_RX_DESC_CNT * sizeof(struct rl_desc))
-#define RL_TX_LIST_SZ (RL_TX_DESC_CNT * sizeof(struct rl_desc))
#define RL_RING_ALIGN 256
#define RL_IFQ_MAXLEN 512
-#define RL_DESC_INC(x) (x = (x + 1) % RL_TX_DESC_CNT)
+#define RL_TX_DESC_NXT(sc,x) ((x + 1) & ((sc)->rl_ldata.rl_tx_desc_cnt - 1))
+#define RL_TX_DESC_PRV(sc,x) ((x - 1) & ((sc)->rl_ldata.rl_tx_desc_cnt - 1))
+#define RL_RX_DESC_NXT(sc,x) ((x + 1) & ((sc)->rl_ldata.rl_rx_desc_cnt - 1))
#define RL_OWN(x) (le32toh((x)->rl_cmdstat) & RL_RDESC_STAT_OWN)
#define RL_RXBYTES(x) (le32toh((x)->rl_cmdstat) & sc->rl_rxlenmask)
#define RL_PKTSZ(x) ((x)/* >> 3*/)
@@ -674,25 +685,29 @@ struct rl_stats {
#define RL_JUMBO_FRAMELEN 7440
#define RL_JUMBO_MTU (RL_JUMBO_FRAMELEN-ETHER_HDR_LEN-ETHER_CRC_LEN)
-struct rl_softc;
+struct rl_txdesc {
+ struct mbuf *tx_m;
+ bus_dmamap_t tx_dmamap;
+};
-struct rl_dmaload_arg {
- int rl_idx;
- int rl_maxsegs;
- uint32_t rl_flags;
- struct rl_desc *rl_ring;
+struct rl_rxdesc {
+ struct mbuf *rx_m;
+ bus_dmamap_t rx_dmamap;
+ bus_size_t rx_size;
};
struct rl_list_data {
- struct mbuf *rl_tx_mbuf[RL_TX_DESC_CNT];
- struct mbuf *rl_rx_mbuf[RL_RX_DESC_CNT];
+ struct rl_txdesc rl_tx_desc[RL_TX_DESC_CNT];
+ struct rl_rxdesc rl_rx_desc[RL_RX_DESC_CNT];
+ int rl_tx_desc_cnt;
+ int rl_rx_desc_cnt;
int rl_tx_prodidx;
int rl_rx_prodidx;
int rl_tx_considx;
int rl_tx_free;
- bus_dmamap_t rl_tx_dmamap[RL_TX_DESC_CNT];
- bus_dmamap_t rl_rx_dmamap[RL_RX_DESC_CNT];
- bus_dma_tag_t rl_mtag; /* mbuf mapping tag */
+ bus_dma_tag_t rl_tx_mtag; /* mbuf TX mapping tag */
+ bus_dma_tag_t rl_rx_mtag; /* mbuf RX mapping tag */
+ bus_dmamap_t rl_rx_sparemap;
bus_dma_tag_t rl_stag; /* stats mapping tag */
bus_dmamap_t rl_smap; /* stats map */
struct rl_stats *rl_stats;
@@ -742,7 +757,6 @@ struct rl_softc {
struct task rl_txtask;
struct task rl_inttask;
- struct mtx rl_intlock;
int rl_txstart;
int rl_link;
int rl_msi;
OpenPOWER on IntegriCloud