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