en_cq.c revision 219820
1219820Sjeff/* 2219820Sjeff * Copyright (c) 2007 Mellanox Technologies. All rights reserved. 3219820Sjeff * 4219820Sjeff * This software is available to you under a choice of one of two 5219820Sjeff * licenses. You may choose to be licensed under the terms of the GNU 6219820Sjeff * General Public License (GPL) Version 2, available from the file 7219820Sjeff * COPYING in the main directory of this source tree, or the 8219820Sjeff * OpenIB.org BSD license below: 9219820Sjeff * 10219820Sjeff * Redistribution and use in source and binary forms, with or 11219820Sjeff * without modification, are permitted provided that the following 12219820Sjeff * conditions are met: 13219820Sjeff * 14219820Sjeff * - Redistributions of source code must retain the above 15219820Sjeff * copyright notice, this list of conditions and the following 16219820Sjeff * disclaimer. 17219820Sjeff * 18219820Sjeff * - Redistributions in binary form must reproduce the above 19219820Sjeff * copyright notice, this list of conditions and the following 20219820Sjeff * disclaimer in the documentation and/or other materials 21219820Sjeff * provided with the distribution. 22219820Sjeff * 23219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30219820Sjeff * SOFTWARE. 31219820Sjeff * 32219820Sjeff */ 33219820Sjeff 34219820Sjeff#include "mlx4_en.h" 35219820Sjeff 36219820Sjeff#include <linux/mlx4/cq.h> 37219820Sjeff#include <linux/mlx4/qp.h> 38219820Sjeff#include <linux/mlx4/cmd.h> 39219820Sjeff 40219820Sjeffstatic void mlx4_en_cq_event(struct mlx4_cq *cq, enum mlx4_event event) 41219820Sjeff{ 42219820Sjeff return; 43219820Sjeff} 44219820Sjeff 45219820Sjeff 46219820Sjeffint mlx4_en_create_cq(struct mlx4_en_priv *priv, 47219820Sjeff struct mlx4_en_cq *cq, 48219820Sjeff int entries, int ring, enum cq_type mode) 49219820Sjeff{ 50219820Sjeff struct mlx4_en_dev *mdev = priv->mdev; 51219820Sjeff int err; 52219820Sjeff 53219820Sjeff cq->size = entries; 54219820Sjeff if (mode == RX) { 55219820Sjeff cq->buf_size = cq->size * sizeof(struct mlx4_cqe); 56219820Sjeff cq->vector = (ring + priv->port) % 57219820Sjeff mdev->dev->caps.num_comp_vectors; 58219820Sjeff TASK_INIT(&cq->cq_task, 0, mlx4_en_rx_que, cq); 59219820Sjeff } else { 60219820Sjeff cq->buf_size = sizeof(struct mlx4_cqe); 61219820Sjeff cq->vector = MLX4_LEAST_ATTACHED_VECTOR; 62219820Sjeff TASK_INIT(&cq->cq_task, 0, mlx4_en_tx_que, cq); 63219820Sjeff } 64219820Sjeff 65219820Sjeff cq->tq = taskqueue_create_fast("mlx4_en_que", M_NOWAIT, 66219820Sjeff taskqueue_thread_enqueue, &cq->tq); 67219820Sjeff taskqueue_start_threads(&cq->tq, 1, PI_NET, "%s cq", 68219820Sjeff if_name(priv->dev)); 69219820Sjeff cq->ring = ring; 70219820Sjeff cq->is_tx = mode; 71219820Sjeff mtx_init(&cq->lock.m, "mlx4 cq", NULL, MTX_DEF); 72219820Sjeff 73219820Sjeff err = mlx4_alloc_hwq_res(mdev->dev, &cq->wqres, 74219820Sjeff cq->buf_size, 2 * PAGE_SIZE); 75219820Sjeff if (err) 76219820Sjeff return err; 77219820Sjeff 78219820Sjeff err = mlx4_en_map_buffer(&cq->wqres.buf); 79219820Sjeff if (err) 80219820Sjeff mlx4_free_hwq_res(mdev->dev, &cq->wqres, cq->buf_size); 81219820Sjeff else 82219820Sjeff cq->buf = (struct mlx4_cqe *) cq->wqres.buf.direct.buf; 83219820Sjeff 84219820Sjeff return err; 85219820Sjeff} 86219820Sjeff 87219820Sjeffint mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq) 88219820Sjeff{ 89219820Sjeff struct mlx4_en_dev *mdev = priv->mdev; 90219820Sjeff int err; 91219820Sjeff 92219820Sjeff cq->dev = mdev->pndev[priv->port]; 93219820Sjeff cq->mcq.set_ci_db = cq->wqres.db.db; 94219820Sjeff cq->mcq.arm_db = cq->wqres.db.db + 1; 95219820Sjeff *cq->mcq.set_ci_db = 0; 96219820Sjeff *cq->mcq.arm_db = 0; 97219820Sjeff memset(cq->buf, 0, cq->buf_size); 98219820Sjeff 99219820Sjeff if (!cq->is_tx) 100219820Sjeff cq->size = priv->rx_ring[cq->ring].actual_size; 101219820Sjeff 102219820Sjeff err = mlx4_cq_alloc(mdev->dev, cq->size, &cq->wqres.mtt, &mdev->priv_uar, 103219820Sjeff cq->wqres.db.dma, &cq->mcq, cq->vector, cq->is_tx); 104219820Sjeff if (err) 105219820Sjeff return err; 106219820Sjeff 107219820Sjeff cq->mcq.comp = cq->is_tx ? mlx4_en_tx_irq : mlx4_en_rx_irq; 108219820Sjeff cq->mcq.event = mlx4_en_cq_event; 109219820Sjeff 110219820Sjeff if (cq->is_tx) { 111219820Sjeff init_timer(&cq->timer); 112219820Sjeff cq->timer.function = mlx4_en_poll_tx_cq; 113219820Sjeff cq->timer.data = (unsigned long) cq; 114219820Sjeff } 115219820Sjeff 116219820Sjeff return 0; 117219820Sjeff} 118219820Sjeff 119219820Sjeffvoid mlx4_en_destroy_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq) 120219820Sjeff{ 121219820Sjeff struct mlx4_en_dev *mdev = priv->mdev; 122219820Sjeff 123219820Sjeff taskqueue_drain(cq->tq, &cq->cq_task); 124219820Sjeff taskqueue_free(cq->tq); 125219820Sjeff mlx4_en_unmap_buffer(&cq->wqres.buf); 126219820Sjeff mlx4_free_hwq_res(mdev->dev, &cq->wqres, cq->buf_size); 127219820Sjeff cq->buf_size = 0; 128219820Sjeff cq->buf = NULL; 129219820Sjeff mtx_destroy(&cq->lock.m); 130219820Sjeff} 131219820Sjeff 132219820Sjeffvoid mlx4_en_deactivate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq) 133219820Sjeff{ 134219820Sjeff struct mlx4_en_dev *mdev = priv->mdev; 135219820Sjeff 136219820Sjeff taskqueue_drain(cq->tq, &cq->cq_task); 137219820Sjeff if (cq->is_tx) 138219820Sjeff del_timer(&cq->timer); 139219820Sjeff 140219820Sjeff mlx4_cq_free(mdev->dev, &cq->mcq); 141219820Sjeff} 142219820Sjeff 143219820Sjeff/* Set rx cq moderation parameters */ 144219820Sjeffint mlx4_en_set_cq_moder(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq) 145219820Sjeff{ 146219820Sjeff return mlx4_cq_modify(priv->mdev->dev, &cq->mcq, 147219820Sjeff cq->moder_cnt, cq->moder_time); 148219820Sjeff} 149219820Sjeff 150219820Sjeffint mlx4_en_arm_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq) 151219820Sjeff{ 152219820Sjeff mlx4_cq_arm(&cq->mcq, MLX4_CQ_DB_REQ_NOT, priv->mdev->uar_map, 153219820Sjeff &priv->mdev->uar_lock); 154219820Sjeff 155219820Sjeff return 0; 156219820Sjeff} 157219820Sjeff 158219820Sjeff 159