Commit 60b24b51 authored by Stephen Hemminger's avatar Stephen Hemminger Committed by Jeff Garzik

skge: changing MTU while running causes problems

Rather than bring network down/up when changing MTU,
only need to impact receiver.
Signed-off-by: default avatarStephen Hemminger <shemminger@linux-foundation.org>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 7fb7ac24
...@@ -2544,6 +2544,15 @@ static int skge_up(struct net_device *dev) ...@@ -2544,6 +2544,15 @@ static int skge_up(struct net_device *dev)
return err; return err;
} }
/* stop receiver */
static void skge_rx_stop(struct skge_hw *hw, int port)
{
skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_STOP);
skge_write32(hw, RB_ADDR(port ? Q_R2 : Q_R1, RB_CTRL),
RB_RST_SET|RB_DIS_OP_MD);
skge_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_SET_RESET);
}
static int skge_down(struct net_device *dev) static int skge_down(struct net_device *dev)
{ {
struct skge_port *skge = netdev_priv(dev); struct skge_port *skge = netdev_priv(dev);
...@@ -2595,11 +2604,8 @@ static int skge_down(struct net_device *dev) ...@@ -2595,11 +2604,8 @@ static int skge_down(struct net_device *dev)
/* Reset the RAM Buffer async Tx queue */ /* Reset the RAM Buffer async Tx queue */
skge_write8(hw, RB_ADDR(port == 0 ? Q_XA1 : Q_XA2, RB_CTRL), RB_RST_SET); skge_write8(hw, RB_ADDR(port == 0 ? Q_XA1 : Q_XA2, RB_CTRL), RB_RST_SET);
/* stop receiver */
skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_STOP); skge_rx_stop(hw, port);
skge_write32(hw, RB_ADDR(port ? Q_R2 : Q_R1, RB_CTRL),
RB_RST_SET|RB_DIS_OP_MD);
skge_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_SET_RESET);
if (hw->chip_id == CHIP_ID_GENESIS) { if (hw->chip_id == CHIP_ID_GENESIS) {
skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_RST_SET); 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,7 +2788,11 @@ static void skge_tx_timeout(struct net_device *dev)
static int skge_change_mtu(struct net_device *dev, int new_mtu) static int skge_change_mtu(struct net_device *dev, int new_mtu)
{ {
struct skge_port *skge = netdev_priv(dev);
struct skge_hw *hw = skge->hw;
int port = skge->port;
int err; int err;
u16 ctl, reg;
if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
return -EINVAL; return -EINVAL;
...@@ -2792,13 +2802,40 @@ static int skge_change_mtu(struct net_device *dev, int new_mtu) ...@@ -2792,13 +2802,40 @@ static int skge_change_mtu(struct net_device *dev, int new_mtu)
return 0; return 0;
} }
skge_down(dev); skge_write32(hw, B0_IMSK, 0);
dev->trans_start = jiffies; /* prevent tx timeout */
netif_stop_queue(dev);
napi_disable(&skge->napi);
ctl = gma_read16(hw, port, GM_GP_CTRL);
gma_write16(hw, port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA);
skge_rx_clean(skge);
skge_rx_stop(hw, port);
dev->mtu = new_mtu; dev->mtu = new_mtu;
err = skge_up(dev); reg = GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF);
if (new_mtu > 1500)
reg |= GM_SMOD_JUMBO_ENA;
gma_write16(hw, port, GM_SERIAL_MODE, reg);
skge_write8(hw, RB_ADDR(rxqaddr[port], RB_CTRL), RB_ENA_OP_MD);
err = skge_rx_fill(dev);
wmb();
if (!err)
skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_START | CSR_IRQ_CL_F);
skge_write32(hw, B0_IMSK, hw->intr_mask);
if (err) if (err)
dev_close(dev); dev_close(dev);
else {
gma_write16(hw, port, GM_GP_CTRL, ctl);
napi_enable(&skge->napi);
netif_wake_queue(dev);
}
return err; return err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment