077-04-bgmac-simplify-tx-ring-index-handling.patch 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. From: Felix Fietkau <nbd@openwrt.org>
  2. Date: Sun, 12 Apr 2015 09:58:56 +0200
  3. Subject: [PATCH] bgmac: simplify tx ring index handling
  4. Keep incrementing ring->start and ring->end instead of pointing it to
  5. the actual ring slot entry. This simplifies the calculation of the
  6. number of free slots.
  7. Signed-off-by: Felix Fietkau <nbd@openwrt.org>
  8. ---
  9. --- a/drivers/net/ethernet/broadcom/bgmac.c
  10. +++ b/drivers/net/ethernet/broadcom/bgmac.c
  11. @@ -142,11 +142,10 @@ static netdev_tx_t bgmac_dma_tx_add(stru
  12. {
  13. struct device *dma_dev = bgmac->core->dma_dev;
  14. struct net_device *net_dev = bgmac->net_dev;
  15. - struct bgmac_slot_info *slot = &ring->slots[ring->end];
  16. - int free_slots;
  17. + int index = ring->end % BGMAC_TX_RING_SLOTS;
  18. + struct bgmac_slot_info *slot = &ring->slots[index];
  19. int nr_frags;
  20. u32 flags;
  21. - int index = ring->end;
  22. int i;
  23. if (skb->len > BGMAC_DESC_CTL1_LEN) {
  24. @@ -159,12 +158,10 @@ static netdev_tx_t bgmac_dma_tx_add(stru
  25. nr_frags = skb_shinfo(skb)->nr_frags;
  26. - if (ring->start <= ring->end)
  27. - free_slots = ring->start - ring->end + BGMAC_TX_RING_SLOTS;
  28. - else
  29. - free_slots = ring->start - ring->end;
  30. -
  31. - if (free_slots <= nr_frags + 1) {
  32. + /* ring->end - ring->start will return the number of valid slots,
  33. + * even when ring->end overflows
  34. + */
  35. + if (ring->end - ring->start + nr_frags + 1 >= BGMAC_TX_RING_SLOTS) {
  36. bgmac_err(bgmac, "TX ring is full, queue should be stopped!\n");
  37. netif_stop_queue(net_dev);
  38. return NETDEV_TX_BUSY;
  39. @@ -200,7 +197,7 @@ static netdev_tx_t bgmac_dma_tx_add(stru
  40. }
  41. slot->skb = skb;
  42. -
  43. + ring->end += nr_frags + 1;
  44. netdev_sent_queue(net_dev, skb->len);
  45. wmb();
  46. @@ -208,13 +205,12 @@ static netdev_tx_t bgmac_dma_tx_add(stru
  47. /* Increase ring->end to point empty slot. We tell hardware the first
  48. * slot it should *not* read.
  49. */
  50. - ring->end = (index + 1) % BGMAC_TX_RING_SLOTS;
  51. bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_INDEX,
  52. ring->index_base +
  53. - ring->end * sizeof(struct bgmac_dma_desc));
  54. + (ring->end % BGMAC_TX_RING_SLOTS) *
  55. + sizeof(struct bgmac_dma_desc));
  56. - free_slots -= nr_frags + 1;
  57. - if (free_slots < 8)
  58. + if (ring->end - ring->start >= BGMAC_TX_RING_SLOTS - 8)
  59. netif_stop_queue(net_dev);
  60. return NETDEV_TX_OK;
  61. @@ -256,17 +252,17 @@ static void bgmac_dma_tx_free(struct bgm
  62. empty_slot &= BGMAC_DMA_TX_STATDPTR;
  63. empty_slot /= sizeof(struct bgmac_dma_desc);
  64. - while (ring->start != empty_slot) {
  65. - struct bgmac_slot_info *slot = &ring->slots[ring->start];
  66. - u32 ctl1 = le32_to_cpu(ring->cpu_base[ring->start].ctl1);
  67. - int len = ctl1 & BGMAC_DESC_CTL1_LEN;
  68. + while (ring->start != ring->end) {
  69. + int slot_idx = ring->start % BGMAC_TX_RING_SLOTS;
  70. + struct bgmac_slot_info *slot = &ring->slots[slot_idx];
  71. + u32 ctl1;
  72. + int len;
  73. - if (!slot->dma_addr) {
  74. - bgmac_err(bgmac, "Hardware reported transmission for empty TX ring slot %d! End of ring: %d\n",
  75. - ring->start, ring->end);
  76. - goto next;
  77. - }
  78. + if (slot_idx == empty_slot)
  79. + break;
  80. + ctl1 = le32_to_cpu(ring->cpu_base[slot_idx].ctl1);
  81. + len = ctl1 & BGMAC_DESC_CTL1_LEN;
  82. if (ctl1 & BGMAC_DESC_CTL0_SOF)
  83. /* Unmap no longer used buffer */
  84. dma_unmap_single(dma_dev, slot->dma_addr, len,
  85. @@ -284,10 +280,8 @@ static void bgmac_dma_tx_free(struct bgm
  86. slot->skb = NULL;
  87. }
  88. -next:
  89. slot->dma_addr = 0;
  90. - if (++ring->start >= BGMAC_TX_RING_SLOTS)
  91. - ring->start = 0;
  92. + ring->start++;
  93. freed = true;
  94. }
  95. --- a/drivers/net/ethernet/broadcom/bgmac.h
  96. +++ b/drivers/net/ethernet/broadcom/bgmac.h
  97. @@ -414,10 +414,10 @@ enum bgmac_dma_ring_type {
  98. * empty.
  99. */
  100. struct bgmac_dma_ring {
  101. - u16 num_slots;
  102. - u16 start;
  103. - u16 end;
  104. + u32 start;
  105. + u32 end;
  106. + u16 num_slots;
  107. u16 mmio_base;
  108. struct bgmac_dma_desc *cpu_base;
  109. dma_addr_t dma_base;