[PATCH V2 for-next 07/19] IB/hns: Delete the sqp_start from the structure hns_roce_caps
From: "Wei Hu (Xavier)" This patch deleted the sqp_start from the structure hns_roce_caps, and modified the calculation of the qp number. Signed-off-by: Wei Hu (Xavier) Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_device.h | 1 - drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 1 - drivers/infiniband/hw/hns/hns_roce_qp.c | 10 -- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index 3058599..3417315 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -465,7 +465,6 @@ struct hns_roce_caps { u32 max_rq_desc_sz; /* 64 */ int max_qp_init_rdma; int max_qp_dest_rdma; - int sqp_start; int num_cqs; int max_cqes; int reserved_cqs; diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c index d767ebe..65c3192 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -936,7 +936,6 @@ void hns_roce_v1_profile(struct hns_roce_dev *hr_dev) caps->mtt_entry_sz = HNS_ROCE_V1_MTT_ENTRY_SIZE; caps->cq_entry_sz = HNS_ROCE_V1_CQE_ENTRY_SIZE; caps->page_size_cap = HNS_ROCE_V1_PAGE_SIZE_SUPPORT; - caps->sqp_start = 0; caps->reserved_lkey = 0; caps->reserved_pds = 0; caps->reserved_mrws = 1; diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c index 177f48f..dd1b214 100644 --- a/drivers/infiniband/hw/hns/hns_roce_qp.c +++ b/drivers/infiniband/hw/hns/hns_roce_qp.c @@ -38,7 +38,7 @@ #include "hns_roce_hem.h" #include "hns_roce_user.h" -#define SQP_NUM12 +#define SQP_NUM(2 * HNS_ROCE_MAX_PORTS) void hns_roce_qp_event(struct hns_roce_dev *hr_dev, u32 qpn, int event_type) { @@ -246,7 +246,7 @@ void hns_roce_release_range_qp(struct hns_roce_dev *hr_dev, int base_qpn, { struct hns_roce_qp_table *qp_table = &hr_dev->qp_table; - if (base_qpn < (hr_dev->caps.sqp_start + 2 * hr_dev->caps.num_ports)) + if (base_qpn < SQP_NUM) return; hns_roce_bitmap_free_range(&qp_table->bitmap, base_qpn, cnt); @@ -608,8 +608,7 @@ struct ib_qp *hns_roce_create_qp(struct ib_pd *pd, hr_qp = &hr_sqp->hr_qp; hr_qp->port = init_attr->port_num - 1; hr_qp->phy_port = hr_dev->iboe.phy_port[hr_qp->port]; - hr_qp->ibqp.qp_num = hr_dev->caps.sqp_start + -HNS_ROCE_MAX_PORTS + + hr_qp->ibqp.qp_num = HNS_ROCE_MAX_PORTS + hr_dev->iboe.phy_port[hr_qp->port]; ret = hns_roce_create_qp_common(hr_dev, pd, init_attr, udata, @@ -825,8 +824,7 @@ int hns_roce_init_qp_table(struct hns_roce_dev *hr_dev) /* A port include two SQP, six port total 12 */ ret = hns_roce_bitmap_init(&qp_table->bitmap, hr_dev->caps.num_qps, - hr_dev->caps.num_qps - 1, - hr_dev->caps.sqp_start + SQP_NUM, + hr_dev->caps.num_qps - 1, SQP_NUM, reserved_from_top); if (ret) { dev_err(&hr_dev->pdev->dev, "qp bitmap init failed!error=%d\n", -- 1.9.1
[PATCH V2 for-next 08/19] IB/hns: Optimize code of aeq and ceq interrupt handle and fix the bug of qpn
From: "Wei Hu (Xavier)" This patch optimized the codes of aeq and ceq interrupt handle and fixed the bug in the calculation of qpn. For the special qp(GSI or SMI), calculated the qp number according to physical port and the qpn reported in the event of async event queue. Signed-off-by: Wei Hu (Xavier) Signed-off-by: Salil Mehta --- PATCH V2: Addressed Leon Romanovsky's comment Link: https://lkml.org/lkml/2016/9/12/303 PATCH V1: Initial patch --- drivers/infiniband/hw/hns/hns_roce_eq.c | 146 drivers/infiniband/hw/hns/hns_roce_eq.h | 4 + 2 files changed, 75 insertions(+), 75 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_eq.c b/drivers/infiniband/hw/hns/hns_roce_eq.c index 98af7fe..21e21b0 100644 --- a/drivers/infiniband/hw/hns/hns_roce_eq.c +++ b/drivers/infiniband/hw/hns/hns_roce_eq.c @@ -66,9 +66,6 @@ static void hns_roce_wq_catas_err_handle(struct hns_roce_dev *hr_dev, { struct device *dev = &hr_dev->pdev->dev; - qpn = roce_get_field(aeqe->event.qp_event.qp, -HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_M, -HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_S); dev_warn(dev, "Local Work Queue Catastrophic Error.\n"); switch (roce_get_field(aeqe->asyn, HNS_ROCE_AEQE_U32_4_EVENT_SUB_TYPE_M, HNS_ROCE_AEQE_U32_4_EVENT_SUB_TYPE_S)) { @@ -96,13 +93,6 @@ static void hns_roce_wq_catas_err_handle(struct hns_roce_dev *hr_dev, default: break; } - - hns_roce_qp_event(hr_dev, roce_get_field(aeqe->event.qp_event.qp, - HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_M, - HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_S), - roce_get_field(aeqe->asyn, - HNS_ROCE_AEQE_U32_4_EVENT_TYPE_M, - HNS_ROCE_AEQE_U32_4_EVENT_TYPE_S)); } static void hns_roce_local_wq_access_err_handle(struct hns_roce_dev *hr_dev, @@ -111,9 +101,6 @@ static void hns_roce_local_wq_access_err_handle(struct hns_roce_dev *hr_dev, { struct device *dev = &hr_dev->pdev->dev; - qpn = roce_get_field(aeqe->event.qp_event.qp, -HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_M, -HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_S); dev_warn(dev, "Local Access Violation Work Queue Error.\n"); switch (roce_get_field(aeqe->asyn, HNS_ROCE_AEQE_U32_4_EVENT_SUB_TYPE_M, HNS_ROCE_AEQE_U32_4_EVENT_SUB_TYPE_S)) { @@ -141,13 +128,69 @@ static void hns_roce_local_wq_access_err_handle(struct hns_roce_dev *hr_dev, default: break; } +} + +static void hns_roce_qp_err_handle(struct hns_roce_dev *hr_dev, + struct hns_roce_aeqe *aeqe, + int event_type) +{ + struct device *dev = &hr_dev->pdev->dev; + int phy_port; + int qpn; + + qpn = roce_get_field(aeqe->event.qp_event.qp, +HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_M, +HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_S); + phy_port = roce_get_field(aeqe->event.qp_event.qp, + HNS_ROCE_AEQE_EVENT_QP_EVENT_PORT_NUM_M, + HNS_ROCE_AEQE_EVENT_QP_EVENT_PORT_NUM_S); + if (qpn <= 1) + qpn = HNS_ROCE_MAX_PORTS * qpn + phy_port; + + switch (event_type) { + case HNS_ROCE_EVENT_TYPE_INV_REQ_LOCAL_WQ_ERROR: + dev_warn(dev, "Invalid Req Local Work Queue Error.\n" + "QP %d, phy_port %d.\n", qpn, phy_port); + break; + case HNS_ROCE_EVENT_TYPE_WQ_CATAS_ERROR: + hns_roce_wq_catas_err_handle(hr_dev, aeqe, qpn); + break; + case HNS_ROCE_EVENT_TYPE_LOCAL_WQ_ACCESS_ERROR: + hns_roce_local_wq_access_err_handle(hr_dev, aeqe, qpn); + break; + default: + break; + } + + hns_roce_qp_event(hr_dev, qpn, event_type); +} + +static void hns_roce_cq_err_handle(struct hns_roce_dev *hr_dev, + struct hns_roce_aeqe *aeqe, + int event_type) +{ + struct device *dev = &hr_dev->pdev->dev; + u32 cqn; + + cqn = le32_to_cpu(roce_get_field(aeqe->event.cq_event.cq, + HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_M, + HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_S)); + + switch (event_type) { + case HNS_ROCE_EVENT_TYPE_CQ_ACCESS_ERROR: + dev_warn(dev, "CQ 0x%x access err.\n", cqn); + break; + case HNS_ROCE_EVENT_TYPE_CQ_OVERFLOW: + dev_warn(dev, &q
[PATCH V2 for-next 06/19] IB/hns: Fix bug of clear hem
From: "Wei Hu (Xavier)" In hip06, there's no interface to release hem memory. So, hardware can't identify whether hem memory released or not. If all context in a hem memory released, the related hem memory will be released by driver and reused by others. But, hardware don't know that this memory can't be used already. In order to fix this bug, hns roce driver reserved 128K memory for each type of hem(QPC/CQC/MTPT). While unmap hem memory, hns roce driver will write base address of reserved memory according to hem type. Signed-off-by: Wei Hu (Xavier) Signed-off-by: Dongdong Huang(Donald) Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_device.h | 2 + drivers/infiniband/hw/hns/hns_roce_hem.c| 76 +-- drivers/infiniband/hw/hns/hns_roce_hem.h| 4 + drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 140 drivers/infiniband/hw/hns/hns_roce_hw_v1.h | 9 ++ 5 files changed, 157 insertions(+), 74 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index 15bc229..3058599 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -506,6 +506,8 @@ struct hns_roce_hw { void (*write_cqc)(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq, void *mb_buf, u64 *mtts, dma_addr_t dma_handle, int nent, u32 vector); + int (*clear_hem)(struct hns_roce_dev *hr_dev, +struct hns_roce_hem_table *table, int obj); int (*query_qp)(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr_mask, struct ib_qp_init_attr *qp_init_attr); int (*modify_qp)(struct ib_qp *ibqp, const struct ib_qp_attr *attr, diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.c b/drivers/infiniband/hw/hns/hns_roce_hem.c index d53d643..250d8f2 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hem.c +++ b/drivers/infiniband/hw/hns/hns_roce_hem.c @@ -36,14 +36,10 @@ #include "hns_roce_hem.h" #include "hns_roce_common.h" -#define HW_SYNC_TIMEOUT_MSECS 500 -#define HW_SYNC_SLEEP_TIME_INTERVAL20 - #define HNS_ROCE_HEM_ALLOC_SIZE(1 << 17) #define HNS_ROCE_TABLE_CHUNK_SIZE (1 << 17) #define DMA_ADDR_T_SHIFT 12 -#define BT_CMD_SYNC_SHIFT 31 #define BT_BA_SHIFT32 struct hns_roce_hem *hns_roce_alloc_hem(struct hns_roce_dev *hr_dev, int npages, @@ -213,74 +209,6 @@ static int hns_roce_set_hem(struct hns_roce_dev *hr_dev, return ret; } -static int hns_roce_clear_hem(struct hns_roce_dev *hr_dev, - struct hns_roce_hem_table *table, - unsigned long obj) -{ - struct device *dev = &hr_dev->pdev->dev; - unsigned long end = 0; - unsigned long flags; - void __iomem *bt_cmd; - uint32_t bt_cmd_val[2]; - u32 bt_cmd_h_val = 0; - int ret = 0; - - switch (table->type) { - case HEM_TYPE_QPC: - roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M, - ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, HEM_TYPE_QPC); - break; - case HEM_TYPE_MTPT: - roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M, - ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, - HEM_TYPE_MTPT); - break; - case HEM_TYPE_CQC: - roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M, - ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, HEM_TYPE_CQC); - break; - case HEM_TYPE_SRQC: - roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M, - ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, - HEM_TYPE_SRQC); - break; - default: - return ret; - } - roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_M, - ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_S, obj); - roce_set_bit(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_S, 0); - roce_set_bit(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_HW_SYNS_S, 1); - roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_M, - ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_S, 0); - - spin_lock_irqsave(&hr_dev->bt_cmd_lock, flags); - - bt_cmd = hr_dev->reg_base + ROCEE_BT_CMD_H_REG; - - end = msecs_to_jiffies(HW_SYNC_TIMEOUT_MSECS) + jiffies; - while (1) { - if (readl(bt_cmd) >> BT_CMD_SYNC_SHIFT) { - if (!(time_before(jiffies, end))) { - dev_err(dev, "Write bt_cmd err,hw_syn
[PATCH V2 for-next 04/19] IB/hns: Simplify function of pd alloc and qp alloc
From: Lijun Ou Hns_roce_pd_alloc and hns_roce_reserve_range_qp use unnecessary transformation of parameters. This patch simplify these two functions. Signed-off-by: Lijun Ou Signed-off-by: Dongdong Huang(Donald) Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_pd.c | 14 +- drivers/infiniband/hw/hns/hns_roce_qp.c | 10 +- 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_pd.c b/drivers/infiniband/hw/hns/hns_roce_pd.c index 4109f74..0cd6132 100644 --- a/drivers/infiniband/hw/hns/hns_roce_pd.c +++ b/drivers/infiniband/hw/hns/hns_roce_pd.c @@ -35,19 +35,7 @@ static int hns_roce_pd_alloc(struct hns_roce_dev *hr_dev, unsigned long *pdn) { - struct device *dev = &hr_dev->pdev->dev; - unsigned long pd_number; - int ret = 0; - - ret = hns_roce_bitmap_alloc(&hr_dev->pd_bitmap, &pd_number); - if (ret == -1) { - dev_err(dev, "alloc pdn from pdbitmap failed\n"); - return -ENOMEM; - } - - *pdn = pd_number; - - return 0; + return hns_roce_bitmap_alloc(&hr_dev->pd_bitmap, pdn); } static void hns_roce_pd_free(struct hns_roce_dev *hr_dev, unsigned long pdn) diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c index dd94e41..73de1d3 100644 --- a/drivers/infiniband/hw/hns/hns_roce_qp.c +++ b/drivers/infiniband/hw/hns/hns_roce_qp.c @@ -112,16 +112,8 @@ static int hns_roce_reserve_range_qp(struct hns_roce_dev *hr_dev, int cnt, int align, unsigned long *base) { struct hns_roce_qp_table *qp_table = &hr_dev->qp_table; - int ret = 0; - unsigned long qpn; - - ret = hns_roce_bitmap_alloc_range(&qp_table->bitmap, cnt, align, &qpn); - if (ret == -1) - return -ENOMEM; - *base = qpn; - - return 0; + return hns_roce_bitmap_alloc_range(&qp_table->bitmap, cnt, align, base); } enum hns_roce_qp_state to_hns_roce_state(enum ib_qp_state state) -- 1.9.1
[PATCH V2 for-next 03/19] IB/hns: Fix bug of using uninit refcount and free
From: Lijun Ou In current version, it uses uninitialized parameters named refcount and free in hns_roce_cq_event. This patch initializes these parameter in cq alloc and add correspond process in cq free. Signed-off-by: Lijun Ou Signed-off-by: Dongdong Huang(Donald) Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_cq.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/infiniband/hw/hns/hns_roce_cq.c b/drivers/infiniband/hw/hns/hns_roce_cq.c index a52306f..3095f06 100644 --- a/drivers/infiniband/hw/hns/hns_roce_cq.c +++ b/drivers/infiniband/hw/hns/hns_roce_cq.c @@ -152,6 +152,9 @@ static int hns_roce_cq_alloc(struct hns_roce_dev *hr_dev, int nent, hr_cq->cons_index = 0; hr_cq->uar = hr_uar; + atomic_set(&hr_cq->refcount, 1); + init_completion(&hr_cq->free); + return 0; err_radix: @@ -191,6 +194,11 @@ static void hns_roce_free_cq(struct hns_roce_dev *hr_dev, /* Waiting interrupt process procedure carried out */ synchronize_irq(hr_dev->eq_table.eq[hr_cq->vector].irq); + /* wait for all interrupt processed */ + if (atomic_dec_and_test(&hr_cq->refcount)) + complete(&hr_cq->free); + wait_for_completion(&hr_cq->free); + spin_lock_irq(&cq_table->lock); radix_tree_delete(&cq_table->tree, hr_cq->cqn); spin_unlock_irq(&cq_table->lock); -- 1.9.1
[PATCH V2 for-next 05/19] IB/hns: Remove unused parameter named qp_type
From: Lijun Ou This patch removes the qp_type parameter in hns_roce_set_kernel_sq_size(). Signed-off-by: Lijun Ou Signed-off-by: Ping Zhang Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_qp.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c index 73de1d3..177f48f 100644 --- a/drivers/infiniband/hw/hns/hns_roce_qp.c +++ b/drivers/infiniband/hw/hns/hns_roce_qp.c @@ -336,12 +336,10 @@ static int hns_roce_set_user_sq_size(struct hns_roce_dev *hr_dev, static int hns_roce_set_kernel_sq_size(struct hns_roce_dev *hr_dev, struct ib_qp_cap *cap, - enum ib_qp_type type, struct hns_roce_qp *hr_qp) { struct device *dev = &hr_dev->pdev->dev; u32 max_cnt; - (void)type; if (cap->max_send_wr > hr_dev->caps.max_wqes || cap->max_send_sge > hr_dev->caps.max_sq_sg || @@ -467,7 +465,7 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev, /* Set SQ size */ ret = hns_roce_set_kernel_sq_size(hr_dev, &init_attr->cap, - init_attr->qp_type, hr_qp); + hr_qp); if (ret) { dev_err(dev, "hns_roce_set_kernel_sq_size error!\n"); goto err_out; -- 1.9.1
[PATCH V2 for-next 00/19] IB/hns: Fixes for various misc. bugs
This patch-set introduces fixes for various bugs and potential problems found during internal review and testing phases of the HNS RoCE driver. NOTE: These fixes have been done over already floated CM patch: https://lkml.org/lkml/2016/9/1/609 All fixes have been done & tested by Oulijun and Huwei. V1->V2: * PATCH 3/20 and 13/20 have been dropped after rework of comments by Leon Romanovsky on V1 patch. * New patch "Fix for removal of redundant code" has been added to remove the redundant code. Lijun Ou (15): IB/hns: Remove unused parameters in some functions IB/hns: Remove parameters of resize cq IB/hns: Fix bug of using uninit refcount and free IB/hns: Simplify function of pd alloc and qp alloc IB/hns: Remove unused parameter named qp_type IB/hns: Modify the init of iboe lock IB/hns: Fix bug of memory leakage for registering user mr IB/hns: Return bad wr while post send failed IB/hns: The Ack timeout need a lower limit value IB/hns: Some items of qpc need to take user param IB/hns: Validate mtu when modified qp IB/hns: Cq has not been freed IB/hns: Update the rq head when modify qp state IB/hns: Fix the bug when platform_get_resource() exec fail IB/hns: Delete the redundant lines in hns_roce_v1_m_qp() Salil Mehta (1): IB/hns: Fix for removal of redundant code Wei Hu (Xavier) (3): IB/hns: Fix bug of clear hem IB/hns: Delete the sqp_start from the structure hns_roce_caps IB/hns: Optimize code of aeq and ceq interrupt handle and fix the bug of qpn drivers/infiniband/hw/hns/hns_roce_cq.c | 23 +-- drivers/infiniband/hw/hns/hns_roce_device.h | 13 +- drivers/infiniband/hw/hns/hns_roce_eq.c | 146 ++- drivers/infiniband/hw/hns/hns_roce_eq.h | 4 + drivers/infiniband/hw/hns/hns_roce_hem.c| 76 +- drivers/infiniband/hw/hns/hns_roce_hem.h| 4 + drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 211 +++- drivers/infiniband/hw/hns/hns_roce_hw_v1.h | 9 ++ drivers/infiniband/hw/hns/hns_roce_main.c | 4 +- drivers/infiniband/hw/hns/hns_roce_mr.c | 3 + drivers/infiniband/hw/hns/hns_roce_pd.c | 18 +-- drivers/infiniband/hw/hns/hns_roce_qp.c | 57 +++- 12 files changed, 312 insertions(+), 256 deletions(-) -- 1.9.1
[PATCH V2 for-next 13/19] IB/hns: Some items of qpc need to take user param
From: Lijun Ou Some items of qpc need to take user param when modified qp state. Signed-off-by: Lijun Ou Signed-off-by: Dongdong Huang(Donald) Reviewed-by: Wei Hu (Xavier) Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c index 5110a18..bc06004 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -2396,10 +2396,12 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr, QP_CONTEXT_QPC_BYTES_148_CHECK_FLAG_S, 0); roce_set_field(context->qpc_bytes_148, QP_CONTEXT_QPC_BYTES_148_RETRY_COUNT_M, - QP_CONTEXT_QPC_BYTES_148_RETRY_COUNT_S, 0); + QP_CONTEXT_QPC_BYTES_148_RETRY_COUNT_S, + attr->retry_cnt); roce_set_field(context->qpc_bytes_148, QP_CONTEXT_QPC_BYTES_148_RNR_RETRY_COUNT_M, - QP_CONTEXT_QPC_BYTES_148_RNR_RETRY_COUNT_S, 0); + QP_CONTEXT_QPC_BYTES_148_RNR_RETRY_COUNT_S, + attr->rnr_retry); roce_set_field(context->qpc_bytes_148, QP_CONTEXT_QPC_BYTES_148_LSN_M, QP_CONTEXT_QPC_BYTES_148_LSN_S, 0x100); -- 1.9.1
[PATCH V2 for-next 11/19] IB/hns: Return bad wr while post send failed
From: Lijun Ou While post failed, hns roce should return the wr failed to user. We omitted this while qp type is wrong and fixed it. Signed-off-by: Lijun Ou Signed-off-by: Dongdong Huang(Donald) Reviewed-by: Wei Hu (Xavier) Signed-off-by: Salil Mehta --- PATCH V2: Addressed commnets by Leon Romanovsky Link: https://lkml.org/lkml/2016/9/15/98 PATCH V1: Initial submit --- drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c index 65c3192..1205d1a 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -73,8 +73,14 @@ int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, u32 ind = 0; int ret = 0; - spin_lock_irqsave(&qp->sq.lock, flags); + if (unlikely(ibqp->qp_type != IB_QPT_GSI && + ibqp->qp_type != IB_QPT_RC)) { + dev_err(dev, "un-supported QP type\n"); + *bad_wr = NULL; + return -EOPNOTSUPP; + } + spin_lock_irqsave(&qp->sq.lock, flags); ind = qp->sq_next_wqe; for (nreq = 0; wr; ++nreq, wr = wr->next) { if (hns_roce_wq_overflow(&qp->sq, nreq, qp->ibqp.send_cq)) { @@ -263,9 +269,6 @@ int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, HNS_ROCE_WQE_SGE_NUM_BIT); } ind++; - } else { - dev_dbg(dev, "unSupported QP type\n"); - break; } } -- 1.9.1
[PATCH V2 for-next 15/19] IB/hns: Cq has not been freed
From: Lijun Ou Cq has not been freed when fail to ib_copy_to_udata, so need to free it. Signed-off-by: Lijun Ou Signed-off-by: Peter Chen Reviewed-by: Wei Hu (Xavier) Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_cq.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_cq.c b/drivers/infiniband/hw/hns/hns_roce_cq.c index 3095f06..0973659 100644 --- a/drivers/infiniband/hw/hns/hns_roce_cq.c +++ b/drivers/infiniband/hw/hns/hns_roce_cq.c @@ -357,12 +357,15 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev, if (context) { if (ib_copy_to_udata(udata, &hr_cq->cqn, sizeof(u64))) { ret = -EFAULT; - goto err_mtt; + goto err_cqc; } } return &hr_cq->ib_cq; +err_cqc: + hns_roce_free_cq(hr_dev, hr_cq); + err_mtt: hns_roce_mtt_cleanup(hr_dev, &hr_cq->hr_buf.hr_mtt); if (context) -- 1.9.1
[PATCH V2 for-next 16/19] IB/hns: Update the rq head when modify qp state
From: Lijun Ou The rq head in qpc was zero will miss the rq wqes which have be sent, so here we should take the real value. Signed-off-by: Lijun Ou Reviewed-by: Wei Hu (Xavier) Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c index bc06004..2070e9e 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -2248,7 +2248,8 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr, roce_set_field(context->qpc_bytes_68, QP_CONTEXT_QPC_BYTES_68_RQ_HEAD_M, - QP_CONTEXT_QPC_BYTES_68_RQ_HEAD_S, 0); + QP_CONTEXT_QPC_BYTES_68_RQ_HEAD_S, + hr_qp->rq.head); roce_set_field(context->qpc_bytes_68, QP_CONTEXT_QPC_BYTES_68_RQ_CUR_INDEX_M, QP_CONTEXT_QPC_BYTES_68_RQ_CUR_INDEX_S, 0); -- 1.9.1
[PATCH V2 for-next 14/19] IB/hns: Validate mtu when modified qp
From: Lijun Ou The mtu should be validated when modify qp,so we check it. Signed-off-by: Lijun Ou Signed-off-by: Peter Chen Reviewed-by: Wei Hu (Xavier) Signed-off-by: Salil Mehta --- PATCH V2: Addressed Leon Romanovsky's comments Link: https://lkml.org/lkml/2016/9/13/39 PATCH V1: Initial Submit --- drivers/infiniband/hw/hns/hns_roce_qp.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c index dd1b214..6a38909 100644 --- a/drivers/infiniband/hw/hns/hns_roce_qp.c +++ b/drivers/infiniband/hw/hns/hns_roce_qp.c @@ -32,6 +32,7 @@ */ #include +#include #include #include "hns_roce_common.h" #include "hns_roce_device.h" @@ -657,6 +658,7 @@ int hns_roce_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, struct device *dev = &hr_dev->pdev->dev; int ret = -EINVAL; int p; + enum ib_mtu active_mtu; mutex_lock(&hr_qp->mutex); @@ -687,6 +689,19 @@ int hns_roce_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, } } + if (attr_mask & IB_QP_PATH_MTU) { + p = attr_mask & IB_QP_PORT ? (attr->port_num - 1) : hr_qp->port; + active_mtu = iboe_get_mtu(hr_dev->iboe.netdevs[p]->mtu); + + if (attr->path_mtu > IB_MTU_2048 || + attr->path_mtu < IB_MTU_256 || + attr->path_mtu > active_mtu) { + dev_err(dev, "attr path_mtu(%d)invalid while modify qp", + attr->path_mtu); + goto out; + } + } + if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC && attr->max_rd_atomic > hr_dev->caps.max_qp_init_rdma) { dev_err(dev, "attr max_rd_atomic invalid.attr->max_rd_atomic=%d\n", -- 1.9.1
[PATCH V2 for-next 09/19] IB/hns: Modify the init of iboe lock
From: Lijun Ou This lock will be used in query port interface, and will be called while IB device was registered to OFED framework/IB Core. So, the lock of iboe must be initiated before IB device was registered. Signed-off-by: Lijun Ou Signed-off-by: Dongdong Huang(Donald) Reviewed-by: Wei Hu (Xavier) Signed-off-by: Salil Mehta --- PATCH V2: Addressed Leon Romanovsky's comments Link: https://lkml.org/lkml/2016/9/13/51 PATCH V1: Initial patch --- drivers/infiniband/hw/hns/hns_roce_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c index 4b44998..764e35a 100644 --- a/drivers/infiniband/hw/hns/hns_roce_main.c +++ b/drivers/infiniband/hw/hns/hns_roce_main.c @@ -602,6 +602,7 @@ static int hns_roce_register_device(struct hns_roce_dev *hr_dev) struct device *dev = &hr_dev->pdev->dev; iboe = &hr_dev->iboe; + spin_lock_init(&iboe->lock); ib_dev = &hr_dev->ib_dev; strlcpy(ib_dev->name, "hisi_%d", IB_DEVICE_NAME_MAX); @@ -686,8 +687,6 @@ static int hns_roce_register_device(struct hns_roce_dev *hr_dev) goto error_failed_setup_mtu_gids; } - spin_lock_init(&iboe->lock); - iboe->nb.notifier_call = hns_roce_netdev_event; ret = register_netdevice_notifier(&iboe->nb); if (ret) { -- 1.9.1
[PATCH V2 for-next 17/19] IB/hns: Fix the bug when platform_get_resource() exec fail
From: Lijun Ou This patch mainly fixes the bug with platform_get_resource(). It should return NULL when platform_get_resource() exec fail. Signed-off-by: Lijun Ou Reviewed-by: Wei Hu (Xavier) Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_pd.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/infiniband/hw/hns/hns_roce_pd.c b/drivers/infiniband/hw/hns/hns_roce_pd.c index 0cd6132..05db7d5 100644 --- a/drivers/infiniband/hw/hns/hns_roce_pd.c +++ b/drivers/infiniband/hw/hns/hns_roce_pd.c @@ -110,6 +110,10 @@ int hns_roce_uar_alloc(struct hns_roce_dev *hr_dev, struct hns_roce_uar *uar) (hr_dev->caps.phy_num_uars - 1) + 1; res = platform_get_resource(hr_dev->pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&hr_dev->pdev->dev, "memory resource not found!\n"); + return -EINVAL; + } uar->pfn = ((res->start) >> PAGE_SHIFT) + uar->index; return 0; -- 1.9.1
[PATCH V2 for-next 19/19] IB/hns: Fix for removal of redundant code
This patch removes the redundant code lines present in the functions get_send_wqe() and get_recv_wqe(). This also fixes the error in calculating the SQ WQE. Signed-off-by: Lijun Ou Reviewed-by: Wei Hu (Xavier) Signed-off-by: Salil Mehta --- PATCH V1: This has been create to address the Leon Romanovsky's comment provided in below patches: Link: https://lkml.org/lkml/2016/9/15/117 Link: https://lkml.org/lkml/2016/9/13/54 --- drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 3 ++- drivers/infiniband/hw/hns/hns_roce_qp.c| 18 -- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c index d52eeda..71232e5 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -1552,7 +1552,8 @@ static int hns_roce_v1_poll_one(struct hns_roce_cq *hr_cq, /* SQ conrespond to CQE */ sq_wqe = get_send_wqe(*cur_qp, roce_get_field(cqe->cqe_byte_4, CQE_BYTE_4_WQE_INDEX_M, - CQE_BYTE_4_WQE_INDEX_S)); + CQE_BYTE_4_WQE_INDEX_S)& + ((*cur_qp)->sq.wqe_cnt-1)); switch (sq_wqe->flag & HNS_ROCE_WQE_OPCODE_MASK) { case HNS_ROCE_WQE_OPCODE_SEND: wc->opcode = IB_WC_SEND; diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c index 6a38909..e86dd8d 100644 --- a/drivers/infiniband/hw/hns/hns_roce_qp.c +++ b/drivers/infiniband/hw/hns/hns_roce_qp.c @@ -784,29 +784,11 @@ static void *get_wqe(struct hns_roce_qp *hr_qp, int offset) void *get_recv_wqe(struct hns_roce_qp *hr_qp, int n) { - struct ib_qp *ibqp = &hr_qp->ibqp; - struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device); - - if ((n < 0) || (n > hr_qp->rq.wqe_cnt)) { - dev_err(&hr_dev->pdev->dev, "rq wqe index:%d,rq wqe cnt:%d\r\n", - n, hr_qp->rq.wqe_cnt); - return NULL; - } - return get_wqe(hr_qp, hr_qp->rq.offset + (n << hr_qp->rq.wqe_shift)); } void *get_send_wqe(struct hns_roce_qp *hr_qp, int n) { - struct ib_qp *ibqp = &hr_qp->ibqp; - struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device); - - if ((n < 0) || (n > hr_qp->sq.wqe_cnt)) { - dev_err(&hr_dev->pdev->dev, "sq wqe index:%d,sq wqe cnt:%d\r\n", - n, hr_qp->sq.wqe_cnt); - return NULL; - } - return get_wqe(hr_qp, hr_qp->sq.offset + (n << hr_qp->sq.wqe_shift)); } -- 1.9.1
[PATCH V2 for-next 10/19] IB/hns: Fix bug of memory leakage for registering user mr
From: Lijun Ou While the page size attribute of umem is illegal, we should release umem that get by ib_umem_get interface. Also, we should return a non-zero value while pbl number is wrong. Signed-off-by: Lijun Ou Signed-off-by: Dongdong Huang(Donald) Reviewed-by: Wei Hu (Xavier) Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_mr.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c index 59f5e2b..fb87883 100644 --- a/drivers/infiniband/hw/hns/hns_roce_mr.c +++ b/drivers/infiniband/hw/hns/hns_roce_mr.c @@ -564,11 +564,14 @@ struct ib_mr *hns_roce_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, if (mr->umem->page_size != HNS_ROCE_HEM_PAGE_SIZE) { dev_err(dev, "Just support 4K page size but is 0x%x now!\n", mr->umem->page_size); + ret = -EINVAL; + goto err_umem; } if (n > HNS_ROCE_MAX_MTPT_PBL_NUM) { dev_err(dev, " MR len %lld err. MR is limited to 4G at most!\n", length); + ret = -EINVAL; goto err_umem; } -- 1.9.1
[PATCH V2 for-next 12/19] IB/hns: The Ack timeout need a lower limit value
From: Lijun Ou The Ack timeout of qpc need a lower limit value,otherwise the read performance will be very lower. Signed-off-by: Lijun Ou Signed-off-by: Dongdong Huang(Donald) Reviewed-by: Wei Hu (Xavier) Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 17 + 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c index 1205d1a..5110a18 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -2410,10 +2410,19 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr, QP_CONTEXT_QPC_BYTES_156_RETRY_COUNT_INIT_M, QP_CONTEXT_QPC_BYTES_156_RETRY_COUNT_INIT_S, attr->retry_cnt); - roce_set_field(context->qpc_bytes_156, - QP_CONTEXT_QPC_BYTES_156_ACK_TIMEOUT_M, - QP_CONTEXT_QPC_BYTES_156_ACK_TIMEOUT_S, - attr->timeout); + if (attr->timeout < 0x12) { + dev_info(dev, "ack timeout value(0x%x) must bigger than 0x12.\n", +attr->timeout); + roce_set_field(context->qpc_bytes_156, + QP_CONTEXT_QPC_BYTES_156_ACK_TIMEOUT_M, + QP_CONTEXT_QPC_BYTES_156_ACK_TIMEOUT_S, + 0x12); + } else { + roce_set_field(context->qpc_bytes_156, + QP_CONTEXT_QPC_BYTES_156_ACK_TIMEOUT_M, + QP_CONTEXT_QPC_BYTES_156_ACK_TIMEOUT_S, + attr->timeout); + } roce_set_field(context->qpc_bytes_156, QP_CONTEXT_QPC_BYTES_156_RNR_RETRY_COUNT_INIT_M, QP_CONTEXT_QPC_BYTES_156_RNR_RETRY_COUNT_INIT_S, -- 1.9.1
[PATCH V2 for-next 18/19] IB/hns: Delete the redundant lines in hns_roce_v1_m_qp()
From: Lijun Ou It doesn't need to assign for the filed of qp state in qpc separately when qp happen to migrate state which supported in RoCE engine v1. Signed-off-by: Lijun Ou Reviewed-by: Wei Hu (Xavier) Signed-off-by: Salil Mehta --- PATCH V2: Addressed comments provided by Leon Romanovsky Link: https://lkml.org/lkml/2016/9/15/123 PATCH V1: Initial Submit --- drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 17 +++-- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c index 2070e9e..d52eeda 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -2387,11 +2387,6 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr, roce_set_bit(context->qpc_bytes_140, QP_CONTEXT_QPC_BYTES_140_RNR_RETRY_FLG_S, 0); - roce_set_field(context->qpc_bytes_144, - QP_CONTEXT_QPC_BYTES_144_QP_STATE_M, - QP_CONTEXT_QPC_BYTES_144_QP_STATE_S, - attr->qp_state); - roce_set_field(context->qpc_bytes_148, QP_CONTEXT_QPC_BYTES_148_CHECK_FLAG_M, QP_CONTEXT_QPC_BYTES_148_CHECK_FLAG_S, 0); @@ -2498,21 +2493,15 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr, QP_CONTEXT_QPC_BYTES_188_TX_RETRY_CUR_INDEX_M, QP_CONTEXT_QPC_BYTES_188_TX_RETRY_CUR_INDEX_S, 0); - } else if ((cur_state == IB_QPS_INIT && new_state == IB_QPS_RESET) || + } else if (!((cur_state == IB_QPS_INIT && new_state == IB_QPS_RESET) || (cur_state == IB_QPS_INIT && new_state == IB_QPS_ERR) || (cur_state == IB_QPS_RTR && new_state == IB_QPS_RESET) || (cur_state == IB_QPS_RTR && new_state == IB_QPS_ERR) || (cur_state == IB_QPS_RTS && new_state == IB_QPS_RESET) || (cur_state == IB_QPS_RTS && new_state == IB_QPS_ERR) || (cur_state == IB_QPS_ERR && new_state == IB_QPS_RESET) || - (cur_state == IB_QPS_ERR && new_state == IB_QPS_ERR)) { - roce_set_field(context->qpc_bytes_144, - QP_CONTEXT_QPC_BYTES_144_QP_STATE_M, - QP_CONTEXT_QPC_BYTES_144_QP_STATE_S, - attr->qp_state); - - } else { - dev_err(dev, "not support this modify\n"); + (cur_state == IB_QPS_ERR && new_state == IB_QPS_ERR))) { + dev_err(dev, "not support this status migration\n"); goto out; } -- 1.9.1
[PATCH V2 for-next 02/19] IB/hns: Remove parameters of resize cq
From: Lijun Ou In old version of RoCE, it doesn't support to resize cq. So, we remove parameters related to resize cq. Signed-off-by: Lijun Ou Signed-off-by: Dongdong Huang(Donald) Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_cq.c | 3 --- drivers/infiniband/hw/hns/hns_roce_device.h | 9 - 2 files changed, 12 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_cq.c b/drivers/infiniband/hw/hns/hns_roce_cq.c index 10fd209..a52306f 100644 --- a/drivers/infiniband/hw/hns/hns_roce_cq.c +++ b/drivers/infiniband/hw/hns/hns_roce_cq.c @@ -299,10 +299,7 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev, cq_entries = roundup_pow_of_two((unsigned int)cq_entries); hr_cq->ib_cq.cqe = cq_entries - 1; - mutex_init(&hr_cq->resize_mutex); spin_lock_init(&hr_cq->lock); - hr_cq->hr_resize_buf = NULL; - hr_cq->resize_umem = NULL; if (context) { if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd))) { diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index db974e4..15bc229 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -284,20 +284,11 @@ struct hns_roce_cq_buf { struct hns_roce_mtt hr_mtt; }; -struct hns_roce_cq_resize { - struct hns_roce_cq_buf hr_buf; - int cqe; -}; - struct hns_roce_cq { struct ib_cqib_cq; struct hns_roce_cq_buf hr_buf; - /* pointer to store information after resize*/ - struct hns_roce_cq_resize *hr_resize_buf; spinlock_t lock; - struct mutexresize_mutex; struct ib_umem *umem; - struct ib_umem *resize_umem; void (*comp)(struct hns_roce_cq *); void (*event)(struct hns_roce_cq *, enum hns_roce_event); -- 1.9.1
[PATCH V2 for-next 01/19] IB/hns: Remove unused parameters in some functions
From: Lijun Ou The parameter named collapsed unused in hns_roce_cq_alloc. Also, parameter named doorbell_lock unsed in hns_roce_v1_cq_set_ci. This patch optimize these parameters. Signed-off-by: Lijun Ou Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_cq.c | 7 +++ drivers/infiniband/hw/hns/hns_roce_device.h | 1 - drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 13 - drivers/infiniband/hw/hns/hns_roce_main.c | 1 - 4 files changed, 7 insertions(+), 15 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_cq.c b/drivers/infiniband/hw/hns/hns_roce_cq.c index 875597b..10fd209 100644 --- a/drivers/infiniband/hw/hns/hns_roce_cq.c +++ b/drivers/infiniband/hw/hns/hns_roce_cq.c @@ -83,8 +83,7 @@ static int hns_roce_sw2hw_cq(struct hns_roce_dev *dev, static int hns_roce_cq_alloc(struct hns_roce_dev *hr_dev, int nent, struct hns_roce_mtt *hr_mtt, struct hns_roce_uar *hr_uar, -struct hns_roce_cq *hr_cq, int vector, -int collapsed) +struct hns_roce_cq *hr_cq, int vector) { struct hns_roce_cmd_mailbox *mailbox = NULL; struct hns_roce_cq_table *cq_table = NULL; @@ -338,8 +337,8 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev, } /* Allocate cq index, fill cq_context */ - ret = hns_roce_cq_alloc(hr_dev, cq_entries, &hr_cq->hr_buf.hr_mtt, - uar, hr_cq, vector, 0); + ret = hns_roce_cq_alloc(hr_dev, cq_entries, &hr_cq->hr_buf.hr_mtt, uar, + hr_cq, vector); if (ret) { dev_err(dev, "Creat CQ .Failed to cq_alloc.\n"); goto err_mtt; diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index 4d02bcf..db974e4 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -536,7 +536,6 @@ struct hns_roce_dev { struct hns_roce_uar priv_uar; const char *irq_names[HNS_ROCE_MAX_IRQ_NUM]; spinlock_t sm_lock; - spinlock_t cq_db_lock; spinlock_t bt_cmd_lock; struct hns_roce_ib_iboe iboe; diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c index 5ffdf7a..48c0862 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -1189,9 +1189,7 @@ static struct hns_roce_cqe *next_cqe_sw(struct hns_roce_cq *hr_cq) return get_sw_cqe(hr_cq, hr_cq->cons_index); } -void hns_roce_v1_cq_set_ci(struct hns_roce_cq *hr_cq, u32 cons_index, - spinlock_t *doorbell_lock) - +void hns_roce_v1_cq_set_ci(struct hns_roce_cq *hr_cq, u32 cons_index) { u32 doorbell[2]; @@ -1251,8 +1249,7 @@ static void __hns_roce_v1_cq_clean(struct hns_roce_cq *hr_cq, u32 qpn, */ wmb(); - hns_roce_v1_cq_set_ci(hr_cq, hr_cq->cons_index, - &to_hr_dev(hr_cq->ib_cq.device)->cq_db_lock); + hns_roce_v1_cq_set_ci(hr_cq, hr_cq->cons_index); } } @@ -1588,10 +1585,8 @@ int hns_roce_v1_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc) break; } - if (npolled) { - hns_roce_v1_cq_set_ci(hr_cq, hr_cq->cons_index, - &to_hr_dev(ibcq->device)->cq_db_lock); - } + if (npolled) + hns_roce_v1_cq_set_ci(hr_cq, hr_cq->cons_index); spin_unlock_irqrestore(&hr_cq->lock, flags); diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c index a9960ba..4b44998 100644 --- a/drivers/infiniband/hw/hns/hns_roce_main.c +++ b/drivers/infiniband/hw/hns/hns_roce_main.c @@ -951,7 +951,6 @@ static int hns_roce_setup_hca(struct hns_roce_dev *hr_dev) struct device *dev = &hr_dev->pdev->dev; spin_lock_init(&hr_dev->sm_lock); - spin_lock_init(&hr_dev->cq_db_lock); spin_lock_init(&hr_dev->bt_cmd_lock); ret = hns_roce_init_uar_table(hr_dev); -- 1.9.1
RE: [PATCH for-next 12/20] IB/hns: Return bad wr while post send failed
> -Original Message- > From: Leon Romanovsky [mailto:l...@kernel.org] > Sent: Thursday, September 15, 2016 10:08 AM > To: Salil Mehta > Cc: dledf...@redhat.com; Huwei (Xavier); oulijun; Zhuangyuzeng (Yisen); > xuwei (O); mehta.salil@gmail.com; linux-r...@vger.kernel.org; > linux-kernel@vger.kernel.org; Linuxarm; Huangdongdong (Donald) > Subject: Re: [PATCH for-next 12/20] IB/hns: Return bad wr while post > send failed > > On Fri, Sep 09, 2016 at 06:30:43PM +0800, Salil Mehta wrote: > > From: Lijun Ou > > > > While post failed, hns roce should return the wr failed to user. > > We omitted this while qp type is wrong and fixed it. > > > > Signed-off-by: Lijun Ou > > Signed-off-by: Dongdong Huang(Donald) > > Reviewed-by: Wei Hu (Xavier) > > Signed-off-by: Salil Mehta > > --- > > drivers/infiniband/hw/hns/hns_roce_hw_v1.c |6 -- > > 1 file changed, 4 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c > b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c > > index f4d2515..f0d6315 100644 > > --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c > > +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c > > @@ -264,8 +264,10 @@ int hns_roce_v1_post_send(struct ib_qp *ibqp, > struct ib_send_wr *wr, > > } > > ind++; > > } else { > > You should move the check of supported QPs to the beginning of > post_send > and don't enter into the loop at all. Hi Leon, Agreed. I have made this change in floated V2 patch. Thanks Salil > > > - dev_dbg(dev, "unSupported QP type\n"); > > - break; > > + dev_err(dev, "unSupported QP type\n"); > > During initial review of hns driver, Lijun was asked to canonize debug > messages and don't use different styles and especially sUcH case. Ok. I have corrected for this instance in V2 patch. Thanks Salil > > > + ret = -EOPNOTSUPP; > > + *bad_wr = wr; > > IMHO, the proper thing is to return NULL, because this is not wrong wr. Ok. Done this change as well. Thanks Salil > > > + goto out; > > } > > } > > > > -- > > 1.7.9.5 > > > > -- > > To unsubscribe from this list: send the line "unsubscribe linux-rdma" > in > > the body of a message to majord...@vger.kernel.org > > More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH for-next 03/20] IB/hns: Add the check for pointer ctrl
> -Original Message- > From: linux-rdma-ow...@vger.kernel.org [mailto:linux-rdma- > ow...@vger.kernel.org] On Behalf Of Leon Romanovsky > Sent: Thursday, September 15, 2016 11:08 AM > To: Salil Mehta > Cc: dledf...@redhat.com; Huwei (Xavier); oulijun; Zhuangyuzeng (Yisen); > xuwei (O); mehta.salil@gmail.com; linux-r...@vger.kernel.org; > linux-kernel@vger.kernel.org; Linuxarm > Subject: Re: [PATCH for-next 03/20] IB/hns: Add the check for pointer > ctrl > > On Fri, Sep 09, 2016 at 06:30:34PM +0800, Salil Mehta wrote: > > From: Lijun Ou > > > > The pointer ctrl may be null, so we add check for it. > > > > Signed-off-by: Lijun Ou > > Reviewed-by: Wei Hu > > Signed-off-by: Salil Mehta > > --- > > drivers/infiniband/hw/hns/hns_roce_hw_v1.c |6 ++ > > 1 file changed, 6 insertions(+) > > > > diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c > b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c > > index 5f76fc1..ea47ec4 100644 > > --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c > > +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c > > @@ -336,6 +336,12 @@ int hns_roce_v1_post_recv(struct ib_qp *ibqp, > struct ib_recv_wr *wr, > > } > > > > ctrl = get_recv_wqe(hr_qp, ind); > > + if (unlikely(!ctrl)) { > > Yes, as you wrote, this check and patch are redundant too. I have dropped this patch in reworked V2 patch and introduced new patch to remove the redundant code as well in get_recv_wqe() and get_send_wqe(). Thanks Salil > > > + dev_err(dev, "Get recv wqe failed!\n"); > > + ret = -EINVAL; > > + *bad_wr = wr; > > + goto out; > > + } > > > > roce_set_field(ctrl->rwqe_byte_12, > >RQ_WQE_CTRL_RWQE_BYTE_12_RWQE_SGE_NUM_M, > > -- > > 1.7.9.5 > > > > -- > > To unsubscribe from this list: send the line "unsubscribe linux-rdma" > in > > the body of a message to majord...@vger.kernel.org > > More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH for-next 18/20] IB/hns: Update the rq head when modify qp state
> -Original Message- > From: Leon Romanovsky [mailto:l...@kernel.org] > Sent: Thursday, September 15, 2016 11:13 AM > To: Salil Mehta > Cc: dledf...@redhat.com; Huwei (Xavier); oulijun; Zhuangyuzeng (Yisen); > xuwei (O); mehta.salil@gmail.com; linux-r...@vger.kernel.org; > linux-kernel@vger.kernel.org; Linuxarm > Subject: Re: [PATCH for-next 18/20] IB/hns: Update the rq head when > modify qp state > > On Fri, Sep 09, 2016 at 06:30:49PM +0800, Salil Mehta wrote: > > From: Lijun Ou > > > > The rq head in qpc was zero will miss the rq wqes which > > have be sent, so here we should take the real value. > > > > Signed-off-by: Lijun Ou > > Reviewed-by: Wei Hu (Xavier) > > Signed-off-by: Salil Mehta > > --- > > drivers/infiniband/hw/hns/hns_roce_hw_v1.c |3 ++- > > 1 file changed, 2 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c > b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c > > index bdd9453..7a61d7e 100644 > > --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c > > +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c > > @@ -2266,7 +2266,8 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, > const struct ib_qp_attr *attr, > > > > roce_set_field(context->qpc_bytes_68, > >QP_CONTEXT_QPC_BYTES_68_RQ_HEAD_M, > > - QP_CONTEXT_QPC_BYTES_68_RQ_HEAD_S, 0); > > + QP_CONTEXT_QPC_BYTES_68_RQ_HEAD_S, > > + hr_qp->rq.head); > > Are you sure that it should be list_head and not value? This is correct. Variable head is not list_head but a u32 value. Hope I understood your point correctly. Best regards Salil > > > roce_set_field(context->qpc_bytes_68, > >QP_CONTEXT_QPC_BYTES_68_RQ_CUR_INDEX_M, > >QP_CONTEXT_QPC_BYTES_68_RQ_CUR_INDEX_S, 0); > > -- > > 1.7.9.5 > > > > -- > > To unsubscribe from this list: send the line "unsubscribe linux-rdma" > in > > the body of a message to majord...@vger.kernel.org > > More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH for-next 20/20] IB/hns: Delete the redundant lines in hns_roce_v1_m_qp()
> -Original Message- > From: linux-rdma-ow...@vger.kernel.org [mailto:linux-rdma- > ow...@vger.kernel.org] On Behalf Of Leon Romanovsky > Sent: Thursday, September 15, 2016 11:15 AM > To: Salil Mehta > Cc: dledf...@redhat.com; Huwei (Xavier); oulijun; Zhuangyuzeng (Yisen); > xuwei (O); mehta.salil@gmail.com; linux-r...@vger.kernel.org; > linux-kernel@vger.kernel.org; Linuxarm > Subject: Re: [PATCH for-next 20/20] IB/hns: Delete the redundant lines > in hns_roce_v1_m_qp() > > On Fri, Sep 09, 2016 at 06:30:51PM +0800, Salil Mehta wrote: > > From: Lijun Ou > > > > It doesn't need to assign for the filed of qp state in qpc separately > > when qp happen to migrate state which supported in RoCE engine v1. > > > > Signed-off-by: Lijun Ou > > Reviewed-by: Wei Hu (Xavier) > > Signed-off-by: Salil Mehta > > --- > > drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 14 +++--- > > 1 file changed, 3 insertions(+), 11 deletions(-) > > > > diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c > b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c > > index 7a61d7e..3bc32fc 100644 > > --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c > > +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c > > @@ -2405,11 +2405,6 @@ static int hns_roce_v1_m_qp(struct ib_qp > *ibqp, const struct ib_qp_attr *attr, > > roce_set_bit(context->qpc_bytes_140, > > QP_CONTEXT_QPC_BYTES_140_RNR_RETRY_FLG_S, 0); > > > > - roce_set_field(context->qpc_bytes_144, > > - QP_CONTEXT_QPC_BYTES_144_QP_STATE_M, > > - QP_CONTEXT_QPC_BYTES_144_QP_STATE_S, > > - attr->qp_state); > > - > > roce_set_field(context->qpc_bytes_148, > >QP_CONTEXT_QPC_BYTES_148_CHECK_FLAG_M, > >QP_CONTEXT_QPC_BYTES_148_CHECK_FLAG_S, 0); > > @@ -2524,13 +2519,10 @@ static int hns_roce_v1_m_qp(struct ib_qp > *ibqp, const struct ib_qp_attr *attr, > >(cur_state == IB_QPS_RTS && new_state == IB_QPS_ERR) || > >(cur_state == IB_QPS_ERR && new_state == IB_QPS_RESET) > || > >(cur_state == IB_QPS_ERR && new_state == IB_QPS_ERR)) { > > - roce_set_field(context->qpc_bytes_144, > > - QP_CONTEXT_QPC_BYTES_144_QP_STATE_M, > > - QP_CONTEXT_QPC_BYTES_144_QP_STATE_S, > > - attr->qp_state); > > - > > + /* It will not do additional options in engine v1 */ > > + ; > > It will leave empty if() {..}, it is worth to rewrite to have one if > for > error path only. Agreed & changed in patch v2! Thanks Salil > > > } else { > > - dev_err(dev, "not support this modify\n"); > > + dev_err(dev, "not support this status migration\n"); > > goto out; > > } > > > > -- > > 1.7.9.5 > > > > -- > > To unsubscribe from this list: send the line "unsubscribe linux-rdma" > in > > the body of a message to majord...@vger.kernel.org > > More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH for-next 18/20] IB/hns: Update the rq head when modify qp state
> -Original Message- > From: linux-rdma-ow...@vger.kernel.org [mailto:linux-rdma- > ow...@vger.kernel.org] On Behalf Of Leon Romanovsky > Sent: Tuesday, September 20, 2016 6:06 PM > To: Salil Mehta > Cc: dledf...@redhat.com; Huwei (Xavier); oulijun; Zhuangyuzeng (Yisen); > xuwei (O); mehta.salil@gmail.com; linux-r...@vger.kernel.org; > linux-kernel@vger.kernel.org; Linuxarm > Subject: Re: [PATCH for-next 18/20] IB/hns: Update the rq head when > modify qp state > > On Tue, Sep 20, 2016 at 04:56:35PM +, Salil Mehta wrote: > > > > > > > -Original Message- > > > From: Leon Romanovsky [mailto:l...@kernel.org] > > > Sent: Thursday, September 15, 2016 11:13 AM > > > To: Salil Mehta > > > Cc: dledf...@redhat.com; Huwei (Xavier); oulijun; Zhuangyuzeng > (Yisen); > > > xuwei (O); mehta.salil@gmail.com; linux-r...@vger.kernel.org; > > > linux-kernel@vger.kernel.org; Linuxarm > > > Subject: Re: [PATCH for-next 18/20] IB/hns: Update the rq head when > > > modify qp state > > > > > > On Fri, Sep 09, 2016 at 06:30:49PM +0800, Salil Mehta wrote: > > > > From: Lijun Ou > > > > > > > > The rq head in qpc was zero will miss the rq wqes which > > > > have be sent, so here we should take the real value. > > > > > > > > Signed-off-by: Lijun Ou > > > > Reviewed-by: Wei Hu (Xavier) > > > > Signed-off-by: Salil Mehta > > > > --- > > > > drivers/infiniband/hw/hns/hns_roce_hw_v1.c |3 ++- > > > > 1 file changed, 2 insertions(+), 1 deletion(-) > > > > > > > > diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c > > > b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c > > > > index bdd9453..7a61d7e 100644 > > > > --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c > > > > +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c > > > > @@ -2266,7 +2266,8 @@ static int hns_roce_v1_m_qp(struct ib_qp > *ibqp, > > > const struct ib_qp_attr *attr, > > > > > > > > roce_set_field(context->qpc_bytes_68, > > > >QP_CONTEXT_QPC_BYTES_68_RQ_HEAD_M, > > > > - QP_CONTEXT_QPC_BYTES_68_RQ_HEAD_S, 0); > > > > + QP_CONTEXT_QPC_BYTES_68_RQ_HEAD_S, > > > > + hr_qp->rq.head); > > > > > > Are you sure that it should be list_head and not value? > > This is correct. Variable head is not list_head but a u32 value. > > Hope I understood your point correctly. > > Thanks, you understood me right. > The name "head" mislead me. > Sorry for that. No worries at all :) Thanks Salil > > > > > Best regards > > Salil > > > > > > > roce_set_field(context->qpc_bytes_68, > > > >QP_CONTEXT_QPC_BYTES_68_RQ_CUR_INDEX_M, > > > >QP_CONTEXT_QPC_BYTES_68_RQ_CUR_INDEX_S, > 0); > > > > -- > > > > 1.7.9.5 > > > > > > > > -- > > > > To unsubscribe from this list: send the line "unsubscribe linux- > rdma" > > > in > > > > the body of a message to majord...@vger.kernel.org > > > > More majordomo info at http://vger.kernel.org/majordomo- > info.html
[PATCH for-next 01/20] IB/hns: Remove unused parameters in some functions
From: Lijun Ou The parameter named collapsed unused in hns_roce_cq_alloc. Also, parameter named doorbell_lock unsed in hns_roce_v1_cq_set_ci. This patch optimize these parameters. Signed-off-by: Lijun Ou Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_cq.c |7 +++ drivers/infiniband/hw/hns/hns_roce_device.h |1 - drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 13 - drivers/infiniband/hw/hns/hns_roce_main.c |1 - 4 files changed, 7 insertions(+), 15 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_cq.c b/drivers/infiniband/hw/hns/hns_roce_cq.c index 875597b..10fd209 100644 --- a/drivers/infiniband/hw/hns/hns_roce_cq.c +++ b/drivers/infiniband/hw/hns/hns_roce_cq.c @@ -83,8 +83,7 @@ static int hns_roce_sw2hw_cq(struct hns_roce_dev *dev, static int hns_roce_cq_alloc(struct hns_roce_dev *hr_dev, int nent, struct hns_roce_mtt *hr_mtt, struct hns_roce_uar *hr_uar, -struct hns_roce_cq *hr_cq, int vector, -int collapsed) +struct hns_roce_cq *hr_cq, int vector) { struct hns_roce_cmd_mailbox *mailbox = NULL; struct hns_roce_cq_table *cq_table = NULL; @@ -338,8 +337,8 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev, } /* Allocate cq index, fill cq_context */ - ret = hns_roce_cq_alloc(hr_dev, cq_entries, &hr_cq->hr_buf.hr_mtt, - uar, hr_cq, vector, 0); + ret = hns_roce_cq_alloc(hr_dev, cq_entries, &hr_cq->hr_buf.hr_mtt, uar, + hr_cq, vector); if (ret) { dev_err(dev, "Creat CQ .Failed to cq_alloc.\n"); goto err_mtt; diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index 066bb3e..ddfef04 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -535,7 +535,6 @@ struct hns_roce_dev { struct hns_roce_uar priv_uar; const char *irq_names[HNS_ROCE_MAX_IRQ_NUM]; spinlock_t sm_lock; - spinlock_t cq_db_lock; spinlock_t bt_cmd_lock; struct hns_roce_ib_iboe iboe; diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c index 3feac8a..5f76fc1 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -1189,9 +1189,7 @@ static struct hns_roce_cqe *next_cqe_sw(struct hns_roce_cq *hr_cq) return get_sw_cqe(hr_cq, hr_cq->cons_index); } -void hns_roce_v1_cq_set_ci(struct hns_roce_cq *hr_cq, u32 cons_index, - spinlock_t *doorbell_lock) - +void hns_roce_v1_cq_set_ci(struct hns_roce_cq *hr_cq, u32 cons_index) { u32 doorbell[2]; @@ -1251,8 +1249,7 @@ static void __hns_roce_v1_cq_clean(struct hns_roce_cq *hr_cq, u32 qpn, */ wmb(); - hns_roce_v1_cq_set_ci(hr_cq, hr_cq->cons_index, - &to_hr_dev(hr_cq->ib_cq.device)->cq_db_lock); + hns_roce_v1_cq_set_ci(hr_cq, hr_cq->cons_index); } } @@ -1588,10 +1585,8 @@ int hns_roce_v1_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc) break; } - if (npolled) { - hns_roce_v1_cq_set_ci(hr_cq, hr_cq->cons_index, - &to_hr_dev(ibcq->device)->cq_db_lock); - } + if (npolled) + hns_roce_v1_cq_set_ci(hr_cq, hr_cq->cons_index); spin_unlock_irqrestore(&hr_cq->lock, flags); diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c index b54074d..2704076 100644 --- a/drivers/infiniband/hw/hns/hns_roce_main.c +++ b/drivers/infiniband/hw/hns/hns_roce_main.c @@ -964,7 +964,6 @@ static int hns_roce_setup_hca(struct hns_roce_dev *hr_dev) struct device *dev = &hr_dev->pdev->dev; spin_lock_init(&hr_dev->sm_lock); - spin_lock_init(&hr_dev->cq_db_lock); spin_lock_init(&hr_dev->bt_cmd_lock); ret = hns_roce_init_uar_table(hr_dev); -- 1.7.9.5
[PATCH for-next 18/20] IB/hns: Update the rq head when modify qp state
From: Lijun Ou The rq head in qpc was zero will miss the rq wqes which have be sent, so here we should take the real value. Signed-off-by: Lijun Ou Reviewed-by: Wei Hu (Xavier) Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_hw_v1.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c index bdd9453..7a61d7e 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -2266,7 +2266,8 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr, roce_set_field(context->qpc_bytes_68, QP_CONTEXT_QPC_BYTES_68_RQ_HEAD_M, - QP_CONTEXT_QPC_BYTES_68_RQ_HEAD_S, 0); + QP_CONTEXT_QPC_BYTES_68_RQ_HEAD_S, + hr_qp->rq.head); roce_set_field(context->qpc_bytes_68, QP_CONTEXT_QPC_BYTES_68_RQ_CUR_INDEX_M, QP_CONTEXT_QPC_BYTES_68_RQ_CUR_INDEX_S, 0); -- 1.7.9.5
[PATCH for-next 04/20] IB/hns: Fix bug of using uninit refcount and free
From: Lijun Ou In current version, it uses uninitialized parameters named refcount and free in hns_roce_cq_event. This patch initializes these parameter in cq alloc and add correspond process in cq free. Signed-off-by: Lijun Ou Signed-off-by: Dongdong Huang(Donald) Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_cq.c |8 1 file changed, 8 insertions(+) diff --git a/drivers/infiniband/hw/hns/hns_roce_cq.c b/drivers/infiniband/hw/hns/hns_roce_cq.c index a52306f..3095f06 100644 --- a/drivers/infiniband/hw/hns/hns_roce_cq.c +++ b/drivers/infiniband/hw/hns/hns_roce_cq.c @@ -152,6 +152,9 @@ static int hns_roce_cq_alloc(struct hns_roce_dev *hr_dev, int nent, hr_cq->cons_index = 0; hr_cq->uar = hr_uar; + atomic_set(&hr_cq->refcount, 1); + init_completion(&hr_cq->free); + return 0; err_radix: @@ -191,6 +194,11 @@ static void hns_roce_free_cq(struct hns_roce_dev *hr_dev, /* Waiting interrupt process procedure carried out */ synchronize_irq(hr_dev->eq_table.eq[hr_cq->vector].irq); + /* wait for all interrupt processed */ + if (atomic_dec_and_test(&hr_cq->refcount)) + complete(&hr_cq->free); + wait_for_completion(&hr_cq->free); + spin_lock_irq(&cq_table->lock); radix_tree_delete(&cq_table->tree, hr_cq->cqn); spin_unlock_irq(&cq_table->lock); -- 1.7.9.5
[PATCH for-next 19/20] IB/hns: Fix the bug when platform_get_resource() exec fail
From: Lijun Ou This patch mainly fixes the bug with platform_get_resource(). It should return NULL when platform_get_resource() exec fail. Signed-off-by: Lijun Ou Reviewed-by: Wei Hu (Xavier) Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_pd.c |4 1 file changed, 4 insertions(+) diff --git a/drivers/infiniband/hw/hns/hns_roce_pd.c b/drivers/infiniband/hw/hns/hns_roce_pd.c index 0cd6132..05db7d5 100644 --- a/drivers/infiniband/hw/hns/hns_roce_pd.c +++ b/drivers/infiniband/hw/hns/hns_roce_pd.c @@ -110,6 +110,10 @@ int hns_roce_uar_alloc(struct hns_roce_dev *hr_dev, struct hns_roce_uar *uar) (hr_dev->caps.phy_num_uars - 1) + 1; res = platform_get_resource(hr_dev->pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&hr_dev->pdev->dev, "memory resource not found!\n"); + return -EINVAL; + } uar->pfn = ((res->start) >> PAGE_SHIFT) + uar->index; return 0; -- 1.7.9.5
[PATCH for-next 10/20] IB/hns: Modify the init of iboe lock
From: Lijun Ou This lock will be used in query port interface, and will be called while IB device was registered to OFED frame. So, the lock of iboe must be initiated before IB device was registered. Signed-off-by: Lijun Ou Signed-off-by: Dongdong Huang(Donald) Reviewed-by: Wei Hu (Xavier) Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_main.c |3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c index 2704076..4721c0c 100644 --- a/drivers/infiniband/hw/hns/hns_roce_main.c +++ b/drivers/infiniband/hw/hns/hns_roce_main.c @@ -615,6 +615,7 @@ static int hns_roce_register_device(struct hns_roce_dev *hr_dev) struct device *dev = &hr_dev->pdev->dev; iboe = &hr_dev->iboe; + spin_lock_init(&iboe->lock); ib_dev = &hr_dev->ib_dev; strlcpy(ib_dev->name, "hisi_%d", IB_DEVICE_NAME_MAX); @@ -701,8 +702,6 @@ static int hns_roce_register_device(struct hns_roce_dev *hr_dev) goto error_failed_setup_mtu_gids; } - spin_lock_init(&iboe->lock); - iboe->nb.notifier_call = hns_roce_netdev_event; ret = register_netdevice_notifier(&iboe->nb); if (ret) { -- 1.7.9.5
[PATCH for-next 13/20] IB/hns: Add check for some NULL pointer scenes
From: Lijun Ou Some pointers have not be checked when they are null, so we add check for them. Signed-off-by: Lijun Ou Signed-off-by: Dongdong Huang(Donald) Reviewed-by: Wei Hu (Xavier) Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c index f0d6315..e3e154c 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -92,6 +92,12 @@ int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, } wqe = get_send_wqe(qp, ind & (qp->sq.wqe_cnt - 1)); + if (unlikely(!wqe)) { + dev_err(dev, "get send wqe failed\n"); + ret = -EINVAL; + *bad_wr = wr; + goto out; + } qp->sq.wrid[(qp->sq.head + nreq) & (qp->sq.wqe_cnt - 1)] = wr->wr_id; @@ -1558,6 +1564,11 @@ static int hns_roce_v1_poll_one(struct hns_roce_cq *hr_cq, sq_wqe = get_send_wqe(*cur_qp, roce_get_field(cqe->cqe_byte_4, CQE_BYTE_4_WQE_INDEX_M, CQE_BYTE_4_WQE_INDEX_S)); + if (unlikely(!sq_wqe)) { + dev_err(dev, "Get send wqe failed!\n"); + return -EFAULT; + } + switch (sq_wqe->flag & HNS_ROCE_WQE_OPCODE_MASK) { case HNS_ROCE_WQE_OPCODE_SEND: wc->opcode = IB_WC_SEND; -- 1.7.9.5
[PATCH for-next 12/20] IB/hns: Return bad wr while post send failed
From: Lijun Ou While post failed, hns roce should return the wr failed to user. We omitted this while qp type is wrong and fixed it. Signed-off-by: Lijun Ou Signed-off-by: Dongdong Huang(Donald) Reviewed-by: Wei Hu (Xavier) Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_hw_v1.c |6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c index f4d2515..f0d6315 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -264,8 +264,10 @@ int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, } ind++; } else { - dev_dbg(dev, "unSupported QP type\n"); - break; + dev_err(dev, "unSupported QP type\n"); + ret = -EOPNOTSUPP; + *bad_wr = wr; + goto out; } } -- 1.7.9.5
[PATCH for-next 03/20] IB/hns: Add the check for pointer ctrl
From: Lijun Ou The pointer ctrl may be null, so we add check for it. Signed-off-by: Lijun Ou Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_hw_v1.c |6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c index 5f76fc1..ea47ec4 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -336,6 +336,12 @@ int hns_roce_v1_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr, } ctrl = get_recv_wqe(hr_qp, ind); + if (unlikely(!ctrl)) { + dev_err(dev, "Get recv wqe failed!\n"); + ret = -EINVAL; + *bad_wr = wr; + goto out; + } roce_set_field(ctrl->rwqe_byte_12, RQ_WQE_CTRL_RWQE_BYTE_12_RWQE_SGE_NUM_M, -- 1.7.9.5
[PATCH for-next 16/20] IB/hns: Validate mtu when modified qp
From: Lijun Ou The mtu should be validated when modify qp,so we check it. Signed-off-by: Lijun Ou Signed-off-by: Peter Chen Reviewed-by: Wei Hu (Xavier) Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_qp.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c index 51fefbf..1c5be59 100644 --- a/drivers/infiniband/hw/hns/hns_roce_qp.c +++ b/drivers/infiniband/hw/hns/hns_roce_qp.c @@ -32,6 +32,7 @@ */ #include +#include #include #include "hns_roce_common.h" #include "hns_roce_device.h" @@ -658,6 +659,7 @@ int hns_roce_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, struct device *dev = &hr_dev->pdev->dev; int ret = -EINVAL; int p; + u32 active_mtu = 0; mutex_lock(&hr_qp->mutex); @@ -688,6 +690,19 @@ int hns_roce_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, } } + if (attr_mask & IB_QP_PATH_MTU) { + p = attr_mask & IB_QP_PORT ? (attr->port_num - 1) : hr_qp->port; + active_mtu = iboe_get_mtu(hr_dev->iboe.netdevs[p]->mtu); + + if (attr->path_mtu > IB_MTU_2048 || + attr->path_mtu < IB_MTU_256 || + attr->path_mtu > active_mtu) { + dev_err(dev, "attr path_mtu(%d)invalid while modify qp", + attr->path_mtu); + goto out; + } + } + if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC && attr->max_rd_atomic > hr_dev->caps.max_qp_init_rdma) { dev_err(dev, "attr max_rd_atomic invalid.attr->max_rd_atomic=%d\n", -- 1.7.9.5
[PATCH for-next 17/20] IB/hns: Cq has not been freed
From: Lijun Ou Cq has not been freed when fail to ib_copy_to_udata, so need to free it. Signed-off-by: Lijun Ou Signed-off-by: Peter Chen Reviewed-by: Wei Hu (Xavier) Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_cq.c |5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_cq.c b/drivers/infiniband/hw/hns/hns_roce_cq.c index 3095f06..0973659 100644 --- a/drivers/infiniband/hw/hns/hns_roce_cq.c +++ b/drivers/infiniband/hw/hns/hns_roce_cq.c @@ -357,12 +357,15 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev, if (context) { if (ib_copy_to_udata(udata, &hr_cq->cqn, sizeof(u64))) { ret = -EFAULT; - goto err_mtt; + goto err_cqc; } } return &hr_cq->ib_cq; +err_cqc: + hns_roce_free_cq(hr_dev, hr_cq); + err_mtt: hns_roce_mtt_cleanup(hr_dev, &hr_cq->hr_buf.hr_mtt); if (context) -- 1.7.9.5
[PATCH for-next 09/20] IB/hns: Optimize code of aeq and ceq interrupt handle and fix the bug of qpn
From: "Wei Hu (Xavier)" This patch optimized the codes of aeq and ceq interrupt handle and fixed the bug in the calculation of qpn. For the special qp(GSI or SMI), calculated the qp number according to physical port and the qpn reported in the event of async event queue. Signed-off-by: Wei Hu (Xavier) Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_eq.c | 146 +++ drivers/infiniband/hw/hns/hns_roce_eq.h |4 + 2 files changed, 75 insertions(+), 75 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_eq.c b/drivers/infiniband/hw/hns/hns_roce_eq.c index 98af7fe..fcab5fb 100644 --- a/drivers/infiniband/hw/hns/hns_roce_eq.c +++ b/drivers/infiniband/hw/hns/hns_roce_eq.c @@ -66,9 +66,6 @@ static void hns_roce_wq_catas_err_handle(struct hns_roce_dev *hr_dev, { struct device *dev = &hr_dev->pdev->dev; - qpn = roce_get_field(aeqe->event.qp_event.qp, -HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_M, -HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_S); dev_warn(dev, "Local Work Queue Catastrophic Error.\n"); switch (roce_get_field(aeqe->asyn, HNS_ROCE_AEQE_U32_4_EVENT_SUB_TYPE_M, HNS_ROCE_AEQE_U32_4_EVENT_SUB_TYPE_S)) { @@ -96,13 +93,6 @@ static void hns_roce_wq_catas_err_handle(struct hns_roce_dev *hr_dev, default: break; } - - hns_roce_qp_event(hr_dev, roce_get_field(aeqe->event.qp_event.qp, - HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_M, - HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_S), - roce_get_field(aeqe->asyn, - HNS_ROCE_AEQE_U32_4_EVENT_TYPE_M, - HNS_ROCE_AEQE_U32_4_EVENT_TYPE_S)); } static void hns_roce_local_wq_access_err_handle(struct hns_roce_dev *hr_dev, @@ -111,9 +101,6 @@ static void hns_roce_local_wq_access_err_handle(struct hns_roce_dev *hr_dev, { struct device *dev = &hr_dev->pdev->dev; - qpn = roce_get_field(aeqe->event.qp_event.qp, -HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_M, -HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_S); dev_warn(dev, "Local Access Violation Work Queue Error.\n"); switch (roce_get_field(aeqe->asyn, HNS_ROCE_AEQE_U32_4_EVENT_SUB_TYPE_M, HNS_ROCE_AEQE_U32_4_EVENT_SUB_TYPE_S)) { @@ -141,13 +128,69 @@ static void hns_roce_local_wq_access_err_handle(struct hns_roce_dev *hr_dev, default: break; } +} + +static void hns_roce_qp_err_handle(struct hns_roce_dev *hr_dev, + struct hns_roce_aeqe *aeqe, + int event_type) +{ + struct device *dev = &hr_dev->pdev->dev; + int phy_port; + int qpn; + + qpn = roce_get_field(aeqe->event.qp_event.qp, +HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_M, +HNS_ROCE_AEQE_EVENT_QP_EVENT_QP_QPN_S); + phy_port = roce_get_field(aeqe->event.qp_event.qp, + HNS_ROCE_AEQE_EVENT_QP_EVENT_PORT_NUM_M, + HNS_ROCE_AEQE_EVENT_QP_EVENT_PORT_NUM_S); + if (qpn <= 1) + qpn = HNS_ROCE_MAX_PORTS * qpn + phy_port; + + switch (event_type) { + case HNS_ROCE_EVENT_TYPE_INV_REQ_LOCAL_WQ_ERROR: + dev_warn(dev, "Invalid Req Local Work Queue Error.\n"); + dev_warn(dev, "QP %d, phy_port %d.\n", qpn, phy_port); + break; + case HNS_ROCE_EVENT_TYPE_WQ_CATAS_ERROR: + hns_roce_wq_catas_err_handle(hr_dev, aeqe, qpn); + break; + case HNS_ROCE_EVENT_TYPE_LOCAL_WQ_ACCESS_ERROR: + hns_roce_local_wq_access_err_handle(hr_dev, aeqe, qpn); + break; + default: + break; + } + + hns_roce_qp_event(hr_dev, qpn, event_type); +} + +static void hns_roce_cq_err_handle(struct hns_roce_dev *hr_dev, + struct hns_roce_aeqe *aeqe, + int event_type) +{ + struct device *dev = &hr_dev->pdev->dev; + u32 cqn; + + cqn = le32_to_cpu(roce_get_field(aeqe->event.cq_event.cq, + HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_M, + HNS_ROCE_AEQE_EVENT_CQ_EVENT_CQ_CQN_S)); + + switch (event_type) { + case HNS_ROCE_EVENT_TYPE_CQ_ACCESS_ERROR: + dev_warn(dev, "CQ 0x%x access err.\n", cqn); + break; + case HNS_ROCE_EVENT_TYPE_CQ_OVERFLOW: + dev_warn(dev, "CQ 0x%x overflow\n", cqn); + break; + case HNS_ROCE_EVENT_TYPE_CQ_ID_INVALID: + dev_w
[PATCH for-next 06/20] IB/hns: Remove unused parameter named qp_type
From: Lijun Ou This patch removes the qp_type parameter in hns_roce_set_kernel_sq_size(). Signed-off-by: Lijun Ou Signed-off-by: Ping Zhang Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_qp.c |4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c index 6095cde..755a4b8 100644 --- a/drivers/infiniband/hw/hns/hns_roce_qp.c +++ b/drivers/infiniband/hw/hns/hns_roce_qp.c @@ -337,12 +337,10 @@ static int hns_roce_set_user_sq_size(struct hns_roce_dev *hr_dev, static int hns_roce_set_kernel_sq_size(struct hns_roce_dev *hr_dev, struct ib_qp_cap *cap, - enum ib_qp_type type, struct hns_roce_qp *hr_qp) { struct device *dev = &hr_dev->pdev->dev; u32 max_cnt; - (void)type; if (cap->max_send_wr > hr_dev->caps.max_wqes || cap->max_send_sge > hr_dev->caps.max_sq_sg || @@ -468,7 +466,7 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev, /* Set SQ size */ ret = hns_roce_set_kernel_sq_size(hr_dev, &init_attr->cap, - init_attr->qp_type, hr_qp); + hr_qp); if (ret) { dev_err(dev, "hns_roce_set_kernel_sq_size error!\n"); goto err_out; -- 1.7.9.5
[PATCH for-next 08/20] IB/hns: Delete the sqp_start from the structure hns_roce_caps
From: "Wei Hu (Xavier)" This patch deleted the sqp_start from the structure hns_roce_caps, and modified the calculation of the qp number. Signed-off-by: Wei Hu (Xavier) Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_device.h |1 - drivers/infiniband/hw/hns/hns_roce_hw_v1.c |1 - drivers/infiniband/hw/hns/hns_roce_qp.c | 10 -- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index f01cc2f..7643716 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -464,7 +464,6 @@ struct hns_roce_caps { u32 max_rq_desc_sz; /* 64 */ int max_qp_init_rdma; int max_qp_dest_rdma; - int sqp_start; int num_cqs; int max_cqes; int reserved_cqs; diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c index f6bb88c..f4d2515 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -942,7 +942,6 @@ void hns_roce_v1_profile(struct hns_roce_dev *hr_dev) caps->mtt_entry_sz = HNS_ROCE_V1_MTT_ENTRY_SIZE; caps->cq_entry_sz = HNS_ROCE_V1_CQE_ENTRY_SIZE; caps->page_size_cap = HNS_ROCE_V1_PAGE_SIZE_SUPPORT; - caps->sqp_start = 0; caps->reserved_lkey = 0; caps->reserved_pds = 0; caps->reserved_mrws = 1; diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c index 755a4b8..51fefbf 100644 --- a/drivers/infiniband/hw/hns/hns_roce_qp.c +++ b/drivers/infiniband/hw/hns/hns_roce_qp.c @@ -39,7 +39,7 @@ #include "hns_roce_user.h" #define DB_REG_OFFSET 0x1000 -#define SQP_NUM12 +#define SQP_NUM(2 * HNS_ROCE_MAX_PORTS) void hns_roce_qp_event(struct hns_roce_dev *hr_dev, u32 qpn, int event_type) { @@ -247,7 +247,7 @@ void hns_roce_release_range_qp(struct hns_roce_dev *hr_dev, int base_qpn, { struct hns_roce_qp_table *qp_table = &hr_dev->qp_table; - if (base_qpn < (hr_dev->caps.sqp_start + 2 * hr_dev->caps.num_ports)) + if (base_qpn < SQP_NUM) return; hns_roce_bitmap_free_range(&qp_table->bitmap, base_qpn, cnt); @@ -609,8 +609,7 @@ struct ib_qp *hns_roce_create_qp(struct ib_pd *pd, hr_qp = &hr_sqp->hr_qp; hr_qp->port = init_attr->port_num - 1; hr_qp->phy_port = hr_dev->iboe.phy_port[hr_qp->port]; - hr_qp->ibqp.qp_num = hr_dev->caps.sqp_start + -HNS_ROCE_MAX_PORTS + + hr_qp->ibqp.qp_num = HNS_ROCE_MAX_PORTS + hr_dev->iboe.phy_port[hr_qp->port]; ret = hns_roce_create_qp_common(hr_dev, pd, init_attr, udata, @@ -826,8 +825,7 @@ int hns_roce_init_qp_table(struct hns_roce_dev *hr_dev) /* A port include two SQP, six port total 12 */ ret = hns_roce_bitmap_init(&qp_table->bitmap, hr_dev->caps.num_qps, - hr_dev->caps.num_qps - 1, - hr_dev->caps.sqp_start + SQP_NUM, + hr_dev->caps.num_qps - 1, SQP_NUM, reserved_from_top); if (ret) { dev_err(&hr_dev->pdev->dev, "qp bitmap init failed!error=%d\n", -- 1.7.9.5
[PATCH for-next 07/20] IB/hns: Fix bug of clear hem
From: "Wei Hu (Xavier)" In hip06, there's no interface to release hem memory. So, hardware can't identify whether hem memory released or not. If all context in a hem memory released, the related hem memory will be released by driver and reused by others. But, hardware don't know that this memory can't be used already. In order to fix this bug, hns roce driver reserved 128K memory for each type of hem(QPC/CQC/MTPT). While unmap hem memory, hns roce driver will write base address of reserved memory according to hem type. Signed-off-by: Wei Hu (Xavier) Signed-off-by: Dongdong Huang(Donald) Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_device.h |2 + drivers/infiniband/hw/hns/hns_roce_hem.c| 76 +-- drivers/infiniband/hw/hns/hns_roce_hem.h|4 + drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 140 +++ drivers/infiniband/hw/hns/hns_roce_hw_v1.h |9 ++ 5 files changed, 157 insertions(+), 74 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index 1c32e9a..f01cc2f 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -505,6 +505,8 @@ struct hns_roce_hw { void (*write_cqc)(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq, void *mb_buf, u64 *mtts, dma_addr_t dma_handle, int nent, u32 vector); + int (*clear_hem)(struct hns_roce_dev *hr_dev, +struct hns_roce_hem_table *table, int obj); int (*query_qp)(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr_mask, struct ib_qp_init_attr *qp_init_attr); int (*modify_qp)(struct ib_qp *ibqp, const struct ib_qp_attr *attr, diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.c b/drivers/infiniband/hw/hns/hns_roce_hem.c index d53d643..250d8f2 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hem.c +++ b/drivers/infiniband/hw/hns/hns_roce_hem.c @@ -36,14 +36,10 @@ #include "hns_roce_hem.h" #include "hns_roce_common.h" -#define HW_SYNC_TIMEOUT_MSECS 500 -#define HW_SYNC_SLEEP_TIME_INTERVAL20 - #define HNS_ROCE_HEM_ALLOC_SIZE(1 << 17) #define HNS_ROCE_TABLE_CHUNK_SIZE (1 << 17) #define DMA_ADDR_T_SHIFT 12 -#define BT_CMD_SYNC_SHIFT 31 #define BT_BA_SHIFT32 struct hns_roce_hem *hns_roce_alloc_hem(struct hns_roce_dev *hr_dev, int npages, @@ -213,74 +209,6 @@ static int hns_roce_set_hem(struct hns_roce_dev *hr_dev, return ret; } -static int hns_roce_clear_hem(struct hns_roce_dev *hr_dev, - struct hns_roce_hem_table *table, - unsigned long obj) -{ - struct device *dev = &hr_dev->pdev->dev; - unsigned long end = 0; - unsigned long flags; - void __iomem *bt_cmd; - uint32_t bt_cmd_val[2]; - u32 bt_cmd_h_val = 0; - int ret = 0; - - switch (table->type) { - case HEM_TYPE_QPC: - roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M, - ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, HEM_TYPE_QPC); - break; - case HEM_TYPE_MTPT: - roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M, - ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, - HEM_TYPE_MTPT); - break; - case HEM_TYPE_CQC: - roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M, - ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, HEM_TYPE_CQC); - break; - case HEM_TYPE_SRQC: - roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M, - ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, - HEM_TYPE_SRQC); - break; - default: - return ret; - } - roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_M, - ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_S, obj); - roce_set_bit(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_S, 0); - roce_set_bit(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_HW_SYNS_S, 1); - roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_M, - ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_S, 0); - - spin_lock_irqsave(&hr_dev->bt_cmd_lock, flags); - - bt_cmd = hr_dev->reg_base + ROCEE_BT_CMD_H_REG; - - end = msecs_to_jiffies(HW_SYNC_TIMEOUT_MSECS) + jiffies; - while (1) { - if (readl(bt_cmd) >> BT_CMD_SYNC_SHIFT) { - if (!(time_before(jiffies, end))) { - dev_err(dev, "Write bt_cmd err,hw_syn
[PATCH for-next 14/20] IB/hns: The Ack timeout need a lower limit value
From: Lijun Ou The Ack timeout of qpc need a lower limit value,otherwise the read performance will be very lower. Signed-off-by: Lijun Ou Signed-off-by: Dongdong Huang(Donald) Reviewed-by: Wei Hu (Xavier) Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 17 + 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c index e3e154c..836a2af 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -2428,10 +2428,19 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr, QP_CONTEXT_QPC_BYTES_156_RETRY_COUNT_INIT_M, QP_CONTEXT_QPC_BYTES_156_RETRY_COUNT_INIT_S, attr->retry_cnt); - roce_set_field(context->qpc_bytes_156, - QP_CONTEXT_QPC_BYTES_156_ACK_TIMEOUT_M, - QP_CONTEXT_QPC_BYTES_156_ACK_TIMEOUT_S, - attr->timeout); + if (attr->timeout < 0x12) { + dev_info(dev, "ack timeout value(0x%x) must bigger than 0x12.\n", +attr->timeout); + roce_set_field(context->qpc_bytes_156, + QP_CONTEXT_QPC_BYTES_156_ACK_TIMEOUT_M, + QP_CONTEXT_QPC_BYTES_156_ACK_TIMEOUT_S, + 0x12); + } else { + roce_set_field(context->qpc_bytes_156, + QP_CONTEXT_QPC_BYTES_156_ACK_TIMEOUT_M, + QP_CONTEXT_QPC_BYTES_156_ACK_TIMEOUT_S, + attr->timeout); + } roce_set_field(context->qpc_bytes_156, QP_CONTEXT_QPC_BYTES_156_RNR_RETRY_COUNT_INIT_M, QP_CONTEXT_QPC_BYTES_156_RNR_RETRY_COUNT_INIT_S, -- 1.7.9.5
[PATCH for-next 05/20] IB/hns: Simplify function of pd alloc and qp alloc
From: Lijun Ou Hns_roce_pd_alloc and hns_roce_reserve_range_qp use unnecessary transformation of parameters. This patch simplify these two functions. Signed-off-by: Lijun Ou Signed-off-by: Dongdong Huang(Donald) Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_pd.c | 14 +- drivers/infiniband/hw/hns/hns_roce_qp.c | 10 +- 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_pd.c b/drivers/infiniband/hw/hns/hns_roce_pd.c index 4109f74..0cd6132 100644 --- a/drivers/infiniband/hw/hns/hns_roce_pd.c +++ b/drivers/infiniband/hw/hns/hns_roce_pd.c @@ -35,19 +35,7 @@ static int hns_roce_pd_alloc(struct hns_roce_dev *hr_dev, unsigned long *pdn) { - struct device *dev = &hr_dev->pdev->dev; - unsigned long pd_number; - int ret = 0; - - ret = hns_roce_bitmap_alloc(&hr_dev->pd_bitmap, &pd_number); - if (ret == -1) { - dev_err(dev, "alloc pdn from pdbitmap failed\n"); - return -ENOMEM; - } - - *pdn = pd_number; - - return 0; + return hns_roce_bitmap_alloc(&hr_dev->pd_bitmap, pdn); } static void hns_roce_pd_free(struct hns_roce_dev *hr_dev, unsigned long pdn) diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c index 089da7f..6095cde 100644 --- a/drivers/infiniband/hw/hns/hns_roce_qp.c +++ b/drivers/infiniband/hw/hns/hns_roce_qp.c @@ -113,16 +113,8 @@ static int hns_roce_reserve_range_qp(struct hns_roce_dev *hr_dev, int cnt, int align, unsigned long *base) { struct hns_roce_qp_table *qp_table = &hr_dev->qp_table; - int ret = 0; - unsigned long qpn; - - ret = hns_roce_bitmap_alloc_range(&qp_table->bitmap, cnt, align, &qpn); - if (ret == -1) - return -ENOMEM; - *base = qpn; - - return 0; + return hns_roce_bitmap_alloc_range(&qp_table->bitmap, cnt, align, base); } enum hns_roce_qp_state to_hns_roce_state(enum ib_qp_state state) -- 1.7.9.5
[PATCH for-next 11/20] IB/hns: Fix bug of memory leakage for registering user mr
From: Lijun Ou While the page size attribute of umem is illegal, we should release umem that get by ib_umem_get interface. Also, we should return a non-zero value while pbl number is wrong. Signed-off-by: Lijun Ou Signed-off-by: Dongdong Huang(Donald) Reviewed-by: Wei Hu (Xavier) Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_mr.c |3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c index 59f5e2b..fb87883 100644 --- a/drivers/infiniband/hw/hns/hns_roce_mr.c +++ b/drivers/infiniband/hw/hns/hns_roce_mr.c @@ -564,11 +564,14 @@ struct ib_mr *hns_roce_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, if (mr->umem->page_size != HNS_ROCE_HEM_PAGE_SIZE) { dev_err(dev, "Just support 4K page size but is 0x%x now!\n", mr->umem->page_size); + ret = -EINVAL; + goto err_umem; } if (n > HNS_ROCE_MAX_MTPT_PBL_NUM) { dev_err(dev, " MR len %lld err. MR is limited to 4G at most!\n", length); + ret = -EINVAL; goto err_umem; } -- 1.7.9.5
[PATCH for-next 02/20] IB/hns: Remove parameters of resize cq
From: Lijun Ou In old version of RoCE, it doesn't support to resize cq. So, we remove parameters related to resize cq. Signed-off-by: Lijun Ou Signed-off-by: Dongdong Huang(Donald) Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_cq.c |3 --- drivers/infiniband/hw/hns/hns_roce_device.h |9 - 2 files changed, 12 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_cq.c b/drivers/infiniband/hw/hns/hns_roce_cq.c index 10fd209..a52306f 100644 --- a/drivers/infiniband/hw/hns/hns_roce_cq.c +++ b/drivers/infiniband/hw/hns/hns_roce_cq.c @@ -299,10 +299,7 @@ struct ib_cq *hns_roce_ib_create_cq(struct ib_device *ib_dev, cq_entries = roundup_pow_of_two((unsigned int)cq_entries); hr_cq->ib_cq.cqe = cq_entries - 1; - mutex_init(&hr_cq->resize_mutex); spin_lock_init(&hr_cq->lock); - hr_cq->hr_resize_buf = NULL; - hr_cq->resize_umem = NULL; if (context) { if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd))) { diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index ddfef04..1c32e9a 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -283,20 +283,11 @@ struct hns_roce_cq_buf { struct hns_roce_mtt hr_mtt; }; -struct hns_roce_cq_resize { - struct hns_roce_cq_buf hr_buf; - int cqe; -}; - struct hns_roce_cq { struct ib_cqib_cq; struct hns_roce_cq_buf hr_buf; - /* pointer to store information after resize*/ - struct hns_roce_cq_resize *hr_resize_buf; spinlock_t lock; - struct mutexresize_mutex; struct ib_umem *umem; - struct ib_umem *resize_umem; void (*comp)(struct hns_roce_cq *); void (*event)(struct hns_roce_cq *, enum hns_roce_event); -- 1.7.9.5
[PATCH for-next 20/20] IB/hns: Delete the redundant lines in hns_roce_v1_m_qp()
From: Lijun Ou It doesn't need to assign for the filed of qp state in qpc separately when qp happen to migrate state which supported in RoCE engine v1. Signed-off-by: Lijun Ou Reviewed-by: Wei Hu (Xavier) Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 14 +++--- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c index 7a61d7e..3bc32fc 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -2405,11 +2405,6 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr, roce_set_bit(context->qpc_bytes_140, QP_CONTEXT_QPC_BYTES_140_RNR_RETRY_FLG_S, 0); - roce_set_field(context->qpc_bytes_144, - QP_CONTEXT_QPC_BYTES_144_QP_STATE_M, - QP_CONTEXT_QPC_BYTES_144_QP_STATE_S, - attr->qp_state); - roce_set_field(context->qpc_bytes_148, QP_CONTEXT_QPC_BYTES_148_CHECK_FLAG_M, QP_CONTEXT_QPC_BYTES_148_CHECK_FLAG_S, 0); @@ -2524,13 +2519,10 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr, (cur_state == IB_QPS_RTS && new_state == IB_QPS_ERR) || (cur_state == IB_QPS_ERR && new_state == IB_QPS_RESET) || (cur_state == IB_QPS_ERR && new_state == IB_QPS_ERR)) { - roce_set_field(context->qpc_bytes_144, - QP_CONTEXT_QPC_BYTES_144_QP_STATE_M, - QP_CONTEXT_QPC_BYTES_144_QP_STATE_S, - attr->qp_state); - + /* It will not do additional options in engine v1 */ + ; } else { - dev_err(dev, "not support this modify\n"); + dev_err(dev, "not support this status migration\n"); goto out; } -- 1.7.9.5
[PATCH for-next 15/20] IB/hns: Some items of qpc need to take user param
From: Lijun Ou Some items of qpc need to take user param when modified qp state. Signed-off-by: Lijun Ou Signed-off-by: Dongdong Huang(Donald) Reviewed-by: Wei Hu (Xavier) Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_hw_v1.c |6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c index 836a2af..bdd9453 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -2414,10 +2414,12 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr, QP_CONTEXT_QPC_BYTES_148_CHECK_FLAG_S, 0); roce_set_field(context->qpc_bytes_148, QP_CONTEXT_QPC_BYTES_148_RETRY_COUNT_M, - QP_CONTEXT_QPC_BYTES_148_RETRY_COUNT_S, 0); + QP_CONTEXT_QPC_BYTES_148_RETRY_COUNT_S, + attr->retry_cnt); roce_set_field(context->qpc_bytes_148, QP_CONTEXT_QPC_BYTES_148_RNR_RETRY_COUNT_M, - QP_CONTEXT_QPC_BYTES_148_RNR_RETRY_COUNT_S, 0); + QP_CONTEXT_QPC_BYTES_148_RNR_RETRY_COUNT_S, + attr->rnr_retry); roce_set_field(context->qpc_bytes_148, QP_CONTEXT_QPC_BYTES_148_LSN_M, QP_CONTEXT_QPC_BYTES_148_LSN_S, 0x100); -- 1.7.9.5
[PATCH for-next 00/20] IB/hns: Fixes for various misc. bugs
This patch-set introduces fixes for various bugs and potential problems found during internal review and testing phases of the HNS RoCE driver. NOTE: These fixes have been done over already floated CM patch: https://lkml.org/lkml/2016/9/1/609 Fixes have been done & tested by Oulijun and Huwei. Lijun Ou (17): IB/hns: Remove unused parameters in some functions IB/hns: Remove parameters of resize cq IB/hns: Add the check for pointer ctrl IB/hns: Fix bug of using uninit refcount and free IB/hns: Simplify function of pd alloc and qp alloc IB/hns: Remove unused parameter named qp_type IB/hns: Modify the init of iboe lock IB/hns: Fix bug of memory leakage for registering user mr IB/hns: Return bad wr while post send failed IB/hns: Add check for some NULL pointer scenes IB/hns: The Ack timeout need a lower limit value IB/hns: Some items of qpc need to take user param IB/hns: Validate mtu when modified qp IB/hns: Cq has not been freed IB/hns: Update the rq head when modify qp state IB/hns: Fix the bug when platform_get_resource() exec fail IB/hns: Delete the redundant lines in hns_roce_v1_m_qp() Wei Hu (Xavier) (3): IB/hns: Fix bug of clear hem IB/hns: Delete the sqp_start from the structure hns_roce_caps IB/hns: Optimize code of aeq and ceq interrupt handle and fix the bug of qpn drivers/infiniband/hw/hns/hns_roce_cq.c | 23 ++- drivers/infiniband/hw/hns/hns_roce_device.h | 13 +- drivers/infiniband/hw/hns/hns_roce_eq.c | 146 +- drivers/infiniband/hw/hns/hns_roce_eq.h |4 + drivers/infiniband/hw/hns/hns_roce_hem.c| 76 +- drivers/infiniband/hw/hns/hns_roce_hem.h|4 + drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 217 +++ drivers/infiniband/hw/hns/hns_roce_hw_v1.h |9 ++ drivers/infiniband/hw/hns/hns_roce_main.c |4 +- drivers/infiniband/hw/hns/hns_roce_mr.c |3 + drivers/infiniband/hw/hns/hns_roce_pd.c | 18 +-- drivers/infiniband/hw/hns/hns_roce_qp.c | 39 ++--- 12 files changed, 324 insertions(+), 232 deletions(-) -- 1.7.9.5
RE: [PATCH for-next 02/10] IB/hns: Register add_gid and del_gid for GID Table management
> -Original Message- > From: Leon Romanovsky [mailto:l...@kernel.org] > Sent: Monday, September 12, 2016 1:40 PM > To: Salil Mehta > Cc: dledf...@redhat.com; Huwei (Xavier); oulijun; Zhuangyuzeng (Yisen); > mehta.salil@gmail.com; linux-r...@vger.kernel.org; linux- > ker...@vger.kernel.org; Linuxarm > Subject: Re: [PATCH for-next 02/10] IB/hns: Register add_gid and > del_gid for GID Table management > > On Fri, Sep 02, 2016 at 05:37:17AM +0800, Salil Mehta wrote: > > From: Lijun Ou > > > > This patch adds support of add_gid() and del_gid() function in the > > HNS RoCE driver for manipulation of the GID table associated with > > port. This shall be used be used by CM when connection is > > established. > > > > Signed-off-by: Lijun Ou > > Reviewed-by: Wei Hu > > Signed-off-by: Salil Mehta > > --- > > drivers/infiniband/hw/hns/hns_roce_main.c | 15 +++ > > 1 file changed, 15 insertions(+) > > > > diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c > b/drivers/infiniband/hw/hns/hns_roce_main.c > > index 39e69c3..4e93120 100644 > > --- a/drivers/infiniband/hw/hns/hns_roce_main.c > > +++ b/drivers/infiniband/hw/hns/hns_roce_main.c > > @@ -158,6 +158,19 @@ static void hns_roce_update_gids(struct > hns_roce_dev *hr_dev, int port) > > ib_dispatch_event(&event); > > } > > > > +static int hns_roce_add_gid(struct ib_device *device, u8 port_num, > > + unsigned int index, const union ib_gid *gid, > > + const struct ib_gid_attr *attr, void **context) > > +{ > > + return 0; > > +} > > + > > +static int hns_roce_del_gid(struct ib_device *device, u8 port_num, > > + unsigned int index, void **context) > > +{ > > + return 0; > > +} > > This patch makes no sense to me. It is the same as not write this > functions at all. I think you are correct. Will remove this patch. Thanks Salil > > > + > > static int handle_en_event(struct hns_roce_dev *hr_dev, u8 port, > >unsigned long event) > > { > > @@ -639,6 +652,8 @@ static int hns_roce_register_device(struct > hns_roce_dev *hr_dev) > > ib_dev->get_link_layer = hns_roce_get_link_layer; > > ib_dev->get_netdev = hns_roce_get_netdev; > > ib_dev->query_gid = hns_roce_query_gid; > > + ib_dev->add_gid = hns_roce_add_gid; > > + ib_dev->del_gid = hns_roce_del_gid; > > ib_dev->query_pkey = hns_roce_query_pkey; > > ib_dev->alloc_ucontext = hns_roce_alloc_ucontext; > > ib_dev->dealloc_ucontext= hns_roce_dealloc_ucontext; > > -- > > 1.7.9.5 > > > > -- > > To unsubscribe from this list: send the line "unsubscribe linux-rdma" > in > > the body of a message to majord...@vger.kernel.org > > More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V2 for-next 0/9] IB/hns: Add CM(Connection Manager) Support to HNS RoCe Driver
This patch-set adds the CM(Connection Manager) support to the HNS RoCE driver. Changes done are primarily to add support of APIs in IB device and some fixes over the base driver to support RDMA Connection Manager. This patch-set also updates the Device binding document as new parameter node-guid was added to the DT. All of the patches have been authored by Oulijun and reviewed by Huwei. Change Log: V1->V2: Addressed the comments from Leon Romanovsky. Please refer individual patch for details. Lijun Ou (9): IB/hns: Register HNS RoCE Driver get_netdev() with IB Core IB/hns: Add & initialize "node_guid" parameter for RDMA CM IB/hns: Fix the value of device_cap_flags IB/hns: Fix two possible bugs for rdma cm IB/hns: Add phy_port for computing GSI/QPN IB/hns: Change the logic for allocating uar registers IB/hns: Fix the bug of rdma cm connecting on user mode IB/hns: Fix two bugs for rdma cm connecting IB/hns: Add node_guid definition to the bindings document .../bindings/infiniband/hisilicon-hns-roce.txt | 2 + drivers/infiniband/hw/hns/hns_roce_device.h| 4 +- drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 80 +- drivers/infiniband/hw/hns/hns_roce_main.c | 32 - drivers/infiniband/hw/hns/hns_roce_pd.c| 4 +- drivers/infiniband/hw/hns/hns_roce_qp.c| 13 ++-- 6 files changed, 76 insertions(+), 59 deletions(-) -- 1.9.1
[PATCH V2 for-next 1/9] IB/hns: Register HNS RoCE Driver get_netdev() with IB Core
From: Lijun Ou This patch adds get_netdev() function to the IB device. This shall be used to fetch netdev corresponding to the port number. This function would be called by IB core(Generic CM Agent) for example, when the RDMA connection is being established. Signed-off-by: Lijun Ou Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_main.c | 20 1 file changed, 20 insertions(+) diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c index f64f0dd..39e69c3 100644 --- a/drivers/infiniband/hw/hns/hns_roce_main.c +++ b/drivers/infiniband/hw/hns/hns_roce_main.c @@ -372,6 +372,25 @@ static int hns_roce_query_device(struct ib_device *ib_dev, return 0; } +static struct net_device *hns_roce_get_netdev(struct ib_device *ib_dev, + u8 port_num) +{ + struct hns_roce_dev *hr_dev = to_hr_dev(ib_dev); + struct net_device *ndev; + + if (port_num < 1 || port_num > hr_dev->caps.num_ports) + return NULL; + + rcu_read_lock(); + + ndev = hr_dev->iboe.netdevs[port_num - 1]; + if (ndev) + dev_hold(ndev); + + rcu_read_unlock(); + return ndev; +} + static int hns_roce_query_port(struct ib_device *ib_dev, u8 port_num, struct ib_port_attr *props) { @@ -618,6 +637,7 @@ static int hns_roce_register_device(struct hns_roce_dev *hr_dev) ib_dev->query_port = hns_roce_query_port; ib_dev->modify_port = hns_roce_modify_port; ib_dev->get_link_layer = hns_roce_get_link_layer; + ib_dev->get_netdev = hns_roce_get_netdev; ib_dev->query_gid = hns_roce_query_gid; ib_dev->query_pkey = hns_roce_query_pkey; ib_dev->alloc_ucontext = hns_roce_alloc_ucontext; -- 1.9.1
[PATCH V2 for-next 2/9] IB/hns: Add & initialize "node_guid" parameter for RDMA CM
From: Lijun Ou According to the Infiniband spec, NodeGUID uniquely identifies a node. This must be initialized to some unique value. This patch adds the support to the HNS RoCE driver to fetch the NodeGUID value from DT or ACPI and then use this value to initialize the node_guid parameter of IB device. This value shall be used by RDMA CM. Signed-off-by: Lijun Ou Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- PATCH V2: Addressed the comment by Leon Romanovsky * Link: https://lkml.org/lkml/2016/9/12/309 PATCH V1: Initial Patch --- drivers/infiniband/hw/hns/hns_roce_device.h | 1 + drivers/infiniband/hw/hns/hns_roce_main.c | 9 + 2 files changed, 10 insertions(+) diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index ea73580..e943b98 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -74,6 +74,7 @@ #define MR_TYPE_DMA0x03 #define PKEY_ID0x +#define GUID_LEN 8 #define NODE_DESC_SIZE 64 #define SERV_TYPE_RC 0 diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c index 39e69c3..f0700f4 100644 --- a/drivers/infiniband/hw/hns/hns_roce_main.c +++ b/drivers/infiniband/hw/hns/hns_roce_main.c @@ -797,6 +797,15 @@ static int hns_roce_get_cfg(struct hns_roce_dev *hr_dev) if (IS_ERR(hr_dev->reg_base)) return PTR_ERR(hr_dev->reg_base); + /* read the node_guid of IB device from the DT or ACPI */ + ret = device_property_read_u8_array(dev, "node-guid", + (u8 *)&hr_dev->ib_dev.node_guid, + GUID_LEN); + if (ret) { + dev_err(dev, "couldn't get node_guid from DT or ACPI!\n"); + return ret; + } + /* get the RoCE associated ethernet ports or netdevices */ for (i = 0; i < HNS_ROCE_MAX_PORTS; i++) { if (dev_of_node(dev)) { -- 1.9.1
[PATCH V2 for-next 4/9] IB/hns: Fix two possible bugs for rdma cm
From: Lijun Ou Fix the length of wqe that maybe lead to an error and write the end bytes of QP1C into the register. Signed-off-by: Lijun Ou Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c index 399f5de..aaea95c 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -205,8 +205,7 @@ int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, (wr->send_flags & IB_SEND_FENCE ? (cpu_to_le32(HNS_ROCE_WQE_FENCE)) : 0); - wqe = (struct hns_roce_wqe_ctrl_seg *)wqe + - sizeof(struct hns_roce_wqe_ctrl_seg); + wqe += sizeof(struct hns_roce_wqe_ctrl_seg); switch (wr->opcode) { case IB_WR_RDMA_READ: @@ -235,8 +234,7 @@ int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, break; } ctrl->flag |= cpu_to_le32(ps_opcode); - wqe = (struct hns_roce_wqe_raddr_seg *)wqe + - sizeof(struct hns_roce_wqe_raddr_seg); + wqe += sizeof(struct hns_roce_wqe_raddr_seg); dseg = wqe; if (wr->send_flags & IB_SEND_INLINE && wr->num_sge) { @@ -253,8 +251,7 @@ int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, memcpy(wqe, ((void *) (uintptr_t) wr->sg_list[i].addr), wr->sg_list[i].length); - wqe = (struct hns_roce_wqe_raddr_seg *) - wqe + wr->sg_list[i].length; + wqe += wr->sg_list[i].length; } ctrl->flag |= HNS_ROCE_WQE_INLINE; } else { @@ -1795,6 +1792,7 @@ static int hns_roce_v1_m_sqp(struct ib_qp *ibqp, const struct ib_qp_attr *attr, writel(context->qp1c_bytes_28, addr + 6); writel(context->qp1c_bytes_32, addr + 7); writel(context->cur_sq_wqe_ba_l, addr + 8); + writel(context->qp1c_bytes_40, addr + 9); } /* Modify QP1C status */ -- 1.9.1
[PATCH V2 for-next 6/9] IB/hns: Change the logic for allocating uar registers
From: Lijun Ou This patch mainly modifies the logic for allocating uar registers. In HiP06 SoC, HW has 8 group of uar registers for kernel and user space application. The uar index is assigned as follows: 0 -- for kernel 1~7 -- for user space application Signed-off-by: Lijun Ou Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_pd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_pd.c b/drivers/infiniband/hw/hns/hns_roce_pd.c index 16271b5..4109f74 100644 --- a/drivers/infiniband/hw/hns/hns_roce_pd.c +++ b/drivers/infiniband/hw/hns/hns_roce_pd.c @@ -117,7 +117,9 @@ int hns_roce_uar_alloc(struct hns_roce_dev *hr_dev, struct hns_roce_uar *uar) if (ret == -1) return -ENOMEM; - uar->index = (uar->index - 1) % hr_dev->caps.phy_num_uars + 1; + if (uar->index > 0) + uar->index = (uar->index - 1) % +(hr_dev->caps.phy_num_uars - 1) + 1; res = platform_get_resource(hr_dev->pdev, IORESOURCE_MEM, 0); uar->pfn = ((res->start) >> PAGE_SHIFT) + uar->index; -- 1.9.1
[PATCH V2 for-next 9/9] IB/hns: Add node_guid definition to the bindings document
From: Lijun Ou This patch adds node_guid definition in bindings document. The value of node_guid will be used during RDMA connection. Signed-off-by: Lijun Ou Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- Documentation/devicetree/bindings/infiniband/hisilicon-hns-roce.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/infiniband/hisilicon-hns-roce.txt b/Documentation/devicetree/bindings/infiniband/hisilicon-hns-roce.txt index f97993b..d3b273e 100644 --- a/Documentation/devicetree/bindings/infiniband/hisilicon-hns-roce.txt +++ b/Documentation/devicetree/bindings/infiniband/hisilicon-hns-roce.txt @@ -14,6 +14,7 @@ length of memory mapped region. representing a ethernet device. - dsaf-handle: phandle, specifies a reference to a node representing a dsaf device. +- node_guid: a number that uniquely identifies a device or component - #address-cells: must be 2 - #size-cells: must be 2 Optional properties: @@ -32,6 +33,7 @@ Example: dma-coherent; eth-handle = <ð2 ð3 ð4 ð5 ð6 ð7>; dsaf-handle = <&soc0_dsa>; + node-guid = [00 9A CD 00 00 01 02 03]; #address-cells = <2>; #size-cells = <2>; interrupt-parent = <&mbigen_dsa>; -- 1.9.1
[PATCH V2 for-next 3/9] IB/hns: Fix the value of device_cap_flags
From: Lijun Ou In the latest IB core version, it has some known issues with memory registration using the local_dma_lkey. Thus RoCE don't expose support for it, and remove device->local_dma_lkey which is introduced to working systems. Signed-off-by: Lijun Ou Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c index f0700f4..a9960ba 100644 --- a/drivers/infiniband/hw/hns/hns_roce_main.c +++ b/drivers/infiniband/hw/hns/hns_roce_main.c @@ -355,8 +355,7 @@ static int hns_roce_query_device(struct ib_device *ib_dev, props->max_qp = hr_dev->caps.num_qps; props->max_qp_wr = hr_dev->caps.max_wqes; props->device_cap_flags = IB_DEVICE_PORT_ACTIVE_EVENT | - IB_DEVICE_RC_RNR_NAK_GEN | - IB_DEVICE_LOCAL_DMA_LKEY; + IB_DEVICE_RC_RNR_NAK_GEN; props->max_sge = hr_dev->caps.max_sq_sg; props->max_sge_rd = 1; props->max_cq = hr_dev->caps.num_cqs; -- 1.9.1
[PATCH V2 for-next 8/9] IB/hns: Fix two bugs for rdma cm connecting
From: Lijun Ou This patch mainly modify the value of HNS_ROCE_SL_SHIFT and delete the lines for assigning for the field of local_enable_e2e_credit in QP1C. Signed-off-by: Lijun Ou Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_device.h | 2 +- drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index 833742b..066bb3e 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -62,7 +62,7 @@ #define HNS_ROCE_AEQE_OF_VEC_NUM 1 /* 4G/4K = 1M */ -#define HNS_ROCE_SL_SHIFT 29 +#define HNS_ROCE_SL_SHIFT 28 #define HNS_ROCE_TCLASS_SHIFT 20 #define HNS_ROCE_FLOW_LABLE_MASK 0xf diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c index 206957b..3feac8a 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -1734,9 +1734,6 @@ static int hns_roce_v1_m_sqp(struct ib_qp *ibqp, const struct ib_qp_attr *attr, roce_set_bit(context->qp1c_bytes_16, QP1C_BYTES_16_SIGNALING_TYPE_S, hr_qp->sq_signal_bits); - roce_set_bit(context->qp1c_bytes_16, -QP1C_BYTES_16_LOCAL_ENABLE_E2E_CREDIT_S, -hr_qp->sq_signal_bits); roce_set_bit(context->qp1c_bytes_16, QP1C_BYTES_16_RQ_BA_FLG_S, 1); roce_set_bit(context->qp1c_bytes_16, QP1C_BYTES_16_SQ_BA_FLG_S, -- 1.9.1
[PATCH V2 for-next 5/9] IB/hns: Add phy_port for computing GSI/QPN
From: Lijun Ou This patch mainly adds phy_port to HNS RoCE QP. This shall be used in calculating the GSI QPN for the port. Initally when RDMA is being established, all IB ports share a QPN which later needs to be re-assigned to a particular GSI/QPN and which is per-port. This also fixes a bug in base driver where iboe port was being used instead of phy_port at some places. This values might not be same always. Signed-off-by: Lijun Ou Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_device.h | 1 + drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 30 +++-- drivers/infiniband/hw/hns/hns_roce_qp.c | 13 ++--- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index e943b98..833742b 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -409,6 +409,7 @@ struct hns_roce_qp { u32 buff_size; struct mutexmutex; u8 port; + u8 phy_port; u8 sl; u8 resp_depth; u8 state; diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c index aaea95c..581e542 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -162,7 +162,7 @@ int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, roce_set_field(ud_sq_wqe->u32_36, UD_SEND_WQE_U32_36_SGID_INDEX_M, UD_SEND_WQE_U32_36_SGID_INDEX_S, - hns_get_gid_index(hr_dev, qp->port, + hns_get_gid_index(hr_dev, qp->phy_port, ah->av.gid_index)); roce_set_field(ud_sq_wqe->u32_40, @@ -282,7 +282,7 @@ out: SQ_DOORBELL_U32_4_SQ_HEAD_S, (qp->sq.head & ((qp->sq.wqe_cnt << 1) - 1))); roce_set_field(sq_db.u32_4, SQ_DOORBELL_U32_4_PORT_M, - SQ_DOORBELL_U32_4_PORT_S, qp->port); + SQ_DOORBELL_U32_4_PORT_S, qp->phy_port); roce_set_field(sq_db.u32_8, SQ_DOORBELL_U32_8_QPN_M, SQ_DOORBELL_U32_8_QPN_S, qp->doorbell_qpn); roce_set_bit(sq_db.u32_8, SQ_DOORBELL_HW_SYNC_S, 1); @@ -362,14 +362,14 @@ out: /* SW update GSI rq header */ reg_val = roce_read(to_hr_dev(ibqp->device), ROCEE_QP1C_CFG3_0_REG + - QP1C_CFGN_OFFSET * hr_qp->port); + QP1C_CFGN_OFFSET * hr_qp->phy_port); roce_set_field(reg_val, ROCEE_QP1C_CFG3_0_ROCEE_QP1C_RQ_HEAD_M, ROCEE_QP1C_CFG3_0_ROCEE_QP1C_RQ_HEAD_S, hr_qp->rq.head); roce_write(to_hr_dev(ibqp->device), ROCEE_QP1C_CFG3_0_REG + - QP1C_CFGN_OFFSET * hr_qp->port, reg_val); + QP1C_CFGN_OFFSET * hr_qp->phy_port, reg_val); } else { rq_db.u32_4 = 0; rq_db.u32_8 = 0; @@ -1730,7 +1730,7 @@ static int hns_roce_v1_m_sqp(struct ib_qp *ibqp, const struct ib_qp_attr *attr, roce_set_field(context->qp1c_bytes_16, QP1C_BYTES_16_RQ_HEAD_M, QP1C_BYTES_16_RQ_HEAD_S, hr_qp->rq.head); roce_set_field(context->qp1c_bytes_16, QP1C_BYTES_16_PORT_NUM_M, - QP1C_BYTES_16_PORT_NUM_S, hr_qp->port); + QP1C_BYTES_16_PORT_NUM_S, hr_qp->phy_port); roce_set_bit(context->qp1c_bytes_16, QP1C_BYTES_16_SIGNALING_TYPE_S, hr_qp->sq_signal_bits); @@ -1781,7 +1781,7 @@ static int hns_roce_v1_m_sqp(struct ib_qp *ibqp, const struct ib_qp_attr *attr, /* Copy context to QP1C register */ addr = (u32 *)(hr_dev->reg_base + ROCEE_QP1C_CFG0_0_REG + - hr_qp->port * sizeof(*context)); + hr_qp->phy_port * sizeof(*context)); writel(context->qp1c_bytes_4, addr); writel(context->sq_rq_bt_l, addr + 1); @@ -1797,11 +1797,11 @@ static int hns_roce_v1_m_sqp(struct ib_qp *ibq
[PATCH V2 for-next 7/9] IB/hns: Fix the bug of rdma cm connecting on user mode
From: Lijun Ou Fix bug of modify qp from init to init on user mode. Otherwise, it will oops when rmda cm established. Signed-off-by: Lijun Ou Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 41 ++ 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c index 581e542..206957b 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -2395,35 +2395,22 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr, if (cur_state == IB_QPS_INIT && new_state == IB_QPS_INIT) { /* Memory barrier */ wmb(); - if (hr_qp->ibqp.qp_type == IB_QPT_GSI) { - /* SW update GSI rq header */ - reg_val = roce_read(hr_dev, ROCEE_QP1C_CFG3_0_REG + - QP1C_CFGN_OFFSET * hr_qp->phy_port); - roce_set_field(reg_val, - ROCEE_QP1C_CFG3_0_ROCEE_QP1C_RQ_HEAD_M, - ROCEE_QP1C_CFG3_0_ROCEE_QP1C_RQ_HEAD_S, - hr_qp->rq.head); - roce_write(hr_dev, ROCEE_QP1C_CFG3_0_REG + - QP1C_CFGN_OFFSET * hr_qp->phy_port, reg_val); - } else { - rq_db.u32_4 = 0; - rq_db.u32_8 = 0; - roce_set_field(rq_db.u32_4, RQ_DOORBELL_U32_4_RQ_HEAD_M, - RQ_DOORBELL_U32_4_RQ_HEAD_S, - hr_qp->rq.head); - roce_set_field(rq_db.u32_8, RQ_DOORBELL_U32_8_QPN_M, - RQ_DOORBELL_U32_8_QPN_S, hr_qp->qpn); - roce_set_field(rq_db.u32_8, RQ_DOORBELL_U32_8_CMD_M, - RQ_DOORBELL_U32_8_CMD_S, 1); - roce_set_bit(rq_db.u32_8, RQ_DOORBELL_U32_8_HW_SYNC_S, -1); - - doorbell[0] = rq_db.u32_4; - doorbell[1] = rq_db.u32_8; - - hns_roce_write64_k(doorbell, hr_qp->rq.db_reg_l); + roce_set_field(doorbell[0], RQ_DOORBELL_U32_4_RQ_HEAD_M, + RQ_DOORBELL_U32_4_RQ_HEAD_S, hr_qp->rq.head); + roce_set_field(doorbell[1], RQ_DOORBELL_U32_8_QPN_M, + RQ_DOORBELL_U32_8_QPN_S, hr_qp->qpn); + roce_set_field(doorbell[1], RQ_DOORBELL_U32_8_CMD_M, + RQ_DOORBELL_U32_8_CMD_S, 1); + roce_set_bit(doorbell[1], RQ_DOORBELL_U32_8_HW_SYNC_S, 1); + + if (ibqp->uobject) { + hr_qp->rq.db_reg_l = hr_dev->reg_base + +ROCEE_DB_OTHERS_L_0_REG + +DB_REG_OFFSET * hr_dev->priv_uar.index; } + + hns_roce_write64_k(doorbell, hr_qp->rq.db_reg_l); } hr_qp->state = new_state; -- 1.9.1
RE: [PATCH for-next 16/20] IB/hns: Validate mtu when modified qp
> -Original Message- > From: Leon Romanovsky [mailto:l...@kernel.org] > Sent: Tuesday, September 13, 2016 7:33 AM > To: Salil Mehta > Cc: dledf...@redhat.com; Huwei (Xavier); oulijun; Zhuangyuzeng (Yisen); > xuwei (O); mehta.salil@gmail.com; linux-r...@vger.kernel.org; > linux-kernel@vger.kernel.org; Linuxarm; chenguolong (A) > Subject: Re: [PATCH for-next 16/20] IB/hns: Validate mtu when modified > qp > > On Fri, Sep 09, 2016 at 06:30:47PM +0800, Salil Mehta wrote: > > From: Lijun Ou > > > > The mtu should be validated when modify qp,so we check it. > > > > Signed-off-by: Lijun Ou > > Signed-off-by: Peter Chen > > Reviewed-by: Wei Hu (Xavier) > > Signed-off-by: Salil Mehta > > --- > > drivers/infiniband/hw/hns/hns_roce_qp.c | 15 +++ > > 1 file changed, 15 insertions(+) > > > > diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c > b/drivers/infiniband/hw/hns/hns_roce_qp.c > > index 51fefbf..1c5be59 100644 > > --- a/drivers/infiniband/hw/hns/hns_roce_qp.c > > +++ b/drivers/infiniband/hw/hns/hns_roce_qp.c > > @@ -32,6 +32,7 @@ > > */ > > > > #include > > +#include > > #include > > #include "hns_roce_common.h" > > #include "hns_roce_device.h" > > @@ -658,6 +659,7 @@ int hns_roce_modify_qp(struct ib_qp *ibqp, struct > ib_qp_attr *attr, > > struct device *dev = &hr_dev->pdev->dev; > > int ret = -EINVAL; > > int p; > > + u32 active_mtu = 0; > > There is no need to assign value to a variable which will be > overwritten. Agreed. This initialization seems redundant. Will remove. Thanks! Best regards Salil > > > > > mutex_lock(&hr_qp->mutex); > > > > @@ -688,6 +690,19 @@ int hns_roce_modify_qp(struct ib_qp *ibqp, > struct ib_qp_attr *attr, > > } > > } > > > > + if (attr_mask & IB_QP_PATH_MTU) { > > + p = attr_mask & IB_QP_PORT ? (attr->port_num - 1) : hr_qp- > >port; > > + active_mtu = iboe_get_mtu(hr_dev->iboe.netdevs[p]->mtu); > > ib_mtu iboe_get_mtu returns "enum ib_mtu" and not u32. Ok. This can be converted to 'enum'. Will change. Thanks! Best regards Salil > > > + > > + if (attr->path_mtu > IB_MTU_2048 || > > + attr->path_mtu < IB_MTU_256 || > > + attr->path_mtu > active_mtu) { > > + dev_err(dev, "attr path_mtu(%d)invalid while modify > qp", > > + attr->path_mtu); > > + goto out; > > + } > > + } > > + > > if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC && > > attr->max_rd_atomic > hr_dev->caps.max_qp_init_rdma) { > > dev_err(dev, "attr max_rd_atomic invalid.attr- > >max_rd_atomic=%d\n", > > -- > > 1.7.9.5 > > > > -- > > To unsubscribe from this list: send the line "unsubscribe linux-rdma" > in > > the body of a message to majord...@vger.kernel.org > > More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH for-next 10/20] IB/hns: Modify the init of iboe lock
> -Original Message- > From: linux-rdma-ow...@vger.kernel.org [mailto:linux-rdma- > ow...@vger.kernel.org] On Behalf Of Leon Romanovsky > Sent: Tuesday, September 13, 2016 7:50 AM > To: Salil Mehta > Cc: dledf...@redhat.com; Huwei (Xavier); oulijun; Zhuangyuzeng (Yisen); > xuwei (O); mehta.salil@gmail.com; linux-r...@vger.kernel.org; > linux-kernel@vger.kernel.org; Linuxarm; Huangdongdong (Donald) > Subject: Re: [PATCH for-next 10/20] IB/hns: Modify the init of iboe > lock > > On Fri, Sep 09, 2016 at 06:30:41PM +0800, Salil Mehta wrote: > > From: Lijun Ou > > > > This lock will be used in query port interface, and will be called > > while IB device was registered to OFED frame. So, the lock of iboe > > must be initiated before IB device was registered. > > Sorry, > what did you mean by writing "OFED frame"? It is a typo. It was OFED framework but I guess more appropriate word might have been 'IB core' layer of Infiniband. Will fix this. Thanks! Best regards Salil > > > > > Signed-off-by: Lijun Ou > > Signed-off-by: Dongdong Huang(Donald) > > Reviewed-by: Wei Hu (Xavier) > > Signed-off-by: Salil Mehta > > --- > > drivers/infiniband/hw/hns/hns_roce_main.c |3 +-- > > 1 file changed, 1 insertion(+), 2 deletions(-) > > > > diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c > b/drivers/infiniband/hw/hns/hns_roce_main.c > > index 2704076..4721c0c 100644 > > --- a/drivers/infiniband/hw/hns/hns_roce_main.c > > +++ b/drivers/infiniband/hw/hns/hns_roce_main.c > > @@ -615,6 +615,7 @@ static int hns_roce_register_device(struct > hns_roce_dev *hr_dev) > > struct device *dev = &hr_dev->pdev->dev; > > > > iboe = &hr_dev->iboe; > > + spin_lock_init(&iboe->lock); > > > > ib_dev = &hr_dev->ib_dev; > > strlcpy(ib_dev->name, "hisi_%d", IB_DEVICE_NAME_MAX); > > @@ -701,8 +702,6 @@ static int hns_roce_register_device(struct > hns_roce_dev *hr_dev) > > goto error_failed_setup_mtu_gids; > > } > > > > - spin_lock_init(&iboe->lock); > > - > > iboe->nb.notifier_call = hns_roce_netdev_event; > > ret = register_netdevice_notifier(&iboe->nb); > > if (ret) { > > -- > > 1.7.9.5 > > > > -- > > To unsubscribe from this list: send the line "unsubscribe linux-rdma" > in > > the body of a message to majord...@vger.kernel.org > > More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH for-next 13/20] IB/hns: Add check for some NULL pointer scenes
> -Original Message- > From: linux-rdma-ow...@vger.kernel.org [mailto:linux-rdma- > ow...@vger.kernel.org] On Behalf Of Leon Romanovsky > Sent: Tuesday, September 13, 2016 8:00 AM > To: Salil Mehta > Cc: dledf...@redhat.com; Huwei (Xavier); oulijun; Zhuangyuzeng (Yisen); > xuwei (O); mehta.salil@gmail.com; linux-r...@vger.kernel.org; > linux-kernel@vger.kernel.org; Linuxarm; Huangdongdong (Donald) > Subject: Re: [PATCH for-next 13/20] IB/hns: Add check for some NULL > pointer scenes > > On Fri, Sep 09, 2016 at 06:30:44PM +0800, Salil Mehta wrote: > > From: Lijun Ou > > > > Some pointers have not be checked when they are null, > > so we add check for them. > > > > Signed-off-by: Lijun Ou > > Signed-off-by: Dongdong Huang(Donald) > > Reviewed-by: Wei Hu (Xavier) > > Signed-off-by: Salil Mehta > > I may admit that I didn't check your code to read the implementations > of > get_send_wqe() and hns_roce_v1_poll_one(), but based on my assumption > that the code is similar to mlx4. > > These failures can't occur. > > Can you throw a light on how did you find them and check it? Hi Leon, Looks like this is another redundant patch. These return checks should never be required. I think the mistake lies in the wrong check placed inside below function: void *get_send_wqe(struct hns_roce_qp *hr_qp, int n) { . . /* To Be Deleted: Below check is redundantly placed. */ if ((n < 0) || (n > hr_qp->sq.wqe_cnt)) { dev_err(&hr_dev->pdev->dev, "sq wqe index:%d,sq wqe cnt:%d\r\n", n, hr_qp->sq.wqe_cnt); return NULL; } return get_wqe(hr_qp, hr_qp->sq.offset + (n << hr_qp->sq.wqe_shift)); } and perhaps same is the case in function get_rcv_wqe(). The same check needs to be removed from there as well and also the error handling in the calling functions. Thanks for figuring it out. Will correct in the subsequent patch. Best regards Salil > > > --- > > drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 11 +++ > > 1 file changed, 11 insertions(+) > > > > diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c > b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c > > index f0d6315..e3e154c 100644 > > --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c > > +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c > > @@ -92,6 +92,12 @@ int hns_roce_v1_post_send(struct ib_qp *ibqp, > struct ib_send_wr *wr, > > } > > > > wqe = get_send_wqe(qp, ind & (qp->sq.wqe_cnt - 1)); > > + if (unlikely(!wqe)) { > > + dev_err(dev, "get send wqe failed\n"); > > + ret = -EINVAL; > > + *bad_wr = wr; > > + goto out; > > + } > > qp->sq.wrid[(qp->sq.head + nreq) & (qp->sq.wqe_cnt - 1)] = > > wr->wr_id; > > > > @@ -1558,6 +1564,11 @@ static int hns_roce_v1_poll_one(struct > hns_roce_cq *hr_cq, > > sq_wqe = get_send_wqe(*cur_qp, roce_get_field(cqe- > >cqe_byte_4, > > CQE_BYTE_4_WQE_INDEX_M, > > CQE_BYTE_4_WQE_INDEX_S)); > > + if (unlikely(!sq_wqe)) { > > + dev_err(dev, "Get send wqe failed!\n"); > > + return -EFAULT; > > + } > > + > > switch (sq_wqe->flag & HNS_ROCE_WQE_OPCODE_MASK) { > > case HNS_ROCE_WQE_OPCODE_SEND: > > wc->opcode = IB_WC_SEND; > > -- > > 1.7.9.5 > > > > -- > > To unsubscribe from this list: send the line "unsubscribe linux-rdma" > in > > the body of a message to majord...@vger.kernel.org > > More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH for-next 10/20] IB/hns: Modify the init of iboe lock
> -Original Message- > From: Leon Romanovsky [mailto:l...@kernel.org] > Sent: Wednesday, September 14, 2016 6:05 AM > To: Salil Mehta > Cc: dledf...@redhat.com; Huwei (Xavier); oulijun; Zhuangyuzeng (Yisen); > xuwei (O); mehta.salil@gmail.com; linux-r...@vger.kernel.org; > linux-kernel@vger.kernel.org; Linuxarm; Huangdongdong (Donald) > Subject: Re: [PATCH for-next 10/20] IB/hns: Modify the init of iboe > lock > > On Wed, Sep 14, 2016 at 02:09:37AM +, Salil Mehta wrote: > > > > > > > -Original Message- > > > From: linux-rdma-ow...@vger.kernel.org [mailto:linux-rdma- > > > ow...@vger.kernel.org] On Behalf Of Leon Romanovsky > > > Sent: Tuesday, September 13, 2016 7:50 AM > > > To: Salil Mehta > > > Cc: dledf...@redhat.com; Huwei (Xavier); oulijun; Zhuangyuzeng > (Yisen); > > > xuwei (O); mehta.salil@gmail.com; linux-r...@vger.kernel.org; > > > linux-kernel@vger.kernel.org; Linuxarm; Huangdongdong (Donald) > > > Subject: Re: [PATCH for-next 10/20] IB/hns: Modify the init of iboe > > > lock > > > > > > On Fri, Sep 09, 2016 at 06:30:41PM +0800, Salil Mehta wrote: > > > > From: Lijun Ou > > > > > > > > This lock will be used in query port interface, and will be > called > > > > while IB device was registered to OFED frame. So, the lock of > iboe > > > > must be initiated before IB device was registered. > > > > > > Sorry, > > > what did you mean by writing "OFED frame"? > > It is a typo. It was OFED framework but I guess more appropriate word > > might have been 'IB core' layer of Infiniband. Will fix this. Thanks! > > As a general note, and I understand that these contributors are not > native English speakers, and I understand the desire to submit the > right > code and code should speak by itself, but can you invest more time in > commit messages and write them in English? > > Thanks Hi Leon, Yes, will try to make them better. Best regards Salil > > > > Best regards > > Salil > > > > > > > > > > > Signed-off-by: Lijun Ou > > > > Signed-off-by: Dongdong Huang(Donald) > > > > Reviewed-by: Wei Hu (Xavier) > > > > Signed-off-by: Salil Mehta > > > > --- > > > > drivers/infiniband/hw/hns/hns_roce_main.c |3 +-- > > > > 1 file changed, 1 insertion(+), 2 deletions(-) > > > > > > > > diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c > > > b/drivers/infiniband/hw/hns/hns_roce_main.c > > > > index 2704076..4721c0c 100644 > > > > --- a/drivers/infiniband/hw/hns/hns_roce_main.c > > > > +++ b/drivers/infiniband/hw/hns/hns_roce_main.c > > > > @@ -615,6 +615,7 @@ static int hns_roce_register_device(struct > > > hns_roce_dev *hr_dev) > > > > struct device *dev = &hr_dev->pdev->dev; > > > > > > > > iboe = &hr_dev->iboe; > > > > + spin_lock_init(&iboe->lock); > > > > > > > > ib_dev = &hr_dev->ib_dev; > > > > strlcpy(ib_dev->name, "hisi_%d", IB_DEVICE_NAME_MAX); > > > > @@ -701,8 +702,6 @@ static int hns_roce_register_device(struct > > > hns_roce_dev *hr_dev) > > > > goto error_failed_setup_mtu_gids; > > > > } > > > > > > > > - spin_lock_init(&iboe->lock); > > > > - > > > > iboe->nb.notifier_call = hns_roce_netdev_event; > > > > ret = register_netdevice_notifier(&iboe->nb); > > > > if (ret) { > > > > -- > > > > 1.7.9.5 > > > > > > > > -- > > > > To unsubscribe from this list: send the line "unsubscribe linux- > rdma" > > > in > > > > the body of a message to majord...@vger.kernel.org > > > > More majordomo info at http://vger.kernel.org/majordomo- > info.html
[PATCH for-next 08/10] IB/hns: Fix the bug of rdma cm connecting on user mode
From: Lijun Ou Fix bug of modify qp from init to init on user mode. Otherwise, it will oops when rmda cm established. Signed-off-by: Lijun Ou Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 41 ++-- 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c index 581e542..206957b 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -2395,35 +2395,22 @@ static int hns_roce_v1_m_qp(struct ib_qp *ibqp, const struct ib_qp_attr *attr, if (cur_state == IB_QPS_INIT && new_state == IB_QPS_INIT) { /* Memory barrier */ wmb(); - if (hr_qp->ibqp.qp_type == IB_QPT_GSI) { - /* SW update GSI rq header */ - reg_val = roce_read(hr_dev, ROCEE_QP1C_CFG3_0_REG + - QP1C_CFGN_OFFSET * hr_qp->phy_port); - roce_set_field(reg_val, - ROCEE_QP1C_CFG3_0_ROCEE_QP1C_RQ_HEAD_M, - ROCEE_QP1C_CFG3_0_ROCEE_QP1C_RQ_HEAD_S, - hr_qp->rq.head); - roce_write(hr_dev, ROCEE_QP1C_CFG3_0_REG + - QP1C_CFGN_OFFSET * hr_qp->phy_port, reg_val); - } else { - rq_db.u32_4 = 0; - rq_db.u32_8 = 0; - roce_set_field(rq_db.u32_4, RQ_DOORBELL_U32_4_RQ_HEAD_M, - RQ_DOORBELL_U32_4_RQ_HEAD_S, - hr_qp->rq.head); - roce_set_field(rq_db.u32_8, RQ_DOORBELL_U32_8_QPN_M, - RQ_DOORBELL_U32_8_QPN_S, hr_qp->qpn); - roce_set_field(rq_db.u32_8, RQ_DOORBELL_U32_8_CMD_M, - RQ_DOORBELL_U32_8_CMD_S, 1); - roce_set_bit(rq_db.u32_8, RQ_DOORBELL_U32_8_HW_SYNC_S, -1); - - doorbell[0] = rq_db.u32_4; - doorbell[1] = rq_db.u32_8; - - hns_roce_write64_k(doorbell, hr_qp->rq.db_reg_l); + roce_set_field(doorbell[0], RQ_DOORBELL_U32_4_RQ_HEAD_M, + RQ_DOORBELL_U32_4_RQ_HEAD_S, hr_qp->rq.head); + roce_set_field(doorbell[1], RQ_DOORBELL_U32_8_QPN_M, + RQ_DOORBELL_U32_8_QPN_S, hr_qp->qpn); + roce_set_field(doorbell[1], RQ_DOORBELL_U32_8_CMD_M, + RQ_DOORBELL_U32_8_CMD_S, 1); + roce_set_bit(doorbell[1], RQ_DOORBELL_U32_8_HW_SYNC_S, 1); + + if (ibqp->uobject) { + hr_qp->rq.db_reg_l = hr_dev->reg_base + +ROCEE_DB_OTHERS_L_0_REG + +DB_REG_OFFSET * hr_dev->priv_uar.index; } + + hns_roce_write64_k(doorbell, hr_qp->rq.db_reg_l); } hr_qp->state = new_state; -- 1.7.9.5
[PATCH for-next 01/10] IB/hns: Register HNS RoCE Driver get_netdev() with IB Core
From: Lijun Ou This patch adds get_netdev() function to the IB device. This shall be used to fetch netdev corresponding to the port number. This function would be called by IB core(Generic CM Agent) for example, when the RDMA connection is being established. Signed-off-by: Lijun Ou Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_main.c | 20 1 file changed, 20 insertions(+) diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c index f64f0dd..39e69c3 100644 --- a/drivers/infiniband/hw/hns/hns_roce_main.c +++ b/drivers/infiniband/hw/hns/hns_roce_main.c @@ -372,6 +372,25 @@ static int hns_roce_query_device(struct ib_device *ib_dev, return 0; } +static struct net_device *hns_roce_get_netdev(struct ib_device *ib_dev, + u8 port_num) +{ + struct hns_roce_dev *hr_dev = to_hr_dev(ib_dev); + struct net_device *ndev; + + if (port_num < 1 || port_num > hr_dev->caps.num_ports) + return NULL; + + rcu_read_lock(); + + ndev = hr_dev->iboe.netdevs[port_num - 1]; + if (ndev) + dev_hold(ndev); + + rcu_read_unlock(); + return ndev; +} + static int hns_roce_query_port(struct ib_device *ib_dev, u8 port_num, struct ib_port_attr *props) { @@ -618,6 +637,7 @@ static int hns_roce_register_device(struct hns_roce_dev *hr_dev) ib_dev->query_port = hns_roce_query_port; ib_dev->modify_port = hns_roce_modify_port; ib_dev->get_link_layer = hns_roce_get_link_layer; + ib_dev->get_netdev = hns_roce_get_netdev; ib_dev->query_gid = hns_roce_query_gid; ib_dev->query_pkey = hns_roce_query_pkey; ib_dev->alloc_ucontext = hns_roce_alloc_ucontext; -- 1.7.9.5
[PATCH for-next 07/10] IB/hns: Change the logic for allocating uar registers
From: Lijun Ou This patch mainly modifies the logic for allocating uar registers. In HiP06 SoC, HW has 8 group of uar registers for kernel and user space application. The uar index is assigned as follows: 0 -- for kernel 1~7 -- for user space application Signed-off-by: Lijun Ou Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_pd.c |4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_pd.c b/drivers/infiniband/hw/hns/hns_roce_pd.c index 16271b5..4109f74 100644 --- a/drivers/infiniband/hw/hns/hns_roce_pd.c +++ b/drivers/infiniband/hw/hns/hns_roce_pd.c @@ -117,7 +117,9 @@ int hns_roce_uar_alloc(struct hns_roce_dev *hr_dev, struct hns_roce_uar *uar) if (ret == -1) return -ENOMEM; - uar->index = (uar->index - 1) % hr_dev->caps.phy_num_uars + 1; + if (uar->index > 0) + uar->index = (uar->index - 1) % +(hr_dev->caps.phy_num_uars - 1) + 1; res = platform_get_resource(hr_dev->pdev, IORESOURCE_MEM, 0); uar->pfn = ((res->start) >> PAGE_SHIFT) + uar->index; -- 1.7.9.5
[PATCH for-next 02/10] IB/hns: Register add_gid and del_gid for GID Table management
From: Lijun Ou This patch adds support of add_gid() and del_gid() function in the HNS RoCE driver for manipulation of the GID table associated with port. This shall be used be used by CM when connection is established. Signed-off-by: Lijun Ou Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_main.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c index 39e69c3..4e93120 100644 --- a/drivers/infiniband/hw/hns/hns_roce_main.c +++ b/drivers/infiniband/hw/hns/hns_roce_main.c @@ -158,6 +158,19 @@ static void hns_roce_update_gids(struct hns_roce_dev *hr_dev, int port) ib_dispatch_event(&event); } +static int hns_roce_add_gid(struct ib_device *device, u8 port_num, + unsigned int index, const union ib_gid *gid, + const struct ib_gid_attr *attr, void **context) +{ + return 0; +} + +static int hns_roce_del_gid(struct ib_device *device, u8 port_num, + unsigned int index, void **context) +{ + return 0; +} + static int handle_en_event(struct hns_roce_dev *hr_dev, u8 port, unsigned long event) { @@ -639,6 +652,8 @@ static int hns_roce_register_device(struct hns_roce_dev *hr_dev) ib_dev->get_link_layer = hns_roce_get_link_layer; ib_dev->get_netdev = hns_roce_get_netdev; ib_dev->query_gid = hns_roce_query_gid; + ib_dev->add_gid = hns_roce_add_gid; + ib_dev->del_gid = hns_roce_del_gid; ib_dev->query_pkey = hns_roce_query_pkey; ib_dev->alloc_ucontext = hns_roce_alloc_ucontext; ib_dev->dealloc_ucontext= hns_roce_dealloc_ucontext; -- 1.7.9.5
[PATCH for-next 00/10] Add CM(Connection Manager) Support to HNS RoCe Driver
This patch-set adds the CM(Connection Manager) support to the HNS RoCE driver. Changes done are primarily to add support of APIs in IB device and some fixes over the base driver to support RDMA Connection Manager. This patch-set also updates the Device binding document as new parameter node-guid was added to the DT. All of the patches have been authored by Oulijun and reviewed by Huwei. Lijun Ou (10): IB/hns: Register HNS RoCE Driver get_netdev() with IB Core IB/hns: Register add_gid and del_gid for GID Table management IB/hns: Add & initialize "node_guid" parameter for RDMA CM IB/hns: Fix the value of device_cap_flags IB/hns: Fix two possible bugs for rdma cm IB/hns: Add phy_port for computing GSI/QPN IB/hns: Change the logic for allocating uar registers IB/hns: Fix the bug of rdma cm connecting on user mode IB/hns: Fix two bugs for rdma cm connecting IB/hns: Add node_guid definition to the bindings document .../bindings/infiniband/hisilicon-hns-roce.txt |2 + drivers/infiniband/hw/hns/hns_roce_device.h|4 +- drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 80 drivers/infiniband/hw/hns/hns_roce_main.c | 45 ++- drivers/infiniband/hw/hns/hns_roce_pd.c|4 +- drivers/infiniband/hw/hns/hns_roce_qp.c| 13 ++-- 6 files changed, 89 insertions(+), 59 deletions(-) -- 1.7.9.5
[PATCH for-next 04/10] IB/hns: Fix the value of device_cap_flags
From: Lijun Ou In the latest IB core version, it has some known issues with memory registration using the local_dma_lkey. Thus RoCE don't expose support for it, and remove device->local_dma_lkey which is introduced to working systems. Signed-off-by: Lijun Ou Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_main.c |3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c index ec27f0c..b54074d 100644 --- a/drivers/infiniband/hw/hns/hns_roce_main.c +++ b/drivers/infiniband/hw/hns/hns_roce_main.c @@ -368,8 +368,7 @@ static int hns_roce_query_device(struct ib_device *ib_dev, props->max_qp = hr_dev->caps.num_qps; props->max_qp_wr = hr_dev->caps.max_wqes; props->device_cap_flags = IB_DEVICE_PORT_ACTIVE_EVENT | - IB_DEVICE_RC_RNR_NAK_GEN | - IB_DEVICE_LOCAL_DMA_LKEY; + IB_DEVICE_RC_RNR_NAK_GEN; props->max_sge = hr_dev->caps.max_sq_sg; props->max_sge_rd = 1; props->max_cq = hr_dev->caps.num_cqs; -- 1.7.9.5
[PATCH for-next 03/10] IB/hns: Add & initialize "node_guid" parameter for RDMA CM
From: Lijun Ou According to the Infiniband spec, NodeGUID uniquely identifies a node. This must be initialized to some unique value. This patch adds the support to the HNS RoCE driver to fetch the NodeGUID value from DT or ACPI and then use this value to initialize the node_guid parameter of IB device. This value shall be used by RDMA CM. Signed-off-by: Lijun Ou Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_device.h |1 + drivers/infiniband/hw/hns/hns_roce_main.c |7 +++ 2 files changed, 8 insertions(+) diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index ea73580..e943b98 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -74,6 +74,7 @@ #define MR_TYPE_DMA0x03 #define PKEY_ID0x +#define GUID_LEN 8 #define NODE_DESC_SIZE 64 #define SERV_TYPE_RC 0 diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c index 4e93120..ec27f0c 100644 --- a/drivers/infiniband/hw/hns/hns_roce_main.c +++ b/drivers/infiniband/hw/hns/hns_roce_main.c @@ -812,6 +812,13 @@ static int hns_roce_get_cfg(struct hns_roce_dev *hr_dev) if (IS_ERR(hr_dev->reg_base)) return PTR_ERR(hr_dev->reg_base); + /* read the node_guid of IB device from the DT or ACPI */ + ret = device_property_read_u8_array(dev, "node-guid", + (u8 *)&hr_dev->ib_dev.node_guid, + GUID_LEN); + if (ret) + dev_err(dev, "couldn't get node_guid from DT or ACPI!\n"); + /* get the RoCE associated ethernet ports or netdevices */ for (i = 0; i < HNS_ROCE_MAX_PORTS; i++) { if (dev_of_node(dev)) { -- 1.7.9.5
[PATCH for-next 05/10] IB/hns: Fix two possible bugs for rdma cm
From: Lijun Ou Fix the length of wqe that maybe lead to an error and write the end bytes of QP1C into the register. Signed-off-by: Lijun Ou Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c index 399f5de..aaea95c 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -205,8 +205,7 @@ int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, (wr->send_flags & IB_SEND_FENCE ? (cpu_to_le32(HNS_ROCE_WQE_FENCE)) : 0); - wqe = (struct hns_roce_wqe_ctrl_seg *)wqe + - sizeof(struct hns_roce_wqe_ctrl_seg); + wqe += sizeof(struct hns_roce_wqe_ctrl_seg); switch (wr->opcode) { case IB_WR_RDMA_READ: @@ -235,8 +234,7 @@ int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, break; } ctrl->flag |= cpu_to_le32(ps_opcode); - wqe = (struct hns_roce_wqe_raddr_seg *)wqe + - sizeof(struct hns_roce_wqe_raddr_seg); + wqe += sizeof(struct hns_roce_wqe_raddr_seg); dseg = wqe; if (wr->send_flags & IB_SEND_INLINE && wr->num_sge) { @@ -253,8 +251,7 @@ int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, memcpy(wqe, ((void *) (uintptr_t) wr->sg_list[i].addr), wr->sg_list[i].length); - wqe = (struct hns_roce_wqe_raddr_seg *) - wqe + wr->sg_list[i].length; + wqe += wr->sg_list[i].length; } ctrl->flag |= HNS_ROCE_WQE_INLINE; } else { @@ -1795,6 +1792,7 @@ static int hns_roce_v1_m_sqp(struct ib_qp *ibqp, const struct ib_qp_attr *attr, writel(context->qp1c_bytes_28, addr + 6); writel(context->qp1c_bytes_32, addr + 7); writel(context->cur_sq_wqe_ba_l, addr + 8); + writel(context->qp1c_bytes_40, addr + 9); } /* Modify QP1C status */ -- 1.7.9.5
[PATCH for-next 09/10] IB/hns: Fix two bugs for rdma cm connecting
From: Lijun Ou This patch mainly modify the value of HNS_ROCE_SL_SHIFT and delete the lines for assigning for the field of local_enable_e2e_credit in QP1C. Signed-off-by: Lijun Ou Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_device.h |2 +- drivers/infiniband/hw/hns/hns_roce_hw_v1.c |3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index 833742b..066bb3e 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -62,7 +62,7 @@ #define HNS_ROCE_AEQE_OF_VEC_NUM 1 /* 4G/4K = 1M */ -#define HNS_ROCE_SL_SHIFT 29 +#define HNS_ROCE_SL_SHIFT 28 #define HNS_ROCE_TCLASS_SHIFT 20 #define HNS_ROCE_FLOW_LABLE_MASK 0xf diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c index 206957b..3feac8a 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -1734,9 +1734,6 @@ static int hns_roce_v1_m_sqp(struct ib_qp *ibqp, const struct ib_qp_attr *attr, roce_set_bit(context->qp1c_bytes_16, QP1C_BYTES_16_SIGNALING_TYPE_S, hr_qp->sq_signal_bits); - roce_set_bit(context->qp1c_bytes_16, -QP1C_BYTES_16_LOCAL_ENABLE_E2E_CREDIT_S, -hr_qp->sq_signal_bits); roce_set_bit(context->qp1c_bytes_16, QP1C_BYTES_16_RQ_BA_FLG_S, 1); roce_set_bit(context->qp1c_bytes_16, QP1C_BYTES_16_SQ_BA_FLG_S, -- 1.7.9.5
[PATCH for-next 06/10] IB/hns: Add phy_port for computing GSI/QPN
From: Lijun Ou This patch mainly adds phy_port to HNS RoCE QP. This shall be used in calculating the GSI QPN for the port. Initally when RDMA is being established, all IB ports share a QPN which later needs to be re-assigned to a particular GSI/QPN and which is per-port. This also fixes a bug in base driver where iboe port was being used instead of phy_port at some places. This values might not be same always. Signed-off-by: Lijun Ou Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- drivers/infiniband/hw/hns/hns_roce_device.h |1 + drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 30 ++- drivers/infiniband/hw/hns/hns_roce_qp.c | 13 ++-- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index e943b98..833742b 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -409,6 +409,7 @@ struct hns_roce_qp { u32 buff_size; struct mutexmutex; u8 port; + u8 phy_port; u8 sl; u8 resp_depth; u8 state; diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c index aaea95c..581e542 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -162,7 +162,7 @@ int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, roce_set_field(ud_sq_wqe->u32_36, UD_SEND_WQE_U32_36_SGID_INDEX_M, UD_SEND_WQE_U32_36_SGID_INDEX_S, - hns_get_gid_index(hr_dev, qp->port, + hns_get_gid_index(hr_dev, qp->phy_port, ah->av.gid_index)); roce_set_field(ud_sq_wqe->u32_40, @@ -282,7 +282,7 @@ out: SQ_DOORBELL_U32_4_SQ_HEAD_S, (qp->sq.head & ((qp->sq.wqe_cnt << 1) - 1))); roce_set_field(sq_db.u32_4, SQ_DOORBELL_U32_4_PORT_M, - SQ_DOORBELL_U32_4_PORT_S, qp->port); + SQ_DOORBELL_U32_4_PORT_S, qp->phy_port); roce_set_field(sq_db.u32_8, SQ_DOORBELL_U32_8_QPN_M, SQ_DOORBELL_U32_8_QPN_S, qp->doorbell_qpn); roce_set_bit(sq_db.u32_8, SQ_DOORBELL_HW_SYNC_S, 1); @@ -362,14 +362,14 @@ out: /* SW update GSI rq header */ reg_val = roce_read(to_hr_dev(ibqp->device), ROCEE_QP1C_CFG3_0_REG + - QP1C_CFGN_OFFSET * hr_qp->port); + QP1C_CFGN_OFFSET * hr_qp->phy_port); roce_set_field(reg_val, ROCEE_QP1C_CFG3_0_ROCEE_QP1C_RQ_HEAD_M, ROCEE_QP1C_CFG3_0_ROCEE_QP1C_RQ_HEAD_S, hr_qp->rq.head); roce_write(to_hr_dev(ibqp->device), ROCEE_QP1C_CFG3_0_REG + - QP1C_CFGN_OFFSET * hr_qp->port, reg_val); + QP1C_CFGN_OFFSET * hr_qp->phy_port, reg_val); } else { rq_db.u32_4 = 0; rq_db.u32_8 = 0; @@ -1730,7 +1730,7 @@ static int hns_roce_v1_m_sqp(struct ib_qp *ibqp, const struct ib_qp_attr *attr, roce_set_field(context->qp1c_bytes_16, QP1C_BYTES_16_RQ_HEAD_M, QP1C_BYTES_16_RQ_HEAD_S, hr_qp->rq.head); roce_set_field(context->qp1c_bytes_16, QP1C_BYTES_16_PORT_NUM_M, - QP1C_BYTES_16_PORT_NUM_S, hr_qp->port); + QP1C_BYTES_16_PORT_NUM_S, hr_qp->phy_port); roce_set_bit(context->qp1c_bytes_16, QP1C_BYTES_16_SIGNALING_TYPE_S, hr_qp->sq_signal_bits); @@ -1781,7 +1781,7 @@ static int hns_roce_v1_m_sqp(struct ib_qp *ibqp, const struct ib_qp_attr *attr, /* Copy context to QP1C register */ addr = (u32 *)(hr_dev->reg_base + ROCEE_QP1C_CFG0_0_REG + - hr_qp->port * sizeof(*context)); + hr_qp->phy_port * sizeof(*context)); writel(context->qp1c_bytes_4, addr); writel(context->sq_rq_bt_l, addr + 1); @@ -1797,11 +1797,11 @@ static int hns_roce_v1_m_sqp(struct ib_qp *ibq
[PATCH for-next 10/10] IB/hns: Add node_guid definition to the bindings document
From: Lijun Ou This patch adds node_guid definition in bindings document. The value of node_guid will be used during RDMA connection. Signed-off-by: Lijun Ou Reviewed-by: Wei Hu Signed-off-by: Salil Mehta --- .../bindings/infiniband/hisilicon-hns-roce.txt |2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/infiniband/hisilicon-hns-roce.txt b/Documentation/devicetree/bindings/infiniband/hisilicon-hns-roce.txt index f97993b..d3b273e 100644 --- a/Documentation/devicetree/bindings/infiniband/hisilicon-hns-roce.txt +++ b/Documentation/devicetree/bindings/infiniband/hisilicon-hns-roce.txt @@ -14,6 +14,7 @@ length of memory mapped region. representing a ethernet device. - dsaf-handle: phandle, specifies a reference to a node representing a dsaf device. +- node_guid: a number that uniquely identifies a device or component - #address-cells: must be 2 - #size-cells: must be 2 Optional properties: @@ -32,6 +33,7 @@ Example: dma-coherent; eth-handle = <ð2 ð3 ð4 ð5 ð6 ð7>; dsaf-handle = <&soc0_dsa>; + node-guid = [00 9A CD 00 00 01 02 03]; #address-cells = <2>; #size-cells = <2>; interrupt-parent = <&mbigen_dsa>; -- 1.7.9.5
[PATCH for-next 0/2] {IB,net}/hns: Add support of ACPI to the Hisilicon RoCE Driver
This patch is meant to add support of ACPI to the Hisilicon RoCE driver. Following changes have been made in the driver(s): Patch 1/2: HNS Ethernet Driver: changes to support ACPI have been done in the RoCE reset function part of the HNS ethernet driver. Earlier it only supported DT/syscon. Patch 2/2. HNS RoCE driver: changes done in RoCE driver are meant to detect the type and then either use DT specific or ACPI spcific functions. Where ever possible, this patch tries to make use of "Unified Device Property Interface" APIs to support both DT and ACPI through single interface. NOTE 1: ACPI changes done in both of the drivers depend upon the ACPI Table (DSDT and IORT tables) changes part of UEFI/BIOS. These changes are NOT part of this patch-set. NOTE 2: Reset function in Patch 1/2 depends upon the reset function added in ACPI tables(basically DSDT table) part of the UEFI/BIOS. Again, this change is NOT reflected in this patch-set. Salil Mehta (2): net: hns: Add support of ACPI to HNS driver RoCE Reset function IB/hns: Add support of ACPI to the Hisilicon RoCE driver drivers/infiniband/hw/hns/hns_roce_device.h|2 +- drivers/infiniband/hw/hns/hns_roce_eq.c|2 +- drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 37 -- drivers/infiniband/hw/hns/hns_roce_hw_v1.h |2 +- drivers/infiniband/hw/hns/hns_roce_main.c | 127 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c | 17 +-- drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c | 47 ++-- drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h |9 +- drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c | 53 +++- drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.h |3 +- drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h |4 +- 11 files changed, 228 insertions(+), 75 deletions(-) -- 1.7.9.5
[PATCH for-next 2/2] IB/hns: Add support of ACPI to the Hisilicon RoCE driver
This patch is meant to add support of ACPI to the Hisilicon RoCE driver. Changes done are primarily meant to detect the type and then either use DT specific or ACPI spcific functions. Where ever possible, this patch tries to make use of Unified Device Property Interface APIs to support both DT and ACPI through single interface. This patch depends upon HNS ethernet driver to Reset RoCE. This function within HNS ethernet driver has also been enhanced to support ACPI and is part of other accompanying patch with this patch-set. NOTE: The changes in this patch are done over below branch, https://github.com/dledford/linux/tree/hns-roce Signed-off-by: Salil Mehta --- Change Log PATCH V1: Initial version to support ACPI in HNS RoCE driver. --- drivers/infiniband/hw/hns/hns_roce_device.h |2 +- drivers/infiniband/hw/hns/hns_roce_eq.c |2 +- drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 37 ++-- drivers/infiniband/hw/hns/hns_roce_hw_v1.h |2 +- drivers/infiniband/hw/hns/hns_roce_main.c | 127 ++- 5 files changed, 136 insertions(+), 34 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index 00f01be..ea73580 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -531,7 +531,7 @@ struct hns_roce_dev { struct ib_deviceib_dev; struct platform_device *pdev; struct hns_roce_uar priv_uar; - const char *irq_names; + const char *irq_names[HNS_ROCE_MAX_IRQ_NUM]; spinlock_t sm_lock; spinlock_t cq_db_lock; spinlock_t bt_cmd_lock; diff --git a/drivers/infiniband/hw/hns/hns_roce_eq.c b/drivers/infiniband/hw/hns/hns_roce_eq.c index 5febbb4..98af7fe 100644 --- a/drivers/infiniband/hw/hns/hns_roce_eq.c +++ b/drivers/infiniband/hw/hns/hns_roce_eq.c @@ -713,7 +713,7 @@ int hns_roce_init_eq_table(struct hns_roce_dev *hr_dev) for (j = 0; j < eq_num; j++) { ret = request_irq(eq_table->eq[j].irq, hns_roce_msi_x_interrupt, - 0, hr_dev->irq_names, eq_table->eq + j); + 0, hr_dev->irq_names[j], eq_table->eq + j); if (ret) { dev_err(dev, "request irq error!\n"); goto err_request_irq_fail; diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c index b52f3ba..399f5de 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -31,6 +31,7 @@ */ #include +#include #include #include "hns_roce_common.h" #include "hns_roce_device.h" @@ -794,29 +795,47 @@ static void hns_roce_port_enable(struct hns_roce_dev *hr_dev, int enable_flag) * @enable: true -- drop reset, false -- reset * return 0 - success , negative --fail */ -int hns_roce_v1_reset(struct hns_roce_dev *hr_dev, bool enable) +int hns_roce_v1_reset(struct hns_roce_dev *hr_dev, bool dereset) { struct device_node *dsaf_node; struct device *dev = &hr_dev->pdev->dev; struct device_node *np = dev->of_node; + struct fwnode_handle *fwnode; int ret; - dsaf_node = of_parse_phandle(np, "dsaf-handle", 0); - if (!dsaf_node) { - dev_err(dev, "Unable to get dsaf node by dsaf-handle!\n"); - return -EINVAL; + /* check if this is DT/ACPI case */ + if (dev_of_node(dev)) { + dsaf_node = of_parse_phandle(np, "dsaf-handle", 0); + if (!dsaf_node) { + dev_err(dev, "could not find dsaf-handle\n"); + return -EINVAL; + } + fwnode = &dsaf_node->fwnode; + } else if (is_acpi_device_node(dev->fwnode)) { + struct acpi_reference_args args; + + ret = acpi_node_get_property_reference(dev->fwnode, + "dsaf-handle", 0, &args); + if (ret) { + dev_err(dev, "could not find dsaf-handle\n"); + return ret; + } + fwnode = acpi_fwnode_handle(args.adev); + } else { + dev_err(dev, "cannot read data from DT or ACPI\n"); + return -ENXIO; } - ret = hns_dsaf_roce_reset(&dsaf_node->fwnode, false); + ret = hns_dsaf_roce_reset(fwnode, false); if (ret) return ret; - if (enable) { + if (dereset) { msleep(SLEEP_TIME_INTERVAL); - return hns_dsaf_roce_reset(&dsaf_node->fwnode, true); + ret = hns_dsaf_roce_reset(f
[PATCH for-next 1/2] net: hns: Add support of ACPI to HNS driver RoCE Reset function
In the Hip06 SoC, the RoCE Engine is part of the Hisilicon Network Subsystem and is dependent upon DSAF module. Therefore, certain functions like RESET are exposed through the common registers of HNS DSAF module which are memory-mapped by the HNS driver and currently can only be accessed through DT/syscon interface. This patch adds the support of ACPI to the existing RoCE reset function in the HNS driver(please refer NOTE 2). Hisilicon RoCE driver (please refer NOTE 1) shall call this reset function during probe time to reset the RoCE Engine. The HNS Reset function indirectly ends up in calling the _DSM() function part of the DSDT ACPI Table. Actual reset functionality for ACPI is implemented within the ACPI DSDT Table which also has been enhanced to support this change. Support of ACPI in the HNS RoCE driver shall be pushed through a different accompanying below patch: "IB/hns: Add support of ACPI to the Hisilicon RoCE Driver" NOTE 1: HNS RoCE driver has already been accepted by its maintainer Doug Ledford. Please refer below link: https://www.spinics.net/lists/linux-rdma/msg38850.html NOTE 2: RoCE reset function patch has been accepted and now is part of the net-next: https://www.mail-archive.com/netdev@vger.kernel.org/msg123867.html Signed-off-by: Salil Mehta Reviewed-by: Yisen Zhuang --- Change Log PATCH V1: Initial version to support ACPI in RoCE Reset functionality of the HNS driver. --- drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c | 17 +-- drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c | 47 - drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h |9 ++-- drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c | 53 ++-- drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.h |3 +- drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h |4 +- 6 files changed, 92 insertions(+), 41 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c index a834774..a68eef0 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c @@ -644,21 +644,6 @@ hns_mac_phy_parse_addr(struct device *dev, struct fwnode_handle *fwnode) return addr; } -static int hns_mac_phydev_match(struct device *dev, void *fwnode) -{ - return dev->fwnode == fwnode; -} - -static struct -platform_device *hns_mac_find_platform_device(struct fwnode_handle *fwnode) -{ - struct device *dev; - - dev = bus_find_device(&platform_bus_type, NULL, - fwnode, hns_mac_phydev_match); - return dev ? to_platform_device(dev) : NULL; -} - static int hns_mac_register_phydev(struct mii_bus *mdio, struct hns_mac_cb *mac_cb, u32 addr) @@ -724,7 +709,7 @@ static void hns_mac_register_phy(struct hns_mac_cb *mac_cb) return; /* dev address in adev */ - pdev = hns_mac_find_platform_device(acpi_fwnode_handle(args.adev)); + pdev = hns_dsaf_find_platform_device(acpi_fwnode_handle(args.adev)); mii_bus = platform_get_drvdata(pdev); rc = hns_mac_register_phydev(mii_bus, mac_cb, addr); if (!rc) diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c index 05bd19f..9283bc6 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c @@ -2788,7 +2788,7 @@ module_platform_driver(g_dsaf_driver); * @enable: false - request reset , true - drop reset * retuen 0 - success , negative -fail */ -int hns_dsaf_roce_reset(struct fwnode_handle *dsaf_fwnode, bool enable) +int hns_dsaf_roce_reset(struct fwnode_handle *dsaf_fwnode, bool dereset) { struct dsaf_device *dsaf_dev; struct platform_device *pdev; @@ -2817,24 +2817,44 @@ int hns_dsaf_roce_reset(struct fwnode_handle *dsaf_fwnode, bool enable) {DSAF_ROCE_SL_1, DSAF_ROCE_SL_1, DSAF_ROCE_SL_3}, }; - if (!is_of_node(dsaf_fwnode)) { - pr_err("hisi_dsaf: Only support DT node!\n"); + /* find the platform device corresponding to fwnode */ + if (is_of_node(dsaf_fwnode)) { + pdev = of_find_device_by_node(to_of_node(dsaf_fwnode)); + } else if (is_acpi_device_node(dsaf_fwnode)) { + pdev = hns_dsaf_find_platform_device(dsaf_fwnode); + } else { + pr_err("fwnode is neither OF or ACPI type\n"); return -EINVAL; } - pdev = of_find_device_by_node(to_of_node(dsaf_fwnode)); + + /* check if we were a success in fetching pdev */ + if (!pdev) { + pr_err("couldn't find platform device for node\n"); + return -ENODEV; + } + + /* retrieve the dsaf_device from the driver data */ dsaf_dev = dev_get_drvdata(&pdev->d
RE: [PATCH for-next 2/2] IB/hns: Add support of ACPI to the Hisilicon RoCE driver
> -Original Message- > From: Leon Romanovsky [mailto:l...@kernel.org] > Sent: Wednesday, August 24, 2016 2:59 PM > To: Salil Mehta > Cc: dledf...@redhat.com; da...@davemloft.net; Huwei (Xavier); oulijun; > Zhuangyuzeng (Yisen); mehta.salil@gmail.com; linux- > r...@vger.kernel.org; net...@vger.kernel.org; linux- > ker...@vger.kernel.org; Linuxarm > Subject: Re: [PATCH for-next 2/2] IB/hns: Add support of ACPI to the > Hisilicon RoCE driver > > On Wed, Aug 24, 2016 at 04:44:50AM +0800, Salil Mehta wrote: > > This patch is meant to add support of ACPI to the Hisilicon RoCE > > driver. > > > > Changes done are primarily meant to detect the type and then either > > use DT specific or ACPI spcific functions. Where ever possible, > > this patch tries to make use of Unified Device Property Interface > > APIs to support both DT and ACPI through single interface. > > > > This patch depends upon HNS ethernet driver to Reset RoCE. This > > function within HNS ethernet driver has also been enhanced to > > support ACPI and is part of other accompanying patch with this > > patch-set. > > > > NOTE: The changes in this patch are done over below branch, > > https://github.com/dledford/linux/tree/hns-roce > > > > Signed-off-by: Salil Mehta > > --- > > Change Log > > > > PATCH V1: Initial version to support ACPI in HNS RoCE driver. > > --- > > drivers/infiniband/hw/hns/hns_roce_device.h |2 +- > > drivers/infiniband/hw/hns/hns_roce_eq.c |2 +- > > drivers/infiniband/hw/hns/hns_roce_hw_v1.c | 37 ++-- > > drivers/infiniband/hw/hns/hns_roce_hw_v1.h |2 +- > > drivers/infiniband/hw/hns/hns_roce_main.c | 127 > ++- > > 5 files changed, 136 insertions(+), 34 deletions(-) > > > > diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h > b/drivers/infiniband/hw/hns/hns_roce_device.h > > index 00f01be..ea73580 100644 > > --- a/drivers/infiniband/hw/hns/hns_roce_device.h > > +++ b/drivers/infiniband/hw/hns/hns_roce_device.h > > @@ -531,7 +531,7 @@ struct hns_roce_dev { > > struct ib_deviceib_dev; > > struct platform_device *pdev; > > struct hns_roce_uar priv_uar; > > - const char *irq_names; > > + const char *irq_names[HNS_ROCE_MAX_IRQ_NUM]; > > spinlock_t sm_lock; > > spinlock_t cq_db_lock; > > spinlock_t bt_cmd_lock; > > diff --git a/drivers/infiniband/hw/hns/hns_roce_eq.c > b/drivers/infiniband/hw/hns/hns_roce_eq.c > > index 5febbb4..98af7fe 100644 > > --- a/drivers/infiniband/hw/hns/hns_roce_eq.c > > +++ b/drivers/infiniband/hw/hns/hns_roce_eq.c > > @@ -713,7 +713,7 @@ int hns_roce_init_eq_table(struct hns_roce_dev > *hr_dev) > > > > for (j = 0; j < eq_num; j++) { > > ret = request_irq(eq_table->eq[j].irq, > hns_roce_msi_x_interrupt, > > - 0, hr_dev->irq_names, eq_table->eq + j); > > + 0, hr_dev->irq_names[j], eq_table->eq + j); > > if (ret) { > > dev_err(dev, "request irq error!\n"); > > goto err_request_irq_fail; > > diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c > b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c > > index b52f3ba..399f5de 100644 > > --- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c > > +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c > > @@ -31,6 +31,7 @@ > > */ > > > > #include > > +#include > > #include > > #include "hns_roce_common.h" > > #include "hns_roce_device.h" > > @@ -794,29 +795,47 @@ static void hns_roce_port_enable(struct > hns_roce_dev *hr_dev, int enable_flag) > > * @enable: true -- drop reset, false -- reset > > * return 0 - success , negative --fail > > */ > > -int hns_roce_v1_reset(struct hns_roce_dev *hr_dev, bool enable) > > +int hns_roce_v1_reset(struct hns_roce_dev *hr_dev, bool dereset) > > { > > struct device_node *dsaf_node; > > struct device *dev = &hr_dev->pdev->dev; > > struct device_node *np = dev->of_node; > > + struct fwnode_handle *fwnode; > > int ret; > > > > - dsaf_node = of_parse_phandle(np, "dsaf-handle", 0); > > - if (!dsaf_node) { > > - dev_err(dev, "Unable to get dsaf node by dsaf-handle!\n"); > > - return -EINVAL; > > + /* check if this is DT/ACPI case */ > > +
RE: [PATCH for-next 0/2] {IB,net}/hns: Add support of ACPI to the Hisilicon RoCE Driver
> -Original Message- > From: David Miller [mailto:da...@davemloft.net] > Sent: Thursday, August 25, 2016 5:54 AM > To: Salil Mehta > Cc: dledf...@redhat.com; Huwei (Xavier); oulijun; Zhuangyuzeng (Yisen); > mehta.salil@gmail.com; linux-r...@vger.kernel.org; > net...@vger.kernel.org; linux-kernel@vger.kernel.org; Linuxarm > Subject: Re: [PATCH for-next 0/2] {IB,net}/hns: Add support of ACPI to > the Hisilicon RoCE Driver > > From: Salil Mehta > Date: Wed, 24 Aug 2016 04:44:48 +0800 > > > This patch is meant to add support of ACPI to the Hisilicon RoCE > driver. > > Following changes have been made in the driver(s): > > > > Patch 1/2: HNS Ethernet Driver: changes to support ACPI have been > done in > >the RoCE reset function part of the HNS ethernet driver. Earlier > it only > >supported DT/syscon. > > > > Patch 2/2. HNS RoCE driver: changes done in RoCE driver are meant to > detect > >the type and then either use DT specific or ACPI spcific > functions. Where > >ever possible, this patch tries to make use of "Unified Device > Property > >Interface" APIs to support both DT and ACPI through single > interface. > > > > NOTE 1: ACPI changes done in both of the drivers depend upon the ACPI > Table > > (DSDT and IORT tables) changes part of UEFI/BIOS. These changes > are NOT > > part of this patch-set. > > NOTE 2: Reset function in Patch 1/2 depends upon the reset function > added in > > ACPI tables(basically DSDT table) part of the UEFI/BIOS. Again, > this > > change is NOT reflected in this patch-set. > > I can't apply this series to my tree because the hns infiniband driver > doesn't exist in it. Hi David, I understand your point. This patch-set was primarily sent for Doug Ledford and is based on his internal repository (which has been rebased on the net-next). Though we were hoping, if by any chance, we can expedite the acceptance of the below patch part of patch-set in the net-next. This might help Doug Ledford as well later on when he pushes the already accepted RoCE driver and ACPI patches to linux-next, "[PATCH for-next 1/2] net: hns: Add support of ACPI to HNS driver RoCE Reset function" Below HNS RoCE reset function patch has already been accepted and is part of your net-next, https://patchwork.kernel.org/patch/9287497/ Above ACPI support of RoCE Reset patch cleanly applies over the already accepted patch in the link. It is not dependent on other accompanying RoCE driver ACPI changes related patch or even the presence of the Infiniband/RoCE Driver in the net-next repository. Could you please suggest anything here? Thanks Salil
RE: [PATCH for-next 0/2] {IB,net}/hns: Add support of ACPI to the Hisilicon RoCE Driver
> -Original Message- > From: Doug Ledford [mailto:dledf...@redhat.com] > Sent: Thursday, August 25, 2016 12:57 PM > To: David Miller; Salil Mehta > Cc: Huwei (Xavier); oulijun; Zhuangyuzeng (Yisen); > mehta.salil@gmail.com; linux-r...@vger.kernel.org; > net...@vger.kernel.org; linux-kernel@vger.kernel.org; Linuxarm > Subject: Re: [PATCH for-next 0/2] {IB,net}/hns: Add support of ACPI to > the Hisilicon RoCE Driver > > On 8/25/2016 12:53 AM, David Miller wrote: > > From: Salil Mehta > > Date: Wed, 24 Aug 2016 04:44:48 +0800 > > > >> This patch is meant to add support of ACPI to the Hisilicon RoCE > driver. > >> Following changes have been made in the driver(s): > >> > >> Patch 1/2: HNS Ethernet Driver: changes to support ACPI have been > done in > >>the RoCE reset function part of the HNS ethernet driver. Earlier > it only > >>supported DT/syscon. > >> > >> Patch 2/2. HNS RoCE driver: changes done in RoCE driver are meant to > detect > >>the type and then either use DT specific or ACPI spcific > functions. Where > >>ever possible, this patch tries to make use of "Unified Device > Property > >>Interface" APIs to support both DT and ACPI through single > interface. > >> > >> NOTE 1: ACPI changes done in both of the drivers depend upon the > ACPI Table > >> (DSDT and IORT tables) changes part of UEFI/BIOS. These changes > are NOT > >> part of this patch-set. > >> NOTE 2: Reset function in Patch 1/2 depends upon the reset function > added in > >> ACPI tables(basically DSDT table) part of the UEFI/BIOS. Again, > this > >> change is NOT reflected in this patch-set. > > > > I can't apply this series to my tree because the hns infiniband > driver > > doesn't exist in it. > > > > No. This probably needs to go through my tree. Although with all of > the requirements, I'm a bit concerned about those being present > elsewhere. > > -- > Doug Ledford > GPG Key ID: 0E572FDD Hello Doug, Thanks for your reply. I have just replied to David email as well and did not realize your response was already on the way. Sorry for this! I would just like to request, if by any chance, we can expedite the acceptance of the below patch (part of patch-set) in the net-next. This might help you as well in future when you will actually push the RoCE driver to the linux-next. "[PATCH for-next 1/2] net: hns: Add support of ACPI to HNS driver RoCE Reset function" Below HNS RoCE reset function patch has already been accepted by Dave Miller and is part of net-next, https://patchwork.kernel.org/patch/9287497/ Also, above ACPI support of RoCE Reset patch cleanly applies over the already accepted patch in the link and is not dependent on other accompanying RoCE driver ACPI changes or even the presence of the Infiniband/RoCE Driver in the net-next repository. Could you please suggest if this the something which can be considered? Thanks in anticipation Salil Mehta
RE: [PATCH for-next 0/2] {IB,net}/hns: Add support of ACPI to the Hisilicon RoCE Driver
> -Original Message- > From: Doug Ledford [mailto:dledf...@redhat.com] > Sent: Thursday, August 25, 2016 2:53 PM > To: Salil Mehta; David Miller > Cc: Huwei (Xavier); oulijun; Zhuangyuzeng (Yisen); > mehta.salil@gmail.com; linux-r...@vger.kernel.org; > net...@vger.kernel.org; linux-kernel@vger.kernel.org; Linuxarm > Subject: Re: [PATCH for-next 0/2] {IB,net}/hns: Add support of ACPI to > the Hisilicon RoCE Driver > > On 8/25/2016 8:00 AM, Salil Mehta wrote: > > > > > >> -Original Message- > >> From: David Miller [mailto:da...@davemloft.net] > >> Sent: Thursday, August 25, 2016 5:54 AM > >> To: Salil Mehta > >> Cc: dledf...@redhat.com; Huwei (Xavier); oulijun; Zhuangyuzeng > (Yisen); > >> mehta.salil@gmail.com; linux-r...@vger.kernel.org; > >> net...@vger.kernel.org; linux-kernel@vger.kernel.org; Linuxarm > >> Subject: Re: [PATCH for-next 0/2] {IB,net}/hns: Add support of ACPI > to > >> the Hisilicon RoCE Driver > >> > >> From: Salil Mehta > >> Date: Wed, 24 Aug 2016 04:44:48 +0800 > >> > >>> This patch is meant to add support of ACPI to the Hisilicon RoCE > >> driver. > >>> Following changes have been made in the driver(s): > >>> > >>> Patch 1/2: HNS Ethernet Driver: changes to support ACPI have been > >> done in > >>>the RoCE reset function part of the HNS ethernet driver. Earlier > >> it only > >>>supported DT/syscon. > >>> > >>> Patch 2/2. HNS RoCE driver: changes done in RoCE driver are meant > to > >> detect > >>>the type and then either use DT specific or ACPI spcific > >> functions. Where > >>>ever possible, this patch tries to make use of "Unified Device > >> Property > >>>Interface" APIs to support both DT and ACPI through single > >> interface. > >>> > >>> NOTE 1: ACPI changes done in both of the drivers depend upon the > ACPI > >> Table > >>> (DSDT and IORT tables) changes part of UEFI/BIOS. These > changes > >> are NOT > >>> part of this patch-set. > >>> NOTE 2: Reset function in Patch 1/2 depends upon the reset function > >> added in > >>> ACPI tables(basically DSDT table) part of the UEFI/BIOS. > Again, > >> this > >>> change is NOT reflected in this patch-set. > >> > >> I can't apply this series to my tree because the hns infiniband > driver > >> doesn't exist in it. > > Hi David, > > I understand your point. This patch-set was primarily sent for Doug > Ledford > > and is based on his internal repository (which has been rebased on > the > > net-next). > > > > Though we were hoping, if by any chance, we can expedite the > acceptance of the > > below patch part of patch-set in the net-next. This might help Doug > Ledford as > > well later on when he pushes the already accepted RoCE driver and > ACPI patches > > to linux-next, > > > > "[PATCH for-next 1/2] net: hns: Add support of ACPI to HNS driver > RoCE Reset > > function" > > > > Below HNS RoCE reset function patch has already been accepted and is > part of your > > net-next, > > https://patchwork.kernel.org/patch/9287497/ > > > > Above ACPI support of RoCE Reset patch cleanly applies over the > already accepted > > patch in the link. It is not dependent on other accompanying RoCE > driver ACPI > > changes related patch or even the presence of the Infiniband/RoCE > Driver in the > > net-next repository. > > > > Could you please suggest anything here? > > > > Thanks > > Salil > > > > I can take both. I already pulled net-next to get the initial hns roce > reset patch from Dave, so these will apply cleanly with my tree and > merge cleanly with Dave's due to the common ancestral base. The only > problem is that if you intend to send any other patches that effect > this > code, then they would need to come through me until the 4.9 merge > window > is complete so that we don't have later merge conflicts. Ok sure, I got your point. Yes, there are few patches we need to push in but are related to RoCE CM(Connection Manager) mode and would follow soon. There are no further patches we foresee which are for RoCE Driver but are dependent upon HNS Ethernet driver. But kindly note, there could be some patches in development in HNS Ethernet driver which might sneak in through net-next. These might not be rel
RE: [PATCH for-next 0/2] {IB,net}/hns: Add support of ACPI to the Hisilicon RoCE Driver
> -Original Message- > From: linux-rdma-ow...@vger.kernel.org [mailto:linux-rdma- > ow...@vger.kernel.org] On Behalf Of Doug Ledford > Sent: Thursday, August 25, 2016 3:09 PM > To: Salil Mehta; David Miller > Cc: Huwei (Xavier); oulijun; Zhuangyuzeng (Yisen); > mehta.salil@gmail.com; linux-r...@vger.kernel.org; > net...@vger.kernel.org; linux-kernel@vger.kernel.org; Linuxarm > Subject: Re: [PATCH for-next 0/2] {IB,net}/hns: Add support of ACPI to > the Hisilicon RoCE Driver > > On 8/25/2016 8:08 AM, Salil Mehta wrote: > > > > > >> -Original Message- > >> From: Doug Ledford [mailto:dledf...@redhat.com] > >> Sent: Thursday, August 25, 2016 12:57 PM > >> To: David Miller; Salil Mehta > >> Cc: Huwei (Xavier); oulijun; Zhuangyuzeng (Yisen); > >> mehta.salil@gmail.com; linux-r...@vger.kernel.org; > >> net...@vger.kernel.org; linux-kernel@vger.kernel.org; Linuxarm > >> Subject: Re: [PATCH for-next 0/2] {IB,net}/hns: Add support of ACPI > to > >> the Hisilicon RoCE Driver > >> > >> On 8/25/2016 12:53 AM, David Miller wrote: > >>> From: Salil Mehta > >>> Date: Wed, 24 Aug 2016 04:44:48 +0800 > >>> > >>>> This patch is meant to add support of ACPI to the Hisilicon RoCE > >> driver. > >>>> Following changes have been made in the driver(s): > >>>> > >>>> Patch 1/2: HNS Ethernet Driver: changes to support ACPI have been > >> done in > >>>>the RoCE reset function part of the HNS ethernet driver. > Earlier > >> it only > >>>>supported DT/syscon. > >>>> > >>>> Patch 2/2. HNS RoCE driver: changes done in RoCE driver are meant > to > >> detect > >>>>the type and then either use DT specific or ACPI spcific > >> functions. Where > >>>>ever possible, this patch tries to make use of "Unified Device > >> Property > >>>>Interface" APIs to support both DT and ACPI through single > >> interface. > >>>> > >>>> NOTE 1: ACPI changes done in both of the drivers depend upon the > >> ACPI Table > >>>> (DSDT and IORT tables) changes part of UEFI/BIOS. These > changes > >> are NOT > >>>> part of this patch-set. > >>>> NOTE 2: Reset function in Patch 1/2 depends upon the reset > function > >> added in > >>>> ACPI tables(basically DSDT table) part of the UEFI/BIOS. > Again, > >> this > >>>> change is NOT reflected in this patch-set. > >>> > >>> I can't apply this series to my tree because the hns infiniband > >> driver > >>> doesn't exist in it. > >>> > >> > >> No. This probably needs to go through my tree. Although with all > of > >> the requirements, I'm a bit concerned about those being present > >> elsewhere. > >> > >> -- > >> Doug Ledford > >> GPG Key ID: 0E572FDD > > Hello Doug, > > Thanks for your reply. I have just replied to David email as well and > did > > not realize your response was already on the way. Sorry for this! > > > > I would just like to request, if by any chance, we can expedite the > acceptance > > of the below patch (part of patch-set) in the net-next. This might > help you as > > well in future when you will actually push the RoCE driver to the > linux-next. > > > > "[PATCH for-next 1/2] net: hns: Add support of ACPI to HNS driver > RoCE Reset > > function" > > > > Below HNS RoCE reset function patch has already been accepted by Dave > Miller and > > is part of net-next, > > https://patchwork.kernel.org/patch/9287497/ > > > > Also, above ACPI support of RoCE Reset patch cleanly applies over the > already > > accepted patch in the link and is not dependent on other accompanying > RoCE > > driver ACPI changes or even the presence of the Infiniband/RoCE > Driver in the > > net-next repository. > > > > Could you please suggest if this the something which can be > considered? > > I've pulled both of these patches in. I usually merge late in the > merge > window, so it won't be any stretch to wait until the ACPI tree has been > merged before I send Linus my pull request. Thanks David! Hope we can take care of the delta which might get created because of unrelated (not related to RoCE driver from other people) HNS Ethernet changes? The pace & magnitude at which HNS development is going on and at which RoCE Development is going on is different. Best regards Salil > > > -- > Doug Ledford > GPG Key ID: 0E572FDD
RE: [PATCH for-next 0/2] {IB,net}/hns: Add support of ACPI to the Hisilicon RoCE Driver
> -Original Message- > From: Doug Ledford [mailto:dledf...@redhat.com] > Sent: Thursday, August 25, 2016 4:00 PM > To: Salil Mehta; David Miller > Cc: Huwei (Xavier); oulijun; Zhuangyuzeng (Yisen); > mehta.salil@gmail.com; linux-r...@vger.kernel.org; > net...@vger.kernel.org; linux-kernel@vger.kernel.org; Linuxarm > Subject: Re: [PATCH for-next 0/2] {IB,net}/hns: Add support of ACPI to > the Hisilicon RoCE Driver > > On 8/25/2016 10:50 AM, Salil Mehta wrote: > > >> I can take both. I already pulled net-next to get the initial hns > roce > >> reset patch from Dave, so these will apply cleanly with my tree and > >> merge cleanly with Dave's due to the common ancestral base. The > only > >> problem is that if you intend to send any other patches that effect > >> this > >> code, then they would need to come through me until the 4.9 merge > >> window > >> is complete so that we don't have later merge conflicts. > > Ok sure, I got your point. Yes, there are few patches we need to push > in > > but are related to RoCE CM(Connection Manager) mode and would follow > > soon. There are no further patches we foresee which are for RoCE > Driver but are > > dependent upon HNS Ethernet driver. > > Ok. > > > But kindly note, there could be some patches in development in HNS > Ethernet driver > > which might sneak in through net-next. These might not be related to > RoCE Driver but > > might have some common files which might lead to conflict again > further down > > the line when you try to merge ACPI RoCE reset again. This HNS driver > change > > is very difficult for us to control since amount of development going > on in HNS > > is of much higher magnitude than the RoCE as of now. It will be > almost impossible > > for us to convince internally and shift that entire development being > done right > > now on net-next and rebase it to your internal hns-roce branch for a > month of time > > till 4.9. This will affect many features deadlines internally. > > This is what Linus wants to avoid. It's not necessary to shift your > work from one tree to another, what is needed if for your RoCE team and > your net team to plan out what you are going to submit for the next > kernel and provide a complete list of conflicting code patches to both > Dave and myself and allow us to pull those patches into both our trees > so there are no conflicts. See the recent threads on linux-rdma about > the pull requests from Mellanox. This is how it needs to be done. > Neither team needs to slow down, or not do your work, you simply need > to > plan that work out and provide a common base for Dave and I to apply > the > separate patches on top of. I got your point now. Thanks for this clear explanation, Doug. I would discuss this internally and plan the other non-related HNS conflicting patches according to the example procedure you indicated in linux-rdma mail-chain. > > > So, if I understood you correctly, this delta (which could be large), > when next merge > > window open would be taken care by you. And we can expect below to be > part of 4.9 > > 1) RoCE Base driver (*Already Accepted*) > > 2) ACPI changes for RoCE Driver (*if accepted*) > >* ACPI changes for the RoCE Driver > >* ACPI changes for RoCE reset function part of the HNS driver > > Both of these changes are already applied to my tree. However, if you > submit other changes to net-next and it starts generating merge > conflicts, you and the net team are going to get yelled at. Ok thanks. I totally understand that, my current efforts of the discussion are to understand the process correctly and to ensure that conflict do not happen. > If you are > going to have a shared driver, then you *HAVE* to work as a larger team > and plan your changes you submit to the linux kernel. Sure, agreed > > -- > Doug Ledford > GPG Key ID: 0E572FDD
[PATCH net-next 3/3] net: hns3: Fixes the static check warning due to missing unsupp L3 proto check
This patch fixes the static check warning due to missing handling leg of unsupported L3 protocol type in the hns3_get_l4_protocol() function. Fixes: 76ad4f0ee747 ("net: hns3: Add support of HNS3 Ethernet Driver for hip08 SoC") Reported-by: Dan Carpenter Signed-off-by: Salil Mehta --- drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c | 14 ++ 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c index b12730a..e731f87 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c @@ -436,8 +436,8 @@ static int hns3_set_tso(struct sk_buff *skb, u32 *paylen, return 0; } -static void hns3_get_l4_protocol(struct sk_buff *skb, u8 *ol4_proto, -u8 *il4_proto) +static int hns3_get_l4_protocol(struct sk_buff *skb, u8 *ol4_proto, + u8 *il4_proto) { union { struct iphdr *v4; @@ -461,6 +461,8 @@ static void hns3_get_l4_protocol(struct sk_buff *skb, u8 *ol4_proto, &l4_proto_tmp, &frag_off); } else if (skb->protocol == htons(ETH_P_IP)) { l4_proto_tmp = l3.v4->protocol; + } else { + return -EINVAL; } *ol4_proto = l4_proto_tmp; @@ -468,7 +470,7 @@ static void hns3_get_l4_protocol(struct sk_buff *skb, u8 *ol4_proto, /* tunnel packet */ if (!skb->encapsulation) { *il4_proto = 0; - return; + return 0; } /* find inner header point */ @@ -486,6 +488,8 @@ static void hns3_get_l4_protocol(struct sk_buff *skb, u8 *ol4_proto, } *il4_proto = l4_proto_tmp; + + return 0; } static void hns3_set_l2l3l4_len(struct sk_buff *skb, u8 ol4_proto, @@ -757,7 +761,9 @@ static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv, protocol = vlan_get_protocol(skb); skb->protocol = protocol; } - hns3_get_l4_protocol(skb, &ol4_proto, &il4_proto); + ret = hns3_get_l4_protocol(skb, &ol4_proto, &il4_proto); + if (ret) + return ret; hns3_set_l2l3l4_len(skb, ol4_proto, il4_proto, &type_cs_vlan_tso, &ol_type_vlan_len_msec); -- 2.7.4
[PATCH net-next 0/3] Misc. Bug fixes for HNS3 Ethernet Driver
This patch-set fixes various bugs reported by community. Salil Mehta (3): net: hns3: Fixes the missing u64_stats_fetch_begin_irq in 64-bit stats fetch net: hns3: Fixes the static checker error warning in hns3_get_link_ksettings() net: hns3: Fixes the static check warning due to missing unsupp L3 proto check .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c | 16 +++- .../ethernet/hisilicon/hns3/hns3pf/hns3_ethtool.c | 85 -- 2 files changed, 60 insertions(+), 41 deletions(-) -- 2.7.4
[PATCH net-next 2/3] net: hns3: Fixes the static checker error warning in hns3_get_link_ksettings()
This patch fixes the static check error warning in hns3_get_link_ksettings() function by re-arranging the code. Fixes: 496d03e960ae ("net: hns3: Add Ethtool support to HNS3 Driver") Reported-by: Dan Carpenter Signed-off-by: Salil Mehta --- .../ethernet/hisilicon/hns3/hns3pf/hns3_ethtool.c | 85 -- 1 file changed, 48 insertions(+), 37 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_ethtool.c index 0ad65e4..ffc837b 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_ethtool.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_ethtool.c @@ -313,7 +313,7 @@ static int hns3_get_link_ksettings(struct net_device *netdev, if (!h->ae_algo || !h->ae_algo->ops) return -EOPNOTSUPP; - /* 1.auto_neg&speed&duplex from cmd */ + /* 1.auto_neg & speed & duplex from cmd */ if (h->ae_algo->ops->get_ksettings_an_result) { h->ae_algo->ops->get_ksettings_an_result(h, &auto_neg, &speed, &duplex); @@ -329,50 +329,61 @@ static int hns3_get_link_ksettings(struct net_device *netdev, } /* 2.media_type get from bios parameter block */ - if (h->ae_algo->ops->get_media_type) + if (h->ae_algo->ops->get_media_type) { h->ae_algo->ops->get_media_type(h, &media_type); - switch (media_type) { - case HNAE3_MEDIA_TYPE_FIBER: - cmd->base.port = PORT_FIBRE; - supported_caps = HNS3_LM_FIBRE_BIT | HNS3_LM_AUTONEG_BIT | - HNS3_LM_PAUSE_BIT | HNS3_LM_1000BASET_FULL_BIT; + switch (media_type) { + case HNAE3_MEDIA_TYPE_FIBER: + cmd->base.port = PORT_FIBRE; + supported_caps = HNS3_LM_FIBRE_BIT | +HNS3_LM_AUTONEG_BIT | +HNS3_LM_PAUSE_BIT | +HNS3_LM_1000BASET_FULL_BIT; + + advertised_caps = supported_caps; + break; + case HNAE3_MEDIA_TYPE_COPPER: + cmd->base.port = PORT_TP; + supported_caps = HNS3_LM_TP_BIT | +HNS3_LM_AUTONEG_BIT | +HNS3_LM_PAUSE_BIT | +HNS3_LM_1000BASET_FULL_BIT | +HNS3_LM_100BASET_FULL_BIT | +HNS3_LM_100BASET_HALF_BIT | +HNS3_LM_10BASET_FULL_BIT | +HNS3_LM_10BASET_HALF_BIT; + advertised_caps = supported_caps; + break; + case HNAE3_MEDIA_TYPE_BACKPLANE: + cmd->base.port = PORT_NONE; + supported_caps = HNS3_LM_BACKPLANE_BIT | +HNS3_LM_PAUSE_BIT | +HNS3_LM_AUTONEG_BIT | +HNS3_LM_1000BASET_FULL_BIT | +HNS3_LM_100BASET_FULL_BIT | +HNS3_LM_100BASET_HALF_BIT | +HNS3_LM_10BASET_FULL_BIT | +HNS3_LM_10BASET_HALF_BIT; + + advertised_caps = supported_caps; + break; + case HNAE3_MEDIA_TYPE_UNKNOWN: + default: + cmd->base.port = PORT_OTHER; + supported_caps = 0; + advertised_caps = 0; + break; + } - advertised_caps = supported_caps; - break; - case HNAE3_MEDIA_TYPE_COPPER: - cmd->base.port = PORT_TP; - supported_caps = HNS3_LM_TP_BIT | HNS3_LM_AUTONEG_BIT | - HNS3_LM_PAUSE_BIT | HNS3_LM_1000BASET_FULL_BIT | - HNS3_LM_100BASET_FULL_BIT | HNS3_LM_100BASET_HALF_BIT | - HNS3_LM_10BASET_FULL_BIT | HNS3_LM_10BASET_HALF_BIT; - advertised_caps = supported_caps; - break; - case HNAE3_MEDIA_TYPE_BACKPLANE: - cmd->base.port = PORT_NONE; - supported_caps = HNS3_LM_BACKPLANE_BIT | HNS3_LM_PAUSE_BIT | - HNS3_LM_AUTONEG_BIT | HNS3_LM_1000BASET_FULL_BIT | - HNS3_LM_100BASET_FULL_BIT | HNS3_LM_100BASET_HALF_BIT | - HNS3_LM_10BASET_FULL_BIT | HNS3_LM_10BASET_HALF_BIT; - - advertised_caps = supported_caps; -
RE: [PATCH V2 net] net: hns3: Updates MSI/MSI-X alloc/free APIs(depricated) to new APIs
Hi David, > -Original Message- > From: David Miller [mailto:da...@davemloft.net] > Sent: Monday, November 13, 2017 1:19 AM > To: Salil Mehta > Cc: h...@lst.de; Zhuangyuzeng (Yisen); lipeng (Y); > mehta.salil@gmail.com; net...@vger.kernel.org; linux- > ker...@vger.kernel.org; linux-r...@vger.kernel.org; Linuxarm > Subject: Re: [PATCH V2 net] net: hns3: Updates MSI/MSI-X alloc/free > APIs(depricated) to new APIs > > From: Salil Mehta > Date: Thu, 9 Nov 2017 16:38:13 + > > > This patch migrates the HNS3 driver code from use of depricated PCI > > MSI/MSI-X interrupt vector allocation/free APIs to new common APIs. > > > > Signed-off-by: Salil Mehta > > Suggested-by: Christoph Hellwig > > This doesn't apply cleanly to the net-next tree. It was meant for net repo. I will again re-spin it against net-next and re-submit it today.
[PATCH V3 net-next] net: hns3: Updates MSI/MSI-X alloc/free APIs(depricated) to new APIs
This patch migrates the HNS3 driver code from use of depricated PCI MSI/MSI-X interrupt vector allocation/free APIs to new common APIs. Signed-off-by: Salil Mehta Suggested-by: Christoph Hellwig --- PATCH V3: respin against latest net-next PATCH V2: Yuval Shaia Link -> https://lkml.org/lkml/2017/11/9/138 PATCH V1: Initial Submit --- .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 107 +++-- .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h| 17 ++-- 2 files changed, 43 insertions(+), 81 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 781d5a8..59ed806 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -891,14 +891,14 @@ static int hclge_query_pf_resource(struct hclge_dev *hdev) hdev->pkt_buf_size = __le16_to_cpu(req->buf_size) << HCLGE_BUF_UNIT_S; if (hnae3_dev_roce_supported(hdev)) { - hdev->num_roce_msix = + hdev->num_roce_msi = hnae_get_field(__le16_to_cpu(req->pf_intr_vector_number), HCLGE_PF_VEC_NUM_M, HCLGE_PF_VEC_NUM_S); /* PF should have NIC vectors and Roce vectors, * NIC vectors are queued before Roce vectors. */ - hdev->num_msi = hdev->num_roce_msix + HCLGE_ROCE_VECTOR_OFFSET; + hdev->num_msi = hdev->num_roce_msi + HCLGE_ROCE_VECTOR_OFFSET; } else { hdev->num_msi = hnae_get_field(__le16_to_cpu(req->pf_intr_vector_number), @@ -1950,7 +1950,7 @@ static int hclge_init_roce_base_info(struct hclge_vport *vport) struct hnae3_handle *roce = &vport->roce; struct hnae3_handle *nic = &vport->nic; - roce->rinfo.num_vectors = vport->back->num_roce_msix; + roce->rinfo.num_vectors = vport->back->num_roce_msi; if (vport->back->num_msi_left < vport->roce.rinfo.num_vectors || vport->back->num_msi_left == 0) @@ -1968,67 +1968,47 @@ static int hclge_init_roce_base_info(struct hclge_vport *vport) return 0; } -static int hclge_init_msix(struct hclge_dev *hdev) +static int hclge_init_msi(struct hclge_dev *hdev) { struct pci_dev *pdev = hdev->pdev; - int ret, i; - - hdev->msix_entries = devm_kcalloc(&pdev->dev, hdev->num_msi, - sizeof(struct msix_entry), - GFP_KERNEL); - if (!hdev->msix_entries) - return -ENOMEM; - - hdev->vector_status = devm_kcalloc(&pdev->dev, hdev->num_msi, - sizeof(u16), GFP_KERNEL); - if (!hdev->vector_status) - return -ENOMEM; + int vectors; + int i; - for (i = 0; i < hdev->num_msi; i++) { - hdev->msix_entries[i].entry = i; - hdev->vector_status[i] = HCLGE_INVALID_VPORT; + vectors = pci_alloc_irq_vectors(pdev, 1, hdev->num_msi, + PCI_IRQ_MSI | PCI_IRQ_MSIX); + if (vectors < 0) { + dev_err(&pdev->dev, + "failed(%d) to allocate MSI/MSI-X vectors\n", + vectors); + return vectors; } + if (vectors < hdev->num_msi) + dev_warn(&hdev->pdev->dev, +"requested %d MSI/MSI-X, but allocated %d MSI/MSI-X\n", +hdev->num_msi, vectors); - hdev->num_msi_left = hdev->num_msi; - hdev->base_msi_vector = hdev->pdev->irq; + hdev->num_msi = vectors; + hdev->num_msi_left = vectors; + hdev->base_msi_vector = pdev->irq; hdev->roce_base_vector = hdev->base_msi_vector + HCLGE_ROCE_VECTOR_OFFSET; - ret = pci_enable_msix_range(hdev->pdev, hdev->msix_entries, - hdev->num_msi, hdev->num_msi); - if (ret < 0) { - dev_info(&hdev->pdev->dev, -"MSI-X vector alloc failed: %d\n", ret); - return ret; - } - - return 0; -} - -static int hclge_init_msi(struct hclge_dev *hdev) -{ - struct pci_dev *pdev = hdev->pdev; - int vectors; - int i; - hdev->vector_status = devm_kcalloc(&pdev->dev, hdev->num_msi, sizeof(u16), GFP_KERNEL); - if (!hdev->vector_status) + if (!hdev->vector_status) { + pci_free_irq_vectors(pdev); return -ENOMEM; + } f
RE: [PATCH V3 net-next] net: hns3: Updates MSI/MSI-X alloc/free APIs(depricated) to new APIs
> -Original Message- > From: David Miller [mailto:da...@davemloft.net] > Sent: Tuesday, November 14, 2017 12:46 PM > To: Salil Mehta > Cc: Zhuangyuzeng (Yisen); lipeng (Y); h...@lst.de; > mehta.salil@gmail.com; net...@vger.kernel.org; linux- > ker...@vger.kernel.org; linux-r...@vger.kernel.org; Linuxarm > Subject: Re: [PATCH V3 net-next] net: hns3: Updates MSI/MSI-X > alloc/free APIs(depricated) to new APIs > > From: Salil Mehta > Date: Mon, 13 Nov 2017 11:39:38 + > > > This patch migrates the HNS3 driver code from use of depricated PCI > > MSI/MSI-X interrupt vector allocation/free APIs to new common APIs. > > > > Signed-off-by: Salil Mehta > > Suggested-by: Christoph Hellwig > > Applied. Thanks David.
RE: [PATCH net-next 0/6] net: hns3: support set_link_ksettings and for nway_reset ethtool command
Hi Andrew, > -Original Message- > From: Andrew Lunn [mailto:and...@lunn.ch] > Sent: Friday, November 03, 2017 3:52 PM > To: lipeng (Y) > Cc: da...@davemloft.net; net...@vger.kernel.org; linux- > ker...@vger.kernel.org; Linuxarm; Salil Mehta > Subject: Re: [PATCH net-next 0/6] net: hns3: support set_link_ksettings > and for nway_reset ethtool command > > On Fri, Nov 03, 2017 at 12:18:24PM +0800, Lipeng wrote: > > This patch-set adds support for set_link_ksettings && for nway_resets > > ethtool command and fixes some related ethtool bugs. > > 1, patch[4/6] adds support for ethtool_ops.set_link_ksettings. > > 2, patch[5/6] adds support ethtool_ops.for nway_reset. > > 3, patch[1/6,2/6,3/6,6/6] fix some bugs for getting port information > by > >ethtool command(ethtool ethx). > > Hi Lipeng > > Do you want the fixes applied to net, and back ported to stable? > > If so, you need to submit them separately, and against the correct > tree. Yes, you are correct. This should have been submitted against net repo. But now this patch-set has been accepted by Dave for net-next do you think we can still submit it again against Dave's net repo? Thanks Salil > > Andrew
RE: [PATCH net-next 5/9] net: hns3: Fix for vf vlan delete failed problem
Hi Dave, > -Original Message- > From: David Miller [mailto:da...@davemloft.net] > Sent: Monday, August 13, 2018 4:57 PM > To: Salil Mehta > Cc: Zhuangyuzeng (Yisen) ; lipeng (Y) > ; mehta.salil@gmail.com; > net...@vger.kernel.org; linux-kernel@vger.kernel.org; Linuxarm > ; linyunsheng > Subject: Re: [PATCH net-next 5/9] net: hns3: Fix for vf vlan delete > failed problem > > From: Salil Mehta > Date: Sun, 12 Aug 2018 10:47:34 +0100 > > > Fixes: 9dba194574e3 ("{topost} net: hns3: fix for vlan table > problem") > > This commit ID doesn't exist. Thanks for catching this. This commit ID was from our internal branch and ideally should have been from net-next - I should have caught this earlier, sorry for this! I have for now dropped this patch from the series as there is another related patch(being referred in the Fixes string) that would need to be merged with this patch before sending to net-next. Therefore, will refloat this patch along with other related patch later in next cycle. > > Also, I really don't think the string "{topost}" would be in the commit > header line. Yes, this is stray and will be removed when this patch is sent next. Thank you Salil
[PATCH net-next] net: hns3: converting spaces into tabs to avoid checkpatch.pl warning
Spaces were mistakenly used instead of tabs in some of the code related to reset functionality, which caused checkpatch.pl errors. These were missed earlier so fixing them now. Signed-off-by: Salil Mehta --- drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index ac84816..601b629 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -3318,8 +3318,8 @@ static int hns3_reset_notify(struct hnae3_handle *handle, switch (type) { case HNAE3_UP_CLIENT: -ret = hns3_reset_notify_up_enet(handle); -break; + ret = hns3_reset_notify_up_enet(handle); + break; case HNAE3_DOWN_CLIENT: ret = hns3_reset_notify_down_enet(handle); break; -- 2.7.4
[PATCH net-next 0/9] Add support of VF Reset to HNS3 VF driver
This patch-set adds the support of VF reset to the existing VF driver. VF Reset can be triggered due to TX watchdog firing as a result of TX data-path not working. VF reset could also be a result of some internal configuration changes if that requires reset, or as a result of the PF/Core/Global/IMP(Integrated Management Processor) reset happened in the PF. Summary of Patches: * Watchdog timer trigger chnages are present in Patch 1. * Reset Service Task and related Event handling is present in Patches {2,3} * Changes to send reset request to PF, reset stack and re-initialization of the hclge device is present in Patches {4,5,6} * Changes related to ARQ (Asynchronous Receive Queue) and its event handling are present in Patches {7,8} * Changes required in PF to handle the VF Reset request and actually perform hardware VF reset is there in Patch 9. NOTE: This patch depends upon "[PATCH net-next 00/11] fix some bugs for HNS3 driver" Link: https://lkml.org/lkml/2018/3/21/72 Salil Mehta (9): net: hns3: Changes to make enet watchdog timeout func common for PF/VF net: hns3: Add VF Reset Service Task to support event handling net: hns3: Add VF Reset device state and its handling net: hns3: Add support to request VF Reset to PF net: hns3: Add support to reset the enet/ring mgmt layer net: hns3: Add support to re-initialize the hclge device net: hns3: Changes to support ARQ(Asynchronous Receive Queue) net: hns3: Add *Asserting Reset* mailbox message & handling in VF net: hns3: Changes required in PF mailbox to support VF reset drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h| 16 + drivers/net/ethernet/hisilicon/hns3/hnae3.h| 8 +- drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 30 +- drivers/net/ethernet/hisilicon/hns3/hns3_enet.h| 2 - .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 38 +-- .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h| 1 + .../net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 42 +++ .../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c | 6 + .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 336 +++-- .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h | 31 ++ .../ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c | 95 +- 11 files changed, 534 insertions(+), 71 deletions(-) -- 2.7.4
[PATCH net-next 5/9] net: hns3: Add support to reset the enet/ring mgmt layer
After VF driver knows that hardware reset has been performed successfully, it should proceed ahead and reset the enet layer. This primarily consists of bringing down interface, clearing TX/RX rings, disassociating vectors from ring etc. Signed-off-by: Salil Mehta --- .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 103 - .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h | 3 + 2 files changed, 102 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index b648311..bd45b11 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -2,6 +2,7 @@ // Copyright (c) 2016-2017 Hisilicon Limited. #include +#include #include "hclgevf_cmd.h" #include "hclgevf_main.h" #include "hclge_mbx.h" @@ -832,6 +833,101 @@ static void hclgevf_reset_tqp(struct hnae3_handle *handle, u16 queue_id) 2, true, NULL, 0); } +static int hclgevf_notify_client(struct hclgevf_dev *hdev, +enum hnae3_reset_notify_type type) +{ + struct hnae3_client *client = hdev->nic_client; + struct hnae3_handle *handle = &hdev->nic; + + if (!client->ops->reset_notify) + return -EOPNOTSUPP; + + return client->ops->reset_notify(handle, type); +} + +static int hclgevf_reset_wait(struct hclgevf_dev *hdev) +{ +#define HCLGEVF_RESET_WAIT_MS 500 +#define HCLGEVF_RESET_WAIT_CNT 20 + u32 val, cnt = 0; + + /* wait to check the hardware reset completion status */ + val = hclgevf_read_dev(&hdev->hw, HCLGEVF_FUN_RST_ING); + while (hnae_get_bit(val, HCLGEVF_FUN_RST_ING_B) && + (cnt < HCLGEVF_RESET_WAIT_CNT)) { + msleep(HCLGEVF_RESET_WAIT_MS); + val = hclgevf_read_dev(&hdev->hw, HCLGEVF_FUN_RST_ING); + cnt++; + } + + /* hardware completion status should be available by this time */ + if (cnt >= HCLGEVF_RESET_WAIT_CNT) { + dev_warn(&hdev->pdev->dev, +"could'nt get reset done status from h/w, timeout!\n"); + return -EBUSY; + } + + /* we will wait a bit more to let reset of the stack to complete. This +* might happen in case reset assertion was made by PF. Yes, this also +* means we might end up waiting bit more even for VF reset. +*/ + msleep(5000); + + return 0; +} + +static int hclgevf_reset_stack(struct hclgevf_dev *hdev) +{ + /* uninitialize the nic client */ + hclgevf_notify_client(hdev, HNAE3_UNINIT_CLIENT); + + /* re-initialize the hclge device - add code here */ + + /* bring up the nic client again */ + hclgevf_notify_client(hdev, HNAE3_INIT_CLIENT); + + return 0; +} + +static int hclgevf_reset(struct hclgevf_dev *hdev) +{ + int ret; + + rtnl_lock(); + + /* bring down the nic to stop any ongoing TX/RX */ + hclgevf_notify_client(hdev, HNAE3_DOWN_CLIENT); + + /* check if VF could successfully fetch the hardware reset completion +* status from the hardware +*/ + ret = hclgevf_reset_wait(hdev); + if (ret) { + /* can't do much in this situation, will disable VF */ + dev_err(&hdev->pdev->dev, + "VF failed(=%d) to fetch H/W reset completion status\n", + ret); + + dev_warn(&hdev->pdev->dev, "VF reset failed, disabling VF!\n"); + hclgevf_notify_client(hdev, HNAE3_UNINIT_CLIENT); + + rtnl_unlock(); + return ret; + } + + /* now, re-initialize the nic client and ae device*/ + ret = hclgevf_reset_stack(hdev); + if (ret) + dev_err(&hdev->pdev->dev, "failed to reset VF stack\n"); + + /* bring up the nic to enable TX/RX again */ + hclgevf_notify_client(hdev, HNAE3_UP_CLIENT); + + rtnl_unlock(); + + return ret; +} + static int hclgevf_do_reset(struct hclgevf_dev *hdev) { int status; @@ -940,10 +1036,9 @@ static void hclgevf_reset_service_task(struct work_struct *work) */ hdev->reset_attempts = 0; - /* code to check/wait for hardware reset completion and the -* further initiating software stack reset would be added here -*/ - + ret = hclgevf_reset(hdev); + if (ret) + dev_err(&hdev->pdev->dev, "VF stack reset failed.\n"); } else if (test_and_clear_bit(HCLGEVF_RESET_REQUESTED, &hdev-&g
[PATCH net-next 7/9] net: hns3: Changes to support ARQ(Asynchronous Receive Queue)
Current mailbox CRQ could consists of both synchronous and async responses from the PF. Synchronous responses are time critical and should be handed over to the waiting tasks/context as quickly as possible otherwise timeout occurs. Above problem gets accentuated if CRQ consists of even single async message. Hence, it is important to have quick handling of synchronous messages and maybe deferred handling of async messages This patch introduces separate ARQ(async receive queues) for the async messages. These messages are processed later with repsect to mailbox task while synchronous messages still gets processed in context to mailbox interrupt. ARQ is important as VF reset introduces some new async messages like MBX_ASSERTING_RESET which adds up to the presssure on the responses for synchronousmessages and they timeout even more quickly. Signed-off-by: Salil Mehta --- drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h| 15 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c | 6 ++ .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 16 +++-- .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h | 5 ++ .../ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c | 83 +++--- 5 files changed, 111 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h index e6e1d22..f3e90c2 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h +++ b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h @@ -85,6 +85,21 @@ struct hclge_mbx_pf_to_vf_cmd { u16 msg[8]; }; +/* used by VF to store the received Async responses from PF */ +struct hclgevf_mbx_arq_ring { +#define HCLGE_MBX_MAX_ARQ_MSG_SIZE 8 +#define HCLGE_MBX_MAX_ARQ_MSG_NUM 1024 + struct hclgevf_dev *hdev; + u32 head; + u32 tail; + u32 count; + u16 msg_q[HCLGE_MBX_MAX_ARQ_MSG_NUM][HCLGE_MBX_MAX_ARQ_MSG_SIZE]; +}; + #define hclge_mbx_ring_ptr_move_crq(crq) \ (crq->next_to_use = (crq->next_to_use + 1) % crq->desc_num) +#define hclge_mbx_tail_ptr_move_arq(arq) \ + (arq.tail = (arq.tail + 1) % HCLGE_MBX_MAX_ARQ_MSG_SIZE) +#define hclge_mbx_head_ptr_move_arq(arq) \ + (arq.head = (arq.head + 1) % HCLGE_MBX_MAX_ARQ_MSG_SIZE) #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c index 85985e7..1bbfe13 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c @@ -315,6 +315,12 @@ int hclgevf_cmd_init(struct hclgevf_dev *hdev) goto err_csq; } + /* initialize the pointers of async rx queue of mailbox */ + hdev->arq.hdev = hdev; + hdev->arq.head = 0; + hdev->arq.tail = 0; + hdev->arq.count = 0; + /* get firmware version */ ret = hclgevf_cmd_query_firmware_version(&hdev->hw, &version); if (ret) { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index 6dd7561..2b84264 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -1010,10 +1010,13 @@ void hclgevf_reset_task_schedule(struct hclgevf_dev *hdev) } } -static void hclgevf_mbx_task_schedule(struct hclgevf_dev *hdev) +void hclgevf_mbx_task_schedule(struct hclgevf_dev *hdev) { - if (!test_and_set_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state)) + if (!test_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state) && + !test_bit(HCLGEVF_STATE_MBX_HANDLING, &hdev->state)) { + set_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state); schedule_work(&hdev->mbx_service_task); + } } static void hclgevf_task_schedule(struct hclgevf_dev *hdev) @@ -1025,6 +1028,10 @@ static void hclgevf_task_schedule(struct hclgevf_dev *hdev) static void hclgevf_deferred_task_schedule(struct hclgevf_dev *hdev) { + /* if we have any pending mailbox event then schedule the mbx task */ + if (hdev->mbx_event_pending) + hclgevf_mbx_task_schedule(hdev); + if (test_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state)) hclgevf_reset_task_schedule(hdev); } @@ -1118,7 +1125,7 @@ static void hclgevf_mailbox_service_task(struct work_struct *work) clear_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state); - hclgevf_mbx_handler(hdev); + hclgevf_mbx_async_handler(hdev); clear_bit(HCLGEVF_STATE_MBX_HANDLING, &hdev->state); } @@ -1178,8 +1185,7 @@ static irqreturn_t hclgevf_misc_irq_handle(int irq, void *data) if (!hclgevf_check_event_cause(hdev, &clearval)) goto skip_sched; - /* schedule the VF mailbox service
[PATCH net-next 8/9] net: hns3: Add *Asserting Reset* mailbox message & handling in VF
Reset Asserting message is forwarded by PF to inform VF about the hardware reset which is about to happen. This might be due to the earlier VF reset request received by the PF or because PF for any reason decides to undergo reset. This message results in VF to go in pending state in which it polls the hardware to complete the reset and then further resets/tears its own stack. Signed-off-by: Salil Mehta --- drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h | 1 + drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c | 12 2 files changed, 13 insertions(+) diff --git a/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h index f3e90c2..519e2bd 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h +++ b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h @@ -11,6 +11,7 @@ enum HCLGE_MBX_OPCODE { HCLGE_MBX_RESET = 0x01, /* (VF -> PF) assert reset */ + HCLGE_MBX_ASSERTING_RESET, /* (PF -> VF) PF is asserting reset*/ HCLGE_MBX_SET_UNICAST, /* (VF -> PF) set UC addr */ HCLGE_MBX_SET_MULTICAST,/* (VF -> PF) set MC addr */ HCLGE_MBX_SET_VLAN, /* (VF -> PF) set VLAN */ diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c index 7687911..a286184 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c @@ -170,6 +170,7 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev) } break; case HCLGE_MBX_LINK_STAT_CHANGE: + case HCLGE_MBX_ASSERTING_RESET: /* set this mbx event as pending. This is required as we * might loose interrupt event when mbx task is busy * handling. This shall be cleared when mbx task just @@ -242,6 +243,17 @@ void hclgevf_mbx_async_handler(struct hclgevf_dev *hdev) hclgevf_update_speed_duplex(hdev, speed, duplex); break; + case HCLGE_MBX_ASSERTING_RESET: + /* PF has asserted reset hence VF should go in pending +* state and poll for the hardware reset status till it +* has been completely reset. After this stack should +* eventually be re-initialized. +*/ + hdev->nic.reset_level = HNAE3_VF_RESET; + set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state); + hclgevf_reset_task_schedule(hdev); + + break; default: dev_err(&hdev->pdev->dev, "fetched unsupported(%d) message from arq\n", -- 2.7.4
[PATCH net-next 4/9] net: hns3: Add support to request VF Reset to PF
VF driver depends upon PF to eventually reset the hardware. This request is made using the mailbox command. This patch adds the required function to acheive above. Signed-off-by: Salil Mehta --- .../net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 19 +++ 1 file changed, 19 insertions(+) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index 0d204e2..b648311 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -832,6 +832,20 @@ static void hclgevf_reset_tqp(struct hnae3_handle *handle, u16 queue_id) 2, true, NULL, 0); } +static int hclgevf_do_reset(struct hclgevf_dev *hdev) +{ + int status; + u8 respmsg; + + status = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_RESET, 0, NULL, + 0, false, &respmsg, sizeof(u8)); + if (status) + dev_err(&hdev->pdev->dev, + "VF reset request to PF failed(=%d)\n", status); + + return status; +} + static void hclgevf_reset_event(struct hnae3_handle *handle) { struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); @@ -910,6 +924,7 @@ static void hclgevf_reset_service_task(struct work_struct *work) { struct hclgevf_dev *hdev = container_of(work, struct hclgevf_dev, rst_service_task); + int ret; if (test_and_set_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state)) return; @@ -965,6 +980,10 @@ static void hclgevf_reset_service_task(struct work_struct *work) hdev->reset_attempts++; /* request PF for resetting this VF via mailbox */ + ret = hclgevf_do_reset(hdev); + if (ret) + dev_warn(&hdev->pdev->dev, +"VF rst fail, stack will call\n"); } } -- 2.7.4
[PATCH net-next 9/9] net: hns3: Changes required in PF mailbox to support VF reset
PF needs to assert the VF reset when it receives the request to reset from VF. After receiving request PF ackknowledges the request by replying back MBX_ASSERTING_RESET message to VF. VF then goes to pending state and wait for hardware to complete the reset. This patch contains code to handle the received VF message, inform the VF of assertion and reset the VF using cmdq interface. Signed-off-by: Salil Mehta --- .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 2 +- .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h| 1 + .../net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 42 ++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index a3e00da..bede411 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -2749,7 +2749,7 @@ static int hclge_reset_wait(struct hclge_dev *hdev) return 0; } -static int hclge_func_reset_cmd(struct hclge_dev *hdev, int func_id) +int hclge_func_reset_cmd(struct hclge_dev *hdev, int func_id) { struct hclge_desc desc; struct hclge_reset_cmd *req = (struct hclge_reset_cmd *)desc.data; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index 8c14d10..0f4157e 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -657,4 +657,5 @@ void hclge_mbx_handler(struct hclge_dev *hdev); void hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id); void hclge_reset_vf_queue(struct hclge_vport *vport, u16 queue_id); int hclge_cfg_flowctrl(struct hclge_dev *hdev); +int hclge_func_reset_cmd(struct hclge_dev *hdev, int func_id); #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c index 949da0c..3901333 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c @@ -79,6 +79,18 @@ static int hclge_send_mbx_msg(struct hclge_vport *vport, u8 *msg, u16 msg_len, return status; } +int hclge_inform_reset_assert_to_vf(struct hclge_vport *vport) +{ + u8 msg_data[2]; + u8 dest_vfid; + + dest_vfid = (u8)vport->vport_id; + + /* send this requested info to VF */ + return hclge_send_mbx_msg(vport, msg_data, sizeof(u8), + HCLGE_MBX_ASSERTING_RESET, dest_vfid); +} + static void hclge_free_vector_ring_chain(struct hnae3_ring_chain_node *head) { struct hnae3_ring_chain_node *chain_tmp, *chain; @@ -339,6 +351,33 @@ static void hclge_mbx_reset_vf_queue(struct hclge_vport *vport, hclge_gen_resp_to_vf(vport, mbx_req, 0, NULL, 0); } +static void hclge_reset_vf(struct hclge_vport *vport, + struct hclge_mbx_vf_to_pf_cmd *mbx_req) +{ + struct hclge_dev *hdev = vport->back; + int ret; + + dev_warn(&hdev->pdev->dev, "PF received VF reset request from VF %d!", +mbx_req->mbx_src_vfid); + + /* Acknowledge VF that PF is now about to assert the reset for the VF. +* On receiving this message VF will get into pending state and will +* start polling for the hardware reset completion status. +*/ + ret = hclge_inform_reset_assert_to_vf(vport); + if (ret) { + dev_err(&hdev->pdev->dev, + "PF fail(%d) to inform VF(%d)of reset, reset failed!\n", + ret, vport->vport_id); + return; + } + + dev_warn(&hdev->pdev->dev, "PF is now resetting VF %d.\n", +mbx_req->mbx_src_vfid); + /* reset this virtual function */ + hclge_func_reset_cmd(hdev, mbx_req->mbx_src_vfid); +} + void hclge_mbx_handler(struct hclge_dev *hdev) { struct hclge_cmq_ring *crq = &hdev->hw.cmq.crq; @@ -416,6 +455,9 @@ void hclge_mbx_handler(struct hclge_dev *hdev) case HCLGE_MBX_QUEUE_RESET: hclge_mbx_reset_vf_queue(vport, req); break; + case HCLGE_MBX_RESET: + hclge_reset_vf(vport, req); + break; default: dev_err(&hdev->pdev->dev, "un-supported mailbox message, code = %d\n", -- 2.7.4
[PATCH net-next 3/9] net: hns3: Add VF Reset device state and its handling
This introduces the hclge device reset states of "requested" and "pending" and also its handling in context to Reset Service Task. Device gets into requested state because of any VF reset request asserted from upper layers, for example due to watchdog timeout expiration. Requested state would result in eventually forwarding the VF reset request to PF which would actually reset the VF. Device will get into pending state if: 1. VF receives the acknowledgement from PF for the VF reset request it originally sent to PF. 2. Reset Service Task detects that after asserting VF reset for certain times the data-path is not working and device then decides to assert full VF reset(this means also resetting the PCIe interface). 3. PF intimates the VF that it has undergone reset. Pending state would result in VF to poll for hardware reset completion status and then resetting the stack/enet layer, which in turn means reinitializing the ring management/enet layer. Note: we would be adding support of 3. later as a separate patch. This decision should not affect VF reset as its event handling is generic in nature. Signed-off-by: Salil Mehta --- drivers/net/ethernet/hisilicon/hns3/hnae3.h| 1 + .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 67 -- .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h | 5 ++ 3 files changed, 68 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index 56f9e650..37ec1b3 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -119,6 +119,7 @@ enum hnae3_reset_notify_type { enum hnae3_reset_type { HNAE3_VF_RESET, + HNAE3_VF_FULL_RESET, HNAE3_FUNC_RESET, HNAE3_CORE_RESET, HNAE3_GLOBAL_RESET, diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index cdb6e7a..0d204e2 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -840,7 +840,9 @@ static void hclgevf_reset_event(struct hnae3_handle *handle) handle->reset_level = HNAE3_VF_RESET; - /* request VF reset here. Code added later */ + /* reset of this VF requested */ + set_bit(HCLGEVF_RESET_REQUESTED, &hdev->reset_state); + hclgevf_reset_task_schedule(hdev); handle->last_reset_time = jiffies; } @@ -889,6 +891,12 @@ static void hclgevf_task_schedule(struct hclgevf_dev *hdev) schedule_work(&hdev->service_task); } +static void hclgevf_deferred_task_schedule(struct hclgevf_dev *hdev) +{ + if (test_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state)) + hclgevf_reset_task_schedule(hdev); +} + static void hclgevf_service_timer(struct timer_list *t) { struct hclgevf_dev *hdev = from_timer(hdev, t, service_timer); @@ -908,10 +916,57 @@ static void hclgevf_reset_service_task(struct work_struct *work) clear_bit(HCLGEVF_STATE_RST_SERVICE_SCHED, &hdev->state); - /* body of the reset service task will constitute of hclge device -* reset state handling. This code shall be added subsequently in -* next patches. -*/ + if (test_and_clear_bit(HCLGEVF_RESET_PENDING, + &hdev->reset_state)) { + /* PF has initmated that it is about to reset the hardware. +* We now have to poll & check if harware has actually completed +* the reset sequence. On hardware reset completion, VF needs to +* reset the client and ae device. +*/ + hdev->reset_attempts = 0; + + /* code to check/wait for hardware reset completion and the +* further initiating software stack reset would be added here +*/ + + } else if (test_and_clear_bit(HCLGEVF_RESET_REQUESTED, + &hdev->reset_state)) { + /* we could be here when either of below happens: +* 1. reset was initiated due to watchdog timeout due to +*a. IMP was earlier reset and our TX got choked down and +* which resulted in watchdog reacting and inducing VF +* reset. This also means our cmdq would be unreliable. +*b. problem in TX due to other lower layer(example link +* layer not functioning properly etc.) +* 2. VF reset might have been initiated due to some config +*change. +* +* NOTE: Theres no clear way to detect above cases than to react +* to the response of PF for this reset request. PF will ack the +* 1b and 2. c
[PATCH net-next 2/9] net: hns3: Add VF Reset Service Task to support event handling
VF reset would involve handling of different reset related events from the stack, physical function, mailbox etc. Reset service task would be used in servicing such reset event requests and later handling the hardware completions waits and initiating the stack resets. Signed-off-by: Salil Mehta --- .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 31 ++ .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h | 4 +++ 2 files changed, 35 insertions(+) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index 6c3881d..cdb6e7a 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -867,6 +867,15 @@ static void hclgevf_get_misc_vector(struct hclgevf_dev *hdev) hdev->num_msi_used += 1; } +void hclgevf_reset_task_schedule(struct hclgevf_dev *hdev) +{ + if (!test_bit(HCLGEVF_STATE_RST_SERVICE_SCHED, &hdev->state) && + !test_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state)) { + set_bit(HCLGEVF_STATE_RST_SERVICE_SCHED, &hdev->state); + schedule_work(&hdev->rst_service_task); + } +} + static void hclgevf_mbx_task_schedule(struct hclgevf_dev *hdev) { if (!test_and_set_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state)) @@ -889,6 +898,24 @@ static void hclgevf_service_timer(struct timer_list *t) hclgevf_task_schedule(hdev); } +static void hclgevf_reset_service_task(struct work_struct *work) +{ + struct hclgevf_dev *hdev = + container_of(work, struct hclgevf_dev, rst_service_task); + + if (test_and_set_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state)) + return; + + clear_bit(HCLGEVF_STATE_RST_SERVICE_SCHED, &hdev->state); + + /* body of the reset service task will constitute of hclge device +* reset state handling. This code shall be added subsequently in +* next patches. +*/ + + clear_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state); +} + static void hclgevf_mailbox_service_task(struct work_struct *work) { struct hclgevf_dev *hdev; @@ -1097,6 +1124,8 @@ static void hclgevf_state_init(struct hclgevf_dev *hdev) INIT_WORK(&hdev->service_task, hclgevf_service_task); clear_bit(HCLGEVF_STATE_SERVICE_SCHED, &hdev->state); + INIT_WORK(&hdev->rst_service_task, hclgevf_reset_service_task); + mutex_init(&hdev->mbx_resp.mbx_mutex); /* bring the device down */ @@ -1113,6 +1142,8 @@ static void hclgevf_state_uninit(struct hclgevf_dev *hdev) cancel_work_sync(&hdev->service_task); if (hdev->mbx_service_task.func) cancel_work_sync(&hdev->mbx_service_task); + if (hdev->rst_service_task.func) + cancel_work_sync(&hdev->rst_service_task); mutex_destroy(&hdev->mbx_resp.mbx_mutex); } diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h index 0eaea06..8b5fa67 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h @@ -52,6 +52,8 @@ enum hclgevf_states { HCLGEVF_STATE_DISABLED, /* task states */ HCLGEVF_STATE_SERVICE_SCHED, + HCLGEVF_STATE_RST_SERVICE_SCHED, + HCLGEVF_STATE_RST_HANDLING, HCLGEVF_STATE_MBX_SERVICE_SCHED, HCLGEVF_STATE_MBX_HANDLING, }; @@ -146,6 +148,7 @@ struct hclgevf_dev { struct timer_list service_timer; struct work_struct service_task; + struct work_struct rst_service_task; struct work_struct mbx_service_task; struct hclgevf_tqp *htqp; @@ -165,4 +168,5 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev); void hclgevf_update_link_status(struct hclgevf_dev *hdev, int link_state); void hclgevf_update_speed_duplex(struct hclgevf_dev *hdev, u32 speed, u8 duplex); +void hclgevf_reset_task_schedule(struct hclgevf_dev *hdev); #endif -- 2.7.4
[PATCH net-next 1/9] net: hns3: Changes to make enet watchdog timeout func common for PF/VF
HNS3 drivers enet layer, used for the ring management and stack interaction, is common to both VF and PF. PF already supports reset functionality to handle the network stack watchdog timeout trigger but the existing code is not generic enough to be used to support VF reset as well. This patch does following: 1. Makes the existing watchdog timeout handler in enet layer generic i.e. suitable for both VF and PF and 2. Introduces the new reset event handler for the VF code. 3. Changes existing reset event handler of PF code to initialize the reset level Signed-off-by: Salil Mehta --- drivers/net/ethernet/hisilicon/hns3/hnae3.h| 7 +++-- drivers/net/ethernet/hisilicon/hns3/hns3_enet.c| 30 +- drivers/net/ethernet/hisilicon/hns3/hns3_enet.h| 2 -- .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 36 -- .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 14 + 5 files changed, 46 insertions(+), 43 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index 9daa88d..56f9e650 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -118,6 +118,7 @@ enum hnae3_reset_notify_type { }; enum hnae3_reset_type { + HNAE3_VF_RESET, HNAE3_FUNC_RESET, HNAE3_CORE_RESET, HNAE3_GLOBAL_RESET, @@ -400,8 +401,7 @@ struct hnae3_ae_ops { int (*set_vf_vlan_filter)(struct hnae3_handle *handle, int vfid, u16 vlan, u8 qos, __be16 proto); int (*enable_hw_strip_rxvtag)(struct hnae3_handle *handle, bool enable); - void (*reset_event)(struct hnae3_handle *handle, - enum hnae3_reset_type reset); + void (*reset_event)(struct hnae3_handle *handle); void (*get_channels)(struct hnae3_handle *handle, struct ethtool_channels *ch); void (*get_tqps_and_rss_info)(struct hnae3_handle *h, @@ -495,6 +495,9 @@ struct hnae3_handle { struct hnae3_ae_algo *ae_algo; /* the class who provides this handle */ u64 flags; /* Indicate the capabilities for this handle*/ + unsigned long last_reset_time; + enum hnae3_reset_type reset_level; + union { struct net_device *netdev; /* first member */ struct hnae3_knic_private_info kinfo; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index 0b4a676..40a3eb7 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -320,7 +320,7 @@ static int hns3_nic_net_open(struct net_device *netdev) return ret; } - priv->last_reset_time = jiffies; + priv->ae_handle->last_reset_time = jiffies; return 0; } @@ -1543,7 +1543,6 @@ static bool hns3_get_tx_timeo_queue_info(struct net_device *ndev) static void hns3_nic_net_timeout(struct net_device *ndev) { struct hns3_nic_priv *priv = netdev_priv(ndev); - unsigned long last_reset_time = priv->last_reset_time; struct hnae3_handle *h = priv->ae_handle; if (!hns3_get_tx_timeo_queue_info(ndev)) @@ -1551,24 +1550,12 @@ static void hns3_nic_net_timeout(struct net_device *ndev) priv->tx_timeout_count++; - /* This timeout is far away enough from last timeout, -* if timeout again,set the reset type to PF reset -*/ - if (time_after(jiffies, (last_reset_time + 20 * HZ))) - priv->reset_level = HNAE3_FUNC_RESET; - - /* Don't do any new action before the next timeout */ - else if (time_before(jiffies, (last_reset_time + ndev->watchdog_timeo))) + if (time_before(jiffies, (h->last_reset_time + ndev->watchdog_timeo))) return; - priv->last_reset_time = jiffies; - + /* request the reset */ if (h->ae_algo->ops->reset_event) - h->ae_algo->ops->reset_event(h, priv->reset_level); - - priv->reset_level++; - if (priv->reset_level > HNAE3_GLOBAL_RESET) - priv->reset_level = HNAE3_GLOBAL_RESET; + h->ae_algo->ops->reset_event(h); } static const struct net_device_ops hns3_nic_netdev_ops = { @@ -3122,8 +3109,8 @@ static int hns3_client_init(struct hnae3_handle *handle) priv->dev = &pdev->dev; priv->netdev = netdev; priv->ae_handle = handle; - priv->last_reset_time = jiffies; - priv->reset_level = HNAE3_FUNC_RESET; + priv->ae_handle->reset_level = HNAE3_NONE_RESET; + priv->ae_handle->last_reset_time = jiffies; priv->tx_timeout_count = 0; handle->kinfo.netdev = netdev; @@ -3355,7 +3342,6 @@ static int hns3_reset_notify_down_enet(struct hnae3_hand
[PATCH net-next 6/9] net: hns3: Add support to re-initialize the hclge device
After the hardware reset we should re-fetch the configuration from PF like queue info and tc info. This might have impact on allocations made like that of TQPs. Hence, we should release all such allocations and re-allocate fresh according to new fetched configuration after reset. Signed-off-by: Salil Mehta --- .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 106 ++--- .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h | 14 +++ 2 files changed, 106 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index bd45b11..6dd7561 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -10,6 +10,8 @@ #define HCLGEVF_NAME "hclgevf" +static int hclgevf_init_hdev(struct hclgevf_dev *hdev); +static void hclgevf_uninit_hdev(struct hclgevf_dev *hdev); static struct hnae3_ae_algo ae_algovf; static const struct pci_device_id ae_algovf_pci_tbl[] = { @@ -209,6 +211,12 @@ static int hclgevf_alloc_tqps(struct hclgevf_dev *hdev) struct hclgevf_tqp *tqp; int i; + /* if this is on going reset then we need to re-allocate the TPQs +* since we cannot assume we would get same number of TPQs back from PF +*/ + if (hclgevf_dev_ongoing_reset(hdev)) + devm_kfree(&hdev->pdev->dev, hdev->htqp); + hdev->htqp = devm_kcalloc(&hdev->pdev->dev, hdev->num_tqps, sizeof(struct hclgevf_tqp), GFP_KERNEL); if (!hdev->htqp) @@ -252,6 +260,12 @@ static int hclgevf_knic_setup(struct hclgevf_dev *hdev) new_tqps = kinfo->rss_size * kinfo->num_tc; kinfo->num_tqps = min(new_tqps, hdev->num_tqps); + /* if this is on going reset then we need to re-allocate the hnae queues +* as well since number of TPQs from PF might have changed. +*/ + if (hclgevf_dev_ongoing_reset(hdev)) + devm_kfree(&hdev->pdev->dev, kinfo->tqp); + kinfo->tqp = devm_kcalloc(&hdev->pdev->dev, kinfo->num_tqps, sizeof(struct hnae3_queue *), GFP_KERNEL); if (!kinfo->tqp) @@ -878,10 +892,18 @@ static int hclgevf_reset_wait(struct hclgevf_dev *hdev) static int hclgevf_reset_stack(struct hclgevf_dev *hdev) { + int ret; + /* uninitialize the nic client */ hclgevf_notify_client(hdev, HNAE3_UNINIT_CLIENT); - /* re-initialize the hclge device - add code here */ + /* re-initialize the hclge device */ + ret = hclgevf_init_hdev(hdev); + if (ret) { + dev_err(&hdev->pdev->dev, + "hclge device re-init failed, VF is disabled!\n"); + return ret; + } /* bring up the nic client again */ hclgevf_notify_client(hdev, HNAE3_INIT_CLIENT); @@ -1179,6 +1201,22 @@ static int hclgevf_configure(struct hclgevf_dev *hdev) return hclgevf_get_tc_info(hdev); } +static int hclgevf_alloc_hdev(struct hnae3_ae_dev *ae_dev) +{ + struct pci_dev *pdev = ae_dev->pdev; + struct hclgevf_dev *hdev = ae_dev->priv; + + hdev = devm_kzalloc(&pdev->dev, sizeof(*hdev), GFP_KERNEL); + if (!hdev) + return -ENOMEM; + + hdev->pdev = pdev; + hdev->ae_dev = ae_dev; + ae_dev->priv = hdev; + + return 0; +} + static int hclgevf_init_roce_base_info(struct hclgevf_dev *hdev) { struct hnae3_handle *roce = &hdev->roce; @@ -1284,6 +1322,10 @@ static void hclgevf_ae_stop(struct hnae3_handle *handle) static void hclgevf_state_init(struct hclgevf_dev *hdev) { + /* if this is on going reset then skip this initialization */ + if (hclgevf_dev_ongoing_reset(hdev)) + return; + /* setup tasks for the MBX */ INIT_WORK(&hdev->mbx_service_task, hclgevf_mailbox_service_task); clear_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state); @@ -1325,6 +1367,10 @@ static int hclgevf_init_msi(struct hclgevf_dev *hdev) int vectors; int i; + /* if this is on going reset then skip this initialization */ + if (hclgevf_dev_ongoing_reset(hdev)) + return 0; + hdev->num_msi = HCLGEVF_MAX_VF_VECTOR_NUM; vectors = pci_alloc_irq_vectors(pdev, 1, hdev->num_msi, @@ -1375,6 +1421,10 @@ static int hclgevf_misc_irq_init(struct hclgevf_dev *hdev) { int ret = 0; + /* if this is on going reset then skip this initialization */ + if (hclgevf_dev_ongoing_reset(hdev)) + return 0; + hclgevf_get_misc_vector(hdev); ret = request_irq(hdev->misc_vector.vector_irq, hclgevf_misc_irq_handle, @@ -1485,6 +1535,14 @@ static int hclgevf_pc