1195838Sbz/*- 2195838Sbz * SPDX-License-Identifier: BSD-2-Clause 3195838Sbz * 4195838Sbz * Copyright (c) 2015 Bjoern A. Zeeb 5195838Sbz * Copyright (c) 2020 Denis Salopek 6195838Sbz * 7195838Sbz * This software was developed by SRI International and the University of 8195838Sbz * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-11-C-0249 9195838Sbz * ("MRC2"), as part of the DARPA MRC research programme. 10195838Sbz * 11195838Sbz * Redistribution and use in source and binary forms, with or without 12195838Sbz * modification, are permitted provided that the following conditions 13195838Sbz * are met: 14195838Sbz * 1. Redistributions of source code must retain the above copyright 15195838Sbz * notice, this list of conditions and the following disclaimer. 16195838Sbz * 2. Redistributions in binary form must reproduce the above copyright 17195838Sbz * notice, this list of conditions and the following disclaimer in the 18195838Sbz * documentation and/or other materials provided with the distribution. 19195838Sbz * 20195838Sbz * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21195838Sbz * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22195838Sbz * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23195838Sbz * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24195838Sbz * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25195838Sbz * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26195838Sbz * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27195838Sbz * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28195838Sbz * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29195838Sbz * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30195838Sbz * POSSIBILITY OF SUCH DAMAGE. 31195838Sbz */ 32195838Sbz 33195838Sbz 34195838Sbz#define DEFAULT_ETHER_ADDRESS "\02SUME\00" 35195838Sbz#define SUME_ETH_DEVICE_NAME "sume" 36195838Sbz#define MAX_IFC_NAME_LEN 8 37195838Sbz 38195838Sbz#define SUME_NPORTS 4 39195838Sbz 40195838Sbz#define SUME_IOCTL_CMD_WRITE_REG (SIOCGPRIVATE_0) 41195838Sbz#define SUME_IOCTL_CMD_READ_REG (SIOCGPRIVATE_1) 42195838Sbz 43195838Sbz#define SUME_LOCK(adapter) mtx_lock(&adapter->lock); 44195838Sbz#define SUME_UNLOCK(adapter) mtx_unlock(&adapter->lock); 45195838Sbz 46195838Sbz/* Currently SUME only uses 2 fixed channels for all port traffic and regs. */ 47195838Sbz#define SUME_RIFFA_CHANNEL_DATA 0 48195838Sbz#define SUME_RIFFA_CHANNEL_REG 1 49195838Sbz#define SUME_RIFFA_CHANNELS 2 50195838Sbz 51195838Sbz/* RIFFA constants. */ 52195838Sbz#define RIFFA_MAX_CHNLS 12 53195838Sbz#define RIFFA_MAX_BUS_WIDTH_PARAM 4 54195838Sbz#define RIFFA_SG_BUF_SIZE (4*1024) 55195838Sbz#define RIFFA_SG_ELEMS 200 56195838Sbz 57195838Sbz/* RIFFA register offsets. */ 58195838Sbz#define RIFFA_RX_SG_LEN_REG_OFF 0x0 59195838Sbz#define RIFFA_RX_SG_ADDR_LO_REG_OFF 0x1 60195838Sbz#define RIFFA_RX_SG_ADDR_HI_REG_OFF 0x2 61195838Sbz#define RIFFA_RX_LEN_REG_OFF 0x3 62195838Sbz#define RIFFA_RX_OFFLAST_REG_OFF 0x4 63195838Sbz#define RIFFA_TX_SG_LEN_REG_OFF 0x5 64195838Sbz#define RIFFA_TX_SG_ADDR_LO_REG_OFF 0x6 65195838Sbz#define RIFFA_TX_SG_ADDR_HI_REG_OFF 0x7 66195838Sbz#define RIFFA_TX_LEN_REG_OFF 0x8 67195838Sbz#define RIFFA_TX_OFFLAST_REG_OFF 0x9 68195838Sbz#define RIFFA_INFO_REG_OFF 0xA 69195838Sbz#define RIFFA_IRQ_REG0_OFF 0xB 70195838Sbz#define RIFFA_IRQ_REG1_OFF 0xC 71195838Sbz#define RIFFA_RX_TNFR_LEN_REG_OFF 0xD 72195838Sbz#define RIFFA_TX_TNFR_LEN_REG_OFF 0xE 73195838Sbz 74195838Sbz#define RIFFA_CHNL_REG(c, o) ((c << 4) + o) 75195838Sbz 76195838Sbz/* 77195838Sbz * RIFFA state machine; 78195838Sbz * rather than using complex circular buffers for 1 transaction. 79195838Sbz */ 80195838Sbz#define SUME_RIFFA_CHAN_STATE_IDLE 0x01 81195838Sbz#define SUME_RIFFA_CHAN_STATE_READY 0x02 82195838Sbz#define SUME_RIFFA_CHAN_STATE_READ 0x04 83195838Sbz#define SUME_RIFFA_CHAN_STATE_LEN 0x08 84217744Suqs 85217744Suqs/* Accessor macros. */ 86217744Suqs#define SUME_OFFLAST ((0 << 1) | (1 & 0x01)) 87217744Suqs#define SUME_RIFFA_LAST(offlast) ((offlast) & 0x01) 88217744Suqs#define SUME_RIFFA_OFFSET(offlast) ((uint64_t)((offlast) >> 1) << 2) 89217744Suqs#define SUME_RIFFA_LEN(len) ((uint64_t)(len) << 2) 90195838Sbz 91195838Sbz#define SUME_RIFFA_LO_ADDR(addr) (addr & 0xFFFFFFFF) 92195838Sbz#define SUME_RIFFA_HI_ADDR(addr) ((addr >> 32) & 0xFFFFFFFF) 93195838Sbz 94195838Sbz/* Vector bits. */ 95195838Sbz#define SUME_MSI_RXQUE (1 << 0) 96195838Sbz#define SUME_MSI_RXBUF (1 << 1) 97195838Sbz#define SUME_MSI_RXDONE (1 << 2) 98195838Sbz#define SUME_MSI_TXBUF (1 << 3) 99195838Sbz#define SUME_MSI_TXDONE (1 << 4) 100195838Sbz 101195838Sbz/* Invalid vector. */ 102195838Sbz#define SUME_INVALID_VECT 0xc0000000 103195838Sbz 104195838Sbz/* Module register data (packet counters, link status...) */ 105195838Sbz#define SUME_MOD0_REG_BASE 0x44040000 106195838Sbz#define SUME_MOD_REG(port) (SUME_MOD0_REG_BASE + 0x10000 * port) 107195838Sbz 108195838Sbz#define SUME_RESET_OFFSET 0x8 109195838Sbz#define SUME_PKTIN_OFFSET 0x18 110195838Sbz#define SUME_PKTOUT_OFFSET 0x1c 111195838Sbz#define SUME_STATUS_OFFSET 0x48 112195838Sbz 113195838Sbz#define SUME_RESET_ADDR(p) (SUME_MOD_REG(p) + SUME_RESET_OFFSET) 114195838Sbz#define SUME_STAT_RX_ADDR(p) (SUME_MOD_REG(p) + SUME_PKTIN_OFFSET) 115195838Sbz#define SUME_STAT_TX_ADDR(p) (SUME_MOD_REG(p) + SUME_PKTOUT_OFFSET) 116195838Sbz#define SUME_STATUS_ADDR(p) (SUME_MOD_REG(p) + SUME_STATUS_OFFSET) 117195838Sbz 118195838Sbz#define SUME_LINK_STATUS(val) ((val >> 12) & 0x1) 119195838Sbz 120195838Sbz/* Various bits and pieces. */ 121195838Sbz#define SUME_RIFFA_MAGIC 0xcafe 122195838Sbz#define SUME_MR_WRITE 0x1f 123195838Sbz#define SUME_MR_READ 0x00 124204435Srwatson#define SUME_INIT_RTAG -3 125204435Srwatson#define SUME_DPORT_MASK 0xaa 126195838Sbz#define SUME_MIN_PKT_SIZE (ETHER_MIN_LEN - ETHER_CRC_LEN) 127195838Sbz 128195838Sbzstruct irq { 129195838Sbz uint32_t rid; 130195838Sbz struct resource *res; 131195838Sbz void *tag; 132195838Sbz} __aligned(CACHE_LINE_SIZE); 133195838Sbz 134195838Sbzstruct nf_stats { 135195838Sbz uint64_t hw_rx_packets; 136195838Sbz uint64_t hw_tx_packets; 137195838Sbz uint64_t ifc_down_bytes; 138195838Sbz uint64_t ifc_down_packets; 139195838Sbz uint64_t rx_bytes; 140195838Sbz uint64_t rx_dropped; 141195838Sbz uint64_t rx_packets; 142195838Sbz uint64_t tx_bytes; 143195838Sbz uint64_t tx_dropped; 144195838Sbz uint64_t tx_packets; 145195838Sbz}; 146195838Sbz 147195838Sbzstruct riffa_chnl_dir { 148195838Sbz uint32_t state; 149195838Sbz bus_dma_tag_t ch_tag; 150195838Sbz bus_dmamap_t ch_map; 151195838Sbz char *buf_addr; /* bouncebuf addresses+len. */ 152195838Sbz bus_addr_t buf_hw_addr; /* -- " -- mapped. */ 153195838Sbz uint32_t num_sg; 154195838Sbz uint32_t event; /* Used for modreg r/w */ 155195838Sbz uint32_t len; /* words */ 156195838Sbz uint32_t offlast; 157195838Sbz uint32_t recovery; 158195838Sbz uint32_t rtag; 159195838Sbz}; 160195838Sbz 161195838Sbzstruct sume_ifreq { 162195838Sbz uint32_t addr; 163195838Sbz uint32_t val; 164195838Sbz}; 165195838Sbz 166195838Sbzstruct nf_priv { 167195838Sbz struct sume_adapter *adapter; 168195838Sbz struct ifmedia media; 169195838Sbz struct nf_stats stats; 170195838Sbz uint32_t unit; 171195838Sbz uint32_t port; 172195838Sbz uint32_t link_up; 173195838Sbz}; 174195838Sbz 175195838Sbzstruct sume_adapter { 176195838Sbz struct mtx lock; 177195838Sbz uint32_t running; 178195838Sbz uint32_t rid; 179195838Sbz struct riffa_chnl_dir **recv; 180195838Sbz struct riffa_chnl_dir **send; 181195838Sbz device_t dev; 182195838Sbz if_t ifp[SUME_NPORTS]; 183195838Sbz struct resource *bar0_addr; 184195838Sbz bus_space_tag_t bt; 185195838Sbz bus_space_handle_t bh; 186195838Sbz bus_size_t bar0_len; 187195838Sbz struct irq irq; 188195838Sbz struct callout timer; 189195838Sbz struct task stat_task; 190195838Sbz struct taskqueue *tq; 191195838Sbz uint64_t bytes_err; 192195838Sbz uint64_t packets_err; 193195838Sbz uint32_t last_ifc; 194195838Sbz uint32_t num_sg; 195195838Sbz uint32_t sg_buf_size; 196195838Sbz uint32_t sume_debug; 197195838Sbz uint32_t wd_counter; 198195838Sbz}; 199195838Sbz 200195838Sbz/* SUME metadata: 201196185Sbz * sport - not used for RX. For TX, set to 0x02, 0x08, 0x20, 0x80, depending on 202195838Sbz * the sending interface (nf0, nf1, nf2 or nf3). 203195838Sbz * dport - For RX, is set to 0x02, 0x08, 0x20, 0x80, depending on the receiving 204195838Sbz * interface (nf0, nf1, nf2 or nf3). For TX, set to 0x01, 0x04, 0x10, 0x40, 205195838Sbz * depending on the sending HW interface (nf0, nf1, nf2 or nf3). 206195838Sbz * plen - length of the send/receive packet data (in bytes) 207195838Sbz * magic - SUME hardcoded magic number which should be 0xcafe 208195838Sbz * t1, t1 - could be used for timestamping by SUME 209195838Sbz */ 210195838Sbzstruct nf_metadata { 211195838Sbz uint16_t sport; 212195838Sbz uint16_t dport; 213195838Sbz uint16_t plen; 214195838Sbz uint16_t magic; 215195838Sbz uint32_t t1; 216195838Sbz uint32_t t2; 217195838Sbz}; 218195838Sbz 219195838Sbz/* Used for ioctl communication with the rwaxi program used to read/write SUME 220195838Sbz * internally defined register data. 221195838Sbz * addr - address of the SUME module register to read/write 222195838Sbz * val - value to write/read to/from the register 223195838Sbz * rtag - returned on read: transaction tag, for syncronization 224195838Sbz * optype - 0x1f when writing, 0x00 for reading 225195838Sbz */ 226195838Sbzstruct nf_regop_data { 227195838Sbz uint32_t addr; 228195838Sbz uint32_t val; 229195838Sbz uint32_t rtag; 230195838Sbz uint32_t optype; 231195838Sbz}; 232195838Sbz 233195838Sbz/* Our bouncebuffer "descriptor". This holds our physical address (lower and 234195838Sbz * upper values) of the beginning of the DMA data to RX/TX. The len is number 235195838Sbz * of words to transmit. 236195838Sbz */ 237195838Sbzstruct nf_bb_desc { 238195838Sbz uint32_t lower; 239195838Sbz uint32_t upper; 240 uint32_t len; 241}; 242