IB/mlx4: Unregister IB device prior to CLOSE PORT command
[safe/jmp/linux-2.6] / drivers / infiniband / hw / ehca / ehca_classes.h
index daf823e..c825142 100644 (file)
@@ -43,7 +43,6 @@
 #ifndef __EHCA_CLASSES_H__
 #define __EHCA_CLASSES_H__
 
-
 struct ehca_module;
 struct ehca_qp;
 struct ehca_cq;
@@ -54,6 +53,7 @@ struct ehca_pd;
 struct ehca_av;
 
 #include <linux/wait.h>
+#include <linux/mutex.h>
 
 #include <rdma/ib_verbs.h>
 #include <rdma/ib_user_verbs.h>
@@ -66,6 +66,7 @@ struct ehca_av;
 #include "ehca_irq.h"
 
 #define EHCA_EQE_CACHE_SIZE 20
+#define EHCA_MAX_NUM_QUEUES 0xffff
 
 struct ehca_eqe_cache_entry {
        struct ehca_eqe *eqe;
@@ -94,15 +95,24 @@ struct ehca_sma_attr {
 
 struct ehca_sport {
        struct ib_cq *ibcq_aqp1;
-       struct ib_qp *ibqp_aqp1;
-       enum ib_rate  rate;
+       struct ib_qp *ibqp_sqp[2];
+       /* lock to serialze modify_qp() calls for sqp in normal
+        * and irq path (when event PORT_ACTIVE is received first time)
+        */
+       spinlock_t mod_sqp_lock;
        enum ib_port_state port_state;
        struct ehca_sma_attr saved_attr;
+       u32 pma_qp_nr;
 };
 
+#define HCA_CAP_MR_PGSIZE_4K  0x80000000
+#define HCA_CAP_MR_PGSIZE_64K 0x40000000
+#define HCA_CAP_MR_PGSIZE_1M  0x20000000
+#define HCA_CAP_MR_PGSIZE_16M 0x10000000
+
 struct ehca_shca {
        struct ib_device ib_device;
-       struct ibmebus_dev *ibmebus_dev;
+       struct of_device *ofdev;
        u8 num_ports;
        int hw_level;
        struct list_head shca_list;
@@ -115,13 +125,22 @@ struct ehca_shca {
        struct h_galpas galpas;
        struct mutex modify_mutex;
        u64 hca_cap;
+       /* MR pgsize: bit 0-3 means 4K, 64K, 1M, 16M respectively */
+       u32 hca_cap_mr_pgsize;
        int max_mtu;
+       int max_num_qps;
+       int max_num_cqs;
+       atomic_t num_cqs;
+       atomic_t num_qps;
 };
 
 struct ehca_pd {
        struct ib_pd ib_pd;
        struct ipz_pd fw_pd;
-       u32 ownpid;
+       /* small queue mgmt */
+       struct mutex lock;
+       struct list_head free[2];
+       struct list_head full[2];
 };
 
 enum ehca_ext_qp_type {
@@ -131,6 +150,38 @@ enum ehca_ext_qp_type {
        EQPT_SRQ       = 3,
 };
 
+/* struct to cache modify_qp()'s parms for GSI/SMI qp */
+struct ehca_mod_qp_parm {
+       int mask;
+       struct ib_qp_attr attr;
+};
+
+#define EHCA_MOD_QP_PARM_MAX 4
+
+#define QMAP_IDX_MASK 0xFFFFULL
+
+/* struct for tracking if cqes have been reported to the application */
+struct ehca_qmap_entry {
+       u16 app_wr_id;
+       u8 reported;
+       u8 cqe_req;
+};
+
+struct ehca_queue_map {
+       struct ehca_qmap_entry *map;
+       unsigned int entries;
+       unsigned int tail;
+       unsigned int left_to_poll;
+       unsigned int next_wqe_idx;   /* Idx to first wqe to be flushed */
+};
+
+/* function to calculate the next index for the qmap */
+static inline unsigned int next_index(unsigned int cur_index, unsigned int limit)
+{
+       unsigned int temp = cur_index + 1;
+       return (temp == limit) ? 0 : temp;
+}
+
 struct ehca_qp {
        union {
                struct ib_qp ib_qp;
@@ -138,8 +189,11 @@ struct ehca_qp {
        };
        u32 qp_type;
        enum ehca_ext_qp_type ext_type;
+       enum ib_qp_state state;
        struct ipz_queue ipz_squeue;
+       struct ehca_queue_map sq_map;
        struct ipz_queue ipz_rqueue;
+       struct ehca_queue_map rq_map;
        struct h_galpas galpas;
        u32 qkey;
        u32 real_qp_num;
@@ -154,10 +208,23 @@ struct ehca_qp {
        struct ehca_cq *recv_cq;
        unsigned int sqerr_purgeflag;
        struct hlist_node list_entries;
+       /* array to cache modify_qp()'s parms for GSI/SMI qp */
+       struct ehca_mod_qp_parm *mod_qp_parm;
+       int mod_qp_parm_idx;
        /* mmap counter for resources mapped into user space */
        u32 mm_count_squeue;
        u32 mm_count_rqueue;
        u32 mm_count_galpa;
+       /* unsolicited ack circumvention */
+       int unsol_ack_circ;
+       int mtu_shift;
+       u32 message_count;
+       u32 packet_count;
+       atomic_t nr_events; /* events seen */
+       wait_queue_head_t wait_completion;
+       int mig_armed;
+       struct list_head sq_err_node;
+       struct list_head rq_err_node;
 };
 
 #define IS_SRQ(qp) (qp->ext_type == EQPT_SRQ)
@@ -184,10 +251,11 @@ struct ehca_cq {
        atomic_t nr_events; /* #events seen */
        wait_queue_head_t wait_completion;
        spinlock_t task_lock;
-       u32 ownpid;
        /* mmap counter for resources mapped into user space */
        u32 mm_count_queue;
        u32 mm_count_galpa;
+       struct list_head sqp_err_list;
+       struct list_head rqp_err_list;
 };
 
 enum ehca_mr_flag {
@@ -204,11 +272,12 @@ struct ehca_mr {
        spinlock_t mrlock;
 
        enum ehca_mr_flag flags;
-       u32 num_pages;          /* number of MR pages */
-       u32 num_4k;             /* number of 4k "page" portions to form MR */
+       u32 num_kpages;         /* number of kernel pages */
+       u32 num_hwpages;        /* number of hw pages to form MR */
+       u64 hwpage_size;        /* hw page size used for this MR */
        int acl;                /* ACL (stored here for usage in reregister) */
        u64 *start;             /* virtual start address (stored here for */
-                               /* usage in reregister) */
+                               /* usage in reregister) */
        u64 size;               /* size (stored here for usage in reregister) */
        u32 fmr_page_size;      /* page size for FMR */
        u32 fmr_max_pages;      /* max pages for FMR */
@@ -217,9 +286,6 @@ struct ehca_mr {
        /* fw specific data */
        struct ipz_mrmw_handle ipz_mr_handle;   /* MR handle for h-calls */
        struct h_galpas galpas;
-       /* data for userspace bridge */
-       u32 nr_of_pages;
-       void *pagearray;
 };
 
 struct ehca_mw {
@@ -241,26 +307,30 @@ enum ehca_mr_pgi_type {
 
 struct ehca_mr_pginfo {
        enum ehca_mr_pgi_type type;
-       u64 num_pages;
-       u64 page_cnt;
-       u64 num_4k;       /* number of 4k "page" portions */
-       u64 page_4k_cnt;  /* counter for 4k "page" portions */
-       u64 next_4k;      /* next 4k "page" portion in buffer/chunk/listelem */
-
-       /* type EHCA_MR_PGI_PHYS section */
-       int num_phys_buf;
-       struct ib_phys_buf *phys_buf_array;
-       u64 next_buf;
-
-       /* type EHCA_MR_PGI_USER section */
-       struct ib_umem *region;
-       struct ib_umem_chunk *next_chunk;
-       u64 next_nmap;
-
-       /* type EHCA_MR_PGI_FMR section */
-       u64 *page_list;
-       u64 next_listelem;
-       /* next_4k also used within EHCA_MR_PGI_FMR */
+       u64 num_kpages;
+       u64 kpage_cnt;
+       u64 hwpage_size;     /* hw page size used for this MR */
+       u64 num_hwpages;     /* number of hw pages */
+       u64 hwpage_cnt;      /* counter for hw pages */
+       u64 next_hwpage;     /* next hw page in buffer/chunk/listelem */
+
+       union {
+               struct { /* type EHCA_MR_PGI_PHYS section */
+                       int num_phys_buf;
+                       struct ib_phys_buf *phys_buf_array;
+                       u64 next_buf;
+               } phy;
+               struct { /* type EHCA_MR_PGI_USER section */
+                       struct ib_umem *region;
+                       struct ib_umem_chunk *next_chunk;
+                       u64 next_nmap;
+               } usr;
+               struct { /* type EHCA_MR_PGI_FMR section */
+                       u64 fmr_pgsize;
+                       u64 *page_list;
+                       u64 next_listelem;
+               } fmr;
+       } u;
 };
 
 /* output parameters for MR/FMR hipz calls */
@@ -298,6 +368,8 @@ int ehca_init_av_cache(void);
 void ehca_cleanup_av_cache(void);
 int ehca_init_mrmw_cache(void);
 void ehca_cleanup_mrmw_cache(void);
+int ehca_init_small_qp_cache(void);
+void ehca_cleanup_small_qp_cache(void);
 
 extern rwlock_t ehca_qp_idr_lock;
 extern rwlock_t ehca_cq_idr_lock;
@@ -308,6 +380,10 @@ extern int ehca_static_rate;
 extern int ehca_port_act_time;
 extern int ehca_use_hp_mr;
 extern int ehca_scaling_code;
+extern int ehca_lock_hcalls;
+extern int ehca_nr_ports;
+extern int ehca_max_cq;
+extern int ehca_max_qp;
 
 struct ipzu_queue_resp {
        u32 qe_size;      /* queue entry size */
@@ -315,13 +391,15 @@ struct ipzu_queue_resp {
        u32 queue_length; /* queue length allocated in bytes */
        u32 pagesize;
        u32 toggle_state;
-       u32 dummy; /* padding for 8 byte alignment */
+       u32 offset; /* save offset within a page for small_qp */
 };
 
 struct ehca_create_cq_resp {
        u32 cq_number;
        u32 token;
        struct ipzu_queue_resp ipz_queue;
+       u32 fw_handle_ofs;
+       u32 dummy;
 };
 
 struct ehca_create_qp_resp {
@@ -332,7 +410,8 @@ struct ehca_create_qp_resp {
        u32 qkey;
        /* qp_num assigned by ehca: sqp0/1 may have got different numbers */
        u32 real_qp_num;
-       u32 dummy; /* padding for 8 byte alignment */
+       u32 fw_handle_ofs;
+       u32 dummy;
        struct ipzu_queue_resp ipz_squeue;
        struct ipzu_queue_resp ipz_rqueue;
 };
@@ -357,15 +436,29 @@ enum ehca_ll_comp_flags {
        LLQP_COMP_MASK = 0x60,
 };
 
+struct ehca_alloc_queue_parms {
+       /* input parameters */
+       int max_wr;
+       int max_sge;
+       int page_size;
+       int is_small;
+
+       /* output parameters */
+       u16 act_nr_wqes;
+       u8  act_nr_sges;
+       u32 queue_size; /* bytes for small queues, pages otherwise */
+};
+
 struct ehca_alloc_qp_parms {
-/* input parameters */
+       struct ehca_alloc_queue_parms squeue;
+       struct ehca_alloc_queue_parms rqueue;
+
+       /* input parameters */
        enum ehca_service_type servicetype;
+       int qp_storage;
        int sigtype;
        enum ehca_ext_qp_type ext_type;
        enum ehca_ll_comp_flags ll_comp_flags;
-
-       int max_send_wr, max_recv_wr;
-       int max_send_sge, max_recv_sge;
        int ud_av_l_key_ctl;
 
        u32 token;
@@ -375,22 +468,14 @@ struct ehca_alloc_qp_parms {
 
        u32 srq_qpn, srq_token, srq_limit;
 
-/* output parameters */
+       /* output parameters */
        u32 real_qp_num;
        struct ipz_qp_handle qp_handle;
        struct h_galpas galpas;
-
-       u16 act_nr_send_wqes;
-       u16 act_nr_recv_wqes;
-       u8  act_nr_recv_sges;
-       u8  act_nr_send_sges;
-
-       u32 nr_rq_pages;
-       u32 nr_sq_pages;
 };
 
 int ehca_cq_assign_qp(struct ehca_cq *cq, struct ehca_qp *qp);
 int ehca_cq_unassign_qp(struct ehca_cq *cq, unsigned int qp_num);
-struct ehca_qpehca_cq_get_qp(struct ehca_cq *cq, int qp_num);
+struct ehca_qp *ehca_cq_get_qp(struct ehca_cq *cq, int qp_num);
 
 #endif