diff options
Diffstat (limited to 'sys/dev/thunderbolt/router_var.h')
-rw-r--r-- | sys/dev/thunderbolt/router_var.h | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/sys/dev/thunderbolt/router_var.h b/sys/dev/thunderbolt/router_var.h new file mode 100644 index 000000000000..8366ede852e7 --- /dev/null +++ b/sys/dev/thunderbolt/router_var.h @@ -0,0 +1,242 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2022 Scott Long + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _ROUTER_VAR_H +#define _ROUTER_VAR_H + +struct router_softc; +struct router_command; +struct router_topo; + +typedef void (*router_callback_t)(struct router_softc *, + struct router_command *, void *); + +struct router_command { + TAILQ_ENTRY(router_command) link; + struct router_softc *sc; + struct nhi_cmd_frame *nhicmd; + u_int flags; +#define RCMD_POLLED (1 << 0) +#define RCMD_POLL_COMPLETE (1 << 1) + int resp_len; + router_callback_t callback; + void *callback_arg; + u_int dwlen; + u_int timeout; + int retries; + u_int ev; + uint8_t resp_buffer[NHI_RING0_FRAME_SIZE]; +}; + +struct router_softc { + TAILQ_ENTRY(router_softc) link; + u_int debug; + tb_route_t route; + device_t dev; + struct nhi_softc *nsc; + + struct mtx mtx; + struct nhi_ring_pair *ring0; + TAILQ_HEAD(,router_command) cmd_queue; + + struct router_command *inflight_cmd; + + uint8_t depth; + uint8_t max_adap; + + struct router_softc **adapters; + + uint32_t uuid[4]; +}; + +struct router_cfg_cap { + uint16_t current_cap; + uint16_t next_cap; + uint32_t space; + uint8_t adap; + uint8_t cap_id; + uint8_t vsc_id; + uint8_t vsc_len; + uint16_t vsec_len; +}; + +int tb_router_attach(struct router_softc *, tb_route_t); +int tb_router_attach_root(struct nhi_softc *, tb_route_t); +int tb_router_detach(struct router_softc *); +int tb_config_read(struct router_softc *, u_int, u_int, u_int, u_int, + uint32_t *); +int tb_config_read_polled(struct router_softc *, u_int, u_int, u_int, u_int, + uint32_t *); +int tb_config_read_async(struct router_softc *, u_int, u_int, u_int, u_int, + uint32_t *, void *); +int tb_config_write(struct router_softc *, u_int, u_int, u_int, u_int, + uint32_t *); +int tb_config_next_cap(struct router_softc *, struct router_cfg_cap *); +int tb_config_find_cap(struct router_softc *, struct router_cfg_cap *); +int tb_config_find_router_cap(struct router_softc *, u_int, u_int, u_int *); +int tb_config_find_router_vsc(struct router_softc *, u_int, u_int *); +int tb_config_find_router_vsec(struct router_softc *, u_int, u_int *); +int tb_config_find_adapter_cap(struct router_softc *, u_int, u_int, u_int *); +int tb_config_get_lc_uuid(struct router_softc *, uint8_t *); + +#define TB_CONFIG_ADDR(seq, space, adapter, dwlen, offset) \ + ((seq << TB_CFG_SEQ_SHIFT) | space | \ + (adapter << TB_CFG_ADAPTER_SHIFT) | (dwlen << TB_CFG_SIZE_SHIFT) | \ + (offset & TB_CFG_ADDR_MASK)) + +#define TB_ROUTE(router) \ + ((uint64_t)(router)->route.hi << 32) | (router)->route.lo + +static __inline void * +router_get_frame_data(struct router_command *cmd) +{ + return ((void *)cmd->nhicmd->data); +} + +/* + * Read the Router config space for the router referred to in the softc. + * addr - The dword offset in the config space + * dwlen - The number of dwords + * buf - must be large enough to hold the number of dwords requested. + */ +static __inline int +tb_config_router_read(struct router_softc *sc, u_int addr, u_int dwlen, + uint32_t *buf) +{ + return (tb_config_read(sc, TB_CFG_CS_ROUTER, 0, addr, dwlen, buf)); +} + +static __inline int +tb_config_router_read_polled(struct router_softc *sc, u_int addr, u_int dwlen, + uint32_t *buf) +{ + return (tb_config_read_polled(sc, TB_CFG_CS_ROUTER, 0, addr, dwlen, buf)); +} + +/* + * Write the Router config space for the router referred to in the softc. + * addr - The dword offset in the config space + * dwlen - The number of dwords + * buf - must be large enough to hold the number of dwords requested. + */ +static __inline int +tb_config_router_write(struct router_softc *sc, u_int addr, u_int dwlen, + uint32_t *buf) +{ + return (tb_config_write(sc, TB_CFG_CS_ROUTER, 0, addr, dwlen, buf)); +} + +/* + * Read the Adapter config space for the router referred to in the softc. + * adap - Adapter number + * addr - The dword offset in the config space + * dwlen - The number of dwords + * buf - must be large enough to hold the number of dwords requested. + */ +static __inline int +tb_config_adapter_read(struct router_softc *sc, u_int adap, u_int addr, + u_int dwlen, uint32_t *buf) +{ + return (tb_config_read(sc, TB_CFG_CS_ADAPTER, adap, addr, dwlen, buf)); +} + +/* + * Read the Adapter config space for the router referred to in the softc. + * adap - Adapter number + * addr - The dword offset in the config space + * dwlen - The number of dwords + * buf - must be large enough to hold the number of dwords requested. + */ +static __inline int +tb_config_adapter_write(struct router_softc *sc, u_int adap, u_int addr, + u_int dwlen, uint32_t *buf) +{ + return (tb_config_write(sc, TB_CFG_CS_ADAPTER, adap, addr, dwlen, buf)); +} + +/* + * Read the Path config space for the router referred to in the softc. + * adap - Adapter number + * hopid - HopID of the path + * len - The number of adjacent paths + * buf - must be large enough to hold the number of dwords requested. + */ +static __inline int +tb_config_path_read(struct router_softc *sc, u_int adap, u_int hopid, + u_int num, uint32_t *buf) +{ + return (tb_config_read(sc, TB_CFG_CS_PATH, adap, hopid * 2, + num * 2, buf)); +} + +/* + * Write the Path config space for the router referred to in the softc. + * adap - Adapter number + * hopid - HopID of the path + * len - The number of adjacent paths + * buf - must be large enough to hold the number of dwords requested. + */ +static __inline int +tb_config_path_write(struct router_softc *sc, u_int adap, u_int hopid, + u_int num, uint32_t *buf) +{ + return (tb_config_write(sc, TB_CFG_CS_PATH, adap, hopid * 2, + num * 2, buf)); +} + +/* + * Read the Counters config space for the router referred to in the softc. + * Counters come in sets of 3 dwords. + * adap - Adapter number + * set - The counter set index + * num - The number of adjacent counter sets to read + * buf - must be large enough to hold the number of dwords requested. + */ +static __inline int +tb_config_counters_read(struct router_softc *sc, u_int adap, u_int set, + u_int num, uint32_t *buf) +{ + return (tb_config_read(sc, TB_CFG_CS_COUNTERS, adap, set * 3, + num * 3, buf)); +} + +static __inline void +tb_config_set_root(struct router_softc *sc) +{ + sc->nsc->root_rsc = sc; +} + +static __inline void * +tb_config_get_root(struct router_softc *sc) +{ + return (sc->nsc->root_rsc); +} + +#endif /* _ROUTER_VAR_H */ |