RDMA/nes: Add a driver for NetEffect RNICs

Add a standard NIC and RDMA/iWARP driver for NetEffect 1/10Gb ethernet adapters.

Signed-off-by: Glenn Streiff <gstreiff@neteffect.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>

authored by Glenn Streiff and committed by Roland Dreier 3c2d774c 2c788534

+16561 -1
+10
MAINTAINERS
··· 2681 L: linux-scsi@vger.kernel.org 2682 S: Maintained 2683 2684 NETEM NETWORK EMULATOR 2685 P: Stephen Hemminger 2686 M: shemminger@linux-foundation.org
··· 2681 L: linux-scsi@vger.kernel.org 2682 S: Maintained 2683 2684 + NETEFFECT IWARP RNIC DRIVER (IW_NES) 2685 + P: Faisal Latif 2686 + M: flatif@neteffect.com 2687 + P: Glenn Streiff 2688 + M: gstreiff@neteffect.com 2689 + L: general@lists.openfabrics.org 2690 + W: http://www.neteffect.com 2691 + S: Supported 2692 + F: drivers/infiniband/hw/nes/ 2693 + 2694 NETEM NETWORK EMULATOR 2695 P: Stephen Hemminger 2696 M: shemminger@linux-foundation.org
+1 -1
drivers/infiniband/Kconfig
··· 44 source "drivers/infiniband/hw/ehca/Kconfig" 45 source "drivers/infiniband/hw/amso1100/Kconfig" 46 source "drivers/infiniband/hw/cxgb3/Kconfig" 47 - 48 source "drivers/infiniband/hw/mlx4/Kconfig" 49 50 source "drivers/infiniband/ulp/ipoib/Kconfig" 51
··· 44 source "drivers/infiniband/hw/ehca/Kconfig" 45 source "drivers/infiniband/hw/amso1100/Kconfig" 46 source "drivers/infiniband/hw/cxgb3/Kconfig" 47 source "drivers/infiniband/hw/mlx4/Kconfig" 48 + source "drivers/infiniband/hw/nes/Kconfig" 49 50 source "drivers/infiniband/ulp/ipoib/Kconfig" 51
+1
drivers/infiniband/Makefile
··· 5 obj-$(CONFIG_INFINIBAND_AMSO1100) += hw/amso1100/ 6 obj-$(CONFIG_INFINIBAND_CXGB3) += hw/cxgb3/ 7 obj-$(CONFIG_MLX4_INFINIBAND) += hw/mlx4/ 8 obj-$(CONFIG_INFINIBAND_IPOIB) += ulp/ipoib/ 9 obj-$(CONFIG_INFINIBAND_SRP) += ulp/srp/ 10 obj-$(CONFIG_INFINIBAND_ISER) += ulp/iser/
··· 5 obj-$(CONFIG_INFINIBAND_AMSO1100) += hw/amso1100/ 6 obj-$(CONFIG_INFINIBAND_CXGB3) += hw/cxgb3/ 7 obj-$(CONFIG_MLX4_INFINIBAND) += hw/mlx4/ 8 + obj-$(CONFIG_INFINIBAND_NES) += hw/nes/ 9 obj-$(CONFIG_INFINIBAND_IPOIB) += ulp/ipoib/ 10 obj-$(CONFIG_INFINIBAND_SRP) += ulp/srp/ 11 obj-$(CONFIG_INFINIBAND_ISER) += ulp/iser/
+16
drivers/infiniband/hw/nes/Kconfig
···
··· 1 + config INFINIBAND_NES 2 + tristate "NetEffect RNIC Driver" 3 + depends on PCI && INET && INFINIBAND 4 + select LIBCRC32C 5 + ---help--- 6 + This is a low-level driver for NetEffect RDMA enabled 7 + Network Interface Cards (RNIC). 8 + 9 + config INFINIBAND_NES_DEBUG 10 + bool "Verbose debugging output" 11 + depends on INFINIBAND_NES 12 + default n 13 + ---help--- 14 + This option causes the NetEffect RNIC driver to produce debug 15 + messages. Select this if you are developing the driver 16 + or trying to diagnose a problem.
+3
drivers/infiniband/hw/nes/Makefile
···
··· 1 + obj-$(CONFIG_INFINIBAND_NES) += iw_nes.o 2 + 3 + iw_nes-objs := nes.o nes_hw.o nes_nic.o nes_utils.o nes_verbs.o nes_cm.o
+1152
drivers/infiniband/hw/nes/nes.c
···
··· 1 + /* 2 + * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved. 3 + * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. 4 + * 5 + * This software is available to you under a choice of one of two 6 + * licenses. You may choose to be licensed under the terms of the GNU 7 + * General Public License (GPL) Version 2, available from the file 8 + * COPYING in the main directory of this source tree, or the 9 + * OpenIB.org BSD license below: 10 + * 11 + * Redistribution and use in source and binary forms, with or 12 + * without modification, are permitted provided that the following 13 + * conditions are met: 14 + * 15 + * - Redistributions of source code must retain the above 16 + * copyright notice, this list of conditions and the following 17 + * disclaimer. 18 + * 19 + * - Redistributions in binary form must reproduce the above 20 + * copyright notice, this list of conditions and the following 21 + * disclaimer in the documentation and/or other materials 22 + * provided with the distribution. 23 + * 24 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 28 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 29 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 30 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 + * SOFTWARE. 32 + */ 33 + 34 + #include <linux/module.h> 35 + #include <linux/moduleparam.h> 36 + #include <linux/netdevice.h> 37 + #include <linux/etherdevice.h> 38 + #include <linux/ethtool.h> 39 + #include <linux/mii.h> 40 + #include <linux/if_vlan.h> 41 + #include <linux/crc32.h> 42 + #include <linux/in.h> 43 + #include <linux/fs.h> 44 + #include <linux/init.h> 45 + #include <linux/if_arp.h> 46 + #include <linux/highmem.h> 47 + #include <asm/io.h> 48 + #include <asm/irq.h> 49 + #include <asm/byteorder.h> 50 + #include <rdma/ib_smi.h> 51 + #include <rdma/ib_verbs.h> 52 + #include <rdma/ib_pack.h> 53 + #include <rdma/iw_cm.h> 54 + 55 + #include "nes.h" 56 + 57 + #include <net/netevent.h> 58 + #include <net/neighbour.h> 59 + #include <linux/route.h> 60 + #include <net/ip_fib.h> 61 + 62 + MODULE_AUTHOR("NetEffect"); 63 + MODULE_DESCRIPTION("NetEffect RNIC Low-level iWARP Driver"); 64 + MODULE_LICENSE("Dual BSD/GPL"); 65 + MODULE_VERSION(DRV_VERSION); 66 + 67 + int max_mtu = 9000; 68 + int nics_per_function = 1; 69 + int interrupt_mod_interval = 0; 70 + 71 + 72 + /* Interoperability */ 73 + int mpa_version = 1; 74 + module_param(mpa_version, int, 0); 75 + MODULE_PARM_DESC(mpa_version, "MPA version to be used int MPA Req/Resp (0 or 1)"); 76 + 77 + /* Interoperability */ 78 + int disable_mpa_crc = 0; 79 + module_param(disable_mpa_crc, int, 0); 80 + MODULE_PARM_DESC(disable_mpa_crc, "Disable checking of MPA CRC"); 81 + 82 + unsigned int send_first = 0; 83 + module_param(send_first, int, 0); 84 + MODULE_PARM_DESC(send_first, "Send RDMA Message First on Active Connection"); 85 + 86 + 87 + unsigned int nes_drv_opt = 0; 88 + module_param(nes_drv_opt, int, 0); 89 + MODULE_PARM_DESC(nes_drv_opt, "Driver option parameters"); 90 + 91 + unsigned int nes_debug_level = 0; 92 + module_param_named(debug_level, nes_debug_level, uint, 0644); 93 + MODULE_PARM_DESC(debug_level, "Enable debug output level"); 94 + 95 + LIST_HEAD(nes_adapter_list); 96 + LIST_HEAD(nes_dev_list); 97 + 98 + atomic_t qps_destroyed; 99 + atomic_t cqp_reqs_allocated; 100 + atomic_t cqp_reqs_freed; 101 + atomic_t cqp_reqs_dynallocated; 102 + atomic_t cqp_reqs_dynfreed; 103 + atomic_t cqp_reqs_queued; 104 + atomic_t cqp_reqs_redriven; 105 + 106 + static void nes_print_macaddr(struct net_device *netdev); 107 + static irqreturn_t nes_interrupt(int, void *); 108 + static int __devinit nes_probe(struct pci_dev *, const struct pci_device_id *); 109 + static void __devexit nes_remove(struct pci_dev *); 110 + static int __init nes_init_module(void); 111 + static void __exit nes_exit_module(void); 112 + static unsigned int ee_flsh_adapter; 113 + static unsigned int sysfs_nonidx_addr; 114 + static unsigned int sysfs_idx_addr; 115 + 116 + static struct pci_device_id nes_pci_table[] = { 117 + {PCI_VENDOR_ID_NETEFFECT, PCI_DEVICE_ID_NETEFFECT_NE020, PCI_ANY_ID, PCI_ANY_ID}, 118 + {0} 119 + }; 120 + 121 + MODULE_DEVICE_TABLE(pci, nes_pci_table); 122 + 123 + static int nes_inetaddr_event(struct notifier_block *, unsigned long, void *); 124 + static int nes_net_event(struct notifier_block *, unsigned long, void *); 125 + static int nes_notifiers_registered; 126 + 127 + 128 + static struct notifier_block nes_inetaddr_notifier = { 129 + .notifier_call = nes_inetaddr_event 130 + }; 131 + 132 + static struct notifier_block nes_net_notifier = { 133 + .notifier_call = nes_net_event 134 + }; 135 + 136 + 137 + 138 + 139 + /** 140 + * nes_inetaddr_event 141 + */ 142 + static int nes_inetaddr_event(struct notifier_block *notifier, 143 + unsigned long event, void *ptr) 144 + { 145 + struct in_ifaddr *ifa = ptr; 146 + struct net_device *event_netdev = ifa->ifa_dev->dev; 147 + struct nes_device *nesdev; 148 + struct net_device *netdev; 149 + struct nes_vnic *nesvnic; 150 + unsigned int addr; 151 + unsigned int mask; 152 + 153 + addr = ntohl(ifa->ifa_address); 154 + mask = ntohl(ifa->ifa_mask); 155 + nes_debug(NES_DBG_NETDEV, "nes_inetaddr_event: ip address %08X, netmask %08X.\n", 156 + addr, mask); 157 + list_for_each_entry(nesdev, &nes_dev_list, list) { 158 + nes_debug(NES_DBG_NETDEV, "Nesdev list entry = 0x%p. (%s)\n", 159 + nesdev, nesdev->netdev[0]->name); 160 + netdev = nesdev->netdev[0]; 161 + nesvnic = netdev_priv(netdev); 162 + if (netdev == event_netdev) { 163 + if (nesvnic->rdma_enabled == 0) { 164 + nes_debug(NES_DBG_NETDEV, "Returning without processing event for %s since" 165 + " RDMA is not enabled.\n", 166 + netdev->name); 167 + return NOTIFY_OK; 168 + } 169 + /* we have ifa->ifa_address/mask here if we need it */ 170 + switch (event) { 171 + case NETDEV_DOWN: 172 + nes_debug(NES_DBG_NETDEV, "event:DOWN\n"); 173 + nes_write_indexed(nesdev, 174 + NES_IDX_DST_IP_ADDR+(0x10*PCI_FUNC(nesdev->pcidev->devfn)), 0); 175 + 176 + nes_manage_arp_cache(netdev, netdev->dev_addr, 177 + ntohl(nesvnic->local_ipaddr), NES_ARP_DELETE); 178 + nesvnic->local_ipaddr = 0; 179 + return NOTIFY_OK; 180 + break; 181 + case NETDEV_UP: 182 + nes_debug(NES_DBG_NETDEV, "event:UP\n"); 183 + 184 + if (nesvnic->local_ipaddr != 0) { 185 + nes_debug(NES_DBG_NETDEV, "Interface already has local_ipaddr\n"); 186 + return NOTIFY_OK; 187 + } 188 + /* Add the address to the IP table */ 189 + nesvnic->local_ipaddr = ifa->ifa_address; 190 + 191 + nes_write_indexed(nesdev, 192 + NES_IDX_DST_IP_ADDR+(0x10*PCI_FUNC(nesdev->pcidev->devfn)), 193 + ntohl(ifa->ifa_address)); 194 + nes_manage_arp_cache(netdev, netdev->dev_addr, 195 + ntohl(nesvnic->local_ipaddr), NES_ARP_ADD); 196 + return NOTIFY_OK; 197 + break; 198 + default: 199 + break; 200 + } 201 + } 202 + } 203 + 204 + return NOTIFY_DONE; 205 + } 206 + 207 + 208 + /** 209 + * nes_net_event 210 + */ 211 + static int nes_net_event(struct notifier_block *notifier, 212 + unsigned long event, void *ptr) 213 + { 214 + struct neighbour *neigh = ptr; 215 + struct nes_device *nesdev; 216 + struct net_device *netdev; 217 + struct nes_vnic *nesvnic; 218 + 219 + switch (event) { 220 + case NETEVENT_NEIGH_UPDATE: 221 + list_for_each_entry(nesdev, &nes_dev_list, list) { 222 + /* nes_debug(NES_DBG_NETDEV, "Nesdev list entry = 0x%p.\n", nesdev); */ 223 + netdev = nesdev->netdev[0]; 224 + nesvnic = netdev_priv(netdev); 225 + if (netdev == neigh->dev) { 226 + if (nesvnic->rdma_enabled == 0) { 227 + nes_debug(NES_DBG_NETDEV, "Skipping device %s since no RDMA\n", 228 + netdev->name); 229 + } else { 230 + if (neigh->nud_state & NUD_VALID) { 231 + nes_manage_arp_cache(neigh->dev, neigh->ha, 232 + ntohl(*(__be32 *)neigh->primary_key), NES_ARP_ADD); 233 + } else { 234 + nes_manage_arp_cache(neigh->dev, neigh->ha, 235 + ntohl(*(__be32 *)neigh->primary_key), NES_ARP_DELETE); 236 + } 237 + } 238 + return NOTIFY_OK; 239 + } 240 + } 241 + break; 242 + default: 243 + nes_debug(NES_DBG_NETDEV, "NETEVENT_ %lu undefined\n", event); 244 + break; 245 + } 246 + 247 + return NOTIFY_DONE; 248 + } 249 + 250 + 251 + /** 252 + * nes_add_ref 253 + */ 254 + void nes_add_ref(struct ib_qp *ibqp) 255 + { 256 + struct nes_qp *nesqp; 257 + 258 + nesqp = to_nesqp(ibqp); 259 + nes_debug(NES_DBG_QP, "Bumping refcount for QP%u. Pre-inc value = %u\n", 260 + ibqp->qp_num, atomic_read(&nesqp->refcount)); 261 + atomic_inc(&nesqp->refcount); 262 + } 263 + 264 + static void nes_cqp_rem_ref_callback(struct nes_device *nesdev, struct nes_cqp_request *cqp_request) 265 + { 266 + unsigned long flags; 267 + struct nes_qp *nesqp = cqp_request->cqp_callback_pointer; 268 + struct nes_adapter *nesadapter = nesdev->nesadapter; 269 + u32 qp_id; 270 + 271 + atomic_inc(&qps_destroyed); 272 + 273 + /* Free the control structures */ 274 + 275 + qp_id = nesqp->hwqp.qp_id; 276 + if (nesqp->pbl_vbase) { 277 + pci_free_consistent(nesdev->pcidev, nesqp->qp_mem_size, 278 + nesqp->hwqp.q2_vbase, nesqp->hwqp.q2_pbase); 279 + spin_lock_irqsave(&nesadapter->pbl_lock, flags); 280 + nesadapter->free_256pbl++; 281 + spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); 282 + pci_free_consistent(nesdev->pcidev, 256, nesqp->pbl_vbase, nesqp->pbl_pbase); 283 + nesqp->pbl_vbase = NULL; 284 + 285 + } else { 286 + pci_free_consistent(nesdev->pcidev, nesqp->qp_mem_size, 287 + nesqp->hwqp.sq_vbase, nesqp->hwqp.sq_pbase); 288 + } 289 + nes_free_resource(nesadapter, nesadapter->allocated_qps, nesqp->hwqp.qp_id); 290 + 291 + kfree(nesqp->allocated_buffer); 292 + 293 + } 294 + 295 + /** 296 + * nes_rem_ref 297 + */ 298 + void nes_rem_ref(struct ib_qp *ibqp) 299 + { 300 + u64 u64temp; 301 + struct nes_qp *nesqp; 302 + struct nes_vnic *nesvnic = to_nesvnic(ibqp->device); 303 + struct nes_device *nesdev = nesvnic->nesdev; 304 + struct nes_adapter *nesadapter = nesdev->nesadapter; 305 + struct nes_hw_cqp_wqe *cqp_wqe; 306 + struct nes_cqp_request *cqp_request; 307 + u32 opcode; 308 + 309 + nesqp = to_nesqp(ibqp); 310 + 311 + if (atomic_read(&nesqp->refcount) == 0) { 312 + printk(KERN_INFO PFX "%s: Reference count already 0 for QP%d, last aeq = 0x%04X.\n", 313 + __FUNCTION__, ibqp->qp_num, nesqp->last_aeq); 314 + BUG(); 315 + } 316 + 317 + if (atomic_dec_and_test(&nesqp->refcount)) { 318 + nesadapter->qp_table[nesqp->hwqp.qp_id-NES_FIRST_QPN] = NULL; 319 + 320 + /* Destroy the QP */ 321 + cqp_request = nes_get_cqp_request(nesdev); 322 + if (cqp_request == NULL) { 323 + nes_debug(NES_DBG_QP, "Failed to get a cqp_request.\n"); 324 + return; 325 + } 326 + cqp_request->waiting = 0; 327 + cqp_request->callback = 1; 328 + cqp_request->cqp_callback = nes_cqp_rem_ref_callback; 329 + cqp_request->cqp_callback_pointer = nesqp; 330 + cqp_wqe = &cqp_request->cqp_wqe; 331 + 332 + nes_fill_init_cqp_wqe(cqp_wqe, nesdev); 333 + opcode = NES_CQP_DESTROY_QP | NES_CQP_QP_TYPE_IWARP; 334 + 335 + if (nesqp->hte_added) { 336 + opcode |= NES_CQP_QP_DEL_HTE; 337 + nesqp->hte_added = 0; 338 + } 339 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX, opcode); 340 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_ID_IDX, nesqp->hwqp.qp_id); 341 + u64temp = (u64)nesqp->nesqp_context_pbase; 342 + set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_QP_WQE_CONTEXT_LOW_IDX, u64temp); 343 + nes_post_cqp_request(nesdev, cqp_request, NES_CQP_REQUEST_RING_DOORBELL); 344 + } 345 + } 346 + 347 + 348 + /** 349 + * nes_get_qp 350 + */ 351 + struct ib_qp *nes_get_qp(struct ib_device *device, int qpn) 352 + { 353 + struct nes_vnic *nesvnic = to_nesvnic(device); 354 + struct nes_device *nesdev = nesvnic->nesdev; 355 + struct nes_adapter *nesadapter = nesdev->nesadapter; 356 + 357 + if ((qpn < NES_FIRST_QPN) || (qpn >= (NES_FIRST_QPN + nesadapter->max_qp))) 358 + return NULL; 359 + 360 + return &nesadapter->qp_table[qpn - NES_FIRST_QPN]->ibqp; 361 + } 362 + 363 + 364 + /** 365 + * nes_print_macaddr 366 + */ 367 + static void nes_print_macaddr(struct net_device *netdev) 368 + { 369 + nes_debug(NES_DBG_INIT, "%s: MAC %02X:%02X:%02X:%02X:%02X:%02X, IRQ %u\n", 370 + netdev->name, 371 + netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2], 372 + netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5], 373 + netdev->irq); 374 + } 375 + 376 + 377 + /** 378 + * nes_interrupt - handle interrupts 379 + */ 380 + static irqreturn_t nes_interrupt(int irq, void *dev_id) 381 + { 382 + struct nes_device *nesdev = (struct nes_device *)dev_id; 383 + int handled = 0; 384 + u32 int_mask; 385 + u32 int_req; 386 + u32 int_stat; 387 + u32 intf_int_stat; 388 + u32 timer_stat; 389 + 390 + if (nesdev->msi_enabled) { 391 + /* No need to read the interrupt pending register if msi is enabled */ 392 + handled = 1; 393 + } else { 394 + if (unlikely(nesdev->nesadapter->hw_rev == NE020_REV)) { 395 + /* Master interrupt enable provides synchronization for kicking off bottom half 396 + when interrupt sharing is going on */ 397 + int_mask = nes_read32(nesdev->regs + NES_INT_MASK); 398 + if (int_mask & 0x80000000) { 399 + /* Check interrupt status to see if this might be ours */ 400 + int_stat = nes_read32(nesdev->regs + NES_INT_STAT); 401 + int_req = nesdev->int_req; 402 + if (int_stat&int_req) { 403 + /* if interesting CEQ or AEQ is pending, claim the interrupt */ 404 + if ((int_stat&int_req) & (~(NES_INT_TIMER|NES_INT_INTF))) { 405 + handled = 1; 406 + } else { 407 + if (((int_stat & int_req) & NES_INT_TIMER) == NES_INT_TIMER) { 408 + /* Timer might be running but might be for another function */ 409 + timer_stat = nes_read32(nesdev->regs + NES_TIMER_STAT); 410 + if ((timer_stat & nesdev->timer_int_req) != 0) { 411 + handled = 1; 412 + } 413 + } 414 + if ((((int_stat & int_req) & NES_INT_INTF) == NES_INT_INTF) && 415 + (handled == 0)) { 416 + intf_int_stat = nes_read32(nesdev->regs+NES_INTF_INT_STAT); 417 + if ((intf_int_stat & nesdev->intf_int_req) != 0) { 418 + handled = 1; 419 + } 420 + } 421 + } 422 + if (handled) { 423 + nes_write32(nesdev->regs+NES_INT_MASK, int_mask & (~0x80000000)); 424 + int_mask = nes_read32(nesdev->regs+NES_INT_MASK); 425 + /* Save off the status to save an additional read */ 426 + nesdev->int_stat = int_stat; 427 + nesdev->napi_isr_ran = 1; 428 + } 429 + } 430 + } 431 + } else { 432 + handled = nes_read32(nesdev->regs+NES_INT_PENDING); 433 + } 434 + } 435 + 436 + if (handled) { 437 + 438 + if (nes_napi_isr(nesdev) == 0) { 439 + tasklet_schedule(&nesdev->dpc_tasklet); 440 + 441 + } 442 + return IRQ_HANDLED; 443 + } else { 444 + return IRQ_NONE; 445 + } 446 + } 447 + 448 + 449 + /** 450 + * nes_probe - Device initialization 451 + */ 452 + static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) 453 + { 454 + struct net_device *netdev = NULL; 455 + struct nes_device *nesdev = NULL; 456 + int ret = 0; 457 + struct nes_vnic *nesvnic = NULL; 458 + void __iomem *mmio_regs = NULL; 459 + u8 hw_rev; 460 + 461 + assert(pcidev != NULL); 462 + assert(ent != NULL); 463 + 464 + printk(KERN_INFO PFX "NetEffect RNIC driver v%s loading. (%s)\n", 465 + DRV_VERSION, pci_name(pcidev)); 466 + 467 + ret = pci_enable_device(pcidev); 468 + if (ret) { 469 + printk(KERN_ERR PFX "Unable to enable PCI device. (%s)\n", pci_name(pcidev)); 470 + goto bail0; 471 + } 472 + 473 + nes_debug(NES_DBG_INIT, "BAR0 (@0x%08lX) size = 0x%lX bytes\n", 474 + (long unsigned int)pci_resource_start(pcidev, BAR_0), 475 + (long unsigned int)pci_resource_len(pcidev, BAR_0)); 476 + nes_debug(NES_DBG_INIT, "BAR1 (@0x%08lX) size = 0x%lX bytes\n", 477 + (long unsigned int)pci_resource_start(pcidev, BAR_1), 478 + (long unsigned int)pci_resource_len(pcidev, BAR_1)); 479 + 480 + /* Make sure PCI base addr are MMIO */ 481 + if (!(pci_resource_flags(pcidev, BAR_0) & IORESOURCE_MEM) || 482 + !(pci_resource_flags(pcidev, BAR_1) & IORESOURCE_MEM)) { 483 + printk(KERN_ERR PFX "PCI regions not an MMIO resource\n"); 484 + ret = -ENODEV; 485 + goto bail1; 486 + } 487 + 488 + /* Reserve PCI I/O and memory resources */ 489 + ret = pci_request_regions(pcidev, DRV_NAME); 490 + if (ret) { 491 + printk(KERN_ERR PFX "Unable to request regions. (%s)\n", pci_name(pcidev)); 492 + goto bail1; 493 + } 494 + 495 + if ((sizeof(dma_addr_t) > 4)) { 496 + ret = pci_set_dma_mask(pcidev, DMA_64BIT_MASK); 497 + if (ret < 0) { 498 + printk(KERN_ERR PFX "64b DMA mask configuration failed\n"); 499 + goto bail2; 500 + } 501 + ret = pci_set_consistent_dma_mask(pcidev, DMA_64BIT_MASK); 502 + if (ret) { 503 + printk(KERN_ERR PFX "64b DMA consistent mask configuration failed\n"); 504 + goto bail2; 505 + } 506 + } else { 507 + ret = pci_set_dma_mask(pcidev, DMA_32BIT_MASK); 508 + if (ret < 0) { 509 + printk(KERN_ERR PFX "32b DMA mask configuration failed\n"); 510 + goto bail2; 511 + } 512 + ret = pci_set_consistent_dma_mask(pcidev, DMA_32BIT_MASK); 513 + if (ret) { 514 + printk(KERN_ERR PFX "32b DMA consistent mask configuration failed\n"); 515 + goto bail2; 516 + } 517 + } 518 + 519 + pci_set_master(pcidev); 520 + 521 + /* Allocate hardware structure */ 522 + nesdev = kzalloc(sizeof(struct nes_device), GFP_KERNEL); 523 + if (!nesdev) { 524 + printk(KERN_ERR PFX "%s: Unable to alloc hardware struct\n", pci_name(pcidev)); 525 + ret = -ENOMEM; 526 + goto bail2; 527 + } 528 + 529 + nes_debug(NES_DBG_INIT, "Allocated nes device at %p\n", nesdev); 530 + nesdev->pcidev = pcidev; 531 + pci_set_drvdata(pcidev, nesdev); 532 + 533 + pci_read_config_byte(pcidev, 0x0008, &hw_rev); 534 + nes_debug(NES_DBG_INIT, "hw_rev=%u\n", hw_rev); 535 + 536 + spin_lock_init(&nesdev->indexed_regs_lock); 537 + 538 + /* Remap the PCI registers in adapter BAR0 to kernel VA space */ 539 + mmio_regs = ioremap_nocache(pci_resource_start(pcidev, BAR_0), sizeof(mmio_regs)); 540 + if (mmio_regs == NULL) { 541 + printk(KERN_ERR PFX "Unable to remap BAR0\n"); 542 + ret = -EIO; 543 + goto bail3; 544 + } 545 + nesdev->regs = mmio_regs; 546 + nesdev->index_reg = 0x50 + (PCI_FUNC(pcidev->devfn)*8) + mmio_regs; 547 + 548 + /* Ensure interrupts are disabled */ 549 + nes_write32(nesdev->regs+NES_INT_MASK, 0x7fffffff); 550 + 551 + if (nes_drv_opt & NES_DRV_OPT_ENABLE_MSI) { 552 + if (!pci_enable_msi(nesdev->pcidev)) { 553 + nesdev->msi_enabled = 1; 554 + nes_debug(NES_DBG_INIT, "MSI is enabled for device %s\n", 555 + pci_name(pcidev)); 556 + } else { 557 + nes_debug(NES_DBG_INIT, "MSI is disabled by linux for device %s\n", 558 + pci_name(pcidev)); 559 + } 560 + } else { 561 + nes_debug(NES_DBG_INIT, "MSI not requested due to driver options for device %s\n", 562 + pci_name(pcidev)); 563 + } 564 + 565 + nesdev->csr_start = pci_resource_start(nesdev->pcidev, BAR_0); 566 + nesdev->doorbell_region = pci_resource_start(nesdev->pcidev, BAR_1); 567 + 568 + /* Init the adapter */ 569 + nesdev->nesadapter = nes_init_adapter(nesdev, hw_rev); 570 + nesdev->nesadapter->et_rx_coalesce_usecs_irq = interrupt_mod_interval; 571 + if (!nesdev->nesadapter) { 572 + printk(KERN_ERR PFX "Unable to initialize adapter.\n"); 573 + ret = -ENOMEM; 574 + goto bail5; 575 + } 576 + 577 + /* nesdev->base_doorbell_index = 578 + nesdev->nesadapter->pd_config_base[PCI_FUNC(nesdev->pcidev->devfn)]; */ 579 + nesdev->base_doorbell_index = 1; 580 + nesdev->doorbell_start = nesdev->nesadapter->doorbell_start; 581 + nesdev->mac_index = PCI_FUNC(nesdev->pcidev->devfn) % nesdev->nesadapter->port_count; 582 + 583 + tasklet_init(&nesdev->dpc_tasklet, nes_dpc, (unsigned long)nesdev); 584 + 585 + /* bring up the Control QP */ 586 + if (nes_init_cqp(nesdev)) { 587 + ret = -ENODEV; 588 + goto bail6; 589 + } 590 + 591 + /* Arm the CCQ */ 592 + nes_write32(nesdev->regs+NES_CQE_ALLOC, NES_CQE_ALLOC_NOTIFY_NEXT | 593 + PCI_FUNC(nesdev->pcidev->devfn)); 594 + nes_read32(nesdev->regs+NES_CQE_ALLOC); 595 + 596 + /* Enable the interrupts */ 597 + nesdev->int_req = (0x101 << PCI_FUNC(nesdev->pcidev->devfn)) | 598 + (1 << (PCI_FUNC(nesdev->pcidev->devfn)+16)); 599 + if (PCI_FUNC(nesdev->pcidev->devfn) < 4) { 600 + nesdev->int_req |= (1 << (PCI_FUNC(nesdev->pcidev->devfn)+24)); 601 + } 602 + 603 + /* TODO: This really should be the first driver to load, not function 0 */ 604 + if (PCI_FUNC(nesdev->pcidev->devfn) == 0) { 605 + /* pick up PCI and critical errors if the first driver to load */ 606 + nesdev->intf_int_req = NES_INTF_INT_PCIERR | NES_INTF_INT_CRITERR; 607 + nesdev->int_req |= NES_INT_INTF; 608 + } else { 609 + nesdev->intf_int_req = 0; 610 + } 611 + nesdev->intf_int_req |= (1 << (PCI_FUNC(nesdev->pcidev->devfn)+16)); 612 + nes_write_indexed(nesdev, NES_IDX_DEBUG_ERROR_MASKS0, 0); 613 + nes_write_indexed(nesdev, NES_IDX_DEBUG_ERROR_MASKS1, 0); 614 + nes_write_indexed(nesdev, NES_IDX_DEBUG_ERROR_MASKS2, 0x00001265); 615 + nes_write_indexed(nesdev, NES_IDX_DEBUG_ERROR_MASKS4, 0x18021804); 616 + 617 + nes_write_indexed(nesdev, NES_IDX_DEBUG_ERROR_MASKS3, 0x17801790); 618 + 619 + /* deal with both periodic and one_shot */ 620 + nesdev->timer_int_req = 0x101 << PCI_FUNC(nesdev->pcidev->devfn); 621 + nesdev->nesadapter->timer_int_req |= nesdev->timer_int_req; 622 + nes_debug(NES_DBG_INIT, "setting int_req for function %u, nesdev = 0x%04X, adapter = 0x%04X\n", 623 + PCI_FUNC(nesdev->pcidev->devfn), 624 + nesdev->timer_int_req, nesdev->nesadapter->timer_int_req); 625 + 626 + nes_write32(nesdev->regs+NES_INTF_INT_MASK, ~(nesdev->intf_int_req)); 627 + 628 + list_add_tail(&nesdev->list, &nes_dev_list); 629 + 630 + /* Request an interrupt line for the driver */ 631 + ret = request_irq(pcidev->irq, nes_interrupt, IRQF_SHARED, DRV_NAME, nesdev); 632 + if (ret) { 633 + printk(KERN_ERR PFX "%s: requested IRQ %u is busy\n", 634 + pci_name(pcidev), pcidev->irq); 635 + goto bail65; 636 + } 637 + 638 + nes_write32(nesdev->regs+NES_INT_MASK, ~nesdev->int_req); 639 + 640 + if (nes_notifiers_registered == 0) { 641 + register_inetaddr_notifier(&nes_inetaddr_notifier); 642 + register_netevent_notifier(&nes_net_notifier); 643 + } 644 + nes_notifiers_registered++; 645 + 646 + /* Initialize network devices */ 647 + if ((netdev = nes_netdev_init(nesdev, mmio_regs)) == NULL) { 648 + goto bail7; 649 + } 650 + 651 + /* Register network device */ 652 + ret = register_netdev(netdev); 653 + if (ret) { 654 + printk(KERN_ERR PFX "Unable to register netdev, ret = %d\n", ret); 655 + nes_netdev_destroy(netdev); 656 + goto bail7; 657 + } 658 + 659 + nes_print_macaddr(netdev); 660 + /* create a CM core for this netdev */ 661 + nesvnic = netdev_priv(netdev); 662 + 663 + nesdev->netdev_count++; 664 + nesdev->nesadapter->netdev_count++; 665 + 666 + 667 + printk(KERN_ERR PFX "%s: NetEffect RNIC driver successfully loaded.\n", 668 + pci_name(pcidev)); 669 + return 0; 670 + 671 + bail7: 672 + printk(KERN_ERR PFX "bail7\n"); 673 + while (nesdev->netdev_count > 0) { 674 + nesdev->netdev_count--; 675 + nesdev->nesadapter->netdev_count--; 676 + 677 + unregister_netdev(nesdev->netdev[nesdev->netdev_count]); 678 + nes_netdev_destroy(nesdev->netdev[nesdev->netdev_count]); 679 + } 680 + 681 + nes_debug(NES_DBG_INIT, "netdev_count=%d, nesadapter->netdev_count=%d\n", 682 + nesdev->netdev_count, nesdev->nesadapter->netdev_count); 683 + 684 + nes_notifiers_registered--; 685 + if (nes_notifiers_registered == 0) { 686 + unregister_netevent_notifier(&nes_net_notifier); 687 + unregister_inetaddr_notifier(&nes_inetaddr_notifier); 688 + } 689 + 690 + list_del(&nesdev->list); 691 + nes_destroy_cqp(nesdev); 692 + 693 + bail65: 694 + printk(KERN_ERR PFX "bail65\n"); 695 + free_irq(pcidev->irq, nesdev); 696 + if (nesdev->msi_enabled) { 697 + pci_disable_msi(pcidev); 698 + } 699 + bail6: 700 + printk(KERN_ERR PFX "bail6\n"); 701 + tasklet_kill(&nesdev->dpc_tasklet); 702 + /* Deallocate the Adapter Structure */ 703 + nes_destroy_adapter(nesdev->nesadapter); 704 + 705 + bail5: 706 + printk(KERN_ERR PFX "bail5\n"); 707 + iounmap(nesdev->regs); 708 + 709 + bail3: 710 + printk(KERN_ERR PFX "bail3\n"); 711 + kfree(nesdev); 712 + 713 + bail2: 714 + pci_release_regions(pcidev); 715 + 716 + bail1: 717 + pci_disable_device(pcidev); 718 + 719 + bail0: 720 + return ret; 721 + } 722 + 723 + 724 + /** 725 + * nes_remove - unload from kernel 726 + */ 727 + static void __devexit nes_remove(struct pci_dev *pcidev) 728 + { 729 + struct nes_device *nesdev = pci_get_drvdata(pcidev); 730 + struct net_device *netdev; 731 + int netdev_index = 0; 732 + 733 + if (nesdev->netdev_count) { 734 + netdev = nesdev->netdev[netdev_index]; 735 + if (netdev) { 736 + netif_stop_queue(netdev); 737 + unregister_netdev(netdev); 738 + nes_netdev_destroy(netdev); 739 + 740 + nesdev->netdev[netdev_index] = NULL; 741 + nesdev->netdev_count--; 742 + nesdev->nesadapter->netdev_count--; 743 + } 744 + } 745 + 746 + nes_notifiers_registered--; 747 + if (nes_notifiers_registered == 0) { 748 + unregister_netevent_notifier(&nes_net_notifier); 749 + unregister_inetaddr_notifier(&nes_inetaddr_notifier); 750 + } 751 + 752 + list_del(&nesdev->list); 753 + nes_destroy_cqp(nesdev); 754 + tasklet_kill(&nesdev->dpc_tasklet); 755 + 756 + /* Deallocate the Adapter Structure */ 757 + nes_destroy_adapter(nesdev->nesadapter); 758 + 759 + free_irq(pcidev->irq, nesdev); 760 + 761 + if (nesdev->msi_enabled) { 762 + pci_disable_msi(pcidev); 763 + } 764 + 765 + iounmap(nesdev->regs); 766 + kfree(nesdev); 767 + 768 + /* nes_debug(NES_DBG_SHUTDOWN, "calling pci_release_regions.\n"); */ 769 + pci_release_regions(pcidev); 770 + pci_disable_device(pcidev); 771 + pci_set_drvdata(pcidev, NULL); 772 + } 773 + 774 + 775 + static struct pci_driver nes_pci_driver = { 776 + .name = DRV_NAME, 777 + .id_table = nes_pci_table, 778 + .probe = nes_probe, 779 + .remove = __devexit_p(nes_remove), 780 + }; 781 + 782 + static ssize_t nes_show_adapter(struct device_driver *ddp, char *buf) 783 + { 784 + unsigned int devfn = 0xffffffff; 785 + unsigned char bus_number = 0xff; 786 + unsigned int i = 0; 787 + struct nes_device *nesdev; 788 + 789 + list_for_each_entry(nesdev, &nes_dev_list, list) { 790 + if (i == ee_flsh_adapter) { 791 + devfn = nesdev->nesadapter->devfn; 792 + bus_number = nesdev->nesadapter->bus_number; 793 + break; 794 + } 795 + i++; 796 + } 797 + 798 + return snprintf(buf, PAGE_SIZE, "%x:%x", bus_number, devfn); 799 + } 800 + 801 + static ssize_t nes_store_adapter(struct device_driver *ddp, 802 + const char *buf, size_t count) 803 + { 804 + char *p = (char *)buf; 805 + 806 + ee_flsh_adapter = simple_strtoul(p, &p, 10); 807 + return strnlen(buf, count); 808 + } 809 + 810 + static ssize_t nes_show_ee_cmd(struct device_driver *ddp, char *buf) 811 + { 812 + u32 eeprom_cmd = 0xdead; 813 + u32 i = 0; 814 + struct nes_device *nesdev; 815 + 816 + list_for_each_entry(nesdev, &nes_dev_list, list) { 817 + if (i == ee_flsh_adapter) { 818 + eeprom_cmd = nes_read32(nesdev->regs + NES_EEPROM_COMMAND); 819 + break; 820 + } 821 + i++; 822 + } 823 + return snprintf(buf, PAGE_SIZE, "0x%x\n", eeprom_cmd); 824 + } 825 + 826 + static ssize_t nes_store_ee_cmd(struct device_driver *ddp, 827 + const char *buf, size_t count) 828 + { 829 + char *p = (char *)buf; 830 + u32 val; 831 + u32 i = 0; 832 + struct nes_device *nesdev; 833 + 834 + if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') { 835 + val = simple_strtoul(p, &p, 16); 836 + list_for_each_entry(nesdev, &nes_dev_list, list) { 837 + if (i == ee_flsh_adapter) { 838 + nes_write32(nesdev->regs + NES_EEPROM_COMMAND, val); 839 + break; 840 + } 841 + i++; 842 + } 843 + } 844 + return strnlen(buf, count); 845 + } 846 + 847 + static ssize_t nes_show_ee_data(struct device_driver *ddp, char *buf) 848 + { 849 + u32 eeprom_data = 0xdead; 850 + u32 i = 0; 851 + struct nes_device *nesdev; 852 + 853 + list_for_each_entry(nesdev, &nes_dev_list, list) { 854 + if (i == ee_flsh_adapter) { 855 + eeprom_data = nes_read32(nesdev->regs + NES_EEPROM_DATA); 856 + break; 857 + } 858 + i++; 859 + } 860 + 861 + return snprintf(buf, PAGE_SIZE, "0x%x\n", eeprom_data); 862 + } 863 + 864 + static ssize_t nes_store_ee_data(struct device_driver *ddp, 865 + const char *buf, size_t count) 866 + { 867 + char *p = (char *)buf; 868 + u32 val; 869 + u32 i = 0; 870 + struct nes_device *nesdev; 871 + 872 + if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') { 873 + val = simple_strtoul(p, &p, 16); 874 + list_for_each_entry(nesdev, &nes_dev_list, list) { 875 + if (i == ee_flsh_adapter) { 876 + nes_write32(nesdev->regs + NES_EEPROM_DATA, val); 877 + break; 878 + } 879 + i++; 880 + } 881 + } 882 + return strnlen(buf, count); 883 + } 884 + 885 + static ssize_t nes_show_flash_cmd(struct device_driver *ddp, char *buf) 886 + { 887 + u32 flash_cmd = 0xdead; 888 + u32 i = 0; 889 + struct nes_device *nesdev; 890 + 891 + list_for_each_entry(nesdev, &nes_dev_list, list) { 892 + if (i == ee_flsh_adapter) { 893 + flash_cmd = nes_read32(nesdev->regs + NES_FLASH_COMMAND); 894 + break; 895 + } 896 + i++; 897 + } 898 + 899 + return snprintf(buf, PAGE_SIZE, "0x%x\n", flash_cmd); 900 + } 901 + 902 + static ssize_t nes_store_flash_cmd(struct device_driver *ddp, 903 + const char *buf, size_t count) 904 + { 905 + char *p = (char *)buf; 906 + u32 val; 907 + u32 i = 0; 908 + struct nes_device *nesdev; 909 + 910 + if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') { 911 + val = simple_strtoul(p, &p, 16); 912 + list_for_each_entry(nesdev, &nes_dev_list, list) { 913 + if (i == ee_flsh_adapter) { 914 + nes_write32(nesdev->regs + NES_FLASH_COMMAND, val); 915 + break; 916 + } 917 + i++; 918 + } 919 + } 920 + return strnlen(buf, count); 921 + } 922 + 923 + static ssize_t nes_show_flash_data(struct device_driver *ddp, char *buf) 924 + { 925 + u32 flash_data = 0xdead; 926 + u32 i = 0; 927 + struct nes_device *nesdev; 928 + 929 + list_for_each_entry(nesdev, &nes_dev_list, list) { 930 + if (i == ee_flsh_adapter) { 931 + flash_data = nes_read32(nesdev->regs + NES_FLASH_DATA); 932 + break; 933 + } 934 + i++; 935 + } 936 + 937 + return snprintf(buf, PAGE_SIZE, "0x%x\n", flash_data); 938 + } 939 + 940 + static ssize_t nes_store_flash_data(struct device_driver *ddp, 941 + const char *buf, size_t count) 942 + { 943 + char *p = (char *)buf; 944 + u32 val; 945 + u32 i = 0; 946 + struct nes_device *nesdev; 947 + 948 + if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') { 949 + val = simple_strtoul(p, &p, 16); 950 + list_for_each_entry(nesdev, &nes_dev_list, list) { 951 + if (i == ee_flsh_adapter) { 952 + nes_write32(nesdev->regs + NES_FLASH_DATA, val); 953 + break; 954 + } 955 + i++; 956 + } 957 + } 958 + return strnlen(buf, count); 959 + } 960 + 961 + static ssize_t nes_show_nonidx_addr(struct device_driver *ddp, char *buf) 962 + { 963 + return snprintf(buf, PAGE_SIZE, "0x%x\n", sysfs_nonidx_addr); 964 + } 965 + 966 + static ssize_t nes_store_nonidx_addr(struct device_driver *ddp, 967 + const char *buf, size_t count) 968 + { 969 + char *p = (char *)buf; 970 + 971 + if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') 972 + sysfs_nonidx_addr = simple_strtoul(p, &p, 16); 973 + 974 + return strnlen(buf, count); 975 + } 976 + 977 + static ssize_t nes_show_nonidx_data(struct device_driver *ddp, char *buf) 978 + { 979 + u32 nonidx_data = 0xdead; 980 + u32 i = 0; 981 + struct nes_device *nesdev; 982 + 983 + list_for_each_entry(nesdev, &nes_dev_list, list) { 984 + if (i == ee_flsh_adapter) { 985 + nonidx_data = nes_read32(nesdev->regs + sysfs_nonidx_addr); 986 + break; 987 + } 988 + i++; 989 + } 990 + 991 + return snprintf(buf, PAGE_SIZE, "0x%x\n", nonidx_data); 992 + } 993 + 994 + static ssize_t nes_store_nonidx_data(struct device_driver *ddp, 995 + const char *buf, size_t count) 996 + { 997 + char *p = (char *)buf; 998 + u32 val; 999 + u32 i = 0; 1000 + struct nes_device *nesdev; 1001 + 1002 + if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') { 1003 + val = simple_strtoul(p, &p, 16); 1004 + list_for_each_entry(nesdev, &nes_dev_list, list) { 1005 + if (i == ee_flsh_adapter) { 1006 + nes_write32(nesdev->regs + sysfs_nonidx_addr, val); 1007 + break; 1008 + } 1009 + i++; 1010 + } 1011 + } 1012 + return strnlen(buf, count); 1013 + } 1014 + 1015 + static ssize_t nes_show_idx_addr(struct device_driver *ddp, char *buf) 1016 + { 1017 + return snprintf(buf, PAGE_SIZE, "0x%x\n", sysfs_idx_addr); 1018 + } 1019 + 1020 + static ssize_t nes_store_idx_addr(struct device_driver *ddp, 1021 + const char *buf, size_t count) 1022 + { 1023 + char *p = (char *)buf; 1024 + 1025 + if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') 1026 + sysfs_idx_addr = simple_strtoul(p, &p, 16); 1027 + 1028 + return strnlen(buf, count); 1029 + } 1030 + 1031 + static ssize_t nes_show_idx_data(struct device_driver *ddp, char *buf) 1032 + { 1033 + u32 idx_data = 0xdead; 1034 + u32 i = 0; 1035 + struct nes_device *nesdev; 1036 + 1037 + list_for_each_entry(nesdev, &nes_dev_list, list) { 1038 + if (i == ee_flsh_adapter) { 1039 + idx_data = nes_read_indexed(nesdev, sysfs_idx_addr); 1040 + break; 1041 + } 1042 + i++; 1043 + } 1044 + 1045 + return snprintf(buf, PAGE_SIZE, "0x%x\n", idx_data); 1046 + } 1047 + 1048 + static ssize_t nes_store_idx_data(struct device_driver *ddp, 1049 + const char *buf, size_t count) 1050 + { 1051 + char *p = (char *)buf; 1052 + u32 val; 1053 + u32 i = 0; 1054 + struct nes_device *nesdev; 1055 + 1056 + if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') { 1057 + val = simple_strtoul(p, &p, 16); 1058 + list_for_each_entry(nesdev, &nes_dev_list, list) { 1059 + if (i == ee_flsh_adapter) { 1060 + nes_write_indexed(nesdev, sysfs_idx_addr, val); 1061 + break; 1062 + } 1063 + i++; 1064 + } 1065 + } 1066 + return strnlen(buf, count); 1067 + } 1068 + 1069 + static DRIVER_ATTR(adapter, S_IRUSR | S_IWUSR, 1070 + nes_show_adapter, nes_store_adapter); 1071 + static DRIVER_ATTR(eeprom_cmd, S_IRUSR | S_IWUSR, 1072 + nes_show_ee_cmd, nes_store_ee_cmd); 1073 + static DRIVER_ATTR(eeprom_data, S_IRUSR | S_IWUSR, 1074 + nes_show_ee_data, nes_store_ee_data); 1075 + static DRIVER_ATTR(flash_cmd, S_IRUSR | S_IWUSR, 1076 + nes_show_flash_cmd, nes_store_flash_cmd); 1077 + static DRIVER_ATTR(flash_data, S_IRUSR | S_IWUSR, 1078 + nes_show_flash_data, nes_store_flash_data); 1079 + static DRIVER_ATTR(nonidx_addr, S_IRUSR | S_IWUSR, 1080 + nes_show_nonidx_addr, nes_store_nonidx_addr); 1081 + static DRIVER_ATTR(nonidx_data, S_IRUSR | S_IWUSR, 1082 + nes_show_nonidx_data, nes_store_nonidx_data); 1083 + static DRIVER_ATTR(idx_addr, S_IRUSR | S_IWUSR, 1084 + nes_show_idx_addr, nes_store_idx_addr); 1085 + static DRIVER_ATTR(idx_data, S_IRUSR | S_IWUSR, 1086 + nes_show_idx_data, nes_store_idx_data); 1087 + 1088 + static int nes_create_driver_sysfs(struct pci_driver *drv) 1089 + { 1090 + int error; 1091 + error = driver_create_file(&drv->driver, &driver_attr_adapter); 1092 + error |= driver_create_file(&drv->driver, &driver_attr_eeprom_cmd); 1093 + error |= driver_create_file(&drv->driver, &driver_attr_eeprom_data); 1094 + error |= driver_create_file(&drv->driver, &driver_attr_flash_cmd); 1095 + error |= driver_create_file(&drv->driver, &driver_attr_flash_data); 1096 + error |= driver_create_file(&drv->driver, &driver_attr_nonidx_addr); 1097 + error |= driver_create_file(&drv->driver, &driver_attr_nonidx_data); 1098 + error |= driver_create_file(&drv->driver, &driver_attr_idx_addr); 1099 + error |= driver_create_file(&drv->driver, &driver_attr_idx_data); 1100 + return error; 1101 + } 1102 + 1103 + static void nes_remove_driver_sysfs(struct pci_driver *drv) 1104 + { 1105 + driver_remove_file(&drv->driver, &driver_attr_adapter); 1106 + driver_remove_file(&drv->driver, &driver_attr_eeprom_cmd); 1107 + driver_remove_file(&drv->driver, &driver_attr_eeprom_data); 1108 + driver_remove_file(&drv->driver, &driver_attr_flash_cmd); 1109 + driver_remove_file(&drv->driver, &driver_attr_flash_data); 1110 + driver_remove_file(&drv->driver, &driver_attr_nonidx_addr); 1111 + driver_remove_file(&drv->driver, &driver_attr_nonidx_data); 1112 + driver_remove_file(&drv->driver, &driver_attr_idx_addr); 1113 + driver_remove_file(&drv->driver, &driver_attr_idx_data); 1114 + } 1115 + 1116 + /** 1117 + * nes_init_module - module initialization entry point 1118 + */ 1119 + static int __init nes_init_module(void) 1120 + { 1121 + int retval; 1122 + int retval1; 1123 + 1124 + retval = nes_cm_start(); 1125 + if (retval) { 1126 + printk(KERN_ERR PFX "Unable to start NetEffect iWARP CM.\n"); 1127 + return retval; 1128 + } 1129 + retval = pci_register_driver(&nes_pci_driver); 1130 + if (retval >= 0) { 1131 + retval1 = nes_create_driver_sysfs(&nes_pci_driver); 1132 + if (retval1 < 0) 1133 + printk(KERN_ERR PFX "Unable to create NetEffect sys files.\n"); 1134 + } 1135 + return retval; 1136 + } 1137 + 1138 + 1139 + /** 1140 + * nes_exit_module - module unload entry point 1141 + */ 1142 + static void __exit nes_exit_module(void) 1143 + { 1144 + nes_cm_stop(); 1145 + nes_remove_driver_sysfs(&nes_pci_driver); 1146 + 1147 + pci_unregister_driver(&nes_pci_driver); 1148 + } 1149 + 1150 + 1151 + module_init(nes_init_module); 1152 + module_exit(nes_exit_module);
+560
drivers/infiniband/hw/nes/nes.h
···
··· 1 + /* 2 + * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved. 3 + * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. 4 + * 5 + * This software is available to you under a choice of one of two 6 + * licenses. You may choose to be licensed under the terms of the GNU 7 + * General Public License (GPL) Version 2, available from the file 8 + * COPYING in the main directory of this source tree, or the 9 + * OpenIB.org BSD license below: 10 + * 11 + * Redistribution and use in source and binary forms, with or 12 + * without modification, are permitted provided that the following 13 + * conditions are met: 14 + * 15 + * - Redistributions of source code must retain the above 16 + * copyright notice, this list of conditions and the following 17 + * disclaimer. 18 + * 19 + * - Redistributions in binary form must reproduce the above 20 + * copyright notice, this list of conditions and the following 21 + * disclaimer in the documentation and/or other materials 22 + * provided with the distribution. 23 + * 24 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 28 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 29 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 30 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 + * SOFTWARE. 32 + */ 33 + 34 + #ifndef __NES_H 35 + #define __NES_H 36 + 37 + #include <linux/netdevice.h> 38 + #include <linux/inetdevice.h> 39 + #include <linux/spinlock.h> 40 + #include <linux/kernel.h> 41 + #include <linux/delay.h> 42 + #include <linux/pci.h> 43 + #include <linux/dma-mapping.h> 44 + #include <linux/workqueue.h> 45 + #include <linux/slab.h> 46 + #include <asm/semaphore.h> 47 + #include <linux/version.h> 48 + #include <asm/io.h> 49 + #include <linux/crc32c.h> 50 + 51 + #include <rdma/ib_smi.h> 52 + #include <rdma/ib_verbs.h> 53 + #include <rdma/ib_pack.h> 54 + #include <rdma/rdma_cm.h> 55 + #include <rdma/iw_cm.h> 56 + 57 + #define NES_SEND_FIRST_WRITE 58 + 59 + #define QUEUE_DISCONNECTS 60 + 61 + #define DRV_BUILD "1" 62 + 63 + #define DRV_NAME "iw_nes" 64 + #define DRV_VERSION "1.0 KO Build " DRV_BUILD 65 + #define PFX DRV_NAME ": " 66 + 67 + /* 68 + * NetEffect PCI vendor id and NE010 PCI device id. 69 + */ 70 + #ifndef PCI_VENDOR_ID_NETEFFECT /* not in pci.ids yet */ 71 + #define PCI_VENDOR_ID_NETEFFECT 0x1678 72 + #define PCI_DEVICE_ID_NETEFFECT_NE020 0x0100 73 + #endif 74 + 75 + #define NE020_REV 4 76 + #define NE020_REV1 5 77 + 78 + #define BAR_0 0 79 + #define BAR_1 2 80 + 81 + #define RX_BUF_SIZE (1536 + 8) 82 + #define NES_REG0_SIZE (4 * 1024) 83 + #define NES_TX_TIMEOUT (6*HZ) 84 + #define NES_FIRST_QPN 64 85 + #define NES_SW_CONTEXT_ALIGN 1024 86 + 87 + #define NES_NIC_MAX_NICS 16 88 + #define NES_MAX_ARP_TABLE_SIZE 4096 89 + 90 + #define NES_NIC_CEQ_SIZE 8 91 + /* NICs will be on a separate CQ */ 92 + #define NES_CCEQ_SIZE ((nesadapter->max_cq / nesadapter->port_count) - 32) 93 + 94 + #define NES_MAX_PORT_COUNT 4 95 + 96 + #define MAX_DPC_ITERATIONS 128 97 + 98 + #define NES_CQP_REQUEST_NO_DOORBELL_RING 0 99 + #define NES_CQP_REQUEST_RING_DOORBELL 1 100 + 101 + #define NES_DRV_OPT_ENABLE_MPA_VER_0 0x00000001 102 + #define NES_DRV_OPT_DISABLE_MPA_CRC 0x00000002 103 + #define NES_DRV_OPT_DISABLE_FIRST_WRITE 0x00000004 104 + #define NES_DRV_OPT_DISABLE_INTF 0x00000008 105 + #define NES_DRV_OPT_ENABLE_MSI 0x00000010 106 + #define NES_DRV_OPT_DUAL_LOGICAL_PORT 0x00000020 107 + #define NES_DRV_OPT_SUPRESS_OPTION_BC 0x00000040 108 + #define NES_DRV_OPT_NO_INLINE_DATA 0x00000080 109 + #define NES_DRV_OPT_DISABLE_INT_MOD 0x00000100 110 + #define NES_DRV_OPT_DISABLE_VIRT_WQ 0x00000200 111 + 112 + #define NES_AEQ_EVENT_TIMEOUT 2500 113 + #define NES_DISCONNECT_EVENT_TIMEOUT 2000 114 + 115 + /* debug levels */ 116 + /* must match userspace */ 117 + #define NES_DBG_HW 0x00000001 118 + #define NES_DBG_INIT 0x00000002 119 + #define NES_DBG_ISR 0x00000004 120 + #define NES_DBG_PHY 0x00000008 121 + #define NES_DBG_NETDEV 0x00000010 122 + #define NES_DBG_CM 0x00000020 123 + #define NES_DBG_CM1 0x00000040 124 + #define NES_DBG_NIC_RX 0x00000080 125 + #define NES_DBG_NIC_TX 0x00000100 126 + #define NES_DBG_CQP 0x00000200 127 + #define NES_DBG_MMAP 0x00000400 128 + #define NES_DBG_MR 0x00000800 129 + #define NES_DBG_PD 0x00001000 130 + #define NES_DBG_CQ 0x00002000 131 + #define NES_DBG_QP 0x00004000 132 + #define NES_DBG_MOD_QP 0x00008000 133 + #define NES_DBG_AEQ 0x00010000 134 + #define NES_DBG_IW_RX 0x00020000 135 + #define NES_DBG_IW_TX 0x00040000 136 + #define NES_DBG_SHUTDOWN 0x00080000 137 + #define NES_DBG_RSVD1 0x10000000 138 + #define NES_DBG_RSVD2 0x20000000 139 + #define NES_DBG_RSVD3 0x40000000 140 + #define NES_DBG_RSVD4 0x80000000 141 + #define NES_DBG_ALL 0xffffffff 142 + 143 + #ifdef CONFIG_INFINIBAND_NES_DEBUG 144 + #define nes_debug(level, fmt, args...) \ 145 + if (level & nes_debug_level) \ 146 + printk(KERN_ERR PFX "%s[%u]: " fmt, __FUNCTION__, __LINE__, ##args) 147 + 148 + #define assert(expr) \ 149 + if (!(expr)) { \ 150 + printk(KERN_ERR PFX "Assertion failed! %s, %s, %s, line %d\n", \ 151 + #expr, __FILE__, __FUNCTION__, __LINE__); \ 152 + } 153 + 154 + #define NES_EVENT_TIMEOUT 1200000 155 + #else 156 + #define nes_debug(level, fmt, args...) 157 + #define assert(expr) do {} while (0) 158 + 159 + #define NES_EVENT_TIMEOUT 100000 160 + #endif 161 + 162 + #include "nes_hw.h" 163 + #include "nes_verbs.h" 164 + #include "nes_context.h" 165 + #include "nes_user.h" 166 + #include "nes_cm.h" 167 + 168 + extern int max_mtu; 169 + extern int nics_per_function; 170 + #define max_frame_len (max_mtu+ETH_HLEN) 171 + extern int interrupt_mod_interval; 172 + extern int nes_if_count; 173 + extern int mpa_version; 174 + extern int disable_mpa_crc; 175 + extern unsigned int send_first; 176 + extern unsigned int nes_drv_opt; 177 + extern unsigned int nes_debug_level; 178 + 179 + extern struct list_head nes_adapter_list; 180 + extern struct list_head nes_dev_list; 181 + 182 + extern struct nes_cm_core *g_cm_core; 183 + 184 + extern atomic_t cm_connects; 185 + extern atomic_t cm_accepts; 186 + extern atomic_t cm_disconnects; 187 + extern atomic_t cm_closes; 188 + extern atomic_t cm_connecteds; 189 + extern atomic_t cm_connect_reqs; 190 + extern atomic_t cm_rejects; 191 + extern atomic_t mod_qp_timouts; 192 + extern atomic_t qps_created; 193 + extern atomic_t qps_destroyed; 194 + extern atomic_t sw_qps_destroyed; 195 + extern u32 mh_detected; 196 + extern u32 mh_pauses_sent; 197 + extern u32 cm_packets_sent; 198 + extern u32 cm_packets_bounced; 199 + extern u32 cm_packets_created; 200 + extern u32 cm_packets_received; 201 + extern u32 cm_packets_dropped; 202 + extern u32 cm_packets_retrans; 203 + extern u32 cm_listens_created; 204 + extern u32 cm_listens_destroyed; 205 + extern u32 cm_backlog_drops; 206 + extern atomic_t cm_loopbacks; 207 + extern atomic_t cm_nodes_created; 208 + extern atomic_t cm_nodes_destroyed; 209 + extern atomic_t cm_accel_dropped_pkts; 210 + extern atomic_t cm_resets_recvd; 211 + 212 + extern u32 crit_err_count; 213 + extern u32 int_mod_timer_init; 214 + extern u32 int_mod_cq_depth_256; 215 + extern u32 int_mod_cq_depth_128; 216 + extern u32 int_mod_cq_depth_32; 217 + extern u32 int_mod_cq_depth_24; 218 + extern u32 int_mod_cq_depth_16; 219 + extern u32 int_mod_cq_depth_4; 220 + extern u32 int_mod_cq_depth_1; 221 + 222 + extern atomic_t cqp_reqs_allocated; 223 + extern atomic_t cqp_reqs_freed; 224 + extern atomic_t cqp_reqs_dynallocated; 225 + extern atomic_t cqp_reqs_dynfreed; 226 + extern atomic_t cqp_reqs_queued; 227 + extern atomic_t cqp_reqs_redriven; 228 + 229 + 230 + struct nes_device { 231 + struct nes_adapter *nesadapter; 232 + void __iomem *regs; 233 + void __iomem *index_reg; 234 + struct pci_dev *pcidev; 235 + struct net_device *netdev[NES_NIC_MAX_NICS]; 236 + u64 link_status_interrupts; 237 + struct tasklet_struct dpc_tasklet; 238 + spinlock_t indexed_regs_lock; 239 + unsigned long csr_start; 240 + unsigned long doorbell_region; 241 + unsigned long doorbell_start; 242 + unsigned long mac_tx_errors; 243 + unsigned long mac_pause_frames_sent; 244 + unsigned long mac_pause_frames_received; 245 + unsigned long mac_rx_errors; 246 + unsigned long mac_rx_crc_errors; 247 + unsigned long mac_rx_symbol_err_frames; 248 + unsigned long mac_rx_jabber_frames; 249 + unsigned long mac_rx_oversized_frames; 250 + unsigned long mac_rx_short_frames; 251 + unsigned long port_rx_discards; 252 + unsigned long port_tx_discards; 253 + unsigned int mac_index; 254 + unsigned int nes_stack_start; 255 + 256 + /* Control Structures */ 257 + void *cqp_vbase; 258 + dma_addr_t cqp_pbase; 259 + u32 cqp_mem_size; 260 + u8 ceq_index; 261 + u8 nic_ceq_index; 262 + struct nes_hw_cqp cqp; 263 + struct nes_hw_cq ccq; 264 + struct list_head cqp_avail_reqs; 265 + struct list_head cqp_pending_reqs; 266 + struct nes_cqp_request *nes_cqp_requests; 267 + 268 + u32 int_req; 269 + u32 int_stat; 270 + u32 timer_int_req; 271 + u32 timer_only_int_count; 272 + u32 intf_int_req; 273 + u32 last_mac_tx_pauses; 274 + u32 last_used_chunks_tx; 275 + struct list_head list; 276 + 277 + u16 base_doorbell_index; 278 + u16 currcq_count; 279 + u16 deepcq_count; 280 + u8 msi_enabled; 281 + u8 netdev_count; 282 + u8 napi_isr_ran; 283 + u8 disable_rx_flow_control; 284 + u8 disable_tx_flow_control; 285 + }; 286 + 287 + 288 + static inline void 289 + set_wqe_64bit_value(__le32 *wqe_words, u32 index, u64 value) 290 + { 291 + wqe_words[index] = cpu_to_le32((u32) ((unsigned long)value)); 292 + wqe_words[index + 1] = cpu_to_le32((u32)(upper_32_bits((unsigned long)value))); 293 + } 294 + 295 + static inline void 296 + set_wqe_32bit_value(__le32 *wqe_words, u32 index, u32 value) 297 + { 298 + wqe_words[index] = cpu_to_le32(value); 299 + } 300 + 301 + static inline void 302 + nes_fill_init_cqp_wqe(struct nes_hw_cqp_wqe *cqp_wqe, struct nes_device *nesdev) 303 + { 304 + set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_COMP_CTX_LOW_IDX, 305 + (u64)((unsigned long) &nesdev->cqp)); 306 + cqp_wqe->wqe_words[NES_CQP_WQE_COMP_SCRATCH_LOW_IDX] = 0; 307 + cqp_wqe->wqe_words[NES_CQP_WQE_COMP_SCRATCH_HIGH_IDX] = 0; 308 + cqp_wqe->wqe_words[NES_CQP_STAG_WQE_PBL_BLK_COUNT_IDX] = 0; 309 + cqp_wqe->wqe_words[NES_CQP_STAG_WQE_PBL_LEN_IDX] = 0; 310 + cqp_wqe->wqe_words[NES_CQP_STAG_WQE_LEN_LOW_IDX] = 0; 311 + cqp_wqe->wqe_words[NES_CQP_STAG_WQE_PA_LOW_IDX] = 0; 312 + cqp_wqe->wqe_words[NES_CQP_STAG_WQE_PA_HIGH_IDX] = 0; 313 + } 314 + 315 + static inline void 316 + nes_fill_init_qp_wqe(struct nes_hw_qp_wqe *wqe, struct nes_qp *nesqp, u32 head) 317 + { 318 + u32 value; 319 + value = ((u32)((unsigned long) nesqp)) | head; 320 + set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_COMP_CTX_HIGH_IDX, 321 + (u32)(upper_32_bits((unsigned long)(nesqp)))); 322 + set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_COMP_CTX_LOW_IDX, value); 323 + } 324 + 325 + /* Read from memory-mapped device */ 326 + static inline u32 nes_read_indexed(struct nes_device *nesdev, u32 reg_index) 327 + { 328 + unsigned long flags; 329 + void __iomem *addr = nesdev->index_reg; 330 + u32 value; 331 + 332 + spin_lock_irqsave(&nesdev->indexed_regs_lock, flags); 333 + 334 + writel(reg_index, addr); 335 + value = readl((void __iomem *)addr + 4); 336 + 337 + spin_unlock_irqrestore(&nesdev->indexed_regs_lock, flags); 338 + return value; 339 + } 340 + 341 + static inline u32 nes_read32(const void __iomem *addr) 342 + { 343 + return readl(addr); 344 + } 345 + 346 + static inline u16 nes_read16(const void __iomem *addr) 347 + { 348 + return readw(addr); 349 + } 350 + 351 + static inline u8 nes_read8(const void __iomem *addr) 352 + { 353 + return readb(addr); 354 + } 355 + 356 + /* Write to memory-mapped device */ 357 + static inline void nes_write_indexed(struct nes_device *nesdev, u32 reg_index, u32 val) 358 + { 359 + unsigned long flags; 360 + void __iomem *addr = nesdev->index_reg; 361 + 362 + spin_lock_irqsave(&nesdev->indexed_regs_lock, flags); 363 + 364 + writel(reg_index, addr); 365 + writel(val, (void __iomem *)addr + 4); 366 + 367 + spin_unlock_irqrestore(&nesdev->indexed_regs_lock, flags); 368 + } 369 + 370 + static inline void nes_write32(void __iomem *addr, u32 val) 371 + { 372 + writel(val, addr); 373 + } 374 + 375 + static inline void nes_write16(void __iomem *addr, u16 val) 376 + { 377 + writew(val, addr); 378 + } 379 + 380 + static inline void nes_write8(void __iomem *addr, u8 val) 381 + { 382 + writeb(val, addr); 383 + } 384 + 385 + 386 + 387 + static inline int nes_alloc_resource(struct nes_adapter *nesadapter, 388 + unsigned long *resource_array, u32 max_resources, 389 + u32 *req_resource_num, u32 *next) 390 + { 391 + unsigned long flags; 392 + u32 resource_num; 393 + 394 + spin_lock_irqsave(&nesadapter->resource_lock, flags); 395 + 396 + resource_num = find_next_zero_bit(resource_array, max_resources, *next); 397 + if (resource_num >= max_resources) { 398 + resource_num = find_first_zero_bit(resource_array, max_resources); 399 + if (resource_num >= max_resources) { 400 + printk(KERN_ERR PFX "%s: No available resourcess.\n", __FUNCTION__); 401 + spin_unlock_irqrestore(&nesadapter->resource_lock, flags); 402 + return -EMFILE; 403 + } 404 + } 405 + set_bit(resource_num, resource_array); 406 + *next = resource_num+1; 407 + if (*next == max_resources) { 408 + *next = 0; 409 + } 410 + spin_unlock_irqrestore(&nesadapter->resource_lock, flags); 411 + *req_resource_num = resource_num; 412 + 413 + return 0; 414 + } 415 + 416 + static inline int nes_is_resource_allocated(struct nes_adapter *nesadapter, 417 + unsigned long *resource_array, u32 resource_num) 418 + { 419 + unsigned long flags; 420 + int bit_is_set; 421 + 422 + spin_lock_irqsave(&nesadapter->resource_lock, flags); 423 + 424 + bit_is_set = test_bit(resource_num, resource_array); 425 + nes_debug(NES_DBG_HW, "resource_num %u is%s allocated.\n", 426 + resource_num, (bit_is_set ? "": " not")); 427 + spin_unlock_irqrestore(&nesadapter->resource_lock, flags); 428 + 429 + return bit_is_set; 430 + } 431 + 432 + static inline void nes_free_resource(struct nes_adapter *nesadapter, 433 + unsigned long *resource_array, u32 resource_num) 434 + { 435 + unsigned long flags; 436 + 437 + spin_lock_irqsave(&nesadapter->resource_lock, flags); 438 + clear_bit(resource_num, resource_array); 439 + spin_unlock_irqrestore(&nesadapter->resource_lock, flags); 440 + } 441 + 442 + static inline struct nes_vnic *to_nesvnic(struct ib_device *ibdev) 443 + { 444 + return container_of(ibdev, struct nes_ib_device, ibdev)->nesvnic; 445 + } 446 + 447 + static inline struct nes_pd *to_nespd(struct ib_pd *ibpd) 448 + { 449 + return container_of(ibpd, struct nes_pd, ibpd); 450 + } 451 + 452 + static inline struct nes_ucontext *to_nesucontext(struct ib_ucontext *ibucontext) 453 + { 454 + return container_of(ibucontext, struct nes_ucontext, ibucontext); 455 + } 456 + 457 + static inline struct nes_mr *to_nesmr(struct ib_mr *ibmr) 458 + { 459 + return container_of(ibmr, struct nes_mr, ibmr); 460 + } 461 + 462 + static inline struct nes_mr *to_nesmr_from_ibfmr(struct ib_fmr *ibfmr) 463 + { 464 + return container_of(ibfmr, struct nes_mr, ibfmr); 465 + } 466 + 467 + static inline struct nes_mr *to_nesmw(struct ib_mw *ibmw) 468 + { 469 + return container_of(ibmw, struct nes_mr, ibmw); 470 + } 471 + 472 + static inline struct nes_fmr *to_nesfmr(struct nes_mr *nesmr) 473 + { 474 + return container_of(nesmr, struct nes_fmr, nesmr); 475 + } 476 + 477 + static inline struct nes_cq *to_nescq(struct ib_cq *ibcq) 478 + { 479 + return container_of(ibcq, struct nes_cq, ibcq); 480 + } 481 + 482 + static inline struct nes_qp *to_nesqp(struct ib_qp *ibqp) 483 + { 484 + return container_of(ibqp, struct nes_qp, ibqp); 485 + } 486 + 487 + 488 + 489 + /* nes.c */ 490 + void nes_add_ref(struct ib_qp *); 491 + void nes_rem_ref(struct ib_qp *); 492 + struct ib_qp *nes_get_qp(struct ib_device *, int); 493 + 494 + 495 + /* nes_hw.c */ 496 + struct nes_adapter *nes_init_adapter(struct nes_device *, u8); 497 + void nes_nic_init_timer_defaults(struct nes_device *, u8); 498 + unsigned int nes_reset_adapter_ne020(struct nes_device *, u8 *); 499 + int nes_init_serdes(struct nes_device *, u8, u8, u8); 500 + void nes_init_csr_ne020(struct nes_device *, u8, u8); 501 + void nes_destroy_adapter(struct nes_adapter *); 502 + int nes_init_cqp(struct nes_device *); 503 + int nes_init_phy(struct nes_device *); 504 + int nes_init_nic_qp(struct nes_device *, struct net_device *); 505 + void nes_destroy_nic_qp(struct nes_vnic *); 506 + int nes_napi_isr(struct nes_device *); 507 + void nes_dpc(unsigned long); 508 + void nes_process_ceq(struct nes_device *, struct nes_hw_ceq *); 509 + void nes_process_aeq(struct nes_device *, struct nes_hw_aeq *); 510 + void nes_process_mac_intr(struct nes_device *, u32); 511 + void nes_nic_napi_ce_handler(struct nes_device *, struct nes_hw_nic_cq *); 512 + void nes_nic_ce_handler(struct nes_device *, struct nes_hw_nic_cq *); 513 + void nes_cqp_ce_handler(struct nes_device *, struct nes_hw_cq *); 514 + void nes_process_iwarp_aeqe(struct nes_device *, struct nes_hw_aeqe *); 515 + void nes_iwarp_ce_handler(struct nes_device *, struct nes_hw_cq *); 516 + int nes_destroy_cqp(struct nes_device *); 517 + int nes_nic_cm_xmit(struct sk_buff *, struct net_device *); 518 + 519 + /* nes_nic.c */ 520 + void nes_netdev_set_multicast_list(struct net_device *); 521 + void nes_netdev_exit(struct nes_vnic *); 522 + struct net_device *nes_netdev_init(struct nes_device *, void __iomem *); 523 + void nes_netdev_destroy(struct net_device *); 524 + int nes_nic_cm_xmit(struct sk_buff *, struct net_device *); 525 + 526 + /* nes_cm.c */ 527 + void *nes_cm_create(struct net_device *); 528 + int nes_cm_recv(struct sk_buff *, struct net_device *); 529 + void nes_update_arp(unsigned char *, u32, u32, u16, u16); 530 + void nes_manage_arp_cache(struct net_device *, unsigned char *, u32, u32); 531 + void nes_sock_release(struct nes_qp *, unsigned long *); 532 + struct nes_cm_core *nes_cm_alloc_core(void); 533 + void flush_wqes(struct nes_device *nesdev, struct nes_qp *, u32, u32); 534 + int nes_manage_apbvt(struct nes_vnic *, u32, u32, u32); 535 + int nes_cm_disconn(struct nes_qp *); 536 + void nes_cm_disconn_worker(void *); 537 + 538 + /* nes_verbs.c */ 539 + int nes_hw_modify_qp(struct nes_device *, struct nes_qp *, u32, u32); 540 + int nes_modify_qp(struct ib_qp *, struct ib_qp_attr *, int, struct ib_udata *); 541 + struct nes_ib_device *nes_init_ofa_device(struct net_device *); 542 + void nes_destroy_ofa_device(struct nes_ib_device *); 543 + int nes_register_ofa_device(struct nes_ib_device *); 544 + void nes_unregister_ofa_device(struct nes_ib_device *); 545 + 546 + /* nes_util.c */ 547 + int nes_read_eeprom_values(struct nes_device *, struct nes_adapter *); 548 + void nes_write_1G_phy_reg(struct nes_device *, u8, u8, u16); 549 + void nes_read_1G_phy_reg(struct nes_device *, u8, u8, u16 *); 550 + void nes_write_10G_phy_reg(struct nes_device *, u16, u8, u16); 551 + void nes_read_10G_phy_reg(struct nes_device *, u16, u8); 552 + struct nes_cqp_request *nes_get_cqp_request(struct nes_device *); 553 + void nes_post_cqp_request(struct nes_device *, struct nes_cqp_request *, int); 554 + int nes_arp_table(struct nes_device *, u32, u8 *, u32); 555 + void nes_mh_fix(unsigned long); 556 + void nes_clc(unsigned long); 557 + void nes_dump_mem(unsigned int, void *, int); 558 + u32 nes_crc32(u32, u32, u32, u32, u8 *, u32, u32, u32); 559 + 560 + #endif /* __NES_H */
+3088
drivers/infiniband/hw/nes/nes_cm.c
···
··· 1 + /* 2 + * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved. 3 + * 4 + * This software is available to you under a choice of one of two 5 + * licenses. You may choose to be licensed under the terms of the GNU 6 + * General Public License (GPL) Version 2, available from the file 7 + * COPYING in the main directory of this source tree, or the 8 + * OpenIB.org BSD license below: 9 + * 10 + * Redistribution and use in source and binary forms, with or 11 + * without modification, are permitted provided that the following 12 + * conditions are met: 13 + * 14 + * - Redistributions of source code must retain the above 15 + * copyright notice, this list of conditions and the following 16 + * disclaimer. 17 + * 18 + * - Redistributions in binary form must reproduce the above 19 + * copyright notice, this list of conditions and the following 20 + * disclaimer in the documentation and/or other materials 21 + * provided with the distribution. 22 + * 23 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 + * SOFTWARE. 31 + * 32 + */ 33 + 34 + 35 + #define TCPOPT_TIMESTAMP 8 36 + 37 + #include <asm/atomic.h> 38 + #include <linux/skbuff.h> 39 + #include <linux/ip.h> 40 + #include <linux/tcp.h> 41 + #include <linux/init.h> 42 + #include <linux/if_arp.h> 43 + #include <linux/notifier.h> 44 + #include <linux/net.h> 45 + #include <linux/types.h> 46 + #include <linux/timer.h> 47 + #include <linux/time.h> 48 + #include <linux/delay.h> 49 + #include <linux/etherdevice.h> 50 + #include <linux/netdevice.h> 51 + #include <linux/random.h> 52 + #include <linux/list.h> 53 + #include <linux/threads.h> 54 + 55 + #include <net/neighbour.h> 56 + #include <net/route.h> 57 + #include <net/ip_fib.h> 58 + 59 + #include "nes.h" 60 + 61 + u32 cm_packets_sent; 62 + u32 cm_packets_bounced; 63 + u32 cm_packets_dropped; 64 + u32 cm_packets_retrans; 65 + u32 cm_packets_created; 66 + u32 cm_packets_received; 67 + u32 cm_listens_created; 68 + u32 cm_listens_destroyed; 69 + u32 cm_backlog_drops; 70 + atomic_t cm_loopbacks; 71 + atomic_t cm_nodes_created; 72 + atomic_t cm_nodes_destroyed; 73 + atomic_t cm_accel_dropped_pkts; 74 + atomic_t cm_resets_recvd; 75 + 76 + static inline int mini_cm_accelerated(struct nes_cm_core *, struct nes_cm_node *); 77 + static struct nes_cm_listener *mini_cm_listen(struct nes_cm_core *, 78 + struct nes_vnic *, struct nes_cm_info *); 79 + static int add_ref_cm_node(struct nes_cm_node *); 80 + static int rem_ref_cm_node(struct nes_cm_core *, struct nes_cm_node *); 81 + static int mini_cm_del_listen(struct nes_cm_core *, struct nes_cm_listener *); 82 + 83 + 84 + /* External CM API Interface */ 85 + /* instance of function pointers for client API */ 86 + /* set address of this instance to cm_core->cm_ops at cm_core alloc */ 87 + static struct nes_cm_ops nes_cm_api = { 88 + mini_cm_accelerated, 89 + mini_cm_listen, 90 + mini_cm_del_listen, 91 + mini_cm_connect, 92 + mini_cm_close, 93 + mini_cm_accept, 94 + mini_cm_reject, 95 + mini_cm_recv_pkt, 96 + mini_cm_dealloc_core, 97 + mini_cm_get, 98 + mini_cm_set 99 + }; 100 + 101 + struct nes_cm_core *g_cm_core; 102 + 103 + atomic_t cm_connects; 104 + atomic_t cm_accepts; 105 + atomic_t cm_disconnects; 106 + atomic_t cm_closes; 107 + atomic_t cm_connecteds; 108 + atomic_t cm_connect_reqs; 109 + atomic_t cm_rejects; 110 + 111 + 112 + /** 113 + * create_event 114 + */ 115 + static struct nes_cm_event *create_event(struct nes_cm_node *cm_node, 116 + enum nes_cm_event_type type) 117 + { 118 + struct nes_cm_event *event; 119 + 120 + if (!cm_node->cm_id) 121 + return NULL; 122 + 123 + /* allocate an empty event */ 124 + event = kzalloc(sizeof(*event), GFP_ATOMIC); 125 + 126 + if (!event) 127 + return NULL; 128 + 129 + event->type = type; 130 + event->cm_node = cm_node; 131 + event->cm_info.rem_addr = cm_node->rem_addr; 132 + event->cm_info.loc_addr = cm_node->loc_addr; 133 + event->cm_info.rem_port = cm_node->rem_port; 134 + event->cm_info.loc_port = cm_node->loc_port; 135 + event->cm_info.cm_id = cm_node->cm_id; 136 + 137 + nes_debug(NES_DBG_CM, "Created event=%p, type=%u, dst_addr=%08x[%x]," 138 + " src_addr=%08x[%x]\n", 139 + event, type, 140 + event->cm_info.loc_addr, event->cm_info.loc_port, 141 + event->cm_info.rem_addr, event->cm_info.rem_port); 142 + 143 + nes_cm_post_event(event); 144 + return event; 145 + } 146 + 147 + 148 + /** 149 + * send_mpa_request 150 + */ 151 + int send_mpa_request(struct nes_cm_node *cm_node) 152 + { 153 + struct sk_buff *skb; 154 + int ret; 155 + 156 + skb = get_free_pkt(cm_node); 157 + if (!skb) { 158 + nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n"); 159 + return -1; 160 + } 161 + 162 + /* send an MPA Request frame */ 163 + form_cm_frame(skb, cm_node, NULL, 0, &cm_node->mpa_frame, 164 + cm_node->mpa_frame_size, SET_ACK); 165 + 166 + ret = schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 1, 0); 167 + if (ret < 0) { 168 + return ret; 169 + } 170 + 171 + return 0; 172 + } 173 + 174 + 175 + /** 176 + * recv_mpa - process a received TCP pkt, we are expecting an 177 + * IETF MPA frame 178 + */ 179 + static int parse_mpa(struct nes_cm_node *cm_node, u8 *buffer, u32 len) 180 + { 181 + struct ietf_mpa_frame *mpa_frame; 182 + 183 + /* assume req frame is in tcp data payload */ 184 + if (len < sizeof(struct ietf_mpa_frame)) { 185 + nes_debug(NES_DBG_CM, "The received ietf buffer was too small (%x)\n", len); 186 + return -1; 187 + } 188 + 189 + mpa_frame = (struct ietf_mpa_frame *)buffer; 190 + cm_node->mpa_frame_size = ntohs(mpa_frame->priv_data_len); 191 + 192 + if (cm_node->mpa_frame_size + sizeof(struct ietf_mpa_frame) != len) { 193 + nes_debug(NES_DBG_CM, "The received ietf buffer was not right" 194 + " complete (%x + %x != %x)\n", 195 + cm_node->mpa_frame_size, (u32)sizeof(struct ietf_mpa_frame), len); 196 + return -1; 197 + } 198 + 199 + /* copy entire MPA frame to our cm_node's frame */ 200 + memcpy(cm_node->mpa_frame_buf, buffer + sizeof(struct ietf_mpa_frame), 201 + cm_node->mpa_frame_size); 202 + 203 + return 0; 204 + } 205 + 206 + 207 + /** 208 + * handle_exception_pkt - process an exception packet. 209 + * We have been in a TSA state, and we have now received SW 210 + * TCP/IP traffic should be a FIN request or IP pkt with options 211 + */ 212 + static int handle_exception_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb) 213 + { 214 + int ret = 0; 215 + struct tcphdr *tcph = tcp_hdr(skb); 216 + 217 + /* first check to see if this a FIN pkt */ 218 + if (tcph->fin) { 219 + /* we need to ACK the FIN request */ 220 + send_ack(cm_node); 221 + 222 + /* check which side we are (client/server) and set next state accordingly */ 223 + if (cm_node->tcp_cntxt.client) 224 + cm_node->state = NES_CM_STATE_CLOSING; 225 + else { 226 + /* we are the server side */ 227 + cm_node->state = NES_CM_STATE_CLOSE_WAIT; 228 + /* since this is a self contained CM we don't wait for */ 229 + /* an APP to close us, just send final FIN immediately */ 230 + ret = send_fin(cm_node, NULL); 231 + cm_node->state = NES_CM_STATE_LAST_ACK; 232 + } 233 + } else { 234 + ret = -EINVAL; 235 + } 236 + 237 + return ret; 238 + } 239 + 240 + 241 + /** 242 + * form_cm_frame - get a free packet and build empty frame Use 243 + * node info to build. 244 + */ 245 + struct sk_buff *form_cm_frame(struct sk_buff *skb, struct nes_cm_node *cm_node, 246 + void *options, u32 optionsize, void *data, u32 datasize, u8 flags) 247 + { 248 + struct tcphdr *tcph; 249 + struct iphdr *iph; 250 + struct ethhdr *ethh; 251 + u8 *buf; 252 + u16 packetsize = sizeof(*iph); 253 + 254 + packetsize += sizeof(*tcph); 255 + packetsize += optionsize + datasize; 256 + 257 + memset(skb->data, 0x00, ETH_HLEN + sizeof(*iph) + sizeof(*tcph)); 258 + 259 + skb->len = 0; 260 + buf = skb_put(skb, packetsize + ETH_HLEN); 261 + 262 + ethh = (struct ethhdr *) buf; 263 + buf += ETH_HLEN; 264 + 265 + iph = (struct iphdr *)buf; 266 + buf += sizeof(*iph); 267 + tcph = (struct tcphdr *)buf; 268 + skb_reset_mac_header(skb); 269 + skb_set_network_header(skb, ETH_HLEN); 270 + skb_set_transport_header(skb, ETH_HLEN+sizeof(*iph)); 271 + buf += sizeof(*tcph); 272 + 273 + skb->ip_summed = CHECKSUM_PARTIAL; 274 + skb->protocol = htons(0x800); 275 + skb->data_len = 0; 276 + skb->mac_len = ETH_HLEN; 277 + 278 + memcpy(ethh->h_dest, cm_node->rem_mac, ETH_ALEN); 279 + memcpy(ethh->h_source, cm_node->loc_mac, ETH_ALEN); 280 + ethh->h_proto = htons(0x0800); 281 + 282 + iph->version = IPVERSION; 283 + iph->ihl = 5; /* 5 * 4Byte words, IP headr len */ 284 + iph->tos = 0; 285 + iph->tot_len = htons(packetsize); 286 + iph->id = htons(++cm_node->tcp_cntxt.loc_id); 287 + 288 + iph->frag_off = htons(0x4000); 289 + iph->ttl = 0x40; 290 + iph->protocol = 0x06; /* IPPROTO_TCP */ 291 + 292 + iph->saddr = htonl(cm_node->loc_addr); 293 + iph->daddr = htonl(cm_node->rem_addr); 294 + 295 + tcph->source = htons(cm_node->loc_port); 296 + tcph->dest = htons(cm_node->rem_port); 297 + tcph->seq = htonl(cm_node->tcp_cntxt.loc_seq_num); 298 + 299 + if (flags & SET_ACK) { 300 + cm_node->tcp_cntxt.loc_ack_num = cm_node->tcp_cntxt.rcv_nxt; 301 + tcph->ack_seq = htonl(cm_node->tcp_cntxt.loc_ack_num); 302 + tcph->ack = 1; 303 + } else 304 + tcph->ack_seq = 0; 305 + 306 + if (flags & SET_SYN) { 307 + cm_node->tcp_cntxt.loc_seq_num++; 308 + tcph->syn = 1; 309 + } else 310 + cm_node->tcp_cntxt.loc_seq_num += datasize; /* data (no headers) */ 311 + 312 + if (flags & SET_FIN) 313 + tcph->fin = 1; 314 + 315 + if (flags & SET_RST) 316 + tcph->rst = 1; 317 + 318 + tcph->doff = (u16)((sizeof(*tcph) + optionsize + 3) >> 2); 319 + tcph->window = htons(cm_node->tcp_cntxt.rcv_wnd); 320 + tcph->urg_ptr = 0; 321 + if (optionsize) 322 + memcpy(buf, options, optionsize); 323 + buf += optionsize; 324 + if (datasize) 325 + memcpy(buf, data, datasize); 326 + 327 + skb_shinfo(skb)->nr_frags = 0; 328 + cm_packets_created++; 329 + 330 + return skb; 331 + } 332 + 333 + 334 + /** 335 + * print_core - dump a cm core 336 + */ 337 + static void print_core(struct nes_cm_core *core) 338 + { 339 + nes_debug(NES_DBG_CM, "---------------------------------------------\n"); 340 + nes_debug(NES_DBG_CM, "CM Core -- (core = %p )\n", core); 341 + if (!core) 342 + return; 343 + nes_debug(NES_DBG_CM, "---------------------------------------------\n"); 344 + nes_debug(NES_DBG_CM, "Session ID : %u \n", atomic_read(&core->session_id)); 345 + 346 + nes_debug(NES_DBG_CM, "State : %u \n", core->state); 347 + 348 + nes_debug(NES_DBG_CM, "Tx Free cnt : %u \n", skb_queue_len(&core->tx_free_list)); 349 + nes_debug(NES_DBG_CM, "Listen Nodes : %u \n", atomic_read(&core->listen_node_cnt)); 350 + nes_debug(NES_DBG_CM, "Active Nodes : %u \n", atomic_read(&core->node_cnt)); 351 + 352 + nes_debug(NES_DBG_CM, "core : %p \n", core); 353 + 354 + nes_debug(NES_DBG_CM, "-------------- end core ---------------\n"); 355 + } 356 + 357 + 358 + /** 359 + * schedule_nes_timer 360 + * note - cm_node needs to be protected before calling this. Encase in: 361 + * rem_ref_cm_node(cm_core, cm_node);add_ref_cm_node(cm_node); 362 + */ 363 + int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb, 364 + enum nes_timer_type type, int send_retrans, 365 + int close_when_complete) 366 + { 367 + unsigned long flags; 368 + struct nes_cm_core *cm_core; 369 + struct nes_timer_entry *new_send; 370 + int ret = 0; 371 + u32 was_timer_set; 372 + 373 + new_send = kzalloc(sizeof(*new_send), GFP_ATOMIC); 374 + if (!new_send) 375 + return -1; 376 + if (!cm_node) 377 + return -EINVAL; 378 + 379 + /* new_send->timetosend = currenttime */ 380 + new_send->retrycount = NES_DEFAULT_RETRYS; 381 + new_send->retranscount = NES_DEFAULT_RETRANS; 382 + new_send->skb = skb; 383 + new_send->timetosend = jiffies; 384 + new_send->type = type; 385 + new_send->netdev = cm_node->netdev; 386 + new_send->send_retrans = send_retrans; 387 + new_send->close_when_complete = close_when_complete; 388 + 389 + if (type == NES_TIMER_TYPE_CLOSE) { 390 + new_send->timetosend += (HZ/2); /* TODO: decide on the correct value here */ 391 + spin_lock_irqsave(&cm_node->recv_list_lock, flags); 392 + list_add_tail(&new_send->list, &cm_node->recv_list); 393 + spin_unlock_irqrestore(&cm_node->recv_list_lock, flags); 394 + } 395 + 396 + if (type == NES_TIMER_TYPE_SEND) { 397 + new_send->seq_num = htonl(tcp_hdr(skb)->seq); 398 + atomic_inc(&new_send->skb->users); 399 + 400 + ret = nes_nic_cm_xmit(new_send->skb, cm_node->netdev); 401 + if (ret != NETDEV_TX_OK) { 402 + nes_debug(NES_DBG_CM, "Error sending packet %p (jiffies = %lu)\n", 403 + new_send, jiffies); 404 + atomic_dec(&new_send->skb->users); 405 + new_send->timetosend = jiffies; 406 + } else { 407 + cm_packets_sent++; 408 + if (!send_retrans) { 409 + if (close_when_complete) 410 + rem_ref_cm_node(cm_node->cm_core, cm_node); 411 + dev_kfree_skb_any(new_send->skb); 412 + kfree(new_send); 413 + return ret; 414 + } 415 + new_send->timetosend = jiffies + NES_RETRY_TIMEOUT; 416 + } 417 + spin_lock_irqsave(&cm_node->retrans_list_lock, flags); 418 + list_add_tail(&new_send->list, &cm_node->retrans_list); 419 + spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); 420 + } 421 + if (type == NES_TIMER_TYPE_RECV) { 422 + new_send->seq_num = htonl(tcp_hdr(skb)->seq); 423 + new_send->timetosend = jiffies; 424 + spin_lock_irqsave(&cm_node->recv_list_lock, flags); 425 + list_add_tail(&new_send->list, &cm_node->recv_list); 426 + spin_unlock_irqrestore(&cm_node->recv_list_lock, flags); 427 + } 428 + cm_core = cm_node->cm_core; 429 + 430 + was_timer_set = timer_pending(&cm_core->tcp_timer); 431 + 432 + if (!was_timer_set) { 433 + cm_core->tcp_timer.expires = new_send->timetosend; 434 + add_timer(&cm_core->tcp_timer); 435 + } 436 + 437 + return ret; 438 + } 439 + 440 + 441 + /** 442 + * nes_cm_timer_tick 443 + */ 444 + void nes_cm_timer_tick(unsigned long pass) 445 + { 446 + unsigned long flags, qplockflags; 447 + unsigned long nexttimeout = jiffies + NES_LONG_TIME; 448 + struct iw_cm_id *cm_id; 449 + struct nes_cm_node *cm_node; 450 + struct nes_timer_entry *send_entry, *recv_entry; 451 + struct list_head *list_core, *list_core_temp; 452 + struct list_head *list_node, *list_node_temp; 453 + struct nes_cm_core *cm_core = g_cm_core; 454 + struct nes_qp *nesqp; 455 + struct sk_buff *skb; 456 + u32 settimer = 0; 457 + int ret = NETDEV_TX_OK; 458 + int node_done; 459 + 460 + spin_lock_irqsave(&cm_core->ht_lock, flags); 461 + 462 + list_for_each_safe(list_node, list_core_temp, &cm_core->connected_nodes) { 463 + cm_node = container_of(list_node, struct nes_cm_node, list); 464 + add_ref_cm_node(cm_node); 465 + spin_unlock_irqrestore(&cm_core->ht_lock, flags); 466 + spin_lock_irqsave(&cm_node->recv_list_lock, flags); 467 + list_for_each_safe(list_core, list_node_temp, &cm_node->recv_list) { 468 + recv_entry = container_of(list_core, struct nes_timer_entry, list); 469 + if ((time_after(recv_entry->timetosend, jiffies)) && 470 + (recv_entry->type == NES_TIMER_TYPE_CLOSE)) { 471 + if (nexttimeout > recv_entry->timetosend || !settimer) { 472 + nexttimeout = recv_entry->timetosend; 473 + settimer = 1; 474 + } 475 + continue; 476 + } 477 + list_del(&recv_entry->list); 478 + cm_id = cm_node->cm_id; 479 + spin_unlock_irqrestore(&cm_node->recv_list_lock, flags); 480 + if (recv_entry->type == NES_TIMER_TYPE_CLOSE) { 481 + nesqp = (struct nes_qp *)recv_entry->skb; 482 + spin_lock_irqsave(&nesqp->lock, qplockflags); 483 + if (nesqp->cm_id) { 484 + nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, refcount = %d: " 485 + "****** HIT A NES_TIMER_TYPE_CLOSE" 486 + " with something to do!!! ******\n", 487 + nesqp->hwqp.qp_id, cm_id, 488 + atomic_read(&nesqp->refcount)); 489 + nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED; 490 + nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT; 491 + nesqp->ibqp_state = IB_QPS_ERR; 492 + spin_unlock_irqrestore(&nesqp->lock, qplockflags); 493 + nes_cm_disconn(nesqp); 494 + } else { 495 + spin_unlock_irqrestore(&nesqp->lock, qplockflags); 496 + nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, refcount = %d:" 497 + " ****** HIT A NES_TIMER_TYPE_CLOSE" 498 + " with nothing to do!!! ******\n", 499 + nesqp->hwqp.qp_id, cm_id, 500 + atomic_read(&nesqp->refcount)); 501 + nes_rem_ref(&nesqp->ibqp); 502 + } 503 + if (cm_id) 504 + cm_id->rem_ref(cm_id); 505 + } 506 + kfree(recv_entry); 507 + spin_lock_irqsave(&cm_node->recv_list_lock, flags); 508 + } 509 + spin_unlock_irqrestore(&cm_node->recv_list_lock, flags); 510 + 511 + spin_lock_irqsave(&cm_node->retrans_list_lock, flags); 512 + node_done = 0; 513 + list_for_each_safe(list_core, list_node_temp, &cm_node->retrans_list) { 514 + if (node_done) { 515 + break; 516 + } 517 + send_entry = container_of(list_core, struct nes_timer_entry, list); 518 + if (time_after(send_entry->timetosend, jiffies)) { 519 + if (cm_node->state != NES_CM_STATE_TSA) { 520 + if ((nexttimeout > send_entry->timetosend) || !settimer) { 521 + nexttimeout = send_entry->timetosend; 522 + settimer = 1; 523 + } 524 + node_done = 1; 525 + continue; 526 + } else { 527 + list_del(&send_entry->list); 528 + skb = send_entry->skb; 529 + spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); 530 + dev_kfree_skb_any(skb); 531 + kfree(send_entry); 532 + spin_lock_irqsave(&cm_node->retrans_list_lock, flags); 533 + continue; 534 + } 535 + } 536 + if (send_entry->type == NES_TIMER_NODE_CLEANUP) { 537 + list_del(&send_entry->list); 538 + spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); 539 + kfree(send_entry); 540 + spin_lock_irqsave(&cm_node->retrans_list_lock, flags); 541 + continue; 542 + } 543 + if ((send_entry->seq_num < cm_node->tcp_cntxt.rem_ack_num) || 544 + (cm_node->state == NES_CM_STATE_TSA) || 545 + (cm_node->state == NES_CM_STATE_CLOSED)) { 546 + skb = send_entry->skb; 547 + list_del(&send_entry->list); 548 + spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); 549 + kfree(send_entry); 550 + dev_kfree_skb_any(skb); 551 + spin_lock_irqsave(&cm_node->retrans_list_lock, flags); 552 + continue; 553 + } 554 + 555 + if (!send_entry->retranscount || !send_entry->retrycount) { 556 + cm_packets_dropped++; 557 + skb = send_entry->skb; 558 + list_del(&send_entry->list); 559 + spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); 560 + dev_kfree_skb_any(skb); 561 + kfree(send_entry); 562 + if (cm_node->state == NES_CM_STATE_SYN_RCVD) { 563 + /* this node never even generated an indication up to the cm */ 564 + rem_ref_cm_node(cm_core, cm_node); 565 + } else { 566 + cm_node->state = NES_CM_STATE_CLOSED; 567 + create_event(cm_node, NES_CM_EVENT_ABORTED); 568 + } 569 + spin_lock_irqsave(&cm_node->retrans_list_lock, flags); 570 + continue; 571 + } 572 + /* this seems like the correct place, but leave send entry unprotected */ 573 + // spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); 574 + atomic_inc(&send_entry->skb->users); 575 + cm_packets_retrans++; 576 + nes_debug(NES_DBG_CM, "Retransmitting send_entry %p for node %p," 577 + " jiffies = %lu, time to send = %lu, retranscount = %u, " 578 + "send_entry->seq_num = 0x%08X, cm_node->tcp_cntxt.rem_ack_num = 0x%08X\n", 579 + send_entry, cm_node, jiffies, send_entry->timetosend, send_entry->retranscount, 580 + send_entry->seq_num, cm_node->tcp_cntxt.rem_ack_num); 581 + 582 + spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); 583 + ret = nes_nic_cm_xmit(send_entry->skb, cm_node->netdev); 584 + if (ret != NETDEV_TX_OK) { 585 + cm_packets_bounced++; 586 + atomic_dec(&send_entry->skb->users); 587 + send_entry->retrycount--; 588 + nexttimeout = jiffies + NES_SHORT_TIME; 589 + settimer = 1; 590 + node_done = 1; 591 + spin_lock_irqsave(&cm_node->retrans_list_lock, flags); 592 + continue; 593 + } else { 594 + cm_packets_sent++; 595 + } 596 + spin_lock_irqsave(&cm_node->retrans_list_lock, flags); 597 + list_del(&send_entry->list); 598 + nes_debug(NES_DBG_CM, "Packet Sent: retrans count = %u, retry count = %u.\n", 599 + send_entry->retranscount, send_entry->retrycount); 600 + if (send_entry->send_retrans) { 601 + send_entry->retranscount--; 602 + send_entry->timetosend = jiffies + NES_RETRY_TIMEOUT; 603 + if (nexttimeout > send_entry->timetosend || !settimer) { 604 + nexttimeout = send_entry->timetosend; 605 + settimer = 1; 606 + } 607 + list_add(&send_entry->list, &cm_node->retrans_list); 608 + continue; 609 + } else { 610 + int close_when_complete; 611 + skb = send_entry->skb; 612 + close_when_complete = send_entry->close_when_complete; 613 + spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); 614 + if (close_when_complete) { 615 + BUG_ON(atomic_read(&cm_node->ref_count) == 1); 616 + rem_ref_cm_node(cm_core, cm_node); 617 + } 618 + dev_kfree_skb_any(skb); 619 + kfree(send_entry); 620 + spin_lock_irqsave(&cm_node->retrans_list_lock, flags); 621 + continue; 622 + } 623 + } 624 + spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); 625 + 626 + rem_ref_cm_node(cm_core, cm_node); 627 + 628 + spin_lock_irqsave(&cm_core->ht_lock, flags); 629 + if (ret != NETDEV_TX_OK) 630 + break; 631 + } 632 + spin_unlock_irqrestore(&cm_core->ht_lock, flags); 633 + 634 + if (settimer) { 635 + if (!timer_pending(&cm_core->tcp_timer)) { 636 + cm_core->tcp_timer.expires = nexttimeout; 637 + add_timer(&cm_core->tcp_timer); 638 + } 639 + } 640 + } 641 + 642 + 643 + /** 644 + * send_syn 645 + */ 646 + int send_syn(struct nes_cm_node *cm_node, u32 sendack) 647 + { 648 + int ret; 649 + int flags = SET_SYN; 650 + struct sk_buff *skb; 651 + char optionsbuffer[sizeof(struct option_mss) + 652 + sizeof(struct option_windowscale) + 653 + sizeof(struct option_base) + 1]; 654 + 655 + int optionssize = 0; 656 + /* Sending MSS option */ 657 + union all_known_options *options; 658 + 659 + if (!cm_node) 660 + return -EINVAL; 661 + 662 + options = (union all_known_options *)&optionsbuffer[optionssize]; 663 + options->as_mss.optionnum = OPTION_NUMBER_MSS; 664 + options->as_mss.length = sizeof(struct option_mss); 665 + options->as_mss.mss = htons(cm_node->tcp_cntxt.mss); 666 + optionssize += sizeof(struct option_mss); 667 + 668 + options = (union all_known_options *)&optionsbuffer[optionssize]; 669 + options->as_windowscale.optionnum = OPTION_NUMBER_WINDOW_SCALE; 670 + options->as_windowscale.length = sizeof(struct option_windowscale); 671 + options->as_windowscale.shiftcount = cm_node->tcp_cntxt.rcv_wscale; 672 + optionssize += sizeof(struct option_windowscale); 673 + 674 + if (sendack && !(NES_DRV_OPT_SUPRESS_OPTION_BC & nes_drv_opt) 675 + ) { 676 + options = (union all_known_options *)&optionsbuffer[optionssize]; 677 + options->as_base.optionnum = OPTION_NUMBER_WRITE0; 678 + options->as_base.length = sizeof(struct option_base); 679 + optionssize += sizeof(struct option_base); 680 + /* we need the size to be a multiple of 4 */ 681 + options = (union all_known_options *)&optionsbuffer[optionssize]; 682 + options->as_end = 1; 683 + optionssize += 1; 684 + options = (union all_known_options *)&optionsbuffer[optionssize]; 685 + options->as_end = 1; 686 + optionssize += 1; 687 + } 688 + 689 + options = (union all_known_options *)&optionsbuffer[optionssize]; 690 + options->as_end = OPTION_NUMBER_END; 691 + optionssize += 1; 692 + 693 + skb = get_free_pkt(cm_node); 694 + if (!skb) { 695 + nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n"); 696 + return -1; 697 + } 698 + 699 + if (sendack) 700 + flags |= SET_ACK; 701 + 702 + form_cm_frame(skb, cm_node, optionsbuffer, optionssize, NULL, 0, flags); 703 + ret = schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 1, 0); 704 + 705 + return ret; 706 + } 707 + 708 + 709 + /** 710 + * send_reset 711 + */ 712 + int send_reset(struct nes_cm_node *cm_node) 713 + { 714 + int ret; 715 + struct sk_buff *skb = get_free_pkt(cm_node); 716 + int flags = SET_RST | SET_ACK; 717 + 718 + if (!skb) { 719 + nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n"); 720 + return -1; 721 + } 722 + 723 + add_ref_cm_node(cm_node); 724 + form_cm_frame(skb, cm_node, NULL, 0, NULL, 0, flags); 725 + ret = schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 0, 1); 726 + 727 + return ret; 728 + } 729 + 730 + 731 + /** 732 + * send_ack 733 + */ 734 + int send_ack(struct nes_cm_node *cm_node) 735 + { 736 + int ret; 737 + struct sk_buff *skb = get_free_pkt(cm_node); 738 + 739 + if (!skb) { 740 + nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n"); 741 + return -1; 742 + } 743 + 744 + form_cm_frame(skb, cm_node, NULL, 0, NULL, 0, SET_ACK); 745 + ret = schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 0, 0); 746 + 747 + return ret; 748 + } 749 + 750 + 751 + /** 752 + * send_fin 753 + */ 754 + int send_fin(struct nes_cm_node *cm_node, struct sk_buff *skb) 755 + { 756 + int ret; 757 + 758 + /* if we didn't get a frame get one */ 759 + if (!skb) 760 + skb = get_free_pkt(cm_node); 761 + 762 + if (!skb) { 763 + nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n"); 764 + return -1; 765 + } 766 + 767 + form_cm_frame(skb, cm_node, NULL, 0, NULL, 0, SET_ACK | SET_FIN); 768 + ret = schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 1, 0); 769 + 770 + return ret; 771 + } 772 + 773 + 774 + /** 775 + * get_free_pkt 776 + */ 777 + struct sk_buff *get_free_pkt(struct nes_cm_node *cm_node) 778 + { 779 + struct sk_buff *skb, *new_skb; 780 + 781 + /* check to see if we need to repopulate the free tx pkt queue */ 782 + if (skb_queue_len(&cm_node->cm_core->tx_free_list) < NES_CM_FREE_PKT_LO_WATERMARK) { 783 + while (skb_queue_len(&cm_node->cm_core->tx_free_list) < 784 + cm_node->cm_core->free_tx_pkt_max) { 785 + /* replace the frame we took, we won't get it back */ 786 + new_skb = dev_alloc_skb(cm_node->cm_core->mtu); 787 + BUG_ON(!new_skb); 788 + /* add a replacement frame to the free tx list head */ 789 + skb_queue_head(&cm_node->cm_core->tx_free_list, new_skb); 790 + } 791 + } 792 + 793 + skb = skb_dequeue(&cm_node->cm_core->tx_free_list); 794 + 795 + return skb; 796 + } 797 + 798 + 799 + /** 800 + * make_hashkey - generate hash key from node tuple 801 + */ 802 + static inline int make_hashkey(u16 loc_port, nes_addr_t loc_addr, u16 rem_port, 803 + nes_addr_t rem_addr) 804 + { 805 + u32 hashkey = 0; 806 + 807 + hashkey = loc_addr + rem_addr + loc_port + rem_port; 808 + hashkey = (hashkey % NES_CM_HASHTABLE_SIZE); 809 + 810 + return hashkey; 811 + } 812 + 813 + 814 + /** 815 + * find_node - find a cm node that matches the reference cm node 816 + */ 817 + static struct nes_cm_node *find_node(struct nes_cm_core *cm_core, 818 + u16 rem_port, nes_addr_t rem_addr, u16 loc_port, nes_addr_t loc_addr) 819 + { 820 + unsigned long flags; 821 + u32 hashkey; 822 + struct list_head *list_pos; 823 + struct list_head *hte; 824 + struct nes_cm_node *cm_node; 825 + 826 + /* make a hash index key for this packet */ 827 + hashkey = make_hashkey(loc_port, loc_addr, rem_port, rem_addr); 828 + 829 + /* get a handle on the hte */ 830 + hte = &cm_core->connected_nodes; 831 + 832 + nes_debug(NES_DBG_CM, "Searching for an owner node:%x:%x from core %p->%p\n", 833 + loc_addr, loc_port, cm_core, hte); 834 + 835 + /* walk list and find cm_node associated with this session ID */ 836 + spin_lock_irqsave(&cm_core->ht_lock, flags); 837 + list_for_each(list_pos, hte) { 838 + cm_node = container_of(list_pos, struct nes_cm_node, list); 839 + /* compare quad, return node handle if a match */ 840 + nes_debug(NES_DBG_CM, "finding node %x:%x =? %x:%x ^ %x:%x =? %x:%x\n", 841 + cm_node->loc_addr, cm_node->loc_port, 842 + loc_addr, loc_port, 843 + cm_node->rem_addr, cm_node->rem_port, 844 + rem_addr, rem_port); 845 + if ((cm_node->loc_addr == loc_addr) && (cm_node->loc_port == loc_port) && 846 + (cm_node->rem_addr == rem_addr) && (cm_node->rem_port == rem_port)) { 847 + add_ref_cm_node(cm_node); 848 + spin_unlock_irqrestore(&cm_core->ht_lock, flags); 849 + return cm_node; 850 + } 851 + } 852 + spin_unlock_irqrestore(&cm_core->ht_lock, flags); 853 + 854 + /* no owner node */ 855 + return NULL; 856 + } 857 + 858 + 859 + /** 860 + * find_listener - find a cm node listening on this addr-port pair 861 + */ 862 + static struct nes_cm_listener *find_listener(struct nes_cm_core *cm_core, 863 + nes_addr_t dst_addr, u16 dst_port, enum nes_cm_listener_state listener_state) 864 + { 865 + unsigned long flags; 866 + struct list_head *listen_list; 867 + struct nes_cm_listener *listen_node; 868 + 869 + /* walk list and find cm_node associated with this session ID */ 870 + spin_lock_irqsave(&cm_core->listen_list_lock, flags); 871 + list_for_each(listen_list, &cm_core->listen_list.list) { 872 + listen_node = container_of(listen_list, struct nes_cm_listener, list); 873 + /* compare node pair, return node handle if a match */ 874 + if (((listen_node->loc_addr == dst_addr) || 875 + listen_node->loc_addr == 0x00000000) && 876 + (listen_node->loc_port == dst_port) && 877 + (listener_state & listen_node->listener_state)) { 878 + atomic_inc(&listen_node->ref_count); 879 + spin_unlock_irqrestore(&cm_core->listen_list_lock, flags); 880 + return listen_node; 881 + } 882 + } 883 + spin_unlock_irqrestore(&cm_core->listen_list_lock, flags); 884 + 885 + nes_debug(NES_DBG_CM, "Unable to find listener- %x:%x\n", 886 + dst_addr, dst_port); 887 + 888 + /* no listener */ 889 + return NULL; 890 + } 891 + 892 + 893 + /** 894 + * add_hte_node - add a cm node to the hash table 895 + */ 896 + static int add_hte_node(struct nes_cm_core *cm_core, struct nes_cm_node *cm_node) 897 + { 898 + unsigned long flags; 899 + u32 hashkey; 900 + struct list_head *hte; 901 + 902 + if (!cm_node || !cm_core) 903 + return -EINVAL; 904 + 905 + nes_debug(NES_DBG_CM, "Adding Node to Active Connection HT\n"); 906 + 907 + /* first, make an index into our hash table */ 908 + hashkey = make_hashkey(cm_node->loc_port, cm_node->loc_addr, 909 + cm_node->rem_port, cm_node->rem_addr); 910 + cm_node->hashkey = hashkey; 911 + 912 + spin_lock_irqsave(&cm_core->ht_lock, flags); 913 + 914 + /* get a handle on the hash table element (list head for this slot) */ 915 + hte = &cm_core->connected_nodes; 916 + list_add_tail(&cm_node->list, hte); 917 + atomic_inc(&cm_core->ht_node_cnt); 918 + 919 + spin_unlock_irqrestore(&cm_core->ht_lock, flags); 920 + 921 + return 0; 922 + } 923 + 924 + 925 + /** 926 + * mini_cm_dec_refcnt_listen 927 + */ 928 + static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core, 929 + struct nes_cm_listener *listener, int free_hanging_nodes) 930 + { 931 + int ret = 1; 932 + unsigned long flags; 933 + spin_lock_irqsave(&cm_core->listen_list_lock, flags); 934 + if (!atomic_dec_return(&listener->ref_count)) { 935 + list_del(&listener->list); 936 + 937 + /* decrement our listen node count */ 938 + atomic_dec(&cm_core->listen_node_cnt); 939 + 940 + spin_unlock_irqrestore(&cm_core->listen_list_lock, flags); 941 + 942 + if (listener->nesvnic) { 943 + nes_manage_apbvt(listener->nesvnic, listener->loc_port, 944 + PCI_FUNC(listener->nesvnic->nesdev->pcidev->devfn), NES_MANAGE_APBVT_DEL); 945 + } 946 + 947 + nes_debug(NES_DBG_CM, "destroying listener (%p)\n", listener); 948 + 949 + kfree(listener); 950 + ret = 0; 951 + cm_listens_destroyed++; 952 + } else { 953 + spin_unlock_irqrestore(&cm_core->listen_list_lock, flags); 954 + } 955 + if (listener) { 956 + if (atomic_read(&listener->pend_accepts_cnt) > 0) 957 + nes_debug(NES_DBG_CM, "destroying listener (%p)" 958 + " with non-zero pending accepts=%u\n", 959 + listener, atomic_read(&listener->pend_accepts_cnt)); 960 + } 961 + 962 + return ret; 963 + } 964 + 965 + 966 + /** 967 + * mini_cm_del_listen 968 + */ 969 + static int mini_cm_del_listen(struct nes_cm_core *cm_core, 970 + struct nes_cm_listener *listener) 971 + { 972 + listener->listener_state = NES_CM_LISTENER_PASSIVE_STATE; 973 + listener->cm_id = NULL; /* going to be destroyed pretty soon */ 974 + return mini_cm_dec_refcnt_listen(cm_core, listener, 1); 975 + } 976 + 977 + 978 + /** 979 + * mini_cm_accelerated 980 + */ 981 + static inline int mini_cm_accelerated(struct nes_cm_core *cm_core, 982 + struct nes_cm_node *cm_node) 983 + { 984 + u32 was_timer_set; 985 + cm_node->accelerated = 1; 986 + 987 + if (cm_node->accept_pend) { 988 + BUG_ON(!cm_node->listener); 989 + atomic_dec(&cm_node->listener->pend_accepts_cnt); 990 + BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0); 991 + } 992 + 993 + was_timer_set = timer_pending(&cm_core->tcp_timer); 994 + if (!was_timer_set) { 995 + cm_core->tcp_timer.expires = jiffies + NES_SHORT_TIME; 996 + add_timer(&cm_core->tcp_timer); 997 + } 998 + 999 + return 0; 1000 + } 1001 + 1002 + 1003 + /** 1004 + * nes_addr_send_arp 1005 + */ 1006 + static void nes_addr_send_arp(u32 dst_ip) 1007 + { 1008 + struct rtable *rt; 1009 + struct flowi fl; 1010 + 1011 + memset(&fl, 0, sizeof fl); 1012 + fl.nl_u.ip4_u.daddr = htonl(dst_ip); 1013 + if (ip_route_output_key(&init_net, &rt, &fl)) { 1014 + printk("%s: ip_route_output_key failed for 0x%08X\n", 1015 + __FUNCTION__, dst_ip); 1016 + return; 1017 + } 1018 + 1019 + neigh_event_send(rt->u.dst.neighbour, NULL); 1020 + ip_rt_put(rt); 1021 + } 1022 + 1023 + 1024 + /** 1025 + * make_cm_node - create a new instance of a cm node 1026 + */ 1027 + static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core, 1028 + struct nes_vnic *nesvnic, struct nes_cm_info *cm_info, 1029 + struct nes_cm_listener *listener) 1030 + { 1031 + struct nes_cm_node *cm_node; 1032 + struct timespec ts; 1033 + int arpindex = 0; 1034 + struct nes_device *nesdev; 1035 + struct nes_adapter *nesadapter; 1036 + 1037 + /* create an hte and cm_node for this instance */ 1038 + cm_node = kzalloc(sizeof(*cm_node), GFP_ATOMIC); 1039 + if (!cm_node) 1040 + return NULL; 1041 + 1042 + /* set our node specific transport info */ 1043 + cm_node->loc_addr = cm_info->loc_addr; 1044 + cm_node->rem_addr = cm_info->rem_addr; 1045 + cm_node->loc_port = cm_info->loc_port; 1046 + cm_node->rem_port = cm_info->rem_port; 1047 + cm_node->send_write0 = send_first; 1048 + nes_debug(NES_DBG_CM, "Make node addresses : loc = %x:%x, rem = %x:%x\n", 1049 + cm_node->loc_addr, cm_node->loc_port, cm_node->rem_addr, cm_node->rem_port); 1050 + cm_node->listener = listener; 1051 + cm_node->netdev = nesvnic->netdev; 1052 + cm_node->cm_id = cm_info->cm_id; 1053 + memcpy(cm_node->loc_mac, nesvnic->netdev->dev_addr, ETH_ALEN); 1054 + 1055 + nes_debug(NES_DBG_CM, "listener=%p, cm_id=%p\n", 1056 + cm_node->listener, cm_node->cm_id); 1057 + 1058 + INIT_LIST_HEAD(&cm_node->retrans_list); 1059 + spin_lock_init(&cm_node->retrans_list_lock); 1060 + INIT_LIST_HEAD(&cm_node->recv_list); 1061 + spin_lock_init(&cm_node->recv_list_lock); 1062 + 1063 + cm_node->loopbackpartner = NULL; 1064 + atomic_set(&cm_node->ref_count, 1); 1065 + /* associate our parent CM core */ 1066 + cm_node->cm_core = cm_core; 1067 + cm_node->tcp_cntxt.loc_id = NES_CM_DEF_LOCAL_ID; 1068 + cm_node->tcp_cntxt.rcv_wscale = NES_CM_DEFAULT_RCV_WND_SCALE; 1069 + cm_node->tcp_cntxt.rcv_wnd = NES_CM_DEFAULT_RCV_WND_SCALED >> 1070 + NES_CM_DEFAULT_RCV_WND_SCALE; 1071 + ts = current_kernel_time(); 1072 + cm_node->tcp_cntxt.loc_seq_num = htonl(ts.tv_nsec); 1073 + cm_node->tcp_cntxt.mss = nesvnic->max_frame_size - sizeof(struct iphdr) - 1074 + sizeof(struct tcphdr) - ETH_HLEN; 1075 + cm_node->tcp_cntxt.rcv_nxt = 0; 1076 + /* get a unique session ID , add thread_id to an upcounter to handle race */ 1077 + atomic_inc(&cm_core->node_cnt); 1078 + atomic_inc(&cm_core->session_id); 1079 + cm_node->session_id = (u32)(atomic_read(&cm_core->session_id) + current->tgid); 1080 + cm_node->conn_type = cm_info->conn_type; 1081 + cm_node->apbvt_set = 0; 1082 + cm_node->accept_pend = 0; 1083 + 1084 + cm_node->nesvnic = nesvnic; 1085 + /* get some device handles, for arp lookup */ 1086 + nesdev = nesvnic->nesdev; 1087 + nesadapter = nesdev->nesadapter; 1088 + 1089 + cm_node->loopbackpartner = NULL; 1090 + /* get the mac addr for the remote node */ 1091 + arpindex = nes_arp_table(nesdev, cm_node->rem_addr, NULL, NES_ARP_RESOLVE); 1092 + if (arpindex < 0) { 1093 + kfree(cm_node); 1094 + nes_addr_send_arp(cm_info->rem_addr); 1095 + return NULL; 1096 + } 1097 + 1098 + /* copy the mac addr to node context */ 1099 + memcpy(cm_node->rem_mac, nesadapter->arp_table[arpindex].mac_addr, ETH_ALEN); 1100 + nes_debug(NES_DBG_CM, "Remote mac addr from arp table:%02x," 1101 + " %02x, %02x, %02x, %02x, %02x\n", 1102 + cm_node->rem_mac[0], cm_node->rem_mac[1], 1103 + cm_node->rem_mac[2], cm_node->rem_mac[3], 1104 + cm_node->rem_mac[4], cm_node->rem_mac[5]); 1105 + 1106 + add_hte_node(cm_core, cm_node); 1107 + atomic_inc(&cm_nodes_created); 1108 + 1109 + return cm_node; 1110 + } 1111 + 1112 + 1113 + /** 1114 + * add_ref_cm_node - destroy an instance of a cm node 1115 + */ 1116 + static int add_ref_cm_node(struct nes_cm_node *cm_node) 1117 + { 1118 + atomic_inc(&cm_node->ref_count); 1119 + return 0; 1120 + } 1121 + 1122 + 1123 + /** 1124 + * rem_ref_cm_node - destroy an instance of a cm node 1125 + */ 1126 + static int rem_ref_cm_node(struct nes_cm_core *cm_core, 1127 + struct nes_cm_node *cm_node) 1128 + { 1129 + unsigned long flags, qplockflags; 1130 + struct nes_timer_entry *send_entry; 1131 + struct nes_timer_entry *recv_entry; 1132 + struct iw_cm_id *cm_id; 1133 + struct list_head *list_core, *list_node_temp; 1134 + struct nes_qp *nesqp; 1135 + 1136 + if (!cm_node) 1137 + return -EINVAL; 1138 + 1139 + spin_lock_irqsave(&cm_node->cm_core->ht_lock, flags); 1140 + if (atomic_dec_return(&cm_node->ref_count)) { 1141 + spin_unlock_irqrestore(&cm_node->cm_core->ht_lock, flags); 1142 + return 0; 1143 + } 1144 + list_del(&cm_node->list); 1145 + atomic_dec(&cm_core->ht_node_cnt); 1146 + spin_unlock_irqrestore(&cm_node->cm_core->ht_lock, flags); 1147 + 1148 + /* if the node is destroyed before connection was accelerated */ 1149 + if (!cm_node->accelerated && cm_node->accept_pend) { 1150 + BUG_ON(!cm_node->listener); 1151 + atomic_dec(&cm_node->listener->pend_accepts_cnt); 1152 + BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0); 1153 + } 1154 + 1155 + spin_lock_irqsave(&cm_node->retrans_list_lock, flags); 1156 + list_for_each_safe(list_core, list_node_temp, &cm_node->retrans_list) { 1157 + send_entry = container_of(list_core, struct nes_timer_entry, list); 1158 + list_del(&send_entry->list); 1159 + spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); 1160 + dev_kfree_skb_any(send_entry->skb); 1161 + kfree(send_entry); 1162 + spin_lock_irqsave(&cm_node->retrans_list_lock, flags); 1163 + continue; 1164 + } 1165 + spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); 1166 + 1167 + spin_lock_irqsave(&cm_node->recv_list_lock, flags); 1168 + list_for_each_safe(list_core, list_node_temp, &cm_node->recv_list) { 1169 + recv_entry = container_of(list_core, struct nes_timer_entry, list); 1170 + list_del(&recv_entry->list); 1171 + cm_id = cm_node->cm_id; 1172 + spin_unlock_irqrestore(&cm_node->recv_list_lock, flags); 1173 + if (recv_entry->type == NES_TIMER_TYPE_CLOSE) { 1174 + nesqp = (struct nes_qp *)recv_entry->skb; 1175 + spin_lock_irqsave(&nesqp->lock, qplockflags); 1176 + if (nesqp->cm_id) { 1177 + nes_debug(NES_DBG_CM, "QP%u: cm_id = %p: ****** HIT A NES_TIMER_TYPE_CLOSE" 1178 + " with something to do!!! ******\n", 1179 + nesqp->hwqp.qp_id, cm_id); 1180 + nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED; 1181 + nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT; 1182 + nesqp->ibqp_state = IB_QPS_ERR; 1183 + spin_unlock_irqrestore(&nesqp->lock, qplockflags); 1184 + nes_cm_disconn(nesqp); 1185 + } else { 1186 + spin_unlock_irqrestore(&nesqp->lock, qplockflags); 1187 + nes_debug(NES_DBG_CM, "QP%u: cm_id = %p: ****** HIT A NES_TIMER_TYPE_CLOSE" 1188 + " with nothing to do!!! ******\n", 1189 + nesqp->hwqp.qp_id, cm_id); 1190 + nes_rem_ref(&nesqp->ibqp); 1191 + } 1192 + cm_id->rem_ref(cm_id); 1193 + } else if (recv_entry->type == NES_TIMER_TYPE_RECV) { 1194 + dev_kfree_skb_any(recv_entry->skb); 1195 + } 1196 + kfree(recv_entry); 1197 + spin_lock_irqsave(&cm_node->recv_list_lock, flags); 1198 + } 1199 + spin_unlock_irqrestore(&cm_node->recv_list_lock, flags); 1200 + 1201 + if (cm_node->listener) { 1202 + mini_cm_dec_refcnt_listen(cm_core, cm_node->listener, 0); 1203 + } else { 1204 + if (cm_node->apbvt_set && cm_node->nesvnic) { 1205 + nes_manage_apbvt(cm_node->nesvnic, cm_node->loc_port, 1206 + PCI_FUNC(cm_node->nesvnic->nesdev->pcidev->devfn), 1207 + NES_MANAGE_APBVT_DEL); 1208 + } 1209 + } 1210 + 1211 + kfree(cm_node); 1212 + atomic_dec(&cm_core->node_cnt); 1213 + atomic_inc(&cm_nodes_destroyed); 1214 + 1215 + return 0; 1216 + } 1217 + 1218 + 1219 + /** 1220 + * process_options 1221 + */ 1222 + static int process_options(struct nes_cm_node *cm_node, u8 *optionsloc, u32 optionsize, u32 syn_packet) 1223 + { 1224 + u32 tmp; 1225 + u32 offset = 0; 1226 + union all_known_options *all_options; 1227 + char got_mss_option = 0; 1228 + 1229 + while (offset < optionsize) { 1230 + all_options = (union all_known_options *)(optionsloc + offset); 1231 + switch (all_options->as_base.optionnum) { 1232 + case OPTION_NUMBER_END: 1233 + offset = optionsize; 1234 + break; 1235 + case OPTION_NUMBER_NONE: 1236 + offset += 1; 1237 + continue; 1238 + case OPTION_NUMBER_MSS: 1239 + nes_debug(NES_DBG_CM, "%s: MSS Length: %d Offset: %d Size: %d\n", 1240 + __FUNCTION__, 1241 + all_options->as_mss.length, offset, optionsize); 1242 + got_mss_option = 1; 1243 + if (all_options->as_mss.length != 4) { 1244 + return 1; 1245 + } else { 1246 + tmp = ntohs(all_options->as_mss.mss); 1247 + if (tmp > 0 && tmp < cm_node->tcp_cntxt.mss) 1248 + cm_node->tcp_cntxt.mss = tmp; 1249 + } 1250 + break; 1251 + case OPTION_NUMBER_WINDOW_SCALE: 1252 + cm_node->tcp_cntxt.snd_wscale = all_options->as_windowscale.shiftcount; 1253 + break; 1254 + case OPTION_NUMBER_WRITE0: 1255 + cm_node->send_write0 = 1; 1256 + break; 1257 + default: 1258 + nes_debug(NES_DBG_CM, "TCP Option not understood: %x\n", 1259 + all_options->as_base.optionnum); 1260 + break; 1261 + } 1262 + offset += all_options->as_base.length; 1263 + } 1264 + if ((!got_mss_option) && (syn_packet)) 1265 + cm_node->tcp_cntxt.mss = NES_CM_DEFAULT_MSS; 1266 + return 0; 1267 + } 1268 + 1269 + 1270 + /** 1271 + * process_packet 1272 + */ 1273 + int process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb, 1274 + struct nes_cm_core *cm_core) 1275 + { 1276 + int optionsize; 1277 + int datasize; 1278 + int ret = 0; 1279 + struct tcphdr *tcph = tcp_hdr(skb); 1280 + u32 inc_sequence; 1281 + if (cm_node->state == NES_CM_STATE_SYN_SENT && tcph->syn) { 1282 + inc_sequence = ntohl(tcph->seq); 1283 + cm_node->tcp_cntxt.rcv_nxt = inc_sequence; 1284 + } 1285 + 1286 + if ((!tcph) || (cm_node->state == NES_CM_STATE_TSA)) { 1287 + BUG_ON(!tcph); 1288 + atomic_inc(&cm_accel_dropped_pkts); 1289 + return -1; 1290 + } 1291 + 1292 + if (tcph->rst) { 1293 + atomic_inc(&cm_resets_recvd); 1294 + nes_debug(NES_DBG_CM, "Received Reset, cm_node = %p, state = %u. refcnt=%d\n", 1295 + cm_node, cm_node->state, atomic_read(&cm_node->ref_count)); 1296 + switch (cm_node->state) { 1297 + case NES_CM_STATE_LISTENING: 1298 + rem_ref_cm_node(cm_core, cm_node); 1299 + break; 1300 + case NES_CM_STATE_TSA: 1301 + case NES_CM_STATE_CLOSED: 1302 + break; 1303 + case NES_CM_STATE_SYN_RCVD: 1304 + nes_debug(NES_DBG_CM, "Received a reset for local 0x%08X:%04X," 1305 + " remote 0x%08X:%04X, node state = %u\n", 1306 + cm_node->loc_addr, cm_node->loc_port, 1307 + cm_node->rem_addr, cm_node->rem_port, 1308 + cm_node->state); 1309 + rem_ref_cm_node(cm_core, cm_node); 1310 + break; 1311 + case NES_CM_STATE_ONE_SIDE_ESTABLISHED: 1312 + case NES_CM_STATE_ESTABLISHED: 1313 + case NES_CM_STATE_MPAREQ_SENT: 1314 + default: 1315 + nes_debug(NES_DBG_CM, "Received a reset for local 0x%08X:%04X," 1316 + " remote 0x%08X:%04X, node state = %u refcnt=%d\n", 1317 + cm_node->loc_addr, cm_node->loc_port, 1318 + cm_node->rem_addr, cm_node->rem_port, 1319 + cm_node->state, atomic_read(&cm_node->ref_count)); 1320 + // create event 1321 + cm_node->state = NES_CM_STATE_CLOSED; 1322 + 1323 + create_event(cm_node, NES_CM_EVENT_ABORTED); 1324 + break; 1325 + 1326 + } 1327 + return -1; 1328 + } 1329 + 1330 + optionsize = (tcph->doff << 2) - sizeof(struct tcphdr); 1331 + 1332 + skb_pull(skb, ip_hdr(skb)->ihl << 2); 1333 + skb_pull(skb, tcph->doff << 2); 1334 + 1335 + datasize = skb->len; 1336 + inc_sequence = ntohl(tcph->seq); 1337 + nes_debug(NES_DBG_CM, "datasize = %u, sequence = 0x%08X, ack_seq = 0x%08X," 1338 + " rcv_nxt = 0x%08X Flags: %s %s.\n", 1339 + datasize, inc_sequence, ntohl(tcph->ack_seq), 1340 + cm_node->tcp_cntxt.rcv_nxt, (tcph->syn ? "SYN":""), 1341 + (tcph->ack ? "ACK":"")); 1342 + 1343 + if (!tcph->syn && (inc_sequence != cm_node->tcp_cntxt.rcv_nxt) 1344 + ) { 1345 + nes_debug(NES_DBG_CM, "dropping packet, datasize = %u, sequence = 0x%08X," 1346 + " ack_seq = 0x%08X, rcv_nxt = 0x%08X Flags: %s.\n", 1347 + datasize, inc_sequence, ntohl(tcph->ack_seq), 1348 + cm_node->tcp_cntxt.rcv_nxt, (tcph->ack ? "ACK":"")); 1349 + if (cm_node->state == NES_CM_STATE_LISTENING) { 1350 + rem_ref_cm_node(cm_core, cm_node); 1351 + } 1352 + return -1; 1353 + } 1354 + 1355 + cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize; 1356 + 1357 + 1358 + if (optionsize) { 1359 + u8 *optionsloc = (u8 *)&tcph[1]; 1360 + if (process_options(cm_node, optionsloc, optionsize, (u32)tcph->syn)) { 1361 + nes_debug(NES_DBG_CM, "%s: Node %p, Sending RESET\n", __FUNCTION__, cm_node); 1362 + send_reset(cm_node); 1363 + if (cm_node->state != NES_CM_STATE_SYN_SENT) 1364 + rem_ref_cm_node(cm_core, cm_node); 1365 + return 0; 1366 + } 1367 + } else if (tcph->syn) 1368 + cm_node->tcp_cntxt.mss = NES_CM_DEFAULT_MSS; 1369 + 1370 + cm_node->tcp_cntxt.snd_wnd = ntohs(tcph->window) << 1371 + cm_node->tcp_cntxt.snd_wscale; 1372 + 1373 + if (cm_node->tcp_cntxt.snd_wnd > cm_node->tcp_cntxt.max_snd_wnd) { 1374 + cm_node->tcp_cntxt.max_snd_wnd = cm_node->tcp_cntxt.snd_wnd; 1375 + } 1376 + 1377 + if (tcph->ack) { 1378 + cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq); 1379 + switch (cm_node->state) { 1380 + case NES_CM_STATE_SYN_RCVD: 1381 + case NES_CM_STATE_SYN_SENT: 1382 + /* read and stash current sequence number */ 1383 + if (cm_node->tcp_cntxt.rem_ack_num != cm_node->tcp_cntxt.loc_seq_num) { 1384 + nes_debug(NES_DBG_CM, "ERROR - cm_node->tcp_cntxt.rem_ack_num !=" 1385 + " cm_node->tcp_cntxt.loc_seq_num\n"); 1386 + send_reset(cm_node); 1387 + return 0; 1388 + } 1389 + if (cm_node->state == NES_CM_STATE_SYN_SENT) 1390 + cm_node->state = NES_CM_STATE_ONE_SIDE_ESTABLISHED; 1391 + else { 1392 + cm_node->state = NES_CM_STATE_ESTABLISHED; 1393 + } 1394 + break; 1395 + case NES_CM_STATE_LAST_ACK: 1396 + cm_node->state = NES_CM_STATE_CLOSED; 1397 + break; 1398 + case NES_CM_STATE_FIN_WAIT1: 1399 + cm_node->state = NES_CM_STATE_FIN_WAIT2; 1400 + break; 1401 + case NES_CM_STATE_CLOSING: 1402 + cm_node->state = NES_CM_STATE_TIME_WAIT; 1403 + /* need to schedule this to happen in 2MSL timeouts */ 1404 + cm_node->state = NES_CM_STATE_CLOSED; 1405 + break; 1406 + case NES_CM_STATE_ONE_SIDE_ESTABLISHED: 1407 + case NES_CM_STATE_ESTABLISHED: 1408 + case NES_CM_STATE_MPAREQ_SENT: 1409 + case NES_CM_STATE_CLOSE_WAIT: 1410 + case NES_CM_STATE_TIME_WAIT: 1411 + case NES_CM_STATE_CLOSED: 1412 + break; 1413 + case NES_CM_STATE_LISTENING: 1414 + nes_debug(NES_DBG_CM, "Received an ACK on a listening port (SYN %d)\n", tcph->syn); 1415 + cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq); 1416 + send_reset(cm_node); 1417 + /* send_reset bumps refcount, this should have been a new node */ 1418 + rem_ref_cm_node(cm_core, cm_node); 1419 + return -1; 1420 + break; 1421 + case NES_CM_STATE_TSA: 1422 + nes_debug(NES_DBG_CM, "Received a packet with the ack bit set while in TSA state\n"); 1423 + break; 1424 + case NES_CM_STATE_UNKNOWN: 1425 + case NES_CM_STATE_INITED: 1426 + case NES_CM_STATE_ACCEPTING: 1427 + case NES_CM_STATE_FIN_WAIT2: 1428 + default: 1429 + nes_debug(NES_DBG_CM, "Received ack from unknown state: %x\n", 1430 + cm_node->state); 1431 + send_reset(cm_node); 1432 + break; 1433 + } 1434 + } 1435 + 1436 + if (tcph->syn) { 1437 + if (cm_node->state == NES_CM_STATE_LISTENING) { 1438 + /* do not exceed backlog */ 1439 + atomic_inc(&cm_node->listener->pend_accepts_cnt); 1440 + if (atomic_read(&cm_node->listener->pend_accepts_cnt) > 1441 + cm_node->listener->backlog) { 1442 + nes_debug(NES_DBG_CM, "drop syn due to backlog pressure \n"); 1443 + cm_backlog_drops++; 1444 + atomic_dec(&cm_node->listener->pend_accepts_cnt); 1445 + rem_ref_cm_node(cm_core, cm_node); 1446 + return 0; 1447 + } 1448 + cm_node->accept_pend = 1; 1449 + 1450 + } 1451 + if (datasize == 0) 1452 + cm_node->tcp_cntxt.rcv_nxt ++; 1453 + 1454 + if (cm_node->state == NES_CM_STATE_LISTENING) { 1455 + cm_node->state = NES_CM_STATE_SYN_RCVD; 1456 + send_syn(cm_node, 1); 1457 + } 1458 + if (cm_node->state == NES_CM_STATE_ONE_SIDE_ESTABLISHED) { 1459 + cm_node->state = NES_CM_STATE_ESTABLISHED; 1460 + /* send final handshake ACK */ 1461 + ret = send_ack(cm_node); 1462 + if (ret < 0) 1463 + return ret; 1464 + 1465 + cm_node->state = NES_CM_STATE_MPAREQ_SENT; 1466 + ret = send_mpa_request(cm_node); 1467 + if (ret < 0) 1468 + return ret; 1469 + } 1470 + } 1471 + 1472 + if (tcph->fin) { 1473 + cm_node->tcp_cntxt.rcv_nxt++; 1474 + switch (cm_node->state) { 1475 + case NES_CM_STATE_SYN_RCVD: 1476 + case NES_CM_STATE_SYN_SENT: 1477 + case NES_CM_STATE_ONE_SIDE_ESTABLISHED: 1478 + case NES_CM_STATE_ESTABLISHED: 1479 + case NES_CM_STATE_ACCEPTING: 1480 + case NES_CM_STATE_MPAREQ_SENT: 1481 + cm_node->state = NES_CM_STATE_CLOSE_WAIT; 1482 + cm_node->state = NES_CM_STATE_LAST_ACK; 1483 + ret = send_fin(cm_node, NULL); 1484 + break; 1485 + case NES_CM_STATE_FIN_WAIT1: 1486 + cm_node->state = NES_CM_STATE_CLOSING; 1487 + ret = send_ack(cm_node); 1488 + break; 1489 + case NES_CM_STATE_FIN_WAIT2: 1490 + cm_node->state = NES_CM_STATE_TIME_WAIT; 1491 + cm_node->tcp_cntxt.loc_seq_num ++; 1492 + ret = send_ack(cm_node); 1493 + /* need to schedule this to happen in 2MSL timeouts */ 1494 + cm_node->state = NES_CM_STATE_CLOSED; 1495 + break; 1496 + case NES_CM_STATE_CLOSE_WAIT: 1497 + case NES_CM_STATE_LAST_ACK: 1498 + case NES_CM_STATE_CLOSING: 1499 + case NES_CM_STATE_TSA: 1500 + default: 1501 + nes_debug(NES_DBG_CM, "Received a fin while in %x state\n", 1502 + cm_node->state); 1503 + ret = -EINVAL; 1504 + break; 1505 + } 1506 + } 1507 + 1508 + if (datasize) { 1509 + u8 *dataloc = skb->data; 1510 + /* figure out what state we are in and handle transition to next state */ 1511 + switch (cm_node->state) { 1512 + case NES_CM_STATE_LISTENING: 1513 + case NES_CM_STATE_SYN_RCVD: 1514 + case NES_CM_STATE_SYN_SENT: 1515 + case NES_CM_STATE_FIN_WAIT1: 1516 + case NES_CM_STATE_FIN_WAIT2: 1517 + case NES_CM_STATE_CLOSE_WAIT: 1518 + case NES_CM_STATE_LAST_ACK: 1519 + case NES_CM_STATE_CLOSING: 1520 + break; 1521 + case NES_CM_STATE_MPAREQ_SENT: 1522 + /* recv the mpa res frame, ret=frame len (incl priv data) */ 1523 + ret = parse_mpa(cm_node, dataloc, datasize); 1524 + if (ret < 0) 1525 + break; 1526 + /* set the req frame payload len in skb */ 1527 + /* we are done handling this state, set node to a TSA state */ 1528 + cm_node->state = NES_CM_STATE_TSA; 1529 + send_ack(cm_node); 1530 + create_event(cm_node, NES_CM_EVENT_CONNECTED); 1531 + break; 1532 + 1533 + case NES_CM_STATE_ESTABLISHED: 1534 + /* we are expecting an MPA req frame */ 1535 + ret = parse_mpa(cm_node, dataloc, datasize); 1536 + if (ret < 0) { 1537 + break; 1538 + } 1539 + cm_node->state = NES_CM_STATE_TSA; 1540 + send_ack(cm_node); 1541 + /* we got a valid MPA request, create an event */ 1542 + create_event(cm_node, NES_CM_EVENT_MPA_REQ); 1543 + break; 1544 + case NES_CM_STATE_TSA: 1545 + handle_exception_pkt(cm_node, skb); 1546 + break; 1547 + case NES_CM_STATE_UNKNOWN: 1548 + case NES_CM_STATE_INITED: 1549 + default: 1550 + ret = -1; 1551 + } 1552 + } 1553 + 1554 + return ret; 1555 + } 1556 + 1557 + 1558 + /** 1559 + * mini_cm_listen - create a listen node with params 1560 + */ 1561 + static struct nes_cm_listener *mini_cm_listen(struct nes_cm_core *cm_core, 1562 + struct nes_vnic *nesvnic, struct nes_cm_info *cm_info) 1563 + { 1564 + struct nes_cm_listener *listener; 1565 + unsigned long flags; 1566 + 1567 + nes_debug(NES_DBG_CM, "Search for 0x%08x : 0x%04x\n", 1568 + cm_info->loc_addr, cm_info->loc_port); 1569 + 1570 + /* cannot have multiple matching listeners */ 1571 + listener = find_listener(cm_core, htonl(cm_info->loc_addr), 1572 + htons(cm_info->loc_port), NES_CM_LISTENER_EITHER_STATE); 1573 + if (listener && listener->listener_state == NES_CM_LISTENER_ACTIVE_STATE) { 1574 + /* find automatically incs ref count ??? */ 1575 + atomic_dec(&listener->ref_count); 1576 + nes_debug(NES_DBG_CM, "Not creating listener since it already exists\n"); 1577 + return NULL; 1578 + } 1579 + 1580 + if (!listener) { 1581 + /* create a CM listen node (1/2 node to compare incoming traffic to) */ 1582 + listener = kzalloc(sizeof(*listener), GFP_ATOMIC); 1583 + if (!listener) { 1584 + nes_debug(NES_DBG_CM, "Not creating listener memory allocation failed\n"); 1585 + return NULL; 1586 + } 1587 + 1588 + memset(listener, 0, sizeof(struct nes_cm_listener)); 1589 + listener->loc_addr = htonl(cm_info->loc_addr); 1590 + listener->loc_port = htons(cm_info->loc_port); 1591 + listener->reused_node = 0; 1592 + 1593 + atomic_set(&listener->ref_count, 1); 1594 + } 1595 + /* pasive case */ 1596 + /* find already inc'ed the ref count */ 1597 + else { 1598 + listener->reused_node = 1; 1599 + } 1600 + 1601 + listener->cm_id = cm_info->cm_id; 1602 + atomic_set(&listener->pend_accepts_cnt, 0); 1603 + listener->cm_core = cm_core; 1604 + listener->nesvnic = nesvnic; 1605 + atomic_inc(&cm_core->node_cnt); 1606 + atomic_inc(&cm_core->session_id); 1607 + 1608 + listener->session_id = (u32)(atomic_read(&cm_core->session_id) + current->tgid); 1609 + listener->conn_type = cm_info->conn_type; 1610 + listener->backlog = cm_info->backlog; 1611 + listener->listener_state = NES_CM_LISTENER_ACTIVE_STATE; 1612 + 1613 + if (!listener->reused_node) { 1614 + spin_lock_irqsave(&cm_core->listen_list_lock, flags); 1615 + list_add(&listener->list, &cm_core->listen_list.list); 1616 + spin_unlock_irqrestore(&cm_core->listen_list_lock, flags); 1617 + atomic_inc(&cm_core->listen_node_cnt); 1618 + } 1619 + 1620 + nes_debug(NES_DBG_CM, "Api - listen(): addr=0x%08X, port=0x%04x," 1621 + " listener = %p, backlog = %d, cm_id = %p.\n", 1622 + cm_info->loc_addr, cm_info->loc_port, 1623 + listener, listener->backlog, listener->cm_id); 1624 + 1625 + return listener; 1626 + } 1627 + 1628 + 1629 + /** 1630 + * mini_cm_connect - make a connection node with params 1631 + */ 1632 + struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core, 1633 + struct nes_vnic *nesvnic, struct ietf_mpa_frame *mpa_frame, 1634 + struct nes_cm_info *cm_info) 1635 + { 1636 + int ret = 0; 1637 + struct nes_cm_node *cm_node; 1638 + struct nes_cm_listener *loopbackremotelistener; 1639 + struct nes_cm_node *loopbackremotenode; 1640 + struct nes_cm_info loopback_cm_info; 1641 + 1642 + u16 mpa_frame_size = sizeof(struct ietf_mpa_frame) + 1643 + ntohs(mpa_frame->priv_data_len); 1644 + 1645 + cm_info->loc_addr = htonl(cm_info->loc_addr); 1646 + cm_info->rem_addr = htonl(cm_info->rem_addr); 1647 + cm_info->loc_port = htons(cm_info->loc_port); 1648 + cm_info->rem_port = htons(cm_info->rem_port); 1649 + 1650 + /* create a CM connection node */ 1651 + cm_node = make_cm_node(cm_core, nesvnic, cm_info, NULL); 1652 + if (!cm_node) 1653 + return NULL; 1654 + 1655 + // set our node side to client (active) side 1656 + cm_node->tcp_cntxt.client = 1; 1657 + cm_node->tcp_cntxt.rcv_wscale = NES_CM_DEFAULT_RCV_WND_SCALE; 1658 + 1659 + if (cm_info->loc_addr == cm_info->rem_addr) { 1660 + loopbackremotelistener = find_listener(cm_core, cm_node->rem_addr, 1661 + cm_node->rem_port, NES_CM_LISTENER_ACTIVE_STATE); 1662 + if (loopbackremotelistener == NULL) { 1663 + create_event(cm_node, NES_CM_EVENT_ABORTED); 1664 + } else { 1665 + atomic_inc(&cm_loopbacks); 1666 + loopback_cm_info = *cm_info; 1667 + loopback_cm_info.loc_port = cm_info->rem_port; 1668 + loopback_cm_info.rem_port = cm_info->loc_port; 1669 + loopback_cm_info.cm_id = loopbackremotelistener->cm_id; 1670 + loopbackremotenode = make_cm_node(cm_core, nesvnic, &loopback_cm_info, 1671 + loopbackremotelistener); 1672 + loopbackremotenode->loopbackpartner = cm_node; 1673 + loopbackremotenode->tcp_cntxt.rcv_wscale = NES_CM_DEFAULT_RCV_WND_SCALE; 1674 + cm_node->loopbackpartner = loopbackremotenode; 1675 + memcpy(loopbackremotenode->mpa_frame_buf, &mpa_frame->priv_data, 1676 + mpa_frame_size); 1677 + loopbackremotenode->mpa_frame_size = mpa_frame_size - 1678 + sizeof(struct ietf_mpa_frame); 1679 + 1680 + // we are done handling this state, set node to a TSA state 1681 + cm_node->state = NES_CM_STATE_TSA; 1682 + cm_node->tcp_cntxt.rcv_nxt = loopbackremotenode->tcp_cntxt.loc_seq_num; 1683 + loopbackremotenode->tcp_cntxt.rcv_nxt = cm_node->tcp_cntxt.loc_seq_num; 1684 + cm_node->tcp_cntxt.max_snd_wnd = loopbackremotenode->tcp_cntxt.rcv_wnd; 1685 + loopbackremotenode->tcp_cntxt.max_snd_wnd = cm_node->tcp_cntxt.rcv_wnd; 1686 + cm_node->tcp_cntxt.snd_wnd = loopbackremotenode->tcp_cntxt.rcv_wnd; 1687 + loopbackremotenode->tcp_cntxt.snd_wnd = cm_node->tcp_cntxt.rcv_wnd; 1688 + cm_node->tcp_cntxt.snd_wscale = loopbackremotenode->tcp_cntxt.rcv_wscale; 1689 + loopbackremotenode->tcp_cntxt.snd_wscale = cm_node->tcp_cntxt.rcv_wscale; 1690 + 1691 + create_event(loopbackremotenode, NES_CM_EVENT_MPA_REQ); 1692 + } 1693 + return cm_node; 1694 + } 1695 + 1696 + /* set our node side to client (active) side */ 1697 + cm_node->tcp_cntxt.client = 1; 1698 + /* init our MPA frame ptr */ 1699 + memcpy(&cm_node->mpa_frame, mpa_frame, mpa_frame_size); 1700 + cm_node->mpa_frame_size = mpa_frame_size; 1701 + 1702 + /* send a syn and goto syn sent state */ 1703 + cm_node->state = NES_CM_STATE_SYN_SENT; 1704 + ret = send_syn(cm_node, 0); 1705 + 1706 + nes_debug(NES_DBG_CM, "Api - connect(): dest addr=0x%08X, port=0x%04x," 1707 + " cm_node=%p, cm_id = %p.\n", 1708 + cm_node->rem_addr, cm_node->rem_port, cm_node, cm_node->cm_id); 1709 + 1710 + return cm_node; 1711 + } 1712 + 1713 + 1714 + /** 1715 + * mini_cm_accept - accept a connection 1716 + * This function is never called 1717 + */ 1718 + int mini_cm_accept(struct nes_cm_core *cm_core, struct ietf_mpa_frame *mpa_frame, 1719 + struct nes_cm_node *cm_node) 1720 + { 1721 + return 0; 1722 + } 1723 + 1724 + 1725 + /** 1726 + * mini_cm_reject - reject and teardown a connection 1727 + */ 1728 + int mini_cm_reject(struct nes_cm_core *cm_core, 1729 + struct ietf_mpa_frame *mpa_frame, 1730 + struct nes_cm_node *cm_node) 1731 + { 1732 + int ret = 0; 1733 + struct sk_buff *skb; 1734 + u16 mpa_frame_size = sizeof(struct ietf_mpa_frame) + 1735 + ntohs(mpa_frame->priv_data_len); 1736 + 1737 + skb = get_free_pkt(cm_node); 1738 + if (!skb) { 1739 + nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n"); 1740 + return -1; 1741 + } 1742 + 1743 + /* send an MPA Request frame */ 1744 + form_cm_frame(skb, cm_node, NULL, 0, mpa_frame, mpa_frame_size, SET_ACK | SET_FIN); 1745 + ret = schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 1, 0); 1746 + 1747 + cm_node->state = NES_CM_STATE_CLOSED; 1748 + ret = send_fin(cm_node, NULL); 1749 + 1750 + if (ret < 0) { 1751 + printk(KERN_INFO PFX "failed to send MPA Reply (reject)\n"); 1752 + return ret; 1753 + } 1754 + 1755 + return ret; 1756 + } 1757 + 1758 + 1759 + /** 1760 + * mini_cm_close 1761 + */ 1762 + int mini_cm_close(struct nes_cm_core *cm_core, struct nes_cm_node *cm_node) 1763 + { 1764 + int ret = 0; 1765 + 1766 + if (!cm_core || !cm_node) 1767 + return -EINVAL; 1768 + 1769 + switch (cm_node->state) { 1770 + /* if passed in node is null, create a reference key node for node search */ 1771 + /* check if we found an owner node for this pkt */ 1772 + case NES_CM_STATE_SYN_RCVD: 1773 + case NES_CM_STATE_SYN_SENT: 1774 + case NES_CM_STATE_ONE_SIDE_ESTABLISHED: 1775 + case NES_CM_STATE_ESTABLISHED: 1776 + case NES_CM_STATE_ACCEPTING: 1777 + case NES_CM_STATE_MPAREQ_SENT: 1778 + cm_node->state = NES_CM_STATE_FIN_WAIT1; 1779 + send_fin(cm_node, NULL); 1780 + break; 1781 + case NES_CM_STATE_CLOSE_WAIT: 1782 + cm_node->state = NES_CM_STATE_LAST_ACK; 1783 + send_fin(cm_node, NULL); 1784 + break; 1785 + case NES_CM_STATE_FIN_WAIT1: 1786 + case NES_CM_STATE_FIN_WAIT2: 1787 + case NES_CM_STATE_LAST_ACK: 1788 + case NES_CM_STATE_TIME_WAIT: 1789 + case NES_CM_STATE_CLOSING: 1790 + ret = -1; 1791 + break; 1792 + case NES_CM_STATE_LISTENING: 1793 + case NES_CM_STATE_UNKNOWN: 1794 + case NES_CM_STATE_INITED: 1795 + case NES_CM_STATE_CLOSED: 1796 + case NES_CM_STATE_TSA: 1797 + ret = rem_ref_cm_node(cm_core, cm_node); 1798 + break; 1799 + } 1800 + cm_node->cm_id = NULL; 1801 + return ret; 1802 + } 1803 + 1804 + 1805 + /** 1806 + * recv_pkt - recv an ETHERNET packet, and process it through CM 1807 + * node state machine 1808 + */ 1809 + int mini_cm_recv_pkt(struct nes_cm_core *cm_core, struct nes_vnic *nesvnic, 1810 + struct sk_buff *skb) 1811 + { 1812 + struct nes_cm_node *cm_node = NULL; 1813 + struct nes_cm_listener *listener = NULL; 1814 + struct iphdr *iph; 1815 + struct tcphdr *tcph; 1816 + struct nes_cm_info nfo; 1817 + int ret = 0; 1818 + 1819 + if (!skb || skb->len < sizeof(struct iphdr) + sizeof(struct tcphdr)) { 1820 + ret = -EINVAL; 1821 + goto out; 1822 + } 1823 + 1824 + iph = (struct iphdr *)skb->data; 1825 + tcph = (struct tcphdr *)(skb->data + sizeof(struct iphdr)); 1826 + skb_reset_network_header(skb); 1827 + skb_set_transport_header(skb, sizeof(*tcph)); 1828 + skb->len = ntohs(iph->tot_len); 1829 + 1830 + nfo.loc_addr = ntohl(iph->daddr); 1831 + nfo.loc_port = ntohs(tcph->dest); 1832 + nfo.rem_addr = ntohl(iph->saddr); 1833 + nfo.rem_port = ntohs(tcph->source); 1834 + 1835 + nes_debug(NES_DBG_CM, "Received packet: dest=0x%08X:0x%04X src=0x%08X:0x%04X\n", 1836 + iph->daddr, tcph->dest, iph->saddr, tcph->source); 1837 + 1838 + /* note: this call is going to increment cm_node ref count */ 1839 + cm_node = find_node(cm_core, 1840 + nfo.rem_port, nfo.rem_addr, 1841 + nfo.loc_port, nfo.loc_addr); 1842 + 1843 + if (!cm_node) { 1844 + listener = find_listener(cm_core, nfo.loc_addr, nfo.loc_port, 1845 + NES_CM_LISTENER_ACTIVE_STATE); 1846 + if (listener) { 1847 + nfo.cm_id = listener->cm_id; 1848 + nfo.conn_type = listener->conn_type; 1849 + } else { 1850 + nfo.cm_id = NULL; 1851 + nfo.conn_type = 0; 1852 + } 1853 + 1854 + cm_node = make_cm_node(cm_core, nesvnic, &nfo, listener); 1855 + if (!cm_node) { 1856 + nes_debug(NES_DBG_CM, "Unable to allocate node\n"); 1857 + if (listener) { 1858 + nes_debug(NES_DBG_CM, "unable to allocate node and decrementing listener refcount\n"); 1859 + atomic_dec(&listener->ref_count); 1860 + } 1861 + ret = -1; 1862 + goto out; 1863 + } 1864 + if (!listener) { 1865 + nes_debug(NES_DBG_CM, "Packet found for unknown port %x refcnt=%d\n", 1866 + nfo.loc_port, atomic_read(&cm_node->ref_count)); 1867 + if (!tcph->rst) { 1868 + nes_debug(NES_DBG_CM, "Packet found for unknown port=%d" 1869 + " rem_port=%d refcnt=%d\n", 1870 + nfo.loc_port, nfo.rem_port, atomic_read(&cm_node->ref_count)); 1871 + 1872 + cm_node->tcp_cntxt.rcv_nxt = ntohl(tcph->seq); 1873 + cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq); 1874 + send_reset(cm_node); 1875 + } 1876 + rem_ref_cm_node(cm_core, cm_node); 1877 + ret = -1; 1878 + goto out; 1879 + } 1880 + add_ref_cm_node(cm_node); 1881 + cm_node->state = NES_CM_STATE_LISTENING; 1882 + } 1883 + 1884 + nes_debug(NES_DBG_CM, "Processing Packet for node %p, data = (%p):\n", 1885 + cm_node, skb->data); 1886 + process_packet(cm_node, skb, cm_core); 1887 + 1888 + rem_ref_cm_node(cm_core, cm_node); 1889 + out: 1890 + if (skb) 1891 + dev_kfree_skb_any(skb); 1892 + return ret; 1893 + } 1894 + 1895 + 1896 + /** 1897 + * nes_cm_alloc_core - allocate a top level instance of a cm core 1898 + */ 1899 + struct nes_cm_core *nes_cm_alloc_core(void) 1900 + { 1901 + int i; 1902 + 1903 + struct nes_cm_core *cm_core; 1904 + struct sk_buff *skb = NULL; 1905 + 1906 + /* setup the CM core */ 1907 + /* alloc top level core control structure */ 1908 + cm_core = kzalloc(sizeof(*cm_core), GFP_KERNEL); 1909 + if (!cm_core) 1910 + return NULL; 1911 + 1912 + INIT_LIST_HEAD(&cm_core->connected_nodes); 1913 + init_timer(&cm_core->tcp_timer); 1914 + cm_core->tcp_timer.function = nes_cm_timer_tick; 1915 + 1916 + cm_core->mtu = NES_CM_DEFAULT_MTU; 1917 + cm_core->state = NES_CM_STATE_INITED; 1918 + cm_core->free_tx_pkt_max = NES_CM_DEFAULT_FREE_PKTS; 1919 + 1920 + atomic_set(&cm_core->session_id, 0); 1921 + atomic_set(&cm_core->events_posted, 0); 1922 + 1923 + /* init the packet lists */ 1924 + skb_queue_head_init(&cm_core->tx_free_list); 1925 + 1926 + for (i = 0; i < NES_CM_DEFAULT_FRAME_CNT; i++) { 1927 + skb = dev_alloc_skb(cm_core->mtu); 1928 + if (!skb) { 1929 + kfree(cm_core); 1930 + return NULL; 1931 + } 1932 + /* add 'raw' skb to free frame list */ 1933 + skb_queue_head(&cm_core->tx_free_list, skb); 1934 + } 1935 + 1936 + cm_core->api = &nes_cm_api; 1937 + 1938 + spin_lock_init(&cm_core->ht_lock); 1939 + spin_lock_init(&cm_core->listen_list_lock); 1940 + 1941 + INIT_LIST_HEAD(&cm_core->listen_list.list); 1942 + 1943 + nes_debug(NES_DBG_CM, "Init CM Core completed -- cm_core=%p\n", cm_core); 1944 + 1945 + nes_debug(NES_DBG_CM, "Enable QUEUE EVENTS\n"); 1946 + cm_core->event_wq = create_singlethread_workqueue("nesewq"); 1947 + cm_core->post_event = nes_cm_post_event; 1948 + nes_debug(NES_DBG_CM, "Enable QUEUE DISCONNECTS\n"); 1949 + cm_core->disconn_wq = create_singlethread_workqueue("nesdwq"); 1950 + 1951 + print_core(cm_core); 1952 + return cm_core; 1953 + } 1954 + 1955 + 1956 + /** 1957 + * mini_cm_dealloc_core - deallocate a top level instance of a cm core 1958 + */ 1959 + int mini_cm_dealloc_core(struct nes_cm_core *cm_core) 1960 + { 1961 + nes_debug(NES_DBG_CM, "De-Alloc CM Core (%p)\n", cm_core); 1962 + 1963 + if (!cm_core) 1964 + return -EINVAL; 1965 + 1966 + barrier(); 1967 + 1968 + if (timer_pending(&cm_core->tcp_timer)) { 1969 + del_timer(&cm_core->tcp_timer); 1970 + } 1971 + 1972 + destroy_workqueue(cm_core->event_wq); 1973 + destroy_workqueue(cm_core->disconn_wq); 1974 + nes_debug(NES_DBG_CM, "\n"); 1975 + kfree(cm_core); 1976 + 1977 + return 0; 1978 + } 1979 + 1980 + 1981 + /** 1982 + * mini_cm_get 1983 + */ 1984 + int mini_cm_get(struct nes_cm_core *cm_core) 1985 + { 1986 + return cm_core->state; 1987 + } 1988 + 1989 + 1990 + /** 1991 + * mini_cm_set 1992 + */ 1993 + int mini_cm_set(struct nes_cm_core *cm_core, u32 type, u32 value) 1994 + { 1995 + int ret = 0; 1996 + 1997 + switch (type) { 1998 + case NES_CM_SET_PKT_SIZE: 1999 + cm_core->mtu = value; 2000 + break; 2001 + case NES_CM_SET_FREE_PKT_Q_SIZE: 2002 + cm_core->free_tx_pkt_max = value; 2003 + break; 2004 + default: 2005 + /* unknown set option */ 2006 + ret = -EINVAL; 2007 + } 2008 + 2009 + return ret; 2010 + } 2011 + 2012 + 2013 + /** 2014 + * nes_cm_init_tsa_conn setup HW; MPA frames must be 2015 + * successfully exchanged when this is called 2016 + */ 2017 + static int nes_cm_init_tsa_conn(struct nes_qp *nesqp, struct nes_cm_node *cm_node) 2018 + { 2019 + int ret = 0; 2020 + 2021 + if (!nesqp) 2022 + return -EINVAL; 2023 + 2024 + nesqp->nesqp_context->misc |= cpu_to_le32(NES_QPCONTEXT_MISC_IPV4 | 2025 + NES_QPCONTEXT_MISC_NO_NAGLE | NES_QPCONTEXT_MISC_DO_NOT_FRAG | 2026 + NES_QPCONTEXT_MISC_DROS); 2027 + 2028 + if (cm_node->tcp_cntxt.snd_wscale || cm_node->tcp_cntxt.rcv_wscale) 2029 + nesqp->nesqp_context->misc |= cpu_to_le32(NES_QPCONTEXT_MISC_WSCALE); 2030 + 2031 + nesqp->nesqp_context->misc2 |= cpu_to_le32(64 << NES_QPCONTEXT_MISC2_TTL_SHIFT); 2032 + 2033 + nesqp->nesqp_context->mss |= cpu_to_le32(((u32)cm_node->tcp_cntxt.mss) << 16); 2034 + 2035 + nesqp->nesqp_context->tcp_state_flow_label |= cpu_to_le32( 2036 + (u32)NES_QPCONTEXT_TCPSTATE_EST << NES_QPCONTEXT_TCPFLOW_TCP_STATE_SHIFT); 2037 + 2038 + nesqp->nesqp_context->pd_index_wscale |= cpu_to_le32( 2039 + (cm_node->tcp_cntxt.snd_wscale << NES_QPCONTEXT_PDWSCALE_SND_WSCALE_SHIFT) & 2040 + NES_QPCONTEXT_PDWSCALE_SND_WSCALE_MASK); 2041 + 2042 + nesqp->nesqp_context->pd_index_wscale |= cpu_to_le32( 2043 + (cm_node->tcp_cntxt.rcv_wscale << NES_QPCONTEXT_PDWSCALE_RCV_WSCALE_SHIFT) & 2044 + NES_QPCONTEXT_PDWSCALE_RCV_WSCALE_MASK); 2045 + 2046 + nesqp->nesqp_context->keepalive = cpu_to_le32(0x80); 2047 + nesqp->nesqp_context->ts_recent = 0; 2048 + nesqp->nesqp_context->ts_age = 0; 2049 + nesqp->nesqp_context->snd_nxt = cpu_to_le32(cm_node->tcp_cntxt.loc_seq_num); 2050 + nesqp->nesqp_context->snd_wnd = cpu_to_le32(cm_node->tcp_cntxt.snd_wnd); 2051 + nesqp->nesqp_context->rcv_nxt = cpu_to_le32(cm_node->tcp_cntxt.rcv_nxt); 2052 + nesqp->nesqp_context->rcv_wnd = cpu_to_le32(cm_node->tcp_cntxt.rcv_wnd << 2053 + cm_node->tcp_cntxt.rcv_wscale); 2054 + nesqp->nesqp_context->snd_max = cpu_to_le32(cm_node->tcp_cntxt.loc_seq_num); 2055 + nesqp->nesqp_context->snd_una = cpu_to_le32(cm_node->tcp_cntxt.loc_seq_num); 2056 + nesqp->nesqp_context->srtt = 0; 2057 + nesqp->nesqp_context->rttvar = cpu_to_le32(0x6); 2058 + nesqp->nesqp_context->ssthresh = cpu_to_le32(0x3FFFC000); 2059 + nesqp->nesqp_context->cwnd = cpu_to_le32(2*cm_node->tcp_cntxt.mss); 2060 + nesqp->nesqp_context->snd_wl1 = cpu_to_le32(cm_node->tcp_cntxt.rcv_nxt); 2061 + nesqp->nesqp_context->snd_wl2 = cpu_to_le32(cm_node->tcp_cntxt.loc_seq_num); 2062 + nesqp->nesqp_context->max_snd_wnd = cpu_to_le32(cm_node->tcp_cntxt.max_snd_wnd); 2063 + 2064 + nes_debug(NES_DBG_CM, "QP%u: rcv_nxt = 0x%08X, snd_nxt = 0x%08X," 2065 + " Setting MSS to %u, PDWscale = 0x%08X, rcv_wnd = %u, context misc = 0x%08X.\n", 2066 + nesqp->hwqp.qp_id, le32_to_cpu(nesqp->nesqp_context->rcv_nxt), 2067 + le32_to_cpu(nesqp->nesqp_context->snd_nxt), 2068 + cm_node->tcp_cntxt.mss, le32_to_cpu(nesqp->nesqp_context->pd_index_wscale), 2069 + le32_to_cpu(nesqp->nesqp_context->rcv_wnd), 2070 + le32_to_cpu(nesqp->nesqp_context->misc)); 2071 + nes_debug(NES_DBG_CM, " snd_wnd = 0x%08X.\n", le32_to_cpu(nesqp->nesqp_context->snd_wnd)); 2072 + nes_debug(NES_DBG_CM, " snd_cwnd = 0x%08X.\n", le32_to_cpu(nesqp->nesqp_context->cwnd)); 2073 + nes_debug(NES_DBG_CM, " max_swnd = 0x%08X.\n", le32_to_cpu(nesqp->nesqp_context->max_snd_wnd)); 2074 + 2075 + nes_debug(NES_DBG_CM, "Change cm_node state to TSA\n"); 2076 + cm_node->state = NES_CM_STATE_TSA; 2077 + 2078 + return ret; 2079 + } 2080 + 2081 + 2082 + /** 2083 + * nes_cm_disconn 2084 + */ 2085 + int nes_cm_disconn(struct nes_qp *nesqp) 2086 + { 2087 + unsigned long flags; 2088 + 2089 + spin_lock_irqsave(&nesqp->lock, flags); 2090 + if (nesqp->disconn_pending == 0) { 2091 + nesqp->disconn_pending++; 2092 + spin_unlock_irqrestore(&nesqp->lock, flags); 2093 + /* nes_add_ref(&nesqp->ibqp); */ 2094 + /* init our disconnect work element, to */ 2095 + INIT_WORK(&nesqp->disconn_work, nes_disconnect_worker); 2096 + 2097 + queue_work(g_cm_core->disconn_wq, &nesqp->disconn_work); 2098 + } else { 2099 + spin_unlock_irqrestore(&nesqp->lock, flags); 2100 + nes_rem_ref(&nesqp->ibqp); 2101 + } 2102 + 2103 + return 0; 2104 + } 2105 + 2106 + 2107 + /** 2108 + * nes_disconnect_worker 2109 + */ 2110 + void nes_disconnect_worker(struct work_struct *work) 2111 + { 2112 + struct nes_qp *nesqp = container_of(work, struct nes_qp, disconn_work); 2113 + 2114 + nes_debug(NES_DBG_CM, "processing AEQE id 0x%04X for QP%u.\n", 2115 + nesqp->last_aeq, nesqp->hwqp.qp_id); 2116 + nes_cm_disconn_true(nesqp); 2117 + } 2118 + 2119 + 2120 + /** 2121 + * nes_cm_disconn_true 2122 + */ 2123 + int nes_cm_disconn_true(struct nes_qp *nesqp) 2124 + { 2125 + unsigned long flags; 2126 + int ret = 0; 2127 + struct iw_cm_id *cm_id; 2128 + struct iw_cm_event cm_event; 2129 + struct nes_vnic *nesvnic; 2130 + u16 last_ae; 2131 + u8 original_hw_tcp_state; 2132 + u8 original_ibqp_state; 2133 + u8 issued_disconnect_reset = 0; 2134 + 2135 + if (!nesqp) { 2136 + nes_debug(NES_DBG_CM, "disconnect_worker nesqp is NULL\n"); 2137 + return -1; 2138 + } 2139 + 2140 + spin_lock_irqsave(&nesqp->lock, flags); 2141 + cm_id = nesqp->cm_id; 2142 + /* make sure we havent already closed this connection */ 2143 + if (!cm_id) { 2144 + nes_debug(NES_DBG_CM, "QP%u disconnect_worker cmid is NULL\n", 2145 + nesqp->hwqp.qp_id); 2146 + spin_unlock_irqrestore(&nesqp->lock, flags); 2147 + nes_rem_ref(&nesqp->ibqp); 2148 + return -1; 2149 + } 2150 + 2151 + nesvnic = to_nesvnic(nesqp->ibqp.device); 2152 + nes_debug(NES_DBG_CM, "Disconnecting QP%u\n", nesqp->hwqp.qp_id); 2153 + 2154 + original_hw_tcp_state = nesqp->hw_tcp_state; 2155 + original_ibqp_state = nesqp->ibqp_state; 2156 + last_ae = nesqp->last_aeq; 2157 + 2158 + 2159 + nes_debug(NES_DBG_CM, "set ibqp_state=%u\n", nesqp->ibqp_state); 2160 + 2161 + if ((nesqp->cm_id) && (cm_id->event_handler)) { 2162 + if ((original_hw_tcp_state == NES_AEQE_TCP_STATE_CLOSE_WAIT) || 2163 + ((original_ibqp_state == IB_QPS_RTS) && 2164 + (last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET))) { 2165 + atomic_inc(&cm_disconnects); 2166 + cm_event.event = IW_CM_EVENT_DISCONNECT; 2167 + if (last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET) { 2168 + issued_disconnect_reset = 1; 2169 + cm_event.status = IW_CM_EVENT_STATUS_RESET; 2170 + nes_debug(NES_DBG_CM, "Generating a CM Disconnect Event (status reset) for " 2171 + " QP%u, cm_id = %p. \n", 2172 + nesqp->hwqp.qp_id, cm_id); 2173 + } else { 2174 + cm_event.status = IW_CM_EVENT_STATUS_OK; 2175 + } 2176 + 2177 + cm_event.local_addr = cm_id->local_addr; 2178 + cm_event.remote_addr = cm_id->remote_addr; 2179 + cm_event.private_data = NULL; 2180 + cm_event.private_data_len = 0; 2181 + 2182 + nes_debug(NES_DBG_CM, "Generating a CM Disconnect Event for " 2183 + " QP%u, SQ Head = %u, SQ Tail = %u. cm_id = %p, refcount = %u.\n", 2184 + nesqp->hwqp.qp_id, 2185 + nesqp->hwqp.sq_head, nesqp->hwqp.sq_tail, cm_id, 2186 + atomic_read(&nesqp->refcount)); 2187 + 2188 + spin_unlock_irqrestore(&nesqp->lock, flags); 2189 + ret = cm_id->event_handler(cm_id, &cm_event); 2190 + if (ret) 2191 + nes_debug(NES_DBG_CM, "OFA CM event_handler returned, ret=%d\n", ret); 2192 + spin_lock_irqsave(&nesqp->lock, flags); 2193 + } 2194 + 2195 + nesqp->disconn_pending = 0; 2196 + /* There might have been another AE while the lock was released */ 2197 + original_hw_tcp_state = nesqp->hw_tcp_state; 2198 + original_ibqp_state = nesqp->ibqp_state; 2199 + last_ae = nesqp->last_aeq; 2200 + 2201 + if ((issued_disconnect_reset == 0) && (nesqp->cm_id) && 2202 + ((original_hw_tcp_state == NES_AEQE_TCP_STATE_CLOSED) || 2203 + (original_hw_tcp_state == NES_AEQE_TCP_STATE_TIME_WAIT) || 2204 + (last_ae == NES_AEQE_AEID_RDMAP_ROE_BAD_LLP_CLOSE) || 2205 + (last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET))) { 2206 + atomic_inc(&cm_closes); 2207 + nesqp->cm_id = NULL; 2208 + nesqp->in_disconnect = 0; 2209 + spin_unlock_irqrestore(&nesqp->lock, flags); 2210 + nes_disconnect(nesqp, 1); 2211 + 2212 + cm_id->provider_data = nesqp; 2213 + /* Send up the close complete event */ 2214 + cm_event.event = IW_CM_EVENT_CLOSE; 2215 + cm_event.status = IW_CM_EVENT_STATUS_OK; 2216 + cm_event.provider_data = cm_id->provider_data; 2217 + cm_event.local_addr = cm_id->local_addr; 2218 + cm_event.remote_addr = cm_id->remote_addr; 2219 + cm_event.private_data = NULL; 2220 + cm_event.private_data_len = 0; 2221 + 2222 + ret = cm_id->event_handler(cm_id, &cm_event); 2223 + if (ret) { 2224 + nes_debug(NES_DBG_CM, "OFA CM event_handler returned, ret=%d\n", ret); 2225 + } 2226 + 2227 + cm_id->rem_ref(cm_id); 2228 + 2229 + spin_lock_irqsave(&nesqp->lock, flags); 2230 + if (nesqp->flush_issued == 0) { 2231 + nesqp->flush_issued = 1; 2232 + spin_unlock_irqrestore(&nesqp->lock, flags); 2233 + flush_wqes(nesvnic->nesdev, nesqp, NES_CQP_FLUSH_RQ, 1); 2234 + } else { 2235 + spin_unlock_irqrestore(&nesqp->lock, flags); 2236 + } 2237 + 2238 + /* This reference is from either ModifyQP or the AE processing, 2239 + there is still a race here with modifyqp */ 2240 + nes_rem_ref(&nesqp->ibqp); 2241 + 2242 + } else { 2243 + cm_id = nesqp->cm_id; 2244 + spin_unlock_irqrestore(&nesqp->lock, flags); 2245 + /* check to see if the inbound reset beat the outbound reset */ 2246 + if ((!cm_id) && (last_ae==NES_AEQE_AEID_RESET_SENT)) { 2247 + nes_debug(NES_DBG_CM, "QP%u: Decing refcount due to inbound reset" 2248 + " beating the outbound reset.\n", 2249 + nesqp->hwqp.qp_id); 2250 + nes_rem_ref(&nesqp->ibqp); 2251 + } 2252 + } 2253 + } else { 2254 + nesqp->disconn_pending = 0; 2255 + spin_unlock_irqrestore(&nesqp->lock, flags); 2256 + } 2257 + nes_rem_ref(&nesqp->ibqp); 2258 + 2259 + return 0; 2260 + } 2261 + 2262 + 2263 + /** 2264 + * nes_disconnect 2265 + */ 2266 + int nes_disconnect(struct nes_qp *nesqp, int abrupt) 2267 + { 2268 + int ret = 0; 2269 + struct nes_vnic *nesvnic; 2270 + struct nes_device *nesdev; 2271 + 2272 + nesvnic = to_nesvnic(nesqp->ibqp.device); 2273 + if (!nesvnic) 2274 + return -EINVAL; 2275 + 2276 + nesdev = nesvnic->nesdev; 2277 + 2278 + nes_debug(NES_DBG_CM, "netdev refcnt = %u.\n", 2279 + atomic_read(&nesvnic->netdev->refcnt)); 2280 + 2281 + if (nesqp->active_conn) { 2282 + 2283 + /* indicate this connection is NOT active */ 2284 + nesqp->active_conn = 0; 2285 + } else { 2286 + /* Need to free the Last Streaming Mode Message */ 2287 + if (nesqp->ietf_frame) { 2288 + pci_free_consistent(nesdev->pcidev, 2289 + nesqp->private_data_len+sizeof(struct ietf_mpa_frame), 2290 + nesqp->ietf_frame, nesqp->ietf_frame_pbase); 2291 + } 2292 + } 2293 + 2294 + /* close the CM node down if it is still active */ 2295 + if (nesqp->cm_node) { 2296 + nes_debug(NES_DBG_CM, "Call close API\n"); 2297 + 2298 + g_cm_core->api->close(g_cm_core, nesqp->cm_node); 2299 + nesqp->cm_node = NULL; 2300 + } 2301 + 2302 + return ret; 2303 + } 2304 + 2305 + 2306 + /** 2307 + * nes_accept 2308 + */ 2309 + int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) 2310 + { 2311 + u64 u64temp; 2312 + struct ib_qp *ibqp; 2313 + struct nes_qp *nesqp; 2314 + struct nes_vnic *nesvnic; 2315 + struct nes_device *nesdev; 2316 + struct nes_cm_node *cm_node; 2317 + struct nes_adapter *adapter; 2318 + struct ib_qp_attr attr; 2319 + struct iw_cm_event cm_event; 2320 + struct nes_hw_qp_wqe *wqe; 2321 + struct nes_v4_quad nes_quad; 2322 + int ret; 2323 + 2324 + ibqp = nes_get_qp(cm_id->device, conn_param->qpn); 2325 + if (!ibqp) 2326 + return -EINVAL; 2327 + 2328 + /* get all our handles */ 2329 + nesqp = to_nesqp(ibqp); 2330 + nesvnic = to_nesvnic(nesqp->ibqp.device); 2331 + nesdev = nesvnic->nesdev; 2332 + adapter = nesdev->nesadapter; 2333 + 2334 + nes_debug(NES_DBG_CM, "nesvnic=%p, netdev=%p, %s\n", 2335 + nesvnic, nesvnic->netdev, nesvnic->netdev->name); 2336 + 2337 + /* since this is from a listen, we were able to put node handle into cm_id */ 2338 + cm_node = (struct nes_cm_node *)cm_id->provider_data; 2339 + 2340 + /* associate the node with the QP */ 2341 + nesqp->cm_node = (void *)cm_node; 2342 + 2343 + nes_debug(NES_DBG_CM, "QP%u, cm_node=%p, jiffies = %lu\n", 2344 + nesqp->hwqp.qp_id, cm_node, jiffies); 2345 + atomic_inc(&cm_accepts); 2346 + 2347 + nes_debug(NES_DBG_CM, "netdev refcnt = %u.\n", 2348 + atomic_read(&nesvnic->netdev->refcnt)); 2349 + 2350 + /* allocate the ietf frame and space for private data */ 2351 + nesqp->ietf_frame = pci_alloc_consistent(nesdev->pcidev, 2352 + sizeof(struct ietf_mpa_frame) + conn_param->private_data_len, 2353 + &nesqp->ietf_frame_pbase); 2354 + 2355 + if (!nesqp->ietf_frame) { 2356 + nes_debug(NES_DBG_CM, "Unable to allocate memory for private data\n"); 2357 + return -ENOMEM; 2358 + } 2359 + 2360 + 2361 + /* setup the MPA frame */ 2362 + nesqp->private_data_len = conn_param->private_data_len; 2363 + memcpy(nesqp->ietf_frame->key, IEFT_MPA_KEY_REP, IETF_MPA_KEY_SIZE); 2364 + 2365 + memcpy(nesqp->ietf_frame->priv_data, conn_param->private_data, 2366 + conn_param->private_data_len); 2367 + 2368 + nesqp->ietf_frame->priv_data_len = cpu_to_be16(conn_param->private_data_len); 2369 + nesqp->ietf_frame->rev = mpa_version; 2370 + nesqp->ietf_frame->flags = IETF_MPA_FLAGS_CRC; 2371 + 2372 + /* setup our first outgoing iWarp send WQE (the IETF frame response) */ 2373 + wqe = &nesqp->hwqp.sq_vbase[0]; 2374 + 2375 + if (cm_id->remote_addr.sin_addr.s_addr != cm_id->local_addr.sin_addr.s_addr) { 2376 + u64temp = (unsigned long)nesqp; 2377 + u64temp |= NES_SW_CONTEXT_ALIGN>>1; 2378 + set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_COMP_CTX_LOW_IDX, 2379 + u64temp); 2380 + wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] = 2381 + cpu_to_le32(NES_IWARP_SQ_WQE_STREAMING | NES_IWARP_SQ_WQE_WRPDU); 2382 + wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX] = 2383 + cpu_to_le32(conn_param->private_data_len + sizeof(struct ietf_mpa_frame)); 2384 + wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_LOW_IDX] = 2385 + cpu_to_le32((u32)nesqp->ietf_frame_pbase); 2386 + wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_HIGH_IDX] = 2387 + cpu_to_le32((u32)((u64)nesqp->ietf_frame_pbase >> 32)); 2388 + wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] = 2389 + cpu_to_le32(conn_param->private_data_len + sizeof(struct ietf_mpa_frame)); 2390 + wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = 0; 2391 + 2392 + nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32( 2393 + NES_QPCONTEXT_ORDIRD_LSMM_PRESENT | NES_QPCONTEXT_ORDIRD_WRPDU); 2394 + } else { 2395 + nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32((NES_QPCONTEXT_ORDIRD_LSMM_PRESENT | 2396 + NES_QPCONTEXT_ORDIRD_WRPDU | NES_QPCONTEXT_ORDIRD_ALSMM)); 2397 + } 2398 + nesqp->skip_lsmm = 1; 2399 + 2400 + 2401 + /* Cache the cm_id in the qp */ 2402 + nesqp->cm_id = cm_id; 2403 + cm_node->cm_id = cm_id; 2404 + 2405 + /* nesqp->cm_node = (void *)cm_id->provider_data; */ 2406 + cm_id->provider_data = nesqp; 2407 + nesqp->active_conn = 0; 2408 + 2409 + nes_cm_init_tsa_conn(nesqp, cm_node); 2410 + 2411 + nesqp->nesqp_context->tcpPorts[0] = cpu_to_le16(ntohs(cm_id->local_addr.sin_port)); 2412 + nesqp->nesqp_context->tcpPorts[1] = cpu_to_le16(ntohs(cm_id->remote_addr.sin_port)); 2413 + nesqp->nesqp_context->ip0 = cpu_to_le32(ntohl(cm_id->remote_addr.sin_addr.s_addr)); 2414 + 2415 + nesqp->nesqp_context->misc2 |= cpu_to_le32( 2416 + (u32)PCI_FUNC(nesdev->pcidev->devfn) << NES_QPCONTEXT_MISC2_SRC_IP_SHIFT); 2417 + 2418 + nesqp->nesqp_context->arp_index_vlan |= cpu_to_le32( 2419 + nes_arp_table(nesdev, le32_to_cpu(nesqp->nesqp_context->ip0), NULL, 2420 + NES_ARP_RESOLVE) << 16); 2421 + 2422 + nesqp->nesqp_context->ts_val_delta = cpu_to_le32( 2423 + jiffies - nes_read_indexed(nesdev, NES_IDX_TCP_NOW)); 2424 + 2425 + nesqp->nesqp_context->ird_index = cpu_to_le32(nesqp->hwqp.qp_id); 2426 + 2427 + nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32( 2428 + ((u32)1 << NES_QPCONTEXT_ORDIRD_IWARP_MODE_SHIFT)); 2429 + nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32((u32)conn_param->ord); 2430 + 2431 + memset(&nes_quad, 0, sizeof(nes_quad)); 2432 + nes_quad.DstIpAdrIndex = cpu_to_le32((u32)PCI_FUNC(nesdev->pcidev->devfn) << 24); 2433 + nes_quad.SrcIpadr = cm_id->remote_addr.sin_addr.s_addr; 2434 + nes_quad.TcpPorts[0] = cm_id->remote_addr.sin_port; 2435 + nes_quad.TcpPorts[1] = cm_id->local_addr.sin_port; 2436 + 2437 + /* Produce hash key */ 2438 + nesqp->hte_index = cpu_to_be32( 2439 + crc32c(~0, (void *)&nes_quad, sizeof(nes_quad)) ^ 0xffffffff); 2440 + nes_debug(NES_DBG_CM, "HTE Index = 0x%08X, CRC = 0x%08X\n", 2441 + nesqp->hte_index, nesqp->hte_index & adapter->hte_index_mask); 2442 + 2443 + nesqp->hte_index &= adapter->hte_index_mask; 2444 + nesqp->nesqp_context->hte_index = cpu_to_le32(nesqp->hte_index); 2445 + 2446 + cm_node->cm_core->api->accelerated(cm_node->cm_core, cm_node); 2447 + 2448 + nes_debug(NES_DBG_CM, "QP%u, Destination IP = 0x%08X:0x%04X, local = 0x%08X:0x%04X," 2449 + " rcv_nxt=0x%08X, snd_nxt=0x%08X, mpa + private data length=%zu.\n", 2450 + nesqp->hwqp.qp_id, 2451 + ntohl(cm_id->remote_addr.sin_addr.s_addr), 2452 + ntohs(cm_id->remote_addr.sin_port), 2453 + ntohl(cm_id->local_addr.sin_addr.s_addr), 2454 + ntohs(cm_id->local_addr.sin_port), 2455 + le32_to_cpu(nesqp->nesqp_context->rcv_nxt), 2456 + le32_to_cpu(nesqp->nesqp_context->snd_nxt), 2457 + conn_param->private_data_len+sizeof(struct ietf_mpa_frame)); 2458 + 2459 + attr.qp_state = IB_QPS_RTS; 2460 + nes_modify_qp(&nesqp->ibqp, &attr, IB_QP_STATE, NULL); 2461 + 2462 + /* notify OF layer that accept event was successfull */ 2463 + cm_id->add_ref(cm_id); 2464 + 2465 + cm_event.event = IW_CM_EVENT_ESTABLISHED; 2466 + cm_event.status = IW_CM_EVENT_STATUS_ACCEPTED; 2467 + cm_event.provider_data = (void *)nesqp; 2468 + cm_event.local_addr = cm_id->local_addr; 2469 + cm_event.remote_addr = cm_id->remote_addr; 2470 + cm_event.private_data = NULL; 2471 + cm_event.private_data_len = 0; 2472 + ret = cm_id->event_handler(cm_id, &cm_event); 2473 + if (cm_node->loopbackpartner) { 2474 + cm_node->loopbackpartner->mpa_frame_size = nesqp->private_data_len; 2475 + /* copy entire MPA frame to our cm_node's frame */ 2476 + memcpy(cm_node->loopbackpartner->mpa_frame_buf, nesqp->ietf_frame->priv_data, 2477 + nesqp->private_data_len); 2478 + create_event(cm_node->loopbackpartner, NES_CM_EVENT_CONNECTED); 2479 + } 2480 + if (ret) 2481 + printk("%s[%u] OFA CM event_handler returned, ret=%d\n", 2482 + __FUNCTION__, __LINE__, ret); 2483 + 2484 + return 0; 2485 + } 2486 + 2487 + 2488 + /** 2489 + * nes_reject 2490 + */ 2491 + int nes_reject(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len) 2492 + { 2493 + struct nes_cm_node *cm_node; 2494 + struct nes_cm_core *cm_core; 2495 + 2496 + atomic_inc(&cm_rejects); 2497 + cm_node = (struct nes_cm_node *) cm_id->provider_data; 2498 + cm_core = cm_node->cm_core; 2499 + cm_node->mpa_frame_size = sizeof(struct ietf_mpa_frame) + pdata_len; 2500 + 2501 + strcpy(&cm_node->mpa_frame.key[0], IEFT_MPA_KEY_REP); 2502 + memcpy(&cm_node->mpa_frame.priv_data, pdata, pdata_len); 2503 + 2504 + cm_node->mpa_frame.priv_data_len = cpu_to_be16(pdata_len); 2505 + cm_node->mpa_frame.rev = mpa_version; 2506 + cm_node->mpa_frame.flags = IETF_MPA_FLAGS_CRC | IETF_MPA_FLAGS_REJECT; 2507 + 2508 + cm_core->api->reject(cm_core, &cm_node->mpa_frame, cm_node); 2509 + 2510 + return 0; 2511 + } 2512 + 2513 + 2514 + /** 2515 + * nes_connect 2516 + * setup and launch cm connect node 2517 + */ 2518 + int nes_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) 2519 + { 2520 + struct ib_qp *ibqp; 2521 + struct nes_qp *nesqp; 2522 + struct nes_vnic *nesvnic; 2523 + struct nes_device *nesdev; 2524 + struct nes_cm_node *cm_node; 2525 + struct nes_cm_info cm_info; 2526 + 2527 + ibqp = nes_get_qp(cm_id->device, conn_param->qpn); 2528 + if (!ibqp) 2529 + return -EINVAL; 2530 + nesqp = to_nesqp(ibqp); 2531 + if (!nesqp) 2532 + return -EINVAL; 2533 + nesvnic = to_nesvnic(nesqp->ibqp.device); 2534 + if (!nesvnic) 2535 + return -EINVAL; 2536 + nesdev = nesvnic->nesdev; 2537 + if (!nesdev) 2538 + return -EINVAL; 2539 + 2540 + atomic_inc(&cm_connects); 2541 + 2542 + nesqp->ietf_frame = kzalloc(sizeof(struct ietf_mpa_frame) + 2543 + conn_param->private_data_len, GFP_KERNEL); 2544 + if (!nesqp->ietf_frame) 2545 + return -ENOMEM; 2546 + 2547 + /* set qp as having an active connection */ 2548 + nesqp->active_conn = 1; 2549 + 2550 + nes_debug(NES_DBG_CM, "QP%u, Destination IP = 0x%08X:0x%04X, local = 0x%08X:0x%04X.\n", 2551 + nesqp->hwqp.qp_id, 2552 + ntohl(cm_id->remote_addr.sin_addr.s_addr), 2553 + ntohs(cm_id->remote_addr.sin_port), 2554 + ntohl(cm_id->local_addr.sin_addr.s_addr), 2555 + ntohs(cm_id->local_addr.sin_port)); 2556 + 2557 + /* cache the cm_id in the qp */ 2558 + nesqp->cm_id = cm_id; 2559 + 2560 + cm_id->provider_data = nesqp; 2561 + 2562 + /* copy the private data */ 2563 + if (conn_param->private_data_len) { 2564 + memcpy(nesqp->ietf_frame->priv_data, conn_param->private_data, 2565 + conn_param->private_data_len); 2566 + } 2567 + 2568 + nesqp->private_data_len = conn_param->private_data_len; 2569 + nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32((u32)conn_param->ord); 2570 + nes_debug(NES_DBG_CM, "requested ord = 0x%08X.\n", (u32)conn_param->ord); 2571 + nes_debug(NES_DBG_CM, "mpa private data len =%u\n", conn_param->private_data_len); 2572 + 2573 + strcpy(&nesqp->ietf_frame->key[0], IEFT_MPA_KEY_REQ); 2574 + nesqp->ietf_frame->flags = IETF_MPA_FLAGS_CRC; 2575 + nesqp->ietf_frame->rev = IETF_MPA_VERSION; 2576 + nesqp->ietf_frame->priv_data_len = htons(conn_param->private_data_len); 2577 + 2578 + if (cm_id->local_addr.sin_addr.s_addr != cm_id->remote_addr.sin_addr.s_addr) 2579 + nes_manage_apbvt(nesvnic, ntohs(cm_id->local_addr.sin_port), 2580 + PCI_FUNC(nesdev->pcidev->devfn), NES_MANAGE_APBVT_ADD); 2581 + 2582 + /* set up the connection params for the node */ 2583 + cm_info.loc_addr = (cm_id->local_addr.sin_addr.s_addr); 2584 + cm_info.loc_port = (cm_id->local_addr.sin_port); 2585 + cm_info.rem_addr = (cm_id->remote_addr.sin_addr.s_addr); 2586 + cm_info.rem_port = (cm_id->remote_addr.sin_port); 2587 + cm_info.cm_id = cm_id; 2588 + cm_info.conn_type = NES_CM_IWARP_CONN_TYPE; 2589 + 2590 + cm_id->add_ref(cm_id); 2591 + nes_add_ref(&nesqp->ibqp); 2592 + 2593 + /* create a connect CM node connection */ 2594 + cm_node = g_cm_core->api->connect(g_cm_core, nesvnic, nesqp->ietf_frame, &cm_info); 2595 + if (!cm_node) { 2596 + if (cm_id->local_addr.sin_addr.s_addr != cm_id->remote_addr.sin_addr.s_addr) 2597 + nes_manage_apbvt(nesvnic, ntohs(cm_id->local_addr.sin_port), 2598 + PCI_FUNC(nesdev->pcidev->devfn), NES_MANAGE_APBVT_DEL); 2599 + nes_rem_ref(&nesqp->ibqp); 2600 + kfree(nesqp->ietf_frame); 2601 + nesqp->ietf_frame = NULL; 2602 + cm_id->rem_ref(cm_id); 2603 + return -ENOMEM; 2604 + } 2605 + 2606 + cm_node->apbvt_set = 1; 2607 + nesqp->cm_node = cm_node; 2608 + 2609 + return 0; 2610 + } 2611 + 2612 + 2613 + /** 2614 + * nes_create_listen 2615 + */ 2616 + int nes_create_listen(struct iw_cm_id *cm_id, int backlog) 2617 + { 2618 + struct nes_vnic *nesvnic; 2619 + struct nes_cm_listener *cm_node; 2620 + struct nes_cm_info cm_info; 2621 + struct nes_adapter *adapter; 2622 + int err; 2623 + 2624 + 2625 + nes_debug(NES_DBG_CM, "cm_id = %p, local port = 0x%04X.\n", 2626 + cm_id, ntohs(cm_id->local_addr.sin_port)); 2627 + 2628 + nesvnic = to_nesvnic(cm_id->device); 2629 + if (!nesvnic) 2630 + return -EINVAL; 2631 + adapter = nesvnic->nesdev->nesadapter; 2632 + nes_debug(NES_DBG_CM, "nesvnic=%p, netdev=%p, %s\n", 2633 + nesvnic, nesvnic->netdev, nesvnic->netdev->name); 2634 + 2635 + nes_debug(NES_DBG_CM, "nesvnic->local_ipaddr=0x%08x, sin_addr.s_addr=0x%08x\n", 2636 + nesvnic->local_ipaddr, cm_id->local_addr.sin_addr.s_addr); 2637 + 2638 + /* setup listen params in our api call struct */ 2639 + cm_info.loc_addr = nesvnic->local_ipaddr; 2640 + cm_info.loc_port = cm_id->local_addr.sin_port; 2641 + cm_info.backlog = backlog; 2642 + cm_info.cm_id = cm_id; 2643 + 2644 + cm_info.conn_type = NES_CM_IWARP_CONN_TYPE; 2645 + 2646 + 2647 + cm_node = g_cm_core->api->listen(g_cm_core, nesvnic, &cm_info); 2648 + if (!cm_node) { 2649 + printk("%s[%u] Error returned from listen API call\n", 2650 + __FUNCTION__, __LINE__); 2651 + return -ENOMEM; 2652 + } 2653 + 2654 + cm_id->provider_data = cm_node; 2655 + 2656 + if (!cm_node->reused_node) { 2657 + err = nes_manage_apbvt(nesvnic, ntohs(cm_id->local_addr.sin_port), 2658 + PCI_FUNC(nesvnic->nesdev->pcidev->devfn), NES_MANAGE_APBVT_ADD); 2659 + if (err) { 2660 + printk("nes_manage_apbvt call returned %d.\n", err); 2661 + g_cm_core->api->stop_listener(g_cm_core, (void *)cm_node); 2662 + return err; 2663 + } 2664 + cm_listens_created++; 2665 + } 2666 + 2667 + cm_id->add_ref(cm_id); 2668 + cm_id->provider_data = (void *)cm_node; 2669 + 2670 + 2671 + return 0; 2672 + } 2673 + 2674 + 2675 + /** 2676 + * nes_destroy_listen 2677 + */ 2678 + int nes_destroy_listen(struct iw_cm_id *cm_id) 2679 + { 2680 + if (cm_id->provider_data) 2681 + g_cm_core->api->stop_listener(g_cm_core, cm_id->provider_data); 2682 + else 2683 + nes_debug(NES_DBG_CM, "cm_id->provider_data was NULL\n"); 2684 + 2685 + cm_id->rem_ref(cm_id); 2686 + 2687 + return 0; 2688 + } 2689 + 2690 + 2691 + /** 2692 + * nes_cm_recv 2693 + */ 2694 + int nes_cm_recv(struct sk_buff *skb, struct net_device *netdevice) 2695 + { 2696 + cm_packets_received++; 2697 + if ((g_cm_core) && (g_cm_core->api)) { 2698 + g_cm_core->api->recv_pkt(g_cm_core, netdev_priv(netdevice), skb); 2699 + } else { 2700 + nes_debug(NES_DBG_CM, "Unable to process packet for CM," 2701 + " cm is not setup properly.\n"); 2702 + } 2703 + 2704 + return 0; 2705 + } 2706 + 2707 + 2708 + /** 2709 + * nes_cm_start 2710 + * Start and init a cm core module 2711 + */ 2712 + int nes_cm_start(void) 2713 + { 2714 + nes_debug(NES_DBG_CM, "\n"); 2715 + /* create the primary CM core, pass this handle to subsequent core inits */ 2716 + g_cm_core = nes_cm_alloc_core(); 2717 + if (g_cm_core) { 2718 + return 0; 2719 + } else { 2720 + return -ENOMEM; 2721 + } 2722 + } 2723 + 2724 + 2725 + /** 2726 + * nes_cm_stop 2727 + * stop and dealloc all cm core instances 2728 + */ 2729 + int nes_cm_stop(void) 2730 + { 2731 + g_cm_core->api->destroy_cm_core(g_cm_core); 2732 + return 0; 2733 + } 2734 + 2735 + 2736 + /** 2737 + * cm_event_connected 2738 + * handle a connected event, setup QPs and HW 2739 + */ 2740 + void cm_event_connected(struct nes_cm_event *event) 2741 + { 2742 + u64 u64temp; 2743 + struct nes_qp *nesqp; 2744 + struct nes_vnic *nesvnic; 2745 + struct nes_device *nesdev; 2746 + struct nes_cm_node *cm_node; 2747 + struct nes_adapter *nesadapter; 2748 + struct ib_qp_attr attr; 2749 + struct iw_cm_id *cm_id; 2750 + struct iw_cm_event cm_event; 2751 + struct nes_hw_qp_wqe *wqe; 2752 + struct nes_v4_quad nes_quad; 2753 + int ret; 2754 + 2755 + /* get all our handles */ 2756 + cm_node = event->cm_node; 2757 + cm_id = cm_node->cm_id; 2758 + nes_debug(NES_DBG_CM, "cm_event_connected - %p - cm_id = %p\n", cm_node, cm_id); 2759 + nesqp = (struct nes_qp *)cm_id->provider_data; 2760 + nesvnic = to_nesvnic(nesqp->ibqp.device); 2761 + nesdev = nesvnic->nesdev; 2762 + nesadapter = nesdev->nesadapter; 2763 + 2764 + if (nesqp->destroyed) { 2765 + return; 2766 + } 2767 + atomic_inc(&cm_connecteds); 2768 + nes_debug(NES_DBG_CM, "QP%u attempting to connect to 0x%08X:0x%04X on" 2769 + " local port 0x%04X. jiffies = %lu.\n", 2770 + nesqp->hwqp.qp_id, 2771 + ntohl(cm_id->remote_addr.sin_addr.s_addr), 2772 + ntohs(cm_id->remote_addr.sin_port), 2773 + ntohs(cm_id->local_addr.sin_port), 2774 + jiffies); 2775 + 2776 + nes_cm_init_tsa_conn(nesqp, cm_node); 2777 + 2778 + /* set the QP tsa context */ 2779 + nesqp->nesqp_context->tcpPorts[0] = cpu_to_le16(ntohs(cm_id->local_addr.sin_port)); 2780 + nesqp->nesqp_context->tcpPorts[1] = cpu_to_le16(ntohs(cm_id->remote_addr.sin_port)); 2781 + nesqp->nesqp_context->ip0 = cpu_to_le32(ntohl(cm_id->remote_addr.sin_addr.s_addr)); 2782 + 2783 + nesqp->nesqp_context->misc2 |= cpu_to_le32( 2784 + (u32)PCI_FUNC(nesdev->pcidev->devfn) << NES_QPCONTEXT_MISC2_SRC_IP_SHIFT); 2785 + nesqp->nesqp_context->arp_index_vlan |= cpu_to_le32( 2786 + nes_arp_table(nesdev, le32_to_cpu(nesqp->nesqp_context->ip0), 2787 + NULL, NES_ARP_RESOLVE) << 16); 2788 + nesqp->nesqp_context->ts_val_delta = cpu_to_le32( 2789 + jiffies - nes_read_indexed(nesdev, NES_IDX_TCP_NOW)); 2790 + nesqp->nesqp_context->ird_index = cpu_to_le32(nesqp->hwqp.qp_id); 2791 + nesqp->nesqp_context->ird_ord_sizes |= 2792 + cpu_to_le32((u32)1 << NES_QPCONTEXT_ORDIRD_IWARP_MODE_SHIFT); 2793 + 2794 + /* Adjust tail for not having a LSMM */ 2795 + nesqp->hwqp.sq_tail = 1; 2796 + 2797 + #if defined(NES_SEND_FIRST_WRITE) 2798 + if (cm_node->send_write0) { 2799 + nes_debug(NES_DBG_CM, "Sending first write.\n"); 2800 + wqe = &nesqp->hwqp.sq_vbase[0]; 2801 + u64temp = (unsigned long)nesqp; 2802 + u64temp |= NES_SW_CONTEXT_ALIGN>>1; 2803 + set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_COMP_CTX_LOW_IDX, 2804 + u64temp); 2805 + wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] = cpu_to_le32(NES_IWARP_SQ_OP_RDMAW); 2806 + wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX] = 0; 2807 + wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_LOW_IDX] = 0; 2808 + wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_HIGH_IDX] = 0; 2809 + wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] = 0; 2810 + wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = 0; 2811 + 2812 + /* use the reserved spot on the WQ for the extra first WQE */ 2813 + nesqp->nesqp_context->ird_ord_sizes &= cpu_to_le32(~(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT | 2814 + NES_QPCONTEXT_ORDIRD_WRPDU | NES_QPCONTEXT_ORDIRD_ALSMM)); 2815 + nesqp->skip_lsmm = 1; 2816 + nesqp->hwqp.sq_tail = 0; 2817 + nes_write32(nesdev->regs + NES_WQE_ALLOC, 2818 + (1 << 24) | 0x00800000 | nesqp->hwqp.qp_id); 2819 + } 2820 + #endif 2821 + 2822 + memset(&nes_quad, 0, sizeof(nes_quad)); 2823 + 2824 + nes_quad.DstIpAdrIndex = cpu_to_le32((u32)PCI_FUNC(nesdev->pcidev->devfn) << 24); 2825 + nes_quad.SrcIpadr = cm_id->remote_addr.sin_addr.s_addr; 2826 + nes_quad.TcpPorts[0] = cm_id->remote_addr.sin_port; 2827 + nes_quad.TcpPorts[1] = cm_id->local_addr.sin_port; 2828 + 2829 + /* Produce hash key */ 2830 + nesqp->hte_index = cpu_to_be32( 2831 + crc32c(~0, (void *)&nes_quad, sizeof(nes_quad)) ^ 0xffffffff); 2832 + nes_debug(NES_DBG_CM, "HTE Index = 0x%08X, After CRC = 0x%08X\n", 2833 + nesqp->hte_index, nesqp->hte_index & nesadapter->hte_index_mask); 2834 + 2835 + nesqp->hte_index &= nesadapter->hte_index_mask; 2836 + nesqp->nesqp_context->hte_index = cpu_to_le32(nesqp->hte_index); 2837 + 2838 + nesqp->ietf_frame = &cm_node->mpa_frame; 2839 + nesqp->private_data_len = (u8) cm_node->mpa_frame_size; 2840 + cm_node->cm_core->api->accelerated(cm_node->cm_core, cm_node); 2841 + 2842 + /* modify QP state to rts */ 2843 + attr.qp_state = IB_QPS_RTS; 2844 + nes_modify_qp(&nesqp->ibqp, &attr, IB_QP_STATE, NULL); 2845 + 2846 + /* notify OF layer we successfully created the requested connection */ 2847 + cm_event.event = IW_CM_EVENT_CONNECT_REPLY; 2848 + cm_event.status = IW_CM_EVENT_STATUS_ACCEPTED; 2849 + cm_event.provider_data = cm_id->provider_data; 2850 + cm_event.local_addr.sin_family = AF_INET; 2851 + cm_event.local_addr.sin_port = cm_id->local_addr.sin_port; 2852 + cm_event.remote_addr = cm_id->remote_addr; 2853 + 2854 + cm_event.private_data = (void *)event->cm_node->mpa_frame_buf; 2855 + cm_event.private_data_len = (u8) event->cm_node->mpa_frame_size; 2856 + 2857 + cm_event.local_addr.sin_addr.s_addr = event->cm_info.rem_addr; 2858 + ret = cm_id->event_handler(cm_id, &cm_event); 2859 + nes_debug(NES_DBG_CM, "OFA CM event_handler returned, ret=%d\n", ret); 2860 + 2861 + if (ret) 2862 + printk("%s[%u] OFA CM event_handler returned, ret=%d\n", 2863 + __FUNCTION__, __LINE__, ret); 2864 + nes_debug(NES_DBG_CM, "Exiting connect thread for QP%u. jiffies = %lu\n", 2865 + nesqp->hwqp.qp_id, jiffies ); 2866 + 2867 + nes_rem_ref(&nesqp->ibqp); 2868 + 2869 + return; 2870 + } 2871 + 2872 + 2873 + /** 2874 + * cm_event_connect_error 2875 + */ 2876 + void cm_event_connect_error(struct nes_cm_event *event) 2877 + { 2878 + struct nes_qp *nesqp; 2879 + struct iw_cm_id *cm_id; 2880 + struct iw_cm_event cm_event; 2881 + /* struct nes_cm_info cm_info; */ 2882 + int ret; 2883 + 2884 + if (!event->cm_node) 2885 + return; 2886 + 2887 + cm_id = event->cm_node->cm_id; 2888 + if (!cm_id) { 2889 + return; 2890 + } 2891 + 2892 + nes_debug(NES_DBG_CM, "cm_node=%p, cm_id=%p\n", event->cm_node, cm_id); 2893 + nesqp = cm_id->provider_data; 2894 + 2895 + if (!nesqp) { 2896 + return; 2897 + } 2898 + 2899 + /* notify OF layer about this connection error event */ 2900 + /* cm_id->rem_ref(cm_id); */ 2901 + nesqp->cm_id = NULL; 2902 + cm_id->provider_data = NULL; 2903 + cm_event.event = IW_CM_EVENT_CONNECT_REPLY; 2904 + cm_event.status = IW_CM_EVENT_STATUS_REJECTED; 2905 + cm_event.provider_data = cm_id->provider_data; 2906 + cm_event.local_addr = cm_id->local_addr; 2907 + cm_event.remote_addr = cm_id->remote_addr; 2908 + cm_event.private_data = NULL; 2909 + cm_event.private_data_len = 0; 2910 + 2911 + nes_debug(NES_DBG_CM, "call CM_EVENT REJECTED, local_addr=%08x, remove_addr=%08x\n", 2912 + cm_event.local_addr.sin_addr.s_addr, cm_event.remote_addr.sin_addr.s_addr); 2913 + 2914 + ret = cm_id->event_handler(cm_id, &cm_event); 2915 + nes_debug(NES_DBG_CM, "OFA CM event_handler returned, ret=%d\n", ret); 2916 + if (ret) 2917 + printk("%s[%u] OFA CM event_handler returned, ret=%d\n", 2918 + __FUNCTION__, __LINE__, ret); 2919 + nes_rem_ref(&nesqp->ibqp); 2920 + cm_id->rem_ref(cm_id); 2921 + 2922 + return; 2923 + } 2924 + 2925 + 2926 + /** 2927 + * cm_event_reset 2928 + */ 2929 + void cm_event_reset(struct nes_cm_event *event) 2930 + { 2931 + struct nes_qp *nesqp; 2932 + struct iw_cm_id *cm_id; 2933 + struct iw_cm_event cm_event; 2934 + /* struct nes_cm_info cm_info; */ 2935 + int ret; 2936 + 2937 + if (!event->cm_node) 2938 + return; 2939 + 2940 + if (!event->cm_node->cm_id) 2941 + return; 2942 + 2943 + cm_id = event->cm_node->cm_id; 2944 + 2945 + nes_debug(NES_DBG_CM, "%p - cm_id = %p\n", event->cm_node, cm_id); 2946 + nesqp = cm_id->provider_data; 2947 + 2948 + nesqp->cm_id = NULL; 2949 + /* cm_id->provider_data = NULL; */ 2950 + cm_event.event = IW_CM_EVENT_DISCONNECT; 2951 + cm_event.status = IW_CM_EVENT_STATUS_RESET; 2952 + cm_event.provider_data = cm_id->provider_data; 2953 + cm_event.local_addr = cm_id->local_addr; 2954 + cm_event.remote_addr = cm_id->remote_addr; 2955 + cm_event.private_data = NULL; 2956 + cm_event.private_data_len = 0; 2957 + 2958 + ret = cm_id->event_handler(cm_id, &cm_event); 2959 + nes_debug(NES_DBG_CM, "OFA CM event_handler returned, ret=%d\n", ret); 2960 + 2961 + 2962 + /* notify OF layer about this connection error event */ 2963 + cm_id->rem_ref(cm_id); 2964 + 2965 + return; 2966 + } 2967 + 2968 + 2969 + /** 2970 + * cm_event_mpa_req 2971 + */ 2972 + void cm_event_mpa_req(struct nes_cm_event *event) 2973 + { 2974 + struct iw_cm_id *cm_id; 2975 + struct iw_cm_event cm_event; 2976 + int ret; 2977 + struct nes_cm_node *cm_node; 2978 + 2979 + cm_node = event->cm_node; 2980 + if (!cm_node) 2981 + return; 2982 + cm_id = cm_node->cm_id; 2983 + 2984 + atomic_inc(&cm_connect_reqs); 2985 + nes_debug(NES_DBG_CM, "cm_node = %p - cm_id = %p, jiffies = %lu\n", 2986 + cm_node, cm_id, jiffies); 2987 + 2988 + cm_event.event = IW_CM_EVENT_CONNECT_REQUEST; 2989 + cm_event.status = IW_CM_EVENT_STATUS_OK; 2990 + cm_event.provider_data = (void *)cm_node; 2991 + 2992 + cm_event.local_addr.sin_family = AF_INET; 2993 + cm_event.local_addr.sin_port = htons(event->cm_info.loc_port); 2994 + cm_event.local_addr.sin_addr.s_addr = htonl(event->cm_info.loc_addr); 2995 + 2996 + cm_event.remote_addr.sin_family = AF_INET; 2997 + cm_event.remote_addr.sin_port = htons(event->cm_info.rem_port); 2998 + cm_event.remote_addr.sin_addr.s_addr = htonl(event->cm_info.rem_addr); 2999 + 3000 + cm_event.private_data = cm_node->mpa_frame_buf; 3001 + cm_event.private_data_len = (u8) cm_node->mpa_frame_size; 3002 + 3003 + ret = cm_id->event_handler(cm_id, &cm_event); 3004 + if (ret) 3005 + printk("%s[%u] OFA CM event_handler returned, ret=%d\n", 3006 + __FUNCTION__, __LINE__, ret); 3007 + 3008 + return; 3009 + } 3010 + 3011 + 3012 + static void nes_cm_event_handler(struct work_struct *); 3013 + 3014 + /** 3015 + * nes_cm_post_event 3016 + * post an event to the cm event handler 3017 + */ 3018 + int nes_cm_post_event(struct nes_cm_event *event) 3019 + { 3020 + atomic_inc(&event->cm_node->cm_core->events_posted); 3021 + add_ref_cm_node(event->cm_node); 3022 + event->cm_info.cm_id->add_ref(event->cm_info.cm_id); 3023 + INIT_WORK(&event->event_work, nes_cm_event_handler); 3024 + nes_debug(NES_DBG_CM, "queue_work, event=%p\n", event); 3025 + 3026 + queue_work(event->cm_node->cm_core->event_wq, &event->event_work); 3027 + 3028 + nes_debug(NES_DBG_CM, "Exit\n"); 3029 + return 0; 3030 + } 3031 + 3032 + 3033 + /** 3034 + * nes_cm_event_handler 3035 + * worker function to handle cm events 3036 + * will free instance of nes_cm_event 3037 + */ 3038 + static void nes_cm_event_handler(struct work_struct *work) 3039 + { 3040 + struct nes_cm_event *event = container_of(work, struct nes_cm_event, event_work); 3041 + struct nes_cm_core *cm_core; 3042 + 3043 + if ((!event) || (!event->cm_node) || (!event->cm_node->cm_core)) { 3044 + return; 3045 + } 3046 + cm_core = event->cm_node->cm_core; 3047 + nes_debug(NES_DBG_CM, "event=%p, event->type=%u, events posted=%u\n", 3048 + event, event->type, atomic_read(&cm_core->events_posted)); 3049 + 3050 + switch (event->type) { 3051 + case NES_CM_EVENT_MPA_REQ: 3052 + cm_event_mpa_req(event); 3053 + nes_debug(NES_DBG_CM, "CM Event: MPA REQUEST\n"); 3054 + break; 3055 + case NES_CM_EVENT_RESET: 3056 + nes_debug(NES_DBG_CM, "CM Event: RESET\n"); 3057 + cm_event_reset(event); 3058 + break; 3059 + case NES_CM_EVENT_CONNECTED: 3060 + if ((!event->cm_node->cm_id) || 3061 + (event->cm_node->state != NES_CM_STATE_TSA)) { 3062 + break; 3063 + } 3064 + cm_event_connected(event); 3065 + nes_debug(NES_DBG_CM, "CM Event: CONNECTED\n"); 3066 + break; 3067 + case NES_CM_EVENT_ABORTED: 3068 + if ((!event->cm_node->cm_id) || (event->cm_node->state == NES_CM_STATE_TSA)) { 3069 + break; 3070 + } 3071 + cm_event_connect_error(event); 3072 + nes_debug(NES_DBG_CM, "CM Event: ABORTED\n"); 3073 + break; 3074 + case NES_CM_EVENT_DROPPED_PKT: 3075 + nes_debug(NES_DBG_CM, "CM Event: DROPPED PKT\n"); 3076 + break; 3077 + default: 3078 + nes_debug(NES_DBG_CM, "CM Event: UNKNOWN EVENT TYPE\n"); 3079 + break; 3080 + } 3081 + 3082 + atomic_dec(&cm_core->events_posted); 3083 + event->cm_info.cm_id->rem_ref(event->cm_info.cm_id); 3084 + rem_ref_cm_node(cm_core, event->cm_node); 3085 + kfree(event); 3086 + 3087 + return; 3088 + }
+433
drivers/infiniband/hw/nes/nes_cm.h
···
··· 1 + /* 2 + * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved. 3 + * 4 + * This software is available to you under a choice of one of two 5 + * licenses. You may choose to be licensed under the terms of the GNU 6 + * General Public License (GPL) Version 2, available from the file 7 + * COPYING in the main directory of this source tree, or the 8 + * OpenIB.org BSD license below: 9 + * 10 + * Redistribution and use in source and binary forms, with or 11 + * without modification, are permitted provided that the following 12 + * conditions are met: 13 + * 14 + * - Redistributions of source code must retain the above 15 + * copyright notice, this list of conditions and the following 16 + * disclaimer. 17 + * 18 + * - Redistributions in binary form must reproduce the above 19 + * copyright notice, this list of conditions and the following 20 + * disclaimer in the documentation and/or other materials 21 + * provided with the distribution. 22 + * 23 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 + * SOFTWARE. 31 + * 32 + */ 33 + 34 + #ifndef NES_CM_H 35 + #define NES_CM_H 36 + 37 + #define QUEUE_EVENTS 38 + 39 + #define NES_MANAGE_APBVT_DEL 0 40 + #define NES_MANAGE_APBVT_ADD 1 41 + 42 + /* IETF MPA -- defines, enums, structs */ 43 + #define IEFT_MPA_KEY_REQ "MPA ID Req Frame" 44 + #define IEFT_MPA_KEY_REP "MPA ID Rep Frame" 45 + #define IETF_MPA_KEY_SIZE 16 46 + #define IETF_MPA_VERSION 1 47 + 48 + enum ietf_mpa_flags { 49 + IETF_MPA_FLAGS_MARKERS = 0x80, /* receive Markers */ 50 + IETF_MPA_FLAGS_CRC = 0x40, /* receive Markers */ 51 + IETF_MPA_FLAGS_REJECT = 0x20, /* Reject */ 52 + }; 53 + 54 + struct ietf_mpa_frame { 55 + u8 key[IETF_MPA_KEY_SIZE]; 56 + u8 flags; 57 + u8 rev; 58 + __be16 priv_data_len; 59 + u8 priv_data[0]; 60 + }; 61 + 62 + #define ietf_mpa_req_resp_frame ietf_mpa_frame 63 + 64 + struct nes_v4_quad { 65 + u32 rsvd0; 66 + __le32 DstIpAdrIndex; /* Only most significant 5 bits are valid */ 67 + __be32 SrcIpadr; 68 + __be16 TcpPorts[2]; /* src is low, dest is high */ 69 + }; 70 + 71 + struct nes_cm_node; 72 + enum nes_timer_type { 73 + NES_TIMER_TYPE_SEND, 74 + NES_TIMER_TYPE_RECV, 75 + NES_TIMER_NODE_CLEANUP, 76 + NES_TIMER_TYPE_CLOSE, 77 + }; 78 + 79 + #define MAX_NES_IFS 4 80 + 81 + #define SET_ACK 1 82 + #define SET_SYN 2 83 + #define SET_FIN 4 84 + #define SET_RST 8 85 + 86 + struct option_base { 87 + u8 optionnum; 88 + u8 length; 89 + }; 90 + 91 + enum option_numbers { 92 + OPTION_NUMBER_END, 93 + OPTION_NUMBER_NONE, 94 + OPTION_NUMBER_MSS, 95 + OPTION_NUMBER_WINDOW_SCALE, 96 + OPTION_NUMBER_SACK_PERM, 97 + OPTION_NUMBER_SACK, 98 + OPTION_NUMBER_WRITE0 = 0xbc 99 + }; 100 + 101 + struct option_mss { 102 + u8 optionnum; 103 + u8 length; 104 + __be16 mss; 105 + }; 106 + 107 + struct option_windowscale { 108 + u8 optionnum; 109 + u8 length; 110 + u8 shiftcount; 111 + }; 112 + 113 + union all_known_options { 114 + char as_end; 115 + struct option_base as_base; 116 + struct option_mss as_mss; 117 + struct option_windowscale as_windowscale; 118 + }; 119 + 120 + struct nes_timer_entry { 121 + struct list_head list; 122 + unsigned long timetosend; /* jiffies */ 123 + struct sk_buff *skb; 124 + u32 type; 125 + u32 retrycount; 126 + u32 retranscount; 127 + u32 context; 128 + u32 seq_num; 129 + u32 send_retrans; 130 + int close_when_complete; 131 + struct net_device *netdev; 132 + }; 133 + 134 + #define NES_DEFAULT_RETRYS 64 135 + #define NES_DEFAULT_RETRANS 8 136 + #ifdef CONFIG_INFINIBAND_NES_DEBUG 137 + #define NES_RETRY_TIMEOUT (1000*HZ/1000) 138 + #else 139 + #define NES_RETRY_TIMEOUT (3000*HZ/1000) 140 + #endif 141 + #define NES_SHORT_TIME (10) 142 + #define NES_LONG_TIME (2000*HZ/1000) 143 + 144 + #define NES_CM_HASHTABLE_SIZE 1024 145 + #define NES_CM_TCP_TIMER_INTERVAL 3000 146 + #define NES_CM_DEFAULT_MTU 1540 147 + #define NES_CM_DEFAULT_FRAME_CNT 10 148 + #define NES_CM_THREAD_STACK_SIZE 256 149 + #define NES_CM_DEFAULT_RCV_WND 64240 // before we know that window scaling is allowed 150 + #define NES_CM_DEFAULT_RCV_WND_SCALED 256960 // after we know that window scaling is allowed 151 + #define NES_CM_DEFAULT_RCV_WND_SCALE 2 152 + #define NES_CM_DEFAULT_FREE_PKTS 0x000A 153 + #define NES_CM_FREE_PKT_LO_WATERMARK 2 154 + 155 + #define NES_CM_DEFAULT_MSS 536 156 + 157 + #define NES_CM_DEF_SEQ 0x159bf75f 158 + #define NES_CM_DEF_LOCAL_ID 0x3b47 159 + 160 + #define NES_CM_DEF_SEQ2 0x18ed5740 161 + #define NES_CM_DEF_LOCAL_ID2 0xb807 162 + 163 + typedef u32 nes_addr_t; 164 + 165 + #define nes_cm_tsa_context nes_qp_context 166 + 167 + struct nes_qp; 168 + 169 + /* cm node transition states */ 170 + enum nes_cm_node_state { 171 + NES_CM_STATE_UNKNOWN, 172 + NES_CM_STATE_INITED, 173 + NES_CM_STATE_LISTENING, 174 + NES_CM_STATE_SYN_RCVD, 175 + NES_CM_STATE_SYN_SENT, 176 + NES_CM_STATE_ONE_SIDE_ESTABLISHED, 177 + NES_CM_STATE_ESTABLISHED, 178 + NES_CM_STATE_ACCEPTING, 179 + NES_CM_STATE_MPAREQ_SENT, 180 + NES_CM_STATE_TSA, 181 + NES_CM_STATE_FIN_WAIT1, 182 + NES_CM_STATE_FIN_WAIT2, 183 + NES_CM_STATE_CLOSE_WAIT, 184 + NES_CM_STATE_TIME_WAIT, 185 + NES_CM_STATE_LAST_ACK, 186 + NES_CM_STATE_CLOSING, 187 + NES_CM_STATE_CLOSED 188 + }; 189 + 190 + /* type of nes connection */ 191 + enum nes_cm_conn_type { 192 + NES_CM_IWARP_CONN_TYPE, 193 + }; 194 + 195 + /* CM context params */ 196 + struct nes_cm_tcp_context { 197 + u8 client; 198 + 199 + u32 loc_seq_num; 200 + u32 loc_ack_num; 201 + u32 rem_ack_num; 202 + u32 rcv_nxt; 203 + 204 + u32 loc_id; 205 + u32 rem_id; 206 + 207 + u32 snd_wnd; 208 + u32 max_snd_wnd; 209 + 210 + u32 rcv_wnd; 211 + u32 mss; 212 + u8 snd_wscale; 213 + u8 rcv_wscale; 214 + 215 + struct nes_cm_tsa_context tsa_cntxt; 216 + struct timeval sent_ts; 217 + }; 218 + 219 + 220 + enum nes_cm_listener_state { 221 + NES_CM_LISTENER_PASSIVE_STATE=1, 222 + NES_CM_LISTENER_ACTIVE_STATE=2, 223 + NES_CM_LISTENER_EITHER_STATE=3 224 + }; 225 + 226 + struct nes_cm_listener { 227 + struct list_head list; 228 + u64 session_id; 229 + struct nes_cm_core *cm_core; 230 + u8 loc_mac[ETH_ALEN]; 231 + nes_addr_t loc_addr; 232 + u16 loc_port; 233 + struct iw_cm_id *cm_id; 234 + enum nes_cm_conn_type conn_type; 235 + atomic_t ref_count; 236 + struct nes_vnic *nesvnic; 237 + atomic_t pend_accepts_cnt; 238 + int backlog; 239 + enum nes_cm_listener_state listener_state; 240 + u32 reused_node; 241 + }; 242 + 243 + /* per connection node and node state information */ 244 + struct nes_cm_node { 245 + u64 session_id; 246 + u32 hashkey; 247 + 248 + nes_addr_t loc_addr, rem_addr; 249 + u16 loc_port, rem_port; 250 + 251 + u8 loc_mac[ETH_ALEN]; 252 + u8 rem_mac[ETH_ALEN]; 253 + 254 + enum nes_cm_node_state state; 255 + struct nes_cm_tcp_context tcp_cntxt; 256 + struct nes_cm_core *cm_core; 257 + struct sk_buff_head resend_list; 258 + atomic_t ref_count; 259 + struct net_device *netdev; 260 + 261 + struct nes_cm_node *loopbackpartner; 262 + struct list_head retrans_list; 263 + spinlock_t retrans_list_lock; 264 + struct list_head recv_list; 265 + spinlock_t recv_list_lock; 266 + 267 + int send_write0; 268 + union { 269 + struct ietf_mpa_frame mpa_frame; 270 + u8 mpa_frame_buf[NES_CM_DEFAULT_MTU]; 271 + }; 272 + u16 mpa_frame_size; 273 + struct iw_cm_id *cm_id; 274 + struct list_head list; 275 + int accelerated; 276 + struct nes_cm_listener *listener; 277 + enum nes_cm_conn_type conn_type; 278 + struct nes_vnic *nesvnic; 279 + int apbvt_set; 280 + int accept_pend; 281 + }; 282 + 283 + /* structure for client or CM to fill when making CM api calls. */ 284 + /* - only need to set relevant data, based on op. */ 285 + struct nes_cm_info { 286 + union { 287 + struct iw_cm_id *cm_id; 288 + struct net_device *netdev; 289 + }; 290 + 291 + u16 loc_port; 292 + u16 rem_port; 293 + nes_addr_t loc_addr; 294 + nes_addr_t rem_addr; 295 + 296 + enum nes_cm_conn_type conn_type; 297 + int backlog; 298 + }; 299 + 300 + /* CM event codes */ 301 + enum nes_cm_event_type { 302 + NES_CM_EVENT_UNKNOWN, 303 + NES_CM_EVENT_ESTABLISHED, 304 + NES_CM_EVENT_MPA_REQ, 305 + NES_CM_EVENT_MPA_CONNECT, 306 + NES_CM_EVENT_MPA_ACCEPT, 307 + NES_CM_EVENT_MPA_ESTABLISHED, 308 + NES_CM_EVENT_CONNECTED, 309 + NES_CM_EVENT_CLOSED, 310 + NES_CM_EVENT_RESET, 311 + NES_CM_EVENT_DROPPED_PKT, 312 + NES_CM_EVENT_CLOSE_IMMED, 313 + NES_CM_EVENT_CLOSE_HARD, 314 + NES_CM_EVENT_CLOSE_CLEAN, 315 + NES_CM_EVENT_ABORTED, 316 + NES_CM_EVENT_SEND_FIRST 317 + }; 318 + 319 + /* event to post to CM event handler */ 320 + struct nes_cm_event { 321 + enum nes_cm_event_type type; 322 + 323 + struct nes_cm_info cm_info; 324 + struct work_struct event_work; 325 + struct nes_cm_node *cm_node; 326 + }; 327 + 328 + struct nes_cm_core { 329 + enum nes_cm_node_state state; 330 + atomic_t session_id; 331 + 332 + atomic_t listen_node_cnt; 333 + struct nes_cm_node listen_list; 334 + spinlock_t listen_list_lock; 335 + 336 + u32 mtu; 337 + u32 free_tx_pkt_max; 338 + u32 rx_pkt_posted; 339 + struct sk_buff_head tx_free_list; 340 + atomic_t ht_node_cnt; 341 + struct list_head connected_nodes; 342 + /* struct list_head hashtable[NES_CM_HASHTABLE_SIZE]; */ 343 + spinlock_t ht_lock; 344 + 345 + struct timer_list tcp_timer; 346 + 347 + struct nes_cm_ops *api; 348 + 349 + int (*post_event)(struct nes_cm_event *event); 350 + atomic_t events_posted; 351 + struct workqueue_struct *event_wq; 352 + struct workqueue_struct *disconn_wq; 353 + 354 + atomic_t node_cnt; 355 + u64 aborted_connects; 356 + u32 options; 357 + 358 + struct nes_cm_node *current_listen_node; 359 + }; 360 + 361 + 362 + #define NES_CM_SET_PKT_SIZE (1 << 1) 363 + #define NES_CM_SET_FREE_PKT_Q_SIZE (1 << 2) 364 + 365 + /* CM ops/API for client interface */ 366 + struct nes_cm_ops { 367 + int (*accelerated)(struct nes_cm_core *, struct nes_cm_node *); 368 + struct nes_cm_listener * (*listen)(struct nes_cm_core *, struct nes_vnic *, 369 + struct nes_cm_info *); 370 + int (*stop_listener)(struct nes_cm_core *, struct nes_cm_listener *); 371 + struct nes_cm_node * (*connect)(struct nes_cm_core *, 372 + struct nes_vnic *, struct ietf_mpa_frame *, 373 + struct nes_cm_info *); 374 + int (*close)(struct nes_cm_core *, struct nes_cm_node *); 375 + int (*accept)(struct nes_cm_core *, struct ietf_mpa_frame *, 376 + struct nes_cm_node *); 377 + int (*reject)(struct nes_cm_core *, struct ietf_mpa_frame *, 378 + struct nes_cm_node *); 379 + int (*recv_pkt)(struct nes_cm_core *, struct nes_vnic *, 380 + struct sk_buff *); 381 + int (*destroy_cm_core)(struct nes_cm_core *); 382 + int (*get)(struct nes_cm_core *); 383 + int (*set)(struct nes_cm_core *, u32, u32); 384 + }; 385 + 386 + 387 + int send_mpa_request(struct nes_cm_node *); 388 + struct sk_buff *form_cm_frame(struct sk_buff *, struct nes_cm_node *, 389 + void *, u32, void *, u32, u8); 390 + int schedule_nes_timer(struct nes_cm_node *, struct sk_buff *, 391 + enum nes_timer_type, int, int); 392 + void nes_cm_timer_tick(unsigned long); 393 + int send_syn(struct nes_cm_node *, u32); 394 + int send_reset(struct nes_cm_node *); 395 + int send_ack(struct nes_cm_node *); 396 + int send_fin(struct nes_cm_node *, struct sk_buff *); 397 + struct sk_buff *get_free_pkt(struct nes_cm_node *); 398 + int process_packet(struct nes_cm_node *, struct sk_buff *, struct nes_cm_core *); 399 + 400 + struct nes_cm_node * mini_cm_connect(struct nes_cm_core *, 401 + struct nes_vnic *, struct ietf_mpa_frame *, struct nes_cm_info *); 402 + int mini_cm_accept(struct nes_cm_core *, struct ietf_mpa_frame *, struct nes_cm_node *); 403 + int mini_cm_reject(struct nes_cm_core *, struct ietf_mpa_frame *, struct nes_cm_node *); 404 + int mini_cm_close(struct nes_cm_core *, struct nes_cm_node *); 405 + int mini_cm_recv_pkt(struct nes_cm_core *, struct nes_vnic *, struct sk_buff *); 406 + struct nes_cm_core *mini_cm_alloc_core(struct nes_cm_info *); 407 + int mini_cm_dealloc_core(struct nes_cm_core *); 408 + int mini_cm_get(struct nes_cm_core *); 409 + int mini_cm_set(struct nes_cm_core *, u32, u32); 410 + 411 + int nes_cm_disconn(struct nes_qp *); 412 + void nes_disconnect_worker(struct work_struct *); 413 + int nes_cm_disconn_true(struct nes_qp *); 414 + int nes_disconnect(struct nes_qp *, int); 415 + 416 + int nes_accept(struct iw_cm_id *, struct iw_cm_conn_param *); 417 + int nes_reject(struct iw_cm_id *, const void *, u8); 418 + int nes_connect(struct iw_cm_id *, struct iw_cm_conn_param *); 419 + int nes_create_listen(struct iw_cm_id *, int); 420 + int nes_destroy_listen(struct iw_cm_id *); 421 + 422 + int nes_cm_recv(struct sk_buff *, struct net_device *); 423 + int nes_cm_start(void); 424 + int nes_cm_stop(void); 425 + 426 + /* CM event handler functions */ 427 + void cm_event_connected(struct nes_cm_event *); 428 + void cm_event_connect_error(struct nes_cm_event *); 429 + void cm_event_reset(struct nes_cm_event *); 430 + void cm_event_mpa_req(struct nes_cm_event *); 431 + int nes_cm_post_event(struct nes_cm_event *); 432 + 433 + #endif /* NES_CM_H */
+193
drivers/infiniband/hw/nes/nes_context.h
···
··· 1 + /* 2 + * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved. 3 + * 4 + * This software is available to you under a choice of one of two 5 + * licenses. You may choose to be licensed under the terms of the GNU 6 + * General Public License (GPL) Version 2, available from the file 7 + * COPYING in the main directory of this source tree, or the 8 + * OpenIB.org BSD license below: 9 + * 10 + * Redistribution and use in source and binary forms, with or 11 + * without modification, are permitted provided that the following 12 + * conditions are met: 13 + * 14 + * - Redistributions of source code must retain the above 15 + * copyright notice, this list of conditions and the following 16 + * disclaimer. 17 + * 18 + * - Redistributions in binary form must reproduce the above 19 + * copyright notice, this list of conditions and the following 20 + * disclaimer in the documentation and/or other materials 21 + * provided with the distribution. 22 + * 23 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 + * SOFTWARE. 31 + */ 32 + 33 + #ifndef NES_CONTEXT_H 34 + #define NES_CONTEXT_H 35 + 36 + struct nes_qp_context { 37 + __le32 misc; 38 + __le32 cqs; 39 + __le32 sq_addr_low; 40 + __le32 sq_addr_high; 41 + __le32 rq_addr_low; 42 + __le32 rq_addr_high; 43 + __le32 misc2; 44 + __le16 tcpPorts[2]; 45 + __le32 ip0; 46 + __le32 ip1; 47 + __le32 ip2; 48 + __le32 ip3; 49 + __le32 mss; 50 + __le32 arp_index_vlan; 51 + __le32 tcp_state_flow_label; 52 + __le32 pd_index_wscale; 53 + __le32 keepalive; 54 + u32 ts_recent; 55 + u32 ts_age; 56 + __le32 snd_nxt; 57 + __le32 snd_wnd; 58 + __le32 rcv_nxt; 59 + __le32 rcv_wnd; 60 + __le32 snd_max; 61 + __le32 snd_una; 62 + u32 srtt; 63 + __le32 rttvar; 64 + __le32 ssthresh; 65 + __le32 cwnd; 66 + __le32 snd_wl1; 67 + __le32 snd_wl2; 68 + __le32 max_snd_wnd; 69 + __le32 ts_val_delta; 70 + u32 retransmit; 71 + u32 probe_cnt; 72 + u32 hte_index; 73 + __le32 q2_addr_low; 74 + __le32 q2_addr_high; 75 + __le32 ird_index; 76 + u32 Rsvd3; 77 + __le32 ird_ord_sizes; 78 + u32 mrkr_offset; 79 + __le32 aeq_token_low; 80 + __le32 aeq_token_high; 81 + }; 82 + 83 + /* QP Context Misc Field */ 84 + 85 + #define NES_QPCONTEXT_MISC_IWARP_VER_MASK 0x00000003 86 + #define NES_QPCONTEXT_MISC_IWARP_VER_SHIFT 0 87 + #define NES_QPCONTEXT_MISC_EFB_SIZE_MASK 0x000000C0 88 + #define NES_QPCONTEXT_MISC_EFB_SIZE_SHIFT 6 89 + #define NES_QPCONTEXT_MISC_RQ_SIZE_MASK 0x00000300 90 + #define NES_QPCONTEXT_MISC_RQ_SIZE_SHIFT 8 91 + #define NES_QPCONTEXT_MISC_SQ_SIZE_MASK 0x00000c00 92 + #define NES_QPCONTEXT_MISC_SQ_SIZE_SHIFT 10 93 + #define NES_QPCONTEXT_MISC_PCI_FCN_MASK 0x00007000 94 + #define NES_QPCONTEXT_MISC_PCI_FCN_SHIFT 12 95 + #define NES_QPCONTEXT_MISC_DUP_ACKS_MASK 0x00070000 96 + #define NES_QPCONTEXT_MISC_DUP_ACKS_SHIFT 16 97 + 98 + enum nes_qp_context_misc_bits { 99 + NES_QPCONTEXT_MISC_RX_WQE_SIZE = 0x00000004, 100 + NES_QPCONTEXT_MISC_IPV4 = 0x00000008, 101 + NES_QPCONTEXT_MISC_DO_NOT_FRAG = 0x00000010, 102 + NES_QPCONTEXT_MISC_INSERT_VLAN = 0x00000020, 103 + NES_QPCONTEXT_MISC_DROS = 0x00008000, 104 + NES_QPCONTEXT_MISC_WSCALE = 0x00080000, 105 + NES_QPCONTEXT_MISC_KEEPALIVE = 0x00100000, 106 + NES_QPCONTEXT_MISC_TIMESTAMP = 0x00200000, 107 + NES_QPCONTEXT_MISC_SACK = 0x00400000, 108 + NES_QPCONTEXT_MISC_RDMA_WRITE_EN = 0x00800000, 109 + NES_QPCONTEXT_MISC_RDMA_READ_EN = 0x01000000, 110 + NES_QPCONTEXT_MISC_WBIND_EN = 0x10000000, 111 + NES_QPCONTEXT_MISC_FAST_REGISTER_EN = 0x20000000, 112 + NES_QPCONTEXT_MISC_PRIV_EN = 0x40000000, 113 + NES_QPCONTEXT_MISC_NO_NAGLE = 0x80000000 114 + }; 115 + 116 + enum nes_qp_acc_wq_sizes { 117 + HCONTEXT_TSA_WQ_SIZE_4 = 0, 118 + HCONTEXT_TSA_WQ_SIZE_32 = 1, 119 + HCONTEXT_TSA_WQ_SIZE_128 = 2, 120 + HCONTEXT_TSA_WQ_SIZE_512 = 3 121 + }; 122 + 123 + /* QP Context Misc2 Fields */ 124 + #define NES_QPCONTEXT_MISC2_TTL_MASK 0x000000ff 125 + #define NES_QPCONTEXT_MISC2_TTL_SHIFT 0 126 + #define NES_QPCONTEXT_MISC2_HOP_LIMIT_MASK 0x000000ff 127 + #define NES_QPCONTEXT_MISC2_HOP_LIMIT_SHIFT 0 128 + #define NES_QPCONTEXT_MISC2_LIMIT_MASK 0x00000300 129 + #define NES_QPCONTEXT_MISC2_LIMIT_SHIFT 8 130 + #define NES_QPCONTEXT_MISC2_NIC_INDEX_MASK 0x0000fc00 131 + #define NES_QPCONTEXT_MISC2_NIC_INDEX_SHIFT 10 132 + #define NES_QPCONTEXT_MISC2_SRC_IP_MASK 0x001f0000 133 + #define NES_QPCONTEXT_MISC2_SRC_IP_SHIFT 16 134 + #define NES_QPCONTEXT_MISC2_TOS_MASK 0xff000000 135 + #define NES_QPCONTEXT_MISC2_TOS_SHIFT 24 136 + #define NES_QPCONTEXT_MISC2_TRAFFIC_CLASS_MASK 0xff000000 137 + #define NES_QPCONTEXT_MISC2_TRAFFIC_CLASS_SHIFT 24 138 + 139 + /* QP Context Tcp State/Flow Label Fields */ 140 + #define NES_QPCONTEXT_TCPFLOW_FLOW_LABEL_MASK 0x000fffff 141 + #define NES_QPCONTEXT_TCPFLOW_FLOW_LABEL_SHIFT 0 142 + #define NES_QPCONTEXT_TCPFLOW_TCP_STATE_MASK 0xf0000000 143 + #define NES_QPCONTEXT_TCPFLOW_TCP_STATE_SHIFT 28 144 + 145 + enum nes_qp_tcp_state { 146 + NES_QPCONTEXT_TCPSTATE_CLOSED = 1, 147 + NES_QPCONTEXT_TCPSTATE_EST = 5, 148 + NES_QPCONTEXT_TCPSTATE_TIME_WAIT = 11, 149 + }; 150 + 151 + /* QP Context PD Index/wscale Fields */ 152 + #define NES_QPCONTEXT_PDWSCALE_RCV_WSCALE_MASK 0x0000000f 153 + #define NES_QPCONTEXT_PDWSCALE_RCV_WSCALE_SHIFT 0 154 + #define NES_QPCONTEXT_PDWSCALE_SND_WSCALE_MASK 0x00000f00 155 + #define NES_QPCONTEXT_PDWSCALE_SND_WSCALE_SHIFT 8 156 + #define NES_QPCONTEXT_PDWSCALE_PDINDEX_MASK 0xffff0000 157 + #define NES_QPCONTEXT_PDWSCALE_PDINDEX_SHIFT 16 158 + 159 + /* QP Context Keepalive Fields */ 160 + #define NES_QPCONTEXT_KEEPALIVE_DELTA_MASK 0x0000ffff 161 + #define NES_QPCONTEXT_KEEPALIVE_DELTA_SHIFT 0 162 + #define NES_QPCONTEXT_KEEPALIVE_PROBE_CNT_MASK 0x00ff0000 163 + #define NES_QPCONTEXT_KEEPALIVE_PROBE_CNT_SHIFT 16 164 + #define NES_QPCONTEXT_KEEPALIVE_INTV_MASK 0xff000000 165 + #define NES_QPCONTEXT_KEEPALIVE_INTV_SHIFT 24 166 + 167 + /* QP Context ORD/IRD Fields */ 168 + #define NES_QPCONTEXT_ORDIRD_ORDSIZE_MASK 0x0000007f 169 + #define NES_QPCONTEXT_ORDIRD_ORDSIZE_SHIFT 0 170 + #define NES_QPCONTEXT_ORDIRD_IRDSIZE_MASK 0x00030000 171 + #define NES_QPCONTEXT_ORDIRD_IRDSIZE_SHIFT 16 172 + #define NES_QPCONTEXT_ORDIRD_IWARP_MODE_MASK 0x30000000 173 + #define NES_QPCONTEXT_ORDIRD_IWARP_MODE_SHIFT 28 174 + 175 + enum nes_ord_ird_bits { 176 + NES_QPCONTEXT_ORDIRD_WRPDU = 0x02000000, 177 + NES_QPCONTEXT_ORDIRD_LSMM_PRESENT = 0x04000000, 178 + NES_QPCONTEXT_ORDIRD_ALSMM = 0x08000000, 179 + NES_QPCONTEXT_ORDIRD_AAH = 0x40000000, 180 + NES_QPCONTEXT_ORDIRD_RNMC = 0x80000000 181 + }; 182 + 183 + enum nes_iwarp_qp_state { 184 + NES_QPCONTEXT_IWARP_STATE_NONEXIST = 0, 185 + NES_QPCONTEXT_IWARP_STATE_IDLE = 1, 186 + NES_QPCONTEXT_IWARP_STATE_RTS = 2, 187 + NES_QPCONTEXT_IWARP_STATE_CLOSING = 3, 188 + NES_QPCONTEXT_IWARP_STATE_TERMINATE = 5, 189 + NES_QPCONTEXT_IWARP_STATE_ERROR = 6 190 + }; 191 + 192 + 193 + #endif /* NES_CONTEXT_H */
+3080
drivers/infiniband/hw/nes/nes_hw.c
···
··· 1 + /* 2 + * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved. 3 + * 4 + * This software is available to you under a choice of one of two 5 + * licenses. You may choose to be licensed under the terms of the GNU 6 + * General Public License (GPL) Version 2, available from the file 7 + * COPYING in the main directory of this source tree, or the 8 + * OpenIB.org BSD license below: 9 + * 10 + * Redistribution and use in source and binary forms, with or 11 + * without modification, are permitted provided that the following 12 + * conditions are met: 13 + * 14 + * - Redistributions of source code must retain the above 15 + * copyright notice, this list of conditions and the following 16 + * disclaimer. 17 + * 18 + * - Redistributions in binary form must reproduce the above 19 + * copyright notice, this list of conditions and the following 20 + * disclaimer in the documentation and/or other materials 21 + * provided with the distribution. 22 + * 23 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 + * SOFTWARE. 31 + * 32 + */ 33 + 34 + #include <linux/module.h> 35 + #include <linux/moduleparam.h> 36 + #include <linux/netdevice.h> 37 + #include <linux/etherdevice.h> 38 + #include <linux/ip.h> 39 + #include <linux/tcp.h> 40 + #include <linux/if_vlan.h> 41 + 42 + #include "nes.h" 43 + 44 + u32 crit_err_count = 0; 45 + u32 int_mod_timer_init; 46 + u32 int_mod_cq_depth_256; 47 + u32 int_mod_cq_depth_128; 48 + u32 int_mod_cq_depth_32; 49 + u32 int_mod_cq_depth_24; 50 + u32 int_mod_cq_depth_16; 51 + u32 int_mod_cq_depth_4; 52 + u32 int_mod_cq_depth_1; 53 + 54 + #include "nes_cm.h" 55 + 56 + 57 + #ifdef CONFIG_INFINIBAND_NES_DEBUG 58 + static unsigned char *nes_iwarp_state_str[] = { 59 + "Non-Existant", 60 + "Idle", 61 + "RTS", 62 + "Closing", 63 + "RSVD1", 64 + "Terminate", 65 + "Error", 66 + "RSVD2", 67 + }; 68 + 69 + static unsigned char *nes_tcp_state_str[] = { 70 + "Non-Existant", 71 + "Closed", 72 + "Listen", 73 + "SYN Sent", 74 + "SYN Rcvd", 75 + "Established", 76 + "Close Wait", 77 + "FIN Wait 1", 78 + "Closing", 79 + "Last Ack", 80 + "FIN Wait 2", 81 + "Time Wait", 82 + "RSVD1", 83 + "RSVD2", 84 + "RSVD3", 85 + "RSVD4", 86 + }; 87 + #endif 88 + 89 + 90 + /** 91 + * nes_nic_init_timer_defaults 92 + */ 93 + void nes_nic_init_timer_defaults(struct nes_device *nesdev, u8 jumbomode) 94 + { 95 + unsigned long flags; 96 + struct nes_adapter *nesadapter = nesdev->nesadapter; 97 + struct nes_hw_tune_timer *shared_timer = &nesadapter->tune_timer; 98 + 99 + spin_lock_irqsave(&nesadapter->periodic_timer_lock, flags); 100 + 101 + shared_timer->timer_in_use_min = NES_NIC_FAST_TIMER_LOW; 102 + shared_timer->timer_in_use_max = NES_NIC_FAST_TIMER_HIGH; 103 + if (jumbomode) { 104 + shared_timer->threshold_low = DEFAULT_JUMBO_NES_QL_LOW; 105 + shared_timer->threshold_target = DEFAULT_JUMBO_NES_QL_TARGET; 106 + shared_timer->threshold_high = DEFAULT_JUMBO_NES_QL_HIGH; 107 + } else { 108 + shared_timer->threshold_low = DEFAULT_NES_QL_LOW; 109 + shared_timer->threshold_target = DEFAULT_NES_QL_TARGET; 110 + shared_timer->threshold_high = DEFAULT_NES_QL_HIGH; 111 + } 112 + 113 + /* todo use netdev->mtu to set thresholds */ 114 + spin_unlock_irqrestore(&nesadapter->periodic_timer_lock, flags); 115 + } 116 + 117 + 118 + /** 119 + * nes_nic_init_timer 120 + */ 121 + static void nes_nic_init_timer(struct nes_device *nesdev) 122 + { 123 + unsigned long flags; 124 + struct nes_adapter *nesadapter = nesdev->nesadapter; 125 + struct nes_hw_tune_timer *shared_timer = &nesadapter->tune_timer; 126 + 127 + spin_lock_irqsave(&nesadapter->periodic_timer_lock, flags); 128 + 129 + if (shared_timer->timer_in_use_old == 0) { 130 + nesdev->deepcq_count = 0; 131 + shared_timer->timer_direction_upward = 0; 132 + shared_timer->timer_direction_downward = 0; 133 + shared_timer->timer_in_use = NES_NIC_FAST_TIMER; 134 + shared_timer->timer_in_use_old = 0; 135 + 136 + } 137 + if (shared_timer->timer_in_use != shared_timer->timer_in_use_old) { 138 + shared_timer->timer_in_use_old = shared_timer->timer_in_use; 139 + nes_write32(nesdev->regs+NES_PERIODIC_CONTROL, 140 + 0x80000000 | ((u32)(shared_timer->timer_in_use*8))); 141 + } 142 + /* todo use netdev->mtu to set thresholds */ 143 + spin_unlock_irqrestore(&nesadapter->periodic_timer_lock, flags); 144 + } 145 + 146 + 147 + /** 148 + * nes_nic_tune_timer 149 + */ 150 + static void nes_nic_tune_timer(struct nes_device *nesdev) 151 + { 152 + unsigned long flags; 153 + struct nes_adapter *nesadapter = nesdev->nesadapter; 154 + struct nes_hw_tune_timer *shared_timer = &nesadapter->tune_timer; 155 + u16 cq_count = nesdev->currcq_count; 156 + 157 + spin_lock_irqsave(&nesadapter->periodic_timer_lock, flags); 158 + 159 + if (shared_timer->cq_count_old < cq_count) { 160 + if (cq_count > shared_timer->threshold_low) 161 + shared_timer->cq_direction_downward=0; 162 + } 163 + if (shared_timer->cq_count_old >= cq_count) 164 + shared_timer->cq_direction_downward++; 165 + shared_timer->cq_count_old = cq_count; 166 + if (shared_timer->cq_direction_downward > NES_NIC_CQ_DOWNWARD_TREND) { 167 + if (cq_count <= shared_timer->threshold_low) { 168 + shared_timer->threshold_low = shared_timer->threshold_low/2; 169 + shared_timer->cq_direction_downward=0; 170 + nesdev->currcq_count = 0; 171 + spin_unlock_irqrestore(&nesadapter->periodic_timer_lock, flags); 172 + return; 173 + } 174 + } 175 + 176 + if (cq_count > 1) { 177 + nesdev->deepcq_count += cq_count; 178 + if (cq_count <= shared_timer->threshold_low) { /* increase timer gently */ 179 + shared_timer->timer_direction_upward++; 180 + shared_timer->timer_direction_downward = 0; 181 + } else if (cq_count <= shared_timer->threshold_target) { /* balanced */ 182 + shared_timer->timer_direction_upward = 0; 183 + shared_timer->timer_direction_downward = 0; 184 + } else if (cq_count <= shared_timer->threshold_high) { /* decrease timer gently */ 185 + shared_timer->timer_direction_downward++; 186 + shared_timer->timer_direction_upward = 0; 187 + } else if (cq_count <= (shared_timer->threshold_high) * 2) { 188 + shared_timer->timer_in_use -= 2; 189 + shared_timer->timer_direction_upward = 0; 190 + shared_timer->timer_direction_downward++; 191 + } else { 192 + shared_timer->timer_in_use -= 4; 193 + shared_timer->timer_direction_upward = 0; 194 + shared_timer->timer_direction_downward++; 195 + } 196 + 197 + if (shared_timer->timer_direction_upward > 3 ) { /* using history */ 198 + shared_timer->timer_in_use += 3; 199 + shared_timer->timer_direction_upward = 0; 200 + shared_timer->timer_direction_downward = 0; 201 + } 202 + if (shared_timer->timer_direction_downward > 5) { /* using history */ 203 + shared_timer->timer_in_use -= 4 ; 204 + shared_timer->timer_direction_downward = 0; 205 + shared_timer->timer_direction_upward = 0; 206 + } 207 + } 208 + 209 + /* boundary checking */ 210 + if (shared_timer->timer_in_use > NES_NIC_FAST_TIMER_HIGH) 211 + shared_timer->timer_in_use = NES_NIC_FAST_TIMER_HIGH; 212 + else if (shared_timer->timer_in_use < NES_NIC_FAST_TIMER_LOW) { 213 + shared_timer->timer_in_use = NES_NIC_FAST_TIMER_LOW; 214 + } 215 + 216 + nesdev->currcq_count = 0; 217 + 218 + spin_unlock_irqrestore(&nesadapter->periodic_timer_lock, flags); 219 + } 220 + 221 + 222 + /** 223 + * nes_init_adapter - initialize adapter 224 + */ 225 + struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) { 226 + struct nes_adapter *nesadapter = NULL; 227 + unsigned long num_pds; 228 + u32 u32temp; 229 + u32 port_count; 230 + u16 max_rq_wrs; 231 + u16 max_sq_wrs; 232 + u32 max_mr; 233 + u32 max_256pbl; 234 + u32 max_4kpbl; 235 + u32 max_qp; 236 + u32 max_irrq; 237 + u32 max_cq; 238 + u32 hte_index_mask; 239 + u32 adapter_size; 240 + u32 arp_table_size; 241 + u16 vendor_id; 242 + u8 OneG_Mode; 243 + u8 func_index; 244 + 245 + /* search the list of existing adapters */ 246 + list_for_each_entry(nesadapter, &nes_adapter_list, list) { 247 + nes_debug(NES_DBG_INIT, "Searching Adapter list for PCI devfn = 0x%X," 248 + " adapter PCI slot/bus = %u/%u, pci devices PCI slot/bus = %u/%u, .\n", 249 + nesdev->pcidev->devfn, 250 + PCI_SLOT(nesadapter->devfn), 251 + nesadapter->bus_number, 252 + PCI_SLOT(nesdev->pcidev->devfn), 253 + nesdev->pcidev->bus->number ); 254 + if ((PCI_SLOT(nesadapter->devfn) == PCI_SLOT(nesdev->pcidev->devfn)) && 255 + (nesadapter->bus_number == nesdev->pcidev->bus->number)) { 256 + nesadapter->ref_count++; 257 + return nesadapter; 258 + } 259 + } 260 + 261 + /* no adapter found */ 262 + num_pds = pci_resource_len(nesdev->pcidev, BAR_1) >> PAGE_SHIFT; 263 + if ((hw_rev != NE020_REV) && (hw_rev != NE020_REV1)) { 264 + nes_debug(NES_DBG_INIT, "NE020 driver detected unknown hardware revision 0x%x\n", 265 + hw_rev); 266 + return NULL; 267 + } 268 + 269 + nes_debug(NES_DBG_INIT, "Determine Soft Reset, QP_control=0x%x, CPU0=0x%x, CPU1=0x%x, CPU2=0x%x\n", 270 + nes_read_indexed(nesdev, NES_IDX_QP_CONTROL + PCI_FUNC(nesdev->pcidev->devfn) * 8), 271 + nes_read_indexed(nesdev, NES_IDX_INT_CPU_STATUS), 272 + nes_read_indexed(nesdev, NES_IDX_INT_CPU_STATUS + 4), 273 + nes_read_indexed(nesdev, NES_IDX_INT_CPU_STATUS + 8)); 274 + 275 + nes_debug(NES_DBG_INIT, "Reset and init NE020\n"); 276 + 277 + 278 + if ((port_count = nes_reset_adapter_ne020(nesdev, &OneG_Mode)) == 0) 279 + return NULL; 280 + if (nes_init_serdes(nesdev, hw_rev, port_count, OneG_Mode)) 281 + return NULL; 282 + nes_init_csr_ne020(nesdev, hw_rev, port_count); 283 + 284 + max_qp = nes_read_indexed(nesdev, NES_IDX_QP_CTX_SIZE); 285 + nes_debug(NES_DBG_INIT, "QP_CTX_SIZE=%u\n", max_qp); 286 + 287 + u32temp = nes_read_indexed(nesdev, NES_IDX_QUAD_HASH_TABLE_SIZE); 288 + if (max_qp > ((u32)1 << (u32temp & 0x001f))) { 289 + nes_debug(NES_DBG_INIT, "Reducing Max QPs to %u due to hash table size = 0x%08X\n", 290 + max_qp, u32temp); 291 + max_qp = (u32)1 << (u32temp & 0x001f); 292 + } 293 + 294 + hte_index_mask = ((u32)1 << ((u32temp & 0x001f)+1))-1; 295 + nes_debug(NES_DBG_INIT, "Max QP = %u, hte_index_mask = 0x%08X.\n", 296 + max_qp, hte_index_mask); 297 + 298 + u32temp = nes_read_indexed(nesdev, NES_IDX_IRRQ_COUNT); 299 + 300 + max_irrq = 1 << (u32temp & 0x001f); 301 + 302 + if (max_qp > max_irrq) { 303 + max_qp = max_irrq; 304 + nes_debug(NES_DBG_INIT, "Reducing Max QPs to %u due to Available Q1s.\n", 305 + max_qp); 306 + } 307 + 308 + /* there should be no reason to allocate more pds than qps */ 309 + if (num_pds > max_qp) 310 + num_pds = max_qp; 311 + 312 + u32temp = nes_read_indexed(nesdev, NES_IDX_MRT_SIZE); 313 + max_mr = (u32)8192 << (u32temp & 0x7); 314 + 315 + u32temp = nes_read_indexed(nesdev, NES_IDX_PBL_REGION_SIZE); 316 + max_256pbl = (u32)1 << (u32temp & 0x0000001f); 317 + max_4kpbl = (u32)1 << ((u32temp >> 16) & 0x0000001f); 318 + max_cq = nes_read_indexed(nesdev, NES_IDX_CQ_CTX_SIZE); 319 + 320 + u32temp = nes_read_indexed(nesdev, NES_IDX_ARP_CACHE_SIZE); 321 + arp_table_size = 1 << u32temp; 322 + 323 + adapter_size = (sizeof(struct nes_adapter) + 324 + (sizeof(unsigned long)-1)) & (~(sizeof(unsigned long)-1)); 325 + adapter_size += sizeof(unsigned long) * BITS_TO_LONGS(max_qp); 326 + adapter_size += sizeof(unsigned long) * BITS_TO_LONGS(max_mr); 327 + adapter_size += sizeof(unsigned long) * BITS_TO_LONGS(max_cq); 328 + adapter_size += sizeof(unsigned long) * BITS_TO_LONGS(num_pds); 329 + adapter_size += sizeof(unsigned long) * BITS_TO_LONGS(arp_table_size); 330 + adapter_size += sizeof(struct nes_qp **) * max_qp; 331 + 332 + /* allocate a new adapter struct */ 333 + nesadapter = kzalloc(adapter_size, GFP_KERNEL); 334 + if (nesadapter == NULL) { 335 + return NULL; 336 + } 337 + 338 + nes_debug(NES_DBG_INIT, "Allocating new nesadapter @ %p, size = %u (actual size = %u).\n", 339 + nesadapter, (u32)sizeof(struct nes_adapter), adapter_size); 340 + 341 + /* populate the new nesadapter */ 342 + nesadapter->devfn = nesdev->pcidev->devfn; 343 + nesadapter->bus_number = nesdev->pcidev->bus->number; 344 + nesadapter->ref_count = 1; 345 + nesadapter->timer_int_req = 0xffff0000; 346 + nesadapter->OneG_Mode = OneG_Mode; 347 + nesadapter->doorbell_start = nesdev->doorbell_region; 348 + 349 + /* nesadapter->tick_delta = clk_divisor; */ 350 + nesadapter->hw_rev = hw_rev; 351 + nesadapter->port_count = port_count; 352 + 353 + nesadapter->max_qp = max_qp; 354 + nesadapter->hte_index_mask = hte_index_mask; 355 + nesadapter->max_irrq = max_irrq; 356 + nesadapter->max_mr = max_mr; 357 + nesadapter->max_256pbl = max_256pbl - 1; 358 + nesadapter->max_4kpbl = max_4kpbl - 1; 359 + nesadapter->max_cq = max_cq; 360 + nesadapter->free_256pbl = max_256pbl - 1; 361 + nesadapter->free_4kpbl = max_4kpbl - 1; 362 + nesadapter->max_pd = num_pds; 363 + nesadapter->arp_table_size = arp_table_size; 364 + 365 + nesadapter->et_pkt_rate_low = NES_TIMER_ENABLE_LIMIT; 366 + if (nes_drv_opt & NES_DRV_OPT_DISABLE_INT_MOD) { 367 + nesadapter->et_use_adaptive_rx_coalesce = 0; 368 + nesadapter->timer_int_limit = NES_TIMER_INT_LIMIT; 369 + nesadapter->et_rx_coalesce_usecs_irq = interrupt_mod_interval; 370 + } else { 371 + nesadapter->et_use_adaptive_rx_coalesce = 1; 372 + nesadapter->timer_int_limit = NES_TIMER_INT_LIMIT_DYNAMIC; 373 + nesadapter->et_rx_coalesce_usecs_irq = 0; 374 + printk(PFX "%s: Using Adaptive Interrupt Moderation\n", __FUNCTION__); 375 + } 376 + /* Setup and enable the periodic timer */ 377 + if (nesadapter->et_rx_coalesce_usecs_irq) 378 + nes_write32(nesdev->regs+NES_PERIODIC_CONTROL, 0x80000000 | 379 + ((u32)(nesadapter->et_rx_coalesce_usecs_irq * 8))); 380 + else 381 + nes_write32(nesdev->regs+NES_PERIODIC_CONTROL, 0x00000000); 382 + 383 + nesadapter->base_pd = 1; 384 + 385 + nesadapter->device_cap_flags = 386 + IB_DEVICE_ZERO_STAG | IB_DEVICE_SEND_W_INV | IB_DEVICE_MEM_WINDOW; 387 + 388 + nesadapter->allocated_qps = (unsigned long *)&(((unsigned char *)nesadapter) 389 + [(sizeof(struct nes_adapter)+(sizeof(unsigned long)-1))&(~(sizeof(unsigned long)-1))]); 390 + nesadapter->allocated_cqs = &nesadapter->allocated_qps[BITS_TO_LONGS(max_qp)]; 391 + nesadapter->allocated_mrs = &nesadapter->allocated_cqs[BITS_TO_LONGS(max_cq)]; 392 + nesadapter->allocated_pds = &nesadapter->allocated_mrs[BITS_TO_LONGS(max_mr)]; 393 + nesadapter->allocated_arps = &nesadapter->allocated_pds[BITS_TO_LONGS(num_pds)]; 394 + nesadapter->qp_table = (struct nes_qp **)(&nesadapter->allocated_arps[BITS_TO_LONGS(arp_table_size)]); 395 + 396 + 397 + /* mark the usual suspect QPs and CQs as in use */ 398 + for (u32temp = 0; u32temp < NES_FIRST_QPN; u32temp++) { 399 + set_bit(u32temp, nesadapter->allocated_qps); 400 + set_bit(u32temp, nesadapter->allocated_cqs); 401 + } 402 + 403 + for (u32temp = 0; u32temp < 20; u32temp++) 404 + set_bit(u32temp, nesadapter->allocated_pds); 405 + u32temp = nes_read_indexed(nesdev, NES_IDX_QP_MAX_CFG_SIZES); 406 + 407 + max_rq_wrs = ((u32temp >> 8) & 3); 408 + switch (max_rq_wrs) { 409 + case 0: 410 + max_rq_wrs = 4; 411 + break; 412 + case 1: 413 + max_rq_wrs = 16; 414 + break; 415 + case 2: 416 + max_rq_wrs = 32; 417 + break; 418 + case 3: 419 + max_rq_wrs = 512; 420 + break; 421 + } 422 + 423 + max_sq_wrs = (u32temp & 3); 424 + switch (max_sq_wrs) { 425 + case 0: 426 + max_sq_wrs = 4; 427 + break; 428 + case 1: 429 + max_sq_wrs = 16; 430 + break; 431 + case 2: 432 + max_sq_wrs = 32; 433 + break; 434 + case 3: 435 + max_sq_wrs = 512; 436 + break; 437 + } 438 + nesadapter->max_qp_wr = min(max_rq_wrs, max_sq_wrs); 439 + nesadapter->max_irrq_wr = (u32temp >> 16) & 3; 440 + 441 + nesadapter->max_sge = 4; 442 + nesadapter->max_cqe = 32767; 443 + 444 + if (nes_read_eeprom_values(nesdev, nesadapter)) { 445 + printk(KERN_ERR PFX "Unable to read EEPROM data.\n"); 446 + kfree(nesadapter); 447 + return NULL; 448 + } 449 + 450 + u32temp = nes_read_indexed(nesdev, NES_IDX_TCP_TIMER_CONFIG); 451 + nes_write_indexed(nesdev, NES_IDX_TCP_TIMER_CONFIG, 452 + (u32temp & 0xff000000) | (nesadapter->tcp_timer_core_clk_divisor & 0x00ffffff)); 453 + 454 + /* setup port configuration */ 455 + if (nesadapter->port_count == 1) { 456 + u32temp = 0x00000000; 457 + if (nes_drv_opt & NES_DRV_OPT_DUAL_LOGICAL_PORT) 458 + nes_write_indexed(nesdev, NES_IDX_TX_POOL_SIZE, 0x00000002); 459 + else 460 + nes_write_indexed(nesdev, NES_IDX_TX_POOL_SIZE, 0x00000003); 461 + } else { 462 + if (nesadapter->port_count == 2) 463 + u32temp = 0x00000044; 464 + else 465 + u32temp = 0x000000e4; 466 + nes_write_indexed(nesdev, NES_IDX_TX_POOL_SIZE, 0x00000003); 467 + } 468 + 469 + nes_write_indexed(nesdev, NES_IDX_NIC_LOGPORT_TO_PHYPORT, u32temp); 470 + nes_debug(NES_DBG_INIT, "Probe time, LOG2PHY=%u\n", 471 + nes_read_indexed(nesdev, NES_IDX_NIC_LOGPORT_TO_PHYPORT)); 472 + 473 + spin_lock_init(&nesadapter->resource_lock); 474 + spin_lock_init(&nesadapter->phy_lock); 475 + spin_lock_init(&nesadapter->pbl_lock); 476 + spin_lock_init(&nesadapter->periodic_timer_lock); 477 + 478 + INIT_LIST_HEAD(&nesadapter->nesvnic_list[0]); 479 + INIT_LIST_HEAD(&nesadapter->nesvnic_list[1]); 480 + INIT_LIST_HEAD(&nesadapter->nesvnic_list[2]); 481 + INIT_LIST_HEAD(&nesadapter->nesvnic_list[3]); 482 + 483 + if ((!nesadapter->OneG_Mode) && (nesadapter->port_count == 2)) { 484 + u32 pcs_control_status0, pcs_control_status1; 485 + u32 reset_value; 486 + u32 i = 0; 487 + u32 int_cnt = 0; 488 + u32 ext_cnt = 0; 489 + unsigned long flags; 490 + u32 j = 0; 491 + 492 + pcs_control_status0 = nes_read_indexed(nesdev, 493 + NES_IDX_PHY_PCS_CONTROL_STATUS0); 494 + pcs_control_status1 = nes_read_indexed(nesdev, 495 + NES_IDX_PHY_PCS_CONTROL_STATUS0 + 0x200); 496 + 497 + for (i = 0; i < NES_MAX_LINK_CHECK; i++) { 498 + pcs_control_status0 = nes_read_indexed(nesdev, 499 + NES_IDX_PHY_PCS_CONTROL_STATUS0); 500 + pcs_control_status1 = nes_read_indexed(nesdev, 501 + NES_IDX_PHY_PCS_CONTROL_STATUS0 + 0x200); 502 + if ((0x0F000100 == (pcs_control_status0 & 0x0F000100)) 503 + || (0x0F000100 == (pcs_control_status1 & 0x0F000100))) 504 + int_cnt++; 505 + msleep(1); 506 + } 507 + if (int_cnt > 1) { 508 + spin_lock_irqsave(&nesadapter->phy_lock, flags); 509 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, 0x0000F088); 510 + mh_detected++; 511 + reset_value = nes_read32(nesdev->regs+NES_SOFTWARE_RESET); 512 + reset_value |= 0x0000003d; 513 + nes_write32(nesdev->regs+NES_SOFTWARE_RESET, reset_value); 514 + 515 + while (((nes_read32(nesdev->regs+NES_SOFTWARE_RESET) 516 + & 0x00000040) != 0x00000040) && (j++ < 5000)); 517 + spin_unlock_irqrestore(&nesadapter->phy_lock, flags); 518 + 519 + pcs_control_status0 = nes_read_indexed(nesdev, 520 + NES_IDX_PHY_PCS_CONTROL_STATUS0); 521 + pcs_control_status1 = nes_read_indexed(nesdev, 522 + NES_IDX_PHY_PCS_CONTROL_STATUS0 + 0x200); 523 + 524 + for (i = 0; i < NES_MAX_LINK_CHECK; i++) { 525 + pcs_control_status0 = nes_read_indexed(nesdev, 526 + NES_IDX_PHY_PCS_CONTROL_STATUS0); 527 + pcs_control_status1 = nes_read_indexed(nesdev, 528 + NES_IDX_PHY_PCS_CONTROL_STATUS0 + 0x200); 529 + if ((0x0F000100 == (pcs_control_status0 & 0x0F000100)) 530 + || (0x0F000100 == (pcs_control_status1 & 0x0F000100))) { 531 + if (++ext_cnt > int_cnt) { 532 + spin_lock_irqsave(&nesadapter->phy_lock, flags); 533 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, 534 + 0x0000F0C8); 535 + mh_detected++; 536 + reset_value = nes_read32(nesdev->regs+NES_SOFTWARE_RESET); 537 + reset_value |= 0x0000003d; 538 + nes_write32(nesdev->regs+NES_SOFTWARE_RESET, reset_value); 539 + 540 + while (((nes_read32(nesdev->regs+NES_SOFTWARE_RESET) 541 + & 0x00000040) != 0x00000040) && (j++ < 5000)); 542 + spin_unlock_irqrestore(&nesadapter->phy_lock, flags); 543 + break; 544 + } 545 + } 546 + msleep(1); 547 + } 548 + } 549 + } 550 + 551 + if (nesadapter->hw_rev == NE020_REV) { 552 + init_timer(&nesadapter->mh_timer); 553 + nesadapter->mh_timer.function = nes_mh_fix; 554 + nesadapter->mh_timer.expires = jiffies + (HZ/5); /* 1 second */ 555 + nesadapter->mh_timer.data = (unsigned long)nesdev; 556 + add_timer(&nesadapter->mh_timer); 557 + } else { 558 + nes_write32(nesdev->regs+NES_INTF_INT_STAT, 0x0f000000); 559 + } 560 + 561 + init_timer(&nesadapter->lc_timer); 562 + nesadapter->lc_timer.function = nes_clc; 563 + nesadapter->lc_timer.expires = jiffies + 3600 * HZ; /* 1 hour */ 564 + nesadapter->lc_timer.data = (unsigned long)nesdev; 565 + add_timer(&nesadapter->lc_timer); 566 + 567 + list_add_tail(&nesadapter->list, &nes_adapter_list); 568 + 569 + for (func_index = 0; func_index < 8; func_index++) { 570 + pci_bus_read_config_word(nesdev->pcidev->bus, 571 + PCI_DEVFN(PCI_SLOT(nesdev->pcidev->devfn), 572 + func_index), 0, &vendor_id); 573 + if (vendor_id == 0xffff) 574 + break; 575 + } 576 + nes_debug(NES_DBG_INIT, "%s %d functions found for %s.\n", __FUNCTION__, 577 + func_index, pci_name(nesdev->pcidev)); 578 + nesadapter->adapter_fcn_count = func_index; 579 + 580 + return nesadapter; 581 + } 582 + 583 + 584 + /** 585 + * nes_reset_adapter_ne020 586 + */ 587 + unsigned int nes_reset_adapter_ne020(struct nes_device *nesdev, u8 *OneG_Mode) 588 + { 589 + u32 port_count; 590 + u32 u32temp; 591 + u32 i; 592 + 593 + u32temp = nes_read32(nesdev->regs+NES_SOFTWARE_RESET); 594 + port_count = ((u32temp & 0x00000300) >> 8) + 1; 595 + /* TODO: assuming that both SERDES are set the same for now */ 596 + *OneG_Mode = (u32temp & 0x00003c00) ? 0 : 1; 597 + nes_debug(NES_DBG_INIT, "Initial Software Reset = 0x%08X, port_count=%u\n", 598 + u32temp, port_count); 599 + if (*OneG_Mode) 600 + nes_debug(NES_DBG_INIT, "Running in 1G mode.\n"); 601 + u32temp &= 0xff00ffc0; 602 + switch (port_count) { 603 + case 1: 604 + u32temp |= 0x00ee0000; 605 + break; 606 + case 2: 607 + u32temp |= 0x00cc0000; 608 + break; 609 + case 4: 610 + u32temp |= 0x00000000; 611 + break; 612 + default: 613 + return 0; 614 + break; 615 + } 616 + 617 + /* check and do full reset if needed */ 618 + if (nes_read_indexed(nesdev, NES_IDX_QP_CONTROL+(PCI_FUNC(nesdev->pcidev->devfn)*8))) { 619 + nes_debug(NES_DBG_INIT, "Issuing Full Soft reset = 0x%08X\n", u32temp | 0xd); 620 + nes_write32(nesdev->regs+NES_SOFTWARE_RESET, u32temp | 0xd); 621 + 622 + i = 0; 623 + while (((nes_read32(nesdev->regs+NES_SOFTWARE_RESET) & 0x00000040) == 0) && i++ < 10000) 624 + mdelay(1); 625 + if (i >= 10000) { 626 + nes_debug(NES_DBG_INIT, "Did not see full soft reset done.\n"); 627 + return 0; 628 + } 629 + } 630 + 631 + /* port reset */ 632 + switch (port_count) { 633 + case 1: 634 + u32temp |= 0x00ee0010; 635 + break; 636 + case 2: 637 + u32temp |= 0x00cc0030; 638 + break; 639 + case 4: 640 + u32temp |= 0x00000030; 641 + break; 642 + } 643 + 644 + nes_debug(NES_DBG_INIT, "Issuing Port Soft reset = 0x%08X\n", u32temp | 0xd); 645 + nes_write32(nesdev->regs+NES_SOFTWARE_RESET, u32temp | 0xd); 646 + 647 + i = 0; 648 + while (((nes_read32(nesdev->regs+NES_SOFTWARE_RESET) & 0x00000040) == 0) && i++ < 10000) 649 + mdelay(1); 650 + if (i >= 10000) { 651 + nes_debug(NES_DBG_INIT, "Did not see port soft reset done.\n"); 652 + return 0; 653 + } 654 + 655 + /* serdes 0 */ 656 + i = 0; 657 + while (((u32temp = (nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0) 658 + & 0x0000000f)) != 0x0000000f) && i++ < 5000) 659 + mdelay(1); 660 + if (i >= 5000) { 661 + nes_debug(NES_DBG_INIT, "Serdes 0 not ready, status=%x\n", u32temp); 662 + return 0; 663 + } 664 + 665 + /* serdes 1 */ 666 + if (port_count > 1) { 667 + i = 0; 668 + while (((u32temp = (nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS1) 669 + & 0x0000000f)) != 0x0000000f) && i++ < 5000) 670 + mdelay(1); 671 + if (i >= 5000) { 672 + nes_debug(NES_DBG_INIT, "Serdes 1 not ready, status=%x\n", u32temp); 673 + return 0; 674 + } 675 + } 676 + 677 + 678 + 679 + i = 0; 680 + while ((nes_read_indexed(nesdev, NES_IDX_INT_CPU_STATUS) != 0x80) && i++ < 10000) 681 + mdelay(1); 682 + if (i >= 10000) { 683 + printk(KERN_ERR PFX "Internal CPU not ready, status = %02X\n", 684 + nes_read_indexed(nesdev, NES_IDX_INT_CPU_STATUS)); 685 + return 0; 686 + } 687 + 688 + return port_count; 689 + } 690 + 691 + 692 + /** 693 + * nes_init_serdes 694 + */ 695 + int nes_init_serdes(struct nes_device *nesdev, u8 hw_rev, u8 port_count, u8 OneG_Mode) 696 + { 697 + int i; 698 + u32 u32temp; 699 + 700 + if (hw_rev != NE020_REV) { 701 + /* init serdes 0 */ 702 + 703 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF); 704 + if (!OneG_Mode) 705 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE0, 0x11110000); 706 + if (port_count > 1) { 707 + /* init serdes 1 */ 708 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000000FF); 709 + if (!OneG_Mode) 710 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE1, 0x11110000); 711 + } 712 + } else { 713 + /* init serdes 0 */ 714 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, 0x00000008); 715 + i = 0; 716 + while (((u32temp = (nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0) 717 + & 0x0000000f)) != 0x0000000f) && i++ < 5000) 718 + mdelay(1); 719 + if (i >= 5000) { 720 + nes_debug(NES_DBG_PHY, "Init: serdes 0 not ready, status=%x\n", u32temp); 721 + return 1; 722 + } 723 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_EMP0, 0x000bdef7); 724 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_DRIVE0, 0x9ce73000); 725 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_RX_MODE0, 0x0ff00000); 726 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_RX_SIGDET0, 0x00000000); 727 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_BYPASS0, 0x00000000); 728 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_LOOPBACK_CONTROL0, 0x00000000); 729 + if (OneG_Mode) 730 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_RX_EQ_CONTROL0, 0xf0182222); 731 + else 732 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_RX_EQ_CONTROL0, 0xf0042222); 733 + 734 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000ff); 735 + if (port_count > 1) { 736 + /* init serdes 1 */ 737 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, 0x00000048); 738 + i = 0; 739 + while (((u32temp = (nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS1) 740 + & 0x0000000f)) != 0x0000000f) && (i++ < 5000)) 741 + mdelay(1); 742 + if (i >= 5000) { 743 + printk("%s: Init: serdes 1 not ready, status=%x\n", __FUNCTION__, u32temp); 744 + /* return 1; */ 745 + } 746 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_EMP1, 0x000bdef7); 747 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_DRIVE1, 0x9ce73000); 748 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_RX_MODE1, 0x0ff00000); 749 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_RX_SIGDET1, 0x00000000); 750 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_BYPASS1, 0x00000000); 751 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_LOOPBACK_CONTROL1, 0x00000000); 752 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_RX_EQ_CONTROL1, 0xf0002222); 753 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000000ff); 754 + } 755 + } 756 + return 0; 757 + } 758 + 759 + 760 + /** 761 + * nes_init_csr_ne020 762 + * Initialize registers for ne020 hardware 763 + */ 764 + void nes_init_csr_ne020(struct nes_device *nesdev, u8 hw_rev, u8 port_count) 765 + { 766 + u32 u32temp; 767 + 768 + nes_debug(NES_DBG_INIT, "port_count=%d\n", port_count); 769 + 770 + nes_write_indexed(nesdev, 0x000001E4, 0x00000007); 771 + /* nes_write_indexed(nesdev, 0x000001E8, 0x000208C4); */ 772 + nes_write_indexed(nesdev, 0x000001E8, 0x00020874); 773 + nes_write_indexed(nesdev, 0x000001D8, 0x00048002); 774 + /* nes_write_indexed(nesdev, 0x000001D8, 0x0004B002); */ 775 + nes_write_indexed(nesdev, 0x000001FC, 0x00050005); 776 + nes_write_indexed(nesdev, 0x00000600, 0x55555555); 777 + nes_write_indexed(nesdev, 0x00000604, 0x55555555); 778 + 779 + /* TODO: move these MAC register settings to NIC bringup */ 780 + nes_write_indexed(nesdev, 0x00002000, 0x00000001); 781 + nes_write_indexed(nesdev, 0x00002004, 0x00000001); 782 + nes_write_indexed(nesdev, 0x00002008, 0x0000FFFF); 783 + nes_write_indexed(nesdev, 0x0000200C, 0x00000001); 784 + nes_write_indexed(nesdev, 0x00002010, 0x000003c1); 785 + nes_write_indexed(nesdev, 0x0000201C, 0x75345678); 786 + if (port_count > 1) { 787 + nes_write_indexed(nesdev, 0x00002200, 0x00000001); 788 + nes_write_indexed(nesdev, 0x00002204, 0x00000001); 789 + nes_write_indexed(nesdev, 0x00002208, 0x0000FFFF); 790 + nes_write_indexed(nesdev, 0x0000220C, 0x00000001); 791 + nes_write_indexed(nesdev, 0x00002210, 0x000003c1); 792 + nes_write_indexed(nesdev, 0x0000221C, 0x75345678); 793 + nes_write_indexed(nesdev, 0x00000908, 0x20000001); 794 + } 795 + if (port_count > 2) { 796 + nes_write_indexed(nesdev, 0x00002400, 0x00000001); 797 + nes_write_indexed(nesdev, 0x00002404, 0x00000001); 798 + nes_write_indexed(nesdev, 0x00002408, 0x0000FFFF); 799 + nes_write_indexed(nesdev, 0x0000240C, 0x00000001); 800 + nes_write_indexed(nesdev, 0x00002410, 0x000003c1); 801 + nes_write_indexed(nesdev, 0x0000241C, 0x75345678); 802 + nes_write_indexed(nesdev, 0x00000910, 0x20000001); 803 + 804 + nes_write_indexed(nesdev, 0x00002600, 0x00000001); 805 + nes_write_indexed(nesdev, 0x00002604, 0x00000001); 806 + nes_write_indexed(nesdev, 0x00002608, 0x0000FFFF); 807 + nes_write_indexed(nesdev, 0x0000260C, 0x00000001); 808 + nes_write_indexed(nesdev, 0x00002610, 0x000003c1); 809 + nes_write_indexed(nesdev, 0x0000261C, 0x75345678); 810 + nes_write_indexed(nesdev, 0x00000918, 0x20000001); 811 + } 812 + 813 + nes_write_indexed(nesdev, 0x00005000, 0x00018000); 814 + /* nes_write_indexed(nesdev, 0x00005000, 0x00010000); */ 815 + nes_write_indexed(nesdev, 0x00005004, 0x00020001); 816 + nes_write_indexed(nesdev, 0x00005008, 0x1F1F1F1F); 817 + nes_write_indexed(nesdev, 0x00005010, 0x1F1F1F1F); 818 + nes_write_indexed(nesdev, 0x00005018, 0x1F1F1F1F); 819 + nes_write_indexed(nesdev, 0x00005020, 0x1F1F1F1F); 820 + nes_write_indexed(nesdev, 0x00006090, 0xFFFFFFFF); 821 + 822 + /* TODO: move this to code, get from EEPROM */ 823 + nes_write_indexed(nesdev, 0x00000900, 0x20000001); 824 + nes_write_indexed(nesdev, 0x000060C0, 0x0000028e); 825 + nes_write_indexed(nesdev, 0x000060C8, 0x00000020); 826 + // 827 + nes_write_indexed(nesdev, 0x000001EC, 0x7b2625a0); 828 + /* nes_write_indexed(nesdev, 0x000001EC, 0x5f2625a0); */ 829 + 830 + if (hw_rev != NE020_REV) { 831 + u32temp = nes_read_indexed(nesdev, 0x000008e8); 832 + u32temp |= 0x80000000; 833 + nes_write_indexed(nesdev, 0x000008e8, u32temp); 834 + u32temp = nes_read_indexed(nesdev, 0x000021f8); 835 + u32temp &= 0x7fffffff; 836 + u32temp |= 0x7fff0010; 837 + nes_write_indexed(nesdev, 0x000021f8, u32temp); 838 + } 839 + } 840 + 841 + 842 + /** 843 + * nes_destroy_adapter - destroy the adapter structure 844 + */ 845 + void nes_destroy_adapter(struct nes_adapter *nesadapter) 846 + { 847 + struct nes_adapter *tmp_adapter; 848 + 849 + list_for_each_entry(tmp_adapter, &nes_adapter_list, list) { 850 + nes_debug(NES_DBG_SHUTDOWN, "Nes Adapter list entry = 0x%p.\n", 851 + tmp_adapter); 852 + } 853 + 854 + nesadapter->ref_count--; 855 + if (!nesadapter->ref_count) { 856 + if (nesadapter->hw_rev == NE020_REV) { 857 + del_timer(&nesadapter->mh_timer); 858 + } 859 + del_timer(&nesadapter->lc_timer); 860 + 861 + list_del(&nesadapter->list); 862 + kfree(nesadapter); 863 + } 864 + } 865 + 866 + 867 + /** 868 + * nes_init_cqp 869 + */ 870 + int nes_init_cqp(struct nes_device *nesdev) 871 + { 872 + struct nes_adapter *nesadapter = nesdev->nesadapter; 873 + struct nes_hw_cqp_qp_context *cqp_qp_context; 874 + struct nes_hw_cqp_wqe *cqp_wqe; 875 + struct nes_hw_ceq *ceq; 876 + struct nes_hw_ceq *nic_ceq; 877 + struct nes_hw_aeq *aeq; 878 + void *vmem; 879 + dma_addr_t pmem; 880 + u32 count=0; 881 + u32 cqp_head; 882 + u64 u64temp; 883 + u32 u32temp; 884 + 885 + /* allocate CQP memory */ 886 + /* Need to add max_cq to the aeq size once cq overflow checking is added back */ 887 + /* SQ is 512 byte aligned, others are 256 byte aligned */ 888 + nesdev->cqp_mem_size = 512 + 889 + (sizeof(struct nes_hw_cqp_wqe) * NES_CQP_SQ_SIZE) + 890 + (sizeof(struct nes_hw_cqe) * NES_CCQ_SIZE) + 891 + max(((u32)sizeof(struct nes_hw_ceqe) * NES_CCEQ_SIZE), (u32)256) + 892 + max(((u32)sizeof(struct nes_hw_ceqe) * NES_NIC_CEQ_SIZE), (u32)256) + 893 + (sizeof(struct nes_hw_aeqe) * nesadapter->max_qp) + 894 + sizeof(struct nes_hw_cqp_qp_context); 895 + 896 + nesdev->cqp_vbase = pci_alloc_consistent(nesdev->pcidev, nesdev->cqp_mem_size, 897 + &nesdev->cqp_pbase); 898 + if (!nesdev->cqp_vbase) { 899 + nes_debug(NES_DBG_INIT, "Unable to allocate memory for host descriptor rings\n"); 900 + return -ENOMEM; 901 + } 902 + memset(nesdev->cqp_vbase, 0, nesdev->cqp_mem_size); 903 + 904 + /* Allocate a twice the number of CQP requests as the SQ size */ 905 + nesdev->nes_cqp_requests = kzalloc(sizeof(struct nes_cqp_request) * 906 + 2 * NES_CQP_SQ_SIZE, GFP_KERNEL); 907 + if (nesdev->nes_cqp_requests == NULL) { 908 + nes_debug(NES_DBG_INIT, "Unable to allocate memory CQP request entries.\n"); 909 + pci_free_consistent(nesdev->pcidev, nesdev->cqp_mem_size, nesdev->cqp.sq_vbase, 910 + nesdev->cqp.sq_pbase); 911 + return -ENOMEM; 912 + } 913 + 914 + nes_debug(NES_DBG_INIT, "Allocated CQP structures at %p (phys = %016lX), size = %u.\n", 915 + nesdev->cqp_vbase, (unsigned long)nesdev->cqp_pbase, nesdev->cqp_mem_size); 916 + 917 + spin_lock_init(&nesdev->cqp.lock); 918 + init_waitqueue_head(&nesdev->cqp.waitq); 919 + 920 + /* Setup Various Structures */ 921 + vmem = (void *)(((unsigned long)nesdev->cqp_vbase + (512 - 1)) & 922 + ~(unsigned long)(512 - 1)); 923 + pmem = (dma_addr_t)(((unsigned long long)nesdev->cqp_pbase + (512 - 1)) & 924 + ~(unsigned long long)(512 - 1)); 925 + 926 + nesdev->cqp.sq_vbase = vmem; 927 + nesdev->cqp.sq_pbase = pmem; 928 + nesdev->cqp.sq_size = NES_CQP_SQ_SIZE; 929 + nesdev->cqp.sq_head = 0; 930 + nesdev->cqp.sq_tail = 0; 931 + nesdev->cqp.qp_id = PCI_FUNC(nesdev->pcidev->devfn); 932 + 933 + vmem += (sizeof(struct nes_hw_cqp_wqe) * nesdev->cqp.sq_size); 934 + pmem += (sizeof(struct nes_hw_cqp_wqe) * nesdev->cqp.sq_size); 935 + 936 + nesdev->ccq.cq_vbase = vmem; 937 + nesdev->ccq.cq_pbase = pmem; 938 + nesdev->ccq.cq_size = NES_CCQ_SIZE; 939 + nesdev->ccq.cq_head = 0; 940 + nesdev->ccq.ce_handler = nes_cqp_ce_handler; 941 + nesdev->ccq.cq_number = PCI_FUNC(nesdev->pcidev->devfn); 942 + 943 + vmem += (sizeof(struct nes_hw_cqe) * nesdev->ccq.cq_size); 944 + pmem += (sizeof(struct nes_hw_cqe) * nesdev->ccq.cq_size); 945 + 946 + nesdev->ceq_index = PCI_FUNC(nesdev->pcidev->devfn); 947 + ceq = &nesadapter->ceq[nesdev->ceq_index]; 948 + ceq->ceq_vbase = vmem; 949 + ceq->ceq_pbase = pmem; 950 + ceq->ceq_size = NES_CCEQ_SIZE; 951 + ceq->ceq_head = 0; 952 + 953 + vmem += max(((u32)sizeof(struct nes_hw_ceqe) * ceq->ceq_size), (u32)256); 954 + pmem += max(((u32)sizeof(struct nes_hw_ceqe) * ceq->ceq_size), (u32)256); 955 + 956 + nesdev->nic_ceq_index = PCI_FUNC(nesdev->pcidev->devfn) + 8; 957 + nic_ceq = &nesadapter->ceq[nesdev->nic_ceq_index]; 958 + nic_ceq->ceq_vbase = vmem; 959 + nic_ceq->ceq_pbase = pmem; 960 + nic_ceq->ceq_size = NES_NIC_CEQ_SIZE; 961 + nic_ceq->ceq_head = 0; 962 + 963 + vmem += max(((u32)sizeof(struct nes_hw_ceqe) * nic_ceq->ceq_size), (u32)256); 964 + pmem += max(((u32)sizeof(struct nes_hw_ceqe) * nic_ceq->ceq_size), (u32)256); 965 + 966 + aeq = &nesadapter->aeq[PCI_FUNC(nesdev->pcidev->devfn)]; 967 + aeq->aeq_vbase = vmem; 968 + aeq->aeq_pbase = pmem; 969 + aeq->aeq_size = nesadapter->max_qp; 970 + aeq->aeq_head = 0; 971 + 972 + /* Setup QP Context */ 973 + vmem += (sizeof(struct nes_hw_aeqe) * aeq->aeq_size); 974 + pmem += (sizeof(struct nes_hw_aeqe) * aeq->aeq_size); 975 + 976 + cqp_qp_context = vmem; 977 + cqp_qp_context->context_words[0] = 978 + cpu_to_le32((PCI_FUNC(nesdev->pcidev->devfn) << 12) + (2 << 10)); 979 + cqp_qp_context->context_words[1] = 0; 980 + cqp_qp_context->context_words[2] = cpu_to_le32((u32)nesdev->cqp.sq_pbase); 981 + cqp_qp_context->context_words[3] = cpu_to_le32(((u64)nesdev->cqp.sq_pbase) >> 32); 982 + 983 + 984 + /* Write the address to Create CQP */ 985 + if ((sizeof(dma_addr_t) > 4)) { 986 + nes_write_indexed(nesdev, 987 + NES_IDX_CREATE_CQP_HIGH + (PCI_FUNC(nesdev->pcidev->devfn) * 8), 988 + ((u64)pmem) >> 32); 989 + } else { 990 + nes_write_indexed(nesdev, 991 + NES_IDX_CREATE_CQP_HIGH + (PCI_FUNC(nesdev->pcidev->devfn) * 8), 0); 992 + } 993 + nes_write_indexed(nesdev, 994 + NES_IDX_CREATE_CQP_LOW + (PCI_FUNC(nesdev->pcidev->devfn) * 8), 995 + (u32)pmem); 996 + 997 + INIT_LIST_HEAD(&nesdev->cqp_avail_reqs); 998 + INIT_LIST_HEAD(&nesdev->cqp_pending_reqs); 999 + 1000 + for (count = 0; count < 2*NES_CQP_SQ_SIZE; count++) { 1001 + init_waitqueue_head(&nesdev->nes_cqp_requests[count].waitq); 1002 + list_add_tail(&nesdev->nes_cqp_requests[count].list, &nesdev->cqp_avail_reqs); 1003 + } 1004 + 1005 + /* Write Create CCQ WQE */ 1006 + cqp_head = nesdev->cqp.sq_head++; 1007 + cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head]; 1008 + nes_fill_init_cqp_wqe(cqp_wqe, nesdev); 1009 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX, 1010 + (NES_CQP_CREATE_CQ | NES_CQP_CQ_CEQ_VALID | 1011 + NES_CQP_CQ_CHK_OVERFLOW | ((u32)nesdev->ccq.cq_size << 16))); 1012 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_ID_IDX, 1013 + (nesdev->ccq.cq_number | 1014 + ((u32)nesdev->ceq_index << 16))); 1015 + u64temp = (u64)nesdev->ccq.cq_pbase; 1016 + set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_CQ_WQE_PBL_LOW_IDX, u64temp); 1017 + cqp_wqe->wqe_words[NES_CQP_CQ_WQE_CQ_CONTEXT_HIGH_IDX] = 0; 1018 + u64temp = (unsigned long)&nesdev->ccq; 1019 + cqp_wqe->wqe_words[NES_CQP_CQ_WQE_CQ_CONTEXT_LOW_IDX] = 1020 + cpu_to_le32((u32)(u64temp >> 1)); 1021 + cqp_wqe->wqe_words[NES_CQP_CQ_WQE_CQ_CONTEXT_HIGH_IDX] = 1022 + cpu_to_le32(((u32)((u64temp) >> 33)) & 0x7FFFFFFF); 1023 + cqp_wqe->wqe_words[NES_CQP_CQ_WQE_DOORBELL_INDEX_HIGH_IDX] = 0; 1024 + 1025 + /* Write Create CEQ WQE */ 1026 + cqp_head = nesdev->cqp.sq_head++; 1027 + cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head]; 1028 + nes_fill_init_cqp_wqe(cqp_wqe, nesdev); 1029 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX, 1030 + (NES_CQP_CREATE_CEQ + ((u32)nesdev->ceq_index << 8))); 1031 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_CEQ_WQE_ELEMENT_COUNT_IDX, ceq->ceq_size); 1032 + u64temp = (u64)ceq->ceq_pbase; 1033 + set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_CQ_WQE_PBL_LOW_IDX, u64temp); 1034 + 1035 + /* Write Create AEQ WQE */ 1036 + cqp_head = nesdev->cqp.sq_head++; 1037 + cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head]; 1038 + nes_fill_init_cqp_wqe(cqp_wqe, nesdev); 1039 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX, 1040 + (NES_CQP_CREATE_AEQ + ((u32)PCI_FUNC(nesdev->pcidev->devfn) << 8))); 1041 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_AEQ_WQE_ELEMENT_COUNT_IDX, aeq->aeq_size); 1042 + u64temp = (u64)aeq->aeq_pbase; 1043 + set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_CQ_WQE_PBL_LOW_IDX, u64temp); 1044 + 1045 + /* Write Create NIC CEQ WQE */ 1046 + cqp_head = nesdev->cqp.sq_head++; 1047 + cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head]; 1048 + nes_fill_init_cqp_wqe(cqp_wqe, nesdev); 1049 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX, 1050 + (NES_CQP_CREATE_CEQ + ((u32)nesdev->nic_ceq_index << 8))); 1051 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_CEQ_WQE_ELEMENT_COUNT_IDX, nic_ceq->ceq_size); 1052 + u64temp = (u64)nic_ceq->ceq_pbase; 1053 + set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_CQ_WQE_PBL_LOW_IDX, u64temp); 1054 + 1055 + /* Poll until CCQP done */ 1056 + count = 0; 1057 + do { 1058 + if (count++ > 1000) { 1059 + printk(KERN_ERR PFX "Error creating CQP\n"); 1060 + pci_free_consistent(nesdev->pcidev, nesdev->cqp_mem_size, 1061 + nesdev->cqp_vbase, nesdev->cqp_pbase); 1062 + return -1; 1063 + } 1064 + udelay(10); 1065 + } while (!(nes_read_indexed(nesdev, 1066 + NES_IDX_QP_CONTROL + (PCI_FUNC(nesdev->pcidev->devfn) * 8)) & (1 << 8))); 1067 + 1068 + nes_debug(NES_DBG_INIT, "CQP Status = 0x%08X\n", nes_read_indexed(nesdev, 1069 + NES_IDX_QP_CONTROL+(PCI_FUNC(nesdev->pcidev->devfn)*8))); 1070 + 1071 + u32temp = 0x04800000; 1072 + nes_write32(nesdev->regs+NES_WQE_ALLOC, u32temp | nesdev->cqp.qp_id); 1073 + 1074 + /* wait for the CCQ, CEQ, and AEQ to get created */ 1075 + count = 0; 1076 + do { 1077 + if (count++ > 1000) { 1078 + printk(KERN_ERR PFX "Error creating CCQ, CEQ, and AEQ\n"); 1079 + pci_free_consistent(nesdev->pcidev, nesdev->cqp_mem_size, 1080 + nesdev->cqp_vbase, nesdev->cqp_pbase); 1081 + return -1; 1082 + } 1083 + udelay(10); 1084 + } while (((nes_read_indexed(nesdev, 1085 + NES_IDX_QP_CONTROL+(PCI_FUNC(nesdev->pcidev->devfn)*8)) & (15<<8)) != (15<<8))); 1086 + 1087 + /* dump the QP status value */ 1088 + nes_debug(NES_DBG_INIT, "QP Status = 0x%08X\n", nes_read_indexed(nesdev, 1089 + NES_IDX_QP_CONTROL+(PCI_FUNC(nesdev->pcidev->devfn)*8))); 1090 + 1091 + nesdev->cqp.sq_tail++; 1092 + 1093 + return 0; 1094 + } 1095 + 1096 + 1097 + /** 1098 + * nes_destroy_cqp 1099 + */ 1100 + int nes_destroy_cqp(struct nes_device *nesdev) 1101 + { 1102 + struct nes_hw_cqp_wqe *cqp_wqe; 1103 + u32 count = 0; 1104 + u32 cqp_head; 1105 + unsigned long flags; 1106 + 1107 + do { 1108 + if (count++ > 1000) 1109 + break; 1110 + udelay(10); 1111 + } while (!(nesdev->cqp.sq_head == nesdev->cqp.sq_tail)); 1112 + 1113 + /* Reset CCQ */ 1114 + nes_write32(nesdev->regs+NES_CQE_ALLOC, NES_CQE_ALLOC_RESET | 1115 + nesdev->ccq.cq_number); 1116 + 1117 + /* Disable device interrupts */ 1118 + nes_write32(nesdev->regs+NES_INT_MASK, 0x7fffffff); 1119 + 1120 + spin_lock_irqsave(&nesdev->cqp.lock, flags); 1121 + 1122 + /* Destroy the AEQ */ 1123 + cqp_head = nesdev->cqp.sq_head++; 1124 + nesdev->cqp.sq_head &= nesdev->cqp.sq_size-1; 1125 + cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head]; 1126 + cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32(NES_CQP_DESTROY_AEQ | 1127 + ((u32)PCI_FUNC(nesdev->pcidev->devfn) << 8)); 1128 + cqp_wqe->wqe_words[NES_CQP_WQE_COMP_CTX_HIGH_IDX] = 0; 1129 + 1130 + /* Destroy the NIC CEQ */ 1131 + cqp_head = nesdev->cqp.sq_head++; 1132 + nesdev->cqp.sq_head &= nesdev->cqp.sq_size-1; 1133 + cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head]; 1134 + cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32(NES_CQP_DESTROY_CEQ | 1135 + ((u32)nesdev->nic_ceq_index << 8)); 1136 + 1137 + /* Destroy the CEQ */ 1138 + cqp_head = nesdev->cqp.sq_head++; 1139 + nesdev->cqp.sq_head &= nesdev->cqp.sq_size-1; 1140 + cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head]; 1141 + cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32(NES_CQP_DESTROY_CEQ | 1142 + (nesdev->ceq_index << 8)); 1143 + 1144 + /* Destroy the CCQ */ 1145 + cqp_head = nesdev->cqp.sq_head++; 1146 + nesdev->cqp.sq_head &= nesdev->cqp.sq_size-1; 1147 + cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head]; 1148 + cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32(NES_CQP_DESTROY_CQ); 1149 + cqp_wqe->wqe_words[NES_CQP_WQE_ID_IDX] = cpu_to_le32(nesdev->ccq.cq_number | 1150 + ((u32)nesdev->ceq_index << 16)); 1151 + 1152 + /* Destroy CQP */ 1153 + cqp_head = nesdev->cqp.sq_head++; 1154 + nesdev->cqp.sq_head &= nesdev->cqp.sq_size-1; 1155 + cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head]; 1156 + cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32(NES_CQP_DESTROY_QP | 1157 + NES_CQP_QP_TYPE_CQP); 1158 + cqp_wqe->wqe_words[NES_CQP_WQE_ID_IDX] = cpu_to_le32(nesdev->cqp.qp_id); 1159 + 1160 + barrier(); 1161 + /* Ring doorbell (5 WQEs) */ 1162 + nes_write32(nesdev->regs+NES_WQE_ALLOC, 0x05800000 | nesdev->cqp.qp_id); 1163 + 1164 + spin_unlock_irqrestore(&nesdev->cqp.lock, flags); 1165 + 1166 + /* wait for the CCQ, CEQ, and AEQ to get destroyed */ 1167 + count = 0; 1168 + do { 1169 + if (count++ > 1000) { 1170 + printk(KERN_ERR PFX "Function%d: Error destroying CCQ, CEQ, and AEQ\n", 1171 + PCI_FUNC(nesdev->pcidev->devfn)); 1172 + break; 1173 + } 1174 + udelay(10); 1175 + } while (((nes_read_indexed(nesdev, 1176 + NES_IDX_QP_CONTROL + (PCI_FUNC(nesdev->pcidev->devfn)*8)) & (15 << 8)) != 0)); 1177 + 1178 + /* dump the QP status value */ 1179 + nes_debug(NES_DBG_SHUTDOWN, "Function%d: QP Status = 0x%08X\n", 1180 + PCI_FUNC(nesdev->pcidev->devfn), 1181 + nes_read_indexed(nesdev, 1182 + NES_IDX_QP_CONTROL+(PCI_FUNC(nesdev->pcidev->devfn)*8))); 1183 + 1184 + kfree(nesdev->nes_cqp_requests); 1185 + 1186 + /* Free the control structures */ 1187 + pci_free_consistent(nesdev->pcidev, nesdev->cqp_mem_size, nesdev->cqp.sq_vbase, 1188 + nesdev->cqp.sq_pbase); 1189 + 1190 + return 0; 1191 + } 1192 + 1193 + 1194 + /** 1195 + * nes_init_phy 1196 + */ 1197 + int nes_init_phy(struct nes_device *nesdev) 1198 + { 1199 + struct nes_adapter *nesadapter = nesdev->nesadapter; 1200 + u32 counter = 0; 1201 + u32 mac_index = nesdev->mac_index; 1202 + u32 tx_config; 1203 + u16 phy_data; 1204 + 1205 + if (nesadapter->OneG_Mode) { 1206 + nes_debug(NES_DBG_PHY, "1G PHY, mac_index = %d.\n", mac_index); 1207 + if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_1G) { 1208 + printk(PFX "%s: Programming mdc config for 1G\n", __FUNCTION__); 1209 + tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG); 1210 + tx_config |= 0x04; 1211 + nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config); 1212 + } 1213 + 1214 + nes_read_1G_phy_reg(nesdev, 1, nesadapter->phy_index[mac_index], &phy_data); 1215 + nes_debug(NES_DBG_PHY, "Phy data from register 1 phy address %u = 0x%X.\n", 1216 + nesadapter->phy_index[mac_index], phy_data); 1217 + nes_write_1G_phy_reg(nesdev, 23, nesadapter->phy_index[mac_index], 0xb000); 1218 + 1219 + /* Reset the PHY */ 1220 + nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], 0x8000); 1221 + udelay(100); 1222 + counter = 0; 1223 + do { 1224 + nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data); 1225 + nes_debug(NES_DBG_PHY, "Phy data from register 0 = 0x%X.\n", phy_data); 1226 + if (counter++ > 100) break; 1227 + } while (phy_data & 0x8000); 1228 + 1229 + /* Setting no phy loopback */ 1230 + phy_data &= 0xbfff; 1231 + phy_data |= 0x1140; 1232 + nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], phy_data); 1233 + nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data); 1234 + nes_debug(NES_DBG_PHY, "Phy data from register 0 = 0x%X.\n", phy_data); 1235 + 1236 + nes_read_1G_phy_reg(nesdev, 0x17, nesadapter->phy_index[mac_index], &phy_data); 1237 + nes_debug(NES_DBG_PHY, "Phy data from register 0x17 = 0x%X.\n", phy_data); 1238 + 1239 + nes_read_1G_phy_reg(nesdev, 0x1e, nesadapter->phy_index[mac_index], &phy_data); 1240 + nes_debug(NES_DBG_PHY, "Phy data from register 0x1e = 0x%X.\n", phy_data); 1241 + 1242 + /* Setting the interrupt mask */ 1243 + nes_read_1G_phy_reg(nesdev, 0x19, nesadapter->phy_index[mac_index], &phy_data); 1244 + nes_debug(NES_DBG_PHY, "Phy data from register 0x19 = 0x%X.\n", phy_data); 1245 + nes_write_1G_phy_reg(nesdev, 0x19, nesadapter->phy_index[mac_index], 0xffee); 1246 + 1247 + nes_read_1G_phy_reg(nesdev, 0x19, nesadapter->phy_index[mac_index], &phy_data); 1248 + nes_debug(NES_DBG_PHY, "Phy data from register 0x19 = 0x%X.\n", phy_data); 1249 + 1250 + /* turning on flow control */ 1251 + nes_read_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index], &phy_data); 1252 + nes_debug(NES_DBG_PHY, "Phy data from register 0x4 = 0x%X.\n", phy_data); 1253 + nes_write_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index], 1254 + (phy_data & ~(0x03E0)) | 0xc00); 1255 + /* nes_write_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index], 1256 + phy_data | 0xc00); */ 1257 + nes_read_1G_phy_reg(nesdev, 4, nesadapter->phy_index[mac_index], &phy_data); 1258 + nes_debug(NES_DBG_PHY, "Phy data from register 0x4 = 0x%X.\n", phy_data); 1259 + 1260 + nes_read_1G_phy_reg(nesdev, 9, nesadapter->phy_index[mac_index], &phy_data); 1261 + nes_debug(NES_DBG_PHY, "Phy data from register 0x9 = 0x%X.\n", phy_data); 1262 + /* Clear Half duplex */ 1263 + nes_write_1G_phy_reg(nesdev, 9, nesadapter->phy_index[mac_index], 1264 + phy_data & ~(0x0100)); 1265 + nes_read_1G_phy_reg(nesdev, 9, nesadapter->phy_index[mac_index], &phy_data); 1266 + nes_debug(NES_DBG_PHY, "Phy data from register 0x9 = 0x%X.\n", phy_data); 1267 + 1268 + nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data); 1269 + nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], phy_data | 0x0300); 1270 + } else { 1271 + if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_IRIS) { 1272 + /* setup 10G MDIO operation */ 1273 + tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG); 1274 + tx_config |= 0x14; 1275 + nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config); 1276 + } 1277 + } 1278 + return 0; 1279 + } 1280 + 1281 + 1282 + /** 1283 + * nes_replenish_nic_rq 1284 + */ 1285 + static void nes_replenish_nic_rq(struct nes_vnic *nesvnic) 1286 + { 1287 + unsigned long flags; 1288 + dma_addr_t bus_address; 1289 + struct sk_buff *skb; 1290 + struct nes_hw_nic_rq_wqe *nic_rqe; 1291 + struct nes_hw_nic *nesnic; 1292 + struct nes_device *nesdev; 1293 + u32 rx_wqes_posted = 0; 1294 + 1295 + nesnic = &nesvnic->nic; 1296 + nesdev = nesvnic->nesdev; 1297 + spin_lock_irqsave(&nesnic->rq_lock, flags); 1298 + if (nesnic->replenishing_rq !=0) { 1299 + if (((nesnic->rq_size-1) == atomic_read(&nesvnic->rx_skbs_needed)) && 1300 + (atomic_read(&nesvnic->rx_skb_timer_running) == 0)) { 1301 + atomic_set(&nesvnic->rx_skb_timer_running, 1); 1302 + spin_unlock_irqrestore(&nesnic->rq_lock, flags); 1303 + nesvnic->rq_wqes_timer.expires = jiffies + (HZ/2); /* 1/2 second */ 1304 + add_timer(&nesvnic->rq_wqes_timer); 1305 + } else 1306 + spin_unlock_irqrestore(&nesnic->rq_lock, flags); 1307 + return; 1308 + } 1309 + nesnic->replenishing_rq = 1; 1310 + spin_unlock_irqrestore(&nesnic->rq_lock, flags); 1311 + do { 1312 + skb = dev_alloc_skb(nesvnic->max_frame_size); 1313 + if (skb) { 1314 + skb->dev = nesvnic->netdev; 1315 + 1316 + bus_address = pci_map_single(nesdev->pcidev, 1317 + skb->data, nesvnic->max_frame_size, PCI_DMA_FROMDEVICE); 1318 + 1319 + nic_rqe = &nesnic->rq_vbase[nesvnic->nic.rq_head]; 1320 + nic_rqe->wqe_words[NES_NIC_RQ_WQE_LENGTH_1_0_IDX] = 1321 + cpu_to_le32(nesvnic->max_frame_size); 1322 + nic_rqe->wqe_words[NES_NIC_RQ_WQE_LENGTH_3_2_IDX] = 0; 1323 + nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX] = 1324 + cpu_to_le32((u32)bus_address); 1325 + nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX] = 1326 + cpu_to_le32((u32)((u64)bus_address >> 32)); 1327 + nesnic->rx_skb[nesnic->rq_head] = skb; 1328 + nesnic->rq_head++; 1329 + nesnic->rq_head &= nesnic->rq_size - 1; 1330 + atomic_dec(&nesvnic->rx_skbs_needed); 1331 + barrier(); 1332 + if (++rx_wqes_posted == 255) { 1333 + nes_write32(nesdev->regs+NES_WQE_ALLOC, (rx_wqes_posted << 24) | nesnic->qp_id); 1334 + rx_wqes_posted = 0; 1335 + } 1336 + } else { 1337 + spin_lock_irqsave(&nesnic->rq_lock, flags); 1338 + if (((nesnic->rq_size-1) == atomic_read(&nesvnic->rx_skbs_needed)) && 1339 + (atomic_read(&nesvnic->rx_skb_timer_running) == 0)) { 1340 + atomic_set(&nesvnic->rx_skb_timer_running, 1); 1341 + spin_unlock_irqrestore(&nesnic->rq_lock, flags); 1342 + nesvnic->rq_wqes_timer.expires = jiffies + (HZ/2); /* 1/2 second */ 1343 + add_timer(&nesvnic->rq_wqes_timer); 1344 + } else 1345 + spin_unlock_irqrestore(&nesnic->rq_lock, flags); 1346 + break; 1347 + } 1348 + } while (atomic_read(&nesvnic->rx_skbs_needed)); 1349 + barrier(); 1350 + if (rx_wqes_posted) 1351 + nes_write32(nesdev->regs+NES_WQE_ALLOC, (rx_wqes_posted << 24) | nesnic->qp_id); 1352 + nesnic->replenishing_rq = 0; 1353 + } 1354 + 1355 + 1356 + /** 1357 + * nes_rq_wqes_timeout 1358 + */ 1359 + static void nes_rq_wqes_timeout(unsigned long parm) 1360 + { 1361 + struct nes_vnic *nesvnic = (struct nes_vnic *)parm; 1362 + printk("%s: Timer fired.\n", __FUNCTION__); 1363 + atomic_set(&nesvnic->rx_skb_timer_running, 0); 1364 + if (atomic_read(&nesvnic->rx_skbs_needed)) 1365 + nes_replenish_nic_rq(nesvnic); 1366 + } 1367 + 1368 + 1369 + /** 1370 + * nes_init_nic_qp 1371 + */ 1372 + int nes_init_nic_qp(struct nes_device *nesdev, struct net_device *netdev) 1373 + { 1374 + struct nes_hw_cqp_wqe *cqp_wqe; 1375 + struct nes_hw_nic_sq_wqe *nic_sqe; 1376 + struct nes_hw_nic_qp_context *nic_context; 1377 + struct sk_buff *skb; 1378 + struct nes_hw_nic_rq_wqe *nic_rqe; 1379 + struct nes_vnic *nesvnic = netdev_priv(netdev); 1380 + unsigned long flags; 1381 + void *vmem; 1382 + dma_addr_t pmem; 1383 + u64 u64temp; 1384 + int ret; 1385 + u32 cqp_head; 1386 + u32 counter; 1387 + u32 wqe_count; 1388 + u8 jumbomode=0; 1389 + 1390 + /* Allocate fragment, SQ, RQ, and CQ; Reuse CEQ based on the PCI function */ 1391 + nesvnic->nic_mem_size = 256 + 1392 + (NES_NIC_WQ_SIZE * sizeof(struct nes_first_frag)) + 1393 + (NES_NIC_WQ_SIZE * sizeof(struct nes_hw_nic_sq_wqe)) + 1394 + (NES_NIC_WQ_SIZE * sizeof(struct nes_hw_nic_rq_wqe)) + 1395 + (NES_NIC_WQ_SIZE * 2 * sizeof(struct nes_hw_nic_cqe)) + 1396 + sizeof(struct nes_hw_nic_qp_context); 1397 + 1398 + nesvnic->nic_vbase = pci_alloc_consistent(nesdev->pcidev, nesvnic->nic_mem_size, 1399 + &nesvnic->nic_pbase); 1400 + if (!nesvnic->nic_vbase) { 1401 + nes_debug(NES_DBG_INIT, "Unable to allocate memory for NIC host descriptor rings\n"); 1402 + return -ENOMEM; 1403 + } 1404 + memset(nesvnic->nic_vbase, 0, nesvnic->nic_mem_size); 1405 + nes_debug(NES_DBG_INIT, "Allocated NIC QP structures at %p (phys = %016lX), size = %u.\n", 1406 + nesvnic->nic_vbase, (unsigned long)nesvnic->nic_pbase, nesvnic->nic_mem_size); 1407 + 1408 + vmem = (void *)(((unsigned long)nesvnic->nic_vbase + (256 - 1)) & 1409 + ~(unsigned long)(256 - 1)); 1410 + pmem = (dma_addr_t)(((unsigned long long)nesvnic->nic_pbase + (256 - 1)) & 1411 + ~(unsigned long long)(256 - 1)); 1412 + 1413 + /* Setup the first Fragment buffers */ 1414 + nesvnic->nic.first_frag_vbase = vmem; 1415 + 1416 + for (counter = 0; counter < NES_NIC_WQ_SIZE; counter++) { 1417 + nesvnic->nic.frag_paddr[counter] = pmem; 1418 + pmem += sizeof(struct nes_first_frag); 1419 + } 1420 + 1421 + /* setup the SQ */ 1422 + vmem += (NES_NIC_WQ_SIZE * sizeof(struct nes_first_frag)); 1423 + 1424 + nesvnic->nic.sq_vbase = (void *)vmem; 1425 + nesvnic->nic.sq_pbase = pmem; 1426 + nesvnic->nic.sq_head = 0; 1427 + nesvnic->nic.sq_tail = 0; 1428 + nesvnic->nic.sq_size = NES_NIC_WQ_SIZE; 1429 + for (counter = 0; counter < NES_NIC_WQ_SIZE; counter++) { 1430 + nic_sqe = &nesvnic->nic.sq_vbase[counter]; 1431 + nic_sqe->wqe_words[NES_NIC_SQ_WQE_MISC_IDX] = 1432 + cpu_to_le32(NES_NIC_SQ_WQE_DISABLE_CHKSUM | 1433 + NES_NIC_SQ_WQE_COMPLETION); 1434 + nic_sqe->wqe_words[NES_NIC_SQ_WQE_LENGTH_0_TAG_IDX] = 1435 + cpu_to_le32((u32)NES_FIRST_FRAG_SIZE << 16); 1436 + nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX] = 1437 + cpu_to_le32((u32)nesvnic->nic.frag_paddr[counter]); 1438 + nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_HIGH_IDX] = 1439 + cpu_to_le32((u32)((u64)nesvnic->nic.frag_paddr[counter] >> 32)); 1440 + } 1441 + 1442 + nesvnic->get_cqp_request = nes_get_cqp_request; 1443 + nesvnic->post_cqp_request = nes_post_cqp_request; 1444 + nesvnic->mcrq_mcast_filter = NULL; 1445 + 1446 + spin_lock_init(&nesvnic->nic.sq_lock); 1447 + spin_lock_init(&nesvnic->nic.rq_lock); 1448 + 1449 + /* setup the RQ */ 1450 + vmem += (NES_NIC_WQ_SIZE * sizeof(struct nes_hw_nic_sq_wqe)); 1451 + pmem += (NES_NIC_WQ_SIZE * sizeof(struct nes_hw_nic_sq_wqe)); 1452 + 1453 + 1454 + nesvnic->nic.rq_vbase = vmem; 1455 + nesvnic->nic.rq_pbase = pmem; 1456 + nesvnic->nic.rq_head = 0; 1457 + nesvnic->nic.rq_tail = 0; 1458 + nesvnic->nic.rq_size = NES_NIC_WQ_SIZE; 1459 + 1460 + /* setup the CQ */ 1461 + vmem += (NES_NIC_WQ_SIZE * sizeof(struct nes_hw_nic_rq_wqe)); 1462 + pmem += (NES_NIC_WQ_SIZE * sizeof(struct nes_hw_nic_rq_wqe)); 1463 + 1464 + if (nesdev->nesadapter->netdev_count > 2) 1465 + nesvnic->mcrq_qp_id = nesvnic->nic_index + 32; 1466 + else 1467 + nesvnic->mcrq_qp_id = nesvnic->nic.qp_id + 4; 1468 + 1469 + nesvnic->nic_cq.cq_vbase = vmem; 1470 + nesvnic->nic_cq.cq_pbase = pmem; 1471 + nesvnic->nic_cq.cq_head = 0; 1472 + nesvnic->nic_cq.cq_size = NES_NIC_WQ_SIZE * 2; 1473 + 1474 + nesvnic->nic_cq.ce_handler = nes_nic_napi_ce_handler; 1475 + 1476 + /* Send CreateCQ request to CQP */ 1477 + spin_lock_irqsave(&nesdev->cqp.lock, flags); 1478 + cqp_head = nesdev->cqp.sq_head; 1479 + 1480 + cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head]; 1481 + nes_fill_init_cqp_wqe(cqp_wqe, nesdev); 1482 + 1483 + cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32( 1484 + NES_CQP_CREATE_CQ | NES_CQP_CQ_CEQ_VALID | 1485 + ((u32)nesvnic->nic_cq.cq_size << 16)); 1486 + cqp_wqe->wqe_words[NES_CQP_WQE_ID_IDX] = cpu_to_le32( 1487 + nesvnic->nic_cq.cq_number | ((u32)nesdev->nic_ceq_index << 16)); 1488 + u64temp = (u64)nesvnic->nic_cq.cq_pbase; 1489 + set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_CQ_WQE_PBL_LOW_IDX, u64temp); 1490 + cqp_wqe->wqe_words[NES_CQP_CQ_WQE_CQ_CONTEXT_HIGH_IDX] = 0; 1491 + u64temp = (unsigned long)&nesvnic->nic_cq; 1492 + cqp_wqe->wqe_words[NES_CQP_CQ_WQE_CQ_CONTEXT_LOW_IDX] = cpu_to_le32((u32)(u64temp >> 1)); 1493 + cqp_wqe->wqe_words[NES_CQP_CQ_WQE_CQ_CONTEXT_HIGH_IDX] = 1494 + cpu_to_le32(((u32)((u64temp) >> 33)) & 0x7FFFFFFF); 1495 + cqp_wqe->wqe_words[NES_CQP_CQ_WQE_DOORBELL_INDEX_HIGH_IDX] = 0; 1496 + if (++cqp_head >= nesdev->cqp.sq_size) 1497 + cqp_head = 0; 1498 + cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head]; 1499 + nes_fill_init_cqp_wqe(cqp_wqe, nesdev); 1500 + 1501 + /* Send CreateQP request to CQP */ 1502 + nic_context = (void *)(&nesvnic->nic_cq.cq_vbase[nesvnic->nic_cq.cq_size]); 1503 + nic_context->context_words[NES_NIC_CTX_MISC_IDX] = 1504 + cpu_to_le32((u32)NES_NIC_CTX_SIZE | 1505 + ((u32)PCI_FUNC(nesdev->pcidev->devfn) << 12)); 1506 + nes_debug(NES_DBG_INIT, "RX_WINDOW_BUFFER_PAGE_TABLE_SIZE = 0x%08X, RX_WINDOW_BUFFER_SIZE = 0x%08X\n", 1507 + nes_read_indexed(nesdev, NES_IDX_RX_WINDOW_BUFFER_PAGE_TABLE_SIZE), 1508 + nes_read_indexed(nesdev, NES_IDX_RX_WINDOW_BUFFER_SIZE)); 1509 + if (nes_read_indexed(nesdev, NES_IDX_RX_WINDOW_BUFFER_SIZE) != 0) { 1510 + nic_context->context_words[NES_NIC_CTX_MISC_IDX] |= cpu_to_le32(NES_NIC_BACK_STORE); 1511 + } 1512 + 1513 + u64temp = (u64)nesvnic->nic.sq_pbase; 1514 + nic_context->context_words[NES_NIC_CTX_SQ_LOW_IDX] = cpu_to_le32((u32)u64temp); 1515 + nic_context->context_words[NES_NIC_CTX_SQ_HIGH_IDX] = cpu_to_le32((u32)(u64temp >> 32)); 1516 + u64temp = (u64)nesvnic->nic.rq_pbase; 1517 + nic_context->context_words[NES_NIC_CTX_RQ_LOW_IDX] = cpu_to_le32((u32)u64temp); 1518 + nic_context->context_words[NES_NIC_CTX_RQ_HIGH_IDX] = cpu_to_le32((u32)(u64temp >> 32)); 1519 + 1520 + cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32(NES_CQP_CREATE_QP | 1521 + NES_CQP_QP_TYPE_NIC); 1522 + cqp_wqe->wqe_words[NES_CQP_WQE_ID_IDX] = cpu_to_le32(nesvnic->nic.qp_id); 1523 + u64temp = (u64)nesvnic->nic_cq.cq_pbase + 1524 + (nesvnic->nic_cq.cq_size * sizeof(struct nes_hw_nic_cqe)); 1525 + set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_QP_WQE_CONTEXT_LOW_IDX, u64temp); 1526 + 1527 + if (++cqp_head >= nesdev->cqp.sq_size) 1528 + cqp_head = 0; 1529 + nesdev->cqp.sq_head = cqp_head; 1530 + 1531 + barrier(); 1532 + 1533 + /* Ring doorbell (2 WQEs) */ 1534 + nes_write32(nesdev->regs+NES_WQE_ALLOC, 0x02800000 | nesdev->cqp.qp_id); 1535 + 1536 + spin_unlock_irqrestore(&nesdev->cqp.lock, flags); 1537 + nes_debug(NES_DBG_INIT, "Waiting for create NIC QP%u to complete.\n", 1538 + nesvnic->nic.qp_id); 1539 + 1540 + ret = wait_event_timeout(nesdev->cqp.waitq, (nesdev->cqp.sq_tail == cqp_head), 1541 + NES_EVENT_TIMEOUT); 1542 + nes_debug(NES_DBG_INIT, "Create NIC QP%u completed, wait_event_timeout ret = %u.\n", 1543 + nesvnic->nic.qp_id, ret); 1544 + if (!ret) { 1545 + nes_debug(NES_DBG_INIT, "NIC QP%u create timeout expired\n", nesvnic->nic.qp_id); 1546 + pci_free_consistent(nesdev->pcidev, nesvnic->nic_mem_size, nesvnic->nic_vbase, 1547 + nesvnic->nic_pbase); 1548 + return -EIO; 1549 + } 1550 + 1551 + /* Populate the RQ */ 1552 + for (counter = 0; counter < (NES_NIC_WQ_SIZE - 1); counter++) { 1553 + skb = dev_alloc_skb(nesvnic->max_frame_size); 1554 + if (!skb) { 1555 + nes_debug(NES_DBG_INIT, "%s: out of memory for receive skb\n", netdev->name); 1556 + 1557 + nes_destroy_nic_qp(nesvnic); 1558 + return -ENOMEM; 1559 + } 1560 + 1561 + skb->dev = netdev; 1562 + 1563 + pmem = pci_map_single(nesdev->pcidev, skb->data, 1564 + nesvnic->max_frame_size, PCI_DMA_FROMDEVICE); 1565 + 1566 + nic_rqe = &nesvnic->nic.rq_vbase[counter]; 1567 + nic_rqe->wqe_words[NES_NIC_RQ_WQE_LENGTH_1_0_IDX] = cpu_to_le32(nesvnic->max_frame_size); 1568 + nic_rqe->wqe_words[NES_NIC_RQ_WQE_LENGTH_3_2_IDX] = 0; 1569 + nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX] = cpu_to_le32((u32)pmem); 1570 + nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX] = cpu_to_le32((u32)((u64)pmem >> 32)); 1571 + nesvnic->nic.rx_skb[counter] = skb; 1572 + } 1573 + 1574 + wqe_count = NES_NIC_WQ_SIZE - 1; 1575 + nesvnic->nic.rq_head = wqe_count; 1576 + barrier(); 1577 + do { 1578 + counter = min(wqe_count, ((u32)255)); 1579 + wqe_count -= counter; 1580 + nes_write32(nesdev->regs+NES_WQE_ALLOC, (counter << 24) | nesvnic->nic.qp_id); 1581 + } while (wqe_count); 1582 + init_timer(&nesvnic->rq_wqes_timer); 1583 + nesvnic->rq_wqes_timer.function = nes_rq_wqes_timeout; 1584 + nesvnic->rq_wqes_timer.data = (unsigned long)nesvnic; 1585 + nes_debug(NES_DBG_INIT, "NAPI support Enabled\n"); 1586 + 1587 + if (nesdev->nesadapter->et_use_adaptive_rx_coalesce) 1588 + { 1589 + nes_nic_init_timer(nesdev); 1590 + if (netdev->mtu > 1500) 1591 + jumbomode = 1; 1592 + nes_nic_init_timer_defaults(nesdev, jumbomode); 1593 + } 1594 + 1595 + return 0; 1596 + } 1597 + 1598 + 1599 + /** 1600 + * nes_destroy_nic_qp 1601 + */ 1602 + void nes_destroy_nic_qp(struct nes_vnic *nesvnic) 1603 + { 1604 + struct nes_device *nesdev = nesvnic->nesdev; 1605 + struct nes_hw_cqp_wqe *cqp_wqe; 1606 + struct nes_hw_nic_rq_wqe *nic_rqe; 1607 + u64 wqe_frag; 1608 + u32 cqp_head; 1609 + unsigned long flags; 1610 + int ret; 1611 + 1612 + /* Free remaining NIC receive buffers */ 1613 + while (nesvnic->nic.rq_head != nesvnic->nic.rq_tail) { 1614 + nic_rqe = &nesvnic->nic.rq_vbase[nesvnic->nic.rq_tail]; 1615 + wqe_frag = (u64)le32_to_cpu(nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX]); 1616 + wqe_frag |= ((u64)le32_to_cpu(nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX])) << 32; 1617 + pci_unmap_single(nesdev->pcidev, (dma_addr_t)wqe_frag, 1618 + nesvnic->max_frame_size, PCI_DMA_FROMDEVICE); 1619 + dev_kfree_skb(nesvnic->nic.rx_skb[nesvnic->nic.rq_tail++]); 1620 + nesvnic->nic.rq_tail &= (nesvnic->nic.rq_size - 1); 1621 + } 1622 + 1623 + spin_lock_irqsave(&nesdev->cqp.lock, flags); 1624 + 1625 + /* Destroy NIC QP */ 1626 + cqp_head = nesdev->cqp.sq_head; 1627 + cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head]; 1628 + nes_fill_init_cqp_wqe(cqp_wqe, nesdev); 1629 + 1630 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX, 1631 + (NES_CQP_DESTROY_QP | NES_CQP_QP_TYPE_NIC)); 1632 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_ID_IDX, 1633 + nesvnic->nic.qp_id); 1634 + 1635 + if (++cqp_head >= nesdev->cqp.sq_size) 1636 + cqp_head = 0; 1637 + 1638 + cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head]; 1639 + 1640 + /* Destroy NIC CQ */ 1641 + nes_fill_init_cqp_wqe(cqp_wqe, nesdev); 1642 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX, 1643 + (NES_CQP_DESTROY_CQ | ((u32)nesvnic->nic_cq.cq_size << 16))); 1644 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_ID_IDX, 1645 + (nesvnic->nic_cq.cq_number | ((u32)nesdev->nic_ceq_index << 16))); 1646 + 1647 + if (++cqp_head >= nesdev->cqp.sq_size) 1648 + cqp_head = 0; 1649 + 1650 + nesdev->cqp.sq_head = cqp_head; 1651 + barrier(); 1652 + 1653 + /* Ring doorbell (2 WQEs) */ 1654 + nes_write32(nesdev->regs+NES_WQE_ALLOC, 0x02800000 | nesdev->cqp.qp_id); 1655 + 1656 + spin_unlock_irqrestore(&nesdev->cqp.lock, flags); 1657 + nes_debug(NES_DBG_SHUTDOWN, "Waiting for CQP, cqp_head=%u, cqp.sq_head=%u," 1658 + " cqp.sq_tail=%u, cqp.sq_size=%u\n", 1659 + cqp_head, nesdev->cqp.sq_head, 1660 + nesdev->cqp.sq_tail, nesdev->cqp.sq_size); 1661 + 1662 + ret = wait_event_timeout(nesdev->cqp.waitq, (nesdev->cqp.sq_tail == cqp_head), 1663 + NES_EVENT_TIMEOUT); 1664 + 1665 + nes_debug(NES_DBG_SHUTDOWN, "Destroy NIC QP returned, wait_event_timeout ret = %u, cqp_head=%u," 1666 + " cqp.sq_head=%u, cqp.sq_tail=%u\n", 1667 + ret, cqp_head, nesdev->cqp.sq_head, nesdev->cqp.sq_tail); 1668 + if (!ret) { 1669 + nes_debug(NES_DBG_SHUTDOWN, "NIC QP%u destroy timeout expired\n", 1670 + nesvnic->nic.qp_id); 1671 + } 1672 + 1673 + pci_free_consistent(nesdev->pcidev, nesvnic->nic_mem_size, nesvnic->nic_vbase, 1674 + nesvnic->nic_pbase); 1675 + } 1676 + 1677 + /** 1678 + * nes_napi_isr 1679 + */ 1680 + int nes_napi_isr(struct nes_device *nesdev) 1681 + { 1682 + struct nes_adapter *nesadapter = nesdev->nesadapter; 1683 + u32 int_stat; 1684 + 1685 + if (nesdev->napi_isr_ran) { 1686 + /* interrupt status has already been read in ISR */ 1687 + int_stat = nesdev->int_stat; 1688 + } else { 1689 + int_stat = nes_read32(nesdev->regs + NES_INT_STAT); 1690 + nesdev->int_stat = int_stat; 1691 + nesdev->napi_isr_ran = 1; 1692 + } 1693 + 1694 + int_stat &= nesdev->int_req; 1695 + /* iff NIC, process here, else wait for DPC */ 1696 + if ((int_stat) && ((int_stat & 0x0000ff00) == int_stat)) { 1697 + nesdev->napi_isr_ran = 0; 1698 + nes_write32(nesdev->regs+NES_INT_STAT, 1699 + (int_stat & 1700 + ~(NES_INT_INTF|NES_INT_TIMER|NES_INT_MAC0|NES_INT_MAC1|NES_INT_MAC2|NES_INT_MAC3))); 1701 + 1702 + /* Process the CEQs */ 1703 + nes_process_ceq(nesdev, &nesdev->nesadapter->ceq[nesdev->nic_ceq_index]); 1704 + 1705 + if (unlikely((((nesadapter->et_rx_coalesce_usecs_irq) && 1706 + (!nesadapter->et_use_adaptive_rx_coalesce)) || 1707 + ((nesadapter->et_use_adaptive_rx_coalesce) && 1708 + (nesdev->deepcq_count > nesadapter->et_pkt_rate_low)))) ) { 1709 + if ((nesdev->int_req & NES_INT_TIMER) == 0) { 1710 + /* Enable Periodic timer interrupts */ 1711 + nesdev->int_req |= NES_INT_TIMER; 1712 + /* ack any pending periodic timer interrupts so we don't get an immediate interrupt */ 1713 + /* TODO: need to also ack other unused periodic timer values, get from nesadapter */ 1714 + nes_write32(nesdev->regs+NES_TIMER_STAT, 1715 + nesdev->timer_int_req | ~(nesdev->nesadapter->timer_int_req)); 1716 + nes_write32(nesdev->regs+NES_INTF_INT_MASK, 1717 + ~(nesdev->intf_int_req | NES_INTF_PERIODIC_TIMER)); 1718 + } 1719 + 1720 + if (unlikely(nesadapter->et_use_adaptive_rx_coalesce)) 1721 + { 1722 + nes_nic_init_timer(nesdev); 1723 + } 1724 + /* Enable interrupts, except CEQs */ 1725 + nes_write32(nesdev->regs+NES_INT_MASK, 0x0000ffff | (~nesdev->int_req)); 1726 + } else { 1727 + /* Enable interrupts, make sure timer is off */ 1728 + nesdev->int_req &= ~NES_INT_TIMER; 1729 + nes_write32(nesdev->regs+NES_INTF_INT_MASK, ~(nesdev->intf_int_req)); 1730 + nes_write32(nesdev->regs+NES_INT_MASK, ~nesdev->int_req); 1731 + nesadapter->tune_timer.timer_in_use_old = 0; 1732 + } 1733 + nesdev->deepcq_count = 0; 1734 + return 1; 1735 + } else { 1736 + return 0; 1737 + } 1738 + } 1739 + 1740 + 1741 + /** 1742 + * nes_dpc 1743 + */ 1744 + void nes_dpc(unsigned long param) 1745 + { 1746 + struct nes_device *nesdev = (struct nes_device *)param; 1747 + struct nes_adapter *nesadapter = nesdev->nesadapter; 1748 + u32 counter; 1749 + u32 loop_counter = 0; 1750 + u32 int_status_bit; 1751 + u32 int_stat; 1752 + u32 timer_stat; 1753 + u32 temp_int_stat; 1754 + u32 intf_int_stat; 1755 + u32 debug_error; 1756 + u32 processed_intf_int = 0; 1757 + u16 processed_timer_int = 0; 1758 + u16 completion_ints = 0; 1759 + u16 timer_ints = 0; 1760 + 1761 + /* nes_debug(NES_DBG_ISR, "\n"); */ 1762 + 1763 + do { 1764 + timer_stat = 0; 1765 + if (nesdev->napi_isr_ran) { 1766 + nesdev->napi_isr_ran = 0; 1767 + int_stat = nesdev->int_stat; 1768 + } else 1769 + int_stat = nes_read32(nesdev->regs+NES_INT_STAT); 1770 + if (processed_intf_int != 0) 1771 + int_stat &= nesdev->int_req & ~NES_INT_INTF; 1772 + else 1773 + int_stat &= nesdev->int_req; 1774 + if (processed_timer_int == 0) { 1775 + processed_timer_int = 1; 1776 + if (int_stat & NES_INT_TIMER) { 1777 + timer_stat = nes_read32(nesdev->regs + NES_TIMER_STAT); 1778 + if ((timer_stat & nesdev->timer_int_req) == 0) { 1779 + int_stat &= ~NES_INT_TIMER; 1780 + } 1781 + } 1782 + } else { 1783 + int_stat &= ~NES_INT_TIMER; 1784 + } 1785 + 1786 + if (int_stat) { 1787 + if (int_stat & ~(NES_INT_INTF|NES_INT_TIMER|NES_INT_MAC0| 1788 + NES_INT_MAC1|NES_INT_MAC2|NES_INT_MAC3)) { 1789 + /* Ack the interrupts */ 1790 + nes_write32(nesdev->regs+NES_INT_STAT, 1791 + (int_stat & ~(NES_INT_INTF|NES_INT_TIMER|NES_INT_MAC0| 1792 + NES_INT_MAC1|NES_INT_MAC2|NES_INT_MAC3))); 1793 + } 1794 + 1795 + temp_int_stat = int_stat; 1796 + for (counter = 0, int_status_bit = 1; counter < 16; counter++) { 1797 + if (int_stat & int_status_bit) { 1798 + nes_process_ceq(nesdev, &nesadapter->ceq[counter]); 1799 + temp_int_stat &= ~int_status_bit; 1800 + completion_ints = 1; 1801 + } 1802 + if (!(temp_int_stat & 0x0000ffff)) 1803 + break; 1804 + int_status_bit <<= 1; 1805 + } 1806 + 1807 + /* Process the AEQ for this pci function */ 1808 + int_status_bit = 1 << (16 + PCI_FUNC(nesdev->pcidev->devfn)); 1809 + if (int_stat & int_status_bit) { 1810 + nes_process_aeq(nesdev, &nesadapter->aeq[PCI_FUNC(nesdev->pcidev->devfn)]); 1811 + } 1812 + 1813 + /* Process the MAC interrupt for this pci function */ 1814 + int_status_bit = 1 << (24 + nesdev->mac_index); 1815 + if (int_stat & int_status_bit) { 1816 + nes_process_mac_intr(nesdev, nesdev->mac_index); 1817 + } 1818 + 1819 + if (int_stat & NES_INT_TIMER) { 1820 + if (timer_stat & nesdev->timer_int_req) { 1821 + nes_write32(nesdev->regs + NES_TIMER_STAT, 1822 + (timer_stat & nesdev->timer_int_req) | 1823 + ~(nesdev->nesadapter->timer_int_req)); 1824 + timer_ints = 1; 1825 + } 1826 + } 1827 + 1828 + if (int_stat & NES_INT_INTF) { 1829 + processed_intf_int = 1; 1830 + intf_int_stat = nes_read32(nesdev->regs+NES_INTF_INT_STAT); 1831 + intf_int_stat &= nesdev->intf_int_req; 1832 + if (NES_INTF_INT_CRITERR & intf_int_stat) { 1833 + debug_error = nes_read_indexed(nesdev, NES_IDX_DEBUG_ERROR_CONTROL_STATUS); 1834 + printk(KERN_ERR PFX "Critical Error reported by device!!! 0x%02X\n", 1835 + (u16)debug_error); 1836 + nes_write_indexed(nesdev, NES_IDX_DEBUG_ERROR_CONTROL_STATUS, 1837 + 0x01010000 | (debug_error & 0x0000ffff)); 1838 + /* BUG(); */ 1839 + if (crit_err_count++ > 10) 1840 + nes_write_indexed(nesdev, NES_IDX_DEBUG_ERROR_MASKS1, 1 << 0x17); 1841 + } 1842 + if (NES_INTF_INT_PCIERR & intf_int_stat) { 1843 + printk(KERN_ERR PFX "PCI Error reported by device!!!\n"); 1844 + BUG(); 1845 + } 1846 + if (NES_INTF_INT_AEQ_OFLOW & intf_int_stat) { 1847 + printk(KERN_ERR PFX "AEQ Overflow reported by device!!!\n"); 1848 + BUG(); 1849 + } 1850 + nes_write32(nesdev->regs+NES_INTF_INT_STAT, intf_int_stat); 1851 + } 1852 + 1853 + if (int_stat & NES_INT_TSW) { 1854 + } 1855 + } 1856 + /* Don't use the interface interrupt bit stay in loop */ 1857 + int_stat &= ~NES_INT_INTF|NES_INT_TIMER|NES_INT_MAC0| 1858 + NES_INT_MAC1|NES_INT_MAC2|NES_INT_MAC3; 1859 + } while ((int_stat != 0) && (loop_counter++ < MAX_DPC_ITERATIONS)); 1860 + 1861 + if (timer_ints == 1) { 1862 + if ((nesadapter->et_rx_coalesce_usecs_irq) || (nesadapter->et_use_adaptive_rx_coalesce)) { 1863 + if (completion_ints == 0) { 1864 + nesdev->timer_only_int_count++; 1865 + if (nesdev->timer_only_int_count>=nesadapter->timer_int_limit) { 1866 + nesdev->timer_only_int_count = 0; 1867 + nesdev->int_req &= ~NES_INT_TIMER; 1868 + nes_write32(nesdev->regs + NES_INTF_INT_MASK, ~(nesdev->intf_int_req)); 1869 + nes_write32(nesdev->regs+NES_INT_MASK, ~nesdev->int_req); 1870 + nesdev->nesadapter->tune_timer.timer_in_use_old = 0; 1871 + } else { 1872 + nes_write32(nesdev->regs+NES_INT_MASK, 0x0000ffff|(~nesdev->int_req)); 1873 + } 1874 + } else { 1875 + if (unlikely(nesadapter->et_use_adaptive_rx_coalesce)) 1876 + { 1877 + nes_nic_init_timer(nesdev); 1878 + } 1879 + nesdev->timer_only_int_count = 0; 1880 + nes_write32(nesdev->regs+NES_INT_MASK, 0x0000ffff|(~nesdev->int_req)); 1881 + } 1882 + } else { 1883 + nesdev->timer_only_int_count = 0; 1884 + nesdev->int_req &= ~NES_INT_TIMER; 1885 + nes_write32(nesdev->regs+NES_INTF_INT_MASK, ~(nesdev->intf_int_req)); 1886 + nes_write32(nesdev->regs+NES_TIMER_STAT, 1887 + nesdev->timer_int_req | ~(nesdev->nesadapter->timer_int_req)); 1888 + nes_write32(nesdev->regs+NES_INT_MASK, ~nesdev->int_req); 1889 + } 1890 + } else { 1891 + if ( (completion_ints == 1) && 1892 + (((nesadapter->et_rx_coalesce_usecs_irq) && 1893 + (!nesadapter->et_use_adaptive_rx_coalesce)) || 1894 + ((nesdev->deepcq_count > nesadapter->et_pkt_rate_low) && 1895 + (nesadapter->et_use_adaptive_rx_coalesce) )) ) { 1896 + /* nes_debug(NES_DBG_ISR, "Enabling periodic timer interrupt.\n" ); */ 1897 + nesdev->timer_only_int_count = 0; 1898 + nesdev->int_req |= NES_INT_TIMER; 1899 + nes_write32(nesdev->regs+NES_TIMER_STAT, 1900 + nesdev->timer_int_req | ~(nesdev->nesadapter->timer_int_req)); 1901 + nes_write32(nesdev->regs+NES_INTF_INT_MASK, 1902 + ~(nesdev->intf_int_req | NES_INTF_PERIODIC_TIMER)); 1903 + nes_write32(nesdev->regs+NES_INT_MASK, 0x0000ffff | (~nesdev->int_req)); 1904 + } else { 1905 + nes_write32(nesdev->regs+NES_INT_MASK, ~nesdev->int_req); 1906 + } 1907 + } 1908 + nesdev->deepcq_count = 0; 1909 + } 1910 + 1911 + 1912 + /** 1913 + * nes_process_ceq 1914 + */ 1915 + void nes_process_ceq(struct nes_device *nesdev, struct nes_hw_ceq *ceq) 1916 + { 1917 + u64 u64temp; 1918 + struct nes_hw_cq *cq; 1919 + u32 head; 1920 + u32 ceq_size; 1921 + 1922 + /* nes_debug(NES_DBG_CQ, "\n"); */ 1923 + head = ceq->ceq_head; 1924 + ceq_size = ceq->ceq_size; 1925 + 1926 + do { 1927 + if (le32_to_cpu(ceq->ceq_vbase[head].ceqe_words[NES_CEQE_CQ_CTX_HIGH_IDX]) & 1928 + NES_CEQE_VALID) { 1929 + u64temp = (((u64)(le32_to_cpu(ceq->ceq_vbase[head].ceqe_words[NES_CEQE_CQ_CTX_HIGH_IDX])))<<32) | 1930 + ((u64)(le32_to_cpu(ceq->ceq_vbase[head].ceqe_words[NES_CEQE_CQ_CTX_LOW_IDX]))); 1931 + u64temp <<= 1; 1932 + cq = *((struct nes_hw_cq **)&u64temp); 1933 + /* nes_debug(NES_DBG_CQ, "pCQ = %p\n", cq); */ 1934 + barrier(); 1935 + ceq->ceq_vbase[head].ceqe_words[NES_CEQE_CQ_CTX_HIGH_IDX] = 0; 1936 + 1937 + /* call the event handler */ 1938 + cq->ce_handler(nesdev, cq); 1939 + 1940 + if (++head >= ceq_size) 1941 + head = 0; 1942 + } else { 1943 + break; 1944 + } 1945 + 1946 + } while (1); 1947 + 1948 + ceq->ceq_head = head; 1949 + } 1950 + 1951 + 1952 + /** 1953 + * nes_process_aeq 1954 + */ 1955 + void nes_process_aeq(struct nes_device *nesdev, struct nes_hw_aeq *aeq) 1956 + { 1957 + // u64 u64temp; 1958 + u32 head; 1959 + u32 aeq_size; 1960 + u32 aeqe_misc; 1961 + u32 aeqe_cq_id; 1962 + struct nes_hw_aeqe volatile *aeqe; 1963 + 1964 + head = aeq->aeq_head; 1965 + aeq_size = aeq->aeq_size; 1966 + 1967 + do { 1968 + aeqe = &aeq->aeq_vbase[head]; 1969 + if ((le32_to_cpu(aeqe->aeqe_words[NES_AEQE_MISC_IDX]) & NES_AEQE_VALID) == 0) 1970 + break; 1971 + aeqe_misc = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_MISC_IDX]); 1972 + aeqe_cq_id = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]); 1973 + if (aeqe_misc & (NES_AEQE_QP|NES_AEQE_CQ)) { 1974 + if (aeqe_cq_id >= NES_FIRST_QPN) { 1975 + /* dealing with an accelerated QP related AE */ 1976 + // u64temp = (((u64)(le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_HIGH_IDX])))<<32) | 1977 + // ((u64)(le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_LOW_IDX]))); 1978 + nes_process_iwarp_aeqe(nesdev, (struct nes_hw_aeqe *)aeqe); 1979 + } else { 1980 + /* TODO: dealing with a CQP related AE */ 1981 + nes_debug(NES_DBG_AEQ, "Processing CQP related AE, misc = 0x%04X\n", 1982 + (u16)(aeqe_misc >> 16)); 1983 + } 1984 + } 1985 + 1986 + aeqe->aeqe_words[NES_AEQE_MISC_IDX] = 0; 1987 + 1988 + if (++head >= aeq_size) 1989 + head = 0; 1990 + } 1991 + while (1); 1992 + aeq->aeq_head = head; 1993 + } 1994 + 1995 + static void nes_reset_link(struct nes_device *nesdev, u32 mac_index) 1996 + { 1997 + struct nes_adapter *nesadapter = nesdev->nesadapter; 1998 + u32 reset_value; 1999 + u32 i=0; 2000 + u32 u32temp; 2001 + 2002 + if (nesadapter->hw_rev == NE020_REV) { 2003 + return; 2004 + } 2005 + mh_detected++; 2006 + 2007 + reset_value = nes_read32(nesdev->regs+NES_SOFTWARE_RESET); 2008 + 2009 + if ((mac_index == 0) || ((mac_index == 1) && (nesadapter->OneG_Mode))) 2010 + reset_value |= 0x0000001d; 2011 + else 2012 + reset_value |= 0x0000002d; 2013 + 2014 + if (4 <= (nesadapter->link_interrupt_count[mac_index] / ((u16)NES_MAX_LINK_INTERRUPTS))) { 2015 + if ((!nesadapter->OneG_Mode) && (nesadapter->port_count == 2)) { 2016 + nesadapter->link_interrupt_count[0] = 0; 2017 + nesadapter->link_interrupt_count[1] = 0; 2018 + u32temp = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1); 2019 + if (0x00000040 & u32temp) 2020 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, 0x0000F088); 2021 + else 2022 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, 0x0000F0C8); 2023 + 2024 + reset_value |= 0x0000003d; 2025 + } 2026 + nesadapter->link_interrupt_count[mac_index] = 0; 2027 + } 2028 + 2029 + nes_write32(nesdev->regs+NES_SOFTWARE_RESET, reset_value); 2030 + 2031 + while (((nes_read32(nesdev->regs+NES_SOFTWARE_RESET) 2032 + & 0x00000040) != 0x00000040) && (i++ < 5000)); 2033 + 2034 + if (0x0000003d == (reset_value & 0x0000003d)) { 2035 + u32 pcs_control_status0, pcs_control_status1; 2036 + 2037 + for (i = 0; i < 10; i++) { 2038 + pcs_control_status0 = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0); 2039 + pcs_control_status1 = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + 0x200); 2040 + if (((0x0F000000 == (pcs_control_status0 & 0x0F000000)) 2041 + && (pcs_control_status0 & 0x00100000)) 2042 + || ((0x0F000000 == (pcs_control_status1 & 0x0F000000)) 2043 + && (pcs_control_status1 & 0x00100000))) 2044 + continue; 2045 + else 2046 + break; 2047 + } 2048 + if (10 == i) { 2049 + u32temp = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1); 2050 + if (0x00000040 & u32temp) 2051 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, 0x0000F088); 2052 + else 2053 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1, 0x0000F0C8); 2054 + 2055 + nes_write32(nesdev->regs+NES_SOFTWARE_RESET, reset_value); 2056 + 2057 + while (((nes_read32(nesdev->regs + NES_SOFTWARE_RESET) 2058 + & 0x00000040) != 0x00000040) && (i++ < 5000)); 2059 + } 2060 + } 2061 + } 2062 + 2063 + /** 2064 + * nes_process_mac_intr 2065 + */ 2066 + void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) 2067 + { 2068 + unsigned long flags; 2069 + u32 pcs_control_status; 2070 + struct nes_adapter *nesadapter = nesdev->nesadapter; 2071 + struct nes_vnic *nesvnic; 2072 + u32 mac_status; 2073 + u32 mac_index = nesdev->mac_index; 2074 + u32 u32temp; 2075 + u16 phy_data; 2076 + u16 temp_phy_data; 2077 + 2078 + spin_lock_irqsave(&nesadapter->phy_lock, flags); 2079 + if (nesadapter->mac_sw_state[mac_number] != NES_MAC_SW_IDLE) { 2080 + spin_unlock_irqrestore(&nesadapter->phy_lock, flags); 2081 + return; 2082 + } 2083 + nesadapter->mac_sw_state[mac_number] = NES_MAC_SW_INTERRUPT; 2084 + spin_unlock_irqrestore(&nesadapter->phy_lock, flags); 2085 + 2086 + /* ack the MAC interrupt */ 2087 + mac_status = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (mac_index * 0x200)); 2088 + /* Clear the interrupt */ 2089 + nes_write_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (mac_index * 0x200), mac_status); 2090 + 2091 + nes_debug(NES_DBG_PHY, "MAC%u interrupt status = 0x%X.\n", mac_number, mac_status); 2092 + 2093 + if (mac_status & (NES_MAC_INT_LINK_STAT_CHG | NES_MAC_INT_XGMII_EXT)) { 2094 + nesdev->link_status_interrupts++; 2095 + if (0 == (++nesadapter->link_interrupt_count[mac_index] % ((u16)NES_MAX_LINK_INTERRUPTS))) { 2096 + spin_lock_irqsave(&nesadapter->phy_lock, flags); 2097 + nes_reset_link(nesdev, mac_index); 2098 + spin_unlock_irqrestore(&nesadapter->phy_lock, flags); 2099 + } 2100 + /* read the PHY interrupt status register */ 2101 + if (nesadapter->OneG_Mode) { 2102 + do { 2103 + nes_read_1G_phy_reg(nesdev, 0x1a, 2104 + nesadapter->phy_index[mac_index], &phy_data); 2105 + nes_debug(NES_DBG_PHY, "Phy%d data from register 0x1a = 0x%X.\n", 2106 + nesadapter->phy_index[mac_index], phy_data); 2107 + } while (phy_data&0x8000); 2108 + 2109 + temp_phy_data = 0; 2110 + do { 2111 + nes_read_1G_phy_reg(nesdev, 0x11, 2112 + nesadapter->phy_index[mac_index], &phy_data); 2113 + nes_debug(NES_DBG_PHY, "Phy%d data from register 0x11 = 0x%X.\n", 2114 + nesadapter->phy_index[mac_index], phy_data); 2115 + if (temp_phy_data == phy_data) 2116 + break; 2117 + temp_phy_data = phy_data; 2118 + } while (1); 2119 + 2120 + nes_read_1G_phy_reg(nesdev, 0x1e, 2121 + nesadapter->phy_index[mac_index], &phy_data); 2122 + nes_debug(NES_DBG_PHY, "Phy%d data from register 0x1e = 0x%X.\n", 2123 + nesadapter->phy_index[mac_index], phy_data); 2124 + 2125 + nes_read_1G_phy_reg(nesdev, 1, 2126 + nesadapter->phy_index[mac_index], &phy_data); 2127 + nes_debug(NES_DBG_PHY, "1G phy%u data from register 1 = 0x%X\n", 2128 + nesadapter->phy_index[mac_index], phy_data); 2129 + 2130 + if (temp_phy_data & 0x1000) { 2131 + nes_debug(NES_DBG_PHY, "The Link is up according to the PHY\n"); 2132 + phy_data = 4; 2133 + } else { 2134 + nes_debug(NES_DBG_PHY, "The Link is down according to the PHY\n"); 2135 + } 2136 + } 2137 + nes_debug(NES_DBG_PHY, "Eth SERDES Common Status: 0=0x%08X, 1=0x%08X\n", 2138 + nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0), 2139 + nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0+0x200)); 2140 + pcs_control_status = nes_read_indexed(nesdev, 2141 + NES_IDX_PHY_PCS_CONTROL_STATUS0 + ((mac_index&1)*0x200)); 2142 + pcs_control_status = nes_read_indexed(nesdev, 2143 + NES_IDX_PHY_PCS_CONTROL_STATUS0 + ((mac_index&1)*0x200)); 2144 + nes_debug(NES_DBG_PHY, "PCS PHY Control/Status%u: 0x%08X\n", 2145 + mac_index, pcs_control_status); 2146 + if (nesadapter->OneG_Mode) { 2147 + u32temp = 0x01010000; 2148 + if (nesadapter->port_count > 2) { 2149 + u32temp |= 0x02020000; 2150 + } 2151 + if ((pcs_control_status & u32temp)!= u32temp) { 2152 + phy_data = 0; 2153 + nes_debug(NES_DBG_PHY, "PCS says the link is down\n"); 2154 + } 2155 + } else if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_IRIS) { 2156 + nes_read_10G_phy_reg(nesdev, 1, nesadapter->phy_index[mac_index]); 2157 + temp_phy_data = (u16)nes_read_indexed(nesdev, 2158 + NES_IDX_MAC_MDIO_CONTROL); 2159 + u32temp = 20; 2160 + do { 2161 + nes_read_10G_phy_reg(nesdev, 1, nesadapter->phy_index[mac_index]); 2162 + phy_data = (u16)nes_read_indexed(nesdev, 2163 + NES_IDX_MAC_MDIO_CONTROL); 2164 + if ((phy_data == temp_phy_data) || (!(--u32temp))) 2165 + break; 2166 + temp_phy_data = phy_data; 2167 + } while (1); 2168 + nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n", 2169 + __FUNCTION__, phy_data, nesadapter->mac_link_down ? "DOWN" : "UP"); 2170 + 2171 + } else { 2172 + phy_data = (0x0f0f0000 == (pcs_control_status & 0x0f1f0000)) ? 4 : 0; 2173 + } 2174 + 2175 + if (phy_data & 0x0004) { 2176 + nesadapter->mac_link_down[mac_index] = 0; 2177 + list_for_each_entry(nesvnic, &nesadapter->nesvnic_list[mac_index], list) { 2178 + nes_debug(NES_DBG_PHY, "The Link is UP!!. linkup was %d\n", 2179 + nesvnic->linkup); 2180 + if (nesvnic->linkup == 0) { 2181 + printk(PFX "The Link is now up for port %u, netdev %p.\n", 2182 + mac_index, nesvnic->netdev); 2183 + if (netif_queue_stopped(nesvnic->netdev)) 2184 + netif_start_queue(nesvnic->netdev); 2185 + nesvnic->linkup = 1; 2186 + netif_carrier_on(nesvnic->netdev); 2187 + } 2188 + } 2189 + } else { 2190 + nesadapter->mac_link_down[mac_index] = 1; 2191 + list_for_each_entry(nesvnic, &nesadapter->nesvnic_list[mac_index], list) { 2192 + nes_debug(NES_DBG_PHY, "The Link is Down!!. linkup was %d\n", 2193 + nesvnic->linkup); 2194 + if (nesvnic->linkup == 1) { 2195 + printk(PFX "The Link is now down for port %u, netdev %p.\n", 2196 + mac_index, nesvnic->netdev); 2197 + if (!(netif_queue_stopped(nesvnic->netdev))) 2198 + netif_stop_queue(nesvnic->netdev); 2199 + nesvnic->linkup = 0; 2200 + netif_carrier_off(nesvnic->netdev); 2201 + } 2202 + } 2203 + } 2204 + } 2205 + 2206 + nesadapter->mac_sw_state[mac_number] = NES_MAC_SW_IDLE; 2207 + } 2208 + 2209 + 2210 + 2211 + void nes_nic_napi_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq) 2212 + { 2213 + struct nes_vnic *nesvnic = container_of(cq, struct nes_vnic, nic_cq); 2214 + 2215 + netif_rx_schedule(nesdev->netdev[nesvnic->netdev_index], &nesvnic->napi); 2216 + } 2217 + 2218 + 2219 + /* The MAX_RQES_TO_PROCESS defines how many max read requests to complete before 2220 + * getting out of nic_ce_handler 2221 + */ 2222 + #define MAX_RQES_TO_PROCESS 384 2223 + 2224 + /** 2225 + * nes_nic_ce_handler 2226 + */ 2227 + void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq) 2228 + { 2229 + u64 u64temp; 2230 + dma_addr_t bus_address; 2231 + struct nes_hw_nic *nesnic; 2232 + struct nes_vnic *nesvnic = container_of(cq, struct nes_vnic, nic_cq); 2233 + struct nes_adapter *nesadapter = nesdev->nesadapter; 2234 + struct nes_hw_nic_rq_wqe *nic_rqe; 2235 + struct nes_hw_nic_sq_wqe *nic_sqe; 2236 + struct sk_buff *skb; 2237 + struct sk_buff *rx_skb; 2238 + __le16 *wqe_fragment_length; 2239 + u32 head; 2240 + u32 cq_size; 2241 + u32 rx_pkt_size; 2242 + u32 cqe_count=0; 2243 + u32 cqe_errv; 2244 + u32 cqe_misc; 2245 + u16 wqe_fragment_index = 1; /* first fragment (0) is used by copy buffer */ 2246 + u16 vlan_tag; 2247 + u16 pkt_type; 2248 + u16 rqes_processed = 0; 2249 + u8 sq_cqes = 0; 2250 + 2251 + head = cq->cq_head; 2252 + cq_size = cq->cq_size; 2253 + cq->cqes_pending = 1; 2254 + do { 2255 + if (le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_NIC_CQE_MISC_IDX]) & 2256 + NES_NIC_CQE_VALID) { 2257 + nesnic = &nesvnic->nic; 2258 + cqe_misc = le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_NIC_CQE_MISC_IDX]); 2259 + if (cqe_misc & NES_NIC_CQE_SQ) { 2260 + sq_cqes++; 2261 + wqe_fragment_index = 1; 2262 + nic_sqe = &nesnic->sq_vbase[nesnic->sq_tail]; 2263 + skb = nesnic->tx_skb[nesnic->sq_tail]; 2264 + wqe_fragment_length = (__le16 *)&nic_sqe->wqe_words[NES_NIC_SQ_WQE_LENGTH_0_TAG_IDX]; 2265 + /* bump past the vlan tag */ 2266 + wqe_fragment_length++; 2267 + if (le16_to_cpu(wqe_fragment_length[wqe_fragment_index]) != 0) { 2268 + u64temp = (u64) le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX+wqe_fragment_index*2]); 2269 + u64temp += ((u64)le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_HIGH_IDX+wqe_fragment_index*2]))<<32; 2270 + bus_address = (dma_addr_t)u64temp; 2271 + if (test_and_clear_bit(nesnic->sq_tail, nesnic->first_frag_overflow)) { 2272 + pci_unmap_single(nesdev->pcidev, 2273 + bus_address, 2274 + le16_to_cpu(wqe_fragment_length[wqe_fragment_index++]), 2275 + PCI_DMA_TODEVICE); 2276 + } 2277 + for (; wqe_fragment_index < 5; wqe_fragment_index++) { 2278 + if (wqe_fragment_length[wqe_fragment_index]) { 2279 + u64temp = le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX+wqe_fragment_index*2]); 2280 + u64temp += ((u64)le32_to_cpu(nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_HIGH_IDX+wqe_fragment_index*2]))<<32; 2281 + bus_address = (dma_addr_t)u64temp; 2282 + pci_unmap_page(nesdev->pcidev, 2283 + bus_address, 2284 + le16_to_cpu(wqe_fragment_length[wqe_fragment_index]), 2285 + PCI_DMA_TODEVICE); 2286 + } else 2287 + break; 2288 + } 2289 + if (skb) 2290 + dev_kfree_skb_any(skb); 2291 + } 2292 + nesnic->sq_tail++; 2293 + nesnic->sq_tail &= nesnic->sq_size-1; 2294 + if (sq_cqes > 128) { 2295 + barrier(); 2296 + /* restart the queue if it had been stopped */ 2297 + if (netif_queue_stopped(nesvnic->netdev)) 2298 + netif_wake_queue(nesvnic->netdev); 2299 + sq_cqes = 0; 2300 + } 2301 + } else { 2302 + rqes_processed ++; 2303 + 2304 + cq->rx_cqes_completed++; 2305 + cq->rx_pkts_indicated++; 2306 + rx_pkt_size = cqe_misc & 0x0000ffff; 2307 + nic_rqe = &nesnic->rq_vbase[nesnic->rq_tail]; 2308 + /* Get the skb */ 2309 + rx_skb = nesnic->rx_skb[nesnic->rq_tail]; 2310 + nic_rqe = &nesnic->rq_vbase[nesvnic->nic.rq_tail]; 2311 + bus_address = (dma_addr_t)le32_to_cpu(nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_LOW_IDX]); 2312 + bus_address += ((u64)le32_to_cpu(nic_rqe->wqe_words[NES_NIC_RQ_WQE_FRAG0_HIGH_IDX])) << 32; 2313 + pci_unmap_single(nesdev->pcidev, bus_address, 2314 + nesvnic->max_frame_size, PCI_DMA_FROMDEVICE); 2315 + /* rx_skb->tail = rx_skb->data + rx_pkt_size; */ 2316 + /* rx_skb->len = rx_pkt_size; */ 2317 + rx_skb->len = 0; /* TODO: see if this is necessary */ 2318 + skb_put(rx_skb, rx_pkt_size); 2319 + rx_skb->protocol = eth_type_trans(rx_skb, nesvnic->netdev); 2320 + nesnic->rq_tail++; 2321 + nesnic->rq_tail &= nesnic->rq_size - 1; 2322 + 2323 + atomic_inc(&nesvnic->rx_skbs_needed); 2324 + if (atomic_read(&nesvnic->rx_skbs_needed) > (nesvnic->nic.rq_size>>1)) { 2325 + nes_write32(nesdev->regs+NES_CQE_ALLOC, 2326 + cq->cq_number | (cqe_count << 16)); 2327 + // nesadapter->tune_timer.cq_count += cqe_count; 2328 + nesdev->currcq_count += cqe_count; 2329 + cqe_count = 0; 2330 + nes_replenish_nic_rq(nesvnic); 2331 + } 2332 + pkt_type = (u16)(le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_NIC_CQE_TAG_PKT_TYPE_IDX])); 2333 + cqe_errv = (cqe_misc & NES_NIC_CQE_ERRV_MASK) >> NES_NIC_CQE_ERRV_SHIFT; 2334 + rx_skb->ip_summed = CHECKSUM_NONE; 2335 + 2336 + if ((NES_PKT_TYPE_TCPV4_BITS == (pkt_type & NES_PKT_TYPE_TCPV4_MASK)) || 2337 + (NES_PKT_TYPE_UDPV4_BITS == (pkt_type & NES_PKT_TYPE_UDPV4_MASK))) { 2338 + if ((cqe_errv & 2339 + (NES_NIC_ERRV_BITS_IPV4_CSUM_ERR | NES_NIC_ERRV_BITS_TCPUDP_CSUM_ERR | 2340 + NES_NIC_ERRV_BITS_IPH_ERR | NES_NIC_ERRV_BITS_WQE_OVERRUN)) == 0) { 2341 + if (nesvnic->rx_checksum_disabled == 0) { 2342 + rx_skb->ip_summed = CHECKSUM_UNNECESSARY; 2343 + } 2344 + } else 2345 + nes_debug(NES_DBG_CQ, "%s: unsuccessfully checksummed TCP or UDP packet." 2346 + " errv = 0x%X, pkt_type = 0x%X.\n", 2347 + nesvnic->netdev->name, cqe_errv, pkt_type); 2348 + 2349 + } else if ((pkt_type & NES_PKT_TYPE_IPV4_MASK) == NES_PKT_TYPE_IPV4_BITS) { 2350 + if ((cqe_errv & 2351 + (NES_NIC_ERRV_BITS_IPV4_CSUM_ERR | NES_NIC_ERRV_BITS_IPH_ERR | 2352 + NES_NIC_ERRV_BITS_WQE_OVERRUN)) == 0) { 2353 + if (nesvnic->rx_checksum_disabled == 0) { 2354 + rx_skb->ip_summed = CHECKSUM_UNNECESSARY; 2355 + /* nes_debug(NES_DBG_CQ, "%s: Reporting successfully checksummed IPv4 packet.\n", 2356 + nesvnic->netdev->name); */ 2357 + } 2358 + } else 2359 + nes_debug(NES_DBG_CQ, "%s: unsuccessfully checksummed TCP or UDP packet." 2360 + " errv = 0x%X, pkt_type = 0x%X.\n", 2361 + nesvnic->netdev->name, cqe_errv, pkt_type); 2362 + } 2363 + /* nes_debug(NES_DBG_CQ, "pkt_type=%x, APBVT_MASK=%x\n", 2364 + pkt_type, (pkt_type & NES_PKT_TYPE_APBVT_MASK)); */ 2365 + 2366 + if ((pkt_type & NES_PKT_TYPE_APBVT_MASK) == NES_PKT_TYPE_APBVT_BITS) { 2367 + nes_cm_recv(rx_skb, nesvnic->netdev); 2368 + } else { 2369 + if ((cqe_misc & NES_NIC_CQE_TAG_VALID) && (nesvnic->vlan_grp != NULL)) { 2370 + vlan_tag = (u16)(le32_to_cpu( 2371 + cq->cq_vbase[head].cqe_words[NES_NIC_CQE_TAG_PKT_TYPE_IDX]) 2372 + >> 16); 2373 + nes_debug(NES_DBG_CQ, "%s: Reporting stripped VLAN packet. Tag = 0x%04X\n", 2374 + nesvnic->netdev->name, vlan_tag); 2375 + nes_vlan_rx(rx_skb, nesvnic->vlan_grp, vlan_tag); 2376 + } else { 2377 + nes_netif_rx(rx_skb); 2378 + } 2379 + } 2380 + 2381 + nesvnic->netdev->last_rx = jiffies; 2382 + /* nesvnic->netstats.rx_packets++; */ 2383 + /* nesvnic->netstats.rx_bytes += rx_pkt_size; */ 2384 + } 2385 + 2386 + cq->cq_vbase[head].cqe_words[NES_NIC_CQE_MISC_IDX] = 0; 2387 + /* Accounting... */ 2388 + cqe_count++; 2389 + if (++head >= cq_size) 2390 + head = 0; 2391 + if (cqe_count == 255) { 2392 + /* Replenish Nic CQ */ 2393 + nes_write32(nesdev->regs+NES_CQE_ALLOC, 2394 + cq->cq_number | (cqe_count << 16)); 2395 + // nesdev->nesadapter->tune_timer.cq_count += cqe_count; 2396 + nesdev->currcq_count += cqe_count; 2397 + cqe_count = 0; 2398 + } 2399 + 2400 + if (cq->rx_cqes_completed >= nesvnic->budget) 2401 + break; 2402 + } else { 2403 + cq->cqes_pending = 0; 2404 + break; 2405 + } 2406 + 2407 + } while (1); 2408 + 2409 + if (sq_cqes) { 2410 + barrier(); 2411 + /* restart the queue if it had been stopped */ 2412 + if (netif_queue_stopped(nesvnic->netdev)) 2413 + netif_wake_queue(nesvnic->netdev); 2414 + } 2415 + 2416 + cq->cq_head = head; 2417 + /* nes_debug(NES_DBG_CQ, "CQ%u Processed = %u cqes, new head = %u.\n", 2418 + cq->cq_number, cqe_count, cq->cq_head); */ 2419 + cq->cqe_allocs_pending = cqe_count; 2420 + if (unlikely(nesadapter->et_use_adaptive_rx_coalesce)) 2421 + { 2422 + // nesdev->nesadapter->tune_timer.cq_count += cqe_count; 2423 + nesdev->currcq_count += cqe_count; 2424 + nes_nic_tune_timer(nesdev); 2425 + } 2426 + if (atomic_read(&nesvnic->rx_skbs_needed)) 2427 + nes_replenish_nic_rq(nesvnic); 2428 + } 2429 + 2430 + 2431 + /** 2432 + * nes_cqp_ce_handler 2433 + */ 2434 + void nes_cqp_ce_handler(struct nes_device *nesdev, struct nes_hw_cq *cq) 2435 + { 2436 + u64 u64temp; 2437 + unsigned long flags; 2438 + struct nes_hw_cqp *cqp = NULL; 2439 + struct nes_cqp_request *cqp_request; 2440 + struct nes_hw_cqp_wqe *cqp_wqe; 2441 + u32 head; 2442 + u32 cq_size; 2443 + u32 cqe_count=0; 2444 + u32 error_code; 2445 + /* u32 counter; */ 2446 + 2447 + head = cq->cq_head; 2448 + cq_size = cq->cq_size; 2449 + 2450 + do { 2451 + /* process the CQE */ 2452 + /* nes_debug(NES_DBG_CQP, "head=%u cqe_words=%08X\n", head, 2453 + le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX])); */ 2454 + 2455 + if (le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX]) & NES_CQE_VALID) { 2456 + u64temp = (((u64)(le32_to_cpu(cq->cq_vbase[head]. 2457 + cqe_words[NES_CQE_COMP_COMP_CTX_HIGH_IDX])))<<32) | 2458 + ((u64)(le32_to_cpu(cq->cq_vbase[head]. 2459 + cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX]))); 2460 + cqp = *((struct nes_hw_cqp **)&u64temp); 2461 + 2462 + error_code = le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_CQE_ERROR_CODE_IDX]); 2463 + if (error_code) { 2464 + nes_debug(NES_DBG_CQP, "Bad Completion code for opcode 0x%02X from CQP," 2465 + " Major/Minor codes = 0x%04X:%04X.\n", 2466 + le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX])&0x3f, 2467 + (u16)(error_code >> 16), 2468 + (u16)error_code); 2469 + nes_debug(NES_DBG_CQP, "cqp: qp_id=%u, sq_head=%u, sq_tail=%u\n", 2470 + cqp->qp_id, cqp->sq_head, cqp->sq_tail); 2471 + } 2472 + 2473 + u64temp = (((u64)(le32_to_cpu(nesdev->cqp.sq_vbase[cqp->sq_tail]. 2474 + wqe_words[NES_CQP_WQE_COMP_SCRATCH_HIGH_IDX])))<<32) | 2475 + ((u64)(le32_to_cpu(nesdev->cqp.sq_vbase[cqp->sq_tail]. 2476 + wqe_words[NES_CQP_WQE_COMP_SCRATCH_LOW_IDX]))); 2477 + cqp_request = *((struct nes_cqp_request **)&u64temp); 2478 + if (cqp_request) { 2479 + if (cqp_request->waiting) { 2480 + /* nes_debug(NES_DBG_CQP, "%s: Waking up requestor\n"); */ 2481 + cqp_request->major_code = (u16)(error_code >> 16); 2482 + cqp_request->minor_code = (u16)error_code; 2483 + barrier(); 2484 + cqp_request->request_done = 1; 2485 + wake_up(&cqp_request->waitq); 2486 + if (atomic_dec_and_test(&cqp_request->refcount)) { 2487 + nes_debug(NES_DBG_CQP, "CQP request %p (opcode 0x%02X) freed.\n", 2488 + cqp_request, 2489 + le32_to_cpu(cqp_request->cqp_wqe.wqe_words[NES_CQP_WQE_OPCODE_IDX])&0x3f); 2490 + if (cqp_request->dynamic) { 2491 + kfree(cqp_request); 2492 + } else { 2493 + spin_lock_irqsave(&nesdev->cqp.lock, flags); 2494 + list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); 2495 + spin_unlock_irqrestore(&nesdev->cqp.lock, flags); 2496 + } 2497 + } 2498 + } else if (cqp_request->callback) { 2499 + /* Envoke the callback routine */ 2500 + cqp_request->cqp_callback(nesdev, cqp_request); 2501 + if (cqp_request->dynamic) { 2502 + kfree(cqp_request); 2503 + } else { 2504 + spin_lock_irqsave(&nesdev->cqp.lock, flags); 2505 + list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); 2506 + spin_unlock_irqrestore(&nesdev->cqp.lock, flags); 2507 + } 2508 + } else { 2509 + nes_debug(NES_DBG_CQP, "CQP request %p (opcode 0x%02X) freed.\n", 2510 + cqp_request, 2511 + le32_to_cpu(cqp_request->cqp_wqe.wqe_words[NES_CQP_WQE_OPCODE_IDX])&0x3f); 2512 + if (cqp_request->dynamic) { 2513 + kfree(cqp_request); 2514 + } else { 2515 + spin_lock_irqsave(&nesdev->cqp.lock, flags); 2516 + list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); 2517 + spin_unlock_irqrestore(&nesdev->cqp.lock, flags); 2518 + } 2519 + } 2520 + } else { 2521 + wake_up(&nesdev->cqp.waitq); 2522 + } 2523 + 2524 + cq->cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX] = 0; 2525 + nes_write32(nesdev->regs+NES_CQE_ALLOC, cq->cq_number | (1 << 16)); 2526 + if (++cqp->sq_tail >= cqp->sq_size) 2527 + cqp->sq_tail = 0; 2528 + 2529 + /* Accounting... */ 2530 + cqe_count++; 2531 + if (++head >= cq_size) 2532 + head = 0; 2533 + } else { 2534 + break; 2535 + } 2536 + } while (1); 2537 + cq->cq_head = head; 2538 + 2539 + spin_lock_irqsave(&nesdev->cqp.lock, flags); 2540 + while ((!list_empty(&nesdev->cqp_pending_reqs)) && 2541 + ((((nesdev->cqp.sq_tail+nesdev->cqp.sq_size)-nesdev->cqp.sq_head) & 2542 + (nesdev->cqp.sq_size - 1)) != 1)) { 2543 + cqp_request = list_entry(nesdev->cqp_pending_reqs.next, 2544 + struct nes_cqp_request, list); 2545 + list_del_init(&cqp_request->list); 2546 + head = nesdev->cqp.sq_head++; 2547 + nesdev->cqp.sq_head &= nesdev->cqp.sq_size-1; 2548 + cqp_wqe = &nesdev->cqp.sq_vbase[head]; 2549 + memcpy(cqp_wqe, &cqp_request->cqp_wqe, sizeof(*cqp_wqe)); 2550 + barrier(); 2551 + cqp_wqe->wqe_words[NES_CQP_WQE_COMP_SCRATCH_LOW_IDX] = 2552 + cpu_to_le32((u32)((unsigned long)cqp_request)); 2553 + cqp_wqe->wqe_words[NES_CQP_WQE_COMP_SCRATCH_HIGH_IDX] = 2554 + cpu_to_le32((u32)(upper_32_bits((unsigned long)cqp_request))); 2555 + nes_debug(NES_DBG_CQP, "CQP request %p (opcode 0x%02X) put on CQPs SQ wqe%u.\n", 2556 + cqp_request, le32_to_cpu(cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX])&0x3f, head); 2557 + /* Ring doorbell (1 WQEs) */ 2558 + barrier(); 2559 + nes_write32(nesdev->regs+NES_WQE_ALLOC, 0x01800000 | nesdev->cqp.qp_id); 2560 + } 2561 + spin_unlock_irqrestore(&nesdev->cqp.lock, flags); 2562 + 2563 + /* Arm the CCQ */ 2564 + nes_write32(nesdev->regs+NES_CQE_ALLOC, NES_CQE_ALLOC_NOTIFY_NEXT | 2565 + cq->cq_number); 2566 + nes_read32(nesdev->regs+NES_CQE_ALLOC); 2567 + } 2568 + 2569 + 2570 + /** 2571 + * nes_process_iwarp_aeqe 2572 + */ 2573 + void nes_process_iwarp_aeqe(struct nes_device *nesdev, struct nes_hw_aeqe *aeqe) 2574 + { 2575 + u64 context; 2576 + u64 aeqe_context = 0; 2577 + unsigned long flags; 2578 + struct nes_qp *nesqp; 2579 + int resource_allocated; 2580 + /* struct iw_cm_id *cm_id; */ 2581 + struct nes_adapter *nesadapter = nesdev->nesadapter; 2582 + struct ib_event ibevent; 2583 + /* struct iw_cm_event cm_event; */ 2584 + u32 aeq_info; 2585 + u32 next_iwarp_state = 0; 2586 + u16 async_event_id; 2587 + u8 tcp_state; 2588 + u8 iwarp_state; 2589 + 2590 + nes_debug(NES_DBG_AEQ, "\n"); 2591 + aeq_info = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_MISC_IDX]); 2592 + if ((NES_AEQE_INBOUND_RDMA&aeq_info) || (!(NES_AEQE_QP&aeq_info))) { 2593 + context = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_LOW_IDX]); 2594 + context += ((u64)le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_HIGH_IDX])) << 32; 2595 + } else { 2596 + aeqe_context = le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_LOW_IDX]); 2597 + aeqe_context += ((u64)le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_CTXT_HIGH_IDX])) << 32; 2598 + context = (unsigned long)nesadapter->qp_table[le32_to_cpu( 2599 + aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX])-NES_FIRST_QPN]; 2600 + BUG_ON(!context); 2601 + } 2602 + 2603 + async_event_id = (u16)aeq_info; 2604 + tcp_state = (aeq_info & NES_AEQE_TCP_STATE_MASK) >> NES_AEQE_TCP_STATE_SHIFT; 2605 + iwarp_state = (aeq_info & NES_AEQE_IWARP_STATE_MASK) >> NES_AEQE_IWARP_STATE_SHIFT; 2606 + nes_debug(NES_DBG_AEQ, "aeid = 0x%04X, qp-cq id = %d, aeqe = %p," 2607 + " Tcp state = %s, iWARP state = %s\n", 2608 + async_event_id, 2609 + le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]), aeqe, 2610 + nes_tcp_state_str[tcp_state], nes_iwarp_state_str[iwarp_state]); 2611 + 2612 + 2613 + switch (async_event_id) { 2614 + case NES_AEQE_AEID_LLP_FIN_RECEIVED: 2615 + nesqp = *((struct nes_qp **)&context); 2616 + if (atomic_inc_return(&nesqp->close_timer_started) == 1) { 2617 + nesqp->cm_id->add_ref(nesqp->cm_id); 2618 + nes_add_ref(&nesqp->ibqp); 2619 + schedule_nes_timer(nesqp->cm_node, (struct sk_buff *)nesqp, 2620 + NES_TIMER_TYPE_CLOSE, 1, 0); 2621 + nes_debug(NES_DBG_AEQ, "QP%u Not decrementing QP refcount (%d)," 2622 + " need ae to finish up, original_last_aeq = 0x%04X." 2623 + " last_aeq = 0x%04X, scheduling timer. TCP state = %d\n", 2624 + nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount), 2625 + async_event_id, nesqp->last_aeq, tcp_state); 2626 + } 2627 + if ((tcp_state != NES_AEQE_TCP_STATE_CLOSE_WAIT) || 2628 + (nesqp->ibqp_state != IB_QPS_RTS)) { 2629 + /* FIN Received but tcp state or IB state moved on, 2630 + should expect a close complete */ 2631 + return; 2632 + } 2633 + case NES_AEQE_AEID_LLP_CLOSE_COMPLETE: 2634 + case NES_AEQE_AEID_LLP_CONNECTION_RESET: 2635 + case NES_AEQE_AEID_TERMINATE_SENT: 2636 + case NES_AEQE_AEID_RDMAP_ROE_BAD_LLP_CLOSE: 2637 + case NES_AEQE_AEID_RESET_SENT: 2638 + nesqp = *((struct nes_qp **)&context); 2639 + if (async_event_id == NES_AEQE_AEID_RESET_SENT) { 2640 + tcp_state = NES_AEQE_TCP_STATE_CLOSED; 2641 + } 2642 + nes_add_ref(&nesqp->ibqp); 2643 + spin_lock_irqsave(&nesqp->lock, flags); 2644 + nesqp->hw_iwarp_state = iwarp_state; 2645 + nesqp->hw_tcp_state = tcp_state; 2646 + nesqp->last_aeq = async_event_id; 2647 + 2648 + if ((tcp_state == NES_AEQE_TCP_STATE_CLOSED) || 2649 + (tcp_state == NES_AEQE_TCP_STATE_TIME_WAIT)) { 2650 + nesqp->hte_added = 0; 2651 + spin_unlock_irqrestore(&nesqp->lock, flags); 2652 + nes_debug(NES_DBG_AEQ, "issuing hw modifyqp for QP%u to remove hte\n", 2653 + nesqp->hwqp.qp_id); 2654 + nes_hw_modify_qp(nesdev, nesqp, 2655 + NES_CQP_QP_IWARP_STATE_ERROR | NES_CQP_QP_DEL_HTE, 0); 2656 + spin_lock_irqsave(&nesqp->lock, flags); 2657 + } 2658 + 2659 + if ((nesqp->ibqp_state == IB_QPS_RTS) && 2660 + ((tcp_state == NES_AEQE_TCP_STATE_CLOSE_WAIT) || 2661 + (async_event_id == NES_AEQE_AEID_LLP_CONNECTION_RESET))) { 2662 + switch (nesqp->hw_iwarp_state) { 2663 + case NES_AEQE_IWARP_STATE_RTS: 2664 + next_iwarp_state = NES_CQP_QP_IWARP_STATE_CLOSING; 2665 + nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_CLOSING; 2666 + break; 2667 + case NES_AEQE_IWARP_STATE_TERMINATE: 2668 + next_iwarp_state = NES_CQP_QP_IWARP_STATE_TERMINATE; 2669 + nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_TERMINATE; 2670 + if (async_event_id == NES_AEQE_AEID_RDMAP_ROE_BAD_LLP_CLOSE) { 2671 + next_iwarp_state |= 0x02000000; 2672 + nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED; 2673 + } 2674 + break; 2675 + default: 2676 + next_iwarp_state = 0; 2677 + } 2678 + spin_unlock_irqrestore(&nesqp->lock, flags); 2679 + if (next_iwarp_state) { 2680 + nes_add_ref(&nesqp->ibqp); 2681 + nes_debug(NES_DBG_AEQ, "issuing hw modifyqp for QP%u. next state = 0x%08X," 2682 + " also added another reference\n", 2683 + nesqp->hwqp.qp_id, next_iwarp_state); 2684 + nes_hw_modify_qp(nesdev, nesqp, next_iwarp_state, 0); 2685 + } 2686 + nes_cm_disconn(nesqp); 2687 + } else { 2688 + if (async_event_id == NES_AEQE_AEID_LLP_FIN_RECEIVED) { 2689 + /* FIN Received but ib state not RTS, 2690 + close complete will be on its way */ 2691 + spin_unlock_irqrestore(&nesqp->lock, flags); 2692 + nes_rem_ref(&nesqp->ibqp); 2693 + return; 2694 + } 2695 + spin_unlock_irqrestore(&nesqp->lock, flags); 2696 + if (async_event_id == NES_AEQE_AEID_RDMAP_ROE_BAD_LLP_CLOSE) { 2697 + next_iwarp_state = NES_CQP_QP_IWARP_STATE_TERMINATE | 0x02000000; 2698 + nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED; 2699 + nes_debug(NES_DBG_AEQ, "issuing hw modifyqp for QP%u. next state = 0x%08X," 2700 + " also added another reference\n", 2701 + nesqp->hwqp.qp_id, next_iwarp_state); 2702 + nes_hw_modify_qp(nesdev, nesqp, next_iwarp_state, 0); 2703 + } 2704 + nes_cm_disconn(nesqp); 2705 + } 2706 + break; 2707 + case NES_AEQE_AEID_LLP_TERMINATE_RECEIVED: 2708 + nesqp = *((struct nes_qp **)&context); 2709 + spin_lock_irqsave(&nesqp->lock, flags); 2710 + nesqp->hw_iwarp_state = iwarp_state; 2711 + nesqp->hw_tcp_state = tcp_state; 2712 + nesqp->last_aeq = async_event_id; 2713 + spin_unlock_irqrestore(&nesqp->lock, flags); 2714 + nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_LLP_TERMINATE_RECEIVED" 2715 + " event on QP%u \n Q2 Data:\n", 2716 + nesqp->hwqp.qp_id); 2717 + if (nesqp->ibqp.event_handler) { 2718 + ibevent.device = nesqp->ibqp.device; 2719 + ibevent.element.qp = &nesqp->ibqp; 2720 + ibevent.event = IB_EVENT_QP_FATAL; 2721 + nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context); 2722 + } 2723 + if ((tcp_state == NES_AEQE_TCP_STATE_CLOSE_WAIT) || 2724 + ((nesqp->ibqp_state == IB_QPS_RTS)&& 2725 + (async_event_id == NES_AEQE_AEID_LLP_CONNECTION_RESET))) { 2726 + nes_add_ref(&nesqp->ibqp); 2727 + nes_cm_disconn(nesqp); 2728 + } else { 2729 + nesqp->in_disconnect = 0; 2730 + wake_up(&nesqp->kick_waitq); 2731 + } 2732 + break; 2733 + case NES_AEQE_AEID_LLP_TOO_MANY_RETRIES: 2734 + nesqp = *((struct nes_qp **)&context); 2735 + nes_add_ref(&nesqp->ibqp); 2736 + spin_lock_irqsave(&nesqp->lock, flags); 2737 + nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_ERROR; 2738 + nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED; 2739 + nesqp->last_aeq = async_event_id; 2740 + if (nesqp->cm_id) { 2741 + nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_LLP_TOO_MANY_RETRIES" 2742 + " event on QP%u, remote IP = 0x%08X \n", 2743 + nesqp->hwqp.qp_id, 2744 + ntohl(nesqp->cm_id->remote_addr.sin_addr.s_addr)); 2745 + } else { 2746 + nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_LLP_TOO_MANY_RETRIES" 2747 + " event on QP%u \n", 2748 + nesqp->hwqp.qp_id); 2749 + } 2750 + spin_unlock_irqrestore(&nesqp->lock, flags); 2751 + next_iwarp_state = NES_CQP_QP_IWARP_STATE_ERROR | NES_CQP_QP_RESET; 2752 + nes_hw_modify_qp(nesdev, nesqp, next_iwarp_state, 0); 2753 + if (nesqp->ibqp.event_handler) { 2754 + ibevent.device = nesqp->ibqp.device; 2755 + ibevent.element.qp = &nesqp->ibqp; 2756 + ibevent.event = IB_EVENT_QP_FATAL; 2757 + nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context); 2758 + } 2759 + break; 2760 + case NES_AEQE_AEID_AMP_BAD_STAG_INDEX: 2761 + if (NES_AEQE_INBOUND_RDMA&aeq_info) { 2762 + nesqp = nesadapter->qp_table[le32_to_cpu( 2763 + aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX])-NES_FIRST_QPN]; 2764 + } else { 2765 + /* TODO: get the actual WQE and mask off wqe index */ 2766 + context &= ~((u64)511); 2767 + nesqp = *((struct nes_qp **)&context); 2768 + } 2769 + spin_lock_irqsave(&nesqp->lock, flags); 2770 + nesqp->hw_iwarp_state = iwarp_state; 2771 + nesqp->hw_tcp_state = tcp_state; 2772 + nesqp->last_aeq = async_event_id; 2773 + spin_unlock_irqrestore(&nesqp->lock, flags); 2774 + nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_AMP_BAD_STAG_INDEX event on QP%u\n", 2775 + nesqp->hwqp.qp_id); 2776 + if (nesqp->ibqp.event_handler) { 2777 + ibevent.device = nesqp->ibqp.device; 2778 + ibevent.element.qp = &nesqp->ibqp; 2779 + ibevent.event = IB_EVENT_QP_ACCESS_ERR; 2780 + nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context); 2781 + } 2782 + break; 2783 + case NES_AEQE_AEID_AMP_UNALLOCATED_STAG: 2784 + nesqp = *((struct nes_qp **)&context); 2785 + spin_lock_irqsave(&nesqp->lock, flags); 2786 + nesqp->hw_iwarp_state = iwarp_state; 2787 + nesqp->hw_tcp_state = tcp_state; 2788 + nesqp->last_aeq = async_event_id; 2789 + spin_unlock_irqrestore(&nesqp->lock, flags); 2790 + nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_AMP_UNALLOCATED_STAG event on QP%u\n", 2791 + nesqp->hwqp.qp_id); 2792 + if (nesqp->ibqp.event_handler) { 2793 + ibevent.device = nesqp->ibqp.device; 2794 + ibevent.element.qp = &nesqp->ibqp; 2795 + ibevent.event = IB_EVENT_QP_ACCESS_ERR; 2796 + nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context); 2797 + } 2798 + break; 2799 + case NES_AEQE_AEID_PRIV_OPERATION_DENIED: 2800 + nesqp = nesadapter->qp_table[le32_to_cpu(aeqe->aeqe_words 2801 + [NES_AEQE_COMP_QP_CQ_ID_IDX])-NES_FIRST_QPN]; 2802 + spin_lock_irqsave(&nesqp->lock, flags); 2803 + nesqp->hw_iwarp_state = iwarp_state; 2804 + nesqp->hw_tcp_state = tcp_state; 2805 + nesqp->last_aeq = async_event_id; 2806 + spin_unlock_irqrestore(&nesqp->lock, flags); 2807 + nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_PRIV_OPERATION_DENIED event on QP%u," 2808 + " nesqp = %p, AE reported %p\n", 2809 + nesqp->hwqp.qp_id, nesqp, *((struct nes_qp **)&context)); 2810 + if (nesqp->ibqp.event_handler) { 2811 + ibevent.device = nesqp->ibqp.device; 2812 + ibevent.element.qp = &nesqp->ibqp; 2813 + ibevent.event = IB_EVENT_QP_ACCESS_ERR; 2814 + nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context); 2815 + } 2816 + break; 2817 + case NES_AEQE_AEID_CQ_OPERATION_ERROR: 2818 + context <<= 1; 2819 + nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_CQ_OPERATION_ERROR event on CQ%u, %p\n", 2820 + le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX]), (void *)(unsigned long)context); 2821 + resource_allocated = nes_is_resource_allocated(nesadapter, nesadapter->allocated_cqs, 2822 + le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX])); 2823 + if (resource_allocated) { 2824 + printk(KERN_ERR PFX "%s: Processing an NES_AEQE_AEID_CQ_OPERATION_ERROR event on CQ%u\n", 2825 + __FUNCTION__, le32_to_cpu(aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX])); 2826 + } 2827 + break; 2828 + case NES_AEQE_AEID_DDP_UBE_DDP_MESSAGE_TOO_LONG_FOR_AVAILABLE_BUFFER: 2829 + nesqp = nesadapter->qp_table[le32_to_cpu( 2830 + aeqe->aeqe_words[NES_AEQE_COMP_QP_CQ_ID_IDX])-NES_FIRST_QPN]; 2831 + spin_lock_irqsave(&nesqp->lock, flags); 2832 + nesqp->hw_iwarp_state = iwarp_state; 2833 + nesqp->hw_tcp_state = tcp_state; 2834 + nesqp->last_aeq = async_event_id; 2835 + spin_unlock_irqrestore(&nesqp->lock, flags); 2836 + nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_DDP_UBE_DDP_MESSAGE_TOO_LONG" 2837 + "_FOR_AVAILABLE_BUFFER event on QP%u\n", 2838 + nesqp->hwqp.qp_id); 2839 + if (nesqp->ibqp.event_handler) { 2840 + ibevent.device = nesqp->ibqp.device; 2841 + ibevent.element.qp = &nesqp->ibqp; 2842 + ibevent.event = IB_EVENT_QP_ACCESS_ERR; 2843 + nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context); 2844 + } 2845 + /* tell cm to disconnect, cm will queue work to thread */ 2846 + nes_add_ref(&nesqp->ibqp); 2847 + nes_cm_disconn(nesqp); 2848 + break; 2849 + case NES_AEQE_AEID_DDP_UBE_INVALID_MSN_NO_BUFFER_AVAILABLE: 2850 + nesqp = *((struct nes_qp **)&context); 2851 + spin_lock_irqsave(&nesqp->lock, flags); 2852 + nesqp->hw_iwarp_state = iwarp_state; 2853 + nesqp->hw_tcp_state = tcp_state; 2854 + nesqp->last_aeq = async_event_id; 2855 + spin_unlock_irqrestore(&nesqp->lock, flags); 2856 + nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_DDP_UBE_INVALID_MSN" 2857 + "_NO_BUFFER_AVAILABLE event on QP%u\n", 2858 + nesqp->hwqp.qp_id); 2859 + if (nesqp->ibqp.event_handler) { 2860 + ibevent.device = nesqp->ibqp.device; 2861 + ibevent.element.qp = &nesqp->ibqp; 2862 + ibevent.event = IB_EVENT_QP_FATAL; 2863 + nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context); 2864 + } 2865 + /* tell cm to disconnect, cm will queue work to thread */ 2866 + nes_add_ref(&nesqp->ibqp); 2867 + nes_cm_disconn(nesqp); 2868 + break; 2869 + case NES_AEQE_AEID_LLP_RECEIVED_MPA_CRC_ERROR: 2870 + nesqp = *((struct nes_qp **)&context); 2871 + spin_lock_irqsave(&nesqp->lock, flags); 2872 + nesqp->hw_iwarp_state = iwarp_state; 2873 + nesqp->hw_tcp_state = tcp_state; 2874 + nesqp->last_aeq = async_event_id; 2875 + spin_unlock_irqrestore(&nesqp->lock, flags); 2876 + nes_debug(NES_DBG_AEQ, "Processing an NES_AEQE_AEID_LLP_RECEIVED_MPA_CRC_ERROR" 2877 + " event on QP%u \n Q2 Data:\n", 2878 + nesqp->hwqp.qp_id); 2879 + if (nesqp->ibqp.event_handler) { 2880 + ibevent.device = nesqp->ibqp.device; 2881 + ibevent.element.qp = &nesqp->ibqp; 2882 + ibevent.event = IB_EVENT_QP_FATAL; 2883 + nesqp->ibqp.event_handler(&ibevent, nesqp->ibqp.qp_context); 2884 + } 2885 + /* tell cm to disconnect, cm will queue work to thread */ 2886 + nes_add_ref(&nesqp->ibqp); 2887 + nes_cm_disconn(nesqp); 2888 + break; 2889 + /* TODO: additional AEs need to be here */ 2890 + default: 2891 + nes_debug(NES_DBG_AEQ, "Processing an iWARP related AE for QP, misc = 0x%04X\n", 2892 + async_event_id); 2893 + break; 2894 + } 2895 + 2896 + } 2897 + 2898 + 2899 + /** 2900 + * nes_iwarp_ce_handler 2901 + */ 2902 + void nes_iwarp_ce_handler(struct nes_device *nesdev, struct nes_hw_cq *hw_cq) 2903 + { 2904 + struct nes_cq *nescq = container_of(hw_cq, struct nes_cq, hw_cq); 2905 + 2906 + /* nes_debug(NES_DBG_CQ, "Processing completion event for iWARP CQ%u.\n", 2907 + nescq->hw_cq.cq_number); */ 2908 + nes_write32(nesdev->regs+NES_CQ_ACK, nescq->hw_cq.cq_number); 2909 + 2910 + if (nescq->ibcq.comp_handler) 2911 + nescq->ibcq.comp_handler(&nescq->ibcq, nescq->ibcq.cq_context); 2912 + 2913 + return; 2914 + } 2915 + 2916 + 2917 + /** 2918 + * nes_manage_apbvt() 2919 + */ 2920 + int nes_manage_apbvt(struct nes_vnic *nesvnic, u32 accel_local_port, 2921 + u32 nic_index, u32 add_port) 2922 + { 2923 + struct nes_device *nesdev = nesvnic->nesdev; 2924 + struct nes_hw_cqp_wqe *cqp_wqe; 2925 + unsigned long flags; 2926 + struct nes_cqp_request *cqp_request; 2927 + int ret = 0; 2928 + u16 major_code; 2929 + 2930 + /* Send manage APBVT request to CQP */ 2931 + cqp_request = nes_get_cqp_request(nesdev); 2932 + if (cqp_request == NULL) { 2933 + nes_debug(NES_DBG_QP, "Failed to get a cqp_request.\n"); 2934 + return -ENOMEM; 2935 + } 2936 + cqp_request->waiting = 1; 2937 + cqp_wqe = &cqp_request->cqp_wqe; 2938 + 2939 + nes_debug(NES_DBG_QP, "%s APBV for local port=%u(0x%04x), nic_index=%u\n", 2940 + (add_port == NES_MANAGE_APBVT_ADD) ? "ADD" : "DEL", 2941 + accel_local_port, accel_local_port, nic_index); 2942 + 2943 + nes_fill_init_cqp_wqe(cqp_wqe, nesdev); 2944 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX, (NES_CQP_MANAGE_APBVT | 2945 + ((add_port == NES_MANAGE_APBVT_ADD) ? NES_CQP_APBVT_ADD : 0))); 2946 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_ID_IDX, 2947 + ((nic_index << NES_CQP_APBVT_NIC_SHIFT) | accel_local_port)); 2948 + 2949 + nes_debug(NES_DBG_QP, "Waiting for CQP completion for APBVT.\n"); 2950 + 2951 + atomic_set(&cqp_request->refcount, 2); 2952 + nes_post_cqp_request(nesdev, cqp_request, NES_CQP_REQUEST_RING_DOORBELL); 2953 + 2954 + if (add_port == NES_MANAGE_APBVT_ADD) 2955 + ret = wait_event_timeout(cqp_request->waitq, (cqp_request->request_done != 0), 2956 + NES_EVENT_TIMEOUT); 2957 + nes_debug(NES_DBG_QP, "Completed, ret=%u, CQP Major:Minor codes = 0x%04X:0x%04X\n", 2958 + ret, cqp_request->major_code, cqp_request->minor_code); 2959 + major_code = cqp_request->major_code; 2960 + if (atomic_dec_and_test(&cqp_request->refcount)) { 2961 + if (cqp_request->dynamic) { 2962 + kfree(cqp_request); 2963 + } else { 2964 + spin_lock_irqsave(&nesdev->cqp.lock, flags); 2965 + list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); 2966 + spin_unlock_irqrestore(&nesdev->cqp.lock, flags); 2967 + } 2968 + } 2969 + if (!ret) 2970 + return -ETIME; 2971 + else if (major_code) 2972 + return -EIO; 2973 + else 2974 + return 0; 2975 + } 2976 + 2977 + 2978 + /** 2979 + * nes_manage_arp_cache 2980 + */ 2981 + void nes_manage_arp_cache(struct net_device *netdev, unsigned char *mac_addr, 2982 + u32 ip_addr, u32 action) 2983 + { 2984 + struct nes_hw_cqp_wqe *cqp_wqe; 2985 + struct nes_vnic *nesvnic = netdev_priv(netdev); 2986 + struct nes_device *nesdev; 2987 + struct nes_cqp_request *cqp_request; 2988 + int arp_index; 2989 + 2990 + nesdev = nesvnic->nesdev; 2991 + arp_index = nes_arp_table(nesdev, ip_addr, mac_addr, action); 2992 + if (arp_index == -1) { 2993 + return; 2994 + } 2995 + 2996 + /* update the ARP entry */ 2997 + cqp_request = nes_get_cqp_request(nesdev); 2998 + if (cqp_request == NULL) { 2999 + nes_debug(NES_DBG_NETDEV, "Failed to get a cqp_request.\n"); 3000 + return; 3001 + } 3002 + cqp_request->waiting = 0; 3003 + cqp_wqe = &cqp_request->cqp_wqe; 3004 + nes_fill_init_cqp_wqe(cqp_wqe, nesdev); 3005 + 3006 + cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = cpu_to_le32( 3007 + NES_CQP_MANAGE_ARP_CACHE | NES_CQP_ARP_PERM); 3008 + cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] |= cpu_to_le32( 3009 + (u32)PCI_FUNC(nesdev->pcidev->devfn) << NES_CQP_ARP_AEQ_INDEX_SHIFT); 3010 + cqp_wqe->wqe_words[NES_CQP_WQE_ID_IDX] = cpu_to_le32(arp_index); 3011 + 3012 + if (action == NES_ARP_ADD) { 3013 + cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] |= cpu_to_le32(NES_CQP_ARP_VALID); 3014 + cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_ADDR_LOW_IDX] = cpu_to_le32( 3015 + (((u32)mac_addr[2]) << 24) | (((u32)mac_addr[3]) << 16) | 3016 + (((u32)mac_addr[4]) << 8) | (u32)mac_addr[5]); 3017 + cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_HIGH_IDX] = cpu_to_le32( 3018 + (((u32)mac_addr[0]) << 16) | (u32)mac_addr[1]); 3019 + } else { 3020 + cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_ADDR_LOW_IDX] = 0; 3021 + cqp_wqe->wqe_words[NES_CQP_ARP_WQE_MAC_HIGH_IDX] = 0; 3022 + } 3023 + 3024 + nes_debug(NES_DBG_NETDEV, "Not waiting for CQP, cqp.sq_head=%u, cqp.sq_tail=%u\n", 3025 + nesdev->cqp.sq_head, nesdev->cqp.sq_tail); 3026 + 3027 + atomic_set(&cqp_request->refcount, 1); 3028 + nes_post_cqp_request(nesdev, cqp_request, NES_CQP_REQUEST_RING_DOORBELL); 3029 + } 3030 + 3031 + 3032 + /** 3033 + * flush_wqes 3034 + */ 3035 + void flush_wqes(struct nes_device *nesdev, struct nes_qp *nesqp, 3036 + u32 which_wq, u32 wait_completion) 3037 + { 3038 + unsigned long flags; 3039 + struct nes_cqp_request *cqp_request; 3040 + struct nes_hw_cqp_wqe *cqp_wqe; 3041 + int ret; 3042 + 3043 + cqp_request = nes_get_cqp_request(nesdev); 3044 + if (cqp_request == NULL) { 3045 + nes_debug(NES_DBG_QP, "Failed to get a cqp_request.\n"); 3046 + return; 3047 + } 3048 + if (wait_completion) { 3049 + cqp_request->waiting = 1; 3050 + atomic_set(&cqp_request->refcount, 2); 3051 + } else { 3052 + cqp_request->waiting = 0; 3053 + } 3054 + cqp_wqe = &cqp_request->cqp_wqe; 3055 + nes_fill_init_cqp_wqe(cqp_wqe, nesdev); 3056 + 3057 + cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = 3058 + cpu_to_le32(NES_CQP_FLUSH_WQES | which_wq); 3059 + cqp_wqe->wqe_words[NES_CQP_WQE_ID_IDX] = cpu_to_le32(nesqp->hwqp.qp_id); 3060 + 3061 + nes_post_cqp_request(nesdev, cqp_request, NES_CQP_REQUEST_RING_DOORBELL); 3062 + 3063 + if (wait_completion) { 3064 + /* Wait for CQP */ 3065 + ret = wait_event_timeout(cqp_request->waitq, (cqp_request->request_done != 0), 3066 + NES_EVENT_TIMEOUT); 3067 + nes_debug(NES_DBG_QP, "Flush SQ QP WQEs completed, ret=%u," 3068 + " CQP Major:Minor codes = 0x%04X:0x%04X\n", 3069 + ret, cqp_request->major_code, cqp_request->minor_code); 3070 + if (atomic_dec_and_test(&cqp_request->refcount)) { 3071 + if (cqp_request->dynamic) { 3072 + kfree(cqp_request); 3073 + } else { 3074 + spin_lock_irqsave(&nesdev->cqp.lock, flags); 3075 + list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); 3076 + spin_unlock_irqrestore(&nesdev->cqp.lock, flags); 3077 + } 3078 + } 3079 + } 3080 + }
+1206
drivers/infiniband/hw/nes/nes_hw.h
···
··· 1 + /* 2 + * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved. 3 + * 4 + * This software is available to you under a choice of one of two 5 + * licenses. You may choose to be licensed under the terms of the GNU 6 + * General Public License (GPL) Version 2, available from the file 7 + * COPYING in the main directory of this source tree, or the 8 + * OpenIB.org BSD license below: 9 + * 10 + * Redistribution and use in source and binary forms, with or 11 + * without modification, are permitted provided that the following 12 + * conditions are met: 13 + * 14 + * - Redistributions of source code must retain the above 15 + * copyright notice, this list of conditions and the following 16 + * disclaimer. 17 + * 18 + * - Redistributions in binary form must reproduce the above 19 + * copyright notice, this list of conditions and the following 20 + * disclaimer in the documentation and/or other materials 21 + * provided with the distribution. 22 + * 23 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 + * SOFTWARE. 31 + */ 32 + 33 + #ifndef __NES_HW_H 34 + #define __NES_HW_H 35 + 36 + #define NES_PHY_TYPE_1G 2 37 + #define NES_PHY_TYPE_IRIS 3 38 + #define NES_PHY_TYPE_PUMA_10G 6 39 + 40 + #define NES_MULTICAST_PF_MAX 8 41 + 42 + enum pci_regs { 43 + NES_INT_STAT = 0x0000, 44 + NES_INT_MASK = 0x0004, 45 + NES_INT_PENDING = 0x0008, 46 + NES_INTF_INT_STAT = 0x000C, 47 + NES_INTF_INT_MASK = 0x0010, 48 + NES_TIMER_STAT = 0x0014, 49 + NES_PERIODIC_CONTROL = 0x0018, 50 + NES_ONE_SHOT_CONTROL = 0x001C, 51 + NES_EEPROM_COMMAND = 0x0020, 52 + NES_EEPROM_DATA = 0x0024, 53 + NES_FLASH_COMMAND = 0x0028, 54 + NES_FLASH_DATA = 0x002C, 55 + NES_SOFTWARE_RESET = 0x0030, 56 + NES_CQ_ACK = 0x0034, 57 + NES_WQE_ALLOC = 0x0040, 58 + NES_CQE_ALLOC = 0x0044, 59 + }; 60 + 61 + enum indexed_regs { 62 + NES_IDX_CREATE_CQP_LOW = 0x0000, 63 + NES_IDX_CREATE_CQP_HIGH = 0x0004, 64 + NES_IDX_QP_CONTROL = 0x0040, 65 + NES_IDX_FLM_CONTROL = 0x0080, 66 + NES_IDX_INT_CPU_STATUS = 0x00a0, 67 + NES_IDX_GPIO_CONTROL = 0x00f0, 68 + NES_IDX_GPIO_DATA = 0x00f4, 69 + NES_IDX_TCP_CONFIG0 = 0x01e4, 70 + NES_IDX_TCP_TIMER_CONFIG = 0x01ec, 71 + NES_IDX_TCP_NOW = 0x01f0, 72 + NES_IDX_QP_MAX_CFG_SIZES = 0x0200, 73 + NES_IDX_QP_CTX_SIZE = 0x0218, 74 + NES_IDX_TCP_TIMER_SIZE0 = 0x0238, 75 + NES_IDX_TCP_TIMER_SIZE1 = 0x0240, 76 + NES_IDX_ARP_CACHE_SIZE = 0x0258, 77 + NES_IDX_CQ_CTX_SIZE = 0x0260, 78 + NES_IDX_MRT_SIZE = 0x0278, 79 + NES_IDX_PBL_REGION_SIZE = 0x0280, 80 + NES_IDX_IRRQ_COUNT = 0x02b0, 81 + NES_IDX_RX_WINDOW_BUFFER_PAGE_TABLE_SIZE = 0x02f0, 82 + NES_IDX_RX_WINDOW_BUFFER_SIZE = 0x0300, 83 + NES_IDX_DST_IP_ADDR = 0x0400, 84 + NES_IDX_PCIX_DIAG = 0x08e8, 85 + NES_IDX_MPP_DEBUG = 0x0a00, 86 + NES_IDX_PORT_RX_DISCARDS = 0x0a30, 87 + NES_IDX_PORT_TX_DISCARDS = 0x0a34, 88 + NES_IDX_MPP_LB_DEBUG = 0x0b00, 89 + NES_IDX_DENALI_CTL_22 = 0x1058, 90 + NES_IDX_MAC_TX_CONTROL = 0x2000, 91 + NES_IDX_MAC_TX_CONFIG = 0x2004, 92 + NES_IDX_MAC_TX_PAUSE_QUANTA = 0x2008, 93 + NES_IDX_MAC_RX_CONTROL = 0x200c, 94 + NES_IDX_MAC_RX_CONFIG = 0x2010, 95 + NES_IDX_MAC_EXACT_MATCH_BOTTOM = 0x201c, 96 + NES_IDX_MAC_MDIO_CONTROL = 0x2084, 97 + NES_IDX_MAC_TX_OCTETS_LOW = 0x2100, 98 + NES_IDX_MAC_TX_OCTETS_HIGH = 0x2104, 99 + NES_IDX_MAC_TX_FRAMES_LOW = 0x2108, 100 + NES_IDX_MAC_TX_FRAMES_HIGH = 0x210c, 101 + NES_IDX_MAC_TX_PAUSE_FRAMES = 0x2118, 102 + NES_IDX_MAC_TX_ERRORS = 0x2138, 103 + NES_IDX_MAC_RX_OCTETS_LOW = 0x213c, 104 + NES_IDX_MAC_RX_OCTETS_HIGH = 0x2140, 105 + NES_IDX_MAC_RX_FRAMES_LOW = 0x2144, 106 + NES_IDX_MAC_RX_FRAMES_HIGH = 0x2148, 107 + NES_IDX_MAC_RX_BC_FRAMES_LOW = 0x214c, 108 + NES_IDX_MAC_RX_MC_FRAMES_HIGH = 0x2150, 109 + NES_IDX_MAC_RX_PAUSE_FRAMES = 0x2154, 110 + NES_IDX_MAC_RX_SHORT_FRAMES = 0x2174, 111 + NES_IDX_MAC_RX_OVERSIZED_FRAMES = 0x2178, 112 + NES_IDX_MAC_RX_JABBER_FRAMES = 0x217c, 113 + NES_IDX_MAC_RX_CRC_ERR_FRAMES = 0x2180, 114 + NES_IDX_MAC_RX_LENGTH_ERR_FRAMES = 0x2184, 115 + NES_IDX_MAC_RX_SYMBOL_ERR_FRAMES = 0x2188, 116 + NES_IDX_MAC_INT_STATUS = 0x21f0, 117 + NES_IDX_MAC_INT_MASK = 0x21f4, 118 + NES_IDX_PHY_PCS_CONTROL_STATUS0 = 0x2800, 119 + NES_IDX_PHY_PCS_CONTROL_STATUS1 = 0x2a00, 120 + NES_IDX_ETH_SERDES_COMMON_CONTROL0 = 0x2808, 121 + NES_IDX_ETH_SERDES_COMMON_CONTROL1 = 0x2a08, 122 + NES_IDX_ETH_SERDES_COMMON_STATUS0 = 0x280c, 123 + NES_IDX_ETH_SERDES_COMMON_STATUS1 = 0x2a0c, 124 + NES_IDX_ETH_SERDES_TX_EMP0 = 0x2810, 125 + NES_IDX_ETH_SERDES_TX_EMP1 = 0x2a10, 126 + NES_IDX_ETH_SERDES_TX_DRIVE0 = 0x2814, 127 + NES_IDX_ETH_SERDES_TX_DRIVE1 = 0x2a14, 128 + NES_IDX_ETH_SERDES_RX_MODE0 = 0x2818, 129 + NES_IDX_ETH_SERDES_RX_MODE1 = 0x2a18, 130 + NES_IDX_ETH_SERDES_RX_SIGDET0 = 0x281c, 131 + NES_IDX_ETH_SERDES_RX_SIGDET1 = 0x2a1c, 132 + NES_IDX_ETH_SERDES_BYPASS0 = 0x2820, 133 + NES_IDX_ETH_SERDES_BYPASS1 = 0x2a20, 134 + NES_IDX_ETH_SERDES_LOOPBACK_CONTROL0 = 0x2824, 135 + NES_IDX_ETH_SERDES_LOOPBACK_CONTROL1 = 0x2a24, 136 + NES_IDX_ETH_SERDES_RX_EQ_CONTROL0 = 0x2828, 137 + NES_IDX_ETH_SERDES_RX_EQ_CONTROL1 = 0x2a28, 138 + NES_IDX_ETH_SERDES_RX_EQ_STATUS0 = 0x282c, 139 + NES_IDX_ETH_SERDES_RX_EQ_STATUS1 = 0x2a2c, 140 + NES_IDX_ETH_SERDES_CDR_RESET0 = 0x2830, 141 + NES_IDX_ETH_SERDES_CDR_RESET1 = 0x2a30, 142 + NES_IDX_ETH_SERDES_CDR_CONTROL0 = 0x2834, 143 + NES_IDX_ETH_SERDES_CDR_CONTROL1 = 0x2a34, 144 + NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE0 = 0x2838, 145 + NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE1 = 0x2a38, 146 + NES_IDX_ENDNODE0_NSTAT_RX_DISCARD = 0x3080, 147 + NES_IDX_ENDNODE0_NSTAT_RX_OCTETS_LO = 0x3000, 148 + NES_IDX_ENDNODE0_NSTAT_RX_OCTETS_HI = 0x3004, 149 + NES_IDX_ENDNODE0_NSTAT_RX_FRAMES_LO = 0x3008, 150 + NES_IDX_ENDNODE0_NSTAT_RX_FRAMES_HI = 0x300c, 151 + NES_IDX_ENDNODE0_NSTAT_TX_OCTETS_LO = 0x7000, 152 + NES_IDX_ENDNODE0_NSTAT_TX_OCTETS_HI = 0x7004, 153 + NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_LO = 0x7008, 154 + NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_HI = 0x700c, 155 + NES_IDX_CM_CONFIG = 0x5100, 156 + NES_IDX_NIC_LOGPORT_TO_PHYPORT = 0x6000, 157 + NES_IDX_NIC_PHYPORT_TO_USW = 0x6008, 158 + NES_IDX_NIC_ACTIVE = 0x6010, 159 + NES_IDX_NIC_UNICAST_ALL = 0x6018, 160 + NES_IDX_NIC_MULTICAST_ALL = 0x6020, 161 + NES_IDX_NIC_MULTICAST_ENABLE = 0x6028, 162 + NES_IDX_NIC_BROADCAST_ON = 0x6030, 163 + NES_IDX_USED_CHUNKS_TX = 0x60b0, 164 + NES_IDX_TX_POOL_SIZE = 0x60b8, 165 + NES_IDX_QUAD_HASH_TABLE_SIZE = 0x6148, 166 + NES_IDX_PERFECT_FILTER_LOW = 0x6200, 167 + NES_IDX_PERFECT_FILTER_HIGH = 0x6204, 168 + NES_IDX_IPV4_TCP_REXMITS = 0x7080, 169 + NES_IDX_DEBUG_ERROR_CONTROL_STATUS = 0x913c, 170 + NES_IDX_DEBUG_ERROR_MASKS0 = 0x9140, 171 + NES_IDX_DEBUG_ERROR_MASKS1 = 0x9144, 172 + NES_IDX_DEBUG_ERROR_MASKS2 = 0x9148, 173 + NES_IDX_DEBUG_ERROR_MASKS3 = 0x914c, 174 + NES_IDX_DEBUG_ERROR_MASKS4 = 0x9150, 175 + NES_IDX_DEBUG_ERROR_MASKS5 = 0x9154, 176 + }; 177 + 178 + #define NES_IDX_MAC_TX_CONFIG_ENABLE_PAUSE 1 179 + #define NES_IDX_MPP_DEBUG_PORT_DISABLE_PAUSE (1 << 17) 180 + 181 + enum nes_cqp_opcodes { 182 + NES_CQP_CREATE_QP = 0x00, 183 + NES_CQP_MODIFY_QP = 0x01, 184 + NES_CQP_DESTROY_QP = 0x02, 185 + NES_CQP_CREATE_CQ = 0x03, 186 + NES_CQP_MODIFY_CQ = 0x04, 187 + NES_CQP_DESTROY_CQ = 0x05, 188 + NES_CQP_ALLOCATE_STAG = 0x09, 189 + NES_CQP_REGISTER_STAG = 0x0a, 190 + NES_CQP_QUERY_STAG = 0x0b, 191 + NES_CQP_REGISTER_SHARED_STAG = 0x0c, 192 + NES_CQP_DEALLOCATE_STAG = 0x0d, 193 + NES_CQP_MANAGE_ARP_CACHE = 0x0f, 194 + NES_CQP_SUSPEND_QPS = 0x11, 195 + NES_CQP_UPLOAD_CONTEXT = 0x13, 196 + NES_CQP_CREATE_CEQ = 0x16, 197 + NES_CQP_DESTROY_CEQ = 0x18, 198 + NES_CQP_CREATE_AEQ = 0x19, 199 + NES_CQP_DESTROY_AEQ = 0x1b, 200 + NES_CQP_LMI_ACCESS = 0x20, 201 + NES_CQP_FLUSH_WQES = 0x22, 202 + NES_CQP_MANAGE_APBVT = 0x23 203 + }; 204 + 205 + enum nes_cqp_wqe_word_idx { 206 + NES_CQP_WQE_OPCODE_IDX = 0, 207 + NES_CQP_WQE_ID_IDX = 1, 208 + NES_CQP_WQE_COMP_CTX_LOW_IDX = 2, 209 + NES_CQP_WQE_COMP_CTX_HIGH_IDX = 3, 210 + NES_CQP_WQE_COMP_SCRATCH_LOW_IDX = 4, 211 + NES_CQP_WQE_COMP_SCRATCH_HIGH_IDX = 5, 212 + }; 213 + 214 + enum nes_cqp_cq_wqeword_idx { 215 + NES_CQP_CQ_WQE_PBL_LOW_IDX = 6, 216 + NES_CQP_CQ_WQE_PBL_HIGH_IDX = 7, 217 + NES_CQP_CQ_WQE_CQ_CONTEXT_LOW_IDX = 8, 218 + NES_CQP_CQ_WQE_CQ_CONTEXT_HIGH_IDX = 9, 219 + NES_CQP_CQ_WQE_DOORBELL_INDEX_HIGH_IDX = 10, 220 + }; 221 + 222 + enum nes_cqp_stag_wqeword_idx { 223 + NES_CQP_STAG_WQE_PBL_BLK_COUNT_IDX = 1, 224 + NES_CQP_STAG_WQE_LEN_HIGH_PD_IDX = 6, 225 + NES_CQP_STAG_WQE_LEN_LOW_IDX = 7, 226 + NES_CQP_STAG_WQE_STAG_IDX = 8, 227 + NES_CQP_STAG_WQE_VA_LOW_IDX = 10, 228 + NES_CQP_STAG_WQE_VA_HIGH_IDX = 11, 229 + NES_CQP_STAG_WQE_PA_LOW_IDX = 12, 230 + NES_CQP_STAG_WQE_PA_HIGH_IDX = 13, 231 + NES_CQP_STAG_WQE_PBL_LEN_IDX = 14 232 + }; 233 + 234 + #define NES_CQP_OP_IWARP_STATE_SHIFT 28 235 + 236 + enum nes_cqp_qp_bits { 237 + NES_CQP_QP_ARP_VALID = (1<<8), 238 + NES_CQP_QP_WINBUF_VALID = (1<<9), 239 + NES_CQP_QP_CONTEXT_VALID = (1<<10), 240 + NES_CQP_QP_ORD_VALID = (1<<11), 241 + NES_CQP_QP_WINBUF_DATAIND_EN = (1<<12), 242 + NES_CQP_QP_VIRT_WQS = (1<<13), 243 + NES_CQP_QP_DEL_HTE = (1<<14), 244 + NES_CQP_QP_CQS_VALID = (1<<15), 245 + NES_CQP_QP_TYPE_TSA = 0, 246 + NES_CQP_QP_TYPE_IWARP = (1<<16), 247 + NES_CQP_QP_TYPE_CQP = (4<<16), 248 + NES_CQP_QP_TYPE_NIC = (5<<16), 249 + NES_CQP_QP_MSS_CHG = (1<<20), 250 + NES_CQP_QP_STATIC_RESOURCES = (1<<21), 251 + NES_CQP_QP_IGNORE_MW_BOUND = (1<<22), 252 + NES_CQP_QP_VWQ_USE_LMI = (1<<23), 253 + NES_CQP_QP_IWARP_STATE_IDLE = (1<<NES_CQP_OP_IWARP_STATE_SHIFT), 254 + NES_CQP_QP_IWARP_STATE_RTS = (2<<NES_CQP_OP_IWARP_STATE_SHIFT), 255 + NES_CQP_QP_IWARP_STATE_CLOSING = (3<<NES_CQP_OP_IWARP_STATE_SHIFT), 256 + NES_CQP_QP_IWARP_STATE_TERMINATE = (5<<NES_CQP_OP_IWARP_STATE_SHIFT), 257 + NES_CQP_QP_IWARP_STATE_ERROR = (6<<NES_CQP_OP_IWARP_STATE_SHIFT), 258 + NES_CQP_QP_IWARP_STATE_MASK = (7<<NES_CQP_OP_IWARP_STATE_SHIFT), 259 + NES_CQP_QP_RESET = (1<<31), 260 + }; 261 + 262 + enum nes_cqp_qp_wqe_word_idx { 263 + NES_CQP_QP_WQE_CONTEXT_LOW_IDX = 6, 264 + NES_CQP_QP_WQE_CONTEXT_HIGH_IDX = 7, 265 + NES_CQP_QP_WQE_NEW_MSS_IDX = 15, 266 + }; 267 + 268 + enum nes_nic_ctx_bits { 269 + NES_NIC_CTX_RQ_SIZE_32 = (3<<8), 270 + NES_NIC_CTX_RQ_SIZE_512 = (3<<8), 271 + NES_NIC_CTX_SQ_SIZE_32 = (1<<10), 272 + NES_NIC_CTX_SQ_SIZE_512 = (3<<10), 273 + }; 274 + 275 + enum nes_nic_qp_ctx_word_idx { 276 + NES_NIC_CTX_MISC_IDX = 0, 277 + NES_NIC_CTX_SQ_LOW_IDX = 2, 278 + NES_NIC_CTX_SQ_HIGH_IDX = 3, 279 + NES_NIC_CTX_RQ_LOW_IDX = 4, 280 + NES_NIC_CTX_RQ_HIGH_IDX = 5, 281 + }; 282 + 283 + enum nes_cqp_cq_bits { 284 + NES_CQP_CQ_CEQE_MASK = (1<<9), 285 + NES_CQP_CQ_CEQ_VALID = (1<<10), 286 + NES_CQP_CQ_RESIZE = (1<<11), 287 + NES_CQP_CQ_CHK_OVERFLOW = (1<<12), 288 + NES_CQP_CQ_4KB_CHUNK = (1<<14), 289 + NES_CQP_CQ_VIRT = (1<<15), 290 + }; 291 + 292 + enum nes_cqp_stag_bits { 293 + NES_CQP_STAG_VA_TO = (1<<9), 294 + NES_CQP_STAG_DEALLOC_PBLS = (1<<10), 295 + NES_CQP_STAG_PBL_BLK_SIZE = (1<<11), 296 + NES_CQP_STAG_MR = (1<<13), 297 + NES_CQP_STAG_RIGHTS_LOCAL_READ = (1<<16), 298 + NES_CQP_STAG_RIGHTS_LOCAL_WRITE = (1<<17), 299 + NES_CQP_STAG_RIGHTS_REMOTE_READ = (1<<18), 300 + NES_CQP_STAG_RIGHTS_REMOTE_WRITE = (1<<19), 301 + NES_CQP_STAG_RIGHTS_WINDOW_BIND = (1<<20), 302 + NES_CQP_STAG_REM_ACC_EN = (1<<21), 303 + NES_CQP_STAG_LEAVE_PENDING = (1<<31), 304 + }; 305 + 306 + enum nes_cqp_ceq_wqeword_idx { 307 + NES_CQP_CEQ_WQE_ELEMENT_COUNT_IDX = 1, 308 + NES_CQP_CEQ_WQE_PBL_LOW_IDX = 6, 309 + NES_CQP_CEQ_WQE_PBL_HIGH_IDX = 7, 310 + }; 311 + 312 + enum nes_cqp_ceq_bits { 313 + NES_CQP_CEQ_4KB_CHUNK = (1<<14), 314 + NES_CQP_CEQ_VIRT = (1<<15), 315 + }; 316 + 317 + enum nes_cqp_aeq_wqeword_idx { 318 + NES_CQP_AEQ_WQE_ELEMENT_COUNT_IDX = 1, 319 + NES_CQP_AEQ_WQE_PBL_LOW_IDX = 6, 320 + NES_CQP_AEQ_WQE_PBL_HIGH_IDX = 7, 321 + }; 322 + 323 + enum nes_cqp_aeq_bits { 324 + NES_CQP_AEQ_4KB_CHUNK = (1<<14), 325 + NES_CQP_AEQ_VIRT = (1<<15), 326 + }; 327 + 328 + enum nes_cqp_lmi_wqeword_idx { 329 + NES_CQP_LMI_WQE_LMI_OFFSET_IDX = 1, 330 + NES_CQP_LMI_WQE_FRAG_LOW_IDX = 8, 331 + NES_CQP_LMI_WQE_FRAG_HIGH_IDX = 9, 332 + NES_CQP_LMI_WQE_FRAG_LEN_IDX = 10, 333 + }; 334 + 335 + enum nes_cqp_arp_wqeword_idx { 336 + NES_CQP_ARP_WQE_MAC_ADDR_LOW_IDX = 6, 337 + NES_CQP_ARP_WQE_MAC_HIGH_IDX = 7, 338 + NES_CQP_ARP_WQE_REACHABILITY_MAX_IDX = 1, 339 + }; 340 + 341 + enum nes_cqp_upload_wqeword_idx { 342 + NES_CQP_UPLOAD_WQE_CTXT_LOW_IDX = 6, 343 + NES_CQP_UPLOAD_WQE_CTXT_HIGH_IDX = 7, 344 + NES_CQP_UPLOAD_WQE_HTE_IDX = 8, 345 + }; 346 + 347 + enum nes_cqp_arp_bits { 348 + NES_CQP_ARP_VALID = (1<<8), 349 + NES_CQP_ARP_PERM = (1<<9), 350 + }; 351 + 352 + enum nes_cqp_flush_bits { 353 + NES_CQP_FLUSH_SQ = (1<<30), 354 + NES_CQP_FLUSH_RQ = (1<<31), 355 + }; 356 + 357 + enum nes_cqe_opcode_bits { 358 + NES_CQE_STAG_VALID = (1<<6), 359 + NES_CQE_ERROR = (1<<7), 360 + NES_CQE_SQ = (1<<8), 361 + NES_CQE_SE = (1<<9), 362 + NES_CQE_PSH = (1<<29), 363 + NES_CQE_FIN = (1<<30), 364 + NES_CQE_VALID = (1<<31), 365 + }; 366 + 367 + 368 + enum nes_cqe_word_idx { 369 + NES_CQE_PAYLOAD_LENGTH_IDX = 0, 370 + NES_CQE_COMP_COMP_CTX_LOW_IDX = 2, 371 + NES_CQE_COMP_COMP_CTX_HIGH_IDX = 3, 372 + NES_CQE_INV_STAG_IDX = 4, 373 + NES_CQE_QP_ID_IDX = 5, 374 + NES_CQE_ERROR_CODE_IDX = 6, 375 + NES_CQE_OPCODE_IDX = 7, 376 + }; 377 + 378 + enum nes_ceqe_word_idx { 379 + NES_CEQE_CQ_CTX_LOW_IDX = 0, 380 + NES_CEQE_CQ_CTX_HIGH_IDX = 1, 381 + }; 382 + 383 + enum nes_ceqe_status_bit { 384 + NES_CEQE_VALID = (1<<31), 385 + }; 386 + 387 + enum nes_int_bits { 388 + NES_INT_CEQ0 = (1<<0), 389 + NES_INT_CEQ1 = (1<<1), 390 + NES_INT_CEQ2 = (1<<2), 391 + NES_INT_CEQ3 = (1<<3), 392 + NES_INT_CEQ4 = (1<<4), 393 + NES_INT_CEQ5 = (1<<5), 394 + NES_INT_CEQ6 = (1<<6), 395 + NES_INT_CEQ7 = (1<<7), 396 + NES_INT_CEQ8 = (1<<8), 397 + NES_INT_CEQ9 = (1<<9), 398 + NES_INT_CEQ10 = (1<<10), 399 + NES_INT_CEQ11 = (1<<11), 400 + NES_INT_CEQ12 = (1<<12), 401 + NES_INT_CEQ13 = (1<<13), 402 + NES_INT_CEQ14 = (1<<14), 403 + NES_INT_CEQ15 = (1<<15), 404 + NES_INT_AEQ0 = (1<<16), 405 + NES_INT_AEQ1 = (1<<17), 406 + NES_INT_AEQ2 = (1<<18), 407 + NES_INT_AEQ3 = (1<<19), 408 + NES_INT_AEQ4 = (1<<20), 409 + NES_INT_AEQ5 = (1<<21), 410 + NES_INT_AEQ6 = (1<<22), 411 + NES_INT_AEQ7 = (1<<23), 412 + NES_INT_MAC0 = (1<<24), 413 + NES_INT_MAC1 = (1<<25), 414 + NES_INT_MAC2 = (1<<26), 415 + NES_INT_MAC3 = (1<<27), 416 + NES_INT_TSW = (1<<28), 417 + NES_INT_TIMER = (1<<29), 418 + NES_INT_INTF = (1<<30), 419 + }; 420 + 421 + enum nes_intf_int_bits { 422 + NES_INTF_INT_PCIERR = (1<<0), 423 + NES_INTF_PERIODIC_TIMER = (1<<2), 424 + NES_INTF_ONE_SHOT_TIMER = (1<<3), 425 + NES_INTF_INT_CRITERR = (1<<14), 426 + NES_INTF_INT_AEQ0_OFLOW = (1<<16), 427 + NES_INTF_INT_AEQ1_OFLOW = (1<<17), 428 + NES_INTF_INT_AEQ2_OFLOW = (1<<18), 429 + NES_INTF_INT_AEQ3_OFLOW = (1<<19), 430 + NES_INTF_INT_AEQ4_OFLOW = (1<<20), 431 + NES_INTF_INT_AEQ5_OFLOW = (1<<21), 432 + NES_INTF_INT_AEQ6_OFLOW = (1<<22), 433 + NES_INTF_INT_AEQ7_OFLOW = (1<<23), 434 + NES_INTF_INT_AEQ_OFLOW = (0xff<<16), 435 + }; 436 + 437 + enum nes_mac_int_bits { 438 + NES_MAC_INT_LINK_STAT_CHG = (1<<1), 439 + NES_MAC_INT_XGMII_EXT = (1<<2), 440 + NES_MAC_INT_TX_UNDERFLOW = (1<<6), 441 + NES_MAC_INT_TX_ERROR = (1<<7), 442 + }; 443 + 444 + enum nes_cqe_allocate_bits { 445 + NES_CQE_ALLOC_INC_SELECT = (1<<28), 446 + NES_CQE_ALLOC_NOTIFY_NEXT = (1<<29), 447 + NES_CQE_ALLOC_NOTIFY_SE = (1<<30), 448 + NES_CQE_ALLOC_RESET = (1<<31), 449 + }; 450 + 451 + enum nes_nic_rq_wqe_word_idx { 452 + NES_NIC_RQ_WQE_LENGTH_1_0_IDX = 0, 453 + NES_NIC_RQ_WQE_LENGTH_3_2_IDX = 1, 454 + NES_NIC_RQ_WQE_FRAG0_LOW_IDX = 2, 455 + NES_NIC_RQ_WQE_FRAG0_HIGH_IDX = 3, 456 + NES_NIC_RQ_WQE_FRAG1_LOW_IDX = 4, 457 + NES_NIC_RQ_WQE_FRAG1_HIGH_IDX = 5, 458 + NES_NIC_RQ_WQE_FRAG2_LOW_IDX = 6, 459 + NES_NIC_RQ_WQE_FRAG2_HIGH_IDX = 7, 460 + NES_NIC_RQ_WQE_FRAG3_LOW_IDX = 8, 461 + NES_NIC_RQ_WQE_FRAG3_HIGH_IDX = 9, 462 + }; 463 + 464 + enum nes_nic_sq_wqe_word_idx { 465 + NES_NIC_SQ_WQE_MISC_IDX = 0, 466 + NES_NIC_SQ_WQE_TOTAL_LENGTH_IDX = 1, 467 + NES_NIC_SQ_WQE_LSO_INFO_IDX = 2, 468 + NES_NIC_SQ_WQE_LENGTH_0_TAG_IDX = 3, 469 + NES_NIC_SQ_WQE_LENGTH_2_1_IDX = 4, 470 + NES_NIC_SQ_WQE_LENGTH_4_3_IDX = 5, 471 + NES_NIC_SQ_WQE_FRAG0_LOW_IDX = 6, 472 + NES_NIC_SQ_WQE_FRAG0_HIGH_IDX = 7, 473 + NES_NIC_SQ_WQE_FRAG1_LOW_IDX = 8, 474 + NES_NIC_SQ_WQE_FRAG1_HIGH_IDX = 9, 475 + NES_NIC_SQ_WQE_FRAG2_LOW_IDX = 10, 476 + NES_NIC_SQ_WQE_FRAG2_HIGH_IDX = 11, 477 + NES_NIC_SQ_WQE_FRAG3_LOW_IDX = 12, 478 + NES_NIC_SQ_WQE_FRAG3_HIGH_IDX = 13, 479 + NES_NIC_SQ_WQE_FRAG4_LOW_IDX = 14, 480 + NES_NIC_SQ_WQE_FRAG4_HIGH_IDX = 15, 481 + }; 482 + 483 + enum nes_iwarp_sq_wqe_word_idx { 484 + NES_IWARP_SQ_WQE_MISC_IDX = 0, 485 + NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX = 1, 486 + NES_IWARP_SQ_WQE_COMP_CTX_LOW_IDX = 2, 487 + NES_IWARP_SQ_WQE_COMP_CTX_HIGH_IDX = 3, 488 + NES_IWARP_SQ_WQE_COMP_SCRATCH_LOW_IDX = 4, 489 + NES_IWARP_SQ_WQE_COMP_SCRATCH_HIGH_IDX = 5, 490 + NES_IWARP_SQ_WQE_INV_STAG_LOW_IDX = 7, 491 + NES_IWARP_SQ_WQE_RDMA_TO_LOW_IDX = 8, 492 + NES_IWARP_SQ_WQE_RDMA_TO_HIGH_IDX = 9, 493 + NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX = 10, 494 + NES_IWARP_SQ_WQE_RDMA_STAG_IDX = 11, 495 + NES_IWARP_SQ_WQE_IMM_DATA_START_IDX = 12, 496 + NES_IWARP_SQ_WQE_FRAG0_LOW_IDX = 16, 497 + NES_IWARP_SQ_WQE_FRAG0_HIGH_IDX = 17, 498 + NES_IWARP_SQ_WQE_LENGTH0_IDX = 18, 499 + NES_IWARP_SQ_WQE_STAG0_IDX = 19, 500 + NES_IWARP_SQ_WQE_FRAG1_LOW_IDX = 20, 501 + NES_IWARP_SQ_WQE_FRAG1_HIGH_IDX = 21, 502 + NES_IWARP_SQ_WQE_LENGTH1_IDX = 22, 503 + NES_IWARP_SQ_WQE_STAG1_IDX = 23, 504 + NES_IWARP_SQ_WQE_FRAG2_LOW_IDX = 24, 505 + NES_IWARP_SQ_WQE_FRAG2_HIGH_IDX = 25, 506 + NES_IWARP_SQ_WQE_LENGTH2_IDX = 26, 507 + NES_IWARP_SQ_WQE_STAG2_IDX = 27, 508 + NES_IWARP_SQ_WQE_FRAG3_LOW_IDX = 28, 509 + NES_IWARP_SQ_WQE_FRAG3_HIGH_IDX = 29, 510 + NES_IWARP_SQ_WQE_LENGTH3_IDX = 30, 511 + NES_IWARP_SQ_WQE_STAG3_IDX = 31, 512 + }; 513 + 514 + enum nes_iwarp_sq_bind_wqe_word_idx { 515 + NES_IWARP_SQ_BIND_WQE_MR_IDX = 6, 516 + NES_IWARP_SQ_BIND_WQE_MW_IDX = 7, 517 + NES_IWARP_SQ_BIND_WQE_LENGTH_LOW_IDX = 8, 518 + NES_IWARP_SQ_BIND_WQE_LENGTH_HIGH_IDX = 9, 519 + NES_IWARP_SQ_BIND_WQE_VA_FBO_LOW_IDX = 10, 520 + NES_IWARP_SQ_BIND_WQE_VA_FBO_HIGH_IDX = 11, 521 + }; 522 + 523 + enum nes_iwarp_sq_fmr_wqe_word_idx { 524 + NES_IWARP_SQ_FMR_WQE_MR_STAG_IDX = 7, 525 + NES_IWARP_SQ_FMR_WQE_LENGTH_LOW_IDX = 8, 526 + NES_IWARP_SQ_FMR_WQE_LENGTH_HIGH_IDX = 9, 527 + NES_IWARP_SQ_FMR_WQE_VA_FBO_LOW_IDX = 10, 528 + NES_IWARP_SQ_FMR_WQE_VA_FBO_HIGH_IDX = 11, 529 + NES_IWARP_SQ_FMR_WQE_PBL_ADDR_LOW_IDX = 12, 530 + NES_IWARP_SQ_FMR_WQE_PBL_ADDR_HIGH_IDX = 13, 531 + NES_IWARP_SQ_FMR_WQE_PBL_LENGTH_IDX = 14, 532 + }; 533 + 534 + enum nes_iwarp_sq_locinv_wqe_word_idx { 535 + NES_IWARP_SQ_LOCINV_WQE_INV_STAG_IDX = 6, 536 + }; 537 + 538 + 539 + enum nes_iwarp_rq_wqe_word_idx { 540 + NES_IWARP_RQ_WQE_TOTAL_PAYLOAD_IDX = 1, 541 + NES_IWARP_RQ_WQE_COMP_CTX_LOW_IDX = 2, 542 + NES_IWARP_RQ_WQE_COMP_CTX_HIGH_IDX = 3, 543 + NES_IWARP_RQ_WQE_COMP_SCRATCH_LOW_IDX = 4, 544 + NES_IWARP_RQ_WQE_COMP_SCRATCH_HIGH_IDX = 5, 545 + NES_IWARP_RQ_WQE_FRAG0_LOW_IDX = 8, 546 + NES_IWARP_RQ_WQE_FRAG0_HIGH_IDX = 9, 547 + NES_IWARP_RQ_WQE_LENGTH0_IDX = 10, 548 + NES_IWARP_RQ_WQE_STAG0_IDX = 11, 549 + NES_IWARP_RQ_WQE_FRAG1_LOW_IDX = 12, 550 + NES_IWARP_RQ_WQE_FRAG1_HIGH_IDX = 13, 551 + NES_IWARP_RQ_WQE_LENGTH1_IDX = 14, 552 + NES_IWARP_RQ_WQE_STAG1_IDX = 15, 553 + NES_IWARP_RQ_WQE_FRAG2_LOW_IDX = 16, 554 + NES_IWARP_RQ_WQE_FRAG2_HIGH_IDX = 17, 555 + NES_IWARP_RQ_WQE_LENGTH2_IDX = 18, 556 + NES_IWARP_RQ_WQE_STAG2_IDX = 19, 557 + NES_IWARP_RQ_WQE_FRAG3_LOW_IDX = 20, 558 + NES_IWARP_RQ_WQE_FRAG3_HIGH_IDX = 21, 559 + NES_IWARP_RQ_WQE_LENGTH3_IDX = 22, 560 + NES_IWARP_RQ_WQE_STAG3_IDX = 23, 561 + }; 562 + 563 + enum nes_nic_sq_wqe_bits { 564 + NES_NIC_SQ_WQE_PHDR_CS_READY = (1<<21), 565 + NES_NIC_SQ_WQE_LSO_ENABLE = (1<<22), 566 + NES_NIC_SQ_WQE_TAGVALUE_ENABLE = (1<<23), 567 + NES_NIC_SQ_WQE_DISABLE_CHKSUM = (1<<30), 568 + NES_NIC_SQ_WQE_COMPLETION = (1<<31), 569 + }; 570 + 571 + enum nes_nic_cqe_word_idx { 572 + NES_NIC_CQE_ACCQP_ID_IDX = 0, 573 + NES_NIC_CQE_TAG_PKT_TYPE_IDX = 2, 574 + NES_NIC_CQE_MISC_IDX = 3, 575 + }; 576 + 577 + #define NES_PKT_TYPE_APBVT_BITS 0xC112 578 + #define NES_PKT_TYPE_APBVT_MASK 0xff3e 579 + 580 + #define NES_PKT_TYPE_PVALID_BITS 0x10000000 581 + #define NES_PKT_TYPE_PVALID_MASK 0x30000000 582 + 583 + #define NES_PKT_TYPE_TCPV4_BITS 0x0110 584 + #define NES_PKT_TYPE_TCPV4_MASK 0x3f30 585 + 586 + #define NES_PKT_TYPE_UDPV4_BITS 0x0210 587 + #define NES_PKT_TYPE_UDPV4_MASK 0x3f30 588 + 589 + #define NES_PKT_TYPE_IPV4_BITS 0x0010 590 + #define NES_PKT_TYPE_IPV4_MASK 0x3f30 591 + 592 + #define NES_PKT_TYPE_OTHER_BITS 0x0000 593 + #define NES_PKT_TYPE_OTHER_MASK 0x0030 594 + 595 + #define NES_NIC_CQE_ERRV_SHIFT 16 596 + enum nes_nic_ev_bits { 597 + NES_NIC_ERRV_BITS_MODE = (1<<0), 598 + NES_NIC_ERRV_BITS_IPV4_CSUM_ERR = (1<<1), 599 + NES_NIC_ERRV_BITS_TCPUDP_CSUM_ERR = (1<<2), 600 + NES_NIC_ERRV_BITS_WQE_OVERRUN = (1<<3), 601 + NES_NIC_ERRV_BITS_IPH_ERR = (1<<4), 602 + }; 603 + 604 + enum nes_nic_cqe_bits { 605 + NES_NIC_CQE_ERRV_MASK = (0xff<<NES_NIC_CQE_ERRV_SHIFT), 606 + NES_NIC_CQE_SQ = (1<<24), 607 + NES_NIC_CQE_ACCQP_PORT = (1<<28), 608 + NES_NIC_CQE_ACCQP_VALID = (1<<29), 609 + NES_NIC_CQE_TAG_VALID = (1<<30), 610 + NES_NIC_CQE_VALID = (1<<31), 611 + }; 612 + 613 + enum nes_aeqe_word_idx { 614 + NES_AEQE_COMP_CTXT_LOW_IDX = 0, 615 + NES_AEQE_COMP_CTXT_HIGH_IDX = 1, 616 + NES_AEQE_COMP_QP_CQ_ID_IDX = 2, 617 + NES_AEQE_MISC_IDX = 3, 618 + }; 619 + 620 + enum nes_aeqe_bits { 621 + NES_AEQE_QP = (1<<16), 622 + NES_AEQE_CQ = (1<<17), 623 + NES_AEQE_SQ = (1<<18), 624 + NES_AEQE_INBOUND_RDMA = (1<<19), 625 + NES_AEQE_IWARP_STATE_MASK = (7<<20), 626 + NES_AEQE_TCP_STATE_MASK = (0xf<<24), 627 + NES_AEQE_VALID = (1<<31), 628 + }; 629 + 630 + #define NES_AEQE_IWARP_STATE_SHIFT 20 631 + #define NES_AEQE_TCP_STATE_SHIFT 24 632 + 633 + enum nes_aeqe_iwarp_state { 634 + NES_AEQE_IWARP_STATE_NON_EXISTANT = 0, 635 + NES_AEQE_IWARP_STATE_IDLE = 1, 636 + NES_AEQE_IWARP_STATE_RTS = 2, 637 + NES_AEQE_IWARP_STATE_CLOSING = 3, 638 + NES_AEQE_IWARP_STATE_TERMINATE = 5, 639 + NES_AEQE_IWARP_STATE_ERROR = 6 640 + }; 641 + 642 + enum nes_aeqe_tcp_state { 643 + NES_AEQE_TCP_STATE_NON_EXISTANT = 0, 644 + NES_AEQE_TCP_STATE_CLOSED = 1, 645 + NES_AEQE_TCP_STATE_LISTEN = 2, 646 + NES_AEQE_TCP_STATE_SYN_SENT = 3, 647 + NES_AEQE_TCP_STATE_SYN_RCVD = 4, 648 + NES_AEQE_TCP_STATE_ESTABLISHED = 5, 649 + NES_AEQE_TCP_STATE_CLOSE_WAIT = 6, 650 + NES_AEQE_TCP_STATE_FIN_WAIT_1 = 7, 651 + NES_AEQE_TCP_STATE_CLOSING = 8, 652 + NES_AEQE_TCP_STATE_LAST_ACK = 9, 653 + NES_AEQE_TCP_STATE_FIN_WAIT_2 = 10, 654 + NES_AEQE_TCP_STATE_TIME_WAIT = 11 655 + }; 656 + 657 + enum nes_aeqe_aeid { 658 + NES_AEQE_AEID_AMP_UNALLOCATED_STAG = 0x0102, 659 + NES_AEQE_AEID_AMP_INVALID_STAG = 0x0103, 660 + NES_AEQE_AEID_AMP_BAD_QP = 0x0104, 661 + NES_AEQE_AEID_AMP_BAD_PD = 0x0105, 662 + NES_AEQE_AEID_AMP_BAD_STAG_KEY = 0x0106, 663 + NES_AEQE_AEID_AMP_BAD_STAG_INDEX = 0x0107, 664 + NES_AEQE_AEID_AMP_BOUNDS_VIOLATION = 0x0108, 665 + NES_AEQE_AEID_AMP_RIGHTS_VIOLATION = 0x0109, 666 + NES_AEQE_AEID_AMP_TO_WRAP = 0x010a, 667 + NES_AEQE_AEID_AMP_FASTREG_SHARED = 0x010b, 668 + NES_AEQE_AEID_AMP_FASTREG_VALID_STAG = 0x010c, 669 + NES_AEQE_AEID_AMP_FASTREG_MW_STAG = 0x010d, 670 + NES_AEQE_AEID_AMP_FASTREG_INVALID_RIGHTS = 0x010e, 671 + NES_AEQE_AEID_AMP_FASTREG_PBL_TABLE_OVERFLOW = 0x010f, 672 + NES_AEQE_AEID_AMP_FASTREG_INVALID_LENGTH = 0x0110, 673 + NES_AEQE_AEID_AMP_INVALIDATE_SHARED = 0x0111, 674 + NES_AEQE_AEID_AMP_INVALIDATE_NO_REMOTE_ACCESS_RIGHTS = 0x0112, 675 + NES_AEQE_AEID_AMP_INVALIDATE_MR_WITH_BOUND_WINDOWS = 0x0113, 676 + NES_AEQE_AEID_AMP_MWBIND_VALID_STAG = 0x0114, 677 + NES_AEQE_AEID_AMP_MWBIND_OF_MR_STAG = 0x0115, 678 + NES_AEQE_AEID_AMP_MWBIND_TO_ZERO_BASED_STAG = 0x0116, 679 + NES_AEQE_AEID_AMP_MWBIND_TO_MW_STAG = 0x0117, 680 + NES_AEQE_AEID_AMP_MWBIND_INVALID_RIGHTS = 0x0118, 681 + NES_AEQE_AEID_AMP_MWBIND_INVALID_BOUNDS = 0x0119, 682 + NES_AEQE_AEID_AMP_MWBIND_TO_INVALID_PARENT = 0x011a, 683 + NES_AEQE_AEID_AMP_MWBIND_BIND_DISABLED = 0x011b, 684 + NES_AEQE_AEID_BAD_CLOSE = 0x0201, 685 + NES_AEQE_AEID_RDMAP_ROE_BAD_LLP_CLOSE = 0x0202, 686 + NES_AEQE_AEID_CQ_OPERATION_ERROR = 0x0203, 687 + NES_AEQE_AEID_PRIV_OPERATION_DENIED = 0x0204, 688 + NES_AEQE_AEID_RDMA_READ_WHILE_ORD_ZERO = 0x0205, 689 + NES_AEQE_AEID_STAG_ZERO_INVALID = 0x0206, 690 + NES_AEQE_AEID_DDP_INVALID_MSN_GAP_IN_MSN = 0x0301, 691 + NES_AEQE_AEID_DDP_INVALID_MSN_RANGE_IS_NOT_VALID = 0x0302, 692 + NES_AEQE_AEID_DDP_UBE_DDP_MESSAGE_TOO_LONG_FOR_AVAILABLE_BUFFER = 0x0303, 693 + NES_AEQE_AEID_DDP_UBE_INVALID_DDP_VERSION = 0x0304, 694 + NES_AEQE_AEID_DDP_UBE_INVALID_MO = 0x0305, 695 + NES_AEQE_AEID_DDP_UBE_INVALID_MSN_NO_BUFFER_AVAILABLE = 0x0306, 696 + NES_AEQE_AEID_DDP_UBE_INVALID_QN = 0x0307, 697 + NES_AEQE_AEID_DDP_NO_L_BIT = 0x0308, 698 + NES_AEQE_AEID_RDMAP_ROE_INVALID_RDMAP_VERSION = 0x0311, 699 + NES_AEQE_AEID_RDMAP_ROE_UNEXPECTED_OPCODE = 0x0312, 700 + NES_AEQE_AEID_ROE_INVALID_RDMA_READ_REQUEST = 0x0313, 701 + NES_AEQE_AEID_ROE_INVALID_RDMA_WRITE_OR_READ_RESP = 0x0314, 702 + NES_AEQE_AEID_INVALID_ARP_ENTRY = 0x0401, 703 + NES_AEQE_AEID_INVALID_TCP_OPTION_RCVD = 0x0402, 704 + NES_AEQE_AEID_STALE_ARP_ENTRY = 0x0403, 705 + NES_AEQE_AEID_LLP_CLOSE_COMPLETE = 0x0501, 706 + NES_AEQE_AEID_LLP_CONNECTION_RESET = 0x0502, 707 + NES_AEQE_AEID_LLP_FIN_RECEIVED = 0x0503, 708 + NES_AEQE_AEID_LLP_RECEIVED_MARKER_AND_LENGTH_FIELDS_DONT_MATCH = 0x0504, 709 + NES_AEQE_AEID_LLP_RECEIVED_MPA_CRC_ERROR = 0x0505, 710 + NES_AEQE_AEID_LLP_SEGMENT_TOO_LARGE = 0x0506, 711 + NES_AEQE_AEID_LLP_SEGMENT_TOO_SMALL = 0x0507, 712 + NES_AEQE_AEID_LLP_SYN_RECEIVED = 0x0508, 713 + NES_AEQE_AEID_LLP_TERMINATE_RECEIVED = 0x0509, 714 + NES_AEQE_AEID_LLP_TOO_MANY_RETRIES = 0x050a, 715 + NES_AEQE_AEID_LLP_TOO_MANY_KEEPALIVE_RETRIES = 0x050b, 716 + NES_AEQE_AEID_RESET_SENT = 0x0601, 717 + NES_AEQE_AEID_TERMINATE_SENT = 0x0602, 718 + NES_AEQE_AEID_DDP_LCE_LOCAL_CATASTROPHIC = 0x0700 719 + }; 720 + 721 + enum nes_iwarp_sq_opcodes { 722 + NES_IWARP_SQ_WQE_WRPDU = (1<<15), 723 + NES_IWARP_SQ_WQE_PSH = (1<<21), 724 + NES_IWARP_SQ_WQE_STREAMING = (1<<23), 725 + NES_IWARP_SQ_WQE_IMM_DATA = (1<<28), 726 + NES_IWARP_SQ_WQE_READ_FENCE = (1<<29), 727 + NES_IWARP_SQ_WQE_LOCAL_FENCE = (1<<30), 728 + NES_IWARP_SQ_WQE_SIGNALED_COMPL = (1<<31), 729 + }; 730 + 731 + enum nes_iwarp_sq_wqe_bits { 732 + NES_IWARP_SQ_OP_RDMAW = 0, 733 + NES_IWARP_SQ_OP_RDMAR = 1, 734 + NES_IWARP_SQ_OP_SEND = 3, 735 + NES_IWARP_SQ_OP_SENDINV = 4, 736 + NES_IWARP_SQ_OP_SENDSE = 5, 737 + NES_IWARP_SQ_OP_SENDSEINV = 6, 738 + NES_IWARP_SQ_OP_BIND = 8, 739 + NES_IWARP_SQ_OP_FAST_REG = 9, 740 + NES_IWARP_SQ_OP_LOCINV = 10, 741 + NES_IWARP_SQ_OP_RDMAR_LOCINV = 11, 742 + NES_IWARP_SQ_OP_NOP = 12, 743 + }; 744 + 745 + #define NES_EEPROM_READ_REQUEST (1<<16) 746 + #define NES_MAC_ADDR_VALID (1<<20) 747 + 748 + /* 749 + * NES index registers init values. 750 + */ 751 + struct nes_init_values { 752 + u32 index; 753 + u32 data; 754 + u8 wrt; 755 + }; 756 + 757 + /* 758 + * NES registers in BAR0. 759 + */ 760 + struct nes_pci_regs { 761 + u32 int_status; 762 + u32 int_mask; 763 + u32 int_pending; 764 + u32 intf_int_status; 765 + u32 intf_int_mask; 766 + u32 other_regs[59]; /* pad out to 256 bytes for now */ 767 + }; 768 + 769 + #define NES_CQP_SQ_SIZE 128 770 + #define NES_CCQ_SIZE 128 771 + #define NES_NIC_WQ_SIZE 512 772 + #define NES_NIC_CTX_SIZE ((NES_NIC_CTX_RQ_SIZE_512) | (NES_NIC_CTX_SQ_SIZE_512)) 773 + #define NES_NIC_BACK_STORE 0x00038000 774 + 775 + struct nes_device; 776 + 777 + struct nes_hw_nic_qp_context { 778 + __le32 context_words[6]; 779 + }; 780 + 781 + struct nes_hw_nic_sq_wqe { 782 + __le32 wqe_words[16]; 783 + }; 784 + 785 + struct nes_hw_nic_rq_wqe { 786 + __le32 wqe_words[16]; 787 + }; 788 + 789 + struct nes_hw_nic_cqe { 790 + __le32 cqe_words[4]; 791 + }; 792 + 793 + struct nes_hw_cqp_qp_context { 794 + __le32 context_words[4]; 795 + }; 796 + 797 + struct nes_hw_cqp_wqe { 798 + __le32 wqe_words[16]; 799 + }; 800 + 801 + struct nes_hw_qp_wqe { 802 + __le32 wqe_words[32]; 803 + }; 804 + 805 + struct nes_hw_cqe { 806 + __le32 cqe_words[8]; 807 + }; 808 + 809 + struct nes_hw_ceqe { 810 + __le32 ceqe_words[2]; 811 + }; 812 + 813 + struct nes_hw_aeqe { 814 + __le32 aeqe_words[4]; 815 + }; 816 + 817 + struct nes_cqp_request { 818 + union { 819 + u64 cqp_callback_context; 820 + void *cqp_callback_pointer; 821 + }; 822 + wait_queue_head_t waitq; 823 + struct nes_hw_cqp_wqe cqp_wqe; 824 + struct list_head list; 825 + atomic_t refcount; 826 + void (*cqp_callback)(struct nes_device *nesdev, struct nes_cqp_request *cqp_request); 827 + u16 major_code; 828 + u16 minor_code; 829 + u8 waiting; 830 + u8 request_done; 831 + u8 dynamic; 832 + u8 callback; 833 + }; 834 + 835 + struct nes_hw_cqp { 836 + struct nes_hw_cqp_wqe *sq_vbase; 837 + dma_addr_t sq_pbase; 838 + spinlock_t lock; 839 + wait_queue_head_t waitq; 840 + u16 qp_id; 841 + u16 sq_head; 842 + u16 sq_tail; 843 + u16 sq_size; 844 + }; 845 + 846 + #define NES_FIRST_FRAG_SIZE 128 847 + struct nes_first_frag { 848 + u8 buffer[NES_FIRST_FRAG_SIZE]; 849 + }; 850 + 851 + struct nes_hw_nic { 852 + struct nes_first_frag *first_frag_vbase; /* virtual address of first frags */ 853 + struct nes_hw_nic_sq_wqe *sq_vbase; /* virtual address of sq */ 854 + struct nes_hw_nic_rq_wqe *rq_vbase; /* virtual address of rq */ 855 + struct sk_buff *tx_skb[NES_NIC_WQ_SIZE]; 856 + struct sk_buff *rx_skb[NES_NIC_WQ_SIZE]; 857 + dma_addr_t frag_paddr[NES_NIC_WQ_SIZE]; 858 + unsigned long first_frag_overflow[BITS_TO_LONGS(NES_NIC_WQ_SIZE)]; 859 + dma_addr_t sq_pbase; /* PCI memory for host rings */ 860 + dma_addr_t rq_pbase; /* PCI memory for host rings */ 861 + 862 + u16 qp_id; 863 + u16 sq_head; 864 + u16 sq_tail; 865 + u16 sq_size; 866 + u16 rq_head; 867 + u16 rq_tail; 868 + u16 rq_size; 869 + u8 replenishing_rq; 870 + u8 reserved; 871 + 872 + spinlock_t sq_lock; 873 + spinlock_t rq_lock; 874 + }; 875 + 876 + struct nes_hw_nic_cq { 877 + struct nes_hw_nic_cqe volatile *cq_vbase; /* PCI memory for host rings */ 878 + void (*ce_handler)(struct nes_device *nesdev, struct nes_hw_nic_cq *cq); 879 + dma_addr_t cq_pbase; /* PCI memory for host rings */ 880 + int rx_cqes_completed; 881 + int cqe_allocs_pending; 882 + int rx_pkts_indicated; 883 + u16 cq_head; 884 + u16 cq_size; 885 + u16 cq_number; 886 + u8 cqes_pending; 887 + }; 888 + 889 + struct nes_hw_qp { 890 + struct nes_hw_qp_wqe *sq_vbase; /* PCI memory for host rings */ 891 + struct nes_hw_qp_wqe *rq_vbase; /* PCI memory for host rings */ 892 + void *q2_vbase; /* PCI memory for host rings */ 893 + dma_addr_t sq_pbase; /* PCI memory for host rings */ 894 + dma_addr_t rq_pbase; /* PCI memory for host rings */ 895 + dma_addr_t q2_pbase; /* PCI memory for host rings */ 896 + u32 qp_id; 897 + u16 sq_head; 898 + u16 sq_tail; 899 + u16 sq_size; 900 + u16 rq_head; 901 + u16 rq_tail; 902 + u16 rq_size; 903 + u8 rq_encoded_size; 904 + u8 sq_encoded_size; 905 + }; 906 + 907 + struct nes_hw_cq { 908 + struct nes_hw_cqe volatile *cq_vbase; /* PCI memory for host rings */ 909 + void (*ce_handler)(struct nes_device *nesdev, struct nes_hw_cq *cq); 910 + dma_addr_t cq_pbase; /* PCI memory for host rings */ 911 + u16 cq_head; 912 + u16 cq_size; 913 + u16 cq_number; 914 + }; 915 + 916 + struct nes_hw_ceq { 917 + struct nes_hw_ceqe volatile *ceq_vbase; /* PCI memory for host rings */ 918 + dma_addr_t ceq_pbase; /* PCI memory for host rings */ 919 + u16 ceq_head; 920 + u16 ceq_size; 921 + }; 922 + 923 + struct nes_hw_aeq { 924 + struct nes_hw_aeqe volatile *aeq_vbase; /* PCI memory for host rings */ 925 + dma_addr_t aeq_pbase; /* PCI memory for host rings */ 926 + u16 aeq_head; 927 + u16 aeq_size; 928 + }; 929 + 930 + struct nic_qp_map { 931 + u8 qpid; 932 + u8 nic_index; 933 + u8 logical_port; 934 + u8 is_hnic; 935 + }; 936 + 937 + #define NES_CQP_ARP_AEQ_INDEX_MASK 0x000f0000 938 + #define NES_CQP_ARP_AEQ_INDEX_SHIFT 16 939 + 940 + #define NES_CQP_APBVT_ADD 0x00008000 941 + #define NES_CQP_APBVT_NIC_SHIFT 16 942 + 943 + #define NES_ARP_ADD 1 944 + #define NES_ARP_DELETE 2 945 + #define NES_ARP_RESOLVE 3 946 + 947 + #define NES_MAC_SW_IDLE 0 948 + #define NES_MAC_SW_INTERRUPT 1 949 + #define NES_MAC_SW_MH 2 950 + 951 + struct nes_arp_entry { 952 + u32 ip_addr; 953 + u8 mac_addr[ETH_ALEN]; 954 + }; 955 + 956 + #define NES_NIC_FAST_TIMER 96 957 + #define NES_NIC_FAST_TIMER_LOW 40 958 + #define NES_NIC_FAST_TIMER_HIGH 1000 959 + #define DEFAULT_NES_QL_HIGH 256 960 + #define DEFAULT_NES_QL_LOW 16 961 + #define DEFAULT_NES_QL_TARGET 64 962 + #define DEFAULT_JUMBO_NES_QL_LOW 12 963 + #define DEFAULT_JUMBO_NES_QL_TARGET 40 964 + #define DEFAULT_JUMBO_NES_QL_HIGH 128 965 + #define NES_NIC_CQ_DOWNWARD_TREND 8 966 + 967 + struct nes_hw_tune_timer { 968 + //u16 cq_count; 969 + u16 threshold_low; 970 + u16 threshold_target; 971 + u16 threshold_high; 972 + u16 timer_in_use; 973 + u16 timer_in_use_old; 974 + u16 timer_in_use_min; 975 + u16 timer_in_use_max; 976 + u8 timer_direction_upward; 977 + u8 timer_direction_downward; 978 + u16 cq_count_old; 979 + u8 cq_direction_downward; 980 + }; 981 + 982 + #define NES_TIMER_INT_LIMIT 2 983 + #define NES_TIMER_INT_LIMIT_DYNAMIC 10 984 + #define NES_TIMER_ENABLE_LIMIT 4 985 + #define NES_MAX_LINK_INTERRUPTS 128 986 + #define NES_MAX_LINK_CHECK 200 987 + 988 + struct nes_adapter { 989 + u64 fw_ver; 990 + unsigned long *allocated_qps; 991 + unsigned long *allocated_cqs; 992 + unsigned long *allocated_mrs; 993 + unsigned long *allocated_pds; 994 + unsigned long *allocated_arps; 995 + struct nes_qp **qp_table; 996 + struct workqueue_struct *work_q; 997 + 998 + struct list_head list; 999 + struct list_head active_listeners; 1000 + /* list of the netdev's associated with each logical port */ 1001 + struct list_head nesvnic_list[4]; 1002 + 1003 + struct timer_list mh_timer; 1004 + struct timer_list lc_timer; 1005 + struct work_struct work; 1006 + spinlock_t resource_lock; 1007 + spinlock_t phy_lock; 1008 + spinlock_t pbl_lock; 1009 + spinlock_t periodic_timer_lock; 1010 + 1011 + struct nes_arp_entry arp_table[NES_MAX_ARP_TABLE_SIZE]; 1012 + 1013 + /* Adapter CEQ and AEQs */ 1014 + struct nes_hw_ceq ceq[16]; 1015 + struct nes_hw_aeq aeq[8]; 1016 + 1017 + struct nes_hw_tune_timer tune_timer; 1018 + 1019 + unsigned long doorbell_start; 1020 + 1021 + u32 hw_rev; 1022 + u32 vendor_id; 1023 + u32 vendor_part_id; 1024 + u32 device_cap_flags; 1025 + u32 tick_delta; 1026 + u32 timer_int_req; 1027 + u32 arp_table_size; 1028 + u32 next_arp_index; 1029 + 1030 + u32 max_mr; 1031 + u32 max_256pbl; 1032 + u32 max_4kpbl; 1033 + u32 free_256pbl; 1034 + u32 free_4kpbl; 1035 + u32 max_mr_size; 1036 + u32 max_qp; 1037 + u32 next_qp; 1038 + u32 max_irrq; 1039 + u32 max_qp_wr; 1040 + u32 max_sge; 1041 + u32 max_cq; 1042 + u32 next_cq; 1043 + u32 max_cqe; 1044 + u32 max_pd; 1045 + u32 base_pd; 1046 + u32 next_pd; 1047 + u32 hte_index_mask; 1048 + 1049 + /* EEPROM information */ 1050 + u32 rx_pool_size; 1051 + u32 tx_pool_size; 1052 + u32 rx_threshold; 1053 + u32 tcp_timer_core_clk_divisor; 1054 + u32 iwarp_config; 1055 + u32 cm_config; 1056 + u32 sws_timer_config; 1057 + u32 tcp_config1; 1058 + u32 wqm_wat; 1059 + u32 core_clock; 1060 + u32 firmware_version; 1061 + 1062 + u32 nic_rx_eth_route_err; 1063 + 1064 + u32 et_rx_coalesce_usecs; 1065 + u32 et_rx_max_coalesced_frames; 1066 + u32 et_rx_coalesce_usecs_irq; 1067 + u32 et_rx_max_coalesced_frames_irq; 1068 + u32 et_pkt_rate_low; 1069 + u32 et_rx_coalesce_usecs_low; 1070 + u32 et_rx_max_coalesced_frames_low; 1071 + u32 et_pkt_rate_high; 1072 + u32 et_rx_coalesce_usecs_high; 1073 + u32 et_rx_max_coalesced_frames_high; 1074 + u32 et_rate_sample_interval; 1075 + u32 timer_int_limit; 1076 + 1077 + /* Adapter base MAC address */ 1078 + u32 mac_addr_low; 1079 + u16 mac_addr_high; 1080 + 1081 + u16 firmware_eeprom_offset; 1082 + u16 software_eeprom_offset; 1083 + 1084 + u16 max_irrq_wr; 1085 + 1086 + /* pd config for each port */ 1087 + u16 pd_config_size[4]; 1088 + u16 pd_config_base[4]; 1089 + 1090 + u16 link_interrupt_count[4]; 1091 + 1092 + /* the phy index for each port */ 1093 + u8 phy_index[4]; 1094 + u8 mac_sw_state[4]; 1095 + u8 mac_link_down[4]; 1096 + u8 phy_type[4]; 1097 + 1098 + /* PCI information */ 1099 + unsigned int devfn; 1100 + unsigned char bus_number; 1101 + unsigned char OneG_Mode; 1102 + 1103 + unsigned char ref_count; 1104 + u8 netdev_count; 1105 + u8 netdev_max; /* from host nic address count in EEPROM */ 1106 + u8 port_count; 1107 + u8 virtwq; 1108 + u8 et_use_adaptive_rx_coalesce; 1109 + u8 adapter_fcn_count; 1110 + }; 1111 + 1112 + struct nes_pbl { 1113 + u64 *pbl_vbase; 1114 + dma_addr_t pbl_pbase; 1115 + struct page *page; 1116 + unsigned long user_base; 1117 + u32 pbl_size; 1118 + struct list_head list; 1119 + /* TODO: need to add list for two level tables */ 1120 + }; 1121 + 1122 + struct nes_listener { 1123 + struct work_struct work; 1124 + struct workqueue_struct *wq; 1125 + struct nes_vnic *nesvnic; 1126 + struct iw_cm_id *cm_id; 1127 + struct list_head list; 1128 + unsigned long socket; 1129 + u8 accept_failed; 1130 + }; 1131 + 1132 + struct nes_ib_device; 1133 + 1134 + struct nes_vnic { 1135 + struct nes_ib_device *nesibdev; 1136 + u64 sq_full; 1137 + u64 sq_locked; 1138 + u64 tso_requests; 1139 + u64 segmented_tso_requests; 1140 + u64 linearized_skbs; 1141 + u64 tx_sw_dropped; 1142 + u64 endnode_nstat_rx_discard; 1143 + u64 endnode_nstat_rx_octets; 1144 + u64 endnode_nstat_rx_frames; 1145 + u64 endnode_nstat_tx_octets; 1146 + u64 endnode_nstat_tx_frames; 1147 + u64 endnode_ipv4_tcp_retransmits; 1148 + /* void *mem; */ 1149 + struct nes_device *nesdev; 1150 + struct net_device *netdev; 1151 + struct vlan_group *vlan_grp; 1152 + atomic_t rx_skbs_needed; 1153 + atomic_t rx_skb_timer_running; 1154 + int budget; 1155 + u32 msg_enable; 1156 + /* u32 tx_avail; */ 1157 + __be32 local_ipaddr; 1158 + struct napi_struct napi; 1159 + spinlock_t tx_lock; /* could use netdev tx lock? */ 1160 + struct timer_list rq_wqes_timer; 1161 + u32 nic_mem_size; 1162 + void *nic_vbase; 1163 + dma_addr_t nic_pbase; 1164 + struct nes_hw_nic nic; 1165 + struct nes_hw_nic_cq nic_cq; 1166 + u32 mcrq_qp_id; 1167 + struct nes_ucontext *mcrq_ucontext; 1168 + struct nes_cqp_request* (*get_cqp_request)(struct nes_device *nesdev); 1169 + void (*post_cqp_request)(struct nes_device*, struct nes_cqp_request *, int); 1170 + int (*mcrq_mcast_filter)( struct nes_vnic* nesvnic, __u8* dmi_addr ); 1171 + struct net_device_stats netstats; 1172 + /* used to put the netdev on the adapters logical port list */ 1173 + struct list_head list; 1174 + u16 max_frame_size; 1175 + u8 netdev_open; 1176 + u8 linkup; 1177 + u8 logical_port; 1178 + u8 netdev_index; /* might not be needed, indexes nesdev->netdev */ 1179 + u8 perfect_filter_index; 1180 + u8 nic_index; 1181 + u8 qp_nic_index[4]; 1182 + u8 next_qp_nic_index; 1183 + u8 of_device_registered; 1184 + u8 rdma_enabled; 1185 + u8 rx_checksum_disabled; 1186 + }; 1187 + 1188 + struct nes_ib_device { 1189 + struct ib_device ibdev; 1190 + struct nes_vnic *nesvnic; 1191 + 1192 + /* Virtual RNIC Limits */ 1193 + u32 max_mr; 1194 + u32 max_qp; 1195 + u32 max_cq; 1196 + u32 max_pd; 1197 + u32 num_mr; 1198 + u32 num_qp; 1199 + u32 num_cq; 1200 + u32 num_pd; 1201 + }; 1202 + 1203 + #define nes_vlan_rx vlan_hwaccel_receive_skb 1204 + #define nes_netif_rx netif_receive_skb 1205 + 1206 + #endif /* __NES_HW_H */
+1703
drivers/infiniband/hw/nes/nes_nic.c
···
··· 1 + /* 2 + * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved. 3 + * 4 + * This software is available to you under a choice of one of two 5 + * licenses. You may choose to be licensed under the terms of the GNU 6 + * General Public License (GPL) Version 2, available from the file 7 + * COPYING in the main directory of this source tree, or the 8 + * OpenIB.org BSD license below: 9 + * 10 + * Redistribution and use in source and binary forms, with or 11 + * without modification, are permitted provided that the following 12 + * conditions are met: 13 + * 14 + * - Redistributions of source code must retain the above 15 + * copyright notice, this list of conditions and the following 16 + * disclaimer. 17 + * 18 + * - Redistributions in binary form must reproduce the above 19 + * copyright notice, this list of conditions and the following 20 + * disclaimer in the documentation and/or other materials 21 + * provided with the distribution. 22 + * 23 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 + * SOFTWARE. 31 + * 32 + */ 33 + 34 + #include <linux/module.h> 35 + #include <linux/moduleparam.h> 36 + #include <linux/netdevice.h> 37 + #include <linux/etherdevice.h> 38 + #include <linux/ip.h> 39 + #include <linux/tcp.h> 40 + #include <linux/if_arp.h> 41 + #include <linux/if_vlan.h> 42 + #include <linux/ethtool.h> 43 + #include <net/tcp.h> 44 + 45 + #include <net/inet_common.h> 46 + #include <linux/inet.h> 47 + 48 + #include "nes.h" 49 + 50 + static struct nic_qp_map nic_qp_mapping_0[] = { 51 + {16,0,0,1},{24,4,0,0},{28,8,0,0},{32,12,0,0}, 52 + {20,2,2,1},{26,6,2,0},{30,10,2,0},{34,14,2,0}, 53 + {18,1,1,1},{25,5,1,0},{29,9,1,0},{33,13,1,0}, 54 + {22,3,3,1},{27,7,3,0},{31,11,3,0},{35,15,3,0} 55 + }; 56 + 57 + static struct nic_qp_map nic_qp_mapping_1[] = { 58 + {18,1,1,1},{25,5,1,0},{29,9,1,0},{33,13,1,0}, 59 + {22,3,3,1},{27,7,3,0},{31,11,3,0},{35,15,3,0} 60 + }; 61 + 62 + static struct nic_qp_map nic_qp_mapping_2[] = { 63 + {20,2,2,1},{26,6,2,0},{30,10,2,0},{34,14,2,0} 64 + }; 65 + 66 + static struct nic_qp_map nic_qp_mapping_3[] = { 67 + {22,3,3,1},{27,7,3,0},{31,11,3,0},{35,15,3,0} 68 + }; 69 + 70 + static struct nic_qp_map nic_qp_mapping_4[] = { 71 + {28,8,0,0},{32,12,0,0} 72 + }; 73 + 74 + static struct nic_qp_map nic_qp_mapping_5[] = { 75 + {29,9,1,0},{33,13,1,0} 76 + }; 77 + 78 + static struct nic_qp_map nic_qp_mapping_6[] = { 79 + {30,10,2,0},{34,14,2,0} 80 + }; 81 + 82 + static struct nic_qp_map nic_qp_mapping_7[] = { 83 + {31,11,3,0},{35,15,3,0} 84 + }; 85 + 86 + static struct nic_qp_map *nic_qp_mapping_per_function[] = { 87 + nic_qp_mapping_0, nic_qp_mapping_1, nic_qp_mapping_2, nic_qp_mapping_3, 88 + nic_qp_mapping_4, nic_qp_mapping_5, nic_qp_mapping_6, nic_qp_mapping_7 89 + }; 90 + 91 + static const u32 default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK 92 + | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN; 93 + static int debug = -1; 94 + 95 + 96 + static int nes_netdev_open(struct net_device *); 97 + static int nes_netdev_stop(struct net_device *); 98 + static int nes_netdev_start_xmit(struct sk_buff *, struct net_device *); 99 + static struct net_device_stats *nes_netdev_get_stats(struct net_device *); 100 + static void nes_netdev_tx_timeout(struct net_device *); 101 + static int nes_netdev_set_mac_address(struct net_device *, void *); 102 + static int nes_netdev_change_mtu(struct net_device *, int); 103 + 104 + /** 105 + * nes_netdev_poll 106 + */ 107 + static int nes_netdev_poll(struct napi_struct *napi, int budget) 108 + { 109 + struct nes_vnic *nesvnic = container_of(napi, struct nes_vnic, napi); 110 + struct net_device *netdev = nesvnic->netdev; 111 + struct nes_device *nesdev = nesvnic->nesdev; 112 + struct nes_hw_nic_cq *nescq = &nesvnic->nic_cq; 113 + 114 + nesvnic->budget = budget; 115 + nescq->cqes_pending = 0; 116 + nescq->rx_cqes_completed = 0; 117 + nescq->cqe_allocs_pending = 0; 118 + nescq->rx_pkts_indicated = 0; 119 + 120 + nes_nic_ce_handler(nesdev, nescq); 121 + 122 + if (nescq->cqes_pending == 0) { 123 + netif_rx_complete(netdev, napi); 124 + /* clear out completed cqes and arm */ 125 + nes_write32(nesdev->regs+NES_CQE_ALLOC, NES_CQE_ALLOC_NOTIFY_NEXT | 126 + nescq->cq_number | (nescq->cqe_allocs_pending << 16)); 127 + nes_read32(nesdev->regs+NES_CQE_ALLOC); 128 + } else { 129 + /* clear out completed cqes but don't arm */ 130 + nes_write32(nesdev->regs+NES_CQE_ALLOC, 131 + nescq->cq_number | (nescq->cqe_allocs_pending << 16)); 132 + nes_debug(NES_DBG_NETDEV, "%s: exiting with work pending\n", 133 + nesvnic->netdev->name); 134 + } 135 + return nescq->rx_pkts_indicated; 136 + } 137 + 138 + 139 + /** 140 + * nes_netdev_open - Activate the network interface; ifconfig 141 + * ethx up. 142 + */ 143 + static int nes_netdev_open(struct net_device *netdev) 144 + { 145 + u32 macaddr_low; 146 + u16 macaddr_high; 147 + struct nes_vnic *nesvnic = netdev_priv(netdev); 148 + struct nes_device *nesdev = nesvnic->nesdev; 149 + int ret; 150 + int i; 151 + struct nes_vnic *first_nesvnic; 152 + u32 nic_active_bit; 153 + u32 nic_active; 154 + 155 + assert(nesdev != NULL); 156 + 157 + first_nesvnic = list_entry(nesdev->nesadapter->nesvnic_list[nesdev->mac_index].next, 158 + struct nes_vnic, list); 159 + 160 + if (netif_msg_ifup(nesvnic)) 161 + printk(KERN_INFO PFX "%s: enabling interface\n", netdev->name); 162 + 163 + ret = nes_init_nic_qp(nesdev, netdev); 164 + if (ret) { 165 + return ret; 166 + } 167 + 168 + netif_carrier_off(netdev); 169 + netif_stop_queue(netdev); 170 + 171 + if ((!nesvnic->of_device_registered) && (nesvnic->rdma_enabled)) { 172 + nesvnic->nesibdev = nes_init_ofa_device(netdev); 173 + if (nesvnic->nesibdev == NULL) { 174 + printk(KERN_ERR PFX "%s: nesvnic->nesibdev alloc failed", netdev->name); 175 + } else { 176 + nesvnic->nesibdev->nesvnic = nesvnic; 177 + ret = nes_register_ofa_device(nesvnic->nesibdev); 178 + if (ret) { 179 + printk(KERN_ERR PFX "%s: Unable to register RDMA device, ret = %d\n", 180 + netdev->name, ret); 181 + } 182 + } 183 + } 184 + /* Set packet filters */ 185 + nic_active_bit = 1 << nesvnic->nic_index; 186 + nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_ACTIVE); 187 + nic_active |= nic_active_bit; 188 + nes_write_indexed(nesdev, NES_IDX_NIC_ACTIVE, nic_active); 189 + nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ENABLE); 190 + nic_active |= nic_active_bit; 191 + nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ENABLE, nic_active); 192 + nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_BROADCAST_ON); 193 + nic_active |= nic_active_bit; 194 + nes_write_indexed(nesdev, NES_IDX_NIC_BROADCAST_ON, nic_active); 195 + 196 + macaddr_high = ((u16)netdev->dev_addr[0]) << 8; 197 + macaddr_high += (u16)netdev->dev_addr[1]; 198 + macaddr_low = ((u32)netdev->dev_addr[2]) << 24; 199 + macaddr_low += ((u32)netdev->dev_addr[3]) << 16; 200 + macaddr_low += ((u32)netdev->dev_addr[4]) << 8; 201 + macaddr_low += (u32)netdev->dev_addr[5]; 202 + 203 + /* Program the various MAC regs */ 204 + for (i = 0; i < NES_MAX_PORT_COUNT; i++) { 205 + if (nesvnic->qp_nic_index[i] == 0xf) { 206 + break; 207 + } 208 + nes_debug(NES_DBG_NETDEV, "i=%d, perfect filter table index= %d, PERF FILTER LOW" 209 + " (Addr:%08X) = %08X, HIGH = %08X.\n", 210 + i, nesvnic->qp_nic_index[i], 211 + NES_IDX_PERFECT_FILTER_LOW+((nesvnic->perfect_filter_index + i) * 8), 212 + macaddr_low, 213 + (u32)macaddr_high | NES_MAC_ADDR_VALID | 214 + ((((u32)nesvnic->nic_index) << 16))); 215 + nes_write_indexed(nesdev, 216 + NES_IDX_PERFECT_FILTER_LOW + (nesvnic->qp_nic_index[i] * 8), 217 + macaddr_low); 218 + nes_write_indexed(nesdev, 219 + NES_IDX_PERFECT_FILTER_HIGH + (nesvnic->qp_nic_index[i] * 8), 220 + (u32)macaddr_high | NES_MAC_ADDR_VALID | 221 + ((((u32)nesvnic->nic_index) << 16))); 222 + } 223 + 224 + 225 + nes_write32(nesdev->regs+NES_CQE_ALLOC, NES_CQE_ALLOC_NOTIFY_NEXT | 226 + nesvnic->nic_cq.cq_number); 227 + nes_read32(nesdev->regs+NES_CQE_ALLOC); 228 + 229 + if (first_nesvnic->linkup) { 230 + /* Enable network packets */ 231 + nesvnic->linkup = 1; 232 + netif_start_queue(netdev); 233 + netif_carrier_on(netdev); 234 + } 235 + napi_enable(&nesvnic->napi); 236 + nesvnic->netdev_open = 1; 237 + 238 + return 0; 239 + } 240 + 241 + 242 + /** 243 + * nes_netdev_stop 244 + */ 245 + static int nes_netdev_stop(struct net_device *netdev) 246 + { 247 + struct nes_vnic *nesvnic = netdev_priv(netdev); 248 + struct nes_device *nesdev = nesvnic->nesdev; 249 + u32 nic_active_mask; 250 + u32 nic_active; 251 + 252 + nes_debug(NES_DBG_SHUTDOWN, "nesvnic=%p, nesdev=%p, netdev=%p %s\n", 253 + nesvnic, nesdev, netdev, netdev->name); 254 + if (nesvnic->netdev_open == 0) 255 + return 0; 256 + 257 + if (netif_msg_ifdown(nesvnic)) 258 + printk(KERN_INFO PFX "%s: disabling interface\n", netdev->name); 259 + 260 + /* Disable network packets */ 261 + napi_disable(&nesvnic->napi); 262 + netif_stop_queue(netdev); 263 + if ((nesdev->netdev[0] == netdev) & (nesvnic->logical_port == nesdev->mac_index)) { 264 + nes_write_indexed(nesdev, 265 + NES_IDX_MAC_INT_MASK+(0x200*nesdev->mac_index), 0xffffffff); 266 + } 267 + 268 + nic_active_mask = ~((u32)(1 << nesvnic->nic_index)); 269 + nes_write_indexed(nesdev, NES_IDX_PERFECT_FILTER_HIGH+ 270 + (nesvnic->perfect_filter_index*8), 0); 271 + nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_ACTIVE); 272 + nic_active &= nic_active_mask; 273 + nes_write_indexed(nesdev, NES_IDX_NIC_ACTIVE, nic_active); 274 + nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL); 275 + nic_active &= nic_active_mask; 276 + nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL, nic_active); 277 + nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ENABLE); 278 + nic_active &= nic_active_mask; 279 + nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ENABLE, nic_active); 280 + nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL); 281 + nic_active &= nic_active_mask; 282 + nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active); 283 + nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_BROADCAST_ON); 284 + nic_active &= nic_active_mask; 285 + nes_write_indexed(nesdev, NES_IDX_NIC_BROADCAST_ON, nic_active); 286 + 287 + 288 + if (nesvnic->of_device_registered) { 289 + nes_destroy_ofa_device(nesvnic->nesibdev); 290 + nesvnic->nesibdev = NULL; 291 + nesvnic->of_device_registered = 0; 292 + } 293 + nes_destroy_nic_qp(nesvnic); 294 + 295 + nesvnic->netdev_open = 0; 296 + 297 + return 0; 298 + } 299 + 300 + 301 + /** 302 + * nes_nic_send 303 + */ 304 + static int nes_nic_send(struct sk_buff *skb, struct net_device *netdev) 305 + { 306 + struct nes_vnic *nesvnic = netdev_priv(netdev); 307 + struct nes_device *nesdev = nesvnic->nesdev; 308 + struct nes_hw_nic *nesnic = &nesvnic->nic; 309 + struct nes_hw_nic_sq_wqe *nic_sqe; 310 + struct tcphdr *tcph; 311 + __le16 *wqe_fragment_length; 312 + u32 wqe_misc; 313 + u16 wqe_fragment_index = 1; /* first fragment (0) is used by copy buffer */ 314 + u16 skb_fragment_index; 315 + dma_addr_t bus_address; 316 + 317 + nic_sqe = &nesnic->sq_vbase[nesnic->sq_head]; 318 + wqe_fragment_length = (__le16 *)&nic_sqe->wqe_words[NES_NIC_SQ_WQE_LENGTH_0_TAG_IDX]; 319 + 320 + /* setup the VLAN tag if present */ 321 + if (vlan_tx_tag_present(skb)) { 322 + nes_debug(NES_DBG_NIC_TX, "%s: VLAN packet to send... VLAN = %08X\n", 323 + netdev->name, vlan_tx_tag_get(skb)); 324 + wqe_misc = NES_NIC_SQ_WQE_TAGVALUE_ENABLE; 325 + wqe_fragment_length[0] = (__force __le16) vlan_tx_tag_get(skb); 326 + } else 327 + wqe_misc = 0; 328 + 329 + /* bump past the vlan tag */ 330 + wqe_fragment_length++; 331 + /* wqe_fragment_address = (u64 *)&nic_sqe->wqe_words[NES_NIC_SQ_WQE_FRAG0_LOW_IDX]; */ 332 + 333 + if (skb->ip_summed == CHECKSUM_PARTIAL) { 334 + tcph = tcp_hdr(skb); 335 + if (1) { 336 + if (skb_is_gso(skb)) { 337 + /* nes_debug(NES_DBG_NIC_TX, "%s: TSO request... seg size = %u\n", 338 + netdev->name, skb_is_gso(skb)); */ 339 + wqe_misc |= NES_NIC_SQ_WQE_LSO_ENABLE | 340 + NES_NIC_SQ_WQE_COMPLETION | (u16)skb_is_gso(skb); 341 + set_wqe_32bit_value(nic_sqe->wqe_words, NES_NIC_SQ_WQE_LSO_INFO_IDX, 342 + ((u32)tcph->doff) | 343 + (((u32)(((unsigned char *)tcph) - skb->data)) << 4)); 344 + } else { 345 + wqe_misc |= NES_NIC_SQ_WQE_COMPLETION; 346 + } 347 + } 348 + } else { /* CHECKSUM_HW */ 349 + wqe_misc |= NES_NIC_SQ_WQE_DISABLE_CHKSUM | NES_NIC_SQ_WQE_COMPLETION; 350 + } 351 + 352 + set_wqe_32bit_value(nic_sqe->wqe_words, NES_NIC_SQ_WQE_TOTAL_LENGTH_IDX, 353 + skb->len); 354 + memcpy(&nesnic->first_frag_vbase[nesnic->sq_head].buffer, 355 + skb->data, min(((unsigned int)NES_FIRST_FRAG_SIZE), skb_headlen(skb))); 356 + wqe_fragment_length[0] = cpu_to_le16(min(((unsigned int)NES_FIRST_FRAG_SIZE), 357 + skb_headlen(skb))); 358 + wqe_fragment_length[1] = 0; 359 + if (skb_headlen(skb) > NES_FIRST_FRAG_SIZE) { 360 + if ((skb_shinfo(skb)->nr_frags + 1) > 4) { 361 + nes_debug(NES_DBG_NIC_TX, "%s: Packet with %u fragments not sent, skb_headlen=%u\n", 362 + netdev->name, skb_shinfo(skb)->nr_frags + 2, skb_headlen(skb)); 363 + kfree_skb(skb); 364 + nesvnic->tx_sw_dropped++; 365 + return NETDEV_TX_LOCKED; 366 + } 367 + set_bit(nesnic->sq_head, nesnic->first_frag_overflow); 368 + bus_address = pci_map_single(nesdev->pcidev, skb->data + NES_FIRST_FRAG_SIZE, 369 + skb_headlen(skb) - NES_FIRST_FRAG_SIZE, PCI_DMA_TODEVICE); 370 + wqe_fragment_length[wqe_fragment_index++] = 371 + cpu_to_le16(skb_headlen(skb) - NES_FIRST_FRAG_SIZE); 372 + wqe_fragment_length[wqe_fragment_index] = 0; 373 + set_wqe_64bit_value(nic_sqe->wqe_words, NES_NIC_SQ_WQE_FRAG1_LOW_IDX, 374 + ((u64)(bus_address))); 375 + nesnic->tx_skb[nesnic->sq_head] = skb; 376 + } 377 + 378 + if (skb_headlen(skb) == skb->len) { 379 + if (skb_headlen(skb) <= NES_FIRST_FRAG_SIZE) { 380 + nic_sqe->wqe_words[NES_NIC_SQ_WQE_LENGTH_2_1_IDX] = 0; 381 + nesnic->tx_skb[nesnic->sq_head] = NULL; 382 + dev_kfree_skb(skb); 383 + } 384 + } else { 385 + /* Deal with Fragments */ 386 + nesnic->tx_skb[nesnic->sq_head] = skb; 387 + for (skb_fragment_index = 0; skb_fragment_index < skb_shinfo(skb)->nr_frags; 388 + skb_fragment_index++) { 389 + bus_address = pci_map_page( nesdev->pcidev, 390 + skb_shinfo(skb)->frags[skb_fragment_index].page, 391 + skb_shinfo(skb)->frags[skb_fragment_index].page_offset, 392 + skb_shinfo(skb)->frags[skb_fragment_index].size, 393 + PCI_DMA_TODEVICE); 394 + wqe_fragment_length[wqe_fragment_index] = 395 + cpu_to_le16(skb_shinfo(skb)->frags[skb_fragment_index].size); 396 + set_wqe_64bit_value(nic_sqe->wqe_words, NES_NIC_SQ_WQE_FRAG0_LOW_IDX+(2*wqe_fragment_index), 397 + bus_address); 398 + wqe_fragment_index++; 399 + if (wqe_fragment_index < 5) 400 + wqe_fragment_length[wqe_fragment_index] = 0; 401 + } 402 + } 403 + 404 + set_wqe_32bit_value(nic_sqe->wqe_words, NES_NIC_SQ_WQE_MISC_IDX, wqe_misc); 405 + nesnic->sq_head++; 406 + nesnic->sq_head &= nesnic->sq_size - 1; 407 + 408 + return NETDEV_TX_OK; 409 + } 410 + 411 + 412 + /** 413 + * nes_netdev_start_xmit 414 + */ 415 + static int nes_netdev_start_xmit(struct sk_buff *skb, struct net_device *netdev) 416 + { 417 + struct nes_vnic *nesvnic = netdev_priv(netdev); 418 + struct nes_device *nesdev = nesvnic->nesdev; 419 + struct nes_hw_nic *nesnic = &nesvnic->nic; 420 + struct nes_hw_nic_sq_wqe *nic_sqe; 421 + struct tcphdr *tcph; 422 + /* struct udphdr *udph; */ 423 + #define NES_MAX_TSO_FRAGS 18 424 + /* 64K segment plus overflow on each side */ 425 + dma_addr_t tso_bus_address[NES_MAX_TSO_FRAGS]; 426 + dma_addr_t bus_address; 427 + u32 tso_frag_index; 428 + u32 tso_frag_count; 429 + u32 tso_wqe_length; 430 + u32 curr_tcp_seq; 431 + u32 wqe_count=1; 432 + u32 send_rc; 433 + struct iphdr *iph; 434 + unsigned long flags; 435 + __le16 *wqe_fragment_length; 436 + u32 nr_frags; 437 + u32 original_first_length; 438 + // u64 *wqe_fragment_address; 439 + /* first fragment (0) is used by copy buffer */ 440 + u16 wqe_fragment_index=1; 441 + u16 hoffset; 442 + u16 nhoffset; 443 + u16 wqes_needed; 444 + u16 wqes_available; 445 + u32 old_head; 446 + u32 wqe_misc; 447 + 448 + /* nes_debug(NES_DBG_NIC_TX, "%s Request to tx NIC packet length %u, headlen %u," 449 + " (%u frags), tso_size=%u\n", 450 + netdev->name, skb->len, skb_headlen(skb), 451 + skb_shinfo(skb)->nr_frags, skb_is_gso(skb)); 452 + */ 453 + 454 + if (!netif_carrier_ok(netdev)) 455 + return NETDEV_TX_OK; 456 + 457 + if (netif_queue_stopped(netdev)) 458 + return NETDEV_TX_BUSY; 459 + 460 + local_irq_save(flags); 461 + if (!spin_trylock(&nesnic->sq_lock)) { 462 + local_irq_restore(flags); 463 + nesvnic->sq_locked++; 464 + return NETDEV_TX_LOCKED; 465 + } 466 + 467 + /* Check if SQ is full */ 468 + if ((((nesnic->sq_tail+(nesnic->sq_size*2))-nesnic->sq_head) & (nesnic->sq_size - 1)) == 1) { 469 + if (!netif_queue_stopped(netdev)) { 470 + netif_stop_queue(netdev); 471 + barrier(); 472 + if ((((((volatile u16)nesnic->sq_tail)+(nesnic->sq_size*2))-nesnic->sq_head) & (nesnic->sq_size - 1)) != 1) { 473 + netif_start_queue(netdev); 474 + goto sq_no_longer_full; 475 + } 476 + } 477 + nesvnic->sq_full++; 478 + spin_unlock_irqrestore(&nesnic->sq_lock, flags); 479 + return NETDEV_TX_BUSY; 480 + } 481 + 482 + sq_no_longer_full: 483 + nr_frags = skb_shinfo(skb)->nr_frags; 484 + if (skb_headlen(skb) > NES_FIRST_FRAG_SIZE) { 485 + nr_frags++; 486 + } 487 + /* Check if too many fragments */ 488 + if (unlikely((nr_frags > 4))) { 489 + if (skb_is_gso(skb)) { 490 + nesvnic->segmented_tso_requests++; 491 + nesvnic->tso_requests++; 492 + old_head = nesnic->sq_head; 493 + /* Basically 4 fragments available per WQE with extended fragments */ 494 + wqes_needed = nr_frags >> 2; 495 + wqes_needed += (nr_frags&3)?1:0; 496 + wqes_available = (((nesnic->sq_tail+nesnic->sq_size)-nesnic->sq_head) - 1) & 497 + (nesnic->sq_size - 1); 498 + 499 + if (unlikely(wqes_needed > wqes_available)) { 500 + if (!netif_queue_stopped(netdev)) { 501 + netif_stop_queue(netdev); 502 + barrier(); 503 + wqes_available = (((((volatile u16)nesnic->sq_tail)+nesnic->sq_size)-nesnic->sq_head) - 1) & 504 + (nesnic->sq_size - 1); 505 + if (wqes_needed <= wqes_available) { 506 + netif_start_queue(netdev); 507 + goto tso_sq_no_longer_full; 508 + } 509 + } 510 + nesvnic->sq_full++; 511 + spin_unlock_irqrestore(&nesnic->sq_lock, flags); 512 + nes_debug(NES_DBG_NIC_TX, "%s: HNIC SQ full- TSO request has too many frags!\n", 513 + netdev->name); 514 + return NETDEV_TX_BUSY; 515 + } 516 + tso_sq_no_longer_full: 517 + /* Map all the buffers */ 518 + for (tso_frag_count=0; tso_frag_count < skb_shinfo(skb)->nr_frags; 519 + tso_frag_count++) { 520 + tso_bus_address[tso_frag_count] = pci_map_page( nesdev->pcidev, 521 + skb_shinfo(skb)->frags[tso_frag_count].page, 522 + skb_shinfo(skb)->frags[tso_frag_count].page_offset, 523 + skb_shinfo(skb)->frags[tso_frag_count].size, 524 + PCI_DMA_TODEVICE); 525 + } 526 + 527 + tso_frag_index = 0; 528 + curr_tcp_seq = ntohl(tcp_hdr(skb)->seq); 529 + hoffset = skb_transport_header(skb) - skb->data; 530 + nhoffset = skb_network_header(skb) - skb->data; 531 + original_first_length = hoffset + ((((struct tcphdr *)skb_transport_header(skb))->doff)<<2); 532 + 533 + for (wqe_count=0; wqe_count<((u32)wqes_needed); wqe_count++) { 534 + tso_wqe_length = 0; 535 + nic_sqe = &nesnic->sq_vbase[nesnic->sq_head]; 536 + wqe_fragment_length = 537 + (__le16 *)&nic_sqe->wqe_words[NES_NIC_SQ_WQE_LENGTH_0_TAG_IDX]; 538 + /* setup the VLAN tag if present */ 539 + if (vlan_tx_tag_present(skb)) { 540 + nes_debug(NES_DBG_NIC_TX, "%s: VLAN packet to send... VLAN = %08X\n", 541 + netdev->name, vlan_tx_tag_get(skb) ); 542 + wqe_misc = NES_NIC_SQ_WQE_TAGVALUE_ENABLE; 543 + wqe_fragment_length[0] = (__force __le16) vlan_tx_tag_get(skb); 544 + } else 545 + wqe_misc = 0; 546 + 547 + /* bump past the vlan tag */ 548 + wqe_fragment_length++; 549 + 550 + /* Assumes header totally fits in allocated buffer and is in first fragment */ 551 + if (original_first_length > NES_FIRST_FRAG_SIZE) { 552 + nes_debug(NES_DBG_NIC_TX, "ERROR: SKB header too big, headlen=%u, FIRST_FRAG_SIZE=%u\n", 553 + original_first_length, NES_FIRST_FRAG_SIZE); 554 + nes_debug(NES_DBG_NIC_TX, "%s Request to tx NIC packet length %u, headlen %u," 555 + " (%u frags), tso_size=%u\n", 556 + netdev->name, 557 + skb->len, skb_headlen(skb), 558 + skb_shinfo(skb)->nr_frags, skb_is_gso(skb)); 559 + } 560 + memcpy(&nesnic->first_frag_vbase[nesnic->sq_head].buffer, 561 + skb->data, min(((unsigned int)NES_FIRST_FRAG_SIZE), 562 + original_first_length)); 563 + iph = (struct iphdr *) 564 + (&nesnic->first_frag_vbase[nesnic->sq_head].buffer[nhoffset]); 565 + tcph = (struct tcphdr *) 566 + (&nesnic->first_frag_vbase[nesnic->sq_head].buffer[hoffset]); 567 + if ((wqe_count+1)!=(u32)wqes_needed) { 568 + tcph->fin = 0; 569 + tcph->psh = 0; 570 + tcph->rst = 0; 571 + tcph->urg = 0; 572 + } 573 + if (wqe_count) { 574 + tcph->syn = 0; 575 + } 576 + tcph->seq = htonl(curr_tcp_seq); 577 + wqe_fragment_length[0] = cpu_to_le16(min(((unsigned int)NES_FIRST_FRAG_SIZE), 578 + original_first_length)); 579 + 580 + wqe_fragment_index = 1; 581 + if ((wqe_count==0) && (skb_headlen(skb) > original_first_length)) { 582 + set_bit(nesnic->sq_head, nesnic->first_frag_overflow); 583 + bus_address = pci_map_single(nesdev->pcidev, skb->data + original_first_length, 584 + skb_headlen(skb) - original_first_length, PCI_DMA_TODEVICE); 585 + wqe_fragment_length[wqe_fragment_index++] = 586 + cpu_to_le16(skb_headlen(skb) - original_first_length); 587 + wqe_fragment_length[wqe_fragment_index] = 0; 588 + set_wqe_64bit_value(nic_sqe->wqe_words, NES_NIC_SQ_WQE_FRAG1_LOW_IDX, 589 + bus_address); 590 + } 591 + while (wqe_fragment_index < 5) { 592 + wqe_fragment_length[wqe_fragment_index] = 593 + cpu_to_le16(skb_shinfo(skb)->frags[tso_frag_index].size); 594 + set_wqe_64bit_value(nic_sqe->wqe_words, NES_NIC_SQ_WQE_FRAG0_LOW_IDX+(2*wqe_fragment_index), 595 + (u64)tso_bus_address[tso_frag_index]); 596 + wqe_fragment_index++; 597 + tso_wqe_length += skb_shinfo(skb)->frags[tso_frag_index++].size; 598 + if (wqe_fragment_index < 5) 599 + wqe_fragment_length[wqe_fragment_index] = 0; 600 + if (tso_frag_index == tso_frag_count) 601 + break; 602 + } 603 + if ((wqe_count+1) == (u32)wqes_needed) { 604 + nesnic->tx_skb[nesnic->sq_head] = skb; 605 + } else { 606 + nesnic->tx_skb[nesnic->sq_head] = NULL; 607 + } 608 + wqe_misc |= NES_NIC_SQ_WQE_COMPLETION | (u16)skb_is_gso(skb); 609 + if ((tso_wqe_length + original_first_length) > skb_is_gso(skb)) { 610 + wqe_misc |= NES_NIC_SQ_WQE_LSO_ENABLE; 611 + } else { 612 + iph->tot_len = htons(tso_wqe_length + original_first_length - nhoffset); 613 + } 614 + 615 + set_wqe_32bit_value(nic_sqe->wqe_words, NES_NIC_SQ_WQE_MISC_IDX, 616 + wqe_misc); 617 + set_wqe_32bit_value(nic_sqe->wqe_words, NES_NIC_SQ_WQE_LSO_INFO_IDX, 618 + ((u32)tcph->doff) | (((u32)hoffset) << 4)); 619 + 620 + set_wqe_32bit_value(nic_sqe->wqe_words, NES_NIC_SQ_WQE_TOTAL_LENGTH_IDX, 621 + tso_wqe_length + original_first_length); 622 + curr_tcp_seq += tso_wqe_length; 623 + nesnic->sq_head++; 624 + nesnic->sq_head &= nesnic->sq_size-1; 625 + } 626 + } else { 627 + nesvnic->linearized_skbs++; 628 + hoffset = skb_transport_header(skb) - skb->data; 629 + nhoffset = skb_network_header(skb) - skb->data; 630 + skb_linearize(skb); 631 + skb_set_transport_header(skb, hoffset); 632 + skb_set_network_header(skb, nhoffset); 633 + send_rc = nes_nic_send(skb, netdev); 634 + if (send_rc != NETDEV_TX_OK) { 635 + spin_unlock_irqrestore(&nesnic->sq_lock, flags); 636 + return NETDEV_TX_OK; 637 + } 638 + } 639 + } else { 640 + send_rc = nes_nic_send(skb, netdev); 641 + if (send_rc != NETDEV_TX_OK) { 642 + spin_unlock_irqrestore(&nesnic->sq_lock, flags); 643 + return NETDEV_TX_OK; 644 + } 645 + } 646 + 647 + barrier(); 648 + 649 + if (wqe_count) 650 + nes_write32(nesdev->regs+NES_WQE_ALLOC, 651 + (wqe_count << 24) | (1 << 23) | nesvnic->nic.qp_id); 652 + 653 + netdev->trans_start = jiffies; 654 + spin_unlock_irqrestore(&nesnic->sq_lock, flags); 655 + 656 + return NETDEV_TX_OK; 657 + } 658 + 659 + 660 + /** 661 + * nes_netdev_get_stats 662 + */ 663 + static struct net_device_stats *nes_netdev_get_stats(struct net_device *netdev) 664 + { 665 + struct nes_vnic *nesvnic = netdev_priv(netdev); 666 + struct nes_device *nesdev = nesvnic->nesdev; 667 + u64 u64temp; 668 + u32 u32temp; 669 + 670 + u32temp = nes_read_indexed(nesdev, 671 + NES_IDX_ENDNODE0_NSTAT_RX_DISCARD + (nesvnic->nic_index*0x200)); 672 + nesvnic->netstats.rx_dropped += u32temp; 673 + nesvnic->endnode_nstat_rx_discard += u32temp; 674 + 675 + u64temp = (u64)nes_read_indexed(nesdev, 676 + NES_IDX_ENDNODE0_NSTAT_RX_OCTETS_LO + (nesvnic->nic_index*0x200)); 677 + u64temp += ((u64)nes_read_indexed(nesdev, 678 + NES_IDX_ENDNODE0_NSTAT_RX_OCTETS_HI + (nesvnic->nic_index*0x200))) << 32; 679 + 680 + nesvnic->endnode_nstat_rx_octets += u64temp; 681 + nesvnic->netstats.rx_bytes += u64temp; 682 + 683 + u64temp = (u64)nes_read_indexed(nesdev, 684 + NES_IDX_ENDNODE0_NSTAT_RX_FRAMES_LO + (nesvnic->nic_index*0x200)); 685 + u64temp += ((u64)nes_read_indexed(nesdev, 686 + NES_IDX_ENDNODE0_NSTAT_RX_FRAMES_HI + (nesvnic->nic_index*0x200))) << 32; 687 + 688 + nesvnic->endnode_nstat_rx_frames += u64temp; 689 + nesvnic->netstats.rx_packets += u64temp; 690 + 691 + u64temp = (u64)nes_read_indexed(nesdev, 692 + NES_IDX_ENDNODE0_NSTAT_TX_OCTETS_LO + (nesvnic->nic_index*0x200)); 693 + u64temp += ((u64)nes_read_indexed(nesdev, 694 + NES_IDX_ENDNODE0_NSTAT_TX_OCTETS_HI + (nesvnic->nic_index*0x200))) << 32; 695 + 696 + nesvnic->endnode_nstat_tx_octets += u64temp; 697 + nesvnic->netstats.tx_bytes += u64temp; 698 + 699 + u64temp = (u64)nes_read_indexed(nesdev, 700 + NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_LO + (nesvnic->nic_index*0x200)); 701 + u64temp += ((u64)nes_read_indexed(nesdev, 702 + NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_HI + (nesvnic->nic_index*0x200))) << 32; 703 + 704 + nesvnic->endnode_nstat_tx_frames += u64temp; 705 + nesvnic->netstats.tx_packets += u64temp; 706 + 707 + u32temp = nes_read_indexed(nesdev, 708 + NES_IDX_MAC_RX_SHORT_FRAMES + (nesvnic->nesdev->mac_index*0x200)); 709 + nesvnic->netstats.rx_dropped += u32temp; 710 + nesvnic->nesdev->mac_rx_errors += u32temp; 711 + nesvnic->nesdev->mac_rx_short_frames += u32temp; 712 + 713 + u32temp = nes_read_indexed(nesdev, 714 + NES_IDX_MAC_RX_OVERSIZED_FRAMES + (nesvnic->nesdev->mac_index*0x200)); 715 + nesvnic->netstats.rx_dropped += u32temp; 716 + nesvnic->nesdev->mac_rx_errors += u32temp; 717 + nesvnic->nesdev->mac_rx_oversized_frames += u32temp; 718 + 719 + u32temp = nes_read_indexed(nesdev, 720 + NES_IDX_MAC_RX_JABBER_FRAMES + (nesvnic->nesdev->mac_index*0x200)); 721 + nesvnic->netstats.rx_dropped += u32temp; 722 + nesvnic->nesdev->mac_rx_errors += u32temp; 723 + nesvnic->nesdev->mac_rx_jabber_frames += u32temp; 724 + 725 + u32temp = nes_read_indexed(nesdev, 726 + NES_IDX_MAC_RX_SYMBOL_ERR_FRAMES + (nesvnic->nesdev->mac_index*0x200)); 727 + nesvnic->netstats.rx_dropped += u32temp; 728 + nesvnic->nesdev->mac_rx_errors += u32temp; 729 + nesvnic->nesdev->mac_rx_symbol_err_frames += u32temp; 730 + 731 + u32temp = nes_read_indexed(nesdev, 732 + NES_IDX_MAC_RX_LENGTH_ERR_FRAMES + (nesvnic->nesdev->mac_index*0x200)); 733 + nesvnic->netstats.rx_length_errors += u32temp; 734 + nesvnic->nesdev->mac_rx_errors += u32temp; 735 + 736 + u32temp = nes_read_indexed(nesdev, 737 + NES_IDX_MAC_RX_CRC_ERR_FRAMES + (nesvnic->nesdev->mac_index*0x200)); 738 + nesvnic->nesdev->mac_rx_errors += u32temp; 739 + nesvnic->nesdev->mac_rx_crc_errors += u32temp; 740 + nesvnic->netstats.rx_crc_errors += u32temp; 741 + 742 + u32temp = nes_read_indexed(nesdev, 743 + NES_IDX_MAC_TX_ERRORS + (nesvnic->nesdev->mac_index*0x200)); 744 + nesvnic->nesdev->mac_tx_errors += u32temp; 745 + nesvnic->netstats.tx_errors += u32temp; 746 + 747 + return &nesvnic->netstats; 748 + } 749 + 750 + 751 + /** 752 + * nes_netdev_tx_timeout 753 + */ 754 + static void nes_netdev_tx_timeout(struct net_device *netdev) 755 + { 756 + struct nes_vnic *nesvnic = netdev_priv(netdev); 757 + 758 + if (netif_msg_timer(nesvnic)) 759 + nes_debug(NES_DBG_NIC_TX, "%s: tx timeout\n", netdev->name); 760 + } 761 + 762 + 763 + /** 764 + * nes_netdev_set_mac_address 765 + */ 766 + static int nes_netdev_set_mac_address(struct net_device *netdev, void *p) 767 + { 768 + struct nes_vnic *nesvnic = netdev_priv(netdev); 769 + struct nes_device *nesdev = nesvnic->nesdev; 770 + struct sockaddr *mac_addr = p; 771 + int i; 772 + u32 macaddr_low; 773 + u16 macaddr_high; 774 + 775 + if (!is_valid_ether_addr(mac_addr->sa_data)) 776 + return -EADDRNOTAVAIL; 777 + 778 + memcpy(netdev->dev_addr, mac_addr->sa_data, netdev->addr_len); 779 + printk(PFX "%s: Address length = %d, Address = %02X%02X%02X%02X%02X%02X..\n", 780 + __FUNCTION__, netdev->addr_len, 781 + mac_addr->sa_data[0], mac_addr->sa_data[1], 782 + mac_addr->sa_data[2], mac_addr->sa_data[3], 783 + mac_addr->sa_data[4], mac_addr->sa_data[5]); 784 + macaddr_high = ((u16)netdev->dev_addr[0]) << 8; 785 + macaddr_high += (u16)netdev->dev_addr[1]; 786 + macaddr_low = ((u32)netdev->dev_addr[2]) << 24; 787 + macaddr_low += ((u32)netdev->dev_addr[3]) << 16; 788 + macaddr_low += ((u32)netdev->dev_addr[4]) << 8; 789 + macaddr_low += (u32)netdev->dev_addr[5]; 790 + 791 + for (i = 0; i < NES_MAX_PORT_COUNT; i++) { 792 + if (nesvnic->qp_nic_index[i] == 0xf) { 793 + break; 794 + } 795 + nes_write_indexed(nesdev, 796 + NES_IDX_PERFECT_FILTER_LOW + (nesvnic->qp_nic_index[i] * 8), 797 + macaddr_low); 798 + nes_write_indexed(nesdev, 799 + NES_IDX_PERFECT_FILTER_HIGH + (nesvnic->qp_nic_index[i] * 8), 800 + (u32)macaddr_high | NES_MAC_ADDR_VALID | 801 + ((((u32)nesvnic->nic_index) << 16))); 802 + } 803 + return 0; 804 + } 805 + 806 + 807 + /** 808 + * nes_netdev_set_multicast_list 809 + */ 810 + void nes_netdev_set_multicast_list(struct net_device *netdev) 811 + { 812 + struct nes_vnic *nesvnic = netdev_priv(netdev); 813 + struct nes_device *nesdev = nesvnic->nesdev; 814 + struct dev_mc_list *multicast_addr; 815 + u32 nic_active_bit; 816 + u32 nic_active; 817 + u32 perfect_filter_register_address; 818 + u32 macaddr_low; 819 + u16 macaddr_high; 820 + u8 mc_all_on = 0; 821 + u8 mc_index; 822 + int mc_nic_index = -1; 823 + 824 + nic_active_bit = 1 << nesvnic->nic_index; 825 + 826 + if (netdev->flags & IFF_PROMISC) { 827 + nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL); 828 + nic_active |= nic_active_bit; 829 + nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL, nic_active); 830 + nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL); 831 + nic_active |= nic_active_bit; 832 + nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active); 833 + mc_all_on = 1; 834 + } else if ((netdev->flags & IFF_ALLMULTI) || (netdev->mc_count > NES_MULTICAST_PF_MAX) || 835 + (nesvnic->nic_index > 3)) { 836 + nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL); 837 + nic_active |= nic_active_bit; 838 + nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL, nic_active); 839 + nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL); 840 + nic_active &= ~nic_active_bit; 841 + nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active); 842 + mc_all_on = 1; 843 + } else { 844 + nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL); 845 + nic_active &= ~nic_active_bit; 846 + nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL, nic_active); 847 + nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL); 848 + nic_active &= ~nic_active_bit; 849 + nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active); 850 + } 851 + 852 + nes_debug(NES_DBG_NIC_RX, "Number of MC entries = %d, Promiscous = %d, All Multicast = %d.\n", 853 + netdev->mc_count, (netdev->flags & IFF_PROMISC)?1:0, 854 + (netdev->flags & IFF_ALLMULTI)?1:0); 855 + if (!mc_all_on) { 856 + multicast_addr = netdev->mc_list; 857 + perfect_filter_register_address = NES_IDX_PERFECT_FILTER_LOW + 0x80; 858 + perfect_filter_register_address += nesvnic->nic_index*0x40; 859 + for (mc_index=0; mc_index < NES_MULTICAST_PF_MAX; mc_index++) { 860 + while (multicast_addr && nesvnic->mcrq_mcast_filter && ((mc_nic_index = nesvnic->mcrq_mcast_filter(nesvnic, multicast_addr->dmi_addr)) == 0)) 861 + multicast_addr = multicast_addr->next; 862 + 863 + if (mc_nic_index < 0) 864 + mc_nic_index = nesvnic->nic_index; 865 + if (multicast_addr) { 866 + nes_debug(NES_DBG_NIC_RX, "Assigning MC Address = %02X%02X%02X%02X%02X%02X to register 0x%04X nic_idx=%d\n", 867 + multicast_addr->dmi_addr[0], multicast_addr->dmi_addr[1], 868 + multicast_addr->dmi_addr[2], multicast_addr->dmi_addr[3], 869 + multicast_addr->dmi_addr[4], multicast_addr->dmi_addr[5], 870 + perfect_filter_register_address+(mc_index * 8), mc_nic_index); 871 + macaddr_high = ((u16)multicast_addr->dmi_addr[0]) << 8; 872 + macaddr_high += (u16)multicast_addr->dmi_addr[1]; 873 + macaddr_low = ((u32)multicast_addr->dmi_addr[2]) << 24; 874 + macaddr_low += ((u32)multicast_addr->dmi_addr[3]) << 16; 875 + macaddr_low += ((u32)multicast_addr->dmi_addr[4]) << 8; 876 + macaddr_low += (u32)multicast_addr->dmi_addr[5]; 877 + nes_write_indexed(nesdev, 878 + perfect_filter_register_address+(mc_index * 8), 879 + macaddr_low); 880 + nes_write_indexed(nesdev, 881 + perfect_filter_register_address+4+(mc_index * 8), 882 + (u32)macaddr_high | NES_MAC_ADDR_VALID | 883 + ((((u32)(1<<mc_nic_index)) << 16))); 884 + multicast_addr = multicast_addr->next; 885 + } else { 886 + nes_debug(NES_DBG_NIC_RX, "Clearing MC Address at register 0x%04X\n", 887 + perfect_filter_register_address+(mc_index * 8)); 888 + nes_write_indexed(nesdev, 889 + perfect_filter_register_address+4+(mc_index * 8), 890 + 0); 891 + } 892 + } 893 + } 894 + } 895 + 896 + 897 + /** 898 + * nes_netdev_change_mtu 899 + */ 900 + static int nes_netdev_change_mtu(struct net_device *netdev, int new_mtu) 901 + { 902 + struct nes_vnic *nesvnic = netdev_priv(netdev); 903 + struct nes_device *nesdev = nesvnic->nesdev; 904 + int ret = 0; 905 + u8 jumbomode=0; 906 + 907 + if ((new_mtu < ETH_ZLEN) || (new_mtu > max_mtu)) 908 + return -EINVAL; 909 + 910 + netdev->mtu = new_mtu; 911 + nesvnic->max_frame_size = new_mtu+ETH_HLEN; 912 + 913 + if (netdev->mtu > 1500) { 914 + jumbomode=1; 915 + } 916 + nes_nic_init_timer_defaults(nesdev, jumbomode); 917 + 918 + if (netif_running(netdev)) { 919 + nes_netdev_stop(netdev); 920 + nes_netdev_open(netdev); 921 + } 922 + 923 + return ret; 924 + } 925 + 926 + 927 + /** 928 + * nes_netdev_exit - destroy network device 929 + */ 930 + void nes_netdev_exit(struct nes_vnic *nesvnic) 931 + { 932 + struct net_device *netdev = nesvnic->netdev; 933 + struct nes_ib_device *nesibdev = nesvnic->nesibdev; 934 + 935 + nes_debug(NES_DBG_SHUTDOWN, "\n"); 936 + 937 + // destroy the ibdevice if RDMA enabled 938 + if ((nesvnic->rdma_enabled)&&(nesvnic->of_device_registered)) { 939 + nes_destroy_ofa_device( nesibdev ); 940 + nesvnic->of_device_registered = 0; 941 + nesvnic->nesibdev = NULL; 942 + } 943 + unregister_netdev(netdev); 944 + nes_debug(NES_DBG_SHUTDOWN, "\n"); 945 + } 946 + 947 + 948 + #define NES_ETHTOOL_STAT_COUNT 55 949 + static const char nes_ethtool_stringset[NES_ETHTOOL_STAT_COUNT][ETH_GSTRING_LEN] = { 950 + "Link Change Interrupts", 951 + "Linearized SKBs", 952 + "T/GSO Requests", 953 + "Pause Frames Sent", 954 + "Pause Frames Received", 955 + "Internal Routing Errors", 956 + "SQ SW Dropped SKBs", 957 + "SQ Locked", 958 + "SQ Full", 959 + "Segmented TSO Requests", 960 + "Rx Symbol Errors", 961 + "Rx Jabber Errors", 962 + "Rx Oversized Frames", 963 + "Rx Short Frames", 964 + "Endnode Rx Discards", 965 + "Endnode Rx Octets", 966 + "Endnode Rx Frames", 967 + "Endnode Tx Octets", 968 + "Endnode Tx Frames", 969 + "mh detected", 970 + "mh pauses", 971 + "Retransmission Count", 972 + "CM Connects", 973 + "CM Accepts", 974 + "Disconnects", 975 + "Connected Events", 976 + "Connect Requests", 977 + "CM Rejects", 978 + "ModifyQP Timeouts", 979 + "CreateQPs", 980 + "SW DestroyQPs", 981 + "DestroyQPs", 982 + "CM Closes", 983 + "CM Packets Sent", 984 + "CM Packets Bounced", 985 + "CM Packets Created", 986 + "CM Packets Rcvd", 987 + "CM Packets Dropped", 988 + "CM Packets Retrans", 989 + "CM Listens Created", 990 + "CM Listens Destroyed", 991 + "CM Backlog Drops", 992 + "CM Loopbacks", 993 + "CM Nodes Created", 994 + "CM Nodes Destroyed", 995 + "CM Accel Drops", 996 + "CM Resets Received", 997 + "Timer Inits", 998 + "CQ Depth 1", 999 + "CQ Depth 4", 1000 + "CQ Depth 16", 1001 + "CQ Depth 24", 1002 + "CQ Depth 32", 1003 + "CQ Depth 128", 1004 + "CQ Depth 256", 1005 + }; 1006 + 1007 + 1008 + /** 1009 + * nes_netdev_get_rx_csum 1010 + */ 1011 + static u32 nes_netdev_get_rx_csum (struct net_device *netdev) 1012 + { 1013 + struct nes_vnic *nesvnic = netdev_priv(netdev); 1014 + 1015 + if (nesvnic->rx_checksum_disabled) 1016 + return 0; 1017 + else 1018 + return 1; 1019 + } 1020 + 1021 + 1022 + /** 1023 + * nes_netdev_set_rc_csum 1024 + */ 1025 + static int nes_netdev_set_rx_csum(struct net_device *netdev, u32 enable) 1026 + { 1027 + struct nes_vnic *nesvnic = netdev_priv(netdev); 1028 + 1029 + if (enable) 1030 + nesvnic->rx_checksum_disabled = 0; 1031 + else 1032 + nesvnic->rx_checksum_disabled = 1; 1033 + return 0; 1034 + } 1035 + 1036 + 1037 + /** 1038 + * nes_netdev_get_stats_count 1039 + */ 1040 + static int nes_netdev_get_stats_count(struct net_device *netdev) 1041 + { 1042 + return NES_ETHTOOL_STAT_COUNT; 1043 + } 1044 + 1045 + 1046 + /** 1047 + * nes_netdev_get_strings 1048 + */ 1049 + static void nes_netdev_get_strings(struct net_device *netdev, u32 stringset, 1050 + u8 *ethtool_strings) 1051 + { 1052 + if (stringset == ETH_SS_STATS) 1053 + memcpy(ethtool_strings, 1054 + &nes_ethtool_stringset, 1055 + sizeof(nes_ethtool_stringset)); 1056 + } 1057 + 1058 + 1059 + /** 1060 + * nes_netdev_get_ethtool_stats 1061 + */ 1062 + static void nes_netdev_get_ethtool_stats(struct net_device *netdev, 1063 + struct ethtool_stats *target_ethtool_stats, u64 *target_stat_values) 1064 + { 1065 + u64 u64temp; 1066 + struct nes_vnic *nesvnic = netdev_priv(netdev); 1067 + struct nes_device *nesdev = nesvnic->nesdev; 1068 + u32 nic_count; 1069 + u32 u32temp; 1070 + 1071 + target_ethtool_stats->n_stats = NES_ETHTOOL_STAT_COUNT; 1072 + target_stat_values[0] = nesvnic->nesdev->link_status_interrupts; 1073 + target_stat_values[1] = nesvnic->linearized_skbs; 1074 + target_stat_values[2] = nesvnic->tso_requests; 1075 + 1076 + u32temp = nes_read_indexed(nesdev, 1077 + NES_IDX_MAC_TX_PAUSE_FRAMES + (nesvnic->nesdev->mac_index*0x200)); 1078 + nesvnic->nesdev->mac_pause_frames_sent += u32temp; 1079 + target_stat_values[3] = nesvnic->nesdev->mac_pause_frames_sent; 1080 + 1081 + u32temp = nes_read_indexed(nesdev, 1082 + NES_IDX_MAC_RX_PAUSE_FRAMES + (nesvnic->nesdev->mac_index*0x200)); 1083 + nesvnic->nesdev->mac_pause_frames_received += u32temp; 1084 + 1085 + u32temp = nes_read_indexed(nesdev, 1086 + NES_IDX_PORT_RX_DISCARDS + (nesvnic->nesdev->mac_index*0x40)); 1087 + nesvnic->nesdev->port_rx_discards += u32temp; 1088 + nesvnic->netstats.rx_dropped += u32temp; 1089 + 1090 + u32temp = nes_read_indexed(nesdev, 1091 + NES_IDX_PORT_TX_DISCARDS + (nesvnic->nesdev->mac_index*0x40)); 1092 + nesvnic->nesdev->port_tx_discards += u32temp; 1093 + nesvnic->netstats.tx_dropped += u32temp; 1094 + 1095 + for (nic_count = 0; nic_count < NES_MAX_PORT_COUNT; nic_count++) { 1096 + if (nesvnic->qp_nic_index[nic_count] == 0xf) 1097 + break; 1098 + 1099 + u32temp = nes_read_indexed(nesdev, 1100 + NES_IDX_ENDNODE0_NSTAT_RX_DISCARD + 1101 + (nesvnic->qp_nic_index[nic_count]*0x200)); 1102 + nesvnic->netstats.rx_dropped += u32temp; 1103 + nesvnic->endnode_nstat_rx_discard += u32temp; 1104 + 1105 + u64temp = (u64)nes_read_indexed(nesdev, 1106 + NES_IDX_ENDNODE0_NSTAT_RX_OCTETS_LO + 1107 + (nesvnic->qp_nic_index[nic_count]*0x200)); 1108 + u64temp += ((u64)nes_read_indexed(nesdev, 1109 + NES_IDX_ENDNODE0_NSTAT_RX_OCTETS_HI + 1110 + (nesvnic->qp_nic_index[nic_count]*0x200))) << 32; 1111 + 1112 + nesvnic->endnode_nstat_rx_octets += u64temp; 1113 + nesvnic->netstats.rx_bytes += u64temp; 1114 + 1115 + u64temp = (u64)nes_read_indexed(nesdev, 1116 + NES_IDX_ENDNODE0_NSTAT_RX_FRAMES_LO + 1117 + (nesvnic->qp_nic_index[nic_count]*0x200)); 1118 + u64temp += ((u64)nes_read_indexed(nesdev, 1119 + NES_IDX_ENDNODE0_NSTAT_RX_FRAMES_HI + 1120 + (nesvnic->qp_nic_index[nic_count]*0x200))) << 32; 1121 + 1122 + nesvnic->endnode_nstat_rx_frames += u64temp; 1123 + nesvnic->netstats.rx_packets += u64temp; 1124 + 1125 + u64temp = (u64)nes_read_indexed(nesdev, 1126 + NES_IDX_ENDNODE0_NSTAT_TX_OCTETS_LO + 1127 + (nesvnic->qp_nic_index[nic_count]*0x200)); 1128 + u64temp += ((u64)nes_read_indexed(nesdev, 1129 + NES_IDX_ENDNODE0_NSTAT_TX_OCTETS_HI + 1130 + (nesvnic->qp_nic_index[nic_count]*0x200))) << 32; 1131 + 1132 + nesvnic->endnode_nstat_tx_octets += u64temp; 1133 + nesvnic->netstats.tx_bytes += u64temp; 1134 + 1135 + u64temp = (u64)nes_read_indexed(nesdev, 1136 + NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_LO + 1137 + (nesvnic->qp_nic_index[nic_count]*0x200)); 1138 + u64temp += ((u64)nes_read_indexed(nesdev, 1139 + NES_IDX_ENDNODE0_NSTAT_TX_FRAMES_HI + 1140 + (nesvnic->qp_nic_index[nic_count]*0x200))) << 32; 1141 + 1142 + nesvnic->endnode_nstat_tx_frames += u64temp; 1143 + nesvnic->netstats.tx_packets += u64temp; 1144 + 1145 + u32temp = nes_read_indexed(nesdev, 1146 + NES_IDX_IPV4_TCP_REXMITS + (nesvnic->qp_nic_index[nic_count]*0x200)); 1147 + nesvnic->endnode_ipv4_tcp_retransmits += u32temp; 1148 + } 1149 + 1150 + target_stat_values[4] = nesvnic->nesdev->mac_pause_frames_received; 1151 + target_stat_values[5] = nesdev->nesadapter->nic_rx_eth_route_err; 1152 + target_stat_values[6] = nesvnic->tx_sw_dropped; 1153 + target_stat_values[7] = nesvnic->sq_locked; 1154 + target_stat_values[8] = nesvnic->sq_full; 1155 + target_stat_values[9] = nesvnic->segmented_tso_requests; 1156 + target_stat_values[10] = nesvnic->nesdev->mac_rx_symbol_err_frames; 1157 + target_stat_values[11] = nesvnic->nesdev->mac_rx_jabber_frames; 1158 + target_stat_values[12] = nesvnic->nesdev->mac_rx_oversized_frames; 1159 + target_stat_values[13] = nesvnic->nesdev->mac_rx_short_frames; 1160 + target_stat_values[14] = nesvnic->endnode_nstat_rx_discard; 1161 + target_stat_values[15] = nesvnic->endnode_nstat_rx_octets; 1162 + target_stat_values[16] = nesvnic->endnode_nstat_rx_frames; 1163 + target_stat_values[17] = nesvnic->endnode_nstat_tx_octets; 1164 + target_stat_values[18] = nesvnic->endnode_nstat_tx_frames; 1165 + target_stat_values[19] = mh_detected; 1166 + target_stat_values[20] = mh_pauses_sent; 1167 + target_stat_values[21] = nesvnic->endnode_ipv4_tcp_retransmits; 1168 + target_stat_values[22] = atomic_read(&cm_connects); 1169 + target_stat_values[23] = atomic_read(&cm_accepts); 1170 + target_stat_values[24] = atomic_read(&cm_disconnects); 1171 + target_stat_values[25] = atomic_read(&cm_connecteds); 1172 + target_stat_values[26] = atomic_read(&cm_connect_reqs); 1173 + target_stat_values[27] = atomic_read(&cm_rejects); 1174 + target_stat_values[28] = atomic_read(&mod_qp_timouts); 1175 + target_stat_values[29] = atomic_read(&qps_created); 1176 + target_stat_values[30] = atomic_read(&sw_qps_destroyed); 1177 + target_stat_values[31] = atomic_read(&qps_destroyed); 1178 + target_stat_values[32] = atomic_read(&cm_closes); 1179 + target_stat_values[33] = cm_packets_sent; 1180 + target_stat_values[34] = cm_packets_bounced; 1181 + target_stat_values[35] = cm_packets_created; 1182 + target_stat_values[36] = cm_packets_received; 1183 + target_stat_values[37] = cm_packets_dropped; 1184 + target_stat_values[38] = cm_packets_retrans; 1185 + target_stat_values[39] = cm_listens_created; 1186 + target_stat_values[40] = cm_listens_destroyed; 1187 + target_stat_values[41] = cm_backlog_drops; 1188 + target_stat_values[42] = atomic_read(&cm_loopbacks); 1189 + target_stat_values[43] = atomic_read(&cm_nodes_created); 1190 + target_stat_values[44] = atomic_read(&cm_nodes_destroyed); 1191 + target_stat_values[45] = atomic_read(&cm_accel_dropped_pkts); 1192 + target_stat_values[46] = atomic_read(&cm_resets_recvd); 1193 + target_stat_values[47] = int_mod_timer_init; 1194 + target_stat_values[48] = int_mod_cq_depth_1; 1195 + target_stat_values[49] = int_mod_cq_depth_4; 1196 + target_stat_values[50] = int_mod_cq_depth_16; 1197 + target_stat_values[51] = int_mod_cq_depth_24; 1198 + target_stat_values[52] = int_mod_cq_depth_32; 1199 + target_stat_values[53] = int_mod_cq_depth_128; 1200 + target_stat_values[54] = int_mod_cq_depth_256; 1201 + 1202 + } 1203 + 1204 + 1205 + /** 1206 + * nes_netdev_get_drvinfo 1207 + */ 1208 + static void nes_netdev_get_drvinfo(struct net_device *netdev, 1209 + struct ethtool_drvinfo *drvinfo) 1210 + { 1211 + struct nes_vnic *nesvnic = netdev_priv(netdev); 1212 + 1213 + strcpy(drvinfo->driver, DRV_NAME); 1214 + strcpy(drvinfo->bus_info, pci_name(nesvnic->nesdev->pcidev)); 1215 + strcpy(drvinfo->fw_version, "TBD"); 1216 + strcpy(drvinfo->version, DRV_VERSION); 1217 + drvinfo->n_stats = nes_netdev_get_stats_count(netdev); 1218 + drvinfo->testinfo_len = 0; 1219 + drvinfo->eedump_len = 0; 1220 + drvinfo->regdump_len = 0; 1221 + } 1222 + 1223 + 1224 + /** 1225 + * nes_netdev_set_coalesce 1226 + */ 1227 + static int nes_netdev_set_coalesce(struct net_device *netdev, 1228 + struct ethtool_coalesce *et_coalesce) 1229 + { 1230 + struct nes_vnic *nesvnic = netdev_priv(netdev); 1231 + struct nes_device *nesdev = nesvnic->nesdev; 1232 + struct nes_adapter *nesadapter = nesdev->nesadapter; 1233 + struct nes_hw_tune_timer *shared_timer = &nesadapter->tune_timer; 1234 + unsigned long flags; 1235 + 1236 + spin_lock_irqsave(&nesadapter->periodic_timer_lock, flags); 1237 + if (et_coalesce->rx_max_coalesced_frames_low) { 1238 + shared_timer->threshold_low = et_coalesce->rx_max_coalesced_frames_low; 1239 + } 1240 + if (et_coalesce->rx_max_coalesced_frames_irq) { 1241 + shared_timer->threshold_target = et_coalesce->rx_max_coalesced_frames_irq; 1242 + } 1243 + if (et_coalesce->rx_max_coalesced_frames_high) { 1244 + shared_timer->threshold_high = et_coalesce->rx_max_coalesced_frames_high; 1245 + } 1246 + if (et_coalesce->rx_coalesce_usecs_low) { 1247 + shared_timer->timer_in_use_min = et_coalesce->rx_coalesce_usecs_low; 1248 + } 1249 + if (et_coalesce->rx_coalesce_usecs_high) { 1250 + shared_timer->timer_in_use_max = et_coalesce->rx_coalesce_usecs_high; 1251 + } 1252 + spin_unlock_irqrestore(&nesadapter->periodic_timer_lock, flags); 1253 + 1254 + /* using this to drive total interrupt moderation */ 1255 + nesadapter->et_rx_coalesce_usecs_irq = et_coalesce->rx_coalesce_usecs_irq; 1256 + if (et_coalesce->use_adaptive_rx_coalesce) { 1257 + nesadapter->et_use_adaptive_rx_coalesce = 1; 1258 + nesadapter->timer_int_limit = NES_TIMER_INT_LIMIT_DYNAMIC; 1259 + nesadapter->et_rx_coalesce_usecs_irq = 0; 1260 + if (et_coalesce->pkt_rate_low) { 1261 + nesadapter->et_pkt_rate_low = et_coalesce->pkt_rate_low; 1262 + } 1263 + } else { 1264 + nesadapter->et_use_adaptive_rx_coalesce = 0; 1265 + nesadapter->timer_int_limit = NES_TIMER_INT_LIMIT; 1266 + if (nesadapter->et_rx_coalesce_usecs_irq) { 1267 + nes_write32(nesdev->regs+NES_PERIODIC_CONTROL, 1268 + 0x80000000 | ((u32)(nesadapter->et_rx_coalesce_usecs_irq*8))); 1269 + } 1270 + } 1271 + return 0; 1272 + } 1273 + 1274 + 1275 + /** 1276 + * nes_netdev_get_coalesce 1277 + */ 1278 + static int nes_netdev_get_coalesce(struct net_device *netdev, 1279 + struct ethtool_coalesce *et_coalesce) 1280 + { 1281 + struct nes_vnic *nesvnic = netdev_priv(netdev); 1282 + struct nes_device *nesdev = nesvnic->nesdev; 1283 + struct nes_adapter *nesadapter = nesdev->nesadapter; 1284 + struct ethtool_coalesce temp_et_coalesce; 1285 + struct nes_hw_tune_timer *shared_timer = &nesadapter->tune_timer; 1286 + unsigned long flags; 1287 + 1288 + memset(&temp_et_coalesce, 0, sizeof(temp_et_coalesce)); 1289 + temp_et_coalesce.rx_coalesce_usecs_irq = nesadapter->et_rx_coalesce_usecs_irq; 1290 + temp_et_coalesce.use_adaptive_rx_coalesce = nesadapter->et_use_adaptive_rx_coalesce; 1291 + temp_et_coalesce.rate_sample_interval = nesadapter->et_rate_sample_interval; 1292 + temp_et_coalesce.pkt_rate_low = nesadapter->et_pkt_rate_low; 1293 + spin_lock_irqsave(&nesadapter->periodic_timer_lock, flags); 1294 + temp_et_coalesce.rx_max_coalesced_frames_low = shared_timer->threshold_low; 1295 + temp_et_coalesce.rx_max_coalesced_frames_irq = shared_timer->threshold_target; 1296 + temp_et_coalesce.rx_max_coalesced_frames_high = shared_timer->threshold_high; 1297 + temp_et_coalesce.rx_coalesce_usecs_low = shared_timer->timer_in_use_min; 1298 + temp_et_coalesce.rx_coalesce_usecs_high = shared_timer->timer_in_use_max; 1299 + if (nesadapter->et_use_adaptive_rx_coalesce) { 1300 + temp_et_coalesce.rx_coalesce_usecs_irq = shared_timer->timer_in_use; 1301 + } 1302 + spin_unlock_irqrestore(&nesadapter->periodic_timer_lock, flags); 1303 + memcpy(et_coalesce, &temp_et_coalesce, sizeof(*et_coalesce)); 1304 + return 0; 1305 + } 1306 + 1307 + 1308 + /** 1309 + * nes_netdev_get_pauseparam 1310 + */ 1311 + static void nes_netdev_get_pauseparam(struct net_device *netdev, 1312 + struct ethtool_pauseparam *et_pauseparam) 1313 + { 1314 + struct nes_vnic *nesvnic = netdev_priv(netdev); 1315 + 1316 + et_pauseparam->autoneg = 0; 1317 + et_pauseparam->rx_pause = (nesvnic->nesdev->disable_rx_flow_control == 0) ? 1:0; 1318 + et_pauseparam->tx_pause = (nesvnic->nesdev->disable_tx_flow_control == 0) ? 1:0; 1319 + } 1320 + 1321 + 1322 + /** 1323 + * nes_netdev_set_pauseparam 1324 + */ 1325 + static int nes_netdev_set_pauseparam(struct net_device *netdev, 1326 + struct ethtool_pauseparam *et_pauseparam) 1327 + { 1328 + struct nes_vnic *nesvnic = netdev_priv(netdev); 1329 + struct nes_device *nesdev = nesvnic->nesdev; 1330 + u32 u32temp; 1331 + 1332 + if (et_pauseparam->autoneg) { 1333 + /* TODO: should return unsupported */ 1334 + return 0; 1335 + } 1336 + if ((et_pauseparam->tx_pause == 1) && (nesdev->disable_tx_flow_control == 1)) { 1337 + u32temp = nes_read_indexed(nesdev, 1338 + NES_IDX_MAC_TX_CONFIG + (nesdev->mac_index*0x200)); 1339 + u32temp |= NES_IDX_MAC_TX_CONFIG_ENABLE_PAUSE; 1340 + nes_write_indexed(nesdev, 1341 + NES_IDX_MAC_TX_CONFIG_ENABLE_PAUSE + (nesdev->mac_index*0x200), u32temp); 1342 + nesdev->disable_tx_flow_control = 0; 1343 + } else if ((et_pauseparam->tx_pause == 0) && (nesdev->disable_tx_flow_control == 0)) { 1344 + u32temp = nes_read_indexed(nesdev, 1345 + NES_IDX_MAC_TX_CONFIG + (nesdev->mac_index*0x200)); 1346 + u32temp &= ~NES_IDX_MAC_TX_CONFIG_ENABLE_PAUSE; 1347 + nes_write_indexed(nesdev, 1348 + NES_IDX_MAC_TX_CONFIG_ENABLE_PAUSE + (nesdev->mac_index*0x200), u32temp); 1349 + nesdev->disable_tx_flow_control = 1; 1350 + } 1351 + if ((et_pauseparam->rx_pause == 1) && (nesdev->disable_rx_flow_control == 1)) { 1352 + u32temp = nes_read_indexed(nesdev, 1353 + NES_IDX_MPP_DEBUG + (nesdev->mac_index*0x40)); 1354 + u32temp &= ~NES_IDX_MPP_DEBUG_PORT_DISABLE_PAUSE; 1355 + nes_write_indexed(nesdev, 1356 + NES_IDX_MPP_DEBUG + (nesdev->mac_index*0x40), u32temp); 1357 + nesdev->disable_rx_flow_control = 0; 1358 + } else if ((et_pauseparam->rx_pause == 0) && (nesdev->disable_rx_flow_control == 0)) { 1359 + u32temp = nes_read_indexed(nesdev, 1360 + NES_IDX_MPP_DEBUG + (nesdev->mac_index*0x40)); 1361 + u32temp |= NES_IDX_MPP_DEBUG_PORT_DISABLE_PAUSE; 1362 + nes_write_indexed(nesdev, 1363 + NES_IDX_MPP_DEBUG + (nesdev->mac_index*0x40), u32temp); 1364 + nesdev->disable_rx_flow_control = 1; 1365 + } 1366 + 1367 + return 0; 1368 + } 1369 + 1370 + 1371 + /** 1372 + * nes_netdev_get_settings 1373 + */ 1374 + static int nes_netdev_get_settings(struct net_device *netdev, struct ethtool_cmd *et_cmd) 1375 + { 1376 + struct nes_vnic *nesvnic = netdev_priv(netdev); 1377 + struct nes_device *nesdev = nesvnic->nesdev; 1378 + struct nes_adapter *nesadapter = nesdev->nesadapter; 1379 + u16 phy_data; 1380 + 1381 + et_cmd->duplex = DUPLEX_FULL; 1382 + et_cmd->port = PORT_MII; 1383 + if (nesadapter->OneG_Mode) { 1384 + et_cmd->supported = SUPPORTED_1000baseT_Full|SUPPORTED_Autoneg; 1385 + et_cmd->advertising = ADVERTISED_1000baseT_Full|ADVERTISED_Autoneg; 1386 + et_cmd->speed = SPEED_1000; 1387 + nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], 1388 + &phy_data); 1389 + if (phy_data&0x1000) { 1390 + et_cmd->autoneg = AUTONEG_ENABLE; 1391 + } else { 1392 + et_cmd->autoneg = AUTONEG_DISABLE; 1393 + } 1394 + et_cmd->transceiver = XCVR_EXTERNAL; 1395 + et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index]; 1396 + } else { 1397 + if (nesadapter->phy_type[nesvnic->logical_port] == NES_PHY_TYPE_IRIS) { 1398 + et_cmd->transceiver = XCVR_EXTERNAL; 1399 + et_cmd->port = PORT_FIBRE; 1400 + et_cmd->supported = SUPPORTED_FIBRE; 1401 + et_cmd->advertising = ADVERTISED_FIBRE; 1402 + et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index]; 1403 + } else { 1404 + et_cmd->transceiver = XCVR_INTERNAL; 1405 + et_cmd->supported = SUPPORTED_10000baseT_Full; 1406 + et_cmd->advertising = ADVERTISED_10000baseT_Full; 1407 + et_cmd->phy_address = nesdev->mac_index; 1408 + } 1409 + et_cmd->speed = SPEED_10000; 1410 + et_cmd->autoneg = AUTONEG_DISABLE; 1411 + } 1412 + et_cmd->maxtxpkt = 511; 1413 + et_cmd->maxrxpkt = 511; 1414 + return 0; 1415 + } 1416 + 1417 + 1418 + /** 1419 + * nes_netdev_set_settings 1420 + */ 1421 + static int nes_netdev_set_settings(struct net_device *netdev, struct ethtool_cmd *et_cmd) 1422 + { 1423 + struct nes_vnic *nesvnic = netdev_priv(netdev); 1424 + struct nes_device *nesdev = nesvnic->nesdev; 1425 + struct nes_adapter *nesadapter = nesdev->nesadapter; 1426 + u16 phy_data; 1427 + 1428 + if (nesadapter->OneG_Mode) { 1429 + nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], 1430 + &phy_data); 1431 + if (et_cmd->autoneg) { 1432 + /* Turn on Full duplex, Autoneg, and restart autonegotiation */ 1433 + phy_data |= 0x1300; 1434 + } else { 1435 + // Turn off autoneg 1436 + phy_data &= ~0x1000; 1437 + } 1438 + nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], 1439 + phy_data); 1440 + } 1441 + 1442 + return 0; 1443 + } 1444 + 1445 + 1446 + static struct ethtool_ops nes_ethtool_ops = { 1447 + .get_link = ethtool_op_get_link, 1448 + .get_settings = nes_netdev_get_settings, 1449 + .set_settings = nes_netdev_set_settings, 1450 + .get_tx_csum = ethtool_op_get_tx_csum, 1451 + .get_rx_csum = nes_netdev_get_rx_csum, 1452 + .get_sg = ethtool_op_get_sg, 1453 + .get_strings = nes_netdev_get_strings, 1454 + .get_stats_count = nes_netdev_get_stats_count, 1455 + .get_ethtool_stats = nes_netdev_get_ethtool_stats, 1456 + .get_drvinfo = nes_netdev_get_drvinfo, 1457 + .get_coalesce = nes_netdev_get_coalesce, 1458 + .set_coalesce = nes_netdev_set_coalesce, 1459 + .get_pauseparam = nes_netdev_get_pauseparam, 1460 + .set_pauseparam = nes_netdev_set_pauseparam, 1461 + .set_tx_csum = ethtool_op_set_tx_csum, 1462 + .set_rx_csum = nes_netdev_set_rx_csum, 1463 + .set_sg = ethtool_op_set_sg, 1464 + .get_tso = ethtool_op_get_tso, 1465 + .set_tso = ethtool_op_set_tso, 1466 + }; 1467 + 1468 + 1469 + static void nes_netdev_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) 1470 + { 1471 + struct nes_vnic *nesvnic = netdev_priv(netdev); 1472 + struct nes_device *nesdev = nesvnic->nesdev; 1473 + u32 u32temp; 1474 + 1475 + nesvnic->vlan_grp = grp; 1476 + 1477 + /* Enable/Disable VLAN Stripping */ 1478 + u32temp = nes_read_indexed(nesdev, NES_IDX_PCIX_DIAG); 1479 + if (grp) 1480 + u32temp &= 0xfdffffff; 1481 + else 1482 + u32temp |= 0x02000000; 1483 + 1484 + nes_write_indexed(nesdev, NES_IDX_PCIX_DIAG, u32temp); 1485 + } 1486 + 1487 + 1488 + /** 1489 + * nes_netdev_init - initialize network device 1490 + */ 1491 + struct net_device *nes_netdev_init(struct nes_device *nesdev, 1492 + void __iomem *mmio_addr) 1493 + { 1494 + u64 u64temp; 1495 + struct nes_vnic *nesvnic = NULL; 1496 + struct net_device *netdev; 1497 + struct nic_qp_map *curr_qp_map; 1498 + u32 u32temp; 1499 + u16 phy_data; 1500 + u16 temp_phy_data; 1501 + 1502 + netdev = alloc_etherdev(sizeof(struct nes_vnic)); 1503 + if (!netdev) { 1504 + printk(KERN_ERR PFX "nesvnic etherdev alloc failed"); 1505 + return NULL; 1506 + } 1507 + 1508 + nes_debug(NES_DBG_INIT, "netdev = %p, %s\n", netdev, netdev->name); 1509 + 1510 + SET_NETDEV_DEV(netdev, &nesdev->pcidev->dev); 1511 + 1512 + nesvnic = netdev_priv(netdev); 1513 + memset(nesvnic, 0, sizeof(*nesvnic)); 1514 + 1515 + netdev->open = nes_netdev_open; 1516 + netdev->stop = nes_netdev_stop; 1517 + netdev->hard_start_xmit = nes_netdev_start_xmit; 1518 + netdev->get_stats = nes_netdev_get_stats; 1519 + netdev->tx_timeout = nes_netdev_tx_timeout; 1520 + netdev->set_mac_address = nes_netdev_set_mac_address; 1521 + netdev->set_multicast_list = nes_netdev_set_multicast_list; 1522 + netdev->change_mtu = nes_netdev_change_mtu; 1523 + netdev->watchdog_timeo = NES_TX_TIMEOUT; 1524 + netdev->irq = nesdev->pcidev->irq; 1525 + netdev->mtu = ETH_DATA_LEN; 1526 + netdev->hard_header_len = ETH_HLEN; 1527 + netdev->addr_len = ETH_ALEN; 1528 + netdev->type = ARPHRD_ETHER; 1529 + netdev->features = NETIF_F_HIGHDMA; 1530 + netdev->ethtool_ops = &nes_ethtool_ops; 1531 + netif_napi_add(netdev, &nesvnic->napi, nes_netdev_poll, 128); 1532 + nes_debug(NES_DBG_INIT, "Enabling VLAN Insert/Delete.\n"); 1533 + netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; 1534 + netdev->vlan_rx_register = nes_netdev_vlan_rx_register; 1535 + netdev->features |= NETIF_F_LLTX; 1536 + 1537 + /* Fill in the port structure */ 1538 + nesvnic->netdev = netdev; 1539 + nesvnic->nesdev = nesdev; 1540 + nesvnic->msg_enable = netif_msg_init(debug, default_msg); 1541 + nesvnic->netdev_index = nesdev->netdev_count; 1542 + nesvnic->perfect_filter_index = nesdev->nesadapter->netdev_count; 1543 + nesvnic->max_frame_size = netdev->mtu+netdev->hard_header_len; 1544 + 1545 + curr_qp_map = nic_qp_mapping_per_function[PCI_FUNC(nesdev->pcidev->devfn)]; 1546 + nesvnic->nic.qp_id = curr_qp_map[nesdev->netdev_count].qpid; 1547 + nesvnic->nic_index = curr_qp_map[nesdev->netdev_count].nic_index; 1548 + nesvnic->logical_port = curr_qp_map[nesdev->netdev_count].logical_port; 1549 + 1550 + /* Setup the burned in MAC address */ 1551 + u64temp = (u64)nesdev->nesadapter->mac_addr_low; 1552 + u64temp += ((u64)nesdev->nesadapter->mac_addr_high) << 32; 1553 + u64temp += nesvnic->nic_index; 1554 + netdev->dev_addr[0] = (u8)(u64temp>>40); 1555 + netdev->dev_addr[1] = (u8)(u64temp>>32); 1556 + netdev->dev_addr[2] = (u8)(u64temp>>24); 1557 + netdev->dev_addr[3] = (u8)(u64temp>>16); 1558 + netdev->dev_addr[4] = (u8)(u64temp>>8); 1559 + netdev->dev_addr[5] = (u8)u64temp; 1560 + memcpy(netdev->perm_addr, netdev->dev_addr, 6); 1561 + 1562 + if ((nesvnic->logical_port < 2) || (nesdev->nesadapter->hw_rev != NE020_REV)) { 1563 + netdev->features |= NETIF_F_TSO | NETIF_F_SG | NETIF_F_IP_CSUM; 1564 + netdev->features |= NETIF_F_GSO | NETIF_F_TSO | NETIF_F_SG | NETIF_F_IP_CSUM; 1565 + } else { 1566 + netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; 1567 + } 1568 + 1569 + nes_debug(NES_DBG_INIT, "nesvnic = %p, reported features = 0x%lX, QPid = %d," 1570 + " nic_index = %d, logical_port = %d, mac_index = %d.\n", 1571 + nesvnic, (unsigned long)netdev->features, nesvnic->nic.qp_id, 1572 + nesvnic->nic_index, nesvnic->logical_port, nesdev->mac_index); 1573 + 1574 + if (nesvnic->nesdev->nesadapter->port_count == 1) { 1575 + nesvnic->qp_nic_index[0] = nesvnic->nic_index; 1576 + nesvnic->qp_nic_index[1] = nesvnic->nic_index + 1; 1577 + if (nes_drv_opt & NES_DRV_OPT_DUAL_LOGICAL_PORT) { 1578 + nesvnic->qp_nic_index[2] = 0xf; 1579 + nesvnic->qp_nic_index[3] = 0xf; 1580 + } else { 1581 + nesvnic->qp_nic_index[2] = nesvnic->nic_index + 2; 1582 + nesvnic->qp_nic_index[3] = nesvnic->nic_index + 3; 1583 + } 1584 + } else { 1585 + if (nesvnic->nesdev->nesadapter->port_count == 2) { 1586 + nesvnic->qp_nic_index[0] = nesvnic->nic_index; 1587 + nesvnic->qp_nic_index[1] = nesvnic->nic_index + 2; 1588 + nesvnic->qp_nic_index[2] = 0xf; 1589 + nesvnic->qp_nic_index[3] = 0xf; 1590 + } else { 1591 + nesvnic->qp_nic_index[0] = nesvnic->nic_index; 1592 + nesvnic->qp_nic_index[1] = 0xf; 1593 + nesvnic->qp_nic_index[2] = 0xf; 1594 + nesvnic->qp_nic_index[3] = 0xf; 1595 + } 1596 + } 1597 + nesvnic->next_qp_nic_index = 0; 1598 + 1599 + if (nesdev->netdev_count == 0) { 1600 + nesvnic->rdma_enabled = 1; 1601 + } else { 1602 + nesvnic->rdma_enabled = 0; 1603 + } 1604 + nesvnic->nic_cq.cq_number = nesvnic->nic.qp_id; 1605 + spin_lock_init(&nesvnic->tx_lock); 1606 + nesdev->netdev[nesdev->netdev_count] = netdev; 1607 + 1608 + nes_debug(NES_DBG_INIT, "Adding nesvnic (%p) to the adapters nesvnic_list for MAC%d.\n", 1609 + nesvnic, nesdev->mac_index); 1610 + list_add_tail(&nesvnic->list, &nesdev->nesadapter->nesvnic_list[nesdev->mac_index]); 1611 + 1612 + if ((nesdev->netdev_count == 0) && 1613 + (PCI_FUNC(nesdev->pcidev->devfn) == nesdev->mac_index)) { 1614 + nes_debug(NES_DBG_INIT, "Setting up PHY interrupt mask. Using register index 0x%04X\n", 1615 + NES_IDX_PHY_PCS_CONTROL_STATUS0+(0x200*(nesvnic->logical_port&1))); 1616 + u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + 1617 + (0x200*(nesvnic->logical_port&1))); 1618 + u32temp |= 0x00200000; 1619 + nes_write_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + 1620 + (0x200*(nesvnic->logical_port&1)), u32temp); 1621 + u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + 1622 + (0x200*(nesvnic->logical_port&1)) ); 1623 + if ((u32temp&0x0f1f0000) == 0x0f0f0000) { 1624 + if (nesdev->nesadapter->phy_type[nesvnic->logical_port] == NES_PHY_TYPE_IRIS) { 1625 + nes_init_phy(nesdev); 1626 + nes_read_10G_phy_reg(nesdev, 1, 1627 + nesdev->nesadapter->phy_index[nesvnic->logical_port]); 1628 + temp_phy_data = (u16)nes_read_indexed(nesdev, 1629 + NES_IDX_MAC_MDIO_CONTROL); 1630 + u32temp = 20; 1631 + do { 1632 + nes_read_10G_phy_reg(nesdev, 1, 1633 + nesdev->nesadapter->phy_index[nesvnic->logical_port]); 1634 + phy_data = (u16)nes_read_indexed(nesdev, 1635 + NES_IDX_MAC_MDIO_CONTROL); 1636 + if ((phy_data == temp_phy_data) || (!(--u32temp))) 1637 + break; 1638 + temp_phy_data = phy_data; 1639 + } while (1); 1640 + if (phy_data & 4) { 1641 + nes_debug(NES_DBG_INIT, "The Link is UP!!.\n"); 1642 + nesvnic->linkup = 1; 1643 + } else { 1644 + nes_debug(NES_DBG_INIT, "The Link is DOWN!!.\n"); 1645 + } 1646 + } else { 1647 + nes_debug(NES_DBG_INIT, "The Link is UP!!.\n"); 1648 + nesvnic->linkup = 1; 1649 + } 1650 + } 1651 + nes_debug(NES_DBG_INIT, "Setting up MAC interrupt mask.\n"); 1652 + /* clear the MAC interrupt status, assumes direct logical to physical mapping */ 1653 + u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS+(0x200*nesvnic->logical_port)); 1654 + nes_debug(NES_DBG_INIT, "Phy interrupt status = 0x%X.\n", u32temp); 1655 + nes_write_indexed(nesdev, NES_IDX_MAC_INT_STATUS+(0x200*nesvnic->logical_port), u32temp); 1656 + 1657 + if (nesdev->nesadapter->phy_type[nesvnic->logical_port] != NES_PHY_TYPE_IRIS) 1658 + nes_init_phy(nesdev); 1659 + 1660 + nes_write_indexed(nesdev, NES_IDX_MAC_INT_MASK+(0x200*nesvnic->logical_port), 1661 + ~(NES_MAC_INT_LINK_STAT_CHG | NES_MAC_INT_XGMII_EXT | 1662 + NES_MAC_INT_TX_UNDERFLOW | NES_MAC_INT_TX_ERROR)); 1663 + } 1664 + 1665 + return netdev; 1666 + } 1667 + 1668 + 1669 + /** 1670 + * nes_netdev_destroy - destroy network device structure 1671 + */ 1672 + void nes_netdev_destroy(struct net_device *netdev) 1673 + { 1674 + struct nes_vnic *nesvnic = netdev_priv(netdev); 1675 + 1676 + /* make sure 'stop' method is called by Linux stack */ 1677 + /* nes_netdev_stop(netdev); */ 1678 + 1679 + list_del(&nesvnic->list); 1680 + 1681 + if (nesvnic->of_device_registered) { 1682 + nes_destroy_ofa_device(nesvnic->nesibdev); 1683 + } 1684 + 1685 + free_netdev(netdev); 1686 + } 1687 + 1688 + 1689 + /** 1690 + * nes_nic_cm_xmit -- CM calls this to send out pkts 1691 + */ 1692 + int nes_nic_cm_xmit(struct sk_buff *skb, struct net_device *netdev) 1693 + { 1694 + int ret; 1695 + 1696 + skb->dev = netdev; 1697 + ret = dev_queue_xmit(skb); 1698 + if (ret) { 1699 + nes_debug(NES_DBG_CM, "Bad return code from dev_queue_xmit %d\n", ret); 1700 + } 1701 + 1702 + return ret; 1703 + }
+112
drivers/infiniband/hw/nes/nes_user.h
···
··· 1 + /* 2 + * Copyright (c) 2006 - 2008 NetEffect. All rights reserved. 3 + * Copyright (c) 2005 Topspin Communications. All rights reserved. 4 + * Copyright (c) 2005 Cisco Systems. All rights reserved. 5 + * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. 6 + * 7 + * This software is available to you under a choice of one of two 8 + * licenses. You may choose to be licensed under the terms of the GNU 9 + * General Public License (GPL) Version 2, available from the file 10 + * COPYING in the main directory of this source tree, or the 11 + * OpenIB.org BSD license below: 12 + * 13 + * Redistribution and use in source and binary forms, with or 14 + * without modification, are permitted provided that the following 15 + * conditions are met: 16 + * 17 + * - Redistributions of source code must retain the above 18 + * copyright notice, this list of conditions and the following 19 + * disclaimer. 20 + * 21 + * - Redistributions in binary form must reproduce the above 22 + * copyright notice, this list of conditions and the following 23 + * disclaimer in the documentation and/or other materials 24 + * provided with the distribution. 25 + * 26 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 27 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 28 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 29 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 30 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 31 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 32 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 33 + * SOFTWARE. 34 + * 35 + */ 36 + 37 + #ifndef NES_USER_H 38 + #define NES_USER_H 39 + 40 + #include <linux/types.h> 41 + 42 + #define NES_ABI_USERSPACE_VER 1 43 + #define NES_ABI_KERNEL_VER 1 44 + 45 + /* 46 + * Make sure that all structs defined in this file remain laid out so 47 + * that they pack the same way on 32-bit and 64-bit architectures (to 48 + * avoid incompatibility between 32-bit userspace and 64-bit kernels). 49 + * In particular do not use pointer types -- pass pointers in __u64 50 + * instead. 51 + */ 52 + 53 + struct nes_alloc_ucontext_req { 54 + __u32 reserved32; 55 + __u8 userspace_ver; 56 + __u8 reserved8[3]; 57 + }; 58 + 59 + struct nes_alloc_ucontext_resp { 60 + __u32 max_pds; /* maximum pds allowed for this user process */ 61 + __u32 max_qps; /* maximum qps allowed for this user process */ 62 + __u32 wq_size; /* size of the WQs (sq+rq) allocated to the mmaped area */ 63 + __u8 virtwq; /* flag to indicate if virtual WQ are to be used or not */ 64 + __u8 kernel_ver; 65 + __u8 reserved[2]; 66 + }; 67 + 68 + struct nes_alloc_pd_resp { 69 + __u32 pd_id; 70 + __u32 mmap_db_index; 71 + }; 72 + 73 + struct nes_create_cq_req { 74 + __u64 user_cq_buffer; 75 + __u32 mcrqf; 76 + __u8 reserved[4]; 77 + }; 78 + 79 + struct nes_create_qp_req { 80 + __u64 user_wqe_buffers; 81 + }; 82 + 83 + enum iwnes_memreg_type { 84 + IWNES_MEMREG_TYPE_MEM = 0x0000, 85 + IWNES_MEMREG_TYPE_QP = 0x0001, 86 + IWNES_MEMREG_TYPE_CQ = 0x0002, 87 + IWNES_MEMREG_TYPE_MW = 0x0003, 88 + IWNES_MEMREG_TYPE_FMR = 0x0004, 89 + }; 90 + 91 + struct nes_mem_reg_req { 92 + __u32 reg_type; /* indicates if id is memory, QP or CQ */ 93 + __u32 reserved; 94 + }; 95 + 96 + struct nes_create_cq_resp { 97 + __u32 cq_id; 98 + __u32 cq_size; 99 + __u32 mmap_db_index; 100 + __u32 reserved; 101 + }; 102 + 103 + struct nes_create_qp_resp { 104 + __u32 qp_id; 105 + __u32 actual_sq_size; 106 + __u32 actual_rq_size; 107 + __u32 mmap_sq_db_index; 108 + __u32 mmap_rq_db_index; 109 + __u32 nes_drv_opt; 110 + }; 111 + 112 + #endif /* NES_USER_H */
+917
drivers/infiniband/hw/nes/nes_utils.c
···
··· 1 + /* 2 + * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved. 3 + * 4 + * This software is available to you under a choice of one of two 5 + * licenses. You may choose to be licensed under the terms of the GNU 6 + * General Public License (GPL) Version 2, available from the file 7 + * COPYING in the main directory of this source tree, or the 8 + * OpenIB.org BSD license below: 9 + * 10 + * Redistribution and use in source and binary forms, with or 11 + * without modification, are permitted provided that the following 12 + * conditions are met: 13 + * 14 + * - Redistributions of source code must retain the above 15 + * copyright notice, this list of conditions and the following 16 + * disclaimer. 17 + * 18 + * - Redistributions in binary form must reproduce the above 19 + * copyright notice, this list of conditions and the following 20 + * disclaimer in the documentation and/or other materials 21 + * provided with the distribution. 22 + * 23 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 + * SOFTWARE. 31 + * 32 + */ 33 + 34 + #include <linux/module.h> 35 + #include <linux/moduleparam.h> 36 + #include <linux/netdevice.h> 37 + #include <linux/etherdevice.h> 38 + #include <linux/ethtool.h> 39 + #include <linux/mii.h> 40 + #include <linux/if_vlan.h> 41 + #include <linux/crc32.h> 42 + #include <linux/in.h> 43 + #include <linux/ip.h> 44 + #include <linux/tcp.h> 45 + #include <linux/init.h> 46 + 47 + #include <asm/io.h> 48 + #include <asm/irq.h> 49 + #include <asm/byteorder.h> 50 + 51 + #include "nes.h" 52 + 53 + 54 + 55 + static u16 nes_read16_eeprom(void __iomem *addr, u16 offset); 56 + 57 + u32 mh_detected; 58 + u32 mh_pauses_sent; 59 + 60 + /** 61 + * nes_read_eeprom_values - 62 + */ 63 + int nes_read_eeprom_values(struct nes_device *nesdev, struct nes_adapter *nesadapter) 64 + { 65 + u32 mac_addr_low; 66 + u16 mac_addr_high; 67 + u16 eeprom_data; 68 + u16 eeprom_offset; 69 + u16 next_section_address; 70 + u16 sw_section_ver; 71 + u8 major_ver = 0; 72 + u8 minor_ver = 0; 73 + 74 + /* TODO: deal with EEPROM endian issues */ 75 + if (nesadapter->firmware_eeprom_offset == 0) { 76 + /* Read the EEPROM Parameters */ 77 + eeprom_data = nes_read16_eeprom(nesdev->regs, 0); 78 + nes_debug(NES_DBG_HW, "EEPROM Offset 0 = 0x%04X\n", eeprom_data); 79 + eeprom_offset = 2 + (((eeprom_data & 0x007f) << 3) << 80 + ((eeprom_data & 0x0080) >> 7)); 81 + nes_debug(NES_DBG_HW, "Firmware Offset = 0x%04X\n", eeprom_offset); 82 + nesadapter->firmware_eeprom_offset = eeprom_offset; 83 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset + 4); 84 + if (eeprom_data != 0x5746) { 85 + nes_debug(NES_DBG_HW, "Not a valid Firmware Image = 0x%04X\n", eeprom_data); 86 + return -1; 87 + } 88 + 89 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset + 2); 90 + nes_debug(NES_DBG_HW, "EEPROM Offset %u = 0x%04X\n", 91 + eeprom_offset + 2, eeprom_data); 92 + eeprom_offset += ((eeprom_data & 0x00ff) << 3) << ((eeprom_data & 0x0100) >> 8); 93 + nes_debug(NES_DBG_HW, "Software Offset = 0x%04X\n", eeprom_offset); 94 + nesadapter->software_eeprom_offset = eeprom_offset; 95 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset + 4); 96 + if (eeprom_data != 0x5753) { 97 + printk("Not a valid Software Image = 0x%04X\n", eeprom_data); 98 + return -1; 99 + } 100 + sw_section_ver = nes_read16_eeprom(nesdev->regs, nesadapter->software_eeprom_offset + 6); 101 + nes_debug(NES_DBG_HW, "Software section version number = 0x%04X\n", 102 + sw_section_ver); 103 + 104 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset + 2); 105 + nes_debug(NES_DBG_HW, "EEPROM Offset %u (next section) = 0x%04X\n", 106 + eeprom_offset + 2, eeprom_data); 107 + next_section_address = eeprom_offset + (((eeprom_data & 0x00ff) << 3) << 108 + ((eeprom_data & 0x0100) >> 8)); 109 + eeprom_data = nes_read16_eeprom(nesdev->regs, next_section_address + 4); 110 + if (eeprom_data != 0x414d) { 111 + nes_debug(NES_DBG_HW, "EEPROM Changed offset should be 0x414d but was 0x%04X\n", 112 + eeprom_data); 113 + goto no_fw_rev; 114 + } 115 + eeprom_offset = next_section_address; 116 + 117 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset + 2); 118 + nes_debug(NES_DBG_HW, "EEPROM Offset %u (next section) = 0x%04X\n", 119 + eeprom_offset + 2, eeprom_data); 120 + next_section_address = eeprom_offset + (((eeprom_data & 0x00ff) << 3) << 121 + ((eeprom_data & 0x0100) >> 8)); 122 + eeprom_data = nes_read16_eeprom(nesdev->regs, next_section_address + 4); 123 + if (eeprom_data != 0x4f52) { 124 + nes_debug(NES_DBG_HW, "EEPROM Changed offset should be 0x4f52 but was 0x%04X\n", 125 + eeprom_data); 126 + goto no_fw_rev; 127 + } 128 + eeprom_offset = next_section_address; 129 + 130 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset + 2); 131 + nes_debug(NES_DBG_HW, "EEPROM Offset %u (next section) = 0x%04X\n", 132 + eeprom_offset + 2, eeprom_data); 133 + next_section_address = eeprom_offset + ((eeprom_data & 0x00ff) << 3); 134 + eeprom_data = nes_read16_eeprom(nesdev->regs, next_section_address + 4); 135 + if (eeprom_data != 0x5746) { 136 + nes_debug(NES_DBG_HW, "EEPROM Changed offset should be 0x5746 but was 0x%04X\n", 137 + eeprom_data); 138 + goto no_fw_rev; 139 + } 140 + eeprom_offset = next_section_address; 141 + 142 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset + 2); 143 + nes_debug(NES_DBG_HW, "EEPROM Offset %u (next section) = 0x%04X\n", 144 + eeprom_offset + 2, eeprom_data); 145 + next_section_address = eeprom_offset + ((eeprom_data & 0x00ff) << 3); 146 + eeprom_data = nes_read16_eeprom(nesdev->regs, next_section_address + 4); 147 + if (eeprom_data != 0x5753) { 148 + nes_debug(NES_DBG_HW, "EEPROM Changed offset should be 0x5753 but was 0x%04X\n", 149 + eeprom_data); 150 + goto no_fw_rev; 151 + } 152 + eeprom_offset = next_section_address; 153 + 154 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset + 2); 155 + nes_debug(NES_DBG_HW, "EEPROM Offset %u (next section) = 0x%04X\n", 156 + eeprom_offset + 2, eeprom_data); 157 + next_section_address = eeprom_offset + ((eeprom_data & 0x00ff) << 3); 158 + eeprom_data = nes_read16_eeprom(nesdev->regs, next_section_address + 4); 159 + if (eeprom_data != 0x414d) { 160 + nes_debug(NES_DBG_HW, "EEPROM Changed offset should be 0x414d but was 0x%04X\n", 161 + eeprom_data); 162 + goto no_fw_rev; 163 + } 164 + eeprom_offset = next_section_address; 165 + 166 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset + 2); 167 + nes_debug(NES_DBG_HW, "EEPROM Offset %u (next section) = 0x%04X\n", 168 + eeprom_offset + 2, eeprom_data); 169 + next_section_address = eeprom_offset + ((eeprom_data & 0x00ff) << 3); 170 + eeprom_data = nes_read16_eeprom(nesdev->regs, next_section_address + 4); 171 + if (eeprom_data != 0x464e) { 172 + nes_debug(NES_DBG_HW, "EEPROM Changed offset should be 0x464e but was 0x%04X\n", 173 + eeprom_data); 174 + goto no_fw_rev; 175 + } 176 + eeprom_data = nes_read16_eeprom(nesdev->regs, next_section_address + 8); 177 + printk(PFX "Firmware version %u.%u\n", (u8)(eeprom_data>>8), (u8)eeprom_data); 178 + major_ver = (u8)(eeprom_data >> 8); 179 + minor_ver = (u8)(eeprom_data); 180 + 181 + if (nes_drv_opt & NES_DRV_OPT_DISABLE_VIRT_WQ) { 182 + nes_debug(NES_DBG_HW, "Virtual WQs have been disabled\n"); 183 + } else if (((major_ver == 2) && (minor_ver > 21)) || ((major_ver > 2) && (major_ver != 255))) { 184 + nesadapter->virtwq = 1; 185 + } 186 + nesadapter->firmware_version = (((u32)(u8)(eeprom_data>>8)) << 16) + 187 + (u32)((u8)eeprom_data); 188 + 189 + no_fw_rev: 190 + /* eeprom is valid */ 191 + eeprom_offset = nesadapter->software_eeprom_offset; 192 + eeprom_offset += 8; 193 + nesadapter->netdev_max = (u8)nes_read16_eeprom(nesdev->regs, eeprom_offset); 194 + eeprom_offset += 2; 195 + mac_addr_high = nes_read16_eeprom(nesdev->regs, eeprom_offset); 196 + eeprom_offset += 2; 197 + mac_addr_low = (u32)nes_read16_eeprom(nesdev->regs, eeprom_offset); 198 + eeprom_offset += 2; 199 + mac_addr_low <<= 16; 200 + mac_addr_low += (u32)nes_read16_eeprom(nesdev->regs, eeprom_offset); 201 + nes_debug(NES_DBG_HW, "Base MAC Address = 0x%04X%08X\n", 202 + mac_addr_high, mac_addr_low); 203 + nes_debug(NES_DBG_HW, "MAC Address count = %u\n", nesadapter->netdev_max); 204 + 205 + nesadapter->mac_addr_low = mac_addr_low; 206 + nesadapter->mac_addr_high = mac_addr_high; 207 + 208 + /* Read the Phy Type array */ 209 + eeprom_offset += 10; 210 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset); 211 + nesadapter->phy_type[0] = (u8)(eeprom_data >> 8); 212 + nesadapter->phy_type[1] = (u8)eeprom_data; 213 + 214 + /* Read the port array */ 215 + eeprom_offset += 2; 216 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset); 217 + nesadapter->phy_type[2] = (u8)(eeprom_data >> 8); 218 + nesadapter->phy_type[3] = (u8)eeprom_data; 219 + /* port_count is set by soft reset reg */ 220 + nes_debug(NES_DBG_HW, "port_count = %u, port 0 -> %u, port 1 -> %u," 221 + " port 2 -> %u, port 3 -> %u\n", 222 + nesadapter->port_count, 223 + nesadapter->phy_type[0], nesadapter->phy_type[1], 224 + nesadapter->phy_type[2], nesadapter->phy_type[3]); 225 + 226 + /* Read PD config array */ 227 + eeprom_offset += 10; 228 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset); 229 + nesadapter->pd_config_size[0] = eeprom_data; 230 + eeprom_offset += 2; 231 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset); 232 + nesadapter->pd_config_base[0] = eeprom_data; 233 + nes_debug(NES_DBG_HW, "PD0 config, size=0x%04x, base=0x%04x\n", 234 + nesadapter->pd_config_size[0], nesadapter->pd_config_base[0]); 235 + 236 + eeprom_offset += 2; 237 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset); 238 + nesadapter->pd_config_size[1] = eeprom_data; 239 + eeprom_offset += 2; 240 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset); 241 + nesadapter->pd_config_base[1] = eeprom_data; 242 + nes_debug(NES_DBG_HW, "PD1 config, size=0x%04x, base=0x%04x\n", 243 + nesadapter->pd_config_size[1], nesadapter->pd_config_base[1]); 244 + 245 + eeprom_offset += 2; 246 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset); 247 + nesadapter->pd_config_size[2] = eeprom_data; 248 + eeprom_offset += 2; 249 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset); 250 + nesadapter->pd_config_base[2] = eeprom_data; 251 + nes_debug(NES_DBG_HW, "PD2 config, size=0x%04x, base=0x%04x\n", 252 + nesadapter->pd_config_size[2], nesadapter->pd_config_base[2]); 253 + 254 + eeprom_offset += 2; 255 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset); 256 + nesadapter->pd_config_size[3] = eeprom_data; 257 + eeprom_offset += 2; 258 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset); 259 + nesadapter->pd_config_base[3] = eeprom_data; 260 + nes_debug(NES_DBG_HW, "PD3 config, size=0x%04x, base=0x%04x\n", 261 + nesadapter->pd_config_size[3], nesadapter->pd_config_base[3]); 262 + 263 + /* Read Rx Pool Size */ 264 + eeprom_offset += 22; /* 46 */ 265 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset); 266 + eeprom_offset += 2; 267 + nesadapter->rx_pool_size = (((u32)eeprom_data) << 16) + 268 + nes_read16_eeprom(nesdev->regs, eeprom_offset); 269 + nes_debug(NES_DBG_HW, "rx_pool_size = 0x%08X\n", nesadapter->rx_pool_size); 270 + 271 + eeprom_offset += 2; 272 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset); 273 + eeprom_offset += 2; 274 + nesadapter->tx_pool_size = (((u32)eeprom_data) << 16) + 275 + nes_read16_eeprom(nesdev->regs, eeprom_offset); 276 + nes_debug(NES_DBG_HW, "tx_pool_size = 0x%08X\n", nesadapter->tx_pool_size); 277 + 278 + eeprom_offset += 2; 279 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset); 280 + eeprom_offset += 2; 281 + nesadapter->rx_threshold = (((u32)eeprom_data) << 16) + 282 + nes_read16_eeprom(nesdev->regs, eeprom_offset); 283 + nes_debug(NES_DBG_HW, "rx_threshold = 0x%08X\n", nesadapter->rx_threshold); 284 + 285 + eeprom_offset += 2; 286 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset); 287 + eeprom_offset += 2; 288 + nesadapter->tcp_timer_core_clk_divisor = (((u32)eeprom_data) << 16) + 289 + nes_read16_eeprom(nesdev->regs, eeprom_offset); 290 + nes_debug(NES_DBG_HW, "tcp_timer_core_clk_divisor = 0x%08X\n", 291 + nesadapter->tcp_timer_core_clk_divisor); 292 + 293 + eeprom_offset += 2; 294 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset); 295 + eeprom_offset += 2; 296 + nesadapter->iwarp_config = (((u32)eeprom_data) << 16) + 297 + nes_read16_eeprom(nesdev->regs, eeprom_offset); 298 + nes_debug(NES_DBG_HW, "iwarp_config = 0x%08X\n", nesadapter->iwarp_config); 299 + 300 + eeprom_offset += 2; 301 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset); 302 + eeprom_offset += 2; 303 + nesadapter->cm_config = (((u32)eeprom_data) << 16) + 304 + nes_read16_eeprom(nesdev->regs, eeprom_offset); 305 + nes_debug(NES_DBG_HW, "cm_config = 0x%08X\n", nesadapter->cm_config); 306 + 307 + eeprom_offset += 2; 308 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset); 309 + eeprom_offset += 2; 310 + nesadapter->sws_timer_config = (((u32)eeprom_data) << 16) + 311 + nes_read16_eeprom(nesdev->regs, eeprom_offset); 312 + nes_debug(NES_DBG_HW, "sws_timer_config = 0x%08X\n", nesadapter->sws_timer_config); 313 + 314 + eeprom_offset += 2; 315 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset); 316 + eeprom_offset += 2; 317 + nesadapter->tcp_config1 = (((u32)eeprom_data) << 16) + 318 + nes_read16_eeprom(nesdev->regs, eeprom_offset); 319 + nes_debug(NES_DBG_HW, "tcp_config1 = 0x%08X\n", nesadapter->tcp_config1); 320 + 321 + eeprom_offset += 2; 322 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset); 323 + eeprom_offset += 2; 324 + nesadapter->wqm_wat = (((u32)eeprom_data) << 16) + 325 + nes_read16_eeprom(nesdev->regs, eeprom_offset); 326 + nes_debug(NES_DBG_HW, "wqm_wat = 0x%08X\n", nesadapter->wqm_wat); 327 + 328 + eeprom_offset += 2; 329 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset); 330 + eeprom_offset += 2; 331 + nesadapter->core_clock = (((u32)eeprom_data) << 16) + 332 + nes_read16_eeprom(nesdev->regs, eeprom_offset); 333 + nes_debug(NES_DBG_HW, "core_clock = 0x%08X\n", nesadapter->core_clock); 334 + 335 + if ((sw_section_ver) && (nesadapter->hw_rev != NE020_REV)) { 336 + eeprom_offset += 2; 337 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset); 338 + nesadapter->phy_index[0] = (eeprom_data & 0xff00)>>8; 339 + nesadapter->phy_index[1] = eeprom_data & 0x00ff; 340 + eeprom_offset += 2; 341 + eeprom_data = nes_read16_eeprom(nesdev->regs, eeprom_offset); 342 + nesadapter->phy_index[2] = (eeprom_data & 0xff00)>>8; 343 + nesadapter->phy_index[3] = eeprom_data & 0x00ff; 344 + } else { 345 + nesadapter->phy_index[0] = 4; 346 + nesadapter->phy_index[1] = 5; 347 + nesadapter->phy_index[2] = 6; 348 + nesadapter->phy_index[3] = 7; 349 + } 350 + nes_debug(NES_DBG_HW, "Phy address map = 0 > %u, 1 > %u, 2 > %u, 3 > %u\n", 351 + nesadapter->phy_index[0],nesadapter->phy_index[1], 352 + nesadapter->phy_index[2],nesadapter->phy_index[3]); 353 + } 354 + 355 + return 0; 356 + } 357 + 358 + 359 + /** 360 + * nes_read16_eeprom 361 + */ 362 + static u16 nes_read16_eeprom(void __iomem *addr, u16 offset) 363 + { 364 + writel(NES_EEPROM_READ_REQUEST + (offset >> 1), 365 + (void __iomem *)addr + NES_EEPROM_COMMAND); 366 + 367 + do { 368 + } while (readl((void __iomem *)addr + NES_EEPROM_COMMAND) & 369 + NES_EEPROM_READ_REQUEST); 370 + 371 + return readw((void __iomem *)addr + NES_EEPROM_DATA); 372 + } 373 + 374 + 375 + /** 376 + * nes_write_1G_phy_reg 377 + */ 378 + void nes_write_1G_phy_reg(struct nes_device *nesdev, u8 phy_reg, u8 phy_addr, u16 data) 379 + { 380 + struct nes_adapter *nesadapter = nesdev->nesadapter; 381 + u32 u32temp; 382 + u32 counter; 383 + unsigned long flags; 384 + 385 + spin_lock_irqsave(&nesadapter->phy_lock, flags); 386 + 387 + nes_write_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL, 388 + 0x50020000 | data | ((u32)phy_reg << 18) | ((u32)phy_addr << 23)); 389 + for (counter = 0; counter < 100 ; counter++) { 390 + udelay(30); 391 + u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS); 392 + if (u32temp & 1) { 393 + /* nes_debug(NES_DBG_PHY, "Phy interrupt status = 0x%X.\n", u32temp); */ 394 + nes_write_indexed(nesdev, NES_IDX_MAC_INT_STATUS, 1); 395 + break; 396 + } 397 + } 398 + if (!(u32temp & 1)) 399 + nes_debug(NES_DBG_PHY, "Phy is not responding. interrupt status = 0x%X.\n", 400 + u32temp); 401 + 402 + spin_unlock_irqrestore(&nesadapter->phy_lock, flags); 403 + } 404 + 405 + 406 + /** 407 + * nes_read_1G_phy_reg 408 + * This routine only issues the read, the data must be read 409 + * separately. 410 + */ 411 + void nes_read_1G_phy_reg(struct nes_device *nesdev, u8 phy_reg, u8 phy_addr, u16 *data) 412 + { 413 + struct nes_adapter *nesadapter = nesdev->nesadapter; 414 + u32 u32temp; 415 + u32 counter; 416 + unsigned long flags; 417 + 418 + /* nes_debug(NES_DBG_PHY, "phy addr = %d, mac_index = %d\n", 419 + phy_addr, nesdev->mac_index); */ 420 + spin_lock_irqsave(&nesadapter->phy_lock, flags); 421 + 422 + nes_write_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL, 423 + 0x60020000 | ((u32)phy_reg << 18) | ((u32)phy_addr << 23)); 424 + for (counter = 0; counter < 100 ; counter++) { 425 + udelay(30); 426 + u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS); 427 + if (u32temp & 1) { 428 + /* nes_debug(NES_DBG_PHY, "Phy interrupt status = 0x%X.\n", u32temp); */ 429 + nes_write_indexed(nesdev, NES_IDX_MAC_INT_STATUS, 1); 430 + break; 431 + } 432 + } 433 + if (!(u32temp & 1)) { 434 + nes_debug(NES_DBG_PHY, "Phy is not responding. interrupt status = 0x%X.\n", 435 + u32temp); 436 + *data = 0xffff; 437 + } else { 438 + *data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); 439 + } 440 + spin_unlock_irqrestore(&nesadapter->phy_lock, flags); 441 + } 442 + 443 + 444 + /** 445 + * nes_write_10G_phy_reg 446 + */ 447 + void nes_write_10G_phy_reg(struct nes_device *nesdev, u16 phy_reg, 448 + u8 phy_addr, u16 data) 449 + { 450 + u32 dev_addr; 451 + u32 port_addr; 452 + u32 u32temp; 453 + u32 counter; 454 + 455 + dev_addr = 1; 456 + port_addr = phy_addr; 457 + 458 + /* set address */ 459 + nes_write_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL, 460 + 0x00020000 | (u32)phy_reg | (((u32)dev_addr) << 18) | (((u32)port_addr) << 23)); 461 + for (counter = 0; counter < 100 ; counter++) { 462 + udelay(30); 463 + u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS); 464 + if (u32temp & 1) { 465 + nes_write_indexed(nesdev, NES_IDX_MAC_INT_STATUS, 1); 466 + break; 467 + } 468 + } 469 + if (!(u32temp & 1)) 470 + nes_debug(NES_DBG_PHY, "Phy is not responding. interrupt status = 0x%X.\n", 471 + u32temp); 472 + 473 + /* set data */ 474 + nes_write_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL, 475 + 0x10020000 | (u32)data | (((u32)dev_addr) << 18) | (((u32)port_addr) << 23)); 476 + for (counter = 0; counter < 100 ; counter++) { 477 + udelay(30); 478 + u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS); 479 + if (u32temp & 1) { 480 + nes_write_indexed(nesdev, NES_IDX_MAC_INT_STATUS, 1); 481 + break; 482 + } 483 + } 484 + if (!(u32temp & 1)) 485 + nes_debug(NES_DBG_PHY, "Phy is not responding. interrupt status = 0x%X.\n", 486 + u32temp); 487 + } 488 + 489 + 490 + /** 491 + * nes_read_10G_phy_reg 492 + * This routine only issues the read, the data must be read 493 + * separately. 494 + */ 495 + void nes_read_10G_phy_reg(struct nes_device *nesdev, u16 phy_reg, u8 phy_addr) 496 + { 497 + u32 dev_addr; 498 + u32 port_addr; 499 + u32 u32temp; 500 + u32 counter; 501 + 502 + dev_addr = 1; 503 + port_addr = phy_addr; 504 + 505 + /* set address */ 506 + nes_write_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL, 507 + 0x00020000 | (u32)phy_reg | (((u32)dev_addr) << 18) | (((u32)port_addr) << 23)); 508 + for (counter = 0; counter < 100 ; counter++) { 509 + udelay(30); 510 + u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS); 511 + if (u32temp & 1) { 512 + nes_write_indexed(nesdev, NES_IDX_MAC_INT_STATUS, 1); 513 + break; 514 + } 515 + } 516 + if (!(u32temp & 1)) 517 + nes_debug(NES_DBG_PHY, "Phy is not responding. interrupt status = 0x%X.\n", 518 + u32temp); 519 + 520 + /* issue read */ 521 + nes_write_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL, 522 + 0x30020000 | (((u32)dev_addr) << 18) | (((u32)port_addr) << 23)); 523 + for (counter = 0; counter < 100 ; counter++) { 524 + udelay(30); 525 + u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS); 526 + if (u32temp & 1) { 527 + nes_write_indexed(nesdev, NES_IDX_MAC_INT_STATUS, 1); 528 + break; 529 + } 530 + } 531 + if (!(u32temp & 1)) 532 + nes_debug(NES_DBG_PHY, "Phy is not responding. interrupt status = 0x%X.\n", 533 + u32temp); 534 + } 535 + 536 + 537 + /** 538 + * nes_get_cqp_request 539 + */ 540 + struct nes_cqp_request *nes_get_cqp_request(struct nes_device *nesdev) 541 + { 542 + unsigned long flags; 543 + struct nes_cqp_request *cqp_request = NULL; 544 + 545 + if (!list_empty(&nesdev->cqp_avail_reqs)) { 546 + spin_lock_irqsave(&nesdev->cqp.lock, flags); 547 + cqp_request = list_entry(nesdev->cqp_avail_reqs.next, 548 + struct nes_cqp_request, list); 549 + list_del_init(&cqp_request->list); 550 + spin_unlock_irqrestore(&nesdev->cqp.lock, flags); 551 + } else { 552 + cqp_request = kzalloc(sizeof(struct nes_cqp_request), GFP_KERNEL); 553 + if (cqp_request) { 554 + cqp_request->dynamic = 1; 555 + INIT_LIST_HEAD(&cqp_request->list); 556 + } 557 + } 558 + 559 + if (cqp_request) { 560 + init_waitqueue_head(&cqp_request->waitq); 561 + cqp_request->waiting = 0; 562 + cqp_request->request_done = 0; 563 + cqp_request->callback = 0; 564 + init_waitqueue_head(&cqp_request->waitq); 565 + nes_debug(NES_DBG_CQP, "Got cqp request %p from the available list \n", 566 + cqp_request); 567 + } else 568 + printk(KERN_ERR PFX "%s: Could not allocated a CQP request.\n", 569 + __FUNCTION__); 570 + 571 + return cqp_request; 572 + } 573 + 574 + 575 + /** 576 + * nes_post_cqp_request 577 + */ 578 + void nes_post_cqp_request(struct nes_device *nesdev, 579 + struct nes_cqp_request *cqp_request, int ring_doorbell) 580 + { 581 + struct nes_hw_cqp_wqe *cqp_wqe; 582 + unsigned long flags; 583 + u32 cqp_head; 584 + u64 u64temp; 585 + 586 + spin_lock_irqsave(&nesdev->cqp.lock, flags); 587 + 588 + if (((((nesdev->cqp.sq_tail+(nesdev->cqp.sq_size*2))-nesdev->cqp.sq_head) & 589 + (nesdev->cqp.sq_size - 1)) != 1) 590 + && (list_empty(&nesdev->cqp_pending_reqs))) { 591 + cqp_head = nesdev->cqp.sq_head++; 592 + nesdev->cqp.sq_head &= nesdev->cqp.sq_size-1; 593 + cqp_wqe = &nesdev->cqp.sq_vbase[cqp_head]; 594 + memcpy(cqp_wqe, &cqp_request->cqp_wqe, sizeof(*cqp_wqe)); 595 + barrier(); 596 + u64temp = (unsigned long)cqp_request; 597 + set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_COMP_SCRATCH_LOW_IDX, 598 + u64temp); 599 + nes_debug(NES_DBG_CQP, "CQP request (opcode 0x%02X), line 1 = 0x%08X put on CQPs SQ," 600 + " request = %p, cqp_head = %u, cqp_tail = %u, cqp_size = %u," 601 + " waiting = %d, refcount = %d.\n", 602 + le32_to_cpu(cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX])&0x3f, 603 + le32_to_cpu(cqp_wqe->wqe_words[NES_CQP_WQE_ID_IDX]), cqp_request, 604 + nesdev->cqp.sq_head, nesdev->cqp.sq_tail, nesdev->cqp.sq_size, 605 + cqp_request->waiting, atomic_read(&cqp_request->refcount)); 606 + barrier(); 607 + if (ring_doorbell) { 608 + /* Ring doorbell (1 WQEs) */ 609 + nes_write32(nesdev->regs+NES_WQE_ALLOC, 0x01800000 | nesdev->cqp.qp_id); 610 + } 611 + 612 + barrier(); 613 + } else { 614 + nes_debug(NES_DBG_CQP, "CQP request %p (opcode 0x%02X), line 1 = 0x%08X" 615 + " put on the pending queue.\n", 616 + cqp_request, 617 + le32_to_cpu(cqp_request->cqp_wqe.wqe_words[NES_CQP_WQE_OPCODE_IDX])&0x3f, 618 + le32_to_cpu(cqp_request->cqp_wqe.wqe_words[NES_CQP_WQE_ID_IDX])); 619 + list_add_tail(&cqp_request->list, &nesdev->cqp_pending_reqs); 620 + } 621 + 622 + spin_unlock_irqrestore(&nesdev->cqp.lock, flags); 623 + 624 + return; 625 + } 626 + 627 + 628 + /** 629 + * nes_arp_table 630 + */ 631 + int nes_arp_table(struct nes_device *nesdev, u32 ip_addr, u8 *mac_addr, u32 action) 632 + { 633 + struct nes_adapter *nesadapter = nesdev->nesadapter; 634 + int arp_index; 635 + int err = 0; 636 + 637 + for (arp_index = 0; (u32) arp_index < nesadapter->arp_table_size; arp_index++) { 638 + if (nesadapter->arp_table[arp_index].ip_addr == ip_addr) 639 + break; 640 + } 641 + 642 + if (action == NES_ARP_ADD) { 643 + if (arp_index != nesadapter->arp_table_size) { 644 + return -1; 645 + } 646 + 647 + arp_index = 0; 648 + err = nes_alloc_resource(nesadapter, nesadapter->allocated_arps, 649 + nesadapter->arp_table_size, (u32 *)&arp_index, &nesadapter->next_arp_index); 650 + if (err) { 651 + nes_debug(NES_DBG_NETDEV, "nes_alloc_resource returned error = %u\n", err); 652 + return err; 653 + } 654 + nes_debug(NES_DBG_NETDEV, "ADD, arp_index=%d\n", arp_index); 655 + 656 + nesadapter->arp_table[arp_index].ip_addr = ip_addr; 657 + memcpy(nesadapter->arp_table[arp_index].mac_addr, mac_addr, ETH_ALEN); 658 + return arp_index; 659 + } 660 + 661 + /* DELETE or RESOLVE */ 662 + if (arp_index == nesadapter->arp_table_size) { 663 + nes_debug(NES_DBG_NETDEV, "mac address not in ARP table - cannot delete or resolve\n"); 664 + return -1; 665 + } 666 + 667 + if (action == NES_ARP_RESOLVE) { 668 + nes_debug(NES_DBG_NETDEV, "RESOLVE, arp_index=%d\n", arp_index); 669 + return arp_index; 670 + } 671 + 672 + if (action == NES_ARP_DELETE) { 673 + nes_debug(NES_DBG_NETDEV, "DELETE, arp_index=%d\n", arp_index); 674 + nesadapter->arp_table[arp_index].ip_addr = 0; 675 + memset(nesadapter->arp_table[arp_index].mac_addr, 0x00, ETH_ALEN); 676 + nes_free_resource(nesadapter, nesadapter->allocated_arps, arp_index); 677 + return arp_index; 678 + } 679 + 680 + return -1; 681 + } 682 + 683 + 684 + /** 685 + * nes_mh_fix 686 + */ 687 + void nes_mh_fix(unsigned long parm) 688 + { 689 + unsigned long flags; 690 + struct nes_device *nesdev = (struct nes_device *)parm; 691 + struct nes_adapter *nesadapter = nesdev->nesadapter; 692 + struct nes_vnic *nesvnic; 693 + u32 used_chunks_tx; 694 + u32 temp_used_chunks_tx; 695 + u32 temp_last_used_chunks_tx; 696 + u32 used_chunks_mask; 697 + u32 mac_tx_frames_low; 698 + u32 mac_tx_frames_high; 699 + u32 mac_tx_pauses; 700 + u32 serdes_status; 701 + u32 reset_value; 702 + u32 tx_control; 703 + u32 tx_config; 704 + u32 tx_pause_quanta; 705 + u32 rx_control; 706 + u32 rx_config; 707 + u32 mac_exact_match; 708 + u32 mpp_debug; 709 + u32 i=0; 710 + u32 chunks_tx_progress = 0; 711 + 712 + spin_lock_irqsave(&nesadapter->phy_lock, flags); 713 + if ((nesadapter->mac_sw_state[0] != NES_MAC_SW_IDLE) || (nesadapter->mac_link_down[0])) { 714 + spin_unlock_irqrestore(&nesadapter->phy_lock, flags); 715 + goto no_mh_work; 716 + } 717 + nesadapter->mac_sw_state[0] = NES_MAC_SW_MH; 718 + spin_unlock_irqrestore(&nesadapter->phy_lock, flags); 719 + do { 720 + mac_tx_frames_low = nes_read_indexed(nesdev, NES_IDX_MAC_TX_FRAMES_LOW); 721 + mac_tx_frames_high = nes_read_indexed(nesdev, NES_IDX_MAC_TX_FRAMES_HIGH); 722 + mac_tx_pauses = nes_read_indexed(nesdev, NES_IDX_MAC_TX_PAUSE_FRAMES); 723 + used_chunks_tx = nes_read_indexed(nesdev, NES_IDX_USED_CHUNKS_TX); 724 + nesdev->mac_pause_frames_sent += mac_tx_pauses; 725 + used_chunks_mask = 0; 726 + temp_used_chunks_tx = used_chunks_tx; 727 + temp_last_used_chunks_tx = nesdev->last_used_chunks_tx; 728 + 729 + if (nesdev->netdev[0]) { 730 + nesvnic = netdev_priv(nesdev->netdev[0]); 731 + } else { 732 + break; 733 + } 734 + 735 + for (i=0; i<4; i++) { 736 + used_chunks_mask <<= 8; 737 + if (nesvnic->qp_nic_index[i] != 0xff) { 738 + used_chunks_mask |= 0xff; 739 + if ((temp_used_chunks_tx&0xff)<(temp_last_used_chunks_tx&0xff)) { 740 + chunks_tx_progress = 1; 741 + } 742 + } 743 + temp_used_chunks_tx >>= 8; 744 + temp_last_used_chunks_tx >>= 8; 745 + } 746 + if ((mac_tx_frames_low) || (mac_tx_frames_high) || 747 + (!(used_chunks_tx&used_chunks_mask)) || 748 + (!(nesdev->last_used_chunks_tx&used_chunks_mask)) || 749 + (chunks_tx_progress) ) { 750 + nesdev->last_used_chunks_tx = used_chunks_tx; 751 + break; 752 + } 753 + nesdev->last_used_chunks_tx = used_chunks_tx; 754 + barrier(); 755 + 756 + nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONTROL, 0x00000005); 757 + mh_pauses_sent++; 758 + mac_tx_pauses = nes_read_indexed(nesdev, NES_IDX_MAC_TX_PAUSE_FRAMES); 759 + if (mac_tx_pauses) { 760 + nesdev->mac_pause_frames_sent += mac_tx_pauses; 761 + break; 762 + } 763 + 764 + tx_control = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONTROL); 765 + tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG); 766 + tx_pause_quanta = nes_read_indexed(nesdev, NES_IDX_MAC_TX_PAUSE_QUANTA); 767 + rx_control = nes_read_indexed(nesdev, NES_IDX_MAC_RX_CONTROL); 768 + rx_config = nes_read_indexed(nesdev, NES_IDX_MAC_RX_CONFIG); 769 + mac_exact_match = nes_read_indexed(nesdev, NES_IDX_MAC_EXACT_MATCH_BOTTOM); 770 + mpp_debug = nes_read_indexed(nesdev, NES_IDX_MPP_DEBUG); 771 + 772 + /* one last ditch effort to avoid a false positive */ 773 + mac_tx_pauses = nes_read_indexed(nesdev, NES_IDX_MAC_TX_PAUSE_FRAMES); 774 + if (mac_tx_pauses) { 775 + nesdev->last_mac_tx_pauses = nesdev->mac_pause_frames_sent; 776 + nes_debug(NES_DBG_HW, "failsafe caught slow outbound pause\n"); 777 + break; 778 + } 779 + mh_detected++; 780 + 781 + nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONTROL, 0x00000000); 782 + nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, 0x00000000); 783 + reset_value = nes_read32(nesdev->regs+NES_SOFTWARE_RESET); 784 + 785 + nes_write32(nesdev->regs+NES_SOFTWARE_RESET, reset_value | 0x0000001d); 786 + 787 + while (((nes_read32(nesdev->regs+NES_SOFTWARE_RESET) 788 + & 0x00000040) != 0x00000040) && (i++ < 5000)) { 789 + /* mdelay(1); */ 790 + } 791 + 792 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, 0x00000008); 793 + serdes_status = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0); 794 + 795 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_EMP0, 0x000bdef7); 796 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_DRIVE0, 0x9ce73000); 797 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_RX_MODE0, 0x0ff00000); 798 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_RX_SIGDET0, 0x00000000); 799 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_BYPASS0, 0x00000000); 800 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_LOOPBACK_CONTROL0, 0x00000000); 801 + if (nesadapter->OneG_Mode) { 802 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_RX_EQ_CONTROL0, 0xf0182222); 803 + } else { 804 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_RX_EQ_CONTROL0, 0xf0042222); 805 + } 806 + serdes_status = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_RX_EQ_STATUS0); 807 + nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000ff); 808 + 809 + nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONTROL, tx_control); 810 + nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config); 811 + nes_write_indexed(nesdev, NES_IDX_MAC_TX_PAUSE_QUANTA, tx_pause_quanta); 812 + nes_write_indexed(nesdev, NES_IDX_MAC_RX_CONTROL, rx_control); 813 + nes_write_indexed(nesdev, NES_IDX_MAC_RX_CONFIG, rx_config); 814 + nes_write_indexed(nesdev, NES_IDX_MAC_EXACT_MATCH_BOTTOM, mac_exact_match); 815 + nes_write_indexed(nesdev, NES_IDX_MPP_DEBUG, mpp_debug); 816 + 817 + } while (0); 818 + 819 + nesadapter->mac_sw_state[0] = NES_MAC_SW_IDLE; 820 + no_mh_work: 821 + nesdev->nesadapter->mh_timer.expires = jiffies + (HZ/5); 822 + add_timer(&nesdev->nesadapter->mh_timer); 823 + } 824 + 825 + /** 826 + * nes_clc 827 + */ 828 + void nes_clc(unsigned long parm) 829 + { 830 + unsigned long flags; 831 + struct nes_device *nesdev = (struct nes_device *)parm; 832 + struct nes_adapter *nesadapter = nesdev->nesadapter; 833 + 834 + spin_lock_irqsave(&nesadapter->phy_lock, flags); 835 + nesadapter->link_interrupt_count[0] = 0; 836 + nesadapter->link_interrupt_count[1] = 0; 837 + nesadapter->link_interrupt_count[2] = 0; 838 + nesadapter->link_interrupt_count[3] = 0; 839 + spin_unlock_irqrestore(&nesadapter->phy_lock, flags); 840 + 841 + nesadapter->lc_timer.expires = jiffies + 3600 * HZ; /* 1 hour */ 842 + add_timer(&nesadapter->lc_timer); 843 + } 844 + 845 + 846 + /** 847 + * nes_dump_mem 848 + */ 849 + void nes_dump_mem(unsigned int dump_debug_level, void *addr, int length) 850 + { 851 + char xlate[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 852 + 'a', 'b', 'c', 'd', 'e', 'f'}; 853 + char *ptr; 854 + char hex_buf[80]; 855 + char ascii_buf[20]; 856 + int num_char; 857 + int num_ascii; 858 + int num_hex; 859 + 860 + if (!(nes_debug_level & dump_debug_level)) { 861 + return; 862 + } 863 + 864 + ptr = addr; 865 + if (length > 0x100) { 866 + nes_debug(dump_debug_level, "Length truncated from %x to %x\n", length, 0x100); 867 + length = 0x100; 868 + } 869 + nes_debug(dump_debug_level, "Address=0x%p, length=0x%x (%d)\n", ptr, length, length); 870 + 871 + memset(ascii_buf, 0, 20); 872 + memset(hex_buf, 0, 80); 873 + 874 + num_ascii = 0; 875 + num_hex = 0; 876 + for (num_char = 0; num_char < length; num_char++) { 877 + if (num_ascii == 8) { 878 + ascii_buf[num_ascii++] = ' '; 879 + hex_buf[num_hex++] = '-'; 880 + hex_buf[num_hex++] = ' '; 881 + } 882 + 883 + if (*ptr < 0x20 || *ptr > 0x7e) 884 + ascii_buf[num_ascii++] = '.'; 885 + else 886 + ascii_buf[num_ascii++] = *ptr; 887 + hex_buf[num_hex++] = xlate[((*ptr & 0xf0) >> 4)]; 888 + hex_buf[num_hex++] = xlate[*ptr & 0x0f]; 889 + hex_buf[num_hex++] = ' '; 890 + ptr++; 891 + 892 + if (num_ascii >= 17) { 893 + /* output line and reset */ 894 + nes_debug(dump_debug_level, " %s | %s\n", hex_buf, ascii_buf); 895 + memset(ascii_buf, 0, 20); 896 + memset(hex_buf, 0, 80); 897 + num_ascii = 0; 898 + num_hex = 0; 899 + } 900 + } 901 + 902 + /* output the rest */ 903 + if (num_ascii) { 904 + while (num_ascii < 17) { 905 + if (num_ascii == 8) { 906 + hex_buf[num_hex++] = ' '; 907 + hex_buf[num_hex++] = ' '; 908 + } 909 + hex_buf[num_hex++] = ' '; 910 + hex_buf[num_hex++] = ' '; 911 + hex_buf[num_hex++] = ' '; 912 + num_ascii++; 913 + } 914 + 915 + nes_debug(dump_debug_level, " %s | %s\n", hex_buf, ascii_buf); 916 + } 917 + }
+3917
drivers/infiniband/hw/nes/nes_verbs.c
···
··· 1 + /* 2 + * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved. 3 + * 4 + * This software is available to you under a choice of one of two 5 + * licenses. You may choose to be licensed under the terms of the GNU 6 + * General Public License (GPL) Version 2, available from the file 7 + * COPYING in the main directory of this source tree, or the 8 + * OpenIB.org BSD license below: 9 + * 10 + * Redistribution and use in source and binary forms, with or 11 + * without modification, are permitted provided that the following 12 + * conditions are met: 13 + * 14 + * - Redistributions of source code must retain the above 15 + * copyright notice, this list of conditions and the following 16 + * disclaimer. 17 + * 18 + * - Redistributions in binary form must reproduce the above 19 + * copyright notice, this list of conditions and the following 20 + * disclaimer in the documentation and/or other materials 21 + * provided with the distribution. 22 + * 23 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 + * SOFTWARE. 31 + * 32 + */ 33 + 34 + #include <linux/module.h> 35 + #include <linux/moduleparam.h> 36 + #include <linux/random.h> 37 + #include <linux/highmem.h> 38 + #include <asm/byteorder.h> 39 + 40 + #include <rdma/ib_verbs.h> 41 + #include <rdma/iw_cm.h> 42 + #include <rdma/ib_user_verbs.h> 43 + 44 + #include "nes.h" 45 + 46 + #include <rdma/ib_umem.h> 47 + 48 + atomic_t mod_qp_timouts; 49 + atomic_t qps_created; 50 + atomic_t sw_qps_destroyed; 51 + 52 + 53 + /** 54 + * nes_alloc_mw 55 + */ 56 + static struct ib_mw *nes_alloc_mw(struct ib_pd *ibpd) { 57 + unsigned long flags; 58 + struct nes_pd *nespd = to_nespd(ibpd); 59 + struct nes_vnic *nesvnic = to_nesvnic(ibpd->device); 60 + struct nes_device *nesdev = nesvnic->nesdev; 61 + struct nes_adapter *nesadapter = nesdev->nesadapter; 62 + struct nes_cqp_request *cqp_request; 63 + struct nes_mr *nesmr; 64 + struct ib_mw *ibmw; 65 + struct nes_hw_cqp_wqe *cqp_wqe; 66 + int ret; 67 + u32 stag; 68 + u32 stag_index = 0; 69 + u32 next_stag_index = 0; 70 + u32 driver_key = 0; 71 + u8 stag_key = 0; 72 + 73 + get_random_bytes(&next_stag_index, sizeof(next_stag_index)); 74 + stag_key = (u8)next_stag_index; 75 + 76 + driver_key = 0; 77 + 78 + next_stag_index >>= 8; 79 + next_stag_index %= nesadapter->max_mr; 80 + 81 + ret = nes_alloc_resource(nesadapter, nesadapter->allocated_mrs, 82 + nesadapter->max_mr, &stag_index, &next_stag_index); 83 + if (ret) { 84 + return ERR_PTR(ret); 85 + } 86 + 87 + nesmr = kzalloc(sizeof(*nesmr), GFP_KERNEL); 88 + if (!nesmr) { 89 + nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index); 90 + return ERR_PTR(-ENOMEM); 91 + } 92 + 93 + stag = stag_index << 8; 94 + stag |= driver_key; 95 + stag += (u32)stag_key; 96 + 97 + nes_debug(NES_DBG_MR, "Registering STag 0x%08X, index = 0x%08X\n", 98 + stag, stag_index); 99 + 100 + /* Register the region with the adapter */ 101 + cqp_request = nes_get_cqp_request(nesdev); 102 + if (cqp_request == NULL) { 103 + kfree(nesmr); 104 + nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index); 105 + return ERR_PTR(-ENOMEM); 106 + } 107 + 108 + cqp_request->waiting = 1; 109 + cqp_wqe = &cqp_request->cqp_wqe; 110 + 111 + cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] = 112 + cpu_to_le32( NES_CQP_ALLOCATE_STAG | NES_CQP_STAG_RIGHTS_REMOTE_READ | 113 + NES_CQP_STAG_RIGHTS_REMOTE_WRITE | NES_CQP_STAG_VA_TO | 114 + NES_CQP_STAG_REM_ACC_EN); 115 + 116 + nes_fill_init_cqp_wqe(cqp_wqe, nesdev); 117 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_LEN_HIGH_PD_IDX, (nespd->pd_id & 0x00007fff)); 118 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_STAG_IDX, stag); 119 + 120 + atomic_set(&cqp_request->refcount, 2); 121 + nes_post_cqp_request(nesdev, cqp_request, NES_CQP_REQUEST_RING_DOORBELL); 122 + 123 + /* Wait for CQP */ 124 + ret = wait_event_timeout(cqp_request->waitq, (cqp_request->request_done != 0), 125 + NES_EVENT_TIMEOUT); 126 + nes_debug(NES_DBG_MR, "Register STag 0x%08X completed, wait_event_timeout ret = %u," 127 + " CQP Major:Minor codes = 0x%04X:0x%04X.\n", 128 + stag, ret, cqp_request->major_code, cqp_request->minor_code); 129 + if ((!ret) || (cqp_request->major_code)) { 130 + if (atomic_dec_and_test(&cqp_request->refcount)) { 131 + if (cqp_request->dynamic) { 132 + kfree(cqp_request); 133 + } else { 134 + spin_lock_irqsave(&nesdev->cqp.lock, flags); 135 + list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); 136 + spin_unlock_irqrestore(&nesdev->cqp.lock, flags); 137 + } 138 + } 139 + kfree(nesmr); 140 + nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index); 141 + if (!ret) { 142 + return ERR_PTR(-ETIME); 143 + } else { 144 + return ERR_PTR(-ENOMEM); 145 + } 146 + } else { 147 + if (atomic_dec_and_test(&cqp_request->refcount)) { 148 + if (cqp_request->dynamic) { 149 + kfree(cqp_request); 150 + } else { 151 + spin_lock_irqsave(&nesdev->cqp.lock, flags); 152 + list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); 153 + spin_unlock_irqrestore(&nesdev->cqp.lock, flags); 154 + } 155 + } 156 + } 157 + 158 + nesmr->ibmw.rkey = stag; 159 + nesmr->mode = IWNES_MEMREG_TYPE_MW; 160 + ibmw = &nesmr->ibmw; 161 + nesmr->pbl_4k = 0; 162 + nesmr->pbls_used = 0; 163 + 164 + return ibmw; 165 + } 166 + 167 + 168 + /** 169 + * nes_dealloc_mw 170 + */ 171 + static int nes_dealloc_mw(struct ib_mw *ibmw) 172 + { 173 + struct nes_mr *nesmr = to_nesmw(ibmw); 174 + struct nes_vnic *nesvnic = to_nesvnic(ibmw->device); 175 + struct nes_device *nesdev = nesvnic->nesdev; 176 + struct nes_adapter *nesadapter = nesdev->nesadapter; 177 + struct nes_hw_cqp_wqe *cqp_wqe; 178 + struct nes_cqp_request *cqp_request; 179 + int err = 0; 180 + unsigned long flags; 181 + int ret; 182 + 183 + /* Deallocate the window with the adapter */ 184 + cqp_request = nes_get_cqp_request(nesdev); 185 + if (cqp_request == NULL) { 186 + nes_debug(NES_DBG_MR, "Failed to get a cqp_request.\n"); 187 + return -ENOMEM; 188 + } 189 + cqp_request->waiting = 1; 190 + cqp_wqe = &cqp_request->cqp_wqe; 191 + nes_fill_init_cqp_wqe(cqp_wqe, nesdev); 192 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX, NES_CQP_DEALLOCATE_STAG); 193 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_STAG_IDX, ibmw->rkey); 194 + 195 + atomic_set(&cqp_request->refcount, 2); 196 + nes_post_cqp_request(nesdev, cqp_request, NES_CQP_REQUEST_RING_DOORBELL); 197 + 198 + /* Wait for CQP */ 199 + nes_debug(NES_DBG_MR, "Waiting for deallocate STag 0x%08X to complete.\n", 200 + ibmw->rkey); 201 + ret = wait_event_timeout(cqp_request->waitq, (0 != cqp_request->request_done), 202 + NES_EVENT_TIMEOUT); 203 + nes_debug(NES_DBG_MR, "Deallocate STag completed, wait_event_timeout ret = %u," 204 + " CQP Major:Minor codes = 0x%04X:0x%04X.\n", 205 + ret, cqp_request->major_code, cqp_request->minor_code); 206 + if ((!ret) || (cqp_request->major_code)) { 207 + if (atomic_dec_and_test(&cqp_request->refcount)) { 208 + if (cqp_request->dynamic) { 209 + kfree(cqp_request); 210 + } else { 211 + spin_lock_irqsave(&nesdev->cqp.lock, flags); 212 + list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); 213 + spin_unlock_irqrestore(&nesdev->cqp.lock, flags); 214 + } 215 + } 216 + if (!ret) { 217 + err = -ETIME; 218 + } else { 219 + err = -EIO; 220 + } 221 + } else { 222 + if (atomic_dec_and_test(&cqp_request->refcount)) { 223 + if (cqp_request->dynamic) { 224 + kfree(cqp_request); 225 + } else { 226 + spin_lock_irqsave(&nesdev->cqp.lock, flags); 227 + list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); 228 + spin_unlock_irqrestore(&nesdev->cqp.lock, flags); 229 + } 230 + } 231 + } 232 + 233 + nes_free_resource(nesadapter, nesadapter->allocated_mrs, 234 + (ibmw->rkey & 0x0fffff00) >> 8); 235 + kfree(nesmr); 236 + 237 + return err; 238 + } 239 + 240 + 241 + /** 242 + * nes_bind_mw 243 + */ 244 + static int nes_bind_mw(struct ib_qp *ibqp, struct ib_mw *ibmw, 245 + struct ib_mw_bind *ibmw_bind) 246 + { 247 + u64 u64temp; 248 + struct nes_vnic *nesvnic = to_nesvnic(ibqp->device); 249 + struct nes_device *nesdev = nesvnic->nesdev; 250 + /* struct nes_mr *nesmr = to_nesmw(ibmw); */ 251 + struct nes_qp *nesqp = to_nesqp(ibqp); 252 + struct nes_hw_qp_wqe *wqe; 253 + unsigned long flags = 0; 254 + u32 head; 255 + u32 wqe_misc = 0; 256 + u32 qsize; 257 + 258 + if (nesqp->ibqp_state > IB_QPS_RTS) 259 + return -EINVAL; 260 + 261 + spin_lock_irqsave(&nesqp->lock, flags); 262 + 263 + head = nesqp->hwqp.sq_head; 264 + qsize = nesqp->hwqp.sq_tail; 265 + 266 + /* Check for SQ overflow */ 267 + if (((head + (2 * qsize) - nesqp->hwqp.sq_tail) % qsize) == (qsize - 1)) { 268 + spin_unlock_irqrestore(&nesqp->lock, flags); 269 + return -EINVAL; 270 + } 271 + 272 + wqe = &nesqp->hwqp.sq_vbase[head]; 273 + /* nes_debug(NES_DBG_MR, "processing sq wqe at %p, head = %u.\n", wqe, head); */ 274 + nes_fill_init_qp_wqe(wqe, nesqp, head); 275 + u64temp = ibmw_bind->wr_id; 276 + set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_COMP_SCRATCH_LOW_IDX, u64temp); 277 + wqe_misc = NES_IWARP_SQ_OP_BIND; 278 + 279 + wqe_misc |= NES_IWARP_SQ_WQE_LOCAL_FENCE; 280 + 281 + if (ibmw_bind->send_flags & IB_SEND_SIGNALED) 282 + wqe_misc |= NES_IWARP_SQ_WQE_SIGNALED_COMPL; 283 + 284 + if (ibmw_bind->mw_access_flags & IB_ACCESS_REMOTE_WRITE) { 285 + wqe_misc |= NES_CQP_STAG_RIGHTS_REMOTE_WRITE; 286 + } 287 + if (ibmw_bind->mw_access_flags & IB_ACCESS_REMOTE_READ) { 288 + wqe_misc |= NES_CQP_STAG_RIGHTS_REMOTE_READ; 289 + } 290 + 291 + set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_MISC_IDX, wqe_misc); 292 + set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_BIND_WQE_MR_IDX, ibmw_bind->mr->lkey); 293 + set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_BIND_WQE_MW_IDX, ibmw->rkey); 294 + set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_BIND_WQE_LENGTH_LOW_IDX, 295 + ibmw_bind->length); 296 + wqe->wqe_words[NES_IWARP_SQ_BIND_WQE_LENGTH_HIGH_IDX] = 0; 297 + u64temp = (u64)ibmw_bind->addr; 298 + set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_BIND_WQE_VA_FBO_LOW_IDX, u64temp); 299 + 300 + head++; 301 + if (head >= qsize) 302 + head = 0; 303 + 304 + nesqp->hwqp.sq_head = head; 305 + barrier(); 306 + 307 + nes_write32(nesdev->regs+NES_WQE_ALLOC, 308 + (1 << 24) | 0x00800000 | nesqp->hwqp.qp_id); 309 + 310 + spin_unlock_irqrestore(&nesqp->lock, flags); 311 + 312 + return 0; 313 + } 314 + 315 + 316 + /** 317 + * nes_alloc_fmr 318 + */ 319 + static struct ib_fmr *nes_alloc_fmr(struct ib_pd *ibpd, 320 + int ibmr_access_flags, 321 + struct ib_fmr_attr *ibfmr_attr) 322 + { 323 + unsigned long flags; 324 + struct nes_pd *nespd = to_nespd(ibpd); 325 + struct nes_vnic *nesvnic = to_nesvnic(ibpd->device); 326 + struct nes_device *nesdev = nesvnic->nesdev; 327 + struct nes_adapter *nesadapter = nesdev->nesadapter; 328 + struct nes_fmr *nesfmr; 329 + struct nes_cqp_request *cqp_request; 330 + struct nes_hw_cqp_wqe *cqp_wqe; 331 + int ret; 332 + u32 stag; 333 + u32 stag_index = 0; 334 + u32 next_stag_index = 0; 335 + u32 driver_key = 0; 336 + u32 opcode = 0; 337 + u8 stag_key = 0; 338 + int i=0; 339 + struct nes_vpbl vpbl; 340 + 341 + get_random_bytes(&next_stag_index, sizeof(next_stag_index)); 342 + stag_key = (u8)next_stag_index; 343 + 344 + driver_key = 0; 345 + 346 + next_stag_index >>= 8; 347 + next_stag_index %= nesadapter->max_mr; 348 + 349 + ret = nes_alloc_resource(nesadapter, nesadapter->allocated_mrs, 350 + nesadapter->max_mr, &stag_index, &next_stag_index); 351 + if (ret) { 352 + goto failed_resource_alloc; 353 + } 354 + 355 + nesfmr = kzalloc(sizeof(*nesfmr), GFP_KERNEL); 356 + if (!nesfmr) { 357 + ret = -ENOMEM; 358 + goto failed_fmr_alloc; 359 + } 360 + 361 + nesfmr->nesmr.mode = IWNES_MEMREG_TYPE_FMR; 362 + if (ibfmr_attr->max_pages == 1) { 363 + /* use zero length PBL */ 364 + nesfmr->nesmr.pbl_4k = 0; 365 + nesfmr->nesmr.pbls_used = 0; 366 + } else if (ibfmr_attr->max_pages <= 32) { 367 + /* use PBL 256 */ 368 + nesfmr->nesmr.pbl_4k = 0; 369 + nesfmr->nesmr.pbls_used = 1; 370 + } else if (ibfmr_attr->max_pages <= 512) { 371 + /* use 4K PBLs */ 372 + nesfmr->nesmr.pbl_4k = 1; 373 + nesfmr->nesmr.pbls_used = 1; 374 + } else { 375 + /* use two level 4K PBLs */ 376 + /* add support for two level 256B PBLs */ 377 + nesfmr->nesmr.pbl_4k = 1; 378 + nesfmr->nesmr.pbls_used = 1 + (ibfmr_attr->max_pages >> 9) + 379 + ((ibfmr_attr->max_pages & 511) ? 1 : 0); 380 + } 381 + /* Register the region with the adapter */ 382 + spin_lock_irqsave(&nesadapter->pbl_lock, flags); 383 + 384 + /* track PBL resources */ 385 + if (nesfmr->nesmr.pbls_used != 0) { 386 + if (nesfmr->nesmr.pbl_4k) { 387 + if (nesfmr->nesmr.pbls_used > nesadapter->free_4kpbl) { 388 + spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); 389 + ret = -ENOMEM; 390 + goto failed_vpbl_alloc; 391 + } else { 392 + nesadapter->free_4kpbl -= nesfmr->nesmr.pbls_used; 393 + } 394 + } else { 395 + if (nesfmr->nesmr.pbls_used > nesadapter->free_256pbl) { 396 + spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); 397 + ret = -ENOMEM; 398 + goto failed_vpbl_alloc; 399 + } else { 400 + nesadapter->free_256pbl -= nesfmr->nesmr.pbls_used; 401 + } 402 + } 403 + } 404 + 405 + /* one level pbl */ 406 + if (nesfmr->nesmr.pbls_used == 0) { 407 + nesfmr->root_vpbl.pbl_vbase = NULL; 408 + nes_debug(NES_DBG_MR, "zero level pbl \n"); 409 + } else if (nesfmr->nesmr.pbls_used == 1) { 410 + /* can change it to kmalloc & dma_map_single */ 411 + nesfmr->root_vpbl.pbl_vbase = pci_alloc_consistent(nesdev->pcidev, 4096, 412 + &nesfmr->root_vpbl.pbl_pbase); 413 + if (!nesfmr->root_vpbl.pbl_vbase) { 414 + spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); 415 + ret = -ENOMEM; 416 + goto failed_vpbl_alloc; 417 + } 418 + nesfmr->leaf_pbl_cnt = 0; 419 + nes_debug(NES_DBG_MR, "one level pbl, root_vpbl.pbl_vbase=%p \n", 420 + nesfmr->root_vpbl.pbl_vbase); 421 + } 422 + /* two level pbl */ 423 + else { 424 + nesfmr->root_vpbl.pbl_vbase = pci_alloc_consistent(nesdev->pcidev, 8192, 425 + &nesfmr->root_vpbl.pbl_pbase); 426 + if (!nesfmr->root_vpbl.pbl_vbase) { 427 + spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); 428 + ret = -ENOMEM; 429 + goto failed_vpbl_alloc; 430 + } 431 + 432 + nesfmr->root_vpbl.leaf_vpbl = kzalloc(sizeof(*nesfmr->root_vpbl.leaf_vpbl)*1024, GFP_KERNEL); 433 + if (!nesfmr->root_vpbl.leaf_vpbl) { 434 + spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); 435 + ret = -ENOMEM; 436 + goto failed_leaf_vpbl_alloc; 437 + } 438 + 439 + nesfmr->leaf_pbl_cnt = nesfmr->nesmr.pbls_used-1; 440 + nes_debug(NES_DBG_MR, "two level pbl, root_vpbl.pbl_vbase=%p" 441 + " leaf_pbl_cnt=%d root_vpbl.leaf_vpbl=%p\n", 442 + nesfmr->root_vpbl.pbl_vbase, nesfmr->leaf_pbl_cnt, nesfmr->root_vpbl.leaf_vpbl); 443 + 444 + for (i=0; i<nesfmr->leaf_pbl_cnt; i++) 445 + nesfmr->root_vpbl.leaf_vpbl[i].pbl_vbase = NULL; 446 + 447 + for (i=0; i<nesfmr->leaf_pbl_cnt; i++) { 448 + vpbl.pbl_vbase = pci_alloc_consistent(nesdev->pcidev, 4096, 449 + &vpbl.pbl_pbase); 450 + 451 + if (!vpbl.pbl_vbase) { 452 + ret = -ENOMEM; 453 + spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); 454 + goto failed_leaf_vpbl_pages_alloc; 455 + } 456 + 457 + nesfmr->root_vpbl.pbl_vbase[i].pa_low = cpu_to_le32((u32)vpbl.pbl_pbase); 458 + nesfmr->root_vpbl.pbl_vbase[i].pa_high = cpu_to_le32((u32)((((u64)vpbl.pbl_pbase)>>32))); 459 + nesfmr->root_vpbl.leaf_vpbl[i] = vpbl; 460 + 461 + nes_debug(NES_DBG_MR, "pbase_low=0x%x, pbase_high=0x%x, vpbl=%p\n", 462 + nesfmr->root_vpbl.pbl_vbase[i].pa_low, 463 + nesfmr->root_vpbl.pbl_vbase[i].pa_high, 464 + &nesfmr->root_vpbl.leaf_vpbl[i]); 465 + } 466 + } 467 + nesfmr->ib_qp = NULL; 468 + nesfmr->access_rights =0; 469 + 470 + stag = stag_index << 8; 471 + stag |= driver_key; 472 + stag += (u32)stag_key; 473 + 474 + spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); 475 + cqp_request = nes_get_cqp_request(nesdev); 476 + if (cqp_request == NULL) { 477 + nes_debug(NES_DBG_MR, "Failed to get a cqp_request.\n"); 478 + ret = -ENOMEM; 479 + goto failed_leaf_vpbl_pages_alloc; 480 + } 481 + cqp_request->waiting = 1; 482 + cqp_wqe = &cqp_request->cqp_wqe; 483 + 484 + nes_debug(NES_DBG_MR, "Registering STag 0x%08X, index = 0x%08X\n", 485 + stag, stag_index); 486 + 487 + opcode = NES_CQP_ALLOCATE_STAG | NES_CQP_STAG_VA_TO | NES_CQP_STAG_MR; 488 + 489 + if (nesfmr->nesmr.pbl_4k == 1) 490 + opcode |= NES_CQP_STAG_PBL_BLK_SIZE; 491 + 492 + if (ibmr_access_flags & IB_ACCESS_REMOTE_WRITE) { 493 + opcode |= NES_CQP_STAG_RIGHTS_REMOTE_WRITE | 494 + NES_CQP_STAG_RIGHTS_LOCAL_WRITE | NES_CQP_STAG_REM_ACC_EN; 495 + nesfmr->access_rights |= 496 + NES_CQP_STAG_RIGHTS_REMOTE_WRITE | NES_CQP_STAG_RIGHTS_LOCAL_WRITE | 497 + NES_CQP_STAG_REM_ACC_EN; 498 + } 499 + 500 + if (ibmr_access_flags & IB_ACCESS_REMOTE_READ) { 501 + opcode |= NES_CQP_STAG_RIGHTS_REMOTE_READ | 502 + NES_CQP_STAG_RIGHTS_LOCAL_READ | NES_CQP_STAG_REM_ACC_EN; 503 + nesfmr->access_rights |= 504 + NES_CQP_STAG_RIGHTS_REMOTE_READ | NES_CQP_STAG_RIGHTS_LOCAL_READ | 505 + NES_CQP_STAG_REM_ACC_EN; 506 + } 507 + 508 + nes_fill_init_cqp_wqe(cqp_wqe, nesdev); 509 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX, opcode); 510 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_LEN_HIGH_PD_IDX, (nespd->pd_id & 0x00007fff)); 511 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_STAG_IDX, stag); 512 + 513 + cqp_wqe->wqe_words[NES_CQP_STAG_WQE_PBL_BLK_COUNT_IDX] = 514 + cpu_to_le32((nesfmr->nesmr.pbls_used>1) ? 515 + (nesfmr->nesmr.pbls_used-1) : nesfmr->nesmr.pbls_used); 516 + 517 + atomic_set(&cqp_request->refcount, 2); 518 + nes_post_cqp_request(nesdev, cqp_request, NES_CQP_REQUEST_RING_DOORBELL); 519 + 520 + /* Wait for CQP */ 521 + ret = wait_event_timeout(cqp_request->waitq, (cqp_request->request_done != 0), 522 + NES_EVENT_TIMEOUT); 523 + nes_debug(NES_DBG_MR, "Register STag 0x%08X completed, wait_event_timeout ret = %u," 524 + " CQP Major:Minor codes = 0x%04X:0x%04X.\n", 525 + stag, ret, cqp_request->major_code, cqp_request->minor_code); 526 + 527 + if ((!ret) || (cqp_request->major_code)) { 528 + if (atomic_dec_and_test(&cqp_request->refcount)) { 529 + if (cqp_request->dynamic) { 530 + kfree(cqp_request); 531 + } else { 532 + spin_lock_irqsave(&nesdev->cqp.lock, flags); 533 + list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); 534 + spin_unlock_irqrestore(&nesdev->cqp.lock, flags); 535 + } 536 + } 537 + ret = (!ret) ? -ETIME : -EIO; 538 + goto failed_leaf_vpbl_pages_alloc; 539 + } else { 540 + if (atomic_dec_and_test(&cqp_request->refcount)) { 541 + if (cqp_request->dynamic) { 542 + kfree(cqp_request); 543 + } else { 544 + spin_lock_irqsave(&nesdev->cqp.lock, flags); 545 + list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); 546 + spin_unlock_irqrestore(&nesdev->cqp.lock, flags); 547 + } 548 + } 549 + } 550 + 551 + nesfmr->nesmr.ibfmr.lkey = stag; 552 + nesfmr->nesmr.ibfmr.rkey = stag; 553 + nesfmr->attr = *ibfmr_attr; 554 + 555 + return &nesfmr->nesmr.ibfmr; 556 + 557 + failed_leaf_vpbl_pages_alloc: 558 + /* unroll all allocated pages */ 559 + for (i=0; i<nesfmr->leaf_pbl_cnt; i++) { 560 + if (nesfmr->root_vpbl.leaf_vpbl[i].pbl_vbase) { 561 + pci_free_consistent(nesdev->pcidev, 4096, nesfmr->root_vpbl.leaf_vpbl[i].pbl_vbase, 562 + nesfmr->root_vpbl.leaf_vpbl[i].pbl_pbase); 563 + } 564 + } 565 + if (nesfmr->root_vpbl.leaf_vpbl) 566 + kfree(nesfmr->root_vpbl.leaf_vpbl); 567 + 568 + failed_leaf_vpbl_alloc: 569 + if (nesfmr->leaf_pbl_cnt == 0) { 570 + if (nesfmr->root_vpbl.pbl_vbase) 571 + pci_free_consistent(nesdev->pcidev, 4096, nesfmr->root_vpbl.pbl_vbase, 572 + nesfmr->root_vpbl.pbl_pbase); 573 + } else 574 + pci_free_consistent(nesdev->pcidev, 8192, nesfmr->root_vpbl.pbl_vbase, 575 + nesfmr->root_vpbl.pbl_pbase); 576 + 577 + failed_vpbl_alloc: 578 + kfree(nesfmr); 579 + 580 + failed_fmr_alloc: 581 + nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index); 582 + 583 + failed_resource_alloc: 584 + return ERR_PTR(ret); 585 + } 586 + 587 + 588 + /** 589 + * nes_dealloc_fmr 590 + */ 591 + static int nes_dealloc_fmr(struct ib_fmr *ibfmr) 592 + { 593 + struct nes_mr *nesmr = to_nesmr_from_ibfmr(ibfmr); 594 + struct nes_fmr *nesfmr = to_nesfmr(nesmr); 595 + struct nes_vnic *nesvnic = to_nesvnic(ibfmr->device); 596 + struct nes_device *nesdev = nesvnic->nesdev; 597 + struct nes_mr temp_nesmr = *nesmr; 598 + int i = 0; 599 + 600 + temp_nesmr.ibmw.device = ibfmr->device; 601 + temp_nesmr.ibmw.pd = ibfmr->pd; 602 + temp_nesmr.ibmw.rkey = ibfmr->rkey; 603 + temp_nesmr.ibmw.uobject = NULL; 604 + 605 + /* free the resources */ 606 + if (nesfmr->leaf_pbl_cnt == 0) { 607 + /* single PBL case */ 608 + if (nesfmr->root_vpbl.pbl_vbase) 609 + pci_free_consistent(nesdev->pcidev, 4096, nesfmr->root_vpbl.pbl_vbase, 610 + nesfmr->root_vpbl.pbl_pbase); 611 + } else { 612 + for (i = 0; i < nesfmr->leaf_pbl_cnt; i++) { 613 + pci_free_consistent(nesdev->pcidev, 4096, nesfmr->root_vpbl.leaf_vpbl[i].pbl_vbase, 614 + nesfmr->root_vpbl.leaf_vpbl[i].pbl_pbase); 615 + } 616 + kfree(nesfmr->root_vpbl.leaf_vpbl); 617 + pci_free_consistent(nesdev->pcidev, 8192, nesfmr->root_vpbl.pbl_vbase, 618 + nesfmr->root_vpbl.pbl_pbase); 619 + } 620 + 621 + return nes_dealloc_mw(&temp_nesmr.ibmw); 622 + } 623 + 624 + 625 + /** 626 + * nes_map_phys_fmr 627 + */ 628 + static int nes_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list, 629 + int list_len, u64 iova) 630 + { 631 + return 0; 632 + } 633 + 634 + 635 + /** 636 + * nes_unmap_frm 637 + */ 638 + static int nes_unmap_fmr(struct list_head *ibfmr_list) 639 + { 640 + return 0; 641 + } 642 + 643 + 644 + 645 + /** 646 + * nes_query_device 647 + */ 648 + static int nes_query_device(struct ib_device *ibdev, struct ib_device_attr *props) 649 + { 650 + struct nes_vnic *nesvnic = to_nesvnic(ibdev); 651 + struct nes_device *nesdev = nesvnic->nesdev; 652 + struct nes_ib_device *nesibdev = nesvnic->nesibdev; 653 + 654 + memset(props, 0, sizeof(*props)); 655 + memcpy(&props->sys_image_guid, nesvnic->netdev->dev_addr, 6); 656 + 657 + props->fw_ver = nesdev->nesadapter->fw_ver; 658 + props->device_cap_flags = nesdev->nesadapter->device_cap_flags; 659 + props->vendor_id = nesdev->nesadapter->vendor_id; 660 + props->vendor_part_id = nesdev->nesadapter->vendor_part_id; 661 + props->hw_ver = nesdev->nesadapter->hw_rev; 662 + props->max_mr_size = 0x80000000; 663 + props->max_qp = nesibdev->max_qp; 664 + props->max_qp_wr = nesdev->nesadapter->max_qp_wr - 2; 665 + props->max_sge = nesdev->nesadapter->max_sge; 666 + props->max_cq = nesibdev->max_cq; 667 + props->max_cqe = nesdev->nesadapter->max_cqe - 1; 668 + props->max_mr = nesibdev->max_mr; 669 + props->max_mw = nesibdev->max_mr; 670 + props->max_pd = nesibdev->max_pd; 671 + props->max_sge_rd = 1; 672 + switch (nesdev->nesadapter->max_irrq_wr) { 673 + case 0: 674 + props->max_qp_rd_atom = 1; 675 + break; 676 + case 1: 677 + props->max_qp_rd_atom = 4; 678 + break; 679 + case 2: 680 + props->max_qp_rd_atom = 16; 681 + break; 682 + case 3: 683 + props->max_qp_rd_atom = 32; 684 + break; 685 + default: 686 + props->max_qp_rd_atom = 0; 687 + } 688 + props->max_qp_init_rd_atom = props->max_qp_wr; 689 + props->atomic_cap = IB_ATOMIC_NONE; 690 + props->max_map_per_fmr = 1; 691 + 692 + return 0; 693 + } 694 + 695 + 696 + /** 697 + * nes_query_port 698 + */ 699 + static int nes_query_port(struct ib_device *ibdev, u8 port, struct ib_port_attr *props) 700 + { 701 + memset(props, 0, sizeof(*props)); 702 + 703 + props->max_mtu = IB_MTU_2048; 704 + props->active_mtu = IB_MTU_2048; 705 + props->lid = 1; 706 + props->lmc = 0; 707 + props->sm_lid = 0; 708 + props->sm_sl = 0; 709 + props->state = IB_PORT_ACTIVE; 710 + props->phys_state = 0; 711 + props->port_cap_flags = IB_PORT_CM_SUP | IB_PORT_REINIT_SUP | 712 + IB_PORT_VENDOR_CLASS_SUP | IB_PORT_BOOT_MGMT_SUP; 713 + props->gid_tbl_len = 1; 714 + props->pkey_tbl_len = 1; 715 + props->qkey_viol_cntr = 0; 716 + props->active_width = IB_WIDTH_4X; 717 + props->active_speed = 1; 718 + props->max_msg_sz = 0x80000000; 719 + 720 + return 0; 721 + } 722 + 723 + 724 + /** 725 + * nes_modify_port 726 + */ 727 + static int nes_modify_port(struct ib_device *ibdev, u8 port, 728 + int port_modify_mask, struct ib_port_modify *props) 729 + { 730 + return 0; 731 + } 732 + 733 + 734 + /** 735 + * nes_query_pkey 736 + */ 737 + static int nes_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey) 738 + { 739 + *pkey = 0; 740 + return 0; 741 + } 742 + 743 + 744 + /** 745 + * nes_query_gid 746 + */ 747 + static int nes_query_gid(struct ib_device *ibdev, u8 port, 748 + int index, union ib_gid *gid) 749 + { 750 + struct nes_vnic *nesvnic = to_nesvnic(ibdev); 751 + 752 + memset(&(gid->raw[0]), 0, sizeof(gid->raw)); 753 + memcpy(&(gid->raw[0]), nesvnic->netdev->dev_addr, 6); 754 + 755 + return 0; 756 + } 757 + 758 + 759 + /** 760 + * nes_alloc_ucontext - Allocate the user context data structure. This keeps track 761 + * of all objects associated with a particular user-mode client. 762 + */ 763 + static struct ib_ucontext *nes_alloc_ucontext(struct ib_device *ibdev, 764 + struct ib_udata *udata) 765 + { 766 + struct nes_vnic *nesvnic = to_nesvnic(ibdev); 767 + struct nes_device *nesdev = nesvnic->nesdev; 768 + struct nes_adapter *nesadapter = nesdev->nesadapter; 769 + struct nes_alloc_ucontext_req req; 770 + struct nes_alloc_ucontext_resp uresp; 771 + struct nes_ucontext *nes_ucontext; 772 + struct nes_ib_device *nesibdev = nesvnic->nesibdev; 773 + 774 + 775 + if (ib_copy_from_udata(&req, udata, sizeof(struct nes_alloc_ucontext_req))) { 776 + printk(KERN_ERR PFX "Invalid structure size on allocate user context.\n"); 777 + return ERR_PTR(-EINVAL); 778 + } 779 + 780 + if (req.userspace_ver != NES_ABI_USERSPACE_VER) { 781 + printk(KERN_ERR PFX "Invalid userspace driver version detected. Detected version %d, should be %d\n", 782 + req.userspace_ver, NES_ABI_USERSPACE_VER); 783 + return ERR_PTR(-EINVAL); 784 + } 785 + 786 + 787 + memset(&uresp, 0, sizeof uresp); 788 + 789 + uresp.max_qps = nesibdev->max_qp; 790 + uresp.max_pds = nesibdev->max_pd; 791 + uresp.wq_size = nesdev->nesadapter->max_qp_wr * 2; 792 + uresp.virtwq = nesadapter->virtwq; 793 + uresp.kernel_ver = NES_ABI_KERNEL_VER; 794 + 795 + nes_ucontext = kzalloc(sizeof *nes_ucontext, GFP_KERNEL); 796 + if (!nes_ucontext) 797 + return ERR_PTR(-ENOMEM); 798 + 799 + nes_ucontext->nesdev = nesdev; 800 + nes_ucontext->mmap_wq_offset = uresp.max_pds; 801 + nes_ucontext->mmap_cq_offset = nes_ucontext->mmap_wq_offset + 802 + ((sizeof(struct nes_hw_qp_wqe) * uresp.max_qps * 2) + PAGE_SIZE-1) / 803 + PAGE_SIZE; 804 + 805 + 806 + if (ib_copy_to_udata(udata, &uresp, sizeof uresp)) { 807 + kfree(nes_ucontext); 808 + return ERR_PTR(-EFAULT); 809 + } 810 + 811 + INIT_LIST_HEAD(&nes_ucontext->cq_reg_mem_list); 812 + INIT_LIST_HEAD(&nes_ucontext->qp_reg_mem_list); 813 + atomic_set(&nes_ucontext->usecnt, 1); 814 + return &nes_ucontext->ibucontext; 815 + } 816 + 817 + 818 + /** 819 + * nes_dealloc_ucontext 820 + */ 821 + static int nes_dealloc_ucontext(struct ib_ucontext *context) 822 + { 823 + /* struct nes_vnic *nesvnic = to_nesvnic(context->device); */ 824 + /* struct nes_device *nesdev = nesvnic->nesdev; */ 825 + struct nes_ucontext *nes_ucontext = to_nesucontext(context); 826 + 827 + if (!atomic_dec_and_test(&nes_ucontext->usecnt)) 828 + return 0; 829 + kfree(nes_ucontext); 830 + return 0; 831 + } 832 + 833 + 834 + /** 835 + * nes_mmap 836 + */ 837 + static int nes_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) 838 + { 839 + unsigned long index; 840 + struct nes_vnic *nesvnic = to_nesvnic(context->device); 841 + struct nes_device *nesdev = nesvnic->nesdev; 842 + /* struct nes_adapter *nesadapter = nesdev->nesadapter; */ 843 + struct nes_ucontext *nes_ucontext; 844 + struct nes_qp *nesqp; 845 + 846 + nes_ucontext = to_nesucontext(context); 847 + 848 + 849 + if (vma->vm_pgoff >= nes_ucontext->mmap_wq_offset) { 850 + index = (vma->vm_pgoff - nes_ucontext->mmap_wq_offset) * PAGE_SIZE; 851 + index /= ((sizeof(struct nes_hw_qp_wqe) * nesdev->nesadapter->max_qp_wr * 2) + 852 + PAGE_SIZE-1) & (~(PAGE_SIZE-1)); 853 + if (!test_bit(index, nes_ucontext->allocated_wqs)) { 854 + nes_debug(NES_DBG_MMAP, "wq %lu not allocated\n", index); 855 + return -EFAULT; 856 + } 857 + nesqp = nes_ucontext->mmap_nesqp[index]; 858 + if (nesqp == NULL) { 859 + nes_debug(NES_DBG_MMAP, "wq %lu has a NULL QP base.\n", index); 860 + return -EFAULT; 861 + } 862 + if (remap_pfn_range(vma, vma->vm_start, 863 + virt_to_phys(nesqp->hwqp.sq_vbase) >> PAGE_SHIFT, 864 + vma->vm_end - vma->vm_start, 865 + vma->vm_page_prot)) { 866 + nes_debug(NES_DBG_MMAP, "remap_pfn_range failed.\n"); 867 + return -EAGAIN; 868 + } 869 + vma->vm_private_data = nesqp; 870 + return 0; 871 + } else { 872 + index = vma->vm_pgoff; 873 + if (!test_bit(index, nes_ucontext->allocated_doorbells)) 874 + return -EFAULT; 875 + 876 + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 877 + if (io_remap_pfn_range(vma, vma->vm_start, 878 + (nesdev->doorbell_start + 879 + ((nes_ucontext->mmap_db_index[index] - nesdev->base_doorbell_index) * 4096)) 880 + >> PAGE_SHIFT, PAGE_SIZE, vma->vm_page_prot)) 881 + return -EAGAIN; 882 + vma->vm_private_data = nes_ucontext; 883 + return 0; 884 + } 885 + 886 + return -ENOSYS; 887 + } 888 + 889 + 890 + /** 891 + * nes_alloc_pd 892 + */ 893 + static struct ib_pd *nes_alloc_pd(struct ib_device *ibdev, 894 + struct ib_ucontext *context, struct ib_udata *udata) 895 + { 896 + struct nes_pd *nespd; 897 + struct nes_vnic *nesvnic = to_nesvnic(ibdev); 898 + struct nes_device *nesdev = nesvnic->nesdev; 899 + struct nes_adapter *nesadapter = nesdev->nesadapter; 900 + struct nes_ucontext *nesucontext; 901 + struct nes_alloc_pd_resp uresp; 902 + u32 pd_num = 0; 903 + int err; 904 + 905 + nes_debug(NES_DBG_PD, "nesvnic=%p, netdev=%p %s, ibdev=%p, context=%p, netdev refcnt=%u\n", 906 + nesvnic, nesdev->netdev[0], nesdev->netdev[0]->name, ibdev, context, 907 + atomic_read(&nesvnic->netdev->refcnt)); 908 + 909 + err = nes_alloc_resource(nesadapter, nesadapter->allocated_pds, 910 + nesadapter->max_pd, &pd_num, &nesadapter->next_pd); 911 + if (err) { 912 + return ERR_PTR(err); 913 + } 914 + 915 + nespd = kzalloc(sizeof (struct nes_pd), GFP_KERNEL); 916 + if (!nespd) { 917 + nes_free_resource(nesadapter, nesadapter->allocated_pds, pd_num); 918 + return ERR_PTR(-ENOMEM); 919 + } 920 + 921 + nes_debug(NES_DBG_PD, "Allocating PD (%p) for ib device %s\n", 922 + nespd, nesvnic->nesibdev->ibdev.name); 923 + 924 + nespd->pd_id = (pd_num << (PAGE_SHIFT-12)) + nesadapter->base_pd; 925 + 926 + if (context) { 927 + nesucontext = to_nesucontext(context); 928 + nespd->mmap_db_index = find_next_zero_bit(nesucontext->allocated_doorbells, 929 + NES_MAX_USER_DB_REGIONS, nesucontext->first_free_db); 930 + nes_debug(NES_DBG_PD, "find_first_zero_biton doorbells returned %u, mapping pd_id %u.\n", 931 + nespd->mmap_db_index, nespd->pd_id); 932 + if (nespd->mmap_db_index > NES_MAX_USER_DB_REGIONS) { 933 + nes_debug(NES_DBG_PD, "mmap_db_index > MAX\n"); 934 + nes_free_resource(nesadapter, nesadapter->allocated_pds, pd_num); 935 + kfree(nespd); 936 + return ERR_PTR(-ENOMEM); 937 + } 938 + 939 + uresp.pd_id = nespd->pd_id; 940 + uresp.mmap_db_index = nespd->mmap_db_index; 941 + if (ib_copy_to_udata(udata, &uresp, sizeof (struct nes_alloc_pd_resp))) { 942 + nes_free_resource(nesadapter, nesadapter->allocated_pds, pd_num); 943 + kfree(nespd); 944 + return ERR_PTR(-EFAULT); 945 + } 946 + 947 + set_bit(nespd->mmap_db_index, nesucontext->allocated_doorbells); 948 + nesucontext->mmap_db_index[nespd->mmap_db_index] = nespd->pd_id; 949 + nesucontext->first_free_db = nespd->mmap_db_index + 1; 950 + } 951 + 952 + nes_debug(NES_DBG_PD, "PD%u structure located @%p.\n", nespd->pd_id, nespd); 953 + return &nespd->ibpd; 954 + } 955 + 956 + 957 + /** 958 + * nes_dealloc_pd 959 + */ 960 + static int nes_dealloc_pd(struct ib_pd *ibpd) 961 + { 962 + struct nes_ucontext *nesucontext; 963 + struct nes_pd *nespd = to_nespd(ibpd); 964 + struct nes_vnic *nesvnic = to_nesvnic(ibpd->device); 965 + struct nes_device *nesdev = nesvnic->nesdev; 966 + struct nes_adapter *nesadapter = nesdev->nesadapter; 967 + 968 + if ((ibpd->uobject) && (ibpd->uobject->context)) { 969 + nesucontext = to_nesucontext(ibpd->uobject->context); 970 + nes_debug(NES_DBG_PD, "Clearing bit %u from allocated doorbells\n", 971 + nespd->mmap_db_index); 972 + clear_bit(nespd->mmap_db_index, nesucontext->allocated_doorbells); 973 + nesucontext->mmap_db_index[nespd->mmap_db_index] = 0; 974 + if (nesucontext->first_free_db > nespd->mmap_db_index) { 975 + nesucontext->first_free_db = nespd->mmap_db_index; 976 + } 977 + } 978 + 979 + nes_debug(NES_DBG_PD, "Deallocating PD%u structure located @%p.\n", 980 + nespd->pd_id, nespd); 981 + nes_free_resource(nesadapter, nesadapter->allocated_pds, 982 + (nespd->pd_id-nesadapter->base_pd)>>(PAGE_SHIFT-12)); 983 + kfree(nespd); 984 + 985 + return 0; 986 + } 987 + 988 + 989 + /** 990 + * nes_create_ah 991 + */ 992 + static struct ib_ah *nes_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr) 993 + { 994 + return ERR_PTR(-ENOSYS); 995 + } 996 + 997 + 998 + /** 999 + * nes_destroy_ah 1000 + */ 1001 + static int nes_destroy_ah(struct ib_ah *ah) 1002 + { 1003 + return -ENOSYS; 1004 + } 1005 + 1006 + 1007 + /** 1008 + * nes_get_encoded_size 1009 + */ 1010 + static inline u8 nes_get_encoded_size(int *size) 1011 + { 1012 + u8 encoded_size = 0; 1013 + if (*size <= 32) { 1014 + *size = 32; 1015 + encoded_size = 1; 1016 + } else if (*size <= 128) { 1017 + *size = 128; 1018 + encoded_size = 2; 1019 + } else if (*size <= 512) { 1020 + *size = 512; 1021 + encoded_size = 3; 1022 + } 1023 + return (encoded_size); 1024 + } 1025 + 1026 + 1027 + 1028 + /** 1029 + * nes_setup_virt_qp 1030 + */ 1031 + static int nes_setup_virt_qp(struct nes_qp *nesqp, struct nes_pbl *nespbl, 1032 + struct nes_vnic *nesvnic, int sq_size, int rq_size) 1033 + { 1034 + unsigned long flags; 1035 + void *mem; 1036 + __le64 *pbl = NULL; 1037 + __le64 *tpbl; 1038 + __le64 *pblbuffer; 1039 + struct nes_device *nesdev = nesvnic->nesdev; 1040 + struct nes_adapter *nesadapter = nesdev->nesadapter; 1041 + u32 pbl_entries; 1042 + u8 rq_pbl_entries; 1043 + u8 sq_pbl_entries; 1044 + 1045 + pbl_entries = nespbl->pbl_size >> 3; 1046 + nes_debug(NES_DBG_QP, "Userspace PBL, pbl_size=%u, pbl_entries = %d pbl_vbase=%p, pbl_pbase=%p\n", 1047 + nespbl->pbl_size, pbl_entries, 1048 + (void *)nespbl->pbl_vbase, 1049 + (void *)nespbl->pbl_pbase); 1050 + pbl = (__le64 *) nespbl->pbl_vbase; /* points to first pbl entry */ 1051 + /* now lets set the sq_vbase as well as rq_vbase addrs we will assign */ 1052 + /* the first pbl to be fro the rq_vbase... */ 1053 + rq_pbl_entries = (rq_size * sizeof(struct nes_hw_qp_wqe)) >> 12; 1054 + sq_pbl_entries = (sq_size * sizeof(struct nes_hw_qp_wqe)) >> 12; 1055 + nesqp->hwqp.sq_pbase = (le32_to_cpu(((__le32 *)pbl)[0])) | ((u64)((le32_to_cpu(((__le32 *)pbl)[1]))) << 32); 1056 + if (!nespbl->page) { 1057 + nes_debug(NES_DBG_QP, "QP nespbl->page is NULL \n"); 1058 + kfree(nespbl); 1059 + return -ENOMEM; 1060 + } 1061 + 1062 + nesqp->hwqp.sq_vbase = kmap(nespbl->page); 1063 + nesqp->page = nespbl->page; 1064 + if (!nesqp->hwqp.sq_vbase) { 1065 + nes_debug(NES_DBG_QP, "QP sq_vbase kmap failed\n"); 1066 + kfree(nespbl); 1067 + return -ENOMEM; 1068 + } 1069 + 1070 + /* Now to get to sq.. we need to calculate how many */ 1071 + /* PBL entries were used by the rq.. */ 1072 + pbl += sq_pbl_entries; 1073 + nesqp->hwqp.rq_pbase = (le32_to_cpu(((__le32 *)pbl)[0])) | ((u64)((le32_to_cpu(((__le32 *)pbl)[1]))) << 32); 1074 + /* nesqp->hwqp.rq_vbase = bus_to_virt(*pbl); */ 1075 + /*nesqp->hwqp.rq_vbase = phys_to_virt(*pbl); */ 1076 + 1077 + nes_debug(NES_DBG_QP, "QP sq_vbase= %p sq_pbase=%p rq_vbase=%p rq_pbase=%p\n", 1078 + nesqp->hwqp.sq_vbase, (void *)nesqp->hwqp.sq_pbase, 1079 + nesqp->hwqp.rq_vbase, (void *)nesqp->hwqp.rq_pbase); 1080 + spin_lock_irqsave(&nesadapter->pbl_lock, flags); 1081 + if (!nesadapter->free_256pbl) { 1082 + pci_free_consistent(nesdev->pcidev, nespbl->pbl_size, nespbl->pbl_vbase, 1083 + nespbl->pbl_pbase); 1084 + spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); 1085 + kunmap(nesqp->page); 1086 + kfree(nespbl); 1087 + return -ENOMEM; 1088 + } 1089 + nesadapter->free_256pbl--; 1090 + spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); 1091 + 1092 + nesqp->pbl_vbase = pci_alloc_consistent(nesdev->pcidev, 256, &nesqp->pbl_pbase); 1093 + pblbuffer = nesqp->pbl_vbase; 1094 + if (!nesqp->pbl_vbase) { 1095 + /* memory allocated during nes_reg_user_mr() */ 1096 + pci_free_consistent(nesdev->pcidev, nespbl->pbl_size, nespbl->pbl_vbase, 1097 + nespbl->pbl_pbase); 1098 + kfree(nespbl); 1099 + spin_lock_irqsave(&nesadapter->pbl_lock, flags); 1100 + nesadapter->free_256pbl++; 1101 + spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); 1102 + kunmap(nesqp->page); 1103 + return -ENOMEM; 1104 + } 1105 + memset(nesqp->pbl_vbase, 0, 256); 1106 + /* fill in the page address in the pbl buffer.. */ 1107 + tpbl = pblbuffer + 16; 1108 + pbl = (__le64 *)nespbl->pbl_vbase; 1109 + while (sq_pbl_entries--) 1110 + *tpbl++ = *pbl++; 1111 + tpbl = pblbuffer; 1112 + while (rq_pbl_entries--) 1113 + *tpbl++ = *pbl++; 1114 + 1115 + /* done with memory allocated during nes_reg_user_mr() */ 1116 + pci_free_consistent(nesdev->pcidev, nespbl->pbl_size, nespbl->pbl_vbase, 1117 + nespbl->pbl_pbase); 1118 + kfree(nespbl); 1119 + 1120 + nesqp->qp_mem_size = 1121 + max((u32)sizeof(struct nes_qp_context), ((u32)256)) + 256; /* this is Q2 */ 1122 + /* Round up to a multiple of a page */ 1123 + nesqp->qp_mem_size += PAGE_SIZE - 1; 1124 + nesqp->qp_mem_size &= ~(PAGE_SIZE - 1); 1125 + 1126 + mem = pci_alloc_consistent(nesdev->pcidev, nesqp->qp_mem_size, 1127 + &nesqp->hwqp.q2_pbase); 1128 + 1129 + if (!mem) { 1130 + pci_free_consistent(nesdev->pcidev, 256, nesqp->pbl_vbase, nesqp->pbl_pbase); 1131 + nesqp->pbl_vbase = NULL; 1132 + spin_lock_irqsave(&nesadapter->pbl_lock, flags); 1133 + nesadapter->free_256pbl++; 1134 + spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); 1135 + kunmap(nesqp->page); 1136 + return -ENOMEM; 1137 + } 1138 + nesqp->hwqp.q2_vbase = mem; 1139 + mem += 256; 1140 + memset(nesqp->hwqp.q2_vbase, 0, 256); 1141 + nesqp->nesqp_context = mem; 1142 + memset(nesqp->nesqp_context, 0, sizeof(*nesqp->nesqp_context)); 1143 + nesqp->nesqp_context_pbase = nesqp->hwqp.q2_pbase + 256; 1144 + 1145 + return 0; 1146 + } 1147 + 1148 + 1149 + /** 1150 + * nes_setup_mmap_qp 1151 + */ 1152 + static int nes_setup_mmap_qp(struct nes_qp *nesqp, struct nes_vnic *nesvnic, 1153 + int sq_size, int rq_size) 1154 + { 1155 + void *mem; 1156 + struct nes_device *nesdev = nesvnic->nesdev; 1157 + 1158 + nesqp->qp_mem_size = (sizeof(struct nes_hw_qp_wqe) * sq_size) + 1159 + (sizeof(struct nes_hw_qp_wqe) * rq_size) + 1160 + max((u32)sizeof(struct nes_qp_context), ((u32)256)) + 1161 + 256; /* this is Q2 */ 1162 + /* Round up to a multiple of a page */ 1163 + nesqp->qp_mem_size += PAGE_SIZE - 1; 1164 + nesqp->qp_mem_size &= ~(PAGE_SIZE - 1); 1165 + 1166 + mem = pci_alloc_consistent(nesdev->pcidev, nesqp->qp_mem_size, 1167 + &nesqp->hwqp.sq_pbase); 1168 + if (!mem) 1169 + return -ENOMEM; 1170 + nes_debug(NES_DBG_QP, "PCI consistent memory for " 1171 + "host descriptor rings located @ %p (pa = 0x%08lX.) size = %u.\n", 1172 + mem, (unsigned long)nesqp->hwqp.sq_pbase, nesqp->qp_mem_size); 1173 + 1174 + memset(mem, 0, nesqp->qp_mem_size); 1175 + 1176 + nesqp->hwqp.sq_vbase = mem; 1177 + mem += sizeof(struct nes_hw_qp_wqe) * sq_size; 1178 + 1179 + nesqp->hwqp.rq_vbase = mem; 1180 + nesqp->hwqp.rq_pbase = nesqp->hwqp.sq_pbase + 1181 + sizeof(struct nes_hw_qp_wqe) * sq_size; 1182 + mem += sizeof(struct nes_hw_qp_wqe) * rq_size; 1183 + 1184 + nesqp->hwqp.q2_vbase = mem; 1185 + nesqp->hwqp.q2_pbase = nesqp->hwqp.rq_pbase + 1186 + sizeof(struct nes_hw_qp_wqe) * rq_size; 1187 + mem += 256; 1188 + memset(nesqp->hwqp.q2_vbase, 0, 256); 1189 + 1190 + nesqp->nesqp_context = mem; 1191 + nesqp->nesqp_context_pbase = nesqp->hwqp.q2_pbase + 256; 1192 + memset(nesqp->nesqp_context, 0, sizeof(*nesqp->nesqp_context)); 1193 + return 0; 1194 + } 1195 + 1196 + 1197 + /** 1198 + * nes_free_qp_mem() is to free up the qp's pci_alloc_consistent() memory. 1199 + */ 1200 + static inline void nes_free_qp_mem(struct nes_device *nesdev, 1201 + struct nes_qp *nesqp, int virt_wqs) 1202 + { 1203 + unsigned long flags; 1204 + struct nes_adapter *nesadapter = nesdev->nesadapter; 1205 + if (!virt_wqs) { 1206 + pci_free_consistent(nesdev->pcidev, nesqp->qp_mem_size, 1207 + nesqp->hwqp.sq_vbase, nesqp->hwqp.sq_pbase); 1208 + }else { 1209 + spin_lock_irqsave(&nesadapter->pbl_lock, flags); 1210 + nesadapter->free_256pbl++; 1211 + spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); 1212 + pci_free_consistent(nesdev->pcidev, nesqp->qp_mem_size, nesqp->hwqp.q2_vbase, nesqp->hwqp.q2_pbase); 1213 + pci_free_consistent(nesdev->pcidev, 256, nesqp->pbl_vbase, nesqp->pbl_pbase ); 1214 + nesqp->pbl_vbase = NULL; 1215 + kunmap(nesqp->page); 1216 + } 1217 + } 1218 + 1219 + 1220 + /** 1221 + * nes_create_qp 1222 + */ 1223 + static struct ib_qp *nes_create_qp(struct ib_pd *ibpd, 1224 + struct ib_qp_init_attr *init_attr, struct ib_udata *udata) 1225 + { 1226 + u64 u64temp= 0; 1227 + u64 u64nesqp = 0; 1228 + struct nes_pd *nespd = to_nespd(ibpd); 1229 + struct nes_vnic *nesvnic = to_nesvnic(ibpd->device); 1230 + struct nes_device *nesdev = nesvnic->nesdev; 1231 + struct nes_adapter *nesadapter = nesdev->nesadapter; 1232 + struct nes_qp *nesqp; 1233 + struct nes_cq *nescq; 1234 + struct nes_ucontext *nes_ucontext; 1235 + struct nes_hw_cqp_wqe *cqp_wqe; 1236 + struct nes_cqp_request *cqp_request; 1237 + struct nes_create_qp_req req; 1238 + struct nes_create_qp_resp uresp; 1239 + struct nes_pbl *nespbl = NULL; 1240 + u32 qp_num = 0; 1241 + u32 opcode = 0; 1242 + /* u32 counter = 0; */ 1243 + void *mem; 1244 + unsigned long flags; 1245 + int ret; 1246 + int err; 1247 + int virt_wqs = 0; 1248 + int sq_size; 1249 + int rq_size; 1250 + u8 sq_encoded_size; 1251 + u8 rq_encoded_size; 1252 + /* int counter; */ 1253 + 1254 + atomic_inc(&qps_created); 1255 + switch (init_attr->qp_type) { 1256 + case IB_QPT_RC: 1257 + if (nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) { 1258 + init_attr->cap.max_inline_data = 0; 1259 + } else { 1260 + init_attr->cap.max_inline_data = 64; 1261 + } 1262 + sq_size = init_attr->cap.max_send_wr; 1263 + rq_size = init_attr->cap.max_recv_wr; 1264 + 1265 + // check if the encoded sizes are OK or not... 1266 + sq_encoded_size = nes_get_encoded_size(&sq_size); 1267 + rq_encoded_size = nes_get_encoded_size(&rq_size); 1268 + 1269 + if ((!sq_encoded_size) || (!rq_encoded_size)) { 1270 + nes_debug(NES_DBG_QP, "ERROR bad rq (%u) or sq (%u) size\n", 1271 + rq_size, sq_size); 1272 + return ERR_PTR(-EINVAL); 1273 + } 1274 + 1275 + init_attr->cap.max_send_wr = sq_size -2; 1276 + init_attr->cap.max_recv_wr = rq_size -1; 1277 + nes_debug(NES_DBG_QP, "RQ size=%u, SQ Size=%u\n", rq_size, sq_size); 1278 + 1279 + ret = nes_alloc_resource(nesadapter, nesadapter->allocated_qps, 1280 + nesadapter->max_qp, &qp_num, &nesadapter->next_qp); 1281 + if (ret) { 1282 + return ERR_PTR(ret); 1283 + } 1284 + 1285 + /* Need 512 (actually now 1024) byte alignment on this structure */ 1286 + mem = kzalloc(sizeof(*nesqp)+NES_SW_CONTEXT_ALIGN-1, GFP_KERNEL); 1287 + if (!mem) { 1288 + nes_free_resource(nesadapter, nesadapter->allocated_qps, qp_num); 1289 + nes_debug(NES_DBG_QP, "Unable to allocate QP\n"); 1290 + return ERR_PTR(-ENOMEM); 1291 + } 1292 + u64nesqp = (unsigned long)mem; 1293 + u64nesqp += ((u64)NES_SW_CONTEXT_ALIGN) - 1; 1294 + u64temp = ((u64)NES_SW_CONTEXT_ALIGN) - 1; 1295 + u64nesqp &= ~u64temp; 1296 + nesqp = (struct nes_qp *)(unsigned long)u64nesqp; 1297 + /* nes_debug(NES_DBG_QP, "nesqp=%p, allocated buffer=%p. Rounded to closest %u\n", 1298 + nesqp, mem, NES_SW_CONTEXT_ALIGN); */ 1299 + nesqp->allocated_buffer = mem; 1300 + 1301 + if (udata) { 1302 + if (ib_copy_from_udata(&req, udata, sizeof(struct nes_create_qp_req))) { 1303 + nes_free_resource(nesadapter, nesadapter->allocated_qps, qp_num); 1304 + kfree(nesqp->allocated_buffer); 1305 + nes_debug(NES_DBG_QP, "ib_copy_from_udata() Failed \n"); 1306 + return NULL; 1307 + } 1308 + if (req.user_wqe_buffers) { 1309 + virt_wqs = 1; 1310 + } 1311 + if ((ibpd->uobject) && (ibpd->uobject->context)) { 1312 + nesqp->user_mode = 1; 1313 + nes_ucontext = to_nesucontext(ibpd->uobject->context); 1314 + if (virt_wqs) { 1315 + err = 1; 1316 + list_for_each_entry(nespbl, &nes_ucontext->qp_reg_mem_list, list) { 1317 + if (nespbl->user_base == (unsigned long )req.user_wqe_buffers) { 1318 + list_del(&nespbl->list); 1319 + err = 0; 1320 + nes_debug(NES_DBG_QP, "Found PBL for virtual QP. nespbl=%p. user_base=0x%lx\n", 1321 + nespbl, nespbl->user_base); 1322 + break; 1323 + } 1324 + } 1325 + if (err) { 1326 + nes_debug(NES_DBG_QP, "Didn't Find PBL for virtual QP. address = %llx.\n", 1327 + (long long unsigned int)req.user_wqe_buffers); 1328 + nes_free_resource(nesadapter, nesadapter->allocated_qps, qp_num); 1329 + kfree(nesqp->allocated_buffer); 1330 + return ERR_PTR(-ENOMEM); 1331 + } 1332 + } 1333 + 1334 + nes_ucontext = to_nesucontext(ibpd->uobject->context); 1335 + nesqp->mmap_sq_db_index = 1336 + find_next_zero_bit(nes_ucontext->allocated_wqs, 1337 + NES_MAX_USER_WQ_REGIONS, nes_ucontext->first_free_wq); 1338 + /* nes_debug(NES_DBG_QP, "find_first_zero_biton wqs returned %u\n", 1339 + nespd->mmap_db_index); */ 1340 + if (nesqp->mmap_sq_db_index > NES_MAX_USER_WQ_REGIONS) { 1341 + nes_debug(NES_DBG_QP, 1342 + "db index > max user regions, failing create QP\n"); 1343 + nes_free_resource(nesadapter, nesadapter->allocated_qps, qp_num); 1344 + if (virt_wqs) { 1345 + pci_free_consistent(nesdev->pcidev, nespbl->pbl_size, nespbl->pbl_vbase, 1346 + nespbl->pbl_pbase); 1347 + kfree(nespbl); 1348 + } 1349 + kfree(nesqp->allocated_buffer); 1350 + return ERR_PTR(-ENOMEM); 1351 + } 1352 + set_bit(nesqp->mmap_sq_db_index, nes_ucontext->allocated_wqs); 1353 + nes_ucontext->mmap_nesqp[nesqp->mmap_sq_db_index] = nesqp; 1354 + nes_ucontext->first_free_wq = nesqp->mmap_sq_db_index + 1; 1355 + } else { 1356 + nes_free_resource(nesadapter, nesadapter->allocated_qps, qp_num); 1357 + kfree(nesqp->allocated_buffer); 1358 + return ERR_PTR(-EFAULT); 1359 + } 1360 + } 1361 + err = (!virt_wqs) ? nes_setup_mmap_qp(nesqp, nesvnic, sq_size, rq_size) : 1362 + nes_setup_virt_qp(nesqp, nespbl, nesvnic, sq_size, rq_size); 1363 + if (err) { 1364 + nes_debug(NES_DBG_QP, 1365 + "error geting qp mem code = %d\n", err); 1366 + nes_free_resource(nesadapter, nesadapter->allocated_qps, qp_num); 1367 + kfree(nesqp->allocated_buffer); 1368 + return ERR_PTR(-ENOMEM); 1369 + } 1370 + 1371 + nesqp->hwqp.sq_size = sq_size; 1372 + nesqp->hwqp.sq_encoded_size = sq_encoded_size; 1373 + nesqp->hwqp.sq_head = 1; 1374 + nesqp->hwqp.rq_size = rq_size; 1375 + nesqp->hwqp.rq_encoded_size = rq_encoded_size; 1376 + /* nes_debug(NES_DBG_QP, "nesqp->nesqp_context_pbase = %p\n", 1377 + (void *)nesqp->nesqp_context_pbase); 1378 + */ 1379 + nesqp->hwqp.qp_id = qp_num; 1380 + nesqp->ibqp.qp_num = nesqp->hwqp.qp_id; 1381 + nesqp->nespd = nespd; 1382 + 1383 + nescq = to_nescq(init_attr->send_cq); 1384 + nesqp->nesscq = nescq; 1385 + nescq = to_nescq(init_attr->recv_cq); 1386 + nesqp->nesrcq = nescq; 1387 + 1388 + nesqp->nesqp_context->misc |= cpu_to_le32((u32)PCI_FUNC(nesdev->pcidev->devfn) << 1389 + NES_QPCONTEXT_MISC_PCI_FCN_SHIFT); 1390 + nesqp->nesqp_context->misc |= cpu_to_le32((u32)nesqp->hwqp.rq_encoded_size << 1391 + NES_QPCONTEXT_MISC_RQ_SIZE_SHIFT); 1392 + nesqp->nesqp_context->misc |= cpu_to_le32((u32)nesqp->hwqp.sq_encoded_size << 1393 + NES_QPCONTEXT_MISC_SQ_SIZE_SHIFT); 1394 + nesqp->nesqp_context->misc |= cpu_to_le32(NES_QPCONTEXT_MISC_PRIV_EN); 1395 + nesqp->nesqp_context->misc |= cpu_to_le32(NES_QPCONTEXT_MISC_FAST_REGISTER_EN); 1396 + nesqp->nesqp_context->cqs = cpu_to_le32(nesqp->nesscq->hw_cq.cq_number + 1397 + ((u32)nesqp->nesrcq->hw_cq.cq_number << 16)); 1398 + u64temp = (u64)nesqp->hwqp.sq_pbase; 1399 + nesqp->nesqp_context->sq_addr_low = cpu_to_le32((u32)u64temp); 1400 + nesqp->nesqp_context->sq_addr_high = cpu_to_le32((u32)(u64temp >> 32)); 1401 + 1402 + 1403 + if (!virt_wqs) { 1404 + u64temp = (u64)nesqp->hwqp.sq_pbase; 1405 + nesqp->nesqp_context->sq_addr_low = cpu_to_le32((u32)u64temp); 1406 + nesqp->nesqp_context->sq_addr_high = cpu_to_le32((u32)(u64temp >> 32)); 1407 + u64temp = (u64)nesqp->hwqp.rq_pbase; 1408 + nesqp->nesqp_context->rq_addr_low = cpu_to_le32((u32)u64temp); 1409 + nesqp->nesqp_context->rq_addr_high = cpu_to_le32((u32)(u64temp >> 32)); 1410 + } else { 1411 + u64temp = (u64)nesqp->pbl_pbase; 1412 + nesqp->nesqp_context->rq_addr_low = cpu_to_le32((u32)u64temp); 1413 + nesqp->nesqp_context->rq_addr_high = cpu_to_le32((u32)(u64temp >> 32)); 1414 + } 1415 + 1416 + /* nes_debug(NES_DBG_QP, "next_qp_nic_index=%u, using nic_index=%d\n", 1417 + nesvnic->next_qp_nic_index, 1418 + nesvnic->qp_nic_index[nesvnic->next_qp_nic_index]); */ 1419 + spin_lock_irqsave(&nesdev->cqp.lock, flags); 1420 + nesqp->nesqp_context->misc2 |= cpu_to_le32( 1421 + (u32)nesvnic->qp_nic_index[nesvnic->next_qp_nic_index] << 1422 + NES_QPCONTEXT_MISC2_NIC_INDEX_SHIFT); 1423 + nesvnic->next_qp_nic_index++; 1424 + if ((nesvnic->next_qp_nic_index > 3) || 1425 + (nesvnic->qp_nic_index[nesvnic->next_qp_nic_index] == 0xf)) { 1426 + nesvnic->next_qp_nic_index = 0; 1427 + } 1428 + spin_unlock_irqrestore(&nesdev->cqp.lock, flags); 1429 + 1430 + nesqp->nesqp_context->pd_index_wscale |= cpu_to_le32((u32)nesqp->nespd->pd_id << 16); 1431 + u64temp = (u64)nesqp->hwqp.q2_pbase; 1432 + nesqp->nesqp_context->q2_addr_low = cpu_to_le32((u32)u64temp); 1433 + nesqp->nesqp_context->q2_addr_high = cpu_to_le32((u32)(u64temp >> 32)); 1434 + nesqp->nesqp_context->aeq_token_low = cpu_to_le32((u32)((unsigned long)(nesqp))); 1435 + nesqp->nesqp_context->aeq_token_high = cpu_to_le32((u32)(upper_32_bits((unsigned long)(nesqp)))); 1436 + nesqp->nesqp_context->ird_ord_sizes = cpu_to_le32(NES_QPCONTEXT_ORDIRD_ALSMM | 1437 + ((((u32)nesadapter->max_irrq_wr) << 1438 + NES_QPCONTEXT_ORDIRD_IRDSIZE_SHIFT) & NES_QPCONTEXT_ORDIRD_IRDSIZE_MASK)); 1439 + if (disable_mpa_crc) { 1440 + nes_debug(NES_DBG_QP, "Disabling MPA crc checking due to module option.\n"); 1441 + nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32(NES_QPCONTEXT_ORDIRD_RNMC); 1442 + } 1443 + 1444 + 1445 + /* Create the QP */ 1446 + cqp_request = nes_get_cqp_request(nesdev); 1447 + if (cqp_request == NULL) { 1448 + nes_debug(NES_DBG_QP, "Failed to get a cqp_request\n"); 1449 + nes_free_resource(nesadapter, nesadapter->allocated_qps, qp_num); 1450 + nes_free_qp_mem(nesdev, nesqp,virt_wqs); 1451 + kfree(nesqp->allocated_buffer); 1452 + return ERR_PTR(-ENOMEM); 1453 + } 1454 + cqp_request->waiting = 1; 1455 + cqp_wqe = &cqp_request->cqp_wqe; 1456 + 1457 + if (!virt_wqs) { 1458 + opcode = NES_CQP_CREATE_QP | NES_CQP_QP_TYPE_IWARP | 1459 + NES_CQP_QP_IWARP_STATE_IDLE; 1460 + } else { 1461 + opcode = NES_CQP_CREATE_QP | NES_CQP_QP_TYPE_IWARP | NES_CQP_QP_VIRT_WQS | 1462 + NES_CQP_QP_IWARP_STATE_IDLE; 1463 + } 1464 + opcode |= NES_CQP_QP_CQS_VALID; 1465 + nes_fill_init_cqp_wqe(cqp_wqe, nesdev); 1466 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX, opcode); 1467 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_ID_IDX, nesqp->hwqp.qp_id); 1468 + 1469 + u64temp = (u64)nesqp->nesqp_context_pbase; 1470 + set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_QP_WQE_CONTEXT_LOW_IDX, u64temp); 1471 + 1472 + atomic_set(&cqp_request->refcount, 2); 1473 + nes_post_cqp_request(nesdev, cqp_request, NES_CQP_REQUEST_RING_DOORBELL); 1474 + 1475 + /* Wait for CQP */ 1476 + nes_debug(NES_DBG_QP, "Waiting for create iWARP QP%u to complete.\n", 1477 + nesqp->hwqp.qp_id); 1478 + ret = wait_event_timeout(cqp_request->waitq, 1479 + (cqp_request->request_done != 0), NES_EVENT_TIMEOUT); 1480 + nes_debug(NES_DBG_QP, "Create iwarp QP%u completed, wait_event_timeout ret=%u," 1481 + " nesdev->cqp_head = %u, nesdev->cqp.sq_tail = %u," 1482 + " CQP Major:Minor codes = 0x%04X:0x%04X.\n", 1483 + nesqp->hwqp.qp_id, ret, nesdev->cqp.sq_head, nesdev->cqp.sq_tail, 1484 + cqp_request->major_code, cqp_request->minor_code); 1485 + if ((!ret) || (cqp_request->major_code)) { 1486 + if (atomic_dec_and_test(&cqp_request->refcount)) { 1487 + if (cqp_request->dynamic) { 1488 + kfree(cqp_request); 1489 + } else { 1490 + spin_lock_irqsave(&nesdev->cqp.lock, flags); 1491 + list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); 1492 + spin_unlock_irqrestore(&nesdev->cqp.lock, flags); 1493 + } 1494 + } 1495 + nes_free_resource(nesadapter, nesadapter->allocated_qps, qp_num); 1496 + nes_free_qp_mem(nesdev, nesqp,virt_wqs); 1497 + kfree(nesqp->allocated_buffer); 1498 + if (!ret) { 1499 + return ERR_PTR(-ETIME); 1500 + } else { 1501 + return ERR_PTR(-EIO); 1502 + } 1503 + } else { 1504 + if (atomic_dec_and_test(&cqp_request->refcount)) { 1505 + if (cqp_request->dynamic) { 1506 + kfree(cqp_request); 1507 + } else { 1508 + spin_lock_irqsave(&nesdev->cqp.lock, flags); 1509 + list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); 1510 + spin_unlock_irqrestore(&nesdev->cqp.lock, flags); 1511 + } 1512 + } 1513 + } 1514 + 1515 + if (ibpd->uobject) { 1516 + uresp.mmap_sq_db_index = nesqp->mmap_sq_db_index; 1517 + uresp.actual_sq_size = sq_size; 1518 + uresp.actual_rq_size = rq_size; 1519 + uresp.qp_id = nesqp->hwqp.qp_id; 1520 + uresp.nes_drv_opt = nes_drv_opt; 1521 + if (ib_copy_to_udata(udata, &uresp, sizeof uresp)) { 1522 + nes_free_resource(nesadapter, nesadapter->allocated_qps, qp_num); 1523 + nes_free_qp_mem(nesdev, nesqp,virt_wqs); 1524 + kfree(nesqp->allocated_buffer); 1525 + return ERR_PTR(-EFAULT); 1526 + } 1527 + } 1528 + 1529 + nes_debug(NES_DBG_QP, "QP%u structure located @%p.Size = %u.\n", 1530 + nesqp->hwqp.qp_id, nesqp, (u32)sizeof(*nesqp)); 1531 + spin_lock_init(&nesqp->lock); 1532 + init_waitqueue_head(&nesqp->state_waitq); 1533 + init_waitqueue_head(&nesqp->kick_waitq); 1534 + nes_add_ref(&nesqp->ibqp); 1535 + break; 1536 + default: 1537 + nes_debug(NES_DBG_QP, "Invalid QP type: %d\n", init_attr->qp_type); 1538 + return ERR_PTR(-EINVAL); 1539 + break; 1540 + } 1541 + 1542 + /* update the QP table */ 1543 + nesdev->nesadapter->qp_table[nesqp->hwqp.qp_id-NES_FIRST_QPN] = nesqp; 1544 + nes_debug(NES_DBG_QP, "netdev refcnt=%u\n", 1545 + atomic_read(&nesvnic->netdev->refcnt)); 1546 + 1547 + return &nesqp->ibqp; 1548 + } 1549 + 1550 + 1551 + /** 1552 + * nes_destroy_qp 1553 + */ 1554 + static int nes_destroy_qp(struct ib_qp *ibqp) 1555 + { 1556 + struct nes_qp *nesqp = to_nesqp(ibqp); 1557 + /* struct nes_vnic *nesvnic = to_nesvnic(ibqp->device); */ 1558 + struct nes_ucontext *nes_ucontext; 1559 + struct ib_qp_attr attr; 1560 + struct iw_cm_id *cm_id; 1561 + struct iw_cm_event cm_event; 1562 + int ret; 1563 + 1564 + atomic_inc(&sw_qps_destroyed); 1565 + nesqp->destroyed = 1; 1566 + 1567 + /* Blow away the connection if it exists. */ 1568 + if (nesqp->ibqp_state >= IB_QPS_INIT && nesqp->ibqp_state <= IB_QPS_RTS) { 1569 + /* if (nesqp->ibqp_state == IB_QPS_RTS) { */ 1570 + attr.qp_state = IB_QPS_ERR; 1571 + nes_modify_qp(&nesqp->ibqp, &attr, IB_QP_STATE, NULL); 1572 + } 1573 + 1574 + if (((nesqp->ibqp_state == IB_QPS_INIT) || 1575 + (nesqp->ibqp_state == IB_QPS_RTR)) && (nesqp->cm_id)) { 1576 + cm_id = nesqp->cm_id; 1577 + cm_event.event = IW_CM_EVENT_CONNECT_REPLY; 1578 + cm_event.status = IW_CM_EVENT_STATUS_TIMEOUT; 1579 + cm_event.local_addr = cm_id->local_addr; 1580 + cm_event.remote_addr = cm_id->remote_addr; 1581 + cm_event.private_data = NULL; 1582 + cm_event.private_data_len = 0; 1583 + 1584 + nes_debug(NES_DBG_QP, "Generating a CM Timeout Event for " 1585 + "QP%u. cm_id = %p, refcount = %u. \n", 1586 + nesqp->hwqp.qp_id, cm_id, atomic_read(&nesqp->refcount)); 1587 + 1588 + cm_id->rem_ref(cm_id); 1589 + ret = cm_id->event_handler(cm_id, &cm_event); 1590 + if (ret) 1591 + nes_debug(NES_DBG_QP, "OFA CM event_handler returned, ret=%d\n", ret); 1592 + } 1593 + 1594 + 1595 + if (nesqp->user_mode) { 1596 + if ((ibqp->uobject)&&(ibqp->uobject->context)) { 1597 + nes_ucontext = to_nesucontext(ibqp->uobject->context); 1598 + clear_bit(nesqp->mmap_sq_db_index, nes_ucontext->allocated_wqs); 1599 + nes_ucontext->mmap_nesqp[nesqp->mmap_sq_db_index] = NULL; 1600 + if (nes_ucontext->first_free_wq > nesqp->mmap_sq_db_index) { 1601 + nes_ucontext->first_free_wq = nesqp->mmap_sq_db_index; 1602 + } 1603 + } 1604 + if (nesqp->pbl_pbase) 1605 + kunmap(nesqp->page); 1606 + } 1607 + 1608 + nes_rem_ref(&nesqp->ibqp); 1609 + return 0; 1610 + } 1611 + 1612 + 1613 + /** 1614 + * nes_create_cq 1615 + */ 1616 + static struct ib_cq *nes_create_cq(struct ib_device *ibdev, int entries, 1617 + int comp_vector, 1618 + struct ib_ucontext *context, struct ib_udata *udata) 1619 + { 1620 + u64 u64temp; 1621 + struct nes_vnic *nesvnic = to_nesvnic(ibdev); 1622 + struct nes_device *nesdev = nesvnic->nesdev; 1623 + struct nes_adapter *nesadapter = nesdev->nesadapter; 1624 + struct nes_cq *nescq; 1625 + struct nes_ucontext *nes_ucontext = NULL; 1626 + struct nes_cqp_request *cqp_request; 1627 + void *mem = NULL; 1628 + struct nes_hw_cqp_wqe *cqp_wqe; 1629 + struct nes_pbl *nespbl = NULL; 1630 + struct nes_create_cq_req req; 1631 + struct nes_create_cq_resp resp; 1632 + u32 cq_num = 0; 1633 + u32 opcode = 0; 1634 + u32 pbl_entries = 1; 1635 + int err; 1636 + unsigned long flags; 1637 + int ret; 1638 + 1639 + err = nes_alloc_resource(nesadapter, nesadapter->allocated_cqs, 1640 + nesadapter->max_cq, &cq_num, &nesadapter->next_cq); 1641 + if (err) { 1642 + return ERR_PTR(err); 1643 + } 1644 + 1645 + nescq = kzalloc(sizeof(struct nes_cq), GFP_KERNEL); 1646 + if (!nescq) { 1647 + nes_free_resource(nesadapter, nesadapter->allocated_cqs, cq_num); 1648 + nes_debug(NES_DBG_CQ, "Unable to allocate nes_cq struct\n"); 1649 + return ERR_PTR(-ENOMEM); 1650 + } 1651 + 1652 + nescq->hw_cq.cq_size = max(entries + 1, 5); 1653 + nescq->hw_cq.cq_number = cq_num; 1654 + nescq->ibcq.cqe = nescq->hw_cq.cq_size - 1; 1655 + 1656 + 1657 + if (context) { 1658 + nes_ucontext = to_nesucontext(context); 1659 + if (ib_copy_from_udata(&req, udata, sizeof (struct nes_create_cq_req))) { 1660 + nes_free_resource(nesadapter, nesadapter->allocated_cqs, cq_num); 1661 + kfree(nescq); 1662 + return ERR_PTR(-EFAULT); 1663 + } 1664 + nesvnic->mcrq_ucontext = nes_ucontext; 1665 + nes_ucontext->mcrqf = req.mcrqf; 1666 + if (nes_ucontext->mcrqf) { 1667 + if (nes_ucontext->mcrqf & 0x80000000) 1668 + nescq->hw_cq.cq_number = nesvnic->nic.qp_id + 12 + (nes_ucontext->mcrqf & 0xf) - 1; 1669 + else if (nes_ucontext->mcrqf & 0x40000000) 1670 + nescq->hw_cq.cq_number = nes_ucontext->mcrqf & 0xffff; 1671 + else 1672 + nescq->hw_cq.cq_number = nesvnic->mcrq_qp_id + nes_ucontext->mcrqf-1; 1673 + nes_free_resource(nesadapter, nesadapter->allocated_cqs, cq_num); 1674 + } 1675 + nes_debug(NES_DBG_CQ, "CQ Virtual Address = %08lX, size = %u.\n", 1676 + (unsigned long)req.user_cq_buffer, entries); 1677 + list_for_each_entry(nespbl, &nes_ucontext->cq_reg_mem_list, list) { 1678 + if (nespbl->user_base == (unsigned long )req.user_cq_buffer) { 1679 + list_del(&nespbl->list); 1680 + err = 0; 1681 + nes_debug(NES_DBG_CQ, "Found PBL for virtual CQ. nespbl=%p.\n", 1682 + nespbl); 1683 + break; 1684 + } 1685 + } 1686 + if (err) { 1687 + nes_free_resource(nesadapter, nesadapter->allocated_cqs, cq_num); 1688 + kfree(nescq); 1689 + return ERR_PTR(err); 1690 + } 1691 + 1692 + pbl_entries = nespbl->pbl_size >> 3; 1693 + nescq->cq_mem_size = 0; 1694 + } else { 1695 + nescq->cq_mem_size = nescq->hw_cq.cq_size * sizeof(struct nes_hw_cqe); 1696 + nes_debug(NES_DBG_CQ, "Attempting to allocate pci memory (%u entries, %u bytes) for CQ%u.\n", 1697 + entries, nescq->cq_mem_size, nescq->hw_cq.cq_number); 1698 + 1699 + /* allocate the physical buffer space */ 1700 + mem = pci_alloc_consistent(nesdev->pcidev, nescq->cq_mem_size, 1701 + &nescq->hw_cq.cq_pbase); 1702 + if (!mem) { 1703 + printk(KERN_ERR PFX "Unable to allocate pci memory for cq\n"); 1704 + nes_free_resource(nesadapter, nesadapter->allocated_cqs, cq_num); 1705 + kfree(nescq); 1706 + return ERR_PTR(-ENOMEM); 1707 + } 1708 + 1709 + memset(mem, 0, nescq->cq_mem_size); 1710 + nescq->hw_cq.cq_vbase = mem; 1711 + nescq->hw_cq.cq_head = 0; 1712 + nes_debug(NES_DBG_CQ, "CQ%u virtual address @ %p, phys = 0x%08X\n", 1713 + nescq->hw_cq.cq_number, nescq->hw_cq.cq_vbase, 1714 + (u32)nescq->hw_cq.cq_pbase); 1715 + } 1716 + 1717 + nescq->hw_cq.ce_handler = nes_iwarp_ce_handler; 1718 + spin_lock_init(&nescq->lock); 1719 + 1720 + /* send CreateCQ request to CQP */ 1721 + cqp_request = nes_get_cqp_request(nesdev); 1722 + if (cqp_request == NULL) { 1723 + nes_debug(NES_DBG_CQ, "Failed to get a cqp_request.\n"); 1724 + if (!context) 1725 + pci_free_consistent(nesdev->pcidev, nescq->cq_mem_size, mem, 1726 + nescq->hw_cq.cq_pbase); 1727 + nes_free_resource(nesadapter, nesadapter->allocated_cqs, cq_num); 1728 + kfree(nescq); 1729 + return ERR_PTR(-ENOMEM); 1730 + } 1731 + cqp_request->waiting = 1; 1732 + cqp_wqe = &cqp_request->cqp_wqe; 1733 + 1734 + opcode = NES_CQP_CREATE_CQ | NES_CQP_CQ_CEQ_VALID | 1735 + NES_CQP_CQ_CHK_OVERFLOW | 1736 + NES_CQP_CQ_CEQE_MASK | ((u32)nescq->hw_cq.cq_size << 16); 1737 + 1738 + spin_lock_irqsave(&nesadapter->pbl_lock, flags); 1739 + 1740 + if (pbl_entries != 1) { 1741 + if (pbl_entries > 32) { 1742 + /* use 4k pbl */ 1743 + nes_debug(NES_DBG_CQ, "pbl_entries=%u, use a 4k PBL\n", pbl_entries); 1744 + if (nesadapter->free_4kpbl == 0) { 1745 + if (cqp_request->dynamic) { 1746 + spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); 1747 + kfree(cqp_request); 1748 + } else { 1749 + list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); 1750 + spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); 1751 + } 1752 + if (!context) 1753 + pci_free_consistent(nesdev->pcidev, nescq->cq_mem_size, mem, 1754 + nescq->hw_cq.cq_pbase); 1755 + nes_free_resource(nesadapter, nesadapter->allocated_cqs, cq_num); 1756 + kfree(nescq); 1757 + return ERR_PTR(-ENOMEM); 1758 + } else { 1759 + opcode |= (NES_CQP_CQ_VIRT | NES_CQP_CQ_4KB_CHUNK); 1760 + nescq->virtual_cq = 2; 1761 + nesadapter->free_4kpbl--; 1762 + } 1763 + } else { 1764 + /* use 256 byte pbl */ 1765 + nes_debug(NES_DBG_CQ, "pbl_entries=%u, use a 256 byte PBL\n", pbl_entries); 1766 + if (nesadapter->free_256pbl == 0) { 1767 + if (cqp_request->dynamic) { 1768 + spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); 1769 + kfree(cqp_request); 1770 + } else { 1771 + list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); 1772 + spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); 1773 + } 1774 + if (!context) 1775 + pci_free_consistent(nesdev->pcidev, nescq->cq_mem_size, mem, 1776 + nescq->hw_cq.cq_pbase); 1777 + nes_free_resource(nesadapter, nesadapter->allocated_cqs, cq_num); 1778 + kfree(nescq); 1779 + return ERR_PTR(-ENOMEM); 1780 + } else { 1781 + opcode |= NES_CQP_CQ_VIRT; 1782 + nescq->virtual_cq = 1; 1783 + nesadapter->free_256pbl--; 1784 + } 1785 + } 1786 + } 1787 + 1788 + spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); 1789 + 1790 + nes_fill_init_cqp_wqe(cqp_wqe, nesdev); 1791 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX, opcode); 1792 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_ID_IDX, 1793 + (nescq->hw_cq.cq_number | ((u32)nesdev->ceq_index << 16))); 1794 + 1795 + if (context) { 1796 + if (pbl_entries != 1) 1797 + u64temp = (u64)nespbl->pbl_pbase; 1798 + else 1799 + u64temp = le64_to_cpu(nespbl->pbl_vbase[0]); 1800 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_CQ_WQE_DOORBELL_INDEX_HIGH_IDX, 1801 + nes_ucontext->mmap_db_index[0]); 1802 + } else { 1803 + u64temp = (u64)nescq->hw_cq.cq_pbase; 1804 + cqp_wqe->wqe_words[NES_CQP_CQ_WQE_DOORBELL_INDEX_HIGH_IDX] = 0; 1805 + } 1806 + set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_CQ_WQE_PBL_LOW_IDX, u64temp); 1807 + cqp_wqe->wqe_words[NES_CQP_CQ_WQE_CQ_CONTEXT_HIGH_IDX] = 0; 1808 + u64temp = (u64)(unsigned long)&nescq->hw_cq; 1809 + cqp_wqe->wqe_words[NES_CQP_CQ_WQE_CQ_CONTEXT_LOW_IDX] = 1810 + cpu_to_le32((u32)(u64temp >> 1)); 1811 + cqp_wqe->wqe_words[NES_CQP_CQ_WQE_CQ_CONTEXT_HIGH_IDX] = 1812 + cpu_to_le32(((u32)((u64temp) >> 33)) & 0x7FFFFFFF); 1813 + 1814 + atomic_set(&cqp_request->refcount, 2); 1815 + nes_post_cqp_request(nesdev, cqp_request, NES_CQP_REQUEST_RING_DOORBELL); 1816 + 1817 + /* Wait for CQP */ 1818 + nes_debug(NES_DBG_CQ, "Waiting for create iWARP CQ%u to complete.\n", 1819 + nescq->hw_cq.cq_number); 1820 + ret = wait_event_timeout(cqp_request->waitq, (0 != cqp_request->request_done), 1821 + NES_EVENT_TIMEOUT * 2); 1822 + nes_debug(NES_DBG_CQ, "Create iWARP CQ%u completed, wait_event_timeout ret = %d.\n", 1823 + nescq->hw_cq.cq_number, ret); 1824 + if ((!ret) || (cqp_request->major_code)) { 1825 + if (atomic_dec_and_test(&cqp_request->refcount)) { 1826 + if (cqp_request->dynamic) { 1827 + kfree(cqp_request); 1828 + } else { 1829 + spin_lock_irqsave(&nesdev->cqp.lock, flags); 1830 + list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); 1831 + spin_unlock_irqrestore(&nesdev->cqp.lock, flags); 1832 + } 1833 + } 1834 + nes_debug(NES_DBG_CQ, "iWARP CQ%u create timeout expired, major code = 0x%04X," 1835 + " minor code = 0x%04X\n", 1836 + nescq->hw_cq.cq_number, cqp_request->major_code, cqp_request->minor_code); 1837 + if (!context) 1838 + pci_free_consistent(nesdev->pcidev, nescq->cq_mem_size, mem, 1839 + nescq->hw_cq.cq_pbase); 1840 + nes_free_resource(nesadapter, nesadapter->allocated_cqs, cq_num); 1841 + kfree(nescq); 1842 + return ERR_PTR(-EIO); 1843 + } else { 1844 + if (atomic_dec_and_test(&cqp_request->refcount)) { 1845 + if (cqp_request->dynamic) { 1846 + kfree(cqp_request); 1847 + } else { 1848 + spin_lock_irqsave(&nesdev->cqp.lock, flags); 1849 + list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); 1850 + spin_unlock_irqrestore(&nesdev->cqp.lock, flags); 1851 + } 1852 + } 1853 + } 1854 + 1855 + if (context) { 1856 + /* free the nespbl */ 1857 + pci_free_consistent(nesdev->pcidev, nespbl->pbl_size, nespbl->pbl_vbase, 1858 + nespbl->pbl_pbase); 1859 + kfree(nespbl); 1860 + resp.cq_id = nescq->hw_cq.cq_number; 1861 + resp.cq_size = nescq->hw_cq.cq_size; 1862 + resp.mmap_db_index = 0; 1863 + if (ib_copy_to_udata(udata, &resp, sizeof resp)) { 1864 + nes_free_resource(nesadapter, nesadapter->allocated_cqs, cq_num); 1865 + kfree(nescq); 1866 + return ERR_PTR(-EFAULT); 1867 + } 1868 + } 1869 + 1870 + return &nescq->ibcq; 1871 + } 1872 + 1873 + 1874 + /** 1875 + * nes_destroy_cq 1876 + */ 1877 + static int nes_destroy_cq(struct ib_cq *ib_cq) 1878 + { 1879 + struct nes_cq *nescq; 1880 + struct nes_device *nesdev; 1881 + struct nes_vnic *nesvnic; 1882 + struct nes_adapter *nesadapter; 1883 + struct nes_hw_cqp_wqe *cqp_wqe; 1884 + struct nes_cqp_request *cqp_request; 1885 + unsigned long flags; 1886 + u32 opcode = 0; 1887 + int ret; 1888 + 1889 + if (ib_cq == NULL) 1890 + return 0; 1891 + 1892 + nescq = to_nescq(ib_cq); 1893 + nesvnic = to_nesvnic(ib_cq->device); 1894 + nesdev = nesvnic->nesdev; 1895 + nesadapter = nesdev->nesadapter; 1896 + 1897 + nes_debug(NES_DBG_CQ, "Destroy CQ%u\n", nescq->hw_cq.cq_number); 1898 + 1899 + /* Send DestroyCQ request to CQP */ 1900 + cqp_request = nes_get_cqp_request(nesdev); 1901 + if (cqp_request == NULL) { 1902 + nes_debug(NES_DBG_CQ, "Failed to get a cqp_request.\n"); 1903 + return -ENOMEM; 1904 + } 1905 + cqp_request->waiting = 1; 1906 + cqp_wqe = &cqp_request->cqp_wqe; 1907 + opcode = NES_CQP_DESTROY_CQ | (nescq->hw_cq.cq_size << 16); 1908 + spin_lock_irqsave(&nesadapter->pbl_lock, flags); 1909 + if (nescq->virtual_cq == 1) { 1910 + nesadapter->free_256pbl++; 1911 + if (nesadapter->free_256pbl > nesadapter->max_256pbl) { 1912 + printk(KERN_ERR PFX "%s: free 256B PBLs(%u) has exceeded the max(%u)\n", 1913 + __FUNCTION__, nesadapter->free_256pbl, nesadapter->max_256pbl); 1914 + } 1915 + } else if (nescq->virtual_cq == 2) { 1916 + nesadapter->free_4kpbl++; 1917 + if (nesadapter->free_4kpbl > nesadapter->max_4kpbl) { 1918 + printk(KERN_ERR PFX "%s: free 4K PBLs(%u) has exceeded the max(%u)\n", 1919 + __FUNCTION__, nesadapter->free_4kpbl, nesadapter->max_4kpbl); 1920 + } 1921 + opcode |= NES_CQP_CQ_4KB_CHUNK; 1922 + } 1923 + 1924 + spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); 1925 + 1926 + nes_fill_init_cqp_wqe(cqp_wqe, nesdev); 1927 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX, opcode); 1928 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_ID_IDX, 1929 + (nescq->hw_cq.cq_number | ((u32)PCI_FUNC(nesdev->pcidev->devfn) << 16))); 1930 + nes_free_resource(nesadapter, nesadapter->allocated_cqs, nescq->hw_cq.cq_number); 1931 + atomic_set(&cqp_request->refcount, 2); 1932 + nes_post_cqp_request(nesdev, cqp_request, NES_CQP_REQUEST_RING_DOORBELL); 1933 + 1934 + /* Wait for CQP */ 1935 + nes_debug(NES_DBG_CQ, "Waiting for destroy iWARP CQ%u to complete.\n", 1936 + nescq->hw_cq.cq_number); 1937 + ret = wait_event_timeout(cqp_request->waitq, (0 != cqp_request->request_done), 1938 + NES_EVENT_TIMEOUT); 1939 + nes_debug(NES_DBG_CQ, "Destroy iWARP CQ%u completed, wait_event_timeout ret = %u," 1940 + " CQP Major:Minor codes = 0x%04X:0x%04X.\n", 1941 + nescq->hw_cq.cq_number, ret, cqp_request->major_code, 1942 + cqp_request->minor_code); 1943 + if ((!ret) || (cqp_request->major_code)) { 1944 + if (atomic_dec_and_test(&cqp_request->refcount)) { 1945 + if (cqp_request->dynamic) { 1946 + kfree(cqp_request); 1947 + } else { 1948 + spin_lock_irqsave(&nesdev->cqp.lock, flags); 1949 + list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); 1950 + spin_unlock_irqrestore(&nesdev->cqp.lock, flags); 1951 + } 1952 + } 1953 + if (!ret) { 1954 + nes_debug(NES_DBG_CQ, "iWARP CQ%u destroy timeout expired\n", 1955 + nescq->hw_cq.cq_number); 1956 + ret = -ETIME; 1957 + } else { 1958 + nes_debug(NES_DBG_CQ, "iWARP CQ%u destroy failed\n", 1959 + nescq->hw_cq.cq_number); 1960 + ret = -EIO; 1961 + } 1962 + } else { 1963 + ret = 0; 1964 + if (atomic_dec_and_test(&cqp_request->refcount)) { 1965 + if (cqp_request->dynamic) { 1966 + kfree(cqp_request); 1967 + } else { 1968 + spin_lock_irqsave(&nesdev->cqp.lock, flags); 1969 + list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); 1970 + spin_unlock_irqrestore(&nesdev->cqp.lock, flags); 1971 + } 1972 + } 1973 + } 1974 + 1975 + if (nescq->cq_mem_size) 1976 + pci_free_consistent(nesdev->pcidev, nescq->cq_mem_size, 1977 + (void *)nescq->hw_cq.cq_vbase, nescq->hw_cq.cq_pbase); 1978 + kfree(nescq); 1979 + 1980 + return ret; 1981 + } 1982 + 1983 + 1984 + /** 1985 + * nes_reg_mr 1986 + */ 1987 + static int nes_reg_mr(struct nes_device *nesdev, struct nes_pd *nespd, 1988 + u32 stag, u64 region_length, struct nes_root_vpbl *root_vpbl, 1989 + dma_addr_t single_buffer, u16 pbl_count, u16 residual_page_count, 1990 + int acc, u64 *iova_start) 1991 + { 1992 + struct nes_hw_cqp_wqe *cqp_wqe; 1993 + struct nes_cqp_request *cqp_request; 1994 + unsigned long flags; 1995 + int ret; 1996 + struct nes_adapter *nesadapter = nesdev->nesadapter; 1997 + /* int count; */ 1998 + u32 opcode = 0; 1999 + u16 major_code; 2000 + 2001 + /* Register the region with the adapter */ 2002 + cqp_request = nes_get_cqp_request(nesdev); 2003 + if (cqp_request == NULL) { 2004 + nes_debug(NES_DBG_MR, "Failed to get a cqp_request.\n"); 2005 + return -ENOMEM; 2006 + } 2007 + cqp_request->waiting = 1; 2008 + cqp_wqe = &cqp_request->cqp_wqe; 2009 + 2010 + spin_lock_irqsave(&nesadapter->pbl_lock, flags); 2011 + /* track PBL resources */ 2012 + if (pbl_count != 0) { 2013 + if (pbl_count > 1) { 2014 + /* Two level PBL */ 2015 + if ((pbl_count+1) > nesadapter->free_4kpbl) { 2016 + nes_debug(NES_DBG_MR, "Out of 4KB Pbls for two level request.\n"); 2017 + if (cqp_request->dynamic) { 2018 + spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); 2019 + kfree(cqp_request); 2020 + } else { 2021 + list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); 2022 + spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); 2023 + } 2024 + return -ENOMEM; 2025 + } else { 2026 + nesadapter->free_4kpbl -= pbl_count+1; 2027 + } 2028 + } else if (residual_page_count > 32) { 2029 + if (pbl_count > nesadapter->free_4kpbl) { 2030 + nes_debug(NES_DBG_MR, "Out of 4KB Pbls.\n"); 2031 + if (cqp_request->dynamic) { 2032 + spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); 2033 + kfree(cqp_request); 2034 + } else { 2035 + list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); 2036 + spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); 2037 + } 2038 + return -ENOMEM; 2039 + } else { 2040 + nesadapter->free_4kpbl -= pbl_count; 2041 + } 2042 + } else { 2043 + if (pbl_count > nesadapter->free_256pbl) { 2044 + nes_debug(NES_DBG_MR, "Out of 256B Pbls.\n"); 2045 + if (cqp_request->dynamic) { 2046 + spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); 2047 + kfree(cqp_request); 2048 + } else { 2049 + list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); 2050 + spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); 2051 + } 2052 + return -ENOMEM; 2053 + } else { 2054 + nesadapter->free_256pbl -= pbl_count; 2055 + } 2056 + } 2057 + } 2058 + 2059 + spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); 2060 + 2061 + opcode = NES_CQP_REGISTER_STAG | NES_CQP_STAG_RIGHTS_LOCAL_READ | 2062 + NES_CQP_STAG_VA_TO | NES_CQP_STAG_MR; 2063 + if (acc & IB_ACCESS_LOCAL_WRITE) 2064 + opcode |= NES_CQP_STAG_RIGHTS_LOCAL_WRITE; 2065 + if (acc & IB_ACCESS_REMOTE_WRITE) 2066 + opcode |= NES_CQP_STAG_RIGHTS_REMOTE_WRITE | NES_CQP_STAG_REM_ACC_EN; 2067 + if (acc & IB_ACCESS_REMOTE_READ) 2068 + opcode |= NES_CQP_STAG_RIGHTS_REMOTE_READ | NES_CQP_STAG_REM_ACC_EN; 2069 + if (acc & IB_ACCESS_MW_BIND) 2070 + opcode |= NES_CQP_STAG_RIGHTS_WINDOW_BIND | NES_CQP_STAG_REM_ACC_EN; 2071 + 2072 + nes_fill_init_cqp_wqe(cqp_wqe, nesdev); 2073 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX, opcode); 2074 + set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_VA_LOW_IDX, *iova_start); 2075 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_LEN_LOW_IDX, region_length); 2076 + 2077 + cqp_wqe->wqe_words[NES_CQP_STAG_WQE_LEN_HIGH_PD_IDX] = 2078 + cpu_to_le32((u32)(region_length >> 8) & 0xff000000); 2079 + cqp_wqe->wqe_words[NES_CQP_STAG_WQE_LEN_HIGH_PD_IDX] |= 2080 + cpu_to_le32(nespd->pd_id & 0x00007fff); 2081 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_STAG_IDX, stag); 2082 + 2083 + if (pbl_count == 0) { 2084 + set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_PA_LOW_IDX, single_buffer); 2085 + } else { 2086 + set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_PA_LOW_IDX, root_vpbl->pbl_pbase); 2087 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_PBL_BLK_COUNT_IDX, pbl_count); 2088 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_PBL_LEN_IDX, 2089 + (((pbl_count - 1) * 4096) + (residual_page_count*8))); 2090 + 2091 + if ((pbl_count > 1) || (residual_page_count > 32)) 2092 + cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] |= cpu_to_le32(NES_CQP_STAG_PBL_BLK_SIZE); 2093 + } 2094 + barrier(); 2095 + 2096 + atomic_set(&cqp_request->refcount, 2); 2097 + nes_post_cqp_request(nesdev, cqp_request, NES_CQP_REQUEST_RING_DOORBELL); 2098 + 2099 + /* Wait for CQP */ 2100 + ret = wait_event_timeout(cqp_request->waitq, (0 != cqp_request->request_done), 2101 + NES_EVENT_TIMEOUT); 2102 + nes_debug(NES_DBG_MR, "Register STag 0x%08X completed, wait_event_timeout ret = %u," 2103 + " CQP Major:Minor codes = 0x%04X:0x%04X.\n", 2104 + stag, ret, cqp_request->major_code, cqp_request->minor_code); 2105 + major_code = cqp_request->major_code; 2106 + if (atomic_dec_and_test(&cqp_request->refcount)) { 2107 + if (cqp_request->dynamic) { 2108 + kfree(cqp_request); 2109 + } else { 2110 + spin_lock_irqsave(&nesdev->cqp.lock, flags); 2111 + list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); 2112 + spin_unlock_irqrestore(&nesdev->cqp.lock, flags); 2113 + } 2114 + } 2115 + if (!ret) 2116 + return -ETIME; 2117 + else if (major_code) 2118 + return -EIO; 2119 + else 2120 + return 0; 2121 + 2122 + return 0; 2123 + } 2124 + 2125 + 2126 + /** 2127 + * nes_reg_phys_mr 2128 + */ 2129 + static struct ib_mr *nes_reg_phys_mr(struct ib_pd *ib_pd, 2130 + struct ib_phys_buf *buffer_list, int num_phys_buf, int acc, 2131 + u64 * iova_start) 2132 + { 2133 + u64 region_length; 2134 + struct nes_pd *nespd = to_nespd(ib_pd); 2135 + struct nes_vnic *nesvnic = to_nesvnic(ib_pd->device); 2136 + struct nes_device *nesdev = nesvnic->nesdev; 2137 + struct nes_adapter *nesadapter = nesdev->nesadapter; 2138 + struct nes_mr *nesmr; 2139 + struct ib_mr *ibmr; 2140 + struct nes_vpbl vpbl; 2141 + struct nes_root_vpbl root_vpbl; 2142 + u32 stag; 2143 + u32 i; 2144 + u32 stag_index = 0; 2145 + u32 next_stag_index = 0; 2146 + u32 driver_key = 0; 2147 + u32 root_pbl_index = 0; 2148 + u32 cur_pbl_index = 0; 2149 + int err = 0, pbl_depth = 0; 2150 + int ret = 0; 2151 + u16 pbl_count = 0; 2152 + u8 single_page = 1; 2153 + u8 stag_key = 0; 2154 + 2155 + pbl_depth = 0; 2156 + region_length = 0; 2157 + vpbl.pbl_vbase = NULL; 2158 + root_vpbl.pbl_vbase = NULL; 2159 + root_vpbl.pbl_pbase = 0; 2160 + 2161 + get_random_bytes(&next_stag_index, sizeof(next_stag_index)); 2162 + stag_key = (u8)next_stag_index; 2163 + 2164 + driver_key = 0; 2165 + 2166 + next_stag_index >>= 8; 2167 + next_stag_index %= nesadapter->max_mr; 2168 + if (num_phys_buf > (1024*512)) { 2169 + return ERR_PTR(-E2BIG); 2170 + } 2171 + 2172 + err = nes_alloc_resource(nesadapter, nesadapter->allocated_mrs, nesadapter->max_mr, 2173 + &stag_index, &next_stag_index); 2174 + if (err) { 2175 + return ERR_PTR(err); 2176 + } 2177 + 2178 + nesmr = kzalloc(sizeof(*nesmr), GFP_KERNEL); 2179 + if (!nesmr) { 2180 + nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index); 2181 + return ERR_PTR(-ENOMEM); 2182 + } 2183 + 2184 + for (i = 0; i < num_phys_buf; i++) { 2185 + 2186 + if ((i & 0x01FF) == 0) { 2187 + if (root_pbl_index == 1) { 2188 + /* Allocate the root PBL */ 2189 + root_vpbl.pbl_vbase = pci_alloc_consistent(nesdev->pcidev, 8192, 2190 + &root_vpbl.pbl_pbase); 2191 + nes_debug(NES_DBG_MR, "Allocating root PBL, va = %p, pa = 0x%08X\n", 2192 + root_vpbl.pbl_vbase, (unsigned int)root_vpbl.pbl_pbase); 2193 + if (!root_vpbl.pbl_vbase) { 2194 + pci_free_consistent(nesdev->pcidev, 4096, vpbl.pbl_vbase, 2195 + vpbl.pbl_pbase); 2196 + nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index); 2197 + kfree(nesmr); 2198 + return ERR_PTR(-ENOMEM); 2199 + } 2200 + root_vpbl.leaf_vpbl = kzalloc(sizeof(*root_vpbl.leaf_vpbl)*1024, GFP_KERNEL); 2201 + if (!root_vpbl.leaf_vpbl) { 2202 + pci_free_consistent(nesdev->pcidev, 8192, root_vpbl.pbl_vbase, 2203 + root_vpbl.pbl_pbase); 2204 + pci_free_consistent(nesdev->pcidev, 4096, vpbl.pbl_vbase, 2205 + vpbl.pbl_pbase); 2206 + nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index); 2207 + kfree(nesmr); 2208 + return ERR_PTR(-ENOMEM); 2209 + } 2210 + root_vpbl.pbl_vbase[0].pa_low = cpu_to_le32((u32)vpbl.pbl_pbase); 2211 + root_vpbl.pbl_vbase[0].pa_high = 2212 + cpu_to_le32((u32)((((u64)vpbl.pbl_pbase) >> 32))); 2213 + root_vpbl.leaf_vpbl[0] = vpbl; 2214 + } 2215 + /* Allocate a 4K buffer for the PBL */ 2216 + vpbl.pbl_vbase = pci_alloc_consistent(nesdev->pcidev, 4096, 2217 + &vpbl.pbl_pbase); 2218 + nes_debug(NES_DBG_MR, "Allocating leaf PBL, va = %p, pa = 0x%016lX\n", 2219 + vpbl.pbl_vbase, (unsigned long)vpbl.pbl_pbase); 2220 + if (!vpbl.pbl_vbase) { 2221 + nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index); 2222 + ibmr = ERR_PTR(-ENOMEM); 2223 + kfree(nesmr); 2224 + goto reg_phys_err; 2225 + } 2226 + /* Fill in the root table */ 2227 + if (1 <= root_pbl_index) { 2228 + root_vpbl.pbl_vbase[root_pbl_index].pa_low = 2229 + cpu_to_le32((u32)vpbl.pbl_pbase); 2230 + root_vpbl.pbl_vbase[root_pbl_index].pa_high = 2231 + cpu_to_le32((u32)((((u64)vpbl.pbl_pbase) >> 32))); 2232 + root_vpbl.leaf_vpbl[root_pbl_index] = vpbl; 2233 + } 2234 + root_pbl_index++; 2235 + cur_pbl_index = 0; 2236 + } 2237 + if (buffer_list[i].addr & ~PAGE_MASK) { 2238 + /* TODO: Unwind allocated buffers */ 2239 + nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index); 2240 + nes_debug(NES_DBG_MR, "Unaligned Memory Buffer: 0x%x\n", 2241 + (unsigned int) buffer_list[i].addr); 2242 + ibmr = ERR_PTR(-EINVAL); 2243 + kfree(nesmr); 2244 + goto reg_phys_err; 2245 + } 2246 + 2247 + if (!buffer_list[i].size) { 2248 + nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index); 2249 + nes_debug(NES_DBG_MR, "Invalid Buffer Size\n"); 2250 + ibmr = ERR_PTR(-EINVAL); 2251 + kfree(nesmr); 2252 + goto reg_phys_err; 2253 + } 2254 + 2255 + region_length += buffer_list[i].size; 2256 + if ((i != 0) && (single_page)) { 2257 + if ((buffer_list[i-1].addr+PAGE_SIZE) != buffer_list[i].addr) 2258 + single_page = 0; 2259 + } 2260 + vpbl.pbl_vbase[cur_pbl_index].pa_low = cpu_to_le32((u32)buffer_list[i].addr); 2261 + vpbl.pbl_vbase[cur_pbl_index++].pa_high = 2262 + cpu_to_le32((u32)((((u64)buffer_list[i].addr) >> 32))); 2263 + } 2264 + 2265 + stag = stag_index << 8; 2266 + stag |= driver_key; 2267 + stag += (u32)stag_key; 2268 + 2269 + nes_debug(NES_DBG_MR, "Registering STag 0x%08X, VA = 0x%016lX," 2270 + " length = 0x%016lX, index = 0x%08X\n", 2271 + stag, (unsigned long)*iova_start, (unsigned long)region_length, stag_index); 2272 + 2273 + region_length -= (*iova_start)&PAGE_MASK; 2274 + 2275 + /* Make the leaf PBL the root if only one PBL */ 2276 + if (root_pbl_index == 1) { 2277 + root_vpbl.pbl_pbase = vpbl.pbl_pbase; 2278 + } 2279 + 2280 + if (single_page) { 2281 + pbl_count = 0; 2282 + } else { 2283 + pbl_count = root_pbl_index; 2284 + } 2285 + ret = nes_reg_mr(nesdev, nespd, stag, region_length, &root_vpbl, 2286 + buffer_list[0].addr, pbl_count, (u16)cur_pbl_index, acc, iova_start); 2287 + 2288 + if (ret == 0) { 2289 + nesmr->ibmr.rkey = stag; 2290 + nesmr->ibmr.lkey = stag; 2291 + nesmr->mode = IWNES_MEMREG_TYPE_MEM; 2292 + ibmr = &nesmr->ibmr; 2293 + nesmr->pbl_4k = ((pbl_count > 1) || (cur_pbl_index > 32)) ? 1 : 0; 2294 + nesmr->pbls_used = pbl_count; 2295 + if (pbl_count > 1) { 2296 + nesmr->pbls_used++; 2297 + } 2298 + } else { 2299 + kfree(nesmr); 2300 + ibmr = ERR_PTR(-ENOMEM); 2301 + } 2302 + 2303 + reg_phys_err: 2304 + /* free the resources */ 2305 + if (root_pbl_index == 1) { 2306 + /* single PBL case */ 2307 + pci_free_consistent(nesdev->pcidev, 4096, vpbl.pbl_vbase, vpbl.pbl_pbase); 2308 + } else { 2309 + for (i=0; i<root_pbl_index; i++) { 2310 + pci_free_consistent(nesdev->pcidev, 4096, root_vpbl.leaf_vpbl[i].pbl_vbase, 2311 + root_vpbl.leaf_vpbl[i].pbl_pbase); 2312 + } 2313 + kfree(root_vpbl.leaf_vpbl); 2314 + pci_free_consistent(nesdev->pcidev, 8192, root_vpbl.pbl_vbase, 2315 + root_vpbl.pbl_pbase); 2316 + } 2317 + 2318 + return ibmr; 2319 + } 2320 + 2321 + 2322 + /** 2323 + * nes_get_dma_mr 2324 + */ 2325 + static struct ib_mr *nes_get_dma_mr(struct ib_pd *pd, int acc) 2326 + { 2327 + struct ib_phys_buf bl; 2328 + u64 kva = 0; 2329 + 2330 + nes_debug(NES_DBG_MR, "\n"); 2331 + 2332 + bl.size = (u64)0xffffffffffULL; 2333 + bl.addr = 0; 2334 + return nes_reg_phys_mr(pd, &bl, 1, acc, &kva); 2335 + } 2336 + 2337 + 2338 + /** 2339 + * nes_reg_user_mr 2340 + */ 2341 + static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, 2342 + u64 virt, int acc, struct ib_udata *udata) 2343 + { 2344 + u64 iova_start; 2345 + __le64 *pbl; 2346 + u64 region_length; 2347 + dma_addr_t last_dma_addr = 0; 2348 + dma_addr_t first_dma_addr = 0; 2349 + struct nes_pd *nespd = to_nespd(pd); 2350 + struct nes_vnic *nesvnic = to_nesvnic(pd->device); 2351 + struct nes_device *nesdev = nesvnic->nesdev; 2352 + struct nes_adapter *nesadapter = nesdev->nesadapter; 2353 + struct ib_mr *ibmr = ERR_PTR(-EINVAL); 2354 + struct ib_umem_chunk *chunk; 2355 + struct nes_ucontext *nes_ucontext; 2356 + struct nes_pbl *nespbl; 2357 + struct nes_mr *nesmr; 2358 + struct ib_umem *region; 2359 + struct nes_mem_reg_req req; 2360 + struct nes_vpbl vpbl; 2361 + struct nes_root_vpbl root_vpbl; 2362 + int nmap_index, page_index; 2363 + int page_count = 0; 2364 + int err, pbl_depth = 0; 2365 + int chunk_pages; 2366 + int ret; 2367 + u32 stag; 2368 + u32 stag_index = 0; 2369 + u32 next_stag_index; 2370 + u32 driver_key; 2371 + u32 root_pbl_index = 0; 2372 + u32 cur_pbl_index = 0; 2373 + u32 skip_pages; 2374 + u16 pbl_count; 2375 + u8 single_page = 1; 2376 + u8 stag_key; 2377 + 2378 + region = ib_umem_get(pd->uobject->context, start, length, acc); 2379 + if (IS_ERR(region)) { 2380 + return (struct ib_mr *)region; 2381 + } 2382 + 2383 + nes_debug(NES_DBG_MR, "User base = 0x%lX, Virt base = 0x%lX, length = %u," 2384 + " offset = %u, page size = %u.\n", 2385 + (unsigned long int)start, (unsigned long int)virt, (u32)length, 2386 + region->offset, region->page_size); 2387 + 2388 + skip_pages = ((u32)region->offset) >> 12; 2389 + 2390 + if (ib_copy_from_udata(&req, udata, sizeof(req))) 2391 + return ERR_PTR(-EFAULT); 2392 + nes_debug(NES_DBG_MR, "Memory Registration type = %08X.\n", req.reg_type); 2393 + 2394 + switch (req.reg_type) { 2395 + case IWNES_MEMREG_TYPE_MEM: 2396 + pbl_depth = 0; 2397 + region_length = 0; 2398 + vpbl.pbl_vbase = NULL; 2399 + root_vpbl.pbl_vbase = NULL; 2400 + root_vpbl.pbl_pbase = 0; 2401 + 2402 + get_random_bytes(&next_stag_index, sizeof(next_stag_index)); 2403 + stag_key = (u8)next_stag_index; 2404 + 2405 + driver_key = next_stag_index & 0x70000000; 2406 + 2407 + next_stag_index >>= 8; 2408 + next_stag_index %= nesadapter->max_mr; 2409 + 2410 + err = nes_alloc_resource(nesadapter, nesadapter->allocated_mrs, 2411 + nesadapter->max_mr, &stag_index, &next_stag_index); 2412 + if (err) { 2413 + ib_umem_release(region); 2414 + return ERR_PTR(err); 2415 + } 2416 + 2417 + nesmr = kzalloc(sizeof(*nesmr), GFP_KERNEL); 2418 + if (!nesmr) { 2419 + ib_umem_release(region); 2420 + nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index); 2421 + return ERR_PTR(-ENOMEM); 2422 + } 2423 + nesmr->region = region; 2424 + 2425 + list_for_each_entry(chunk, &region->chunk_list, list) { 2426 + nes_debug(NES_DBG_MR, "Chunk: nents = %u, nmap = %u .\n", 2427 + chunk->nents, chunk->nmap); 2428 + for (nmap_index = 0; nmap_index < chunk->nmap; ++nmap_index) { 2429 + if (sg_dma_address(&chunk->page_list[nmap_index]) & ~PAGE_MASK) { 2430 + ib_umem_release(region); 2431 + nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index); 2432 + nes_debug(NES_DBG_MR, "Unaligned Memory Buffer: 0x%x\n", 2433 + (unsigned int) sg_dma_address(&chunk->page_list[nmap_index])); 2434 + ibmr = ERR_PTR(-EINVAL); 2435 + kfree(nesmr); 2436 + goto reg_user_mr_err; 2437 + } 2438 + 2439 + if (!sg_dma_len(&chunk->page_list[nmap_index])) { 2440 + ib_umem_release(region); 2441 + nes_free_resource(nesadapter, nesadapter->allocated_mrs, 2442 + stag_index); 2443 + nes_debug(NES_DBG_MR, "Invalid Buffer Size\n"); 2444 + ibmr = ERR_PTR(-EINVAL); 2445 + kfree(nesmr); 2446 + goto reg_user_mr_err; 2447 + } 2448 + 2449 + region_length += sg_dma_len(&chunk->page_list[nmap_index]); 2450 + chunk_pages = sg_dma_len(&chunk->page_list[nmap_index]) >> 12; 2451 + region_length -= skip_pages << 12; 2452 + for (page_index=skip_pages; page_index < chunk_pages; page_index++) { 2453 + skip_pages = 0; 2454 + if ((page_count!=0)&&(page_count<<12)-(region->offset&(4096-1))>=region->length) 2455 + goto enough_pages; 2456 + if ((page_count&0x01FF) == 0) { 2457 + if (page_count>(1024*512)) { 2458 + ib_umem_release(region); 2459 + pci_free_consistent(nesdev->pcidev, 4096, vpbl.pbl_vbase, 2460 + vpbl.pbl_pbase); 2461 + nes_free_resource(nesadapter, 2462 + nesadapter->allocated_mrs, stag_index); 2463 + kfree(nesmr); 2464 + ibmr = ERR_PTR(-E2BIG); 2465 + goto reg_user_mr_err; 2466 + } 2467 + if (root_pbl_index == 1) { 2468 + root_vpbl.pbl_vbase = pci_alloc_consistent(nesdev->pcidev, 2469 + 8192, &root_vpbl.pbl_pbase); 2470 + nes_debug(NES_DBG_MR, "Allocating root PBL, va = %p, pa = 0x%08X\n", 2471 + root_vpbl.pbl_vbase, (unsigned int)root_vpbl.pbl_pbase); 2472 + if (!root_vpbl.pbl_vbase) { 2473 + ib_umem_release(region); 2474 + pci_free_consistent(nesdev->pcidev, 4096, vpbl.pbl_vbase, 2475 + vpbl.pbl_pbase); 2476 + nes_free_resource(nesadapter, nesadapter->allocated_mrs, 2477 + stag_index); 2478 + kfree(nesmr); 2479 + ibmr = ERR_PTR(-ENOMEM); 2480 + goto reg_user_mr_err; 2481 + } 2482 + root_vpbl.leaf_vpbl = kzalloc(sizeof(*root_vpbl.leaf_vpbl)*1024, 2483 + GFP_KERNEL); 2484 + if (!root_vpbl.leaf_vpbl) { 2485 + ib_umem_release(region); 2486 + pci_free_consistent(nesdev->pcidev, 8192, root_vpbl.pbl_vbase, 2487 + root_vpbl.pbl_pbase); 2488 + pci_free_consistent(nesdev->pcidev, 4096, vpbl.pbl_vbase, 2489 + vpbl.pbl_pbase); 2490 + nes_free_resource(nesadapter, nesadapter->allocated_mrs, 2491 + stag_index); 2492 + kfree(nesmr); 2493 + ibmr = ERR_PTR(-ENOMEM); 2494 + goto reg_user_mr_err; 2495 + } 2496 + root_vpbl.pbl_vbase[0].pa_low = 2497 + cpu_to_le32((u32)vpbl.pbl_pbase); 2498 + root_vpbl.pbl_vbase[0].pa_high = 2499 + cpu_to_le32((u32)((((u64)vpbl.pbl_pbase) >> 32))); 2500 + root_vpbl.leaf_vpbl[0] = vpbl; 2501 + } 2502 + vpbl.pbl_vbase = pci_alloc_consistent(nesdev->pcidev, 4096, 2503 + &vpbl.pbl_pbase); 2504 + nes_debug(NES_DBG_MR, "Allocating leaf PBL, va = %p, pa = 0x%08X\n", 2505 + vpbl.pbl_vbase, (unsigned int)vpbl.pbl_pbase); 2506 + if (!vpbl.pbl_vbase) { 2507 + ib_umem_release(region); 2508 + nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index); 2509 + ibmr = ERR_PTR(-ENOMEM); 2510 + kfree(nesmr); 2511 + goto reg_user_mr_err; 2512 + } 2513 + if (1 <= root_pbl_index) { 2514 + root_vpbl.pbl_vbase[root_pbl_index].pa_low = 2515 + cpu_to_le32((u32)vpbl.pbl_pbase); 2516 + root_vpbl.pbl_vbase[root_pbl_index].pa_high = 2517 + cpu_to_le32((u32)((((u64)vpbl.pbl_pbase)>>32))); 2518 + root_vpbl.leaf_vpbl[root_pbl_index] = vpbl; 2519 + } 2520 + root_pbl_index++; 2521 + cur_pbl_index = 0; 2522 + } 2523 + if (single_page) { 2524 + if (page_count != 0) { 2525 + if ((last_dma_addr+4096) != 2526 + (sg_dma_address(&chunk->page_list[nmap_index])+ 2527 + (page_index*4096))) 2528 + single_page = 0; 2529 + last_dma_addr = sg_dma_address(&chunk->page_list[nmap_index])+ 2530 + (page_index*4096); 2531 + } else { 2532 + first_dma_addr = sg_dma_address(&chunk->page_list[nmap_index])+ 2533 + (page_index*4096); 2534 + last_dma_addr = first_dma_addr; 2535 + } 2536 + } 2537 + 2538 + vpbl.pbl_vbase[cur_pbl_index].pa_low = 2539 + cpu_to_le32((u32)(sg_dma_address(&chunk->page_list[nmap_index])+ 2540 + (page_index*4096))); 2541 + vpbl.pbl_vbase[cur_pbl_index].pa_high = 2542 + cpu_to_le32((u32)((((u64)(sg_dma_address(&chunk->page_list[nmap_index])+ 2543 + (page_index*4096))) >> 32))); 2544 + cur_pbl_index++; 2545 + page_count++; 2546 + } 2547 + } 2548 + } 2549 + enough_pages: 2550 + nes_debug(NES_DBG_MR, "calculating stag, stag_index=0x%08x, driver_key=0x%08x," 2551 + " stag_key=0x%08x\n", 2552 + stag_index, driver_key, stag_key); 2553 + stag = stag_index << 8; 2554 + stag |= driver_key; 2555 + stag += (u32)stag_key; 2556 + if (stag == 0) { 2557 + stag = 1; 2558 + } 2559 + 2560 + iova_start = virt; 2561 + /* Make the leaf PBL the root if only one PBL */ 2562 + if (root_pbl_index == 1) { 2563 + root_vpbl.pbl_pbase = vpbl.pbl_pbase; 2564 + } 2565 + 2566 + if (single_page) { 2567 + pbl_count = 0; 2568 + } else { 2569 + pbl_count = root_pbl_index; 2570 + first_dma_addr = 0; 2571 + } 2572 + nes_debug(NES_DBG_MR, "Registering STag 0x%08X, VA = 0x%08X, length = 0x%08X," 2573 + " index = 0x%08X, region->length=0x%08llx, pbl_count = %u\n", 2574 + stag, (unsigned int)iova_start, 2575 + (unsigned int)region_length, stag_index, 2576 + (unsigned long long)region->length, pbl_count); 2577 + ret = nes_reg_mr( nesdev, nespd, stag, region->length, &root_vpbl, 2578 + first_dma_addr, pbl_count, (u16)cur_pbl_index, acc, &iova_start); 2579 + 2580 + nes_debug(NES_DBG_MR, "ret=%d\n", ret); 2581 + 2582 + if (ret == 0) { 2583 + nesmr->ibmr.rkey = stag; 2584 + nesmr->ibmr.lkey = stag; 2585 + nesmr->mode = IWNES_MEMREG_TYPE_MEM; 2586 + ibmr = &nesmr->ibmr; 2587 + nesmr->pbl_4k = ((pbl_count > 1) || (cur_pbl_index > 32)) ? 1 : 0; 2588 + nesmr->pbls_used = pbl_count; 2589 + if (pbl_count > 1) { 2590 + nesmr->pbls_used++; 2591 + } 2592 + } else { 2593 + ib_umem_release(region); 2594 + kfree(nesmr); 2595 + ibmr = ERR_PTR(-ENOMEM); 2596 + } 2597 + 2598 + reg_user_mr_err: 2599 + /* free the resources */ 2600 + if (root_pbl_index == 1) { 2601 + pci_free_consistent(nesdev->pcidev, 4096, vpbl.pbl_vbase, 2602 + vpbl.pbl_pbase); 2603 + } else { 2604 + for (page_index=0; page_index<root_pbl_index; page_index++) { 2605 + pci_free_consistent(nesdev->pcidev, 4096, 2606 + root_vpbl.leaf_vpbl[page_index].pbl_vbase, 2607 + root_vpbl.leaf_vpbl[page_index].pbl_pbase); 2608 + } 2609 + kfree(root_vpbl.leaf_vpbl); 2610 + pci_free_consistent(nesdev->pcidev, 8192, root_vpbl.pbl_vbase, 2611 + root_vpbl.pbl_pbase); 2612 + } 2613 + 2614 + nes_debug(NES_DBG_MR, "Leaving, ibmr=%p", ibmr); 2615 + 2616 + return ibmr; 2617 + break; 2618 + case IWNES_MEMREG_TYPE_QP: 2619 + case IWNES_MEMREG_TYPE_CQ: 2620 + nespbl = kzalloc(sizeof(*nespbl), GFP_KERNEL); 2621 + if (!nespbl) { 2622 + nes_debug(NES_DBG_MR, "Unable to allocate PBL\n"); 2623 + ib_umem_release(region); 2624 + return ERR_PTR(-ENOMEM); 2625 + } 2626 + nesmr = kzalloc(sizeof(*nesmr), GFP_KERNEL); 2627 + if (!nesmr) { 2628 + ib_umem_release(region); 2629 + kfree(nespbl); 2630 + nes_debug(NES_DBG_MR, "Unable to allocate nesmr\n"); 2631 + return ERR_PTR(-ENOMEM); 2632 + } 2633 + nesmr->region = region; 2634 + nes_ucontext = to_nesucontext(pd->uobject->context); 2635 + pbl_depth = region->length >> 12; 2636 + pbl_depth += (region->length & (4096-1)) ? 1 : 0; 2637 + nespbl->pbl_size = pbl_depth*sizeof(u64); 2638 + if (req.reg_type == IWNES_MEMREG_TYPE_QP) { 2639 + nes_debug(NES_DBG_MR, "Attempting to allocate QP PBL memory"); 2640 + } else { 2641 + nes_debug(NES_DBG_MR, "Attempting to allocate CP PBL memory"); 2642 + } 2643 + 2644 + nes_debug(NES_DBG_MR, " %u bytes, %u entries.\n", 2645 + nespbl->pbl_size, pbl_depth); 2646 + pbl = pci_alloc_consistent(nesdev->pcidev, nespbl->pbl_size, 2647 + &nespbl->pbl_pbase); 2648 + if (!pbl) { 2649 + ib_umem_release(region); 2650 + kfree(nesmr); 2651 + kfree(nespbl); 2652 + nes_debug(NES_DBG_MR, "Unable to allocate PBL memory\n"); 2653 + return ERR_PTR(-ENOMEM); 2654 + } 2655 + 2656 + nespbl->pbl_vbase = (u64 *)pbl; 2657 + nespbl->user_base = start; 2658 + nes_debug(NES_DBG_MR, "Allocated PBL memory, %u bytes, pbl_pbase=%p," 2659 + " pbl_vbase=%p user_base=0x%lx\n", 2660 + nespbl->pbl_size, (void *)nespbl->pbl_pbase, 2661 + (void*)nespbl->pbl_vbase, nespbl->user_base); 2662 + 2663 + list_for_each_entry(chunk, &region->chunk_list, list) { 2664 + for (nmap_index = 0; nmap_index < chunk->nmap; ++nmap_index) { 2665 + chunk_pages = sg_dma_len(&chunk->page_list[nmap_index]) >> 12; 2666 + chunk_pages += (sg_dma_len(&chunk->page_list[nmap_index]) & (4096-1)) ? 1 : 0; 2667 + nespbl->page = sg_page(&chunk->page_list[0]); 2668 + for (page_index=0; page_index<chunk_pages; page_index++) { 2669 + ((__le32 *)pbl)[0] = cpu_to_le32((u32) 2670 + (sg_dma_address(&chunk->page_list[nmap_index])+ 2671 + (page_index*4096))); 2672 + ((__le32 *)pbl)[1] = cpu_to_le32(((u64) 2673 + (sg_dma_address(&chunk->page_list[nmap_index])+ 2674 + (page_index*4096)))>>32); 2675 + nes_debug(NES_DBG_MR, "pbl=%p, *pbl=0x%016llx, 0x%08x%08x\n", pbl, 2676 + (unsigned long long)*pbl, 2677 + le32_to_cpu(((__le32 *)pbl)[1]), le32_to_cpu(((__le32 *)pbl)[0])); 2678 + pbl++; 2679 + } 2680 + } 2681 + } 2682 + if (req.reg_type == IWNES_MEMREG_TYPE_QP) { 2683 + list_add_tail(&nespbl->list, &nes_ucontext->qp_reg_mem_list); 2684 + } else { 2685 + list_add_tail(&nespbl->list, &nes_ucontext->cq_reg_mem_list); 2686 + } 2687 + nesmr->ibmr.rkey = -1; 2688 + nesmr->ibmr.lkey = -1; 2689 + nesmr->mode = req.reg_type; 2690 + return &nesmr->ibmr; 2691 + break; 2692 + } 2693 + 2694 + return ERR_PTR(-ENOSYS); 2695 + } 2696 + 2697 + 2698 + /** 2699 + * nes_dereg_mr 2700 + */ 2701 + static int nes_dereg_mr(struct ib_mr *ib_mr) 2702 + { 2703 + struct nes_mr *nesmr = to_nesmr(ib_mr); 2704 + struct nes_vnic *nesvnic = to_nesvnic(ib_mr->device); 2705 + struct nes_device *nesdev = nesvnic->nesdev; 2706 + struct nes_adapter *nesadapter = nesdev->nesadapter; 2707 + struct nes_hw_cqp_wqe *cqp_wqe; 2708 + struct nes_cqp_request *cqp_request; 2709 + unsigned long flags; 2710 + int ret; 2711 + u16 major_code; 2712 + u16 minor_code; 2713 + 2714 + if (nesmr->region) { 2715 + ib_umem_release(nesmr->region); 2716 + } 2717 + if (nesmr->mode != IWNES_MEMREG_TYPE_MEM) { 2718 + kfree(nesmr); 2719 + return 0; 2720 + } 2721 + 2722 + /* Deallocate the region with the adapter */ 2723 + 2724 + cqp_request = nes_get_cqp_request(nesdev); 2725 + if (cqp_request == NULL) { 2726 + nes_debug(NES_DBG_MR, "Failed to get a cqp_request.\n"); 2727 + return -ENOMEM; 2728 + } 2729 + cqp_request->waiting = 1; 2730 + cqp_wqe = &cqp_request->cqp_wqe; 2731 + 2732 + spin_lock_irqsave(&nesadapter->pbl_lock, flags); 2733 + if (nesmr->pbls_used != 0) { 2734 + if (nesmr->pbl_4k) { 2735 + nesadapter->free_4kpbl += nesmr->pbls_used; 2736 + if (nesadapter->free_4kpbl > nesadapter->max_4kpbl) { 2737 + printk(KERN_ERR PFX "free 4KB PBLs(%u) has exceeded the max(%u)\n", 2738 + nesadapter->free_4kpbl, nesadapter->max_4kpbl); 2739 + } 2740 + } else { 2741 + nesadapter->free_256pbl += nesmr->pbls_used; 2742 + if (nesadapter->free_256pbl > nesadapter->max_256pbl) { 2743 + printk(KERN_ERR PFX "free 256B PBLs(%u) has exceeded the max(%u)\n", 2744 + nesadapter->free_256pbl, nesadapter->max_256pbl); 2745 + } 2746 + } 2747 + } 2748 + 2749 + spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); 2750 + nes_fill_init_cqp_wqe(cqp_wqe, nesdev); 2751 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX, 2752 + NES_CQP_DEALLOCATE_STAG | NES_CQP_STAG_VA_TO | 2753 + NES_CQP_STAG_DEALLOC_PBLS | NES_CQP_STAG_MR); 2754 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_STAG_IDX, ib_mr->rkey); 2755 + 2756 + atomic_set(&cqp_request->refcount, 2); 2757 + nes_post_cqp_request(nesdev, cqp_request, NES_CQP_REQUEST_RING_DOORBELL); 2758 + 2759 + /* Wait for CQP */ 2760 + nes_debug(NES_DBG_MR, "Waiting for deallocate STag 0x%08X completed\n", ib_mr->rkey); 2761 + ret = wait_event_timeout(cqp_request->waitq, (cqp_request->request_done != 0), 2762 + NES_EVENT_TIMEOUT); 2763 + nes_debug(NES_DBG_MR, "Deallocate STag 0x%08X completed, wait_event_timeout ret = %u," 2764 + " CQP Major:Minor codes = 0x%04X:0x%04X\n", 2765 + ib_mr->rkey, ret, cqp_request->major_code, cqp_request->minor_code); 2766 + 2767 + nes_free_resource(nesadapter, nesadapter->allocated_mrs, 2768 + (ib_mr->rkey & 0x0fffff00) >> 8); 2769 + 2770 + kfree(nesmr); 2771 + 2772 + major_code = cqp_request->major_code; 2773 + minor_code = cqp_request->minor_code; 2774 + if (atomic_dec_and_test(&cqp_request->refcount)) { 2775 + if (cqp_request->dynamic) { 2776 + kfree(cqp_request); 2777 + } else { 2778 + spin_lock_irqsave(&nesdev->cqp.lock, flags); 2779 + list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); 2780 + spin_unlock_irqrestore(&nesdev->cqp.lock, flags); 2781 + } 2782 + } 2783 + if (!ret) { 2784 + nes_debug(NES_DBG_MR, "Timeout waiting to destroy STag," 2785 + " ib_mr=%p, rkey = 0x%08X\n", 2786 + ib_mr, ib_mr->rkey); 2787 + return -ETIME; 2788 + } else if (major_code) { 2789 + nes_debug(NES_DBG_MR, "Error (0x%04X:0x%04X) while attempting" 2790 + " to destroy STag, ib_mr=%p, rkey = 0x%08X\n", 2791 + major_code, minor_code, ib_mr, ib_mr->rkey); 2792 + return -EIO; 2793 + } else 2794 + return 0; 2795 + } 2796 + 2797 + 2798 + /** 2799 + * show_rev 2800 + */ 2801 + static ssize_t show_rev(struct class_device *cdev, char *buf) 2802 + { 2803 + struct nes_ib_device *nesibdev = 2804 + container_of(cdev, struct nes_ib_device, ibdev.class_dev); 2805 + struct nes_vnic *nesvnic = nesibdev->nesvnic; 2806 + 2807 + nes_debug(NES_DBG_INIT, "\n"); 2808 + return sprintf(buf, "%x\n", nesvnic->nesdev->nesadapter->hw_rev); 2809 + } 2810 + 2811 + 2812 + /** 2813 + * show_fw_ver 2814 + */ 2815 + static ssize_t show_fw_ver(struct class_device *cdev, char *buf) 2816 + { 2817 + struct nes_ib_device *nesibdev = 2818 + container_of(cdev, struct nes_ib_device, ibdev.class_dev); 2819 + struct nes_vnic *nesvnic = nesibdev->nesvnic; 2820 + 2821 + nes_debug(NES_DBG_INIT, "\n"); 2822 + return sprintf(buf, "%x.%x.%x\n", 2823 + (int)(nesvnic->nesdev->nesadapter->fw_ver >> 32), 2824 + (int)(nesvnic->nesdev->nesadapter->fw_ver >> 16) & 0xffff, 2825 + (int)(nesvnic->nesdev->nesadapter->fw_ver & 0xffff)); 2826 + } 2827 + 2828 + 2829 + /** 2830 + * show_hca 2831 + */ 2832 + static ssize_t show_hca(struct class_device *cdev, char *buf) 2833 + { 2834 + nes_debug(NES_DBG_INIT, "\n"); 2835 + return sprintf(buf, "NES020\n"); 2836 + } 2837 + 2838 + 2839 + /** 2840 + * show_board 2841 + */ 2842 + static ssize_t show_board(struct class_device *cdev, char *buf) 2843 + { 2844 + nes_debug(NES_DBG_INIT, "\n"); 2845 + return sprintf(buf, "%.*s\n", 32, "NES020 Board ID"); 2846 + } 2847 + 2848 + 2849 + static CLASS_DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL); 2850 + static CLASS_DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL); 2851 + static CLASS_DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL); 2852 + static CLASS_DEVICE_ATTR(board_id, S_IRUGO, show_board, NULL); 2853 + 2854 + static struct class_device_attribute *nes_class_attributes[] = { 2855 + &class_device_attr_hw_rev, 2856 + &class_device_attr_fw_ver, 2857 + &class_device_attr_hca_type, 2858 + &class_device_attr_board_id 2859 + }; 2860 + 2861 + 2862 + /** 2863 + * nes_query_qp 2864 + */ 2865 + static int nes_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, 2866 + int attr_mask, struct ib_qp_init_attr *init_attr) 2867 + { 2868 + struct nes_qp *nesqp = to_nesqp(ibqp); 2869 + 2870 + nes_debug(NES_DBG_QP, "\n"); 2871 + 2872 + attr->qp_access_flags = 0; 2873 + attr->cap.max_send_wr = nesqp->hwqp.sq_size; 2874 + attr->cap.max_recv_wr = nesqp->hwqp.rq_size; 2875 + attr->cap.max_recv_sge = 1; 2876 + if (nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) { 2877 + init_attr->cap.max_inline_data = 0; 2878 + } else { 2879 + init_attr->cap.max_inline_data = 64; 2880 + } 2881 + 2882 + init_attr->event_handler = nesqp->ibqp.event_handler; 2883 + init_attr->qp_context = nesqp->ibqp.qp_context; 2884 + init_attr->send_cq = nesqp->ibqp.send_cq; 2885 + init_attr->recv_cq = nesqp->ibqp.recv_cq; 2886 + init_attr->srq = nesqp->ibqp.srq = nesqp->ibqp.srq; 2887 + init_attr->cap = attr->cap; 2888 + 2889 + return 0; 2890 + } 2891 + 2892 + 2893 + /** 2894 + * nes_hw_modify_qp 2895 + */ 2896 + int nes_hw_modify_qp(struct nes_device *nesdev, struct nes_qp *nesqp, 2897 + u32 next_iwarp_state, u32 wait_completion) 2898 + { 2899 + struct nes_hw_cqp_wqe *cqp_wqe; 2900 + /* struct iw_cm_id *cm_id = nesqp->cm_id; */ 2901 + /* struct iw_cm_event cm_event; */ 2902 + struct nes_cqp_request *cqp_request; 2903 + unsigned long flags; 2904 + int ret; 2905 + u16 major_code; 2906 + 2907 + nes_debug(NES_DBG_MOD_QP, "QP%u, refcount=%d\n", 2908 + nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount)); 2909 + 2910 + cqp_request = nes_get_cqp_request(nesdev); 2911 + if (cqp_request == NULL) { 2912 + nes_debug(NES_DBG_MOD_QP, "Failed to get a cqp_request.\n"); 2913 + return -ENOMEM; 2914 + } 2915 + if (wait_completion) { 2916 + cqp_request->waiting = 1; 2917 + } else { 2918 + cqp_request->waiting = 0; 2919 + } 2920 + cqp_wqe = &cqp_request->cqp_wqe; 2921 + 2922 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX, 2923 + NES_CQP_MODIFY_QP | NES_CQP_QP_TYPE_IWARP | next_iwarp_state); 2924 + nes_debug(NES_DBG_MOD_QP, "using next_iwarp_state=%08x, wqe_words=%08x\n", 2925 + next_iwarp_state, le32_to_cpu(cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX])); 2926 + nes_fill_init_cqp_wqe(cqp_wqe, nesdev); 2927 + set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_ID_IDX, nesqp->hwqp.qp_id); 2928 + set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_QP_WQE_CONTEXT_LOW_IDX, (u64)nesqp->nesqp_context_pbase); 2929 + 2930 + atomic_set(&cqp_request->refcount, 2); 2931 + nes_post_cqp_request(nesdev, cqp_request, NES_CQP_REQUEST_RING_DOORBELL); 2932 + 2933 + /* Wait for CQP */ 2934 + if (wait_completion) { 2935 + /* nes_debug(NES_DBG_MOD_QP, "Waiting for modify iWARP QP%u to complete.\n", 2936 + nesqp->hwqp.qp_id); */ 2937 + ret = wait_event_timeout(cqp_request->waitq, (cqp_request->request_done != 0), 2938 + NES_EVENT_TIMEOUT); 2939 + nes_debug(NES_DBG_MOD_QP, "Modify iwarp QP%u completed, wait_event_timeout ret=%u, " 2940 + "CQP Major:Minor codes = 0x%04X:0x%04X.\n", 2941 + nesqp->hwqp.qp_id, ret, cqp_request->major_code, cqp_request->minor_code); 2942 + major_code = cqp_request->major_code; 2943 + if (major_code) { 2944 + nes_debug(NES_DBG_MOD_QP, "Modify iwarp QP%u failed" 2945 + "CQP Major:Minor codes = 0x%04X:0x%04X, intended next state = 0x%08X.\n", 2946 + nesqp->hwqp.qp_id, cqp_request->major_code, 2947 + cqp_request->minor_code, next_iwarp_state); 2948 + } 2949 + if (atomic_dec_and_test(&cqp_request->refcount)) { 2950 + if (cqp_request->dynamic) { 2951 + kfree(cqp_request); 2952 + } else { 2953 + spin_lock_irqsave(&nesdev->cqp.lock, flags); 2954 + list_add_tail(&cqp_request->list, &nesdev->cqp_avail_reqs); 2955 + spin_unlock_irqrestore(&nesdev->cqp.lock, flags); 2956 + } 2957 + } 2958 + if (!ret) 2959 + return -ETIME; 2960 + else if (major_code) 2961 + return -EIO; 2962 + else 2963 + return 0; 2964 + } else { 2965 + return 0; 2966 + } 2967 + } 2968 + 2969 + 2970 + /** 2971 + * nes_modify_qp 2972 + */ 2973 + int nes_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, 2974 + int attr_mask, struct ib_udata *udata) 2975 + { 2976 + struct nes_qp *nesqp = to_nesqp(ibqp); 2977 + struct nes_vnic *nesvnic = to_nesvnic(ibqp->device); 2978 + struct nes_device *nesdev = nesvnic->nesdev; 2979 + /* u32 cqp_head; */ 2980 + /* u32 counter; */ 2981 + u32 next_iwarp_state = 0; 2982 + int err; 2983 + unsigned long qplockflags; 2984 + int ret; 2985 + u16 original_last_aeq; 2986 + u8 issue_modify_qp = 0; 2987 + u8 issue_disconnect = 0; 2988 + u8 dont_wait = 0; 2989 + 2990 + nes_debug(NES_DBG_MOD_QP, "QP%u: QP State=%u, cur QP State=%u," 2991 + " iwarp_state=0x%X, refcount=%d\n", 2992 + nesqp->hwqp.qp_id, attr->qp_state, nesqp->ibqp_state, 2993 + nesqp->iwarp_state, atomic_read(&nesqp->refcount)); 2994 + 2995 + nes_add_ref(&nesqp->ibqp); 2996 + spin_lock_irqsave(&nesqp->lock, qplockflags); 2997 + 2998 + nes_debug(NES_DBG_MOD_QP, "QP%u: hw_iwarp_state=0x%X, hw_tcp_state=0x%X," 2999 + " QP Access Flags=0x%X, attr_mask = 0x%0x\n", 3000 + nesqp->hwqp.qp_id, nesqp->hw_iwarp_state, 3001 + nesqp->hw_tcp_state, attr->qp_access_flags, attr_mask); 3002 + 3003 + if (attr_mask & IB_QP_STATE) { 3004 + switch (attr->qp_state) { 3005 + case IB_QPS_INIT: 3006 + nes_debug(NES_DBG_MOD_QP, "QP%u: new state = init\n", 3007 + nesqp->hwqp.qp_id); 3008 + if (nesqp->iwarp_state > (u32)NES_CQP_QP_IWARP_STATE_IDLE) { 3009 + spin_unlock_irqrestore(&nesqp->lock, qplockflags); 3010 + nes_rem_ref(&nesqp->ibqp); 3011 + return -EINVAL; 3012 + } 3013 + next_iwarp_state = NES_CQP_QP_IWARP_STATE_IDLE; 3014 + issue_modify_qp = 1; 3015 + break; 3016 + case IB_QPS_RTR: 3017 + nes_debug(NES_DBG_MOD_QP, "QP%u: new state = rtr\n", 3018 + nesqp->hwqp.qp_id); 3019 + if (nesqp->iwarp_state>(u32)NES_CQP_QP_IWARP_STATE_IDLE) { 3020 + spin_unlock_irqrestore(&nesqp->lock, qplockflags); 3021 + nes_rem_ref(&nesqp->ibqp); 3022 + return -EINVAL; 3023 + } 3024 + next_iwarp_state = NES_CQP_QP_IWARP_STATE_IDLE; 3025 + issue_modify_qp = 1; 3026 + break; 3027 + case IB_QPS_RTS: 3028 + nes_debug(NES_DBG_MOD_QP, "QP%u: new state = rts\n", 3029 + nesqp->hwqp.qp_id); 3030 + if (nesqp->iwarp_state>(u32)NES_CQP_QP_IWARP_STATE_RTS) { 3031 + spin_unlock_irqrestore(&nesqp->lock, qplockflags); 3032 + nes_rem_ref(&nesqp->ibqp); 3033 + return -EINVAL; 3034 + } 3035 + if (nesqp->cm_id == NULL) { 3036 + nes_debug(NES_DBG_MOD_QP, "QP%u: Failing attempt to move QP to RTS without a CM_ID. \n", 3037 + nesqp->hwqp.qp_id ); 3038 + spin_unlock_irqrestore(&nesqp->lock, qplockflags); 3039 + nes_rem_ref(&nesqp->ibqp); 3040 + return -EINVAL; 3041 + } 3042 + next_iwarp_state = NES_CQP_QP_IWARP_STATE_RTS; 3043 + if (nesqp->iwarp_state != NES_CQP_QP_IWARP_STATE_RTS) 3044 + next_iwarp_state |= NES_CQP_QP_CONTEXT_VALID | 3045 + NES_CQP_QP_ARP_VALID | NES_CQP_QP_ORD_VALID; 3046 + issue_modify_qp = 1; 3047 + nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_ESTABLISHED; 3048 + nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_RTS; 3049 + nesqp->hte_added = 1; 3050 + break; 3051 + case IB_QPS_SQD: 3052 + issue_modify_qp = 1; 3053 + nes_debug(NES_DBG_MOD_QP, "QP%u: new state=closing. SQ head=%u, SQ tail=%u\n", 3054 + nesqp->hwqp.qp_id, nesqp->hwqp.sq_head, nesqp->hwqp.sq_tail); 3055 + if (nesqp->iwarp_state == (u32)NES_CQP_QP_IWARP_STATE_CLOSING) { 3056 + spin_unlock_irqrestore(&nesqp->lock, qplockflags); 3057 + nes_rem_ref(&nesqp->ibqp); 3058 + return 0; 3059 + } else { 3060 + if (nesqp->iwarp_state > (u32)NES_CQP_QP_IWARP_STATE_CLOSING) { 3061 + nes_debug(NES_DBG_MOD_QP, "QP%u: State change to closing" 3062 + " ignored due to current iWARP state\n", 3063 + nesqp->hwqp.qp_id); 3064 + spin_unlock_irqrestore(&nesqp->lock, qplockflags); 3065 + nes_rem_ref(&nesqp->ibqp); 3066 + return -EINVAL; 3067 + } 3068 + if (nesqp->hw_iwarp_state != NES_AEQE_IWARP_STATE_RTS) { 3069 + nes_debug(NES_DBG_MOD_QP, "QP%u: State change to closing" 3070 + " already done based on hw state.\n", 3071 + nesqp->hwqp.qp_id); 3072 + issue_modify_qp = 0; 3073 + nesqp->in_disconnect = 0; 3074 + } 3075 + switch (nesqp->hw_iwarp_state) { 3076 + case NES_AEQE_IWARP_STATE_CLOSING: 3077 + next_iwarp_state = NES_CQP_QP_IWARP_STATE_CLOSING; 3078 + case NES_AEQE_IWARP_STATE_TERMINATE: 3079 + next_iwarp_state = NES_CQP_QP_IWARP_STATE_TERMINATE; 3080 + break; 3081 + case NES_AEQE_IWARP_STATE_ERROR: 3082 + next_iwarp_state = NES_CQP_QP_IWARP_STATE_ERROR; 3083 + break; 3084 + default: 3085 + next_iwarp_state = NES_CQP_QP_IWARP_STATE_CLOSING; 3086 + nesqp->in_disconnect = 1; 3087 + nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_CLOSING; 3088 + break; 3089 + } 3090 + } 3091 + break; 3092 + case IB_QPS_SQE: 3093 + nes_debug(NES_DBG_MOD_QP, "QP%u: new state = terminate\n", 3094 + nesqp->hwqp.qp_id); 3095 + if (nesqp->iwarp_state>=(u32)NES_CQP_QP_IWARP_STATE_TERMINATE) { 3096 + spin_unlock_irqrestore(&nesqp->lock, qplockflags); 3097 + nes_rem_ref(&nesqp->ibqp); 3098 + return -EINVAL; 3099 + } 3100 + /* next_iwarp_state = (NES_CQP_QP_IWARP_STATE_TERMINATE | 0x02000000); */ 3101 + next_iwarp_state = NES_CQP_QP_IWARP_STATE_TERMINATE; 3102 + nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_TERMINATE; 3103 + issue_modify_qp = 1; 3104 + nesqp->in_disconnect = 1; 3105 + break; 3106 + case IB_QPS_ERR: 3107 + case IB_QPS_RESET: 3108 + if (nesqp->iwarp_state == (u32)NES_CQP_QP_IWARP_STATE_ERROR) { 3109 + spin_unlock_irqrestore(&nesqp->lock, qplockflags); 3110 + nes_rem_ref(&nesqp->ibqp); 3111 + return -EINVAL; 3112 + } 3113 + nes_debug(NES_DBG_MOD_QP, "QP%u: new state = error\n", 3114 + nesqp->hwqp.qp_id); 3115 + next_iwarp_state = NES_CQP_QP_IWARP_STATE_ERROR; 3116 + /* next_iwarp_state = (NES_CQP_QP_IWARP_STATE_TERMINATE | 0x02000000); */ 3117 + if (nesqp->hte_added) { 3118 + nes_debug(NES_DBG_MOD_QP, "set CQP_QP_DEL_HTE\n"); 3119 + next_iwarp_state |= NES_CQP_QP_DEL_HTE; 3120 + nesqp->hte_added = 0; 3121 + } 3122 + if ((nesqp->hw_tcp_state > NES_AEQE_TCP_STATE_CLOSED) && 3123 + (nesqp->hw_tcp_state != NES_AEQE_TCP_STATE_TIME_WAIT)) { 3124 + next_iwarp_state |= NES_CQP_QP_RESET; 3125 + nesqp->in_disconnect = 1; 3126 + } else { 3127 + nes_debug(NES_DBG_MOD_QP, "QP%u NOT setting NES_CQP_QP_RESET since TCP state = %u\n", 3128 + nesqp->hwqp.qp_id, nesqp->hw_tcp_state); 3129 + dont_wait = 1; 3130 + } 3131 + issue_modify_qp = 1; 3132 + nesqp->hw_iwarp_state = NES_AEQE_IWARP_STATE_ERROR; 3133 + break; 3134 + default: 3135 + spin_unlock_irqrestore(&nesqp->lock, qplockflags); 3136 + nes_rem_ref(&nesqp->ibqp); 3137 + return -EINVAL; 3138 + break; 3139 + } 3140 + 3141 + nesqp->ibqp_state = attr->qp_state; 3142 + if (((nesqp->iwarp_state & NES_CQP_QP_IWARP_STATE_MASK) == 3143 + (u32)NES_CQP_QP_IWARP_STATE_RTS) && 3144 + ((next_iwarp_state & NES_CQP_QP_IWARP_STATE_MASK) > 3145 + (u32)NES_CQP_QP_IWARP_STATE_RTS)) { 3146 + nesqp->iwarp_state = next_iwarp_state & NES_CQP_QP_IWARP_STATE_MASK; 3147 + nes_debug(NES_DBG_MOD_QP, "Change nesqp->iwarp_state=%08x\n", 3148 + nesqp->iwarp_state); 3149 + issue_disconnect = 1; 3150 + } else { 3151 + nesqp->iwarp_state = next_iwarp_state & NES_CQP_QP_IWARP_STATE_MASK; 3152 + nes_debug(NES_DBG_MOD_QP, "Change nesqp->iwarp_state=%08x\n", 3153 + nesqp->iwarp_state); 3154 + } 3155 + } 3156 + 3157 + if (attr_mask & IB_QP_ACCESS_FLAGS) { 3158 + if (attr->qp_access_flags & IB_ACCESS_LOCAL_WRITE) { 3159 + nesqp->nesqp_context->misc |= cpu_to_le32(NES_QPCONTEXT_MISC_RDMA_WRITE_EN | 3160 + NES_QPCONTEXT_MISC_RDMA_READ_EN); 3161 + issue_modify_qp = 1; 3162 + } 3163 + if (attr->qp_access_flags & IB_ACCESS_REMOTE_WRITE) { 3164 + nesqp->nesqp_context->misc |= cpu_to_le32(NES_QPCONTEXT_MISC_RDMA_WRITE_EN); 3165 + issue_modify_qp = 1; 3166 + } 3167 + if (attr->qp_access_flags & IB_ACCESS_REMOTE_READ) { 3168 + nesqp->nesqp_context->misc |= cpu_to_le32(NES_QPCONTEXT_MISC_RDMA_READ_EN); 3169 + issue_modify_qp = 1; 3170 + } 3171 + if (attr->qp_access_flags & IB_ACCESS_MW_BIND) { 3172 + nesqp->nesqp_context->misc |= cpu_to_le32(NES_QPCONTEXT_MISC_WBIND_EN); 3173 + issue_modify_qp = 1; 3174 + } 3175 + 3176 + if (nesqp->user_mode) { 3177 + nesqp->nesqp_context->misc |= cpu_to_le32(NES_QPCONTEXT_MISC_RDMA_WRITE_EN | 3178 + NES_QPCONTEXT_MISC_RDMA_READ_EN); 3179 + issue_modify_qp = 1; 3180 + } 3181 + } 3182 + 3183 + original_last_aeq = nesqp->last_aeq; 3184 + spin_unlock_irqrestore(&nesqp->lock, qplockflags); 3185 + 3186 + nes_debug(NES_DBG_MOD_QP, "issue_modify_qp=%u\n", issue_modify_qp); 3187 + 3188 + ret = 0; 3189 + 3190 + 3191 + if (issue_modify_qp) { 3192 + nes_debug(NES_DBG_MOD_QP, "call nes_hw_modify_qp\n"); 3193 + ret = nes_hw_modify_qp(nesdev, nesqp, next_iwarp_state, 1); 3194 + if (ret) 3195 + nes_debug(NES_DBG_MOD_QP, "nes_hw_modify_qp (next_iwarp_state = 0x%08X)" 3196 + " failed for QP%u.\n", 3197 + next_iwarp_state, nesqp->hwqp.qp_id); 3198 + 3199 + } 3200 + 3201 + if ((issue_modify_qp) && (nesqp->ibqp_state > IB_QPS_RTS)) { 3202 + nes_debug(NES_DBG_MOD_QP, "QP%u Issued ModifyQP refcount (%d)," 3203 + " original_last_aeq = 0x%04X. last_aeq = 0x%04X.\n", 3204 + nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount), 3205 + original_last_aeq, nesqp->last_aeq); 3206 + if ((!ret) || 3207 + ((original_last_aeq != NES_AEQE_AEID_RDMAP_ROE_BAD_LLP_CLOSE) && 3208 + (ret))) { 3209 + if (dont_wait) { 3210 + if (nesqp->cm_id && nesqp->hw_tcp_state != 0) { 3211 + nes_debug(NES_DBG_MOD_QP, "QP%u Queuing fake disconnect for QP refcount (%d)," 3212 + " original_last_aeq = 0x%04X. last_aeq = 0x%04X.\n", 3213 + nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount), 3214 + original_last_aeq, nesqp->last_aeq); 3215 + /* this one is for the cm_disconnect thread */ 3216 + nes_add_ref(&nesqp->ibqp); 3217 + spin_lock_irqsave(&nesqp->lock, qplockflags); 3218 + nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED; 3219 + nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT; 3220 + spin_unlock_irqrestore(&nesqp->lock, qplockflags); 3221 + nes_cm_disconn(nesqp); 3222 + } else { 3223 + nes_debug(NES_DBG_MOD_QP, "QP%u No fake disconnect, QP refcount=%d\n", 3224 + nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount)); 3225 + nes_rem_ref(&nesqp->ibqp); 3226 + } 3227 + } else { 3228 + spin_lock_irqsave(&nesqp->lock, qplockflags); 3229 + if (nesqp->cm_id) { 3230 + /* These two are for the timer thread */ 3231 + if (atomic_inc_return(&nesqp->close_timer_started) == 1) { 3232 + nes_add_ref(&nesqp->ibqp); 3233 + nesqp->cm_id->add_ref(nesqp->cm_id); 3234 + nes_debug(NES_DBG_MOD_QP, "QP%u Not decrementing QP refcount (%d)," 3235 + " need ae to finish up, original_last_aeq = 0x%04X." 3236 + " last_aeq = 0x%04X, scheduling timer.\n", 3237 + nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount), 3238 + original_last_aeq, nesqp->last_aeq); 3239 + schedule_nes_timer(nesqp->cm_node, (struct sk_buff *) nesqp, NES_TIMER_TYPE_CLOSE, 1, 0); 3240 + } 3241 + spin_unlock_irqrestore(&nesqp->lock, qplockflags); 3242 + } else { 3243 + spin_unlock_irqrestore(&nesqp->lock, qplockflags); 3244 + nes_debug(NES_DBG_MOD_QP, "QP%u Not decrementing QP refcount (%d)," 3245 + " need ae to finish up, original_last_aeq = 0x%04X." 3246 + " last_aeq = 0x%04X.\n", 3247 + nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount), 3248 + original_last_aeq, nesqp->last_aeq); 3249 + } 3250 + } 3251 + } else { 3252 + nes_debug(NES_DBG_MOD_QP, "QP%u Decrementing QP refcount (%d), No ae to finish up," 3253 + " original_last_aeq = 0x%04X. last_aeq = 0x%04X.\n", 3254 + nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount), 3255 + original_last_aeq, nesqp->last_aeq); 3256 + nes_rem_ref(&nesqp->ibqp); 3257 + } 3258 + } else { 3259 + nes_debug(NES_DBG_MOD_QP, "QP%u Decrementing QP refcount (%d), No ae to finish up," 3260 + " original_last_aeq = 0x%04X. last_aeq = 0x%04X.\n", 3261 + nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount), 3262 + original_last_aeq, nesqp->last_aeq); 3263 + nes_rem_ref(&nesqp->ibqp); 3264 + } 3265 + 3266 + err = 0; 3267 + 3268 + nes_debug(NES_DBG_MOD_QP, "QP%u Leaving, refcount=%d\n", 3269 + nesqp->hwqp.qp_id, atomic_read(&nesqp->refcount)); 3270 + 3271 + return err; 3272 + } 3273 + 3274 + 3275 + /** 3276 + * nes_muticast_attach 3277 + */ 3278 + static int nes_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) 3279 + { 3280 + nes_debug(NES_DBG_INIT, "\n"); 3281 + return -ENOSYS; 3282 + } 3283 + 3284 + 3285 + /** 3286 + * nes_multicast_detach 3287 + */ 3288 + static int nes_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) 3289 + { 3290 + nes_debug(NES_DBG_INIT, "\n"); 3291 + return -ENOSYS; 3292 + } 3293 + 3294 + 3295 + /** 3296 + * nes_process_mad 3297 + */ 3298 + static int nes_process_mad(struct ib_device *ibdev, int mad_flags, 3299 + u8 port_num, struct ib_wc *in_wc, struct ib_grh *in_grh, 3300 + struct ib_mad *in_mad, struct ib_mad *out_mad) 3301 + { 3302 + nes_debug(NES_DBG_INIT, "\n"); 3303 + return -ENOSYS; 3304 + } 3305 + 3306 + static inline void 3307 + fill_wqe_sg_send(struct nes_hw_qp_wqe *wqe, struct ib_send_wr *ib_wr, u32 uselkey) 3308 + { 3309 + int sge_index; 3310 + int total_payload_length = 0; 3311 + for (sge_index = 0; sge_index < ib_wr->num_sge; sge_index++) { 3312 + set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_FRAG0_LOW_IDX+(sge_index*4), 3313 + ib_wr->sg_list[sge_index].addr); 3314 + set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_LENGTH0_IDX + (sge_index*4), 3315 + ib_wr->sg_list[sge_index].length); 3316 + if (uselkey) 3317 + set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_STAG0_IDX + (sge_index*4), 3318 + (ib_wr->sg_list[sge_index].lkey)); 3319 + else 3320 + set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_STAG0_IDX + (sge_index*4), 0); 3321 + 3322 + total_payload_length += ib_wr->sg_list[sge_index].length; 3323 + } 3324 + nes_debug(NES_DBG_IW_TX, "UC UC UC, sending total_payload_length=%u \n", 3325 + total_payload_length); 3326 + set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX, 3327 + total_payload_length); 3328 + } 3329 + 3330 + /** 3331 + * nes_post_send 3332 + */ 3333 + static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, 3334 + struct ib_send_wr **bad_wr) 3335 + { 3336 + u64 u64temp; 3337 + unsigned long flags = 0; 3338 + struct nes_vnic *nesvnic = to_nesvnic(ibqp->device); 3339 + struct nes_device *nesdev = nesvnic->nesdev; 3340 + struct nes_qp *nesqp = to_nesqp(ibqp); 3341 + struct nes_hw_qp_wqe *wqe; 3342 + int err; 3343 + u32 qsize = nesqp->hwqp.sq_size; 3344 + u32 head; 3345 + u32 wqe_misc; 3346 + u32 wqe_count; 3347 + u32 counter; 3348 + u32 total_payload_length; 3349 + 3350 + err = 0; 3351 + wqe_misc = 0; 3352 + wqe_count = 0; 3353 + total_payload_length = 0; 3354 + 3355 + if (nesqp->ibqp_state > IB_QPS_RTS) 3356 + return -EINVAL; 3357 + 3358 + spin_lock_irqsave(&nesqp->lock, flags); 3359 + 3360 + head = nesqp->hwqp.sq_head; 3361 + 3362 + while (ib_wr) { 3363 + /* Check for SQ overflow */ 3364 + if (((head + (2 * qsize) - nesqp->hwqp.sq_tail) % qsize) == (qsize - 1)) { 3365 + err = -EINVAL; 3366 + break; 3367 + } 3368 + 3369 + wqe = &nesqp->hwqp.sq_vbase[head]; 3370 + /* nes_debug(NES_DBG_IW_TX, "processing sq wqe for QP%u at %p, head = %u.\n", 3371 + nesqp->hwqp.qp_id, wqe, head); */ 3372 + nes_fill_init_qp_wqe(wqe, nesqp, head); 3373 + u64temp = (u64)(ib_wr->wr_id); 3374 + set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_COMP_SCRATCH_LOW_IDX, 3375 + u64temp); 3376 + switch (ib_wr->opcode) { 3377 + case IB_WR_SEND: 3378 + if (ib_wr->send_flags & IB_SEND_SOLICITED) { 3379 + wqe_misc = NES_IWARP_SQ_OP_SENDSE; 3380 + } else { 3381 + wqe_misc = NES_IWARP_SQ_OP_SEND; 3382 + } 3383 + if (ib_wr->num_sge > nesdev->nesadapter->max_sge) { 3384 + err = -EINVAL; 3385 + break; 3386 + } 3387 + if (ib_wr->send_flags & IB_SEND_FENCE) { 3388 + wqe_misc |= NES_IWARP_SQ_WQE_LOCAL_FENCE; 3389 + } 3390 + if ((ib_wr->send_flags & IB_SEND_INLINE) && 3391 + ((nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) == 0) && 3392 + (ib_wr->sg_list[0].length <= 64)) { 3393 + memcpy(&wqe->wqe_words[NES_IWARP_SQ_WQE_IMM_DATA_START_IDX], 3394 + (void *)(unsigned long)ib_wr->sg_list[0].addr, ib_wr->sg_list[0].length); 3395 + set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX, 3396 + ib_wr->sg_list[0].length); 3397 + wqe_misc |= NES_IWARP_SQ_WQE_IMM_DATA; 3398 + } else { 3399 + fill_wqe_sg_send(wqe, ib_wr, 1); 3400 + } 3401 + 3402 + break; 3403 + case IB_WR_RDMA_WRITE: 3404 + wqe_misc = NES_IWARP_SQ_OP_RDMAW; 3405 + if (ib_wr->num_sge > nesdev->nesadapter->max_sge) { 3406 + nes_debug(NES_DBG_IW_TX, "Exceeded max sge, ib_wr=%u, max=%u\n", 3407 + ib_wr->num_sge, 3408 + nesdev->nesadapter->max_sge); 3409 + err = -EINVAL; 3410 + break; 3411 + } 3412 + if (ib_wr->send_flags & IB_SEND_FENCE) { 3413 + wqe_misc |= NES_IWARP_SQ_WQE_LOCAL_FENCE; 3414 + } 3415 + 3416 + set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_STAG_IDX, 3417 + ib_wr->wr.rdma.rkey); 3418 + set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_TO_LOW_IDX, 3419 + ib_wr->wr.rdma.remote_addr); 3420 + 3421 + if ((ib_wr->send_flags & IB_SEND_INLINE) && 3422 + ((nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) == 0) && 3423 + (ib_wr->sg_list[0].length <= 64)) { 3424 + memcpy(&wqe->wqe_words[NES_IWARP_SQ_WQE_IMM_DATA_START_IDX], 3425 + (void *)(unsigned long)ib_wr->sg_list[0].addr, ib_wr->sg_list[0].length); 3426 + set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX, 3427 + ib_wr->sg_list[0].length); 3428 + wqe_misc |= NES_IWARP_SQ_WQE_IMM_DATA; 3429 + } else { 3430 + fill_wqe_sg_send(wqe, ib_wr, 1); 3431 + } 3432 + wqe->wqe_words[NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX] = 3433 + wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX]; 3434 + break; 3435 + case IB_WR_RDMA_READ: 3436 + /* iWARP only supports 1 sge for RDMA reads */ 3437 + if (ib_wr->num_sge > 1) { 3438 + nes_debug(NES_DBG_IW_TX, "Exceeded max sge, ib_wr=%u, max=1\n", 3439 + ib_wr->num_sge); 3440 + err = -EINVAL; 3441 + break; 3442 + } 3443 + wqe_misc = NES_IWARP_SQ_OP_RDMAR; 3444 + set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_TO_LOW_IDX, 3445 + ib_wr->wr.rdma.remote_addr); 3446 + set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_STAG_IDX, 3447 + ib_wr->wr.rdma.rkey); 3448 + set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX, 3449 + ib_wr->sg_list->length); 3450 + set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_FRAG0_LOW_IDX, 3451 + ib_wr->sg_list->addr); 3452 + set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_STAG0_IDX, 3453 + ib_wr->sg_list->lkey); 3454 + break; 3455 + default: 3456 + /* error */ 3457 + err = -EINVAL; 3458 + break; 3459 + } 3460 + 3461 + if (ib_wr->send_flags & IB_SEND_SIGNALED) { 3462 + wqe_misc |= NES_IWARP_SQ_WQE_SIGNALED_COMPL; 3463 + } 3464 + wqe->wqe_words[NES_IWARP_SQ_WQE_MISC_IDX] = cpu_to_le32(wqe_misc); 3465 + 3466 + ib_wr = ib_wr->next; 3467 + head++; 3468 + wqe_count++; 3469 + if (head >= qsize) 3470 + head = 0; 3471 + 3472 + } 3473 + 3474 + nesqp->hwqp.sq_head = head; 3475 + barrier(); 3476 + while (wqe_count) { 3477 + counter = min(wqe_count, ((u32)255)); 3478 + wqe_count -= counter; 3479 + nes_write32(nesdev->regs + NES_WQE_ALLOC, 3480 + (counter << 24) | 0x00800000 | nesqp->hwqp.qp_id); 3481 + } 3482 + 3483 + spin_unlock_irqrestore(&nesqp->lock, flags); 3484 + 3485 + if (err) 3486 + *bad_wr = ib_wr; 3487 + return err; 3488 + } 3489 + 3490 + 3491 + /** 3492 + * nes_post_recv 3493 + */ 3494 + static int nes_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr, 3495 + struct ib_recv_wr **bad_wr) 3496 + { 3497 + u64 u64temp; 3498 + unsigned long flags = 0; 3499 + struct nes_vnic *nesvnic = to_nesvnic(ibqp->device); 3500 + struct nes_device *nesdev = nesvnic->nesdev; 3501 + struct nes_qp *nesqp = to_nesqp(ibqp); 3502 + struct nes_hw_qp_wqe *wqe; 3503 + int err = 0; 3504 + int sge_index; 3505 + u32 qsize = nesqp->hwqp.rq_size; 3506 + u32 head; 3507 + u32 wqe_count = 0; 3508 + u32 counter; 3509 + u32 total_payload_length; 3510 + 3511 + if (nesqp->ibqp_state > IB_QPS_RTS) 3512 + return -EINVAL; 3513 + 3514 + spin_lock_irqsave(&nesqp->lock, flags); 3515 + 3516 + head = nesqp->hwqp.rq_head; 3517 + 3518 + while (ib_wr) { 3519 + if (ib_wr->num_sge > nesdev->nesadapter->max_sge) { 3520 + err = -EINVAL; 3521 + break; 3522 + } 3523 + /* Check for RQ overflow */ 3524 + if (((head + (2 * qsize) - nesqp->hwqp.rq_tail) % qsize) == (qsize - 1)) { 3525 + err = -EINVAL; 3526 + break; 3527 + } 3528 + 3529 + nes_debug(NES_DBG_IW_RX, "ibwr sge count = %u.\n", ib_wr->num_sge); 3530 + wqe = &nesqp->hwqp.rq_vbase[head]; 3531 + 3532 + /* nes_debug(NES_DBG_IW_RX, "QP%u:processing rq wqe at %p, head = %u.\n", 3533 + nesqp->hwqp.qp_id, wqe, head); */ 3534 + nes_fill_init_qp_wqe(wqe, nesqp, head); 3535 + u64temp = (u64)(ib_wr->wr_id); 3536 + set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_COMP_SCRATCH_LOW_IDX, 3537 + u64temp); 3538 + total_payload_length = 0; 3539 + for (sge_index=0; sge_index < ib_wr->num_sge; sge_index++) { 3540 + set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_RQ_WQE_FRAG0_LOW_IDX+(sge_index*4), 3541 + ib_wr->sg_list[sge_index].addr); 3542 + set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_RQ_WQE_LENGTH0_IDX+(sge_index*4), 3543 + ib_wr->sg_list[sge_index].length); 3544 + set_wqe_32bit_value(wqe->wqe_words,NES_IWARP_RQ_WQE_STAG0_IDX+(sge_index*4), 3545 + ib_wr->sg_list[sge_index].lkey); 3546 + 3547 + total_payload_length += ib_wr->sg_list[sge_index].length; 3548 + } 3549 + set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_RQ_WQE_TOTAL_PAYLOAD_IDX, 3550 + total_payload_length); 3551 + 3552 + ib_wr = ib_wr->next; 3553 + head++; 3554 + wqe_count++; 3555 + if (head >= qsize) 3556 + head = 0; 3557 + } 3558 + 3559 + nesqp->hwqp.rq_head = head; 3560 + barrier(); 3561 + while (wqe_count) { 3562 + counter = min(wqe_count, ((u32)255)); 3563 + wqe_count -= counter; 3564 + nes_write32(nesdev->regs+NES_WQE_ALLOC, (counter<<24) | nesqp->hwqp.qp_id); 3565 + } 3566 + 3567 + spin_unlock_irqrestore(&nesqp->lock, flags); 3568 + 3569 + if (err) 3570 + *bad_wr = ib_wr; 3571 + return err; 3572 + } 3573 + 3574 + 3575 + /** 3576 + * nes_poll_cq 3577 + */ 3578 + static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry) 3579 + { 3580 + u64 u64temp; 3581 + u64 wrid; 3582 + /* u64 u64temp; */ 3583 + unsigned long flags = 0; 3584 + struct nes_vnic *nesvnic = to_nesvnic(ibcq->device); 3585 + struct nes_device *nesdev = nesvnic->nesdev; 3586 + struct nes_cq *nescq = to_nescq(ibcq); 3587 + struct nes_qp *nesqp; 3588 + struct nes_hw_cqe cqe; 3589 + u32 head; 3590 + u32 wq_tail; 3591 + u32 cq_size; 3592 + u32 cqe_count = 0; 3593 + u32 wqe_index; 3594 + u32 u32temp; 3595 + /* u32 counter; */ 3596 + 3597 + nes_debug(NES_DBG_CQ, "\n"); 3598 + 3599 + spin_lock_irqsave(&nescq->lock, flags); 3600 + 3601 + head = nescq->hw_cq.cq_head; 3602 + cq_size = nescq->hw_cq.cq_size; 3603 + 3604 + while (cqe_count < num_entries) { 3605 + if (le32_to_cpu(nescq->hw_cq.cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX]) & 3606 + NES_CQE_VALID) { 3607 + cqe = nescq->hw_cq.cq_vbase[head]; 3608 + nescq->hw_cq.cq_vbase[head].cqe_words[NES_CQE_OPCODE_IDX] = 0; 3609 + u32temp = le32_to_cpu(cqe.cqe_words[NES_CQE_COMP_COMP_CTX_LOW_IDX]); 3610 + wqe_index = u32temp & 3611 + (nesdev->nesadapter->max_qp_wr - 1); 3612 + u32temp &= ~(NES_SW_CONTEXT_ALIGN-1); 3613 + /* parse CQE, get completion context from WQE (either rq or sq */ 3614 + u64temp = (((u64)(le32_to_cpu(cqe.cqe_words[NES_CQE_COMP_COMP_CTX_HIGH_IDX])))<<32) | 3615 + ((u64)u32temp); 3616 + nesqp = *((struct nes_qp **)&u64temp); 3617 + memset(entry, 0, sizeof *entry); 3618 + if (cqe.cqe_words[NES_CQE_ERROR_CODE_IDX] == 0) { 3619 + entry->status = IB_WC_SUCCESS; 3620 + } else { 3621 + entry->status = IB_WC_WR_FLUSH_ERR; 3622 + } 3623 + 3624 + entry->qp = &nesqp->ibqp; 3625 + entry->src_qp = nesqp->hwqp.qp_id; 3626 + 3627 + if (le32_to_cpu(cqe.cqe_words[NES_CQE_OPCODE_IDX]) & NES_CQE_SQ) { 3628 + if (nesqp->skip_lsmm) { 3629 + nesqp->skip_lsmm = 0; 3630 + wq_tail = nesqp->hwqp.sq_tail++; 3631 + } 3632 + 3633 + /* Working on a SQ Completion*/ 3634 + wq_tail = wqe_index; 3635 + nesqp->hwqp.sq_tail = (wqe_index+1)&(nesqp->hwqp.sq_size - 1); 3636 + wrid = (((u64)(cpu_to_le32((u32)nesqp->hwqp.sq_vbase[wq_tail]. 3637 + wqe_words[NES_IWARP_SQ_WQE_COMP_SCRATCH_HIGH_IDX]))) << 32) | 3638 + ((u64)(cpu_to_le32((u32)nesqp->hwqp.sq_vbase[wq_tail]. 3639 + wqe_words[NES_IWARP_SQ_WQE_COMP_SCRATCH_LOW_IDX]))); 3640 + entry->byte_len = le32_to_cpu(nesqp->hwqp.sq_vbase[wq_tail]. 3641 + wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX]); 3642 + 3643 + switch (le32_to_cpu(nesqp->hwqp.sq_vbase[wq_tail]. 3644 + wqe_words[NES_IWARP_SQ_WQE_MISC_IDX]) & 0x3f) { 3645 + case NES_IWARP_SQ_OP_RDMAW: 3646 + nes_debug(NES_DBG_CQ, "Operation = RDMA WRITE.\n"); 3647 + entry->opcode = IB_WC_RDMA_WRITE; 3648 + break; 3649 + case NES_IWARP_SQ_OP_RDMAR: 3650 + nes_debug(NES_DBG_CQ, "Operation = RDMA READ.\n"); 3651 + entry->opcode = IB_WC_RDMA_READ; 3652 + entry->byte_len = le32_to_cpu(nesqp->hwqp.sq_vbase[wq_tail]. 3653 + wqe_words[NES_IWARP_SQ_WQE_RDMA_LENGTH_IDX]); 3654 + break; 3655 + case NES_IWARP_SQ_OP_SENDINV: 3656 + case NES_IWARP_SQ_OP_SENDSEINV: 3657 + case NES_IWARP_SQ_OP_SEND: 3658 + case NES_IWARP_SQ_OP_SENDSE: 3659 + nes_debug(NES_DBG_CQ, "Operation = Send.\n"); 3660 + entry->opcode = IB_WC_SEND; 3661 + break; 3662 + } 3663 + } else { 3664 + /* Working on a RQ Completion*/ 3665 + wq_tail = wqe_index; 3666 + nesqp->hwqp.rq_tail = (wqe_index+1)&(nesqp->hwqp.rq_size - 1); 3667 + entry->byte_len = le32_to_cpu(cqe.cqe_words[NES_CQE_PAYLOAD_LENGTH_IDX]); 3668 + wrid = ((u64)(le32_to_cpu(nesqp->hwqp.rq_vbase[wq_tail].wqe_words[NES_IWARP_RQ_WQE_COMP_SCRATCH_LOW_IDX]))) | 3669 + ((u64)(le32_to_cpu(nesqp->hwqp.rq_vbase[wq_tail].wqe_words[NES_IWARP_RQ_WQE_COMP_SCRATCH_HIGH_IDX]))<<32); 3670 + entry->opcode = IB_WC_RECV; 3671 + } 3672 + entry->wr_id = wrid; 3673 + 3674 + if (++head >= cq_size) 3675 + head = 0; 3676 + cqe_count++; 3677 + nescq->polled_completions++; 3678 + if ((nescq->polled_completions > (cq_size / 2)) || 3679 + (nescq->polled_completions == 255)) { 3680 + nes_debug(NES_DBG_CQ, "CQ%u Issuing CQE Allocate since more than half of cqes" 3681 + " are pending %u of %u.\n", 3682 + nescq->hw_cq.cq_number, nescq->polled_completions, cq_size); 3683 + nes_write32(nesdev->regs+NES_CQE_ALLOC, 3684 + nescq->hw_cq.cq_number | (nescq->polled_completions << 16)); 3685 + nescq->polled_completions = 0; 3686 + } 3687 + entry++; 3688 + } else 3689 + break; 3690 + } 3691 + 3692 + if (nescq->polled_completions) { 3693 + nes_write32(nesdev->regs+NES_CQE_ALLOC, 3694 + nescq->hw_cq.cq_number | (nescq->polled_completions << 16)); 3695 + nescq->polled_completions = 0; 3696 + } 3697 + 3698 + nescq->hw_cq.cq_head = head; 3699 + nes_debug(NES_DBG_CQ, "Reporting %u completions for CQ%u.\n", 3700 + cqe_count, nescq->hw_cq.cq_number); 3701 + 3702 + spin_unlock_irqrestore(&nescq->lock, flags); 3703 + 3704 + return cqe_count; 3705 + } 3706 + 3707 + 3708 + /** 3709 + * nes_req_notify_cq 3710 + */ 3711 + static int nes_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags notify_flags) 3712 + { 3713 + struct nes_vnic *nesvnic = to_nesvnic(ibcq->device); 3714 + struct nes_device *nesdev = nesvnic->nesdev; 3715 + struct nes_cq *nescq = to_nescq(ibcq); 3716 + u32 cq_arm; 3717 + 3718 + nes_debug(NES_DBG_CQ, "Requesting notification for CQ%u.\n", 3719 + nescq->hw_cq.cq_number); 3720 + 3721 + cq_arm = nescq->hw_cq.cq_number; 3722 + if ((notify_flags & IB_CQ_SOLICITED_MASK) == IB_CQ_NEXT_COMP) 3723 + cq_arm |= NES_CQE_ALLOC_NOTIFY_NEXT; 3724 + else if ((notify_flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED) 3725 + cq_arm |= NES_CQE_ALLOC_NOTIFY_SE; 3726 + else 3727 + return -EINVAL; 3728 + 3729 + nes_write32(nesdev->regs+NES_CQE_ALLOC, cq_arm); 3730 + nes_read32(nesdev->regs+NES_CQE_ALLOC); 3731 + 3732 + return 0; 3733 + } 3734 + 3735 + 3736 + /** 3737 + * nes_init_ofa_device 3738 + */ 3739 + struct nes_ib_device *nes_init_ofa_device(struct net_device *netdev) 3740 + { 3741 + struct nes_ib_device *nesibdev; 3742 + struct nes_vnic *nesvnic = netdev_priv(netdev); 3743 + struct nes_device *nesdev = nesvnic->nesdev; 3744 + 3745 + nesibdev = (struct nes_ib_device *)ib_alloc_device(sizeof(struct nes_ib_device)); 3746 + if (nesibdev == NULL) { 3747 + return NULL; 3748 + } 3749 + strlcpy(nesibdev->ibdev.name, "nes%d", IB_DEVICE_NAME_MAX); 3750 + nesibdev->ibdev.owner = THIS_MODULE; 3751 + 3752 + nesibdev->ibdev.node_type = RDMA_NODE_RNIC; 3753 + memset(&nesibdev->ibdev.node_guid, 0, sizeof(nesibdev->ibdev.node_guid)); 3754 + memcpy(&nesibdev->ibdev.node_guid, netdev->dev_addr, 6); 3755 + 3756 + nesibdev->ibdev.uverbs_cmd_mask = 3757 + (1ull << IB_USER_VERBS_CMD_GET_CONTEXT) | 3758 + (1ull << IB_USER_VERBS_CMD_QUERY_DEVICE) | 3759 + (1ull << IB_USER_VERBS_CMD_QUERY_PORT) | 3760 + (1ull << IB_USER_VERBS_CMD_ALLOC_PD) | 3761 + (1ull << IB_USER_VERBS_CMD_DEALLOC_PD) | 3762 + (1ull << IB_USER_VERBS_CMD_REG_MR) | 3763 + (1ull << IB_USER_VERBS_CMD_DEREG_MR) | 3764 + (1ull << IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL) | 3765 + (1ull << IB_USER_VERBS_CMD_CREATE_CQ) | 3766 + (1ull << IB_USER_VERBS_CMD_DESTROY_CQ) | 3767 + (1ull << IB_USER_VERBS_CMD_CREATE_AH) | 3768 + (1ull << IB_USER_VERBS_CMD_DESTROY_AH) | 3769 + (1ull << IB_USER_VERBS_CMD_REQ_NOTIFY_CQ) | 3770 + (1ull << IB_USER_VERBS_CMD_CREATE_QP) | 3771 + (1ull << IB_USER_VERBS_CMD_MODIFY_QP) | 3772 + (1ull << IB_USER_VERBS_CMD_POLL_CQ) | 3773 + (1ull << IB_USER_VERBS_CMD_DESTROY_QP) | 3774 + (1ull << IB_USER_VERBS_CMD_ALLOC_MW) | 3775 + (1ull << IB_USER_VERBS_CMD_BIND_MW) | 3776 + (1ull << IB_USER_VERBS_CMD_DEALLOC_MW) | 3777 + (1ull << IB_USER_VERBS_CMD_POST_RECV) | 3778 + (1ull << IB_USER_VERBS_CMD_POST_SEND); 3779 + 3780 + nesibdev->ibdev.phys_port_cnt = 1; 3781 + nesibdev->ibdev.num_comp_vectors = 1; 3782 + nesibdev->ibdev.dma_device = &nesdev->pcidev->dev; 3783 + nesibdev->ibdev.class_dev.dev = &nesdev->pcidev->dev; 3784 + nesibdev->ibdev.query_device = nes_query_device; 3785 + nesibdev->ibdev.query_port = nes_query_port; 3786 + nesibdev->ibdev.modify_port = nes_modify_port; 3787 + nesibdev->ibdev.query_pkey = nes_query_pkey; 3788 + nesibdev->ibdev.query_gid = nes_query_gid; 3789 + nesibdev->ibdev.alloc_ucontext = nes_alloc_ucontext; 3790 + nesibdev->ibdev.dealloc_ucontext = nes_dealloc_ucontext; 3791 + nesibdev->ibdev.mmap = nes_mmap; 3792 + nesibdev->ibdev.alloc_pd = nes_alloc_pd; 3793 + nesibdev->ibdev.dealloc_pd = nes_dealloc_pd; 3794 + nesibdev->ibdev.create_ah = nes_create_ah; 3795 + nesibdev->ibdev.destroy_ah = nes_destroy_ah; 3796 + nesibdev->ibdev.create_qp = nes_create_qp; 3797 + nesibdev->ibdev.modify_qp = nes_modify_qp; 3798 + nesibdev->ibdev.query_qp = nes_query_qp; 3799 + nesibdev->ibdev.destroy_qp = nes_destroy_qp; 3800 + nesibdev->ibdev.create_cq = nes_create_cq; 3801 + nesibdev->ibdev.destroy_cq = nes_destroy_cq; 3802 + nesibdev->ibdev.poll_cq = nes_poll_cq; 3803 + nesibdev->ibdev.get_dma_mr = nes_get_dma_mr; 3804 + nesibdev->ibdev.reg_phys_mr = nes_reg_phys_mr; 3805 + nesibdev->ibdev.reg_user_mr = nes_reg_user_mr; 3806 + nesibdev->ibdev.dereg_mr = nes_dereg_mr; 3807 + nesibdev->ibdev.alloc_mw = nes_alloc_mw; 3808 + nesibdev->ibdev.dealloc_mw = nes_dealloc_mw; 3809 + nesibdev->ibdev.bind_mw = nes_bind_mw; 3810 + 3811 + nesibdev->ibdev.alloc_fmr = nes_alloc_fmr; 3812 + nesibdev->ibdev.unmap_fmr = nes_unmap_fmr; 3813 + nesibdev->ibdev.dealloc_fmr = nes_dealloc_fmr; 3814 + nesibdev->ibdev.map_phys_fmr = nes_map_phys_fmr; 3815 + 3816 + nesibdev->ibdev.attach_mcast = nes_multicast_attach; 3817 + nesibdev->ibdev.detach_mcast = nes_multicast_detach; 3818 + nesibdev->ibdev.process_mad = nes_process_mad; 3819 + 3820 + nesibdev->ibdev.req_notify_cq = nes_req_notify_cq; 3821 + nesibdev->ibdev.post_send = nes_post_send; 3822 + nesibdev->ibdev.post_recv = nes_post_recv; 3823 + 3824 + nesibdev->ibdev.iwcm = kzalloc(sizeof(*nesibdev->ibdev.iwcm), GFP_KERNEL); 3825 + if (nesibdev->ibdev.iwcm == NULL) { 3826 + ib_dealloc_device(&nesibdev->ibdev); 3827 + return NULL; 3828 + } 3829 + nesibdev->ibdev.iwcm->add_ref = nes_add_ref; 3830 + nesibdev->ibdev.iwcm->rem_ref = nes_rem_ref; 3831 + nesibdev->ibdev.iwcm->get_qp = nes_get_qp; 3832 + nesibdev->ibdev.iwcm->connect = nes_connect; 3833 + nesibdev->ibdev.iwcm->accept = nes_accept; 3834 + nesibdev->ibdev.iwcm->reject = nes_reject; 3835 + nesibdev->ibdev.iwcm->create_listen = nes_create_listen; 3836 + nesibdev->ibdev.iwcm->destroy_listen = nes_destroy_listen; 3837 + 3838 + return nesibdev; 3839 + } 3840 + 3841 + 3842 + /** 3843 + * nes_destroy_ofa_device 3844 + */ 3845 + void nes_destroy_ofa_device(struct nes_ib_device *nesibdev) 3846 + { 3847 + if (nesibdev == NULL) 3848 + return; 3849 + 3850 + nes_unregister_ofa_device(nesibdev); 3851 + 3852 + kfree(nesibdev->ibdev.iwcm); 3853 + ib_dealloc_device(&nesibdev->ibdev); 3854 + } 3855 + 3856 + 3857 + /** 3858 + * nes_register_ofa_device 3859 + */ 3860 + int nes_register_ofa_device(struct nes_ib_device *nesibdev) 3861 + { 3862 + struct nes_vnic *nesvnic = nesibdev->nesvnic; 3863 + struct nes_device *nesdev = nesvnic->nesdev; 3864 + struct nes_adapter *nesadapter = nesdev->nesadapter; 3865 + int i, ret; 3866 + 3867 + ret = ib_register_device(&nesvnic->nesibdev->ibdev); 3868 + if (ret) { 3869 + return ret; 3870 + } 3871 + 3872 + /* Get the resources allocated to this device */ 3873 + nesibdev->max_cq = (nesadapter->max_cq-NES_FIRST_QPN) / nesadapter->port_count; 3874 + nesibdev->max_mr = nesadapter->max_mr / nesadapter->port_count; 3875 + nesibdev->max_qp = (nesadapter->max_qp-NES_FIRST_QPN) / nesadapter->port_count; 3876 + nesibdev->max_pd = nesadapter->max_pd / nesadapter->port_count; 3877 + 3878 + for (i = 0; i < ARRAY_SIZE(nes_class_attributes); ++i) { 3879 + ret = class_device_create_file(&nesibdev->ibdev.class_dev, nes_class_attributes[i]); 3880 + if (ret) { 3881 + while (i > 0) { 3882 + i--; 3883 + class_device_remove_file(&nesibdev->ibdev.class_dev, 3884 + nes_class_attributes[i]); 3885 + } 3886 + ib_unregister_device(&nesibdev->ibdev); 3887 + return ret; 3888 + } 3889 + } 3890 + 3891 + nesvnic->of_device_registered = 1; 3892 + 3893 + return 0; 3894 + } 3895 + 3896 + 3897 + /** 3898 + * nes_unregister_ofa_device 3899 + */ 3900 + void nes_unregister_ofa_device(struct nes_ib_device *nesibdev) 3901 + { 3902 + struct nes_vnic *nesvnic = nesibdev->nesvnic; 3903 + int i; 3904 + 3905 + if (nesibdev == NULL) 3906 + return; 3907 + 3908 + for (i = 0; i < ARRAY_SIZE(nes_class_attributes); ++i) { 3909 + class_device_remove_file(&nesibdev->ibdev.class_dev, nes_class_attributes[i]); 3910 + } 3911 + 3912 + if (nesvnic->of_device_registered) { 3913 + ib_unregister_device(&nesibdev->ibdev); 3914 + } 3915 + 3916 + nesvnic->of_device_registered = 0; 3917 + }
+169
drivers/infiniband/hw/nes/nes_verbs.h
···
··· 1 + /* 2 + * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved. 3 + * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. 4 + * 5 + * This software is available to you under a choice of one of two 6 + * licenses. You may choose to be licensed under the terms of the GNU 7 + * General Public License (GPL) Version 2, available from the file 8 + * COPYING in the main directory of this source tree, or the 9 + * OpenIB.org BSD license below: 10 + * 11 + * Redistribution and use in source and binary forms, with or 12 + * without modification, are permitted provided that the following 13 + * conditions are met: 14 + * 15 + * - Redistributions of source code must retain the above 16 + * copyright notice, this list of conditions and the following 17 + * disclaimer. 18 + * 19 + * - Redistributions in binary form must reproduce the above 20 + * copyright notice, this list of conditions and the following 21 + * disclaimer in the documentation and/or other materials 22 + * provided with the distribution. 23 + * 24 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 28 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 29 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 30 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 + * SOFTWARE. 32 + * 33 + */ 34 + 35 + #ifndef NES_VERBS_H 36 + #define NES_VERBS_H 37 + 38 + struct nes_device; 39 + 40 + #define NES_MAX_USER_DB_REGIONS 4096 41 + #define NES_MAX_USER_WQ_REGIONS 4096 42 + 43 + struct nes_ucontext { 44 + struct ib_ucontext ibucontext; 45 + struct nes_device *nesdev; 46 + unsigned long mmap_wq_offset; 47 + unsigned long mmap_cq_offset; /* to be removed */ 48 + int index; /* rnic index (minor) */ 49 + unsigned long allocated_doorbells[BITS_TO_LONGS(NES_MAX_USER_DB_REGIONS)]; 50 + u16 mmap_db_index[NES_MAX_USER_DB_REGIONS]; 51 + u16 first_free_db; 52 + unsigned long allocated_wqs[BITS_TO_LONGS(NES_MAX_USER_WQ_REGIONS)]; 53 + struct nes_qp *mmap_nesqp[NES_MAX_USER_WQ_REGIONS]; 54 + u16 first_free_wq; 55 + struct list_head cq_reg_mem_list; 56 + struct list_head qp_reg_mem_list; 57 + u32 mcrqf; 58 + atomic_t usecnt; 59 + }; 60 + 61 + struct nes_pd { 62 + struct ib_pd ibpd; 63 + u16 pd_id; 64 + atomic_t sqp_count; 65 + u16 mmap_db_index; 66 + }; 67 + 68 + struct nes_mr { 69 + union { 70 + struct ib_mr ibmr; 71 + struct ib_mw ibmw; 72 + struct ib_fmr ibfmr; 73 + }; 74 + struct ib_umem *region; 75 + u16 pbls_used; 76 + u8 mode; 77 + u8 pbl_4k; 78 + }; 79 + 80 + struct nes_hw_pb { 81 + __le32 pa_low; 82 + __le32 pa_high; 83 + }; 84 + 85 + struct nes_vpbl { 86 + dma_addr_t pbl_pbase; 87 + struct nes_hw_pb *pbl_vbase; 88 + }; 89 + 90 + struct nes_root_vpbl { 91 + dma_addr_t pbl_pbase; 92 + struct nes_hw_pb *pbl_vbase; 93 + struct nes_vpbl *leaf_vpbl; 94 + }; 95 + 96 + struct nes_fmr { 97 + struct nes_mr nesmr; 98 + u32 leaf_pbl_cnt; 99 + struct nes_root_vpbl root_vpbl; 100 + struct ib_qp *ib_qp; 101 + int access_rights; 102 + struct ib_fmr_attr attr; 103 + }; 104 + 105 + struct nes_av; 106 + 107 + struct nes_cq { 108 + struct ib_cq ibcq; 109 + struct nes_hw_cq hw_cq; 110 + u32 polled_completions; 111 + u32 cq_mem_size; 112 + spinlock_t lock; 113 + u8 virtual_cq; 114 + u8 pad[3]; 115 + }; 116 + 117 + struct nes_wq { 118 + spinlock_t lock; 119 + }; 120 + 121 + struct iw_cm_id; 122 + struct ietf_mpa_frame; 123 + 124 + struct nes_qp { 125 + struct ib_qp ibqp; 126 + void *allocated_buffer; 127 + struct iw_cm_id *cm_id; 128 + struct workqueue_struct *wq; 129 + struct work_struct disconn_work; 130 + struct nes_cq *nesscq; 131 + struct nes_cq *nesrcq; 132 + struct nes_pd *nespd; 133 + void *cm_node; /* handle of the node this QP is associated with */ 134 + struct ietf_mpa_frame *ietf_frame; 135 + dma_addr_t ietf_frame_pbase; 136 + wait_queue_head_t state_waitq; 137 + unsigned long socket; 138 + struct nes_hw_qp hwqp; 139 + struct work_struct work; 140 + struct work_struct ae_work; 141 + enum ib_qp_state ibqp_state; 142 + u32 iwarp_state; 143 + u32 hte_index; 144 + u32 last_aeq; 145 + u32 qp_mem_size; 146 + atomic_t refcount; 147 + atomic_t close_timer_started; 148 + u32 mmap_sq_db_index; 149 + u32 mmap_rq_db_index; 150 + spinlock_t lock; 151 + struct nes_qp_context *nesqp_context; 152 + dma_addr_t nesqp_context_pbase; 153 + void *pbl_vbase; 154 + dma_addr_t pbl_pbase; 155 + struct page *page; 156 + wait_queue_head_t kick_waitq; 157 + u16 in_disconnect; 158 + u16 private_data_len; 159 + u8 active_conn; 160 + u8 skip_lsmm; 161 + u8 user_mode; 162 + u8 hte_added; 163 + u8 hw_iwarp_state; 164 + u8 flush_issued; 165 + u8 hw_tcp_state; 166 + u8 disconn_pending; 167 + u8 destroyed; 168 + }; 169 + #endif /* NES_VERBS_H */