diff --git a/modules/mqnic/mqnic.h b/modules/mqnic/mqnic.h index fe28fc41a..60056cba0 100644 --- a/modules/mqnic/mqnic.h +++ b/modules/mqnic/mqnic.h @@ -206,6 +206,7 @@ struct mqnic_ring { struct net_device *ndev; struct mqnic_priv *priv; int index; + struct mqnic_cq_ring *cq_ring; int active; u32 hw_ptr_mask; @@ -233,6 +234,7 @@ struct mqnic_cq_ring { struct napi_struct napi; int index; struct mqnic_eq_ring *eq_ring; + struct mqnic_ring *src_ring; int eq_index; int active; @@ -420,7 +422,7 @@ int mqnic_create_tx_ring(struct mqnic_priv *priv, struct mqnic_ring **ring_ptr, void mqnic_destroy_tx_ring(struct mqnic_ring **ring_ptr); int mqnic_alloc_tx_ring(struct mqnic_ring *ring, int size, int stride); void mqnic_free_tx_ring(struct mqnic_ring *ring); -int mqnic_activate_tx_ring(struct mqnic_ring *ring, int cpl_index); +int mqnic_activate_tx_ring(struct mqnic_ring *ring, struct mqnic_cq_ring *cq_ring); void mqnic_deactivate_tx_ring(struct mqnic_ring *ring); bool mqnic_is_tx_ring_empty(const struct mqnic_ring *ring); bool mqnic_is_tx_ring_full(const struct mqnic_ring *ring); @@ -439,7 +441,7 @@ int mqnic_create_rx_ring(struct mqnic_priv *priv, struct mqnic_ring **ring_ptr, void mqnic_destroy_rx_ring(struct mqnic_ring **ring_ptr); int mqnic_alloc_rx_ring(struct mqnic_ring *ring, int size, int stride); void mqnic_free_rx_ring(struct mqnic_ring *ring); -int mqnic_activate_rx_ring(struct mqnic_ring *ring, int cpl_index); +int mqnic_activate_rx_ring(struct mqnic_ring *ring, struct mqnic_cq_ring *cq_ring); void mqnic_deactivate_rx_ring(struct mqnic_ring *ring); bool mqnic_is_rx_ring_empty(const struct mqnic_ring *ring); bool mqnic_is_rx_ring_full(const struct mqnic_ring *ring); diff --git a/modules/mqnic/mqnic_netdev.c b/modules/mqnic/mqnic_netdev.c index 0ecf49ace..1d578dfff 100644 --- a/modules/mqnic/mqnic_netdev.c +++ b/modules/mqnic/mqnic_netdev.c @@ -54,7 +54,6 @@ static int mqnic_start_port(struct net_device *ndev) // set up CQ mqnic_activate_cq_ring(priv->rx_cpl_ring[k], priv->event_ring[k % priv->event_queue_count]); - priv->rx_cpl_ring[k]->handler = mqnic_rx_irq; netif_napi_add(ndev, &priv->rx_cpl_ring[k]->napi, mqnic_poll_rx_cq, NAPI_POLL_WEIGHT); @@ -68,7 +67,7 @@ static int mqnic_start_port(struct net_device *ndev) priv->rx_ring[k]->page_order = 0; else priv->rx_ring[k]->page_order = ilog2((ndev->mtu + ETH_HLEN + PAGE_SIZE - 1) / PAGE_SIZE - 1) + 1; - mqnic_activate_rx_ring(priv->rx_ring[k], priv->rx_cpl_ring[k]->index); + mqnic_activate_rx_ring(priv->rx_ring[k], priv->rx_cpl_ring[k]); } // set up TX queues @@ -76,7 +75,6 @@ static int mqnic_start_port(struct net_device *ndev) // set up CQ mqnic_activate_cq_ring(priv->tx_cpl_ring[k], priv->event_ring[k % priv->event_queue_count]); - priv->tx_cpl_ring[k]->handler = mqnic_tx_irq; netif_tx_napi_add(ndev, &priv->tx_cpl_ring[k]->napi, mqnic_poll_tx_cq, NAPI_POLL_WEIGHT); @@ -85,8 +83,8 @@ static int mqnic_start_port(struct net_device *ndev) mqnic_arm_cq(priv->tx_cpl_ring[k]); // set up queue - mqnic_activate_tx_ring(priv->tx_ring[k], priv->tx_cpl_ring[k]->index); priv->tx_ring[k]->tx_queue = netdev_get_tx_queue(ndev, k); + mqnic_activate_tx_ring(priv->tx_ring[k], priv->tx_cpl_ring[k]); } // configure ports diff --git a/modules/mqnic/mqnic_rx.c b/modules/mqnic/mqnic_rx.c index bf6d2d1f5..ac88849f6 100644 --- a/modules/mqnic/mqnic_rx.c +++ b/modules/mqnic/mqnic_rx.c @@ -146,20 +146,24 @@ void mqnic_free_rx_ring(struct mqnic_ring *ring) ring->rx_info = NULL; } -int mqnic_activate_rx_ring(struct mqnic_ring *ring, int cpl_index) +int mqnic_activate_rx_ring(struct mqnic_ring *ring, struct mqnic_cq_ring *cq_ring) { mqnic_deactivate_rx_ring(ring); - if (!ring->buf) + if (!ring->buf || !cq_ring || cq_ring->handler || cq_ring->src_ring) return -EINVAL; + ring->cq_ring = cq_ring; + cq_ring->src_ring = ring; + cq_ring->handler = mqnic_rx_irq; + // deactivate queue iowrite32(0, ring->hw_addr + MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG); // set base address iowrite32(ring->buf_dma_addr, ring->hw_addr + MQNIC_QUEUE_BASE_ADDR_REG + 0); iowrite32(ring->buf_dma_addr >> 32, ring->hw_addr + MQNIC_QUEUE_BASE_ADDR_REG + 4); // set completion queue index - iowrite32(cpl_index, ring->hw_addr + MQNIC_QUEUE_CPL_QUEUE_INDEX_REG); + iowrite32(cq_ring->index, ring->hw_addr + MQNIC_QUEUE_CPL_QUEUE_INDEX_REG); // set pointers iowrite32(ring->head_ptr & ring->hw_ptr_mask, ring->hw_addr + MQNIC_QUEUE_HEAD_PTR_REG); iowrite32(ring->tail_ptr & ring->hw_ptr_mask, ring->hw_addr + MQNIC_QUEUE_TAIL_PTR_REG); @@ -180,6 +184,13 @@ void mqnic_deactivate_rx_ring(struct mqnic_ring *ring) iowrite32(ilog2(ring->size) | (ring->log_desc_block_size << 8), ring->hw_addr + MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG); + if (ring->cq_ring) { + ring->cq_ring->src_ring = NULL; + ring->cq_ring->handler = NULL; + } + + ring->cq_ring = NULL; + ring->active = 0; } @@ -302,7 +313,7 @@ int mqnic_process_rx_cq(struct mqnic_cq_ring *cq_ring, int napi_budget) { struct mqnic_priv *priv = cq_ring->priv; struct net_device *ndev = priv->ndev; - struct mqnic_ring *rx_ring = priv->rx_ring[cq_ring->index]; + struct mqnic_ring *rx_ring = cq_ring->src_ring; struct mqnic_rx_info *rx_info; struct mqnic_cpl *cpl; struct sk_buff *skb; diff --git a/modules/mqnic/mqnic_tx.c b/modules/mqnic/mqnic_tx.c index 1ceca2358..b4f999ca4 100644 --- a/modules/mqnic/mqnic_tx.c +++ b/modules/mqnic/mqnic_tx.c @@ -148,20 +148,24 @@ void mqnic_free_tx_ring(struct mqnic_ring *ring) ring->tx_info = NULL; } -int mqnic_activate_tx_ring(struct mqnic_ring *ring, int cpl_index) +int mqnic_activate_tx_ring(struct mqnic_ring *ring, struct mqnic_cq_ring *cq_ring) { mqnic_deactivate_tx_ring(ring); - if (!ring->buf) + if (!ring->buf || !cq_ring || cq_ring->handler || cq_ring->src_ring) return -EINVAL; + ring->cq_ring = cq_ring; + cq_ring->src_ring = ring; + cq_ring->handler = mqnic_tx_irq; + // deactivate queue iowrite32(0, ring->hw_addr + MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG); // set base address iowrite32(ring->buf_dma_addr, ring->hw_addr + MQNIC_QUEUE_BASE_ADDR_REG + 0); iowrite32(ring->buf_dma_addr >> 32, ring->hw_addr + MQNIC_QUEUE_BASE_ADDR_REG + 4); // set completion queue index - iowrite32(cpl_index, ring->hw_addr + MQNIC_QUEUE_CPL_QUEUE_INDEX_REG); + iowrite32(cq_ring->index, ring->hw_addr + MQNIC_QUEUE_CPL_QUEUE_INDEX_REG); // set pointers iowrite32(ring->head_ptr & ring->hw_ptr_mask, ring->hw_addr + MQNIC_QUEUE_HEAD_PTR_REG); iowrite32(ring->tail_ptr & ring->hw_ptr_mask, ring->hw_addr + MQNIC_QUEUE_TAIL_PTR_REG); @@ -180,6 +184,13 @@ void mqnic_deactivate_tx_ring(struct mqnic_ring *ring) iowrite32(ilog2(ring->size) | (ring->log_desc_block_size << 8), ring->hw_addr + MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG); + if (ring->cq_ring) { + ring->cq_ring->src_ring = NULL; + ring->cq_ring->handler = NULL; + } + + ring->cq_ring = NULL; + ring->active = 0; } @@ -246,7 +257,7 @@ int mqnic_free_tx_buf(struct mqnic_ring *ring) int mqnic_process_tx_cq(struct mqnic_cq_ring *cq_ring, int napi_budget) { struct mqnic_priv *priv = cq_ring->priv; - struct mqnic_ring *tx_ring = priv->tx_ring[cq_ring->index]; + struct mqnic_ring *tx_ring = cq_ring->src_ring; struct mqnic_tx_info *tx_info; struct mqnic_cpl *cpl; struct skb_shared_hwtstamps hwts;