aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChien Tin Tung <chien.tin.tung@intel.com>2016-12-21 09:53:46 -0500
committerDoug Ledford <dledford@redhat.com>2016-12-22 11:36:12 -0500
commit61f51b7b20f631ef8fe744bc0412d4eb5194b6a9 (patch)
tree0cd2a30e597dee74e74bd685af593a02f53b77ec
parentfba332b079029c2f4f7e84c1c1cd8e3867310c90 (diff)
i40iw: Set 128B as the only supported RQ WQE size
RQ WQE size other than 128B is not supported. Correct RQ size calculation to use 128B only. Since this breaks ABI, add additional code to provide compatibility with v4 user provider, libi40iw. Signed-off-by: Chien Tin Tung <chien.tin.tung@intel.com> Signed-off-by: Henry Orosco <henry.orosco@intel.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_ctrl.c25
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_puda.c2
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_type.h4
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_ucontext.h4
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_uk.c17
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_user.h4
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_verbs.c21
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_verbs.h1
8 files changed, 53 insertions, 25 deletions
diff --git a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c
index 392f78384a60..98923a8cf86d 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_ctrl.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_ctrl.c
@@ -358,13 +358,16 @@ void i40iw_qp_add_qos(struct i40iw_sc_qp *qp)
358 * @dev: sc device struct 358 * @dev: sc device struct
359 * @pd: sc pd ptr 359 * @pd: sc pd ptr
360 * @pd_id: pd_id for allocated pd 360 * @pd_id: pd_id for allocated pd
361 * @abi_ver: ABI version from user context, -1 if not valid
361 */ 362 */
362static void i40iw_sc_pd_init(struct i40iw_sc_dev *dev, 363static void i40iw_sc_pd_init(struct i40iw_sc_dev *dev,
363 struct i40iw_sc_pd *pd, 364 struct i40iw_sc_pd *pd,
364 u16 pd_id) 365 u16 pd_id,
366 int abi_ver)
365{ 367{
366 pd->size = sizeof(*pd); 368 pd->size = sizeof(*pd);
367 pd->pd_id = pd_id; 369 pd->pd_id = pd_id;
370 pd->abi_ver = abi_ver;
368 pd->dev = dev; 371 pd->dev = dev;
369} 372}
370 373
@@ -2252,6 +2255,7 @@ static enum i40iw_status_code i40iw_sc_qp_init(struct i40iw_sc_qp *qp,
2252 offset); 2255 offset);
2253 2256
2254 info->qp_uk_init_info.wqe_alloc_reg = wqe_alloc_reg; 2257 info->qp_uk_init_info.wqe_alloc_reg = wqe_alloc_reg;
2258 info->qp_uk_init_info.abi_ver = qp->pd->abi_ver;
2255 ret_code = i40iw_qp_uk_init(&qp->qp_uk, &info->qp_uk_init_info); 2259 ret_code = i40iw_qp_uk_init(&qp->qp_uk, &info->qp_uk_init_info);
2256 if (ret_code) 2260 if (ret_code)
2257 return ret_code; 2261 return ret_code;
@@ -2270,10 +2274,21 @@ static enum i40iw_status_code i40iw_sc_qp_init(struct i40iw_sc_qp *qp,
2270 false); 2274 false);
2271 i40iw_debug(qp->dev, I40IW_DEBUG_WQE, "%s: hw_sq_size[%04d] sq_ring.size[%04d]\n", 2275 i40iw_debug(qp->dev, I40IW_DEBUG_WQE, "%s: hw_sq_size[%04d] sq_ring.size[%04d]\n",
2272 __func__, qp->hw_sq_size, qp->qp_uk.sq_ring.size); 2276 __func__, qp->hw_sq_size, qp->qp_uk.sq_ring.size);
2273 ret_code = i40iw_fragcnt_to_wqesize_rq(qp->qp_uk.max_rq_frag_cnt, 2277
2274 &wqe_size); 2278 switch (qp->pd->abi_ver) {
2275 if (ret_code) 2279 case 4:
2276 return ret_code; 2280 ret_code = i40iw_fragcnt_to_wqesize_rq(qp->qp_uk.max_rq_frag_cnt,
2281 &wqe_size);
2282 if (ret_code)
2283 return ret_code;
2284 break;
2285 case 5: /* fallthrough until next ABI version */
2286 default:
2287 if (qp->qp_uk.max_rq_frag_cnt > I40IW_MAX_WQ_FRAGMENT_COUNT)
2288 return I40IW_ERR_INVALID_FRAG_COUNT;
2289 wqe_size = I40IW_MAX_WQE_SIZE_RQ;
2290 break;
2291 }
2277 qp->hw_rq_size = i40iw_get_encoded_wqe_size(qp->qp_uk.rq_size * 2292 qp->hw_rq_size = i40iw_get_encoded_wqe_size(qp->qp_uk.rq_size *
2278 (wqe_size / I40IW_QP_WQE_MIN_SIZE), false); 2293 (wqe_size / I40IW_QP_WQE_MIN_SIZE), false);
2279 i40iw_debug(qp->dev, I40IW_DEBUG_WQE, 2294 i40iw_debug(qp->dev, I40IW_DEBUG_WQE,
diff --git a/drivers/infiniband/hw/i40iw/i40iw_puda.c b/drivers/infiniband/hw/i40iw/i40iw_puda.c
index 449ba8c81ce7..db41ab40da9c 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_puda.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_puda.c
@@ -930,7 +930,7 @@ enum i40iw_status_code i40iw_puda_create_rsrc(struct i40iw_sc_vsi *vsi,
930 INIT_LIST_HEAD(&rsrc->txpend); 930 INIT_LIST_HEAD(&rsrc->txpend);
931 931
932 rsrc->tx_wqe_avail_cnt = info->sq_size - 1; 932 rsrc->tx_wqe_avail_cnt = info->sq_size - 1;
933 dev->iw_pd_ops->pd_init(dev, &rsrc->sc_pd, info->pd_id); 933 dev->iw_pd_ops->pd_init(dev, &rsrc->sc_pd, info->pd_id, -1);
934 rsrc->qp_id = info->qp_id; 934 rsrc->qp_id = info->qp_id;
935 rsrc->cq_id = info->cq_id; 935 rsrc->cq_id = info->cq_id;
936 rsrc->sq_size = info->sq_size; 936 rsrc->sq_size = info->sq_size;
diff --git a/drivers/infiniband/hw/i40iw/i40iw_type.h b/drivers/infiniband/hw/i40iw/i40iw_type.h
index f3f8e9cc3c05..7b76259752b0 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_type.h
+++ b/drivers/infiniband/hw/i40iw/i40iw_type.h
@@ -280,6 +280,7 @@ struct i40iw_sc_pd {
280 u32 size; 280 u32 size;
281 struct i40iw_sc_dev *dev; 281 struct i40iw_sc_dev *dev;
282 u16 pd_id; 282 u16 pd_id;
283 int abi_ver;
283}; 284};
284 285
285struct i40iw_cqp_quanta { 286struct i40iw_cqp_quanta {
@@ -852,6 +853,7 @@ struct i40iw_qp_init_info {
852 u64 host_ctx_pa; 853 u64 host_ctx_pa;
853 u64 q2_pa; 854 u64 q2_pa;
854 u64 shadow_area_pa; 855 u64 shadow_area_pa;
856 int abi_ver;
855 u8 sq_tph_val; 857 u8 sq_tph_val;
856 u8 rq_tph_val; 858 u8 rq_tph_val;
857 u8 type; 859 u8 type;
@@ -1051,7 +1053,7 @@ struct i40iw_aeq_ops {
1051}; 1053};
1052 1054
1053struct i40iw_pd_ops { 1055struct i40iw_pd_ops {
1054 void (*pd_init)(struct i40iw_sc_dev *, struct i40iw_sc_pd *, u16); 1056 void (*pd_init)(struct i40iw_sc_dev *, struct i40iw_sc_pd *, u16, int);
1055}; 1057};
1056 1058
1057struct i40iw_priv_qp_ops { 1059struct i40iw_priv_qp_ops {
diff --git a/drivers/infiniband/hw/i40iw/i40iw_ucontext.h b/drivers/infiniband/hw/i40iw/i40iw_ucontext.h
index 12acd688def4..57d3f1d11ff1 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_ucontext.h
+++ b/drivers/infiniband/hw/i40iw/i40iw_ucontext.h
@@ -39,8 +39,8 @@
39 39
40#include <linux/types.h> 40#include <linux/types.h>
41 41
42#define I40IW_ABI_USERSPACE_VER 4 42#define I40IW_ABI_VER 5
43#define I40IW_ABI_KERNEL_VER 4 43
44struct i40iw_alloc_ucontext_req { 44struct i40iw_alloc_ucontext_req {
45 __u32 reserved32; 45 __u32 reserved32;
46 __u8 userspace_ver; 46 __u8 userspace_ver;
diff --git a/drivers/infiniband/hw/i40iw/i40iw_uk.c b/drivers/infiniband/hw/i40iw/i40iw_uk.c
index 4376cd628774..2800f796271c 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_uk.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_uk.c
@@ -966,10 +966,6 @@ enum i40iw_status_code i40iw_qp_uk_init(struct i40iw_qp_uk *qp,
966 if (ret_code) 966 if (ret_code)
967 return ret_code; 967 return ret_code;
968 968
969 ret_code = i40iw_get_wqe_shift(info->rq_size, info->max_rq_frag_cnt, 0, &rqshift);
970 if (ret_code)
971 return ret_code;
972
973 qp->sq_base = info->sq; 969 qp->sq_base = info->sq;
974 qp->rq_base = info->rq; 970 qp->rq_base = info->rq;
975 qp->shadow_area = info->shadow_area; 971 qp->shadow_area = info->shadow_area;
@@ -998,8 +994,19 @@ enum i40iw_status_code i40iw_qp_uk_init(struct i40iw_qp_uk *qp,
998 if (!qp->use_srq) { 994 if (!qp->use_srq) {
999 qp->rq_size = info->rq_size; 995 qp->rq_size = info->rq_size;
1000 qp->max_rq_frag_cnt = info->max_rq_frag_cnt; 996 qp->max_rq_frag_cnt = info->max_rq_frag_cnt;
1001 qp->rq_wqe_size = rqshift;
1002 I40IW_RING_INIT(qp->rq_ring, qp->rq_size); 997 I40IW_RING_INIT(qp->rq_ring, qp->rq_size);
998 switch (info->abi_ver) {
999 case 4:
1000 ret_code = i40iw_get_wqe_shift(info->rq_size, info->max_rq_frag_cnt, 0, &rqshift);
1001 if (ret_code)
1002 return ret_code;
1003 break;
1004 case 5: /* fallthrough until next ABI version */
1005 default:
1006 rqshift = I40IW_MAX_RQ_WQE_SHIFT;
1007 break;
1008 }
1009 qp->rq_wqe_size = rqshift;
1003 qp->rq_wqe_size_multiplier = 4 << rqshift; 1010 qp->rq_wqe_size_multiplier = 4 << rqshift;
1004 } 1011 }
1005 qp->ops = iw_qp_uk_ops; 1012 qp->ops = iw_qp_uk_ops;
diff --git a/drivers/infiniband/hw/i40iw/i40iw_user.h b/drivers/infiniband/hw/i40iw/i40iw_user.h
index 80d9f464f65e..84be6f13b9c5 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_user.h
+++ b/drivers/infiniband/hw/i40iw/i40iw_user.h
@@ -76,6 +76,7 @@ enum i40iw_device_capabilities_const {
76 I40IW_MAX_ORD_SIZE = 127, 76 I40IW_MAX_ORD_SIZE = 127,
77 I40IW_MAX_WQ_ENTRIES = 2048, 77 I40IW_MAX_WQ_ENTRIES = 2048,
78 I40IW_Q2_BUFFER_SIZE = (248 + 100), 78 I40IW_Q2_BUFFER_SIZE = (248 + 100),
79 I40IW_MAX_WQE_SIZE_RQ = 128,
79 I40IW_QP_CTX_SIZE = 248, 80 I40IW_QP_CTX_SIZE = 248,
80 I40IW_MAX_PDS = 32768 81 I40IW_MAX_PDS = 32768
81}; 82};
@@ -97,6 +98,7 @@ enum i40iw_device_capabilities_const {
97#define i40iw_address_list u64 * 98#define i40iw_address_list u64 *
98 99
99#define I40IW_MAX_MR_SIZE 0x10000000000L 100#define I40IW_MAX_MR_SIZE 0x10000000000L
101#define I40IW_MAX_RQ_WQE_SHIFT 2
100 102
101struct i40iw_qp_uk; 103struct i40iw_qp_uk;
102struct i40iw_cq_uk; 104struct i40iw_cq_uk;
@@ -405,7 +407,7 @@ struct i40iw_qp_uk_init_info {
405 u32 max_sq_frag_cnt; 407 u32 max_sq_frag_cnt;
406 u32 max_rq_frag_cnt; 408 u32 max_rq_frag_cnt;
407 u32 max_inline_data; 409 u32 max_inline_data;
408 410 int abi_ver;
409}; 411};
410 412
411struct i40iw_cq_uk_init_info { 413struct i40iw_cq_uk_init_info {
diff --git a/drivers/infiniband/hw/i40iw/i40iw_verbs.c b/drivers/infiniband/hw/i40iw/i40iw_verbs.c
index 7368a50bbdaa..29e97df9e1a7 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_verbs.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_verbs.c
@@ -145,9 +145,8 @@ static struct ib_ucontext *i40iw_alloc_ucontext(struct ib_device *ibdev,
145 if (ib_copy_from_udata(&req, udata, sizeof(req))) 145 if (ib_copy_from_udata(&req, udata, sizeof(req)))
146 return ERR_PTR(-EINVAL); 146 return ERR_PTR(-EINVAL);
147 147
148 if (req.userspace_ver != I40IW_ABI_USERSPACE_VER) { 148 if (req.userspace_ver < 4 || req.userspace_ver > I40IW_ABI_VER) {
149 i40iw_pr_err("Invalid userspace driver version detected. Detected version %d, should be %d\n", 149 i40iw_pr_err("Unsupported provider library version %u.\n", req.userspace_ver);
150 req.userspace_ver, I40IW_ABI_USERSPACE_VER);
151 return ERR_PTR(-EINVAL); 150 return ERR_PTR(-EINVAL);
152 } 151 }
153 152
@@ -155,13 +154,14 @@ static struct ib_ucontext *i40iw_alloc_ucontext(struct ib_device *ibdev,
155 uresp.max_qps = iwdev->max_qp; 154 uresp.max_qps = iwdev->max_qp;
156 uresp.max_pds = iwdev->max_pd; 155 uresp.max_pds = iwdev->max_pd;
157 uresp.wq_size = iwdev->max_qp_wr * 2; 156 uresp.wq_size = iwdev->max_qp_wr * 2;
158 uresp.kernel_ver = I40IW_ABI_KERNEL_VER; 157 uresp.kernel_ver = req.userspace_ver;
159 158
160 ucontext = kzalloc(sizeof(*ucontext), GFP_KERNEL); 159 ucontext = kzalloc(sizeof(*ucontext), GFP_KERNEL);
161 if (!ucontext) 160 if (!ucontext)
162 return ERR_PTR(-ENOMEM); 161 return ERR_PTR(-ENOMEM);
163 162
164 ucontext->iwdev = iwdev; 163 ucontext->iwdev = iwdev;
164 ucontext->abi_ver = req.userspace_ver;
165 165
166 if (ib_copy_to_udata(udata, &uresp, sizeof(uresp))) { 166 if (ib_copy_to_udata(udata, &uresp, sizeof(uresp))) {
167 kfree(ucontext); 167 kfree(ucontext);
@@ -333,6 +333,7 @@ static struct ib_pd *i40iw_alloc_pd(struct ib_device *ibdev,
333 struct i40iw_sc_dev *dev = &iwdev->sc_dev; 333 struct i40iw_sc_dev *dev = &iwdev->sc_dev;
334 struct i40iw_alloc_pd_resp uresp; 334 struct i40iw_alloc_pd_resp uresp;
335 struct i40iw_sc_pd *sc_pd; 335 struct i40iw_sc_pd *sc_pd;
336 struct i40iw_ucontext *ucontext;
336 u32 pd_id = 0; 337 u32 pd_id = 0;
337 int err; 338 int err;
338 339
@@ -353,15 +354,18 @@ static struct ib_pd *i40iw_alloc_pd(struct ib_device *ibdev,
353 } 354 }
354 355
355 sc_pd = &iwpd->sc_pd; 356 sc_pd = &iwpd->sc_pd;
356 dev->iw_pd_ops->pd_init(dev, sc_pd, pd_id);
357 357
358 if (context) { 358 if (context) {
359 ucontext = to_ucontext(context);
360 dev->iw_pd_ops->pd_init(dev, sc_pd, pd_id, ucontext->abi_ver);
359 memset(&uresp, 0, sizeof(uresp)); 361 memset(&uresp, 0, sizeof(uresp));
360 uresp.pd_id = pd_id; 362 uresp.pd_id = pd_id;
361 if (ib_copy_to_udata(udata, &uresp, sizeof(uresp))) { 363 if (ib_copy_to_udata(udata, &uresp, sizeof(uresp))) {
362 err = -EFAULT; 364 err = -EFAULT;
363 goto error; 365 goto error;
364 } 366 }
367 } else {
368 dev->iw_pd_ops->pd_init(dev, sc_pd, pd_id, -1);
365 } 369 }
366 370
367 i40iw_add_pdusecount(iwpd); 371 i40iw_add_pdusecount(iwpd);
@@ -518,7 +522,7 @@ static int i40iw_setup_kmode_qp(struct i40iw_device *iwdev,
518 struct i40iw_dma_mem *mem = &iwqp->kqp.dma_mem; 522 struct i40iw_dma_mem *mem = &iwqp->kqp.dma_mem;
519 u32 sqdepth, rqdepth; 523 u32 sqdepth, rqdepth;
520 u32 sq_size, rq_size; 524 u32 sq_size, rq_size;
521 u8 sqshift, rqshift; 525 u8 sqshift;
522 u32 size; 526 u32 size;
523 enum i40iw_status_code status; 527 enum i40iw_status_code status;
524 struct i40iw_qp_uk_init_info *ukinfo = &info->qp_uk_init_info; 528 struct i40iw_qp_uk_init_info *ukinfo = &info->qp_uk_init_info;
@@ -527,14 +531,11 @@ static int i40iw_setup_kmode_qp(struct i40iw_device *iwdev,
527 rq_size = i40iw_qp_roundup(ukinfo->rq_size + 1); 531 rq_size = i40iw_qp_roundup(ukinfo->rq_size + 1);
528 532
529 status = i40iw_get_wqe_shift(sq_size, ukinfo->max_sq_frag_cnt, ukinfo->max_inline_data, &sqshift); 533 status = i40iw_get_wqe_shift(sq_size, ukinfo->max_sq_frag_cnt, ukinfo->max_inline_data, &sqshift);
530 if (!status)
531 status = i40iw_get_wqe_shift(rq_size, ukinfo->max_rq_frag_cnt, 0, &rqshift);
532
533 if (status) 534 if (status)
534 return -ENOMEM; 535 return -ENOMEM;
535 536
536 sqdepth = sq_size << sqshift; 537 sqdepth = sq_size << sqshift;
537 rqdepth = rq_size << rqshift; 538 rqdepth = rq_size << I40IW_MAX_RQ_WQE_SHIFT;
538 539
539 size = sqdepth * sizeof(struct i40iw_sq_uk_wr_trk_info) + (rqdepth << 3); 540 size = sqdepth * sizeof(struct i40iw_sq_uk_wr_trk_info) + (rqdepth << 3);
540 iwqp->kqp.wrid_mem = kzalloc(size, GFP_KERNEL); 541 iwqp->kqp.wrid_mem = kzalloc(size, GFP_KERNEL);
diff --git a/drivers/infiniband/hw/i40iw/i40iw_verbs.h b/drivers/infiniband/hw/i40iw/i40iw_verbs.h
index 6549c939500f..07c3fec77de6 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_verbs.h
+++ b/drivers/infiniband/hw/i40iw/i40iw_verbs.h
@@ -42,6 +42,7 @@ struct i40iw_ucontext {
42 spinlock_t cq_reg_mem_list_lock; /* memory list for cq's */ 42 spinlock_t cq_reg_mem_list_lock; /* memory list for cq's */
43 struct list_head qp_reg_mem_list; 43 struct list_head qp_reg_mem_list;
44 spinlock_t qp_reg_mem_list_lock; /* memory list for qp's */ 44 spinlock_t qp_reg_mem_list_lock; /* memory list for qp's */
45 int abi_ver;
45}; 46};
46 47
47struct i40iw_pd { 48struct i40iw_pd {