aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/core/ucm.c10
-rw-r--r--drivers/infiniband/core/ucma.c11
-rw-r--r--drivers/infiniband/hw/mlx4/cq.c1
-rw-r--r--drivers/infiniband/hw/mlx4/main.c1
-rw-r--r--drivers/infiniband/hw/mlx4/mlx4_ib.h1
-rw-r--r--drivers/infiniband/hw/mlx4/mr.c1
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c1
-rw-r--r--drivers/infiniband/hw/mlx4/srq.c1
-rw-r--r--drivers/infiniband/hw/mlx4/user.h1
-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
-rw-r--r--drivers/infiniband/ulp/ipoib/Kconfig22
-rw-r--r--drivers/net/mlx4/alloc.c1
-rw-r--r--drivers/net/mlx4/catas.c1
-rw-r--r--drivers/net/mlx4/cmd.c2
-rw-r--r--drivers/net/mlx4/cq.c2
-rw-r--r--drivers/net/mlx4/eq.c2
-rw-r--r--drivers/net/mlx4/fw.c2
-rw-r--r--drivers/net/mlx4/fw.h2
-rw-r--r--drivers/net/mlx4/icm.c2
-rw-r--r--drivers/net/mlx4/icm.h2
-rw-r--r--drivers/net/mlx4/intf.c1
-rw-r--r--drivers/net/mlx4/main.c2
-rw-r--r--drivers/net/mlx4/mcg.c1
-rw-r--r--drivers/net/mlx4/mlx4.h2
-rw-r--r--drivers/net/mlx4/mr.c2
-rw-r--r--drivers/net/mlx4/qp.c2
-rw-r--r--drivers/net/mlx4/reset.c1
-rw-r--r--drivers/net/mlx4/srq.c1
-rw-r--r--include/linux/mlx4/qp.h4
33 files changed, 1211 insertions, 956 deletions
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c
index 9494005d1c9a..e603736682bf 100644
--- a/drivers/infiniband/core/ucm.c
+++ b/drivers/infiniband/core/ucm.c
@@ -43,7 +43,6 @@
43#include <linux/cdev.h> 43#include <linux/cdev.h>
44#include <linux/idr.h> 44#include <linux/idr.h>
45#include <linux/mutex.h> 45#include <linux/mutex.h>
46#include <linux/smp_lock.h>
47 46
48#include <asm/uaccess.h> 47#include <asm/uaccess.h>
49 48
@@ -1154,11 +1153,18 @@ static unsigned int ib_ucm_poll(struct file *filp,
1154 return mask; 1153 return mask;
1155} 1154}
1156 1155
1156/*
1157 * ib_ucm_open() does not need the BKL:
1158 *
1159 * - no global state is referred to;
1160 * - there is no ioctl method to race against;
1161 * - no further module initialization is required for open to work
1162 * after the device is registered.
1163 */
1157static int ib_ucm_open(struct inode *inode, struct file *filp) 1164static int ib_ucm_open(struct inode *inode, struct file *filp)
1158{ 1165{
1159 struct ib_ucm_file *file; 1166 struct ib_ucm_file *file;
1160 1167
1161 cycle_kernel_lock();
1162 file = kmalloc(sizeof(*file), GFP_KERNEL); 1168 file = kmalloc(sizeof(*file), GFP_KERNEL);
1163 if (!file) 1169 if (!file)
1164 return -ENOMEM; 1170 return -ENOMEM;
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index 195f97302fe5..b41dd26bbfa1 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -38,7 +38,6 @@
38#include <linux/in.h> 38#include <linux/in.h>
39#include <linux/in6.h> 39#include <linux/in6.h>
40#include <linux/miscdevice.h> 40#include <linux/miscdevice.h>
41#include <linux/smp_lock.h>
42 41
43#include <rdma/rdma_user_cm.h> 42#include <rdma/rdma_user_cm.h>
44#include <rdma/ib_marshall.h> 43#include <rdma/ib_marshall.h>
@@ -1149,6 +1148,14 @@ static unsigned int ucma_poll(struct file *filp, struct poll_table_struct *wait)
1149 return mask; 1148 return mask;
1150} 1149}
1151 1150
1151/*
1152 * ucma_open() does not need the BKL:
1153 *
1154 * - no global state is referred to;
1155 * - there is no ioctl method to race against;
1156 * - no further module initialization is required for open to work
1157 * after the device is registered.
1158 */
1152static int ucma_open(struct inode *inode, struct file *filp) 1159static int ucma_open(struct inode *inode, struct file *filp)
1153{ 1160{
1154 struct ucma_file *file; 1161 struct ucma_file *file;
@@ -1157,7 +1164,6 @@ static int ucma_open(struct inode *inode, struct file *filp)
1157 if (!file) 1164 if (!file)
1158 return -ENOMEM; 1165 return -ENOMEM;
1159 1166
1160 lock_kernel();
1161 INIT_LIST_HEAD(&file->event_list); 1167 INIT_LIST_HEAD(&file->event_list);
1162 INIT_LIST_HEAD(&file->ctx_list); 1168 INIT_LIST_HEAD(&file->ctx_list);
1163 init_waitqueue_head(&file->poll_wait); 1169 init_waitqueue_head(&file->poll_wait);
@@ -1165,7 +1171,6 @@ static int ucma_open(struct inode *inode, struct file *filp)
1165 1171
1166 filp->private_data = file; 1172 filp->private_data = file;
1167 file->filp = filp; 1173 file->filp = filp;
1168 unlock_kernel();
1169 return 0; 1174 return 0;
1170} 1175}
1171 1176
diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c
index 0b191a4842ce..a1464574bfdd 100644
--- a/drivers/infiniband/hw/mlx4/cq.c
+++ b/drivers/infiniband/hw/mlx4/cq.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved. 2 * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
3 * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index 38d6907ab521..a3c2851c0545 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved. 2 * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved.
3 * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h
index d26a91317d4d..6e2b0dc21b61 100644
--- a/drivers/infiniband/hw/mlx4/mlx4_ib.h
+++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2006, 2007 Cisco Systems. All rights reserved. 2 * Copyright (c) 2006, 2007 Cisco Systems. All rights reserved.
3 * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c
index db2086faa4ed..a4cdb465cd1d 100644
--- a/drivers/infiniband/hw/mlx4/mr.c
+++ b/drivers/infiniband/hw/mlx4/mr.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved. 2 * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
3 * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 02a99bc4442e..f7bc7dd8578a 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved. 2 * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
3 * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c
index 12d6bc6f8007..d42565258fb7 100644
--- a/drivers/infiniband/hw/mlx4/srq.c
+++ b/drivers/infiniband/hw/mlx4/srq.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved. 2 * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
3 * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/mlx4/user.h b/drivers/infiniband/hw/mlx4/user.h
index e2d11be4525c..13beedeeef9f 100644
--- a/drivers/infiniband/hw/mlx4/user.h
+++ b/drivers/infiniband/hw/mlx4/user.h
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved. 2 * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
3 * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
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;
diff --git a/drivers/infiniband/ulp/ipoib/Kconfig b/drivers/infiniband/ulp/ipoib/Kconfig
index 691525cf394a..9d9a9dc51f18 100644
--- a/drivers/infiniband/ulp/ipoib/Kconfig
+++ b/drivers/infiniband/ulp/ipoib/Kconfig
@@ -11,16 +11,17 @@ config INFINIBAND_IPOIB
11 11
12config INFINIBAND_IPOIB_CM 12config INFINIBAND_IPOIB_CM
13 bool "IP-over-InfiniBand Connected Mode support" 13 bool "IP-over-InfiniBand Connected Mode support"
14 depends on INFINIBAND_IPOIB && EXPERIMENTAL 14 depends on INFINIBAND_IPOIB
15 default n 15 default n
16 ---help--- 16 ---help---
17 This option enables experimental support for IPoIB connected mode. 17 This option enables support for IPoIB connected mode. After
18 After enabling this option, you need to switch to connected mode through 18 enabling this option, you need to switch to connected mode
19 /sys/class/net/ibXXX/mode to actually create connections, and then increase 19 through /sys/class/net/ibXXX/mode to actually create
20 the interface MTU with e.g. ifconfig ib0 mtu 65520. 20 connections, and then increase the interface MTU with
21 e.g. ifconfig ib0 mtu 65520.
21 22
22 WARNING: Enabling connected mode will trigger some 23 WARNING: Enabling connected mode will trigger some packet
23 packet drops for multicast and UD mode traffic from this interface, 24 drops for multicast and UD mode traffic from this interface,
24 unless you limit mtu for these destinations to 2044. 25 unless you limit mtu for these destinations to 2044.
25 26
26config INFINIBAND_IPOIB_DEBUG 27config INFINIBAND_IPOIB_DEBUG
@@ -33,9 +34,10 @@ config INFINIBAND_IPOIB_DEBUG
33 debug_level and mcast_debug_level module parameters (which 34 debug_level and mcast_debug_level module parameters (which
34 can also be set after the driver is loaded through sysfs). 35 can also be set after the driver is loaded through sysfs).
35 36
36 This option also creates an "ipoib_debugfs," which can be 37 This option also creates a directory tree under ipoib/ in
37 mounted to expose debugging information about IB multicast 38 debugfs, which contains files that expose debugging
38 groups used by the IPoIB driver. 39 information about IB multicast groups used by the IPoIB
40 driver.
39 41
40config INFINIBAND_IPOIB_DEBUG_DATA 42config INFINIBAND_IPOIB_DEBUG_DATA
41 bool "IP-over-InfiniBand data path debugging" 43 bool "IP-over-InfiniBand data path debugging"
diff --git a/drivers/net/mlx4/alloc.c b/drivers/net/mlx4/alloc.c
index f9d6b4dca180..096bca54bcf7 100644
--- a/drivers/net/mlx4/alloc.c
+++ b/drivers/net/mlx4/alloc.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved. 2 * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved.
3 * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/net/mlx4/catas.c b/drivers/net/mlx4/catas.c
index aa9528779044..f094ee00c416 100644
--- a/drivers/net/mlx4/catas.c
+++ b/drivers/net/mlx4/catas.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved. 2 * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
3 * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/net/mlx4/cmd.c b/drivers/net/mlx4/cmd.c
index 04d5bc69a6f8..2845a0560b84 100644
--- a/drivers/net/mlx4/cmd.c
+++ b/drivers/net/mlx4/cmd.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Mellanox Technologies. All rights reserved. 3 * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. All rights reserved.
4 * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc. All rights reserved. 4 * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc. All rights reserved.
5 * 5 *
6 * This software is available to you under a choice of one of two 6 * This software is available to you under a choice of one of two
diff --git a/drivers/net/mlx4/cq.c b/drivers/net/mlx4/cq.c
index 95e87a2f8896..9bb50e3f8974 100644
--- a/drivers/net/mlx4/cq.c
+++ b/drivers/net/mlx4/cq.c
@@ -2,7 +2,7 @@
2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. 3 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
4 * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc. All rights reserved. 4 * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc. All rights reserved.
5 * Copyright (c) 2005 Mellanox Technologies. All rights reserved. 5 * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. All rights reserved.
6 * Copyright (c) 2004 Voltaire, Inc. All rights reserved. 6 * Copyright (c) 2004 Voltaire, Inc. All rights reserved.
7 * 7 *
8 * This software is available to you under a choice of one of two 8 * This software is available to you under a choice of one of two
diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c
index 7df928d3a3d8..8a8b56135a58 100644
--- a/drivers/net/mlx4/eq.c
+++ b/drivers/net/mlx4/eq.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2005 Mellanox Technologies. All rights reserved. 2 * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. All rights reserved.
3 * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc. All rights reserved. 3 * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc. All rights reserved.
4 * 4 *
5 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c
index 57278224ba1e..7e32955da982 100644
--- a/drivers/net/mlx4/fw.c
+++ b/drivers/net/mlx4/fw.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Mellanox Technologies. All rights reserved. 3 * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. All rights reserved.
4 * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc. All rights reserved. 4 * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc. All rights reserved.
5 * 5 *
6 * This software is available to you under a choice of one of two 6 * This software is available to you under a choice of one of two
diff --git a/drivers/net/mlx4/fw.h b/drivers/net/mlx4/fw.h
index fbf0e22be122..decbb5c2ad41 100644
--- a/drivers/net/mlx4/fw.h
+++ b/drivers/net/mlx4/fw.h
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Mellanox Technologies. All rights reserved. 3 * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. All rights reserved.
4 * Copyright (c) 2006, 2007 Cisco Systems. All rights reserved. 4 * Copyright (c) 2006, 2007 Cisco Systems. All rights reserved.
5 * 5 *
6 * This software is available to you under a choice of one of two 6 * This software is available to you under a choice of one of two
diff --git a/drivers/net/mlx4/icm.c b/drivers/net/mlx4/icm.c
index 2a5bef6388fe..baf4bf66062c 100644
--- a/drivers/net/mlx4/icm.c
+++ b/drivers/net/mlx4/icm.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2005 Mellanox Technologies. All rights reserved. 2 * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. All rights reserved.
3 * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved. 3 * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved.
4 * 4 *
5 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
diff --git a/drivers/net/mlx4/icm.h b/drivers/net/mlx4/icm.h
index 6c44edf35847..ab56a2f89b65 100644
--- a/drivers/net/mlx4/icm.h
+++ b/drivers/net/mlx4/icm.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2005 Mellanox Technologies. All rights reserved. 2 * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. All rights reserved.
3 * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved. 3 * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved.
4 * 4 *
5 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
diff --git a/drivers/net/mlx4/intf.c b/drivers/net/mlx4/intf.c
index 4a6c4d526f1b..0e7eb1038f9f 100644
--- a/drivers/net/mlx4/intf.c
+++ b/drivers/net/mlx4/intf.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved. 2 * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved.
3 * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
index 8e1d24cda1b0..1252a919de2e 100644
--- a/drivers/net/mlx4/main.c
+++ b/drivers/net/mlx4/main.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. 3 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
4 * Copyright (c) 2005 Mellanox Technologies. All rights reserved. 4 * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. All rights reserved.
5 * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved. 5 * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved.
6 * 6 *
7 * This software is available to you under a choice of one of two 7 * This software is available to you under a choice of one of two
diff --git a/drivers/net/mlx4/mcg.c b/drivers/net/mlx4/mcg.c
index b4b57870ddfd..c83f88ce0736 100644
--- a/drivers/net/mlx4/mcg.c
+++ b/drivers/net/mlx4/mcg.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved. 2 * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved.
3 * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h
index 78038499cff5..5337e3ac3e78 100644
--- a/drivers/net/mlx4/mlx4.h
+++ b/drivers/net/mlx4/mlx4.h
@@ -2,7 +2,7 @@
2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. 3 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
4 * Copyright (c) 2005, 2006, 2007 Cisco Systems. All rights reserved. 4 * Copyright (c) 2005, 2006, 2007 Cisco Systems. All rights reserved.
5 * Copyright (c) 2005 Mellanox Technologies. All rights reserved. 5 * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. All rights reserved.
6 * Copyright (c) 2004 Voltaire, Inc. All rights reserved. 6 * Copyright (c) 2004 Voltaire, Inc. All rights reserved.
7 * 7 *
8 * This software is available to you under a choice of one of two 8 * This software is available to you under a choice of one of two
diff --git a/drivers/net/mlx4/mr.c b/drivers/net/mlx4/mr.c
index a3c04c5f12c2..62071d9c4a55 100644
--- a/drivers/net/mlx4/mr.c
+++ b/drivers/net/mlx4/mr.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Mellanox Technologies. All rights reserved. 3 * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. All rights reserved.
4 * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved. 4 * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved.
5 * 5 *
6 * This software is available to you under a choice of one of two 6 * This software is available to you under a choice of one of two
diff --git a/drivers/net/mlx4/qp.c b/drivers/net/mlx4/qp.c
index ee5484c44a18..c49a86044bf7 100644
--- a/drivers/net/mlx4/qp.c
+++ b/drivers/net/mlx4/qp.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc. All rights reserved. 3 * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc. All rights reserved.
4 * Copyright (c) 2005 Mellanox Technologies. All rights reserved. 4 * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. All rights reserved.
5 * Copyright (c) 2004 Voltaire, Inc. All rights reserved. 5 * Copyright (c) 2004 Voltaire, Inc. All rights reserved.
6 * 6 *
7 * This software is available to you under a choice of one of two 7 * This software is available to you under a choice of one of two
diff --git a/drivers/net/mlx4/reset.c b/drivers/net/mlx4/reset.c
index e199715fabd0..3951b884c0fb 100644
--- a/drivers/net/mlx4/reset.c
+++ b/drivers/net/mlx4/reset.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved. 2 * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved.
3 * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/net/mlx4/srq.c b/drivers/net/mlx4/srq.c
index d23f46d692ef..533eb6db24b3 100644
--- a/drivers/net/mlx4/srq.c
+++ b/drivers/net/mlx4/srq.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved. 2 * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved.
3 * Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/include/linux/mlx4/qp.h b/include/linux/mlx4/qp.h
index e27082cd650e..bf8f11982dae 100644
--- a/include/linux/mlx4/qp.h
+++ b/include/linux/mlx4/qp.h
@@ -164,11 +164,13 @@ enum {
164 MLX4_WQE_CTRL_SOLICITED = 1 << 1, 164 MLX4_WQE_CTRL_SOLICITED = 1 << 1,
165 MLX4_WQE_CTRL_IP_CSUM = 1 << 4, 165 MLX4_WQE_CTRL_IP_CSUM = 1 << 4,
166 MLX4_WQE_CTRL_TCP_UDP_CSUM = 1 << 5, 166 MLX4_WQE_CTRL_TCP_UDP_CSUM = 1 << 5,
167 MLX4_WQE_CTRL_INS_VLAN = 1 << 6,
167}; 168};
168 169
169struct mlx4_wqe_ctrl_seg { 170struct mlx4_wqe_ctrl_seg {
170 __be32 owner_opcode; 171 __be32 owner_opcode;
171 u8 reserved2[3]; 172 __be16 vlan_tag;
173 u8 ins_vlan;
172 u8 fence_size; 174 u8 fence_size;
173 /* 175 /*
174 * High 24 bits are SRC remote buffer; low 8 bits are flags: 176 * High 24 bits are SRC remote buffer; low 8 bits are flags: