diff options
author | Stephen Hemminger <shemminger@linux-foundation.org> | 2007-10-16 15:15:50 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-10-16 21:10:28 -0400 |
commit | 60b24b51799cc23313eed85fb874b70a6d02e2b7 (patch) | |
tree | 7ee3aef13967c65923a24962ece0e8af66a227a2 /drivers/net/skge.c | |
parent | 7fb7ac241162dc51ec0f7644d4a97b2855213c32 (diff) |
skge: changing MTU while running causes problems
Rather than bring network down/up when changing MTU,
only need to impact receiver.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/skge.c')
-rw-r--r-- | drivers/net/skge.c | 51 |
1 files changed, 44 insertions, 7 deletions
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index e593585f8bf7..d5c10fd93bf4 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
@@ -2544,6 +2544,15 @@ static int skge_up(struct net_device *dev) | |||
2544 | return err; | 2544 | return err; |
2545 | } | 2545 | } |
2546 | 2546 | ||
2547 | /* stop receiver */ | ||
2548 | static void skge_rx_stop(struct skge_hw *hw, int port) | ||
2549 | { | ||
2550 | skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_STOP); | ||
2551 | skge_write32(hw, RB_ADDR(port ? Q_R2 : Q_R1, RB_CTRL), | ||
2552 | RB_RST_SET|RB_DIS_OP_MD); | ||
2553 | skge_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_SET_RESET); | ||
2554 | } | ||
2555 | |||
2547 | static int skge_down(struct net_device *dev) | 2556 | static int skge_down(struct net_device *dev) |
2548 | { | 2557 | { |
2549 | struct skge_port *skge = netdev_priv(dev); | 2558 | struct skge_port *skge = netdev_priv(dev); |
@@ -2595,11 +2604,8 @@ static int skge_down(struct net_device *dev) | |||
2595 | 2604 | ||
2596 | /* Reset the RAM Buffer async Tx queue */ | 2605 | /* Reset the RAM Buffer async Tx queue */ |
2597 | skge_write8(hw, RB_ADDR(port == 0 ? Q_XA1 : Q_XA2, RB_CTRL), RB_RST_SET); | 2606 | skge_write8(hw, RB_ADDR(port == 0 ? Q_XA1 : Q_XA2, RB_CTRL), RB_RST_SET); |
2598 | /* stop receiver */ | 2607 | |
2599 | skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_STOP); | 2608 | skge_rx_stop(hw, port); |
2600 | skge_write32(hw, RB_ADDR(port ? Q_R2 : Q_R1, RB_CTRL), | ||
2601 | RB_RST_SET|RB_DIS_OP_MD); | ||
2602 | skge_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_SET_RESET); | ||
2603 | 2609 | ||
2604 | if (hw->chip_id == CHIP_ID_GENESIS) { | 2610 | if (hw->chip_id == CHIP_ID_GENESIS) { |
2605 | skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_RST_SET); | 2611 | skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_RST_SET); |
@@ -2782,7 +2788,11 @@ static void skge_tx_timeout(struct net_device *dev) | |||
2782 | 2788 | ||
2783 | static int skge_change_mtu(struct net_device *dev, int new_mtu) | 2789 | static int skge_change_mtu(struct net_device *dev, int new_mtu) |
2784 | { | 2790 | { |
2791 | struct skge_port *skge = netdev_priv(dev); | ||
2792 | struct skge_hw *hw = skge->hw; | ||
2793 | int port = skge->port; | ||
2785 | int err; | 2794 | int err; |
2795 | u16 ctl, reg; | ||
2786 | 2796 | ||
2787 | if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) | 2797 | if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) |
2788 | return -EINVAL; | 2798 | return -EINVAL; |
@@ -2792,13 +2802,40 @@ static int skge_change_mtu(struct net_device *dev, int new_mtu) | |||
2792 | return 0; | 2802 | return 0; |
2793 | } | 2803 | } |
2794 | 2804 | ||
2795 | skge_down(dev); | 2805 | skge_write32(hw, B0_IMSK, 0); |
2806 | dev->trans_start = jiffies; /* prevent tx timeout */ | ||
2807 | netif_stop_queue(dev); | ||
2808 | napi_disable(&skge->napi); | ||
2809 | |||
2810 | ctl = gma_read16(hw, port, GM_GP_CTRL); | ||
2811 | gma_write16(hw, port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA); | ||
2812 | |||
2813 | skge_rx_clean(skge); | ||
2814 | skge_rx_stop(hw, port); | ||
2796 | 2815 | ||
2797 | dev->mtu = new_mtu; | 2816 | dev->mtu = new_mtu; |
2798 | 2817 | ||
2799 | err = skge_up(dev); | 2818 | reg = GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF); |
2819 | if (new_mtu > 1500) | ||
2820 | reg |= GM_SMOD_JUMBO_ENA; | ||
2821 | gma_write16(hw, port, GM_SERIAL_MODE, reg); | ||
2822 | |||
2823 | skge_write8(hw, RB_ADDR(rxqaddr[port], RB_CTRL), RB_ENA_OP_MD); | ||
2824 | |||
2825 | err = skge_rx_fill(dev); | ||
2826 | wmb(); | ||
2827 | if (!err) | ||
2828 | skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_START | CSR_IRQ_CL_F); | ||
2829 | skge_write32(hw, B0_IMSK, hw->intr_mask); | ||
2830 | |||
2800 | if (err) | 2831 | if (err) |
2801 | dev_close(dev); | 2832 | dev_close(dev); |
2833 | else { | ||
2834 | gma_write16(hw, port, GM_GP_CTRL, ctl); | ||
2835 | |||
2836 | napi_enable(&skge->napi); | ||
2837 | netif_wake_queue(dev); | ||
2838 | } | ||
2802 | 2839 | ||
2803 | return err; | 2840 | return err; |
2804 | } | 2841 | } |