Commit f00fe738 authored by Aviad Krawczyk's avatar Aviad Krawczyk Committed by David S. Miller

net-next/hinic: Add aeqs

Handle aeq elements that are accumulated on the aeq by calling the
registered handler for the specific event.
Signed-off-by: default avatarAviad Krawczyk <aviad.krawczyk@huawei.com>
Signed-off-by: default avatarZhao Chen <zhaochen6@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0ac599c7
...@@ -65,4 +65,53 @@ ...@@ -65,4 +65,53 @@
#define HINIC_CSR_API_CMD_STATUS_ADDR(idx) \ #define HINIC_CSR_API_CMD_STATUS_ADDR(idx) \
(HINIC_CSR_API_CMD_BASE + 0x30 + (idx) * HINIC_CSR_API_CMD_STRIDE) (HINIC_CSR_API_CMD_BASE + 0x30 + (idx) * HINIC_CSR_API_CMD_STRIDE)
/* MSI-X registers */
#define HINIC_CSR_MSIX_CTRL_BASE 0x2000
#define HINIC_CSR_MSIX_CNT_BASE 0x2004
#define HINIC_CSR_MSIX_STRIDE 0x8
#define HINIC_CSR_MSIX_CTRL_ADDR(idx) \
(HINIC_CSR_MSIX_CTRL_BASE + (idx) * HINIC_CSR_MSIX_STRIDE)
#define HINIC_CSR_MSIX_CNT_ADDR(idx) \
(HINIC_CSR_MSIX_CNT_BASE + (idx) * HINIC_CSR_MSIX_STRIDE)
/* EQ registers */
#define HINIC_AEQ_MTT_OFF_BASE_ADDR 0x200
#define HINIC_EQ_MTT_OFF_STRIDE 0x40
#define HINIC_CSR_AEQ_MTT_OFF(id) \
(HINIC_AEQ_MTT_OFF_BASE_ADDR + (id) * HINIC_EQ_MTT_OFF_STRIDE)
#define HINIC_CSR_EQ_PAGE_OFF_STRIDE 8
#define HINIC_CSR_AEQ_HI_PHYS_ADDR_REG(q_id, pg_num) \
(HINIC_CSR_AEQ_MTT_OFF(q_id) + \
(pg_num) * HINIC_CSR_EQ_PAGE_OFF_STRIDE)
#define HINIC_CSR_AEQ_LO_PHYS_ADDR_REG(q_id, pg_num) \
(HINIC_CSR_AEQ_MTT_OFF(q_id) + \
(pg_num) * HINIC_CSR_EQ_PAGE_OFF_STRIDE + 4)
#define HINIC_AEQ_CTRL_0_ADDR_BASE 0xE00
#define HINIC_AEQ_CTRL_1_ADDR_BASE 0xE04
#define HINIC_AEQ_CONS_IDX_ADDR_BASE 0xE08
#define HINIC_AEQ_PROD_IDX_ADDR_BASE 0xE0C
#define HINIC_EQ_OFF_STRIDE 0x80
#define HINIC_CSR_AEQ_CTRL_0_ADDR(idx) \
(HINIC_AEQ_CTRL_0_ADDR_BASE + (idx) * HINIC_EQ_OFF_STRIDE)
#define HINIC_CSR_AEQ_CTRL_1_ADDR(idx) \
(HINIC_AEQ_CTRL_1_ADDR_BASE + (idx) * HINIC_EQ_OFF_STRIDE)
#define HINIC_CSR_AEQ_CONS_IDX_ADDR(idx) \
(HINIC_AEQ_CONS_IDX_ADDR_BASE + (idx) * HINIC_EQ_OFF_STRIDE)
#define HINIC_CSR_AEQ_PROD_IDX_ADDR(idx) \
(HINIC_AEQ_PROD_IDX_ADDR_BASE + (idx) * HINIC_EQ_OFF_STRIDE)
#endif #endif
...@@ -24,8 +24,84 @@ ...@@ -24,8 +24,84 @@
#include "hinic_hw_if.h" #include "hinic_hw_if.h"
#define HINIC_AEQ_CTRL_0_INT_IDX_SHIFT 0
#define HINIC_AEQ_CTRL_0_DMA_ATTR_SHIFT 12
#define HINIC_AEQ_CTRL_0_PCI_INTF_IDX_SHIFT 20
#define HINIC_AEQ_CTRL_0_INT_MODE_SHIFT 31
#define HINIC_AEQ_CTRL_0_INT_IDX_MASK 0x3FF
#define HINIC_AEQ_CTRL_0_DMA_ATTR_MASK 0x3F
#define HINIC_AEQ_CTRL_0_PCI_INTF_IDX_MASK 0x3
#define HINIC_AEQ_CTRL_0_INT_MODE_MASK 0x1
#define HINIC_AEQ_CTRL_0_SET(val, member) \
(((u32)(val) & HINIC_AEQ_CTRL_0_##member##_MASK) << \
HINIC_AEQ_CTRL_0_##member##_SHIFT)
#define HINIC_AEQ_CTRL_0_CLEAR(val, member) \
((val) & (~(HINIC_AEQ_CTRL_0_##member##_MASK \
<< HINIC_AEQ_CTRL_0_##member##_SHIFT)))
#define HINIC_AEQ_CTRL_1_LEN_SHIFT 0
#define HINIC_AEQ_CTRL_1_ELEM_SIZE_SHIFT 24
#define HINIC_AEQ_CTRL_1_PAGE_SIZE_SHIFT 28
#define HINIC_AEQ_CTRL_1_LEN_MASK 0x1FFFFF
#define HINIC_AEQ_CTRL_1_ELEM_SIZE_MASK 0x3
#define HINIC_AEQ_CTRL_1_PAGE_SIZE_MASK 0xF
#define HINIC_AEQ_CTRL_1_SET(val, member) \
(((u32)(val) & HINIC_AEQ_CTRL_1_##member##_MASK) << \
HINIC_AEQ_CTRL_1_##member##_SHIFT)
#define HINIC_AEQ_CTRL_1_CLEAR(val, member) \
((val) & (~(HINIC_AEQ_CTRL_1_##member##_MASK \
<< HINIC_AEQ_CTRL_1_##member##_SHIFT)))
#define HINIC_EQ_ELEM_DESC_TYPE_SHIFT 0
#define HINIC_EQ_ELEM_DESC_SRC_SHIFT 7
#define HINIC_EQ_ELEM_DESC_SIZE_SHIFT 8
#define HINIC_EQ_ELEM_DESC_WRAPPED_SHIFT 31
#define HINIC_EQ_ELEM_DESC_TYPE_MASK 0x7F
#define HINIC_EQ_ELEM_DESC_SRC_MASK 0x1
#define HINIC_EQ_ELEM_DESC_SIZE_MASK 0xFF
#define HINIC_EQ_ELEM_DESC_WRAPPED_MASK 0x1
#define HINIC_EQ_ELEM_DESC_SET(val, member) \
(((u32)(val) & HINIC_EQ_ELEM_DESC_##member##_MASK) << \
HINIC_EQ_ELEM_DESC_##member##_SHIFT)
#define HINIC_EQ_ELEM_DESC_GET(val, member) \
(((val) >> HINIC_EQ_ELEM_DESC_##member##_SHIFT) & \
HINIC_EQ_ELEM_DESC_##member##_MASK)
#define HINIC_EQ_CI_IDX_SHIFT 0
#define HINIC_EQ_CI_WRAPPED_SHIFT 20
#define HINIC_EQ_CI_XOR_CHKSUM_SHIFT 24
#define HINIC_EQ_CI_INT_ARMED_SHIFT 31
#define HINIC_EQ_CI_IDX_MASK 0xFFFFF
#define HINIC_EQ_CI_WRAPPED_MASK 0x1
#define HINIC_EQ_CI_XOR_CHKSUM_MASK 0xF
#define HINIC_EQ_CI_INT_ARMED_MASK 0x1
#define HINIC_EQ_CI_SET(val, member) \
(((u32)(val) & HINIC_EQ_CI_##member##_MASK) << \
HINIC_EQ_CI_##member##_SHIFT)
#define HINIC_EQ_CI_CLEAR(val, member) \
((val) & (~(HINIC_EQ_CI_##member##_MASK \
<< HINIC_EQ_CI_##member##_SHIFT)))
#define HINIC_MAX_AEQS 4 #define HINIC_MAX_AEQS 4
#define HINIC_AEQE_SIZE 64
#define HINIC_AEQE_DESC_SIZE 4
#define HINIC_AEQE_DATA_SIZE \
(HINIC_AEQE_SIZE - HINIC_AEQE_DESC_SIZE)
#define HINIC_DEFAULT_AEQ_LEN 64 #define HINIC_DEFAULT_AEQ_LEN 64
#define HINIC_EQ_PAGE_SIZE SZ_4K #define HINIC_EQ_PAGE_SIZE SZ_4K
...@@ -45,6 +121,11 @@ enum hinic_eqe_state { ...@@ -45,6 +121,11 @@ enum hinic_eqe_state {
HINIC_EQE_RUNNING = BIT(1), HINIC_EQE_RUNNING = BIT(1),
}; };
struct hinic_aeq_elem {
u8 data[HINIC_AEQE_DATA_SIZE];
u32 desc;
};
struct hinic_eq_work { struct hinic_eq_work {
struct work_struct work; struct work_struct work;
void *data; void *data;
......
...@@ -25,6 +25,96 @@ ...@@ -25,6 +25,96 @@
#define PCIE_ATTR_ENTRY 0 #define PCIE_ATTR_ENTRY 0
#define VALID_MSIX_IDX(attr, msix_index) ((msix_index) < (attr)->num_irqs)
/**
* hinic_msix_attr_set - set message attribute for msix entry
* @hwif: the HW interface of a pci function device
* @msix_index: msix_index
* @pending_limit: the maximum pending interrupt events (unit 8)
* @coalesc_timer: coalesc period for interrupt (unit 8 us)
* @lli_timer: replenishing period for low latency credit (unit 8 us)
* @lli_credit_limit: maximum credits for low latency msix messages (unit 8)
* @resend_timer: maximum wait for resending msix (unit coalesc period)
*
* Return 0 - Success, negative - Failure
**/
int hinic_msix_attr_set(struct hinic_hwif *hwif, u16 msix_index,
u8 pending_limit, u8 coalesc_timer,
u8 lli_timer, u8 lli_credit_limit,
u8 resend_timer)
{
u32 msix_ctrl, addr;
if (!VALID_MSIX_IDX(&hwif->attr, msix_index))
return -EINVAL;
msix_ctrl = HINIC_MSIX_ATTR_SET(pending_limit, PENDING_LIMIT) |
HINIC_MSIX_ATTR_SET(coalesc_timer, COALESC_TIMER) |
HINIC_MSIX_ATTR_SET(lli_timer, LLI_TIMER) |
HINIC_MSIX_ATTR_SET(lli_credit_limit, LLI_CREDIT) |
HINIC_MSIX_ATTR_SET(resend_timer, RESEND_TIMER);
addr = HINIC_CSR_MSIX_CTRL_ADDR(msix_index);
hinic_hwif_write_reg(hwif, addr, msix_ctrl);
return 0;
}
/**
* hinic_msix_attr_get - get message attribute of msix entry
* @hwif: the HW interface of a pci function device
* @msix_index: msix_index
* @pending_limit: the maximum pending interrupt events (unit 8)
* @coalesc_timer: coalesc period for interrupt (unit 8 us)
* @lli_timer: replenishing period for low latency credit (unit 8 us)
* @lli_credit_limit: maximum credits for low latency msix messages (unit 8)
* @resend_timer: maximum wait for resending msix (unit coalesc period)
*
* Return 0 - Success, negative - Failure
**/
int hinic_msix_attr_get(struct hinic_hwif *hwif, u16 msix_index,
u8 *pending_limit, u8 *coalesc_timer,
u8 *lli_timer, u8 *lli_credit_limit,
u8 *resend_timer)
{
u32 addr, val;
if (!VALID_MSIX_IDX(&hwif->attr, msix_index))
return -EINVAL;
addr = HINIC_CSR_MSIX_CTRL_ADDR(msix_index);
val = hinic_hwif_read_reg(hwif, addr);
*pending_limit = HINIC_MSIX_ATTR_GET(val, PENDING_LIMIT);
*coalesc_timer = HINIC_MSIX_ATTR_GET(val, COALESC_TIMER);
*lli_timer = HINIC_MSIX_ATTR_GET(val, LLI_TIMER);
*lli_credit_limit = HINIC_MSIX_ATTR_GET(val, LLI_CREDIT);
*resend_timer = HINIC_MSIX_ATTR_GET(val, RESEND_TIMER);
return 0;
}
/**
* hinic_msix_attr_cnt_clear - clear message attribute counters for msix entry
* @hwif: the HW interface of a pci function device
* @msix_index: msix_index
*
* Return 0 - Success, negative - Failure
**/
int hinic_msix_attr_cnt_clear(struct hinic_hwif *hwif, u16 msix_index)
{
u32 msix_ctrl, addr;
if (!VALID_MSIX_IDX(&hwif->attr, msix_index))
return -EINVAL;
msix_ctrl = HINIC_MSIX_CNT_SET(1, RESEND_TIMER);
addr = HINIC_CSR_MSIX_CNT_ADDR(msix_index);
hinic_hwif_write_reg(hwif, addr, msix_ctrl);
return 0;
}
/** /**
* hwif_ready - test if the HW is ready for use * hwif_ready - test if the HW is ready for use
* @hwif: the HW interface of a pci function device * @hwif: the HW interface of a pci function device
......
...@@ -88,6 +88,34 @@ ...@@ -88,6 +88,34 @@
((val) & (~(HINIC_PPF_ELECTION_##member##_MASK \ ((val) & (~(HINIC_PPF_ELECTION_##member##_MASK \
<< HINIC_PPF_ELECTION_##member##_SHIFT))) << HINIC_PPF_ELECTION_##member##_SHIFT)))
#define HINIC_MSIX_PENDING_LIMIT_SHIFT 0
#define HINIC_MSIX_COALESC_TIMER_SHIFT 8
#define HINIC_MSIX_LLI_TIMER_SHIFT 16
#define HINIC_MSIX_LLI_CREDIT_SHIFT 24
#define HINIC_MSIX_RESEND_TIMER_SHIFT 29
#define HINIC_MSIX_PENDING_LIMIT_MASK 0xFF
#define HINIC_MSIX_COALESC_TIMER_MASK 0xFF
#define HINIC_MSIX_LLI_TIMER_MASK 0xFF
#define HINIC_MSIX_LLI_CREDIT_MASK 0x1F
#define HINIC_MSIX_RESEND_TIMER_MASK 0x7
#define HINIC_MSIX_ATTR_SET(val, member) \
(((u32)(val) & HINIC_MSIX_##member##_MASK) << \
HINIC_MSIX_##member##_SHIFT)
#define HINIC_MSIX_ATTR_GET(val, member) \
(((val) >> HINIC_MSIX_##member##_SHIFT) & \
HINIC_MSIX_##member##_MASK)
#define HINIC_MSIX_CNT_RESEND_TIMER_SHIFT 29
#define HINIC_MSIX_CNT_RESEND_TIMER_MASK 0x1
#define HINIC_MSIX_CNT_SET(val, member) \
(((u32)(val) & HINIC_MSIX_CNT_##member##_MASK) << \
HINIC_MSIX_CNT_##member##_SHIFT)
#define HINIC_HWIF_NUM_AEQS(hwif) ((hwif)->attr.num_aeqs) #define HINIC_HWIF_NUM_AEQS(hwif) ((hwif)->attr.num_aeqs)
#define HINIC_HWIF_NUM_CEQS(hwif) ((hwif)->attr.num_ceqs) #define HINIC_HWIF_NUM_CEQS(hwif) ((hwif)->attr.num_ceqs)
#define HINIC_HWIF_NUM_IRQS(hwif) ((hwif)->attr.num_irqs) #define HINIC_HWIF_NUM_IRQS(hwif) ((hwif)->attr.num_irqs)
...@@ -105,6 +133,12 @@ ...@@ -105,6 +133,12 @@
#define HINIC_PCIE_AT_DISABLE 0 #define HINIC_PCIE_AT_DISABLE 0
#define HINIC_PCIE_PH_DISABLE 0 #define HINIC_PCIE_PH_DISABLE 0
#define HINIC_EQ_MSIX_PENDING_LIMIT_DEFAULT 0 /* Disabled */
#define HINIC_EQ_MSIX_COALESC_TIMER_DEFAULT 0xFF /* max */
#define HINIC_EQ_MSIX_LLI_TIMER_DEFAULT 0 /* Disabled */
#define HINIC_EQ_MSIX_LLI_CREDIT_LIMIT_DEFAULT 0 /* Disabled */
#define HINIC_EQ_MSIX_RESEND_TIMER_DEFAULT 7 /* max */
enum hinic_pcie_nosnoop { enum hinic_pcie_nosnoop {
HINIC_PCIE_SNOOP = 0, HINIC_PCIE_SNOOP = 0,
HINIC_PCIE_NO_SNOOP = 1, HINIC_PCIE_NO_SNOOP = 1,
...@@ -166,6 +200,18 @@ static inline void hinic_hwif_write_reg(struct hinic_hwif *hwif, u32 reg, ...@@ -166,6 +200,18 @@ static inline void hinic_hwif_write_reg(struct hinic_hwif *hwif, u32 reg,
writel(cpu_to_be32(val), hwif->cfg_regs_bar + reg); writel(cpu_to_be32(val), hwif->cfg_regs_bar + reg);
} }
int hinic_msix_attr_set(struct hinic_hwif *hwif, u16 msix_index,
u8 pending_limit, u8 coalesc_timer,
u8 lli_timer_cfg, u8 lli_credit_limit,
u8 resend_timer);
int hinic_msix_attr_get(struct hinic_hwif *hwif, u16 msix_index,
u8 *pending_limit, u8 *coalesc_timer_cfg,
u8 *lli_timer, u8 *lli_credit_limit,
u8 *resend_timer);
int hinic_msix_attr_cnt_clear(struct hinic_hwif *hwif, u16 msix_index);
int hinic_init_hwif(struct hinic_hwif *hwif, struct pci_dev *pdev); int hinic_init_hwif(struct hinic_hwif *hwif, struct pci_dev *pdev);
void hinic_free_hwif(struct hinic_hwif *hwif); void hinic_free_hwif(struct hinic_hwif *hwif);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment