xref: /openbmc/linux/drivers/infiniband/hw/cxgb4/cm.c (revision 5dab6d3a)
1cfdda9d7SSteve Wise /*
29eccfe10SSteve Wise  * Copyright (c) 2009-2014 Chelsio, Inc. All rights reserved.
3cfdda9d7SSteve Wise  *
4cfdda9d7SSteve Wise  * This software is available to you under a choice of one of two
5cfdda9d7SSteve Wise  * licenses.  You may choose to be licensed under the terms of the GNU
6cfdda9d7SSteve Wise  * General Public License (GPL) Version 2, available from the file
7cfdda9d7SSteve Wise  * COPYING in the main directory of this source tree, or the
8cfdda9d7SSteve Wise  * OpenIB.org BSD license below:
9cfdda9d7SSteve Wise  *
10cfdda9d7SSteve Wise  *     Redistribution and use in source and binary forms, with or
11cfdda9d7SSteve Wise  *     without modification, are permitted provided that the following
12cfdda9d7SSteve Wise  *     conditions are met:
13cfdda9d7SSteve Wise  *
14cfdda9d7SSteve Wise  *      - Redistributions of source code must retain the above
15cfdda9d7SSteve Wise  *	  copyright notice, this list of conditions and the following
16cfdda9d7SSteve Wise  *	  disclaimer.
17cfdda9d7SSteve Wise  *
18cfdda9d7SSteve Wise  *      - Redistributions in binary form must reproduce the above
19cfdda9d7SSteve Wise  *	  copyright notice, this list of conditions and the following
20cfdda9d7SSteve Wise  *	  disclaimer in the documentation and/or other materials
21cfdda9d7SSteve Wise  *	  provided with the distribution.
22cfdda9d7SSteve Wise  *
23cfdda9d7SSteve Wise  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24cfdda9d7SSteve Wise  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25cfdda9d7SSteve Wise  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26cfdda9d7SSteve Wise  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27cfdda9d7SSteve Wise  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28cfdda9d7SSteve Wise  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29cfdda9d7SSteve Wise  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30cfdda9d7SSteve Wise  * SOFTWARE.
31cfdda9d7SSteve Wise  */
32cfdda9d7SSteve Wise #include <linux/module.h>
33cfdda9d7SSteve Wise #include <linux/list.h>
34cfdda9d7SSteve Wise #include <linux/workqueue.h>
35cfdda9d7SSteve Wise #include <linux/skbuff.h>
36cfdda9d7SSteve Wise #include <linux/timer.h>
37cfdda9d7SSteve Wise #include <linux/notifier.h>
38cfdda9d7SSteve Wise #include <linux/inetdevice.h>
39cfdda9d7SSteve Wise #include <linux/ip.h>
40cfdda9d7SSteve Wise #include <linux/tcp.h>
411cab775cSVipul Pandya #include <linux/if_vlan.h>
42cfdda9d7SSteve Wise 
43cfdda9d7SSteve Wise #include <net/neighbour.h>
44cfdda9d7SSteve Wise #include <net/netevent.h>
45cfdda9d7SSteve Wise #include <net/route.h>
461cab775cSVipul Pandya #include <net/tcp.h>
47830662f6SVipul Pandya #include <net/ip6_route.h>
48830662f6SVipul Pandya #include <net/addrconf.h>
49cfdda9d7SSteve Wise 
5011b8e22dSSteve Wise #include <rdma/ib_addr.h>
5111b8e22dSSteve Wise 
52cfdda9d7SSteve Wise #include "iw_cxgb4.h"
53cfdda9d7SSteve Wise 
54cfdda9d7SSteve Wise static char *states[] = {
55cfdda9d7SSteve Wise 	"idle",
56cfdda9d7SSteve Wise 	"listen",
57cfdda9d7SSteve Wise 	"connecting",
58cfdda9d7SSteve Wise 	"mpa_wait_req",
59cfdda9d7SSteve Wise 	"mpa_req_sent",
60cfdda9d7SSteve Wise 	"mpa_req_rcvd",
61cfdda9d7SSteve Wise 	"mpa_rep_sent",
62cfdda9d7SSteve Wise 	"fpdu_mode",
63cfdda9d7SSteve Wise 	"aborting",
64cfdda9d7SSteve Wise 	"closing",
65cfdda9d7SSteve Wise 	"moribund",
66cfdda9d7SSteve Wise 	"dead",
67cfdda9d7SSteve Wise 	NULL,
68cfdda9d7SSteve Wise };
69cfdda9d7SSteve Wise 
705be78ee9SVipul Pandya static int nocong;
715be78ee9SVipul Pandya module_param(nocong, int, 0644);
725be78ee9SVipul Pandya MODULE_PARM_DESC(nocong, "Turn of congestion control (default=0)");
735be78ee9SVipul Pandya 
745be78ee9SVipul Pandya static int enable_ecn;
755be78ee9SVipul Pandya module_param(enable_ecn, int, 0644);
765be78ee9SVipul Pandya MODULE_PARM_DESC(enable_ecn, "Enable ECN (default=0/disabled)");
775be78ee9SVipul Pandya 
78b52fe09eSSteve Wise static int dack_mode = 1;
79ba6d3925SSteve Wise module_param(dack_mode, int, 0644);
80b52fe09eSSteve Wise MODULE_PARM_DESC(dack_mode, "Delayed ack mode (default=1)");
81ba6d3925SSteve Wise 
82be4c9badSRoland Dreier int c4iw_max_read_depth = 8;
83be4c9badSRoland Dreier module_param(c4iw_max_read_depth, int, 0644);
84be4c9badSRoland Dreier MODULE_PARM_DESC(c4iw_max_read_depth, "Per-connection max ORD/IRD (default=8)");
85be4c9badSRoland Dreier 
86cfdda9d7SSteve Wise static int enable_tcp_timestamps;
87cfdda9d7SSteve Wise module_param(enable_tcp_timestamps, int, 0644);
88cfdda9d7SSteve Wise MODULE_PARM_DESC(enable_tcp_timestamps, "Enable tcp timestamps (default=0)");
89cfdda9d7SSteve Wise 
90cfdda9d7SSteve Wise static int enable_tcp_sack;
91cfdda9d7SSteve Wise module_param(enable_tcp_sack, int, 0644);
92cfdda9d7SSteve Wise MODULE_PARM_DESC(enable_tcp_sack, "Enable tcp SACK (default=0)");
93cfdda9d7SSteve Wise 
94cfdda9d7SSteve Wise static int enable_tcp_window_scaling = 1;
95cfdda9d7SSteve Wise module_param(enable_tcp_window_scaling, int, 0644);
96cfdda9d7SSteve Wise MODULE_PARM_DESC(enable_tcp_window_scaling,
97cfdda9d7SSteve Wise 		 "Enable tcp window scaling (default=1)");
98cfdda9d7SSteve Wise 
99cfdda9d7SSteve Wise int c4iw_debug;
100cfdda9d7SSteve Wise module_param(c4iw_debug, int, 0644);
101cfdda9d7SSteve Wise MODULE_PARM_DESC(c4iw_debug, "Enable debug logging (default=0)");
102cfdda9d7SSteve Wise 
103df2d5130SSteve Wise static int peer2peer = 1;
104cfdda9d7SSteve Wise module_param(peer2peer, int, 0644);
105df2d5130SSteve Wise MODULE_PARM_DESC(peer2peer, "Support peer2peer ULPs (default=1)");
106cfdda9d7SSteve Wise 
107cfdda9d7SSteve Wise static int p2p_type = FW_RI_INIT_P2PTYPE_READ_REQ;
108cfdda9d7SSteve Wise module_param(p2p_type, int, 0644);
109cfdda9d7SSteve Wise MODULE_PARM_DESC(p2p_type, "RDMAP opcode to use for the RTR message: "
110cfdda9d7SSteve Wise 			   "1=RDMA_READ 0=RDMA_WRITE (default 1)");
111cfdda9d7SSteve Wise 
112cfdda9d7SSteve Wise static int ep_timeout_secs = 60;
113cfdda9d7SSteve Wise module_param(ep_timeout_secs, int, 0644);
114cfdda9d7SSteve Wise MODULE_PARM_DESC(ep_timeout_secs, "CM Endpoint operation timeout "
115cfdda9d7SSteve Wise 				   "in seconds (default=60)");
116cfdda9d7SSteve Wise 
117cfdda9d7SSteve Wise static int mpa_rev = 1;
118cfdda9d7SSteve Wise module_param(mpa_rev, int, 0644);
119cfdda9d7SSteve Wise MODULE_PARM_DESC(mpa_rev, "MPA Revision, 0 supports amso1100, "
120d2fe99e8SKumar Sanghvi 		"1 is RFC0544 spec compliant, 2 is IETF MPA Peer Connect Draft"
121d2fe99e8SKumar Sanghvi 		" compliant (default=1)");
122cfdda9d7SSteve Wise 
123cfdda9d7SSteve Wise static int markers_enabled;
124cfdda9d7SSteve Wise module_param(markers_enabled, int, 0644);
125cfdda9d7SSteve Wise MODULE_PARM_DESC(markers_enabled, "Enable MPA MARKERS (default(0)=disabled)");
126cfdda9d7SSteve Wise 
127cfdda9d7SSteve Wise static int crc_enabled = 1;
128cfdda9d7SSteve Wise module_param(crc_enabled, int, 0644);
129cfdda9d7SSteve Wise MODULE_PARM_DESC(crc_enabled, "Enable MPA CRC (default(1)=enabled)");
130cfdda9d7SSteve Wise 
131cfdda9d7SSteve Wise static int rcv_win = 256 * 1024;
132cfdda9d7SSteve Wise module_param(rcv_win, int, 0644);
133cfdda9d7SSteve Wise MODULE_PARM_DESC(rcv_win, "TCP receive window in bytes (default=256KB)");
134cfdda9d7SSteve Wise 
13598ae68b7SSteve Wise static int snd_win = 128 * 1024;
136cfdda9d7SSteve Wise module_param(snd_win, int, 0644);
13798ae68b7SSteve Wise MODULE_PARM_DESC(snd_win, "TCP send window in bytes (default=128KB)");
138cfdda9d7SSteve Wise 
139cfdda9d7SSteve Wise static struct workqueue_struct *workq;
140cfdda9d7SSteve Wise 
141cfdda9d7SSteve Wise static struct sk_buff_head rxq;
142cfdda9d7SSteve Wise 
143cfdda9d7SSteve Wise static struct sk_buff *get_skb(struct sk_buff *skb, int len, gfp_t gfp);
144cfdda9d7SSteve Wise static void ep_timeout(unsigned long arg);
145cfdda9d7SSteve Wise static void connect_reply_upcall(struct c4iw_ep *ep, int status);
146cfdda9d7SSteve Wise 
147be4c9badSRoland Dreier static LIST_HEAD(timeout_list);
148be4c9badSRoland Dreier static spinlock_t timeout_lock;
149be4c9badSRoland Dreier 
150325abeadSVipul Pandya static void deref_qp(struct c4iw_ep *ep)
151325abeadSVipul Pandya {
152325abeadSVipul Pandya 	c4iw_qp_rem_ref(&ep->com.qp->ibqp);
153325abeadSVipul Pandya 	clear_bit(QP_REFERENCED, &ep->com.flags);
154325abeadSVipul Pandya }
155325abeadSVipul Pandya 
156325abeadSVipul Pandya static void ref_qp(struct c4iw_ep *ep)
157325abeadSVipul Pandya {
158325abeadSVipul Pandya 	set_bit(QP_REFERENCED, &ep->com.flags);
159325abeadSVipul Pandya 	c4iw_qp_add_ref(&ep->com.qp->ibqp);
160325abeadSVipul Pandya }
161325abeadSVipul Pandya 
162cfdda9d7SSteve Wise static void start_ep_timer(struct c4iw_ep *ep)
163cfdda9d7SSteve Wise {
164cfdda9d7SSteve Wise 	PDBG("%s ep %p\n", __func__, ep);
165cfdda9d7SSteve Wise 	if (timer_pending(&ep->timer)) {
1661ec779ccSVipul Pandya 		pr_err("%s timer already started! ep %p\n",
1671ec779ccSVipul Pandya 		       __func__, ep);
1681ec779ccSVipul Pandya 		return;
1691ec779ccSVipul Pandya 	}
1701ec779ccSVipul Pandya 	clear_bit(TIMEOUT, &ep->com.flags);
171cfdda9d7SSteve Wise 	c4iw_get_ep(&ep->com);
172cfdda9d7SSteve Wise 	ep->timer.expires = jiffies + ep_timeout_secs * HZ;
173cfdda9d7SSteve Wise 	ep->timer.data = (unsigned long)ep;
174cfdda9d7SSteve Wise 	ep->timer.function = ep_timeout;
175cfdda9d7SSteve Wise 	add_timer(&ep->timer);
176cfdda9d7SSteve Wise }
177cfdda9d7SSteve Wise 
178b33bd0cbSSteve Wise static int stop_ep_timer(struct c4iw_ep *ep)
179cfdda9d7SSteve Wise {
1801ec779ccSVipul Pandya 	PDBG("%s ep %p stopping\n", __func__, ep);
181cfdda9d7SSteve Wise 	del_timer_sync(&ep->timer);
182b33bd0cbSSteve Wise 	if (!test_and_set_bit(TIMEOUT, &ep->com.flags)) {
183cfdda9d7SSteve Wise 		c4iw_put_ep(&ep->com);
184b33bd0cbSSteve Wise 		return 0;
185b33bd0cbSSteve Wise 	}
186b33bd0cbSSteve Wise 	return 1;
187cfdda9d7SSteve Wise }
188cfdda9d7SSteve Wise 
189cfdda9d7SSteve Wise static int c4iw_l2t_send(struct c4iw_rdev *rdev, struct sk_buff *skb,
190cfdda9d7SSteve Wise 		  struct l2t_entry *l2e)
191cfdda9d7SSteve Wise {
192cfdda9d7SSteve Wise 	int	error = 0;
193cfdda9d7SSteve Wise 
194cfdda9d7SSteve Wise 	if (c4iw_fatal_error(rdev)) {
195cfdda9d7SSteve Wise 		kfree_skb(skb);
196cfdda9d7SSteve Wise 		PDBG("%s - device in error state - dropping\n", __func__);
197cfdda9d7SSteve Wise 		return -EIO;
198cfdda9d7SSteve Wise 	}
199cfdda9d7SSteve Wise 	error = cxgb4_l2t_send(rdev->lldi.ports[0], skb, l2e);
200cfdda9d7SSteve Wise 	if (error < 0)
201cfdda9d7SSteve Wise 		kfree_skb(skb);
20274594861SSteve Wise 	return error < 0 ? error : 0;
203cfdda9d7SSteve Wise }
204cfdda9d7SSteve Wise 
205cfdda9d7SSteve Wise int c4iw_ofld_send(struct c4iw_rdev *rdev, struct sk_buff *skb)
206cfdda9d7SSteve Wise {
207cfdda9d7SSteve Wise 	int	error = 0;
208cfdda9d7SSteve Wise 
209cfdda9d7SSteve Wise 	if (c4iw_fatal_error(rdev)) {
210cfdda9d7SSteve Wise 		kfree_skb(skb);
211cfdda9d7SSteve Wise 		PDBG("%s - device in error state - dropping\n", __func__);
212cfdda9d7SSteve Wise 		return -EIO;
213cfdda9d7SSteve Wise 	}
214cfdda9d7SSteve Wise 	error = cxgb4_ofld_send(rdev->lldi.ports[0], skb);
215cfdda9d7SSteve Wise 	if (error < 0)
216cfdda9d7SSteve Wise 		kfree_skb(skb);
21774594861SSteve Wise 	return error < 0 ? error : 0;
218cfdda9d7SSteve Wise }
219cfdda9d7SSteve Wise 
220cfdda9d7SSteve Wise static void release_tid(struct c4iw_rdev *rdev, u32 hwtid, struct sk_buff *skb)
221cfdda9d7SSteve Wise {
222cfdda9d7SSteve Wise 	struct cpl_tid_release *req;
223cfdda9d7SSteve Wise 
224cfdda9d7SSteve Wise 	skb = get_skb(skb, sizeof *req, GFP_KERNEL);
225cfdda9d7SSteve Wise 	if (!skb)
226cfdda9d7SSteve Wise 		return;
227cfdda9d7SSteve Wise 	req = (struct cpl_tid_release *) skb_put(skb, sizeof(*req));
228cfdda9d7SSteve Wise 	INIT_TP_WR(req, hwtid);
229cfdda9d7SSteve Wise 	OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_TID_RELEASE, hwtid));
230cfdda9d7SSteve Wise 	set_wr_txq(skb, CPL_PRIORITY_SETUP, 0);
231cfdda9d7SSteve Wise 	c4iw_ofld_send(rdev, skb);
232cfdda9d7SSteve Wise 	return;
233cfdda9d7SSteve Wise }
234cfdda9d7SSteve Wise 
235cfdda9d7SSteve Wise static void set_emss(struct c4iw_ep *ep, u16 opt)
236cfdda9d7SSteve Wise {
23792e7ae71SHariprasad Shenai 	ep->emss = ep->com.dev->rdev.lldi.mtus[GET_TCPOPT_MSS(opt)] -
23892e7ae71SHariprasad Shenai 		   sizeof(struct iphdr) - sizeof(struct tcphdr);
239cfdda9d7SSteve Wise 	ep->mss = ep->emss;
240cfdda9d7SSteve Wise 	if (GET_TCPOPT_TSTAMP(opt))
241cfdda9d7SSteve Wise 		ep->emss -= 12;
242cfdda9d7SSteve Wise 	if (ep->emss < 128)
243cfdda9d7SSteve Wise 		ep->emss = 128;
24492e7ae71SHariprasad Shenai 	if (ep->emss & 7)
24592e7ae71SHariprasad Shenai 		PDBG("Warning: misaligned mtu idx %u mss %u emss=%u\n",
24692e7ae71SHariprasad Shenai 		     GET_TCPOPT_MSS(opt), ep->mss, ep->emss);
247cfdda9d7SSteve Wise 	PDBG("%s mss_idx %u mss %u emss=%u\n", __func__, GET_TCPOPT_MSS(opt),
248cfdda9d7SSteve Wise 	     ep->mss, ep->emss);
249cfdda9d7SSteve Wise }
250cfdda9d7SSteve Wise 
251cfdda9d7SSteve Wise static enum c4iw_ep_state state_read(struct c4iw_ep_common *epc)
252cfdda9d7SSteve Wise {
253cfdda9d7SSteve Wise 	enum c4iw_ep_state state;
254cfdda9d7SSteve Wise 
2552f5b48c3SSteve Wise 	mutex_lock(&epc->mutex);
256cfdda9d7SSteve Wise 	state = epc->state;
2572f5b48c3SSteve Wise 	mutex_unlock(&epc->mutex);
258cfdda9d7SSteve Wise 	return state;
259cfdda9d7SSteve Wise }
260cfdda9d7SSteve Wise 
261cfdda9d7SSteve Wise static void __state_set(struct c4iw_ep_common *epc, enum c4iw_ep_state new)
262cfdda9d7SSteve Wise {
263cfdda9d7SSteve Wise 	epc->state = new;
264cfdda9d7SSteve Wise }
265cfdda9d7SSteve Wise 
266cfdda9d7SSteve Wise static void state_set(struct c4iw_ep_common *epc, enum c4iw_ep_state new)
267cfdda9d7SSteve Wise {
2682f5b48c3SSteve Wise 	mutex_lock(&epc->mutex);
269cfdda9d7SSteve Wise 	PDBG("%s - %s -> %s\n", __func__, states[epc->state], states[new]);
270cfdda9d7SSteve Wise 	__state_set(epc, new);
2712f5b48c3SSteve Wise 	mutex_unlock(&epc->mutex);
272cfdda9d7SSteve Wise 	return;
273cfdda9d7SSteve Wise }
274cfdda9d7SSteve Wise 
275cfdda9d7SSteve Wise static void *alloc_ep(int size, gfp_t gfp)
276cfdda9d7SSteve Wise {
277cfdda9d7SSteve Wise 	struct c4iw_ep_common *epc;
278cfdda9d7SSteve Wise 
279cfdda9d7SSteve Wise 	epc = kzalloc(size, gfp);
280cfdda9d7SSteve Wise 	if (epc) {
281cfdda9d7SSteve Wise 		kref_init(&epc->kref);
2822f5b48c3SSteve Wise 		mutex_init(&epc->mutex);
283aadc4df3SSteve Wise 		c4iw_init_wr_wait(&epc->wr_wait);
284cfdda9d7SSteve Wise 	}
285cfdda9d7SSteve Wise 	PDBG("%s alloc ep %p\n", __func__, epc);
286cfdda9d7SSteve Wise 	return epc;
287cfdda9d7SSteve Wise }
288cfdda9d7SSteve Wise 
289cfdda9d7SSteve Wise void _c4iw_free_ep(struct kref *kref)
290cfdda9d7SSteve Wise {
291cfdda9d7SSteve Wise 	struct c4iw_ep *ep;
292cfdda9d7SSteve Wise 
293cfdda9d7SSteve Wise 	ep = container_of(kref, struct c4iw_ep, com.kref);
294cfdda9d7SSteve Wise 	PDBG("%s ep %p state %s\n", __func__, ep, states[state_read(&ep->com)]);
295325abeadSVipul Pandya 	if (test_bit(QP_REFERENCED, &ep->com.flags))
296325abeadSVipul Pandya 		deref_qp(ep);
297cfdda9d7SSteve Wise 	if (test_bit(RELEASE_RESOURCES, &ep->com.flags)) {
298fe7e0a4dSVipul Pandya 		remove_handle(ep->com.dev, &ep->com.dev->hwtid_idr, ep->hwtid);
299cfdda9d7SSteve Wise 		cxgb4_remove_tid(ep->com.dev->rdev.lldi.tids, 0, ep->hwtid);
300cfdda9d7SSteve Wise 		dst_release(ep->dst);
301cfdda9d7SSteve Wise 		cxgb4_l2t_release(ep->l2t);
302cfdda9d7SSteve Wise 	}
3039eccfe10SSteve Wise 	if (test_bit(RELEASE_MAPINFO, &ep->com.flags)) {
3049eccfe10SSteve Wise 		print_addr(&ep->com, __func__, "remove_mapinfo/mapping");
3059eccfe10SSteve Wise 		iwpm_remove_mapinfo(&ep->com.local_addr,
3069eccfe10SSteve Wise 				    &ep->com.mapped_local_addr);
3079eccfe10SSteve Wise 		iwpm_remove_mapping(&ep->com.local_addr, RDMA_NL_C4IW);
3089eccfe10SSteve Wise 	}
309cfdda9d7SSteve Wise 	kfree(ep);
310cfdda9d7SSteve Wise }
311cfdda9d7SSteve Wise 
312cfdda9d7SSteve Wise static void release_ep_resources(struct c4iw_ep *ep)
313cfdda9d7SSteve Wise {
314cfdda9d7SSteve Wise 	set_bit(RELEASE_RESOURCES, &ep->com.flags);
315cfdda9d7SSteve Wise 	c4iw_put_ep(&ep->com);
316cfdda9d7SSteve Wise }
317cfdda9d7SSteve Wise 
318cfdda9d7SSteve Wise static int status2errno(int status)
319cfdda9d7SSteve Wise {
320cfdda9d7SSteve Wise 	switch (status) {
321cfdda9d7SSteve Wise 	case CPL_ERR_NONE:
322cfdda9d7SSteve Wise 		return 0;
323cfdda9d7SSteve Wise 	case CPL_ERR_CONN_RESET:
324cfdda9d7SSteve Wise 		return -ECONNRESET;
325cfdda9d7SSteve Wise 	case CPL_ERR_ARP_MISS:
326cfdda9d7SSteve Wise 		return -EHOSTUNREACH;
327cfdda9d7SSteve Wise 	case CPL_ERR_CONN_TIMEDOUT:
328cfdda9d7SSteve Wise 		return -ETIMEDOUT;
329cfdda9d7SSteve Wise 	case CPL_ERR_TCAM_FULL:
330cfdda9d7SSteve Wise 		return -ENOMEM;
331cfdda9d7SSteve Wise 	case CPL_ERR_CONN_EXIST:
332cfdda9d7SSteve Wise 		return -EADDRINUSE;
333cfdda9d7SSteve Wise 	default:
334cfdda9d7SSteve Wise 		return -EIO;
335cfdda9d7SSteve Wise 	}
336cfdda9d7SSteve Wise }
337cfdda9d7SSteve Wise 
338cfdda9d7SSteve Wise /*
339cfdda9d7SSteve Wise  * Try and reuse skbs already allocated...
340cfdda9d7SSteve Wise  */
341cfdda9d7SSteve Wise static struct sk_buff *get_skb(struct sk_buff *skb, int len, gfp_t gfp)
342cfdda9d7SSteve Wise {
343cfdda9d7SSteve Wise 	if (skb && !skb_is_nonlinear(skb) && !skb_cloned(skb)) {
344cfdda9d7SSteve Wise 		skb_trim(skb, 0);
345cfdda9d7SSteve Wise 		skb_get(skb);
346cfdda9d7SSteve Wise 		skb_reset_transport_header(skb);
347cfdda9d7SSteve Wise 	} else {
348cfdda9d7SSteve Wise 		skb = alloc_skb(len, gfp);
349cfdda9d7SSteve Wise 	}
350b38a0ad8SSteve Wise 	t4_set_arp_err_handler(skb, NULL, NULL);
351cfdda9d7SSteve Wise 	return skb;
352cfdda9d7SSteve Wise }
353cfdda9d7SSteve Wise 
354830662f6SVipul Pandya static struct net_device *get_real_dev(struct net_device *egress_dev)
355830662f6SVipul Pandya {
35611b8e22dSSteve Wise 	return rdma_vlan_dev_real_dev(egress_dev) ? : egress_dev;
357830662f6SVipul Pandya }
358830662f6SVipul Pandya 
359830662f6SVipul Pandya static int our_interface(struct c4iw_dev *dev, struct net_device *egress_dev)
360830662f6SVipul Pandya {
361830662f6SVipul Pandya 	int i;
362830662f6SVipul Pandya 
363830662f6SVipul Pandya 	egress_dev = get_real_dev(egress_dev);
364830662f6SVipul Pandya 	for (i = 0; i < dev->rdev.lldi.nports; i++)
365830662f6SVipul Pandya 		if (dev->rdev.lldi.ports[i] == egress_dev)
366830662f6SVipul Pandya 			return 1;
367830662f6SVipul Pandya 	return 0;
368830662f6SVipul Pandya }
369830662f6SVipul Pandya 
370830662f6SVipul Pandya static struct dst_entry *find_route6(struct c4iw_dev *dev, __u8 *local_ip,
371830662f6SVipul Pandya 				     __u8 *peer_ip, __be16 local_port,
372830662f6SVipul Pandya 				     __be16 peer_port, u8 tos,
373830662f6SVipul Pandya 				     __u32 sin6_scope_id)
374830662f6SVipul Pandya {
375830662f6SVipul Pandya 	struct dst_entry *dst = NULL;
376830662f6SVipul Pandya 
377830662f6SVipul Pandya 	if (IS_ENABLED(CONFIG_IPV6)) {
378830662f6SVipul Pandya 		struct flowi6 fl6;
379830662f6SVipul Pandya 
380830662f6SVipul Pandya 		memset(&fl6, 0, sizeof(fl6));
381830662f6SVipul Pandya 		memcpy(&fl6.daddr, peer_ip, 16);
382830662f6SVipul Pandya 		memcpy(&fl6.saddr, local_ip, 16);
383830662f6SVipul Pandya 		if (ipv6_addr_type(&fl6.daddr) & IPV6_ADDR_LINKLOCAL)
384830662f6SVipul Pandya 			fl6.flowi6_oif = sin6_scope_id;
385830662f6SVipul Pandya 		dst = ip6_route_output(&init_net, NULL, &fl6);
386830662f6SVipul Pandya 		if (!dst)
387830662f6SVipul Pandya 			goto out;
388830662f6SVipul Pandya 		if (!our_interface(dev, ip6_dst_idev(dst)->dev) &&
389830662f6SVipul Pandya 		    !(ip6_dst_idev(dst)->dev->flags & IFF_LOOPBACK)) {
390830662f6SVipul Pandya 			dst_release(dst);
391830662f6SVipul Pandya 			dst = NULL;
392830662f6SVipul Pandya 		}
393830662f6SVipul Pandya 	}
394830662f6SVipul Pandya 
395830662f6SVipul Pandya out:
396830662f6SVipul Pandya 	return dst;
397830662f6SVipul Pandya }
398830662f6SVipul Pandya 
399830662f6SVipul Pandya static struct dst_entry *find_route(struct c4iw_dev *dev, __be32 local_ip,
400cfdda9d7SSteve Wise 				 __be32 peer_ip, __be16 local_port,
401cfdda9d7SSteve Wise 				 __be16 peer_port, u8 tos)
402cfdda9d7SSteve Wise {
403cfdda9d7SSteve Wise 	struct rtable *rt;
40431e4543dSDavid S. Miller 	struct flowi4 fl4;
405830662f6SVipul Pandya 	struct neighbour *n;
406cfdda9d7SSteve Wise 
40731e4543dSDavid S. Miller 	rt = ip_route_output_ports(&init_net, &fl4, NULL, peer_ip, local_ip,
40878fbfd8aSDavid S. Miller 				   peer_port, local_port, IPPROTO_TCP,
40978fbfd8aSDavid S. Miller 				   tos, 0);
410b23dd4feSDavid S. Miller 	if (IS_ERR(rt))
411cfdda9d7SSteve Wise 		return NULL;
412830662f6SVipul Pandya 	n = dst_neigh_lookup(&rt->dst, &peer_ip);
413830662f6SVipul Pandya 	if (!n)
414830662f6SVipul Pandya 		return NULL;
415f8e81908SSteve Wise 	if (!our_interface(dev, n->dev) &&
416f8e81908SSteve Wise 	    !(n->dev->flags & IFF_LOOPBACK)) {
417830662f6SVipul Pandya 		dst_release(&rt->dst);
418830662f6SVipul Pandya 		return NULL;
419830662f6SVipul Pandya 	}
420830662f6SVipul Pandya 	neigh_release(n);
421830662f6SVipul Pandya 	return &rt->dst;
422cfdda9d7SSteve Wise }
423cfdda9d7SSteve Wise 
424cfdda9d7SSteve Wise static void arp_failure_discard(void *handle, struct sk_buff *skb)
425cfdda9d7SSteve Wise {
426cfdda9d7SSteve Wise 	PDBG("%s c4iw_dev %p\n", __func__, handle);
427cfdda9d7SSteve Wise 	kfree_skb(skb);
428cfdda9d7SSteve Wise }
429cfdda9d7SSteve Wise 
430cfdda9d7SSteve Wise /*
431cfdda9d7SSteve Wise  * Handle an ARP failure for an active open.
432cfdda9d7SSteve Wise  */
433cfdda9d7SSteve Wise static void act_open_req_arp_failure(void *handle, struct sk_buff *skb)
434cfdda9d7SSteve Wise {
4355dab6d3aSHariprasad S 	struct c4iw_ep *ep = handle;
4365dab6d3aSHariprasad S 
437cfdda9d7SSteve Wise 	printk(KERN_ERR MOD "ARP failure duing connect\n");
438cfdda9d7SSteve Wise 	kfree_skb(skb);
4395dab6d3aSHariprasad S 	connect_reply_upcall(ep, -EHOSTUNREACH);
4405dab6d3aSHariprasad S 	state_set(&ep->com, DEAD);
4415dab6d3aSHariprasad S 	remove_handle(ep->com.dev, &ep->com.dev->atid_idr, ep->atid);
4425dab6d3aSHariprasad S 	cxgb4_free_atid(ep->com.dev->rdev.lldi.tids, ep->atid);
4435dab6d3aSHariprasad S 	dst_release(ep->dst);
4445dab6d3aSHariprasad S 	cxgb4_l2t_release(ep->l2t);
4455dab6d3aSHariprasad S 	c4iw_put_ep(&ep->com);
446cfdda9d7SSteve Wise }
447cfdda9d7SSteve Wise 
448cfdda9d7SSteve Wise /*
449cfdda9d7SSteve Wise  * Handle an ARP failure for a CPL_ABORT_REQ.  Change it into a no RST variant
450cfdda9d7SSteve Wise  * and send it along.
451cfdda9d7SSteve Wise  */
452cfdda9d7SSteve Wise static void abort_arp_failure(void *handle, struct sk_buff *skb)
453cfdda9d7SSteve Wise {
454cfdda9d7SSteve Wise 	struct c4iw_rdev *rdev = handle;
455cfdda9d7SSteve Wise 	struct cpl_abort_req *req = cplhdr(skb);
456cfdda9d7SSteve Wise 
457cfdda9d7SSteve Wise 	PDBG("%s rdev %p\n", __func__, rdev);
458cfdda9d7SSteve Wise 	req->cmd = CPL_ABORT_NO_RST;
459cfdda9d7SSteve Wise 	c4iw_ofld_send(rdev, skb);
460cfdda9d7SSteve Wise }
461cfdda9d7SSteve Wise 
462cfdda9d7SSteve Wise static void send_flowc(struct c4iw_ep *ep, struct sk_buff *skb)
463cfdda9d7SSteve Wise {
464cfdda9d7SSteve Wise 	unsigned int flowclen = 80;
465cfdda9d7SSteve Wise 	struct fw_flowc_wr *flowc;
466cfdda9d7SSteve Wise 	int i;
467cfdda9d7SSteve Wise 
468cfdda9d7SSteve Wise 	skb = get_skb(skb, flowclen, GFP_KERNEL);
469cfdda9d7SSteve Wise 	flowc = (struct fw_flowc_wr *)__skb_put(skb, flowclen);
470cfdda9d7SSteve Wise 
471cfdda9d7SSteve Wise 	flowc->op_to_nparams = cpu_to_be32(FW_WR_OP(FW_FLOWC_WR) |
472cfdda9d7SSteve Wise 					   FW_FLOWC_WR_NPARAMS(8));
473cfdda9d7SSteve Wise 	flowc->flowid_len16 = cpu_to_be32(FW_WR_LEN16(DIV_ROUND_UP(flowclen,
474cfdda9d7SSteve Wise 					  16)) | FW_WR_FLOWID(ep->hwtid));
475cfdda9d7SSteve Wise 
476cfdda9d7SSteve Wise 	flowc->mnemval[0].mnemonic = FW_FLOWC_MNEM_PFNVFN;
47794788657SSteve Wise 	flowc->mnemval[0].val = cpu_to_be32(PCI_FUNC(ep->com.dev->rdev.lldi.pdev->devfn) << 8);
478cfdda9d7SSteve Wise 	flowc->mnemval[1].mnemonic = FW_FLOWC_MNEM_CH;
479cfdda9d7SSteve Wise 	flowc->mnemval[1].val = cpu_to_be32(ep->tx_chan);
480cfdda9d7SSteve Wise 	flowc->mnemval[2].mnemonic = FW_FLOWC_MNEM_PORT;
481cfdda9d7SSteve Wise 	flowc->mnemval[2].val = cpu_to_be32(ep->tx_chan);
482cfdda9d7SSteve Wise 	flowc->mnemval[3].mnemonic = FW_FLOWC_MNEM_IQID;
483cfdda9d7SSteve Wise 	flowc->mnemval[3].val = cpu_to_be32(ep->rss_qid);
484cfdda9d7SSteve Wise 	flowc->mnemval[4].mnemonic = FW_FLOWC_MNEM_SNDNXT;
485cfdda9d7SSteve Wise 	flowc->mnemval[4].val = cpu_to_be32(ep->snd_seq);
486cfdda9d7SSteve Wise 	flowc->mnemval[5].mnemonic = FW_FLOWC_MNEM_RCVNXT;
487cfdda9d7SSteve Wise 	flowc->mnemval[5].val = cpu_to_be32(ep->rcv_seq);
488cfdda9d7SSteve Wise 	flowc->mnemval[6].mnemonic = FW_FLOWC_MNEM_SNDBUF;
489b408ff28SHariprasad Shenai 	flowc->mnemval[6].val = cpu_to_be32(ep->snd_win);
490cfdda9d7SSteve Wise 	flowc->mnemval[7].mnemonic = FW_FLOWC_MNEM_MSS;
491cfdda9d7SSteve Wise 	flowc->mnemval[7].val = cpu_to_be32(ep->emss);
492cfdda9d7SSteve Wise 	/* Pad WR to 16 byte boundary */
493cfdda9d7SSteve Wise 	flowc->mnemval[8].mnemonic = 0;
494cfdda9d7SSteve Wise 	flowc->mnemval[8].val = 0;
495cfdda9d7SSteve Wise 	for (i = 0; i < 9; i++) {
496cfdda9d7SSteve Wise 		flowc->mnemval[i].r4[0] = 0;
497cfdda9d7SSteve Wise 		flowc->mnemval[i].r4[1] = 0;
498cfdda9d7SSteve Wise 		flowc->mnemval[i].r4[2] = 0;
499cfdda9d7SSteve Wise 	}
500cfdda9d7SSteve Wise 
501cfdda9d7SSteve Wise 	set_wr_txq(skb, CPL_PRIORITY_DATA, ep->txq_idx);
502cfdda9d7SSteve Wise 	c4iw_ofld_send(&ep->com.dev->rdev, skb);
503cfdda9d7SSteve Wise }
504cfdda9d7SSteve Wise 
505cfdda9d7SSteve Wise static int send_halfclose(struct c4iw_ep *ep, gfp_t gfp)
506cfdda9d7SSteve Wise {
507cfdda9d7SSteve Wise 	struct cpl_close_con_req *req;
508cfdda9d7SSteve Wise 	struct sk_buff *skb;
509cfdda9d7SSteve Wise 	int wrlen = roundup(sizeof *req, 16);
510cfdda9d7SSteve Wise 
511cfdda9d7SSteve Wise 	PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
512cfdda9d7SSteve Wise 	skb = get_skb(NULL, wrlen, gfp);
513cfdda9d7SSteve Wise 	if (!skb) {
514cfdda9d7SSteve Wise 		printk(KERN_ERR MOD "%s - failed to alloc skb\n", __func__);
515cfdda9d7SSteve Wise 		return -ENOMEM;
516cfdda9d7SSteve Wise 	}
517cfdda9d7SSteve Wise 	set_wr_txq(skb, CPL_PRIORITY_DATA, ep->txq_idx);
518cfdda9d7SSteve Wise 	t4_set_arp_err_handler(skb, NULL, arp_failure_discard);
519cfdda9d7SSteve Wise 	req = (struct cpl_close_con_req *) skb_put(skb, wrlen);
520cfdda9d7SSteve Wise 	memset(req, 0, wrlen);
521cfdda9d7SSteve Wise 	INIT_TP_WR(req, ep->hwtid);
522cfdda9d7SSteve Wise 	OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_CLOSE_CON_REQ,
523cfdda9d7SSteve Wise 						    ep->hwtid));
524cfdda9d7SSteve Wise 	return c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t);
525cfdda9d7SSteve Wise }
526cfdda9d7SSteve Wise 
527cfdda9d7SSteve Wise static int send_abort(struct c4iw_ep *ep, struct sk_buff *skb, gfp_t gfp)
528cfdda9d7SSteve Wise {
529cfdda9d7SSteve Wise 	struct cpl_abort_req *req;
530cfdda9d7SSteve Wise 	int wrlen = roundup(sizeof *req, 16);
531cfdda9d7SSteve Wise 
532cfdda9d7SSteve Wise 	PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
533cfdda9d7SSteve Wise 	skb = get_skb(skb, wrlen, gfp);
534cfdda9d7SSteve Wise 	if (!skb) {
535cfdda9d7SSteve Wise 		printk(KERN_ERR MOD "%s - failed to alloc skb.\n",
536cfdda9d7SSteve Wise 		       __func__);
537cfdda9d7SSteve Wise 		return -ENOMEM;
538cfdda9d7SSteve Wise 	}
539cfdda9d7SSteve Wise 	set_wr_txq(skb, CPL_PRIORITY_DATA, ep->txq_idx);
540cfdda9d7SSteve Wise 	t4_set_arp_err_handler(skb, &ep->com.dev->rdev, abort_arp_failure);
541cfdda9d7SSteve Wise 	req = (struct cpl_abort_req *) skb_put(skb, wrlen);
542cfdda9d7SSteve Wise 	memset(req, 0, wrlen);
543cfdda9d7SSteve Wise 	INIT_TP_WR(req, ep->hwtid);
544cfdda9d7SSteve Wise 	OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_ABORT_REQ, ep->hwtid));
545cfdda9d7SSteve Wise 	req->cmd = CPL_ABORT_SEND_RST;
546cfdda9d7SSteve Wise 	return c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t);
547cfdda9d7SSteve Wise }
548cfdda9d7SSteve Wise 
5499eccfe10SSteve Wise /*
5509eccfe10SSteve Wise  * c4iw_form_pm_msg - Form a port mapper message with mapping info
5519eccfe10SSteve Wise  */
5529eccfe10SSteve Wise static void c4iw_form_pm_msg(struct c4iw_ep *ep,
5539eccfe10SSteve Wise 				struct iwpm_sa_data *pm_msg)
5549eccfe10SSteve Wise {
5559eccfe10SSteve Wise 	memcpy(&pm_msg->loc_addr, &ep->com.local_addr,
5569eccfe10SSteve Wise 		sizeof(ep->com.local_addr));
5579eccfe10SSteve Wise 	memcpy(&pm_msg->rem_addr, &ep->com.remote_addr,
5589eccfe10SSteve Wise 		sizeof(ep->com.remote_addr));
5599eccfe10SSteve Wise }
5609eccfe10SSteve Wise 
5619eccfe10SSteve Wise /*
5629eccfe10SSteve Wise  * c4iw_form_reg_msg - Form a port mapper message with dev info
5639eccfe10SSteve Wise  */
5649eccfe10SSteve Wise static void c4iw_form_reg_msg(struct c4iw_dev *dev,
5659eccfe10SSteve Wise 				struct iwpm_dev_data *pm_msg)
5669eccfe10SSteve Wise {
5679eccfe10SSteve Wise 	memcpy(pm_msg->dev_name, dev->ibdev.name, IWPM_DEVNAME_SIZE);
5689eccfe10SSteve Wise 	memcpy(pm_msg->if_name, dev->rdev.lldi.ports[0]->name,
5699eccfe10SSteve Wise 				IWPM_IFNAME_SIZE);
5709eccfe10SSteve Wise }
5719eccfe10SSteve Wise 
5729eccfe10SSteve Wise static void c4iw_record_pm_msg(struct c4iw_ep *ep,
5739eccfe10SSteve Wise 			struct iwpm_sa_data *pm_msg)
5749eccfe10SSteve Wise {
5759eccfe10SSteve Wise 	memcpy(&ep->com.mapped_local_addr, &pm_msg->mapped_loc_addr,
5769eccfe10SSteve Wise 		sizeof(ep->com.mapped_local_addr));
5779eccfe10SSteve Wise 	memcpy(&ep->com.mapped_remote_addr, &pm_msg->mapped_rem_addr,
5789eccfe10SSteve Wise 		sizeof(ep->com.mapped_remote_addr));
5799eccfe10SSteve Wise }
5809eccfe10SSteve Wise 
58192e7ae71SHariprasad Shenai static void best_mtu(const unsigned short *mtus, unsigned short mtu,
58292e7ae71SHariprasad Shenai 		     unsigned int *idx, int use_ts)
58392e7ae71SHariprasad Shenai {
58492e7ae71SHariprasad Shenai 	unsigned short hdr_size = sizeof(struct iphdr) +
58592e7ae71SHariprasad Shenai 				  sizeof(struct tcphdr) +
58692e7ae71SHariprasad Shenai 				  (use_ts ? 12 : 0);
58792e7ae71SHariprasad Shenai 	unsigned short data_size = mtu - hdr_size;
58892e7ae71SHariprasad Shenai 
58992e7ae71SHariprasad Shenai 	cxgb4_best_aligned_mtu(mtus, hdr_size, data_size, 8, idx);
59092e7ae71SHariprasad Shenai }
59192e7ae71SHariprasad Shenai 
592cfdda9d7SSteve Wise static int send_connect(struct c4iw_ep *ep)
593cfdda9d7SSteve Wise {
594cfdda9d7SSteve Wise 	struct cpl_act_open_req *req;
595f079af7aSVipul Pandya 	struct cpl_t5_act_open_req *t5_req;
596830662f6SVipul Pandya 	struct cpl_act_open_req6 *req6;
597830662f6SVipul Pandya 	struct cpl_t5_act_open_req6 *t5_req6;
598cfdda9d7SSteve Wise 	struct sk_buff *skb;
599cfdda9d7SSteve Wise 	u64 opt0;
600cfdda9d7SSteve Wise 	u32 opt2;
601cfdda9d7SSteve Wise 	unsigned int mtu_idx;
602cfdda9d7SSteve Wise 	int wscale;
603830662f6SVipul Pandya 	int wrlen;
604830662f6SVipul Pandya 	int sizev4 = is_t4(ep->com.dev->rdev.lldi.adapter_type) ?
605f079af7aSVipul Pandya 				sizeof(struct cpl_act_open_req) :
606f079af7aSVipul Pandya 				sizeof(struct cpl_t5_act_open_req);
607830662f6SVipul Pandya 	int sizev6 = is_t4(ep->com.dev->rdev.lldi.adapter_type) ?
608830662f6SVipul Pandya 				sizeof(struct cpl_act_open_req6) :
609830662f6SVipul Pandya 				sizeof(struct cpl_t5_act_open_req6);
6109eccfe10SSteve Wise 	struct sockaddr_in *la = (struct sockaddr_in *)
6119eccfe10SSteve Wise 				 &ep->com.mapped_local_addr;
6129eccfe10SSteve Wise 	struct sockaddr_in *ra = (struct sockaddr_in *)
6139eccfe10SSteve Wise 				 &ep->com.mapped_remote_addr;
6149eccfe10SSteve Wise 	struct sockaddr_in6 *la6 = (struct sockaddr_in6 *)
6159eccfe10SSteve Wise 				   &ep->com.mapped_local_addr;
6169eccfe10SSteve Wise 	struct sockaddr_in6 *ra6 = (struct sockaddr_in6 *)
6179eccfe10SSteve Wise 				   &ep->com.mapped_remote_addr;
618b408ff28SHariprasad Shenai 	int win;
619830662f6SVipul Pandya 
620830662f6SVipul Pandya 	wrlen = (ep->com.remote_addr.ss_family == AF_INET) ?
621830662f6SVipul Pandya 			roundup(sizev4, 16) :
622830662f6SVipul Pandya 			roundup(sizev6, 16);
623cfdda9d7SSteve Wise 
624cfdda9d7SSteve Wise 	PDBG("%s ep %p atid %u\n", __func__, ep, ep->atid);
625cfdda9d7SSteve Wise 
626cfdda9d7SSteve Wise 	skb = get_skb(NULL, wrlen, GFP_KERNEL);
627cfdda9d7SSteve Wise 	if (!skb) {
628cfdda9d7SSteve Wise 		printk(KERN_ERR MOD "%s - failed to alloc skb.\n",
629cfdda9d7SSteve Wise 		       __func__);
630cfdda9d7SSteve Wise 		return -ENOMEM;
631cfdda9d7SSteve Wise 	}
632d4f1a5c6SSteve Wise 	set_wr_txq(skb, CPL_PRIORITY_SETUP, ep->ctrlq_idx);
633cfdda9d7SSteve Wise 
63492e7ae71SHariprasad Shenai 	best_mtu(ep->com.dev->rdev.lldi.mtus, ep->mtu, &mtu_idx,
63592e7ae71SHariprasad Shenai 		 enable_tcp_timestamps);
636cfdda9d7SSteve Wise 	wscale = compute_wscale(rcv_win);
637b408ff28SHariprasad Shenai 
638b408ff28SHariprasad Shenai 	/*
639b408ff28SHariprasad Shenai 	 * Specify the largest window that will fit in opt0. The
640b408ff28SHariprasad Shenai 	 * remainder will be specified in the rx_data_ack.
641b408ff28SHariprasad Shenai 	 */
642b408ff28SHariprasad Shenai 	win = ep->rcv_win >> 10;
643b408ff28SHariprasad Shenai 	if (win > RCV_BUFSIZ_MASK)
644b408ff28SHariprasad Shenai 		win = RCV_BUFSIZ_MASK;
645b408ff28SHariprasad Shenai 
6465be78ee9SVipul Pandya 	opt0 = (nocong ? NO_CONG(1) : 0) |
6475be78ee9SVipul Pandya 	       KEEP_ALIVE(1) |
648ba6d3925SSteve Wise 	       DELACK(1) |
649cfdda9d7SSteve Wise 	       WND_SCALE(wscale) |
650cfdda9d7SSteve Wise 	       MSS_IDX(mtu_idx) |
651cfdda9d7SSteve Wise 	       L2T_IDX(ep->l2t->idx) |
652cfdda9d7SSteve Wise 	       TX_CHAN(ep->tx_chan) |
653cfdda9d7SSteve Wise 	       SMAC_SEL(ep->smac_idx) |
654cfdda9d7SSteve Wise 	       DSCP(ep->tos) |
655b48f3b9cSSteve Wise 	       ULP_MODE(ULP_MODE_TCPDDP) |
656b408ff28SHariprasad Shenai 	       RCV_BUFSIZ(win);
657cfdda9d7SSteve Wise 	opt2 = RX_CHANNEL(0) |
6585be78ee9SVipul Pandya 	       CCTRL_ECN(enable_ecn) |
659cfdda9d7SSteve Wise 	       RSS_QUEUE_VALID | RSS_QUEUE(ep->rss_qid);
660cfdda9d7SSteve Wise 	if (enable_tcp_timestamps)
661cfdda9d7SSteve Wise 		opt2 |= TSTAMPS_EN(1);
662cfdda9d7SSteve Wise 	if (enable_tcp_sack)
663cfdda9d7SSteve Wise 		opt2 |= SACK_EN(1);
664cfdda9d7SSteve Wise 	if (wscale && enable_tcp_window_scaling)
665cfdda9d7SSteve Wise 		opt2 |= WND_SCALE_EN(1);
66692e5011aSSteve Wise 	if (is_t5(ep->com.dev->rdev.lldi.adapter_type)) {
66792e5011aSSteve Wise 		opt2 |= T5_OPT_2_VALID;
66892e5011aSSteve Wise 		opt2 |= V_CONG_CNTRL(CONG_ALG_TAHOE);
66992e5011aSSteve Wise 	}
6705dab6d3aSHariprasad S 	t4_set_arp_err_handler(skb, ep, act_open_req_arp_failure);
671cfdda9d7SSteve Wise 
672f079af7aSVipul Pandya 	if (is_t4(ep->com.dev->rdev.lldi.adapter_type)) {
673830662f6SVipul Pandya 		if (ep->com.remote_addr.ss_family == AF_INET) {
674cfdda9d7SSteve Wise 			req = (struct cpl_act_open_req *) skb_put(skb, wrlen);
675cfdda9d7SSteve Wise 			INIT_TP_WR(req, 0);
676cfdda9d7SSteve Wise 			OPCODE_TID(req) = cpu_to_be32(
677f079af7aSVipul Pandya 					MK_OPCODE_TID(CPL_ACT_OPEN_REQ,
678f079af7aSVipul Pandya 					((ep->rss_qid << 14) | ep->atid)));
679830662f6SVipul Pandya 			req->local_port = la->sin_port;
680830662f6SVipul Pandya 			req->peer_port = ra->sin_port;
681830662f6SVipul Pandya 			req->local_ip = la->sin_addr.s_addr;
682830662f6SVipul Pandya 			req->peer_ip = ra->sin_addr.s_addr;
683cfdda9d7SSteve Wise 			req->opt0 = cpu_to_be64(opt0);
68441b4f86cSKumar Sanghvi 			req->params = cpu_to_be32(cxgb4_select_ntuple(
68541b4f86cSKumar Sanghvi 						ep->com.dev->rdev.lldi.ports[0],
68641b4f86cSKumar Sanghvi 						ep->l2t));
687cfdda9d7SSteve Wise 			req->opt2 = cpu_to_be32(opt2);
688f079af7aSVipul Pandya 		} else {
689830662f6SVipul Pandya 			req6 = (struct cpl_act_open_req6 *)skb_put(skb, wrlen);
690830662f6SVipul Pandya 
691830662f6SVipul Pandya 			INIT_TP_WR(req6, 0);
692830662f6SVipul Pandya 			OPCODE_TID(req6) = cpu_to_be32(
693830662f6SVipul Pandya 					   MK_OPCODE_TID(CPL_ACT_OPEN_REQ6,
694830662f6SVipul Pandya 					   ((ep->rss_qid<<14)|ep->atid)));
695830662f6SVipul Pandya 			req6->local_port = la6->sin6_port;
696830662f6SVipul Pandya 			req6->peer_port = ra6->sin6_port;
697830662f6SVipul Pandya 			req6->local_ip_hi = *((__be64 *)
698830662f6SVipul Pandya 						(la6->sin6_addr.s6_addr));
699830662f6SVipul Pandya 			req6->local_ip_lo = *((__be64 *)
700830662f6SVipul Pandya 						(la6->sin6_addr.s6_addr + 8));
701830662f6SVipul Pandya 			req6->peer_ip_hi = *((__be64 *)
702830662f6SVipul Pandya 						(ra6->sin6_addr.s6_addr));
703830662f6SVipul Pandya 			req6->peer_ip_lo = *((__be64 *)
704830662f6SVipul Pandya 						(ra6->sin6_addr.s6_addr + 8));
705830662f6SVipul Pandya 			req6->opt0 = cpu_to_be64(opt0);
70641b4f86cSKumar Sanghvi 			req6->params = cpu_to_be32(cxgb4_select_ntuple(
70741b4f86cSKumar Sanghvi 						ep->com.dev->rdev.lldi.ports[0],
708830662f6SVipul Pandya 						ep->l2t));
709830662f6SVipul Pandya 			req6->opt2 = cpu_to_be32(opt2);
710830662f6SVipul Pandya 		}
711830662f6SVipul Pandya 	} else {
71292e7ae71SHariprasad Shenai 		u32 isn = (prandom_u32() & ~7UL) - 1;
71392e7ae71SHariprasad Shenai 
71492e7ae71SHariprasad Shenai 		opt2 |= T5_OPT_2_VALID;
71592e7ae71SHariprasad Shenai 		opt2 |= CONG_CNTRL_VALID; /* OPT_2_ISS for T5 */
71692e7ae71SHariprasad Shenai 		if (peer2peer)
71792e7ae71SHariprasad Shenai 			isn += 4;
71892e7ae71SHariprasad Shenai 
719830662f6SVipul Pandya 		if (ep->com.remote_addr.ss_family == AF_INET) {
720830662f6SVipul Pandya 			t5_req = (struct cpl_t5_act_open_req *)
721830662f6SVipul Pandya 				 skb_put(skb, wrlen);
722f079af7aSVipul Pandya 			INIT_TP_WR(t5_req, 0);
723f079af7aSVipul Pandya 			OPCODE_TID(t5_req) = cpu_to_be32(
724f079af7aSVipul Pandya 					MK_OPCODE_TID(CPL_ACT_OPEN_REQ,
725f079af7aSVipul Pandya 					((ep->rss_qid << 14) | ep->atid)));
726830662f6SVipul Pandya 			t5_req->local_port = la->sin_port;
727830662f6SVipul Pandya 			t5_req->peer_port = ra->sin_port;
728830662f6SVipul Pandya 			t5_req->local_ip = la->sin_addr.s_addr;
729830662f6SVipul Pandya 			t5_req->peer_ip = ra->sin_addr.s_addr;
730f079af7aSVipul Pandya 			t5_req->opt0 = cpu_to_be64(opt0);
731f079af7aSVipul Pandya 			t5_req->params = cpu_to_be64(V_FILTER_TUPLE(
73241b4f86cSKumar Sanghvi 						     cxgb4_select_ntuple(
73341b4f86cSKumar Sanghvi 					     ep->com.dev->rdev.lldi.ports[0],
73441b4f86cSKumar Sanghvi 					     ep->l2t)));
73592e7ae71SHariprasad Shenai 			t5_req->rsvd = cpu_to_be32(isn);
73692e7ae71SHariprasad Shenai 			PDBG("%s snd_isn %u\n", __func__,
73792e7ae71SHariprasad Shenai 			     be32_to_cpu(t5_req->rsvd));
738f079af7aSVipul Pandya 			t5_req->opt2 = cpu_to_be32(opt2);
739830662f6SVipul Pandya 		} else {
740830662f6SVipul Pandya 			t5_req6 = (struct cpl_t5_act_open_req6 *)
741830662f6SVipul Pandya 				  skb_put(skb, wrlen);
742830662f6SVipul Pandya 			INIT_TP_WR(t5_req6, 0);
743830662f6SVipul Pandya 			OPCODE_TID(t5_req6) = cpu_to_be32(
744830662f6SVipul Pandya 					      MK_OPCODE_TID(CPL_ACT_OPEN_REQ6,
745830662f6SVipul Pandya 					      ((ep->rss_qid<<14)|ep->atid)));
746830662f6SVipul Pandya 			t5_req6->local_port = la6->sin6_port;
747830662f6SVipul Pandya 			t5_req6->peer_port = ra6->sin6_port;
748830662f6SVipul Pandya 			t5_req6->local_ip_hi = *((__be64 *)
749830662f6SVipul Pandya 						(la6->sin6_addr.s6_addr));
750830662f6SVipul Pandya 			t5_req6->local_ip_lo = *((__be64 *)
751830662f6SVipul Pandya 						(la6->sin6_addr.s6_addr + 8));
752830662f6SVipul Pandya 			t5_req6->peer_ip_hi = *((__be64 *)
753830662f6SVipul Pandya 						(ra6->sin6_addr.s6_addr));
754830662f6SVipul Pandya 			t5_req6->peer_ip_lo = *((__be64 *)
755830662f6SVipul Pandya 						(ra6->sin6_addr.s6_addr + 8));
756830662f6SVipul Pandya 			t5_req6->opt0 = cpu_to_be64(opt0);
757830662f6SVipul Pandya 			t5_req6->params = (__force __be64)cpu_to_be32(
75841b4f86cSKumar Sanghvi 							cxgb4_select_ntuple(
75941b4f86cSKumar Sanghvi 						ep->com.dev->rdev.lldi.ports[0],
76041b4f86cSKumar Sanghvi 						ep->l2t));
76192e7ae71SHariprasad Shenai 			t5_req6->rsvd = cpu_to_be32(isn);
76292e7ae71SHariprasad Shenai 			PDBG("%s snd_isn %u\n", __func__,
76392e7ae71SHariprasad Shenai 			     be32_to_cpu(t5_req6->rsvd));
764830662f6SVipul Pandya 			t5_req6->opt2 = cpu_to_be32(opt2);
765830662f6SVipul Pandya 		}
766f079af7aSVipul Pandya 	}
767f079af7aSVipul Pandya 
768793dad94SVipul Pandya 	set_bit(ACT_OPEN_REQ, &ep->com.history);
769cfdda9d7SSteve Wise 	return c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t);
770cfdda9d7SSteve Wise }
771cfdda9d7SSteve Wise 
772d2fe99e8SKumar Sanghvi static void send_mpa_req(struct c4iw_ep *ep, struct sk_buff *skb,
773d2fe99e8SKumar Sanghvi 		u8 mpa_rev_to_use)
774cfdda9d7SSteve Wise {
775cfdda9d7SSteve Wise 	int mpalen, wrlen;
776cfdda9d7SSteve Wise 	struct fw_ofld_tx_data_wr *req;
777cfdda9d7SSteve Wise 	struct mpa_message *mpa;
778d2fe99e8SKumar Sanghvi 	struct mpa_v2_conn_params mpa_v2_params;
779cfdda9d7SSteve Wise 
780cfdda9d7SSteve Wise 	PDBG("%s ep %p tid %u pd_len %d\n", __func__, ep, ep->hwtid, ep->plen);
781cfdda9d7SSteve Wise 
782cfdda9d7SSteve Wise 	BUG_ON(skb_cloned(skb));
783cfdda9d7SSteve Wise 
784cfdda9d7SSteve Wise 	mpalen = sizeof(*mpa) + ep->plen;
785d2fe99e8SKumar Sanghvi 	if (mpa_rev_to_use == 2)
786d2fe99e8SKumar Sanghvi 		mpalen += sizeof(struct mpa_v2_conn_params);
787cfdda9d7SSteve Wise 	wrlen = roundup(mpalen + sizeof *req, 16);
788cfdda9d7SSteve Wise 	skb = get_skb(skb, wrlen, GFP_KERNEL);
789cfdda9d7SSteve Wise 	if (!skb) {
790cfdda9d7SSteve Wise 		connect_reply_upcall(ep, -ENOMEM);
791cfdda9d7SSteve Wise 		return;
792cfdda9d7SSteve Wise 	}
793cfdda9d7SSteve Wise 	set_wr_txq(skb, CPL_PRIORITY_DATA, ep->txq_idx);
794cfdda9d7SSteve Wise 
795cfdda9d7SSteve Wise 	req = (struct fw_ofld_tx_data_wr *)skb_put(skb, wrlen);
796cfdda9d7SSteve Wise 	memset(req, 0, wrlen);
797cfdda9d7SSteve Wise 	req->op_to_immdlen = cpu_to_be32(
798cfdda9d7SSteve Wise 		FW_WR_OP(FW_OFLD_TX_DATA_WR) |
799cfdda9d7SSteve Wise 		FW_WR_COMPL(1) |
800cfdda9d7SSteve Wise 		FW_WR_IMMDLEN(mpalen));
801cfdda9d7SSteve Wise 	req->flowid_len16 = cpu_to_be32(
802cfdda9d7SSteve Wise 		FW_WR_FLOWID(ep->hwtid) |
803cfdda9d7SSteve Wise 		FW_WR_LEN16(wrlen >> 4));
804cfdda9d7SSteve Wise 	req->plen = cpu_to_be32(mpalen);
805cfdda9d7SSteve Wise 	req->tunnel_to_proxy = cpu_to_be32(
806cfdda9d7SSteve Wise 		FW_OFLD_TX_DATA_WR_FLUSH(1) |
807cfdda9d7SSteve Wise 		FW_OFLD_TX_DATA_WR_SHOVE(1));
808cfdda9d7SSteve Wise 
809cfdda9d7SSteve Wise 	mpa = (struct mpa_message *)(req + 1);
810cfdda9d7SSteve Wise 	memcpy(mpa->key, MPA_KEY_REQ, sizeof(mpa->key));
811cfdda9d7SSteve Wise 	mpa->flags = (crc_enabled ? MPA_CRC : 0) |
812d2fe99e8SKumar Sanghvi 		     (markers_enabled ? MPA_MARKERS : 0) |
813d2fe99e8SKumar Sanghvi 		     (mpa_rev_to_use == 2 ? MPA_ENHANCED_RDMA_CONN : 0);
814cfdda9d7SSteve Wise 	mpa->private_data_size = htons(ep->plen);
815d2fe99e8SKumar Sanghvi 	mpa->revision = mpa_rev_to_use;
81601b225e1SKumar Sanghvi 	if (mpa_rev_to_use == 1) {
817d2fe99e8SKumar Sanghvi 		ep->tried_with_mpa_v1 = 1;
81801b225e1SKumar Sanghvi 		ep->retry_with_mpa_v1 = 0;
81901b225e1SKumar Sanghvi 	}
820d2fe99e8SKumar Sanghvi 
821d2fe99e8SKumar Sanghvi 	if (mpa_rev_to_use == 2) {
822f747c34aSRoland Dreier 		mpa->private_data_size = htons(ntohs(mpa->private_data_size) +
823f747c34aSRoland Dreier 					       sizeof (struct mpa_v2_conn_params));
824d2fe99e8SKumar Sanghvi 		mpa_v2_params.ird = htons((u16)ep->ird);
825d2fe99e8SKumar Sanghvi 		mpa_v2_params.ord = htons((u16)ep->ord);
826d2fe99e8SKumar Sanghvi 
827d2fe99e8SKumar Sanghvi 		if (peer2peer) {
828d2fe99e8SKumar Sanghvi 			mpa_v2_params.ird |= htons(MPA_V2_PEER2PEER_MODEL);
829d2fe99e8SKumar Sanghvi 			if (p2p_type == FW_RI_INIT_P2PTYPE_RDMA_WRITE)
830d2fe99e8SKumar Sanghvi 				mpa_v2_params.ord |=
831d2fe99e8SKumar Sanghvi 					htons(MPA_V2_RDMA_WRITE_RTR);
832d2fe99e8SKumar Sanghvi 			else if (p2p_type == FW_RI_INIT_P2PTYPE_READ_REQ)
833d2fe99e8SKumar Sanghvi 				mpa_v2_params.ord |=
834d2fe99e8SKumar Sanghvi 					htons(MPA_V2_RDMA_READ_RTR);
835d2fe99e8SKumar Sanghvi 		}
836d2fe99e8SKumar Sanghvi 		memcpy(mpa->private_data, &mpa_v2_params,
837d2fe99e8SKumar Sanghvi 		       sizeof(struct mpa_v2_conn_params));
838cfdda9d7SSteve Wise 
839cfdda9d7SSteve Wise 		if (ep->plen)
840d2fe99e8SKumar Sanghvi 			memcpy(mpa->private_data +
841d2fe99e8SKumar Sanghvi 			       sizeof(struct mpa_v2_conn_params),
842d2fe99e8SKumar Sanghvi 			       ep->mpa_pkt + sizeof(*mpa), ep->plen);
843d2fe99e8SKumar Sanghvi 	} else
844d2fe99e8SKumar Sanghvi 		if (ep->plen)
845d2fe99e8SKumar Sanghvi 			memcpy(mpa->private_data,
846d2fe99e8SKumar Sanghvi 					ep->mpa_pkt + sizeof(*mpa), ep->plen);
847cfdda9d7SSteve Wise 
848cfdda9d7SSteve Wise 	/*
849cfdda9d7SSteve Wise 	 * Reference the mpa skb.  This ensures the data area
850cfdda9d7SSteve Wise 	 * will remain in memory until the hw acks the tx.
851cfdda9d7SSteve Wise 	 * Function fw4_ack() will deref it.
852cfdda9d7SSteve Wise 	 */
853cfdda9d7SSteve Wise 	skb_get(skb);
854cfdda9d7SSteve Wise 	t4_set_arp_err_handler(skb, NULL, arp_failure_discard);
855cfdda9d7SSteve Wise 	BUG_ON(ep->mpa_skb);
856cfdda9d7SSteve Wise 	ep->mpa_skb = skb;
857cfdda9d7SSteve Wise 	c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t);
858cfdda9d7SSteve Wise 	start_ep_timer(ep);
859a7db89ebSSteve Wise 	__state_set(&ep->com, MPA_REQ_SENT);
860cfdda9d7SSteve Wise 	ep->mpa_attr.initiator = 1;
8619c88aa00SSteve Wise 	ep->snd_seq += mpalen;
862cfdda9d7SSteve Wise 	return;
863cfdda9d7SSteve Wise }
864cfdda9d7SSteve Wise 
865cfdda9d7SSteve Wise static int send_mpa_reject(struct c4iw_ep *ep, const void *pdata, u8 plen)
866cfdda9d7SSteve Wise {
867cfdda9d7SSteve Wise 	int mpalen, wrlen;
868cfdda9d7SSteve Wise 	struct fw_ofld_tx_data_wr *req;
869cfdda9d7SSteve Wise 	struct mpa_message *mpa;
870cfdda9d7SSteve Wise 	struct sk_buff *skb;
871d2fe99e8SKumar Sanghvi 	struct mpa_v2_conn_params mpa_v2_params;
872cfdda9d7SSteve Wise 
873cfdda9d7SSteve Wise 	PDBG("%s ep %p tid %u pd_len %d\n", __func__, ep, ep->hwtid, ep->plen);
874cfdda9d7SSteve Wise 
875cfdda9d7SSteve Wise 	mpalen = sizeof(*mpa) + plen;
876d2fe99e8SKumar Sanghvi 	if (ep->mpa_attr.version == 2 && ep->mpa_attr.enhanced_rdma_conn)
877d2fe99e8SKumar Sanghvi 		mpalen += sizeof(struct mpa_v2_conn_params);
878cfdda9d7SSteve Wise 	wrlen = roundup(mpalen + sizeof *req, 16);
879cfdda9d7SSteve Wise 
880cfdda9d7SSteve Wise 	skb = get_skb(NULL, wrlen, GFP_KERNEL);
881cfdda9d7SSteve Wise 	if (!skb) {
882cfdda9d7SSteve Wise 		printk(KERN_ERR MOD "%s - cannot alloc skb!\n", __func__);
883cfdda9d7SSteve Wise 		return -ENOMEM;
884cfdda9d7SSteve Wise 	}
885cfdda9d7SSteve Wise 	set_wr_txq(skb, CPL_PRIORITY_DATA, ep->txq_idx);
886cfdda9d7SSteve Wise 
887cfdda9d7SSteve Wise 	req = (struct fw_ofld_tx_data_wr *)skb_put(skb, wrlen);
888cfdda9d7SSteve Wise 	memset(req, 0, wrlen);
889cfdda9d7SSteve Wise 	req->op_to_immdlen = cpu_to_be32(
890cfdda9d7SSteve Wise 		FW_WR_OP(FW_OFLD_TX_DATA_WR) |
891cfdda9d7SSteve Wise 		FW_WR_COMPL(1) |
892cfdda9d7SSteve Wise 		FW_WR_IMMDLEN(mpalen));
893cfdda9d7SSteve Wise 	req->flowid_len16 = cpu_to_be32(
894cfdda9d7SSteve Wise 		FW_WR_FLOWID(ep->hwtid) |
895cfdda9d7SSteve Wise 		FW_WR_LEN16(wrlen >> 4));
896cfdda9d7SSteve Wise 	req->plen = cpu_to_be32(mpalen);
897cfdda9d7SSteve Wise 	req->tunnel_to_proxy = cpu_to_be32(
898cfdda9d7SSteve Wise 		FW_OFLD_TX_DATA_WR_FLUSH(1) |
899cfdda9d7SSteve Wise 		FW_OFLD_TX_DATA_WR_SHOVE(1));
900cfdda9d7SSteve Wise 
901cfdda9d7SSteve Wise 	mpa = (struct mpa_message *)(req + 1);
902cfdda9d7SSteve Wise 	memset(mpa, 0, sizeof(*mpa));
903cfdda9d7SSteve Wise 	memcpy(mpa->key, MPA_KEY_REP, sizeof(mpa->key));
904cfdda9d7SSteve Wise 	mpa->flags = MPA_REJECT;
905fe7e0a4dSVipul Pandya 	mpa->revision = ep->mpa_attr.version;
906cfdda9d7SSteve Wise 	mpa->private_data_size = htons(plen);
907d2fe99e8SKumar Sanghvi 
908d2fe99e8SKumar Sanghvi 	if (ep->mpa_attr.version == 2 && ep->mpa_attr.enhanced_rdma_conn) {
909d2fe99e8SKumar Sanghvi 		mpa->flags |= MPA_ENHANCED_RDMA_CONN;
910f747c34aSRoland Dreier 		mpa->private_data_size = htons(ntohs(mpa->private_data_size) +
911f747c34aSRoland Dreier 					       sizeof (struct mpa_v2_conn_params));
912d2fe99e8SKumar Sanghvi 		mpa_v2_params.ird = htons(((u16)ep->ird) |
913d2fe99e8SKumar Sanghvi 					  (peer2peer ? MPA_V2_PEER2PEER_MODEL :
914d2fe99e8SKumar Sanghvi 					   0));
915d2fe99e8SKumar Sanghvi 		mpa_v2_params.ord = htons(((u16)ep->ord) | (peer2peer ?
916d2fe99e8SKumar Sanghvi 					  (p2p_type ==
917d2fe99e8SKumar Sanghvi 					   FW_RI_INIT_P2PTYPE_RDMA_WRITE ?
918d2fe99e8SKumar Sanghvi 					   MPA_V2_RDMA_WRITE_RTR : p2p_type ==
919d2fe99e8SKumar Sanghvi 					   FW_RI_INIT_P2PTYPE_READ_REQ ?
920d2fe99e8SKumar Sanghvi 					   MPA_V2_RDMA_READ_RTR : 0) : 0));
921d2fe99e8SKumar Sanghvi 		memcpy(mpa->private_data, &mpa_v2_params,
922d2fe99e8SKumar Sanghvi 		       sizeof(struct mpa_v2_conn_params));
923d2fe99e8SKumar Sanghvi 
924d2fe99e8SKumar Sanghvi 		if (ep->plen)
925d2fe99e8SKumar Sanghvi 			memcpy(mpa->private_data +
926d2fe99e8SKumar Sanghvi 			       sizeof(struct mpa_v2_conn_params), pdata, plen);
927d2fe99e8SKumar Sanghvi 	} else
928cfdda9d7SSteve Wise 		if (plen)
929cfdda9d7SSteve Wise 			memcpy(mpa->private_data, pdata, plen);
930cfdda9d7SSteve Wise 
931cfdda9d7SSteve Wise 	/*
932cfdda9d7SSteve Wise 	 * Reference the mpa skb again.  This ensures the data area
933cfdda9d7SSteve Wise 	 * will remain in memory until the hw acks the tx.
934cfdda9d7SSteve Wise 	 * Function fw4_ack() will deref it.
935cfdda9d7SSteve Wise 	 */
936cfdda9d7SSteve Wise 	skb_get(skb);
937cfdda9d7SSteve Wise 	set_wr_txq(skb, CPL_PRIORITY_DATA, ep->txq_idx);
938cfdda9d7SSteve Wise 	t4_set_arp_err_handler(skb, NULL, arp_failure_discard);
939cfdda9d7SSteve Wise 	BUG_ON(ep->mpa_skb);
940cfdda9d7SSteve Wise 	ep->mpa_skb = skb;
9419c88aa00SSteve Wise 	ep->snd_seq += mpalen;
942cfdda9d7SSteve Wise 	return c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t);
943cfdda9d7SSteve Wise }
944cfdda9d7SSteve Wise 
945cfdda9d7SSteve Wise static int send_mpa_reply(struct c4iw_ep *ep, const void *pdata, u8 plen)
946cfdda9d7SSteve Wise {
947cfdda9d7SSteve Wise 	int mpalen, wrlen;
948cfdda9d7SSteve Wise 	struct fw_ofld_tx_data_wr *req;
949cfdda9d7SSteve Wise 	struct mpa_message *mpa;
950cfdda9d7SSteve Wise 	struct sk_buff *skb;
951d2fe99e8SKumar Sanghvi 	struct mpa_v2_conn_params mpa_v2_params;
952cfdda9d7SSteve Wise 
953cfdda9d7SSteve Wise 	PDBG("%s ep %p tid %u pd_len %d\n", __func__, ep, ep->hwtid, ep->plen);
954cfdda9d7SSteve Wise 
955cfdda9d7SSteve Wise 	mpalen = sizeof(*mpa) + plen;
956d2fe99e8SKumar Sanghvi 	if (ep->mpa_attr.version == 2 && ep->mpa_attr.enhanced_rdma_conn)
957d2fe99e8SKumar Sanghvi 		mpalen += sizeof(struct mpa_v2_conn_params);
958cfdda9d7SSteve Wise 	wrlen = roundup(mpalen + sizeof *req, 16);
959cfdda9d7SSteve Wise 
960cfdda9d7SSteve Wise 	skb = get_skb(NULL, wrlen, GFP_KERNEL);
961cfdda9d7SSteve Wise 	if (!skb) {
962cfdda9d7SSteve Wise 		printk(KERN_ERR MOD "%s - cannot alloc skb!\n", __func__);
963cfdda9d7SSteve Wise 		return -ENOMEM;
964cfdda9d7SSteve Wise 	}
965cfdda9d7SSteve Wise 	set_wr_txq(skb, CPL_PRIORITY_DATA, ep->txq_idx);
966cfdda9d7SSteve Wise 
967cfdda9d7SSteve Wise 	req = (struct fw_ofld_tx_data_wr *) skb_put(skb, wrlen);
968cfdda9d7SSteve Wise 	memset(req, 0, wrlen);
969cfdda9d7SSteve Wise 	req->op_to_immdlen = cpu_to_be32(
970cfdda9d7SSteve Wise 		FW_WR_OP(FW_OFLD_TX_DATA_WR) |
971cfdda9d7SSteve Wise 		FW_WR_COMPL(1) |
972cfdda9d7SSteve Wise 		FW_WR_IMMDLEN(mpalen));
973cfdda9d7SSteve Wise 	req->flowid_len16 = cpu_to_be32(
974cfdda9d7SSteve Wise 		FW_WR_FLOWID(ep->hwtid) |
975cfdda9d7SSteve Wise 		FW_WR_LEN16(wrlen >> 4));
976cfdda9d7SSteve Wise 	req->plen = cpu_to_be32(mpalen);
977cfdda9d7SSteve Wise 	req->tunnel_to_proxy = cpu_to_be32(
978cfdda9d7SSteve Wise 		FW_OFLD_TX_DATA_WR_FLUSH(1) |
979cfdda9d7SSteve Wise 		FW_OFLD_TX_DATA_WR_SHOVE(1));
980cfdda9d7SSteve Wise 
981cfdda9d7SSteve Wise 	mpa = (struct mpa_message *)(req + 1);
982cfdda9d7SSteve Wise 	memset(mpa, 0, sizeof(*mpa));
983cfdda9d7SSteve Wise 	memcpy(mpa->key, MPA_KEY_REP, sizeof(mpa->key));
984cfdda9d7SSteve Wise 	mpa->flags = (ep->mpa_attr.crc_enabled ? MPA_CRC : 0) |
985cfdda9d7SSteve Wise 		     (markers_enabled ? MPA_MARKERS : 0);
986d2fe99e8SKumar Sanghvi 	mpa->revision = ep->mpa_attr.version;
987cfdda9d7SSteve Wise 	mpa->private_data_size = htons(plen);
988d2fe99e8SKumar Sanghvi 
989d2fe99e8SKumar Sanghvi 	if (ep->mpa_attr.version == 2 && ep->mpa_attr.enhanced_rdma_conn) {
990d2fe99e8SKumar Sanghvi 		mpa->flags |= MPA_ENHANCED_RDMA_CONN;
991f747c34aSRoland Dreier 		mpa->private_data_size = htons(ntohs(mpa->private_data_size) +
992f747c34aSRoland Dreier 					       sizeof (struct mpa_v2_conn_params));
993d2fe99e8SKumar Sanghvi 		mpa_v2_params.ird = htons((u16)ep->ird);
994d2fe99e8SKumar Sanghvi 		mpa_v2_params.ord = htons((u16)ep->ord);
995d2fe99e8SKumar Sanghvi 		if (peer2peer && (ep->mpa_attr.p2p_type !=
996d2fe99e8SKumar Sanghvi 					FW_RI_INIT_P2PTYPE_DISABLED)) {
997d2fe99e8SKumar Sanghvi 			mpa_v2_params.ird |= htons(MPA_V2_PEER2PEER_MODEL);
998d2fe99e8SKumar Sanghvi 
999d2fe99e8SKumar Sanghvi 			if (p2p_type == FW_RI_INIT_P2PTYPE_RDMA_WRITE)
1000d2fe99e8SKumar Sanghvi 				mpa_v2_params.ord |=
1001d2fe99e8SKumar Sanghvi 					htons(MPA_V2_RDMA_WRITE_RTR);
1002d2fe99e8SKumar Sanghvi 			else if (p2p_type == FW_RI_INIT_P2PTYPE_READ_REQ)
1003d2fe99e8SKumar Sanghvi 				mpa_v2_params.ord |=
1004d2fe99e8SKumar Sanghvi 					htons(MPA_V2_RDMA_READ_RTR);
1005d2fe99e8SKumar Sanghvi 		}
1006d2fe99e8SKumar Sanghvi 
1007d2fe99e8SKumar Sanghvi 		memcpy(mpa->private_data, &mpa_v2_params,
1008d2fe99e8SKumar Sanghvi 		       sizeof(struct mpa_v2_conn_params));
1009d2fe99e8SKumar Sanghvi 
1010d2fe99e8SKumar Sanghvi 		if (ep->plen)
1011d2fe99e8SKumar Sanghvi 			memcpy(mpa->private_data +
1012d2fe99e8SKumar Sanghvi 			       sizeof(struct mpa_v2_conn_params), pdata, plen);
1013d2fe99e8SKumar Sanghvi 	} else
1014cfdda9d7SSteve Wise 		if (plen)
1015cfdda9d7SSteve Wise 			memcpy(mpa->private_data, pdata, plen);
1016cfdda9d7SSteve Wise 
1017cfdda9d7SSteve Wise 	/*
1018cfdda9d7SSteve Wise 	 * Reference the mpa skb.  This ensures the data area
1019cfdda9d7SSteve Wise 	 * will remain in memory until the hw acks the tx.
1020cfdda9d7SSteve Wise 	 * Function fw4_ack() will deref it.
1021cfdda9d7SSteve Wise 	 */
1022cfdda9d7SSteve Wise 	skb_get(skb);
1023cfdda9d7SSteve Wise 	t4_set_arp_err_handler(skb, NULL, arp_failure_discard);
1024cfdda9d7SSteve Wise 	ep->mpa_skb = skb;
1025a7db89ebSSteve Wise 	__state_set(&ep->com, MPA_REP_SENT);
10269c88aa00SSteve Wise 	ep->snd_seq += mpalen;
1027cfdda9d7SSteve Wise 	return c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t);
1028cfdda9d7SSteve Wise }
1029cfdda9d7SSteve Wise 
1030cfdda9d7SSteve Wise static int act_establish(struct c4iw_dev *dev, struct sk_buff *skb)
1031cfdda9d7SSteve Wise {
1032cfdda9d7SSteve Wise 	struct c4iw_ep *ep;
1033cfdda9d7SSteve Wise 	struct cpl_act_establish *req = cplhdr(skb);
1034cfdda9d7SSteve Wise 	unsigned int tid = GET_TID(req);
1035cfdda9d7SSteve Wise 	unsigned int atid = GET_TID_TID(ntohl(req->tos_atid));
1036cfdda9d7SSteve Wise 	struct tid_info *t = dev->rdev.lldi.tids;
1037cfdda9d7SSteve Wise 
1038cfdda9d7SSteve Wise 	ep = lookup_atid(t, atid);
1039cfdda9d7SSteve Wise 
1040cfdda9d7SSteve Wise 	PDBG("%s ep %p tid %u snd_isn %u rcv_isn %u\n", __func__, ep, tid,
1041cfdda9d7SSteve Wise 	     be32_to_cpu(req->snd_isn), be32_to_cpu(req->rcv_isn));
1042cfdda9d7SSteve Wise 
1043a7db89ebSSteve Wise 	mutex_lock(&ep->com.mutex);
1044cfdda9d7SSteve Wise 	dst_confirm(ep->dst);
1045cfdda9d7SSteve Wise 
1046cfdda9d7SSteve Wise 	/* setup the hwtid for this connection */
1047cfdda9d7SSteve Wise 	ep->hwtid = tid;
1048cfdda9d7SSteve Wise 	cxgb4_insert_tid(t, ep, tid);
1049793dad94SVipul Pandya 	insert_handle(dev, &dev->hwtid_idr, ep, ep->hwtid);
1050cfdda9d7SSteve Wise 
1051cfdda9d7SSteve Wise 	ep->snd_seq = be32_to_cpu(req->snd_isn);
1052cfdda9d7SSteve Wise 	ep->rcv_seq = be32_to_cpu(req->rcv_isn);
1053cfdda9d7SSteve Wise 
1054cfdda9d7SSteve Wise 	set_emss(ep, ntohs(req->tcp_opt));
1055cfdda9d7SSteve Wise 
1056cfdda9d7SSteve Wise 	/* dealloc the atid */
1057793dad94SVipul Pandya 	remove_handle(ep->com.dev, &ep->com.dev->atid_idr, atid);
1058cfdda9d7SSteve Wise 	cxgb4_free_atid(t, atid);
1059793dad94SVipul Pandya 	set_bit(ACT_ESTAB, &ep->com.history);
1060cfdda9d7SSteve Wise 
1061cfdda9d7SSteve Wise 	/* start MPA negotiation */
1062cfdda9d7SSteve Wise 	send_flowc(ep, NULL);
1063d2fe99e8SKumar Sanghvi 	if (ep->retry_with_mpa_v1)
1064d2fe99e8SKumar Sanghvi 		send_mpa_req(ep, skb, 1);
1065d2fe99e8SKumar Sanghvi 	else
1066d2fe99e8SKumar Sanghvi 		send_mpa_req(ep, skb, mpa_rev);
1067a7db89ebSSteve Wise 	mutex_unlock(&ep->com.mutex);
1068cfdda9d7SSteve Wise 	return 0;
1069cfdda9d7SSteve Wise }
1070cfdda9d7SSteve Wise 
1071be13b2dfSSteve Wise static void close_complete_upcall(struct c4iw_ep *ep, int status)
1072cfdda9d7SSteve Wise {
1073cfdda9d7SSteve Wise 	struct iw_cm_event event;
1074cfdda9d7SSteve Wise 
1075cfdda9d7SSteve Wise 	PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
1076cfdda9d7SSteve Wise 	memset(&event, 0, sizeof(event));
1077cfdda9d7SSteve Wise 	event.event = IW_CM_EVENT_CLOSE;
1078be13b2dfSSteve Wise 	event.status = status;
1079cfdda9d7SSteve Wise 	if (ep->com.cm_id) {
1080cfdda9d7SSteve Wise 		PDBG("close complete delivered ep %p cm_id %p tid %u\n",
1081cfdda9d7SSteve Wise 		     ep, ep->com.cm_id, ep->hwtid);
1082cfdda9d7SSteve Wise 		ep->com.cm_id->event_handler(ep->com.cm_id, &event);
1083cfdda9d7SSteve Wise 		ep->com.cm_id->rem_ref(ep->com.cm_id);
1084cfdda9d7SSteve Wise 		ep->com.cm_id = NULL;
1085793dad94SVipul Pandya 		set_bit(CLOSE_UPCALL, &ep->com.history);
1086cfdda9d7SSteve Wise 	}
1087cfdda9d7SSteve Wise }
1088cfdda9d7SSteve Wise 
1089cfdda9d7SSteve Wise static int abort_connection(struct c4iw_ep *ep, struct sk_buff *skb, gfp_t gfp)
1090cfdda9d7SSteve Wise {
1091cfdda9d7SSteve Wise 	PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
1092cc18b939SSteve Wise 	__state_set(&ep->com, ABORTING);
1093793dad94SVipul Pandya 	set_bit(ABORT_CONN, &ep->com.history);
1094cfdda9d7SSteve Wise 	return send_abort(ep, skb, gfp);
1095cfdda9d7SSteve Wise }
1096cfdda9d7SSteve Wise 
1097cfdda9d7SSteve Wise static void peer_close_upcall(struct c4iw_ep *ep)
1098cfdda9d7SSteve Wise {
1099cfdda9d7SSteve Wise 	struct iw_cm_event event;
1100cfdda9d7SSteve Wise 
1101cfdda9d7SSteve Wise 	PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
1102cfdda9d7SSteve Wise 	memset(&event, 0, sizeof(event));
1103cfdda9d7SSteve Wise 	event.event = IW_CM_EVENT_DISCONNECT;
1104cfdda9d7SSteve Wise 	if (ep->com.cm_id) {
1105cfdda9d7SSteve Wise 		PDBG("peer close delivered ep %p cm_id %p tid %u\n",
1106cfdda9d7SSteve Wise 		     ep, ep->com.cm_id, ep->hwtid);
1107cfdda9d7SSteve Wise 		ep->com.cm_id->event_handler(ep->com.cm_id, &event);
1108793dad94SVipul Pandya 		set_bit(DISCONN_UPCALL, &ep->com.history);
1109cfdda9d7SSteve Wise 	}
1110cfdda9d7SSteve Wise }
1111cfdda9d7SSteve Wise 
1112cfdda9d7SSteve Wise static void peer_abort_upcall(struct c4iw_ep *ep)
1113cfdda9d7SSteve Wise {
1114cfdda9d7SSteve Wise 	struct iw_cm_event event;
1115cfdda9d7SSteve Wise 
1116cfdda9d7SSteve Wise 	PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
1117cfdda9d7SSteve Wise 	memset(&event, 0, sizeof(event));
1118cfdda9d7SSteve Wise 	event.event = IW_CM_EVENT_CLOSE;
1119cfdda9d7SSteve Wise 	event.status = -ECONNRESET;
1120cfdda9d7SSteve Wise 	if (ep->com.cm_id) {
1121cfdda9d7SSteve Wise 		PDBG("abort delivered ep %p cm_id %p tid %u\n", ep,
1122cfdda9d7SSteve Wise 		     ep->com.cm_id, ep->hwtid);
1123cfdda9d7SSteve Wise 		ep->com.cm_id->event_handler(ep->com.cm_id, &event);
1124cfdda9d7SSteve Wise 		ep->com.cm_id->rem_ref(ep->com.cm_id);
1125cfdda9d7SSteve Wise 		ep->com.cm_id = NULL;
1126793dad94SVipul Pandya 		set_bit(ABORT_UPCALL, &ep->com.history);
1127cfdda9d7SSteve Wise 	}
1128cfdda9d7SSteve Wise }
1129cfdda9d7SSteve Wise 
1130cfdda9d7SSteve Wise static void connect_reply_upcall(struct c4iw_ep *ep, int status)
1131cfdda9d7SSteve Wise {
1132cfdda9d7SSteve Wise 	struct iw_cm_event event;
1133cfdda9d7SSteve Wise 
1134cfdda9d7SSteve Wise 	PDBG("%s ep %p tid %u status %d\n", __func__, ep, ep->hwtid, status);
1135cfdda9d7SSteve Wise 	memset(&event, 0, sizeof(event));
1136cfdda9d7SSteve Wise 	event.event = IW_CM_EVENT_CONNECT_REPLY;
1137cfdda9d7SSteve Wise 	event.status = status;
113824d44a39SSteve Wise 	memcpy(&event.local_addr, &ep->com.local_addr,
113924d44a39SSteve Wise 	       sizeof(ep->com.local_addr));
114024d44a39SSteve Wise 	memcpy(&event.remote_addr, &ep->com.remote_addr,
114124d44a39SSteve Wise 	       sizeof(ep->com.remote_addr));
1142cfdda9d7SSteve Wise 
1143cfdda9d7SSteve Wise 	if ((status == 0) || (status == -ECONNREFUSED)) {
1144d2fe99e8SKumar Sanghvi 		if (!ep->tried_with_mpa_v1) {
1145d2fe99e8SKumar Sanghvi 			/* this means MPA_v2 is used */
1146d2fe99e8SKumar Sanghvi 			event.private_data_len = ep->plen -
1147d2fe99e8SKumar Sanghvi 				sizeof(struct mpa_v2_conn_params);
1148d2fe99e8SKumar Sanghvi 			event.private_data = ep->mpa_pkt +
1149d2fe99e8SKumar Sanghvi 				sizeof(struct mpa_message) +
1150d2fe99e8SKumar Sanghvi 				sizeof(struct mpa_v2_conn_params);
1151d2fe99e8SKumar Sanghvi 		} else {
1152d2fe99e8SKumar Sanghvi 			/* this means MPA_v1 is used */
1153cfdda9d7SSteve Wise 			event.private_data_len = ep->plen;
1154d2fe99e8SKumar Sanghvi 			event.private_data = ep->mpa_pkt +
1155d2fe99e8SKumar Sanghvi 				sizeof(struct mpa_message);
1156d2fe99e8SKumar Sanghvi 		}
1157cfdda9d7SSteve Wise 	}
115885963e4cSRoland Dreier 
1159cfdda9d7SSteve Wise 	PDBG("%s ep %p tid %u status %d\n", __func__, ep,
1160cfdda9d7SSteve Wise 	     ep->hwtid, status);
1161793dad94SVipul Pandya 	set_bit(CONN_RPL_UPCALL, &ep->com.history);
1162cfdda9d7SSteve Wise 	ep->com.cm_id->event_handler(ep->com.cm_id, &event);
116385963e4cSRoland Dreier 
1164cfdda9d7SSteve Wise 	if (status < 0) {
1165cfdda9d7SSteve Wise 		ep->com.cm_id->rem_ref(ep->com.cm_id);
1166cfdda9d7SSteve Wise 		ep->com.cm_id = NULL;
1167cfdda9d7SSteve Wise 	}
1168cfdda9d7SSteve Wise }
1169cfdda9d7SSteve Wise 
1170be13b2dfSSteve Wise static int connect_request_upcall(struct c4iw_ep *ep)
1171cfdda9d7SSteve Wise {
1172cfdda9d7SSteve Wise 	struct iw_cm_event event;
1173be13b2dfSSteve Wise 	int ret;
1174cfdda9d7SSteve Wise 
1175cfdda9d7SSteve Wise 	PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
1176cfdda9d7SSteve Wise 	memset(&event, 0, sizeof(event));
1177cfdda9d7SSteve Wise 	event.event = IW_CM_EVENT_CONNECT_REQUEST;
117824d44a39SSteve Wise 	memcpy(&event.local_addr, &ep->com.local_addr,
117924d44a39SSteve Wise 	       sizeof(ep->com.local_addr));
118024d44a39SSteve Wise 	memcpy(&event.remote_addr, &ep->com.remote_addr,
118124d44a39SSteve Wise 	       sizeof(ep->com.remote_addr));
1182d2fe99e8SKumar Sanghvi 	event.provider_data = ep;
1183d2fe99e8SKumar Sanghvi 	if (!ep->tried_with_mpa_v1) {
1184d2fe99e8SKumar Sanghvi 		/* this means MPA_v2 is used */
1185d2fe99e8SKumar Sanghvi 		event.ord = ep->ord;
1186d2fe99e8SKumar Sanghvi 		event.ird = ep->ird;
1187d2fe99e8SKumar Sanghvi 		event.private_data_len = ep->plen -
1188d2fe99e8SKumar Sanghvi 			sizeof(struct mpa_v2_conn_params);
1189d2fe99e8SKumar Sanghvi 		event.private_data = ep->mpa_pkt + sizeof(struct mpa_message) +
1190d2fe99e8SKumar Sanghvi 			sizeof(struct mpa_v2_conn_params);
1191d2fe99e8SKumar Sanghvi 	} else {
1192d2fe99e8SKumar Sanghvi 		/* this means MPA_v1 is used. Send max supported */
1193d2fe99e8SKumar Sanghvi 		event.ord = c4iw_max_read_depth;
1194d2fe99e8SKumar Sanghvi 		event.ird = c4iw_max_read_depth;
1195cfdda9d7SSteve Wise 		event.private_data_len = ep->plen;
1196cfdda9d7SSteve Wise 		event.private_data = ep->mpa_pkt + sizeof(struct mpa_message);
1197d2fe99e8SKumar Sanghvi 	}
1198cfdda9d7SSteve Wise 	c4iw_get_ep(&ep->com);
1199be13b2dfSSteve Wise 	ret = ep->parent_ep->com.cm_id->event_handler(ep->parent_ep->com.cm_id,
1200cfdda9d7SSteve Wise 						      &event);
1201be13b2dfSSteve Wise 	if (ret)
1202be13b2dfSSteve Wise 		c4iw_put_ep(&ep->com);
1203793dad94SVipul Pandya 	set_bit(CONNREQ_UPCALL, &ep->com.history);
1204cfdda9d7SSteve Wise 	c4iw_put_ep(&ep->parent_ep->com);
1205be13b2dfSSteve Wise 	return ret;
1206cfdda9d7SSteve Wise }
1207cfdda9d7SSteve Wise 
1208cfdda9d7SSteve Wise static void established_upcall(struct c4iw_ep *ep)
1209cfdda9d7SSteve Wise {
1210cfdda9d7SSteve Wise 	struct iw_cm_event event;
1211cfdda9d7SSteve Wise 
1212cfdda9d7SSteve Wise 	PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
1213cfdda9d7SSteve Wise 	memset(&event, 0, sizeof(event));
1214cfdda9d7SSteve Wise 	event.event = IW_CM_EVENT_ESTABLISHED;
1215d2fe99e8SKumar Sanghvi 	event.ird = ep->ird;
1216d2fe99e8SKumar Sanghvi 	event.ord = ep->ord;
1217cfdda9d7SSteve Wise 	if (ep->com.cm_id) {
1218cfdda9d7SSteve Wise 		PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
1219cfdda9d7SSteve Wise 		ep->com.cm_id->event_handler(ep->com.cm_id, &event);
1220793dad94SVipul Pandya 		set_bit(ESTAB_UPCALL, &ep->com.history);
1221cfdda9d7SSteve Wise 	}
1222cfdda9d7SSteve Wise }
1223cfdda9d7SSteve Wise 
1224cfdda9d7SSteve Wise static int update_rx_credits(struct c4iw_ep *ep, u32 credits)
1225cfdda9d7SSteve Wise {
1226cfdda9d7SSteve Wise 	struct cpl_rx_data_ack *req;
1227cfdda9d7SSteve Wise 	struct sk_buff *skb;
1228cfdda9d7SSteve Wise 	int wrlen = roundup(sizeof *req, 16);
1229cfdda9d7SSteve Wise 
1230cfdda9d7SSteve Wise 	PDBG("%s ep %p tid %u credits %u\n", __func__, ep, ep->hwtid, credits);
1231cfdda9d7SSteve Wise 	skb = get_skb(NULL, wrlen, GFP_KERNEL);
1232cfdda9d7SSteve Wise 	if (!skb) {
1233cfdda9d7SSteve Wise 		printk(KERN_ERR MOD "update_rx_credits - cannot alloc skb!\n");
1234cfdda9d7SSteve Wise 		return 0;
1235cfdda9d7SSteve Wise 	}
1236cfdda9d7SSteve Wise 
1237b408ff28SHariprasad Shenai 	/*
1238b408ff28SHariprasad Shenai 	 * If we couldn't specify the entire rcv window at connection setup
1239b408ff28SHariprasad Shenai 	 * due to the limit in the number of bits in the RCV_BUFSIZ field,
1240b408ff28SHariprasad Shenai 	 * then add the overage in to the credits returned.
1241b408ff28SHariprasad Shenai 	 */
1242b408ff28SHariprasad Shenai 	if (ep->rcv_win > RCV_BUFSIZ_MASK * 1024)
1243b408ff28SHariprasad Shenai 		credits += ep->rcv_win - RCV_BUFSIZ_MASK * 1024;
1244b408ff28SHariprasad Shenai 
1245cfdda9d7SSteve Wise 	req = (struct cpl_rx_data_ack *) skb_put(skb, wrlen);
1246cfdda9d7SSteve Wise 	memset(req, 0, wrlen);
1247cfdda9d7SSteve Wise 	INIT_TP_WR(req, ep->hwtid);
1248cfdda9d7SSteve Wise 	OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_RX_DATA_ACK,
1249cfdda9d7SSteve Wise 						    ep->hwtid));
1250ba6d3925SSteve Wise 	req->credit_dack = cpu_to_be32(credits | RX_FORCE_ACK(1) |
1251ba6d3925SSteve Wise 				       F_RX_DACK_CHANGE |
1252ba6d3925SSteve Wise 				       V_RX_DACK_MODE(dack_mode));
1253d4f1a5c6SSteve Wise 	set_wr_txq(skb, CPL_PRIORITY_ACK, ep->ctrlq_idx);
1254cfdda9d7SSteve Wise 	c4iw_ofld_send(&ep->com.dev->rdev, skb);
1255cfdda9d7SSteve Wise 	return credits;
1256cfdda9d7SSteve Wise }
1257cfdda9d7SSteve Wise 
1258cc18b939SSteve Wise static int process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb)
1259cfdda9d7SSteve Wise {
1260cfdda9d7SSteve Wise 	struct mpa_message *mpa;
1261d2fe99e8SKumar Sanghvi 	struct mpa_v2_conn_params *mpa_v2_params;
1262cfdda9d7SSteve Wise 	u16 plen;
1263d2fe99e8SKumar Sanghvi 	u16 resp_ird, resp_ord;
1264d2fe99e8SKumar Sanghvi 	u8 rtr_mismatch = 0, insuff_ird = 0;
1265cfdda9d7SSteve Wise 	struct c4iw_qp_attributes attrs;
1266cfdda9d7SSteve Wise 	enum c4iw_qp_attr_mask mask;
1267cfdda9d7SSteve Wise 	int err;
1268cc18b939SSteve Wise 	int disconnect = 0;
1269cfdda9d7SSteve Wise 
1270cfdda9d7SSteve Wise 	PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
1271cfdda9d7SSteve Wise 
1272cfdda9d7SSteve Wise 	/*
1273b33bd0cbSSteve Wise 	 * Stop mpa timer.  If it expired, then
1274b33bd0cbSSteve Wise 	 * we ignore the MPA reply.  process_timeout()
1275b33bd0cbSSteve Wise 	 * will abort the connection.
1276cfdda9d7SSteve Wise 	 */
1277b33bd0cbSSteve Wise 	if (stop_ep_timer(ep))
1278cc18b939SSteve Wise 		return 0;
1279cfdda9d7SSteve Wise 
1280cfdda9d7SSteve Wise 	/*
1281cfdda9d7SSteve Wise 	 * If we get more than the supported amount of private data
1282cfdda9d7SSteve Wise 	 * then we must fail this connection.
1283cfdda9d7SSteve Wise 	 */
1284cfdda9d7SSteve Wise 	if (ep->mpa_pkt_len + skb->len > sizeof(ep->mpa_pkt)) {
1285cfdda9d7SSteve Wise 		err = -EINVAL;
1286cfdda9d7SSteve Wise 		goto err;
1287cfdda9d7SSteve Wise 	}
1288cfdda9d7SSteve Wise 
1289cfdda9d7SSteve Wise 	/*
1290cfdda9d7SSteve Wise 	 * copy the new data into our accumulation buffer.
1291cfdda9d7SSteve Wise 	 */
1292cfdda9d7SSteve Wise 	skb_copy_from_linear_data(skb, &(ep->mpa_pkt[ep->mpa_pkt_len]),
1293cfdda9d7SSteve Wise 				  skb->len);
1294cfdda9d7SSteve Wise 	ep->mpa_pkt_len += skb->len;
1295cfdda9d7SSteve Wise 
1296cfdda9d7SSteve Wise 	/*
1297cfdda9d7SSteve Wise 	 * if we don't even have the mpa message, then bail.
1298cfdda9d7SSteve Wise 	 */
1299cfdda9d7SSteve Wise 	if (ep->mpa_pkt_len < sizeof(*mpa))
1300cc18b939SSteve Wise 		return 0;
1301cfdda9d7SSteve Wise 	mpa = (struct mpa_message *) ep->mpa_pkt;
1302cfdda9d7SSteve Wise 
1303cfdda9d7SSteve Wise 	/* Validate MPA header. */
1304d2fe99e8SKumar Sanghvi 	if (mpa->revision > mpa_rev) {
1305d2fe99e8SKumar Sanghvi 		printk(KERN_ERR MOD "%s MPA version mismatch. Local = %d,"
1306d2fe99e8SKumar Sanghvi 		       " Received = %d\n", __func__, mpa_rev, mpa->revision);
1307cfdda9d7SSteve Wise 		err = -EPROTO;
1308cfdda9d7SSteve Wise 		goto err;
1309cfdda9d7SSteve Wise 	}
1310cfdda9d7SSteve Wise 	if (memcmp(mpa->key, MPA_KEY_REP, sizeof(mpa->key))) {
1311cfdda9d7SSteve Wise 		err = -EPROTO;
1312cfdda9d7SSteve Wise 		goto err;
1313cfdda9d7SSteve Wise 	}
1314cfdda9d7SSteve Wise 
1315cfdda9d7SSteve Wise 	plen = ntohs(mpa->private_data_size);
1316cfdda9d7SSteve Wise 
1317cfdda9d7SSteve Wise 	/*
1318cfdda9d7SSteve Wise 	 * Fail if there's too much private data.
1319cfdda9d7SSteve Wise 	 */
1320cfdda9d7SSteve Wise 	if (plen > MPA_MAX_PRIVATE_DATA) {
1321cfdda9d7SSteve Wise 		err = -EPROTO;
1322cfdda9d7SSteve Wise 		goto err;
1323cfdda9d7SSteve Wise 	}
1324cfdda9d7SSteve Wise 
1325cfdda9d7SSteve Wise 	/*
1326cfdda9d7SSteve Wise 	 * If plen does not account for pkt size
1327cfdda9d7SSteve Wise 	 */
1328cfdda9d7SSteve Wise 	if (ep->mpa_pkt_len > (sizeof(*mpa) + plen)) {
1329cfdda9d7SSteve Wise 		err = -EPROTO;
1330cfdda9d7SSteve Wise 		goto err;
1331cfdda9d7SSteve Wise 	}
1332cfdda9d7SSteve Wise 
1333cfdda9d7SSteve Wise 	ep->plen = (u8) plen;
1334cfdda9d7SSteve Wise 
1335cfdda9d7SSteve Wise 	/*
1336cfdda9d7SSteve Wise 	 * If we don't have all the pdata yet, then bail.
1337cfdda9d7SSteve Wise 	 * We'll continue process when more data arrives.
1338cfdda9d7SSteve Wise 	 */
1339cfdda9d7SSteve Wise 	if (ep->mpa_pkt_len < (sizeof(*mpa) + plen))
1340cc18b939SSteve Wise 		return 0;
1341cfdda9d7SSteve Wise 
1342cfdda9d7SSteve Wise 	if (mpa->flags & MPA_REJECT) {
1343cfdda9d7SSteve Wise 		err = -ECONNREFUSED;
1344cfdda9d7SSteve Wise 		goto err;
1345cfdda9d7SSteve Wise 	}
1346cfdda9d7SSteve Wise 
1347cfdda9d7SSteve Wise 	/*
1348cfdda9d7SSteve Wise 	 * If we get here we have accumulated the entire mpa
1349cfdda9d7SSteve Wise 	 * start reply message including private data. And
1350cfdda9d7SSteve Wise 	 * the MPA header is valid.
1351cfdda9d7SSteve Wise 	 */
1352c529fb50SSteve Wise 	__state_set(&ep->com, FPDU_MODE);
1353cfdda9d7SSteve Wise 	ep->mpa_attr.crc_enabled = (mpa->flags & MPA_CRC) | crc_enabled ? 1 : 0;
1354cfdda9d7SSteve Wise 	ep->mpa_attr.recv_marker_enabled = markers_enabled;
1355cfdda9d7SSteve Wise 	ep->mpa_attr.xmit_marker_enabled = mpa->flags & MPA_MARKERS ? 1 : 0;
1356d2fe99e8SKumar Sanghvi 	ep->mpa_attr.version = mpa->revision;
1357d2fe99e8SKumar Sanghvi 	ep->mpa_attr.p2p_type = FW_RI_INIT_P2PTYPE_DISABLED;
1358d2fe99e8SKumar Sanghvi 
1359d2fe99e8SKumar Sanghvi 	if (mpa->revision == 2) {
1360d2fe99e8SKumar Sanghvi 		ep->mpa_attr.enhanced_rdma_conn =
1361d2fe99e8SKumar Sanghvi 			mpa->flags & MPA_ENHANCED_RDMA_CONN ? 1 : 0;
1362d2fe99e8SKumar Sanghvi 		if (ep->mpa_attr.enhanced_rdma_conn) {
1363d2fe99e8SKumar Sanghvi 			mpa_v2_params = (struct mpa_v2_conn_params *)
1364d2fe99e8SKumar Sanghvi 				(ep->mpa_pkt + sizeof(*mpa));
1365d2fe99e8SKumar Sanghvi 			resp_ird = ntohs(mpa_v2_params->ird) &
1366d2fe99e8SKumar Sanghvi 				MPA_V2_IRD_ORD_MASK;
1367d2fe99e8SKumar Sanghvi 			resp_ord = ntohs(mpa_v2_params->ord) &
1368d2fe99e8SKumar Sanghvi 				MPA_V2_IRD_ORD_MASK;
1369d2fe99e8SKumar Sanghvi 
1370d2fe99e8SKumar Sanghvi 			/*
1371d2fe99e8SKumar Sanghvi 			 * This is a double-check. Ideally, below checks are
1372d2fe99e8SKumar Sanghvi 			 * not required since ird/ord stuff has been taken
1373d2fe99e8SKumar Sanghvi 			 * care of in c4iw_accept_cr
1374d2fe99e8SKumar Sanghvi 			 */
1375d2fe99e8SKumar Sanghvi 			if ((ep->ird < resp_ord) || (ep->ord > resp_ird)) {
1376d2fe99e8SKumar Sanghvi 				err = -ENOMEM;
1377d2fe99e8SKumar Sanghvi 				ep->ird = resp_ord;
1378d2fe99e8SKumar Sanghvi 				ep->ord = resp_ird;
1379d2fe99e8SKumar Sanghvi 				insuff_ird = 1;
1380d2fe99e8SKumar Sanghvi 			}
1381d2fe99e8SKumar Sanghvi 
1382d2fe99e8SKumar Sanghvi 			if (ntohs(mpa_v2_params->ird) &
1383d2fe99e8SKumar Sanghvi 					MPA_V2_PEER2PEER_MODEL) {
1384d2fe99e8SKumar Sanghvi 				if (ntohs(mpa_v2_params->ord) &
1385d2fe99e8SKumar Sanghvi 						MPA_V2_RDMA_WRITE_RTR)
1386d2fe99e8SKumar Sanghvi 					ep->mpa_attr.p2p_type =
1387d2fe99e8SKumar Sanghvi 						FW_RI_INIT_P2PTYPE_RDMA_WRITE;
1388d2fe99e8SKumar Sanghvi 				else if (ntohs(mpa_v2_params->ord) &
1389d2fe99e8SKumar Sanghvi 						MPA_V2_RDMA_READ_RTR)
1390d2fe99e8SKumar Sanghvi 					ep->mpa_attr.p2p_type =
1391d2fe99e8SKumar Sanghvi 						FW_RI_INIT_P2PTYPE_READ_REQ;
1392d2fe99e8SKumar Sanghvi 			}
1393d2fe99e8SKumar Sanghvi 		}
1394d2fe99e8SKumar Sanghvi 	} else if (mpa->revision == 1)
1395d2fe99e8SKumar Sanghvi 		if (peer2peer)
1396d2fe99e8SKumar Sanghvi 			ep->mpa_attr.p2p_type = p2p_type;
1397d2fe99e8SKumar Sanghvi 
1398cfdda9d7SSteve Wise 	PDBG("%s - crc_enabled=%d, recv_marker_enabled=%d, "
1399d2fe99e8SKumar Sanghvi 	     "xmit_marker_enabled=%d, version=%d p2p_type=%d local-p2p_type = "
1400d2fe99e8SKumar Sanghvi 	     "%d\n", __func__, ep->mpa_attr.crc_enabled,
1401d2fe99e8SKumar Sanghvi 	     ep->mpa_attr.recv_marker_enabled,
1402d2fe99e8SKumar Sanghvi 	     ep->mpa_attr.xmit_marker_enabled, ep->mpa_attr.version,
1403d2fe99e8SKumar Sanghvi 	     ep->mpa_attr.p2p_type, p2p_type);
1404d2fe99e8SKumar Sanghvi 
1405d2fe99e8SKumar Sanghvi 	/*
1406d2fe99e8SKumar Sanghvi 	 * If responder's RTR does not match with that of initiator, assign
1407d2fe99e8SKumar Sanghvi 	 * FW_RI_INIT_P2PTYPE_DISABLED in mpa attributes so that RTR is not
1408d2fe99e8SKumar Sanghvi 	 * generated when moving QP to RTS state.
1409d2fe99e8SKumar Sanghvi 	 * A TERM message will be sent after QP has moved to RTS state
1410d2fe99e8SKumar Sanghvi 	 */
141191018f86SKumar Sanghvi 	if ((ep->mpa_attr.version == 2) && peer2peer &&
1412d2fe99e8SKumar Sanghvi 			(ep->mpa_attr.p2p_type != p2p_type)) {
1413d2fe99e8SKumar Sanghvi 		ep->mpa_attr.p2p_type = FW_RI_INIT_P2PTYPE_DISABLED;
1414d2fe99e8SKumar Sanghvi 		rtr_mismatch = 1;
1415d2fe99e8SKumar Sanghvi 	}
1416cfdda9d7SSteve Wise 
1417cfdda9d7SSteve Wise 	attrs.mpa_attr = ep->mpa_attr;
1418cfdda9d7SSteve Wise 	attrs.max_ird = ep->ird;
1419cfdda9d7SSteve Wise 	attrs.max_ord = ep->ord;
1420cfdda9d7SSteve Wise 	attrs.llp_stream_handle = ep;
1421cfdda9d7SSteve Wise 	attrs.next_state = C4IW_QP_STATE_RTS;
1422cfdda9d7SSteve Wise 
1423cfdda9d7SSteve Wise 	mask = C4IW_QP_ATTR_NEXT_STATE |
1424cfdda9d7SSteve Wise 	    C4IW_QP_ATTR_LLP_STREAM_HANDLE | C4IW_QP_ATTR_MPA_ATTR |
1425cfdda9d7SSteve Wise 	    C4IW_QP_ATTR_MAX_IRD | C4IW_QP_ATTR_MAX_ORD;
1426cfdda9d7SSteve Wise 
1427cfdda9d7SSteve Wise 	/* bind QP and TID with INIT_WR */
1428cfdda9d7SSteve Wise 	err = c4iw_modify_qp(ep->com.qp->rhp,
1429cfdda9d7SSteve Wise 			     ep->com.qp, mask, &attrs, 1);
1430cfdda9d7SSteve Wise 	if (err)
1431cfdda9d7SSteve Wise 		goto err;
1432d2fe99e8SKumar Sanghvi 
1433d2fe99e8SKumar Sanghvi 	/*
1434d2fe99e8SKumar Sanghvi 	 * If responder's RTR requirement did not match with what initiator
1435d2fe99e8SKumar Sanghvi 	 * supports, generate TERM message
1436d2fe99e8SKumar Sanghvi 	 */
1437d2fe99e8SKumar Sanghvi 	if (rtr_mismatch) {
1438d2fe99e8SKumar Sanghvi 		printk(KERN_ERR "%s: RTR mismatch, sending TERM\n", __func__);
1439d2fe99e8SKumar Sanghvi 		attrs.layer_etype = LAYER_MPA | DDP_LLP;
1440d2fe99e8SKumar Sanghvi 		attrs.ecode = MPA_NOMATCH_RTR;
1441d2fe99e8SKumar Sanghvi 		attrs.next_state = C4IW_QP_STATE_TERMINATE;
1442cc18b939SSteve Wise 		attrs.send_term = 1;
1443d2fe99e8SKumar Sanghvi 		err = c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,
1444cc18b939SSteve Wise 				C4IW_QP_ATTR_NEXT_STATE, &attrs, 1);
1445d2fe99e8SKumar Sanghvi 		err = -ENOMEM;
1446cc18b939SSteve Wise 		disconnect = 1;
1447d2fe99e8SKumar Sanghvi 		goto out;
1448d2fe99e8SKumar Sanghvi 	}
1449d2fe99e8SKumar Sanghvi 
1450d2fe99e8SKumar Sanghvi 	/*
1451d2fe99e8SKumar Sanghvi 	 * Generate TERM if initiator IRD is not sufficient for responder
1452d2fe99e8SKumar Sanghvi 	 * provided ORD. Currently, we do the same behaviour even when
1453d2fe99e8SKumar Sanghvi 	 * responder provided IRD is also not sufficient as regards to
1454d2fe99e8SKumar Sanghvi 	 * initiator ORD.
1455d2fe99e8SKumar Sanghvi 	 */
1456d2fe99e8SKumar Sanghvi 	if (insuff_ird) {
1457d2fe99e8SKumar Sanghvi 		printk(KERN_ERR "%s: Insufficient IRD, sending TERM\n",
1458d2fe99e8SKumar Sanghvi 				__func__);
1459d2fe99e8SKumar Sanghvi 		attrs.layer_etype = LAYER_MPA | DDP_LLP;
1460d2fe99e8SKumar Sanghvi 		attrs.ecode = MPA_INSUFF_IRD;
1461d2fe99e8SKumar Sanghvi 		attrs.next_state = C4IW_QP_STATE_TERMINATE;
1462cc18b939SSteve Wise 		attrs.send_term = 1;
1463d2fe99e8SKumar Sanghvi 		err = c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,
1464cc18b939SSteve Wise 				C4IW_QP_ATTR_NEXT_STATE, &attrs, 1);
1465d2fe99e8SKumar Sanghvi 		err = -ENOMEM;
1466cc18b939SSteve Wise 		disconnect = 1;
1467d2fe99e8SKumar Sanghvi 		goto out;
1468d2fe99e8SKumar Sanghvi 	}
1469cfdda9d7SSteve Wise 	goto out;
1470cfdda9d7SSteve Wise err:
1471c529fb50SSteve Wise 	__state_set(&ep->com, ABORTING);
1472b21ef16aSSteve Wise 	send_abort(ep, skb, GFP_KERNEL);
1473cfdda9d7SSteve Wise out:
1474cfdda9d7SSteve Wise 	connect_reply_upcall(ep, err);
1475cc18b939SSteve Wise 	return disconnect;
1476cfdda9d7SSteve Wise }
1477cfdda9d7SSteve Wise 
1478cfdda9d7SSteve Wise static void process_mpa_request(struct c4iw_ep *ep, struct sk_buff *skb)
1479cfdda9d7SSteve Wise {
1480cfdda9d7SSteve Wise 	struct mpa_message *mpa;
1481d2fe99e8SKumar Sanghvi 	struct mpa_v2_conn_params *mpa_v2_params;
1482cfdda9d7SSteve Wise 	u16 plen;
1483cfdda9d7SSteve Wise 
1484cfdda9d7SSteve Wise 	PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
1485cfdda9d7SSteve Wise 
1486cfdda9d7SSteve Wise 	/*
1487cfdda9d7SSteve Wise 	 * If we get more than the supported amount of private data
1488cfdda9d7SSteve Wise 	 * then we must fail this connection.
1489cfdda9d7SSteve Wise 	 */
1490cfdda9d7SSteve Wise 	if (ep->mpa_pkt_len + skb->len > sizeof(ep->mpa_pkt)) {
1491b33bd0cbSSteve Wise 		(void)stop_ep_timer(ep);
1492cfdda9d7SSteve Wise 		abort_connection(ep, skb, GFP_KERNEL);
1493cfdda9d7SSteve Wise 		return;
1494cfdda9d7SSteve Wise 	}
1495cfdda9d7SSteve Wise 
1496cfdda9d7SSteve Wise 	PDBG("%s enter (%s line %u)\n", __func__, __FILE__, __LINE__);
1497cfdda9d7SSteve Wise 
1498cfdda9d7SSteve Wise 	/*
1499cfdda9d7SSteve Wise 	 * Copy the new data into our accumulation buffer.
1500cfdda9d7SSteve Wise 	 */
1501cfdda9d7SSteve Wise 	skb_copy_from_linear_data(skb, &(ep->mpa_pkt[ep->mpa_pkt_len]),
1502cfdda9d7SSteve Wise 				  skb->len);
1503cfdda9d7SSteve Wise 	ep->mpa_pkt_len += skb->len;
1504cfdda9d7SSteve Wise 
1505cfdda9d7SSteve Wise 	/*
1506cfdda9d7SSteve Wise 	 * If we don't even have the mpa message, then bail.
1507cfdda9d7SSteve Wise 	 * We'll continue process when more data arrives.
1508cfdda9d7SSteve Wise 	 */
1509cfdda9d7SSteve Wise 	if (ep->mpa_pkt_len < sizeof(*mpa))
1510cfdda9d7SSteve Wise 		return;
1511cfdda9d7SSteve Wise 
1512cfdda9d7SSteve Wise 	PDBG("%s enter (%s line %u)\n", __func__, __FILE__, __LINE__);
1513cfdda9d7SSteve Wise 	mpa = (struct mpa_message *) ep->mpa_pkt;
1514cfdda9d7SSteve Wise 
1515cfdda9d7SSteve Wise 	/*
1516cfdda9d7SSteve Wise 	 * Validate MPA Header.
1517cfdda9d7SSteve Wise 	 */
1518d2fe99e8SKumar Sanghvi 	if (mpa->revision > mpa_rev) {
1519d2fe99e8SKumar Sanghvi 		printk(KERN_ERR MOD "%s MPA version mismatch. Local = %d,"
1520d2fe99e8SKumar Sanghvi 		       " Received = %d\n", __func__, mpa_rev, mpa->revision);
1521b33bd0cbSSteve Wise 		(void)stop_ep_timer(ep);
1522cfdda9d7SSteve Wise 		abort_connection(ep, skb, GFP_KERNEL);
1523cfdda9d7SSteve Wise 		return;
1524cfdda9d7SSteve Wise 	}
1525cfdda9d7SSteve Wise 
1526cfdda9d7SSteve Wise 	if (memcmp(mpa->key, MPA_KEY_REQ, sizeof(mpa->key))) {
1527b33bd0cbSSteve Wise 		(void)stop_ep_timer(ep);
1528cfdda9d7SSteve Wise 		abort_connection(ep, skb, GFP_KERNEL);
1529cfdda9d7SSteve Wise 		return;
1530cfdda9d7SSteve Wise 	}
1531cfdda9d7SSteve Wise 
1532cfdda9d7SSteve Wise 	plen = ntohs(mpa->private_data_size);
1533cfdda9d7SSteve Wise 
1534cfdda9d7SSteve Wise 	/*
1535cfdda9d7SSteve Wise 	 * Fail if there's too much private data.
1536cfdda9d7SSteve Wise 	 */
1537cfdda9d7SSteve Wise 	if (plen > MPA_MAX_PRIVATE_DATA) {
1538b33bd0cbSSteve Wise 		(void)stop_ep_timer(ep);
1539cfdda9d7SSteve Wise 		abort_connection(ep, skb, GFP_KERNEL);
1540cfdda9d7SSteve Wise 		return;
1541cfdda9d7SSteve Wise 	}
1542cfdda9d7SSteve Wise 
1543cfdda9d7SSteve Wise 	/*
1544cfdda9d7SSteve Wise 	 * If plen does not account for pkt size
1545cfdda9d7SSteve Wise 	 */
1546cfdda9d7SSteve Wise 	if (ep->mpa_pkt_len > (sizeof(*mpa) + plen)) {
1547b33bd0cbSSteve Wise 		(void)stop_ep_timer(ep);
1548cfdda9d7SSteve Wise 		abort_connection(ep, skb, GFP_KERNEL);
1549cfdda9d7SSteve Wise 		return;
1550cfdda9d7SSteve Wise 	}
1551cfdda9d7SSteve Wise 	ep->plen = (u8) plen;
1552cfdda9d7SSteve Wise 
1553cfdda9d7SSteve Wise 	/*
1554cfdda9d7SSteve Wise 	 * If we don't have all the pdata yet, then bail.
1555cfdda9d7SSteve Wise 	 */
1556cfdda9d7SSteve Wise 	if (ep->mpa_pkt_len < (sizeof(*mpa) + plen))
1557cfdda9d7SSteve Wise 		return;
1558cfdda9d7SSteve Wise 
1559cfdda9d7SSteve Wise 	/*
1560cfdda9d7SSteve Wise 	 * If we get here we have accumulated the entire mpa
1561cfdda9d7SSteve Wise 	 * start reply message including private data.
1562cfdda9d7SSteve Wise 	 */
1563cfdda9d7SSteve Wise 	ep->mpa_attr.initiator = 0;
1564cfdda9d7SSteve Wise 	ep->mpa_attr.crc_enabled = (mpa->flags & MPA_CRC) | crc_enabled ? 1 : 0;
1565cfdda9d7SSteve Wise 	ep->mpa_attr.recv_marker_enabled = markers_enabled;
1566cfdda9d7SSteve Wise 	ep->mpa_attr.xmit_marker_enabled = mpa->flags & MPA_MARKERS ? 1 : 0;
1567d2fe99e8SKumar Sanghvi 	ep->mpa_attr.version = mpa->revision;
1568d2fe99e8SKumar Sanghvi 	if (mpa->revision == 1)
1569d2fe99e8SKumar Sanghvi 		ep->tried_with_mpa_v1 = 1;
1570d2fe99e8SKumar Sanghvi 	ep->mpa_attr.p2p_type = FW_RI_INIT_P2PTYPE_DISABLED;
1571d2fe99e8SKumar Sanghvi 
1572d2fe99e8SKumar Sanghvi 	if (mpa->revision == 2) {
1573d2fe99e8SKumar Sanghvi 		ep->mpa_attr.enhanced_rdma_conn =
1574d2fe99e8SKumar Sanghvi 			mpa->flags & MPA_ENHANCED_RDMA_CONN ? 1 : 0;
1575d2fe99e8SKumar Sanghvi 		if (ep->mpa_attr.enhanced_rdma_conn) {
1576d2fe99e8SKumar Sanghvi 			mpa_v2_params = (struct mpa_v2_conn_params *)
1577d2fe99e8SKumar Sanghvi 				(ep->mpa_pkt + sizeof(*mpa));
1578d2fe99e8SKumar Sanghvi 			ep->ird = ntohs(mpa_v2_params->ird) &
1579d2fe99e8SKumar Sanghvi 				MPA_V2_IRD_ORD_MASK;
1580d2fe99e8SKumar Sanghvi 			ep->ord = ntohs(mpa_v2_params->ord) &
1581d2fe99e8SKumar Sanghvi 				MPA_V2_IRD_ORD_MASK;
1582d2fe99e8SKumar Sanghvi 			if (ntohs(mpa_v2_params->ird) & MPA_V2_PEER2PEER_MODEL)
1583d2fe99e8SKumar Sanghvi 				if (peer2peer) {
1584d2fe99e8SKumar Sanghvi 					if (ntohs(mpa_v2_params->ord) &
1585d2fe99e8SKumar Sanghvi 							MPA_V2_RDMA_WRITE_RTR)
1586d2fe99e8SKumar Sanghvi 						ep->mpa_attr.p2p_type =
1587d2fe99e8SKumar Sanghvi 						FW_RI_INIT_P2PTYPE_RDMA_WRITE;
1588d2fe99e8SKumar Sanghvi 					else if (ntohs(mpa_v2_params->ord) &
1589d2fe99e8SKumar Sanghvi 							MPA_V2_RDMA_READ_RTR)
1590d2fe99e8SKumar Sanghvi 						ep->mpa_attr.p2p_type =
1591d2fe99e8SKumar Sanghvi 						FW_RI_INIT_P2PTYPE_READ_REQ;
1592d2fe99e8SKumar Sanghvi 				}
1593d2fe99e8SKumar Sanghvi 		}
1594d2fe99e8SKumar Sanghvi 	} else if (mpa->revision == 1)
1595d2fe99e8SKumar Sanghvi 		if (peer2peer)
1596d2fe99e8SKumar Sanghvi 			ep->mpa_attr.p2p_type = p2p_type;
1597d2fe99e8SKumar Sanghvi 
1598cfdda9d7SSteve Wise 	PDBG("%s - crc_enabled=%d, recv_marker_enabled=%d, "
1599cfdda9d7SSteve Wise 	     "xmit_marker_enabled=%d, version=%d p2p_type=%d\n", __func__,
1600cfdda9d7SSteve Wise 	     ep->mpa_attr.crc_enabled, ep->mpa_attr.recv_marker_enabled,
1601cfdda9d7SSteve Wise 	     ep->mpa_attr.xmit_marker_enabled, ep->mpa_attr.version,
1602cfdda9d7SSteve Wise 	     ep->mpa_attr.p2p_type);
1603cfdda9d7SSteve Wise 
1604b33bd0cbSSteve Wise 	/*
1605b33bd0cbSSteve Wise 	 * If the endpoint timer already expired, then we ignore
1606b33bd0cbSSteve Wise 	 * the start request.  process_timeout() will abort
1607b33bd0cbSSteve Wise 	 * the connection.
1608b33bd0cbSSteve Wise 	 */
1609b33bd0cbSSteve Wise 	if (!stop_ep_timer(ep)) {
1610c529fb50SSteve Wise 		__state_set(&ep->com, MPA_REQ_RCVD);
1611cfdda9d7SSteve Wise 
1612cfdda9d7SSteve Wise 		/* drive upcall */
1613be13b2dfSSteve Wise 		mutex_lock(&ep->parent_ep->com.mutex);
1614be13b2dfSSteve Wise 		if (ep->parent_ep->com.state != DEAD) {
1615be13b2dfSSteve Wise 			if (connect_request_upcall(ep))
1616be13b2dfSSteve Wise 				abort_connection(ep, skb, GFP_KERNEL);
1617be13b2dfSSteve Wise 		} else {
1618be13b2dfSSteve Wise 			abort_connection(ep, skb, GFP_KERNEL);
1619be13b2dfSSteve Wise 		}
1620be13b2dfSSteve Wise 		mutex_unlock(&ep->parent_ep->com.mutex);
1621b33bd0cbSSteve Wise 	}
1622cfdda9d7SSteve Wise 	return;
1623cfdda9d7SSteve Wise }
1624cfdda9d7SSteve Wise 
1625cfdda9d7SSteve Wise static int rx_data(struct c4iw_dev *dev, struct sk_buff *skb)
1626cfdda9d7SSteve Wise {
1627cfdda9d7SSteve Wise 	struct c4iw_ep *ep;
1628cfdda9d7SSteve Wise 	struct cpl_rx_data *hdr = cplhdr(skb);
1629cfdda9d7SSteve Wise 	unsigned int dlen = ntohs(hdr->len);
1630cfdda9d7SSteve Wise 	unsigned int tid = GET_TID(hdr);
1631cfdda9d7SSteve Wise 	struct tid_info *t = dev->rdev.lldi.tids;
1632793dad94SVipul Pandya 	__u8 status = hdr->status;
1633cc18b939SSteve Wise 	int disconnect = 0;
1634cfdda9d7SSteve Wise 
1635cfdda9d7SSteve Wise 	ep = lookup_tid(t, tid);
1636977116c6SSteve Wise 	if (!ep)
1637977116c6SSteve Wise 		return 0;
1638cfdda9d7SSteve Wise 	PDBG("%s ep %p tid %u dlen %u\n", __func__, ep, ep->hwtid, dlen);
1639cfdda9d7SSteve Wise 	skb_pull(skb, sizeof(*hdr));
1640cfdda9d7SSteve Wise 	skb_trim(skb, dlen);
1641c529fb50SSteve Wise 	mutex_lock(&ep->com.mutex);
1642cfdda9d7SSteve Wise 
1643cfdda9d7SSteve Wise 	/* update RX credits */
1644cfdda9d7SSteve Wise 	update_rx_credits(ep, dlen);
1645cfdda9d7SSteve Wise 
1646c529fb50SSteve Wise 	switch (ep->com.state) {
1647cfdda9d7SSteve Wise 	case MPA_REQ_SENT:
164855abf8dfSVipul Pandya 		ep->rcv_seq += dlen;
1649cc18b939SSteve Wise 		disconnect = process_mpa_reply(ep, skb);
1650cfdda9d7SSteve Wise 		break;
1651cfdda9d7SSteve Wise 	case MPA_REQ_WAIT:
165255abf8dfSVipul Pandya 		ep->rcv_seq += dlen;
1653cfdda9d7SSteve Wise 		process_mpa_request(ep, skb);
1654cfdda9d7SSteve Wise 		break;
16551557967bSVipul Pandya 	case FPDU_MODE: {
16561557967bSVipul Pandya 		struct c4iw_qp_attributes attrs;
16571557967bSVipul Pandya 		BUG_ON(!ep->com.qp);
1658e8e5b927SVipul Pandya 		if (status)
1659793dad94SVipul Pandya 			pr_err("%s Unexpected streaming data." \
166004236df2SVipul Pandya 			       " qpid %u ep %p state %d tid %u status %d\n",
166104236df2SVipul Pandya 			       __func__, ep->com.qp->wq.sq.qid, ep,
1662c529fb50SSteve Wise 			       ep->com.state, ep->hwtid, status);
166397d7ec0cSSteve Wise 		attrs.next_state = C4IW_QP_STATE_TERMINATE;
166455abf8dfSVipul Pandya 		c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,
1665cc18b939SSteve Wise 			       C4IW_QP_ATTR_NEXT_STATE, &attrs, 1);
1666cc18b939SSteve Wise 		disconnect = 1;
1667cfdda9d7SSteve Wise 		break;
1668cfdda9d7SSteve Wise 	}
16691557967bSVipul Pandya 	default:
16701557967bSVipul Pandya 		break;
16711557967bSVipul Pandya 	}
1672c529fb50SSteve Wise 	mutex_unlock(&ep->com.mutex);
1673cc18b939SSteve Wise 	if (disconnect)
1674cc18b939SSteve Wise 		c4iw_ep_disconnect(ep, 0, GFP_KERNEL);
1675cfdda9d7SSteve Wise 	return 0;
1676cfdda9d7SSteve Wise }
1677cfdda9d7SSteve Wise 
1678cfdda9d7SSteve Wise static int abort_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
1679cfdda9d7SSteve Wise {
1680cfdda9d7SSteve Wise 	struct c4iw_ep *ep;
1681cfdda9d7SSteve Wise 	struct cpl_abort_rpl_rss *rpl = cplhdr(skb);
1682cfdda9d7SSteve Wise 	int release = 0;
1683cfdda9d7SSteve Wise 	unsigned int tid = GET_TID(rpl);
1684cfdda9d7SSteve Wise 	struct tid_info *t = dev->rdev.lldi.tids;
1685cfdda9d7SSteve Wise 
1686cfdda9d7SSteve Wise 	ep = lookup_tid(t, tid);
16874984037bSVipul Pandya 	if (!ep) {
16884984037bSVipul Pandya 		printk(KERN_WARNING MOD "Abort rpl to freed endpoint\n");
16894984037bSVipul Pandya 		return 0;
16904984037bSVipul Pandya 	}
169192dd6c3dSWei Yongjun 	PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
16922f5b48c3SSteve Wise 	mutex_lock(&ep->com.mutex);
1693cfdda9d7SSteve Wise 	switch (ep->com.state) {
1694cfdda9d7SSteve Wise 	case ABORTING:
169591e9c071SVipul Pandya 		c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET);
1696cfdda9d7SSteve Wise 		__state_set(&ep->com, DEAD);
1697cfdda9d7SSteve Wise 		release = 1;
1698cfdda9d7SSteve Wise 		break;
1699cfdda9d7SSteve Wise 	default:
1700cfdda9d7SSteve Wise 		printk(KERN_ERR "%s ep %p state %d\n",
1701cfdda9d7SSteve Wise 		     __func__, ep, ep->com.state);
1702cfdda9d7SSteve Wise 		break;
1703cfdda9d7SSteve Wise 	}
17042f5b48c3SSteve Wise 	mutex_unlock(&ep->com.mutex);
1705cfdda9d7SSteve Wise 
1706cfdda9d7SSteve Wise 	if (release)
1707cfdda9d7SSteve Wise 		release_ep_resources(ep);
1708cfdda9d7SSteve Wise 	return 0;
1709cfdda9d7SSteve Wise }
1710cfdda9d7SSteve Wise 
17115be78ee9SVipul Pandya static void send_fw_act_open_req(struct c4iw_ep *ep, unsigned int atid)
17125be78ee9SVipul Pandya {
17135be78ee9SVipul Pandya 	struct sk_buff *skb;
17145be78ee9SVipul Pandya 	struct fw_ofld_connection_wr *req;
17155be78ee9SVipul Pandya 	unsigned int mtu_idx;
17165be78ee9SVipul Pandya 	int wscale;
1717830662f6SVipul Pandya 	struct sockaddr_in *sin;
1718b408ff28SHariprasad Shenai 	int win;
17195be78ee9SVipul Pandya 
17205be78ee9SVipul Pandya 	skb = get_skb(NULL, sizeof(*req), GFP_KERNEL);
17215be78ee9SVipul Pandya 	req = (struct fw_ofld_connection_wr *)__skb_put(skb, sizeof(*req));
17225be78ee9SVipul Pandya 	memset(req, 0, sizeof(*req));
17235be78ee9SVipul Pandya 	req->op_compl = htonl(V_WR_OP(FW_OFLD_CONNECTION_WR));
17245be78ee9SVipul Pandya 	req->len16_pkd = htonl(FW_WR_LEN16(DIV_ROUND_UP(sizeof(*req), 16)));
172541b4f86cSKumar Sanghvi 	req->le.filter = cpu_to_be32(cxgb4_select_ntuple(
172641b4f86cSKumar Sanghvi 				     ep->com.dev->rdev.lldi.ports[0],
17275be78ee9SVipul Pandya 				     ep->l2t));
17289eccfe10SSteve Wise 	sin = (struct sockaddr_in *)&ep->com.mapped_local_addr;
1729830662f6SVipul Pandya 	req->le.lport = sin->sin_port;
1730830662f6SVipul Pandya 	req->le.u.ipv4.lip = sin->sin_addr.s_addr;
17319eccfe10SSteve Wise 	sin = (struct sockaddr_in *)&ep->com.mapped_remote_addr;
1732830662f6SVipul Pandya 	req->le.pport = sin->sin_port;
1733830662f6SVipul Pandya 	req->le.u.ipv4.pip = sin->sin_addr.s_addr;
17345be78ee9SVipul Pandya 	req->tcb.t_state_to_astid =
17355be78ee9SVipul Pandya 			htonl(V_FW_OFLD_CONNECTION_WR_T_STATE(TCP_SYN_SENT) |
17365be78ee9SVipul Pandya 			V_FW_OFLD_CONNECTION_WR_ASTID(atid));
17375be78ee9SVipul Pandya 	req->tcb.cplrxdataack_cplpassacceptrpl =
17385be78ee9SVipul Pandya 			htons(F_FW_OFLD_CONNECTION_WR_CPLRXDATAACK);
1739ef5d6355SVipul Pandya 	req->tcb.tx_max = (__force __be32) jiffies;
1740793dad94SVipul Pandya 	req->tcb.rcv_adv = htons(1);
174192e7ae71SHariprasad Shenai 	best_mtu(ep->com.dev->rdev.lldi.mtus, ep->mtu, &mtu_idx,
174292e7ae71SHariprasad Shenai 		 enable_tcp_timestamps);
17435be78ee9SVipul Pandya 	wscale = compute_wscale(rcv_win);
1744b408ff28SHariprasad Shenai 
1745b408ff28SHariprasad Shenai 	/*
1746b408ff28SHariprasad Shenai 	 * Specify the largest window that will fit in opt0. The
1747b408ff28SHariprasad Shenai 	 * remainder will be specified in the rx_data_ack.
1748b408ff28SHariprasad Shenai 	 */
1749b408ff28SHariprasad Shenai 	win = ep->rcv_win >> 10;
1750b408ff28SHariprasad Shenai 	if (win > RCV_BUFSIZ_MASK)
1751b408ff28SHariprasad Shenai 		win = RCV_BUFSIZ_MASK;
1752b408ff28SHariprasad Shenai 
1753ef5d6355SVipul Pandya 	req->tcb.opt0 = (__force __be64) (TCAM_BYPASS(1) |
17545be78ee9SVipul Pandya 		(nocong ? NO_CONG(1) : 0) |
17555be78ee9SVipul Pandya 		KEEP_ALIVE(1) |
17565be78ee9SVipul Pandya 		DELACK(1) |
17575be78ee9SVipul Pandya 		WND_SCALE(wscale) |
17585be78ee9SVipul Pandya 		MSS_IDX(mtu_idx) |
17595be78ee9SVipul Pandya 		L2T_IDX(ep->l2t->idx) |
17605be78ee9SVipul Pandya 		TX_CHAN(ep->tx_chan) |
17615be78ee9SVipul Pandya 		SMAC_SEL(ep->smac_idx) |
17625be78ee9SVipul Pandya 		DSCP(ep->tos) |
17635be78ee9SVipul Pandya 		ULP_MODE(ULP_MODE_TCPDDP) |
1764b408ff28SHariprasad Shenai 		RCV_BUFSIZ(win));
1765ef5d6355SVipul Pandya 	req->tcb.opt2 = (__force __be32) (PACE(1) |
17665be78ee9SVipul Pandya 		TX_QUEUE(ep->com.dev->rdev.lldi.tx_modq[ep->tx_chan]) |
17675be78ee9SVipul Pandya 		RX_CHANNEL(0) |
17685be78ee9SVipul Pandya 		CCTRL_ECN(enable_ecn) |
1769ef5d6355SVipul Pandya 		RSS_QUEUE_VALID | RSS_QUEUE(ep->rss_qid));
17705be78ee9SVipul Pandya 	if (enable_tcp_timestamps)
1771ef5d6355SVipul Pandya 		req->tcb.opt2 |= (__force __be32) TSTAMPS_EN(1);
17725be78ee9SVipul Pandya 	if (enable_tcp_sack)
1773ef5d6355SVipul Pandya 		req->tcb.opt2 |= (__force __be32) SACK_EN(1);
17745be78ee9SVipul Pandya 	if (wscale && enable_tcp_window_scaling)
1775ef5d6355SVipul Pandya 		req->tcb.opt2 |= (__force __be32) WND_SCALE_EN(1);
1776ef5d6355SVipul Pandya 	req->tcb.opt0 = cpu_to_be64((__force u64) req->tcb.opt0);
1777ef5d6355SVipul Pandya 	req->tcb.opt2 = cpu_to_be32((__force u32) req->tcb.opt2);
1778793dad94SVipul Pandya 	set_wr_txq(skb, CPL_PRIORITY_CONTROL, ep->ctrlq_idx);
1779793dad94SVipul Pandya 	set_bit(ACT_OFLD_CONN, &ep->com.history);
17805be78ee9SVipul Pandya 	c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t);
17815be78ee9SVipul Pandya }
17825be78ee9SVipul Pandya 
1783cfdda9d7SSteve Wise /*
1784cfdda9d7SSteve Wise  * Return whether a failed active open has allocated a TID
1785cfdda9d7SSteve Wise  */
1786cfdda9d7SSteve Wise static inline int act_open_has_tid(int status)
1787cfdda9d7SSteve Wise {
1788cfdda9d7SSteve Wise 	return status != CPL_ERR_TCAM_FULL && status != CPL_ERR_CONN_EXIST &&
1789cfdda9d7SSteve Wise 	       status != CPL_ERR_ARP_MISS;
1790cfdda9d7SSteve Wise }
1791cfdda9d7SSteve Wise 
17927a2cea2aSSteve Wise /* Returns whether a CPL status conveys negative advice.
17937a2cea2aSSteve Wise  */
17947a2cea2aSSteve Wise static int is_neg_adv(unsigned int status)
17957a2cea2aSSteve Wise {
17967a2cea2aSSteve Wise 	return status == CPL_ERR_RTX_NEG_ADVICE ||
17977a2cea2aSSteve Wise 	       status == CPL_ERR_PERSIST_NEG_ADVICE ||
17987a2cea2aSSteve Wise 	       status == CPL_ERR_KEEPALV_NEG_ADVICE;
17997a2cea2aSSteve Wise }
18007a2cea2aSSteve Wise 
1801b408ff28SHariprasad Shenai static void set_tcp_window(struct c4iw_ep *ep, struct port_info *pi)
1802b408ff28SHariprasad Shenai {
1803b408ff28SHariprasad Shenai 	ep->snd_win = snd_win;
1804b408ff28SHariprasad Shenai 	ep->rcv_win = rcv_win;
1805b408ff28SHariprasad Shenai 	PDBG("%s snd_win %d rcv_win %d\n", __func__, ep->snd_win, ep->rcv_win);
1806b408ff28SHariprasad Shenai }
1807b408ff28SHariprasad Shenai 
1808793dad94SVipul Pandya #define ACT_OPEN_RETRY_COUNT 2
1809793dad94SVipul Pandya 
1810830662f6SVipul Pandya static int import_ep(struct c4iw_ep *ep, int iptype, __u8 *peer_ip,
1811830662f6SVipul Pandya 		     struct dst_entry *dst, struct c4iw_dev *cdev,
1812830662f6SVipul Pandya 		     bool clear_mpa_v1)
1813830662f6SVipul Pandya {
1814830662f6SVipul Pandya 	struct neighbour *n;
1815830662f6SVipul Pandya 	int err, step;
1816830662f6SVipul Pandya 	struct net_device *pdev;
1817830662f6SVipul Pandya 
1818830662f6SVipul Pandya 	n = dst_neigh_lookup(dst, peer_ip);
1819830662f6SVipul Pandya 	if (!n)
1820830662f6SVipul Pandya 		return -ENODEV;
1821830662f6SVipul Pandya 
1822830662f6SVipul Pandya 	rcu_read_lock();
1823830662f6SVipul Pandya 	err = -ENOMEM;
1824830662f6SVipul Pandya 	if (n->dev->flags & IFF_LOOPBACK) {
1825830662f6SVipul Pandya 		if (iptype == 4)
1826830662f6SVipul Pandya 			pdev = ip_dev_find(&init_net, *(__be32 *)peer_ip);
1827830662f6SVipul Pandya 		else if (IS_ENABLED(CONFIG_IPV6))
1828830662f6SVipul Pandya 			for_each_netdev(&init_net, pdev) {
1829830662f6SVipul Pandya 				if (ipv6_chk_addr(&init_net,
1830830662f6SVipul Pandya 						  (struct in6_addr *)peer_ip,
1831830662f6SVipul Pandya 						  pdev, 1))
1832830662f6SVipul Pandya 					break;
1833830662f6SVipul Pandya 			}
1834830662f6SVipul Pandya 		else
1835830662f6SVipul Pandya 			pdev = NULL;
1836830662f6SVipul Pandya 
1837830662f6SVipul Pandya 		if (!pdev) {
1838830662f6SVipul Pandya 			err = -ENODEV;
1839830662f6SVipul Pandya 			goto out;
1840830662f6SVipul Pandya 		}
1841830662f6SVipul Pandya 		ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t,
1842830662f6SVipul Pandya 					n, pdev, 0);
1843830662f6SVipul Pandya 		if (!ep->l2t)
1844830662f6SVipul Pandya 			goto out;
1845830662f6SVipul Pandya 		ep->mtu = pdev->mtu;
1846830662f6SVipul Pandya 		ep->tx_chan = cxgb4_port_chan(pdev);
1847830662f6SVipul Pandya 		ep->smac_idx = (cxgb4_port_viid(pdev) & 0x7F) << 1;
1848830662f6SVipul Pandya 		step = cdev->rdev.lldi.ntxq /
1849830662f6SVipul Pandya 			cdev->rdev.lldi.nchan;
1850830662f6SVipul Pandya 		ep->txq_idx = cxgb4_port_idx(pdev) * step;
1851830662f6SVipul Pandya 		step = cdev->rdev.lldi.nrxq /
1852830662f6SVipul Pandya 			cdev->rdev.lldi.nchan;
1853830662f6SVipul Pandya 		ep->ctrlq_idx = cxgb4_port_idx(pdev);
1854830662f6SVipul Pandya 		ep->rss_qid = cdev->rdev.lldi.rxq_ids[
1855830662f6SVipul Pandya 			cxgb4_port_idx(pdev) * step];
1856b408ff28SHariprasad Shenai 		set_tcp_window(ep, (struct port_info *)netdev_priv(pdev));
1857830662f6SVipul Pandya 		dev_put(pdev);
1858830662f6SVipul Pandya 	} else {
1859830662f6SVipul Pandya 		pdev = get_real_dev(n->dev);
1860830662f6SVipul Pandya 		ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t,
1861830662f6SVipul Pandya 					n, pdev, 0);
1862830662f6SVipul Pandya 		if (!ep->l2t)
1863830662f6SVipul Pandya 			goto out;
1864830662f6SVipul Pandya 		ep->mtu = dst_mtu(dst);
186511b8e22dSSteve Wise 		ep->tx_chan = cxgb4_port_chan(pdev);
186611b8e22dSSteve Wise 		ep->smac_idx = (cxgb4_port_viid(pdev) & 0x7F) << 1;
1867830662f6SVipul Pandya 		step = cdev->rdev.lldi.ntxq /
1868830662f6SVipul Pandya 			cdev->rdev.lldi.nchan;
186911b8e22dSSteve Wise 		ep->txq_idx = cxgb4_port_idx(pdev) * step;
187011b8e22dSSteve Wise 		ep->ctrlq_idx = cxgb4_port_idx(pdev);
1871830662f6SVipul Pandya 		step = cdev->rdev.lldi.nrxq /
1872830662f6SVipul Pandya 			cdev->rdev.lldi.nchan;
1873830662f6SVipul Pandya 		ep->rss_qid = cdev->rdev.lldi.rxq_ids[
187411b8e22dSSteve Wise 			cxgb4_port_idx(pdev) * step];
1875b408ff28SHariprasad Shenai 		set_tcp_window(ep, (struct port_info *)netdev_priv(pdev));
1876830662f6SVipul Pandya 
1877830662f6SVipul Pandya 		if (clear_mpa_v1) {
1878830662f6SVipul Pandya 			ep->retry_with_mpa_v1 = 0;
1879830662f6SVipul Pandya 			ep->tried_with_mpa_v1 = 0;
1880830662f6SVipul Pandya 		}
1881830662f6SVipul Pandya 	}
1882830662f6SVipul Pandya 	err = 0;
1883830662f6SVipul Pandya out:
1884830662f6SVipul Pandya 	rcu_read_unlock();
1885830662f6SVipul Pandya 
1886830662f6SVipul Pandya 	neigh_release(n);
1887830662f6SVipul Pandya 
1888830662f6SVipul Pandya 	return err;
1889830662f6SVipul Pandya }
1890830662f6SVipul Pandya 
1891793dad94SVipul Pandya static int c4iw_reconnect(struct c4iw_ep *ep)
1892793dad94SVipul Pandya {
1893793dad94SVipul Pandya 	int err = 0;
189424d44a39SSteve Wise 	struct sockaddr_in *laddr = (struct sockaddr_in *)
189524d44a39SSteve Wise 				    &ep->com.cm_id->local_addr;
189624d44a39SSteve Wise 	struct sockaddr_in *raddr = (struct sockaddr_in *)
189724d44a39SSteve Wise 				    &ep->com.cm_id->remote_addr;
1898830662f6SVipul Pandya 	struct sockaddr_in6 *laddr6 = (struct sockaddr_in6 *)
1899830662f6SVipul Pandya 				      &ep->com.cm_id->local_addr;
1900830662f6SVipul Pandya 	struct sockaddr_in6 *raddr6 = (struct sockaddr_in6 *)
1901830662f6SVipul Pandya 				      &ep->com.cm_id->remote_addr;
1902830662f6SVipul Pandya 	int iptype;
1903830662f6SVipul Pandya 	__u8 *ra;
1904793dad94SVipul Pandya 
1905793dad94SVipul Pandya 	PDBG("%s qp %p cm_id %p\n", __func__, ep->com.qp, ep->com.cm_id);
1906793dad94SVipul Pandya 	init_timer(&ep->timer);
1907793dad94SVipul Pandya 
1908793dad94SVipul Pandya 	/*
1909793dad94SVipul Pandya 	 * Allocate an active TID to initiate a TCP connection.
1910793dad94SVipul Pandya 	 */
1911793dad94SVipul Pandya 	ep->atid = cxgb4_alloc_atid(ep->com.dev->rdev.lldi.tids, ep);
1912793dad94SVipul Pandya 	if (ep->atid == -1) {
1913793dad94SVipul Pandya 		pr_err("%s - cannot alloc atid.\n", __func__);
1914793dad94SVipul Pandya 		err = -ENOMEM;
1915793dad94SVipul Pandya 		goto fail2;
1916793dad94SVipul Pandya 	}
1917793dad94SVipul Pandya 	insert_handle(ep->com.dev, &ep->com.dev->atid_idr, ep, ep->atid);
1918793dad94SVipul Pandya 
1919793dad94SVipul Pandya 	/* find a route */
1920830662f6SVipul Pandya 	if (ep->com.cm_id->local_addr.ss_family == AF_INET) {
1921830662f6SVipul Pandya 		ep->dst = find_route(ep->com.dev, laddr->sin_addr.s_addr,
1922830662f6SVipul Pandya 				     raddr->sin_addr.s_addr, laddr->sin_port,
1923830662f6SVipul Pandya 				     raddr->sin_port, 0);
1924830662f6SVipul Pandya 		iptype = 4;
1925830662f6SVipul Pandya 		ra = (__u8 *)&raddr->sin_addr;
1926830662f6SVipul Pandya 	} else {
1927830662f6SVipul Pandya 		ep->dst = find_route6(ep->com.dev, laddr6->sin6_addr.s6_addr,
1928830662f6SVipul Pandya 				      raddr6->sin6_addr.s6_addr,
1929830662f6SVipul Pandya 				      laddr6->sin6_port, raddr6->sin6_port, 0,
1930830662f6SVipul Pandya 				      raddr6->sin6_scope_id);
1931830662f6SVipul Pandya 		iptype = 6;
1932830662f6SVipul Pandya 		ra = (__u8 *)&raddr6->sin6_addr;
1933830662f6SVipul Pandya 	}
1934830662f6SVipul Pandya 	if (!ep->dst) {
1935793dad94SVipul Pandya 		pr_err("%s - cannot find route.\n", __func__);
1936793dad94SVipul Pandya 		err = -EHOSTUNREACH;
1937793dad94SVipul Pandya 		goto fail3;
1938793dad94SVipul Pandya 	}
1939830662f6SVipul Pandya 	err = import_ep(ep, iptype, ra, ep->dst, ep->com.dev, false);
1940830662f6SVipul Pandya 	if (err) {
1941793dad94SVipul Pandya 		pr_err("%s - cannot alloc l2e.\n", __func__);
1942793dad94SVipul Pandya 		goto fail4;
1943793dad94SVipul Pandya 	}
1944793dad94SVipul Pandya 
1945793dad94SVipul Pandya 	PDBG("%s txq_idx %u tx_chan %u smac_idx %u rss_qid %u l2t_idx %u\n",
1946793dad94SVipul Pandya 	     __func__, ep->txq_idx, ep->tx_chan, ep->smac_idx, ep->rss_qid,
1947793dad94SVipul Pandya 	     ep->l2t->idx);
1948793dad94SVipul Pandya 
1949793dad94SVipul Pandya 	state_set(&ep->com, CONNECTING);
1950793dad94SVipul Pandya 	ep->tos = 0;
1951793dad94SVipul Pandya 
1952793dad94SVipul Pandya 	/* send connect request to rnic */
1953793dad94SVipul Pandya 	err = send_connect(ep);
1954793dad94SVipul Pandya 	if (!err)
1955793dad94SVipul Pandya 		goto out;
1956793dad94SVipul Pandya 
1957793dad94SVipul Pandya 	cxgb4_l2t_release(ep->l2t);
1958793dad94SVipul Pandya fail4:
1959793dad94SVipul Pandya 	dst_release(ep->dst);
1960793dad94SVipul Pandya fail3:
1961793dad94SVipul Pandya 	remove_handle(ep->com.dev, &ep->com.dev->atid_idr, ep->atid);
1962793dad94SVipul Pandya 	cxgb4_free_atid(ep->com.dev->rdev.lldi.tids, ep->atid);
1963793dad94SVipul Pandya fail2:
1964793dad94SVipul Pandya 	/*
1965793dad94SVipul Pandya 	 * remember to send notification to upper layer.
1966793dad94SVipul Pandya 	 * We are in here so the upper layer is not aware that this is
1967793dad94SVipul Pandya 	 * re-connect attempt and so, upper layer is still waiting for
1968793dad94SVipul Pandya 	 * response of 1st connect request.
1969793dad94SVipul Pandya 	 */
1970793dad94SVipul Pandya 	connect_reply_upcall(ep, -ECONNRESET);
1971793dad94SVipul Pandya 	c4iw_put_ep(&ep->com);
1972793dad94SVipul Pandya out:
1973793dad94SVipul Pandya 	return err;
1974793dad94SVipul Pandya }
1975793dad94SVipul Pandya 
1976cfdda9d7SSteve Wise static int act_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
1977cfdda9d7SSteve Wise {
1978cfdda9d7SSteve Wise 	struct c4iw_ep *ep;
1979cfdda9d7SSteve Wise 	struct cpl_act_open_rpl *rpl = cplhdr(skb);
1980cfdda9d7SSteve Wise 	unsigned int atid = GET_TID_TID(GET_AOPEN_ATID(
1981cfdda9d7SSteve Wise 					ntohl(rpl->atid_status)));
1982cfdda9d7SSteve Wise 	struct tid_info *t = dev->rdev.lldi.tids;
1983cfdda9d7SSteve Wise 	int status = GET_AOPEN_STATUS(ntohl(rpl->atid_status));
1984830662f6SVipul Pandya 	struct sockaddr_in *la;
1985830662f6SVipul Pandya 	struct sockaddr_in *ra;
1986830662f6SVipul Pandya 	struct sockaddr_in6 *la6;
1987830662f6SVipul Pandya 	struct sockaddr_in6 *ra6;
1988cfdda9d7SSteve Wise 
1989cfdda9d7SSteve Wise 	ep = lookup_atid(t, atid);
19909eccfe10SSteve Wise 	la = (struct sockaddr_in *)&ep->com.mapped_local_addr;
19919eccfe10SSteve Wise 	ra = (struct sockaddr_in *)&ep->com.mapped_remote_addr;
19929eccfe10SSteve Wise 	la6 = (struct sockaddr_in6 *)&ep->com.mapped_local_addr;
19939eccfe10SSteve Wise 	ra6 = (struct sockaddr_in6 *)&ep->com.mapped_remote_addr;
1994cfdda9d7SSteve Wise 
1995cfdda9d7SSteve Wise 	PDBG("%s ep %p atid %u status %u errno %d\n", __func__, ep, atid,
1996cfdda9d7SSteve Wise 	     status, status2errno(status));
1997cfdda9d7SSteve Wise 
19987a2cea2aSSteve Wise 	if (is_neg_adv(status)) {
1999cfdda9d7SSteve Wise 		printk(KERN_WARNING MOD "Connection problems for atid %u\n",
2000cfdda9d7SSteve Wise 			atid);
2001cfdda9d7SSteve Wise 		return 0;
2002cfdda9d7SSteve Wise 	}
2003cfdda9d7SSteve Wise 
2004793dad94SVipul Pandya 	set_bit(ACT_OPEN_RPL, &ep->com.history);
2005793dad94SVipul Pandya 
2006d716a2a0SVipul Pandya 	/*
2007d716a2a0SVipul Pandya 	 * Log interesting failures.
2008d716a2a0SVipul Pandya 	 */
2009d716a2a0SVipul Pandya 	switch (status) {
2010d716a2a0SVipul Pandya 	case CPL_ERR_CONN_RESET:
2011d716a2a0SVipul Pandya 	case CPL_ERR_CONN_TIMEDOUT:
2012d716a2a0SVipul Pandya 		break;
20135be78ee9SVipul Pandya 	case CPL_ERR_TCAM_FULL:
20145be78ee9SVipul Pandya 		mutex_lock(&dev->rdev.stats.lock);
2015830662f6SVipul Pandya 		dev->rdev.stats.tcam_full++;
20165be78ee9SVipul Pandya 		mutex_unlock(&dev->rdev.stats.lock);
2017830662f6SVipul Pandya 		if (ep->com.local_addr.ss_family == AF_INET &&
2018830662f6SVipul Pandya 		    dev->rdev.lldi.enable_fw_ofld_conn) {
20195be78ee9SVipul Pandya 			send_fw_act_open_req(ep,
2020793dad94SVipul Pandya 					     GET_TID_TID(GET_AOPEN_ATID(
2021793dad94SVipul Pandya 					     ntohl(rpl->atid_status))));
20225be78ee9SVipul Pandya 			return 0;
2023793dad94SVipul Pandya 		}
2024793dad94SVipul Pandya 		break;
2025793dad94SVipul Pandya 	case CPL_ERR_CONN_EXIST:
2026793dad94SVipul Pandya 		if (ep->retry_count++ < ACT_OPEN_RETRY_COUNT) {
2027793dad94SVipul Pandya 			set_bit(ACT_RETRY_INUSE, &ep->com.history);
2028793dad94SVipul Pandya 			remove_handle(ep->com.dev, &ep->com.dev->atid_idr,
2029793dad94SVipul Pandya 					atid);
2030793dad94SVipul Pandya 			cxgb4_free_atid(t, atid);
2031793dad94SVipul Pandya 			dst_release(ep->dst);
2032793dad94SVipul Pandya 			cxgb4_l2t_release(ep->l2t);
2033793dad94SVipul Pandya 			c4iw_reconnect(ep);
2034793dad94SVipul Pandya 			return 0;
2035793dad94SVipul Pandya 		}
20365be78ee9SVipul Pandya 		break;
2037d716a2a0SVipul Pandya 	default:
2038830662f6SVipul Pandya 		if (ep->com.local_addr.ss_family == AF_INET) {
2039830662f6SVipul Pandya 			pr_info("Active open failure - atid %u status %u errno %d %pI4:%u->%pI4:%u\n",
2040d716a2a0SVipul Pandya 				atid, status, status2errno(status),
2041830662f6SVipul Pandya 				&la->sin_addr.s_addr, ntohs(la->sin_port),
2042830662f6SVipul Pandya 				&ra->sin_addr.s_addr, ntohs(ra->sin_port));
2043830662f6SVipul Pandya 		} else {
2044830662f6SVipul Pandya 			pr_info("Active open failure - atid %u status %u errno %d %pI6:%u->%pI6:%u\n",
2045830662f6SVipul Pandya 				atid, status, status2errno(status),
2046830662f6SVipul Pandya 				la6->sin6_addr.s6_addr, ntohs(la6->sin6_port),
2047830662f6SVipul Pandya 				ra6->sin6_addr.s6_addr, ntohs(ra6->sin6_port));
2048830662f6SVipul Pandya 		}
2049d716a2a0SVipul Pandya 		break;
2050d716a2a0SVipul Pandya 	}
2051d716a2a0SVipul Pandya 
2052cfdda9d7SSteve Wise 	connect_reply_upcall(ep, status2errno(status));
2053cfdda9d7SSteve Wise 	state_set(&ep->com, DEAD);
2054cfdda9d7SSteve Wise 
2055cfdda9d7SSteve Wise 	if (status && act_open_has_tid(status))
2056cfdda9d7SSteve Wise 		cxgb4_remove_tid(ep->com.dev->rdev.lldi.tids, 0, GET_TID(rpl));
2057cfdda9d7SSteve Wise 
2058793dad94SVipul Pandya 	remove_handle(ep->com.dev, &ep->com.dev->atid_idr, atid);
2059cfdda9d7SSteve Wise 	cxgb4_free_atid(t, atid);
2060cfdda9d7SSteve Wise 	dst_release(ep->dst);
2061cfdda9d7SSteve Wise 	cxgb4_l2t_release(ep->l2t);
2062cfdda9d7SSteve Wise 	c4iw_put_ep(&ep->com);
2063cfdda9d7SSteve Wise 
2064cfdda9d7SSteve Wise 	return 0;
2065cfdda9d7SSteve Wise }
2066cfdda9d7SSteve Wise 
2067cfdda9d7SSteve Wise static int pass_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
2068cfdda9d7SSteve Wise {
2069cfdda9d7SSteve Wise 	struct cpl_pass_open_rpl *rpl = cplhdr(skb);
2070cfdda9d7SSteve Wise 	struct tid_info *t = dev->rdev.lldi.tids;
2071cfdda9d7SSteve Wise 	unsigned int stid = GET_TID(rpl);
2072cfdda9d7SSteve Wise 	struct c4iw_listen_ep *ep = lookup_stid(t, stid);
2073cfdda9d7SSteve Wise 
2074cfdda9d7SSteve Wise 	if (!ep) {
20751cab775cSVipul Pandya 		PDBG("%s stid %d lookup failure!\n", __func__, stid);
20761cab775cSVipul Pandya 		goto out;
2077cfdda9d7SSteve Wise 	}
2078cfdda9d7SSteve Wise 	PDBG("%s ep %p status %d error %d\n", __func__, ep,
2079cfdda9d7SSteve Wise 	     rpl->status, status2errno(rpl->status));
2080d9594d99SSteve Wise 	c4iw_wake_up(&ep->com.wr_wait, status2errno(rpl->status));
2081cfdda9d7SSteve Wise 
20821cab775cSVipul Pandya out:
2083cfdda9d7SSteve Wise 	return 0;
2084cfdda9d7SSteve Wise }
2085cfdda9d7SSteve Wise 
2086cfdda9d7SSteve Wise static int close_listsrv_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
2087cfdda9d7SSteve Wise {
2088cfdda9d7SSteve Wise 	struct cpl_close_listsvr_rpl *rpl = cplhdr(skb);
2089cfdda9d7SSteve Wise 	struct tid_info *t = dev->rdev.lldi.tids;
2090cfdda9d7SSteve Wise 	unsigned int stid = GET_TID(rpl);
2091cfdda9d7SSteve Wise 	struct c4iw_listen_ep *ep = lookup_stid(t, stid);
2092cfdda9d7SSteve Wise 
2093cfdda9d7SSteve Wise 	PDBG("%s ep %p\n", __func__, ep);
2094d9594d99SSteve Wise 	c4iw_wake_up(&ep->com.wr_wait, status2errno(rpl->status));
2095cfdda9d7SSteve Wise 	return 0;
2096cfdda9d7SSteve Wise }
2097cfdda9d7SSteve Wise 
2098830662f6SVipul Pandya static void accept_cr(struct c4iw_ep *ep, struct sk_buff *skb,
2099cfdda9d7SSteve Wise 		      struct cpl_pass_accept_req *req)
2100cfdda9d7SSteve Wise {
2101cfdda9d7SSteve Wise 	struct cpl_pass_accept_rpl *rpl;
2102cfdda9d7SSteve Wise 	unsigned int mtu_idx;
2103cfdda9d7SSteve Wise 	u64 opt0;
2104cfdda9d7SSteve Wise 	u32 opt2;
2105cfdda9d7SSteve Wise 	int wscale;
210692e7ae71SHariprasad Shenai 	struct cpl_t5_pass_accept_rpl *rpl5 = NULL;
2107b408ff28SHariprasad Shenai 	int win;
2108cfdda9d7SSteve Wise 
2109cfdda9d7SSteve Wise 	PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
2110cfdda9d7SSteve Wise 	BUG_ON(skb_cloned(skb));
211192e7ae71SHariprasad Shenai 
2112cfdda9d7SSteve Wise 	skb_get(skb);
211392e7ae71SHariprasad Shenai 	rpl = cplhdr(skb);
211492e7ae71SHariprasad Shenai 	if (is_t5(ep->com.dev->rdev.lldi.adapter_type)) {
211592e7ae71SHariprasad Shenai 		skb_trim(skb, roundup(sizeof(*rpl5), 16));
211692e7ae71SHariprasad Shenai 		rpl5 = (void *)rpl;
211792e7ae71SHariprasad Shenai 		INIT_TP_WR(rpl5, ep->hwtid);
211892e7ae71SHariprasad Shenai 	} else {
211992e7ae71SHariprasad Shenai 		skb_trim(skb, sizeof(*rpl));
212092e7ae71SHariprasad Shenai 		INIT_TP_WR(rpl, ep->hwtid);
212192e7ae71SHariprasad Shenai 	}
212292e7ae71SHariprasad Shenai 	OPCODE_TID(rpl) = cpu_to_be32(MK_OPCODE_TID(CPL_PASS_ACCEPT_RPL,
212392e7ae71SHariprasad Shenai 						    ep->hwtid));
212492e7ae71SHariprasad Shenai 
212592e7ae71SHariprasad Shenai 	best_mtu(ep->com.dev->rdev.lldi.mtus, ep->mtu, &mtu_idx,
212692e7ae71SHariprasad Shenai 		 enable_tcp_timestamps && req->tcpopt.tstamp);
2127cfdda9d7SSteve Wise 	wscale = compute_wscale(rcv_win);
2128b408ff28SHariprasad Shenai 
2129b408ff28SHariprasad Shenai 	/*
2130b408ff28SHariprasad Shenai 	 * Specify the largest window that will fit in opt0. The
2131b408ff28SHariprasad Shenai 	 * remainder will be specified in the rx_data_ack.
2132b408ff28SHariprasad Shenai 	 */
2133b408ff28SHariprasad Shenai 	win = ep->rcv_win >> 10;
2134b408ff28SHariprasad Shenai 	if (win > RCV_BUFSIZ_MASK)
2135b408ff28SHariprasad Shenai 		win = RCV_BUFSIZ_MASK;
21365be78ee9SVipul Pandya 	opt0 = (nocong ? NO_CONG(1) : 0) |
21375be78ee9SVipul Pandya 	       KEEP_ALIVE(1) |
2138ba6d3925SSteve Wise 	       DELACK(1) |
2139cfdda9d7SSteve Wise 	       WND_SCALE(wscale) |
2140cfdda9d7SSteve Wise 	       MSS_IDX(mtu_idx) |
2141cfdda9d7SSteve Wise 	       L2T_IDX(ep->l2t->idx) |
2142cfdda9d7SSteve Wise 	       TX_CHAN(ep->tx_chan) |
2143cfdda9d7SSteve Wise 	       SMAC_SEL(ep->smac_idx) |
21445be78ee9SVipul Pandya 	       DSCP(ep->tos >> 2) |
2145b48f3b9cSSteve Wise 	       ULP_MODE(ULP_MODE_TCPDDP) |
2146b408ff28SHariprasad Shenai 	       RCV_BUFSIZ(win);
2147cfdda9d7SSteve Wise 	opt2 = RX_CHANNEL(0) |
2148cfdda9d7SSteve Wise 	       RSS_QUEUE_VALID | RSS_QUEUE(ep->rss_qid);
2149cfdda9d7SSteve Wise 
2150cfdda9d7SSteve Wise 	if (enable_tcp_timestamps && req->tcpopt.tstamp)
2151cfdda9d7SSteve Wise 		opt2 |= TSTAMPS_EN(1);
2152cfdda9d7SSteve Wise 	if (enable_tcp_sack && req->tcpopt.sack)
2153cfdda9d7SSteve Wise 		opt2 |= SACK_EN(1);
2154cfdda9d7SSteve Wise 	if (wscale && enable_tcp_window_scaling)
2155cfdda9d7SSteve Wise 		opt2 |= WND_SCALE_EN(1);
21565be78ee9SVipul Pandya 	if (enable_ecn) {
21575be78ee9SVipul Pandya 		const struct tcphdr *tcph;
21585be78ee9SVipul Pandya 		u32 hlen = ntohl(req->hdr_len);
21595be78ee9SVipul Pandya 
21605be78ee9SVipul Pandya 		tcph = (const void *)(req + 1) + G_ETH_HDR_LEN(hlen) +
21615be78ee9SVipul Pandya 			G_IP_HDR_LEN(hlen);
21625be78ee9SVipul Pandya 		if (tcph->ece && tcph->cwr)
21635be78ee9SVipul Pandya 			opt2 |= CCTRL_ECN(1);
21645be78ee9SVipul Pandya 	}
216592e5011aSSteve Wise 	if (is_t5(ep->com.dev->rdev.lldi.adapter_type)) {
216692e7ae71SHariprasad Shenai 		u32 isn = (prandom_u32() & ~7UL) - 1;
216792e5011aSSteve Wise 		opt2 |= T5_OPT_2_VALID;
216892e5011aSSteve Wise 		opt2 |= V_CONG_CNTRL(CONG_ALG_TAHOE);
216992e7ae71SHariprasad Shenai 		opt2 |= CONG_CNTRL_VALID; /* OPT_2_ISS for T5 */
217092e7ae71SHariprasad Shenai 		rpl5 = (void *)rpl;
217192e7ae71SHariprasad Shenai 		memset(&rpl5->iss, 0, roundup(sizeof(*rpl5)-sizeof(*rpl), 16));
217292e7ae71SHariprasad Shenai 		if (peer2peer)
217392e7ae71SHariprasad Shenai 			isn += 4;
217492e7ae71SHariprasad Shenai 		rpl5->iss = cpu_to_be32(isn);
217592e7ae71SHariprasad Shenai 		PDBG("%s iss %u\n", __func__, be32_to_cpu(rpl5->iss));
217692e5011aSSteve Wise 	}
2177cfdda9d7SSteve Wise 
2178cfdda9d7SSteve Wise 	rpl->opt0 = cpu_to_be64(opt0);
2179cfdda9d7SSteve Wise 	rpl->opt2 = cpu_to_be32(opt2);
2180d4f1a5c6SSteve Wise 	set_wr_txq(skb, CPL_PRIORITY_SETUP, ep->ctrlq_idx);
2181b38a0ad8SSteve Wise 	t4_set_arp_err_handler(skb, NULL, arp_failure_discard);
2182cfdda9d7SSteve Wise 	c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t);
2183cfdda9d7SSteve Wise 
2184cfdda9d7SSteve Wise 	return;
2185cfdda9d7SSteve Wise }
2186cfdda9d7SSteve Wise 
2187830662f6SVipul Pandya static void reject_cr(struct c4iw_dev *dev, u32 hwtid, struct sk_buff *skb)
2188cfdda9d7SSteve Wise {
2189830662f6SVipul Pandya 	PDBG("%s c4iw_dev %p tid %u\n", __func__, dev, hwtid);
2190cfdda9d7SSteve Wise 	BUG_ON(skb_cloned(skb));
2191cfdda9d7SSteve Wise 	skb_trim(skb, sizeof(struct cpl_tid_release));
2192cfdda9d7SSteve Wise 	release_tid(&dev->rdev, hwtid, skb);
2193cfdda9d7SSteve Wise 	return;
2194cfdda9d7SSteve Wise }
2195cfdda9d7SSteve Wise 
2196830662f6SVipul Pandya static void get_4tuple(struct cpl_pass_accept_req *req, int *iptype,
2197830662f6SVipul Pandya 		       __u8 *local_ip, __u8 *peer_ip,
2198cfdda9d7SSteve Wise 		       __be16 *local_port, __be16 *peer_port)
2199cfdda9d7SSteve Wise {
2200cfdda9d7SSteve Wise 	int eth_len = G_ETH_HDR_LEN(be32_to_cpu(req->hdr_len));
2201cfdda9d7SSteve Wise 	int ip_len = G_IP_HDR_LEN(be32_to_cpu(req->hdr_len));
2202cfdda9d7SSteve Wise 	struct iphdr *ip = (struct iphdr *)((u8 *)(req + 1) + eth_len);
2203830662f6SVipul Pandya 	struct ipv6hdr *ip6 = (struct ipv6hdr *)((u8 *)(req + 1) + eth_len);
2204cfdda9d7SSteve Wise 	struct tcphdr *tcp = (struct tcphdr *)
2205cfdda9d7SSteve Wise 			     ((u8 *)(req + 1) + eth_len + ip_len);
2206cfdda9d7SSteve Wise 
2207830662f6SVipul Pandya 	if (ip->version == 4) {
2208cfdda9d7SSteve Wise 		PDBG("%s saddr 0x%x daddr 0x%x sport %u dport %u\n", __func__,
2209cfdda9d7SSteve Wise 		     ntohl(ip->saddr), ntohl(ip->daddr), ntohs(tcp->source),
2210cfdda9d7SSteve Wise 		     ntohs(tcp->dest));
2211830662f6SVipul Pandya 		*iptype = 4;
2212830662f6SVipul Pandya 		memcpy(peer_ip, &ip->saddr, 4);
2213830662f6SVipul Pandya 		memcpy(local_ip, &ip->daddr, 4);
2214830662f6SVipul Pandya 	} else {
2215830662f6SVipul Pandya 		PDBG("%s saddr %pI6 daddr %pI6 sport %u dport %u\n", __func__,
2216830662f6SVipul Pandya 		     ip6->saddr.s6_addr, ip6->daddr.s6_addr, ntohs(tcp->source),
2217830662f6SVipul Pandya 		     ntohs(tcp->dest));
2218830662f6SVipul Pandya 		*iptype = 6;
2219830662f6SVipul Pandya 		memcpy(peer_ip, ip6->saddr.s6_addr, 16);
2220830662f6SVipul Pandya 		memcpy(local_ip, ip6->daddr.s6_addr, 16);
2221830662f6SVipul Pandya 	}
2222cfdda9d7SSteve Wise 	*peer_port = tcp->source;
2223cfdda9d7SSteve Wise 	*local_port = tcp->dest;
2224cfdda9d7SSteve Wise 
2225cfdda9d7SSteve Wise 	return;
2226cfdda9d7SSteve Wise }
2227cfdda9d7SSteve Wise 
2228cfdda9d7SSteve Wise static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb)
2229cfdda9d7SSteve Wise {
2230793dad94SVipul Pandya 	struct c4iw_ep *child_ep = NULL, *parent_ep;
2231cfdda9d7SSteve Wise 	struct cpl_pass_accept_req *req = cplhdr(skb);
2232cfdda9d7SSteve Wise 	unsigned int stid = GET_POPEN_TID(ntohl(req->tos_stid));
2233cfdda9d7SSteve Wise 	struct tid_info *t = dev->rdev.lldi.tids;
2234cfdda9d7SSteve Wise 	unsigned int hwtid = GET_TID(req);
2235cfdda9d7SSteve Wise 	struct dst_entry *dst;
2236830662f6SVipul Pandya 	__u8 local_ip[16], peer_ip[16];
2237cfdda9d7SSteve Wise 	__be16 local_port, peer_port;
22383786cf18SDavid Miller 	int err;
22391cab775cSVipul Pandya 	u16 peer_mss = ntohs(req->tcpopt.mss);
2240830662f6SVipul Pandya 	int iptype;
224192e7ae71SHariprasad Shenai 	unsigned short hdrs;
2242cfdda9d7SSteve Wise 
2243cfdda9d7SSteve Wise 	parent_ep = lookup_stid(t, stid);
22441cab775cSVipul Pandya 	if (!parent_ep) {
22451cab775cSVipul Pandya 		PDBG("%s connect request on invalid stid %d\n", __func__, stid);
22461cab775cSVipul Pandya 		goto reject;
22471cab775cSVipul Pandya 	}
22481cab775cSVipul Pandya 
2249cfdda9d7SSteve Wise 	if (state_read(&parent_ep->com) != LISTEN) {
2250cfdda9d7SSteve Wise 		printk(KERN_ERR "%s - listening ep not in LISTEN\n",
2251cfdda9d7SSteve Wise 		       __func__);
2252cfdda9d7SSteve Wise 		goto reject;
2253cfdda9d7SSteve Wise 	}
2254cfdda9d7SSteve Wise 
2255830662f6SVipul Pandya 	get_4tuple(req, &iptype, local_ip, peer_ip, &local_port, &peer_port);
2256830662f6SVipul Pandya 
2257cfdda9d7SSteve Wise 	/* Find output route */
2258830662f6SVipul Pandya 	if (iptype == 4)  {
2259830662f6SVipul Pandya 		PDBG("%s parent ep %p hwtid %u laddr %pI4 raddr %pI4 lport %d rport %d peer_mss %d\n"
2260830662f6SVipul Pandya 		     , __func__, parent_ep, hwtid,
2261830662f6SVipul Pandya 		     local_ip, peer_ip, ntohs(local_port),
2262830662f6SVipul Pandya 		     ntohs(peer_port), peer_mss);
2263830662f6SVipul Pandya 		dst = find_route(dev, *(__be32 *)local_ip, *(__be32 *)peer_ip,
2264830662f6SVipul Pandya 				 local_port, peer_port,
2265cfdda9d7SSteve Wise 				 GET_POPEN_TOS(ntohl(req->tos_stid)));
2266830662f6SVipul Pandya 	} else {
2267830662f6SVipul Pandya 		PDBG("%s parent ep %p hwtid %u laddr %pI6 raddr %pI6 lport %d rport %d peer_mss %d\n"
2268830662f6SVipul Pandya 		     , __func__, parent_ep, hwtid,
2269830662f6SVipul Pandya 		     local_ip, peer_ip, ntohs(local_port),
2270830662f6SVipul Pandya 		     ntohs(peer_port), peer_mss);
2271830662f6SVipul Pandya 		dst = find_route6(dev, local_ip, peer_ip, local_port, peer_port,
2272830662f6SVipul Pandya 				  PASS_OPEN_TOS(ntohl(req->tos_stid)),
2273830662f6SVipul Pandya 				  ((struct sockaddr_in6 *)
2274830662f6SVipul Pandya 				  &parent_ep->com.local_addr)->sin6_scope_id);
2275830662f6SVipul Pandya 	}
2276830662f6SVipul Pandya 	if (!dst) {
2277cfdda9d7SSteve Wise 		printk(KERN_ERR MOD "%s - failed to find dst entry!\n",
2278cfdda9d7SSteve Wise 		       __func__);
2279cfdda9d7SSteve Wise 		goto reject;
2280cfdda9d7SSteve Wise 	}
2281cfdda9d7SSteve Wise 
2282cfdda9d7SSteve Wise 	child_ep = alloc_ep(sizeof(*child_ep), GFP_KERNEL);
2283cfdda9d7SSteve Wise 	if (!child_ep) {
2284cfdda9d7SSteve Wise 		printk(KERN_ERR MOD "%s - failed to allocate ep entry!\n",
2285cfdda9d7SSteve Wise 		       __func__);
2286cfdda9d7SSteve Wise 		dst_release(dst);
2287cfdda9d7SSteve Wise 		goto reject;
2288cfdda9d7SSteve Wise 	}
22893786cf18SDavid Miller 
2290830662f6SVipul Pandya 	err = import_ep(child_ep, iptype, peer_ip, dst, dev, false);
22913786cf18SDavid Miller 	if (err) {
22923786cf18SDavid Miller 		printk(KERN_ERR MOD "%s - failed to allocate l2t entry!\n",
22933786cf18SDavid Miller 		       __func__);
22943786cf18SDavid Miller 		dst_release(dst);
22953786cf18SDavid Miller 		kfree(child_ep);
22963786cf18SDavid Miller 		goto reject;
22973786cf18SDavid Miller 	}
22983786cf18SDavid Miller 
229992e7ae71SHariprasad Shenai 	hdrs = sizeof(struct iphdr) + sizeof(struct tcphdr) +
230092e7ae71SHariprasad Shenai 	       ((enable_tcp_timestamps && req->tcpopt.tstamp) ? 12 : 0);
230192e7ae71SHariprasad Shenai 	if (peer_mss && child_ep->mtu > (peer_mss + hdrs))
230292e7ae71SHariprasad Shenai 		child_ep->mtu = peer_mss + hdrs;
23031cab775cSVipul Pandya 
2304cfdda9d7SSteve Wise 	state_set(&child_ep->com, CONNECTING);
2305cfdda9d7SSteve Wise 	child_ep->com.dev = dev;
2306cfdda9d7SSteve Wise 	child_ep->com.cm_id = NULL;
2307830662f6SVipul Pandya 	if (iptype == 4) {
2308830662f6SVipul Pandya 		struct sockaddr_in *sin = (struct sockaddr_in *)
2309830662f6SVipul Pandya 			&child_ep->com.local_addr;
2310830662f6SVipul Pandya 		sin->sin_family = PF_INET;
2311830662f6SVipul Pandya 		sin->sin_port = local_port;
2312830662f6SVipul Pandya 		sin->sin_addr.s_addr = *(__be32 *)local_ip;
2313830662f6SVipul Pandya 		sin = (struct sockaddr_in *)&child_ep->com.remote_addr;
2314830662f6SVipul Pandya 		sin->sin_family = PF_INET;
2315830662f6SVipul Pandya 		sin->sin_port = peer_port;
2316830662f6SVipul Pandya 		sin->sin_addr.s_addr = *(__be32 *)peer_ip;
2317830662f6SVipul Pandya 	} else {
2318830662f6SVipul Pandya 		struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)
2319830662f6SVipul Pandya 			&child_ep->com.local_addr;
2320830662f6SVipul Pandya 		sin6->sin6_family = PF_INET6;
2321830662f6SVipul Pandya 		sin6->sin6_port = local_port;
2322830662f6SVipul Pandya 		memcpy(sin6->sin6_addr.s6_addr, local_ip, 16);
2323830662f6SVipul Pandya 		sin6 = (struct sockaddr_in6 *)&child_ep->com.remote_addr;
2324830662f6SVipul Pandya 		sin6->sin6_family = PF_INET6;
2325830662f6SVipul Pandya 		sin6->sin6_port = peer_port;
2326830662f6SVipul Pandya 		memcpy(sin6->sin6_addr.s6_addr, peer_ip, 16);
2327830662f6SVipul Pandya 	}
2328cfdda9d7SSteve Wise 	c4iw_get_ep(&parent_ep->com);
2329cfdda9d7SSteve Wise 	child_ep->parent_ep = parent_ep;
2330cfdda9d7SSteve Wise 	child_ep->tos = GET_POPEN_TOS(ntohl(req->tos_stid));
2331cfdda9d7SSteve Wise 	child_ep->dst = dst;
2332cfdda9d7SSteve Wise 	child_ep->hwtid = hwtid;
2333cfdda9d7SSteve Wise 
2334cfdda9d7SSteve Wise 	PDBG("%s tx_chan %u smac_idx %u rss_qid %u\n", __func__,
23353786cf18SDavid Miller 	     child_ep->tx_chan, child_ep->smac_idx, child_ep->rss_qid);
2336cfdda9d7SSteve Wise 
2337cfdda9d7SSteve Wise 	init_timer(&child_ep->timer);
2338cfdda9d7SSteve Wise 	cxgb4_insert_tid(t, child_ep, hwtid);
2339b3de6cfeSVipul Pandya 	insert_handle(dev, &dev->hwtid_idr, child_ep, child_ep->hwtid);
2340830662f6SVipul Pandya 	accept_cr(child_ep, skb, req);
2341793dad94SVipul Pandya 	set_bit(PASS_ACCEPT_REQ, &child_ep->com.history);
2342cfdda9d7SSteve Wise 	goto out;
2343cfdda9d7SSteve Wise reject:
2344830662f6SVipul Pandya 	reject_cr(dev, hwtid, skb);
2345cfdda9d7SSteve Wise out:
2346cfdda9d7SSteve Wise 	return 0;
2347cfdda9d7SSteve Wise }
2348cfdda9d7SSteve Wise 
2349cfdda9d7SSteve Wise static int pass_establish(struct c4iw_dev *dev, struct sk_buff *skb)
2350cfdda9d7SSteve Wise {
2351cfdda9d7SSteve Wise 	struct c4iw_ep *ep;
2352cfdda9d7SSteve Wise 	struct cpl_pass_establish *req = cplhdr(skb);
2353cfdda9d7SSteve Wise 	struct tid_info *t = dev->rdev.lldi.tids;
2354cfdda9d7SSteve Wise 	unsigned int tid = GET_TID(req);
2355cfdda9d7SSteve Wise 
2356cfdda9d7SSteve Wise 	ep = lookup_tid(t, tid);
2357cfdda9d7SSteve Wise 	PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
2358cfdda9d7SSteve Wise 	ep->snd_seq = be32_to_cpu(req->snd_isn);
2359cfdda9d7SSteve Wise 	ep->rcv_seq = be32_to_cpu(req->rcv_isn);
2360cfdda9d7SSteve Wise 
23611cab775cSVipul Pandya 	PDBG("%s ep %p hwtid %u tcp_opt 0x%02x\n", __func__, ep, tid,
23621cab775cSVipul Pandya 	     ntohs(req->tcp_opt));
23631cab775cSVipul Pandya 
2364cfdda9d7SSteve Wise 	set_emss(ep, ntohs(req->tcp_opt));
2365cfdda9d7SSteve Wise 
2366cfdda9d7SSteve Wise 	dst_confirm(ep->dst);
2367cfdda9d7SSteve Wise 	state_set(&ep->com, MPA_REQ_WAIT);
2368cfdda9d7SSteve Wise 	start_ep_timer(ep);
2369cfdda9d7SSteve Wise 	send_flowc(ep, skb);
2370793dad94SVipul Pandya 	set_bit(PASS_ESTAB, &ep->com.history);
2371cfdda9d7SSteve Wise 
2372cfdda9d7SSteve Wise 	return 0;
2373cfdda9d7SSteve Wise }
2374cfdda9d7SSteve Wise 
2375cfdda9d7SSteve Wise static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb)
2376cfdda9d7SSteve Wise {
2377cfdda9d7SSteve Wise 	struct cpl_peer_close *hdr = cplhdr(skb);
2378cfdda9d7SSteve Wise 	struct c4iw_ep *ep;
2379cfdda9d7SSteve Wise 	struct c4iw_qp_attributes attrs;
2380cfdda9d7SSteve Wise 	int disconnect = 1;
2381cfdda9d7SSteve Wise 	int release = 0;
2382cfdda9d7SSteve Wise 	struct tid_info *t = dev->rdev.lldi.tids;
2383cfdda9d7SSteve Wise 	unsigned int tid = GET_TID(hdr);
23848da7e7a5SSteve Wise 	int ret;
2385cfdda9d7SSteve Wise 
2386cfdda9d7SSteve Wise 	ep = lookup_tid(t, tid);
2387cfdda9d7SSteve Wise 	PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
2388cfdda9d7SSteve Wise 	dst_confirm(ep->dst);
2389cfdda9d7SSteve Wise 
2390793dad94SVipul Pandya 	set_bit(PEER_CLOSE, &ep->com.history);
23912f5b48c3SSteve Wise 	mutex_lock(&ep->com.mutex);
2392cfdda9d7SSteve Wise 	switch (ep->com.state) {
2393cfdda9d7SSteve Wise 	case MPA_REQ_WAIT:
2394cfdda9d7SSteve Wise 		__state_set(&ep->com, CLOSING);
2395cfdda9d7SSteve Wise 		break;
2396cfdda9d7SSteve Wise 	case MPA_REQ_SENT:
2397cfdda9d7SSteve Wise 		__state_set(&ep->com, CLOSING);
2398cfdda9d7SSteve Wise 		connect_reply_upcall(ep, -ECONNRESET);
2399cfdda9d7SSteve Wise 		break;
2400cfdda9d7SSteve Wise 	case MPA_REQ_RCVD:
2401cfdda9d7SSteve Wise 
2402cfdda9d7SSteve Wise 		/*
2403cfdda9d7SSteve Wise 		 * We're gonna mark this puppy DEAD, but keep
2404cfdda9d7SSteve Wise 		 * the reference on it until the ULP accepts or
2405cfdda9d7SSteve Wise 		 * rejects the CR. Also wake up anyone waiting
2406cfdda9d7SSteve Wise 		 * in rdma connection migration (see c4iw_accept_cr()).
2407cfdda9d7SSteve Wise 		 */
2408cfdda9d7SSteve Wise 		__state_set(&ep->com, CLOSING);
2409cfdda9d7SSteve Wise 		PDBG("waking up ep %p tid %u\n", ep, ep->hwtid);
2410d9594d99SSteve Wise 		c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET);
2411cfdda9d7SSteve Wise 		break;
2412cfdda9d7SSteve Wise 	case MPA_REP_SENT:
2413cfdda9d7SSteve Wise 		__state_set(&ep->com, CLOSING);
2414cfdda9d7SSteve Wise 		PDBG("waking up ep %p tid %u\n", ep, ep->hwtid);
2415d9594d99SSteve Wise 		c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET);
2416cfdda9d7SSteve Wise 		break;
2417cfdda9d7SSteve Wise 	case FPDU_MODE:
2418ca5a2202SSteve Wise 		start_ep_timer(ep);
2419cfdda9d7SSteve Wise 		__state_set(&ep->com, CLOSING);
242030c95c2dSSteve Wise 		attrs.next_state = C4IW_QP_STATE_CLOSING;
24218da7e7a5SSteve Wise 		ret = c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,
242230c95c2dSSteve Wise 				       C4IW_QP_ATTR_NEXT_STATE, &attrs, 1);
24238da7e7a5SSteve Wise 		if (ret != -ECONNRESET) {
2424cfdda9d7SSteve Wise 			peer_close_upcall(ep);
242530c95c2dSSteve Wise 			disconnect = 1;
24268da7e7a5SSteve Wise 		}
2427cfdda9d7SSteve Wise 		break;
2428cfdda9d7SSteve Wise 	case ABORTING:
2429cfdda9d7SSteve Wise 		disconnect = 0;
2430cfdda9d7SSteve Wise 		break;
2431cfdda9d7SSteve Wise 	case CLOSING:
2432cfdda9d7SSteve Wise 		__state_set(&ep->com, MORIBUND);
2433cfdda9d7SSteve Wise 		disconnect = 0;
2434cfdda9d7SSteve Wise 		break;
2435cfdda9d7SSteve Wise 	case MORIBUND:
2436b33bd0cbSSteve Wise 		(void)stop_ep_timer(ep);
2437cfdda9d7SSteve Wise 		if (ep->com.cm_id && ep->com.qp) {
2438cfdda9d7SSteve Wise 			attrs.next_state = C4IW_QP_STATE_IDLE;
2439cfdda9d7SSteve Wise 			c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,
2440cfdda9d7SSteve Wise 				       C4IW_QP_ATTR_NEXT_STATE, &attrs, 1);
2441cfdda9d7SSteve Wise 		}
2442be13b2dfSSteve Wise 		close_complete_upcall(ep, 0);
2443cfdda9d7SSteve Wise 		__state_set(&ep->com, DEAD);
2444cfdda9d7SSteve Wise 		release = 1;
2445cfdda9d7SSteve Wise 		disconnect = 0;
2446cfdda9d7SSteve Wise 		break;
2447cfdda9d7SSteve Wise 	case DEAD:
2448cfdda9d7SSteve Wise 		disconnect = 0;
2449cfdda9d7SSteve Wise 		break;
2450cfdda9d7SSteve Wise 	default:
2451cfdda9d7SSteve Wise 		BUG_ON(1);
2452cfdda9d7SSteve Wise 	}
24532f5b48c3SSteve Wise 	mutex_unlock(&ep->com.mutex);
2454cfdda9d7SSteve Wise 	if (disconnect)
2455cfdda9d7SSteve Wise 		c4iw_ep_disconnect(ep, 0, GFP_KERNEL);
2456cfdda9d7SSteve Wise 	if (release)
2457cfdda9d7SSteve Wise 		release_ep_resources(ep);
2458cfdda9d7SSteve Wise 	return 0;
2459cfdda9d7SSteve Wise }
2460cfdda9d7SSteve Wise 
2461cfdda9d7SSteve Wise static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb)
2462cfdda9d7SSteve Wise {
2463cfdda9d7SSteve Wise 	struct cpl_abort_req_rss *req = cplhdr(skb);
2464cfdda9d7SSteve Wise 	struct c4iw_ep *ep;
2465cfdda9d7SSteve Wise 	struct cpl_abort_rpl *rpl;
2466cfdda9d7SSteve Wise 	struct sk_buff *rpl_skb;
2467cfdda9d7SSteve Wise 	struct c4iw_qp_attributes attrs;
2468cfdda9d7SSteve Wise 	int ret;
2469cfdda9d7SSteve Wise 	int release = 0;
2470cfdda9d7SSteve Wise 	struct tid_info *t = dev->rdev.lldi.tids;
2471cfdda9d7SSteve Wise 	unsigned int tid = GET_TID(req);
2472cfdda9d7SSteve Wise 
2473cfdda9d7SSteve Wise 	ep = lookup_tid(t, tid);
24747a2cea2aSSteve Wise 	if (is_neg_adv(req->status)) {
2475cfdda9d7SSteve Wise 		PDBG("%s neg_adv_abort ep %p tid %u\n", __func__, ep,
2476cfdda9d7SSteve Wise 		     ep->hwtid);
2477cfdda9d7SSteve Wise 		return 0;
2478cfdda9d7SSteve Wise 	}
2479cfdda9d7SSteve Wise 	PDBG("%s ep %p tid %u state %u\n", __func__, ep, ep->hwtid,
2480cfdda9d7SSteve Wise 	     ep->com.state);
2481793dad94SVipul Pandya 	set_bit(PEER_ABORT, &ep->com.history);
24822f5b48c3SSteve Wise 
24832f5b48c3SSteve Wise 	/*
24842f5b48c3SSteve Wise 	 * Wake up any threads in rdma_init() or rdma_fini().
2485d2fe99e8SKumar Sanghvi 	 * However, this is not needed if com state is just
2486d2fe99e8SKumar Sanghvi 	 * MPA_REQ_SENT
24872f5b48c3SSteve Wise 	 */
2488d2fe99e8SKumar Sanghvi 	if (ep->com.state != MPA_REQ_SENT)
2489d9594d99SSteve Wise 		c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET);
24902f5b48c3SSteve Wise 
24912f5b48c3SSteve Wise 	mutex_lock(&ep->com.mutex);
2492cfdda9d7SSteve Wise 	switch (ep->com.state) {
2493cfdda9d7SSteve Wise 	case CONNECTING:
2494cfdda9d7SSteve Wise 		break;
2495cfdda9d7SSteve Wise 	case MPA_REQ_WAIT:
2496b33bd0cbSSteve Wise 		(void)stop_ep_timer(ep);
2497cfdda9d7SSteve Wise 		break;
2498cfdda9d7SSteve Wise 	case MPA_REQ_SENT:
2499b33bd0cbSSteve Wise 		(void)stop_ep_timer(ep);
2500fe7e0a4dSVipul Pandya 		if (mpa_rev == 1 || (mpa_rev == 2 && ep->tried_with_mpa_v1))
2501cfdda9d7SSteve Wise 			connect_reply_upcall(ep, -ECONNRESET);
2502d2fe99e8SKumar Sanghvi 		else {
2503d2fe99e8SKumar Sanghvi 			/*
2504d2fe99e8SKumar Sanghvi 			 * we just don't send notification upwards because we
2505d2fe99e8SKumar Sanghvi 			 * want to retry with mpa_v1 without upper layers even
2506d2fe99e8SKumar Sanghvi 			 * knowing it.
2507d2fe99e8SKumar Sanghvi 			 *
2508d2fe99e8SKumar Sanghvi 			 * do some housekeeping so as to re-initiate the
2509d2fe99e8SKumar Sanghvi 			 * connection
2510d2fe99e8SKumar Sanghvi 			 */
2511d2fe99e8SKumar Sanghvi 			PDBG("%s: mpa_rev=%d. Retrying with mpav1\n", __func__,
2512d2fe99e8SKumar Sanghvi 			     mpa_rev);
2513d2fe99e8SKumar Sanghvi 			ep->retry_with_mpa_v1 = 1;
2514d2fe99e8SKumar Sanghvi 		}
2515cfdda9d7SSteve Wise 		break;
2516cfdda9d7SSteve Wise 	case MPA_REP_SENT:
2517cfdda9d7SSteve Wise 		break;
2518cfdda9d7SSteve Wise 	case MPA_REQ_RCVD:
2519cfdda9d7SSteve Wise 		break;
2520cfdda9d7SSteve Wise 	case MORIBUND:
2521cfdda9d7SSteve Wise 	case CLOSING:
2522ca5a2202SSteve Wise 		stop_ep_timer(ep);
2523cfdda9d7SSteve Wise 		/*FALLTHROUGH*/
2524cfdda9d7SSteve Wise 	case FPDU_MODE:
2525cfdda9d7SSteve Wise 		if (ep->com.cm_id && ep->com.qp) {
2526cfdda9d7SSteve Wise 			attrs.next_state = C4IW_QP_STATE_ERROR;
2527cfdda9d7SSteve Wise 			ret = c4iw_modify_qp(ep->com.qp->rhp,
2528cfdda9d7SSteve Wise 				     ep->com.qp, C4IW_QP_ATTR_NEXT_STATE,
2529cfdda9d7SSteve Wise 				     &attrs, 1);
2530cfdda9d7SSteve Wise 			if (ret)
2531cfdda9d7SSteve Wise 				printk(KERN_ERR MOD
2532cfdda9d7SSteve Wise 				       "%s - qp <- error failed!\n",
2533cfdda9d7SSteve Wise 				       __func__);
2534cfdda9d7SSteve Wise 		}
2535cfdda9d7SSteve Wise 		peer_abort_upcall(ep);
2536cfdda9d7SSteve Wise 		break;
2537cfdda9d7SSteve Wise 	case ABORTING:
2538cfdda9d7SSteve Wise 		break;
2539cfdda9d7SSteve Wise 	case DEAD:
2540cfdda9d7SSteve Wise 		PDBG("%s PEER_ABORT IN DEAD STATE!!!!\n", __func__);
25412f5b48c3SSteve Wise 		mutex_unlock(&ep->com.mutex);
2542cfdda9d7SSteve Wise 		return 0;
2543cfdda9d7SSteve Wise 	default:
2544cfdda9d7SSteve Wise 		BUG_ON(1);
2545cfdda9d7SSteve Wise 		break;
2546cfdda9d7SSteve Wise 	}
2547cfdda9d7SSteve Wise 	dst_confirm(ep->dst);
2548cfdda9d7SSteve Wise 	if (ep->com.state != ABORTING) {
2549cfdda9d7SSteve Wise 		__state_set(&ep->com, DEAD);
2550d2fe99e8SKumar Sanghvi 		/* we don't release if we want to retry with mpa_v1 */
2551d2fe99e8SKumar Sanghvi 		if (!ep->retry_with_mpa_v1)
2552cfdda9d7SSteve Wise 			release = 1;
2553cfdda9d7SSteve Wise 	}
25542f5b48c3SSteve Wise 	mutex_unlock(&ep->com.mutex);
2555cfdda9d7SSteve Wise 
2556cfdda9d7SSteve Wise 	rpl_skb = get_skb(skb, sizeof(*rpl), GFP_KERNEL);
2557cfdda9d7SSteve Wise 	if (!rpl_skb) {
2558cfdda9d7SSteve Wise 		printk(KERN_ERR MOD "%s - cannot allocate skb!\n",
2559cfdda9d7SSteve Wise 		       __func__);
2560cfdda9d7SSteve Wise 		release = 1;
2561cfdda9d7SSteve Wise 		goto out;
2562cfdda9d7SSteve Wise 	}
2563cfdda9d7SSteve Wise 	set_wr_txq(skb, CPL_PRIORITY_DATA, ep->txq_idx);
2564cfdda9d7SSteve Wise 	rpl = (struct cpl_abort_rpl *) skb_put(rpl_skb, sizeof(*rpl));
2565cfdda9d7SSteve Wise 	INIT_TP_WR(rpl, ep->hwtid);
2566cfdda9d7SSteve Wise 	OPCODE_TID(rpl) = cpu_to_be32(MK_OPCODE_TID(CPL_ABORT_RPL, ep->hwtid));
2567cfdda9d7SSteve Wise 	rpl->cmd = CPL_ABORT_NO_RST;
2568cfdda9d7SSteve Wise 	c4iw_ofld_send(&ep->com.dev->rdev, rpl_skb);
2569cfdda9d7SSteve Wise out:
2570cfdda9d7SSteve Wise 	if (release)
2571cfdda9d7SSteve Wise 		release_ep_resources(ep);
2572fe7e0a4dSVipul Pandya 	else if (ep->retry_with_mpa_v1) {
2573fe7e0a4dSVipul Pandya 		remove_handle(ep->com.dev, &ep->com.dev->hwtid_idr, ep->hwtid);
2574d2fe99e8SKumar Sanghvi 		cxgb4_remove_tid(ep->com.dev->rdev.lldi.tids, 0, ep->hwtid);
2575d2fe99e8SKumar Sanghvi 		dst_release(ep->dst);
2576d2fe99e8SKumar Sanghvi 		cxgb4_l2t_release(ep->l2t);
2577d2fe99e8SKumar Sanghvi 		c4iw_reconnect(ep);
2578d2fe99e8SKumar Sanghvi 	}
2579d2fe99e8SKumar Sanghvi 
2580cfdda9d7SSteve Wise 	return 0;
2581cfdda9d7SSteve Wise }
2582cfdda9d7SSteve Wise 
2583cfdda9d7SSteve Wise static int close_con_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
2584cfdda9d7SSteve Wise {
2585cfdda9d7SSteve Wise 	struct c4iw_ep *ep;
2586cfdda9d7SSteve Wise 	struct c4iw_qp_attributes attrs;
2587cfdda9d7SSteve Wise 	struct cpl_close_con_rpl *rpl = cplhdr(skb);
2588cfdda9d7SSteve Wise 	int release = 0;
2589cfdda9d7SSteve Wise 	struct tid_info *t = dev->rdev.lldi.tids;
2590cfdda9d7SSteve Wise 	unsigned int tid = GET_TID(rpl);
2591cfdda9d7SSteve Wise 
2592cfdda9d7SSteve Wise 	ep = lookup_tid(t, tid);
2593cfdda9d7SSteve Wise 
2594cfdda9d7SSteve Wise 	PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
2595cfdda9d7SSteve Wise 	BUG_ON(!ep);
2596cfdda9d7SSteve Wise 
2597cfdda9d7SSteve Wise 	/* The cm_id may be null if we failed to connect */
25982f5b48c3SSteve Wise 	mutex_lock(&ep->com.mutex);
2599cfdda9d7SSteve Wise 	switch (ep->com.state) {
2600cfdda9d7SSteve Wise 	case CLOSING:
2601cfdda9d7SSteve Wise 		__state_set(&ep->com, MORIBUND);
2602cfdda9d7SSteve Wise 		break;
2603cfdda9d7SSteve Wise 	case MORIBUND:
2604b33bd0cbSSteve Wise 		(void)stop_ep_timer(ep);
2605cfdda9d7SSteve Wise 		if ((ep->com.cm_id) && (ep->com.qp)) {
2606cfdda9d7SSteve Wise 			attrs.next_state = C4IW_QP_STATE_IDLE;
2607cfdda9d7SSteve Wise 			c4iw_modify_qp(ep->com.qp->rhp,
2608cfdda9d7SSteve Wise 					     ep->com.qp,
2609cfdda9d7SSteve Wise 					     C4IW_QP_ATTR_NEXT_STATE,
2610cfdda9d7SSteve Wise 					     &attrs, 1);
2611cfdda9d7SSteve Wise 		}
2612be13b2dfSSteve Wise 		close_complete_upcall(ep, 0);
2613cfdda9d7SSteve Wise 		__state_set(&ep->com, DEAD);
2614cfdda9d7SSteve Wise 		release = 1;
2615cfdda9d7SSteve Wise 		break;
2616cfdda9d7SSteve Wise 	case ABORTING:
2617cfdda9d7SSteve Wise 	case DEAD:
2618cfdda9d7SSteve Wise 		break;
2619cfdda9d7SSteve Wise 	default:
2620cfdda9d7SSteve Wise 		BUG_ON(1);
2621cfdda9d7SSteve Wise 		break;
2622cfdda9d7SSteve Wise 	}
26232f5b48c3SSteve Wise 	mutex_unlock(&ep->com.mutex);
2624cfdda9d7SSteve Wise 	if (release)
2625cfdda9d7SSteve Wise 		release_ep_resources(ep);
2626cfdda9d7SSteve Wise 	return 0;
2627cfdda9d7SSteve Wise }
2628cfdda9d7SSteve Wise 
2629cfdda9d7SSteve Wise static int terminate(struct c4iw_dev *dev, struct sk_buff *skb)
2630cfdda9d7SSteve Wise {
26310e42c1f4SSteve Wise 	struct cpl_rdma_terminate *rpl = cplhdr(skb);
2632cfdda9d7SSteve Wise 	struct tid_info *t = dev->rdev.lldi.tids;
26330e42c1f4SSteve Wise 	unsigned int tid = GET_TID(rpl);
26340e42c1f4SSteve Wise 	struct c4iw_ep *ep;
26350e42c1f4SSteve Wise 	struct c4iw_qp_attributes attrs;
2636cfdda9d7SSteve Wise 
2637cfdda9d7SSteve Wise 	ep = lookup_tid(t, tid);
26380e42c1f4SSteve Wise 	BUG_ON(!ep);
2639cfdda9d7SSteve Wise 
264030c95c2dSSteve Wise 	if (ep && ep->com.qp) {
26410e42c1f4SSteve Wise 		printk(KERN_WARNING MOD "TERM received tid %u qpid %u\n", tid,
26420e42c1f4SSteve Wise 		       ep->com.qp->wq.sq.qid);
26430e42c1f4SSteve Wise 		attrs.next_state = C4IW_QP_STATE_TERMINATE;
26440e42c1f4SSteve Wise 		c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,
26450e42c1f4SSteve Wise 			       C4IW_QP_ATTR_NEXT_STATE, &attrs, 1);
26460e42c1f4SSteve Wise 	} else
264730c95c2dSSteve Wise 		printk(KERN_WARNING MOD "TERM received tid %u no ep/qp\n", tid);
2648cfdda9d7SSteve Wise 
2649cfdda9d7SSteve Wise 	return 0;
2650cfdda9d7SSteve Wise }
2651cfdda9d7SSteve Wise 
2652cfdda9d7SSteve Wise /*
2653cfdda9d7SSteve Wise  * Upcall from the adapter indicating data has been transmitted.
2654cfdda9d7SSteve Wise  * For us its just the single MPA request or reply.  We can now free
2655cfdda9d7SSteve Wise  * the skb holding the mpa message.
2656cfdda9d7SSteve Wise  */
2657cfdda9d7SSteve Wise static int fw4_ack(struct c4iw_dev *dev, struct sk_buff *skb)
2658cfdda9d7SSteve Wise {
2659cfdda9d7SSteve Wise 	struct c4iw_ep *ep;
2660cfdda9d7SSteve Wise 	struct cpl_fw4_ack *hdr = cplhdr(skb);
2661cfdda9d7SSteve Wise 	u8 credits = hdr->credits;
2662cfdda9d7SSteve Wise 	unsigned int tid = GET_TID(hdr);
2663cfdda9d7SSteve Wise 	struct tid_info *t = dev->rdev.lldi.tids;
2664cfdda9d7SSteve Wise 
2665cfdda9d7SSteve Wise 
2666cfdda9d7SSteve Wise 	ep = lookup_tid(t, tid);
2667cfdda9d7SSteve Wise 	PDBG("%s ep %p tid %u credits %u\n", __func__, ep, ep->hwtid, credits);
2668cfdda9d7SSteve Wise 	if (credits == 0) {
2669aa1ad260SJoe Perches 		PDBG("%s 0 credit ack ep %p tid %u state %u\n",
2670cfdda9d7SSteve Wise 		     __func__, ep, ep->hwtid, state_read(&ep->com));
2671cfdda9d7SSteve Wise 		return 0;
2672cfdda9d7SSteve Wise 	}
2673cfdda9d7SSteve Wise 
2674cfdda9d7SSteve Wise 	dst_confirm(ep->dst);
2675cfdda9d7SSteve Wise 	if (ep->mpa_skb) {
2676cfdda9d7SSteve Wise 		PDBG("%s last streaming msg ack ep %p tid %u state %u "
2677cfdda9d7SSteve Wise 		     "initiator %u freeing skb\n", __func__, ep, ep->hwtid,
2678cfdda9d7SSteve Wise 		     state_read(&ep->com), ep->mpa_attr.initiator ? 1 : 0);
2679cfdda9d7SSteve Wise 		kfree_skb(ep->mpa_skb);
2680cfdda9d7SSteve Wise 		ep->mpa_skb = NULL;
2681cfdda9d7SSteve Wise 	}
2682cfdda9d7SSteve Wise 	return 0;
2683cfdda9d7SSteve Wise }
2684cfdda9d7SSteve Wise 
2685cfdda9d7SSteve Wise int c4iw_reject_cr(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len)
2686cfdda9d7SSteve Wise {
2687a7db89ebSSteve Wise 	int err = 0;
2688a7db89ebSSteve Wise 	int disconnect = 0;
2689cfdda9d7SSteve Wise 	struct c4iw_ep *ep = to_ep(cm_id);
2690cfdda9d7SSteve Wise 	PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
2691cfdda9d7SSteve Wise 
2692a7db89ebSSteve Wise 	mutex_lock(&ep->com.mutex);
2693a7db89ebSSteve Wise 	if (ep->com.state == DEAD) {
2694a7db89ebSSteve Wise 		mutex_unlock(&ep->com.mutex);
2695cfdda9d7SSteve Wise 		c4iw_put_ep(&ep->com);
2696cfdda9d7SSteve Wise 		return -ECONNRESET;
2697cfdda9d7SSteve Wise 	}
2698793dad94SVipul Pandya 	set_bit(ULP_REJECT, &ep->com.history);
2699a7db89ebSSteve Wise 	BUG_ON(ep->com.state != MPA_REQ_RCVD);
2700cfdda9d7SSteve Wise 	if (mpa_rev == 0)
2701cfdda9d7SSteve Wise 		abort_connection(ep, NULL, GFP_KERNEL);
2702cfdda9d7SSteve Wise 	else {
2703cfdda9d7SSteve Wise 		err = send_mpa_reject(ep, pdata, pdata_len);
2704a7db89ebSSteve Wise 		disconnect = 1;
2705cfdda9d7SSteve Wise 	}
2706a7db89ebSSteve Wise 	mutex_unlock(&ep->com.mutex);
2707a7db89ebSSteve Wise 	if (disconnect)
2708a7db89ebSSteve Wise 		err = c4iw_ep_disconnect(ep, 0, GFP_KERNEL);
2709cfdda9d7SSteve Wise 	c4iw_put_ep(&ep->com);
2710cfdda9d7SSteve Wise 	return 0;
2711cfdda9d7SSteve Wise }
2712cfdda9d7SSteve Wise 
2713cfdda9d7SSteve Wise int c4iw_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
2714cfdda9d7SSteve Wise {
2715cfdda9d7SSteve Wise 	int err;
2716cfdda9d7SSteve Wise 	struct c4iw_qp_attributes attrs;
2717cfdda9d7SSteve Wise 	enum c4iw_qp_attr_mask mask;
2718cfdda9d7SSteve Wise 	struct c4iw_ep *ep = to_ep(cm_id);
2719cfdda9d7SSteve Wise 	struct c4iw_dev *h = to_c4iw_dev(cm_id->device);
2720cfdda9d7SSteve Wise 	struct c4iw_qp *qp = get_qhp(h, conn_param->qpn);
2721cfdda9d7SSteve Wise 
2722cfdda9d7SSteve Wise 	PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
2723a7db89ebSSteve Wise 
2724a7db89ebSSteve Wise 	mutex_lock(&ep->com.mutex);
2725a7db89ebSSteve Wise 	if (ep->com.state == DEAD) {
2726cfdda9d7SSteve Wise 		err = -ECONNRESET;
2727cfdda9d7SSteve Wise 		goto err;
2728cfdda9d7SSteve Wise 	}
2729cfdda9d7SSteve Wise 
2730a7db89ebSSteve Wise 	BUG_ON(ep->com.state != MPA_REQ_RCVD);
2731cfdda9d7SSteve Wise 	BUG_ON(!qp);
2732cfdda9d7SSteve Wise 
2733793dad94SVipul Pandya 	set_bit(ULP_ACCEPT, &ep->com.history);
2734be4c9badSRoland Dreier 	if ((conn_param->ord > c4iw_max_read_depth) ||
2735be4c9badSRoland Dreier 	    (conn_param->ird > c4iw_max_read_depth)) {
2736cfdda9d7SSteve Wise 		abort_connection(ep, NULL, GFP_KERNEL);
2737cfdda9d7SSteve Wise 		err = -EINVAL;
2738cfdda9d7SSteve Wise 		goto err;
2739cfdda9d7SSteve Wise 	}
2740cfdda9d7SSteve Wise 
2741d2fe99e8SKumar Sanghvi 	if (ep->mpa_attr.version == 2 && ep->mpa_attr.enhanced_rdma_conn) {
2742d2fe99e8SKumar Sanghvi 		if (conn_param->ord > ep->ird) {
2743d2fe99e8SKumar Sanghvi 			ep->ird = conn_param->ird;
2744d2fe99e8SKumar Sanghvi 			ep->ord = conn_param->ord;
2745d2fe99e8SKumar Sanghvi 			send_mpa_reject(ep, conn_param->private_data,
2746d2fe99e8SKumar Sanghvi 					conn_param->private_data_len);
2747d2fe99e8SKumar Sanghvi 			abort_connection(ep, NULL, GFP_KERNEL);
2748d2fe99e8SKumar Sanghvi 			err = -ENOMEM;
2749d2fe99e8SKumar Sanghvi 			goto err;
2750d2fe99e8SKumar Sanghvi 		}
2751d2fe99e8SKumar Sanghvi 		if (conn_param->ird > ep->ord) {
2752d2fe99e8SKumar Sanghvi 			if (!ep->ord)
2753d2fe99e8SKumar Sanghvi 				conn_param->ird = 1;
2754d2fe99e8SKumar Sanghvi 			else {
2755d2fe99e8SKumar Sanghvi 				abort_connection(ep, NULL, GFP_KERNEL);
2756d2fe99e8SKumar Sanghvi 				err = -ENOMEM;
2757d2fe99e8SKumar Sanghvi 				goto err;
2758d2fe99e8SKumar Sanghvi 			}
2759d2fe99e8SKumar Sanghvi 		}
2760cfdda9d7SSteve Wise 
2761d2fe99e8SKumar Sanghvi 	}
2762cfdda9d7SSteve Wise 	ep->ird = conn_param->ird;
2763cfdda9d7SSteve Wise 	ep->ord = conn_param->ord;
2764cfdda9d7SSteve Wise 
2765d2fe99e8SKumar Sanghvi 	if (ep->mpa_attr.version != 2)
2766cfdda9d7SSteve Wise 		if (peer2peer && ep->ird == 0)
2767cfdda9d7SSteve Wise 			ep->ird = 1;
2768cfdda9d7SSteve Wise 
2769cfdda9d7SSteve Wise 	PDBG("%s %d ird %d ord %d\n", __func__, __LINE__, ep->ird, ep->ord);
2770cfdda9d7SSteve Wise 
2771d2fe99e8SKumar Sanghvi 	cm_id->add_ref(cm_id);
2772d2fe99e8SKumar Sanghvi 	ep->com.cm_id = cm_id;
2773d2fe99e8SKumar Sanghvi 	ep->com.qp = qp;
2774325abeadSVipul Pandya 	ref_qp(ep);
2775d2fe99e8SKumar Sanghvi 
2776cfdda9d7SSteve Wise 	/* bind QP to EP and move to RTS */
2777cfdda9d7SSteve Wise 	attrs.mpa_attr = ep->mpa_attr;
2778cfdda9d7SSteve Wise 	attrs.max_ird = ep->ird;
2779cfdda9d7SSteve Wise 	attrs.max_ord = ep->ord;
2780cfdda9d7SSteve Wise 	attrs.llp_stream_handle = ep;
2781cfdda9d7SSteve Wise 	attrs.next_state = C4IW_QP_STATE_RTS;
2782cfdda9d7SSteve Wise 
2783cfdda9d7SSteve Wise 	/* bind QP and TID with INIT_WR */
2784cfdda9d7SSteve Wise 	mask = C4IW_QP_ATTR_NEXT_STATE |
2785cfdda9d7SSteve Wise 			     C4IW_QP_ATTR_LLP_STREAM_HANDLE |
2786cfdda9d7SSteve Wise 			     C4IW_QP_ATTR_MPA_ATTR |
2787cfdda9d7SSteve Wise 			     C4IW_QP_ATTR_MAX_IRD |
2788cfdda9d7SSteve Wise 			     C4IW_QP_ATTR_MAX_ORD;
2789cfdda9d7SSteve Wise 
2790cfdda9d7SSteve Wise 	err = c4iw_modify_qp(ep->com.qp->rhp,
2791cfdda9d7SSteve Wise 			     ep->com.qp, mask, &attrs, 1);
2792cfdda9d7SSteve Wise 	if (err)
2793cfdda9d7SSteve Wise 		goto err1;
2794cfdda9d7SSteve Wise 	err = send_mpa_reply(ep, conn_param->private_data,
2795cfdda9d7SSteve Wise 			     conn_param->private_data_len);
2796cfdda9d7SSteve Wise 	if (err)
2797cfdda9d7SSteve Wise 		goto err1;
2798cfdda9d7SSteve Wise 
2799a7db89ebSSteve Wise 	__state_set(&ep->com, FPDU_MODE);
2800cfdda9d7SSteve Wise 	established_upcall(ep);
2801a7db89ebSSteve Wise 	mutex_unlock(&ep->com.mutex);
2802cfdda9d7SSteve Wise 	c4iw_put_ep(&ep->com);
2803cfdda9d7SSteve Wise 	return 0;
2804cfdda9d7SSteve Wise err1:
2805cfdda9d7SSteve Wise 	ep->com.cm_id = NULL;
2806cfdda9d7SSteve Wise 	cm_id->rem_ref(cm_id);
2807cfdda9d7SSteve Wise err:
2808a7db89ebSSteve Wise 	mutex_unlock(&ep->com.mutex);
2809cfdda9d7SSteve Wise 	c4iw_put_ep(&ep->com);
2810cfdda9d7SSteve Wise 	return err;
2811cfdda9d7SSteve Wise }
2812cfdda9d7SSteve Wise 
2813830662f6SVipul Pandya static int pick_local_ipaddrs(struct c4iw_dev *dev, struct iw_cm_id *cm_id)
2814830662f6SVipul Pandya {
2815830662f6SVipul Pandya 	struct in_device *ind;
2816830662f6SVipul Pandya 	int found = 0;
2817830662f6SVipul Pandya 	struct sockaddr_in *laddr = (struct sockaddr_in *)&cm_id->local_addr;
2818830662f6SVipul Pandya 	struct sockaddr_in *raddr = (struct sockaddr_in *)&cm_id->remote_addr;
2819830662f6SVipul Pandya 
2820830662f6SVipul Pandya 	ind = in_dev_get(dev->rdev.lldi.ports[0]);
2821830662f6SVipul Pandya 	if (!ind)
2822830662f6SVipul Pandya 		return -EADDRNOTAVAIL;
2823830662f6SVipul Pandya 	for_primary_ifa(ind) {
2824830662f6SVipul Pandya 		laddr->sin_addr.s_addr = ifa->ifa_address;
2825830662f6SVipul Pandya 		raddr->sin_addr.s_addr = ifa->ifa_address;
2826830662f6SVipul Pandya 		found = 1;
2827830662f6SVipul Pandya 		break;
2828830662f6SVipul Pandya 	}
2829830662f6SVipul Pandya 	endfor_ifa(ind);
2830830662f6SVipul Pandya 	in_dev_put(ind);
2831830662f6SVipul Pandya 	return found ? 0 : -EADDRNOTAVAIL;
2832830662f6SVipul Pandya }
2833830662f6SVipul Pandya 
2834830662f6SVipul Pandya static int get_lladdr(struct net_device *dev, struct in6_addr *addr,
2835830662f6SVipul Pandya 		      unsigned char banned_flags)
2836830662f6SVipul Pandya {
2837830662f6SVipul Pandya 	struct inet6_dev *idev;
2838830662f6SVipul Pandya 	int err = -EADDRNOTAVAIL;
2839830662f6SVipul Pandya 
2840830662f6SVipul Pandya 	rcu_read_lock();
2841830662f6SVipul Pandya 	idev = __in6_dev_get(dev);
2842830662f6SVipul Pandya 	if (idev != NULL) {
2843830662f6SVipul Pandya 		struct inet6_ifaddr *ifp;
2844830662f6SVipul Pandya 
2845830662f6SVipul Pandya 		read_lock_bh(&idev->lock);
2846830662f6SVipul Pandya 		list_for_each_entry(ifp, &idev->addr_list, if_list) {
2847830662f6SVipul Pandya 			if (ifp->scope == IFA_LINK &&
2848830662f6SVipul Pandya 			    !(ifp->flags & banned_flags)) {
2849830662f6SVipul Pandya 				memcpy(addr, &ifp->addr, 16);
2850830662f6SVipul Pandya 				err = 0;
2851830662f6SVipul Pandya 				break;
2852830662f6SVipul Pandya 			}
2853830662f6SVipul Pandya 		}
2854830662f6SVipul Pandya 		read_unlock_bh(&idev->lock);
2855830662f6SVipul Pandya 	}
2856830662f6SVipul Pandya 	rcu_read_unlock();
2857830662f6SVipul Pandya 	return err;
2858830662f6SVipul Pandya }
2859830662f6SVipul Pandya 
2860830662f6SVipul Pandya static int pick_local_ip6addrs(struct c4iw_dev *dev, struct iw_cm_id *cm_id)
2861830662f6SVipul Pandya {
2862830662f6SVipul Pandya 	struct in6_addr uninitialized_var(addr);
2863830662f6SVipul Pandya 	struct sockaddr_in6 *la6 = (struct sockaddr_in6 *)&cm_id->local_addr;
2864830662f6SVipul Pandya 	struct sockaddr_in6 *ra6 = (struct sockaddr_in6 *)&cm_id->remote_addr;
2865830662f6SVipul Pandya 
2866830662f6SVipul Pandya 	if (get_lladdr(dev->rdev.lldi.ports[0], &addr, IFA_F_TENTATIVE)) {
2867830662f6SVipul Pandya 		memcpy(la6->sin6_addr.s6_addr, &addr, 16);
2868830662f6SVipul Pandya 		memcpy(ra6->sin6_addr.s6_addr, &addr, 16);
2869830662f6SVipul Pandya 		return 0;
2870830662f6SVipul Pandya 	}
2871830662f6SVipul Pandya 	return -EADDRNOTAVAIL;
2872830662f6SVipul Pandya }
2873830662f6SVipul Pandya 
2874cfdda9d7SSteve Wise int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
2875cfdda9d7SSteve Wise {
2876cfdda9d7SSteve Wise 	struct c4iw_dev *dev = to_c4iw_dev(cm_id->device);
2877cfdda9d7SSteve Wise 	struct c4iw_ep *ep;
28783786cf18SDavid Miller 	int err = 0;
28799eccfe10SSteve Wise 	struct sockaddr_in *laddr;
28809eccfe10SSteve Wise 	struct sockaddr_in *raddr;
28819eccfe10SSteve Wise 	struct sockaddr_in6 *laddr6;
28829eccfe10SSteve Wise 	struct sockaddr_in6 *raddr6;
28839eccfe10SSteve Wise 	struct iwpm_dev_data pm_reg_msg;
28849eccfe10SSteve Wise 	struct iwpm_sa_data pm_msg;
2885830662f6SVipul Pandya 	__u8 *ra;
2886830662f6SVipul Pandya 	int iptype;
28879eccfe10SSteve Wise 	int iwpm_err = 0;
2888cfdda9d7SSteve Wise 
2889be4c9badSRoland Dreier 	if ((conn_param->ord > c4iw_max_read_depth) ||
2890be4c9badSRoland Dreier 	    (conn_param->ird > c4iw_max_read_depth)) {
2891be4c9badSRoland Dreier 		err = -EINVAL;
2892be4c9badSRoland Dreier 		goto out;
2893be4c9badSRoland Dreier 	}
2894cfdda9d7SSteve Wise 	ep = alloc_ep(sizeof(*ep), GFP_KERNEL);
2895cfdda9d7SSteve Wise 	if (!ep) {
2896cfdda9d7SSteve Wise 		printk(KERN_ERR MOD "%s - cannot alloc ep.\n", __func__);
2897cfdda9d7SSteve Wise 		err = -ENOMEM;
2898cfdda9d7SSteve Wise 		goto out;
2899cfdda9d7SSteve Wise 	}
2900cfdda9d7SSteve Wise 	init_timer(&ep->timer);
2901cfdda9d7SSteve Wise 	ep->plen = conn_param->private_data_len;
2902cfdda9d7SSteve Wise 	if (ep->plen)
2903cfdda9d7SSteve Wise 		memcpy(ep->mpa_pkt + sizeof(struct mpa_message),
2904cfdda9d7SSteve Wise 		       conn_param->private_data, ep->plen);
2905cfdda9d7SSteve Wise 	ep->ird = conn_param->ird;
2906cfdda9d7SSteve Wise 	ep->ord = conn_param->ord;
2907cfdda9d7SSteve Wise 
2908cfdda9d7SSteve Wise 	if (peer2peer && ep->ord == 0)
2909cfdda9d7SSteve Wise 		ep->ord = 1;
2910cfdda9d7SSteve Wise 
2911cfdda9d7SSteve Wise 	cm_id->add_ref(cm_id);
2912cfdda9d7SSteve Wise 	ep->com.dev = dev;
2913cfdda9d7SSteve Wise 	ep->com.cm_id = cm_id;
2914cfdda9d7SSteve Wise 	ep->com.qp = get_qhp(dev, conn_param->qpn);
2915830662f6SVipul Pandya 	if (!ep->com.qp) {
2916830662f6SVipul Pandya 		PDBG("%s qpn 0x%x not found!\n", __func__, conn_param->qpn);
2917830662f6SVipul Pandya 		err = -EINVAL;
29189eccfe10SSteve Wise 		goto fail1;
2919830662f6SVipul Pandya 	}
2920325abeadSVipul Pandya 	ref_qp(ep);
2921cfdda9d7SSteve Wise 	PDBG("%s qpn 0x%x qp %p cm_id %p\n", __func__, conn_param->qpn,
2922cfdda9d7SSteve Wise 	     ep->com.qp, cm_id);
2923cfdda9d7SSteve Wise 
2924cfdda9d7SSteve Wise 	/*
2925cfdda9d7SSteve Wise 	 * Allocate an active TID to initiate a TCP connection.
2926cfdda9d7SSteve Wise 	 */
2927cfdda9d7SSteve Wise 	ep->atid = cxgb4_alloc_atid(dev->rdev.lldi.tids, ep);
2928cfdda9d7SSteve Wise 	if (ep->atid == -1) {
2929cfdda9d7SSteve Wise 		printk(KERN_ERR MOD "%s - cannot alloc atid.\n", __func__);
2930cfdda9d7SSteve Wise 		err = -ENOMEM;
29319eccfe10SSteve Wise 		goto fail1;
2932cfdda9d7SSteve Wise 	}
2933793dad94SVipul Pandya 	insert_handle(dev, &dev->atid_idr, ep, ep->atid);
2934cfdda9d7SSteve Wise 
29359eccfe10SSteve Wise 	memcpy(&ep->com.local_addr, &cm_id->local_addr,
29369eccfe10SSteve Wise 	       sizeof(ep->com.local_addr));
29379eccfe10SSteve Wise 	memcpy(&ep->com.remote_addr, &cm_id->remote_addr,
29389eccfe10SSteve Wise 	       sizeof(ep->com.remote_addr));
29399eccfe10SSteve Wise 
29409eccfe10SSteve Wise 	/* No port mapper available, go with the specified peer information */
29419eccfe10SSteve Wise 	memcpy(&ep->com.mapped_local_addr, &cm_id->local_addr,
29429eccfe10SSteve Wise 	       sizeof(ep->com.mapped_local_addr));
29439eccfe10SSteve Wise 	memcpy(&ep->com.mapped_remote_addr, &cm_id->remote_addr,
29449eccfe10SSteve Wise 	       sizeof(ep->com.mapped_remote_addr));
29459eccfe10SSteve Wise 
29469eccfe10SSteve Wise 	c4iw_form_reg_msg(dev, &pm_reg_msg);
29479eccfe10SSteve Wise 	iwpm_err = iwpm_register_pid(&pm_reg_msg, RDMA_NL_C4IW);
29489eccfe10SSteve Wise 	if (iwpm_err) {
29499eccfe10SSteve Wise 		PDBG("%s: Port Mapper reg pid fail (err = %d).\n",
29509eccfe10SSteve Wise 			__func__, iwpm_err);
29519eccfe10SSteve Wise 	}
29529eccfe10SSteve Wise 	if (iwpm_valid_pid() && !iwpm_err) {
29539eccfe10SSteve Wise 		c4iw_form_pm_msg(ep, &pm_msg);
29549eccfe10SSteve Wise 		iwpm_err = iwpm_add_and_query_mapping(&pm_msg, RDMA_NL_C4IW);
29559eccfe10SSteve Wise 		if (iwpm_err)
29569eccfe10SSteve Wise 			PDBG("%s: Port Mapper query fail (err = %d).\n",
29579eccfe10SSteve Wise 				__func__, iwpm_err);
29589eccfe10SSteve Wise 		else
29599eccfe10SSteve Wise 			c4iw_record_pm_msg(ep, &pm_msg);
29609eccfe10SSteve Wise 	}
29619eccfe10SSteve Wise 	if (iwpm_create_mapinfo(&ep->com.local_addr,
29629eccfe10SSteve Wise 				&ep->com.mapped_local_addr, RDMA_NL_C4IW)) {
29639eccfe10SSteve Wise 		iwpm_remove_mapping(&ep->com.local_addr, RDMA_NL_C4IW);
29649eccfe10SSteve Wise 		err = -ENOMEM;
29659eccfe10SSteve Wise 		goto fail1;
29669eccfe10SSteve Wise 	}
29679eccfe10SSteve Wise 	print_addr(&ep->com, __func__, "add_query/create_mapinfo");
29689eccfe10SSteve Wise 	set_bit(RELEASE_MAPINFO, &ep->com.flags);
29699eccfe10SSteve Wise 
29709eccfe10SSteve Wise 	laddr = (struct sockaddr_in *)&ep->com.mapped_local_addr;
29719eccfe10SSteve Wise 	raddr = (struct sockaddr_in *)&ep->com.mapped_remote_addr;
29729eccfe10SSteve Wise 	laddr6 = (struct sockaddr_in6 *)&ep->com.mapped_local_addr;
29739eccfe10SSteve Wise 	raddr6 = (struct sockaddr_in6 *) &ep->com.mapped_remote_addr;
29749eccfe10SSteve Wise 
2975830662f6SVipul Pandya 	if (cm_id->remote_addr.ss_family == AF_INET) {
2976830662f6SVipul Pandya 		iptype = 4;
2977830662f6SVipul Pandya 		ra = (__u8 *)&raddr->sin_addr;
2978830662f6SVipul Pandya 
2979830662f6SVipul Pandya 		/*
2980830662f6SVipul Pandya 		 * Handle loopback requests to INADDR_ANY.
2981830662f6SVipul Pandya 		 */
2982830662f6SVipul Pandya 		if ((__force int)raddr->sin_addr.s_addr == INADDR_ANY) {
2983830662f6SVipul Pandya 			err = pick_local_ipaddrs(dev, cm_id);
2984830662f6SVipul Pandya 			if (err)
29859eccfe10SSteve Wise 				goto fail1;
2986830662f6SVipul Pandya 		}
2987cfdda9d7SSteve Wise 
2988cfdda9d7SSteve Wise 		/* find a route */
2989830662f6SVipul Pandya 		PDBG("%s saddr %pI4 sport 0x%x raddr %pI4 rport 0x%x\n",
2990830662f6SVipul Pandya 		     __func__, &laddr->sin_addr, ntohs(laddr->sin_port),
2991830662f6SVipul Pandya 		     ra, ntohs(raddr->sin_port));
2992830662f6SVipul Pandya 		ep->dst = find_route(dev, laddr->sin_addr.s_addr,
2993830662f6SVipul Pandya 				     raddr->sin_addr.s_addr, laddr->sin_port,
2994830662f6SVipul Pandya 				     raddr->sin_port, 0);
2995830662f6SVipul Pandya 	} else {
2996830662f6SVipul Pandya 		iptype = 6;
2997830662f6SVipul Pandya 		ra = (__u8 *)&raddr6->sin6_addr;
2998830662f6SVipul Pandya 
2999830662f6SVipul Pandya 		/*
3000830662f6SVipul Pandya 		 * Handle loopback requests to INADDR_ANY.
3001830662f6SVipul Pandya 		 */
3002830662f6SVipul Pandya 		if (ipv6_addr_type(&raddr6->sin6_addr) == IPV6_ADDR_ANY) {
3003830662f6SVipul Pandya 			err = pick_local_ip6addrs(dev, cm_id);
3004830662f6SVipul Pandya 			if (err)
30059eccfe10SSteve Wise 				goto fail1;
3006830662f6SVipul Pandya 		}
3007830662f6SVipul Pandya 
3008830662f6SVipul Pandya 		/* find a route */
3009830662f6SVipul Pandya 		PDBG("%s saddr %pI6 sport 0x%x raddr %pI6 rport 0x%x\n",
3010830662f6SVipul Pandya 		     __func__, laddr6->sin6_addr.s6_addr,
3011830662f6SVipul Pandya 		     ntohs(laddr6->sin6_port),
3012830662f6SVipul Pandya 		     raddr6->sin6_addr.s6_addr, ntohs(raddr6->sin6_port));
3013830662f6SVipul Pandya 		ep->dst = find_route6(dev, laddr6->sin6_addr.s6_addr,
3014830662f6SVipul Pandya 				      raddr6->sin6_addr.s6_addr,
3015830662f6SVipul Pandya 				      laddr6->sin6_port, raddr6->sin6_port, 0,
3016830662f6SVipul Pandya 				      raddr6->sin6_scope_id);
3017830662f6SVipul Pandya 	}
3018830662f6SVipul Pandya 	if (!ep->dst) {
3019cfdda9d7SSteve Wise 		printk(KERN_ERR MOD "%s - cannot find route.\n", __func__);
3020cfdda9d7SSteve Wise 		err = -EHOSTUNREACH;
30219eccfe10SSteve Wise 		goto fail2;
3022cfdda9d7SSteve Wise 	}
3023cfdda9d7SSteve Wise 
3024830662f6SVipul Pandya 	err = import_ep(ep, iptype, ra, ep->dst, ep->com.dev, true);
30253786cf18SDavid Miller 	if (err) {
3026cfdda9d7SSteve Wise 		printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__);
30279eccfe10SSteve Wise 		goto fail3;
3028cfdda9d7SSteve Wise 	}
3029cfdda9d7SSteve Wise 
3030cfdda9d7SSteve Wise 	PDBG("%s txq_idx %u tx_chan %u smac_idx %u rss_qid %u l2t_idx %u\n",
3031cfdda9d7SSteve Wise 		__func__, ep->txq_idx, ep->tx_chan, ep->smac_idx, ep->rss_qid,
3032cfdda9d7SSteve Wise 		ep->l2t->idx);
3033cfdda9d7SSteve Wise 
3034cfdda9d7SSteve Wise 	state_set(&ep->com, CONNECTING);
3035cfdda9d7SSteve Wise 	ep->tos = 0;
3036cfdda9d7SSteve Wise 
3037cfdda9d7SSteve Wise 	/* send connect request to rnic */
3038cfdda9d7SSteve Wise 	err = send_connect(ep);
3039cfdda9d7SSteve Wise 	if (!err)
3040cfdda9d7SSteve Wise 		goto out;
3041cfdda9d7SSteve Wise 
3042cfdda9d7SSteve Wise 	cxgb4_l2t_release(ep->l2t);
3043cfdda9d7SSteve Wise fail3:
30449eccfe10SSteve Wise 	dst_release(ep->dst);
30459eccfe10SSteve Wise fail2:
3046793dad94SVipul Pandya 	remove_handle(ep->com.dev, &ep->com.dev->atid_idr, ep->atid);
3047cfdda9d7SSteve Wise 	cxgb4_free_atid(ep->com.dev->rdev.lldi.tids, ep->atid);
30489eccfe10SSteve Wise fail1:
3049cfdda9d7SSteve Wise 	cm_id->rem_ref(cm_id);
3050cfdda9d7SSteve Wise 	c4iw_put_ep(&ep->com);
3051cfdda9d7SSteve Wise out:
3052cfdda9d7SSteve Wise 	return err;
3053cfdda9d7SSteve Wise }
3054cfdda9d7SSteve Wise 
3055830662f6SVipul Pandya static int create_server6(struct c4iw_dev *dev, struct c4iw_listen_ep *ep)
3056830662f6SVipul Pandya {
3057830662f6SVipul Pandya 	int err;
30589eccfe10SSteve Wise 	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)
30599eccfe10SSteve Wise 				    &ep->com.mapped_local_addr;
3060830662f6SVipul Pandya 
3061830662f6SVipul Pandya 	c4iw_init_wr_wait(&ep->com.wr_wait);
3062830662f6SVipul Pandya 	err = cxgb4_create_server6(ep->com.dev->rdev.lldi.ports[0],
3063830662f6SVipul Pandya 				   ep->stid, &sin6->sin6_addr,
3064830662f6SVipul Pandya 				   sin6->sin6_port,
3065830662f6SVipul Pandya 				   ep->com.dev->rdev.lldi.rxq_ids[0]);
3066830662f6SVipul Pandya 	if (!err)
3067830662f6SVipul Pandya 		err = c4iw_wait_for_reply(&ep->com.dev->rdev,
3068830662f6SVipul Pandya 					  &ep->com.wr_wait,
3069830662f6SVipul Pandya 					  0, 0, __func__);
3070830662f6SVipul Pandya 	if (err)
3071830662f6SVipul Pandya 		pr_err("cxgb4_create_server6/filter failed err %d stid %d laddr %pI6 lport %d\n",
3072830662f6SVipul Pandya 		       err, ep->stid,
3073830662f6SVipul Pandya 		       sin6->sin6_addr.s6_addr, ntohs(sin6->sin6_port));
3074830662f6SVipul Pandya 	return err;
3075830662f6SVipul Pandya }
3076830662f6SVipul Pandya 
3077830662f6SVipul Pandya static int create_server4(struct c4iw_dev *dev, struct c4iw_listen_ep *ep)
3078830662f6SVipul Pandya {
3079830662f6SVipul Pandya 	int err;
30809eccfe10SSteve Wise 	struct sockaddr_in *sin = (struct sockaddr_in *)
30819eccfe10SSteve Wise 				  &ep->com.mapped_local_addr;
3082830662f6SVipul Pandya 
3083830662f6SVipul Pandya 	if (dev->rdev.lldi.enable_fw_ofld_conn) {
3084830662f6SVipul Pandya 		do {
3085830662f6SVipul Pandya 			err = cxgb4_create_server_filter(
3086830662f6SVipul Pandya 				ep->com.dev->rdev.lldi.ports[0], ep->stid,
3087830662f6SVipul Pandya 				sin->sin_addr.s_addr, sin->sin_port, 0,
3088830662f6SVipul Pandya 				ep->com.dev->rdev.lldi.rxq_ids[0], 0, 0);
3089830662f6SVipul Pandya 			if (err == -EBUSY) {
3090830662f6SVipul Pandya 				set_current_state(TASK_UNINTERRUPTIBLE);
3091830662f6SVipul Pandya 				schedule_timeout(usecs_to_jiffies(100));
3092830662f6SVipul Pandya 			}
3093830662f6SVipul Pandya 		} while (err == -EBUSY);
3094830662f6SVipul Pandya 	} else {
3095830662f6SVipul Pandya 		c4iw_init_wr_wait(&ep->com.wr_wait);
3096830662f6SVipul Pandya 		err = cxgb4_create_server(ep->com.dev->rdev.lldi.ports[0],
3097830662f6SVipul Pandya 				ep->stid, sin->sin_addr.s_addr, sin->sin_port,
3098830662f6SVipul Pandya 				0, ep->com.dev->rdev.lldi.rxq_ids[0]);
3099830662f6SVipul Pandya 		if (!err)
3100830662f6SVipul Pandya 			err = c4iw_wait_for_reply(&ep->com.dev->rdev,
3101830662f6SVipul Pandya 						  &ep->com.wr_wait,
3102830662f6SVipul Pandya 						  0, 0, __func__);
3103830662f6SVipul Pandya 	}
3104830662f6SVipul Pandya 	if (err)
3105830662f6SVipul Pandya 		pr_err("cxgb4_create_server/filter failed err %d stid %d laddr %pI4 lport %d\n"
3106830662f6SVipul Pandya 		       , err, ep->stid,
3107830662f6SVipul Pandya 		       &sin->sin_addr, ntohs(sin->sin_port));
3108830662f6SVipul Pandya 	return err;
3109830662f6SVipul Pandya }
3110830662f6SVipul Pandya 
3111cfdda9d7SSteve Wise int c4iw_create_listen(struct iw_cm_id *cm_id, int backlog)
3112cfdda9d7SSteve Wise {
3113cfdda9d7SSteve Wise 	int err = 0;
3114cfdda9d7SSteve Wise 	struct c4iw_dev *dev = to_c4iw_dev(cm_id->device);
3115cfdda9d7SSteve Wise 	struct c4iw_listen_ep *ep;
31169eccfe10SSteve Wise 	struct iwpm_dev_data pm_reg_msg;
31179eccfe10SSteve Wise 	struct iwpm_sa_data pm_msg;
31189eccfe10SSteve Wise 	int iwpm_err = 0;
3119cfdda9d7SSteve Wise 
3120cfdda9d7SSteve Wise 	might_sleep();
3121cfdda9d7SSteve Wise 
3122cfdda9d7SSteve Wise 	ep = alloc_ep(sizeof(*ep), GFP_KERNEL);
3123cfdda9d7SSteve Wise 	if (!ep) {
3124cfdda9d7SSteve Wise 		printk(KERN_ERR MOD "%s - cannot alloc ep.\n", __func__);
3125cfdda9d7SSteve Wise 		err = -ENOMEM;
3126cfdda9d7SSteve Wise 		goto fail1;
3127cfdda9d7SSteve Wise 	}
3128cfdda9d7SSteve Wise 	PDBG("%s ep %p\n", __func__, ep);
3129cfdda9d7SSteve Wise 	cm_id->add_ref(cm_id);
3130cfdda9d7SSteve Wise 	ep->com.cm_id = cm_id;
3131cfdda9d7SSteve Wise 	ep->com.dev = dev;
3132cfdda9d7SSteve Wise 	ep->backlog = backlog;
313324d44a39SSteve Wise 	memcpy(&ep->com.local_addr, &cm_id->local_addr,
313424d44a39SSteve Wise 	       sizeof(ep->com.local_addr));
3135cfdda9d7SSteve Wise 
3136cfdda9d7SSteve Wise 	/*
3137cfdda9d7SSteve Wise 	 * Allocate a server TID.
3138cfdda9d7SSteve Wise 	 */
31398c044690SKumar Sanghvi 	if (dev->rdev.lldi.enable_fw_ofld_conn &&
31408c044690SKumar Sanghvi 	    ep->com.local_addr.ss_family == AF_INET)
3141830662f6SVipul Pandya 		ep->stid = cxgb4_alloc_sftid(dev->rdev.lldi.tids,
3142830662f6SVipul Pandya 					     cm_id->local_addr.ss_family, ep);
31431cab775cSVipul Pandya 	else
3144830662f6SVipul Pandya 		ep->stid = cxgb4_alloc_stid(dev->rdev.lldi.tids,
3145830662f6SVipul Pandya 					    cm_id->local_addr.ss_family, ep);
31461cab775cSVipul Pandya 
3147cfdda9d7SSteve Wise 	if (ep->stid == -1) {
3148be4c9badSRoland Dreier 		printk(KERN_ERR MOD "%s - cannot alloc stid.\n", __func__);
3149cfdda9d7SSteve Wise 		err = -ENOMEM;
3150cfdda9d7SSteve Wise 		goto fail2;
3151cfdda9d7SSteve Wise 	}
3152793dad94SVipul Pandya 	insert_handle(dev, &dev->stid_idr, ep, ep->stid);
31539eccfe10SSteve Wise 
31549eccfe10SSteve Wise 	/* No port mapper available, go with the specified info */
31559eccfe10SSteve Wise 	memcpy(&ep->com.mapped_local_addr, &cm_id->local_addr,
31569eccfe10SSteve Wise 	       sizeof(ep->com.mapped_local_addr));
31579eccfe10SSteve Wise 
31589eccfe10SSteve Wise 	c4iw_form_reg_msg(dev, &pm_reg_msg);
31599eccfe10SSteve Wise 	iwpm_err = iwpm_register_pid(&pm_reg_msg, RDMA_NL_C4IW);
31609eccfe10SSteve Wise 	if (iwpm_err) {
31619eccfe10SSteve Wise 		PDBG("%s: Port Mapper reg pid fail (err = %d).\n",
31629eccfe10SSteve Wise 			__func__, iwpm_err);
31639eccfe10SSteve Wise 	}
31649eccfe10SSteve Wise 	if (iwpm_valid_pid() && !iwpm_err) {
31659eccfe10SSteve Wise 		memcpy(&pm_msg.loc_addr, &ep->com.local_addr,
31669eccfe10SSteve Wise 				sizeof(ep->com.local_addr));
31679eccfe10SSteve Wise 		iwpm_err = iwpm_add_mapping(&pm_msg, RDMA_NL_C4IW);
31689eccfe10SSteve Wise 		if (iwpm_err)
31699eccfe10SSteve Wise 			PDBG("%s: Port Mapper query fail (err = %d).\n",
31709eccfe10SSteve Wise 				__func__, iwpm_err);
31719eccfe10SSteve Wise 		else
31729eccfe10SSteve Wise 			memcpy(&ep->com.mapped_local_addr,
31739eccfe10SSteve Wise 				&pm_msg.mapped_loc_addr,
31749eccfe10SSteve Wise 				sizeof(ep->com.mapped_local_addr));
31759eccfe10SSteve Wise 	}
31769eccfe10SSteve Wise 	if (iwpm_create_mapinfo(&ep->com.local_addr,
31779eccfe10SSteve Wise 				&ep->com.mapped_local_addr, RDMA_NL_C4IW)) {
31789eccfe10SSteve Wise 		err = -ENOMEM;
31799eccfe10SSteve Wise 		goto fail3;
31809eccfe10SSteve Wise 	}
31819eccfe10SSteve Wise 	print_addr(&ep->com, __func__, "add_mapping/create_mapinfo");
31829eccfe10SSteve Wise 
31839eccfe10SSteve Wise 	set_bit(RELEASE_MAPINFO, &ep->com.flags);
3184cfdda9d7SSteve Wise 	state_set(&ep->com, LISTEN);
3185830662f6SVipul Pandya 	if (ep->com.local_addr.ss_family == AF_INET)
3186830662f6SVipul Pandya 		err = create_server4(dev, ep);
3187830662f6SVipul Pandya 	else
3188830662f6SVipul Pandya 		err = create_server6(dev, ep);
3189cfdda9d7SSteve Wise 	if (!err) {
3190cfdda9d7SSteve Wise 		cm_id->provider_data = ep;
3191cfdda9d7SSteve Wise 		goto out;
3192cfdda9d7SSteve Wise 	}
31939eccfe10SSteve Wise 
31949eccfe10SSteve Wise fail3:
3195830662f6SVipul Pandya 	cxgb4_free_stid(ep->com.dev->rdev.lldi.tids, ep->stid,
3196830662f6SVipul Pandya 			ep->com.local_addr.ss_family);
3197cfdda9d7SSteve Wise fail2:
3198cfdda9d7SSteve Wise 	cm_id->rem_ref(cm_id);
3199cfdda9d7SSteve Wise 	c4iw_put_ep(&ep->com);
3200cfdda9d7SSteve Wise fail1:
3201cfdda9d7SSteve Wise out:
3202cfdda9d7SSteve Wise 	return err;
3203cfdda9d7SSteve Wise }
3204cfdda9d7SSteve Wise 
3205cfdda9d7SSteve Wise int c4iw_destroy_listen(struct iw_cm_id *cm_id)
3206cfdda9d7SSteve Wise {
3207cfdda9d7SSteve Wise 	int err;
3208cfdda9d7SSteve Wise 	struct c4iw_listen_ep *ep = to_listen_ep(cm_id);
3209cfdda9d7SSteve Wise 
3210cfdda9d7SSteve Wise 	PDBG("%s ep %p\n", __func__, ep);
3211cfdda9d7SSteve Wise 
3212cfdda9d7SSteve Wise 	might_sleep();
3213cfdda9d7SSteve Wise 	state_set(&ep->com, DEAD);
3214830662f6SVipul Pandya 	if (ep->com.dev->rdev.lldi.enable_fw_ofld_conn &&
3215830662f6SVipul Pandya 	    ep->com.local_addr.ss_family == AF_INET) {
32161cab775cSVipul Pandya 		err = cxgb4_remove_server_filter(
32171cab775cSVipul Pandya 			ep->com.dev->rdev.lldi.ports[0], ep->stid,
32181cab775cSVipul Pandya 			ep->com.dev->rdev.lldi.rxq_ids[0], 0);
32191cab775cSVipul Pandya 	} else {
3220aadc4df3SSteve Wise 		c4iw_init_wr_wait(&ep->com.wr_wait);
3221830662f6SVipul Pandya 		err = cxgb4_remove_server(
3222830662f6SVipul Pandya 				ep->com.dev->rdev.lldi.ports[0], ep->stid,
3223830662f6SVipul Pandya 				ep->com.dev->rdev.lldi.rxq_ids[0], 0);
3224cfdda9d7SSteve Wise 		if (err)
3225cfdda9d7SSteve Wise 			goto done;
32261cab775cSVipul Pandya 		err = c4iw_wait_for_reply(&ep->com.dev->rdev, &ep->com.wr_wait,
32271cab775cSVipul Pandya 					  0, 0, __func__);
32281cab775cSVipul Pandya 	}
3229793dad94SVipul Pandya 	remove_handle(ep->com.dev, &ep->com.dev->stid_idr, ep->stid);
3230830662f6SVipul Pandya 	cxgb4_free_stid(ep->com.dev->rdev.lldi.tids, ep->stid,
3231830662f6SVipul Pandya 			ep->com.local_addr.ss_family);
3232cfdda9d7SSteve Wise done:
3233cfdda9d7SSteve Wise 	cm_id->rem_ref(cm_id);
3234cfdda9d7SSteve Wise 	c4iw_put_ep(&ep->com);
3235cfdda9d7SSteve Wise 	return err;
3236cfdda9d7SSteve Wise }
3237cfdda9d7SSteve Wise 
3238cfdda9d7SSteve Wise int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp)
3239cfdda9d7SSteve Wise {
3240cfdda9d7SSteve Wise 	int ret = 0;
3241cfdda9d7SSteve Wise 	int close = 0;
3242cfdda9d7SSteve Wise 	int fatal = 0;
3243cfdda9d7SSteve Wise 	struct c4iw_rdev *rdev;
3244cfdda9d7SSteve Wise 
32452f5b48c3SSteve Wise 	mutex_lock(&ep->com.mutex);
3246cfdda9d7SSteve Wise 
3247cfdda9d7SSteve Wise 	PDBG("%s ep %p state %s, abrupt %d\n", __func__, ep,
3248cfdda9d7SSteve Wise 	     states[ep->com.state], abrupt);
3249cfdda9d7SSteve Wise 
3250cfdda9d7SSteve Wise 	rdev = &ep->com.dev->rdev;
3251cfdda9d7SSteve Wise 	if (c4iw_fatal_error(rdev)) {
3252cfdda9d7SSteve Wise 		fatal = 1;
3253be13b2dfSSteve Wise 		close_complete_upcall(ep, -EIO);
3254cfdda9d7SSteve Wise 		ep->com.state = DEAD;
3255cfdda9d7SSteve Wise 	}
3256cfdda9d7SSteve Wise 	switch (ep->com.state) {
3257cfdda9d7SSteve Wise 	case MPA_REQ_WAIT:
3258cfdda9d7SSteve Wise 	case MPA_REQ_SENT:
3259cfdda9d7SSteve Wise 	case MPA_REQ_RCVD:
3260cfdda9d7SSteve Wise 	case MPA_REP_SENT:
3261cfdda9d7SSteve Wise 	case FPDU_MODE:
3262cfdda9d7SSteve Wise 		close = 1;
3263cfdda9d7SSteve Wise 		if (abrupt)
3264cfdda9d7SSteve Wise 			ep->com.state = ABORTING;
3265cfdda9d7SSteve Wise 		else {
3266cfdda9d7SSteve Wise 			ep->com.state = CLOSING;
3267ca5a2202SSteve Wise 			start_ep_timer(ep);
3268cfdda9d7SSteve Wise 		}
3269cfdda9d7SSteve Wise 		set_bit(CLOSE_SENT, &ep->com.flags);
3270cfdda9d7SSteve Wise 		break;
3271cfdda9d7SSteve Wise 	case CLOSING:
3272cfdda9d7SSteve Wise 		if (!test_and_set_bit(CLOSE_SENT, &ep->com.flags)) {
3273cfdda9d7SSteve Wise 			close = 1;
3274cfdda9d7SSteve Wise 			if (abrupt) {
3275b33bd0cbSSteve Wise 				(void)stop_ep_timer(ep);
3276cfdda9d7SSteve Wise 				ep->com.state = ABORTING;
3277cfdda9d7SSteve Wise 			} else
3278cfdda9d7SSteve Wise 				ep->com.state = MORIBUND;
3279cfdda9d7SSteve Wise 		}
3280cfdda9d7SSteve Wise 		break;
3281cfdda9d7SSteve Wise 	case MORIBUND:
3282cfdda9d7SSteve Wise 	case ABORTING:
3283cfdda9d7SSteve Wise 	case DEAD:
3284cfdda9d7SSteve Wise 		PDBG("%s ignoring disconnect ep %p state %u\n",
3285cfdda9d7SSteve Wise 		     __func__, ep, ep->com.state);
3286cfdda9d7SSteve Wise 		break;
3287cfdda9d7SSteve Wise 	default:
3288cfdda9d7SSteve Wise 		BUG();
3289cfdda9d7SSteve Wise 		break;
3290cfdda9d7SSteve Wise 	}
3291cfdda9d7SSteve Wise 
3292cfdda9d7SSteve Wise 	if (close) {
32938da7e7a5SSteve Wise 		if (abrupt) {
3294793dad94SVipul Pandya 			set_bit(EP_DISC_ABORT, &ep->com.history);
3295be13b2dfSSteve Wise 			close_complete_upcall(ep, -ECONNRESET);
32968da7e7a5SSteve Wise 			ret = send_abort(ep, NULL, gfp);
3297793dad94SVipul Pandya 		} else {
3298793dad94SVipul Pandya 			set_bit(EP_DISC_CLOSE, &ep->com.history);
3299cfdda9d7SSteve Wise 			ret = send_halfclose(ep, gfp);
3300793dad94SVipul Pandya 		}
3301cfdda9d7SSteve Wise 		if (ret)
3302cfdda9d7SSteve Wise 			fatal = 1;
3303cfdda9d7SSteve Wise 	}
33048da7e7a5SSteve Wise 	mutex_unlock(&ep->com.mutex);
3305cfdda9d7SSteve Wise 	if (fatal)
3306cfdda9d7SSteve Wise 		release_ep_resources(ep);
3307cfdda9d7SSteve Wise 	return ret;
3308cfdda9d7SSteve Wise }
3309cfdda9d7SSteve Wise 
33101cab775cSVipul Pandya static void active_ofld_conn_reply(struct c4iw_dev *dev, struct sk_buff *skb,
33111cab775cSVipul Pandya 			struct cpl_fw6_msg_ofld_connection_wr_rpl *req)
33121cab775cSVipul Pandya {
33131cab775cSVipul Pandya 	struct c4iw_ep *ep;
3314793dad94SVipul Pandya 	int atid = be32_to_cpu(req->tid);
33151cab775cSVipul Pandya 
3316ef5d6355SVipul Pandya 	ep = (struct c4iw_ep *)lookup_atid(dev->rdev.lldi.tids,
3317ef5d6355SVipul Pandya 					   (__force u32) req->tid);
33181cab775cSVipul Pandya 	if (!ep)
33191cab775cSVipul Pandya 		return;
33201cab775cSVipul Pandya 
33211cab775cSVipul Pandya 	switch (req->retval) {
33221cab775cSVipul Pandya 	case FW_ENOMEM:
3323793dad94SVipul Pandya 		set_bit(ACT_RETRY_NOMEM, &ep->com.history);
3324793dad94SVipul Pandya 		if (ep->retry_count++ < ACT_OPEN_RETRY_COUNT) {
3325793dad94SVipul Pandya 			send_fw_act_open_req(ep, atid);
3326793dad94SVipul Pandya 			return;
3327793dad94SVipul Pandya 		}
33281cab775cSVipul Pandya 	case FW_EADDRINUSE:
3329793dad94SVipul Pandya 		set_bit(ACT_RETRY_INUSE, &ep->com.history);
3330793dad94SVipul Pandya 		if (ep->retry_count++ < ACT_OPEN_RETRY_COUNT) {
3331793dad94SVipul Pandya 			send_fw_act_open_req(ep, atid);
3332793dad94SVipul Pandya 			return;
3333793dad94SVipul Pandya 		}
33341cab775cSVipul Pandya 		break;
33351cab775cSVipul Pandya 	default:
33361cab775cSVipul Pandya 		pr_info("%s unexpected ofld conn wr retval %d\n",
33371cab775cSVipul Pandya 		       __func__, req->retval);
33381cab775cSVipul Pandya 		break;
33391cab775cSVipul Pandya 	}
3340793dad94SVipul Pandya 	pr_err("active ofld_connect_wr failure %d atid %d\n",
3341793dad94SVipul Pandya 	       req->retval, atid);
3342793dad94SVipul Pandya 	mutex_lock(&dev->rdev.stats.lock);
3343793dad94SVipul Pandya 	dev->rdev.stats.act_ofld_conn_fails++;
3344793dad94SVipul Pandya 	mutex_unlock(&dev->rdev.stats.lock);
33451cab775cSVipul Pandya 	connect_reply_upcall(ep, status2errno(req->retval));
3346793dad94SVipul Pandya 	state_set(&ep->com, DEAD);
3347793dad94SVipul Pandya 	remove_handle(dev, &dev->atid_idr, atid);
3348793dad94SVipul Pandya 	cxgb4_free_atid(dev->rdev.lldi.tids, atid);
3349793dad94SVipul Pandya 	dst_release(ep->dst);
3350793dad94SVipul Pandya 	cxgb4_l2t_release(ep->l2t);
3351793dad94SVipul Pandya 	c4iw_put_ep(&ep->com);
33521cab775cSVipul Pandya }
33531cab775cSVipul Pandya 
33541cab775cSVipul Pandya static void passive_ofld_conn_reply(struct c4iw_dev *dev, struct sk_buff *skb,
33551cab775cSVipul Pandya 			struct cpl_fw6_msg_ofld_connection_wr_rpl *req)
33561cab775cSVipul Pandya {
33571cab775cSVipul Pandya 	struct sk_buff *rpl_skb;
33581cab775cSVipul Pandya 	struct cpl_pass_accept_req *cpl;
33591cab775cSVipul Pandya 	int ret;
33601cab775cSVipul Pandya 
3361710a3110SPaul Bolle 	rpl_skb = (struct sk_buff *)(unsigned long)req->cookie;
33621cab775cSVipul Pandya 	BUG_ON(!rpl_skb);
33631cab775cSVipul Pandya 	if (req->retval) {
33641cab775cSVipul Pandya 		PDBG("%s passive open failure %d\n", __func__, req->retval);
3365793dad94SVipul Pandya 		mutex_lock(&dev->rdev.stats.lock);
3366793dad94SVipul Pandya 		dev->rdev.stats.pas_ofld_conn_fails++;
3367793dad94SVipul Pandya 		mutex_unlock(&dev->rdev.stats.lock);
33681cab775cSVipul Pandya 		kfree_skb(rpl_skb);
33691cab775cSVipul Pandya 	} else {
33701cab775cSVipul Pandya 		cpl = (struct cpl_pass_accept_req *)cplhdr(rpl_skb);
33711cab775cSVipul Pandya 		OPCODE_TID(cpl) = htonl(MK_OPCODE_TID(CPL_PASS_ACCEPT_REQ,
3372ef5d6355SVipul Pandya 					(__force u32) htonl(
3373ef5d6355SVipul Pandya 					(__force u32) req->tid)));
33741cab775cSVipul Pandya 		ret = pass_accept_req(dev, rpl_skb);
33751cab775cSVipul Pandya 		if (!ret)
33761cab775cSVipul Pandya 			kfree_skb(rpl_skb);
33771cab775cSVipul Pandya 	}
33781cab775cSVipul Pandya 	return;
33791cab775cSVipul Pandya }
33801cab775cSVipul Pandya 
33811cab775cSVipul Pandya static int deferred_fw6_msg(struct c4iw_dev *dev, struct sk_buff *skb)
33822f5b48c3SSteve Wise {
33832f5b48c3SSteve Wise 	struct cpl_fw6_msg *rpl = cplhdr(skb);
33841cab775cSVipul Pandya 	struct cpl_fw6_msg_ofld_connection_wr_rpl *req;
33851cab775cSVipul Pandya 
33861cab775cSVipul Pandya 	switch (rpl->type) {
33871cab775cSVipul Pandya 	case FW6_TYPE_CQE:
33882f5b48c3SSteve Wise 		c4iw_ev_dispatch(dev, (struct t4_cqe *)&rpl->data[0]);
33891cab775cSVipul Pandya 		break;
33901cab775cSVipul Pandya 	case FW6_TYPE_OFLD_CONNECTION_WR_RPL:
33911cab775cSVipul Pandya 		req = (struct cpl_fw6_msg_ofld_connection_wr_rpl *)rpl->data;
33921cab775cSVipul Pandya 		switch (req->t_state) {
33931cab775cSVipul Pandya 		case TCP_SYN_SENT:
33941cab775cSVipul Pandya 			active_ofld_conn_reply(dev, skb, req);
33951cab775cSVipul Pandya 			break;
33961cab775cSVipul Pandya 		case TCP_SYN_RECV:
33971cab775cSVipul Pandya 			passive_ofld_conn_reply(dev, skb, req);
33981cab775cSVipul Pandya 			break;
33991cab775cSVipul Pandya 		default:
34001cab775cSVipul Pandya 			pr_err("%s unexpected ofld conn wr state %d\n",
34011cab775cSVipul Pandya 			       __func__, req->t_state);
34021cab775cSVipul Pandya 			break;
34031cab775cSVipul Pandya 		}
34041cab775cSVipul Pandya 		break;
34051cab775cSVipul Pandya 	}
34061cab775cSVipul Pandya 	return 0;
34071cab775cSVipul Pandya }
34081cab775cSVipul Pandya 
34091cab775cSVipul Pandya static void build_cpl_pass_accept_req(struct sk_buff *skb, int stid , u8 tos)
34101cab775cSVipul Pandya {
34111cab775cSVipul Pandya 	u32 l2info;
3412f079af7aSVipul Pandya 	u16 vlantag, len, hdr_len, eth_hdr_len;
34131cab775cSVipul Pandya 	u8 intf;
34141cab775cSVipul Pandya 	struct cpl_rx_pkt *cpl = cplhdr(skb);
34151cab775cSVipul Pandya 	struct cpl_pass_accept_req *req;
34161cab775cSVipul Pandya 	struct tcp_options_received tmp_opt;
3417f079af7aSVipul Pandya 	struct c4iw_dev *dev;
34181cab775cSVipul Pandya 
3419f079af7aSVipul Pandya 	dev = *((struct c4iw_dev **) (skb->cb + sizeof(void *)));
34201cab775cSVipul Pandya 	/* Store values from cpl_rx_pkt in temporary location. */
3421ef5d6355SVipul Pandya 	vlantag = (__force u16) cpl->vlan;
3422ef5d6355SVipul Pandya 	len = (__force u16) cpl->len;
3423ef5d6355SVipul Pandya 	l2info  = (__force u32) cpl->l2info;
3424ef5d6355SVipul Pandya 	hdr_len = (__force u16) cpl->hdr_len;
34251cab775cSVipul Pandya 	intf = cpl->iff;
34261cab775cSVipul Pandya 
34271cab775cSVipul Pandya 	__skb_pull(skb, sizeof(*req) + sizeof(struct rss_header));
34281cab775cSVipul Pandya 
34291cab775cSVipul Pandya 	/*
34301cab775cSVipul Pandya 	 * We need to parse the TCP options from SYN packet.
34311cab775cSVipul Pandya 	 * to generate cpl_pass_accept_req.
34321cab775cSVipul Pandya 	 */
34331cab775cSVipul Pandya 	memset(&tmp_opt, 0, sizeof(tmp_opt));
34341cab775cSVipul Pandya 	tcp_clear_options(&tmp_opt);
34351a2c6181SChristoph Paasch 	tcp_parse_options(skb, &tmp_opt, 0, NULL);
34361cab775cSVipul Pandya 
34371cab775cSVipul Pandya 	req = (struct cpl_pass_accept_req *)__skb_push(skb, sizeof(*req));
34381cab775cSVipul Pandya 	memset(req, 0, sizeof(*req));
34391cab775cSVipul Pandya 	req->l2info = cpu_to_be16(V_SYN_INTF(intf) |
3440ef5d6355SVipul Pandya 			 V_SYN_MAC_IDX(G_RX_MACIDX(
3441ef5d6355SVipul Pandya 			 (__force int) htonl(l2info))) |
34421cab775cSVipul Pandya 			 F_SYN_XACT_MATCH);
3443f079af7aSVipul Pandya 	eth_hdr_len = is_t4(dev->rdev.lldi.adapter_type) ?
3444f079af7aSVipul Pandya 			    G_RX_ETHHDR_LEN((__force int) htonl(l2info)) :
3445f079af7aSVipul Pandya 			    G_RX_T5_ETHHDR_LEN((__force int) htonl(l2info));
3446ef5d6355SVipul Pandya 	req->hdr_len = cpu_to_be32(V_SYN_RX_CHAN(G_RX_CHAN(
3447ef5d6355SVipul Pandya 					(__force int) htonl(l2info))) |
3448ef5d6355SVipul Pandya 				   V_TCP_HDR_LEN(G_RX_TCPHDR_LEN(
3449ef5d6355SVipul Pandya 					(__force int) htons(hdr_len))) |
3450ef5d6355SVipul Pandya 				   V_IP_HDR_LEN(G_RX_IPHDR_LEN(
3451ef5d6355SVipul Pandya 					(__force int) htons(hdr_len))) |
3452f079af7aSVipul Pandya 				   V_ETH_HDR_LEN(G_RX_ETHHDR_LEN(eth_hdr_len)));
3453ef5d6355SVipul Pandya 	req->vlan = (__force __be16) vlantag;
3454ef5d6355SVipul Pandya 	req->len = (__force __be16) len;
34551cab775cSVipul Pandya 	req->tos_stid = cpu_to_be32(PASS_OPEN_TID(stid) |
34561cab775cSVipul Pandya 				    PASS_OPEN_TOS(tos));
34571cab775cSVipul Pandya 	req->tcpopt.mss = htons(tmp_opt.mss_clamp);
34581cab775cSVipul Pandya 	if (tmp_opt.wscale_ok)
34591cab775cSVipul Pandya 		req->tcpopt.wsf = tmp_opt.snd_wscale;
34601cab775cSVipul Pandya 	req->tcpopt.tstamp = tmp_opt.saw_tstamp;
34611cab775cSVipul Pandya 	if (tmp_opt.sack_ok)
34621cab775cSVipul Pandya 		req->tcpopt.sack = 1;
34631cab775cSVipul Pandya 	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_PASS_ACCEPT_REQ, 0));
34641cab775cSVipul Pandya 	return;
34651cab775cSVipul Pandya }
34661cab775cSVipul Pandya 
34671cab775cSVipul Pandya static void send_fw_pass_open_req(struct c4iw_dev *dev, struct sk_buff *skb,
34681cab775cSVipul Pandya 				  __be32 laddr, __be16 lport,
34691cab775cSVipul Pandya 				  __be32 raddr, __be16 rport,
34701cab775cSVipul Pandya 				  u32 rcv_isn, u32 filter, u16 window,
34711cab775cSVipul Pandya 				  u32 rss_qid, u8 port_id)
34721cab775cSVipul Pandya {
34731cab775cSVipul Pandya 	struct sk_buff *req_skb;
34741cab775cSVipul Pandya 	struct fw_ofld_connection_wr *req;
34751cab775cSVipul Pandya 	struct cpl_pass_accept_req *cpl = cplhdr(skb);
34761ce1d471SSteve Wise 	int ret;
34771cab775cSVipul Pandya 
34781cab775cSVipul Pandya 	req_skb = alloc_skb(sizeof(struct fw_ofld_connection_wr), GFP_KERNEL);
34791cab775cSVipul Pandya 	req = (struct fw_ofld_connection_wr *)__skb_put(req_skb, sizeof(*req));
34801cab775cSVipul Pandya 	memset(req, 0, sizeof(*req));
34811cab775cSVipul Pandya 	req->op_compl = htonl(V_WR_OP(FW_OFLD_CONNECTION_WR) | FW_WR_COMPL(1));
34821cab775cSVipul Pandya 	req->len16_pkd = htonl(FW_WR_LEN16(DIV_ROUND_UP(sizeof(*req), 16)));
34831cab775cSVipul Pandya 	req->le.version_cpl = htonl(F_FW_OFLD_CONNECTION_WR_CPL);
3484ef5d6355SVipul Pandya 	req->le.filter = (__force __be32) filter;
34851cab775cSVipul Pandya 	req->le.lport = lport;
34861cab775cSVipul Pandya 	req->le.pport = rport;
34871cab775cSVipul Pandya 	req->le.u.ipv4.lip = laddr;
34881cab775cSVipul Pandya 	req->le.u.ipv4.pip = raddr;
34891cab775cSVipul Pandya 	req->tcb.rcv_nxt = htonl(rcv_isn + 1);
34901cab775cSVipul Pandya 	req->tcb.rcv_adv = htons(window);
34911cab775cSVipul Pandya 	req->tcb.t_state_to_astid =
34921cab775cSVipul Pandya 		 htonl(V_FW_OFLD_CONNECTION_WR_T_STATE(TCP_SYN_RECV) |
34931cab775cSVipul Pandya 			V_FW_OFLD_CONNECTION_WR_RCV_SCALE(cpl->tcpopt.wsf) |
34941cab775cSVipul Pandya 			V_FW_OFLD_CONNECTION_WR_ASTID(
34951cab775cSVipul Pandya 			GET_PASS_OPEN_TID(ntohl(cpl->tos_stid))));
34961cab775cSVipul Pandya 
34971cab775cSVipul Pandya 	/*
34981cab775cSVipul Pandya 	 * We store the qid in opt2 which will be used by the firmware
34991cab775cSVipul Pandya 	 * to send us the wr response.
35001cab775cSVipul Pandya 	 */
35011cab775cSVipul Pandya 	req->tcb.opt2 = htonl(V_RSS_QUEUE(rss_qid));
35021cab775cSVipul Pandya 
35031cab775cSVipul Pandya 	/*
35041cab775cSVipul Pandya 	 * We initialize the MSS index in TCB to 0xF.
35051cab775cSVipul Pandya 	 * So that when driver sends cpl_pass_accept_rpl
35061cab775cSVipul Pandya 	 * TCB picks up the correct value. If this was 0
35071cab775cSVipul Pandya 	 * TP will ignore any value > 0 for MSS index.
35081cab775cSVipul Pandya 	 */
35091cab775cSVipul Pandya 	req->tcb.opt0 = cpu_to_be64(V_MSS_IDX(0xF));
3510710a3110SPaul Bolle 	req->cookie = (unsigned long)skb;
35111cab775cSVipul Pandya 
35121cab775cSVipul Pandya 	set_wr_txq(req_skb, CPL_PRIORITY_CONTROL, port_id);
35131ce1d471SSteve Wise 	ret = cxgb4_ofld_send(dev->rdev.lldi.ports[0], req_skb);
35141ce1d471SSteve Wise 	if (ret < 0) {
35151ce1d471SSteve Wise 		pr_err("%s - cxgb4_ofld_send error %d - dropping\n", __func__,
35161ce1d471SSteve Wise 		       ret);
35171ce1d471SSteve Wise 		kfree_skb(skb);
35181ce1d471SSteve Wise 		kfree_skb(req_skb);
35191ce1d471SSteve Wise 	}
35201cab775cSVipul Pandya }
35211cab775cSVipul Pandya 
35221cab775cSVipul Pandya /*
35231cab775cSVipul Pandya  * Handler for CPL_RX_PKT message. Need to handle cpl_rx_pkt
35241cab775cSVipul Pandya  * messages when a filter is being used instead of server to
35251cab775cSVipul Pandya  * redirect a syn packet. When packets hit filter they are redirected
35261cab775cSVipul Pandya  * to the offload queue and driver tries to establish the connection
35271cab775cSVipul Pandya  * using firmware work request.
35281cab775cSVipul Pandya  */
35291cab775cSVipul Pandya static int rx_pkt(struct c4iw_dev *dev, struct sk_buff *skb)
35301cab775cSVipul Pandya {
35311cab775cSVipul Pandya 	int stid;
35321cab775cSVipul Pandya 	unsigned int filter;
35331cab775cSVipul Pandya 	struct ethhdr *eh = NULL;
35341cab775cSVipul Pandya 	struct vlan_ethhdr *vlan_eh = NULL;
35351cab775cSVipul Pandya 	struct iphdr *iph;
35361cab775cSVipul Pandya 	struct tcphdr *tcph;
35371cab775cSVipul Pandya 	struct rss_header *rss = (void *)skb->data;
35381cab775cSVipul Pandya 	struct cpl_rx_pkt *cpl = (void *)skb->data;
35391cab775cSVipul Pandya 	struct cpl_pass_accept_req *req = (void *)(rss + 1);
35401cab775cSVipul Pandya 	struct l2t_entry *e;
35411cab775cSVipul Pandya 	struct dst_entry *dst;
35421cab775cSVipul Pandya 	struct c4iw_ep *lep;
35431cab775cSVipul Pandya 	u16 window;
35441cab775cSVipul Pandya 	struct port_info *pi;
35451cab775cSVipul Pandya 	struct net_device *pdev;
3546f079af7aSVipul Pandya 	u16 rss_qid, eth_hdr_len;
35471cab775cSVipul Pandya 	int step;
35481cab775cSVipul Pandya 	u32 tx_chan;
35491cab775cSVipul Pandya 	struct neighbour *neigh;
35501cab775cSVipul Pandya 
35511cab775cSVipul Pandya 	/* Drop all non-SYN packets */
35521cab775cSVipul Pandya 	if (!(cpl->l2info & cpu_to_be32(F_RXF_SYN)))
35531cab775cSVipul Pandya 		goto reject;
35541cab775cSVipul Pandya 
35551cab775cSVipul Pandya 	/*
35561cab775cSVipul Pandya 	 * Drop all packets which did not hit the filter.
35571cab775cSVipul Pandya 	 * Unlikely to happen.
35581cab775cSVipul Pandya 	 */
35591cab775cSVipul Pandya 	if (!(rss->filter_hit && rss->filter_tid))
35601cab775cSVipul Pandya 		goto reject;
35611cab775cSVipul Pandya 
35621cab775cSVipul Pandya 	/*
35631cab775cSVipul Pandya 	 * Calculate the server tid from filter hit index from cpl_rx_pkt.
35641cab775cSVipul Pandya 	 */
3565a4ea025fSKumar Sanghvi 	stid = (__force int) cpu_to_be32((__force u32) rss->hash_val);
35661cab775cSVipul Pandya 
35671cab775cSVipul Pandya 	lep = (struct c4iw_ep *)lookup_stid(dev->rdev.lldi.tids, stid);
35681cab775cSVipul Pandya 	if (!lep) {
35691cab775cSVipul Pandya 		PDBG("%s connect request on invalid stid %d\n", __func__, stid);
35701cab775cSVipul Pandya 		goto reject;
35711cab775cSVipul Pandya 	}
35721cab775cSVipul Pandya 
3573f079af7aSVipul Pandya 	eth_hdr_len = is_t4(dev->rdev.lldi.adapter_type) ?
3574f079af7aSVipul Pandya 			    G_RX_ETHHDR_LEN(htonl(cpl->l2info)) :
3575f079af7aSVipul Pandya 			    G_RX_T5_ETHHDR_LEN(htonl(cpl->l2info));
3576f079af7aSVipul Pandya 	if (eth_hdr_len == ETH_HLEN) {
35771cab775cSVipul Pandya 		eh = (struct ethhdr *)(req + 1);
35781cab775cSVipul Pandya 		iph = (struct iphdr *)(eh + 1);
35791cab775cSVipul Pandya 	} else {
35801cab775cSVipul Pandya 		vlan_eh = (struct vlan_ethhdr *)(req + 1);
35811cab775cSVipul Pandya 		iph = (struct iphdr *)(vlan_eh + 1);
35821cab775cSVipul Pandya 		skb->vlan_tci = ntohs(cpl->vlan);
35831cab775cSVipul Pandya 	}
35841cab775cSVipul Pandya 
35851cab775cSVipul Pandya 	if (iph->version != 0x4)
35861cab775cSVipul Pandya 		goto reject;
35871cab775cSVipul Pandya 
35881cab775cSVipul Pandya 	tcph = (struct tcphdr *)(iph + 1);
35891cab775cSVipul Pandya 	skb_set_network_header(skb, (void *)iph - (void *)rss);
35901cab775cSVipul Pandya 	skb_set_transport_header(skb, (void *)tcph - (void *)rss);
35911cab775cSVipul Pandya 	skb_get(skb);
35921cab775cSVipul Pandya 
35931cab775cSVipul Pandya 	PDBG("%s lip 0x%x lport %u pip 0x%x pport %u tos %d\n", __func__,
35941cab775cSVipul Pandya 	     ntohl(iph->daddr), ntohs(tcph->dest), ntohl(iph->saddr),
35951cab775cSVipul Pandya 	     ntohs(tcph->source), iph->tos);
35961cab775cSVipul Pandya 
3597830662f6SVipul Pandya 	dst = find_route(dev, iph->daddr, iph->saddr, tcph->dest, tcph->source,
35981cab775cSVipul Pandya 			 iph->tos);
3599830662f6SVipul Pandya 	if (!dst) {
36001cab775cSVipul Pandya 		pr_err("%s - failed to find dst entry!\n",
36011cab775cSVipul Pandya 		       __func__);
36021cab775cSVipul Pandya 		goto reject;
36031cab775cSVipul Pandya 	}
36041cab775cSVipul Pandya 	neigh = dst_neigh_lookup_skb(dst, skb);
36051cab775cSVipul Pandya 
3606aaa0c23cSZhouyi Zhou 	if (!neigh) {
3607aaa0c23cSZhouyi Zhou 		pr_err("%s - failed to allocate neigh!\n",
3608aaa0c23cSZhouyi Zhou 		       __func__);
3609aaa0c23cSZhouyi Zhou 		goto free_dst;
3610aaa0c23cSZhouyi Zhou 	}
3611aaa0c23cSZhouyi Zhou 
36121cab775cSVipul Pandya 	if (neigh->dev->flags & IFF_LOOPBACK) {
36131cab775cSVipul Pandya 		pdev = ip_dev_find(&init_net, iph->daddr);
36141cab775cSVipul Pandya 		e = cxgb4_l2t_get(dev->rdev.lldi.l2t, neigh,
36151cab775cSVipul Pandya 				    pdev, 0);
36161cab775cSVipul Pandya 		pi = (struct port_info *)netdev_priv(pdev);
36171cab775cSVipul Pandya 		tx_chan = cxgb4_port_chan(pdev);
36181cab775cSVipul Pandya 		dev_put(pdev);
36191cab775cSVipul Pandya 	} else {
3620830662f6SVipul Pandya 		pdev = get_real_dev(neigh->dev);
36211cab775cSVipul Pandya 		e = cxgb4_l2t_get(dev->rdev.lldi.l2t, neigh,
3622830662f6SVipul Pandya 					pdev, 0);
3623830662f6SVipul Pandya 		pi = (struct port_info *)netdev_priv(pdev);
3624830662f6SVipul Pandya 		tx_chan = cxgb4_port_chan(pdev);
36251cab775cSVipul Pandya 	}
3626ebf00060SSteve Wise 	neigh_release(neigh);
36271cab775cSVipul Pandya 	if (!e) {
36281cab775cSVipul Pandya 		pr_err("%s - failed to allocate l2t entry!\n",
36291cab775cSVipul Pandya 		       __func__);
36301cab775cSVipul Pandya 		goto free_dst;
36311cab775cSVipul Pandya 	}
36321cab775cSVipul Pandya 
36331cab775cSVipul Pandya 	step = dev->rdev.lldi.nrxq / dev->rdev.lldi.nchan;
36341cab775cSVipul Pandya 	rss_qid = dev->rdev.lldi.rxq_ids[pi->port_id * step];
3635ef5d6355SVipul Pandya 	window = (__force u16) htons((__force u16)tcph->window);
36361cab775cSVipul Pandya 
36371cab775cSVipul Pandya 	/* Calcuate filter portion for LE region. */
363841b4f86cSKumar Sanghvi 	filter = (__force unsigned int) cpu_to_be32(cxgb4_select_ntuple(
363941b4f86cSKumar Sanghvi 						    dev->rdev.lldi.ports[0],
364041b4f86cSKumar Sanghvi 						    e));
36411cab775cSVipul Pandya 
36421cab775cSVipul Pandya 	/*
36431cab775cSVipul Pandya 	 * Synthesize the cpl_pass_accept_req. We have everything except the
36441cab775cSVipul Pandya 	 * TID. Once firmware sends a reply with TID we update the TID field
36451cab775cSVipul Pandya 	 * in cpl and pass it through the regular cpl_pass_accept_req path.
36461cab775cSVipul Pandya 	 */
36471cab775cSVipul Pandya 	build_cpl_pass_accept_req(skb, stid, iph->tos);
36481cab775cSVipul Pandya 	send_fw_pass_open_req(dev, skb, iph->daddr, tcph->dest, iph->saddr,
36491cab775cSVipul Pandya 			      tcph->source, ntohl(tcph->seq), filter, window,
36501cab775cSVipul Pandya 			      rss_qid, pi->port_id);
36511cab775cSVipul Pandya 	cxgb4_l2t_release(e);
36521cab775cSVipul Pandya free_dst:
36531cab775cSVipul Pandya 	dst_release(dst);
36541cab775cSVipul Pandya reject:
36552f5b48c3SSteve Wise 	return 0;
36562f5b48c3SSteve Wise }
36572f5b48c3SSteve Wise 
3658cfdda9d7SSteve Wise /*
3659be4c9badSRoland Dreier  * These are the real handlers that are called from a
3660be4c9badSRoland Dreier  * work queue.
3661be4c9badSRoland Dreier  */
3662be4c9badSRoland Dreier static c4iw_handler_func work_handlers[NUM_CPL_CMDS] = {
3663be4c9badSRoland Dreier 	[CPL_ACT_ESTABLISH] = act_establish,
3664be4c9badSRoland Dreier 	[CPL_ACT_OPEN_RPL] = act_open_rpl,
3665be4c9badSRoland Dreier 	[CPL_RX_DATA] = rx_data,
3666be4c9badSRoland Dreier 	[CPL_ABORT_RPL_RSS] = abort_rpl,
3667be4c9badSRoland Dreier 	[CPL_ABORT_RPL] = abort_rpl,
3668be4c9badSRoland Dreier 	[CPL_PASS_OPEN_RPL] = pass_open_rpl,
3669be4c9badSRoland Dreier 	[CPL_CLOSE_LISTSRV_RPL] = close_listsrv_rpl,
3670be4c9badSRoland Dreier 	[CPL_PASS_ACCEPT_REQ] = pass_accept_req,
3671be4c9badSRoland Dreier 	[CPL_PASS_ESTABLISH] = pass_establish,
3672be4c9badSRoland Dreier 	[CPL_PEER_CLOSE] = peer_close,
3673be4c9badSRoland Dreier 	[CPL_ABORT_REQ_RSS] = peer_abort,
3674be4c9badSRoland Dreier 	[CPL_CLOSE_CON_RPL] = close_con_rpl,
3675be4c9badSRoland Dreier 	[CPL_RDMA_TERMINATE] = terminate,
36762f5b48c3SSteve Wise 	[CPL_FW4_ACK] = fw4_ack,
36771cab775cSVipul Pandya 	[CPL_FW6_MSG] = deferred_fw6_msg,
36781cab775cSVipul Pandya 	[CPL_RX_PKT] = rx_pkt
3679be4c9badSRoland Dreier };
3680be4c9badSRoland Dreier 
3681be4c9badSRoland Dreier static void process_timeout(struct c4iw_ep *ep)
3682be4c9badSRoland Dreier {
3683be4c9badSRoland Dreier 	struct c4iw_qp_attributes attrs;
3684be4c9badSRoland Dreier 	int abort = 1;
3685be4c9badSRoland Dreier 
36862f5b48c3SSteve Wise 	mutex_lock(&ep->com.mutex);
3687be4c9badSRoland Dreier 	PDBG("%s ep %p tid %u state %d\n", __func__, ep, ep->hwtid,
3688be4c9badSRoland Dreier 	     ep->com.state);
3689793dad94SVipul Pandya 	set_bit(TIMEDOUT, &ep->com.history);
3690be4c9badSRoland Dreier 	switch (ep->com.state) {
3691be4c9badSRoland Dreier 	case MPA_REQ_SENT:
3692be4c9badSRoland Dreier 		__state_set(&ep->com, ABORTING);
3693be4c9badSRoland Dreier 		connect_reply_upcall(ep, -ETIMEDOUT);
3694be4c9badSRoland Dreier 		break;
3695be4c9badSRoland Dreier 	case MPA_REQ_WAIT:
3696be4c9badSRoland Dreier 		__state_set(&ep->com, ABORTING);
3697be4c9badSRoland Dreier 		break;
3698be4c9badSRoland Dreier 	case CLOSING:
3699be4c9badSRoland Dreier 	case MORIBUND:
3700be4c9badSRoland Dreier 		if (ep->com.cm_id && ep->com.qp) {
3701be4c9badSRoland Dreier 			attrs.next_state = C4IW_QP_STATE_ERROR;
3702be4c9badSRoland Dreier 			c4iw_modify_qp(ep->com.qp->rhp,
3703be4c9badSRoland Dreier 				     ep->com.qp, C4IW_QP_ATTR_NEXT_STATE,
3704be4c9badSRoland Dreier 				     &attrs, 1);
3705be4c9badSRoland Dreier 		}
3706be4c9badSRoland Dreier 		__state_set(&ep->com, ABORTING);
3707be13b2dfSSteve Wise 		close_complete_upcall(ep, -ETIMEDOUT);
3708be4c9badSRoland Dreier 		break;
3709b33bd0cbSSteve Wise 	case ABORTING:
3710b33bd0cbSSteve Wise 	case DEAD:
3711b33bd0cbSSteve Wise 
3712b33bd0cbSSteve Wise 		/*
3713b33bd0cbSSteve Wise 		 * These states are expected if the ep timed out at the same
3714b33bd0cbSSteve Wise 		 * time as another thread was calling stop_ep_timer().
3715b33bd0cbSSteve Wise 		 * So we silently do nothing for these states.
3716b33bd0cbSSteve Wise 		 */
3717b33bd0cbSSteve Wise 		abort = 0;
3718b33bd0cbSSteve Wise 		break;
3719be4c9badSRoland Dreier 	default:
372076f267b7SJulia Lawall 		WARN(1, "%s unexpected state ep %p tid %u state %u\n",
3721be4c9badSRoland Dreier 			__func__, ep, ep->hwtid, ep->com.state);
3722be4c9badSRoland Dreier 		abort = 0;
3723be4c9badSRoland Dreier 	}
3724be4c9badSRoland Dreier 	if (abort)
3725be4c9badSRoland Dreier 		abort_connection(ep, NULL, GFP_KERNEL);
3726cc18b939SSteve Wise 	mutex_unlock(&ep->com.mutex);
3727be4c9badSRoland Dreier 	c4iw_put_ep(&ep->com);
3728be4c9badSRoland Dreier }
3729be4c9badSRoland Dreier 
3730be4c9badSRoland Dreier static void process_timedout_eps(void)
3731be4c9badSRoland Dreier {
3732be4c9badSRoland Dreier 	struct c4iw_ep *ep;
3733be4c9badSRoland Dreier 
3734be4c9badSRoland Dreier 	spin_lock_irq(&timeout_lock);
3735be4c9badSRoland Dreier 	while (!list_empty(&timeout_list)) {
3736be4c9badSRoland Dreier 		struct list_head *tmp;
3737be4c9badSRoland Dreier 
3738be4c9badSRoland Dreier 		tmp = timeout_list.next;
3739be4c9badSRoland Dreier 		list_del(tmp);
3740b33bd0cbSSteve Wise 		tmp->next = NULL;
3741b33bd0cbSSteve Wise 		tmp->prev = NULL;
3742be4c9badSRoland Dreier 		spin_unlock_irq(&timeout_lock);
3743be4c9badSRoland Dreier 		ep = list_entry(tmp, struct c4iw_ep, entry);
3744be4c9badSRoland Dreier 		process_timeout(ep);
3745be4c9badSRoland Dreier 		spin_lock_irq(&timeout_lock);
3746be4c9badSRoland Dreier 	}
3747be4c9badSRoland Dreier 	spin_unlock_irq(&timeout_lock);
3748be4c9badSRoland Dreier }
3749be4c9badSRoland Dreier 
3750be4c9badSRoland Dreier static void process_work(struct work_struct *work)
3751be4c9badSRoland Dreier {
3752be4c9badSRoland Dreier 	struct sk_buff *skb = NULL;
3753be4c9badSRoland Dreier 	struct c4iw_dev *dev;
3754c1d7356cSDan Carpenter 	struct cpl_act_establish *rpl;
3755be4c9badSRoland Dreier 	unsigned int opcode;
3756be4c9badSRoland Dreier 	int ret;
3757be4c9badSRoland Dreier 
3758b33bd0cbSSteve Wise 	process_timedout_eps();
3759be4c9badSRoland Dreier 	while ((skb = skb_dequeue(&rxq))) {
3760be4c9badSRoland Dreier 		rpl = cplhdr(skb);
3761be4c9badSRoland Dreier 		dev = *((struct c4iw_dev **) (skb->cb + sizeof(void *)));
3762be4c9badSRoland Dreier 		opcode = rpl->ot.opcode;
3763be4c9badSRoland Dreier 
3764be4c9badSRoland Dreier 		BUG_ON(!work_handlers[opcode]);
3765be4c9badSRoland Dreier 		ret = work_handlers[opcode](dev, skb);
3766be4c9badSRoland Dreier 		if (!ret)
3767be4c9badSRoland Dreier 			kfree_skb(skb);
3768be4c9badSRoland Dreier 		process_timedout_eps();
3769be4c9badSRoland Dreier 	}
3770b33bd0cbSSteve Wise }
3771be4c9badSRoland Dreier 
3772be4c9badSRoland Dreier static DECLARE_WORK(skb_work, process_work);
3773be4c9badSRoland Dreier 
3774be4c9badSRoland Dreier static void ep_timeout(unsigned long arg)
3775be4c9badSRoland Dreier {
3776be4c9badSRoland Dreier 	struct c4iw_ep *ep = (struct c4iw_ep *)arg;
37771ec779ccSVipul Pandya 	int kickit = 0;
3778be4c9badSRoland Dreier 
3779be4c9badSRoland Dreier 	spin_lock(&timeout_lock);
37801ec779ccSVipul Pandya 	if (!test_and_set_bit(TIMEOUT, &ep->com.flags)) {
3781b33bd0cbSSteve Wise 		/*
3782b33bd0cbSSteve Wise 		 * Only insert if it is not already on the list.
3783b33bd0cbSSteve Wise 		 */
3784b33bd0cbSSteve Wise 		if (!ep->entry.next) {
3785be4c9badSRoland Dreier 			list_add_tail(&ep->entry, &timeout_list);
37861ec779ccSVipul Pandya 			kickit = 1;
37871ec779ccSVipul Pandya 		}
3788b33bd0cbSSteve Wise 	}
3789be4c9badSRoland Dreier 	spin_unlock(&timeout_lock);
37901ec779ccSVipul Pandya 	if (kickit)
3791be4c9badSRoland Dreier 		queue_work(workq, &skb_work);
3792be4c9badSRoland Dreier }
3793be4c9badSRoland Dreier 
3794be4c9badSRoland Dreier /*
3795cfdda9d7SSteve Wise  * All the CM events are handled on a work queue to have a safe context.
3796cfdda9d7SSteve Wise  */
3797cfdda9d7SSteve Wise static int sched(struct c4iw_dev *dev, struct sk_buff *skb)
3798cfdda9d7SSteve Wise {
3799cfdda9d7SSteve Wise 
3800cfdda9d7SSteve Wise 	/*
3801cfdda9d7SSteve Wise 	 * Save dev in the skb->cb area.
3802cfdda9d7SSteve Wise 	 */
3803cfdda9d7SSteve Wise 	*((struct c4iw_dev **) (skb->cb + sizeof(void *))) = dev;
3804cfdda9d7SSteve Wise 
3805cfdda9d7SSteve Wise 	/*
3806cfdda9d7SSteve Wise 	 * Queue the skb and schedule the worker thread.
3807cfdda9d7SSteve Wise 	 */
3808cfdda9d7SSteve Wise 	skb_queue_tail(&rxq, skb);
3809cfdda9d7SSteve Wise 	queue_work(workq, &skb_work);
3810cfdda9d7SSteve Wise 	return 0;
3811cfdda9d7SSteve Wise }
3812cfdda9d7SSteve Wise 
3813cfdda9d7SSteve Wise static int set_tcb_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
3814cfdda9d7SSteve Wise {
3815cfdda9d7SSteve Wise 	struct cpl_set_tcb_rpl *rpl = cplhdr(skb);
3816cfdda9d7SSteve Wise 
3817cfdda9d7SSteve Wise 	if (rpl->status != CPL_ERR_NONE) {
3818cfdda9d7SSteve Wise 		printk(KERN_ERR MOD "Unexpected SET_TCB_RPL status %u "
3819cfdda9d7SSteve Wise 		       "for tid %u\n", rpl->status, GET_TID(rpl));
3820cfdda9d7SSteve Wise 	}
38212f5b48c3SSteve Wise 	kfree_skb(skb);
3822cfdda9d7SSteve Wise 	return 0;
3823cfdda9d7SSteve Wise }
3824cfdda9d7SSteve Wise 
3825be4c9badSRoland Dreier static int fw6_msg(struct c4iw_dev *dev, struct sk_buff *skb)
3826be4c9badSRoland Dreier {
3827be4c9badSRoland Dreier 	struct cpl_fw6_msg *rpl = cplhdr(skb);
3828be4c9badSRoland Dreier 	struct c4iw_wr_wait *wr_waitp;
3829be4c9badSRoland Dreier 	int ret;
3830be4c9badSRoland Dreier 
3831be4c9badSRoland Dreier 	PDBG("%s type %u\n", __func__, rpl->type);
3832be4c9badSRoland Dreier 
3833be4c9badSRoland Dreier 	switch (rpl->type) {
38345be78ee9SVipul Pandya 	case FW6_TYPE_WR_RPL:
3835be4c9badSRoland Dreier 		ret = (int)((be64_to_cpu(rpl->data[0]) >> 8) & 0xff);
3836c8e081a1SRoland Dreier 		wr_waitp = (struct c4iw_wr_wait *)(__force unsigned long) rpl->data[1];
3837be4c9badSRoland Dreier 		PDBG("%s wr_waitp %p ret %u\n", __func__, wr_waitp, ret);
3838d9594d99SSteve Wise 		if (wr_waitp)
3839d9594d99SSteve Wise 			c4iw_wake_up(wr_waitp, ret ? -ret : 0);
38402f5b48c3SSteve Wise 		kfree_skb(skb);
3841be4c9badSRoland Dreier 		break;
38425be78ee9SVipul Pandya 	case FW6_TYPE_CQE:
38435be78ee9SVipul Pandya 	case FW6_TYPE_OFLD_CONNECTION_WR_RPL:
38441cab775cSVipul Pandya 		sched(dev, skb);
38455be78ee9SVipul Pandya 		break;
3846be4c9badSRoland Dreier 	default:
3847be4c9badSRoland Dreier 		printk(KERN_ERR MOD "%s unexpected fw6 msg type %u\n", __func__,
3848be4c9badSRoland Dreier 		       rpl->type);
38492f5b48c3SSteve Wise 		kfree_skb(skb);
3850be4c9badSRoland Dreier 		break;
3851be4c9badSRoland Dreier 	}
3852be4c9badSRoland Dreier 	return 0;
3853be4c9badSRoland Dreier }
3854be4c9badSRoland Dreier 
38558da7e7a5SSteve Wise static int peer_abort_intr(struct c4iw_dev *dev, struct sk_buff *skb)
38568da7e7a5SSteve Wise {
38578da7e7a5SSteve Wise 	struct cpl_abort_req_rss *req = cplhdr(skb);
38588da7e7a5SSteve Wise 	struct c4iw_ep *ep;
38598da7e7a5SSteve Wise 	struct tid_info *t = dev->rdev.lldi.tids;
38608da7e7a5SSteve Wise 	unsigned int tid = GET_TID(req);
38618da7e7a5SSteve Wise 
38628da7e7a5SSteve Wise 	ep = lookup_tid(t, tid);
386314b92228SSteve Wise 	if (!ep) {
386414b92228SSteve Wise 		printk(KERN_WARNING MOD
386514b92228SSteve Wise 		       "Abort on non-existent endpoint, tid %d\n", tid);
386614b92228SSteve Wise 		kfree_skb(skb);
386714b92228SSteve Wise 		return 0;
386814b92228SSteve Wise 	}
38697a2cea2aSSteve Wise 	if (is_neg_adv(req->status)) {
38708da7e7a5SSteve Wise 		PDBG("%s neg_adv_abort ep %p tid %u\n", __func__, ep,
38718da7e7a5SSteve Wise 		     ep->hwtid);
38728da7e7a5SSteve Wise 		kfree_skb(skb);
38738da7e7a5SSteve Wise 		return 0;
38748da7e7a5SSteve Wise 	}
38758da7e7a5SSteve Wise 	PDBG("%s ep %p tid %u state %u\n", __func__, ep, ep->hwtid,
38768da7e7a5SSteve Wise 	     ep->com.state);
38778da7e7a5SSteve Wise 
38788da7e7a5SSteve Wise 	/*
38798da7e7a5SSteve Wise 	 * Wake up any threads in rdma_init() or rdma_fini().
38807c0a33d6SVipul Pandya 	 * However, if we are on MPAv2 and want to retry with MPAv1
38817c0a33d6SVipul Pandya 	 * then, don't wake up yet.
38828da7e7a5SSteve Wise 	 */
38837c0a33d6SVipul Pandya 	if (mpa_rev == 2 && !ep->tried_with_mpa_v1) {
38847c0a33d6SVipul Pandya 		if (ep->com.state != MPA_REQ_SENT)
38857c0a33d6SVipul Pandya 			c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET);
38867c0a33d6SVipul Pandya 	} else
38878da7e7a5SSteve Wise 		c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET);
38888da7e7a5SSteve Wise 	sched(dev, skb);
38898da7e7a5SSteve Wise 	return 0;
38908da7e7a5SSteve Wise }
38918da7e7a5SSteve Wise 
3892be4c9badSRoland Dreier /*
3893be4c9badSRoland Dreier  * Most upcalls from the T4 Core go to sched() to
3894be4c9badSRoland Dreier  * schedule the processing on a work queue.
3895be4c9badSRoland Dreier  */
3896be4c9badSRoland Dreier c4iw_handler_func c4iw_handlers[NUM_CPL_CMDS] = {
3897be4c9badSRoland Dreier 	[CPL_ACT_ESTABLISH] = sched,
3898be4c9badSRoland Dreier 	[CPL_ACT_OPEN_RPL] = sched,
3899be4c9badSRoland Dreier 	[CPL_RX_DATA] = sched,
3900be4c9badSRoland Dreier 	[CPL_ABORT_RPL_RSS] = sched,
3901be4c9badSRoland Dreier 	[CPL_ABORT_RPL] = sched,
3902be4c9badSRoland Dreier 	[CPL_PASS_OPEN_RPL] = sched,
3903be4c9badSRoland Dreier 	[CPL_CLOSE_LISTSRV_RPL] = sched,
3904be4c9badSRoland Dreier 	[CPL_PASS_ACCEPT_REQ] = sched,
3905be4c9badSRoland Dreier 	[CPL_PASS_ESTABLISH] = sched,
3906be4c9badSRoland Dreier 	[CPL_PEER_CLOSE] = sched,
3907be4c9badSRoland Dreier 	[CPL_CLOSE_CON_RPL] = sched,
39088da7e7a5SSteve Wise 	[CPL_ABORT_REQ_RSS] = peer_abort_intr,
3909be4c9badSRoland Dreier 	[CPL_RDMA_TERMINATE] = sched,
3910be4c9badSRoland Dreier 	[CPL_FW4_ACK] = sched,
3911be4c9badSRoland Dreier 	[CPL_SET_TCB_RPL] = set_tcb_rpl,
39121cab775cSVipul Pandya 	[CPL_FW6_MSG] = fw6_msg,
39131cab775cSVipul Pandya 	[CPL_RX_PKT] = sched
3914be4c9badSRoland Dreier };
3915be4c9badSRoland Dreier 
3916cfdda9d7SSteve Wise int __init c4iw_cm_init(void)
3917cfdda9d7SSteve Wise {
3918be4c9badSRoland Dreier 	spin_lock_init(&timeout_lock);
3919cfdda9d7SSteve Wise 	skb_queue_head_init(&rxq);
3920cfdda9d7SSteve Wise 
3921cfdda9d7SSteve Wise 	workq = create_singlethread_workqueue("iw_cxgb4");
3922cfdda9d7SSteve Wise 	if (!workq)
3923cfdda9d7SSteve Wise 		return -ENOMEM;
3924cfdda9d7SSteve Wise 
3925cfdda9d7SSteve Wise 	return 0;
3926cfdda9d7SSteve Wise }
3927cfdda9d7SSteve Wise 
3928cfdda9d7SSteve Wise void __exit c4iw_cm_term(void)
3929cfdda9d7SSteve Wise {
3930be4c9badSRoland Dreier 	WARN_ON(!list_empty(&timeout_list));
3931cfdda9d7SSteve Wise 	flush_workqueue(workq);
3932cfdda9d7SSteve Wise 	destroy_workqueue(workq);
3933cfdda9d7SSteve Wise }
3934