162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All rights reserved. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#ifndef _EFA_COM_H_ 762306a36Sopenharmony_ci#define _EFA_COM_H_ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/delay.h> 1062306a36Sopenharmony_ci#include <linux/device.h> 1162306a36Sopenharmony_ci#include <linux/dma-mapping.h> 1262306a36Sopenharmony_ci#include <linux/semaphore.h> 1362306a36Sopenharmony_ci#include <linux/sched.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include <rdma/ib_verbs.h> 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#include "efa_common_defs.h" 1862306a36Sopenharmony_ci#include "efa_admin_defs.h" 1962306a36Sopenharmony_ci#include "efa_admin_cmds_defs.h" 2062306a36Sopenharmony_ci#include "efa_regs_defs.h" 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#define EFA_MAX_HANDLERS 256 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_cistruct efa_com_admin_cq { 2562306a36Sopenharmony_ci struct efa_admin_acq_entry *entries; 2662306a36Sopenharmony_ci dma_addr_t dma_addr; 2762306a36Sopenharmony_ci spinlock_t lock; /* Protects ACQ */ 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci u16 cc; /* consumer counter */ 3062306a36Sopenharmony_ci u8 phase; 3162306a36Sopenharmony_ci}; 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_cistruct efa_com_admin_sq { 3462306a36Sopenharmony_ci struct efa_admin_aq_entry *entries; 3562306a36Sopenharmony_ci dma_addr_t dma_addr; 3662306a36Sopenharmony_ci spinlock_t lock; /* Protects ASQ */ 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci u32 __iomem *db_addr; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci u16 cc; /* consumer counter */ 4162306a36Sopenharmony_ci u16 pc; /* producer counter */ 4262306a36Sopenharmony_ci u8 phase; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci}; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci/* Don't use anything other than atomic64 */ 4762306a36Sopenharmony_cistruct efa_com_stats_admin { 4862306a36Sopenharmony_ci atomic64_t submitted_cmd; 4962306a36Sopenharmony_ci atomic64_t completed_cmd; 5062306a36Sopenharmony_ci atomic64_t cmd_err; 5162306a36Sopenharmony_ci atomic64_t no_completion; 5262306a36Sopenharmony_ci}; 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_cienum { 5562306a36Sopenharmony_ci EFA_AQ_STATE_RUNNING_BIT = 0, 5662306a36Sopenharmony_ci EFA_AQ_STATE_POLLING_BIT = 1, 5762306a36Sopenharmony_ci}; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_cistruct efa_com_admin_queue { 6062306a36Sopenharmony_ci void *dmadev; 6162306a36Sopenharmony_ci void *efa_dev; 6262306a36Sopenharmony_ci struct efa_comp_ctx *comp_ctx; 6362306a36Sopenharmony_ci u32 completion_timeout; /* usecs */ 6462306a36Sopenharmony_ci u16 poll_interval; /* msecs */ 6562306a36Sopenharmony_ci u16 depth; 6662306a36Sopenharmony_ci struct efa_com_admin_cq cq; 6762306a36Sopenharmony_ci struct efa_com_admin_sq sq; 6862306a36Sopenharmony_ci u16 msix_vector_idx; 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci unsigned long state; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci /* Count the number of available admin commands */ 7362306a36Sopenharmony_ci struct semaphore avail_cmds; 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci struct efa_com_stats_admin stats; 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci spinlock_t comp_ctx_lock; /* Protects completion context pool */ 7862306a36Sopenharmony_ci u32 *comp_ctx_pool; 7962306a36Sopenharmony_ci u16 comp_ctx_pool_next; 8062306a36Sopenharmony_ci}; 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_cistruct efa_aenq_handlers; 8362306a36Sopenharmony_cistruct efa_com_eq; 8462306a36Sopenharmony_citypedef void (*efa_eqe_handler)(struct efa_com_eq *eeq, 8562306a36Sopenharmony_ci struct efa_admin_eqe *eqe); 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_cistruct efa_com_aenq { 8862306a36Sopenharmony_ci struct efa_admin_aenq_entry *entries; 8962306a36Sopenharmony_ci struct efa_aenq_handlers *aenq_handlers; 9062306a36Sopenharmony_ci dma_addr_t dma_addr; 9162306a36Sopenharmony_ci u32 cc; /* consumer counter */ 9262306a36Sopenharmony_ci u16 msix_vector_idx; 9362306a36Sopenharmony_ci u16 depth; 9462306a36Sopenharmony_ci u8 phase; 9562306a36Sopenharmony_ci}; 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_cistruct efa_com_mmio_read { 9862306a36Sopenharmony_ci struct efa_admin_mmio_req_read_less_resp *read_resp; 9962306a36Sopenharmony_ci dma_addr_t read_resp_dma_addr; 10062306a36Sopenharmony_ci u16 seq_num; 10162306a36Sopenharmony_ci u16 mmio_read_timeout; /* usecs */ 10262306a36Sopenharmony_ci /* serializes mmio reads */ 10362306a36Sopenharmony_ci spinlock_t lock; 10462306a36Sopenharmony_ci}; 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_cistruct efa_com_dev { 10762306a36Sopenharmony_ci struct efa_com_admin_queue aq; 10862306a36Sopenharmony_ci struct efa_com_aenq aenq; 10962306a36Sopenharmony_ci u8 __iomem *reg_bar; 11062306a36Sopenharmony_ci void *dmadev; 11162306a36Sopenharmony_ci void *efa_dev; 11262306a36Sopenharmony_ci u32 supported_features; 11362306a36Sopenharmony_ci u32 dma_addr_bits; 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci struct efa_com_mmio_read mmio_read; 11662306a36Sopenharmony_ci}; 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_cistruct efa_com_eq { 11962306a36Sopenharmony_ci struct efa_com_dev *edev; 12062306a36Sopenharmony_ci struct efa_admin_eqe *eqes; 12162306a36Sopenharmony_ci dma_addr_t dma_addr; 12262306a36Sopenharmony_ci u32 cc; /* Consumer counter */ 12362306a36Sopenharmony_ci u16 eqn; 12462306a36Sopenharmony_ci u16 depth; 12562306a36Sopenharmony_ci u8 phase; 12662306a36Sopenharmony_ci efa_eqe_handler cb; 12762306a36Sopenharmony_ci}; 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_cistruct efa_com_create_eq_params { 13062306a36Sopenharmony_ci dma_addr_t dma_addr; 13162306a36Sopenharmony_ci u32 event_bitmask; 13262306a36Sopenharmony_ci u16 depth; 13362306a36Sopenharmony_ci u8 entry_size_in_bytes; 13462306a36Sopenharmony_ci u8 msix_vec; 13562306a36Sopenharmony_ci}; 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_cistruct efa_com_create_eq_result { 13862306a36Sopenharmony_ci u16 eqn; 13962306a36Sopenharmony_ci}; 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_cistruct efa_com_destroy_eq_params { 14262306a36Sopenharmony_ci u16 eqn; 14362306a36Sopenharmony_ci}; 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_citypedef void (*efa_aenq_handler)(void *data, 14662306a36Sopenharmony_ci struct efa_admin_aenq_entry *aenq_e); 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci/* Holds aenq handlers. Indexed by AENQ event group */ 14962306a36Sopenharmony_cistruct efa_aenq_handlers { 15062306a36Sopenharmony_ci efa_aenq_handler handlers[EFA_MAX_HANDLERS]; 15162306a36Sopenharmony_ci efa_aenq_handler unimplemented_handler; 15262306a36Sopenharmony_ci}; 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_civoid efa_com_set_dma_addr(dma_addr_t addr, u32 *addr_high, u32 *addr_low); 15562306a36Sopenharmony_ciint efa_com_admin_init(struct efa_com_dev *edev, 15662306a36Sopenharmony_ci struct efa_aenq_handlers *aenq_handlers); 15762306a36Sopenharmony_civoid efa_com_admin_destroy(struct efa_com_dev *edev); 15862306a36Sopenharmony_ciint efa_com_eq_init(struct efa_com_dev *edev, struct efa_com_eq *eeq, 15962306a36Sopenharmony_ci efa_eqe_handler cb, u16 depth, u8 msix_vec); 16062306a36Sopenharmony_civoid efa_com_eq_destroy(struct efa_com_dev *edev, struct efa_com_eq *eeq); 16162306a36Sopenharmony_ciint efa_com_dev_reset(struct efa_com_dev *edev, 16262306a36Sopenharmony_ci enum efa_regs_reset_reason_types reset_reason); 16362306a36Sopenharmony_civoid efa_com_set_admin_polling_mode(struct efa_com_dev *edev, bool polling); 16462306a36Sopenharmony_civoid efa_com_admin_q_comp_intr_handler(struct efa_com_dev *edev); 16562306a36Sopenharmony_ciint efa_com_mmio_reg_read_init(struct efa_com_dev *edev); 16662306a36Sopenharmony_civoid efa_com_mmio_reg_read_destroy(struct efa_com_dev *edev); 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ciint efa_com_validate_version(struct efa_com_dev *edev); 16962306a36Sopenharmony_ciint efa_com_get_dma_width(struct efa_com_dev *edev); 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ciint efa_com_cmd_exec(struct efa_com_admin_queue *aq, 17262306a36Sopenharmony_ci struct efa_admin_aq_entry *cmd, 17362306a36Sopenharmony_ci size_t cmd_size, 17462306a36Sopenharmony_ci struct efa_admin_acq_entry *comp, 17562306a36Sopenharmony_ci size_t comp_size); 17662306a36Sopenharmony_civoid efa_com_aenq_intr_handler(struct efa_com_dev *edev, void *data); 17762306a36Sopenharmony_civoid efa_com_eq_comp_intr_handler(struct efa_com_dev *edev, 17862306a36Sopenharmony_ci struct efa_com_eq *eeq); 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci#endif /* _EFA_COM_H_ */ 181