178 lines
3.9 KiB
C
178 lines
3.9 KiB
C
/* SPDX-License-Identifier: GPL-2.0*/
|
|
/* Huawei HiNIC PCI Express Linux driver
|
|
* Copyright(c) 2017 Huawei Technologies Co., Ltd
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms and conditions of the GNU General Public License,
|
|
* version 2, as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* for more details.
|
|
*
|
|
*/
|
|
|
|
#ifndef HINIC_EQS_H
|
|
#include <linux/interrupt.h>
|
|
|
|
#define HINIC_EQS_H
|
|
|
|
#define HINIC_EQ_PAGE_SIZE 0x00001000
|
|
|
|
#define HINIC_HW_MAX_AEQS 4
|
|
#define HINIC_MAX_AEQS 3
|
|
#define HINIC_MAX_CEQS 32
|
|
|
|
#define HINIC_EQ_MAX_PAGES 8
|
|
|
|
#define HINIC_AEQE_SIZE 64
|
|
#define HINIC_CEQE_SIZE 4
|
|
|
|
#define HINIC_AEQE_DESC_SIZE 4
|
|
#define HINIC_AEQE_DATA_SIZE \
|
|
(HINIC_AEQE_SIZE - HINIC_AEQE_DESC_SIZE)
|
|
|
|
#define HINIC_DEFAULT_AEQ_LEN 0x10000
|
|
#define HINIC_DEFAULT_CEQ_LEN 0x10000
|
|
|
|
#define HINIC_VMGW_DEFAULT_AEQ_LEN 128
|
|
#define HINIC_VMGW_DEFAULT_CEQ_LEN 1024
|
|
|
|
#define HINIC_MIN_AEQ_LEN 64
|
|
#define HINIC_MAX_AEQ_LEN (512 * 1024)
|
|
#define HINIC_MIN_CEQ_LEN 64
|
|
#define HINIC_MAX_CEQ_LEN (1024 * 1024)
|
|
|
|
#define HINIC_CEQ_ID_CMDQ 0
|
|
|
|
#define EQ_IRQ_NAME_LEN 64
|
|
|
|
enum hinic_eq_type {
|
|
HINIC_AEQ,
|
|
HINIC_CEQ
|
|
};
|
|
|
|
enum hinic_eq_intr_mode {
|
|
HINIC_INTR_MODE_ARMED,
|
|
HINIC_INTR_MODE_ALWAYS,
|
|
};
|
|
|
|
enum hinic_eq_ci_arm_state {
|
|
HINIC_EQ_NOT_ARMED,
|
|
HINIC_EQ_ARMED,
|
|
};
|
|
|
|
struct hinic_eq {
|
|
struct hinic_hwdev *hwdev;
|
|
u16 q_id;
|
|
enum hinic_eq_type type;
|
|
u32 page_size;
|
|
u32 orig_page_size;
|
|
u32 eq_len;
|
|
|
|
u32 cons_idx;
|
|
u16 wrapped;
|
|
|
|
u16 elem_size;
|
|
u16 num_pages;
|
|
u32 num_elem_in_pg;
|
|
|
|
struct irq_info eq_irq;
|
|
char irq_name[EQ_IRQ_NAME_LEN];
|
|
|
|
dma_addr_t *dma_addr;
|
|
u8 **virt_addr;
|
|
dma_addr_t *dma_addr_for_free;
|
|
u8 **virt_addr_for_free;
|
|
|
|
struct work_struct aeq_work;
|
|
struct tasklet_struct ceq_tasklet;
|
|
|
|
u64 hard_intr_jif;
|
|
u64 soft_intr_jif;
|
|
};
|
|
|
|
struct hinic_aeq_elem {
|
|
u8 aeqe_data[HINIC_AEQE_DATA_SIZE];
|
|
u32 desc;
|
|
};
|
|
|
|
enum hinic_aeq_cb_state {
|
|
HINIC_AEQ_HW_CB_REG = 0,
|
|
HINIC_AEQ_HW_CB_RUNNING,
|
|
HINIC_AEQ_SW_CB_REG,
|
|
HINIC_AEQ_SW_CB_RUNNING,
|
|
};
|
|
|
|
struct hinic_aeqs {
|
|
struct hinic_hwdev *hwdev;
|
|
|
|
hinic_aeq_hwe_cb aeq_hwe_cb[HINIC_MAX_AEQ_EVENTS];
|
|
hinic_aeq_swe_cb aeq_swe_cb[HINIC_MAX_AEQ_SW_EVENTS];
|
|
unsigned long aeq_hw_cb_state[HINIC_MAX_AEQ_EVENTS];
|
|
unsigned long aeq_sw_cb_state[HINIC_MAX_AEQ_SW_EVENTS];
|
|
|
|
struct hinic_eq aeq[HINIC_MAX_AEQS];
|
|
u16 num_aeqs;
|
|
|
|
struct workqueue_struct *workq;
|
|
};
|
|
|
|
enum hinic_ceq_cb_state {
|
|
HINIC_CEQ_CB_REG = 0,
|
|
HINIC_CEQ_CB_RUNNING,
|
|
};
|
|
|
|
struct hinic_ceqs {
|
|
struct hinic_hwdev *hwdev;
|
|
|
|
hinic_ceq_event_cb ceq_cb[HINIC_MAX_CEQ_EVENTS];
|
|
void *ceq_data[HINIC_MAX_CEQ_EVENTS];
|
|
unsigned long ceq_cb_state[HINIC_MAX_CEQ_EVENTS];
|
|
|
|
struct hinic_eq ceq[HINIC_MAX_CEQS];
|
|
u16 num_ceqs;
|
|
};
|
|
|
|
enum hinic_msg_pipe_state {
|
|
PIPE_STATE_IDLE,
|
|
PIPE_STATE_BUSY,
|
|
PIPE_STATE_SUSPEND,
|
|
};
|
|
|
|
#define PIPE_CYCLE_MAX 10000
|
|
|
|
u32 hinic_func_busy_state_get(struct hinic_hwdev *hwdev);
|
|
|
|
void hinic_func_busy_state_set(struct hinic_hwdev *hwdev, u32 cfg);
|
|
|
|
u32 hinic_func_own_bit_get(struct hinic_hwdev *hwdev);
|
|
|
|
void hinic_func_own_bit_set(struct hinic_hwdev *hwdev, u32 cfg);
|
|
|
|
int hinic_aeqs_init(struct hinic_hwdev *hwdev, u16 num_aeqs,
|
|
struct irq_info *msix_entries);
|
|
|
|
void hinic_aeqs_free(struct hinic_hwdev *hwdev);
|
|
|
|
int hinic_ceqs_init(struct hinic_hwdev *hwdev, u16 num_ceqs,
|
|
struct irq_info *msix_entries);
|
|
|
|
void hinic_ceqs_free(struct hinic_hwdev *hwdev);
|
|
|
|
void hinic_get_ceq_irqs(struct hinic_hwdev *hwdev, struct irq_info *irqs,
|
|
u16 *num_irqs);
|
|
|
|
void hinic_get_aeq_irqs(struct hinic_hwdev *hwdev, struct irq_info *irqs,
|
|
u16 *num_irqs);
|
|
|
|
void hinic_dump_ceq_info(struct hinic_hwdev *hwdev);
|
|
|
|
void hinic_dump_aeq_info(struct hinic_hwdev *hwdev);
|
|
|
|
int hinic_reschedule_eq(struct hinic_hwdev *hwdev, enum hinic_eq_type type,
|
|
u16 eq_id);
|
|
|
|
#endif
|