Path: blob/master/drivers/infiniband/hw/cxgb4/cm.c
15112 views
/*1* Copyright (c) 2009-2010 Chelsio, Inc. All rights reserved.2*3* This software is available to you under a choice of one of two4* licenses. You may choose to be licensed under the terms of the GNU5* General Public License (GPL) Version 2, available from the file6* COPYING in the main directory of this source tree, or the7* OpenIB.org BSD license below:8*9* Redistribution and use in source and binary forms, with or10* without modification, are permitted provided that the following11* conditions are met:12*13* - Redistributions of source code must retain the above14* copyright notice, this list of conditions and the following15* disclaimer.16*17* - Redistributions in binary form must reproduce the above18* copyright notice, this list of conditions and the following19* disclaimer in the documentation and/or other materials20* provided with the distribution.21*22* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,23* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF24* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND25* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS26* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN27* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN28* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE29* SOFTWARE.30*/31#include <linux/module.h>32#include <linux/list.h>33#include <linux/workqueue.h>34#include <linux/skbuff.h>35#include <linux/timer.h>36#include <linux/notifier.h>37#include <linux/inetdevice.h>38#include <linux/ip.h>39#include <linux/tcp.h>4041#include <net/neighbour.h>42#include <net/netevent.h>43#include <net/route.h>4445#include "iw_cxgb4.h"4647static char *states[] = {48"idle",49"listen",50"connecting",51"mpa_wait_req",52"mpa_req_sent",53"mpa_req_rcvd",54"mpa_rep_sent",55"fpdu_mode",56"aborting",57"closing",58"moribund",59"dead",60NULL,61};6263static int dack_mode = 1;64module_param(dack_mode, int, 0644);65MODULE_PARM_DESC(dack_mode, "Delayed ack mode (default=1)");6667int c4iw_max_read_depth = 8;68module_param(c4iw_max_read_depth, int, 0644);69MODULE_PARM_DESC(c4iw_max_read_depth, "Per-connection max ORD/IRD (default=8)");7071static int enable_tcp_timestamps;72module_param(enable_tcp_timestamps, int, 0644);73MODULE_PARM_DESC(enable_tcp_timestamps, "Enable tcp timestamps (default=0)");7475static int enable_tcp_sack;76module_param(enable_tcp_sack, int, 0644);77MODULE_PARM_DESC(enable_tcp_sack, "Enable tcp SACK (default=0)");7879static int enable_tcp_window_scaling = 1;80module_param(enable_tcp_window_scaling, int, 0644);81MODULE_PARM_DESC(enable_tcp_window_scaling,82"Enable tcp window scaling (default=1)");8384int c4iw_debug;85module_param(c4iw_debug, int, 0644);86MODULE_PARM_DESC(c4iw_debug, "Enable debug logging (default=0)");8788static int peer2peer;89module_param(peer2peer, int, 0644);90MODULE_PARM_DESC(peer2peer, "Support peer2peer ULPs (default=0)");9192static int p2p_type = FW_RI_INIT_P2PTYPE_READ_REQ;93module_param(p2p_type, int, 0644);94MODULE_PARM_DESC(p2p_type, "RDMAP opcode to use for the RTR message: "95"1=RDMA_READ 0=RDMA_WRITE (default 1)");9697static int ep_timeout_secs = 60;98module_param(ep_timeout_secs, int, 0644);99MODULE_PARM_DESC(ep_timeout_secs, "CM Endpoint operation timeout "100"in seconds (default=60)");101102static int mpa_rev = 1;103module_param(mpa_rev, int, 0644);104MODULE_PARM_DESC(mpa_rev, "MPA Revision, 0 supports amso1100, "105"1 is spec compliant. (default=1)");106107static int markers_enabled;108module_param(markers_enabled, int, 0644);109MODULE_PARM_DESC(markers_enabled, "Enable MPA MARKERS (default(0)=disabled)");110111static int crc_enabled = 1;112module_param(crc_enabled, int, 0644);113MODULE_PARM_DESC(crc_enabled, "Enable MPA CRC (default(1)=enabled)");114115static int rcv_win = 256 * 1024;116module_param(rcv_win, int, 0644);117MODULE_PARM_DESC(rcv_win, "TCP receive window in bytes (default=256KB)");118119static int snd_win = 128 * 1024;120module_param(snd_win, int, 0644);121MODULE_PARM_DESC(snd_win, "TCP send window in bytes (default=128KB)");122123static struct workqueue_struct *workq;124125static struct sk_buff_head rxq;126127static struct sk_buff *get_skb(struct sk_buff *skb, int len, gfp_t gfp);128static void ep_timeout(unsigned long arg);129static void connect_reply_upcall(struct c4iw_ep *ep, int status);130131static LIST_HEAD(timeout_list);132static spinlock_t timeout_lock;133134static void start_ep_timer(struct c4iw_ep *ep)135{136PDBG("%s ep %p\n", __func__, ep);137if (timer_pending(&ep->timer)) {138PDBG("%s stopped / restarted timer ep %p\n", __func__, ep);139del_timer_sync(&ep->timer);140} else141c4iw_get_ep(&ep->com);142ep->timer.expires = jiffies + ep_timeout_secs * HZ;143ep->timer.data = (unsigned long)ep;144ep->timer.function = ep_timeout;145add_timer(&ep->timer);146}147148static void stop_ep_timer(struct c4iw_ep *ep)149{150PDBG("%s ep %p\n", __func__, ep);151if (!timer_pending(&ep->timer)) {152printk(KERN_ERR "%s timer stopped when its not running! "153"ep %p state %u\n", __func__, ep, ep->com.state);154WARN_ON(1);155return;156}157del_timer_sync(&ep->timer);158c4iw_put_ep(&ep->com);159}160161static int c4iw_l2t_send(struct c4iw_rdev *rdev, struct sk_buff *skb,162struct l2t_entry *l2e)163{164int error = 0;165166if (c4iw_fatal_error(rdev)) {167kfree_skb(skb);168PDBG("%s - device in error state - dropping\n", __func__);169return -EIO;170}171error = cxgb4_l2t_send(rdev->lldi.ports[0], skb, l2e);172if (error < 0)173kfree_skb(skb);174return error < 0 ? error : 0;175}176177int c4iw_ofld_send(struct c4iw_rdev *rdev, struct sk_buff *skb)178{179int error = 0;180181if (c4iw_fatal_error(rdev)) {182kfree_skb(skb);183PDBG("%s - device in error state - dropping\n", __func__);184return -EIO;185}186error = cxgb4_ofld_send(rdev->lldi.ports[0], skb);187if (error < 0)188kfree_skb(skb);189return error < 0 ? error : 0;190}191192static void release_tid(struct c4iw_rdev *rdev, u32 hwtid, struct sk_buff *skb)193{194struct cpl_tid_release *req;195196skb = get_skb(skb, sizeof *req, GFP_KERNEL);197if (!skb)198return;199req = (struct cpl_tid_release *) skb_put(skb, sizeof(*req));200INIT_TP_WR(req, hwtid);201OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_TID_RELEASE, hwtid));202set_wr_txq(skb, CPL_PRIORITY_SETUP, 0);203c4iw_ofld_send(rdev, skb);204return;205}206207static void set_emss(struct c4iw_ep *ep, u16 opt)208{209ep->emss = ep->com.dev->rdev.lldi.mtus[GET_TCPOPT_MSS(opt)] - 40;210ep->mss = ep->emss;211if (GET_TCPOPT_TSTAMP(opt))212ep->emss -= 12;213if (ep->emss < 128)214ep->emss = 128;215PDBG("%s mss_idx %u mss %u emss=%u\n", __func__, GET_TCPOPT_MSS(opt),216ep->mss, ep->emss);217}218219static enum c4iw_ep_state state_read(struct c4iw_ep_common *epc)220{221enum c4iw_ep_state state;222223mutex_lock(&epc->mutex);224state = epc->state;225mutex_unlock(&epc->mutex);226return state;227}228229static void __state_set(struct c4iw_ep_common *epc, enum c4iw_ep_state new)230{231epc->state = new;232}233234static void state_set(struct c4iw_ep_common *epc, enum c4iw_ep_state new)235{236mutex_lock(&epc->mutex);237PDBG("%s - %s -> %s\n", __func__, states[epc->state], states[new]);238__state_set(epc, new);239mutex_unlock(&epc->mutex);240return;241}242243static void *alloc_ep(int size, gfp_t gfp)244{245struct c4iw_ep_common *epc;246247epc = kzalloc(size, gfp);248if (epc) {249kref_init(&epc->kref);250mutex_init(&epc->mutex);251c4iw_init_wr_wait(&epc->wr_wait);252}253PDBG("%s alloc ep %p\n", __func__, epc);254return epc;255}256257void _c4iw_free_ep(struct kref *kref)258{259struct c4iw_ep *ep;260261ep = container_of(kref, struct c4iw_ep, com.kref);262PDBG("%s ep %p state %s\n", __func__, ep, states[state_read(&ep->com)]);263if (test_bit(RELEASE_RESOURCES, &ep->com.flags)) {264cxgb4_remove_tid(ep->com.dev->rdev.lldi.tids, 0, ep->hwtid);265dst_release(ep->dst);266cxgb4_l2t_release(ep->l2t);267}268kfree(ep);269}270271static void release_ep_resources(struct c4iw_ep *ep)272{273set_bit(RELEASE_RESOURCES, &ep->com.flags);274c4iw_put_ep(&ep->com);275}276277static int status2errno(int status)278{279switch (status) {280case CPL_ERR_NONE:281return 0;282case CPL_ERR_CONN_RESET:283return -ECONNRESET;284case CPL_ERR_ARP_MISS:285return -EHOSTUNREACH;286case CPL_ERR_CONN_TIMEDOUT:287return -ETIMEDOUT;288case CPL_ERR_TCAM_FULL:289return -ENOMEM;290case CPL_ERR_CONN_EXIST:291return -EADDRINUSE;292default:293return -EIO;294}295}296297/*298* Try and reuse skbs already allocated...299*/300static struct sk_buff *get_skb(struct sk_buff *skb, int len, gfp_t gfp)301{302if (skb && !skb_is_nonlinear(skb) && !skb_cloned(skb)) {303skb_trim(skb, 0);304skb_get(skb);305skb_reset_transport_header(skb);306} else {307skb = alloc_skb(len, gfp);308}309return skb;310}311312static struct rtable *find_route(struct c4iw_dev *dev, __be32 local_ip,313__be32 peer_ip, __be16 local_port,314__be16 peer_port, u8 tos)315{316struct rtable *rt;317struct flowi4 fl4;318319rt = ip_route_output_ports(&init_net, &fl4, NULL, peer_ip, local_ip,320peer_port, local_port, IPPROTO_TCP,321tos, 0);322if (IS_ERR(rt))323return NULL;324return rt;325}326327static void arp_failure_discard(void *handle, struct sk_buff *skb)328{329PDBG("%s c4iw_dev %p\n", __func__, handle);330kfree_skb(skb);331}332333/*334* Handle an ARP failure for an active open.335*/336static void act_open_req_arp_failure(void *handle, struct sk_buff *skb)337{338printk(KERN_ERR MOD "ARP failure duing connect\n");339kfree_skb(skb);340}341342/*343* Handle an ARP failure for a CPL_ABORT_REQ. Change it into a no RST variant344* and send it along.345*/346static void abort_arp_failure(void *handle, struct sk_buff *skb)347{348struct c4iw_rdev *rdev = handle;349struct cpl_abort_req *req = cplhdr(skb);350351PDBG("%s rdev %p\n", __func__, rdev);352req->cmd = CPL_ABORT_NO_RST;353c4iw_ofld_send(rdev, skb);354}355356static void send_flowc(struct c4iw_ep *ep, struct sk_buff *skb)357{358unsigned int flowclen = 80;359struct fw_flowc_wr *flowc;360int i;361362skb = get_skb(skb, flowclen, GFP_KERNEL);363flowc = (struct fw_flowc_wr *)__skb_put(skb, flowclen);364365flowc->op_to_nparams = cpu_to_be32(FW_WR_OP(FW_FLOWC_WR) |366FW_FLOWC_WR_NPARAMS(8));367flowc->flowid_len16 = cpu_to_be32(FW_WR_LEN16(DIV_ROUND_UP(flowclen,36816)) | FW_WR_FLOWID(ep->hwtid));369370flowc->mnemval[0].mnemonic = FW_FLOWC_MNEM_PFNVFN;371flowc->mnemval[0].val = cpu_to_be32(PCI_FUNC(ep->com.dev->rdev.lldi.pdev->devfn) << 8);372flowc->mnemval[1].mnemonic = FW_FLOWC_MNEM_CH;373flowc->mnemval[1].val = cpu_to_be32(ep->tx_chan);374flowc->mnemval[2].mnemonic = FW_FLOWC_MNEM_PORT;375flowc->mnemval[2].val = cpu_to_be32(ep->tx_chan);376flowc->mnemval[3].mnemonic = FW_FLOWC_MNEM_IQID;377flowc->mnemval[3].val = cpu_to_be32(ep->rss_qid);378flowc->mnemval[4].mnemonic = FW_FLOWC_MNEM_SNDNXT;379flowc->mnemval[4].val = cpu_to_be32(ep->snd_seq);380flowc->mnemval[5].mnemonic = FW_FLOWC_MNEM_RCVNXT;381flowc->mnemval[5].val = cpu_to_be32(ep->rcv_seq);382flowc->mnemval[6].mnemonic = FW_FLOWC_MNEM_SNDBUF;383flowc->mnemval[6].val = cpu_to_be32(snd_win);384flowc->mnemval[7].mnemonic = FW_FLOWC_MNEM_MSS;385flowc->mnemval[7].val = cpu_to_be32(ep->emss);386/* Pad WR to 16 byte boundary */387flowc->mnemval[8].mnemonic = 0;388flowc->mnemval[8].val = 0;389for (i = 0; i < 9; i++) {390flowc->mnemval[i].r4[0] = 0;391flowc->mnemval[i].r4[1] = 0;392flowc->mnemval[i].r4[2] = 0;393}394395set_wr_txq(skb, CPL_PRIORITY_DATA, ep->txq_idx);396c4iw_ofld_send(&ep->com.dev->rdev, skb);397}398399static int send_halfclose(struct c4iw_ep *ep, gfp_t gfp)400{401struct cpl_close_con_req *req;402struct sk_buff *skb;403int wrlen = roundup(sizeof *req, 16);404405PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);406skb = get_skb(NULL, wrlen, gfp);407if (!skb) {408printk(KERN_ERR MOD "%s - failed to alloc skb\n", __func__);409return -ENOMEM;410}411set_wr_txq(skb, CPL_PRIORITY_DATA, ep->txq_idx);412t4_set_arp_err_handler(skb, NULL, arp_failure_discard);413req = (struct cpl_close_con_req *) skb_put(skb, wrlen);414memset(req, 0, wrlen);415INIT_TP_WR(req, ep->hwtid);416OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_CLOSE_CON_REQ,417ep->hwtid));418return c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t);419}420421static int send_abort(struct c4iw_ep *ep, struct sk_buff *skb, gfp_t gfp)422{423struct cpl_abort_req *req;424int wrlen = roundup(sizeof *req, 16);425426PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);427skb = get_skb(skb, wrlen, gfp);428if (!skb) {429printk(KERN_ERR MOD "%s - failed to alloc skb.\n",430__func__);431return -ENOMEM;432}433set_wr_txq(skb, CPL_PRIORITY_DATA, ep->txq_idx);434t4_set_arp_err_handler(skb, &ep->com.dev->rdev, abort_arp_failure);435req = (struct cpl_abort_req *) skb_put(skb, wrlen);436memset(req, 0, wrlen);437INIT_TP_WR(req, ep->hwtid);438OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_ABORT_REQ, ep->hwtid));439req->cmd = CPL_ABORT_SEND_RST;440return c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t);441}442443static int send_connect(struct c4iw_ep *ep)444{445struct cpl_act_open_req *req;446struct sk_buff *skb;447u64 opt0;448u32 opt2;449unsigned int mtu_idx;450int wscale;451int wrlen = roundup(sizeof *req, 16);452453PDBG("%s ep %p atid %u\n", __func__, ep, ep->atid);454455skb = get_skb(NULL, wrlen, GFP_KERNEL);456if (!skb) {457printk(KERN_ERR MOD "%s - failed to alloc skb.\n",458__func__);459return -ENOMEM;460}461set_wr_txq(skb, CPL_PRIORITY_SETUP, ep->ctrlq_idx);462463cxgb4_best_mtu(ep->com.dev->rdev.lldi.mtus, ep->mtu, &mtu_idx);464wscale = compute_wscale(rcv_win);465opt0 = KEEP_ALIVE(1) |466DELACK(1) |467WND_SCALE(wscale) |468MSS_IDX(mtu_idx) |469L2T_IDX(ep->l2t->idx) |470TX_CHAN(ep->tx_chan) |471SMAC_SEL(ep->smac_idx) |472DSCP(ep->tos) |473ULP_MODE(ULP_MODE_TCPDDP) |474RCV_BUFSIZ(rcv_win>>10);475opt2 = RX_CHANNEL(0) |476RSS_QUEUE_VALID | RSS_QUEUE(ep->rss_qid);477if (enable_tcp_timestamps)478opt2 |= TSTAMPS_EN(1);479if (enable_tcp_sack)480opt2 |= SACK_EN(1);481if (wscale && enable_tcp_window_scaling)482opt2 |= WND_SCALE_EN(1);483t4_set_arp_err_handler(skb, NULL, act_open_req_arp_failure);484485req = (struct cpl_act_open_req *) skb_put(skb, wrlen);486INIT_TP_WR(req, 0);487OPCODE_TID(req) = cpu_to_be32(488MK_OPCODE_TID(CPL_ACT_OPEN_REQ, ((ep->rss_qid<<14)|ep->atid)));489req->local_port = ep->com.local_addr.sin_port;490req->peer_port = ep->com.remote_addr.sin_port;491req->local_ip = ep->com.local_addr.sin_addr.s_addr;492req->peer_ip = ep->com.remote_addr.sin_addr.s_addr;493req->opt0 = cpu_to_be64(opt0);494req->params = 0;495req->opt2 = cpu_to_be32(opt2);496return c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t);497}498499static void send_mpa_req(struct c4iw_ep *ep, struct sk_buff *skb)500{501int mpalen, wrlen;502struct fw_ofld_tx_data_wr *req;503struct mpa_message *mpa;504505PDBG("%s ep %p tid %u pd_len %d\n", __func__, ep, ep->hwtid, ep->plen);506507BUG_ON(skb_cloned(skb));508509mpalen = sizeof(*mpa) + ep->plen;510wrlen = roundup(mpalen + sizeof *req, 16);511skb = get_skb(skb, wrlen, GFP_KERNEL);512if (!skb) {513connect_reply_upcall(ep, -ENOMEM);514return;515}516set_wr_txq(skb, CPL_PRIORITY_DATA, ep->txq_idx);517518req = (struct fw_ofld_tx_data_wr *)skb_put(skb, wrlen);519memset(req, 0, wrlen);520req->op_to_immdlen = cpu_to_be32(521FW_WR_OP(FW_OFLD_TX_DATA_WR) |522FW_WR_COMPL(1) |523FW_WR_IMMDLEN(mpalen));524req->flowid_len16 = cpu_to_be32(525FW_WR_FLOWID(ep->hwtid) |526FW_WR_LEN16(wrlen >> 4));527req->plen = cpu_to_be32(mpalen);528req->tunnel_to_proxy = cpu_to_be32(529FW_OFLD_TX_DATA_WR_FLUSH(1) |530FW_OFLD_TX_DATA_WR_SHOVE(1));531532mpa = (struct mpa_message *)(req + 1);533memcpy(mpa->key, MPA_KEY_REQ, sizeof(mpa->key));534mpa->flags = (crc_enabled ? MPA_CRC : 0) |535(markers_enabled ? MPA_MARKERS : 0);536mpa->private_data_size = htons(ep->plen);537mpa->revision = mpa_rev;538539if (ep->plen)540memcpy(mpa->private_data, ep->mpa_pkt + sizeof(*mpa), ep->plen);541542/*543* Reference the mpa skb. This ensures the data area544* will remain in memory until the hw acks the tx.545* Function fw4_ack() will deref it.546*/547skb_get(skb);548t4_set_arp_err_handler(skb, NULL, arp_failure_discard);549BUG_ON(ep->mpa_skb);550ep->mpa_skb = skb;551c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t);552start_ep_timer(ep);553state_set(&ep->com, MPA_REQ_SENT);554ep->mpa_attr.initiator = 1;555return;556}557558static int send_mpa_reject(struct c4iw_ep *ep, const void *pdata, u8 plen)559{560int mpalen, wrlen;561struct fw_ofld_tx_data_wr *req;562struct mpa_message *mpa;563struct sk_buff *skb;564565PDBG("%s ep %p tid %u pd_len %d\n", __func__, ep, ep->hwtid, ep->plen);566567mpalen = sizeof(*mpa) + plen;568wrlen = roundup(mpalen + sizeof *req, 16);569570skb = get_skb(NULL, wrlen, GFP_KERNEL);571if (!skb) {572printk(KERN_ERR MOD "%s - cannot alloc skb!\n", __func__);573return -ENOMEM;574}575set_wr_txq(skb, CPL_PRIORITY_DATA, ep->txq_idx);576577req = (struct fw_ofld_tx_data_wr *)skb_put(skb, wrlen);578memset(req, 0, wrlen);579req->op_to_immdlen = cpu_to_be32(580FW_WR_OP(FW_OFLD_TX_DATA_WR) |581FW_WR_COMPL(1) |582FW_WR_IMMDLEN(mpalen));583req->flowid_len16 = cpu_to_be32(584FW_WR_FLOWID(ep->hwtid) |585FW_WR_LEN16(wrlen >> 4));586req->plen = cpu_to_be32(mpalen);587req->tunnel_to_proxy = cpu_to_be32(588FW_OFLD_TX_DATA_WR_FLUSH(1) |589FW_OFLD_TX_DATA_WR_SHOVE(1));590591mpa = (struct mpa_message *)(req + 1);592memset(mpa, 0, sizeof(*mpa));593memcpy(mpa->key, MPA_KEY_REP, sizeof(mpa->key));594mpa->flags = MPA_REJECT;595mpa->revision = mpa_rev;596mpa->private_data_size = htons(plen);597if (plen)598memcpy(mpa->private_data, pdata, plen);599600/*601* Reference the mpa skb again. This ensures the data area602* will remain in memory until the hw acks the tx.603* Function fw4_ack() will deref it.604*/605skb_get(skb);606set_wr_txq(skb, CPL_PRIORITY_DATA, ep->txq_idx);607t4_set_arp_err_handler(skb, NULL, arp_failure_discard);608BUG_ON(ep->mpa_skb);609ep->mpa_skb = skb;610return c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t);611}612613static int send_mpa_reply(struct c4iw_ep *ep, const void *pdata, u8 plen)614{615int mpalen, wrlen;616struct fw_ofld_tx_data_wr *req;617struct mpa_message *mpa;618struct sk_buff *skb;619620PDBG("%s ep %p tid %u pd_len %d\n", __func__, ep, ep->hwtid, ep->plen);621622mpalen = sizeof(*mpa) + plen;623wrlen = roundup(mpalen + sizeof *req, 16);624625skb = get_skb(NULL, wrlen, GFP_KERNEL);626if (!skb) {627printk(KERN_ERR MOD "%s - cannot alloc skb!\n", __func__);628return -ENOMEM;629}630set_wr_txq(skb, CPL_PRIORITY_DATA, ep->txq_idx);631632req = (struct fw_ofld_tx_data_wr *) skb_put(skb, wrlen);633memset(req, 0, wrlen);634req->op_to_immdlen = cpu_to_be32(635FW_WR_OP(FW_OFLD_TX_DATA_WR) |636FW_WR_COMPL(1) |637FW_WR_IMMDLEN(mpalen));638req->flowid_len16 = cpu_to_be32(639FW_WR_FLOWID(ep->hwtid) |640FW_WR_LEN16(wrlen >> 4));641req->plen = cpu_to_be32(mpalen);642req->tunnel_to_proxy = cpu_to_be32(643FW_OFLD_TX_DATA_WR_FLUSH(1) |644FW_OFLD_TX_DATA_WR_SHOVE(1));645646mpa = (struct mpa_message *)(req + 1);647memset(mpa, 0, sizeof(*mpa));648memcpy(mpa->key, MPA_KEY_REP, sizeof(mpa->key));649mpa->flags = (ep->mpa_attr.crc_enabled ? MPA_CRC : 0) |650(markers_enabled ? MPA_MARKERS : 0);651mpa->revision = mpa_rev;652mpa->private_data_size = htons(plen);653if (plen)654memcpy(mpa->private_data, pdata, plen);655656/*657* Reference the mpa skb. This ensures the data area658* will remain in memory until the hw acks the tx.659* Function fw4_ack() will deref it.660*/661skb_get(skb);662t4_set_arp_err_handler(skb, NULL, arp_failure_discard);663ep->mpa_skb = skb;664state_set(&ep->com, MPA_REP_SENT);665return c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t);666}667668static int act_establish(struct c4iw_dev *dev, struct sk_buff *skb)669{670struct c4iw_ep *ep;671struct cpl_act_establish *req = cplhdr(skb);672unsigned int tid = GET_TID(req);673unsigned int atid = GET_TID_TID(ntohl(req->tos_atid));674struct tid_info *t = dev->rdev.lldi.tids;675676ep = lookup_atid(t, atid);677678PDBG("%s ep %p tid %u snd_isn %u rcv_isn %u\n", __func__, ep, tid,679be32_to_cpu(req->snd_isn), be32_to_cpu(req->rcv_isn));680681dst_confirm(ep->dst);682683/* setup the hwtid for this connection */684ep->hwtid = tid;685cxgb4_insert_tid(t, ep, tid);686687ep->snd_seq = be32_to_cpu(req->snd_isn);688ep->rcv_seq = be32_to_cpu(req->rcv_isn);689690set_emss(ep, ntohs(req->tcp_opt));691692/* dealloc the atid */693cxgb4_free_atid(t, atid);694695/* start MPA negotiation */696send_flowc(ep, NULL);697send_mpa_req(ep, skb);698699return 0;700}701702static void close_complete_upcall(struct c4iw_ep *ep)703{704struct iw_cm_event event;705706PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);707memset(&event, 0, sizeof(event));708event.event = IW_CM_EVENT_CLOSE;709if (ep->com.cm_id) {710PDBG("close complete delivered ep %p cm_id %p tid %u\n",711ep, ep->com.cm_id, ep->hwtid);712ep->com.cm_id->event_handler(ep->com.cm_id, &event);713ep->com.cm_id->rem_ref(ep->com.cm_id);714ep->com.cm_id = NULL;715ep->com.qp = NULL;716}717}718719static int abort_connection(struct c4iw_ep *ep, struct sk_buff *skb, gfp_t gfp)720{721PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);722close_complete_upcall(ep);723state_set(&ep->com, ABORTING);724return send_abort(ep, skb, gfp);725}726727static void peer_close_upcall(struct c4iw_ep *ep)728{729struct iw_cm_event event;730731PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);732memset(&event, 0, sizeof(event));733event.event = IW_CM_EVENT_DISCONNECT;734if (ep->com.cm_id) {735PDBG("peer close delivered ep %p cm_id %p tid %u\n",736ep, ep->com.cm_id, ep->hwtid);737ep->com.cm_id->event_handler(ep->com.cm_id, &event);738}739}740741static void peer_abort_upcall(struct c4iw_ep *ep)742{743struct iw_cm_event event;744745PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);746memset(&event, 0, sizeof(event));747event.event = IW_CM_EVENT_CLOSE;748event.status = -ECONNRESET;749if (ep->com.cm_id) {750PDBG("abort delivered ep %p cm_id %p tid %u\n", ep,751ep->com.cm_id, ep->hwtid);752ep->com.cm_id->event_handler(ep->com.cm_id, &event);753ep->com.cm_id->rem_ref(ep->com.cm_id);754ep->com.cm_id = NULL;755ep->com.qp = NULL;756}757}758759static void connect_reply_upcall(struct c4iw_ep *ep, int status)760{761struct iw_cm_event event;762763PDBG("%s ep %p tid %u status %d\n", __func__, ep, ep->hwtid, status);764memset(&event, 0, sizeof(event));765event.event = IW_CM_EVENT_CONNECT_REPLY;766event.status = status;767event.local_addr = ep->com.local_addr;768event.remote_addr = ep->com.remote_addr;769770if ((status == 0) || (status == -ECONNREFUSED)) {771event.private_data_len = ep->plen;772event.private_data = ep->mpa_pkt + sizeof(struct mpa_message);773}774775PDBG("%s ep %p tid %u status %d\n", __func__, ep,776ep->hwtid, status);777ep->com.cm_id->event_handler(ep->com.cm_id, &event);778779if (status < 0) {780ep->com.cm_id->rem_ref(ep->com.cm_id);781ep->com.cm_id = NULL;782ep->com.qp = NULL;783}784}785786static void connect_request_upcall(struct c4iw_ep *ep)787{788struct iw_cm_event event;789790PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);791memset(&event, 0, sizeof(event));792event.event = IW_CM_EVENT_CONNECT_REQUEST;793event.local_addr = ep->com.local_addr;794event.remote_addr = ep->com.remote_addr;795event.private_data_len = ep->plen;796event.private_data = ep->mpa_pkt + sizeof(struct mpa_message);797event.provider_data = ep;798if (state_read(&ep->parent_ep->com) != DEAD) {799c4iw_get_ep(&ep->com);800ep->parent_ep->com.cm_id->event_handler(801ep->parent_ep->com.cm_id,802&event);803}804c4iw_put_ep(&ep->parent_ep->com);805ep->parent_ep = NULL;806}807808static void established_upcall(struct c4iw_ep *ep)809{810struct iw_cm_event event;811812PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);813memset(&event, 0, sizeof(event));814event.event = IW_CM_EVENT_ESTABLISHED;815if (ep->com.cm_id) {816PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);817ep->com.cm_id->event_handler(ep->com.cm_id, &event);818}819}820821static int update_rx_credits(struct c4iw_ep *ep, u32 credits)822{823struct cpl_rx_data_ack *req;824struct sk_buff *skb;825int wrlen = roundup(sizeof *req, 16);826827PDBG("%s ep %p tid %u credits %u\n", __func__, ep, ep->hwtid, credits);828skb = get_skb(NULL, wrlen, GFP_KERNEL);829if (!skb) {830printk(KERN_ERR MOD "update_rx_credits - cannot alloc skb!\n");831return 0;832}833834req = (struct cpl_rx_data_ack *) skb_put(skb, wrlen);835memset(req, 0, wrlen);836INIT_TP_WR(req, ep->hwtid);837OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_RX_DATA_ACK,838ep->hwtid));839req->credit_dack = cpu_to_be32(credits | RX_FORCE_ACK(1) |840F_RX_DACK_CHANGE |841V_RX_DACK_MODE(dack_mode));842set_wr_txq(skb, CPL_PRIORITY_ACK, ep->ctrlq_idx);843c4iw_ofld_send(&ep->com.dev->rdev, skb);844return credits;845}846847static void process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb)848{849struct mpa_message *mpa;850u16 plen;851struct c4iw_qp_attributes attrs;852enum c4iw_qp_attr_mask mask;853int err;854855PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);856857/*858* Stop mpa timer. If it expired, then the state has859* changed and we bail since ep_timeout already aborted860* the connection.861*/862stop_ep_timer(ep);863if (state_read(&ep->com) != MPA_REQ_SENT)864return;865866/*867* If we get more than the supported amount of private data868* then we must fail this connection.869*/870if (ep->mpa_pkt_len + skb->len > sizeof(ep->mpa_pkt)) {871err = -EINVAL;872goto err;873}874875/*876* copy the new data into our accumulation buffer.877*/878skb_copy_from_linear_data(skb, &(ep->mpa_pkt[ep->mpa_pkt_len]),879skb->len);880ep->mpa_pkt_len += skb->len;881882/*883* if we don't even have the mpa message, then bail.884*/885if (ep->mpa_pkt_len < sizeof(*mpa))886return;887mpa = (struct mpa_message *) ep->mpa_pkt;888889/* Validate MPA header. */890if (mpa->revision != mpa_rev) {891err = -EPROTO;892goto err;893}894if (memcmp(mpa->key, MPA_KEY_REP, sizeof(mpa->key))) {895err = -EPROTO;896goto err;897}898899plen = ntohs(mpa->private_data_size);900901/*902* Fail if there's too much private data.903*/904if (plen > MPA_MAX_PRIVATE_DATA) {905err = -EPROTO;906goto err;907}908909/*910* If plen does not account for pkt size911*/912if (ep->mpa_pkt_len > (sizeof(*mpa) + plen)) {913err = -EPROTO;914goto err;915}916917ep->plen = (u8) plen;918919/*920* If we don't have all the pdata yet, then bail.921* We'll continue process when more data arrives.922*/923if (ep->mpa_pkt_len < (sizeof(*mpa) + plen))924return;925926if (mpa->flags & MPA_REJECT) {927err = -ECONNREFUSED;928goto err;929}930931/*932* If we get here we have accumulated the entire mpa933* start reply message including private data. And934* the MPA header is valid.935*/936state_set(&ep->com, FPDU_MODE);937ep->mpa_attr.crc_enabled = (mpa->flags & MPA_CRC) | crc_enabled ? 1 : 0;938ep->mpa_attr.recv_marker_enabled = markers_enabled;939ep->mpa_attr.xmit_marker_enabled = mpa->flags & MPA_MARKERS ? 1 : 0;940ep->mpa_attr.version = mpa_rev;941ep->mpa_attr.p2p_type = peer2peer ? p2p_type :942FW_RI_INIT_P2PTYPE_DISABLED;943PDBG("%s - crc_enabled=%d, recv_marker_enabled=%d, "944"xmit_marker_enabled=%d, version=%d\n", __func__,945ep->mpa_attr.crc_enabled, ep->mpa_attr.recv_marker_enabled,946ep->mpa_attr.xmit_marker_enabled, ep->mpa_attr.version);947948attrs.mpa_attr = ep->mpa_attr;949attrs.max_ird = ep->ird;950attrs.max_ord = ep->ord;951attrs.llp_stream_handle = ep;952attrs.next_state = C4IW_QP_STATE_RTS;953954mask = C4IW_QP_ATTR_NEXT_STATE |955C4IW_QP_ATTR_LLP_STREAM_HANDLE | C4IW_QP_ATTR_MPA_ATTR |956C4IW_QP_ATTR_MAX_IRD | C4IW_QP_ATTR_MAX_ORD;957958/* bind QP and TID with INIT_WR */959err = c4iw_modify_qp(ep->com.qp->rhp,960ep->com.qp, mask, &attrs, 1);961if (err)962goto err;963goto out;964err:965state_set(&ep->com, ABORTING);966send_abort(ep, skb, GFP_KERNEL);967out:968connect_reply_upcall(ep, err);969return;970}971972static void process_mpa_request(struct c4iw_ep *ep, struct sk_buff *skb)973{974struct mpa_message *mpa;975u16 plen;976977PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);978979if (state_read(&ep->com) != MPA_REQ_WAIT)980return;981982/*983* If we get more than the supported amount of private data984* then we must fail this connection.985*/986if (ep->mpa_pkt_len + skb->len > sizeof(ep->mpa_pkt)) {987stop_ep_timer(ep);988abort_connection(ep, skb, GFP_KERNEL);989return;990}991992PDBG("%s enter (%s line %u)\n", __func__, __FILE__, __LINE__);993994/*995* Copy the new data into our accumulation buffer.996*/997skb_copy_from_linear_data(skb, &(ep->mpa_pkt[ep->mpa_pkt_len]),998skb->len);999ep->mpa_pkt_len += skb->len;10001001/*1002* If we don't even have the mpa message, then bail.1003* We'll continue process when more data arrives.1004*/1005if (ep->mpa_pkt_len < sizeof(*mpa))1006return;10071008PDBG("%s enter (%s line %u)\n", __func__, __FILE__, __LINE__);1009stop_ep_timer(ep);1010mpa = (struct mpa_message *) ep->mpa_pkt;10111012/*1013* Validate MPA Header.1014*/1015if (mpa->revision != mpa_rev) {1016abort_connection(ep, skb, GFP_KERNEL);1017return;1018}10191020if (memcmp(mpa->key, MPA_KEY_REQ, sizeof(mpa->key))) {1021abort_connection(ep, skb, GFP_KERNEL);1022return;1023}10241025plen = ntohs(mpa->private_data_size);10261027/*1028* Fail if there's too much private data.1029*/1030if (plen > MPA_MAX_PRIVATE_DATA) {1031abort_connection(ep, skb, GFP_KERNEL);1032return;1033}10341035/*1036* If plen does not account for pkt size1037*/1038if (ep->mpa_pkt_len > (sizeof(*mpa) + plen)) {1039abort_connection(ep, skb, GFP_KERNEL);1040return;1041}1042ep->plen = (u8) plen;10431044/*1045* If we don't have all the pdata yet, then bail.1046*/1047if (ep->mpa_pkt_len < (sizeof(*mpa) + plen))1048return;10491050/*1051* If we get here we have accumulated the entire mpa1052* start reply message including private data.1053*/1054ep->mpa_attr.initiator = 0;1055ep->mpa_attr.crc_enabled = (mpa->flags & MPA_CRC) | crc_enabled ? 1 : 0;1056ep->mpa_attr.recv_marker_enabled = markers_enabled;1057ep->mpa_attr.xmit_marker_enabled = mpa->flags & MPA_MARKERS ? 1 : 0;1058ep->mpa_attr.version = mpa_rev;1059ep->mpa_attr.p2p_type = peer2peer ? p2p_type :1060FW_RI_INIT_P2PTYPE_DISABLED;1061PDBG("%s - crc_enabled=%d, recv_marker_enabled=%d, "1062"xmit_marker_enabled=%d, version=%d p2p_type=%d\n", __func__,1063ep->mpa_attr.crc_enabled, ep->mpa_attr.recv_marker_enabled,1064ep->mpa_attr.xmit_marker_enabled, ep->mpa_attr.version,1065ep->mpa_attr.p2p_type);10661067state_set(&ep->com, MPA_REQ_RCVD);10681069/* drive upcall */1070connect_request_upcall(ep);1071return;1072}10731074static int rx_data(struct c4iw_dev *dev, struct sk_buff *skb)1075{1076struct c4iw_ep *ep;1077struct cpl_rx_data *hdr = cplhdr(skb);1078unsigned int dlen = ntohs(hdr->len);1079unsigned int tid = GET_TID(hdr);1080struct tid_info *t = dev->rdev.lldi.tids;10811082ep = lookup_tid(t, tid);1083PDBG("%s ep %p tid %u dlen %u\n", __func__, ep, ep->hwtid, dlen);1084skb_pull(skb, sizeof(*hdr));1085skb_trim(skb, dlen);10861087ep->rcv_seq += dlen;1088BUG_ON(ep->rcv_seq != (ntohl(hdr->seq) + dlen));10891090/* update RX credits */1091update_rx_credits(ep, dlen);10921093switch (state_read(&ep->com)) {1094case MPA_REQ_SENT:1095process_mpa_reply(ep, skb);1096break;1097case MPA_REQ_WAIT:1098process_mpa_request(ep, skb);1099break;1100case MPA_REP_SENT:1101break;1102default:1103printk(KERN_ERR MOD "%s Unexpected streaming data."1104" ep %p state %d tid %u\n",1105__func__, ep, state_read(&ep->com), ep->hwtid);11061107/*1108* The ep will timeout and inform the ULP of the failure.1109* See ep_timeout().1110*/1111break;1112}1113return 0;1114}11151116static int abort_rpl(struct c4iw_dev *dev, struct sk_buff *skb)1117{1118struct c4iw_ep *ep;1119struct cpl_abort_rpl_rss *rpl = cplhdr(skb);1120int release = 0;1121unsigned int tid = GET_TID(rpl);1122struct tid_info *t = dev->rdev.lldi.tids;11231124ep = lookup_tid(t, tid);1125PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);1126BUG_ON(!ep);1127mutex_lock(&ep->com.mutex);1128switch (ep->com.state) {1129case ABORTING:1130__state_set(&ep->com, DEAD);1131release = 1;1132break;1133default:1134printk(KERN_ERR "%s ep %p state %d\n",1135__func__, ep, ep->com.state);1136break;1137}1138mutex_unlock(&ep->com.mutex);11391140if (release)1141release_ep_resources(ep);1142return 0;1143}11441145/*1146* Return whether a failed active open has allocated a TID1147*/1148static inline int act_open_has_tid(int status)1149{1150return status != CPL_ERR_TCAM_FULL && status != CPL_ERR_CONN_EXIST &&1151status != CPL_ERR_ARP_MISS;1152}11531154static int act_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb)1155{1156struct c4iw_ep *ep;1157struct cpl_act_open_rpl *rpl = cplhdr(skb);1158unsigned int atid = GET_TID_TID(GET_AOPEN_ATID(1159ntohl(rpl->atid_status)));1160struct tid_info *t = dev->rdev.lldi.tids;1161int status = GET_AOPEN_STATUS(ntohl(rpl->atid_status));11621163ep = lookup_atid(t, atid);11641165PDBG("%s ep %p atid %u status %u errno %d\n", __func__, ep, atid,1166status, status2errno(status));11671168if (status == CPL_ERR_RTX_NEG_ADVICE) {1169printk(KERN_WARNING MOD "Connection problems for atid %u\n",1170atid);1171return 0;1172}11731174connect_reply_upcall(ep, status2errno(status));1175state_set(&ep->com, DEAD);11761177if (status && act_open_has_tid(status))1178cxgb4_remove_tid(ep->com.dev->rdev.lldi.tids, 0, GET_TID(rpl));11791180cxgb4_free_atid(t, atid);1181dst_release(ep->dst);1182cxgb4_l2t_release(ep->l2t);1183c4iw_put_ep(&ep->com);11841185return 0;1186}11871188static int pass_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb)1189{1190struct cpl_pass_open_rpl *rpl = cplhdr(skb);1191struct tid_info *t = dev->rdev.lldi.tids;1192unsigned int stid = GET_TID(rpl);1193struct c4iw_listen_ep *ep = lookup_stid(t, stid);11941195if (!ep) {1196printk(KERN_ERR MOD "stid %d lookup failure!\n", stid);1197return 0;1198}1199PDBG("%s ep %p status %d error %d\n", __func__, ep,1200rpl->status, status2errno(rpl->status));1201c4iw_wake_up(&ep->com.wr_wait, status2errno(rpl->status));12021203return 0;1204}12051206static int listen_stop(struct c4iw_listen_ep *ep)1207{1208struct sk_buff *skb;1209struct cpl_close_listsvr_req *req;12101211PDBG("%s ep %p\n", __func__, ep);1212skb = get_skb(NULL, sizeof(*req), GFP_KERNEL);1213if (!skb) {1214printk(KERN_ERR MOD "%s - failed to alloc skb\n", __func__);1215return -ENOMEM;1216}1217req = (struct cpl_close_listsvr_req *) skb_put(skb, sizeof(*req));1218INIT_TP_WR(req, 0);1219OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_CLOSE_LISTSRV_REQ,1220ep->stid));1221req->reply_ctrl = cpu_to_be16(1222QUEUENO(ep->com.dev->rdev.lldi.rxq_ids[0]));1223set_wr_txq(skb, CPL_PRIORITY_SETUP, 0);1224return c4iw_ofld_send(&ep->com.dev->rdev, skb);1225}12261227static int close_listsrv_rpl(struct c4iw_dev *dev, struct sk_buff *skb)1228{1229struct cpl_close_listsvr_rpl *rpl = cplhdr(skb);1230struct tid_info *t = dev->rdev.lldi.tids;1231unsigned int stid = GET_TID(rpl);1232struct c4iw_listen_ep *ep = lookup_stid(t, stid);12331234PDBG("%s ep %p\n", __func__, ep);1235c4iw_wake_up(&ep->com.wr_wait, status2errno(rpl->status));1236return 0;1237}12381239static void accept_cr(struct c4iw_ep *ep, __be32 peer_ip, struct sk_buff *skb,1240struct cpl_pass_accept_req *req)1241{1242struct cpl_pass_accept_rpl *rpl;1243unsigned int mtu_idx;1244u64 opt0;1245u32 opt2;1246int wscale;12471248PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);1249BUG_ON(skb_cloned(skb));1250skb_trim(skb, sizeof(*rpl));1251skb_get(skb);1252cxgb4_best_mtu(ep->com.dev->rdev.lldi.mtus, ep->mtu, &mtu_idx);1253wscale = compute_wscale(rcv_win);1254opt0 = KEEP_ALIVE(1) |1255DELACK(1) |1256WND_SCALE(wscale) |1257MSS_IDX(mtu_idx) |1258L2T_IDX(ep->l2t->idx) |1259TX_CHAN(ep->tx_chan) |1260SMAC_SEL(ep->smac_idx) |1261DSCP(ep->tos) |1262ULP_MODE(ULP_MODE_TCPDDP) |1263RCV_BUFSIZ(rcv_win>>10);1264opt2 = RX_CHANNEL(0) |1265RSS_QUEUE_VALID | RSS_QUEUE(ep->rss_qid);12661267if (enable_tcp_timestamps && req->tcpopt.tstamp)1268opt2 |= TSTAMPS_EN(1);1269if (enable_tcp_sack && req->tcpopt.sack)1270opt2 |= SACK_EN(1);1271if (wscale && enable_tcp_window_scaling)1272opt2 |= WND_SCALE_EN(1);12731274rpl = cplhdr(skb);1275INIT_TP_WR(rpl, ep->hwtid);1276OPCODE_TID(rpl) = cpu_to_be32(MK_OPCODE_TID(CPL_PASS_ACCEPT_RPL,1277ep->hwtid));1278rpl->opt0 = cpu_to_be64(opt0);1279rpl->opt2 = cpu_to_be32(opt2);1280set_wr_txq(skb, CPL_PRIORITY_SETUP, ep->ctrlq_idx);1281c4iw_l2t_send(&ep->com.dev->rdev, skb, ep->l2t);12821283return;1284}12851286static void reject_cr(struct c4iw_dev *dev, u32 hwtid, __be32 peer_ip,1287struct sk_buff *skb)1288{1289PDBG("%s c4iw_dev %p tid %u peer_ip %x\n", __func__, dev, hwtid,1290peer_ip);1291BUG_ON(skb_cloned(skb));1292skb_trim(skb, sizeof(struct cpl_tid_release));1293skb_get(skb);1294release_tid(&dev->rdev, hwtid, skb);1295return;1296}12971298static void get_4tuple(struct cpl_pass_accept_req *req,1299__be32 *local_ip, __be32 *peer_ip,1300__be16 *local_port, __be16 *peer_port)1301{1302int eth_len = G_ETH_HDR_LEN(be32_to_cpu(req->hdr_len));1303int ip_len = G_IP_HDR_LEN(be32_to_cpu(req->hdr_len));1304struct iphdr *ip = (struct iphdr *)((u8 *)(req + 1) + eth_len);1305struct tcphdr *tcp = (struct tcphdr *)1306((u8 *)(req + 1) + eth_len + ip_len);13071308PDBG("%s saddr 0x%x daddr 0x%x sport %u dport %u\n", __func__,1309ntohl(ip->saddr), ntohl(ip->daddr), ntohs(tcp->source),1310ntohs(tcp->dest));13111312*peer_ip = ip->saddr;1313*local_ip = ip->daddr;1314*peer_port = tcp->source;1315*local_port = tcp->dest;13161317return;1318}13191320static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb)1321{1322struct c4iw_ep *child_ep, *parent_ep;1323struct cpl_pass_accept_req *req = cplhdr(skb);1324unsigned int stid = GET_POPEN_TID(ntohl(req->tos_stid));1325struct tid_info *t = dev->rdev.lldi.tids;1326unsigned int hwtid = GET_TID(req);1327struct dst_entry *dst;1328struct l2t_entry *l2t;1329struct rtable *rt;1330__be32 local_ip, peer_ip;1331__be16 local_port, peer_port;1332struct net_device *pdev;1333u32 tx_chan, smac_idx;1334u16 rss_qid;1335u32 mtu;1336int step;1337int txq_idx, ctrlq_idx;13381339parent_ep = lookup_stid(t, stid);1340PDBG("%s parent ep %p tid %u\n", __func__, parent_ep, hwtid);13411342get_4tuple(req, &local_ip, &peer_ip, &local_port, &peer_port);13431344if (state_read(&parent_ep->com) != LISTEN) {1345printk(KERN_ERR "%s - listening ep not in LISTEN\n",1346__func__);1347goto reject;1348}13491350/* Find output route */1351rt = find_route(dev, local_ip, peer_ip, local_port, peer_port,1352GET_POPEN_TOS(ntohl(req->tos_stid)));1353if (!rt) {1354printk(KERN_ERR MOD "%s - failed to find dst entry!\n",1355__func__);1356goto reject;1357}1358dst = &rt->dst;1359if (dst->neighbour->dev->flags & IFF_LOOPBACK) {1360pdev = ip_dev_find(&init_net, peer_ip);1361BUG_ON(!pdev);1362l2t = cxgb4_l2t_get(dev->rdev.lldi.l2t, dst->neighbour,1363pdev, 0);1364mtu = pdev->mtu;1365tx_chan = cxgb4_port_chan(pdev);1366smac_idx = (cxgb4_port_viid(pdev) & 0x7F) << 1;1367step = dev->rdev.lldi.ntxq / dev->rdev.lldi.nchan;1368txq_idx = cxgb4_port_idx(pdev) * step;1369ctrlq_idx = cxgb4_port_idx(pdev);1370step = dev->rdev.lldi.nrxq / dev->rdev.lldi.nchan;1371rss_qid = dev->rdev.lldi.rxq_ids[cxgb4_port_idx(pdev) * step];1372dev_put(pdev);1373} else {1374l2t = cxgb4_l2t_get(dev->rdev.lldi.l2t, dst->neighbour,1375dst->neighbour->dev, 0);1376mtu = dst_mtu(dst);1377tx_chan = cxgb4_port_chan(dst->neighbour->dev);1378smac_idx = (cxgb4_port_viid(dst->neighbour->dev) & 0x7F) << 1;1379step = dev->rdev.lldi.ntxq / dev->rdev.lldi.nchan;1380txq_idx = cxgb4_port_idx(dst->neighbour->dev) * step;1381ctrlq_idx = cxgb4_port_idx(dst->neighbour->dev);1382step = dev->rdev.lldi.nrxq / dev->rdev.lldi.nchan;1383rss_qid = dev->rdev.lldi.rxq_ids[1384cxgb4_port_idx(dst->neighbour->dev) * step];1385}1386if (!l2t) {1387printk(KERN_ERR MOD "%s - failed to allocate l2t entry!\n",1388__func__);1389dst_release(dst);1390goto reject;1391}13921393child_ep = alloc_ep(sizeof(*child_ep), GFP_KERNEL);1394if (!child_ep) {1395printk(KERN_ERR MOD "%s - failed to allocate ep entry!\n",1396__func__);1397cxgb4_l2t_release(l2t);1398dst_release(dst);1399goto reject;1400}1401state_set(&child_ep->com, CONNECTING);1402child_ep->com.dev = dev;1403child_ep->com.cm_id = NULL;1404child_ep->com.local_addr.sin_family = PF_INET;1405child_ep->com.local_addr.sin_port = local_port;1406child_ep->com.local_addr.sin_addr.s_addr = local_ip;1407child_ep->com.remote_addr.sin_family = PF_INET;1408child_ep->com.remote_addr.sin_port = peer_port;1409child_ep->com.remote_addr.sin_addr.s_addr = peer_ip;1410c4iw_get_ep(&parent_ep->com);1411child_ep->parent_ep = parent_ep;1412child_ep->tos = GET_POPEN_TOS(ntohl(req->tos_stid));1413child_ep->l2t = l2t;1414child_ep->dst = dst;1415child_ep->hwtid = hwtid;1416child_ep->tx_chan = tx_chan;1417child_ep->smac_idx = smac_idx;1418child_ep->rss_qid = rss_qid;1419child_ep->mtu = mtu;1420child_ep->txq_idx = txq_idx;1421child_ep->ctrlq_idx = ctrlq_idx;14221423PDBG("%s tx_chan %u smac_idx %u rss_qid %u\n", __func__,1424tx_chan, smac_idx, rss_qid);14251426init_timer(&child_ep->timer);1427cxgb4_insert_tid(t, child_ep, hwtid);1428accept_cr(child_ep, peer_ip, skb, req);1429goto out;1430reject:1431reject_cr(dev, hwtid, peer_ip, skb);1432out:1433return 0;1434}14351436static int pass_establish(struct c4iw_dev *dev, struct sk_buff *skb)1437{1438struct c4iw_ep *ep;1439struct cpl_pass_establish *req = cplhdr(skb);1440struct tid_info *t = dev->rdev.lldi.tids;1441unsigned int tid = GET_TID(req);14421443ep = lookup_tid(t, tid);1444PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);1445ep->snd_seq = be32_to_cpu(req->snd_isn);1446ep->rcv_seq = be32_to_cpu(req->rcv_isn);14471448set_emss(ep, ntohs(req->tcp_opt));14491450dst_confirm(ep->dst);1451state_set(&ep->com, MPA_REQ_WAIT);1452start_ep_timer(ep);1453send_flowc(ep, skb);14541455return 0;1456}14571458static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb)1459{1460struct cpl_peer_close *hdr = cplhdr(skb);1461struct c4iw_ep *ep;1462struct c4iw_qp_attributes attrs;1463int disconnect = 1;1464int release = 0;1465struct tid_info *t = dev->rdev.lldi.tids;1466unsigned int tid = GET_TID(hdr);1467int ret;14681469ep = lookup_tid(t, tid);1470PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);1471dst_confirm(ep->dst);14721473mutex_lock(&ep->com.mutex);1474switch (ep->com.state) {1475case MPA_REQ_WAIT:1476__state_set(&ep->com, CLOSING);1477break;1478case MPA_REQ_SENT:1479__state_set(&ep->com, CLOSING);1480connect_reply_upcall(ep, -ECONNRESET);1481break;1482case MPA_REQ_RCVD:14831484/*1485* We're gonna mark this puppy DEAD, but keep1486* the reference on it until the ULP accepts or1487* rejects the CR. Also wake up anyone waiting1488* in rdma connection migration (see c4iw_accept_cr()).1489*/1490__state_set(&ep->com, CLOSING);1491PDBG("waking up ep %p tid %u\n", ep, ep->hwtid);1492c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET);1493break;1494case MPA_REP_SENT:1495__state_set(&ep->com, CLOSING);1496PDBG("waking up ep %p tid %u\n", ep, ep->hwtid);1497c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET);1498break;1499case FPDU_MODE:1500start_ep_timer(ep);1501__state_set(&ep->com, CLOSING);1502attrs.next_state = C4IW_QP_STATE_CLOSING;1503ret = c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,1504C4IW_QP_ATTR_NEXT_STATE, &attrs, 1);1505if (ret != -ECONNRESET) {1506peer_close_upcall(ep);1507disconnect = 1;1508}1509break;1510case ABORTING:1511disconnect = 0;1512break;1513case CLOSING:1514__state_set(&ep->com, MORIBUND);1515disconnect = 0;1516break;1517case MORIBUND:1518stop_ep_timer(ep);1519if (ep->com.cm_id && ep->com.qp) {1520attrs.next_state = C4IW_QP_STATE_IDLE;1521c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,1522C4IW_QP_ATTR_NEXT_STATE, &attrs, 1);1523}1524close_complete_upcall(ep);1525__state_set(&ep->com, DEAD);1526release = 1;1527disconnect = 0;1528break;1529case DEAD:1530disconnect = 0;1531break;1532default:1533BUG_ON(1);1534}1535mutex_unlock(&ep->com.mutex);1536if (disconnect)1537c4iw_ep_disconnect(ep, 0, GFP_KERNEL);1538if (release)1539release_ep_resources(ep);1540return 0;1541}15421543/*1544* Returns whether an ABORT_REQ_RSS message is a negative advice.1545*/1546static int is_neg_adv_abort(unsigned int status)1547{1548return status == CPL_ERR_RTX_NEG_ADVICE ||1549status == CPL_ERR_PERSIST_NEG_ADVICE;1550}15511552static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb)1553{1554struct cpl_abort_req_rss *req = cplhdr(skb);1555struct c4iw_ep *ep;1556struct cpl_abort_rpl *rpl;1557struct sk_buff *rpl_skb;1558struct c4iw_qp_attributes attrs;1559int ret;1560int release = 0;1561struct tid_info *t = dev->rdev.lldi.tids;1562unsigned int tid = GET_TID(req);15631564ep = lookup_tid(t, tid);1565if (is_neg_adv_abort(req->status)) {1566PDBG("%s neg_adv_abort ep %p tid %u\n", __func__, ep,1567ep->hwtid);1568return 0;1569}1570PDBG("%s ep %p tid %u state %u\n", __func__, ep, ep->hwtid,1571ep->com.state);15721573/*1574* Wake up any threads in rdma_init() or rdma_fini().1575*/1576c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET);15771578mutex_lock(&ep->com.mutex);1579switch (ep->com.state) {1580case CONNECTING:1581break;1582case MPA_REQ_WAIT:1583stop_ep_timer(ep);1584break;1585case MPA_REQ_SENT:1586stop_ep_timer(ep);1587connect_reply_upcall(ep, -ECONNRESET);1588break;1589case MPA_REP_SENT:1590break;1591case MPA_REQ_RCVD:1592break;1593case MORIBUND:1594case CLOSING:1595stop_ep_timer(ep);1596/*FALLTHROUGH*/1597case FPDU_MODE:1598if (ep->com.cm_id && ep->com.qp) {1599attrs.next_state = C4IW_QP_STATE_ERROR;1600ret = c4iw_modify_qp(ep->com.qp->rhp,1601ep->com.qp, C4IW_QP_ATTR_NEXT_STATE,1602&attrs, 1);1603if (ret)1604printk(KERN_ERR MOD1605"%s - qp <- error failed!\n",1606__func__);1607}1608peer_abort_upcall(ep);1609break;1610case ABORTING:1611break;1612case DEAD:1613PDBG("%s PEER_ABORT IN DEAD STATE!!!!\n", __func__);1614mutex_unlock(&ep->com.mutex);1615return 0;1616default:1617BUG_ON(1);1618break;1619}1620dst_confirm(ep->dst);1621if (ep->com.state != ABORTING) {1622__state_set(&ep->com, DEAD);1623release = 1;1624}1625mutex_unlock(&ep->com.mutex);16261627rpl_skb = get_skb(skb, sizeof(*rpl), GFP_KERNEL);1628if (!rpl_skb) {1629printk(KERN_ERR MOD "%s - cannot allocate skb!\n",1630__func__);1631release = 1;1632goto out;1633}1634set_wr_txq(skb, CPL_PRIORITY_DATA, ep->txq_idx);1635rpl = (struct cpl_abort_rpl *) skb_put(rpl_skb, sizeof(*rpl));1636INIT_TP_WR(rpl, ep->hwtid);1637OPCODE_TID(rpl) = cpu_to_be32(MK_OPCODE_TID(CPL_ABORT_RPL, ep->hwtid));1638rpl->cmd = CPL_ABORT_NO_RST;1639c4iw_ofld_send(&ep->com.dev->rdev, rpl_skb);1640out:1641if (release)1642release_ep_resources(ep);1643return 0;1644}16451646static int close_con_rpl(struct c4iw_dev *dev, struct sk_buff *skb)1647{1648struct c4iw_ep *ep;1649struct c4iw_qp_attributes attrs;1650struct cpl_close_con_rpl *rpl = cplhdr(skb);1651int release = 0;1652struct tid_info *t = dev->rdev.lldi.tids;1653unsigned int tid = GET_TID(rpl);16541655ep = lookup_tid(t, tid);16561657PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);1658BUG_ON(!ep);16591660/* The cm_id may be null if we failed to connect */1661mutex_lock(&ep->com.mutex);1662switch (ep->com.state) {1663case CLOSING:1664__state_set(&ep->com, MORIBUND);1665break;1666case MORIBUND:1667stop_ep_timer(ep);1668if ((ep->com.cm_id) && (ep->com.qp)) {1669attrs.next_state = C4IW_QP_STATE_IDLE;1670c4iw_modify_qp(ep->com.qp->rhp,1671ep->com.qp,1672C4IW_QP_ATTR_NEXT_STATE,1673&attrs, 1);1674}1675close_complete_upcall(ep);1676__state_set(&ep->com, DEAD);1677release = 1;1678break;1679case ABORTING:1680case DEAD:1681break;1682default:1683BUG_ON(1);1684break;1685}1686mutex_unlock(&ep->com.mutex);1687if (release)1688release_ep_resources(ep);1689return 0;1690}16911692static int terminate(struct c4iw_dev *dev, struct sk_buff *skb)1693{1694struct cpl_rdma_terminate *rpl = cplhdr(skb);1695struct tid_info *t = dev->rdev.lldi.tids;1696unsigned int tid = GET_TID(rpl);1697struct c4iw_ep *ep;1698struct c4iw_qp_attributes attrs;16991700ep = lookup_tid(t, tid);1701BUG_ON(!ep);17021703if (ep && ep->com.qp) {1704printk(KERN_WARNING MOD "TERM received tid %u qpid %u\n", tid,1705ep->com.qp->wq.sq.qid);1706attrs.next_state = C4IW_QP_STATE_TERMINATE;1707c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,1708C4IW_QP_ATTR_NEXT_STATE, &attrs, 1);1709} else1710printk(KERN_WARNING MOD "TERM received tid %u no ep/qp\n", tid);17111712return 0;1713}17141715/*1716* Upcall from the adapter indicating data has been transmitted.1717* For us its just the single MPA request or reply. We can now free1718* the skb holding the mpa message.1719*/1720static int fw4_ack(struct c4iw_dev *dev, struct sk_buff *skb)1721{1722struct c4iw_ep *ep;1723struct cpl_fw4_ack *hdr = cplhdr(skb);1724u8 credits = hdr->credits;1725unsigned int tid = GET_TID(hdr);1726struct tid_info *t = dev->rdev.lldi.tids;172717281729ep = lookup_tid(t, tid);1730PDBG("%s ep %p tid %u credits %u\n", __func__, ep, ep->hwtid, credits);1731if (credits == 0) {1732PDBG("%s 0 credit ack ep %p tid %u state %u\n",1733__func__, ep, ep->hwtid, state_read(&ep->com));1734return 0;1735}17361737dst_confirm(ep->dst);1738if (ep->mpa_skb) {1739PDBG("%s last streaming msg ack ep %p tid %u state %u "1740"initiator %u freeing skb\n", __func__, ep, ep->hwtid,1741state_read(&ep->com), ep->mpa_attr.initiator ? 1 : 0);1742kfree_skb(ep->mpa_skb);1743ep->mpa_skb = NULL;1744}1745return 0;1746}17471748int c4iw_reject_cr(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len)1749{1750int err;1751struct c4iw_ep *ep = to_ep(cm_id);1752PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);17531754if (state_read(&ep->com) == DEAD) {1755c4iw_put_ep(&ep->com);1756return -ECONNRESET;1757}1758BUG_ON(state_read(&ep->com) != MPA_REQ_RCVD);1759if (mpa_rev == 0)1760abort_connection(ep, NULL, GFP_KERNEL);1761else {1762err = send_mpa_reject(ep, pdata, pdata_len);1763err = c4iw_ep_disconnect(ep, 0, GFP_KERNEL);1764}1765c4iw_put_ep(&ep->com);1766return 0;1767}17681769int c4iw_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)1770{1771int err;1772struct c4iw_qp_attributes attrs;1773enum c4iw_qp_attr_mask mask;1774struct c4iw_ep *ep = to_ep(cm_id);1775struct c4iw_dev *h = to_c4iw_dev(cm_id->device);1776struct c4iw_qp *qp = get_qhp(h, conn_param->qpn);17771778PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);1779if (state_read(&ep->com) == DEAD) {1780err = -ECONNRESET;1781goto err;1782}17831784BUG_ON(state_read(&ep->com) != MPA_REQ_RCVD);1785BUG_ON(!qp);17861787if ((conn_param->ord > c4iw_max_read_depth) ||1788(conn_param->ird > c4iw_max_read_depth)) {1789abort_connection(ep, NULL, GFP_KERNEL);1790err = -EINVAL;1791goto err;1792}17931794cm_id->add_ref(cm_id);1795ep->com.cm_id = cm_id;1796ep->com.qp = qp;17971798ep->ird = conn_param->ird;1799ep->ord = conn_param->ord;18001801if (peer2peer && ep->ird == 0)1802ep->ird = 1;18031804PDBG("%s %d ird %d ord %d\n", __func__, __LINE__, ep->ird, ep->ord);18051806/* bind QP to EP and move to RTS */1807attrs.mpa_attr = ep->mpa_attr;1808attrs.max_ird = ep->ird;1809attrs.max_ord = ep->ord;1810attrs.llp_stream_handle = ep;1811attrs.next_state = C4IW_QP_STATE_RTS;18121813/* bind QP and TID with INIT_WR */1814mask = C4IW_QP_ATTR_NEXT_STATE |1815C4IW_QP_ATTR_LLP_STREAM_HANDLE |1816C4IW_QP_ATTR_MPA_ATTR |1817C4IW_QP_ATTR_MAX_IRD |1818C4IW_QP_ATTR_MAX_ORD;18191820err = c4iw_modify_qp(ep->com.qp->rhp,1821ep->com.qp, mask, &attrs, 1);1822if (err)1823goto err1;1824err = send_mpa_reply(ep, conn_param->private_data,1825conn_param->private_data_len);1826if (err)1827goto err1;18281829state_set(&ep->com, FPDU_MODE);1830established_upcall(ep);1831c4iw_put_ep(&ep->com);1832return 0;1833err1:1834ep->com.cm_id = NULL;1835ep->com.qp = NULL;1836cm_id->rem_ref(cm_id);1837err:1838c4iw_put_ep(&ep->com);1839return err;1840}18411842int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)1843{1844int err = 0;1845struct c4iw_dev *dev = to_c4iw_dev(cm_id->device);1846struct c4iw_ep *ep;1847struct rtable *rt;1848struct net_device *pdev;1849int step;18501851if ((conn_param->ord > c4iw_max_read_depth) ||1852(conn_param->ird > c4iw_max_read_depth)) {1853err = -EINVAL;1854goto out;1855}1856ep = alloc_ep(sizeof(*ep), GFP_KERNEL);1857if (!ep) {1858printk(KERN_ERR MOD "%s - cannot alloc ep.\n", __func__);1859err = -ENOMEM;1860goto out;1861}1862init_timer(&ep->timer);1863ep->plen = conn_param->private_data_len;1864if (ep->plen)1865memcpy(ep->mpa_pkt + sizeof(struct mpa_message),1866conn_param->private_data, ep->plen);1867ep->ird = conn_param->ird;1868ep->ord = conn_param->ord;18691870if (peer2peer && ep->ord == 0)1871ep->ord = 1;18721873cm_id->add_ref(cm_id);1874ep->com.dev = dev;1875ep->com.cm_id = cm_id;1876ep->com.qp = get_qhp(dev, conn_param->qpn);1877BUG_ON(!ep->com.qp);1878PDBG("%s qpn 0x%x qp %p cm_id %p\n", __func__, conn_param->qpn,1879ep->com.qp, cm_id);18801881/*1882* Allocate an active TID to initiate a TCP connection.1883*/1884ep->atid = cxgb4_alloc_atid(dev->rdev.lldi.tids, ep);1885if (ep->atid == -1) {1886printk(KERN_ERR MOD "%s - cannot alloc atid.\n", __func__);1887err = -ENOMEM;1888goto fail2;1889}18901891PDBG("%s saddr 0x%x sport 0x%x raddr 0x%x rport 0x%x\n", __func__,1892ntohl(cm_id->local_addr.sin_addr.s_addr),1893ntohs(cm_id->local_addr.sin_port),1894ntohl(cm_id->remote_addr.sin_addr.s_addr),1895ntohs(cm_id->remote_addr.sin_port));18961897/* find a route */1898rt = find_route(dev,1899cm_id->local_addr.sin_addr.s_addr,1900cm_id->remote_addr.sin_addr.s_addr,1901cm_id->local_addr.sin_port,1902cm_id->remote_addr.sin_port, 0);1903if (!rt) {1904printk(KERN_ERR MOD "%s - cannot find route.\n", __func__);1905err = -EHOSTUNREACH;1906goto fail3;1907}1908ep->dst = &rt->dst;19091910/* get a l2t entry */1911if (ep->dst->neighbour->dev->flags & IFF_LOOPBACK) {1912PDBG("%s LOOPBACK\n", __func__);1913pdev = ip_dev_find(&init_net,1914cm_id->remote_addr.sin_addr.s_addr);1915ep->l2t = cxgb4_l2t_get(ep->com.dev->rdev.lldi.l2t,1916ep->dst->neighbour,1917pdev, 0);1918ep->mtu = pdev->mtu;1919ep->tx_chan = cxgb4_port_chan(pdev);1920ep->smac_idx = (cxgb4_port_viid(pdev) & 0x7F) << 1;1921step = ep->com.dev->rdev.lldi.ntxq /1922ep->com.dev->rdev.lldi.nchan;1923ep->txq_idx = cxgb4_port_idx(pdev) * step;1924step = ep->com.dev->rdev.lldi.nrxq /1925ep->com.dev->rdev.lldi.nchan;1926ep->ctrlq_idx = cxgb4_port_idx(pdev);1927ep->rss_qid = ep->com.dev->rdev.lldi.rxq_ids[1928cxgb4_port_idx(pdev) * step];1929dev_put(pdev);1930} else {1931ep->l2t = cxgb4_l2t_get(ep->com.dev->rdev.lldi.l2t,1932ep->dst->neighbour,1933ep->dst->neighbour->dev, 0);1934ep->mtu = dst_mtu(ep->dst);1935ep->tx_chan = cxgb4_port_chan(ep->dst->neighbour->dev);1936ep->smac_idx = (cxgb4_port_viid(ep->dst->neighbour->dev) &19370x7F) << 1;1938step = ep->com.dev->rdev.lldi.ntxq /1939ep->com.dev->rdev.lldi.nchan;1940ep->txq_idx = cxgb4_port_idx(ep->dst->neighbour->dev) * step;1941ep->ctrlq_idx = cxgb4_port_idx(ep->dst->neighbour->dev);1942step = ep->com.dev->rdev.lldi.nrxq /1943ep->com.dev->rdev.lldi.nchan;1944ep->rss_qid = ep->com.dev->rdev.lldi.rxq_ids[1945cxgb4_port_idx(ep->dst->neighbour->dev) * step];1946}1947if (!ep->l2t) {1948printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__);1949err = -ENOMEM;1950goto fail4;1951}19521953PDBG("%s txq_idx %u tx_chan %u smac_idx %u rss_qid %u l2t_idx %u\n",1954__func__, ep->txq_idx, ep->tx_chan, ep->smac_idx, ep->rss_qid,1955ep->l2t->idx);19561957state_set(&ep->com, CONNECTING);1958ep->tos = 0;1959ep->com.local_addr = cm_id->local_addr;1960ep->com.remote_addr = cm_id->remote_addr;19611962/* send connect request to rnic */1963err = send_connect(ep);1964if (!err)1965goto out;19661967cxgb4_l2t_release(ep->l2t);1968fail4:1969dst_release(ep->dst);1970fail3:1971cxgb4_free_atid(ep->com.dev->rdev.lldi.tids, ep->atid);1972fail2:1973cm_id->rem_ref(cm_id);1974c4iw_put_ep(&ep->com);1975out:1976return err;1977}19781979int c4iw_create_listen(struct iw_cm_id *cm_id, int backlog)1980{1981int err = 0;1982struct c4iw_dev *dev = to_c4iw_dev(cm_id->device);1983struct c4iw_listen_ep *ep;198419851986might_sleep();19871988ep = alloc_ep(sizeof(*ep), GFP_KERNEL);1989if (!ep) {1990printk(KERN_ERR MOD "%s - cannot alloc ep.\n", __func__);1991err = -ENOMEM;1992goto fail1;1993}1994PDBG("%s ep %p\n", __func__, ep);1995cm_id->add_ref(cm_id);1996ep->com.cm_id = cm_id;1997ep->com.dev = dev;1998ep->backlog = backlog;1999ep->com.local_addr = cm_id->local_addr;20002001/*2002* Allocate a server TID.2003*/2004ep->stid = cxgb4_alloc_stid(dev->rdev.lldi.tids, PF_INET, ep);2005if (ep->stid == -1) {2006printk(KERN_ERR MOD "%s - cannot alloc stid.\n", __func__);2007err = -ENOMEM;2008goto fail2;2009}20102011state_set(&ep->com, LISTEN);2012c4iw_init_wr_wait(&ep->com.wr_wait);2013err = cxgb4_create_server(ep->com.dev->rdev.lldi.ports[0], ep->stid,2014ep->com.local_addr.sin_addr.s_addr,2015ep->com.local_addr.sin_port,2016ep->com.dev->rdev.lldi.rxq_ids[0]);2017if (err)2018goto fail3;20192020/* wait for pass_open_rpl */2021err = c4iw_wait_for_reply(&ep->com.dev->rdev, &ep->com.wr_wait, 0, 0,2022__func__);2023if (!err) {2024cm_id->provider_data = ep;2025goto out;2026}2027fail3:2028cxgb4_free_stid(ep->com.dev->rdev.lldi.tids, ep->stid, PF_INET);2029fail2:2030cm_id->rem_ref(cm_id);2031c4iw_put_ep(&ep->com);2032fail1:2033out:2034return err;2035}20362037int c4iw_destroy_listen(struct iw_cm_id *cm_id)2038{2039int err;2040struct c4iw_listen_ep *ep = to_listen_ep(cm_id);20412042PDBG("%s ep %p\n", __func__, ep);20432044might_sleep();2045state_set(&ep->com, DEAD);2046c4iw_init_wr_wait(&ep->com.wr_wait);2047err = listen_stop(ep);2048if (err)2049goto done;2050err = c4iw_wait_for_reply(&ep->com.dev->rdev, &ep->com.wr_wait, 0, 0,2051__func__);2052cxgb4_free_stid(ep->com.dev->rdev.lldi.tids, ep->stid, PF_INET);2053done:2054cm_id->rem_ref(cm_id);2055c4iw_put_ep(&ep->com);2056return err;2057}20582059int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp)2060{2061int ret = 0;2062int close = 0;2063int fatal = 0;2064struct c4iw_rdev *rdev;20652066mutex_lock(&ep->com.mutex);20672068PDBG("%s ep %p state %s, abrupt %d\n", __func__, ep,2069states[ep->com.state], abrupt);20702071rdev = &ep->com.dev->rdev;2072if (c4iw_fatal_error(rdev)) {2073fatal = 1;2074close_complete_upcall(ep);2075ep->com.state = DEAD;2076}2077switch (ep->com.state) {2078case MPA_REQ_WAIT:2079case MPA_REQ_SENT:2080case MPA_REQ_RCVD:2081case MPA_REP_SENT:2082case FPDU_MODE:2083close = 1;2084if (abrupt)2085ep->com.state = ABORTING;2086else {2087ep->com.state = CLOSING;2088start_ep_timer(ep);2089}2090set_bit(CLOSE_SENT, &ep->com.flags);2091break;2092case CLOSING:2093if (!test_and_set_bit(CLOSE_SENT, &ep->com.flags)) {2094close = 1;2095if (abrupt) {2096stop_ep_timer(ep);2097ep->com.state = ABORTING;2098} else2099ep->com.state = MORIBUND;2100}2101break;2102case MORIBUND:2103case ABORTING:2104case DEAD:2105PDBG("%s ignoring disconnect ep %p state %u\n",2106__func__, ep, ep->com.state);2107break;2108default:2109BUG();2110break;2111}21122113if (close) {2114if (abrupt) {2115close_complete_upcall(ep);2116ret = send_abort(ep, NULL, gfp);2117} else2118ret = send_halfclose(ep, gfp);2119if (ret)2120fatal = 1;2121}2122mutex_unlock(&ep->com.mutex);2123if (fatal)2124release_ep_resources(ep);2125return ret;2126}21272128static int async_event(struct c4iw_dev *dev, struct sk_buff *skb)2129{2130struct cpl_fw6_msg *rpl = cplhdr(skb);2131c4iw_ev_dispatch(dev, (struct t4_cqe *)&rpl->data[0]);2132return 0;2133}21342135/*2136* These are the real handlers that are called from a2137* work queue.2138*/2139static c4iw_handler_func work_handlers[NUM_CPL_CMDS] = {2140[CPL_ACT_ESTABLISH] = act_establish,2141[CPL_ACT_OPEN_RPL] = act_open_rpl,2142[CPL_RX_DATA] = rx_data,2143[CPL_ABORT_RPL_RSS] = abort_rpl,2144[CPL_ABORT_RPL] = abort_rpl,2145[CPL_PASS_OPEN_RPL] = pass_open_rpl,2146[CPL_CLOSE_LISTSRV_RPL] = close_listsrv_rpl,2147[CPL_PASS_ACCEPT_REQ] = pass_accept_req,2148[CPL_PASS_ESTABLISH] = pass_establish,2149[CPL_PEER_CLOSE] = peer_close,2150[CPL_ABORT_REQ_RSS] = peer_abort,2151[CPL_CLOSE_CON_RPL] = close_con_rpl,2152[CPL_RDMA_TERMINATE] = terminate,2153[CPL_FW4_ACK] = fw4_ack,2154[CPL_FW6_MSG] = async_event2155};21562157static void process_timeout(struct c4iw_ep *ep)2158{2159struct c4iw_qp_attributes attrs;2160int abort = 1;21612162mutex_lock(&ep->com.mutex);2163PDBG("%s ep %p tid %u state %d\n", __func__, ep, ep->hwtid,2164ep->com.state);2165switch (ep->com.state) {2166case MPA_REQ_SENT:2167__state_set(&ep->com, ABORTING);2168connect_reply_upcall(ep, -ETIMEDOUT);2169break;2170case MPA_REQ_WAIT:2171__state_set(&ep->com, ABORTING);2172break;2173case CLOSING:2174case MORIBUND:2175if (ep->com.cm_id && ep->com.qp) {2176attrs.next_state = C4IW_QP_STATE_ERROR;2177c4iw_modify_qp(ep->com.qp->rhp,2178ep->com.qp, C4IW_QP_ATTR_NEXT_STATE,2179&attrs, 1);2180}2181__state_set(&ep->com, ABORTING);2182break;2183default:2184printk(KERN_ERR "%s unexpected state ep %p tid %u state %u\n",2185__func__, ep, ep->hwtid, ep->com.state);2186WARN_ON(1);2187abort = 0;2188}2189mutex_unlock(&ep->com.mutex);2190if (abort)2191abort_connection(ep, NULL, GFP_KERNEL);2192c4iw_put_ep(&ep->com);2193}21942195static void process_timedout_eps(void)2196{2197struct c4iw_ep *ep;21982199spin_lock_irq(&timeout_lock);2200while (!list_empty(&timeout_list)) {2201struct list_head *tmp;22022203tmp = timeout_list.next;2204list_del(tmp);2205spin_unlock_irq(&timeout_lock);2206ep = list_entry(tmp, struct c4iw_ep, entry);2207process_timeout(ep);2208spin_lock_irq(&timeout_lock);2209}2210spin_unlock_irq(&timeout_lock);2211}22122213static void process_work(struct work_struct *work)2214{2215struct sk_buff *skb = NULL;2216struct c4iw_dev *dev;2217struct cpl_act_establish *rpl;2218unsigned int opcode;2219int ret;22202221while ((skb = skb_dequeue(&rxq))) {2222rpl = cplhdr(skb);2223dev = *((struct c4iw_dev **) (skb->cb + sizeof(void *)));2224opcode = rpl->ot.opcode;22252226BUG_ON(!work_handlers[opcode]);2227ret = work_handlers[opcode](dev, skb);2228if (!ret)2229kfree_skb(skb);2230}2231process_timedout_eps();2232}22332234static DECLARE_WORK(skb_work, process_work);22352236static void ep_timeout(unsigned long arg)2237{2238struct c4iw_ep *ep = (struct c4iw_ep *)arg;22392240spin_lock(&timeout_lock);2241list_add_tail(&ep->entry, &timeout_list);2242spin_unlock(&timeout_lock);2243queue_work(workq, &skb_work);2244}22452246/*2247* All the CM events are handled on a work queue to have a safe context.2248*/2249static int sched(struct c4iw_dev *dev, struct sk_buff *skb)2250{22512252/*2253* Save dev in the skb->cb area.2254*/2255*((struct c4iw_dev **) (skb->cb + sizeof(void *))) = dev;22562257/*2258* Queue the skb and schedule the worker thread.2259*/2260skb_queue_tail(&rxq, skb);2261queue_work(workq, &skb_work);2262return 0;2263}22642265static int set_tcb_rpl(struct c4iw_dev *dev, struct sk_buff *skb)2266{2267struct cpl_set_tcb_rpl *rpl = cplhdr(skb);22682269if (rpl->status != CPL_ERR_NONE) {2270printk(KERN_ERR MOD "Unexpected SET_TCB_RPL status %u "2271"for tid %u\n", rpl->status, GET_TID(rpl));2272}2273kfree_skb(skb);2274return 0;2275}22762277static int fw6_msg(struct c4iw_dev *dev, struct sk_buff *skb)2278{2279struct cpl_fw6_msg *rpl = cplhdr(skb);2280struct c4iw_wr_wait *wr_waitp;2281int ret;22822283PDBG("%s type %u\n", __func__, rpl->type);22842285switch (rpl->type) {2286case 1:2287ret = (int)((be64_to_cpu(rpl->data[0]) >> 8) & 0xff);2288wr_waitp = (struct c4iw_wr_wait *)(__force unsigned long) rpl->data[1];2289PDBG("%s wr_waitp %p ret %u\n", __func__, wr_waitp, ret);2290if (wr_waitp)2291c4iw_wake_up(wr_waitp, ret ? -ret : 0);2292kfree_skb(skb);2293break;2294case 2:2295sched(dev, skb);2296break;2297default:2298printk(KERN_ERR MOD "%s unexpected fw6 msg type %u\n", __func__,2299rpl->type);2300kfree_skb(skb);2301break;2302}2303return 0;2304}23052306static int peer_abort_intr(struct c4iw_dev *dev, struct sk_buff *skb)2307{2308struct cpl_abort_req_rss *req = cplhdr(skb);2309struct c4iw_ep *ep;2310struct tid_info *t = dev->rdev.lldi.tids;2311unsigned int tid = GET_TID(req);23122313ep = lookup_tid(t, tid);2314if (is_neg_adv_abort(req->status)) {2315PDBG("%s neg_adv_abort ep %p tid %u\n", __func__, ep,2316ep->hwtid);2317kfree_skb(skb);2318return 0;2319}2320PDBG("%s ep %p tid %u state %u\n", __func__, ep, ep->hwtid,2321ep->com.state);23222323/*2324* Wake up any threads in rdma_init() or rdma_fini().2325*/2326c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET);2327sched(dev, skb);2328return 0;2329}23302331/*2332* Most upcalls from the T4 Core go to sched() to2333* schedule the processing on a work queue.2334*/2335c4iw_handler_func c4iw_handlers[NUM_CPL_CMDS] = {2336[CPL_ACT_ESTABLISH] = sched,2337[CPL_ACT_OPEN_RPL] = sched,2338[CPL_RX_DATA] = sched,2339[CPL_ABORT_RPL_RSS] = sched,2340[CPL_ABORT_RPL] = sched,2341[CPL_PASS_OPEN_RPL] = sched,2342[CPL_CLOSE_LISTSRV_RPL] = sched,2343[CPL_PASS_ACCEPT_REQ] = sched,2344[CPL_PASS_ESTABLISH] = sched,2345[CPL_PEER_CLOSE] = sched,2346[CPL_CLOSE_CON_RPL] = sched,2347[CPL_ABORT_REQ_RSS] = peer_abort_intr,2348[CPL_RDMA_TERMINATE] = sched,2349[CPL_FW4_ACK] = sched,2350[CPL_SET_TCB_RPL] = set_tcb_rpl,2351[CPL_FW6_MSG] = fw6_msg2352};23532354int __init c4iw_cm_init(void)2355{2356spin_lock_init(&timeout_lock);2357skb_queue_head_init(&rxq);23582359workq = create_singlethread_workqueue("iw_cxgb4");2360if (!workq)2361return -ENOMEM;23622363return 0;2364}23652366void __exit c4iw_cm_term(void)2367{2368WARN_ON(!list_empty(&timeout_list));2369flush_workqueue(workq);2370destroy_workqueue(workq);2371}237223732374