qedr_iw_cm.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764
  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. static inline void
  42. qedr_fill_sockaddr4(const struct qed_iwarp_cm_info *cm_info,
  43. struct iw_cm_event *event)
  44. {
  45. struct sockaddr_in *laddr = (struct sockaddr_in *)&event->local_addr;
  46. struct sockaddr_in *raddr = (struct sockaddr_in *)&event->remote_addr;
  47. laddr->sin_family = AF_INET;
  48. raddr->sin_family = AF_INET;
  49. laddr->sin_port = htons(cm_info->local_port);
  50. raddr->sin_port = htons(cm_info->remote_port);
  51. laddr->sin_addr.s_addr = htonl(cm_info->local_ip[0]);
  52. raddr->sin_addr.s_addr = htonl(cm_info->remote_ip[0]);
  53. }
  54. static inline void
  55. qedr_fill_sockaddr6(const struct qed_iwarp_cm_info *cm_info,
  56. struct iw_cm_event *event)
  57. {
  58. struct sockaddr_in6 *laddr6 = (struct sockaddr_in6 *)&event->local_addr;
  59. struct sockaddr_in6 *raddr6 =
  60. (struct sockaddr_in6 *)&event->remote_addr;
  61. int i;
  62. laddr6->sin6_family = AF_INET6;
  63. raddr6->sin6_family = AF_INET6;
  64. laddr6->sin6_port = htons(cm_info->local_port);
  65. raddr6->sin6_port = htons(cm_info->remote_port);
  66. for (i = 0; i < 4; i++) {
  67. laddr6->sin6_addr.in6_u.u6_addr32[i] =
  68. htonl(cm_info->local_ip[i]);
  69. raddr6->sin6_addr.in6_u.u6_addr32[i] =
  70. htonl(cm_info->remote_ip[i]);
  71. }
  72. }
  73. static void
  74. qedr_iw_mpa_request(void *context, struct qed_iwarp_cm_event_params *params)
  75. {
  76. struct qedr_iw_listener *listener = (struct qedr_iw_listener *)context;
  77. struct qedr_dev *dev = listener->dev;
  78. struct iw_cm_event event;
  79. struct qedr_iw_ep *ep;
  80. ep = kzalloc(sizeof(*ep), GFP_ATOMIC);
  81. if (!ep)
  82. return;
  83. ep->dev = dev;
  84. ep->qed_context = params->ep_context;
  85. memset(&event, 0, sizeof(event));
  86. event.event = IW_CM_EVENT_CONNECT_REQUEST;
  87. event.status = params->status;
  88. if (!IS_ENABLED(CONFIG_IPV6) ||
  89. params->cm_info->ip_version == QED_TCP_IPV4)
  90. qedr_fill_sockaddr4(params->cm_info, &event);
  91. else
  92. qedr_fill_sockaddr6(params->cm_info, &event);
  93. event.provider_data = (void *)ep;
  94. event.private_data = (void *)params->cm_info->private_data;
  95. event.private_data_len = (u8)params->cm_info->private_data_len;
  96. event.ord = params->cm_info->ord;
  97. event.ird = params->cm_info->ird;
  98. listener->cm_id->event_handler(listener->cm_id, &event);
  99. }
  100. static void
  101. qedr_iw_issue_event(void *context,
  102. struct qed_iwarp_cm_event_params *params,
  103. enum iw_cm_event_type event_type)
  104. {
  105. struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context;
  106. struct iw_cm_event event;
  107. memset(&event, 0, sizeof(event));
  108. event.status = params->status;
  109. event.event = event_type;
  110. if (params->cm_info) {
  111. event.ird = params->cm_info->ird;
  112. event.ord = params->cm_info->ord;
  113. /* Only connect_request and reply have valid private data
  114. * the rest of the events this may be left overs from
  115. * connection establishment. CONNECT_REQUEST is issued via
  116. * qedr_iw_mpa_request
  117. */
  118. if (event_type == IW_CM_EVENT_CONNECT_REPLY) {
  119. event.private_data_len =
  120. params->cm_info->private_data_len;
  121. event.private_data =
  122. (void *)params->cm_info->private_data;
  123. }
  124. }
  125. if (ep->cm_id)
  126. ep->cm_id->event_handler(ep->cm_id, &event);
  127. }
  128. static void
  129. qedr_iw_close_event(void *context, struct qed_iwarp_cm_event_params *params)
  130. {
  131. struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context;
  132. if (ep->cm_id) {
  133. qedr_iw_issue_event(context, params, IW_CM_EVENT_CLOSE);
  134. ep->cm_id->rem_ref(ep->cm_id);
  135. ep->cm_id = NULL;
  136. }
  137. }
  138. static void
  139. qedr_iw_qp_event(void *context,
  140. struct qed_iwarp_cm_event_params *params,
  141. enum ib_event_type ib_event, char *str)
  142. {
  143. struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context;
  144. struct qedr_dev *dev = ep->dev;
  145. struct ib_qp *ibqp = &ep->qp->ibqp;
  146. struct ib_event event;
  147. DP_NOTICE(dev, "QP error received: %s\n", str);
  148. if (ibqp->event_handler) {
  149. event.event = ib_event;
  150. event.device = ibqp->device;
  151. event.element.qp = ibqp;
  152. ibqp->event_handler(&event, ibqp->qp_context);
  153. }
  154. }
  155. struct qedr_discon_work {
  156. struct work_struct work;
  157. struct qedr_iw_ep *ep;
  158. enum qed_iwarp_event_type event;
  159. int status;
  160. };
  161. static void qedr_iw_disconnect_worker(struct work_struct *work)
  162. {
  163. struct qedr_discon_work *dwork =
  164. container_of(work, struct qedr_discon_work, work);
  165. struct qed_rdma_modify_qp_in_params qp_params = { 0 };
  166. struct qedr_iw_ep *ep = dwork->ep;
  167. struct qedr_dev *dev = ep->dev;
  168. struct qedr_qp *qp = ep->qp;
  169. struct iw_cm_event event;
  170. if (qp->destroyed) {
  171. kfree(dwork);
  172. qedr_iw_qp_rem_ref(&qp->ibqp);
  173. return;
  174. }
  175. memset(&event, 0, sizeof(event));
  176. event.status = dwork->status;
  177. event.event = IW_CM_EVENT_DISCONNECT;
  178. /* Success means graceful disconnect was requested. modifying
  179. * to SQD is translated to graceful disconnect. O/w reset is sent
  180. */
  181. if (dwork->status)
  182. qp_params.new_state = QED_ROCE_QP_STATE_ERR;
  183. else
  184. qp_params.new_state = QED_ROCE_QP_STATE_SQD;
  185. kfree(dwork);
  186. if (ep->cm_id)
  187. ep->cm_id->event_handler(ep->cm_id, &event);
  188. SET_FIELD(qp_params.modify_flags,
  189. QED_RDMA_MODIFY_QP_VALID_NEW_STATE, 1);
  190. dev->ops->rdma_modify_qp(dev->rdma_ctx, qp->qed_qp, &qp_params);
  191. qedr_iw_qp_rem_ref(&qp->ibqp);
  192. }
  193. static void
  194. qedr_iw_disconnect_event(void *context,
  195. struct qed_iwarp_cm_event_params *params)
  196. {
  197. struct qedr_discon_work *work;
  198. struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context;
  199. struct qedr_dev *dev = ep->dev;
  200. struct qedr_qp *qp = ep->qp;
  201. work = kzalloc(sizeof(*work), GFP_ATOMIC);
  202. if (!work)
  203. return;
  204. qedr_iw_qp_add_ref(&qp->ibqp);
  205. work->ep = ep;
  206. work->event = params->event;
  207. work->status = params->status;
  208. INIT_WORK(&work->work, qedr_iw_disconnect_worker);
  209. queue_work(dev->iwarp_wq, &work->work);
  210. }
  211. static void
  212. qedr_iw_passive_complete(void *context,
  213. struct qed_iwarp_cm_event_params *params)
  214. {
  215. struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context;
  216. struct qedr_dev *dev = ep->dev;
  217. /* We will only reach the following state if MPA_REJECT was called on
  218. * passive. In this case there will be no associated QP.
  219. */
  220. if ((params->status == -ECONNREFUSED) && (!ep->qp)) {
  221. DP_DEBUG(dev, QEDR_MSG_IWARP,
  222. "PASSIVE connection refused releasing ep...\n");
  223. kfree(ep);
  224. return;
  225. }
  226. qedr_iw_issue_event(context, params, IW_CM_EVENT_ESTABLISHED);
  227. if (params->status < 0)
  228. qedr_iw_close_event(context, params);
  229. }
  230. static int
  231. qedr_iw_mpa_reply(void *context, struct qed_iwarp_cm_event_params *params)
  232. {
  233. struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context;
  234. struct qedr_dev *dev = ep->dev;
  235. struct qed_iwarp_send_rtr_in rtr_in;
  236. rtr_in.ep_context = params->ep_context;
  237. return dev->ops->iwarp_send_rtr(dev->rdma_ctx, &rtr_in);
  238. }
  239. static int
  240. qedr_iw_event_handler(void *context, struct qed_iwarp_cm_event_params *params)
  241. {
  242. struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context;
  243. struct qedr_dev *dev = ep->dev;
  244. switch (params->event) {
  245. case QED_IWARP_EVENT_MPA_REQUEST:
  246. qedr_iw_mpa_request(context, params);
  247. break;
  248. case QED_IWARP_EVENT_ACTIVE_MPA_REPLY:
  249. qedr_iw_mpa_reply(context, params);
  250. break;
  251. case QED_IWARP_EVENT_PASSIVE_COMPLETE:
  252. ep->during_connect = 0;
  253. qedr_iw_passive_complete(context, params);
  254. break;
  255. case QED_IWARP_EVENT_ACTIVE_COMPLETE:
  256. ep->during_connect = 0;
  257. qedr_iw_issue_event(context,
  258. params,
  259. IW_CM_EVENT_CONNECT_REPLY);
  260. if (params->status < 0) {
  261. struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context;
  262. ep->cm_id->rem_ref(ep->cm_id);
  263. ep->cm_id = NULL;
  264. }
  265. break;
  266. case QED_IWARP_EVENT_DISCONNECT:
  267. qedr_iw_disconnect_event(context, params);
  268. break;
  269. case QED_IWARP_EVENT_CLOSE:
  270. ep->during_connect = 0;
  271. qedr_iw_close_event(context, params);
  272. break;
  273. case QED_IWARP_EVENT_RQ_EMPTY:
  274. qedr_iw_qp_event(context, params, IB_EVENT_QP_FATAL,
  275. "QED_IWARP_EVENT_RQ_EMPTY");
  276. break;
  277. case QED_IWARP_EVENT_IRQ_FULL:
  278. qedr_iw_qp_event(context, params, IB_EVENT_QP_FATAL,
  279. "QED_IWARP_EVENT_IRQ_FULL");
  280. break;
  281. case QED_IWARP_EVENT_LLP_TIMEOUT:
  282. qedr_iw_qp_event(context, params, IB_EVENT_QP_FATAL,
  283. "QED_IWARP_EVENT_LLP_TIMEOUT");
  284. break;
  285. case QED_IWARP_EVENT_REMOTE_PROTECTION_ERROR:
  286. qedr_iw_qp_event(context, params, IB_EVENT_QP_ACCESS_ERR,
  287. "QED_IWARP_EVENT_REMOTE_PROTECTION_ERROR");
  288. break;
  289. case QED_IWARP_EVENT_CQ_OVERFLOW:
  290. qedr_iw_qp_event(context, params, IB_EVENT_QP_FATAL,
  291. "QED_IWARP_EVENT_CQ_OVERFLOW");
  292. break;
  293. case QED_IWARP_EVENT_QP_CATASTROPHIC:
  294. qedr_iw_qp_event(context, params, IB_EVENT_QP_FATAL,
  295. "QED_IWARP_EVENT_QP_CATASTROPHIC");
  296. break;
  297. case QED_IWARP_EVENT_LOCAL_ACCESS_ERROR:
  298. qedr_iw_qp_event(context, params, IB_EVENT_QP_ACCESS_ERR,
  299. "QED_IWARP_EVENT_LOCAL_ACCESS_ERROR");
  300. break;
  301. case QED_IWARP_EVENT_REMOTE_OPERATION_ERROR:
  302. qedr_iw_qp_event(context, params, IB_EVENT_QP_FATAL,
  303. "QED_IWARP_EVENT_REMOTE_OPERATION_ERROR");
  304. break;
  305. case QED_IWARP_EVENT_TERMINATE_RECEIVED:
  306. DP_NOTICE(dev, "Got terminate message\n");
  307. break;
  308. default:
  309. DP_NOTICE(dev, "Unknown event received %d\n", params->event);
  310. break;
  311. };
  312. return 0;
  313. }
  314. static u16 qedr_iw_get_vlan_ipv4(struct qedr_dev *dev, u32 *addr)
  315. {
  316. struct net_device *ndev;
  317. u16 vlan_id = 0;
  318. ndev = ip_dev_find(&init_net, htonl(addr[0]));
  319. if (ndev) {
  320. vlan_id = rdma_vlan_dev_vlan_id(ndev);
  321. dev_put(ndev);
  322. }
  323. if (vlan_id == 0xffff)
  324. vlan_id = 0;
  325. return vlan_id;
  326. }
  327. static u16 qedr_iw_get_vlan_ipv6(u32 *addr)
  328. {
  329. struct net_device *ndev = NULL;
  330. struct in6_addr laddr6;
  331. u16 vlan_id = 0;
  332. int i;
  333. if (!IS_ENABLED(CONFIG_IPV6))
  334. return vlan_id;
  335. for (i = 0; i < 4; i++)
  336. laddr6.in6_u.u6_addr32[i] = htonl(addr[i]);
  337. rcu_read_lock();
  338. for_each_netdev_rcu(&init_net, ndev) {
  339. if (ipv6_chk_addr(&init_net, &laddr6, ndev, 1)) {
  340. vlan_id = rdma_vlan_dev_vlan_id(ndev);
  341. break;
  342. }
  343. }
  344. rcu_read_unlock();
  345. if (vlan_id == 0xffff)
  346. vlan_id = 0;
  347. return vlan_id;
  348. }
  349. static int
  350. qedr_addr4_resolve(struct qedr_dev *dev,
  351. struct sockaddr_in *src_in,
  352. struct sockaddr_in *dst_in, u8 *dst_mac)
  353. {
  354. __be32 src_ip = src_in->sin_addr.s_addr;
  355. __be32 dst_ip = dst_in->sin_addr.s_addr;
  356. struct neighbour *neigh = NULL;
  357. struct rtable *rt = NULL;
  358. int rc = 0;
  359. rt = ip_route_output(&init_net, dst_ip, src_ip, 0, 0);
  360. if (IS_ERR(rt)) {
  361. DP_ERR(dev, "ip_route_output returned error\n");
  362. return -EINVAL;
  363. }
  364. neigh = dst_neigh_lookup(&rt->dst, &dst_ip);
  365. if (neigh) {
  366. rcu_read_lock();
  367. if (neigh->nud_state & NUD_VALID) {
  368. ether_addr_copy(dst_mac, neigh->ha);
  369. DP_DEBUG(dev, QEDR_MSG_QP, "mac_addr=[%pM]\n", dst_mac);
  370. } else {
  371. neigh_event_send(neigh, NULL);
  372. }
  373. rcu_read_unlock();
  374. neigh_release(neigh);
  375. }
  376. ip_rt_put(rt);
  377. return rc;
  378. }
  379. static int
  380. qedr_addr6_resolve(struct qedr_dev *dev,
  381. struct sockaddr_in6 *src_in,
  382. struct sockaddr_in6 *dst_in, u8 *dst_mac)
  383. {
  384. struct neighbour *neigh = NULL;
  385. struct dst_entry *dst;
  386. struct flowi6 fl6;
  387. int rc = 0;
  388. memset(&fl6, 0, sizeof(fl6));
  389. fl6.daddr = dst_in->sin6_addr;
  390. fl6.saddr = src_in->sin6_addr;
  391. dst = ip6_route_output(&init_net, NULL, &fl6);
  392. if ((!dst) || dst->error) {
  393. if (dst) {
  394. DP_ERR(dev,
  395. "ip6_route_output returned dst->error = %d\n",
  396. dst->error);
  397. dst_release(dst);
  398. }
  399. return -EINVAL;
  400. }
  401. neigh = dst_neigh_lookup(dst, &fl6.daddr);
  402. if (neigh) {
  403. rcu_read_lock();
  404. if (neigh->nud_state & NUD_VALID) {
  405. ether_addr_copy(dst_mac, neigh->ha);
  406. DP_DEBUG(dev, QEDR_MSG_QP, "mac_addr=[%pM]\n", dst_mac);
  407. } else {
  408. neigh_event_send(neigh, NULL);
  409. }
  410. rcu_read_unlock();
  411. neigh_release(neigh);
  412. }
  413. dst_release(dst);
  414. return rc;
  415. }
  416. int qedr_iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
  417. {
  418. struct qedr_dev *dev = get_qedr_dev(cm_id->device);
  419. struct qed_iwarp_connect_out out_params;
  420. struct qed_iwarp_connect_in in_params;
  421. struct qed_iwarp_cm_info *cm_info;
  422. struct sockaddr_in6 *laddr6;
  423. struct sockaddr_in6 *raddr6;
  424. struct sockaddr_in *laddr;
  425. struct sockaddr_in *raddr;
  426. struct qedr_iw_ep *ep;
  427. struct qedr_qp *qp;
  428. int rc = 0;
  429. int i;
  430. qp = idr_find(&dev->qpidr.idr, conn_param->qpn);
  431. if (unlikely(!qp))
  432. return -EINVAL;
  433. laddr = (struct sockaddr_in *)&cm_id->m_local_addr;
  434. raddr = (struct sockaddr_in *)&cm_id->m_remote_addr;
  435. laddr6 = (struct sockaddr_in6 *)&cm_id->m_local_addr;
  436. raddr6 = (struct sockaddr_in6 *)&cm_id->m_remote_addr;
  437. DP_DEBUG(dev, QEDR_MSG_IWARP, "MAPPED %d %d\n",
  438. ntohs(((struct sockaddr_in *)&cm_id->remote_addr)->sin_port),
  439. ntohs(raddr->sin_port));
  440. DP_DEBUG(dev, QEDR_MSG_IWARP,
  441. "Connect source address: %pISpc, remote address: %pISpc\n",
  442. &cm_id->local_addr, &cm_id->remote_addr);
  443. if (!laddr->sin_port || !raddr->sin_port)
  444. return -EINVAL;
  445. ep = kzalloc(sizeof(*ep), GFP_KERNEL);
  446. if (!ep)
  447. return -ENOMEM;
  448. ep->dev = dev;
  449. ep->qp = qp;
  450. qp->ep = ep;
  451. cm_id->add_ref(cm_id);
  452. ep->cm_id = cm_id;
  453. in_params.event_cb = qedr_iw_event_handler;
  454. in_params.cb_context = ep;
  455. cm_info = &in_params.cm_info;
  456. memset(cm_info->local_ip, 0, sizeof(cm_info->local_ip));
  457. memset(cm_info->remote_ip, 0, sizeof(cm_info->remote_ip));
  458. if (!IS_ENABLED(CONFIG_IPV6) ||
  459. cm_id->remote_addr.ss_family == AF_INET) {
  460. cm_info->ip_version = QED_TCP_IPV4;
  461. cm_info->remote_ip[0] = ntohl(raddr->sin_addr.s_addr);
  462. cm_info->local_ip[0] = ntohl(laddr->sin_addr.s_addr);
  463. cm_info->remote_port = ntohs(raddr->sin_port);
  464. cm_info->local_port = ntohs(laddr->sin_port);
  465. cm_info->vlan = qedr_iw_get_vlan_ipv4(dev, cm_info->local_ip);
  466. rc = qedr_addr4_resolve(dev, laddr, raddr,
  467. (u8 *)in_params.remote_mac_addr);
  468. in_params.mss = dev->iwarp_max_mtu -
  469. (sizeof(struct iphdr) + sizeof(struct tcphdr));
  470. } else {
  471. in_params.cm_info.ip_version = QED_TCP_IPV6;
  472. for (i = 0; i < 4; i++) {
  473. cm_info->remote_ip[i] =
  474. ntohl(raddr6->sin6_addr.in6_u.u6_addr32[i]);
  475. cm_info->local_ip[i] =
  476. ntohl(laddr6->sin6_addr.in6_u.u6_addr32[i]);
  477. }
  478. cm_info->local_port = ntohs(laddr6->sin6_port);
  479. cm_info->remote_port = ntohs(raddr6->sin6_port);
  480. in_params.mss = dev->iwarp_max_mtu -
  481. (sizeof(struct ipv6hdr) + sizeof(struct tcphdr));
  482. cm_info->vlan = qedr_iw_get_vlan_ipv6(cm_info->local_ip);
  483. rc = qedr_addr6_resolve(dev, laddr6, raddr6,
  484. (u8 *)in_params.remote_mac_addr);
  485. }
  486. if (rc)
  487. goto err;
  488. DP_DEBUG(dev, QEDR_MSG_IWARP,
  489. "ord = %d ird=%d private_data=%p private_data_len=%d rq_psn=%d\n",
  490. conn_param->ord, conn_param->ird, conn_param->private_data,
  491. conn_param->private_data_len, qp->rq_psn);
  492. cm_info->ord = conn_param->ord;
  493. cm_info->ird = conn_param->ird;
  494. cm_info->private_data = conn_param->private_data;
  495. cm_info->private_data_len = conn_param->private_data_len;
  496. in_params.qp = qp->qed_qp;
  497. memcpy(in_params.local_mac_addr, dev->ndev->dev_addr, ETH_ALEN);
  498. ep->during_connect = 1;
  499. rc = dev->ops->iwarp_connect(dev->rdma_ctx, &in_params, &out_params);
  500. if (rc)
  501. goto err;
  502. return rc;
  503. err:
  504. cm_id->rem_ref(cm_id);
  505. kfree(ep);
  506. return rc;
  507. }
  508. int qedr_iw_create_listen(struct iw_cm_id *cm_id, int backlog)
  509. {
  510. struct qedr_dev *dev = get_qedr_dev(cm_id->device);
  511. struct qedr_iw_listener *listener;
  512. struct qed_iwarp_listen_in iparams;
  513. struct qed_iwarp_listen_out oparams;
  514. struct sockaddr_in *laddr;
  515. struct sockaddr_in6 *laddr6;
  516. int rc;
  517. int i;
  518. laddr = (struct sockaddr_in *)&cm_id->m_local_addr;
  519. laddr6 = (struct sockaddr_in6 *)&cm_id->m_local_addr;
  520. DP_DEBUG(dev, QEDR_MSG_IWARP,
  521. "Create Listener address: %pISpc\n", &cm_id->local_addr);
  522. listener = kzalloc(sizeof(*listener), GFP_KERNEL);
  523. if (!listener)
  524. return -ENOMEM;
  525. listener->dev = dev;
  526. cm_id->add_ref(cm_id);
  527. listener->cm_id = cm_id;
  528. listener->backlog = backlog;
  529. iparams.cb_context = listener;
  530. iparams.event_cb = qedr_iw_event_handler;
  531. iparams.max_backlog = backlog;
  532. if (!IS_ENABLED(CONFIG_IPV6) ||
  533. cm_id->local_addr.ss_family == AF_INET) {
  534. iparams.ip_version = QED_TCP_IPV4;
  535. memset(iparams.ip_addr, 0, sizeof(iparams.ip_addr));
  536. iparams.ip_addr[0] = ntohl(laddr->sin_addr.s_addr);
  537. iparams.port = ntohs(laddr->sin_port);
  538. iparams.vlan = qedr_iw_get_vlan_ipv4(dev, iparams.ip_addr);
  539. } else {
  540. iparams.ip_version = QED_TCP_IPV6;
  541. for (i = 0; i < 4; i++) {
  542. iparams.ip_addr[i] =
  543. ntohl(laddr6->sin6_addr.in6_u.u6_addr32[i]);
  544. }
  545. iparams.port = ntohs(laddr6->sin6_port);
  546. iparams.vlan = qedr_iw_get_vlan_ipv6(iparams.ip_addr);
  547. }
  548. rc = dev->ops->iwarp_create_listen(dev->rdma_ctx, &iparams, &oparams);
  549. if (rc)
  550. goto err;
  551. listener->qed_handle = oparams.handle;
  552. cm_id->provider_data = listener;
  553. return rc;
  554. err:
  555. cm_id->rem_ref(cm_id);
  556. kfree(listener);
  557. return rc;
  558. }
  559. int qedr_iw_destroy_listen(struct iw_cm_id *cm_id)
  560. {
  561. struct qedr_iw_listener *listener = cm_id->provider_data;
  562. struct qedr_dev *dev = get_qedr_dev(cm_id->device);
  563. int rc = 0;
  564. if (listener->qed_handle)
  565. rc = dev->ops->iwarp_destroy_listen(dev->rdma_ctx,
  566. listener->qed_handle);
  567. cm_id->rem_ref(cm_id);
  568. kfree(listener);
  569. return rc;
  570. }
  571. int qedr_iw_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
  572. {
  573. struct qedr_iw_ep *ep = (struct qedr_iw_ep *)cm_id->provider_data;
  574. struct qedr_dev *dev = ep->dev;
  575. struct qedr_qp *qp;
  576. struct qed_iwarp_accept_in params;
  577. int rc;
  578. DP_DEBUG(dev, QEDR_MSG_IWARP, "Accept on qpid=%d\n", conn_param->qpn);
  579. qp = idr_find(&dev->qpidr.idr, conn_param->qpn);
  580. if (!qp) {
  581. DP_ERR(dev, "Invalid QP number %d\n", conn_param->qpn);
  582. return -EINVAL;
  583. }
  584. ep->qp = qp;
  585. qp->ep = ep;
  586. cm_id->add_ref(cm_id);
  587. ep->cm_id = cm_id;
  588. params.ep_context = ep->qed_context;
  589. params.cb_context = ep;
  590. params.qp = ep->qp->qed_qp;
  591. params.private_data = conn_param->private_data;
  592. params.private_data_len = conn_param->private_data_len;
  593. params.ird = conn_param->ird;
  594. params.ord = conn_param->ord;
  595. ep->during_connect = 1;
  596. rc = dev->ops->iwarp_accept(dev->rdma_ctx, &params);
  597. if (rc)
  598. goto err;
  599. return rc;
  600. err:
  601. ep->during_connect = 0;
  602. cm_id->rem_ref(cm_id);
  603. return rc;
  604. }
  605. int qedr_iw_reject(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len)
  606. {
  607. struct qedr_iw_ep *ep = (struct qedr_iw_ep *)cm_id->provider_data;
  608. struct qedr_dev *dev = ep->dev;
  609. struct qed_iwarp_reject_in params;
  610. params.ep_context = ep->qed_context;
  611. params.cb_context = ep;
  612. params.private_data = pdata;
  613. params.private_data_len = pdata_len;
  614. ep->qp = NULL;
  615. return dev->ops->iwarp_reject(dev->rdma_ctx, &params);
  616. }
  617. void qedr_iw_qp_add_ref(struct ib_qp *ibqp)
  618. {
  619. struct qedr_qp *qp = get_qedr_qp(ibqp);
  620. atomic_inc(&qp->refcnt);
  621. }
  622. void qedr_iw_qp_rem_ref(struct ib_qp *ibqp)
  623. {
  624. struct qedr_qp *qp = get_qedr_qp(ibqp);
  625. if (atomic_dec_and_test(&qp->refcnt)) {
  626. spin_lock_irq(&qp->dev->qpidr.idr_lock);
  627. idr_remove(&qp->dev->qpidr.idr, qp->qp_id);
  628. spin_unlock_irq(&qp->dev->qpidr.idr_lock);
  629. kfree(qp);
  630. }
  631. }
  632. struct ib_qp *qedr_iw_get_qp(struct ib_device *ibdev, int qpn)
  633. {
  634. struct qedr_dev *dev = get_qedr_dev(ibdev);
  635. return idr_find(&dev->qpidr.idr, qpn);
  636. }