X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fnet%2Fmlx4%2Fmlx4_intr.c;h=2ff72188a78de3db1c3af79a2987a5a318f990d2;hb=3669a1af893088064778f14fba0c2ca88819e095;hp=3806322e5f9a61df20206c23d26a557b3d1ac955;hpb=d84fb5eba1dac6a8d8b5506fa38e555c2c8d7e91;p=dpdk.git diff --git a/drivers/net/mlx4/mlx4_intr.c b/drivers/net/mlx4/mlx4_intr.c index 3806322e5f..2ff72188a7 100644 --- a/drivers/net/mlx4/mlx4_intr.c +++ b/drivers/net/mlx4/mlx4_intr.c @@ -52,7 +52,8 @@ #include #include -#include +#include +#include #include #include "mlx4.h" @@ -97,7 +98,7 @@ mlx4_rx_intr_vec_enable(struct priv *priv) struct rte_intr_handle *intr_handle = &priv->intr_handle; mlx4_rx_intr_vec_disable(priv); - intr_handle->intr_vec = malloc(sizeof(intr_handle->intr_vec[rxqs_n])); + intr_handle->intr_vec = malloc(n * sizeof(intr_handle->intr_vec[0])); if (intr_handle->intr_vec == NULL) { rte_errno = ENOMEM; ERROR("failed to allocate memory for interrupt vector," @@ -153,7 +154,7 @@ mlx4_link_status_alarm(struct priv *priv) if (intr_conf->lsc && !mlx4_link_status_check(priv)) _rte_eth_dev_callback_process(priv->dev, RTE_ETH_EVENT_INTR_LSC, - NULL, NULL); + NULL); } /** @@ -235,7 +236,36 @@ mlx4_interrupt_handler(struct priv *priv) for (i = 0; i != RTE_DIM(caught); ++i) if (caught[i]) _rte_eth_dev_callback_process(priv->dev, type[i], - NULL, NULL); + NULL); +} + +/** + * MLX4 CQ notification . + * + * @param rxq + * Pointer to receive queue structure. + * @param solicited + * Is request solicited or not. + */ +static void +mlx4_arm_cq(struct rxq *rxq, int solicited) +{ + struct mlx4_cq *cq = &rxq->mcq; + uint64_t doorbell; + uint32_t sn = cq->arm_sn & MLX4_CQ_DB_GEQ_N_MASK; + uint32_t ci = cq->cons_index & MLX4_CQ_DB_CI_MASK; + uint32_t cmd = solicited ? MLX4_CQ_DB_REQ_NOT_SOL : MLX4_CQ_DB_REQ_NOT; + + *cq->arm_db = rte_cpu_to_be_32(sn << 28 | cmd | ci); + /* + * Make sure that the doorbell record in host memory is + * written before ringing the doorbell via PCI MMIO. + */ + rte_wmb(); + doorbell = sn << 28 | cmd | cq->cqn; + doorbell <<= 32; + doorbell |= ci; + rte_write64(rte_cpu_to_be_64(doorbell), cq->cq_db_reg); } /** @@ -333,6 +363,7 @@ mlx4_rx_intr_disable(struct rte_eth_dev *dev, uint16_t idx) WARN("unable to disable interrupt on rx queue %d", idx); } else { + rxq->mcq.arm_sn++; ibv_ack_cq_events(rxq->cq, 1); } return -ret; @@ -353,15 +384,14 @@ int mlx4_rx_intr_enable(struct rte_eth_dev *dev, uint16_t idx) { struct rxq *rxq = dev->data->rx_queues[idx]; - int ret; + int ret = 0; - if (!rxq || !rxq->channel) + if (!rxq || !rxq->channel) { ret = EINVAL; - else - ret = ibv_req_notify_cq(rxq->cq, 0); - if (ret) { rte_errno = ret; WARN("unable to arm interrupt on rx queue %d", idx); + } else { + mlx4_arm_cq(rxq, 0); } return -ret; }