0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 #ifndef MTHCA_MEMFREE_H
0036 #define MTHCA_MEMFREE_H
0037
0038 #include <linux/list.h>
0039 #include <linux/mutex.h>
0040
0041 #define MTHCA_ICM_CHUNK_LEN \
0042 ((256 - sizeof (struct list_head) - 2 * sizeof (int)) / \
0043 (sizeof (struct scatterlist)))
0044
0045 enum {
0046 MTHCA_ICM_PAGE_SHIFT = 12,
0047 MTHCA_ICM_PAGE_SIZE = 1 << MTHCA_ICM_PAGE_SHIFT,
0048 MTHCA_DB_REC_PER_PAGE = MTHCA_ICM_PAGE_SIZE / 8
0049 };
0050
0051 struct mthca_icm_chunk {
0052 struct list_head list;
0053 int npages;
0054 int nsg;
0055 struct scatterlist mem[MTHCA_ICM_CHUNK_LEN];
0056 };
0057
0058 struct mthca_icm {
0059 struct list_head chunk_list;
0060 int refcount;
0061 };
0062
0063 struct mthca_icm_table {
0064 u64 virt;
0065 int num_icm;
0066 int num_obj;
0067 int obj_size;
0068 int lowmem;
0069 int coherent;
0070 struct mutex mutex;
0071 struct mthca_icm *icm[];
0072 };
0073
0074 struct mthca_icm_iter {
0075 struct mthca_icm *icm;
0076 struct mthca_icm_chunk *chunk;
0077 int page_idx;
0078 };
0079
0080 struct mthca_dev;
0081
0082 struct mthca_icm *mthca_alloc_icm(struct mthca_dev *dev, int npages,
0083 gfp_t gfp_mask, int coherent);
0084 void mthca_free_icm(struct mthca_dev *dev, struct mthca_icm *icm, int coherent);
0085
0086 struct mthca_icm_table *mthca_alloc_icm_table(struct mthca_dev *dev,
0087 u64 virt, int obj_size,
0088 int nobj, int reserved,
0089 int use_lowmem, int use_coherent);
0090 void mthca_free_icm_table(struct mthca_dev *dev, struct mthca_icm_table *table);
0091 int mthca_table_get(struct mthca_dev *dev, struct mthca_icm_table *table, int obj);
0092 void mthca_table_put(struct mthca_dev *dev, struct mthca_icm_table *table, int obj);
0093 void *mthca_table_find(struct mthca_icm_table *table, int obj, dma_addr_t *dma_handle);
0094 int mthca_table_get_range(struct mthca_dev *dev, struct mthca_icm_table *table,
0095 int start, int end);
0096 void mthca_table_put_range(struct mthca_dev *dev, struct mthca_icm_table *table,
0097 int start, int end);
0098
0099 static inline void mthca_icm_first(struct mthca_icm *icm,
0100 struct mthca_icm_iter *iter)
0101 {
0102 iter->icm = icm;
0103 iter->chunk = list_empty(&icm->chunk_list) ?
0104 NULL : list_entry(icm->chunk_list.next,
0105 struct mthca_icm_chunk, list);
0106 iter->page_idx = 0;
0107 }
0108
0109 static inline int mthca_icm_last(struct mthca_icm_iter *iter)
0110 {
0111 return !iter->chunk;
0112 }
0113
0114 static inline void mthca_icm_next(struct mthca_icm_iter *iter)
0115 {
0116 if (++iter->page_idx >= iter->chunk->nsg) {
0117 if (iter->chunk->list.next == &iter->icm->chunk_list) {
0118 iter->chunk = NULL;
0119 return;
0120 }
0121
0122 iter->chunk = list_entry(iter->chunk->list.next,
0123 struct mthca_icm_chunk, list);
0124 iter->page_idx = 0;
0125 }
0126 }
0127
0128 static inline dma_addr_t mthca_icm_addr(struct mthca_icm_iter *iter)
0129 {
0130 return sg_dma_address(&iter->chunk->mem[iter->page_idx]);
0131 }
0132
0133 static inline unsigned long mthca_icm_size(struct mthca_icm_iter *iter)
0134 {
0135 return sg_dma_len(&iter->chunk->mem[iter->page_idx]);
0136 }
0137
0138 struct mthca_db_page {
0139 DECLARE_BITMAP(used, MTHCA_DB_REC_PER_PAGE);
0140 __be64 *db_rec;
0141 dma_addr_t mapping;
0142 };
0143
0144 struct mthca_db_table {
0145 int npages;
0146 int max_group1;
0147 int min_group2;
0148 struct mthca_db_page *page;
0149 struct mutex mutex;
0150 };
0151
0152 enum mthca_db_type {
0153 MTHCA_DB_TYPE_INVALID = 0x0,
0154 MTHCA_DB_TYPE_CQ_SET_CI = 0x1,
0155 MTHCA_DB_TYPE_CQ_ARM = 0x2,
0156 MTHCA_DB_TYPE_SQ = 0x3,
0157 MTHCA_DB_TYPE_RQ = 0x4,
0158 MTHCA_DB_TYPE_SRQ = 0x5,
0159 MTHCA_DB_TYPE_GROUP_SEP = 0x7
0160 };
0161
0162 struct mthca_user_db_table;
0163 struct mthca_uar;
0164
0165 int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
0166 struct mthca_user_db_table *db_tab, int index, u64 uaddr);
0167 void mthca_unmap_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
0168 struct mthca_user_db_table *db_tab, int index);
0169 struct mthca_user_db_table *mthca_init_user_db_tab(struct mthca_dev *dev);
0170 void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar,
0171 struct mthca_user_db_table *db_tab);
0172
0173 int mthca_init_db_tab(struct mthca_dev *dev);
0174 void mthca_cleanup_db_tab(struct mthca_dev *dev);
0175 int mthca_alloc_db(struct mthca_dev *dev, enum mthca_db_type type,
0176 u32 qn, __be32 **db);
0177 void mthca_free_db(struct mthca_dev *dev, int type, int db_index);
0178
0179 #endif