diff options
author | Yevgeny Petrilin <yevgenyp@mellanox.co.il> | 2011-03-23 01:37:52 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-03-23 22:24:18 +0300 |
commit | 1fb9876e9bf895ea4127ff17180f1b2ab37771b6 (patch) | |
tree | 4d26408ec346531ee99e01c0c397c73e782cacef /drivers/net/mlx4/en_cq.c | |
parent | 0b7ca5a928e2271bbc225e9e1ac1f22e9fbee54f (diff) | |
download | linux-1fb9876e9bf895ea4127ff17180f1b2ab37771b6.tar.xz |
mlx4_en: using new mlx4 interrupt scheme
Each RX ring will have its own interrupt vector, and TX rings will share one
(we mostly use polling for TX completions).
The vectors are assigned first time device is opened, and its name includes
the interface name and ring number.
Signed-off-by: Markuze Alex <markuze@mellanox.co.il>
Signed-off-by: Yevgeny Petrilin <yevgenyp@mellanox.co.il>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/mlx4/en_cq.c')
-rw-r--r-- | drivers/net/mlx4/en_cq.c | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/drivers/net/mlx4/en_cq.c b/drivers/net/mlx4/en_cq.c index 21786ad4455e..ec4b6d047fe0 100644 --- a/drivers/net/mlx4/en_cq.c +++ b/drivers/net/mlx4/en_cq.c @@ -51,13 +51,10 @@ int mlx4_en_create_cq(struct mlx4_en_priv *priv, int err; cq->size = entries; - if (mode == RX) { + if (mode == RX) cq->buf_size = cq->size * sizeof(struct mlx4_cqe); - cq->vector = ring % mdev->dev->caps.num_comp_vectors; - } else { + else cq->buf_size = sizeof(struct mlx4_cqe); - cq->vector = 0; - } cq->ring = ring; cq->is_tx = mode; @@ -80,7 +77,8 @@ int mlx4_en_create_cq(struct mlx4_en_priv *priv, int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq) { struct mlx4_en_dev *mdev = priv->mdev; - int err; + int err = 0; + char name[25]; cq->dev = mdev->pndev[priv->port]; cq->mcq.set_ci_db = cq->wqres.db.db; @@ -89,6 +87,29 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq) *cq->mcq.arm_db = 0; memset(cq->buf, 0, cq->buf_size); + if (cq->is_tx == RX) { + if (mdev->dev->caps.comp_pool) { + if (!cq->vector) { + sprintf(name , "%s-rx-%d", priv->dev->name, cq->ring); + if (mlx4_assign_eq(mdev->dev, name, &cq->vector)) { + cq->vector = (cq->ring + 1 + priv->port) % + mdev->dev->caps.num_comp_vectors; + mlx4_warn(mdev, "Failed Assigning an EQ to " + "%s_rx-%d ,Falling back to legacy EQ's\n", + priv->dev->name, cq->ring); + } + } + } else { + cq->vector = (cq->ring + 1 + priv->port) % + mdev->dev->caps.num_comp_vectors; + } + } else { + if (!cq->vector || !mdev->dev->caps.comp_pool) { + /*Fallback to legacy pool in case of error*/ + cq->vector = 0; + } + } + if (!cq->is_tx) cq->size = priv->rx_ring[cq->ring].actual_size; @@ -112,12 +133,15 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq) return 0; } -void mlx4_en_destroy_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq) +void mlx4_en_destroy_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq, + bool reserve_vectors) { struct mlx4_en_dev *mdev = priv->mdev; mlx4_en_unmap_buffer(&cq->wqres.buf); mlx4_free_hwq_res(mdev->dev, &cq->wqres, cq->buf_size); + if (priv->mdev->dev->caps.comp_pool && cq->vector && !reserve_vectors) + mlx4_release_eq(priv->mdev->dev, cq->vector); cq->buf_size = 0; cq->buf = NULL; } |