0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 #include <net/ip.h>
0033 #include <net/ipv6.h>
0034 #include <net/udp.h>
0035 #include <net/addrconf.h>
0036 #include <net/route.h>
0037 #include <net/ip6_route.h>
0038 #include <net/flow.h>
0039 #include "qedr.h"
0040 #include "qedr_iw_cm.h"
0041
0042 static inline void
0043 qedr_fill_sockaddr4(const struct qed_iwarp_cm_info *cm_info,
0044 struct iw_cm_event *event)
0045 {
0046 struct sockaddr_in *laddr = (struct sockaddr_in *)&event->local_addr;
0047 struct sockaddr_in *raddr = (struct sockaddr_in *)&event->remote_addr;
0048
0049 laddr->sin_family = AF_INET;
0050 raddr->sin_family = AF_INET;
0051
0052 laddr->sin_port = htons(cm_info->local_port);
0053 raddr->sin_port = htons(cm_info->remote_port);
0054
0055 laddr->sin_addr.s_addr = htonl(cm_info->local_ip[0]);
0056 raddr->sin_addr.s_addr = htonl(cm_info->remote_ip[0]);
0057 }
0058
0059 static inline void
0060 qedr_fill_sockaddr6(const struct qed_iwarp_cm_info *cm_info,
0061 struct iw_cm_event *event)
0062 {
0063 struct sockaddr_in6 *laddr6 = (struct sockaddr_in6 *)&event->local_addr;
0064 struct sockaddr_in6 *raddr6 =
0065 (struct sockaddr_in6 *)&event->remote_addr;
0066 int i;
0067
0068 laddr6->sin6_family = AF_INET6;
0069 raddr6->sin6_family = AF_INET6;
0070
0071 laddr6->sin6_port = htons(cm_info->local_port);
0072 raddr6->sin6_port = htons(cm_info->remote_port);
0073
0074 for (i = 0; i < 4; i++) {
0075 laddr6->sin6_addr.in6_u.u6_addr32[i] =
0076 htonl(cm_info->local_ip[i]);
0077 raddr6->sin6_addr.in6_u.u6_addr32[i] =
0078 htonl(cm_info->remote_ip[i]);
0079 }
0080 }
0081
0082 static void qedr_iw_free_qp(struct kref *ref)
0083 {
0084 struct qedr_qp *qp = container_of(ref, struct qedr_qp, refcnt);
0085
0086 complete(&qp->qp_rel_comp);
0087 }
0088
0089 static void
0090 qedr_iw_free_ep(struct kref *ref)
0091 {
0092 struct qedr_iw_ep *ep = container_of(ref, struct qedr_iw_ep, refcnt);
0093
0094 if (ep->qp)
0095 kref_put(&ep->qp->refcnt, qedr_iw_free_qp);
0096
0097 if (ep->cm_id)
0098 ep->cm_id->rem_ref(ep->cm_id);
0099
0100 kfree(ep);
0101 }
0102
0103 static void
0104 qedr_iw_mpa_request(void *context, struct qed_iwarp_cm_event_params *params)
0105 {
0106 struct qedr_iw_listener *listener = (struct qedr_iw_listener *)context;
0107 struct qedr_dev *dev = listener->dev;
0108 struct iw_cm_event event;
0109 struct qedr_iw_ep *ep;
0110
0111 ep = kzalloc(sizeof(*ep), GFP_ATOMIC);
0112 if (!ep)
0113 return;
0114
0115 ep->dev = dev;
0116 ep->qed_context = params->ep_context;
0117 kref_init(&ep->refcnt);
0118
0119 memset(&event, 0, sizeof(event));
0120 event.event = IW_CM_EVENT_CONNECT_REQUEST;
0121 event.status = params->status;
0122
0123 if (!IS_ENABLED(CONFIG_IPV6) ||
0124 params->cm_info->ip_version == QED_TCP_IPV4)
0125 qedr_fill_sockaddr4(params->cm_info, &event);
0126 else
0127 qedr_fill_sockaddr6(params->cm_info, &event);
0128
0129 event.provider_data = (void *)ep;
0130 event.private_data = (void *)params->cm_info->private_data;
0131 event.private_data_len = (u8)params->cm_info->private_data_len;
0132 event.ord = params->cm_info->ord;
0133 event.ird = params->cm_info->ird;
0134
0135 listener->cm_id->event_handler(listener->cm_id, &event);
0136 }
0137
0138 static void
0139 qedr_iw_issue_event(void *context,
0140 struct qed_iwarp_cm_event_params *params,
0141 enum iw_cm_event_type event_type)
0142 {
0143 struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context;
0144 struct iw_cm_event event;
0145
0146 memset(&event, 0, sizeof(event));
0147 event.status = params->status;
0148 event.event = event_type;
0149
0150 if (params->cm_info) {
0151 event.ird = params->cm_info->ird;
0152 event.ord = params->cm_info->ord;
0153
0154
0155
0156
0157
0158 if (event_type == IW_CM_EVENT_CONNECT_REPLY) {
0159 event.private_data_len =
0160 params->cm_info->private_data_len;
0161 event.private_data =
0162 (void *)params->cm_info->private_data;
0163 }
0164 }
0165
0166 if (ep->cm_id)
0167 ep->cm_id->event_handler(ep->cm_id, &event);
0168 }
0169
0170 static void
0171 qedr_iw_close_event(void *context, struct qed_iwarp_cm_event_params *params)
0172 {
0173 struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context;
0174
0175 if (ep->cm_id)
0176 qedr_iw_issue_event(context, params, IW_CM_EVENT_CLOSE);
0177
0178 kref_put(&ep->refcnt, qedr_iw_free_ep);
0179 }
0180
0181 static void
0182 qedr_iw_qp_event(void *context,
0183 struct qed_iwarp_cm_event_params *params,
0184 enum ib_event_type ib_event, char *str)
0185 {
0186 struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context;
0187 struct qedr_dev *dev = ep->dev;
0188 struct ib_qp *ibqp = &ep->qp->ibqp;
0189 struct ib_event event;
0190
0191 DP_NOTICE(dev, "QP error received: %s\n", str);
0192
0193 if (ibqp->event_handler) {
0194 event.event = ib_event;
0195 event.device = ibqp->device;
0196 event.element.qp = ibqp;
0197 ibqp->event_handler(&event, ibqp->qp_context);
0198 }
0199 }
0200
0201 struct qedr_discon_work {
0202 struct work_struct work;
0203 struct qedr_iw_ep *ep;
0204 enum qed_iwarp_event_type event;
0205 int status;
0206 };
0207
0208 static void qedr_iw_disconnect_worker(struct work_struct *work)
0209 {
0210 struct qedr_discon_work *dwork =
0211 container_of(work, struct qedr_discon_work, work);
0212 struct qed_rdma_modify_qp_in_params qp_params = { 0 };
0213 struct qedr_iw_ep *ep = dwork->ep;
0214 struct qedr_dev *dev = ep->dev;
0215 struct qedr_qp *qp = ep->qp;
0216 struct iw_cm_event event;
0217
0218
0219
0220
0221
0222 if (test_and_set_bit(QEDR_IWARP_CM_WAIT_FOR_DISCONNECT,
0223 &qp->iwarp_cm_flags))
0224 goto out;
0225
0226 memset(&event, 0, sizeof(event));
0227 event.status = dwork->status;
0228 event.event = IW_CM_EVENT_DISCONNECT;
0229
0230
0231
0232
0233 if (dwork->status)
0234 qp_params.new_state = QED_ROCE_QP_STATE_ERR;
0235 else
0236 qp_params.new_state = QED_ROCE_QP_STATE_SQD;
0237
0238
0239 if (ep->cm_id)
0240 ep->cm_id->event_handler(ep->cm_id, &event);
0241
0242 SET_FIELD(qp_params.modify_flags,
0243 QED_RDMA_MODIFY_QP_VALID_NEW_STATE, 1);
0244
0245 dev->ops->rdma_modify_qp(dev->rdma_ctx, qp->qed_qp, &qp_params);
0246
0247 complete(&ep->qp->iwarp_cm_comp);
0248 out:
0249 kfree(dwork);
0250 kref_put(&ep->refcnt, qedr_iw_free_ep);
0251 }
0252
0253 static void
0254 qedr_iw_disconnect_event(void *context,
0255 struct qed_iwarp_cm_event_params *params)
0256 {
0257 struct qedr_discon_work *work;
0258 struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context;
0259 struct qedr_dev *dev = ep->dev;
0260
0261 work = kzalloc(sizeof(*work), GFP_ATOMIC);
0262 if (!work)
0263 return;
0264
0265
0266
0267
0268
0269 kref_get(&ep->refcnt);
0270
0271 work->ep = ep;
0272 work->event = params->event;
0273 work->status = params->status;
0274
0275 INIT_WORK(&work->work, qedr_iw_disconnect_worker);
0276 queue_work(dev->iwarp_wq, &work->work);
0277 }
0278
0279 static void
0280 qedr_iw_passive_complete(void *context,
0281 struct qed_iwarp_cm_event_params *params)
0282 {
0283 struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context;
0284 struct qedr_dev *dev = ep->dev;
0285
0286
0287
0288
0289 if ((params->status == -ECONNREFUSED) && (!ep->qp)) {
0290 DP_DEBUG(dev, QEDR_MSG_IWARP,
0291 "PASSIVE connection refused releasing ep...\n");
0292 kref_put(&ep->refcnt, qedr_iw_free_ep);
0293 return;
0294 }
0295
0296 complete(&ep->qp->iwarp_cm_comp);
0297 qedr_iw_issue_event(context, params, IW_CM_EVENT_ESTABLISHED);
0298
0299 if (params->status < 0)
0300 qedr_iw_close_event(context, params);
0301 }
0302
0303 static void
0304 qedr_iw_active_complete(void *context,
0305 struct qed_iwarp_cm_event_params *params)
0306 {
0307 struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context;
0308
0309 complete(&ep->qp->iwarp_cm_comp);
0310 qedr_iw_issue_event(context, params, IW_CM_EVENT_CONNECT_REPLY);
0311
0312 if (params->status < 0)
0313 kref_put(&ep->refcnt, qedr_iw_free_ep);
0314 }
0315
0316 static int
0317 qedr_iw_mpa_reply(void *context, struct qed_iwarp_cm_event_params *params)
0318 {
0319 struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context;
0320 struct qedr_dev *dev = ep->dev;
0321 struct qed_iwarp_send_rtr_in rtr_in;
0322
0323 rtr_in.ep_context = params->ep_context;
0324
0325 return dev->ops->iwarp_send_rtr(dev->rdma_ctx, &rtr_in);
0326 }
0327
0328 static int
0329 qedr_iw_event_handler(void *context, struct qed_iwarp_cm_event_params *params)
0330 {
0331 struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context;
0332 struct qedr_dev *dev = ep->dev;
0333
0334 switch (params->event) {
0335 case QED_IWARP_EVENT_MPA_REQUEST:
0336 qedr_iw_mpa_request(context, params);
0337 break;
0338 case QED_IWARP_EVENT_ACTIVE_MPA_REPLY:
0339 qedr_iw_mpa_reply(context, params);
0340 break;
0341 case QED_IWARP_EVENT_PASSIVE_COMPLETE:
0342 qedr_iw_passive_complete(context, params);
0343 break;
0344 case QED_IWARP_EVENT_ACTIVE_COMPLETE:
0345 qedr_iw_active_complete(context, params);
0346 break;
0347 case QED_IWARP_EVENT_DISCONNECT:
0348 qedr_iw_disconnect_event(context, params);
0349 break;
0350 case QED_IWARP_EVENT_CLOSE:
0351 qedr_iw_close_event(context, params);
0352 break;
0353 case QED_IWARP_EVENT_RQ_EMPTY:
0354 qedr_iw_qp_event(context, params, IB_EVENT_QP_FATAL,
0355 "QED_IWARP_EVENT_RQ_EMPTY");
0356 break;
0357 case QED_IWARP_EVENT_IRQ_FULL:
0358 qedr_iw_qp_event(context, params, IB_EVENT_QP_FATAL,
0359 "QED_IWARP_EVENT_IRQ_FULL");
0360 break;
0361 case QED_IWARP_EVENT_LLP_TIMEOUT:
0362 qedr_iw_qp_event(context, params, IB_EVENT_QP_FATAL,
0363 "QED_IWARP_EVENT_LLP_TIMEOUT");
0364 break;
0365 case QED_IWARP_EVENT_REMOTE_PROTECTION_ERROR:
0366 qedr_iw_qp_event(context, params, IB_EVENT_QP_ACCESS_ERR,
0367 "QED_IWARP_EVENT_REMOTE_PROTECTION_ERROR");
0368 break;
0369 case QED_IWARP_EVENT_CQ_OVERFLOW:
0370 qedr_iw_qp_event(context, params, IB_EVENT_QP_FATAL,
0371 "QED_IWARP_EVENT_CQ_OVERFLOW");
0372 break;
0373 case QED_IWARP_EVENT_QP_CATASTROPHIC:
0374 qedr_iw_qp_event(context, params, IB_EVENT_QP_FATAL,
0375 "QED_IWARP_EVENT_QP_CATASTROPHIC");
0376 break;
0377 case QED_IWARP_EVENT_LOCAL_ACCESS_ERROR:
0378 qedr_iw_qp_event(context, params, IB_EVENT_QP_ACCESS_ERR,
0379 "QED_IWARP_EVENT_LOCAL_ACCESS_ERROR");
0380 break;
0381 case QED_IWARP_EVENT_REMOTE_OPERATION_ERROR:
0382 qedr_iw_qp_event(context, params, IB_EVENT_QP_FATAL,
0383 "QED_IWARP_EVENT_REMOTE_OPERATION_ERROR");
0384 break;
0385 case QED_IWARP_EVENT_TERMINATE_RECEIVED:
0386 DP_NOTICE(dev, "Got terminate message\n");
0387 break;
0388 default:
0389 DP_NOTICE(dev, "Unknown event received %d\n", params->event);
0390 break;
0391 }
0392 return 0;
0393 }
0394
0395 static u16 qedr_iw_get_vlan_ipv4(struct qedr_dev *dev, u32 *addr)
0396 {
0397 struct net_device *ndev;
0398 u16 vlan_id = 0;
0399
0400 ndev = ip_dev_find(&init_net, htonl(addr[0]));
0401
0402 if (ndev) {
0403 vlan_id = rdma_vlan_dev_vlan_id(ndev);
0404 dev_put(ndev);
0405 }
0406 if (vlan_id == 0xffff)
0407 vlan_id = 0;
0408 return vlan_id;
0409 }
0410
0411 static u16 qedr_iw_get_vlan_ipv6(u32 *addr)
0412 {
0413 struct net_device *ndev = NULL;
0414 struct in6_addr laddr6;
0415 u16 vlan_id = 0;
0416 int i;
0417
0418 if (!IS_ENABLED(CONFIG_IPV6))
0419 return vlan_id;
0420
0421 for (i = 0; i < 4; i++)
0422 laddr6.in6_u.u6_addr32[i] = htonl(addr[i]);
0423
0424 rcu_read_lock();
0425 for_each_netdev_rcu(&init_net, ndev) {
0426 if (ipv6_chk_addr(&init_net, &laddr6, ndev, 1)) {
0427 vlan_id = rdma_vlan_dev_vlan_id(ndev);
0428 break;
0429 }
0430 }
0431
0432 rcu_read_unlock();
0433 if (vlan_id == 0xffff)
0434 vlan_id = 0;
0435
0436 return vlan_id;
0437 }
0438
0439 static int
0440 qedr_addr4_resolve(struct qedr_dev *dev,
0441 struct sockaddr_in *src_in,
0442 struct sockaddr_in *dst_in, u8 *dst_mac)
0443 {
0444 __be32 src_ip = src_in->sin_addr.s_addr;
0445 __be32 dst_ip = dst_in->sin_addr.s_addr;
0446 struct neighbour *neigh = NULL;
0447 struct rtable *rt = NULL;
0448 int rc = 0;
0449
0450 rt = ip_route_output(&init_net, dst_ip, src_ip, 0, 0);
0451 if (IS_ERR(rt)) {
0452 DP_ERR(dev, "ip_route_output returned error\n");
0453 return -EINVAL;
0454 }
0455
0456 neigh = dst_neigh_lookup(&rt->dst, &dst_ip);
0457
0458 if (neigh) {
0459 rcu_read_lock();
0460 if (neigh->nud_state & NUD_VALID) {
0461 ether_addr_copy(dst_mac, neigh->ha);
0462 DP_DEBUG(dev, QEDR_MSG_QP, "mac_addr=[%pM]\n", dst_mac);
0463 } else {
0464 neigh_event_send(neigh, NULL);
0465 }
0466 rcu_read_unlock();
0467 neigh_release(neigh);
0468 }
0469
0470 ip_rt_put(rt);
0471
0472 return rc;
0473 }
0474
0475 static int
0476 qedr_addr6_resolve(struct qedr_dev *dev,
0477 struct sockaddr_in6 *src_in,
0478 struct sockaddr_in6 *dst_in, u8 *dst_mac)
0479 {
0480 struct neighbour *neigh = NULL;
0481 struct dst_entry *dst;
0482 struct flowi6 fl6;
0483 int rc = 0;
0484
0485 memset(&fl6, 0, sizeof(fl6));
0486 fl6.daddr = dst_in->sin6_addr;
0487 fl6.saddr = src_in->sin6_addr;
0488
0489 dst = ip6_route_output(&init_net, NULL, &fl6);
0490
0491 if ((!dst) || dst->error) {
0492 if (dst) {
0493 DP_ERR(dev,
0494 "ip6_route_output returned dst->error = %d\n",
0495 dst->error);
0496 dst_release(dst);
0497 }
0498 return -EINVAL;
0499 }
0500 neigh = dst_neigh_lookup(dst, &fl6.daddr);
0501 if (neigh) {
0502 rcu_read_lock();
0503 if (neigh->nud_state & NUD_VALID) {
0504 ether_addr_copy(dst_mac, neigh->ha);
0505 DP_DEBUG(dev, QEDR_MSG_QP, "mac_addr=[%pM]\n", dst_mac);
0506 } else {
0507 neigh_event_send(neigh, NULL);
0508 }
0509 rcu_read_unlock();
0510 neigh_release(neigh);
0511 }
0512
0513 dst_release(dst);
0514
0515 return rc;
0516 }
0517
0518 static struct qedr_qp *qedr_iw_load_qp(struct qedr_dev *dev, u32 qpn)
0519 {
0520 struct qedr_qp *qp;
0521
0522 xa_lock(&dev->qps);
0523 qp = xa_load(&dev->qps, qpn);
0524 if (qp)
0525 kref_get(&qp->refcnt);
0526 xa_unlock(&dev->qps);
0527
0528 return qp;
0529 }
0530
0531 int qedr_iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
0532 {
0533 struct qedr_dev *dev = get_qedr_dev(cm_id->device);
0534 struct qed_iwarp_connect_out out_params;
0535 struct qed_iwarp_connect_in in_params;
0536 struct qed_iwarp_cm_info *cm_info;
0537 struct sockaddr_in6 *laddr6;
0538 struct sockaddr_in6 *raddr6;
0539 struct sockaddr_in *laddr;
0540 struct sockaddr_in *raddr;
0541 struct qedr_iw_ep *ep;
0542 struct qedr_qp *qp;
0543 int rc = 0;
0544 int i;
0545
0546 laddr = (struct sockaddr_in *)&cm_id->m_local_addr;
0547 raddr = (struct sockaddr_in *)&cm_id->m_remote_addr;
0548 laddr6 = (struct sockaddr_in6 *)&cm_id->m_local_addr;
0549 raddr6 = (struct sockaddr_in6 *)&cm_id->m_remote_addr;
0550
0551 DP_DEBUG(dev, QEDR_MSG_IWARP, "MAPPED %d %d\n",
0552 ntohs(((struct sockaddr_in *)&cm_id->remote_addr)->sin_port),
0553 ntohs(raddr->sin_port));
0554
0555 DP_DEBUG(dev, QEDR_MSG_IWARP,
0556 "Connect source address: %pISpc, remote address: %pISpc\n",
0557 &cm_id->local_addr, &cm_id->remote_addr);
0558
0559 if (!laddr->sin_port || !raddr->sin_port)
0560 return -EINVAL;
0561
0562 ep = kzalloc(sizeof(*ep), GFP_KERNEL);
0563 if (!ep)
0564 return -ENOMEM;
0565
0566 ep->dev = dev;
0567 kref_init(&ep->refcnt);
0568
0569 qp = qedr_iw_load_qp(dev, conn_param->qpn);
0570 if (!qp) {
0571 rc = -EINVAL;
0572 goto err;
0573 }
0574
0575 ep->qp = qp;
0576 cm_id->add_ref(cm_id);
0577 ep->cm_id = cm_id;
0578
0579 in_params.event_cb = qedr_iw_event_handler;
0580 in_params.cb_context = ep;
0581
0582 cm_info = &in_params.cm_info;
0583 memset(cm_info->local_ip, 0, sizeof(cm_info->local_ip));
0584 memset(cm_info->remote_ip, 0, sizeof(cm_info->remote_ip));
0585
0586 if (!IS_ENABLED(CONFIG_IPV6) ||
0587 cm_id->remote_addr.ss_family == AF_INET) {
0588 cm_info->ip_version = QED_TCP_IPV4;
0589
0590 cm_info->remote_ip[0] = ntohl(raddr->sin_addr.s_addr);
0591 cm_info->local_ip[0] = ntohl(laddr->sin_addr.s_addr);
0592 cm_info->remote_port = ntohs(raddr->sin_port);
0593 cm_info->local_port = ntohs(laddr->sin_port);
0594 cm_info->vlan = qedr_iw_get_vlan_ipv4(dev, cm_info->local_ip);
0595
0596 rc = qedr_addr4_resolve(dev, laddr, raddr,
0597 (u8 *)in_params.remote_mac_addr);
0598
0599 in_params.mss = dev->iwarp_max_mtu -
0600 (sizeof(struct iphdr) + sizeof(struct tcphdr));
0601
0602 } else {
0603 in_params.cm_info.ip_version = QED_TCP_IPV6;
0604
0605 for (i = 0; i < 4; i++) {
0606 cm_info->remote_ip[i] =
0607 ntohl(raddr6->sin6_addr.in6_u.u6_addr32[i]);
0608 cm_info->local_ip[i] =
0609 ntohl(laddr6->sin6_addr.in6_u.u6_addr32[i]);
0610 }
0611
0612 cm_info->local_port = ntohs(laddr6->sin6_port);
0613 cm_info->remote_port = ntohs(raddr6->sin6_port);
0614
0615 in_params.mss = dev->iwarp_max_mtu -
0616 (sizeof(struct ipv6hdr) + sizeof(struct tcphdr));
0617
0618 cm_info->vlan = qedr_iw_get_vlan_ipv6(cm_info->local_ip);
0619
0620 rc = qedr_addr6_resolve(dev, laddr6, raddr6,
0621 (u8 *)in_params.remote_mac_addr);
0622 }
0623 if (rc)
0624 goto err;
0625
0626 DP_DEBUG(dev, QEDR_MSG_IWARP,
0627 "ord = %d ird=%d private_data=%p private_data_len=%d rq_psn=%d\n",
0628 conn_param->ord, conn_param->ird, conn_param->private_data,
0629 conn_param->private_data_len, qp->rq_psn);
0630
0631 cm_info->ord = conn_param->ord;
0632 cm_info->ird = conn_param->ird;
0633 cm_info->private_data = conn_param->private_data;
0634 cm_info->private_data_len = conn_param->private_data_len;
0635 in_params.qp = qp->qed_qp;
0636 memcpy(in_params.local_mac_addr, dev->ndev->dev_addr, ETH_ALEN);
0637
0638 if (test_and_set_bit(QEDR_IWARP_CM_WAIT_FOR_CONNECT,
0639 &qp->iwarp_cm_flags)) {
0640 rc = -ENODEV;
0641 goto err;
0642 }
0643
0644 rc = dev->ops->iwarp_connect(dev->rdma_ctx, &in_params, &out_params);
0645 if (rc) {
0646 complete(&qp->iwarp_cm_comp);
0647 goto err;
0648 }
0649
0650 return rc;
0651
0652 err:
0653 kref_put(&ep->refcnt, qedr_iw_free_ep);
0654 return rc;
0655 }
0656
0657 int qedr_iw_create_listen(struct iw_cm_id *cm_id, int backlog)
0658 {
0659 struct qedr_dev *dev = get_qedr_dev(cm_id->device);
0660 struct qedr_iw_listener *listener;
0661 struct qed_iwarp_listen_in iparams;
0662 struct qed_iwarp_listen_out oparams;
0663 struct sockaddr_in *laddr;
0664 struct sockaddr_in6 *laddr6;
0665 int rc;
0666 int i;
0667
0668 laddr = (struct sockaddr_in *)&cm_id->m_local_addr;
0669 laddr6 = (struct sockaddr_in6 *)&cm_id->m_local_addr;
0670
0671 DP_DEBUG(dev, QEDR_MSG_IWARP,
0672 "Create Listener address: %pISpc\n", &cm_id->local_addr);
0673
0674 listener = kzalloc(sizeof(*listener), GFP_KERNEL);
0675 if (!listener)
0676 return -ENOMEM;
0677
0678 listener->dev = dev;
0679 cm_id->add_ref(cm_id);
0680 listener->cm_id = cm_id;
0681 listener->backlog = backlog;
0682
0683 iparams.cb_context = listener;
0684 iparams.event_cb = qedr_iw_event_handler;
0685 iparams.max_backlog = backlog;
0686
0687 if (!IS_ENABLED(CONFIG_IPV6) ||
0688 cm_id->local_addr.ss_family == AF_INET) {
0689 iparams.ip_version = QED_TCP_IPV4;
0690 memset(iparams.ip_addr, 0, sizeof(iparams.ip_addr));
0691
0692 iparams.ip_addr[0] = ntohl(laddr->sin_addr.s_addr);
0693 iparams.port = ntohs(laddr->sin_port);
0694 iparams.vlan = qedr_iw_get_vlan_ipv4(dev, iparams.ip_addr);
0695 } else {
0696 iparams.ip_version = QED_TCP_IPV6;
0697
0698 for (i = 0; i < 4; i++) {
0699 iparams.ip_addr[i] =
0700 ntohl(laddr6->sin6_addr.in6_u.u6_addr32[i]);
0701 }
0702
0703 iparams.port = ntohs(laddr6->sin6_port);
0704
0705 iparams.vlan = qedr_iw_get_vlan_ipv6(iparams.ip_addr);
0706 }
0707 rc = dev->ops->iwarp_create_listen(dev->rdma_ctx, &iparams, &oparams);
0708 if (rc)
0709 goto err;
0710
0711 listener->qed_handle = oparams.handle;
0712 cm_id->provider_data = listener;
0713 return rc;
0714
0715 err:
0716 cm_id->rem_ref(cm_id);
0717 kfree(listener);
0718 return rc;
0719 }
0720
0721 int qedr_iw_destroy_listen(struct iw_cm_id *cm_id)
0722 {
0723 struct qedr_iw_listener *listener = cm_id->provider_data;
0724 struct qedr_dev *dev = get_qedr_dev(cm_id->device);
0725 int rc = 0;
0726
0727 if (listener->qed_handle)
0728 rc = dev->ops->iwarp_destroy_listen(dev->rdma_ctx,
0729 listener->qed_handle);
0730
0731 cm_id->rem_ref(cm_id);
0732 kfree(listener);
0733 return rc;
0734 }
0735
0736 int qedr_iw_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
0737 {
0738 struct qedr_iw_ep *ep = (struct qedr_iw_ep *)cm_id->provider_data;
0739 struct qedr_dev *dev = ep->dev;
0740 struct qedr_qp *qp;
0741 struct qed_iwarp_accept_in params;
0742 int rc;
0743
0744 DP_DEBUG(dev, QEDR_MSG_IWARP, "Accept on qpid=%d\n", conn_param->qpn);
0745
0746 qp = qedr_iw_load_qp(dev, conn_param->qpn);
0747 if (!qp) {
0748 DP_ERR(dev, "Invalid QP number %d\n", conn_param->qpn);
0749 return -EINVAL;
0750 }
0751
0752 ep->qp = qp;
0753 cm_id->add_ref(cm_id);
0754 ep->cm_id = cm_id;
0755
0756 params.ep_context = ep->qed_context;
0757 params.cb_context = ep;
0758 params.qp = ep->qp->qed_qp;
0759 params.private_data = conn_param->private_data;
0760 params.private_data_len = conn_param->private_data_len;
0761 params.ird = conn_param->ird;
0762 params.ord = conn_param->ord;
0763
0764 if (test_and_set_bit(QEDR_IWARP_CM_WAIT_FOR_CONNECT,
0765 &qp->iwarp_cm_flags)) {
0766 rc = -EINVAL;
0767 goto err;
0768 }
0769
0770 rc = dev->ops->iwarp_accept(dev->rdma_ctx, ¶ms);
0771 if (rc) {
0772 complete(&qp->iwarp_cm_comp);
0773 goto err;
0774 }
0775
0776 return rc;
0777
0778 err:
0779 kref_put(&ep->refcnt, qedr_iw_free_ep);
0780
0781 return rc;
0782 }
0783
0784 int qedr_iw_reject(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len)
0785 {
0786 struct qedr_iw_ep *ep = (struct qedr_iw_ep *)cm_id->provider_data;
0787 struct qedr_dev *dev = ep->dev;
0788 struct qed_iwarp_reject_in params;
0789
0790 params.ep_context = ep->qed_context;
0791 params.cb_context = ep;
0792 params.private_data = pdata;
0793 params.private_data_len = pdata_len;
0794 ep->qp = NULL;
0795
0796 return dev->ops->iwarp_reject(dev->rdma_ctx, ¶ms);
0797 }
0798
0799 void qedr_iw_qp_add_ref(struct ib_qp *ibqp)
0800 {
0801 struct qedr_qp *qp = get_qedr_qp(ibqp);
0802
0803 kref_get(&qp->refcnt);
0804 }
0805
0806 void qedr_iw_qp_rem_ref(struct ib_qp *ibqp)
0807 {
0808 struct qedr_qp *qp = get_qedr_qp(ibqp);
0809
0810 kref_put(&qp->refcnt, qedr_iw_free_qp);
0811 }
0812
0813 struct ib_qp *qedr_iw_get_qp(struct ib_device *ibdev, int qpn)
0814 {
0815 struct qedr_dev *dev = get_qedr_dev(ibdev);
0816
0817 return xa_load(&dev->qps, qpn);
0818 }