Back to home page

OSCL-LXR

 
 

    


0001 /* QLogic qedr NIC Driver
0002  * Copyright (c) 2015-2017  QLogic Corporation
0003  *
0004  * This software is available to you under a choice of one of two
0005  * licenses.  You may choose to be licensed under the terms of the GNU
0006  * General Public License (GPL) Version 2, available from the file
0007  * COPYING in the main directory of this source tree, or the
0008  * OpenIB.org BSD license below:
0009  *
0010  *     Redistribution and use in source and binary forms, with or
0011  *     without modification, are permitted provided that the following
0012  *     conditions are met:
0013  *
0014  *      - Redistributions of source code must retain the above
0015  *        copyright notice, this list of conditions and the following
0016  *        disclaimer.
0017  *
0018  *      - Redistributions in binary form must reproduce the above
0019  *        copyright notice, this list of conditions and the following
0020  *        disclaimer in the documentation and /or other materials
0021  *        provided with the distribution.
0022  *
0023  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
0024  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
0025  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
0026  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
0027  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
0028  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
0029  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
0030  * SOFTWARE.
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         /* Only connect_request and reply have valid private data
0154          * the rest of the events this may be left overs from
0155          * connection establishment. CONNECT_REQUEST is issued via
0156          * qedr_iw_mpa_request
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     /* The qp won't be released until we release the ep.
0219      * the ep's refcnt was increased before calling this
0220      * function, therefore it is safe to access qp
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     /* Success means graceful disconnect was requested. modifying
0231      * to SQD is translated to graceful disconnect. O/w reset is sent
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     /* We can't get a close event before disconnect, but since
0266      * we're scheduling a work queue we need to make sure close
0267      * won't delete the ep, so we increase the refcnt
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     /* We will only reach the following state if MPA_REJECT was called on
0287      * passive. In this case there will be no associated QP.
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; /* QP already being destroyed */
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; /* QP already destroyed */
0768     }
0769 
0770     rc = dev->ops->iwarp_accept(dev->rdma_ctx, &params);
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, &params);
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 }