sfxge_tx.h revision 282942
1288943Sdim/*- 2249259Sdim * Copyright (c) 2010-2011 Solarflare Communications, Inc. 3249259Sdim * All rights reserved. 4249259Sdim * 5249259Sdim * This software was developed in part by Philip Paeps under contract for 6249259Sdim * Solarflare Communications, Inc. 7249259Sdim * 8249259Sdim * Redistribution and use in source and binary forms, with or without 9249259Sdim * modification, are permitted provided that the following conditions 10249259Sdim * are met: 11249259Sdim * 1. Redistributions of source code must retain the above copyright 12249259Sdim * notice, this list of conditions and the following disclaimer. 13249259Sdim * 2. Redistributions in binary form must reproduce the above copyright 14249259Sdim * notice, this list of conditions and the following disclaimer in the 15249259Sdim * documentation and/or other materials provided with the distribution. 16288943Sdim * 17249259Sdim * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18249259Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19249259Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20276479Sdim * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21249259Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22249259Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23276479Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24288943Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25249259Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26249259Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27249259Sdim * SUCH DAMAGE. 28276479Sdim * 29280031Sdim * $FreeBSD: head/sys/dev/sfxge/sfxge_tx.h 282942 2015-05-15 06:50:59Z arybchik $ 30249259Sdim */ 31249259Sdim 32280031Sdim#ifndef _SFXGE_TX_H 33280031Sdim#define _SFXGE_TX_H 34280031Sdim 35280031Sdim#include <netinet/in.h> 36249259Sdim#include <netinet/ip.h> 37280031Sdim#include <netinet/tcp.h> 38280031Sdim 39280031Sdim/* Maximum size of TSO packet */ 40280031Sdim#define SFXGE_TSO_MAX_SIZE (65535) 41249259Sdim 42280031Sdim/* 43280031Sdim * Maximum number of segments to be created for a TSO packet. 44280031Sdim * Allow for a reasonable minimum MSS of 512. 45280031Sdim */ 46280031Sdim#define SFXGE_TSO_MAX_SEGS howmany(SFXGE_TSO_MAX_SIZE, 512) 47280031Sdim 48280031Sdim/* Maximum number of DMA segments needed to map an mbuf chain. With 49280031Sdim * TSO, the mbuf length may be just over 64K, divided into 2K mbuf 50280031Sdim * clusters. (The chain could be longer than this initially, but can 51280031Sdim * be shortened with m_collapse().) 52280031Sdim */ 53280031Sdim#define SFXGE_TX_MAPPING_MAX_SEG \ 54280031Sdim (1 + howmany(SFXGE_TSO_MAX_SIZE, MCLBYTES)) 55280031Sdim 56280031Sdim/* 57280031Sdim * Buffer mapping flags. 58249259Sdim * 59280031Sdim * Buffers and DMA mappings must be freed when the last descriptor 60280031Sdim * referring to them is completed. Set the TX_BUF_UNMAP and 61280031Sdim * TX_BUF_MBUF flags on the last descriptor generated for an mbuf 62280031Sdim * chain. Set only the TX_BUF_UNMAP flag on a descriptor referring to 63249259Sdim * a heap buffer. 64280031Sdim */ 65280031Sdimenum sfxge_tx_buf_flags { 66280031Sdim TX_BUF_UNMAP = 1, 67249259Sdim TX_BUF_MBUF = 2, 68280031Sdim}; 69280031Sdim 70280031Sdim/* 71249259Sdim * Buffer mapping information for descriptors in flight. 72280031Sdim */ 73280031Sdimstruct sfxge_tx_mapping { 74249259Sdim union { 75280031Sdim struct mbuf *mbuf; 76280031Sdim caddr_t heap_buf; 77280031Sdim } u; 78280031Sdim bus_dmamap_t map; 79280031Sdim enum sfxge_tx_buf_flags flags; 80280031Sdim}; 81280031Sdim 82249259Sdim#define SFXGE_TX_DPL_GET_PKT_LIMIT_DEFAULT (64 * 1024) 83280031Sdim#define SFXGE_TX_DPL_GET_NON_TCP_PKT_LIMIT_DEFAULT 1024 84280031Sdim#define SFXGE_TX_DPL_PUT_PKT_LIMIT_DEFAULT 1024 85280031Sdim 86280031Sdim/* 87288943Sdim * Deferred packet list. 88280031Sdim */ 89249259Sdimstruct sfxge_tx_dpl { 90280031Sdim unsigned int std_get_max; /* Maximum number of packets 91280031Sdim * in get list */ 92280031Sdim unsigned int std_get_non_tcp_max; /* Maximum number 93280031Sdim * of non-TCP packets 94249259Sdim * in get list */ 95280031Sdim unsigned int std_put_max; /* Maximum number of packets 96280031Sdim * in put list */ 97280031Sdim uintptr_t std_put; /* Head of put list. */ 98280031Sdim struct mbuf *std_get; /* Head of get list. */ 99249259Sdim struct mbuf **std_getp; /* Tail of get list. */ 100280031Sdim unsigned int std_get_count; /* Packets in get list. */ 101280031Sdim unsigned int std_get_non_tcp_count; /* Non-TCP packets 102280031Sdim * in get list */ 103280031Sdim unsigned int std_get_hiwat; /* Packets in get list 104280031Sdim * high watermark */ 105280031Sdim unsigned int std_put_hiwat; /* Packets in put list 106280031Sdim * high watermark */ 107249259Sdim}; 108280031Sdim 109280031Sdim 110280031Sdim#define SFXGE_TX_BUFFER_SIZE 0x400 111280031Sdim#define SFXGE_TX_HEADER_SIZE 0x100 112249259Sdim#define SFXGE_TX_COPY_THRESHOLD 0x200 113280031Sdim 114280031Sdimenum sfxge_txq_state { 115280031Sdim SFXGE_TXQ_UNINITIALIZED = 0, 116249259Sdim SFXGE_TXQ_INITIALIZED, 117249259Sdim SFXGE_TXQ_STARTED 118280031Sdim}; 119280031Sdim 120280031Sdimenum sfxge_txq_type { 121249259Sdim SFXGE_TXQ_NON_CKSUM = 0, 122249259Sdim SFXGE_TXQ_IP_CKSUM, 123296417Sdim SFXGE_TXQ_IP_TCP_UDP_CKSUM, 124296417Sdim SFXGE_TXQ_NTYPES 125296417Sdim}; 126296417Sdim 127296417Sdim#define SFXGE_TXQ_UNBLOCK_LEVEL(_entries) (EFX_TXQ_LIMIT(_entries) / 4) 128296417Sdim 129296417Sdim#define SFXGE_TX_BATCH 64 130296417Sdim 131296417Sdim#define SFXGE_TXQ_LOCK_INIT(_txq, _ifname, _txq_index) \ 132296417Sdim do { \ 133296417Sdim struct sfxge_txq *__txq = (_txq); \ 134296417Sdim \ 135296417Sdim snprintf((__txq)->lock_name, \ 136296417Sdim sizeof((__txq)->lock_name), \ 137296417Sdim "%s:txq%u", (_ifname), (_txq_index)); \ 138296417Sdim mtx_init(&(__txq)->lock, (__txq)->lock_name, \ 139296417Sdim NULL, MTX_DEF); \ 140296417Sdim } while (B_FALSE) 141296417Sdim#define SFXGE_TXQ_LOCK_DESTROY(_txq) \ 142296417Sdim mtx_destroy(&(_txq)->lock) 143296417Sdim#define SFXGE_TXQ_LOCK(_txq) \ 144296417Sdim mtx_lock(&(_txq)->lock) 145296417Sdim#define SFXGE_TXQ_TRYLOCK(_txq) \ 146296417Sdim mtx_trylock(&(_txq)->lock) 147296417Sdim#define SFXGE_TXQ_UNLOCK(_txq) \ 148296417Sdim mtx_unlock(&(_txq)->lock) 149296417Sdim#define SFXGE_TXQ_LOCK_ASSERT_OWNED(_txq) \ 150296417Sdim mtx_assert(&(_txq)->lock, MA_OWNED) 151296417Sdim#define SFXGE_TXQ_LOCK_ASSERT_NOTOWNED(_txq) \ 152296417Sdim mtx_assert(&(_txq)->lock, MA_NOTOWNED) 153296417Sdim 154296417Sdim 155280031Sdimstruct sfxge_txq { 156280031Sdim /* The following fields should be written very rarely */ 157280031Sdim struct sfxge_softc *sc; 158280031Sdim enum sfxge_txq_state init_state; 159280031Sdim enum sfxge_flush_state flush_state; 160280031Sdim enum sfxge_txq_type type; 161249259Sdim unsigned int txq_index; 162280031Sdim unsigned int evq_index; 163280031Sdim efsys_mem_t mem; 164249259Sdim unsigned int buf_base_id; 165249259Sdim unsigned int entries; 166280031Sdim unsigned int ptr_mask; 167280031Sdim 168280031Sdim struct sfxge_tx_mapping *stmp; /* Packets in flight. */ 169280031Sdim bus_dma_tag_t packet_dma_tag; 170249259Sdim efx_buffer_t *pend_desc; 171249259Sdim efx_txq_t *common; 172280031Sdim 173280031Sdim efsys_mem_t *tsoh_buffer; 174280031Sdim 175280031Sdim char lock_name[SFXGE_LOCK_NAME_MAX]; 176280031Sdim 177280031Sdim /* This field changes more often and is read regularly on both 178280031Sdim * the initiation and completion paths 179280031Sdim */ 180280031Sdim int blocked __aligned(CACHE_LINE_SIZE); 181249259Sdim 182280031Sdim /* The following fields change more often, and are used mostly 183280031Sdim * on the initiation path 184280031Sdim */ 185280031Sdim struct mtx lock __aligned(CACHE_LINE_SIZE); 186280031Sdim struct sfxge_tx_dpl dpl; /* Deferred packet list. */ 187280031Sdim unsigned int n_pend_desc; 188280031Sdim unsigned int added; 189249259Sdim unsigned int reaped; 190280031Sdim /* Statistics */ 191288943Sdim unsigned long tso_bursts; 192288943Sdim unsigned long tso_packets; 193296417Sdim unsigned long tso_long_headers; 194296417Sdim unsigned long collapses; 195249259Sdim unsigned long drops; 196280031Sdim unsigned long get_overflow; 197280031Sdim unsigned long get_non_tcp_overflow; 198280031Sdim unsigned long put_overflow; 199280031Sdim unsigned long netdown_drops; 200280031Sdim unsigned long tso_pdrop_too_many; 201280031Sdim unsigned long tso_pdrop_no_rsrc; 202280031Sdim 203280031Sdim /* The following fields change more often, and are used mostly 204280031Sdim * on the completion path 205280031Sdim */ 206280031Sdim unsigned int pending __aligned(CACHE_LINE_SIZE); 207280031Sdim unsigned int completed; 208280031Sdim struct sfxge_txq *next; 209280031Sdim}; 210280031Sdim 211280031Sdimstruct sfxge_evq; 212280031Sdim 213280031Sdimextern int sfxge_tx_packet_add(struct sfxge_txq *, struct mbuf *); 214280031Sdimextern uint64_t sfxge_tx_get_drops(struct sfxge_softc *sc); 215280031Sdim 216280031Sdimextern int sfxge_tx_init(struct sfxge_softc *sc); 217280031Sdimextern void sfxge_tx_fini(struct sfxge_softc *sc); 218280031Sdimextern int sfxge_tx_start(struct sfxge_softc *sc); 219280031Sdimextern void sfxge_tx_stop(struct sfxge_softc *sc); 220280031Sdimextern void sfxge_tx_qcomplete(struct sfxge_txq *txq, struct sfxge_evq *evq); 221280031Sdimextern void sfxge_tx_qflush_done(struct sfxge_txq *txq); 222280031Sdimextern void sfxge_if_qflush(struct ifnet *ifp); 223280031Sdimextern int sfxge_if_transmit(struct ifnet *ifp, struct mbuf *m); 224280031Sdim 225280031Sdim#endif 226280031Sdim