diff options
author | Hayes Wang <hayeswang@realtek.com> | 2011-07-06 03:58:03 -0400 |
---|---|---|
committer | Francois Romieu <romieu@fr.zoreil.com> | 2011-07-14 17:22:22 -0400 |
commit | 92fc43b4159b518f5baae57301f26d770b0834c9 (patch) | |
tree | fa2a785a90e3d5d0aada24cf0672d2c516db38b6 /drivers/net/r8169.c | |
parent | 4f6b00e5f139d7be3ca8371b769778f94fa549dd (diff) |
r8169: modify the flow of the hw reset.
- Disable tx and rx by resetting hw, so replace rtl8169_asic_down
with rtl8169_hw_reset.
- RxConfig bits 0 ~ 5 have to be cleared before hw reset to avoid
receiving spurious data.
- Certain chips need to do some checking before reset.
- Remove hw reset which is done before hw_start. It is done in close,
down or device probe functions.
- Move rtl8169_init_ring_indexes function into rtl_hw_reset function.
The indexes of tx and rx only need to be zero when the hw resets.
Signed-off-by: Hayes Wang <hayeswang@realtek.com>
Acked-by: Francois Romieu <romieu@fr.zoreil.com>
Diffstat (limited to 'drivers/net/r8169.c')
-rw-r--r-- | drivers/net/r8169.c | 53 |
1 files changed, 28 insertions, 25 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 52ad6cea4e7a..604f94647b63 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -1071,13 +1071,6 @@ static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr) | |||
1071 | RTL_W16(IntrStatus, 0xffff); | 1071 | RTL_W16(IntrStatus, 0xffff); |
1072 | } | 1072 | } |
1073 | 1073 | ||
1074 | static void rtl8169_asic_down(void __iomem *ioaddr) | ||
1075 | { | ||
1076 | RTL_W8(ChipCmd, 0x00); | ||
1077 | rtl8169_irq_mask_and_ack(ioaddr); | ||
1078 | RTL_R16(CPlusCmd); | ||
1079 | } | ||
1080 | |||
1081 | static unsigned int rtl8169_tbi_reset_pending(struct rtl8169_private *tp) | 1074 | static unsigned int rtl8169_tbi_reset_pending(struct rtl8169_private *tp) |
1082 | { | 1075 | { |
1083 | void __iomem *ioaddr = tp->mmio_addr; | 1076 | void __iomem *ioaddr = tp->mmio_addr; |
@@ -3337,6 +3330,11 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp) | |||
3337 | } | 3330 | } |
3338 | } | 3331 | } |
3339 | 3332 | ||
3333 | static void rtl8169_init_ring_indexes(struct rtl8169_private *tp) | ||
3334 | { | ||
3335 | tp->dirty_tx = tp->dirty_rx = tp->cur_tx = tp->cur_rx = 0; | ||
3336 | } | ||
3337 | |||
3340 | static void rtl_hw_reset(struct rtl8169_private *tp) | 3338 | static void rtl_hw_reset(struct rtl8169_private *tp) |
3341 | { | 3339 | { |
3342 | void __iomem *ioaddr = tp->mmio_addr; | 3340 | void __iomem *ioaddr = tp->mmio_addr; |
@@ -3349,8 +3347,10 @@ static void rtl_hw_reset(struct rtl8169_private *tp) | |||
3349 | for (i = 0; i < 100; i++) { | 3347 | for (i = 0; i < 100; i++) { |
3350 | if ((RTL_R8(ChipCmd) & CmdReset) == 0) | 3348 | if ((RTL_R8(ChipCmd) & CmdReset) == 0) |
3351 | break; | 3349 | break; |
3352 | msleep_interruptible(1); | 3350 | udelay(100); |
3353 | } | 3351 | } |
3352 | |||
3353 | rtl8169_init_ring_indexes(tp); | ||
3354 | } | 3354 | } |
3355 | 3355 | ||
3356 | static int __devinit | 3356 | static int __devinit |
@@ -3732,6 +3732,16 @@ err_pm_runtime_put: | |||
3732 | goto out; | 3732 | goto out; |
3733 | } | 3733 | } |
3734 | 3734 | ||
3735 | static void rtl_rx_close(struct rtl8169_private *tp) | ||
3736 | { | ||
3737 | void __iomem *ioaddr = tp->mmio_addr; | ||
3738 | u32 rxcfg = RTL_R32(RxConfig); | ||
3739 | |||
3740 | rxcfg &= ~(AcceptErr | AcceptRunt | AcceptBroadcast | AcceptMulticast | | ||
3741 | AcceptMyPhys | AcceptAllPhys); | ||
3742 | RTL_W32(RxConfig, rxcfg); | ||
3743 | } | ||
3744 | |||
3735 | static void rtl8169_hw_reset(struct rtl8169_private *tp) | 3745 | static void rtl8169_hw_reset(struct rtl8169_private *tp) |
3736 | { | 3746 | { |
3737 | void __iomem *ioaddr = tp->mmio_addr; | 3747 | void __iomem *ioaddr = tp->mmio_addr; |
@@ -3739,19 +3749,19 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp) | |||
3739 | /* Disable interrupts */ | 3749 | /* Disable interrupts */ |
3740 | rtl8169_irq_mask_and_ack(ioaddr); | 3750 | rtl8169_irq_mask_and_ack(ioaddr); |
3741 | 3751 | ||
3752 | rtl_rx_close(tp); | ||
3753 | |||
3742 | if (tp->mac_version == RTL_GIGA_MAC_VER_27 || | 3754 | if (tp->mac_version == RTL_GIGA_MAC_VER_27 || |
3743 | tp->mac_version == RTL_GIGA_MAC_VER_28 || | 3755 | tp->mac_version == RTL_GIGA_MAC_VER_28 || |
3744 | tp->mac_version == RTL_GIGA_MAC_VER_31) { | 3756 | tp->mac_version == RTL_GIGA_MAC_VER_31) { |
3745 | while (RTL_R8(TxPoll) & NPQ) | 3757 | while (RTL_R8(TxPoll) & NPQ) |
3746 | udelay(20); | 3758 | udelay(20); |
3747 | 3759 | } else { | |
3760 | RTL_W8(ChipCmd, RTL_R8(ChipCmd) | StopReq); | ||
3761 | udelay(100); | ||
3748 | } | 3762 | } |
3749 | 3763 | ||
3750 | /* Reset the chipset */ | 3764 | rtl_hw_reset(tp); |
3751 | RTL_W8(ChipCmd, CmdReset); | ||
3752 | |||
3753 | /* PCI commit */ | ||
3754 | RTL_R8(ChipCmd); | ||
3755 | } | 3765 | } |
3756 | 3766 | ||
3757 | static void rtl_set_rx_tx_config_registers(struct rtl8169_private *tp) | 3767 | static void rtl_set_rx_tx_config_registers(struct rtl8169_private *tp) |
@@ -3771,8 +3781,6 @@ static void rtl_hw_start(struct net_device *dev) | |||
3771 | { | 3781 | { |
3772 | struct rtl8169_private *tp = netdev_priv(dev); | 3782 | struct rtl8169_private *tp = netdev_priv(dev); |
3773 | 3783 | ||
3774 | rtl_hw_reset(tp); | ||
3775 | |||
3776 | tp->hw_start(dev); | 3784 | tp->hw_start(dev); |
3777 | 3785 | ||
3778 | netif_start_queue(dev); | 3786 | netif_start_queue(dev); |
@@ -4581,11 +4589,6 @@ err_out: | |||
4581 | return -ENOMEM; | 4589 | return -ENOMEM; |
4582 | } | 4590 | } |
4583 | 4591 | ||
4584 | static void rtl8169_init_ring_indexes(struct rtl8169_private *tp) | ||
4585 | { | ||
4586 | tp->dirty_tx = tp->dirty_rx = tp->cur_tx = tp->cur_rx = 0; | ||
4587 | } | ||
4588 | |||
4589 | static int rtl8169_init_ring(struct net_device *dev) | 4592 | static int rtl8169_init_ring(struct net_device *dev) |
4590 | { | 4593 | { |
4591 | struct rtl8169_private *tp = netdev_priv(dev); | 4594 | struct rtl8169_private *tp = netdev_priv(dev); |
@@ -4713,7 +4716,7 @@ static void rtl8169_reset_task(struct work_struct *work) | |||
4713 | 4716 | ||
4714 | rtl8169_tx_clear(tp); | 4717 | rtl8169_tx_clear(tp); |
4715 | 4718 | ||
4716 | rtl8169_init_ring_indexes(tp); | 4719 | rtl8169_hw_reset(tp); |
4717 | rtl_hw_start(dev); | 4720 | rtl_hw_start(dev); |
4718 | netif_wake_queue(dev); | 4721 | netif_wake_queue(dev); |
4719 | rtl8169_check_link_status(dev, tp, tp->mmio_addr); | 4722 | rtl8169_check_link_status(dev, tp, tp->mmio_addr); |
@@ -5127,7 +5130,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) | |||
5127 | * the chip, so just exit the loop. | 5130 | * the chip, so just exit the loop. |
5128 | */ | 5131 | */ |
5129 | if (unlikely(!netif_running(dev))) { | 5132 | if (unlikely(!netif_running(dev))) { |
5130 | rtl8169_asic_down(ioaddr); | 5133 | rtl8169_hw_reset(tp); |
5131 | break; | 5134 | break; |
5132 | } | 5135 | } |
5133 | 5136 | ||
@@ -5250,7 +5253,7 @@ static void rtl8169_down(struct net_device *dev) | |||
5250 | 5253 | ||
5251 | spin_lock_irq(&tp->lock); | 5254 | spin_lock_irq(&tp->lock); |
5252 | 5255 | ||
5253 | rtl8169_asic_down(ioaddr); | 5256 | rtl8169_hw_reset(tp); |
5254 | /* | 5257 | /* |
5255 | * At this point device interrupts can not be enabled in any function, | 5258 | * At this point device interrupts can not be enabled in any function, |
5256 | * as netif_running is not true (rtl8169_interrupt, rtl8169_reset_task, | 5259 | * as netif_running is not true (rtl8169_interrupt, rtl8169_reset_task, |
@@ -5504,7 +5507,7 @@ static void rtl_shutdown(struct pci_dev *pdev) | |||
5504 | 5507 | ||
5505 | spin_lock_irq(&tp->lock); | 5508 | spin_lock_irq(&tp->lock); |
5506 | 5509 | ||
5507 | rtl8169_asic_down(ioaddr); | 5510 | rtl8169_hw_reset(tp); |
5508 | 5511 | ||
5509 | spin_unlock_irq(&tp->lock); | 5512 | spin_unlock_irq(&tp->lock); |
5510 | 5513 | ||