forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-10-09 244b2c5ca8b14627e4a17755e5922221e121c771
kernel/drivers/infiniband/core/verbs.c
....@@ -50,8 +50,10 @@
5050 #include <rdma/ib_cache.h>
5151 #include <rdma/ib_addr.h>
5252 #include <rdma/rw.h>
53
+#include <rdma/lag.h>
5354
5455 #include "core_priv.h"
56
+#include <trace/events/rdma_core.h>
5557
5658 static int ib_resolve_eth_dmac(struct ib_device *device,
5759 struct rdma_ah_attr *ah_attr);
....@@ -141,6 +143,10 @@
141143 case IB_RATE_100_GBPS: return 40;
142144 case IB_RATE_200_GBPS: return 80;
143145 case IB_RATE_300_GBPS: return 120;
146
+ case IB_RATE_28_GBPS: return 11;
147
+ case IB_RATE_50_GBPS: return 20;
148
+ case IB_RATE_400_GBPS: return 160;
149
+ case IB_RATE_600_GBPS: return 240;
144150 default: return -1;
145151 }
146152 }
....@@ -166,6 +172,10 @@
166172 case 40: return IB_RATE_100_GBPS;
167173 case 80: return IB_RATE_200_GBPS;
168174 case 120: return IB_RATE_300_GBPS;
175
+ case 11: return IB_RATE_28_GBPS;
176
+ case 20: return IB_RATE_50_GBPS;
177
+ case 160: return IB_RATE_400_GBPS;
178
+ case 240: return IB_RATE_600_GBPS;
169179 default: return IB_RATE_PORT_CURRENT;
170180 }
171181 }
....@@ -191,13 +201,17 @@
191201 case IB_RATE_100_GBPS: return 103125;
192202 case IB_RATE_200_GBPS: return 206250;
193203 case IB_RATE_300_GBPS: return 309375;
204
+ case IB_RATE_28_GBPS: return 28125;
205
+ case IB_RATE_50_GBPS: return 53125;
206
+ case IB_RATE_400_GBPS: return 425000;
207
+ case IB_RATE_600_GBPS: return 637500;
194208 default: return -1;
195209 }
196210 }
197211 EXPORT_SYMBOL(ib_rate_to_mbps);
198212
199213 __attribute_const__ enum rdma_transport_type
200
-rdma_node_get_transport(enum rdma_node_type node_type)
214
+rdma_node_get_transport(unsigned int node_type)
201215 {
202216
203217 if (node_type == RDMA_NODE_USNIC)
....@@ -206,6 +220,8 @@
206220 return RDMA_TRANSPORT_USNIC_UDP;
207221 if (node_type == RDMA_NODE_RNIC)
208222 return RDMA_TRANSPORT_IWARP;
223
+ if (node_type == RDMA_NODE_UNSPECIFIED)
224
+ return RDMA_TRANSPORT_UNSPECIFIED;
209225
210226 return RDMA_TRANSPORT_IB;
211227 }
....@@ -214,8 +230,8 @@
214230 enum rdma_link_layer rdma_port_get_link_layer(struct ib_device *device, u8 port_num)
215231 {
216232 enum rdma_transport_type lt;
217
- if (device->get_link_layer)
218
- return device->get_link_layer(device, port_num);
233
+ if (device->ops.get_link_layer)
234
+ return device->ops.get_link_layer(device, port_num);
219235
220236 lt = rdma_node_get_transport(device->node_type);
221237 if (lt == RDMA_TRANSPORT_IB)
....@@ -230,6 +246,8 @@
230246 /**
231247 * ib_alloc_pd - Allocates an unused protection domain.
232248 * @device: The device on which to allocate the protection domain.
249
+ * @flags: protection domain flags
250
+ * @caller: caller's build-time module name
233251 *
234252 * A protection domain object provides an association between QPs, shared
235253 * receive queues, address handles, memory regions, and memory windows.
....@@ -242,16 +260,28 @@
242260 {
243261 struct ib_pd *pd;
244262 int mr_access_flags = 0;
263
+ int ret;
245264
246
- pd = device->alloc_pd(device, NULL, NULL);
247
- if (IS_ERR(pd))
248
- return pd;
265
+ pd = rdma_zalloc_drv_obj(device, ib_pd);
266
+ if (!pd)
267
+ return ERR_PTR(-ENOMEM);
249268
250269 pd->device = device;
251270 pd->uobject = NULL;
252271 pd->__internal_mr = NULL;
253272 atomic_set(&pd->usecnt, 0);
254273 pd->flags = flags;
274
+
275
+ rdma_restrack_new(&pd->res, RDMA_RESTRACK_PD);
276
+ rdma_restrack_set_name(&pd->res, caller);
277
+
278
+ ret = device->ops.alloc_pd(pd, NULL);
279
+ if (ret) {
280
+ rdma_restrack_put(&pd->res);
281
+ kfree(pd);
282
+ return ERR_PTR(ret);
283
+ }
284
+ rdma_restrack_add(&pd->res);
255285
256286 if (device->attrs.device_cap_flags & IB_DEVICE_LOCAL_DMA_LKEY)
257287 pd->local_dma_lkey = device->local_dma_lkey;
....@@ -263,14 +293,10 @@
263293 mr_access_flags |= IB_ACCESS_REMOTE_READ | IB_ACCESS_REMOTE_WRITE;
264294 }
265295
266
- pd->res.type = RDMA_RESTRACK_PD;
267
- pd->res.kern_name = caller;
268
- rdma_restrack_add(&pd->res);
269
-
270296 if (mr_access_flags) {
271297 struct ib_mr *mr;
272298
273
- mr = pd->device->get_dma_mr(pd, mr_access_flags);
299
+ mr = pd->device->ops.get_dma_mr(pd, mr_access_flags);
274300 if (IS_ERR(mr)) {
275301 ib_dealloc_pd(pd);
276302 return ERR_CAST(mr);
....@@ -278,6 +304,7 @@
278304
279305 mr->device = pd->device;
280306 mr->pd = pd;
307
+ mr->type = IB_MR_TYPE_DMA;
281308 mr->uobject = NULL;
282309 mr->need_inval = false;
283310
....@@ -295,19 +322,20 @@
295322 EXPORT_SYMBOL(__ib_alloc_pd);
296323
297324 /**
298
- * ib_dealloc_pd - Deallocates a protection domain.
325
+ * ib_dealloc_pd_user - Deallocates a protection domain.
299326 * @pd: The protection domain to deallocate.
327
+ * @udata: Valid user data or NULL for kernel object
300328 *
301329 * It is an error to call this function while any resources in the pd still
302330 * exist. The caller is responsible to synchronously destroy them and
303331 * guarantee no new allocations will happen.
304332 */
305
-void ib_dealloc_pd(struct ib_pd *pd)
333
+int ib_dealloc_pd_user(struct ib_pd *pd, struct ib_udata *udata)
306334 {
307335 int ret;
308336
309337 if (pd->__internal_mr) {
310
- ret = pd->device->dereg_mr(pd->__internal_mr);
338
+ ret = pd->device->ops.dereg_mr(pd->__internal_mr, NULL);
311339 WARN_ON(ret);
312340 pd->__internal_mr = NULL;
313341 }
....@@ -316,13 +344,15 @@
316344 requires the caller to guarantee we can't race here. */
317345 WARN_ON(atomic_read(&pd->usecnt));
318346
347
+ ret = pd->device->ops.dealloc_pd(pd, udata);
348
+ if (ret)
349
+ return ret;
350
+
319351 rdma_restrack_del(&pd->res);
320
- /* Making delalloc_pd a void return is a WIP, no driver should return
321
- an error here. */
322
- ret = pd->device->dealloc_pd(pd);
323
- WARN_ONCE(ret, "Infiniband HW driver failed dealloc_pd");
352
+ kfree(pd);
353
+ return ret;
324354 }
325
-EXPORT_SYMBOL(ib_dealloc_pd);
355
+EXPORT_SYMBOL(ib_dealloc_pd_user);
326356
327357 /* Address handles */
328358
....@@ -475,25 +505,43 @@
475505
476506 static struct ib_ah *_rdma_create_ah(struct ib_pd *pd,
477507 struct rdma_ah_attr *ah_attr,
478
- struct ib_udata *udata)
508
+ u32 flags,
509
+ struct ib_udata *udata,
510
+ struct net_device *xmit_slave)
479511 {
512
+ struct rdma_ah_init_attr init_attr = {};
513
+ struct ib_device *device = pd->device;
480514 struct ib_ah *ah;
515
+ int ret;
481516
482
- if (!pd->device->create_ah)
517
+ might_sleep_if(flags & RDMA_CREATE_AH_SLEEPABLE);
518
+
519
+ if (!device->ops.create_ah)
483520 return ERR_PTR(-EOPNOTSUPP);
484521
485
- ah = pd->device->create_ah(pd, ah_attr, udata);
522
+ ah = rdma_zalloc_drv_obj_gfp(
523
+ device, ib_ah,
524
+ (flags & RDMA_CREATE_AH_SLEEPABLE) ? GFP_KERNEL : GFP_ATOMIC);
525
+ if (!ah)
526
+ return ERR_PTR(-ENOMEM);
486527
487
- if (!IS_ERR(ah)) {
488
- ah->device = pd->device;
489
- ah->pd = pd;
490
- ah->uobject = NULL;
491
- ah->type = ah_attr->type;
492
- ah->sgid_attr = rdma_update_sgid_attr(ah_attr, NULL);
528
+ ah->device = device;
529
+ ah->pd = pd;
530
+ ah->type = ah_attr->type;
531
+ ah->sgid_attr = rdma_update_sgid_attr(ah_attr, NULL);
532
+ init_attr.ah_attr = ah_attr;
533
+ init_attr.flags = flags;
534
+ init_attr.xmit_slave = xmit_slave;
493535
494
- atomic_inc(&pd->usecnt);
536
+ ret = device->ops.create_ah(ah, &init_attr, udata);
537
+ if (ret) {
538
+ if (ah->sgid_attr)
539
+ rdma_put_gid_attr(ah->sgid_attr);
540
+ kfree(ah);
541
+ return ERR_PTR(ret);
495542 }
496543
544
+ atomic_inc(&pd->usecnt);
497545 return ah;
498546 }
499547
....@@ -502,23 +550,32 @@
502550 * given address vector.
503551 * @pd: The protection domain associated with the address handle.
504552 * @ah_attr: The attributes of the address vector.
553
+ * @flags: Create address handle flags (see enum rdma_create_ah_flags).
505554 *
506555 * It returns 0 on success and returns appropriate error code on error.
507556 * The address handle is used to reference a local or global destination
508557 * in all UD QP post sends.
509558 */
510
-struct ib_ah *rdma_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr)
559
+struct ib_ah *rdma_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr,
560
+ u32 flags)
511561 {
512562 const struct ib_gid_attr *old_sgid_attr;
563
+ struct net_device *slave;
513564 struct ib_ah *ah;
514565 int ret;
515566
516567 ret = rdma_fill_sgid_attr(pd->device, ah_attr, &old_sgid_attr);
517568 if (ret)
518569 return ERR_PTR(ret);
519
-
520
- ah = _rdma_create_ah(pd, ah_attr, NULL);
521
-
570
+ slave = rdma_lag_get_ah_roce_slave(pd->device, ah_attr,
571
+ (flags & RDMA_CREATE_AH_SLEEPABLE) ?
572
+ GFP_KERNEL : GFP_ATOMIC);
573
+ if (IS_ERR(slave)) {
574
+ rdma_unfill_sgid_attr(ah_attr, old_sgid_attr);
575
+ return (void *)slave;
576
+ }
577
+ ah = _rdma_create_ah(pd, ah_attr, flags, NULL, slave);
578
+ rdma_lag_put_ah_roce_slave(slave);
522579 rdma_unfill_sgid_attr(ah_attr, old_sgid_attr);
523580 return ah;
524581 }
....@@ -557,7 +614,8 @@
557614 }
558615 }
559616
560
- ah = _rdma_create_ah(pd, ah_attr, udata);
617
+ ah = _rdma_create_ah(pd, ah_attr, RDMA_CREATE_AH_SLEEPABLE,
618
+ udata, NULL);
561619
562620 out:
563621 rdma_unfill_sgid_attr(ah_attr, old_sgid_attr);
....@@ -628,16 +686,17 @@
628686 void *context)
629687 {
630688 struct find_gid_index_context *ctx = context;
689
+ u16 vlan_id = 0xffff;
690
+ int ret;
631691
632692 if (ctx->gid_type != gid_attr->gid_type)
633693 return false;
634694
635
- if ((!!(ctx->vlan_id != 0xffff) == !is_vlan_dev(gid_attr->ndev)) ||
636
- (is_vlan_dev(gid_attr->ndev) &&
637
- vlan_dev_vlan_id(gid_attr->ndev) != ctx->vlan_id))
695
+ ret = rdma_read_gid_l2_fields(gid_attr, &vlan_id, NULL);
696
+ if (ret)
638697 return false;
639698
640
- return true;
699
+ return ctx->vlan_id == vlan_id;
641700 }
642701
643702 static const struct ib_gid_attr *
....@@ -676,7 +735,7 @@
676735 (struct in6_addr *)dgid);
677736 return 0;
678737 } else if (net_type == RDMA_NETWORK_IPV6 ||
679
- net_type == RDMA_NETWORK_IB) {
738
+ net_type == RDMA_NETWORK_IB || RDMA_NETWORK_ROCE_V1) {
680739 *dgid = hdr->ibgrh.dgid;
681740 *sgid = hdr->ibgrh.sgid;
682741 return 0;
....@@ -710,7 +769,7 @@
710769
711770 ret = rdma_addr_find_l2_eth_by_grh(&sgid_attr->gid, &grh->dgid,
712771 ah_attr->roce.dmac,
713
- sgid_attr->ndev, &hop_limit);
772
+ sgid_attr, &hop_limit);
714773
715774 grh->hop_limit = hop_limit;
716775 return ret;
....@@ -869,7 +928,7 @@
869928 if (ret)
870929 return ERR_PTR(ret);
871930
872
- ah = rdma_create_ah(pd, &ah_attr);
931
+ ah = rdma_create_ah(pd, &ah_attr, RDMA_CREATE_AH_SLEEPABLE);
873932
874933 rdma_destroy_ah_attr(&ah_attr);
875934 return ah;
....@@ -888,8 +947,8 @@
888947 if (ret)
889948 return ret;
890949
891
- ret = ah->device->modify_ah ?
892
- ah->device->modify_ah(ah, ah_attr) :
950
+ ret = ah->device->ops.modify_ah ?
951
+ ah->device->ops.modify_ah(ah, ah_attr) :
893952 -EOPNOTSUPP;
894953
895954 ah->sgid_attr = rdma_update_sgid_attr(ah_attr, ah->sgid_attr);
....@@ -902,113 +961,135 @@
902961 {
903962 ah_attr->grh.sgid_attr = NULL;
904963
905
- return ah->device->query_ah ?
906
- ah->device->query_ah(ah, ah_attr) :
964
+ return ah->device->ops.query_ah ?
965
+ ah->device->ops.query_ah(ah, ah_attr) :
907966 -EOPNOTSUPP;
908967 }
909968 EXPORT_SYMBOL(rdma_query_ah);
910969
911
-int rdma_destroy_ah(struct ib_ah *ah)
970
+int rdma_destroy_ah_user(struct ib_ah *ah, u32 flags, struct ib_udata *udata)
912971 {
913972 const struct ib_gid_attr *sgid_attr = ah->sgid_attr;
914973 struct ib_pd *pd;
915974 int ret;
916975
917
- pd = ah->pd;
918
- ret = ah->device->destroy_ah(ah);
919
- if (!ret) {
920
- atomic_dec(&pd->usecnt);
921
- if (sgid_attr)
922
- rdma_put_gid_attr(sgid_attr);
923
- }
976
+ might_sleep_if(flags & RDMA_DESTROY_AH_SLEEPABLE);
924977
978
+ pd = ah->pd;
979
+
980
+ ret = ah->device->ops.destroy_ah(ah, flags);
981
+ if (ret)
982
+ return ret;
983
+
984
+ atomic_dec(&pd->usecnt);
985
+ if (sgid_attr)
986
+ rdma_put_gid_attr(sgid_attr);
987
+
988
+ kfree(ah);
925989 return ret;
926990 }
927
-EXPORT_SYMBOL(rdma_destroy_ah);
991
+EXPORT_SYMBOL(rdma_destroy_ah_user);
928992
929993 /* Shared receive queues */
930994
931
-struct ib_srq *ib_create_srq(struct ib_pd *pd,
932
- struct ib_srq_init_attr *srq_init_attr)
995
+/**
996
+ * ib_create_srq_user - Creates a SRQ associated with the specified protection
997
+ * domain.
998
+ * @pd: The protection domain associated with the SRQ.
999
+ * @srq_init_attr: A list of initial attributes required to create the
1000
+ * SRQ. If SRQ creation succeeds, then the attributes are updated to
1001
+ * the actual capabilities of the created SRQ.
1002
+ * @uobject: uobject pointer if this is not a kernel SRQ
1003
+ * @udata: udata pointer if this is not a kernel SRQ
1004
+ *
1005
+ * srq_attr->max_wr and srq_attr->max_sge are read the determine the
1006
+ * requested size of the SRQ, and set to the actual values allocated
1007
+ * on return. If ib_create_srq() succeeds, then max_wr and max_sge
1008
+ * will always be at least as large as the requested values.
1009
+ */
1010
+struct ib_srq *ib_create_srq_user(struct ib_pd *pd,
1011
+ struct ib_srq_init_attr *srq_init_attr,
1012
+ struct ib_usrq_object *uobject,
1013
+ struct ib_udata *udata)
9331014 {
9341015 struct ib_srq *srq;
1016
+ int ret;
9351017
936
- if (!pd->device->create_srq)
937
- return ERR_PTR(-EOPNOTSUPP);
1018
+ srq = rdma_zalloc_drv_obj(pd->device, ib_srq);
1019
+ if (!srq)
1020
+ return ERR_PTR(-ENOMEM);
9381021
939
- srq = pd->device->create_srq(pd, srq_init_attr, NULL);
1022
+ srq->device = pd->device;
1023
+ srq->pd = pd;
1024
+ srq->event_handler = srq_init_attr->event_handler;
1025
+ srq->srq_context = srq_init_attr->srq_context;
1026
+ srq->srq_type = srq_init_attr->srq_type;
1027
+ srq->uobject = uobject;
9401028
941
- if (!IS_ERR(srq)) {
942
- srq->device = pd->device;
943
- srq->pd = pd;
944
- srq->uobject = NULL;
945
- srq->event_handler = srq_init_attr->event_handler;
946
- srq->srq_context = srq_init_attr->srq_context;
947
- srq->srq_type = srq_init_attr->srq_type;
948
- if (ib_srq_has_cq(srq->srq_type)) {
949
- srq->ext.cq = srq_init_attr->ext.cq;
950
- atomic_inc(&srq->ext.cq->usecnt);
951
- }
952
- if (srq->srq_type == IB_SRQT_XRC) {
953
- srq->ext.xrc.xrcd = srq_init_attr->ext.xrc.xrcd;
954
- atomic_inc(&srq->ext.xrc.xrcd->usecnt);
955
- }
956
- atomic_inc(&pd->usecnt);
957
- atomic_set(&srq->usecnt, 0);
1029
+ if (ib_srq_has_cq(srq->srq_type)) {
1030
+ srq->ext.cq = srq_init_attr->ext.cq;
1031
+ atomic_inc(&srq->ext.cq->usecnt);
1032
+ }
1033
+ if (srq->srq_type == IB_SRQT_XRC) {
1034
+ srq->ext.xrc.xrcd = srq_init_attr->ext.xrc.xrcd;
1035
+ atomic_inc(&srq->ext.xrc.xrcd->usecnt);
1036
+ }
1037
+ atomic_inc(&pd->usecnt);
1038
+
1039
+ ret = pd->device->ops.create_srq(srq, srq_init_attr, udata);
1040
+ if (ret) {
1041
+ atomic_dec(&srq->pd->usecnt);
1042
+ if (srq->srq_type == IB_SRQT_XRC)
1043
+ atomic_dec(&srq->ext.xrc.xrcd->usecnt);
1044
+ if (ib_srq_has_cq(srq->srq_type))
1045
+ atomic_dec(&srq->ext.cq->usecnt);
1046
+ kfree(srq);
1047
+ return ERR_PTR(ret);
9581048 }
9591049
9601050 return srq;
9611051 }
962
-EXPORT_SYMBOL(ib_create_srq);
1052
+EXPORT_SYMBOL(ib_create_srq_user);
9631053
9641054 int ib_modify_srq(struct ib_srq *srq,
9651055 struct ib_srq_attr *srq_attr,
9661056 enum ib_srq_attr_mask srq_attr_mask)
9671057 {
968
- return srq->device->modify_srq ?
969
- srq->device->modify_srq(srq, srq_attr, srq_attr_mask, NULL) :
970
- -EOPNOTSUPP;
1058
+ return srq->device->ops.modify_srq ?
1059
+ srq->device->ops.modify_srq(srq, srq_attr, srq_attr_mask,
1060
+ NULL) : -EOPNOTSUPP;
9711061 }
9721062 EXPORT_SYMBOL(ib_modify_srq);
9731063
9741064 int ib_query_srq(struct ib_srq *srq,
9751065 struct ib_srq_attr *srq_attr)
9761066 {
977
- return srq->device->query_srq ?
978
- srq->device->query_srq(srq, srq_attr) : -EOPNOTSUPP;
1067
+ return srq->device->ops.query_srq ?
1068
+ srq->device->ops.query_srq(srq, srq_attr) : -EOPNOTSUPP;
9791069 }
9801070 EXPORT_SYMBOL(ib_query_srq);
9811071
982
-int ib_destroy_srq(struct ib_srq *srq)
1072
+int ib_destroy_srq_user(struct ib_srq *srq, struct ib_udata *udata)
9831073 {
984
- struct ib_pd *pd;
985
- enum ib_srq_type srq_type;
986
- struct ib_xrcd *uninitialized_var(xrcd);
987
- struct ib_cq *uninitialized_var(cq);
9881074 int ret;
9891075
9901076 if (atomic_read(&srq->usecnt))
9911077 return -EBUSY;
9921078
993
- pd = srq->pd;
994
- srq_type = srq->srq_type;
995
- if (ib_srq_has_cq(srq_type))
996
- cq = srq->ext.cq;
997
- if (srq_type == IB_SRQT_XRC)
998
- xrcd = srq->ext.xrc.xrcd;
1079
+ ret = srq->device->ops.destroy_srq(srq, udata);
1080
+ if (ret)
1081
+ return ret;
9991082
1000
- ret = srq->device->destroy_srq(srq);
1001
- if (!ret) {
1002
- atomic_dec(&pd->usecnt);
1003
- if (srq_type == IB_SRQT_XRC)
1004
- atomic_dec(&xrcd->usecnt);
1005
- if (ib_srq_has_cq(srq_type))
1006
- atomic_dec(&cq->usecnt);
1007
- }
1083
+ atomic_dec(&srq->pd->usecnt);
1084
+ if (srq->srq_type == IB_SRQT_XRC)
1085
+ atomic_dec(&srq->ext.xrc.xrcd->usecnt);
1086
+ if (ib_srq_has_cq(srq->srq_type))
1087
+ atomic_dec(&srq->ext.cq->usecnt);
1088
+ kfree(srq);
10081089
10091090 return ret;
10101091 }
1011
-EXPORT_SYMBOL(ib_destroy_srq);
1092
+EXPORT_SYMBOL(ib_destroy_srq_user);
10121093
10131094 /* Queue pairs */
10141095
....@@ -1017,18 +1098,11 @@
10171098 struct ib_qp *qp = context;
10181099 unsigned long flags;
10191100
1020
- spin_lock_irqsave(&qp->device->event_handler_lock, flags);
1101
+ spin_lock_irqsave(&qp->device->qp_open_list_lock, flags);
10211102 list_for_each_entry(event->element.qp, &qp->open_list, open_list)
10221103 if (event->element.qp->event_handler)
10231104 event->element.qp->event_handler(event, event->element.qp->qp_context);
1024
- spin_unlock_irqrestore(&qp->device->event_handler_lock, flags);
1025
-}
1026
-
1027
-static void __ib_insert_xrcd_qp(struct ib_xrcd *xrcd, struct ib_qp *qp)
1028
-{
1029
- mutex_lock(&xrcd->tgt_qp_mutex);
1030
- list_add(&qp->xrcd_list, &xrcd->tgt_qp_list);
1031
- mutex_unlock(&xrcd->tgt_qp_mutex);
1105
+ spin_unlock_irqrestore(&qp->device->qp_open_list_lock, flags);
10321106 }
10331107
10341108 static struct ib_qp *__ib_open_qp(struct ib_qp *real_qp,
....@@ -1058,9 +1132,9 @@
10581132 qp->qp_num = real_qp->qp_num;
10591133 qp->qp_type = real_qp->qp_type;
10601134
1061
- spin_lock_irqsave(&real_qp->device->event_handler_lock, flags);
1135
+ spin_lock_irqsave(&real_qp->device->qp_open_list_lock, flags);
10621136 list_add(&qp->open_list, &real_qp->open_list);
1063
- spin_unlock_irqrestore(&real_qp->device->event_handler_lock, flags);
1137
+ spin_unlock_irqrestore(&real_qp->device->qp_open_list_lock, flags);
10641138
10651139 return qp;
10661140 }
....@@ -1073,24 +1147,24 @@
10731147 if (qp_open_attr->qp_type != IB_QPT_XRC_TGT)
10741148 return ERR_PTR(-EINVAL);
10751149
1076
- qp = ERR_PTR(-EINVAL);
1077
- mutex_lock(&xrcd->tgt_qp_mutex);
1078
- list_for_each_entry(real_qp, &xrcd->tgt_qp_list, xrcd_list) {
1079
- if (real_qp->qp_num == qp_open_attr->qp_num) {
1080
- qp = __ib_open_qp(real_qp, qp_open_attr->event_handler,
1081
- qp_open_attr->qp_context);
1082
- break;
1083
- }
1150
+ down_read(&xrcd->tgt_qps_rwsem);
1151
+ real_qp = xa_load(&xrcd->tgt_qps, qp_open_attr->qp_num);
1152
+ if (!real_qp) {
1153
+ up_read(&xrcd->tgt_qps_rwsem);
1154
+ return ERR_PTR(-EINVAL);
10841155 }
1085
- mutex_unlock(&xrcd->tgt_qp_mutex);
1156
+ qp = __ib_open_qp(real_qp, qp_open_attr->event_handler,
1157
+ qp_open_attr->qp_context);
1158
+ up_read(&xrcd->tgt_qps_rwsem);
10861159 return qp;
10871160 }
10881161 EXPORT_SYMBOL(ib_open_qp);
10891162
1090
-static struct ib_qp *create_xrc_qp(struct ib_qp *qp,
1091
- struct ib_qp_init_attr *qp_init_attr)
1163
+static struct ib_qp *create_xrc_qp_user(struct ib_qp *qp,
1164
+ struct ib_qp_init_attr *qp_init_attr)
10921165 {
10931166 struct ib_qp *real_qp = qp;
1167
+ int err;
10941168
10951169 qp->event_handler = __ib_shared_qp_event_handler;
10961170 qp->qp_context = qp;
....@@ -1106,10 +1180,25 @@
11061180 if (IS_ERR(qp))
11071181 return qp;
11081182
1109
- __ib_insert_xrcd_qp(qp_init_attr->xrcd, real_qp);
1183
+ err = xa_err(xa_store(&qp_init_attr->xrcd->tgt_qps, real_qp->qp_num,
1184
+ real_qp, GFP_KERNEL));
1185
+ if (err) {
1186
+ ib_close_qp(qp);
1187
+ return ERR_PTR(err);
1188
+ }
11101189 return qp;
11111190 }
11121191
1192
+/**
1193
+ * ib_create_qp - Creates a kernel QP associated with the specified protection
1194
+ * domain.
1195
+ * @pd: The protection domain associated with the QP.
1196
+ * @qp_init_attr: A list of initial attributes required to create the
1197
+ * QP. If QP creation succeeds, then the attributes are updated to
1198
+ * the actual capabilities of the created QP.
1199
+ *
1200
+ * NOTE: for user qp use ib_create_qp_user with valid udata!
1201
+ */
11131202 struct ib_qp *ib_create_qp(struct ib_pd *pd,
11141203 struct ib_qp_init_attr *qp_init_attr)
11151204 {
....@@ -1121,6 +1210,10 @@
11211210 (qp_init_attr->recv_cq ||
11221211 qp_init_attr->srq || qp_init_attr->cap.max_recv_wr ||
11231212 qp_init_attr->cap.max_recv_sge))
1213
+ return ERR_PTR(-EINVAL);
1214
+
1215
+ if ((qp_init_attr->create_flags & IB_QP_CREATE_INTEGRITY_EN) &&
1216
+ !(device->attrs.device_cap_flags & IB_DEVICE_INTEGRITY_HANDOVER))
11241217 return ERR_PTR(-EINVAL);
11251218
11261219 /*
....@@ -1140,19 +1233,9 @@
11401233 if (ret)
11411234 goto err;
11421235
1143
- qp->real_qp = qp;
1144
- qp->qp_type = qp_init_attr->qp_type;
1145
- qp->rwq_ind_tbl = qp_init_attr->rwq_ind_tbl;
1146
-
1147
- atomic_set(&qp->usecnt, 0);
1148
- qp->mrs_used = 0;
1149
- spin_lock_init(&qp->mr_lock);
1150
- INIT_LIST_HEAD(&qp->rdma_mrs);
1151
- INIT_LIST_HEAD(&qp->sig_mrs);
1152
- qp->port = 0;
1153
-
11541236 if (qp_init_attr->qp_type == IB_QPT_XRC_TGT) {
1155
- struct ib_qp *xrc_qp = create_xrc_qp(qp, qp_init_attr);
1237
+ struct ib_qp *xrc_qp =
1238
+ create_xrc_qp_user(qp, qp_init_attr);
11561239
11571240 if (IS_ERR(xrc_qp)) {
11581241 ret = PTR_ERR(xrc_qp);
....@@ -1198,6 +1281,8 @@
11981281 qp->max_write_sge = qp_init_attr->cap.max_send_sge;
11991282 qp->max_read_sge = min_t(u32, qp_init_attr->cap.max_send_sge,
12001283 device->attrs.max_sge_rd);
1284
+ if (qp_init_attr->create_flags & IB_QP_CREATE_INTEGRITY_EN)
1285
+ qp->integrity_en = true;
12011286
12021287 return qp;
12031288
....@@ -1516,8 +1601,7 @@
15161601 };
15171602
15181603 bool ib_modify_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state next_state,
1519
- enum ib_qp_type type, enum ib_qp_attr_mask mask,
1520
- enum rdma_link_layer ll)
1604
+ enum ib_qp_type type, enum ib_qp_attr_mask mask)
15211605 {
15221606 enum ib_qp_attr_mask req_param, opt_param;
15231607
....@@ -1591,11 +1675,37 @@
15911675 const struct ib_gid_attr *old_sgid_attr_alt_av;
15921676 int ret;
15931677
1678
+ attr->xmit_slave = NULL;
15941679 if (attr_mask & IB_QP_AV) {
15951680 ret = rdma_fill_sgid_attr(qp->device, &attr->ah_attr,
15961681 &old_sgid_attr_av);
15971682 if (ret)
15981683 return ret;
1684
+
1685
+ if (attr->ah_attr.type == RDMA_AH_ATTR_TYPE_ROCE &&
1686
+ is_qp_type_connected(qp)) {
1687
+ struct net_device *slave;
1688
+
1689
+ /*
1690
+ * If the user provided the qp_attr then we have to
1691
+ * resolve it. Kerne users have to provide already
1692
+ * resolved rdma_ah_attr's.
1693
+ */
1694
+ if (udata) {
1695
+ ret = ib_resolve_eth_dmac(qp->device,
1696
+ &attr->ah_attr);
1697
+ if (ret)
1698
+ goto out_av;
1699
+ }
1700
+ slave = rdma_lag_get_ah_roce_slave(qp->device,
1701
+ &attr->ah_attr,
1702
+ GFP_KERNEL);
1703
+ if (IS_ERR(slave)) {
1704
+ ret = PTR_ERR(slave);
1705
+ goto out_av;
1706
+ }
1707
+ attr->xmit_slave = slave;
1708
+ }
15991709 }
16001710 if (attr_mask & IB_QP_ALT_PATH) {
16011711 /*
....@@ -1622,31 +1732,29 @@
16221732 }
16231733 }
16241734
1625
- /*
1626
- * If the user provided the qp_attr then we have to resolve it. Kernel
1627
- * users have to provide already resolved rdma_ah_attr's
1628
- */
1629
- if (udata && (attr_mask & IB_QP_AV) &&
1630
- attr->ah_attr.type == RDMA_AH_ATTR_TYPE_ROCE &&
1631
- is_qp_type_connected(qp)) {
1632
- ret = ib_resolve_eth_dmac(qp->device, &attr->ah_attr);
1633
- if (ret)
1634
- goto out;
1635
- }
1636
-
16371735 if (rdma_ib_or_roce(qp->device, port)) {
16381736 if (attr_mask & IB_QP_RQ_PSN && attr->rq_psn & ~0xffffff) {
1639
- pr_warn("%s: %s rq_psn overflow, masking to 24 bits\n",
1640
- __func__, qp->device->name);
1737
+ dev_warn(&qp->device->dev,
1738
+ "%s rq_psn overflow, masking to 24 bits\n",
1739
+ __func__);
16411740 attr->rq_psn &= 0xffffff;
16421741 }
16431742
16441743 if (attr_mask & IB_QP_SQ_PSN && attr->sq_psn & ~0xffffff) {
1645
- pr_warn("%s: %s sq_psn overflow, masking to 24 bits\n",
1646
- __func__, qp->device->name);
1744
+ dev_warn(&qp->device->dev,
1745
+ " %s sq_psn overflow, masking to 24 bits\n",
1746
+ __func__);
16471747 attr->sq_psn &= 0xffffff;
16481748 }
16491749 }
1750
+
1751
+ /*
1752
+ * Bind this qp to a counter automatically based on the rdma counter
1753
+ * rules. This only set in RST2INIT with port specified
1754
+ */
1755
+ if (!qp->counter && (attr_mask & IB_QP_PORT) &&
1756
+ ((attr_mask & IB_QP_STATE) && attr->qp_state == IB_QPS_INIT))
1757
+ rdma_counter_bind_qp_auto(qp, attr->port_num);
16501758
16511759 ret = ib_security_modify_qp(qp, attr, attr_mask, udata);
16521760 if (ret)
....@@ -1665,8 +1773,10 @@
16651773 if (attr_mask & IB_QP_ALT_PATH)
16661774 rdma_unfill_sgid_attr(&attr->alt_ah_attr, old_sgid_attr_alt_av);
16671775 out_av:
1668
- if (attr_mask & IB_QP_AV)
1776
+ if (attr_mask & IB_QP_AV) {
1777
+ rdma_lag_put_ah_roce_slave(attr->xmit_slave);
16691778 rdma_unfill_sgid_attr(&attr->ah_attr, old_sgid_attr_av);
1779
+ }
16701780 return ret;
16711781 }
16721782
....@@ -1688,7 +1798,7 @@
16881798 }
16891799 EXPORT_SYMBOL(ib_modify_qp_with_udata);
16901800
1691
-int ib_get_eth_speed(struct ib_device *dev, u8 port_num, u8 *speed, u8 *width)
1801
+int ib_get_eth_speed(struct ib_device *dev, u8 port_num, u16 *speed, u8 *width)
16921802 {
16931803 int rc;
16941804 u32 netdev_speed;
....@@ -1698,10 +1808,7 @@
16981808 if (rdma_port_get_link_layer(dev, port_num) != IB_LINK_LAYER_ETHERNET)
16991809 return -EINVAL;
17001810
1701
- if (!dev->get_netdev)
1702
- return -EOPNOTSUPP;
1703
-
1704
- netdev = dev->get_netdev(dev, port_num);
1811
+ netdev = ib_device_get_netdev(dev, port_num);
17051812 if (!netdev)
17061813 return -ENODEV;
17071814
....@@ -1759,9 +1866,9 @@
17591866 qp_attr->ah_attr.grh.sgid_attr = NULL;
17601867 qp_attr->alt_ah_attr.grh.sgid_attr = NULL;
17611868
1762
- return qp->device->query_qp ?
1763
- qp->device->query_qp(qp->real_qp, qp_attr, qp_attr_mask, qp_init_attr) :
1764
- -EOPNOTSUPP;
1869
+ return qp->device->ops.query_qp ?
1870
+ qp->device->ops.query_qp(qp->real_qp, qp_attr, qp_attr_mask,
1871
+ qp_init_attr) : -EOPNOTSUPP;
17651872 }
17661873 EXPORT_SYMBOL(ib_query_qp);
17671874
....@@ -1774,9 +1881,9 @@
17741881 if (real_qp == qp)
17751882 return -EINVAL;
17761883
1777
- spin_lock_irqsave(&real_qp->device->event_handler_lock, flags);
1884
+ spin_lock_irqsave(&real_qp->device->qp_open_list_lock, flags);
17781885 list_del(&qp->open_list);
1779
- spin_unlock_irqrestore(&real_qp->device->event_handler_lock, flags);
1886
+ spin_unlock_irqrestore(&real_qp->device->qp_open_list_lock, flags);
17801887
17811888 atomic_dec(&real_qp->usecnt);
17821889 if (qp->qp_sec)
....@@ -1795,27 +1902,24 @@
17951902
17961903 real_qp = qp->real_qp;
17971904 xrcd = real_qp->xrcd;
1798
-
1799
- mutex_lock(&xrcd->tgt_qp_mutex);
1905
+ down_write(&xrcd->tgt_qps_rwsem);
18001906 ib_close_qp(qp);
18011907 if (atomic_read(&real_qp->usecnt) == 0)
1802
- list_del(&real_qp->xrcd_list);
1908
+ xa_erase(&xrcd->tgt_qps, real_qp->qp_num);
18031909 else
18041910 real_qp = NULL;
1805
- mutex_unlock(&xrcd->tgt_qp_mutex);
1911
+ up_write(&xrcd->tgt_qps_rwsem);
18061912
18071913 if (real_qp) {
18081914 ret = ib_destroy_qp(real_qp);
18091915 if (!ret)
18101916 atomic_dec(&xrcd->usecnt);
1811
- else
1812
- __ib_insert_xrcd_qp(xrcd, real_qp);
18131917 }
18141918
18151919 return 0;
18161920 }
18171921
1818
-int ib_destroy_qp(struct ib_qp *qp)
1922
+int ib_destroy_qp_user(struct ib_qp *qp, struct ib_udata *udata)
18191923 {
18201924 const struct ib_gid_attr *alt_path_sgid_attr = qp->alt_path_sgid_attr;
18211925 const struct ib_gid_attr *av_sgid_attr = qp->av_sgid_attr;
....@@ -1846,8 +1950,9 @@
18461950 if (!qp->uobject)
18471951 rdma_rw_cleanup_mrs(qp);
18481952
1953
+ rdma_counter_unbind_qp(qp, true);
18491954 rdma_restrack_del(&qp->res);
1850
- ret = qp->device->destroy_qp(qp);
1955
+ ret = qp->device->ops.destroy_qp(qp, udata);
18511956 if (!ret) {
18521957 if (alt_path_sgid_attr)
18531958 rdma_put_gid_attr(alt_path_sgid_attr);
....@@ -1872,7 +1977,7 @@
18721977
18731978 return ret;
18741979 }
1875
-EXPORT_SYMBOL(ib_destroy_qp);
1980
+EXPORT_SYMBOL(ib_destroy_qp_user);
18761981
18771982 /* Completion queues */
18781983
....@@ -1884,68 +1989,146 @@
18841989 const char *caller)
18851990 {
18861991 struct ib_cq *cq;
1992
+ int ret;
18871993
1888
- cq = device->create_cq(device, cq_attr, NULL, NULL);
1994
+ cq = rdma_zalloc_drv_obj(device, ib_cq);
1995
+ if (!cq)
1996
+ return ERR_PTR(-ENOMEM);
18891997
1890
- if (!IS_ERR(cq)) {
1891
- cq->device = device;
1892
- cq->uobject = NULL;
1893
- cq->comp_handler = comp_handler;
1894
- cq->event_handler = event_handler;
1895
- cq->cq_context = cq_context;
1896
- atomic_set(&cq->usecnt, 0);
1897
- cq->res.type = RDMA_RESTRACK_CQ;
1898
- cq->res.kern_name = caller;
1899
- rdma_restrack_add(&cq->res);
1998
+ cq->device = device;
1999
+ cq->uobject = NULL;
2000
+ cq->comp_handler = comp_handler;
2001
+ cq->event_handler = event_handler;
2002
+ cq->cq_context = cq_context;
2003
+ atomic_set(&cq->usecnt, 0);
2004
+
2005
+ rdma_restrack_new(&cq->res, RDMA_RESTRACK_CQ);
2006
+ rdma_restrack_set_name(&cq->res, caller);
2007
+
2008
+ ret = device->ops.create_cq(cq, cq_attr, NULL);
2009
+ if (ret) {
2010
+ rdma_restrack_put(&cq->res);
2011
+ kfree(cq);
2012
+ return ERR_PTR(ret);
19002013 }
19012014
2015
+ rdma_restrack_add(&cq->res);
19022016 return cq;
19032017 }
19042018 EXPORT_SYMBOL(__ib_create_cq);
19052019
19062020 int rdma_set_cq_moderation(struct ib_cq *cq, u16 cq_count, u16 cq_period)
19072021 {
1908
- return cq->device->modify_cq ?
1909
- cq->device->modify_cq(cq, cq_count, cq_period) : -EOPNOTSUPP;
2022
+ if (cq->shared)
2023
+ return -EOPNOTSUPP;
2024
+
2025
+ return cq->device->ops.modify_cq ?
2026
+ cq->device->ops.modify_cq(cq, cq_count,
2027
+ cq_period) : -EOPNOTSUPP;
19102028 }
19112029 EXPORT_SYMBOL(rdma_set_cq_moderation);
19122030
1913
-int ib_destroy_cq(struct ib_cq *cq)
2031
+int ib_destroy_cq_user(struct ib_cq *cq, struct ib_udata *udata)
19142032 {
2033
+ int ret;
2034
+
2035
+ if (WARN_ON_ONCE(cq->shared))
2036
+ return -EOPNOTSUPP;
2037
+
19152038 if (atomic_read(&cq->usecnt))
19162039 return -EBUSY;
19172040
2041
+ ret = cq->device->ops.destroy_cq(cq, udata);
2042
+ if (ret)
2043
+ return ret;
2044
+
19182045 rdma_restrack_del(&cq->res);
1919
- return cq->device->destroy_cq(cq);
2046
+ kfree(cq);
2047
+ return ret;
19202048 }
1921
-EXPORT_SYMBOL(ib_destroy_cq);
2049
+EXPORT_SYMBOL(ib_destroy_cq_user);
19222050
19232051 int ib_resize_cq(struct ib_cq *cq, int cqe)
19242052 {
1925
- return cq->device->resize_cq ?
1926
- cq->device->resize_cq(cq, cqe, NULL) : -EOPNOTSUPP;
2053
+ if (cq->shared)
2054
+ return -EOPNOTSUPP;
2055
+
2056
+ return cq->device->ops.resize_cq ?
2057
+ cq->device->ops.resize_cq(cq, cqe, NULL) : -EOPNOTSUPP;
19272058 }
19282059 EXPORT_SYMBOL(ib_resize_cq);
19292060
19302061 /* Memory regions */
19312062
1932
-int ib_dereg_mr(struct ib_mr *mr)
2063
+struct ib_mr *ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
2064
+ u64 virt_addr, int access_flags)
2065
+{
2066
+ struct ib_mr *mr;
2067
+
2068
+ if (access_flags & IB_ACCESS_ON_DEMAND) {
2069
+ if (!(pd->device->attrs.device_cap_flags &
2070
+ IB_DEVICE_ON_DEMAND_PAGING)) {
2071
+ pr_debug("ODP support not available\n");
2072
+ return ERR_PTR(-EINVAL);
2073
+ }
2074
+ }
2075
+
2076
+ mr = pd->device->ops.reg_user_mr(pd, start, length, virt_addr,
2077
+ access_flags, NULL);
2078
+
2079
+ if (IS_ERR(mr))
2080
+ return mr;
2081
+
2082
+ mr->device = pd->device;
2083
+ mr->type = IB_MR_TYPE_USER;
2084
+ mr->pd = pd;
2085
+ mr->dm = NULL;
2086
+ atomic_inc(&pd->usecnt);
2087
+ mr->iova = virt_addr;
2088
+ mr->length = length;
2089
+
2090
+ rdma_restrack_new(&mr->res, RDMA_RESTRACK_MR);
2091
+ rdma_restrack_parent_name(&mr->res, &pd->res);
2092
+ rdma_restrack_add(&mr->res);
2093
+
2094
+ return mr;
2095
+}
2096
+EXPORT_SYMBOL(ib_reg_user_mr);
2097
+
2098
+int ib_advise_mr(struct ib_pd *pd, enum ib_uverbs_advise_mr_advice advice,
2099
+ u32 flags, struct ib_sge *sg_list, u32 num_sge)
2100
+{
2101
+ if (!pd->device->ops.advise_mr)
2102
+ return -EOPNOTSUPP;
2103
+
2104
+ if (!num_sge)
2105
+ return 0;
2106
+
2107
+ return pd->device->ops.advise_mr(pd, advice, flags, sg_list, num_sge,
2108
+ NULL);
2109
+}
2110
+EXPORT_SYMBOL(ib_advise_mr);
2111
+
2112
+int ib_dereg_mr_user(struct ib_mr *mr, struct ib_udata *udata)
19332113 {
19342114 struct ib_pd *pd = mr->pd;
19352115 struct ib_dm *dm = mr->dm;
2116
+ struct ib_sig_attrs *sig_attrs = mr->sig_attrs;
19362117 int ret;
19372118
2119
+ trace_mr_dereg(mr);
19382120 rdma_restrack_del(&mr->res);
1939
- ret = mr->device->dereg_mr(mr);
2121
+ ret = mr->device->ops.dereg_mr(mr, udata);
19402122 if (!ret) {
19412123 atomic_dec(&pd->usecnt);
19422124 if (dm)
19432125 atomic_dec(&dm->usecnt);
2126
+ kfree(sig_attrs);
19442127 }
19452128
19462129 return ret;
19472130 }
1948
-EXPORT_SYMBOL(ib_dereg_mr);
2131
+EXPORT_SYMBOL(ib_dereg_mr_user);
19492132
19502133 /**
19512134 * ib_alloc_mr() - Allocates a memory region
....@@ -1959,78 +2142,104 @@
19592142 * max_num_sg * used_page_size.
19602143 *
19612144 */
1962
-struct ib_mr *ib_alloc_mr(struct ib_pd *pd,
1963
- enum ib_mr_type mr_type,
2145
+struct ib_mr *ib_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
19642146 u32 max_num_sg)
19652147 {
19662148 struct ib_mr *mr;
19672149
1968
- if (!pd->device->alloc_mr)
1969
- return ERR_PTR(-EOPNOTSUPP);
1970
-
1971
- mr = pd->device->alloc_mr(pd, mr_type, max_num_sg);
1972
- if (!IS_ERR(mr)) {
1973
- mr->device = pd->device;
1974
- mr->pd = pd;
1975
- mr->dm = NULL;
1976
- mr->uobject = NULL;
1977
- atomic_inc(&pd->usecnt);
1978
- mr->need_inval = false;
1979
- mr->res.type = RDMA_RESTRACK_MR;
1980
- rdma_restrack_add(&mr->res);
2150
+ if (!pd->device->ops.alloc_mr) {
2151
+ mr = ERR_PTR(-EOPNOTSUPP);
2152
+ goto out;
19812153 }
19822154
2155
+ if (mr_type == IB_MR_TYPE_INTEGRITY) {
2156
+ WARN_ON_ONCE(1);
2157
+ mr = ERR_PTR(-EINVAL);
2158
+ goto out;
2159
+ }
2160
+
2161
+ mr = pd->device->ops.alloc_mr(pd, mr_type, max_num_sg);
2162
+ if (IS_ERR(mr))
2163
+ goto out;
2164
+
2165
+ mr->device = pd->device;
2166
+ mr->pd = pd;
2167
+ mr->dm = NULL;
2168
+ mr->uobject = NULL;
2169
+ atomic_inc(&pd->usecnt);
2170
+ mr->need_inval = false;
2171
+ mr->type = mr_type;
2172
+ mr->sig_attrs = NULL;
2173
+
2174
+ rdma_restrack_new(&mr->res, RDMA_RESTRACK_MR);
2175
+ rdma_restrack_parent_name(&mr->res, &pd->res);
2176
+ rdma_restrack_add(&mr->res);
2177
+out:
2178
+ trace_mr_alloc(pd, mr_type, max_num_sg, mr);
19832179 return mr;
19842180 }
19852181 EXPORT_SYMBOL(ib_alloc_mr);
19862182
1987
-/* "Fast" memory regions */
1988
-
1989
-struct ib_fmr *ib_alloc_fmr(struct ib_pd *pd,
1990
- int mr_access_flags,
1991
- struct ib_fmr_attr *fmr_attr)
2183
+/**
2184
+ * ib_alloc_mr_integrity() - Allocates an integrity memory region
2185
+ * @pd: protection domain associated with the region
2186
+ * @max_num_data_sg: maximum data sg entries available for registration
2187
+ * @max_num_meta_sg: maximum metadata sg entries available for
2188
+ * registration
2189
+ *
2190
+ * Notes:
2191
+ * Memory registration page/sg lists must not exceed max_num_sg,
2192
+ * also the integrity page/sg lists must not exceed max_num_meta_sg.
2193
+ *
2194
+ */
2195
+struct ib_mr *ib_alloc_mr_integrity(struct ib_pd *pd,
2196
+ u32 max_num_data_sg,
2197
+ u32 max_num_meta_sg)
19922198 {
1993
- struct ib_fmr *fmr;
2199
+ struct ib_mr *mr;
2200
+ struct ib_sig_attrs *sig_attrs;
19942201
1995
- if (!pd->device->alloc_fmr)
1996
- return ERR_PTR(-EOPNOTSUPP);
1997
-
1998
- fmr = pd->device->alloc_fmr(pd, mr_access_flags, fmr_attr);
1999
- if (!IS_ERR(fmr)) {
2000
- fmr->device = pd->device;
2001
- fmr->pd = pd;
2002
- atomic_inc(&pd->usecnt);
2202
+ if (!pd->device->ops.alloc_mr_integrity ||
2203
+ !pd->device->ops.map_mr_sg_pi) {
2204
+ mr = ERR_PTR(-EOPNOTSUPP);
2205
+ goto out;
20032206 }
20042207
2005
- return fmr;
2208
+ if (!max_num_meta_sg) {
2209
+ mr = ERR_PTR(-EINVAL);
2210
+ goto out;
2211
+ }
2212
+
2213
+ sig_attrs = kzalloc(sizeof(struct ib_sig_attrs), GFP_KERNEL);
2214
+ if (!sig_attrs) {
2215
+ mr = ERR_PTR(-ENOMEM);
2216
+ goto out;
2217
+ }
2218
+
2219
+ mr = pd->device->ops.alloc_mr_integrity(pd, max_num_data_sg,
2220
+ max_num_meta_sg);
2221
+ if (IS_ERR(mr)) {
2222
+ kfree(sig_attrs);
2223
+ goto out;
2224
+ }
2225
+
2226
+ mr->device = pd->device;
2227
+ mr->pd = pd;
2228
+ mr->dm = NULL;
2229
+ mr->uobject = NULL;
2230
+ atomic_inc(&pd->usecnt);
2231
+ mr->need_inval = false;
2232
+ mr->type = IB_MR_TYPE_INTEGRITY;
2233
+ mr->sig_attrs = sig_attrs;
2234
+
2235
+ rdma_restrack_new(&mr->res, RDMA_RESTRACK_MR);
2236
+ rdma_restrack_parent_name(&mr->res, &pd->res);
2237
+ rdma_restrack_add(&mr->res);
2238
+out:
2239
+ trace_mr_integ_alloc(pd, max_num_data_sg, max_num_meta_sg, mr);
2240
+ return mr;
20062241 }
2007
-EXPORT_SYMBOL(ib_alloc_fmr);
2008
-
2009
-int ib_unmap_fmr(struct list_head *fmr_list)
2010
-{
2011
- struct ib_fmr *fmr;
2012
-
2013
- if (list_empty(fmr_list))
2014
- return 0;
2015
-
2016
- fmr = list_entry(fmr_list->next, struct ib_fmr, list);
2017
- return fmr->device->unmap_fmr(fmr_list);
2018
-}
2019
-EXPORT_SYMBOL(ib_unmap_fmr);
2020
-
2021
-int ib_dealloc_fmr(struct ib_fmr *fmr)
2022
-{
2023
- struct ib_pd *pd;
2024
- int ret;
2025
-
2026
- pd = fmr->pd;
2027
- ret = fmr->device->dealloc_fmr(fmr);
2028
- if (!ret)
2029
- atomic_dec(&pd->usecnt);
2030
-
2031
- return ret;
2032
-}
2033
-EXPORT_SYMBOL(ib_dealloc_fmr);
2242
+EXPORT_SYMBOL(ib_alloc_mr_integrity);
20342243
20352244 /* Multicast groups */
20362245
....@@ -2076,14 +2285,14 @@
20762285 {
20772286 int ret;
20782287
2079
- if (!qp->device->attach_mcast)
2288
+ if (!qp->device->ops.attach_mcast)
20802289 return -EOPNOTSUPP;
20812290
20822291 if (!rdma_is_multicast_addr((struct in6_addr *)gid->raw) ||
20832292 qp->qp_type != IB_QPT_UD || !is_valid_mcast_lid(qp, lid))
20842293 return -EINVAL;
20852294
2086
- ret = qp->device->attach_mcast(qp, gid, lid);
2295
+ ret = qp->device->ops.attach_mcast(qp, gid, lid);
20872296 if (!ret)
20882297 atomic_inc(&qp->usecnt);
20892298 return ret;
....@@ -2094,58 +2303,75 @@
20942303 {
20952304 int ret;
20962305
2097
- if (!qp->device->detach_mcast)
2306
+ if (!qp->device->ops.detach_mcast)
20982307 return -EOPNOTSUPP;
20992308
21002309 if (!rdma_is_multicast_addr((struct in6_addr *)gid->raw) ||
21012310 qp->qp_type != IB_QPT_UD || !is_valid_mcast_lid(qp, lid))
21022311 return -EINVAL;
21032312
2104
- ret = qp->device->detach_mcast(qp, gid, lid);
2313
+ ret = qp->device->ops.detach_mcast(qp, gid, lid);
21052314 if (!ret)
21062315 atomic_dec(&qp->usecnt);
21072316 return ret;
21082317 }
21092318 EXPORT_SYMBOL(ib_detach_mcast);
21102319
2111
-struct ib_xrcd *__ib_alloc_xrcd(struct ib_device *device, const char *caller)
2320
+/**
2321
+ * ib_alloc_xrcd_user - Allocates an XRC domain.
2322
+ * @device: The device on which to allocate the XRC domain.
2323
+ * @inode: inode to connect XRCD
2324
+ * @udata: Valid user data or NULL for kernel object
2325
+ */
2326
+struct ib_xrcd *ib_alloc_xrcd_user(struct ib_device *device,
2327
+ struct inode *inode, struct ib_udata *udata)
21122328 {
21132329 struct ib_xrcd *xrcd;
2330
+ int ret;
21142331
2115
- if (!device->alloc_xrcd)
2332
+ if (!device->ops.alloc_xrcd)
21162333 return ERR_PTR(-EOPNOTSUPP);
21172334
2118
- xrcd = device->alloc_xrcd(device, NULL, NULL);
2119
- if (!IS_ERR(xrcd)) {
2120
- xrcd->device = device;
2121
- xrcd->inode = NULL;
2122
- atomic_set(&xrcd->usecnt, 0);
2123
- mutex_init(&xrcd->tgt_qp_mutex);
2124
- INIT_LIST_HEAD(&xrcd->tgt_qp_list);
2125
- }
2335
+ xrcd = rdma_zalloc_drv_obj(device, ib_xrcd);
2336
+ if (!xrcd)
2337
+ return ERR_PTR(-ENOMEM);
21262338
2339
+ xrcd->device = device;
2340
+ xrcd->inode = inode;
2341
+ atomic_set(&xrcd->usecnt, 0);
2342
+ init_rwsem(&xrcd->tgt_qps_rwsem);
2343
+ xa_init(&xrcd->tgt_qps);
2344
+
2345
+ ret = device->ops.alloc_xrcd(xrcd, udata);
2346
+ if (ret)
2347
+ goto err;
21272348 return xrcd;
2349
+err:
2350
+ kfree(xrcd);
2351
+ return ERR_PTR(ret);
21282352 }
2129
-EXPORT_SYMBOL(__ib_alloc_xrcd);
2353
+EXPORT_SYMBOL(ib_alloc_xrcd_user);
21302354
2131
-int ib_dealloc_xrcd(struct ib_xrcd *xrcd)
2355
+/**
2356
+ * ib_dealloc_xrcd_user - Deallocates an XRC domain.
2357
+ * @xrcd: The XRC domain to deallocate.
2358
+ * @udata: Valid user data or NULL for kernel object
2359
+ */
2360
+int ib_dealloc_xrcd_user(struct ib_xrcd *xrcd, struct ib_udata *udata)
21322361 {
2133
- struct ib_qp *qp;
21342362 int ret;
21352363
21362364 if (atomic_read(&xrcd->usecnt))
21372365 return -EBUSY;
21382366
2139
- while (!list_empty(&xrcd->tgt_qp_list)) {
2140
- qp = list_entry(xrcd->tgt_qp_list.next, struct ib_qp, xrcd_list);
2141
- ret = ib_destroy_qp(qp);
2142
- if (ret)
2143
- return ret;
2144
- }
2145
-
2146
- return xrcd->device->dealloc_xrcd(xrcd);
2367
+ WARN_ON(!xa_empty(&xrcd->tgt_qps));
2368
+ ret = xrcd->device->ops.dealloc_xrcd(xrcd, udata);
2369
+ if (ret)
2370
+ return ret;
2371
+ kfree(xrcd);
2372
+ return ret;
21472373 }
2148
-EXPORT_SYMBOL(ib_dealloc_xrcd);
2374
+EXPORT_SYMBOL(ib_dealloc_xrcd_user);
21492375
21502376 /**
21512377 * ib_create_wq - Creates a WQ associated with the specified protection
....@@ -2166,10 +2392,10 @@
21662392 {
21672393 struct ib_wq *wq;
21682394
2169
- if (!pd->device->create_wq)
2395
+ if (!pd->device->ops.create_wq)
21702396 return ERR_PTR(-EOPNOTSUPP);
21712397
2172
- wq = pd->device->create_wq(pd, wq_attr, NULL);
2398
+ wq = pd->device->ops.create_wq(pd, wq_attr, NULL);
21732399 if (!IS_ERR(wq)) {
21742400 wq->event_handler = wq_attr->event_handler;
21752401 wq->wq_context = wq_attr->wq_context;
....@@ -2187,26 +2413,28 @@
21872413 EXPORT_SYMBOL(ib_create_wq);
21882414
21892415 /**
2190
- * ib_destroy_wq - Destroys the specified WQ.
2416
+ * ib_destroy_wq_user - Destroys the specified user WQ.
21912417 * @wq: The WQ to destroy.
2418
+ * @udata: Valid user data
21922419 */
2193
-int ib_destroy_wq(struct ib_wq *wq)
2420
+int ib_destroy_wq_user(struct ib_wq *wq, struct ib_udata *udata)
21942421 {
2195
- int err;
21962422 struct ib_cq *cq = wq->cq;
21972423 struct ib_pd *pd = wq->pd;
2424
+ int ret;
21982425
21992426 if (atomic_read(&wq->usecnt))
22002427 return -EBUSY;
22012428
2202
- err = wq->device->destroy_wq(wq);
2203
- if (!err) {
2204
- atomic_dec(&pd->usecnt);
2205
- atomic_dec(&cq->usecnt);
2206
- }
2207
- return err;
2429
+ ret = wq->device->ops.destroy_wq(wq, udata);
2430
+ if (ret)
2431
+ return ret;
2432
+
2433
+ atomic_dec(&pd->usecnt);
2434
+ atomic_dec(&cq->usecnt);
2435
+ return ret;
22082436 }
2209
-EXPORT_SYMBOL(ib_destroy_wq);
2437
+EXPORT_SYMBOL(ib_destroy_wq_user);
22102438
22112439 /**
22122440 * ib_modify_wq - Modifies the specified WQ.
....@@ -2221,123 +2449,110 @@
22212449 {
22222450 int err;
22232451
2224
- if (!wq->device->modify_wq)
2452
+ if (!wq->device->ops.modify_wq)
22252453 return -EOPNOTSUPP;
22262454
2227
- err = wq->device->modify_wq(wq, wq_attr, wq_attr_mask, NULL);
2455
+ err = wq->device->ops.modify_wq(wq, wq_attr, wq_attr_mask, NULL);
22282456 return err;
22292457 }
22302458 EXPORT_SYMBOL(ib_modify_wq);
22312459
2232
-/*
2233
- * ib_create_rwq_ind_table - Creates a RQ Indirection Table.
2234
- * @device: The device on which to create the rwq indirection table.
2235
- * @ib_rwq_ind_table_init_attr: A list of initial attributes required to
2236
- * create the Indirection Table.
2237
- *
2238
- * Note: The life time of ib_rwq_ind_table_init_attr->ind_tbl is not less
2239
- * than the created ib_rwq_ind_table object and the caller is responsible
2240
- * for its memory allocation/free.
2241
- */
2242
-struct ib_rwq_ind_table *ib_create_rwq_ind_table(struct ib_device *device,
2243
- struct ib_rwq_ind_table_init_attr *init_attr)
2244
-{
2245
- struct ib_rwq_ind_table *rwq_ind_table;
2246
- int i;
2247
- u32 table_size;
2248
-
2249
- if (!device->create_rwq_ind_table)
2250
- return ERR_PTR(-EOPNOTSUPP);
2251
-
2252
- table_size = (1 << init_attr->log_ind_tbl_size);
2253
- rwq_ind_table = device->create_rwq_ind_table(device,
2254
- init_attr, NULL);
2255
- if (IS_ERR(rwq_ind_table))
2256
- return rwq_ind_table;
2257
-
2258
- rwq_ind_table->ind_tbl = init_attr->ind_tbl;
2259
- rwq_ind_table->log_ind_tbl_size = init_attr->log_ind_tbl_size;
2260
- rwq_ind_table->device = device;
2261
- rwq_ind_table->uobject = NULL;
2262
- atomic_set(&rwq_ind_table->usecnt, 0);
2263
-
2264
- for (i = 0; i < table_size; i++)
2265
- atomic_inc(&rwq_ind_table->ind_tbl[i]->usecnt);
2266
-
2267
- return rwq_ind_table;
2268
-}
2269
-EXPORT_SYMBOL(ib_create_rwq_ind_table);
2270
-
2271
-/*
2272
- * ib_destroy_rwq_ind_table - Destroys the specified Indirection Table.
2273
- * @wq_ind_table: The Indirection Table to destroy.
2274
-*/
2275
-int ib_destroy_rwq_ind_table(struct ib_rwq_ind_table *rwq_ind_table)
2276
-{
2277
- int err, i;
2278
- u32 table_size = (1 << rwq_ind_table->log_ind_tbl_size);
2279
- struct ib_wq **ind_tbl = rwq_ind_table->ind_tbl;
2280
-
2281
- if (atomic_read(&rwq_ind_table->usecnt))
2282
- return -EBUSY;
2283
-
2284
- err = rwq_ind_table->device->destroy_rwq_ind_table(rwq_ind_table);
2285
- if (!err) {
2286
- for (i = 0; i < table_size; i++)
2287
- atomic_dec(&ind_tbl[i]->usecnt);
2288
- }
2289
-
2290
- return err;
2291
-}
2292
-EXPORT_SYMBOL(ib_destroy_rwq_ind_table);
2293
-
22942460 int ib_check_mr_status(struct ib_mr *mr, u32 check_mask,
22952461 struct ib_mr_status *mr_status)
22962462 {
2297
- return mr->device->check_mr_status ?
2298
- mr->device->check_mr_status(mr, check_mask, mr_status) : -EOPNOTSUPP;
2463
+ if (!mr->device->ops.check_mr_status)
2464
+ return -EOPNOTSUPP;
2465
+
2466
+ return mr->device->ops.check_mr_status(mr, check_mask, mr_status);
22992467 }
23002468 EXPORT_SYMBOL(ib_check_mr_status);
23012469
23022470 int ib_set_vf_link_state(struct ib_device *device, int vf, u8 port,
23032471 int state)
23042472 {
2305
- if (!device->set_vf_link_state)
2473
+ if (!device->ops.set_vf_link_state)
23062474 return -EOPNOTSUPP;
23072475
2308
- return device->set_vf_link_state(device, vf, port, state);
2476
+ return device->ops.set_vf_link_state(device, vf, port, state);
23092477 }
23102478 EXPORT_SYMBOL(ib_set_vf_link_state);
23112479
23122480 int ib_get_vf_config(struct ib_device *device, int vf, u8 port,
23132481 struct ifla_vf_info *info)
23142482 {
2315
- if (!device->get_vf_config)
2483
+ if (!device->ops.get_vf_config)
23162484 return -EOPNOTSUPP;
23172485
2318
- return device->get_vf_config(device, vf, port, info);
2486
+ return device->ops.get_vf_config(device, vf, port, info);
23192487 }
23202488 EXPORT_SYMBOL(ib_get_vf_config);
23212489
23222490 int ib_get_vf_stats(struct ib_device *device, int vf, u8 port,
23232491 struct ifla_vf_stats *stats)
23242492 {
2325
- if (!device->get_vf_stats)
2493
+ if (!device->ops.get_vf_stats)
23262494 return -EOPNOTSUPP;
23272495
2328
- return device->get_vf_stats(device, vf, port, stats);
2496
+ return device->ops.get_vf_stats(device, vf, port, stats);
23292497 }
23302498 EXPORT_SYMBOL(ib_get_vf_stats);
23312499
23322500 int ib_set_vf_guid(struct ib_device *device, int vf, u8 port, u64 guid,
23332501 int type)
23342502 {
2335
- if (!device->set_vf_guid)
2503
+ if (!device->ops.set_vf_guid)
23362504 return -EOPNOTSUPP;
23372505
2338
- return device->set_vf_guid(device, vf, port, guid, type);
2506
+ return device->ops.set_vf_guid(device, vf, port, guid, type);
23392507 }
23402508 EXPORT_SYMBOL(ib_set_vf_guid);
2509
+
2510
+int ib_get_vf_guid(struct ib_device *device, int vf, u8 port,
2511
+ struct ifla_vf_guid *node_guid,
2512
+ struct ifla_vf_guid *port_guid)
2513
+{
2514
+ if (!device->ops.get_vf_guid)
2515
+ return -EOPNOTSUPP;
2516
+
2517
+ return device->ops.get_vf_guid(device, vf, port, node_guid, port_guid);
2518
+}
2519
+EXPORT_SYMBOL(ib_get_vf_guid);
2520
+/**
2521
+ * ib_map_mr_sg_pi() - Map the dma mapped SG lists for PI (protection
2522
+ * information) and set an appropriate memory region for registration.
2523
+ * @mr: memory region
2524
+ * @data_sg: dma mapped scatterlist for data
2525
+ * @data_sg_nents: number of entries in data_sg
2526
+ * @data_sg_offset: offset in bytes into data_sg
2527
+ * @meta_sg: dma mapped scatterlist for metadata
2528
+ * @meta_sg_nents: number of entries in meta_sg
2529
+ * @meta_sg_offset: offset in bytes into meta_sg
2530
+ * @page_size: page vector desired page size
2531
+ *
2532
+ * Constraints:
2533
+ * - The MR must be allocated with type IB_MR_TYPE_INTEGRITY.
2534
+ *
2535
+ * Return: 0 on success.
2536
+ *
2537
+ * After this completes successfully, the memory region
2538
+ * is ready for registration.
2539
+ */
2540
+int ib_map_mr_sg_pi(struct ib_mr *mr, struct scatterlist *data_sg,
2541
+ int data_sg_nents, unsigned int *data_sg_offset,
2542
+ struct scatterlist *meta_sg, int meta_sg_nents,
2543
+ unsigned int *meta_sg_offset, unsigned int page_size)
2544
+{
2545
+ if (unlikely(!mr->device->ops.map_mr_sg_pi ||
2546
+ WARN_ON_ONCE(mr->type != IB_MR_TYPE_INTEGRITY)))
2547
+ return -EOPNOTSUPP;
2548
+
2549
+ mr->page_size = page_size;
2550
+
2551
+ return mr->device->ops.map_mr_sg_pi(mr, data_sg, data_sg_nents,
2552
+ data_sg_offset, meta_sg,
2553
+ meta_sg_nents, meta_sg_offset);
2554
+}
2555
+EXPORT_SYMBOL(ib_map_mr_sg_pi);
23412556
23422557 /**
23432558 * ib_map_mr_sg() - Map the largest prefix of a dma mapped SG list
....@@ -2349,6 +2564,7 @@
23492564 * @page_size: page vector desired page size
23502565 *
23512566 * Constraints:
2567
+ *
23522568 * - The first sg element is allowed to have an offset.
23532569 * - Each sg element must either be aligned to page_size or virtually
23542570 * contiguous to the previous element. In case an sg element has a
....@@ -2367,12 +2583,12 @@
23672583 int ib_map_mr_sg(struct ib_mr *mr, struct scatterlist *sg, int sg_nents,
23682584 unsigned int *sg_offset, unsigned int page_size)
23692585 {
2370
- if (unlikely(!mr->device->map_mr_sg))
2586
+ if (unlikely(!mr->device->ops.map_mr_sg))
23712587 return -EOPNOTSUPP;
23722588
23732589 mr->page_size = page_size;
23742590
2375
- return mr->device->map_mr_sg(mr, sg, sg_nents, sg_offset);
2591
+ return mr->device->ops.map_mr_sg(mr, sg, sg_nents, sg_offset);
23762592 }
23772593 EXPORT_SYMBOL(ib_map_mr_sg);
23782594
....@@ -2382,10 +2598,12 @@
23822598 * @mr: memory region
23832599 * @sgl: dma mapped scatterlist
23842600 * @sg_nents: number of entries in sg
2385
- * @sg_offset_p: IN: start offset in bytes into sg
2386
- * OUT: offset in bytes for element n of the sg of the first
2601
+ * @sg_offset_p: ==== =======================================================
2602
+ * IN start offset in bytes into sg
2603
+ * OUT offset in bytes for element n of the sg of the first
23872604 * byte that has not been processed where n is the return
23882605 * value of this function.
2606
+ * ==== =======================================================
23892607 * @set_page: driver page assignment function pointer
23902608 *
23912609 * Core service helper for drivers to convert the largest
....@@ -2571,10 +2789,11 @@
25712789 */
25722790 void ib_drain_sq(struct ib_qp *qp)
25732791 {
2574
- if (qp->device->drain_sq)
2575
- qp->device->drain_sq(qp);
2792
+ if (qp->device->ops.drain_sq)
2793
+ qp->device->ops.drain_sq(qp);
25762794 else
25772795 __ib_drain_sq(qp);
2796
+ trace_cq_drain_complete(qp->send_cq);
25782797 }
25792798 EXPORT_SYMBOL(ib_drain_sq);
25802799
....@@ -2599,10 +2818,11 @@
25992818 */
26002819 void ib_drain_rq(struct ib_qp *qp)
26012820 {
2602
- if (qp->device->drain_rq)
2603
- qp->device->drain_rq(qp);
2821
+ if (qp->device->ops.drain_rq)
2822
+ qp->device->ops.drain_rq(qp);
26042823 else
26052824 __ib_drain_rq(qp);
2825
+ trace_cq_drain_complete(qp->recv_cq);
26062826 }
26072827 EXPORT_SYMBOL(ib_drain_rq);
26082828
....@@ -2628,3 +2848,88 @@
26282848 ib_drain_rq(qp);
26292849 }
26302850 EXPORT_SYMBOL(ib_drain_qp);
2851
+
2852
+struct net_device *rdma_alloc_netdev(struct ib_device *device, u8 port_num,
2853
+ enum rdma_netdev_t type, const char *name,
2854
+ unsigned char name_assign_type,
2855
+ void (*setup)(struct net_device *))
2856
+{
2857
+ struct rdma_netdev_alloc_params params;
2858
+ struct net_device *netdev;
2859
+ int rc;
2860
+
2861
+ if (!device->ops.rdma_netdev_get_params)
2862
+ return ERR_PTR(-EOPNOTSUPP);
2863
+
2864
+ rc = device->ops.rdma_netdev_get_params(device, port_num, type,
2865
+ &params);
2866
+ if (rc)
2867
+ return ERR_PTR(rc);
2868
+
2869
+ netdev = alloc_netdev_mqs(params.sizeof_priv, name, name_assign_type,
2870
+ setup, params.txqs, params.rxqs);
2871
+ if (!netdev)
2872
+ return ERR_PTR(-ENOMEM);
2873
+
2874
+ return netdev;
2875
+}
2876
+EXPORT_SYMBOL(rdma_alloc_netdev);
2877
+
2878
+int rdma_init_netdev(struct ib_device *device, u8 port_num,
2879
+ enum rdma_netdev_t type, const char *name,
2880
+ unsigned char name_assign_type,
2881
+ void (*setup)(struct net_device *),
2882
+ struct net_device *netdev)
2883
+{
2884
+ struct rdma_netdev_alloc_params params;
2885
+ int rc;
2886
+
2887
+ if (!device->ops.rdma_netdev_get_params)
2888
+ return -EOPNOTSUPP;
2889
+
2890
+ rc = device->ops.rdma_netdev_get_params(device, port_num, type,
2891
+ &params);
2892
+ if (rc)
2893
+ return rc;
2894
+
2895
+ return params.initialize_rdma_netdev(device, port_num,
2896
+ netdev, params.param);
2897
+}
2898
+EXPORT_SYMBOL(rdma_init_netdev);
2899
+
2900
+void __rdma_block_iter_start(struct ib_block_iter *biter,
2901
+ struct scatterlist *sglist, unsigned int nents,
2902
+ unsigned long pgsz)
2903
+{
2904
+ memset(biter, 0, sizeof(struct ib_block_iter));
2905
+ biter->__sg = sglist;
2906
+ biter->__sg_nents = nents;
2907
+
2908
+ /* Driver provides best block size to use */
2909
+ biter->__pg_bit = __fls(pgsz);
2910
+}
2911
+EXPORT_SYMBOL(__rdma_block_iter_start);
2912
+
2913
+bool __rdma_block_iter_next(struct ib_block_iter *biter)
2914
+{
2915
+ unsigned int block_offset;
2916
+ unsigned int sg_delta;
2917
+
2918
+ if (!biter->__sg_nents || !biter->__sg)
2919
+ return false;
2920
+
2921
+ biter->__dma_addr = sg_dma_address(biter->__sg) + biter->__sg_advance;
2922
+ block_offset = biter->__dma_addr & (BIT_ULL(biter->__pg_bit) - 1);
2923
+ sg_delta = BIT_ULL(biter->__pg_bit) - block_offset;
2924
+
2925
+ if (sg_dma_len(biter->__sg) - biter->__sg_advance > sg_delta) {
2926
+ biter->__sg_advance += sg_delta;
2927
+ } else {
2928
+ biter->__sg_advance = 0;
2929
+ biter->__sg = sg_next(biter->__sg);
2930
+ biter->__sg_nents--;
2931
+ }
2932
+
2933
+ return true;
2934
+}
2935
+EXPORT_SYMBOL(__rdma_block_iter_next);