diff options
author | hayeswang <hayeswang@realtek.com> | 2014-03-07 11:04:36 +0800 |
---|---|---|
committer | Seema Khowala <seemaj@nvidia.com> | 2014-04-23 14:07:36 -0700 |
commit | 2e3b6f7ec3b202ef9418e83365559fe6a6fff87e (patch) | |
tree | dad39282962780b2359350c5f8a4c394c8dec12a /drivers/net | |
parent | 8fec9e0be6e073567f39440b5ba0bca51a794996 (diff) |
r8152: up the priority of the transmission
move the tx_bottom() from delayed_work to tasklet. It makes the rx
and tx balanced. If the device is in runtime suspend when getting
the tx packet, wakeup the device before trasmitting.
Change-Id: Ib200ea8e98de1425d2e95185e75766b763619623
Signed-off-by: Hayes Wang <hayeswang@realtek.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Aly Hirani <ahirani@nvidia.com>
Reviewed-on: http://git-master/r/390294
(cherry picked from commit 46737054c934399d0e7f1ea9723620e250f74e9a)
Reviewed-on: http://git-master/r/396896
Reviewed-by: Preetham Chandru <pchandru@nvidia.com>
Tested-by: Preetham Chandru <pchandru@nvidia.com>
Reviewed-by: Bitan Biswas <bbiswas@nvidia.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/usb/r8152.c | 45 |
1 files changed, 27 insertions, 18 deletions
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 647c2ae4382a..b9811a971ff7 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -448,6 +448,7 @@ enum rtl8152_flags { RTL8152_LINK_CHG, SELECTIVE_SUSPEND, PHY_RESET, + SCHEDULE_TASKLET, }; /* Define these values to match your device */ @@ -1069,7 +1070,7 @@ static void write_bulk_callback(struct urb *urb) return; if (!skb_queue_empty(&tp->tx_queue)) - schedule_delayed_work(&tp->schedule, 0); + tasklet_schedule(&tp->tl); } static void intr_callback(struct urb *urb) @@ -1333,9 +1334,9 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg) u8 *tx_data; __skb_queue_head_init(&skb_head); - spin_lock_bh(&tx_queue->lock); + spin_lock(&tx_queue->lock); skb_queue_splice_init(tx_queue, &skb_head); - spin_unlock_bh(&tx_queue->lock); + spin_unlock(&tx_queue->lock); tx_data = agg->head; agg->skb_num = agg->skb_len = 0; @@ -1372,20 +1373,20 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg) } if (!skb_queue_empty(&skb_head)) { - spin_lock_bh(&tx_queue->lock); + spin_lock(&tx_queue->lock); skb_queue_splice(&skb_head, tx_queue); - spin_unlock_bh(&tx_queue->lock); + spin_unlock(&tx_queue->lock); } - netif_tx_lock_bh(tp->netdev); + netif_tx_lock(tp->netdev); if (netif_queue_stopped(tp->netdev) && skb_queue_len(&tp->tx_queue) < tp->tx_qlen) netif_wake_queue(tp->netdev); - netif_tx_unlock_bh(tp->netdev); + netif_tx_unlock(tp->netdev); - ret = usb_autopm_get_interface(tp->intf); + ret = usb_autopm_get_interface_async(tp->intf); if (ret < 0) goto out_tx_fill; @@ -1393,9 +1394,9 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg) agg->head, (int)(tx_data - (u8 *)agg->head), (usb_complete_t)write_bulk_callback, agg); - ret = usb_submit_urb(agg->urb, GFP_KERNEL); + ret = usb_submit_urb(agg->urb, GFP_ATOMIC); if (ret < 0) - usb_autopm_put_interface(tp->intf); + usb_autopm_put_interface_async(tp->intf); out_tx_fill: return ret; @@ -1533,6 +1534,7 @@ static void bottom_half(unsigned long data) return; rx_bottom(tp); + tx_bottom(tp); } static @@ -1628,7 +1630,7 @@ static void _rtl8152_set_rx_mode(struct net_device *netdev) } static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb, - struct net_device *netdev) + struct net_device *netdev) { struct r8152 *tp = netdev_priv(netdev); @@ -1636,13 +1638,17 @@ static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb, skb_queue_tail(&tp->tx_queue, skb); - if (list_empty(&tp->tx_free) && - skb_queue_len(&tp->tx_queue) > tp->tx_qlen) + if (!list_empty(&tp->tx_free)) { + if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) { + set_bit(SCHEDULE_TASKLET, &tp->flags); + schedule_delayed_work(&tp->schedule, 0); + } else { + usb_mark_last_busy(tp->udev); + tasklet_schedule(&tp->tl); + } + } else if (skb_queue_len(&tp->tx_queue) > tp->tx_qlen) netif_stop_queue(netdev); - if (!list_empty(&tp->tx_free)) - schedule_delayed_work(&tp->schedule, 0); - return NETDEV_TX_OK; } @@ -2521,8 +2527,11 @@ static void rtl_work_func_t(struct work_struct *work) if (test_bit(RTL8152_SET_RX_MODE, &tp->flags)) _rtl8152_set_rx_mode(tp->netdev); - if (tp->speed & LINK_STATUS) - tx_bottom(tp); + if (test_bit(SCHEDULE_TASKLET, &tp->flags) && + (tp->speed & LINK_STATUS)) { + clear_bit(SCHEDULE_TASKLET, &tp->flags); + tasklet_schedule(&tp->tl); + } if (test_bit(PHY_RESET, &tp->flags)) rtl_phy_reset(tp); |