Showing error 1627

User: Jiri Slaby
Error type: Invalid Pointer Dereference
Error type description: A pointer which is invalid is being dereferenced
File location: drivers/infiniband/hw/nes/nes_cm.c
Line in file: 1891
Project: Linux Kernel
Project version: 2.6.28
Tools: Smatch (1.59)
Entered: 2013-09-10 07:54:05 UTC


Source:

   1/*
   2 * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
   3 *
   4 * This software is available to you under a choice of one of two
   5 * licenses.  You may choose to be licensed under the terms of the GNU
   6 * General Public License (GPL) Version 2, available from the file
   7 * COPYING in the main directory of this source tree, or the
   8 * OpenIB.org BSD license below:
   9 *
  10 *     Redistribution and use in source and binary forms, with or
  11 *     without modification, are permitted provided that the following
  12 *     conditions are met:
  13 *
  14 *      - Redistributions of source code must retain the above
  15 *        copyright notice, this list of conditions and the following
  16 *        disclaimer.
  17 *
  18 *      - Redistributions in binary form must reproduce the above
  19 *        copyright notice, this list of conditions and the following
  20 *        disclaimer in the documentation and/or other materials
  21 *        provided with the distribution.
  22 *
  23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  30 * SOFTWARE.
  31 *
  32 */
  33
  34
  35#define TCPOPT_TIMESTAMP 8
  36
  37#include <asm/atomic.h>
  38#include <linux/skbuff.h>
  39#include <linux/ip.h>
  40#include <linux/tcp.h>
  41#include <linux/init.h>
  42#include <linux/if_arp.h>
  43#include <linux/if_vlan.h>
  44#include <linux/notifier.h>
  45#include <linux/net.h>
  46#include <linux/types.h>
  47#include <linux/timer.h>
  48#include <linux/time.h>
  49#include <linux/delay.h>
  50#include <linux/etherdevice.h>
  51#include <linux/netdevice.h>
  52#include <linux/random.h>
  53#include <linux/list.h>
  54#include <linux/threads.h>
  55#include <net/arp.h>
  56#include <net/neighbour.h>
  57#include <net/route.h>
  58#include <net/ip_fib.h>
  59
  60#include "nes.h"
  61
  62u32 cm_packets_sent;
  63u32 cm_packets_bounced;
  64u32 cm_packets_dropped;
  65u32 cm_packets_retrans;
  66u32 cm_packets_created;
  67u32 cm_packets_received;
  68u32 cm_listens_created;
  69u32 cm_listens_destroyed;
  70u32 cm_backlog_drops;
  71atomic_t cm_loopbacks;
  72atomic_t cm_nodes_created;
  73atomic_t cm_nodes_destroyed;
  74atomic_t cm_accel_dropped_pkts;
  75atomic_t cm_resets_recvd;
  76
  77static inline int mini_cm_accelerated(struct nes_cm_core *,
  78        struct nes_cm_node *);
  79static struct nes_cm_listener *mini_cm_listen(struct nes_cm_core *,
  80        struct nes_vnic *, struct nes_cm_info *);
  81static int mini_cm_del_listen(struct nes_cm_core *, struct nes_cm_listener *);
  82static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *,
  83        struct nes_vnic *, u16, void *, struct nes_cm_info *);
  84static int mini_cm_close(struct nes_cm_core *, struct nes_cm_node *);
  85static int mini_cm_accept(struct nes_cm_core *, struct ietf_mpa_frame *,
  86        struct nes_cm_node *);
  87static int mini_cm_reject(struct nes_cm_core *, struct ietf_mpa_frame *,
  88        struct nes_cm_node *);
  89static void mini_cm_recv_pkt(struct nes_cm_core *, struct nes_vnic *,
  90        struct sk_buff *);
  91static int mini_cm_dealloc_core(struct nes_cm_core *);
  92static int mini_cm_get(struct nes_cm_core *);
  93static int mini_cm_set(struct nes_cm_core *, u32, u32);
  94
  95static struct sk_buff *form_cm_frame(struct sk_buff *, struct nes_cm_node *,
  96        void *, u32, void *, u32, u8);
  97static struct sk_buff *get_free_pkt(struct nes_cm_node *cm_node);
  98static int add_ref_cm_node(struct nes_cm_node *);
  99static int rem_ref_cm_node(struct nes_cm_core *, struct nes_cm_node *);
 100
 101static int nes_cm_disconn_true(struct nes_qp *);
 102static int nes_cm_post_event(struct nes_cm_event *event);
 103static int nes_disconnect(struct nes_qp *nesqp, int abrupt);
 104static void nes_disconnect_worker(struct work_struct *work);
 105
 106static int send_mpa_request(struct nes_cm_node *, struct sk_buff *);
 107static int send_syn(struct nes_cm_node *, u32, struct sk_buff *);
 108static int send_reset(struct nes_cm_node *, struct sk_buff *);
 109static int send_ack(struct nes_cm_node *cm_node, struct sk_buff *skb);
 110static int send_fin(struct nes_cm_node *cm_node, struct sk_buff *skb);
 111static void process_packet(struct nes_cm_node *, struct sk_buff *,
 112        struct nes_cm_core *);
 113
 114static void active_open_err(struct nes_cm_node *, struct sk_buff *, int);
 115static void passive_open_err(struct nes_cm_node *, struct sk_buff *, int);
 116static void cleanup_retrans_entry(struct nes_cm_node *);
 117static void handle_rcv_mpa(struct nes_cm_node *, struct sk_buff *,
 118        enum nes_cm_event_type);
 119static void free_retrans_entry(struct nes_cm_node *cm_node);
 120static int handle_tcp_options(struct nes_cm_node *cm_node, struct tcphdr *tcph,
 121        struct sk_buff *skb, int optionsize, int passive);
 122
 123/* CM event handler functions */
 124static void cm_event_connected(struct nes_cm_event *);
 125static void cm_event_connect_error(struct nes_cm_event *);
 126static void cm_event_reset(struct nes_cm_event *);
 127static void cm_event_mpa_req(struct nes_cm_event *);
 128
 129static void print_core(struct nes_cm_core *core);
 130
 131/* External CM API Interface */
 132/* instance of function pointers for client API */
 133/* set address of this instance to cm_core->cm_ops at cm_core alloc */
 134static struct nes_cm_ops nes_cm_api = {
 135        mini_cm_accelerated,
 136        mini_cm_listen,
 137        mini_cm_del_listen,
 138        mini_cm_connect,
 139        mini_cm_close,
 140        mini_cm_accept,
 141        mini_cm_reject,
 142        mini_cm_recv_pkt,
 143        mini_cm_dealloc_core,
 144        mini_cm_get,
 145        mini_cm_set
 146};
 147
 148static struct nes_cm_core *g_cm_core;
 149
 150atomic_t cm_connects;
 151atomic_t cm_accepts;
 152atomic_t cm_disconnects;
 153atomic_t cm_closes;
 154atomic_t cm_connecteds;
 155atomic_t cm_connect_reqs;
 156atomic_t cm_rejects;
 157
 158
 159/**
 160 * create_event
 161 */
 162static struct nes_cm_event *create_event(struct nes_cm_node *cm_node,
 163                enum nes_cm_event_type type)
 164{
 165        struct nes_cm_event *event;
 166
 167        if (!cm_node->cm_id)
 168                return NULL;
 169
 170        /* allocate an empty event */
 171        event = kzalloc(sizeof(*event), GFP_ATOMIC);
 172
 173        if (!event)
 174                return NULL;
 175
 176        event->type = type;
 177        event->cm_node = cm_node;
 178        event->cm_info.rem_addr = cm_node->rem_addr;
 179        event->cm_info.loc_addr = cm_node->loc_addr;
 180        event->cm_info.rem_port = cm_node->rem_port;
 181        event->cm_info.loc_port = cm_node->loc_port;
 182        event->cm_info.cm_id = cm_node->cm_id;
 183
 184        nes_debug(NES_DBG_CM, "cm_node=%p Created event=%p, type=%u, "
 185                "dst_addr=%08x[%x], src_addr=%08x[%x]\n",
 186                cm_node, event, type, event->cm_info.loc_addr,
 187                event->cm_info.loc_port, event->cm_info.rem_addr,
 188                event->cm_info.rem_port);
 189
 190        nes_cm_post_event(event);
 191        return event;
 192}
 193
 194
 195/**
 196 * send_mpa_request
 197 */
 198static int send_mpa_request(struct nes_cm_node *cm_node, struct sk_buff *skb)
 199{
 200        int ret;
 201        if (!skb) {
 202                nes_debug(NES_DBG_CM, "skb set to NULL\n");
 203                return -1;
 204        }
 205
 206        /* send an MPA Request frame */
 207        form_cm_frame(skb, cm_node, NULL, 0, &cm_node->mpa_frame,
 208                        cm_node->mpa_frame_size, SET_ACK);
 209
 210        ret = schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 1, 0);
 211        if (ret < 0)
 212                return ret;
 213
 214        return 0;
 215}
 216
 217
 218/**
 219 * recv_mpa - process a received TCP pkt, we are expecting an
 220 * IETF MPA frame
 221 */
 222static int parse_mpa(struct nes_cm_node *cm_node, u8 *buffer, u32 len)
 223{
 224        struct ietf_mpa_frame *mpa_frame;
 225
 226        /* assume req frame is in tcp data payload */
 227        if (len < sizeof(struct ietf_mpa_frame)) {
 228                nes_debug(NES_DBG_CM, "The received ietf buffer was too small (%x)\n", len);
 229                return -1;
 230        }
 231
 232        mpa_frame = (struct ietf_mpa_frame *)buffer;
 233        cm_node->mpa_frame_size = ntohs(mpa_frame->priv_data_len);
 234
 235        if (cm_node->mpa_frame_size + sizeof(struct ietf_mpa_frame) != len) {
 236                nes_debug(NES_DBG_CM, "The received ietf buffer was not right"
 237                                " complete (%x + %x != %x)\n",
 238                                cm_node->mpa_frame_size, (u32)sizeof(struct ietf_mpa_frame), len);
 239                return -1;
 240        }
 241
 242        /* copy entire MPA frame to our cm_node's frame */
 243        memcpy(cm_node->mpa_frame_buf, buffer + sizeof(struct ietf_mpa_frame),
 244                        cm_node->mpa_frame_size);
 245
 246        return 0;
 247}
 248
 249
 250/**
 251 * form_cm_frame - get a free packet and build empty frame Use
 252 * node info to build.
 253 */
 254static struct sk_buff *form_cm_frame(struct sk_buff *skb,
 255        struct nes_cm_node *cm_node, void *options, u32 optionsize,
 256        void *data, u32 datasize, u8 flags)
 257{
 258        struct tcphdr *tcph;
 259        struct iphdr *iph;
 260        struct ethhdr *ethh;
 261        u8 *buf;
 262        u16 packetsize = sizeof(*iph);
 263
 264        packetsize += sizeof(*tcph);
 265        packetsize +=  optionsize + datasize;
 266
 267        memset(skb->data, 0x00, ETH_HLEN + sizeof(*iph) + sizeof(*tcph));
 268
 269        skb->len = 0;
 270        buf = skb_put(skb, packetsize + ETH_HLEN);
 271
 272        ethh = (struct ethhdr *) buf;
 273        buf += ETH_HLEN;
 274
 275        iph = (struct iphdr *)buf;
 276        buf += sizeof(*iph);
 277        tcph = (struct tcphdr *)buf;
 278        skb_reset_mac_header(skb);
 279        skb_set_network_header(skb, ETH_HLEN);
 280        skb_set_transport_header(skb, ETH_HLEN+sizeof(*iph));
 281        buf += sizeof(*tcph);
 282
 283        skb->ip_summed = CHECKSUM_PARTIAL;
 284        skb->protocol = htons(0x800);
 285        skb->data_len = 0;
 286        skb->mac_len = ETH_HLEN;
 287
 288        memcpy(ethh->h_dest, cm_node->rem_mac, ETH_ALEN);
 289        memcpy(ethh->h_source, cm_node->loc_mac, ETH_ALEN);
 290        ethh->h_proto = htons(0x0800);
 291
 292        iph->version = IPVERSION;
 293        iph->ihl = 5;                /* 5 * 4Byte words, IP headr len */
 294        iph->tos = 0;
 295        iph->tot_len = htons(packetsize);
 296        iph->id = htons(++cm_node->tcp_cntxt.loc_id);
 297
 298        iph->frag_off = htons(0x4000);
 299        iph->ttl = 0x40;
 300        iph->protocol = 0x06;        /* IPPROTO_TCP */
 301
 302        iph->saddr = htonl(cm_node->loc_addr);
 303        iph->daddr = htonl(cm_node->rem_addr);
 304
 305        tcph->source = htons(cm_node->loc_port);
 306        tcph->dest = htons(cm_node->rem_port);
 307        tcph->seq = htonl(cm_node->tcp_cntxt.loc_seq_num);
 308
 309        if (flags & SET_ACK) {
 310                cm_node->tcp_cntxt.loc_ack_num = cm_node->tcp_cntxt.rcv_nxt;
 311                tcph->ack_seq = htonl(cm_node->tcp_cntxt.loc_ack_num);
 312                tcph->ack = 1;
 313        } else
 314                tcph->ack_seq = 0;
 315
 316        if (flags & SET_SYN) {
 317                cm_node->tcp_cntxt.loc_seq_num++;
 318                tcph->syn = 1;
 319        } else
 320                cm_node->tcp_cntxt.loc_seq_num += datasize;
 321
 322        if (flags & SET_FIN) {
 323                cm_node->tcp_cntxt.loc_seq_num++;
 324                tcph->fin = 1;
 325        }
 326
 327        if (flags & SET_RST)
 328                tcph->rst = 1;
 329
 330        tcph->doff = (u16)((sizeof(*tcph) + optionsize + 3) >> 2);
 331        tcph->window = htons(cm_node->tcp_cntxt.rcv_wnd);
 332        tcph->urg_ptr = 0;
 333        if (optionsize)
 334                memcpy(buf, options, optionsize);
 335        buf += optionsize;
 336        if (datasize)
 337                memcpy(buf, data, datasize);
 338
 339        skb_shinfo(skb)->nr_frags = 0;
 340        cm_packets_created++;
 341
 342        return skb;
 343}
 344
 345
 346/**
 347 * print_core - dump a cm core
 348 */
 349static void print_core(struct nes_cm_core *core)
 350{
 351        nes_debug(NES_DBG_CM, "---------------------------------------------\n");
 352        nes_debug(NES_DBG_CM, "CM Core  -- (core = %p )\n", core);
 353        if (!core)
 354                return;
 355        nes_debug(NES_DBG_CM, "---------------------------------------------\n");
 356
 357        nes_debug(NES_DBG_CM, "State         : %u \n",  core->state);
 358
 359        nes_debug(NES_DBG_CM, "Tx Free cnt   : %u \n", skb_queue_len(&core->tx_free_list));
 360        nes_debug(NES_DBG_CM, "Listen Nodes  : %u \n", atomic_read(&core->listen_node_cnt));
 361        nes_debug(NES_DBG_CM, "Active Nodes  : %u \n", atomic_read(&core->node_cnt));
 362
 363        nes_debug(NES_DBG_CM, "core          : %p \n", core);
 364
 365        nes_debug(NES_DBG_CM, "-------------- end core ---------------\n");
 366}
 367
 368
 369/**
 370 * schedule_nes_timer
 371 * note - cm_node needs to be protected before calling this. Encase in:
 372 *                        rem_ref_cm_node(cm_core, cm_node);add_ref_cm_node(cm_node);
 373 */
 374int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb,
 375                enum nes_timer_type type, int send_retrans,
 376                int close_when_complete)
 377{
 378        unsigned long  flags;
 379        struct nes_cm_core *cm_core = cm_node->cm_core;
 380        struct nes_timer_entry *new_send;
 381        int ret = 0;
 382        u32 was_timer_set;
 383
 384        if (!cm_node)
 385                return -EINVAL;
 386        new_send = kzalloc(sizeof(*new_send), GFP_ATOMIC);
 387        if (!new_send)
 388                return -1;
 389
 390        /* new_send->timetosend = currenttime */
 391        new_send->retrycount = NES_DEFAULT_RETRYS;
 392        new_send->retranscount = NES_DEFAULT_RETRANS;
 393        new_send->skb = skb;
 394        new_send->timetosend = jiffies;
 395        new_send->type = type;
 396        new_send->netdev = cm_node->netdev;
 397        new_send->send_retrans = send_retrans;
 398        new_send->close_when_complete = close_when_complete;
 399
 400        if (type == NES_TIMER_TYPE_CLOSE) {
 401                new_send->timetosend += (HZ/10);
 402                spin_lock_irqsave(&cm_node->recv_list_lock, flags);
 403                list_add_tail(&new_send->list, &cm_node->recv_list);
 404                spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
 405        }
 406
 407        if (type == NES_TIMER_TYPE_SEND) {
 408                new_send->seq_num = ntohl(tcp_hdr(skb)->seq);
 409                atomic_inc(&new_send->skb->users);
 410                spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
 411                cm_node->send_entry = new_send;
 412                add_ref_cm_node(cm_node);
 413                spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags);
 414                new_send->timetosend = jiffies + NES_RETRY_TIMEOUT;
 415
 416                ret = nes_nic_cm_xmit(new_send->skb, cm_node->netdev);
 417                if (ret != NETDEV_TX_OK) {
 418                        nes_debug(NES_DBG_CM, "Error sending packet %p "
 419                                "(jiffies = %lu)\n", new_send, jiffies);
 420                        atomic_dec(&new_send->skb->users);
 421                        new_send->timetosend = jiffies;
 422                } else {
 423                        cm_packets_sent++;
 424                        if (!send_retrans) {
 425                                cleanup_retrans_entry(cm_node);
 426                                if (close_when_complete)
 427                                        rem_ref_cm_node(cm_core, cm_node);
 428                                return ret;
 429                        }
 430                }
 431        }
 432
 433        was_timer_set = timer_pending(&cm_core->tcp_timer);
 434
 435        if (!was_timer_set) {
 436                cm_core->tcp_timer.expires = new_send->timetosend;
 437                add_timer(&cm_core->tcp_timer);
 438        }
 439
 440        return ret;
 441}
 442
 443
 444/**
 445 * nes_cm_timer_tick
 446 */
 447static void nes_cm_timer_tick(unsigned long pass)
 448{
 449        unsigned long flags, qplockflags;
 450        unsigned long nexttimeout = jiffies + NES_LONG_TIME;
 451        struct iw_cm_id *cm_id;
 452        struct nes_cm_node *cm_node;
 453        struct nes_timer_entry *send_entry, *recv_entry;
 454        struct list_head *list_core, *list_core_temp;
 455        struct list_head *list_node, *list_node_temp;
 456        struct nes_cm_core *cm_core = g_cm_core;
 457        struct nes_qp *nesqp;
 458        u32 settimer = 0;
 459        int ret = NETDEV_TX_OK;
 460        enum nes_cm_node_state last_state;
 461
 462        spin_lock_irqsave(&cm_core->ht_lock, flags);
 463
 464        list_for_each_safe(list_node, list_core_temp,
 465                &cm_core->connected_nodes) {
 466                cm_node = container_of(list_node, struct nes_cm_node, list);
 467                add_ref_cm_node(cm_node);
 468                spin_unlock_irqrestore(&cm_core->ht_lock, flags);
 469                spin_lock_irqsave(&cm_node->recv_list_lock, flags);
 470                list_for_each_safe(list_core, list_node_temp,
 471                        &cm_node->recv_list) {
 472                        recv_entry = container_of(list_core,
 473                                struct nes_timer_entry, list);
 474                        if (!recv_entry)
 475                                break;
 476                        if (time_after(recv_entry->timetosend, jiffies)) {
 477                                if (nexttimeout > recv_entry->timetosend ||
 478                                        !settimer) {
 479                                        nexttimeout = recv_entry->timetosend;
 480                                        settimer = 1;
 481                                }
 482                                continue;
 483                        }
 484                        list_del(&recv_entry->list);
 485                        cm_id = cm_node->cm_id;
 486                        spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
 487                        nesqp = (struct nes_qp *)recv_entry->skb;
 488                        spin_lock_irqsave(&nesqp->lock, qplockflags);
 489                        if (nesqp->cm_id) {
 490                                nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, "
 491                                        "refcount = %d: HIT A "
 492                                        "NES_TIMER_TYPE_CLOSE with something "
 493                                        "to do!!!\n", nesqp->hwqp.qp_id, cm_id,
 494                                        atomic_read(&nesqp->refcount));
 495                                nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED;
 496                                nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT;
 497                                nesqp->ibqp_state = IB_QPS_ERR;
 498                                spin_unlock_irqrestore(&nesqp->lock,
 499                                        qplockflags);
 500                                nes_cm_disconn(nesqp);
 501                        } else {
 502                                spin_unlock_irqrestore(&nesqp->lock,
 503                                        qplockflags);
 504                                nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, "
 505                                        "refcount = %d: HIT A "
 506                                        "NES_TIMER_TYPE_CLOSE with nothing "
 507                                        "to do!!!\n", nesqp->hwqp.qp_id, cm_id,
 508                                        atomic_read(&nesqp->refcount));
 509                        }
 510                        if (cm_id)
 511                                cm_id->rem_ref(cm_id);
 512
 513                        kfree(recv_entry);
 514                        spin_lock_irqsave(&cm_node->recv_list_lock, flags);
 515                }
 516                spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
 517
 518                spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
 519                do {
 520                        send_entry = cm_node->send_entry;
 521                        if (!send_entry)
 522                                continue;
 523                        if (time_after(send_entry->timetosend, jiffies)) {
 524                                if (cm_node->state != NES_CM_STATE_TSA) {
 525                                        if ((nexttimeout >
 526                                                send_entry->timetosend) ||
 527                                                !settimer) {
 528                                                nexttimeout =
 529                                                        send_entry->timetosend;
 530                                                settimer = 1;
 531                                                continue;
 532                                        }
 533                                } else {
 534                                        free_retrans_entry(cm_node);
 535                                        continue;
 536                                }
 537                        }
 538
 539                        if ((cm_node->state == NES_CM_STATE_TSA) ||
 540                                (cm_node->state == NES_CM_STATE_CLOSED)) {
 541                                free_retrans_entry(cm_node);
 542                                continue;
 543                        }
 544
 545                        if (!send_entry->retranscount ||
 546                                !send_entry->retrycount) {
 547                                cm_packets_dropped++;
 548                                last_state = cm_node->state;
 549                                cm_node->state = NES_CM_STATE_CLOSED;
 550                                free_retrans_entry(cm_node);
 551                                spin_unlock_irqrestore(
 552                                        &cm_node->retrans_list_lock, flags);
 553                                if (last_state == NES_CM_STATE_SYN_RCVD)
 554                                        rem_ref_cm_node(cm_core, cm_node);
 555                                else
 556                                        create_event(cm_node,
 557                                                NES_CM_EVENT_ABORTED);
 558                                spin_lock_irqsave(&cm_node->retrans_list_lock,
 559                                        flags);
 560                                continue;
 561                        }
 562                        atomic_inc(&send_entry->skb->users);
 563                        cm_packets_retrans++;
 564                        nes_debug(NES_DBG_CM, "Retransmitting send_entry %p "
 565                                "for node %p, jiffies = %lu, time to send = "
 566                                "%lu, retranscount = %u, send_entry->seq_num = "
 567                                "0x%08X, cm_node->tcp_cntxt.rem_ack_num = "
 568                                "0x%08X\n", send_entry, cm_node, jiffies,
 569                                send_entry->timetosend,
 570                                send_entry->retranscount,
 571                                send_entry->seq_num,
 572                                cm_node->tcp_cntxt.rem_ack_num);
 573
 574                        spin_unlock_irqrestore(&cm_node->retrans_list_lock,
 575                                flags);
 576                        ret = nes_nic_cm_xmit(send_entry->skb, cm_node->netdev);
 577                        spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
 578                        if (ret != NETDEV_TX_OK) {
 579                                nes_debug(NES_DBG_CM, "rexmit failed for "
 580                                        "node=%p\n", cm_node);
 581                                cm_packets_bounced++;
 582                                atomic_dec(&send_entry->skb->users);
 583                                send_entry->retrycount--;
 584                                nexttimeout = jiffies + NES_SHORT_TIME;
 585                                settimer = 1;
 586                                continue;
 587                        } else {
 588                                cm_packets_sent++;
 589                        }
 590                        nes_debug(NES_DBG_CM, "Packet Sent: retrans count = "
 591                                "%u, retry count = %u.\n",
 592                                send_entry->retranscount,
 593                                send_entry->retrycount);
 594                        if (send_entry->send_retrans) {
 595                                send_entry->retranscount--;
 596                                send_entry->timetosend = jiffies +
 597                                        NES_RETRY_TIMEOUT;
 598                                if (nexttimeout > send_entry->timetosend ||
 599                                        !settimer) {
 600                                        nexttimeout = send_entry->timetosend;
 601                                        settimer = 1;
 602                                }
 603                        } else {
 604                                int close_when_complete;
 605                                close_when_complete =
 606                                        send_entry->close_when_complete;
 607                                nes_debug(NES_DBG_CM, "cm_node=%p state=%d\n",
 608                                        cm_node, cm_node->state);
 609                                free_retrans_entry(cm_node);
 610                                if (close_when_complete)
 611                                        rem_ref_cm_node(cm_node->cm_core,
 612                                                cm_node);
 613                        }
 614                } while (0);
 615
 616                spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags);
 617                rem_ref_cm_node(cm_node->cm_core, cm_node);
 618                spin_lock_irqsave(&cm_core->ht_lock, flags);
 619                if (ret != NETDEV_TX_OK) {
 620                        nes_debug(NES_DBG_CM, "rexmit failed for cm_node=%p\n",
 621                                cm_node);
 622                        break;
 623                }
 624        }
 625        spin_unlock_irqrestore(&cm_core->ht_lock, flags);
 626
 627        if (settimer) {
 628                if (!timer_pending(&cm_core->tcp_timer)) {
 629                        cm_core->tcp_timer.expires  = nexttimeout;
 630                        add_timer(&cm_core->tcp_timer);
 631                }
 632        }
 633}
 634
 635
 636/**
 637 * send_syn
 638 */
 639static int send_syn(struct nes_cm_node *cm_node, u32 sendack,
 640        struct sk_buff *skb)
 641{
 642        int ret;
 643        int flags = SET_SYN;
 644        char optionsbuffer[sizeof(struct option_mss) +
 645                sizeof(struct option_windowscale) + sizeof(struct option_base) +
 646                TCP_OPTIONS_PADDING];
 647
 648        int optionssize = 0;
 649        /* Sending MSS option */
 650        union all_known_options *options;
 651
 652        if (!cm_node)
 653                return -EINVAL;
 654
 655        options = (union all_known_options *)&optionsbuffer[optionssize];
 656        options->as_mss.optionnum = OPTION_NUMBER_MSS;
 657        options->as_mss.length = sizeof(struct option_mss);
 658        options->as_mss.mss = htons(cm_node->tcp_cntxt.mss);
 659        optionssize += sizeof(struct option_mss);
 660
 661        options = (union all_known_options *)&optionsbuffer[optionssize];
 662        options->as_windowscale.optionnum = OPTION_NUMBER_WINDOW_SCALE;
 663        options->as_windowscale.length = sizeof(struct option_windowscale);
 664        options->as_windowscale.shiftcount = cm_node->tcp_cntxt.rcv_wscale;
 665        optionssize += sizeof(struct option_windowscale);
 666
 667        if (sendack && !(NES_DRV_OPT_SUPRESS_OPTION_BC & nes_drv_opt)) {
 668                options = (union all_known_options *)&optionsbuffer[optionssize];
 669                options->as_base.optionnum = OPTION_NUMBER_WRITE0;
 670                options->as_base.length = sizeof(struct option_base);
 671                optionssize += sizeof(struct option_base);
 672                /* we need the size to be a multiple of 4 */
 673                options = (union all_known_options *)&optionsbuffer[optionssize];
 674                options->as_end = 1;
 675                optionssize += 1;
 676                options = (union all_known_options *)&optionsbuffer[optionssize];
 677                options->as_end = 1;
 678                optionssize += 1;
 679        }
 680
 681        options = (union all_known_options *)&optionsbuffer[optionssize];
 682        options->as_end = OPTION_NUMBER_END;
 683        optionssize += 1;
 684
 685        if (!skb)
 686                skb = get_free_pkt(cm_node);
 687        if (!skb) {
 688                nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n");
 689                return -1;
 690        }
 691
 692        if (sendack)
 693                flags |= SET_ACK;
 694
 695        form_cm_frame(skb, cm_node, optionsbuffer, optionssize, NULL, 0, flags);
 696        ret = schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 1, 0);
 697
 698        return ret;
 699}
 700
 701
 702/**
 703 * send_reset
 704 */
 705static int send_reset(struct nes_cm_node *cm_node, struct sk_buff *skb)
 706{
 707        int ret;
 708        int flags = SET_RST | SET_ACK;
 709
 710        if (!skb)
 711                skb = get_free_pkt(cm_node);
 712        if (!skb) {
 713                nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n");
 714                return -1;
 715        }
 716
 717        form_cm_frame(skb, cm_node, NULL, 0, NULL, 0, flags);
 718        ret = schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 0, 1);
 719
 720        return ret;
 721}
 722
 723
 724/**
 725 * send_ack
 726 */
 727static int send_ack(struct nes_cm_node *cm_node, struct sk_buff *skb)
 728{
 729        int ret;
 730
 731        if (!skb)
 732                skb = get_free_pkt(cm_node);
 733
 734        if (!skb) {
 735                nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n");
 736                return -1;
 737        }
 738
 739        form_cm_frame(skb, cm_node, NULL, 0, NULL, 0, SET_ACK);
 740        ret = schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 0, 0);
 741
 742        return ret;
 743}
 744
 745
 746/**
 747 * send_fin
 748 */
 749static int send_fin(struct nes_cm_node *cm_node, struct sk_buff *skb)
 750{
 751        int ret;
 752
 753        /* if we didn't get a frame get one */
 754        if (!skb)
 755                skb = get_free_pkt(cm_node);
 756
 757        if (!skb) {
 758                nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n");
 759                return -1;
 760        }
 761
 762        form_cm_frame(skb, cm_node, NULL, 0, NULL, 0, SET_ACK | SET_FIN);
 763        ret = schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 1, 0);
 764
 765        return ret;
 766}
 767
 768
 769/**
 770 * get_free_pkt
 771 */
 772static struct sk_buff *get_free_pkt(struct nes_cm_node *cm_node)
 773{
 774        struct sk_buff *skb, *new_skb;
 775
 776        /* check to see if we need to repopulate the free tx pkt queue */
 777        if (skb_queue_len(&cm_node->cm_core->tx_free_list) < NES_CM_FREE_PKT_LO_WATERMARK) {
 778                while (skb_queue_len(&cm_node->cm_core->tx_free_list) <
 779                                cm_node->cm_core->free_tx_pkt_max) {
 780                        /* replace the frame we took, we won't get it back */
 781                        new_skb = dev_alloc_skb(cm_node->cm_core->mtu);
 782                        BUG_ON(!new_skb);
 783                        /* add a replacement frame to the free tx list head */
 784                        skb_queue_head(&cm_node->cm_core->tx_free_list, new_skb);
 785                }
 786        }
 787
 788        skb = skb_dequeue(&cm_node->cm_core->tx_free_list);
 789
 790        return skb;
 791}
 792
 793
 794/**
 795 * make_hashkey - generate hash key from node tuple
 796 */
 797static inline int make_hashkey(u16 loc_port, nes_addr_t loc_addr, u16 rem_port,
 798                nes_addr_t rem_addr)
 799{
 800        u32 hashkey = 0;
 801
 802        hashkey = loc_addr + rem_addr + loc_port + rem_port;
 803        hashkey = (hashkey % NES_CM_HASHTABLE_SIZE);
 804
 805        return hashkey;
 806}
 807
 808
 809/**
 810 * find_node - find a cm node that matches the reference cm node
 811 */
 812static struct nes_cm_node *find_node(struct nes_cm_core *cm_core,
 813                u16 rem_port, nes_addr_t rem_addr, u16 loc_port, nes_addr_t loc_addr)
 814{
 815        unsigned long flags;
 816        u32 hashkey;
 817        struct list_head *hte;
 818        struct nes_cm_node *cm_node;
 819
 820        /* make a hash index key for this packet */
 821        hashkey = make_hashkey(loc_port, loc_addr, rem_port, rem_addr);
 822
 823        /* get a handle on the hte */
 824        hte = &cm_core->connected_nodes;
 825
 826        nes_debug(NES_DBG_CM, "Searching for an owner node: " NIPQUAD_FMT ":%x from core %p->%p\n",
 827                  HIPQUAD(loc_addr), loc_port, cm_core, hte);
 828
 829        /* walk list and find cm_node associated with this session ID */
 830        spin_lock_irqsave(&cm_core->ht_lock, flags);
 831        list_for_each_entry(cm_node, hte, list) {
 832                /* compare quad, return node handle if a match */
 833                nes_debug(NES_DBG_CM, "finding node %x:%x =? %x:%x ^ %x:%x =? %x:%x\n",
 834                                cm_node->loc_addr, cm_node->loc_port,
 835                                loc_addr, loc_port,
 836                                cm_node->rem_addr, cm_node->rem_port,
 837                                rem_addr, rem_port);
 838                if ((cm_node->loc_addr == loc_addr) && (cm_node->loc_port == loc_port) &&
 839                                (cm_node->rem_addr == rem_addr) && (cm_node->rem_port == rem_port)) {
 840                        add_ref_cm_node(cm_node);
 841                        spin_unlock_irqrestore(&cm_core->ht_lock, flags);
 842                        return cm_node;
 843                }
 844        }
 845        spin_unlock_irqrestore(&cm_core->ht_lock, flags);
 846
 847        /* no owner node */
 848        return NULL;
 849}
 850
 851
 852/**
 853 * find_listener - find a cm node listening on this addr-port pair
 854 */
 855static struct nes_cm_listener *find_listener(struct nes_cm_core *cm_core,
 856                nes_addr_t dst_addr, u16 dst_port, enum nes_cm_listener_state listener_state)
 857{
 858        unsigned long flags;
 859        struct nes_cm_listener *listen_node;
 860
 861        /* walk list and find cm_node associated with this session ID */
 862        spin_lock_irqsave(&cm_core->listen_list_lock, flags);
 863        list_for_each_entry(listen_node, &cm_core->listen_list.list, list) {
 864                /* compare node pair, return node handle if a match */
 865                if (((listen_node->loc_addr == dst_addr) ||
 866                                listen_node->loc_addr == 0x00000000) &&
 867                                (listen_node->loc_port == dst_port) &&
 868                                (listener_state & listen_node->listener_state)) {
 869                        atomic_inc(&listen_node->ref_count);
 870                        spin_unlock_irqrestore(&cm_core->listen_list_lock, flags);
 871                        return listen_node;
 872                }
 873        }
 874        spin_unlock_irqrestore(&cm_core->listen_list_lock, flags);
 875
 876        nes_debug(NES_DBG_CM, "Unable to find listener for " NIPQUAD_FMT ":%x\n",
 877                  HIPQUAD(dst_addr), dst_port);
 878
 879        /* no listener */
 880        return NULL;
 881}
 882
 883
 884/**
 885 * add_hte_node - add a cm node to the hash table
 886 */
 887static int add_hte_node(struct nes_cm_core *cm_core, struct nes_cm_node *cm_node)
 888{
 889        unsigned long flags;
 890        u32 hashkey;
 891        struct list_head *hte;
 892
 893        if (!cm_node || !cm_core)
 894                return -EINVAL;
 895
 896        nes_debug(NES_DBG_CM, "Adding Node %p to Active Connection HT\n",
 897                cm_node);
 898
 899        /* first, make an index into our hash table */
 900        hashkey = make_hashkey(cm_node->loc_port, cm_node->loc_addr,
 901                        cm_node->rem_port, cm_node->rem_addr);
 902        cm_node->hashkey = hashkey;
 903
 904        spin_lock_irqsave(&cm_core->ht_lock, flags);
 905
 906        /* get a handle on the hash table element (list head for this slot) */
 907        hte = &cm_core->connected_nodes;
 908        list_add_tail(&cm_node->list, hte);
 909        atomic_inc(&cm_core->ht_node_cnt);
 910
 911        spin_unlock_irqrestore(&cm_core->ht_lock, flags);
 912
 913        return 0;
 914}
 915
 916
 917/**
 918 * mini_cm_dec_refcnt_listen
 919 */
 920static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core,
 921        struct nes_cm_listener *listener, int free_hanging_nodes)
 922{
 923        int ret = 1;
 924        unsigned long flags;
 925        struct list_head *list_pos = NULL;
 926        struct list_head *list_temp = NULL;
 927        struct nes_cm_node *cm_node = NULL;
 928
 929        nes_debug(NES_DBG_CM, "attempting listener= %p free_nodes= %d, "
 930                "refcnt=%d\n", listener, free_hanging_nodes,
 931                atomic_read(&listener->ref_count));
 932        /* free non-accelerated child nodes for this listener */
 933        if (free_hanging_nodes) {
 934                spin_lock_irqsave(&cm_core->ht_lock, flags);
 935                list_for_each_safe(list_pos, list_temp,
 936                        &g_cm_core->connected_nodes) {
 937                        cm_node = container_of(list_pos, struct nes_cm_node,
 938                                list);
 939                        if ((cm_node->listener == listener) &&
 940                                (!cm_node->accelerated)) {
 941                                cleanup_retrans_entry(cm_node);
 942                                spin_unlock_irqrestore(&cm_core->ht_lock,
 943                                        flags);
 944                                send_reset(cm_node, NULL);
 945                                spin_lock_irqsave(&cm_core->ht_lock, flags);
 946                        }
 947                }
 948                spin_unlock_irqrestore(&cm_core->ht_lock, flags);
 949        }
 950        spin_lock_irqsave(&cm_core->listen_list_lock, flags);
 951        if (!atomic_dec_return(&listener->ref_count)) {
 952                list_del(&listener->list);
 953
 954                /* decrement our listen node count */
 955                atomic_dec(&cm_core->listen_node_cnt);
 956
 957                spin_unlock_irqrestore(&cm_core->listen_list_lock, flags);
 958
 959                if (listener->nesvnic) {
 960                        nes_manage_apbvt(listener->nesvnic, listener->loc_port,
 961                                        PCI_FUNC(listener->nesvnic->nesdev->pcidev->devfn), NES_MANAGE_APBVT_DEL);
 962                }
 963
 964                nes_debug(NES_DBG_CM, "destroying listener (%p)\n", listener);
 965
 966                kfree(listener);
 967                listener = NULL;
 968                ret = 0;
 969                cm_listens_destroyed++;
 970        } else {
 971                spin_unlock_irqrestore(&cm_core->listen_list_lock, flags);
 972        }
 973        if (listener) {
 974                if (atomic_read(&listener->pend_accepts_cnt) > 0)
 975                        nes_debug(NES_DBG_CM, "destroying listener (%p)"
 976                                        " with non-zero pending accepts=%u\n",
 977                                        listener, atomic_read(&listener->pend_accepts_cnt));
 978        }
 979
 980        return ret;
 981}
 982
 983
 984/**
 985 * mini_cm_del_listen
 986 */
 987static int mini_cm_del_listen(struct nes_cm_core *cm_core,
 988                struct nes_cm_listener *listener)
 989{
 990        listener->listener_state = NES_CM_LISTENER_PASSIVE_STATE;
 991        listener->cm_id = NULL; /* going to be destroyed pretty soon */
 992        return mini_cm_dec_refcnt_listen(cm_core, listener, 1);
 993}
 994
 995
 996/**
 997 * mini_cm_accelerated
 998 */
 999static inline int mini_cm_accelerated(struct nes_cm_core *cm_core,
1000                struct nes_cm_node *cm_node)
1001{
1002        u32 was_timer_set;
1003        cm_node->accelerated = 1;
1004
1005        if (cm_node->accept_pend) {
1006                BUG_ON(!cm_node->listener);
1007                atomic_dec(&cm_node->listener->pend_accepts_cnt);
1008                BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0);
1009        }
1010
1011        was_timer_set = timer_pending(&cm_core->tcp_timer);
1012        if (!was_timer_set) {
1013                cm_core->tcp_timer.expires = jiffies + NES_SHORT_TIME;
1014                add_timer(&cm_core->tcp_timer);
1015        }
1016
1017        return 0;
1018}
1019
1020
1021/**
1022 * nes_addr_resolve_neigh
1023 */
1024static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip)
1025{
1026        struct rtable *rt;
1027        struct flowi fl;
1028        struct neighbour *neigh;
1029        int rc = -1;
1030        DECLARE_MAC_BUF(mac);
1031
1032        memset(&fl, 0, sizeof fl);
1033        fl.nl_u.ip4_u.daddr = htonl(dst_ip);
1034        if (ip_route_output_key(&init_net, &rt, &fl)) {
1035                printk("%s: ip_route_output_key failed for 0x%08X\n",
1036                                __func__, dst_ip);
1037                return rc;
1038        }
1039
1040        neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, nesvnic->netdev);
1041        if (neigh) {
1042                if (neigh->nud_state & NUD_VALID) {
1043                        nes_debug(NES_DBG_CM, "Neighbor MAC address for 0x%08X"
1044                                  " is %s, Gateway is 0x%08X \n", dst_ip,
1045                                  print_mac(mac, neigh->ha), ntohl(rt->rt_gateway));
1046                        nes_manage_arp_cache(nesvnic->netdev, neigh->ha,
1047                                             dst_ip, NES_ARP_ADD);
1048                        rc = nes_arp_table(nesvnic->nesdev, dst_ip, NULL,
1049                                           NES_ARP_RESOLVE);
1050                }
1051                neigh_release(neigh);
1052        }
1053
1054        if ((neigh == NULL) || (!(neigh->nud_state & NUD_VALID)))
1055                neigh_event_send(rt->u.dst.neighbour, NULL);
1056
1057        ip_rt_put(rt);
1058        return rc;
1059}
1060
1061
1062/**
1063 * make_cm_node - create a new instance of a cm node
1064 */
1065static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core,
1066                struct nes_vnic *nesvnic, struct nes_cm_info *cm_info,
1067                struct nes_cm_listener *listener)
1068{
1069        struct nes_cm_node *cm_node;
1070        struct timespec ts;
1071        int arpindex = 0;
1072        struct nes_device *nesdev;
1073        struct nes_adapter *nesadapter;
1074        DECLARE_MAC_BUF(mac);
1075
1076        /* create an hte and cm_node for this instance */
1077        cm_node = kzalloc(sizeof(*cm_node), GFP_ATOMIC);
1078        if (!cm_node)
1079                return NULL;
1080
1081        /* set our node specific transport info */
1082        cm_node->loc_addr = cm_info->loc_addr;
1083        cm_node->rem_addr = cm_info->rem_addr;
1084        cm_node->loc_port = cm_info->loc_port;
1085        cm_node->rem_port = cm_info->rem_port;
1086        cm_node->send_write0 = send_first;
1087        nes_debug(NES_DBG_CM, "Make node addresses : loc = " NIPQUAD_FMT
1088                        ":%x, rem = " NIPQUAD_FMT ":%x\n",
1089                        HIPQUAD(cm_node->loc_addr), cm_node->loc_port,
1090                        HIPQUAD(cm_node->rem_addr), cm_node->rem_port);
1091        cm_node->listener = listener;
1092        cm_node->netdev = nesvnic->netdev;
1093        cm_node->cm_id = cm_info->cm_id;
1094        memcpy(cm_node->loc_mac, nesvnic->netdev->dev_addr, ETH_ALEN);
1095
1096        nes_debug(NES_DBG_CM, "listener=%p, cm_id=%p\n", cm_node->listener,
1097                        cm_node->cm_id);
1098
1099        spin_lock_init(&cm_node->retrans_list_lock);
1100        INIT_LIST_HEAD(&cm_node->recv_list);
1101        spin_lock_init(&cm_node->recv_list_lock);
1102
1103        cm_node->loopbackpartner = NULL;
1104        atomic_set(&cm_node->ref_count, 1);
1105        /* associate our parent CM core */
1106        cm_node->cm_core = cm_core;
1107        cm_node->tcp_cntxt.loc_id = NES_CM_DEF_LOCAL_ID;
1108        cm_node->tcp_cntxt.rcv_wscale = NES_CM_DEFAULT_RCV_WND_SCALE;
1109        cm_node->tcp_cntxt.rcv_wnd = NES_CM_DEFAULT_RCV_WND_SCALED >>
1110                        NES_CM_DEFAULT_RCV_WND_SCALE;
1111        ts = current_kernel_time();
1112        cm_node->tcp_cntxt.loc_seq_num = htonl(ts.tv_nsec);
1113        cm_node->tcp_cntxt.mss = nesvnic->max_frame_size - sizeof(struct iphdr) -
1114                        sizeof(struct tcphdr) - ETH_HLEN - VLAN_HLEN;
1115        cm_node->tcp_cntxt.rcv_nxt = 0;
1116        /* get a unique session ID , add thread_id to an upcounter to handle race */
1117        atomic_inc(&cm_core->node_cnt);
1118        cm_node->conn_type = cm_info->conn_type;
1119        cm_node->apbvt_set = 0;
1120        cm_node->accept_pend = 0;
1121
1122        cm_node->nesvnic = nesvnic;
1123        /* get some device handles, for arp lookup */
1124        nesdev = nesvnic->nesdev;
1125        nesadapter = nesdev->nesadapter;
1126
1127        cm_node->loopbackpartner = NULL;
1128        /* get the mac addr for the remote node */
1129        arpindex = nes_arp_table(nesdev, cm_node->rem_addr, NULL, NES_ARP_RESOLVE);
1130        if (arpindex < 0) {
1131                arpindex = nes_addr_resolve_neigh(nesvnic, cm_info->rem_addr);
1132                if (arpindex < 0) {
1133                        kfree(cm_node);
1134                        return NULL;
1135                }
1136        }
1137
1138        /* copy the mac addr to node context */
1139        memcpy(cm_node->rem_mac, nesadapter->arp_table[arpindex].mac_addr, ETH_ALEN);
1140        nes_debug(NES_DBG_CM, "Remote mac addr from arp table: %s\n",
1141                  print_mac(mac, cm_node->rem_mac));
1142
1143        add_hte_node(cm_core, cm_node);
1144        atomic_inc(&cm_nodes_created);
1145
1146        return cm_node;
1147}
1148
1149
1150/**
1151 * add_ref_cm_node - destroy an instance of a cm node
1152 */
1153static int add_ref_cm_node(struct nes_cm_node *cm_node)
1154{
1155        atomic_inc(&cm_node->ref_count);
1156        return 0;
1157}
1158
1159
1160/**
1161 * rem_ref_cm_node - destroy an instance of a cm node
1162 */
1163static int rem_ref_cm_node(struct nes_cm_core *cm_core,
1164        struct nes_cm_node *cm_node)
1165{
1166        unsigned long flags, qplockflags;
1167        struct nes_timer_entry *recv_entry;
1168        struct iw_cm_id *cm_id;
1169        struct list_head *list_core, *list_node_temp;
1170        struct nes_qp *nesqp;
1171
1172        if (!cm_node)
1173                return -EINVAL;
1174
1175        spin_lock_irqsave(&cm_node->cm_core->ht_lock, flags);
1176        if (atomic_dec_return(&cm_node->ref_count)) {
1177                spin_unlock_irqrestore(&cm_node->cm_core->ht_lock, flags);
1178                return 0;
1179        }
1180        list_del(&cm_node->list);
1181        atomic_dec(&cm_core->ht_node_cnt);
1182        spin_unlock_irqrestore(&cm_node->cm_core->ht_lock, flags);
1183
1184        /* if the node is destroyed before connection was accelerated */
1185        if (!cm_node->accelerated && cm_node->accept_pend) {
1186                BUG_ON(!cm_node->listener);
1187                atomic_dec(&cm_node->listener->pend_accepts_cnt);
1188                BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0);
1189        }
1190        BUG_ON(cm_node->send_entry);
1191        spin_lock_irqsave(&cm_node->recv_list_lock, flags);
1192        list_for_each_safe(list_core, list_node_temp, &cm_node->recv_list) {
1193                recv_entry = container_of(list_core, struct nes_timer_entry,
1194                                list);
1195                list_del(&recv_entry->list);
1196                cm_id = cm_node->cm_id;
1197                spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
1198                nesqp = (struct nes_qp *)recv_entry->skb;
1199                spin_lock_irqsave(&nesqp->lock, qplockflags);
1200                if (nesqp->cm_id) {
1201                        nes_debug(NES_DBG_CM, "QP%u: cm_id = %p: HIT A "
1202                                "NES_TIMER_TYPE_CLOSE with something to do!\n",
1203                                nesqp->hwqp.qp_id, cm_id);
1204                        nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED;
1205                        nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT;
1206                        nesqp->ibqp_state = IB_QPS_ERR;
1207                        spin_unlock_irqrestore(&nesqp->lock, qplockflags);
1208                        nes_cm_disconn(nesqp);
1209                } else {
1210                        spin_unlock_irqrestore(&nesqp->lock, qplockflags);
1211                        nes_debug(NES_DBG_CM, "QP%u: cm_id = %p: HIT A "
1212                                "NES_TIMER_TYPE_CLOSE with nothing to do!\n",
1213                                nesqp->hwqp.qp_id, cm_id);
1214                }
1215                cm_id->rem_ref(cm_id);
1216
1217                kfree(recv_entry);
1218                spin_lock_irqsave(&cm_node->recv_list_lock, flags);
1219        }
1220        spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
1221
1222        if (cm_node->listener) {
1223                mini_cm_dec_refcnt_listen(cm_core, cm_node->listener, 0);
1224        } else {
1225                if (cm_node->apbvt_set && cm_node->nesvnic) {
1226                        nes_manage_apbvt(cm_node->nesvnic, cm_node->loc_port,
1227                                PCI_FUNC(
1228                                cm_node->nesvnic->nesdev->pcidev->devfn),
1229                                NES_MANAGE_APBVT_DEL);
1230                }
1231        }
1232
1233        atomic_dec(&cm_core->node_cnt);
1234        atomic_inc(&cm_nodes_destroyed);
1235        nesqp = cm_node->nesqp;
1236        if (nesqp) {
1237                nesqp->cm_node = NULL;
1238                nes_rem_ref(&nesqp->ibqp);
1239                cm_node->nesqp = NULL;
1240        }
1241
1242        cm_node->freed = 1;
1243        kfree(cm_node);
1244        return 0;
1245}
1246
1247/**
1248 * process_options
1249 */
1250static int process_options(struct nes_cm_node *cm_node, u8 *optionsloc,
1251        u32 optionsize, u32 syn_packet)
1252{
1253        u32 tmp;
1254        u32 offset = 0;
1255        union all_known_options *all_options;
1256        char got_mss_option = 0;
1257
1258        while (offset < optionsize) {
1259                all_options = (union all_known_options *)(optionsloc + offset);
1260                switch (all_options->as_base.optionnum) {
1261                case OPTION_NUMBER_END:
1262                        offset = optionsize;
1263                        break;
1264                case OPTION_NUMBER_NONE:
1265                        offset += 1;
1266                        continue;
1267                case OPTION_NUMBER_MSS:
1268                        nes_debug(NES_DBG_CM, "%s: MSS Length: %d Offset: %d "
1269                                "Size: %d\n", __func__,
1270                                all_options->as_mss.length, offset, optionsize);
1271                        got_mss_option = 1;
1272                        if (all_options->as_mss.length != 4) {
1273                                return 1;
1274                        } else {
1275                                tmp = ntohs(all_options->as_mss.mss);
1276                                if (tmp > 0 && tmp <
1277                                        cm_node->tcp_cntxt.mss)
1278                                        cm_node->tcp_cntxt.mss = tmp;
1279                        }
1280                        break;
1281                case OPTION_NUMBER_WINDOW_SCALE:
1282                        cm_node->tcp_cntxt.snd_wscale =
1283                                all_options->as_windowscale.shiftcount;
1284                        break;
1285                case OPTION_NUMBER_WRITE0:
1286                        cm_node->send_write0 = 1;
1287                        break;
1288                default:
1289                        nes_debug(NES_DBG_CM, "TCP Option not understood: %x\n",
1290                                all_options->as_base.optionnum);
1291                        break;
1292                }
1293                offset += all_options->as_base.length;
1294        }
1295        if ((!got_mss_option) && (syn_packet))
1296                cm_node->tcp_cntxt.mss = NES_CM_DEFAULT_MSS;
1297        return 0;
1298}
1299
1300static void drop_packet(struct sk_buff *skb)
1301{
1302        atomic_inc(&cm_accel_dropped_pkts);
1303        dev_kfree_skb_any(skb);
1304}
1305
1306static void handle_fin_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1307        struct tcphdr *tcph)
1308{
1309        atomic_inc(&cm_resets_recvd);
1310        nes_debug(NES_DBG_CM, "Received FIN, cm_node = %p, state = %u. "
1311                "refcnt=%d\n", cm_node, cm_node->state,
1312                atomic_read(&cm_node->ref_count));
1313        cm_node->tcp_cntxt.rcv_nxt++;
1314        cleanup_retrans_entry(cm_node);
1315        switch (cm_node->state) {
1316        case NES_CM_STATE_SYN_RCVD:
1317        case NES_CM_STATE_SYN_SENT:
1318        case NES_CM_STATE_ESTABLISHED:
1319        case NES_CM_STATE_MPAREQ_SENT:
1320                cm_node->state = NES_CM_STATE_LAST_ACK;
1321                send_fin(cm_node, skb);
1322                break;
1323        case NES_CM_STATE_FIN_WAIT1:
1324                cm_node->state = NES_CM_STATE_CLOSING;
1325                send_ack(cm_node, skb);
1326                break;
1327        case NES_CM_STATE_FIN_WAIT2:
1328                cm_node->state = NES_CM_STATE_TIME_WAIT;
1329                send_ack(cm_node, skb);
1330                cm_node->state = NES_CM_STATE_CLOSED;
1331                break;
1332        case NES_CM_STATE_TSA:
1333        default:
1334                nes_debug(NES_DBG_CM, "Error Rcvd FIN for node-%p state = %d\n",
1335                        cm_node, cm_node->state);
1336                drop_packet(skb);
1337                break;
1338        }
1339}
1340
1341
1342static void handle_rst_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1343        struct tcphdr *tcph)
1344{
1345
1346        int        reset = 0;        /* whether to send reset in case of err.. */
1347        atomic_inc(&cm_resets_recvd);
1348        nes_debug(NES_DBG_CM, "Received Reset, cm_node = %p, state = %u."
1349                        " refcnt=%d\n", cm_node, cm_node->state,
1350                        atomic_read(&cm_node->ref_count));
1351        cleanup_retrans_entry(cm_node);
1352        switch (cm_node->state) {
1353        case NES_CM_STATE_SYN_SENT:
1354        case NES_CM_STATE_MPAREQ_SENT:
1355                nes_debug(NES_DBG_CM, "%s[%u] create abort for cm_node=%p "
1356                        "listener=%p state=%d\n", __func__, __LINE__, cm_node,
1357                        cm_node->listener, cm_node->state);
1358                active_open_err(cm_node, skb, reset);
1359                break;
1360        /* For PASSIVE open states, remove the cm_node event */
1361        case NES_CM_STATE_ESTABLISHED:
1362        case NES_CM_STATE_SYN_RCVD:
1363        case NES_CM_STATE_LISTENING:
1364                nes_debug(NES_DBG_CM, "Bad state %s[%u]\n", __func__, __LINE__);
1365                passive_open_err(cm_node, skb, reset);
1366                break;
1367        case NES_CM_STATE_TSA:
1368        default:
1369                break;
1370        }
1371}
1372
1373static void handle_rcv_mpa(struct nes_cm_node *cm_node, struct sk_buff *skb,
1374        enum nes_cm_event_type type)
1375{
1376
1377        int        ret;
1378        int datasize = skb->len;
1379        u8 *dataloc = skb->data;
1380        ret = parse_mpa(cm_node, dataloc, datasize);
1381        if (ret < 0) {
1382                nes_debug(NES_DBG_CM, "didn't like MPA Request\n");
1383                if (type == NES_CM_EVENT_CONNECTED) {
1384                        nes_debug(NES_DBG_CM, "%s[%u] create abort for "
1385                                "cm_node=%p listener=%p state=%d\n", __func__,
1386                                __LINE__, cm_node, cm_node->listener,
1387                                cm_node->state);
1388                        active_open_err(cm_node, skb, 1);
1389                } else {
1390                        passive_open_err(cm_node, skb, 1);
1391                }
1392        } else {
1393                cleanup_retrans_entry(cm_node);
1394                dev_kfree_skb_any(skb);
1395                if (type == NES_CM_EVENT_CONNECTED)
1396                        cm_node->state = NES_CM_STATE_TSA;
1397                create_event(cm_node, type);
1398
1399        }
1400        return ;
1401}
1402
1403static void indicate_pkt_err(struct nes_cm_node *cm_node, struct sk_buff *skb)
1404{
1405        switch (cm_node->state) {
1406        case NES_CM_STATE_SYN_SENT:
1407        case NES_CM_STATE_MPAREQ_SENT:
1408                nes_debug(NES_DBG_CM, "%s[%u] create abort for cm_node=%p "
1409                        "listener=%p state=%d\n", __func__, __LINE__, cm_node,
1410                        cm_node->listener, cm_node->state);
1411                active_open_err(cm_node, skb, 1);
1412                break;
1413        case NES_CM_STATE_ESTABLISHED:
1414        case NES_CM_STATE_SYN_RCVD:
1415                passive_open_err(cm_node, skb, 1);
1416                break;
1417        case NES_CM_STATE_TSA:
1418        default:
1419                drop_packet(skb);
1420        }
1421}
1422
1423static int check_syn(struct nes_cm_node *cm_node, struct tcphdr *tcph,
1424        struct sk_buff *skb)
1425{
1426        int err;
1427
1428        err = ((ntohl(tcph->ack_seq) == cm_node->tcp_cntxt.loc_seq_num))? 0 : 1;
1429        if (err)
1430                active_open_err(cm_node, skb, 1);
1431
1432        return err;
1433}
1434
1435static int check_seq(struct nes_cm_node *cm_node, struct tcphdr *tcph,
1436        struct sk_buff *skb)
1437{
1438        int err = 0;
1439        u32 seq;
1440        u32 ack_seq;
1441        u32 loc_seq_num = cm_node->tcp_cntxt.loc_seq_num;
1442        u32 rcv_nxt = cm_node->tcp_cntxt.rcv_nxt;
1443        u32 rcv_wnd;
1444        seq = ntohl(tcph->seq);
1445        ack_seq = ntohl(tcph->ack_seq);
1446        rcv_wnd = cm_node->tcp_cntxt.rcv_wnd;
1447        if (ack_seq != loc_seq_num)
1448                err = 1;
1449        else if ((seq + rcv_wnd) < rcv_nxt)
1450                err = 1;
1451        if (err) {
1452                nes_debug(NES_DBG_CM, "%s[%u] create abort for cm_node=%p "
1453                        "listener=%p state=%d\n", __func__, __LINE__, cm_node,
1454                        cm_node->listener, cm_node->state);
1455                indicate_pkt_err(cm_node, skb);
1456                nes_debug(NES_DBG_CM, "seq ERROR cm_node =%p seq=0x%08X "
1457                        "rcv_nxt=0x%08X rcv_wnd=0x%x\n", cm_node, seq, rcv_nxt,
1458                        rcv_wnd);
1459        }
1460        return err;
1461}
1462
1463/*
1464 * handle_syn_pkt() is for Passive node. The syn packet is received when a node
1465 * is created with a listener or it may comein as rexmitted packet which in
1466 * that case will be just dropped.
1467 */
1468
1469static void handle_syn_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1470        struct tcphdr *tcph)
1471{
1472        int ret;
1473        u32 inc_sequence;
1474        int optionsize;
1475
1476        optionsize = (tcph->doff << 2) - sizeof(struct tcphdr);
1477        skb_pull(skb, tcph->doff << 2);
1478        inc_sequence = ntohl(tcph->seq);
1479
1480        switch (cm_node->state) {
1481        case NES_CM_STATE_SYN_SENT:
1482        case NES_CM_STATE_MPAREQ_SENT:
1483                /* Rcvd syn on active open connection*/
1484                active_open_err(cm_node, skb, 1);
1485                break;
1486        case NES_CM_STATE_LISTENING:
1487                /* Passive OPEN */
1488                cm_node->accept_pend = 1;
1489                atomic_inc(&cm_node->listener->pend_accepts_cnt);
1490                if (atomic_read(&cm_node->listener->pend_accepts_cnt) >
1491                                cm_node->listener->backlog) {
1492                        nes_debug(NES_DBG_CM, "drop syn due to backlog "
1493                                "pressure \n");
1494                        cm_backlog_drops++;
1495                        passive_open_err(cm_node, skb, 0);
1496                        break;
1497                }
1498                ret = handle_tcp_options(cm_node, tcph, skb, optionsize,
1499                        1);
1500                if (ret) {
1501                        passive_open_err(cm_node, skb, 0);
1502                        /* drop pkt */
1503                        break;
1504                }
1505                cm_node->tcp_cntxt.rcv_nxt = inc_sequence + 1;
1506                BUG_ON(cm_node->send_entry);
1507                cm_node->state = NES_CM_STATE_SYN_RCVD;
1508                send_syn(cm_node, 1, skb);
1509                break;
1510        case NES_CM_STATE_TSA:
1511        case NES_CM_STATE_ESTABLISHED:
1512        case NES_CM_STATE_FIN_WAIT1:
1513        case NES_CM_STATE_FIN_WAIT2:
1514        case NES_CM_STATE_MPAREQ_RCVD:
1515        case NES_CM_STATE_LAST_ACK:
1516        case NES_CM_STATE_CLOSING:
1517        case NES_CM_STATE_UNKNOWN:
1518        case NES_CM_STATE_CLOSED:
1519        default:
1520                drop_packet(skb);
1521                break;
1522        }
1523}
1524
1525static void handle_synack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1526        struct tcphdr *tcph)
1527{
1528
1529        int ret;
1530        u32 inc_sequence;
1531        int optionsize;
1532
1533        optionsize = (tcph->doff << 2) - sizeof(struct tcphdr);
1534        skb_pull(skb, tcph->doff << 2);
1535        inc_sequence = ntohl(tcph->seq);
1536        switch (cm_node->state) {
1537        case NES_CM_STATE_SYN_SENT:
1538                /* active open */
1539                if (check_syn(cm_node, tcph, skb))
1540                        return;
1541                cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq);
1542                /* setup options */
1543                ret = handle_tcp_options(cm_node, tcph, skb, optionsize, 0);
1544                if (ret) {
1545                        nes_debug(NES_DBG_CM, "cm_node=%p tcp_options failed\n",
1546                                cm_node);
1547                        break;
1548                }
1549                cleanup_retrans_entry(cm_node);
1550                cm_node->tcp_cntxt.rcv_nxt = inc_sequence + 1;
1551                send_mpa_request(cm_node, skb);
1552                cm_node->state = NES_CM_STATE_MPAREQ_SENT;
1553                break;
1554        case NES_CM_STATE_MPAREQ_RCVD:
1555                /* passive open, so should not be here */
1556                passive_open_err(cm_node, skb, 1);
1557                break;
1558        case NES_CM_STATE_ESTABLISHED:
1559        case NES_CM_STATE_FIN_WAIT1:
1560        case NES_CM_STATE_FIN_WAIT2:
1561        case NES_CM_STATE_LAST_ACK:
1562        case NES_CM_STATE_TSA:
1563        case NES_CM_STATE_CLOSING:
1564        case NES_CM_STATE_UNKNOWN:
1565        case NES_CM_STATE_CLOSED:
1566        case NES_CM_STATE_MPAREQ_SENT:
1567        default:
1568                drop_packet(skb);
1569                break;
1570        }
1571}
1572
1573static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
1574        struct tcphdr *tcph)
1575{
1576        int datasize = 0;
1577        u32 inc_sequence;
1578        u32 rem_seq_ack;
1579        u32 rem_seq;
1580        if (check_seq(cm_node, tcph, skb))
1581                return;
1582
1583        skb_pull(skb, tcph->doff << 2);
1584        inc_sequence = ntohl(tcph->seq);
1585        rem_seq = ntohl(tcph->seq);
1586        rem_seq_ack =  ntohl(tcph->ack_seq);
1587        datasize = skb->len;
1588
1589        switch (cm_node->state) {
1590        case NES_CM_STATE_SYN_RCVD:
1591                /* Passive OPEN */
1592                cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq);
1593                cm_node->state = NES_CM_STATE_ESTABLISHED;
1594                if (datasize) {
1595                        cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
1596                        cm_node->state = NES_CM_STATE_MPAREQ_RCVD;
1597                        handle_rcv_mpa(cm_node, skb, NES_CM_EVENT_MPA_REQ);
1598                 } else { /* rcvd ACK only */
1599                        dev_kfree_skb_any(skb);
1600                        cleanup_retrans_entry(cm_node);
1601                 }
1602                break;
1603        case NES_CM_STATE_ESTABLISHED:
1604                /* Passive OPEN */
1605                /* We expect mpa frame to be received only */
1606                if (datasize) {
1607                        cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
1608                        cm_node->state = NES_CM_STATE_MPAREQ_RCVD;
1609                        handle_rcv_mpa(cm_node, skb,
1610                                NES_CM_EVENT_MPA_REQ);
1611                } else
1612                        drop_packet(skb);
1613                break;
1614        case NES_CM_STATE_MPAREQ_SENT:
1615                cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq);
1616                if (datasize) {
1617                        cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
1618                        handle_rcv_mpa(cm_node, skb, NES_CM_EVENT_CONNECTED);
1619                } else { /* Could be just an ack pkt.. */
1620                        cleanup_retrans_entry(cm_node);
1621                        dev_kfree_skb_any(skb);
1622                }
1623                break;
1624        case NES_CM_STATE_FIN_WAIT1:
1625        case NES_CM_STATE_SYN_SENT:
1626        case NES_CM_STATE_FIN_WAIT2:
1627        case NES_CM_STATE_TSA:
1628        case NES_CM_STATE_CLOSED:
1629        case NES_CM_STATE_MPAREQ_RCVD:
1630        case NES_CM_STATE_LAST_ACK:
1631        case NES_CM_STATE_CLOSING:
1632        case NES_CM_STATE_UNKNOWN:
1633        default:
1634                drop_packet(skb);
1635                break;
1636        }
1637}
1638
1639
1640
1641static int handle_tcp_options(struct nes_cm_node *cm_node, struct tcphdr *tcph,
1642        struct sk_buff *skb, int optionsize, int passive)
1643{
1644        u8 *optionsloc = (u8 *)&tcph[1];
1645        if (optionsize) {
1646                if (process_options(cm_node, optionsloc, optionsize,
1647                        (u32)tcph->syn)) {
1648                        nes_debug(NES_DBG_CM, "%s: Node %p, Sending RESET\n",
1649                                __func__, cm_node);
1650                        if (passive)
1651                                passive_open_err(cm_node, skb, 0);
1652                        else
1653                                active_open_err(cm_node, skb, 0);
1654                        return 1;
1655                }
1656        }
1657
1658        cm_node->tcp_cntxt.snd_wnd = ntohs(tcph->window) <<
1659                        cm_node->tcp_cntxt.snd_wscale;
1660
1661        if (cm_node->tcp_cntxt.snd_wnd > cm_node->tcp_cntxt.max_snd_wnd)
1662                cm_node->tcp_cntxt.max_snd_wnd = cm_node->tcp_cntxt.snd_wnd;
1663        return 0;
1664}
1665
1666/*
1667 * active_open_err() will send reset() if flag set..
1668 * It will also send ABORT event.
1669 */
1670
1671static void active_open_err(struct nes_cm_node *cm_node, struct sk_buff *skb,
1672        int reset)
1673{
1674        cleanup_retrans_entry(cm_node);
1675        if (reset) {
1676                nes_debug(NES_DBG_CM, "ERROR active err called for cm_node=%p, "
1677                                "state=%d\n", cm_node, cm_node->state);
1678                add_ref_cm_node(cm_node);
1679                send_reset(cm_node, skb);
1680        } else
1681                dev_kfree_skb_any(skb);
1682
1683        cm_node->state = NES_CM_STATE_CLOSED;
1684        create_event(cm_node, NES_CM_EVENT_ABORTED);
1685}
1686
1687/*
1688 * passive_open_err() will either do a reset() or will free up the skb and
1689 * remove the cm_node.
1690 */
1691
1692static void passive_open_err(struct nes_cm_node *cm_node, struct sk_buff *skb,
1693        int reset)
1694{
1695        cleanup_retrans_entry(cm_node);
1696        cm_node->state = NES_CM_STATE_CLOSED;
1697        if (reset) {
1698                nes_debug(NES_DBG_CM, "passive_open_err sending RST for "
1699                        "cm_node=%p state =%d\n", cm_node, cm_node->state);
1700                send_reset(cm_node, skb);
1701        } else {
1702                dev_kfree_skb_any(skb);
1703                rem_ref_cm_node(cm_node->cm_core, cm_node);
1704        }
1705}
1706
1707/*
1708 * free_retrans_entry() routines assumes that the retrans_list_lock has
1709 * been acquired before calling.
1710 */
1711static void free_retrans_entry(struct nes_cm_node *cm_node)
1712{
1713        struct nes_timer_entry *send_entry;
1714        send_entry = cm_node->send_entry;
1715        if (send_entry) {
1716                cm_node->send_entry = NULL;
1717                dev_kfree_skb_any(send_entry->skb);
1718                kfree(send_entry);
1719                rem_ref_cm_node(cm_node->cm_core, cm_node);
1720        }
1721}
1722
1723static void cleanup_retrans_entry(struct nes_cm_node *cm_node)
1724{
1725        unsigned long flags;
1726
1727        spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
1728        free_retrans_entry(cm_node);
1729        spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags);
1730}
1731
1732/**
1733 * process_packet
1734 * Returns skb if to be freed, else it will return NULL if already used..
1735 */
1736static void process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb,
1737        struct nes_cm_core *cm_core)
1738{
1739        enum nes_tcpip_pkt_type        pkt_type = NES_PKT_TYPE_UNKNOWN;
1740        struct tcphdr *tcph = tcp_hdr(skb);
1741        skb_pull(skb, ip_hdr(skb)->ihl << 2);
1742
1743        nes_debug(NES_DBG_CM, "process_packet: cm_node=%p state =%d syn=%d "
1744                "ack=%d rst=%d fin=%d\n", cm_node, cm_node->state, tcph->syn,
1745                tcph->ack, tcph->rst, tcph->fin);
1746
1747        if (tcph->rst)
1748                pkt_type = NES_PKT_TYPE_RST;
1749        else if (tcph->syn) {
1750                pkt_type = NES_PKT_TYPE_SYN;
1751                if (tcph->ack)
1752                        pkt_type = NES_PKT_TYPE_SYNACK;
1753        } else if (tcph->fin)
1754                pkt_type = NES_PKT_TYPE_FIN;
1755        else if (tcph->ack)
1756                pkt_type = NES_PKT_TYPE_ACK;
1757
1758        switch (pkt_type) {
1759        case NES_PKT_TYPE_SYN:
1760                handle_syn_pkt(cm_node, skb, tcph);
1761                break;
1762        case NES_PKT_TYPE_SYNACK:
1763                handle_synack_pkt(cm_node, skb, tcph);
1764                break;
1765        case NES_PKT_TYPE_ACK:
1766                handle_ack_pkt(cm_node, skb, tcph);
1767                break;
1768        case NES_PKT_TYPE_RST:
1769                handle_rst_pkt(cm_node, skb, tcph);
1770                break;
1771        case NES_PKT_TYPE_FIN:
1772                handle_fin_pkt(cm_node, skb, tcph);
1773                break;
1774        default:
1775                drop_packet(skb);
1776                break;
1777        }
1778}
1779
1780/**
1781 * mini_cm_listen - create a listen node with params
1782 */
1783static struct nes_cm_listener *mini_cm_listen(struct nes_cm_core *cm_core,
1784        struct nes_vnic *nesvnic, struct nes_cm_info *cm_info)
1785{
1786        struct nes_cm_listener *listener;
1787        unsigned long flags;
1788
1789        nes_debug(NES_DBG_CM, "Search for 0x%08x : 0x%04x\n",
1790                cm_info->loc_addr, cm_info->loc_port);
1791
1792        /* cannot have multiple matching listeners */
1793        listener = find_listener(cm_core, htonl(cm_info->loc_addr),
1794                        htons(cm_info->loc_port), NES_CM_LISTENER_EITHER_STATE);
1795        if (listener && listener->listener_state == NES_CM_LISTENER_ACTIVE_STATE) {
1796                /* find automatically incs ref count ??? */
1797                atomic_dec(&listener->ref_count);
1798                nes_debug(NES_DBG_CM, "Not creating listener since it already exists\n");
1799                return NULL;
1800        }
1801
1802        if (!listener) {
1803                /* create a CM listen node (1/2 node to compare incoming traffic to) */
1804                listener = kzalloc(sizeof(*listener), GFP_ATOMIC);
1805                if (!listener) {
1806                        nes_debug(NES_DBG_CM, "Not creating listener memory allocation failed\n");
1807                        return NULL;
1808                }
1809
1810                listener->loc_addr = htonl(cm_info->loc_addr);
1811                listener->loc_port = htons(cm_info->loc_port);
1812                listener->reused_node = 0;
1813
1814                atomic_set(&listener->ref_count, 1);
1815        }
1816        /* pasive case */
1817        /* find already inc'ed the ref count */
1818        else {
1819                listener->reused_node = 1;
1820        }
1821
1822        listener->cm_id = cm_info->cm_id;
1823        atomic_set(&listener->pend_accepts_cnt, 0);
1824        listener->cm_core = cm_core;
1825        listener->nesvnic = nesvnic;
1826        atomic_inc(&cm_core->node_cnt);
1827
1828        listener->conn_type = cm_info->conn_type;
1829        listener->backlog = cm_info->backlog;
1830        listener->listener_state = NES_CM_LISTENER_ACTIVE_STATE;
1831
1832        if (!listener->reused_node) {
1833                spin_lock_irqsave(&cm_core->listen_list_lock, flags);
1834                list_add(&listener->list, &cm_core->listen_list.list);
1835                spin_unlock_irqrestore(&cm_core->listen_list_lock, flags);
1836                atomic_inc(&cm_core->listen_node_cnt);
1837        }
1838
1839        nes_debug(NES_DBG_CM, "Api - listen(): addr=0x%08X, port=0x%04x,"
1840                        " listener = %p, backlog = %d, cm_id = %p.\n",
1841                        cm_info->loc_addr, cm_info->loc_port,
1842                        listener, listener->backlog, listener->cm_id);
1843
1844        return listener;
1845}
1846
1847
1848/**
1849 * mini_cm_connect - make a connection node with params
1850 */
1851static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core,
1852        struct nes_vnic *nesvnic, u16 private_data_len,
1853        void *private_data, struct nes_cm_info *cm_info)
1854{
1855        int ret = 0;
1856        struct nes_cm_node *cm_node;
1857        struct nes_cm_listener *loopbackremotelistener;
1858        struct nes_cm_node *loopbackremotenode;
1859        struct nes_cm_info loopback_cm_info;
1860        u16 mpa_frame_size = sizeof(struct ietf_mpa_frame) + private_data_len;
1861        struct ietf_mpa_frame *mpa_frame = NULL;
1862
1863        /* create a CM connection node */
1864        cm_node = make_cm_node(cm_core, nesvnic, cm_info, NULL);
1865        if (!cm_node)
1866                return NULL;
1867        mpa_frame = &cm_node->mpa_frame;
1868        strcpy(mpa_frame->key, IEFT_MPA_KEY_REQ);
1869        mpa_frame->flags = IETF_MPA_FLAGS_CRC;
1870        mpa_frame->rev =  IETF_MPA_VERSION;
1871        mpa_frame->priv_data_len = htons(private_data_len);
1872
1873        /* set our node side to client (active) side */
1874        cm_node->tcp_cntxt.client = 1;
1875        cm_node->tcp_cntxt.rcv_wscale = NES_CM_DEFAULT_RCV_WND_SCALE;
1876
1877        if (cm_info->loc_addr == cm_info->rem_addr) {
1878                loopbackremotelistener = find_listener(cm_core,
1879                                ntohl(nesvnic->local_ipaddr), cm_node->rem_port,
1880                                NES_CM_LISTENER_ACTIVE_STATE);
1881                if (loopbackremotelistener == NULL) {
1882                        create_event(cm_node, NES_CM_EVENT_ABORTED);
1883                } else {
1884                        atomic_inc(&cm_loopbacks);
1885                        loopback_cm_info = *cm_info;
1886                        loopback_cm_info.loc_port = cm_info->rem_port;
1887                        loopback_cm_info.rem_port = cm_info->loc_port;
1888                        loopback_cm_info.cm_id = loopbackremotelistener->cm_id;
1889                        loopbackremotenode = make_cm_node(cm_core, nesvnic,
1890                                &loopback_cm_info, loopbackremotelistener);
1891                        loopbackremotenode->loopbackpartner = cm_node;
1892                        loopbackremotenode->tcp_cntxt.rcv_wscale =
1893                                NES_CM_DEFAULT_RCV_WND_SCALE;
1894                        cm_node->loopbackpartner = loopbackremotenode;
1895                        memcpy(loopbackremotenode->mpa_frame_buf, private_data,
1896                                private_data_len);
1897                        loopbackremotenode->mpa_frame_size = private_data_len;
1898
1899                        /* we are done handling this state. */
1900                        /* set node to a TSA state */
1901                        cm_node->state = NES_CM_STATE_TSA;
1902                        cm_node->tcp_cntxt.rcv_nxt =
1903                                loopbackremotenode->tcp_cntxt.loc_seq_num;
1904                        loopbackremotenode->tcp_cntxt.rcv_nxt =
1905                                cm_node->tcp_cntxt.loc_seq_num;
1906                        cm_node->tcp_cntxt.max_snd_wnd =
1907                                loopbackremotenode->tcp_cntxt.rcv_wnd;
1908                        loopbackremotenode->tcp_cntxt.max_snd_wnd =
1909                                cm_node->tcp_cntxt.rcv_wnd;
1910                        cm_node->tcp_cntxt.snd_wnd =
1911                                loopbackremotenode->tcp_cntxt.rcv_wnd;
1912                        loopbackremotenode->tcp_cntxt.snd_wnd =
1913                                cm_node->tcp_cntxt.rcv_wnd;
1914                        cm_node->tcp_cntxt.snd_wscale =
1915                                loopbackremotenode->tcp_cntxt.rcv_wscale;
1916                        loopbackremotenode->tcp_cntxt.snd_wscale =
1917                                cm_node->tcp_cntxt.rcv_wscale;
1918
1919                        create_event(loopbackremotenode, NES_CM_EVENT_MPA_REQ);
1920                }
1921                return cm_node;
1922        }
1923
1924        /* set our node side to client (active) side */
1925        cm_node->tcp_cntxt.client = 1;
1926        /* init our MPA frame ptr */
1927        memcpy(mpa_frame->priv_data, private_data, private_data_len);
1928
1929        cm_node->mpa_frame_size = mpa_frame_size;
1930
1931        /* send a syn and goto syn sent state */
1932        cm_node->state = NES_CM_STATE_SYN_SENT;
1933        ret = send_syn(cm_node, 0, NULL);
1934
1935        if (ret) {
1936                /* error in sending the syn free up the cm_node struct */
1937                nes_debug(NES_DBG_CM, "Api - connect() FAILED: dest "
1938                        "addr=0x%08X, port=0x%04x, cm_node=%p, cm_id = %p.\n",
1939                        cm_node->rem_addr, cm_node->rem_port, cm_node,
1940                        cm_node->cm_id);
1941                rem_ref_cm_node(cm_node->cm_core, cm_node);
1942                cm_node = NULL;
1943        }
1944
1945        if (cm_node)
1946                nes_debug(NES_DBG_CM, "Api - connect(): dest addr=0x%08X,"
1947                        "port=0x%04x, cm_node=%p, cm_id = %p.\n",
1948                        cm_node->rem_addr, cm_node->rem_port, cm_node,
1949                        cm_node->cm_id);
1950
1951        return cm_node;
1952}
1953
1954
1955/**
1956 * mini_cm_accept - accept a connection
1957 * This function is never called
1958 */
1959static int mini_cm_accept(struct nes_cm_core *cm_core,
1960        struct ietf_mpa_frame *mpa_frame, struct nes_cm_node *cm_node)
1961{
1962        return 0;
1963}
1964
1965
1966/**
1967 * mini_cm_reject - reject and teardown a connection
1968 */
1969static int mini_cm_reject(struct nes_cm_core *cm_core,
1970        struct ietf_mpa_frame *mpa_frame, struct nes_cm_node *cm_node)
1971{
1972        int ret = 0;
1973
1974        nes_debug(NES_DBG_CM, "%s cm_node=%p type=%d state=%d\n",
1975                __func__, cm_node, cm_node->tcp_cntxt.client, cm_node->state);
1976
1977        if (cm_node->tcp_cntxt.client)
1978                return ret;
1979        cleanup_retrans_entry(cm_node);
1980        cm_node->state = NES_CM_STATE_CLOSED;
1981
1982        ret = send_reset(cm_node, NULL);
1983        return ret;
1984}
1985
1986
1987/**
1988 * mini_cm_close
1989 */
1990static int mini_cm_close(struct nes_cm_core *cm_core, struct nes_cm_node *cm_node)
1991{
1992        int ret = 0;
1993
1994        if (!cm_core || !cm_node)
1995                return -EINVAL;
1996
1997        switch (cm_node->state) {
1998        case NES_CM_STATE_SYN_RCVD:
1999        case NES_CM_STATE_SYN_SENT:
2000        case NES_CM_STATE_ONE_SIDE_ESTABLISHED:
2001        case NES_CM_STATE_ESTABLISHED:
2002        case NES_CM_STATE_ACCEPTING:
2003        case NES_CM_STATE_MPAREQ_SENT:
2004        case NES_CM_STATE_MPAREQ_RCVD:
2005                cleanup_retrans_entry(cm_node);
2006                send_reset(cm_node, NULL);
2007                break;
2008        case NES_CM_STATE_CLOSE_WAIT:
2009                cm_node->state = NES_CM_STATE_LAST_ACK;
2010                send_fin(cm_node, NULL);
2011                break;
2012        case NES_CM_STATE_FIN_WAIT1:
2013        case NES_CM_STATE_FIN_WAIT2:
2014        case NES_CM_STATE_LAST_ACK:
2015        case NES_CM_STATE_TIME_WAIT:
2016        case NES_CM_STATE_CLOSING:
2017                ret = -1;
2018                break;
2019        case NES_CM_STATE_LISTENING:
2020        case NES_CM_STATE_UNKNOWN:
2021        case NES_CM_STATE_INITED:
2022        case NES_CM_STATE_CLOSED:
2023                ret = rem_ref_cm_node(cm_core, cm_node);
2024                break;
2025        case NES_CM_STATE_TSA:
2026                if (cm_node->send_entry)
2027                        printk(KERN_ERR "ERROR Close got called from STATE_TSA "
2028                                "send_entry=%p\n", cm_node->send_entry);
2029                ret = rem_ref_cm_node(cm_core, cm_node);
2030                break;
2031        }
2032        return ret;
2033}
2034
2035
2036/**
2037 * recv_pkt - recv an ETHERNET packet, and process it through CM
2038 * node state machine
2039 */
2040static void mini_cm_recv_pkt(struct nes_cm_core *cm_core,
2041        struct nes_vnic *nesvnic, struct sk_buff *skb)
2042{
2043        struct nes_cm_node *cm_node = NULL;
2044        struct nes_cm_listener *listener = NULL;
2045        struct iphdr *iph;
2046        struct tcphdr *tcph;
2047        struct nes_cm_info nfo;
2048
2049        if (!skb)
2050                return;
2051        if (skb->len < sizeof(struct iphdr) + sizeof(struct tcphdr)) {
2052                dev_kfree_skb_any(skb);
2053                return;
2054        }
2055
2056        iph = (struct iphdr *)skb->data;
2057        tcph = (struct tcphdr *)(skb->data + sizeof(struct iphdr));
2058        skb_reset_network_header(skb);
2059        skb_set_transport_header(skb, sizeof(*tcph));
2060        if (!tcph) {
2061                dev_kfree_skb_any(skb);
2062                return;
2063        }
2064        skb->len = ntohs(iph->tot_len);
2065
2066        nfo.loc_addr = ntohl(iph->daddr);
2067        nfo.loc_port = ntohs(tcph->dest);
2068        nfo.rem_addr = ntohl(iph->saddr);
2069        nfo.rem_port = ntohs(tcph->source);
2070
2071        nes_debug(NES_DBG_CM, "Received packet: dest=" NIPQUAD_FMT
2072                  ":0x%04X src=" NIPQUAD_FMT ":0x%04X\n",
2073                  NIPQUAD(iph->daddr), tcph->dest,
2074                  NIPQUAD(iph->saddr), tcph->source);
2075
2076        do {
2077                cm_node = find_node(cm_core,
2078                        nfo.rem_port, nfo.rem_addr,
2079                        nfo.loc_port, nfo.loc_addr);
2080
2081                if (!cm_node) {
2082                        /* Only type of packet accepted are for */
2083                        /* the PASSIVE open (syn only) */
2084                        if ((!tcph->syn) || (tcph->ack)) {
2085                                cm_packets_dropped++;
2086                                break;
2087                        }
2088                        listener = find_listener(cm_core, nfo.loc_addr,
2089                                nfo.loc_port,
2090                                NES_CM_LISTENER_ACTIVE_STATE);
2091                        if (listener) {
2092                                nfo.cm_id = listener->cm_id;
2093                                nfo.conn_type = listener->conn_type;
2094                        } else {
2095                                nes_debug(NES_DBG_CM, "Unable to find listener "
2096                                        "for the pkt\n");
2097                                cm_packets_dropped++;
2098                                dev_kfree_skb_any(skb);
2099                                break;
2100                        }
2101
2102                        cm_node = make_cm_node(cm_core, nesvnic, &nfo,
2103                                listener);
2104                        if (!cm_node) {
2105                                nes_debug(NES_DBG_CM, "Unable to allocate "
2106                                        "node\n");
2107                                cm_packets_dropped++;
2108                                atomic_dec(&listener->ref_count);
2109                                dev_kfree_skb_any(skb);
2110                                break;
2111                        }
2112                        if (!tcph->rst && !tcph->fin) {
2113                                cm_node->state = NES_CM_STATE_LISTENING;
2114                        } else {
2115                                cm_packets_dropped++;
2116                                rem_ref_cm_node(cm_core, cm_node);
2117                                dev_kfree_skb_any(skb);
2118                                break;
2119                        }
2120                        add_ref_cm_node(cm_node);
2121                } else if (cm_node->state == NES_CM_STATE_TSA) {
2122                        rem_ref_cm_node(cm_core, cm_node);
2123                        atomic_inc(&cm_accel_dropped_pkts);
2124                        dev_kfree_skb_any(skb);
2125                        break;
2126                }
2127                process_packet(cm_node, skb, cm_core);
2128                rem_ref_cm_node(cm_core, cm_node);
2129        } while (0);
2130}
2131
2132
2133/**
2134 * nes_cm_alloc_core - allocate a top level instance of a cm core
2135 */
2136static struct nes_cm_core *nes_cm_alloc_core(void)
2137{
2138        int i;
2139
2140        struct nes_cm_core *cm_core;
2141        struct sk_buff *skb = NULL;
2142
2143        /* setup the CM core */
2144        /* alloc top level core control structure */
2145        cm_core = kzalloc(sizeof(*cm_core), GFP_KERNEL);
2146        if (!cm_core)
2147                return NULL;
2148
2149        INIT_LIST_HEAD(&cm_core->connected_nodes);
2150        init_timer(&cm_core->tcp_timer);
2151        cm_core->tcp_timer.function = nes_cm_timer_tick;
2152
2153        cm_core->mtu   = NES_CM_DEFAULT_MTU;
2154        cm_core->state = NES_CM_STATE_INITED;
2155        cm_core->free_tx_pkt_max = NES_CM_DEFAULT_FREE_PKTS;
2156
2157        atomic_set(&cm_core->events_posted, 0);
2158
2159        /* init the packet lists */
2160        skb_queue_head_init(&cm_core->tx_free_list);
2161
2162        for (i = 0; i < NES_CM_DEFAULT_FRAME_CNT; i++) {
2163                skb = dev_alloc_skb(cm_core->mtu);
2164                if (!skb) {
2165                        kfree(cm_core);
2166                        return NULL;
2167                }
2168                /* add 'raw' skb to free frame list */
2169                skb_queue_head(&cm_core->tx_free_list, skb);
2170        }
2171
2172        cm_core->api = &nes_cm_api;
2173
2174        spin_lock_init(&cm_core->ht_lock);
2175        spin_lock_init(&cm_core->listen_list_lock);
2176
2177        INIT_LIST_HEAD(&cm_core->listen_list.list);
2178
2179        nes_debug(NES_DBG_CM, "Init CM Core completed -- cm_core=%p\n", cm_core);
2180
2181        nes_debug(NES_DBG_CM, "Enable QUEUE EVENTS\n");
2182        cm_core->event_wq = create_singlethread_workqueue("nesewq");
2183        cm_core->post_event = nes_cm_post_event;
2184        nes_debug(NES_DBG_CM, "Enable QUEUE DISCONNECTS\n");
2185        cm_core->disconn_wq = create_singlethread_workqueue("nesdwq");
2186
2187        print_core(cm_core);
2188        return cm_core;
2189}
2190
2191
2192/**
2193 * mini_cm_dealloc_core - deallocate a top level instance of a cm core
2194 */
2195static int mini_cm_dealloc_core(struct nes_cm_core *cm_core)
2196{
2197        nes_debug(NES_DBG_CM, "De-Alloc CM Core (%p)\n", cm_core);
2198
2199        if (!cm_core)
2200                return -EINVAL;
2201
2202        barrier();
2203
2204        if (timer_pending(&cm_core->tcp_timer)) {
2205                del_timer(&cm_core->tcp_timer);
2206        }
2207
2208        destroy_workqueue(cm_core->event_wq);
2209        destroy_workqueue(cm_core->disconn_wq);
2210        nes_debug(NES_DBG_CM, "\n");
2211        kfree(cm_core);
2212
2213        return 0;
2214}
2215
2216
2217/**
2218 * mini_cm_get
2219 */
2220static int mini_cm_get(struct nes_cm_core *cm_core)
2221{
2222        return cm_core->state;
2223}
2224
2225
2226/**
2227 * mini_cm_set
2228 */
2229static int mini_cm_set(struct nes_cm_core *cm_core, u32 type, u32 value)
2230{
2231        int ret = 0;
2232
2233        switch (type) {
2234                case NES_CM_SET_PKT_SIZE:
2235                        cm_core->mtu = value;
2236                        break;
2237                case NES_CM_SET_FREE_PKT_Q_SIZE:
2238                        cm_core->free_tx_pkt_max = value;
2239                        break;
2240                default:
2241                        /* unknown set option */
2242                        ret = -EINVAL;
2243        }
2244
2245        return ret;
2246}
2247
2248
2249/**
2250 * nes_cm_init_tsa_conn setup HW; MPA frames must be
2251 * successfully exchanged when this is called
2252 */
2253static int nes_cm_init_tsa_conn(struct nes_qp *nesqp, struct nes_cm_node *cm_node)
2254{
2255        int ret = 0;
2256
2257        if (!nesqp)
2258                return -EINVAL;
2259
2260        nesqp->nesqp_context->misc |= cpu_to_le32(NES_QPCONTEXT_MISC_IPV4 |
2261                        NES_QPCONTEXT_MISC_NO_NAGLE | NES_QPCONTEXT_MISC_DO_NOT_FRAG |
2262                        NES_QPCONTEXT_MISC_DROS);
2263
2264        if (cm_node->tcp_cntxt.snd_wscale || cm_node->tcp_cntxt.rcv_wscale)
2265                nesqp->nesqp_context->misc |= cpu_to_le32(NES_QPCONTEXT_MISC_WSCALE);
2266
2267        nesqp->nesqp_context->misc2 |= cpu_to_le32(64 << NES_QPCONTEXT_MISC2_TTL_SHIFT);
2268
2269        nesqp->nesqp_context->mss |= cpu_to_le32(((u32)cm_node->tcp_cntxt.mss) << 16);
2270
2271        nesqp->nesqp_context->tcp_state_flow_label |= cpu_to_le32(
2272                        (u32)NES_QPCONTEXT_TCPSTATE_EST << NES_QPCONTEXT_TCPFLOW_TCP_STATE_SHIFT);
2273
2274        nesqp->nesqp_context->pd_index_wscale |= cpu_to_le32(
2275                        (cm_node->tcp_cntxt.snd_wscale << NES_QPCONTEXT_PDWSCALE_SND_WSCALE_SHIFT) &
2276                        NES_QPCONTEXT_PDWSCALE_SND_WSCALE_MASK);
2277
2278        nesqp->nesqp_context->pd_index_wscale |= cpu_to_le32(
2279                        (cm_node->tcp_cntxt.rcv_wscale << NES_QPCONTEXT_PDWSCALE_RCV_WSCALE_SHIFT) &
2280                        NES_QPCONTEXT_PDWSCALE_RCV_WSCALE_MASK);
2281
2282        nesqp->nesqp_context->keepalive = cpu_to_le32(0x80);
2283        nesqp->nesqp_context->ts_recent = 0;
2284        nesqp->nesqp_context->ts_age = 0;
2285        nesqp->nesqp_context->snd_nxt = cpu_to_le32(cm_node->tcp_cntxt.loc_seq_num);
2286        nesqp->nesqp_context->snd_wnd = cpu_to_le32(cm_node->tcp_cntxt.snd_wnd);
2287        nesqp->nesqp_context->rcv_nxt = cpu_to_le32(cm_node->tcp_cntxt.rcv_nxt);
2288        nesqp->nesqp_context->rcv_wnd = cpu_to_le32(cm_node->tcp_cntxt.rcv_wnd <<
2289                        cm_node->tcp_cntxt.rcv_wscale);
2290        nesqp->nesqp_context->snd_max = cpu_to_le32(cm_node->tcp_cntxt.loc_seq_num);
2291        nesqp->nesqp_context->snd_una = cpu_to_le32(cm_node->tcp_cntxt.loc_seq_num);
2292        nesqp->nesqp_context->srtt = 0;
2293        nesqp->nesqp_context->rttvar = cpu_to_le32(0x6);
2294        nesqp->nesqp_context->ssthresh = cpu_to_le32(0x3FFFC000);
2295        nesqp->nesqp_context->cwnd = cpu_to_le32(2*cm_node->tcp_cntxt.mss);
2296        nesqp->nesqp_context->snd_wl1 = cpu_to_le32(cm_node->tcp_cntxt.rcv_nxt);
2297        nesqp->nesqp_context->snd_wl2 = cpu_to_le32(cm_node->tcp_cntxt.loc_seq_num);
2298        nesqp->nesqp_context->max_snd_wnd = cpu_to_le32(cm_node->tcp_cntxt.max_snd_wnd);
2299
2300        nes_debug(NES_DBG_CM, "QP%u: rcv_nxt = 0x%08X, snd_nxt = 0x%08X,"
2301                        " Setting MSS to %u, PDWscale = 0x%08X, rcv_wnd = %u, context misc = 0x%08X.\n",
2302                        nesqp->hwqp.qp_id, le32_to_cpu(nesqp->nesqp_context->rcv_nxt),
2303                        le32_to_cpu(nesqp->nesqp_context->snd_nxt),
2304                        cm_node->tcp_cntxt.mss, le32_to_cpu(nesqp->nesqp_context->pd_index_wscale),
2305                        le32_to_cpu(nesqp->nesqp_context->rcv_wnd),
2306                        le32_to_cpu(nesqp->nesqp_context->misc));
2307        nes_debug(NES_DBG_CM, "  snd_wnd  = 0x%08X.\n", le32_to_cpu(nesqp->nesqp_context->snd_wnd));
2308        nes_debug(NES_DBG_CM, "  snd_cwnd = 0x%08X.\n", le32_to_cpu(nesqp->nesqp_context->cwnd));
2309        nes_debug(NES_DBG_CM, "  max_swnd = 0x%08X.\n", le32_to_cpu(nesqp->nesqp_context->max_snd_wnd));
2310
2311        nes_debug(NES_DBG_CM, "Change cm_node state to TSA\n");
2312        cm_node->state = NES_CM_STATE_TSA;
2313
2314        return ret;
2315}
2316
2317
2318/**
2319 * nes_cm_disconn
2320 */
2321int nes_cm_disconn(struct nes_qp *nesqp)
2322{
2323        unsigned long flags;
2324
2325        spin_lock_irqsave(&nesqp->lock, flags);
2326        if (nesqp->disconn_pending == 0) {
2327                nesqp->disconn_pending++;
2328                spin_unlock_irqrestore(&nesqp->lock, flags);
2329                /* init our disconnect work element, to */
2330                INIT_WORK(&nesqp->disconn_work, nes_disconnect_worker);
2331
2332                queue_work(g_cm_core->disconn_wq, &nesqp->disconn_work);
2333        } else
2334                spin_unlock_irqrestore(&nesqp->lock, flags);
2335
2336        return 0;
2337}
2338
2339
2340/**
2341 * nes_disconnect_worker
2342 */
2343static void nes_disconnect_worker(struct work_struct *work)
2344{
2345        struct nes_qp *nesqp = container_of(work, struct nes_qp, disconn_work);
2346
2347        nes_debug(NES_DBG_CM, "processing AEQE id 0x%04X for QP%u.\n",
2348                        nesqp->last_aeq, nesqp->hwqp.qp_id);
2349        nes_cm_disconn_true(nesqp);
2350}
2351
2352
2353/**
2354 * nes_cm_disconn_true
2355 */
2356static int nes_cm_disconn_true(struct nes_qp *nesqp)
2357{
2358        unsigned long flags;
2359        int ret = 0;
2360        struct iw_cm_id *cm_id;
2361        struct iw_cm_event cm_event;
2362        struct nes_vnic *nesvnic;
2363        u16 last_ae;
2364        u8 original_hw_tcp_state;
2365        u8 original_ibqp_state;
2366        u8 issued_disconnect_reset = 0;
2367
2368        if (!nesqp) {
2369                nes_debug(NES_DBG_CM, "disconnect_worker nesqp is NULL\n");
2370                return -1;
2371        }
2372
2373        spin_lock_irqsave(&nesqp->lock, flags);
2374        cm_id = nesqp->cm_id;
2375        /* make sure we havent already closed this connection */
2376        if (!cm_id) {
2377                nes_debug(NES_DBG_CM, "QP%u disconnect_worker cmid is NULL\n",
2378                                nesqp->hwqp.qp_id);
2379                spin_unlock_irqrestore(&nesqp->lock, flags);
2380                return -1;
2381        }
2382
2383        nesvnic = to_nesvnic(nesqp->ibqp.device);
2384        nes_debug(NES_DBG_CM, "Disconnecting QP%u\n", nesqp->hwqp.qp_id);
2385
2386        original_hw_tcp_state = nesqp->hw_tcp_state;
2387        original_ibqp_state   = nesqp->ibqp_state;
2388        last_ae = nesqp->last_aeq;
2389
2390
2391        nes_debug(NES_DBG_CM, "set ibqp_state=%u\n", nesqp->ibqp_state);
2392
2393        if ((nesqp->cm_id) && (cm_id->event_handler)) {
2394                if ((original_hw_tcp_state == NES_AEQE_TCP_STATE_CLOSE_WAIT) ||
2395                                ((original_ibqp_state == IB_QPS_RTS) &&
2396                                (last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET))) {
2397                        atomic_inc(&cm_disconnects);
2398                        cm_event.event = IW_CM_EVENT_DISCONNECT;
2399                        if (last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET) {
2400                                issued_disconnect_reset = 1;
2401                                cm_event.status = IW_CM_EVENT_STATUS_RESET;
2402                                nes_debug(NES_DBG_CM, "Generating a CM "
2403                                        "Disconnect Event (status reset) for "
2404                                        "QP%u, cm_id = %p. \n",
2405                                        nesqp->hwqp.qp_id, cm_id);
2406                        } else
2407                                cm_event.status = IW_CM_EVENT_STATUS_OK;
2408
2409                        cm_event.local_addr = cm_id->local_addr;
2410                        cm_event.remote_addr = cm_id->remote_addr;
2411                        cm_event.private_data = NULL;
2412                        cm_event.private_data_len = 0;
2413
2414                        nes_debug(NES_DBG_CM, "Generating a CM Disconnect Event"
2415                                " for  QP%u, SQ Head = %u, SQ Tail = %u. "
2416                                "cm_id = %p, refcount = %u.\n",
2417                                nesqp->hwqp.qp_id, nesqp->hwqp.sq_head,
2418                                nesqp->hwqp.sq_tail, cm_id,
2419                                atomic_read(&nesqp->refcount));
2420
2421                        spin_unlock_irqrestore(&nesqp->lock, flags);
2422                        ret = cm_id->event_handler(cm_id, &cm_event);
2423                        if (ret)
2424                                nes_debug(NES_DBG_CM, "OFA CM event_handler "
2425                                        "returned, ret=%d\n", ret);
2426                        spin_lock_irqsave(&nesqp->lock, flags);
2427                }
2428
2429                nesqp->disconn_pending = 0;
2430                /* There might have been another AE while the lock was released */
2431                original_hw_tcp_state = nesqp->hw_tcp_state;
2432                original_ibqp_state   = nesqp->ibqp_state;
2433                last_ae = nesqp->last_aeq;
2434
2435                if ((issued_disconnect_reset == 0) && (nesqp->cm_id) &&
2436                                ((original_hw_tcp_state == NES_AEQE_TCP_STATE_CLOSED) ||
2437                                 (original_hw_tcp_state == NES_AEQE_TCP_STATE_TIME_WAIT) ||
2438                                 (last_ae == NES_AEQE_AEID_RDMAP_ROE_BAD_LLP_CLOSE) ||
2439                                 (last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET))) {
2440                        atomic_inc(&cm_closes);
2441                        nesqp->cm_id = NULL;
2442                        nesqp->in_disconnect = 0;
2443                        spin_unlock_irqrestore(&nesqp->lock, flags);
2444                        nes_disconnect(nesqp, 1);
2445
2446                        cm_id->provider_data = nesqp;
2447                        /* Send up the close complete event */
2448                        cm_event.event = IW_CM_EVENT_CLOSE;
2449                        cm_event.status = IW_CM_EVENT_STATUS_OK;
2450                        cm_event.provider_data = cm_id->provider_data;
2451                        cm_event.local_addr = cm_id->local_addr;
2452                        cm_event.remote_addr = cm_id->remote_addr;
2453                        cm_event.private_data = NULL;
2454                        cm_event.private_data_len = 0;
2455
2456                        ret = cm_id->event_handler(cm_id, &cm_event);
2457                        if (ret) {
2458                                nes_debug(NES_DBG_CM, "OFA CM event_handler returned, ret=%d\n", ret);
2459                        }
2460
2461                        cm_id->rem_ref(cm_id);
2462
2463                        spin_lock_irqsave(&nesqp->lock, flags);
2464                        if (nesqp->flush_issued == 0) {
2465                                nesqp->flush_issued = 1;
2466                                spin_unlock_irqrestore(&nesqp->lock, flags);
2467                                flush_wqes(nesvnic->nesdev, nesqp,
2468                                        NES_CQP_FLUSH_RQ, 1);
2469                        } else
2470                                spin_unlock_irqrestore(&nesqp->lock, flags);
2471                } else {
2472                        cm_id = nesqp->cm_id;
2473                        spin_unlock_irqrestore(&nesqp->lock, flags);
2474                        /* check to see if the inbound reset beat the outbound reset */
2475                        if ((!cm_id) && (last_ae==NES_AEQE_AEID_RESET_SENT)) {
2476                                nes_debug(NES_DBG_CM, "QP%u: Decing refcount "
2477                                        "due to inbound reset beating the "
2478                                        "outbound reset.\n", nesqp->hwqp.qp_id);
2479                        }
2480                }
2481        } else {
2482                nesqp->disconn_pending = 0;
2483                spin_unlock_irqrestore(&nesqp->lock, flags);
2484        }
2485
2486        return 0;
2487}
2488
2489
2490/**
2491 * nes_disconnect
2492 */
2493static int nes_disconnect(struct nes_qp *nesqp, int abrupt)
2494{
2495        int ret = 0;
2496        struct nes_vnic *nesvnic;
2497        struct nes_device *nesdev;
2498
2499        nesvnic = to_nesvnic(nesqp->ibqp.device);
2500        if (!nesvnic)
2501                return -EINVAL;
2502
2503        nesdev = nesvnic->nesdev;
2504
2505        nes_debug(NES_DBG_CM, "netdev refcnt = %u.\n",
2506                        atomic_read(&nesvnic->netdev->refcnt));
2507
2508        if (nesqp->active_conn) {
2509
2510                /* indicate this connection is NOT active */
2511                nesqp->active_conn = 0;
2512        } else {
2513                /* Need to free the Last Streaming Mode Message */
2514                if (nesqp->ietf_frame) {
2515                        pci_free_consistent(nesdev->pcidev,
2516                                        nesqp->private_data_len+sizeof(struct ietf_mpa_frame),
2517                                        nesqp->ietf_frame, nesqp->ietf_frame_pbase);
2518                }
2519        }
2520
2521        /* close the CM node down if it is still active */
2522        if (nesqp->cm_node) {
2523                nes_debug(NES_DBG_CM, "Call close API\n");
2524
2525                g_cm_core->api->close(g_cm_core, nesqp->cm_node);
2526        }
2527
2528        return ret;
2529}
2530
2531
2532/**
2533 * nes_accept
2534 */
2535int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
2536{
2537        u64 u64temp;
2538        struct ib_qp *ibqp;
2539        struct nes_qp *nesqp;
2540        struct nes_vnic *nesvnic;
2541        struct nes_device *nesdev;
2542        struct nes_cm_node *cm_node;
2543        struct nes_adapter *adapter;
2544        struct ib_qp_attr attr;
2545        struct iw_cm_event cm_event;
2546        struct nes_hw_qp_wqe *wqe;
2547        struct nes_v4_quad nes_quad;
2548        u32 crc_value;
2549        int ret;
2550
2551        ibqp = nes_get_qp(cm_id->device, conn_param->qpn);
2552        if (!ibqp)
2553                return -EINVAL;
2554
2555        /* get all our handles */
2556        nesqp = to_nesqp(ibqp);
2557        nesvnic = to_nesvnic(nesqp->ibqp.device);
2558        nesdev = nesvnic->nesdev;
2559        adapter = nesdev->nesadapter;
2560
2561        cm_node = (struct nes_cm_node *)cm_id->provider_data;
2562        nes_debug(NES_DBG_CM, "nes_accept: cm_node= %p nesvnic=%p, netdev=%p,"
2563                "%s\n", cm_node, nesvnic, nesvnic->netdev,
2564                nesvnic->netdev->name);
2565
2566        /* associate the node with the QP */
2567        nesqp->cm_node = (void *)cm_node;
2568        cm_node->nesqp = nesqp;
2569        nes_add_ref(&nesqp->ibqp);
2570
2571        nes_debug(NES_DBG_CM, "QP%u, cm_node=%p, jiffies = %lu listener = %p\n",
2572                nesqp->hwqp.qp_id, cm_node, jiffies, cm_node->listener);
2573        atomic_inc(&cm_accepts);
2574
2575        nes_debug(NES_DBG_CM, "netdev refcnt = %u.\n",
2576                        atomic_read(&nesvnic->netdev->refcnt));
2577
2578        /* allocate the ietf frame and space for private data */
2579        nesqp->ietf_frame = pci_alloc_consistent(nesdev->pcidev,
2580                sizeof(struct ietf_mpa_frame) + conn_param->private_data_len,
2581                &nesqp->ietf_frame_pbase);
2582
2583        if (!nesqp->ietf_frame) {
2584                nes_debug(NES_DBG_CM, "Unable to allocate memory for private "
2585                        "data\n");
2586                return -ENOMEM;
2587        }
2588
2589
2590        /* setup the MPA frame */
2591        nesqp->private_data_len = conn_param->private_data_len;
2592        memcpy(nesqp->ietf_frame->key, IEFT_MPA_KEY_REP, IETF_MPA_KEY_SIZE);
2593
2594        memcpy(nesqp->ietf_frame->priv_data, conn_param->private_data,
2595                        conn_param->private_data_len);
2596
2597        nesqp->ietf_frame->priv_data_len =
2598                cpu_to_be16(conn_param->private_data_len);
2599        nesqp->ietf_frame->rev = mpa_version;
2600        nesqp->ietf_frame->flags = IETF_MPA_FLAGS_CRC;
2601
2602        /* setup our first outgoing iWarp send WQE (the IETF frame response) */
2603        wqe = &nesqp->hwqp.sq_vbase[0];
2604
2605        if (cm_id->remote_addr.sin_addr.s_addr !=
2606                        cm_id->local_addr.sin_addr.s_addr) {
2607                u64temp = (unsigned long)nesqp;
2608                u64temp |= NES_SW_CONTEXT_ALIGN>>1;
2609                set_wqe_64bit_value(wqe->wqe_words,
2610                        NES_IWARP_SQ_WQE_COMP_CTX_LOW_IDX,
2611                        u64temp);
2612                wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] =
2613                        cpu_to_le32(NES_IWARP_SQ_WQE_STREAMING |
2614                        NES_IWARP_SQ_WQE_WRPDU);
2615                wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX] =
2616                        cpu_to_le32(conn_param->private_data_len +
2617                        sizeof(struct ietf_mpa_frame));
2618                wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_LOW_IDX] =
2619                        cpu_to_le32((u32)nesqp->ietf_frame_pbase);
2620                wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_HIGH_IDX] =
2621                        cpu_to_le32((u32)((u64)nesqp->ietf_frame_pbase >> 32));
2622                wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] =
2623                        cpu_to_le32(conn_param->private_data_len +
2624                        sizeof(struct ietf_mpa_frame));
2625                wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = 0;
2626
2627                nesqp->nesqp_context->ird_ord_sizes |=
2628                        cpu_to_le32(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT |
2629                        NES_QPCONTEXT_ORDIRD_WRPDU);
2630        } else {
2631                nesqp->nesqp_context->ird_ord_sizes |=
2632                        cpu_to_le32((NES_QPCONTEXT_ORDIRD_LSMM_PRESENT |
2633                        NES_QPCONTEXT_ORDIRD_WRPDU |
2634                        NES_QPCONTEXT_ORDIRD_ALSMM));
2635        }
2636        nesqp->skip_lsmm = 1;
2637
2638
2639        /* Cache the cm_id in the qp */
2640        nesqp->cm_id = cm_id;
2641        cm_node->cm_id = cm_id;
2642
2643        /*  nesqp->cm_node = (void *)cm_id->provider_data; */
2644        cm_id->provider_data = nesqp;
2645        nesqp->active_conn   = 0;
2646
2647        if (cm_node->state == NES_CM_STATE_TSA)
2648                nes_debug(NES_DBG_CM, "Already state = TSA for cm_node=%p\n",
2649                        cm_node);
2650
2651        nes_cm_init_tsa_conn(nesqp, cm_node);
2652
2653        nesqp->nesqp_context->tcpPorts[0] =
2654                cpu_to_le16(ntohs(cm_id->local_addr.sin_port));
2655        nesqp->nesqp_context->tcpPorts[1] =
2656                cpu_to_le16(ntohs(cm_id->remote_addr.sin_port));
2657
2658        if (ipv4_is_loopback(cm_id->remote_addr.sin_addr.s_addr))
2659                nesqp->nesqp_context->ip0 =
2660                        cpu_to_le32(ntohl(nesvnic->local_ipaddr));
2661        else
2662                nesqp->nesqp_context->ip0 =
2663                        cpu_to_le32(ntohl(cm_id->remote_addr.sin_addr.s_addr));
2664
2665        nesqp->nesqp_context->misc2 |= cpu_to_le32(
2666                        (u32)PCI_FUNC(nesdev->pcidev->devfn) <<
2667                        NES_QPCONTEXT_MISC2_SRC_IP_SHIFT);
2668
2669        nesqp->nesqp_context->arp_index_vlan |=
2670                cpu_to_le32(nes_arp_table(nesdev,
2671                        le32_to_cpu(nesqp->nesqp_context->ip0), NULL,
2672                        NES_ARP_RESOLVE) << 16);
2673
2674        nesqp->nesqp_context->ts_val_delta = cpu_to_le32(
2675                jiffies - nes_read_indexed(nesdev, NES_IDX_TCP_NOW));
2676
2677        nesqp->nesqp_context->ird_index = cpu_to_le32(nesqp->hwqp.qp_id);
2678
2679        nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32(
2680                ((u32)1 << NES_QPCONTEXT_ORDIRD_IWARP_MODE_SHIFT));
2681        nesqp->nesqp_context->ird_ord_sizes |=
2682                cpu_to_le32((u32)conn_param->ord);
2683
2684        memset(&nes_quad, 0, sizeof(nes_quad));
2685        nes_quad.DstIpAdrIndex =
2686                cpu_to_le32((u32)PCI_FUNC(nesdev->pcidev->devfn) << 24);
2687        if (ipv4_is_loopback(cm_id->remote_addr.sin_addr.s_addr))
2688                nes_quad.SrcIpadr = nesvnic->local_ipaddr;
2689        else
2690                nes_quad.SrcIpadr = cm_id->remote_addr.sin_addr.s_addr;
2691        nes_quad.TcpPorts[0] = cm_id->remote_addr.sin_port;
2692        nes_quad.TcpPorts[1] = cm_id->local_addr.sin_port;
2693
2694        /* Produce hash key */
2695        crc_value = get_crc_value(&nes_quad);
2696        nesqp->hte_index = cpu_to_be32(crc_value ^ 0xffffffff);
2697        nes_debug(NES_DBG_CM, "HTE Index = 0x%08X, CRC = 0x%08X\n",
2698                nesqp->hte_index, nesqp->hte_index & adapter->hte_index_mask);
2699
2700        nesqp->hte_index &= adapter->hte_index_mask;
2701        nesqp->nesqp_context->hte_index = cpu_to_le32(nesqp->hte_index);
2702
2703        cm_node->cm_core->api->accelerated(cm_node->cm_core, cm_node);
2704
2705        nes_debug(NES_DBG_CM, "QP%u, Destination IP = 0x%08X:0x%04X, local = "
2706                        "0x%08X:0x%04X, rcv_nxt=0x%08X, snd_nxt=0x%08X, mpa + "
2707                        "private data length=%zu.\n", nesqp->hwqp.qp_id,
2708                        ntohl(cm_id->remote_addr.sin_addr.s_addr),
2709                        ntohs(cm_id->remote_addr.sin_port),
2710                        ntohl(cm_id->local_addr.sin_addr.s_addr),
2711                        ntohs(cm_id->local_addr.sin_port),
2712                        le32_to_cpu(nesqp->nesqp_context->rcv_nxt),
2713                        le32_to_cpu(nesqp->nesqp_context->snd_nxt),
2714                        conn_param->private_data_len +
2715                        sizeof(struct ietf_mpa_frame));
2716
2717        attr.qp_state = IB_QPS_RTS;
2718        nes_modify_qp(&nesqp->ibqp, &attr, IB_QP_STATE, NULL);
2719
2720        /* notify OF layer that accept event was successfull */
2721        cm_id->add_ref(cm_id);
2722
2723        cm_event.event = IW_CM_EVENT_ESTABLISHED;
2724        cm_event.status = IW_CM_EVENT_STATUS_ACCEPTED;
2725        cm_event.provider_data = (void *)nesqp;
2726        cm_event.local_addr = cm_id->local_addr;
2727        cm_event.remote_addr = cm_id->remote_addr;
2728        cm_event.private_data = NULL;
2729        cm_event.private_data_len = 0;
2730        ret = cm_id->event_handler(cm_id, &cm_event);
2731        if (cm_node->loopbackpartner) {
2732                cm_node->loopbackpartner->mpa_frame_size =
2733                        nesqp->private_data_len;
2734                /* copy entire MPA frame to our cm_node's frame */
2735                memcpy(cm_node->loopbackpartner->mpa_frame_buf,
2736                        nesqp->ietf_frame->priv_data, nesqp->private_data_len);
2737                create_event(cm_node->loopbackpartner, NES_CM_EVENT_CONNECTED);
2738        }
2739        if (ret)
2740                printk(KERN_ERR "%s[%u] OFA CM event_handler returned, "
2741                        "ret=%d\n", __func__, __LINE__, ret);
2742
2743        return 0;
2744}
2745
2746
2747/**
2748 * nes_reject
2749 */
2750int nes_reject(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len)
2751{
2752        struct nes_cm_node *cm_node;
2753        struct nes_cm_core *cm_core;
2754
2755        atomic_inc(&cm_rejects);
2756        cm_node = (struct nes_cm_node *) cm_id->provider_data;
2757        cm_core = cm_node->cm_core;
2758        cm_node->mpa_frame_size = sizeof(struct ietf_mpa_frame) + pdata_len;
2759
2760        strcpy(&cm_node->mpa_frame.key[0], IEFT_MPA_KEY_REP);
2761        memcpy(&cm_node->mpa_frame.priv_data, pdata, pdata_len);
2762
2763        cm_node->mpa_frame.priv_data_len = cpu_to_be16(pdata_len);
2764        cm_node->mpa_frame.rev = mpa_version;
2765        cm_node->mpa_frame.flags = IETF_MPA_FLAGS_CRC | IETF_MPA_FLAGS_REJECT;
2766
2767        cm_core->api->reject(cm_core, &cm_node->mpa_frame, cm_node);
2768
2769        return 0;
2770}
2771
2772
2773/**
2774 * nes_connect
2775 * setup and launch cm connect node
2776 */
2777int nes_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
2778{
2779        struct ib_qp *ibqp;
2780        struct nes_qp *nesqp;
2781        struct nes_vnic *nesvnic;
2782        struct nes_device *nesdev;
2783        struct nes_cm_node *cm_node;
2784        struct nes_cm_info cm_info;
2785
2786        ibqp = nes_get_qp(cm_id->device, conn_param->qpn);
2787        if (!ibqp)
2788                return -EINVAL;
2789        nesqp = to_nesqp(ibqp);
2790        if (!nesqp)
2791                return -EINVAL;
2792        nesvnic = to_nesvnic(nesqp->ibqp.device);
2793        if (!nesvnic)
2794                return -EINVAL;
2795        nesdev  = nesvnic->nesdev;
2796        if (!nesdev)
2797                return -EINVAL;
2798
2799        nes_debug(NES_DBG_CM, "QP%u, current IP = 0x%08X, Destination IP = "
2800                "0x%08X:0x%04X, local = 0x%08X:0x%04X.\n", nesqp->hwqp.qp_id,
2801                ntohl(nesvnic->local_ipaddr),
2802                ntohl(cm_id->remote_addr.sin_addr.s_addr),
2803                ntohs(cm_id->remote_addr.sin_port),
2804                ntohl(cm_id->local_addr.sin_addr.s_addr),
2805                ntohs(cm_id->local_addr.sin_port));
2806
2807        atomic_inc(&cm_connects);
2808        nesqp->active_conn = 1;
2809
2810        /* cache the cm_id in the qp */
2811        nesqp->cm_id = cm_id;
2812
2813        cm_id->provider_data = nesqp;
2814
2815        nesqp->private_data_len = conn_param->private_data_len;
2816        nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32((u32)conn_param->ord);
2817        nes_debug(NES_DBG_CM, "requested ord = 0x%08X.\n", (u32)conn_param->ord);
2818        nes_debug(NES_DBG_CM, "mpa private data len =%u\n",
2819                conn_param->private_data_len);
2820
2821        if (cm_id->local_addr.sin_addr.s_addr !=
2822                cm_id->remote_addr.sin_addr.s_addr)
2823                nes_manage_apbvt(nesvnic, ntohs(cm_id->local_addr.sin_port),
2824                        PCI_FUNC(nesdev->pcidev->devfn), NES_MANAGE_APBVT_ADD);
2825
2826        /* set up the connection params for the node */
2827        cm_info.loc_addr = htonl(cm_id->local_addr.sin_addr.s_addr);
2828        cm_info.loc_port = htons(cm_id->local_addr.sin_port);
2829        cm_info.rem_addr = htonl(cm_id->remote_addr.sin_addr.s_addr);
2830        cm_info.rem_port = htons(cm_id->remote_addr.sin_port);
2831        cm_info.cm_id = cm_id;
2832        cm_info.conn_type = NES_CM_IWARP_CONN_TYPE;
2833
2834        cm_id->add_ref(cm_id);
2835
2836        /* create a connect CM node connection */
2837        cm_node = g_cm_core->api->connect(g_cm_core, nesvnic,
2838                conn_param->private_data_len, (void *)conn_param->private_data,
2839                &cm_info);
2840        if (!cm_node) {
2841                if (cm_id->local_addr.sin_addr.s_addr !=
2842                                cm_id->remote_addr.sin_addr.s_addr)
2843                        nes_manage_apbvt(nesvnic, ntohs(cm_id->local_addr.sin_port),
2844                                PCI_FUNC(nesdev->pcidev->devfn),
2845                                NES_MANAGE_APBVT_DEL);
2846
2847                cm_id->rem_ref(cm_id);
2848                return -ENOMEM;
2849        }
2850
2851        cm_node->apbvt_set = 1;
2852        nesqp->cm_node = cm_node;
2853        cm_node->nesqp = nesqp;
2854        nes_add_ref(&nesqp->ibqp);
2855
2856        return 0;
2857}
2858
2859
2860/**
2861 * nes_create_listen
2862 */
2863int nes_create_listen(struct iw_cm_id *cm_id, int backlog)
2864{
2865        struct nes_vnic *nesvnic;
2866        struct nes_cm_listener *cm_node;
2867        struct nes_cm_info cm_info;
2868        struct nes_adapter *adapter;
2869        int err;
2870
2871
2872        nes_debug(NES_DBG_CM, "cm_id = %p, local port = 0x%04X.\n",
2873                        cm_id, ntohs(cm_id->local_addr.sin_port));
2874
2875        nesvnic = to_nesvnic(cm_id->device);
2876        if (!nesvnic)
2877                return -EINVAL;
2878        adapter = nesvnic->nesdev->nesadapter;
2879        nes_debug(NES_DBG_CM, "nesvnic=%p, netdev=%p, %s\n",
2880                        nesvnic, nesvnic->netdev, nesvnic->netdev->name);
2881
2882        nes_debug(NES_DBG_CM, "nesvnic->local_ipaddr=0x%08x, sin_addr.s_addr=0x%08x\n",
2883                        nesvnic->local_ipaddr, cm_id->local_addr.sin_addr.s_addr);
2884
2885        /* setup listen params in our api call struct */
2886        cm_info.loc_addr = nesvnic->local_ipaddr;
2887        cm_info.loc_port = cm_id->local_addr.sin_port;
2888        cm_info.backlog = backlog;
2889        cm_info.cm_id = cm_id;
2890
2891        cm_info.conn_type = NES_CM_IWARP_CONN_TYPE;
2892
2893
2894        cm_node = g_cm_core->api->listen(g_cm_core, nesvnic, &cm_info);
2895        if (!cm_node) {
2896                printk(KERN_ERR "%s[%u] Error returned from listen API call\n",
2897                                __func__, __LINE__);
2898                return -ENOMEM;
2899        }
2900
2901        cm_id->provider_data = cm_node;
2902
2903        if (!cm_node->reused_node) {
2904                err = nes_manage_apbvt(nesvnic,
2905                        ntohs(cm_id->local_addr.sin_port),
2906                        PCI_FUNC(nesvnic->nesdev->pcidev->devfn),
2907                        NES_MANAGE_APBVT_ADD);
2908                if (err) {
2909                        printk(KERN_ERR "nes_manage_apbvt call returned %d.\n",
2910                                err);
2911                        g_cm_core->api->stop_listener(g_cm_core, (void *)cm_node);
2912                        return err;
2913                }
2914                cm_listens_created++;
2915        }
2916
2917        cm_id->add_ref(cm_id);
2918        cm_id->provider_data = (void *)cm_node;
2919
2920
2921        return 0;
2922}
2923
2924
2925/**
2926 * nes_destroy_listen
2927 */
2928int nes_destroy_listen(struct iw_cm_id *cm_id)
2929{
2930        if (cm_id->provider_data)
2931                g_cm_core->api->stop_listener(g_cm_core, cm_id->provider_data);
2932        else
2933                nes_debug(NES_DBG_CM, "cm_id->provider_data was NULL\n");
2934
2935        cm_id->rem_ref(cm_id);
2936
2937        return 0;
2938}
2939
2940
2941/**
2942 * nes_cm_recv
2943 */
2944int nes_cm_recv(struct sk_buff *skb, struct net_device *netdevice)
2945{
2946        cm_packets_received++;
2947        if ((g_cm_core) && (g_cm_core->api)) {
2948                g_cm_core->api->recv_pkt(g_cm_core, netdev_priv(netdevice), skb);
2949        } else {
2950                nes_debug(NES_DBG_CM, "Unable to process packet for CM,"
2951                                " cm is not setup properly.\n");
2952        }
2953
2954        return 0;
2955}
2956
2957
2958/**
2959 * nes_cm_start
2960 * Start and init a cm core module
2961 */
2962int nes_cm_start(void)
2963{
2964        nes_debug(NES_DBG_CM, "\n");
2965        /* create the primary CM core, pass this handle to subsequent core inits */
2966        g_cm_core = nes_cm_alloc_core();
2967        if (g_cm_core) {
2968                return 0;
2969        } else {
2970                return -ENOMEM;
2971        }
2972}
2973
2974
2975/**
2976 * nes_cm_stop
2977 * stop and dealloc all cm core instances
2978 */
2979int nes_cm_stop(void)
2980{
2981        g_cm_core->api->destroy_cm_core(g_cm_core);
2982        return 0;
2983}
2984
2985
2986/**
2987 * cm_event_connected
2988 * handle a connected event, setup QPs and HW
2989 */
2990static void cm_event_connected(struct nes_cm_event *event)
2991{
2992        u64 u64temp;
2993        struct nes_qp *nesqp;
2994        struct nes_vnic *nesvnic;
2995        struct nes_device *nesdev;
2996        struct nes_cm_node *cm_node;
2997        struct nes_adapter *nesadapter;
2998        struct ib_qp_attr attr;
2999        struct iw_cm_id *cm_id;
3000        struct iw_cm_event cm_event;
3001        struct nes_hw_qp_wqe *wqe;
3002        struct nes_v4_quad nes_quad;
3003        u32 crc_value;
3004        int ret;
3005
3006        /* get all our handles */
3007        cm_node = event->cm_node;
3008        cm_id = cm_node->cm_id;
3009        nes_debug(NES_DBG_CM, "cm_event_connected - %p - cm_id = %p\n", cm_node, cm_id);
3010        nesqp = (struct nes_qp *)cm_id->provider_data;
3011        nesvnic = to_nesvnic(nesqp->ibqp.device);
3012        nesdev = nesvnic->nesdev;
3013        nesadapter = nesdev->nesadapter;
3014
3015        if (nesqp->destroyed) {
3016                return;
3017        }
3018        atomic_inc(&cm_connecteds);
3019        nes_debug(NES_DBG_CM, "QP%u attempting to connect to  0x%08X:0x%04X on"
3020                        " local port 0x%04X. jiffies = %lu.\n",
3021                        nesqp->hwqp.qp_id,
3022                        ntohl(cm_id->remote_addr.sin_addr.s_addr),
3023                        ntohs(cm_id->remote_addr.sin_port),
3024                        ntohs(cm_id->local_addr.sin_port),
3025                        jiffies);
3026
3027        nes_cm_init_tsa_conn(nesqp, cm_node);
3028
3029        /* set the QP tsa context */
3030        nesqp->nesqp_context->tcpPorts[0] =
3031                cpu_to_le16(ntohs(cm_id->local_addr.sin_port));
3032        nesqp->nesqp_context->tcpPorts[1] =
3033                cpu_to_le16(ntohs(cm_id->remote_addr.sin_port));
3034        if (ipv4_is_loopback(cm_id->remote_addr.sin_addr.s_addr))
3035                nesqp->nesqp_context->ip0 =
3036                        cpu_to_le32(ntohl(nesvnic->local_ipaddr));
3037        else
3038                nesqp->nesqp_context->ip0 =
3039                        cpu_to_le32(ntohl(cm_id->remote_addr.sin_addr.s_addr));
3040
3041        nesqp->nesqp_context->misc2 |= cpu_to_le32(
3042                        (u32)PCI_FUNC(nesdev->pcidev->devfn) <<
3043                        NES_QPCONTEXT_MISC2_SRC_IP_SHIFT);
3044        nesqp->nesqp_context->arp_index_vlan |= cpu_to_le32(
3045                        nes_arp_table(nesdev,
3046                        le32_to_cpu(nesqp->nesqp_context->ip0),
3047                        NULL, NES_ARP_RESOLVE) << 16);
3048        nesqp->nesqp_context->ts_val_delta = cpu_to_le32(
3049                        jiffies - nes_read_indexed(nesdev, NES_IDX_TCP_NOW));
3050        nesqp->nesqp_context->ird_index = cpu_to_le32(nesqp->hwqp.qp_id);
3051        nesqp->nesqp_context->ird_ord_sizes |=
3052                        cpu_to_le32((u32)1 <<
3053                        NES_QPCONTEXT_ORDIRD_IWARP_MODE_SHIFT);
3054
3055        /* Adjust tail for not having a LSMM */
3056        nesqp->hwqp.sq_tail = 1;
3057
3058#if defined(NES_SEND_FIRST_WRITE)
3059        if (cm_node->send_write0) {
3060                nes_debug(NES_DBG_CM, "Sending first write.\n");
3061                wqe = &nesqp->hwqp.sq_vbase[0];
3062                u64temp = (unsigned long)nesqp;
3063                u64temp |= NES_SW_CONTEXT_ALIGN>>1;
3064                set_wqe_64bit_value(wqe->wqe_words,
3065                                NES_IWARP_SQ_WQE_COMP_CTX_LOW_IDX, u64temp);
3066                wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] =
3067                        cpu_to_le32(NES_IWARP_SQ_OP_RDMAW);
3068                wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX] = 0;
3069                wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_LOW_IDX] = 0;
3070                wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_HIGH_IDX] = 0;
3071                wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] = 0;
3072                wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = 0;
3073
3074                /* use the reserved spot on the WQ for the extra first WQE */
3075                nesqp->nesqp_context->ird_ord_sizes &=
3076                        cpu_to_le32(~(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT |
3077                                                NES_QPCONTEXT_ORDIRD_WRPDU |
3078                                                NES_QPCONTEXT_ORDIRD_ALSMM));
3079                nesqp->skip_lsmm = 1;
3080                nesqp->hwqp.sq_tail = 0;
3081                nes_write32(nesdev->regs + NES_WQE_ALLOC,
3082                                (1 << 24) | 0x00800000 | nesqp->hwqp.qp_id);
3083        }
3084#endif
3085
3086        memset(&nes_quad, 0, sizeof(nes_quad));
3087
3088        nes_quad.DstIpAdrIndex =
3089                cpu_to_le32((u32)PCI_FUNC(nesdev->pcidev->devfn) << 24);
3090        if (ipv4_is_loopback(cm_id->remote_addr.sin_addr.s_addr))
3091                nes_quad.SrcIpadr = nesvnic->local_ipaddr;
3092        else
3093                nes_quad.SrcIpadr = cm_id->remote_addr.sin_addr.s_addr;
3094        nes_quad.TcpPorts[0] = cm_id->remote_addr.sin_port;
3095        nes_quad.TcpPorts[1] = cm_id->local_addr.sin_port;
3096
3097        /* Produce hash key */
3098        crc_value = get_crc_value(&nes_quad);
3099        nesqp->hte_index = cpu_to_be32(crc_value ^ 0xffffffff);
3100        nes_debug(NES_DBG_CM, "HTE Index = 0x%08X, After CRC = 0x%08X\n",
3101                        nesqp->hte_index, nesqp->hte_index & nesadapter->hte_index_mask);
3102
3103        nesqp->hte_index &= nesadapter->hte_index_mask;
3104        nesqp->nesqp_context->hte_index = cpu_to_le32(nesqp->hte_index);
3105
3106        nesqp->ietf_frame = &cm_node->mpa_frame;
3107        nesqp->private_data_len = (u8) cm_node->mpa_frame_size;
3108        cm_node->cm_core->api->accelerated(cm_node->cm_core, cm_node);
3109
3110        /* notify OF layer we successfully created the requested connection */
3111        cm_event.event = IW_CM_EVENT_CONNECT_REPLY;
3112        cm_event.status = IW_CM_EVENT_STATUS_ACCEPTED;
3113        cm_event.provider_data = cm_id->provider_data;
3114        cm_event.local_addr.sin_family = AF_INET;
3115        cm_event.local_addr.sin_port = cm_id->local_addr.sin_port;
3116        cm_event.remote_addr = cm_id->remote_addr;
3117
3118        cm_event.private_data = (void *)event->cm_node->mpa_frame_buf;
3119        cm_event.private_data_len = (u8) event->cm_node->mpa_frame_size;
3120
3121        cm_event.local_addr.sin_addr.s_addr = event->cm_info.rem_addr;
3122        ret = cm_id->event_handler(cm_id, &cm_event);
3123        nes_debug(NES_DBG_CM, "OFA CM event_handler returned, ret=%d\n", ret);
3124
3125        if (ret)
3126                printk(KERN_ERR "%s[%u] OFA CM event_handler returned, "
3127                        "ret=%d\n", __func__, __LINE__, ret);
3128        attr.qp_state = IB_QPS_RTS;
3129        nes_modify_qp(&nesqp->ibqp, &attr, IB_QP_STATE, NULL);
3130
3131        nes_debug(NES_DBG_CM, "Exiting connect thread for QP%u. jiffies = "
3132                "%lu\n", nesqp->hwqp.qp_id, jiffies);
3133
3134        return;
3135}
3136
3137
3138/**
3139 * cm_event_connect_error
3140 */
3141static void cm_event_connect_error(struct nes_cm_event *event)
3142{
3143        struct nes_qp *nesqp;
3144        struct iw_cm_id *cm_id;
3145        struct iw_cm_event cm_event;
3146        /* struct nes_cm_info cm_info; */
3147        int ret;
3148
3149        if (!event->cm_node)
3150                return;
3151
3152        cm_id = event->cm_node->cm_id;
3153        if (!cm_id) {
3154                return;
3155        }
3156
3157        nes_debug(NES_DBG_CM, "cm_node=%p, cm_id=%p\n", event->cm_node, cm_id);
3158        nesqp = cm_id->provider_data;
3159
3160        if (!nesqp) {
3161                return;
3162        }
3163
3164        /* notify OF layer about this connection error event */
3165        /* cm_id->rem_ref(cm_id); */
3166        nesqp->cm_id = NULL;
3167        cm_id->provider_data = NULL;
3168        cm_event.event = IW_CM_EVENT_CONNECT_REPLY;
3169        cm_event.status = IW_CM_EVENT_STATUS_REJECTED;
3170        cm_event.provider_data = cm_id->provider_data;
3171        cm_event.local_addr = cm_id->local_addr;
3172        cm_event.remote_addr = cm_id->remote_addr;
3173        cm_event.private_data = NULL;
3174        cm_event.private_data_len = 0;
3175
3176        nes_debug(NES_DBG_CM, "call CM_EVENT REJECTED, local_addr=%08x, "
3177                "remove_addr=%08x\n", cm_event.local_addr.sin_addr.s_addr,
3178                cm_event.remote_addr.sin_addr.s_addr);
3179
3180        ret = cm_id->event_handler(cm_id, &cm_event);
3181        nes_debug(NES_DBG_CM, "OFA CM event_handler returned, ret=%d\n", ret);
3182        if (ret)
3183                printk(KERN_ERR "%s[%u] OFA CM event_handler returned, "
3184                        "ret=%d\n", __func__, __LINE__, ret);
3185        cm_id->rem_ref(cm_id);
3186
3187        rem_ref_cm_node(event->cm_node->cm_core, event->cm_node);
3188        return;
3189}
3190
3191
3192/**
3193 * cm_event_reset
3194 */
3195static void cm_event_reset(struct nes_cm_event *event)
3196{
3197        struct nes_qp *nesqp;
3198        struct iw_cm_id *cm_id;
3199        struct iw_cm_event cm_event;
3200        /* struct nes_cm_info cm_info; */
3201        int ret;
3202
3203        if (!event->cm_node)
3204                return;
3205
3206        if (!event->cm_node->cm_id)
3207                return;
3208
3209        cm_id = event->cm_node->cm_id;
3210
3211        nes_debug(NES_DBG_CM, "%p - cm_id = %p\n", event->cm_node, cm_id);
3212        nesqp = cm_id->provider_data;
3213
3214        nesqp->cm_id = NULL;
3215        /* cm_id->provider_data = NULL; */
3216        cm_event.event = IW_CM_EVENT_DISCONNECT;
3217        cm_event.status = IW_CM_EVENT_STATUS_RESET;
3218        cm_event.provider_data = cm_id->provider_data;
3219        cm_event.local_addr = cm_id->local_addr;
3220        cm_event.remote_addr = cm_id->remote_addr;
3221        cm_event.private_data = NULL;
3222        cm_event.private_data_len = 0;
3223
3224        ret = cm_id->event_handler(cm_id, &cm_event);
3225        nes_debug(NES_DBG_CM, "OFA CM event_handler returned, ret=%d\n", ret);
3226
3227
3228        /* notify OF layer about this connection error event */
3229        cm_id->rem_ref(cm_id);
3230
3231        return;
3232}
3233
3234
3235/**
3236 * cm_event_mpa_req
3237 */
3238static void cm_event_mpa_req(struct nes_cm_event *event)
3239{
3240        struct iw_cm_id   *cm_id;
3241        struct iw_cm_event cm_event;
3242        int ret;
3243        struct nes_cm_node *cm_node;
3244
3245        cm_node = event->cm_node;
3246        if (!cm_node)
3247                return;
3248        cm_id = cm_node->cm_id;
3249
3250        atomic_inc(&cm_connect_reqs);
3251        nes_debug(NES_DBG_CM, "cm_node = %p - cm_id = %p, jiffies = %lu\n",
3252                        cm_node, cm_id, jiffies);
3253
3254        cm_event.event = IW_CM_EVENT_CONNECT_REQUEST;
3255        cm_event.status = IW_CM_EVENT_STATUS_OK;
3256        cm_event.provider_data = (void *)cm_node;
3257
3258        cm_event.local_addr.sin_family = AF_INET;
3259        cm_event.local_addr.sin_port = htons(event->cm_info.loc_port);
3260        cm_event.local_addr.sin_addr.s_addr = htonl(event->cm_info.loc_addr);
3261
3262        cm_event.remote_addr.sin_family = AF_INET;
3263        cm_event.remote_addr.sin_port = htons(event->cm_info.rem_port);
3264        cm_event.remote_addr.sin_addr.s_addr = htonl(event->cm_info.rem_addr);
3265
3266                cm_event.private_data                = cm_node->mpa_frame_buf;
3267                cm_event.private_data_len            = (u8) cm_node->mpa_frame_size;
3268
3269        ret = cm_id->event_handler(cm_id, &cm_event);
3270        if (ret)
3271                printk("%s[%u] OFA CM event_handler returned, ret=%d\n",
3272                                __func__, __LINE__, ret);
3273
3274        return;
3275}
3276
3277
3278static void nes_cm_event_handler(struct work_struct *);
3279
3280/**
3281 * nes_cm_post_event
3282 * post an event to the cm event handler
3283 */
3284static int nes_cm_post_event(struct nes_cm_event *event)
3285{
3286        atomic_inc(&event->cm_node->cm_core->events_posted);
3287        add_ref_cm_node(event->cm_node);
3288        event->cm_info.cm_id->add_ref(event->cm_info.cm_id);
3289        INIT_WORK(&event->event_work, nes_cm_event_handler);
3290        nes_debug(NES_DBG_CM, "cm_node=%p queue_work, event=%p\n",
3291                event->cm_node, event);
3292
3293        queue_work(event->cm_node->cm_core->event_wq, &event->event_work);
3294
3295        nes_debug(NES_DBG_CM, "Exit\n");
3296        return 0;
3297}
3298
3299
3300/**
3301 * nes_cm_event_handler
3302 * worker function to handle cm events
3303 * will free instance of nes_cm_event
3304 */
3305static void nes_cm_event_handler(struct work_struct *work)
3306{
3307        struct nes_cm_event *event = container_of(work, struct nes_cm_event,
3308                        event_work);
3309        struct nes_cm_core *cm_core;
3310
3311        if ((!event) || (!event->cm_node) || (!event->cm_node->cm_core))
3312                return;
3313
3314        cm_core = event->cm_node->cm_core;
3315        nes_debug(NES_DBG_CM, "event=%p, event->type=%u, events posted=%u\n",
3316                event, event->type, atomic_read(&cm_core->events_posted));
3317
3318        switch (event->type) {
3319        case NES_CM_EVENT_MPA_REQ:
3320                cm_event_mpa_req(event);
3321                nes_debug(NES_DBG_CM, "cm_node=%p CM Event: MPA REQUEST\n",
3322                        event->cm_node);
3323                break;
3324        case NES_CM_EVENT_RESET:
3325                nes_debug(NES_DBG_CM, "cm_node = %p CM Event: RESET\n",
3326                        event->cm_node);
3327                cm_event_reset(event);
3328                break;
3329        case NES_CM_EVENT_CONNECTED:
3330                if ((!event->cm_node->cm_id) ||
3331                        (event->cm_node->state != NES_CM_STATE_TSA))
3332                        break;
3333                cm_event_connected(event);
3334                nes_debug(NES_DBG_CM, "CM Event: CONNECTED\n");
3335                break;
3336        case NES_CM_EVENT_ABORTED:
3337                if ((!event->cm_node->cm_id) ||
3338                        (event->cm_node->state == NES_CM_STATE_TSA))
3339                        break;
3340                cm_event_connect_error(event);
3341                nes_debug(NES_DBG_CM, "CM Event: ABORTED\n");
3342                break;
3343        case NES_CM_EVENT_DROPPED_PKT:
3344                nes_debug(NES_DBG_CM, "CM Event: DROPPED PKT\n");
3345                break;
3346        default:
3347                nes_debug(NES_DBG_CM, "CM Event: UNKNOWN EVENT TYPE\n");
3348                break;
3349        }
3350
3351        atomic_dec(&cm_core->events_posted);
3352        event->cm_info.cm_id->rem_ref(event->cm_info.cm_id);
3353        rem_ref_cm_node(cm_core, event->cm_node);
3354        kfree(event);
3355
3356        return;
3357}