blob: 185452abf32cf336049e20802759a4352996392b [file] [log] [blame]
Steve Wisecfdda9d2010-04-21 15:30:06 -07001/*
2 * Copyright (c) 2009-2010 Chelsio, Inc. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 */
32#include <linux/module.h>
33#include <linux/list.h>
34#include <linux/workqueue.h>
35#include <linux/skbuff.h>
36#include <linux/timer.h>
37#include <linux/notifier.h>
38#include <linux/inetdevice.h>
39#include <linux/ip.h>
40#include <linux/tcp.h>
Vipul Pandya1cab7752012-12-10 09:30:55 +000041#include <linux/if_vlan.h>
Steve Wisecfdda9d2010-04-21 15:30:06 -070042
43#include <net/neighbour.h>
44#include <net/netevent.h>
45#include <net/route.h>
Vipul Pandya1cab7752012-12-10 09:30:55 +000046#include <net/tcp.h>
Vipul Pandya830662f2013-07-04 16:10:47 +053047#include <net/ip6_route.h>
48#include <net/addrconf.h>
Steve Wisecfdda9d2010-04-21 15:30:06 -070049
50#include "iw_cxgb4.h"
51
52static char *states[] = {
53 "idle",
54 "listen",
55 "connecting",
56 "mpa_wait_req",
57 "mpa_req_sent",
58 "mpa_req_rcvd",
59 "mpa_rep_sent",
60 "fpdu_mode",
61 "aborting",
62 "closing",
63 "moribund",
64 "dead",
65 NULL,
66};
67
Vipul Pandya5be78ee2012-12-10 09:30:54 +000068static int nocong;
69module_param(nocong, int, 0644);
70MODULE_PARM_DESC(nocong, "Turn of congestion control (default=0)");
71
72static int enable_ecn;
73module_param(enable_ecn, int, 0644);
74MODULE_PARM_DESC(enable_ecn, "Enable ECN (default=0/disabled)");
75
Steve Wiseb52fe092011-03-11 22:30:01 +000076static int dack_mode = 1;
Steve Wiseba6d3922010-06-23 15:46:49 +000077module_param(dack_mode, int, 0644);
Steve Wiseb52fe092011-03-11 22:30:01 +000078MODULE_PARM_DESC(dack_mode, "Delayed ack mode (default=1)");
Steve Wiseba6d3922010-06-23 15:46:49 +000079
Roland Dreierbe4c9ba2010-05-05 14:45:40 -070080int c4iw_max_read_depth = 8;
81module_param(c4iw_max_read_depth, int, 0644);
82MODULE_PARM_DESC(c4iw_max_read_depth, "Per-connection max ORD/IRD (default=8)");
83
Steve Wisecfdda9d2010-04-21 15:30:06 -070084static int enable_tcp_timestamps;
85module_param(enable_tcp_timestamps, int, 0644);
86MODULE_PARM_DESC(enable_tcp_timestamps, "Enable tcp timestamps (default=0)");
87
88static int enable_tcp_sack;
89module_param(enable_tcp_sack, int, 0644);
90MODULE_PARM_DESC(enable_tcp_sack, "Enable tcp SACK (default=0)");
91
92static int enable_tcp_window_scaling = 1;
93module_param(enable_tcp_window_scaling, int, 0644);
94MODULE_PARM_DESC(enable_tcp_window_scaling,
95 "Enable tcp window scaling (default=1)");
96
97int c4iw_debug;
98module_param(c4iw_debug, int, 0644);
99MODULE_PARM_DESC(c4iw_debug, "Enable debug logging (default=0)");
100
Steve Wisedf2d5132014-03-19 17:44:44 +0530101static int peer2peer = 1;
Steve Wisecfdda9d2010-04-21 15:30:06 -0700102module_param(peer2peer, int, 0644);
Steve Wisedf2d5132014-03-19 17:44:44 +0530103MODULE_PARM_DESC(peer2peer, "Support peer2peer ULPs (default=1)");
Steve Wisecfdda9d2010-04-21 15:30:06 -0700104
105static int p2p_type = FW_RI_INIT_P2PTYPE_READ_REQ;
106module_param(p2p_type, int, 0644);
107MODULE_PARM_DESC(p2p_type, "RDMAP opcode to use for the RTR message: "
108 "1=RDMA_READ 0=RDMA_WRITE (default 1)");
109
110static int ep_timeout_secs = 60;
111module_param(ep_timeout_secs, int, 0644);
112MODULE_PARM_DESC(ep_timeout_secs, "CM Endpoint operation timeout "
113 "in seconds (default=60)");
114
115static int mpa_rev = 1;
116module_param(mpa_rev, int, 0644);
117MODULE_PARM_DESC(mpa_rev, "MPA Revision, 0 supports amso1100, "
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +0530118 "1 is RFC0544 spec compliant, 2 is IETF MPA Peer Connect Draft"
119 " compliant (default=1)");
Steve Wisecfdda9d2010-04-21 15:30:06 -0700120
121static int markers_enabled;
122module_param(markers_enabled, int, 0644);
123MODULE_PARM_DESC(markers_enabled, "Enable MPA MARKERS (default(0)=disabled)");
124
125static int crc_enabled = 1;
126module_param(crc_enabled, int, 0644);
127MODULE_PARM_DESC(crc_enabled, "Enable MPA CRC (default(1)=enabled)");
128
129static int rcv_win = 256 * 1024;
130module_param(rcv_win, int, 0644);
131MODULE_PARM_DESC(rcv_win, "TCP receive window in bytes (default=256KB)");
132
Steve Wise98ae68b2010-09-10 11:15:41 -0500133static int snd_win = 128 * 1024;
Steve Wisecfdda9d2010-04-21 15:30:06 -0700134module_param(snd_win, int, 0644);
Steve Wise98ae68b2010-09-10 11:15:41 -0500135MODULE_PARM_DESC(snd_win, "TCP send window in bytes (default=128KB)");
Steve Wisecfdda9d2010-04-21 15:30:06 -0700136
Steve Wisecfdda9d2010-04-21 15:30:06 -0700137static struct workqueue_struct *workq;
Steve Wisecfdda9d2010-04-21 15:30:06 -0700138
139static struct sk_buff_head rxq;
Steve Wisecfdda9d2010-04-21 15:30:06 -0700140
141static struct sk_buff *get_skb(struct sk_buff *skb, int len, gfp_t gfp);
142static void ep_timeout(unsigned long arg);
143static void connect_reply_upcall(struct c4iw_ep *ep, int status);
144
Roland Dreierbe4c9ba2010-05-05 14:45:40 -0700145static LIST_HEAD(timeout_list);
146static spinlock_t timeout_lock;
147
Vipul Pandya325abea2013-01-07 13:11:53 +0000148static void deref_qp(struct c4iw_ep *ep)
149{
150 c4iw_qp_rem_ref(&ep->com.qp->ibqp);
151 clear_bit(QP_REFERENCED, &ep->com.flags);
152}
153
154static void ref_qp(struct c4iw_ep *ep)
155{
156 set_bit(QP_REFERENCED, &ep->com.flags);
157 c4iw_qp_add_ref(&ep->com.qp->ibqp);
158}
159
Steve Wisecfdda9d2010-04-21 15:30:06 -0700160static void start_ep_timer(struct c4iw_ep *ep)
161{
162 PDBG("%s ep %p\n", __func__, ep);
163 if (timer_pending(&ep->timer)) {
Vipul Pandya1ec779c2013-01-07 13:11:56 +0000164 pr_err("%s timer already started! ep %p\n",
165 __func__, ep);
166 return;
167 }
168 clear_bit(TIMEOUT, &ep->com.flags);
169 c4iw_get_ep(&ep->com);
Steve Wisecfdda9d2010-04-21 15:30:06 -0700170 ep->timer.expires = jiffies + ep_timeout_secs * HZ;
171 ep->timer.data = (unsigned long)ep;
172 ep->timer.function = ep_timeout;
173 add_timer(&ep->timer);
174}
175
Steve Wiseb33bd0c2014-04-09 09:38:25 -0500176static int stop_ep_timer(struct c4iw_ep *ep)
Steve Wisecfdda9d2010-04-21 15:30:06 -0700177{
Vipul Pandya1ec779c2013-01-07 13:11:56 +0000178 PDBG("%s ep %p stopping\n", __func__, ep);
Steve Wisecfdda9d2010-04-21 15:30:06 -0700179 del_timer_sync(&ep->timer);
Steve Wiseb33bd0c2014-04-09 09:38:25 -0500180 if (!test_and_set_bit(TIMEOUT, &ep->com.flags)) {
Vipul Pandya1ec779c2013-01-07 13:11:56 +0000181 c4iw_put_ep(&ep->com);
Steve Wiseb33bd0c2014-04-09 09:38:25 -0500182 return 0;
183 }
184 return 1;
Steve Wisecfdda9d2010-04-21 15:30:06 -0700185}
186
187static int c4iw_l2t_send(struct c4iw_rdev *rdev, struct sk_buff *skb,
188 struct l2t_entry *l2e)
189{
190 int error = 0;
191
192 if (c4iw_fatal_error(rdev)) {
193 kfree_skb(skb);
194 PDBG("%s - device in error state - dropping\n", __func__);
195 return -EIO;
196 }
197 error = cxgb4_l2t_send(rdev->lldi.ports[0], skb, l2e);
198 if (error < 0)
199 kfree_skb(skb);
Steve Wise74594862010-09-10 11:14:58 -0500200 return error < 0 ? error : 0;
Steve Wisecfdda9d2010-04-21 15:30:06 -0700201}
202
203int c4iw_ofld_send(struct c4iw_rdev *rdev, struct sk_buff *skb)
204{
205 int error = 0;
206
207 if (c4iw_fatal_error(rdev)) {
208 kfree_skb(skb);
209 PDBG("%s - device in error state - dropping\n", __func__);
210 return -EIO;
211 }
212 error = cxgb4_ofld_send(rdev->lldi.ports[0], skb);
213 if (error < 0)
214 kfree_skb(skb);
Steve Wise74594862010-09-10 11:14:58 -0500215 return error < 0 ? error : 0;
Steve Wisecfdda9d2010-04-21 15:30:06 -0700216}
217
218static void release_tid(struct c4iw_rdev *rdev, u32 hwtid, struct sk_buff *skb)
219{
220 struct cpl_tid_release *req;
221
222 skb = get_skb(skb, sizeof *req, GFP_KERNEL);
223 if (!skb)
224 return;
225 req = (struct cpl_tid_release *) skb_put(skb, sizeof(*req));
226 INIT_TP_WR(req, hwtid);
227 OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_TID_RELEASE, hwtid));
228 set_wr_txq(skb, CPL_PRIORITY_SETUP, 0);
229 c4iw_ofld_send(rdev, skb);
230 return;
231}
232
233static void set_emss(struct c4iw_ep *ep, u16 opt)
234{
235 ep->emss = ep->com.dev->rdev.lldi.mtus[GET_TCPOPT_MSS(opt)] - 40;
236 ep->mss = ep->emss;
237 if (GET_TCPOPT_TSTAMP(opt))
238 ep->emss -= 12;
239 if (ep->emss < 128)
240 ep->emss = 128;
241 PDBG("%s mss_idx %u mss %u emss=%u\n", __func__, GET_TCPOPT_MSS(opt),
242 ep->mss, ep->emss);
243}
244
245static enum c4iw_ep_state state_read(struct c4iw_ep_common *epc)
246{
Steve Wisecfdda9d2010-04-21 15:30:06 -0700247 enum c4iw_ep_state state;
248
Steve Wise2f5b48c2010-09-10 11:15:36 -0500249 mutex_lock(&epc->mutex);
Steve Wisecfdda9d2010-04-21 15:30:06 -0700250 state = epc->state;
Steve Wise2f5b48c2010-09-10 11:15:36 -0500251 mutex_unlock(&epc->mutex);
Steve Wisecfdda9d2010-04-21 15:30:06 -0700252 return state;
253}
254
255static void __state_set(struct c4iw_ep_common *epc, enum c4iw_ep_state new)
256{
257 epc->state = new;
258}
259
260static void state_set(struct c4iw_ep_common *epc, enum c4iw_ep_state new)
261{
Steve Wise2f5b48c2010-09-10 11:15:36 -0500262 mutex_lock(&epc->mutex);
Steve Wisecfdda9d2010-04-21 15:30:06 -0700263 PDBG("%s - %s -> %s\n", __func__, states[epc->state], states[new]);
264 __state_set(epc, new);
Steve Wise2f5b48c2010-09-10 11:15:36 -0500265 mutex_unlock(&epc->mutex);
Steve Wisecfdda9d2010-04-21 15:30:06 -0700266 return;
267}
268
269static void *alloc_ep(int size, gfp_t gfp)
270{
271 struct c4iw_ep_common *epc;
272
273 epc = kzalloc(size, gfp);
274 if (epc) {
275 kref_init(&epc->kref);
Steve Wise2f5b48c2010-09-10 11:15:36 -0500276 mutex_init(&epc->mutex);
Steve Wiseaadc4df2010-09-10 11:15:25 -0500277 c4iw_init_wr_wait(&epc->wr_wait);
Steve Wisecfdda9d2010-04-21 15:30:06 -0700278 }
279 PDBG("%s alloc ep %p\n", __func__, epc);
280 return epc;
281}
282
283void _c4iw_free_ep(struct kref *kref)
284{
285 struct c4iw_ep *ep;
286
287 ep = container_of(kref, struct c4iw_ep, com.kref);
288 PDBG("%s ep %p state %s\n", __func__, ep, states[state_read(&ep->com)]);
Vipul Pandya325abea2013-01-07 13:11:53 +0000289 if (test_bit(QP_REFERENCED, &ep->com.flags))
290 deref_qp(ep);
Steve Wisecfdda9d2010-04-21 15:30:06 -0700291 if (test_bit(RELEASE_RESOURCES, &ep->com.flags)) {
Vipul Pandyafe7e0a42013-01-07 13:11:57 +0000292 remove_handle(ep->com.dev, &ep->com.dev->hwtid_idr, ep->hwtid);
Steve Wisecfdda9d2010-04-21 15:30:06 -0700293 cxgb4_remove_tid(ep->com.dev->rdev.lldi.tids, 0, ep->hwtid);
294 dst_release(ep->dst);
295 cxgb4_l2t_release(ep->l2t);
296 }
297 kfree(ep);
298}
299
300static void release_ep_resources(struct c4iw_ep *ep)
301{
302 set_bit(RELEASE_RESOURCES, &ep->com.flags);
303 c4iw_put_ep(&ep->com);
304}
305
Steve Wisecfdda9d2010-04-21 15:30:06 -0700306static int status2errno(int status)
307{
308 switch (status) {
309 case CPL_ERR_NONE:
310 return 0;
311 case CPL_ERR_CONN_RESET:
312 return -ECONNRESET;
313 case CPL_ERR_ARP_MISS:
314 return -EHOSTUNREACH;
315 case CPL_ERR_CONN_TIMEDOUT:
316 return -ETIMEDOUT;
317 case CPL_ERR_TCAM_FULL:
318 return -ENOMEM;
319 case CPL_ERR_CONN_EXIST:
320 return -EADDRINUSE;
321 default:
322 return -EIO;
323 }
324}
325
326/*
327 * Try and reuse skbs already allocated...
328 */
329static struct sk_buff *get_skb(struct sk_buff *skb, int len, gfp_t gfp)
330{
331 if (skb && !skb_is_nonlinear(skb) && !skb_cloned(skb)) {
332 skb_trim(skb, 0);
333 skb_get(skb);
334 skb_reset_transport_header(skb);
335 } else {
336 skb = alloc_skb(len, gfp);
337 }
Steve Wiseb38a0ad2013-08-06 21:04:37 +0530338 t4_set_arp_err_handler(skb, NULL, NULL);
Steve Wisecfdda9d2010-04-21 15:30:06 -0700339 return skb;
340}
341
Vipul Pandya830662f2013-07-04 16:10:47 +0530342static struct net_device *get_real_dev(struct net_device *egress_dev)
343{
344 struct net_device *phys_dev = egress_dev;
345 if (egress_dev->priv_flags & IFF_802_1Q_VLAN)
346 phys_dev = vlan_dev_real_dev(egress_dev);
347 return phys_dev;
348}
349
350static int our_interface(struct c4iw_dev *dev, struct net_device *egress_dev)
351{
352 int i;
353
354 egress_dev = get_real_dev(egress_dev);
355 for (i = 0; i < dev->rdev.lldi.nports; i++)
356 if (dev->rdev.lldi.ports[i] == egress_dev)
357 return 1;
358 return 0;
359}
360
361static struct dst_entry *find_route6(struct c4iw_dev *dev, __u8 *local_ip,
362 __u8 *peer_ip, __be16 local_port,
363 __be16 peer_port, u8 tos,
364 __u32 sin6_scope_id)
365{
366 struct dst_entry *dst = NULL;
367
368 if (IS_ENABLED(CONFIG_IPV6)) {
369 struct flowi6 fl6;
370
371 memset(&fl6, 0, sizeof(fl6));
372 memcpy(&fl6.daddr, peer_ip, 16);
373 memcpy(&fl6.saddr, local_ip, 16);
374 if (ipv6_addr_type(&fl6.daddr) & IPV6_ADDR_LINKLOCAL)
375 fl6.flowi6_oif = sin6_scope_id;
376 dst = ip6_route_output(&init_net, NULL, &fl6);
377 if (!dst)
378 goto out;
379 if (!our_interface(dev, ip6_dst_idev(dst)->dev) &&
380 !(ip6_dst_idev(dst)->dev->flags & IFF_LOOPBACK)) {
381 dst_release(dst);
382 dst = NULL;
383 }
384 }
385
386out:
387 return dst;
388}
389
390static struct dst_entry *find_route(struct c4iw_dev *dev, __be32 local_ip,
Steve Wisecfdda9d2010-04-21 15:30:06 -0700391 __be32 peer_ip, __be16 local_port,
392 __be16 peer_port, u8 tos)
393{
394 struct rtable *rt;
David S. Miller31e4543d2011-05-03 20:25:42 -0700395 struct flowi4 fl4;
Vipul Pandya830662f2013-07-04 16:10:47 +0530396 struct neighbour *n;
Steve Wisecfdda9d2010-04-21 15:30:06 -0700397
David S. Miller31e4543d2011-05-03 20:25:42 -0700398 rt = ip_route_output_ports(&init_net, &fl4, NULL, peer_ip, local_ip,
David S. Miller78fbfd82011-03-12 00:00:52 -0500399 peer_port, local_port, IPPROTO_TCP,
400 tos, 0);
David S. Millerb23dd4f2011-03-02 14:31:35 -0800401 if (IS_ERR(rt))
Steve Wisecfdda9d2010-04-21 15:30:06 -0700402 return NULL;
Vipul Pandya830662f2013-07-04 16:10:47 +0530403 n = dst_neigh_lookup(&rt->dst, &peer_ip);
404 if (!n)
405 return NULL;
Steve Wisef8e81902014-03-19 17:44:39 +0530406 if (!our_interface(dev, n->dev) &&
407 !(n->dev->flags & IFF_LOOPBACK)) {
Vipul Pandya830662f2013-07-04 16:10:47 +0530408 dst_release(&rt->dst);
409 return NULL;
410 }
411 neigh_release(n);
412 return &rt->dst;
Steve Wisecfdda9d2010-04-21 15:30:06 -0700413}
414
415static void arp_failure_discard(void *handle, struct sk_buff *skb)
416{
417 PDBG("%s c4iw_dev %p\n", __func__, handle);
418 kfree_skb(skb);
419}
420
421/*
422 * Handle an ARP failure for an active open.
423 */
424static void act_open_req_arp_failure(void *handle, struct sk_buff *skb)
425{
426 printk(KERN_ERR MOD "ARP failure duing connect\n");
427 kfree_skb(skb);
428}
429
430/*
431 * Handle an ARP failure for a CPL_ABORT_REQ. Change it into a no RST variant
432 * and send it along.
433 */
434static void abort_arp_failure(void *handle, struct sk_buff *skb)
435{
436 struct c4iw_rdev *rdev = handle;
437 struct cpl_abort_req *req = cplhdr(skb);
438
439 PDBG("%s rdev %p\n", __func__, rdev);
440 req->cmd = CPL_ABORT_NO_RST;
441 c4iw_ofld_send(rdev, skb);
442}
443
444static void send_flowc(struct c4iw_ep *ep, struct sk_buff *skb)
445{
446 unsigned int flowclen = 80;
447 struct fw_flowc_wr *flowc;
448 int i;
449
450 skb = get_skb(skb, flowclen, GFP_KERNEL);
451 flowc = (struct fw_flowc_wr *)__skb_put(skb, flowclen);
452
453 flowc->op_to_nparams = cpu_to_be32(FW_WR_OP(FW_FLOWC_WR) |
454 FW_FLOWC_WR_NPARAMS(8));
455 flowc->flowid_len16 = cpu_to_be32(FW_WR_LEN16(DIV_ROUND_UP(flowclen,
456 16)) | FW_WR_FLOWID(ep->hwtid));
457
458 flowc->mnemval[0].mnemonic = FW_FLOWC_MNEM_PFNVFN;
Steve Wise94788652011-01-21 17:00:34 +0000459 flowc->mnemval[0].val = cpu_to_be32(PCI_FUNC(ep->com.dev->rdev.lldi.pdev->devfn) << 8);
Steve Wisecfdda9d2010-04-21 15:30:06 -0700460 flowc->mnemval[1].mnemonic = FW_FLOWC_MNEM_CH;
461 flowc->mnemval[1].val = cpu_to_be32(ep->tx_chan);
462 flowc->mnemval[2].mnemonic = FW_FLOWC_MNEM_PORT;
463 flowc->mnemval[2].val = cpu_to_be32(ep->tx_chan);
464 flowc->mnemval[3].mnemonic = FW_FLOWC_MNEM_IQID;
465 flowc->mnemval[3].val = cpu_to_be32(ep->rss_qid);
466 flowc->mnemval[4].mnemonic = FW_FLOWC_MNEM_SNDNXT;
467 flowc->mnemval[4].val = cpu_to_be32(ep->snd_seq);
468 flowc->mnemval[5].mnemonic = FW_FLOWC_MNEM_RCVNXT;
469 flowc->mnemval[5].val = cpu_to_be32(ep->rcv_seq);
470 flowc->mnemval[6].mnemonic = FW_FLOWC_MNEM_SNDBUF;
471 flowc->mnemval[6].val = cpu_to_be32(snd_win);
472 flowc->mnemval[7].mnemonic = FW_FLOWC_MNEM_MSS;
473 flowc->mnemval[7].val = cpu_to_be32(ep->emss);
474 /* Pad WR to 16 byte boundary */
475 flowc->mnemval[8].mnemonic = 0;
476 flowc->mnemval[8].val = 0;
477 for (i = 0; i < 9; i++) {
478 flowc->mnemval[i].r4[0] = 0;
479 flowc->mnemval[i].r4[1] = 0;
480 flowc->mnemval[i].r4[2] = 0;
481 }
482
483 set_wr_txq(skb, CPL_PRIORITY_DATA, ep->txq_idx);
484 c4iw_ofld_send(&ep->com.dev->rdev, skb);
485}
486
487static int send_halfclose(struct c4iw_ep *ep, gfp_t gfp)
488{
489 struct cpl_close_con_req *req;
490 struct sk_buff *skb;
491 int wrlen = roundup(sizeof *req, 16);
492
493 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
494 skb = get_skb(NULL, wrlen, gfp);
495 if (!skb) {
496 printk(KERN_ERR MOD "%s - failed to alloc skb\n", __func__);
497 return -ENOMEM;
498 }
499 set_wr_txq(skb, CPL_PRIORITY_DATA, ep->txq_idx);
500 t4_set_arp_err_handler(skb, NULL, arp_failure_discard);
501 req = (struct cpl_close_con_req *) skb_put(skb, wrlen);
502 memset(req, 0, wrlen);
503 INIT_TP_WR(req, ep->hwtid);
504 OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_CLOSE_CON_REQ,
505 ep->hwtid));
506 return c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t);
507}
508
509static int send_abort(struct c4iw_ep *ep, struct sk_buff *skb, gfp_t gfp)
510{
511 struct cpl_abort_req *req;
512 int wrlen = roundup(sizeof *req, 16);
513
514 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
515 skb = get_skb(skb, wrlen, gfp);
516 if (!skb) {
517 printk(KERN_ERR MOD "%s - failed to alloc skb.\n",
518 __func__);
519 return -ENOMEM;
520 }
521 set_wr_txq(skb, CPL_PRIORITY_DATA, ep->txq_idx);
522 t4_set_arp_err_handler(skb, &ep->com.dev->rdev, abort_arp_failure);
523 req = (struct cpl_abort_req *) skb_put(skb, wrlen);
524 memset(req, 0, wrlen);
525 INIT_TP_WR(req, ep->hwtid);
526 OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_ABORT_REQ, ep->hwtid));
527 req->cmd = CPL_ABORT_SEND_RST;
528 return c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t);
529}
530
531static int send_connect(struct c4iw_ep *ep)
532{
533 struct cpl_act_open_req *req;
Vipul Pandyaf079af72013-03-14 05:08:58 +0000534 struct cpl_t5_act_open_req *t5_req;
Vipul Pandya830662f2013-07-04 16:10:47 +0530535 struct cpl_act_open_req6 *req6;
536 struct cpl_t5_act_open_req6 *t5_req6;
Steve Wisecfdda9d2010-04-21 15:30:06 -0700537 struct sk_buff *skb;
538 u64 opt0;
539 u32 opt2;
540 unsigned int mtu_idx;
541 int wscale;
Vipul Pandya830662f2013-07-04 16:10:47 +0530542 int wrlen;
543 int sizev4 = is_t4(ep->com.dev->rdev.lldi.adapter_type) ?
544 sizeof(struct cpl_act_open_req) :
545 sizeof(struct cpl_t5_act_open_req);
546 int sizev6 = is_t4(ep->com.dev->rdev.lldi.adapter_type) ?
547 sizeof(struct cpl_act_open_req6) :
548 sizeof(struct cpl_t5_act_open_req6);
549 struct sockaddr_in *la = (struct sockaddr_in *)&ep->com.local_addr;
550 struct sockaddr_in *ra = (struct sockaddr_in *)&ep->com.remote_addr;
551 struct sockaddr_in6 *la6 = (struct sockaddr_in6 *)&ep->com.local_addr;
552 struct sockaddr_in6 *ra6 = (struct sockaddr_in6 *)&ep->com.remote_addr;
553
554 wrlen = (ep->com.remote_addr.ss_family == AF_INET) ?
555 roundup(sizev4, 16) :
556 roundup(sizev6, 16);
Steve Wisecfdda9d2010-04-21 15:30:06 -0700557
558 PDBG("%s ep %p atid %u\n", __func__, ep, ep->atid);
559
560 skb = get_skb(NULL, wrlen, GFP_KERNEL);
561 if (!skb) {
562 printk(KERN_ERR MOD "%s - failed to alloc skb.\n",
563 __func__);
564 return -ENOMEM;
565 }
Steve Wised4f1a5c2010-07-23 19:12:32 +0000566 set_wr_txq(skb, CPL_PRIORITY_SETUP, ep->ctrlq_idx);
Steve Wisecfdda9d2010-04-21 15:30:06 -0700567
568 cxgb4_best_mtu(ep->com.dev->rdev.lldi.mtus, ep->mtu, &mtu_idx);
569 wscale = compute_wscale(rcv_win);
Vipul Pandya5be78ee2012-12-10 09:30:54 +0000570 opt0 = (nocong ? NO_CONG(1) : 0) |
571 KEEP_ALIVE(1) |
Steve Wiseba6d3922010-06-23 15:46:49 +0000572 DELACK(1) |
Steve Wisecfdda9d2010-04-21 15:30:06 -0700573 WND_SCALE(wscale) |
574 MSS_IDX(mtu_idx) |
575 L2T_IDX(ep->l2t->idx) |
576 TX_CHAN(ep->tx_chan) |
577 SMAC_SEL(ep->smac_idx) |
578 DSCP(ep->tos) |
Steve Wiseb48f3b92011-03-11 22:30:21 +0000579 ULP_MODE(ULP_MODE_TCPDDP) |
Steve Wisecfdda9d2010-04-21 15:30:06 -0700580 RCV_BUFSIZ(rcv_win>>10);
581 opt2 = RX_CHANNEL(0) |
Vipul Pandya5be78ee2012-12-10 09:30:54 +0000582 CCTRL_ECN(enable_ecn) |
Steve Wisecfdda9d2010-04-21 15:30:06 -0700583 RSS_QUEUE_VALID | RSS_QUEUE(ep->rss_qid);
584 if (enable_tcp_timestamps)
585 opt2 |= TSTAMPS_EN(1);
586 if (enable_tcp_sack)
587 opt2 |= SACK_EN(1);
588 if (wscale && enable_tcp_window_scaling)
589 opt2 |= WND_SCALE_EN(1);
590 t4_set_arp_err_handler(skb, NULL, act_open_req_arp_failure);
591
Vipul Pandyaf079af72013-03-14 05:08:58 +0000592 if (is_t4(ep->com.dev->rdev.lldi.adapter_type)) {
Vipul Pandya830662f2013-07-04 16:10:47 +0530593 if (ep->com.remote_addr.ss_family == AF_INET) {
594 req = (struct cpl_act_open_req *) skb_put(skb, wrlen);
595 INIT_TP_WR(req, 0);
596 OPCODE_TID(req) = cpu_to_be32(
Vipul Pandyaf079af72013-03-14 05:08:58 +0000597 MK_OPCODE_TID(CPL_ACT_OPEN_REQ,
598 ((ep->rss_qid << 14) | ep->atid)));
Vipul Pandya830662f2013-07-04 16:10:47 +0530599 req->local_port = la->sin_port;
600 req->peer_port = ra->sin_port;
601 req->local_ip = la->sin_addr.s_addr;
602 req->peer_ip = ra->sin_addr.s_addr;
603 req->opt0 = cpu_to_be64(opt0);
Kumar Sanghvi41b4f862013-12-18 16:38:26 +0530604 req->params = cpu_to_be32(cxgb4_select_ntuple(
605 ep->com.dev->rdev.lldi.ports[0],
606 ep->l2t));
Vipul Pandya830662f2013-07-04 16:10:47 +0530607 req->opt2 = cpu_to_be32(opt2);
608 } else {
609 req6 = (struct cpl_act_open_req6 *)skb_put(skb, wrlen);
610
611 INIT_TP_WR(req6, 0);
612 OPCODE_TID(req6) = cpu_to_be32(
613 MK_OPCODE_TID(CPL_ACT_OPEN_REQ6,
614 ((ep->rss_qid<<14)|ep->atid)));
615 req6->local_port = la6->sin6_port;
616 req6->peer_port = ra6->sin6_port;
617 req6->local_ip_hi = *((__be64 *)
618 (la6->sin6_addr.s6_addr));
619 req6->local_ip_lo = *((__be64 *)
620 (la6->sin6_addr.s6_addr + 8));
621 req6->peer_ip_hi = *((__be64 *)
622 (ra6->sin6_addr.s6_addr));
623 req6->peer_ip_lo = *((__be64 *)
624 (ra6->sin6_addr.s6_addr + 8));
625 req6->opt0 = cpu_to_be64(opt0);
Kumar Sanghvi41b4f862013-12-18 16:38:26 +0530626 req6->params = cpu_to_be32(cxgb4_select_ntuple(
627 ep->com.dev->rdev.lldi.ports[0],
628 ep->l2t));
Vipul Pandya830662f2013-07-04 16:10:47 +0530629 req6->opt2 = cpu_to_be32(opt2);
630 }
631 } else {
632 if (ep->com.remote_addr.ss_family == AF_INET) {
633 t5_req = (struct cpl_t5_act_open_req *)
634 skb_put(skb, wrlen);
635 INIT_TP_WR(t5_req, 0);
636 OPCODE_TID(t5_req) = cpu_to_be32(
637 MK_OPCODE_TID(CPL_ACT_OPEN_REQ,
638 ((ep->rss_qid << 14) | ep->atid)));
639 t5_req->local_port = la->sin_port;
640 t5_req->peer_port = ra->sin_port;
641 t5_req->local_ip = la->sin_addr.s_addr;
642 t5_req->peer_ip = ra->sin_addr.s_addr;
643 t5_req->opt0 = cpu_to_be64(opt0);
644 t5_req->params = cpu_to_be64(V_FILTER_TUPLE(
Kumar Sanghvi41b4f862013-12-18 16:38:26 +0530645 cxgb4_select_ntuple(
646 ep->com.dev->rdev.lldi.ports[0],
647 ep->l2t)));
Vipul Pandya830662f2013-07-04 16:10:47 +0530648 t5_req->opt2 = cpu_to_be32(opt2);
649 } else {
650 t5_req6 = (struct cpl_t5_act_open_req6 *)
651 skb_put(skb, wrlen);
652 INIT_TP_WR(t5_req6, 0);
653 OPCODE_TID(t5_req6) = cpu_to_be32(
654 MK_OPCODE_TID(CPL_ACT_OPEN_REQ6,
655 ((ep->rss_qid<<14)|ep->atid)));
656 t5_req6->local_port = la6->sin6_port;
657 t5_req6->peer_port = ra6->sin6_port;
658 t5_req6->local_ip_hi = *((__be64 *)
659 (la6->sin6_addr.s6_addr));
660 t5_req6->local_ip_lo = *((__be64 *)
661 (la6->sin6_addr.s6_addr + 8));
662 t5_req6->peer_ip_hi = *((__be64 *)
663 (ra6->sin6_addr.s6_addr));
664 t5_req6->peer_ip_lo = *((__be64 *)
665 (ra6->sin6_addr.s6_addr + 8));
666 t5_req6->opt0 = cpu_to_be64(opt0);
667 t5_req6->params = (__force __be64)cpu_to_be32(
Kumar Sanghvi41b4f862013-12-18 16:38:26 +0530668 cxgb4_select_ntuple(
669 ep->com.dev->rdev.lldi.ports[0],
670 ep->l2t));
Vipul Pandya830662f2013-07-04 16:10:47 +0530671 t5_req6->opt2 = cpu_to_be32(opt2);
672 }
Vipul Pandyaf079af72013-03-14 05:08:58 +0000673 }
674
Vipul Pandya793dad92012-12-10 09:30:56 +0000675 set_bit(ACT_OPEN_REQ, &ep->com.history);
Steve Wisecfdda9d2010-04-21 15:30:06 -0700676 return c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t);
677}
678
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +0530679static void send_mpa_req(struct c4iw_ep *ep, struct sk_buff *skb,
680 u8 mpa_rev_to_use)
Steve Wisecfdda9d2010-04-21 15:30:06 -0700681{
682 int mpalen, wrlen;
683 struct fw_ofld_tx_data_wr *req;
684 struct mpa_message *mpa;
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +0530685 struct mpa_v2_conn_params mpa_v2_params;
Steve Wisecfdda9d2010-04-21 15:30:06 -0700686
687 PDBG("%s ep %p tid %u pd_len %d\n", __func__, ep, ep->hwtid, ep->plen);
688
689 BUG_ON(skb_cloned(skb));
690
691 mpalen = sizeof(*mpa) + ep->plen;
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +0530692 if (mpa_rev_to_use == 2)
693 mpalen += sizeof(struct mpa_v2_conn_params);
Steve Wisecfdda9d2010-04-21 15:30:06 -0700694 wrlen = roundup(mpalen + sizeof *req, 16);
695 skb = get_skb(skb, wrlen, GFP_KERNEL);
696 if (!skb) {
697 connect_reply_upcall(ep, -ENOMEM);
698 return;
699 }
700 set_wr_txq(skb, CPL_PRIORITY_DATA, ep->txq_idx);
701
702 req = (struct fw_ofld_tx_data_wr *)skb_put(skb, wrlen);
703 memset(req, 0, wrlen);
704 req->op_to_immdlen = cpu_to_be32(
705 FW_WR_OP(FW_OFLD_TX_DATA_WR) |
706 FW_WR_COMPL(1) |
707 FW_WR_IMMDLEN(mpalen));
708 req->flowid_len16 = cpu_to_be32(
709 FW_WR_FLOWID(ep->hwtid) |
710 FW_WR_LEN16(wrlen >> 4));
711 req->plen = cpu_to_be32(mpalen);
712 req->tunnel_to_proxy = cpu_to_be32(
713 FW_OFLD_TX_DATA_WR_FLUSH(1) |
714 FW_OFLD_TX_DATA_WR_SHOVE(1));
715
716 mpa = (struct mpa_message *)(req + 1);
717 memcpy(mpa->key, MPA_KEY_REQ, sizeof(mpa->key));
718 mpa->flags = (crc_enabled ? MPA_CRC : 0) |
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +0530719 (markers_enabled ? MPA_MARKERS : 0) |
720 (mpa_rev_to_use == 2 ? MPA_ENHANCED_RDMA_CONN : 0);
Steve Wisecfdda9d2010-04-21 15:30:06 -0700721 mpa->private_data_size = htons(ep->plen);
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +0530722 mpa->revision = mpa_rev_to_use;
Kumar Sanghvi01b225e2011-11-28 22:09:15 +0530723 if (mpa_rev_to_use == 1) {
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +0530724 ep->tried_with_mpa_v1 = 1;
Kumar Sanghvi01b225e2011-11-28 22:09:15 +0530725 ep->retry_with_mpa_v1 = 0;
726 }
Steve Wisecfdda9d2010-04-21 15:30:06 -0700727
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +0530728 if (mpa_rev_to_use == 2) {
Roland Dreierf747c342012-07-05 14:16:54 -0700729 mpa->private_data_size = htons(ntohs(mpa->private_data_size) +
730 sizeof (struct mpa_v2_conn_params));
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +0530731 mpa_v2_params.ird = htons((u16)ep->ird);
732 mpa_v2_params.ord = htons((u16)ep->ord);
733
734 if (peer2peer) {
735 mpa_v2_params.ird |= htons(MPA_V2_PEER2PEER_MODEL);
736 if (p2p_type == FW_RI_INIT_P2PTYPE_RDMA_WRITE)
737 mpa_v2_params.ord |=
738 htons(MPA_V2_RDMA_WRITE_RTR);
739 else if (p2p_type == FW_RI_INIT_P2PTYPE_READ_REQ)
740 mpa_v2_params.ord |=
741 htons(MPA_V2_RDMA_READ_RTR);
742 }
743 memcpy(mpa->private_data, &mpa_v2_params,
744 sizeof(struct mpa_v2_conn_params));
745
746 if (ep->plen)
747 memcpy(mpa->private_data +
748 sizeof(struct mpa_v2_conn_params),
749 ep->mpa_pkt + sizeof(*mpa), ep->plen);
750 } else
751 if (ep->plen)
752 memcpy(mpa->private_data,
753 ep->mpa_pkt + sizeof(*mpa), ep->plen);
Steve Wisecfdda9d2010-04-21 15:30:06 -0700754
755 /*
756 * Reference the mpa skb. This ensures the data area
757 * will remain in memory until the hw acks the tx.
758 * Function fw4_ack() will deref it.
759 */
760 skb_get(skb);
761 t4_set_arp_err_handler(skb, NULL, arp_failure_discard);
762 BUG_ON(ep->mpa_skb);
763 ep->mpa_skb = skb;
764 c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t);
765 start_ep_timer(ep);
Steve Wisea7db89e2014-03-21 20:40:35 +0530766 __state_set(&ep->com, MPA_REQ_SENT);
Steve Wisecfdda9d2010-04-21 15:30:06 -0700767 ep->mpa_attr.initiator = 1;
Steve Wise9c88aa02014-03-21 20:40:34 +0530768 ep->snd_seq += mpalen;
Steve Wisecfdda9d2010-04-21 15:30:06 -0700769 return;
770}
771
772static int send_mpa_reject(struct c4iw_ep *ep, const void *pdata, u8 plen)
773{
774 int mpalen, wrlen;
775 struct fw_ofld_tx_data_wr *req;
776 struct mpa_message *mpa;
777 struct sk_buff *skb;
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +0530778 struct mpa_v2_conn_params mpa_v2_params;
Steve Wisecfdda9d2010-04-21 15:30:06 -0700779
780 PDBG("%s ep %p tid %u pd_len %d\n", __func__, ep, ep->hwtid, ep->plen);
781
782 mpalen = sizeof(*mpa) + plen;
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +0530783 if (ep->mpa_attr.version == 2 && ep->mpa_attr.enhanced_rdma_conn)
784 mpalen += sizeof(struct mpa_v2_conn_params);
Steve Wisecfdda9d2010-04-21 15:30:06 -0700785 wrlen = roundup(mpalen + sizeof *req, 16);
786
787 skb = get_skb(NULL, wrlen, GFP_KERNEL);
788 if (!skb) {
789 printk(KERN_ERR MOD "%s - cannot alloc skb!\n", __func__);
790 return -ENOMEM;
791 }
792 set_wr_txq(skb, CPL_PRIORITY_DATA, ep->txq_idx);
793
794 req = (struct fw_ofld_tx_data_wr *)skb_put(skb, wrlen);
795 memset(req, 0, wrlen);
796 req->op_to_immdlen = cpu_to_be32(
797 FW_WR_OP(FW_OFLD_TX_DATA_WR) |
798 FW_WR_COMPL(1) |
799 FW_WR_IMMDLEN(mpalen));
800 req->flowid_len16 = cpu_to_be32(
801 FW_WR_FLOWID(ep->hwtid) |
802 FW_WR_LEN16(wrlen >> 4));
803 req->plen = cpu_to_be32(mpalen);
804 req->tunnel_to_proxy = cpu_to_be32(
805 FW_OFLD_TX_DATA_WR_FLUSH(1) |
806 FW_OFLD_TX_DATA_WR_SHOVE(1));
807
808 mpa = (struct mpa_message *)(req + 1);
809 memset(mpa, 0, sizeof(*mpa));
810 memcpy(mpa->key, MPA_KEY_REP, sizeof(mpa->key));
811 mpa->flags = MPA_REJECT;
Vipul Pandyafe7e0a42013-01-07 13:11:57 +0000812 mpa->revision = ep->mpa_attr.version;
Steve Wisecfdda9d2010-04-21 15:30:06 -0700813 mpa->private_data_size = htons(plen);
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +0530814
815 if (ep->mpa_attr.version == 2 && ep->mpa_attr.enhanced_rdma_conn) {
816 mpa->flags |= MPA_ENHANCED_RDMA_CONN;
Roland Dreierf747c342012-07-05 14:16:54 -0700817 mpa->private_data_size = htons(ntohs(mpa->private_data_size) +
818 sizeof (struct mpa_v2_conn_params));
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +0530819 mpa_v2_params.ird = htons(((u16)ep->ird) |
820 (peer2peer ? MPA_V2_PEER2PEER_MODEL :
821 0));
822 mpa_v2_params.ord = htons(((u16)ep->ord) | (peer2peer ?
823 (p2p_type ==
824 FW_RI_INIT_P2PTYPE_RDMA_WRITE ?
825 MPA_V2_RDMA_WRITE_RTR : p2p_type ==
826 FW_RI_INIT_P2PTYPE_READ_REQ ?
827 MPA_V2_RDMA_READ_RTR : 0) : 0));
828 memcpy(mpa->private_data, &mpa_v2_params,
829 sizeof(struct mpa_v2_conn_params));
830
831 if (ep->plen)
832 memcpy(mpa->private_data +
833 sizeof(struct mpa_v2_conn_params), pdata, plen);
834 } else
835 if (plen)
836 memcpy(mpa->private_data, pdata, plen);
Steve Wisecfdda9d2010-04-21 15:30:06 -0700837
838 /*
839 * Reference the mpa skb again. This ensures the data area
840 * will remain in memory until the hw acks the tx.
841 * Function fw4_ack() will deref it.
842 */
843 skb_get(skb);
844 set_wr_txq(skb, CPL_PRIORITY_DATA, ep->txq_idx);
845 t4_set_arp_err_handler(skb, NULL, arp_failure_discard);
846 BUG_ON(ep->mpa_skb);
847 ep->mpa_skb = skb;
Steve Wise9c88aa02014-03-21 20:40:34 +0530848 ep->snd_seq += mpalen;
Steve Wisecfdda9d2010-04-21 15:30:06 -0700849 return c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t);
850}
851
852static int send_mpa_reply(struct c4iw_ep *ep, const void *pdata, u8 plen)
853{
854 int mpalen, wrlen;
855 struct fw_ofld_tx_data_wr *req;
856 struct mpa_message *mpa;
857 struct sk_buff *skb;
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +0530858 struct mpa_v2_conn_params mpa_v2_params;
Steve Wisecfdda9d2010-04-21 15:30:06 -0700859
860 PDBG("%s ep %p tid %u pd_len %d\n", __func__, ep, ep->hwtid, ep->plen);
861
862 mpalen = sizeof(*mpa) + plen;
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +0530863 if (ep->mpa_attr.version == 2 && ep->mpa_attr.enhanced_rdma_conn)
864 mpalen += sizeof(struct mpa_v2_conn_params);
Steve Wisecfdda9d2010-04-21 15:30:06 -0700865 wrlen = roundup(mpalen + sizeof *req, 16);
866
867 skb = get_skb(NULL, wrlen, GFP_KERNEL);
868 if (!skb) {
869 printk(KERN_ERR MOD "%s - cannot alloc skb!\n", __func__);
870 return -ENOMEM;
871 }
872 set_wr_txq(skb, CPL_PRIORITY_DATA, ep->txq_idx);
873
874 req = (struct fw_ofld_tx_data_wr *) skb_put(skb, wrlen);
875 memset(req, 0, wrlen);
876 req->op_to_immdlen = cpu_to_be32(
877 FW_WR_OP(FW_OFLD_TX_DATA_WR) |
878 FW_WR_COMPL(1) |
879 FW_WR_IMMDLEN(mpalen));
880 req->flowid_len16 = cpu_to_be32(
881 FW_WR_FLOWID(ep->hwtid) |
882 FW_WR_LEN16(wrlen >> 4));
883 req->plen = cpu_to_be32(mpalen);
884 req->tunnel_to_proxy = cpu_to_be32(
885 FW_OFLD_TX_DATA_WR_FLUSH(1) |
886 FW_OFLD_TX_DATA_WR_SHOVE(1));
887
888 mpa = (struct mpa_message *)(req + 1);
889 memset(mpa, 0, sizeof(*mpa));
890 memcpy(mpa->key, MPA_KEY_REP, sizeof(mpa->key));
891 mpa->flags = (ep->mpa_attr.crc_enabled ? MPA_CRC : 0) |
892 (markers_enabled ? MPA_MARKERS : 0);
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +0530893 mpa->revision = ep->mpa_attr.version;
Steve Wisecfdda9d2010-04-21 15:30:06 -0700894 mpa->private_data_size = htons(plen);
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +0530895
896 if (ep->mpa_attr.version == 2 && ep->mpa_attr.enhanced_rdma_conn) {
897 mpa->flags |= MPA_ENHANCED_RDMA_CONN;
Roland Dreierf747c342012-07-05 14:16:54 -0700898 mpa->private_data_size = htons(ntohs(mpa->private_data_size) +
899 sizeof (struct mpa_v2_conn_params));
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +0530900 mpa_v2_params.ird = htons((u16)ep->ird);
901 mpa_v2_params.ord = htons((u16)ep->ord);
902 if (peer2peer && (ep->mpa_attr.p2p_type !=
903 FW_RI_INIT_P2PTYPE_DISABLED)) {
904 mpa_v2_params.ird |= htons(MPA_V2_PEER2PEER_MODEL);
905
906 if (p2p_type == FW_RI_INIT_P2PTYPE_RDMA_WRITE)
907 mpa_v2_params.ord |=
908 htons(MPA_V2_RDMA_WRITE_RTR);
909 else if (p2p_type == FW_RI_INIT_P2PTYPE_READ_REQ)
910 mpa_v2_params.ord |=
911 htons(MPA_V2_RDMA_READ_RTR);
912 }
913
914 memcpy(mpa->private_data, &mpa_v2_params,
915 sizeof(struct mpa_v2_conn_params));
916
917 if (ep->plen)
918 memcpy(mpa->private_data +
919 sizeof(struct mpa_v2_conn_params), pdata, plen);
920 } else
921 if (plen)
922 memcpy(mpa->private_data, pdata, plen);
Steve Wisecfdda9d2010-04-21 15:30:06 -0700923
924 /*
925 * Reference the mpa skb. This ensures the data area
926 * will remain in memory until the hw acks the tx.
927 * Function fw4_ack() will deref it.
928 */
929 skb_get(skb);
930 t4_set_arp_err_handler(skb, NULL, arp_failure_discard);
931 ep->mpa_skb = skb;
Steve Wisea7db89e2014-03-21 20:40:35 +0530932 __state_set(&ep->com, MPA_REP_SENT);
Steve Wise9c88aa02014-03-21 20:40:34 +0530933 ep->snd_seq += mpalen;
Steve Wisecfdda9d2010-04-21 15:30:06 -0700934 return c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t);
935}
936
937static int act_establish(struct c4iw_dev *dev, struct sk_buff *skb)
938{
939 struct c4iw_ep *ep;
940 struct cpl_act_establish *req = cplhdr(skb);
941 unsigned int tid = GET_TID(req);
942 unsigned int atid = GET_TID_TID(ntohl(req->tos_atid));
943 struct tid_info *t = dev->rdev.lldi.tids;
944
945 ep = lookup_atid(t, atid);
946
947 PDBG("%s ep %p tid %u snd_isn %u rcv_isn %u\n", __func__, ep, tid,
948 be32_to_cpu(req->snd_isn), be32_to_cpu(req->rcv_isn));
949
Steve Wisea7db89e2014-03-21 20:40:35 +0530950 mutex_lock(&ep->com.mutex);
Steve Wisecfdda9d2010-04-21 15:30:06 -0700951 dst_confirm(ep->dst);
952
953 /* setup the hwtid for this connection */
954 ep->hwtid = tid;
955 cxgb4_insert_tid(t, ep, tid);
Vipul Pandya793dad92012-12-10 09:30:56 +0000956 insert_handle(dev, &dev->hwtid_idr, ep, ep->hwtid);
Steve Wisecfdda9d2010-04-21 15:30:06 -0700957
958 ep->snd_seq = be32_to_cpu(req->snd_isn);
959 ep->rcv_seq = be32_to_cpu(req->rcv_isn);
960
961 set_emss(ep, ntohs(req->tcp_opt));
962
963 /* dealloc the atid */
Vipul Pandya793dad92012-12-10 09:30:56 +0000964 remove_handle(ep->com.dev, &ep->com.dev->atid_idr, atid);
Steve Wisecfdda9d2010-04-21 15:30:06 -0700965 cxgb4_free_atid(t, atid);
Vipul Pandya793dad92012-12-10 09:30:56 +0000966 set_bit(ACT_ESTAB, &ep->com.history);
Steve Wisecfdda9d2010-04-21 15:30:06 -0700967
968 /* start MPA negotiation */
969 send_flowc(ep, NULL);
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +0530970 if (ep->retry_with_mpa_v1)
971 send_mpa_req(ep, skb, 1);
972 else
973 send_mpa_req(ep, skb, mpa_rev);
Steve Wisea7db89e2014-03-21 20:40:35 +0530974 mutex_unlock(&ep->com.mutex);
Steve Wisecfdda9d2010-04-21 15:30:06 -0700975 return 0;
976}
977
Steve Wisebe13b2d2014-03-21 20:40:33 +0530978static void close_complete_upcall(struct c4iw_ep *ep, int status)
Steve Wisecfdda9d2010-04-21 15:30:06 -0700979{
980 struct iw_cm_event event;
981
982 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
983 memset(&event, 0, sizeof(event));
984 event.event = IW_CM_EVENT_CLOSE;
Steve Wisebe13b2d2014-03-21 20:40:33 +0530985 event.status = status;
Steve Wisecfdda9d2010-04-21 15:30:06 -0700986 if (ep->com.cm_id) {
987 PDBG("close complete delivered ep %p cm_id %p tid %u\n",
988 ep, ep->com.cm_id, ep->hwtid);
989 ep->com.cm_id->event_handler(ep->com.cm_id, &event);
990 ep->com.cm_id->rem_ref(ep->com.cm_id);
991 ep->com.cm_id = NULL;
Vipul Pandya793dad92012-12-10 09:30:56 +0000992 set_bit(CLOSE_UPCALL, &ep->com.history);
Steve Wisecfdda9d2010-04-21 15:30:06 -0700993 }
994}
995
996static int abort_connection(struct c4iw_ep *ep, struct sk_buff *skb, gfp_t gfp)
997{
998 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
Steve Wisecfdda9d2010-04-21 15:30:06 -0700999 state_set(&ep->com, ABORTING);
Vipul Pandya793dad92012-12-10 09:30:56 +00001000 set_bit(ABORT_CONN, &ep->com.history);
Steve Wisecfdda9d2010-04-21 15:30:06 -07001001 return send_abort(ep, skb, gfp);
1002}
1003
1004static void peer_close_upcall(struct c4iw_ep *ep)
1005{
1006 struct iw_cm_event event;
1007
1008 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
1009 memset(&event, 0, sizeof(event));
1010 event.event = IW_CM_EVENT_DISCONNECT;
1011 if (ep->com.cm_id) {
1012 PDBG("peer close delivered ep %p cm_id %p tid %u\n",
1013 ep, ep->com.cm_id, ep->hwtid);
1014 ep->com.cm_id->event_handler(ep->com.cm_id, &event);
Vipul Pandya793dad92012-12-10 09:30:56 +00001015 set_bit(DISCONN_UPCALL, &ep->com.history);
Steve Wisecfdda9d2010-04-21 15:30:06 -07001016 }
1017}
1018
1019static void peer_abort_upcall(struct c4iw_ep *ep)
1020{
1021 struct iw_cm_event event;
1022
1023 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
1024 memset(&event, 0, sizeof(event));
1025 event.event = IW_CM_EVENT_CLOSE;
1026 event.status = -ECONNRESET;
1027 if (ep->com.cm_id) {
1028 PDBG("abort delivered ep %p cm_id %p tid %u\n", ep,
1029 ep->com.cm_id, ep->hwtid);
1030 ep->com.cm_id->event_handler(ep->com.cm_id, &event);
1031 ep->com.cm_id->rem_ref(ep->com.cm_id);
1032 ep->com.cm_id = NULL;
Vipul Pandya793dad92012-12-10 09:30:56 +00001033 set_bit(ABORT_UPCALL, &ep->com.history);
Steve Wisecfdda9d2010-04-21 15:30:06 -07001034 }
1035}
1036
1037static void connect_reply_upcall(struct c4iw_ep *ep, int status)
1038{
1039 struct iw_cm_event event;
1040
1041 PDBG("%s ep %p tid %u status %d\n", __func__, ep, ep->hwtid, status);
1042 memset(&event, 0, sizeof(event));
1043 event.event = IW_CM_EVENT_CONNECT_REPLY;
1044 event.status = status;
Steve Wise24d44a32013-07-04 16:10:44 +05301045 memcpy(&event.local_addr, &ep->com.local_addr,
1046 sizeof(ep->com.local_addr));
1047 memcpy(&event.remote_addr, &ep->com.remote_addr,
1048 sizeof(ep->com.remote_addr));
Steve Wisecfdda9d2010-04-21 15:30:06 -07001049
1050 if ((status == 0) || (status == -ECONNREFUSED)) {
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +05301051 if (!ep->tried_with_mpa_v1) {
1052 /* this means MPA_v2 is used */
1053 event.private_data_len = ep->plen -
1054 sizeof(struct mpa_v2_conn_params);
1055 event.private_data = ep->mpa_pkt +
1056 sizeof(struct mpa_message) +
1057 sizeof(struct mpa_v2_conn_params);
1058 } else {
1059 /* this means MPA_v1 is used */
1060 event.private_data_len = ep->plen;
1061 event.private_data = ep->mpa_pkt +
1062 sizeof(struct mpa_message);
1063 }
Steve Wisecfdda9d2010-04-21 15:30:06 -07001064 }
Roland Dreier85963e42010-07-19 13:13:09 -07001065
1066 PDBG("%s ep %p tid %u status %d\n", __func__, ep,
1067 ep->hwtid, status);
Vipul Pandya793dad92012-12-10 09:30:56 +00001068 set_bit(CONN_RPL_UPCALL, &ep->com.history);
Roland Dreier85963e42010-07-19 13:13:09 -07001069 ep->com.cm_id->event_handler(ep->com.cm_id, &event);
1070
Steve Wisecfdda9d2010-04-21 15:30:06 -07001071 if (status < 0) {
1072 ep->com.cm_id->rem_ref(ep->com.cm_id);
1073 ep->com.cm_id = NULL;
Steve Wisecfdda9d2010-04-21 15:30:06 -07001074 }
1075}
1076
Steve Wisebe13b2d2014-03-21 20:40:33 +05301077static int connect_request_upcall(struct c4iw_ep *ep)
Steve Wisecfdda9d2010-04-21 15:30:06 -07001078{
1079 struct iw_cm_event event;
Steve Wisebe13b2d2014-03-21 20:40:33 +05301080 int ret;
Steve Wisecfdda9d2010-04-21 15:30:06 -07001081
1082 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
1083 memset(&event, 0, sizeof(event));
1084 event.event = IW_CM_EVENT_CONNECT_REQUEST;
Steve Wise24d44a32013-07-04 16:10:44 +05301085 memcpy(&event.local_addr, &ep->com.local_addr,
1086 sizeof(ep->com.local_addr));
1087 memcpy(&event.remote_addr, &ep->com.remote_addr,
1088 sizeof(ep->com.remote_addr));
Steve Wisecfdda9d2010-04-21 15:30:06 -07001089 event.provider_data = ep;
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +05301090 if (!ep->tried_with_mpa_v1) {
1091 /* this means MPA_v2 is used */
1092 event.ord = ep->ord;
1093 event.ird = ep->ird;
1094 event.private_data_len = ep->plen -
1095 sizeof(struct mpa_v2_conn_params);
1096 event.private_data = ep->mpa_pkt + sizeof(struct mpa_message) +
1097 sizeof(struct mpa_v2_conn_params);
1098 } else {
1099 /* this means MPA_v1 is used. Send max supported */
1100 event.ord = c4iw_max_read_depth;
1101 event.ird = c4iw_max_read_depth;
1102 event.private_data_len = ep->plen;
1103 event.private_data = ep->mpa_pkt + sizeof(struct mpa_message);
1104 }
Steve Wisebe13b2d2014-03-21 20:40:33 +05301105 c4iw_get_ep(&ep->com);
1106 ret = ep->parent_ep->com.cm_id->event_handler(ep->parent_ep->com.cm_id,
1107 &event);
1108 if (ret)
1109 c4iw_put_ep(&ep->com);
Vipul Pandya793dad92012-12-10 09:30:56 +00001110 set_bit(CONNREQ_UPCALL, &ep->com.history);
Steve Wisecfdda9d2010-04-21 15:30:06 -07001111 c4iw_put_ep(&ep->parent_ep->com);
Steve Wisebe13b2d2014-03-21 20:40:33 +05301112 return ret;
Steve Wisecfdda9d2010-04-21 15:30:06 -07001113}
1114
1115static void established_upcall(struct c4iw_ep *ep)
1116{
1117 struct iw_cm_event event;
1118
1119 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
1120 memset(&event, 0, sizeof(event));
1121 event.event = IW_CM_EVENT_ESTABLISHED;
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +05301122 event.ird = ep->ird;
1123 event.ord = ep->ord;
Steve Wisecfdda9d2010-04-21 15:30:06 -07001124 if (ep->com.cm_id) {
1125 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
1126 ep->com.cm_id->event_handler(ep->com.cm_id, &event);
Vipul Pandya793dad92012-12-10 09:30:56 +00001127 set_bit(ESTAB_UPCALL, &ep->com.history);
Steve Wisecfdda9d2010-04-21 15:30:06 -07001128 }
1129}
1130
1131static int update_rx_credits(struct c4iw_ep *ep, u32 credits)
1132{
1133 struct cpl_rx_data_ack *req;
1134 struct sk_buff *skb;
1135 int wrlen = roundup(sizeof *req, 16);
1136
1137 PDBG("%s ep %p tid %u credits %u\n", __func__, ep, ep->hwtid, credits);
1138 skb = get_skb(NULL, wrlen, GFP_KERNEL);
1139 if (!skb) {
1140 printk(KERN_ERR MOD "update_rx_credits - cannot alloc skb!\n");
1141 return 0;
1142 }
1143
1144 req = (struct cpl_rx_data_ack *) skb_put(skb, wrlen);
1145 memset(req, 0, wrlen);
1146 INIT_TP_WR(req, ep->hwtid);
1147 OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_RX_DATA_ACK,
1148 ep->hwtid));
Steve Wiseba6d3922010-06-23 15:46:49 +00001149 req->credit_dack = cpu_to_be32(credits | RX_FORCE_ACK(1) |
1150 F_RX_DACK_CHANGE |
1151 V_RX_DACK_MODE(dack_mode));
Steve Wised4f1a5c2010-07-23 19:12:32 +00001152 set_wr_txq(skb, CPL_PRIORITY_ACK, ep->ctrlq_idx);
Steve Wisecfdda9d2010-04-21 15:30:06 -07001153 c4iw_ofld_send(&ep->com.dev->rdev, skb);
1154 return credits;
1155}
1156
1157static void process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb)
1158{
1159 struct mpa_message *mpa;
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +05301160 struct mpa_v2_conn_params *mpa_v2_params;
Steve Wisecfdda9d2010-04-21 15:30:06 -07001161 u16 plen;
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +05301162 u16 resp_ird, resp_ord;
1163 u8 rtr_mismatch = 0, insuff_ird = 0;
Steve Wisecfdda9d2010-04-21 15:30:06 -07001164 struct c4iw_qp_attributes attrs;
1165 enum c4iw_qp_attr_mask mask;
1166 int err;
1167
1168 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
1169
1170 /*
Steve Wiseb33bd0c2014-04-09 09:38:25 -05001171 * Stop mpa timer. If it expired, then
1172 * we ignore the MPA reply. process_timeout()
1173 * will abort the connection.
Steve Wisecfdda9d2010-04-21 15:30:06 -07001174 */
Steve Wiseb33bd0c2014-04-09 09:38:25 -05001175 if (stop_ep_timer(ep))
Steve Wisecfdda9d2010-04-21 15:30:06 -07001176 return;
1177
1178 /*
1179 * If we get more than the supported amount of private data
1180 * then we must fail this connection.
1181 */
1182 if (ep->mpa_pkt_len + skb->len > sizeof(ep->mpa_pkt)) {
1183 err = -EINVAL;
1184 goto err;
1185 }
1186
1187 /*
1188 * copy the new data into our accumulation buffer.
1189 */
1190 skb_copy_from_linear_data(skb, &(ep->mpa_pkt[ep->mpa_pkt_len]),
1191 skb->len);
1192 ep->mpa_pkt_len += skb->len;
1193
1194 /*
1195 * if we don't even have the mpa message, then bail.
1196 */
1197 if (ep->mpa_pkt_len < sizeof(*mpa))
1198 return;
1199 mpa = (struct mpa_message *) ep->mpa_pkt;
1200
1201 /* Validate MPA header. */
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +05301202 if (mpa->revision > mpa_rev) {
1203 printk(KERN_ERR MOD "%s MPA version mismatch. Local = %d,"
1204 " Received = %d\n", __func__, mpa_rev, mpa->revision);
Steve Wisecfdda9d2010-04-21 15:30:06 -07001205 err = -EPROTO;
1206 goto err;
1207 }
1208 if (memcmp(mpa->key, MPA_KEY_REP, sizeof(mpa->key))) {
1209 err = -EPROTO;
1210 goto err;
1211 }
1212
1213 plen = ntohs(mpa->private_data_size);
1214
1215 /*
1216 * Fail if there's too much private data.
1217 */
1218 if (plen > MPA_MAX_PRIVATE_DATA) {
1219 err = -EPROTO;
1220 goto err;
1221 }
1222
1223 /*
1224 * If plen does not account for pkt size
1225 */
1226 if (ep->mpa_pkt_len > (sizeof(*mpa) + plen)) {
1227 err = -EPROTO;
1228 goto err;
1229 }
1230
1231 ep->plen = (u8) plen;
1232
1233 /*
1234 * If we don't have all the pdata yet, then bail.
1235 * We'll continue process when more data arrives.
1236 */
1237 if (ep->mpa_pkt_len < (sizeof(*mpa) + plen))
1238 return;
1239
1240 if (mpa->flags & MPA_REJECT) {
1241 err = -ECONNREFUSED;
1242 goto err;
1243 }
1244
1245 /*
1246 * If we get here we have accumulated the entire mpa
1247 * start reply message including private data. And
1248 * the MPA header is valid.
1249 */
Steve Wisec529fb52014-03-21 20:40:37 +05301250 __state_set(&ep->com, FPDU_MODE);
Steve Wisecfdda9d2010-04-21 15:30:06 -07001251 ep->mpa_attr.crc_enabled = (mpa->flags & MPA_CRC) | crc_enabled ? 1 : 0;
1252 ep->mpa_attr.recv_marker_enabled = markers_enabled;
1253 ep->mpa_attr.xmit_marker_enabled = mpa->flags & MPA_MARKERS ? 1 : 0;
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +05301254 ep->mpa_attr.version = mpa->revision;
1255 ep->mpa_attr.p2p_type = FW_RI_INIT_P2PTYPE_DISABLED;
1256
1257 if (mpa->revision == 2) {
1258 ep->mpa_attr.enhanced_rdma_conn =
1259 mpa->flags & MPA_ENHANCED_RDMA_CONN ? 1 : 0;
1260 if (ep->mpa_attr.enhanced_rdma_conn) {
1261 mpa_v2_params = (struct mpa_v2_conn_params *)
1262 (ep->mpa_pkt + sizeof(*mpa));
1263 resp_ird = ntohs(mpa_v2_params->ird) &
1264 MPA_V2_IRD_ORD_MASK;
1265 resp_ord = ntohs(mpa_v2_params->ord) &
1266 MPA_V2_IRD_ORD_MASK;
1267
1268 /*
1269 * This is a double-check. Ideally, below checks are
1270 * not required since ird/ord stuff has been taken
1271 * care of in c4iw_accept_cr
1272 */
1273 if ((ep->ird < resp_ord) || (ep->ord > resp_ird)) {
1274 err = -ENOMEM;
1275 ep->ird = resp_ord;
1276 ep->ord = resp_ird;
1277 insuff_ird = 1;
1278 }
1279
1280 if (ntohs(mpa_v2_params->ird) &
1281 MPA_V2_PEER2PEER_MODEL) {
1282 if (ntohs(mpa_v2_params->ord) &
1283 MPA_V2_RDMA_WRITE_RTR)
1284 ep->mpa_attr.p2p_type =
1285 FW_RI_INIT_P2PTYPE_RDMA_WRITE;
1286 else if (ntohs(mpa_v2_params->ord) &
1287 MPA_V2_RDMA_READ_RTR)
1288 ep->mpa_attr.p2p_type =
1289 FW_RI_INIT_P2PTYPE_READ_REQ;
1290 }
1291 }
1292 } else if (mpa->revision == 1)
1293 if (peer2peer)
1294 ep->mpa_attr.p2p_type = p2p_type;
1295
Steve Wisecfdda9d2010-04-21 15:30:06 -07001296 PDBG("%s - crc_enabled=%d, recv_marker_enabled=%d, "
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +05301297 "xmit_marker_enabled=%d, version=%d p2p_type=%d local-p2p_type = "
1298 "%d\n", __func__, ep->mpa_attr.crc_enabled,
1299 ep->mpa_attr.recv_marker_enabled,
1300 ep->mpa_attr.xmit_marker_enabled, ep->mpa_attr.version,
1301 ep->mpa_attr.p2p_type, p2p_type);
1302
1303 /*
1304 * If responder's RTR does not match with that of initiator, assign
1305 * FW_RI_INIT_P2PTYPE_DISABLED in mpa attributes so that RTR is not
1306 * generated when moving QP to RTS state.
1307 * A TERM message will be sent after QP has moved to RTS state
1308 */
Kumar Sanghvi91018f82012-02-25 17:45:02 -08001309 if ((ep->mpa_attr.version == 2) && peer2peer &&
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +05301310 (ep->mpa_attr.p2p_type != p2p_type)) {
1311 ep->mpa_attr.p2p_type = FW_RI_INIT_P2PTYPE_DISABLED;
1312 rtr_mismatch = 1;
1313 }
Steve Wisecfdda9d2010-04-21 15:30:06 -07001314
1315 attrs.mpa_attr = ep->mpa_attr;
1316 attrs.max_ird = ep->ird;
1317 attrs.max_ord = ep->ord;
1318 attrs.llp_stream_handle = ep;
1319 attrs.next_state = C4IW_QP_STATE_RTS;
1320
1321 mask = C4IW_QP_ATTR_NEXT_STATE |
1322 C4IW_QP_ATTR_LLP_STREAM_HANDLE | C4IW_QP_ATTR_MPA_ATTR |
1323 C4IW_QP_ATTR_MAX_IRD | C4IW_QP_ATTR_MAX_ORD;
1324
1325 /* bind QP and TID with INIT_WR */
1326 err = c4iw_modify_qp(ep->com.qp->rhp,
1327 ep->com.qp, mask, &attrs, 1);
1328 if (err)
1329 goto err;
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +05301330
1331 /*
1332 * If responder's RTR requirement did not match with what initiator
1333 * supports, generate TERM message
1334 */
1335 if (rtr_mismatch) {
1336 printk(KERN_ERR "%s: RTR mismatch, sending TERM\n", __func__);
1337 attrs.layer_etype = LAYER_MPA | DDP_LLP;
1338 attrs.ecode = MPA_NOMATCH_RTR;
1339 attrs.next_state = C4IW_QP_STATE_TERMINATE;
1340 err = c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,
1341 C4IW_QP_ATTR_NEXT_STATE, &attrs, 0);
1342 err = -ENOMEM;
1343 goto out;
1344 }
1345
1346 /*
1347 * Generate TERM if initiator IRD is not sufficient for responder
1348 * provided ORD. Currently, we do the same behaviour even when
1349 * responder provided IRD is also not sufficient as regards to
1350 * initiator ORD.
1351 */
1352 if (insuff_ird) {
1353 printk(KERN_ERR "%s: Insufficient IRD, sending TERM\n",
1354 __func__);
1355 attrs.layer_etype = LAYER_MPA | DDP_LLP;
1356 attrs.ecode = MPA_INSUFF_IRD;
1357 attrs.next_state = C4IW_QP_STATE_TERMINATE;
1358 err = c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,
1359 C4IW_QP_ATTR_NEXT_STATE, &attrs, 0);
1360 err = -ENOMEM;
1361 goto out;
1362 }
Steve Wisecfdda9d2010-04-21 15:30:06 -07001363 goto out;
1364err:
Steve Wisec529fb52014-03-21 20:40:37 +05301365 __state_set(&ep->com, ABORTING);
Steve Wiseb21ef162010-06-10 19:02:55 +00001366 send_abort(ep, skb, GFP_KERNEL);
Steve Wisecfdda9d2010-04-21 15:30:06 -07001367out:
1368 connect_reply_upcall(ep, err);
1369 return;
1370}
1371
1372static void process_mpa_request(struct c4iw_ep *ep, struct sk_buff *skb)
1373{
1374 struct mpa_message *mpa;
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +05301375 struct mpa_v2_conn_params *mpa_v2_params;
Steve Wisecfdda9d2010-04-21 15:30:06 -07001376 u16 plen;
1377
1378 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
1379
Steve Wisecfdda9d2010-04-21 15:30:06 -07001380 /*
1381 * If we get more than the supported amount of private data
1382 * then we must fail this connection.
1383 */
1384 if (ep->mpa_pkt_len + skb->len > sizeof(ep->mpa_pkt)) {
Steve Wiseb33bd0c2014-04-09 09:38:25 -05001385 (void)stop_ep_timer(ep);
Steve Wisecfdda9d2010-04-21 15:30:06 -07001386 abort_connection(ep, skb, GFP_KERNEL);
1387 return;
1388 }
1389
1390 PDBG("%s enter (%s line %u)\n", __func__, __FILE__, __LINE__);
1391
1392 /*
1393 * Copy the new data into our accumulation buffer.
1394 */
1395 skb_copy_from_linear_data(skb, &(ep->mpa_pkt[ep->mpa_pkt_len]),
1396 skb->len);
1397 ep->mpa_pkt_len += skb->len;
1398
1399 /*
1400 * If we don't even have the mpa message, then bail.
1401 * We'll continue process when more data arrives.
1402 */
1403 if (ep->mpa_pkt_len < sizeof(*mpa))
1404 return;
1405
1406 PDBG("%s enter (%s line %u)\n", __func__, __FILE__, __LINE__);
Steve Wisecfdda9d2010-04-21 15:30:06 -07001407 mpa = (struct mpa_message *) ep->mpa_pkt;
1408
1409 /*
1410 * Validate MPA Header.
1411 */
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +05301412 if (mpa->revision > mpa_rev) {
1413 printk(KERN_ERR MOD "%s MPA version mismatch. Local = %d,"
1414 " Received = %d\n", __func__, mpa_rev, mpa->revision);
Steve Wiseb33bd0c2014-04-09 09:38:25 -05001415 (void)stop_ep_timer(ep);
Steve Wisecfdda9d2010-04-21 15:30:06 -07001416 abort_connection(ep, skb, GFP_KERNEL);
1417 return;
1418 }
1419
1420 if (memcmp(mpa->key, MPA_KEY_REQ, sizeof(mpa->key))) {
Steve Wiseb33bd0c2014-04-09 09:38:25 -05001421 (void)stop_ep_timer(ep);
Steve Wisecfdda9d2010-04-21 15:30:06 -07001422 abort_connection(ep, skb, GFP_KERNEL);
1423 return;
1424 }
1425
1426 plen = ntohs(mpa->private_data_size);
1427
1428 /*
1429 * Fail if there's too much private data.
1430 */
1431 if (plen > MPA_MAX_PRIVATE_DATA) {
Steve Wiseb33bd0c2014-04-09 09:38:25 -05001432 (void)stop_ep_timer(ep);
Steve Wisecfdda9d2010-04-21 15:30:06 -07001433 abort_connection(ep, skb, GFP_KERNEL);
1434 return;
1435 }
1436
1437 /*
1438 * If plen does not account for pkt size
1439 */
1440 if (ep->mpa_pkt_len > (sizeof(*mpa) + plen)) {
Steve Wiseb33bd0c2014-04-09 09:38:25 -05001441 (void)stop_ep_timer(ep);
Steve Wisecfdda9d2010-04-21 15:30:06 -07001442 abort_connection(ep, skb, GFP_KERNEL);
1443 return;
1444 }
1445 ep->plen = (u8) plen;
1446
1447 /*
1448 * If we don't have all the pdata yet, then bail.
1449 */
1450 if (ep->mpa_pkt_len < (sizeof(*mpa) + plen))
1451 return;
1452
1453 /*
1454 * If we get here we have accumulated the entire mpa
1455 * start reply message including private data.
1456 */
1457 ep->mpa_attr.initiator = 0;
1458 ep->mpa_attr.crc_enabled = (mpa->flags & MPA_CRC) | crc_enabled ? 1 : 0;
1459 ep->mpa_attr.recv_marker_enabled = markers_enabled;
1460 ep->mpa_attr.xmit_marker_enabled = mpa->flags & MPA_MARKERS ? 1 : 0;
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +05301461 ep->mpa_attr.version = mpa->revision;
1462 if (mpa->revision == 1)
1463 ep->tried_with_mpa_v1 = 1;
1464 ep->mpa_attr.p2p_type = FW_RI_INIT_P2PTYPE_DISABLED;
1465
1466 if (mpa->revision == 2) {
1467 ep->mpa_attr.enhanced_rdma_conn =
1468 mpa->flags & MPA_ENHANCED_RDMA_CONN ? 1 : 0;
1469 if (ep->mpa_attr.enhanced_rdma_conn) {
1470 mpa_v2_params = (struct mpa_v2_conn_params *)
1471 (ep->mpa_pkt + sizeof(*mpa));
1472 ep->ird = ntohs(mpa_v2_params->ird) &
1473 MPA_V2_IRD_ORD_MASK;
1474 ep->ord = ntohs(mpa_v2_params->ord) &
1475 MPA_V2_IRD_ORD_MASK;
1476 if (ntohs(mpa_v2_params->ird) & MPA_V2_PEER2PEER_MODEL)
1477 if (peer2peer) {
1478 if (ntohs(mpa_v2_params->ord) &
1479 MPA_V2_RDMA_WRITE_RTR)
1480 ep->mpa_attr.p2p_type =
1481 FW_RI_INIT_P2PTYPE_RDMA_WRITE;
1482 else if (ntohs(mpa_v2_params->ord) &
1483 MPA_V2_RDMA_READ_RTR)
1484 ep->mpa_attr.p2p_type =
1485 FW_RI_INIT_P2PTYPE_READ_REQ;
1486 }
1487 }
1488 } else if (mpa->revision == 1)
1489 if (peer2peer)
1490 ep->mpa_attr.p2p_type = p2p_type;
1491
Steve Wisecfdda9d2010-04-21 15:30:06 -07001492 PDBG("%s - crc_enabled=%d, recv_marker_enabled=%d, "
1493 "xmit_marker_enabled=%d, version=%d p2p_type=%d\n", __func__,
1494 ep->mpa_attr.crc_enabled, ep->mpa_attr.recv_marker_enabled,
1495 ep->mpa_attr.xmit_marker_enabled, ep->mpa_attr.version,
1496 ep->mpa_attr.p2p_type);
1497
Steve Wiseb33bd0c2014-04-09 09:38:25 -05001498 /*
1499 * If the endpoint timer already expired, then we ignore
1500 * the start request. process_timeout() will abort
1501 * the connection.
1502 */
1503 if (!stop_ep_timer(ep)) {
1504 __state_set(&ep->com, MPA_REQ_RCVD);
Steve Wisecfdda9d2010-04-21 15:30:06 -07001505
Steve Wiseb33bd0c2014-04-09 09:38:25 -05001506 /* drive upcall */
1507 mutex_lock(&ep->parent_ep->com.mutex);
1508 if (ep->parent_ep->com.state != DEAD) {
1509 if (connect_request_upcall(ep))
1510 abort_connection(ep, skb, GFP_KERNEL);
1511 } else {
Steve Wisebe13b2d2014-03-21 20:40:33 +05301512 abort_connection(ep, skb, GFP_KERNEL);
Steve Wiseb33bd0c2014-04-09 09:38:25 -05001513 }
1514 mutex_unlock(&ep->parent_ep->com.mutex);
Steve Wisebe13b2d2014-03-21 20:40:33 +05301515 }
Steve Wisecfdda9d2010-04-21 15:30:06 -07001516 return;
1517}
1518
1519static int rx_data(struct c4iw_dev *dev, struct sk_buff *skb)
1520{
1521 struct c4iw_ep *ep;
1522 struct cpl_rx_data *hdr = cplhdr(skb);
1523 unsigned int dlen = ntohs(hdr->len);
1524 unsigned int tid = GET_TID(hdr);
1525 struct tid_info *t = dev->rdev.lldi.tids;
Vipul Pandya793dad92012-12-10 09:30:56 +00001526 __u8 status = hdr->status;
Steve Wisecfdda9d2010-04-21 15:30:06 -07001527
1528 ep = lookup_tid(t, tid);
Steve Wise977116c2014-03-21 20:40:36 +05301529 if (!ep)
1530 return 0;
Steve Wisecfdda9d2010-04-21 15:30:06 -07001531 PDBG("%s ep %p tid %u dlen %u\n", __func__, ep, ep->hwtid, dlen);
1532 skb_pull(skb, sizeof(*hdr));
1533 skb_trim(skb, dlen);
Steve Wisec529fb52014-03-21 20:40:37 +05301534 mutex_lock(&ep->com.mutex);
Steve Wisecfdda9d2010-04-21 15:30:06 -07001535
Steve Wisecfdda9d2010-04-21 15:30:06 -07001536 /* update RX credits */
1537 update_rx_credits(ep, dlen);
1538
Steve Wisec529fb52014-03-21 20:40:37 +05301539 switch (ep->com.state) {
Steve Wisecfdda9d2010-04-21 15:30:06 -07001540 case MPA_REQ_SENT:
Vipul Pandya55abf8d2013-01-07 13:11:50 +00001541 ep->rcv_seq += dlen;
Steve Wisecfdda9d2010-04-21 15:30:06 -07001542 process_mpa_reply(ep, skb);
1543 break;
1544 case MPA_REQ_WAIT:
Vipul Pandya55abf8d2013-01-07 13:11:50 +00001545 ep->rcv_seq += dlen;
Steve Wisecfdda9d2010-04-21 15:30:06 -07001546 process_mpa_request(ep, skb);
1547 break;
Vipul Pandya15579672013-01-07 13:11:52 +00001548 case FPDU_MODE: {
1549 struct c4iw_qp_attributes attrs;
1550 BUG_ON(!ep->com.qp);
Vipul Pandyae8e5b922013-01-07 13:11:55 +00001551 if (status)
Vipul Pandya15579672013-01-07 13:11:52 +00001552 pr_err("%s Unexpected streaming data." \
Vipul Pandya04236df2013-01-07 13:11:54 +00001553 " qpid %u ep %p state %d tid %u status %d\n",
1554 __func__, ep->com.qp->wq.sq.qid, ep,
Steve Wisec529fb52014-03-21 20:40:37 +05301555 ep->com.state, ep->hwtid, status);
Steve Wise97d7ec02013-08-06 21:04:34 +05301556 attrs.next_state = C4IW_QP_STATE_TERMINATE;
Vipul Pandya15579672013-01-07 13:11:52 +00001557 c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,
Steve Wise97d7ec02013-08-06 21:04:34 +05301558 C4IW_QP_ATTR_NEXT_STATE, &attrs, 0);
Steve Wisecfdda9d2010-04-21 15:30:06 -07001559 break;
1560 }
Vipul Pandya15579672013-01-07 13:11:52 +00001561 default:
1562 break;
1563 }
Steve Wisec529fb52014-03-21 20:40:37 +05301564 mutex_unlock(&ep->com.mutex);
Steve Wisecfdda9d2010-04-21 15:30:06 -07001565 return 0;
1566}
1567
1568static int abort_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
1569{
1570 struct c4iw_ep *ep;
1571 struct cpl_abort_rpl_rss *rpl = cplhdr(skb);
Steve Wisecfdda9d2010-04-21 15:30:06 -07001572 int release = 0;
1573 unsigned int tid = GET_TID(rpl);
1574 struct tid_info *t = dev->rdev.lldi.tids;
1575
1576 ep = lookup_tid(t, tid);
Vipul Pandya49840372012-05-18 15:29:29 +05301577 if (!ep) {
1578 printk(KERN_WARNING MOD "Abort rpl to freed endpoint\n");
1579 return 0;
1580 }
Wei Yongjun92dd6c32012-09-07 06:51:23 +00001581 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
Steve Wise2f5b48c2010-09-10 11:15:36 -05001582 mutex_lock(&ep->com.mutex);
Steve Wisecfdda9d2010-04-21 15:30:06 -07001583 switch (ep->com.state) {
1584 case ABORTING:
Vipul Pandya91e9c0712013-01-07 13:11:51 +00001585 c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET);
Steve Wisecfdda9d2010-04-21 15:30:06 -07001586 __state_set(&ep->com, DEAD);
1587 release = 1;
1588 break;
1589 default:
1590 printk(KERN_ERR "%s ep %p state %d\n",
1591 __func__, ep, ep->com.state);
1592 break;
1593 }
Steve Wise2f5b48c2010-09-10 11:15:36 -05001594 mutex_unlock(&ep->com.mutex);
Steve Wisecfdda9d2010-04-21 15:30:06 -07001595
1596 if (release)
1597 release_ep_resources(ep);
1598 return 0;
1599}
1600
Vipul Pandya5be78ee2012-12-10 09:30:54 +00001601static void send_fw_act_open_req(struct c4iw_ep *ep, unsigned int atid)
1602{
1603 struct sk_buff *skb;
1604 struct fw_ofld_connection_wr *req;
1605 unsigned int mtu_idx;
1606 int wscale;
Vipul Pandya830662f2013-07-04 16:10:47 +05301607 struct sockaddr_in *sin;
Vipul Pandya5be78ee2012-12-10 09:30:54 +00001608
1609 skb = get_skb(NULL, sizeof(*req), GFP_KERNEL);
1610 req = (struct fw_ofld_connection_wr *)__skb_put(skb, sizeof(*req));
1611 memset(req, 0, sizeof(*req));
1612 req->op_compl = htonl(V_WR_OP(FW_OFLD_CONNECTION_WR));
1613 req->len16_pkd = htonl(FW_WR_LEN16(DIV_ROUND_UP(sizeof(*req), 16)));
Kumar Sanghvi41b4f862013-12-18 16:38:26 +05301614 req->le.filter = cpu_to_be32(cxgb4_select_ntuple(
1615 ep->com.dev->rdev.lldi.ports[0],
Vipul Pandya5be78ee2012-12-10 09:30:54 +00001616 ep->l2t));
Vipul Pandya830662f2013-07-04 16:10:47 +05301617 sin = (struct sockaddr_in *)&ep->com.local_addr;
1618 req->le.lport = sin->sin_port;
1619 req->le.u.ipv4.lip = sin->sin_addr.s_addr;
1620 sin = (struct sockaddr_in *)&ep->com.remote_addr;
1621 req->le.pport = sin->sin_port;
1622 req->le.u.ipv4.pip = sin->sin_addr.s_addr;
Vipul Pandya5be78ee2012-12-10 09:30:54 +00001623 req->tcb.t_state_to_astid =
1624 htonl(V_FW_OFLD_CONNECTION_WR_T_STATE(TCP_SYN_SENT) |
1625 V_FW_OFLD_CONNECTION_WR_ASTID(atid));
1626 req->tcb.cplrxdataack_cplpassacceptrpl =
1627 htons(F_FW_OFLD_CONNECTION_WR_CPLRXDATAACK);
Vipul Pandyaef5d6352013-01-07 13:12:00 +00001628 req->tcb.tx_max = (__force __be32) jiffies;
Vipul Pandya793dad92012-12-10 09:30:56 +00001629 req->tcb.rcv_adv = htons(1);
Vipul Pandya5be78ee2012-12-10 09:30:54 +00001630 cxgb4_best_mtu(ep->com.dev->rdev.lldi.mtus, ep->mtu, &mtu_idx);
1631 wscale = compute_wscale(rcv_win);
Vipul Pandyaef5d6352013-01-07 13:12:00 +00001632 req->tcb.opt0 = (__force __be64) (TCAM_BYPASS(1) |
Vipul Pandya5be78ee2012-12-10 09:30:54 +00001633 (nocong ? NO_CONG(1) : 0) |
1634 KEEP_ALIVE(1) |
1635 DELACK(1) |
1636 WND_SCALE(wscale) |
1637 MSS_IDX(mtu_idx) |
1638 L2T_IDX(ep->l2t->idx) |
1639 TX_CHAN(ep->tx_chan) |
1640 SMAC_SEL(ep->smac_idx) |
1641 DSCP(ep->tos) |
1642 ULP_MODE(ULP_MODE_TCPDDP) |
Vipul Pandyaef5d6352013-01-07 13:12:00 +00001643 RCV_BUFSIZ(rcv_win >> 10));
1644 req->tcb.opt2 = (__force __be32) (PACE(1) |
Vipul Pandya5be78ee2012-12-10 09:30:54 +00001645 TX_QUEUE(ep->com.dev->rdev.lldi.tx_modq[ep->tx_chan]) |
1646 RX_CHANNEL(0) |
1647 CCTRL_ECN(enable_ecn) |
Vipul Pandyaef5d6352013-01-07 13:12:00 +00001648 RSS_QUEUE_VALID | RSS_QUEUE(ep->rss_qid));
Vipul Pandya5be78ee2012-12-10 09:30:54 +00001649 if (enable_tcp_timestamps)
Vipul Pandyaef5d6352013-01-07 13:12:00 +00001650 req->tcb.opt2 |= (__force __be32) TSTAMPS_EN(1);
Vipul Pandya5be78ee2012-12-10 09:30:54 +00001651 if (enable_tcp_sack)
Vipul Pandyaef5d6352013-01-07 13:12:00 +00001652 req->tcb.opt2 |= (__force __be32) SACK_EN(1);
Vipul Pandya5be78ee2012-12-10 09:30:54 +00001653 if (wscale && enable_tcp_window_scaling)
Vipul Pandyaef5d6352013-01-07 13:12:00 +00001654 req->tcb.opt2 |= (__force __be32) WND_SCALE_EN(1);
1655 req->tcb.opt0 = cpu_to_be64((__force u64) req->tcb.opt0);
1656 req->tcb.opt2 = cpu_to_be32((__force u32) req->tcb.opt2);
Vipul Pandya793dad92012-12-10 09:30:56 +00001657 set_wr_txq(skb, CPL_PRIORITY_CONTROL, ep->ctrlq_idx);
1658 set_bit(ACT_OFLD_CONN, &ep->com.history);
Vipul Pandya5be78ee2012-12-10 09:30:54 +00001659 c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t);
1660}
1661
Steve Wisecfdda9d2010-04-21 15:30:06 -07001662/*
1663 * Return whether a failed active open has allocated a TID
1664 */
1665static inline int act_open_has_tid(int status)
1666{
1667 return status != CPL_ERR_TCAM_FULL && status != CPL_ERR_CONN_EXIST &&
1668 status != CPL_ERR_ARP_MISS;
1669}
1670
Steve Wise7a2cea22014-03-14 21:52:07 +05301671/* Returns whether a CPL status conveys negative advice.
1672 */
1673static int is_neg_adv(unsigned int status)
1674{
1675 return status == CPL_ERR_RTX_NEG_ADVICE ||
1676 status == CPL_ERR_PERSIST_NEG_ADVICE ||
1677 status == CPL_ERR_KEEPALV_NEG_ADVICE;
1678}
1679
Vipul Pandya793dad92012-12-10 09:30:56 +00001680#define ACT_OPEN_RETRY_COUNT 2
1681
Vipul Pandya830662f2013-07-04 16:10:47 +05301682static int import_ep(struct c4iw_ep *ep, int iptype, __u8 *peer_ip,
1683 struct dst_entry *dst, struct c4iw_dev *cdev,
1684 bool clear_mpa_v1)
1685{
1686 struct neighbour *n;
1687 int err, step;
1688 struct net_device *pdev;
1689
1690 n = dst_neigh_lookup(dst, peer_ip);
1691 if (!n)
1692 return -ENODEV;
1693
1694 rcu_read_lock();
1695 err = -ENOMEM;
1696 if (n->dev->flags & IFF_LOOPBACK) {
1697 if (iptype == 4)
1698 pdev = ip_dev_find(&init_net, *(__be32 *)peer_ip);
1699 else if (IS_ENABLED(CONFIG_IPV6))
1700 for_each_netdev(&init_net, pdev) {
1701 if (ipv6_chk_addr(&init_net,
1702 (struct in6_addr *)peer_ip,
1703 pdev, 1))
1704 break;
1705 }
1706 else
1707 pdev = NULL;
1708
1709 if (!pdev) {
1710 err = -ENODEV;
1711 goto out;
1712 }
1713 ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t,
1714 n, pdev, 0);
1715 if (!ep->l2t)
1716 goto out;
1717 ep->mtu = pdev->mtu;
1718 ep->tx_chan = cxgb4_port_chan(pdev);
1719 ep->smac_idx = (cxgb4_port_viid(pdev) & 0x7F) << 1;
1720 step = cdev->rdev.lldi.ntxq /
1721 cdev->rdev.lldi.nchan;
1722 ep->txq_idx = cxgb4_port_idx(pdev) * step;
1723 step = cdev->rdev.lldi.nrxq /
1724 cdev->rdev.lldi.nchan;
1725 ep->ctrlq_idx = cxgb4_port_idx(pdev);
1726 ep->rss_qid = cdev->rdev.lldi.rxq_ids[
1727 cxgb4_port_idx(pdev) * step];
1728 dev_put(pdev);
1729 } else {
1730 pdev = get_real_dev(n->dev);
1731 ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t,
1732 n, pdev, 0);
1733 if (!ep->l2t)
1734 goto out;
1735 ep->mtu = dst_mtu(dst);
1736 ep->tx_chan = cxgb4_port_chan(n->dev);
1737 ep->smac_idx = (cxgb4_port_viid(n->dev) & 0x7F) << 1;
1738 step = cdev->rdev.lldi.ntxq /
1739 cdev->rdev.lldi.nchan;
1740 ep->txq_idx = cxgb4_port_idx(n->dev) * step;
1741 ep->ctrlq_idx = cxgb4_port_idx(n->dev);
1742 step = cdev->rdev.lldi.nrxq /
1743 cdev->rdev.lldi.nchan;
1744 ep->rss_qid = cdev->rdev.lldi.rxq_ids[
1745 cxgb4_port_idx(n->dev) * step];
1746
1747 if (clear_mpa_v1) {
1748 ep->retry_with_mpa_v1 = 0;
1749 ep->tried_with_mpa_v1 = 0;
1750 }
1751 }
1752 err = 0;
1753out:
1754 rcu_read_unlock();
1755
1756 neigh_release(n);
1757
1758 return err;
1759}
1760
Vipul Pandya793dad92012-12-10 09:30:56 +00001761static int c4iw_reconnect(struct c4iw_ep *ep)
1762{
1763 int err = 0;
Steve Wise24d44a32013-07-04 16:10:44 +05301764 struct sockaddr_in *laddr = (struct sockaddr_in *)
1765 &ep->com.cm_id->local_addr;
1766 struct sockaddr_in *raddr = (struct sockaddr_in *)
1767 &ep->com.cm_id->remote_addr;
Vipul Pandya830662f2013-07-04 16:10:47 +05301768 struct sockaddr_in6 *laddr6 = (struct sockaddr_in6 *)
1769 &ep->com.cm_id->local_addr;
1770 struct sockaddr_in6 *raddr6 = (struct sockaddr_in6 *)
1771 &ep->com.cm_id->remote_addr;
1772 int iptype;
1773 __u8 *ra;
Vipul Pandya793dad92012-12-10 09:30:56 +00001774
1775 PDBG("%s qp %p cm_id %p\n", __func__, ep->com.qp, ep->com.cm_id);
1776 init_timer(&ep->timer);
1777
1778 /*
1779 * Allocate an active TID to initiate a TCP connection.
1780 */
1781 ep->atid = cxgb4_alloc_atid(ep->com.dev->rdev.lldi.tids, ep);
1782 if (ep->atid == -1) {
1783 pr_err("%s - cannot alloc atid.\n", __func__);
1784 err = -ENOMEM;
1785 goto fail2;
1786 }
1787 insert_handle(ep->com.dev, &ep->com.dev->atid_idr, ep, ep->atid);
1788
1789 /* find a route */
Vipul Pandya830662f2013-07-04 16:10:47 +05301790 if (ep->com.cm_id->local_addr.ss_family == AF_INET) {
1791 ep->dst = find_route(ep->com.dev, laddr->sin_addr.s_addr,
1792 raddr->sin_addr.s_addr, laddr->sin_port,
1793 raddr->sin_port, 0);
1794 iptype = 4;
1795 ra = (__u8 *)&raddr->sin_addr;
1796 } else {
1797 ep->dst = find_route6(ep->com.dev, laddr6->sin6_addr.s6_addr,
1798 raddr6->sin6_addr.s6_addr,
1799 laddr6->sin6_port, raddr6->sin6_port, 0,
1800 raddr6->sin6_scope_id);
1801 iptype = 6;
1802 ra = (__u8 *)&raddr6->sin6_addr;
1803 }
1804 if (!ep->dst) {
Vipul Pandya793dad92012-12-10 09:30:56 +00001805 pr_err("%s - cannot find route.\n", __func__);
1806 err = -EHOSTUNREACH;
1807 goto fail3;
1808 }
Vipul Pandya830662f2013-07-04 16:10:47 +05301809 err = import_ep(ep, iptype, ra, ep->dst, ep->com.dev, false);
1810 if (err) {
Vipul Pandya793dad92012-12-10 09:30:56 +00001811 pr_err("%s - cannot alloc l2e.\n", __func__);
Vipul Pandya793dad92012-12-10 09:30:56 +00001812 goto fail4;
1813 }
1814
1815 PDBG("%s txq_idx %u tx_chan %u smac_idx %u rss_qid %u l2t_idx %u\n",
1816 __func__, ep->txq_idx, ep->tx_chan, ep->smac_idx, ep->rss_qid,
1817 ep->l2t->idx);
1818
1819 state_set(&ep->com, CONNECTING);
1820 ep->tos = 0;
1821
1822 /* send connect request to rnic */
1823 err = send_connect(ep);
1824 if (!err)
1825 goto out;
1826
1827 cxgb4_l2t_release(ep->l2t);
1828fail4:
1829 dst_release(ep->dst);
1830fail3:
1831 remove_handle(ep->com.dev, &ep->com.dev->atid_idr, ep->atid);
1832 cxgb4_free_atid(ep->com.dev->rdev.lldi.tids, ep->atid);
1833fail2:
1834 /*
1835 * remember to send notification to upper layer.
1836 * We are in here so the upper layer is not aware that this is
1837 * re-connect attempt and so, upper layer is still waiting for
1838 * response of 1st connect request.
1839 */
1840 connect_reply_upcall(ep, -ECONNRESET);
1841 c4iw_put_ep(&ep->com);
1842out:
1843 return err;
1844}
1845
Steve Wisecfdda9d2010-04-21 15:30:06 -07001846static int act_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
1847{
1848 struct c4iw_ep *ep;
1849 struct cpl_act_open_rpl *rpl = cplhdr(skb);
1850 unsigned int atid = GET_TID_TID(GET_AOPEN_ATID(
1851 ntohl(rpl->atid_status)));
1852 struct tid_info *t = dev->rdev.lldi.tids;
1853 int status = GET_AOPEN_STATUS(ntohl(rpl->atid_status));
Vipul Pandya830662f2013-07-04 16:10:47 +05301854 struct sockaddr_in *la;
1855 struct sockaddr_in *ra;
1856 struct sockaddr_in6 *la6;
1857 struct sockaddr_in6 *ra6;
Steve Wisecfdda9d2010-04-21 15:30:06 -07001858
1859 ep = lookup_atid(t, atid);
Vipul Pandya830662f2013-07-04 16:10:47 +05301860 la = (struct sockaddr_in *)&ep->com.local_addr;
1861 ra = (struct sockaddr_in *)&ep->com.remote_addr;
1862 la6 = (struct sockaddr_in6 *)&ep->com.local_addr;
1863 ra6 = (struct sockaddr_in6 *)&ep->com.remote_addr;
Steve Wisecfdda9d2010-04-21 15:30:06 -07001864
1865 PDBG("%s ep %p atid %u status %u errno %d\n", __func__, ep, atid,
1866 status, status2errno(status));
1867
Steve Wise7a2cea22014-03-14 21:52:07 +05301868 if (is_neg_adv(status)) {
Steve Wisecfdda9d2010-04-21 15:30:06 -07001869 printk(KERN_WARNING MOD "Connection problems for atid %u\n",
1870 atid);
1871 return 0;
1872 }
1873
Vipul Pandya793dad92012-12-10 09:30:56 +00001874 set_bit(ACT_OPEN_RPL, &ep->com.history);
1875
Vipul Pandyad716a2a2012-05-18 15:29:31 +05301876 /*
1877 * Log interesting failures.
1878 */
1879 switch (status) {
1880 case CPL_ERR_CONN_RESET:
1881 case CPL_ERR_CONN_TIMEDOUT:
1882 break;
Vipul Pandya5be78ee2012-12-10 09:30:54 +00001883 case CPL_ERR_TCAM_FULL:
Vipul Pandya830662f2013-07-04 16:10:47 +05301884 mutex_lock(&dev->rdev.stats.lock);
Vipul Pandya3b174d92013-03-14 05:09:03 +00001885 dev->rdev.stats.tcam_full++;
Vipul Pandya830662f2013-07-04 16:10:47 +05301886 mutex_unlock(&dev->rdev.stats.lock);
1887 if (ep->com.local_addr.ss_family == AF_INET &&
1888 dev->rdev.lldi.enable_fw_ofld_conn) {
Vipul Pandya793dad92012-12-10 09:30:56 +00001889 send_fw_act_open_req(ep,
1890 GET_TID_TID(GET_AOPEN_ATID(
1891 ntohl(rpl->atid_status))));
1892 return 0;
1893 }
1894 break;
1895 case CPL_ERR_CONN_EXIST:
1896 if (ep->retry_count++ < ACT_OPEN_RETRY_COUNT) {
1897 set_bit(ACT_RETRY_INUSE, &ep->com.history);
1898 remove_handle(ep->com.dev, &ep->com.dev->atid_idr,
1899 atid);
1900 cxgb4_free_atid(t, atid);
1901 dst_release(ep->dst);
1902 cxgb4_l2t_release(ep->l2t);
1903 c4iw_reconnect(ep);
1904 return 0;
1905 }
Vipul Pandya5be78ee2012-12-10 09:30:54 +00001906 break;
Vipul Pandyad716a2a2012-05-18 15:29:31 +05301907 default:
Vipul Pandya830662f2013-07-04 16:10:47 +05301908 if (ep->com.local_addr.ss_family == AF_INET) {
1909 pr_info("Active open failure - atid %u status %u errno %d %pI4:%u->%pI4:%u\n",
1910 atid, status, status2errno(status),
1911 &la->sin_addr.s_addr, ntohs(la->sin_port),
1912 &ra->sin_addr.s_addr, ntohs(ra->sin_port));
1913 } else {
1914 pr_info("Active open failure - atid %u status %u errno %d %pI6:%u->%pI6:%u\n",
1915 atid, status, status2errno(status),
1916 la6->sin6_addr.s6_addr, ntohs(la6->sin6_port),
1917 ra6->sin6_addr.s6_addr, ntohs(ra6->sin6_port));
1918 }
Vipul Pandyad716a2a2012-05-18 15:29:31 +05301919 break;
1920 }
1921
Steve Wisecfdda9d2010-04-21 15:30:06 -07001922 connect_reply_upcall(ep, status2errno(status));
1923 state_set(&ep->com, DEAD);
1924
1925 if (status && act_open_has_tid(status))
1926 cxgb4_remove_tid(ep->com.dev->rdev.lldi.tids, 0, GET_TID(rpl));
1927
Vipul Pandya793dad92012-12-10 09:30:56 +00001928 remove_handle(ep->com.dev, &ep->com.dev->atid_idr, atid);
Steve Wisecfdda9d2010-04-21 15:30:06 -07001929 cxgb4_free_atid(t, atid);
1930 dst_release(ep->dst);
1931 cxgb4_l2t_release(ep->l2t);
1932 c4iw_put_ep(&ep->com);
1933
1934 return 0;
1935}
1936
1937static int pass_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
1938{
1939 struct cpl_pass_open_rpl *rpl = cplhdr(skb);
1940 struct tid_info *t = dev->rdev.lldi.tids;
1941 unsigned int stid = GET_TID(rpl);
1942 struct c4iw_listen_ep *ep = lookup_stid(t, stid);
1943
1944 if (!ep) {
Vipul Pandya1cab7752012-12-10 09:30:55 +00001945 PDBG("%s stid %d lookup failure!\n", __func__, stid);
1946 goto out;
Steve Wisecfdda9d2010-04-21 15:30:06 -07001947 }
1948 PDBG("%s ep %p status %d error %d\n", __func__, ep,
1949 rpl->status, status2errno(rpl->status));
Steve Wised9594d92011-05-09 22:06:22 -07001950 c4iw_wake_up(&ep->com.wr_wait, status2errno(rpl->status));
Steve Wisecfdda9d2010-04-21 15:30:06 -07001951
Vipul Pandya1cab7752012-12-10 09:30:55 +00001952out:
Steve Wisecfdda9d2010-04-21 15:30:06 -07001953 return 0;
1954}
1955
Steve Wisecfdda9d2010-04-21 15:30:06 -07001956static int close_listsrv_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
1957{
1958 struct cpl_close_listsvr_rpl *rpl = cplhdr(skb);
1959 struct tid_info *t = dev->rdev.lldi.tids;
1960 unsigned int stid = GET_TID(rpl);
1961 struct c4iw_listen_ep *ep = lookup_stid(t, stid);
1962
1963 PDBG("%s ep %p\n", __func__, ep);
Steve Wised9594d92011-05-09 22:06:22 -07001964 c4iw_wake_up(&ep->com.wr_wait, status2errno(rpl->status));
Steve Wisecfdda9d2010-04-21 15:30:06 -07001965 return 0;
1966}
1967
Vipul Pandya830662f2013-07-04 16:10:47 +05301968static void accept_cr(struct c4iw_ep *ep, struct sk_buff *skb,
Steve Wisecfdda9d2010-04-21 15:30:06 -07001969 struct cpl_pass_accept_req *req)
1970{
1971 struct cpl_pass_accept_rpl *rpl;
1972 unsigned int mtu_idx;
1973 u64 opt0;
1974 u32 opt2;
1975 int wscale;
1976
1977 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
1978 BUG_ON(skb_cloned(skb));
1979 skb_trim(skb, sizeof(*rpl));
1980 skb_get(skb);
1981 cxgb4_best_mtu(ep->com.dev->rdev.lldi.mtus, ep->mtu, &mtu_idx);
1982 wscale = compute_wscale(rcv_win);
Vipul Pandya5be78ee2012-12-10 09:30:54 +00001983 opt0 = (nocong ? NO_CONG(1) : 0) |
1984 KEEP_ALIVE(1) |
Steve Wiseba6d3922010-06-23 15:46:49 +00001985 DELACK(1) |
Steve Wisecfdda9d2010-04-21 15:30:06 -07001986 WND_SCALE(wscale) |
1987 MSS_IDX(mtu_idx) |
1988 L2T_IDX(ep->l2t->idx) |
1989 TX_CHAN(ep->tx_chan) |
1990 SMAC_SEL(ep->smac_idx) |
Vipul Pandya5be78ee2012-12-10 09:30:54 +00001991 DSCP(ep->tos >> 2) |
Steve Wiseb48f3b92011-03-11 22:30:21 +00001992 ULP_MODE(ULP_MODE_TCPDDP) |
Steve Wisecfdda9d2010-04-21 15:30:06 -07001993 RCV_BUFSIZ(rcv_win>>10);
1994 opt2 = RX_CHANNEL(0) |
1995 RSS_QUEUE_VALID | RSS_QUEUE(ep->rss_qid);
1996
1997 if (enable_tcp_timestamps && req->tcpopt.tstamp)
1998 opt2 |= TSTAMPS_EN(1);
1999 if (enable_tcp_sack && req->tcpopt.sack)
2000 opt2 |= SACK_EN(1);
2001 if (wscale && enable_tcp_window_scaling)
2002 opt2 |= WND_SCALE_EN(1);
Vipul Pandya5be78ee2012-12-10 09:30:54 +00002003 if (enable_ecn) {
2004 const struct tcphdr *tcph;
2005 u32 hlen = ntohl(req->hdr_len);
2006
2007 tcph = (const void *)(req + 1) + G_ETH_HDR_LEN(hlen) +
2008 G_IP_HDR_LEN(hlen);
2009 if (tcph->ece && tcph->cwr)
2010 opt2 |= CCTRL_ECN(1);
2011 }
Steve Wisecfdda9d2010-04-21 15:30:06 -07002012
2013 rpl = cplhdr(skb);
2014 INIT_TP_WR(rpl, ep->hwtid);
2015 OPCODE_TID(rpl) = cpu_to_be32(MK_OPCODE_TID(CPL_PASS_ACCEPT_RPL,
2016 ep->hwtid));
2017 rpl->opt0 = cpu_to_be64(opt0);
2018 rpl->opt2 = cpu_to_be32(opt2);
Steve Wised4f1a5c2010-07-23 19:12:32 +00002019 set_wr_txq(skb, CPL_PRIORITY_SETUP, ep->ctrlq_idx);
Steve Wiseb38a0ad2013-08-06 21:04:37 +05302020 t4_set_arp_err_handler(skb, NULL, arp_failure_discard);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002021 c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t);
2022
2023 return;
2024}
2025
Vipul Pandya830662f2013-07-04 16:10:47 +05302026static void reject_cr(struct c4iw_dev *dev, u32 hwtid, struct sk_buff *skb)
Steve Wisecfdda9d2010-04-21 15:30:06 -07002027{
Vipul Pandya830662f2013-07-04 16:10:47 +05302028 PDBG("%s c4iw_dev %p tid %u\n", __func__, dev, hwtid);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002029 BUG_ON(skb_cloned(skb));
2030 skb_trim(skb, sizeof(struct cpl_tid_release));
2031 skb_get(skb);
2032 release_tid(&dev->rdev, hwtid, skb);
2033 return;
2034}
2035
Vipul Pandya830662f2013-07-04 16:10:47 +05302036static void get_4tuple(struct cpl_pass_accept_req *req, int *iptype,
2037 __u8 *local_ip, __u8 *peer_ip,
Steve Wisecfdda9d2010-04-21 15:30:06 -07002038 __be16 *local_port, __be16 *peer_port)
2039{
2040 int eth_len = G_ETH_HDR_LEN(be32_to_cpu(req->hdr_len));
2041 int ip_len = G_IP_HDR_LEN(be32_to_cpu(req->hdr_len));
2042 struct iphdr *ip = (struct iphdr *)((u8 *)(req + 1) + eth_len);
Vipul Pandya830662f2013-07-04 16:10:47 +05302043 struct ipv6hdr *ip6 = (struct ipv6hdr *)((u8 *)(req + 1) + eth_len);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002044 struct tcphdr *tcp = (struct tcphdr *)
2045 ((u8 *)(req + 1) + eth_len + ip_len);
2046
Vipul Pandya830662f2013-07-04 16:10:47 +05302047 if (ip->version == 4) {
2048 PDBG("%s saddr 0x%x daddr 0x%x sport %u dport %u\n", __func__,
2049 ntohl(ip->saddr), ntohl(ip->daddr), ntohs(tcp->source),
2050 ntohs(tcp->dest));
2051 *iptype = 4;
2052 memcpy(peer_ip, &ip->saddr, 4);
2053 memcpy(local_ip, &ip->daddr, 4);
2054 } else {
2055 PDBG("%s saddr %pI6 daddr %pI6 sport %u dport %u\n", __func__,
2056 ip6->saddr.s6_addr, ip6->daddr.s6_addr, ntohs(tcp->source),
2057 ntohs(tcp->dest));
2058 *iptype = 6;
2059 memcpy(peer_ip, ip6->saddr.s6_addr, 16);
2060 memcpy(local_ip, ip6->daddr.s6_addr, 16);
2061 }
Steve Wisecfdda9d2010-04-21 15:30:06 -07002062 *peer_port = tcp->source;
2063 *local_port = tcp->dest;
2064
2065 return;
2066}
2067
2068static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb)
2069{
Vipul Pandya793dad92012-12-10 09:30:56 +00002070 struct c4iw_ep *child_ep = NULL, *parent_ep;
Steve Wisecfdda9d2010-04-21 15:30:06 -07002071 struct cpl_pass_accept_req *req = cplhdr(skb);
2072 unsigned int stid = GET_POPEN_TID(ntohl(req->tos_stid));
2073 struct tid_info *t = dev->rdev.lldi.tids;
2074 unsigned int hwtid = GET_TID(req);
2075 struct dst_entry *dst;
Vipul Pandya830662f2013-07-04 16:10:47 +05302076 __u8 local_ip[16], peer_ip[16];
Steve Wisecfdda9d2010-04-21 15:30:06 -07002077 __be16 local_port, peer_port;
David Miller3786cf12011-12-02 16:52:31 +00002078 int err;
Vipul Pandya1cab7752012-12-10 09:30:55 +00002079 u16 peer_mss = ntohs(req->tcpopt.mss);
Vipul Pandya830662f2013-07-04 16:10:47 +05302080 int iptype;
Steve Wisecfdda9d2010-04-21 15:30:06 -07002081
2082 parent_ep = lookup_stid(t, stid);
Vipul Pandya1cab7752012-12-10 09:30:55 +00002083 if (!parent_ep) {
2084 PDBG("%s connect request on invalid stid %d\n", __func__, stid);
2085 goto reject;
2086 }
Vipul Pandya1cab7752012-12-10 09:30:55 +00002087
Steve Wisecfdda9d2010-04-21 15:30:06 -07002088 if (state_read(&parent_ep->com) != LISTEN) {
2089 printk(KERN_ERR "%s - listening ep not in LISTEN\n",
2090 __func__);
2091 goto reject;
2092 }
2093
Vipul Pandya830662f2013-07-04 16:10:47 +05302094 get_4tuple(req, &iptype, local_ip, peer_ip, &local_port, &peer_port);
2095
Steve Wisecfdda9d2010-04-21 15:30:06 -07002096 /* Find output route */
Vipul Pandya830662f2013-07-04 16:10:47 +05302097 if (iptype == 4) {
2098 PDBG("%s parent ep %p hwtid %u laddr %pI4 raddr %pI4 lport %d rport %d peer_mss %d\n"
2099 , __func__, parent_ep, hwtid,
2100 local_ip, peer_ip, ntohs(local_port),
2101 ntohs(peer_port), peer_mss);
2102 dst = find_route(dev, *(__be32 *)local_ip, *(__be32 *)peer_ip,
2103 local_port, peer_port,
2104 GET_POPEN_TOS(ntohl(req->tos_stid)));
2105 } else {
2106 PDBG("%s parent ep %p hwtid %u laddr %pI6 raddr %pI6 lport %d rport %d peer_mss %d\n"
2107 , __func__, parent_ep, hwtid,
2108 local_ip, peer_ip, ntohs(local_port),
2109 ntohs(peer_port), peer_mss);
2110 dst = find_route6(dev, local_ip, peer_ip, local_port, peer_port,
2111 PASS_OPEN_TOS(ntohl(req->tos_stid)),
2112 ((struct sockaddr_in6 *)
2113 &parent_ep->com.local_addr)->sin6_scope_id);
2114 }
2115 if (!dst) {
Steve Wisecfdda9d2010-04-21 15:30:06 -07002116 printk(KERN_ERR MOD "%s - failed to find dst entry!\n",
2117 __func__);
2118 goto reject;
2119 }
Steve Wisecfdda9d2010-04-21 15:30:06 -07002120
2121 child_ep = alloc_ep(sizeof(*child_ep), GFP_KERNEL);
2122 if (!child_ep) {
2123 printk(KERN_ERR MOD "%s - failed to allocate ep entry!\n",
2124 __func__);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002125 dst_release(dst);
2126 goto reject;
2127 }
David Miller3786cf12011-12-02 16:52:31 +00002128
Vipul Pandya830662f2013-07-04 16:10:47 +05302129 err = import_ep(child_ep, iptype, peer_ip, dst, dev, false);
David Miller3786cf12011-12-02 16:52:31 +00002130 if (err) {
2131 printk(KERN_ERR MOD "%s - failed to allocate l2t entry!\n",
2132 __func__);
2133 dst_release(dst);
2134 kfree(child_ep);
2135 goto reject;
2136 }
2137
Vipul Pandya1cab7752012-12-10 09:30:55 +00002138 if (peer_mss && child_ep->mtu > (peer_mss + 40))
2139 child_ep->mtu = peer_mss + 40;
2140
Steve Wisecfdda9d2010-04-21 15:30:06 -07002141 state_set(&child_ep->com, CONNECTING);
2142 child_ep->com.dev = dev;
2143 child_ep->com.cm_id = NULL;
Vipul Pandya830662f2013-07-04 16:10:47 +05302144 if (iptype == 4) {
2145 struct sockaddr_in *sin = (struct sockaddr_in *)
2146 &child_ep->com.local_addr;
2147 sin->sin_family = PF_INET;
2148 sin->sin_port = local_port;
2149 sin->sin_addr.s_addr = *(__be32 *)local_ip;
2150 sin = (struct sockaddr_in *)&child_ep->com.remote_addr;
2151 sin->sin_family = PF_INET;
2152 sin->sin_port = peer_port;
2153 sin->sin_addr.s_addr = *(__be32 *)peer_ip;
2154 } else {
2155 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)
2156 &child_ep->com.local_addr;
2157 sin6->sin6_family = PF_INET6;
2158 sin6->sin6_port = local_port;
2159 memcpy(sin6->sin6_addr.s6_addr, local_ip, 16);
2160 sin6 = (struct sockaddr_in6 *)&child_ep->com.remote_addr;
2161 sin6->sin6_family = PF_INET6;
2162 sin6->sin6_port = peer_port;
2163 memcpy(sin6->sin6_addr.s6_addr, peer_ip, 16);
2164 }
Steve Wisecfdda9d2010-04-21 15:30:06 -07002165 c4iw_get_ep(&parent_ep->com);
2166 child_ep->parent_ep = parent_ep;
2167 child_ep->tos = GET_POPEN_TOS(ntohl(req->tos_stid));
Steve Wisecfdda9d2010-04-21 15:30:06 -07002168 child_ep->dst = dst;
2169 child_ep->hwtid = hwtid;
Steve Wisecfdda9d2010-04-21 15:30:06 -07002170
2171 PDBG("%s tx_chan %u smac_idx %u rss_qid %u\n", __func__,
David Miller3786cf12011-12-02 16:52:31 +00002172 child_ep->tx_chan, child_ep->smac_idx, child_ep->rss_qid);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002173
2174 init_timer(&child_ep->timer);
2175 cxgb4_insert_tid(t, child_ep, hwtid);
Vipul Pandyab3de6cf2013-01-07 13:11:59 +00002176 insert_handle(dev, &dev->hwtid_idr, child_ep, child_ep->hwtid);
Vipul Pandya830662f2013-07-04 16:10:47 +05302177 accept_cr(child_ep, skb, req);
Vipul Pandya793dad92012-12-10 09:30:56 +00002178 set_bit(PASS_ACCEPT_REQ, &child_ep->com.history);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002179 goto out;
2180reject:
Vipul Pandya830662f2013-07-04 16:10:47 +05302181 reject_cr(dev, hwtid, skb);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002182out:
2183 return 0;
2184}
2185
2186static int pass_establish(struct c4iw_dev *dev, struct sk_buff *skb)
2187{
2188 struct c4iw_ep *ep;
2189 struct cpl_pass_establish *req = cplhdr(skb);
2190 struct tid_info *t = dev->rdev.lldi.tids;
2191 unsigned int tid = GET_TID(req);
2192
2193 ep = lookup_tid(t, tid);
2194 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
2195 ep->snd_seq = be32_to_cpu(req->snd_isn);
2196 ep->rcv_seq = be32_to_cpu(req->rcv_isn);
2197
Vipul Pandya1cab7752012-12-10 09:30:55 +00002198 PDBG("%s ep %p hwtid %u tcp_opt 0x%02x\n", __func__, ep, tid,
2199 ntohs(req->tcp_opt));
2200
Steve Wisecfdda9d2010-04-21 15:30:06 -07002201 set_emss(ep, ntohs(req->tcp_opt));
2202
2203 dst_confirm(ep->dst);
2204 state_set(&ep->com, MPA_REQ_WAIT);
2205 start_ep_timer(ep);
2206 send_flowc(ep, skb);
Vipul Pandya793dad92012-12-10 09:30:56 +00002207 set_bit(PASS_ESTAB, &ep->com.history);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002208
2209 return 0;
2210}
2211
2212static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb)
2213{
2214 struct cpl_peer_close *hdr = cplhdr(skb);
2215 struct c4iw_ep *ep;
2216 struct c4iw_qp_attributes attrs;
Steve Wisecfdda9d2010-04-21 15:30:06 -07002217 int disconnect = 1;
2218 int release = 0;
Steve Wisecfdda9d2010-04-21 15:30:06 -07002219 struct tid_info *t = dev->rdev.lldi.tids;
2220 unsigned int tid = GET_TID(hdr);
Steve Wise8da7e7a2011-06-14 20:59:27 +00002221 int ret;
Steve Wisecfdda9d2010-04-21 15:30:06 -07002222
2223 ep = lookup_tid(t, tid);
2224 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
2225 dst_confirm(ep->dst);
2226
Vipul Pandya793dad92012-12-10 09:30:56 +00002227 set_bit(PEER_CLOSE, &ep->com.history);
Steve Wise2f5b48c2010-09-10 11:15:36 -05002228 mutex_lock(&ep->com.mutex);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002229 switch (ep->com.state) {
2230 case MPA_REQ_WAIT:
2231 __state_set(&ep->com, CLOSING);
2232 break;
2233 case MPA_REQ_SENT:
2234 __state_set(&ep->com, CLOSING);
2235 connect_reply_upcall(ep, -ECONNRESET);
2236 break;
2237 case MPA_REQ_RCVD:
2238
2239 /*
2240 * We're gonna mark this puppy DEAD, but keep
2241 * the reference on it until the ULP accepts or
2242 * rejects the CR. Also wake up anyone waiting
2243 * in rdma connection migration (see c4iw_accept_cr()).
2244 */
2245 __state_set(&ep->com, CLOSING);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002246 PDBG("waking up ep %p tid %u\n", ep, ep->hwtid);
Steve Wised9594d92011-05-09 22:06:22 -07002247 c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002248 break;
2249 case MPA_REP_SENT:
2250 __state_set(&ep->com, CLOSING);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002251 PDBG("waking up ep %p tid %u\n", ep, ep->hwtid);
Steve Wised9594d92011-05-09 22:06:22 -07002252 c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002253 break;
2254 case FPDU_MODE:
Steve Wiseca5a2202010-07-23 19:12:37 +00002255 start_ep_timer(ep);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002256 __state_set(&ep->com, CLOSING);
Steve Wise30c95c22011-05-09 22:06:22 -07002257 attrs.next_state = C4IW_QP_STATE_CLOSING;
Steve Wise8da7e7a2011-06-14 20:59:27 +00002258 ret = c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,
Steve Wise30c95c22011-05-09 22:06:22 -07002259 C4IW_QP_ATTR_NEXT_STATE, &attrs, 1);
Steve Wise8da7e7a2011-06-14 20:59:27 +00002260 if (ret != -ECONNRESET) {
2261 peer_close_upcall(ep);
2262 disconnect = 1;
2263 }
Steve Wisecfdda9d2010-04-21 15:30:06 -07002264 break;
2265 case ABORTING:
2266 disconnect = 0;
2267 break;
2268 case CLOSING:
2269 __state_set(&ep->com, MORIBUND);
2270 disconnect = 0;
2271 break;
2272 case MORIBUND:
Steve Wiseb33bd0c2014-04-09 09:38:25 -05002273 (void)stop_ep_timer(ep);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002274 if (ep->com.cm_id && ep->com.qp) {
2275 attrs.next_state = C4IW_QP_STATE_IDLE;
2276 c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,
2277 C4IW_QP_ATTR_NEXT_STATE, &attrs, 1);
2278 }
Steve Wisebe13b2d2014-03-21 20:40:33 +05302279 close_complete_upcall(ep, 0);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002280 __state_set(&ep->com, DEAD);
2281 release = 1;
2282 disconnect = 0;
2283 break;
2284 case DEAD:
2285 disconnect = 0;
2286 break;
2287 default:
2288 BUG_ON(1);
2289 }
Steve Wise2f5b48c2010-09-10 11:15:36 -05002290 mutex_unlock(&ep->com.mutex);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002291 if (disconnect)
2292 c4iw_ep_disconnect(ep, 0, GFP_KERNEL);
2293 if (release)
2294 release_ep_resources(ep);
2295 return 0;
2296}
2297
Steve Wisecfdda9d2010-04-21 15:30:06 -07002298static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb)
2299{
2300 struct cpl_abort_req_rss *req = cplhdr(skb);
2301 struct c4iw_ep *ep;
2302 struct cpl_abort_rpl *rpl;
2303 struct sk_buff *rpl_skb;
2304 struct c4iw_qp_attributes attrs;
2305 int ret;
2306 int release = 0;
Steve Wisecfdda9d2010-04-21 15:30:06 -07002307 struct tid_info *t = dev->rdev.lldi.tids;
2308 unsigned int tid = GET_TID(req);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002309
2310 ep = lookup_tid(t, tid);
Steve Wise7a2cea22014-03-14 21:52:07 +05302311 if (is_neg_adv(req->status)) {
Steve Wisecfdda9d2010-04-21 15:30:06 -07002312 PDBG("%s neg_adv_abort ep %p tid %u\n", __func__, ep,
2313 ep->hwtid);
2314 return 0;
2315 }
Steve Wisecfdda9d2010-04-21 15:30:06 -07002316 PDBG("%s ep %p tid %u state %u\n", __func__, ep, ep->hwtid,
2317 ep->com.state);
Vipul Pandya793dad92012-12-10 09:30:56 +00002318 set_bit(PEER_ABORT, &ep->com.history);
Steve Wise2f5b48c2010-09-10 11:15:36 -05002319
2320 /*
2321 * Wake up any threads in rdma_init() or rdma_fini().
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +05302322 * However, this is not needed if com state is just
2323 * MPA_REQ_SENT
Steve Wise2f5b48c2010-09-10 11:15:36 -05002324 */
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +05302325 if (ep->com.state != MPA_REQ_SENT)
2326 c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET);
Steve Wise2f5b48c2010-09-10 11:15:36 -05002327
2328 mutex_lock(&ep->com.mutex);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002329 switch (ep->com.state) {
2330 case CONNECTING:
2331 break;
2332 case MPA_REQ_WAIT:
Steve Wiseb33bd0c2014-04-09 09:38:25 -05002333 (void)stop_ep_timer(ep);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002334 break;
2335 case MPA_REQ_SENT:
Steve Wiseb33bd0c2014-04-09 09:38:25 -05002336 (void)stop_ep_timer(ep);
Vipul Pandyafe7e0a42013-01-07 13:11:57 +00002337 if (mpa_rev == 1 || (mpa_rev == 2 && ep->tried_with_mpa_v1))
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +05302338 connect_reply_upcall(ep, -ECONNRESET);
2339 else {
2340 /*
2341 * we just don't send notification upwards because we
2342 * want to retry with mpa_v1 without upper layers even
2343 * knowing it.
2344 *
2345 * do some housekeeping so as to re-initiate the
2346 * connection
2347 */
2348 PDBG("%s: mpa_rev=%d. Retrying with mpav1\n", __func__,
2349 mpa_rev);
2350 ep->retry_with_mpa_v1 = 1;
2351 }
Steve Wisecfdda9d2010-04-21 15:30:06 -07002352 break;
2353 case MPA_REP_SENT:
Steve Wisecfdda9d2010-04-21 15:30:06 -07002354 break;
2355 case MPA_REQ_RCVD:
Steve Wisecfdda9d2010-04-21 15:30:06 -07002356 break;
2357 case MORIBUND:
2358 case CLOSING:
Steve Wiseca5a2202010-07-23 19:12:37 +00002359 stop_ep_timer(ep);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002360 /*FALLTHROUGH*/
2361 case FPDU_MODE:
2362 if (ep->com.cm_id && ep->com.qp) {
2363 attrs.next_state = C4IW_QP_STATE_ERROR;
2364 ret = c4iw_modify_qp(ep->com.qp->rhp,
2365 ep->com.qp, C4IW_QP_ATTR_NEXT_STATE,
2366 &attrs, 1);
2367 if (ret)
2368 printk(KERN_ERR MOD
2369 "%s - qp <- error failed!\n",
2370 __func__);
2371 }
2372 peer_abort_upcall(ep);
2373 break;
2374 case ABORTING:
2375 break;
2376 case DEAD:
2377 PDBG("%s PEER_ABORT IN DEAD STATE!!!!\n", __func__);
Steve Wise2f5b48c2010-09-10 11:15:36 -05002378 mutex_unlock(&ep->com.mutex);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002379 return 0;
2380 default:
2381 BUG_ON(1);
2382 break;
2383 }
2384 dst_confirm(ep->dst);
2385 if (ep->com.state != ABORTING) {
2386 __state_set(&ep->com, DEAD);
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +05302387 /* we don't release if we want to retry with mpa_v1 */
2388 if (!ep->retry_with_mpa_v1)
2389 release = 1;
Steve Wisecfdda9d2010-04-21 15:30:06 -07002390 }
Steve Wise2f5b48c2010-09-10 11:15:36 -05002391 mutex_unlock(&ep->com.mutex);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002392
2393 rpl_skb = get_skb(skb, sizeof(*rpl), GFP_KERNEL);
2394 if (!rpl_skb) {
2395 printk(KERN_ERR MOD "%s - cannot allocate skb!\n",
2396 __func__);
2397 release = 1;
2398 goto out;
2399 }
2400 set_wr_txq(skb, CPL_PRIORITY_DATA, ep->txq_idx);
2401 rpl = (struct cpl_abort_rpl *) skb_put(rpl_skb, sizeof(*rpl));
2402 INIT_TP_WR(rpl, ep->hwtid);
2403 OPCODE_TID(rpl) = cpu_to_be32(MK_OPCODE_TID(CPL_ABORT_RPL, ep->hwtid));
2404 rpl->cmd = CPL_ABORT_NO_RST;
2405 c4iw_ofld_send(&ep->com.dev->rdev, rpl_skb);
2406out:
Steve Wisecfdda9d2010-04-21 15:30:06 -07002407 if (release)
2408 release_ep_resources(ep);
Vipul Pandyafe7e0a42013-01-07 13:11:57 +00002409 else if (ep->retry_with_mpa_v1) {
2410 remove_handle(ep->com.dev, &ep->com.dev->hwtid_idr, ep->hwtid);
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +05302411 cxgb4_remove_tid(ep->com.dev->rdev.lldi.tids, 0, ep->hwtid);
2412 dst_release(ep->dst);
2413 cxgb4_l2t_release(ep->l2t);
2414 c4iw_reconnect(ep);
2415 }
2416
Steve Wisecfdda9d2010-04-21 15:30:06 -07002417 return 0;
2418}
2419
2420static int close_con_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
2421{
2422 struct c4iw_ep *ep;
2423 struct c4iw_qp_attributes attrs;
2424 struct cpl_close_con_rpl *rpl = cplhdr(skb);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002425 int release = 0;
2426 struct tid_info *t = dev->rdev.lldi.tids;
2427 unsigned int tid = GET_TID(rpl);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002428
2429 ep = lookup_tid(t, tid);
2430
2431 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
2432 BUG_ON(!ep);
2433
2434 /* The cm_id may be null if we failed to connect */
Steve Wise2f5b48c2010-09-10 11:15:36 -05002435 mutex_lock(&ep->com.mutex);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002436 switch (ep->com.state) {
2437 case CLOSING:
2438 __state_set(&ep->com, MORIBUND);
2439 break;
2440 case MORIBUND:
Steve Wiseb33bd0c2014-04-09 09:38:25 -05002441 (void)stop_ep_timer(ep);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002442 if ((ep->com.cm_id) && (ep->com.qp)) {
2443 attrs.next_state = C4IW_QP_STATE_IDLE;
2444 c4iw_modify_qp(ep->com.qp->rhp,
2445 ep->com.qp,
2446 C4IW_QP_ATTR_NEXT_STATE,
2447 &attrs, 1);
2448 }
Steve Wisebe13b2d2014-03-21 20:40:33 +05302449 close_complete_upcall(ep, 0);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002450 __state_set(&ep->com, DEAD);
2451 release = 1;
2452 break;
2453 case ABORTING:
2454 case DEAD:
2455 break;
2456 default:
2457 BUG_ON(1);
2458 break;
2459 }
Steve Wise2f5b48c2010-09-10 11:15:36 -05002460 mutex_unlock(&ep->com.mutex);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002461 if (release)
2462 release_ep_resources(ep);
2463 return 0;
2464}
2465
2466static int terminate(struct c4iw_dev *dev, struct sk_buff *skb)
2467{
Steve Wise0e42c1f2010-09-10 11:15:09 -05002468 struct cpl_rdma_terminate *rpl = cplhdr(skb);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002469 struct tid_info *t = dev->rdev.lldi.tids;
Steve Wise0e42c1f2010-09-10 11:15:09 -05002470 unsigned int tid = GET_TID(rpl);
2471 struct c4iw_ep *ep;
2472 struct c4iw_qp_attributes attrs;
Steve Wisecfdda9d2010-04-21 15:30:06 -07002473
2474 ep = lookup_tid(t, tid);
Steve Wise0e42c1f2010-09-10 11:15:09 -05002475 BUG_ON(!ep);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002476
Steve Wise30c95c22011-05-09 22:06:22 -07002477 if (ep && ep->com.qp) {
Steve Wise0e42c1f2010-09-10 11:15:09 -05002478 printk(KERN_WARNING MOD "TERM received tid %u qpid %u\n", tid,
2479 ep->com.qp->wq.sq.qid);
2480 attrs.next_state = C4IW_QP_STATE_TERMINATE;
2481 c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,
2482 C4IW_QP_ATTR_NEXT_STATE, &attrs, 1);
2483 } else
Steve Wise30c95c22011-05-09 22:06:22 -07002484 printk(KERN_WARNING MOD "TERM received tid %u no ep/qp\n", tid);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002485
Steve Wisecfdda9d2010-04-21 15:30:06 -07002486 return 0;
2487}
2488
2489/*
2490 * Upcall from the adapter indicating data has been transmitted.
2491 * For us its just the single MPA request or reply. We can now free
2492 * the skb holding the mpa message.
2493 */
2494static int fw4_ack(struct c4iw_dev *dev, struct sk_buff *skb)
2495{
2496 struct c4iw_ep *ep;
2497 struct cpl_fw4_ack *hdr = cplhdr(skb);
2498 u8 credits = hdr->credits;
2499 unsigned int tid = GET_TID(hdr);
2500 struct tid_info *t = dev->rdev.lldi.tids;
2501
2502
2503 ep = lookup_tid(t, tid);
2504 PDBG("%s ep %p tid %u credits %u\n", __func__, ep, ep->hwtid, credits);
2505 if (credits == 0) {
Joe Perchesaa1ad262010-10-25 19:44:22 -07002506 PDBG("%s 0 credit ack ep %p tid %u state %u\n",
2507 __func__, ep, ep->hwtid, state_read(&ep->com));
Steve Wisecfdda9d2010-04-21 15:30:06 -07002508 return 0;
2509 }
2510
2511 dst_confirm(ep->dst);
2512 if (ep->mpa_skb) {
2513 PDBG("%s last streaming msg ack ep %p tid %u state %u "
2514 "initiator %u freeing skb\n", __func__, ep, ep->hwtid,
2515 state_read(&ep->com), ep->mpa_attr.initiator ? 1 : 0);
2516 kfree_skb(ep->mpa_skb);
2517 ep->mpa_skb = NULL;
2518 }
2519 return 0;
2520}
2521
Steve Wisecfdda9d2010-04-21 15:30:06 -07002522int c4iw_reject_cr(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len)
2523{
Steve Wisea7db89e2014-03-21 20:40:35 +05302524 int err = 0;
2525 int disconnect = 0;
Steve Wisecfdda9d2010-04-21 15:30:06 -07002526 struct c4iw_ep *ep = to_ep(cm_id);
2527 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
2528
Steve Wisea7db89e2014-03-21 20:40:35 +05302529 mutex_lock(&ep->com.mutex);
2530 if (ep->com.state == DEAD) {
2531 mutex_unlock(&ep->com.mutex);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002532 c4iw_put_ep(&ep->com);
2533 return -ECONNRESET;
2534 }
Vipul Pandya793dad92012-12-10 09:30:56 +00002535 set_bit(ULP_REJECT, &ep->com.history);
Steve Wisea7db89e2014-03-21 20:40:35 +05302536 BUG_ON(ep->com.state != MPA_REQ_RCVD);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002537 if (mpa_rev == 0)
2538 abort_connection(ep, NULL, GFP_KERNEL);
2539 else {
2540 err = send_mpa_reject(ep, pdata, pdata_len);
Steve Wisea7db89e2014-03-21 20:40:35 +05302541 disconnect = 1;
Steve Wisecfdda9d2010-04-21 15:30:06 -07002542 }
Steve Wisea7db89e2014-03-21 20:40:35 +05302543 mutex_unlock(&ep->com.mutex);
2544 if (disconnect)
2545 err = c4iw_ep_disconnect(ep, 0, GFP_KERNEL);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002546 c4iw_put_ep(&ep->com);
2547 return 0;
2548}
2549
2550int c4iw_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
2551{
2552 int err;
2553 struct c4iw_qp_attributes attrs;
2554 enum c4iw_qp_attr_mask mask;
2555 struct c4iw_ep *ep = to_ep(cm_id);
2556 struct c4iw_dev *h = to_c4iw_dev(cm_id->device);
2557 struct c4iw_qp *qp = get_qhp(h, conn_param->qpn);
2558
2559 PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
Steve Wisea7db89e2014-03-21 20:40:35 +05302560
2561 mutex_lock(&ep->com.mutex);
2562 if (ep->com.state == DEAD) {
Steve Wisecfdda9d2010-04-21 15:30:06 -07002563 err = -ECONNRESET;
2564 goto err;
2565 }
2566
Steve Wisea7db89e2014-03-21 20:40:35 +05302567 BUG_ON(ep->com.state != MPA_REQ_RCVD);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002568 BUG_ON(!qp);
2569
Vipul Pandya793dad92012-12-10 09:30:56 +00002570 set_bit(ULP_ACCEPT, &ep->com.history);
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07002571 if ((conn_param->ord > c4iw_max_read_depth) ||
2572 (conn_param->ird > c4iw_max_read_depth)) {
Steve Wisecfdda9d2010-04-21 15:30:06 -07002573 abort_connection(ep, NULL, GFP_KERNEL);
2574 err = -EINVAL;
2575 goto err;
2576 }
2577
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +05302578 if (ep->mpa_attr.version == 2 && ep->mpa_attr.enhanced_rdma_conn) {
2579 if (conn_param->ord > ep->ird) {
2580 ep->ird = conn_param->ird;
2581 ep->ord = conn_param->ord;
2582 send_mpa_reject(ep, conn_param->private_data,
2583 conn_param->private_data_len);
2584 abort_connection(ep, NULL, GFP_KERNEL);
2585 err = -ENOMEM;
2586 goto err;
2587 }
2588 if (conn_param->ird > ep->ord) {
2589 if (!ep->ord)
2590 conn_param->ird = 1;
2591 else {
2592 abort_connection(ep, NULL, GFP_KERNEL);
2593 err = -ENOMEM;
2594 goto err;
2595 }
2596 }
Steve Wisecfdda9d2010-04-21 15:30:06 -07002597
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +05302598 }
Steve Wisecfdda9d2010-04-21 15:30:06 -07002599 ep->ird = conn_param->ird;
2600 ep->ord = conn_param->ord;
2601
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +05302602 if (ep->mpa_attr.version != 2)
2603 if (peer2peer && ep->ird == 0)
2604 ep->ird = 1;
Steve Wisecfdda9d2010-04-21 15:30:06 -07002605
2606 PDBG("%s %d ird %d ord %d\n", __func__, __LINE__, ep->ird, ep->ord);
2607
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +05302608 cm_id->add_ref(cm_id);
2609 ep->com.cm_id = cm_id;
2610 ep->com.qp = qp;
Vipul Pandya325abea2013-01-07 13:11:53 +00002611 ref_qp(ep);
Kumar Sanghvid2fe99e2011-09-25 20:17:44 +05302612
Steve Wisecfdda9d2010-04-21 15:30:06 -07002613 /* bind QP to EP and move to RTS */
2614 attrs.mpa_attr = ep->mpa_attr;
2615 attrs.max_ird = ep->ird;
2616 attrs.max_ord = ep->ord;
2617 attrs.llp_stream_handle = ep;
2618 attrs.next_state = C4IW_QP_STATE_RTS;
2619
2620 /* bind QP and TID with INIT_WR */
2621 mask = C4IW_QP_ATTR_NEXT_STATE |
2622 C4IW_QP_ATTR_LLP_STREAM_HANDLE |
2623 C4IW_QP_ATTR_MPA_ATTR |
2624 C4IW_QP_ATTR_MAX_IRD |
2625 C4IW_QP_ATTR_MAX_ORD;
2626
2627 err = c4iw_modify_qp(ep->com.qp->rhp,
2628 ep->com.qp, mask, &attrs, 1);
2629 if (err)
2630 goto err1;
2631 err = send_mpa_reply(ep, conn_param->private_data,
2632 conn_param->private_data_len);
2633 if (err)
2634 goto err1;
2635
Steve Wisea7db89e2014-03-21 20:40:35 +05302636 __state_set(&ep->com, FPDU_MODE);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002637 established_upcall(ep);
Steve Wisea7db89e2014-03-21 20:40:35 +05302638 mutex_unlock(&ep->com.mutex);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002639 c4iw_put_ep(&ep->com);
2640 return 0;
2641err1:
2642 ep->com.cm_id = NULL;
Steve Wisecfdda9d2010-04-21 15:30:06 -07002643 cm_id->rem_ref(cm_id);
2644err:
Steve Wisea7db89e2014-03-21 20:40:35 +05302645 mutex_unlock(&ep->com.mutex);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002646 c4iw_put_ep(&ep->com);
2647 return err;
2648}
2649
Vipul Pandya830662f2013-07-04 16:10:47 +05302650static int pick_local_ipaddrs(struct c4iw_dev *dev, struct iw_cm_id *cm_id)
2651{
2652 struct in_device *ind;
2653 int found = 0;
2654 struct sockaddr_in *laddr = (struct sockaddr_in *)&cm_id->local_addr;
2655 struct sockaddr_in *raddr = (struct sockaddr_in *)&cm_id->remote_addr;
2656
2657 ind = in_dev_get(dev->rdev.lldi.ports[0]);
2658 if (!ind)
2659 return -EADDRNOTAVAIL;
2660 for_primary_ifa(ind) {
2661 laddr->sin_addr.s_addr = ifa->ifa_address;
2662 raddr->sin_addr.s_addr = ifa->ifa_address;
2663 found = 1;
2664 break;
2665 }
2666 endfor_ifa(ind);
2667 in_dev_put(ind);
2668 return found ? 0 : -EADDRNOTAVAIL;
2669}
2670
2671static int get_lladdr(struct net_device *dev, struct in6_addr *addr,
2672 unsigned char banned_flags)
2673{
2674 struct inet6_dev *idev;
2675 int err = -EADDRNOTAVAIL;
2676
2677 rcu_read_lock();
2678 idev = __in6_dev_get(dev);
2679 if (idev != NULL) {
2680 struct inet6_ifaddr *ifp;
2681
2682 read_lock_bh(&idev->lock);
2683 list_for_each_entry(ifp, &idev->addr_list, if_list) {
2684 if (ifp->scope == IFA_LINK &&
2685 !(ifp->flags & banned_flags)) {
2686 memcpy(addr, &ifp->addr, 16);
2687 err = 0;
2688 break;
2689 }
2690 }
2691 read_unlock_bh(&idev->lock);
2692 }
2693 rcu_read_unlock();
2694 return err;
2695}
2696
2697static int pick_local_ip6addrs(struct c4iw_dev *dev, struct iw_cm_id *cm_id)
2698{
2699 struct in6_addr uninitialized_var(addr);
2700 struct sockaddr_in6 *la6 = (struct sockaddr_in6 *)&cm_id->local_addr;
2701 struct sockaddr_in6 *ra6 = (struct sockaddr_in6 *)&cm_id->remote_addr;
2702
2703 if (get_lladdr(dev->rdev.lldi.ports[0], &addr, IFA_F_TENTATIVE)) {
2704 memcpy(la6->sin6_addr.s6_addr, &addr, 16);
2705 memcpy(ra6->sin6_addr.s6_addr, &addr, 16);
2706 return 0;
2707 }
2708 return -EADDRNOTAVAIL;
2709}
2710
Steve Wisecfdda9d2010-04-21 15:30:06 -07002711int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
2712{
Steve Wisecfdda9d2010-04-21 15:30:06 -07002713 struct c4iw_dev *dev = to_c4iw_dev(cm_id->device);
2714 struct c4iw_ep *ep;
David Miller3786cf12011-12-02 16:52:31 +00002715 int err = 0;
Steve Wise24d44a32013-07-04 16:10:44 +05302716 struct sockaddr_in *laddr = (struct sockaddr_in *)&cm_id->local_addr;
2717 struct sockaddr_in *raddr = (struct sockaddr_in *)&cm_id->remote_addr;
Vipul Pandya830662f2013-07-04 16:10:47 +05302718 struct sockaddr_in6 *laddr6 = (struct sockaddr_in6 *)&cm_id->local_addr;
2719 struct sockaddr_in6 *raddr6 = (struct sockaddr_in6 *)
2720 &cm_id->remote_addr;
2721 __u8 *ra;
2722 int iptype;
Steve Wisecfdda9d2010-04-21 15:30:06 -07002723
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07002724 if ((conn_param->ord > c4iw_max_read_depth) ||
2725 (conn_param->ird > c4iw_max_read_depth)) {
2726 err = -EINVAL;
2727 goto out;
2728 }
Steve Wisecfdda9d2010-04-21 15:30:06 -07002729 ep = alloc_ep(sizeof(*ep), GFP_KERNEL);
2730 if (!ep) {
2731 printk(KERN_ERR MOD "%s - cannot alloc ep.\n", __func__);
2732 err = -ENOMEM;
2733 goto out;
2734 }
2735 init_timer(&ep->timer);
2736 ep->plen = conn_param->private_data_len;
2737 if (ep->plen)
2738 memcpy(ep->mpa_pkt + sizeof(struct mpa_message),
2739 conn_param->private_data, ep->plen);
2740 ep->ird = conn_param->ird;
2741 ep->ord = conn_param->ord;
2742
2743 if (peer2peer && ep->ord == 0)
2744 ep->ord = 1;
2745
2746 cm_id->add_ref(cm_id);
2747 ep->com.dev = dev;
2748 ep->com.cm_id = cm_id;
2749 ep->com.qp = get_qhp(dev, conn_param->qpn);
Vipul Pandya830662f2013-07-04 16:10:47 +05302750 if (!ep->com.qp) {
2751 PDBG("%s qpn 0x%x not found!\n", __func__, conn_param->qpn);
2752 err = -EINVAL;
2753 goto fail2;
2754 }
Vipul Pandya325abea2013-01-07 13:11:53 +00002755 ref_qp(ep);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002756 PDBG("%s qpn 0x%x qp %p cm_id %p\n", __func__, conn_param->qpn,
2757 ep->com.qp, cm_id);
2758
2759 /*
2760 * Allocate an active TID to initiate a TCP connection.
2761 */
2762 ep->atid = cxgb4_alloc_atid(dev->rdev.lldi.tids, ep);
2763 if (ep->atid == -1) {
2764 printk(KERN_ERR MOD "%s - cannot alloc atid.\n", __func__);
2765 err = -ENOMEM;
2766 goto fail2;
2767 }
Vipul Pandya793dad92012-12-10 09:30:56 +00002768 insert_handle(dev, &dev->atid_idr, ep, ep->atid);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002769
Vipul Pandya830662f2013-07-04 16:10:47 +05302770 if (cm_id->remote_addr.ss_family == AF_INET) {
2771 iptype = 4;
2772 ra = (__u8 *)&raddr->sin_addr;
Steve Wisecfdda9d2010-04-21 15:30:06 -07002773
Vipul Pandya830662f2013-07-04 16:10:47 +05302774 /*
2775 * Handle loopback requests to INADDR_ANY.
2776 */
2777 if ((__force int)raddr->sin_addr.s_addr == INADDR_ANY) {
2778 err = pick_local_ipaddrs(dev, cm_id);
2779 if (err)
2780 goto fail2;
2781 }
2782
2783 /* find a route */
2784 PDBG("%s saddr %pI4 sport 0x%x raddr %pI4 rport 0x%x\n",
2785 __func__, &laddr->sin_addr, ntohs(laddr->sin_port),
2786 ra, ntohs(raddr->sin_port));
2787 ep->dst = find_route(dev, laddr->sin_addr.s_addr,
2788 raddr->sin_addr.s_addr, laddr->sin_port,
2789 raddr->sin_port, 0);
2790 } else {
2791 iptype = 6;
2792 ra = (__u8 *)&raddr6->sin6_addr;
2793
2794 /*
2795 * Handle loopback requests to INADDR_ANY.
2796 */
2797 if (ipv6_addr_type(&raddr6->sin6_addr) == IPV6_ADDR_ANY) {
2798 err = pick_local_ip6addrs(dev, cm_id);
2799 if (err)
2800 goto fail2;
2801 }
2802
2803 /* find a route */
2804 PDBG("%s saddr %pI6 sport 0x%x raddr %pI6 rport 0x%x\n",
2805 __func__, laddr6->sin6_addr.s6_addr,
2806 ntohs(laddr6->sin6_port),
2807 raddr6->sin6_addr.s6_addr, ntohs(raddr6->sin6_port));
2808 ep->dst = find_route6(dev, laddr6->sin6_addr.s6_addr,
2809 raddr6->sin6_addr.s6_addr,
2810 laddr6->sin6_port, raddr6->sin6_port, 0,
2811 raddr6->sin6_scope_id);
2812 }
2813 if (!ep->dst) {
Steve Wisecfdda9d2010-04-21 15:30:06 -07002814 printk(KERN_ERR MOD "%s - cannot find route.\n", __func__);
2815 err = -EHOSTUNREACH;
2816 goto fail3;
2817 }
Steve Wisecfdda9d2010-04-21 15:30:06 -07002818
Vipul Pandya830662f2013-07-04 16:10:47 +05302819 err = import_ep(ep, iptype, ra, ep->dst, ep->com.dev, true);
David Miller3786cf12011-12-02 16:52:31 +00002820 if (err) {
Steve Wisecfdda9d2010-04-21 15:30:06 -07002821 printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002822 goto fail4;
2823 }
2824
2825 PDBG("%s txq_idx %u tx_chan %u smac_idx %u rss_qid %u l2t_idx %u\n",
2826 __func__, ep->txq_idx, ep->tx_chan, ep->smac_idx, ep->rss_qid,
2827 ep->l2t->idx);
2828
2829 state_set(&ep->com, CONNECTING);
2830 ep->tos = 0;
Steve Wise24d44a32013-07-04 16:10:44 +05302831 memcpy(&ep->com.local_addr, &cm_id->local_addr,
2832 sizeof(ep->com.local_addr));
2833 memcpy(&ep->com.remote_addr, &cm_id->remote_addr,
2834 sizeof(ep->com.remote_addr));
Steve Wisecfdda9d2010-04-21 15:30:06 -07002835
2836 /* send connect request to rnic */
2837 err = send_connect(ep);
2838 if (!err)
2839 goto out;
2840
2841 cxgb4_l2t_release(ep->l2t);
2842fail4:
2843 dst_release(ep->dst);
2844fail3:
Vipul Pandya793dad92012-12-10 09:30:56 +00002845 remove_handle(ep->com.dev, &ep->com.dev->atid_idr, ep->atid);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002846 cxgb4_free_atid(ep->com.dev->rdev.lldi.tids, ep->atid);
2847fail2:
2848 cm_id->rem_ref(cm_id);
2849 c4iw_put_ep(&ep->com);
2850out:
2851 return err;
2852}
2853
Vipul Pandya830662f2013-07-04 16:10:47 +05302854static int create_server6(struct c4iw_dev *dev, struct c4iw_listen_ep *ep)
2855{
2856 int err;
2857 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&ep->com.local_addr;
2858
2859 c4iw_init_wr_wait(&ep->com.wr_wait);
2860 err = cxgb4_create_server6(ep->com.dev->rdev.lldi.ports[0],
2861 ep->stid, &sin6->sin6_addr,
2862 sin6->sin6_port,
2863 ep->com.dev->rdev.lldi.rxq_ids[0]);
2864 if (!err)
2865 err = c4iw_wait_for_reply(&ep->com.dev->rdev,
2866 &ep->com.wr_wait,
2867 0, 0, __func__);
2868 if (err)
2869 pr_err("cxgb4_create_server6/filter failed err %d stid %d laddr %pI6 lport %d\n",
2870 err, ep->stid,
2871 sin6->sin6_addr.s6_addr, ntohs(sin6->sin6_port));
2872 return err;
2873}
2874
2875static int create_server4(struct c4iw_dev *dev, struct c4iw_listen_ep *ep)
2876{
2877 int err;
2878 struct sockaddr_in *sin = (struct sockaddr_in *)&ep->com.local_addr;
2879
2880 if (dev->rdev.lldi.enable_fw_ofld_conn) {
2881 do {
2882 err = cxgb4_create_server_filter(
2883 ep->com.dev->rdev.lldi.ports[0], ep->stid,
2884 sin->sin_addr.s_addr, sin->sin_port, 0,
2885 ep->com.dev->rdev.lldi.rxq_ids[0], 0, 0);
2886 if (err == -EBUSY) {
2887 set_current_state(TASK_UNINTERRUPTIBLE);
2888 schedule_timeout(usecs_to_jiffies(100));
2889 }
2890 } while (err == -EBUSY);
2891 } else {
2892 c4iw_init_wr_wait(&ep->com.wr_wait);
2893 err = cxgb4_create_server(ep->com.dev->rdev.lldi.ports[0],
2894 ep->stid, sin->sin_addr.s_addr, sin->sin_port,
2895 0, ep->com.dev->rdev.lldi.rxq_ids[0]);
2896 if (!err)
2897 err = c4iw_wait_for_reply(&ep->com.dev->rdev,
2898 &ep->com.wr_wait,
2899 0, 0, __func__);
2900 }
2901 if (err)
2902 pr_err("cxgb4_create_server/filter failed err %d stid %d laddr %pI4 lport %d\n"
2903 , err, ep->stid,
2904 &sin->sin_addr, ntohs(sin->sin_port));
2905 return err;
2906}
2907
Steve Wisecfdda9d2010-04-21 15:30:06 -07002908int c4iw_create_listen(struct iw_cm_id *cm_id, int backlog)
2909{
2910 int err = 0;
2911 struct c4iw_dev *dev = to_c4iw_dev(cm_id->device);
2912 struct c4iw_listen_ep *ep;
2913
Steve Wisecfdda9d2010-04-21 15:30:06 -07002914 might_sleep();
2915
2916 ep = alloc_ep(sizeof(*ep), GFP_KERNEL);
2917 if (!ep) {
2918 printk(KERN_ERR MOD "%s - cannot alloc ep.\n", __func__);
2919 err = -ENOMEM;
2920 goto fail1;
2921 }
2922 PDBG("%s ep %p\n", __func__, ep);
2923 cm_id->add_ref(cm_id);
2924 ep->com.cm_id = cm_id;
2925 ep->com.dev = dev;
2926 ep->backlog = backlog;
Steve Wise24d44a32013-07-04 16:10:44 +05302927 memcpy(&ep->com.local_addr, &cm_id->local_addr,
2928 sizeof(ep->com.local_addr));
Steve Wisecfdda9d2010-04-21 15:30:06 -07002929
2930 /*
2931 * Allocate a server TID.
2932 */
Kumar Sanghvi8c044692013-12-18 16:38:25 +05302933 if (dev->rdev.lldi.enable_fw_ofld_conn &&
2934 ep->com.local_addr.ss_family == AF_INET)
Vipul Pandya830662f2013-07-04 16:10:47 +05302935 ep->stid = cxgb4_alloc_sftid(dev->rdev.lldi.tids,
2936 cm_id->local_addr.ss_family, ep);
Vipul Pandya1cab7752012-12-10 09:30:55 +00002937 else
Vipul Pandya830662f2013-07-04 16:10:47 +05302938 ep->stid = cxgb4_alloc_stid(dev->rdev.lldi.tids,
2939 cm_id->local_addr.ss_family, ep);
Vipul Pandya1cab7752012-12-10 09:30:55 +00002940
Steve Wisecfdda9d2010-04-21 15:30:06 -07002941 if (ep->stid == -1) {
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07002942 printk(KERN_ERR MOD "%s - cannot alloc stid.\n", __func__);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002943 err = -ENOMEM;
2944 goto fail2;
2945 }
Vipul Pandya793dad92012-12-10 09:30:56 +00002946 insert_handle(dev, &dev->stid_idr, ep, ep->stid);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002947 state_set(&ep->com, LISTEN);
Vipul Pandya830662f2013-07-04 16:10:47 +05302948 if (ep->com.local_addr.ss_family == AF_INET)
2949 err = create_server4(dev, ep);
2950 else
2951 err = create_server6(dev, ep);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002952 if (!err) {
2953 cm_id->provider_data = ep;
2954 goto out;
2955 }
Vipul Pandya830662f2013-07-04 16:10:47 +05302956 cxgb4_free_stid(ep->com.dev->rdev.lldi.tids, ep->stid,
2957 ep->com.local_addr.ss_family);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002958fail2:
2959 cm_id->rem_ref(cm_id);
2960 c4iw_put_ep(&ep->com);
2961fail1:
2962out:
2963 return err;
2964}
2965
2966int c4iw_destroy_listen(struct iw_cm_id *cm_id)
2967{
2968 int err;
2969 struct c4iw_listen_ep *ep = to_listen_ep(cm_id);
2970
2971 PDBG("%s ep %p\n", __func__, ep);
2972
2973 might_sleep();
2974 state_set(&ep->com, DEAD);
Vipul Pandya830662f2013-07-04 16:10:47 +05302975 if (ep->com.dev->rdev.lldi.enable_fw_ofld_conn &&
2976 ep->com.local_addr.ss_family == AF_INET) {
Vipul Pandya1cab7752012-12-10 09:30:55 +00002977 err = cxgb4_remove_server_filter(
2978 ep->com.dev->rdev.lldi.ports[0], ep->stid,
2979 ep->com.dev->rdev.lldi.rxq_ids[0], 0);
2980 } else {
2981 c4iw_init_wr_wait(&ep->com.wr_wait);
Vipul Pandya830662f2013-07-04 16:10:47 +05302982 err = cxgb4_remove_server(
2983 ep->com.dev->rdev.lldi.ports[0], ep->stid,
2984 ep->com.dev->rdev.lldi.rxq_ids[0], 0);
Vipul Pandya1cab7752012-12-10 09:30:55 +00002985 if (err)
2986 goto done;
2987 err = c4iw_wait_for_reply(&ep->com.dev->rdev, &ep->com.wr_wait,
2988 0, 0, __func__);
2989 }
Vipul Pandya793dad92012-12-10 09:30:56 +00002990 remove_handle(ep->com.dev, &ep->com.dev->stid_idr, ep->stid);
Vipul Pandya830662f2013-07-04 16:10:47 +05302991 cxgb4_free_stid(ep->com.dev->rdev.lldi.tids, ep->stid,
2992 ep->com.local_addr.ss_family);
Steve Wisecfdda9d2010-04-21 15:30:06 -07002993done:
Steve Wisecfdda9d2010-04-21 15:30:06 -07002994 cm_id->rem_ref(cm_id);
2995 c4iw_put_ep(&ep->com);
2996 return err;
2997}
2998
2999int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp)
3000{
3001 int ret = 0;
Steve Wisecfdda9d2010-04-21 15:30:06 -07003002 int close = 0;
3003 int fatal = 0;
3004 struct c4iw_rdev *rdev;
Steve Wisecfdda9d2010-04-21 15:30:06 -07003005
Steve Wise2f5b48c2010-09-10 11:15:36 -05003006 mutex_lock(&ep->com.mutex);
Steve Wisecfdda9d2010-04-21 15:30:06 -07003007
3008 PDBG("%s ep %p state %s, abrupt %d\n", __func__, ep,
3009 states[ep->com.state], abrupt);
3010
3011 rdev = &ep->com.dev->rdev;
3012 if (c4iw_fatal_error(rdev)) {
3013 fatal = 1;
Steve Wisebe13b2d2014-03-21 20:40:33 +05303014 close_complete_upcall(ep, -EIO);
Steve Wisecfdda9d2010-04-21 15:30:06 -07003015 ep->com.state = DEAD;
3016 }
3017 switch (ep->com.state) {
3018 case MPA_REQ_WAIT:
3019 case MPA_REQ_SENT:
3020 case MPA_REQ_RCVD:
3021 case MPA_REP_SENT:
3022 case FPDU_MODE:
3023 close = 1;
3024 if (abrupt)
3025 ep->com.state = ABORTING;
3026 else {
3027 ep->com.state = CLOSING;
Steve Wiseca5a2202010-07-23 19:12:37 +00003028 start_ep_timer(ep);
Steve Wisecfdda9d2010-04-21 15:30:06 -07003029 }
3030 set_bit(CLOSE_SENT, &ep->com.flags);
3031 break;
3032 case CLOSING:
3033 if (!test_and_set_bit(CLOSE_SENT, &ep->com.flags)) {
3034 close = 1;
3035 if (abrupt) {
Steve Wiseb33bd0c2014-04-09 09:38:25 -05003036 (void)stop_ep_timer(ep);
Steve Wisecfdda9d2010-04-21 15:30:06 -07003037 ep->com.state = ABORTING;
3038 } else
3039 ep->com.state = MORIBUND;
3040 }
3041 break;
3042 case MORIBUND:
3043 case ABORTING:
3044 case DEAD:
3045 PDBG("%s ignoring disconnect ep %p state %u\n",
3046 __func__, ep, ep->com.state);
3047 break;
3048 default:
3049 BUG();
3050 break;
3051 }
3052
Steve Wisecfdda9d2010-04-21 15:30:06 -07003053 if (close) {
Steve Wise8da7e7a2011-06-14 20:59:27 +00003054 if (abrupt) {
Vipul Pandya793dad92012-12-10 09:30:56 +00003055 set_bit(EP_DISC_ABORT, &ep->com.history);
Steve Wisebe13b2d2014-03-21 20:40:33 +05303056 close_complete_upcall(ep, -ECONNRESET);
Steve Wise8da7e7a2011-06-14 20:59:27 +00003057 ret = send_abort(ep, NULL, gfp);
Vipul Pandya793dad92012-12-10 09:30:56 +00003058 } else {
3059 set_bit(EP_DISC_CLOSE, &ep->com.history);
Steve Wisecfdda9d2010-04-21 15:30:06 -07003060 ret = send_halfclose(ep, gfp);
Vipul Pandya793dad92012-12-10 09:30:56 +00003061 }
Steve Wisecfdda9d2010-04-21 15:30:06 -07003062 if (ret)
3063 fatal = 1;
3064 }
Steve Wise8da7e7a2011-06-14 20:59:27 +00003065 mutex_unlock(&ep->com.mutex);
Steve Wisecfdda9d2010-04-21 15:30:06 -07003066 if (fatal)
3067 release_ep_resources(ep);
3068 return ret;
3069}
3070
Vipul Pandya1cab7752012-12-10 09:30:55 +00003071static void active_ofld_conn_reply(struct c4iw_dev *dev, struct sk_buff *skb,
3072 struct cpl_fw6_msg_ofld_connection_wr_rpl *req)
3073{
3074 struct c4iw_ep *ep;
Vipul Pandya793dad92012-12-10 09:30:56 +00003075 int atid = be32_to_cpu(req->tid);
Vipul Pandya1cab7752012-12-10 09:30:55 +00003076
Vipul Pandyaef5d6352013-01-07 13:12:00 +00003077 ep = (struct c4iw_ep *)lookup_atid(dev->rdev.lldi.tids,
3078 (__force u32) req->tid);
Vipul Pandya1cab7752012-12-10 09:30:55 +00003079 if (!ep)
3080 return;
3081
3082 switch (req->retval) {
3083 case FW_ENOMEM:
Vipul Pandya793dad92012-12-10 09:30:56 +00003084 set_bit(ACT_RETRY_NOMEM, &ep->com.history);
3085 if (ep->retry_count++ < ACT_OPEN_RETRY_COUNT) {
3086 send_fw_act_open_req(ep, atid);
3087 return;
3088 }
Vipul Pandya1cab7752012-12-10 09:30:55 +00003089 case FW_EADDRINUSE:
Vipul Pandya793dad92012-12-10 09:30:56 +00003090 set_bit(ACT_RETRY_INUSE, &ep->com.history);
3091 if (ep->retry_count++ < ACT_OPEN_RETRY_COUNT) {
3092 send_fw_act_open_req(ep, atid);
3093 return;
3094 }
Vipul Pandya1cab7752012-12-10 09:30:55 +00003095 break;
3096 default:
3097 pr_info("%s unexpected ofld conn wr retval %d\n",
3098 __func__, req->retval);
3099 break;
3100 }
Vipul Pandya793dad92012-12-10 09:30:56 +00003101 pr_err("active ofld_connect_wr failure %d atid %d\n",
3102 req->retval, atid);
3103 mutex_lock(&dev->rdev.stats.lock);
3104 dev->rdev.stats.act_ofld_conn_fails++;
3105 mutex_unlock(&dev->rdev.stats.lock);
Vipul Pandya1cab7752012-12-10 09:30:55 +00003106 connect_reply_upcall(ep, status2errno(req->retval));
Vipul Pandya793dad92012-12-10 09:30:56 +00003107 state_set(&ep->com, DEAD);
3108 remove_handle(dev, &dev->atid_idr, atid);
3109 cxgb4_free_atid(dev->rdev.lldi.tids, atid);
3110 dst_release(ep->dst);
3111 cxgb4_l2t_release(ep->l2t);
3112 c4iw_put_ep(&ep->com);
Vipul Pandya1cab7752012-12-10 09:30:55 +00003113}
3114
3115static void passive_ofld_conn_reply(struct c4iw_dev *dev, struct sk_buff *skb,
3116 struct cpl_fw6_msg_ofld_connection_wr_rpl *req)
3117{
3118 struct sk_buff *rpl_skb;
3119 struct cpl_pass_accept_req *cpl;
3120 int ret;
3121
Paul Bolle710a3112013-02-05 20:51:30 +00003122 rpl_skb = (struct sk_buff *)(unsigned long)req->cookie;
Vipul Pandya1cab7752012-12-10 09:30:55 +00003123 BUG_ON(!rpl_skb);
3124 if (req->retval) {
3125 PDBG("%s passive open failure %d\n", __func__, req->retval);
Vipul Pandya793dad92012-12-10 09:30:56 +00003126 mutex_lock(&dev->rdev.stats.lock);
3127 dev->rdev.stats.pas_ofld_conn_fails++;
3128 mutex_unlock(&dev->rdev.stats.lock);
Vipul Pandya1cab7752012-12-10 09:30:55 +00003129 kfree_skb(rpl_skb);
3130 } else {
3131 cpl = (struct cpl_pass_accept_req *)cplhdr(rpl_skb);
3132 OPCODE_TID(cpl) = htonl(MK_OPCODE_TID(CPL_PASS_ACCEPT_REQ,
Vipul Pandyaef5d6352013-01-07 13:12:00 +00003133 (__force u32) htonl(
3134 (__force u32) req->tid)));
Vipul Pandya1cab7752012-12-10 09:30:55 +00003135 ret = pass_accept_req(dev, rpl_skb);
3136 if (!ret)
3137 kfree_skb(rpl_skb);
3138 }
3139 return;
3140}
3141
3142static int deferred_fw6_msg(struct c4iw_dev *dev, struct sk_buff *skb)
Steve Wise2f5b48c2010-09-10 11:15:36 -05003143{
3144 struct cpl_fw6_msg *rpl = cplhdr(skb);
Vipul Pandya1cab7752012-12-10 09:30:55 +00003145 struct cpl_fw6_msg_ofld_connection_wr_rpl *req;
3146
3147 switch (rpl->type) {
3148 case FW6_TYPE_CQE:
3149 c4iw_ev_dispatch(dev, (struct t4_cqe *)&rpl->data[0]);
3150 break;
3151 case FW6_TYPE_OFLD_CONNECTION_WR_RPL:
3152 req = (struct cpl_fw6_msg_ofld_connection_wr_rpl *)rpl->data;
3153 switch (req->t_state) {
3154 case TCP_SYN_SENT:
3155 active_ofld_conn_reply(dev, skb, req);
3156 break;
3157 case TCP_SYN_RECV:
3158 passive_ofld_conn_reply(dev, skb, req);
3159 break;
3160 default:
3161 pr_err("%s unexpected ofld conn wr state %d\n",
3162 __func__, req->t_state);
3163 break;
3164 }
3165 break;
3166 }
3167 return 0;
3168}
3169
3170static void build_cpl_pass_accept_req(struct sk_buff *skb, int stid , u8 tos)
3171{
3172 u32 l2info;
Vipul Pandyaf079af72013-03-14 05:08:58 +00003173 u16 vlantag, len, hdr_len, eth_hdr_len;
Vipul Pandya1cab7752012-12-10 09:30:55 +00003174 u8 intf;
3175 struct cpl_rx_pkt *cpl = cplhdr(skb);
3176 struct cpl_pass_accept_req *req;
3177 struct tcp_options_received tmp_opt;
Vipul Pandyaf079af72013-03-14 05:08:58 +00003178 struct c4iw_dev *dev;
Vipul Pandya1cab7752012-12-10 09:30:55 +00003179
Vipul Pandyaf079af72013-03-14 05:08:58 +00003180 dev = *((struct c4iw_dev **) (skb->cb + sizeof(void *)));
Vipul Pandya1cab7752012-12-10 09:30:55 +00003181 /* Store values from cpl_rx_pkt in temporary location. */
Vipul Pandyaef5d6352013-01-07 13:12:00 +00003182 vlantag = (__force u16) cpl->vlan;
3183 len = (__force u16) cpl->len;
3184 l2info = (__force u32) cpl->l2info;
3185 hdr_len = (__force u16) cpl->hdr_len;
Vipul Pandya1cab7752012-12-10 09:30:55 +00003186 intf = cpl->iff;
3187
3188 __skb_pull(skb, sizeof(*req) + sizeof(struct rss_header));
3189
3190 /*
3191 * We need to parse the TCP options from SYN packet.
3192 * to generate cpl_pass_accept_req.
3193 */
3194 memset(&tmp_opt, 0, sizeof(tmp_opt));
3195 tcp_clear_options(&tmp_opt);
Christoph Paasch1a2c6182013-03-17 08:23:34 +00003196 tcp_parse_options(skb, &tmp_opt, 0, NULL);
Vipul Pandya1cab7752012-12-10 09:30:55 +00003197
3198 req = (struct cpl_pass_accept_req *)__skb_push(skb, sizeof(*req));
3199 memset(req, 0, sizeof(*req));
3200 req->l2info = cpu_to_be16(V_SYN_INTF(intf) |
Vipul Pandyaef5d6352013-01-07 13:12:00 +00003201 V_SYN_MAC_IDX(G_RX_MACIDX(
3202 (__force int) htonl(l2info))) |
Vipul Pandya1cab7752012-12-10 09:30:55 +00003203 F_SYN_XACT_MATCH);
Vipul Pandyaf079af72013-03-14 05:08:58 +00003204 eth_hdr_len = is_t4(dev->rdev.lldi.adapter_type) ?
3205 G_RX_ETHHDR_LEN((__force int) htonl(l2info)) :
3206 G_RX_T5_ETHHDR_LEN((__force int) htonl(l2info));
Vipul Pandyaef5d6352013-01-07 13:12:00 +00003207 req->hdr_len = cpu_to_be32(V_SYN_RX_CHAN(G_RX_CHAN(
3208 (__force int) htonl(l2info))) |
3209 V_TCP_HDR_LEN(G_RX_TCPHDR_LEN(
3210 (__force int) htons(hdr_len))) |
3211 V_IP_HDR_LEN(G_RX_IPHDR_LEN(
3212 (__force int) htons(hdr_len))) |
Vipul Pandyaf079af72013-03-14 05:08:58 +00003213 V_ETH_HDR_LEN(G_RX_ETHHDR_LEN(eth_hdr_len)));
Vipul Pandyaef5d6352013-01-07 13:12:00 +00003214 req->vlan = (__force __be16) vlantag;
3215 req->len = (__force __be16) len;
Vipul Pandya1cab7752012-12-10 09:30:55 +00003216 req->tos_stid = cpu_to_be32(PASS_OPEN_TID(stid) |
3217 PASS_OPEN_TOS(tos));
3218 req->tcpopt.mss = htons(tmp_opt.mss_clamp);
3219 if (tmp_opt.wscale_ok)
3220 req->tcpopt.wsf = tmp_opt.snd_wscale;
3221 req->tcpopt.tstamp = tmp_opt.saw_tstamp;
3222 if (tmp_opt.sack_ok)
3223 req->tcpopt.sack = 1;
3224 OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_PASS_ACCEPT_REQ, 0));
3225 return;
3226}
3227
3228static void send_fw_pass_open_req(struct c4iw_dev *dev, struct sk_buff *skb,
3229 __be32 laddr, __be16 lport,
3230 __be32 raddr, __be16 rport,
3231 u32 rcv_isn, u32 filter, u16 window,
3232 u32 rss_qid, u8 port_id)
3233{
3234 struct sk_buff *req_skb;
3235 struct fw_ofld_connection_wr *req;
3236 struct cpl_pass_accept_req *cpl = cplhdr(skb);
Steve Wise1ce1d472014-03-21 20:40:31 +05303237 int ret;
Vipul Pandya1cab7752012-12-10 09:30:55 +00003238
3239 req_skb = alloc_skb(sizeof(struct fw_ofld_connection_wr), GFP_KERNEL);
3240 req = (struct fw_ofld_connection_wr *)__skb_put(req_skb, sizeof(*req));
3241 memset(req, 0, sizeof(*req));
3242 req->op_compl = htonl(V_WR_OP(FW_OFLD_CONNECTION_WR) | FW_WR_COMPL(1));
3243 req->len16_pkd = htonl(FW_WR_LEN16(DIV_ROUND_UP(sizeof(*req), 16)));
3244 req->le.version_cpl = htonl(F_FW_OFLD_CONNECTION_WR_CPL);
Vipul Pandyaef5d6352013-01-07 13:12:00 +00003245 req->le.filter = (__force __be32) filter;
Vipul Pandya1cab7752012-12-10 09:30:55 +00003246 req->le.lport = lport;
3247 req->le.pport = rport;
3248 req->le.u.ipv4.lip = laddr;
3249 req->le.u.ipv4.pip = raddr;
3250 req->tcb.rcv_nxt = htonl(rcv_isn + 1);
3251 req->tcb.rcv_adv = htons(window);
3252 req->tcb.t_state_to_astid =
3253 htonl(V_FW_OFLD_CONNECTION_WR_T_STATE(TCP_SYN_RECV) |
3254 V_FW_OFLD_CONNECTION_WR_RCV_SCALE(cpl->tcpopt.wsf) |
3255 V_FW_OFLD_CONNECTION_WR_ASTID(
3256 GET_PASS_OPEN_TID(ntohl(cpl->tos_stid))));
3257
3258 /*
3259 * We store the qid in opt2 which will be used by the firmware
3260 * to send us the wr response.
3261 */
3262 req->tcb.opt2 = htonl(V_RSS_QUEUE(rss_qid));
3263
3264 /*
3265 * We initialize the MSS index in TCB to 0xF.
3266 * So that when driver sends cpl_pass_accept_rpl
3267 * TCB picks up the correct value. If this was 0
3268 * TP will ignore any value > 0 for MSS index.
3269 */
3270 req->tcb.opt0 = cpu_to_be64(V_MSS_IDX(0xF));
Paul Bolle710a3112013-02-05 20:51:30 +00003271 req->cookie = (unsigned long)skb;
Vipul Pandya1cab7752012-12-10 09:30:55 +00003272
3273 set_wr_txq(req_skb, CPL_PRIORITY_CONTROL, port_id);
Steve Wise1ce1d472014-03-21 20:40:31 +05303274 ret = cxgb4_ofld_send(dev->rdev.lldi.ports[0], req_skb);
3275 if (ret < 0) {
3276 pr_err("%s - cxgb4_ofld_send error %d - dropping\n", __func__,
3277 ret);
3278 kfree_skb(skb);
3279 kfree_skb(req_skb);
3280 }
Vipul Pandya1cab7752012-12-10 09:30:55 +00003281}
3282
3283/*
3284 * Handler for CPL_RX_PKT message. Need to handle cpl_rx_pkt
3285 * messages when a filter is being used instead of server to
3286 * redirect a syn packet. When packets hit filter they are redirected
3287 * to the offload queue and driver tries to establish the connection
3288 * using firmware work request.
3289 */
3290static int rx_pkt(struct c4iw_dev *dev, struct sk_buff *skb)
3291{
3292 int stid;
3293 unsigned int filter;
3294 struct ethhdr *eh = NULL;
3295 struct vlan_ethhdr *vlan_eh = NULL;
3296 struct iphdr *iph;
3297 struct tcphdr *tcph;
3298 struct rss_header *rss = (void *)skb->data;
3299 struct cpl_rx_pkt *cpl = (void *)skb->data;
3300 struct cpl_pass_accept_req *req = (void *)(rss + 1);
3301 struct l2t_entry *e;
3302 struct dst_entry *dst;
Vipul Pandya1cab7752012-12-10 09:30:55 +00003303 struct c4iw_ep *lep;
3304 u16 window;
3305 struct port_info *pi;
3306 struct net_device *pdev;
Vipul Pandyaf079af72013-03-14 05:08:58 +00003307 u16 rss_qid, eth_hdr_len;
Vipul Pandya1cab7752012-12-10 09:30:55 +00003308 int step;
3309 u32 tx_chan;
3310 struct neighbour *neigh;
3311
3312 /* Drop all non-SYN packets */
3313 if (!(cpl->l2info & cpu_to_be32(F_RXF_SYN)))
3314 goto reject;
3315
3316 /*
3317 * Drop all packets which did not hit the filter.
3318 * Unlikely to happen.
3319 */
3320 if (!(rss->filter_hit && rss->filter_tid))
3321 goto reject;
3322
3323 /*
3324 * Calculate the server tid from filter hit index from cpl_rx_pkt.
3325 */
Kumar Sanghvia4ea0252013-12-18 16:38:24 +05303326 stid = (__force int) cpu_to_be32((__force u32) rss->hash_val);
Vipul Pandya1cab7752012-12-10 09:30:55 +00003327
3328 lep = (struct c4iw_ep *)lookup_stid(dev->rdev.lldi.tids, stid);
3329 if (!lep) {
3330 PDBG("%s connect request on invalid stid %d\n", __func__, stid);
3331 goto reject;
3332 }
3333
Vipul Pandyaf079af72013-03-14 05:08:58 +00003334 eth_hdr_len = is_t4(dev->rdev.lldi.adapter_type) ?
3335 G_RX_ETHHDR_LEN(htonl(cpl->l2info)) :
3336 G_RX_T5_ETHHDR_LEN(htonl(cpl->l2info));
3337 if (eth_hdr_len == ETH_HLEN) {
Vipul Pandya1cab7752012-12-10 09:30:55 +00003338 eh = (struct ethhdr *)(req + 1);
3339 iph = (struct iphdr *)(eh + 1);
3340 } else {
3341 vlan_eh = (struct vlan_ethhdr *)(req + 1);
3342 iph = (struct iphdr *)(vlan_eh + 1);
3343 skb->vlan_tci = ntohs(cpl->vlan);
3344 }
3345
3346 if (iph->version != 0x4)
3347 goto reject;
3348
3349 tcph = (struct tcphdr *)(iph + 1);
3350 skb_set_network_header(skb, (void *)iph - (void *)rss);
3351 skb_set_transport_header(skb, (void *)tcph - (void *)rss);
3352 skb_get(skb);
3353
3354 PDBG("%s lip 0x%x lport %u pip 0x%x pport %u tos %d\n", __func__,
3355 ntohl(iph->daddr), ntohs(tcph->dest), ntohl(iph->saddr),
3356 ntohs(tcph->source), iph->tos);
3357
Vipul Pandya830662f2013-07-04 16:10:47 +05303358 dst = find_route(dev, iph->daddr, iph->saddr, tcph->dest, tcph->source,
3359 iph->tos);
3360 if (!dst) {
Vipul Pandya1cab7752012-12-10 09:30:55 +00003361 pr_err("%s - failed to find dst entry!\n",
3362 __func__);
3363 goto reject;
3364 }
Vipul Pandya1cab7752012-12-10 09:30:55 +00003365 neigh = dst_neigh_lookup_skb(dst, skb);
3366
Zhouyi Zhouaaa0c232013-03-14 17:21:50 +00003367 if (!neigh) {
3368 pr_err("%s - failed to allocate neigh!\n",
3369 __func__);
3370 goto free_dst;
3371 }
3372
Vipul Pandya1cab7752012-12-10 09:30:55 +00003373 if (neigh->dev->flags & IFF_LOOPBACK) {
3374 pdev = ip_dev_find(&init_net, iph->daddr);
3375 e = cxgb4_l2t_get(dev->rdev.lldi.l2t, neigh,
3376 pdev, 0);
3377 pi = (struct port_info *)netdev_priv(pdev);
3378 tx_chan = cxgb4_port_chan(pdev);
3379 dev_put(pdev);
3380 } else {
Vipul Pandya830662f2013-07-04 16:10:47 +05303381 pdev = get_real_dev(neigh->dev);
Vipul Pandya1cab7752012-12-10 09:30:55 +00003382 e = cxgb4_l2t_get(dev->rdev.lldi.l2t, neigh,
Vipul Pandya830662f2013-07-04 16:10:47 +05303383 pdev, 0);
3384 pi = (struct port_info *)netdev_priv(pdev);
3385 tx_chan = cxgb4_port_chan(pdev);
Vipul Pandya1cab7752012-12-10 09:30:55 +00003386 }
Steve Wiseebf00062014-03-19 17:44:40 +05303387 neigh_release(neigh);
Vipul Pandya1cab7752012-12-10 09:30:55 +00003388 if (!e) {
3389 pr_err("%s - failed to allocate l2t entry!\n",
3390 __func__);
3391 goto free_dst;
3392 }
3393
3394 step = dev->rdev.lldi.nrxq / dev->rdev.lldi.nchan;
3395 rss_qid = dev->rdev.lldi.rxq_ids[pi->port_id * step];
Vipul Pandyaef5d6352013-01-07 13:12:00 +00003396 window = (__force u16) htons((__force u16)tcph->window);
Vipul Pandya1cab7752012-12-10 09:30:55 +00003397
3398 /* Calcuate filter portion for LE region. */
Kumar Sanghvi41b4f862013-12-18 16:38:26 +05303399 filter = (__force unsigned int) cpu_to_be32(cxgb4_select_ntuple(
3400 dev->rdev.lldi.ports[0],
3401 e));
Vipul Pandya1cab7752012-12-10 09:30:55 +00003402
3403 /*
3404 * Synthesize the cpl_pass_accept_req. We have everything except the
3405 * TID. Once firmware sends a reply with TID we update the TID field
3406 * in cpl and pass it through the regular cpl_pass_accept_req path.
3407 */
3408 build_cpl_pass_accept_req(skb, stid, iph->tos);
3409 send_fw_pass_open_req(dev, skb, iph->daddr, tcph->dest, iph->saddr,
3410 tcph->source, ntohl(tcph->seq), filter, window,
3411 rss_qid, pi->port_id);
3412 cxgb4_l2t_release(e);
3413free_dst:
3414 dst_release(dst);
3415reject:
Steve Wise2f5b48c2010-09-10 11:15:36 -05003416 return 0;
3417}
3418
Steve Wisecfdda9d2010-04-21 15:30:06 -07003419/*
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07003420 * These are the real handlers that are called from a
3421 * work queue.
3422 */
3423static c4iw_handler_func work_handlers[NUM_CPL_CMDS] = {
3424 [CPL_ACT_ESTABLISH] = act_establish,
3425 [CPL_ACT_OPEN_RPL] = act_open_rpl,
3426 [CPL_RX_DATA] = rx_data,
3427 [CPL_ABORT_RPL_RSS] = abort_rpl,
3428 [CPL_ABORT_RPL] = abort_rpl,
3429 [CPL_PASS_OPEN_RPL] = pass_open_rpl,
3430 [CPL_CLOSE_LISTSRV_RPL] = close_listsrv_rpl,
3431 [CPL_PASS_ACCEPT_REQ] = pass_accept_req,
3432 [CPL_PASS_ESTABLISH] = pass_establish,
3433 [CPL_PEER_CLOSE] = peer_close,
3434 [CPL_ABORT_REQ_RSS] = peer_abort,
3435 [CPL_CLOSE_CON_RPL] = close_con_rpl,
3436 [CPL_RDMA_TERMINATE] = terminate,
Steve Wise2f5b48c2010-09-10 11:15:36 -05003437 [CPL_FW4_ACK] = fw4_ack,
Vipul Pandya1cab7752012-12-10 09:30:55 +00003438 [CPL_FW6_MSG] = deferred_fw6_msg,
3439 [CPL_RX_PKT] = rx_pkt
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07003440};
3441
3442static void process_timeout(struct c4iw_ep *ep)
3443{
3444 struct c4iw_qp_attributes attrs;
3445 int abort = 1;
3446
Steve Wise2f5b48c2010-09-10 11:15:36 -05003447 mutex_lock(&ep->com.mutex);
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07003448 PDBG("%s ep %p tid %u state %d\n", __func__, ep, ep->hwtid,
3449 ep->com.state);
Vipul Pandya793dad92012-12-10 09:30:56 +00003450 set_bit(TIMEDOUT, &ep->com.history);
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07003451 switch (ep->com.state) {
3452 case MPA_REQ_SENT:
3453 __state_set(&ep->com, ABORTING);
3454 connect_reply_upcall(ep, -ETIMEDOUT);
3455 break;
3456 case MPA_REQ_WAIT:
3457 __state_set(&ep->com, ABORTING);
3458 break;
3459 case CLOSING:
3460 case MORIBUND:
3461 if (ep->com.cm_id && ep->com.qp) {
3462 attrs.next_state = C4IW_QP_STATE_ERROR;
3463 c4iw_modify_qp(ep->com.qp->rhp,
3464 ep->com.qp, C4IW_QP_ATTR_NEXT_STATE,
3465 &attrs, 1);
3466 }
3467 __state_set(&ep->com, ABORTING);
Steve Wisebe13b2d2014-03-21 20:40:33 +05303468 close_complete_upcall(ep, -ETIMEDOUT);
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07003469 break;
Steve Wiseb33bd0c2014-04-09 09:38:25 -05003470 case ABORTING:
3471 case DEAD:
3472
3473 /*
3474 * These states are expected if the ep timed out at the same
3475 * time as another thread was calling stop_ep_timer().
3476 * So we silently do nothing for these states.
3477 */
3478 abort = 0;
3479 break;
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07003480 default:
Julia Lawall76f267b2012-11-03 10:58:27 +00003481 WARN(1, "%s unexpected state ep %p tid %u state %u\n",
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07003482 __func__, ep, ep->hwtid, ep->com.state);
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07003483 abort = 0;
3484 }
Steve Wise2f5b48c2010-09-10 11:15:36 -05003485 mutex_unlock(&ep->com.mutex);
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07003486 if (abort)
3487 abort_connection(ep, NULL, GFP_KERNEL);
3488 c4iw_put_ep(&ep->com);
3489}
3490
3491static void process_timedout_eps(void)
3492{
3493 struct c4iw_ep *ep;
3494
3495 spin_lock_irq(&timeout_lock);
3496 while (!list_empty(&timeout_list)) {
3497 struct list_head *tmp;
3498
3499 tmp = timeout_list.next;
3500 list_del(tmp);
Steve Wiseb33bd0c2014-04-09 09:38:25 -05003501 tmp->next = NULL;
3502 tmp->prev = NULL;
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07003503 spin_unlock_irq(&timeout_lock);
3504 ep = list_entry(tmp, struct c4iw_ep, entry);
3505 process_timeout(ep);
3506 spin_lock_irq(&timeout_lock);
3507 }
3508 spin_unlock_irq(&timeout_lock);
3509}
3510
3511static void process_work(struct work_struct *work)
3512{
3513 struct sk_buff *skb = NULL;
3514 struct c4iw_dev *dev;
Dan Carpenterc1d73562010-05-31 14:00:53 +00003515 struct cpl_act_establish *rpl;
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07003516 unsigned int opcode;
3517 int ret;
3518
Steve Wiseb33bd0c2014-04-09 09:38:25 -05003519 process_timedout_eps();
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07003520 while ((skb = skb_dequeue(&rxq))) {
3521 rpl = cplhdr(skb);
3522 dev = *((struct c4iw_dev **) (skb->cb + sizeof(void *)));
3523 opcode = rpl->ot.opcode;
3524
3525 BUG_ON(!work_handlers[opcode]);
3526 ret = work_handlers[opcode](dev, skb);
3527 if (!ret)
3528 kfree_skb(skb);
Steve Wiseb33bd0c2014-04-09 09:38:25 -05003529 process_timedout_eps();
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07003530 }
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07003531}
3532
3533static DECLARE_WORK(skb_work, process_work);
3534
3535static void ep_timeout(unsigned long arg)
3536{
3537 struct c4iw_ep *ep = (struct c4iw_ep *)arg;
Vipul Pandya1ec779c2013-01-07 13:11:56 +00003538 int kickit = 0;
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07003539
3540 spin_lock(&timeout_lock);
Vipul Pandya1ec779c2013-01-07 13:11:56 +00003541 if (!test_and_set_bit(TIMEOUT, &ep->com.flags)) {
Steve Wiseb33bd0c2014-04-09 09:38:25 -05003542 /*
3543 * Only insert if it is not already on the list.
3544 */
3545 if (!ep->entry.next) {
3546 list_add_tail(&ep->entry, &timeout_list);
3547 kickit = 1;
3548 }
Vipul Pandya1ec779c2013-01-07 13:11:56 +00003549 }
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07003550 spin_unlock(&timeout_lock);
Vipul Pandya1ec779c2013-01-07 13:11:56 +00003551 if (kickit)
3552 queue_work(workq, &skb_work);
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07003553}
3554
3555/*
Steve Wisecfdda9d2010-04-21 15:30:06 -07003556 * All the CM events are handled on a work queue to have a safe context.
3557 */
3558static int sched(struct c4iw_dev *dev, struct sk_buff *skb)
3559{
3560
3561 /*
3562 * Save dev in the skb->cb area.
3563 */
3564 *((struct c4iw_dev **) (skb->cb + sizeof(void *))) = dev;
3565
3566 /*
3567 * Queue the skb and schedule the worker thread.
3568 */
3569 skb_queue_tail(&rxq, skb);
3570 queue_work(workq, &skb_work);
3571 return 0;
3572}
3573
3574static int set_tcb_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
3575{
3576 struct cpl_set_tcb_rpl *rpl = cplhdr(skb);
3577
3578 if (rpl->status != CPL_ERR_NONE) {
3579 printk(KERN_ERR MOD "Unexpected SET_TCB_RPL status %u "
3580 "for tid %u\n", rpl->status, GET_TID(rpl));
3581 }
Steve Wise2f5b48c2010-09-10 11:15:36 -05003582 kfree_skb(skb);
Steve Wisecfdda9d2010-04-21 15:30:06 -07003583 return 0;
3584}
3585
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07003586static int fw6_msg(struct c4iw_dev *dev, struct sk_buff *skb)
3587{
3588 struct cpl_fw6_msg *rpl = cplhdr(skb);
3589 struct c4iw_wr_wait *wr_waitp;
3590 int ret;
3591
3592 PDBG("%s type %u\n", __func__, rpl->type);
3593
3594 switch (rpl->type) {
Vipul Pandya5be78ee2012-12-10 09:30:54 +00003595 case FW6_TYPE_WR_RPL:
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07003596 ret = (int)((be64_to_cpu(rpl->data[0]) >> 8) & 0xff);
Roland Dreierc8e081a2010-09-27 17:51:04 -07003597 wr_waitp = (struct c4iw_wr_wait *)(__force unsigned long) rpl->data[1];
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07003598 PDBG("%s wr_waitp %p ret %u\n", __func__, wr_waitp, ret);
Steve Wised9594d92011-05-09 22:06:22 -07003599 if (wr_waitp)
3600 c4iw_wake_up(wr_waitp, ret ? -ret : 0);
Steve Wise2f5b48c2010-09-10 11:15:36 -05003601 kfree_skb(skb);
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07003602 break;
Vipul Pandya5be78ee2012-12-10 09:30:54 +00003603 case FW6_TYPE_CQE:
Vipul Pandya5be78ee2012-12-10 09:30:54 +00003604 case FW6_TYPE_OFLD_CONNECTION_WR_RPL:
Vipul Pandya1cab7752012-12-10 09:30:55 +00003605 sched(dev, skb);
Vipul Pandya5be78ee2012-12-10 09:30:54 +00003606 break;
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07003607 default:
3608 printk(KERN_ERR MOD "%s unexpected fw6 msg type %u\n", __func__,
3609 rpl->type);
Steve Wise2f5b48c2010-09-10 11:15:36 -05003610 kfree_skb(skb);
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07003611 break;
3612 }
3613 return 0;
3614}
3615
Steve Wise8da7e7a2011-06-14 20:59:27 +00003616static int peer_abort_intr(struct c4iw_dev *dev, struct sk_buff *skb)
3617{
3618 struct cpl_abort_req_rss *req = cplhdr(skb);
3619 struct c4iw_ep *ep;
3620 struct tid_info *t = dev->rdev.lldi.tids;
3621 unsigned int tid = GET_TID(req);
3622
3623 ep = lookup_tid(t, tid);
Steve Wise14b92222012-04-30 15:31:29 -05003624 if (!ep) {
3625 printk(KERN_WARNING MOD
3626 "Abort on non-existent endpoint, tid %d\n", tid);
3627 kfree_skb(skb);
3628 return 0;
3629 }
Steve Wise7a2cea22014-03-14 21:52:07 +05303630 if (is_neg_adv(req->status)) {
Steve Wise8da7e7a2011-06-14 20:59:27 +00003631 PDBG("%s neg_adv_abort ep %p tid %u\n", __func__, ep,
3632 ep->hwtid);
3633 kfree_skb(skb);
3634 return 0;
3635 }
3636 PDBG("%s ep %p tid %u state %u\n", __func__, ep, ep->hwtid,
3637 ep->com.state);
3638
3639 /*
3640 * Wake up any threads in rdma_init() or rdma_fini().
Vipul Pandya7c0a33d2013-01-07 13:11:58 +00003641 * However, if we are on MPAv2 and want to retry with MPAv1
3642 * then, don't wake up yet.
Steve Wise8da7e7a2011-06-14 20:59:27 +00003643 */
Vipul Pandya7c0a33d2013-01-07 13:11:58 +00003644 if (mpa_rev == 2 && !ep->tried_with_mpa_v1) {
3645 if (ep->com.state != MPA_REQ_SENT)
3646 c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET);
3647 } else
3648 c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET);
Steve Wise8da7e7a2011-06-14 20:59:27 +00003649 sched(dev, skb);
3650 return 0;
3651}
3652
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07003653/*
3654 * Most upcalls from the T4 Core go to sched() to
3655 * schedule the processing on a work queue.
3656 */
3657c4iw_handler_func c4iw_handlers[NUM_CPL_CMDS] = {
3658 [CPL_ACT_ESTABLISH] = sched,
3659 [CPL_ACT_OPEN_RPL] = sched,
3660 [CPL_RX_DATA] = sched,
3661 [CPL_ABORT_RPL_RSS] = sched,
3662 [CPL_ABORT_RPL] = sched,
3663 [CPL_PASS_OPEN_RPL] = sched,
3664 [CPL_CLOSE_LISTSRV_RPL] = sched,
3665 [CPL_PASS_ACCEPT_REQ] = sched,
3666 [CPL_PASS_ESTABLISH] = sched,
3667 [CPL_PEER_CLOSE] = sched,
3668 [CPL_CLOSE_CON_RPL] = sched,
Steve Wise8da7e7a2011-06-14 20:59:27 +00003669 [CPL_ABORT_REQ_RSS] = peer_abort_intr,
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07003670 [CPL_RDMA_TERMINATE] = sched,
3671 [CPL_FW4_ACK] = sched,
3672 [CPL_SET_TCB_RPL] = set_tcb_rpl,
Vipul Pandya1cab7752012-12-10 09:30:55 +00003673 [CPL_FW6_MSG] = fw6_msg,
3674 [CPL_RX_PKT] = sched
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07003675};
3676
Steve Wisecfdda9d2010-04-21 15:30:06 -07003677int __init c4iw_cm_init(void)
3678{
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07003679 spin_lock_init(&timeout_lock);
Steve Wisecfdda9d2010-04-21 15:30:06 -07003680 skb_queue_head_init(&rxq);
3681
3682 workq = create_singlethread_workqueue("iw_cxgb4");
3683 if (!workq)
3684 return -ENOMEM;
3685
Steve Wisecfdda9d2010-04-21 15:30:06 -07003686 return 0;
3687}
3688
3689void __exit c4iw_cm_term(void)
3690{
Roland Dreierbe4c9ba2010-05-05 14:45:40 -07003691 WARN_ON(!list_empty(&timeout_list));
Steve Wisecfdda9d2010-04-21 15:30:06 -07003692 flush_workqueue(workq);
3693 destroy_workqueue(workq);
3694}