网卡关闭或打开接收中断

 

https://blog.csdn.net/hz5034/article/details/79794478

static irqreturn_t ixgbe_msix_clean_many(int irq, void *data)
{
    struct ixgbe_q_vector *q_vector = data;
    struct ixgbe_adapter  *adapter = q_vector->adapter;
    struct ixgbe_ring  *ring;
    int r_idx;
    int i;

    // 若发送/接收队列数都为零
    if (!q_vector->txr_count && !q_vector->rxr_count)
        return IRQ_HANDLED;

    r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
    for (i = 0; i < q_vector->txr_count; i++) {
        // 遍历中断对应的发送队列(一般一个中断只对应一个发送队列)
        ring = &(adapter->tx_ring[r_idx]);
        // 清零total_bytes和total_packets
        ring->total_bytes = 0;
        ring->total_packets = 0;
        r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
                              r_idx + 1);
    }

    r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
    for (i = 0; i < q_vector->rxr_count; i++) {
        // 遍历中断对应的接收队列(一般一个中断只对应一个接收队列)
        ring = &(adapter->rx_ring[r_idx]);
        // 清零total_bytes和total_packets
        ring->total_bytes = 0;
        ring->total_packets = 0;
        r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
                              r_idx + 1);
    }

    /* disable interrupts on this vector only */
    ixgbe_irq_disable_queues(adapter, ((u64)1 << q_vector->v_idx));
    napi_schedule(&q_vector->napi); // NAPI调度

    return IRQ_HANDLED;
}

 

static inline void ixgbe_irq_disable_queues(struct ixgbe_adapter *adapter,
                        u64 qmask)
{
    u32 mask;
    struct ixgbe_hw *hw = &adapter->hw;

    switch (hw->mac.type) {
    case ixgbe_mac_82598EB:
        mask = (IXGBE_EIMS_RTX_QUEUE & qmask);
        IXGBE_WRITE_REG(hw, IXGBE_EIMC, mask);
        break;
    case ixgbe_mac_82599EB:
    case ixgbe_mac_X540:
    case ixgbe_mac_X550:
    case ixgbe_mac_X550EM_x:
    case ixgbe_mac_x550em_a:
        mask = (qmask & 0xFFFFFFFF);
        if (mask)
            IXGBE_WRITE_REG(hw, IXGBE_EIMC_EX(0), mask);
        mask = (qmask >> 32);
        if (mask)
            IXGBE_WRITE_REG(hw, IXGBE_EIMC_EX(1), mask);
        break;
    default:
        break;
    }
    /* skip the flush */
}

 

 

 

 

static irqreturn_t e100_intr(int irq, void *dev_id)
{
    struct net_device *netdev = dev_id;
    struct nic *nic = netdev_priv(netdev);
    u8 stat_ack = ioread8(&nic->csr->scb.stat_ack);

    netif_printk(nic, intr, KERN_DEBUG, nic->netdev,
             "stat_ack = 0x%02X\n", stat_ack);

    if (stat_ack == stat_ack_not_ours ||    /* Not our interrupt */
       stat_ack == stat_ack_not_present)    /* Hardware is ejected */
        return IRQ_NONE;

    /* Ack interrupt(s) */
    iowrite8(stat_ack, &nic->csr->scb.stat_ack);

    /* We hit Receive No Resource (RNR); restart RU after cleaning */
    if (stat_ack & stat_ack_rnr)
        nic->ru_running = RU_SUSPENDED;

    if (likely(napi_schedule_prep(&nic->napi))) {
        e100_disable_irq(nic);
        //将该网络设备加入到sd的poll_list中
        __napi_schedule(&nic->napi);
    }

    return IRQ_HANDLED;
}

 

 

 

static void e100_enable_irq(struct nic *nic)
{
    unsigned long flags;

    spin_lock_irqsave(&nic->cmd_lock, flags);
    iowrite8(irq_mask_none, &nic->csr->scb.cmd_hi);
    e100_write_flush(nic);
    spin_unlock_irqrestore(&nic->cmd_lock, flags);
}

static void e100_disable_irq(struct nic *nic)
{
    unsigned long flags;

    spin_lock_irqsave(&nic->cmd_lock, flags);
    iowrite8(irq_mask_all, &nic->csr->scb.cmd_hi);
    e100_write_flush(nic);
    spin_unlock_irqrestore(&nic->cmd_lock, flags);
}

 

posted on 2020-09-04 17:35  tycoon3  阅读(441)  评论(0编辑  收藏  举报

导航