ring_mode.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*******************************************************************************
  3. Specialised functions for managing Ring mode
  4. Copyright(C) 2011 STMicroelectronics Ltd
  5. It defines all the functions used to handle the normal/enhanced
  6. descriptors in case of the DMA is configured to work in chained or
  7. in ring mode.
  8. Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
  9. *******************************************************************************/
  10. #include "stmmac.h"
  11. static int jumbo_frm(struct stmmac_tx_queue *tx_q, struct sk_buff *skb,
  12. int csum)
  13. {
  14. unsigned int nopaged_len = skb_headlen(skb);
  15. struct stmmac_priv *priv = tx_q->priv_data;
  16. unsigned int entry = tx_q->cur_tx;
  17. unsigned int bmax, len, des2;
  18. struct dma_desc *desc;
  19. if (priv->extend_desc)
  20. desc = (struct dma_desc *)(tx_q->dma_etx + entry);
  21. else
  22. desc = tx_q->dma_tx + entry;
  23. if (priv->plat->enh_desc)
  24. bmax = BUF_SIZE_8KiB;
  25. else
  26. bmax = BUF_SIZE_2KiB;
  27. len = nopaged_len - bmax;
  28. if (nopaged_len > BUF_SIZE_8KiB) {
  29. des2 = dma_map_single(priv->device, skb->data, bmax,
  30. DMA_TO_DEVICE);
  31. desc->des2 = cpu_to_le32(des2);
  32. if (dma_mapping_error(priv->device, des2))
  33. return -1;
  34. tx_q->tx_skbuff_dma[entry].buf = des2;
  35. tx_q->tx_skbuff_dma[entry].len = bmax;
  36. tx_q->tx_skbuff_dma[entry].is_jumbo = true;
  37. desc->des3 = cpu_to_le32(des2 + BUF_SIZE_4KiB);
  38. stmmac_prepare_tx_desc(priv, desc, 1, bmax, csum,
  39. STMMAC_RING_MODE, 0, false, skb->len);
  40. tx_q->tx_skbuff[entry] = NULL;
  41. entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_tx_size);
  42. if (priv->extend_desc)
  43. desc = (struct dma_desc *)(tx_q->dma_etx + entry);
  44. else
  45. desc = tx_q->dma_tx + entry;
  46. des2 = dma_map_single(priv->device, skb->data + bmax, len,
  47. DMA_TO_DEVICE);
  48. desc->des2 = cpu_to_le32(des2);
  49. if (dma_mapping_error(priv->device, des2))
  50. return -1;
  51. tx_q->tx_skbuff_dma[entry].buf = des2;
  52. tx_q->tx_skbuff_dma[entry].len = len;
  53. tx_q->tx_skbuff_dma[entry].is_jumbo = true;
  54. desc->des3 = cpu_to_le32(des2 + BUF_SIZE_4KiB);
  55. stmmac_prepare_tx_desc(priv, desc, 0, len, csum,
  56. STMMAC_RING_MODE, 1, !skb_is_nonlinear(skb),
  57. skb->len);
  58. } else {
  59. des2 = dma_map_single(priv->device, skb->data,
  60. nopaged_len, DMA_TO_DEVICE);
  61. desc->des2 = cpu_to_le32(des2);
  62. if (dma_mapping_error(priv->device, des2))
  63. return -1;
  64. tx_q->tx_skbuff_dma[entry].buf = des2;
  65. tx_q->tx_skbuff_dma[entry].len = nopaged_len;
  66. tx_q->tx_skbuff_dma[entry].is_jumbo = true;
  67. desc->des3 = cpu_to_le32(des2 + BUF_SIZE_4KiB);
  68. stmmac_prepare_tx_desc(priv, desc, 1, nopaged_len, csum,
  69. STMMAC_RING_MODE, 0, !skb_is_nonlinear(skb),
  70. skb->len);
  71. }
  72. tx_q->cur_tx = entry;
  73. return entry;
  74. }
  75. static bool is_jumbo_frm(unsigned int len, bool enh_desc)
  76. {
  77. return len >= BUF_SIZE_4KiB;
  78. }
  79. static void refill_desc3(struct stmmac_rx_queue *rx_q, struct dma_desc *p)
  80. {
  81. struct stmmac_priv *priv = rx_q->priv_data;
  82. /* Fill DES3 in case of RING mode */
  83. if (priv->dma_conf.dma_buf_sz == BUF_SIZE_16KiB)
  84. p->des3 = cpu_to_le32(le32_to_cpu(p->des2) + BUF_SIZE_8KiB);
  85. }
  86. /* In ring mode we need to fill the desc3 because it is used as buffer */
  87. static void init_desc3(struct dma_desc *p)
  88. {
  89. p->des3 = cpu_to_le32(le32_to_cpu(p->des2) + BUF_SIZE_8KiB);
  90. }
  91. static void clean_desc3(struct stmmac_tx_queue *tx_q, struct dma_desc *p)
  92. {
  93. struct stmmac_priv *priv = tx_q->priv_data;
  94. unsigned int entry = tx_q->dirty_tx;
  95. /* des3 is only used for jumbo frames tx or time stamping */
  96. if (unlikely(tx_q->tx_skbuff_dma[entry].is_jumbo ||
  97. (tx_q->tx_skbuff_dma[entry].last_segment &&
  98. !priv->extend_desc && priv->hwts_tx_en)))
  99. p->des3 = 0;
  100. }
  101. static int set_16kib_bfsize(int mtu)
  102. {
  103. int ret = 0;
  104. if (unlikely(mtu > BUF_SIZE_8KiB))
  105. ret = BUF_SIZE_16KiB;
  106. return ret;
  107. }
  108. const struct stmmac_mode_ops ring_mode_ops = {
  109. .is_jumbo_frm = is_jumbo_frm,
  110. .jumbo_frm = jumbo_frm,
  111. .refill_desc3 = refill_desc3,
  112. .init_desc3 = init_desc3,
  113. .clean_desc3 = clean_desc3,
  114. .set_16kib_bfsize = set_16kib_bfsize,
  115. };