diff options
Diffstat (limited to 'drivers/net/ucc_geth.c')
-rw-r--r-- | drivers/net/ucc_geth.c | 92 |
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) | |||
3350 | return 0; | 3350 | return 0; |
3351 | } | 3351 | } |
3352 | 3352 | ||
3353 | /* returns a net_device_stats structure pointer */ | ||
3354 | static struct net_device_stats *ucc_geth_get_stats(struct net_device *dev) | ||
3355 | { | ||
3356 | struct ucc_geth_private *ugeth = netdev_priv(dev); | ||
3357 | |||
3358 | return &(ugeth->stats); | ||
3359 | } | ||
3360 | |||
3361 | /* ucc_geth_timeout gets called when a packet has not been | 3353 | /* ucc_geth_timeout gets called when a packet has not been |
3362 | * transmitted after a set amount of time. | 3354 | * transmitted after a set amount of time. |
3363 | * For now, assume that clearing out all the structures, and | 3355 | * For now, assume that clearing out all the structures, and |
@@ -3368,7 +3360,7 @@ static void ucc_geth_timeout(struct net_device *dev) | |||
3368 | 3360 | ||
3369 | ugeth_vdbg("%s: IN", __FUNCTION__); | 3361 | ugeth_vdbg("%s: IN", __FUNCTION__); |
3370 | 3362 | ||
3371 | ugeth->stats.tx_errors++; | 3363 | dev->stats.tx_errors++; |
3372 | 3364 | ||
3373 | ugeth_dump_regs(ugeth); | 3365 | ugeth_dump_regs(ugeth); |
3374 | 3366 | ||
@@ -3396,7 +3388,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3396 | 3388 | ||
3397 | spin_lock_irq(&ugeth->lock); | 3389 | spin_lock_irq(&ugeth->lock); |
3398 | 3390 | ||
3399 | ugeth->stats.tx_bytes += skb->len; | 3391 | dev->stats.tx_bytes += skb->len; |
3400 | 3392 | ||
3401 | /* Start from the next BD that should be filled */ | 3393 | /* Start from the next BD that should be filled */ |
3402 | bd = ugeth->txBd[txQ]; | 3394 | bd = ugeth->txBd[txQ]; |
@@ -3488,9 +3480,9 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit | |||
3488 | dev_kfree_skb_any(skb); | 3480 | dev_kfree_skb_any(skb); |
3489 | 3481 | ||
3490 | ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]] = NULL; | 3482 | ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]] = NULL; |
3491 | ugeth->stats.rx_dropped++; | 3483 | dev->stats.rx_dropped++; |
3492 | } else { | 3484 | } else { |
3493 | ugeth->stats.rx_packets++; | 3485 | dev->stats.rx_packets++; |
3494 | howmany++; | 3486 | howmany++; |
3495 | 3487 | ||
3496 | /* Prep the skb for the packet */ | 3488 | /* 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 | |||
3499 | /* Tell the skb what kind of packet this is */ | 3491 | /* Tell the skb what kind of packet this is */ |
3500 | skb->protocol = eth_type_trans(skb, ugeth->dev); | 3492 | skb->protocol = eth_type_trans(skb, ugeth->dev); |
3501 | 3493 | ||
3502 | ugeth->stats.rx_bytes += length; | 3494 | dev->stats.rx_bytes += length; |
3503 | /* Send the packet up the stack */ | 3495 | /* Send the packet up the stack */ |
3504 | #ifdef CONFIG_UGETH_NAPI | 3496 | #ifdef CONFIG_UGETH_NAPI |
3505 | netif_receive_skb(skb); | 3497 | netif_receive_skb(skb); |
@@ -3514,7 +3506,7 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit | |||
3514 | if (!skb) { | 3506 | if (!skb) { |
3515 | if (netif_msg_rx_err(ugeth)) | 3507 | if (netif_msg_rx_err(ugeth)) |
3516 | ugeth_warn("%s: No Rx Data Buffer", __FUNCTION__); | 3508 | ugeth_warn("%s: No Rx Data Buffer", __FUNCTION__); |
3517 | ugeth->stats.rx_dropped++; | 3509 | dev->stats.rx_dropped++; |
3518 | break; | 3510 | break; |
3519 | } | 3511 | } |
3520 | 3512 | ||
@@ -3556,7 +3548,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) | |||
3556 | if ((bd == ugeth->txBd[txQ]) && (netif_queue_stopped(dev) == 0)) | 3548 | if ((bd == ugeth->txBd[txQ]) && (netif_queue_stopped(dev) == 0)) |
3557 | break; | 3549 | break; |
3558 | 3550 | ||
3559 | ugeth->stats.tx_packets++; | 3551 | dev->stats.tx_packets++; |
3560 | 3552 | ||
3561 | /* Free the sk buffer associated with this TxBD */ | 3553 | /* Free the sk buffer associated with this TxBD */ |
3562 | dev_kfree_skb_irq(ugeth-> | 3554 | dev_kfree_skb_irq(ugeth-> |
@@ -3582,41 +3574,31 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) | |||
3582 | } | 3574 | } |
3583 | 3575 | ||
3584 | #ifdef CONFIG_UGETH_NAPI | 3576 | #ifdef CONFIG_UGETH_NAPI |
3585 | static int ucc_geth_poll(struct net_device *dev, int *budget) | 3577 | static int ucc_geth_poll(struct napi_struct *napi, int budget) |
3586 | { | 3578 | { |
3587 | struct ucc_geth_private *ugeth = netdev_priv(dev); | 3579 | struct ucc_geth_private *ugeth = container_of(napi, struct ucc_geth_private, napi); |
3580 | struct net_device *dev = ugeth->dev; | ||
3588 | struct ucc_geth_info *ug_info; | 3581 | struct ucc_geth_info *ug_info; |
3589 | struct ucc_fast_private *uccf; | 3582 | int howmany, i; |
3590 | int howmany; | ||
3591 | u8 i; | ||
3592 | int rx_work_limit; | ||
3593 | register u32 uccm; | ||
3594 | 3583 | ||
3595 | ug_info = ugeth->ug_info; | 3584 | ug_info = ugeth->ug_info; |
3596 | 3585 | ||
3597 | rx_work_limit = *budget; | ||
3598 | if (rx_work_limit > dev->quota) | ||
3599 | rx_work_limit = dev->quota; | ||
3600 | |||
3601 | howmany = 0; | 3586 | howmany = 0; |
3587 | for (i = 0; i < ug_info->numQueuesRx; i++) | ||
3588 | howmany += ucc_geth_rx(ugeth, i, budget - howmany); | ||
3602 | 3589 | ||
3603 | for (i = 0; i < ug_info->numQueuesRx; i++) { | 3590 | if (howmany < budget) { |
3604 | howmany += ucc_geth_rx(ugeth, i, rx_work_limit); | 3591 | struct ucc_fast_private *uccf; |
3605 | } | 3592 | u32 uccm; |
3606 | |||
3607 | dev->quota -= howmany; | ||
3608 | rx_work_limit -= howmany; | ||
3609 | *budget -= howmany; | ||
3610 | 3593 | ||
3611 | if (rx_work_limit > 0) { | 3594 | netif_rx_complete(dev, napi); |
3612 | netif_rx_complete(dev); | ||
3613 | uccf = ugeth->uccf; | 3595 | uccf = ugeth->uccf; |
3614 | uccm = in_be32(uccf->p_uccm); | 3596 | uccm = in_be32(uccf->p_uccm); |
3615 | uccm |= UCCE_RX_EVENTS; | 3597 | uccm |= UCCE_RX_EVENTS; |
3616 | out_be32(uccf->p_uccm, uccm); | 3598 | out_be32(uccf->p_uccm, uccm); |
3617 | } | 3599 | } |
3618 | 3600 | ||
3619 | return (rx_work_limit > 0) ? 0 : 1; | 3601 | return howmany; |
3620 | } | 3602 | } |
3621 | #endif /* CONFIG_UGETH_NAPI */ | 3603 | #endif /* CONFIG_UGETH_NAPI */ |
3622 | 3604 | ||
@@ -3651,10 +3633,10 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info) | |||
3651 | /* check for receive events that require processing */ | 3633 | /* check for receive events that require processing */ |
3652 | if (ucce & UCCE_RX_EVENTS) { | 3634 | if (ucce & UCCE_RX_EVENTS) { |
3653 | #ifdef CONFIG_UGETH_NAPI | 3635 | #ifdef CONFIG_UGETH_NAPI |
3654 | if (netif_rx_schedule_prep(dev)) { | 3636 | if (netif_rx_schedule_prep(dev, &ugeth->napi)) { |
3655 | uccm &= ~UCCE_RX_EVENTS; | 3637 | uccm &= ~UCCE_RX_EVENTS; |
3656 | out_be32(uccf->p_uccm, uccm); | 3638 | out_be32(uccf->p_uccm, uccm); |
3657 | __netif_rx_schedule(dev); | 3639 | __netif_rx_schedule(dev, &ugeth->napi); |
3658 | } | 3640 | } |
3659 | #else | 3641 | #else |
3660 | rx_mask = UCCE_RXBF_SINGLE_MASK; | 3642 | rx_mask = UCCE_RXBF_SINGLE_MASK; |
@@ -3683,10 +3665,10 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info) | |||
3683 | /* Errors and other events */ | 3665 | /* Errors and other events */ |
3684 | if (ucce & UCCE_OTHER) { | 3666 | if (ucce & UCCE_OTHER) { |
3685 | if (ucce & UCCE_BSY) { | 3667 | if (ucce & UCCE_BSY) { |
3686 | ugeth->stats.rx_errors++; | 3668 | dev->stats.rx_errors++; |
3687 | } | 3669 | } |
3688 | if (ucce & UCCE_TXE) { | 3670 | if (ucce & UCCE_TXE) { |
3689 | ugeth->stats.tx_errors++; | 3671 | dev->stats.tx_errors++; |
3690 | } | 3672 | } |
3691 | } | 3673 | } |
3692 | 3674 | ||
@@ -3717,12 +3699,15 @@ static int ucc_geth_open(struct net_device *dev) | |||
3717 | return err; | 3699 | return err; |
3718 | } | 3700 | } |
3719 | 3701 | ||
3702 | #ifdef CONFIG_UGETH_NAPI | ||
3703 | napi_enable(&ugeth->napi); | ||
3704 | #endif | ||
3720 | err = ucc_geth_startup(ugeth); | 3705 | err = ucc_geth_startup(ugeth); |
3721 | if (err) { | 3706 | if (err) { |
3722 | if (netif_msg_ifup(ugeth)) | 3707 | if (netif_msg_ifup(ugeth)) |
3723 | ugeth_err("%s: Cannot configure net device, aborting.", | 3708 | ugeth_err("%s: Cannot configure net device, aborting.", |
3724 | dev->name); | 3709 | dev->name); |
3725 | return err; | 3710 | goto out_err; |
3726 | } | 3711 | } |
3727 | 3712 | ||
3728 | err = adjust_enet_interface(ugeth); | 3713 | err = adjust_enet_interface(ugeth); |
@@ -3730,7 +3715,7 @@ static int ucc_geth_open(struct net_device *dev) | |||
3730 | if (netif_msg_ifup(ugeth)) | 3715 | if (netif_msg_ifup(ugeth)) |
3731 | ugeth_err("%s: Cannot configure net device, aborting.", | 3716 | ugeth_err("%s: Cannot configure net device, aborting.", |
3732 | dev->name); | 3717 | dev->name); |
3733 | return err; | 3718 | goto out_err; |
3734 | } | 3719 | } |
3735 | 3720 | ||
3736 | /* Set MACSTNADDR1, MACSTNADDR2 */ | 3721 | /* Set MACSTNADDR1, MACSTNADDR2 */ |
@@ -3748,7 +3733,7 @@ static int ucc_geth_open(struct net_device *dev) | |||
3748 | if (err) { | 3733 | if (err) { |
3749 | if (netif_msg_ifup(ugeth)) | 3734 | if (netif_msg_ifup(ugeth)) |
3750 | ugeth_err("%s: Cannot initialize PHY, aborting.", dev->name); | 3735 | ugeth_err("%s: Cannot initialize PHY, aborting.", dev->name); |
3751 | return err; | 3736 | goto out_err; |
3752 | } | 3737 | } |
3753 | 3738 | ||
3754 | phy_start(ugeth->phydev); | 3739 | phy_start(ugeth->phydev); |
@@ -3761,7 +3746,7 @@ static int ucc_geth_open(struct net_device *dev) | |||
3761 | ugeth_err("%s: Cannot get IRQ for net device, aborting.", | 3746 | ugeth_err("%s: Cannot get IRQ for net device, aborting.", |
3762 | dev->name); | 3747 | dev->name); |
3763 | ucc_geth_stop(ugeth); | 3748 | ucc_geth_stop(ugeth); |
3764 | return err; | 3749 | goto out_err; |
3765 | } | 3750 | } |
3766 | 3751 | ||
3767 | err = ugeth_enable(ugeth, COMM_DIR_RX_AND_TX); | 3752 | err = ugeth_enable(ugeth, COMM_DIR_RX_AND_TX); |
@@ -3769,12 +3754,18 @@ static int ucc_geth_open(struct net_device *dev) | |||
3769 | if (netif_msg_ifup(ugeth)) | 3754 | if (netif_msg_ifup(ugeth)) |
3770 | ugeth_err("%s: Cannot enable net device, aborting.", dev->name); | 3755 | ugeth_err("%s: Cannot enable net device, aborting.", dev->name); |
3771 | ucc_geth_stop(ugeth); | 3756 | ucc_geth_stop(ugeth); |
3772 | return err; | 3757 | goto out_err; |
3773 | } | 3758 | } |
3774 | 3759 | ||
3775 | netif_start_queue(dev); | 3760 | netif_start_queue(dev); |
3776 | 3761 | ||
3777 | return err; | 3762 | return err; |
3763 | |||
3764 | out_err: | ||
3765 | #ifdef CONFIG_UGETH_NAPI | ||
3766 | napi_disable(&ugeth->napi); | ||
3767 | #endif | ||
3768 | return err; | ||
3778 | } | 3769 | } |
3779 | 3770 | ||
3780 | /* Stops the kernel queue, and halts the controller */ | 3771 | /* Stops the kernel queue, and halts the controller */ |
@@ -3784,6 +3775,10 @@ static int ucc_geth_close(struct net_device *dev) | |||
3784 | 3775 | ||
3785 | ugeth_vdbg("%s: IN", __FUNCTION__); | 3776 | ugeth_vdbg("%s: IN", __FUNCTION__); |
3786 | 3777 | ||
3778 | #ifdef CONFIG_UGETH_NAPI | ||
3779 | napi_disable(&ugeth->napi); | ||
3780 | #endif | ||
3781 | |||
3787 | ucc_geth_stop(ugeth); | 3782 | ucc_geth_stop(ugeth); |
3788 | 3783 | ||
3789 | phy_disconnect(ugeth->phydev); | 3784 | phy_disconnect(ugeth->phydev); |
@@ -3954,7 +3949,6 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma | |||
3954 | /* Set the dev->base_addr to the gfar reg region */ | 3949 | /* Set the dev->base_addr to the gfar reg region */ |
3955 | dev->base_addr = (unsigned long)(ug_info->uf_info.regs); | 3950 | dev->base_addr = (unsigned long)(ug_info->uf_info.regs); |
3956 | 3951 | ||
3957 | SET_MODULE_OWNER(dev); | ||
3958 | SET_NETDEV_DEV(dev, device); | 3952 | SET_NETDEV_DEV(dev, device); |
3959 | 3953 | ||
3960 | /* Fill in the dev structure */ | 3954 | /* Fill in the dev structure */ |
@@ -3964,11 +3958,9 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma | |||
3964 | dev->tx_timeout = ucc_geth_timeout; | 3958 | dev->tx_timeout = ucc_geth_timeout; |
3965 | dev->watchdog_timeo = TX_TIMEOUT; | 3959 | dev->watchdog_timeo = TX_TIMEOUT; |
3966 | #ifdef CONFIG_UGETH_NAPI | 3960 | #ifdef CONFIG_UGETH_NAPI |
3967 | dev->poll = ucc_geth_poll; | 3961 | 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 */ | 3962 | #endif /* CONFIG_UGETH_NAPI */ |
3970 | dev->stop = ucc_geth_close; | 3963 | dev->stop = ucc_geth_close; |
3971 | dev->get_stats = ucc_geth_get_stats; | ||
3972 | // dev->change_mtu = ucc_geth_change_mtu; | 3964 | // dev->change_mtu = ucc_geth_change_mtu; |
3973 | dev->mtu = 1500; | 3965 | dev->mtu = 1500; |
3974 | dev->set_multicast_list = ucc_geth_set_multi; | 3966 | dev->set_multicast_list = ucc_geth_set_multi; |