summaryrefslogtreecommitdiffstats
path: root/drivers/net/ucc_geth.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ucc_geth.c')
-rw-r--r--drivers/net/ucc_geth.c92
1 files changed, 42 insertions, 50 deletions
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 9a38dfe45f8f..9667dac383f0 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -3350,14 +3350,6 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
return 0;
}
-/* returns a net_device_stats structure pointer */
-static struct net_device_stats *ucc_geth_get_stats(struct net_device *dev)
-{
- struct ucc_geth_private *ugeth = netdev_priv(dev);
-
- return &(ugeth->stats);
-}
-
/* ucc_geth_timeout gets called when a packet has not been
* transmitted after a set amount of time.
* For now, assume that clearing out all the structures, and
@@ -3368,7 +3360,7 @@ static void ucc_geth_timeout(struct net_device *dev)
ugeth_vdbg("%s: IN", __FUNCTION__);
- ugeth->stats.tx_errors++;
+ dev->stats.tx_errors++;
ugeth_dump_regs(ugeth);
@@ -3396,7 +3388,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
spin_lock_irq(&ugeth->lock);
- ugeth->stats.tx_bytes += skb->len;
+ dev->stats.tx_bytes += skb->len;
/* Start from the next BD that should be filled */
bd = ugeth->txBd[txQ];
@@ -3488,9 +3480,9 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
dev_kfree_skb_any(skb);
ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]] = NULL;
- ugeth->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
} else {
- ugeth->stats.rx_packets++;
+ dev->stats.rx_packets++;
howmany++;
/* Prep the skb for the packet */
@@ -3499,7 +3491,7 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
/* Tell the skb what kind of packet this is */
skb->protocol = eth_type_trans(skb, ugeth->dev);
- ugeth->stats.rx_bytes += length;
+ dev->stats.rx_bytes += length;
/* Send the packet up the stack */
#ifdef CONFIG_UGETH_NAPI
netif_receive_skb(skb);
@@ -3514,7 +3506,7 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
if (!skb) {
if (netif_msg_rx_err(ugeth))
ugeth_warn("%s: No Rx Data Buffer", __FUNCTION__);
- ugeth->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
break;
}
@@ -3556,7 +3548,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ)
if ((bd == ugeth->txBd[txQ]) && (netif_queue_stopped(dev) == 0))
break;
- ugeth->stats.tx_packets++;
+ dev->stats.tx_packets++;
/* Free the sk buffer associated with this TxBD */
dev_kfree_skb_irq(ugeth->
@@ -3582,41 +3574,31 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ)
}
#ifdef CONFIG_UGETH_NAPI
-static int ucc_geth_poll(struct net_device *dev, int *budget)
+static int ucc_geth_poll(struct napi_struct *napi, int budget)
{
- struct ucc_geth_private *ugeth = netdev_priv(dev);
+ struct ucc_geth_private *ugeth = container_of(napi, struct ucc_geth_private, napi);
+ struct net_device *dev = ugeth->dev;
struct ucc_geth_info *ug_info;
- struct ucc_fast_private *uccf;
- int howmany;
- u8 i;
- int rx_work_limit;
- register u32 uccm;
+ int howmany, i;
ug_info = ugeth->ug_info;
- rx_work_limit = *budget;
- if (rx_work_limit > dev->quota)
- rx_work_limit = dev->quota;
-
howmany = 0;
+ for (i = 0; i < ug_info->numQueuesRx; i++)
+ howmany += ucc_geth_rx(ugeth, i, budget - howmany);
- for (i = 0; i < ug_info->numQueuesRx; i++) {
- howmany += ucc_geth_rx(ugeth, i, rx_work_limit);
- }
-
- dev->quota -= howmany;
- rx_work_limit -= howmany;
- *budget -= howmany;
+ if (howmany < budget) {
+ struct ucc_fast_private *uccf;
+ u32 uccm;
- if (rx_work_limit > 0) {
- netif_rx_complete(dev);
+ netif_rx_complete(dev, napi);
uccf = ugeth->uccf;
uccm = in_be32(uccf->p_uccm);
uccm |= UCCE_RX_EVENTS;
out_be32(uccf->p_uccm, uccm);
}
- return (rx_work_limit > 0) ? 0 : 1;
+ return howmany;
}
#endif /* CONFIG_UGETH_NAPI */
@@ -3651,10 +3633,10 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
/* check for receive events that require processing */
if (ucce & UCCE_RX_EVENTS) {
#ifdef CONFIG_UGETH_NAPI
- if (netif_rx_schedule_prep(dev)) {
- uccm &= ~UCCE_RX_EVENTS;
+ if (netif_rx_schedule_prep(dev, &ugeth->napi)) {
+ uccm &= ~UCCE_RX_EVENTS;
out_be32(uccf->p_uccm, uccm);
- __netif_rx_schedule(dev);
+ __netif_rx_schedule(dev, &ugeth->napi);
}
#else
rx_mask = UCCE_RXBF_SINGLE_MASK;
@@ -3683,10 +3665,10 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
/* Errors and other events */
if (ucce & UCCE_OTHER) {
if (ucce & UCCE_BSY) {
- ugeth->stats.rx_errors++;
+ dev->stats.rx_errors++;
}
if (ucce & UCCE_TXE) {
- ugeth->stats.tx_errors++;
+ dev->stats.tx_errors++;
}
}
@@ -3717,12 +3699,15 @@ static int ucc_geth_open(struct net_device *dev)
return err;
}
+#ifdef CONFIG_UGETH_NAPI
+ napi_enable(&ugeth->napi);
+#endif
err = ucc_geth_startup(ugeth);
if (err) {
if (netif_msg_ifup(ugeth))
ugeth_err("%s: Cannot configure net device, aborting.",
dev->name);
- return err;
+ goto out_err;
}
err = adjust_enet_interface(ugeth);
@@ -3730,7 +3715,7 @@ static int ucc_geth_open(struct net_device *dev)
if (netif_msg_ifup(ugeth))
ugeth_err("%s: Cannot configure net device, aborting.",
dev->name);
- return err;
+ goto out_err;
}
/* Set MACSTNADDR1, MACSTNADDR2 */
@@ -3748,7 +3733,7 @@ static int ucc_geth_open(struct net_device *dev)
if (err) {
if (netif_msg_ifup(ugeth))
ugeth_err("%s: Cannot initialize PHY, aborting.", dev->name);
- return err;
+ goto out_err;
}
phy_start(ugeth->phydev);
@@ -3761,7 +3746,7 @@ static int ucc_geth_open(struct net_device *dev)
ugeth_err("%s: Cannot get IRQ for net device, aborting.",
dev->name);
ucc_geth_stop(ugeth);
- return err;
+ goto out_err;
}
err = ugeth_enable(ugeth, COMM_DIR_RX_AND_TX);
@@ -3769,12 +3754,18 @@ static int ucc_geth_open(struct net_device *dev)
if (netif_msg_ifup(ugeth))
ugeth_err("%s: Cannot enable net device, aborting.", dev->name);
ucc_geth_stop(ugeth);
- return err;
+ goto out_err;
}
netif_start_queue(dev);
return err;
+
+out_err:
+#ifdef CONFIG_UGETH_NAPI
+ napi_disable(&ugeth->napi);
+#endif
+ return err;
}
/* Stops the kernel queue, and halts the controller */
@@ -3784,6 +3775,10 @@ static int ucc_geth_close(struct net_device *dev)
ugeth_vdbg("%s: IN", __FUNCTION__);
+#ifdef CONFIG_UGETH_NAPI
+ napi_disable(&ugeth->napi);
+#endif
+
ucc_geth_stop(ugeth);
phy_disconnect(ugeth->phydev);
@@ -3954,7 +3949,6 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
/* Set the dev->base_addr to the gfar reg region */
dev->base_addr = (unsigned long)(ug_info->uf_info.regs);
- SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, device);
/* Fill in the dev structure */
@@ -3964,11 +3958,9 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
dev->tx_timeout = ucc_geth_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
#ifdef CONFIG_UGETH_NAPI
- dev->poll = ucc_geth_poll;
- dev->weight = UCC_GETH_DEV_WEIGHT;
+ netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, UCC_GETH_DEV_WEIGHT);
#endif /* CONFIG_UGETH_NAPI */
dev->stop = ucc_geth_close;
- dev->get_stats = ucc_geth_get_stats;
// dev->change_mtu = ucc_geth_change_mtu;
dev->mtu = 1500;
dev->set_multicast_list = ucc_geth_set_multi;
OpenPOWER on IntegriCloud