|
@@ -45,6 +45,8 @@ int __devinit mal_register_commac(struct mal_instance *mal,
|
|
|
return -EBUSY;
|
|
|
}
|
|
|
|
|
|
+ if (list_empty(&mal->list))
|
|
|
+ napi_enable(&mal->napi);
|
|
|
mal->tx_chan_mask |= commac->tx_chan_mask;
|
|
|
mal->rx_chan_mask |= commac->rx_chan_mask;
|
|
|
list_add(&commac->list, &mal->list);
|
|
@@ -67,6 +69,8 @@ void __devexit mal_unregister_commac(struct mal_instance *mal,
|
|
|
mal->tx_chan_mask &= ~commac->tx_chan_mask;
|
|
|
mal->rx_chan_mask &= ~commac->rx_chan_mask;
|
|
|
list_del_init(&commac->list);
|
|
|
+ if (list_empty(&mal->list))
|
|
|
+ napi_disable(&mal->napi);
|
|
|
|
|
|
spin_unlock_irqrestore(&mal->lock, flags);
|
|
|
}
|
|
@@ -182,7 +186,7 @@ static inline void mal_enable_eob_irq(struct mal_instance *mal)
|
|
|
set_mal_dcrn(mal, MAL_CFG, get_mal_dcrn(mal, MAL_CFG) | MAL_CFG_EOPIE);
|
|
|
}
|
|
|
|
|
|
-/* synchronized by __LINK_STATE_RX_SCHED bit in ndev->state */
|
|
|
+/* synchronized by NAPI state */
|
|
|
static inline void mal_disable_eob_irq(struct mal_instance *mal)
|
|
|
{
|
|
|
// XXX might want to cache MAL_CFG as the DCR read can be slooooow
|
|
@@ -317,8 +321,8 @@ void mal_poll_disable(struct mal_instance *mal, struct mal_commac *commac)
|
|
|
while (test_and_set_bit(MAL_COMMAC_POLL_DISABLED, &commac->flags))
|
|
|
msleep(1);
|
|
|
|
|
|
- /* Synchronize with the MAL NAPI poller. */
|
|
|
- napi_disable(&mal->napi);
|
|
|
+ /* Synchronize with the MAL NAPI poller */
|
|
|
+ __napi_synchronize(&mal->napi);
|
|
|
}
|
|
|
|
|
|
void mal_poll_enable(struct mal_instance *mal, struct mal_commac *commac)
|
|
@@ -326,7 +330,12 @@ void mal_poll_enable(struct mal_instance *mal, struct mal_commac *commac)
|
|
|
smp_wmb();
|
|
|
clear_bit(MAL_COMMAC_POLL_DISABLED, &commac->flags);
|
|
|
|
|
|
- // XXX might want to kick a poll now...
|
|
|
+ /* Feels better to trigger a poll here to catch up with events that
|
|
|
+ * may have happened on this channel while disabled. It will most
|
|
|
+ * probably be delayed until the next interrupt but that's mostly a
|
|
|
+ * non-issue in the context where this is called.
|
|
|
+ */
|
|
|
+ napi_schedule(&mal->napi);
|
|
|
}
|
|
|
|
|
|
static int mal_poll(struct napi_struct *napi, int budget)
|
|
@@ -336,8 +345,7 @@ static int mal_poll(struct napi_struct *napi, int budget)
|
|
|
int received = 0;
|
|
|
unsigned long flags;
|
|
|
|
|
|
- MAL_DBG2(mal, "poll(%d) %d ->" NL, *budget,
|
|
|
- rx_work_limit);
|
|
|
+ MAL_DBG2(mal, "poll(%d)" NL, budget);
|
|
|
again:
|
|
|
/* Process TX skbs */
|
|
|
list_for_each(l, &mal->poll_list) {
|
|
@@ -528,11 +536,12 @@ static int __devinit mal_probe(struct of_device *ofdev,
|
|
|
}
|
|
|
|
|
|
INIT_LIST_HEAD(&mal->poll_list);
|
|
|
- mal->napi.weight = CONFIG_IBM_NEW_EMAC_POLL_WEIGHT;
|
|
|
- mal->napi.poll = mal_poll;
|
|
|
INIT_LIST_HEAD(&mal->list);
|
|
|
spin_lock_init(&mal->lock);
|
|
|
|
|
|
+ netif_napi_add(NULL, &mal->napi, mal_poll,
|
|
|
+ CONFIG_IBM_NEW_EMAC_POLL_WEIGHT);
|
|
|
+
|
|
|
/* Load power-on reset defaults */
|
|
|
mal_reset(mal);
|
|
|
|