Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.15.
  1/* QLogic qedr NIC Driver
  2 * Copyright (c) 2015-2017  QLogic Corporation
  3 *
  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:
  9 *
 10 *     Redistribution and use in source and binary forms, with or
 11 *     without modification, are permitted provided that the following
 12 *     conditions are met:
 13 *
 14 *      - Redistributions of source code must retain the above
 15 *        copyright notice, this list of conditions and the following
 16 *        disclaimer.
 17 *
 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.
 22 *
 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
 30 * SOFTWARE.
 31 */
 32#include <net/ip.h>
 33#include <net/ipv6.h>
 34#include <net/udp.h>
 35#include <net/addrconf.h>
 36#include <net/route.h>
 37#include <net/ip6_route.h>
 38#include <net/flow.h>
 39#include "qedr.h"
 40#include "qedr_iw_cm.h"
 41
 42static inline void
 43qedr_fill_sockaddr4(const struct qed_iwarp_cm_info *cm_info,
 44		    struct iw_cm_event *event)
 45{
 46	struct sockaddr_in *laddr = (struct sockaddr_in *)&event->local_addr;
 47	struct sockaddr_in *raddr = (struct sockaddr_in *)&event->remote_addr;
 48
 49	laddr->sin_family = AF_INET;
 50	raddr->sin_family = AF_INET;
 51
 52	laddr->sin_port = htons(cm_info->local_port);
 53	raddr->sin_port = htons(cm_info->remote_port);
 54
 55	laddr->sin_addr.s_addr = htonl(cm_info->local_ip[0]);
 56	raddr->sin_addr.s_addr = htonl(cm_info->remote_ip[0]);
 57}
 58
 59static inline void
 60qedr_fill_sockaddr6(const struct qed_iwarp_cm_info *cm_info,
 61		    struct iw_cm_event *event)
 62{
 63	struct sockaddr_in6 *laddr6 = (struct sockaddr_in6 *)&event->local_addr;
 64	struct sockaddr_in6 *raddr6 =
 65	    (struct sockaddr_in6 *)&event->remote_addr;
 66	int i;
 67
 68	laddr6->sin6_family = AF_INET6;
 69	raddr6->sin6_family = AF_INET6;
 70
 71	laddr6->sin6_port = htons(cm_info->local_port);
 72	raddr6->sin6_port = htons(cm_info->remote_port);
 73
 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]);
 79	}
 80}
 81
 82static void qedr_iw_free_qp(struct kref *ref)
 83{
 84	struct qedr_qp *qp = container_of(ref, struct qedr_qp, refcnt);
 85
 86	complete(&qp->qp_rel_comp);
 87}
 88
 89static void
 90qedr_iw_free_ep(struct kref *ref)
 91{
 92	struct qedr_iw_ep *ep = container_of(ref, struct qedr_iw_ep, refcnt);
 93
 94	if (ep->qp)
 95		kref_put(&ep->qp->refcnt, qedr_iw_free_qp);
 96
 97	if (ep->cm_id)
 98		ep->cm_id->rem_ref(ep->cm_id);
 99
100	kfree(ep);
101}
102
103static void
104qedr_iw_mpa_request(void *context, struct qed_iwarp_cm_event_params *params)
105{
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;
110
111	ep = kzalloc(sizeof(*ep), GFP_ATOMIC);
112	if (!ep)
113		return;
114
115	ep->dev = dev;
116	ep->qed_context = params->ep_context;
117	kref_init(&ep->refcnt);
118
119	memset(&event, 0, sizeof(event));
120	event.event = IW_CM_EVENT_CONNECT_REQUEST;
121	event.status = params->status;
122
123	if (!IS_ENABLED(CONFIG_IPV6) ||
124	    params->cm_info->ip_version == QED_TCP_IPV4)
125		qedr_fill_sockaddr4(params->cm_info, &event);
126	else
127		qedr_fill_sockaddr6(params->cm_info, &event);
128
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;
134
135	listener->cm_id->event_handler(listener->cm_id, &event);
136}
137
138static void
139qedr_iw_issue_event(void *context,
140		    struct qed_iwarp_cm_event_params *params,
141		    enum iw_cm_event_type event_type)
142{
143	struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context;
144	struct iw_cm_event event;
145
146	memset(&event, 0, sizeof(event));
147	event.status = params->status;
148	event.event = event_type;
149
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
157		 */
158		if (event_type == IW_CM_EVENT_CONNECT_REPLY) {
159			event.private_data_len =
160				params->cm_info->private_data_len;
161			event.private_data =
162				(void *)params->cm_info->private_data;
163		}
164	}
165
166	if (ep->cm_id)
167		ep->cm_id->event_handler(ep->cm_id, &event);
168}
169
170static void
171qedr_iw_close_event(void *context, struct qed_iwarp_cm_event_params *params)
172{
173	struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context;
174
175	if (ep->cm_id)
176		qedr_iw_issue_event(context, params, IW_CM_EVENT_CLOSE);
177
178	kref_put(&ep->refcnt, qedr_iw_free_ep);
179}
180
181static void
182qedr_iw_qp_event(void *context,
183		 struct qed_iwarp_cm_event_params *params,
184		 enum ib_event_type ib_event, char *str)
185{
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;
190
191	DP_NOTICE(dev, "QP error received: %s\n", str);
192
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);
198	}
199}
200
201struct qedr_discon_work {
202	struct work_struct		work;
203	struct qedr_iw_ep		*ep;
204	enum qed_iwarp_event_type	event;
205	int				status;
206};
207
208static void qedr_iw_disconnect_worker(struct work_struct *work)
209{
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;
217
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
221	 */
222	if (test_and_set_bit(QEDR_IWARP_CM_WAIT_FOR_DISCONNECT,
223			     &qp->iwarp_cm_flags))
224		goto out;
225
226	memset(&event, 0, sizeof(event));
227	event.status = dwork->status;
228	event.event = IW_CM_EVENT_DISCONNECT;
229
230	/* Success means graceful disconnect was requested. modifying
231	 * to SQD is translated to graceful disconnect. O/w reset is sent
232	 */
233	if (dwork->status)
234		qp_params.new_state = QED_ROCE_QP_STATE_ERR;
235	else
236		qp_params.new_state = QED_ROCE_QP_STATE_SQD;
237
238
239	if (ep->cm_id)
240		ep->cm_id->event_handler(ep->cm_id, &event);
241
242	SET_FIELD(qp_params.modify_flags,
243		  QED_RDMA_MODIFY_QP_VALID_NEW_STATE, 1);
244
245	dev->ops->rdma_modify_qp(dev->rdma_ctx, qp->qed_qp, &qp_params);
246
247	complete(&ep->qp->iwarp_cm_comp);
248out:
249	kfree(dwork);
250	kref_put(&ep->refcnt, qedr_iw_free_ep);
251}
252
253static void
254qedr_iw_disconnect_event(void *context,
255			 struct qed_iwarp_cm_event_params *params)
256{
257	struct qedr_discon_work *work;
258	struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context;
259	struct qedr_dev *dev = ep->dev;
260
261	work = kzalloc(sizeof(*work), GFP_ATOMIC);
262	if (!work)
263		return;
264
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
268	 */
269	kref_get(&ep->refcnt);
270
271	work->ep = ep;
272	work->event = params->event;
273	work->status = params->status;
274
275	INIT_WORK(&work->work, qedr_iw_disconnect_worker);
276	queue_work(dev->iwarp_wq, &work->work);
277}
278
279static void
280qedr_iw_passive_complete(void *context,
281			 struct qed_iwarp_cm_event_params *params)
282{
283	struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context;
284	struct qedr_dev *dev = ep->dev;
285
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.
288	 */
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);
293		return;
294	}
295
296	complete(&ep->qp->iwarp_cm_comp);
297	qedr_iw_issue_event(context, params, IW_CM_EVENT_ESTABLISHED);
298
299	if (params->status < 0)
300		qedr_iw_close_event(context, params);
301}
302
303static void
304qedr_iw_active_complete(void *context,
305			struct qed_iwarp_cm_event_params *params)
306{
307	struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context;
308
309	complete(&ep->qp->iwarp_cm_comp);
310	qedr_iw_issue_event(context, params, IW_CM_EVENT_CONNECT_REPLY);
311
312	if (params->status < 0)
313		kref_put(&ep->refcnt, qedr_iw_free_ep);
314}
315
316static int
317qedr_iw_mpa_reply(void *context, struct qed_iwarp_cm_event_params *params)
318{
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;
322
323	rtr_in.ep_context = params->ep_context;
324
325	return dev->ops->iwarp_send_rtr(dev->rdma_ctx, &rtr_in);
326}
327
328static int
329qedr_iw_event_handler(void *context, struct qed_iwarp_cm_event_params *params)
330{
331	struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context;
332	struct qedr_dev *dev = ep->dev;
333
334	switch (params->event) {
335	case QED_IWARP_EVENT_MPA_REQUEST:
336		qedr_iw_mpa_request(context, params);
337		break;
338	case QED_IWARP_EVENT_ACTIVE_MPA_REPLY:
339		qedr_iw_mpa_reply(context, params);
340		break;
341	case QED_IWARP_EVENT_PASSIVE_COMPLETE:
342		qedr_iw_passive_complete(context, params);
343		break;
344	case QED_IWARP_EVENT_ACTIVE_COMPLETE:
345		qedr_iw_active_complete(context, params);
346		break;
347	case QED_IWARP_EVENT_DISCONNECT:
348		qedr_iw_disconnect_event(context, params);
349		break;
350	case QED_IWARP_EVENT_CLOSE:
351		qedr_iw_close_event(context, params);
352		break;
353	case QED_IWARP_EVENT_RQ_EMPTY:
354		qedr_iw_qp_event(context, params, IB_EVENT_QP_FATAL,
355				 "QED_IWARP_EVENT_RQ_EMPTY");
356		break;
357	case QED_IWARP_EVENT_IRQ_FULL:
358		qedr_iw_qp_event(context, params, IB_EVENT_QP_FATAL,
359				 "QED_IWARP_EVENT_IRQ_FULL");
360		break;
361	case QED_IWARP_EVENT_LLP_TIMEOUT:
362		qedr_iw_qp_event(context, params, IB_EVENT_QP_FATAL,
363				 "QED_IWARP_EVENT_LLP_TIMEOUT");
364		break;
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");
368		break;
369	case QED_IWARP_EVENT_CQ_OVERFLOW:
370		qedr_iw_qp_event(context, params, IB_EVENT_QP_FATAL,
371				 "QED_IWARP_EVENT_CQ_OVERFLOW");
372		break;
373	case QED_IWARP_EVENT_QP_CATASTROPHIC:
374		qedr_iw_qp_event(context, params, IB_EVENT_QP_FATAL,
375				 "QED_IWARP_EVENT_QP_CATASTROPHIC");
376		break;
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");
380		break;
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");
384		break;
385	case QED_IWARP_EVENT_TERMINATE_RECEIVED:
386		DP_NOTICE(dev, "Got terminate message\n");
387		break;
388	default:
389		DP_NOTICE(dev, "Unknown event received %d\n", params->event);
390		break;
391	}
392	return 0;
393}
394
395static u16 qedr_iw_get_vlan_ipv4(struct qedr_dev *dev, u32 *addr)
396{
397	struct net_device *ndev;
398	u16 vlan_id = 0;
399
400	ndev = ip_dev_find(&init_net, htonl(addr[0]));
401
402	if (ndev) {
403		vlan_id = rdma_vlan_dev_vlan_id(ndev);
404		dev_put(ndev);
405	}
406	if (vlan_id == 0xffff)
407		vlan_id = 0;
408	return vlan_id;
409}
410
411static u16 qedr_iw_get_vlan_ipv6(u32 *addr)
412{
413	struct net_device *ndev = NULL;
414	struct in6_addr laddr6;
415	u16 vlan_id = 0;
416	int i;
417
418	if (!IS_ENABLED(CONFIG_IPV6))
419		return vlan_id;
420
421	for (i = 0; i < 4; i++)
422		laddr6.in6_u.u6_addr32[i] = htonl(addr[i]);
423
424	rcu_read_lock();
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);
428			break;
429		}
430	}
431
432	rcu_read_unlock();
433	if (vlan_id == 0xffff)
434		vlan_id = 0;
435
436	return vlan_id;
437}
438
439static int
440qedr_addr4_resolve(struct qedr_dev *dev,
441		   struct sockaddr_in *src_in,
442		   struct sockaddr_in *dst_in, u8 *dst_mac)
443{
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;
448	int rc = 0;
449
450	rt = ip_route_output(&init_net, dst_ip, src_ip, 0, 0);
451	if (IS_ERR(rt)) {
452		DP_ERR(dev, "ip_route_output returned error\n");
453		return -EINVAL;
454	}
455
456	neigh = dst_neigh_lookup(&rt->dst, &dst_ip);
457
458	if (neigh) {
459		rcu_read_lock();
460		if (neigh->nud_state & NUD_VALID) {
461			ether_addr_copy(dst_mac, neigh->ha);
462			DP_DEBUG(dev, QEDR_MSG_QP, "mac_addr=[%pM]\n", dst_mac);
463		} else {
464			neigh_event_send(neigh, NULL);
465		}
466		rcu_read_unlock();
467		neigh_release(neigh);
468	}
469
470	ip_rt_put(rt);
471
472	return rc;
473}
474
475static int
476qedr_addr6_resolve(struct qedr_dev *dev,
477		   struct sockaddr_in6 *src_in,
478		   struct sockaddr_in6 *dst_in, u8 *dst_mac)
479{
480	struct neighbour *neigh = NULL;
481	struct dst_entry *dst;
482	struct flowi6 fl6;
483	int rc = 0;
484
485	memset(&fl6, 0, sizeof(fl6));
486	fl6.daddr = dst_in->sin6_addr;
487	fl6.saddr = src_in->sin6_addr;
488
489	dst = ip6_route_output(&init_net, NULL, &fl6);
490
491	if ((!dst) || dst->error) {
492		if (dst) {
493			DP_ERR(dev,
494			       "ip6_route_output returned dst->error = %d\n",
495			       dst->error);
496			dst_release(dst);
497		}
498		return -EINVAL;
499	}
500	neigh = dst_neigh_lookup(dst, &fl6.daddr);
501	if (neigh) {
502		rcu_read_lock();
503		if (neigh->nud_state & NUD_VALID) {
504			ether_addr_copy(dst_mac, neigh->ha);
505			DP_DEBUG(dev, QEDR_MSG_QP, "mac_addr=[%pM]\n", dst_mac);
506		} else {
507			neigh_event_send(neigh, NULL);
508		}
509		rcu_read_unlock();
510		neigh_release(neigh);
511	}
512
513	dst_release(dst);
514
515	return rc;
516}
517
518static struct qedr_qp *qedr_iw_load_qp(struct qedr_dev *dev, u32 qpn)
519{
520	struct qedr_qp *qp;
521
522	xa_lock(&dev->qps);
523	qp = xa_load(&dev->qps, qpn);
524	if (qp)
525		kref_get(&qp->refcnt);
526	xa_unlock(&dev->qps);
527
528	return qp;
529}
530
531int qedr_iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
532{
533	struct qedr_dev *dev = get_qedr_dev(cm_id->device);
534	struct qed_iwarp_connect_out out_params;
535	struct qed_iwarp_connect_in in_params;
536	struct qed_iwarp_cm_info *cm_info;
537	struct sockaddr_in6 *laddr6;
538	struct sockaddr_in6 *raddr6;
539	struct sockaddr_in *laddr;
540	struct sockaddr_in *raddr;
541	struct qedr_iw_ep *ep;
542	struct qedr_qp *qp;
543	int rc = 0;
544	int i;
545
546	laddr = (struct sockaddr_in *)&cm_id->m_local_addr;
547	raddr = (struct sockaddr_in *)&cm_id->m_remote_addr;
548	laddr6 = (struct sockaddr_in6 *)&cm_id->m_local_addr;
549	raddr6 = (struct sockaddr_in6 *)&cm_id->m_remote_addr;
550
551	DP_DEBUG(dev, QEDR_MSG_IWARP, "MAPPED %d %d\n",
552		 ntohs(((struct sockaddr_in *)&cm_id->remote_addr)->sin_port),
553		 ntohs(raddr->sin_port));
554
555	DP_DEBUG(dev, QEDR_MSG_IWARP,
556		 "Connect source address: %pISpc, remote address: %pISpc\n",
557		 &cm_id->local_addr, &cm_id->remote_addr);
558
559	if (!laddr->sin_port || !raddr->sin_port)
560		return -EINVAL;
561
562	ep = kzalloc(sizeof(*ep), GFP_KERNEL);
563	if (!ep)
564		return -ENOMEM;
565
566	ep->dev = dev;
567	kref_init(&ep->refcnt);
568
569	qp = qedr_iw_load_qp(dev, conn_param->qpn);
570	if (!qp) {
571		rc = -EINVAL;
572		goto err;
573	}
574
575	ep->qp = qp;
576	cm_id->add_ref(cm_id);
577	ep->cm_id = cm_id;
578
579	in_params.event_cb = qedr_iw_event_handler;
580	in_params.cb_context = ep;
581
582	cm_info = &in_params.cm_info;
583	memset(cm_info->local_ip, 0, sizeof(cm_info->local_ip));
584	memset(cm_info->remote_ip, 0, sizeof(cm_info->remote_ip));
585
586	if (!IS_ENABLED(CONFIG_IPV6) ||
587	    cm_id->remote_addr.ss_family == AF_INET) {
588		cm_info->ip_version = QED_TCP_IPV4;
589
590		cm_info->remote_ip[0] = ntohl(raddr->sin_addr.s_addr);
591		cm_info->local_ip[0] = ntohl(laddr->sin_addr.s_addr);
592		cm_info->remote_port = ntohs(raddr->sin_port);
593		cm_info->local_port = ntohs(laddr->sin_port);
594		cm_info->vlan = qedr_iw_get_vlan_ipv4(dev, cm_info->local_ip);
595
596		rc = qedr_addr4_resolve(dev, laddr, raddr,
597					(u8 *)in_params.remote_mac_addr);
598
599		in_params.mss = dev->iwarp_max_mtu -
600		    (sizeof(struct iphdr) + sizeof(struct tcphdr));
601
602	} else {
603		in_params.cm_info.ip_version = QED_TCP_IPV6;
604
605		for (i = 0; i < 4; i++) {
606			cm_info->remote_ip[i] =
607			    ntohl(raddr6->sin6_addr.in6_u.u6_addr32[i]);
608			cm_info->local_ip[i] =
609			    ntohl(laddr6->sin6_addr.in6_u.u6_addr32[i]);
610		}
611
612		cm_info->local_port = ntohs(laddr6->sin6_port);
613		cm_info->remote_port = ntohs(raddr6->sin6_port);
614
615		in_params.mss = dev->iwarp_max_mtu -
616		    (sizeof(struct ipv6hdr) + sizeof(struct tcphdr));
617
618		cm_info->vlan = qedr_iw_get_vlan_ipv6(cm_info->local_ip);
619
620		rc = qedr_addr6_resolve(dev, laddr6, raddr6,
621					(u8 *)in_params.remote_mac_addr);
622	}
623	if (rc)
624		goto err;
625
626	DP_DEBUG(dev, QEDR_MSG_IWARP,
627		 "ord = %d ird=%d private_data=%p private_data_len=%d rq_psn=%d\n",
628		 conn_param->ord, conn_param->ird, conn_param->private_data,
629		 conn_param->private_data_len, qp->rq_psn);
630
631	cm_info->ord = conn_param->ord;
632	cm_info->ird = conn_param->ird;
633	cm_info->private_data = conn_param->private_data;
634	cm_info->private_data_len = conn_param->private_data_len;
635	in_params.qp = qp->qed_qp;
636	memcpy(in_params.local_mac_addr, dev->ndev->dev_addr, ETH_ALEN);
637
638	if (test_and_set_bit(QEDR_IWARP_CM_WAIT_FOR_CONNECT,
639			     &qp->iwarp_cm_flags)) {
640		rc = -ENODEV;
641		goto err; /* QP already being destroyed */
642	}
643
644	rc = dev->ops->iwarp_connect(dev->rdma_ctx, &in_params, &out_params);
645	if (rc) {
646		complete(&qp->iwarp_cm_comp);
647		goto err;
648	}
649
650	return rc;
651
652err:
653	kref_put(&ep->refcnt, qedr_iw_free_ep);
654	return rc;
655}
656
657int qedr_iw_create_listen(struct iw_cm_id *cm_id, int backlog)
658{
659	struct qedr_dev *dev = get_qedr_dev(cm_id->device);
660	struct qedr_iw_listener *listener;
661	struct qed_iwarp_listen_in iparams;
662	struct qed_iwarp_listen_out oparams;
663	struct sockaddr_in *laddr;
664	struct sockaddr_in6 *laddr6;
665	int rc;
666	int i;
667
668	laddr = (struct sockaddr_in *)&cm_id->m_local_addr;
669	laddr6 = (struct sockaddr_in6 *)&cm_id->m_local_addr;
670
671	DP_DEBUG(dev, QEDR_MSG_IWARP,
672		 "Create Listener address: %pISpc\n", &cm_id->local_addr);
673
674	listener = kzalloc(sizeof(*listener), GFP_KERNEL);
675	if (!listener)
676		return -ENOMEM;
677
678	listener->dev = dev;
679	cm_id->add_ref(cm_id);
680	listener->cm_id = cm_id;
681	listener->backlog = backlog;
682
683	iparams.cb_context = listener;
684	iparams.event_cb = qedr_iw_event_handler;
685	iparams.max_backlog = backlog;
686
687	if (!IS_ENABLED(CONFIG_IPV6) ||
688	    cm_id->local_addr.ss_family == AF_INET) {
689		iparams.ip_version = QED_TCP_IPV4;
690		memset(iparams.ip_addr, 0, sizeof(iparams.ip_addr));
691
692		iparams.ip_addr[0] = ntohl(laddr->sin_addr.s_addr);
693		iparams.port = ntohs(laddr->sin_port);
694		iparams.vlan = qedr_iw_get_vlan_ipv4(dev, iparams.ip_addr);
695	} else {
696		iparams.ip_version = QED_TCP_IPV6;
697
698		for (i = 0; i < 4; i++) {
699			iparams.ip_addr[i] =
700			    ntohl(laddr6->sin6_addr.in6_u.u6_addr32[i]);
701		}
702
703		iparams.port = ntohs(laddr6->sin6_port);
704
705		iparams.vlan = qedr_iw_get_vlan_ipv6(iparams.ip_addr);
706	}
707	rc = dev->ops->iwarp_create_listen(dev->rdma_ctx, &iparams, &oparams);
708	if (rc)
709		goto err;
710
711	listener->qed_handle = oparams.handle;
712	cm_id->provider_data = listener;
713	return rc;
714
715err:
716	cm_id->rem_ref(cm_id);
717	kfree(listener);
718	return rc;
719}
720
721int qedr_iw_destroy_listen(struct iw_cm_id *cm_id)
722{
723	struct qedr_iw_listener *listener = cm_id->provider_data;
724	struct qedr_dev *dev = get_qedr_dev(cm_id->device);
725	int rc = 0;
726
727	if (listener->qed_handle)
728		rc = dev->ops->iwarp_destroy_listen(dev->rdma_ctx,
729						    listener->qed_handle);
730
731	cm_id->rem_ref(cm_id);
732	kfree(listener);
733	return rc;
734}
735
736int qedr_iw_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
737{
738	struct qedr_iw_ep *ep = (struct qedr_iw_ep *)cm_id->provider_data;
739	struct qedr_dev *dev = ep->dev;
740	struct qedr_qp *qp;
741	struct qed_iwarp_accept_in params;
742	int rc;
743
744	DP_DEBUG(dev, QEDR_MSG_IWARP, "Accept on qpid=%d\n", conn_param->qpn);
745
746	qp = qedr_iw_load_qp(dev, conn_param->qpn);
747	if (!qp) {
748		DP_ERR(dev, "Invalid QP number %d\n", conn_param->qpn);
749		return -EINVAL;
750	}
751
752	ep->qp = qp;
753	cm_id->add_ref(cm_id);
754	ep->cm_id = cm_id;
755
756	params.ep_context = ep->qed_context;
757	params.cb_context = ep;
758	params.qp = ep->qp->qed_qp;
759	params.private_data = conn_param->private_data;
760	params.private_data_len = conn_param->private_data_len;
761	params.ird = conn_param->ird;
762	params.ord = conn_param->ord;
763
764	if (test_and_set_bit(QEDR_IWARP_CM_WAIT_FOR_CONNECT,
765			     &qp->iwarp_cm_flags)) {
766		rc = -EINVAL;
767		goto err; /* QP already destroyed */
768	}
769
770	rc = dev->ops->iwarp_accept(dev->rdma_ctx, &params);
771	if (rc) {
772		complete(&qp->iwarp_cm_comp);
773		goto err;
774	}
775
776	return rc;
777
778err:
779	kref_put(&ep->refcnt, qedr_iw_free_ep);
780
781	return rc;
782}
783
784int qedr_iw_reject(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len)
785{
786	struct qedr_iw_ep *ep = (struct qedr_iw_ep *)cm_id->provider_data;
787	struct qedr_dev *dev = ep->dev;
788	struct qed_iwarp_reject_in params;
789
790	params.ep_context = ep->qed_context;
791	params.cb_context = ep;
792	params.private_data = pdata;
793	params.private_data_len = pdata_len;
794	ep->qp = NULL;
795
796	return dev->ops->iwarp_reject(dev->rdma_ctx, &params);
797}
798
799void qedr_iw_qp_add_ref(struct ib_qp *ibqp)
800{
801	struct qedr_qp *qp = get_qedr_qp(ibqp);
802
803	kref_get(&qp->refcnt);
804}
805
806void qedr_iw_qp_rem_ref(struct ib_qp *ibqp)
807{
808	struct qedr_qp *qp = get_qedr_qp(ibqp);
809
810	kref_put(&qp->refcnt, qedr_iw_free_qp);
811}
812
813struct ib_qp *qedr_iw_get_qp(struct ib_device *ibdev, int qpn)
814{
815	struct qedr_dev *dev = get_qedr_dev(ibdev);
816
817	return xa_load(&dev->qps, qpn);
818}