lkml.org 
[lkml]   [2017]   [Dec]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.9 040/104] r8152: prevent the driver from transmitting packets with carrier off
    Date
    4.9-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: hayeswang <hayeswang@realtek.com>


    [ Upstream commit 2f25abe6bac573928a990ccbdac75873add8127e ]

    The linking status may be changed when autosuspend. And, after
    autoresume, the driver may try to transmit packets when the device
    is carrier off, because the interrupt transfer doesn't update the
    linking status, yet. And, if the device is in ALDPS mode, the device
    would stop working.

    The another similar case is
    1. unplug the cable.
    2. interrupt transfer queue a work_queue for linking change.
    3. device enters the ALDPS mode.
    4. a tx occurs before the work_queue is called.

    Signed-off-by: Hayes Wang <hayeswang@realtek.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/net/usb/r8152.c | 18 ++++++++++++++++--
    1 file changed, 16 insertions(+), 2 deletions(-)

    --- a/drivers/net/usb/r8152.c
    +++ b/drivers/net/usb/r8152.c
    @@ -1294,6 +1294,7 @@ static void intr_callback(struct urb *ur
    }
    } else {
    if (netif_carrier_ok(tp->netdev)) {
    + netif_stop_queue(tp->netdev);
    set_bit(RTL8152_LINK_CHG, &tp->flags);
    schedule_delayed_work(&tp->schedule, 0);
    }
    @@ -3167,6 +3168,9 @@ static void set_carrier(struct r8152 *tp
    napi_enable(&tp->napi);
    netif_wake_queue(netdev);
    netif_info(tp, link, netdev, "carrier on\n");
    + } else if (netif_queue_stopped(netdev) &&
    + skb_queue_len(&tp->tx_queue) < tp->tx_qlen) {
    + netif_wake_queue(netdev);
    }
    } else {
    if (netif_carrier_ok(netdev)) {
    @@ -3700,8 +3704,18 @@ static int rtl8152_resume(struct usb_int
    tp->rtl_ops.autosuspend_en(tp, false);
    napi_disable(&tp->napi);
    set_bit(WORK_ENABLE, &tp->flags);
    - if (netif_carrier_ok(tp->netdev))
    - rtl_start_rx(tp);
    +
    + if (netif_carrier_ok(tp->netdev)) {
    + if (rtl8152_get_speed(tp) & LINK_STATUS) {
    + rtl_start_rx(tp);
    + } else {
    + netif_carrier_off(tp->netdev);
    + tp->rtl_ops.disable(tp);
    + netif_info(tp, link, tp->netdev,
    + "linking down\n");
    + }
    + }
    +
    napi_enable(&tp->napi);
    clear_bit(SELECTIVE_SUSPEND, &tp->flags);
    smp_mb__after_atomic();

    \
     
     \ /
      Last update: 2017-12-22 11:25    [W:2.252 / U:0.360 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site