diff options
Diffstat (limited to 'drivers/net/ucc_geth.c')
-rw-r--r-- | drivers/net/ucc_geth.c | 64 |
1 files changed, 33 insertions, 31 deletions
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 9a38dfe45f8f..72f617bf2520 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c | |||
@@ -3582,41 +3582,31 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) | |||
3582 | } | 3582 | } |
3583 | 3583 | ||
3584 | #ifdef CONFIG_UGETH_NAPI | 3584 | #ifdef CONFIG_UGETH_NAPI |
3585 | static int ucc_geth_poll(struct net_device *dev, int *budget) | 3585 | static int ucc_geth_poll(struct napi_struct *napi, int budget) |
3586 | { | 3586 | { |
3587 | struct ucc_geth_private *ugeth = netdev_priv(dev); | 3587 | struct ucc_geth_private *ugeth = container_of(napi, struct ucc_geth_private, napi); |
3588 | struct net_device *dev = ugeth->dev; | ||
3588 | struct ucc_geth_info *ug_info; | 3589 | struct ucc_geth_info *ug_info; |
3589 | struct ucc_fast_private *uccf; | 3590 | int howmany, i; |
3590 | int howmany; | ||
3591 | u8 i; | ||
3592 | int rx_work_limit; | ||
3593 | register u32 uccm; | ||
3594 | 3591 | ||
3595 | ug_info = ugeth->ug_info; | 3592 | ug_info = ugeth->ug_info; |
3596 | 3593 | ||
3597 | rx_work_limit = *budget; | ||
3598 | if (rx_work_limit > dev->quota) | ||
3599 | rx_work_limit = dev->quota; | ||
3600 | |||
3601 | howmany = 0; | 3594 | howmany = 0; |
3595 | for (i = 0; i < ug_info->numQueuesRx; i++) | ||
3596 | howmany += ucc_geth_rx(ugeth, i, budget - howmany); | ||
3602 | 3597 | ||
3603 | for (i = 0; i < ug_info->numQueuesRx; i++) { | 3598 | if (howmany < budget) { |
3604 | howmany += ucc_geth_rx(ugeth, i, rx_work_limit); | 3599 | struct ucc_fast_private *uccf; |
3605 | } | 3600 | u32 uccm; |
3606 | |||
3607 | dev->quota -= howmany; | ||
3608 | rx_work_limit -= howmany; | ||
3609 | *budget -= howmany; | ||
3610 | 3601 | ||
3611 | if (rx_work_limit > 0) { | 3602 | netif_rx_complete(dev, napi); |
3612 | netif_rx_complete(dev); | ||
3613 | uccf = ugeth->uccf; | 3603 | uccf = ugeth->uccf; |
3614 | uccm = in_be32(uccf->p_uccm); | 3604 | uccm = in_be32(uccf->p_uccm); |
3615 | uccm |= UCCE_RX_EVENTS; | 3605 | uccm |= UCCE_RX_EVENTS; |
3616 | out_be32(uccf->p_uccm, uccm); | 3606 | out_be32(uccf->p_uccm, uccm); |
3617 | } | 3607 | } |
3618 | 3608 | ||
3619 | return (rx_work_limit > 0) ? 0 : 1; | 3609 | return howmany; |
3620 | } | 3610 | } |
3621 | #endif /* CONFIG_UGETH_NAPI */ | 3611 | #endif /* CONFIG_UGETH_NAPI */ |
3622 | 3612 | ||
@@ -3651,10 +3641,10 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info) | |||
3651 | /* check for receive events that require processing */ | 3641 | /* check for receive events that require processing */ |
3652 | if (ucce & UCCE_RX_EVENTS) { | 3642 | if (ucce & UCCE_RX_EVENTS) { |
3653 | #ifdef CONFIG_UGETH_NAPI | 3643 | #ifdef CONFIG_UGETH_NAPI |
3654 | if (netif_rx_schedule_prep(dev)) { | 3644 | if (netif_rx_schedule_prep(dev, &ugeth->napi)) { |
3655 | uccm &= ~UCCE_RX_EVENTS; | 3645 | uccm &= ~UCCE_RX_EVENTS; |
3656 | out_be32(uccf->p_uccm, uccm); | 3646 | out_be32(uccf->p_uccm, uccm); |
3657 | __netif_rx_schedule(dev); | 3647 | __netif_rx_schedule(dev, &ugeth->napi); |
3658 | } | 3648 | } |
3659 | #else | 3649 | #else |
3660 | rx_mask = UCCE_RXBF_SINGLE_MASK; | 3650 | rx_mask = UCCE_RXBF_SINGLE_MASK; |
@@ -3717,12 +3707,15 @@ static int ucc_geth_open(struct net_device *dev) | |||
3717 | return err; | 3707 | return err; |
3718 | } | 3708 | } |
3719 | 3709 | ||
3710 | #ifdef CONFIG_UGETH_NAPI | ||
3711 | napi_enable(&ugeth->napi); | ||
3712 | #endif | ||
3720 | err = ucc_geth_startup(ugeth); | 3713 | err = ucc_geth_startup(ugeth); |
3721 | if (err) { | 3714 | if (err) { |
3722 | if (netif_msg_ifup(ugeth)) | 3715 | if (netif_msg_ifup(ugeth)) |
3723 | ugeth_err("%s: Cannot configure net device, aborting.", | 3716 | ugeth_err("%s: Cannot configure net device, aborting.", |
3724 | dev->name); | 3717 | dev->name); |
3725 | return err; | 3718 | goto out_err; |
3726 | } | 3719 | } |
3727 | 3720 | ||
3728 | err = adjust_enet_interface(ugeth); | 3721 | err = adjust_enet_interface(ugeth); |
@@ -3730,7 +3723,7 @@ static int ucc_geth_open(struct net_device *dev) | |||
3730 | if (netif_msg_ifup(ugeth)) | 3723 | if (netif_msg_ifup(ugeth)) |
3731 | ugeth_err("%s: Cannot configure net device, aborting.", | 3724 | ugeth_err("%s: Cannot configure net device, aborting.", |
3732 | dev->name); | 3725 | dev->name); |
3733 | return err; | 3726 | goto out_err; |
3734 | } | 3727 | } |
3735 | 3728 | ||
3736 | /* Set MACSTNADDR1, MACSTNADDR2 */ | 3729 | /* Set MACSTNADDR1, MACSTNADDR2 */ |
@@ -3748,7 +3741,7 @@ static int ucc_geth_open(struct net_device *dev) | |||
3748 | if (err) { | 3741 | if (err) { |
3749 | if (netif_msg_ifup(ugeth)) | 3742 | if (netif_msg_ifup(ugeth)) |
3750 | ugeth_err("%s: Cannot initialize PHY, aborting.", dev->name); | 3743 | ugeth_err("%s: Cannot initialize PHY, aborting.", dev->name); |
3751 | return err; | 3744 | goto out_err; |
3752 | } | 3745 | } |
3753 | 3746 | ||
3754 | phy_start(ugeth->phydev); | 3747 | phy_start(ugeth->phydev); |
@@ -3761,7 +3754,7 @@ static int ucc_geth_open(struct net_device *dev) | |||
3761 | ugeth_err("%s: Cannot get IRQ for net device, aborting.", | 3754 | ugeth_err("%s: Cannot get IRQ for net device, aborting.", |
3762 | dev->name); | 3755 | dev->name); |
3763 | ucc_geth_stop(ugeth); | 3756 | ucc_geth_stop(ugeth); |
3764 | return err; | 3757 | goto out_err; |
3765 | } | 3758 | } |
3766 | 3759 | ||
3767 | err = ugeth_enable(ugeth, COMM_DIR_RX_AND_TX); | 3760 | err = ugeth_enable(ugeth, COMM_DIR_RX_AND_TX); |
@@ -3769,12 +3762,18 @@ static int ucc_geth_open(struct net_device *dev) | |||
3769 | if (netif_msg_ifup(ugeth)) | 3762 | if (netif_msg_ifup(ugeth)) |
3770 | ugeth_err("%s: Cannot enable net device, aborting.", dev->name); | 3763 | ugeth_err("%s: Cannot enable net device, aborting.", dev->name); |
3771 | ucc_geth_stop(ugeth); | 3764 | ucc_geth_stop(ugeth); |
3772 | return err; | 3765 | goto out_err; |
3773 | } | 3766 | } |
3774 | 3767 | ||
3775 | netif_start_queue(dev); | 3768 | netif_start_queue(dev); |
3776 | 3769 | ||
3777 | return err; | 3770 | return err; |
3771 | |||
3772 | out_err: | ||
3773 | #ifdef CONFIG_UGETH_NAPI | ||
3774 | napi_disable(&ugeth->napi); | ||
3775 | #endif | ||
3776 | return err; | ||
3778 | } | 3777 | } |
3779 | 3778 | ||
3780 | /* Stops the kernel queue, and halts the controller */ | 3779 | /* Stops the kernel queue, and halts the controller */ |
@@ -3784,6 +3783,10 @@ static int ucc_geth_close(struct net_device *dev) | |||
3784 | 3783 | ||
3785 | ugeth_vdbg("%s: IN", __FUNCTION__); | 3784 | ugeth_vdbg("%s: IN", __FUNCTION__); |
3786 | 3785 | ||
3786 | #ifdef CONFIG_UGETH_NAPI | ||
3787 | napi_disable(&ugeth->napi); | ||
3788 | #endif | ||
3789 | |||
3787 | ucc_geth_stop(ugeth); | 3790 | ucc_geth_stop(ugeth); |
3788 | 3791 | ||
3789 | phy_disconnect(ugeth->phydev); | 3792 | phy_disconnect(ugeth->phydev); |
@@ -3964,8 +3967,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma | |||
3964 | dev->tx_timeout = ucc_geth_timeout; | 3967 | dev->tx_timeout = ucc_geth_timeout; |
3965 | dev->watchdog_timeo = TX_TIMEOUT; | 3968 | dev->watchdog_timeo = TX_TIMEOUT; |
3966 | #ifdef CONFIG_UGETH_NAPI | 3969 | #ifdef CONFIG_UGETH_NAPI |
3967 | dev->poll = ucc_geth_poll; | 3970 | netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, UCC_GETH_DEV_WEIGHT); |
3968 | dev->weight = UCC_GETH_DEV_WEIGHT; | ||
3969 | #endif /* CONFIG_UGETH_NAPI */ | 3971 | #endif /* CONFIG_UGETH_NAPI */ |
3970 | dev->stop = ucc_geth_close; | 3972 | dev->stop = ucc_geth_close; |
3971 | dev->get_stats = ucc_geth_get_stats; | 3973 | dev->get_stats = ucc_geth_get_stats; |