Files
@ bd21c8aa7237
Branch filter:
Location: vmkdrivers/vmkdrivers/src_9/drivers/net/mlnx/mlx4_core/icm.h
bd21c8aa7237
6.3 KiB
text/x-chdr
ESXi-6.0.0b
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | /*
* Copyright (c) 2005-2008, 2011-2013 Mellanox Technologies.
* All rights reserved.
* Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved.
*
* This software is available to you 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.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#ifndef MLX4_ICM_H
#define MLX4_ICM_H
#include <linux/list.h>
#include <linux/pci.h>
#include <linux/mutex.h>
#define MLX4_ICM_CHUNK_LEN \
((256 - sizeof (struct list_head) - 2 * sizeof (int)) / \
(sizeof (struct scatterlist)))
enum {
MLX4_ICM_PAGE_SHIFT = 12,
MLX4_ICM_PAGE_SIZE = 1 << MLX4_ICM_PAGE_SHIFT,
};
struct mlx4_icm_chunk {
struct list_head list;
int npages;
int nsg;
#ifdef __VMKERNEL_MODULE__
struct scatterlist mem;
/*
* We need to save the virtual address for every page
* we are allocating because in vmkernel going back from
* physical address to virtual one can give different
* virtual address. Both virtual addresses point to same
* location but you can dma_free_coherent the memory only
* with the original virtual address you received from
* dma_alloc_coherent
*/
void *sg_virt_addr[MLX4_ICM_CHUNK_LEN];
#else
struct scatterlist mem[MLX4_ICM_CHUNK_LEN];
#endif /* __VMKERNEL_MODULE__ */
};
struct mlx4_icm {
struct list_head chunk_list;
int refcount;
};
struct mlx4_icm_iter {
struct mlx4_icm *icm;
struct mlx4_icm_chunk *chunk;
int page_idx;
};
struct mlx4_dev;
struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages,
gfp_t gfp_mask, int coherent);
void mlx4_free_icm(struct mlx4_dev *dev, struct mlx4_icm *icm, int coherent);
int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj);
void mlx4_table_put(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj);
int mlx4_table_get_range(struct mlx4_dev *dev, struct mlx4_icm_table *table,
int start, int end);
void mlx4_table_put_range(struct mlx4_dev *dev, struct mlx4_icm_table *table,
int start, int end);
int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table,
u64 virt, int obj_size, int nobj, int reserved,
int use_lowmem, int use_coherent);
void mlx4_cleanup_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table);
int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj);
void mlx4_table_put(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj);
void *mlx4_table_find(struct mlx4_icm_table *table, int obj, dma_addr_t *dma_handle);
int mlx4_table_get_range(struct mlx4_dev *dev, struct mlx4_icm_table *table,
int start, int end);
void mlx4_table_put_range(struct mlx4_dev *dev, struct mlx4_icm_table *table,
int start, int end);
static inline void mlx4_icm_first(struct mlx4_icm *icm,
struct mlx4_icm_iter *iter)
{
iter->icm = icm;
iter->chunk = list_empty(&icm->chunk_list) ?
NULL : list_entry(icm->chunk_list.next,
struct mlx4_icm_chunk, list);
iter->page_idx = 0;
#ifdef __VMKERNEL_MODULE__
/*
* We need to reset the current location inside the
* scatterlist (the pages list) in vmkernel.
* The scatterlist in vmkernel isn't an array but rather
* a data structure. We are going on all pages one by one
* with sg_next and we return to first one by sg_reset
*/
if (iter->chunk)
sg_reset(&(iter->chunk->mem));
#endif /* __VMKERNEL_MODULE__ */
}
static inline int mlx4_icm_last(struct mlx4_icm_iter *iter)
{
return !iter->chunk;
}
static inline void mlx4_icm_next(struct mlx4_icm_iter *iter)
{
if (++iter->page_idx >= iter->chunk->nsg) {
if (iter->chunk->list.next == &iter->icm->chunk_list) {
iter->chunk = NULL;
return;
}
iter->chunk = list_entry(iter->chunk->list.next,
struct mlx4_icm_chunk, list);
iter->page_idx = 0;
#ifdef __VMKERNEL_MODULE__
sg_reset(&(iter->chunk->mem));
} else {
sg_next(&(iter->chunk->mem));
}
#endif /* __VMKERNEL_MODULE__ */
}
static inline dma_addr_t mlx4_icm_addr(struct mlx4_icm_iter *iter)
{
#ifdef __VMKERNEL_MODULE__
return sg_dma_address(&iter->chunk->mem);
#else
return sg_dma_address(&iter->chunk->mem[iter->page_idx]);
#endif /* __VMKERNEL_MODULE__ */
}
static inline unsigned long mlx4_icm_size(struct mlx4_icm_iter *iter)
{
#ifdef __VMKERNEL_MODULE__
return sg_dma_len(&iter->chunk->mem);
#else
return sg_dma_len(&iter->chunk->mem[iter->page_idx]);
#endif /* __VMKERNEL_MODULE__ */
}
#ifdef __VMKERNEL_MODULE__
#define MLNX_VMKSGEL(mem) (mem)->vmksgel
#define MLNX_VMKIOSGEL(mem) (mem)->vmkIOsgel
#define MLNX_CURSGEL(mem) (mem)->cursgel
#define MLNX_CURIOSGEL(mem) (mem)->curIOsgel
#define MLNX_PREMAPED(mem) (mem)->premapped
#define MLNX_VMKSGA(mem) (mem)->vmksga
#define MLNX_VMKIOSGA(mem) (mem)->vmkIOsga
#define MLNX_NUMELEM(sga) (sga)->numElems
#define MLNX_MAXELEM(sga) (sga)->maxElems
#define MLNX_VMKSGA_NUMELEM(mem) MLNX_NUMELEM(MLNX_VMKSGA(mem))
#define MLNX_VMKSGA_MAXELEM(mem) MLNX_MAXELEM(MLNX_VMKSGA(mem))
#define MLNX_VMKIOSGA_NUMELEM(mem) MLNX_NUMELEM(MLNX_VMKIOSGA(mem))
#define MLNX_VMKIOSGA_MAXELEM(mem) MLNX_MAXELEM(MLNX_VMKIOSGA(mem))
#define MLNX_LENGTH(sgel) (sgel)->length
#define MLNX_CURSGEL_LENGTH(mem) MLNX_LENGTH(MLNX_CURSGEL(mem))
#define MLNX_CURIOSGEL_LENGTH(mem) MLNX_LENGTH(MLNX_CURIOSGEL(mem))
#define MLNX_ADDR(sgel) (sgel)->addr
#define MLNX_CURSGEL_ADDR(mem) MLNX_ADDR(MLNX_CURSGEL(mem))
#define MLNX_IOADDR(sgel) (sgel)->ioAddr
#define MLNX_CURIOSGEL_IOADDR(mem) MLNX_IOADDR(MLNX_CURIOSGEL(mem))
static inline int mlx4_alloc_sga(vmk_SgArray** ptr, gfp_t gfp_mask)
{
*ptr = kmalloc(sizeof(struct vmk_SgElem) * MLX4_ICM_CHUNK_LEN
+ sizeof(struct vmk_SgArray), gfp_mask);
if(!*ptr)
return -ENOMEM;
MLNX_MAXELEM(*ptr) = MLX4_ICM_CHUNK_LEN;
MLNX_NUMELEM(*ptr) = 0;
return 0;
}
static inline int mlx4_alloc_sgel(vmk_sgelem **ptr, gfp_t gfp_mask)
{
*ptr = kmalloc(sizeof(vmk_sgelem) * MLX4_ICM_CHUNK_LEN , gfp_mask);
if(!*ptr)
return -ENOMEM;
return 0;
}
#endif /* __VMKERNEL_MODULE__ */
int mlx4_MAP_ICM_AUX(struct mlx4_dev *dev, struct mlx4_icm *icm);
int mlx4_UNMAP_ICM_AUX(struct mlx4_dev *dev);
#endif /* MLX4_ICM_H */
|