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