diff options
author | Aviad Krawczyk <aviad.krawczyk@huawei.com> | 2017-08-21 23:56:01 +0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-08-22 10:48:53 -0700 |
commit | fc9319e4025d49875fdb97c06618de2c0088ac31 (patch) | |
tree | ece7148606cb60246552a8c46dbd14a69513df14 /drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h | |
parent | d0b9805e8222e86378c04d6bab366181b707631e (diff) | |
download | linux-fc9319e4025d49875fdb97c06618de2c0088ac31.tar.bz2 |
net-next/hinic: Add ceqs
Initialize the completion event queues and handle ceq events by calling
the registered handlers. Used for cmdq command completion.
Signed-off-by: Aviad Krawczyk <aviad.krawczyk@huawei.com>
Signed-off-by: Zhao Chen <zhaochen6@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h')
-rw-r--r-- | drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h b/drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h index ca584c05d30e..ecb9c2bc6dc8 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h @@ -21,6 +21,7 @@ #include <linux/pci.h> #include <linux/sizes.h> #include <linux/bitops.h> +#include <linux/interrupt.h> #include "hinic_hw_if.h" @@ -58,6 +59,40 @@ ((val) & (~(HINIC_AEQ_CTRL_1_##member##_MASK \ << HINIC_AEQ_CTRL_1_##member##_SHIFT))) +#define HINIC_CEQ_CTRL_0_INTR_IDX_SHIFT 0 +#define HINIC_CEQ_CTRL_0_DMA_ATTR_SHIFT 12 +#define HINIC_CEQ_CTRL_0_KICK_THRESH_SHIFT 20 +#define HINIC_CEQ_CTRL_0_PCI_INTF_IDX_SHIFT 24 +#define HINIC_CEQ_CTRL_0_INTR_MODE_SHIFT 31 + +#define HINIC_CEQ_CTRL_0_INTR_IDX_MASK 0x3FF +#define HINIC_CEQ_CTRL_0_DMA_ATTR_MASK 0x3F +#define HINIC_CEQ_CTRL_0_KICK_THRESH_MASK 0xF +#define HINIC_CEQ_CTRL_0_PCI_INTF_IDX_MASK 0x3 +#define HINIC_CEQ_CTRL_0_INTR_MODE_MASK 0x1 + +#define HINIC_CEQ_CTRL_0_SET(val, member) \ + (((u32)(val) & HINIC_CEQ_CTRL_0_##member##_MASK) << \ + HINIC_CEQ_CTRL_0_##member##_SHIFT) + +#define HINIC_CEQ_CTRL_0_CLEAR(val, member) \ + ((val) & (~(HINIC_CEQ_CTRL_0_##member##_MASK \ + << HINIC_CEQ_CTRL_0_##member##_SHIFT))) + +#define HINIC_CEQ_CTRL_1_LEN_SHIFT 0 +#define HINIC_CEQ_CTRL_1_PAGE_SIZE_SHIFT 28 + +#define HINIC_CEQ_CTRL_1_LEN_MASK 0x1FFFFF +#define HINIC_CEQ_CTRL_1_PAGE_SIZE_MASK 0xF + +#define HINIC_CEQ_CTRL_1_SET(val, member) \ + (((u32)(val) & HINIC_CEQ_CTRL_1_##member##_MASK) << \ + HINIC_CEQ_CTRL_1_##member##_SHIFT) + +#define HINIC_CEQ_CTRL_1_CLEAR(val, member) \ + ((val) & (~(HINIC_CEQ_CTRL_1_##member##_MASK \ + << HINIC_CEQ_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 @@ -95,14 +130,17 @@ << HINIC_EQ_CI_##member##_SHIFT))) #define HINIC_MAX_AEQS 4 +#define HINIC_MAX_CEQS 32 #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 64 +#define HINIC_DEFAULT_CEQ_LEN 1024 #define HINIC_EQ_PAGE_SIZE SZ_4K @@ -110,6 +148,7 @@ enum hinic_eq_type { HINIC_AEQ, + HINIC_CEQ, }; enum hinic_aeq_type { @@ -118,6 +157,12 @@ enum hinic_aeq_type { HINIC_MAX_AEQ_EVENTS, }; +enum hinic_ceq_type { + HINIC_CEQ_CMDQ = 3, + + HINIC_MAX_CEQ_EVENTS, +}; + enum hinic_eqe_state { HINIC_EQE_ENABLED = BIT(0), HINIC_EQE_RUNNING = BIT(1), @@ -154,6 +199,8 @@ struct hinic_eq { void **virt_addr; struct hinic_eq_work aeq_work; + + struct tasklet_struct ceq_tasklet; }; struct hinic_hw_event_cb { @@ -173,6 +220,21 @@ struct hinic_aeqs { struct workqueue_struct *workq; }; +struct hinic_ceq_cb { + void (*handler)(void *handle, u32 ceqe_data); + void *handle; + enum hinic_eqe_state ceqe_state; +}; + +struct hinic_ceqs { + struct hinic_hwif *hwif; + + struct hinic_eq ceq[HINIC_MAX_CEQS]; + int num_ceqs; + + struct hinic_ceq_cb ceq_cb[HINIC_MAX_CEQ_EVENTS]; +}; + void hinic_aeq_register_hw_cb(struct hinic_aeqs *aeqs, enum hinic_aeq_type event, void *handle, void (*hwe_handler)(void *handle, void *data, @@ -181,10 +243,23 @@ void hinic_aeq_register_hw_cb(struct hinic_aeqs *aeqs, void hinic_aeq_unregister_hw_cb(struct hinic_aeqs *aeqs, enum hinic_aeq_type event); +void hinic_ceq_register_cb(struct hinic_ceqs *ceqs, + enum hinic_ceq_type event, void *handle, + void (*ceq_cb)(void *handle, u32 ceqe_data)); + +void hinic_ceq_unregister_cb(struct hinic_ceqs *ceqs, + enum hinic_ceq_type event); + int hinic_aeqs_init(struct hinic_aeqs *aeqs, struct hinic_hwif *hwif, int num_aeqs, u32 q_len, u32 page_size, struct msix_entry *msix_entries); void hinic_aeqs_free(struct hinic_aeqs *aeqs); +int hinic_ceqs_init(struct hinic_ceqs *ceqs, struct hinic_hwif *hwif, + int num_ceqs, u32 q_len, u32 page_size, + struct msix_entry *msix_entries); + +void hinic_ceqs_free(struct hinic_ceqs *ceqs); + #endif |