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