diff options
author | Yevgeny Petrilin <yevgenyp@mellanox.co.il> | 2008-04-23 14:55:45 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2008-04-23 14:55:45 -0400 |
commit | 6296883ca4cd52dafb45f191d24102e28ded38f2 (patch) | |
tree | 341e90a9560d8cf6b498d249a6ac81aeea97dd7b /drivers/net | |
parent | 14fb05b3497351fbeb514381bcd227d84e115bd9 (diff) |
mlx4_core: Move kernel doorbell management into core
In addition to mlx4_ib, there will be ethernet and FC consumers of
mlx4_core, so move the code for managing kernel doorbells into the
core module to avoid having to duplicate this multiple times.
Signed-off-by: Yevgeny Petrilin <yevgenyp@mellanox.co.il>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/mlx4/alloc.c | 111 | ||||
-rw-r--r-- | drivers/net/mlx4/main.c | 3 | ||||
-rw-r--r-- | drivers/net/mlx4/mlx4.h | 3 |
3 files changed, 117 insertions, 0 deletions
diff --git a/drivers/net/mlx4/alloc.c b/drivers/net/mlx4/alloc.c index 75ef9d0d974d..43c6d04bb880 100644 --- a/drivers/net/mlx4/alloc.c +++ b/drivers/net/mlx4/alloc.c | |||
@@ -196,3 +196,114 @@ void mlx4_buf_free(struct mlx4_dev *dev, int size, struct mlx4_buf *buf) | |||
196 | } | 196 | } |
197 | } | 197 | } |
198 | EXPORT_SYMBOL_GPL(mlx4_buf_free); | 198 | EXPORT_SYMBOL_GPL(mlx4_buf_free); |
199 | |||
200 | static struct mlx4_db_pgdir *mlx4_alloc_db_pgdir(struct device *dma_device) | ||
201 | { | ||
202 | struct mlx4_db_pgdir *pgdir; | ||
203 | |||
204 | pgdir = kzalloc(sizeof *pgdir, GFP_KERNEL); | ||
205 | if (!pgdir) | ||
206 | return NULL; | ||
207 | |||
208 | bitmap_fill(pgdir->order1, MLX4_DB_PER_PAGE / 2); | ||
209 | pgdir->bits[0] = pgdir->order0; | ||
210 | pgdir->bits[1] = pgdir->order1; | ||
211 | pgdir->db_page = dma_alloc_coherent(dma_device, PAGE_SIZE, | ||
212 | &pgdir->db_dma, GFP_KERNEL); | ||
213 | if (!pgdir->db_page) { | ||
214 | kfree(pgdir); | ||
215 | return NULL; | ||
216 | } | ||
217 | |||
218 | return pgdir; | ||
219 | } | ||
220 | |||
221 | static int mlx4_alloc_db_from_pgdir(struct mlx4_db_pgdir *pgdir, | ||
222 | struct mlx4_db *db, int order) | ||
223 | { | ||
224 | int o; | ||
225 | int i; | ||
226 | |||
227 | for (o = order; o <= 1; ++o) { | ||
228 | i = find_first_bit(pgdir->bits[o], MLX4_DB_PER_PAGE >> o); | ||
229 | if (i < MLX4_DB_PER_PAGE >> o) | ||
230 | goto found; | ||
231 | } | ||
232 | |||
233 | return -ENOMEM; | ||
234 | |||
235 | found: | ||
236 | clear_bit(i, pgdir->bits[o]); | ||
237 | |||
238 | i <<= o; | ||
239 | |||
240 | if (o > order) | ||
241 | set_bit(i ^ 1, pgdir->bits[order]); | ||
242 | |||
243 | db->u.pgdir = pgdir; | ||
244 | db->index = i; | ||
245 | db->db = pgdir->db_page + db->index; | ||
246 | db->dma = pgdir->db_dma + db->index * 4; | ||
247 | db->order = order; | ||
248 | |||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | int mlx4_db_alloc(struct mlx4_dev *dev, struct mlx4_db *db, int order) | ||
253 | { | ||
254 | struct mlx4_priv *priv = mlx4_priv(dev); | ||
255 | struct mlx4_db_pgdir *pgdir; | ||
256 | int ret = 0; | ||
257 | |||
258 | mutex_lock(&priv->pgdir_mutex); | ||
259 | |||
260 | list_for_each_entry(pgdir, &priv->pgdir_list, list) | ||
261 | if (!mlx4_alloc_db_from_pgdir(pgdir, db, order)) | ||
262 | goto out; | ||
263 | |||
264 | pgdir = mlx4_alloc_db_pgdir(&(dev->pdev->dev)); | ||
265 | if (!pgdir) { | ||
266 | ret = -ENOMEM; | ||
267 | goto out; | ||
268 | } | ||
269 | |||
270 | list_add(&pgdir->list, &priv->pgdir_list); | ||
271 | |||
272 | /* This should never fail -- we just allocated an empty page: */ | ||
273 | WARN_ON(mlx4_alloc_db_from_pgdir(pgdir, db, order)); | ||
274 | |||
275 | out: | ||
276 | mutex_unlock(&priv->pgdir_mutex); | ||
277 | |||
278 | return ret; | ||
279 | } | ||
280 | EXPORT_SYMBOL_GPL(mlx4_db_alloc); | ||
281 | |||
282 | void mlx4_db_free(struct mlx4_dev *dev, struct mlx4_db *db) | ||
283 | { | ||
284 | struct mlx4_priv *priv = mlx4_priv(dev); | ||
285 | int o; | ||
286 | int i; | ||
287 | |||
288 | mutex_lock(&priv->pgdir_mutex); | ||
289 | |||
290 | o = db->order; | ||
291 | i = db->index; | ||
292 | |||
293 | if (db->order == 0 && test_bit(i ^ 1, db->u.pgdir->order0)) { | ||
294 | clear_bit(i ^ 1, db->u.pgdir->order0); | ||
295 | ++o; | ||
296 | } | ||
297 | i >>= o; | ||
298 | set_bit(i, db->u.pgdir->bits[o]); | ||
299 | |||
300 | if (bitmap_full(db->u.pgdir->order1, MLX4_DB_PER_PAGE / 2)) { | ||
301 | dma_free_coherent(&(dev->pdev->dev), PAGE_SIZE, | ||
302 | db->u.pgdir->db_page, db->u.pgdir->db_dma); | ||
303 | list_del(&db->u.pgdir->list); | ||
304 | kfree(db->u.pgdir); | ||
305 | } | ||
306 | |||
307 | mutex_unlock(&priv->pgdir_mutex); | ||
308 | } | ||
309 | EXPORT_SYMBOL_GPL(mlx4_db_free); | ||
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c index 49a4acab5e82..a6aa49fc1d68 100644 --- a/drivers/net/mlx4/main.c +++ b/drivers/net/mlx4/main.c | |||
@@ -798,6 +798,9 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
798 | INIT_LIST_HEAD(&priv->ctx_list); | 798 | INIT_LIST_HEAD(&priv->ctx_list); |
799 | spin_lock_init(&priv->ctx_lock); | 799 | spin_lock_init(&priv->ctx_lock); |
800 | 800 | ||
801 | INIT_LIST_HEAD(&priv->pgdir_list); | ||
802 | mutex_init(&priv->pgdir_mutex); | ||
803 | |||
801 | /* | 804 | /* |
802 | * Now reset the HCA before we touch the PCI capabilities or | 805 | * Now reset the HCA before we touch the PCI capabilities or |
803 | * attempt a firmware command, since a boot ROM may have left | 806 | * attempt a firmware command, since a boot ROM may have left |
diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h index 73336810e652..a4023c2dd050 100644 --- a/drivers/net/mlx4/mlx4.h +++ b/drivers/net/mlx4/mlx4.h | |||
@@ -257,6 +257,9 @@ struct mlx4_priv { | |||
257 | struct list_head ctx_list; | 257 | struct list_head ctx_list; |
258 | spinlock_t ctx_lock; | 258 | spinlock_t ctx_lock; |
259 | 259 | ||
260 | struct list_head pgdir_list; | ||
261 | struct mutex pgdir_mutex; | ||
262 | |||
260 | struct mlx4_fw fw; | 263 | struct mlx4_fw fw; |
261 | struct mlx4_cmd cmd; | 264 | struct mlx4_cmd cmd; |
262 | 265 | ||