static irqreturn_t p54p_interrupt(int irq, void *dev_id) { struct ieee80211_hw *dev = dev_id; struct p54p_priv *priv = dev->priv; struct p54p_ring_control *ring_control = priv->ring_control; __le32 reg; spin_lock(&priv->lock); reg = P54P_READ(int_ident); if (unlikely(reg == cpu_to_le32(0xFFFFFFFF))) { spin_unlock(&priv->lock); return IRQ_HANDLED; } P54P_WRITE(int_ack, reg); reg &= P54P_READ(int_enable); if (reg & cpu_to_le32(ISL38XX_INT_IDENT_UPDATE)) { p54p_check_tx_ring(dev, &priv->tx_idx_mgmt, 3, ring_control->tx_mgmt, ARRAY_SIZE(ring_control->tx_mgmt), priv->tx_buf_mgmt); p54p_check_tx_ring(dev, &priv->tx_idx_data, 1, ring_control->tx_data, ARRAY_SIZE(ring_control->tx_data), priv->tx_buf_data); tasklet_schedule(&priv->rx_tasklet); } else if (reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT)) complete(&priv->boot_comp); spin_unlock(&priv->lock); return reg ? IRQ_HANDLED : IRQ_NONE; }
static void p54p_tasklet(unsigned long dev_id) { struct ieee80211_hw *dev = (struct ieee80211_hw *)dev_id; struct p54p_priv *priv = dev->priv; struct p54p_ring_control *ring_control = priv->ring_control; p54p_check_tx_ring(dev, &priv->tx_idx_mgmt, 3, ring_control->tx_mgmt, ARRAY_SIZE(ring_control->tx_mgmt), priv->tx_buf_mgmt); p54p_check_tx_ring(dev, &priv->tx_idx_data, 1, ring_control->tx_data, ARRAY_SIZE(ring_control->tx_data), priv->tx_buf_data); p54p_check_rx_ring(dev, &priv->rx_idx_mgmt, 2, ring_control->rx_mgmt, ARRAY_SIZE(ring_control->rx_mgmt), priv->rx_buf_mgmt); p54p_check_rx_ring(dev, &priv->rx_idx_data, 0, ring_control->rx_data, ARRAY_SIZE(ring_control->rx_data), priv->rx_buf_data); wmb(); P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_UPDATE)); }