1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2022 Scott Long 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 * $FreeBSD$ 29 */ 30 31 #ifndef _ROUTER_VAR_H 32 #define _ROUTER_VAR_H 33 34 struct router_softc; 35 struct router_command; 36 struct router_topo; 37 38 typedef void (*router_callback_t)(struct router_softc *, 39 struct router_command *, void *); 40 41 struct router_command { 42 TAILQ_ENTRY(router_command) link; 43 struct router_softc *sc; 44 struct nhi_cmd_frame *nhicmd; 45 u_int flags; 46 #define RCMD_POLLED (1 << 0) 47 #define RCMD_POLL_COMPLETE (1 << 1) 48 int resp_len; 49 router_callback_t callback; 50 void *callback_arg; 51 u_int dwlen; 52 u_int timeout; 53 int retries; 54 u_int ev; 55 uint8_t resp_buffer[NHI_RING0_FRAME_SIZE]; 56 }; 57 58 struct router_softc { 59 TAILQ_ENTRY(router_softc) link; 60 u_int debug; 61 tb_route_t route; 62 device_t dev; 63 struct nhi_softc *nsc; 64 65 struct mtx mtx; 66 struct nhi_ring_pair *ring0; 67 TAILQ_HEAD(,router_command) cmd_queue; 68 69 struct router_command *inflight_cmd; 70 71 uint8_t depth; 72 uint8_t max_adap; 73 74 struct router_softc **adapters; 75 76 uint32_t uuid[4]; 77 }; 78 79 struct router_cfg_cap { 80 uint16_t current_cap; 81 uint16_t next_cap; 82 uint32_t space; 83 uint8_t adap; 84 uint8_t cap_id; 85 uint8_t vsc_id; 86 uint8_t vsc_len; 87 uint16_t vsec_len; 88 }; 89 90 int tb_router_attach(struct router_softc *, tb_route_t); 91 int tb_router_attach_root(struct nhi_softc *, tb_route_t); 92 int tb_router_detach(struct router_softc *); 93 int tb_config_read(struct router_softc *, u_int, u_int, u_int, u_int, 94 uint32_t *); 95 int tb_config_read_polled(struct router_softc *, u_int, u_int, u_int, u_int, 96 uint32_t *); 97 int tb_config_read_async(struct router_softc *, u_int, u_int, u_int, u_int, 98 uint32_t *, void *); 99 int tb_config_write(struct router_softc *, u_int, u_int, u_int, u_int, 100 uint32_t *); 101 int tb_config_next_cap(struct router_softc *, struct router_cfg_cap *); 102 int tb_config_find_cap(struct router_softc *, struct router_cfg_cap *); 103 int tb_config_find_router_cap(struct router_softc *, u_int, u_int, u_int *); 104 int tb_config_find_router_vsc(struct router_softc *, u_int, u_int *); 105 int tb_config_find_router_vsec(struct router_softc *, u_int, u_int *); 106 int tb_config_find_adapter_cap(struct router_softc *, u_int, u_int, u_int *); 107 int tb_config_get_lc_uuid(struct router_softc *, uint8_t *); 108 109 #define TB_CONFIG_ADDR(seq, space, adapter, dwlen, offset) \ 110 ((seq << TB_CFG_SEQ_SHIFT) | space | \ 111 (adapter << TB_CFG_ADAPTER_SHIFT) | (dwlen << TB_CFG_SIZE_SHIFT) | \ 112 (offset & TB_CFG_ADDR_MASK)) 113 114 #define TB_ROUTE(router) \ 115 ((uint64_t)(router)->route.hi << 32) | (router)->route.lo 116 117 static __inline void * 118 router_get_frame_data(struct router_command *cmd) 119 { 120 return ((void *)cmd->nhicmd->data); 121 } 122 123 /* 124 * Read the Router config space for the router referred to in the softc. 125 * addr - The dword offset in the config space 126 * dwlen - The number of dwords 127 * buf - must be large enough to hold the number of dwords requested. 128 */ 129 static __inline int 130 tb_config_router_read(struct router_softc *sc, u_int addr, u_int dwlen, 131 uint32_t *buf) 132 { 133 return (tb_config_read(sc, TB_CFG_CS_ROUTER, 0, addr, dwlen, buf)); 134 } 135 136 static __inline int 137 tb_config_router_read_polled(struct router_softc *sc, u_int addr, u_int dwlen, 138 uint32_t *buf) 139 { 140 return (tb_config_read_polled(sc, TB_CFG_CS_ROUTER, 0, addr, dwlen, buf)); 141 } 142 143 /* 144 * Write the Router config space for the router referred to in the softc. 145 * addr - The dword offset in the config space 146 * dwlen - The number of dwords 147 * buf - must be large enough to hold the number of dwords requested. 148 */ 149 static __inline int 150 tb_config_router_write(struct router_softc *sc, u_int addr, u_int dwlen, 151 uint32_t *buf) 152 { 153 return (tb_config_write(sc, TB_CFG_CS_ROUTER, 0, addr, dwlen, buf)); 154 } 155 156 /* 157 * Read the Adapter config space for the router referred to in the softc. 158 * adap - Adapter number 159 * addr - The dword offset in the config space 160 * dwlen - The number of dwords 161 * buf - must be large enough to hold the number of dwords requested. 162 */ 163 static __inline int 164 tb_config_adapter_read(struct router_softc *sc, u_int adap, u_int addr, 165 u_int dwlen, uint32_t *buf) 166 { 167 return (tb_config_read(sc, TB_CFG_CS_ADAPTER, adap, addr, dwlen, buf)); 168 } 169 170 /* 171 * Read the Adapter config space for the router referred to in the softc. 172 * adap - Adapter number 173 * addr - The dword offset in the config space 174 * dwlen - The number of dwords 175 * buf - must be large enough to hold the number of dwords requested. 176 */ 177 static __inline int 178 tb_config_adapter_write(struct router_softc *sc, u_int adap, u_int addr, 179 u_int dwlen, uint32_t *buf) 180 { 181 return (tb_config_write(sc, TB_CFG_CS_ADAPTER, adap, addr, dwlen, buf)); 182 } 183 184 /* 185 * Read the Path config space for the router referred to in the softc. 186 * adap - Adapter number 187 * hopid - HopID of the path 188 * len - The number of adjacent paths 189 * buf - must be large enough to hold the number of dwords requested. 190 */ 191 static __inline int 192 tb_config_path_read(struct router_softc *sc, u_int adap, u_int hopid, 193 u_int num, uint32_t *buf) 194 { 195 return (tb_config_read(sc, TB_CFG_CS_PATH, adap, hopid * 2, 196 num * 2, buf)); 197 } 198 199 /* 200 * Write the Path config space for the router referred to in the softc. 201 * adap - Adapter number 202 * hopid - HopID of the path 203 * len - The number of adjacent paths 204 * buf - must be large enough to hold the number of dwords requested. 205 */ 206 static __inline int 207 tb_config_path_write(struct router_softc *sc, u_int adap, u_int hopid, 208 u_int num, uint32_t *buf) 209 { 210 return (tb_config_write(sc, TB_CFG_CS_PATH, adap, hopid * 2, 211 num * 2, buf)); 212 } 213 214 /* 215 * Read the Counters config space for the router referred to in the softc. 216 * Counters come in sets of 3 dwords. 217 * adap - Adapter number 218 * set - The counter set index 219 * num - The number of adjacent counter sets to read 220 * buf - must be large enough to hold the number of dwords requested. 221 */ 222 static __inline int 223 tb_config_counters_read(struct router_softc *sc, u_int adap, u_int set, 224 u_int num, uint32_t *buf) 225 { 226 return (tb_config_read(sc, TB_CFG_CS_COUNTERS, adap, set * 3, 227 num * 3, buf)); 228 } 229 230 static __inline void 231 tb_config_set_root(struct router_softc *sc) 232 { 233 sc->nsc->root_rsc = sc; 234 } 235 236 static __inline void * 237 tb_config_get_root(struct router_softc *sc) 238 { 239 return (sc->nsc->root_rsc); 240 } 241 242 #endif /* _ROUTER_VAR_H */ 243