2 * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35 #define TCPOPT_TIMESTAMP 8
37 #include <asm/atomic.h>
38 #include <linux/skbuff.h>
40 #include <linux/tcp.h>
41 #include <linux/init.h>
42 #include <linux/if_arp.h>
43 #include <linux/if_vlan.h>
44 #include <linux/notifier.h>
45 #include <linux/net.h>
46 #include <linux/types.h>
47 #include <linux/timer.h>
48 #include <linux/time.h>
49 #include <linux/delay.h>
50 #include <linux/etherdevice.h>
51 #include <linux/netdevice.h>
52 #include <linux/random.h>
53 #include <linux/list.h>
54 #include <linux/threads.h>
56 #include <net/neighbour.h>
57 #include <net/route.h>
58 #include <net/ip_fib.h>
63 u32 cm_packets_bounced
;
64 u32 cm_packets_dropped
;
65 u32 cm_packets_retrans
;
66 u32 cm_packets_created
;
67 u32 cm_packets_received
;
68 u32 cm_listens_created
;
69 u32 cm_listens_destroyed
;
71 atomic_t cm_loopbacks
;
72 atomic_t cm_nodes_created
;
73 atomic_t cm_nodes_destroyed
;
74 atomic_t cm_accel_dropped_pkts
;
75 atomic_t cm_resets_recvd
;
77 static inline int mini_cm_accelerated(struct nes_cm_core
*, struct nes_cm_node
*);
78 static struct nes_cm_listener
*mini_cm_listen(struct nes_cm_core
*,
79 struct nes_vnic
*, struct nes_cm_info
*);
80 static int add_ref_cm_node(struct nes_cm_node
*);
81 static int rem_ref_cm_node(struct nes_cm_core
*, struct nes_cm_node
*);
82 static int mini_cm_del_listen(struct nes_cm_core
*, struct nes_cm_listener
*);
83 static struct sk_buff
*form_cm_frame(struct sk_buff
*, struct nes_cm_node
*,
84 void *, u32
, void *, u32
, u8
);
85 static struct sk_buff
*get_free_pkt(struct nes_cm_node
*cm_node
);
87 static struct nes_cm_node
*mini_cm_connect(struct nes_cm_core
*,
89 struct ietf_mpa_frame
*,
90 struct nes_cm_info
*);
91 static int mini_cm_accept(struct nes_cm_core
*, struct ietf_mpa_frame
*,
92 struct nes_cm_node
*);
93 static int mini_cm_reject(struct nes_cm_core
*, struct ietf_mpa_frame
*,
94 struct nes_cm_node
*);
95 static int mini_cm_close(struct nes_cm_core
*, struct nes_cm_node
*);
96 static int mini_cm_recv_pkt(struct nes_cm_core
*, struct nes_vnic
*,
98 static int mini_cm_dealloc_core(struct nes_cm_core
*);
99 static int mini_cm_get(struct nes_cm_core
*);
100 static int mini_cm_set(struct nes_cm_core
*, u32
, u32
);
101 static int nes_cm_disconn_true(struct nes_qp
*);
102 static int nes_cm_post_event(struct nes_cm_event
*event
);
103 static int nes_disconnect(struct nes_qp
*nesqp
, int abrupt
);
104 static void nes_disconnect_worker(struct work_struct
*work
);
105 static int send_ack(struct nes_cm_node
*cm_node
);
106 static int send_fin(struct nes_cm_node
*cm_node
, struct sk_buff
*skb
);
108 /* External CM API Interface */
109 /* instance of function pointers for client API */
110 /* set address of this instance to cm_core->cm_ops at cm_core alloc */
111 static struct nes_cm_ops nes_cm_api
= {
120 mini_cm_dealloc_core
,
125 static struct nes_cm_core
*g_cm_core
;
127 atomic_t cm_connects
;
129 atomic_t cm_disconnects
;
131 atomic_t cm_connecteds
;
132 atomic_t cm_connect_reqs
;
139 static struct nes_cm_event
*create_event(struct nes_cm_node
*cm_node
,
140 enum nes_cm_event_type type
)
142 struct nes_cm_event
*event
;
147 /* allocate an empty event */
148 event
= kzalloc(sizeof(*event
), GFP_ATOMIC
);
154 event
->cm_node
= cm_node
;
155 event
->cm_info
.rem_addr
= cm_node
->rem_addr
;
156 event
->cm_info
.loc_addr
= cm_node
->loc_addr
;
157 event
->cm_info
.rem_port
= cm_node
->rem_port
;
158 event
->cm_info
.loc_port
= cm_node
->loc_port
;
159 event
->cm_info
.cm_id
= cm_node
->cm_id
;
161 nes_debug(NES_DBG_CM
, "Created event=%p, type=%u, dst_addr=%08x[%x],"
162 " src_addr=%08x[%x]\n",
164 event
->cm_info
.loc_addr
, event
->cm_info
.loc_port
,
165 event
->cm_info
.rem_addr
, event
->cm_info
.rem_port
);
167 nes_cm_post_event(event
);
175 static int send_mpa_request(struct nes_cm_node
*cm_node
)
180 skb
= get_free_pkt(cm_node
);
182 nes_debug(NES_DBG_CM
, "Failed to get a Free pkt\n");
186 /* send an MPA Request frame */
187 form_cm_frame(skb
, cm_node
, NULL
, 0, &cm_node
->mpa_frame
,
188 cm_node
->mpa_frame_size
, SET_ACK
);
190 ret
= schedule_nes_timer(cm_node
, skb
, NES_TIMER_TYPE_SEND
, 1, 0);
200 * recv_mpa - process a received TCP pkt, we are expecting an
203 static int parse_mpa(struct nes_cm_node
*cm_node
, u8
*buffer
, u32 len
)
205 struct ietf_mpa_frame
*mpa_frame
;
207 /* assume req frame is in tcp data payload */
208 if (len
< sizeof(struct ietf_mpa_frame
)) {
209 nes_debug(NES_DBG_CM
, "The received ietf buffer was too small (%x)\n", len
);
213 mpa_frame
= (struct ietf_mpa_frame
*)buffer
;
214 cm_node
->mpa_frame_size
= ntohs(mpa_frame
->priv_data_len
);
216 if (cm_node
->mpa_frame_size
+ sizeof(struct ietf_mpa_frame
) != len
) {
217 nes_debug(NES_DBG_CM
, "The received ietf buffer was not right"
218 " complete (%x + %x != %x)\n",
219 cm_node
->mpa_frame_size
, (u32
)sizeof(struct ietf_mpa_frame
), len
);
223 /* copy entire MPA frame to our cm_node's frame */
224 memcpy(cm_node
->mpa_frame_buf
, buffer
+ sizeof(struct ietf_mpa_frame
),
225 cm_node
->mpa_frame_size
);
232 * handle_exception_pkt - process an exception packet.
233 * We have been in a TSA state, and we have now received SW
234 * TCP/IP traffic should be a FIN request or IP pkt with options
236 static int handle_exception_pkt(struct nes_cm_node
*cm_node
, struct sk_buff
*skb
)
239 struct tcphdr
*tcph
= tcp_hdr(skb
);
241 /* first check to see if this a FIN pkt */
243 /* we need to ACK the FIN request */
246 /* check which side we are (client/server) and set next state accordingly */
247 if (cm_node
->tcp_cntxt
.client
)
248 cm_node
->state
= NES_CM_STATE_CLOSING
;
250 /* we are the server side */
251 cm_node
->state
= NES_CM_STATE_CLOSE_WAIT
;
252 /* since this is a self contained CM we don't wait for */
253 /* an APP to close us, just send final FIN immediately */
254 ret
= send_fin(cm_node
, NULL
);
255 cm_node
->state
= NES_CM_STATE_LAST_ACK
;
266 * form_cm_frame - get a free packet and build empty frame Use
267 * node info to build.
269 static struct sk_buff
*form_cm_frame(struct sk_buff
*skb
, struct nes_cm_node
*cm_node
,
270 void *options
, u32 optionsize
, void *data
,
271 u32 datasize
, u8 flags
)
277 u16 packetsize
= sizeof(*iph
);
279 packetsize
+= sizeof(*tcph
);
280 packetsize
+= optionsize
+ datasize
;
282 memset(skb
->data
, 0x00, ETH_HLEN
+ sizeof(*iph
) + sizeof(*tcph
));
285 buf
= skb_put(skb
, packetsize
+ ETH_HLEN
);
287 ethh
= (struct ethhdr
*) buf
;
290 iph
= (struct iphdr
*)buf
;
292 tcph
= (struct tcphdr
*)buf
;
293 skb_reset_mac_header(skb
);
294 skb_set_network_header(skb
, ETH_HLEN
);
295 skb_set_transport_header(skb
, ETH_HLEN
+sizeof(*iph
));
296 buf
+= sizeof(*tcph
);
298 skb
->ip_summed
= CHECKSUM_PARTIAL
;
299 skb
->protocol
= htons(0x800);
301 skb
->mac_len
= ETH_HLEN
;
303 memcpy(ethh
->h_dest
, cm_node
->rem_mac
, ETH_ALEN
);
304 memcpy(ethh
->h_source
, cm_node
->loc_mac
, ETH_ALEN
);
305 ethh
->h_proto
= htons(0x0800);
307 iph
->version
= IPVERSION
;
308 iph
->ihl
= 5; /* 5 * 4Byte words, IP headr len */
310 iph
->tot_len
= htons(packetsize
);
311 iph
->id
= htons(++cm_node
->tcp_cntxt
.loc_id
);
313 iph
->frag_off
= htons(0x4000);
315 iph
->protocol
= 0x06; /* IPPROTO_TCP */
317 iph
->saddr
= htonl(cm_node
->loc_addr
);
318 iph
->daddr
= htonl(cm_node
->rem_addr
);
320 tcph
->source
= htons(cm_node
->loc_port
);
321 tcph
->dest
= htons(cm_node
->rem_port
);
322 tcph
->seq
= htonl(cm_node
->tcp_cntxt
.loc_seq_num
);
324 if (flags
& SET_ACK
) {
325 cm_node
->tcp_cntxt
.loc_ack_num
= cm_node
->tcp_cntxt
.rcv_nxt
;
326 tcph
->ack_seq
= htonl(cm_node
->tcp_cntxt
.loc_ack_num
);
331 if (flags
& SET_SYN
) {
332 cm_node
->tcp_cntxt
.loc_seq_num
++;
335 cm_node
->tcp_cntxt
.loc_seq_num
+= datasize
; /* data (no headers) */
343 tcph
->doff
= (u16
)((sizeof(*tcph
) + optionsize
+ 3) >> 2);
344 tcph
->window
= htons(cm_node
->tcp_cntxt
.rcv_wnd
);
347 memcpy(buf
, options
, optionsize
);
350 memcpy(buf
, data
, datasize
);
352 skb_shinfo(skb
)->nr_frags
= 0;
353 cm_packets_created
++;
360 * print_core - dump a cm core
362 static void print_core(struct nes_cm_core
*core
)
364 nes_debug(NES_DBG_CM
, "---------------------------------------------\n");
365 nes_debug(NES_DBG_CM
, "CM Core -- (core = %p )\n", core
);
368 nes_debug(NES_DBG_CM
, "---------------------------------------------\n");
369 nes_debug(NES_DBG_CM
, "Session ID : %u \n", atomic_read(&core
->session_id
));
371 nes_debug(NES_DBG_CM
, "State : %u \n", core
->state
);
373 nes_debug(NES_DBG_CM
, "Tx Free cnt : %u \n", skb_queue_len(&core
->tx_free_list
));
374 nes_debug(NES_DBG_CM
, "Listen Nodes : %u \n", atomic_read(&core
->listen_node_cnt
));
375 nes_debug(NES_DBG_CM
, "Active Nodes : %u \n", atomic_read(&core
->node_cnt
));
377 nes_debug(NES_DBG_CM
, "core : %p \n", core
);
379 nes_debug(NES_DBG_CM
, "-------------- end core ---------------\n");
385 * note - cm_node needs to be protected before calling this. Encase in:
386 * rem_ref_cm_node(cm_core, cm_node);add_ref_cm_node(cm_node);
388 int schedule_nes_timer(struct nes_cm_node
*cm_node
, struct sk_buff
*skb
,
389 enum nes_timer_type type
, int send_retrans
,
390 int close_when_complete
)
393 struct nes_cm_core
*cm_core
;
394 struct nes_timer_entry
*new_send
;
400 new_send
= kzalloc(sizeof(*new_send
), GFP_ATOMIC
);
404 /* new_send->timetosend = currenttime */
405 new_send
->retrycount
= NES_DEFAULT_RETRYS
;
406 new_send
->retranscount
= NES_DEFAULT_RETRANS
;
408 new_send
->timetosend
= jiffies
;
409 new_send
->type
= type
;
410 new_send
->netdev
= cm_node
->netdev
;
411 new_send
->send_retrans
= send_retrans
;
412 new_send
->close_when_complete
= close_when_complete
;
414 if (type
== NES_TIMER_TYPE_CLOSE
) {
415 new_send
->timetosend
+= (HZ
/2); /* TODO: decide on the correct value here */
416 spin_lock_irqsave(&cm_node
->recv_list_lock
, flags
);
417 list_add_tail(&new_send
->list
, &cm_node
->recv_list
);
418 spin_unlock_irqrestore(&cm_node
->recv_list_lock
, flags
);
421 if (type
== NES_TIMER_TYPE_SEND
) {
422 new_send
->seq_num
= ntohl(tcp_hdr(skb
)->seq
);
423 atomic_inc(&new_send
->skb
->users
);
425 ret
= nes_nic_cm_xmit(new_send
->skb
, cm_node
->netdev
);
426 if (ret
!= NETDEV_TX_OK
) {
427 nes_debug(NES_DBG_CM
, "Error sending packet %p (jiffies = %lu)\n",
429 atomic_dec(&new_send
->skb
->users
);
430 new_send
->timetosend
= jiffies
;
434 if (close_when_complete
)
435 rem_ref_cm_node(cm_node
->cm_core
, cm_node
);
436 dev_kfree_skb_any(new_send
->skb
);
440 new_send
->timetosend
= jiffies
+ NES_RETRY_TIMEOUT
;
442 spin_lock_irqsave(&cm_node
->retrans_list_lock
, flags
);
443 list_add_tail(&new_send
->list
, &cm_node
->retrans_list
);
444 spin_unlock_irqrestore(&cm_node
->retrans_list_lock
, flags
);
446 if (type
== NES_TIMER_TYPE_RECV
) {
447 new_send
->seq_num
= ntohl(tcp_hdr(skb
)->seq
);
448 new_send
->timetosend
= jiffies
;
449 spin_lock_irqsave(&cm_node
->recv_list_lock
, flags
);
450 list_add_tail(&new_send
->list
, &cm_node
->recv_list
);
451 spin_unlock_irqrestore(&cm_node
->recv_list_lock
, flags
);
453 cm_core
= cm_node
->cm_core
;
455 was_timer_set
= timer_pending(&cm_core
->tcp_timer
);
457 if (!was_timer_set
) {
458 cm_core
->tcp_timer
.expires
= new_send
->timetosend
;
459 add_timer(&cm_core
->tcp_timer
);
469 static void nes_cm_timer_tick(unsigned long pass
)
471 unsigned long flags
, qplockflags
;
472 unsigned long nexttimeout
= jiffies
+ NES_LONG_TIME
;
473 struct iw_cm_id
*cm_id
;
474 struct nes_cm_node
*cm_node
;
475 struct nes_timer_entry
*send_entry
, *recv_entry
;
476 struct list_head
*list_core
, *list_core_temp
;
477 struct list_head
*list_node
, *list_node_temp
;
478 struct nes_cm_core
*cm_core
= g_cm_core
;
479 struct nes_qp
*nesqp
;
482 int ret
= NETDEV_TX_OK
;
485 spin_lock_irqsave(&cm_core
->ht_lock
, flags
);
487 list_for_each_safe(list_node
, list_core_temp
, &cm_core
->connected_nodes
) {
488 cm_node
= container_of(list_node
, struct nes_cm_node
, list
);
489 add_ref_cm_node(cm_node
);
490 spin_unlock_irqrestore(&cm_core
->ht_lock
, flags
);
491 spin_lock_irqsave(&cm_node
->recv_list_lock
, flags
);
492 list_for_each_safe(list_core
, list_node_temp
, &cm_node
->recv_list
) {
493 recv_entry
= container_of(list_core
, struct nes_timer_entry
, list
);
494 if ((time_after(recv_entry
->timetosend
, jiffies
)) &&
495 (recv_entry
->type
== NES_TIMER_TYPE_CLOSE
)) {
496 if (nexttimeout
> recv_entry
->timetosend
|| !settimer
) {
497 nexttimeout
= recv_entry
->timetosend
;
502 list_del(&recv_entry
->list
);
503 cm_id
= cm_node
->cm_id
;
504 spin_unlock_irqrestore(&cm_node
->recv_list_lock
, flags
);
505 if (recv_entry
->type
== NES_TIMER_TYPE_CLOSE
) {
506 nesqp
= (struct nes_qp
*)recv_entry
->skb
;
507 spin_lock_irqsave(&nesqp
->lock
, qplockflags
);
509 nes_debug(NES_DBG_CM
, "QP%u: cm_id = %p, refcount = %d: "
510 "****** HIT A NES_TIMER_TYPE_CLOSE"
511 " with something to do!!! ******\n",
512 nesqp
->hwqp
.qp_id
, cm_id
,
513 atomic_read(&nesqp
->refcount
));
514 nesqp
->hw_tcp_state
= NES_AEQE_TCP_STATE_CLOSED
;
515 nesqp
->last_aeq
= NES_AEQE_AEID_RESET_SENT
;
516 nesqp
->ibqp_state
= IB_QPS_ERR
;
517 spin_unlock_irqrestore(&nesqp
->lock
, qplockflags
);
518 nes_cm_disconn(nesqp
);
520 spin_unlock_irqrestore(&nesqp
->lock
, qplockflags
);
521 nes_debug(NES_DBG_CM
, "QP%u: cm_id = %p, refcount = %d:"
522 " ****** HIT A NES_TIMER_TYPE_CLOSE"
523 " with nothing to do!!! ******\n",
524 nesqp
->hwqp
.qp_id
, cm_id
,
525 atomic_read(&nesqp
->refcount
));
526 nes_rem_ref(&nesqp
->ibqp
);
529 cm_id
->rem_ref(cm_id
);
532 spin_lock_irqsave(&cm_node
->recv_list_lock
, flags
);
534 spin_unlock_irqrestore(&cm_node
->recv_list_lock
, flags
);
536 spin_lock_irqsave(&cm_node
->retrans_list_lock
, flags
);
538 list_for_each_safe(list_core
, list_node_temp
, &cm_node
->retrans_list
) {
542 send_entry
= container_of(list_core
, struct nes_timer_entry
, list
);
543 if (time_after(send_entry
->timetosend
, jiffies
)) {
544 if (cm_node
->state
!= NES_CM_STATE_TSA
) {
545 if ((nexttimeout
> send_entry
->timetosend
) || !settimer
) {
546 nexttimeout
= send_entry
->timetosend
;
552 list_del(&send_entry
->list
);
553 skb
= send_entry
->skb
;
554 spin_unlock_irqrestore(&cm_node
->retrans_list_lock
, flags
);
555 dev_kfree_skb_any(skb
);
557 spin_lock_irqsave(&cm_node
->retrans_list_lock
, flags
);
561 if (send_entry
->type
== NES_TIMER_NODE_CLEANUP
) {
562 list_del(&send_entry
->list
);
563 spin_unlock_irqrestore(&cm_node
->retrans_list_lock
, flags
);
565 spin_lock_irqsave(&cm_node
->retrans_list_lock
, flags
);
568 if ((send_entry
->seq_num
< cm_node
->tcp_cntxt
.rem_ack_num
) ||
569 (cm_node
->state
== NES_CM_STATE_TSA
) ||
570 (cm_node
->state
== NES_CM_STATE_CLOSED
)) {
571 skb
= send_entry
->skb
;
572 list_del(&send_entry
->list
);
573 spin_unlock_irqrestore(&cm_node
->retrans_list_lock
, flags
);
575 dev_kfree_skb_any(skb
);
576 spin_lock_irqsave(&cm_node
->retrans_list_lock
, flags
);
580 if (!send_entry
->retranscount
|| !send_entry
->retrycount
) {
581 cm_packets_dropped
++;
582 skb
= send_entry
->skb
;
583 list_del(&send_entry
->list
);
584 spin_unlock_irqrestore(&cm_node
->retrans_list_lock
, flags
);
585 dev_kfree_skb_any(skb
);
587 if (cm_node
->state
== NES_CM_STATE_SYN_RCVD
) {
588 /* this node never even generated an indication up to the cm */
589 rem_ref_cm_node(cm_core
, cm_node
);
591 cm_node
->state
= NES_CM_STATE_CLOSED
;
592 create_event(cm_node
, NES_CM_EVENT_ABORTED
);
594 spin_lock_irqsave(&cm_node
->retrans_list_lock
, flags
);
597 /* this seems like the correct place, but leave send entry unprotected */
598 // spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags);
599 atomic_inc(&send_entry
->skb
->users
);
600 cm_packets_retrans
++;
601 nes_debug(NES_DBG_CM
, "Retransmitting send_entry %p for node %p,"
602 " jiffies = %lu, time to send = %lu, retranscount = %u, "
603 "send_entry->seq_num = 0x%08X, cm_node->tcp_cntxt.rem_ack_num = 0x%08X\n",
604 send_entry
, cm_node
, jiffies
, send_entry
->timetosend
, send_entry
->retranscount
,
605 send_entry
->seq_num
, cm_node
->tcp_cntxt
.rem_ack_num
);
607 spin_unlock_irqrestore(&cm_node
->retrans_list_lock
, flags
);
608 ret
= nes_nic_cm_xmit(send_entry
->skb
, cm_node
->netdev
);
609 if (ret
!= NETDEV_TX_OK
) {
610 cm_packets_bounced
++;
611 atomic_dec(&send_entry
->skb
->users
);
612 send_entry
->retrycount
--;
613 nexttimeout
= jiffies
+ NES_SHORT_TIME
;
616 spin_lock_irqsave(&cm_node
->retrans_list_lock
, flags
);
621 spin_lock_irqsave(&cm_node
->retrans_list_lock
, flags
);
622 list_del(&send_entry
->list
);
623 nes_debug(NES_DBG_CM
, "Packet Sent: retrans count = %u, retry count = %u.\n",
624 send_entry
->retranscount
, send_entry
->retrycount
);
625 if (send_entry
->send_retrans
) {
626 send_entry
->retranscount
--;
627 send_entry
->timetosend
= jiffies
+ NES_RETRY_TIMEOUT
;
628 if (nexttimeout
> send_entry
->timetosend
|| !settimer
) {
629 nexttimeout
= send_entry
->timetosend
;
632 list_add(&send_entry
->list
, &cm_node
->retrans_list
);
635 int close_when_complete
;
636 skb
= send_entry
->skb
;
637 close_when_complete
= send_entry
->close_when_complete
;
638 spin_unlock_irqrestore(&cm_node
->retrans_list_lock
, flags
);
639 if (close_when_complete
) {
640 BUG_ON(atomic_read(&cm_node
->ref_count
) == 1);
641 rem_ref_cm_node(cm_core
, cm_node
);
643 dev_kfree_skb_any(skb
);
645 spin_lock_irqsave(&cm_node
->retrans_list_lock
, flags
);
649 spin_unlock_irqrestore(&cm_node
->retrans_list_lock
, flags
);
651 rem_ref_cm_node(cm_core
, cm_node
);
653 spin_lock_irqsave(&cm_core
->ht_lock
, flags
);
654 if (ret
!= NETDEV_TX_OK
)
657 spin_unlock_irqrestore(&cm_core
->ht_lock
, flags
);
660 if (!timer_pending(&cm_core
->tcp_timer
)) {
661 cm_core
->tcp_timer
.expires
= nexttimeout
;
662 add_timer(&cm_core
->tcp_timer
);
671 static int send_syn(struct nes_cm_node
*cm_node
, u32 sendack
)
676 char optionsbuffer
[sizeof(struct option_mss
) +
677 sizeof(struct option_windowscale
) +
678 sizeof(struct option_base
) + 1];
681 /* Sending MSS option */
682 union all_known_options
*options
;
687 options
= (union all_known_options
*)&optionsbuffer
[optionssize
];
688 options
->as_mss
.optionnum
= OPTION_NUMBER_MSS
;
689 options
->as_mss
.length
= sizeof(struct option_mss
);
690 options
->as_mss
.mss
= htons(cm_node
->tcp_cntxt
.mss
);
691 optionssize
+= sizeof(struct option_mss
);
693 options
= (union all_known_options
*)&optionsbuffer
[optionssize
];
694 options
->as_windowscale
.optionnum
= OPTION_NUMBER_WINDOW_SCALE
;
695 options
->as_windowscale
.length
= sizeof(struct option_windowscale
);
696 options
->as_windowscale
.shiftcount
= cm_node
->tcp_cntxt
.rcv_wscale
;
697 optionssize
+= sizeof(struct option_windowscale
);
699 if (sendack
&& !(NES_DRV_OPT_SUPRESS_OPTION_BC
& nes_drv_opt
)
701 options
= (union all_known_options
*)&optionsbuffer
[optionssize
];
702 options
->as_base
.optionnum
= OPTION_NUMBER_WRITE0
;
703 options
->as_base
.length
= sizeof(struct option_base
);
704 optionssize
+= sizeof(struct option_base
);
705 /* we need the size to be a multiple of 4 */
706 options
= (union all_known_options
*)&optionsbuffer
[optionssize
];
709 options
= (union all_known_options
*)&optionsbuffer
[optionssize
];
714 options
= (union all_known_options
*)&optionsbuffer
[optionssize
];
715 options
->as_end
= OPTION_NUMBER_END
;
718 skb
= get_free_pkt(cm_node
);
720 nes_debug(NES_DBG_CM
, "Failed to get a Free pkt\n");
727 form_cm_frame(skb
, cm_node
, optionsbuffer
, optionssize
, NULL
, 0, flags
);
728 ret
= schedule_nes_timer(cm_node
, skb
, NES_TIMER_TYPE_SEND
, 1, 0);
737 static int send_reset(struct nes_cm_node
*cm_node
)
740 struct sk_buff
*skb
= get_free_pkt(cm_node
);
741 int flags
= SET_RST
| SET_ACK
;
744 nes_debug(NES_DBG_CM
, "Failed to get a Free pkt\n");
748 add_ref_cm_node(cm_node
);
749 form_cm_frame(skb
, cm_node
, NULL
, 0, NULL
, 0, flags
);
750 ret
= schedule_nes_timer(cm_node
, skb
, NES_TIMER_TYPE_SEND
, 0, 1);
759 static int send_ack(struct nes_cm_node
*cm_node
)
762 struct sk_buff
*skb
= get_free_pkt(cm_node
);
765 nes_debug(NES_DBG_CM
, "Failed to get a Free pkt\n");
769 form_cm_frame(skb
, cm_node
, NULL
, 0, NULL
, 0, SET_ACK
);
770 ret
= schedule_nes_timer(cm_node
, skb
, NES_TIMER_TYPE_SEND
, 0, 0);
779 static int send_fin(struct nes_cm_node
*cm_node
, struct sk_buff
*skb
)
783 /* if we didn't get a frame get one */
785 skb
= get_free_pkt(cm_node
);
788 nes_debug(NES_DBG_CM
, "Failed to get a Free pkt\n");
792 form_cm_frame(skb
, cm_node
, NULL
, 0, NULL
, 0, SET_ACK
| SET_FIN
);
793 ret
= schedule_nes_timer(cm_node
, skb
, NES_TIMER_TYPE_SEND
, 1, 0);
802 static struct sk_buff
*get_free_pkt(struct nes_cm_node
*cm_node
)
804 struct sk_buff
*skb
, *new_skb
;
806 /* check to see if we need to repopulate the free tx pkt queue */
807 if (skb_queue_len(&cm_node
->cm_core
->tx_free_list
) < NES_CM_FREE_PKT_LO_WATERMARK
) {
808 while (skb_queue_len(&cm_node
->cm_core
->tx_free_list
) <
809 cm_node
->cm_core
->free_tx_pkt_max
) {
810 /* replace the frame we took, we won't get it back */
811 new_skb
= dev_alloc_skb(cm_node
->cm_core
->mtu
);
813 /* add a replacement frame to the free tx list head */
814 skb_queue_head(&cm_node
->cm_core
->tx_free_list
, new_skb
);
818 skb
= skb_dequeue(&cm_node
->cm_core
->tx_free_list
);
825 * make_hashkey - generate hash key from node tuple
827 static inline int make_hashkey(u16 loc_port
, nes_addr_t loc_addr
, u16 rem_port
,
832 hashkey
= loc_addr
+ rem_addr
+ loc_port
+ rem_port
;
833 hashkey
= (hashkey
% NES_CM_HASHTABLE_SIZE
);
840 * find_node - find a cm node that matches the reference cm node
842 static struct nes_cm_node
*find_node(struct nes_cm_core
*cm_core
,
843 u16 rem_port
, nes_addr_t rem_addr
, u16 loc_port
, nes_addr_t loc_addr
)
847 struct list_head
*list_pos
;
848 struct list_head
*hte
;
849 struct nes_cm_node
*cm_node
;
851 /* make a hash index key for this packet */
852 hashkey
= make_hashkey(loc_port
, loc_addr
, rem_port
, rem_addr
);
854 /* get a handle on the hte */
855 hte
= &cm_core
->connected_nodes
;
857 nes_debug(NES_DBG_CM
, "Searching for an owner node:%x:%x from core %p->%p\n",
858 loc_addr
, loc_port
, cm_core
, hte
);
860 /* walk list and find cm_node associated with this session ID */
861 spin_lock_irqsave(&cm_core
->ht_lock
, flags
);
862 list_for_each(list_pos
, hte
) {
863 cm_node
= container_of(list_pos
, struct nes_cm_node
, list
);
864 /* compare quad, return node handle if a match */
865 nes_debug(NES_DBG_CM
, "finding node %x:%x =? %x:%x ^ %x:%x =? %x:%x\n",
866 cm_node
->loc_addr
, cm_node
->loc_port
,
868 cm_node
->rem_addr
, cm_node
->rem_port
,
870 if ((cm_node
->loc_addr
== loc_addr
) && (cm_node
->loc_port
== loc_port
) &&
871 (cm_node
->rem_addr
== rem_addr
) && (cm_node
->rem_port
== rem_port
)) {
872 add_ref_cm_node(cm_node
);
873 spin_unlock_irqrestore(&cm_core
->ht_lock
, flags
);
877 spin_unlock_irqrestore(&cm_core
->ht_lock
, flags
);
885 * find_listener - find a cm node listening on this addr-port pair
887 static struct nes_cm_listener
*find_listener(struct nes_cm_core
*cm_core
,
888 nes_addr_t dst_addr
, u16 dst_port
, enum nes_cm_listener_state listener_state
)
891 struct list_head
*listen_list
;
892 struct nes_cm_listener
*listen_node
;
894 /* walk list and find cm_node associated with this session ID */
895 spin_lock_irqsave(&cm_core
->listen_list_lock
, flags
);
896 list_for_each(listen_list
, &cm_core
->listen_list
.list
) {
897 listen_node
= container_of(listen_list
, struct nes_cm_listener
, list
);
898 /* compare node pair, return node handle if a match */
899 if (((listen_node
->loc_addr
== dst_addr
) ||
900 listen_node
->loc_addr
== 0x00000000) &&
901 (listen_node
->loc_port
== dst_port
) &&
902 (listener_state
& listen_node
->listener_state
)) {
903 atomic_inc(&listen_node
->ref_count
);
904 spin_unlock_irqrestore(&cm_core
->listen_list_lock
, flags
);
908 spin_unlock_irqrestore(&cm_core
->listen_list_lock
, flags
);
910 nes_debug(NES_DBG_CM
, "Unable to find listener- %x:%x\n",
919 * add_hte_node - add a cm node to the hash table
921 static int add_hte_node(struct nes_cm_core
*cm_core
, struct nes_cm_node
*cm_node
)
925 struct list_head
*hte
;
927 if (!cm_node
|| !cm_core
)
930 nes_debug(NES_DBG_CM
, "Adding Node to Active Connection HT\n");
932 /* first, make an index into our hash table */
933 hashkey
= make_hashkey(cm_node
->loc_port
, cm_node
->loc_addr
,
934 cm_node
->rem_port
, cm_node
->rem_addr
);
935 cm_node
->hashkey
= hashkey
;
937 spin_lock_irqsave(&cm_core
->ht_lock
, flags
);
939 /* get a handle on the hash table element (list head for this slot) */
940 hte
= &cm_core
->connected_nodes
;
941 list_add_tail(&cm_node
->list
, hte
);
942 atomic_inc(&cm_core
->ht_node_cnt
);
944 spin_unlock_irqrestore(&cm_core
->ht_lock
, flags
);
951 * mini_cm_dec_refcnt_listen
953 static int mini_cm_dec_refcnt_listen(struct nes_cm_core
*cm_core
,
954 struct nes_cm_listener
*listener
, int free_hanging_nodes
)
958 spin_lock_irqsave(&cm_core
->listen_list_lock
, flags
);
959 if (!atomic_dec_return(&listener
->ref_count
)) {
960 list_del(&listener
->list
);
962 /* decrement our listen node count */
963 atomic_dec(&cm_core
->listen_node_cnt
);
965 spin_unlock_irqrestore(&cm_core
->listen_list_lock
, flags
);
967 if (listener
->nesvnic
) {
968 nes_manage_apbvt(listener
->nesvnic
, listener
->loc_port
,
969 PCI_FUNC(listener
->nesvnic
->nesdev
->pcidev
->devfn
), NES_MANAGE_APBVT_DEL
);
972 nes_debug(NES_DBG_CM
, "destroying listener (%p)\n", listener
);
977 cm_listens_destroyed
++;
979 spin_unlock_irqrestore(&cm_core
->listen_list_lock
, flags
);
982 if (atomic_read(&listener
->pend_accepts_cnt
) > 0)
983 nes_debug(NES_DBG_CM
, "destroying listener (%p)"
984 " with non-zero pending accepts=%u\n",
985 listener
, atomic_read(&listener
->pend_accepts_cnt
));
995 static int mini_cm_del_listen(struct nes_cm_core
*cm_core
,
996 struct nes_cm_listener
*listener
)
998 listener
->listener_state
= NES_CM_LISTENER_PASSIVE_STATE
;
999 listener
->cm_id
= NULL
; /* going to be destroyed pretty soon */
1000 return mini_cm_dec_refcnt_listen(cm_core
, listener
, 1);
1005 * mini_cm_accelerated
1007 static inline int mini_cm_accelerated(struct nes_cm_core
*cm_core
,
1008 struct nes_cm_node
*cm_node
)
1011 cm_node
->accelerated
= 1;
1013 if (cm_node
->accept_pend
) {
1014 BUG_ON(!cm_node
->listener
);
1015 atomic_dec(&cm_node
->listener
->pend_accepts_cnt
);
1016 BUG_ON(atomic_read(&cm_node
->listener
->pend_accepts_cnt
) < 0);
1019 was_timer_set
= timer_pending(&cm_core
->tcp_timer
);
1020 if (!was_timer_set
) {
1021 cm_core
->tcp_timer
.expires
= jiffies
+ NES_SHORT_TIME
;
1022 add_timer(&cm_core
->tcp_timer
);
1032 static void nes_addr_send_arp(u32 dst_ip
)
1037 memset(&fl
, 0, sizeof fl
);
1038 fl
.nl_u
.ip4_u
.daddr
= htonl(dst_ip
);
1039 if (ip_route_output_key(&init_net
, &rt
, &fl
)) {
1040 printk("%s: ip_route_output_key failed for 0x%08X\n",
1041 __FUNCTION__
, dst_ip
);
1045 neigh_event_send(rt
->u
.dst
.neighbour
, NULL
);
1051 * make_cm_node - create a new instance of a cm node
1053 static struct nes_cm_node
*make_cm_node(struct nes_cm_core
*cm_core
,
1054 struct nes_vnic
*nesvnic
, struct nes_cm_info
*cm_info
,
1055 struct nes_cm_listener
*listener
)
1057 struct nes_cm_node
*cm_node
;
1060 struct nes_device
*nesdev
;
1061 struct nes_adapter
*nesadapter
;
1063 /* create an hte and cm_node for this instance */
1064 cm_node
= kzalloc(sizeof(*cm_node
), GFP_ATOMIC
);
1068 /* set our node specific transport info */
1069 cm_node
->loc_addr
= cm_info
->loc_addr
;
1070 cm_node
->rem_addr
= cm_info
->rem_addr
;
1071 cm_node
->loc_port
= cm_info
->loc_port
;
1072 cm_node
->rem_port
= cm_info
->rem_port
;
1073 cm_node
->send_write0
= send_first
;
1074 nes_debug(NES_DBG_CM
, "Make node addresses : loc = %x:%x, rem = %x:%x\n",
1075 cm_node
->loc_addr
, cm_node
->loc_port
, cm_node
->rem_addr
, cm_node
->rem_port
);
1076 cm_node
->listener
= listener
;
1077 cm_node
->netdev
= nesvnic
->netdev
;
1078 cm_node
->cm_id
= cm_info
->cm_id
;
1079 memcpy(cm_node
->loc_mac
, nesvnic
->netdev
->dev_addr
, ETH_ALEN
);
1081 nes_debug(NES_DBG_CM
, "listener=%p, cm_id=%p\n",
1082 cm_node
->listener
, cm_node
->cm_id
);
1084 INIT_LIST_HEAD(&cm_node
->retrans_list
);
1085 spin_lock_init(&cm_node
->retrans_list_lock
);
1086 INIT_LIST_HEAD(&cm_node
->recv_list
);
1087 spin_lock_init(&cm_node
->recv_list_lock
);
1089 cm_node
->loopbackpartner
= NULL
;
1090 atomic_set(&cm_node
->ref_count
, 1);
1091 /* associate our parent CM core */
1092 cm_node
->cm_core
= cm_core
;
1093 cm_node
->tcp_cntxt
.loc_id
= NES_CM_DEF_LOCAL_ID
;
1094 cm_node
->tcp_cntxt
.rcv_wscale
= NES_CM_DEFAULT_RCV_WND_SCALE
;
1095 cm_node
->tcp_cntxt
.rcv_wnd
= NES_CM_DEFAULT_RCV_WND_SCALED
>>
1096 NES_CM_DEFAULT_RCV_WND_SCALE
;
1097 ts
= current_kernel_time();
1098 cm_node
->tcp_cntxt
.loc_seq_num
= htonl(ts
.tv_nsec
);
1099 cm_node
->tcp_cntxt
.mss
= nesvnic
->max_frame_size
- sizeof(struct iphdr
) -
1100 sizeof(struct tcphdr
) - ETH_HLEN
- VLAN_HLEN
;
1101 cm_node
->tcp_cntxt
.rcv_nxt
= 0;
1102 /* get a unique session ID , add thread_id to an upcounter to handle race */
1103 atomic_inc(&cm_core
->node_cnt
);
1104 atomic_inc(&cm_core
->session_id
);
1105 cm_node
->session_id
= (u32
)(atomic_read(&cm_core
->session_id
) + current
->tgid
);
1106 cm_node
->conn_type
= cm_info
->conn_type
;
1107 cm_node
->apbvt_set
= 0;
1108 cm_node
->accept_pend
= 0;
1110 cm_node
->nesvnic
= nesvnic
;
1111 /* get some device handles, for arp lookup */
1112 nesdev
= nesvnic
->nesdev
;
1113 nesadapter
= nesdev
->nesadapter
;
1115 cm_node
->loopbackpartner
= NULL
;
1116 /* get the mac addr for the remote node */
1117 arpindex
= nes_arp_table(nesdev
, cm_node
->rem_addr
, NULL
, NES_ARP_RESOLVE
);
1120 nes_addr_send_arp(cm_info
->rem_addr
);
1124 /* copy the mac addr to node context */
1125 memcpy(cm_node
->rem_mac
, nesadapter
->arp_table
[arpindex
].mac_addr
, ETH_ALEN
);
1126 nes_debug(NES_DBG_CM
, "Remote mac addr from arp table:%02x,"
1127 " %02x, %02x, %02x, %02x, %02x\n",
1128 cm_node
->rem_mac
[0], cm_node
->rem_mac
[1],
1129 cm_node
->rem_mac
[2], cm_node
->rem_mac
[3],
1130 cm_node
->rem_mac
[4], cm_node
->rem_mac
[5]);
1132 add_hte_node(cm_core
, cm_node
);
1133 atomic_inc(&cm_nodes_created
);
1140 * add_ref_cm_node - destroy an instance of a cm node
1142 static int add_ref_cm_node(struct nes_cm_node
*cm_node
)
1144 atomic_inc(&cm_node
->ref_count
);
1150 * rem_ref_cm_node - destroy an instance of a cm node
1152 static int rem_ref_cm_node(struct nes_cm_core
*cm_core
,
1153 struct nes_cm_node
*cm_node
)
1155 unsigned long flags
, qplockflags
;
1156 struct nes_timer_entry
*send_entry
;
1157 struct nes_timer_entry
*recv_entry
;
1158 struct iw_cm_id
*cm_id
;
1159 struct list_head
*list_core
, *list_node_temp
;
1160 struct nes_qp
*nesqp
;
1165 spin_lock_irqsave(&cm_node
->cm_core
->ht_lock
, flags
);
1166 if (atomic_dec_return(&cm_node
->ref_count
)) {
1167 spin_unlock_irqrestore(&cm_node
->cm_core
->ht_lock
, flags
);
1170 list_del(&cm_node
->list
);
1171 atomic_dec(&cm_core
->ht_node_cnt
);
1172 spin_unlock_irqrestore(&cm_node
->cm_core
->ht_lock
, flags
);
1174 /* if the node is destroyed before connection was accelerated */
1175 if (!cm_node
->accelerated
&& cm_node
->accept_pend
) {
1176 BUG_ON(!cm_node
->listener
);
1177 atomic_dec(&cm_node
->listener
->pend_accepts_cnt
);
1178 BUG_ON(atomic_read(&cm_node
->listener
->pend_accepts_cnt
) < 0);
1181 spin_lock_irqsave(&cm_node
->retrans_list_lock
, flags
);
1182 list_for_each_safe(list_core
, list_node_temp
, &cm_node
->retrans_list
) {
1183 send_entry
= container_of(list_core
, struct nes_timer_entry
, list
);
1184 list_del(&send_entry
->list
);
1185 spin_unlock_irqrestore(&cm_node
->retrans_list_lock
, flags
);
1186 dev_kfree_skb_any(send_entry
->skb
);
1188 spin_lock_irqsave(&cm_node
->retrans_list_lock
, flags
);
1191 spin_unlock_irqrestore(&cm_node
->retrans_list_lock
, flags
);
1193 spin_lock_irqsave(&cm_node
->recv_list_lock
, flags
);
1194 list_for_each_safe(list_core
, list_node_temp
, &cm_node
->recv_list
) {
1195 recv_entry
= container_of(list_core
, struct nes_timer_entry
, list
);
1196 list_del(&recv_entry
->list
);
1197 cm_id
= cm_node
->cm_id
;
1198 spin_unlock_irqrestore(&cm_node
->recv_list_lock
, flags
);
1199 if (recv_entry
->type
== NES_TIMER_TYPE_CLOSE
) {
1200 nesqp
= (struct nes_qp
*)recv_entry
->skb
;
1201 spin_lock_irqsave(&nesqp
->lock
, qplockflags
);
1203 nes_debug(NES_DBG_CM
, "QP%u: cm_id = %p: ****** HIT A NES_TIMER_TYPE_CLOSE"
1204 " with something to do!!! ******\n",
1205 nesqp
->hwqp
.qp_id
, cm_id
);
1206 nesqp
->hw_tcp_state
= NES_AEQE_TCP_STATE_CLOSED
;
1207 nesqp
->last_aeq
= NES_AEQE_AEID_RESET_SENT
;
1208 nesqp
->ibqp_state
= IB_QPS_ERR
;
1209 spin_unlock_irqrestore(&nesqp
->lock
, qplockflags
);
1210 nes_cm_disconn(nesqp
);
1212 spin_unlock_irqrestore(&nesqp
->lock
, qplockflags
);
1213 nes_debug(NES_DBG_CM
, "QP%u: cm_id = %p: ****** HIT A NES_TIMER_TYPE_CLOSE"
1214 " with nothing to do!!! ******\n",
1215 nesqp
->hwqp
.qp_id
, cm_id
);
1216 nes_rem_ref(&nesqp
->ibqp
);
1218 cm_id
->rem_ref(cm_id
);
1219 } else if (recv_entry
->type
== NES_TIMER_TYPE_RECV
) {
1220 dev_kfree_skb_any(recv_entry
->skb
);
1223 spin_lock_irqsave(&cm_node
->recv_list_lock
, flags
);
1225 spin_unlock_irqrestore(&cm_node
->recv_list_lock
, flags
);
1227 if (cm_node
->listener
) {
1228 mini_cm_dec_refcnt_listen(cm_core
, cm_node
->listener
, 0);
1230 if (cm_node
->apbvt_set
&& cm_node
->nesvnic
) {
1231 nes_manage_apbvt(cm_node
->nesvnic
, cm_node
->loc_port
,
1232 PCI_FUNC(cm_node
->nesvnic
->nesdev
->pcidev
->devfn
),
1233 NES_MANAGE_APBVT_DEL
);
1238 atomic_dec(&cm_core
->node_cnt
);
1239 atomic_inc(&cm_nodes_destroyed
);
1248 static int process_options(struct nes_cm_node
*cm_node
, u8
*optionsloc
, u32 optionsize
, u32 syn_packet
)
1252 union all_known_options
*all_options
;
1253 char got_mss_option
= 0;
1255 while (offset
< optionsize
) {
1256 all_options
= (union all_known_options
*)(optionsloc
+ offset
);
1257 switch (all_options
->as_base
.optionnum
) {
1258 case OPTION_NUMBER_END
:
1259 offset
= optionsize
;
1261 case OPTION_NUMBER_NONE
:
1264 case OPTION_NUMBER_MSS
:
1265 nes_debug(NES_DBG_CM
, "%s: MSS Length: %d Offset: %d Size: %d\n",
1267 all_options
->as_mss
.length
, offset
, optionsize
);
1269 if (all_options
->as_mss
.length
!= 4) {
1272 tmp
= ntohs(all_options
->as_mss
.mss
);
1273 if (tmp
> 0 && tmp
< cm_node
->tcp_cntxt
.mss
)
1274 cm_node
->tcp_cntxt
.mss
= tmp
;
1277 case OPTION_NUMBER_WINDOW_SCALE
:
1278 cm_node
->tcp_cntxt
.snd_wscale
= all_options
->as_windowscale
.shiftcount
;
1280 case OPTION_NUMBER_WRITE0
:
1281 cm_node
->send_write0
= 1;
1284 nes_debug(NES_DBG_CM
, "TCP Option not understood: %x\n",
1285 all_options
->as_base
.optionnum
);
1288 offset
+= all_options
->as_base
.length
;
1290 if ((!got_mss_option
) && (syn_packet
))
1291 cm_node
->tcp_cntxt
.mss
= NES_CM_DEFAULT_MSS
;
1299 static int process_packet(struct nes_cm_node
*cm_node
, struct sk_buff
*skb
,
1300 struct nes_cm_core
*cm_core
)
1305 struct tcphdr
*tcph
= tcp_hdr(skb
);
1307 if (cm_node
->state
== NES_CM_STATE_SYN_SENT
&& tcph
->syn
) {
1308 inc_sequence
= ntohl(tcph
->seq
);
1309 cm_node
->tcp_cntxt
.rcv_nxt
= inc_sequence
;
1312 if ((!tcph
) || (cm_node
->state
== NES_CM_STATE_TSA
)) {
1314 atomic_inc(&cm_accel_dropped_pkts
);
1319 atomic_inc(&cm_resets_recvd
);
1320 nes_debug(NES_DBG_CM
, "Received Reset, cm_node = %p, state = %u. refcnt=%d\n",
1321 cm_node
, cm_node
->state
, atomic_read(&cm_node
->ref_count
));
1322 switch (cm_node
->state
) {
1323 case NES_CM_STATE_LISTENING
:
1324 rem_ref_cm_node(cm_core
, cm_node
);
1326 case NES_CM_STATE_TSA
:
1327 case NES_CM_STATE_CLOSED
:
1329 case NES_CM_STATE_SYN_RCVD
:
1330 nes_debug(NES_DBG_CM
, "Received a reset for local 0x%08X:%04X,"
1331 " remote 0x%08X:%04X, node state = %u\n",
1332 cm_node
->loc_addr
, cm_node
->loc_port
,
1333 cm_node
->rem_addr
, cm_node
->rem_port
,
1335 rem_ref_cm_node(cm_core
, cm_node
);
1337 case NES_CM_STATE_ONE_SIDE_ESTABLISHED
:
1338 case NES_CM_STATE_ESTABLISHED
:
1339 case NES_CM_STATE_MPAREQ_SENT
:
1341 nes_debug(NES_DBG_CM
, "Received a reset for local 0x%08X:%04X,"
1342 " remote 0x%08X:%04X, node state = %u refcnt=%d\n",
1343 cm_node
->loc_addr
, cm_node
->loc_port
,
1344 cm_node
->rem_addr
, cm_node
->rem_port
,
1345 cm_node
->state
, atomic_read(&cm_node
->ref_count
));
1347 cm_node
->state
= NES_CM_STATE_CLOSED
;
1349 create_event(cm_node
, NES_CM_EVENT_ABORTED
);
1356 optionsize
= (tcph
->doff
<< 2) - sizeof(struct tcphdr
);
1358 skb_pull(skb
, ip_hdr(skb
)->ihl
<< 2);
1359 skb_pull(skb
, tcph
->doff
<< 2);
1361 datasize
= skb
->len
;
1362 inc_sequence
= ntohl(tcph
->seq
);
1363 nes_debug(NES_DBG_CM
, "datasize = %u, sequence = 0x%08X, ack_seq = 0x%08X,"
1364 " rcv_nxt = 0x%08X Flags: %s %s.\n",
1365 datasize
, inc_sequence
, ntohl(tcph
->ack_seq
),
1366 cm_node
->tcp_cntxt
.rcv_nxt
, (tcph
->syn
? "SYN":""),
1367 (tcph
->ack
? "ACK":""));
1369 if (!tcph
->syn
&& (inc_sequence
!= cm_node
->tcp_cntxt
.rcv_nxt
)
1371 nes_debug(NES_DBG_CM
, "dropping packet, datasize = %u, sequence = 0x%08X,"
1372 " ack_seq = 0x%08X, rcv_nxt = 0x%08X Flags: %s.\n",
1373 datasize
, inc_sequence
, ntohl(tcph
->ack_seq
),
1374 cm_node
->tcp_cntxt
.rcv_nxt
, (tcph
->ack
? "ACK":""));
1375 if (cm_node
->state
== NES_CM_STATE_LISTENING
) {
1376 rem_ref_cm_node(cm_core
, cm_node
);
1381 cm_node
->tcp_cntxt
.rcv_nxt
= inc_sequence
+ datasize
;
1385 u8
*optionsloc
= (u8
*)&tcph
[1];
1386 if (process_options(cm_node
, optionsloc
, optionsize
, (u32
)tcph
->syn
)) {
1387 nes_debug(NES_DBG_CM
, "%s: Node %p, Sending RESET\n", __FUNCTION__
, cm_node
);
1388 send_reset(cm_node
);
1389 if (cm_node
->state
!= NES_CM_STATE_SYN_SENT
)
1390 rem_ref_cm_node(cm_core
, cm_node
);
1393 } else if (tcph
->syn
)
1394 cm_node
->tcp_cntxt
.mss
= NES_CM_DEFAULT_MSS
;
1396 cm_node
->tcp_cntxt
.snd_wnd
= ntohs(tcph
->window
) <<
1397 cm_node
->tcp_cntxt
.snd_wscale
;
1399 if (cm_node
->tcp_cntxt
.snd_wnd
> cm_node
->tcp_cntxt
.max_snd_wnd
) {
1400 cm_node
->tcp_cntxt
.max_snd_wnd
= cm_node
->tcp_cntxt
.snd_wnd
;
1404 cm_node
->tcp_cntxt
.rem_ack_num
= ntohl(tcph
->ack_seq
);
1405 switch (cm_node
->state
) {
1406 case NES_CM_STATE_SYN_RCVD
:
1407 case NES_CM_STATE_SYN_SENT
:
1408 /* read and stash current sequence number */
1409 if (cm_node
->tcp_cntxt
.rem_ack_num
!= cm_node
->tcp_cntxt
.loc_seq_num
) {
1410 nes_debug(NES_DBG_CM
, "ERROR - cm_node->tcp_cntxt.rem_ack_num !="
1411 " cm_node->tcp_cntxt.loc_seq_num\n");
1412 send_reset(cm_node
);
1415 if (cm_node
->state
== NES_CM_STATE_SYN_SENT
)
1416 cm_node
->state
= NES_CM_STATE_ONE_SIDE_ESTABLISHED
;
1418 cm_node
->state
= NES_CM_STATE_ESTABLISHED
;
1421 case NES_CM_STATE_LAST_ACK
:
1422 cm_node
->state
= NES_CM_STATE_CLOSED
;
1424 case NES_CM_STATE_FIN_WAIT1
:
1425 cm_node
->state
= NES_CM_STATE_FIN_WAIT2
;
1427 case NES_CM_STATE_CLOSING
:
1428 cm_node
->state
= NES_CM_STATE_TIME_WAIT
;
1429 /* need to schedule this to happen in 2MSL timeouts */
1430 cm_node
->state
= NES_CM_STATE_CLOSED
;
1432 case NES_CM_STATE_ONE_SIDE_ESTABLISHED
:
1433 case NES_CM_STATE_ESTABLISHED
:
1434 case NES_CM_STATE_MPAREQ_SENT
:
1435 case NES_CM_STATE_CLOSE_WAIT
:
1436 case NES_CM_STATE_TIME_WAIT
:
1437 case NES_CM_STATE_CLOSED
:
1439 case NES_CM_STATE_LISTENING
:
1440 nes_debug(NES_DBG_CM
, "Received an ACK on a listening port (SYN %d)\n", tcph
->syn
);
1441 cm_node
->tcp_cntxt
.loc_seq_num
= ntohl(tcph
->ack_seq
);
1442 send_reset(cm_node
);
1443 /* send_reset bumps refcount, this should have been a new node */
1444 rem_ref_cm_node(cm_core
, cm_node
);
1447 case NES_CM_STATE_TSA
:
1448 nes_debug(NES_DBG_CM
, "Received a packet with the ack bit set while in TSA state\n");
1450 case NES_CM_STATE_UNKNOWN
:
1451 case NES_CM_STATE_INITED
:
1452 case NES_CM_STATE_ACCEPTING
:
1453 case NES_CM_STATE_FIN_WAIT2
:
1455 nes_debug(NES_DBG_CM
, "Received ack from unknown state: %x\n",
1457 send_reset(cm_node
);
1463 if (cm_node
->state
== NES_CM_STATE_LISTENING
) {
1464 /* do not exceed backlog */
1465 atomic_inc(&cm_node
->listener
->pend_accepts_cnt
);
1466 if (atomic_read(&cm_node
->listener
->pend_accepts_cnt
) >
1467 cm_node
->listener
->backlog
) {
1468 nes_debug(NES_DBG_CM
, "drop syn due to backlog pressure \n");
1470 atomic_dec(&cm_node
->listener
->pend_accepts_cnt
);
1471 rem_ref_cm_node(cm_core
, cm_node
);
1474 cm_node
->accept_pend
= 1;
1478 cm_node
->tcp_cntxt
.rcv_nxt
++;
1480 if (cm_node
->state
== NES_CM_STATE_LISTENING
) {
1481 cm_node
->state
= NES_CM_STATE_SYN_RCVD
;
1482 send_syn(cm_node
, 1);
1484 if (cm_node
->state
== NES_CM_STATE_ONE_SIDE_ESTABLISHED
) {
1485 cm_node
->state
= NES_CM_STATE_ESTABLISHED
;
1486 /* send final handshake ACK */
1487 ret
= send_ack(cm_node
);
1491 cm_node
->state
= NES_CM_STATE_MPAREQ_SENT
;
1492 ret
= send_mpa_request(cm_node
);
1499 cm_node
->tcp_cntxt
.rcv_nxt
++;
1500 switch (cm_node
->state
) {
1501 case NES_CM_STATE_SYN_RCVD
:
1502 case NES_CM_STATE_SYN_SENT
:
1503 case NES_CM_STATE_ONE_SIDE_ESTABLISHED
:
1504 case NES_CM_STATE_ESTABLISHED
:
1505 case NES_CM_STATE_ACCEPTING
:
1506 case NES_CM_STATE_MPAREQ_SENT
:
1507 cm_node
->state
= NES_CM_STATE_CLOSE_WAIT
;
1508 cm_node
->state
= NES_CM_STATE_LAST_ACK
;
1509 ret
= send_fin(cm_node
, NULL
);
1511 case NES_CM_STATE_FIN_WAIT1
:
1512 cm_node
->state
= NES_CM_STATE_CLOSING
;
1513 ret
= send_ack(cm_node
);
1515 case NES_CM_STATE_FIN_WAIT2
:
1516 cm_node
->state
= NES_CM_STATE_TIME_WAIT
;
1517 cm_node
->tcp_cntxt
.loc_seq_num
++;
1518 ret
= send_ack(cm_node
);
1519 /* need to schedule this to happen in 2MSL timeouts */
1520 cm_node
->state
= NES_CM_STATE_CLOSED
;
1522 case NES_CM_STATE_CLOSE_WAIT
:
1523 case NES_CM_STATE_LAST_ACK
:
1524 case NES_CM_STATE_CLOSING
:
1525 case NES_CM_STATE_TSA
:
1527 nes_debug(NES_DBG_CM
, "Received a fin while in %x state\n",
1535 u8
*dataloc
= skb
->data
;
1536 /* figure out what state we are in and handle transition to next state */
1537 switch (cm_node
->state
) {
1538 case NES_CM_STATE_LISTENING
:
1539 case NES_CM_STATE_SYN_RCVD
:
1540 case NES_CM_STATE_SYN_SENT
:
1541 case NES_CM_STATE_FIN_WAIT1
:
1542 case NES_CM_STATE_FIN_WAIT2
:
1543 case NES_CM_STATE_CLOSE_WAIT
:
1544 case NES_CM_STATE_LAST_ACK
:
1545 case NES_CM_STATE_CLOSING
:
1547 case NES_CM_STATE_MPAREQ_SENT
:
1548 /* recv the mpa res frame, ret=frame len (incl priv data) */
1549 ret
= parse_mpa(cm_node
, dataloc
, datasize
);
1552 /* set the req frame payload len in skb */
1553 /* we are done handling this state, set node to a TSA state */
1554 cm_node
->state
= NES_CM_STATE_TSA
;
1556 create_event(cm_node
, NES_CM_EVENT_CONNECTED
);
1559 case NES_CM_STATE_ESTABLISHED
:
1560 /* we are expecting an MPA req frame */
1561 ret
= parse_mpa(cm_node
, dataloc
, datasize
);
1565 cm_node
->state
= NES_CM_STATE_TSA
;
1567 /* we got a valid MPA request, create an event */
1568 create_event(cm_node
, NES_CM_EVENT_MPA_REQ
);
1570 case NES_CM_STATE_TSA
:
1571 handle_exception_pkt(cm_node
, skb
);
1573 case NES_CM_STATE_UNKNOWN
:
1574 case NES_CM_STATE_INITED
:
1585 * mini_cm_listen - create a listen node with params
1587 static struct nes_cm_listener
*mini_cm_listen(struct nes_cm_core
*cm_core
,
1588 struct nes_vnic
*nesvnic
, struct nes_cm_info
*cm_info
)
1590 struct nes_cm_listener
*listener
;
1591 unsigned long flags
;
1593 nes_debug(NES_DBG_CM
, "Search for 0x%08x : 0x%04x\n",
1594 cm_info
->loc_addr
, cm_info
->loc_port
);
1596 /* cannot have multiple matching listeners */
1597 listener
= find_listener(cm_core
, htonl(cm_info
->loc_addr
),
1598 htons(cm_info
->loc_port
), NES_CM_LISTENER_EITHER_STATE
);
1599 if (listener
&& listener
->listener_state
== NES_CM_LISTENER_ACTIVE_STATE
) {
1600 /* find automatically incs ref count ??? */
1601 atomic_dec(&listener
->ref_count
);
1602 nes_debug(NES_DBG_CM
, "Not creating listener since it already exists\n");
1607 /* create a CM listen node (1/2 node to compare incoming traffic to) */
1608 listener
= kzalloc(sizeof(*listener
), GFP_ATOMIC
);
1610 nes_debug(NES_DBG_CM
, "Not creating listener memory allocation failed\n");
1614 memset(listener
, 0, sizeof(struct nes_cm_listener
));
1615 listener
->loc_addr
= htonl(cm_info
->loc_addr
);
1616 listener
->loc_port
= htons(cm_info
->loc_port
);
1617 listener
->reused_node
= 0;
1619 atomic_set(&listener
->ref_count
, 1);
1622 /* find already inc'ed the ref count */
1624 listener
->reused_node
= 1;
1627 listener
->cm_id
= cm_info
->cm_id
;
1628 atomic_set(&listener
->pend_accepts_cnt
, 0);
1629 listener
->cm_core
= cm_core
;
1630 listener
->nesvnic
= nesvnic
;
1631 atomic_inc(&cm_core
->node_cnt
);
1632 atomic_inc(&cm_core
->session_id
);
1634 listener
->session_id
= (u32
)(atomic_read(&cm_core
->session_id
) + current
->tgid
);
1635 listener
->conn_type
= cm_info
->conn_type
;
1636 listener
->backlog
= cm_info
->backlog
;
1637 listener
->listener_state
= NES_CM_LISTENER_ACTIVE_STATE
;
1639 if (!listener
->reused_node
) {
1640 spin_lock_irqsave(&cm_core
->listen_list_lock
, flags
);
1641 list_add(&listener
->list
, &cm_core
->listen_list
.list
);
1642 spin_unlock_irqrestore(&cm_core
->listen_list_lock
, flags
);
1643 atomic_inc(&cm_core
->listen_node_cnt
);
1646 nes_debug(NES_DBG_CM
, "Api - listen(): addr=0x%08X, port=0x%04x,"
1647 " listener = %p, backlog = %d, cm_id = %p.\n",
1648 cm_info
->loc_addr
, cm_info
->loc_port
,
1649 listener
, listener
->backlog
, listener
->cm_id
);
1656 * mini_cm_connect - make a connection node with params
1658 static struct nes_cm_node
*mini_cm_connect(struct nes_cm_core
*cm_core
,
1659 struct nes_vnic
*nesvnic
,
1660 struct ietf_mpa_frame
*mpa_frame
,
1661 struct nes_cm_info
*cm_info
)
1664 struct nes_cm_node
*cm_node
;
1665 struct nes_cm_listener
*loopbackremotelistener
;
1666 struct nes_cm_node
*loopbackremotenode
;
1667 struct nes_cm_info loopback_cm_info
;
1669 u16 mpa_frame_size
= sizeof(struct ietf_mpa_frame
) +
1670 ntohs(mpa_frame
->priv_data_len
);
1672 cm_info
->loc_addr
= htonl(cm_info
->loc_addr
);
1673 cm_info
->rem_addr
= htonl(cm_info
->rem_addr
);
1674 cm_info
->loc_port
= htons(cm_info
->loc_port
);
1675 cm_info
->rem_port
= htons(cm_info
->rem_port
);
1677 /* create a CM connection node */
1678 cm_node
= make_cm_node(cm_core
, nesvnic
, cm_info
, NULL
);
1682 // set our node side to client (active) side
1683 cm_node
->tcp_cntxt
.client
= 1;
1684 cm_node
->tcp_cntxt
.rcv_wscale
= NES_CM_DEFAULT_RCV_WND_SCALE
;
1686 if (cm_info
->loc_addr
== cm_info
->rem_addr
) {
1687 loopbackremotelistener
= find_listener(cm_core
, cm_node
->rem_addr
,
1688 cm_node
->rem_port
, NES_CM_LISTENER_ACTIVE_STATE
);
1689 if (loopbackremotelistener
== NULL
) {
1690 create_event(cm_node
, NES_CM_EVENT_ABORTED
);
1692 atomic_inc(&cm_loopbacks
);
1693 loopback_cm_info
= *cm_info
;
1694 loopback_cm_info
.loc_port
= cm_info
->rem_port
;
1695 loopback_cm_info
.rem_port
= cm_info
->loc_port
;
1696 loopback_cm_info
.cm_id
= loopbackremotelistener
->cm_id
;
1697 loopbackremotenode
= make_cm_node(cm_core
, nesvnic
, &loopback_cm_info
,
1698 loopbackremotelistener
);
1699 loopbackremotenode
->loopbackpartner
= cm_node
;
1700 loopbackremotenode
->tcp_cntxt
.rcv_wscale
= NES_CM_DEFAULT_RCV_WND_SCALE
;
1701 cm_node
->loopbackpartner
= loopbackremotenode
;
1702 memcpy(loopbackremotenode
->mpa_frame_buf
, &mpa_frame
->priv_data
,
1704 loopbackremotenode
->mpa_frame_size
= mpa_frame_size
-
1705 sizeof(struct ietf_mpa_frame
);
1707 // we are done handling this state, set node to a TSA state
1708 cm_node
->state
= NES_CM_STATE_TSA
;
1709 cm_node
->tcp_cntxt
.rcv_nxt
= loopbackremotenode
->tcp_cntxt
.loc_seq_num
;
1710 loopbackremotenode
->tcp_cntxt
.rcv_nxt
= cm_node
->tcp_cntxt
.loc_seq_num
;
1711 cm_node
->tcp_cntxt
.max_snd_wnd
= loopbackremotenode
->tcp_cntxt
.rcv_wnd
;
1712 loopbackremotenode
->tcp_cntxt
.max_snd_wnd
= cm_node
->tcp_cntxt
.rcv_wnd
;
1713 cm_node
->tcp_cntxt
.snd_wnd
= loopbackremotenode
->tcp_cntxt
.rcv_wnd
;
1714 loopbackremotenode
->tcp_cntxt
.snd_wnd
= cm_node
->tcp_cntxt
.rcv_wnd
;
1715 cm_node
->tcp_cntxt
.snd_wscale
= loopbackremotenode
->tcp_cntxt
.rcv_wscale
;
1716 loopbackremotenode
->tcp_cntxt
.snd_wscale
= cm_node
->tcp_cntxt
.rcv_wscale
;
1718 create_event(loopbackremotenode
, NES_CM_EVENT_MPA_REQ
);
1723 /* set our node side to client (active) side */
1724 cm_node
->tcp_cntxt
.client
= 1;
1725 /* init our MPA frame ptr */
1726 memcpy(&cm_node
->mpa_frame
, mpa_frame
, mpa_frame_size
);
1727 cm_node
->mpa_frame_size
= mpa_frame_size
;
1729 /* send a syn and goto syn sent state */
1730 cm_node
->state
= NES_CM_STATE_SYN_SENT
;
1731 ret
= send_syn(cm_node
, 0);
1733 nes_debug(NES_DBG_CM
, "Api - connect(): dest addr=0x%08X, port=0x%04x,"
1734 " cm_node=%p, cm_id = %p.\n",
1735 cm_node
->rem_addr
, cm_node
->rem_port
, cm_node
, cm_node
->cm_id
);
1742 * mini_cm_accept - accept a connection
1743 * This function is never called
1745 static int mini_cm_accept(struct nes_cm_core
*cm_core
, struct ietf_mpa_frame
*mpa_frame
,
1746 struct nes_cm_node
*cm_node
)
1753 * mini_cm_reject - reject and teardown a connection
1755 static int mini_cm_reject(struct nes_cm_core
*cm_core
,
1756 struct ietf_mpa_frame
*mpa_frame
,
1757 struct nes_cm_node
*cm_node
)
1760 struct sk_buff
*skb
;
1761 u16 mpa_frame_size
= sizeof(struct ietf_mpa_frame
) +
1762 ntohs(mpa_frame
->priv_data_len
);
1764 skb
= get_free_pkt(cm_node
);
1766 nes_debug(NES_DBG_CM
, "Failed to get a Free pkt\n");
1770 /* send an MPA Request frame */
1771 form_cm_frame(skb
, cm_node
, NULL
, 0, mpa_frame
, mpa_frame_size
, SET_ACK
| SET_FIN
);
1772 ret
= schedule_nes_timer(cm_node
, skb
, NES_TIMER_TYPE_SEND
, 1, 0);
1774 cm_node
->state
= NES_CM_STATE_CLOSED
;
1775 ret
= send_fin(cm_node
, NULL
);
1778 printk(KERN_INFO PFX
"failed to send MPA Reply (reject)\n");
1789 static int mini_cm_close(struct nes_cm_core
*cm_core
, struct nes_cm_node
*cm_node
)
1793 if (!cm_core
|| !cm_node
)
1796 switch (cm_node
->state
) {
1797 /* if passed in node is null, create a reference key node for node search */
1798 /* check if we found an owner node for this pkt */
1799 case NES_CM_STATE_SYN_RCVD
:
1800 case NES_CM_STATE_SYN_SENT
:
1801 case NES_CM_STATE_ONE_SIDE_ESTABLISHED
:
1802 case NES_CM_STATE_ESTABLISHED
:
1803 case NES_CM_STATE_ACCEPTING
:
1804 case NES_CM_STATE_MPAREQ_SENT
:
1805 cm_node
->state
= NES_CM_STATE_FIN_WAIT1
;
1806 send_fin(cm_node
, NULL
);
1808 case NES_CM_STATE_CLOSE_WAIT
:
1809 cm_node
->state
= NES_CM_STATE_LAST_ACK
;
1810 send_fin(cm_node
, NULL
);
1812 case NES_CM_STATE_FIN_WAIT1
:
1813 case NES_CM_STATE_FIN_WAIT2
:
1814 case NES_CM_STATE_LAST_ACK
:
1815 case NES_CM_STATE_TIME_WAIT
:
1816 case NES_CM_STATE_CLOSING
:
1819 case NES_CM_STATE_LISTENING
:
1820 case NES_CM_STATE_UNKNOWN
:
1821 case NES_CM_STATE_INITED
:
1822 case NES_CM_STATE_CLOSED
:
1823 case NES_CM_STATE_TSA
:
1824 ret
= rem_ref_cm_node(cm_core
, cm_node
);
1827 cm_node
->cm_id
= NULL
;
1833 * recv_pkt - recv an ETHERNET packet, and process it through CM
1834 * node state machine
1836 static int mini_cm_recv_pkt(struct nes_cm_core
*cm_core
, struct nes_vnic
*nesvnic
,
1837 struct sk_buff
*skb
)
1839 struct nes_cm_node
*cm_node
= NULL
;
1840 struct nes_cm_listener
*listener
= NULL
;
1842 struct tcphdr
*tcph
;
1843 struct nes_cm_info nfo
;
1846 if (!skb
|| skb
->len
< sizeof(struct iphdr
) + sizeof(struct tcphdr
)) {
1851 iph
= (struct iphdr
*)skb
->data
;
1852 tcph
= (struct tcphdr
*)(skb
->data
+ sizeof(struct iphdr
));
1853 skb_reset_network_header(skb
);
1854 skb_set_transport_header(skb
, sizeof(*tcph
));
1855 skb
->len
= ntohs(iph
->tot_len
);
1857 nfo
.loc_addr
= ntohl(iph
->daddr
);
1858 nfo
.loc_port
= ntohs(tcph
->dest
);
1859 nfo
.rem_addr
= ntohl(iph
->saddr
);
1860 nfo
.rem_port
= ntohs(tcph
->source
);
1862 nes_debug(NES_DBG_CM
, "Received packet: dest=0x%08X:0x%04X src=0x%08X:0x%04X\n",
1863 iph
->daddr
, tcph
->dest
, iph
->saddr
, tcph
->source
);
1865 /* note: this call is going to increment cm_node ref count */
1866 cm_node
= find_node(cm_core
,
1867 nfo
.rem_port
, nfo
.rem_addr
,
1868 nfo
.loc_port
, nfo
.loc_addr
);
1871 listener
= find_listener(cm_core
, nfo
.loc_addr
, nfo
.loc_port
,
1872 NES_CM_LISTENER_ACTIVE_STATE
);
1874 nfo
.cm_id
= listener
->cm_id
;
1875 nfo
.conn_type
= listener
->conn_type
;
1881 cm_node
= make_cm_node(cm_core
, nesvnic
, &nfo
, listener
);
1883 nes_debug(NES_DBG_CM
, "Unable to allocate node\n");
1885 nes_debug(NES_DBG_CM
, "unable to allocate node and decrementing listener refcount\n");
1886 atomic_dec(&listener
->ref_count
);
1892 nes_debug(NES_DBG_CM
, "Packet found for unknown port %x refcnt=%d\n",
1893 nfo
.loc_port
, atomic_read(&cm_node
->ref_count
));
1895 nes_debug(NES_DBG_CM
, "Packet found for unknown port=%d"
1896 " rem_port=%d refcnt=%d\n",
1897 nfo
.loc_port
, nfo
.rem_port
, atomic_read(&cm_node
->ref_count
));
1899 cm_node
->tcp_cntxt
.rcv_nxt
= ntohl(tcph
->seq
);
1900 cm_node
->tcp_cntxt
.loc_seq_num
= ntohl(tcph
->ack_seq
);
1901 send_reset(cm_node
);
1903 rem_ref_cm_node(cm_core
, cm_node
);
1907 add_ref_cm_node(cm_node
);
1908 cm_node
->state
= NES_CM_STATE_LISTENING
;
1911 nes_debug(NES_DBG_CM
, "Processing Packet for node %p, data = (%p):\n",
1912 cm_node
, skb
->data
);
1913 process_packet(cm_node
, skb
, cm_core
);
1915 rem_ref_cm_node(cm_core
, cm_node
);
1918 dev_kfree_skb_any(skb
);
1924 * nes_cm_alloc_core - allocate a top level instance of a cm core
1926 static struct nes_cm_core
*nes_cm_alloc_core(void)
1930 struct nes_cm_core
*cm_core
;
1931 struct sk_buff
*skb
= NULL
;
1933 /* setup the CM core */
1934 /* alloc top level core control structure */
1935 cm_core
= kzalloc(sizeof(*cm_core
), GFP_KERNEL
);
1939 INIT_LIST_HEAD(&cm_core
->connected_nodes
);
1940 init_timer(&cm_core
->tcp_timer
);
1941 cm_core
->tcp_timer
.function
= nes_cm_timer_tick
;
1943 cm_core
->mtu
= NES_CM_DEFAULT_MTU
;
1944 cm_core
->state
= NES_CM_STATE_INITED
;
1945 cm_core
->free_tx_pkt_max
= NES_CM_DEFAULT_FREE_PKTS
;
1947 atomic_set(&cm_core
->session_id
, 0);
1948 atomic_set(&cm_core
->events_posted
, 0);
1950 /* init the packet lists */
1951 skb_queue_head_init(&cm_core
->tx_free_list
);
1953 for (i
= 0; i
< NES_CM_DEFAULT_FRAME_CNT
; i
++) {
1954 skb
= dev_alloc_skb(cm_core
->mtu
);
1959 /* add 'raw' skb to free frame list */
1960 skb_queue_head(&cm_core
->tx_free_list
, skb
);
1963 cm_core
->api
= &nes_cm_api
;
1965 spin_lock_init(&cm_core
->ht_lock
);
1966 spin_lock_init(&cm_core
->listen_list_lock
);
1968 INIT_LIST_HEAD(&cm_core
->listen_list
.list
);
1970 nes_debug(NES_DBG_CM
, "Init CM Core completed -- cm_core=%p\n", cm_core
);
1972 nes_debug(NES_DBG_CM
, "Enable QUEUE EVENTS\n");
1973 cm_core
->event_wq
= create_singlethread_workqueue("nesewq");
1974 cm_core
->post_event
= nes_cm_post_event
;
1975 nes_debug(NES_DBG_CM
, "Enable QUEUE DISCONNECTS\n");
1976 cm_core
->disconn_wq
= create_singlethread_workqueue("nesdwq");
1978 print_core(cm_core
);
1984 * mini_cm_dealloc_core - deallocate a top level instance of a cm core
1986 static int mini_cm_dealloc_core(struct nes_cm_core
*cm_core
)
1988 nes_debug(NES_DBG_CM
, "De-Alloc CM Core (%p)\n", cm_core
);
1995 if (timer_pending(&cm_core
->tcp_timer
)) {
1996 del_timer(&cm_core
->tcp_timer
);
1999 destroy_workqueue(cm_core
->event_wq
);
2000 destroy_workqueue(cm_core
->disconn_wq
);
2001 nes_debug(NES_DBG_CM
, "\n");
2011 static int mini_cm_get(struct nes_cm_core
*cm_core
)
2013 return cm_core
->state
;
2020 static int mini_cm_set(struct nes_cm_core
*cm_core
, u32 type
, u32 value
)
2025 case NES_CM_SET_PKT_SIZE
:
2026 cm_core
->mtu
= value
;
2028 case NES_CM_SET_FREE_PKT_Q_SIZE
:
2029 cm_core
->free_tx_pkt_max
= value
;
2032 /* unknown set option */
2041 * nes_cm_init_tsa_conn setup HW; MPA frames must be
2042 * successfully exchanged when this is called
2044 static int nes_cm_init_tsa_conn(struct nes_qp
*nesqp
, struct nes_cm_node
*cm_node
)
2051 nesqp
->nesqp_context
->misc
|= cpu_to_le32(NES_QPCONTEXT_MISC_IPV4
|
2052 NES_QPCONTEXT_MISC_NO_NAGLE
| NES_QPCONTEXT_MISC_DO_NOT_FRAG
|
2053 NES_QPCONTEXT_MISC_DROS
);
2055 if (cm_node
->tcp_cntxt
.snd_wscale
|| cm_node
->tcp_cntxt
.rcv_wscale
)
2056 nesqp
->nesqp_context
->misc
|= cpu_to_le32(NES_QPCONTEXT_MISC_WSCALE
);
2058 nesqp
->nesqp_context
->misc2
|= cpu_to_le32(64 << NES_QPCONTEXT_MISC2_TTL_SHIFT
);
2060 nesqp
->nesqp_context
->mss
|= cpu_to_le32(((u32
)cm_node
->tcp_cntxt
.mss
) << 16);
2062 nesqp
->nesqp_context
->tcp_state_flow_label
|= cpu_to_le32(
2063 (u32
)NES_QPCONTEXT_TCPSTATE_EST
<< NES_QPCONTEXT_TCPFLOW_TCP_STATE_SHIFT
);
2065 nesqp
->nesqp_context
->pd_index_wscale
|= cpu_to_le32(
2066 (cm_node
->tcp_cntxt
.snd_wscale
<< NES_QPCONTEXT_PDWSCALE_SND_WSCALE_SHIFT
) &
2067 NES_QPCONTEXT_PDWSCALE_SND_WSCALE_MASK
);
2069 nesqp
->nesqp_context
->pd_index_wscale
|= cpu_to_le32(
2070 (cm_node
->tcp_cntxt
.rcv_wscale
<< NES_QPCONTEXT_PDWSCALE_RCV_WSCALE_SHIFT
) &
2071 NES_QPCONTEXT_PDWSCALE_RCV_WSCALE_MASK
);
2073 nesqp
->nesqp_context
->keepalive
= cpu_to_le32(0x80);
2074 nesqp
->nesqp_context
->ts_recent
= 0;
2075 nesqp
->nesqp_context
->ts_age
= 0;
2076 nesqp
->nesqp_context
->snd_nxt
= cpu_to_le32(cm_node
->tcp_cntxt
.loc_seq_num
);
2077 nesqp
->nesqp_context
->snd_wnd
= cpu_to_le32(cm_node
->tcp_cntxt
.snd_wnd
);
2078 nesqp
->nesqp_context
->rcv_nxt
= cpu_to_le32(cm_node
->tcp_cntxt
.rcv_nxt
);
2079 nesqp
->nesqp_context
->rcv_wnd
= cpu_to_le32(cm_node
->tcp_cntxt
.rcv_wnd
<<
2080 cm_node
->tcp_cntxt
.rcv_wscale
);
2081 nesqp
->nesqp_context
->snd_max
= cpu_to_le32(cm_node
->tcp_cntxt
.loc_seq_num
);
2082 nesqp
->nesqp_context
->snd_una
= cpu_to_le32(cm_node
->tcp_cntxt
.loc_seq_num
);
2083 nesqp
->nesqp_context
->srtt
= 0;
2084 nesqp
->nesqp_context
->rttvar
= cpu_to_le32(0x6);
2085 nesqp
->nesqp_context
->ssthresh
= cpu_to_le32(0x3FFFC000);
2086 nesqp
->nesqp_context
->cwnd
= cpu_to_le32(2*cm_node
->tcp_cntxt
.mss
);
2087 nesqp
->nesqp_context
->snd_wl1
= cpu_to_le32(cm_node
->tcp_cntxt
.rcv_nxt
);
2088 nesqp
->nesqp_context
->snd_wl2
= cpu_to_le32(cm_node
->tcp_cntxt
.loc_seq_num
);
2089 nesqp
->nesqp_context
->max_snd_wnd
= cpu_to_le32(cm_node
->tcp_cntxt
.max_snd_wnd
);
2091 nes_debug(NES_DBG_CM
, "QP%u: rcv_nxt = 0x%08X, snd_nxt = 0x%08X,"
2092 " Setting MSS to %u, PDWscale = 0x%08X, rcv_wnd = %u, context misc = 0x%08X.\n",
2093 nesqp
->hwqp
.qp_id
, le32_to_cpu(nesqp
->nesqp_context
->rcv_nxt
),
2094 le32_to_cpu(nesqp
->nesqp_context
->snd_nxt
),
2095 cm_node
->tcp_cntxt
.mss
, le32_to_cpu(nesqp
->nesqp_context
->pd_index_wscale
),
2096 le32_to_cpu(nesqp
->nesqp_context
->rcv_wnd
),
2097 le32_to_cpu(nesqp
->nesqp_context
->misc
));
2098 nes_debug(NES_DBG_CM
, " snd_wnd = 0x%08X.\n", le32_to_cpu(nesqp
->nesqp_context
->snd_wnd
));
2099 nes_debug(NES_DBG_CM
, " snd_cwnd = 0x%08X.\n", le32_to_cpu(nesqp
->nesqp_context
->cwnd
));
2100 nes_debug(NES_DBG_CM
, " max_swnd = 0x%08X.\n", le32_to_cpu(nesqp
->nesqp_context
->max_snd_wnd
));
2102 nes_debug(NES_DBG_CM
, "Change cm_node state to TSA\n");
2103 cm_node
->state
= NES_CM_STATE_TSA
;
2112 int nes_cm_disconn(struct nes_qp
*nesqp
)
2114 unsigned long flags
;
2116 spin_lock_irqsave(&nesqp
->lock
, flags
);
2117 if (nesqp
->disconn_pending
== 0) {
2118 nesqp
->disconn_pending
++;
2119 spin_unlock_irqrestore(&nesqp
->lock
, flags
);
2120 /* nes_add_ref(&nesqp->ibqp); */
2121 /* init our disconnect work element, to */
2122 INIT_WORK(&nesqp
->disconn_work
, nes_disconnect_worker
);
2124 queue_work(g_cm_core
->disconn_wq
, &nesqp
->disconn_work
);
2126 spin_unlock_irqrestore(&nesqp
->lock
, flags
);
2127 nes_rem_ref(&nesqp
->ibqp
);
2135 * nes_disconnect_worker
2137 static void nes_disconnect_worker(struct work_struct
*work
)
2139 struct nes_qp
*nesqp
= container_of(work
, struct nes_qp
, disconn_work
);
2141 nes_debug(NES_DBG_CM
, "processing AEQE id 0x%04X for QP%u.\n",
2142 nesqp
->last_aeq
, nesqp
->hwqp
.qp_id
);
2143 nes_cm_disconn_true(nesqp
);
2148 * nes_cm_disconn_true
2150 static int nes_cm_disconn_true(struct nes_qp
*nesqp
)
2152 unsigned long flags
;
2154 struct iw_cm_id
*cm_id
;
2155 struct iw_cm_event cm_event
;
2156 struct nes_vnic
*nesvnic
;
2158 u8 original_hw_tcp_state
;
2159 u8 original_ibqp_state
;
2160 u8 issued_disconnect_reset
= 0;
2163 nes_debug(NES_DBG_CM
, "disconnect_worker nesqp is NULL\n");
2167 spin_lock_irqsave(&nesqp
->lock
, flags
);
2168 cm_id
= nesqp
->cm_id
;
2169 /* make sure we havent already closed this connection */
2171 nes_debug(NES_DBG_CM
, "QP%u disconnect_worker cmid is NULL\n",
2173 spin_unlock_irqrestore(&nesqp
->lock
, flags
);
2174 nes_rem_ref(&nesqp
->ibqp
);
2178 nesvnic
= to_nesvnic(nesqp
->ibqp
.device
);
2179 nes_debug(NES_DBG_CM
, "Disconnecting QP%u\n", nesqp
->hwqp
.qp_id
);
2181 original_hw_tcp_state
= nesqp
->hw_tcp_state
;
2182 original_ibqp_state
= nesqp
->ibqp_state
;
2183 last_ae
= nesqp
->last_aeq
;
2186 nes_debug(NES_DBG_CM
, "set ibqp_state=%u\n", nesqp
->ibqp_state
);
2188 if ((nesqp
->cm_id
) && (cm_id
->event_handler
)) {
2189 if ((original_hw_tcp_state
== NES_AEQE_TCP_STATE_CLOSE_WAIT
) ||
2190 ((original_ibqp_state
== IB_QPS_RTS
) &&
2191 (last_ae
== NES_AEQE_AEID_LLP_CONNECTION_RESET
))) {
2192 atomic_inc(&cm_disconnects
);
2193 cm_event
.event
= IW_CM_EVENT_DISCONNECT
;
2194 if (last_ae
== NES_AEQE_AEID_LLP_CONNECTION_RESET
) {
2195 issued_disconnect_reset
= 1;
2196 cm_event
.status
= IW_CM_EVENT_STATUS_RESET
;
2197 nes_debug(NES_DBG_CM
, "Generating a CM Disconnect Event (status reset) for "
2198 " QP%u, cm_id = %p. \n",
2199 nesqp
->hwqp
.qp_id
, cm_id
);
2201 cm_event
.status
= IW_CM_EVENT_STATUS_OK
;
2204 cm_event
.local_addr
= cm_id
->local_addr
;
2205 cm_event
.remote_addr
= cm_id
->remote_addr
;
2206 cm_event
.private_data
= NULL
;
2207 cm_event
.private_data_len
= 0;
2209 nes_debug(NES_DBG_CM
, "Generating a CM Disconnect Event for "
2210 " QP%u, SQ Head = %u, SQ Tail = %u. cm_id = %p, refcount = %u.\n",
2212 nesqp
->hwqp
.sq_head
, nesqp
->hwqp
.sq_tail
, cm_id
,
2213 atomic_read(&nesqp
->refcount
));
2215 spin_unlock_irqrestore(&nesqp
->lock
, flags
);
2216 ret
= cm_id
->event_handler(cm_id
, &cm_event
);
2218 nes_debug(NES_DBG_CM
, "OFA CM event_handler returned, ret=%d\n", ret
);
2219 spin_lock_irqsave(&nesqp
->lock
, flags
);
2222 nesqp
->disconn_pending
= 0;
2223 /* There might have been another AE while the lock was released */
2224 original_hw_tcp_state
= nesqp
->hw_tcp_state
;
2225 original_ibqp_state
= nesqp
->ibqp_state
;
2226 last_ae
= nesqp
->last_aeq
;
2228 if ((issued_disconnect_reset
== 0) && (nesqp
->cm_id
) &&
2229 ((original_hw_tcp_state
== NES_AEQE_TCP_STATE_CLOSED
) ||
2230 (original_hw_tcp_state
== NES_AEQE_TCP_STATE_TIME_WAIT
) ||
2231 (last_ae
== NES_AEQE_AEID_RDMAP_ROE_BAD_LLP_CLOSE
) ||
2232 (last_ae
== NES_AEQE_AEID_LLP_CONNECTION_RESET
))) {
2233 atomic_inc(&cm_closes
);
2234 nesqp
->cm_id
= NULL
;
2235 nesqp
->in_disconnect
= 0;
2236 spin_unlock_irqrestore(&nesqp
->lock
, flags
);
2237 nes_disconnect(nesqp
, 1);
2239 cm_id
->provider_data
= nesqp
;
2240 /* Send up the close complete event */
2241 cm_event
.event
= IW_CM_EVENT_CLOSE
;
2242 cm_event
.status
= IW_CM_EVENT_STATUS_OK
;
2243 cm_event
.provider_data
= cm_id
->provider_data
;
2244 cm_event
.local_addr
= cm_id
->local_addr
;
2245 cm_event
.remote_addr
= cm_id
->remote_addr
;
2246 cm_event
.private_data
= NULL
;
2247 cm_event
.private_data_len
= 0;
2249 ret
= cm_id
->event_handler(cm_id
, &cm_event
);
2251 nes_debug(NES_DBG_CM
, "OFA CM event_handler returned, ret=%d\n", ret
);
2254 cm_id
->rem_ref(cm_id
);
2256 spin_lock_irqsave(&nesqp
->lock
, flags
);
2257 if (nesqp
->flush_issued
== 0) {
2258 nesqp
->flush_issued
= 1;
2259 spin_unlock_irqrestore(&nesqp
->lock
, flags
);
2260 flush_wqes(nesvnic
->nesdev
, nesqp
, NES_CQP_FLUSH_RQ
, 1);
2262 spin_unlock_irqrestore(&nesqp
->lock
, flags
);
2265 /* This reference is from either ModifyQP or the AE processing,
2266 there is still a race here with modifyqp */
2267 nes_rem_ref(&nesqp
->ibqp
);
2270 cm_id
= nesqp
->cm_id
;
2271 spin_unlock_irqrestore(&nesqp
->lock
, flags
);
2272 /* check to see if the inbound reset beat the outbound reset */
2273 if ((!cm_id
) && (last_ae
==NES_AEQE_AEID_RESET_SENT
)) {
2274 nes_debug(NES_DBG_CM
, "QP%u: Decing refcount due to inbound reset"
2275 " beating the outbound reset.\n",
2277 nes_rem_ref(&nesqp
->ibqp
);
2281 nesqp
->disconn_pending
= 0;
2282 spin_unlock_irqrestore(&nesqp
->lock
, flags
);
2284 nes_rem_ref(&nesqp
->ibqp
);
2293 static int nes_disconnect(struct nes_qp
*nesqp
, int abrupt
)
2296 struct nes_vnic
*nesvnic
;
2297 struct nes_device
*nesdev
;
2299 nesvnic
= to_nesvnic(nesqp
->ibqp
.device
);
2303 nesdev
= nesvnic
->nesdev
;
2305 nes_debug(NES_DBG_CM
, "netdev refcnt = %u.\n",
2306 atomic_read(&nesvnic
->netdev
->refcnt
));
2308 if (nesqp
->active_conn
) {
2310 /* indicate this connection is NOT active */
2311 nesqp
->active_conn
= 0;
2313 /* Need to free the Last Streaming Mode Message */
2314 if (nesqp
->ietf_frame
) {
2315 pci_free_consistent(nesdev
->pcidev
,
2316 nesqp
->private_data_len
+sizeof(struct ietf_mpa_frame
),
2317 nesqp
->ietf_frame
, nesqp
->ietf_frame_pbase
);
2321 /* close the CM node down if it is still active */
2322 if (nesqp
->cm_node
) {
2323 nes_debug(NES_DBG_CM
, "Call close API\n");
2325 g_cm_core
->api
->close(g_cm_core
, nesqp
->cm_node
);
2326 nesqp
->cm_node
= NULL
;
2336 int nes_accept(struct iw_cm_id
*cm_id
, struct iw_cm_conn_param
*conn_param
)
2340 struct nes_qp
*nesqp
;
2341 struct nes_vnic
*nesvnic
;
2342 struct nes_device
*nesdev
;
2343 struct nes_cm_node
*cm_node
;
2344 struct nes_adapter
*adapter
;
2345 struct ib_qp_attr attr
;
2346 struct iw_cm_event cm_event
;
2347 struct nes_hw_qp_wqe
*wqe
;
2348 struct nes_v4_quad nes_quad
;
2352 ibqp
= nes_get_qp(cm_id
->device
, conn_param
->qpn
);
2356 /* get all our handles */
2357 nesqp
= to_nesqp(ibqp
);
2358 nesvnic
= to_nesvnic(nesqp
->ibqp
.device
);
2359 nesdev
= nesvnic
->nesdev
;
2360 adapter
= nesdev
->nesadapter
;
2362 nes_debug(NES_DBG_CM
, "nesvnic=%p, netdev=%p, %s\n",
2363 nesvnic
, nesvnic
->netdev
, nesvnic
->netdev
->name
);
2365 /* since this is from a listen, we were able to put node handle into cm_id */
2366 cm_node
= (struct nes_cm_node
*)cm_id
->provider_data
;
2368 /* associate the node with the QP */
2369 nesqp
->cm_node
= (void *)cm_node
;
2371 nes_debug(NES_DBG_CM
, "QP%u, cm_node=%p, jiffies = %lu\n",
2372 nesqp
->hwqp
.qp_id
, cm_node
, jiffies
);
2373 atomic_inc(&cm_accepts
);
2375 nes_debug(NES_DBG_CM
, "netdev refcnt = %u.\n",
2376 atomic_read(&nesvnic
->netdev
->refcnt
));
2378 /* allocate the ietf frame and space for private data */
2379 nesqp
->ietf_frame
= pci_alloc_consistent(nesdev
->pcidev
,
2380 sizeof(struct ietf_mpa_frame
) + conn_param
->private_data_len
,
2381 &nesqp
->ietf_frame_pbase
);
2383 if (!nesqp
->ietf_frame
) {
2384 nes_debug(NES_DBG_CM
, "Unable to allocate memory for private data\n");
2389 /* setup the MPA frame */
2390 nesqp
->private_data_len
= conn_param
->private_data_len
;
2391 memcpy(nesqp
->ietf_frame
->key
, IEFT_MPA_KEY_REP
, IETF_MPA_KEY_SIZE
);
2393 memcpy(nesqp
->ietf_frame
->priv_data
, conn_param
->private_data
,
2394 conn_param
->private_data_len
);
2396 nesqp
->ietf_frame
->priv_data_len
= cpu_to_be16(conn_param
->private_data_len
);
2397 nesqp
->ietf_frame
->rev
= mpa_version
;
2398 nesqp
->ietf_frame
->flags
= IETF_MPA_FLAGS_CRC
;
2400 /* setup our first outgoing iWarp send WQE (the IETF frame response) */
2401 wqe
= &nesqp
->hwqp
.sq_vbase
[0];
2403 if (cm_id
->remote_addr
.sin_addr
.s_addr
!= cm_id
->local_addr
.sin_addr
.s_addr
) {
2404 u64temp
= (unsigned long)nesqp
;
2405 u64temp
|= NES_SW_CONTEXT_ALIGN
>>1;
2406 set_wqe_64bit_value(wqe
->wqe_words
, NES_IWARP_SQ_WQE_COMP_CTX_LOW_IDX
,
2408 wqe
->wqe_words
[NES_IWARP_SQ_WQE_MISC_IDX
] =
2409 cpu_to_le32(NES_IWARP_SQ_WQE_STREAMING
| NES_IWARP_SQ_WQE_WRPDU
);
2410 wqe
->wqe_words
[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX
] =
2411 cpu_to_le32(conn_param
->private_data_len
+ sizeof(struct ietf_mpa_frame
));
2412 wqe
->wqe_words
[NES_IWARP_SQ_WQE_FRAG0_LOW_IDX
] =
2413 cpu_to_le32((u32
)nesqp
->ietf_frame_pbase
);
2414 wqe
->wqe_words
[NES_IWARP_SQ_WQE_FRAG0_HIGH_IDX
] =
2415 cpu_to_le32((u32
)((u64
)nesqp
->ietf_frame_pbase
>> 32));
2416 wqe
->wqe_words
[NES_IWARP_SQ_WQE_LENGTH0_IDX
] =
2417 cpu_to_le32(conn_param
->private_data_len
+ sizeof(struct ietf_mpa_frame
));
2418 wqe
->wqe_words
[NES_IWARP_SQ_WQE_STAG0_IDX
] = 0;
2420 nesqp
->nesqp_context
->ird_ord_sizes
|= cpu_to_le32(
2421 NES_QPCONTEXT_ORDIRD_LSMM_PRESENT
| NES_QPCONTEXT_ORDIRD_WRPDU
);
2423 nesqp
->nesqp_context
->ird_ord_sizes
|= cpu_to_le32((NES_QPCONTEXT_ORDIRD_LSMM_PRESENT
|
2424 NES_QPCONTEXT_ORDIRD_WRPDU
| NES_QPCONTEXT_ORDIRD_ALSMM
));
2426 nesqp
->skip_lsmm
= 1;
2429 /* Cache the cm_id in the qp */
2430 nesqp
->cm_id
= cm_id
;
2431 cm_node
->cm_id
= cm_id
;
2433 /* nesqp->cm_node = (void *)cm_id->provider_data; */
2434 cm_id
->provider_data
= nesqp
;
2435 nesqp
->active_conn
= 0;
2437 nes_cm_init_tsa_conn(nesqp
, cm_node
);
2439 nesqp
->nesqp_context
->tcpPorts
[0] = cpu_to_le16(ntohs(cm_id
->local_addr
.sin_port
));
2440 nesqp
->nesqp_context
->tcpPorts
[1] = cpu_to_le16(ntohs(cm_id
->remote_addr
.sin_port
));
2441 nesqp
->nesqp_context
->ip0
= cpu_to_le32(ntohl(cm_id
->remote_addr
.sin_addr
.s_addr
));
2443 nesqp
->nesqp_context
->misc2
|= cpu_to_le32(
2444 (u32
)PCI_FUNC(nesdev
->pcidev
->devfn
) << NES_QPCONTEXT_MISC2_SRC_IP_SHIFT
);
2446 nesqp
->nesqp_context
->arp_index_vlan
|= cpu_to_le32(
2447 nes_arp_table(nesdev
, le32_to_cpu(nesqp
->nesqp_context
->ip0
), NULL
,
2448 NES_ARP_RESOLVE
) << 16);
2450 nesqp
->nesqp_context
->ts_val_delta
= cpu_to_le32(
2451 jiffies
- nes_read_indexed(nesdev
, NES_IDX_TCP_NOW
));
2453 nesqp
->nesqp_context
->ird_index
= cpu_to_le32(nesqp
->hwqp
.qp_id
);
2455 nesqp
->nesqp_context
->ird_ord_sizes
|= cpu_to_le32(
2456 ((u32
)1 << NES_QPCONTEXT_ORDIRD_IWARP_MODE_SHIFT
));
2457 nesqp
->nesqp_context
->ird_ord_sizes
|= cpu_to_le32((u32
)conn_param
->ord
);
2459 memset(&nes_quad
, 0, sizeof(nes_quad
));
2460 nes_quad
.DstIpAdrIndex
= cpu_to_le32((u32
)PCI_FUNC(nesdev
->pcidev
->devfn
) << 24);
2461 nes_quad
.SrcIpadr
= cm_id
->remote_addr
.sin_addr
.s_addr
;
2462 nes_quad
.TcpPorts
[0] = cm_id
->remote_addr
.sin_port
;
2463 nes_quad
.TcpPorts
[1] = cm_id
->local_addr
.sin_port
;
2465 /* Produce hash key */
2466 crc_value
= get_crc_value(&nes_quad
);
2467 nesqp
->hte_index
= cpu_to_be32(crc_value
^ 0xffffffff);
2468 nes_debug(NES_DBG_CM
, "HTE Index = 0x%08X, CRC = 0x%08X\n",
2469 nesqp
->hte_index
, nesqp
->hte_index
& adapter
->hte_index_mask
);
2471 nesqp
->hte_index
&= adapter
->hte_index_mask
;
2472 nesqp
->nesqp_context
->hte_index
= cpu_to_le32(nesqp
->hte_index
);
2474 cm_node
->cm_core
->api
->accelerated(cm_node
->cm_core
, cm_node
);
2476 nes_debug(NES_DBG_CM
, "QP%u, Destination IP = 0x%08X:0x%04X, local = 0x%08X:0x%04X,"
2477 " rcv_nxt=0x%08X, snd_nxt=0x%08X, mpa + private data length=%zu.\n",
2479 ntohl(cm_id
->remote_addr
.sin_addr
.s_addr
),
2480 ntohs(cm_id
->remote_addr
.sin_port
),
2481 ntohl(cm_id
->local_addr
.sin_addr
.s_addr
),
2482 ntohs(cm_id
->local_addr
.sin_port
),
2483 le32_to_cpu(nesqp
->nesqp_context
->rcv_nxt
),
2484 le32_to_cpu(nesqp
->nesqp_context
->snd_nxt
),
2485 conn_param
->private_data_len
+sizeof(struct ietf_mpa_frame
));
2487 attr
.qp_state
= IB_QPS_RTS
;
2488 nes_modify_qp(&nesqp
->ibqp
, &attr
, IB_QP_STATE
, NULL
);
2490 /* notify OF layer that accept event was successfull */
2491 cm_id
->add_ref(cm_id
);
2493 cm_event
.event
= IW_CM_EVENT_ESTABLISHED
;
2494 cm_event
.status
= IW_CM_EVENT_STATUS_ACCEPTED
;
2495 cm_event
.provider_data
= (void *)nesqp
;
2496 cm_event
.local_addr
= cm_id
->local_addr
;
2497 cm_event
.remote_addr
= cm_id
->remote_addr
;
2498 cm_event
.private_data
= NULL
;
2499 cm_event
.private_data_len
= 0;
2500 ret
= cm_id
->event_handler(cm_id
, &cm_event
);
2501 if (cm_node
->loopbackpartner
) {
2502 cm_node
->loopbackpartner
->mpa_frame_size
= nesqp
->private_data_len
;
2503 /* copy entire MPA frame to our cm_node's frame */
2504 memcpy(cm_node
->loopbackpartner
->mpa_frame_buf
, nesqp
->ietf_frame
->priv_data
,
2505 nesqp
->private_data_len
);
2506 create_event(cm_node
->loopbackpartner
, NES_CM_EVENT_CONNECTED
);
2509 printk("%s[%u] OFA CM event_handler returned, ret=%d\n",
2510 __FUNCTION__
, __LINE__
, ret
);
2519 int nes_reject(struct iw_cm_id
*cm_id
, const void *pdata
, u8 pdata_len
)
2521 struct nes_cm_node
*cm_node
;
2522 struct nes_cm_core
*cm_core
;
2524 atomic_inc(&cm_rejects
);
2525 cm_node
= (struct nes_cm_node
*) cm_id
->provider_data
;
2526 cm_core
= cm_node
->cm_core
;
2527 cm_node
->mpa_frame_size
= sizeof(struct ietf_mpa_frame
) + pdata_len
;
2529 strcpy(&cm_node
->mpa_frame
.key
[0], IEFT_MPA_KEY_REP
);
2530 memcpy(&cm_node
->mpa_frame
.priv_data
, pdata
, pdata_len
);
2532 cm_node
->mpa_frame
.priv_data_len
= cpu_to_be16(pdata_len
);
2533 cm_node
->mpa_frame
.rev
= mpa_version
;
2534 cm_node
->mpa_frame
.flags
= IETF_MPA_FLAGS_CRC
| IETF_MPA_FLAGS_REJECT
;
2536 cm_core
->api
->reject(cm_core
, &cm_node
->mpa_frame
, cm_node
);
2544 * setup and launch cm connect node
2546 int nes_connect(struct iw_cm_id
*cm_id
, struct iw_cm_conn_param
*conn_param
)
2549 struct nes_qp
*nesqp
;
2550 struct nes_vnic
*nesvnic
;
2551 struct nes_device
*nesdev
;
2552 struct nes_cm_node
*cm_node
;
2553 struct nes_cm_info cm_info
;
2555 ibqp
= nes_get_qp(cm_id
->device
, conn_param
->qpn
);
2558 nesqp
= to_nesqp(ibqp
);
2561 nesvnic
= to_nesvnic(nesqp
->ibqp
.device
);
2564 nesdev
= nesvnic
->nesdev
;
2568 atomic_inc(&cm_connects
);
2570 nesqp
->ietf_frame
= kzalloc(sizeof(struct ietf_mpa_frame
) +
2571 conn_param
->private_data_len
, GFP_KERNEL
);
2572 if (!nesqp
->ietf_frame
)
2575 /* set qp as having an active connection */
2576 nesqp
->active_conn
= 1;
2578 nes_debug(NES_DBG_CM
, "QP%u, Destination IP = 0x%08X:0x%04X, local = 0x%08X:0x%04X.\n",
2580 ntohl(cm_id
->remote_addr
.sin_addr
.s_addr
),
2581 ntohs(cm_id
->remote_addr
.sin_port
),
2582 ntohl(cm_id
->local_addr
.sin_addr
.s_addr
),
2583 ntohs(cm_id
->local_addr
.sin_port
));
2585 /* cache the cm_id in the qp */
2586 nesqp
->cm_id
= cm_id
;
2588 cm_id
->provider_data
= nesqp
;
2590 /* copy the private data */
2591 if (conn_param
->private_data_len
) {
2592 memcpy(nesqp
->ietf_frame
->priv_data
, conn_param
->private_data
,
2593 conn_param
->private_data_len
);
2596 nesqp
->private_data_len
= conn_param
->private_data_len
;
2597 nesqp
->nesqp_context
->ird_ord_sizes
|= cpu_to_le32((u32
)conn_param
->ord
);
2598 nes_debug(NES_DBG_CM
, "requested ord = 0x%08X.\n", (u32
)conn_param
->ord
);
2599 nes_debug(NES_DBG_CM
, "mpa private data len =%u\n", conn_param
->private_data_len
);
2601 strcpy(&nesqp
->ietf_frame
->key
[0], IEFT_MPA_KEY_REQ
);
2602 nesqp
->ietf_frame
->flags
= IETF_MPA_FLAGS_CRC
;
2603 nesqp
->ietf_frame
->rev
= IETF_MPA_VERSION
;
2604 nesqp
->ietf_frame
->priv_data_len
= htons(conn_param
->private_data_len
);
2606 if (cm_id
->local_addr
.sin_addr
.s_addr
!= cm_id
->remote_addr
.sin_addr
.s_addr
)
2607 nes_manage_apbvt(nesvnic
, ntohs(cm_id
->local_addr
.sin_port
),
2608 PCI_FUNC(nesdev
->pcidev
->devfn
), NES_MANAGE_APBVT_ADD
);
2610 /* set up the connection params for the node */
2611 cm_info
.loc_addr
= (cm_id
->local_addr
.sin_addr
.s_addr
);
2612 cm_info
.loc_port
= (cm_id
->local_addr
.sin_port
);
2613 cm_info
.rem_addr
= (cm_id
->remote_addr
.sin_addr
.s_addr
);
2614 cm_info
.rem_port
= (cm_id
->remote_addr
.sin_port
);
2615 cm_info
.cm_id
= cm_id
;
2616 cm_info
.conn_type
= NES_CM_IWARP_CONN_TYPE
;
2618 cm_id
->add_ref(cm_id
);
2619 nes_add_ref(&nesqp
->ibqp
);
2621 /* create a connect CM node connection */
2622 cm_node
= g_cm_core
->api
->connect(g_cm_core
, nesvnic
, nesqp
->ietf_frame
, &cm_info
);
2624 if (cm_id
->local_addr
.sin_addr
.s_addr
!= cm_id
->remote_addr
.sin_addr
.s_addr
)
2625 nes_manage_apbvt(nesvnic
, ntohs(cm_id
->local_addr
.sin_port
),
2626 PCI_FUNC(nesdev
->pcidev
->devfn
), NES_MANAGE_APBVT_DEL
);
2627 nes_rem_ref(&nesqp
->ibqp
);
2628 kfree(nesqp
->ietf_frame
);
2629 nesqp
->ietf_frame
= NULL
;
2630 cm_id
->rem_ref(cm_id
);
2634 cm_node
->apbvt_set
= 1;
2635 nesqp
->cm_node
= cm_node
;
2644 int nes_create_listen(struct iw_cm_id
*cm_id
, int backlog
)
2646 struct nes_vnic
*nesvnic
;
2647 struct nes_cm_listener
*cm_node
;
2648 struct nes_cm_info cm_info
;
2649 struct nes_adapter
*adapter
;
2653 nes_debug(NES_DBG_CM
, "cm_id = %p, local port = 0x%04X.\n",
2654 cm_id
, ntohs(cm_id
->local_addr
.sin_port
));
2656 nesvnic
= to_nesvnic(cm_id
->device
);
2659 adapter
= nesvnic
->nesdev
->nesadapter
;
2660 nes_debug(NES_DBG_CM
, "nesvnic=%p, netdev=%p, %s\n",
2661 nesvnic
, nesvnic
->netdev
, nesvnic
->netdev
->name
);
2663 nes_debug(NES_DBG_CM
, "nesvnic->local_ipaddr=0x%08x, sin_addr.s_addr=0x%08x\n",
2664 nesvnic
->local_ipaddr
, cm_id
->local_addr
.sin_addr
.s_addr
);
2666 /* setup listen params in our api call struct */
2667 cm_info
.loc_addr
= nesvnic
->local_ipaddr
;
2668 cm_info
.loc_port
= cm_id
->local_addr
.sin_port
;
2669 cm_info
.backlog
= backlog
;
2670 cm_info
.cm_id
= cm_id
;
2672 cm_info
.conn_type
= NES_CM_IWARP_CONN_TYPE
;
2675 cm_node
= g_cm_core
->api
->listen(g_cm_core
, nesvnic
, &cm_info
);
2677 printk("%s[%u] Error returned from listen API call\n",
2678 __FUNCTION__
, __LINE__
);
2682 cm_id
->provider_data
= cm_node
;
2684 if (!cm_node
->reused_node
) {
2685 err
= nes_manage_apbvt(nesvnic
, ntohs(cm_id
->local_addr
.sin_port
),
2686 PCI_FUNC(nesvnic
->nesdev
->pcidev
->devfn
), NES_MANAGE_APBVT_ADD
);
2688 printk("nes_manage_apbvt call returned %d.\n", err
);
2689 g_cm_core
->api
->stop_listener(g_cm_core
, (void *)cm_node
);
2692 cm_listens_created
++;
2695 cm_id
->add_ref(cm_id
);
2696 cm_id
->provider_data
= (void *)cm_node
;
2704 * nes_destroy_listen
2706 int nes_destroy_listen(struct iw_cm_id
*cm_id
)
2708 if (cm_id
->provider_data
)
2709 g_cm_core
->api
->stop_listener(g_cm_core
, cm_id
->provider_data
);
2711 nes_debug(NES_DBG_CM
, "cm_id->provider_data was NULL\n");
2713 cm_id
->rem_ref(cm_id
);
2722 int nes_cm_recv(struct sk_buff
*skb
, struct net_device
*netdevice
)
2724 cm_packets_received
++;
2725 if ((g_cm_core
) && (g_cm_core
->api
)) {
2726 g_cm_core
->api
->recv_pkt(g_cm_core
, netdev_priv(netdevice
), skb
);
2728 nes_debug(NES_DBG_CM
, "Unable to process packet for CM,"
2729 " cm is not setup properly.\n");
2738 * Start and init a cm core module
2740 int nes_cm_start(void)
2742 nes_debug(NES_DBG_CM
, "\n");
2743 /* create the primary CM core, pass this handle to subsequent core inits */
2744 g_cm_core
= nes_cm_alloc_core();
2755 * stop and dealloc all cm core instances
2757 int nes_cm_stop(void)
2759 g_cm_core
->api
->destroy_cm_core(g_cm_core
);
2765 * cm_event_connected
2766 * handle a connected event, setup QPs and HW
2768 static void cm_event_connected(struct nes_cm_event
*event
)
2771 struct nes_qp
*nesqp
;
2772 struct nes_vnic
*nesvnic
;
2773 struct nes_device
*nesdev
;
2774 struct nes_cm_node
*cm_node
;
2775 struct nes_adapter
*nesadapter
;
2776 struct ib_qp_attr attr
;
2777 struct iw_cm_id
*cm_id
;
2778 struct iw_cm_event cm_event
;
2779 struct nes_hw_qp_wqe
*wqe
;
2780 struct nes_v4_quad nes_quad
;
2784 /* get all our handles */
2785 cm_node
= event
->cm_node
;
2786 cm_id
= cm_node
->cm_id
;
2787 nes_debug(NES_DBG_CM
, "cm_event_connected - %p - cm_id = %p\n", cm_node
, cm_id
);
2788 nesqp
= (struct nes_qp
*)cm_id
->provider_data
;
2789 nesvnic
= to_nesvnic(nesqp
->ibqp
.device
);
2790 nesdev
= nesvnic
->nesdev
;
2791 nesadapter
= nesdev
->nesadapter
;
2793 if (nesqp
->destroyed
) {
2796 atomic_inc(&cm_connecteds
);
2797 nes_debug(NES_DBG_CM
, "QP%u attempting to connect to 0x%08X:0x%04X on"
2798 " local port 0x%04X. jiffies = %lu.\n",
2800 ntohl(cm_id
->remote_addr
.sin_addr
.s_addr
),
2801 ntohs(cm_id
->remote_addr
.sin_port
),
2802 ntohs(cm_id
->local_addr
.sin_port
),
2805 nes_cm_init_tsa_conn(nesqp
, cm_node
);
2807 /* set the QP tsa context */
2808 nesqp
->nesqp_context
->tcpPorts
[0] = cpu_to_le16(ntohs(cm_id
->local_addr
.sin_port
));
2809 nesqp
->nesqp_context
->tcpPorts
[1] = cpu_to_le16(ntohs(cm_id
->remote_addr
.sin_port
));
2810 nesqp
->nesqp_context
->ip0
= cpu_to_le32(ntohl(cm_id
->remote_addr
.sin_addr
.s_addr
));
2812 nesqp
->nesqp_context
->misc2
|= cpu_to_le32(
2813 (u32
)PCI_FUNC(nesdev
->pcidev
->devfn
) << NES_QPCONTEXT_MISC2_SRC_IP_SHIFT
);
2814 nesqp
->nesqp_context
->arp_index_vlan
|= cpu_to_le32(
2815 nes_arp_table(nesdev
, le32_to_cpu(nesqp
->nesqp_context
->ip0
),
2816 NULL
, NES_ARP_RESOLVE
) << 16);
2817 nesqp
->nesqp_context
->ts_val_delta
= cpu_to_le32(
2818 jiffies
- nes_read_indexed(nesdev
, NES_IDX_TCP_NOW
));
2819 nesqp
->nesqp_context
->ird_index
= cpu_to_le32(nesqp
->hwqp
.qp_id
);
2820 nesqp
->nesqp_context
->ird_ord_sizes
|=
2821 cpu_to_le32((u32
)1 << NES_QPCONTEXT_ORDIRD_IWARP_MODE_SHIFT
);
2823 /* Adjust tail for not having a LSMM */
2824 nesqp
->hwqp
.sq_tail
= 1;
2826 #if defined(NES_SEND_FIRST_WRITE)
2827 if (cm_node
->send_write0
) {
2828 nes_debug(NES_DBG_CM
, "Sending first write.\n");
2829 wqe
= &nesqp
->hwqp
.sq_vbase
[0];
2830 u64temp
= (unsigned long)nesqp
;
2831 u64temp
|= NES_SW_CONTEXT_ALIGN
>>1;
2832 set_wqe_64bit_value(wqe
->wqe_words
, NES_IWARP_SQ_WQE_COMP_CTX_LOW_IDX
,
2834 wqe
->wqe_words
[NES_IWARP_SQ_WQE_MISC_IDX
] = cpu_to_le32(NES_IWARP_SQ_OP_RDMAW
);
2835 wqe
->wqe_words
[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX
] = 0;
2836 wqe
->wqe_words
[NES_IWARP_SQ_WQE_FRAG0_LOW_IDX
] = 0;
2837 wqe
->wqe_words
[NES_IWARP_SQ_WQE_FRAG0_HIGH_IDX
] = 0;
2838 wqe
->wqe_words
[NES_IWARP_SQ_WQE_LENGTH0_IDX
] = 0;
2839 wqe
->wqe_words
[NES_IWARP_SQ_WQE_STAG0_IDX
] = 0;
2841 /* use the reserved spot on the WQ for the extra first WQE */
2842 nesqp
->nesqp_context
->ird_ord_sizes
&= cpu_to_le32(~(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT
|
2843 NES_QPCONTEXT_ORDIRD_WRPDU
| NES_QPCONTEXT_ORDIRD_ALSMM
));
2844 nesqp
->skip_lsmm
= 1;
2845 nesqp
->hwqp
.sq_tail
= 0;
2846 nes_write32(nesdev
->regs
+ NES_WQE_ALLOC
,
2847 (1 << 24) | 0x00800000 | nesqp
->hwqp
.qp_id
);
2851 memset(&nes_quad
, 0, sizeof(nes_quad
));
2853 nes_quad
.DstIpAdrIndex
= cpu_to_le32((u32
)PCI_FUNC(nesdev
->pcidev
->devfn
) << 24);
2854 nes_quad
.SrcIpadr
= cm_id
->remote_addr
.sin_addr
.s_addr
;
2855 nes_quad
.TcpPorts
[0] = cm_id
->remote_addr
.sin_port
;
2856 nes_quad
.TcpPorts
[1] = cm_id
->local_addr
.sin_port
;
2858 /* Produce hash key */
2859 crc_value
= get_crc_value(&nes_quad
);
2860 nesqp
->hte_index
= cpu_to_be32(crc_value
^ 0xffffffff);
2861 nes_debug(NES_DBG_CM
, "HTE Index = 0x%08X, After CRC = 0x%08X\n",
2862 nesqp
->hte_index
, nesqp
->hte_index
& nesadapter
->hte_index_mask
);
2864 nesqp
->hte_index
&= nesadapter
->hte_index_mask
;
2865 nesqp
->nesqp_context
->hte_index
= cpu_to_le32(nesqp
->hte_index
);
2867 nesqp
->ietf_frame
= &cm_node
->mpa_frame
;
2868 nesqp
->private_data_len
= (u8
) cm_node
->mpa_frame_size
;
2869 cm_node
->cm_core
->api
->accelerated(cm_node
->cm_core
, cm_node
);
2871 /* modify QP state to rts */
2872 attr
.qp_state
= IB_QPS_RTS
;
2873 nes_modify_qp(&nesqp
->ibqp
, &attr
, IB_QP_STATE
, NULL
);
2875 /* notify OF layer we successfully created the requested connection */
2876 cm_event
.event
= IW_CM_EVENT_CONNECT_REPLY
;
2877 cm_event
.status
= IW_CM_EVENT_STATUS_ACCEPTED
;
2878 cm_event
.provider_data
= cm_id
->provider_data
;
2879 cm_event
.local_addr
.sin_family
= AF_INET
;
2880 cm_event
.local_addr
.sin_port
= cm_id
->local_addr
.sin_port
;
2881 cm_event
.remote_addr
= cm_id
->remote_addr
;
2883 cm_event
.private_data
= (void *)event
->cm_node
->mpa_frame_buf
;
2884 cm_event
.private_data_len
= (u8
) event
->cm_node
->mpa_frame_size
;
2886 cm_event
.local_addr
.sin_addr
.s_addr
= event
->cm_info
.rem_addr
;
2887 ret
= cm_id
->event_handler(cm_id
, &cm_event
);
2888 nes_debug(NES_DBG_CM
, "OFA CM event_handler returned, ret=%d\n", ret
);
2891 printk("%s[%u] OFA CM event_handler returned, ret=%d\n",
2892 __FUNCTION__
, __LINE__
, ret
);
2893 nes_debug(NES_DBG_CM
, "Exiting connect thread for QP%u. jiffies = %lu\n",
2894 nesqp
->hwqp
.qp_id
, jiffies
);
2896 nes_rem_ref(&nesqp
->ibqp
);
2903 * cm_event_connect_error
2905 static void cm_event_connect_error(struct nes_cm_event
*event
)
2907 struct nes_qp
*nesqp
;
2908 struct iw_cm_id
*cm_id
;
2909 struct iw_cm_event cm_event
;
2910 /* struct nes_cm_info cm_info; */
2913 if (!event
->cm_node
)
2916 cm_id
= event
->cm_node
->cm_id
;
2921 nes_debug(NES_DBG_CM
, "cm_node=%p, cm_id=%p\n", event
->cm_node
, cm_id
);
2922 nesqp
= cm_id
->provider_data
;
2928 /* notify OF layer about this connection error event */
2929 /* cm_id->rem_ref(cm_id); */
2930 nesqp
->cm_id
= NULL
;
2931 cm_id
->provider_data
= NULL
;
2932 cm_event
.event
= IW_CM_EVENT_CONNECT_REPLY
;
2933 cm_event
.status
= IW_CM_EVENT_STATUS_REJECTED
;
2934 cm_event
.provider_data
= cm_id
->provider_data
;
2935 cm_event
.local_addr
= cm_id
->local_addr
;
2936 cm_event
.remote_addr
= cm_id
->remote_addr
;
2937 cm_event
.private_data
= NULL
;
2938 cm_event
.private_data_len
= 0;
2940 nes_debug(NES_DBG_CM
, "call CM_EVENT REJECTED, local_addr=%08x, remove_addr=%08x\n",
2941 cm_event
.local_addr
.sin_addr
.s_addr
, cm_event
.remote_addr
.sin_addr
.s_addr
);
2943 ret
= cm_id
->event_handler(cm_id
, &cm_event
);
2944 nes_debug(NES_DBG_CM
, "OFA CM event_handler returned, ret=%d\n", ret
);
2946 printk("%s[%u] OFA CM event_handler returned, ret=%d\n",
2947 __FUNCTION__
, __LINE__
, ret
);
2948 nes_rem_ref(&nesqp
->ibqp
);
2949 cm_id
->rem_ref(cm_id
);
2958 static void cm_event_reset(struct nes_cm_event
*event
)
2960 struct nes_qp
*nesqp
;
2961 struct iw_cm_id
*cm_id
;
2962 struct iw_cm_event cm_event
;
2963 /* struct nes_cm_info cm_info; */
2966 if (!event
->cm_node
)
2969 if (!event
->cm_node
->cm_id
)
2972 cm_id
= event
->cm_node
->cm_id
;
2974 nes_debug(NES_DBG_CM
, "%p - cm_id = %p\n", event
->cm_node
, cm_id
);
2975 nesqp
= cm_id
->provider_data
;
2977 nesqp
->cm_id
= NULL
;
2978 /* cm_id->provider_data = NULL; */
2979 cm_event
.event
= IW_CM_EVENT_DISCONNECT
;
2980 cm_event
.status
= IW_CM_EVENT_STATUS_RESET
;
2981 cm_event
.provider_data
= cm_id
->provider_data
;
2982 cm_event
.local_addr
= cm_id
->local_addr
;
2983 cm_event
.remote_addr
= cm_id
->remote_addr
;
2984 cm_event
.private_data
= NULL
;
2985 cm_event
.private_data_len
= 0;
2987 ret
= cm_id
->event_handler(cm_id
, &cm_event
);
2988 nes_debug(NES_DBG_CM
, "OFA CM event_handler returned, ret=%d\n", ret
);
2991 /* notify OF layer about this connection error event */
2992 cm_id
->rem_ref(cm_id
);
3001 static void cm_event_mpa_req(struct nes_cm_event
*event
)
3003 struct iw_cm_id
*cm_id
;
3004 struct iw_cm_event cm_event
;
3006 struct nes_cm_node
*cm_node
;
3008 cm_node
= event
->cm_node
;
3011 cm_id
= cm_node
->cm_id
;
3013 atomic_inc(&cm_connect_reqs
);
3014 nes_debug(NES_DBG_CM
, "cm_node = %p - cm_id = %p, jiffies = %lu\n",
3015 cm_node
, cm_id
, jiffies
);
3017 cm_event
.event
= IW_CM_EVENT_CONNECT_REQUEST
;
3018 cm_event
.status
= IW_CM_EVENT_STATUS_OK
;
3019 cm_event
.provider_data
= (void *)cm_node
;
3021 cm_event
.local_addr
.sin_family
= AF_INET
;
3022 cm_event
.local_addr
.sin_port
= htons(event
->cm_info
.loc_port
);
3023 cm_event
.local_addr
.sin_addr
.s_addr
= htonl(event
->cm_info
.loc_addr
);
3025 cm_event
.remote_addr
.sin_family
= AF_INET
;
3026 cm_event
.remote_addr
.sin_port
= htons(event
->cm_info
.rem_port
);
3027 cm_event
.remote_addr
.sin_addr
.s_addr
= htonl(event
->cm_info
.rem_addr
);
3029 cm_event
.private_data
= cm_node
->mpa_frame_buf
;
3030 cm_event
.private_data_len
= (u8
) cm_node
->mpa_frame_size
;
3032 ret
= cm_id
->event_handler(cm_id
, &cm_event
);
3034 printk("%s[%u] OFA CM event_handler returned, ret=%d\n",
3035 __FUNCTION__
, __LINE__
, ret
);
3041 static void nes_cm_event_handler(struct work_struct
*);
3045 * post an event to the cm event handler
3047 static int nes_cm_post_event(struct nes_cm_event
*event
)
3049 atomic_inc(&event
->cm_node
->cm_core
->events_posted
);
3050 add_ref_cm_node(event
->cm_node
);
3051 event
->cm_info
.cm_id
->add_ref(event
->cm_info
.cm_id
);
3052 INIT_WORK(&event
->event_work
, nes_cm_event_handler
);
3053 nes_debug(NES_DBG_CM
, "queue_work, event=%p\n", event
);
3055 queue_work(event
->cm_node
->cm_core
->event_wq
, &event
->event_work
);
3057 nes_debug(NES_DBG_CM
, "Exit\n");
3063 * nes_cm_event_handler
3064 * worker function to handle cm events
3065 * will free instance of nes_cm_event
3067 static void nes_cm_event_handler(struct work_struct
*work
)
3069 struct nes_cm_event
*event
= container_of(work
, struct nes_cm_event
, event_work
);
3070 struct nes_cm_core
*cm_core
;
3072 if ((!event
) || (!event
->cm_node
) || (!event
->cm_node
->cm_core
)) {
3075 cm_core
= event
->cm_node
->cm_core
;
3076 nes_debug(NES_DBG_CM
, "event=%p, event->type=%u, events posted=%u\n",
3077 event
, event
->type
, atomic_read(&cm_core
->events_posted
));
3079 switch (event
->type
) {
3080 case NES_CM_EVENT_MPA_REQ
:
3081 cm_event_mpa_req(event
);
3082 nes_debug(NES_DBG_CM
, "CM Event: MPA REQUEST\n");
3084 case NES_CM_EVENT_RESET
:
3085 nes_debug(NES_DBG_CM
, "CM Event: RESET\n");
3086 cm_event_reset(event
);
3088 case NES_CM_EVENT_CONNECTED
:
3089 if ((!event
->cm_node
->cm_id
) ||
3090 (event
->cm_node
->state
!= NES_CM_STATE_TSA
)) {
3093 cm_event_connected(event
);
3094 nes_debug(NES_DBG_CM
, "CM Event: CONNECTED\n");
3096 case NES_CM_EVENT_ABORTED
:
3097 if ((!event
->cm_node
->cm_id
) || (event
->cm_node
->state
== NES_CM_STATE_TSA
)) {
3100 cm_event_connect_error(event
);
3101 nes_debug(NES_DBG_CM
, "CM Event: ABORTED\n");
3103 case NES_CM_EVENT_DROPPED_PKT
:
3104 nes_debug(NES_DBG_CM
, "CM Event: DROPPED PKT\n");
3107 nes_debug(NES_DBG_CM
, "CM Event: UNKNOWN EVENT TYPE\n");
3111 atomic_dec(&cm_core
->events_posted
);
3112 event
->cm_info
.cm_id
->rem_ref(event
->cm_info
.cm_id
);
3113 rem_ref_cm_node(cm_core
, event
->cm_node
);