lkml.org 
[lkml]   [2020]   [Feb]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.9 65/68] net/sonic: Quiesce SONIC before re-initializing descriptor memory
    Date
    From: Finn Thain <fthain@telegraphics.com.au>

    [ Upstream commit 3f4b7e6a2be982fd8820a2b54d46dd9c351db899 ]

    Make sure the SONIC's DMA engine is idle before altering the transmit
    and receive descriptors. Add a helper for this as it will be needed
    again.

    Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
    Tested-by: Stan Johnson <userm57@yahoo.com>
    Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/net/ethernet/natsemi/sonic.c | 25 +++++++++++++++++++++++++
    drivers/net/ethernet/natsemi/sonic.h | 3 +++
    2 files changed, 28 insertions(+)

    diff --git a/drivers/net/ethernet/natsemi/sonic.c b/drivers/net/ethernet/natsemi/sonic.c
    index b6599aa22504f..254e6dbc4c6aa 100644
    --- a/drivers/net/ethernet/natsemi/sonic.c
    +++ b/drivers/net/ethernet/natsemi/sonic.c
    @@ -103,6 +103,24 @@ static int sonic_open(struct net_device *dev)
    return 0;
    }

    +/* Wait for the SONIC to become idle. */
    +static void sonic_quiesce(struct net_device *dev, u16 mask)
    +{
    + struct sonic_local * __maybe_unused lp = netdev_priv(dev);
    + int i;
    + u16 bits;
    +
    + for (i = 0; i < 1000; ++i) {
    + bits = SONIC_READ(SONIC_CMD) & mask;
    + if (!bits)
    + return;
    + if (irqs_disabled() || in_interrupt())
    + udelay(20);
    + else
    + usleep_range(100, 200);
    + }
    + WARN_ONCE(1, "command deadline expired! 0x%04x\n", bits);
    +}

    /*
    * Close the SONIC device
    @@ -120,6 +138,9 @@ static int sonic_close(struct net_device *dev)
    /*
    * stop the SONIC, disable interrupts
    */
    + SONIC_WRITE(SONIC_CMD, SONIC_CR_RXDIS);
    + sonic_quiesce(dev, SONIC_CR_ALL);
    +
    SONIC_WRITE(SONIC_IMR, 0);
    SONIC_WRITE(SONIC_ISR, 0x7fff);
    SONIC_WRITE(SONIC_CMD, SONIC_CR_RST);
    @@ -159,6 +180,9 @@ static void sonic_tx_timeout(struct net_device *dev)
    * put the Sonic into software-reset mode and
    * disable all interrupts before releasing DMA buffers
    */
    + SONIC_WRITE(SONIC_CMD, SONIC_CR_RXDIS);
    + sonic_quiesce(dev, SONIC_CR_ALL);
    +
    SONIC_WRITE(SONIC_IMR, 0);
    SONIC_WRITE(SONIC_ISR, 0x7fff);
    SONIC_WRITE(SONIC_CMD, SONIC_CR_RST);
    @@ -638,6 +662,7 @@ static int sonic_init(struct net_device *dev)
    */
    SONIC_WRITE(SONIC_CMD, 0);
    SONIC_WRITE(SONIC_CMD, SONIC_CR_RXDIS);
    + sonic_quiesce(dev, SONIC_CR_ALL);

    /*
    * initialize the receive resource area
    diff --git a/drivers/net/ethernet/natsemi/sonic.h b/drivers/net/ethernet/natsemi/sonic.h
    index d9f8ceb5353a4..7dcf913d7395a 100644
    --- a/drivers/net/ethernet/natsemi/sonic.h
    +++ b/drivers/net/ethernet/natsemi/sonic.h
    @@ -109,6 +109,9 @@
    #define SONIC_CR_TXP 0x0002
    #define SONIC_CR_HTX 0x0001

    +#define SONIC_CR_ALL (SONIC_CR_LCAM | SONIC_CR_RRRA | \
    + SONIC_CR_RXEN | SONIC_CR_TXP)
    +
    /*
    * SONIC data configuration bits
    */
    --
    2.20.1


    \
     
     \ /
      Last update: 2020-02-03 17:27    [W:2.949 / U:0.144 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site