1098ca2bdSWarner Losh /*- 2df57947fSPedro F. Giffuni * SPDX-License-Identifier: BSD-4-Clause 3df57947fSPedro F. Giffuni * 4a07bd003SBill Paul * Copyright (c) 2004 5a07bd003SBill Paul * Bill Paul <wpaul@windriver.com>. All rights reserved. 6a07bd003SBill Paul * 7a07bd003SBill Paul * Redistribution and use in source and binary forms, with or without 8a07bd003SBill Paul * modification, are permitted provided that the following conditions 9a07bd003SBill Paul * are met: 10a07bd003SBill Paul * 1. Redistributions of source code must retain the above copyright 11a07bd003SBill Paul * notice, this list of conditions and the following disclaimer. 12a07bd003SBill Paul * 2. Redistributions in binary form must reproduce the above copyright 13a07bd003SBill Paul * notice, this list of conditions and the following disclaimer in the 14a07bd003SBill Paul * documentation and/or other materials provided with the distribution. 15a07bd003SBill Paul * 3. All advertising materials mentioning features or use of this software 16a07bd003SBill Paul * must display the following acknowledgement: 17a07bd003SBill Paul * This product includes software developed by Bill Paul. 18a07bd003SBill Paul * 4. Neither the name of the author nor the names of any co-contributors 19a07bd003SBill Paul * may be used to endorse or promote products derived from this software 20a07bd003SBill Paul * without specific prior written permission. 21a07bd003SBill Paul * 22a07bd003SBill Paul * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 23a07bd003SBill Paul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24a07bd003SBill Paul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25a07bd003SBill Paul * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 26a07bd003SBill Paul * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27a07bd003SBill Paul * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28a07bd003SBill Paul * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29a07bd003SBill Paul * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30a07bd003SBill Paul * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31a07bd003SBill Paul * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 32a07bd003SBill Paul * THE POSSIBILITY OF SUCH DAMAGE. 33a07bd003SBill Paul */ 34a07bd003SBill Paul 35a07bd003SBill Paul #define VGE_JUMBO_MTU 9000 36a07bd003SBill Paul 37a07bd003SBill Paul #define VGE_TX_DESC_CNT 256 38410f4c60SPyun YongHyeon #define VGE_RX_DESC_CNT 252 /* Must be a multiple of 4!! */ 39410f4c60SPyun YongHyeon #define VGE_TX_RING_ALIGN 64 40410f4c60SPyun YongHyeon #define VGE_RX_RING_ALIGN 64 41410f4c60SPyun YongHyeon #define VGE_MAXTXSEGS 6 42564340e7SPyun YongHyeon #define VGE_RX_BUF_ALIGN sizeof(uint64_t) 43410f4c60SPyun YongHyeon 44410f4c60SPyun YongHyeon /* 45410f4c60SPyun YongHyeon * VIA Velocity allows 64bit DMA addressing but high 16bits 46410f4c60SPyun YongHyeon * of the DMA address should be the same for Tx/Rx buffers. 47410f4c60SPyun YongHyeon * Because this condition can't be guaranteed vge(4) limit 48410f4c60SPyun YongHyeon * DMA address space to 48bits. 49410f4c60SPyun YongHyeon */ 50410f4c60SPyun YongHyeon #if (BUS_SPACE_MAXADDR < 0xFFFFFFFFFF) 51410f4c60SPyun YongHyeon #define VGE_BUF_DMA_MAXADDR BUS_SPACE_MAXADDR 52410f4c60SPyun YongHyeon #else 53410f4c60SPyun YongHyeon #define VGE_BUF_DMA_MAXADDR 0xFFFFFFFFFFFF 54410f4c60SPyun YongHyeon #endif 55410f4c60SPyun YongHyeon 56a07bd003SBill Paul #define VGE_RX_LIST_SZ (VGE_RX_DESC_CNT * sizeof(struct vge_rx_desc)) 57a07bd003SBill Paul #define VGE_TX_LIST_SZ (VGE_TX_DESC_CNT * sizeof(struct vge_tx_desc)) 58410f4c60SPyun YongHyeon #define VGE_TX_DESC_INC(x) ((x) = ((x) + 1) % VGE_TX_DESC_CNT) 59410f4c60SPyun YongHyeon #define VGE_TX_DESC_DEC(x) \ 60410f4c60SPyun YongHyeon ((x) = (((x) + VGE_TX_DESC_CNT - 1) % VGE_TX_DESC_CNT)) 61410f4c60SPyun YongHyeon #define VGE_RX_DESC_INC(x) ((x) = ((x) + 1) % VGE_RX_DESC_CNT) 62410f4c60SPyun YongHyeon #define VGE_ADDR_LO(y) ((uint64_t) (y) & 0xFFFFFFFF) 63410f4c60SPyun YongHyeon #define VGE_ADDR_HI(y) ((uint64_t) (y) >> 32) 64410f4c60SPyun YongHyeon #define VGE_BUFLEN(y) ((y) & 0x3FFF) 65410f4c60SPyun YongHyeon #define VGE_RXBYTES(x) (((x) & VGE_RDSTS_BUFSIZ) >> 16) 66a07bd003SBill Paul #define VGE_MIN_FRAMELEN 60 67a07bd003SBill Paul 683b2b8afbSPyun YongHyeon #define VGE_INT_HOLDOFF_TICK 20 693b2b8afbSPyun YongHyeon #define VGE_INT_HOLDOFF_USEC(x) ((x) / VGE_INT_HOLDOFF_TICK) 703b2b8afbSPyun YongHyeon #define VGE_INT_HOLDOFF_MIN 0 713b2b8afbSPyun YongHyeon #define VGE_INT_HOLDOFF_MAX (255 * VGE_INT_HOLDOFF_TICK) 723b2b8afbSPyun YongHyeon #define VGE_INT_HOLDOFF_DEFAULT 150 733b2b8afbSPyun YongHyeon 743b2b8afbSPyun YongHyeon #define VGE_RX_COAL_PKT_MIN 1 753b2b8afbSPyun YongHyeon #define VGE_RX_COAL_PKT_MAX VGE_RX_DESC_CNT 763b2b8afbSPyun YongHyeon #define VGE_RX_COAL_PKT_DEFAULT 64 773b2b8afbSPyun YongHyeon 783b2b8afbSPyun YongHyeon #define VGE_TX_COAL_PKT_MIN 1 793b2b8afbSPyun YongHyeon #define VGE_TX_COAL_PKT_MAX VGE_TX_DESC_CNT 803b2b8afbSPyun YongHyeon #define VGE_TX_COAL_PKT_DEFAULT 128 813b2b8afbSPyun YongHyeon 82a07bd003SBill Paul struct vge_type { 83a07bd003SBill Paul uint16_t vge_vid; 84a07bd003SBill Paul uint16_t vge_did; 85a07bd003SBill Paul char *vge_name; 86a07bd003SBill Paul }; 87a07bd003SBill Paul 88410f4c60SPyun YongHyeon struct vge_txdesc { 89410f4c60SPyun YongHyeon struct mbuf *tx_m; 90410f4c60SPyun YongHyeon bus_dmamap_t tx_dmamap; 91410f4c60SPyun YongHyeon struct vge_tx_desc *tx_desc; 92410f4c60SPyun YongHyeon struct vge_txdesc *txd_prev; 93a07bd003SBill Paul }; 94a07bd003SBill Paul 95410f4c60SPyun YongHyeon struct vge_rxdesc { 96410f4c60SPyun YongHyeon struct mbuf *rx_m; 97410f4c60SPyun YongHyeon bus_dmamap_t rx_dmamap; 98410f4c60SPyun YongHyeon struct vge_rx_desc *rx_desc; 99410f4c60SPyun YongHyeon struct vge_rxdesc *rxd_prev; 100410f4c60SPyun YongHyeon }; 101410f4c60SPyun YongHyeon 102410f4c60SPyun YongHyeon struct vge_chain_data{ 103410f4c60SPyun YongHyeon bus_dma_tag_t vge_ring_tag; 104410f4c60SPyun YongHyeon bus_dma_tag_t vge_buffer_tag; 105410f4c60SPyun YongHyeon bus_dma_tag_t vge_tx_tag; 106410f4c60SPyun YongHyeon struct vge_txdesc vge_txdesc[VGE_TX_DESC_CNT]; 107410f4c60SPyun YongHyeon bus_dma_tag_t vge_rx_tag; 108410f4c60SPyun YongHyeon struct vge_rxdesc vge_rxdesc[VGE_RX_DESC_CNT]; 109410f4c60SPyun YongHyeon bus_dma_tag_t vge_tx_ring_tag; 110410f4c60SPyun YongHyeon bus_dmamap_t vge_tx_ring_map; 111410f4c60SPyun YongHyeon bus_dma_tag_t vge_rx_ring_tag; 112410f4c60SPyun YongHyeon bus_dmamap_t vge_rx_ring_map; 113410f4c60SPyun YongHyeon bus_dmamap_t vge_rx_sparemap; 114410f4c60SPyun YongHyeon 115a07bd003SBill Paul int vge_tx_prodidx; 116a07bd003SBill Paul int vge_tx_considx; 117410f4c60SPyun YongHyeon int vge_tx_cnt; 118410f4c60SPyun YongHyeon int vge_rx_prodidx; 119410f4c60SPyun YongHyeon int vge_rx_commit; 120410f4c60SPyun YongHyeon 121410f4c60SPyun YongHyeon struct mbuf *vge_head; 122410f4c60SPyun YongHyeon struct mbuf *vge_tail; 123410f4c60SPyun YongHyeon }; 124410f4c60SPyun YongHyeon 125410f4c60SPyun YongHyeon #define VGE_CHAIN_RESET(_sc) \ 126410f4c60SPyun YongHyeon do { \ 127410f4c60SPyun YongHyeon if ((_sc)->vge_cdata.vge_head != NULL) { \ 128410f4c60SPyun YongHyeon m_freem((_sc)->vge_cdata.vge_head); \ 129410f4c60SPyun YongHyeon (_sc)->vge_cdata.vge_head = NULL; \ 130410f4c60SPyun YongHyeon (_sc)->vge_cdata.vge_tail = NULL; \ 131410f4c60SPyun YongHyeon } \ 132410f4c60SPyun YongHyeon } while (0); 133410f4c60SPyun YongHyeon 134410f4c60SPyun YongHyeon struct vge_ring_data { 135410f4c60SPyun YongHyeon struct vge_tx_desc *vge_tx_ring; 136410f4c60SPyun YongHyeon bus_addr_t vge_tx_ring_paddr; 137410f4c60SPyun YongHyeon struct vge_rx_desc *vge_rx_ring; 138410f4c60SPyun YongHyeon bus_addr_t vge_rx_ring_paddr; 139a07bd003SBill Paul }; 140a07bd003SBill Paul 1417129fb20SPyun YongHyeon struct vge_hw_stats { 1427129fb20SPyun YongHyeon uint32_t rx_frames; 1437129fb20SPyun YongHyeon uint32_t rx_good_frames; 1447129fb20SPyun YongHyeon uint32_t rx_fifo_oflows; 1457129fb20SPyun YongHyeon uint32_t rx_runts; 1467129fb20SPyun YongHyeon uint32_t rx_runts_errs; 1477129fb20SPyun YongHyeon uint32_t rx_pkts_64; 1487129fb20SPyun YongHyeon uint32_t rx_pkts_65_127; 1497129fb20SPyun YongHyeon uint32_t rx_pkts_128_255; 1507129fb20SPyun YongHyeon uint32_t rx_pkts_256_511; 1517129fb20SPyun YongHyeon uint32_t rx_pkts_512_1023; 1527129fb20SPyun YongHyeon uint32_t rx_pkts_1024_1518; 1537129fb20SPyun YongHyeon uint32_t rx_pkts_1519_max; 1547129fb20SPyun YongHyeon uint32_t rx_pkts_1519_max_errs; 1557129fb20SPyun YongHyeon uint32_t rx_jumbos; 1567129fb20SPyun YongHyeon uint32_t rx_crcerrs; 1577129fb20SPyun YongHyeon uint32_t rx_pause_frames; 1587129fb20SPyun YongHyeon uint32_t rx_alignerrs; 1597129fb20SPyun YongHyeon uint32_t rx_nobufs; 1607129fb20SPyun YongHyeon uint32_t rx_symerrs; 1617129fb20SPyun YongHyeon uint32_t rx_lenerrs; 1627129fb20SPyun YongHyeon 1637129fb20SPyun YongHyeon uint32_t tx_good_frames; 1647129fb20SPyun YongHyeon uint32_t tx_pkts_64; 1657129fb20SPyun YongHyeon uint32_t tx_pkts_65_127; 1667129fb20SPyun YongHyeon uint32_t tx_pkts_128_255; 1677129fb20SPyun YongHyeon uint32_t tx_pkts_256_511; 1687129fb20SPyun YongHyeon uint32_t tx_pkts_512_1023; 1697129fb20SPyun YongHyeon uint32_t tx_pkts_1024_1518; 1707129fb20SPyun YongHyeon uint32_t tx_jumbos; 1717129fb20SPyun YongHyeon uint32_t tx_colls; 1727129fb20SPyun YongHyeon uint32_t tx_pause; 1737129fb20SPyun YongHyeon uint32_t tx_sqeerrs; 1747129fb20SPyun YongHyeon uint32_t tx_latecolls; 1757129fb20SPyun YongHyeon }; 1767129fb20SPyun YongHyeon 177a07bd003SBill Paul struct vge_softc { 178*3ac0cb32SJustin Hibbits if_t vge_ifp; /* interface info */ 179a07bd003SBill Paul device_t vge_dev; 180a07bd003SBill Paul struct resource *vge_res; 181a07bd003SBill Paul struct resource *vge_irq; 182a07bd003SBill Paul void *vge_intrhand; 183a07bd003SBill Paul device_t vge_miibus; 184a07bd003SBill Paul int vge_if_flags; 185643e9ee9SPyun YongHyeon int vge_phyaddr; 1864d7235ddSPyun YongHyeon int vge_flags; 187643e9ee9SPyun YongHyeon #define VGE_FLAG_PCIE 0x0001 1885957cc2aSPyun YongHyeon #define VGE_FLAG_MSI 0x0002 1897fc94bc4SPyun YongHyeon #define VGE_FLAG_PMCAP 0x0004 19033a0d70bSPyun YongHyeon #define VGE_FLAG_JUMBO 0x0008 191a931e549SPyun YongHyeon #define VGE_FLAG_SUSPENDED 0x4000 1924d7235ddSPyun YongHyeon #define VGE_FLAG_LINK 0x8000 193643e9ee9SPyun YongHyeon int vge_expcap; 194a07bd003SBill Paul int vge_camidx; 1953b2b8afbSPyun YongHyeon int vge_int_holdoff; 1963b2b8afbSPyun YongHyeon int vge_rx_coal_pkt; 1973b2b8afbSPyun YongHyeon int vge_tx_coal_pkt; 198a07bd003SBill Paul struct mtx vge_mtx; 19967e1dfa7SJohn Baldwin struct callout vge_watchdog; 20067e1dfa7SJohn Baldwin int vge_timer; 201a07bd003SBill Paul 202410f4c60SPyun YongHyeon struct vge_chain_data vge_cdata; 203410f4c60SPyun YongHyeon struct vge_ring_data vge_rdata; 2047129fb20SPyun YongHyeon struct vge_hw_stats vge_stats; 205a07bd003SBill Paul }; 206a07bd003SBill Paul 207a07bd003SBill Paul #define VGE_LOCK(_sc) mtx_lock(&(_sc)->vge_mtx) 208a07bd003SBill Paul #define VGE_UNLOCK(_sc) mtx_unlock(&(_sc)->vge_mtx) 209a07bd003SBill Paul #define VGE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->vge_mtx, MA_OWNED) 210a07bd003SBill Paul 211a07bd003SBill Paul /* 212a07bd003SBill Paul * register space access macros 213a07bd003SBill Paul */ 214a07bd003SBill Paul #define CSR_WRITE_STREAM_4(sc, reg, val) \ 215dc8ecaacSJohn Baldwin bus_write_stream_4(sc->vge_res, reg, val) 216a07bd003SBill Paul #define CSR_WRITE_4(sc, reg, val) \ 217dc8ecaacSJohn Baldwin bus_write_4(sc->vge_res, reg, val) 218a07bd003SBill Paul #define CSR_WRITE_2(sc, reg, val) \ 219dc8ecaacSJohn Baldwin bus_write_2(sc->vge_res, reg, val) 220a07bd003SBill Paul #define CSR_WRITE_1(sc, reg, val) \ 221dc8ecaacSJohn Baldwin bus_write_1(sc->vge_res, reg, val) 222a07bd003SBill Paul 223a07bd003SBill Paul #define CSR_READ_4(sc, reg) \ 224dc8ecaacSJohn Baldwin bus_read_4(sc->vge_res, reg) 225a07bd003SBill Paul #define CSR_READ_2(sc, reg) \ 226dc8ecaacSJohn Baldwin bus_read_2(sc->vge_res, reg) 227a07bd003SBill Paul #define CSR_READ_1(sc, reg) \ 228dc8ecaacSJohn Baldwin bus_read_1(sc->vge_res, reg) 229a07bd003SBill Paul 230a07bd003SBill Paul #define CSR_SETBIT_1(sc, reg, x) \ 231a07bd003SBill Paul CSR_WRITE_1(sc, reg, CSR_READ_1(sc, reg) | (x)) 232a07bd003SBill Paul #define CSR_SETBIT_2(sc, reg, x) \ 233a07bd003SBill Paul CSR_WRITE_2(sc, reg, CSR_READ_2(sc, reg) | (x)) 234a07bd003SBill Paul #define CSR_SETBIT_4(sc, reg, x) \ 235a07bd003SBill Paul CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) | (x)) 236a07bd003SBill Paul 237a07bd003SBill Paul #define CSR_CLRBIT_1(sc, reg, x) \ 238a07bd003SBill Paul CSR_WRITE_1(sc, reg, CSR_READ_1(sc, reg) & ~(x)) 239a07bd003SBill Paul #define CSR_CLRBIT_2(sc, reg, x) \ 240a07bd003SBill Paul CSR_WRITE_2(sc, reg, CSR_READ_2(sc, reg) & ~(x)) 241a07bd003SBill Paul #define CSR_CLRBIT_4(sc, reg, x) \ 242a07bd003SBill Paul CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) & ~(x)) 243a07bd003SBill Paul 244410f4c60SPyun YongHyeon #define VGE_RXCHUNK 4 245a07bd003SBill Paul #define VGE_TIMEOUT 10000 246