aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorFaisal Latif <flatif@neteffect.com>2008-07-24 23:50:45 -0400
committerRoland Dreier <rolandd@cisco.com>2008-07-24 23:50:45 -0400
commit6492cdf3a24fd620660c399745b5e169a0ed27d6 (patch)
tree474a0e937cda0b4cff70bc47a657d8338fb91d22 /drivers/infiniband
parentfb2e405fc1fc8b20d9c78eaa1c7fd5a297efde43 (diff)
RDMA/nes: CM connection setup/teardown rework
Major rework of CM connection setup/teardown. We had a number of issues with MPI applications not starting/terminating properly over time. With these changes we were able to run longer on larger clusters. * Remove memory allocation from nes_connect() and nes_cm_connect(). * Fix mini_cm_dec_refcnt_listen() when destroying listener. * Remove unnecessary code from schedule_nes_timer() and nes_cm_timer_tick(). * Functionalize mini_cm_recv_pkt() and process_packet(). * Clean up cm_node->ref_count usage. * Reuse skbs if available. Signed-off-by: Faisal Latif <flatif@neteffect.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/nes/nes.c4
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.c2034
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.h23
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.c9
-rw-r--r--drivers/infiniband/hw/nes/nes_verbs.c15
5 files changed, 1156 insertions, 929 deletions
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
index d2884e778098..b0cab64e5e3d 100644
--- a/drivers/infiniband/hw/nes/nes.c
+++ b/drivers/infiniband/hw/nes/nes.c
@@ -276,6 +276,7 @@ static void nes_cqp_rem_ref_callback(struct nes_device *nesdev, struct nes_cqp_r
276 } 276 }
277 nes_free_resource(nesadapter, nesadapter->allocated_qps, nesqp->hwqp.qp_id); 277 nes_free_resource(nesadapter, nesadapter->allocated_qps, nesqp->hwqp.qp_id);
278 278
279 nesadapter->qp_table[nesqp->hwqp.qp_id-NES_FIRST_QPN] = NULL;
279 kfree(nesqp->allocated_buffer); 280 kfree(nesqp->allocated_buffer);
280 281
281} 282}
@@ -289,7 +290,6 @@ void nes_rem_ref(struct ib_qp *ibqp)
289 struct nes_qp *nesqp; 290 struct nes_qp *nesqp;
290 struct nes_vnic *nesvnic = to_nesvnic(ibqp->device); 291 struct nes_vnic *nesvnic = to_nesvnic(ibqp->device);
291 struct nes_device *nesdev = nesvnic->nesdev; 292 struct nes_device *nesdev = nesvnic->nesdev;
292 struct nes_adapter *nesadapter = nesdev->nesadapter;
293 struct nes_hw_cqp_wqe *cqp_wqe; 293 struct nes_hw_cqp_wqe *cqp_wqe;
294 struct nes_cqp_request *cqp_request; 294 struct nes_cqp_request *cqp_request;
295 u32 opcode; 295 u32 opcode;
@@ -303,8 +303,6 @@ void nes_rem_ref(struct ib_qp *ibqp)
303 } 303 }
304 304
305 if (atomic_dec_and_test(&nesqp->refcount)) { 305 if (atomic_dec_and_test(&nesqp->refcount)) {
306 nesadapter->qp_table[nesqp->hwqp.qp_id-NES_FIRST_QPN] = NULL;
307
308 /* Destroy the QP */ 306 /* Destroy the QP */
309 cqp_request = nes_get_cqp_request(nesdev); 307 cqp_request = nes_get_cqp_request(nesdev);
310 if (cqp_request == NULL) { 308 if (cqp_request == NULL) {
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index 6aa531d5276d..9f0b964b2c99 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -74,36 +74,59 @@ atomic_t cm_nodes_destroyed;
74atomic_t cm_accel_dropped_pkts; 74atomic_t cm_accel_dropped_pkts;
75atomic_t cm_resets_recvd; 75atomic_t cm_resets_recvd;
76 76
77static inline int mini_cm_accelerated(struct nes_cm_core *, struct nes_cm_node *); 77static inline int mini_cm_accelerated(struct nes_cm_core *,
78 struct nes_cm_node *);
78static struct nes_cm_listener *mini_cm_listen(struct nes_cm_core *, 79static struct nes_cm_listener *mini_cm_listen(struct nes_cm_core *,
79 struct nes_vnic *, struct nes_cm_info *); 80 struct nes_vnic *, struct nes_cm_info *);
80static int add_ref_cm_node(struct nes_cm_node *);
81static int rem_ref_cm_node(struct nes_cm_core *, struct nes_cm_node *);
82static int mini_cm_del_listen(struct nes_cm_core *, struct nes_cm_listener *); 81static int mini_cm_del_listen(struct nes_cm_core *, struct nes_cm_listener *);
83static struct sk_buff *form_cm_frame(struct sk_buff *, struct nes_cm_node *,
84 void *, u32, void *, u32, u8);
85static struct sk_buff *get_free_pkt(struct nes_cm_node *cm_node);
86
87static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *, 82static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *,
88 struct nes_vnic *, 83 struct nes_vnic *, u16, void *, struct nes_cm_info *);
89 struct ietf_mpa_frame *, 84static int mini_cm_close(struct nes_cm_core *, struct nes_cm_node *);
90 struct nes_cm_info *);
91static int mini_cm_accept(struct nes_cm_core *, struct ietf_mpa_frame *, 85static int mini_cm_accept(struct nes_cm_core *, struct ietf_mpa_frame *,
92 struct nes_cm_node *); 86 struct nes_cm_node *);
93static int mini_cm_reject(struct nes_cm_core *, struct ietf_mpa_frame *, 87static int mini_cm_reject(struct nes_cm_core *, struct ietf_mpa_frame *,
94 struct nes_cm_node *); 88 struct nes_cm_node *);
95static int mini_cm_close(struct nes_cm_core *, struct nes_cm_node *); 89static void mini_cm_recv_pkt(struct nes_cm_core *, struct nes_vnic *,
96static int mini_cm_recv_pkt(struct nes_cm_core *, struct nes_vnic *, 90 struct sk_buff *);
97 struct sk_buff *);
98static int mini_cm_dealloc_core(struct nes_cm_core *); 91static int mini_cm_dealloc_core(struct nes_cm_core *);
99static int mini_cm_get(struct nes_cm_core *); 92static int mini_cm_get(struct nes_cm_core *);
100static int mini_cm_set(struct nes_cm_core *, u32, u32); 93static int mini_cm_set(struct nes_cm_core *, u32, u32);
94
95static struct sk_buff *form_cm_frame(struct sk_buff *, struct nes_cm_node *,
96 void *, u32, void *, u32, u8);
97static struct sk_buff *get_free_pkt(struct nes_cm_node *cm_node);
98static int add_ref_cm_node(struct nes_cm_node *);
99static int rem_ref_cm_node(struct nes_cm_core *, struct nes_cm_node *);
100
101static int nes_cm_disconn_true(struct nes_qp *); 101static int nes_cm_disconn_true(struct nes_qp *);
102static int nes_cm_post_event(struct nes_cm_event *event); 102static int nes_cm_post_event(struct nes_cm_event *event);
103static int nes_disconnect(struct nes_qp *nesqp, int abrupt); 103static int nes_disconnect(struct nes_qp *nesqp, int abrupt);
104static void nes_disconnect_worker(struct work_struct *work); 104static void nes_disconnect_worker(struct work_struct *work);
105static int send_ack(struct nes_cm_node *cm_node); 105
106static int send_mpa_request(struct nes_cm_node *, struct sk_buff *);
107static int send_syn(struct nes_cm_node *, u32, struct sk_buff *);
108static int send_reset(struct nes_cm_node *, struct sk_buff *);
109static int send_ack(struct nes_cm_node *cm_node, struct sk_buff *skb);
106static int send_fin(struct nes_cm_node *cm_node, struct sk_buff *skb); 110static int send_fin(struct nes_cm_node *cm_node, struct sk_buff *skb);
111static void process_packet(struct nes_cm_node *, struct sk_buff *,
112 struct nes_cm_core *);
113
114static void active_open_err(struct nes_cm_node *, struct sk_buff *, int);
115static void passive_open_err(struct nes_cm_node *, struct sk_buff *, int);
116static void cleanup_retrans_entry(struct nes_cm_node *);
117static void handle_rcv_mpa(struct nes_cm_node *, struct sk_buff *,
118 enum nes_cm_event_type);
119static void free_retrans_entry(struct nes_cm_node *cm_node);
120static int handle_tcp_options(struct nes_cm_node *cm_node, struct tcphdr *tcph,
121 struct sk_buff *skb, int optionsize, int passive);
122
123/* CM event handler functions */
124static void cm_event_connected(struct nes_cm_event *);
125static void cm_event_connect_error(struct nes_cm_event *);
126static void cm_event_reset(struct nes_cm_event *);
127static void cm_event_mpa_req(struct nes_cm_event *);
128
129static void print_core(struct nes_cm_core *core);
107 130
108/* External CM API Interface */ 131/* External CM API Interface */
109/* instance of function pointers for client API */ 132/* instance of function pointers for client API */
@@ -158,11 +181,11 @@ static struct nes_cm_event *create_event(struct nes_cm_node *cm_node,
158 event->cm_info.loc_port = cm_node->loc_port; 181 event->cm_info.loc_port = cm_node->loc_port;
159 event->cm_info.cm_id = cm_node->cm_id; 182 event->cm_info.cm_id = cm_node->cm_id;
160 183
161 nes_debug(NES_DBG_CM, "Created event=%p, type=%u, dst_addr=%08x[%x]," 184 nes_debug(NES_DBG_CM, "cm_node=%p Created event=%p, type=%u, "
162 " src_addr=%08x[%x]\n", 185 "dst_addr=%08x[%x], src_addr=%08x[%x]\n",
163 event, type, 186 cm_node, event, type, event->cm_info.loc_addr,
164 event->cm_info.loc_addr, event->cm_info.loc_port, 187 event->cm_info.loc_port, event->cm_info.rem_addr,
165 event->cm_info.rem_addr, event->cm_info.rem_port); 188 event->cm_info.rem_port);
166 189
167 nes_cm_post_event(event); 190 nes_cm_post_event(event);
168 return event; 191 return event;
@@ -172,14 +195,11 @@ static struct nes_cm_event *create_event(struct nes_cm_node *cm_node,
172/** 195/**
173 * send_mpa_request 196 * send_mpa_request
174 */ 197 */
175static int send_mpa_request(struct nes_cm_node *cm_node) 198static int send_mpa_request(struct nes_cm_node *cm_node, struct sk_buff *skb)
176{ 199{
177 struct sk_buff *skb;
178 int ret; 200 int ret;
179
180 skb = get_free_pkt(cm_node);
181 if (!skb) { 201 if (!skb) {
182 nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n"); 202 nes_debug(NES_DBG_CM, "skb set to NULL\n");
183 return -1; 203 return -1;
184 } 204 }
185 205
@@ -188,9 +208,8 @@ static int send_mpa_request(struct nes_cm_node *cm_node)
188 cm_node->mpa_frame_size, SET_ACK); 208 cm_node->mpa_frame_size, SET_ACK);
189 209
190 ret = schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 1, 0); 210 ret = schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 1, 0);
191 if (ret < 0) { 211 if (ret < 0)
192 return ret; 212 return ret;
193 }
194 213
195 return 0; 214 return 0;
196} 215}
@@ -229,46 +248,12 @@ static int parse_mpa(struct nes_cm_node *cm_node, u8 *buffer, u32 len)
229 248
230 249
231/** 250/**
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
235 */
236static int handle_exception_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb)
237{
238 int ret = 0;
239 struct tcphdr *tcph = tcp_hdr(skb);
240
241 /* first check to see if this a FIN pkt */
242 if (tcph->fin) {
243 /* we need to ACK the FIN request */
244 send_ack(cm_node);
245
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;
249 else {
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;
256 }
257 } else {
258 ret = -EINVAL;
259 }
260
261 return ret;
262}
263
264
265/**
266 * form_cm_frame - get a free packet and build empty frame Use 251 * form_cm_frame - get a free packet and build empty frame Use
267 * node info to build. 252 * node info to build.
268 */ 253 */
269static struct sk_buff *form_cm_frame(struct sk_buff *skb, struct nes_cm_node *cm_node, 254static struct sk_buff *form_cm_frame(struct sk_buff *skb,
270 void *options, u32 optionsize, void *data, 255 struct nes_cm_node *cm_node, void *options, u32 optionsize,
271 u32 datasize, u8 flags) 256 void *data, u32 datasize, u8 flags)
272{ 257{
273 struct tcphdr *tcph; 258 struct tcphdr *tcph;
274 struct iphdr *iph; 259 struct iphdr *iph;
@@ -332,10 +317,12 @@ static struct sk_buff *form_cm_frame(struct sk_buff *skb, struct nes_cm_node *cm
332 cm_node->tcp_cntxt.loc_seq_num++; 317 cm_node->tcp_cntxt.loc_seq_num++;
333 tcph->syn = 1; 318 tcph->syn = 1;
334 } else 319 } else
335 cm_node->tcp_cntxt.loc_seq_num += datasize; /* data (no headers) */ 320 cm_node->tcp_cntxt.loc_seq_num += datasize;
336 321
337 if (flags & SET_FIN) 322 if (flags & SET_FIN) {
323 cm_node->tcp_cntxt.loc_seq_num++;
338 tcph->fin = 1; 324 tcph->fin = 1;
325 }
339 326
340 if (flags & SET_RST) 327 if (flags & SET_RST)
341 tcph->rst = 1; 328 tcph->rst = 1;
@@ -389,7 +376,7 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb,
389 int close_when_complete) 376 int close_when_complete)
390{ 377{
391 unsigned long flags; 378 unsigned long flags;
392 struct nes_cm_core *cm_core; 379 struct nes_cm_core *cm_core = cm_node->cm_core;
393 struct nes_timer_entry *new_send; 380 struct nes_timer_entry *new_send;
394 int ret = 0; 381 int ret = 0;
395 u32 was_timer_set; 382 u32 was_timer_set;
@@ -411,7 +398,7 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb,
411 new_send->close_when_complete = close_when_complete; 398 new_send->close_when_complete = close_when_complete;
412 399
413 if (type == NES_TIMER_TYPE_CLOSE) { 400 if (type == NES_TIMER_TYPE_CLOSE) {
414 new_send->timetosend += (HZ/2); /* TODO: decide on the correct value here */ 401 new_send->timetosend += (HZ/10);
415 spin_lock_irqsave(&cm_node->recv_list_lock, flags); 402 spin_lock_irqsave(&cm_node->recv_list_lock, flags);
416 list_add_tail(&new_send->list, &cm_node->recv_list); 403 list_add_tail(&new_send->list, &cm_node->recv_list);
417 spin_unlock_irqrestore(&cm_node->recv_list_lock, flags); 404 spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
@@ -420,36 +407,28 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb,
420 if (type == NES_TIMER_TYPE_SEND) { 407 if (type == NES_TIMER_TYPE_SEND) {
421 new_send->seq_num = ntohl(tcp_hdr(skb)->seq); 408 new_send->seq_num = ntohl(tcp_hdr(skb)->seq);
422 atomic_inc(&new_send->skb->users); 409 atomic_inc(&new_send->skb->users);
410 spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
411 cm_node->send_entry = new_send;
412 add_ref_cm_node(cm_node);
413 spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags);
414 new_send->timetosend = jiffies + NES_RETRY_TIMEOUT;
423 415
424 ret = nes_nic_cm_xmit(new_send->skb, cm_node->netdev); 416 ret = nes_nic_cm_xmit(new_send->skb, cm_node->netdev);
425 if (ret != NETDEV_TX_OK) { 417 if (ret != NETDEV_TX_OK) {
426 nes_debug(NES_DBG_CM, "Error sending packet %p (jiffies = %lu)\n", 418 nes_debug(NES_DBG_CM, "Error sending packet %p "
427 new_send, jiffies); 419 "(jiffies = %lu)\n", new_send, jiffies);
428 atomic_dec(&new_send->skb->users); 420 atomic_dec(&new_send->skb->users);
429 new_send->timetosend = jiffies; 421 new_send->timetosend = jiffies;
430 } else { 422 } else {
431 cm_packets_sent++; 423 cm_packets_sent++;
432 if (!send_retrans) { 424 if (!send_retrans) {
425 cleanup_retrans_entry(cm_node);
433 if (close_when_complete) 426 if (close_when_complete)
434 rem_ref_cm_node(cm_node->cm_core, cm_node); 427 rem_ref_cm_node(cm_core, cm_node);
435 dev_kfree_skb_any(new_send->skb);
436 kfree(new_send);
437 return ret; 428 return ret;
438 } 429 }
439 new_send->timetosend = jiffies + NES_RETRY_TIMEOUT;
440 } 430 }
441 spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
442 list_add_tail(&new_send->list, &cm_node->retrans_list);
443 spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags);
444 }
445 if (type == NES_TIMER_TYPE_RECV) {
446 new_send->seq_num = ntohl(tcp_hdr(skb)->seq);
447 new_send->timetosend = jiffies;
448 spin_lock_irqsave(&cm_node->recv_list_lock, flags);
449 list_add_tail(&new_send->list, &cm_node->recv_list);
450 spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
451 } 431 }
452 cm_core = cm_node->cm_core;
453 432
454 was_timer_set = timer_pending(&cm_core->tcp_timer); 433 was_timer_set = timer_pending(&cm_core->tcp_timer);
455 434
@@ -476,23 +455,27 @@ static void nes_cm_timer_tick(unsigned long pass)
476 struct list_head *list_node, *list_node_temp; 455 struct list_head *list_node, *list_node_temp;
477 struct nes_cm_core *cm_core = g_cm_core; 456 struct nes_cm_core *cm_core = g_cm_core;
478 struct nes_qp *nesqp; 457 struct nes_qp *nesqp;
479 struct sk_buff *skb;
480 u32 settimer = 0; 458 u32 settimer = 0;
481 int ret = NETDEV_TX_OK; 459 int ret = NETDEV_TX_OK;
482 int node_done; 460 enum nes_cm_node_state last_state;
483 461
484 spin_lock_irqsave(&cm_core->ht_lock, flags); 462 spin_lock_irqsave(&cm_core->ht_lock, flags);
485 463
486 list_for_each_safe(list_node, list_core_temp, &cm_core->connected_nodes) { 464 list_for_each_safe(list_node, list_core_temp,
465 &cm_core->connected_nodes) {
487 cm_node = container_of(list_node, struct nes_cm_node, list); 466 cm_node = container_of(list_node, struct nes_cm_node, list);
488 add_ref_cm_node(cm_node); 467 add_ref_cm_node(cm_node);
489 spin_unlock_irqrestore(&cm_core->ht_lock, flags); 468 spin_unlock_irqrestore(&cm_core->ht_lock, flags);
490 spin_lock_irqsave(&cm_node->recv_list_lock, flags); 469 spin_lock_irqsave(&cm_node->recv_list_lock, flags);
491 list_for_each_safe(list_core, list_node_temp, &cm_node->recv_list) { 470 list_for_each_safe(list_core, list_node_temp,
492 recv_entry = container_of(list_core, struct nes_timer_entry, list); 471 &cm_node->recv_list) {
493 if ((time_after(recv_entry->timetosend, jiffies)) && 472 recv_entry = container_of(list_core,
494 (recv_entry->type == NES_TIMER_TYPE_CLOSE)) { 473 struct nes_timer_entry, list);
495 if (nexttimeout > recv_entry->timetosend || !settimer) { 474 if (!recv_entry)
475 break;
476 if (time_after(recv_entry->timetosend, jiffies)) {
477 if (nexttimeout > recv_entry->timetosend ||
478 !settimer) {
496 nexttimeout = recv_entry->timetosend; 479 nexttimeout = recv_entry->timetosend;
497 settimer = 1; 480 settimer = 1;
498 } 481 }
@@ -501,157 +484,143 @@ static void nes_cm_timer_tick(unsigned long pass)
501 list_del(&recv_entry->list); 484 list_del(&recv_entry->list);
502 cm_id = cm_node->cm_id; 485 cm_id = cm_node->cm_id;
503 spin_unlock_irqrestore(&cm_node->recv_list_lock, flags); 486 spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
504 if (recv_entry->type == NES_TIMER_TYPE_CLOSE) { 487 nesqp = (struct nes_qp *)recv_entry->skb;
505 nesqp = (struct nes_qp *)recv_entry->skb; 488 spin_lock_irqsave(&nesqp->lock, qplockflags);
506 spin_lock_irqsave(&nesqp->lock, qplockflags); 489 if (nesqp->cm_id) {
507 if (nesqp->cm_id) { 490 nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, "
508 nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, refcount = %d: " 491 "refcount = %d: HIT A "
509 "****** HIT A NES_TIMER_TYPE_CLOSE" 492 "NES_TIMER_TYPE_CLOSE with something "
510 " with something to do!!! ******\n", 493 "to do!!!\n", nesqp->hwqp.qp_id, cm_id,
511 nesqp->hwqp.qp_id, cm_id, 494 atomic_read(&nesqp->refcount));
512 atomic_read(&nesqp->refcount)); 495 nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED;
513 nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED; 496 nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT;
514 nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT; 497 nesqp->ibqp_state = IB_QPS_ERR;
515 nesqp->ibqp_state = IB_QPS_ERR; 498 spin_unlock_irqrestore(&nesqp->lock,
516 spin_unlock_irqrestore(&nesqp->lock, qplockflags); 499 qplockflags);
517 nes_cm_disconn(nesqp); 500 nes_cm_disconn(nesqp);
518 } else { 501 } else {
519 spin_unlock_irqrestore(&nesqp->lock, qplockflags); 502 spin_unlock_irqrestore(&nesqp->lock,
520 nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, refcount = %d:" 503 qplockflags);
521 " ****** HIT A NES_TIMER_TYPE_CLOSE" 504 nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, "
522 " with nothing to do!!! ******\n", 505 "refcount = %d: HIT A "
523 nesqp->hwqp.qp_id, cm_id, 506 "NES_TIMER_TYPE_CLOSE with nothing "
524 atomic_read(&nesqp->refcount)); 507 "to do!!!\n", nesqp->hwqp.qp_id, cm_id,
525 nes_rem_ref(&nesqp->ibqp); 508 atomic_read(&nesqp->refcount));
526 }
527 if (cm_id)
528 cm_id->rem_ref(cm_id);
529 } 509 }
510 if (cm_id)
511 cm_id->rem_ref(cm_id);
512
530 kfree(recv_entry); 513 kfree(recv_entry);
531 spin_lock_irqsave(&cm_node->recv_list_lock, flags); 514 spin_lock_irqsave(&cm_node->recv_list_lock, flags);
532 } 515 }
533 spin_unlock_irqrestore(&cm_node->recv_list_lock, flags); 516 spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
534 517
535 spin_lock_irqsave(&cm_node->retrans_list_lock, flags); 518 spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
536 node_done = 0; 519 do {
537 list_for_each_safe(list_core, list_node_temp, &cm_node->retrans_list) { 520 send_entry = cm_node->send_entry;
538 if (node_done) { 521 if (!send_entry)
539 break; 522 continue;
540 }
541 send_entry = container_of(list_core, struct nes_timer_entry, list);
542 if (time_after(send_entry->timetosend, jiffies)) { 523 if (time_after(send_entry->timetosend, jiffies)) {
543 if (cm_node->state != NES_CM_STATE_TSA) { 524 if (cm_node->state != NES_CM_STATE_TSA) {
544 if ((nexttimeout > send_entry->timetosend) || !settimer) { 525 if ((nexttimeout >
545 nexttimeout = send_entry->timetosend; 526 send_entry->timetosend) ||
527 !settimer) {
528 nexttimeout =
529 send_entry->timetosend;
546 settimer = 1; 530 settimer = 1;
531 continue;
547 } 532 }
548 node_done = 1;
549 continue;
550 } else { 533 } else {
551 list_del(&send_entry->list); 534 free_retrans_entry(cm_node);
552 skb = send_entry->skb;
553 spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags);
554 dev_kfree_skb_any(skb);
555 kfree(send_entry);
556 spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
557 continue; 535 continue;
558 } 536 }
559 } 537 }
560 if (send_entry->type == NES_TIMER_NODE_CLEANUP) { 538
561 list_del(&send_entry->list); 539 if ((cm_node->state == NES_CM_STATE_TSA) ||
562 spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); 540 (cm_node->state == NES_CM_STATE_CLOSED)) {
563 kfree(send_entry); 541 free_retrans_entry(cm_node);
564 spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
565 continue;
566 }
567 if ((send_entry->seq_num < cm_node->tcp_cntxt.rem_ack_num) ||
568 (cm_node->state == NES_CM_STATE_TSA) ||
569 (cm_node->state == NES_CM_STATE_CLOSED)) {
570 skb = send_entry->skb;
571 list_del(&send_entry->list);
572 spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags);
573 kfree(send_entry);
574 dev_kfree_skb_any(skb);
575 spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
576 continue; 542 continue;
577 } 543 }
578 544
579 if (!send_entry->retranscount || !send_entry->retrycount) { 545 if (!send_entry->retranscount ||
546 !send_entry->retrycount) {
580 cm_packets_dropped++; 547 cm_packets_dropped++;
581 skb = send_entry->skb; 548 last_state = cm_node->state;
582 list_del(&send_entry->list); 549 cm_node->state = NES_CM_STATE_CLOSED;
583 spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); 550 free_retrans_entry(cm_node);
584 dev_kfree_skb_any(skb); 551 spin_unlock_irqrestore(
585 kfree(send_entry); 552 &cm_node->retrans_list_lock, flags);
586 if (cm_node->state == NES_CM_STATE_SYN_RCVD) { 553 if (last_state == NES_CM_STATE_SYN_RCVD)
587 /* this node never even generated an indication up to the cm */
588 rem_ref_cm_node(cm_core, cm_node); 554 rem_ref_cm_node(cm_core, cm_node);
589 } else { 555 else
590 cm_node->state = NES_CM_STATE_CLOSED; 556 create_event(cm_node,
591 create_event(cm_node, NES_CM_EVENT_ABORTED); 557 NES_CM_EVENT_ABORTED);
592 } 558 spin_lock_irqsave(&cm_node->retrans_list_lock,
593 spin_lock_irqsave(&cm_node->retrans_list_lock, flags); 559 flags);
594 continue; 560 continue;
595 } 561 }
596 /* this seems like the correct place, but leave send entry unprotected */
597 /* spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); */
598 atomic_inc(&send_entry->skb->users); 562 atomic_inc(&send_entry->skb->users);
599 cm_packets_retrans++; 563 cm_packets_retrans++;
600 nes_debug(NES_DBG_CM, "Retransmitting send_entry %p for node %p," 564 nes_debug(NES_DBG_CM, "Retransmitting send_entry %p "
601 " jiffies = %lu, time to send = %lu, retranscount = %u, " 565 "for node %p, jiffies = %lu, time to send = "
602 "send_entry->seq_num = 0x%08X, cm_node->tcp_cntxt.rem_ack_num = 0x%08X\n", 566 "%lu, retranscount = %u, send_entry->seq_num = "
603 send_entry, cm_node, jiffies, send_entry->timetosend, send_entry->retranscount, 567 "0x%08X, cm_node->tcp_cntxt.rem_ack_num = "
604 send_entry->seq_num, cm_node->tcp_cntxt.rem_ack_num); 568 "0x%08X\n", send_entry, cm_node, jiffies,
605 569 send_entry->timetosend,
606 spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); 570 send_entry->retranscount,
571 send_entry->seq_num,
572 cm_node->tcp_cntxt.rem_ack_num);
573
574 spin_unlock_irqrestore(&cm_node->retrans_list_lock,
575 flags);
607 ret = nes_nic_cm_xmit(send_entry->skb, cm_node->netdev); 576 ret = nes_nic_cm_xmit(send_entry->skb, cm_node->netdev);
577 spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
608 if (ret != NETDEV_TX_OK) { 578 if (ret != NETDEV_TX_OK) {
579 nes_debug(NES_DBG_CM, "rexmit failed for "
580 "node=%p\n", cm_node);
609 cm_packets_bounced++; 581 cm_packets_bounced++;
610 atomic_dec(&send_entry->skb->users); 582 atomic_dec(&send_entry->skb->users);
611 send_entry->retrycount--; 583 send_entry->retrycount--;
612 nexttimeout = jiffies + NES_SHORT_TIME; 584 nexttimeout = jiffies + NES_SHORT_TIME;
613 settimer = 1; 585 settimer = 1;
614 node_done = 1;
615 spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
616 continue; 586 continue;
617 } else { 587 } else {
618 cm_packets_sent++; 588 cm_packets_sent++;
619 } 589 }
620 spin_lock_irqsave(&cm_node->retrans_list_lock, flags); 590 nes_debug(NES_DBG_CM, "Packet Sent: retrans count = "
621 list_del(&send_entry->list); 591 "%u, retry count = %u.\n",
622 nes_debug(NES_DBG_CM, "Packet Sent: retrans count = %u, retry count = %u.\n", 592 send_entry->retranscount,
623 send_entry->retranscount, send_entry->retrycount); 593 send_entry->retrycount);
624 if (send_entry->send_retrans) { 594 if (send_entry->send_retrans) {
625 send_entry->retranscount--; 595 send_entry->retranscount--;
626 send_entry->timetosend = jiffies + NES_RETRY_TIMEOUT; 596 send_entry->timetosend = jiffies +
627 if (nexttimeout > send_entry->timetosend || !settimer) { 597 NES_RETRY_TIMEOUT;
598 if (nexttimeout > send_entry->timetosend ||
599 !settimer) {
628 nexttimeout = send_entry->timetosend; 600 nexttimeout = send_entry->timetosend;
629 settimer = 1; 601 settimer = 1;
630 } 602 }
631 list_add(&send_entry->list, &cm_node->retrans_list);
632 continue;
633 } else { 603 } else {
634 int close_when_complete; 604 int close_when_complete;
635 skb = send_entry->skb; 605 close_when_complete =
636 close_when_complete = send_entry->close_when_complete; 606 send_entry->close_when_complete;
637 spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); 607 nes_debug(NES_DBG_CM, "cm_node=%p state=%d\n",
638 if (close_when_complete) { 608 cm_node, cm_node->state);
639 BUG_ON(atomic_read(&cm_node->ref_count) == 1); 609 free_retrans_entry(cm_node);
640 rem_ref_cm_node(cm_core, cm_node); 610 if (close_when_complete)
641 } 611 rem_ref_cm_node(cm_node->cm_core,
642 dev_kfree_skb_any(skb); 612 cm_node);
643 kfree(send_entry);
644 spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
645 continue;
646 } 613 }
647 } 614 } while (0);
648 spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags);
649
650 rem_ref_cm_node(cm_core, cm_node);
651 615
616 spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags);
617 rem_ref_cm_node(cm_node->cm_core, cm_node);
652 spin_lock_irqsave(&cm_core->ht_lock, flags); 618 spin_lock_irqsave(&cm_core->ht_lock, flags);
653 if (ret != NETDEV_TX_OK) 619 if (ret != NETDEV_TX_OK) {
620 nes_debug(NES_DBG_CM, "rexmit failed for cm_node=%p\n",
621 cm_node);
654 break; 622 break;
623 }
655 } 624 }
656 spin_unlock_irqrestore(&cm_core->ht_lock, flags); 625 spin_unlock_irqrestore(&cm_core->ht_lock, flags);
657 626
@@ -667,14 +636,14 @@ static void nes_cm_timer_tick(unsigned long pass)
667/** 636/**
668 * send_syn 637 * send_syn
669 */ 638 */
670static int send_syn(struct nes_cm_node *cm_node, u32 sendack) 639static int send_syn(struct nes_cm_node *cm_node, u32 sendack,
640 struct sk_buff *skb)
671{ 641{
672 int ret; 642 int ret;
673 int flags = SET_SYN; 643 int flags = SET_SYN;
674 struct sk_buff *skb;
675 char optionsbuffer[sizeof(struct option_mss) + 644 char optionsbuffer[sizeof(struct option_mss) +
676 sizeof(struct option_windowscale) + 645 sizeof(struct option_windowscale) + sizeof(struct option_base) +
677 sizeof(struct option_base) + 1]; 646 TCP_OPTIONS_PADDING];
678 647
679 int optionssize = 0; 648 int optionssize = 0;
680 /* Sending MSS option */ 649 /* Sending MSS option */
@@ -695,8 +664,7 @@ static int send_syn(struct nes_cm_node *cm_node, u32 sendack)
695 options->as_windowscale.shiftcount = cm_node->tcp_cntxt.rcv_wscale; 664 options->as_windowscale.shiftcount = cm_node->tcp_cntxt.rcv_wscale;
696 optionssize += sizeof(struct option_windowscale); 665 optionssize += sizeof(struct option_windowscale);
697 666
698 if (sendack && !(NES_DRV_OPT_SUPRESS_OPTION_BC & nes_drv_opt) 667 if (sendack && !(NES_DRV_OPT_SUPRESS_OPTION_BC & nes_drv_opt)) {
699 ) {
700 options = (union all_known_options *)&optionsbuffer[optionssize]; 668 options = (union all_known_options *)&optionsbuffer[optionssize];
701 options->as_base.optionnum = OPTION_NUMBER_WRITE0; 669 options->as_base.optionnum = OPTION_NUMBER_WRITE0;
702 options->as_base.length = sizeof(struct option_base); 670 options->as_base.length = sizeof(struct option_base);
@@ -714,7 +682,8 @@ static int send_syn(struct nes_cm_node *cm_node, u32 sendack)
714 options->as_end = OPTION_NUMBER_END; 682 options->as_end = OPTION_NUMBER_END;
715 optionssize += 1; 683 optionssize += 1;
716 684
717 skb = get_free_pkt(cm_node); 685 if (!skb)
686 skb = get_free_pkt(cm_node);
718 if (!skb) { 687 if (!skb) {
719 nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n"); 688 nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n");
720 return -1; 689 return -1;
@@ -733,18 +702,18 @@ static int send_syn(struct nes_cm_node *cm_node, u32 sendack)
733/** 702/**
734 * send_reset 703 * send_reset
735 */ 704 */
736static int send_reset(struct nes_cm_node *cm_node) 705static int send_reset(struct nes_cm_node *cm_node, struct sk_buff *skb)
737{ 706{
738 int ret; 707 int ret;
739 struct sk_buff *skb = get_free_pkt(cm_node);
740 int flags = SET_RST | SET_ACK; 708 int flags = SET_RST | SET_ACK;
741 709
710 if (!skb)
711 skb = get_free_pkt(cm_node);
742 if (!skb) { 712 if (!skb) {
743 nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n"); 713 nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n");
744 return -1; 714 return -1;
745 } 715 }
746 716
747 add_ref_cm_node(cm_node);
748 form_cm_frame(skb, cm_node, NULL, 0, NULL, 0, flags); 717 form_cm_frame(skb, cm_node, NULL, 0, NULL, 0, flags);
749 ret = schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 0, 1); 718 ret = schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 0, 1);
750 719
@@ -755,10 +724,12 @@ static int send_reset(struct nes_cm_node *cm_node)
755/** 724/**
756 * send_ack 725 * send_ack
757 */ 726 */
758static int send_ack(struct nes_cm_node *cm_node) 727static int send_ack(struct nes_cm_node *cm_node, struct sk_buff *skb)
759{ 728{
760 int ret; 729 int ret;
761 struct sk_buff *skb = get_free_pkt(cm_node); 730
731 if (!skb)
732 skb = get_free_pkt(cm_node);
762 733
763 if (!skb) { 734 if (!skb) {
764 nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n"); 735 nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n");
@@ -922,7 +893,8 @@ static int add_hte_node(struct nes_cm_core *cm_core, struct nes_cm_node *cm_node
922 if (!cm_node || !cm_core) 893 if (!cm_node || !cm_core)
923 return -EINVAL; 894 return -EINVAL;
924 895
925 nes_debug(NES_DBG_CM, "Adding Node to Active Connection HT\n"); 896 nes_debug(NES_DBG_CM, "Adding Node %p to Active Connection HT\n",
897 cm_node);
926 898
927 /* first, make an index into our hash table */ 899 /* first, make an index into our hash table */
928 hashkey = make_hashkey(cm_node->loc_port, cm_node->loc_addr, 900 hashkey = make_hashkey(cm_node->loc_port, cm_node->loc_addr,
@@ -946,10 +918,35 @@ static int add_hte_node(struct nes_cm_core *cm_core, struct nes_cm_node *cm_node
946 * mini_cm_dec_refcnt_listen 918 * mini_cm_dec_refcnt_listen
947 */ 919 */
948static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core, 920static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core,
949 struct nes_cm_listener *listener, int free_hanging_nodes) 921 struct nes_cm_listener *listener, int free_hanging_nodes)
950{ 922{
951 int ret = 1; 923 int ret = 1;
952 unsigned long flags; 924 unsigned long flags;
925 struct list_head *list_pos = NULL;
926 struct list_head *list_temp = NULL;
927 struct nes_cm_node *cm_node = NULL;
928
929 nes_debug(NES_DBG_CM, "attempting listener= %p free_nodes= %d, "
930 "refcnt=%d\n", listener, free_hanging_nodes,
931 atomic_read(&listener->ref_count));
932 /* free non-accelerated child nodes for this listener */
933 if (free_hanging_nodes) {
934 spin_lock_irqsave(&cm_core->ht_lock, flags);
935 list_for_each_safe(list_pos, list_temp,
936 &g_cm_core->connected_nodes) {
937 cm_node = container_of(list_pos, struct nes_cm_node,
938 list);
939 if ((cm_node->listener == listener) &&
940 (!cm_node->accelerated)) {
941 cleanup_retrans_entry(cm_node);
942 spin_unlock_irqrestore(&cm_core->ht_lock,
943 flags);
944 send_reset(cm_node, NULL);
945 spin_lock_irqsave(&cm_core->ht_lock, flags);
946 }
947 }
948 spin_unlock_irqrestore(&cm_core->ht_lock, flags);
949 }
953 spin_lock_irqsave(&cm_core->listen_list_lock, flags); 950 spin_lock_irqsave(&cm_core->listen_list_lock, flags);
954 if (!atomic_dec_return(&listener->ref_count)) { 951 if (!atomic_dec_return(&listener->ref_count)) {
955 list_del(&listener->list); 952 list_del(&listener->list);
@@ -1067,18 +1064,18 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core,
1067 cm_node->loc_port = cm_info->loc_port; 1064 cm_node->loc_port = cm_info->loc_port;
1068 cm_node->rem_port = cm_info->rem_port; 1065 cm_node->rem_port = cm_info->rem_port;
1069 cm_node->send_write0 = send_first; 1066 cm_node->send_write0 = send_first;
1070 nes_debug(NES_DBG_CM, "Make node addresses : loc = " NIPQUAD_FMT ":%x, rem = " NIPQUAD_FMT ":%x\n", 1067 nes_debug(NES_DBG_CM, "Make node addresses : loc = " NIPQUAD_FMT
1071 HIPQUAD(cm_node->loc_addr), cm_node->loc_port, 1068 ":%x, rem = " NIPQUAD_FMT ":%x\n",
1072 HIPQUAD(cm_node->rem_addr), cm_node->rem_port); 1069 HIPQUAD(cm_node->loc_addr), cm_node->loc_port,
1070 HIPQUAD(cm_node->rem_addr), cm_node->rem_port);
1073 cm_node->listener = listener; 1071 cm_node->listener = listener;
1074 cm_node->netdev = nesvnic->netdev; 1072 cm_node->netdev = nesvnic->netdev;
1075 cm_node->cm_id = cm_info->cm_id; 1073 cm_node->cm_id = cm_info->cm_id;
1076 memcpy(cm_node->loc_mac, nesvnic->netdev->dev_addr, ETH_ALEN); 1074 memcpy(cm_node->loc_mac, nesvnic->netdev->dev_addr, ETH_ALEN);
1077 1075
1078 nes_debug(NES_DBG_CM, "listener=%p, cm_id=%p\n", 1076 nes_debug(NES_DBG_CM, "listener=%p, cm_id=%p\n", cm_node->listener,
1079 cm_node->listener, cm_node->cm_id); 1077 cm_node->cm_id);
1080 1078
1081 INIT_LIST_HEAD(&cm_node->retrans_list);
1082 spin_lock_init(&cm_node->retrans_list_lock); 1079 spin_lock_init(&cm_node->retrans_list_lock);
1083 INIT_LIST_HEAD(&cm_node->recv_list); 1080 INIT_LIST_HEAD(&cm_node->recv_list);
1084 spin_lock_init(&cm_node->recv_list_lock); 1081 spin_lock_init(&cm_node->recv_list_lock);
@@ -1142,10 +1139,9 @@ static int add_ref_cm_node(struct nes_cm_node *cm_node)
1142 * rem_ref_cm_node - destroy an instance of a cm node 1139 * rem_ref_cm_node - destroy an instance of a cm node
1143 */ 1140 */
1144static int rem_ref_cm_node(struct nes_cm_core *cm_core, 1141static int rem_ref_cm_node(struct nes_cm_core *cm_core,
1145 struct nes_cm_node *cm_node) 1142 struct nes_cm_node *cm_node)
1146{ 1143{
1147 unsigned long flags, qplockflags; 1144 unsigned long flags, qplockflags;
1148 struct nes_timer_entry *send_entry;
1149 struct nes_timer_entry *recv_entry; 1145 struct nes_timer_entry *recv_entry;
1150 struct iw_cm_id *cm_id; 1146 struct iw_cm_id *cm_id;
1151 struct list_head *list_core, *list_node_temp; 1147 struct list_head *list_core, *list_node_temp;
@@ -1169,48 +1165,33 @@ static int rem_ref_cm_node(struct nes_cm_core *cm_core,
1169 atomic_dec(&cm_node->listener->pend_accepts_cnt); 1165 atomic_dec(&cm_node->listener->pend_accepts_cnt);
1170 BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0); 1166 BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0);
1171 } 1167 }
1172 1168 BUG_ON(cm_node->send_entry);
1173 spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
1174 list_for_each_safe(list_core, list_node_temp, &cm_node->retrans_list) {
1175 send_entry = container_of(list_core, struct nes_timer_entry, list);
1176 list_del(&send_entry->list);
1177 spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags);
1178 dev_kfree_skb_any(send_entry->skb);
1179 kfree(send_entry);
1180 spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
1181 continue;
1182 }
1183 spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags);
1184
1185 spin_lock_irqsave(&cm_node->recv_list_lock, flags); 1169 spin_lock_irqsave(&cm_node->recv_list_lock, flags);
1186 list_for_each_safe(list_core, list_node_temp, &cm_node->recv_list) { 1170 list_for_each_safe(list_core, list_node_temp, &cm_node->recv_list) {
1187 recv_entry = container_of(list_core, struct nes_timer_entry, list); 1171 recv_entry = container_of(list_core, struct nes_timer_entry,
1172 list);
1188 list_del(&recv_entry->list); 1173 list_del(&recv_entry->list);
1189 cm_id = cm_node->cm_id; 1174 cm_id = cm_node->cm_id;
1190 spin_unlock_irqrestore(&cm_node->recv_list_lock, flags); 1175 spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
1191 if (recv_entry->type == NES_TIMER_TYPE_CLOSE) { 1176 nesqp = (struct nes_qp *)recv_entry->skb;
1192 nesqp = (struct nes_qp *)recv_entry->skb; 1177 spin_lock_irqsave(&nesqp->lock, qplockflags);
1193 spin_lock_irqsave(&nesqp->lock, qplockflags); 1178 if (nesqp->cm_id) {
1194 if (nesqp->cm_id) { 1179 nes_debug(NES_DBG_CM, "QP%u: cm_id = %p: HIT A "
1195 nes_debug(NES_DBG_CM, "QP%u: cm_id = %p: ****** HIT A NES_TIMER_TYPE_CLOSE" 1180 "NES_TIMER_TYPE_CLOSE with something to do!\n",
1196 " with something to do!!! ******\n", 1181 nesqp->hwqp.qp_id, cm_id);
1197 nesqp->hwqp.qp_id, cm_id); 1182 nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED;
1198 nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED; 1183 nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT;
1199 nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT; 1184 nesqp->ibqp_state = IB_QPS_ERR;
1200 nesqp->ibqp_state = IB_QPS_ERR; 1185 spin_unlock_irqrestore(&nesqp->lock, qplockflags);
1201 spin_unlock_irqrestore(&nesqp->lock, qplockflags); 1186 nes_cm_disconn(nesqp);
1202 nes_cm_disconn(nesqp); 1187 } else {
1203 } else { 1188 spin_unlock_irqrestore(&nesqp->lock, qplockflags);
1204 spin_unlock_irqrestore(&nesqp->lock, qplockflags); 1189 nes_debug(NES_DBG_CM, "QP%u: cm_id = %p: HIT A "
1205 nes_debug(NES_DBG_CM, "QP%u: cm_id = %p: ****** HIT A NES_TIMER_TYPE_CLOSE" 1190 "NES_TIMER_TYPE_CLOSE with nothing to do!\n",
1206 " with nothing to do!!! ******\n", 1191 nesqp->hwqp.qp_id, cm_id);
1207 nesqp->hwqp.qp_id, cm_id);
1208 nes_rem_ref(&nesqp->ibqp);
1209 }
1210 cm_id->rem_ref(cm_id);
1211 } else if (recv_entry->type == NES_TIMER_TYPE_RECV) {
1212 dev_kfree_skb_any(recv_entry->skb);
1213 } 1192 }
1193 cm_id->rem_ref(cm_id);
1194
1214 kfree(recv_entry); 1195 kfree(recv_entry);
1215 spin_lock_irqsave(&cm_node->recv_list_lock, flags); 1196 spin_lock_irqsave(&cm_node->recv_list_lock, flags);
1216 } 1197 }
@@ -1221,23 +1202,31 @@ static int rem_ref_cm_node(struct nes_cm_core *cm_core,
1221 } else { 1202 } else {
1222 if (cm_node->apbvt_set && cm_node->nesvnic) { 1203 if (cm_node->apbvt_set && cm_node->nesvnic) {
1223 nes_manage_apbvt(cm_node->nesvnic, cm_node->loc_port, 1204 nes_manage_apbvt(cm_node->nesvnic, cm_node->loc_port,
1224 PCI_FUNC(cm_node->nesvnic->nesdev->pcidev->devfn), 1205 PCI_FUNC(
1225 NES_MANAGE_APBVT_DEL); 1206 cm_node->nesvnic->nesdev->pcidev->devfn),
1207 NES_MANAGE_APBVT_DEL);
1226 } 1208 }
1227 } 1209 }
1228 1210
1229 kfree(cm_node);
1230 atomic_dec(&cm_core->node_cnt); 1211 atomic_dec(&cm_core->node_cnt);
1231 atomic_inc(&cm_nodes_destroyed); 1212 atomic_inc(&cm_nodes_destroyed);
1213 nesqp = cm_node->nesqp;
1214 if (nesqp) {
1215 nesqp->cm_node = NULL;
1216 nes_rem_ref(&nesqp->ibqp);
1217 cm_node->nesqp = NULL;
1218 }
1232 1219
1220 cm_node->freed = 1;
1221 kfree(cm_node);
1233 return 0; 1222 return 0;
1234} 1223}
1235 1224
1236
1237/** 1225/**
1238 * process_options 1226 * process_options
1239 */ 1227 */
1240static int process_options(struct nes_cm_node *cm_node, u8 *optionsloc, u32 optionsize, u32 syn_packet) 1228static int process_options(struct nes_cm_node *cm_node, u8 *optionsloc,
1229 u32 optionsize, u32 syn_packet)
1241{ 1230{
1242 u32 tmp; 1231 u32 tmp;
1243 u32 offset = 0; 1232 u32 offset = 0;
@@ -1247,35 +1236,37 @@ static int process_options(struct nes_cm_node *cm_node, u8 *optionsloc, u32 opti
1247 while (offset < optionsize) { 1236 while (offset < optionsize) {
1248 all_options = (union all_known_options *)(optionsloc + offset); 1237 all_options = (union all_known_options *)(optionsloc + offset);
1249 switch (all_options->as_base.optionnum) { 1238 switch (all_options->as_base.optionnum) {
1250 case OPTION_NUMBER_END: 1239 case OPTION_NUMBER_END:
1251 offset = optionsize; 1240 offset = optionsize;
1252 break; 1241 break;
1253 case OPTION_NUMBER_NONE: 1242 case OPTION_NUMBER_NONE:
1254 offset += 1; 1243 offset += 1;
1255 continue; 1244 continue;
1256 case OPTION_NUMBER_MSS: 1245 case OPTION_NUMBER_MSS:
1257 nes_debug(NES_DBG_CM, "%s: MSS Length: %d Offset: %d Size: %d\n", 1246 nes_debug(NES_DBG_CM, "%s: MSS Length: %d Offset: %d "
1258 __func__, 1247 "Size: %d\n", __func__,
1259 all_options->as_mss.length, offset, optionsize); 1248 all_options->as_mss.length, offset, optionsize);
1260 got_mss_option = 1; 1249 got_mss_option = 1;
1261 if (all_options->as_mss.length != 4) { 1250 if (all_options->as_mss.length != 4) {
1262 return 1; 1251 return 1;
1263 } else { 1252 } else {
1264 tmp = ntohs(all_options->as_mss.mss); 1253 tmp = ntohs(all_options->as_mss.mss);
1265 if (tmp > 0 && tmp < cm_node->tcp_cntxt.mss) 1254 if (tmp > 0 && tmp <
1266 cm_node->tcp_cntxt.mss = tmp; 1255 cm_node->tcp_cntxt.mss)
1267 } 1256 cm_node->tcp_cntxt.mss = tmp;
1268 break; 1257 }
1269 case OPTION_NUMBER_WINDOW_SCALE: 1258 break;
1270 cm_node->tcp_cntxt.snd_wscale = all_options->as_windowscale.shiftcount; 1259 case OPTION_NUMBER_WINDOW_SCALE:
1271 break; 1260 cm_node->tcp_cntxt.snd_wscale =
1272 case OPTION_NUMBER_WRITE0: 1261 all_options->as_windowscale.shiftcount;
1273 cm_node->send_write0 = 1; 1262 break;
1274 break; 1263 case OPTION_NUMBER_WRITE0:
1275 default: 1264 cm_node->send_write0 = 1;
1276 nes_debug(NES_DBG_CM, "TCP Option not understood: %x\n", 1265 break;
1277 all_options->as_base.optionnum); 1266 default:
1278 break; 1267 nes_debug(NES_DBG_CM, "TCP Option not understood: %x\n",
1268 all_options->as_base.optionnum);
1269 break;
1279 } 1270 }
1280 offset += all_options->as_base.length; 1271 offset += all_options->as_base.length;
1281 } 1272 }
@@ -1284,300 +1275,491 @@ static int process_options(struct nes_cm_node *cm_node, u8 *optionsloc, u32 opti
1284 return 0; 1275 return 0;
1285} 1276}
1286 1277
1278static void drop_packet(struct sk_buff *skb)
1279{
1280 atomic_inc(&cm_accel_dropped_pkts);
1281 dev_kfree_skb_any(skb);
1282}
1287 1283
1288/** 1284static void handle_fin_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1289 * process_packet 1285 struct tcphdr *tcph)
1290 */
1291static int process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb,
1292 struct nes_cm_core *cm_core)
1293{ 1286{
1294 int optionsize; 1287 atomic_inc(&cm_resets_recvd);
1295 int datasize; 1288 nes_debug(NES_DBG_CM, "Received FIN, cm_node = %p, state = %u. "
1296 int ret = 0; 1289 "refcnt=%d\n", cm_node, cm_node->state,
1297 struct tcphdr *tcph = tcp_hdr(skb); 1290 atomic_read(&cm_node->ref_count));
1298 u32 inc_sequence; 1291 cm_node->tcp_cntxt.rcv_nxt++;
1299 if (cm_node->state == NES_CM_STATE_SYN_SENT && tcph->syn) { 1292 cleanup_retrans_entry(cm_node);
1300 inc_sequence = ntohl(tcph->seq); 1293 switch (cm_node->state) {
1301 cm_node->tcp_cntxt.rcv_nxt = inc_sequence; 1294 case NES_CM_STATE_SYN_RCVD:
1295 case NES_CM_STATE_SYN_SENT:
1296 case NES_CM_STATE_ESTABLISHED:
1297 case NES_CM_STATE_MPAREQ_SENT:
1298 cm_node->state = NES_CM_STATE_LAST_ACK;
1299 send_fin(cm_node, skb);
1300 break;
1301 case NES_CM_STATE_FIN_WAIT1:
1302 cm_node->state = NES_CM_STATE_CLOSING;
1303 send_ack(cm_node, skb);
1304 break;
1305 case NES_CM_STATE_FIN_WAIT2:
1306 cm_node->state = NES_CM_STATE_TIME_WAIT;
1307 send_ack(cm_node, skb);
1308 cm_node->state = NES_CM_STATE_CLOSED;
1309 break;
1310 case NES_CM_STATE_TSA:
1311 default:
1312 nes_debug(NES_DBG_CM, "Error Rcvd FIN for node-%p state = %d\n",
1313 cm_node, cm_node->state);
1314 drop_packet(skb);
1315 break;
1302 } 1316 }
1317}
1303 1318
1304 if ((!tcph) || (cm_node->state == NES_CM_STATE_TSA)) {
1305 BUG_ON(!tcph);
1306 atomic_inc(&cm_accel_dropped_pkts);
1307 return -1;
1308 }
1309 1319
1310 if (tcph->rst) { 1320static void handle_rst_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1311 atomic_inc(&cm_resets_recvd); 1321 struct tcphdr *tcph)
1312 nes_debug(NES_DBG_CM, "Received Reset, cm_node = %p, state = %u. refcnt=%d\n", 1322{
1313 cm_node, cm_node->state, atomic_read(&cm_node->ref_count));
1314 switch (cm_node->state) {
1315 case NES_CM_STATE_LISTENING:
1316 rem_ref_cm_node(cm_core, cm_node);
1317 break;
1318 case NES_CM_STATE_TSA:
1319 case NES_CM_STATE_CLOSED:
1320 break;
1321 case NES_CM_STATE_SYN_RCVD:
1322 nes_debug(NES_DBG_CM, "Received a reset for local 0x%08X:%04X,"
1323 " remote 0x%08X:%04X, node state = %u\n",
1324 cm_node->loc_addr, cm_node->loc_port,
1325 cm_node->rem_addr, cm_node->rem_port,
1326 cm_node->state);
1327 rem_ref_cm_node(cm_core, cm_node);
1328 break;
1329 case NES_CM_STATE_ONE_SIDE_ESTABLISHED:
1330 case NES_CM_STATE_ESTABLISHED:
1331 case NES_CM_STATE_MPAREQ_SENT:
1332 default:
1333 nes_debug(NES_DBG_CM, "Received a reset for local 0x%08X:%04X,"
1334 " remote 0x%08X:%04X, node state = %u refcnt=%d\n",
1335 cm_node->loc_addr, cm_node->loc_port,
1336 cm_node->rem_addr, cm_node->rem_port,
1337 cm_node->state, atomic_read(&cm_node->ref_count));
1338 /* create event */
1339 cm_node->state = NES_CM_STATE_CLOSED;
1340 1323
1341 create_event(cm_node, NES_CM_EVENT_ABORTED); 1324 int reset = 0; /* whether to send reset in case of err.. */
1342 break; 1325 atomic_inc(&cm_resets_recvd);
1326 nes_debug(NES_DBG_CM, "Received Reset, cm_node = %p, state = %u."
1327 " refcnt=%d\n", cm_node, cm_node->state,
1328 atomic_read(&cm_node->ref_count));
1329 cleanup_retrans_entry(cm_node);
1330 switch (cm_node->state) {
1331 case NES_CM_STATE_SYN_SENT:
1332 case NES_CM_STATE_MPAREQ_SENT:
1333 nes_debug(NES_DBG_CM, "%s[%u] create abort for cm_node=%p "
1334 "listener=%p state=%d\n", __func__, __LINE__, cm_node,
1335 cm_node->listener, cm_node->state);
1336 active_open_err(cm_node, skb, reset);
1337 break;
1338 /* For PASSIVE open states, remove the cm_node event */
1339 case NES_CM_STATE_ESTABLISHED:
1340 case NES_CM_STATE_SYN_RCVD:
1341 case NES_CM_STATE_LISTENING:
1342 nes_debug(NES_DBG_CM, "Bad state %s[%u]\n", __func__, __LINE__);
1343 passive_open_err(cm_node, skb, reset);
1344 break;
1345 case NES_CM_STATE_TSA:
1346 default:
1347 break;
1348 }
1349}
1343 1350
1351static void handle_rcv_mpa(struct nes_cm_node *cm_node, struct sk_buff *skb,
1352 enum nes_cm_event_type type)
1353{
1354
1355 int ret;
1356 int datasize = skb->len;
1357 u8 *dataloc = skb->data;
1358 ret = parse_mpa(cm_node, dataloc, datasize);
1359 if (ret < 0) {
1360 nes_debug(NES_DBG_CM, "didn't like MPA Request\n");
1361 if (type == NES_CM_EVENT_CONNECTED) {
1362 nes_debug(NES_DBG_CM, "%s[%u] create abort for "
1363 "cm_node=%p listener=%p state=%d\n", __func__,
1364 __LINE__, cm_node, cm_node->listener,
1365 cm_node->state);
1366 active_open_err(cm_node, skb, 1);
1367 } else {
1368 passive_open_err(cm_node, skb, 1);
1344 } 1369 }
1345 return -1; 1370 } else {
1371 cleanup_retrans_entry(cm_node);
1372 dev_kfree_skb_any(skb);
1373 if (type == NES_CM_EVENT_CONNECTED)
1374 cm_node->state = NES_CM_STATE_TSA;
1375 create_event(cm_node, type);
1376
1377 }
1378 return ;
1379}
1380
1381static void indicate_pkt_err(struct nes_cm_node *cm_node, struct sk_buff *skb)
1382{
1383 switch (cm_node->state) {
1384 case NES_CM_STATE_SYN_SENT:
1385 case NES_CM_STATE_MPAREQ_SENT:
1386 nes_debug(NES_DBG_CM, "%s[%u] create abort for cm_node=%p "
1387 "listener=%p state=%d\n", __func__, __LINE__, cm_node,
1388 cm_node->listener, cm_node->state);
1389 active_open_err(cm_node, skb, 1);
1390 break;
1391 case NES_CM_STATE_ESTABLISHED:
1392 case NES_CM_STATE_SYN_RCVD:
1393 passive_open_err(cm_node, skb, 1);
1394 break;
1395 case NES_CM_STATE_TSA:
1396 default:
1397 drop_packet(skb);
1346 } 1398 }
1399}
1400
1401static int check_syn(struct nes_cm_node *cm_node, struct tcphdr *tcph,
1402 struct sk_buff *skb)
1403{
1404 int err;
1405
1406 err = ((ntohl(tcph->ack_seq) == cm_node->tcp_cntxt.loc_seq_num))? 0 : 1;
1407 if (err)
1408 active_open_err(cm_node, skb, 1);
1409
1410 return err;
1411}
1412
1413static int check_seq(struct nes_cm_node *cm_node, struct tcphdr *tcph,
1414 struct sk_buff *skb)
1415{
1416 int err = 0;
1417 u32 seq;
1418 u32 ack_seq;
1419 u32 loc_seq_num = cm_node->tcp_cntxt.loc_seq_num;
1420 u32 rcv_nxt = cm_node->tcp_cntxt.rcv_nxt;
1421 u32 rcv_wnd;
1422 seq = ntohl(tcph->seq);
1423 ack_seq = ntohl(tcph->ack_seq);
1424 rcv_wnd = cm_node->tcp_cntxt.rcv_wnd;
1425 if (ack_seq != loc_seq_num)
1426 err = 1;
1427 else if ((seq + rcv_wnd) < rcv_nxt)
1428 err = 1;
1429 if (err) {
1430 nes_debug(NES_DBG_CM, "%s[%u] create abort for cm_node=%p "
1431 "listener=%p state=%d\n", __func__, __LINE__, cm_node,
1432 cm_node->listener, cm_node->state);
1433 indicate_pkt_err(cm_node, skb);
1434 nes_debug(NES_DBG_CM, "seq ERROR cm_node =%p seq=0x%08X "
1435 "rcv_nxt=0x%08X rcv_wnd=0x%x\n", cm_node, seq, rcv_nxt,
1436 rcv_wnd);
1437 }
1438 return err;
1439}
1440
1441/*
1442 * handle_syn_pkt() is for Passive node. The syn packet is received when a node
1443 * is created with a listener or it may comein as rexmitted packet which in
1444 * that case will be just dropped.
1445 */
1446
1447static void handle_syn_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1448 struct tcphdr *tcph)
1449{
1450 int ret;
1451 u32 inc_sequence;
1452 int optionsize;
1347 1453
1348 optionsize = (tcph->doff << 2) - sizeof(struct tcphdr); 1454 optionsize = (tcph->doff << 2) - sizeof(struct tcphdr);
1455 skb_pull(skb, tcph->doff << 2);
1456 inc_sequence = ntohl(tcph->seq);
1349 1457
1350 skb_pull(skb, ip_hdr(skb)->ihl << 2); 1458 switch (cm_node->state) {
1459 case NES_CM_STATE_SYN_SENT:
1460 case NES_CM_STATE_MPAREQ_SENT:
1461 /* Rcvd syn on active open connection*/
1462 active_open_err(cm_node, skb, 1);
1463 break;
1464 case NES_CM_STATE_LISTENING:
1465 /* Passive OPEN */
1466 cm_node->accept_pend = 1;
1467 atomic_inc(&cm_node->listener->pend_accepts_cnt);
1468 if (atomic_read(&cm_node->listener->pend_accepts_cnt) >
1469 cm_node->listener->backlog) {
1470 nes_debug(NES_DBG_CM, "drop syn due to backlog "
1471 "pressure \n");
1472 cm_backlog_drops++;
1473 passive_open_err(cm_node, skb, 0);
1474 break;
1475 }
1476 ret = handle_tcp_options(cm_node, tcph, skb, optionsize,
1477 1);
1478 if (ret) {
1479 passive_open_err(cm_node, skb, 0);
1480 /* drop pkt */
1481 break;
1482 }
1483 cm_node->tcp_cntxt.rcv_nxt = inc_sequence + 1;
1484 BUG_ON(cm_node->send_entry);
1485 cm_node->state = NES_CM_STATE_SYN_RCVD;
1486 send_syn(cm_node, 1, skb);
1487 break;
1488 case NES_CM_STATE_TSA:
1489 case NES_CM_STATE_ESTABLISHED:
1490 case NES_CM_STATE_FIN_WAIT1:
1491 case NES_CM_STATE_FIN_WAIT2:
1492 case NES_CM_STATE_MPAREQ_RCVD:
1493 case NES_CM_STATE_LAST_ACK:
1494 case NES_CM_STATE_CLOSING:
1495 case NES_CM_STATE_UNKNOWN:
1496 case NES_CM_STATE_CLOSED:
1497 default:
1498 drop_packet(skb);
1499 break;
1500 }
1501}
1502
1503static void handle_synack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1504 struct tcphdr *tcph)
1505{
1506
1507 int ret;
1508 u32 inc_sequence;
1509 int optionsize;
1510
1511 optionsize = (tcph->doff << 2) - sizeof(struct tcphdr);
1351 skb_pull(skb, tcph->doff << 2); 1512 skb_pull(skb, tcph->doff << 2);
1513 inc_sequence = ntohl(tcph->seq);
1514 switch (cm_node->state) {
1515 case NES_CM_STATE_SYN_SENT:
1516 /* active open */
1517 if (check_syn(cm_node, tcph, skb))
1518 return;
1519 cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq);
1520 /* setup options */
1521 ret = handle_tcp_options(cm_node, tcph, skb, optionsize, 0);
1522 if (ret) {
1523 nes_debug(NES_DBG_CM, "cm_node=%p tcp_options failed\n",
1524 cm_node);
1525 break;
1526 }
1527 cleanup_retrans_entry(cm_node);
1528 cm_node->tcp_cntxt.rcv_nxt = inc_sequence + 1;
1529 send_mpa_request(cm_node, skb);
1530 cm_node->state = NES_CM_STATE_MPAREQ_SENT;
1531 break;
1532 case NES_CM_STATE_MPAREQ_RCVD:
1533 /* passive open, so should not be here */
1534 passive_open_err(cm_node, skb, 1);
1535 break;
1536 case NES_CM_STATE_ESTABLISHED:
1537 case NES_CM_STATE_FIN_WAIT1:
1538 case NES_CM_STATE_FIN_WAIT2:
1539 case NES_CM_STATE_LAST_ACK:
1540 case NES_CM_STATE_TSA:
1541 case NES_CM_STATE_CLOSING:
1542 case NES_CM_STATE_UNKNOWN:
1543 case NES_CM_STATE_CLOSED:
1544 case NES_CM_STATE_MPAREQ_SENT:
1545 default:
1546 drop_packet(skb);
1547 break;
1548 }
1549}
1352 1550
1353 datasize = skb->len; 1551static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1552 struct tcphdr *tcph)
1553{
1554 int datasize = 0;
1555 u32 inc_sequence;
1556 u32 rem_seq_ack;
1557 u32 rem_seq;
1558 if (check_seq(cm_node, tcph, skb))
1559 return;
1560
1561 skb_pull(skb, tcph->doff << 2);
1354 inc_sequence = ntohl(tcph->seq); 1562 inc_sequence = ntohl(tcph->seq);
1355 nes_debug(NES_DBG_CM, "datasize = %u, sequence = 0x%08X, ack_seq = 0x%08X," 1563 rem_seq = ntohl(tcph->seq);
1356 " rcv_nxt = 0x%08X Flags: %s %s.\n", 1564 rem_seq_ack = ntohl(tcph->ack_seq);
1357 datasize, inc_sequence, ntohl(tcph->ack_seq), 1565 datasize = skb->len;
1358 cm_node->tcp_cntxt.rcv_nxt, (tcph->syn ? "SYN":""), 1566
1359 (tcph->ack ? "ACK":"")); 1567 switch (cm_node->state) {
1360 1568 case NES_CM_STATE_SYN_RCVD:
1361 if (!tcph->syn && (inc_sequence != cm_node->tcp_cntxt.rcv_nxt) 1569 /* Passive OPEN */
1362 ) { 1570 cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq);
1363 nes_debug(NES_DBG_CM, "dropping packet, datasize = %u, sequence = 0x%08X," 1571 cm_node->state = NES_CM_STATE_ESTABLISHED;
1364 " ack_seq = 0x%08X, rcv_nxt = 0x%08X Flags: %s.\n", 1572 if (datasize) {
1365 datasize, inc_sequence, ntohl(tcph->ack_seq), 1573 cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
1366 cm_node->tcp_cntxt.rcv_nxt, (tcph->ack ? "ACK":"")); 1574 cm_node->state = NES_CM_STATE_MPAREQ_RCVD;
1367 if (cm_node->state == NES_CM_STATE_LISTENING) { 1575 handle_rcv_mpa(cm_node, skb, NES_CM_EVENT_MPA_REQ);
1368 rem_ref_cm_node(cm_core, cm_node); 1576 } else { /* rcvd ACK only */
1577 dev_kfree_skb_any(skb);
1578 cleanup_retrans_entry(cm_node);
1579 }
1580 break;
1581 case NES_CM_STATE_ESTABLISHED:
1582 /* Passive OPEN */
1583 /* We expect mpa frame to be received only */
1584 if (datasize) {
1585 cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
1586 cm_node->state = NES_CM_STATE_MPAREQ_RCVD;
1587 handle_rcv_mpa(cm_node, skb,
1588 NES_CM_EVENT_MPA_REQ);
1589 } else
1590 drop_packet(skb);
1591 break;
1592 case NES_CM_STATE_MPAREQ_SENT:
1593 cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq);
1594 if (datasize) {
1595 cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
1596 handle_rcv_mpa(cm_node, skb, NES_CM_EVENT_CONNECTED);
1597 } else { /* Could be just an ack pkt.. */
1598 cleanup_retrans_entry(cm_node);
1599 dev_kfree_skb_any(skb);
1369 } 1600 }
1370 return -1; 1601 break;
1602 case NES_CM_STATE_FIN_WAIT1:
1603 case NES_CM_STATE_SYN_SENT:
1604 case NES_CM_STATE_FIN_WAIT2:
1605 case NES_CM_STATE_TSA:
1606 case NES_CM_STATE_CLOSED:
1607 case NES_CM_STATE_MPAREQ_RCVD:
1608 case NES_CM_STATE_LAST_ACK:
1609 case NES_CM_STATE_CLOSING:
1610 case NES_CM_STATE_UNKNOWN:
1611 default:
1612 drop_packet(skb);
1613 break;
1371 } 1614 }
1615}
1372 1616
1373 cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
1374 1617
1375 1618
1619static int handle_tcp_options(struct nes_cm_node *cm_node, struct tcphdr *tcph,
1620 struct sk_buff *skb, int optionsize, int passive)
1621{
1622 u8 *optionsloc = (u8 *)&tcph[1];
1376 if (optionsize) { 1623 if (optionsize) {
1377 u8 *optionsloc = (u8 *)&tcph[1]; 1624 if (process_options(cm_node, optionsloc, optionsize,
1378 if (process_options(cm_node, optionsloc, optionsize, (u32)tcph->syn)) { 1625 (u32)tcph->syn)) {
1379 nes_debug(NES_DBG_CM, "%s: Node %p, Sending RESET\n", __func__, cm_node); 1626 nes_debug(NES_DBG_CM, "%s: Node %p, Sending RESET\n",
1380 send_reset(cm_node); 1627 __func__, cm_node);
1381 if (cm_node->state != NES_CM_STATE_SYN_SENT) 1628 if (passive)
1382 rem_ref_cm_node(cm_core, cm_node); 1629 passive_open_err(cm_node, skb, 0);
1383 return 0; 1630 else
1631 active_open_err(cm_node, skb, 0);
1632 return 1;
1384 } 1633 }
1385 } else if (tcph->syn) 1634 }
1386 cm_node->tcp_cntxt.mss = NES_CM_DEFAULT_MSS;
1387 1635
1388 cm_node->tcp_cntxt.snd_wnd = ntohs(tcph->window) << 1636 cm_node->tcp_cntxt.snd_wnd = ntohs(tcph->window) <<
1389 cm_node->tcp_cntxt.snd_wscale; 1637 cm_node->tcp_cntxt.snd_wscale;
1390 1638
1391 if (cm_node->tcp_cntxt.snd_wnd > cm_node->tcp_cntxt.max_snd_wnd) { 1639 if (cm_node->tcp_cntxt.snd_wnd > cm_node->tcp_cntxt.max_snd_wnd)
1392 cm_node->tcp_cntxt.max_snd_wnd = cm_node->tcp_cntxt.snd_wnd; 1640 cm_node->tcp_cntxt.max_snd_wnd = cm_node->tcp_cntxt.snd_wnd;
1393 } 1641 return 0;
1642}
1394 1643
1395 if (tcph->ack) { 1644/*
1396 cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq); 1645 * active_open_err() will send reset() if flag set..
1397 switch (cm_node->state) { 1646 * It will also send ABORT event.
1398 case NES_CM_STATE_SYN_RCVD: 1647 */
1399 case NES_CM_STATE_SYN_SENT:
1400 /* read and stash current sequence number */
1401 if (cm_node->tcp_cntxt.rem_ack_num != cm_node->tcp_cntxt.loc_seq_num) {
1402 nes_debug(NES_DBG_CM, "ERROR - cm_node->tcp_cntxt.rem_ack_num !="
1403 " cm_node->tcp_cntxt.loc_seq_num\n");
1404 send_reset(cm_node);
1405 return 0;
1406 }
1407 if (cm_node->state == NES_CM_STATE_SYN_SENT)
1408 cm_node->state = NES_CM_STATE_ONE_SIDE_ESTABLISHED;
1409 else {
1410 cm_node->state = NES_CM_STATE_ESTABLISHED;
1411 }
1412 break;
1413 case NES_CM_STATE_LAST_ACK:
1414 cm_node->state = NES_CM_STATE_CLOSED;
1415 break;
1416 case NES_CM_STATE_FIN_WAIT1:
1417 cm_node->state = NES_CM_STATE_FIN_WAIT2;
1418 break;
1419 case NES_CM_STATE_CLOSING:
1420 cm_node->state = NES_CM_STATE_TIME_WAIT;
1421 /* need to schedule this to happen in 2MSL timeouts */
1422 cm_node->state = NES_CM_STATE_CLOSED;
1423 break;
1424 case NES_CM_STATE_ONE_SIDE_ESTABLISHED:
1425 case NES_CM_STATE_ESTABLISHED:
1426 case NES_CM_STATE_MPAREQ_SENT:
1427 case NES_CM_STATE_CLOSE_WAIT:
1428 case NES_CM_STATE_TIME_WAIT:
1429 case NES_CM_STATE_CLOSED:
1430 break;
1431 case NES_CM_STATE_LISTENING:
1432 nes_debug(NES_DBG_CM, "Received an ACK on a listening port (SYN %d)\n", tcph->syn);
1433 cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq);
1434 send_reset(cm_node);
1435 /* send_reset bumps refcount, this should have been a new node */
1436 rem_ref_cm_node(cm_core, cm_node);
1437 return -1;
1438 break;
1439 case NES_CM_STATE_TSA:
1440 nes_debug(NES_DBG_CM, "Received a packet with the ack bit set while in TSA state\n");
1441 break;
1442 case NES_CM_STATE_UNKNOWN:
1443 case NES_CM_STATE_INITED:
1444 case NES_CM_STATE_ACCEPTING:
1445 case NES_CM_STATE_FIN_WAIT2:
1446 default:
1447 nes_debug(NES_DBG_CM, "Received ack from unknown state: %x\n",
1448 cm_node->state);
1449 send_reset(cm_node);
1450 break;
1451 }
1452 }
1453 1648
1454 if (tcph->syn) { 1649static void active_open_err(struct nes_cm_node *cm_node, struct sk_buff *skb,
1455 if (cm_node->state == NES_CM_STATE_LISTENING) { 1650 int reset)
1456 /* do not exceed backlog */ 1651{
1457 atomic_inc(&cm_node->listener->pend_accepts_cnt); 1652 cleanup_retrans_entry(cm_node);
1458 if (atomic_read(&cm_node->listener->pend_accepts_cnt) > 1653 if (reset) {
1459 cm_node->listener->backlog) { 1654 nes_debug(NES_DBG_CM, "ERROR active err called for cm_node=%p, "
1460 nes_debug(NES_DBG_CM, "drop syn due to backlog pressure \n"); 1655 "state=%d\n", cm_node, cm_node->state);
1461 cm_backlog_drops++; 1656 add_ref_cm_node(cm_node);
1462 atomic_dec(&cm_node->listener->pend_accepts_cnt); 1657 send_reset(cm_node, skb);
1463 rem_ref_cm_node(cm_core, cm_node); 1658 } else
1464 return 0; 1659 dev_kfree_skb_any(skb);
1465 }
1466 cm_node->accept_pend = 1;
1467 1660
1468 } 1661 cm_node->state = NES_CM_STATE_CLOSED;
1469 if (datasize == 0) 1662 create_event(cm_node, NES_CM_EVENT_ABORTED);
1470 cm_node->tcp_cntxt.rcv_nxt ++; 1663}
1471 1664
1472 if (cm_node->state == NES_CM_STATE_LISTENING) { 1665/*
1473 cm_node->state = NES_CM_STATE_SYN_RCVD; 1666 * passive_open_err() will either do a reset() or will free up the skb and
1474 send_syn(cm_node, 1); 1667 * remove the cm_node.
1475 } 1668 */
1476 if (cm_node->state == NES_CM_STATE_ONE_SIDE_ESTABLISHED) {
1477 cm_node->state = NES_CM_STATE_ESTABLISHED;
1478 /* send final handshake ACK */
1479 ret = send_ack(cm_node);
1480 if (ret < 0)
1481 return ret;
1482 1669
1483 cm_node->state = NES_CM_STATE_MPAREQ_SENT; 1670static void passive_open_err(struct nes_cm_node *cm_node, struct sk_buff *skb,
1484 ret = send_mpa_request(cm_node); 1671 int reset)
1485 if (ret < 0) 1672{
1486 return ret; 1673 cleanup_retrans_entry(cm_node);
1487 } 1674 cm_node->state = NES_CM_STATE_CLOSED;
1675 if (reset) {
1676 nes_debug(NES_DBG_CM, "passive_open_err sending RST for "
1677 "cm_node=%p state =%d\n", cm_node, cm_node->state);
1678 send_reset(cm_node, skb);
1679 } else {
1680 dev_kfree_skb_any(skb);
1681 rem_ref_cm_node(cm_node->cm_core, cm_node);
1488 } 1682 }
1683}
1489 1684
1490 if (tcph->fin) { 1685/*
1491 cm_node->tcp_cntxt.rcv_nxt++; 1686 * free_retrans_entry() routines assumes that the retrans_list_lock has
1492 switch (cm_node->state) { 1687 * been acquired before calling.
1493 case NES_CM_STATE_SYN_RCVD: 1688 */
1494 case NES_CM_STATE_SYN_SENT: 1689static void free_retrans_entry(struct nes_cm_node *cm_node)
1495 case NES_CM_STATE_ONE_SIDE_ESTABLISHED: 1690{
1496 case NES_CM_STATE_ESTABLISHED: 1691 struct nes_timer_entry *send_entry;
1497 case NES_CM_STATE_ACCEPTING: 1692 send_entry = cm_node->send_entry;
1498 case NES_CM_STATE_MPAREQ_SENT: 1693 if (send_entry) {
1499 cm_node->state = NES_CM_STATE_CLOSE_WAIT; 1694 cm_node->send_entry = NULL;
1500 cm_node->state = NES_CM_STATE_LAST_ACK; 1695 dev_kfree_skb_any(send_entry->skb);
1501 ret = send_fin(cm_node, NULL); 1696 kfree(send_entry);
1502 break; 1697 rem_ref_cm_node(cm_node->cm_core, cm_node);
1503 case NES_CM_STATE_FIN_WAIT1:
1504 cm_node->state = NES_CM_STATE_CLOSING;
1505 ret = send_ack(cm_node);
1506 break;
1507 case NES_CM_STATE_FIN_WAIT2:
1508 cm_node->state = NES_CM_STATE_TIME_WAIT;
1509 cm_node->tcp_cntxt.loc_seq_num ++;
1510 ret = send_ack(cm_node);
1511 /* need to schedule this to happen in 2MSL timeouts */
1512 cm_node->state = NES_CM_STATE_CLOSED;
1513 break;
1514 case NES_CM_STATE_CLOSE_WAIT:
1515 case NES_CM_STATE_LAST_ACK:
1516 case NES_CM_STATE_CLOSING:
1517 case NES_CM_STATE_TSA:
1518 default:
1519 nes_debug(NES_DBG_CM, "Received a fin while in %x state\n",
1520 cm_node->state);
1521 ret = -EINVAL;
1522 break;
1523 }
1524 } 1698 }
1699}
1525 1700
1526 if (datasize) { 1701static void cleanup_retrans_entry(struct nes_cm_node *cm_node)
1527 u8 *dataloc = skb->data; 1702{
1528 /* figure out what state we are in and handle transition to next state */ 1703 unsigned long flags;
1529 switch (cm_node->state) {
1530 case NES_CM_STATE_LISTENING:
1531 case NES_CM_STATE_SYN_RCVD:
1532 case NES_CM_STATE_SYN_SENT:
1533 case NES_CM_STATE_FIN_WAIT1:
1534 case NES_CM_STATE_FIN_WAIT2:
1535 case NES_CM_STATE_CLOSE_WAIT:
1536 case NES_CM_STATE_LAST_ACK:
1537 case NES_CM_STATE_CLOSING:
1538 break;
1539 case NES_CM_STATE_MPAREQ_SENT:
1540 /* recv the mpa res frame, ret=frame len (incl priv data) */
1541 ret = parse_mpa(cm_node, dataloc, datasize);
1542 if (ret < 0)
1543 break;
1544 /* set the req frame payload len in skb */
1545 /* we are done handling this state, set node to a TSA state */
1546 cm_node->state = NES_CM_STATE_TSA;
1547 send_ack(cm_node);
1548 create_event(cm_node, NES_CM_EVENT_CONNECTED);
1549 break;
1550
1551 case NES_CM_STATE_ESTABLISHED:
1552 /* we are expecting an MPA req frame */
1553 ret = parse_mpa(cm_node, dataloc, datasize);
1554 if (ret < 0) {
1555 break;
1556 }
1557 cm_node->state = NES_CM_STATE_TSA;
1558 send_ack(cm_node);
1559 /* we got a valid MPA request, create an event */
1560 create_event(cm_node, NES_CM_EVENT_MPA_REQ);
1561 break;
1562 case NES_CM_STATE_TSA:
1563 handle_exception_pkt(cm_node, skb);
1564 break;
1565 case NES_CM_STATE_UNKNOWN:
1566 case NES_CM_STATE_INITED:
1567 default:
1568 ret = -1;
1569 }
1570 }
1571 1704
1572 return ret; 1705 spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
1706 free_retrans_entry(cm_node);
1707 spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags);
1573} 1708}
1574 1709
1710/**
1711 * process_packet
1712 * Returns skb if to be freed, else it will return NULL if already used..
1713 */
1714static void process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb,
1715 struct nes_cm_core *cm_core)
1716{
1717 enum nes_tcpip_pkt_type pkt_type = NES_PKT_TYPE_UNKNOWN;
1718 struct tcphdr *tcph = tcp_hdr(skb);
1719 skb_pull(skb, ip_hdr(skb)->ihl << 2);
1720
1721 nes_debug(NES_DBG_CM, "process_packet: cm_node=%p state =%d syn=%d "
1722 "ack=%d rst=%d fin=%d\n", cm_node, cm_node->state, tcph->syn,
1723 tcph->ack, tcph->rst, tcph->fin);
1724
1725 if (tcph->rst)
1726 pkt_type = NES_PKT_TYPE_RST;
1727 else if (tcph->syn) {
1728 pkt_type = NES_PKT_TYPE_SYN;
1729 if (tcph->ack)
1730 pkt_type = NES_PKT_TYPE_SYNACK;
1731 } else if (tcph->fin)
1732 pkt_type = NES_PKT_TYPE_FIN;
1733 else if (tcph->ack)
1734 pkt_type = NES_PKT_TYPE_ACK;
1735
1736 switch (pkt_type) {
1737 case NES_PKT_TYPE_SYN:
1738 handle_syn_pkt(cm_node, skb, tcph);
1739 break;
1740 case NES_PKT_TYPE_SYNACK:
1741 handle_synack_pkt(cm_node, skb, tcph);
1742 break;
1743 case NES_PKT_TYPE_ACK:
1744 handle_ack_pkt(cm_node, skb, tcph);
1745 break;
1746 case NES_PKT_TYPE_RST:
1747 handle_rst_pkt(cm_node, skb, tcph);
1748 break;
1749 case NES_PKT_TYPE_FIN:
1750 handle_fin_pkt(cm_node, skb, tcph);
1751 break;
1752 default:
1753 drop_packet(skb);
1754 break;
1755 }
1756}
1575 1757
1576/** 1758/**
1577 * mini_cm_listen - create a listen node with params 1759 * mini_cm_listen - create a listen node with params
1578 */ 1760 */
1579static struct nes_cm_listener *mini_cm_listen(struct nes_cm_core *cm_core, 1761static struct nes_cm_listener *mini_cm_listen(struct nes_cm_core *cm_core,
1580 struct nes_vnic *nesvnic, struct nes_cm_info *cm_info) 1762 struct nes_vnic *nesvnic, struct nes_cm_info *cm_info)
1581{ 1763{
1582 struct nes_cm_listener *listener; 1764 struct nes_cm_listener *listener;
1583 unsigned long flags; 1765 unsigned long flags;
@@ -1644,37 +1826,36 @@ static struct nes_cm_listener *mini_cm_listen(struct nes_cm_core *cm_core,
1644/** 1826/**
1645 * mini_cm_connect - make a connection node with params 1827 * mini_cm_connect - make a connection node with params
1646 */ 1828 */
1647static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core, 1829struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core,
1648 struct nes_vnic *nesvnic, 1830 struct nes_vnic *nesvnic, u16 private_data_len,
1649 struct ietf_mpa_frame *mpa_frame, 1831 void *private_data, struct nes_cm_info *cm_info)
1650 struct nes_cm_info *cm_info)
1651{ 1832{
1652 int ret = 0; 1833 int ret = 0;
1653 struct nes_cm_node *cm_node; 1834 struct nes_cm_node *cm_node;
1654 struct nes_cm_listener *loopbackremotelistener; 1835 struct nes_cm_listener *loopbackremotelistener;
1655 struct nes_cm_node *loopbackremotenode; 1836 struct nes_cm_node *loopbackremotenode;
1656 struct nes_cm_info loopback_cm_info; 1837 struct nes_cm_info loopback_cm_info;
1657 1838 u16 mpa_frame_size = sizeof(struct ietf_mpa_frame) + private_data_len;
1658 u16 mpa_frame_size = sizeof(struct ietf_mpa_frame) + 1839 struct ietf_mpa_frame *mpa_frame = NULL;
1659 ntohs(mpa_frame->priv_data_len);
1660
1661 cm_info->loc_addr = htonl(cm_info->loc_addr);
1662 cm_info->rem_addr = htonl(cm_info->rem_addr);
1663 cm_info->loc_port = htons(cm_info->loc_port);
1664 cm_info->rem_port = htons(cm_info->rem_port);
1665 1840
1666 /* create a CM connection node */ 1841 /* create a CM connection node */
1667 cm_node = make_cm_node(cm_core, nesvnic, cm_info, NULL); 1842 cm_node = make_cm_node(cm_core, nesvnic, cm_info, NULL);
1668 if (!cm_node) 1843 if (!cm_node)
1669 return NULL; 1844 return NULL;
1845 mpa_frame = &cm_node->mpa_frame;
1846 strcpy(mpa_frame->key, IEFT_MPA_KEY_REQ);
1847 mpa_frame->flags = IETF_MPA_FLAGS_CRC;
1848 mpa_frame->rev = IETF_MPA_VERSION;
1849 mpa_frame->priv_data_len = htons(private_data_len);
1670 1850
1671 /* set our node side to client (active) side */ 1851 /* set our node side to client (active) side */
1672 cm_node->tcp_cntxt.client = 1; 1852 cm_node->tcp_cntxt.client = 1;
1673 cm_node->tcp_cntxt.rcv_wscale = NES_CM_DEFAULT_RCV_WND_SCALE; 1853 cm_node->tcp_cntxt.rcv_wscale = NES_CM_DEFAULT_RCV_WND_SCALE;
1674 1854
1675 if (cm_info->loc_addr == cm_info->rem_addr) { 1855 if (cm_info->loc_addr == cm_info->rem_addr) {
1676 loopbackremotelistener = find_listener(cm_core, cm_node->rem_addr, 1856 loopbackremotelistener = find_listener(cm_core,
1677 cm_node->rem_port, NES_CM_LISTENER_ACTIVE_STATE); 1857 ntohl(nesvnic->local_ipaddr), cm_node->rem_port,
1858 NES_CM_LISTENER_ACTIVE_STATE);
1678 if (loopbackremotelistener == NULL) { 1859 if (loopbackremotelistener == NULL) {
1679 create_event(cm_node, NES_CM_EVENT_ABORTED); 1860 create_event(cm_node, NES_CM_EVENT_ABORTED);
1680 } else { 1861 } else {
@@ -1683,26 +1864,35 @@ static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core,
1683 loopback_cm_info.loc_port = cm_info->rem_port; 1864 loopback_cm_info.loc_port = cm_info->rem_port;
1684 loopback_cm_info.rem_port = cm_info->loc_port; 1865 loopback_cm_info.rem_port = cm_info->loc_port;
1685 loopback_cm_info.cm_id = loopbackremotelistener->cm_id; 1866 loopback_cm_info.cm_id = loopbackremotelistener->cm_id;
1686 loopbackremotenode = make_cm_node(cm_core, nesvnic, &loopback_cm_info, 1867 loopbackremotenode = make_cm_node(cm_core, nesvnic,
1687 loopbackremotelistener); 1868 &loopback_cm_info, loopbackremotelistener);
1688 loopbackremotenode->loopbackpartner = cm_node; 1869 loopbackremotenode->loopbackpartner = cm_node;
1689 loopbackremotenode->tcp_cntxt.rcv_wscale = NES_CM_DEFAULT_RCV_WND_SCALE; 1870 loopbackremotenode->tcp_cntxt.rcv_wscale =
1871 NES_CM_DEFAULT_RCV_WND_SCALE;
1690 cm_node->loopbackpartner = loopbackremotenode; 1872 cm_node->loopbackpartner = loopbackremotenode;
1691 memcpy(loopbackremotenode->mpa_frame_buf, &mpa_frame->priv_data, 1873 memcpy(loopbackremotenode->mpa_frame_buf, private_data,
1692 mpa_frame_size); 1874 private_data_len);
1693 loopbackremotenode->mpa_frame_size = mpa_frame_size - 1875 loopbackremotenode->mpa_frame_size = private_data_len;
1694 sizeof(struct ietf_mpa_frame);
1695 1876
1696 /* we are done handling this state, set node to a TSA state */ 1877 /* we are done handling this state. */
1878 /* set node to a TSA state */
1697 cm_node->state = NES_CM_STATE_TSA; 1879 cm_node->state = NES_CM_STATE_TSA;
1698 cm_node->tcp_cntxt.rcv_nxt = loopbackremotenode->tcp_cntxt.loc_seq_num; 1880 cm_node->tcp_cntxt.rcv_nxt =
1699 loopbackremotenode->tcp_cntxt.rcv_nxt = cm_node->tcp_cntxt.loc_seq_num; 1881 loopbackremotenode->tcp_cntxt.loc_seq_num;
1700 cm_node->tcp_cntxt.max_snd_wnd = loopbackremotenode->tcp_cntxt.rcv_wnd; 1882 loopbackremotenode->tcp_cntxt.rcv_nxt =
1701 loopbackremotenode->tcp_cntxt.max_snd_wnd = cm_node->tcp_cntxt.rcv_wnd; 1883 cm_node->tcp_cntxt.loc_seq_num;
1702 cm_node->tcp_cntxt.snd_wnd = loopbackremotenode->tcp_cntxt.rcv_wnd; 1884 cm_node->tcp_cntxt.max_snd_wnd =
1703 loopbackremotenode->tcp_cntxt.snd_wnd = cm_node->tcp_cntxt.rcv_wnd; 1885 loopbackremotenode->tcp_cntxt.rcv_wnd;
1704 cm_node->tcp_cntxt.snd_wscale = loopbackremotenode->tcp_cntxt.rcv_wscale; 1886 loopbackremotenode->tcp_cntxt.max_snd_wnd =
1705 loopbackremotenode->tcp_cntxt.snd_wscale = cm_node->tcp_cntxt.rcv_wscale; 1887 cm_node->tcp_cntxt.rcv_wnd;
1888 cm_node->tcp_cntxt.snd_wnd =
1889 loopbackremotenode->tcp_cntxt.rcv_wnd;
1890 loopbackremotenode->tcp_cntxt.snd_wnd =
1891 cm_node->tcp_cntxt.rcv_wnd;
1892 cm_node->tcp_cntxt.snd_wscale =
1893 loopbackremotenode->tcp_cntxt.rcv_wscale;
1894 loopbackremotenode->tcp_cntxt.snd_wscale =
1895 cm_node->tcp_cntxt.rcv_wscale;
1706 1896
1707 create_event(loopbackremotenode, NES_CM_EVENT_MPA_REQ); 1897 create_event(loopbackremotenode, NES_CM_EVENT_MPA_REQ);
1708 } 1898 }
@@ -1712,16 +1902,29 @@ static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core,
1712 /* set our node side to client (active) side */ 1902 /* set our node side to client (active) side */
1713 cm_node->tcp_cntxt.client = 1; 1903 cm_node->tcp_cntxt.client = 1;
1714 /* init our MPA frame ptr */ 1904 /* init our MPA frame ptr */
1715 memcpy(&cm_node->mpa_frame, mpa_frame, mpa_frame_size); 1905 memcpy(mpa_frame->priv_data, private_data, private_data_len);
1906
1716 cm_node->mpa_frame_size = mpa_frame_size; 1907 cm_node->mpa_frame_size = mpa_frame_size;
1717 1908
1718 /* send a syn and goto syn sent state */ 1909 /* send a syn and goto syn sent state */
1719 cm_node->state = NES_CM_STATE_SYN_SENT; 1910 cm_node->state = NES_CM_STATE_SYN_SENT;
1720 ret = send_syn(cm_node, 0); 1911 ret = send_syn(cm_node, 0, NULL);
1912
1913 if (ret) {
1914 /* error in sending the syn free up the cm_node struct */
1915 nes_debug(NES_DBG_CM, "Api - connect() FAILED: dest "
1916 "addr=0x%08X, port=0x%04x, cm_node=%p, cm_id = %p.\n",
1917 cm_node->rem_addr, cm_node->rem_port, cm_node,
1918 cm_node->cm_id);
1919 rem_ref_cm_node(cm_node->cm_core, cm_node);
1920 cm_node = NULL;
1921 }
1721 1922
1722 nes_debug(NES_DBG_CM, "Api - connect(): dest addr=0x%08X, port=0x%04x," 1923 if (cm_node)
1723 " cm_node=%p, cm_id = %p.\n", 1924 nes_debug(NES_DBG_CM, "Api - connect(): dest addr=0x%08X,"
1724 cm_node->rem_addr, cm_node->rem_port, cm_node, cm_node->cm_id); 1925 "port=0x%04x, cm_node=%p, cm_id = %p.\n",
1926 cm_node->rem_addr, cm_node->rem_port, cm_node,
1927 cm_node->cm_id);
1725 1928
1726 return cm_node; 1929 return cm_node;
1727} 1930}
@@ -1731,8 +1934,8 @@ static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core,
1731 * mini_cm_accept - accept a connection 1934 * mini_cm_accept - accept a connection
1732 * This function is never called 1935 * This function is never called
1733 */ 1936 */
1734static int mini_cm_accept(struct nes_cm_core *cm_core, struct ietf_mpa_frame *mpa_frame, 1937static int mini_cm_accept(struct nes_cm_core *cm_core,
1735 struct nes_cm_node *cm_node) 1938 struct ietf_mpa_frame *mpa_frame, struct nes_cm_node *cm_node)
1736{ 1939{
1737 return 0; 1940 return 0;
1738} 1941}
@@ -1742,32 +1945,26 @@ static int mini_cm_accept(struct nes_cm_core *cm_core, struct ietf_mpa_frame *mp
1742 * mini_cm_reject - reject and teardown a connection 1945 * mini_cm_reject - reject and teardown a connection
1743 */ 1946 */
1744static int mini_cm_reject(struct nes_cm_core *cm_core, 1947static int mini_cm_reject(struct nes_cm_core *cm_core,
1745 struct ietf_mpa_frame *mpa_frame, 1948 struct ietf_mpa_frame *mpa_frame, struct nes_cm_node *cm_node)
1746 struct nes_cm_node *cm_node)
1747{ 1949{
1748 int ret = 0; 1950 int ret = 0;
1749 struct sk_buff *skb;
1750 u16 mpa_frame_size = sizeof(struct ietf_mpa_frame) +
1751 ntohs(mpa_frame->priv_data_len);
1752 1951
1753 skb = get_free_pkt(cm_node); 1952 nes_debug(NES_DBG_CM, "%s cm_node=%p type=%d state=%d\n",
1754 if (!skb) { 1953 __func__, cm_node, cm_node->tcp_cntxt.client, cm_node->state);
1755 nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n");
1756 return -1;
1757 }
1758
1759 /* send an MPA Request frame */
1760 form_cm_frame(skb, cm_node, NULL, 0, mpa_frame, mpa_frame_size, SET_ACK | SET_FIN);
1761 ret = schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 1, 0);
1762 1954
1955 if (cm_node->tcp_cntxt.client)
1956 return ret;
1957 cleanup_retrans_entry(cm_node);
1763 cm_node->state = NES_CM_STATE_CLOSED; 1958 cm_node->state = NES_CM_STATE_CLOSED;
1764 ret = send_fin(cm_node, NULL); 1959 ret = send_fin(cm_node, NULL);
1765 1960
1766 if (ret < 0) { 1961 if (cm_node->accept_pend) {
1767 printk(KERN_INFO PFX "failed to send MPA Reply (reject)\n"); 1962 BUG_ON(!cm_node->listener);
1768 return ret; 1963 atomic_dec(&cm_node->listener->pend_accepts_cnt);
1964 BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0);
1769 } 1965 }
1770 1966
1967 ret = send_reset(cm_node, NULL);
1771 return ret; 1968 return ret;
1772} 1969}
1773 1970
@@ -1783,35 +1980,39 @@ static int mini_cm_close(struct nes_cm_core *cm_core, struct nes_cm_node *cm_nod
1783 return -EINVAL; 1980 return -EINVAL;
1784 1981
1785 switch (cm_node->state) { 1982 switch (cm_node->state) {
1786 /* if passed in node is null, create a reference key node for node search */ 1983 case NES_CM_STATE_SYN_RCVD:
1787 /* check if we found an owner node for this pkt */ 1984 case NES_CM_STATE_SYN_SENT:
1788 case NES_CM_STATE_SYN_RCVD: 1985 case NES_CM_STATE_ONE_SIDE_ESTABLISHED:
1789 case NES_CM_STATE_SYN_SENT: 1986 case NES_CM_STATE_ESTABLISHED:
1790 case NES_CM_STATE_ONE_SIDE_ESTABLISHED: 1987 case NES_CM_STATE_ACCEPTING:
1791 case NES_CM_STATE_ESTABLISHED: 1988 case NES_CM_STATE_MPAREQ_SENT:
1792 case NES_CM_STATE_ACCEPTING: 1989 case NES_CM_STATE_MPAREQ_RCVD:
1793 case NES_CM_STATE_MPAREQ_SENT: 1990 cleanup_retrans_entry(cm_node);
1794 cm_node->state = NES_CM_STATE_FIN_WAIT1; 1991 send_reset(cm_node, NULL);
1795 send_fin(cm_node, NULL); 1992 break;
1796 break; 1993 case NES_CM_STATE_CLOSE_WAIT:
1797 case NES_CM_STATE_CLOSE_WAIT: 1994 cm_node->state = NES_CM_STATE_LAST_ACK;
1798 cm_node->state = NES_CM_STATE_LAST_ACK; 1995 send_fin(cm_node, NULL);
1799 send_fin(cm_node, NULL); 1996 break;
1800 break; 1997 case NES_CM_STATE_FIN_WAIT1:
1801 case NES_CM_STATE_FIN_WAIT1: 1998 case NES_CM_STATE_FIN_WAIT2:
1802 case NES_CM_STATE_FIN_WAIT2: 1999 case NES_CM_STATE_LAST_ACK:
1803 case NES_CM_STATE_LAST_ACK: 2000 case NES_CM_STATE_TIME_WAIT:
1804 case NES_CM_STATE_TIME_WAIT: 2001 case NES_CM_STATE_CLOSING:
1805 case NES_CM_STATE_CLOSING: 2002 ret = -1;
1806 ret = -1; 2003 break;
1807 break; 2004 case NES_CM_STATE_LISTENING:
1808 case NES_CM_STATE_LISTENING: 2005 case NES_CM_STATE_UNKNOWN:
1809 case NES_CM_STATE_UNKNOWN: 2006 case NES_CM_STATE_INITED:
1810 case NES_CM_STATE_INITED: 2007 case NES_CM_STATE_CLOSED:
1811 case NES_CM_STATE_CLOSED: 2008 ret = rem_ref_cm_node(cm_core, cm_node);
1812 case NES_CM_STATE_TSA: 2009 break;
1813 ret = rem_ref_cm_node(cm_core, cm_node); 2010 case NES_CM_STATE_TSA:
1814 break; 2011 if (cm_node->send_entry)
2012 printk(KERN_ERR "ERROR Close got called from STATE_TSA "
2013 "send_entry=%p\n", cm_node->send_entry);
2014 ret = rem_ref_cm_node(cm_core, cm_node);
2015 break;
1815 } 2016 }
1816 cm_node->cm_id = NULL; 2017 cm_node->cm_id = NULL;
1817 return ret; 2018 return ret;
@@ -1822,25 +2023,30 @@ static int mini_cm_close(struct nes_cm_core *cm_core, struct nes_cm_node *cm_nod
1822 * recv_pkt - recv an ETHERNET packet, and process it through CM 2023 * recv_pkt - recv an ETHERNET packet, and process it through CM
1823 * node state machine 2024 * node state machine
1824 */ 2025 */
1825static int mini_cm_recv_pkt(struct nes_cm_core *cm_core, struct nes_vnic *nesvnic, 2026static void mini_cm_recv_pkt(struct nes_cm_core *cm_core,
1826 struct sk_buff *skb) 2027 struct nes_vnic *nesvnic, struct sk_buff *skb)
1827{ 2028{
1828 struct nes_cm_node *cm_node = NULL; 2029 struct nes_cm_node *cm_node = NULL;
1829 struct nes_cm_listener *listener = NULL; 2030 struct nes_cm_listener *listener = NULL;
1830 struct iphdr *iph; 2031 struct iphdr *iph;
1831 struct tcphdr *tcph; 2032 struct tcphdr *tcph;
1832 struct nes_cm_info nfo; 2033 struct nes_cm_info nfo;
1833 int ret = 0;
1834 2034
1835 if (!skb || skb->len < sizeof(struct iphdr) + sizeof(struct tcphdr)) { 2035 if (!skb)
1836 ret = -EINVAL; 2036 return;
1837 goto out; 2037 if (skb->len < sizeof(struct iphdr) + sizeof(struct tcphdr)) {
2038 dev_kfree_skb_any(skb);
2039 return;
1838 } 2040 }
1839 2041
1840 iph = (struct iphdr *)skb->data; 2042 iph = (struct iphdr *)skb->data;
1841 tcph = (struct tcphdr *)(skb->data + sizeof(struct iphdr)); 2043 tcph = (struct tcphdr *)(skb->data + sizeof(struct iphdr));
1842 skb_reset_network_header(skb); 2044 skb_reset_network_header(skb);
1843 skb_set_transport_header(skb, sizeof(*tcph)); 2045 skb_set_transport_header(skb, sizeof(*tcph));
2046 if (!tcph) {
2047 dev_kfree_skb_any(skb);
2048 return;
2049 }
1844 skb->len = ntohs(iph->tot_len); 2050 skb->len = ntohs(iph->tot_len);
1845 2051
1846 nfo.loc_addr = ntohl(iph->daddr); 2052 nfo.loc_addr = ntohl(iph->daddr);
@@ -1853,61 +2059,60 @@ static int mini_cm_recv_pkt(struct nes_cm_core *cm_core, struct nes_vnic *nesvni
1853 NIPQUAD(iph->daddr), tcph->dest, 2059 NIPQUAD(iph->daddr), tcph->dest,
1854 NIPQUAD(iph->saddr), tcph->source); 2060 NIPQUAD(iph->saddr), tcph->source);
1855 2061
1856 /* note: this call is going to increment cm_node ref count */ 2062 do {
1857 cm_node = find_node(cm_core, 2063 cm_node = find_node(cm_core,
1858 nfo.rem_port, nfo.rem_addr, 2064 nfo.rem_port, nfo.rem_addr,
1859 nfo.loc_port, nfo.loc_addr); 2065 nfo.loc_port, nfo.loc_addr);
1860 2066
1861 if (!cm_node) {
1862 listener = find_listener(cm_core, nfo.loc_addr, nfo.loc_port,
1863 NES_CM_LISTENER_ACTIVE_STATE);
1864 if (listener) {
1865 nfo.cm_id = listener->cm_id;
1866 nfo.conn_type = listener->conn_type;
1867 } else {
1868 nfo.cm_id = NULL;
1869 nfo.conn_type = 0;
1870 }
1871
1872 cm_node = make_cm_node(cm_core, nesvnic, &nfo, listener);
1873 if (!cm_node) { 2067 if (!cm_node) {
1874 nes_debug(NES_DBG_CM, "Unable to allocate node\n"); 2068 /* Only type of packet accepted are for */
2069 /* the PASSIVE open (syn only) */
2070 if ((!tcph->syn) || (tcph->ack)) {
2071 cm_packets_dropped++;
2072 break;
2073 }
2074 listener = find_listener(cm_core, nfo.loc_addr,
2075 nfo.loc_port,
2076 NES_CM_LISTENER_ACTIVE_STATE);
1875 if (listener) { 2077 if (listener) {
1876 nes_debug(NES_DBG_CM, "unable to allocate node and decrementing listener refcount\n"); 2078 nfo.cm_id = listener->cm_id;
2079 nfo.conn_type = listener->conn_type;
2080 } else {
2081 nes_debug(NES_DBG_CM, "Unable to find listener "
2082 "for the pkt\n");
2083 cm_packets_dropped++;
2084 dev_kfree_skb_any(skb);
2085 break;
2086 }
2087
2088 cm_node = make_cm_node(cm_core, nesvnic, &nfo,
2089 listener);
2090 if (!cm_node) {
2091 nes_debug(NES_DBG_CM, "Unable to allocate "
2092 "node\n");
2093 cm_packets_dropped++;
1877 atomic_dec(&listener->ref_count); 2094 atomic_dec(&listener->ref_count);
2095 dev_kfree_skb_any(skb);
2096 break;
1878 } 2097 }
1879 ret = -1; 2098 if (!tcph->rst && !tcph->fin) {
1880 goto out; 2099 cm_node->state = NES_CM_STATE_LISTENING;
1881 } 2100 } else {
1882 if (!listener) { 2101 cm_packets_dropped++;
1883 nes_debug(NES_DBG_CM, "Packet found for unknown port %x refcnt=%d\n", 2102 rem_ref_cm_node(cm_core, cm_node);
1884 nfo.loc_port, atomic_read(&cm_node->ref_count)); 2103 dev_kfree_skb_any(skb);
1885 if (!tcph->rst) { 2104 break;
1886 nes_debug(NES_DBG_CM, "Packet found for unknown port=%d"
1887 " rem_port=%d refcnt=%d\n",
1888 nfo.loc_port, nfo.rem_port, atomic_read(&cm_node->ref_count));
1889
1890 cm_node->tcp_cntxt.rcv_nxt = ntohl(tcph->seq);
1891 cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq);
1892 send_reset(cm_node);
1893 } 2105 }
2106 add_ref_cm_node(cm_node);
2107 } else if (cm_node->state == NES_CM_STATE_TSA) {
1894 rem_ref_cm_node(cm_core, cm_node); 2108 rem_ref_cm_node(cm_core, cm_node);
1895 ret = -1; 2109 atomic_inc(&cm_accel_dropped_pkts);
1896 goto out; 2110 dev_kfree_skb_any(skb);
2111 break;
1897 } 2112 }
1898 add_ref_cm_node(cm_node); 2113 process_packet(cm_node, skb, cm_core);
1899 cm_node->state = NES_CM_STATE_LISTENING; 2114 rem_ref_cm_node(cm_core, cm_node);
1900 } 2115 } while (0);
1901
1902 nes_debug(NES_DBG_CM, "Processing Packet for node %p, data = (%p):\n",
1903 cm_node, skb->data);
1904 process_packet(cm_node, skb, cm_core);
1905
1906 rem_ref_cm_node(cm_core, cm_node);
1907 out:
1908 if (skb)
1909 dev_kfree_skb_any(skb);
1910 return ret;
1911} 2116}
1912 2117
1913 2118
@@ -2107,15 +2312,12 @@ int nes_cm_disconn(struct nes_qp *nesqp)
2107 if (nesqp->disconn_pending == 0) { 2312 if (nesqp->disconn_pending == 0) {
2108 nesqp->disconn_pending++; 2313 nesqp->disconn_pending++;
2109 spin_unlock_irqrestore(&nesqp->lock, flags); 2314 spin_unlock_irqrestore(&nesqp->lock, flags);
2110 /* nes_add_ref(&nesqp->ibqp); */
2111 /* init our disconnect work element, to */ 2315 /* init our disconnect work element, to */
2112 INIT_WORK(&nesqp->disconn_work, nes_disconnect_worker); 2316 INIT_WORK(&nesqp->disconn_work, nes_disconnect_worker);
2113 2317
2114 queue_work(g_cm_core->disconn_wq, &nesqp->disconn_work); 2318 queue_work(g_cm_core->disconn_wq, &nesqp->disconn_work);
2115 } else { 2319 } else
2116 spin_unlock_irqrestore(&nesqp->lock, flags); 2320 spin_unlock_irqrestore(&nesqp->lock, flags);
2117 nes_rem_ref(&nesqp->ibqp);
2118 }
2119 2321
2120 return 0; 2322 return 0;
2121} 2323}
@@ -2161,7 +2363,6 @@ static int nes_cm_disconn_true(struct nes_qp *nesqp)
2161 nes_debug(NES_DBG_CM, "QP%u disconnect_worker cmid is NULL\n", 2363 nes_debug(NES_DBG_CM, "QP%u disconnect_worker cmid is NULL\n",
2162 nesqp->hwqp.qp_id); 2364 nesqp->hwqp.qp_id);
2163 spin_unlock_irqrestore(&nesqp->lock, flags); 2365 spin_unlock_irqrestore(&nesqp->lock, flags);
2164 nes_rem_ref(&nesqp->ibqp);
2165 return -1; 2366 return -1;
2166 } 2367 }
2167 2368
@@ -2182,30 +2383,31 @@ static int nes_cm_disconn_true(struct nes_qp *nesqp)
2182 atomic_inc(&cm_disconnects); 2383 atomic_inc(&cm_disconnects);
2183 cm_event.event = IW_CM_EVENT_DISCONNECT; 2384 cm_event.event = IW_CM_EVENT_DISCONNECT;
2184 if (last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET) { 2385 if (last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET) {
2185 issued_disconnect_reset = 1;
2186 cm_event.status = IW_CM_EVENT_STATUS_RESET; 2386 cm_event.status = IW_CM_EVENT_STATUS_RESET;
2187 nes_debug(NES_DBG_CM, "Generating a CM Disconnect Event (status reset) for " 2387 nes_debug(NES_DBG_CM, "Generating a CM "
2188 " QP%u, cm_id = %p. \n", 2388 "Disconnect Event (status reset) for "
2189 nesqp->hwqp.qp_id, cm_id); 2389 "QP%u, cm_id = %p. \n",
2190 } else { 2390 nesqp->hwqp.qp_id, cm_id);
2391 } else
2191 cm_event.status = IW_CM_EVENT_STATUS_OK; 2392 cm_event.status = IW_CM_EVENT_STATUS_OK;
2192 }
2193 2393
2194 cm_event.local_addr = cm_id->local_addr; 2394 cm_event.local_addr = cm_id->local_addr;
2195 cm_event.remote_addr = cm_id->remote_addr; 2395 cm_event.remote_addr = cm_id->remote_addr;
2196 cm_event.private_data = NULL; 2396 cm_event.private_data = NULL;
2197 cm_event.private_data_len = 0; 2397 cm_event.private_data_len = 0;
2198 2398
2199 nes_debug(NES_DBG_CM, "Generating a CM Disconnect Event for " 2399 nes_debug(NES_DBG_CM, "Generating a CM Disconnect Event"
2200 " QP%u, SQ Head = %u, SQ Tail = %u. cm_id = %p, refcount = %u.\n", 2400 " for QP%u, SQ Head = %u, SQ Tail = %u. "
2201 nesqp->hwqp.qp_id, 2401 "cm_id = %p, refcount = %u.\n",
2202 nesqp->hwqp.sq_head, nesqp->hwqp.sq_tail, cm_id, 2402 nesqp->hwqp.qp_id, nesqp->hwqp.sq_head,
2203 atomic_read(&nesqp->refcount)); 2403 nesqp->hwqp.sq_tail, cm_id,
2404 atomic_read(&nesqp->refcount));
2204 2405
2205 spin_unlock_irqrestore(&nesqp->lock, flags); 2406 spin_unlock_irqrestore(&nesqp->lock, flags);
2206 ret = cm_id->event_handler(cm_id, &cm_event); 2407 ret = cm_id->event_handler(cm_id, &cm_event);
2207 if (ret) 2408 if (ret)
2208 nes_debug(NES_DBG_CM, "OFA CM event_handler returned, ret=%d\n", ret); 2409 nes_debug(NES_DBG_CM, "OFA CM event_handler "
2410 "returned, ret=%d\n", ret);
2209 spin_lock_irqsave(&nesqp->lock, flags); 2411 spin_lock_irqsave(&nesqp->lock, flags);
2210 } 2412 }
2211 2413
@@ -2247,31 +2449,24 @@ static int nes_cm_disconn_true(struct nes_qp *nesqp)
2247 if (nesqp->flush_issued == 0) { 2449 if (nesqp->flush_issued == 0) {
2248 nesqp->flush_issued = 1; 2450 nesqp->flush_issued = 1;
2249 spin_unlock_irqrestore(&nesqp->lock, flags); 2451 spin_unlock_irqrestore(&nesqp->lock, flags);
2250 flush_wqes(nesvnic->nesdev, nesqp, NES_CQP_FLUSH_RQ, 1); 2452 flush_wqes(nesvnic->nesdev, nesqp,
2251 } else { 2453 NES_CQP_FLUSH_RQ, 1);
2454 } else
2252 spin_unlock_irqrestore(&nesqp->lock, flags); 2455 spin_unlock_irqrestore(&nesqp->lock, flags);
2253 }
2254
2255 /* This reference is from either ModifyQP or the AE processing,
2256 there is still a race here with modifyqp */
2257 nes_rem_ref(&nesqp->ibqp);
2258
2259 } else { 2456 } else {
2260 cm_id = nesqp->cm_id; 2457 cm_id = nesqp->cm_id;
2261 spin_unlock_irqrestore(&nesqp->lock, flags); 2458 spin_unlock_irqrestore(&nesqp->lock, flags);
2262 /* check to see if the inbound reset beat the outbound reset */ 2459 /* check to see if the inbound reset beat the outbound reset */
2263 if ((!cm_id) && (last_ae==NES_AEQE_AEID_RESET_SENT)) { 2460 if ((!cm_id) && (last_ae==NES_AEQE_AEID_RESET_SENT)) {
2264 nes_debug(NES_DBG_CM, "QP%u: Decing refcount due to inbound reset" 2461 nes_debug(NES_DBG_CM, "QP%u: Decing refcount "
2265 " beating the outbound reset.\n", 2462 "due to inbound reset beating the "
2266 nesqp->hwqp.qp_id); 2463 "outbound reset.\n", nesqp->hwqp.qp_id);
2267 nes_rem_ref(&nesqp->ibqp);
2268 } 2464 }
2269 } 2465 }
2270 } else { 2466 } else {
2271 nesqp->disconn_pending = 0; 2467 nesqp->disconn_pending = 0;
2272 spin_unlock_irqrestore(&nesqp->lock, flags); 2468 spin_unlock_irqrestore(&nesqp->lock, flags);
2273 } 2469 }
2274 nes_rem_ref(&nesqp->ibqp);
2275 2470
2276 return 0; 2471 return 0;
2277} 2472}
@@ -2349,71 +2544,82 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
2349 nesdev = nesvnic->nesdev; 2544 nesdev = nesvnic->nesdev;
2350 adapter = nesdev->nesadapter; 2545 adapter = nesdev->nesadapter;
2351 2546
2352 nes_debug(NES_DBG_CM, "nesvnic=%p, netdev=%p, %s\n",
2353 nesvnic, nesvnic->netdev, nesvnic->netdev->name);
2354
2355 /* since this is from a listen, we were able to put node handle into cm_id */
2356 cm_node = (struct nes_cm_node *)cm_id->provider_data; 2547 cm_node = (struct nes_cm_node *)cm_id->provider_data;
2548 nes_debug(NES_DBG_CM, "nes_accept: cm_node= %p nesvnic=%p, netdev=%p,"
2549 "%s\n", cm_node, nesvnic, nesvnic->netdev,
2550 nesvnic->netdev->name);
2357 2551
2358 /* associate the node with the QP */ 2552 /* associate the node with the QP */
2359 nesqp->cm_node = (void *)cm_node; 2553 nesqp->cm_node = (void *)cm_node;
2554 cm_node->nesqp = nesqp;
2555 nes_add_ref(&nesqp->ibqp);
2360 2556
2361 nes_debug(NES_DBG_CM, "QP%u, cm_node=%p, jiffies = %lu\n", 2557 nes_debug(NES_DBG_CM, "QP%u, cm_node=%p, jiffies = %lu listener = %p\n",
2362 nesqp->hwqp.qp_id, cm_node, jiffies); 2558 nesqp->hwqp.qp_id, cm_node, jiffies, cm_node->listener);
2363 atomic_inc(&cm_accepts); 2559 atomic_inc(&cm_accepts);
2364 2560
2365 nes_debug(NES_DBG_CM, "netdev refcnt = %u.\n", 2561 nes_debug(NES_DBG_CM, "netdev refcnt = %u.\n",
2366 atomic_read(&nesvnic->netdev->refcnt)); 2562 atomic_read(&nesvnic->netdev->refcnt));
2367 2563
2368 /* allocate the ietf frame and space for private data */ 2564 /* allocate the ietf frame and space for private data */
2369 nesqp->ietf_frame = pci_alloc_consistent(nesdev->pcidev, 2565 nesqp->ietf_frame = pci_alloc_consistent(nesdev->pcidev,
2370 sizeof(struct ietf_mpa_frame) + conn_param->private_data_len, 2566 sizeof(struct ietf_mpa_frame) + conn_param->private_data_len,
2371 &nesqp->ietf_frame_pbase); 2567 &nesqp->ietf_frame_pbase);
2372
2373 if (!nesqp->ietf_frame) {
2374 nes_debug(NES_DBG_CM, "Unable to allocate memory for private data\n");
2375 return -ENOMEM;
2376 }
2377 2568
2569 if (!nesqp->ietf_frame) {
2570 nes_debug(NES_DBG_CM, "Unable to allocate memory for private "
2571 "data\n");
2572 return -ENOMEM;
2573 }
2378 2574
2379 /* setup the MPA frame */
2380 nesqp->private_data_len = conn_param->private_data_len;
2381 memcpy(nesqp->ietf_frame->key, IEFT_MPA_KEY_REP, IETF_MPA_KEY_SIZE);
2382 2575
2383 memcpy(nesqp->ietf_frame->priv_data, conn_param->private_data, 2576 /* setup the MPA frame */
2384 conn_param->private_data_len); 2577 nesqp->private_data_len = conn_param->private_data_len;
2578 memcpy(nesqp->ietf_frame->key, IEFT_MPA_KEY_REP, IETF_MPA_KEY_SIZE);
2385 2579
2386 nesqp->ietf_frame->priv_data_len = cpu_to_be16(conn_param->private_data_len); 2580 memcpy(nesqp->ietf_frame->priv_data, conn_param->private_data,
2387 nesqp->ietf_frame->rev = mpa_version; 2581 conn_param->private_data_len);
2388 nesqp->ietf_frame->flags = IETF_MPA_FLAGS_CRC;
2389 2582
2390 /* setup our first outgoing iWarp send WQE (the IETF frame response) */ 2583 nesqp->ietf_frame->priv_data_len =
2391 wqe = &nesqp->hwqp.sq_vbase[0]; 2584 cpu_to_be16(conn_param->private_data_len);
2585 nesqp->ietf_frame->rev = mpa_version;
2586 nesqp->ietf_frame->flags = IETF_MPA_FLAGS_CRC;
2392 2587
2393 if (cm_id->remote_addr.sin_addr.s_addr != cm_id->local_addr.sin_addr.s_addr) { 2588 /* setup our first outgoing iWarp send WQE (the IETF frame response) */
2394 u64temp = (unsigned long)nesqp; 2589 wqe = &nesqp->hwqp.sq_vbase[0];
2395 u64temp |= NES_SW_CONTEXT_ALIGN>>1; 2590
2396 set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_COMP_CTX_LOW_IDX, 2591 if (cm_id->remote_addr.sin_addr.s_addr !=
2397 u64temp); 2592 cm_id->local_addr.sin_addr.s_addr) {
2398 wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] = 2593 u64temp = (unsigned long)nesqp;
2399 cpu_to_le32(NES_IWARP_SQ_WQE_STREAMING | NES_IWARP_SQ_WQE_WRPDU); 2594 u64temp |= NES_SW_CONTEXT_ALIGN>>1;
2400 wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX] = 2595 set_wqe_64bit_value(wqe->wqe_words,
2401 cpu_to_le32(conn_param->private_data_len + sizeof(struct ietf_mpa_frame)); 2596 NES_IWARP_SQ_WQE_COMP_CTX_LOW_IDX,
2402 wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_LOW_IDX] = 2597 u64temp);
2403 cpu_to_le32((u32)nesqp->ietf_frame_pbase); 2598 wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] =
2404 wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_HIGH_IDX] = 2599 cpu_to_le32(NES_IWARP_SQ_WQE_STREAMING |
2405 cpu_to_le32((u32)((u64)nesqp->ietf_frame_pbase >> 32)); 2600 NES_IWARP_SQ_WQE_WRPDU);
2406 wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] = 2601 wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX] =
2407 cpu_to_le32(conn_param->private_data_len + sizeof(struct ietf_mpa_frame)); 2602 cpu_to_le32(conn_param->private_data_len +
2408 wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = 0; 2603 sizeof(struct ietf_mpa_frame));
2409 2604 wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_LOW_IDX] =
2410 nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32( 2605 cpu_to_le32((u32)nesqp->ietf_frame_pbase);
2411 NES_QPCONTEXT_ORDIRD_LSMM_PRESENT | NES_QPCONTEXT_ORDIRD_WRPDU); 2606 wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_HIGH_IDX] =
2412 } else { 2607 cpu_to_le32((u32)((u64)nesqp->ietf_frame_pbase >> 32));
2413 nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32((NES_QPCONTEXT_ORDIRD_LSMM_PRESENT | 2608 wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] =
2414 NES_QPCONTEXT_ORDIRD_WRPDU | NES_QPCONTEXT_ORDIRD_ALSMM)); 2609 cpu_to_le32(conn_param->private_data_len +
2415 } 2610 sizeof(struct ietf_mpa_frame));
2416 nesqp->skip_lsmm = 1; 2611 wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = 0;
2612
2613 nesqp->nesqp_context->ird_ord_sizes |=
2614 cpu_to_le32(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT |
2615 NES_QPCONTEXT_ORDIRD_WRPDU);
2616 } else {
2617 nesqp->nesqp_context->ird_ord_sizes |=
2618 cpu_to_le32((NES_QPCONTEXT_ORDIRD_LSMM_PRESENT |
2619 NES_QPCONTEXT_ORDIRD_WRPDU |
2620 NES_QPCONTEXT_ORDIRD_ALSMM));
2621 }
2622 nesqp->skip_lsmm = 1;
2417 2623
2418 2624
2419 /* Cache the cm_id in the qp */ 2625 /* Cache the cm_id in the qp */
@@ -2424,55 +2630,75 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
2424 cm_id->provider_data = nesqp; 2630 cm_id->provider_data = nesqp;
2425 nesqp->active_conn = 0; 2631 nesqp->active_conn = 0;
2426 2632
2633 if (cm_node->state == NES_CM_STATE_TSA)
2634 nes_debug(NES_DBG_CM, "Already state = TSA for cm_node=%p\n",
2635 cm_node);
2636
2427 nes_cm_init_tsa_conn(nesqp, cm_node); 2637 nes_cm_init_tsa_conn(nesqp, cm_node);
2428 2638
2429 nesqp->nesqp_context->tcpPorts[0] = cpu_to_le16(ntohs(cm_id->local_addr.sin_port)); 2639 nesqp->nesqp_context->tcpPorts[0] =
2430 nesqp->nesqp_context->tcpPorts[1] = cpu_to_le16(ntohs(cm_id->remote_addr.sin_port)); 2640 cpu_to_le16(ntohs(cm_id->local_addr.sin_port));
2431 nesqp->nesqp_context->ip0 = cpu_to_le32(ntohl(cm_id->remote_addr.sin_addr.s_addr)); 2641 nesqp->nesqp_context->tcpPorts[1] =
2642 cpu_to_le16(ntohs(cm_id->remote_addr.sin_port));
2643
2644 if (ipv4_is_loopback(cm_id->remote_addr.sin_addr.s_addr))
2645 nesqp->nesqp_context->ip0 =
2646 cpu_to_le32(ntohl(nesvnic->local_ipaddr));
2647 else
2648 nesqp->nesqp_context->ip0 =
2649 cpu_to_le32(ntohl(cm_id->remote_addr.sin_addr.s_addr));
2432 2650
2433 nesqp->nesqp_context->misc2 |= cpu_to_le32( 2651 nesqp->nesqp_context->misc2 |= cpu_to_le32(
2434 (u32)PCI_FUNC(nesdev->pcidev->devfn) << NES_QPCONTEXT_MISC2_SRC_IP_SHIFT); 2652 (u32)PCI_FUNC(nesdev->pcidev->devfn) <<
2653 NES_QPCONTEXT_MISC2_SRC_IP_SHIFT);
2435 2654
2436 nesqp->nesqp_context->arp_index_vlan |= cpu_to_le32( 2655 nesqp->nesqp_context->arp_index_vlan |=
2437 nes_arp_table(nesdev, le32_to_cpu(nesqp->nesqp_context->ip0), NULL, 2656 cpu_to_le32(nes_arp_table(nesdev,
2657 le32_to_cpu(nesqp->nesqp_context->ip0), NULL,
2438 NES_ARP_RESOLVE) << 16); 2658 NES_ARP_RESOLVE) << 16);
2439 2659
2440 nesqp->nesqp_context->ts_val_delta = cpu_to_le32( 2660 nesqp->nesqp_context->ts_val_delta = cpu_to_le32(
2441 jiffies - nes_read_indexed(nesdev, NES_IDX_TCP_NOW)); 2661 jiffies - nes_read_indexed(nesdev, NES_IDX_TCP_NOW));
2442 2662
2443 nesqp->nesqp_context->ird_index = cpu_to_le32(nesqp->hwqp.qp_id); 2663 nesqp->nesqp_context->ird_index = cpu_to_le32(nesqp->hwqp.qp_id);
2444 2664
2445 nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32( 2665 nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32(
2446 ((u32)1 << NES_QPCONTEXT_ORDIRD_IWARP_MODE_SHIFT)); 2666 ((u32)1 << NES_QPCONTEXT_ORDIRD_IWARP_MODE_SHIFT));
2447 nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32((u32)conn_param->ord); 2667 nesqp->nesqp_context->ird_ord_sizes |=
2668 cpu_to_le32((u32)conn_param->ord);
2448 2669
2449 memset(&nes_quad, 0, sizeof(nes_quad)); 2670 memset(&nes_quad, 0, sizeof(nes_quad));
2450 nes_quad.DstIpAdrIndex = cpu_to_le32((u32)PCI_FUNC(nesdev->pcidev->devfn) << 24); 2671 nes_quad.DstIpAdrIndex =
2451 nes_quad.SrcIpadr = cm_id->remote_addr.sin_addr.s_addr; 2672 cpu_to_le32((u32)PCI_FUNC(nesdev->pcidev->devfn) << 24);
2452 nes_quad.TcpPorts[0] = cm_id->remote_addr.sin_port; 2673 if (ipv4_is_loopback(cm_id->remote_addr.sin_addr.s_addr))
2453 nes_quad.TcpPorts[1] = cm_id->local_addr.sin_port; 2674 nes_quad.SrcIpadr = nesvnic->local_ipaddr;
2675 else
2676 nes_quad.SrcIpadr = cm_id->remote_addr.sin_addr.s_addr;
2677 nes_quad.TcpPorts[0] = cm_id->remote_addr.sin_port;
2678 nes_quad.TcpPorts[1] = cm_id->local_addr.sin_port;
2454 2679
2455 /* Produce hash key */ 2680 /* Produce hash key */
2456 crc_value = get_crc_value(&nes_quad); 2681 crc_value = get_crc_value(&nes_quad);
2457 nesqp->hte_index = cpu_to_be32(crc_value ^ 0xffffffff); 2682 nesqp->hte_index = cpu_to_be32(crc_value ^ 0xffffffff);
2458 nes_debug(NES_DBG_CM, "HTE Index = 0x%08X, CRC = 0x%08X\n", 2683 nes_debug(NES_DBG_CM, "HTE Index = 0x%08X, CRC = 0x%08X\n",
2459 nesqp->hte_index, nesqp->hte_index & adapter->hte_index_mask); 2684 nesqp->hte_index, nesqp->hte_index & adapter->hte_index_mask);
2460 2685
2461 nesqp->hte_index &= adapter->hte_index_mask; 2686 nesqp->hte_index &= adapter->hte_index_mask;
2462 nesqp->nesqp_context->hte_index = cpu_to_le32(nesqp->hte_index); 2687 nesqp->nesqp_context->hte_index = cpu_to_le32(nesqp->hte_index);
2463 2688
2464 cm_node->cm_core->api->accelerated(cm_node->cm_core, cm_node); 2689 cm_node->cm_core->api->accelerated(cm_node->cm_core, cm_node);
2465 2690
2466 nes_debug(NES_DBG_CM, "QP%u, Destination IP = 0x%08X:0x%04X, local = 0x%08X:0x%04X," 2691 nes_debug(NES_DBG_CM, "QP%u, Destination IP = 0x%08X:0x%04X, local = "
2467 " rcv_nxt=0x%08X, snd_nxt=0x%08X, mpa + private data length=%zu.\n", 2692 "0x%08X:0x%04X, rcv_nxt=0x%08X, snd_nxt=0x%08X, mpa + "
2468 nesqp->hwqp.qp_id, 2693 "private data length=%zu.\n", nesqp->hwqp.qp_id,
2469 ntohl(cm_id->remote_addr.sin_addr.s_addr), 2694 ntohl(cm_id->remote_addr.sin_addr.s_addr),
2470 ntohs(cm_id->remote_addr.sin_port), 2695 ntohs(cm_id->remote_addr.sin_port),
2471 ntohl(cm_id->local_addr.sin_addr.s_addr), 2696 ntohl(cm_id->local_addr.sin_addr.s_addr),
2472 ntohs(cm_id->local_addr.sin_port), 2697 ntohs(cm_id->local_addr.sin_port),
2473 le32_to_cpu(nesqp->nesqp_context->rcv_nxt), 2698 le32_to_cpu(nesqp->nesqp_context->rcv_nxt),
2474 le32_to_cpu(nesqp->nesqp_context->snd_nxt), 2699 le32_to_cpu(nesqp->nesqp_context->snd_nxt),
2475 conn_param->private_data_len+sizeof(struct ietf_mpa_frame)); 2700 conn_param->private_data_len +
2701 sizeof(struct ietf_mpa_frame));
2476 2702
2477 attr.qp_state = IB_QPS_RTS; 2703 attr.qp_state = IB_QPS_RTS;
2478 nes_modify_qp(&nesqp->ibqp, &attr, IB_QP_STATE, NULL); 2704 nes_modify_qp(&nesqp->ibqp, &attr, IB_QP_STATE, NULL);
@@ -2489,15 +2715,16 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
2489 cm_event.private_data_len = 0; 2715 cm_event.private_data_len = 0;
2490 ret = cm_id->event_handler(cm_id, &cm_event); 2716 ret = cm_id->event_handler(cm_id, &cm_event);
2491 if (cm_node->loopbackpartner) { 2717 if (cm_node->loopbackpartner) {
2492 cm_node->loopbackpartner->mpa_frame_size = nesqp->private_data_len; 2718 cm_node->loopbackpartner->mpa_frame_size =
2719 nesqp->private_data_len;
2493 /* copy entire MPA frame to our cm_node's frame */ 2720 /* copy entire MPA frame to our cm_node's frame */
2494 memcpy(cm_node->loopbackpartner->mpa_frame_buf, nesqp->ietf_frame->priv_data, 2721 memcpy(cm_node->loopbackpartner->mpa_frame_buf,
2495 nesqp->private_data_len); 2722 nesqp->ietf_frame->priv_data, nesqp->private_data_len);
2496 create_event(cm_node->loopbackpartner, NES_CM_EVENT_CONNECTED); 2723 create_event(cm_node->loopbackpartner, NES_CM_EVENT_CONNECTED);
2497 } 2724 }
2498 if (ret) 2725 if (ret)
2499 printk("%s[%u] OFA CM event_handler returned, ret=%d\n", 2726 printk(KERN_ERR "%s[%u] OFA CM event_handler returned, "
2500 __func__, __LINE__, ret); 2727 "ret=%d\n", __func__, __LINE__, ret);
2501 2728
2502 return 0; 2729 return 0;
2503} 2730}
@@ -2555,74 +2782,61 @@ int nes_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
2555 if (!nesdev) 2782 if (!nesdev)
2556 return -EINVAL; 2783 return -EINVAL;
2557 2784
2558 atomic_inc(&cm_connects); 2785 nes_debug(NES_DBG_CM, "QP%u, current IP = 0x%08X, Destination IP = "
2559 2786 "0x%08X:0x%04X, local = 0x%08X:0x%04X.\n", nesqp->hwqp.qp_id,
2560 nesqp->ietf_frame = kzalloc(sizeof(struct ietf_mpa_frame) + 2787 ntohl(nesvnic->local_ipaddr),
2561 conn_param->private_data_len, GFP_KERNEL); 2788 ntohl(cm_id->remote_addr.sin_addr.s_addr),
2562 if (!nesqp->ietf_frame) 2789 ntohs(cm_id->remote_addr.sin_port),
2563 return -ENOMEM; 2790 ntohl(cm_id->local_addr.sin_addr.s_addr),
2791 ntohs(cm_id->local_addr.sin_port));
2564 2792
2565 /* set qp as having an active connection */ 2793 atomic_inc(&cm_connects);
2566 nesqp->active_conn = 1; 2794 nesqp->active_conn = 1;
2567 2795
2568 nes_debug(NES_DBG_CM, "QP%u, Destination IP = 0x%08X:0x%04X, local = 0x%08X:0x%04X.\n",
2569 nesqp->hwqp.qp_id,
2570 ntohl(cm_id->remote_addr.sin_addr.s_addr),
2571 ntohs(cm_id->remote_addr.sin_port),
2572 ntohl(cm_id->local_addr.sin_addr.s_addr),
2573 ntohs(cm_id->local_addr.sin_port));
2574
2575 /* cache the cm_id in the qp */ 2796 /* cache the cm_id in the qp */
2576 nesqp->cm_id = cm_id; 2797 nesqp->cm_id = cm_id;
2577 2798
2578 cm_id->provider_data = nesqp; 2799 cm_id->provider_data = nesqp;
2579 2800
2580 /* copy the private data */
2581 if (conn_param->private_data_len) {
2582 memcpy(nesqp->ietf_frame->priv_data, conn_param->private_data,
2583 conn_param->private_data_len);
2584 }
2585
2586 nesqp->private_data_len = conn_param->private_data_len; 2801 nesqp->private_data_len = conn_param->private_data_len;
2587 nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32((u32)conn_param->ord); 2802 nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32((u32)conn_param->ord);
2588 nes_debug(NES_DBG_CM, "requested ord = 0x%08X.\n", (u32)conn_param->ord); 2803 nes_debug(NES_DBG_CM, "requested ord = 0x%08X.\n", (u32)conn_param->ord);
2589 nes_debug(NES_DBG_CM, "mpa private data len =%u\n", conn_param->private_data_len); 2804 nes_debug(NES_DBG_CM, "mpa private data len =%u\n",
2590 2805 conn_param->private_data_len);
2591 strcpy(&nesqp->ietf_frame->key[0], IEFT_MPA_KEY_REQ);
2592 nesqp->ietf_frame->flags = IETF_MPA_FLAGS_CRC;
2593 nesqp->ietf_frame->rev = IETF_MPA_VERSION;
2594 nesqp->ietf_frame->priv_data_len = htons(conn_param->private_data_len);
2595 2806
2596 if (cm_id->local_addr.sin_addr.s_addr != cm_id->remote_addr.sin_addr.s_addr) 2807 if (cm_id->local_addr.sin_addr.s_addr !=
2808 cm_id->remote_addr.sin_addr.s_addr)
2597 nes_manage_apbvt(nesvnic, ntohs(cm_id->local_addr.sin_port), 2809 nes_manage_apbvt(nesvnic, ntohs(cm_id->local_addr.sin_port),
2598 PCI_FUNC(nesdev->pcidev->devfn), NES_MANAGE_APBVT_ADD); 2810 PCI_FUNC(nesdev->pcidev->devfn), NES_MANAGE_APBVT_ADD);
2599 2811
2600 /* set up the connection params for the node */ 2812 /* set up the connection params for the node */
2601 cm_info.loc_addr = (cm_id->local_addr.sin_addr.s_addr); 2813 cm_info.loc_addr = htonl(cm_id->local_addr.sin_addr.s_addr);
2602 cm_info.loc_port = (cm_id->local_addr.sin_port); 2814 cm_info.loc_port = htons(cm_id->local_addr.sin_port);
2603 cm_info.rem_addr = (cm_id->remote_addr.sin_addr.s_addr); 2815 cm_info.rem_addr = htonl(cm_id->remote_addr.sin_addr.s_addr);
2604 cm_info.rem_port = (cm_id->remote_addr.sin_port); 2816 cm_info.rem_port = htons(cm_id->remote_addr.sin_port);
2605 cm_info.cm_id = cm_id; 2817 cm_info.cm_id = cm_id;
2606 cm_info.conn_type = NES_CM_IWARP_CONN_TYPE; 2818 cm_info.conn_type = NES_CM_IWARP_CONN_TYPE;
2607 2819
2608 cm_id->add_ref(cm_id); 2820 cm_id->add_ref(cm_id);
2609 nes_add_ref(&nesqp->ibqp);
2610 2821
2611 /* create a connect CM node connection */ 2822 /* create a connect CM node connection */
2612 cm_node = g_cm_core->api->connect(g_cm_core, nesvnic, nesqp->ietf_frame, &cm_info); 2823 cm_node = g_cm_core->api->connect(g_cm_core, nesvnic,
2824 conn_param->private_data_len, (void *)conn_param->private_data,
2825 &cm_info);
2613 if (!cm_node) { 2826 if (!cm_node) {
2614 if (cm_id->local_addr.sin_addr.s_addr != cm_id->remote_addr.sin_addr.s_addr) 2827 if (cm_id->local_addr.sin_addr.s_addr !=
2828 cm_id->remote_addr.sin_addr.s_addr)
2615 nes_manage_apbvt(nesvnic, ntohs(cm_id->local_addr.sin_port), 2829 nes_manage_apbvt(nesvnic, ntohs(cm_id->local_addr.sin_port),
2616 PCI_FUNC(nesdev->pcidev->devfn), NES_MANAGE_APBVT_DEL); 2830 PCI_FUNC(nesdev->pcidev->devfn),
2617 nes_rem_ref(&nesqp->ibqp); 2831 NES_MANAGE_APBVT_DEL);
2618 kfree(nesqp->ietf_frame); 2832
2619 nesqp->ietf_frame = NULL;
2620 cm_id->rem_ref(cm_id); 2833 cm_id->rem_ref(cm_id);
2621 return -ENOMEM; 2834 return -ENOMEM;
2622 } 2835 }
2623 2836
2624 cm_node->apbvt_set = 1; 2837 cm_node->apbvt_set = 1;
2625 nesqp->cm_node = cm_node; 2838 nesqp->cm_node = cm_node;
2839 cm_node->nesqp = nesqp;
2626 2840
2627 return 0; 2841 return 0;
2628} 2842}
@@ -2664,7 +2878,7 @@ int nes_create_listen(struct iw_cm_id *cm_id, int backlog)
2664 2878
2665 cm_node = g_cm_core->api->listen(g_cm_core, nesvnic, &cm_info); 2879 cm_node = g_cm_core->api->listen(g_cm_core, nesvnic, &cm_info);
2666 if (!cm_node) { 2880 if (!cm_node) {
2667 printk("%s[%u] Error returned from listen API call\n", 2881 printk(KERN_ERR "%s[%u] Error returned from listen API call\n",
2668 __func__, __LINE__); 2882 __func__, __LINE__);
2669 return -ENOMEM; 2883 return -ENOMEM;
2670 } 2884 }
@@ -2672,10 +2886,13 @@ int nes_create_listen(struct iw_cm_id *cm_id, int backlog)
2672 cm_id->provider_data = cm_node; 2886 cm_id->provider_data = cm_node;
2673 2887
2674 if (!cm_node->reused_node) { 2888 if (!cm_node->reused_node) {
2675 err = nes_manage_apbvt(nesvnic, ntohs(cm_id->local_addr.sin_port), 2889 err = nes_manage_apbvt(nesvnic,
2676 PCI_FUNC(nesvnic->nesdev->pcidev->devfn), NES_MANAGE_APBVT_ADD); 2890 ntohs(cm_id->local_addr.sin_port),
2891 PCI_FUNC(nesvnic->nesdev->pcidev->devfn),
2892 NES_MANAGE_APBVT_ADD);
2677 if (err) { 2893 if (err) {
2678 printk("nes_manage_apbvt call returned %d.\n", err); 2894 printk(KERN_ERR "nes_manage_apbvt call returned %d.\n",
2895 err);
2679 g_cm_core->api->stop_listener(g_cm_core, (void *)cm_node); 2896 g_cm_core->api->stop_listener(g_cm_core, (void *)cm_node);
2680 return err; 2897 return err;
2681 } 2898 }
@@ -2795,53 +3012,70 @@ static void cm_event_connected(struct nes_cm_event *event)
2795 nes_cm_init_tsa_conn(nesqp, cm_node); 3012 nes_cm_init_tsa_conn(nesqp, cm_node);
2796 3013
2797 /* set the QP tsa context */ 3014 /* set the QP tsa context */
2798 nesqp->nesqp_context->tcpPorts[0] = cpu_to_le16(ntohs(cm_id->local_addr.sin_port)); 3015 nesqp->nesqp_context->tcpPorts[0] =
2799 nesqp->nesqp_context->tcpPorts[1] = cpu_to_le16(ntohs(cm_id->remote_addr.sin_port)); 3016 cpu_to_le16(ntohs(cm_id->local_addr.sin_port));
2800 nesqp->nesqp_context->ip0 = cpu_to_le32(ntohl(cm_id->remote_addr.sin_addr.s_addr)); 3017 nesqp->nesqp_context->tcpPorts[1] =
3018 cpu_to_le16(ntohs(cm_id->remote_addr.sin_port));
3019 if (ipv4_is_loopback(cm_id->remote_addr.sin_addr.s_addr))
3020 nesqp->nesqp_context->ip0 =
3021 cpu_to_le32(ntohl(nesvnic->local_ipaddr));
3022 else
3023 nesqp->nesqp_context->ip0 =
3024 cpu_to_le32(ntohl(cm_id->remote_addr.sin_addr.s_addr));
2801 3025
2802 nesqp->nesqp_context->misc2 |= cpu_to_le32( 3026 nesqp->nesqp_context->misc2 |= cpu_to_le32(
2803 (u32)PCI_FUNC(nesdev->pcidev->devfn) << NES_QPCONTEXT_MISC2_SRC_IP_SHIFT); 3027 (u32)PCI_FUNC(nesdev->pcidev->devfn) <<
3028 NES_QPCONTEXT_MISC2_SRC_IP_SHIFT);
2804 nesqp->nesqp_context->arp_index_vlan |= cpu_to_le32( 3029 nesqp->nesqp_context->arp_index_vlan |= cpu_to_le32(
2805 nes_arp_table(nesdev, le32_to_cpu(nesqp->nesqp_context->ip0), 3030 nes_arp_table(nesdev,
3031 le32_to_cpu(nesqp->nesqp_context->ip0),
2806 NULL, NES_ARP_RESOLVE) << 16); 3032 NULL, NES_ARP_RESOLVE) << 16);
2807 nesqp->nesqp_context->ts_val_delta = cpu_to_le32( 3033 nesqp->nesqp_context->ts_val_delta = cpu_to_le32(
2808 jiffies - nes_read_indexed(nesdev, NES_IDX_TCP_NOW)); 3034 jiffies - nes_read_indexed(nesdev, NES_IDX_TCP_NOW));
2809 nesqp->nesqp_context->ird_index = cpu_to_le32(nesqp->hwqp.qp_id); 3035 nesqp->nesqp_context->ird_index = cpu_to_le32(nesqp->hwqp.qp_id);
2810 nesqp->nesqp_context->ird_ord_sizes |= 3036 nesqp->nesqp_context->ird_ord_sizes |=
2811 cpu_to_le32((u32)1 << NES_QPCONTEXT_ORDIRD_IWARP_MODE_SHIFT); 3037 cpu_to_le32((u32)1 <<
3038 NES_QPCONTEXT_ORDIRD_IWARP_MODE_SHIFT);
2812 3039
2813 /* Adjust tail for not having a LSMM */ 3040 /* Adjust tail for not having a LSMM */
2814 nesqp->hwqp.sq_tail = 1; 3041 nesqp->hwqp.sq_tail = 1;
2815 3042
2816#if defined(NES_SEND_FIRST_WRITE) 3043#if defined(NES_SEND_FIRST_WRITE)
2817 if (cm_node->send_write0) { 3044 if (cm_node->send_write0) {
2818 nes_debug(NES_DBG_CM, "Sending first write.\n"); 3045 nes_debug(NES_DBG_CM, "Sending first write.\n");
2819 wqe = &nesqp->hwqp.sq_vbase[0]; 3046 wqe = &nesqp->hwqp.sq_vbase[0];
2820 u64temp = (unsigned long)nesqp; 3047 u64temp = (unsigned long)nesqp;
2821 u64temp |= NES_SW_CONTEXT_ALIGN>>1; 3048 u64temp |= NES_SW_CONTEXT_ALIGN>>1;
2822 set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_COMP_CTX_LOW_IDX, 3049 set_wqe_64bit_value(wqe->wqe_words,
2823 u64temp); 3050 NES_IWARP_SQ_WQE_COMP_CTX_LOW_IDX, u64temp);
2824 wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] = cpu_to_le32(NES_IWARP_SQ_OP_RDMAW); 3051 wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] =
2825 wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX] = 0; 3052 cpu_to_le32(NES_IWARP_SQ_OP_RDMAW);
2826 wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_LOW_IDX] = 0; 3053 wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX] = 0;
2827 wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_HIGH_IDX] = 0; 3054 wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_LOW_IDX] = 0;
2828 wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] = 0; 3055 wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_HIGH_IDX] = 0;
2829 wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = 0; 3056 wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] = 0;
2830 3057 wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = 0;
2831 /* use the reserved spot on the WQ for the extra first WQE */ 3058
2832 nesqp->nesqp_context->ird_ord_sizes &= cpu_to_le32(~(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT | 3059 /* use the reserved spot on the WQ for the extra first WQE */
2833 NES_QPCONTEXT_ORDIRD_WRPDU | NES_QPCONTEXT_ORDIRD_ALSMM)); 3060 nesqp->nesqp_context->ird_ord_sizes &=
2834 nesqp->skip_lsmm = 1; 3061 cpu_to_le32(~(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT |
2835 nesqp->hwqp.sq_tail = 0; 3062 NES_QPCONTEXT_ORDIRD_WRPDU |
2836 nes_write32(nesdev->regs + NES_WQE_ALLOC, 3063 NES_QPCONTEXT_ORDIRD_ALSMM));
2837 (1 << 24) | 0x00800000 | nesqp->hwqp.qp_id); 3064 nesqp->skip_lsmm = 1;
2838 } 3065 nesqp->hwqp.sq_tail = 0;
3066 nes_write32(nesdev->regs + NES_WQE_ALLOC,
3067 (1 << 24) | 0x00800000 | nesqp->hwqp.qp_id);
3068 }
2839#endif 3069#endif
2840 3070
2841 memset(&nes_quad, 0, sizeof(nes_quad)); 3071 memset(&nes_quad, 0, sizeof(nes_quad));
2842 3072
2843 nes_quad.DstIpAdrIndex = cpu_to_le32((u32)PCI_FUNC(nesdev->pcidev->devfn) << 24); 3073 nes_quad.DstIpAdrIndex =
2844 nes_quad.SrcIpadr = cm_id->remote_addr.sin_addr.s_addr; 3074 cpu_to_le32((u32)PCI_FUNC(nesdev->pcidev->devfn) << 24);
3075 if (ipv4_is_loopback(cm_id->remote_addr.sin_addr.s_addr))
3076 nes_quad.SrcIpadr = nesvnic->local_ipaddr;
3077 else
3078 nes_quad.SrcIpadr = cm_id->remote_addr.sin_addr.s_addr;
2845 nes_quad.TcpPorts[0] = cm_id->remote_addr.sin_port; 3079 nes_quad.TcpPorts[0] = cm_id->remote_addr.sin_port;
2846 nes_quad.TcpPorts[1] = cm_id->local_addr.sin_port; 3080 nes_quad.TcpPorts[1] = cm_id->local_addr.sin_port;
2847 3081
@@ -2858,10 +3092,6 @@ static void cm_event_connected(struct nes_cm_event *event)
2858 nesqp->private_data_len = (u8) cm_node->mpa_frame_size; 3092 nesqp->private_data_len = (u8) cm_node->mpa_frame_size;
2859 cm_node->cm_core->api->accelerated(cm_node->cm_core, cm_node); 3093 cm_node->cm_core->api->accelerated(cm_node->cm_core, cm_node);
2860 3094
2861 /* modify QP state to rts */
2862 attr.qp_state = IB_QPS_RTS;
2863 nes_modify_qp(&nesqp->ibqp, &attr, IB_QP_STATE, NULL);
2864
2865 /* notify OF layer we successfully created the requested connection */ 3095 /* notify OF layer we successfully created the requested connection */
2866 cm_event.event = IW_CM_EVENT_CONNECT_REPLY; 3096 cm_event.event = IW_CM_EVENT_CONNECT_REPLY;
2867 cm_event.status = IW_CM_EVENT_STATUS_ACCEPTED; 3097 cm_event.status = IW_CM_EVENT_STATUS_ACCEPTED;
@@ -2870,20 +3100,21 @@ static void cm_event_connected(struct nes_cm_event *event)
2870 cm_event.local_addr.sin_port = cm_id->local_addr.sin_port; 3100 cm_event.local_addr.sin_port = cm_id->local_addr.sin_port;
2871 cm_event.remote_addr = cm_id->remote_addr; 3101 cm_event.remote_addr = cm_id->remote_addr;
2872 3102
2873 cm_event.private_data = (void *)event->cm_node->mpa_frame_buf; 3103 cm_event.private_data = (void *)event->cm_node->mpa_frame_buf;
2874 cm_event.private_data_len = (u8) event->cm_node->mpa_frame_size; 3104 cm_event.private_data_len = (u8) event->cm_node->mpa_frame_size;
2875 3105
2876 cm_event.local_addr.sin_addr.s_addr = event->cm_info.rem_addr; 3106 cm_event.local_addr.sin_addr.s_addr = event->cm_info.rem_addr;
2877 ret = cm_id->event_handler(cm_id, &cm_event); 3107 ret = cm_id->event_handler(cm_id, &cm_event);
2878 nes_debug(NES_DBG_CM, "OFA CM event_handler returned, ret=%d\n", ret); 3108 nes_debug(NES_DBG_CM, "OFA CM event_handler returned, ret=%d\n", ret);
2879 3109
2880 if (ret) 3110 if (ret)
2881 printk("%s[%u] OFA CM event_handler returned, ret=%d\n", 3111 printk(KERN_ERR "%s[%u] OFA CM event_handler returned, "
2882 __func__, __LINE__, ret); 3112 "ret=%d\n", __func__, __LINE__, ret);
2883 nes_debug(NES_DBG_CM, "Exiting connect thread for QP%u. jiffies = %lu\n", 3113 attr.qp_state = IB_QPS_RTS;
2884 nesqp->hwqp.qp_id, jiffies ); 3114 nes_modify_qp(&nesqp->ibqp, &attr, IB_QP_STATE, NULL);
2885 3115
2886 nes_rem_ref(&nesqp->ibqp); 3116 nes_debug(NES_DBG_CM, "Exiting connect thread for QP%u. jiffies = "
3117 "%lu\n", nesqp->hwqp.qp_id, jiffies);
2887 3118
2888 return; 3119 return;
2889} 3120}
@@ -2927,17 +3158,19 @@ static void cm_event_connect_error(struct nes_cm_event *event)
2927 cm_event.private_data = NULL; 3158 cm_event.private_data = NULL;
2928 cm_event.private_data_len = 0; 3159 cm_event.private_data_len = 0;
2929 3160
2930 nes_debug(NES_DBG_CM, "call CM_EVENT REJECTED, local_addr=%08x, remove_addr=%08x\n", 3161 nes_debug(NES_DBG_CM, "call CM_EVENT REJECTED, local_addr=%08x, "
2931 cm_event.local_addr.sin_addr.s_addr, cm_event.remote_addr.sin_addr.s_addr); 3162 "remove_addr=%08x\n", cm_event.local_addr.sin_addr.s_addr,
3163 cm_event.remote_addr.sin_addr.s_addr);
2932 3164
2933 ret = cm_id->event_handler(cm_id, &cm_event); 3165 ret = cm_id->event_handler(cm_id, &cm_event);
2934 nes_debug(NES_DBG_CM, "OFA CM event_handler returned, ret=%d\n", ret); 3166 nes_debug(NES_DBG_CM, "OFA CM event_handler returned, ret=%d\n", ret);
2935 if (ret) 3167 if (ret)
2936 printk("%s[%u] OFA CM event_handler returned, ret=%d\n", 3168 printk(KERN_ERR "%s[%u] OFA CM event_handler returned, "
2937 __func__, __LINE__, ret); 3169 "ret=%d\n", __func__, __LINE__, ret);
2938 nes_rem_ref(&nesqp->ibqp); 3170 nes_rem_ref(&nesqp->ibqp);
2939 cm_id->rem_ref(cm_id); 3171 cm_id->rem_ref(cm_id);
2940 3172
3173 rem_ref_cm_node(event->cm_node->cm_core, event->cm_node);
2941 return; 3174 return;
2942} 3175}
2943 3176
@@ -3040,7 +3273,8 @@ static int nes_cm_post_event(struct nes_cm_event *event)
3040 add_ref_cm_node(event->cm_node); 3273 add_ref_cm_node(event->cm_node);
3041 event->cm_info.cm_id->add_ref(event->cm_info.cm_id); 3274 event->cm_info.cm_id->add_ref(event->cm_info.cm_id);
3042 INIT_WORK(&event->event_work, nes_cm_event_handler); 3275 INIT_WORK(&event->event_work, nes_cm_event_handler);
3043 nes_debug(NES_DBG_CM, "queue_work, event=%p\n", event); 3276 nes_debug(NES_DBG_CM, "cm_node=%p queue_work, event=%p\n",
3277 event->cm_node, event);
3044 3278
3045 queue_work(event->cm_node->cm_core->event_wq, &event->event_work); 3279 queue_work(event->cm_node->cm_core->event_wq, &event->event_work);
3046 3280
@@ -3056,46 +3290,48 @@ static int nes_cm_post_event(struct nes_cm_event *event)
3056 */ 3290 */
3057static void nes_cm_event_handler(struct work_struct *work) 3291static void nes_cm_event_handler(struct work_struct *work)
3058{ 3292{
3059 struct nes_cm_event *event = container_of(work, struct nes_cm_event, event_work); 3293 struct nes_cm_event *event = container_of(work, struct nes_cm_event,
3294 event_work);
3060 struct nes_cm_core *cm_core; 3295 struct nes_cm_core *cm_core;
3061 3296
3062 if ((!event) || (!event->cm_node) || (!event->cm_node->cm_core)) { 3297 if ((!event) || (!event->cm_node) || (!event->cm_node->cm_core))
3063 return; 3298 return;
3064 } 3299
3065 cm_core = event->cm_node->cm_core; 3300 cm_core = event->cm_node->cm_core;
3066 nes_debug(NES_DBG_CM, "event=%p, event->type=%u, events posted=%u\n", 3301 nes_debug(NES_DBG_CM, "event=%p, event->type=%u, events posted=%u\n",
3067 event, event->type, atomic_read(&cm_core->events_posted)); 3302 event, event->type, atomic_read(&cm_core->events_posted));
3068 3303
3069 switch (event->type) { 3304 switch (event->type) {
3070 case NES_CM_EVENT_MPA_REQ: 3305 case NES_CM_EVENT_MPA_REQ:
3071 cm_event_mpa_req(event); 3306 cm_event_mpa_req(event);
3072 nes_debug(NES_DBG_CM, "CM Event: MPA REQUEST\n"); 3307 nes_debug(NES_DBG_CM, "cm_node=%p CM Event: MPA REQUEST\n",
3073 break; 3308 event->cm_node);
3074 case NES_CM_EVENT_RESET: 3309 break;
3075 nes_debug(NES_DBG_CM, "CM Event: RESET\n"); 3310 case NES_CM_EVENT_RESET:
3076 cm_event_reset(event); 3311 nes_debug(NES_DBG_CM, "cm_node = %p CM Event: RESET\n",
3077 break; 3312 event->cm_node);
3078 case NES_CM_EVENT_CONNECTED: 3313 cm_event_reset(event);
3079 if ((!event->cm_node->cm_id) || 3314 break;
3080 (event->cm_node->state != NES_CM_STATE_TSA)) { 3315 case NES_CM_EVENT_CONNECTED:
3081 break; 3316 if ((!event->cm_node->cm_id) ||
3082 } 3317 (event->cm_node->state != NES_CM_STATE_TSA))
3083 cm_event_connected(event);
3084 nes_debug(NES_DBG_CM, "CM Event: CONNECTED\n");
3085 break; 3318 break;
3086 case NES_CM_EVENT_ABORTED: 3319 cm_event_connected(event);
3087 if ((!event->cm_node->cm_id) || (event->cm_node->state == NES_CM_STATE_TSA)) { 3320 nes_debug(NES_DBG_CM, "CM Event: CONNECTED\n");
3088 break; 3321 break;
3089 } 3322 case NES_CM_EVENT_ABORTED:
3090 cm_event_connect_error(event); 3323 if ((!event->cm_node->cm_id) ||
3091 nes_debug(NES_DBG_CM, "CM Event: ABORTED\n"); 3324 (event->cm_node->state == NES_CM_STATE_TSA))
3092 break;
3093 case NES_CM_EVENT_DROPPED_PKT:
3094 nes_debug(NES_DBG_CM, "CM Event: DROPPED PKT\n");
3095 break;
3096 default:
3097 nes_debug(NES_DBG_CM, "CM Event: UNKNOWN EVENT TYPE\n");
3098 break; 3325 break;
3326 cm_event_connect_error(event);
3327 nes_debug(NES_DBG_CM, "CM Event: ABORTED\n");
3328 break;
3329 case NES_CM_EVENT_DROPPED_PKT:
3330 nes_debug(NES_DBG_CM, "CM Event: DROPPED PKT\n");
3331 break;
3332 default:
3333 nes_debug(NES_DBG_CM, "CM Event: UNKNOWN EVENT TYPE\n");
3334 break;
3099 } 3335 }
3100 3336
3101 atomic_dec(&cm_core->events_posted); 3337 atomic_dec(&cm_core->events_posted);
diff --git a/drivers/infiniband/hw/nes/nes_cm.h b/drivers/infiniband/hw/nes/nes_cm.h
index 7717cb2ab500..367b3d290140 100644
--- a/drivers/infiniband/hw/nes/nes_cm.h
+++ b/drivers/infiniband/hw/nes/nes_cm.h
@@ -83,6 +83,8 @@ enum nes_timer_type {
83#define SET_FIN 4 83#define SET_FIN 4
84#define SET_RST 8 84#define SET_RST 8
85 85
86#define TCP_OPTIONS_PADDING 3
87
86struct option_base { 88struct option_base {
87 u8 optionnum; 89 u8 optionnum;
88 u8 length; 90 u8 length;
@@ -177,6 +179,7 @@ enum nes_cm_node_state {
177 NES_CM_STATE_ESTABLISHED, 179 NES_CM_STATE_ESTABLISHED,
178 NES_CM_STATE_ACCEPTING, 180 NES_CM_STATE_ACCEPTING,
179 NES_CM_STATE_MPAREQ_SENT, 181 NES_CM_STATE_MPAREQ_SENT,
182 NES_CM_STATE_MPAREQ_RCVD,
180 NES_CM_STATE_TSA, 183 NES_CM_STATE_TSA,
181 NES_CM_STATE_FIN_WAIT1, 184 NES_CM_STATE_FIN_WAIT1,
182 NES_CM_STATE_FIN_WAIT2, 185 NES_CM_STATE_FIN_WAIT2,
@@ -187,6 +190,16 @@ enum nes_cm_node_state {
187 NES_CM_STATE_CLOSED 190 NES_CM_STATE_CLOSED
188}; 191};
189 192
193enum nes_tcpip_pkt_type {
194 NES_PKT_TYPE_UNKNOWN,
195 NES_PKT_TYPE_SYN,
196 NES_PKT_TYPE_SYNACK,
197 NES_PKT_TYPE_ACK,
198 NES_PKT_TYPE_FIN,
199 NES_PKT_TYPE_RST
200};
201
202
190/* type of nes connection */ 203/* type of nes connection */
191enum nes_cm_conn_type { 204enum nes_cm_conn_type {
192 NES_CM_IWARP_CONN_TYPE, 205 NES_CM_IWARP_CONN_TYPE,
@@ -257,7 +270,9 @@ struct nes_cm_node {
257 struct net_device *netdev; 270 struct net_device *netdev;
258 271
259 struct nes_cm_node *loopbackpartner; 272 struct nes_cm_node *loopbackpartner;
260 struct list_head retrans_list; 273
274 struct nes_timer_entry *send_entry;
275
261 spinlock_t retrans_list_lock; 276 spinlock_t retrans_list_lock;
262 struct list_head recv_list; 277 struct list_head recv_list;
263 spinlock_t recv_list_lock; 278 spinlock_t recv_list_lock;
@@ -276,6 +291,8 @@ struct nes_cm_node {
276 struct nes_vnic *nesvnic; 291 struct nes_vnic *nesvnic;
277 int apbvt_set; 292 int apbvt_set;
278 int accept_pend; 293 int accept_pend;
294 int freed;
295 struct nes_qp *nesqp;
279}; 296};
280 297
281/* structure for client or CM to fill when making CM api calls. */ 298/* structure for client or CM to fill when making CM api calls. */
@@ -366,14 +383,14 @@ struct nes_cm_ops {
366 struct nes_cm_info *); 383 struct nes_cm_info *);
367 int (*stop_listener)(struct nes_cm_core *, struct nes_cm_listener *); 384 int (*stop_listener)(struct nes_cm_core *, struct nes_cm_listener *);
368 struct nes_cm_node * (*connect)(struct nes_cm_core *, 385 struct nes_cm_node * (*connect)(struct nes_cm_core *,
369 struct nes_vnic *, struct ietf_mpa_frame *, 386 struct nes_vnic *, u16, void *,
370 struct nes_cm_info *); 387 struct nes_cm_info *);
371 int (*close)(struct nes_cm_core *, struct nes_cm_node *); 388 int (*close)(struct nes_cm_core *, struct nes_cm_node *);
372 int (*accept)(struct nes_cm_core *, struct ietf_mpa_frame *, 389 int (*accept)(struct nes_cm_core *, struct ietf_mpa_frame *,
373 struct nes_cm_node *); 390 struct nes_cm_node *);
374 int (*reject)(struct nes_cm_core *, struct ietf_mpa_frame *, 391 int (*reject)(struct nes_cm_core *, struct ietf_mpa_frame *,
375 struct nes_cm_node *); 392 struct nes_cm_node *);
376 int (*recv_pkt)(struct nes_cm_core *, struct nes_vnic *, 393 void (*recv_pkt)(struct nes_cm_core *, struct nes_vnic *,
377 struct sk_buff *); 394 struct sk_buff *);
378 int (*destroy_cm_core)(struct nes_cm_core *); 395 int (*destroy_cm_core)(struct nes_cm_core *);
379 int (*get)(struct nes_cm_core *); 396 int (*get)(struct nes_cm_core *);
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c
index 85f26d19a32b..1513d4066f1b 100644
--- a/drivers/infiniband/hw/nes/nes_hw.c
+++ b/drivers/infiniband/hw/nes/nes_hw.c
@@ -2814,7 +2814,6 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev,
2814 nesqp = *((struct nes_qp **)&context); 2814 nesqp = *((struct nes_qp **)&context);
2815 if (atomic_inc_return(&nesqp->close_timer_started) == 1) { 2815 if (atomic_inc_return(&nesqp->close_timer_started) == 1) {
2816 nesqp->cm_id->add_ref(nesqp->cm_id); 2816 nesqp->cm_id->add_ref(nesqp->cm_id);
2817 nes_add_ref(&nesqp->ibqp);
2818 schedule_nes_timer(nesqp->cm_node, (struct sk_buff *)nesqp, 2817 schedule_nes_timer(nesqp->cm_node, (struct sk_buff *)nesqp,
2819 NES_TIMER_TYPE_CLOSE, 1, 0); 2818 NES_TIMER_TYPE_CLOSE, 1, 0);
2820 nes_debug(NES_DBG_AEQ, "QP%u Not decrementing QP refcount (%d)," 2819 nes_debug(NES_DBG_AEQ, "QP%u Not decrementing QP refcount (%d),"
@@ -2838,7 +2837,6 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev,
2838 if (async_event_id == NES_AEQE_AEID_RESET_SENT) { 2837 if (async_event_id == NES_AEQE_AEID_RESET_SENT) {
2839 tcp_state = NES_AEQE_TCP_STATE_CLOSED; 2838 tcp_state = NES_AEQE_TCP_STATE_CLOSED;
2840 } 2839 }
2841 nes_add_ref(&nesqp->ibqp);
2842 spin_lock_irqsave(&nesqp->lock, flags); 2840 spin_lock_irqsave(&nesqp->lock, flags);
2843 nesqp->hw_iwarp_state = iwarp_state; 2841 nesqp->hw_iwarp_state = iwarp_state;
2844 nesqp->hw_tcp_state = tcp_state; 2842 nesqp->hw_tcp_state = tcp_state;
@@ -2876,7 +2874,6 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev,
2876 } 2874 }
2877 spin_unlock_irqrestore(&nesqp->lock, flags); 2875 spin_unlock_irqrestore(&nesqp->lock, flags);
2878 if (next_iwarp_state) { 2876 if (next_iwarp_state) {
2879 nes_add_ref(&nesqp->ibqp);
2880 nes_debug(NES_DBG_AEQ, "issuing hw modifyqp for QP%u. next state = 0x%08X," 2877 nes_debug(NES_DBG_AEQ, "issuing hw modifyqp for QP%u. next state = 0x%08X,"
2881 " also added another reference\n", 2878 " also added another reference\n",
2882 nesqp->hwqp.qp_id, next_iwarp_state); 2879 nesqp->hwqp.qp_id, next_iwarp_state);
@@ -2888,7 +2885,6 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev,
2888 /* FIN Received but ib state not RTS, 2885 /* FIN Received but ib state not RTS,
2889 close complete will be on its way */ 2886 close complete will be on its way */
2890 spin_unlock_irqrestore(&nesqp->lock, flags); 2887 spin_unlock_irqrestore(&nesqp->lock, flags);
2891 nes_rem_ref(&nesqp->ibqp);
2892 return; 2888 return;
2893 } 2889 }
2894 spin_unlock_irqrestore(&nesqp->lock, flags); 2890 spin_unlock_irqrestore(&nesqp->lock, flags);
@@ -2922,7 +2918,6 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev,
2922 if ((tcp_state == NES_AEQE_TCP_STATE_CLOSE_WAIT) || 2918 if ((tcp_state == NES_AEQE_TCP_STATE_CLOSE_WAIT) ||
2923 ((nesqp->ibqp_state == IB_QPS_RTS)&& 2919 ((nesqp->ibqp_state == IB_QPS_RTS)&&
2924 (async_event_id == NES_AEQE_AEID_LLP_CONNECTION_RESET))) { 2920 (async_event_id == NES_AEQE_AEID_LLP_CONNECTION_RESET))) {
2925 nes_add_ref(&nesqp->ibqp);
2926 nes_cm_disconn(nesqp); 2921 nes_cm_disconn(nesqp);
2927 } else { 2922 } else {
2928 nesqp->in_disconnect = 0; 2923 nesqp->in_disconnect = 0;
@@ -2931,7 +2926,6 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev,
2931 break; 2926 break;
2932 case NES_AEQE_AEID_LLP_TOO_MANY_RETRIES: 2927 case NES_AEQE_AEID_LLP_TOO_MANY_RETRIES:
2933 nesqp = *((struct nes_qp **)&context); 2928 nesqp = *((struct nes_qp **)&context);
2934 nes_add_ref(&nesqp->ibqp);
2935 spin_lock_irqsave(&nesqp->lock, flags); 2929 spin_lock_irqsave(&nesqp->lock, flags);
2936 nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_ERROR; 2930 nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_ERROR;
2937 nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED; 2931 nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED;
@@ -3042,7 +3036,6 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev,
3042 nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context); 3036 nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context);
3043 } 3037 }
3044 /* tell cm to disconnect, cm will queue work to thread */ 3038 /* tell cm to disconnect, cm will queue work to thread */
3045 nes_add_ref(&nesqp->ibqp);
3046 nes_cm_disconn(nesqp); 3039 nes_cm_disconn(nesqp);
3047 break; 3040 break;
3048 case NES_AEQE_AEID_DDP_UBE_INVALID_MSN_NO_BUFFER_AVAILABLE: 3041 case NES_AEQE_AEID_DDP_UBE_INVALID_MSN_NO_BUFFER_AVAILABLE:
@@ -3062,7 +3055,6 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev,
3062 nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context); 3055 nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context);
3063 } 3056 }
3064 /* tell cm to disconnect, cm will queue work to thread */ 3057 /* tell cm to disconnect, cm will queue work to thread */
3065 nes_add_ref(&nesqp->ibqp);
3066 nes_cm_disconn(nesqp); 3058 nes_cm_disconn(nesqp);
3067 break; 3059 break;
3068 case NES_AEQE_AEID_LLP_RECEIVED_MPA_CRC_ERROR: 3060 case NES_AEQE_AEID_LLP_RECEIVED_MPA_CRC_ERROR:
@@ -3082,7 +3074,6 @@ static void nes_process_iwarp_aeqe(struct nes_device *nesdev,
3082 nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context); 3074 nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context);
3083 } 3075 }
3084 /* tell cm to disconnect, cm will queue work to thread */ 3076 /* tell cm to disconnect, cm will queue work to thread */
3085 nes_add_ref(&nesqp->ibqp);
3086 nes_cm_disconn(nesqp); 3077 nes_cm_disconn(nesqp);
3087 break; 3078 break;
3088 /* TODO: additional AEs need to be here */ 3079 /* TODO: additional AEs need to be here */
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c
index e3939d13484e..d79942e84979 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.c
+++ b/drivers/infiniband/hw/nes/nes_verbs.c
@@ -2867,7 +2867,6 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
2867 nesqp->hwqp.qp_id, attr->qp_state, nesqp->ibqp_state, 2867 nesqp->hwqp.qp_id, attr->qp_state, nesqp->ibqp_state,
2868 nesqp->iwarp_state, atomic_read(&nesqp->refcount)); 2868 nesqp->iwarp_state, atomic_read(&nesqp->refcount));
2869 2869
2870 nes_add_ref(&nesqp->ibqp);
2871 spin_lock_irqsave(&nesqp->lock, qplockflags); 2870 spin_lock_irqsave(&nesqp->lock, qplockflags);
2872 2871
2873 nes_debug(NES_DBG_MOD_QP, "QP%u: hw_iwarp_state=0x%X, hw_tcp_state=0x%X," 2872 nes_debug(NES_DBG_MOD_QP, "QP%u: hw_iwarp_state=0x%X, hw_tcp_state=0x%X,"
@@ -2882,7 +2881,6 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
2882 nesqp->hwqp.qp_id); 2881 nesqp->hwqp.qp_id);
2883 if (nesqp->iwarp_state > (u32)NES_CQP_QP_IWARP_STATE_IDLE) { 2882 if (nesqp->iwarp_state > (u32)NES_CQP_QP_IWARP_STATE_IDLE) {
2884 spin_unlock_irqrestore(&nesqp->lock, qplockflags); 2883 spin_unlock_irqrestore(&nesqp->lock, qplockflags);
2885 nes_rem_ref(&nesqp->ibqp);
2886 return -EINVAL; 2884 return -EINVAL;
2887 } 2885 }
2888 next_iwarp_state = NES_CQP_QP_IWARP_STATE_IDLE; 2886 next_iwarp_state = NES_CQP_QP_IWARP_STATE_IDLE;
@@ -2893,7 +2891,6 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
2893 nesqp->hwqp.qp_id); 2891 nesqp->hwqp.qp_id);
2894 if (nesqp->iwarp_state>(u32)NES_CQP_QP_IWARP_STATE_IDLE) { 2892 if (nesqp->iwarp_state>(u32)NES_CQP_QP_IWARP_STATE_IDLE) {
2895 spin_unlock_irqrestore(&nesqp->lock, qplockflags); 2893 spin_unlock_irqrestore(&nesqp->lock, qplockflags);
2896 nes_rem_ref(&nesqp->ibqp);
2897 return -EINVAL; 2894 return -EINVAL;
2898 } 2895 }
2899 next_iwarp_state = NES_CQP_QP_IWARP_STATE_IDLE; 2896 next_iwarp_state = NES_CQP_QP_IWARP_STATE_IDLE;
@@ -2904,14 +2901,12 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
2904 nesqp->hwqp.qp_id); 2901 nesqp->hwqp.qp_id);
2905 if (nesqp->iwarp_state>(u32)NES_CQP_QP_IWARP_STATE_RTS) { 2902 if (nesqp->iwarp_state>(u32)NES_CQP_QP_IWARP_STATE_RTS) {
2906 spin_unlock_irqrestore(&nesqp->lock, qplockflags); 2903 spin_unlock_irqrestore(&nesqp->lock, qplockflags);
2907 nes_rem_ref(&nesqp->ibqp);
2908 return -EINVAL; 2904 return -EINVAL;
2909 } 2905 }
2910 if (nesqp->cm_id == NULL) { 2906 if (nesqp->cm_id == NULL) {
2911 nes_debug(NES_DBG_MOD_QP, "QP%u: Failing attempt to move QP to RTS without a CM_ID. \n", 2907 nes_debug(NES_DBG_MOD_QP, "QP%u: Failing attempt to move QP to RTS without a CM_ID. \n",
2912 nesqp->hwqp.qp_id ); 2908 nesqp->hwqp.qp_id );
2913 spin_unlock_irqrestore(&nesqp->lock, qplockflags); 2909 spin_unlock_irqrestore(&nesqp->lock, qplockflags);
2914 nes_rem_ref(&nesqp->ibqp);
2915 return -EINVAL; 2910 return -EINVAL;
2916 } 2911 }
2917 next_iwarp_state = NES_CQP_QP_IWARP_STATE_RTS; 2912 next_iwarp_state = NES_CQP_QP_IWARP_STATE_RTS;
@@ -2929,7 +2924,6 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
2929 nesqp->hwqp.qp_id, nesqp->hwqp.sq_head, nesqp->hwqp.sq_tail); 2924 nesqp->hwqp.qp_id, nesqp->hwqp.sq_head, nesqp->hwqp.sq_tail);
2930 if (nesqp->iwarp_state == (u32)NES_CQP_QP_IWARP_STATE_CLOSING) { 2925 if (nesqp->iwarp_state == (u32)NES_CQP_QP_IWARP_STATE_CLOSING) {
2931 spin_unlock_irqrestore(&nesqp->lock, qplockflags); 2926 spin_unlock_irqrestore(&nesqp->lock, qplockflags);
2932 nes_rem_ref(&nesqp->ibqp);
2933 return 0; 2927 return 0;
2934 } else { 2928 } else {
2935 if (nesqp->iwarp_state > (u32)NES_CQP_QP_IWARP_STATE_CLOSING) { 2929 if (nesqp->iwarp_state > (u32)NES_CQP_QP_IWARP_STATE_CLOSING) {
@@ -2937,7 +2931,6 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
2937 " ignored due to current iWARP state\n", 2931 " ignored due to current iWARP state\n",
2938 nesqp->hwqp.qp_id); 2932 nesqp->hwqp.qp_id);
2939 spin_unlock_irqrestore(&nesqp->lock, qplockflags); 2933 spin_unlock_irqrestore(&nesqp->lock, qplockflags);
2940 nes_rem_ref(&nesqp->ibqp);
2941 return -EINVAL; 2934 return -EINVAL;
2942 } 2935 }
2943 if (nesqp->hw_iwarp_state != NES_AEQE_IWARP_STATE_RTS) { 2936 if (nesqp->hw_iwarp_state != NES_AEQE_IWARP_STATE_RTS) {
@@ -2969,7 +2962,6 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
2969 nesqp->hwqp.qp_id); 2962 nesqp->hwqp.qp_id);
2970 if (nesqp->iwarp_state>=(u32)NES_CQP_QP_IWARP_STATE_TERMINATE) { 2963 if (nesqp->iwarp_state>=(u32)NES_CQP_QP_IWARP_STATE_TERMINATE) {
2971 spin_unlock_irqrestore(&nesqp->lock, qplockflags); 2964 spin_unlock_irqrestore(&nesqp->lock, qplockflags);
2972 nes_rem_ref(&nesqp->ibqp);
2973 return -EINVAL; 2965 return -EINVAL;
2974 } 2966 }
2975 /* next_iwarp_state = (NES_CQP_QP_IWARP_STATE_TERMINATE | 0x02000000); */ 2967 /* next_iwarp_state = (NES_CQP_QP_IWARP_STATE_TERMINATE | 0x02000000); */
@@ -2982,7 +2974,6 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
2982 case IB_QPS_RESET: 2974 case IB_QPS_RESET:
2983 if (nesqp->iwarp_state == (u32)NES_CQP_QP_IWARP_STATE_ERROR) { 2975 if (nesqp->iwarp_state == (u32)NES_CQP_QP_IWARP_STATE_ERROR) {
2984 spin_unlock_irqrestore(&nesqp->lock, qplockflags); 2976 spin_unlock_irqrestore(&nesqp->lock, qplockflags);
2985 nes_rem_ref(&nesqp->ibqp);
2986 return -EINVAL; 2977 return -EINVAL;
2987 } 2978 }
2988 nes_debug(NES_DBG_MOD_QP, "QP%u: new state = error\n", 2979 nes_debug(NES_DBG_MOD_QP, "QP%u: new state = error\n",
@@ -3008,7 +2999,6 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
3008 break; 2999 break;
3009 default: 3000 default:
3010 spin_unlock_irqrestore(&nesqp->lock, qplockflags); 3001 spin_unlock_irqrestore(&nesqp->lock, qplockflags);
3011 nes_rem_ref(&nesqp->ibqp);
3012 return -EINVAL; 3002 return -EINVAL;
3013 break; 3003 break;
3014 } 3004 }
@@ -3088,7 +3078,6 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
3088 nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount), 3078 nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount),
3089 original_last_aeq, nesqp->last_aeq); 3079 original_last_aeq, nesqp->last_aeq);
3090 /* this one is for the cm_disconnect thread */ 3080 /* this one is for the cm_disconnect thread */
3091 nes_add_ref(&nesqp->ibqp);
3092 spin_lock_irqsave(&nesqp->lock, qplockflags); 3081 spin_lock_irqsave(&nesqp->lock, qplockflags);
3093 nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED; 3082 nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED;
3094 nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT; 3083 nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT;
@@ -3097,14 +3086,12 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
3097 } else { 3086 } else {
3098 nes_debug(NES_DBG_MOD_QP, "QP%u No fake disconnect, QP refcount=%d\n", 3087 nes_debug(NES_DBG_MOD_QP, "QP%u No fake disconnect, QP refcount=%d\n",
3099 nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount)); 3088 nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount));
3100 nes_rem_ref(&nesqp->ibqp);
3101 } 3089 }
3102 } else { 3090 } else {
3103 spin_lock_irqsave(&nesqp->lock, qplockflags); 3091 spin_lock_irqsave(&nesqp->lock, qplockflags);
3104 if (nesqp->cm_id) { 3092 if (nesqp->cm_id) {
3105 /* These two are for the timer thread */ 3093 /* These two are for the timer thread */
3106 if (atomic_inc_return(&nesqp->close_timer_started) == 1) { 3094 if (atomic_inc_return(&nesqp->close_timer_started) == 1) {
3107 nes_add_ref(&nesqp->ibqp);
3108 nesqp->cm_id->add_ref(nesqp->cm_id); 3095 nesqp->cm_id->add_ref(nesqp->cm_id);
3109 nes_debug(NES_DBG_MOD_QP, "QP%u Not decrementing QP refcount (%d)," 3096 nes_debug(NES_DBG_MOD_QP, "QP%u Not decrementing QP refcount (%d),"
3110 " need ae to finish up, original_last_aeq = 0x%04X." 3097 " need ae to finish up, original_last_aeq = 0x%04X."
@@ -3128,14 +3115,12 @@ int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
3128 " original_last_aeq = 0x%04X. last_aeq = 0x%04X.\n", 3115 " original_last_aeq = 0x%04X. last_aeq = 0x%04X.\n",
3129 nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount), 3116 nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount),
3130 original_last_aeq, nesqp->last_aeq); 3117 original_last_aeq, nesqp->last_aeq);
3131 nes_rem_ref(&nesqp->ibqp);
3132 } 3118 }
3133 } else { 3119 } else {
3134 nes_debug(NES_DBG_MOD_QP, "QP%u Decrementing QP refcount (%d), No ae to finish up," 3120 nes_debug(NES_DBG_MOD_QP, "QP%u Decrementing QP refcount (%d), No ae to finish up,"
3135 " original_last_aeq = 0x%04X. last_aeq = 0x%04X.\n", 3121 " original_last_aeq = 0x%04X. last_aeq = 0x%04X.\n",
3136 nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount), 3122 nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount),
3137 original_last_aeq, nesqp->last_aeq); 3123 original_last_aeq, nesqp->last_aeq);
3138 nes_rem_ref(&nesqp->ibqp);
3139 } 3124 }
3140 3125
3141 err = 0; 3126 err = 0;