1c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin/* 2c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * Copyright (c) 2007 Mellanox Technologies. All rights reserved. 3c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * 4c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * This software is available to you under a choice of one of two 5c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * licenses. You may choose to be licensed under the terms of the GNU 6c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * General Public License (GPL) Version 2, available from the file 7c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * COPYING in the main directory of this source tree, or the 8c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * OpenIB.org BSD license below: 9c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * 10c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * Redistribution and use in source and binary forms, with or 11c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * without modification, are permitted provided that the following 12c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * conditions are met: 13c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * 14c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * - Redistributions of source code must retain the above 15c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * copyright notice, this list of conditions and the following 16c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * disclaimer. 17c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * 18c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * - Redistributions in binary form must reproduce the above 19c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * copyright notice, this list of conditions and the following 20c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * disclaimer in the documentation and/or other materials 21c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * provided with the distribution. 22c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * 23c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * SOFTWARE. 31c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin * 32c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin */ 33c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin 34c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin#include <linux/mlx4/cq.h> 35c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin#include <linux/mlx4/qp.h> 36c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin#include <linux/mlx4/cmd.h> 37c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin 38c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin#include "mlx4_en.h" 39c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin 40c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilinstatic void mlx4_en_cq_event(struct mlx4_cq *cq, enum mlx4_event event) 41c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin{ 42c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin return; 43c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin} 44c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin 45c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin 46c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilinint mlx4_en_create_cq(struct mlx4_en_priv *priv, 47c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin struct mlx4_en_cq *cq, 48c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin int entries, int ring, enum cq_type mode) 49c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin{ 50c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin struct mlx4_en_dev *mdev = priv->mdev; 51c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin int err; 52c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin 53c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin cq->size = entries; 54f0ab34f011d805ce5b1a341409c9c26f0fc8252bYevgeny Petrilin cq->buf_size = cq->size * sizeof(struct mlx4_cqe); 55c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin 56c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin cq->ring = ring; 57c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin cq->is_tx = mode; 58c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin spin_lock_init(&cq->lock); 59c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin 60c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin err = mlx4_alloc_hwq_res(mdev->dev, &cq->wqres, 61c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin cq->buf_size, 2 * PAGE_SIZE); 62c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin if (err) 63c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin return err; 64c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin 65c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin err = mlx4_en_map_buffer(&cq->wqres.buf); 66c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin if (err) 67c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin mlx4_free_hwq_res(mdev->dev, &cq->wqres, cq->buf_size); 68b51968d676db1c4e541b4c84de7ce7af812c9e9fYevgeny Petrilin else 69b51968d676db1c4e541b4c84de7ce7af812c9e9fYevgeny Petrilin cq->buf = (struct mlx4_cqe *) cq->wqres.buf.direct.buf; 70c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin 71c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin return err; 72c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin} 73c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin 7476532d0c7e7424914ab6f24683c63e50f0a08f1cAlexander Gullerint mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq, 7576532d0c7e7424914ab6f24683c63e50f0a08f1cAlexander Guller int cq_idx) 76c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin{ 77c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin struct mlx4_en_dev *mdev = priv->mdev; 781fb9876e9bf895ea4127ff17180f1b2ab37771b6Yevgeny Petrilin int err = 0; 791fb9876e9bf895ea4127ff17180f1b2ab37771b6Yevgeny Petrilin char name[25]; 80c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin 81c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin cq->dev = mdev->pndev[priv->port]; 82c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin cq->mcq.set_ci_db = cq->wqres.db.db; 83c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin cq->mcq.arm_db = cq->wqres.db.db + 1; 84c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin *cq->mcq.set_ci_db = 0; 85c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin *cq->mcq.arm_db = 0; 86c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin memset(cq->buf, 0, cq->buf_size); 87c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin 881fb9876e9bf895ea4127ff17180f1b2ab37771b6Yevgeny Petrilin if (cq->is_tx == RX) { 891fb9876e9bf895ea4127ff17180f1b2ab37771b6Yevgeny Petrilin if (mdev->dev->caps.comp_pool) { 901fb9876e9bf895ea4127ff17180f1b2ab37771b6Yevgeny Petrilin if (!cq->vector) { 9176532d0c7e7424914ab6f24683c63e50f0a08f1cAlexander Guller sprintf(name, "%s-%d", priv->dev->name, 9276532d0c7e7424914ab6f24683c63e50f0a08f1cAlexander Guller cq->ring); 9376532d0c7e7424914ab6f24683c63e50f0a08f1cAlexander Guller /* Set IRQ for specific name (per ring) */ 941fb9876e9bf895ea4127ff17180f1b2ab37771b6Yevgeny Petrilin if (mlx4_assign_eq(mdev->dev, name, &cq->vector)) { 9576532d0c7e7424914ab6f24683c63e50f0a08f1cAlexander Guller cq->vector = (cq->ring + 1 + priv->port) 9676532d0c7e7424914ab6f24683c63e50f0a08f1cAlexander Guller % mdev->dev->caps.num_comp_vectors; 971fb9876e9bf895ea4127ff17180f1b2ab37771b6Yevgeny Petrilin mlx4_warn(mdev, "Failed Assigning an EQ to " 9876532d0c7e7424914ab6f24683c63e50f0a08f1cAlexander Guller "%s ,Falling back to legacy EQ's\n", 9976532d0c7e7424914ab6f24683c63e50f0a08f1cAlexander Guller name); 1001fb9876e9bf895ea4127ff17180f1b2ab37771b6Yevgeny Petrilin } 1011fb9876e9bf895ea4127ff17180f1b2ab37771b6Yevgeny Petrilin } 1021fb9876e9bf895ea4127ff17180f1b2ab37771b6Yevgeny Petrilin } else { 1031fb9876e9bf895ea4127ff17180f1b2ab37771b6Yevgeny Petrilin cq->vector = (cq->ring + 1 + priv->port) % 1041fb9876e9bf895ea4127ff17180f1b2ab37771b6Yevgeny Petrilin mdev->dev->caps.num_comp_vectors; 1051fb9876e9bf895ea4127ff17180f1b2ab37771b6Yevgeny Petrilin } 1061fb9876e9bf895ea4127ff17180f1b2ab37771b6Yevgeny Petrilin } else { 10776532d0c7e7424914ab6f24683c63e50f0a08f1cAlexander Guller /* For TX we use the same irq per 10876532d0c7e7424914ab6f24683c63e50f0a08f1cAlexander Guller ring we assigned for the RX */ 10976532d0c7e7424914ab6f24683c63e50f0a08f1cAlexander Guller struct mlx4_en_cq *rx_cq; 11076532d0c7e7424914ab6f24683c63e50f0a08f1cAlexander Guller 11176532d0c7e7424914ab6f24683c63e50f0a08f1cAlexander Guller cq_idx = cq_idx % priv->rx_ring_num; 11276532d0c7e7424914ab6f24683c63e50f0a08f1cAlexander Guller rx_cq = &priv->rx_cq[cq_idx]; 11376532d0c7e7424914ab6f24683c63e50f0a08f1cAlexander Guller cq->vector = rx_cq->vector; 1141fb9876e9bf895ea4127ff17180f1b2ab37771b6Yevgeny Petrilin } 1151fb9876e9bf895ea4127ff17180f1b2ab37771b6Yevgeny Petrilin 11638aab07c14adbf3c7257793d764a91923341e96aYevgeny Petrilin if (!cq->is_tx) 11738aab07c14adbf3c7257793d764a91923341e96aYevgeny Petrilin cq->size = priv->rx_ring[cq->ring].actual_size; 11838aab07c14adbf3c7257793d764a91923341e96aYevgeny Petrilin 119c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin err = mlx4_cq_alloc(mdev->dev, cq->size, &cq->wqres.mtt, &mdev->priv_uar, 120f0ab34f011d805ce5b1a341409c9c26f0fc8252bYevgeny Petrilin cq->wqres.db.dma, &cq->mcq, cq->vector, 0); 121c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin if (err) 122c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin return err; 123c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin 124c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin cq->mcq.comp = cq->is_tx ? mlx4_en_tx_irq : mlx4_en_rx_irq; 125c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin cq->mcq.event = mlx4_en_cq_event; 126c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin 127c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin if (cq->is_tx) { 128c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin init_timer(&cq->timer); 129c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin cq->timer.function = mlx4_en_poll_tx_cq; 130c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin cq->timer.data = (unsigned long) cq; 131c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin } else { 132c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin netif_napi_add(cq->dev, &cq->napi, mlx4_en_poll_rx_cq, 64); 133c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin napi_enable(&cq->napi); 134c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin } 135c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin 136c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin return 0; 137c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin} 138c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin 139fe0af03c69abc2178fc4667664726ec1f688539bAlexander Gullervoid mlx4_en_destroy_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq) 140c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin{ 141c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin struct mlx4_en_dev *mdev = priv->mdev; 142c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin 143c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin mlx4_en_unmap_buffer(&cq->wqres.buf); 144c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin mlx4_free_hwq_res(mdev->dev, &cq->wqres, cq->buf_size); 145fe0af03c69abc2178fc4667664726ec1f688539bAlexander Guller if (priv->mdev->dev->caps.comp_pool && cq->vector) 1461fb9876e9bf895ea4127ff17180f1b2ab37771b6Yevgeny Petrilin mlx4_release_eq(priv->mdev->dev, cq->vector); 147cd3109d23c32452c85d73cc1a01282846a23582cYevgeny Petrilin cq->vector = 0; 148c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin cq->buf_size = 0; 149c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin cq->buf = NULL; 150c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin} 151c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin 152c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilinvoid mlx4_en_deactivate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq) 153c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin{ 154c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin struct mlx4_en_dev *mdev = priv->mdev; 155c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin 156c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin if (cq->is_tx) 157c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin del_timer(&cq->timer); 15872876a603422d3767273ffb3918033fa1bfda0f3Yevgeny Petrilin else { 159c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin napi_disable(&cq->napi); 16072876a603422d3767273ffb3918033fa1bfda0f3Yevgeny Petrilin netif_napi_del(&cq->napi); 16172876a603422d3767273ffb3918033fa1bfda0f3Yevgeny Petrilin } 162c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin 163c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin mlx4_cq_free(mdev->dev, &cq->mcq); 164c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin} 165c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin 166c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin/* Set rx cq moderation parameters */ 167c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilinint mlx4_en_set_cq_moder(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq) 168c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin{ 169c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin return mlx4_cq_modify(priv->mdev->dev, &cq->mcq, 170c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin cq->moder_cnt, cq->moder_time); 171c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin} 172c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin 173c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilinint mlx4_en_arm_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq) 174c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin{ 175c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin mlx4_cq_arm(&cq->mcq, MLX4_CQ_DB_REQ_NOT, priv->mdev->uar_map, 176c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin &priv->mdev->uar_lock); 177c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin 178c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin return 0; 179c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin} 180c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin 181c27a02cd94d6695fbe5858ca364b1e415af02212Yevgeny Petrilin 182