diff options
Diffstat (limited to 'kernel/drivers/infiniband/hw/amso1100')
23 files changed, 0 insertions, 9079 deletions
diff --git a/kernel/drivers/infiniband/hw/amso1100/Kbuild b/kernel/drivers/infiniband/hw/amso1100/Kbuild deleted file mode 100644 index 950dfabcd..000000000 --- a/kernel/drivers/infiniband/hw/amso1100/Kbuild +++ /dev/null @@ -1,6 +0,0 @@ -ccflags-$(CONFIG_INFINIBAND_AMSO1100_DEBUG) := -DDEBUG - -obj-$(CONFIG_INFINIBAND_AMSO1100) += iw_c2.o - -iw_c2-y := c2.o c2_provider.o c2_rnic.o c2_alloc.o c2_mq.o c2_ae.o c2_vq.o \ - c2_intr.o c2_cq.o c2_qp.o c2_cm.o c2_mm.o c2_pd.o diff --git a/kernel/drivers/infiniband/hw/amso1100/Kconfig b/kernel/drivers/infiniband/hw/amso1100/Kconfig deleted file mode 100644 index e6ce5f209..000000000 --- a/kernel/drivers/infiniband/hw/amso1100/Kconfig +++ /dev/null @@ -1,15 +0,0 @@ -config INFINIBAND_AMSO1100 - tristate "Ammasso 1100 HCA support" - depends on PCI && INET - ---help--- - This is a low-level driver for the Ammasso 1100 host - channel adapter (HCA). - -config INFINIBAND_AMSO1100_DEBUG - bool "Verbose debugging output" - depends on INFINIBAND_AMSO1100 - default n - ---help--- - This option causes the amso1100 driver to produce a bunch of - debug messages. Select this if you are developing the driver - or trying to diagnose a problem. diff --git a/kernel/drivers/infiniband/hw/amso1100/c2.c b/kernel/drivers/infiniband/hw/amso1100/c2.c deleted file mode 100644 index 766a71cce..000000000 --- a/kernel/drivers/infiniband/hw/amso1100/c2.c +++ /dev/null @@ -1,1241 +0,0 @@ -/* - * Copyright (c) 2005 Ammasso, Inc. All rights reserved. - * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/pci.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/inetdevice.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <linux/ethtool.h> -#include <linux/mii.h> -#include <linux/if_vlan.h> -#include <linux/crc32.h> -#include <linux/in.h> -#include <linux/ip.h> -#include <linux/tcp.h> -#include <linux/init.h> -#include <linux/dma-mapping.h> -#include <linux/slab.h> -#include <linux/prefetch.h> - -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/byteorder.h> - -#include <rdma/ib_smi.h> -#include "c2.h" -#include "c2_provider.h" - -MODULE_AUTHOR("Tom Tucker <tom@opengridcomputing.com>"); -MODULE_DESCRIPTION("Ammasso AMSO1100 Low-level iWARP Driver"); -MODULE_LICENSE("Dual BSD/GPL"); -MODULE_VERSION(DRV_VERSION); - -static const u32 default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK - | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN; - -static int debug = -1; /* defaults above */ -module_param(debug, int, 0); -MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); - -static int c2_up(struct net_device *netdev); -static int c2_down(struct net_device *netdev); -static int c2_xmit_frame(struct sk_buff *skb, struct net_device *netdev); -static void c2_tx_interrupt(struct net_device *netdev); -static void c2_rx_interrupt(struct net_device *netdev); -static irqreturn_t c2_interrupt(int irq, void *dev_id); -static void c2_tx_timeout(struct net_device *netdev); -static int c2_change_mtu(struct net_device *netdev, int new_mtu); -static void c2_reset(struct c2_port *c2_port); - -static struct pci_device_id c2_pci_table[] = { - { PCI_DEVICE(0x18b8, 0xb001) }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, c2_pci_table); - -static void c2_print_macaddr(struct net_device *netdev) -{ - pr_debug("%s: MAC %pM, IRQ %u\n", netdev->name, netdev->dev_addr, netdev->irq); -} - -static void c2_set_rxbufsize(struct c2_port *c2_port) -{ - struct net_device *netdev = c2_port->netdev; - - if (netdev->mtu > RX_BUF_SIZE) - c2_port->rx_buf_size = - netdev->mtu + ETH_HLEN + sizeof(struct c2_rxp_hdr) + - NET_IP_ALIGN; - else - c2_port->rx_buf_size = sizeof(struct c2_rxp_hdr) + RX_BUF_SIZE; -} - -/* - * Allocate TX ring elements and chain them together. - * One-to-one association of adapter descriptors with ring elements. - */ -static int c2_tx_ring_alloc(struct c2_ring *tx_ring, void *vaddr, - dma_addr_t base, void __iomem * mmio_txp_ring) -{ - struct c2_tx_desc *tx_desc; - struct c2_txp_desc __iomem *txp_desc; - struct c2_element *elem; - int i; - - tx_ring->start = kmalloc(sizeof(*elem) * tx_ring->count, GFP_KERNEL); - if (!tx_ring->start) - return -ENOMEM; - - elem = tx_ring->start; - tx_desc = vaddr; - txp_desc = mmio_txp_ring; - for (i = 0; i < tx_ring->count; i++, elem++, tx_desc++, txp_desc++) { - tx_desc->len = 0; - tx_desc->status = 0; - - /* Set TXP_HTXD_UNINIT */ - __raw_writeq((__force u64) cpu_to_be64(0x1122334455667788ULL), - (void __iomem *) txp_desc + C2_TXP_ADDR); - __raw_writew(0, (void __iomem *) txp_desc + C2_TXP_LEN); - __raw_writew((__force u16) cpu_to_be16(TXP_HTXD_UNINIT), - (void __iomem *) txp_desc + C2_TXP_FLAGS); - - elem->skb = NULL; - elem->ht_desc = tx_desc; - elem->hw_desc = txp_desc; - - if (i == tx_ring->count - 1) { - elem->next = tx_ring->start; - tx_desc->next_offset = base; - } else { - elem->next = elem + 1; - tx_desc->next_offset = - base + (i + 1) * sizeof(*tx_desc); - } - } - - tx_ring->to_use = tx_ring->to_clean = tx_ring->start; - - return 0; -} - -/* - * Allocate RX ring elements and chain them together. - * One-to-one association of adapter descriptors with ring elements. - */ -static int c2_rx_ring_alloc(struct c2_ring *rx_ring, void *vaddr, - dma_addr_t base, void __iomem * mmio_rxp_ring) -{ - struct c2_rx_desc *rx_desc; - struct c2_rxp_desc __iomem *rxp_desc; - struct c2_element *elem; - int i; - - rx_ring->start = kmalloc(sizeof(*elem) * rx_ring->count, GFP_KERNEL); - if (!rx_ring->start) - return -ENOMEM; - - elem = rx_ring->start; - rx_desc = vaddr; - rxp_desc = mmio_rxp_ring; - for (i = 0; i < rx_ring->count; i++, elem++, rx_desc++, rxp_desc++) { - rx_desc->len = 0; - rx_desc->status = 0; - - /* Set RXP_HRXD_UNINIT */ - __raw_writew((__force u16) cpu_to_be16(RXP_HRXD_OK), - (void __iomem *) rxp_desc + C2_RXP_STATUS); - __raw_writew(0, (void __iomem *) rxp_desc + C2_RXP_COUNT); - __raw_writew(0, (void __iomem *) rxp_desc + C2_RXP_LEN); - __raw_writeq((__force u64) cpu_to_be64(0x99aabbccddeeffULL), - (void __iomem *) rxp_desc + C2_RXP_ADDR); - __raw_writew((__force u16) cpu_to_be16(RXP_HRXD_UNINIT), - (void __iomem *) rxp_desc + C2_RXP_FLAGS); - - elem->skb = NULL; - elem->ht_desc = rx_desc; - elem->hw_desc = rxp_desc; - - if (i == rx_ring->count - 1) { - elem->next = rx_ring->start; - rx_desc->next_offset = base; - } else { - elem->next = elem + 1; - rx_desc->next_offset = - base + (i + 1) * sizeof(*rx_desc); - } - } - - rx_ring->to_use = rx_ring->to_clean = rx_ring->start; - - return 0; -} - -/* Setup buffer for receiving */ -static inline int c2_rx_alloc(struct c2_port *c2_port, struct c2_element *elem) -{ - struct c2_dev *c2dev = c2_port->c2dev; - struct c2_rx_desc *rx_desc = elem->ht_desc; - struct sk_buff *skb; - dma_addr_t mapaddr; - u32 maplen; - struct c2_rxp_hdr *rxp_hdr; - - skb = dev_alloc_skb(c2_port->rx_buf_size); - if (unlikely(!skb)) { - pr_debug("%s: out of memory for receive\n", - c2_port->netdev->name); - return -ENOMEM; - } - - /* Zero out the rxp hdr in the sk_buff */ - memset(skb->data, 0, sizeof(*rxp_hdr)); - - skb->dev = c2_port->netdev; - - maplen = c2_port->rx_buf_size; - mapaddr = - pci_map_single(c2dev->pcidev, skb->data, maplen, - PCI_DMA_FROMDEVICE); - - /* Set the sk_buff RXP_header to RXP_HRXD_READY */ - rxp_hdr = (struct c2_rxp_hdr *) skb->data; - rxp_hdr->flags = RXP_HRXD_READY; - - __raw_writew(0, elem->hw_desc + C2_RXP_STATUS); - __raw_writew((__force u16) cpu_to_be16((u16) maplen - sizeof(*rxp_hdr)), - elem->hw_desc + C2_RXP_LEN); - __raw_writeq((__force u64) cpu_to_be64(mapaddr), elem->hw_desc + C2_RXP_ADDR); - __raw_writew((__force u16) cpu_to_be16(RXP_HRXD_READY), - elem->hw_desc + C2_RXP_FLAGS); - - elem->skb = skb; - elem->mapaddr = mapaddr; - elem->maplen = maplen; - rx_desc->len = maplen; - - return 0; -} - -/* - * Allocate buffers for the Rx ring - * For receive: rx_ring.to_clean is next received frame - */ -static int c2_rx_fill(struct c2_port *c2_port) -{ - struct c2_ring *rx_ring = &c2_port->rx_ring; - struct c2_element *elem; - int ret = 0; - - elem = rx_ring->start; - do { - if (c2_rx_alloc(c2_port, elem)) { - ret = 1; - break; - } - } while ((elem = elem->next) != rx_ring->start); - - rx_ring->to_clean = rx_ring->start; - return ret; -} - -/* Free all buffers in RX ring, assumes receiver stopped */ -static void c2_rx_clean(struct c2_port *c2_port) -{ - struct c2_dev *c2dev = c2_port->c2dev; - struct c2_ring *rx_ring = &c2_port->rx_ring; - struct c2_element *elem; - struct c2_rx_desc *rx_desc; - - elem = rx_ring->start; - do { - rx_desc = elem->ht_desc; - rx_desc->len = 0; - - __raw_writew(0, elem->hw_desc + C2_RXP_STATUS); - __raw_writew(0, elem->hw_desc + C2_RXP_COUNT); - __raw_writew(0, elem->hw_desc + C2_RXP_LEN); - __raw_writeq((__force u64) cpu_to_be64(0x99aabbccddeeffULL), - elem->hw_desc + C2_RXP_ADDR); - __raw_writew((__force u16) cpu_to_be16(RXP_HRXD_UNINIT), - elem->hw_desc + C2_RXP_FLAGS); - - if (elem->skb) { - pci_unmap_single(c2dev->pcidev, elem->mapaddr, - elem->maplen, PCI_DMA_FROMDEVICE); - dev_kfree_skb(elem->skb); - elem->skb = NULL; - } - } while ((elem = elem->next) != rx_ring->start); -} - -static inline int c2_tx_free(struct c2_dev *c2dev, struct c2_element *elem) -{ - struct c2_tx_desc *tx_desc = elem->ht_desc; - - tx_desc->len = 0; - - pci_unmap_single(c2dev->pcidev, elem->mapaddr, elem->maplen, - PCI_DMA_TODEVICE); - - if (elem->skb) { - dev_kfree_skb_any(elem->skb); - elem->skb = NULL; - } - - return 0; -} - -/* Free all buffers in TX ring, assumes transmitter stopped */ -static void c2_tx_clean(struct c2_port *c2_port) -{ - struct c2_ring *tx_ring = &c2_port->tx_ring; - struct c2_element *elem; - struct c2_txp_desc txp_htxd; - int retry; - unsigned long flags; - - spin_lock_irqsave(&c2_port->tx_lock, flags); - - elem = tx_ring->start; - - do { - retry = 0; - do { - txp_htxd.flags = - readw(elem->hw_desc + C2_TXP_FLAGS); - - if (txp_htxd.flags == TXP_HTXD_READY) { - retry = 1; - __raw_writew(0, - elem->hw_desc + C2_TXP_LEN); - __raw_writeq(0, - elem->hw_desc + C2_TXP_ADDR); - __raw_writew((__force u16) cpu_to_be16(TXP_HTXD_DONE), - elem->hw_desc + C2_TXP_FLAGS); - c2_port->netdev->stats.tx_dropped++; - break; - } else { - __raw_writew(0, - elem->hw_desc + C2_TXP_LEN); - __raw_writeq((__force u64) cpu_to_be64(0x1122334455667788ULL), - elem->hw_desc + C2_TXP_ADDR); - __raw_writew((__force u16) cpu_to_be16(TXP_HTXD_UNINIT), - elem->hw_desc + C2_TXP_FLAGS); - } - - c2_tx_free(c2_port->c2dev, elem); - - } while ((elem = elem->next) != tx_ring->start); - } while (retry); - - c2_port->tx_avail = c2_port->tx_ring.count - 1; - c2_port->c2dev->cur_tx = tx_ring->to_use - tx_ring->start; - - if (c2_port->tx_avail > MAX_SKB_FRAGS + 1) - netif_wake_queue(c2_port->netdev); - - spin_unlock_irqrestore(&c2_port->tx_lock, flags); -} - -/* - * Process transmit descriptors marked 'DONE' by the firmware, - * freeing up their unneeded sk_buffs. - */ -static void c2_tx_interrupt(struct net_device *netdev) -{ - struct c2_port *c2_port = netdev_priv(netdev); - struct c2_dev *c2dev = c2_port->c2dev; - struct c2_ring *tx_ring = &c2_port->tx_ring; - struct c2_element *elem; - struct c2_txp_desc txp_htxd; - - spin_lock(&c2_port->tx_lock); - - for (elem = tx_ring->to_clean; elem != tx_ring->to_use; - elem = elem->next) { - txp_htxd.flags = - be16_to_cpu((__force __be16) readw(elem->hw_desc + C2_TXP_FLAGS)); - - if (txp_htxd.flags != TXP_HTXD_DONE) - break; - - if (netif_msg_tx_done(c2_port)) { - /* PCI reads are expensive in fast path */ - txp_htxd.len = - be16_to_cpu((__force __be16) readw(elem->hw_desc + C2_TXP_LEN)); - pr_debug("%s: tx done slot %3Zu status 0x%x len " - "%5u bytes\n", - netdev->name, elem - tx_ring->start, - txp_htxd.flags, txp_htxd.len); - } - - c2_tx_free(c2dev, elem); - ++(c2_port->tx_avail); - } - - tx_ring->to_clean = elem; - - if (netif_queue_stopped(netdev) - && c2_port->tx_avail > MAX_SKB_FRAGS + 1) - netif_wake_queue(netdev); - - spin_unlock(&c2_port->tx_lock); -} - -static void c2_rx_error(struct c2_port *c2_port, struct c2_element *elem) -{ - struct c2_rx_desc *rx_desc = elem->ht_desc; - struct c2_rxp_hdr *rxp_hdr = (struct c2_rxp_hdr *) elem->skb->data; - - if (rxp_hdr->status != RXP_HRXD_OK || - rxp_hdr->len > (rx_desc->len - sizeof(*rxp_hdr))) { - pr_debug("BAD RXP_HRXD\n"); - pr_debug(" rx_desc : %p\n", rx_desc); - pr_debug(" index : %Zu\n", - elem - c2_port->rx_ring.start); - pr_debug(" len : %u\n", rx_desc->len); - pr_debug(" rxp_hdr : %p [PA %p]\n", rxp_hdr, - (void *) __pa((unsigned long) rxp_hdr)); - pr_debug(" flags : 0x%x\n", rxp_hdr->flags); - pr_debug(" status: 0x%x\n", rxp_hdr->status); - pr_debug(" len : %u\n", rxp_hdr->len); - pr_debug(" rsvd : 0x%x\n", rxp_hdr->rsvd); - } - - /* Setup the skb for reuse since we're dropping this pkt */ - elem->skb->data = elem->skb->head; - skb_reset_tail_pointer(elem->skb); - - /* Zero out the rxp hdr in the sk_buff */ - memset(elem->skb->data, 0, sizeof(*rxp_hdr)); - - /* Write the descriptor to the adapter's rx ring */ - __raw_writew(0, elem->hw_desc + C2_RXP_STATUS); - __raw_writew(0, elem->hw_desc + C2_RXP_COUNT); - __raw_writew((__force u16) cpu_to_be16((u16) elem->maplen - sizeof(*rxp_hdr)), - elem->hw_desc + C2_RXP_LEN); - __raw_writeq((__force u64) cpu_to_be64(elem->mapaddr), - elem->hw_desc + C2_RXP_ADDR); - __raw_writew((__force u16) cpu_to_be16(RXP_HRXD_READY), - elem->hw_desc + C2_RXP_FLAGS); - - pr_debug("packet dropped\n"); - c2_port->netdev->stats.rx_dropped++; -} - -static void c2_rx_interrupt(struct net_device *netdev) -{ - struct c2_port *c2_port = netdev_priv(netdev); - struct c2_dev *c2dev = c2_port->c2dev; - struct c2_ring *rx_ring = &c2_port->rx_ring; - struct c2_element *elem; - struct c2_rx_desc *rx_desc; - struct c2_rxp_hdr *rxp_hdr; - struct sk_buff *skb; - dma_addr_t mapaddr; - u32 maplen, buflen; - unsigned long flags; - - spin_lock_irqsave(&c2dev->lock, flags); - - /* Begin where we left off */ - rx_ring->to_clean = rx_ring->start + c2dev->cur_rx; - - for (elem = rx_ring->to_clean; elem->next != rx_ring->to_clean; - elem = elem->next) { - rx_desc = elem->ht_desc; - mapaddr = elem->mapaddr; - maplen = elem->maplen; - skb = elem->skb; - rxp_hdr = (struct c2_rxp_hdr *) skb->data; - - if (rxp_hdr->flags != RXP_HRXD_DONE) - break; - buflen = rxp_hdr->len; - - /* Sanity check the RXP header */ - if (rxp_hdr->status != RXP_HRXD_OK || - buflen > (rx_desc->len - sizeof(*rxp_hdr))) { - c2_rx_error(c2_port, elem); - continue; - } - - /* - * Allocate and map a new skb for replenishing the host - * RX desc - */ - if (c2_rx_alloc(c2_port, elem)) { - c2_rx_error(c2_port, elem); - continue; - } - - /* Unmap the old skb */ - pci_unmap_single(c2dev->pcidev, mapaddr, maplen, - PCI_DMA_FROMDEVICE); - - prefetch(skb->data); - - /* - * Skip past the leading 8 bytes comprising of the - * "struct c2_rxp_hdr", prepended by the adapter - * to the usual Ethernet header ("struct ethhdr"), - * to the start of the raw Ethernet packet. - * - * Fix up the various fields in the sk_buff before - * passing it up to netif_rx(). The transfer size - * (in bytes) specified by the adapter len field of - * the "struct rxp_hdr_t" does NOT include the - * "sizeof(struct c2_rxp_hdr)". - */ - skb->data += sizeof(*rxp_hdr); - skb_set_tail_pointer(skb, buflen); - skb->len = buflen; - skb->protocol = eth_type_trans(skb, netdev); - - netif_rx(skb); - - netdev->stats.rx_packets++; - netdev->stats.rx_bytes += buflen; - } - - /* Save where we left off */ - rx_ring->to_clean = elem; - c2dev->cur_rx = elem - rx_ring->start; - C2_SET_CUR_RX(c2dev, c2dev->cur_rx); - - spin_unlock_irqrestore(&c2dev->lock, flags); -} - -/* - * Handle netisr0 TX & RX interrupts. - */ -static irqreturn_t c2_interrupt(int irq, void *dev_id) -{ - unsigned int netisr0, dmaisr; - int handled = 0; - struct c2_dev *c2dev = (struct c2_dev *) dev_id; - - /* Process CCILNET interrupts */ - netisr0 = readl(c2dev->regs + C2_NISR0); - if (netisr0) { - - /* - * There is an issue with the firmware that always - * provides the status of RX for both TX & RX - * interrupts. So process both queues here. - */ - c2_rx_interrupt(c2dev->netdev); - c2_tx_interrupt(c2dev->netdev); - - /* Clear the interrupt */ - writel(netisr0, c2dev->regs + C2_NISR0); - handled++; - } - - /* Process RNIC interrupts */ - dmaisr = readl(c2dev->regs + C2_DISR); - if (dmaisr) { - writel(dmaisr, c2dev->regs + C2_DISR); - c2_rnic_interrupt(c2dev); - handled++; - } - - if (handled) { - return IRQ_HANDLED; - } else { - return IRQ_NONE; - } -} - -static int c2_up(struct net_device *netdev) -{ - struct c2_port *c2_port = netdev_priv(netdev); - struct c2_dev *c2dev = c2_port->c2dev; - struct c2_element *elem; - struct c2_rxp_hdr *rxp_hdr; - struct in_device *in_dev; - size_t rx_size, tx_size; - int ret, i; - unsigned int netimr0; - - if (netif_msg_ifup(c2_port)) - pr_debug("%s: enabling interface\n", netdev->name); - - /* Set the Rx buffer size based on MTU */ - c2_set_rxbufsize(c2_port); - - /* Allocate DMA'able memory for Tx/Rx host descriptor rings */ - rx_size = c2_port->rx_ring.count * sizeof(struct c2_rx_desc); - tx_size = c2_port->tx_ring.count * sizeof(struct c2_tx_desc); - - c2_port->mem_size = tx_size + rx_size; - c2_port->mem = pci_zalloc_consistent(c2dev->pcidev, c2_port->mem_size, - &c2_port->dma); - if (c2_port->mem == NULL) { - pr_debug("Unable to allocate memory for " - "host descriptor rings\n"); - return -ENOMEM; - } - - /* Create the Rx host descriptor ring */ - if ((ret = - c2_rx_ring_alloc(&c2_port->rx_ring, c2_port->mem, c2_port->dma, - c2dev->mmio_rxp_ring))) { - pr_debug("Unable to create RX ring\n"); - goto bail0; - } - - /* Allocate Rx buffers for the host descriptor ring */ - if (c2_rx_fill(c2_port)) { - pr_debug("Unable to fill RX ring\n"); - goto bail1; - } - - /* Create the Tx host descriptor ring */ - if ((ret = c2_tx_ring_alloc(&c2_port->tx_ring, c2_port->mem + rx_size, - c2_port->dma + rx_size, - c2dev->mmio_txp_ring))) { - pr_debug("Unable to create TX ring\n"); - goto bail1; - } - - /* Set the TX pointer to where we left off */ - c2_port->tx_avail = c2_port->tx_ring.count - 1; - c2_port->tx_ring.to_use = c2_port->tx_ring.to_clean = - c2_port->tx_ring.start + c2dev->cur_tx; - - /* missing: Initialize MAC */ - - BUG_ON(c2_port->tx_ring.to_use != c2_port->tx_ring.to_clean); - - /* Reset the adapter, ensures the driver is in sync with the RXP */ - c2_reset(c2_port); - - /* Reset the READY bit in the sk_buff RXP headers & adapter HRXDQ */ - for (i = 0, elem = c2_port->rx_ring.start; i < c2_port->rx_ring.count; - i++, elem++) { - rxp_hdr = (struct c2_rxp_hdr *) elem->skb->data; - rxp_hdr->flags = 0; - __raw_writew((__force u16) cpu_to_be16(RXP_HRXD_READY), - elem->hw_desc + C2_RXP_FLAGS); - } - - /* Enable network packets */ - netif_start_queue(netdev); - - /* Enable IRQ */ - writel(0, c2dev->regs + C2_IDIS); - netimr0 = readl(c2dev->regs + C2_NIMR0); - netimr0 &= ~(C2_PCI_HTX_INT | C2_PCI_HRX_INT); - writel(netimr0, c2dev->regs + C2_NIMR0); - - /* Tell the stack to ignore arp requests for ipaddrs bound to - * other interfaces. This is needed to prevent the host stack - * from responding to arp requests to the ipaddr bound on the - * rdma interface. - */ - in_dev = in_dev_get(netdev); - IN_DEV_CONF_SET(in_dev, ARP_IGNORE, 1); - in_dev_put(in_dev); - - return 0; - - bail1: - c2_rx_clean(c2_port); - kfree(c2_port->rx_ring.start); - - bail0: - pci_free_consistent(c2dev->pcidev, c2_port->mem_size, c2_port->mem, - c2_port->dma); - - return ret; -} - -static int c2_down(struct net_device *netdev) -{ - struct c2_port *c2_port = netdev_priv(netdev); - struct c2_dev *c2dev = c2_port->c2dev; - - if (netif_msg_ifdown(c2_port)) - pr_debug("%s: disabling interface\n", - netdev->name); - - /* Wait for all the queued packets to get sent */ - c2_tx_interrupt(netdev); - - /* Disable network packets */ - netif_stop_queue(netdev); - - /* Disable IRQs by clearing the interrupt mask */ - writel(1, c2dev->regs + C2_IDIS); - writel(0, c2dev->regs + C2_NIMR0); - - /* missing: Stop transmitter */ - - /* missing: Stop receiver */ - - /* Reset the adapter, ensures the driver is in sync with the RXP */ - c2_reset(c2_port); - - /* missing: Turn off LEDs here */ - - /* Free all buffers in the host descriptor rings */ - c2_tx_clean(c2_port); - c2_rx_clean(c2_port); - - /* Free the host descriptor rings */ - kfree(c2_port->rx_ring.start); - kfree(c2_port->tx_ring.start); - pci_free_consistent(c2dev->pcidev, c2_port->mem_size, c2_port->mem, - c2_port->dma); - - return 0; -} - -static void c2_reset(struct c2_port *c2_port) -{ - struct c2_dev *c2dev = c2_port->c2dev; - unsigned int cur_rx = c2dev->cur_rx; - - /* Tell the hardware to quiesce */ - C2_SET_CUR_RX(c2dev, cur_rx | C2_PCI_HRX_QUI); - - /* - * The hardware will reset the C2_PCI_HRX_QUI bit once - * the RXP is quiesced. Wait 2 seconds for this. - */ - ssleep(2); - - cur_rx = C2_GET_CUR_RX(c2dev); - - if (cur_rx & C2_PCI_HRX_QUI) - pr_debug("c2_reset: failed to quiesce the hardware!\n"); - - cur_rx &= ~C2_PCI_HRX_QUI; - - c2dev->cur_rx = cur_rx; - - pr_debug("Current RX: %u\n", c2dev->cur_rx); -} - -static int c2_xmit_frame(struct sk_buff *skb, struct net_device *netdev) -{ - struct c2_port *c2_port = netdev_priv(netdev); - struct c2_dev *c2dev = c2_port->c2dev; - struct c2_ring *tx_ring = &c2_port->tx_ring; - struct c2_element *elem; - dma_addr_t mapaddr; - u32 maplen; - unsigned long flags; - unsigned int i; - - spin_lock_irqsave(&c2_port->tx_lock, flags); - - if (unlikely(c2_port->tx_avail < (skb_shinfo(skb)->nr_frags + 1))) { - netif_stop_queue(netdev); - spin_unlock_irqrestore(&c2_port->tx_lock, flags); - - pr_debug("%s: Tx ring full when queue awake!\n", - netdev->name); - return NETDEV_TX_BUSY; - } - - maplen = skb_headlen(skb); - mapaddr = - pci_map_single(c2dev->pcidev, skb->data, maplen, PCI_DMA_TODEVICE); - - elem = tx_ring->to_use; - elem->skb = skb; - elem->mapaddr = mapaddr; - elem->maplen = maplen; - - /* Tell HW to xmit */ - __raw_writeq((__force u64) cpu_to_be64(mapaddr), - elem->hw_desc + C2_TXP_ADDR); - __raw_writew((__force u16) cpu_to_be16(maplen), - elem->hw_desc + C2_TXP_LEN); - __raw_writew((__force u16) cpu_to_be16(TXP_HTXD_READY), - elem->hw_desc + C2_TXP_FLAGS); - - netdev->stats.tx_packets++; - netdev->stats.tx_bytes += maplen; - - /* Loop thru additional data fragments and queue them */ - if (skb_shinfo(skb)->nr_frags) { - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { - const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - maplen = skb_frag_size(frag); - mapaddr = skb_frag_dma_map(&c2dev->pcidev->dev, frag, - 0, maplen, DMA_TO_DEVICE); - elem = elem->next; - elem->skb = NULL; - elem->mapaddr = mapaddr; - elem->maplen = maplen; - - /* Tell HW to xmit */ - __raw_writeq((__force u64) cpu_to_be64(mapaddr), - elem->hw_desc + C2_TXP_ADDR); - __raw_writew((__force u16) cpu_to_be16(maplen), - elem->hw_desc + C2_TXP_LEN); - __raw_writew((__force u16) cpu_to_be16(TXP_HTXD_READY), - elem->hw_desc + C2_TXP_FLAGS); - - netdev->stats.tx_packets++; - netdev->stats.tx_bytes += maplen; - } - } - - tx_ring->to_use = elem->next; - c2_port->tx_avail -= (skb_shinfo(skb)->nr_frags + 1); - - if (c2_port->tx_avail <= MAX_SKB_FRAGS + 1) { - netif_stop_queue(netdev); - if (netif_msg_tx_queued(c2_port)) - pr_debug("%s: transmit queue full\n", - netdev->name); - } - - spin_unlock_irqrestore(&c2_port->tx_lock, flags); - - netdev->trans_start = jiffies; - - return NETDEV_TX_OK; -} - -static void c2_tx_timeout(struct net_device *netdev) -{ - struct c2_port *c2_port = netdev_priv(netdev); - - if (netif_msg_timer(c2_port)) - pr_debug("%s: tx timeout\n", netdev->name); - - c2_tx_clean(c2_port); -} - -static int c2_change_mtu(struct net_device *netdev, int new_mtu) -{ - int ret = 0; - - if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) - return -EINVAL; - - netdev->mtu = new_mtu; - - if (netif_running(netdev)) { - c2_down(netdev); - - c2_up(netdev); - } - - return ret; -} - -static const struct net_device_ops c2_netdev = { - .ndo_open = c2_up, - .ndo_stop = c2_down, - .ndo_start_xmit = c2_xmit_frame, - .ndo_tx_timeout = c2_tx_timeout, - .ndo_change_mtu = c2_change_mtu, - .ndo_set_mac_address = eth_mac_addr, - .ndo_validate_addr = eth_validate_addr, -}; - -/* Initialize network device */ -static struct net_device *c2_devinit(struct c2_dev *c2dev, - void __iomem * mmio_addr) -{ - struct c2_port *c2_port = NULL; - struct net_device *netdev = alloc_etherdev(sizeof(*c2_port)); - - if (!netdev) { - pr_debug("c2_port etherdev alloc failed"); - return NULL; - } - - SET_NETDEV_DEV(netdev, &c2dev->pcidev->dev); - - netdev->netdev_ops = &c2_netdev; - netdev->watchdog_timeo = C2_TX_TIMEOUT; - netdev->irq = c2dev->pcidev->irq; - - c2_port = netdev_priv(netdev); - c2_port->netdev = netdev; - c2_port->c2dev = c2dev; - c2_port->msg_enable = netif_msg_init(debug, default_msg); - c2_port->tx_ring.count = C2_NUM_TX_DESC; - c2_port->rx_ring.count = C2_NUM_RX_DESC; - - spin_lock_init(&c2_port->tx_lock); - - /* Copy our 48-bit ethernet hardware address */ - memcpy_fromio(netdev->dev_addr, mmio_addr + C2_REGS_ENADDR, 6); - - /* Validate the MAC address */ - if (!is_valid_ether_addr(netdev->dev_addr)) { - pr_debug("Invalid MAC Address\n"); - c2_print_macaddr(netdev); - free_netdev(netdev); - return NULL; - } - - c2dev->netdev = netdev; - - return netdev; -} - -static int c2_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) -{ - int ret = 0, i; - unsigned long reg0_start, reg0_flags, reg0_len; - unsigned long reg2_start, reg2_flags, reg2_len; - unsigned long reg4_start, reg4_flags, reg4_len; - unsigned kva_map_size; - struct net_device *netdev = NULL; - struct c2_dev *c2dev = NULL; - void __iomem *mmio_regs = NULL; - - printk(KERN_INFO PFX "AMSO1100 Gigabit Ethernet driver v%s loaded\n", - DRV_VERSION); - - /* Enable PCI device */ - ret = pci_enable_device(pcidev); - if (ret) { - printk(KERN_ERR PFX "%s: Unable to enable PCI device\n", - pci_name(pcidev)); - goto bail0; - } - - reg0_start = pci_resource_start(pcidev, BAR_0); - reg0_len = pci_resource_len(pcidev, BAR_0); - reg0_flags = pci_resource_flags(pcidev, BAR_0); - - reg2_start = pci_resource_start(pcidev, BAR_2); - reg2_len = pci_resource_len(pcidev, BAR_2); - reg2_flags = pci_resource_flags(pcidev, BAR_2); - - reg4_start = pci_resource_start(pcidev, BAR_4); - reg4_len = pci_resource_len(pcidev, BAR_4); - reg4_flags = pci_resource_flags(pcidev, BAR_4); - - pr_debug("BAR0 size = 0x%lX bytes\n", reg0_len); - pr_debug("BAR2 size = 0x%lX bytes\n", reg2_len); - pr_debug("BAR4 size = 0x%lX bytes\n", reg4_len); - - /* Make sure PCI base addr are MMIO */ - if (!(reg0_flags & IORESOURCE_MEM) || - !(reg2_flags & IORESOURCE_MEM) || !(reg4_flags & IORESOURCE_MEM)) { - printk(KERN_ERR PFX "PCI regions not an MMIO resource\n"); - ret = -ENODEV; - goto bail1; - } - - /* Check for weird/broken PCI region reporting */ - if ((reg0_len < C2_REG0_SIZE) || - (reg2_len < C2_REG2_SIZE) || (reg4_len < C2_REG4_SIZE)) { - printk(KERN_ERR PFX "Invalid PCI region sizes\n"); - ret = -ENODEV; - goto bail1; - } - - /* Reserve PCI I/O and memory resources */ - ret = pci_request_regions(pcidev, DRV_NAME); - if (ret) { - printk(KERN_ERR PFX "%s: Unable to request regions\n", - pci_name(pcidev)); - goto bail1; - } - - if ((sizeof(dma_addr_t) > 4)) { - ret = pci_set_dma_mask(pcidev, DMA_BIT_MASK(64)); - if (ret < 0) { - printk(KERN_ERR PFX "64b DMA configuration failed\n"); - goto bail2; - } - } else { - ret = pci_set_dma_mask(pcidev, DMA_BIT_MASK(32)); - if (ret < 0) { - printk(KERN_ERR PFX "32b DMA configuration failed\n"); - goto bail2; - } - } - - /* Enables bus-mastering on the device */ - pci_set_master(pcidev); - - /* Remap the adapter PCI registers in BAR4 */ - mmio_regs = ioremap_nocache(reg4_start + C2_PCI_REGS_OFFSET, - sizeof(struct c2_adapter_pci_regs)); - if (!mmio_regs) { - printk(KERN_ERR PFX - "Unable to remap adapter PCI registers in BAR4\n"); - ret = -EIO; - goto bail2; - } - - /* Validate PCI regs magic */ - for (i = 0; i < sizeof(c2_magic); i++) { - if (c2_magic[i] != readb(mmio_regs + C2_REGS_MAGIC + i)) { - printk(KERN_ERR PFX "Downlevel Firmware boot loader " - "[%d/%Zd: got 0x%x, exp 0x%x]. Use the cc_flash " - "utility to update your boot loader\n", - i + 1, sizeof(c2_magic), - readb(mmio_regs + C2_REGS_MAGIC + i), - c2_magic[i]); - printk(KERN_ERR PFX "Adapter not claimed\n"); - iounmap(mmio_regs); - ret = -EIO; - goto bail2; - } - } - - /* Validate the adapter version */ - if (be32_to_cpu((__force __be32) readl(mmio_regs + C2_REGS_VERS)) != C2_VERSION) { - printk(KERN_ERR PFX "Version mismatch " - "[fw=%u, c2=%u], Adapter not claimed\n", - be32_to_cpu((__force __be32) readl(mmio_regs + C2_REGS_VERS)), - C2_VERSION); - ret = -EINVAL; - iounmap(mmio_regs); - goto bail2; - } - - /* Validate the adapter IVN */ - if (be32_to_cpu((__force __be32) readl(mmio_regs + C2_REGS_IVN)) != C2_IVN) { - printk(KERN_ERR PFX "Downlevel FIrmware level. You should be using " - "the OpenIB device support kit. " - "[fw=0x%x, c2=0x%x], Adapter not claimed\n", - be32_to_cpu((__force __be32) readl(mmio_regs + C2_REGS_IVN)), - C2_IVN); - ret = -EINVAL; - iounmap(mmio_regs); - goto bail2; - } - - /* Allocate hardware structure */ - c2dev = (struct c2_dev *) ib_alloc_device(sizeof(*c2dev)); - if (!c2dev) { - printk(KERN_ERR PFX "%s: Unable to alloc hardware struct\n", - pci_name(pcidev)); - ret = -ENOMEM; - iounmap(mmio_regs); - goto bail2; - } - - memset(c2dev, 0, sizeof(*c2dev)); - spin_lock_init(&c2dev->lock); - c2dev->pcidev = pcidev; - c2dev->cur_tx = 0; - - /* Get the last RX index */ - c2dev->cur_rx = - (be32_to_cpu((__force __be32) readl(mmio_regs + C2_REGS_HRX_CUR)) - - 0xffffc000) / sizeof(struct c2_rxp_desc); - - /* Request an interrupt line for the driver */ - ret = request_irq(pcidev->irq, c2_interrupt, IRQF_SHARED, DRV_NAME, c2dev); - if (ret) { - printk(KERN_ERR PFX "%s: requested IRQ %u is busy\n", - pci_name(pcidev), pcidev->irq); - iounmap(mmio_regs); - goto bail3; - } - - /* Set driver specific data */ - pci_set_drvdata(pcidev, c2dev); - - /* Initialize network device */ - if ((netdev = c2_devinit(c2dev, mmio_regs)) == NULL) { - ret = -ENOMEM; - iounmap(mmio_regs); - goto bail4; - } - - /* Save off the actual size prior to unmapping mmio_regs */ - kva_map_size = be32_to_cpu((__force __be32) readl(mmio_regs + C2_REGS_PCI_WINSIZE)); - - /* Unmap the adapter PCI registers in BAR4 */ - iounmap(mmio_regs); - - /* Register network device */ - ret = register_netdev(netdev); - if (ret) { - printk(KERN_ERR PFX "Unable to register netdev, ret = %d\n", - ret); - goto bail5; - } - - /* Disable network packets */ - netif_stop_queue(netdev); - - /* Remap the adapter HRXDQ PA space to kernel VA space */ - c2dev->mmio_rxp_ring = ioremap_nocache(reg4_start + C2_RXP_HRXDQ_OFFSET, - C2_RXP_HRXDQ_SIZE); - if (!c2dev->mmio_rxp_ring) { - printk(KERN_ERR PFX "Unable to remap MMIO HRXDQ region\n"); - ret = -EIO; - goto bail6; - } - - /* Remap the adapter HTXDQ PA space to kernel VA space */ - c2dev->mmio_txp_ring = ioremap_nocache(reg4_start + C2_TXP_HTXDQ_OFFSET, - C2_TXP_HTXDQ_SIZE); - if (!c2dev->mmio_txp_ring) { - printk(KERN_ERR PFX "Unable to remap MMIO HTXDQ region\n"); - ret = -EIO; - goto bail7; - } - - /* Save off the current RX index in the last 4 bytes of the TXP Ring */ - C2_SET_CUR_RX(c2dev, c2dev->cur_rx); - - /* Remap the PCI registers in adapter BAR0 to kernel VA space */ - c2dev->regs = ioremap_nocache(reg0_start, reg0_len); - if (!c2dev->regs) { - printk(KERN_ERR PFX "Unable to remap BAR0\n"); - ret = -EIO; - goto bail8; - } - - /* Remap the PCI registers in adapter BAR4 to kernel VA space */ - c2dev->pa = reg4_start + C2_PCI_REGS_OFFSET; - c2dev->kva = ioremap_nocache(reg4_start + C2_PCI_REGS_OFFSET, - kva_map_size); - if (!c2dev->kva) { - printk(KERN_ERR PFX "Unable to remap BAR4\n"); - ret = -EIO; - goto bail9; - } - - /* Print out the MAC address */ - c2_print_macaddr(netdev); - - ret = c2_rnic_init(c2dev); - if (ret) { - printk(KERN_ERR PFX "c2_rnic_init failed: %d\n", ret); - goto bail10; - } - - ret = c2_register_device(c2dev); - if (ret) - goto bail10; - - return 0; - - bail10: - iounmap(c2dev->kva); - - bail9: - iounmap(c2dev->regs); - - bail8: - iounmap(c2dev->mmio_txp_ring); - - bail7: - iounmap(c2dev->mmio_rxp_ring); - - bail6: - unregister_netdev(netdev); - - bail5: - free_netdev(netdev); - - bail4: - free_irq(pcidev->irq, c2dev); - - bail3: - ib_dealloc_device(&c2dev->ibdev); - - bail2: - pci_release_regions(pcidev); - - bail1: - pci_disable_device(pcidev); - - bail0: - return ret; -} - -static void c2_remove(struct pci_dev *pcidev) -{ - struct c2_dev *c2dev = pci_get_drvdata(pcidev); - struct net_device *netdev = c2dev->netdev; - - /* Unregister with OpenIB */ - c2_unregister_device(c2dev); - - /* Clean up the RNIC resources */ - c2_rnic_term(c2dev); - - /* Remove network device from the kernel */ - unregister_netdev(netdev); - - /* Free network device */ - free_netdev(netdev); - - /* Free the interrupt line */ - free_irq(pcidev->irq, c2dev); - - /* missing: Turn LEDs off here */ - - /* Unmap adapter PA space */ - iounmap(c2dev->kva); - iounmap(c2dev->regs); - iounmap(c2dev->mmio_txp_ring); - iounmap(c2dev->mmio_rxp_ring); - - /* Free the hardware structure */ - ib_dealloc_device(&c2dev->ibdev); - - /* Release reserved PCI I/O and memory resources */ - pci_release_regions(pcidev); - - /* Disable PCI device */ - pci_disable_device(pcidev); - - /* Clear driver specific data */ - pci_set_drvdata(pcidev, NULL); -} - -static struct pci_driver c2_pci_driver = { - .name = DRV_NAME, - .id_table = c2_pci_table, - .probe = c2_probe, - .remove = c2_remove, -}; - -module_pci_driver(c2_pci_driver); diff --git a/kernel/drivers/infiniband/hw/amso1100/c2.h b/kernel/drivers/infiniband/hw/amso1100/c2.h deleted file mode 100644 index d619d7358..000000000 --- a/kernel/drivers/infiniband/hw/amso1100/c2.h +++ /dev/null @@ -1,547 +0,0 @@ -/* - * Copyright (c) 2005 Ammasso, Inc. All rights reserved. - * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef __C2_H -#define __C2_H - -#include <linux/netdevice.h> -#include <linux/spinlock.h> -#include <linux/kernel.h> -#include <linux/pci.h> -#include <linux/dma-mapping.h> -#include <linux/idr.h> - -#include "c2_provider.h" -#include "c2_mq.h" -#include "c2_status.h" - -#define DRV_NAME "c2" -#define DRV_VERSION "1.1" -#define PFX DRV_NAME ": " - -#define BAR_0 0 -#define BAR_2 2 -#define BAR_4 4 - -#define RX_BUF_SIZE (1536 + 8) -#define ETH_JUMBO_MTU 9000 -#define C2_MAGIC "CEPHEUS" -#define C2_VERSION 4 -#define C2_IVN (18 & 0x7fffffff) - -#define C2_REG0_SIZE (16 * 1024) -#define C2_REG2_SIZE (2 * 1024 * 1024) -#define C2_REG4_SIZE (256 * 1024 * 1024) -#define C2_NUM_TX_DESC 341 -#define C2_NUM_RX_DESC 256 -#define C2_PCI_REGS_OFFSET (0x10000) -#define C2_RXP_HRXDQ_OFFSET (((C2_REG4_SIZE)/2)) -#define C2_RXP_HRXDQ_SIZE (4096) -#define C2_TXP_HTXDQ_OFFSET (((C2_REG4_SIZE)/2) + C2_RXP_HRXDQ_SIZE) -#define C2_TXP_HTXDQ_SIZE (4096) -#define C2_TX_TIMEOUT (6*HZ) - -/* CEPHEUS */ -static const u8 c2_magic[] = { - 0x43, 0x45, 0x50, 0x48, 0x45, 0x55, 0x53 -}; - -enum adapter_pci_regs { - C2_REGS_MAGIC = 0x0000, - C2_REGS_VERS = 0x0008, - C2_REGS_IVN = 0x000C, - C2_REGS_PCI_WINSIZE = 0x0010, - C2_REGS_Q0_QSIZE = 0x0014, - C2_REGS_Q0_MSGSIZE = 0x0018, - C2_REGS_Q0_POOLSTART = 0x001C, - C2_REGS_Q0_SHARED = 0x0020, - C2_REGS_Q1_QSIZE = 0x0024, - C2_REGS_Q1_MSGSIZE = 0x0028, - C2_REGS_Q1_SHARED = 0x0030, - C2_REGS_Q2_QSIZE = 0x0034, - C2_REGS_Q2_MSGSIZE = 0x0038, - C2_REGS_Q2_SHARED = 0x0040, - C2_REGS_ENADDR = 0x004C, - C2_REGS_RDMA_ENADDR = 0x0054, - C2_REGS_HRX_CUR = 0x006C, -}; - -struct c2_adapter_pci_regs { - char reg_magic[8]; - u32 version; - u32 ivn; - u32 pci_window_size; - u32 q0_q_size; - u32 q0_msg_size; - u32 q0_pool_start; - u32 q0_shared; - u32 q1_q_size; - u32 q1_msg_size; - u32 q1_pool_start; - u32 q1_shared; - u32 q2_q_size; - u32 q2_msg_size; - u32 q2_pool_start; - u32 q2_shared; - u32 log_start; - u32 log_size; - u8 host_enaddr[8]; - u8 rdma_enaddr[8]; - u32 crash_entry; - u32 crash_ready[2]; - u32 fw_txd_cur; - u32 fw_hrxd_cur; - u32 fw_rxd_cur; -}; - -enum pci_regs { - C2_HISR = 0x0000, - C2_DISR = 0x0004, - C2_HIMR = 0x0008, - C2_DIMR = 0x000C, - C2_NISR0 = 0x0010, - C2_NISR1 = 0x0014, - C2_NIMR0 = 0x0018, - C2_NIMR1 = 0x001C, - C2_IDIS = 0x0020, -}; - -enum { - C2_PCI_HRX_INT = 1 << 8, - C2_PCI_HTX_INT = 1 << 17, - C2_PCI_HRX_QUI = 1 << 31, -}; - -/* - * Cepheus registers in BAR0. - */ -struct c2_pci_regs { - u32 hostisr; - u32 dmaisr; - u32 hostimr; - u32 dmaimr; - u32 netisr0; - u32 netisr1; - u32 netimr0; - u32 netimr1; - u32 int_disable; -}; - -/* TXP flags */ -enum c2_txp_flags { - TXP_HTXD_DONE = 0, - TXP_HTXD_READY = 1 << 0, - TXP_HTXD_UNINIT = 1 << 1, -}; - -/* RXP flags */ -enum c2_rxp_flags { - RXP_HRXD_UNINIT = 0, - RXP_HRXD_READY = 1 << 0, - RXP_HRXD_DONE = 1 << 1, -}; - -/* RXP status */ -enum c2_rxp_status { - RXP_HRXD_ZERO = 0, - RXP_HRXD_OK = 1 << 0, - RXP_HRXD_BUF_OV = 1 << 1, -}; - -/* TXP descriptor fields */ -enum txp_desc { - C2_TXP_FLAGS = 0x0000, - C2_TXP_LEN = 0x0002, - C2_TXP_ADDR = 0x0004, -}; - -/* RXP descriptor fields */ -enum rxp_desc { - C2_RXP_FLAGS = 0x0000, - C2_RXP_STATUS = 0x0002, - C2_RXP_COUNT = 0x0004, - C2_RXP_LEN = 0x0006, - C2_RXP_ADDR = 0x0008, -}; - -struct c2_txp_desc { - u16 flags; - u16 len; - u64 addr; -} __attribute__ ((packed)); - -struct c2_rxp_desc { - u16 flags; - u16 status; - u16 count; - u16 len; - u64 addr; -} __attribute__ ((packed)); - -struct c2_rxp_hdr { - u16 flags; - u16 status; - u16 len; - u16 rsvd; -} __attribute__ ((packed)); - -struct c2_tx_desc { - u32 len; - u32 status; - dma_addr_t next_offset; -}; - -struct c2_rx_desc { - u32 len; - u32 status; - dma_addr_t next_offset; -}; - -struct c2_alloc { - u32 last; - u32 max; - spinlock_t lock; - unsigned long *table; -}; - -struct c2_array { - struct { - void **page; - int used; - } *page_list; -}; - -/* - * The MQ shared pointer pool is organized as a linked list of - * chunks. Each chunk contains a linked list of free shared pointers - * that can be allocated to a given user mode client. - * - */ -struct sp_chunk { - struct sp_chunk *next; - dma_addr_t dma_addr; - DEFINE_DMA_UNMAP_ADDR(mapping); - u16 head; - u16 shared_ptr[0]; -}; - -struct c2_pd_table { - u32 last; - u32 max; - spinlock_t lock; - unsigned long *table; -}; - -struct c2_qp_table { - struct idr idr; - spinlock_t lock; -}; - -struct c2_element { - struct c2_element *next; - void *ht_desc; /* host descriptor */ - void __iomem *hw_desc; /* hardware descriptor */ - struct sk_buff *skb; - dma_addr_t mapaddr; - u32 maplen; -}; - -struct c2_ring { - struct c2_element *to_clean; - struct c2_element *to_use; - struct c2_element *start; - unsigned long count; -}; - -struct c2_dev { - struct ib_device ibdev; - void __iomem *regs; - void __iomem *mmio_txp_ring; /* remapped adapter memory for hw rings */ - void __iomem *mmio_rxp_ring; - spinlock_t lock; - struct pci_dev *pcidev; - struct net_device *netdev; - struct net_device *pseudo_netdev; - unsigned int cur_tx; - unsigned int cur_rx; - u32 adapter_handle; - int device_cap_flags; - void __iomem *kva; /* KVA device memory */ - unsigned long pa; /* PA device memory */ - void **qptr_array; - - struct kmem_cache *host_msg_cache; - - struct list_head cca_link; /* adapter list */ - struct list_head eh_wakeup_list; /* event wakeup list */ - wait_queue_head_t req_vq_wo; - - /* Cached RNIC properties */ - struct ib_device_attr props; - - struct c2_pd_table pd_table; - struct c2_qp_table qp_table; - int ports; /* num of GigE ports */ - int devnum; - spinlock_t vqlock; /* sync vbs req MQ */ - - /* Verbs Queues */ - struct c2_mq req_vq; /* Verbs Request MQ */ - struct c2_mq rep_vq; /* Verbs Reply MQ */ - struct c2_mq aeq; /* Async Events MQ */ - - /* Kernel client MQs */ - struct sp_chunk *kern_mqsp_pool; - - /* Device updates these values when posting messages to a host - * target queue */ - u16 req_vq_shared; - u16 rep_vq_shared; - u16 aeq_shared; - u16 irq_claimed; - - /* - * Shared host target pages for user-accessible MQs. - */ - int hthead; /* index of first free entry */ - void *htpages; /* kernel vaddr */ - int htlen; /* length of htpages memory */ - void *htuva; /* user mapped vaddr */ - spinlock_t htlock; /* serialize allocation */ - - u64 adapter_hint_uva; /* access to the activity FIFO */ - - // spinlock_t aeq_lock; - // spinlock_t rnic_lock; - - __be16 *hint_count; - dma_addr_t hint_count_dma; - u16 hints_read; - - int init; /* TRUE if it's ready */ - char ae_cache_name[16]; - char vq_cache_name[16]; -}; - -struct c2_port { - u32 msg_enable; - struct c2_dev *c2dev; - struct net_device *netdev; - - spinlock_t tx_lock; - u32 tx_avail; - struct c2_ring tx_ring; - struct c2_ring rx_ring; - - void *mem; /* PCI memory for host rings */ - dma_addr_t dma; - unsigned long mem_size; - - u32 rx_buf_size; -}; - -/* - * Activity FIFO registers in BAR0. - */ -#define PCI_BAR0_HOST_HINT 0x100 -#define PCI_BAR0_ADAPTER_HINT 0x2000 - -/* - * Ammasso PCI vendor id and Cepheus PCI device id. - */ -#define CQ_ARMED 0x01 -#define CQ_WAIT_FOR_DMA 0x80 - -/* - * The format of a hint is as follows: - * Lower 16 bits are the count of hints for the queue. - * Next 15 bits are the qp_index - * Upper most bit depends on who reads it: - * If read by producer, then it means Full (1) or Not-Full (0) - * If read by consumer, then it means Empty (1) or Not-Empty (0) - */ -#define C2_HINT_MAKE(q_index, hint_count) (((q_index) << 16) | hint_count) -#define C2_HINT_GET_INDEX(hint) (((hint) & 0x7FFF0000) >> 16) -#define C2_HINT_GET_COUNT(hint) ((hint) & 0x0000FFFF) - - -/* - * The following defines the offset in SDRAM for the c2_adapter_pci_regs_t - * struct. - */ -#define C2_ADAPTER_PCI_REGS_OFFSET 0x10000 - -#ifndef readq -static inline u64 readq(const void __iomem * addr) -{ - u64 ret = readl(addr + 4); - ret <<= 32; - ret |= readl(addr); - - return ret; -} -#endif - -#ifndef writeq -static inline void __raw_writeq(u64 val, void __iomem * addr) -{ - __raw_writel((u32) (val), addr); - __raw_writel((u32) (val >> 32), (addr + 4)); -} -#endif - -#define C2_SET_CUR_RX(c2dev, cur_rx) \ - __raw_writel((__force u32) cpu_to_be32(cur_rx), c2dev->mmio_txp_ring + 4092) - -#define C2_GET_CUR_RX(c2dev) \ - be32_to_cpu((__force __be32) readl(c2dev->mmio_txp_ring + 4092)) - -static inline struct c2_dev *to_c2dev(struct ib_device *ibdev) -{ - return container_of(ibdev, struct c2_dev, ibdev); -} - -static inline int c2_errno(void *reply) -{ - switch (c2_wr_get_result(reply)) { - case C2_OK: - return 0; - case CCERR_NO_BUFS: - case CCERR_INSUFFICIENT_RESOURCES: - case CCERR_ZERO_RDMA_READ_RESOURCES: - return -ENOMEM; - case CCERR_MR_IN_USE: - case CCERR_QP_IN_USE: - return -EBUSY; - case CCERR_ADDR_IN_USE: - return -EADDRINUSE; - case CCERR_ADDR_NOT_AVAIL: - return -EADDRNOTAVAIL; - case CCERR_CONN_RESET: - return -ECONNRESET; - case CCERR_NOT_IMPLEMENTED: - case CCERR_INVALID_WQE: - return -ENOSYS; - case CCERR_QP_NOT_PRIVILEGED: - return -EPERM; - case CCERR_STACK_ERROR: - return -EPROTO; - case CCERR_ACCESS_VIOLATION: - case CCERR_BASE_AND_BOUNDS_VIOLATION: - return -EFAULT; - case CCERR_STAG_STATE_NOT_INVALID: - case CCERR_INVALID_ADDRESS: - case CCERR_INVALID_CQ: - case CCERR_INVALID_EP: - case CCERR_INVALID_MODIFIER: - case CCERR_INVALID_MTU: - case CCERR_INVALID_PD_ID: - case CCERR_INVALID_QP: - case CCERR_INVALID_RNIC: - case CCERR_INVALID_STAG: - return -EINVAL; - default: - return -EAGAIN; - } -} - -/* Device */ -extern int c2_register_device(struct c2_dev *c2dev); -extern void c2_unregister_device(struct c2_dev *c2dev); -extern int c2_rnic_init(struct c2_dev *c2dev); -extern void c2_rnic_term(struct c2_dev *c2dev); -extern void c2_rnic_interrupt(struct c2_dev *c2dev); -extern int c2_del_addr(struct c2_dev *c2dev, __be32 inaddr, __be32 inmask); -extern int c2_add_addr(struct c2_dev *c2dev, __be32 inaddr, __be32 inmask); - -/* QPs */ -extern int c2_alloc_qp(struct c2_dev *c2dev, struct c2_pd *pd, - struct ib_qp_init_attr *qp_attrs, struct c2_qp *qp); -extern void c2_free_qp(struct c2_dev *c2dev, struct c2_qp *qp); -extern struct ib_qp *c2_get_qp(struct ib_device *device, int qpn); -extern int c2_qp_modify(struct c2_dev *c2dev, struct c2_qp *qp, - struct ib_qp_attr *attr, int attr_mask); -extern int c2_qp_set_read_limits(struct c2_dev *c2dev, struct c2_qp *qp, - int ord, int ird); -extern int c2_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, - struct ib_send_wr **bad_wr); -extern int c2_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr, - struct ib_recv_wr **bad_wr); -extern void c2_init_qp_table(struct c2_dev *c2dev); -extern void c2_cleanup_qp_table(struct c2_dev *c2dev); -extern void c2_set_qp_state(struct c2_qp *, int); -extern struct c2_qp *c2_find_qpn(struct c2_dev *c2dev, int qpn); - -/* PDs */ -extern int c2_pd_alloc(struct c2_dev *c2dev, int privileged, struct c2_pd *pd); -extern void c2_pd_free(struct c2_dev *c2dev, struct c2_pd *pd); -extern int c2_init_pd_table(struct c2_dev *c2dev); -extern void c2_cleanup_pd_table(struct c2_dev *c2dev); - -/* CQs */ -extern int c2_init_cq(struct c2_dev *c2dev, int entries, - struct c2_ucontext *ctx, struct c2_cq *cq); -extern void c2_free_cq(struct c2_dev *c2dev, struct c2_cq *cq); -extern void c2_cq_event(struct c2_dev *c2dev, u32 mq_index); -extern void c2_cq_clean(struct c2_dev *c2dev, struct c2_qp *qp, u32 mq_index); -extern int c2_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry); -extern int c2_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags); - -/* CM */ -extern int c2_llp_connect(struct iw_cm_id *cm_id, - struct iw_cm_conn_param *iw_param); -extern int c2_llp_accept(struct iw_cm_id *cm_id, - struct iw_cm_conn_param *iw_param); -extern int c2_llp_reject(struct iw_cm_id *cm_id, const void *pdata, - u8 pdata_len); -extern int c2_llp_service_create(struct iw_cm_id *cm_id, int backlog); -extern int c2_llp_service_destroy(struct iw_cm_id *cm_id); - -/* MM */ -extern int c2_nsmr_register_phys_kern(struct c2_dev *c2dev, u64 *addr_list, - int page_size, int pbl_depth, u32 length, - u32 off, u64 *va, enum c2_acf acf, - struct c2_mr *mr); -extern int c2_stag_dealloc(struct c2_dev *c2dev, u32 stag_index); - -/* AE */ -extern void c2_ae_event(struct c2_dev *c2dev, u32 mq_index); - -/* MQSP Allocator */ -extern int c2_init_mqsp_pool(struct c2_dev *c2dev, gfp_t gfp_mask, - struct sp_chunk **root); -extern void c2_free_mqsp_pool(struct c2_dev *c2dev, struct sp_chunk *root); -extern __be16 *c2_alloc_mqsp(struct c2_dev *c2dev, struct sp_chunk *head, - dma_addr_t *dma_addr, gfp_t gfp_mask); -extern void c2_free_mqsp(__be16* mqsp); -#endif diff --git a/kernel/drivers/infiniband/hw/amso1100/c2_ae.c b/kernel/drivers/infiniband/hw/amso1100/c2_ae.c deleted file mode 100644 index cedda2523..000000000 --- a/kernel/drivers/infiniband/hw/amso1100/c2_ae.c +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright (c) 2005 Ammasso, Inc. All rights reserved. - * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include "c2.h" -#include <rdma/iw_cm.h> -#include "c2_status.h" -#include "c2_ae.h" - -static int c2_convert_cm_status(u32 c2_status) -{ - switch (c2_status) { - case C2_CONN_STATUS_SUCCESS: - return 0; - case C2_CONN_STATUS_REJECTED: - return -ENETRESET; - case C2_CONN_STATUS_REFUSED: - return -ECONNREFUSED; - case C2_CONN_STATUS_TIMEDOUT: - return -ETIMEDOUT; - case C2_CONN_STATUS_NETUNREACH: - return -ENETUNREACH; - case C2_CONN_STATUS_HOSTUNREACH: - return -EHOSTUNREACH; - case C2_CONN_STATUS_INVALID_RNIC: - return -EINVAL; - case C2_CONN_STATUS_INVALID_QP: - return -EINVAL; - case C2_CONN_STATUS_INVALID_QP_STATE: - return -EINVAL; - case C2_CONN_STATUS_ADDR_NOT_AVAIL: - return -EADDRNOTAVAIL; - default: - printk(KERN_ERR PFX - "%s - Unable to convert CM status: %d\n", - __func__, c2_status); - return -EIO; - } -} - -static const char* to_event_str(int event) -{ - static const char* event_str[] = { - "CCAE_REMOTE_SHUTDOWN", - "CCAE_ACTIVE_CONNECT_RESULTS", - "CCAE_CONNECTION_REQUEST", - "CCAE_LLP_CLOSE_COMPLETE", - "CCAE_TERMINATE_MESSAGE_RECEIVED", - "CCAE_LLP_CONNECTION_RESET", - "CCAE_LLP_CONNECTION_LOST", - "CCAE_LLP_SEGMENT_SIZE_INVALID", - "CCAE_LLP_INVALID_CRC", - "CCAE_LLP_BAD_FPDU", - "CCAE_INVALID_DDP_VERSION", - "CCAE_INVALID_RDMA_VERSION", - "CCAE_UNEXPECTED_OPCODE", - "CCAE_INVALID_DDP_QUEUE_NUMBER", - "CCAE_RDMA_READ_NOT_ENABLED", - "CCAE_RDMA_WRITE_NOT_ENABLED", - "CCAE_RDMA_READ_TOO_SMALL", - "CCAE_NO_L_BIT", - "CCAE_TAGGED_INVALID_STAG", - "CCAE_TAGGED_BASE_BOUNDS_VIOLATION", - "CCAE_TAGGED_ACCESS_RIGHTS_VIOLATION", - "CCAE_TAGGED_INVALID_PD", - "CCAE_WRAP_ERROR", - "CCAE_BAD_CLOSE", - "CCAE_BAD_LLP_CLOSE", - "CCAE_INVALID_MSN_RANGE", - "CCAE_INVALID_MSN_GAP", - "CCAE_IRRQ_OVERFLOW", - "CCAE_IRRQ_MSN_GAP", - "CCAE_IRRQ_MSN_RANGE", - "CCAE_IRRQ_INVALID_STAG", - "CCAE_IRRQ_BASE_BOUNDS_VIOLATION", - "CCAE_IRRQ_ACCESS_RIGHTS_VIOLATION", - "CCAE_IRRQ_INVALID_PD", - "CCAE_IRRQ_WRAP_ERROR", - "CCAE_CQ_SQ_COMPLETION_OVERFLOW", - "CCAE_CQ_RQ_COMPLETION_ERROR", - "CCAE_QP_SRQ_WQE_ERROR", - "CCAE_QP_LOCAL_CATASTROPHIC_ERROR", - "CCAE_CQ_OVERFLOW", - "CCAE_CQ_OPERATION_ERROR", - "CCAE_SRQ_LIMIT_REACHED", - "CCAE_QP_RQ_LIMIT_REACHED", - "CCAE_SRQ_CATASTROPHIC_ERROR", - "CCAE_RNIC_CATASTROPHIC_ERROR" - }; - - if (event < CCAE_REMOTE_SHUTDOWN || - event > CCAE_RNIC_CATASTROPHIC_ERROR) - return "<invalid event>"; - - event -= CCAE_REMOTE_SHUTDOWN; - return event_str[event]; -} - -static const char *to_qp_state_str(int state) -{ - switch (state) { - case C2_QP_STATE_IDLE: - return "C2_QP_STATE_IDLE"; - case C2_QP_STATE_CONNECTING: - return "C2_QP_STATE_CONNECTING"; - case C2_QP_STATE_RTS: - return "C2_QP_STATE_RTS"; - case C2_QP_STATE_CLOSING: - return "C2_QP_STATE_CLOSING"; - case C2_QP_STATE_TERMINATE: - return "C2_QP_STATE_TERMINATE"; - case C2_QP_STATE_ERROR: - return "C2_QP_STATE_ERROR"; - default: - return "<invalid QP state>"; - } -} - -void c2_ae_event(struct c2_dev *c2dev, u32 mq_index) -{ - struct c2_mq *mq = c2dev->qptr_array[mq_index]; - union c2wr *wr; - void *resource_user_context; - struct iw_cm_event cm_event; - struct ib_event ib_event; - enum c2_resource_indicator resource_indicator; - enum c2_event_id event_id; - unsigned long flags; - int status; - struct sockaddr_in *laddr = (struct sockaddr_in *)&cm_event.local_addr; - struct sockaddr_in *raddr = (struct sockaddr_in *)&cm_event.remote_addr; - - /* - * retrieve the message - */ - wr = c2_mq_consume(mq); - if (!wr) - return; - - memset(&ib_event, 0, sizeof(ib_event)); - memset(&cm_event, 0, sizeof(cm_event)); - - event_id = c2_wr_get_id(wr); - resource_indicator = be32_to_cpu(wr->ae.ae_generic.resource_type); - resource_user_context = - (void *) (unsigned long) wr->ae.ae_generic.user_context; - - status = cm_event.status = c2_convert_cm_status(c2_wr_get_result(wr)); - - pr_debug("event received c2_dev=%p, event_id=%d, " - "resource_indicator=%d, user_context=%p, status = %d\n", - c2dev, event_id, resource_indicator, resource_user_context, - status); - - switch (resource_indicator) { - case C2_RES_IND_QP:{ - - struct c2_qp *qp = (struct c2_qp *)resource_user_context; - struct iw_cm_id *cm_id = qp->cm_id; - struct c2wr_ae_active_connect_results *res; - - if (!cm_id) { - pr_debug("event received, but cm_id is <nul>, qp=%p!\n", - qp); - goto ignore_it; - } - pr_debug("%s: event = %s, user_context=%llx, " - "resource_type=%x, " - "resource=%x, qp_state=%s\n", - __func__, - to_event_str(event_id), - (unsigned long long) wr->ae.ae_generic.user_context, - be32_to_cpu(wr->ae.ae_generic.resource_type), - be32_to_cpu(wr->ae.ae_generic.resource), - to_qp_state_str(be32_to_cpu(wr->ae.ae_generic.qp_state))); - - c2_set_qp_state(qp, be32_to_cpu(wr->ae.ae_generic.qp_state)); - - switch (event_id) { - case CCAE_ACTIVE_CONNECT_RESULTS: - res = &wr->ae.ae_active_connect_results; - cm_event.event = IW_CM_EVENT_CONNECT_REPLY; - laddr->sin_addr.s_addr = res->laddr; - raddr->sin_addr.s_addr = res->raddr; - laddr->sin_port = res->lport; - raddr->sin_port = res->rport; - if (status == 0) { - cm_event.private_data_len = - be32_to_cpu(res->private_data_length); - cm_event.private_data = res->private_data; - } else { - spin_lock_irqsave(&qp->lock, flags); - if (qp->cm_id) { - qp->cm_id->rem_ref(qp->cm_id); - qp->cm_id = NULL; - } - spin_unlock_irqrestore(&qp->lock, flags); - cm_event.private_data_len = 0; - cm_event.private_data = NULL; - } - if (cm_id->event_handler) - cm_id->event_handler(cm_id, &cm_event); - break; - case CCAE_TERMINATE_MESSAGE_RECEIVED: - case CCAE_CQ_SQ_COMPLETION_OVERFLOW: - ib_event.device = &c2dev->ibdev; - ib_event.element.qp = &qp->ibqp; - ib_event.event = IB_EVENT_QP_REQ_ERR; - - if (qp->ibqp.event_handler) - qp->ibqp.event_handler(&ib_event, - qp->ibqp. - qp_context); - break; - case CCAE_BAD_CLOSE: - case CCAE_LLP_CLOSE_COMPLETE: - case CCAE_LLP_CONNECTION_RESET: - case CCAE_LLP_CONNECTION_LOST: - BUG_ON(cm_id->event_handler==(void*)0x6b6b6b6b); - - spin_lock_irqsave(&qp->lock, flags); - if (qp->cm_id) { - qp->cm_id->rem_ref(qp->cm_id); - qp->cm_id = NULL; - } - spin_unlock_irqrestore(&qp->lock, flags); - cm_event.event = IW_CM_EVENT_CLOSE; - cm_event.status = 0; - if (cm_id->event_handler) - cm_id->event_handler(cm_id, &cm_event); - break; - default: - BUG_ON(1); - pr_debug("%s:%d Unexpected event_id=%d on QP=%p, " - "CM_ID=%p\n", - __func__, __LINE__, - event_id, qp, cm_id); - break; - } - break; - } - - case C2_RES_IND_EP:{ - - struct c2wr_ae_connection_request *req = - &wr->ae.ae_connection_request; - struct iw_cm_id *cm_id = - (struct iw_cm_id *)resource_user_context; - - pr_debug("C2_RES_IND_EP event_id=%d\n", event_id); - if (event_id != CCAE_CONNECTION_REQUEST) { - pr_debug("%s: Invalid event_id: %d\n", - __func__, event_id); - break; - } - cm_event.event = IW_CM_EVENT_CONNECT_REQUEST; - cm_event.provider_data = (void*)(unsigned long)req->cr_handle; - laddr->sin_addr.s_addr = req->laddr; - raddr->sin_addr.s_addr = req->raddr; - laddr->sin_port = req->lport; - raddr->sin_port = req->rport; - cm_event.private_data_len = - be32_to_cpu(req->private_data_length); - cm_event.private_data = req->private_data; - /* - * Until ird/ord negotiation via MPAv2 support is added, send - * max supported values - */ - cm_event.ird = cm_event.ord = 128; - - if (cm_id->event_handler) - cm_id->event_handler(cm_id, &cm_event); - break; - } - - case C2_RES_IND_CQ:{ - struct c2_cq *cq = - (struct c2_cq *) resource_user_context; - - pr_debug("IB_EVENT_CQ_ERR\n"); - ib_event.device = &c2dev->ibdev; - ib_event.element.cq = &cq->ibcq; - ib_event.event = IB_EVENT_CQ_ERR; - - if (cq->ibcq.event_handler) - cq->ibcq.event_handler(&ib_event, - cq->ibcq.cq_context); - break; - } - - default: - printk("Bad resource indicator = %d\n", - resource_indicator); - break; - } - - ignore_it: - c2_mq_free(mq); -} diff --git a/kernel/drivers/infiniband/hw/amso1100/c2_ae.h b/kernel/drivers/infiniband/hw/amso1100/c2_ae.h deleted file mode 100644 index 3a065c33b..000000000 --- a/kernel/drivers/infiniband/hw/amso1100/c2_ae.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2005 Ammasso, Inc. All rights reserved. - * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef _C2_AE_H_ -#define _C2_AE_H_ - -/* - * WARNING: If you change this file, also bump C2_IVN_BASE - * in common/include/clustercore/c2_ivn.h. - */ - -/* - * Asynchronous Event Identifiers - * - * These start at 0x80 only so it's obvious from inspection that - * they are not work-request statuses. This isn't critical. - * - * NOTE: these event id's must fit in eight bits. - */ -enum c2_event_id { - CCAE_REMOTE_SHUTDOWN = 0x80, - CCAE_ACTIVE_CONNECT_RESULTS, - CCAE_CONNECTION_REQUEST, - CCAE_LLP_CLOSE_COMPLETE, - CCAE_TERMINATE_MESSAGE_RECEIVED, - CCAE_LLP_CONNECTION_RESET, - CCAE_LLP_CONNECTION_LOST, - CCAE_LLP_SEGMENT_SIZE_INVALID, - CCAE_LLP_INVALID_CRC, - CCAE_LLP_BAD_FPDU, - CCAE_INVALID_DDP_VERSION, - CCAE_INVALID_RDMA_VERSION, - CCAE_UNEXPECTED_OPCODE, - CCAE_INVALID_DDP_QUEUE_NUMBER, - CCAE_RDMA_READ_NOT_ENABLED, - CCAE_RDMA_WRITE_NOT_ENABLED, - CCAE_RDMA_READ_TOO_SMALL, - CCAE_NO_L_BIT, - CCAE_TAGGED_INVALID_STAG, - CCAE_TAGGED_BASE_BOUNDS_VIOLATION, - CCAE_TAGGED_ACCESS_RIGHTS_VIOLATION, - CCAE_TAGGED_INVALID_PD, - CCAE_WRAP_ERROR, - CCAE_BAD_CLOSE, - CCAE_BAD_LLP_CLOSE, - CCAE_INVALID_MSN_RANGE, - CCAE_INVALID_MSN_GAP, - CCAE_IRRQ_OVERFLOW, - CCAE_IRRQ_MSN_GAP, - CCAE_IRRQ_MSN_RANGE, - CCAE_IRRQ_INVALID_STAG, - CCAE_IRRQ_BASE_BOUNDS_VIOLATION, - CCAE_IRRQ_ACCESS_RIGHTS_VIOLATION, - CCAE_IRRQ_INVALID_PD, - CCAE_IRRQ_WRAP_ERROR, - CCAE_CQ_SQ_COMPLETION_OVERFLOW, - CCAE_CQ_RQ_COMPLETION_ERROR, - CCAE_QP_SRQ_WQE_ERROR, - CCAE_QP_LOCAL_CATASTROPHIC_ERROR, - CCAE_CQ_OVERFLOW, - CCAE_CQ_OPERATION_ERROR, - CCAE_SRQ_LIMIT_REACHED, - CCAE_QP_RQ_LIMIT_REACHED, - CCAE_SRQ_CATASTROPHIC_ERROR, - CCAE_RNIC_CATASTROPHIC_ERROR -/* WARNING If you add more id's, make sure their values fit in eight bits. */ -}; - -/* - * Resource Indicators and Identifiers - */ -enum c2_resource_indicator { - C2_RES_IND_QP = 1, - C2_RES_IND_EP, - C2_RES_IND_CQ, - C2_RES_IND_SRQ, -}; - -#endif /* _C2_AE_H_ */ diff --git a/kernel/drivers/infiniband/hw/amso1100/c2_alloc.c b/kernel/drivers/infiniband/hw/amso1100/c2_alloc.c deleted file mode 100644 index 78d247ec6..000000000 --- a/kernel/drivers/infiniband/hw/amso1100/c2_alloc.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2004 Topspin Communications. All rights reserved. - * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include <linux/errno.h> -#include <linux/bitmap.h> - -#include "c2.h" - -static int c2_alloc_mqsp_chunk(struct c2_dev *c2dev, gfp_t gfp_mask, - struct sp_chunk **head) -{ - int i; - struct sp_chunk *new_head; - dma_addr_t dma_addr; - - new_head = dma_alloc_coherent(&c2dev->pcidev->dev, PAGE_SIZE, - &dma_addr, gfp_mask); - if (new_head == NULL) - return -ENOMEM; - - new_head->dma_addr = dma_addr; - dma_unmap_addr_set(new_head, mapping, new_head->dma_addr); - - new_head->next = NULL; - new_head->head = 0; - - /* build list where each index is the next free slot */ - for (i = 0; - i < (PAGE_SIZE - sizeof(struct sp_chunk) - - sizeof(u16)) / sizeof(u16) - 1; - i++) { - new_head->shared_ptr[i] = i + 1; - } - /* terminate list */ - new_head->shared_ptr[i] = 0xFFFF; - - *head = new_head; - return 0; -} - -int c2_init_mqsp_pool(struct c2_dev *c2dev, gfp_t gfp_mask, - struct sp_chunk **root) -{ - return c2_alloc_mqsp_chunk(c2dev, gfp_mask, root); -} - -void c2_free_mqsp_pool(struct c2_dev *c2dev, struct sp_chunk *root) -{ - struct sp_chunk *next; - - while (root) { - next = root->next; - dma_free_coherent(&c2dev->pcidev->dev, PAGE_SIZE, root, - dma_unmap_addr(root, mapping)); - root = next; - } -} - -__be16 *c2_alloc_mqsp(struct c2_dev *c2dev, struct sp_chunk *head, - dma_addr_t *dma_addr, gfp_t gfp_mask) -{ - u16 mqsp; - - while (head) { - mqsp = head->head; - if (mqsp != 0xFFFF) { - head->head = head->shared_ptr[mqsp]; - break; - } else if (head->next == NULL) { - if (c2_alloc_mqsp_chunk(c2dev, gfp_mask, &head->next) == - 0) { - head = head->next; - mqsp = head->head; - head->head = head->shared_ptr[mqsp]; - break; - } else - return NULL; - } else - head = head->next; - } - if (head) { - *dma_addr = head->dma_addr + - ((unsigned long) &(head->shared_ptr[mqsp]) - - (unsigned long) head); - pr_debug("%s addr %p dma_addr %llx\n", __func__, - &(head->shared_ptr[mqsp]), (unsigned long long) *dma_addr); - return (__force __be16 *) &(head->shared_ptr[mqsp]); - } - return NULL; -} - -void c2_free_mqsp(__be16 *mqsp) -{ - struct sp_chunk *head; - u16 idx; - - /* The chunk containing this ptr begins at the page boundary */ - head = (struct sp_chunk *) ((unsigned long) mqsp & PAGE_MASK); - - /* Link head to new mqsp */ - *mqsp = (__force __be16) head->head; - - /* Compute the shared_ptr index */ - idx = ((unsigned long) mqsp & ~PAGE_MASK) >> 1; - idx -= (unsigned long) &(((struct sp_chunk *) 0)->shared_ptr[0]) >> 1; - - /* Point this index at the head */ - head->shared_ptr[idx] = head->head; - - /* Point head at this index */ - head->head = idx; -} diff --git a/kernel/drivers/infiniband/hw/amso1100/c2_cm.c b/kernel/drivers/infiniband/hw/amso1100/c2_cm.c deleted file mode 100644 index 23bfa94fb..000000000 --- a/kernel/drivers/infiniband/hw/amso1100/c2_cm.c +++ /dev/null @@ -1,461 +0,0 @@ -/* - * Copyright (c) 2005 Ammasso, Inc. All rights reserved. - * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ -#include <linux/slab.h> - -#include "c2.h" -#include "c2_wr.h" -#include "c2_vq.h" -#include <rdma/iw_cm.h> - -int c2_llp_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param) -{ - struct c2_dev *c2dev = to_c2dev(cm_id->device); - struct ib_qp *ibqp; - struct c2_qp *qp; - struct c2wr_qp_connect_req *wr; /* variable size needs a malloc. */ - struct c2_vq_req *vq_req; - int err; - struct sockaddr_in *raddr = (struct sockaddr_in *)&cm_id->remote_addr; - - if (cm_id->remote_addr.ss_family != AF_INET) - return -ENOSYS; - - ibqp = c2_get_qp(cm_id->device, iw_param->qpn); - if (!ibqp) - return -EINVAL; - qp = to_c2qp(ibqp); - - /* Associate QP <--> CM_ID */ - cm_id->provider_data = qp; - cm_id->add_ref(cm_id); - qp->cm_id = cm_id; - - /* - * only support the max private_data length - */ - if (iw_param->private_data_len > C2_MAX_PRIVATE_DATA_SIZE) { - err = -EINVAL; - goto bail0; - } - /* - * Set the rdma read limits - */ - err = c2_qp_set_read_limits(c2dev, qp, iw_param->ord, iw_param->ird); - if (err) - goto bail0; - - /* - * Create and send a WR_QP_CONNECT... - */ - wr = kmalloc(c2dev->req_vq.msg_size, GFP_KERNEL); - if (!wr) { - err = -ENOMEM; - goto bail0; - } - - vq_req = vq_req_alloc(c2dev); - if (!vq_req) { - err = -ENOMEM; - goto bail1; - } - - c2_wr_set_id(wr, CCWR_QP_CONNECT); - wr->hdr.context = 0; - wr->rnic_handle = c2dev->adapter_handle; - wr->qp_handle = qp->adapter_handle; - - wr->remote_addr = raddr->sin_addr.s_addr; - wr->remote_port = raddr->sin_port; - - /* - * Move any private data from the callers's buf into - * the WR. - */ - if (iw_param->private_data) { - wr->private_data_length = - cpu_to_be32(iw_param->private_data_len); - memcpy(&wr->private_data[0], iw_param->private_data, - iw_param->private_data_len); - } else - wr->private_data_length = 0; - - /* - * Send WR to adapter. NOTE: There is no synch reply from - * the adapter. - */ - err = vq_send_wr(c2dev, (union c2wr *) wr); - vq_req_free(c2dev, vq_req); - - bail1: - kfree(wr); - bail0: - if (err) { - /* - * If we fail, release reference on QP and - * disassociate QP from CM_ID - */ - cm_id->provider_data = NULL; - qp->cm_id = NULL; - cm_id->rem_ref(cm_id); - } - return err; -} - -int c2_llp_service_create(struct iw_cm_id *cm_id, int backlog) -{ - struct c2_dev *c2dev; - struct c2wr_ep_listen_create_req wr; - struct c2wr_ep_listen_create_rep *reply; - struct c2_vq_req *vq_req; - int err; - struct sockaddr_in *laddr = (struct sockaddr_in *)&cm_id->local_addr; - - if (cm_id->local_addr.ss_family != AF_INET) - return -ENOSYS; - - c2dev = to_c2dev(cm_id->device); - if (c2dev == NULL) - return -EINVAL; - - /* - * Allocate verbs request. - */ - vq_req = vq_req_alloc(c2dev); - if (!vq_req) - return -ENOMEM; - - /* - * Build the WR - */ - c2_wr_set_id(&wr, CCWR_EP_LISTEN_CREATE); - wr.hdr.context = (u64) (unsigned long) vq_req; - wr.rnic_handle = c2dev->adapter_handle; - wr.local_addr = laddr->sin_addr.s_addr; - wr.local_port = laddr->sin_port; - wr.backlog = cpu_to_be32(backlog); - wr.user_context = (u64) (unsigned long) cm_id; - - /* - * Reference the request struct. Dereferenced in the int handler. - */ - vq_req_get(c2dev, vq_req); - - /* - * Send WR to adapter - */ - err = vq_send_wr(c2dev, (union c2wr *) & wr); - if (err) { - vq_req_put(c2dev, vq_req); - goto bail0; - } - - /* - * Wait for reply from adapter - */ - err = vq_wait_for_reply(c2dev, vq_req); - if (err) - goto bail0; - - /* - * Process reply - */ - reply = - (struct c2wr_ep_listen_create_rep *) (unsigned long) vq_req->reply_msg; - if (!reply) { - err = -ENOMEM; - goto bail1; - } - - if ((err = c2_errno(reply)) != 0) - goto bail1; - - /* - * Keep the adapter handle. Used in subsequent destroy - */ - cm_id->provider_data = (void*)(unsigned long) reply->ep_handle; - - /* - * free vq stuff - */ - vq_repbuf_free(c2dev, reply); - vq_req_free(c2dev, vq_req); - - return 0; - - bail1: - vq_repbuf_free(c2dev, reply); - bail0: - vq_req_free(c2dev, vq_req); - return err; -} - - -int c2_llp_service_destroy(struct iw_cm_id *cm_id) -{ - - struct c2_dev *c2dev; - struct c2wr_ep_listen_destroy_req wr; - struct c2wr_ep_listen_destroy_rep *reply; - struct c2_vq_req *vq_req; - int err; - - c2dev = to_c2dev(cm_id->device); - if (c2dev == NULL) - return -EINVAL; - - /* - * Allocate verbs request. - */ - vq_req = vq_req_alloc(c2dev); - if (!vq_req) - return -ENOMEM; - - /* - * Build the WR - */ - c2_wr_set_id(&wr, CCWR_EP_LISTEN_DESTROY); - wr.hdr.context = (unsigned long) vq_req; - wr.rnic_handle = c2dev->adapter_handle; - wr.ep_handle = (u32)(unsigned long)cm_id->provider_data; - - /* - * reference the request struct. dereferenced in the int handler. - */ - vq_req_get(c2dev, vq_req); - - /* - * Send WR to adapter - */ - err = vq_send_wr(c2dev, (union c2wr *) & wr); - if (err) { - vq_req_put(c2dev, vq_req); - goto bail0; - } - - /* - * Wait for reply from adapter - */ - err = vq_wait_for_reply(c2dev, vq_req); - if (err) - goto bail0; - - /* - * Process reply - */ - reply=(struct c2wr_ep_listen_destroy_rep *)(unsigned long)vq_req->reply_msg; - if (!reply) { - err = -ENOMEM; - goto bail0; - } - if ((err = c2_errno(reply)) != 0) - goto bail1; - - bail1: - vq_repbuf_free(c2dev, reply); - bail0: - vq_req_free(c2dev, vq_req); - return err; -} - -int c2_llp_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param) -{ - struct c2_dev *c2dev = to_c2dev(cm_id->device); - struct c2_qp *qp; - struct ib_qp *ibqp; - struct c2wr_cr_accept_req *wr; /* variable length WR */ - struct c2_vq_req *vq_req; - struct c2wr_cr_accept_rep *reply; /* VQ Reply msg ptr. */ - int err; - - ibqp = c2_get_qp(cm_id->device, iw_param->qpn); - if (!ibqp) - return -EINVAL; - qp = to_c2qp(ibqp); - - /* Set the RDMA read limits */ - err = c2_qp_set_read_limits(c2dev, qp, iw_param->ord, iw_param->ird); - if (err) - goto bail0; - - /* Allocate verbs request. */ - vq_req = vq_req_alloc(c2dev); - if (!vq_req) { - err = -ENOMEM; - goto bail0; - } - vq_req->qp = qp; - vq_req->cm_id = cm_id; - vq_req->event = IW_CM_EVENT_ESTABLISHED; - - wr = kmalloc(c2dev->req_vq.msg_size, GFP_KERNEL); - if (!wr) { - err = -ENOMEM; - goto bail1; - } - - /* Build the WR */ - c2_wr_set_id(wr, CCWR_CR_ACCEPT); - wr->hdr.context = (unsigned long) vq_req; - wr->rnic_handle = c2dev->adapter_handle; - wr->ep_handle = (u32) (unsigned long) cm_id->provider_data; - wr->qp_handle = qp->adapter_handle; - - /* Replace the cr_handle with the QP after accept */ - cm_id->provider_data = qp; - cm_id->add_ref(cm_id); - qp->cm_id = cm_id; - - cm_id->provider_data = qp; - - /* Validate private_data length */ - if (iw_param->private_data_len > C2_MAX_PRIVATE_DATA_SIZE) { - err = -EINVAL; - goto bail1; - } - - if (iw_param->private_data) { - wr->private_data_length = cpu_to_be32(iw_param->private_data_len); - memcpy(&wr->private_data[0], - iw_param->private_data, iw_param->private_data_len); - } else - wr->private_data_length = 0; - - /* Reference the request struct. Dereferenced in the int handler. */ - vq_req_get(c2dev, vq_req); - - /* Send WR to adapter */ - err = vq_send_wr(c2dev, (union c2wr *) wr); - if (err) { - vq_req_put(c2dev, vq_req); - goto bail1; - } - - /* Wait for reply from adapter */ - err = vq_wait_for_reply(c2dev, vq_req); - if (err) - goto bail1; - - /* Check that reply is present */ - reply = (struct c2wr_cr_accept_rep *) (unsigned long) vq_req->reply_msg; - if (!reply) { - err = -ENOMEM; - goto bail1; - } - - err = c2_errno(reply); - vq_repbuf_free(c2dev, reply); - - if (!err) - c2_set_qp_state(qp, C2_QP_STATE_RTS); - bail1: - kfree(wr); - vq_req_free(c2dev, vq_req); - bail0: - if (err) { - /* - * If we fail, release reference on QP and - * disassociate QP from CM_ID - */ - cm_id->provider_data = NULL; - qp->cm_id = NULL; - cm_id->rem_ref(cm_id); - } - return err; -} - -int c2_llp_reject(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len) -{ - struct c2_dev *c2dev; - struct c2wr_cr_reject_req wr; - struct c2_vq_req *vq_req; - struct c2wr_cr_reject_rep *reply; - int err; - - c2dev = to_c2dev(cm_id->device); - - /* - * Allocate verbs request. - */ - vq_req = vq_req_alloc(c2dev); - if (!vq_req) - return -ENOMEM; - - /* - * Build the WR - */ - c2_wr_set_id(&wr, CCWR_CR_REJECT); - wr.hdr.context = (unsigned long) vq_req; - wr.rnic_handle = c2dev->adapter_handle; - wr.ep_handle = (u32) (unsigned long) cm_id->provider_data; - - /* - * reference the request struct. dereferenced in the int handler. - */ - vq_req_get(c2dev, vq_req); - - /* - * Send WR to adapter - */ - err = vq_send_wr(c2dev, (union c2wr *) & wr); - if (err) { - vq_req_put(c2dev, vq_req); - goto bail0; - } - - /* - * Wait for reply from adapter - */ - err = vq_wait_for_reply(c2dev, vq_req); - if (err) - goto bail0; - - /* - * Process reply - */ - reply = (struct c2wr_cr_reject_rep *) (unsigned long) - vq_req->reply_msg; - if (!reply) { - err = -ENOMEM; - goto bail0; - } - err = c2_errno(reply); - /* - * free vq stuff - */ - vq_repbuf_free(c2dev, reply); - - bail0: - vq_req_free(c2dev, vq_req); - return err; -} diff --git a/kernel/drivers/infiniband/hw/amso1100/c2_cq.c b/kernel/drivers/infiniband/hw/amso1100/c2_cq.c deleted file mode 100644 index 1b63185b4..000000000 --- a/kernel/drivers/infiniband/hw/amso1100/c2_cq.c +++ /dev/null @@ -1,440 +0,0 @@ -/* - * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. - * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. - * Copyright (c) 2005 Cisco Systems, Inc. All rights reserved. - * Copyright (c) 2005 Mellanox Technologies. All rights reserved. - * Copyright (c) 2004 Voltaire, Inc. All rights reserved. - * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ -#include <linux/gfp.h> - -#include "c2.h" -#include "c2_vq.h" -#include "c2_status.h" - -#define C2_CQ_MSG_SIZE ((sizeof(struct c2wr_ce) + 32-1) & ~(32-1)) - -static struct c2_cq *c2_cq_get(struct c2_dev *c2dev, int cqn) -{ - struct c2_cq *cq; - unsigned long flags; - - spin_lock_irqsave(&c2dev->lock, flags); - cq = c2dev->qptr_array[cqn]; - if (!cq) { - spin_unlock_irqrestore(&c2dev->lock, flags); - return NULL; - } - atomic_inc(&cq->refcount); - spin_unlock_irqrestore(&c2dev->lock, flags); - return cq; -} - -static void c2_cq_put(struct c2_cq *cq) -{ - if (atomic_dec_and_test(&cq->refcount)) - wake_up(&cq->wait); -} - -void c2_cq_event(struct c2_dev *c2dev, u32 mq_index) -{ - struct c2_cq *cq; - - cq = c2_cq_get(c2dev, mq_index); - if (!cq) { - printk("discarding events on destroyed CQN=%d\n", mq_index); - return; - } - - (*cq->ibcq.comp_handler) (&cq->ibcq, cq->ibcq.cq_context); - c2_cq_put(cq); -} - -void c2_cq_clean(struct c2_dev *c2dev, struct c2_qp *qp, u32 mq_index) -{ - struct c2_cq *cq; - struct c2_mq *q; - - cq = c2_cq_get(c2dev, mq_index); - if (!cq) - return; - - spin_lock_irq(&cq->lock); - q = &cq->mq; - if (q && !c2_mq_empty(q)) { - u16 priv = q->priv; - struct c2wr_ce *msg; - - while (priv != be16_to_cpu(*q->shared)) { - msg = (struct c2wr_ce *) - (q->msg_pool.host + priv * q->msg_size); - if (msg->qp_user_context == (u64) (unsigned long) qp) { - msg->qp_user_context = (u64) 0; - } - priv = (priv + 1) % q->q_size; - } - } - spin_unlock_irq(&cq->lock); - c2_cq_put(cq); -} - -static inline enum ib_wc_status c2_cqe_status_to_openib(u8 status) -{ - switch (status) { - case C2_OK: - return IB_WC_SUCCESS; - case CCERR_FLUSHED: - return IB_WC_WR_FLUSH_ERR; - case CCERR_BASE_AND_BOUNDS_VIOLATION: - return IB_WC_LOC_PROT_ERR; - case CCERR_ACCESS_VIOLATION: - return IB_WC_LOC_ACCESS_ERR; - case CCERR_TOTAL_LENGTH_TOO_BIG: - return IB_WC_LOC_LEN_ERR; - case CCERR_INVALID_WINDOW: - return IB_WC_MW_BIND_ERR; - default: - return IB_WC_GENERAL_ERR; - } -} - - -static inline int c2_poll_one(struct c2_dev *c2dev, - struct c2_cq *cq, struct ib_wc *entry) -{ - struct c2wr_ce *ce; - struct c2_qp *qp; - int is_recv = 0; - - ce = c2_mq_consume(&cq->mq); - if (!ce) { - return -EAGAIN; - } - - /* - * if the qp returned is null then this qp has already - * been freed and we are unable process the completion. - * try pulling the next message - */ - while ((qp = - (struct c2_qp *) (unsigned long) ce->qp_user_context) == NULL) { - c2_mq_free(&cq->mq); - ce = c2_mq_consume(&cq->mq); - if (!ce) - return -EAGAIN; - } - - entry->status = c2_cqe_status_to_openib(c2_wr_get_result(ce)); - entry->wr_id = ce->hdr.context; - entry->qp = &qp->ibqp; - entry->wc_flags = 0; - entry->slid = 0; - entry->sl = 0; - entry->src_qp = 0; - entry->dlid_path_bits = 0; - entry->pkey_index = 0; - - switch (c2_wr_get_id(ce)) { - case C2_WR_TYPE_SEND: - entry->opcode = IB_WC_SEND; - break; - case C2_WR_TYPE_RDMA_WRITE: - entry->opcode = IB_WC_RDMA_WRITE; - break; - case C2_WR_TYPE_RDMA_READ: - entry->opcode = IB_WC_RDMA_READ; - break; - case C2_WR_TYPE_BIND_MW: - entry->opcode = IB_WC_BIND_MW; - break; - case C2_WR_TYPE_RECV: - entry->byte_len = be32_to_cpu(ce->bytes_rcvd); - entry->opcode = IB_WC_RECV; - is_recv = 1; - break; - default: - break; - } - - /* consume the WQEs */ - if (is_recv) - c2_mq_lconsume(&qp->rq_mq, 1); - else - c2_mq_lconsume(&qp->sq_mq, - be32_to_cpu(c2_wr_get_wqe_count(ce)) + 1); - - /* free the message */ - c2_mq_free(&cq->mq); - - return 0; -} - -int c2_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry) -{ - struct c2_dev *c2dev = to_c2dev(ibcq->device); - struct c2_cq *cq = to_c2cq(ibcq); - unsigned long flags; - int npolled, err; - - spin_lock_irqsave(&cq->lock, flags); - - for (npolled = 0; npolled < num_entries; ++npolled) { - - err = c2_poll_one(c2dev, cq, entry + npolled); - if (err) - break; - } - - spin_unlock_irqrestore(&cq->lock, flags); - - return npolled; -} - -int c2_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags notify_flags) -{ - struct c2_mq_shared __iomem *shared; - struct c2_cq *cq; - unsigned long flags; - int ret = 0; - - cq = to_c2cq(ibcq); - shared = cq->mq.peer; - - if ((notify_flags & IB_CQ_SOLICITED_MASK) == IB_CQ_NEXT_COMP) - writeb(C2_CQ_NOTIFICATION_TYPE_NEXT, &shared->notification_type); - else if ((notify_flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED) - writeb(C2_CQ_NOTIFICATION_TYPE_NEXT_SE, &shared->notification_type); - else - return -EINVAL; - - writeb(CQ_WAIT_FOR_DMA | CQ_ARMED, &shared->armed); - - /* - * Now read back shared->armed to make the PCI - * write synchronous. This is necessary for - * correct cq notification semantics. - */ - readb(&shared->armed); - - if (notify_flags & IB_CQ_REPORT_MISSED_EVENTS) { - spin_lock_irqsave(&cq->lock, flags); - ret = !c2_mq_empty(&cq->mq); - spin_unlock_irqrestore(&cq->lock, flags); - } - - return ret; -} - -static void c2_free_cq_buf(struct c2_dev *c2dev, struct c2_mq *mq) -{ - dma_free_coherent(&c2dev->pcidev->dev, mq->q_size * mq->msg_size, - mq->msg_pool.host, dma_unmap_addr(mq, mapping)); -} - -static int c2_alloc_cq_buf(struct c2_dev *c2dev, struct c2_mq *mq, - size_t q_size, size_t msg_size) -{ - u8 *pool_start; - - if (q_size > SIZE_MAX / msg_size) - return -EINVAL; - - pool_start = dma_alloc_coherent(&c2dev->pcidev->dev, q_size * msg_size, - &mq->host_dma, GFP_KERNEL); - if (!pool_start) - return -ENOMEM; - - c2_mq_rep_init(mq, - 0, /* index (currently unknown) */ - q_size, - msg_size, - pool_start, - NULL, /* peer (currently unknown) */ - C2_MQ_HOST_TARGET); - - dma_unmap_addr_set(mq, mapping, mq->host_dma); - - return 0; -} - -int c2_init_cq(struct c2_dev *c2dev, int entries, - struct c2_ucontext *ctx, struct c2_cq *cq) -{ - struct c2wr_cq_create_req wr; - struct c2wr_cq_create_rep *reply; - unsigned long peer_pa; - struct c2_vq_req *vq_req; - int err; - - might_sleep(); - - cq->ibcq.cqe = entries - 1; - cq->is_kernel = !ctx; - - /* Allocate a shared pointer */ - cq->mq.shared = c2_alloc_mqsp(c2dev, c2dev->kern_mqsp_pool, - &cq->mq.shared_dma, GFP_KERNEL); - if (!cq->mq.shared) - return -ENOMEM; - - /* Allocate pages for the message pool */ - err = c2_alloc_cq_buf(c2dev, &cq->mq, entries + 1, C2_CQ_MSG_SIZE); - if (err) - goto bail0; - - vq_req = vq_req_alloc(c2dev); - if (!vq_req) { - err = -ENOMEM; - goto bail1; - } - - memset(&wr, 0, sizeof(wr)); - c2_wr_set_id(&wr, CCWR_CQ_CREATE); - wr.hdr.context = (unsigned long) vq_req; - wr.rnic_handle = c2dev->adapter_handle; - wr.msg_size = cpu_to_be32(cq->mq.msg_size); - wr.depth = cpu_to_be32(cq->mq.q_size); - wr.shared_ht = cpu_to_be64(cq->mq.shared_dma); - wr.msg_pool = cpu_to_be64(cq->mq.host_dma); - wr.user_context = (u64) (unsigned long) (cq); - - vq_req_get(c2dev, vq_req); - - err = vq_send_wr(c2dev, (union c2wr *) & wr); - if (err) { - vq_req_put(c2dev, vq_req); - goto bail2; - } - - err = vq_wait_for_reply(c2dev, vq_req); - if (err) - goto bail2; - - reply = (struct c2wr_cq_create_rep *) (unsigned long) (vq_req->reply_msg); - if (!reply) { - err = -ENOMEM; - goto bail2; - } - - if ((err = c2_errno(reply)) != 0) - goto bail3; - - cq->adapter_handle = reply->cq_handle; - cq->mq.index = be32_to_cpu(reply->mq_index); - - peer_pa = c2dev->pa + be32_to_cpu(reply->adapter_shared); - cq->mq.peer = ioremap_nocache(peer_pa, PAGE_SIZE); - if (!cq->mq.peer) { - err = -ENOMEM; - goto bail3; - } - - vq_repbuf_free(c2dev, reply); - vq_req_free(c2dev, vq_req); - - spin_lock_init(&cq->lock); - atomic_set(&cq->refcount, 1); - init_waitqueue_head(&cq->wait); - - /* - * Use the MQ index allocated by the adapter to - * store the CQ in the qptr_array - */ - cq->cqn = cq->mq.index; - c2dev->qptr_array[cq->cqn] = cq; - - return 0; - - bail3: - vq_repbuf_free(c2dev, reply); - bail2: - vq_req_free(c2dev, vq_req); - bail1: - c2_free_cq_buf(c2dev, &cq->mq); - bail0: - c2_free_mqsp(cq->mq.shared); - - return err; -} - -void c2_free_cq(struct c2_dev *c2dev, struct c2_cq *cq) -{ - int err; - struct c2_vq_req *vq_req; - struct c2wr_cq_destroy_req wr; - struct c2wr_cq_destroy_rep *reply; - - might_sleep(); - - /* Clear CQ from the qptr array */ - spin_lock_irq(&c2dev->lock); - c2dev->qptr_array[cq->mq.index] = NULL; - atomic_dec(&cq->refcount); - spin_unlock_irq(&c2dev->lock); - - wait_event(cq->wait, !atomic_read(&cq->refcount)); - - vq_req = vq_req_alloc(c2dev); - if (!vq_req) { - goto bail0; - } - - memset(&wr, 0, sizeof(wr)); - c2_wr_set_id(&wr, CCWR_CQ_DESTROY); - wr.hdr.context = (unsigned long) vq_req; - wr.rnic_handle = c2dev->adapter_handle; - wr.cq_handle = cq->adapter_handle; - - vq_req_get(c2dev, vq_req); - - err = vq_send_wr(c2dev, (union c2wr *) & wr); - if (err) { - vq_req_put(c2dev, vq_req); - goto bail1; - } - - err = vq_wait_for_reply(c2dev, vq_req); - if (err) - goto bail1; - - reply = (struct c2wr_cq_destroy_rep *) (unsigned long) (vq_req->reply_msg); - if (reply) - vq_repbuf_free(c2dev, reply); - bail1: - vq_req_free(c2dev, vq_req); - bail0: - if (cq->is_kernel) { - c2_free_cq_buf(c2dev, &cq->mq); - } - - return; -} diff --git a/kernel/drivers/infiniband/hw/amso1100/c2_intr.c b/kernel/drivers/infiniband/hw/amso1100/c2_intr.c deleted file mode 100644 index 3a17d9b36..000000000 --- a/kernel/drivers/infiniband/hw/amso1100/c2_intr.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright (c) 2005 Ammasso, Inc. All rights reserved. - * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include "c2.h" -#include <rdma/iw_cm.h> -#include "c2_vq.h" - -static void handle_mq(struct c2_dev *c2dev, u32 index); -static void handle_vq(struct c2_dev *c2dev, u32 mq_index); - -/* - * Handle RNIC interrupts - */ -void c2_rnic_interrupt(struct c2_dev *c2dev) -{ - unsigned int mq_index; - - while (c2dev->hints_read != be16_to_cpu(*c2dev->hint_count)) { - mq_index = readl(c2dev->regs + PCI_BAR0_HOST_HINT); - if (mq_index & 0x80000000) { - break; - } - - c2dev->hints_read++; - handle_mq(c2dev, mq_index); - } - -} - -/* - * Top level MQ handler - */ -static void handle_mq(struct c2_dev *c2dev, u32 mq_index) -{ - if (c2dev->qptr_array[mq_index] == NULL) { - pr_debug("handle_mq: stray activity for mq_index=%d\n", - mq_index); - return; - } - - switch (mq_index) { - case (0): - /* - * An index of 0 in the activity queue - * indicates the req vq now has messages - * available... - * - * Wake up any waiters waiting on req VQ - * message availability. - */ - wake_up(&c2dev->req_vq_wo); - break; - case (1): - handle_vq(c2dev, mq_index); - break; - case (2): - /* We have to purge the VQ in case there are pending - * accept reply requests that would result in the - * generation of an ESTABLISHED event. If we don't - * generate these first, a CLOSE event could end up - * being delivered before the ESTABLISHED event. - */ - handle_vq(c2dev, 1); - - c2_ae_event(c2dev, mq_index); - break; - default: - /* There is no event synchronization between CQ events - * and AE or CM events. In fact, CQE could be - * delivered for all of the I/O up to and including the - * FLUSH for a peer disconenct prior to the ESTABLISHED - * event being delivered to the app. The reason for this - * is that CM events are delivered on a thread, while AE - * and CM events are delivered on interrupt context. - */ - c2_cq_event(c2dev, mq_index); - break; - } - - return; -} - -/* - * Handles verbs WR replies. - */ -static void handle_vq(struct c2_dev *c2dev, u32 mq_index) -{ - void *adapter_msg, *reply_msg; - struct c2wr_hdr *host_msg; - struct c2wr_hdr tmp; - struct c2_mq *reply_vq; - struct c2_vq_req *req; - struct iw_cm_event cm_event; - int err; - - reply_vq = (struct c2_mq *) c2dev->qptr_array[mq_index]; - - /* - * get next msg from mq_index into adapter_msg. - * don't free it yet. - */ - adapter_msg = c2_mq_consume(reply_vq); - if (adapter_msg == NULL) { - return; - } - - host_msg = vq_repbuf_alloc(c2dev); - - /* - * If we can't get a host buffer, then we'll still - * wakeup the waiter, we just won't give him the msg. - * It is assumed the waiter will deal with this... - */ - if (!host_msg) { - pr_debug("handle_vq: no repbufs!\n"); - - /* - * just copy the WR header into a local variable. - * this allows us to still demux on the context - */ - host_msg = &tmp; - memcpy(host_msg, adapter_msg, sizeof(tmp)); - reply_msg = NULL; - } else { - memcpy(host_msg, adapter_msg, reply_vq->msg_size); - reply_msg = host_msg; - } - - /* - * consume the msg from the MQ - */ - c2_mq_free(reply_vq); - - /* - * wakeup the waiter. - */ - req = (struct c2_vq_req *) (unsigned long) host_msg->context; - if (req == NULL) { - /* - * We should never get here, as the adapter should - * never send us a reply that we're not expecting. - */ - if (reply_msg != NULL) - vq_repbuf_free(c2dev, host_msg); - pr_debug("handle_vq: UNEXPECTEDLY got NULL req\n"); - return; - } - - if (reply_msg) - err = c2_errno(reply_msg); - else - err = -ENOMEM; - - if (!err) switch (req->event) { - case IW_CM_EVENT_ESTABLISHED: - c2_set_qp_state(req->qp, - C2_QP_STATE_RTS); - /* - * Until ird/ord negotiation via MPAv2 support is added, send - * max supported values - */ - cm_event.ird = cm_event.ord = 128; - case IW_CM_EVENT_CLOSE: - - /* - * Move the QP to RTS if this is - * the established event - */ - cm_event.event = req->event; - cm_event.status = 0; - cm_event.local_addr = req->cm_id->local_addr; - cm_event.remote_addr = req->cm_id->remote_addr; - cm_event.private_data = NULL; - cm_event.private_data_len = 0; - req->cm_id->event_handler(req->cm_id, &cm_event); - break; - default: - break; - } - - req->reply_msg = (u64) (unsigned long) (reply_msg); - atomic_set(&req->reply_ready, 1); - wake_up(&req->wait_object); - - /* - * If the request was cancelled, then this put will - * free the vq_req memory...and reply_msg!!! - */ - vq_req_put(c2dev, req); -} diff --git a/kernel/drivers/infiniband/hw/amso1100/c2_mm.c b/kernel/drivers/infiniband/hw/amso1100/c2_mm.c deleted file mode 100644 index 119c4f3d9..000000000 --- a/kernel/drivers/infiniband/hw/amso1100/c2_mm.c +++ /dev/null @@ -1,377 +0,0 @@ -/* - * Copyright (c) 2005 Ammasso, Inc. All rights reserved. - * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include <linux/slab.h> - -#include "c2.h" -#include "c2_vq.h" - -#define PBL_VIRT 1 -#define PBL_PHYS 2 - -/* - * Send all the PBL messages to convey the remainder of the PBL - * Wait for the adapter's reply on the last one. - * This is indicated by setting the MEM_PBL_COMPLETE in the flags. - * - * NOTE: vq_req is _not_ freed by this function. The VQ Host - * Reply buffer _is_ freed by this function. - */ -static int -send_pbl_messages(struct c2_dev *c2dev, __be32 stag_index, - unsigned long va, u32 pbl_depth, - struct c2_vq_req *vq_req, int pbl_type) -{ - u32 pbe_count; /* amt that fits in a PBL msg */ - u32 count; /* amt in this PBL MSG. */ - struct c2wr_nsmr_pbl_req *wr; /* PBL WR ptr */ - struct c2wr_nsmr_pbl_rep *reply; /* reply ptr */ - int err, pbl_virt, pbl_index, i; - - switch (pbl_type) { - case PBL_VIRT: - pbl_virt = 1; - break; - case PBL_PHYS: - pbl_virt = 0; - break; - default: - return -EINVAL; - break; - } - - pbe_count = (c2dev->req_vq.msg_size - - sizeof(struct c2wr_nsmr_pbl_req)) / sizeof(u64); - wr = kmalloc(c2dev->req_vq.msg_size, GFP_KERNEL); - if (!wr) { - return -ENOMEM; - } - c2_wr_set_id(wr, CCWR_NSMR_PBL); - - /* - * Only the last PBL message will generate a reply from the verbs, - * so we set the context to 0 indicating there is no kernel verbs - * handler blocked awaiting this reply. - */ - wr->hdr.context = 0; - wr->rnic_handle = c2dev->adapter_handle; - wr->stag_index = stag_index; /* already swapped */ - wr->flags = 0; - pbl_index = 0; - while (pbl_depth) { - count = min(pbe_count, pbl_depth); - wr->addrs_length = cpu_to_be32(count); - - /* - * If this is the last message, then reference the - * vq request struct cuz we're gonna wait for a reply. - * also make this PBL msg as the last one. - */ - if (count == pbl_depth) { - /* - * reference the request struct. dereferenced in the - * int handler. - */ - vq_req_get(c2dev, vq_req); - wr->flags = cpu_to_be32(MEM_PBL_COMPLETE); - - /* - * This is the last PBL message. - * Set the context to our VQ Request Object so we can - * wait for the reply. - */ - wr->hdr.context = (unsigned long) vq_req; - } - - /* - * If pbl_virt is set then va is a virtual address - * that describes a virtually contiguous memory - * allocation. The wr needs the start of each virtual page - * to be converted to the corresponding physical address - * of the page. If pbl_virt is not set then va is an array - * of physical addresses and there is no conversion to do. - * Just fill in the wr with what is in the array. - */ - for (i = 0; i < count; i++) { - if (pbl_virt) { - va += PAGE_SIZE; - } else { - wr->paddrs[i] = - cpu_to_be64(((u64 *)va)[pbl_index + i]); - } - } - - /* - * Send WR to adapter - */ - err = vq_send_wr(c2dev, (union c2wr *) wr); - if (err) { - if (count <= pbe_count) { - vq_req_put(c2dev, vq_req); - } - goto bail0; - } - pbl_depth -= count; - pbl_index += count; - } - - /* - * Now wait for the reply... - */ - err = vq_wait_for_reply(c2dev, vq_req); - if (err) { - goto bail0; - } - - /* - * Process reply - */ - reply = (struct c2wr_nsmr_pbl_rep *) (unsigned long) vq_req->reply_msg; - if (!reply) { - err = -ENOMEM; - goto bail0; - } - - err = c2_errno(reply); - - vq_repbuf_free(c2dev, reply); - bail0: - kfree(wr); - return err; -} - -#define C2_PBL_MAX_DEPTH 131072 -int -c2_nsmr_register_phys_kern(struct c2_dev *c2dev, u64 *addr_list, - int page_size, int pbl_depth, u32 length, - u32 offset, u64 *va, enum c2_acf acf, - struct c2_mr *mr) -{ - struct c2_vq_req *vq_req; - struct c2wr_nsmr_register_req *wr; - struct c2wr_nsmr_register_rep *reply; - u16 flags; - int i, pbe_count, count; - int err; - - if (!va || !length || !addr_list || !pbl_depth) - return -EINTR; - - /* - * Verify PBL depth is within rnic max - */ - if (pbl_depth > C2_PBL_MAX_DEPTH) { - return -EINTR; - } - - /* - * allocate verbs request object - */ - vq_req = vq_req_alloc(c2dev); - if (!vq_req) - return -ENOMEM; - - wr = kmalloc(c2dev->req_vq.msg_size, GFP_KERNEL); - if (!wr) { - err = -ENOMEM; - goto bail0; - } - - /* - * build the WR - */ - c2_wr_set_id(wr, CCWR_NSMR_REGISTER); - wr->hdr.context = (unsigned long) vq_req; - wr->rnic_handle = c2dev->adapter_handle; - - flags = (acf | MEM_VA_BASED | MEM_REMOTE); - - /* - * compute how many pbes can fit in the message - */ - pbe_count = (c2dev->req_vq.msg_size - - sizeof(struct c2wr_nsmr_register_req)) / sizeof(u64); - - if (pbl_depth <= pbe_count) { - flags |= MEM_PBL_COMPLETE; - } - wr->flags = cpu_to_be16(flags); - wr->stag_key = 0; //stag_key; - wr->va = cpu_to_be64(*va); - wr->pd_id = mr->pd->pd_id; - wr->pbe_size = cpu_to_be32(page_size); - wr->length = cpu_to_be32(length); - wr->pbl_depth = cpu_to_be32(pbl_depth); - wr->fbo = cpu_to_be32(offset); - count = min(pbl_depth, pbe_count); - wr->addrs_length = cpu_to_be32(count); - - /* - * fill out the PBL for this message - */ - for (i = 0; i < count; i++) { - wr->paddrs[i] = cpu_to_be64(addr_list[i]); - } - - /* - * regerence the request struct - */ - vq_req_get(c2dev, vq_req); - - /* - * send the WR to the adapter - */ - err = vq_send_wr(c2dev, (union c2wr *) wr); - if (err) { - vq_req_put(c2dev, vq_req); - goto bail1; - } - - /* - * wait for reply from adapter - */ - err = vq_wait_for_reply(c2dev, vq_req); - if (err) { - goto bail1; - } - - /* - * process reply - */ - reply = - (struct c2wr_nsmr_register_rep *) (unsigned long) (vq_req->reply_msg); - if (!reply) { - err = -ENOMEM; - goto bail1; - } - if ((err = c2_errno(reply))) { - goto bail2; - } - //*p_pb_entries = be32_to_cpu(reply->pbl_depth); - mr->ibmr.lkey = mr->ibmr.rkey = be32_to_cpu(reply->stag_index); - vq_repbuf_free(c2dev, reply); - - /* - * if there are still more PBEs we need to send them to - * the adapter and wait for a reply on the final one. - * reuse vq_req for this purpose. - */ - pbl_depth -= count; - if (pbl_depth) { - - vq_req->reply_msg = (unsigned long) NULL; - atomic_set(&vq_req->reply_ready, 0); - err = send_pbl_messages(c2dev, - cpu_to_be32(mr->ibmr.lkey), - (unsigned long) &addr_list[i], - pbl_depth, vq_req, PBL_PHYS); - if (err) { - goto bail1; - } - } - - vq_req_free(c2dev, vq_req); - kfree(wr); - - return err; - - bail2: - vq_repbuf_free(c2dev, reply); - bail1: - kfree(wr); - bail0: - vq_req_free(c2dev, vq_req); - return err; -} - -int c2_stag_dealloc(struct c2_dev *c2dev, u32 stag_index) -{ - struct c2_vq_req *vq_req; /* verbs request object */ - struct c2wr_stag_dealloc_req wr; /* work request */ - struct c2wr_stag_dealloc_rep *reply; /* WR reply */ - int err; - - - /* - * allocate verbs request object - */ - vq_req = vq_req_alloc(c2dev); - if (!vq_req) { - return -ENOMEM; - } - - /* - * Build the WR - */ - c2_wr_set_id(&wr, CCWR_STAG_DEALLOC); - wr.hdr.context = (u64) (unsigned long) vq_req; - wr.rnic_handle = c2dev->adapter_handle; - wr.stag_index = cpu_to_be32(stag_index); - - /* - * reference the request struct. dereferenced in the int handler. - */ - vq_req_get(c2dev, vq_req); - - /* - * Send WR to adapter - */ - err = vq_send_wr(c2dev, (union c2wr *) & wr); - if (err) { - vq_req_put(c2dev, vq_req); - goto bail0; - } - - /* - * Wait for reply from adapter - */ - err = vq_wait_for_reply(c2dev, vq_req); - if (err) { - goto bail0; - } - - /* - * Process reply - */ - reply = (struct c2wr_stag_dealloc_rep *) (unsigned long) vq_req->reply_msg; - if (!reply) { - err = -ENOMEM; - goto bail0; - } - - err = c2_errno(reply); - - vq_repbuf_free(c2dev, reply); - bail0: - vq_req_free(c2dev, vq_req); - return err; -} diff --git a/kernel/drivers/infiniband/hw/amso1100/c2_mq.c b/kernel/drivers/infiniband/hw/amso1100/c2_mq.c deleted file mode 100644 index 0cddc49be..000000000 --- a/kernel/drivers/infiniband/hw/amso1100/c2_mq.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (c) 2005 Ammasso, Inc. All rights reserved. - * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include "c2.h" -#include "c2_mq.h" - -void *c2_mq_alloc(struct c2_mq *q) -{ - BUG_ON(q->magic != C2_MQ_MAGIC); - BUG_ON(q->type != C2_MQ_ADAPTER_TARGET); - - if (c2_mq_full(q)) { - return NULL; - } else { -#ifdef DEBUG - struct c2wr_hdr *m = - (struct c2wr_hdr *) (q->msg_pool.host + q->priv * q->msg_size); -#ifdef CCMSGMAGIC - BUG_ON(m->magic != be32_to_cpu(~CCWR_MAGIC)); - m->magic = cpu_to_be32(CCWR_MAGIC); -#endif - return m; -#else - return q->msg_pool.host + q->priv * q->msg_size; -#endif - } -} - -void c2_mq_produce(struct c2_mq *q) -{ - BUG_ON(q->magic != C2_MQ_MAGIC); - BUG_ON(q->type != C2_MQ_ADAPTER_TARGET); - - if (!c2_mq_full(q)) { - q->priv = (q->priv + 1) % q->q_size; - q->hint_count++; - /* Update peer's offset. */ - __raw_writew((__force u16) cpu_to_be16(q->priv), &q->peer->shared); - } -} - -void *c2_mq_consume(struct c2_mq *q) -{ - BUG_ON(q->magic != C2_MQ_MAGIC); - BUG_ON(q->type != C2_MQ_HOST_TARGET); - - if (c2_mq_empty(q)) { - return NULL; - } else { -#ifdef DEBUG - struct c2wr_hdr *m = (struct c2wr_hdr *) - (q->msg_pool.host + q->priv * q->msg_size); -#ifdef CCMSGMAGIC - BUG_ON(m->magic != be32_to_cpu(CCWR_MAGIC)); -#endif - return m; -#else - return q->msg_pool.host + q->priv * q->msg_size; -#endif - } -} - -void c2_mq_free(struct c2_mq *q) -{ - BUG_ON(q->magic != C2_MQ_MAGIC); - BUG_ON(q->type != C2_MQ_HOST_TARGET); - - if (!c2_mq_empty(q)) { - -#ifdef CCMSGMAGIC - { - struct c2wr_hdr __iomem *m = (struct c2wr_hdr __iomem *) - (q->msg_pool.adapter + q->priv * q->msg_size); - __raw_writel(cpu_to_be32(~CCWR_MAGIC), &m->magic); - } -#endif - q->priv = (q->priv + 1) % q->q_size; - /* Update peer's offset. */ - __raw_writew((__force u16) cpu_to_be16(q->priv), &q->peer->shared); - } -} - - -void c2_mq_lconsume(struct c2_mq *q, u32 wqe_count) -{ - BUG_ON(q->magic != C2_MQ_MAGIC); - BUG_ON(q->type != C2_MQ_ADAPTER_TARGET); - - while (wqe_count--) { - BUG_ON(c2_mq_empty(q)); - *q->shared = cpu_to_be16((be16_to_cpu(*q->shared)+1) % q->q_size); - } -} - -#if 0 -u32 c2_mq_count(struct c2_mq *q) -{ - s32 count; - - if (q->type == C2_MQ_HOST_TARGET) - count = be16_to_cpu(*q->shared) - q->priv; - else - count = q->priv - be16_to_cpu(*q->shared); - - if (count < 0) - count += q->q_size; - - return (u32) count; -} -#endif /* 0 */ - -void c2_mq_req_init(struct c2_mq *q, u32 index, u32 q_size, u32 msg_size, - u8 __iomem *pool_start, u16 __iomem *peer, u32 type) -{ - BUG_ON(!q->shared); - - /* This code assumes the byte swapping has already been done! */ - q->index = index; - q->q_size = q_size; - q->msg_size = msg_size; - q->msg_pool.adapter = pool_start; - q->peer = (struct c2_mq_shared __iomem *) peer; - q->magic = C2_MQ_MAGIC; - q->type = type; - q->priv = 0; - q->hint_count = 0; - return; -} -void c2_mq_rep_init(struct c2_mq *q, u32 index, u32 q_size, u32 msg_size, - u8 *pool_start, u16 __iomem *peer, u32 type) -{ - BUG_ON(!q->shared); - - /* This code assumes the byte swapping has already been done! */ - q->index = index; - q->q_size = q_size; - q->msg_size = msg_size; - q->msg_pool.host = pool_start; - q->peer = (struct c2_mq_shared __iomem *) peer; - q->magic = C2_MQ_MAGIC; - q->type = type; - q->priv = 0; - q->hint_count = 0; - return; -} diff --git a/kernel/drivers/infiniband/hw/amso1100/c2_mq.h b/kernel/drivers/infiniband/hw/amso1100/c2_mq.h deleted file mode 100644 index fc1b9a7ce..000000000 --- a/kernel/drivers/infiniband/hw/amso1100/c2_mq.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2005 Ammasso, Inc. All rights reserved. - * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef _C2_MQ_H_ -#define _C2_MQ_H_ -#include <linux/kernel.h> -#include <linux/dma-mapping.h> -#include "c2_wr.h" - -enum c2_shared_regs { - - C2_SHARED_ARMED = 0x10, - C2_SHARED_NOTIFY = 0x18, - C2_SHARED_SHARED = 0x40, -}; - -struct c2_mq_shared { - u16 unused1; - u8 armed; - u8 notification_type; - u32 unused2; - u16 shared; - /* Pad to 64 bytes. */ - u8 pad[64 - sizeof(u16) - 2 * sizeof(u8) - sizeof(u32) - sizeof(u16)]; -}; - -enum c2_mq_type { - C2_MQ_HOST_TARGET = 1, - C2_MQ_ADAPTER_TARGET = 2, -}; - -/* - * c2_mq_t is for kernel-mode MQs like the VQs Cand the AEQ. - * c2_user_mq_t (which is the same format) is for user-mode MQs... - */ -#define C2_MQ_MAGIC 0x4d512020 /* 'MQ ' */ -struct c2_mq { - u32 magic; - union { - u8 *host; - u8 __iomem *adapter; - } msg_pool; - dma_addr_t host_dma; - DEFINE_DMA_UNMAP_ADDR(mapping); - u16 hint_count; - u16 priv; - struct c2_mq_shared __iomem *peer; - __be16 *shared; - dma_addr_t shared_dma; - u32 q_size; - u32 msg_size; - u32 index; - enum c2_mq_type type; -}; - -static __inline__ int c2_mq_empty(struct c2_mq *q) -{ - return q->priv == be16_to_cpu(*q->shared); -} - -static __inline__ int c2_mq_full(struct c2_mq *q) -{ - return q->priv == (be16_to_cpu(*q->shared) + q->q_size - 1) % q->q_size; -} - -extern void c2_mq_lconsume(struct c2_mq *q, u32 wqe_count); -extern void *c2_mq_alloc(struct c2_mq *q); -extern void c2_mq_produce(struct c2_mq *q); -extern void *c2_mq_consume(struct c2_mq *q); -extern void c2_mq_free(struct c2_mq *q); -extern void c2_mq_req_init(struct c2_mq *q, u32 index, u32 q_size, u32 msg_size, - u8 __iomem *pool_start, u16 __iomem *peer, u32 type); -extern void c2_mq_rep_init(struct c2_mq *q, u32 index, u32 q_size, u32 msg_size, - u8 *pool_start, u16 __iomem *peer, u32 type); - -#endif /* _C2_MQ_H_ */ diff --git a/kernel/drivers/infiniband/hw/amso1100/c2_pd.c b/kernel/drivers/infiniband/hw/amso1100/c2_pd.c deleted file mode 100644 index f3e81dc35..000000000 --- a/kernel/drivers/infiniband/hw/amso1100/c2_pd.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2004 Topspin Communications. All rights reserved. - * Copyright (c) 2005 Cisco Systems. All rights reserved. - * Copyright (c) 2005 Mellanox Technologies. All rights reserved. - * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/errno.h> - -#include "c2.h" -#include "c2_provider.h" - -int c2_pd_alloc(struct c2_dev *c2dev, int privileged, struct c2_pd *pd) -{ - u32 obj; - int ret = 0; - - spin_lock(&c2dev->pd_table.lock); - obj = find_next_zero_bit(c2dev->pd_table.table, c2dev->pd_table.max, - c2dev->pd_table.last); - if (obj >= c2dev->pd_table.max) - obj = find_first_zero_bit(c2dev->pd_table.table, - c2dev->pd_table.max); - if (obj < c2dev->pd_table.max) { - pd->pd_id = obj; - __set_bit(obj, c2dev->pd_table.table); - c2dev->pd_table.last = obj+1; - if (c2dev->pd_table.last >= c2dev->pd_table.max) - c2dev->pd_table.last = 0; - } else - ret = -ENOMEM; - spin_unlock(&c2dev->pd_table.lock); - return ret; -} - -void c2_pd_free(struct c2_dev *c2dev, struct c2_pd *pd) -{ - spin_lock(&c2dev->pd_table.lock); - __clear_bit(pd->pd_id, c2dev->pd_table.table); - spin_unlock(&c2dev->pd_table.lock); -} - -int c2_init_pd_table(struct c2_dev *c2dev) -{ - - c2dev->pd_table.last = 0; - c2dev->pd_table.max = c2dev->props.max_pd; - spin_lock_init(&c2dev->pd_table.lock); - c2dev->pd_table.table = kmalloc(BITS_TO_LONGS(c2dev->props.max_pd) * - sizeof(long), GFP_KERNEL); - if (!c2dev->pd_table.table) - return -ENOMEM; - bitmap_zero(c2dev->pd_table.table, c2dev->props.max_pd); - return 0; -} - -void c2_cleanup_pd_table(struct c2_dev *c2dev) -{ - kfree(c2dev->pd_table.table); -} diff --git a/kernel/drivers/infiniband/hw/amso1100/c2_provider.c b/kernel/drivers/infiniband/hw/amso1100/c2_provider.c deleted file mode 100644 index bdf350781..000000000 --- a/kernel/drivers/infiniband/hw/amso1100/c2_provider.c +++ /dev/null @@ -1,882 +0,0 @@ -/* - * Copyright (c) 2005 Ammasso, Inc. All rights reserved. - * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/pci.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/inetdevice.h> -#include <linux/delay.h> -#include <linux/ethtool.h> -#include <linux/mii.h> -#include <linux/if_vlan.h> -#include <linux/crc32.h> -#include <linux/in.h> -#include <linux/ip.h> -#include <linux/tcp.h> -#include <linux/init.h> -#include <linux/dma-mapping.h> -#include <linux/if_arp.h> -#include <linux/vmalloc.h> -#include <linux/slab.h> - -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/byteorder.h> - -#include <rdma/ib_smi.h> -#include <rdma/ib_umem.h> -#include <rdma/ib_user_verbs.h> -#include "c2.h" -#include "c2_provider.h" -#include "c2_user.h" - -static int c2_query_device(struct ib_device *ibdev, - struct ib_device_attr *props) -{ - struct c2_dev *c2dev = to_c2dev(ibdev); - - pr_debug("%s:%u\n", __func__, __LINE__); - - *props = c2dev->props; - return 0; -} - -static int c2_query_port(struct ib_device *ibdev, - u8 port, struct ib_port_attr *props) -{ - pr_debug("%s:%u\n", __func__, __LINE__); - - props->max_mtu = IB_MTU_4096; - props->lid = 0; - props->lmc = 0; - props->sm_lid = 0; - props->sm_sl = 0; - props->state = IB_PORT_ACTIVE; - props->phys_state = 0; - props->port_cap_flags = - IB_PORT_CM_SUP | - IB_PORT_REINIT_SUP | - IB_PORT_VENDOR_CLASS_SUP | IB_PORT_BOOT_MGMT_SUP; - props->gid_tbl_len = 1; - props->pkey_tbl_len = 1; - props->qkey_viol_cntr = 0; - props->active_width = 1; - props->active_speed = IB_SPEED_SDR; - - return 0; -} - -static int c2_query_pkey(struct ib_device *ibdev, - u8 port, u16 index, u16 * pkey) -{ - pr_debug("%s:%u\n", __func__, __LINE__); - *pkey = 0; - return 0; -} - -static int c2_query_gid(struct ib_device *ibdev, u8 port, - int index, union ib_gid *gid) -{ - struct c2_dev *c2dev = to_c2dev(ibdev); - - pr_debug("%s:%u\n", __func__, __LINE__); - memset(&(gid->raw[0]), 0, sizeof(gid->raw)); - memcpy(&(gid->raw[0]), c2dev->pseudo_netdev->dev_addr, 6); - - return 0; -} - -/* Allocate the user context data structure. This keeps track - * of all objects associated with a particular user-mode client. - */ -static struct ib_ucontext *c2_alloc_ucontext(struct ib_device *ibdev, - struct ib_udata *udata) -{ - struct c2_ucontext *context; - - pr_debug("%s:%u\n", __func__, __LINE__); - context = kmalloc(sizeof(*context), GFP_KERNEL); - if (!context) - return ERR_PTR(-ENOMEM); - - return &context->ibucontext; -} - -static int c2_dealloc_ucontext(struct ib_ucontext *context) -{ - pr_debug("%s:%u\n", __func__, __LINE__); - kfree(context); - return 0; -} - -static int c2_mmap_uar(struct ib_ucontext *context, struct vm_area_struct *vma) -{ - pr_debug("%s:%u\n", __func__, __LINE__); - return -ENOSYS; -} - -static struct ib_pd *c2_alloc_pd(struct ib_device *ibdev, - struct ib_ucontext *context, - struct ib_udata *udata) -{ - struct c2_pd *pd; - int err; - - pr_debug("%s:%u\n", __func__, __LINE__); - - pd = kmalloc(sizeof(*pd), GFP_KERNEL); - if (!pd) - return ERR_PTR(-ENOMEM); - - err = c2_pd_alloc(to_c2dev(ibdev), !context, pd); - if (err) { - kfree(pd); - return ERR_PTR(err); - } - - if (context) { - if (ib_copy_to_udata(udata, &pd->pd_id, sizeof(__u32))) { - c2_pd_free(to_c2dev(ibdev), pd); - kfree(pd); - return ERR_PTR(-EFAULT); - } - } - - return &pd->ibpd; -} - -static int c2_dealloc_pd(struct ib_pd *pd) -{ - pr_debug("%s:%u\n", __func__, __LINE__); - c2_pd_free(to_c2dev(pd->device), to_c2pd(pd)); - kfree(pd); - - return 0; -} - -static struct ib_ah *c2_ah_create(struct ib_pd *pd, struct ib_ah_attr *ah_attr) -{ - pr_debug("%s:%u\n", __func__, __LINE__); - return ERR_PTR(-ENOSYS); -} - -static int c2_ah_destroy(struct ib_ah *ah) -{ - pr_debug("%s:%u\n", __func__, __LINE__); - return -ENOSYS; -} - -static void c2_add_ref(struct ib_qp *ibqp) -{ - struct c2_qp *qp; - BUG_ON(!ibqp); - qp = to_c2qp(ibqp); - atomic_inc(&qp->refcount); -} - -static void c2_rem_ref(struct ib_qp *ibqp) -{ - struct c2_qp *qp; - BUG_ON(!ibqp); - qp = to_c2qp(ibqp); - if (atomic_dec_and_test(&qp->refcount)) - wake_up(&qp->wait); -} - -struct ib_qp *c2_get_qp(struct ib_device *device, int qpn) -{ - struct c2_dev* c2dev = to_c2dev(device); - struct c2_qp *qp; - - qp = c2_find_qpn(c2dev, qpn); - pr_debug("%s Returning QP=%p for QPN=%d, device=%p, refcount=%d\n", - __func__, qp, qpn, device, - (qp?atomic_read(&qp->refcount):0)); - - return (qp?&qp->ibqp:NULL); -} - -static struct ib_qp *c2_create_qp(struct ib_pd *pd, - struct ib_qp_init_attr *init_attr, - struct ib_udata *udata) -{ - struct c2_qp *qp; - int err; - - pr_debug("%s:%u\n", __func__, __LINE__); - - if (init_attr->create_flags) - return ERR_PTR(-EINVAL); - - switch (init_attr->qp_type) { - case IB_QPT_RC: - qp = kzalloc(sizeof(*qp), GFP_KERNEL); - if (!qp) { - pr_debug("%s: Unable to allocate QP\n", __func__); - return ERR_PTR(-ENOMEM); - } - spin_lock_init(&qp->lock); - if (pd->uobject) { - /* userspace specific */ - } - - err = c2_alloc_qp(to_c2dev(pd->device), - to_c2pd(pd), init_attr, qp); - - if (err && pd->uobject) { - /* userspace specific */ - } - - break; - default: - pr_debug("%s: Invalid QP type: %d\n", __func__, - init_attr->qp_type); - return ERR_PTR(-EINVAL); - } - - if (err) { - kfree(qp); - return ERR_PTR(err); - } - - return &qp->ibqp; -} - -static int c2_destroy_qp(struct ib_qp *ib_qp) -{ - struct c2_qp *qp = to_c2qp(ib_qp); - - pr_debug("%s:%u qp=%p,qp->state=%d\n", - __func__, __LINE__, ib_qp, qp->state); - c2_free_qp(to_c2dev(ib_qp->device), qp); - kfree(qp); - return 0; -} - -static struct ib_cq *c2_create_cq(struct ib_device *ibdev, int entries, int vector, - struct ib_ucontext *context, - struct ib_udata *udata) -{ - struct c2_cq *cq; - int err; - - cq = kmalloc(sizeof(*cq), GFP_KERNEL); - if (!cq) { - pr_debug("%s: Unable to allocate CQ\n", __func__); - return ERR_PTR(-ENOMEM); - } - - err = c2_init_cq(to_c2dev(ibdev), entries, NULL, cq); - if (err) { - pr_debug("%s: error initializing CQ\n", __func__); - kfree(cq); - return ERR_PTR(err); - } - - return &cq->ibcq; -} - -static int c2_destroy_cq(struct ib_cq *ib_cq) -{ - struct c2_cq *cq = to_c2cq(ib_cq); - - pr_debug("%s:%u\n", __func__, __LINE__); - - c2_free_cq(to_c2dev(ib_cq->device), cq); - kfree(cq); - - return 0; -} - -static inline u32 c2_convert_access(int acc) -{ - return (acc & IB_ACCESS_REMOTE_WRITE ? C2_ACF_REMOTE_WRITE : 0) | - (acc & IB_ACCESS_REMOTE_READ ? C2_ACF_REMOTE_READ : 0) | - (acc & IB_ACCESS_LOCAL_WRITE ? C2_ACF_LOCAL_WRITE : 0) | - C2_ACF_LOCAL_READ | C2_ACF_WINDOW_BIND; -} - -static struct ib_mr *c2_reg_phys_mr(struct ib_pd *ib_pd, - struct ib_phys_buf *buffer_list, - int num_phys_buf, int acc, u64 * iova_start) -{ - struct c2_mr *mr; - u64 *page_list; - u32 total_len; - int err, i, j, k, page_shift, pbl_depth; - - pbl_depth = 0; - total_len = 0; - - page_shift = PAGE_SHIFT; - /* - * If there is only 1 buffer we assume this could - * be a map of all phy mem...use a 32k page_shift. - */ - if (num_phys_buf == 1) - page_shift += 3; - - for (i = 0; i < num_phys_buf; i++) { - - if (buffer_list[i].addr & ~PAGE_MASK) { - pr_debug("Unaligned Memory Buffer: 0x%x\n", - (unsigned int) buffer_list[i].addr); - return ERR_PTR(-EINVAL); - } - - if (!buffer_list[i].size) { - pr_debug("Invalid Buffer Size\n"); - return ERR_PTR(-EINVAL); - } - - total_len += buffer_list[i].size; - pbl_depth += ALIGN(buffer_list[i].size, - (1 << page_shift)) >> page_shift; - } - - page_list = vmalloc(sizeof(u64) * pbl_depth); - if (!page_list) { - pr_debug("couldn't vmalloc page_list of size %zd\n", - (sizeof(u64) * pbl_depth)); - return ERR_PTR(-ENOMEM); - } - - for (i = 0, j = 0; i < num_phys_buf; i++) { - - int naddrs; - - naddrs = ALIGN(buffer_list[i].size, - (1 << page_shift)) >> page_shift; - for (k = 0; k < naddrs; k++) - page_list[j++] = (buffer_list[i].addr + - (k << page_shift)); - } - - mr = kmalloc(sizeof(*mr), GFP_KERNEL); - if (!mr) { - vfree(page_list); - return ERR_PTR(-ENOMEM); - } - - mr->pd = to_c2pd(ib_pd); - mr->umem = NULL; - pr_debug("%s - page shift %d, pbl_depth %d, total_len %u, " - "*iova_start %llx, first pa %llx, last pa %llx\n", - __func__, page_shift, pbl_depth, total_len, - (unsigned long long) *iova_start, - (unsigned long long) page_list[0], - (unsigned long long) page_list[pbl_depth-1]); - err = c2_nsmr_register_phys_kern(to_c2dev(ib_pd->device), page_list, - (1 << page_shift), pbl_depth, - total_len, 0, iova_start, - c2_convert_access(acc), mr); - vfree(page_list); - if (err) { - kfree(mr); - return ERR_PTR(err); - } - - return &mr->ibmr; -} - -static struct ib_mr *c2_get_dma_mr(struct ib_pd *pd, int acc) -{ - struct ib_phys_buf bl; - u64 kva = 0; - - pr_debug("%s:%u\n", __func__, __LINE__); - - /* AMSO1100 limit */ - bl.size = 0xffffffff; - bl.addr = 0; - return c2_reg_phys_mr(pd, &bl, 1, acc, &kva); -} - -static struct ib_mr *c2_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, - u64 virt, int acc, struct ib_udata *udata) -{ - u64 *pages; - u64 kva = 0; - int shift, n, len; - int i, k, entry; - int err = 0; - struct scatterlist *sg; - struct c2_pd *c2pd = to_c2pd(pd); - struct c2_mr *c2mr; - - pr_debug("%s:%u\n", __func__, __LINE__); - - c2mr = kmalloc(sizeof(*c2mr), GFP_KERNEL); - if (!c2mr) - return ERR_PTR(-ENOMEM); - c2mr->pd = c2pd; - - c2mr->umem = ib_umem_get(pd->uobject->context, start, length, acc, 0); - if (IS_ERR(c2mr->umem)) { - err = PTR_ERR(c2mr->umem); - kfree(c2mr); - return ERR_PTR(err); - } - - shift = ffs(c2mr->umem->page_size) - 1; - n = c2mr->umem->nmap; - - pages = kmalloc(n * sizeof(u64), GFP_KERNEL); - if (!pages) { - err = -ENOMEM; - goto err; - } - - i = 0; - for_each_sg(c2mr->umem->sg_head.sgl, sg, c2mr->umem->nmap, entry) { - len = sg_dma_len(sg) >> shift; - for (k = 0; k < len; ++k) { - pages[i++] = - sg_dma_address(sg) + - (c2mr->umem->page_size * k); - } - } - - kva = virt; - err = c2_nsmr_register_phys_kern(to_c2dev(pd->device), - pages, - c2mr->umem->page_size, - i, - length, - ib_umem_offset(c2mr->umem), - &kva, - c2_convert_access(acc), - c2mr); - kfree(pages); - if (err) - goto err; - return &c2mr->ibmr; - -err: - ib_umem_release(c2mr->umem); - kfree(c2mr); - return ERR_PTR(err); -} - -static int c2_dereg_mr(struct ib_mr *ib_mr) -{ - struct c2_mr *mr = to_c2mr(ib_mr); - int err; - - pr_debug("%s:%u\n", __func__, __LINE__); - - err = c2_stag_dealloc(to_c2dev(ib_mr->device), ib_mr->lkey); - if (err) - pr_debug("c2_stag_dealloc failed: %d\n", err); - else { - if (mr->umem) - ib_umem_release(mr->umem); - kfree(mr); - } - - return err; -} - -static ssize_t show_rev(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct c2_dev *c2dev = container_of(dev, struct c2_dev, ibdev.dev); - pr_debug("%s:%u\n", __func__, __LINE__); - return sprintf(buf, "%x\n", c2dev->props.hw_ver); -} - -static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct c2_dev *c2dev = container_of(dev, struct c2_dev, ibdev.dev); - pr_debug("%s:%u\n", __func__, __LINE__); - return sprintf(buf, "%x.%x.%x\n", - (int) (c2dev->props.fw_ver >> 32), - (int) (c2dev->props.fw_ver >> 16) & 0xffff, - (int) (c2dev->props.fw_ver & 0xffff)); -} - -static ssize_t show_hca(struct device *dev, struct device_attribute *attr, - char *buf) -{ - pr_debug("%s:%u\n", __func__, __LINE__); - return sprintf(buf, "AMSO1100\n"); -} - -static ssize_t show_board(struct device *dev, struct device_attribute *attr, - char *buf) -{ - pr_debug("%s:%u\n", __func__, __LINE__); - return sprintf(buf, "%.*s\n", 32, "AMSO1100 Board ID"); -} - -static DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL); -static DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL); -static DEVICE_ATTR(hca_type, S_IRUGO, show_hca, NULL); -static DEVICE_ATTR(board_id, S_IRUGO, show_board, NULL); - -static struct device_attribute *c2_dev_attributes[] = { - &dev_attr_hw_rev, - &dev_attr_fw_ver, - &dev_attr_hca_type, - &dev_attr_board_id -}; - -static int c2_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, - int attr_mask, struct ib_udata *udata) -{ - int err; - - err = - c2_qp_modify(to_c2dev(ibqp->device), to_c2qp(ibqp), attr, - attr_mask); - - return err; -} - -static int c2_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) -{ - pr_debug("%s:%u\n", __func__, __LINE__); - return -ENOSYS; -} - -static int c2_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) -{ - pr_debug("%s:%u\n", __func__, __LINE__); - return -ENOSYS; -} - -static int c2_process_mad(struct ib_device *ibdev, - int mad_flags, - u8 port_num, - struct ib_wc *in_wc, - struct ib_grh *in_grh, - struct ib_mad *in_mad, struct ib_mad *out_mad) -{ - pr_debug("%s:%u\n", __func__, __LINE__); - return -ENOSYS; -} - -static int c2_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param) -{ - pr_debug("%s:%u\n", __func__, __LINE__); - - /* Request a connection */ - return c2_llp_connect(cm_id, iw_param); -} - -static int c2_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *iw_param) -{ - pr_debug("%s:%u\n", __func__, __LINE__); - - /* Accept the new connection */ - return c2_llp_accept(cm_id, iw_param); -} - -static int c2_reject(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len) -{ - int err; - - pr_debug("%s:%u\n", __func__, __LINE__); - - err = c2_llp_reject(cm_id, pdata, pdata_len); - return err; -} - -static int c2_service_create(struct iw_cm_id *cm_id, int backlog) -{ - int err; - - pr_debug("%s:%u\n", __func__, __LINE__); - err = c2_llp_service_create(cm_id, backlog); - pr_debug("%s:%u err=%d\n", - __func__, __LINE__, - err); - return err; -} - -static int c2_service_destroy(struct iw_cm_id *cm_id) -{ - int err; - pr_debug("%s:%u\n", __func__, __LINE__); - - err = c2_llp_service_destroy(cm_id); - - return err; -} - -static int c2_pseudo_up(struct net_device *netdev) -{ - struct in_device *ind; - struct c2_dev *c2dev = netdev->ml_priv; - - ind = in_dev_get(netdev); - if (!ind) - return 0; - - pr_debug("adding...\n"); - for_ifa(ind) { -#ifdef DEBUG - u8 *ip = (u8 *) & ifa->ifa_address; - - pr_debug("%s: %d.%d.%d.%d\n", - ifa->ifa_label, ip[0], ip[1], ip[2], ip[3]); -#endif - c2_add_addr(c2dev, ifa->ifa_address, ifa->ifa_mask); - } - endfor_ifa(ind); - in_dev_put(ind); - - return 0; -} - -static int c2_pseudo_down(struct net_device *netdev) -{ - struct in_device *ind; - struct c2_dev *c2dev = netdev->ml_priv; - - ind = in_dev_get(netdev); - if (!ind) - return 0; - - pr_debug("deleting...\n"); - for_ifa(ind) { -#ifdef DEBUG - u8 *ip = (u8 *) & ifa->ifa_address; - - pr_debug("%s: %d.%d.%d.%d\n", - ifa->ifa_label, ip[0], ip[1], ip[2], ip[3]); -#endif - c2_del_addr(c2dev, ifa->ifa_address, ifa->ifa_mask); - } - endfor_ifa(ind); - in_dev_put(ind); - - return 0; -} - -static int c2_pseudo_xmit_frame(struct sk_buff *skb, struct net_device *netdev) -{ - kfree_skb(skb); - return NETDEV_TX_OK; -} - -static int c2_pseudo_change_mtu(struct net_device *netdev, int new_mtu) -{ - if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) - return -EINVAL; - - netdev->mtu = new_mtu; - - /* TODO: Tell rnic about new rmda interface mtu */ - return 0; -} - -static const struct net_device_ops c2_pseudo_netdev_ops = { - .ndo_open = c2_pseudo_up, - .ndo_stop = c2_pseudo_down, - .ndo_start_xmit = c2_pseudo_xmit_frame, - .ndo_change_mtu = c2_pseudo_change_mtu, - .ndo_validate_addr = eth_validate_addr, -}; - -static void setup(struct net_device *netdev) -{ - netdev->netdev_ops = &c2_pseudo_netdev_ops; - - netdev->watchdog_timeo = 0; - netdev->type = ARPHRD_ETHER; - netdev->mtu = 1500; - netdev->hard_header_len = ETH_HLEN; - netdev->addr_len = ETH_ALEN; - netdev->tx_queue_len = 0; - netdev->flags |= IFF_NOARP; -} - -static struct net_device *c2_pseudo_netdev_init(struct c2_dev *c2dev) -{ - char name[IFNAMSIZ]; - struct net_device *netdev; - - /* change ethxxx to iwxxx */ - strcpy(name, "iw"); - strcat(name, &c2dev->netdev->name[3]); - netdev = alloc_netdev(0, name, NET_NAME_UNKNOWN, setup); - if (!netdev) { - printk(KERN_ERR PFX "%s - etherdev alloc failed", - __func__); - return NULL; - } - - netdev->ml_priv = c2dev; - - SET_NETDEV_DEV(netdev, &c2dev->pcidev->dev); - - memcpy_fromio(netdev->dev_addr, c2dev->kva + C2_REGS_RDMA_ENADDR, 6); - - /* Print out the MAC address */ - pr_debug("%s: MAC %pM\n", netdev->name, netdev->dev_addr); - -#if 0 - /* Disable network packets */ - netif_stop_queue(netdev); -#endif - return netdev; -} - -int c2_register_device(struct c2_dev *dev) -{ - int ret = -ENOMEM; - int i; - - /* Register pseudo network device */ - dev->pseudo_netdev = c2_pseudo_netdev_init(dev); - if (!dev->pseudo_netdev) - goto out; - - ret = register_netdev(dev->pseudo_netdev); - if (ret) - goto out_free_netdev; - - pr_debug("%s:%u\n", __func__, __LINE__); - strlcpy(dev->ibdev.name, "amso%d", IB_DEVICE_NAME_MAX); - dev->ibdev.owner = THIS_MODULE; - dev->ibdev.uverbs_cmd_mask = - (1ull << IB_USER_VERBS_CMD_GET_CONTEXT) | - (1ull << IB_USER_VERBS_CMD_QUERY_DEVICE) | - (1ull << IB_USER_VERBS_CMD_QUERY_PORT) | - (1ull << IB_USER_VERBS_CMD_ALLOC_PD) | - (1ull << IB_USER_VERBS_CMD_DEALLOC_PD) | - (1ull << IB_USER_VERBS_CMD_REG_MR) | - (1ull << IB_USER_VERBS_CMD_DEREG_MR) | - (1ull << IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL) | - (1ull << IB_USER_VERBS_CMD_CREATE_CQ) | - (1ull << IB_USER_VERBS_CMD_DESTROY_CQ) | - (1ull << IB_USER_VERBS_CMD_REQ_NOTIFY_CQ) | - (1ull << IB_USER_VERBS_CMD_CREATE_QP) | - (1ull << IB_USER_VERBS_CMD_MODIFY_QP) | - (1ull << IB_USER_VERBS_CMD_POLL_CQ) | - (1ull << IB_USER_VERBS_CMD_DESTROY_QP) | - (1ull << IB_USER_VERBS_CMD_POST_SEND) | - (1ull << IB_USER_VERBS_CMD_POST_RECV); - - dev->ibdev.node_type = RDMA_NODE_RNIC; - memset(&dev->ibdev.node_guid, 0, sizeof(dev->ibdev.node_guid)); - memcpy(&dev->ibdev.node_guid, dev->pseudo_netdev->dev_addr, 6); - dev->ibdev.phys_port_cnt = 1; - dev->ibdev.num_comp_vectors = 1; - dev->ibdev.dma_device = &dev->pcidev->dev; - dev->ibdev.query_device = c2_query_device; - dev->ibdev.query_port = c2_query_port; - dev->ibdev.query_pkey = c2_query_pkey; - dev->ibdev.query_gid = c2_query_gid; - dev->ibdev.alloc_ucontext = c2_alloc_ucontext; - dev->ibdev.dealloc_ucontext = c2_dealloc_ucontext; - dev->ibdev.mmap = c2_mmap_uar; - dev->ibdev.alloc_pd = c2_alloc_pd; - dev->ibdev.dealloc_pd = c2_dealloc_pd; - dev->ibdev.create_ah = c2_ah_create; - dev->ibdev.destroy_ah = c2_ah_destroy; - dev->ibdev.create_qp = c2_create_qp; - dev->ibdev.modify_qp = c2_modify_qp; - dev->ibdev.destroy_qp = c2_destroy_qp; - dev->ibdev.create_cq = c2_create_cq; - dev->ibdev.destroy_cq = c2_destroy_cq; - dev->ibdev.poll_cq = c2_poll_cq; - dev->ibdev.get_dma_mr = c2_get_dma_mr; - dev->ibdev.reg_phys_mr = c2_reg_phys_mr; - dev->ibdev.reg_user_mr = c2_reg_user_mr; - dev->ibdev.dereg_mr = c2_dereg_mr; - - dev->ibdev.alloc_fmr = NULL; - dev->ibdev.unmap_fmr = NULL; - dev->ibdev.dealloc_fmr = NULL; - dev->ibdev.map_phys_fmr = NULL; - - dev->ibdev.attach_mcast = c2_multicast_attach; - dev->ibdev.detach_mcast = c2_multicast_detach; - dev->ibdev.process_mad = c2_process_mad; - - dev->ibdev.req_notify_cq = c2_arm_cq; - dev->ibdev.post_send = c2_post_send; - dev->ibdev.post_recv = c2_post_receive; - - dev->ibdev.iwcm = kmalloc(sizeof(*dev->ibdev.iwcm), GFP_KERNEL); - if (dev->ibdev.iwcm == NULL) { - ret = -ENOMEM; - goto out_unregister_netdev; - } - dev->ibdev.iwcm->add_ref = c2_add_ref; - dev->ibdev.iwcm->rem_ref = c2_rem_ref; - dev->ibdev.iwcm->get_qp = c2_get_qp; - dev->ibdev.iwcm->connect = c2_connect; - dev->ibdev.iwcm->accept = c2_accept; - dev->ibdev.iwcm->reject = c2_reject; - dev->ibdev.iwcm->create_listen = c2_service_create; - dev->ibdev.iwcm->destroy_listen = c2_service_destroy; - - ret = ib_register_device(&dev->ibdev, NULL); - if (ret) - goto out_free_iwcm; - - for (i = 0; i < ARRAY_SIZE(c2_dev_attributes); ++i) { - ret = device_create_file(&dev->ibdev.dev, - c2_dev_attributes[i]); - if (ret) - goto out_unregister_ibdev; - } - goto out; - -out_unregister_ibdev: - ib_unregister_device(&dev->ibdev); -out_free_iwcm: - kfree(dev->ibdev.iwcm); -out_unregister_netdev: - unregister_netdev(dev->pseudo_netdev); -out_free_netdev: - free_netdev(dev->pseudo_netdev); -out: - pr_debug("%s:%u ret=%d\n", __func__, __LINE__, ret); - return ret; -} - -void c2_unregister_device(struct c2_dev *dev) -{ - pr_debug("%s:%u\n", __func__, __LINE__); - unregister_netdev(dev->pseudo_netdev); - free_netdev(dev->pseudo_netdev); - ib_unregister_device(&dev->ibdev); -} diff --git a/kernel/drivers/infiniband/hw/amso1100/c2_provider.h b/kernel/drivers/infiniband/hw/amso1100/c2_provider.h deleted file mode 100644 index bf1899877..000000000 --- a/kernel/drivers/infiniband/hw/amso1100/c2_provider.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (c) 2005 Ammasso, Inc. All rights reserved. - * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#ifndef C2_PROVIDER_H -#define C2_PROVIDER_H -#include <linux/inetdevice.h> - -#include <rdma/ib_verbs.h> -#include <rdma/ib_pack.h> - -#include "c2_mq.h" -#include <rdma/iw_cm.h> - -#define C2_MPT_FLAG_ATOMIC (1 << 14) -#define C2_MPT_FLAG_REMOTE_WRITE (1 << 13) -#define C2_MPT_FLAG_REMOTE_READ (1 << 12) -#define C2_MPT_FLAG_LOCAL_WRITE (1 << 11) -#define C2_MPT_FLAG_LOCAL_READ (1 << 10) - -struct c2_buf_list { - void *buf; - DEFINE_DMA_UNMAP_ADDR(mapping); -}; - - -/* The user context keeps track of objects allocated for a - * particular user-mode client. */ -struct c2_ucontext { - struct ib_ucontext ibucontext; -}; - -struct c2_mtt; - -/* All objects associated with a PD are kept in the - * associated user context if present. - */ -struct c2_pd { - struct ib_pd ibpd; - u32 pd_id; -}; - -struct c2_mr { - struct ib_mr ibmr; - struct c2_pd *pd; - struct ib_umem *umem; -}; - -struct c2_av; - -enum c2_ah_type { - C2_AH_ON_HCA, - C2_AH_PCI_POOL, - C2_AH_KMALLOC -}; - -struct c2_ah { - struct ib_ah ibah; -}; - -struct c2_cq { - struct ib_cq ibcq; - spinlock_t lock; - atomic_t refcount; - int cqn; - int is_kernel; - wait_queue_head_t wait; - - u32 adapter_handle; - struct c2_mq mq; -}; - -struct c2_wq { - spinlock_t lock; -}; -struct iw_cm_id; -struct c2_qp { - struct ib_qp ibqp; - struct iw_cm_id *cm_id; - spinlock_t lock; - atomic_t refcount; - wait_queue_head_t wait; - int qpn; - - u32 adapter_handle; - u32 send_sgl_depth; - u32 recv_sgl_depth; - u32 rdma_write_sgl_depth; - u8 state; - - struct c2_mq sq_mq; - struct c2_mq rq_mq; -}; - -struct c2_cr_query_attrs { - u32 local_addr; - u32 remote_addr; - u16 local_port; - u16 remote_port; -}; - -static inline struct c2_pd *to_c2pd(struct ib_pd *ibpd) -{ - return container_of(ibpd, struct c2_pd, ibpd); -} - -static inline struct c2_ucontext *to_c2ucontext(struct ib_ucontext *ibucontext) -{ - return container_of(ibucontext, struct c2_ucontext, ibucontext); -} - -static inline struct c2_mr *to_c2mr(struct ib_mr *ibmr) -{ - return container_of(ibmr, struct c2_mr, ibmr); -} - - -static inline struct c2_ah *to_c2ah(struct ib_ah *ibah) -{ - return container_of(ibah, struct c2_ah, ibah); -} - -static inline struct c2_cq *to_c2cq(struct ib_cq *ibcq) -{ - return container_of(ibcq, struct c2_cq, ibcq); -} - -static inline struct c2_qp *to_c2qp(struct ib_qp *ibqp) -{ - return container_of(ibqp, struct c2_qp, ibqp); -} - -static inline int is_rnic_addr(struct net_device *netdev, u32 addr) -{ - struct in_device *ind; - int ret = 0; - - ind = in_dev_get(netdev); - if (!ind) - return 0; - - for_ifa(ind) { - if (ifa->ifa_address == addr) { - ret = 1; - break; - } - } - endfor_ifa(ind); - in_dev_put(ind); - return ret; -} -#endif /* C2_PROVIDER_H */ diff --git a/kernel/drivers/infiniband/hw/amso1100/c2_qp.c b/kernel/drivers/infiniband/hw/amso1100/c2_qp.c deleted file mode 100644 index 86708dee5..000000000 --- a/kernel/drivers/infiniband/hw/amso1100/c2_qp.c +++ /dev/null @@ -1,1024 +0,0 @@ -/* - * Copyright (c) 2004 Topspin Communications. All rights reserved. - * Copyright (c) 2005 Cisco Systems. All rights reserved. - * Copyright (c) 2005 Mellanox Technologies. All rights reserved. - * Copyright (c) 2004 Voltaire, Inc. All rights reserved. - * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#include <linux/delay.h> -#include <linux/gfp.h> - -#include "c2.h" -#include "c2_vq.h" -#include "c2_status.h" - -#define C2_MAX_ORD_PER_QP 128 -#define C2_MAX_IRD_PER_QP 128 - -#define C2_HINT_MAKE(q_index, hint_count) (((q_index) << 16) | hint_count) -#define C2_HINT_GET_INDEX(hint) (((hint) & 0x7FFF0000) >> 16) -#define C2_HINT_GET_COUNT(hint) ((hint) & 0x0000FFFF) - -#define NO_SUPPORT -1 -static const u8 c2_opcode[] = { - [IB_WR_SEND] = C2_WR_TYPE_SEND, - [IB_WR_SEND_WITH_IMM] = NO_SUPPORT, - [IB_WR_RDMA_WRITE] = C2_WR_TYPE_RDMA_WRITE, - [IB_WR_RDMA_WRITE_WITH_IMM] = NO_SUPPORT, - [IB_WR_RDMA_READ] = C2_WR_TYPE_RDMA_READ, - [IB_WR_ATOMIC_CMP_AND_SWP] = NO_SUPPORT, - [IB_WR_ATOMIC_FETCH_AND_ADD] = NO_SUPPORT, -}; - -static int to_c2_state(enum ib_qp_state ib_state) -{ - switch (ib_state) { - case IB_QPS_RESET: - return C2_QP_STATE_IDLE; - case IB_QPS_RTS: - return C2_QP_STATE_RTS; - case IB_QPS_SQD: - return C2_QP_STATE_CLOSING; - case IB_QPS_SQE: - return C2_QP_STATE_CLOSING; - case IB_QPS_ERR: - return C2_QP_STATE_ERROR; - default: - return -1; - } -} - -static int to_ib_state(enum c2_qp_state c2_state) -{ - switch (c2_state) { - case C2_QP_STATE_IDLE: - return IB_QPS_RESET; - case C2_QP_STATE_CONNECTING: - return IB_QPS_RTR; - case C2_QP_STATE_RTS: - return IB_QPS_RTS; - case C2_QP_STATE_CLOSING: - return IB_QPS_SQD; - case C2_QP_STATE_ERROR: - return IB_QPS_ERR; - case C2_QP_STATE_TERMINATE: - return IB_QPS_SQE; - default: - return -1; - } -} - -static const char *to_ib_state_str(int ib_state) -{ - static const char *state_str[] = { - "IB_QPS_RESET", - "IB_QPS_INIT", - "IB_QPS_RTR", - "IB_QPS_RTS", - "IB_QPS_SQD", - "IB_QPS_SQE", - "IB_QPS_ERR" - }; - if (ib_state < IB_QPS_RESET || - ib_state > IB_QPS_ERR) - return "<invalid IB QP state>"; - - ib_state -= IB_QPS_RESET; - return state_str[ib_state]; -} - -void c2_set_qp_state(struct c2_qp *qp, int c2_state) -{ - int new_state = to_ib_state(c2_state); - - pr_debug("%s: qp[%p] state modify %s --> %s\n", - __func__, - qp, - to_ib_state_str(qp->state), - to_ib_state_str(new_state)); - qp->state = new_state; -} - -#define C2_QP_NO_ATTR_CHANGE 0xFFFFFFFF - -int c2_qp_modify(struct c2_dev *c2dev, struct c2_qp *qp, - struct ib_qp_attr *attr, int attr_mask) -{ - struct c2wr_qp_modify_req wr; - struct c2wr_qp_modify_rep *reply; - struct c2_vq_req *vq_req; - unsigned long flags; - u8 next_state; - int err; - - pr_debug("%s:%d qp=%p, %s --> %s\n", - __func__, __LINE__, - qp, - to_ib_state_str(qp->state), - to_ib_state_str(attr->qp_state)); - - vq_req = vq_req_alloc(c2dev); - if (!vq_req) - return -ENOMEM; - - c2_wr_set_id(&wr, CCWR_QP_MODIFY); - wr.hdr.context = (unsigned long) vq_req; - wr.rnic_handle = c2dev->adapter_handle; - wr.qp_handle = qp->adapter_handle; - wr.ord = cpu_to_be32(C2_QP_NO_ATTR_CHANGE); - wr.ird = cpu_to_be32(C2_QP_NO_ATTR_CHANGE); - wr.sq_depth = cpu_to_be32(C2_QP_NO_ATTR_CHANGE); - wr.rq_depth = cpu_to_be32(C2_QP_NO_ATTR_CHANGE); - - if (attr_mask & IB_QP_STATE) { - /* Ensure the state is valid */ - if (attr->qp_state < 0 || attr->qp_state > IB_QPS_ERR) { - err = -EINVAL; - goto bail0; - } - - wr.next_qp_state = cpu_to_be32(to_c2_state(attr->qp_state)); - - if (attr->qp_state == IB_QPS_ERR) { - spin_lock_irqsave(&qp->lock, flags); - if (qp->cm_id && qp->state == IB_QPS_RTS) { - pr_debug("Generating CLOSE event for QP-->ERR, " - "qp=%p, cm_id=%p\n",qp,qp->cm_id); - /* Generate an CLOSE event */ - vq_req->cm_id = qp->cm_id; - vq_req->event = IW_CM_EVENT_CLOSE; - } - spin_unlock_irqrestore(&qp->lock, flags); - } - next_state = attr->qp_state; - - } else if (attr_mask & IB_QP_CUR_STATE) { - - if (attr->cur_qp_state != IB_QPS_RTR && - attr->cur_qp_state != IB_QPS_RTS && - attr->cur_qp_state != IB_QPS_SQD && - attr->cur_qp_state != IB_QPS_SQE) { - err = -EINVAL; - goto bail0; - } else - wr.next_qp_state = - cpu_to_be32(to_c2_state(attr->cur_qp_state)); - - next_state = attr->cur_qp_state; - - } else { - err = 0; - goto bail0; - } - - /* reference the request struct */ - vq_req_get(c2dev, vq_req); - - err = vq_send_wr(c2dev, (union c2wr *) & wr); - if (err) { - vq_req_put(c2dev, vq_req); - goto bail0; - } - - err = vq_wait_for_reply(c2dev, vq_req); - if (err) - goto bail0; - - reply = (struct c2wr_qp_modify_rep *) (unsigned long) vq_req->reply_msg; - if (!reply) { - err = -ENOMEM; - goto bail0; - } - - err = c2_errno(reply); - if (!err) - qp->state = next_state; -#ifdef DEBUG - else - pr_debug("%s: c2_errno=%d\n", __func__, err); -#endif - /* - * If we're going to error and generating the event here, then - * we need to remove the reference because there will be no - * close event generated by the adapter - */ - spin_lock_irqsave(&qp->lock, flags); - if (vq_req->event==IW_CM_EVENT_CLOSE && qp->cm_id) { - qp->cm_id->rem_ref(qp->cm_id); - qp->cm_id = NULL; - } - spin_unlock_irqrestore(&qp->lock, flags); - - vq_repbuf_free(c2dev, reply); - bail0: - vq_req_free(c2dev, vq_req); - - pr_debug("%s:%d qp=%p, cur_state=%s\n", - __func__, __LINE__, - qp, - to_ib_state_str(qp->state)); - return err; -} - -int c2_qp_set_read_limits(struct c2_dev *c2dev, struct c2_qp *qp, - int ord, int ird) -{ - struct c2wr_qp_modify_req wr; - struct c2wr_qp_modify_rep *reply; - struct c2_vq_req *vq_req; - int err; - - vq_req = vq_req_alloc(c2dev); - if (!vq_req) - return -ENOMEM; - - c2_wr_set_id(&wr, CCWR_QP_MODIFY); - wr.hdr.context = (unsigned long) vq_req; - wr.rnic_handle = c2dev->adapter_handle; - wr.qp_handle = qp->adapter_handle; - wr.ord = cpu_to_be32(ord); - wr.ird = cpu_to_be32(ird); - wr.sq_depth = cpu_to_be32(C2_QP_NO_ATTR_CHANGE); - wr.rq_depth = cpu_to_be32(C2_QP_NO_ATTR_CHANGE); - wr.next_qp_state = cpu_to_be32(C2_QP_NO_ATTR_CHANGE); - - /* reference the request struct */ - vq_req_get(c2dev, vq_req); - - err = vq_send_wr(c2dev, (union c2wr *) & wr); - if (err) { - vq_req_put(c2dev, vq_req); - goto bail0; - } - - err = vq_wait_for_reply(c2dev, vq_req); - if (err) - goto bail0; - - reply = (struct c2wr_qp_modify_rep *) (unsigned long) - vq_req->reply_msg; - if (!reply) { - err = -ENOMEM; - goto bail0; - } - - err = c2_errno(reply); - vq_repbuf_free(c2dev, reply); - bail0: - vq_req_free(c2dev, vq_req); - return err; -} - -static int destroy_qp(struct c2_dev *c2dev, struct c2_qp *qp) -{ - struct c2_vq_req *vq_req; - struct c2wr_qp_destroy_req wr; - struct c2wr_qp_destroy_rep *reply; - unsigned long flags; - int err; - - /* - * Allocate a verb request message - */ - vq_req = vq_req_alloc(c2dev); - if (!vq_req) { - return -ENOMEM; - } - - /* - * Initialize the WR - */ - c2_wr_set_id(&wr, CCWR_QP_DESTROY); - wr.hdr.context = (unsigned long) vq_req; - wr.rnic_handle = c2dev->adapter_handle; - wr.qp_handle = qp->adapter_handle; - - /* - * reference the request struct. dereferenced in the int handler. - */ - vq_req_get(c2dev, vq_req); - - spin_lock_irqsave(&qp->lock, flags); - if (qp->cm_id && qp->state == IB_QPS_RTS) { - pr_debug("destroy_qp: generating CLOSE event for QP-->ERR, " - "qp=%p, cm_id=%p\n",qp,qp->cm_id); - /* Generate an CLOSE event */ - vq_req->qp = qp; - vq_req->cm_id = qp->cm_id; - vq_req->event = IW_CM_EVENT_CLOSE; - } - spin_unlock_irqrestore(&qp->lock, flags); - - /* - * Send WR to adapter - */ - err = vq_send_wr(c2dev, (union c2wr *) & wr); - if (err) { - vq_req_put(c2dev, vq_req); - goto bail0; - } - - /* - * Wait for reply from adapter - */ - err = vq_wait_for_reply(c2dev, vq_req); - if (err) { - goto bail0; - } - - /* - * Process reply - */ - reply = (struct c2wr_qp_destroy_rep *) (unsigned long) (vq_req->reply_msg); - if (!reply) { - err = -ENOMEM; - goto bail0; - } - - spin_lock_irqsave(&qp->lock, flags); - if (qp->cm_id) { - qp->cm_id->rem_ref(qp->cm_id); - qp->cm_id = NULL; - } - spin_unlock_irqrestore(&qp->lock, flags); - - vq_repbuf_free(c2dev, reply); - bail0: - vq_req_free(c2dev, vq_req); - return err; -} - -static int c2_alloc_qpn(struct c2_dev *c2dev, struct c2_qp *qp) -{ - int ret; - - idr_preload(GFP_KERNEL); - spin_lock_irq(&c2dev->qp_table.lock); - - ret = idr_alloc_cyclic(&c2dev->qp_table.idr, qp, 0, 0, GFP_NOWAIT); - if (ret >= 0) - qp->qpn = ret; - - spin_unlock_irq(&c2dev->qp_table.lock); - idr_preload_end(); - return ret < 0 ? ret : 0; -} - -static void c2_free_qpn(struct c2_dev *c2dev, int qpn) -{ - spin_lock_irq(&c2dev->qp_table.lock); - idr_remove(&c2dev->qp_table.idr, qpn); - spin_unlock_irq(&c2dev->qp_table.lock); -} - -struct c2_qp *c2_find_qpn(struct c2_dev *c2dev, int qpn) -{ - unsigned long flags; - struct c2_qp *qp; - - spin_lock_irqsave(&c2dev->qp_table.lock, flags); - qp = idr_find(&c2dev->qp_table.idr, qpn); - spin_unlock_irqrestore(&c2dev->qp_table.lock, flags); - return qp; -} - -int c2_alloc_qp(struct c2_dev *c2dev, - struct c2_pd *pd, - struct ib_qp_init_attr *qp_attrs, struct c2_qp *qp) -{ - struct c2wr_qp_create_req wr; - struct c2wr_qp_create_rep *reply; - struct c2_vq_req *vq_req; - struct c2_cq *send_cq = to_c2cq(qp_attrs->send_cq); - struct c2_cq *recv_cq = to_c2cq(qp_attrs->recv_cq); - unsigned long peer_pa; - u32 q_size, msg_size, mmap_size; - void __iomem *mmap; - int err; - - err = c2_alloc_qpn(c2dev, qp); - if (err) - return err; - qp->ibqp.qp_num = qp->qpn; - qp->ibqp.qp_type = IB_QPT_RC; - - /* Allocate the SQ and RQ shared pointers */ - qp->sq_mq.shared = c2_alloc_mqsp(c2dev, c2dev->kern_mqsp_pool, - &qp->sq_mq.shared_dma, GFP_KERNEL); - if (!qp->sq_mq.shared) { - err = -ENOMEM; - goto bail0; - } - - qp->rq_mq.shared = c2_alloc_mqsp(c2dev, c2dev->kern_mqsp_pool, - &qp->rq_mq.shared_dma, GFP_KERNEL); - if (!qp->rq_mq.shared) { - err = -ENOMEM; - goto bail1; - } - - /* Allocate the verbs request */ - vq_req = vq_req_alloc(c2dev); - if (vq_req == NULL) { - err = -ENOMEM; - goto bail2; - } - - /* Initialize the work request */ - memset(&wr, 0, sizeof(wr)); - c2_wr_set_id(&wr, CCWR_QP_CREATE); - wr.hdr.context = (unsigned long) vq_req; - wr.rnic_handle = c2dev->adapter_handle; - wr.sq_cq_handle = send_cq->adapter_handle; - wr.rq_cq_handle = recv_cq->adapter_handle; - wr.sq_depth = cpu_to_be32(qp_attrs->cap.max_send_wr + 1); - wr.rq_depth = cpu_to_be32(qp_attrs->cap.max_recv_wr + 1); - wr.srq_handle = 0; - wr.flags = cpu_to_be32(QP_RDMA_READ | QP_RDMA_WRITE | QP_MW_BIND | - QP_ZERO_STAG | QP_RDMA_READ_RESPONSE); - wr.send_sgl_depth = cpu_to_be32(qp_attrs->cap.max_send_sge); - wr.recv_sgl_depth = cpu_to_be32(qp_attrs->cap.max_recv_sge); - wr.rdma_write_sgl_depth = cpu_to_be32(qp_attrs->cap.max_send_sge); - wr.shared_sq_ht = cpu_to_be64(qp->sq_mq.shared_dma); - wr.shared_rq_ht = cpu_to_be64(qp->rq_mq.shared_dma); - wr.ord = cpu_to_be32(C2_MAX_ORD_PER_QP); - wr.ird = cpu_to_be32(C2_MAX_IRD_PER_QP); - wr.pd_id = pd->pd_id; - wr.user_context = (unsigned long) qp; - - vq_req_get(c2dev, vq_req); - - /* Send the WR to the adapter */ - err = vq_send_wr(c2dev, (union c2wr *) & wr); - if (err) { - vq_req_put(c2dev, vq_req); - goto bail3; - } - - /* Wait for the verb reply */ - err = vq_wait_for_reply(c2dev, vq_req); - if (err) { - goto bail3; - } - - /* Process the reply */ - reply = (struct c2wr_qp_create_rep *) (unsigned long) (vq_req->reply_msg); - if (!reply) { - err = -ENOMEM; - goto bail3; - } - - if ((err = c2_wr_get_result(reply)) != 0) { - goto bail4; - } - - /* Fill in the kernel QP struct */ - atomic_set(&qp->refcount, 1); - qp->adapter_handle = reply->qp_handle; - qp->state = IB_QPS_RESET; - qp->send_sgl_depth = qp_attrs->cap.max_send_sge; - qp->rdma_write_sgl_depth = qp_attrs->cap.max_send_sge; - qp->recv_sgl_depth = qp_attrs->cap.max_recv_sge; - init_waitqueue_head(&qp->wait); - - /* Initialize the SQ MQ */ - q_size = be32_to_cpu(reply->sq_depth); - msg_size = be32_to_cpu(reply->sq_msg_size); - peer_pa = c2dev->pa + be32_to_cpu(reply->sq_mq_start); - mmap_size = PAGE_ALIGN(sizeof(struct c2_mq_shared) + msg_size * q_size); - mmap = ioremap_nocache(peer_pa, mmap_size); - if (!mmap) { - err = -ENOMEM; - goto bail5; - } - - c2_mq_req_init(&qp->sq_mq, - be32_to_cpu(reply->sq_mq_index), - q_size, - msg_size, - mmap + sizeof(struct c2_mq_shared), /* pool start */ - mmap, /* peer */ - C2_MQ_ADAPTER_TARGET); - - /* Initialize the RQ mq */ - q_size = be32_to_cpu(reply->rq_depth); - msg_size = be32_to_cpu(reply->rq_msg_size); - peer_pa = c2dev->pa + be32_to_cpu(reply->rq_mq_start); - mmap_size = PAGE_ALIGN(sizeof(struct c2_mq_shared) + msg_size * q_size); - mmap = ioremap_nocache(peer_pa, mmap_size); - if (!mmap) { - err = -ENOMEM; - goto bail6; - } - - c2_mq_req_init(&qp->rq_mq, - be32_to_cpu(reply->rq_mq_index), - q_size, - msg_size, - mmap + sizeof(struct c2_mq_shared), /* pool start */ - mmap, /* peer */ - C2_MQ_ADAPTER_TARGET); - - vq_repbuf_free(c2dev, reply); - vq_req_free(c2dev, vq_req); - - return 0; - - bail6: - iounmap(qp->sq_mq.peer); - bail5: - destroy_qp(c2dev, qp); - bail4: - vq_repbuf_free(c2dev, reply); - bail3: - vq_req_free(c2dev, vq_req); - bail2: - c2_free_mqsp(qp->rq_mq.shared); - bail1: - c2_free_mqsp(qp->sq_mq.shared); - bail0: - c2_free_qpn(c2dev, qp->qpn); - return err; -} - -static inline void c2_lock_cqs(struct c2_cq *send_cq, struct c2_cq *recv_cq) -{ - if (send_cq == recv_cq) - spin_lock_irq(&send_cq->lock); - else if (send_cq > recv_cq) { - spin_lock_irq(&send_cq->lock); - spin_lock_nested(&recv_cq->lock, SINGLE_DEPTH_NESTING); - } else { - spin_lock_irq(&recv_cq->lock); - spin_lock_nested(&send_cq->lock, SINGLE_DEPTH_NESTING); - } -} - -static inline void c2_unlock_cqs(struct c2_cq *send_cq, struct c2_cq *recv_cq) -{ - if (send_cq == recv_cq) - spin_unlock_irq(&send_cq->lock); - else if (send_cq > recv_cq) { - spin_unlock(&recv_cq->lock); - spin_unlock_irq(&send_cq->lock); - } else { - spin_unlock(&send_cq->lock); - spin_unlock_irq(&recv_cq->lock); - } -} - -void c2_free_qp(struct c2_dev *c2dev, struct c2_qp *qp) -{ - struct c2_cq *send_cq; - struct c2_cq *recv_cq; - - send_cq = to_c2cq(qp->ibqp.send_cq); - recv_cq = to_c2cq(qp->ibqp.recv_cq); - - /* - * Lock CQs here, so that CQ polling code can do QP lookup - * without taking a lock. - */ - c2_lock_cqs(send_cq, recv_cq); - c2_free_qpn(c2dev, qp->qpn); - c2_unlock_cqs(send_cq, recv_cq); - - /* - * Destroy qp in the rnic... - */ - destroy_qp(c2dev, qp); - - /* - * Mark any unreaped CQEs as null and void. - */ - c2_cq_clean(c2dev, qp, send_cq->cqn); - if (send_cq != recv_cq) - c2_cq_clean(c2dev, qp, recv_cq->cqn); - /* - * Unmap the MQs and return the shared pointers - * to the message pool. - */ - iounmap(qp->sq_mq.peer); - iounmap(qp->rq_mq.peer); - c2_free_mqsp(qp->sq_mq.shared); - c2_free_mqsp(qp->rq_mq.shared); - - atomic_dec(&qp->refcount); - wait_event(qp->wait, !atomic_read(&qp->refcount)); -} - -/* - * Function: move_sgl - * - * Description: - * Move an SGL from the user's work request struct into a CCIL Work Request - * message, swapping to WR byte order and ensure the total length doesn't - * overflow. - * - * IN: - * dst - ptr to CCIL Work Request message SGL memory. - * src - ptr to the consumers SGL memory. - * - * OUT: none - * - * Return: - * CCIL status codes. - */ -static int -move_sgl(struct c2_data_addr * dst, struct ib_sge *src, int count, u32 * p_len, - u8 * actual_count) -{ - u32 tot = 0; /* running total */ - u8 acount = 0; /* running total non-0 len sge's */ - - while (count > 0) { - /* - * If the addition of this SGE causes the - * total SGL length to exceed 2^32-1, then - * fail-n-bail. - * - * If the current total plus the next element length - * wraps, then it will go negative and be less than the - * current total... - */ - if ((tot + src->length) < tot) { - return -EINVAL; - } - /* - * Bug: 1456 (as well as 1498 & 1643) - * Skip over any sge's supplied with len=0 - */ - if (src->length) { - tot += src->length; - dst->stag = cpu_to_be32(src->lkey); - dst->to = cpu_to_be64(src->addr); - dst->length = cpu_to_be32(src->length); - dst++; - acount++; - } - src++; - count--; - } - - if (acount == 0) { - /* - * Bug: 1476 (as well as 1498, 1456 and 1643) - * Setup the SGL in the WR to make it easier for the RNIC. - * This way, the FW doesn't have to deal with special cases. - * Setting length=0 should be sufficient. - */ - dst->stag = 0; - dst->to = 0; - dst->length = 0; - } - - *p_len = tot; - *actual_count = acount; - return 0; -} - -/* - * Function: c2_activity (private function) - * - * Description: - * Post an mq index to the host->adapter activity fifo. - * - * IN: - * c2dev - ptr to c2dev structure - * mq_index - mq index to post - * shared - value most recently written to shared - * - * OUT: - * - * Return: - * none - */ -static inline void c2_activity(struct c2_dev *c2dev, u32 mq_index, u16 shared) -{ - /* - * First read the register to see if the FIFO is full, and if so, - * spin until it's not. This isn't perfect -- there is no - * synchronization among the clients of the register, but in - * practice it prevents multiple CPU from hammering the bus - * with PCI RETRY. Note that when this does happen, the card - * cannot get on the bus and the card and system hang in a - * deadlock -- thus the need for this code. [TOT] - */ - while (readl(c2dev->regs + PCI_BAR0_ADAPTER_HINT) & 0x80000000) - udelay(10); - - __raw_writel(C2_HINT_MAKE(mq_index, shared), - c2dev->regs + PCI_BAR0_ADAPTER_HINT); -} - -/* - * Function: qp_wr_post - * - * Description: - * This in-line function allocates a MQ msg, then moves the host-copy of - * the completed WR into msg. Then it posts the message. - * - * IN: - * q - ptr to user MQ. - * wr - ptr to host-copy of the WR. - * qp - ptr to user qp - * size - Number of bytes to post. Assumed to be divisible by 4. - * - * OUT: none - * - * Return: - * CCIL status codes. - */ -static int qp_wr_post(struct c2_mq *q, union c2wr * wr, struct c2_qp *qp, u32 size) -{ - union c2wr *msg; - - msg = c2_mq_alloc(q); - if (msg == NULL) { - return -EINVAL; - } -#ifdef CCMSGMAGIC - ((c2wr_hdr_t *) wr)->magic = cpu_to_be32(CCWR_MAGIC); -#endif - - /* - * Since all header fields in the WR are the same as the - * CQE, set the following so the adapter need not. - */ - c2_wr_set_result(wr, CCERR_PENDING); - - /* - * Copy the wr down to the adapter - */ - memcpy((void *) msg, (void *) wr, size); - - c2_mq_produce(q); - return 0; -} - - -int c2_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, - struct ib_send_wr **bad_wr) -{ - struct c2_dev *c2dev = to_c2dev(ibqp->device); - struct c2_qp *qp = to_c2qp(ibqp); - union c2wr wr; - unsigned long lock_flags; - int err = 0; - - u32 flags; - u32 tot_len; - u8 actual_sge_count; - u32 msg_size; - - if (qp->state > IB_QPS_RTS) { - err = -EINVAL; - goto out; - } - - while (ib_wr) { - - flags = 0; - wr.sqwr.sq_hdr.user_hdr.hdr.context = ib_wr->wr_id; - if (ib_wr->send_flags & IB_SEND_SIGNALED) { - flags |= SQ_SIGNALED; - } - - switch (ib_wr->opcode) { - case IB_WR_SEND: - case IB_WR_SEND_WITH_INV: - if (ib_wr->opcode == IB_WR_SEND) { - if (ib_wr->send_flags & IB_SEND_SOLICITED) - c2_wr_set_id(&wr, C2_WR_TYPE_SEND_SE); - else - c2_wr_set_id(&wr, C2_WR_TYPE_SEND); - wr.sqwr.send.remote_stag = 0; - } else { - if (ib_wr->send_flags & IB_SEND_SOLICITED) - c2_wr_set_id(&wr, C2_WR_TYPE_SEND_SE_INV); - else - c2_wr_set_id(&wr, C2_WR_TYPE_SEND_INV); - wr.sqwr.send.remote_stag = - cpu_to_be32(ib_wr->ex.invalidate_rkey); - } - - msg_size = sizeof(struct c2wr_send_req) + - sizeof(struct c2_data_addr) * ib_wr->num_sge; - if (ib_wr->num_sge > qp->send_sgl_depth) { - err = -EINVAL; - break; - } - if (ib_wr->send_flags & IB_SEND_FENCE) { - flags |= SQ_READ_FENCE; - } - err = move_sgl((struct c2_data_addr *) & (wr.sqwr.send.data), - ib_wr->sg_list, - ib_wr->num_sge, - &tot_len, &actual_sge_count); - wr.sqwr.send.sge_len = cpu_to_be32(tot_len); - c2_wr_set_sge_count(&wr, actual_sge_count); - break; - case IB_WR_RDMA_WRITE: - c2_wr_set_id(&wr, C2_WR_TYPE_RDMA_WRITE); - msg_size = sizeof(struct c2wr_rdma_write_req) + - (sizeof(struct c2_data_addr) * ib_wr->num_sge); - if (ib_wr->num_sge > qp->rdma_write_sgl_depth) { - err = -EINVAL; - break; - } - if (ib_wr->send_flags & IB_SEND_FENCE) { - flags |= SQ_READ_FENCE; - } - wr.sqwr.rdma_write.remote_stag = - cpu_to_be32(ib_wr->wr.rdma.rkey); - wr.sqwr.rdma_write.remote_to = - cpu_to_be64(ib_wr->wr.rdma.remote_addr); - err = move_sgl((struct c2_data_addr *) - & (wr.sqwr.rdma_write.data), - ib_wr->sg_list, - ib_wr->num_sge, - &tot_len, &actual_sge_count); - wr.sqwr.rdma_write.sge_len = cpu_to_be32(tot_len); - c2_wr_set_sge_count(&wr, actual_sge_count); - break; - case IB_WR_RDMA_READ: - c2_wr_set_id(&wr, C2_WR_TYPE_RDMA_READ); - msg_size = sizeof(struct c2wr_rdma_read_req); - - /* IWarp only suppots 1 sge for RDMA reads */ - if (ib_wr->num_sge > 1) { - err = -EINVAL; - break; - } - - /* - * Move the local and remote stag/to/len into the WR. - */ - wr.sqwr.rdma_read.local_stag = - cpu_to_be32(ib_wr->sg_list->lkey); - wr.sqwr.rdma_read.local_to = - cpu_to_be64(ib_wr->sg_list->addr); - wr.sqwr.rdma_read.remote_stag = - cpu_to_be32(ib_wr->wr.rdma.rkey); - wr.sqwr.rdma_read.remote_to = - cpu_to_be64(ib_wr->wr.rdma.remote_addr); - wr.sqwr.rdma_read.length = - cpu_to_be32(ib_wr->sg_list->length); - break; - default: - /* error */ - msg_size = 0; - err = -EINVAL; - break; - } - - /* - * If we had an error on the last wr build, then - * break out. Possible errors include bogus WR - * type, and a bogus SGL length... - */ - if (err) { - break; - } - - /* - * Store flags - */ - c2_wr_set_flags(&wr, flags); - - /* - * Post the puppy! - */ - spin_lock_irqsave(&qp->lock, lock_flags); - err = qp_wr_post(&qp->sq_mq, &wr, qp, msg_size); - if (err) { - spin_unlock_irqrestore(&qp->lock, lock_flags); - break; - } - - /* - * Enqueue mq index to activity FIFO. - */ - c2_activity(c2dev, qp->sq_mq.index, qp->sq_mq.hint_count); - spin_unlock_irqrestore(&qp->lock, lock_flags); - - ib_wr = ib_wr->next; - } - -out: - if (err) - *bad_wr = ib_wr; - return err; -} - -int c2_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr, - struct ib_recv_wr **bad_wr) -{ - struct c2_dev *c2dev = to_c2dev(ibqp->device); - struct c2_qp *qp = to_c2qp(ibqp); - union c2wr wr; - unsigned long lock_flags; - int err = 0; - - if (qp->state > IB_QPS_RTS) { - err = -EINVAL; - goto out; - } - - /* - * Try and post each work request - */ - while (ib_wr) { - u32 tot_len; - u8 actual_sge_count; - - if (ib_wr->num_sge > qp->recv_sgl_depth) { - err = -EINVAL; - break; - } - - /* - * Create local host-copy of the WR - */ - wr.rqwr.rq_hdr.user_hdr.hdr.context = ib_wr->wr_id; - c2_wr_set_id(&wr, CCWR_RECV); - c2_wr_set_flags(&wr, 0); - - /* sge_count is limited to eight bits. */ - BUG_ON(ib_wr->num_sge >= 256); - err = move_sgl((struct c2_data_addr *) & (wr.rqwr.data), - ib_wr->sg_list, - ib_wr->num_sge, &tot_len, &actual_sge_count); - c2_wr_set_sge_count(&wr, actual_sge_count); - - /* - * If we had an error on the last wr build, then - * break out. Possible errors include bogus WR - * type, and a bogus SGL length... - */ - if (err) { - break; - } - - spin_lock_irqsave(&qp->lock, lock_flags); - err = qp_wr_post(&qp->rq_mq, &wr, qp, qp->rq_mq.msg_size); - if (err) { - spin_unlock_irqrestore(&qp->lock, lock_flags); - break; - } - - /* - * Enqueue mq index to activity FIFO - */ - c2_activity(c2dev, qp->rq_mq.index, qp->rq_mq.hint_count); - spin_unlock_irqrestore(&qp->lock, lock_flags); - - ib_wr = ib_wr->next; - } - -out: - if (err) - *bad_wr = ib_wr; - return err; -} - -void c2_init_qp_table(struct c2_dev *c2dev) -{ - spin_lock_init(&c2dev->qp_table.lock); - idr_init(&c2dev->qp_table.idr); -} - -void c2_cleanup_qp_table(struct c2_dev *c2dev) -{ - idr_destroy(&c2dev->qp_table.idr); -} diff --git a/kernel/drivers/infiniband/hw/amso1100/c2_rnic.c b/kernel/drivers/infiniband/hw/amso1100/c2_rnic.c deleted file mode 100644 index d2a6d9613..000000000 --- a/kernel/drivers/infiniband/hw/amso1100/c2_rnic.c +++ /dev/null @@ -1,655 +0,0 @@ -/* - * Copyright (c) 2005 Ammasso, Inc. All rights reserved. - * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/pci.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/delay.h> -#include <linux/ethtool.h> -#include <linux/mii.h> -#include <linux/if_vlan.h> -#include <linux/crc32.h> -#include <linux/in.h> -#include <linux/ip.h> -#include <linux/tcp.h> -#include <linux/init.h> -#include <linux/dma-mapping.h> -#include <linux/mm.h> -#include <linux/inet.h> -#include <linux/vmalloc.h> -#include <linux/slab.h> - -#include <linux/route.h> - -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/byteorder.h> -#include <rdma/ib_smi.h> -#include "c2.h" -#include "c2_vq.h" - -/* Device capabilities */ -#define C2_MIN_PAGESIZE 1024 - -#define C2_MAX_MRS 32768 -#define C2_MAX_QPS 16000 -#define C2_MAX_WQE_SZ 256 -#define C2_MAX_QP_WR ((128*1024)/C2_MAX_WQE_SZ) -#define C2_MAX_SGES 4 -#define C2_MAX_SGE_RD 1 -#define C2_MAX_CQS 32768 -#define C2_MAX_CQES 4096 -#define C2_MAX_PDS 16384 - -/* - * Send the adapter INIT message to the amso1100 - */ -static int c2_adapter_init(struct c2_dev *c2dev) -{ - struct c2wr_init_req wr; - int err; - - memset(&wr, 0, sizeof(wr)); - c2_wr_set_id(&wr, CCWR_INIT); - wr.hdr.context = 0; - wr.hint_count = cpu_to_be64(c2dev->hint_count_dma); - wr.q0_host_shared = cpu_to_be64(c2dev->req_vq.shared_dma); - wr.q1_host_shared = cpu_to_be64(c2dev->rep_vq.shared_dma); - wr.q1_host_msg_pool = cpu_to_be64(c2dev->rep_vq.host_dma); - wr.q2_host_shared = cpu_to_be64(c2dev->aeq.shared_dma); - wr.q2_host_msg_pool = cpu_to_be64(c2dev->aeq.host_dma); - - /* Post the init message */ - err = vq_send_wr(c2dev, (union c2wr *) & wr); - - return err; -} - -/* - * Send the adapter TERM message to the amso1100 - */ -static void c2_adapter_term(struct c2_dev *c2dev) -{ - struct c2wr_init_req wr; - - memset(&wr, 0, sizeof(wr)); - c2_wr_set_id(&wr, CCWR_TERM); - wr.hdr.context = 0; - - /* Post the init message */ - vq_send_wr(c2dev, (union c2wr *) & wr); - c2dev->init = 0; - - return; -} - -/* - * Query the adapter - */ -static int c2_rnic_query(struct c2_dev *c2dev, struct ib_device_attr *props) -{ - struct c2_vq_req *vq_req; - struct c2wr_rnic_query_req wr; - struct c2wr_rnic_query_rep *reply; - int err; - - vq_req = vq_req_alloc(c2dev); - if (!vq_req) - return -ENOMEM; - - c2_wr_set_id(&wr, CCWR_RNIC_QUERY); - wr.hdr.context = (unsigned long) vq_req; - wr.rnic_handle = c2dev->adapter_handle; - - vq_req_get(c2dev, vq_req); - - err = vq_send_wr(c2dev, (union c2wr *) &wr); - if (err) { - vq_req_put(c2dev, vq_req); - goto bail1; - } - - err = vq_wait_for_reply(c2dev, vq_req); - if (err) - goto bail1; - - reply = - (struct c2wr_rnic_query_rep *) (unsigned long) (vq_req->reply_msg); - if (!reply) - err = -ENOMEM; - else - err = c2_errno(reply); - if (err) - goto bail2; - - props->fw_ver = - ((u64)be32_to_cpu(reply->fw_ver_major) << 32) | - ((be32_to_cpu(reply->fw_ver_minor) & 0xFFFF) << 16) | - (be32_to_cpu(reply->fw_ver_patch) & 0xFFFF); - memcpy(&props->sys_image_guid, c2dev->netdev->dev_addr, 6); - props->max_mr_size = 0xFFFFFFFF; - props->page_size_cap = ~(C2_MIN_PAGESIZE-1); - props->vendor_id = be32_to_cpu(reply->vendor_id); - props->vendor_part_id = be32_to_cpu(reply->part_number); - props->hw_ver = be32_to_cpu(reply->hw_version); - props->max_qp = be32_to_cpu(reply->max_qps); - props->max_qp_wr = be32_to_cpu(reply->max_qp_depth); - props->device_cap_flags = c2dev->device_cap_flags; - props->max_sge = C2_MAX_SGES; - props->max_sge_rd = C2_MAX_SGE_RD; - props->max_cq = be32_to_cpu(reply->max_cqs); - props->max_cqe = be32_to_cpu(reply->max_cq_depth); - props->max_mr = be32_to_cpu(reply->max_mrs); - props->max_pd = be32_to_cpu(reply->max_pds); - props->max_qp_rd_atom = be32_to_cpu(reply->max_qp_ird); - props->max_ee_rd_atom = 0; - props->max_res_rd_atom = be32_to_cpu(reply->max_global_ird); - props->max_qp_init_rd_atom = be32_to_cpu(reply->max_qp_ord); - props->max_ee_init_rd_atom = 0; - props->atomic_cap = IB_ATOMIC_NONE; - props->max_ee = 0; - props->max_rdd = 0; - props->max_mw = be32_to_cpu(reply->max_mws); - props->max_raw_ipv6_qp = 0; - props->max_raw_ethy_qp = 0; - props->max_mcast_grp = 0; - props->max_mcast_qp_attach = 0; - props->max_total_mcast_qp_attach = 0; - props->max_ah = 0; - props->max_fmr = 0; - props->max_map_per_fmr = 0; - props->max_srq = 0; - props->max_srq_wr = 0; - props->max_srq_sge = 0; - props->max_pkeys = 0; - props->local_ca_ack_delay = 0; - - bail2: - vq_repbuf_free(c2dev, reply); - - bail1: - vq_req_free(c2dev, vq_req); - return err; -} - -/* - * Add an IP address to the RNIC interface - */ -int c2_add_addr(struct c2_dev *c2dev, __be32 inaddr, __be32 inmask) -{ - struct c2_vq_req *vq_req; - struct c2wr_rnic_setconfig_req *wr; - struct c2wr_rnic_setconfig_rep *reply; - struct c2_netaddr netaddr; - int err, len; - - vq_req = vq_req_alloc(c2dev); - if (!vq_req) - return -ENOMEM; - - len = sizeof(struct c2_netaddr); - wr = kmalloc(c2dev->req_vq.msg_size, GFP_KERNEL); - if (!wr) { - err = -ENOMEM; - goto bail0; - } - - c2_wr_set_id(wr, CCWR_RNIC_SETCONFIG); - wr->hdr.context = (unsigned long) vq_req; - wr->rnic_handle = c2dev->adapter_handle; - wr->option = cpu_to_be32(C2_CFG_ADD_ADDR); - - netaddr.ip_addr = inaddr; - netaddr.netmask = inmask; - netaddr.mtu = 0; - - memcpy(wr->data, &netaddr, len); - - vq_req_get(c2dev, vq_req); - - err = vq_send_wr(c2dev, (union c2wr *) wr); - if (err) { - vq_req_put(c2dev, vq_req); - goto bail1; - } - - err = vq_wait_for_reply(c2dev, vq_req); - if (err) - goto bail1; - - reply = - (struct c2wr_rnic_setconfig_rep *) (unsigned long) (vq_req->reply_msg); - if (!reply) { - err = -ENOMEM; - goto bail1; - } - - err = c2_errno(reply); - vq_repbuf_free(c2dev, reply); - - bail1: - kfree(wr); - bail0: - vq_req_free(c2dev, vq_req); - return err; -} - -/* - * Delete an IP address from the RNIC interface - */ -int c2_del_addr(struct c2_dev *c2dev, __be32 inaddr, __be32 inmask) -{ - struct c2_vq_req *vq_req; - struct c2wr_rnic_setconfig_req *wr; - struct c2wr_rnic_setconfig_rep *reply; - struct c2_netaddr netaddr; - int err, len; - - vq_req = vq_req_alloc(c2dev); - if (!vq_req) - return -ENOMEM; - - len = sizeof(struct c2_netaddr); - wr = kmalloc(c2dev->req_vq.msg_size, GFP_KERNEL); - if (!wr) { - err = -ENOMEM; - goto bail0; - } - - c2_wr_set_id(wr, CCWR_RNIC_SETCONFIG); - wr->hdr.context = (unsigned long) vq_req; - wr->rnic_handle = c2dev->adapter_handle; - wr->option = cpu_to_be32(C2_CFG_DEL_ADDR); - - netaddr.ip_addr = inaddr; - netaddr.netmask = inmask; - netaddr.mtu = 0; - - memcpy(wr->data, &netaddr, len); - - vq_req_get(c2dev, vq_req); - - err = vq_send_wr(c2dev, (union c2wr *) wr); - if (err) { - vq_req_put(c2dev, vq_req); - goto bail1; - } - - err = vq_wait_for_reply(c2dev, vq_req); - if (err) - goto bail1; - - reply = - (struct c2wr_rnic_setconfig_rep *) (unsigned long) (vq_req->reply_msg); - if (!reply) { - err = -ENOMEM; - goto bail1; - } - - err = c2_errno(reply); - vq_repbuf_free(c2dev, reply); - - bail1: - kfree(wr); - bail0: - vq_req_free(c2dev, vq_req); - return err; -} - -/* - * Open a single RNIC instance to use with all - * low level openib calls - */ -static int c2_rnic_open(struct c2_dev *c2dev) -{ - struct c2_vq_req *vq_req; - union c2wr wr; - struct c2wr_rnic_open_rep *reply; - int err; - - vq_req = vq_req_alloc(c2dev); - if (vq_req == NULL) { - return -ENOMEM; - } - - memset(&wr, 0, sizeof(wr)); - c2_wr_set_id(&wr, CCWR_RNIC_OPEN); - wr.rnic_open.req.hdr.context = (unsigned long) (vq_req); - wr.rnic_open.req.flags = cpu_to_be16(RNIC_PRIV_MODE); - wr.rnic_open.req.port_num = cpu_to_be16(0); - wr.rnic_open.req.user_context = (unsigned long) c2dev; - - vq_req_get(c2dev, vq_req); - - err = vq_send_wr(c2dev, &wr); - if (err) { - vq_req_put(c2dev, vq_req); - goto bail0; - } - - err = vq_wait_for_reply(c2dev, vq_req); - if (err) { - goto bail0; - } - - reply = (struct c2wr_rnic_open_rep *) (unsigned long) (vq_req->reply_msg); - if (!reply) { - err = -ENOMEM; - goto bail0; - } - - if ((err = c2_errno(reply)) != 0) { - goto bail1; - } - - c2dev->adapter_handle = reply->rnic_handle; - - bail1: - vq_repbuf_free(c2dev, reply); - bail0: - vq_req_free(c2dev, vq_req); - return err; -} - -/* - * Close the RNIC instance - */ -static int c2_rnic_close(struct c2_dev *c2dev) -{ - struct c2_vq_req *vq_req; - union c2wr wr; - struct c2wr_rnic_close_rep *reply; - int err; - - vq_req = vq_req_alloc(c2dev); - if (vq_req == NULL) { - return -ENOMEM; - } - - memset(&wr, 0, sizeof(wr)); - c2_wr_set_id(&wr, CCWR_RNIC_CLOSE); - wr.rnic_close.req.hdr.context = (unsigned long) vq_req; - wr.rnic_close.req.rnic_handle = c2dev->adapter_handle; - - vq_req_get(c2dev, vq_req); - - err = vq_send_wr(c2dev, &wr); - if (err) { - vq_req_put(c2dev, vq_req); - goto bail0; - } - - err = vq_wait_for_reply(c2dev, vq_req); - if (err) { - goto bail0; - } - - reply = (struct c2wr_rnic_close_rep *) (unsigned long) (vq_req->reply_msg); - if (!reply) { - err = -ENOMEM; - goto bail0; - } - - if ((err = c2_errno(reply)) != 0) { - goto bail1; - } - - c2dev->adapter_handle = 0; - - bail1: - vq_repbuf_free(c2dev, reply); - bail0: - vq_req_free(c2dev, vq_req); - return err; -} - -/* - * Called by c2_probe to initialize the RNIC. This principally - * involves initializing the various limits and resource pools that - * comprise the RNIC instance. - */ -int c2_rnic_init(struct c2_dev *c2dev) -{ - int err; - u32 qsize, msgsize; - void *q1_pages; - void *q2_pages; - void __iomem *mmio_regs; - - /* Device capabilities */ - c2dev->device_cap_flags = - (IB_DEVICE_RESIZE_MAX_WR | - IB_DEVICE_CURR_QP_STATE_MOD | - IB_DEVICE_SYS_IMAGE_GUID | - IB_DEVICE_LOCAL_DMA_LKEY | - IB_DEVICE_MEM_WINDOW); - - /* Allocate the qptr_array */ - c2dev->qptr_array = vzalloc(C2_MAX_CQS * sizeof(void *)); - if (!c2dev->qptr_array) { - return -ENOMEM; - } - - /* Initialize the qptr_array */ - c2dev->qptr_array[0] = (void *) &c2dev->req_vq; - c2dev->qptr_array[1] = (void *) &c2dev->rep_vq; - c2dev->qptr_array[2] = (void *) &c2dev->aeq; - - /* Initialize data structures */ - init_waitqueue_head(&c2dev->req_vq_wo); - spin_lock_init(&c2dev->vqlock); - spin_lock_init(&c2dev->lock); - - /* Allocate MQ shared pointer pool for kernel clients. User - * mode client pools are hung off the user context - */ - err = c2_init_mqsp_pool(c2dev, GFP_KERNEL, &c2dev->kern_mqsp_pool); - if (err) { - goto bail0; - } - - /* Allocate shared pointers for Q0, Q1, and Q2 from - * the shared pointer pool. - */ - - c2dev->hint_count = c2_alloc_mqsp(c2dev, c2dev->kern_mqsp_pool, - &c2dev->hint_count_dma, - GFP_KERNEL); - c2dev->req_vq.shared = c2_alloc_mqsp(c2dev, c2dev->kern_mqsp_pool, - &c2dev->req_vq.shared_dma, - GFP_KERNEL); - c2dev->rep_vq.shared = c2_alloc_mqsp(c2dev, c2dev->kern_mqsp_pool, - &c2dev->rep_vq.shared_dma, - GFP_KERNEL); - c2dev->aeq.shared = c2_alloc_mqsp(c2dev, c2dev->kern_mqsp_pool, - &c2dev->aeq.shared_dma, GFP_KERNEL); - if (!c2dev->hint_count || !c2dev->req_vq.shared || - !c2dev->rep_vq.shared || !c2dev->aeq.shared) { - err = -ENOMEM; - goto bail1; - } - - mmio_regs = c2dev->kva; - /* Initialize the Verbs Request Queue */ - c2_mq_req_init(&c2dev->req_vq, 0, - be32_to_cpu((__force __be32) readl(mmio_regs + C2_REGS_Q0_QSIZE)), - be32_to_cpu((__force __be32) readl(mmio_regs + C2_REGS_Q0_MSGSIZE)), - mmio_regs + - be32_to_cpu((__force __be32) readl(mmio_regs + C2_REGS_Q0_POOLSTART)), - mmio_regs + - be32_to_cpu((__force __be32) readl(mmio_regs + C2_REGS_Q0_SHARED)), - C2_MQ_ADAPTER_TARGET); - - /* Initialize the Verbs Reply Queue */ - qsize = be32_to_cpu((__force __be32) readl(mmio_regs + C2_REGS_Q1_QSIZE)); - msgsize = be32_to_cpu((__force __be32) readl(mmio_regs + C2_REGS_Q1_MSGSIZE)); - q1_pages = dma_alloc_coherent(&c2dev->pcidev->dev, qsize * msgsize, - &c2dev->rep_vq.host_dma, GFP_KERNEL); - if (!q1_pages) { - err = -ENOMEM; - goto bail1; - } - dma_unmap_addr_set(&c2dev->rep_vq, mapping, c2dev->rep_vq.host_dma); - pr_debug("%s rep_vq va %p dma %llx\n", __func__, q1_pages, - (unsigned long long) c2dev->rep_vq.host_dma); - c2_mq_rep_init(&c2dev->rep_vq, - 1, - qsize, - msgsize, - q1_pages, - mmio_regs + - be32_to_cpu((__force __be32) readl(mmio_regs + C2_REGS_Q1_SHARED)), - C2_MQ_HOST_TARGET); - - /* Initialize the Asynchronus Event Queue */ - qsize = be32_to_cpu((__force __be32) readl(mmio_regs + C2_REGS_Q2_QSIZE)); - msgsize = be32_to_cpu((__force __be32) readl(mmio_regs + C2_REGS_Q2_MSGSIZE)); - q2_pages = dma_alloc_coherent(&c2dev->pcidev->dev, qsize * msgsize, - &c2dev->aeq.host_dma, GFP_KERNEL); - if (!q2_pages) { - err = -ENOMEM; - goto bail2; - } - dma_unmap_addr_set(&c2dev->aeq, mapping, c2dev->aeq.host_dma); - pr_debug("%s aeq va %p dma %llx\n", __func__, q2_pages, - (unsigned long long) c2dev->aeq.host_dma); - c2_mq_rep_init(&c2dev->aeq, - 2, - qsize, - msgsize, - q2_pages, - mmio_regs + - be32_to_cpu((__force __be32) readl(mmio_regs + C2_REGS_Q2_SHARED)), - C2_MQ_HOST_TARGET); - - /* Initialize the verbs request allocator */ - err = vq_init(c2dev); - if (err) - goto bail3; - - /* Enable interrupts on the adapter */ - writel(0, c2dev->regs + C2_IDIS); - - /* create the WR init message */ - err = c2_adapter_init(c2dev); - if (err) - goto bail4; - c2dev->init++; - - /* open an adapter instance */ - err = c2_rnic_open(c2dev); - if (err) - goto bail4; - - /* Initialize cached the adapter limits */ - err = c2_rnic_query(c2dev, &c2dev->props); - if (err) - goto bail5; - - /* Initialize the PD pool */ - err = c2_init_pd_table(c2dev); - if (err) - goto bail5; - - /* Initialize the QP pool */ - c2_init_qp_table(c2dev); - return 0; - - bail5: - c2_rnic_close(c2dev); - bail4: - vq_term(c2dev); - bail3: - dma_free_coherent(&c2dev->pcidev->dev, - c2dev->aeq.q_size * c2dev->aeq.msg_size, - q2_pages, dma_unmap_addr(&c2dev->aeq, mapping)); - bail2: - dma_free_coherent(&c2dev->pcidev->dev, - c2dev->rep_vq.q_size * c2dev->rep_vq.msg_size, - q1_pages, dma_unmap_addr(&c2dev->rep_vq, mapping)); - bail1: - c2_free_mqsp_pool(c2dev, c2dev->kern_mqsp_pool); - bail0: - vfree(c2dev->qptr_array); - - return err; -} - -/* - * Called by c2_remove to cleanup the RNIC resources. - */ -void c2_rnic_term(struct c2_dev *c2dev) -{ - - /* Close the open adapter instance */ - c2_rnic_close(c2dev); - - /* Send the TERM message to the adapter */ - c2_adapter_term(c2dev); - - /* Disable interrupts on the adapter */ - writel(1, c2dev->regs + C2_IDIS); - - /* Free the QP pool */ - c2_cleanup_qp_table(c2dev); - - /* Free the PD pool */ - c2_cleanup_pd_table(c2dev); - - /* Free the verbs request allocator */ - vq_term(c2dev); - - /* Free the asynchronus event queue */ - dma_free_coherent(&c2dev->pcidev->dev, - c2dev->aeq.q_size * c2dev->aeq.msg_size, - c2dev->aeq.msg_pool.host, - dma_unmap_addr(&c2dev->aeq, mapping)); - - /* Free the verbs reply queue */ - dma_free_coherent(&c2dev->pcidev->dev, - c2dev->rep_vq.q_size * c2dev->rep_vq.msg_size, - c2dev->rep_vq.msg_pool.host, - dma_unmap_addr(&c2dev->rep_vq, mapping)); - - /* Free the MQ shared pointer pool */ - c2_free_mqsp_pool(c2dev, c2dev->kern_mqsp_pool); - - /* Free the qptr_array */ - vfree(c2dev->qptr_array); - - return; -} diff --git a/kernel/drivers/infiniband/hw/amso1100/c2_status.h b/kernel/drivers/infiniband/hw/amso1100/c2_status.h deleted file mode 100644 index 6ee4aa92d..000000000 --- a/kernel/drivers/infiniband/hw/amso1100/c2_status.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2005 Ammasso, Inc. All rights reserved. - * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef _C2_STATUS_H_ -#define _C2_STATUS_H_ - -/* - * Verbs Status Codes - */ -enum c2_status { - C2_OK = 0, /* This must be zero */ - CCERR_INSUFFICIENT_RESOURCES = 1, - CCERR_INVALID_MODIFIER = 2, - CCERR_INVALID_MODE = 3, - CCERR_IN_USE = 4, - CCERR_INVALID_RNIC = 5, - CCERR_INTERRUPTED_OPERATION = 6, - CCERR_INVALID_EH = 7, - CCERR_INVALID_CQ = 8, - CCERR_CQ_EMPTY = 9, - CCERR_NOT_IMPLEMENTED = 10, - CCERR_CQ_DEPTH_TOO_SMALL = 11, - CCERR_PD_IN_USE = 12, - CCERR_INVALID_PD = 13, - CCERR_INVALID_SRQ = 14, - CCERR_INVALID_ADDRESS = 15, - CCERR_INVALID_NETMASK = 16, - CCERR_INVALID_QP = 17, - CCERR_INVALID_QP_STATE = 18, - CCERR_TOO_MANY_WRS_POSTED = 19, - CCERR_INVALID_WR_TYPE = 20, - CCERR_INVALID_SGL_LENGTH = 21, - CCERR_INVALID_SQ_DEPTH = 22, - CCERR_INVALID_RQ_DEPTH = 23, - CCERR_INVALID_ORD = 24, - CCERR_INVALID_IRD = 25, - CCERR_QP_ATTR_CANNOT_CHANGE = 26, - CCERR_INVALID_STAG = 27, - CCERR_QP_IN_USE = 28, - CCERR_OUTSTANDING_WRS = 29, - CCERR_STAG_IN_USE = 30, - CCERR_INVALID_STAG_INDEX = 31, - CCERR_INVALID_SGL_FORMAT = 32, - CCERR_ADAPTER_TIMEOUT = 33, - CCERR_INVALID_CQ_DEPTH = 34, - CCERR_INVALID_PRIVATE_DATA_LENGTH = 35, - CCERR_INVALID_EP = 36, - CCERR_MR_IN_USE = CCERR_STAG_IN_USE, - CCERR_FLUSHED = 38, - CCERR_INVALID_WQE = 39, - CCERR_LOCAL_QP_CATASTROPHIC_ERROR = 40, - CCERR_REMOTE_TERMINATION_ERROR = 41, - CCERR_BASE_AND_BOUNDS_VIOLATION = 42, - CCERR_ACCESS_VIOLATION = 43, - CCERR_INVALID_PD_ID = 44, - CCERR_WRAP_ERROR = 45, - CCERR_INV_STAG_ACCESS_ERROR = 46, - CCERR_ZERO_RDMA_READ_RESOURCES = 47, - CCERR_QP_NOT_PRIVILEGED = 48, - CCERR_STAG_STATE_NOT_INVALID = 49, - CCERR_INVALID_PAGE_SIZE = 50, - CCERR_INVALID_BUFFER_SIZE = 51, - CCERR_INVALID_PBE = 52, - CCERR_INVALID_FBO = 53, - CCERR_INVALID_LENGTH = 54, - CCERR_INVALID_ACCESS_RIGHTS = 55, - CCERR_PBL_TOO_BIG = 56, - CCERR_INVALID_VA = 57, - CCERR_INVALID_REGION = 58, - CCERR_INVALID_WINDOW = 59, - CCERR_TOTAL_LENGTH_TOO_BIG = 60, - CCERR_INVALID_QP_ID = 61, - CCERR_ADDR_IN_USE = 62, - CCERR_ADDR_NOT_AVAIL = 63, - CCERR_NET_DOWN = 64, - CCERR_NET_UNREACHABLE = 65, - CCERR_CONN_ABORTED = 66, - CCERR_CONN_RESET = 67, - CCERR_NO_BUFS = 68, - CCERR_CONN_TIMEDOUT = 69, - CCERR_CONN_REFUSED = 70, - CCERR_HOST_UNREACHABLE = 71, - CCERR_INVALID_SEND_SGL_DEPTH = 72, - CCERR_INVALID_RECV_SGL_DEPTH = 73, - CCERR_INVALID_RDMA_WRITE_SGL_DEPTH = 74, - CCERR_INSUFFICIENT_PRIVILEGES = 75, - CCERR_STACK_ERROR = 76, - CCERR_INVALID_VERSION = 77, - CCERR_INVALID_MTU = 78, - CCERR_INVALID_IMAGE = 79, - CCERR_PENDING = 98, /* not an error; user internally by adapter */ - CCERR_DEFER = 99, /* not an error; used internally by adapter */ - CCERR_FAILED_WRITE = 100, - CCERR_FAILED_ERASE = 101, - CCERR_FAILED_VERIFICATION = 102, - CCERR_NOT_FOUND = 103, - -}; - -/* - * CCAE_ACTIVE_CONNECT_RESULTS status result codes. - */ -enum c2_connect_status { - C2_CONN_STATUS_SUCCESS = C2_OK, - C2_CONN_STATUS_NO_MEM = CCERR_INSUFFICIENT_RESOURCES, - C2_CONN_STATUS_TIMEDOUT = CCERR_CONN_TIMEDOUT, - C2_CONN_STATUS_REFUSED = CCERR_CONN_REFUSED, - C2_CONN_STATUS_NETUNREACH = CCERR_NET_UNREACHABLE, - C2_CONN_STATUS_HOSTUNREACH = CCERR_HOST_UNREACHABLE, - C2_CONN_STATUS_INVALID_RNIC = CCERR_INVALID_RNIC, - C2_CONN_STATUS_INVALID_QP = CCERR_INVALID_QP, - C2_CONN_STATUS_INVALID_QP_STATE = CCERR_INVALID_QP_STATE, - C2_CONN_STATUS_REJECTED = CCERR_CONN_RESET, - C2_CONN_STATUS_ADDR_NOT_AVAIL = CCERR_ADDR_NOT_AVAIL, -}; - -/* - * Flash programming status codes. - */ -enum c2_flash_status { - C2_FLASH_STATUS_SUCCESS = 0x0000, - C2_FLASH_STATUS_VERIFY_ERR = 0x0002, - C2_FLASH_STATUS_IMAGE_ERR = 0x0004, - C2_FLASH_STATUS_ECLBS = 0x0400, - C2_FLASH_STATUS_PSLBS = 0x0800, - C2_FLASH_STATUS_VPENS = 0x1000, -}; - -#endif /* _C2_STATUS_H_ */ diff --git a/kernel/drivers/infiniband/hw/amso1100/c2_user.h b/kernel/drivers/infiniband/hw/amso1100/c2_user.h deleted file mode 100644 index 7e9e7ad65..000000000 --- a/kernel/drivers/infiniband/hw/amso1100/c2_user.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2005 Topspin Communications. All rights reserved. - * Copyright (c) 2005 Cisco Systems. All rights reserved. - * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#ifndef C2_USER_H -#define C2_USER_H - -#include <linux/types.h> - -/* - * Make sure that all structs defined in this file remain laid out so - * that they pack the same way on 32-bit and 64-bit architectures (to - * avoid incompatibility between 32-bit userspace and 64-bit kernels). - * In particular do not use pointer types -- pass pointers in __u64 - * instead. - */ - -struct c2_alloc_ucontext_resp { - __u32 qp_tab_size; - __u32 uarc_size; -}; - -struct c2_alloc_pd_resp { - __u32 pdn; - __u32 reserved; -}; - -struct c2_create_cq { - __u32 lkey; - __u32 pdn; - __u64 arm_db_page; - __u64 set_db_page; - __u32 arm_db_index; - __u32 set_db_index; -}; - -struct c2_create_cq_resp { - __u32 cqn; - __u32 reserved; -}; - -struct c2_create_qp { - __u32 lkey; - __u32 reserved; - __u64 sq_db_page; - __u64 rq_db_page; - __u32 sq_db_index; - __u32 rq_db_index; -}; - -#endif /* C2_USER_H */ diff --git a/kernel/drivers/infiniband/hw/amso1100/c2_vq.c b/kernel/drivers/infiniband/hw/amso1100/c2_vq.c deleted file mode 100644 index 2ec716fb2..000000000 --- a/kernel/drivers/infiniband/hw/amso1100/c2_vq.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (c) 2005 Ammasso, Inc. All rights reserved. - * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include <linux/slab.h> -#include <linux/spinlock.h> - -#include "c2_vq.h" -#include "c2_provider.h" - -/* - * Verbs Request Objects: - * - * VQ Request Objects are allocated by the kernel verbs handlers. - * They contain a wait object, a refcnt, an atomic bool indicating that the - * adapter has replied, and a copy of the verb reply work request. - * A pointer to the VQ Request Object is passed down in the context - * field of the work request message, and reflected back by the adapter - * in the verbs reply message. The function handle_vq() in the interrupt - * path will use this pointer to: - * 1) append a copy of the verbs reply message - * 2) mark that the reply is ready - * 3) wake up the kernel verbs handler blocked awaiting the reply. - * - * - * The kernel verbs handlers do a "get" to put a 2nd reference on the - * VQ Request object. If the kernel verbs handler exits before the adapter - * can respond, this extra reference will keep the VQ Request object around - * until the adapter's reply can be processed. The reason we need this is - * because a pointer to this object is stuffed into the context field of - * the verbs work request message, and reflected back in the reply message. - * It is used in the interrupt handler (handle_vq()) to wake up the appropriate - * kernel verb handler that is blocked awaiting the verb reply. - * So handle_vq() will do a "put" on the object when it's done accessing it. - * NOTE: If we guarantee that the kernel verb handler will never bail before - * getting the reply, then we don't need these refcnts. - * - * - * VQ Request objects are freed by the kernel verbs handlers only - * after the verb has been processed, or when the adapter fails and - * does not reply. - * - * - * Verbs Reply Buffers: - * - * VQ Reply bufs are local host memory copies of a - * outstanding Verb Request reply - * message. The are always allocated by the kernel verbs handlers, and _may_ be - * freed by either the kernel verbs handler -or- the interrupt handler. The - * kernel verbs handler _must_ free the repbuf, then free the vq request object - * in that order. - */ - -int vq_init(struct c2_dev *c2dev) -{ - sprintf(c2dev->vq_cache_name, "c2-vq:dev%c", - (char) ('0' + c2dev->devnum)); - c2dev->host_msg_cache = - kmem_cache_create(c2dev->vq_cache_name, c2dev->rep_vq.msg_size, 0, - SLAB_HWCACHE_ALIGN, NULL); - if (c2dev->host_msg_cache == NULL) { - return -ENOMEM; - } - return 0; -} - -void vq_term(struct c2_dev *c2dev) -{ - kmem_cache_destroy(c2dev->host_msg_cache); -} - -/* vq_req_alloc - allocate a VQ Request Object and initialize it. - * The refcnt is set to 1. - */ -struct c2_vq_req *vq_req_alloc(struct c2_dev *c2dev) -{ - struct c2_vq_req *r; - - r = kmalloc(sizeof(struct c2_vq_req), GFP_KERNEL); - if (r) { - init_waitqueue_head(&r->wait_object); - r->reply_msg = 0; - r->event = 0; - r->cm_id = NULL; - r->qp = NULL; - atomic_set(&r->refcnt, 1); - atomic_set(&r->reply_ready, 0); - } - return r; -} - - -/* vq_req_free - free the VQ Request Object. It is assumed the verbs handler - * has already free the VQ Reply Buffer if it existed. - */ -void vq_req_free(struct c2_dev *c2dev, struct c2_vq_req *r) -{ - r->reply_msg = 0; - if (atomic_dec_and_test(&r->refcnt)) { - kfree(r); - } -} - -/* vq_req_get - reference a VQ Request Object. Done - * only in the kernel verbs handlers. - */ -void vq_req_get(struct c2_dev *c2dev, struct c2_vq_req *r) -{ - atomic_inc(&r->refcnt); -} - - -/* vq_req_put - dereference and potentially free a VQ Request Object. - * - * This is only called by handle_vq() on the - * interrupt when it is done processing - * a verb reply message. If the associated - * kernel verbs handler has already bailed, - * then this put will actually free the VQ - * Request object _and_ the VQ Reply Buffer - * if it exists. - */ -void vq_req_put(struct c2_dev *c2dev, struct c2_vq_req *r) -{ - if (atomic_dec_and_test(&r->refcnt)) { - if (r->reply_msg != 0) - vq_repbuf_free(c2dev, - (void *) (unsigned long) r->reply_msg); - kfree(r); - } -} - - -/* - * vq_repbuf_alloc - allocate a VQ Reply Buffer. - */ -void *vq_repbuf_alloc(struct c2_dev *c2dev) -{ - return kmem_cache_alloc(c2dev->host_msg_cache, GFP_ATOMIC); -} - -/* - * vq_send_wr - post a verbs request message to the Verbs Request Queue. - * If a message is not available in the MQ, then block until one is available. - * NOTE: handle_mq() on the interrupt context will wake up threads blocked here. - * When the adapter drains the Verbs Request Queue, - * it inserts MQ index 0 in to the - * adapter->host activity fifo and interrupts the host. - */ -int vq_send_wr(struct c2_dev *c2dev, union c2wr *wr) -{ - void *msg; - wait_queue_t __wait; - - /* - * grab adapter vq lock - */ - spin_lock(&c2dev->vqlock); - - /* - * allocate msg - */ - msg = c2_mq_alloc(&c2dev->req_vq); - - /* - * If we cannot get a msg, then we'll wait - * When a messages are available, the int handler will wake_up() - * any waiters. - */ - while (msg == NULL) { - pr_debug("%s:%d no available msg in VQ, waiting...\n", - __func__, __LINE__); - init_waitqueue_entry(&__wait, current); - add_wait_queue(&c2dev->req_vq_wo, &__wait); - spin_unlock(&c2dev->vqlock); - for (;;) { - set_current_state(TASK_INTERRUPTIBLE); - if (!c2_mq_full(&c2dev->req_vq)) { - break; - } - if (!signal_pending(current)) { - schedule_timeout(1 * HZ); /* 1 second... */ - continue; - } - set_current_state(TASK_RUNNING); - remove_wait_queue(&c2dev->req_vq_wo, &__wait); - return -EINTR; - } - set_current_state(TASK_RUNNING); - remove_wait_queue(&c2dev->req_vq_wo, &__wait); - spin_lock(&c2dev->vqlock); - msg = c2_mq_alloc(&c2dev->req_vq); - } - - /* - * copy wr into adapter msg - */ - memcpy(msg, wr, c2dev->req_vq.msg_size); - - /* - * post msg - */ - c2_mq_produce(&c2dev->req_vq); - - /* - * release adapter vq lock - */ - spin_unlock(&c2dev->vqlock); - return 0; -} - - -/* - * vq_wait_for_reply - block until the adapter posts a Verb Reply Message. - */ -int vq_wait_for_reply(struct c2_dev *c2dev, struct c2_vq_req *req) -{ - if (!wait_event_timeout(req->wait_object, - atomic_read(&req->reply_ready), - 60*HZ)) - return -ETIMEDOUT; - - return 0; -} - -/* - * vq_repbuf_free - Free a Verbs Reply Buffer. - */ -void vq_repbuf_free(struct c2_dev *c2dev, void *reply) -{ - kmem_cache_free(c2dev->host_msg_cache, reply); -} diff --git a/kernel/drivers/infiniband/hw/amso1100/c2_vq.h b/kernel/drivers/infiniband/hw/amso1100/c2_vq.h deleted file mode 100644 index 33805627a..000000000 --- a/kernel/drivers/infiniband/hw/amso1100/c2_vq.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2005 Ammasso, Inc. All rights reserved. - * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef _C2_VQ_H_ -#define _C2_VQ_H_ -#include <linux/sched.h> -#include "c2.h" -#include "c2_wr.h" -#include "c2_provider.h" - -struct c2_vq_req { - u64 reply_msg; /* ptr to reply msg */ - wait_queue_head_t wait_object; /* wait object for vq reqs */ - atomic_t reply_ready; /* set when reply is ready */ - atomic_t refcnt; /* used to cancel WRs... */ - int event; - struct iw_cm_id *cm_id; - struct c2_qp *qp; -}; - -extern int vq_init(struct c2_dev *c2dev); -extern void vq_term(struct c2_dev *c2dev); - -extern struct c2_vq_req *vq_req_alloc(struct c2_dev *c2dev); -extern void vq_req_free(struct c2_dev *c2dev, struct c2_vq_req *req); -extern void vq_req_get(struct c2_dev *c2dev, struct c2_vq_req *req); -extern void vq_req_put(struct c2_dev *c2dev, struct c2_vq_req *req); -extern int vq_send_wr(struct c2_dev *c2dev, union c2wr * wr); - -extern void *vq_repbuf_alloc(struct c2_dev *c2dev); -extern void vq_repbuf_free(struct c2_dev *c2dev, void *reply); - -extern int vq_wait_for_reply(struct c2_dev *c2dev, struct c2_vq_req *req); -#endif /* _C2_VQ_H_ */ diff --git a/kernel/drivers/infiniband/hw/amso1100/c2_wr.h b/kernel/drivers/infiniband/hw/amso1100/c2_wr.h deleted file mode 100644 index 8d4b4ca46..000000000 --- a/kernel/drivers/infiniband/hw/amso1100/c2_wr.h +++ /dev/null @@ -1,1520 +0,0 @@ -/* - * Copyright (c) 2005 Ammasso, Inc. All rights reserved. - * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * OpenIB.org BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef _C2_WR_H_ -#define _C2_WR_H_ - -#ifdef CCDEBUG -#define CCWR_MAGIC 0xb07700b0 -#endif - -#define C2_QP_NO_ATTR_CHANGE 0xFFFFFFFF - -/* Maximum allowed size in bytes of private_data exchange - * on connect. - */ -#define C2_MAX_PRIVATE_DATA_SIZE 200 - -/* - * These types are shared among the adapter, host, and CCIL consumer. - */ -enum c2_cq_notification_type { - C2_CQ_NOTIFICATION_TYPE_NONE = 1, - C2_CQ_NOTIFICATION_TYPE_NEXT, - C2_CQ_NOTIFICATION_TYPE_NEXT_SE -}; - -enum c2_setconfig_cmd { - C2_CFG_ADD_ADDR = 1, - C2_CFG_DEL_ADDR = 2, - C2_CFG_ADD_ROUTE = 3, - C2_CFG_DEL_ROUTE = 4 -}; - -enum c2_getconfig_cmd { - C2_GETCONFIG_ROUTES = 1, - C2_GETCONFIG_ADDRS -}; - -/* - * CCIL Work Request Identifiers - */ -enum c2wr_ids { - CCWR_RNIC_OPEN = 1, - CCWR_RNIC_QUERY, - CCWR_RNIC_SETCONFIG, - CCWR_RNIC_GETCONFIG, - CCWR_RNIC_CLOSE, - CCWR_CQ_CREATE, - CCWR_CQ_QUERY, - CCWR_CQ_MODIFY, - CCWR_CQ_DESTROY, - CCWR_QP_CONNECT, - CCWR_PD_ALLOC, - CCWR_PD_DEALLOC, - CCWR_SRQ_CREATE, - CCWR_SRQ_QUERY, - CCWR_SRQ_MODIFY, - CCWR_SRQ_DESTROY, - CCWR_QP_CREATE, - CCWR_QP_QUERY, - CCWR_QP_MODIFY, - CCWR_QP_DESTROY, - CCWR_NSMR_STAG_ALLOC, - CCWR_NSMR_REGISTER, - CCWR_NSMR_PBL, - CCWR_STAG_DEALLOC, - CCWR_NSMR_REREGISTER, - CCWR_SMR_REGISTER, - CCWR_MR_QUERY, - CCWR_MW_ALLOC, - CCWR_MW_QUERY, - CCWR_EP_CREATE, - CCWR_EP_GETOPT, - CCWR_EP_SETOPT, - CCWR_EP_DESTROY, - CCWR_EP_BIND, - CCWR_EP_CONNECT, - CCWR_EP_LISTEN, - CCWR_EP_SHUTDOWN, - CCWR_EP_LISTEN_CREATE, - CCWR_EP_LISTEN_DESTROY, - CCWR_EP_QUERY, - CCWR_CR_ACCEPT, - CCWR_CR_REJECT, - CCWR_CONSOLE, - CCWR_TERM, - CCWR_FLASH_INIT, - CCWR_FLASH, - CCWR_BUF_ALLOC, - CCWR_BUF_FREE, - CCWR_FLASH_WRITE, - CCWR_INIT, /* WARNING: Don't move this ever again! */ - - - - /* Add new IDs here */ - - - - /* - * WARNING: CCWR_LAST must always be the last verbs id defined! - * All the preceding IDs are fixed, and must not change. - * You can add new IDs, but must not remove or reorder - * any IDs. If you do, YOU will ruin any hope of - * compatibility between versions. - */ - CCWR_LAST, - - /* - * Start over at 1 so that arrays indexed by user wr id's - * begin at 1. This is OK since the verbs and user wr id's - * are always used on disjoint sets of queues. - */ - /* - * The order of the CCWR_SEND_XX verbs must - * match the order of the RDMA_OPs - */ - CCWR_SEND = 1, - CCWR_SEND_INV, - CCWR_SEND_SE, - CCWR_SEND_SE_INV, - CCWR_RDMA_WRITE, - CCWR_RDMA_READ, - CCWR_RDMA_READ_INV, - CCWR_MW_BIND, - CCWR_NSMR_FASTREG, - CCWR_STAG_INVALIDATE, - CCWR_RECV, - CCWR_NOP, - CCWR_UNIMPL, -/* WARNING: This must always be the last user wr id defined! */ -}; -#define RDMA_SEND_OPCODE_FROM_WR_ID(x) (x+2) - -/* - * SQ/RQ Work Request Types - */ -enum c2_wr_type { - C2_WR_TYPE_SEND = CCWR_SEND, - C2_WR_TYPE_SEND_SE = CCWR_SEND_SE, - C2_WR_TYPE_SEND_INV = CCWR_SEND_INV, - C2_WR_TYPE_SEND_SE_INV = CCWR_SEND_SE_INV, - C2_WR_TYPE_RDMA_WRITE = CCWR_RDMA_WRITE, - C2_WR_TYPE_RDMA_READ = CCWR_RDMA_READ, - C2_WR_TYPE_RDMA_READ_INV_STAG = CCWR_RDMA_READ_INV, - C2_WR_TYPE_BIND_MW = CCWR_MW_BIND, - C2_WR_TYPE_FASTREG_NSMR = CCWR_NSMR_FASTREG, - C2_WR_TYPE_INV_STAG = CCWR_STAG_INVALIDATE, - C2_WR_TYPE_RECV = CCWR_RECV, - C2_WR_TYPE_NOP = CCWR_NOP, -}; - -struct c2_netaddr { - __be32 ip_addr; - __be32 netmask; - u32 mtu; -}; - -struct c2_route { - u32 ip_addr; /* 0 indicates the default route */ - u32 netmask; /* netmask associated with dst */ - u32 flags; - union { - u32 ipaddr; /* address of the nexthop interface */ - u8 enaddr[6]; - } nexthop; -}; - -/* - * A Scatter Gather Entry. - */ -struct c2_data_addr { - __be32 stag; - __be32 length; - __be64 to; -}; - -/* - * MR and MW flags used by the consumer, RI, and RNIC. - */ -enum c2_mm_flags { - MEM_REMOTE = 0x0001, /* allow mw binds with remote access. */ - MEM_VA_BASED = 0x0002, /* Not Zero-based */ - MEM_PBL_COMPLETE = 0x0004, /* PBL array is complete in this msg */ - MEM_LOCAL_READ = 0x0008, /* allow local reads */ - MEM_LOCAL_WRITE = 0x0010, /* allow local writes */ - MEM_REMOTE_READ = 0x0020, /* allow remote reads */ - MEM_REMOTE_WRITE = 0x0040, /* allow remote writes */ - MEM_WINDOW_BIND = 0x0080, /* binds allowed */ - MEM_SHARED = 0x0100, /* set if MR is shared */ - MEM_STAG_VALID = 0x0200 /* set if STAG is in valid state */ -}; - -/* - * CCIL API ACF flags defined in terms of the low level mem flags. - * This minimizes translation needed in the user API - */ -enum c2_acf { - C2_ACF_LOCAL_READ = MEM_LOCAL_READ, - C2_ACF_LOCAL_WRITE = MEM_LOCAL_WRITE, - C2_ACF_REMOTE_READ = MEM_REMOTE_READ, - C2_ACF_REMOTE_WRITE = MEM_REMOTE_WRITE, - C2_ACF_WINDOW_BIND = MEM_WINDOW_BIND -}; - -/* - * Image types of objects written to flash - */ -#define C2_FLASH_IMG_BITFILE 1 -#define C2_FLASH_IMG_OPTION_ROM 2 -#define C2_FLASH_IMG_VPD 3 - -/* - * to fix bug 1815 we define the max size allowable of the - * terminate message (per the IETF spec).Refer to the IETF - * protocol specification, section 12.1.6, page 64) - * The message is prefixed by 20 types of DDP info. - * - * Then the message has 6 bytes for the terminate control - * and DDP segment length info plus a DDP header (either - * 14 or 18 byts) plus 28 bytes for the RDMA header. - * Thus the max size in: - * 20 + (6 + 18 + 28) = 72 - */ -#define C2_MAX_TERMINATE_MESSAGE_SIZE (72) - -/* - * Build String Length. It must be the same as C2_BUILD_STR_LEN in ccil_api.h - */ -#define WR_BUILD_STR_LEN 64 - -/* - * WARNING: All of these structs need to align any 64bit types on - * 64 bit boundaries! 64bit types include u64 and u64. - */ - -/* - * Clustercore Work Request Header. Be sensitive to field layout - * and alignment. - */ -struct c2wr_hdr { - /* wqe_count is part of the cqe. It is put here so the - * adapter can write to it while the wr is pending without - * clobbering part of the wr. This word need not be dma'd - * from the host to adapter by libccil, but we copy it anyway - * to make the memcpy to the adapter better aligned. - */ - __be32 wqe_count; - - /* Put these fields next so that later 32- and 64-bit - * quantities are naturally aligned. - */ - u8 id; - u8 result; /* adapter -> host */ - u8 sge_count; /* host -> adapter */ - u8 flags; /* host -> adapter */ - - u64 context; -#ifdef CCMSGMAGIC - u32 magic; - u32 pad; -#endif -} __attribute__((packed)); - -/* - *------------------------ RNIC ------------------------ - */ - -/* - * WR_RNIC_OPEN - */ - -/* - * Flags for the RNIC WRs - */ -enum c2_rnic_flags { - RNIC_IRD_STATIC = 0x0001, - RNIC_ORD_STATIC = 0x0002, - RNIC_QP_STATIC = 0x0004, - RNIC_SRQ_SUPPORTED = 0x0008, - RNIC_PBL_BLOCK_MODE = 0x0010, - RNIC_SRQ_MODEL_ARRIVAL = 0x0020, - RNIC_CQ_OVF_DETECTED = 0x0040, - RNIC_PRIV_MODE = 0x0080 -}; - -struct c2wr_rnic_open_req { - struct c2wr_hdr hdr; - u64 user_context; - __be16 flags; /* See enum c2_rnic_flags */ - __be16 port_num; -} __attribute__((packed)); - -struct c2wr_rnic_open_rep { - struct c2wr_hdr hdr; - u32 rnic_handle; -} __attribute__((packed)); - -union c2wr_rnic_open { - struct c2wr_rnic_open_req req; - struct c2wr_rnic_open_rep rep; -} __attribute__((packed)); - -struct c2wr_rnic_query_req { - struct c2wr_hdr hdr; - u32 rnic_handle; -} __attribute__((packed)); - -/* - * WR_RNIC_QUERY - */ -struct c2wr_rnic_query_rep { - struct c2wr_hdr hdr; - u64 user_context; - __be32 vendor_id; - __be32 part_number; - __be32 hw_version; - __be32 fw_ver_major; - __be32 fw_ver_minor; - __be32 fw_ver_patch; - char fw_ver_build_str[WR_BUILD_STR_LEN]; - __be32 max_qps; - __be32 max_qp_depth; - u32 max_srq_depth; - u32 max_send_sgl_depth; - u32 max_rdma_sgl_depth; - __be32 max_cqs; - __be32 max_cq_depth; - u32 max_cq_event_handlers; - __be32 max_mrs; - u32 max_pbl_depth; - __be32 max_pds; - __be32 max_global_ird; - u32 max_global_ord; - __be32 max_qp_ird; - __be32 max_qp_ord; - u32 flags; - __be32 max_mws; - u32 pbe_range_low; - u32 pbe_range_high; - u32 max_srqs; - u32 page_size; -} __attribute__((packed)); - -union c2wr_rnic_query { - struct c2wr_rnic_query_req req; - struct c2wr_rnic_query_rep rep; -} __attribute__((packed)); - -/* - * WR_RNIC_GETCONFIG - */ - -struct c2wr_rnic_getconfig_req { - struct c2wr_hdr hdr; - u32 rnic_handle; - u32 option; /* see c2_getconfig_cmd_t */ - u64 reply_buf; - u32 reply_buf_len; -} __attribute__((packed)) ; - -struct c2wr_rnic_getconfig_rep { - struct c2wr_hdr hdr; - u32 option; /* see c2_getconfig_cmd_t */ - u32 count_len; /* length of the number of addresses configured */ -} __attribute__((packed)) ; - -union c2wr_rnic_getconfig { - struct c2wr_rnic_getconfig_req req; - struct c2wr_rnic_getconfig_rep rep; -} __attribute__((packed)) ; - -/* - * WR_RNIC_SETCONFIG - */ -struct c2wr_rnic_setconfig_req { - struct c2wr_hdr hdr; - u32 rnic_handle; - __be32 option; /* See c2_setconfig_cmd_t */ - /* variable data and pad. See c2_netaddr and c2_route */ - u8 data[0]; -} __attribute__((packed)) ; - -struct c2wr_rnic_setconfig_rep { - struct c2wr_hdr hdr; -} __attribute__((packed)) ; - -union c2wr_rnic_setconfig { - struct c2wr_rnic_setconfig_req req; - struct c2wr_rnic_setconfig_rep rep; -} __attribute__((packed)) ; - -/* - * WR_RNIC_CLOSE - */ -struct c2wr_rnic_close_req { - struct c2wr_hdr hdr; - u32 rnic_handle; -} __attribute__((packed)) ; - -struct c2wr_rnic_close_rep { - struct c2wr_hdr hdr; -} __attribute__((packed)) ; - -union c2wr_rnic_close { - struct c2wr_rnic_close_req req; - struct c2wr_rnic_close_rep rep; -} __attribute__((packed)) ; - -/* - *------------------------ CQ ------------------------ - */ -struct c2wr_cq_create_req { - struct c2wr_hdr hdr; - __be64 shared_ht; - u64 user_context; - __be64 msg_pool; - u32 rnic_handle; - __be32 msg_size; - __be32 depth; -} __attribute__((packed)) ; - -struct c2wr_cq_create_rep { - struct c2wr_hdr hdr; - __be32 mq_index; - __be32 adapter_shared; - u32 cq_handle; -} __attribute__((packed)) ; - -union c2wr_cq_create { - struct c2wr_cq_create_req req; - struct c2wr_cq_create_rep rep; -} __attribute__((packed)) ; - -struct c2wr_cq_modify_req { - struct c2wr_hdr hdr; - u32 rnic_handle; - u32 cq_handle; - u32 new_depth; - u64 new_msg_pool; -} __attribute__((packed)) ; - -struct c2wr_cq_modify_rep { - struct c2wr_hdr hdr; -} __attribute__((packed)) ; - -union c2wr_cq_modify { - struct c2wr_cq_modify_req req; - struct c2wr_cq_modify_rep rep; -} __attribute__((packed)) ; - -struct c2wr_cq_destroy_req { - struct c2wr_hdr hdr; - u32 rnic_handle; - u32 cq_handle; -} __attribute__((packed)) ; - -struct c2wr_cq_destroy_rep { - struct c2wr_hdr hdr; -} __attribute__((packed)) ; - -union c2wr_cq_destroy { - struct c2wr_cq_destroy_req req; - struct c2wr_cq_destroy_rep rep; -} __attribute__((packed)) ; - -/* - *------------------------ PD ------------------------ - */ -struct c2wr_pd_alloc_req { - struct c2wr_hdr hdr; - u32 rnic_handle; - u32 pd_id; -} __attribute__((packed)) ; - -struct c2wr_pd_alloc_rep { - struct c2wr_hdr hdr; -} __attribute__((packed)) ; - -union c2wr_pd_alloc { - struct c2wr_pd_alloc_req req; - struct c2wr_pd_alloc_rep rep; -} __attribute__((packed)) ; - -struct c2wr_pd_dealloc_req { - struct c2wr_hdr hdr; - u32 rnic_handle; - u32 pd_id; -} __attribute__((packed)) ; - -struct c2wr_pd_dealloc_rep { - struct c2wr_hdr hdr; -} __attribute__((packed)) ; - -union c2wr_pd_dealloc { - struct c2wr_pd_dealloc_req req; - struct c2wr_pd_dealloc_rep rep; -} __attribute__((packed)) ; - -/* - *------------------------ SRQ ------------------------ - */ -struct c2wr_srq_create_req { - struct c2wr_hdr hdr; - u64 shared_ht; - u64 user_context; - u32 rnic_handle; - u32 srq_depth; - u32 srq_limit; - u32 sgl_depth; - u32 pd_id; -} __attribute__((packed)) ; - -struct c2wr_srq_create_rep { - struct c2wr_hdr hdr; - u32 srq_depth; - u32 sgl_depth; - u32 msg_size; - u32 mq_index; - u32 mq_start; - u32 srq_handle; -} __attribute__((packed)) ; - -union c2wr_srq_create { - struct c2wr_srq_create_req req; - struct c2wr_srq_create_rep rep; -} __attribute__((packed)) ; - -struct c2wr_srq_destroy_req { - struct c2wr_hdr hdr; - u32 rnic_handle; - u32 srq_handle; -} __attribute__((packed)) ; - -struct c2wr_srq_destroy_rep { - struct c2wr_hdr hdr; -} __attribute__((packed)) ; - -union c2wr_srq_destroy { - struct c2wr_srq_destroy_req req; - struct c2wr_srq_destroy_rep rep; -} __attribute__((packed)) ; - -/* - *------------------------ QP ------------------------ - */ -enum c2wr_qp_flags { - QP_RDMA_READ = 0x00000001, /* RDMA read enabled? */ - QP_RDMA_WRITE = 0x00000002, /* RDMA write enabled? */ - QP_MW_BIND = 0x00000004, /* MWs enabled */ - QP_ZERO_STAG = 0x00000008, /* enabled? */ - QP_REMOTE_TERMINATION = 0x00000010, /* remote end terminated */ - QP_RDMA_READ_RESPONSE = 0x00000020 /* Remote RDMA read */ - /* enabled? */ -}; - -struct c2wr_qp_create_req { - struct c2wr_hdr hdr; - __be64 shared_sq_ht; - __be64 shared_rq_ht; - u64 user_context; - u32 rnic_handle; - u32 sq_cq_handle; - u32 rq_cq_handle; - __be32 sq_depth; - __be32 rq_depth; - u32 srq_handle; - u32 srq_limit; - __be32 flags; /* see enum c2wr_qp_flags */ - __be32 send_sgl_depth; - __be32 recv_sgl_depth; - __be32 rdma_write_sgl_depth; - __be32 ord; - __be32 ird; - u32 pd_id; -} __attribute__((packed)) ; - -struct c2wr_qp_create_rep { - struct c2wr_hdr hdr; - __be32 sq_depth; - __be32 rq_depth; - u32 send_sgl_depth; - u32 recv_sgl_depth; - u32 rdma_write_sgl_depth; - u32 ord; - u32 ird; - __be32 sq_msg_size; - __be32 sq_mq_index; - __be32 sq_mq_start; - __be32 rq_msg_size; - __be32 rq_mq_index; - __be32 rq_mq_start; - u32 qp_handle; -} __attribute__((packed)) ; - -union c2wr_qp_create { - struct c2wr_qp_create_req req; - struct c2wr_qp_create_rep rep; -} __attribute__((packed)) ; - -struct c2wr_qp_query_req { - struct c2wr_hdr hdr; - u32 rnic_handle; - u32 qp_handle; -} __attribute__((packed)) ; - -struct c2wr_qp_query_rep { - struct c2wr_hdr hdr; - u64 user_context; - u32 rnic_handle; - u32 sq_depth; - u32 rq_depth; - u32 send_sgl_depth; - u32 rdma_write_sgl_depth; - u32 recv_sgl_depth; - u32 ord; - u32 ird; - u16 qp_state; - u16 flags; /* see c2wr_qp_flags_t */ - u32 qp_id; - u32 local_addr; - u32 remote_addr; - u16 local_port; - u16 remote_port; - u32 terminate_msg_length; /* 0 if not present */ - u8 data[0]; - /* Terminate Message in-line here. */ -} __attribute__((packed)) ; - -union c2wr_qp_query { - struct c2wr_qp_query_req req; - struct c2wr_qp_query_rep rep; -} __attribute__((packed)) ; - -struct c2wr_qp_modify_req { - struct c2wr_hdr hdr; - u64 stream_msg; - u32 stream_msg_length; - u32 rnic_handle; - u32 qp_handle; - __be32 next_qp_state; - __be32 ord; - __be32 ird; - __be32 sq_depth; - __be32 rq_depth; - u32 llp_ep_handle; -} __attribute__((packed)) ; - -struct c2wr_qp_modify_rep { - struct c2wr_hdr hdr; - u32 ord; - u32 ird; - u32 sq_depth; - u32 rq_depth; - u32 sq_msg_size; - u32 sq_mq_index; - u32 sq_mq_start; - u32 rq_msg_size; - u32 rq_mq_index; - u32 rq_mq_start; -} __attribute__((packed)) ; - -union c2wr_qp_modify { - struct c2wr_qp_modify_req req; - struct c2wr_qp_modify_rep rep; -} __attribute__((packed)) ; - -struct c2wr_qp_destroy_req { - struct c2wr_hdr hdr; - u32 rnic_handle; - u32 qp_handle; -} __attribute__((packed)) ; - -struct c2wr_qp_destroy_rep { - struct c2wr_hdr hdr; -} __attribute__((packed)) ; - -union c2wr_qp_destroy { - struct c2wr_qp_destroy_req req; - struct c2wr_qp_destroy_rep rep; -} __attribute__((packed)) ; - -/* - * The CCWR_QP_CONNECT msg is posted on the verbs request queue. It can - * only be posted when a QP is in IDLE state. After the connect request is - * submitted to the LLP, the adapter moves the QP to CONNECT_PENDING state. - * No synchronous reply from adapter to this WR. The results of - * connection are passed back in an async event CCAE_ACTIVE_CONNECT_RESULTS - * See c2wr_ae_active_connect_results_t - */ -struct c2wr_qp_connect_req { - struct c2wr_hdr hdr; - u32 rnic_handle; - u32 qp_handle; - __be32 remote_addr; - __be16 remote_port; - u16 pad; - __be32 private_data_length; - u8 private_data[0]; /* Private data in-line. */ -} __attribute__((packed)) ; - -struct c2wr_qp_connect { - struct c2wr_qp_connect_req req; - /* no synchronous reply. */ -} __attribute__((packed)) ; - - -/* - *------------------------ MM ------------------------ - */ - -struct c2wr_nsmr_stag_alloc_req { - struct c2wr_hdr hdr; - u32 rnic_handle; - u32 pbl_depth; - u32 pd_id; - u32 flags; -} __attribute__((packed)) ; - -struct c2wr_nsmr_stag_alloc_rep { - struct c2wr_hdr hdr; - u32 pbl_depth; - u32 stag_index; -} __attribute__((packed)) ; - -union c2wr_nsmr_stag_alloc { - struct c2wr_nsmr_stag_alloc_req req; - struct c2wr_nsmr_stag_alloc_rep rep; -} __attribute__((packed)) ; - -struct c2wr_nsmr_register_req { - struct c2wr_hdr hdr; - __be64 va; - u32 rnic_handle; - __be16 flags; - u8 stag_key; - u8 pad; - u32 pd_id; - __be32 pbl_depth; - __be32 pbe_size; - __be32 fbo; - __be32 length; - __be32 addrs_length; - /* array of paddrs (must be aligned on a 64bit boundary) */ - __be64 paddrs[0]; -} __attribute__((packed)) ; - -struct c2wr_nsmr_register_rep { - struct c2wr_hdr hdr; - u32 pbl_depth; - __be32 stag_index; -} __attribute__((packed)) ; - -union c2wr_nsmr_register { - struct c2wr_nsmr_register_req req; - struct c2wr_nsmr_register_rep rep; -} __attribute__((packed)) ; - -struct c2wr_nsmr_pbl_req { - struct c2wr_hdr hdr; - u32 rnic_handle; - __be32 flags; - __be32 stag_index; - __be32 addrs_length; - /* array of paddrs (must be aligned on a 64bit boundary) */ - __be64 paddrs[0]; -} __attribute__((packed)) ; - -struct c2wr_nsmr_pbl_rep { - struct c2wr_hdr hdr; -} __attribute__((packed)) ; - -union c2wr_nsmr_pbl { - struct c2wr_nsmr_pbl_req req; - struct c2wr_nsmr_pbl_rep rep; -} __attribute__((packed)) ; - -struct c2wr_mr_query_req { - struct c2wr_hdr hdr; - u32 rnic_handle; - u32 stag_index; -} __attribute__((packed)) ; - -struct c2wr_mr_query_rep { - struct c2wr_hdr hdr; - u8 stag_key; - u8 pad[3]; - u32 pd_id; - u32 flags; - u32 pbl_depth; -} __attribute__((packed)) ; - -union c2wr_mr_query { - struct c2wr_mr_query_req req; - struct c2wr_mr_query_rep rep; -} __attribute__((packed)) ; - -struct c2wr_mw_query_req { - struct c2wr_hdr hdr; - u32 rnic_handle; - u32 stag_index; -} __attribute__((packed)) ; - -struct c2wr_mw_query_rep { - struct c2wr_hdr hdr; - u8 stag_key; - u8 pad[3]; - u32 pd_id; - u32 flags; -} __attribute__((packed)) ; - -union c2wr_mw_query { - struct c2wr_mw_query_req req; - struct c2wr_mw_query_rep rep; -} __attribute__((packed)) ; - - -struct c2wr_stag_dealloc_req { - struct c2wr_hdr hdr; - u32 rnic_handle; - __be32 stag_index; -} __attribute__((packed)) ; - -struct c2wr_stag_dealloc_rep { - struct c2wr_hdr hdr; -} __attribute__((packed)) ; - -union c2wr_stag_dealloc { - struct c2wr_stag_dealloc_req req; - struct c2wr_stag_dealloc_rep rep; -} __attribute__((packed)) ; - -struct c2wr_nsmr_reregister_req { - struct c2wr_hdr hdr; - u64 va; - u32 rnic_handle; - u16 flags; - u8 stag_key; - u8 pad; - u32 stag_index; - u32 pd_id; - u32 pbl_depth; - u32 pbe_size; - u32 fbo; - u32 length; - u32 addrs_length; - u32 pad1; - /* array of paddrs (must be aligned on a 64bit boundary) */ - u64 paddrs[0]; -} __attribute__((packed)) ; - -struct c2wr_nsmr_reregister_rep { - struct c2wr_hdr hdr; - u32 pbl_depth; - u32 stag_index; -} __attribute__((packed)) ; - -union c2wr_nsmr_reregister { - struct c2wr_nsmr_reregister_req req; - struct c2wr_nsmr_reregister_rep rep; -} __attribute__((packed)) ; - -struct c2wr_smr_register_req { - struct c2wr_hdr hdr; - u64 va; - u32 rnic_handle; - u16 flags; - u8 stag_key; - u8 pad; - u32 stag_index; - u32 pd_id; -} __attribute__((packed)) ; - -struct c2wr_smr_register_rep { - struct c2wr_hdr hdr; - u32 stag_index; -} __attribute__((packed)) ; - -union c2wr_smr_register { - struct c2wr_smr_register_req req; - struct c2wr_smr_register_rep rep; -} __attribute__((packed)) ; - -struct c2wr_mw_alloc_req { - struct c2wr_hdr hdr; - u32 rnic_handle; - u32 pd_id; -} __attribute__((packed)) ; - -struct c2wr_mw_alloc_rep { - struct c2wr_hdr hdr; - u32 stag_index; -} __attribute__((packed)) ; - -union c2wr_mw_alloc { - struct c2wr_mw_alloc_req req; - struct c2wr_mw_alloc_rep rep; -} __attribute__((packed)) ; - -/* - *------------------------ WRs ----------------------- - */ - -struct c2wr_user_hdr { - struct c2wr_hdr hdr; /* Has status and WR Type */ -} __attribute__((packed)) ; - -enum c2_qp_state { - C2_QP_STATE_IDLE = 0x01, - C2_QP_STATE_CONNECTING = 0x02, - C2_QP_STATE_RTS = 0x04, - C2_QP_STATE_CLOSING = 0x08, - C2_QP_STATE_TERMINATE = 0x10, - C2_QP_STATE_ERROR = 0x20, -}; - -/* Completion queue entry. */ -struct c2wr_ce { - struct c2wr_hdr hdr; /* Has status and WR Type */ - u64 qp_user_context; /* c2_user_qp_t * */ - u32 qp_state; /* Current QP State */ - u32 handle; /* QPID or EP Handle */ - __be32 bytes_rcvd; /* valid for RECV WCs */ - u32 stag; -} __attribute__((packed)) ; - - -/* - * Flags used for all post-sq WRs. These must fit in the flags - * field of the struct c2wr_hdr (eight bits). - */ -enum { - SQ_SIGNALED = 0x01, - SQ_READ_FENCE = 0x02, - SQ_FENCE = 0x04, -}; - -/* - * Common fields for all post-sq WRs. Namely the standard header and a - * secondary header with fields common to all post-sq WRs. - */ -struct c2_sq_hdr { - struct c2wr_user_hdr user_hdr; -} __attribute__((packed)); - -/* - * Same as above but for post-rq WRs. - */ -struct c2_rq_hdr { - struct c2wr_user_hdr user_hdr; -} __attribute__((packed)); - -/* - * use the same struct for all sends. - */ -struct c2wr_send_req { - struct c2_sq_hdr sq_hdr; - __be32 sge_len; - __be32 remote_stag; - u8 data[0]; /* SGE array */ -} __attribute__((packed)); - -union c2wr_send { - struct c2wr_send_req req; - struct c2wr_ce rep; -} __attribute__((packed)); - -struct c2wr_rdma_write_req { - struct c2_sq_hdr sq_hdr; - __be64 remote_to; - __be32 remote_stag; - __be32 sge_len; - u8 data[0]; /* SGE array */ -} __attribute__((packed)); - -union c2wr_rdma_write { - struct c2wr_rdma_write_req req; - struct c2wr_ce rep; -} __attribute__((packed)); - -struct c2wr_rdma_read_req { - struct c2_sq_hdr sq_hdr; - __be64 local_to; - __be64 remote_to; - __be32 local_stag; - __be32 remote_stag; - __be32 length; -} __attribute__((packed)); - -union c2wr_rdma_read { - struct c2wr_rdma_read_req req; - struct c2wr_ce rep; -} __attribute__((packed)); - -struct c2wr_mw_bind_req { - struct c2_sq_hdr sq_hdr; - u64 va; - u8 stag_key; - u8 pad[3]; - u32 mw_stag_index; - u32 mr_stag_index; - u32 length; - u32 flags; -} __attribute__((packed)); - -union c2wr_mw_bind { - struct c2wr_mw_bind_req req; - struct c2wr_ce rep; -} __attribute__((packed)); - -struct c2wr_nsmr_fastreg_req { - struct c2_sq_hdr sq_hdr; - u64 va; - u8 stag_key; - u8 pad[3]; - u32 stag_index; - u32 pbe_size; - u32 fbo; - u32 length; - u32 addrs_length; - /* array of paddrs (must be aligned on a 64bit boundary) */ - u64 paddrs[0]; -} __attribute__((packed)); - -union c2wr_nsmr_fastreg { - struct c2wr_nsmr_fastreg_req req; - struct c2wr_ce rep; -} __attribute__((packed)); - -struct c2wr_stag_invalidate_req { - struct c2_sq_hdr sq_hdr; - u8 stag_key; - u8 pad[3]; - u32 stag_index; -} __attribute__((packed)); - -union c2wr_stag_invalidate { - struct c2wr_stag_invalidate_req req; - struct c2wr_ce rep; -} __attribute__((packed)); - -union c2wr_sqwr { - struct c2_sq_hdr sq_hdr; - struct c2wr_send_req send; - struct c2wr_send_req send_se; - struct c2wr_send_req send_inv; - struct c2wr_send_req send_se_inv; - struct c2wr_rdma_write_req rdma_write; - struct c2wr_rdma_read_req rdma_read; - struct c2wr_mw_bind_req mw_bind; - struct c2wr_nsmr_fastreg_req nsmr_fastreg; - struct c2wr_stag_invalidate_req stag_inv; -} __attribute__((packed)); - - -/* - * RQ WRs - */ -struct c2wr_rqwr { - struct c2_rq_hdr rq_hdr; - u8 data[0]; /* array of SGEs */ -} __attribute__((packed)); - -union c2wr_recv { - struct c2wr_rqwr req; - struct c2wr_ce rep; -} __attribute__((packed)); - -/* - * All AEs start with this header. Most AEs only need to convey the - * information in the header. Some, like LLP connection events, need - * more info. The union typdef c2wr_ae_t has all the possible AEs. - * - * hdr.context is the user_context from the rnic_open WR. NULL If this - * is not affiliated with an rnic - * - * hdr.id is the AE identifier (eg; CCAE_REMOTE_SHUTDOWN, - * CCAE_LLP_CLOSE_COMPLETE) - * - * resource_type is one of: C2_RES_IND_QP, C2_RES_IND_CQ, C2_RES_IND_SRQ - * - * user_context is the context passed down when the host created the resource. - */ -struct c2wr_ae_hdr { - struct c2wr_hdr hdr; - u64 user_context; /* user context for this res. */ - __be32 resource_type; /* see enum c2_resource_indicator */ - __be32 resource; /* handle for resource */ - __be32 qp_state; /* current QP State */ -} __attribute__((packed)); - -/* - * After submitting the CCAE_ACTIVE_CONNECT_RESULTS message on the AEQ, - * the adapter moves the QP into RTS state - */ -struct c2wr_ae_active_connect_results { - struct c2wr_ae_hdr ae_hdr; - __be32 laddr; - __be32 raddr; - __be16 lport; - __be16 rport; - __be32 private_data_length; - u8 private_data[0]; /* data is in-line in the msg. */ -} __attribute__((packed)); - -/* - * When connections are established by the stack (and the private data - * MPA frame is received), the adapter will generate an event to the host. - * The details of the connection, any private data, and the new connection - * request handle is passed up via the CCAE_CONNECTION_REQUEST msg on the - * AE queue: - */ -struct c2wr_ae_connection_request { - struct c2wr_ae_hdr ae_hdr; - u32 cr_handle; /* connreq handle (sock ptr) */ - __be32 laddr; - __be32 raddr; - __be16 lport; - __be16 rport; - __be32 private_data_length; - u8 private_data[0]; /* data is in-line in the msg. */ -} __attribute__((packed)); - -union c2wr_ae { - struct c2wr_ae_hdr ae_generic; - struct c2wr_ae_active_connect_results ae_active_connect_results; - struct c2wr_ae_connection_request ae_connection_request; -} __attribute__((packed)); - -struct c2wr_init_req { - struct c2wr_hdr hdr; - __be64 hint_count; - __be64 q0_host_shared; - __be64 q1_host_shared; - __be64 q1_host_msg_pool; - __be64 q2_host_shared; - __be64 q2_host_msg_pool; -} __attribute__((packed)); - -struct c2wr_init_rep { - struct c2wr_hdr hdr; -} __attribute__((packed)); - -union c2wr_init { - struct c2wr_init_req req; - struct c2wr_init_rep rep; -} __attribute__((packed)); - -/* - * For upgrading flash. - */ - -struct c2wr_flash_init_req { - struct c2wr_hdr hdr; - u32 rnic_handle; -} __attribute__((packed)); - -struct c2wr_flash_init_rep { - struct c2wr_hdr hdr; - u32 adapter_flash_buf_offset; - u32 adapter_flash_len; -} __attribute__((packed)); - -union c2wr_flash_init { - struct c2wr_flash_init_req req; - struct c2wr_flash_init_rep rep; -} __attribute__((packed)); - -struct c2wr_flash_req { - struct c2wr_hdr hdr; - u32 rnic_handle; - u32 len; -} __attribute__((packed)); - -struct c2wr_flash_rep { - struct c2wr_hdr hdr; - u32 status; -} __attribute__((packed)); - -union c2wr_flash { - struct c2wr_flash_req req; - struct c2wr_flash_rep rep; -} __attribute__((packed)); - -struct c2wr_buf_alloc_req { - struct c2wr_hdr hdr; - u32 rnic_handle; - u32 size; -} __attribute__((packed)); - -struct c2wr_buf_alloc_rep { - struct c2wr_hdr hdr; - u32 offset; /* 0 if mem not available */ - u32 size; /* 0 if mem not available */ -} __attribute__((packed)); - -union c2wr_buf_alloc { - struct c2wr_buf_alloc_req req; - struct c2wr_buf_alloc_rep rep; -} __attribute__((packed)); - -struct c2wr_buf_free_req { - struct c2wr_hdr hdr; - u32 rnic_handle; - u32 offset; /* Must match value from alloc */ - u32 size; /* Must match value from alloc */ -} __attribute__((packed)); - -struct c2wr_buf_free_rep { - struct c2wr_hdr hdr; -} __attribute__((packed)); - -union c2wr_buf_free { - struct c2wr_buf_free_req req; - struct c2wr_ce rep; -} __attribute__((packed)); - -struct c2wr_flash_write_req { - struct c2wr_hdr hdr; - u32 rnic_handle; - u32 offset; - u32 size; - u32 type; - u32 flags; -} __attribute__((packed)); - -struct c2wr_flash_write_rep { - struct c2wr_hdr hdr; - u32 status; -} __attribute__((packed)); - -union c2wr_flash_write { - struct c2wr_flash_write_req req; - struct c2wr_flash_write_rep rep; -} __attribute__((packed)); - -/* - * Messages for LLP connection setup. - */ - -/* - * Listen Request. This allocates a listening endpoint to allow passive - * connection setup. Newly established LLP connections are passed up - * via an AE. See c2wr_ae_connection_request_t - */ -struct c2wr_ep_listen_create_req { - struct c2wr_hdr hdr; - u64 user_context; /* returned in AEs. */ - u32 rnic_handle; - __be32 local_addr; /* local addr, or 0 */ - __be16 local_port; /* 0 means "pick one" */ - u16 pad; - __be32 backlog; /* tradional tcp listen bl */ -} __attribute__((packed)); - -struct c2wr_ep_listen_create_rep { - struct c2wr_hdr hdr; - u32 ep_handle; /* handle to new listening ep */ - u16 local_port; /* resulting port... */ - u16 pad; -} __attribute__((packed)); - -union c2wr_ep_listen_create { - struct c2wr_ep_listen_create_req req; - struct c2wr_ep_listen_create_rep rep; -} __attribute__((packed)); - -struct c2wr_ep_listen_destroy_req { - struct c2wr_hdr hdr; - u32 rnic_handle; - u32 ep_handle; -} __attribute__((packed)); - -struct c2wr_ep_listen_destroy_rep { - struct c2wr_hdr hdr; -} __attribute__((packed)); - -union c2wr_ep_listen_destroy { - struct c2wr_ep_listen_destroy_req req; - struct c2wr_ep_listen_destroy_rep rep; -} __attribute__((packed)); - -struct c2wr_ep_query_req { - struct c2wr_hdr hdr; - u32 rnic_handle; - u32 ep_handle; -} __attribute__((packed)); - -struct c2wr_ep_query_rep { - struct c2wr_hdr hdr; - u32 rnic_handle; - u32 local_addr; - u32 remote_addr; - u16 local_port; - u16 remote_port; -} __attribute__((packed)); - -union c2wr_ep_query { - struct c2wr_ep_query_req req; - struct c2wr_ep_query_rep rep; -} __attribute__((packed)); - - -/* - * The host passes this down to indicate acceptance of a pending iWARP - * connection. The cr_handle was obtained from the CONNECTION_REQUEST - * AE passed up by the adapter. See c2wr_ae_connection_request_t. - */ -struct c2wr_cr_accept_req { - struct c2wr_hdr hdr; - u32 rnic_handle; - u32 qp_handle; /* QP to bind to this LLP conn */ - u32 ep_handle; /* LLP handle to accept */ - __be32 private_data_length; - u8 private_data[0]; /* data in-line in msg. */ -} __attribute__((packed)); - -/* - * adapter sends reply when private data is successfully submitted to - * the LLP. - */ -struct c2wr_cr_accept_rep { - struct c2wr_hdr hdr; -} __attribute__((packed)); - -union c2wr_cr_accept { - struct c2wr_cr_accept_req req; - struct c2wr_cr_accept_rep rep; -} __attribute__((packed)); - -/* - * The host sends this down if a given iWARP connection request was - * rejected by the consumer. The cr_handle was obtained from a - * previous c2wr_ae_connection_request_t AE sent by the adapter. - */ -struct c2wr_cr_reject_req { - struct c2wr_hdr hdr; - u32 rnic_handle; - u32 ep_handle; /* LLP handle to reject */ -} __attribute__((packed)); - -/* - * Dunno if this is needed, but we'll add it for now. The adapter will - * send the reject_reply after the LLP endpoint has been destroyed. - */ -struct c2wr_cr_reject_rep { - struct c2wr_hdr hdr; -} __attribute__((packed)); - -union c2wr_cr_reject { - struct c2wr_cr_reject_req req; - struct c2wr_cr_reject_rep rep; -} __attribute__((packed)); - -/* - * console command. Used to implement a debug console over the verbs - * request and reply queues. - */ - -/* - * Console request message. It contains: - * - message hdr with id = CCWR_CONSOLE - * - the physaddr/len of host memory to be used for the reply. - * - the command string. eg: "netstat -s" or "zoneinfo" - */ -struct c2wr_console_req { - struct c2wr_hdr hdr; /* id = CCWR_CONSOLE */ - u64 reply_buf; /* pinned host buf for reply */ - u32 reply_buf_len; /* length of reply buffer */ - u8 command[0]; /* NUL terminated ascii string */ - /* containing the command req */ -} __attribute__((packed)); - -/* - * flags used in the console reply. - */ -enum c2_console_flags { - CONS_REPLY_TRUNCATED = 0x00000001 /* reply was truncated */ -} __attribute__((packed)); - -/* - * Console reply message. - * hdr.result contains the c2_status_t error if the reply was _not_ generated, - * or C2_OK if the reply was generated. - */ -struct c2wr_console_rep { - struct c2wr_hdr hdr; /* id = CCWR_CONSOLE */ - u32 flags; -} __attribute__((packed)); - -union c2wr_console { - struct c2wr_console_req req; - struct c2wr_console_rep rep; -} __attribute__((packed)); - - -/* - * Giant union with all WRs. Makes life easier... - */ -union c2wr { - struct c2wr_hdr hdr; - struct c2wr_user_hdr user_hdr; - union c2wr_rnic_open rnic_open; - union c2wr_rnic_query rnic_query; - union c2wr_rnic_getconfig rnic_getconfig; - union c2wr_rnic_setconfig rnic_setconfig; - union c2wr_rnic_close rnic_close; - union c2wr_cq_create cq_create; - union c2wr_cq_modify cq_modify; - union c2wr_cq_destroy cq_destroy; - union c2wr_pd_alloc pd_alloc; - union c2wr_pd_dealloc pd_dealloc; - union c2wr_srq_create srq_create; - union c2wr_srq_destroy srq_destroy; - union c2wr_qp_create qp_create; - union c2wr_qp_query qp_query; - union c2wr_qp_modify qp_modify; - union c2wr_qp_destroy qp_destroy; - struct c2wr_qp_connect qp_connect; - union c2wr_nsmr_stag_alloc nsmr_stag_alloc; - union c2wr_nsmr_register nsmr_register; - union c2wr_nsmr_pbl nsmr_pbl; - union c2wr_mr_query mr_query; - union c2wr_mw_query mw_query; - union c2wr_stag_dealloc stag_dealloc; - union c2wr_sqwr sqwr; - struct c2wr_rqwr rqwr; - struct c2wr_ce ce; - union c2wr_ae ae; - union c2wr_init init; - union c2wr_ep_listen_create ep_listen_create; - union c2wr_ep_listen_destroy ep_listen_destroy; - union c2wr_cr_accept cr_accept; - union c2wr_cr_reject cr_reject; - union c2wr_console console; - union c2wr_flash_init flash_init; - union c2wr_flash flash; - union c2wr_buf_alloc buf_alloc; - union c2wr_buf_free buf_free; - union c2wr_flash_write flash_write; -} __attribute__((packed)); - - -/* - * Accessors for the wr fields that are packed together tightly to - * reduce the wr message size. The wr arguments are void* so that - * either a struct c2wr*, a struct c2wr_hdr*, or a pointer to any of the types - * in the struct c2wr union can be passed in. - */ -static __inline__ u8 c2_wr_get_id(void *wr) -{ - return ((struct c2wr_hdr *) wr)->id; -} -static __inline__ void c2_wr_set_id(void *wr, u8 id) -{ - ((struct c2wr_hdr *) wr)->id = id; -} -static __inline__ u8 c2_wr_get_result(void *wr) -{ - return ((struct c2wr_hdr *) wr)->result; -} -static __inline__ void c2_wr_set_result(void *wr, u8 result) -{ - ((struct c2wr_hdr *) wr)->result = result; -} -static __inline__ u8 c2_wr_get_flags(void *wr) -{ - return ((struct c2wr_hdr *) wr)->flags; -} -static __inline__ void c2_wr_set_flags(void *wr, u8 flags) -{ - ((struct c2wr_hdr *) wr)->flags = flags; -} -static __inline__ u8 c2_wr_get_sge_count(void *wr) -{ - return ((struct c2wr_hdr *) wr)->sge_count; -} -static __inline__ void c2_wr_set_sge_count(void *wr, u8 sge_count) -{ - ((struct c2wr_hdr *) wr)->sge_count = sge_count; -} -static __inline__ __be32 c2_wr_get_wqe_count(void *wr) -{ - return ((struct c2wr_hdr *) wr)->wqe_count; -} -static __inline__ void c2_wr_set_wqe_count(void *wr, u32 wqe_count) -{ - ((struct c2wr_hdr *) wr)->wqe_count = wqe_count; -} - -#endif /* _C2_WR_H_ */ |