|
@@ -2544,6 +2544,15 @@ static int skge_up(struct net_device *dev)
|
|
|
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)
|
|
|
{
|
|
|
struct skge_port *skge = netdev_priv(dev);
|
|
@@ -2595,11 +2604,8 @@ static int skge_down(struct net_device *dev)
|
|
|
|
|
|
/* Reset the RAM Buffer async Tx queue */
|
|
|
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_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);
|
|
|
+
|
|
|
+ skge_rx_stop(hw, port);
|
|
|
|
|
|
if (hw->chip_id == CHIP_ID_GENESIS) {
|
|
|
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)
|
|
|
|
|
|
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;
|
|
|
+ u16 ctl, reg;
|
|
|
|
|
|
if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
|
|
|
return -EINVAL;
|
|
@@ -2792,13 +2802,40 @@ static int skge_change_mtu(struct net_device *dev, int new_mtu)
|
|
|
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;
|
|
|
|
|
|
- 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)
|
|
|
dev_close(dev);
|
|
|
+ else {
|
|
|
+ gma_write16(hw, port, GM_GP_CTRL, ctl);
|
|
|
+
|
|
|
+ napi_enable(&skge->napi);
|
|
|
+ netif_wake_queue(dev);
|
|
|
+ }
|
|
|
|
|
|
return err;
|
|
|
}
|