From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752053Ab3KSDZ7 (ORCPT ); Mon, 18 Nov 2013 22:25:59 -0500 Received: from rtits2.realtek.com ([60.250.210.242]:59026 "EHLO rtits2.realtek.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751726Ab3KSDZ1 (ORCPT ); Mon, 18 Nov 2013 22:25:27 -0500 X-SpamFilter-By: BOX Solutions SpamTrap 5.37 with qID rAJ3POao016317, This message is accepted by code: ctloc85258 From: Hayes Wang To: CC: , , , Hayes Wang Subject: [PATCH net v4 3/4] r8152: support stopping/waking tx queue Date: Tue, 19 Nov 2013 11:25:10 +0800 Message-ID: <1384831511-1625-4-git-send-email-hayeswang@realtek.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1384831511-1625-1-git-send-email-hayeswang@realtek.com> References: <1384502279-9959-1-git-send-email-hayeswang@realtek.com> <1384831511-1625-1-git-send-email-hayeswang@realtek.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [172.21.71.44] Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The maximum packet number which a tx aggregation buffer could contain is the buffer size / (packet size + descriptor size). If the tx buffer is empty and the tx queue length is more than the maximum value which is defined above, stop the tx queue. Wake the tx queue after any queued packet is filled in a available tx buffer. Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 8a786b6..0ac2b53 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -365,6 +365,7 @@ struct r8152 { struct mii_if_info mii; int intr_interval; u32 msg_enable; + u32 tx_qlen; u16 ocp_base; u8 *intr_buff; u8 version; @@ -1173,6 +1174,9 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg) remain = rx_buf_sz - (int)(tx_agg_align(tx_data) - agg->head); } + if (netif_queue_stopped(tp->netdev)) + netif_wake_queue(tp->netdev); + usb_fill_bulk_urb(agg->urb, tp->udev, usb_sndbulkpipe(tp->udev, 2), agg->head, (int)(tx_data - (u8 *)agg->head), (usb_complete_t)write_bulk_callback, agg); @@ -1393,6 +1397,10 @@ 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) + netif_stop_queue(netdev); + if (!list_empty(&tp->tx_free)) tasklet_schedule(&tp->tl); @@ -1423,6 +1431,14 @@ static void rtl8152_nic_reset(struct r8152 *tp) } } +static void set_tx_qlen(struct r8152 *tp) +{ + struct net_device *netdev = tp->netdev; + + tp->tx_qlen = rx_buf_sz / (netdev->mtu + VLAN_ETH_HLEN + VLAN_HLEN + + sizeof(struct tx_desc)); +} + static inline u8 rtl8152_get_speed(struct r8152 *tp) { return ocp_read_byte(tp, MCU_TYPE_PLA, PLA_PHYSTATUS); @@ -1434,6 +1450,7 @@ static int rtl8152_enable(struct r8152 *tp) int i, ret; u8 speed; + set_tx_qlen(tp); speed = rtl8152_get_speed(tp); if (speed & _10bps) { ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR); -- 1.8.3.1