/*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright © 2021-2022 Dmitry Salychev * * 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. */ #ifndef _DPAA2_MCP_H #define _DPAA2_MCP_H #include #include #include "dpaa2_types.h" /* * DPAA2 MC command interface helper routines. */ #define DPAA2_PORTAL_TIMEOUT 100000 /* us */ #define DPAA2_MCP_MEM_WIDTH 0x40 /* Minimal size of the MC portal. */ #define DPAA2_MCP_MAX_RESOURCES 1 /* resources per DPMCP: 1 SYS_MEM */ /* * Portal flags. * * TODO: Use the same flags for both MC and software portals. */ #define DPAA2_PORTAL_DEF 0x0u #define DPAA2_PORTAL_NOWAIT_ALLOC 0x2u /* Do not sleep during init */ #define DPAA2_PORTAL_LOCKED 0x4000u /* Wait till portal's unlocked */ #define DPAA2_PORTAL_DESTROYED 0x8000u /* Terminate any operations */ /* Command flags. */ #define DPAA2_CMD_DEF 0x0u #define DPAA2_CMD_HIGH_PRIO 0x80u /* High priority command */ #define DPAA2_CMD_INTR_DIS 0x100u /* Disable cmd finished intr */ #define DPAA2_CMD_NOWAIT_ALLOC 0x8000u /* Do not sleep during init */ /* DPAA2 command return codes. */ #define DPAA2_CMD_STAT_OK 0x0 /* Set by MC on success */ #define DPAA2_CMD_STAT_READY 0x1 /* Ready to be processed */ #define DPAA2_CMD_STAT_AUTH_ERR 0x3 /* Illegal object-portal-icid */ #define DPAA2_CMD_STAT_NO_PRIVILEGE 0x4 /* No privilege */ #define DPAA2_CMD_STAT_DMA_ERR 0x5 /* DMA or I/O error */ #define DPAA2_CMD_STAT_CONFIG_ERR 0x6 /* Invalid/conflicting params */ #define DPAA2_CMD_STAT_TIMEOUT 0x7 /* Command timed out */ #define DPAA2_CMD_STAT_NO_RESOURCE 0x8 /* No DPAA2 resources */ #define DPAA2_CMD_STAT_NO_MEMORY 0x9 /* No memory available */ #define DPAA2_CMD_STAT_BUSY 0xA /* Device is busy */ #define DPAA2_CMD_STAT_UNSUPPORTED_OP 0xB /* Unsupported operation */ #define DPAA2_CMD_STAT_INVALID_STATE 0xC /* Invalid state */ /* Driver-specific return codes. */ #define DPAA2_CMD_STAT_UNKNOWN_OBJ 0xFD /* Unknown DPAA2 object. */ #define DPAA2_CMD_STAT_EINVAL 0xFE /* Invalid argument */ #define DPAA2_CMD_STAT_ERR 0xFF /* General error */ /* Object's memory region flags. */ #define DPAA2_RC_REG_CACHEABLE 0x1 /* Cacheable memory mapping */ #define DPAA2_HW_FLAG_HIGH_PRIO 0x80u #define DPAA2_SW_FLAG_INTR_DIS 0x01u #define DPAA2_CMD_PARAMS_N 7u #define DPAA2_LABEL_SZ 16 /* ------------------------- MNG command IDs -------------------------------- */ #define CMD_MNG_BASE_VERSION 1 #define CMD_MNG_ID_OFFSET 4 #define CMD_MNG(id) (((id) << CMD_MNG_ID_OFFSET) | CMD_MNG_BASE_VERSION) #define CMDID_MNG_GET_VER CMD_MNG(0x831) #define CMDID_MNG_GET_SOC_VER CMD_MNG(0x832) #define CMDID_MNG_GET_CONT_ID CMD_MNG(0x830) /* ------------------------- DPRC command IDs ------------------------------- */ #define CMD_RC_BASE_VERSION 1 #define CMD_RC_2ND_VERSION 2 #define CMD_RC_3RD_VERSION 3 #define CMD_RC_ID_OFFSET 4 #define CMD_RC(id) (((id) << CMD_RC_ID_OFFSET) | CMD_RC_BASE_VERSION) #define CMD_RC_V2(id) (((id) << CMD_RC_ID_OFFSET) | CMD_RC_2ND_VERSION) #define CMD_RC_V3(id) (((id) << CMD_RC_ID_OFFSET) | CMD_RC_3RD_VERSION) #define CMDID_RC_OPEN CMD_RC(0x805) #define CMDID_RC_CLOSE CMD_RC(0x800) #define CMDID_RC_GET_API_VERSION CMD_RC(0xA05) #define CMDID_RC_GET_ATTR CMD_RC(0x004) #define CMDID_RC_RESET_CONT CMD_RC(0x005) #define CMDID_RC_RESET_CONT_V2 CMD_RC_V2(0x005) #define CMDID_RC_SET_IRQ CMD_RC(0x010) #define CMDID_RC_SET_IRQ_ENABLE CMD_RC(0x012) #define CMDID_RC_SET_IRQ_MASK CMD_RC(0x014) #define CMDID_RC_GET_IRQ_STATUS CMD_RC(0x016) #define CMDID_RC_CLEAR_IRQ_STATUS CMD_RC(0x017) #define CMDID_RC_GET_CONT_ID CMD_RC(0x830) #define CMDID_RC_GET_OBJ_COUNT CMD_RC(0x159) #define CMDID_RC_GET_OBJ CMD_RC(0x15A) #define CMDID_RC_GET_OBJ_DESC CMD_RC(0x162) #define CMDID_RC_GET_OBJ_REG CMD_RC(0x15E) #define CMDID_RC_GET_OBJ_REG_V2 CMD_RC_V2(0x15E) #define CMDID_RC_GET_OBJ_REG_V3 CMD_RC_V3(0x15E) #define CMDID_RC_SET_OBJ_IRQ CMD_RC(0x15F) #define CMDID_RC_GET_CONN CMD_RC(0x16C) /* ------------------------- DPIO command IDs ------------------------------- */ #define CMD_IO_BASE_VERSION 1 #define CMD_IO_ID_OFFSET 4 #define CMD_IO(id) (((id) << CMD_IO_ID_OFFSET) | CMD_IO_BASE_VERSION) #define CMDID_IO_OPEN CMD_IO(0x803) #define CMDID_IO_CLOSE CMD_IO(0x800) #define CMDID_IO_ENABLE CMD_IO(0x002) #define CMDID_IO_DISABLE CMD_IO(0x003) #define CMDID_IO_GET_ATTR CMD_IO(0x004) #define CMDID_IO_RESET CMD_IO(0x005) #define CMDID_IO_SET_IRQ_ENABLE CMD_IO(0x012) #define CMDID_IO_SET_IRQ_MASK CMD_IO(0x014) #define CMDID_IO_GET_IRQ_STATUS CMD_IO(0x016) #define CMDID_IO_ADD_STATIC_DQ_CHAN CMD_IO(0x122) /* ------------------------- DPNI command IDs ------------------------------- */ #define CMD_NI_BASE_VERSION 1 #define CMD_NI_2ND_VERSION 2 #define CMD_NI_4TH_VERSION 4 #define CMD_NI_ID_OFFSET 4 #define CMD_NI(id) (((id) << CMD_NI_ID_OFFSET) | CMD_NI_BASE_VERSION) #define CMD_NI_V2(id) (((id) << CMD_NI_ID_OFFSET) | CMD_NI_2ND_VERSION) #define CMD_NI_V4(id) (((id) << CMD_NI_ID_OFFSET) | CMD_NI_4TH_VERSION) #define CMDID_NI_OPEN CMD_NI(0x801) #define CMDID_NI_CLOSE CMD_NI(0x800) #define CMDID_NI_ENABLE CMD_NI(0x002) #define CMDID_NI_DISABLE CMD_NI(0x003) #define CMDID_NI_GET_API_VER CMD_NI(0xA01) #define CMDID_NI_RESET CMD_NI(0x005) #define CMDID_NI_GET_ATTR CMD_NI(0x004) #define CMDID_NI_SET_BUF_LAYOUT CMD_NI(0x265) #define CMDID_NI_GET_TX_DATA_OFF CMD_NI(0x212) #define CMDID_NI_GET_PORT_MAC_ADDR CMD_NI(0x263) #define CMDID_NI_SET_PRIM_MAC_ADDR CMD_NI(0x224) #define CMDID_NI_GET_PRIM_MAC_ADDR CMD_NI(0x225) #define CMDID_NI_SET_LINK_CFG CMD_NI(0x21A) #define CMDID_NI_GET_LINK_CFG CMD_NI(0x278) #define CMDID_NI_GET_LINK_STATE CMD_NI(0x215) #define CMDID_NI_SET_QOS_TABLE CMD_NI(0x240) #define CMDID_NI_CLEAR_QOS_TABLE CMD_NI(0x243) #define CMDID_NI_SET_POOLS CMD_NI(0x200) #define CMDID_NI_SET_ERR_BEHAVIOR CMD_NI(0x20B) #define CMDID_NI_GET_QUEUE CMD_NI(0x25F) #define CMDID_NI_SET_QUEUE CMD_NI(0x260) #define CMDID_NI_GET_QDID CMD_NI(0x210) #define CMDID_NI_ADD_MAC_ADDR CMD_NI(0x226) #define CMDID_NI_REMOVE_MAC_ADDR CMD_NI(0x227) #define CMDID_NI_CLEAR_MAC_FILTERS CMD_NI(0x228) #define CMDID_NI_SET_MFL CMD_NI(0x216) #define CMDID_NI_SET_OFFLOAD CMD_NI(0x26C) #define CMDID_NI_SET_IRQ_MASK CMD_NI(0x014) #define CMDID_NI_SET_IRQ_ENABLE CMD_NI(0x012) #define CMDID_NI_GET_IRQ_STATUS CMD_NI(0x016) #define CMDID_NI_SET_UNI_PROMISC CMD_NI(0x222) #define CMDID_NI_SET_MULTI_PROMISC CMD_NI(0x220) #define CMDID_NI_GET_STATISTICS CMD_NI(0x25D) #define CMDID_NI_SET_RX_TC_DIST CMD_NI(0x235) /* ------------------------- DPBP command IDs ------------------------------- */ #define CMD_BP_BASE_VERSION 1 #define CMD_BP_ID_OFFSET 4 #define CMD_BP(id) (((id) << CMD_BP_ID_OFFSET) | CMD_BP_BASE_VERSION) #define CMDID_BP_OPEN CMD_BP(0x804) #define CMDID_BP_CLOSE CMD_BP(0x800) #define CMDID_BP_ENABLE CMD_BP(0x002) #define CMDID_BP_DISABLE CMD_BP(0x003) #define CMDID_BP_GET_ATTR CMD_BP(0x004) #define CMDID_BP_RESET CMD_BP(0x005) /* ------------------------- DPMAC command IDs ------------------------------ */ #define CMD_MAC_BASE_VERSION 1 #define CMD_MAC_2ND_VERSION 2 #define CMD_MAC_ID_OFFSET 4 #define CMD_MAC(id) (((id) << CMD_MAC_ID_OFFSET) | CMD_MAC_BASE_VERSION) #define CMD_MAC_V2(id) (((id) << CMD_MAC_ID_OFFSET) | CMD_MAC_2ND_VERSION) #define CMDID_MAC_OPEN CMD_MAC(0x80C) #define CMDID_MAC_CLOSE CMD_MAC(0x800) #define CMDID_MAC_RESET CMD_MAC(0x005) #define CMDID_MAC_MDIO_READ CMD_MAC(0x0C0) #define CMDID_MAC_MDIO_WRITE CMD_MAC(0x0C1) #define CMDID_MAC_GET_ADDR CMD_MAC(0x0C5) #define CMDID_MAC_GET_ATTR CMD_MAC(0x004) #define CMDID_MAC_SET_LINK_STATE CMD_MAC_V2(0x0C3) #define CMDID_MAC_SET_IRQ_MASK CMD_MAC(0x014) #define CMDID_MAC_SET_IRQ_ENABLE CMD_MAC(0x012) #define CMDID_MAC_GET_IRQ_STATUS CMD_MAC(0x016) /* ------------------------- DPCON command IDs ------------------------------ */ #define CMD_CON_BASE_VERSION 1 #define CMD_CON_ID_OFFSET 4 #define CMD_CON(id) (((id) << CMD_CON_ID_OFFSET) | CMD_CON_BASE_VERSION) #define CMDID_CON_OPEN CMD_CON(0x808) #define CMDID_CON_CLOSE CMD_CON(0x800) #define CMDID_CON_ENABLE CMD_CON(0x002) #define CMDID_CON_DISABLE CMD_CON(0x003) #define CMDID_CON_GET_ATTR CMD_CON(0x004) #define CMDID_CON_RESET CMD_CON(0x005) #define CMDID_CON_SET_NOTIF CMD_CON(0x100) /* ------------------------- DPMCP command IDs ------------------------------ */ #define CMD_MCP_BASE_VERSION 1 #define CMD_MCP_2ND_VERSION 2 #define CMD_MCP_ID_OFFSET 4 #define CMD_MCP(id) (((id) << CMD_MCP_ID_OFFSET) | CMD_MCP_BASE_VERSION) #define CMD_MCP_V2(id) (((id) << CMD_MCP_ID_OFFSET) | CMD_MCP_2ND_VERSION) #define CMDID_MCP_CREATE CMD_MCP_V2(0x90B) #define CMDID_MCP_DESTROY CMD_MCP(0x98B) #define CMDID_MCP_OPEN CMD_MCP(0x80B) #define CMDID_MCP_CLOSE CMD_MCP(0x800) #define CMDID_MCP_RESET CMD_MCP(0x005) #define DPAA2_MCP_LOCK(__mcp, __flags) do { \ mtx_assert(&(__mcp)->lock, MA_NOTOWNED); \ mtx_lock(&(__mcp)->lock); \ *(__flags) = (__mcp)->flags; \ (__mcp)->flags |= DPAA2_PORTAL_LOCKED; \ } while (0) #define DPAA2_MCP_UNLOCK(__mcp) do { \ mtx_assert(&(__mcp)->lock, MA_OWNED); \ (__mcp)->flags &= ~DPAA2_PORTAL_LOCKED; \ mtx_unlock(&(__mcp)->lock); \ } while (0) enum dpaa2_rc_region_type { DPAA2_RC_REG_MC_PORTAL, DPAA2_RC_REG_QBMAN_PORTAL }; /** * @brief Helper object to interact with the MC portal. * * res: Unmapped portal's I/O memory. * map: Mapped portal's I/O memory. * lock: Lock to send a command to the portal and wait for the * result. * flags: Current state of the object. * rc_api_major: Major version of the DPRC API. * rc_api_minor: Minor version of the DPRC API. */ struct dpaa2_mcp { struct resource *res; struct resource_map *map; struct mtx lock; uint16_t flags; uint16_t rc_api_major; uint16_t rc_api_minor; }; /** * @brief Command object holds data to be written to the MC portal. * * header: 8 least significant bytes of the MC portal. * params: Parameters to pass together with the command to MC. Might keep * command execution results. * * NOTE: 64 bytes. */ struct dpaa2_cmd { uint64_t header; uint64_t params[DPAA2_CMD_PARAMS_N]; }; /** * @brief Helper object to access fields of the MC command header. * * srcid: The SoC architected source ID of the submitter. This field is * reserved and cannot be written by the driver. * flags_hw: Bits from 8 to 15 of the command header. Most of them are * reserved at the moment. * status: Command ready/status. This field is used as the handshake field * between MC and the driver. MC reports command completion with * success/error codes in this field. * flags_sw: ... * token: ... * cmdid: ... * * NOTE: 8 bytes. */ struct dpaa2_cmd_header { uint8_t srcid; uint8_t flags_hw; uint8_t status; uint8_t flags_sw; uint16_t token; uint16_t cmdid; } __packed; /** * @brief Information about DPAA2 object. * * id: ID of a logical object resource. * vendor: Object vendor identifier. * irq_count: Number of interrupts supported by the object. * reg_count: Number of mappable regions supported by the object. * state: Object state (combination of states). * ver_major: Major version of the object. * ver_minor: Minor version of the object. * flags: Object attributes flags. * type: ... * label: ... */ struct dpaa2_obj { uint32_t id; uint16_t vendor; uint8_t irq_count; uint8_t reg_count; uint32_t state; uint16_t ver_major; uint16_t ver_minor; uint16_t flags; uint8_t label[DPAA2_LABEL_SZ]; enum dpaa2_dev_type type; }; /** * @brief Attributes of the DPRC object. * * cont_id: Container ID. * portal_id: Container's portal ID. * options: Container's options as set at container's creation. * icid: Container's isolation context ID. */ struct dpaa2_rc_attr { uint32_t cont_id; uint32_t portal_id; uint32_t options; uint32_t icid; }; /** * @brief Description of the object's memory region. * * base_paddr: Region base physical address. * base_offset: Region base offset. * size: Region size (in bytes). * flags: Region flags (cacheable, etc.) * type: Type of a software portal this region belongs to. */ struct dpaa2_rc_obj_region { uint64_t base_paddr; uint64_t base_offset; uint32_t size; uint32_t flags; enum dpaa2_rc_region_type type; }; /** * @brief DPAA2 endpoint descriptor. * * obj_id: Endpoint object ID. * if_id: Interface ID; for endpoints with multiple interfaces * (DPSW, DPDMUX), 0 - otherwise. * type: Endpoint object type, null-terminated string. */ struct dpaa2_ep_desc { uint32_t obj_id; uint32_t if_id; enum dpaa2_dev_type type; }; /** * @brief Configuration of the channel data availability notification (CDAN). * * qman_ctx: Context value provided with each CDAN message. * dpio_id: DPIO object ID configured with a notification channel. * prior: Priority selection within the DPIO channel; valid values * are 0-7, depending on the number of priorities in that channel. */ struct dpaa2_con_notif_cfg { uint64_t qman_ctx; uint32_t dpio_id; uint8_t prior; }; /** * @brief Attributes of the DPMCP object. * * id: DPMCP object ID. * options: Options of the MC portal (disabled high-prio commands, etc.). */ struct dpaa2_mcp_attr { uint32_t id; uint32_t options; }; /** * @brief Software context for the DPAA2 MC portal. */ struct dpaa2_mcp_softc { device_t dev; struct dpaa2_mcp_attr attr; struct resource *res[DPAA2_MCP_MAX_RESOURCES]; struct resource_map map[DPAA2_MCP_MAX_RESOURCES]; }; int dpaa2_mcp_init_portal(struct dpaa2_mcp **mcp, struct resource *res, struct resource_map *map, uint16_t flags); void dpaa2_mcp_free_portal(struct dpaa2_mcp *mcp); /* to quickly update command token */ struct dpaa2_cmd *dpaa2_mcp_tk(struct dpaa2_cmd *cmd, const uint16_t token); /* to quickly update command flags */ struct dpaa2_cmd *dpaa2_mcp_f(struct dpaa2_cmd *cmd, const uint16_t flags); #define DPAA2_CMD_INIT_FLAGS(__cmd, __flags) do { \ KASSERT((__cmd) != NULL, ("%s:%d: failed", __func__, __LINE__)); \ struct dpaa2_cmd_header *__hdr; \ uint32_t __dcpi; \ \ __hdr = (struct dpaa2_cmd_header *)&((__cmd)->header); \ __hdr->srcid = 0; \ __hdr->status = DPAA2_CMD_STAT_OK; \ __hdr->token = 0; \ __hdr->cmdid = 0; \ __hdr->flags_hw = DPAA2_CMD_DEF; \ __hdr->flags_sw = DPAA2_CMD_DEF; \ if ((__flags) & DPAA2_CMD_HIGH_PRIO) { \ __hdr->flags_hw |= DPAA2_HW_FLAG_HIGH_PRIO; \ } \ if ((__flags) & DPAA2_CMD_INTR_DIS) { \ __hdr->flags_sw |= DPAA2_SW_FLAG_INTR_DIS; \ } \ for (__dcpi = 0; __dcpi < DPAA2_CMD_PARAMS_N; __dcpi++) { \ (__cmd)->params[__dcpi] = 0; \ } \ } while (0) #define DPAA2_CMD_INIT(c) DPAA2_CMD_INIT_FLAGS((c), DPAA2_CMD_DEF) #define DPAA2_CMD_TK(c, t) dpaa2_mcp_tk((c), (t)) #define DPAA2_CMD_F(c, f) dpaa2_mcp_f((c), (f)) #endif /* _DPAA2_MCP_H */