1227569Sphilip/*- 2284555Sarybchik * Copyright (c) 2010-2015 Solarflare Communications Inc. 3227569Sphilip * All rights reserved. 4227569Sphilip * 5227569Sphilip * This software was developed in part by Philip Paeps under contract for 6227569Sphilip * Solarflare Communications, Inc. 7227569Sphilip * 8227569Sphilip * Redistribution and use in source and binary forms, with or without 9284555Sarybchik * modification, are permitted provided that the following conditions are met: 10227569Sphilip * 11284555Sarybchik * 1. Redistributions of source code must retain the above copyright notice, 12284555Sarybchik * this list of conditions and the following disclaimer. 13284555Sarybchik * 2. Redistributions in binary form must reproduce the above copyright notice, 14284555Sarybchik * this list of conditions and the following disclaimer in the documentation 15284555Sarybchik * and/or other materials provided with the distribution. 16227569Sphilip * 17284555Sarybchik * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18284555Sarybchik * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 19284555Sarybchik * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20284555Sarybchik * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 21284555Sarybchik * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22284555Sarybchik * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23284555Sarybchik * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 24284555Sarybchik * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25284555Sarybchik * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 26284555Sarybchik * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 27284555Sarybchik * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28284555Sarybchik * 29284555Sarybchik * The views and conclusions contained in the software and documentation are 30284555Sarybchik * those of the authors and should not be interpreted as representing official 31284555Sarybchik * policies, either expressed or implied, of the FreeBSD Project. 32284555Sarybchik * 33227569Sphilip * $FreeBSD: releng/10.2/sys/dev/sfxge/sfxge_rx.h 284555 2015-06-18 15:46:39Z arybchik $ 34227569Sphilip */ 35227569Sphilip 36227569Sphilip#ifndef _SFXGE_RX_H 37280501Sarybchik#define _SFXGE_RX_H 38227569Sphilip 39280615Sarybchik#include "opt_inet.h" 40280615Sarybchik#include "opt_inet6.h" 41280615Sarybchik 42280615Sarybchik#if defined(INET) || defined(INET6) 43280615Sarybchik#define SFXGE_LRO 1 44280615Sarybchik#endif 45280615Sarybchik 46284555Sarybchik#define SFXGE_MAGIC_RESERVED 0x8000 47227569Sphilip 48280501Sarybchik#define SFXGE_MAGIC_DMAQ_LABEL_WIDTH 6 49284555Sarybchik#define SFXGE_MAGIC_DMAQ_LABEL_MASK \ 50280501Sarybchik ((1 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH) - 1) 51227569Sphilip 52284555Sarybchik#define SFXGE_MAGIC_RX_QFLUSH_DONE \ 53280501Sarybchik (SFXGE_MAGIC_RESERVED | (1 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH)) 54227569Sphilip 55284555Sarybchik#define SFXGE_MAGIC_RX_QFLUSH_FAILED \ 56280501Sarybchik (SFXGE_MAGIC_RESERVED | (2 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH)) 57227569Sphilip 58284555Sarybchik#define SFXGE_MAGIC_RX_QREFILL \ 59280501Sarybchik (SFXGE_MAGIC_RESERVED | (3 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH)) 60227569Sphilip 61284555Sarybchik#define SFXGE_MAGIC_TX_QFLUSH_DONE \ 62280501Sarybchik (SFXGE_MAGIC_RESERVED | (4 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH)) 63227569Sphilip 64227569Sphilip#define SFXGE_RX_SCALE_MAX EFX_MAXRSS 65227569Sphilip 66227569Sphilipstruct sfxge_rx_sw_desc { 67227569Sphilip struct mbuf *mbuf; 68227569Sphilip bus_dmamap_t map; 69227569Sphilip int flags; 70227569Sphilip int size; 71227569Sphilip}; 72227569Sphilip 73280615Sarybchik#ifdef SFXGE_LRO 74280615Sarybchik 75227569Sphilip/** 76227569Sphilip * struct sfxge_lro_conn - Connection state for software LRO 77227569Sphilip * @link: Link for hash table and free list. 78227569Sphilip * @active_link: Link for active_conns list 79227569Sphilip * @l2_id: Identifying information from layer 2 80227569Sphilip * @conn_hash: Hash of connection 4-tuple 81227569Sphilip * @nh: IP (v4 or v6) header of super-packet 82227569Sphilip * @source: Source TCP port number 83227569Sphilip * @dest: Destination TCP port number 84227569Sphilip * @n_in_order_pkts: Number of in-order packets with payload. 85227569Sphilip * @next_seq: Next in-order sequence number. 86227569Sphilip * @last_pkt_ticks: Time we last saw a packet on this connection. 87227569Sphilip * @mbuf: The mbuf we are currently holding. 88227569Sphilip * If %NULL, then all following fields are undefined. 89227569Sphilip * @mbuf_tail: The tail of the frag_list of mbufs we're holding. 90227569Sphilip * Only valid after at least one merge. 91227569Sphilip * @th_last: The TCP header of the last packet merged. 92227569Sphilip * @next_buf: The next RX buffer to process. 93227569Sphilip * @next_eh: Ethernet header of the next buffer. 94227569Sphilip * @next_nh: IP header of the next buffer. 95227569Sphilip * @delivered: True if we've delivered a payload packet up this interrupt. 96227569Sphilip */ 97227569Sphilipstruct sfxge_lro_conn { 98227569Sphilip TAILQ_ENTRY(sfxge_lro_conn) link; 99227569Sphilip LIST_ENTRY(sfxge_lro_conn) active_link; 100227569Sphilip uint16_t l2_id; 101227569Sphilip uint32_t conn_hash; 102227569Sphilip void *nh; 103227569Sphilip uint16_t source, dest; 104227569Sphilip int n_in_order_pkts; 105227569Sphilip unsigned next_seq; 106227569Sphilip unsigned last_pkt_ticks; 107227569Sphilip struct mbuf *mbuf; 108227569Sphilip struct mbuf *mbuf_tail; 109227569Sphilip struct tcphdr *th_last; 110227569Sphilip struct sfxge_rx_sw_desc next_buf; 111227569Sphilip void *next_eh; 112227569Sphilip void *next_nh; 113227569Sphilip int delivered; 114227569Sphilip}; 115227569Sphilip 116227569Sphilip/** 117227569Sphilip * struct sfxge_lro_state - Port state for software LRO 118227569Sphilip * @sc: The associated NIC. 119227569Sphilip * @conns_mask: Number of hash buckets - 1. 120227569Sphilip * @conns: Hash buckets for tracked connections. 121227569Sphilip * @conns_n: Length of linked list for each hash bucket. 122227569Sphilip * @active_conns: Connections that are holding a packet. 123227569Sphilip * Connections are self-linked when not in this list. 124227569Sphilip * @free_conns: Free sfxge_lro_conn instances. 125227569Sphilip * @last_purge_ticks: The value of ticks last time we purged idle 126227569Sphilip * connections. 127227569Sphilip * @n_merges: Number of packets absorbed by LRO. 128227569Sphilip * @n_bursts: Number of bursts spotted by LRO. 129227569Sphilip * @n_slow_start: Number of packets not merged because connection may be in 130227569Sphilip * slow-start. 131227569Sphilip * @n_misorder: Number of out-of-order packets seen in tracked streams. 132227569Sphilip * @n_too_many: Incremented when we're trying to track too many streams. 133227569Sphilip * @n_new_stream: Number of distinct streams we've tracked. 134227569Sphilip * @n_drop_idle: Number of streams discarded because they went idle. 135227569Sphilip * @n_drop_closed: Number of streams that have seen a FIN or RST. 136227569Sphilip */ 137227569Sphilipstruct sfxge_lro_state { 138227569Sphilip struct sfxge_softc *sc; 139227569Sphilip unsigned conns_mask; 140227569Sphilip TAILQ_HEAD(sfxge_lro_tailq, sfxge_lro_conn) *conns; 141227569Sphilip unsigned *conns_n; 142227569Sphilip LIST_HEAD(, sfxge_lro_conn) active_conns; 143227569Sphilip TAILQ_HEAD(, sfxge_lro_conn) free_conns; 144227569Sphilip unsigned last_purge_ticks; 145227569Sphilip unsigned n_merges; 146227569Sphilip unsigned n_bursts; 147227569Sphilip unsigned n_slow_start; 148227569Sphilip unsigned n_misorder; 149227569Sphilip unsigned n_too_many; 150227569Sphilip unsigned n_new_stream; 151227569Sphilip unsigned n_drop_idle; 152227569Sphilip unsigned n_drop_closed; 153227569Sphilip}; 154227569Sphilip 155280615Sarybchik#endif /* SFXGE_LRO */ 156280615Sarybchik 157227569Sphilipenum sfxge_flush_state { 158227569Sphilip SFXGE_FLUSH_DONE = 0, 159284555Sarybchik SFXGE_FLUSH_REQUIRED, 160227569Sphilip SFXGE_FLUSH_PENDING, 161227569Sphilip SFXGE_FLUSH_FAILED 162227569Sphilip}; 163227569Sphilip 164227569Sphilipenum sfxge_rxq_state { 165227569Sphilip SFXGE_RXQ_UNINITIALIZED = 0, 166227569Sphilip SFXGE_RXQ_INITIALIZED, 167227569Sphilip SFXGE_RXQ_STARTED 168227569Sphilip}; 169227569Sphilip 170227569Sphilip#define SFXGE_RX_BATCH 128 171227569Sphilip 172227569Sphilipstruct sfxge_rxq { 173227569Sphilip struct sfxge_softc *sc __aligned(CACHE_LINE_SIZE); 174227569Sphilip unsigned int index; 175227569Sphilip efsys_mem_t mem; 176227569Sphilip unsigned int buf_base_id; 177227569Sphilip enum sfxge_rxq_state init_state; 178280502Sarybchik unsigned int entries; 179280502Sarybchik unsigned int ptr_mask; 180227569Sphilip 181227569Sphilip struct sfxge_rx_sw_desc *queue __aligned(CACHE_LINE_SIZE); 182227569Sphilip unsigned int added; 183284555Sarybchik unsigned int pushed; 184227569Sphilip unsigned int pending; 185227569Sphilip unsigned int completed; 186227569Sphilip unsigned int loopback; 187280615Sarybchik#ifdef SFXGE_LRO 188227569Sphilip struct sfxge_lro_state lro; 189280615Sarybchik#endif 190280502Sarybchik unsigned int refill_threshold; 191227569Sphilip struct callout refill_callout; 192227569Sphilip unsigned int refill_delay; 193227569Sphilip 194227569Sphilip efx_rxq_t *common __aligned(CACHE_LINE_SIZE); 195227569Sphilip volatile enum sfxge_flush_state flush_state; 196227569Sphilip}; 197227569Sphilip 198227569Sphilip/* 199227569Sphilip * From sfxge_rx.c. 200227569Sphilip */ 201227569Sphilipextern int sfxge_rx_init(struct sfxge_softc *sc); 202227569Sphilipextern void sfxge_rx_fini(struct sfxge_softc *sc); 203227569Sphilipextern int sfxge_rx_start(struct sfxge_softc *sc); 204227569Sphilipextern void sfxge_rx_stop(struct sfxge_softc *sc); 205227569Sphilipextern void sfxge_rx_qcomplete(struct sfxge_rxq *rxq, boolean_t eop); 206227569Sphilipextern void sfxge_rx_qrefill(struct sfxge_rxq *rxq); 207227569Sphilipextern void sfxge_rx_qflush_done(struct sfxge_rxq *rxq); 208227569Sphilipextern void sfxge_rx_qflush_failed(struct sfxge_rxq *rxq); 209227569Sphilipextern void sfxge_rx_scale_update(void *arg, int npending); 210227569Sphilip 211227569Sphilip#endif 212