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