| @@ -148,12 +148,14 @@ static void stmmac_verify_args(void) · 147 unmodified lines |
| 148 | static void stmmac_disable_all_queues(struct stmmac_priv *priv) | 148 | static 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 |
| 164 | static void stmmac_enable_all_queues(struct stmmac_priv *priv) | 166 | static 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 index | 1847 | * @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 | */ |
| 1846 | static void stmmac_tx_clean(struct stmmac_priv *priv, u32 queue) | 1850 | static 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 reading | 1879 | /* 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 | |
| | 2032 | static 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 ISR | 2060 | * stmmac_dma_interrupt - DMA ISR |
| 2025 | * @priv: driver private structure | 2061 | * @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 | |
| | 2229 | static 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 pointer | 2238 | * @data: data pointer |
| @@ -2241,13 +2241,14 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv) · 2 unmodified lines |
| 2241 | */ | 2241 | */ |
| 2242 | static void stmmac_tx_timer(struct timer_list *t) | 2242 | static 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 | */ |
| 2261 | static void stmmac_init_tx_coalesce(struct stmmac_priv *priv) | 2262 | static 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 | |
| 2270 | static void stmmac_set_rings_length(struct stmmac_priv *priv) | 2277 | static 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 |
| 2592 | static int stmmac_open(struct net_device *dev) | 2599 | static 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); |
| 2693 | init_error: | 2703 | init_error: |
| 2694 | free_dma_desc_resources(priv); | 2704 | free_dma_desc_resources(priv); |
| @@ -2708,6 +2718,7 @@ dma_desc_error: · 13 unmodified lines |
| 2708 | static int stmmac_release(struct net_device *dev) | 2718 | static 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 first | 3157 | * 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 |
| 3319 | static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) | 3330 | static 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 | else | 3503 | 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 | */ |
| 3517 | static int stmmac_poll(struct napi_struct *napi, int budget) | 3529 | static 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); |
| 4374 | error_mdio_register: | 4403 | error_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 | } |
| 4380 | error_hw_init: | 4409 | error_hw_init: |
| 4381 | destroy_workqueue(priv->wq); | 4410 | destroy_workqueue(priv->wq); |