static int greth_poll(struct napi_struct *napi, int budget)
{
	struct greth_private *greth;
	int work_done = 0;
	greth = container_of(napi, struct greth_private, napi);

	if (greth->gbit_mac) {
		greth_clean_tx_gbit(greth->netdev);
	} else {
		greth_clean_tx(greth->netdev);
	}

restart_poll:
	if (greth->gbit_mac) {
		work_done += greth_rx_gbit(greth->netdev, budget - work_done);
	} else {
		work_done += greth_rx(greth->netdev, budget - work_done);
	}

	if (work_done < budget) {

		napi_complete(napi);

		if (greth_pending_packets(greth)) {
			napi_reschedule(napi);
			goto restart_poll;
		}
	}

	greth_enable_irqs(greth);
	return work_done;
}
Esempio n. 2
0
static int greth_poll(struct napi_struct *napi, int budget)
{
	struct greth_private *greth;
	int work_done = 0;
	unsigned long flags;
	u32 mask, ctrl;
	greth = container_of(napi, struct greth_private, napi);

restart_txrx_poll:
	if (netif_queue_stopped(greth->netdev)) {
		if (greth->gbit_mac)
			greth_clean_tx_gbit(greth->netdev);
		else
			greth_clean_tx(greth->netdev);
	}

	if (greth->gbit_mac) {
		work_done += greth_rx_gbit(greth->netdev, budget - work_done);
	} else {
		work_done += greth_rx(greth->netdev, budget - work_done);
	}

	if (work_done < budget) {

		spin_lock_irqsave(&greth->devlock, flags);

		ctrl = GRETH_REGLOAD(greth->regs->control);
		if (netif_queue_stopped(greth->netdev)) {
			GRETH_REGSAVE(greth->regs->control,
					ctrl | GRETH_TXI | GRETH_RXI);
			mask = GRETH_INT_RX | GRETH_INT_RE |
			       GRETH_INT_TX | GRETH_INT_TE;
		} else {
			GRETH_REGSAVE(greth->regs->control, ctrl | GRETH_RXI);
			mask = GRETH_INT_RX | GRETH_INT_RE;
		}

		if (GRETH_REGLOAD(greth->regs->status) & mask) {
			GRETH_REGSAVE(greth->regs->control, ctrl);
			spin_unlock_irqrestore(&greth->devlock, flags);
			goto restart_txrx_poll;
		} else {
			__napi_complete(napi);
			spin_unlock_irqrestore(&greth->devlock, flags);
		}
	}

	return work_done;
}