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 29 #ifndef _ROUTER_VAR_H 30 #define _ROUTER_VAR_H 31 32 struct router_softc; 33 struct router_command; 34 struct router_topo; 35 36 typedef void (*router_callback_t)(struct router_softc *, 37 struct router_command *, void *); 38 39 struct router_command { 40 TAILQ_ENTRY(router_command) link; 41 struct router_softc *sc; 42 struct nhi_cmd_frame *nhicmd; 43 u_int flags; 44 #define RCMD_POLLED (1 << 0) 45 #define RCMD_POLL_COMPLETE (1 << 1) 46 int resp_len; 47 router_callback_t callback; 48 void *callback_arg; 49 u_int dwlen; 50 u_int timeout; 51 int retries; 52 u_int ev; 53 uint8_t resp_buffer[NHI_RING0_FRAME_SIZE]; 54 }; 55 56 struct router_softc { 57 TAILQ_ENTRY(router_softc) link; 58 u_int debug; 59 tb_route_t route; 60 device_t dev; 61 struct nhi_softc *nsc; 62 63 struct mtx mtx; 64 struct nhi_ring_pair *ring0; 65 TAILQ_HEAD(,router_command) cmd_queue; 66 67 struct router_command *inflight_cmd; 68 69 uint8_t depth; 70 uint8_t max_adap; 71 72 struct router_softc **adapters; 73 74 uint32_t uuid[4]; 75 }; 76 77 struct router_cfg_cap { 78 uint16_t current_cap; 79 uint16_t next_cap; 80 uint32_t space; 81 uint8_t adap; 82 uint8_t cap_id; 83 uint8_t vsc_id; 84 uint8_t vsc_len; 85 uint16_t vsec_len; 86 }; 87 88 /* Router reset registers */ 89 #define ROUTER_HRR 0x39898 90 #define ROUTER_HIR 0x39858 91 92 int tb_router_attach(struct router_softc *, tb_route_t); 93 int tb_router_attach_root(struct nhi_softc *, tb_route_t); 94 int tb_router_detach(struct router_softc *); 95 int tb_config_read(struct router_softc *, u_int, u_int, u_int, u_int, 96 uint32_t *); 97 int tb_config_read_polled(struct router_softc *, u_int, u_int, u_int, u_int, 98 uint32_t *); 99 int tb_config_read_async(struct router_softc *, u_int, u_int, u_int, u_int, 100 uint32_t *, void *); 101 int tb_config_write(struct router_softc *, u_int, u_int, u_int, u_int, 102 uint32_t *); 103 int tb_config_next_cap(struct router_softc *, struct router_cfg_cap *); 104 int tb_config_find_cap(struct router_softc *, struct router_cfg_cap *); 105 int tb_config_find_router_cap(struct router_softc *, u_int, u_int, u_int *); 106 int tb_config_find_router_vsc(struct router_softc *, u_int, u_int *); 107 int tb_config_find_router_vsec(struct router_softc *, u_int, u_int *); 108 int tb_config_find_adapter_cap(struct router_softc *, u_int, u_int, u_int *); 109 int tb_config_get_lc_uuid(struct router_softc *, uint8_t *); 110 111 #define TB_CONFIG_ADDR(seq, space, adapter, dwlen, offset) \ 112 ((seq << TB_CFG_SEQ_SHIFT) | space | \ 113 (adapter << TB_CFG_ADAPTER_SHIFT) | (dwlen << TB_CFG_SIZE_SHIFT) | \ 114 (offset & TB_CFG_ADDR_MASK)) 115 116 #define TB_ROUTE(router) \ 117 ((uint64_t)(router)->route.hi << 32) | (router)->route.lo 118 119 static __inline void * 120 router_get_frame_data(struct router_command *cmd) 121 { 122 return ((void *)cmd->nhicmd->data); 123 } 124 125 /* 126 * Read the Router config space for the router referred to in the softc. 127 * addr - The dword offset in the config space 128 * dwlen - The number of dwords 129 * buf - must be large enough to hold the number of dwords requested. 130 */ 131 static __inline int 132 tb_config_router_read(struct router_softc *sc, u_int addr, u_int dwlen, 133 uint32_t *buf) 134 { 135 return (tb_config_read(sc, TB_CFG_CS_ROUTER, 0, addr, dwlen, buf)); 136 } 137 138 static __inline int 139 tb_config_router_read_polled(struct router_softc *sc, u_int addr, u_int dwlen, 140 uint32_t *buf) 141 { 142 return (tb_config_read_polled(sc, TB_CFG_CS_ROUTER, 0, addr, dwlen, buf)); 143 } 144 145 /* 146 * Write the Router config space for the router referred to in the softc. 147 * addr - The dword offset in the config space 148 * dwlen - The number of dwords 149 * buf - must be large enough to hold the number of dwords requested. 150 */ 151 static __inline int 152 tb_config_router_write(struct router_softc *sc, u_int addr, u_int dwlen, 153 uint32_t *buf) 154 { 155 return (tb_config_write(sc, TB_CFG_CS_ROUTER, 0, addr, dwlen, buf)); 156 } 157 158 /* 159 * Read the Adapter config space for the router referred to in the softc. 160 * adap - Adapter number 161 * addr - The dword offset in the config space 162 * dwlen - The number of dwords 163 * buf - must be large enough to hold the number of dwords requested. 164 */ 165 static __inline int 166 tb_config_adapter_read(struct router_softc *sc, u_int adap, u_int addr, 167 u_int dwlen, uint32_t *buf) 168 { 169 return (tb_config_read(sc, TB_CFG_CS_ADAPTER, adap, addr, dwlen, buf)); 170 } 171 172 /* 173 * Read the Adapter config space for the router referred to in the softc. 174 * adap - Adapter number 175 * addr - The dword offset in the config space 176 * dwlen - The number of dwords 177 * buf - must be large enough to hold the number of dwords requested. 178 */ 179 static __inline int 180 tb_config_adapter_write(struct router_softc *sc, u_int adap, u_int addr, 181 u_int dwlen, uint32_t *buf) 182 { 183 return (tb_config_write(sc, TB_CFG_CS_ADAPTER, adap, addr, dwlen, buf)); 184 } 185 186 /* 187 * Read the Path config space for the router referred to in the softc. 188 * adap - Adapter number 189 * hopid - HopID of the path 190 * len - The number of adjacent paths 191 * buf - must be large enough to hold the number of dwords requested. 192 */ 193 static __inline int 194 tb_config_path_read(struct router_softc *sc, u_int adap, u_int hopid, 195 u_int num, uint32_t *buf) 196 { 197 return (tb_config_read(sc, TB_CFG_CS_PATH, adap, hopid * 2, 198 num * 2, buf)); 199 } 200 201 /* 202 * Write the Path config space for the router referred to in the softc. 203 * adap - Adapter number 204 * hopid - HopID of the path 205 * len - The number of adjacent paths 206 * buf - must be large enough to hold the number of dwords requested. 207 */ 208 static __inline int 209 tb_config_path_write(struct router_softc *sc, u_int adap, u_int hopid, 210 u_int num, uint32_t *buf) 211 { 212 return (tb_config_write(sc, TB_CFG_CS_PATH, adap, hopid * 2, 213 num * 2, buf)); 214 } 215 216 /* 217 * Read the Counters config space for the router referred to in the softc. 218 * Counters come in sets of 3 dwords. 219 * adap - Adapter number 220 * set - The counter set index 221 * num - The number of adjacent counter sets to read 222 * buf - must be large enough to hold the number of dwords requested. 223 */ 224 static __inline int 225 tb_config_counters_read(struct router_softc *sc, u_int adap, u_int set, 226 u_int num, uint32_t *buf) 227 { 228 return (tb_config_read(sc, TB_CFG_CS_COUNTERS, adap, set * 3, 229 num * 3, buf)); 230 } 231 232 static __inline void 233 tb_config_set_root(struct router_softc *sc) 234 { 235 sc->nsc->root_rsc = sc; 236 } 237 238 static __inline void * 239 tb_config_get_root(struct router_softc *sc) 240 { 241 return (sc->nsc->root_rsc); 242 } 243 244 #endif /* _ROUTER_VAR_H */ 245