Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
[cris-mirror.git] / drivers / infiniband / hw / i40iw / i40iw_cm.c
blobabf4cd8978495ef52ca6e62e52ee1205e193bb07
1 /*******************************************************************************
3 * Copyright (c) 2015-2016 Intel Corporation. All rights reserved.
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenFabrics.org BSD license below:
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
33 *******************************************************************************/
35 #include <linux/atomic.h>
36 #include <linux/ip.h>
37 #include <linux/tcp.h>
38 #include <linux/init.h>
39 #include <linux/if_arp.h>
40 #include <linux/if_vlan.h>
41 #include <linux/notifier.h>
42 #include <linux/net.h>
43 #include <linux/types.h>
44 #include <linux/timer.h>
45 #include <linux/time.h>
46 #include <linux/delay.h>
47 #include <linux/etherdevice.h>
48 #include <linux/netdevice.h>
49 #include <linux/random.h>
50 #include <linux/list.h>
51 #include <linux/threads.h>
52 #include <linux/highmem.h>
53 #include <net/arp.h>
54 #include <net/ndisc.h>
55 #include <net/neighbour.h>
56 #include <net/route.h>
57 #include <net/addrconf.h>
58 #include <net/ip6_route.h>
59 #include <net/ip_fib.h>
60 #include <net/tcp.h>
61 #include <asm/checksum.h>
63 #include "i40iw.h"
65 static void i40iw_rem_ref_cm_node(struct i40iw_cm_node *);
66 static void i40iw_cm_post_event(struct i40iw_cm_event *event);
67 static void i40iw_disconnect_worker(struct work_struct *work);
69 /**
70 * i40iw_free_sqbuf - put back puda buffer if refcount = 0
71 * @vsi: pointer to vsi structure
72 * @buf: puda buffer to free
74 void i40iw_free_sqbuf(struct i40iw_sc_vsi *vsi, void *bufp)
76 struct i40iw_puda_buf *buf = (struct i40iw_puda_buf *)bufp;
77 struct i40iw_puda_rsrc *ilq = vsi->ilq;
79 if (!atomic_dec_return(&buf->refcount))
80 i40iw_puda_ret_bufpool(ilq, buf);
83 /**
84 * i40iw_derive_hw_ird_setting - Calculate IRD
86 * @cm_ird: IRD of connection's node
88 * The ird from the connection is rounded to a supported HW
89 * setting (2,8,32,64) and then encoded for ird_size field of
90 * qp_ctx
92 static u8 i40iw_derive_hw_ird_setting(u16 cm_ird)
94 u8 encoded_ird_size;
96 /* ird_size field is encoded in qp_ctx */
97 switch (cm_ird ? roundup_pow_of_two(cm_ird) : 0) {
98 case I40IW_HW_IRD_SETTING_64:
99 encoded_ird_size = 3;
100 break;
101 case I40IW_HW_IRD_SETTING_32:
102 case I40IW_HW_IRD_SETTING_16:
103 encoded_ird_size = 2;
104 break;
105 case I40IW_HW_IRD_SETTING_8:
106 case I40IW_HW_IRD_SETTING_4:
107 encoded_ird_size = 1;
108 break;
109 case I40IW_HW_IRD_SETTING_2:
110 default:
111 encoded_ird_size = 0;
112 break;
114 return encoded_ird_size;
118 * i40iw_record_ird_ord - Record IRD/ORD passed in
119 * @cm_node: connection's node
120 * @conn_ird: connection IRD
121 * @conn_ord: connection ORD
123 static void i40iw_record_ird_ord(struct i40iw_cm_node *cm_node, u32 conn_ird,
124 u32 conn_ord)
126 if (conn_ird > I40IW_MAX_IRD_SIZE)
127 conn_ird = I40IW_MAX_IRD_SIZE;
129 if (conn_ord > I40IW_MAX_ORD_SIZE)
130 conn_ord = I40IW_MAX_ORD_SIZE;
131 else if (!conn_ord && cm_node->send_rdma0_op == SEND_RDMA_READ_ZERO)
132 conn_ord = 1;
134 cm_node->ird_size = conn_ird;
135 cm_node->ord_size = conn_ord;
139 * i40iw_copy_ip_ntohl - change network to host ip
140 * @dst: host ip
141 * @src: big endian
143 void i40iw_copy_ip_ntohl(u32 *dst, __be32 *src)
145 *dst++ = ntohl(*src++);
146 *dst++ = ntohl(*src++);
147 *dst++ = ntohl(*src++);
148 *dst = ntohl(*src);
152 * i40iw_copy_ip_htonl - change host addr to network ip
153 * @dst: host ip
154 * @src: little endian
156 static inline void i40iw_copy_ip_htonl(__be32 *dst, u32 *src)
158 *dst++ = htonl(*src++);
159 *dst++ = htonl(*src++);
160 *dst++ = htonl(*src++);
161 *dst = htonl(*src);
165 * i40iw_fill_sockaddr4 - get addr info for passive connection
166 * @cm_node: connection's node
167 * @event: upper layer's cm event
169 static inline void i40iw_fill_sockaddr4(struct i40iw_cm_node *cm_node,
170 struct iw_cm_event *event)
172 struct sockaddr_in *laddr = (struct sockaddr_in *)&event->local_addr;
173 struct sockaddr_in *raddr = (struct sockaddr_in *)&event->remote_addr;
175 laddr->sin_family = AF_INET;
176 raddr->sin_family = AF_INET;
178 laddr->sin_port = htons(cm_node->loc_port);
179 raddr->sin_port = htons(cm_node->rem_port);
181 laddr->sin_addr.s_addr = htonl(cm_node->loc_addr[0]);
182 raddr->sin_addr.s_addr = htonl(cm_node->rem_addr[0]);
186 * i40iw_fill_sockaddr6 - get ipv6 addr info for passive side
187 * @cm_node: connection's node
188 * @event: upper layer's cm event
190 static inline void i40iw_fill_sockaddr6(struct i40iw_cm_node *cm_node,
191 struct iw_cm_event *event)
193 struct sockaddr_in6 *laddr6 = (struct sockaddr_in6 *)&event->local_addr;
194 struct sockaddr_in6 *raddr6 = (struct sockaddr_in6 *)&event->remote_addr;
196 laddr6->sin6_family = AF_INET6;
197 raddr6->sin6_family = AF_INET6;
199 laddr6->sin6_port = htons(cm_node->loc_port);
200 raddr6->sin6_port = htons(cm_node->rem_port);
202 i40iw_copy_ip_htonl(laddr6->sin6_addr.in6_u.u6_addr32,
203 cm_node->loc_addr);
204 i40iw_copy_ip_htonl(raddr6->sin6_addr.in6_u.u6_addr32,
205 cm_node->rem_addr);
209 * i40iw_get_addr_info
210 * @cm_node: contains ip/tcp info
211 * @cm_info: to get a copy of the cm_node ip/tcp info
213 static void i40iw_get_addr_info(struct i40iw_cm_node *cm_node,
214 struct i40iw_cm_info *cm_info)
216 cm_info->ipv4 = cm_node->ipv4;
217 cm_info->vlan_id = cm_node->vlan_id;
218 memcpy(cm_info->loc_addr, cm_node->loc_addr, sizeof(cm_info->loc_addr));
219 memcpy(cm_info->rem_addr, cm_node->rem_addr, sizeof(cm_info->rem_addr));
220 cm_info->loc_port = cm_node->loc_port;
221 cm_info->rem_port = cm_node->rem_port;
222 cm_info->user_pri = cm_node->user_pri;
226 * i40iw_get_cmevent_info - for cm event upcall
227 * @cm_node: connection's node
228 * @cm_id: upper layers cm struct for the event
229 * @event: upper layer's cm event
231 static inline void i40iw_get_cmevent_info(struct i40iw_cm_node *cm_node,
232 struct iw_cm_id *cm_id,
233 struct iw_cm_event *event)
235 memcpy(&event->local_addr, &cm_id->m_local_addr,
236 sizeof(event->local_addr));
237 memcpy(&event->remote_addr, &cm_id->m_remote_addr,
238 sizeof(event->remote_addr));
239 if (cm_node) {
240 event->private_data = (void *)cm_node->pdata_buf;
241 event->private_data_len = (u8)cm_node->pdata.size;
242 event->ird = cm_node->ird_size;
243 event->ord = cm_node->ord_size;
248 * i40iw_send_cm_event - upcall cm's event handler
249 * @cm_node: connection's node
250 * @cm_id: upper layer's cm info struct
251 * @type: Event type to indicate
252 * @status: status for the event type
254 static int i40iw_send_cm_event(struct i40iw_cm_node *cm_node,
255 struct iw_cm_id *cm_id,
256 enum iw_cm_event_type type,
257 int status)
259 struct iw_cm_event event;
261 memset(&event, 0, sizeof(event));
262 event.event = type;
263 event.status = status;
264 switch (type) {
265 case IW_CM_EVENT_CONNECT_REQUEST:
266 if (cm_node->ipv4)
267 i40iw_fill_sockaddr4(cm_node, &event);
268 else
269 i40iw_fill_sockaddr6(cm_node, &event);
270 event.provider_data = (void *)cm_node;
271 event.private_data = (void *)cm_node->pdata_buf;
272 event.private_data_len = (u8)cm_node->pdata.size;
273 event.ird = cm_node->ird_size;
274 break;
275 case IW_CM_EVENT_CONNECT_REPLY:
276 i40iw_get_cmevent_info(cm_node, cm_id, &event);
277 break;
278 case IW_CM_EVENT_ESTABLISHED:
279 event.ird = cm_node->ird_size;
280 event.ord = cm_node->ord_size;
281 break;
282 case IW_CM_EVENT_DISCONNECT:
283 break;
284 case IW_CM_EVENT_CLOSE:
285 break;
286 default:
287 i40iw_pr_err("event type received type = %d\n", type);
288 return -1;
290 return cm_id->event_handler(cm_id, &event);
294 * i40iw_create_event - create cm event
295 * @cm_node: connection's node
296 * @type: Event type to generate
298 static struct i40iw_cm_event *i40iw_create_event(struct i40iw_cm_node *cm_node,
299 enum i40iw_cm_event_type type)
301 struct i40iw_cm_event *event;
303 if (!cm_node->cm_id)
304 return NULL;
306 event = kzalloc(sizeof(*event), GFP_ATOMIC);
308 if (!event)
309 return NULL;
311 event->type = type;
312 event->cm_node = cm_node;
313 memcpy(event->cm_info.rem_addr, cm_node->rem_addr, sizeof(event->cm_info.rem_addr));
314 memcpy(event->cm_info.loc_addr, cm_node->loc_addr, sizeof(event->cm_info.loc_addr));
315 event->cm_info.rem_port = cm_node->rem_port;
316 event->cm_info.loc_port = cm_node->loc_port;
317 event->cm_info.cm_id = cm_node->cm_id;
319 i40iw_debug(cm_node->dev,
320 I40IW_DEBUG_CM,
321 "node=%p event=%p type=%u dst=%pI4 src=%pI4\n",
322 cm_node,
323 event,
324 type,
325 event->cm_info.loc_addr,
326 event->cm_info.rem_addr);
328 i40iw_cm_post_event(event);
329 return event;
333 * i40iw_free_retrans_entry - free send entry
334 * @cm_node: connection's node
336 static void i40iw_free_retrans_entry(struct i40iw_cm_node *cm_node)
338 struct i40iw_device *iwdev = cm_node->iwdev;
339 struct i40iw_timer_entry *send_entry;
341 send_entry = cm_node->send_entry;
342 if (send_entry) {
343 cm_node->send_entry = NULL;
344 i40iw_free_sqbuf(&iwdev->vsi, (void *)send_entry->sqbuf);
345 kfree(send_entry);
346 atomic_dec(&cm_node->ref_count);
351 * i40iw_cleanup_retrans_entry - free send entry with lock
352 * @cm_node: connection's node
354 static void i40iw_cleanup_retrans_entry(struct i40iw_cm_node *cm_node)
356 unsigned long flags;
358 spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
359 i40iw_free_retrans_entry(cm_node);
360 spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags);
364 * i40iw_form_cm_frame - get a free packet and build frame
365 * @cm_node: connection's node ionfo to use in frame
366 * @options: pointer to options info
367 * @hdr: pointer mpa header
368 * @pdata: pointer to private data
369 * @flags: indicates FIN or ACK
371 static struct i40iw_puda_buf *i40iw_form_cm_frame(struct i40iw_cm_node *cm_node,
372 struct i40iw_kmem_info *options,
373 struct i40iw_kmem_info *hdr,
374 struct i40iw_kmem_info *pdata,
375 u8 flags)
377 struct i40iw_puda_buf *sqbuf;
378 struct i40iw_sc_vsi *vsi = &cm_node->iwdev->vsi;
379 u8 *buf;
381 struct tcphdr *tcph;
382 struct iphdr *iph;
383 struct ipv6hdr *ip6h;
384 struct ethhdr *ethh;
385 u16 packetsize;
386 u16 eth_hlen = ETH_HLEN;
387 u32 opts_len = 0;
388 u32 pd_len = 0;
389 u32 hdr_len = 0;
390 u16 vtag;
392 sqbuf = i40iw_puda_get_bufpool(vsi->ilq);
393 if (!sqbuf)
394 return NULL;
395 buf = sqbuf->mem.va;
397 if (options)
398 opts_len = (u32)options->size;
400 if (hdr)
401 hdr_len = hdr->size;
403 if (pdata)
404 pd_len = pdata->size;
406 if (cm_node->vlan_id < VLAN_TAG_PRESENT)
407 eth_hlen += 4;
409 if (cm_node->ipv4)
410 packetsize = sizeof(*iph) + sizeof(*tcph);
411 else
412 packetsize = sizeof(*ip6h) + sizeof(*tcph);
413 packetsize += opts_len + hdr_len + pd_len;
415 memset(buf, 0x00, eth_hlen + packetsize);
417 sqbuf->totallen = packetsize + eth_hlen;
418 sqbuf->maclen = eth_hlen;
419 sqbuf->tcphlen = sizeof(*tcph) + opts_len;
420 sqbuf->scratch = (void *)cm_node;
422 ethh = (struct ethhdr *)buf;
423 buf += eth_hlen;
425 if (cm_node->ipv4) {
426 sqbuf->ipv4 = true;
428 iph = (struct iphdr *)buf;
429 buf += sizeof(*iph);
430 tcph = (struct tcphdr *)buf;
431 buf += sizeof(*tcph);
433 ether_addr_copy(ethh->h_dest, cm_node->rem_mac);
434 ether_addr_copy(ethh->h_source, cm_node->loc_mac);
435 if (cm_node->vlan_id < VLAN_TAG_PRESENT) {
436 ((struct vlan_ethhdr *)ethh)->h_vlan_proto = htons(ETH_P_8021Q);
437 vtag = (cm_node->user_pri << VLAN_PRIO_SHIFT) | cm_node->vlan_id;
438 ((struct vlan_ethhdr *)ethh)->h_vlan_TCI = htons(vtag);
440 ((struct vlan_ethhdr *)ethh)->h_vlan_encapsulated_proto = htons(ETH_P_IP);
441 } else {
442 ethh->h_proto = htons(ETH_P_IP);
445 iph->version = IPVERSION;
446 iph->ihl = 5; /* 5 * 4Byte words, IP headr len */
447 iph->tos = cm_node->tos;
448 iph->tot_len = htons(packetsize);
449 iph->id = htons(++cm_node->tcp_cntxt.loc_id);
451 iph->frag_off = htons(0x4000);
452 iph->ttl = 0x40;
453 iph->protocol = IPPROTO_TCP;
454 iph->saddr = htonl(cm_node->loc_addr[0]);
455 iph->daddr = htonl(cm_node->rem_addr[0]);
456 } else {
457 sqbuf->ipv4 = false;
458 ip6h = (struct ipv6hdr *)buf;
459 buf += sizeof(*ip6h);
460 tcph = (struct tcphdr *)buf;
461 buf += sizeof(*tcph);
463 ether_addr_copy(ethh->h_dest, cm_node->rem_mac);
464 ether_addr_copy(ethh->h_source, cm_node->loc_mac);
465 if (cm_node->vlan_id < VLAN_TAG_PRESENT) {
466 ((struct vlan_ethhdr *)ethh)->h_vlan_proto = htons(ETH_P_8021Q);
467 vtag = (cm_node->user_pri << VLAN_PRIO_SHIFT) | cm_node->vlan_id;
468 ((struct vlan_ethhdr *)ethh)->h_vlan_TCI = htons(vtag);
469 ((struct vlan_ethhdr *)ethh)->h_vlan_encapsulated_proto = htons(ETH_P_IPV6);
470 } else {
471 ethh->h_proto = htons(ETH_P_IPV6);
473 ip6h->version = 6;
474 ip6h->priority = cm_node->tos >> 4;
475 ip6h->flow_lbl[0] = cm_node->tos << 4;
476 ip6h->flow_lbl[1] = 0;
477 ip6h->flow_lbl[2] = 0;
478 ip6h->payload_len = htons(packetsize - sizeof(*ip6h));
479 ip6h->nexthdr = 6;
480 ip6h->hop_limit = 128;
481 i40iw_copy_ip_htonl(ip6h->saddr.in6_u.u6_addr32,
482 cm_node->loc_addr);
483 i40iw_copy_ip_htonl(ip6h->daddr.in6_u.u6_addr32,
484 cm_node->rem_addr);
487 tcph->source = htons(cm_node->loc_port);
488 tcph->dest = htons(cm_node->rem_port);
490 tcph->seq = htonl(cm_node->tcp_cntxt.loc_seq_num);
492 if (flags & SET_ACK) {
493 cm_node->tcp_cntxt.loc_ack_num = cm_node->tcp_cntxt.rcv_nxt;
494 tcph->ack_seq = htonl(cm_node->tcp_cntxt.loc_ack_num);
495 tcph->ack = 1;
496 } else {
497 tcph->ack_seq = 0;
500 if (flags & SET_SYN) {
501 cm_node->tcp_cntxt.loc_seq_num++;
502 tcph->syn = 1;
503 } else {
504 cm_node->tcp_cntxt.loc_seq_num += hdr_len + pd_len;
507 if (flags & SET_FIN) {
508 cm_node->tcp_cntxt.loc_seq_num++;
509 tcph->fin = 1;
512 if (flags & SET_RST)
513 tcph->rst = 1;
515 tcph->doff = (u16)((sizeof(*tcph) + opts_len + 3) >> 2);
516 sqbuf->tcphlen = tcph->doff << 2;
517 tcph->window = htons(cm_node->tcp_cntxt.rcv_wnd);
518 tcph->urg_ptr = 0;
520 if (opts_len) {
521 memcpy(buf, options->addr, opts_len);
522 buf += opts_len;
525 if (hdr_len) {
526 memcpy(buf, hdr->addr, hdr_len);
527 buf += hdr_len;
530 if (pdata && pdata->addr)
531 memcpy(buf, pdata->addr, pdata->size);
533 atomic_set(&sqbuf->refcount, 1);
535 return sqbuf;
539 * i40iw_send_reset - Send RST packet
540 * @cm_node: connection's node
542 static int i40iw_send_reset(struct i40iw_cm_node *cm_node)
544 struct i40iw_puda_buf *sqbuf;
545 int flags = SET_RST | SET_ACK;
547 sqbuf = i40iw_form_cm_frame(cm_node, NULL, NULL, NULL, flags);
548 if (!sqbuf) {
549 i40iw_pr_err("no sqbuf\n");
550 return -1;
553 return i40iw_schedule_cm_timer(cm_node, sqbuf, I40IW_TIMER_TYPE_SEND, 0, 1);
557 * i40iw_active_open_err - send event for active side cm error
558 * @cm_node: connection's node
559 * @reset: Flag to send reset or not
561 static void i40iw_active_open_err(struct i40iw_cm_node *cm_node, bool reset)
563 i40iw_cleanup_retrans_entry(cm_node);
564 cm_node->cm_core->stats_connect_errs++;
565 if (reset) {
566 i40iw_debug(cm_node->dev,
567 I40IW_DEBUG_CM,
568 "%s cm_node=%p state=%d\n",
569 __func__,
570 cm_node,
571 cm_node->state);
572 atomic_inc(&cm_node->ref_count);
573 i40iw_send_reset(cm_node);
576 cm_node->state = I40IW_CM_STATE_CLOSED;
577 i40iw_create_event(cm_node, I40IW_CM_EVENT_ABORTED);
581 * i40iw_passive_open_err - handle passive side cm error
582 * @cm_node: connection's node
583 * @reset: send reset or just free cm_node
585 static void i40iw_passive_open_err(struct i40iw_cm_node *cm_node, bool reset)
587 i40iw_cleanup_retrans_entry(cm_node);
588 cm_node->cm_core->stats_passive_errs++;
589 cm_node->state = I40IW_CM_STATE_CLOSED;
590 i40iw_debug(cm_node->dev,
591 I40IW_DEBUG_CM,
592 "%s cm_node=%p state =%d\n",
593 __func__,
594 cm_node,
595 cm_node->state);
596 if (reset)
597 i40iw_send_reset(cm_node);
598 else
599 i40iw_rem_ref_cm_node(cm_node);
603 * i40iw_event_connect_error - to create connect error event
604 * @event: cm information for connect event
606 static void i40iw_event_connect_error(struct i40iw_cm_event *event)
608 struct i40iw_qp *iwqp;
609 struct iw_cm_id *cm_id;
611 cm_id = event->cm_node->cm_id;
612 if (!cm_id)
613 return;
615 iwqp = cm_id->provider_data;
617 if (!iwqp || !iwqp->iwdev)
618 return;
620 iwqp->cm_id = NULL;
621 cm_id->provider_data = NULL;
622 i40iw_send_cm_event(event->cm_node, cm_id,
623 IW_CM_EVENT_CONNECT_REPLY,
624 -ECONNRESET);
625 cm_id->rem_ref(cm_id);
626 i40iw_rem_ref_cm_node(event->cm_node);
630 * i40iw_process_options
631 * @cm_node: connection's node
632 * @optionsloc: point to start of options
633 * @optionsize: size of all options
634 * @syn_packet: flag if syn packet
636 static int i40iw_process_options(struct i40iw_cm_node *cm_node,
637 u8 *optionsloc,
638 u32 optionsize,
639 u32 syn_packet)
641 u32 tmp;
642 u32 offset = 0;
643 union all_known_options *all_options;
644 char got_mss_option = 0;
646 while (offset < optionsize) {
647 all_options = (union all_known_options *)(optionsloc + offset);
648 switch (all_options->as_base.optionnum) {
649 case OPTION_NUMBER_END:
650 offset = optionsize;
651 break;
652 case OPTION_NUMBER_NONE:
653 offset += 1;
654 continue;
655 case OPTION_NUMBER_MSS:
656 i40iw_debug(cm_node->dev,
657 I40IW_DEBUG_CM,
658 "%s: MSS Length: %d Offset: %d Size: %d\n",
659 __func__,
660 all_options->as_mss.length,
661 offset,
662 optionsize);
663 got_mss_option = 1;
664 if (all_options->as_mss.length != 4)
665 return -1;
666 tmp = ntohs(all_options->as_mss.mss);
667 if (tmp > 0 && tmp < cm_node->tcp_cntxt.mss)
668 cm_node->tcp_cntxt.mss = tmp;
669 break;
670 case OPTION_NUMBER_WINDOW_SCALE:
671 cm_node->tcp_cntxt.snd_wscale =
672 all_options->as_windowscale.shiftcount;
673 break;
674 default:
675 i40iw_debug(cm_node->dev,
676 I40IW_DEBUG_CM,
677 "TCP Option not understood: %x\n",
678 all_options->as_base.optionnum);
679 break;
681 offset += all_options->as_base.length;
683 if (!got_mss_option && syn_packet)
684 cm_node->tcp_cntxt.mss = I40IW_CM_DEFAULT_MSS;
685 return 0;
689 * i40iw_handle_tcp_options -
690 * @cm_node: connection's node
691 * @tcph: pointer tcp header
692 * @optionsize: size of options rcvd
693 * @passive: active or passive flag
695 static int i40iw_handle_tcp_options(struct i40iw_cm_node *cm_node,
696 struct tcphdr *tcph,
697 int optionsize,
698 int passive)
700 u8 *optionsloc = (u8 *)&tcph[1];
702 if (optionsize) {
703 if (i40iw_process_options(cm_node,
704 optionsloc,
705 optionsize,
706 (u32)tcph->syn)) {
707 i40iw_debug(cm_node->dev,
708 I40IW_DEBUG_CM,
709 "%s: Node %p, Sending RESET\n",
710 __func__,
711 cm_node);
712 if (passive)
713 i40iw_passive_open_err(cm_node, true);
714 else
715 i40iw_active_open_err(cm_node, true);
716 return -1;
720 cm_node->tcp_cntxt.snd_wnd = ntohs(tcph->window) <<
721 cm_node->tcp_cntxt.snd_wscale;
723 if (cm_node->tcp_cntxt.snd_wnd > cm_node->tcp_cntxt.max_snd_wnd)
724 cm_node->tcp_cntxt.max_snd_wnd = cm_node->tcp_cntxt.snd_wnd;
725 return 0;
729 * i40iw_build_mpa_v1 - build a MPA V1 frame
730 * @cm_node: connection's node
731 * @mpa_key: to do read0 or write0
733 static void i40iw_build_mpa_v1(struct i40iw_cm_node *cm_node,
734 void *start_addr,
735 u8 mpa_key)
737 struct ietf_mpa_v1 *mpa_frame = (struct ietf_mpa_v1 *)start_addr;
739 switch (mpa_key) {
740 case MPA_KEY_REQUEST:
741 memcpy(mpa_frame->key, IEFT_MPA_KEY_REQ, IETF_MPA_KEY_SIZE);
742 break;
743 case MPA_KEY_REPLY:
744 memcpy(mpa_frame->key, IEFT_MPA_KEY_REP, IETF_MPA_KEY_SIZE);
745 break;
746 default:
747 break;
749 mpa_frame->flags = IETF_MPA_FLAGS_CRC;
750 mpa_frame->rev = cm_node->mpa_frame_rev;
751 mpa_frame->priv_data_len = htons(cm_node->pdata.size);
755 * i40iw_build_mpa_v2 - build a MPA V2 frame
756 * @cm_node: connection's node
757 * @start_addr: buffer start address
758 * @mpa_key: to do read0 or write0
760 static void i40iw_build_mpa_v2(struct i40iw_cm_node *cm_node,
761 void *start_addr,
762 u8 mpa_key)
764 struct ietf_mpa_v2 *mpa_frame = (struct ietf_mpa_v2 *)start_addr;
765 struct ietf_rtr_msg *rtr_msg = &mpa_frame->rtr_msg;
766 u16 ctrl_ird, ctrl_ord;
768 /* initialize the upper 5 bytes of the frame */
769 i40iw_build_mpa_v1(cm_node, start_addr, mpa_key);
770 mpa_frame->flags |= IETF_MPA_V2_FLAG;
771 mpa_frame->priv_data_len += htons(IETF_RTR_MSG_SIZE);
773 /* initialize RTR msg */
774 if (cm_node->mpav2_ird_ord == IETF_NO_IRD_ORD) {
775 ctrl_ird = IETF_NO_IRD_ORD;
776 ctrl_ord = IETF_NO_IRD_ORD;
777 } else {
778 ctrl_ird = (cm_node->ird_size > IETF_NO_IRD_ORD) ?
779 IETF_NO_IRD_ORD : cm_node->ird_size;
780 ctrl_ord = (cm_node->ord_size > IETF_NO_IRD_ORD) ?
781 IETF_NO_IRD_ORD : cm_node->ord_size;
784 ctrl_ird |= IETF_PEER_TO_PEER;
786 switch (mpa_key) {
787 case MPA_KEY_REQUEST:
788 ctrl_ord |= IETF_RDMA0_WRITE;
789 ctrl_ord |= IETF_RDMA0_READ;
790 break;
791 case MPA_KEY_REPLY:
792 switch (cm_node->send_rdma0_op) {
793 case SEND_RDMA_WRITE_ZERO:
794 ctrl_ord |= IETF_RDMA0_WRITE;
795 break;
796 case SEND_RDMA_READ_ZERO:
797 ctrl_ord |= IETF_RDMA0_READ;
798 break;
800 break;
801 default:
802 break;
804 rtr_msg->ctrl_ird = htons(ctrl_ird);
805 rtr_msg->ctrl_ord = htons(ctrl_ord);
809 * i40iw_cm_build_mpa_frame - build mpa frame for mpa version 1 or version 2
810 * @cm_node: connection's node
811 * @mpa: mpa: data buffer
812 * @mpa_key: to do read0 or write0
814 static int i40iw_cm_build_mpa_frame(struct i40iw_cm_node *cm_node,
815 struct i40iw_kmem_info *mpa,
816 u8 mpa_key)
818 int hdr_len = 0;
820 switch (cm_node->mpa_frame_rev) {
821 case IETF_MPA_V1:
822 hdr_len = sizeof(struct ietf_mpa_v1);
823 i40iw_build_mpa_v1(cm_node, mpa->addr, mpa_key);
824 break;
825 case IETF_MPA_V2:
826 hdr_len = sizeof(struct ietf_mpa_v2);
827 i40iw_build_mpa_v2(cm_node, mpa->addr, mpa_key);
828 break;
829 default:
830 break;
833 return hdr_len;
837 * i40iw_send_mpa_request - active node send mpa request to passive node
838 * @cm_node: connection's node
840 static int i40iw_send_mpa_request(struct i40iw_cm_node *cm_node)
842 struct i40iw_puda_buf *sqbuf;
844 if (!cm_node) {
845 i40iw_pr_err("cm_node == NULL\n");
846 return -1;
849 cm_node->mpa_hdr.addr = &cm_node->mpa_frame;
850 cm_node->mpa_hdr.size = i40iw_cm_build_mpa_frame(cm_node,
851 &cm_node->mpa_hdr,
852 MPA_KEY_REQUEST);
853 if (!cm_node->mpa_hdr.size) {
854 i40iw_pr_err("mpa size = %d\n", cm_node->mpa_hdr.size);
855 return -1;
858 sqbuf = i40iw_form_cm_frame(cm_node,
859 NULL,
860 &cm_node->mpa_hdr,
861 &cm_node->pdata,
862 SET_ACK);
863 if (!sqbuf) {
864 i40iw_pr_err("sq_buf == NULL\n");
865 return -1;
867 return i40iw_schedule_cm_timer(cm_node, sqbuf, I40IW_TIMER_TYPE_SEND, 1, 0);
871 * i40iw_send_mpa_reject -
872 * @cm_node: connection's node
873 * @pdata: reject data for connection
874 * @plen: length of reject data
876 static int i40iw_send_mpa_reject(struct i40iw_cm_node *cm_node,
877 const void *pdata,
878 u8 plen)
880 struct i40iw_puda_buf *sqbuf;
881 struct i40iw_kmem_info priv_info;
883 cm_node->mpa_hdr.addr = &cm_node->mpa_frame;
884 cm_node->mpa_hdr.size = i40iw_cm_build_mpa_frame(cm_node,
885 &cm_node->mpa_hdr,
886 MPA_KEY_REPLY);
888 cm_node->mpa_frame.flags |= IETF_MPA_FLAGS_REJECT;
889 priv_info.addr = (void *)pdata;
890 priv_info.size = plen;
892 sqbuf = i40iw_form_cm_frame(cm_node,
893 NULL,
894 &cm_node->mpa_hdr,
895 &priv_info,
896 SET_ACK | SET_FIN);
897 if (!sqbuf) {
898 i40iw_pr_err("no sqbuf\n");
899 return -ENOMEM;
901 cm_node->state = I40IW_CM_STATE_FIN_WAIT1;
902 return i40iw_schedule_cm_timer(cm_node, sqbuf, I40IW_TIMER_TYPE_SEND, 1, 0);
906 * recv_mpa - process an IETF MPA frame
907 * @cm_node: connection's node
908 * @buffer: Data pointer
909 * @type: to return accept or reject
910 * @len: Len of mpa buffer
912 static int i40iw_parse_mpa(struct i40iw_cm_node *cm_node, u8 *buffer, u32 *type, u32 len)
914 struct ietf_mpa_v1 *mpa_frame;
915 struct ietf_mpa_v2 *mpa_v2_frame;
916 struct ietf_rtr_msg *rtr_msg;
917 int mpa_hdr_len;
918 int priv_data_len;
920 *type = I40IW_MPA_REQUEST_ACCEPT;
922 if (len < sizeof(struct ietf_mpa_v1)) {
923 i40iw_pr_err("ietf buffer small (%x)\n", len);
924 return -1;
927 mpa_frame = (struct ietf_mpa_v1 *)buffer;
928 mpa_hdr_len = sizeof(struct ietf_mpa_v1);
929 priv_data_len = ntohs(mpa_frame->priv_data_len);
931 if (priv_data_len > IETF_MAX_PRIV_DATA_LEN) {
932 i40iw_pr_err("large pri_data %d\n", priv_data_len);
933 return -1;
935 if (mpa_frame->rev != IETF_MPA_V1 && mpa_frame->rev != IETF_MPA_V2) {
936 i40iw_pr_err("unsupported mpa rev = %d\n", mpa_frame->rev);
937 return -1;
939 if (mpa_frame->rev > cm_node->mpa_frame_rev) {
940 i40iw_pr_err("rev %d\n", mpa_frame->rev);
941 return -1;
943 cm_node->mpa_frame_rev = mpa_frame->rev;
945 if (cm_node->state != I40IW_CM_STATE_MPAREQ_SENT) {
946 if (memcmp(mpa_frame->key, IEFT_MPA_KEY_REQ, IETF_MPA_KEY_SIZE)) {
947 i40iw_pr_err("Unexpected MPA Key received\n");
948 return -1;
950 } else {
951 if (memcmp(mpa_frame->key, IEFT_MPA_KEY_REP, IETF_MPA_KEY_SIZE)) {
952 i40iw_pr_err("Unexpected MPA Key received\n");
953 return -1;
957 if (priv_data_len + mpa_hdr_len > len) {
958 i40iw_pr_err("ietf buffer len(%x + %x != %x)\n",
959 priv_data_len, mpa_hdr_len, len);
960 return -1;
962 if (len > MAX_CM_BUFFER) {
963 i40iw_pr_err("ietf buffer large len = %d\n", len);
964 return -1;
967 switch (mpa_frame->rev) {
968 case IETF_MPA_V2:{
969 u16 ird_size;
970 u16 ord_size;
971 u16 ctrl_ord;
972 u16 ctrl_ird;
974 mpa_v2_frame = (struct ietf_mpa_v2 *)buffer;
975 mpa_hdr_len += IETF_RTR_MSG_SIZE;
976 rtr_msg = &mpa_v2_frame->rtr_msg;
978 /* parse rtr message */
979 ctrl_ord = ntohs(rtr_msg->ctrl_ord);
980 ctrl_ird = ntohs(rtr_msg->ctrl_ird);
981 ird_size = ctrl_ird & IETF_NO_IRD_ORD;
982 ord_size = ctrl_ord & IETF_NO_IRD_ORD;
984 if (!(ctrl_ird & IETF_PEER_TO_PEER))
985 return -1;
987 if (ird_size == IETF_NO_IRD_ORD || ord_size == IETF_NO_IRD_ORD) {
988 cm_node->mpav2_ird_ord = IETF_NO_IRD_ORD;
989 goto negotiate_done;
992 if (cm_node->state != I40IW_CM_STATE_MPAREQ_SENT) {
993 /* responder */
994 if (!ord_size && (ctrl_ord & IETF_RDMA0_READ))
995 cm_node->ird_size = 1;
996 if (cm_node->ord_size > ird_size)
997 cm_node->ord_size = ird_size;
998 } else {
999 /* initiator */
1000 if (!ird_size && (ctrl_ord & IETF_RDMA0_READ))
1001 return -1;
1002 if (cm_node->ord_size > ird_size)
1003 cm_node->ord_size = ird_size;
1005 if (cm_node->ird_size < ord_size)
1006 /* no resources available */
1007 return -1;
1010 negotiate_done:
1011 if (ctrl_ord & IETF_RDMA0_READ)
1012 cm_node->send_rdma0_op = SEND_RDMA_READ_ZERO;
1013 else if (ctrl_ord & IETF_RDMA0_WRITE)
1014 cm_node->send_rdma0_op = SEND_RDMA_WRITE_ZERO;
1015 else /* Not supported RDMA0 operation */
1016 return -1;
1017 i40iw_debug(cm_node->dev, I40IW_DEBUG_CM,
1018 "MPAV2: Negotiated ORD: %d, IRD: %d\n",
1019 cm_node->ord_size, cm_node->ird_size);
1020 break;
1022 break;
1023 case IETF_MPA_V1:
1024 default:
1025 break;
1028 memcpy(cm_node->pdata_buf, buffer + mpa_hdr_len, priv_data_len);
1029 cm_node->pdata.size = priv_data_len;
1031 if (mpa_frame->flags & IETF_MPA_FLAGS_REJECT)
1032 *type = I40IW_MPA_REQUEST_REJECT;
1034 if (mpa_frame->flags & IETF_MPA_FLAGS_MARKERS)
1035 cm_node->snd_mark_en = true;
1037 return 0;
1041 * i40iw_schedule_cm_timer
1042 * @@cm_node: connection's node
1043 * @sqbuf: buffer to send
1044 * @type: if it is send or close
1045 * @send_retrans: if rexmits to be done
1046 * @close_when_complete: is cm_node to be removed
1048 * note - cm_node needs to be protected before calling this. Encase in:
1049 * i40iw_rem_ref_cm_node(cm_core, cm_node);
1050 * i40iw_schedule_cm_timer(...)
1051 * atomic_inc(&cm_node->ref_count);
1053 int i40iw_schedule_cm_timer(struct i40iw_cm_node *cm_node,
1054 struct i40iw_puda_buf *sqbuf,
1055 enum i40iw_timer_type type,
1056 int send_retrans,
1057 int close_when_complete)
1059 struct i40iw_sc_vsi *vsi = &cm_node->iwdev->vsi;
1060 struct i40iw_cm_core *cm_core = cm_node->cm_core;
1061 struct i40iw_timer_entry *new_send;
1062 int ret = 0;
1063 u32 was_timer_set;
1064 unsigned long flags;
1066 new_send = kzalloc(sizeof(*new_send), GFP_ATOMIC);
1067 if (!new_send) {
1068 if (type != I40IW_TIMER_TYPE_CLOSE)
1069 i40iw_free_sqbuf(vsi, (void *)sqbuf);
1070 return -ENOMEM;
1072 new_send->retrycount = I40IW_DEFAULT_RETRYS;
1073 new_send->retranscount = I40IW_DEFAULT_RETRANS;
1074 new_send->sqbuf = sqbuf;
1075 new_send->timetosend = jiffies;
1076 new_send->type = type;
1077 new_send->send_retrans = send_retrans;
1078 new_send->close_when_complete = close_when_complete;
1080 if (type == I40IW_TIMER_TYPE_CLOSE) {
1081 new_send->timetosend += (HZ / 10);
1082 if (cm_node->close_entry) {
1083 kfree(new_send);
1084 i40iw_pr_err("already close entry\n");
1085 return -EINVAL;
1087 cm_node->close_entry = new_send;
1090 if (type == I40IW_TIMER_TYPE_SEND) {
1091 spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
1092 cm_node->send_entry = new_send;
1093 atomic_inc(&cm_node->ref_count);
1094 spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags);
1095 new_send->timetosend = jiffies + I40IW_RETRY_TIMEOUT;
1097 atomic_inc(&sqbuf->refcount);
1098 i40iw_puda_send_buf(vsi->ilq, sqbuf);
1099 if (!send_retrans) {
1100 i40iw_cleanup_retrans_entry(cm_node);
1101 if (close_when_complete)
1102 i40iw_rem_ref_cm_node(cm_node);
1103 return ret;
1107 spin_lock_irqsave(&cm_core->ht_lock, flags);
1108 was_timer_set = timer_pending(&cm_core->tcp_timer);
1110 if (!was_timer_set) {
1111 cm_core->tcp_timer.expires = new_send->timetosend;
1112 add_timer(&cm_core->tcp_timer);
1114 spin_unlock_irqrestore(&cm_core->ht_lock, flags);
1116 return ret;
1120 * i40iw_retrans_expired - Could not rexmit the packet
1121 * @cm_node: connection's node
1123 static void i40iw_retrans_expired(struct i40iw_cm_node *cm_node)
1125 struct iw_cm_id *cm_id = cm_node->cm_id;
1126 enum i40iw_cm_node_state state = cm_node->state;
1128 cm_node->state = I40IW_CM_STATE_CLOSED;
1129 switch (state) {
1130 case I40IW_CM_STATE_SYN_RCVD:
1131 case I40IW_CM_STATE_CLOSING:
1132 i40iw_rem_ref_cm_node(cm_node);
1133 break;
1134 case I40IW_CM_STATE_FIN_WAIT1:
1135 case I40IW_CM_STATE_LAST_ACK:
1136 if (cm_node->cm_id)
1137 cm_id->rem_ref(cm_id);
1138 i40iw_send_reset(cm_node);
1139 break;
1140 default:
1141 atomic_inc(&cm_node->ref_count);
1142 i40iw_send_reset(cm_node);
1143 i40iw_create_event(cm_node, I40IW_CM_EVENT_ABORTED);
1144 break;
1149 * i40iw_handle_close_entry - for handling retry/timeouts
1150 * @cm_node: connection's node
1151 * @rem_node: flag for remove cm_node
1153 static void i40iw_handle_close_entry(struct i40iw_cm_node *cm_node, u32 rem_node)
1155 struct i40iw_timer_entry *close_entry = cm_node->close_entry;
1156 struct iw_cm_id *cm_id = cm_node->cm_id;
1157 struct i40iw_qp *iwqp;
1158 unsigned long flags;
1160 if (!close_entry)
1161 return;
1162 iwqp = (struct i40iw_qp *)close_entry->sqbuf;
1163 if (iwqp) {
1164 spin_lock_irqsave(&iwqp->lock, flags);
1165 if (iwqp->cm_id) {
1166 iwqp->hw_tcp_state = I40IW_TCP_STATE_CLOSED;
1167 iwqp->hw_iwarp_state = I40IW_QP_STATE_ERROR;
1168 iwqp->last_aeq = I40IW_AE_RESET_SENT;
1169 iwqp->ibqp_state = IB_QPS_ERR;
1170 spin_unlock_irqrestore(&iwqp->lock, flags);
1171 i40iw_cm_disconn(iwqp);
1172 } else {
1173 spin_unlock_irqrestore(&iwqp->lock, flags);
1175 } else if (rem_node) {
1176 /* TIME_WAIT state */
1177 i40iw_rem_ref_cm_node(cm_node);
1179 if (cm_id)
1180 cm_id->rem_ref(cm_id);
1181 kfree(close_entry);
1182 cm_node->close_entry = NULL;
1186 * i40iw_cm_timer_tick - system's timer expired callback
1187 * @pass: Pointing to cm_core
1189 static void i40iw_cm_timer_tick(struct timer_list *t)
1191 unsigned long nexttimeout = jiffies + I40IW_LONG_TIME;
1192 struct i40iw_cm_node *cm_node;
1193 struct i40iw_timer_entry *send_entry, *close_entry;
1194 struct list_head *list_core_temp;
1195 struct i40iw_sc_vsi *vsi;
1196 struct list_head *list_node;
1197 struct i40iw_cm_core *cm_core = from_timer(cm_core, t, tcp_timer);
1198 u32 settimer = 0;
1199 unsigned long timetosend;
1200 unsigned long flags;
1202 struct list_head timer_list;
1204 INIT_LIST_HEAD(&timer_list);
1205 spin_lock_irqsave(&cm_core->ht_lock, flags);
1207 list_for_each_safe(list_node, list_core_temp, &cm_core->connected_nodes) {
1208 cm_node = container_of(list_node, struct i40iw_cm_node, list);
1209 if (cm_node->close_entry || cm_node->send_entry) {
1210 atomic_inc(&cm_node->ref_count);
1211 list_add(&cm_node->timer_entry, &timer_list);
1214 spin_unlock_irqrestore(&cm_core->ht_lock, flags);
1216 list_for_each_safe(list_node, list_core_temp, &timer_list) {
1217 cm_node = container_of(list_node,
1218 struct i40iw_cm_node,
1219 timer_entry);
1220 close_entry = cm_node->close_entry;
1222 if (close_entry) {
1223 if (time_after(close_entry->timetosend, jiffies)) {
1224 if (nexttimeout > close_entry->timetosend ||
1225 !settimer) {
1226 nexttimeout = close_entry->timetosend;
1227 settimer = 1;
1229 } else {
1230 i40iw_handle_close_entry(cm_node, 1);
1234 spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
1236 send_entry = cm_node->send_entry;
1237 if (!send_entry)
1238 goto done;
1239 if (time_after(send_entry->timetosend, jiffies)) {
1240 if (cm_node->state != I40IW_CM_STATE_OFFLOADED) {
1241 if ((nexttimeout > send_entry->timetosend) ||
1242 !settimer) {
1243 nexttimeout = send_entry->timetosend;
1244 settimer = 1;
1246 } else {
1247 i40iw_free_retrans_entry(cm_node);
1249 goto done;
1252 if ((cm_node->state == I40IW_CM_STATE_OFFLOADED) ||
1253 (cm_node->state == I40IW_CM_STATE_CLOSED)) {
1254 i40iw_free_retrans_entry(cm_node);
1255 goto done;
1258 if (!send_entry->retranscount || !send_entry->retrycount) {
1259 i40iw_free_retrans_entry(cm_node);
1261 spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags);
1262 i40iw_retrans_expired(cm_node);
1263 cm_node->state = I40IW_CM_STATE_CLOSED;
1264 spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
1265 goto done;
1267 spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags);
1269 vsi = &cm_node->iwdev->vsi;
1271 if (!cm_node->ack_rcvd) {
1272 atomic_inc(&send_entry->sqbuf->refcount);
1273 i40iw_puda_send_buf(vsi->ilq, send_entry->sqbuf);
1274 cm_node->cm_core->stats_pkt_retrans++;
1276 spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
1277 if (send_entry->send_retrans) {
1278 send_entry->retranscount--;
1279 timetosend = (I40IW_RETRY_TIMEOUT <<
1280 (I40IW_DEFAULT_RETRANS -
1281 send_entry->retranscount));
1283 send_entry->timetosend = jiffies +
1284 min(timetosend, I40IW_MAX_TIMEOUT);
1285 if (nexttimeout > send_entry->timetosend || !settimer) {
1286 nexttimeout = send_entry->timetosend;
1287 settimer = 1;
1289 } else {
1290 int close_when_complete;
1292 close_when_complete = send_entry->close_when_complete;
1293 i40iw_debug(cm_node->dev,
1294 I40IW_DEBUG_CM,
1295 "cm_node=%p state=%d\n",
1296 cm_node,
1297 cm_node->state);
1298 i40iw_free_retrans_entry(cm_node);
1299 if (close_when_complete)
1300 i40iw_rem_ref_cm_node(cm_node);
1302 done:
1303 spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags);
1304 i40iw_rem_ref_cm_node(cm_node);
1307 if (settimer) {
1308 spin_lock_irqsave(&cm_core->ht_lock, flags);
1309 if (!timer_pending(&cm_core->tcp_timer)) {
1310 cm_core->tcp_timer.expires = nexttimeout;
1311 add_timer(&cm_core->tcp_timer);
1313 spin_unlock_irqrestore(&cm_core->ht_lock, flags);
1318 * i40iw_send_syn - send SYN packet
1319 * @cm_node: connection's node
1320 * @sendack: flag to set ACK bit or not
1322 int i40iw_send_syn(struct i40iw_cm_node *cm_node, u32 sendack)
1324 struct i40iw_puda_buf *sqbuf;
1325 int flags = SET_SYN;
1326 char optionsbuffer[sizeof(struct option_mss) +
1327 sizeof(struct option_windowscale) +
1328 sizeof(struct option_base) + TCP_OPTIONS_PADDING];
1329 struct i40iw_kmem_info opts;
1331 int optionssize = 0;
1332 /* Sending MSS option */
1333 union all_known_options *options;
1335 opts.addr = optionsbuffer;
1336 if (!cm_node) {
1337 i40iw_pr_err("no cm_node\n");
1338 return -EINVAL;
1341 options = (union all_known_options *)&optionsbuffer[optionssize];
1342 options->as_mss.optionnum = OPTION_NUMBER_MSS;
1343 options->as_mss.length = sizeof(struct option_mss);
1344 options->as_mss.mss = htons(cm_node->tcp_cntxt.mss);
1345 optionssize += sizeof(struct option_mss);
1347 options = (union all_known_options *)&optionsbuffer[optionssize];
1348 options->as_windowscale.optionnum = OPTION_NUMBER_WINDOW_SCALE;
1349 options->as_windowscale.length = sizeof(struct option_windowscale);
1350 options->as_windowscale.shiftcount = cm_node->tcp_cntxt.rcv_wscale;
1351 optionssize += sizeof(struct option_windowscale);
1352 options = (union all_known_options *)&optionsbuffer[optionssize];
1353 options->as_end = OPTION_NUMBER_END;
1354 optionssize += 1;
1356 if (sendack)
1357 flags |= SET_ACK;
1359 opts.size = optionssize;
1361 sqbuf = i40iw_form_cm_frame(cm_node, &opts, NULL, NULL, flags);
1362 if (!sqbuf) {
1363 i40iw_pr_err("no sqbuf\n");
1364 return -1;
1366 return i40iw_schedule_cm_timer(cm_node, sqbuf, I40IW_TIMER_TYPE_SEND, 1, 0);
1370 * i40iw_send_ack - Send ACK packet
1371 * @cm_node: connection's node
1373 static void i40iw_send_ack(struct i40iw_cm_node *cm_node)
1375 struct i40iw_puda_buf *sqbuf;
1376 struct i40iw_sc_vsi *vsi = &cm_node->iwdev->vsi;
1378 sqbuf = i40iw_form_cm_frame(cm_node, NULL, NULL, NULL, SET_ACK);
1379 if (sqbuf)
1380 i40iw_puda_send_buf(vsi->ilq, sqbuf);
1381 else
1382 i40iw_pr_err("no sqbuf\n");
1386 * i40iw_send_fin - Send FIN pkt
1387 * @cm_node: connection's node
1389 static int i40iw_send_fin(struct i40iw_cm_node *cm_node)
1391 struct i40iw_puda_buf *sqbuf;
1393 sqbuf = i40iw_form_cm_frame(cm_node, NULL, NULL, NULL, SET_ACK | SET_FIN);
1394 if (!sqbuf) {
1395 i40iw_pr_err("no sqbuf\n");
1396 return -1;
1398 return i40iw_schedule_cm_timer(cm_node, sqbuf, I40IW_TIMER_TYPE_SEND, 1, 0);
1402 * i40iw_find_node - find a cm node that matches the reference cm node
1403 * @cm_core: cm's core
1404 * @rem_port: remote tcp port num
1405 * @rem_addr: remote ip addr
1406 * @loc_port: local tcp port num
1407 * @loc_addr: loc ip addr
1408 * @add_refcnt: flag to increment refcount of cm_node
1410 struct i40iw_cm_node *i40iw_find_node(struct i40iw_cm_core *cm_core,
1411 u16 rem_port,
1412 u32 *rem_addr,
1413 u16 loc_port,
1414 u32 *loc_addr,
1415 bool add_refcnt)
1417 struct list_head *hte;
1418 struct i40iw_cm_node *cm_node;
1419 unsigned long flags;
1421 hte = &cm_core->connected_nodes;
1423 /* walk list and find cm_node associated with this session ID */
1424 spin_lock_irqsave(&cm_core->ht_lock, flags);
1425 list_for_each_entry(cm_node, hte, list) {
1426 if (!memcmp(cm_node->loc_addr, loc_addr, sizeof(cm_node->loc_addr)) &&
1427 (cm_node->loc_port == loc_port) &&
1428 !memcmp(cm_node->rem_addr, rem_addr, sizeof(cm_node->rem_addr)) &&
1429 (cm_node->rem_port == rem_port)) {
1430 if (add_refcnt)
1431 atomic_inc(&cm_node->ref_count);
1432 spin_unlock_irqrestore(&cm_core->ht_lock, flags);
1433 return cm_node;
1436 spin_unlock_irqrestore(&cm_core->ht_lock, flags);
1438 /* no owner node */
1439 return NULL;
1443 * i40iw_find_listener - find a cm node listening on this addr-port pair
1444 * @cm_core: cm's core
1445 * @dst_port: listener tcp port num
1446 * @dst_addr: listener ip addr
1447 * @listener_state: state to match with listen node's
1449 static struct i40iw_cm_listener *i40iw_find_listener(
1450 struct i40iw_cm_core *cm_core,
1451 u32 *dst_addr,
1452 u16 dst_port,
1453 u16 vlan_id,
1454 enum i40iw_cm_listener_state
1455 listener_state)
1457 struct i40iw_cm_listener *listen_node;
1458 static const u32 ip_zero[4] = { 0, 0, 0, 0 };
1459 u32 listen_addr[4];
1460 u16 listen_port;
1461 unsigned long flags;
1463 /* walk list and find cm_node associated with this session ID */
1464 spin_lock_irqsave(&cm_core->listen_list_lock, flags);
1465 list_for_each_entry(listen_node, &cm_core->listen_nodes, list) {
1466 memcpy(listen_addr, listen_node->loc_addr, sizeof(listen_addr));
1467 listen_port = listen_node->loc_port;
1468 /* compare node pair, return node handle if a match */
1469 if ((!memcmp(listen_addr, dst_addr, sizeof(listen_addr)) ||
1470 !memcmp(listen_addr, ip_zero, sizeof(listen_addr))) &&
1471 (listen_port == dst_port) &&
1472 (listener_state & listen_node->listener_state)) {
1473 atomic_inc(&listen_node->ref_count);
1474 spin_unlock_irqrestore(&cm_core->listen_list_lock, flags);
1475 return listen_node;
1478 spin_unlock_irqrestore(&cm_core->listen_list_lock, flags);
1479 return NULL;
1483 * i40iw_add_hte_node - add a cm node to the hash table
1484 * @cm_core: cm's core
1485 * @cm_node: connection's node
1487 static void i40iw_add_hte_node(struct i40iw_cm_core *cm_core,
1488 struct i40iw_cm_node *cm_node)
1490 struct list_head *hte;
1491 unsigned long flags;
1493 if (!cm_node || !cm_core) {
1494 i40iw_pr_err("cm_node or cm_core == NULL\n");
1495 return;
1497 spin_lock_irqsave(&cm_core->ht_lock, flags);
1499 /* get a handle on the hash table element (list head for this slot) */
1500 hte = &cm_core->connected_nodes;
1501 list_add_tail(&cm_node->list, hte);
1502 spin_unlock_irqrestore(&cm_core->ht_lock, flags);
1506 * i40iw_port_in_use - determine if port is in use
1507 * @port: port number
1508 * @active_side: flag for listener side vs active side
1510 static bool i40iw_port_in_use(struct i40iw_cm_core *cm_core, u16 port, bool active_side)
1512 struct i40iw_cm_listener *listen_node;
1513 struct i40iw_cm_node *cm_node;
1514 unsigned long flags;
1515 bool ret = false;
1517 if (active_side) {
1518 /* search connected node list */
1519 spin_lock_irqsave(&cm_core->ht_lock, flags);
1520 list_for_each_entry(cm_node, &cm_core->connected_nodes, list) {
1521 if (cm_node->loc_port == port) {
1522 ret = true;
1523 break;
1526 if (!ret)
1527 clear_bit(port, cm_core->active_side_ports);
1528 spin_unlock_irqrestore(&cm_core->ht_lock, flags);
1529 } else {
1530 spin_lock_irqsave(&cm_core->listen_list_lock, flags);
1531 list_for_each_entry(listen_node, &cm_core->listen_nodes, list) {
1532 if (listen_node->loc_port == port) {
1533 ret = true;
1534 break;
1537 spin_unlock_irqrestore(&cm_core->listen_list_lock, flags);
1540 return ret;
1544 * i40iw_del_multiple_qhash - Remove qhash and child listens
1545 * @iwdev: iWarp device
1546 * @cm_info: CM info for parent listen node
1547 * @cm_parent_listen_node: The parent listen node
1549 static enum i40iw_status_code i40iw_del_multiple_qhash(
1550 struct i40iw_device *iwdev,
1551 struct i40iw_cm_info *cm_info,
1552 struct i40iw_cm_listener *cm_parent_listen_node)
1554 struct i40iw_cm_listener *child_listen_node;
1555 enum i40iw_status_code ret = I40IW_ERR_CONFIG;
1556 struct list_head *pos, *tpos;
1557 unsigned long flags;
1559 spin_lock_irqsave(&iwdev->cm_core.listen_list_lock, flags);
1560 list_for_each_safe(pos, tpos, &cm_parent_listen_node->child_listen_list) {
1561 child_listen_node = list_entry(pos, struct i40iw_cm_listener, child_listen_list);
1562 if (child_listen_node->ipv4)
1563 i40iw_debug(&iwdev->sc_dev,
1564 I40IW_DEBUG_CM,
1565 "removing child listen for IP=%pI4, port=%d, vlan=%d\n",
1566 child_listen_node->loc_addr,
1567 child_listen_node->loc_port,
1568 child_listen_node->vlan_id);
1569 else
1570 i40iw_debug(&iwdev->sc_dev, I40IW_DEBUG_CM,
1571 "removing child listen for IP=%pI6, port=%d, vlan=%d\n",
1572 child_listen_node->loc_addr,
1573 child_listen_node->loc_port,
1574 child_listen_node->vlan_id);
1575 list_del(pos);
1576 memcpy(cm_info->loc_addr, child_listen_node->loc_addr,
1577 sizeof(cm_info->loc_addr));
1578 cm_info->vlan_id = child_listen_node->vlan_id;
1579 if (child_listen_node->qhash_set) {
1580 ret = i40iw_manage_qhash(iwdev, cm_info,
1581 I40IW_QHASH_TYPE_TCP_SYN,
1582 I40IW_QHASH_MANAGE_TYPE_DELETE,
1583 NULL, false);
1584 child_listen_node->qhash_set = false;
1585 } else {
1586 ret = I40IW_SUCCESS;
1588 i40iw_debug(&iwdev->sc_dev,
1589 I40IW_DEBUG_CM,
1590 "freed pointer = %p\n",
1591 child_listen_node);
1592 kfree(child_listen_node);
1593 cm_parent_listen_node->cm_core->stats_listen_nodes_destroyed++;
1595 spin_unlock_irqrestore(&iwdev->cm_core.listen_list_lock, flags);
1597 return ret;
1601 * i40iw_netdev_vlan_ipv6 - Gets the netdev and vlan
1602 * @addr: local IPv6 address
1603 * @vlan_id: vlan id for the given IPv6 address
1605 * Returns the net_device of the IPv6 address and also sets the
1606 * vlan id for that address.
1608 static struct net_device *i40iw_netdev_vlan_ipv6(u32 *addr, u16 *vlan_id)
1610 struct net_device *ip_dev = NULL;
1611 struct in6_addr laddr6;
1613 if (!IS_ENABLED(CONFIG_IPV6))
1614 return NULL;
1615 i40iw_copy_ip_htonl(laddr6.in6_u.u6_addr32, addr);
1616 if (vlan_id)
1617 *vlan_id = I40IW_NO_VLAN;
1618 rcu_read_lock();
1619 for_each_netdev_rcu(&init_net, ip_dev) {
1620 if (ipv6_chk_addr(&init_net, &laddr6, ip_dev, 1)) {
1621 if (vlan_id)
1622 *vlan_id = rdma_vlan_dev_vlan_id(ip_dev);
1623 break;
1626 rcu_read_unlock();
1627 return ip_dev;
1631 * i40iw_get_vlan_ipv4 - Returns the vlan_id for IPv4 address
1632 * @addr: local IPv4 address
1634 static u16 i40iw_get_vlan_ipv4(u32 *addr)
1636 struct net_device *netdev;
1637 u16 vlan_id = I40IW_NO_VLAN;
1639 netdev = ip_dev_find(&init_net, htonl(addr[0]));
1640 if (netdev) {
1641 vlan_id = rdma_vlan_dev_vlan_id(netdev);
1642 dev_put(netdev);
1644 return vlan_id;
1648 * i40iw_add_mqh_6 - Adds multiple qhashes for IPv6
1649 * @iwdev: iWarp device
1650 * @cm_info: CM info for parent listen node
1651 * @cm_parent_listen_node: The parent listen node
1653 * Adds a qhash and a child listen node for every IPv6 address
1654 * on the adapter and adds the associated qhash filter
1656 static enum i40iw_status_code i40iw_add_mqh_6(struct i40iw_device *iwdev,
1657 struct i40iw_cm_info *cm_info,
1658 struct i40iw_cm_listener *cm_parent_listen_node)
1660 struct net_device *ip_dev;
1661 struct inet6_dev *idev;
1662 struct inet6_ifaddr *ifp, *tmp;
1663 enum i40iw_status_code ret = 0;
1664 struct i40iw_cm_listener *child_listen_node;
1665 unsigned long flags;
1667 rtnl_lock();
1668 for_each_netdev_rcu(&init_net, ip_dev) {
1669 if ((((rdma_vlan_dev_vlan_id(ip_dev) < I40IW_NO_VLAN) &&
1670 (rdma_vlan_dev_real_dev(ip_dev) == iwdev->netdev)) ||
1671 (ip_dev == iwdev->netdev)) && (ip_dev->flags & IFF_UP)) {
1672 idev = __in6_dev_get(ip_dev);
1673 if (!idev) {
1674 i40iw_pr_err("idev == NULL\n");
1675 break;
1677 list_for_each_entry_safe(ifp, tmp, &idev->addr_list, if_list) {
1678 i40iw_debug(&iwdev->sc_dev,
1679 I40IW_DEBUG_CM,
1680 "IP=%pI6, vlan_id=%d, MAC=%pM\n",
1681 &ifp->addr,
1682 rdma_vlan_dev_vlan_id(ip_dev),
1683 ip_dev->dev_addr);
1684 child_listen_node =
1685 kzalloc(sizeof(*child_listen_node), GFP_ATOMIC);
1686 i40iw_debug(&iwdev->sc_dev,
1687 I40IW_DEBUG_CM,
1688 "Allocating child listener %p\n",
1689 child_listen_node);
1690 if (!child_listen_node) {
1691 ret = I40IW_ERR_NO_MEMORY;
1692 goto exit;
1694 cm_info->vlan_id = rdma_vlan_dev_vlan_id(ip_dev);
1695 cm_parent_listen_node->vlan_id = cm_info->vlan_id;
1697 memcpy(child_listen_node, cm_parent_listen_node,
1698 sizeof(*child_listen_node));
1700 i40iw_copy_ip_ntohl(child_listen_node->loc_addr,
1701 ifp->addr.in6_u.u6_addr32);
1702 memcpy(cm_info->loc_addr, child_listen_node->loc_addr,
1703 sizeof(cm_info->loc_addr));
1705 ret = i40iw_manage_qhash(iwdev, cm_info,
1706 I40IW_QHASH_TYPE_TCP_SYN,
1707 I40IW_QHASH_MANAGE_TYPE_ADD,
1708 NULL, true);
1709 if (!ret) {
1710 child_listen_node->qhash_set = true;
1711 spin_lock_irqsave(&iwdev->cm_core.listen_list_lock, flags);
1712 list_add(&child_listen_node->child_listen_list,
1713 &cm_parent_listen_node->child_listen_list);
1714 spin_unlock_irqrestore(&iwdev->cm_core.listen_list_lock, flags);
1715 cm_parent_listen_node->cm_core->stats_listen_nodes_created++;
1716 } else {
1717 kfree(child_listen_node);
1722 exit:
1723 rtnl_unlock();
1724 return ret;
1728 * i40iw_add_mqh_4 - Adds multiple qhashes for IPv4
1729 * @iwdev: iWarp device
1730 * @cm_info: CM info for parent listen node
1731 * @cm_parent_listen_node: The parent listen node
1733 * Adds a qhash and a child listen node for every IPv4 address
1734 * on the adapter and adds the associated qhash filter
1736 static enum i40iw_status_code i40iw_add_mqh_4(
1737 struct i40iw_device *iwdev,
1738 struct i40iw_cm_info *cm_info,
1739 struct i40iw_cm_listener *cm_parent_listen_node)
1741 struct net_device *dev;
1742 struct in_device *idev;
1743 struct i40iw_cm_listener *child_listen_node;
1744 enum i40iw_status_code ret = 0;
1745 unsigned long flags;
1747 rtnl_lock();
1748 for_each_netdev(&init_net, dev) {
1749 if ((((rdma_vlan_dev_vlan_id(dev) < I40IW_NO_VLAN) &&
1750 (rdma_vlan_dev_real_dev(dev) == iwdev->netdev)) ||
1751 (dev == iwdev->netdev)) && (dev->flags & IFF_UP)) {
1752 idev = in_dev_get(dev);
1753 for_ifa(idev) {
1754 i40iw_debug(&iwdev->sc_dev,
1755 I40IW_DEBUG_CM,
1756 "Allocating child CM Listener forIP=%pI4, vlan_id=%d, MAC=%pM\n",
1757 &ifa->ifa_address,
1758 rdma_vlan_dev_vlan_id(dev),
1759 dev->dev_addr);
1760 child_listen_node = kzalloc(sizeof(*child_listen_node), GFP_ATOMIC);
1761 cm_parent_listen_node->cm_core->stats_listen_nodes_created++;
1762 i40iw_debug(&iwdev->sc_dev,
1763 I40IW_DEBUG_CM,
1764 "Allocating child listener %p\n",
1765 child_listen_node);
1766 if (!child_listen_node) {
1767 in_dev_put(idev);
1768 ret = I40IW_ERR_NO_MEMORY;
1769 goto exit;
1771 cm_info->vlan_id = rdma_vlan_dev_vlan_id(dev);
1772 cm_parent_listen_node->vlan_id = cm_info->vlan_id;
1773 memcpy(child_listen_node,
1774 cm_parent_listen_node,
1775 sizeof(*child_listen_node));
1777 child_listen_node->loc_addr[0] = ntohl(ifa->ifa_address);
1778 memcpy(cm_info->loc_addr, child_listen_node->loc_addr,
1779 sizeof(cm_info->loc_addr));
1781 ret = i40iw_manage_qhash(iwdev,
1782 cm_info,
1783 I40IW_QHASH_TYPE_TCP_SYN,
1784 I40IW_QHASH_MANAGE_TYPE_ADD,
1785 NULL,
1786 true);
1787 if (!ret) {
1788 child_listen_node->qhash_set = true;
1789 spin_lock_irqsave(&iwdev->cm_core.listen_list_lock, flags);
1790 list_add(&child_listen_node->child_listen_list,
1791 &cm_parent_listen_node->child_listen_list);
1792 spin_unlock_irqrestore(&iwdev->cm_core.listen_list_lock, flags);
1793 } else {
1794 kfree(child_listen_node);
1795 cm_parent_listen_node->cm_core->stats_listen_nodes_created--;
1798 endfor_ifa(idev);
1799 in_dev_put(idev);
1802 exit:
1803 rtnl_unlock();
1804 return ret;
1808 * i40iw_dec_refcnt_listen - delete listener and associated cm nodes
1809 * @cm_core: cm's core
1810 * @free_hanging_nodes: to free associated cm_nodes
1811 * @apbvt_del: flag to delete the apbvt
1813 static int i40iw_dec_refcnt_listen(struct i40iw_cm_core *cm_core,
1814 struct i40iw_cm_listener *listener,
1815 int free_hanging_nodes, bool apbvt_del)
1817 int ret = -EINVAL;
1818 int err = 0;
1819 struct list_head *list_pos;
1820 struct list_head *list_temp;
1821 struct i40iw_cm_node *cm_node;
1822 struct list_head reset_list;
1823 struct i40iw_cm_info nfo;
1824 struct i40iw_cm_node *loopback;
1825 enum i40iw_cm_node_state old_state;
1826 unsigned long flags;
1828 /* free non-accelerated child nodes for this listener */
1829 INIT_LIST_HEAD(&reset_list);
1830 if (free_hanging_nodes) {
1831 spin_lock_irqsave(&cm_core->ht_lock, flags);
1832 list_for_each_safe(list_pos, list_temp, &cm_core->connected_nodes) {
1833 cm_node = container_of(list_pos, struct i40iw_cm_node, list);
1834 if ((cm_node->listener == listener) && !cm_node->accelerated) {
1835 atomic_inc(&cm_node->ref_count);
1836 list_add(&cm_node->reset_entry, &reset_list);
1839 spin_unlock_irqrestore(&cm_core->ht_lock, flags);
1842 list_for_each_safe(list_pos, list_temp, &reset_list) {
1843 cm_node = container_of(list_pos, struct i40iw_cm_node, reset_entry);
1844 loopback = cm_node->loopbackpartner;
1845 if (cm_node->state >= I40IW_CM_STATE_FIN_WAIT1) {
1846 i40iw_rem_ref_cm_node(cm_node);
1847 } else {
1848 if (!loopback) {
1849 i40iw_cleanup_retrans_entry(cm_node);
1850 err = i40iw_send_reset(cm_node);
1851 if (err) {
1852 cm_node->state = I40IW_CM_STATE_CLOSED;
1853 i40iw_pr_err("send reset\n");
1854 } else {
1855 old_state = cm_node->state;
1856 cm_node->state = I40IW_CM_STATE_LISTENER_DESTROYED;
1857 if (old_state != I40IW_CM_STATE_MPAREQ_RCVD)
1858 i40iw_rem_ref_cm_node(cm_node);
1860 } else {
1861 struct i40iw_cm_event event;
1863 event.cm_node = loopback;
1864 memcpy(event.cm_info.rem_addr,
1865 loopback->rem_addr, sizeof(event.cm_info.rem_addr));
1866 memcpy(event.cm_info.loc_addr,
1867 loopback->loc_addr, sizeof(event.cm_info.loc_addr));
1868 event.cm_info.rem_port = loopback->rem_port;
1869 event.cm_info.loc_port = loopback->loc_port;
1870 event.cm_info.cm_id = loopback->cm_id;
1871 event.cm_info.ipv4 = loopback->ipv4;
1872 atomic_inc(&loopback->ref_count);
1873 loopback->state = I40IW_CM_STATE_CLOSED;
1874 i40iw_event_connect_error(&event);
1875 cm_node->state = I40IW_CM_STATE_LISTENER_DESTROYED;
1876 i40iw_rem_ref_cm_node(cm_node);
1881 if (!atomic_dec_return(&listener->ref_count)) {
1882 spin_lock_irqsave(&cm_core->listen_list_lock, flags);
1883 list_del(&listener->list);
1884 spin_unlock_irqrestore(&cm_core->listen_list_lock, flags);
1886 if (listener->iwdev) {
1887 if (apbvt_del && !i40iw_port_in_use(cm_core, listener->loc_port, false))
1888 i40iw_manage_apbvt(listener->iwdev,
1889 listener->loc_port,
1890 I40IW_MANAGE_APBVT_DEL);
1892 memcpy(nfo.loc_addr, listener->loc_addr, sizeof(nfo.loc_addr));
1893 nfo.loc_port = listener->loc_port;
1894 nfo.ipv4 = listener->ipv4;
1895 nfo.vlan_id = listener->vlan_id;
1896 nfo.user_pri = listener->user_pri;
1898 if (!list_empty(&listener->child_listen_list)) {
1899 i40iw_del_multiple_qhash(listener->iwdev, &nfo, listener);
1900 } else {
1901 if (listener->qhash_set)
1902 i40iw_manage_qhash(listener->iwdev,
1903 &nfo,
1904 I40IW_QHASH_TYPE_TCP_SYN,
1905 I40IW_QHASH_MANAGE_TYPE_DELETE,
1906 NULL,
1907 false);
1911 cm_core->stats_listen_destroyed++;
1912 kfree(listener);
1913 cm_core->stats_listen_nodes_destroyed++;
1914 listener = NULL;
1915 ret = 0;
1918 if (listener) {
1919 if (atomic_read(&listener->pend_accepts_cnt) > 0)
1920 i40iw_debug(cm_core->dev,
1921 I40IW_DEBUG_CM,
1922 "%s: listener (%p) pending accepts=%u\n",
1923 __func__,
1924 listener,
1925 atomic_read(&listener->pend_accepts_cnt));
1928 return ret;
1932 * i40iw_cm_del_listen - delete a linstener
1933 * @cm_core: cm's core
1934 * @listener: passive connection's listener
1935 * @apbvt_del: flag to delete apbvt
1937 static int i40iw_cm_del_listen(struct i40iw_cm_core *cm_core,
1938 struct i40iw_cm_listener *listener,
1939 bool apbvt_del)
1941 listener->listener_state = I40IW_CM_LISTENER_PASSIVE_STATE;
1942 listener->cm_id = NULL; /* going to be destroyed pretty soon */
1943 return i40iw_dec_refcnt_listen(cm_core, listener, 1, apbvt_del);
1947 * i40iw_addr_resolve_neigh - resolve neighbor address
1948 * @iwdev: iwarp device structure
1949 * @src_ip: local ip address
1950 * @dst_ip: remote ip address
1951 * @arpindex: if there is an arp entry
1953 static int i40iw_addr_resolve_neigh(struct i40iw_device *iwdev,
1954 u32 src_ip,
1955 u32 dst_ip,
1956 int arpindex)
1958 struct rtable *rt;
1959 struct neighbour *neigh;
1960 int rc = arpindex;
1961 struct net_device *netdev = iwdev->netdev;
1962 __be32 dst_ipaddr = htonl(dst_ip);
1963 __be32 src_ipaddr = htonl(src_ip);
1965 rt = ip_route_output(&init_net, dst_ipaddr, src_ipaddr, 0, 0);
1966 if (IS_ERR(rt)) {
1967 i40iw_pr_err("ip_route_output\n");
1968 return rc;
1971 if (netif_is_bond_slave(netdev))
1972 netdev = netdev_master_upper_dev_get(netdev);
1974 neigh = dst_neigh_lookup(&rt->dst, &dst_ipaddr);
1976 rcu_read_lock();
1977 if (neigh) {
1978 if (neigh->nud_state & NUD_VALID) {
1979 if (arpindex >= 0) {
1980 if (ether_addr_equal(iwdev->arp_table[arpindex].mac_addr,
1981 neigh->ha))
1982 /* Mac address same as arp table */
1983 goto resolve_neigh_exit;
1984 i40iw_manage_arp_cache(iwdev,
1985 iwdev->arp_table[arpindex].mac_addr,
1986 &dst_ip,
1987 true,
1988 I40IW_ARP_DELETE);
1991 i40iw_manage_arp_cache(iwdev, neigh->ha, &dst_ip, true, I40IW_ARP_ADD);
1992 rc = i40iw_arp_table(iwdev, &dst_ip, true, NULL, I40IW_ARP_RESOLVE);
1993 } else {
1994 neigh_event_send(neigh, NULL);
1997 resolve_neigh_exit:
1999 rcu_read_unlock();
2000 if (neigh)
2001 neigh_release(neigh);
2003 ip_rt_put(rt);
2004 return rc;
2008 * i40iw_get_dst_ipv6
2010 static struct dst_entry *i40iw_get_dst_ipv6(struct sockaddr_in6 *src_addr,
2011 struct sockaddr_in6 *dst_addr)
2013 struct dst_entry *dst;
2014 struct flowi6 fl6;
2016 memset(&fl6, 0, sizeof(fl6));
2017 fl6.daddr = dst_addr->sin6_addr;
2018 fl6.saddr = src_addr->sin6_addr;
2019 if (ipv6_addr_type(&fl6.daddr) & IPV6_ADDR_LINKLOCAL)
2020 fl6.flowi6_oif = dst_addr->sin6_scope_id;
2022 dst = ip6_route_output(&init_net, NULL, &fl6);
2023 return dst;
2027 * i40iw_addr_resolve_neigh_ipv6 - resolve neighbor ipv6 address
2028 * @iwdev: iwarp device structure
2029 * @dst_ip: remote ip address
2030 * @arpindex: if there is an arp entry
2032 static int i40iw_addr_resolve_neigh_ipv6(struct i40iw_device *iwdev,
2033 u32 *src,
2034 u32 *dest,
2035 int arpindex)
2037 struct neighbour *neigh;
2038 int rc = arpindex;
2039 struct net_device *netdev = iwdev->netdev;
2040 struct dst_entry *dst;
2041 struct sockaddr_in6 dst_addr;
2042 struct sockaddr_in6 src_addr;
2044 memset(&dst_addr, 0, sizeof(dst_addr));
2045 dst_addr.sin6_family = AF_INET6;
2046 i40iw_copy_ip_htonl(dst_addr.sin6_addr.in6_u.u6_addr32, dest);
2047 memset(&src_addr, 0, sizeof(src_addr));
2048 src_addr.sin6_family = AF_INET6;
2049 i40iw_copy_ip_htonl(src_addr.sin6_addr.in6_u.u6_addr32, src);
2050 dst = i40iw_get_dst_ipv6(&src_addr, &dst_addr);
2051 if (!dst || dst->error) {
2052 if (dst) {
2053 dst_release(dst);
2054 i40iw_pr_err("ip6_route_output returned dst->error = %d\n",
2055 dst->error);
2057 return rc;
2060 if (netif_is_bond_slave(netdev))
2061 netdev = netdev_master_upper_dev_get(netdev);
2063 neigh = dst_neigh_lookup(dst, &dst_addr);
2065 rcu_read_lock();
2066 if (neigh) {
2067 i40iw_debug(&iwdev->sc_dev, I40IW_DEBUG_CM, "dst_neigh_lookup MAC=%pM\n", neigh->ha);
2068 if (neigh->nud_state & NUD_VALID) {
2069 if (arpindex >= 0) {
2070 if (ether_addr_equal
2071 (iwdev->arp_table[arpindex].mac_addr,
2072 neigh->ha)) {
2073 /* Mac address same as in arp table */
2074 goto resolve_neigh_exit6;
2076 i40iw_manage_arp_cache(iwdev,
2077 iwdev->arp_table[arpindex].mac_addr,
2078 dest,
2079 false,
2080 I40IW_ARP_DELETE);
2082 i40iw_manage_arp_cache(iwdev,
2083 neigh->ha,
2084 dest,
2085 false,
2086 I40IW_ARP_ADD);
2087 rc = i40iw_arp_table(iwdev,
2088 dest,
2089 false,
2090 NULL,
2091 I40IW_ARP_RESOLVE);
2092 } else {
2093 neigh_event_send(neigh, NULL);
2097 resolve_neigh_exit6:
2098 rcu_read_unlock();
2099 if (neigh)
2100 neigh_release(neigh);
2101 dst_release(dst);
2102 return rc;
2106 * i40iw_ipv4_is_loopback - check if loopback
2107 * @loc_addr: local addr to compare
2108 * @rem_addr: remote address
2110 static bool i40iw_ipv4_is_loopback(u32 loc_addr, u32 rem_addr)
2112 return ipv4_is_loopback(htonl(rem_addr)) || (loc_addr == rem_addr);
2116 * i40iw_ipv6_is_loopback - check if loopback
2117 * @loc_addr: local addr to compare
2118 * @rem_addr: remote address
2120 static bool i40iw_ipv6_is_loopback(u32 *loc_addr, u32 *rem_addr)
2122 struct in6_addr raddr6;
2124 i40iw_copy_ip_htonl(raddr6.in6_u.u6_addr32, rem_addr);
2125 return !memcmp(loc_addr, rem_addr, 16) || ipv6_addr_loopback(&raddr6);
2129 * i40iw_make_cm_node - create a new instance of a cm node
2130 * @cm_core: cm's core
2131 * @iwdev: iwarp device structure
2132 * @cm_info: quad info for connection
2133 * @listener: passive connection's listener
2135 static struct i40iw_cm_node *i40iw_make_cm_node(
2136 struct i40iw_cm_core *cm_core,
2137 struct i40iw_device *iwdev,
2138 struct i40iw_cm_info *cm_info,
2139 struct i40iw_cm_listener *listener)
2141 struct i40iw_cm_node *cm_node;
2142 struct timespec ts;
2143 int oldarpindex;
2144 int arpindex;
2145 struct net_device *netdev = iwdev->netdev;
2147 /* create an hte and cm_node for this instance */
2148 cm_node = kzalloc(sizeof(*cm_node), GFP_ATOMIC);
2149 if (!cm_node)
2150 return NULL;
2152 /* set our node specific transport info */
2153 cm_node->ipv4 = cm_info->ipv4;
2154 cm_node->vlan_id = cm_info->vlan_id;
2155 if ((cm_node->vlan_id == I40IW_NO_VLAN) && iwdev->dcb)
2156 cm_node->vlan_id = 0;
2157 cm_node->tos = cm_info->tos;
2158 cm_node->user_pri = cm_info->user_pri;
2159 if (listener) {
2160 if (listener->tos != cm_info->tos)
2161 i40iw_debug(&iwdev->sc_dev, I40IW_DEBUG_DCB,
2162 "application TOS[%d] and remote client TOS[%d] mismatch\n",
2163 listener->tos, cm_info->tos);
2164 cm_node->tos = max(listener->tos, cm_info->tos);
2165 cm_node->user_pri = rt_tos2priority(cm_node->tos);
2166 i40iw_debug(&iwdev->sc_dev, I40IW_DEBUG_DCB, "listener: TOS:[%d] UP:[%d]\n",
2167 cm_node->tos, cm_node->user_pri);
2169 memcpy(cm_node->loc_addr, cm_info->loc_addr, sizeof(cm_node->loc_addr));
2170 memcpy(cm_node->rem_addr, cm_info->rem_addr, sizeof(cm_node->rem_addr));
2171 cm_node->loc_port = cm_info->loc_port;
2172 cm_node->rem_port = cm_info->rem_port;
2174 cm_node->mpa_frame_rev = iwdev->mpa_version;
2175 cm_node->send_rdma0_op = SEND_RDMA_READ_ZERO;
2176 cm_node->ird_size = I40IW_MAX_IRD_SIZE;
2177 cm_node->ord_size = I40IW_MAX_ORD_SIZE;
2179 cm_node->listener = listener;
2180 cm_node->cm_id = cm_info->cm_id;
2181 ether_addr_copy(cm_node->loc_mac, netdev->dev_addr);
2182 spin_lock_init(&cm_node->retrans_list_lock);
2183 cm_node->ack_rcvd = false;
2185 atomic_set(&cm_node->ref_count, 1);
2186 /* associate our parent CM core */
2187 cm_node->cm_core = cm_core;
2188 cm_node->tcp_cntxt.loc_id = I40IW_CM_DEF_LOCAL_ID;
2189 cm_node->tcp_cntxt.rcv_wscale = I40IW_CM_DEFAULT_RCV_WND_SCALE;
2190 cm_node->tcp_cntxt.rcv_wnd =
2191 I40IW_CM_DEFAULT_RCV_WND_SCALED >> I40IW_CM_DEFAULT_RCV_WND_SCALE;
2192 ts = current_kernel_time();
2193 cm_node->tcp_cntxt.loc_seq_num = ts.tv_nsec;
2194 cm_node->tcp_cntxt.mss = (cm_node->ipv4) ? (iwdev->vsi.mtu - I40IW_MTU_TO_MSS_IPV4) :
2195 (iwdev->vsi.mtu - I40IW_MTU_TO_MSS_IPV6);
2197 cm_node->iwdev = iwdev;
2198 cm_node->dev = &iwdev->sc_dev;
2200 if ((cm_node->ipv4 &&
2201 i40iw_ipv4_is_loopback(cm_node->loc_addr[0], cm_node->rem_addr[0])) ||
2202 (!cm_node->ipv4 && i40iw_ipv6_is_loopback(cm_node->loc_addr,
2203 cm_node->rem_addr))) {
2204 arpindex = i40iw_arp_table(iwdev,
2205 cm_node->rem_addr,
2206 false,
2207 NULL,
2208 I40IW_ARP_RESOLVE);
2209 } else {
2210 oldarpindex = i40iw_arp_table(iwdev,
2211 cm_node->rem_addr,
2212 false,
2213 NULL,
2214 I40IW_ARP_RESOLVE);
2215 if (cm_node->ipv4)
2216 arpindex = i40iw_addr_resolve_neigh(iwdev,
2217 cm_info->loc_addr[0],
2218 cm_info->rem_addr[0],
2219 oldarpindex);
2220 else if (IS_ENABLED(CONFIG_IPV6))
2221 arpindex = i40iw_addr_resolve_neigh_ipv6(iwdev,
2222 cm_info->loc_addr,
2223 cm_info->rem_addr,
2224 oldarpindex);
2225 else
2226 arpindex = -EINVAL;
2228 if (arpindex < 0) {
2229 i40iw_pr_err("cm_node arpindex\n");
2230 kfree(cm_node);
2231 return NULL;
2233 ether_addr_copy(cm_node->rem_mac, iwdev->arp_table[arpindex].mac_addr);
2234 i40iw_add_hte_node(cm_core, cm_node);
2235 cm_core->stats_nodes_created++;
2236 return cm_node;
2240 * i40iw_rem_ref_cm_node - destroy an instance of a cm node
2241 * @cm_node: connection's node
2243 static void i40iw_rem_ref_cm_node(struct i40iw_cm_node *cm_node)
2245 struct i40iw_cm_core *cm_core = cm_node->cm_core;
2246 struct i40iw_qp *iwqp;
2247 struct i40iw_cm_info nfo;
2248 unsigned long flags;
2250 spin_lock_irqsave(&cm_node->cm_core->ht_lock, flags);
2251 if (atomic_dec_return(&cm_node->ref_count)) {
2252 spin_unlock_irqrestore(&cm_node->cm_core->ht_lock, flags);
2253 return;
2255 list_del(&cm_node->list);
2256 spin_unlock_irqrestore(&cm_node->cm_core->ht_lock, flags);
2258 /* if the node is destroyed before connection was accelerated */
2259 if (!cm_node->accelerated && cm_node->accept_pend) {
2260 pr_err("node destroyed before established\n");
2261 atomic_dec(&cm_node->listener->pend_accepts_cnt);
2263 if (cm_node->close_entry)
2264 i40iw_handle_close_entry(cm_node, 0);
2265 if (cm_node->listener) {
2266 i40iw_dec_refcnt_listen(cm_core, cm_node->listener, 0, true);
2267 } else {
2268 if (!i40iw_port_in_use(cm_core, cm_node->loc_port, true) && cm_node->apbvt_set) {
2269 i40iw_manage_apbvt(cm_node->iwdev,
2270 cm_node->loc_port,
2271 I40IW_MANAGE_APBVT_DEL);
2272 cm_node->apbvt_set = 0;
2274 i40iw_get_addr_info(cm_node, &nfo);
2275 if (cm_node->qhash_set) {
2276 i40iw_manage_qhash(cm_node->iwdev,
2277 &nfo,
2278 I40IW_QHASH_TYPE_TCP_ESTABLISHED,
2279 I40IW_QHASH_MANAGE_TYPE_DELETE,
2280 NULL,
2281 false);
2282 cm_node->qhash_set = 0;
2286 iwqp = cm_node->iwqp;
2287 if (iwqp) {
2288 iwqp->cm_node = NULL;
2289 i40iw_rem_ref(&iwqp->ibqp);
2290 cm_node->iwqp = NULL;
2291 } else if (cm_node->qhash_set) {
2292 i40iw_get_addr_info(cm_node, &nfo);
2293 i40iw_manage_qhash(cm_node->iwdev,
2294 &nfo,
2295 I40IW_QHASH_TYPE_TCP_ESTABLISHED,
2296 I40IW_QHASH_MANAGE_TYPE_DELETE,
2297 NULL,
2298 false);
2299 cm_node->qhash_set = 0;
2302 cm_node->cm_core->stats_nodes_destroyed++;
2303 kfree(cm_node);
2307 * i40iw_handle_fin_pkt - FIN packet received
2308 * @cm_node: connection's node
2310 static void i40iw_handle_fin_pkt(struct i40iw_cm_node *cm_node)
2312 u32 ret;
2314 switch (cm_node->state) {
2315 case I40IW_CM_STATE_SYN_RCVD:
2316 case I40IW_CM_STATE_SYN_SENT:
2317 case I40IW_CM_STATE_ESTABLISHED:
2318 case I40IW_CM_STATE_MPAREJ_RCVD:
2319 cm_node->tcp_cntxt.rcv_nxt++;
2320 i40iw_cleanup_retrans_entry(cm_node);
2321 cm_node->state = I40IW_CM_STATE_LAST_ACK;
2322 i40iw_send_fin(cm_node);
2323 break;
2324 case I40IW_CM_STATE_MPAREQ_SENT:
2325 i40iw_create_event(cm_node, I40IW_CM_EVENT_ABORTED);
2326 cm_node->tcp_cntxt.rcv_nxt++;
2327 i40iw_cleanup_retrans_entry(cm_node);
2328 cm_node->state = I40IW_CM_STATE_CLOSED;
2329 atomic_inc(&cm_node->ref_count);
2330 i40iw_send_reset(cm_node);
2331 break;
2332 case I40IW_CM_STATE_FIN_WAIT1:
2333 cm_node->tcp_cntxt.rcv_nxt++;
2334 i40iw_cleanup_retrans_entry(cm_node);
2335 cm_node->state = I40IW_CM_STATE_CLOSING;
2336 i40iw_send_ack(cm_node);
2338 * Wait for ACK as this is simultaneous close.
2339 * After we receive ACK, do not send anything.
2340 * Just rm the node.
2342 break;
2343 case I40IW_CM_STATE_FIN_WAIT2:
2344 cm_node->tcp_cntxt.rcv_nxt++;
2345 i40iw_cleanup_retrans_entry(cm_node);
2346 cm_node->state = I40IW_CM_STATE_TIME_WAIT;
2347 i40iw_send_ack(cm_node);
2348 ret =
2349 i40iw_schedule_cm_timer(cm_node, NULL, I40IW_TIMER_TYPE_CLOSE, 1, 0);
2350 if (ret)
2351 i40iw_pr_err("node %p state = %d\n", cm_node, cm_node->state);
2352 break;
2353 case I40IW_CM_STATE_TIME_WAIT:
2354 cm_node->tcp_cntxt.rcv_nxt++;
2355 i40iw_cleanup_retrans_entry(cm_node);
2356 cm_node->state = I40IW_CM_STATE_CLOSED;
2357 i40iw_rem_ref_cm_node(cm_node);
2358 break;
2359 case I40IW_CM_STATE_OFFLOADED:
2360 default:
2361 i40iw_pr_err("bad state node %p state = %d\n", cm_node, cm_node->state);
2362 break;
2367 * i40iw_handle_rst_pkt - process received RST packet
2368 * @cm_node: connection's node
2369 * @rbuf: receive buffer
2371 static void i40iw_handle_rst_pkt(struct i40iw_cm_node *cm_node,
2372 struct i40iw_puda_buf *rbuf)
2374 i40iw_cleanup_retrans_entry(cm_node);
2375 switch (cm_node->state) {
2376 case I40IW_CM_STATE_SYN_SENT:
2377 case I40IW_CM_STATE_MPAREQ_SENT:
2378 switch (cm_node->mpa_frame_rev) {
2379 case IETF_MPA_V2:
2380 cm_node->mpa_frame_rev = IETF_MPA_V1;
2381 /* send a syn and goto syn sent state */
2382 cm_node->state = I40IW_CM_STATE_SYN_SENT;
2383 if (i40iw_send_syn(cm_node, 0))
2384 i40iw_active_open_err(cm_node, false);
2385 break;
2386 case IETF_MPA_V1:
2387 default:
2388 i40iw_active_open_err(cm_node, false);
2389 break;
2391 break;
2392 case I40IW_CM_STATE_MPAREQ_RCVD:
2393 atomic_add_return(1, &cm_node->passive_state);
2394 break;
2395 case I40IW_CM_STATE_ESTABLISHED:
2396 case I40IW_CM_STATE_SYN_RCVD:
2397 case I40IW_CM_STATE_LISTENING:
2398 i40iw_pr_err("Bad state state = %d\n", cm_node->state);
2399 i40iw_passive_open_err(cm_node, false);
2400 break;
2401 case I40IW_CM_STATE_OFFLOADED:
2402 i40iw_active_open_err(cm_node, false);
2403 break;
2404 case I40IW_CM_STATE_CLOSED:
2405 break;
2406 case I40IW_CM_STATE_FIN_WAIT2:
2407 case I40IW_CM_STATE_FIN_WAIT1:
2408 case I40IW_CM_STATE_LAST_ACK:
2409 cm_node->cm_id->rem_ref(cm_node->cm_id);
2410 /* fall through */
2411 case I40IW_CM_STATE_TIME_WAIT:
2412 cm_node->state = I40IW_CM_STATE_CLOSED;
2413 i40iw_rem_ref_cm_node(cm_node);
2414 break;
2415 default:
2416 break;
2421 * i40iw_handle_rcv_mpa - Process a recv'd mpa buffer
2422 * @cm_node: connection's node
2423 * @rbuf: receive buffer
2425 static void i40iw_handle_rcv_mpa(struct i40iw_cm_node *cm_node,
2426 struct i40iw_puda_buf *rbuf)
2428 int ret;
2429 int datasize = rbuf->datalen;
2430 u8 *dataloc = rbuf->data;
2432 enum i40iw_cm_event_type type = I40IW_CM_EVENT_UNKNOWN;
2433 u32 res_type;
2435 ret = i40iw_parse_mpa(cm_node, dataloc, &res_type, datasize);
2436 if (ret) {
2437 if (cm_node->state == I40IW_CM_STATE_MPAREQ_SENT)
2438 i40iw_active_open_err(cm_node, true);
2439 else
2440 i40iw_passive_open_err(cm_node, true);
2441 return;
2444 switch (cm_node->state) {
2445 case I40IW_CM_STATE_ESTABLISHED:
2446 if (res_type == I40IW_MPA_REQUEST_REJECT)
2447 i40iw_pr_err("state for reject\n");
2448 cm_node->state = I40IW_CM_STATE_MPAREQ_RCVD;
2449 type = I40IW_CM_EVENT_MPA_REQ;
2450 i40iw_send_ack(cm_node); /* ACK received MPA request */
2451 atomic_set(&cm_node->passive_state,
2452 I40IW_PASSIVE_STATE_INDICATED);
2453 break;
2454 case I40IW_CM_STATE_MPAREQ_SENT:
2455 i40iw_cleanup_retrans_entry(cm_node);
2456 if (res_type == I40IW_MPA_REQUEST_REJECT) {
2457 type = I40IW_CM_EVENT_MPA_REJECT;
2458 cm_node->state = I40IW_CM_STATE_MPAREJ_RCVD;
2459 } else {
2460 type = I40IW_CM_EVENT_CONNECTED;
2461 cm_node->state = I40IW_CM_STATE_OFFLOADED;
2463 i40iw_send_ack(cm_node);
2464 break;
2465 default:
2466 pr_err("%s wrong cm_node state =%d\n", __func__, cm_node->state);
2467 break;
2469 i40iw_create_event(cm_node, type);
2473 * i40iw_indicate_pkt_err - Send up err event to cm
2474 * @cm_node: connection's node
2476 static void i40iw_indicate_pkt_err(struct i40iw_cm_node *cm_node)
2478 switch (cm_node->state) {
2479 case I40IW_CM_STATE_SYN_SENT:
2480 case I40IW_CM_STATE_MPAREQ_SENT:
2481 i40iw_active_open_err(cm_node, true);
2482 break;
2483 case I40IW_CM_STATE_ESTABLISHED:
2484 case I40IW_CM_STATE_SYN_RCVD:
2485 i40iw_passive_open_err(cm_node, true);
2486 break;
2487 case I40IW_CM_STATE_OFFLOADED:
2488 default:
2489 break;
2494 * i40iw_check_syn - Check for error on received syn ack
2495 * @cm_node: connection's node
2496 * @tcph: pointer tcp header
2498 static int i40iw_check_syn(struct i40iw_cm_node *cm_node, struct tcphdr *tcph)
2500 int err = 0;
2502 if (ntohl(tcph->ack_seq) != cm_node->tcp_cntxt.loc_seq_num) {
2503 err = 1;
2504 i40iw_active_open_err(cm_node, true);
2506 return err;
2510 * i40iw_check_seq - check seq numbers if OK
2511 * @cm_node: connection's node
2512 * @tcph: pointer tcp header
2514 static int i40iw_check_seq(struct i40iw_cm_node *cm_node, struct tcphdr *tcph)
2516 int err = 0;
2517 u32 seq;
2518 u32 ack_seq;
2519 u32 loc_seq_num = cm_node->tcp_cntxt.loc_seq_num;
2520 u32 rcv_nxt = cm_node->tcp_cntxt.rcv_nxt;
2521 u32 rcv_wnd;
2523 seq = ntohl(tcph->seq);
2524 ack_seq = ntohl(tcph->ack_seq);
2525 rcv_wnd = cm_node->tcp_cntxt.rcv_wnd;
2526 if (ack_seq != loc_seq_num)
2527 err = -1;
2528 else if (!between(seq, rcv_nxt, (rcv_nxt + rcv_wnd)))
2529 err = -1;
2530 if (err) {
2531 i40iw_pr_err("seq number\n");
2532 i40iw_indicate_pkt_err(cm_node);
2534 return err;
2538 * i40iw_handle_syn_pkt - is for Passive node
2539 * @cm_node: connection's node
2540 * @rbuf: receive buffer
2542 static void i40iw_handle_syn_pkt(struct i40iw_cm_node *cm_node,
2543 struct i40iw_puda_buf *rbuf)
2545 struct tcphdr *tcph = (struct tcphdr *)rbuf->tcph;
2546 int ret;
2547 u32 inc_sequence;
2548 int optionsize;
2549 struct i40iw_cm_info nfo;
2551 optionsize = (tcph->doff << 2) - sizeof(struct tcphdr);
2552 inc_sequence = ntohl(tcph->seq);
2554 switch (cm_node->state) {
2555 case I40IW_CM_STATE_SYN_SENT:
2556 case I40IW_CM_STATE_MPAREQ_SENT:
2557 /* Rcvd syn on active open connection */
2558 i40iw_active_open_err(cm_node, 1);
2559 break;
2560 case I40IW_CM_STATE_LISTENING:
2561 /* Passive OPEN */
2562 if (atomic_read(&cm_node->listener->pend_accepts_cnt) >
2563 cm_node->listener->backlog) {
2564 cm_node->cm_core->stats_backlog_drops++;
2565 i40iw_passive_open_err(cm_node, false);
2566 break;
2568 ret = i40iw_handle_tcp_options(cm_node, tcph, optionsize, 1);
2569 if (ret) {
2570 i40iw_passive_open_err(cm_node, false);
2571 /* drop pkt */
2572 break;
2574 cm_node->tcp_cntxt.rcv_nxt = inc_sequence + 1;
2575 cm_node->accept_pend = 1;
2576 atomic_inc(&cm_node->listener->pend_accepts_cnt);
2578 cm_node->state = I40IW_CM_STATE_SYN_RCVD;
2579 i40iw_get_addr_info(cm_node, &nfo);
2580 ret = i40iw_manage_qhash(cm_node->iwdev,
2581 &nfo,
2582 I40IW_QHASH_TYPE_TCP_ESTABLISHED,
2583 I40IW_QHASH_MANAGE_TYPE_ADD,
2584 (void *)cm_node,
2585 false);
2586 cm_node->qhash_set = true;
2587 break;
2588 case I40IW_CM_STATE_CLOSED:
2589 i40iw_cleanup_retrans_entry(cm_node);
2590 atomic_inc(&cm_node->ref_count);
2591 i40iw_send_reset(cm_node);
2592 break;
2593 case I40IW_CM_STATE_OFFLOADED:
2594 case I40IW_CM_STATE_ESTABLISHED:
2595 case I40IW_CM_STATE_FIN_WAIT1:
2596 case I40IW_CM_STATE_FIN_WAIT2:
2597 case I40IW_CM_STATE_MPAREQ_RCVD:
2598 case I40IW_CM_STATE_LAST_ACK:
2599 case I40IW_CM_STATE_CLOSING:
2600 case I40IW_CM_STATE_UNKNOWN:
2601 default:
2602 break;
2607 * i40iw_handle_synack_pkt - Process SYN+ACK packet (active side)
2608 * @cm_node: connection's node
2609 * @rbuf: receive buffer
2611 static void i40iw_handle_synack_pkt(struct i40iw_cm_node *cm_node,
2612 struct i40iw_puda_buf *rbuf)
2614 struct tcphdr *tcph = (struct tcphdr *)rbuf->tcph;
2615 int ret;
2616 u32 inc_sequence;
2617 int optionsize;
2619 optionsize = (tcph->doff << 2) - sizeof(struct tcphdr);
2620 inc_sequence = ntohl(tcph->seq);
2621 switch (cm_node->state) {
2622 case I40IW_CM_STATE_SYN_SENT:
2623 i40iw_cleanup_retrans_entry(cm_node);
2624 /* active open */
2625 if (i40iw_check_syn(cm_node, tcph)) {
2626 i40iw_pr_err("check syn fail\n");
2627 return;
2629 cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq);
2630 /* setup options */
2631 ret = i40iw_handle_tcp_options(cm_node, tcph, optionsize, 0);
2632 if (ret) {
2633 i40iw_debug(cm_node->dev,
2634 I40IW_DEBUG_CM,
2635 "cm_node=%p tcp_options failed\n",
2636 cm_node);
2637 break;
2639 i40iw_cleanup_retrans_entry(cm_node);
2640 cm_node->tcp_cntxt.rcv_nxt = inc_sequence + 1;
2641 i40iw_send_ack(cm_node); /* ACK for the syn_ack */
2642 ret = i40iw_send_mpa_request(cm_node);
2643 if (ret) {
2644 i40iw_debug(cm_node->dev,
2645 I40IW_DEBUG_CM,
2646 "cm_node=%p i40iw_send_mpa_request failed\n",
2647 cm_node);
2648 break;
2650 cm_node->state = I40IW_CM_STATE_MPAREQ_SENT;
2651 break;
2652 case I40IW_CM_STATE_MPAREQ_RCVD:
2653 i40iw_passive_open_err(cm_node, true);
2654 break;
2655 case I40IW_CM_STATE_LISTENING:
2656 cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq);
2657 i40iw_cleanup_retrans_entry(cm_node);
2658 cm_node->state = I40IW_CM_STATE_CLOSED;
2659 i40iw_send_reset(cm_node);
2660 break;
2661 case I40IW_CM_STATE_CLOSED:
2662 cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq);
2663 i40iw_cleanup_retrans_entry(cm_node);
2664 atomic_inc(&cm_node->ref_count);
2665 i40iw_send_reset(cm_node);
2666 break;
2667 case I40IW_CM_STATE_ESTABLISHED:
2668 case I40IW_CM_STATE_FIN_WAIT1:
2669 case I40IW_CM_STATE_FIN_WAIT2:
2670 case I40IW_CM_STATE_LAST_ACK:
2671 case I40IW_CM_STATE_OFFLOADED:
2672 case I40IW_CM_STATE_CLOSING:
2673 case I40IW_CM_STATE_UNKNOWN:
2674 case I40IW_CM_STATE_MPAREQ_SENT:
2675 default:
2676 break;
2681 * i40iw_handle_ack_pkt - process packet with ACK
2682 * @cm_node: connection's node
2683 * @rbuf: receive buffer
2685 static int i40iw_handle_ack_pkt(struct i40iw_cm_node *cm_node,
2686 struct i40iw_puda_buf *rbuf)
2688 struct tcphdr *tcph = (struct tcphdr *)rbuf->tcph;
2689 u32 inc_sequence;
2690 int ret = 0;
2691 int optionsize;
2692 u32 datasize = rbuf->datalen;
2694 optionsize = (tcph->doff << 2) - sizeof(struct tcphdr);
2696 if (i40iw_check_seq(cm_node, tcph))
2697 return -EINVAL;
2699 inc_sequence = ntohl(tcph->seq);
2700 switch (cm_node->state) {
2701 case I40IW_CM_STATE_SYN_RCVD:
2702 i40iw_cleanup_retrans_entry(cm_node);
2703 ret = i40iw_handle_tcp_options(cm_node, tcph, optionsize, 1);
2704 if (ret)
2705 break;
2706 cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq);
2707 cm_node->state = I40IW_CM_STATE_ESTABLISHED;
2708 if (datasize) {
2709 cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
2710 i40iw_handle_rcv_mpa(cm_node, rbuf);
2712 break;
2713 case I40IW_CM_STATE_ESTABLISHED:
2714 i40iw_cleanup_retrans_entry(cm_node);
2715 if (datasize) {
2716 cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
2717 i40iw_handle_rcv_mpa(cm_node, rbuf);
2719 break;
2720 case I40IW_CM_STATE_MPAREQ_SENT:
2721 cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq);
2722 if (datasize) {
2723 cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
2724 cm_node->ack_rcvd = false;
2725 i40iw_handle_rcv_mpa(cm_node, rbuf);
2726 } else {
2727 cm_node->ack_rcvd = true;
2729 break;
2730 case I40IW_CM_STATE_LISTENING:
2731 i40iw_cleanup_retrans_entry(cm_node);
2732 cm_node->state = I40IW_CM_STATE_CLOSED;
2733 i40iw_send_reset(cm_node);
2734 break;
2735 case I40IW_CM_STATE_CLOSED:
2736 i40iw_cleanup_retrans_entry(cm_node);
2737 atomic_inc(&cm_node->ref_count);
2738 i40iw_send_reset(cm_node);
2739 break;
2740 case I40IW_CM_STATE_LAST_ACK:
2741 case I40IW_CM_STATE_CLOSING:
2742 i40iw_cleanup_retrans_entry(cm_node);
2743 cm_node->state = I40IW_CM_STATE_CLOSED;
2744 if (!cm_node->accept_pend)
2745 cm_node->cm_id->rem_ref(cm_node->cm_id);
2746 i40iw_rem_ref_cm_node(cm_node);
2747 break;
2748 case I40IW_CM_STATE_FIN_WAIT1:
2749 i40iw_cleanup_retrans_entry(cm_node);
2750 cm_node->state = I40IW_CM_STATE_FIN_WAIT2;
2751 break;
2752 case I40IW_CM_STATE_SYN_SENT:
2753 case I40IW_CM_STATE_FIN_WAIT2:
2754 case I40IW_CM_STATE_OFFLOADED:
2755 case I40IW_CM_STATE_MPAREQ_RCVD:
2756 case I40IW_CM_STATE_UNKNOWN:
2757 default:
2758 i40iw_cleanup_retrans_entry(cm_node);
2759 break;
2761 return ret;
2765 * i40iw_process_packet - process cm packet
2766 * @cm_node: connection's node
2767 * @rbuf: receive buffer
2769 static void i40iw_process_packet(struct i40iw_cm_node *cm_node,
2770 struct i40iw_puda_buf *rbuf)
2772 enum i40iw_tcpip_pkt_type pkt_type = I40IW_PKT_TYPE_UNKNOWN;
2773 struct tcphdr *tcph = (struct tcphdr *)rbuf->tcph;
2774 u32 fin_set = 0;
2775 int ret;
2777 if (tcph->rst) {
2778 pkt_type = I40IW_PKT_TYPE_RST;
2779 } else if (tcph->syn) {
2780 pkt_type = I40IW_PKT_TYPE_SYN;
2781 if (tcph->ack)
2782 pkt_type = I40IW_PKT_TYPE_SYNACK;
2783 } else if (tcph->ack) {
2784 pkt_type = I40IW_PKT_TYPE_ACK;
2786 if (tcph->fin)
2787 fin_set = 1;
2789 switch (pkt_type) {
2790 case I40IW_PKT_TYPE_SYN:
2791 i40iw_handle_syn_pkt(cm_node, rbuf);
2792 break;
2793 case I40IW_PKT_TYPE_SYNACK:
2794 i40iw_handle_synack_pkt(cm_node, rbuf);
2795 break;
2796 case I40IW_PKT_TYPE_ACK:
2797 ret = i40iw_handle_ack_pkt(cm_node, rbuf);
2798 if (fin_set && !ret)
2799 i40iw_handle_fin_pkt(cm_node);
2800 break;
2801 case I40IW_PKT_TYPE_RST:
2802 i40iw_handle_rst_pkt(cm_node, rbuf);
2803 break;
2804 default:
2805 if (fin_set &&
2806 (!i40iw_check_seq(cm_node, (struct tcphdr *)rbuf->tcph)))
2807 i40iw_handle_fin_pkt(cm_node);
2808 break;
2813 * i40iw_make_listen_node - create a listen node with params
2814 * @cm_core: cm's core
2815 * @iwdev: iwarp device structure
2816 * @cm_info: quad info for connection
2818 static struct i40iw_cm_listener *i40iw_make_listen_node(
2819 struct i40iw_cm_core *cm_core,
2820 struct i40iw_device *iwdev,
2821 struct i40iw_cm_info *cm_info)
2823 struct i40iw_cm_listener *listener;
2824 unsigned long flags;
2826 /* cannot have multiple matching listeners */
2827 listener = i40iw_find_listener(cm_core, cm_info->loc_addr,
2828 cm_info->loc_port,
2829 cm_info->vlan_id,
2830 I40IW_CM_LISTENER_EITHER_STATE);
2831 if (listener &&
2832 (listener->listener_state == I40IW_CM_LISTENER_ACTIVE_STATE)) {
2833 atomic_dec(&listener->ref_count);
2834 i40iw_debug(cm_core->dev,
2835 I40IW_DEBUG_CM,
2836 "Not creating listener since it already exists\n");
2837 return NULL;
2840 if (!listener) {
2841 /* create a CM listen node (1/2 node to compare incoming traffic to) */
2842 listener = kzalloc(sizeof(*listener), GFP_ATOMIC);
2843 if (!listener)
2844 return NULL;
2845 cm_core->stats_listen_nodes_created++;
2846 memcpy(listener->loc_addr, cm_info->loc_addr, sizeof(listener->loc_addr));
2847 listener->loc_port = cm_info->loc_port;
2849 INIT_LIST_HEAD(&listener->child_listen_list);
2851 atomic_set(&listener->ref_count, 1);
2852 } else {
2853 listener->reused_node = 1;
2856 listener->cm_id = cm_info->cm_id;
2857 listener->ipv4 = cm_info->ipv4;
2858 listener->vlan_id = cm_info->vlan_id;
2859 atomic_set(&listener->pend_accepts_cnt, 0);
2860 listener->cm_core = cm_core;
2861 listener->iwdev = iwdev;
2863 listener->backlog = cm_info->backlog;
2864 listener->listener_state = I40IW_CM_LISTENER_ACTIVE_STATE;
2866 if (!listener->reused_node) {
2867 spin_lock_irqsave(&cm_core->listen_list_lock, flags);
2868 list_add(&listener->list, &cm_core->listen_nodes);
2869 spin_unlock_irqrestore(&cm_core->listen_list_lock, flags);
2872 return listener;
2876 * i40iw_create_cm_node - make a connection node with params
2877 * @cm_core: cm's core
2878 * @iwdev: iwarp device structure
2879 * @conn_param: upper layer connection parameters
2880 * @cm_info: quad info for connection
2882 static struct i40iw_cm_node *i40iw_create_cm_node(
2883 struct i40iw_cm_core *cm_core,
2884 struct i40iw_device *iwdev,
2885 struct iw_cm_conn_param *conn_param,
2886 struct i40iw_cm_info *cm_info)
2888 struct i40iw_cm_node *cm_node;
2889 struct i40iw_cm_listener *loopback_remotelistener;
2890 struct i40iw_cm_node *loopback_remotenode;
2891 struct i40iw_cm_info loopback_cm_info;
2893 u16 private_data_len = conn_param->private_data_len;
2894 const void *private_data = conn_param->private_data;
2896 /* create a CM connection node */
2897 cm_node = i40iw_make_cm_node(cm_core, iwdev, cm_info, NULL);
2898 if (!cm_node)
2899 return ERR_PTR(-ENOMEM);
2900 /* set our node side to client (active) side */
2901 cm_node->tcp_cntxt.client = 1;
2902 cm_node->tcp_cntxt.rcv_wscale = I40IW_CM_DEFAULT_RCV_WND_SCALE;
2904 i40iw_record_ird_ord(cm_node, conn_param->ird, conn_param->ord);
2906 if (!memcmp(cm_info->loc_addr, cm_info->rem_addr, sizeof(cm_info->loc_addr))) {
2907 loopback_remotelistener = i40iw_find_listener(
2908 cm_core,
2909 cm_info->rem_addr,
2910 cm_node->rem_port,
2911 cm_node->vlan_id,
2912 I40IW_CM_LISTENER_ACTIVE_STATE);
2913 if (!loopback_remotelistener) {
2914 i40iw_rem_ref_cm_node(cm_node);
2915 return ERR_PTR(-ECONNREFUSED);
2916 } else {
2917 loopback_cm_info = *cm_info;
2918 loopback_cm_info.loc_port = cm_info->rem_port;
2919 loopback_cm_info.rem_port = cm_info->loc_port;
2920 loopback_cm_info.cm_id = loopback_remotelistener->cm_id;
2921 loopback_cm_info.ipv4 = cm_info->ipv4;
2922 loopback_remotenode = i40iw_make_cm_node(cm_core,
2923 iwdev,
2924 &loopback_cm_info,
2925 loopback_remotelistener);
2926 if (!loopback_remotenode) {
2927 i40iw_rem_ref_cm_node(cm_node);
2928 return ERR_PTR(-ENOMEM);
2930 cm_core->stats_loopbacks++;
2931 loopback_remotenode->loopbackpartner = cm_node;
2932 loopback_remotenode->tcp_cntxt.rcv_wscale =
2933 I40IW_CM_DEFAULT_RCV_WND_SCALE;
2934 cm_node->loopbackpartner = loopback_remotenode;
2935 memcpy(loopback_remotenode->pdata_buf, private_data,
2936 private_data_len);
2937 loopback_remotenode->pdata.size = private_data_len;
2939 if (loopback_remotenode->ord_size > cm_node->ird_size)
2940 loopback_remotenode->ord_size =
2941 cm_node->ird_size;
2943 cm_node->state = I40IW_CM_STATE_OFFLOADED;
2944 cm_node->tcp_cntxt.rcv_nxt =
2945 loopback_remotenode->tcp_cntxt.loc_seq_num;
2946 loopback_remotenode->tcp_cntxt.rcv_nxt =
2947 cm_node->tcp_cntxt.loc_seq_num;
2948 cm_node->tcp_cntxt.max_snd_wnd =
2949 loopback_remotenode->tcp_cntxt.rcv_wnd;
2950 loopback_remotenode->tcp_cntxt.max_snd_wnd = cm_node->tcp_cntxt.rcv_wnd;
2951 cm_node->tcp_cntxt.snd_wnd = loopback_remotenode->tcp_cntxt.rcv_wnd;
2952 loopback_remotenode->tcp_cntxt.snd_wnd = cm_node->tcp_cntxt.rcv_wnd;
2953 cm_node->tcp_cntxt.snd_wscale = loopback_remotenode->tcp_cntxt.rcv_wscale;
2954 loopback_remotenode->tcp_cntxt.snd_wscale = cm_node->tcp_cntxt.rcv_wscale;
2956 return cm_node;
2959 cm_node->pdata.size = private_data_len;
2960 cm_node->pdata.addr = cm_node->pdata_buf;
2962 memcpy(cm_node->pdata_buf, private_data, private_data_len);
2964 cm_node->state = I40IW_CM_STATE_SYN_SENT;
2965 return cm_node;
2969 * i40iw_cm_reject - reject and teardown a connection
2970 * @cm_node: connection's node
2971 * @pdate: ptr to private data for reject
2972 * @plen: size of private data
2974 static int i40iw_cm_reject(struct i40iw_cm_node *cm_node, const void *pdata, u8 plen)
2976 int ret = 0;
2977 int err;
2978 int passive_state;
2979 struct iw_cm_id *cm_id = cm_node->cm_id;
2980 struct i40iw_cm_node *loopback = cm_node->loopbackpartner;
2982 if (cm_node->tcp_cntxt.client)
2983 return ret;
2984 i40iw_cleanup_retrans_entry(cm_node);
2986 if (!loopback) {
2987 passive_state = atomic_add_return(1, &cm_node->passive_state);
2988 if (passive_state == I40IW_SEND_RESET_EVENT) {
2989 cm_node->state = I40IW_CM_STATE_CLOSED;
2990 i40iw_rem_ref_cm_node(cm_node);
2991 } else {
2992 if (cm_node->state == I40IW_CM_STATE_LISTENER_DESTROYED) {
2993 i40iw_rem_ref_cm_node(cm_node);
2994 } else {
2995 ret = i40iw_send_mpa_reject(cm_node, pdata, plen);
2996 if (ret) {
2997 cm_node->state = I40IW_CM_STATE_CLOSED;
2998 err = i40iw_send_reset(cm_node);
2999 if (err)
3000 i40iw_pr_err("send reset failed\n");
3001 } else {
3002 cm_id->add_ref(cm_id);
3006 } else {
3007 cm_node->cm_id = NULL;
3008 if (cm_node->state == I40IW_CM_STATE_LISTENER_DESTROYED) {
3009 i40iw_rem_ref_cm_node(cm_node);
3010 i40iw_rem_ref_cm_node(loopback);
3011 } else {
3012 ret = i40iw_send_cm_event(loopback,
3013 loopback->cm_id,
3014 IW_CM_EVENT_CONNECT_REPLY,
3015 -ECONNREFUSED);
3016 i40iw_rem_ref_cm_node(cm_node);
3017 loopback->state = I40IW_CM_STATE_CLOSING;
3019 cm_id = loopback->cm_id;
3020 i40iw_rem_ref_cm_node(loopback);
3021 cm_id->rem_ref(cm_id);
3025 return ret;
3029 * i40iw_cm_close - close of cm connection
3030 * @cm_node: connection's node
3032 static int i40iw_cm_close(struct i40iw_cm_node *cm_node)
3034 int ret = 0;
3036 if (!cm_node)
3037 return -EINVAL;
3039 switch (cm_node->state) {
3040 case I40IW_CM_STATE_SYN_RCVD:
3041 case I40IW_CM_STATE_SYN_SENT:
3042 case I40IW_CM_STATE_ONE_SIDE_ESTABLISHED:
3043 case I40IW_CM_STATE_ESTABLISHED:
3044 case I40IW_CM_STATE_ACCEPTING:
3045 case I40IW_CM_STATE_MPAREQ_SENT:
3046 case I40IW_CM_STATE_MPAREQ_RCVD:
3047 i40iw_cleanup_retrans_entry(cm_node);
3048 i40iw_send_reset(cm_node);
3049 break;
3050 case I40IW_CM_STATE_CLOSE_WAIT:
3051 cm_node->state = I40IW_CM_STATE_LAST_ACK;
3052 i40iw_send_fin(cm_node);
3053 break;
3054 case I40IW_CM_STATE_FIN_WAIT1:
3055 case I40IW_CM_STATE_FIN_WAIT2:
3056 case I40IW_CM_STATE_LAST_ACK:
3057 case I40IW_CM_STATE_TIME_WAIT:
3058 case I40IW_CM_STATE_CLOSING:
3059 ret = -1;
3060 break;
3061 case I40IW_CM_STATE_LISTENING:
3062 i40iw_cleanup_retrans_entry(cm_node);
3063 i40iw_send_reset(cm_node);
3064 break;
3065 case I40IW_CM_STATE_MPAREJ_RCVD:
3066 case I40IW_CM_STATE_UNKNOWN:
3067 case I40IW_CM_STATE_INITED:
3068 case I40IW_CM_STATE_CLOSED:
3069 case I40IW_CM_STATE_LISTENER_DESTROYED:
3070 i40iw_rem_ref_cm_node(cm_node);
3071 break;
3072 case I40IW_CM_STATE_OFFLOADED:
3073 if (cm_node->send_entry)
3074 i40iw_pr_err("send_entry\n");
3075 i40iw_rem_ref_cm_node(cm_node);
3076 break;
3078 return ret;
3082 * i40iw_receive_ilq - recv an ETHERNET packet, and process it
3083 * through CM
3084 * @vsi: pointer to the vsi structure
3085 * @rbuf: receive buffer
3087 void i40iw_receive_ilq(struct i40iw_sc_vsi *vsi, struct i40iw_puda_buf *rbuf)
3089 struct i40iw_cm_node *cm_node;
3090 struct i40iw_cm_listener *listener;
3091 struct iphdr *iph;
3092 struct ipv6hdr *ip6h;
3093 struct tcphdr *tcph;
3094 struct i40iw_cm_info cm_info;
3095 struct i40iw_sc_dev *dev = vsi->dev;
3096 struct i40iw_device *iwdev = (struct i40iw_device *)dev->back_dev;
3097 struct i40iw_cm_core *cm_core = &iwdev->cm_core;
3098 struct vlan_ethhdr *ethh;
3099 u16 vtag;
3101 /* if vlan, then maclen = 18 else 14 */
3102 iph = (struct iphdr *)rbuf->iph;
3103 memset(&cm_info, 0, sizeof(cm_info));
3105 i40iw_debug_buf(dev,
3106 I40IW_DEBUG_ILQ,
3107 "RECEIVE ILQ BUFFER",
3108 rbuf->mem.va,
3109 rbuf->totallen);
3110 ethh = (struct vlan_ethhdr *)rbuf->mem.va;
3112 if (ethh->h_vlan_proto == htons(ETH_P_8021Q)) {
3113 vtag = ntohs(ethh->h_vlan_TCI);
3114 cm_info.user_pri = (vtag & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
3115 cm_info.vlan_id = vtag & VLAN_VID_MASK;
3116 i40iw_debug(cm_core->dev,
3117 I40IW_DEBUG_CM,
3118 "%s vlan_id=%d\n",
3119 __func__,
3120 cm_info.vlan_id);
3121 } else {
3122 cm_info.vlan_id = I40IW_NO_VLAN;
3124 tcph = (struct tcphdr *)rbuf->tcph;
3126 if (rbuf->ipv4) {
3127 cm_info.loc_addr[0] = ntohl(iph->daddr);
3128 cm_info.rem_addr[0] = ntohl(iph->saddr);
3129 cm_info.ipv4 = true;
3130 cm_info.tos = iph->tos;
3131 } else {
3132 ip6h = (struct ipv6hdr *)rbuf->iph;
3133 i40iw_copy_ip_ntohl(cm_info.loc_addr,
3134 ip6h->daddr.in6_u.u6_addr32);
3135 i40iw_copy_ip_ntohl(cm_info.rem_addr,
3136 ip6h->saddr.in6_u.u6_addr32);
3137 cm_info.ipv4 = false;
3138 cm_info.tos = (ip6h->priority << 4) | (ip6h->flow_lbl[0] >> 4);
3140 cm_info.loc_port = ntohs(tcph->dest);
3141 cm_info.rem_port = ntohs(tcph->source);
3142 cm_node = i40iw_find_node(cm_core,
3143 cm_info.rem_port,
3144 cm_info.rem_addr,
3145 cm_info.loc_port,
3146 cm_info.loc_addr,
3147 true);
3149 if (!cm_node) {
3150 /* Only type of packet accepted are for */
3151 /* the PASSIVE open (syn only) */
3152 if (!tcph->syn || tcph->ack)
3153 return;
3154 listener =
3155 i40iw_find_listener(cm_core,
3156 cm_info.loc_addr,
3157 cm_info.loc_port,
3158 cm_info.vlan_id,
3159 I40IW_CM_LISTENER_ACTIVE_STATE);
3160 if (!listener) {
3161 cm_info.cm_id = NULL;
3162 i40iw_debug(cm_core->dev,
3163 I40IW_DEBUG_CM,
3164 "%s no listener found\n",
3165 __func__);
3166 return;
3168 cm_info.cm_id = listener->cm_id;
3169 cm_node = i40iw_make_cm_node(cm_core, iwdev, &cm_info, listener);
3170 if (!cm_node) {
3171 i40iw_debug(cm_core->dev,
3172 I40IW_DEBUG_CM,
3173 "%s allocate node failed\n",
3174 __func__);
3175 atomic_dec(&listener->ref_count);
3176 return;
3178 if (!tcph->rst && !tcph->fin) {
3179 cm_node->state = I40IW_CM_STATE_LISTENING;
3180 } else {
3181 i40iw_rem_ref_cm_node(cm_node);
3182 return;
3184 atomic_inc(&cm_node->ref_count);
3185 } else if (cm_node->state == I40IW_CM_STATE_OFFLOADED) {
3186 i40iw_rem_ref_cm_node(cm_node);
3187 return;
3189 i40iw_process_packet(cm_node, rbuf);
3190 i40iw_rem_ref_cm_node(cm_node);
3194 * i40iw_setup_cm_core - allocate a top level instance of a cm
3195 * core
3196 * @iwdev: iwarp device structure
3198 void i40iw_setup_cm_core(struct i40iw_device *iwdev)
3200 struct i40iw_cm_core *cm_core = &iwdev->cm_core;
3202 cm_core->iwdev = iwdev;
3203 cm_core->dev = &iwdev->sc_dev;
3205 INIT_LIST_HEAD(&cm_core->connected_nodes);
3206 INIT_LIST_HEAD(&cm_core->listen_nodes);
3208 timer_setup(&cm_core->tcp_timer, i40iw_cm_timer_tick, 0);
3210 spin_lock_init(&cm_core->ht_lock);
3211 spin_lock_init(&cm_core->listen_list_lock);
3213 cm_core->event_wq = alloc_ordered_workqueue("iwewq",
3214 WQ_MEM_RECLAIM);
3216 cm_core->disconn_wq = alloc_ordered_workqueue("iwdwq",
3217 WQ_MEM_RECLAIM);
3221 * i40iw_cleanup_cm_core - deallocate a top level instance of a
3222 * cm core
3223 * @cm_core: cm's core
3225 void i40iw_cleanup_cm_core(struct i40iw_cm_core *cm_core)
3227 unsigned long flags;
3229 if (!cm_core)
3230 return;
3232 spin_lock_irqsave(&cm_core->ht_lock, flags);
3233 if (timer_pending(&cm_core->tcp_timer))
3234 del_timer_sync(&cm_core->tcp_timer);
3235 spin_unlock_irqrestore(&cm_core->ht_lock, flags);
3237 destroy_workqueue(cm_core->event_wq);
3238 destroy_workqueue(cm_core->disconn_wq);
3242 * i40iw_init_tcp_ctx - setup qp context
3243 * @cm_node: connection's node
3244 * @tcp_info: offload info for tcp
3245 * @iwqp: associate qp for the connection
3247 static void i40iw_init_tcp_ctx(struct i40iw_cm_node *cm_node,
3248 struct i40iw_tcp_offload_info *tcp_info,
3249 struct i40iw_qp *iwqp)
3251 tcp_info->ipv4 = cm_node->ipv4;
3252 tcp_info->drop_ooo_seg = true;
3253 tcp_info->wscale = true;
3254 tcp_info->ignore_tcp_opt = true;
3255 tcp_info->ignore_tcp_uns_opt = true;
3256 tcp_info->no_nagle = false;
3258 tcp_info->ttl = I40IW_DEFAULT_TTL;
3259 tcp_info->rtt_var = cpu_to_le32(I40IW_DEFAULT_RTT_VAR);
3260 tcp_info->ss_thresh = cpu_to_le32(I40IW_DEFAULT_SS_THRESH);
3261 tcp_info->rexmit_thresh = I40IW_DEFAULT_REXMIT_THRESH;
3263 tcp_info->tcp_state = I40IW_TCP_STATE_ESTABLISHED;
3264 tcp_info->snd_wscale = cm_node->tcp_cntxt.snd_wscale;
3265 tcp_info->rcv_wscale = cm_node->tcp_cntxt.rcv_wscale;
3267 tcp_info->snd_nxt = cpu_to_le32(cm_node->tcp_cntxt.loc_seq_num);
3268 tcp_info->snd_wnd = cpu_to_le32(cm_node->tcp_cntxt.snd_wnd);
3269 tcp_info->rcv_nxt = cpu_to_le32(cm_node->tcp_cntxt.rcv_nxt);
3270 tcp_info->snd_max = cpu_to_le32(cm_node->tcp_cntxt.loc_seq_num);
3272 tcp_info->snd_una = cpu_to_le32(cm_node->tcp_cntxt.loc_seq_num);
3273 tcp_info->cwnd = cpu_to_le32(2 * cm_node->tcp_cntxt.mss);
3274 tcp_info->snd_wl1 = cpu_to_le32(cm_node->tcp_cntxt.rcv_nxt);
3275 tcp_info->snd_wl2 = cpu_to_le32(cm_node->tcp_cntxt.loc_seq_num);
3276 tcp_info->max_snd_window = cpu_to_le32(cm_node->tcp_cntxt.max_snd_wnd);
3277 tcp_info->rcv_wnd = cpu_to_le32(cm_node->tcp_cntxt.rcv_wnd <<
3278 cm_node->tcp_cntxt.rcv_wscale);
3280 tcp_info->flow_label = 0;
3281 tcp_info->snd_mss = cpu_to_le32(((u32)cm_node->tcp_cntxt.mss));
3282 if (cm_node->vlan_id < VLAN_TAG_PRESENT) {
3283 tcp_info->insert_vlan_tag = true;
3284 tcp_info->vlan_tag = cpu_to_le16(((u16)cm_node->user_pri << I40IW_VLAN_PRIO_SHIFT) |
3285 cm_node->vlan_id);
3287 if (cm_node->ipv4) {
3288 tcp_info->src_port = cpu_to_le16(cm_node->loc_port);
3289 tcp_info->dst_port = cpu_to_le16(cm_node->rem_port);
3291 tcp_info->dest_ip_addr3 = cpu_to_le32(cm_node->rem_addr[0]);
3292 tcp_info->local_ipaddr3 = cpu_to_le32(cm_node->loc_addr[0]);
3293 tcp_info->arp_idx =
3294 cpu_to_le16((u16)i40iw_arp_table(
3295 iwqp->iwdev,
3296 &tcp_info->dest_ip_addr3,
3297 true,
3298 NULL,
3299 I40IW_ARP_RESOLVE));
3300 } else {
3301 tcp_info->src_port = cpu_to_le16(cm_node->loc_port);
3302 tcp_info->dst_port = cpu_to_le16(cm_node->rem_port);
3303 tcp_info->dest_ip_addr0 = cpu_to_le32(cm_node->rem_addr[0]);
3304 tcp_info->dest_ip_addr1 = cpu_to_le32(cm_node->rem_addr[1]);
3305 tcp_info->dest_ip_addr2 = cpu_to_le32(cm_node->rem_addr[2]);
3306 tcp_info->dest_ip_addr3 = cpu_to_le32(cm_node->rem_addr[3]);
3307 tcp_info->local_ipaddr0 = cpu_to_le32(cm_node->loc_addr[0]);
3308 tcp_info->local_ipaddr1 = cpu_to_le32(cm_node->loc_addr[1]);
3309 tcp_info->local_ipaddr2 = cpu_to_le32(cm_node->loc_addr[2]);
3310 tcp_info->local_ipaddr3 = cpu_to_le32(cm_node->loc_addr[3]);
3311 tcp_info->arp_idx =
3312 cpu_to_le16((u16)i40iw_arp_table(
3313 iwqp->iwdev,
3314 &tcp_info->dest_ip_addr0,
3315 false,
3316 NULL,
3317 I40IW_ARP_RESOLVE));
3322 * i40iw_cm_init_tsa_conn - setup qp for RTS
3323 * @iwqp: associate qp for the connection
3324 * @cm_node: connection's node
3326 static void i40iw_cm_init_tsa_conn(struct i40iw_qp *iwqp,
3327 struct i40iw_cm_node *cm_node)
3329 struct i40iw_tcp_offload_info tcp_info;
3330 struct i40iwarp_offload_info *iwarp_info;
3331 struct i40iw_qp_host_ctx_info *ctx_info;
3332 struct i40iw_device *iwdev = iwqp->iwdev;
3333 struct i40iw_sc_dev *dev = &iwqp->iwdev->sc_dev;
3335 memset(&tcp_info, 0x00, sizeof(struct i40iw_tcp_offload_info));
3336 iwarp_info = &iwqp->iwarp_info;
3337 ctx_info = &iwqp->ctx_info;
3339 ctx_info->tcp_info = &tcp_info;
3340 ctx_info->send_cq_num = iwqp->iwscq->sc_cq.cq_uk.cq_id;
3341 ctx_info->rcv_cq_num = iwqp->iwrcq->sc_cq.cq_uk.cq_id;
3343 iwarp_info->ord_size = cm_node->ord_size;
3344 iwarp_info->ird_size = i40iw_derive_hw_ird_setting(cm_node->ird_size);
3346 if (iwarp_info->ord_size == 1)
3347 iwarp_info->ord_size = 2;
3349 iwarp_info->rd_enable = true;
3350 iwarp_info->rdmap_ver = 1;
3351 iwarp_info->ddp_ver = 1;
3353 iwarp_info->pd_id = iwqp->iwpd->sc_pd.pd_id;
3355 ctx_info->tcp_info_valid = true;
3356 ctx_info->iwarp_info_valid = true;
3357 ctx_info->add_to_qoslist = true;
3358 ctx_info->user_pri = cm_node->user_pri;
3360 i40iw_init_tcp_ctx(cm_node, &tcp_info, iwqp);
3361 if (cm_node->snd_mark_en) {
3362 iwarp_info->snd_mark_en = true;
3363 iwarp_info->snd_mark_offset = (tcp_info.snd_nxt &
3364 SNDMARKER_SEQNMASK) + cm_node->lsmm_size;
3367 cm_node->state = I40IW_CM_STATE_OFFLOADED;
3368 tcp_info.tcp_state = I40IW_TCP_STATE_ESTABLISHED;
3369 tcp_info.src_mac_addr_idx = iwdev->mac_ip_table_idx;
3370 tcp_info.tos = cm_node->tos;
3372 dev->iw_priv_qp_ops->qp_setctx(&iwqp->sc_qp, (u64 *)(iwqp->host_ctx.va), ctx_info);
3374 /* once tcp_info is set, no need to do it again */
3375 ctx_info->tcp_info_valid = false;
3376 ctx_info->iwarp_info_valid = false;
3377 ctx_info->add_to_qoslist = false;
3381 * i40iw_cm_disconn - when a connection is being closed
3382 * @iwqp: associate qp for the connection
3384 void i40iw_cm_disconn(struct i40iw_qp *iwqp)
3386 struct disconn_work *work;
3387 struct i40iw_device *iwdev = iwqp->iwdev;
3388 struct i40iw_cm_core *cm_core = &iwdev->cm_core;
3389 unsigned long flags;
3391 work = kzalloc(sizeof(*work), GFP_ATOMIC);
3392 if (!work)
3393 return; /* Timer will clean up */
3395 spin_lock_irqsave(&iwdev->qptable_lock, flags);
3396 if (!iwdev->qp_table[iwqp->ibqp.qp_num]) {
3397 spin_unlock_irqrestore(&iwdev->qptable_lock, flags);
3398 i40iw_debug(&iwdev->sc_dev, I40IW_DEBUG_CM,
3399 "%s qp_id %d is already freed\n",
3400 __func__, iwqp->ibqp.qp_num);
3401 kfree(work);
3402 return;
3404 i40iw_add_ref(&iwqp->ibqp);
3405 spin_unlock_irqrestore(&iwdev->qptable_lock, flags);
3407 work->iwqp = iwqp;
3408 INIT_WORK(&work->work, i40iw_disconnect_worker);
3409 queue_work(cm_core->disconn_wq, &work->work);
3410 return;
3414 * i40iw_qp_disconnect - free qp and close cm
3415 * @iwqp: associate qp for the connection
3417 static void i40iw_qp_disconnect(struct i40iw_qp *iwqp)
3419 struct i40iw_device *iwdev;
3420 struct i40iw_ib_device *iwibdev;
3422 iwdev = to_iwdev(iwqp->ibqp.device);
3423 if (!iwdev) {
3424 i40iw_pr_err("iwdev == NULL\n");
3425 return;
3428 iwibdev = iwdev->iwibdev;
3430 if (iwqp->active_conn) {
3431 /* indicate this connection is NOT active */
3432 iwqp->active_conn = 0;
3433 } else {
3434 /* Need to free the Last Streaming Mode Message */
3435 if (iwqp->ietf_mem.va) {
3436 if (iwqp->lsmm_mr)
3437 iwibdev->ibdev.dereg_mr(iwqp->lsmm_mr);
3438 i40iw_free_dma_mem(iwdev->sc_dev.hw, &iwqp->ietf_mem);
3442 /* close the CM node down if it is still active */
3443 if (iwqp->cm_node) {
3444 i40iw_debug(&iwdev->sc_dev, I40IW_DEBUG_CM, "%s Call close API\n", __func__);
3445 i40iw_cm_close(iwqp->cm_node);
3450 * i40iw_cm_disconn_true - called by worker thread to disconnect qp
3451 * @iwqp: associate qp for the connection
3453 static void i40iw_cm_disconn_true(struct i40iw_qp *iwqp)
3455 struct iw_cm_id *cm_id;
3456 struct i40iw_device *iwdev;
3457 struct i40iw_sc_qp *qp = &iwqp->sc_qp;
3458 u16 last_ae;
3459 u8 original_hw_tcp_state;
3460 u8 original_ibqp_state;
3461 int disconn_status = 0;
3462 int issue_disconn = 0;
3463 int issue_close = 0;
3464 int issue_flush = 0;
3465 struct ib_event ibevent;
3466 unsigned long flags;
3467 int ret;
3469 if (!iwqp) {
3470 i40iw_pr_err("iwqp == NULL\n");
3471 return;
3474 spin_lock_irqsave(&iwqp->lock, flags);
3475 cm_id = iwqp->cm_id;
3476 /* make sure we havent already closed this connection */
3477 if (!cm_id) {
3478 spin_unlock_irqrestore(&iwqp->lock, flags);
3479 return;
3482 iwdev = to_iwdev(iwqp->ibqp.device);
3484 original_hw_tcp_state = iwqp->hw_tcp_state;
3485 original_ibqp_state = iwqp->ibqp_state;
3486 last_ae = iwqp->last_aeq;
3488 if (qp->term_flags) {
3489 issue_disconn = 1;
3490 issue_close = 1;
3491 iwqp->cm_id = NULL;
3492 /*When term timer expires after cm_timer, don't want
3493 *terminate-handler to issue cm_disconn which can re-free
3494 *a QP even after its refcnt=0.
3496 i40iw_terminate_del_timer(qp);
3497 if (!iwqp->flush_issued) {
3498 iwqp->flush_issued = 1;
3499 issue_flush = 1;
3501 } else if ((original_hw_tcp_state == I40IW_TCP_STATE_CLOSE_WAIT) ||
3502 ((original_ibqp_state == IB_QPS_RTS) &&
3503 (last_ae == I40IW_AE_LLP_CONNECTION_RESET))) {
3504 issue_disconn = 1;
3505 if (last_ae == I40IW_AE_LLP_CONNECTION_RESET)
3506 disconn_status = -ECONNRESET;
3509 if (((original_hw_tcp_state == I40IW_TCP_STATE_CLOSED) ||
3510 (original_hw_tcp_state == I40IW_TCP_STATE_TIME_WAIT) ||
3511 (last_ae == I40IW_AE_RDMAP_ROE_BAD_LLP_CLOSE) ||
3512 (last_ae == I40IW_AE_LLP_CONNECTION_RESET) ||
3513 iwdev->reset)) {
3514 issue_close = 1;
3515 iwqp->cm_id = NULL;
3516 if (!iwqp->flush_issued) {
3517 iwqp->flush_issued = 1;
3518 issue_flush = 1;
3522 spin_unlock_irqrestore(&iwqp->lock, flags);
3523 if (issue_flush && !iwqp->destroyed) {
3524 /* Flush the queues */
3525 i40iw_flush_wqes(iwdev, iwqp);
3527 if (qp->term_flags && iwqp->ibqp.event_handler) {
3528 ibevent.device = iwqp->ibqp.device;
3529 ibevent.event = (qp->eventtype == TERM_EVENT_QP_FATAL) ?
3530 IB_EVENT_QP_FATAL : IB_EVENT_QP_ACCESS_ERR;
3531 ibevent.element.qp = &iwqp->ibqp;
3532 iwqp->ibqp.event_handler(&ibevent, iwqp->ibqp.qp_context);
3536 if (cm_id && cm_id->event_handler) {
3537 if (issue_disconn) {
3538 ret = i40iw_send_cm_event(NULL,
3539 cm_id,
3540 IW_CM_EVENT_DISCONNECT,
3541 disconn_status);
3543 if (ret)
3544 i40iw_debug(&iwdev->sc_dev,
3545 I40IW_DEBUG_CM,
3546 "disconnect event failed %s: - cm_id = %p\n",
3547 __func__, cm_id);
3549 if (issue_close) {
3550 i40iw_qp_disconnect(iwqp);
3551 cm_id->provider_data = iwqp;
3552 ret = i40iw_send_cm_event(NULL, cm_id, IW_CM_EVENT_CLOSE, 0);
3553 if (ret)
3554 i40iw_debug(&iwdev->sc_dev,
3555 I40IW_DEBUG_CM,
3556 "close event failed %s: - cm_id = %p\n",
3557 __func__, cm_id);
3558 cm_id->rem_ref(cm_id);
3564 * i40iw_disconnect_worker - worker for connection close
3565 * @work: points or disconn structure
3567 static void i40iw_disconnect_worker(struct work_struct *work)
3569 struct disconn_work *dwork = container_of(work, struct disconn_work, work);
3570 struct i40iw_qp *iwqp = dwork->iwqp;
3572 kfree(dwork);
3573 i40iw_cm_disconn_true(iwqp);
3574 i40iw_rem_ref(&iwqp->ibqp);
3578 * i40iw_accept - registered call for connection to be accepted
3579 * @cm_id: cm information for passive connection
3580 * @conn_param: accpet parameters
3582 int i40iw_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
3584 struct ib_qp *ibqp;
3585 struct i40iw_qp *iwqp;
3586 struct i40iw_device *iwdev;
3587 struct i40iw_sc_dev *dev;
3588 struct i40iw_cm_node *cm_node;
3589 struct ib_qp_attr attr;
3590 int passive_state;
3591 struct ib_mr *ibmr;
3592 struct i40iw_pd *iwpd;
3593 u16 buf_len = 0;
3594 struct i40iw_kmem_info accept;
3595 enum i40iw_status_code status;
3596 u64 tagged_offset;
3598 memset(&attr, 0, sizeof(attr));
3599 ibqp = i40iw_get_qp(cm_id->device, conn_param->qpn);
3600 if (!ibqp)
3601 return -EINVAL;
3603 iwqp = to_iwqp(ibqp);
3604 iwdev = iwqp->iwdev;
3605 dev = &iwdev->sc_dev;
3606 cm_node = (struct i40iw_cm_node *)cm_id->provider_data;
3608 if (((struct sockaddr_in *)&cm_id->local_addr)->sin_family == AF_INET) {
3609 cm_node->ipv4 = true;
3610 cm_node->vlan_id = i40iw_get_vlan_ipv4(cm_node->loc_addr);
3611 } else {
3612 cm_node->ipv4 = false;
3613 i40iw_netdev_vlan_ipv6(cm_node->loc_addr, &cm_node->vlan_id);
3615 i40iw_debug(cm_node->dev,
3616 I40IW_DEBUG_CM,
3617 "Accept vlan_id=%d\n",
3618 cm_node->vlan_id);
3619 if (cm_node->state == I40IW_CM_STATE_LISTENER_DESTROYED) {
3620 if (cm_node->loopbackpartner)
3621 i40iw_rem_ref_cm_node(cm_node->loopbackpartner);
3622 i40iw_rem_ref_cm_node(cm_node);
3623 return -EINVAL;
3626 passive_state = atomic_add_return(1, &cm_node->passive_state);
3627 if (passive_state == I40IW_SEND_RESET_EVENT) {
3628 i40iw_rem_ref_cm_node(cm_node);
3629 return -ECONNRESET;
3632 cm_node->cm_core->stats_accepts++;
3633 iwqp->cm_node = (void *)cm_node;
3634 cm_node->iwqp = iwqp;
3636 buf_len = conn_param->private_data_len + I40IW_MAX_IETF_SIZE;
3638 status = i40iw_allocate_dma_mem(dev->hw, &iwqp->ietf_mem, buf_len, 1);
3640 if (status)
3641 return -ENOMEM;
3642 cm_node->pdata.size = conn_param->private_data_len;
3643 accept.addr = iwqp->ietf_mem.va;
3644 accept.size = i40iw_cm_build_mpa_frame(cm_node, &accept, MPA_KEY_REPLY);
3645 memcpy(accept.addr + accept.size, conn_param->private_data,
3646 conn_param->private_data_len);
3648 /* setup our first outgoing iWarp send WQE (the IETF frame response) */
3649 if ((cm_node->ipv4 &&
3650 !i40iw_ipv4_is_loopback(cm_node->loc_addr[0], cm_node->rem_addr[0])) ||
3651 (!cm_node->ipv4 &&
3652 !i40iw_ipv6_is_loopback(cm_node->loc_addr, cm_node->rem_addr))) {
3653 iwpd = iwqp->iwpd;
3654 tagged_offset = (uintptr_t)iwqp->ietf_mem.va;
3655 ibmr = i40iw_reg_phys_mr(&iwpd->ibpd,
3656 iwqp->ietf_mem.pa,
3657 buf_len,
3658 IB_ACCESS_LOCAL_WRITE,
3659 &tagged_offset);
3660 if (IS_ERR(ibmr)) {
3661 i40iw_free_dma_mem(dev->hw, &iwqp->ietf_mem);
3662 return -ENOMEM;
3665 ibmr->pd = &iwpd->ibpd;
3666 ibmr->device = iwpd->ibpd.device;
3667 iwqp->lsmm_mr = ibmr;
3668 if (iwqp->page)
3669 iwqp->sc_qp.qp_uk.sq_base = kmap(iwqp->page);
3670 dev->iw_priv_qp_ops->qp_send_lsmm(&iwqp->sc_qp,
3671 iwqp->ietf_mem.va,
3672 (accept.size + conn_param->private_data_len),
3673 ibmr->lkey);
3675 } else {
3676 if (iwqp->page)
3677 iwqp->sc_qp.qp_uk.sq_base = kmap(iwqp->page);
3678 dev->iw_priv_qp_ops->qp_send_lsmm(&iwqp->sc_qp, NULL, 0, 0);
3681 if (iwqp->page)
3682 kunmap(iwqp->page);
3684 iwqp->cm_id = cm_id;
3685 cm_node->cm_id = cm_id;
3687 cm_id->provider_data = (void *)iwqp;
3688 iwqp->active_conn = 0;
3690 cm_node->lsmm_size = accept.size + conn_param->private_data_len;
3691 i40iw_cm_init_tsa_conn(iwqp, cm_node);
3692 cm_id->add_ref(cm_id);
3693 i40iw_add_ref(&iwqp->ibqp);
3695 attr.qp_state = IB_QPS_RTS;
3696 cm_node->qhash_set = false;
3697 i40iw_modify_qp(&iwqp->ibqp, &attr, IB_QP_STATE, NULL);
3699 cm_node->accelerated = true;
3700 status =
3701 i40iw_send_cm_event(cm_node, cm_id, IW_CM_EVENT_ESTABLISHED, 0);
3702 if (status)
3703 i40iw_debug(dev, I40IW_DEBUG_CM, "error sending cm event - ESTABLISHED\n");
3705 if (cm_node->loopbackpartner) {
3706 cm_node->loopbackpartner->pdata.size = conn_param->private_data_len;
3708 /* copy entire MPA frame to our cm_node's frame */
3709 memcpy(cm_node->loopbackpartner->pdata_buf,
3710 conn_param->private_data,
3711 conn_param->private_data_len);
3712 i40iw_create_event(cm_node->loopbackpartner, I40IW_CM_EVENT_CONNECTED);
3715 if (cm_node->accept_pend) {
3716 atomic_dec(&cm_node->listener->pend_accepts_cnt);
3717 cm_node->accept_pend = 0;
3719 return 0;
3723 * i40iw_reject - registered call for connection to be rejected
3724 * @cm_id: cm information for passive connection
3725 * @pdata: private data to be sent
3726 * @pdata_len: private data length
3728 int i40iw_reject(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len)
3730 struct i40iw_device *iwdev;
3731 struct i40iw_cm_node *cm_node;
3732 struct i40iw_cm_node *loopback;
3734 cm_node = (struct i40iw_cm_node *)cm_id->provider_data;
3735 loopback = cm_node->loopbackpartner;
3736 cm_node->cm_id = cm_id;
3737 cm_node->pdata.size = pdata_len;
3739 iwdev = to_iwdev(cm_id->device);
3740 if (!iwdev)
3741 return -EINVAL;
3742 cm_node->cm_core->stats_rejects++;
3744 if (pdata_len + sizeof(struct ietf_mpa_v2) > MAX_CM_BUFFER)
3745 return -EINVAL;
3747 if (loopback) {
3748 memcpy(&loopback->pdata_buf, pdata, pdata_len);
3749 loopback->pdata.size = pdata_len;
3752 return i40iw_cm_reject(cm_node, pdata, pdata_len);
3756 * i40iw_connect - registered call for connection to be established
3757 * @cm_id: cm information for passive connection
3758 * @conn_param: Information about the connection
3760 int i40iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
3762 struct ib_qp *ibqp;
3763 struct i40iw_qp *iwqp;
3764 struct i40iw_device *iwdev;
3765 struct i40iw_cm_node *cm_node;
3766 struct i40iw_cm_info cm_info;
3767 struct sockaddr_in *laddr;
3768 struct sockaddr_in *raddr;
3769 struct sockaddr_in6 *laddr6;
3770 struct sockaddr_in6 *raddr6;
3771 int ret = 0;
3772 unsigned long flags;
3774 ibqp = i40iw_get_qp(cm_id->device, conn_param->qpn);
3775 if (!ibqp)
3776 return -EINVAL;
3777 iwqp = to_iwqp(ibqp);
3778 if (!iwqp)
3779 return -EINVAL;
3780 iwdev = to_iwdev(iwqp->ibqp.device);
3781 if (!iwdev)
3782 return -EINVAL;
3784 laddr = (struct sockaddr_in *)&cm_id->m_local_addr;
3785 raddr = (struct sockaddr_in *)&cm_id->m_remote_addr;
3786 laddr6 = (struct sockaddr_in6 *)&cm_id->m_local_addr;
3787 raddr6 = (struct sockaddr_in6 *)&cm_id->m_remote_addr;
3789 if (!(laddr->sin_port) || !(raddr->sin_port))
3790 return -EINVAL;
3792 iwqp->active_conn = 1;
3793 iwqp->cm_id = NULL;
3794 cm_id->provider_data = iwqp;
3796 /* set up the connection params for the node */
3797 if (cm_id->remote_addr.ss_family == AF_INET) {
3798 cm_info.ipv4 = true;
3799 memset(cm_info.loc_addr, 0, sizeof(cm_info.loc_addr));
3800 memset(cm_info.rem_addr, 0, sizeof(cm_info.rem_addr));
3801 cm_info.loc_addr[0] = ntohl(laddr->sin_addr.s_addr);
3802 cm_info.rem_addr[0] = ntohl(raddr->sin_addr.s_addr);
3803 cm_info.loc_port = ntohs(laddr->sin_port);
3804 cm_info.rem_port = ntohs(raddr->sin_port);
3805 cm_info.vlan_id = i40iw_get_vlan_ipv4(cm_info.loc_addr);
3806 } else {
3807 cm_info.ipv4 = false;
3808 i40iw_copy_ip_ntohl(cm_info.loc_addr,
3809 laddr6->sin6_addr.in6_u.u6_addr32);
3810 i40iw_copy_ip_ntohl(cm_info.rem_addr,
3811 raddr6->sin6_addr.in6_u.u6_addr32);
3812 cm_info.loc_port = ntohs(laddr6->sin6_port);
3813 cm_info.rem_port = ntohs(raddr6->sin6_port);
3814 i40iw_netdev_vlan_ipv6(cm_info.loc_addr, &cm_info.vlan_id);
3816 cm_info.cm_id = cm_id;
3817 cm_info.tos = cm_id->tos;
3818 cm_info.user_pri = rt_tos2priority(cm_id->tos);
3819 i40iw_debug(&iwdev->sc_dev, I40IW_DEBUG_DCB, "%s TOS:[%d] UP:[%d]\n",
3820 __func__, cm_id->tos, cm_info.user_pri);
3821 cm_id->add_ref(cm_id);
3822 cm_node = i40iw_create_cm_node(&iwdev->cm_core, iwdev,
3823 conn_param, &cm_info);
3825 if (IS_ERR(cm_node)) {
3826 ret = PTR_ERR(cm_node);
3827 cm_id->rem_ref(cm_id);
3828 return ret;
3831 if ((cm_info.ipv4 && (laddr->sin_addr.s_addr != raddr->sin_addr.s_addr)) ||
3832 (!cm_info.ipv4 && memcmp(laddr6->sin6_addr.in6_u.u6_addr32,
3833 raddr6->sin6_addr.in6_u.u6_addr32,
3834 sizeof(laddr6->sin6_addr.in6_u.u6_addr32)))) {
3835 if (i40iw_manage_qhash(iwdev, &cm_info, I40IW_QHASH_TYPE_TCP_ESTABLISHED,
3836 I40IW_QHASH_MANAGE_TYPE_ADD, NULL, true)) {
3837 ret = -EINVAL;
3838 goto err;
3840 cm_node->qhash_set = true;
3843 spin_lock_irqsave(&iwdev->cm_core.ht_lock, flags);
3844 if (!test_and_set_bit(cm_info.loc_port, iwdev->cm_core.active_side_ports)) {
3845 spin_unlock_irqrestore(&iwdev->cm_core.ht_lock, flags);
3846 if (i40iw_manage_apbvt(iwdev, cm_info.loc_port, I40IW_MANAGE_APBVT_ADD)) {
3847 ret = -EINVAL;
3848 goto err;
3850 } else {
3851 spin_unlock_irqrestore(&iwdev->cm_core.ht_lock, flags);
3854 cm_node->apbvt_set = true;
3855 iwqp->cm_node = cm_node;
3856 cm_node->iwqp = iwqp;
3857 iwqp->cm_id = cm_id;
3858 i40iw_add_ref(&iwqp->ibqp);
3860 if (cm_node->state != I40IW_CM_STATE_OFFLOADED) {
3861 cm_node->state = I40IW_CM_STATE_SYN_SENT;
3862 ret = i40iw_send_syn(cm_node, 0);
3863 if (ret)
3864 goto err;
3867 if (cm_node->loopbackpartner) {
3868 cm_node->loopbackpartner->state = I40IW_CM_STATE_MPAREQ_RCVD;
3869 i40iw_create_event(cm_node->loopbackpartner,
3870 I40IW_CM_EVENT_MPA_REQ);
3873 i40iw_debug(cm_node->dev,
3874 I40IW_DEBUG_CM,
3875 "Api - connect(): port=0x%04x, cm_node=%p, cm_id = %p.\n",
3876 cm_node->rem_port,
3877 cm_node,
3878 cm_node->cm_id);
3880 return 0;
3882 err:
3883 if (cm_info.ipv4)
3884 i40iw_debug(&iwdev->sc_dev,
3885 I40IW_DEBUG_CM,
3886 "Api - connect() FAILED: dest addr=%pI4",
3887 cm_info.rem_addr);
3888 else
3889 i40iw_debug(&iwdev->sc_dev,
3890 I40IW_DEBUG_CM,
3891 "Api - connect() FAILED: dest addr=%pI6",
3892 cm_info.rem_addr);
3894 i40iw_rem_ref_cm_node(cm_node);
3895 cm_id->rem_ref(cm_id);
3896 iwdev->cm_core.stats_connect_errs++;
3897 return ret;
3901 * i40iw_create_listen - registered call creating listener
3902 * @cm_id: cm information for passive connection
3903 * @backlog: to max accept pending count
3905 int i40iw_create_listen(struct iw_cm_id *cm_id, int backlog)
3907 struct i40iw_device *iwdev;
3908 struct i40iw_cm_listener *cm_listen_node;
3909 struct i40iw_cm_info cm_info;
3910 enum i40iw_status_code ret;
3911 struct sockaddr_in *laddr;
3912 struct sockaddr_in6 *laddr6;
3913 bool wildcard = false;
3915 iwdev = to_iwdev(cm_id->device);
3916 if (!iwdev)
3917 return -EINVAL;
3919 laddr = (struct sockaddr_in *)&cm_id->m_local_addr;
3920 laddr6 = (struct sockaddr_in6 *)&cm_id->m_local_addr;
3921 memset(&cm_info, 0, sizeof(cm_info));
3922 if (laddr->sin_family == AF_INET) {
3923 cm_info.ipv4 = true;
3924 cm_info.loc_addr[0] = ntohl(laddr->sin_addr.s_addr);
3925 cm_info.loc_port = ntohs(laddr->sin_port);
3927 if (laddr->sin_addr.s_addr != INADDR_ANY)
3928 cm_info.vlan_id = i40iw_get_vlan_ipv4(cm_info.loc_addr);
3929 else
3930 wildcard = true;
3932 } else {
3933 cm_info.ipv4 = false;
3934 i40iw_copy_ip_ntohl(cm_info.loc_addr,
3935 laddr6->sin6_addr.in6_u.u6_addr32);
3936 cm_info.loc_port = ntohs(laddr6->sin6_port);
3937 if (ipv6_addr_type(&laddr6->sin6_addr) != IPV6_ADDR_ANY)
3938 i40iw_netdev_vlan_ipv6(cm_info.loc_addr,
3939 &cm_info.vlan_id);
3940 else
3941 wildcard = true;
3943 cm_info.backlog = backlog;
3944 cm_info.cm_id = cm_id;
3946 cm_listen_node = i40iw_make_listen_node(&iwdev->cm_core, iwdev, &cm_info);
3947 if (!cm_listen_node) {
3948 i40iw_pr_err("cm_listen_node == NULL\n");
3949 return -ENOMEM;
3952 cm_id->provider_data = cm_listen_node;
3954 cm_listen_node->tos = cm_id->tos;
3955 cm_listen_node->user_pri = rt_tos2priority(cm_id->tos);
3956 cm_info.user_pri = cm_listen_node->user_pri;
3958 if (!cm_listen_node->reused_node) {
3959 if (wildcard) {
3960 if (cm_info.ipv4)
3961 ret = i40iw_add_mqh_4(iwdev,
3962 &cm_info,
3963 cm_listen_node);
3964 else
3965 ret = i40iw_add_mqh_6(iwdev,
3966 &cm_info,
3967 cm_listen_node);
3968 if (ret)
3969 goto error;
3971 ret = i40iw_manage_apbvt(iwdev,
3972 cm_info.loc_port,
3973 I40IW_MANAGE_APBVT_ADD);
3975 if (ret)
3976 goto error;
3977 } else {
3978 ret = i40iw_manage_qhash(iwdev,
3979 &cm_info,
3980 I40IW_QHASH_TYPE_TCP_SYN,
3981 I40IW_QHASH_MANAGE_TYPE_ADD,
3982 NULL,
3983 true);
3984 if (ret)
3985 goto error;
3986 cm_listen_node->qhash_set = true;
3987 ret = i40iw_manage_apbvt(iwdev,
3988 cm_info.loc_port,
3989 I40IW_MANAGE_APBVT_ADD);
3990 if (ret)
3991 goto error;
3994 cm_id->add_ref(cm_id);
3995 cm_listen_node->cm_core->stats_listen_created++;
3996 return 0;
3997 error:
3998 i40iw_cm_del_listen(&iwdev->cm_core, (void *)cm_listen_node, false);
3999 return -EINVAL;
4003 * i40iw_destroy_listen - registered call to destroy listener
4004 * @cm_id: cm information for passive connection
4006 int i40iw_destroy_listen(struct iw_cm_id *cm_id)
4008 struct i40iw_device *iwdev;
4010 iwdev = to_iwdev(cm_id->device);
4011 if (cm_id->provider_data)
4012 i40iw_cm_del_listen(&iwdev->cm_core, cm_id->provider_data, true);
4013 else
4014 i40iw_pr_err("cm_id->provider_data was NULL\n");
4016 cm_id->rem_ref(cm_id);
4018 return 0;
4022 * i40iw_cm_event_connected - handle connected active node
4023 * @event: the info for cm_node of connection
4025 static void i40iw_cm_event_connected(struct i40iw_cm_event *event)
4027 struct i40iw_qp *iwqp;
4028 struct i40iw_device *iwdev;
4029 struct i40iw_cm_node *cm_node;
4030 struct i40iw_sc_dev *dev;
4031 struct ib_qp_attr attr;
4032 struct iw_cm_id *cm_id;
4033 int status;
4034 bool read0;
4036 cm_node = event->cm_node;
4037 cm_id = cm_node->cm_id;
4038 iwqp = (struct i40iw_qp *)cm_id->provider_data;
4039 iwdev = to_iwdev(iwqp->ibqp.device);
4040 dev = &iwdev->sc_dev;
4042 if (iwqp->destroyed) {
4043 status = -ETIMEDOUT;
4044 goto error;
4046 i40iw_cm_init_tsa_conn(iwqp, cm_node);
4047 read0 = (cm_node->send_rdma0_op == SEND_RDMA_READ_ZERO);
4048 if (iwqp->page)
4049 iwqp->sc_qp.qp_uk.sq_base = kmap(iwqp->page);
4050 dev->iw_priv_qp_ops->qp_send_rtt(&iwqp->sc_qp, read0);
4051 if (iwqp->page)
4052 kunmap(iwqp->page);
4054 memset(&attr, 0, sizeof(attr));
4055 attr.qp_state = IB_QPS_RTS;
4056 cm_node->qhash_set = false;
4057 i40iw_modify_qp(&iwqp->ibqp, &attr, IB_QP_STATE, NULL);
4059 cm_node->accelerated = true;
4060 status = i40iw_send_cm_event(cm_node, cm_id, IW_CM_EVENT_CONNECT_REPLY,
4062 if (status)
4063 i40iw_debug(dev, I40IW_DEBUG_CM, "error sending cm event - CONNECT_REPLY\n");
4065 return;
4067 error:
4068 iwqp->cm_id = NULL;
4069 cm_id->provider_data = NULL;
4070 i40iw_send_cm_event(event->cm_node,
4071 cm_id,
4072 IW_CM_EVENT_CONNECT_REPLY,
4073 status);
4074 cm_id->rem_ref(cm_id);
4075 i40iw_rem_ref_cm_node(event->cm_node);
4079 * i40iw_cm_event_reset - handle reset
4080 * @event: the info for cm_node of connection
4082 static void i40iw_cm_event_reset(struct i40iw_cm_event *event)
4084 struct i40iw_cm_node *cm_node = event->cm_node;
4085 struct iw_cm_id *cm_id = cm_node->cm_id;
4086 struct i40iw_qp *iwqp;
4088 if (!cm_id)
4089 return;
4091 iwqp = cm_id->provider_data;
4092 if (!iwqp)
4093 return;
4095 i40iw_debug(cm_node->dev,
4096 I40IW_DEBUG_CM,
4097 "reset event %p - cm_id = %p\n",
4098 event->cm_node, cm_id);
4099 iwqp->cm_id = NULL;
4101 i40iw_send_cm_event(cm_node, cm_node->cm_id, IW_CM_EVENT_DISCONNECT, -ECONNRESET);
4102 i40iw_send_cm_event(cm_node, cm_node->cm_id, IW_CM_EVENT_CLOSE, 0);
4106 * i40iw_cm_event_handler - worker thread callback to send event to cm upper layer
4107 * @work: pointer of cm event info.
4109 static void i40iw_cm_event_handler(struct work_struct *work)
4111 struct i40iw_cm_event *event = container_of(work,
4112 struct i40iw_cm_event,
4113 event_work);
4114 struct i40iw_cm_node *cm_node;
4116 if (!event || !event->cm_node || !event->cm_node->cm_core)
4117 return;
4119 cm_node = event->cm_node;
4121 switch (event->type) {
4122 case I40IW_CM_EVENT_MPA_REQ:
4123 i40iw_send_cm_event(cm_node,
4124 cm_node->cm_id,
4125 IW_CM_EVENT_CONNECT_REQUEST,
4127 break;
4128 case I40IW_CM_EVENT_RESET:
4129 i40iw_cm_event_reset(event);
4130 break;
4131 case I40IW_CM_EVENT_CONNECTED:
4132 if (!event->cm_node->cm_id ||
4133 (event->cm_node->state != I40IW_CM_STATE_OFFLOADED))
4134 break;
4135 i40iw_cm_event_connected(event);
4136 break;
4137 case I40IW_CM_EVENT_MPA_REJECT:
4138 if (!event->cm_node->cm_id ||
4139 (cm_node->state == I40IW_CM_STATE_OFFLOADED))
4140 break;
4141 i40iw_send_cm_event(cm_node,
4142 cm_node->cm_id,
4143 IW_CM_EVENT_CONNECT_REPLY,
4144 -ECONNREFUSED);
4145 break;
4146 case I40IW_CM_EVENT_ABORTED:
4147 if (!event->cm_node->cm_id ||
4148 (event->cm_node->state == I40IW_CM_STATE_OFFLOADED))
4149 break;
4150 i40iw_event_connect_error(event);
4151 break;
4152 default:
4153 i40iw_pr_err("event type = %d\n", event->type);
4154 break;
4157 event->cm_info.cm_id->rem_ref(event->cm_info.cm_id);
4158 i40iw_rem_ref_cm_node(event->cm_node);
4159 kfree(event);
4163 * i40iw_cm_post_event - queue event request for worker thread
4164 * @event: cm node's info for up event call
4166 static void i40iw_cm_post_event(struct i40iw_cm_event *event)
4168 atomic_inc(&event->cm_node->ref_count);
4169 event->cm_info.cm_id->add_ref(event->cm_info.cm_id);
4170 INIT_WORK(&event->event_work, i40iw_cm_event_handler);
4172 queue_work(event->cm_node->cm_core->event_wq, &event->event_work);
4176 * i40iw_qhash_ctrl - enable/disable qhash for list
4177 * @iwdev: device pointer
4178 * @parent_listen_node: parent listen node
4179 * @nfo: cm info node
4180 * @ipaddr: Pointer to IPv4 or IPv6 address
4181 * @ipv4: flag indicating IPv4 when true
4182 * @ifup: flag indicating interface up when true
4184 * Enables or disables the qhash for the node in the child
4185 * listen list that matches ipaddr. If no matching IP was found
4186 * it will allocate and add a new child listen node to the
4187 * parent listen node. The listen_list_lock is assumed to be
4188 * held when called.
4190 static void i40iw_qhash_ctrl(struct i40iw_device *iwdev,
4191 struct i40iw_cm_listener *parent_listen_node,
4192 struct i40iw_cm_info *nfo,
4193 u32 *ipaddr, bool ipv4, bool ifup)
4195 struct list_head *child_listen_list = &parent_listen_node->child_listen_list;
4196 struct i40iw_cm_listener *child_listen_node;
4197 struct list_head *pos, *tpos;
4198 enum i40iw_status_code ret;
4199 bool node_allocated = false;
4200 enum i40iw_quad_hash_manage_type op =
4201 ifup ? I40IW_QHASH_MANAGE_TYPE_ADD : I40IW_QHASH_MANAGE_TYPE_DELETE;
4203 list_for_each_safe(pos, tpos, child_listen_list) {
4204 child_listen_node =
4205 list_entry(pos,
4206 struct i40iw_cm_listener,
4207 child_listen_list);
4208 if (!memcmp(child_listen_node->loc_addr, ipaddr, ipv4 ? 4 : 16))
4209 goto set_qhash;
4212 /* if not found then add a child listener if interface is going up */
4213 if (!ifup)
4214 return;
4215 child_listen_node = kzalloc(sizeof(*child_listen_node), GFP_ATOMIC);
4216 if (!child_listen_node)
4217 return;
4218 node_allocated = true;
4219 memcpy(child_listen_node, parent_listen_node, sizeof(*child_listen_node));
4221 memcpy(child_listen_node->loc_addr, ipaddr, ipv4 ? 4 : 16);
4223 set_qhash:
4224 memcpy(nfo->loc_addr,
4225 child_listen_node->loc_addr,
4226 sizeof(nfo->loc_addr));
4227 nfo->vlan_id = child_listen_node->vlan_id;
4228 ret = i40iw_manage_qhash(iwdev, nfo,
4229 I40IW_QHASH_TYPE_TCP_SYN,
4231 NULL, false);
4232 if (!ret) {
4233 child_listen_node->qhash_set = ifup;
4234 if (node_allocated)
4235 list_add(&child_listen_node->child_listen_list,
4236 &parent_listen_node->child_listen_list);
4237 } else if (node_allocated) {
4238 kfree(child_listen_node);
4243 * i40iw_cm_teardown_connections - teardown QPs
4244 * @iwdev: device pointer
4245 * @ipaddr: Pointer to IPv4 or IPv6 address
4246 * @ipv4: flag indicating IPv4 when true
4247 * @disconnect_all: flag indicating disconnect all QPs
4248 * teardown QPs where source or destination addr matches ip addr
4250 void i40iw_cm_teardown_connections(struct i40iw_device *iwdev, u32 *ipaddr,
4251 struct i40iw_cm_info *nfo,
4252 bool disconnect_all)
4254 struct i40iw_cm_core *cm_core = &iwdev->cm_core;
4255 struct list_head *list_core_temp;
4256 struct list_head *list_node;
4257 struct i40iw_cm_node *cm_node;
4258 unsigned long flags;
4259 struct list_head connected_list;
4260 struct ib_qp_attr attr;
4262 INIT_LIST_HEAD(&connected_list);
4263 spin_lock_irqsave(&cm_core->ht_lock, flags);
4264 list_for_each_safe(list_node, list_core_temp, &cm_core->connected_nodes) {
4265 cm_node = container_of(list_node, struct i40iw_cm_node, list);
4266 if (disconnect_all ||
4267 (nfo->vlan_id == cm_node->vlan_id &&
4268 (!memcmp(cm_node->loc_addr, ipaddr, nfo->ipv4 ? 4 : 16) ||
4269 !memcmp(cm_node->rem_addr, ipaddr, nfo->ipv4 ? 4 : 16)))) {
4270 atomic_inc(&cm_node->ref_count);
4271 list_add(&cm_node->connected_entry, &connected_list);
4274 spin_unlock_irqrestore(&cm_core->ht_lock, flags);
4276 list_for_each_safe(list_node, list_core_temp, &connected_list) {
4277 cm_node = container_of(list_node, struct i40iw_cm_node, connected_entry);
4278 attr.qp_state = IB_QPS_ERR;
4279 i40iw_modify_qp(&cm_node->iwqp->ibqp, &attr, IB_QP_STATE, NULL);
4280 if (iwdev->reset)
4281 i40iw_cm_disconn(cm_node->iwqp);
4282 i40iw_rem_ref_cm_node(cm_node);
4287 * i40iw_ifdown_notify - process an ifdown on an interface
4288 * @iwdev: device pointer
4289 * @ipaddr: Pointer to IPv4 or IPv6 address
4290 * @ipv4: flag indicating IPv4 when true
4291 * @ifup: flag indicating interface up when true
4293 void i40iw_if_notify(struct i40iw_device *iwdev, struct net_device *netdev,
4294 u32 *ipaddr, bool ipv4, bool ifup)
4296 struct i40iw_cm_core *cm_core = &iwdev->cm_core;
4297 unsigned long flags;
4298 struct i40iw_cm_listener *listen_node;
4299 static const u32 ip_zero[4] = { 0, 0, 0, 0 };
4300 struct i40iw_cm_info nfo;
4301 u16 vlan_id = rdma_vlan_dev_vlan_id(netdev);
4302 enum i40iw_status_code ret;
4303 enum i40iw_quad_hash_manage_type op =
4304 ifup ? I40IW_QHASH_MANAGE_TYPE_ADD : I40IW_QHASH_MANAGE_TYPE_DELETE;
4306 nfo.vlan_id = vlan_id;
4307 nfo.ipv4 = ipv4;
4309 /* Disable or enable qhash for listeners */
4310 spin_lock_irqsave(&cm_core->listen_list_lock, flags);
4311 list_for_each_entry(listen_node, &cm_core->listen_nodes, list) {
4312 if (vlan_id == listen_node->vlan_id &&
4313 (!memcmp(listen_node->loc_addr, ipaddr, ipv4 ? 4 : 16) ||
4314 !memcmp(listen_node->loc_addr, ip_zero, ipv4 ? 4 : 16))) {
4315 memcpy(nfo.loc_addr, listen_node->loc_addr,
4316 sizeof(nfo.loc_addr));
4317 nfo.loc_port = listen_node->loc_port;
4318 nfo.user_pri = listen_node->user_pri;
4319 if (!list_empty(&listen_node->child_listen_list)) {
4320 i40iw_qhash_ctrl(iwdev,
4321 listen_node,
4322 &nfo,
4323 ipaddr, ipv4, ifup);
4324 } else if (memcmp(listen_node->loc_addr, ip_zero,
4325 ipv4 ? 4 : 16)) {
4326 ret = i40iw_manage_qhash(iwdev,
4327 &nfo,
4328 I40IW_QHASH_TYPE_TCP_SYN,
4330 NULL,
4331 false);
4332 if (!ret)
4333 listen_node->qhash_set = ifup;
4337 spin_unlock_irqrestore(&cm_core->listen_list_lock, flags);
4339 /* teardown connected qp's on ifdown */
4340 if (!ifup)
4341 i40iw_cm_teardown_connections(iwdev, ipaddr, &nfo, false);