History

net: stmmac: Rework coalesce timer and fix multi-queue races

This follows David Miller advice and tries to fix coalesce timer in multi-queue scenarios. We are now using per-queue coalesce values and per-queue TX timer. Coalesce timer default values was changed to 1ms and the coalesce frames to 25. Tested in B2B setup between XGMAC2 and GMAC5.

Jose Abreu committed 8 years ago

Commit 8fce3331 parent 5211da94 files · +146 −106Browse files

Unified · Split

4 files
  1. drivers/net/ethernet/stmicro/stmmac/common.h +2 −2
  2. drivers/net/ethernet/stmicro/stmmac/stmmac.h +12 −2
  3. drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +131 −102
  4. include/linux/stmmac.h +1 −0
drivers/net/ethernet/stmicro/stmmac/common.h+2−2
@@ -258,10 +258,10 @@ struct stmmac_safety_stats { · 257 unmodified lines
258#define MAX_DMA_RIWT 0xff258#define MAX_DMA_RIWT 0xff
259#define MIN_DMA_RIWT 0x20259#define MIN_DMA_RIWT 0x20
260/* Tx coalesce parameters */260/* Tx coalesce parameters */
261#define STMMAC_COAL_TX_TIMER 40000261#define STMMAC_COAL_TX_TIMER 1000
262#define STMMAC_MAX_COAL_TX_TICK 100000262#define STMMAC_MAX_COAL_TX_TICK 100000
263#define STMMAC_TX_MAX_FRAMES 256263#define STMMAC_TX_MAX_FRAMES 256
264#define STMMAC_TX_FRAMES 64264#define STMMAC_TX_FRAMES 25
265 265
266/* Packets types */266/* Packets types */
267enum packets_types {267enum packets_types {
drivers/net/ethernet/stmicro/stmmac/stmmac.h+12−2
@@ -48,6 +48,8 @@ struct stmmac_tx_info { · 47 unmodified lines
48 48
49/* Frequently used values are kept adjacent for cache effect */49/* Frequently used values are kept adjacent for cache effect */
50struct stmmac_tx_queue {50struct stmmac_tx_queue {
51 u32 tx_count_frames;
52 struct timer_list txtimer;
51 u32 queue_index;53 u32 queue_index;
52 struct stmmac_priv *priv_data;54 struct stmmac_priv *priv_data;
53 struct dma_extended_desc *dma_etx ____cacheline_aligned_in_smp;55 struct dma_extended_desc *dma_etx ____cacheline_aligned_in_smp;
@@ -73,7 +75,14 @@ struct stmmac_rx_queue { · 19 unmodified lines
73 u32 rx_zeroc_thresh;75 u32 rx_zeroc_thresh;
74 dma_addr_t dma_rx_phy;76 dma_addr_t dma_rx_phy;
75 u32 rx_tail_addr;77 u32 rx_tail_addr;
78};
79
80struct stmmac_channel {
76 struct napi_struct napi ____cacheline_aligned_in_smp;81 struct napi_struct napi ____cacheline_aligned_in_smp;
82 struct stmmac_priv *priv_data;
83 u32 index;
84 int has_rx;
85 int has_tx;
77};86};
78 87
79struct stmmac_tc_entry {88struct stmmac_tc_entry {
@@ -109,14 +118,12 @@ struct stmmac_pps_cfg { · 29 unmodified lines
109 118
110struct stmmac_priv {119struct stmmac_priv {
111 /* Frequently used values are kept adjacent for cache effect */120 /* Frequently used values are kept adjacent for cache effect */
112 u32 tx_count_frames;
113 u32 tx_coal_frames;121 u32 tx_coal_frames;
114 u32 tx_coal_timer;122 u32 tx_coal_timer;
115 123
116 int tx_coalesce;124 int tx_coalesce;
117 int hwts_tx_en;125 int hwts_tx_en;
118 bool tx_path_in_lpi_mode;126 bool tx_path_in_lpi_mode;
119 struct timer_list txtimer;
120 bool tso;127 bool tso;
121 128
122 unsigned int dma_buf_sz;129 unsigned int dma_buf_sz;
@@ -137,6 +144,9 @@ struct stmmac_priv { · 14 unmodified lines
137 /* TX Queue */144 /* TX Queue */
138 struct stmmac_tx_queue tx_queue[MTL_MAX_TX_QUEUES];145 struct stmmac_tx_queue tx_queue[MTL_MAX_TX_QUEUES];
139 146
147 /* Generic channel for NAPI */
148 struct stmmac_channel channel[STMMAC_CH_MAX];
149
140 bool oldlink;150 bool oldlink;
141 int speed;151 int speed;
142 int oldduplex;152 int oldduplex;
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c+131−102
@@ -148,12 +148,14 @@ static void stmmac_verify_args(void) · 147 unmodified lines
148static void stmmac_disable_all_queues(struct stmmac_priv *priv)148static void stmmac_disable_all_queues(struct stmmac_priv *priv)
149{149{
150 u32 rx_queues_cnt = priv->plat->rx_queues_to_use;150 u32 rx_queues_cnt = priv->plat->rx_queues_to_use;
151 u32 tx_queues_cnt = priv->plat->tx_queues_to_use;
152 u32 maxq = max(rx_queues_cnt, tx_queues_cnt);
151 u32 queue;153 u32 queue;
152 154
153 for (queue = 0; queue < rx_queues_cnt; queue++) {155 for (queue = 0; queue < maxq; queue++) {
154 struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];156 struct stmmac_channel *ch = &priv->channel[queue];
155 157
156 napi_disable(&rx_q->napi);158 napi_disable(&ch->napi);
157 }159 }
158}160}
159 161
@@ -164,12 +166,14 @@ static void stmmac_disable_all_queues(struct stmmac_priv *priv) · 4 unmodified lines
164static void stmmac_enable_all_queues(struct stmmac_priv *priv)166static void stmmac_enable_all_queues(struct stmmac_priv *priv)
165{167{
166 u32 rx_queues_cnt = priv->plat->rx_queues_to_use;168 u32 rx_queues_cnt = priv->plat->rx_queues_to_use;
169 u32 tx_queues_cnt = priv->plat->tx_queues_to_use;
170 u32 maxq = max(rx_queues_cnt, tx_queues_cnt);
167 u32 queue;171 u32 queue;
168 172
169 for (queue = 0; queue < rx_queues_cnt; queue++) {173 for (queue = 0; queue < maxq; queue++) {
170 struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];174 struct stmmac_channel *ch = &priv->channel[queue];
171 175
172 napi_enable(&rx_q->napi);176 napi_enable(&ch->napi);
173 }177 }
174}178}
175 179
@@ -1843,18 +1847,18 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv) · 1667 unmodified lines
1843 * @queue: TX queue index1847 * @queue: TX queue index
1844 * Description: it reclaims the transmit resources after transmission completes.1848 * Description: it reclaims the transmit resources after transmission completes.
1845 */1849 */
1846static void stmmac_tx_clean(struct stmmac_priv *priv, u32 queue)1850static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue)
1847{1851{
1848 struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];1852 struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
1849 unsigned int bytes_compl = 0, pkts_compl = 0;1853 unsigned int bytes_compl = 0, pkts_compl = 0;
1850 unsigned int entry;1854 unsigned int entry, count = 0;
1851 1855
1852 netif_tx_lock(priv->dev);1856 __netif_tx_lock_bh(netdev_get_tx_queue(priv->dev, queue));
1853 1857
1854 priv->xstats.tx_clean++;1858 priv->xstats.tx_clean++;
1855 1859
1856 entry = tx_q->dirty_tx;1860 entry = tx_q->dirty_tx;
1857 while (entry != tx_q->cur_tx) {1861 while ((entry != tx_q->cur_tx) && (count < budget)) {
1858 struct sk_buff *skb = tx_q->tx_skbuff[entry];1862 struct sk_buff *skb = tx_q->tx_skbuff[entry];
1859 struct dma_desc *p;1863 struct dma_desc *p;
1860 int status;1864 int status;
@@ -1870,6 +1874,8 @@ static void stmmac_tx_clean(struct stmmac_priv *priv, u32 queue) · 9 unmodified lines
1870 if (unlikely(status & tx_dma_own))1874 if (unlikely(status & tx_dma_own))
1871 break;1875 break;
1872 1876
1877 count++;
1878
1873 /* Make sure descriptor fields are read after reading1879 /* Make sure descriptor fields are read after reading
1874 * the own bit.1880 * the own bit.
1875 */1881 */
@@ -1937,7 +1943,10 @@ static void stmmac_tx_clean(struct stmmac_priv *priv, u32 queue) · 61 unmodified lines
1937 stmmac_enable_eee_mode(priv);1943 stmmac_enable_eee_mode(priv);
1938 mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(eee_timer));1944 mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(eee_timer));
1939 }1945 }
1940 netif_tx_unlock(priv->dev);1946
1947 __netif_tx_unlock_bh(netdev_get_tx_queue(priv->dev, queue));
1948
1949 return count;
1941}1950}
1942 1951
1943/**1952/**
@@ -2020,6 +2029,33 @@ static bool stmmac_safety_feat_interrupt(struct stmmac_priv *priv) · 76 unmodified lines
2020 return false;2029 return false;
2021}2030}
2022 2031
2032static int stmmac_napi_check(struct stmmac_priv *priv, u32 chan)
2033{
2034 int status = stmmac_dma_interrupt_status(priv, priv->ioaddr,
2035 &priv->xstats, chan);
2036 struct stmmac_channel *ch = &priv->channel[chan];
2037 bool needs_work = false;
2038
2039 if ((status & handle_rx) && ch->has_rx) {
2040 needs_work = true;
2041 } else {
2042 status &= ~handle_rx;
2043 }
2044
2045 if ((status & handle_tx) && ch->has_tx) {
2046 needs_work = true;
2047 } else {
2048 status &= ~handle_tx;
2049 }
2050
2051 if (needs_work && napi_schedule_prep(&ch->napi)) {
2052 stmmac_disable_dma_irq(priv, priv->ioaddr, chan);
2053 __napi_schedule(&ch->napi);
2054 }
2055
2056 return status;
2057}
2058
2023/**2059/**
2024 * stmmac_dma_interrupt - DMA ISR2060 * stmmac_dma_interrupt - DMA ISR
2025 * @priv: driver private structure2061 * @priv: driver private structure
@@ -2034,57 +2070,14 @@ static void stmmac_dma_interrupt(struct stmmac_priv *priv) · 8 unmodified lines
2034 u32 channels_to_check = tx_channel_count > rx_channel_count ?2070 u32 channels_to_check = tx_channel_count > rx_channel_count ?
2035 tx_channel_count : rx_channel_count;2071 tx_channel_count : rx_channel_count;
2036 u32 chan;2072 u32 chan;
2037 bool poll_scheduled = false;
2038 int status[max_t(u32, MTL_MAX_TX_QUEUES, MTL_MAX_RX_QUEUES)];2073 int status[max_t(u32, MTL_MAX_TX_QUEUES, MTL_MAX_RX_QUEUES)];
2039 2074
2040 /* Make sure we never check beyond our status buffer. */2075 /* Make sure we never check beyond our status buffer. */
2041 if (WARN_ON_ONCE(channels_to_check > ARRAY_SIZE(status)))2076 if (WARN_ON_ONCE(channels_to_check > ARRAY_SIZE(status)))
2042 channels_to_check = ARRAY_SIZE(status);2077 channels_to_check = ARRAY_SIZE(status);
2043 2078
2044 /* Each DMA channel can be used for rx and tx simultaneously, yet
2045 * napi_struct is embedded in struct stmmac_rx_queue rather than in a
2046 * stmmac_channel struct.
2047 * Because of this, stmmac_poll currently checks (and possibly wakes)
2048 * all tx queues rather than just a single tx queue.
2049 */
2050 for (chan = 0; chan < channels_to_check; chan++)2079 for (chan = 0; chan < channels_to_check; chan++)
2051 status[chan] = stmmac_dma_interrupt_status(priv, priv->ioaddr,2080 status[chan] = stmmac_napi_check(priv, chan);
2052 &priv->xstats, chan);
2053
2054 for (chan = 0; chan < rx_channel_count; chan++) {
2055 if (likely(status[chan] & handle_rx)) {
2056 struct stmmac_rx_queue *rx_q = &priv->rx_queue[chan];
2057
2058 if (likely(napi_schedule_prep(&rx_q->napi))) {
2059 stmmac_disable_dma_irq(priv, priv->ioaddr, chan);
2060 __napi_schedule(&rx_q->napi);
2061 poll_scheduled = true;
2062 }
2063 }
2064 }
2065
2066 /* If we scheduled poll, we already know that tx queues will be checked.
2067 * If we didn't schedule poll, see if any DMA channel (used by tx) has a
2068 * completed transmission, if so, call stmmac_poll (once).
2069 */
2070 if (!poll_scheduled) {
2071 for (chan = 0; chan < tx_channel_count; chan++) {
2072 if (status[chan] & handle_tx) {
2073 /* It doesn't matter what rx queue we choose
2074 * here. We use 0 since it always exists.
2075 */
2076 struct stmmac_rx_queue *rx_q =
2077 &priv->rx_queue[0];
2078
2079 if (likely(napi_schedule_prep(&rx_q->napi))) {
2080 stmmac_disable_dma_irq(priv,
2081 priv->ioaddr, chan);
2082 __napi_schedule(&rx_q->napi);
2083 }
2084 break;
2085 }
2086 }
2087 }
2088 2081
2089 for (chan = 0; chan < tx_channel_count; chan++) {2082 for (chan = 0; chan < tx_channel_count; chan++) {
2090 if (unlikely(status[chan] & tx_hard_error_bump_tc)) {2083 if (unlikely(status[chan] & tx_hard_error_bump_tc)) {
@@ -2233,6 +2226,13 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv) · 142 unmodified lines
2233 return ret;2226 return ret;
2234}2227}
2235 2228
2229static void stmmac_tx_timer_arm(struct stmmac_priv *priv, u32 queue)
2230{
2231 struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
2232
2233 mod_timer(&tx_q->txtimer, STMMAC_COAL_TIMER(priv->tx_coal_timer));
2234}
2235
2236/**2236/**
2237 * stmmac_tx_timer - mitigation sw timer for tx.2237 * stmmac_tx_timer - mitigation sw timer for tx.
2238 * @data: data pointer2238 * @data: data pointer
@@ -2241,13 +2241,14 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv) · 2 unmodified lines
2241 */2241 */
2242static void stmmac_tx_timer(struct timer_list *t)2242static void stmmac_tx_timer(struct timer_list *t)
2243{2243{
2244 struct stmmac_priv *priv = from_timer(priv, t, txtimer);2244 struct stmmac_tx_queue *tx_q = from_timer(tx_q, t, txtimer);
2245 u32 tx_queues_count = priv->plat->tx_queues_to_use;2245 struct stmmac_priv *priv = tx_q->priv_data;
2246 u32 queue;2246 struct stmmac_channel *ch;
2247
2248 ch = &priv->channel[tx_q->queue_index];
2247 2249
2248 /* let's scan all the tx queues */2250 if (likely(napi_schedule_prep(&ch->napi)))
2249 for (queue = 0; queue < tx_queues_count; queue++)2251 __napi_schedule(&ch->napi);
2250 stmmac_tx_clean(priv, queue);
2251}2252}
2252 2253
2253/**2254/**
@@ -2260,11 +2261,17 @@ static void stmmac_tx_timer(struct timer_list *t) · 6 unmodified lines
2260 */2261 */
2261static void stmmac_init_tx_coalesce(struct stmmac_priv *priv)2262static void stmmac_init_tx_coalesce(struct stmmac_priv *priv)
2262{2263{
2264 u32 tx_channel_count = priv->plat->tx_queues_to_use;
2265 u32 chan;
2266
2263 priv->tx_coal_frames = STMMAC_TX_FRAMES;2267 priv->tx_coal_frames = STMMAC_TX_FRAMES;
2264 priv->tx_coal_timer = STMMAC_COAL_TX_TIMER;2268 priv->tx_coal_timer = STMMAC_COAL_TX_TIMER;
2265 timer_setup(&priv->txtimer, stmmac_tx_timer, 0);2269
2266 priv->txtimer.expires = STMMAC_COAL_TIMER(priv->tx_coal_timer);2270 for (chan = 0; chan < tx_channel_count; chan++) {
2267 add_timer(&priv->txtimer);2271 struct stmmac_tx_queue *tx_q = &priv->tx_queue[chan];
2272
2273 timer_setup(&tx_q->txtimer, stmmac_tx_timer, 0);
2274 }
2268}2275}
2269 2276
2270static void stmmac_set_rings_length(struct stmmac_priv *priv)2277static void stmmac_set_rings_length(struct stmmac_priv *priv)
@@ -2592,6 +2599,7 @@ static void stmmac_hw_teardown(struct net_device *dev) · 321 unmodified lines
2592static int stmmac_open(struct net_device *dev)2599static int stmmac_open(struct net_device *dev)
2593{2600{
2594 struct stmmac_priv *priv = netdev_priv(dev);2601 struct stmmac_priv *priv = netdev_priv(dev);
2602 u32 chan;
2595 int ret;2603 int ret;
2596 2604
2597 stmmac_check_ether_addr(priv);2605 stmmac_check_ether_addr(priv);
@@ -2688,7 +2696,9 @@ irq_error: · 90 unmodified lines
2688 if (dev->phydev)2696 if (dev->phydev)
2689 phy_stop(dev->phydev);2697 phy_stop(dev->phydev);
2690 2698
2691 del_timer_sync(&priv->txtimer);2699 for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++)
2700 del_timer_sync(&priv->tx_queue[chan].txtimer);
2701
2692 stmmac_hw_teardown(dev);2702 stmmac_hw_teardown(dev);
2693init_error:2703init_error:
2694 free_dma_desc_resources(priv);2704 free_dma_desc_resources(priv);
@@ -2708,6 +2718,7 @@ dma_desc_error: · 13 unmodified lines
2708static int stmmac_release(struct net_device *dev)2718static int stmmac_release(struct net_device *dev)
2709{2719{
2710 struct stmmac_priv *priv = netdev_priv(dev);2720 struct stmmac_priv *priv = netdev_priv(dev);
2721 u32 chan;
2711 2722
2712 if (priv->eee_enabled)2723 if (priv->eee_enabled)
2713 del_timer_sync(&priv->eee_ctrl_timer);2724 del_timer_sync(&priv->eee_ctrl_timer);
@@ -2722,7 +2733,8 @@ static int stmmac_release(struct net_device *dev) · 8 unmodified lines
2722 2733
2723 stmmac_disable_all_queues(priv);2734 stmmac_disable_all_queues(priv);
2724 2735
2725 del_timer_sync(&priv->txtimer);2736 for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++)
2737 del_timer_sync(&priv->tx_queue[chan].txtimer);
2726 2738
2727 /* Free the IRQ lines */2739 /* Free the IRQ lines */
2728 free_irq(dev->irq, dev);2740 free_irq(dev->irq, dev);
@@ -2936,14 +2948,13 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) · 207 unmodified lines
2936 priv->xstats.tx_tso_nfrags += nfrags;2948 priv->xstats.tx_tso_nfrags += nfrags;
2937 2949
2938 /* Manage tx mitigation */2950 /* Manage tx mitigation */
2939 priv->tx_count_frames += nfrags + 1;2951 tx_q->tx_count_frames += nfrags + 1;
2940 if (likely(priv->tx_coal_frames > priv->tx_count_frames)) {2952 if (priv->tx_coal_frames <= tx_q->tx_count_frames) {
2941 mod_timer(&priv->txtimer,
2942 STMMAC_COAL_TIMER(priv->tx_coal_timer));
2943 } else {
2944 priv->tx_count_frames = 0;
2945 stmmac_set_tx_ic(priv, desc);2953 stmmac_set_tx_ic(priv, desc);
2946 priv->xstats.tx_set_ic_bit++;2954 priv->xstats.tx_set_ic_bit++;
2955 tx_q->tx_count_frames = 0;
2956 } else {
2957 stmmac_tx_timer_arm(priv, queue);
2947 }2958 }
2948 2959
2949 skb_tx_timestamp(skb);2960 skb_tx_timestamp(skb);
@@ -3146,14 +3157,13 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) · 196 unmodified lines
3146 * This approach takes care about the fragments: desc is the first3157 * This approach takes care about the fragments: desc is the first
3147 * element in case of no SG.3158 * element in case of no SG.
3148 */3159 */
3149 priv->tx_count_frames += nfrags + 1;3160 tx_q->tx_count_frames += nfrags + 1;
3150 if (likely(priv->tx_coal_frames > priv->tx_count_frames)) {3161 if (priv->tx_coal_frames <= tx_q->tx_count_frames) {
3151 mod_timer(&priv->txtimer,
3152 STMMAC_COAL_TIMER(priv->tx_coal_timer));
3153 } else {
3154 priv->tx_count_frames = 0;
3155 stmmac_set_tx_ic(priv, desc);3162 stmmac_set_tx_ic(priv, desc);
3156 priv->xstats.tx_set_ic_bit++;3163 priv->xstats.tx_set_ic_bit++;
3164 tx_q->tx_count_frames = 0;
3165 } else {
3166 stmmac_tx_timer_arm(priv, queue);
3157 }3167 }
3158 3168
3159 skb_tx_timestamp(skb);3169 skb_tx_timestamp(skb);
@@ -3199,6 +3209,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) · 39 unmodified lines
3199 netdev_tx_sent_queue(netdev_get_tx_queue(dev, queue), skb->len);3209 netdev_tx_sent_queue(netdev_get_tx_queue(dev, queue), skb->len);
3200 3210
3201 stmmac_enable_dma_transmission(priv, priv->ioaddr);3211 stmmac_enable_dma_transmission(priv, priv->ioaddr);
3212
3202 stmmac_set_tx_tail_ptr(priv, priv->ioaddr, tx_q->tx_tail_addr, queue);3213 stmmac_set_tx_tail_ptr(priv, priv->ioaddr, tx_q->tx_tail_addr, queue);
3203 3214
3204 return NETDEV_TX_OK;3215 return NETDEV_TX_OK;
@@ -3319,6 +3330,7 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv, u32 queue) · 114 unmodified lines
3319static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)3330static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
3320{3331{
3321 struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];3332 struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
3333 struct stmmac_channel *ch = &priv->channel[queue];
3322 unsigned int entry = rx_q->cur_rx;3334 unsigned int entry = rx_q->cur_rx;
3323 int coe = priv->hw->rx_csum;3335 int coe = priv->hw->rx_csum;
3324 unsigned int next_entry;3336 unsigned int next_entry;
@@ -3491,7 +3503,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) · 166 unmodified lines
3491 else3503 else
3492 skb->ip_summed = CHECKSUM_UNNECESSARY;3504 skb->ip_summed = CHECKSUM_UNNECESSARY;
3493 3505
3494 napi_gro_receive(&rx_q->napi, skb);3506 napi_gro_receive(&ch->napi, skb);
3495 3507
3496 priv->dev->stats.rx_packets++;3508 priv->dev->stats.rx_packets++;
3497 priv->dev->stats.rx_bytes += frame_len;3509 priv->dev->stats.rx_bytes += frame_len;
@@ -3514,27 +3526,33 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) · 16 unmodified lines
3514 * Description :3526 * Description :
3515 * To look at the incoming frames and clear the tx resources.3527 * To look at the incoming frames and clear the tx resources.
3516 */3528 */
3517static int stmmac_poll(struct napi_struct *napi, int budget)3529static int stmmac_napi_poll(struct napi_struct *napi, int budget)
3518{3530{
3519 struct stmmac_rx_queue *rx_q =3531 struct stmmac_channel *ch =
3520 container_of(napi, struct stmmac_rx_queue, napi);3532 container_of(napi, struct stmmac_channel, napi);
3521 struct stmmac_priv *priv = rx_q->priv_data;3533 struct stmmac_priv *priv = ch->priv_data;
3522 u32 tx_count = priv->plat->tx_queues_to_use;3534 int work_done = 0, work_rem = budget;
3523 u32 chan = rx_q->queue_index;3535 u32 chan = ch->index;
3524 int work_done = 0;
3525 u32 queue;
3526 3536
3527 priv->xstats.napi_poll++;3537 priv->xstats.napi_poll++;
3528 3538
3529 /* check all the queues */3539 if (ch->has_tx) {
3530 for (queue = 0; queue < tx_count; queue++)3540 int done = stmmac_tx_clean(priv, work_rem, chan);
3531 stmmac_tx_clean(priv, queue);
3532 3541
3533 work_done = stmmac_rx(priv, budget, rx_q->queue_index);3542 work_done += done;
3534 if (work_done < budget) {3543 work_rem -= done;
3535 napi_complete_done(napi, work_done);3544 }
3536 stmmac_enable_dma_irq(priv, priv->ioaddr, chan);3545
3546 if (ch->has_rx) {
3547 int done = stmmac_rx(priv, work_rem, chan);
3548
3549 work_done += done;
3550 work_rem -= done;
3537 }3551 }
3552
3553 if (work_done < budget && napi_complete_done(napi, work_done))
3554 stmmac_enable_dma_irq(priv, priv->ioaddr, chan);
3555
3538 return work_done;3556 return work_done;
3539}3557}
3540 3558
@@ -4198,8 +4216,8 @@ int stmmac_dvr_probe(struct device *device, · 657 unmodified lines
4198{4216{
4199 struct net_device *ndev = NULL;4217 struct net_device *ndev = NULL;
4200 struct stmmac_priv *priv;4218 struct stmmac_priv *priv;
4219 u32 queue, maxq;
4201 int ret = 0;4220 int ret = 0;
4202 u32 queue;
4203 4221
4204 ndev = alloc_etherdev_mqs(sizeof(struct stmmac_priv),4222 ndev = alloc_etherdev_mqs(sizeof(struct stmmac_priv),
4205 MTL_MAX_TX_QUEUES,4223 MTL_MAX_TX_QUEUES,
@@ -4322,11 +4340,22 @@ int stmmac_dvr_probe(struct device *device, · 116 unmodified lines
4322 "Enable RX Mitigation via HW Watchdog Timer\n");4340 "Enable RX Mitigation via HW Watchdog Timer\n");
4323 }4341 }
4324 4342
4325 for (queue = 0; queue < priv->plat->rx_queues_to_use; queue++) {4343 /* Setup channels NAPI */
4326 struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];4344 maxq = max(priv->plat->rx_queues_to_use, priv->plat->tx_queues_to_use);
4327 4345
4328 netif_napi_add(ndev, &rx_q->napi, stmmac_poll,4346 for (queue = 0; queue < maxq; queue++) {
4329 (8 * priv->plat->rx_queues_to_use));4347 struct stmmac_channel *ch = &priv->channel[queue];
4348
4349 ch->priv_data = priv;
4350 ch->index = queue;
4351
4352 if (queue < priv->plat->rx_queues_to_use)
4353 ch->has_rx = true;
4354 if (queue < priv->plat->tx_queues_to_use)
4355 ch->has_tx = true;
4356
4357 netif_napi_add(ndev, &ch->napi, stmmac_napi_poll,
4358 NAPI_POLL_WEIGHT);
4330 }4359 }
4331 4360
4332 mutex_init(&priv->lock);4361 mutex_init(&priv->lock);
@@ -4372,10 +4401,10 @@ error_netdev_register: · 39 unmodified lines
4372 priv->hw->pcs != STMMAC_PCS_RTBI)4401 priv->hw->pcs != STMMAC_PCS_RTBI)
4373 stmmac_mdio_unregister(ndev);4402 stmmac_mdio_unregister(ndev);
4374error_mdio_register:4403error_mdio_register:
4375 for (queue = 0; queue < priv->plat->rx_queues_to_use; queue++) {4404 for (queue = 0; queue < maxq; queue++) {
4376 struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];4405 struct stmmac_channel *ch = &priv->channel[queue];
4377 4406
4378 netif_napi_del(&rx_q->napi);4407 netif_napi_del(&ch->napi);
4379 }4408 }
4380error_hw_init:4409error_hw_init:
4381 destroy_workqueue(priv->wq);4410 destroy_workqueue(priv->wq);
include/linux/stmmac.h+1−0
@@ -30,6 +30,7 @@ · 29 unmodified lines
30 30
31#define MTL_MAX_RX_QUEUES 831#define MTL_MAX_RX_QUEUES 8
32#define MTL_MAX_TX_QUEUES 832#define MTL_MAX_TX_QUEUES 8
33#define STMMAC_CH_MAX 8
33 34
34#define STMMAC_RX_COE_NONE 035#define STMMAC_RX_COE_NONE 0
35#define STMMAC_RX_COE_TYPE1 136#define STMMAC_RX_COE_TYPE1 1