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

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: 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 d0b9805e
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include "hinic_hw_if.h" #include "hinic_hw_if.h"
#include "hinic_hw_eqs.h"
#include "hinic_hw_mgmt.h" #include "hinic_hw_mgmt.h"
#include "hinic_hw_wq.h" #include "hinic_hw_wq.h"
#include "hinic_hw_cmdq.h" #include "hinic_hw_cmdq.h"
...@@ -109,6 +110,16 @@ int hinic_cmdq_direct_resp(struct hinic_cmdqs *cmdqs, ...@@ -109,6 +110,16 @@ int hinic_cmdq_direct_resp(struct hinic_cmdqs *cmdqs,
return -EINVAL; return -EINVAL;
} }
/**
* cmdq_ceq_handler - cmdq completion event handler
* @handle: private data for the handler(cmdqs)
* @ceqe_data: ceq element data
**/
static void cmdq_ceq_handler(void *handle, u32 ceqe_data)
{
/* should be implemented */
}
/** /**
* cmdq_init_queue_ctxt - init the queue ctxt of a cmdq * cmdq_init_queue_ctxt - init the queue ctxt of a cmdq
* @cmdq_ctxt: cmdq ctxt to initialize * @cmdq_ctxt: cmdq ctxt to initialize
...@@ -320,6 +331,8 @@ int hinic_init_cmdqs(struct hinic_cmdqs *cmdqs, struct hinic_hwif *hwif, ...@@ -320,6 +331,8 @@ int hinic_init_cmdqs(struct hinic_cmdqs *cmdqs, struct hinic_hwif *hwif,
goto err_cmdq_ctxt; goto err_cmdq_ctxt;
} }
hinic_ceq_register_cb(&func_to_io->ceqs, HINIC_CEQ_CMDQ, cmdqs,
cmdq_ceq_handler);
return 0; return 0;
err_cmdq_ctxt: err_cmdq_ctxt:
...@@ -340,10 +353,13 @@ int hinic_init_cmdqs(struct hinic_cmdqs *cmdqs, struct hinic_hwif *hwif, ...@@ -340,10 +353,13 @@ int hinic_init_cmdqs(struct hinic_cmdqs *cmdqs, struct hinic_hwif *hwif,
**/ **/
void hinic_free_cmdqs(struct hinic_cmdqs *cmdqs) void hinic_free_cmdqs(struct hinic_cmdqs *cmdqs)
{ {
struct hinic_func_to_io *func_to_io = cmdqs_to_func_to_io(cmdqs);
struct hinic_hwif *hwif = cmdqs->hwif; struct hinic_hwif *hwif = cmdqs->hwif;
struct pci_dev *pdev = hwif->pdev; struct pci_dev *pdev = hwif->pdev;
enum hinic_cmdq_type cmdq_type; enum hinic_cmdq_type cmdq_type;
hinic_ceq_unregister_cb(&func_to_io->ceqs, HINIC_CEQ_CMDQ);
cmdq_type = HINIC_CMDQ_SYNC; cmdq_type = HINIC_CMDQ_SYNC;
for (; cmdq_type < HINIC_MAX_CMDQ_TYPES; cmdq_type++) for (; cmdq_type < HINIC_MAX_CMDQ_TYPES; cmdq_type++)
free_cmdq(&cmdqs->cmdq[cmdq_type]); free_cmdq(&cmdqs->cmdq[cmdq_type]);
......
...@@ -81,27 +81,44 @@ ...@@ -81,27 +81,44 @@
/* EQ registers */ /* EQ registers */
#define HINIC_AEQ_MTT_OFF_BASE_ADDR 0x200 #define HINIC_AEQ_MTT_OFF_BASE_ADDR 0x200
#define HINIC_CEQ_MTT_OFF_BASE_ADDR 0x400
#define HINIC_EQ_MTT_OFF_STRIDE 0x40 #define HINIC_EQ_MTT_OFF_STRIDE 0x40
#define HINIC_CSR_AEQ_MTT_OFF(id) \ #define HINIC_CSR_AEQ_MTT_OFF(id) \
(HINIC_AEQ_MTT_OFF_BASE_ADDR + (id) * HINIC_EQ_MTT_OFF_STRIDE) (HINIC_AEQ_MTT_OFF_BASE_ADDR + (id) * HINIC_EQ_MTT_OFF_STRIDE)
#define HINIC_CSR_CEQ_MTT_OFF(id) \
(HINIC_CEQ_MTT_OFF_BASE_ADDR + (id) * HINIC_EQ_MTT_OFF_STRIDE)
#define HINIC_CSR_EQ_PAGE_OFF_STRIDE 8 #define HINIC_CSR_EQ_PAGE_OFF_STRIDE 8
#define HINIC_CSR_AEQ_HI_PHYS_ADDR_REG(q_id, pg_num) \ #define HINIC_CSR_AEQ_HI_PHYS_ADDR_REG(q_id, pg_num) \
(HINIC_CSR_AEQ_MTT_OFF(q_id) + \ (HINIC_CSR_AEQ_MTT_OFF(q_id) + \
(pg_num) * HINIC_CSR_EQ_PAGE_OFF_STRIDE) (pg_num) * HINIC_CSR_EQ_PAGE_OFF_STRIDE)
#define HINIC_CSR_CEQ_HI_PHYS_ADDR_REG(q_id, pg_num) \
(HINIC_CSR_CEQ_MTT_OFF(q_id) + \
(pg_num) * HINIC_CSR_EQ_PAGE_OFF_STRIDE)
#define HINIC_CSR_AEQ_LO_PHYS_ADDR_REG(q_id, pg_num) \ #define HINIC_CSR_AEQ_LO_PHYS_ADDR_REG(q_id, pg_num) \
(HINIC_CSR_AEQ_MTT_OFF(q_id) + \ (HINIC_CSR_AEQ_MTT_OFF(q_id) + \
(pg_num) * HINIC_CSR_EQ_PAGE_OFF_STRIDE + 4) (pg_num) * HINIC_CSR_EQ_PAGE_OFF_STRIDE + 4)
#define HINIC_CSR_CEQ_LO_PHYS_ADDR_REG(q_id, pg_num) \
(HINIC_CSR_CEQ_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_0_ADDR_BASE 0xE00
#define HINIC_AEQ_CTRL_1_ADDR_BASE 0xE04 #define HINIC_AEQ_CTRL_1_ADDR_BASE 0xE04
#define HINIC_AEQ_CONS_IDX_ADDR_BASE 0xE08 #define HINIC_AEQ_CONS_IDX_ADDR_BASE 0xE08
#define HINIC_AEQ_PROD_IDX_ADDR_BASE 0xE0C #define HINIC_AEQ_PROD_IDX_ADDR_BASE 0xE0C
#define HINIC_CEQ_CTRL_0_ADDR_BASE 0x1000
#define HINIC_CEQ_CTRL_1_ADDR_BASE 0x1004
#define HINIC_CEQ_CONS_IDX_ADDR_BASE 0x1008
#define HINIC_CEQ_PROD_IDX_ADDR_BASE 0x100C
#define HINIC_EQ_OFF_STRIDE 0x80 #define HINIC_EQ_OFF_STRIDE 0x80
#define HINIC_CSR_AEQ_CTRL_0_ADDR(idx) \ #define HINIC_CSR_AEQ_CTRL_0_ADDR(idx) \
...@@ -116,4 +133,16 @@ ...@@ -116,4 +133,16 @@
#define HINIC_CSR_AEQ_PROD_IDX_ADDR(idx) \ #define HINIC_CSR_AEQ_PROD_IDX_ADDR(idx) \
(HINIC_AEQ_PROD_IDX_ADDR_BASE + (idx) * HINIC_EQ_OFF_STRIDE) (HINIC_AEQ_PROD_IDX_ADDR_BASE + (idx) * HINIC_EQ_OFF_STRIDE)
#define HINIC_CSR_CEQ_CTRL_0_ADDR(idx) \
(HINIC_CEQ_CTRL_0_ADDR_BASE + (idx) * HINIC_EQ_OFF_STRIDE)
#define HINIC_CSR_CEQ_CTRL_1_ADDR(idx) \
(HINIC_CEQ_CTRL_1_ADDR_BASE + (idx) * HINIC_EQ_OFF_STRIDE)
#define HINIC_CSR_CEQ_CONS_IDX_ADDR(idx) \
(HINIC_CEQ_CONS_IDX_ADDR_BASE + (idx) * HINIC_EQ_OFF_STRIDE)
#define HINIC_CSR_CEQ_PROD_IDX_ADDR(idx) \
(HINIC_CEQ_PROD_IDX_ADDR_BASE + (idx) * HINIC_EQ_OFF_STRIDE)
#endif #endif
...@@ -277,6 +277,7 @@ int hinic_hwdev_ifup(struct hinic_hwdev *hwdev) ...@@ -277,6 +277,7 @@ int hinic_hwdev_ifup(struct hinic_hwdev *hwdev)
struct hinic_cap *nic_cap = &hwdev->nic_cap; struct hinic_cap *nic_cap = &hwdev->nic_cap;
struct hinic_hwif *hwif = hwdev->hwif; struct hinic_hwif *hwif = hwdev->hwif;
int err, num_aeqs, num_ceqs, num_qps; int err, num_aeqs, num_ceqs, num_qps;
struct msix_entry *ceq_msix_entries;
struct msix_entry *sq_msix_entries; struct msix_entry *sq_msix_entries;
struct msix_entry *rq_msix_entries; struct msix_entry *rq_msix_entries;
struct pci_dev *pdev = hwif->pdev; struct pci_dev *pdev = hwif->pdev;
...@@ -290,7 +291,11 @@ int hinic_hwdev_ifup(struct hinic_hwdev *hwdev) ...@@ -290,7 +291,11 @@ int hinic_hwdev_ifup(struct hinic_hwdev *hwdev)
num_aeqs = HINIC_HWIF_NUM_AEQS(hwif); num_aeqs = HINIC_HWIF_NUM_AEQS(hwif);
num_ceqs = HINIC_HWIF_NUM_CEQS(hwif); num_ceqs = HINIC_HWIF_NUM_CEQS(hwif);
err = hinic_io_init(func_to_io, hwif, nic_cap->max_qps, 0, NULL);
ceq_msix_entries = &hwdev->msix_entries[num_aeqs];
err = hinic_io_init(func_to_io, hwif, nic_cap->max_qps, num_ceqs,
ceq_msix_entries);
if (err) { if (err) {
dev_err(&pdev->dev, "Failed to init IO channel\n"); dev_err(&pdev->dev, "Failed to init IO channel\n");
return err; return err;
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/sizes.h> #include <linux/sizes.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/interrupt.h>
#include "hinic_hw_if.h" #include "hinic_hw_if.h"
...@@ -58,6 +59,40 @@ ...@@ -58,6 +59,40 @@
((val) & (~(HINIC_AEQ_CTRL_1_##member##_MASK \ ((val) & (~(HINIC_AEQ_CTRL_1_##member##_MASK \
<< HINIC_AEQ_CTRL_1_##member##_SHIFT))) << 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_TYPE_SHIFT 0
#define HINIC_EQ_ELEM_DESC_SRC_SHIFT 7 #define HINIC_EQ_ELEM_DESC_SRC_SHIFT 7
#define HINIC_EQ_ELEM_DESC_SIZE_SHIFT 8 #define HINIC_EQ_ELEM_DESC_SIZE_SHIFT 8
...@@ -95,14 +130,17 @@ ...@@ -95,14 +130,17 @@
<< HINIC_EQ_CI_##member##_SHIFT))) << HINIC_EQ_CI_##member##_SHIFT)))
#define HINIC_MAX_AEQS 4 #define HINIC_MAX_AEQS 4
#define HINIC_MAX_CEQS 32
#define HINIC_AEQE_SIZE 64 #define HINIC_AEQE_SIZE 64
#define HINIC_CEQE_SIZE 4
#define HINIC_AEQE_DESC_SIZE 4 #define HINIC_AEQE_DESC_SIZE 4
#define HINIC_AEQE_DATA_SIZE \ #define HINIC_AEQE_DATA_SIZE \
(HINIC_AEQE_SIZE - HINIC_AEQE_DESC_SIZE) (HINIC_AEQE_SIZE - HINIC_AEQE_DESC_SIZE)
#define HINIC_DEFAULT_AEQ_LEN 64 #define HINIC_DEFAULT_AEQ_LEN 64
#define HINIC_DEFAULT_CEQ_LEN 1024
#define HINIC_EQ_PAGE_SIZE SZ_4K #define HINIC_EQ_PAGE_SIZE SZ_4K
...@@ -110,6 +148,7 @@ ...@@ -110,6 +148,7 @@
enum hinic_eq_type { enum hinic_eq_type {
HINIC_AEQ, HINIC_AEQ,
HINIC_CEQ,
}; };
enum hinic_aeq_type { enum hinic_aeq_type {
...@@ -118,6 +157,12 @@ enum hinic_aeq_type { ...@@ -118,6 +157,12 @@ enum hinic_aeq_type {
HINIC_MAX_AEQ_EVENTS, HINIC_MAX_AEQ_EVENTS,
}; };
enum hinic_ceq_type {
HINIC_CEQ_CMDQ = 3,
HINIC_MAX_CEQ_EVENTS,
};
enum hinic_eqe_state { enum hinic_eqe_state {
HINIC_EQE_ENABLED = BIT(0), HINIC_EQE_ENABLED = BIT(0),
HINIC_EQE_RUNNING = BIT(1), HINIC_EQE_RUNNING = BIT(1),
...@@ -154,6 +199,8 @@ struct hinic_eq { ...@@ -154,6 +199,8 @@ struct hinic_eq {
void **virt_addr; void **virt_addr;
struct hinic_eq_work aeq_work; struct hinic_eq_work aeq_work;
struct tasklet_struct ceq_tasklet;
}; };
struct hinic_hw_event_cb { struct hinic_hw_event_cb {
...@@ -173,6 +220,21 @@ struct hinic_aeqs { ...@@ -173,6 +220,21 @@ struct hinic_aeqs {
struct workqueue_struct *workq; 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, void hinic_aeq_register_hw_cb(struct hinic_aeqs *aeqs,
enum hinic_aeq_type event, void *handle, enum hinic_aeq_type event, void *handle,
void (*hwe_handler)(void *handle, void *data, void (*hwe_handler)(void *handle, void *data,
...@@ -181,10 +243,23 @@ void hinic_aeq_register_hw_cb(struct hinic_aeqs *aeqs, ...@@ -181,10 +243,23 @@ void hinic_aeq_register_hw_cb(struct hinic_aeqs *aeqs,
void hinic_aeq_unregister_hw_cb(struct hinic_aeqs *aeqs, void hinic_aeq_unregister_hw_cb(struct hinic_aeqs *aeqs,
enum hinic_aeq_type event); 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 hinic_aeqs_init(struct hinic_aeqs *aeqs, struct hinic_hwif *hwif,
int num_aeqs, u32 q_len, u32 page_size, int num_aeqs, u32 q_len, u32 page_size,
struct msix_entry *msix_entries); struct msix_entry *msix_entries);
void hinic_aeqs_free(struct hinic_aeqs *aeqs); 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 #endif
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/err.h> #include <linux/err.h>
#include "hinic_hw_if.h" #include "hinic_hw_if.h"
#include "hinic_hw_eqs.h"
#include "hinic_hw_wqe.h" #include "hinic_hw_wqe.h"
#include "hinic_hw_wq.h" #include "hinic_hw_wq.h"
#include "hinic_hw_cmdq.h" #include "hinic_hw_cmdq.h"
...@@ -455,10 +456,18 @@ int hinic_io_init(struct hinic_func_to_io *func_to_io, ...@@ -455,10 +456,18 @@ int hinic_io_init(struct hinic_func_to_io *func_to_io,
func_to_io->qps = NULL; func_to_io->qps = NULL;
func_to_io->max_qps = max_qps; func_to_io->max_qps = max_qps;
err = hinic_ceqs_init(&func_to_io->ceqs, hwif, num_ceqs,
HINIC_DEFAULT_CEQ_LEN, HINIC_EQ_PAGE_SIZE,
ceq_msix_entries);
if (err) {
dev_err(&pdev->dev, "Failed to init CEQs\n");
return err;
}
err = hinic_wqs_alloc(&func_to_io->wqs, 2 * max_qps, hwif); err = hinic_wqs_alloc(&func_to_io->wqs, 2 * max_qps, hwif);
if (err) { if (err) {
dev_err(&pdev->dev, "Failed to allocate WQS for IO\n"); dev_err(&pdev->dev, "Failed to allocate WQS for IO\n");
return err; goto err_wqs_alloc;
} }
func_to_io->db_base = pci_ioremap_bar(pdev, HINIC_PCI_DB_BAR); func_to_io->db_base = pci_ioremap_bar(pdev, HINIC_PCI_DB_BAR);
...@@ -499,6 +508,9 @@ int hinic_io_init(struct hinic_func_to_io *func_to_io, ...@@ -499,6 +508,9 @@ int hinic_io_init(struct hinic_func_to_io *func_to_io,
err_db_ioremap: err_db_ioremap:
hinic_wqs_free(&func_to_io->wqs); hinic_wqs_free(&func_to_io->wqs);
err_wqs_alloc:
hinic_ceqs_free(&func_to_io->ceqs);
return err; return err;
} }
...@@ -517,4 +529,5 @@ void hinic_io_free(struct hinic_func_to_io *func_to_io) ...@@ -517,4 +529,5 @@ void hinic_io_free(struct hinic_func_to_io *func_to_io)
iounmap(func_to_io->db_base); iounmap(func_to_io->db_base);
hinic_wqs_free(&func_to_io->wqs); hinic_wqs_free(&func_to_io->wqs);
hinic_ceqs_free(&func_to_io->ceqs);
} }
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <linux/sizes.h> #include <linux/sizes.h>
#include "hinic_hw_if.h" #include "hinic_hw_if.h"
#include "hinic_hw_eqs.h"
#include "hinic_hw_wq.h" #include "hinic_hw_wq.h"
#include "hinic_hw_cmdq.h" #include "hinic_hw_cmdq.h"
#include "hinic_hw_qp.h" #include "hinic_hw_qp.h"
...@@ -46,6 +47,8 @@ struct hinic_free_db_area { ...@@ -46,6 +47,8 @@ struct hinic_free_db_area {
struct hinic_func_to_io { struct hinic_func_to_io {
struct hinic_hwif *hwif; struct hinic_hwif *hwif;
struct hinic_ceqs ceqs;
struct hinic_wqs wqs; struct hinic_wqs wqs;
struct hinic_wq *sq_wq; struct hinic_wq *sq_wq;
......
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