| /* SPDX-License-Identifier: GPL-2.0 */ |
| /* Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. */ |
| |
| #ifndef _HINIC3_EQS_H_ |
| #define _HINIC3_EQS_H_ |
| |
| #include <linux/interrupt.h> |
| |
| #include "hinic3_hw_cfg.h" |
| #include "hinic3_queue_common.h" |
| |
| #define HINIC3_MAX_AEQS 4 |
| #define HINIC3_MAX_CEQS 32 |
| |
| #define HINIC3_AEQ_MAX_PAGES 4 |
| #define HINIC3_CEQ_MAX_PAGES 8 |
| |
| #define HINIC3_AEQE_SIZE 64 |
| #define HINIC3_CEQE_SIZE 4 |
| |
| #define HINIC3_AEQE_DESC_SIZE 4 |
| #define HINIC3_AEQE_DATA_SIZE (HINIC3_AEQE_SIZE - HINIC3_AEQE_DESC_SIZE) |
| |
| #define HINIC3_DEFAULT_AEQ_LEN 0x10000 |
| #define HINIC3_DEFAULT_CEQ_LEN 0x10000 |
| |
| #define HINIC3_EQ_IRQ_NAME_LEN 64 |
| |
| #define HINIC3_EQ_USLEEP_LOW_BOUND 900 |
| #define HINIC3_EQ_USLEEP_HIGH_BOUND 1000 |
| |
| enum hinic3_eq_type { |
| HINIC3_AEQ = 0, |
| HINIC3_CEQ = 1, |
| }; |
| |
| enum hinic3_eq_intr_mode { |
| HINIC3_INTR_MODE_ARMED = 0, |
| HINIC3_INTR_MODE_ALWAYS = 1, |
| }; |
| |
| enum hinic3_eq_ci_arm_state { |
| HINIC3_EQ_NOT_ARMED = 0, |
| HINIC3_EQ_ARMED = 1, |
| }; |
| |
| struct hinic3_eq { |
| struct hinic3_hwdev *hwdev; |
| struct hinic3_queue_pages qpages; |
| u16 q_id; |
| enum hinic3_eq_type type; |
| u32 eq_len; |
| u32 cons_idx; |
| u8 wrapped; |
| u32 irq_id; |
| u16 msix_entry_idx; |
| char irq_name[HINIC3_EQ_IRQ_NAME_LEN]; |
| struct work_struct aeq_work; |
| |
| u64 soft_intr_jif; |
| }; |
| |
| struct hinic3_aeq_elem { |
| u8 aeqe_data[HINIC3_AEQE_DATA_SIZE]; |
| __be32 desc; |
| }; |
| |
| enum hinic3_aeq_type { |
| HINIC3_HW_INTER_INT = 0, |
| HINIC3_MBX_FROM_FUNC = 1, |
| HINIC3_MSG_FROM_FW = 2, |
| HINIC3_MAX_AEQ_EVENTS = 6, |
| }; |
| |
| typedef void (*hinic3_aeq_event_cb)(struct hinic3_hwdev *hwdev, u8 *data, |
| u8 size); |
| |
| struct hinic3_aeqs { |
| struct hinic3_hwdev *hwdev; |
| hinic3_aeq_event_cb aeq_cb[HINIC3_MAX_AEQ_EVENTS]; |
| struct hinic3_eq aeq[HINIC3_MAX_AEQS]; |
| u16 num_aeqs; |
| struct workqueue_struct *workq; |
| /* lock for aeq event flag */ |
| spinlock_t aeq_lock; |
| }; |
| |
| enum hinic3_ceq_event { |
| HINIC3_CMDQ = 3, |
| HINIC3_MAX_CEQ_EVENTS = 6, |
| }; |
| |
| typedef void (*hinic3_ceq_event_cb)(struct hinic3_hwdev *hwdev, |
| __le32 ceqe_data); |
| |
| struct hinic3_ceqs { |
| struct hinic3_hwdev *hwdev; |
| |
| hinic3_ceq_event_cb ceq_cb[HINIC3_MAX_CEQ_EVENTS]; |
| |
| struct hinic3_eq ceq[HINIC3_MAX_CEQS]; |
| u16 num_ceqs; |
| /* lock for ceq event flag */ |
| spinlock_t ceq_lock; |
| }; |
| |
| int hinic3_aeqs_init(struct hinic3_hwdev *hwdev, u16 num_aeqs, |
| struct msix_entry *msix_entries); |
| void hinic3_aeqs_free(struct hinic3_hwdev *hwdev); |
| int hinic3_aeq_register_cb(struct hinic3_hwdev *hwdev, |
| enum hinic3_aeq_type event, |
| hinic3_aeq_event_cb hwe_cb); |
| void hinic3_aeq_unregister_cb(struct hinic3_hwdev *hwdev, |
| enum hinic3_aeq_type event); |
| void hinic3_dump_aeq_info(struct hinic3_hwdev *hwdev); |
| |
| int hinic3_ceqs_init(struct hinic3_hwdev *hwdev, u16 num_ceqs, |
| struct msix_entry *msix_entries); |
| void hinic3_ceqs_free(struct hinic3_hwdev *hwdev); |
| int hinic3_ceq_register_cb(struct hinic3_hwdev *hwdev, |
| enum hinic3_ceq_event event, |
| hinic3_ceq_event_cb callback); |
| void hinic3_ceq_unregister_cb(struct hinic3_hwdev *hwdev, |
| enum hinic3_ceq_event event); |
| void hinic3_dump_ceq_info(struct hinic3_hwdev *hwdev); |
| |
| #endif |