fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / include / rdma / ib_verbs.h
index 22fc886..0bfa332 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (c) 2004 Topspin Corporation.  All rights reserved.
  * Copyright (c) 2004 Voltaire Corporation.  All rights reserved.
  * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
- * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ * Copyright (c) 2005, 2006 Cisco Systems.  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
@@ -43,6 +43,8 @@
 
 #include <linux/types.h>
 #include <linux/device.h>
+#include <linux/mm.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/atomic.h>
 #include <asm/scatterlist.h>
@@ -56,12 +58,22 @@ union ib_gid {
        } global;
 };
 
-enum ib_node_type {
-       IB_NODE_CA      = 1,
-       IB_NODE_SWITCH,
-       IB_NODE_ROUTER
+enum rdma_node_type {
+       /* IB values map to NodeInfo:NodeType. */
+       RDMA_NODE_IB_CA         = 1,
+       RDMA_NODE_IB_SWITCH,
+       RDMA_NODE_IB_ROUTER,
+       RDMA_NODE_RNIC
 };
 
+enum rdma_transport_type {
+       RDMA_TRANSPORT_IB,
+       RDMA_TRANSPORT_IWARP
+};
+
+enum rdma_transport_type
+rdma_node_get_transport(enum rdma_node_type node_type) __attribute_const__;
+
 enum ib_device_cap_flags {
        IB_DEVICE_RESIZE_MAX_WR         = 1,
        IB_DEVICE_BAD_PKEY_CNTR         = (1<<1),
@@ -78,6 +90,9 @@ enum ib_device_cap_flags {
        IB_DEVICE_RC_RNR_NAK_GEN        = (1<<12),
        IB_DEVICE_SRQ_RESIZE            = (1<<13),
        IB_DEVICE_N_NOTIFY_CQ           = (1<<14),
+       IB_DEVICE_ZERO_STAG             = (1<<15),
+       IB_DEVICE_SEND_W_INV            = (1<<16),
+       IB_DEVICE_MEM_WINDOW            = (1<<17)
 };
 
 enum ib_atomic_cap {
@@ -222,11 +237,13 @@ struct ib_port_attr {
 };
 
 enum ib_device_modify_flags {
-       IB_DEVICE_MODIFY_SYS_IMAGE_GUID = 1
+       IB_DEVICE_MODIFY_SYS_IMAGE_GUID = 1 << 0,
+       IB_DEVICE_MODIFY_NODE_DESC      = 1 << 1
 };
 
 struct ib_device_modify {
        u64     sys_image_guid;
+       char    node_desc[64];
 };
 
 enum ib_port_modify_flags {
@@ -258,7 +275,8 @@ enum ib_event_type {
        IB_EVENT_SM_CHANGE,
        IB_EVENT_SRQ_ERR,
        IB_EVENT_SRQ_LIMIT_REACHED,
-       IB_EVENT_QP_LAST_WQE_REACHED
+       IB_EVENT_QP_LAST_WQE_REACHED,
+       IB_EVENT_CLIENT_REREGISTER
 };
 
 struct ib_event {
@@ -312,6 +330,34 @@ enum ib_ah_flags {
        IB_AH_GRH       = 1
 };
 
+enum ib_rate {
+       IB_RATE_PORT_CURRENT = 0,
+       IB_RATE_2_5_GBPS = 2,
+       IB_RATE_5_GBPS   = 5,
+       IB_RATE_10_GBPS  = 3,
+       IB_RATE_20_GBPS  = 6,
+       IB_RATE_30_GBPS  = 4,
+       IB_RATE_40_GBPS  = 7,
+       IB_RATE_60_GBPS  = 8,
+       IB_RATE_80_GBPS  = 9,
+       IB_RATE_120_GBPS = 10
+};
+
+/**
+ * ib_rate_to_mult - Convert the IB rate enum to a multiple of the
+ * base rate of 2.5 Gbit/sec.  For example, IB_RATE_5_GBPS will be
+ * converted to 2, since 5 Gbit/sec is 2 * 2.5 Gbit/sec.
+ * @rate: rate to convert.
+ */
+int ib_rate_to_mult(enum ib_rate rate) __attribute_const__;
+
+/**
+ * mult_to_ib_rate - Convert a multiple of 2.5 Gbit/sec to an IB rate
+ * enum.
+ * @mult: multiple to convert.
+ */
+enum ib_rate mult_to_ib_rate(int mult) __attribute_const__;
+
 struct ib_ah_attr {
        struct ib_global_route  grh;
        u16                     dlid;
@@ -649,7 +695,7 @@ struct ib_mw_bind {
 struct ib_fmr_attr {
        int     max_pages;
        int     max_maps;
-       u8      page_size;
+       u8      page_shift;
 };
 
 struct ib_ucontext {
@@ -666,8 +712,12 @@ struct ib_ucontext {
 struct ib_uobject {
        u64                     user_handle;    /* handle given to us by userspace */
        struct ib_ucontext     *context;        /* associated user context */
+       void                   *object;         /* containing object */
        struct list_head        list;           /* link to context's list */
        u32                     id;             /* index into kernel idr */
+       struct kref             ref;
+       struct rw_semaphore     mutex;          /* protects .live */
+       int                     live;
 };
 
 struct ib_umem {
@@ -797,7 +847,53 @@ struct ib_cache {
        struct ib_event_handler event_handler;
        struct ib_pkey_cache  **pkey_cache;
        struct ib_gid_cache   **gid_cache;
-};
+       u8                     *lmc_cache;
+};
+
+struct ib_dma_mapping_ops {
+       int             (*mapping_error)(struct ib_device *dev,
+                                        u64 dma_addr);
+       u64             (*map_single)(struct ib_device *dev,
+                                     void *ptr, size_t size,
+                                     enum dma_data_direction direction);
+       void            (*unmap_single)(struct ib_device *dev,
+                                       u64 addr, size_t size,
+                                       enum dma_data_direction direction);
+       u64             (*map_page)(struct ib_device *dev,
+                                   struct page *page, unsigned long offset,
+                                   size_t size,
+                                   enum dma_data_direction direction);
+       void            (*unmap_page)(struct ib_device *dev,
+                                     u64 addr, size_t size,
+                                     enum dma_data_direction direction);
+       int             (*map_sg)(struct ib_device *dev,
+                                 struct scatterlist *sg, int nents,
+                                 enum dma_data_direction direction);
+       void            (*unmap_sg)(struct ib_device *dev,
+                                   struct scatterlist *sg, int nents,
+                                   enum dma_data_direction direction);
+       u64             (*dma_address)(struct ib_device *dev,
+                                      struct scatterlist *sg);
+       unsigned int    (*dma_len)(struct ib_device *dev,
+                                  struct scatterlist *sg);
+       void            (*sync_single_for_cpu)(struct ib_device *dev,
+                                              u64 dma_handle,
+                                              size_t size,
+                                              enum dma_data_direction dir);
+       void            (*sync_single_for_device)(struct ib_device *dev,
+                                                 u64 dma_handle,
+                                                 size_t size,
+                                                 enum dma_data_direction dir);
+       void            *(*alloc_coherent)(struct ib_device *dev,
+                                          size_t size,
+                                          u64 *dma_handle,
+                                          gfp_t flag);
+       void            (*free_coherent)(struct ib_device *dev,
+                                        size_t size, void *cpu_addr,
+                                        u64 dma_handle);
+};
+
+struct iw_cm_verbs;
 
 struct ib_device {
        struct device                *dma_device;
@@ -815,6 +911,8 @@ struct ib_device {
 
        u32                           flags;
 
+       struct iw_cm_verbs           *iwcm;
+
        int                        (*query_device)(struct ib_device *device,
                                                   struct ib_device_attr *device_attr);
        int                        (*query_port)(struct ib_device *device,
@@ -852,7 +950,8 @@ struct ib_device {
                                                 struct ib_udata *udata);
        int                        (*modify_srq)(struct ib_srq *srq,
                                                 struct ib_srq_attr *srq_attr,
-                                                enum ib_srq_attr_mask srq_attr_mask);
+                                                enum ib_srq_attr_mask srq_attr_mask,
+                                                struct ib_udata *udata);
        int                        (*query_srq)(struct ib_srq *srq,
                                                struct ib_srq_attr *srq_attr);
        int                        (*destroy_srq)(struct ib_srq *srq);
@@ -864,7 +963,8 @@ struct ib_device {
                                                struct ib_udata *udata);
        int                        (*modify_qp)(struct ib_qp *qp,
                                                struct ib_qp_attr *qp_attr,
-                                               int qp_attr_mask);
+                                               int qp_attr_mask,
+                                               struct ib_udata *udata);
        int                        (*query_qp)(struct ib_qp *qp,
                                               struct ib_qp_attr *qp_attr,
                                               int qp_attr_mask,
@@ -880,7 +980,8 @@ struct ib_device {
                                                struct ib_ucontext *context,
                                                struct ib_udata *udata);
        int                        (*destroy_cq)(struct ib_cq *cq);
-       int                        (*resize_cq)(struct ib_cq *cq, int cqe);
+       int                        (*resize_cq)(struct ib_cq *cq, int cqe,
+                                               struct ib_udata *udata);
        int                        (*poll_cq)(struct ib_cq *cq, int num_entries,
                                              struct ib_wc *wc);
        int                        (*peek_cq)(struct ib_cq *cq, int wc_cnt);
@@ -936,6 +1037,8 @@ struct ib_device {
                                                  struct ib_mad *in_mad,
                                                  struct ib_mad *out_mad);
 
+       struct ib_dma_mapping_ops   *dma_ops;
+
        struct module               *owner;
        struct class_device          class_dev;
        struct kobject               ports_parent;
@@ -950,6 +1053,7 @@ struct ib_device {
        u64                          uverbs_cmd_mask;
        int                          uverbs_abi_ver;
 
+       char                         node_desc[64];
        __be64                       node_guid;
        u8                           node_type;
        u8                           phys_port_cnt;
@@ -986,6 +1090,24 @@ static inline int ib_copy_to_udata(struct ib_udata *udata, void *src, size_t len
        return copy_to_user(udata->outbuf, src, len) ? -EFAULT : 0;
 }
 
+/**
+ * ib_modify_qp_is_ok - Check that the supplied attribute mask
+ * contains all required attributes and no attributes not allowed for
+ * the given QP state transition.
+ * @cur_state: Current QP state
+ * @next_state: Next QP state
+ * @type: QP type
+ * @mask: Mask of supplied QP attributes
+ *
+ * This function is a helper function that a low-level driver's
+ * modify_qp method can use to validate the consumer's input.  It
+ * checks that cur_state and next_state are valid QP states, that a
+ * transition from cur_state to next_state is allowed by the IB spec,
+ * and that the attribute mask supplied is allowed for the transition.
+ */
+int ib_modify_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state next_state,
+                      enum ib_qp_type type, enum ib_qp_attr_mask mask);
+
 int ib_register_event_handler  (struct ib_event_handler *event_handler);
 int ib_unregister_event_handler(struct ib_event_handler *event_handler);
 void ib_dispatch_event(struct ib_event *event);
@@ -1035,6 +1157,20 @@ int ib_dealloc_pd(struct ib_pd *pd);
  */
 struct ib_ah *ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr);
 
+/**
+ * ib_init_ah_from_wc - Initializes address handle attributes from a
+ *   work completion.
+ * @device: Device on which the received message arrived.
+ * @port_num: Port on which the received message arrived.
+ * @wc: Work completion associated with the received message.
+ * @grh: References the received global route header.  This parameter is
+ *   ignored unless the work completion indicates that the GRH is valid.
+ * @ah_attr: Returned attributes that can be used when creating an address
+ *   handle for replying to the message.
+ */
+int ib_init_ah_from_wc(struct ib_device *device, u8 port_num, struct ib_wc *wc,
+                      struct ib_grh *grh, struct ib_ah_attr *ah_attr);
+
 /**
  * ib_create_ah_from_wc - Creates an address handle associated with the
  *   sender of the specified work completion.
@@ -1078,7 +1214,9 @@ int ib_destroy_ah(struct ib_ah *ah);
  * ib_create_srq - Creates a SRQ associated with the specified protection
  *   domain.
  * @pd: The protection domain associated with the SRQ.
- * @srq_init_attr: A list of initial attributes required to create the SRQ.
+ * @srq_init_attr: A list of initial attributes required to create the
+ *   SRQ.  If SRQ creation succeeds, then the attributes are updated to
+ *   the actual capabilities of the created SRQ.
  *
  * srq_attr->max_wr and srq_attr->max_sge are read the determine the
  * requested size of the SRQ, and set to the actual values allocated
@@ -1137,7 +1275,9 @@ static inline int ib_post_srq_recv(struct ib_srq *srq,
  * ib_create_qp - Creates a QP associated with the specified protection
  *   domain.
  * @pd: The protection domain associated with the QP.
- * @qp_init_attr: A list of initial attributes required to create the QP.
+ * @qp_init_attr: A list of initial attributes required to create the
+ *   QP.  If QP creation succeeds, then the attributes are updated to
+ *   the actual capabilities of the created QP.
  */
 struct ib_qp *ib_create_qp(struct ib_pd *pd,
                           struct ib_qp_init_attr *qp_init_attr);
@@ -1302,9 +1442,230 @@ static inline int ib_req_ncomp_notif(struct ib_cq *cq, int wc_cnt)
  *   usable for DMA.
  * @pd: The protection domain associated with the memory region.
  * @mr_access_flags: Specifies the memory access rights.
+ *
+ * Note that the ib_dma_*() functions defined below must be used
+ * to create/destroy addresses used with the Lkey or Rkey returned
+ * by ib_get_dma_mr().
  */
 struct ib_mr *ib_get_dma_mr(struct ib_pd *pd, int mr_access_flags);
 
+/**
+ * ib_dma_mapping_error - check a DMA addr for error
+ * @dev: The device for which the dma_addr was created
+ * @dma_addr: The DMA address to check
+ */
+static inline int ib_dma_mapping_error(struct ib_device *dev, u64 dma_addr)
+{
+       if (dev->dma_ops)
+               return dev->dma_ops->mapping_error(dev, dma_addr);
+       return dma_mapping_error(dma_addr);
+}
+
+/**
+ * ib_dma_map_single - Map a kernel virtual address to DMA address
+ * @dev: The device for which the dma_addr is to be created
+ * @cpu_addr: The kernel virtual address
+ * @size: The size of the region in bytes
+ * @direction: The direction of the DMA
+ */
+static inline u64 ib_dma_map_single(struct ib_device *dev,
+                                   void *cpu_addr, size_t size,
+                                   enum dma_data_direction direction)
+{
+       if (dev->dma_ops)
+               return dev->dma_ops->map_single(dev, cpu_addr, size, direction);
+       return dma_map_single(dev->dma_device, cpu_addr, size, direction);
+}
+
+/**
+ * ib_dma_unmap_single - Destroy a mapping created by ib_dma_map_single()
+ * @dev: The device for which the DMA address was created
+ * @addr: The DMA address
+ * @size: The size of the region in bytes
+ * @direction: The direction of the DMA
+ */
+static inline void ib_dma_unmap_single(struct ib_device *dev,
+                                      u64 addr, size_t size,
+                                      enum dma_data_direction direction)
+{
+       if (dev->dma_ops)
+               dev->dma_ops->unmap_single(dev, addr, size, direction);
+       else
+               dma_unmap_single(dev->dma_device, addr, size, direction);
+}
+
+/**
+ * ib_dma_map_page - Map a physical page to DMA address
+ * @dev: The device for which the dma_addr is to be created
+ * @page: The page to be mapped
+ * @offset: The offset within the page
+ * @size: The size of the region in bytes
+ * @direction: The direction of the DMA
+ */
+static inline u64 ib_dma_map_page(struct ib_device *dev,
+                                 struct page *page,
+                                 unsigned long offset,
+                                 size_t size,
+                                        enum dma_data_direction direction)
+{
+       if (dev->dma_ops)
+               return dev->dma_ops->map_page(dev, page, offset, size, direction);
+       return dma_map_page(dev->dma_device, page, offset, size, direction);
+}
+
+/**
+ * ib_dma_unmap_page - Destroy a mapping created by ib_dma_map_page()
+ * @dev: The device for which the DMA address was created
+ * @addr: The DMA address
+ * @size: The size of the region in bytes
+ * @direction: The direction of the DMA
+ */
+static inline void ib_dma_unmap_page(struct ib_device *dev,
+                                    u64 addr, size_t size,
+                                    enum dma_data_direction direction)
+{
+       if (dev->dma_ops)
+               dev->dma_ops->unmap_page(dev, addr, size, direction);
+       else
+               dma_unmap_page(dev->dma_device, addr, size, direction);
+}
+
+/**
+ * ib_dma_map_sg - Map a scatter/gather list to DMA addresses
+ * @dev: The device for which the DMA addresses are to be created
+ * @sg: The array of scatter/gather entries
+ * @nents: The number of scatter/gather entries
+ * @direction: The direction of the DMA
+ */
+static inline int ib_dma_map_sg(struct ib_device *dev,
+                               struct scatterlist *sg, int nents,
+                               enum dma_data_direction direction)
+{
+       if (dev->dma_ops)
+               return dev->dma_ops->map_sg(dev, sg, nents, direction);
+       return dma_map_sg(dev->dma_device, sg, nents, direction);
+}
+
+/**
+ * ib_dma_unmap_sg - Unmap a scatter/gather list of DMA addresses
+ * @dev: The device for which the DMA addresses were created
+ * @sg: The array of scatter/gather entries
+ * @nents: The number of scatter/gather entries
+ * @direction: The direction of the DMA
+ */
+static inline void ib_dma_unmap_sg(struct ib_device *dev,
+                                  struct scatterlist *sg, int nents,
+                                  enum dma_data_direction direction)
+{
+       if (dev->dma_ops)
+               dev->dma_ops->unmap_sg(dev, sg, nents, direction);
+       else
+               dma_unmap_sg(dev->dma_device, sg, nents, direction);
+}
+
+/**
+ * ib_sg_dma_address - Return the DMA address from a scatter/gather entry
+ * @dev: The device for which the DMA addresses were created
+ * @sg: The scatter/gather entry
+ */
+static inline u64 ib_sg_dma_address(struct ib_device *dev,
+                                   struct scatterlist *sg)
+{
+       if (dev->dma_ops)
+               return dev->dma_ops->dma_address(dev, sg);
+       return sg_dma_address(sg);
+}
+
+/**
+ * ib_sg_dma_len - Return the DMA length from a scatter/gather entry
+ * @dev: The device for which the DMA addresses were created
+ * @sg: The scatter/gather entry
+ */
+static inline unsigned int ib_sg_dma_len(struct ib_device *dev,
+                                        struct scatterlist *sg)
+{
+       if (dev->dma_ops)
+               return dev->dma_ops->dma_len(dev, sg);
+       return sg_dma_len(sg);
+}
+
+/**
+ * ib_dma_sync_single_for_cpu - Prepare DMA region to be accessed by CPU
+ * @dev: The device for which the DMA address was created
+ * @addr: The DMA address
+ * @size: The size of the region in bytes
+ * @dir: The direction of the DMA
+ */
+static inline void ib_dma_sync_single_for_cpu(struct ib_device *dev,
+                                             u64 addr,
+                                             size_t size,
+                                             enum dma_data_direction dir)
+{
+       if (dev->dma_ops)
+               dev->dma_ops->sync_single_for_cpu(dev, addr, size, dir);
+       else
+               dma_sync_single_for_cpu(dev->dma_device, addr, size, dir);
+}
+
+/**
+ * ib_dma_sync_single_for_device - Prepare DMA region to be accessed by device
+ * @dev: The device for which the DMA address was created
+ * @addr: The DMA address
+ * @size: The size of the region in bytes
+ * @dir: The direction of the DMA
+ */
+static inline void ib_dma_sync_single_for_device(struct ib_device *dev,
+                                                u64 addr,
+                                                size_t size,
+                                                enum dma_data_direction dir)
+{
+       if (dev->dma_ops)
+               dev->dma_ops->sync_single_for_device(dev, addr, size, dir);
+       else
+               dma_sync_single_for_device(dev->dma_device, addr, size, dir);
+}
+
+/**
+ * ib_dma_alloc_coherent - Allocate memory and map it for DMA
+ * @dev: The device for which the DMA address is requested
+ * @size: The size of the region to allocate in bytes
+ * @dma_handle: A pointer for returning the DMA address of the region
+ * @flag: memory allocator flags
+ */
+static inline void *ib_dma_alloc_coherent(struct ib_device *dev,
+                                          size_t size,
+                                          u64 *dma_handle,
+                                          gfp_t flag)
+{
+       if (dev->dma_ops)
+               return dev->dma_ops->alloc_coherent(dev, size, dma_handle, flag);
+       else {
+               dma_addr_t handle;
+               void *ret;
+
+               ret = dma_alloc_coherent(dev->dma_device, size, &handle, flag);
+               *dma_handle = handle;
+               return ret;
+       }
+}
+
+/**
+ * ib_dma_free_coherent - Free memory allocated by ib_dma_alloc_coherent()
+ * @dev: The device for which the DMA addresses were allocated
+ * @size: The size of the region
+ * @cpu_addr: the address returned by ib_dma_alloc_coherent()
+ * @dma_handle: the DMA address returned by ib_dma_alloc_coherent()
+ */
+static inline void ib_dma_free_coherent(struct ib_device *dev,
+                                       size_t size, void *cpu_addr,
+                                       u64 dma_handle)
+{
+       if (dev->dma_ops)
+               dev->dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
+       else
+               dma_free_coherent(dev->dma_device, size, cpu_addr, dma_handle);
+}
+
 /**
  * ib_reg_phys_mr - Prepares a virtually addressed memory region for use
  *   by an HCA.