1fbfb8031SShannon Nelson /* SPDX-License-Identifier: GPL-2.0 */ 2fbfb8031SShannon Nelson /* Copyright(c) 2017 - 2019 Pensando Systems, Inc */ 3fbfb8031SShannon Nelson 4fbfb8031SShannon Nelson #ifndef _IONIC_DEV_H_ 5fbfb8031SShannon Nelson #define _IONIC_DEV_H_ 6fbfb8031SShannon Nelson 7fbfb8031SShannon Nelson #include <linux/mutex.h> 8fbfb8031SShannon Nelson #include <linux/workqueue.h> 9fbfb8031SShannon Nelson 10fbfb8031SShannon Nelson #include "ionic_if.h" 11fbfb8031SShannon Nelson #include "ionic_regs.h" 12fbfb8031SShannon Nelson 13beead698SShannon Nelson #define IONIC_MIN_MTU ETH_MIN_MTU 14beead698SShannon Nelson #define IONIC_MAX_MTU 9194 15*4d03e00aSShannon Nelson #define IONIC_MAX_TXRX_DESC 16384 16*4d03e00aSShannon Nelson #define IONIC_MIN_TXRX_DESC 16 17*4d03e00aSShannon Nelson #define IONIC_DEF_TXRX_DESC 4096 181a58e196SShannon Nelson #define IONIC_LIFS_MAX 1024 191a58e196SShannon Nelson 20*4d03e00aSShannon Nelson #define IONIC_DEV_CMD_REG_VERSION 1 21*4d03e00aSShannon Nelson #define IONIC_DEV_INFO_REG_COUNT 32 22*4d03e00aSShannon Nelson #define IONIC_DEV_CMD_REG_COUNT 32 23*4d03e00aSShannon Nelson 24fbfb8031SShannon Nelson struct ionic_dev_bar { 25fbfb8031SShannon Nelson void __iomem *vaddr; 26fbfb8031SShannon Nelson phys_addr_t bus_addr; 27fbfb8031SShannon Nelson unsigned long len; 28fbfb8031SShannon Nelson int res_index; 29fbfb8031SShannon Nelson }; 30fbfb8031SShannon Nelson 31fbfb8031SShannon Nelson /* Registers */ 32fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_intr) == 32); 33fbfb8031SShannon Nelson 34fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_doorbell) == 8); 35fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_intr_status) == 8); 36fbfb8031SShannon Nelson static_assert(sizeof(union ionic_dev_regs) == 4096); 37fbfb8031SShannon Nelson static_assert(sizeof(union ionic_dev_info_regs) == 2048); 38fbfb8031SShannon Nelson static_assert(sizeof(union ionic_dev_cmd_regs) == 2048); 39fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_lif_stats) == 1024); 40fbfb8031SShannon Nelson 41fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_admin_cmd) == 64); 42fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_admin_comp) == 16); 43fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_nop_cmd) == 64); 44fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_nop_comp) == 16); 45fbfb8031SShannon Nelson 46fbfb8031SShannon Nelson /* Device commands */ 47fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_dev_identify_cmd) == 64); 48fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_dev_identify_comp) == 16); 49fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_dev_init_cmd) == 64); 50fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_dev_init_comp) == 16); 51fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_dev_reset_cmd) == 64); 52fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_dev_reset_comp) == 16); 53fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_dev_getattr_cmd) == 64); 54fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_dev_getattr_comp) == 16); 55fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_dev_setattr_cmd) == 64); 56fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_dev_setattr_comp) == 16); 57fbfb8031SShannon Nelson 58fbfb8031SShannon Nelson /* Port commands */ 59fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_port_identify_cmd) == 64); 60fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_port_identify_comp) == 16); 61fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_port_init_cmd) == 64); 62fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_port_init_comp) == 16); 63fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_port_reset_cmd) == 64); 64fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_port_reset_comp) == 16); 65fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_port_getattr_cmd) == 64); 66fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_port_getattr_comp) == 16); 67fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_port_setattr_cmd) == 64); 68fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_port_setattr_comp) == 16); 69fbfb8031SShannon Nelson 70fbfb8031SShannon Nelson /* LIF commands */ 71fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_lif_init_cmd) == 64); 72fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_lif_init_comp) == 16); 73fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_lif_reset_cmd) == 64); 74fbfb8031SShannon Nelson static_assert(sizeof(ionic_lif_reset_comp) == 16); 75fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_lif_getattr_cmd) == 64); 76fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_lif_getattr_comp) == 16); 77fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_lif_setattr_cmd) == 64); 78fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_lif_setattr_comp) == 16); 79fbfb8031SShannon Nelson 80fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_q_init_cmd) == 64); 81fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_q_init_comp) == 16); 82fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_q_control_cmd) == 64); 83fbfb8031SShannon Nelson static_assert(sizeof(ionic_q_control_comp) == 16); 84fbfb8031SShannon Nelson 85fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_rx_mode_set_cmd) == 64); 86fbfb8031SShannon Nelson static_assert(sizeof(ionic_rx_mode_set_comp) == 16); 87fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_rx_filter_add_cmd) == 64); 88fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_rx_filter_add_comp) == 16); 89fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_rx_filter_del_cmd) == 64); 90fbfb8031SShannon Nelson static_assert(sizeof(ionic_rx_filter_del_comp) == 16); 91fbfb8031SShannon Nelson 92fbfb8031SShannon Nelson /* RDMA commands */ 93fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_rdma_reset_cmd) == 64); 94fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_rdma_queue_cmd) == 64); 95fbfb8031SShannon Nelson 96fbfb8031SShannon Nelson /* Events */ 97fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_notifyq_cmd) == 4); 98fbfb8031SShannon Nelson static_assert(sizeof(union ionic_notifyq_comp) == 64); 99fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_notifyq_event) == 64); 100fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_link_change_event) == 64); 101fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_reset_event) == 64); 102fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_heartbeat_event) == 64); 103fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_log_event) == 64); 104fbfb8031SShannon Nelson 105fbfb8031SShannon Nelson /* I/O */ 106fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_txq_desc) == 16); 107fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_txq_sg_desc) == 128); 108fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_txq_comp) == 16); 109fbfb8031SShannon Nelson 110fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_rxq_desc) == 16); 111fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_rxq_sg_desc) == 128); 112fbfb8031SShannon Nelson static_assert(sizeof(struct ionic_rxq_comp) == 16); 113fbfb8031SShannon Nelson 114fbfb8031SShannon Nelson struct ionic_devinfo { 115fbfb8031SShannon Nelson u8 asic_type; 116fbfb8031SShannon Nelson u8 asic_rev; 117fbfb8031SShannon Nelson char fw_version[IONIC_DEVINFO_FWVERS_BUFLEN + 1]; 118fbfb8031SShannon Nelson char serial_num[IONIC_DEVINFO_SERIAL_BUFLEN + 1]; 119fbfb8031SShannon Nelson }; 120fbfb8031SShannon Nelson 121fbfb8031SShannon Nelson struct ionic_dev { 122fbfb8031SShannon Nelson union ionic_dev_info_regs __iomem *dev_info_regs; 123fbfb8031SShannon Nelson union ionic_dev_cmd_regs __iomem *dev_cmd_regs; 124fbfb8031SShannon Nelson 125fbfb8031SShannon Nelson u64 __iomem *db_pages; 126fbfb8031SShannon Nelson dma_addr_t phy_db_pages; 127fbfb8031SShannon Nelson 128fbfb8031SShannon Nelson struct ionic_intr __iomem *intr_ctrl; 129fbfb8031SShannon Nelson u64 __iomem *intr_status; 130fbfb8031SShannon Nelson 13104436595SShannon Nelson u32 port_info_sz; 13204436595SShannon Nelson struct ionic_port_info *port_info; 13304436595SShannon Nelson dma_addr_t port_info_pa; 13404436595SShannon Nelson 135fbfb8031SShannon Nelson struct ionic_devinfo dev_info; 136fbfb8031SShannon Nelson }; 137fbfb8031SShannon Nelson 1381d062b7bSShannon Nelson struct ionic_cq_info { 1391d062b7bSShannon Nelson void *cq_desc; 1401d062b7bSShannon Nelson struct ionic_cq_info *next; 1411d062b7bSShannon Nelson unsigned int index; 1421d062b7bSShannon Nelson bool last; 1431d062b7bSShannon Nelson }; 1441d062b7bSShannon Nelson 1451d062b7bSShannon Nelson struct ionic_queue; 1461d062b7bSShannon Nelson struct ionic_qcq; 1471d062b7bSShannon Nelson struct ionic_desc_info; 1481d062b7bSShannon Nelson 1491d062b7bSShannon Nelson typedef void (*ionic_desc_cb)(struct ionic_queue *q, 1501d062b7bSShannon Nelson struct ionic_desc_info *desc_info, 1511d062b7bSShannon Nelson struct ionic_cq_info *cq_info, void *cb_arg); 1521d062b7bSShannon Nelson 1531d062b7bSShannon Nelson struct ionic_desc_info { 1541d062b7bSShannon Nelson void *desc; 1551d062b7bSShannon Nelson void *sg_desc; 1561d062b7bSShannon Nelson struct ionic_desc_info *next; 1571d062b7bSShannon Nelson unsigned int index; 1581d062b7bSShannon Nelson unsigned int left; 1591d062b7bSShannon Nelson ionic_desc_cb cb; 1601d062b7bSShannon Nelson void *cb_arg; 1611d062b7bSShannon Nelson }; 1621d062b7bSShannon Nelson 1631d062b7bSShannon Nelson #define QUEUE_NAME_MAX_SZ 32 1641d062b7bSShannon Nelson 1651d062b7bSShannon Nelson struct ionic_queue { 1661d062b7bSShannon Nelson u64 dbell_count; 1671d062b7bSShannon Nelson u64 drop; 1681d062b7bSShannon Nelson u64 stop; 1691d062b7bSShannon Nelson u64 wake; 1701d062b7bSShannon Nelson struct ionic_lif *lif; 1711d062b7bSShannon Nelson struct ionic_desc_info *info; 1721d062b7bSShannon Nelson struct ionic_desc_info *tail; 1731d062b7bSShannon Nelson struct ionic_desc_info *head; 1741d062b7bSShannon Nelson struct ionic_dev *idev; 1751d062b7bSShannon Nelson unsigned int index; 1761d062b7bSShannon Nelson unsigned int type; 1771d062b7bSShannon Nelson unsigned int hw_index; 1781d062b7bSShannon Nelson unsigned int hw_type; 1791d062b7bSShannon Nelson u64 dbval; 1801d062b7bSShannon Nelson void *base; 1811d062b7bSShannon Nelson void *sg_base; 1821d062b7bSShannon Nelson dma_addr_t base_pa; 1831d062b7bSShannon Nelson dma_addr_t sg_base_pa; 1841d062b7bSShannon Nelson unsigned int num_descs; 1851d062b7bSShannon Nelson unsigned int desc_size; 1861d062b7bSShannon Nelson unsigned int sg_desc_size; 1871d062b7bSShannon Nelson unsigned int pid; 1881d062b7bSShannon Nelson char name[QUEUE_NAME_MAX_SZ]; 1891d062b7bSShannon Nelson }; 1901d062b7bSShannon Nelson 1916461b446SShannon Nelson #define INTR_INDEX_NOT_ASSIGNED -1 1926461b446SShannon Nelson #define INTR_NAME_MAX_SZ 32 1936461b446SShannon Nelson 1946461b446SShannon Nelson struct ionic_intr_info { 1956461b446SShannon Nelson char name[INTR_NAME_MAX_SZ]; 1966461b446SShannon Nelson unsigned int index; 1976461b446SShannon Nelson unsigned int vector; 1986461b446SShannon Nelson u64 rearm_count; 1996461b446SShannon Nelson unsigned int cpu; 2006461b446SShannon Nelson cpumask_t affinity_mask; 2016461b446SShannon Nelson }; 2026461b446SShannon Nelson 2031d062b7bSShannon Nelson struct ionic_cq { 2041d062b7bSShannon Nelson void *base; 2051d062b7bSShannon Nelson dma_addr_t base_pa; 2061d062b7bSShannon Nelson struct ionic_lif *lif; 2071d062b7bSShannon Nelson struct ionic_cq_info *info; 2081d062b7bSShannon Nelson struct ionic_cq_info *tail; 2091d062b7bSShannon Nelson struct ionic_queue *bound_q; 2101d062b7bSShannon Nelson struct ionic_intr_info *bound_intr; 2111d062b7bSShannon Nelson bool done_color; 2121d062b7bSShannon Nelson unsigned int num_descs; 2131d062b7bSShannon Nelson u64 compl_count; 2141d062b7bSShannon Nelson unsigned int desc_size; 2151d062b7bSShannon Nelson }; 2161d062b7bSShannon Nelson 217fbfb8031SShannon Nelson struct ionic; 218fbfb8031SShannon Nelson 2196461b446SShannon Nelson static inline void ionic_intr_init(struct ionic_dev *idev, 2206461b446SShannon Nelson struct ionic_intr_info *intr, 2216461b446SShannon Nelson unsigned long index) 2226461b446SShannon Nelson { 2236461b446SShannon Nelson ionic_intr_clean(idev->intr_ctrl, index); 2246461b446SShannon Nelson intr->index = index; 2256461b446SShannon Nelson } 2266461b446SShannon Nelson 2271d062b7bSShannon Nelson static inline unsigned int ionic_q_space_avail(struct ionic_queue *q) 2281d062b7bSShannon Nelson { 2291d062b7bSShannon Nelson unsigned int avail = q->tail->index; 2301d062b7bSShannon Nelson 2311d062b7bSShannon Nelson if (q->head->index >= avail) 2321d062b7bSShannon Nelson avail += q->head->left - 1; 2331d062b7bSShannon Nelson else 2341d062b7bSShannon Nelson avail -= q->head->index + 1; 2351d062b7bSShannon Nelson 2361d062b7bSShannon Nelson return avail; 2371d062b7bSShannon Nelson } 2381d062b7bSShannon Nelson 2391d062b7bSShannon Nelson static inline bool ionic_q_has_space(struct ionic_queue *q, unsigned int want) 2401d062b7bSShannon Nelson { 2411d062b7bSShannon Nelson return ionic_q_space_avail(q) >= want; 2421d062b7bSShannon Nelson } 2431d062b7bSShannon Nelson 244fbfb8031SShannon Nelson void ionic_init_devinfo(struct ionic *ionic); 245fbfb8031SShannon Nelson int ionic_dev_setup(struct ionic *ionic); 246fbfb8031SShannon Nelson void ionic_dev_teardown(struct ionic *ionic); 247fbfb8031SShannon Nelson 248fbfb8031SShannon Nelson void ionic_dev_cmd_go(struct ionic_dev *idev, union ionic_dev_cmd *cmd); 249fbfb8031SShannon Nelson u8 ionic_dev_cmd_status(struct ionic_dev *idev); 250fbfb8031SShannon Nelson bool ionic_dev_cmd_done(struct ionic_dev *idev); 251fbfb8031SShannon Nelson void ionic_dev_cmd_comp(struct ionic_dev *idev, union ionic_dev_cmd_comp *comp); 252fbfb8031SShannon Nelson 253fbfb8031SShannon Nelson void ionic_dev_cmd_identify(struct ionic_dev *idev, u8 ver); 254fbfb8031SShannon Nelson void ionic_dev_cmd_init(struct ionic_dev *idev); 255fbfb8031SShannon Nelson void ionic_dev_cmd_reset(struct ionic_dev *idev); 256fbfb8031SShannon Nelson 25704436595SShannon Nelson void ionic_dev_cmd_port_identify(struct ionic_dev *idev); 25804436595SShannon Nelson void ionic_dev_cmd_port_init(struct ionic_dev *idev); 25904436595SShannon Nelson void ionic_dev_cmd_port_reset(struct ionic_dev *idev); 26004436595SShannon Nelson void ionic_dev_cmd_port_state(struct ionic_dev *idev, u8 state); 26104436595SShannon Nelson void ionic_dev_cmd_port_speed(struct ionic_dev *idev, u32 speed); 26204436595SShannon Nelson void ionic_dev_cmd_port_autoneg(struct ionic_dev *idev, u8 an_enable); 26304436595SShannon Nelson void ionic_dev_cmd_port_fec(struct ionic_dev *idev, u8 fec_type); 26404436595SShannon Nelson void ionic_dev_cmd_port_pause(struct ionic_dev *idev, u8 pause_type); 26504436595SShannon Nelson 2661a58e196SShannon Nelson void ionic_dev_cmd_lif_identify(struct ionic_dev *idev, u8 type, u8 ver); 2671a58e196SShannon Nelson void ionic_dev_cmd_lif_init(struct ionic_dev *idev, u16 lif_index, 2681a58e196SShannon Nelson dma_addr_t addr); 2691a58e196SShannon Nelson void ionic_dev_cmd_lif_reset(struct ionic_dev *idev, u16 lif_index); 2701d062b7bSShannon Nelson void ionic_dev_cmd_adminq_init(struct ionic_dev *idev, struct ionic_qcq *qcq, 2711d062b7bSShannon Nelson u16 lif_index, u16 intr_index); 2721a58e196SShannon Nelson 2736461b446SShannon Nelson int ionic_db_page_num(struct ionic_lif *lif, int pid); 2746461b446SShannon Nelson 2751d062b7bSShannon Nelson int ionic_cq_init(struct ionic_lif *lif, struct ionic_cq *cq, 2761d062b7bSShannon Nelson struct ionic_intr_info *intr, 2771d062b7bSShannon Nelson unsigned int num_descs, size_t desc_size); 2781d062b7bSShannon Nelson void ionic_cq_map(struct ionic_cq *cq, void *base, dma_addr_t base_pa); 2791d062b7bSShannon Nelson void ionic_cq_bind(struct ionic_cq *cq, struct ionic_queue *q); 2801d062b7bSShannon Nelson typedef bool (*ionic_cq_cb)(struct ionic_cq *cq, struct ionic_cq_info *cq_info); 2811d062b7bSShannon Nelson typedef void (*ionic_cq_done_cb)(void *done_arg); 2821d062b7bSShannon Nelson unsigned int ionic_cq_service(struct ionic_cq *cq, unsigned int work_to_do, 2831d062b7bSShannon Nelson ionic_cq_cb cb, ionic_cq_done_cb done_cb, 2841d062b7bSShannon Nelson void *done_arg); 2851d062b7bSShannon Nelson 2861d062b7bSShannon Nelson int ionic_q_init(struct ionic_lif *lif, struct ionic_dev *idev, 2871d062b7bSShannon Nelson struct ionic_queue *q, unsigned int index, const char *name, 2881d062b7bSShannon Nelson unsigned int num_descs, size_t desc_size, 2891d062b7bSShannon Nelson size_t sg_desc_size, unsigned int pid); 2901d062b7bSShannon Nelson void ionic_q_map(struct ionic_queue *q, void *base, dma_addr_t base_pa); 2911d062b7bSShannon Nelson void ionic_q_sg_map(struct ionic_queue *q, void *base, dma_addr_t base_pa); 2921d062b7bSShannon Nelson void ionic_q_post(struct ionic_queue *q, bool ring_doorbell, ionic_desc_cb cb, 2931d062b7bSShannon Nelson void *cb_arg); 2941d062b7bSShannon Nelson void ionic_q_rewind(struct ionic_queue *q, struct ionic_desc_info *start); 2951d062b7bSShannon Nelson void ionic_q_service(struct ionic_queue *q, struct ionic_cq_info *cq_info, 2961d062b7bSShannon Nelson unsigned int stop_index); 2971d062b7bSShannon Nelson 298fbfb8031SShannon Nelson #endif /* _IONIC_DEV_H_ */ 299