aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@linux-foundation.org>2007-10-16 15:15:50 -0400
committerJeff Garzik <jeff@garzik.org>2007-10-16 21:10:28 -0400
commit60b24b51799cc23313eed85fb874b70a6d02e2b7 (patch)
tree7ee3aef13967c65923a24962ece0e8af66a227a2
parent7fb7ac241162dc51ec0f7644d4a97b2855213c32 (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>
-rw-r--r--drivers/net/skge.c51
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 */
2548static 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
2547static int skge_down(struct net_device *dev) 2556static 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
2783static int skge_change_mtu(struct net_device *dev, int new_mtu) 2789static 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}