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