diff options
Diffstat (limited to 'drivers/net/mv643xx_eth.c')
-rw-r--r-- | drivers/net/mv643xx_eth.c | 65 |
1 files changed, 35 insertions, 30 deletions
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index b3185bf2c158..6bb5af35eda6 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c | |||
@@ -393,12 +393,12 @@ struct mv643xx_eth_private { | |||
393 | struct work_struct tx_timeout_task; | 393 | struct work_struct tx_timeout_task; |
394 | 394 | ||
395 | struct napi_struct napi; | 395 | struct napi_struct napi; |
396 | u8 oom; | ||
396 | u8 work_link; | 397 | u8 work_link; |
397 | u8 work_tx; | 398 | u8 work_tx; |
398 | u8 work_tx_end; | 399 | u8 work_tx_end; |
399 | u8 work_rx; | 400 | u8 work_rx; |
400 | u8 work_rx_refill; | 401 | u8 work_rx_refill; |
401 | u8 work_rx_oom; | ||
402 | 402 | ||
403 | int skb_size; | 403 | int skb_size; |
404 | struct sk_buff_head rx_recycle; | 404 | struct sk_buff_head rx_recycle; |
@@ -569,7 +569,7 @@ static int rxq_process(struct rx_queue *rxq, int budget) | |||
569 | if (rxq->rx_curr_desc == rxq->rx_ring_size) | 569 | if (rxq->rx_curr_desc == rxq->rx_ring_size) |
570 | rxq->rx_curr_desc = 0; | 570 | rxq->rx_curr_desc = 0; |
571 | 571 | ||
572 | dma_unmap_single(NULL, rx_desc->buf_ptr, | 572 | dma_unmap_single(mp->dev->dev.parent, rx_desc->buf_ptr, |
573 | rx_desc->buf_size, DMA_FROM_DEVICE); | 573 | rx_desc->buf_size, DMA_FROM_DEVICE); |
574 | rxq->rx_desc_count--; | 574 | rxq->rx_desc_count--; |
575 | rx++; | 575 | rx++; |
@@ -661,7 +661,7 @@ static int rxq_refill(struct rx_queue *rxq, int budget) | |||
661 | dma_get_cache_alignment() - 1); | 661 | dma_get_cache_alignment() - 1); |
662 | 662 | ||
663 | if (skb == NULL) { | 663 | if (skb == NULL) { |
664 | mp->work_rx_oom |= 1 << rxq->index; | 664 | mp->oom = 1; |
665 | goto oom; | 665 | goto oom; |
666 | } | 666 | } |
667 | 667 | ||
@@ -678,8 +678,9 @@ static int rxq_refill(struct rx_queue *rxq, int budget) | |||
678 | 678 | ||
679 | rx_desc = rxq->rx_desc_area + rx; | 679 | rx_desc = rxq->rx_desc_area + rx; |
680 | 680 | ||
681 | rx_desc->buf_ptr = dma_map_single(NULL, skb->data, | 681 | rx_desc->buf_ptr = dma_map_single(mp->dev->dev.parent, |
682 | mp->skb_size, DMA_FROM_DEVICE); | 682 | skb->data, mp->skb_size, |
683 | DMA_FROM_DEVICE); | ||
683 | rx_desc->buf_size = mp->skb_size; | 684 | rx_desc->buf_size = mp->skb_size; |
684 | rxq->rx_skb[rx] = skb; | 685 | rxq->rx_skb[rx] = skb; |
685 | wmb(); | 686 | wmb(); |
@@ -718,6 +719,7 @@ static inline unsigned int has_tiny_unaligned_frags(struct sk_buff *skb) | |||
718 | 719 | ||
719 | static void txq_submit_frag_skb(struct tx_queue *txq, struct sk_buff *skb) | 720 | static void txq_submit_frag_skb(struct tx_queue *txq, struct sk_buff *skb) |
720 | { | 721 | { |
722 | struct mv643xx_eth_private *mp = txq_to_mp(txq); | ||
721 | int nr_frags = skb_shinfo(skb)->nr_frags; | 723 | int nr_frags = skb_shinfo(skb)->nr_frags; |
722 | int frag; | 724 | int frag; |
723 | 725 | ||
@@ -746,10 +748,10 @@ static void txq_submit_frag_skb(struct tx_queue *txq, struct sk_buff *skb) | |||
746 | 748 | ||
747 | desc->l4i_chk = 0; | 749 | desc->l4i_chk = 0; |
748 | desc->byte_cnt = this_frag->size; | 750 | desc->byte_cnt = this_frag->size; |
749 | desc->buf_ptr = dma_map_page(NULL, this_frag->page, | 751 | desc->buf_ptr = dma_map_page(mp->dev->dev.parent, |
750 | this_frag->page_offset, | 752 | this_frag->page, |
751 | this_frag->size, | 753 | this_frag->page_offset, |
752 | DMA_TO_DEVICE); | 754 | this_frag->size, DMA_TO_DEVICE); |
753 | } | 755 | } |
754 | } | 756 | } |
755 | 757 | ||
@@ -826,7 +828,8 @@ no_csum: | |||
826 | 828 | ||
827 | desc->l4i_chk = l4i_chk; | 829 | desc->l4i_chk = l4i_chk; |
828 | desc->byte_cnt = length; | 830 | desc->byte_cnt = length; |
829 | desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE); | 831 | desc->buf_ptr = dma_map_single(mp->dev->dev.parent, skb->data, |
832 | length, DMA_TO_DEVICE); | ||
830 | 833 | ||
831 | __skb_queue_tail(&txq->tx_skb, skb); | 834 | __skb_queue_tail(&txq->tx_skb, skb); |
832 | 835 | ||
@@ -956,10 +959,10 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force) | |||
956 | } | 959 | } |
957 | 960 | ||
958 | if (cmd_sts & TX_FIRST_DESC) { | 961 | if (cmd_sts & TX_FIRST_DESC) { |
959 | dma_unmap_single(NULL, desc->buf_ptr, | 962 | dma_unmap_single(mp->dev->dev.parent, desc->buf_ptr, |
960 | desc->byte_cnt, DMA_TO_DEVICE); | 963 | desc->byte_cnt, DMA_TO_DEVICE); |
961 | } else { | 964 | } else { |
962 | dma_unmap_page(NULL, desc->buf_ptr, | 965 | dma_unmap_page(mp->dev->dev.parent, desc->buf_ptr, |
963 | desc->byte_cnt, DMA_TO_DEVICE); | 966 | desc->byte_cnt, DMA_TO_DEVICE); |
964 | } | 967 | } |
965 | 968 | ||
@@ -1255,7 +1258,6 @@ static void mib_counters_update(struct mv643xx_eth_private *mp) | |||
1255 | 1258 | ||
1256 | spin_lock_bh(&mp->mib_counters_lock); | 1259 | spin_lock_bh(&mp->mib_counters_lock); |
1257 | p->good_octets_received += mib_read(mp, 0x00); | 1260 | p->good_octets_received += mib_read(mp, 0x00); |
1258 | p->good_octets_received += (u64)mib_read(mp, 0x04) << 32; | ||
1259 | p->bad_octets_received += mib_read(mp, 0x08); | 1261 | p->bad_octets_received += mib_read(mp, 0x08); |
1260 | p->internal_mac_transmit_err += mib_read(mp, 0x0c); | 1262 | p->internal_mac_transmit_err += mib_read(mp, 0x0c); |
1261 | p->good_frames_received += mib_read(mp, 0x10); | 1263 | p->good_frames_received += mib_read(mp, 0x10); |
@@ -1269,7 +1271,6 @@ static void mib_counters_update(struct mv643xx_eth_private *mp) | |||
1269 | p->frames_512_to_1023_octets += mib_read(mp, 0x30); | 1271 | p->frames_512_to_1023_octets += mib_read(mp, 0x30); |
1270 | p->frames_1024_to_max_octets += mib_read(mp, 0x34); | 1272 | p->frames_1024_to_max_octets += mib_read(mp, 0x34); |
1271 | p->good_octets_sent += mib_read(mp, 0x38); | 1273 | p->good_octets_sent += mib_read(mp, 0x38); |
1272 | p->good_octets_sent += (u64)mib_read(mp, 0x3c) << 32; | ||
1273 | p->good_frames_sent += mib_read(mp, 0x40); | 1274 | p->good_frames_sent += mib_read(mp, 0x40); |
1274 | p->excessive_collision += mib_read(mp, 0x44); | 1275 | p->excessive_collision += mib_read(mp, 0x44); |
1275 | p->multicast_frames_sent += mib_read(mp, 0x48); | 1276 | p->multicast_frames_sent += mib_read(mp, 0x48); |
@@ -1896,9 +1897,9 @@ static int rxq_init(struct mv643xx_eth_private *mp, int index) | |||
1896 | mp->rx_desc_sram_size); | 1897 | mp->rx_desc_sram_size); |
1897 | rxq->rx_desc_dma = mp->rx_desc_sram_addr; | 1898 | rxq->rx_desc_dma = mp->rx_desc_sram_addr; |
1898 | } else { | 1899 | } else { |
1899 | rxq->rx_desc_area = dma_alloc_coherent(NULL, size, | 1900 | rxq->rx_desc_area = dma_alloc_coherent(mp->dev->dev.parent, |
1900 | &rxq->rx_desc_dma, | 1901 | size, &rxq->rx_desc_dma, |
1901 | GFP_KERNEL); | 1902 | GFP_KERNEL); |
1902 | } | 1903 | } |
1903 | 1904 | ||
1904 | if (rxq->rx_desc_area == NULL) { | 1905 | if (rxq->rx_desc_area == NULL) { |
@@ -1949,7 +1950,7 @@ out_free: | |||
1949 | if (index == 0 && size <= mp->rx_desc_sram_size) | 1950 | if (index == 0 && size <= mp->rx_desc_sram_size) |
1950 | iounmap(rxq->rx_desc_area); | 1951 | iounmap(rxq->rx_desc_area); |
1951 | else | 1952 | else |
1952 | dma_free_coherent(NULL, size, | 1953 | dma_free_coherent(mp->dev->dev.parent, size, |
1953 | rxq->rx_desc_area, | 1954 | rxq->rx_desc_area, |
1954 | rxq->rx_desc_dma); | 1955 | rxq->rx_desc_dma); |
1955 | 1956 | ||
@@ -1981,7 +1982,7 @@ static void rxq_deinit(struct rx_queue *rxq) | |||
1981 | rxq->rx_desc_area_size <= mp->rx_desc_sram_size) | 1982 | rxq->rx_desc_area_size <= mp->rx_desc_sram_size) |
1982 | iounmap(rxq->rx_desc_area); | 1983 | iounmap(rxq->rx_desc_area); |
1983 | else | 1984 | else |
1984 | dma_free_coherent(NULL, rxq->rx_desc_area_size, | 1985 | dma_free_coherent(mp->dev->dev.parent, rxq->rx_desc_area_size, |
1985 | rxq->rx_desc_area, rxq->rx_desc_dma); | 1986 | rxq->rx_desc_area, rxq->rx_desc_dma); |
1986 | 1987 | ||
1987 | kfree(rxq->rx_skb); | 1988 | kfree(rxq->rx_skb); |
@@ -2009,9 +2010,9 @@ static int txq_init(struct mv643xx_eth_private *mp, int index) | |||
2009 | mp->tx_desc_sram_size); | 2010 | mp->tx_desc_sram_size); |
2010 | txq->tx_desc_dma = mp->tx_desc_sram_addr; | 2011 | txq->tx_desc_dma = mp->tx_desc_sram_addr; |
2011 | } else { | 2012 | } else { |
2012 | txq->tx_desc_area = dma_alloc_coherent(NULL, size, | 2013 | txq->tx_desc_area = dma_alloc_coherent(mp->dev->dev.parent, |
2013 | &txq->tx_desc_dma, | 2014 | size, &txq->tx_desc_dma, |
2014 | GFP_KERNEL); | 2015 | GFP_KERNEL); |
2015 | } | 2016 | } |
2016 | 2017 | ||
2017 | if (txq->tx_desc_area == NULL) { | 2018 | if (txq->tx_desc_area == NULL) { |
@@ -2055,7 +2056,7 @@ static void txq_deinit(struct tx_queue *txq) | |||
2055 | txq->tx_desc_area_size <= mp->tx_desc_sram_size) | 2056 | txq->tx_desc_area_size <= mp->tx_desc_sram_size) |
2056 | iounmap(txq->tx_desc_area); | 2057 | iounmap(txq->tx_desc_area); |
2057 | else | 2058 | else |
2058 | dma_free_coherent(NULL, txq->tx_desc_area_size, | 2059 | dma_free_coherent(mp->dev->dev.parent, txq->tx_desc_area_size, |
2059 | txq->tx_desc_area, txq->tx_desc_dma); | 2060 | txq->tx_desc_area, txq->tx_desc_dma); |
2060 | } | 2061 | } |
2061 | 2062 | ||
@@ -2167,8 +2168,10 @@ static int mv643xx_eth_poll(struct napi_struct *napi, int budget) | |||
2167 | 2168 | ||
2168 | mp = container_of(napi, struct mv643xx_eth_private, napi); | 2169 | mp = container_of(napi, struct mv643xx_eth_private, napi); |
2169 | 2170 | ||
2170 | mp->work_rx_refill |= mp->work_rx_oom; | 2171 | if (unlikely(mp->oom)) { |
2171 | mp->work_rx_oom = 0; | 2172 | mp->oom = 0; |
2173 | del_timer(&mp->rx_oom); | ||
2174 | } | ||
2172 | 2175 | ||
2173 | work_done = 0; | 2176 | work_done = 0; |
2174 | while (work_done < budget) { | 2177 | while (work_done < budget) { |
@@ -2182,8 +2185,10 @@ static int mv643xx_eth_poll(struct napi_struct *napi, int budget) | |||
2182 | continue; | 2185 | continue; |
2183 | } | 2186 | } |
2184 | 2187 | ||
2185 | queue_mask = mp->work_tx | mp->work_tx_end | | 2188 | queue_mask = mp->work_tx | mp->work_tx_end | mp->work_rx; |
2186 | mp->work_rx | mp->work_rx_refill; | 2189 | if (likely(!mp->oom)) |
2190 | queue_mask |= mp->work_rx_refill; | ||
2191 | |||
2187 | if (!queue_mask) { | 2192 | if (!queue_mask) { |
2188 | if (mv643xx_eth_collect_events(mp)) | 2193 | if (mv643xx_eth_collect_events(mp)) |
2189 | continue; | 2194 | continue; |
@@ -2204,7 +2209,7 @@ static int mv643xx_eth_poll(struct napi_struct *napi, int budget) | |||
2204 | txq_maybe_wake(mp->txq + queue); | 2209 | txq_maybe_wake(mp->txq + queue); |
2205 | } else if (mp->work_rx & queue_mask) { | 2210 | } else if (mp->work_rx & queue_mask) { |
2206 | work_done += rxq_process(mp->rxq + queue, work_tbd); | 2211 | work_done += rxq_process(mp->rxq + queue, work_tbd); |
2207 | } else if (mp->work_rx_refill & queue_mask) { | 2212 | } else if (!mp->oom && (mp->work_rx_refill & queue_mask)) { |
2208 | work_done += rxq_refill(mp->rxq + queue, work_tbd); | 2213 | work_done += rxq_refill(mp->rxq + queue, work_tbd); |
2209 | } else { | 2214 | } else { |
2210 | BUG(); | 2215 | BUG(); |
@@ -2212,7 +2217,7 @@ static int mv643xx_eth_poll(struct napi_struct *napi, int budget) | |||
2212 | } | 2217 | } |
2213 | 2218 | ||
2214 | if (work_done < budget) { | 2219 | if (work_done < budget) { |
2215 | if (mp->work_rx_oom) | 2220 | if (mp->oom) |
2216 | mod_timer(&mp->rx_oom, jiffies + (HZ / 10)); | 2221 | mod_timer(&mp->rx_oom, jiffies + (HZ / 10)); |
2217 | napi_complete(napi); | 2222 | napi_complete(napi); |
2218 | wrlp(mp, INT_MASK, INT_TX_END | INT_RX | INT_EXT); | 2223 | wrlp(mp, INT_MASK, INT_TX_END | INT_RX | INT_EXT); |
@@ -2372,7 +2377,7 @@ static int mv643xx_eth_open(struct net_device *dev) | |||
2372 | rxq_refill(mp->rxq + i, INT_MAX); | 2377 | rxq_refill(mp->rxq + i, INT_MAX); |
2373 | } | 2378 | } |
2374 | 2379 | ||
2375 | if (mp->work_rx_oom) { | 2380 | if (mp->oom) { |
2376 | mp->rx_oom.expires = jiffies + (HZ / 10); | 2381 | mp->rx_oom.expires = jiffies + (HZ / 10); |
2377 | add_timer(&mp->rx_oom); | 2382 | add_timer(&mp->rx_oom); |
2378 | } | 2383 | } |