1bd368728SMarko Zec /*- 2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 3bd368728SMarko Zec * 4bd368728SMarko Zec * Copyright (c) 2015 Bjoern A. Zeeb 5bd368728SMarko Zec * Copyright (c) 2020 Denis Salopek 6bd368728SMarko Zec * 7bd368728SMarko Zec * This software was developed by SRI International and the University of 8bd368728SMarko Zec * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-11-C-0249 9bd368728SMarko Zec * ("MRC2"), as part of the DARPA MRC research programme. 10bd368728SMarko Zec * 11bd368728SMarko Zec * Redistribution and use in source and binary forms, with or without 12bd368728SMarko Zec * modification, are permitted provided that the following conditions 13bd368728SMarko Zec * are met: 14bd368728SMarko Zec * 1. Redistributions of source code must retain the above copyright 15bd368728SMarko Zec * notice, this list of conditions and the following disclaimer. 16bd368728SMarko Zec * 2. Redistributions in binary form must reproduce the above copyright 17bd368728SMarko Zec * notice, this list of conditions and the following disclaimer in the 18bd368728SMarko Zec * documentation and/or other materials provided with the distribution. 19bd368728SMarko Zec * 20bd368728SMarko Zec * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21bd368728SMarko Zec * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22bd368728SMarko Zec * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23bd368728SMarko Zec * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24bd368728SMarko Zec * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25bd368728SMarko Zec * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26bd368728SMarko Zec * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27bd368728SMarko Zec * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28bd368728SMarko Zec * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29bd368728SMarko Zec * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30bd368728SMarko Zec * POSSIBILITY OF SUCH DAMAGE. 31bd368728SMarko Zec */ 32bd368728SMarko Zec 33bd368728SMarko Zec 34bd368728SMarko Zec #define DEFAULT_ETHER_ADDRESS "\02SUME\00" 35bd368728SMarko Zec #define SUME_ETH_DEVICE_NAME "sume" 36bd368728SMarko Zec #define MAX_IFC_NAME_LEN 8 37bd368728SMarko Zec 38bd368728SMarko Zec #define SUME_NPORTS 4 39bd368728SMarko Zec 40bd368728SMarko Zec #define SUME_IOCTL_CMD_WRITE_REG (SIOCGPRIVATE_0) 41bd368728SMarko Zec #define SUME_IOCTL_CMD_READ_REG (SIOCGPRIVATE_1) 42bd368728SMarko Zec 43bd368728SMarko Zec #define SUME_LOCK(adapter) mtx_lock(&adapter->lock); 44bd368728SMarko Zec #define SUME_UNLOCK(adapter) mtx_unlock(&adapter->lock); 45bd368728SMarko Zec 46bd368728SMarko Zec /* Currently SUME only uses 2 fixed channels for all port traffic and regs. */ 47bd368728SMarko Zec #define SUME_RIFFA_CHANNEL_DATA 0 48bd368728SMarko Zec #define SUME_RIFFA_CHANNEL_REG 1 49bd368728SMarko Zec #define SUME_RIFFA_CHANNELS 2 50bd368728SMarko Zec 51bd368728SMarko Zec /* RIFFA constants. */ 52bd368728SMarko Zec #define RIFFA_MAX_CHNLS 12 53bd368728SMarko Zec #define RIFFA_MAX_BUS_WIDTH_PARAM 4 54bd368728SMarko Zec #define RIFFA_SG_BUF_SIZE (4*1024) 55bd368728SMarko Zec #define RIFFA_SG_ELEMS 200 56bd368728SMarko Zec 57bd368728SMarko Zec /* RIFFA register offsets. */ 58bd368728SMarko Zec #define RIFFA_RX_SG_LEN_REG_OFF 0x0 59bd368728SMarko Zec #define RIFFA_RX_SG_ADDR_LO_REG_OFF 0x1 60bd368728SMarko Zec #define RIFFA_RX_SG_ADDR_HI_REG_OFF 0x2 61bd368728SMarko Zec #define RIFFA_RX_LEN_REG_OFF 0x3 62bd368728SMarko Zec #define RIFFA_RX_OFFLAST_REG_OFF 0x4 63bd368728SMarko Zec #define RIFFA_TX_SG_LEN_REG_OFF 0x5 64bd368728SMarko Zec #define RIFFA_TX_SG_ADDR_LO_REG_OFF 0x6 65bd368728SMarko Zec #define RIFFA_TX_SG_ADDR_HI_REG_OFF 0x7 66bd368728SMarko Zec #define RIFFA_TX_LEN_REG_OFF 0x8 67bd368728SMarko Zec #define RIFFA_TX_OFFLAST_REG_OFF 0x9 68bd368728SMarko Zec #define RIFFA_INFO_REG_OFF 0xA 69bd368728SMarko Zec #define RIFFA_IRQ_REG0_OFF 0xB 70bd368728SMarko Zec #define RIFFA_IRQ_REG1_OFF 0xC 71bd368728SMarko Zec #define RIFFA_RX_TNFR_LEN_REG_OFF 0xD 72bd368728SMarko Zec #define RIFFA_TX_TNFR_LEN_REG_OFF 0xE 73bd368728SMarko Zec 74bd368728SMarko Zec #define RIFFA_CHNL_REG(c, o) ((c << 4) + o) 75bd368728SMarko Zec 76bd368728SMarko Zec /* 77bd368728SMarko Zec * RIFFA state machine; 78bd368728SMarko Zec * rather than using complex circular buffers for 1 transaction. 79bd368728SMarko Zec */ 80bd368728SMarko Zec #define SUME_RIFFA_CHAN_STATE_IDLE 0x01 81bd368728SMarko Zec #define SUME_RIFFA_CHAN_STATE_READY 0x02 82bd368728SMarko Zec #define SUME_RIFFA_CHAN_STATE_READ 0x04 83bd368728SMarko Zec #define SUME_RIFFA_CHAN_STATE_LEN 0x08 84bd368728SMarko Zec 85bd368728SMarko Zec /* Accessor macros. */ 86bd368728SMarko Zec #define SUME_OFFLAST ((0 << 1) | (1 & 0x01)) 87bd368728SMarko Zec #define SUME_RIFFA_LAST(offlast) ((offlast) & 0x01) 88bd368728SMarko Zec #define SUME_RIFFA_OFFSET(offlast) ((uint64_t)((offlast) >> 1) << 2) 89bd368728SMarko Zec #define SUME_RIFFA_LEN(len) ((uint64_t)(len) << 2) 90bd368728SMarko Zec 91bd368728SMarko Zec #define SUME_RIFFA_LO_ADDR(addr) (addr & 0xFFFFFFFF) 92bd368728SMarko Zec #define SUME_RIFFA_HI_ADDR(addr) ((addr >> 32) & 0xFFFFFFFF) 93bd368728SMarko Zec 94bd368728SMarko Zec /* Vector bits. */ 95bd368728SMarko Zec #define SUME_MSI_RXQUE (1 << 0) 96bd368728SMarko Zec #define SUME_MSI_RXBUF (1 << 1) 97bd368728SMarko Zec #define SUME_MSI_RXDONE (1 << 2) 98bd368728SMarko Zec #define SUME_MSI_TXBUF (1 << 3) 99bd368728SMarko Zec #define SUME_MSI_TXDONE (1 << 4) 100bd368728SMarko Zec 101bd368728SMarko Zec /* Invalid vector. */ 102bd368728SMarko Zec #define SUME_INVALID_VECT 0xc0000000 103bd368728SMarko Zec 104bd368728SMarko Zec /* Module register data (packet counters, link status...) */ 105bd368728SMarko Zec #define SUME_MOD0_REG_BASE 0x44040000 106bd368728SMarko Zec #define SUME_MOD_REG(port) (SUME_MOD0_REG_BASE + 0x10000 * port) 107bd368728SMarko Zec 108bd368728SMarko Zec #define SUME_RESET_OFFSET 0x8 109bd368728SMarko Zec #define SUME_PKTIN_OFFSET 0x18 110bd368728SMarko Zec #define SUME_PKTOUT_OFFSET 0x1c 111bd368728SMarko Zec #define SUME_STATUS_OFFSET 0x48 112bd368728SMarko Zec 113bd368728SMarko Zec #define SUME_RESET_ADDR(p) (SUME_MOD_REG(p) + SUME_RESET_OFFSET) 114bd368728SMarko Zec #define SUME_STAT_RX_ADDR(p) (SUME_MOD_REG(p) + SUME_PKTIN_OFFSET) 115bd368728SMarko Zec #define SUME_STAT_TX_ADDR(p) (SUME_MOD_REG(p) + SUME_PKTOUT_OFFSET) 116bd368728SMarko Zec #define SUME_STATUS_ADDR(p) (SUME_MOD_REG(p) + SUME_STATUS_OFFSET) 117bd368728SMarko Zec 118bd368728SMarko Zec #define SUME_LINK_STATUS(val) ((val >> 12) & 0x1) 119bd368728SMarko Zec 120bd368728SMarko Zec /* Various bits and pieces. */ 121bd368728SMarko Zec #define SUME_RIFFA_MAGIC 0xcafe 122bd368728SMarko Zec #define SUME_MR_WRITE 0x1f 123bd368728SMarko Zec #define SUME_MR_READ 0x00 124bd368728SMarko Zec #define SUME_INIT_RTAG -3 125bd368728SMarko Zec #define SUME_DPORT_MASK 0xaa 126bd368728SMarko Zec #define SUME_MIN_PKT_SIZE (ETHER_MIN_LEN - ETHER_CRC_LEN) 127bd368728SMarko Zec 128bd368728SMarko Zec struct irq { 129bd368728SMarko Zec uint32_t rid; 130bd368728SMarko Zec struct resource *res; 131bd368728SMarko Zec void *tag; 132bd368728SMarko Zec } __aligned(CACHE_LINE_SIZE); 133bd368728SMarko Zec 134bd368728SMarko Zec struct nf_stats { 135bd368728SMarko Zec uint64_t hw_rx_packets; 136bd368728SMarko Zec uint64_t hw_tx_packets; 137bd368728SMarko Zec uint64_t ifc_down_bytes; 138bd368728SMarko Zec uint64_t ifc_down_packets; 139bd368728SMarko Zec uint64_t rx_bytes; 140bd368728SMarko Zec uint64_t rx_dropped; 141bd368728SMarko Zec uint64_t rx_packets; 142bd368728SMarko Zec uint64_t tx_bytes; 143bd368728SMarko Zec uint64_t tx_dropped; 144bd368728SMarko Zec uint64_t tx_packets; 145bd368728SMarko Zec }; 146bd368728SMarko Zec 147bd368728SMarko Zec struct riffa_chnl_dir { 148bd368728SMarko Zec uint32_t state; 149bd368728SMarko Zec bus_dma_tag_t ch_tag; 150bd368728SMarko Zec bus_dmamap_t ch_map; 151bd368728SMarko Zec char *buf_addr; /* bouncebuf addresses+len. */ 152bd368728SMarko Zec bus_addr_t buf_hw_addr; /* -- " -- mapped. */ 153bd368728SMarko Zec uint32_t num_sg; 154bd368728SMarko Zec uint32_t event; /* Used for modreg r/w */ 155bd368728SMarko Zec uint32_t len; /* words */ 156bd368728SMarko Zec uint32_t offlast; 157bd368728SMarko Zec uint32_t recovery; 158bd368728SMarko Zec uint32_t rtag; 159bd368728SMarko Zec }; 160bd368728SMarko Zec 161bd368728SMarko Zec struct sume_ifreq { 162bd368728SMarko Zec uint32_t addr; 163bd368728SMarko Zec uint32_t val; 164bd368728SMarko Zec }; 165bd368728SMarko Zec 166bd368728SMarko Zec struct nf_priv { 167bd368728SMarko Zec struct sume_adapter *adapter; 168bd368728SMarko Zec struct ifmedia media; 169bd368728SMarko Zec struct nf_stats stats; 170bd368728SMarko Zec uint32_t unit; 171bd368728SMarko Zec uint32_t port; 172bd368728SMarko Zec uint32_t link_up; 173bd368728SMarko Zec }; 174bd368728SMarko Zec 175bd368728SMarko Zec struct sume_adapter { 176bd368728SMarko Zec struct mtx lock; 177bd368728SMarko Zec uint32_t running; 178bd368728SMarko Zec uint32_t rid; 179bd368728SMarko Zec struct riffa_chnl_dir **recv; 180bd368728SMarko Zec struct riffa_chnl_dir **send; 181bd368728SMarko Zec device_t dev; 182cc970676SJustin Hibbits if_t ifp[SUME_NPORTS]; 183bd368728SMarko Zec struct resource *bar0_addr; 184bd368728SMarko Zec bus_space_tag_t bt; 185bd368728SMarko Zec bus_space_handle_t bh; 186bd368728SMarko Zec bus_size_t bar0_len; 187bd368728SMarko Zec struct irq irq; 188bd368728SMarko Zec struct callout timer; 189bd368728SMarko Zec struct task stat_task; 190bd368728SMarko Zec struct taskqueue *tq; 191bd368728SMarko Zec uint64_t bytes_err; 192bd368728SMarko Zec uint64_t packets_err; 193bd368728SMarko Zec uint32_t last_ifc; 194bd368728SMarko Zec uint32_t num_sg; 195bd368728SMarko Zec uint32_t sg_buf_size; 196bd368728SMarko Zec uint32_t sume_debug; 197bd368728SMarko Zec uint32_t wd_counter; 198bd368728SMarko Zec }; 199bd368728SMarko Zec 200bd368728SMarko Zec /* SUME metadata: 201bd368728SMarko Zec * sport - not used for RX. For TX, set to 0x02, 0x08, 0x20, 0x80, depending on 202bd368728SMarko Zec * the sending interface (nf0, nf1, nf2 or nf3). 203bd368728SMarko Zec * dport - For RX, is set to 0x02, 0x08, 0x20, 0x80, depending on the receiving 204bd368728SMarko Zec * interface (nf0, nf1, nf2 or nf3). For TX, set to 0x01, 0x04, 0x10, 0x40, 205bd368728SMarko Zec * depending on the sending HW interface (nf0, nf1, nf2 or nf3). 206bd368728SMarko Zec * plen - length of the send/receive packet data (in bytes) 207bd368728SMarko Zec * magic - SUME hardcoded magic number which should be 0xcafe 208bd368728SMarko Zec * t1, t1 - could be used for timestamping by SUME 209bd368728SMarko Zec */ 210bd368728SMarko Zec struct nf_metadata { 211bd368728SMarko Zec uint16_t sport; 212bd368728SMarko Zec uint16_t dport; 213bd368728SMarko Zec uint16_t plen; 214bd368728SMarko Zec uint16_t magic; 215bd368728SMarko Zec uint32_t t1; 216bd368728SMarko Zec uint32_t t2; 217bd368728SMarko Zec }; 218bd368728SMarko Zec 219bd368728SMarko Zec /* Used for ioctl communication with the rwaxi program used to read/write SUME 220bd368728SMarko Zec * internally defined register data. 221bd368728SMarko Zec * addr - address of the SUME module register to read/write 222bd368728SMarko Zec * val - value to write/read to/from the register 223bd368728SMarko Zec * rtag - returned on read: transaction tag, for syncronization 224bd368728SMarko Zec * optype - 0x1f when writing, 0x00 for reading 225bd368728SMarko Zec */ 226bd368728SMarko Zec struct nf_regop_data { 227bd368728SMarko Zec uint32_t addr; 228bd368728SMarko Zec uint32_t val; 229bd368728SMarko Zec uint32_t rtag; 230bd368728SMarko Zec uint32_t optype; 231bd368728SMarko Zec }; 232bd368728SMarko Zec 233bd368728SMarko Zec /* Our bouncebuffer "descriptor". This holds our physical address (lower and 234bd368728SMarko Zec * upper values) of the beginning of the DMA data to RX/TX. The len is number 235bd368728SMarko Zec * of words to transmit. 236bd368728SMarko Zec */ 237bd368728SMarko Zec struct nf_bb_desc { 238bd368728SMarko Zec uint32_t lower; 239bd368728SMarko Zec uint32_t upper; 240bd368728SMarko Zec uint32_t len; 241bd368728SMarko Zec }; 242