1 /* QLogic qedr NIC Driver
2 * Copyright (c) 2015-2017 QLogic Corporation
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and /or other materials
21 * provided with the distribution.
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35 #include <net/addrconf.h>
36 #include <net/route.h>
37 #include <net/ip6_route.h>
40 #include "qedr_iw_cm.h"
43 qedr_fill_sockaddr4(const struct qed_iwarp_cm_info
*cm_info
,
44 struct iw_cm_event
*event
)
46 struct sockaddr_in
*laddr
= (struct sockaddr_in
*)&event
->local_addr
;
47 struct sockaddr_in
*raddr
= (struct sockaddr_in
*)&event
->remote_addr
;
49 laddr
->sin_family
= AF_INET
;
50 raddr
->sin_family
= AF_INET
;
52 laddr
->sin_port
= htons(cm_info
->local_port
);
53 raddr
->sin_port
= htons(cm_info
->remote_port
);
55 laddr
->sin_addr
.s_addr
= htonl(cm_info
->local_ip
[0]);
56 raddr
->sin_addr
.s_addr
= htonl(cm_info
->remote_ip
[0]);
60 qedr_fill_sockaddr6(const struct qed_iwarp_cm_info
*cm_info
,
61 struct iw_cm_event
*event
)
63 struct sockaddr_in6
*laddr6
= (struct sockaddr_in6
*)&event
->local_addr
;
64 struct sockaddr_in6
*raddr6
=
65 (struct sockaddr_in6
*)&event
->remote_addr
;
68 laddr6
->sin6_family
= AF_INET6
;
69 raddr6
->sin6_family
= AF_INET6
;
71 laddr6
->sin6_port
= htons(cm_info
->local_port
);
72 raddr6
->sin6_port
= htons(cm_info
->remote_port
);
74 for (i
= 0; i
< 4; i
++) {
75 laddr6
->sin6_addr
.in6_u
.u6_addr32
[i
] =
76 htonl(cm_info
->local_ip
[i
]);
77 raddr6
->sin6_addr
.in6_u
.u6_addr32
[i
] =
78 htonl(cm_info
->remote_ip
[i
]);
82 static void qedr_iw_free_qp(struct kref
*ref
)
84 struct qedr_qp
*qp
= container_of(ref
, struct qedr_qp
, refcnt
);
86 complete(&qp
->qp_rel_comp
);
90 qedr_iw_free_ep(struct kref
*ref
)
92 struct qedr_iw_ep
*ep
= container_of(ref
, struct qedr_iw_ep
, refcnt
);
95 kref_put(&ep
->qp
->refcnt
, qedr_iw_free_qp
);
98 ep
->cm_id
->rem_ref(ep
->cm_id
);
104 qedr_iw_mpa_request(void *context
, struct qed_iwarp_cm_event_params
*params
)
106 struct qedr_iw_listener
*listener
= (struct qedr_iw_listener
*)context
;
107 struct qedr_dev
*dev
= listener
->dev
;
108 struct iw_cm_event event
;
109 struct qedr_iw_ep
*ep
;
111 ep
= kzalloc(sizeof(*ep
), GFP_ATOMIC
);
116 ep
->qed_context
= params
->ep_context
;
117 kref_init(&ep
->refcnt
);
119 memset(&event
, 0, sizeof(event
));
120 event
.event
= IW_CM_EVENT_CONNECT_REQUEST
;
121 event
.status
= params
->status
;
123 if (!IS_ENABLED(CONFIG_IPV6
) ||
124 params
->cm_info
->ip_version
== QED_TCP_IPV4
)
125 qedr_fill_sockaddr4(params
->cm_info
, &event
);
127 qedr_fill_sockaddr6(params
->cm_info
, &event
);
129 event
.provider_data
= (void *)ep
;
130 event
.private_data
= (void *)params
->cm_info
->private_data
;
131 event
.private_data_len
= (u8
)params
->cm_info
->private_data_len
;
132 event
.ord
= params
->cm_info
->ord
;
133 event
.ird
= params
->cm_info
->ird
;
135 listener
->cm_id
->event_handler(listener
->cm_id
, &event
);
139 qedr_iw_issue_event(void *context
,
140 struct qed_iwarp_cm_event_params
*params
,
141 enum iw_cm_event_type event_type
)
143 struct qedr_iw_ep
*ep
= (struct qedr_iw_ep
*)context
;
144 struct iw_cm_event event
;
146 memset(&event
, 0, sizeof(event
));
147 event
.status
= params
->status
;
148 event
.event
= event_type
;
150 if (params
->cm_info
) {
151 event
.ird
= params
->cm_info
->ird
;
152 event
.ord
= params
->cm_info
->ord
;
153 /* Only connect_request and reply have valid private data
154 * the rest of the events this may be left overs from
155 * connection establishment. CONNECT_REQUEST is issued via
156 * qedr_iw_mpa_request
158 if (event_type
== IW_CM_EVENT_CONNECT_REPLY
) {
159 event
.private_data_len
=
160 params
->cm_info
->private_data_len
;
162 (void *)params
->cm_info
->private_data
;
167 ep
->cm_id
->event_handler(ep
->cm_id
, &event
);
171 qedr_iw_close_event(void *context
, struct qed_iwarp_cm_event_params
*params
)
173 struct qedr_iw_ep
*ep
= (struct qedr_iw_ep
*)context
;
176 qedr_iw_issue_event(context
, params
, IW_CM_EVENT_CLOSE
);
178 kref_put(&ep
->refcnt
, qedr_iw_free_ep
);
182 qedr_iw_qp_event(void *context
,
183 struct qed_iwarp_cm_event_params
*params
,
184 enum ib_event_type ib_event
, char *str
)
186 struct qedr_iw_ep
*ep
= (struct qedr_iw_ep
*)context
;
187 struct qedr_dev
*dev
= ep
->dev
;
188 struct ib_qp
*ibqp
= &ep
->qp
->ibqp
;
189 struct ib_event event
;
191 DP_NOTICE(dev
, "QP error received: %s\n", str
);
193 if (ibqp
->event_handler
) {
194 event
.event
= ib_event
;
195 event
.device
= ibqp
->device
;
196 event
.element
.qp
= ibqp
;
197 ibqp
->event_handler(&event
, ibqp
->qp_context
);
201 struct qedr_discon_work
{
202 struct work_struct work
;
203 struct qedr_iw_ep
*ep
;
204 enum qed_iwarp_event_type event
;
208 static void qedr_iw_disconnect_worker(struct work_struct
*work
)
210 struct qedr_discon_work
*dwork
=
211 container_of(work
, struct qedr_discon_work
, work
);
212 struct qed_rdma_modify_qp_in_params qp_params
= { 0 };
213 struct qedr_iw_ep
*ep
= dwork
->ep
;
214 struct qedr_dev
*dev
= ep
->dev
;
215 struct qedr_qp
*qp
= ep
->qp
;
216 struct iw_cm_event event
;
218 /* The qp won't be released until we release the ep.
219 * the ep's refcnt was increased before calling this
220 * function, therefore it is safe to access qp
222 if (test_and_set_bit(QEDR_IWARP_CM_WAIT_FOR_DISCONNECT
,
223 &qp
->iwarp_cm_flags
))
226 memset(&event
, 0, sizeof(event
));
227 event
.status
= dwork
->status
;
228 event
.event
= IW_CM_EVENT_DISCONNECT
;
230 /* Success means graceful disconnect was requested. modifying
231 * to SQD is translated to graceful disconnect. O/w reset is sent
234 qp_params
.new_state
= QED_ROCE_QP_STATE_ERR
;
236 qp_params
.new_state
= QED_ROCE_QP_STATE_SQD
;
240 ep
->cm_id
->event_handler(ep
->cm_id
, &event
);
242 SET_FIELD(qp_params
.modify_flags
,
243 QED_RDMA_MODIFY_QP_VALID_NEW_STATE
, 1);
245 dev
->ops
->rdma_modify_qp(dev
->rdma_ctx
, qp
->qed_qp
, &qp_params
);
247 complete(&ep
->qp
->iwarp_cm_comp
);
250 kref_put(&ep
->refcnt
, qedr_iw_free_ep
);
254 qedr_iw_disconnect_event(void *context
,
255 struct qed_iwarp_cm_event_params
*params
)
257 struct qedr_discon_work
*work
;
258 struct qedr_iw_ep
*ep
= (struct qedr_iw_ep
*)context
;
259 struct qedr_dev
*dev
= ep
->dev
;
261 work
= kzalloc(sizeof(*work
), GFP_ATOMIC
);
265 /* We can't get a close event before disconnect, but since
266 * we're scheduling a work queue we need to make sure close
267 * won't delete the ep, so we increase the refcnt
269 kref_get(&ep
->refcnt
);
272 work
->event
= params
->event
;
273 work
->status
= params
->status
;
275 INIT_WORK(&work
->work
, qedr_iw_disconnect_worker
);
276 queue_work(dev
->iwarp_wq
, &work
->work
);
280 qedr_iw_passive_complete(void *context
,
281 struct qed_iwarp_cm_event_params
*params
)
283 struct qedr_iw_ep
*ep
= (struct qedr_iw_ep
*)context
;
284 struct qedr_dev
*dev
= ep
->dev
;
286 /* We will only reach the following state if MPA_REJECT was called on
287 * passive. In this case there will be no associated QP.
289 if ((params
->status
== -ECONNREFUSED
) && (!ep
->qp
)) {
290 DP_DEBUG(dev
, QEDR_MSG_IWARP
,
291 "PASSIVE connection refused releasing ep...\n");
292 kref_put(&ep
->refcnt
, qedr_iw_free_ep
);
296 complete(&ep
->qp
->iwarp_cm_comp
);
297 qedr_iw_issue_event(context
, params
, IW_CM_EVENT_ESTABLISHED
);
299 if (params
->status
< 0)
300 qedr_iw_close_event(context
, params
);
304 qedr_iw_active_complete(void *context
,
305 struct qed_iwarp_cm_event_params
*params
)
307 struct qedr_iw_ep
*ep
= (struct qedr_iw_ep
*)context
;
309 complete(&ep
->qp
->iwarp_cm_comp
);
310 qedr_iw_issue_event(context
, params
, IW_CM_EVENT_CONNECT_REPLY
);
312 if (params
->status
< 0)
313 kref_put(&ep
->refcnt
, qedr_iw_free_ep
);
317 qedr_iw_mpa_reply(void *context
, struct qed_iwarp_cm_event_params
*params
)
319 struct qedr_iw_ep
*ep
= (struct qedr_iw_ep
*)context
;
320 struct qedr_dev
*dev
= ep
->dev
;
321 struct qed_iwarp_send_rtr_in rtr_in
;
323 rtr_in
.ep_context
= params
->ep_context
;
325 return dev
->ops
->iwarp_send_rtr(dev
->rdma_ctx
, &rtr_in
);
329 qedr_iw_event_handler(void *context
, struct qed_iwarp_cm_event_params
*params
)
331 struct qedr_iw_ep
*ep
= (struct qedr_iw_ep
*)context
;
332 struct qedr_dev
*dev
= ep
->dev
;
334 switch (params
->event
) {
335 case QED_IWARP_EVENT_MPA_REQUEST
:
336 qedr_iw_mpa_request(context
, params
);
338 case QED_IWARP_EVENT_ACTIVE_MPA_REPLY
:
339 qedr_iw_mpa_reply(context
, params
);
341 case QED_IWARP_EVENT_PASSIVE_COMPLETE
:
342 qedr_iw_passive_complete(context
, params
);
344 case QED_IWARP_EVENT_ACTIVE_COMPLETE
:
345 qedr_iw_active_complete(context
, params
);
347 case QED_IWARP_EVENT_DISCONNECT
:
348 qedr_iw_disconnect_event(context
, params
);
350 case QED_IWARP_EVENT_CLOSE
:
351 qedr_iw_close_event(context
, params
);
353 case QED_IWARP_EVENT_RQ_EMPTY
:
354 qedr_iw_qp_event(context
, params
, IB_EVENT_QP_FATAL
,
355 "QED_IWARP_EVENT_RQ_EMPTY");
357 case QED_IWARP_EVENT_IRQ_FULL
:
358 qedr_iw_qp_event(context
, params
, IB_EVENT_QP_FATAL
,
359 "QED_IWARP_EVENT_IRQ_FULL");
361 case QED_IWARP_EVENT_LLP_TIMEOUT
:
362 qedr_iw_qp_event(context
, params
, IB_EVENT_QP_FATAL
,
363 "QED_IWARP_EVENT_LLP_TIMEOUT");
365 case QED_IWARP_EVENT_REMOTE_PROTECTION_ERROR
:
366 qedr_iw_qp_event(context
, params
, IB_EVENT_QP_ACCESS_ERR
,
367 "QED_IWARP_EVENT_REMOTE_PROTECTION_ERROR");
369 case QED_IWARP_EVENT_CQ_OVERFLOW
:
370 qedr_iw_qp_event(context
, params
, IB_EVENT_QP_FATAL
,
371 "QED_IWARP_EVENT_CQ_OVERFLOW");
373 case QED_IWARP_EVENT_QP_CATASTROPHIC
:
374 qedr_iw_qp_event(context
, params
, IB_EVENT_QP_FATAL
,
375 "QED_IWARP_EVENT_QP_CATASTROPHIC");
377 case QED_IWARP_EVENT_LOCAL_ACCESS_ERROR
:
378 qedr_iw_qp_event(context
, params
, IB_EVENT_QP_ACCESS_ERR
,
379 "QED_IWARP_EVENT_LOCAL_ACCESS_ERROR");
381 case QED_IWARP_EVENT_REMOTE_OPERATION_ERROR
:
382 qedr_iw_qp_event(context
, params
, IB_EVENT_QP_FATAL
,
383 "QED_IWARP_EVENT_REMOTE_OPERATION_ERROR");
385 case QED_IWARP_EVENT_TERMINATE_RECEIVED
:
386 DP_NOTICE(dev
, "Got terminate message\n");
389 DP_NOTICE(dev
, "Unknown event received %d\n", params
->event
);
395 static u16
qedr_iw_get_vlan_ipv4(struct qedr_dev
*dev
, u32
*addr
)
397 struct net_device
*ndev
;
400 ndev
= ip_dev_find(&init_net
, htonl(addr
[0]));
403 vlan_id
= rdma_vlan_dev_vlan_id(ndev
);
406 if (vlan_id
== 0xffff)
411 static u16
qedr_iw_get_vlan_ipv6(u32
*addr
)
413 struct net_device
*ndev
= NULL
;
414 struct in6_addr laddr6
;
418 if (!IS_ENABLED(CONFIG_IPV6
))
421 for (i
= 0; i
< 4; i
++)
422 laddr6
.in6_u
.u6_addr32
[i
] = htonl(addr
[i
]);
425 for_each_netdev_rcu(&init_net
, ndev
) {
426 if (ipv6_chk_addr(&init_net
, &laddr6
, ndev
, 1)) {
427 vlan_id
= rdma_vlan_dev_vlan_id(ndev
);
433 if (vlan_id
== 0xffff)
440 qedr_addr4_resolve(struct qedr_dev
*dev
,
441 struct sockaddr_in
*src_in
,
442 struct sockaddr_in
*dst_in
, u8
*dst_mac
)
444 __be32 src_ip
= src_in
->sin_addr
.s_addr
;
445 __be32 dst_ip
= dst_in
->sin_addr
.s_addr
;
446 struct neighbour
*neigh
= NULL
;
447 struct rtable
*rt
= NULL
;
450 rt
= ip_route_output(&init_net
, dst_ip
, src_ip
, 0, 0,
453 DP_ERR(dev
, "ip_route_output returned error\n");
457 neigh
= dst_neigh_lookup(&rt
->dst
, &dst_ip
);
461 if (neigh
->nud_state
& NUD_VALID
) {
462 ether_addr_copy(dst_mac
, neigh
->ha
);
463 DP_DEBUG(dev
, QEDR_MSG_QP
, "mac_addr=[%pM]\n", dst_mac
);
465 neigh_event_send(neigh
, NULL
);
468 neigh_release(neigh
);
477 qedr_addr6_resolve(struct qedr_dev
*dev
,
478 struct sockaddr_in6
*src_in
,
479 struct sockaddr_in6
*dst_in
, u8
*dst_mac
)
481 struct neighbour
*neigh
= NULL
;
482 struct dst_entry
*dst
;
486 memset(&fl6
, 0, sizeof(fl6
));
487 fl6
.daddr
= dst_in
->sin6_addr
;
488 fl6
.saddr
= src_in
->sin6_addr
;
490 dst
= ip6_route_output(&init_net
, NULL
, &fl6
);
492 if ((!dst
) || dst
->error
) {
495 "ip6_route_output returned dst->error = %d\n",
501 neigh
= dst_neigh_lookup(dst
, &fl6
.daddr
);
504 if (neigh
->nud_state
& NUD_VALID
) {
505 ether_addr_copy(dst_mac
, neigh
->ha
);
506 DP_DEBUG(dev
, QEDR_MSG_QP
, "mac_addr=[%pM]\n", dst_mac
);
508 neigh_event_send(neigh
, NULL
);
511 neigh_release(neigh
);
519 static struct qedr_qp
*qedr_iw_load_qp(struct qedr_dev
*dev
, u32 qpn
)
524 qp
= xa_load(&dev
->qps
, qpn
);
526 kref_get(&qp
->refcnt
);
527 xa_unlock(&dev
->qps
);
532 int qedr_iw_connect(struct iw_cm_id
*cm_id
, struct iw_cm_conn_param
*conn_param
)
534 struct qedr_dev
*dev
= get_qedr_dev(cm_id
->device
);
535 struct qed_iwarp_connect_out out_params
;
536 struct qed_iwarp_connect_in in_params
;
537 struct qed_iwarp_cm_info
*cm_info
;
538 struct sockaddr_in6
*laddr6
;
539 struct sockaddr_in6
*raddr6
;
540 struct sockaddr_in
*laddr
;
541 struct sockaddr_in
*raddr
;
542 struct qedr_iw_ep
*ep
;
547 laddr
= (struct sockaddr_in
*)&cm_id
->m_local_addr
;
548 raddr
= (struct sockaddr_in
*)&cm_id
->m_remote_addr
;
549 laddr6
= (struct sockaddr_in6
*)&cm_id
->m_local_addr
;
550 raddr6
= (struct sockaddr_in6
*)&cm_id
->m_remote_addr
;
552 DP_DEBUG(dev
, QEDR_MSG_IWARP
, "MAPPED %d %d\n",
553 ntohs(((struct sockaddr_in
*)&cm_id
->remote_addr
)->sin_port
),
554 ntohs(raddr
->sin_port
));
556 DP_DEBUG(dev
, QEDR_MSG_IWARP
,
557 "Connect source address: %pISpc, remote address: %pISpc\n",
558 &cm_id
->local_addr
, &cm_id
->remote_addr
);
560 if (!laddr
->sin_port
|| !raddr
->sin_port
)
563 ep
= kzalloc(sizeof(*ep
), GFP_KERNEL
);
568 kref_init(&ep
->refcnt
);
570 qp
= qedr_iw_load_qp(dev
, conn_param
->qpn
);
577 cm_id
->add_ref(cm_id
);
580 in_params
.event_cb
= qedr_iw_event_handler
;
581 in_params
.cb_context
= ep
;
583 cm_info
= &in_params
.cm_info
;
584 memset(cm_info
->local_ip
, 0, sizeof(cm_info
->local_ip
));
585 memset(cm_info
->remote_ip
, 0, sizeof(cm_info
->remote_ip
));
587 if (!IS_ENABLED(CONFIG_IPV6
) ||
588 cm_id
->remote_addr
.ss_family
== AF_INET
) {
589 cm_info
->ip_version
= QED_TCP_IPV4
;
591 cm_info
->remote_ip
[0] = ntohl(raddr
->sin_addr
.s_addr
);
592 cm_info
->local_ip
[0] = ntohl(laddr
->sin_addr
.s_addr
);
593 cm_info
->remote_port
= ntohs(raddr
->sin_port
);
594 cm_info
->local_port
= ntohs(laddr
->sin_port
);
595 cm_info
->vlan
= qedr_iw_get_vlan_ipv4(dev
, cm_info
->local_ip
);
597 rc
= qedr_addr4_resolve(dev
, laddr
, raddr
,
598 (u8
*)in_params
.remote_mac_addr
);
600 in_params
.mss
= dev
->iwarp_max_mtu
-
601 (sizeof(struct iphdr
) + sizeof(struct tcphdr
));
604 in_params
.cm_info
.ip_version
= QED_TCP_IPV6
;
606 for (i
= 0; i
< 4; i
++) {
607 cm_info
->remote_ip
[i
] =
608 ntohl(raddr6
->sin6_addr
.in6_u
.u6_addr32
[i
]);
609 cm_info
->local_ip
[i
] =
610 ntohl(laddr6
->sin6_addr
.in6_u
.u6_addr32
[i
]);
613 cm_info
->local_port
= ntohs(laddr6
->sin6_port
);
614 cm_info
->remote_port
= ntohs(raddr6
->sin6_port
);
616 in_params
.mss
= dev
->iwarp_max_mtu
-
617 (sizeof(struct ipv6hdr
) + sizeof(struct tcphdr
));
619 cm_info
->vlan
= qedr_iw_get_vlan_ipv6(cm_info
->local_ip
);
621 rc
= qedr_addr6_resolve(dev
, laddr6
, raddr6
,
622 (u8
*)in_params
.remote_mac_addr
);
627 DP_DEBUG(dev
, QEDR_MSG_IWARP
,
628 "ord = %d ird=%d private_data=%p private_data_len=%d rq_psn=%d\n",
629 conn_param
->ord
, conn_param
->ird
, conn_param
->private_data
,
630 conn_param
->private_data_len
, qp
->rq_psn
);
632 cm_info
->ord
= conn_param
->ord
;
633 cm_info
->ird
= conn_param
->ird
;
634 cm_info
->private_data
= conn_param
->private_data
;
635 cm_info
->private_data_len
= conn_param
->private_data_len
;
636 in_params
.qp
= qp
->qed_qp
;
637 memcpy(in_params
.local_mac_addr
, dev
->ndev
->dev_addr
, ETH_ALEN
);
639 if (test_and_set_bit(QEDR_IWARP_CM_WAIT_FOR_CONNECT
,
640 &qp
->iwarp_cm_flags
)) {
642 goto err
; /* QP already being destroyed */
645 rc
= dev
->ops
->iwarp_connect(dev
->rdma_ctx
, &in_params
, &out_params
);
647 complete(&qp
->iwarp_cm_comp
);
654 kref_put(&ep
->refcnt
, qedr_iw_free_ep
);
658 int qedr_iw_create_listen(struct iw_cm_id
*cm_id
, int backlog
)
660 struct qedr_dev
*dev
= get_qedr_dev(cm_id
->device
);
661 struct qedr_iw_listener
*listener
;
662 struct qed_iwarp_listen_in iparams
;
663 struct qed_iwarp_listen_out oparams
;
664 struct sockaddr_in
*laddr
;
665 struct sockaddr_in6
*laddr6
;
669 laddr
= (struct sockaddr_in
*)&cm_id
->m_local_addr
;
670 laddr6
= (struct sockaddr_in6
*)&cm_id
->m_local_addr
;
672 DP_DEBUG(dev
, QEDR_MSG_IWARP
,
673 "Create Listener address: %pISpc\n", &cm_id
->local_addr
);
675 listener
= kzalloc(sizeof(*listener
), GFP_KERNEL
);
680 cm_id
->add_ref(cm_id
);
681 listener
->cm_id
= cm_id
;
682 listener
->backlog
= backlog
;
684 iparams
.cb_context
= listener
;
685 iparams
.event_cb
= qedr_iw_event_handler
;
686 iparams
.max_backlog
= backlog
;
688 if (!IS_ENABLED(CONFIG_IPV6
) ||
689 cm_id
->local_addr
.ss_family
== AF_INET
) {
690 iparams
.ip_version
= QED_TCP_IPV4
;
691 memset(iparams
.ip_addr
, 0, sizeof(iparams
.ip_addr
));
693 iparams
.ip_addr
[0] = ntohl(laddr
->sin_addr
.s_addr
);
694 iparams
.port
= ntohs(laddr
->sin_port
);
695 iparams
.vlan
= qedr_iw_get_vlan_ipv4(dev
, iparams
.ip_addr
);
697 iparams
.ip_version
= QED_TCP_IPV6
;
699 for (i
= 0; i
< 4; i
++) {
701 ntohl(laddr6
->sin6_addr
.in6_u
.u6_addr32
[i
]);
704 iparams
.port
= ntohs(laddr6
->sin6_port
);
706 iparams
.vlan
= qedr_iw_get_vlan_ipv6(iparams
.ip_addr
);
708 rc
= dev
->ops
->iwarp_create_listen(dev
->rdma_ctx
, &iparams
, &oparams
);
712 listener
->qed_handle
= oparams
.handle
;
713 cm_id
->provider_data
= listener
;
717 cm_id
->rem_ref(cm_id
);
722 int qedr_iw_destroy_listen(struct iw_cm_id
*cm_id
)
724 struct qedr_iw_listener
*listener
= cm_id
->provider_data
;
725 struct qedr_dev
*dev
= get_qedr_dev(cm_id
->device
);
728 if (listener
->qed_handle
)
729 rc
= dev
->ops
->iwarp_destroy_listen(dev
->rdma_ctx
,
730 listener
->qed_handle
);
732 cm_id
->rem_ref(cm_id
);
737 int qedr_iw_accept(struct iw_cm_id
*cm_id
, struct iw_cm_conn_param
*conn_param
)
739 struct qedr_iw_ep
*ep
= (struct qedr_iw_ep
*)cm_id
->provider_data
;
740 struct qedr_dev
*dev
= ep
->dev
;
742 struct qed_iwarp_accept_in params
;
745 DP_DEBUG(dev
, QEDR_MSG_IWARP
, "Accept on qpid=%d\n", conn_param
->qpn
);
747 qp
= qedr_iw_load_qp(dev
, conn_param
->qpn
);
749 DP_ERR(dev
, "Invalid QP number %d\n", conn_param
->qpn
);
754 cm_id
->add_ref(cm_id
);
757 params
.ep_context
= ep
->qed_context
;
758 params
.cb_context
= ep
;
759 params
.qp
= ep
->qp
->qed_qp
;
760 params
.private_data
= conn_param
->private_data
;
761 params
.private_data_len
= conn_param
->private_data_len
;
762 params
.ird
= conn_param
->ird
;
763 params
.ord
= conn_param
->ord
;
765 if (test_and_set_bit(QEDR_IWARP_CM_WAIT_FOR_CONNECT
,
766 &qp
->iwarp_cm_flags
)) {
768 goto err
; /* QP already destroyed */
771 rc
= dev
->ops
->iwarp_accept(dev
->rdma_ctx
, ¶ms
);
773 complete(&qp
->iwarp_cm_comp
);
780 kref_put(&ep
->refcnt
, qedr_iw_free_ep
);
785 int qedr_iw_reject(struct iw_cm_id
*cm_id
, const void *pdata
, u8 pdata_len
)
787 struct qedr_iw_ep
*ep
= (struct qedr_iw_ep
*)cm_id
->provider_data
;
788 struct qedr_dev
*dev
= ep
->dev
;
789 struct qed_iwarp_reject_in params
;
791 params
.ep_context
= ep
->qed_context
;
792 params
.cb_context
= ep
;
793 params
.private_data
= pdata
;
794 params
.private_data_len
= pdata_len
;
797 return dev
->ops
->iwarp_reject(dev
->rdma_ctx
, ¶ms
);
800 void qedr_iw_qp_add_ref(struct ib_qp
*ibqp
)
802 struct qedr_qp
*qp
= get_qedr_qp(ibqp
);
804 kref_get(&qp
->refcnt
);
807 void qedr_iw_qp_rem_ref(struct ib_qp
*ibqp
)
809 struct qedr_qp
*qp
= get_qedr_qp(ibqp
);
811 kref_put(&qp
->refcnt
, qedr_iw_free_qp
);
814 struct ib_qp
*qedr_iw_get_qp(struct ib_device
*ibdev
, int qpn
)
816 struct qedr_dev
*dev
= get_qedr_dev(ibdev
);
818 return xa_load(&dev
->qps
, qpn
);