ocelot_fdma.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
  2. /*
  3. * Microsemi SoCs FDMA driver
  4. *
  5. * Copyright (c) 2021 Microchip
  6. */
  7. #ifndef _MSCC_OCELOT_FDMA_H_
  8. #define _MSCC_OCELOT_FDMA_H_
  9. #include "ocelot.h"
  10. #define MSCC_FDMA_DCB_STAT_BLOCKO(x) (((x) << 20) & GENMASK(31, 20))
  11. #define MSCC_FDMA_DCB_STAT_BLOCKO_M GENMASK(31, 20)
  12. #define MSCC_FDMA_DCB_STAT_BLOCKO_X(x) (((x) & GENMASK(31, 20)) >> 20)
  13. #define MSCC_FDMA_DCB_STAT_PD BIT(19)
  14. #define MSCC_FDMA_DCB_STAT_ABORT BIT(18)
  15. #define MSCC_FDMA_DCB_STAT_EOF BIT(17)
  16. #define MSCC_FDMA_DCB_STAT_SOF BIT(16)
  17. #define MSCC_FDMA_DCB_STAT_BLOCKL_M GENMASK(15, 0)
  18. #define MSCC_FDMA_DCB_STAT_BLOCKL(x) ((x) & GENMASK(15, 0))
  19. #define MSCC_FDMA_DCB_LLP(x) ((x) * 4 + 0x0)
  20. #define MSCC_FDMA_DCB_LLP_PREV(x) ((x) * 4 + 0xA0)
  21. #define MSCC_FDMA_CH_SAFE 0xcc
  22. #define MSCC_FDMA_CH_ACTIVATE 0xd0
  23. #define MSCC_FDMA_CH_DISABLE 0xd4
  24. #define MSCC_FDMA_CH_FORCEDIS 0xd8
  25. #define MSCC_FDMA_EVT_ERR 0x164
  26. #define MSCC_FDMA_EVT_ERR_CODE 0x168
  27. #define MSCC_FDMA_INTR_LLP 0x16c
  28. #define MSCC_FDMA_INTR_LLP_ENA 0x170
  29. #define MSCC_FDMA_INTR_FRM 0x174
  30. #define MSCC_FDMA_INTR_FRM_ENA 0x178
  31. #define MSCC_FDMA_INTR_ENA 0x184
  32. #define MSCC_FDMA_INTR_IDENT 0x188
  33. #define MSCC_FDMA_INJ_CHAN 2
  34. #define MSCC_FDMA_XTR_CHAN 0
  35. #define OCELOT_FDMA_WEIGHT 32
  36. #define OCELOT_FDMA_CH_SAFE_TIMEOUT_US 10
  37. #define OCELOT_FDMA_RX_RING_SIZE 512
  38. #define OCELOT_FDMA_TX_RING_SIZE 128
  39. #define OCELOT_FDMA_RX_DCB_SIZE (OCELOT_FDMA_RX_RING_SIZE * \
  40. sizeof(struct ocelot_fdma_dcb))
  41. #define OCELOT_FDMA_TX_DCB_SIZE (OCELOT_FDMA_TX_RING_SIZE * \
  42. sizeof(struct ocelot_fdma_dcb))
  43. /* +4 allows for word alignment after allocation */
  44. #define OCELOT_DCBS_HW_ALLOC_SIZE (OCELOT_FDMA_RX_DCB_SIZE + \
  45. OCELOT_FDMA_TX_DCB_SIZE + \
  46. 4)
  47. #define OCELOT_FDMA_RX_SIZE (PAGE_SIZE / 2)
  48. #define OCELOT_FDMA_SKBFRAG_OVR (4 + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
  49. #define OCELOT_FDMA_RXB_SIZE ALIGN_DOWN(OCELOT_FDMA_RX_SIZE - OCELOT_FDMA_SKBFRAG_OVR, 4)
  50. #define OCELOT_FDMA_SKBFRAG_SIZE (OCELOT_FDMA_RXB_SIZE + OCELOT_FDMA_SKBFRAG_OVR)
  51. DECLARE_STATIC_KEY_FALSE(ocelot_fdma_enabled);
  52. struct ocelot_fdma_dcb {
  53. u32 llp;
  54. u32 datap;
  55. u32 datal;
  56. u32 stat;
  57. } __packed;
  58. /**
  59. * struct ocelot_fdma_tx_buf - TX buffer structure
  60. * @skb: SKB currently used in the corresponding DCB.
  61. * @dma_addr: SKB DMA mapped address.
  62. */
  63. struct ocelot_fdma_tx_buf {
  64. struct sk_buff *skb;
  65. DEFINE_DMA_UNMAP_ADDR(dma_addr);
  66. };
  67. /**
  68. * struct ocelot_fdma_tx_ring - TX ring description of DCBs
  69. *
  70. * @dcbs: DCBs allocated for the ring
  71. * @dcbs_dma: DMA base address of the DCBs
  72. * @bufs: List of TX buffer associated to the DCBs
  73. * @xmit_lock: lock for concurrent xmit access
  74. * @next_to_clean: Next DCB to be cleaned in tx_cleanup
  75. * @next_to_use: Next available DCB to send SKB
  76. */
  77. struct ocelot_fdma_tx_ring {
  78. struct ocelot_fdma_dcb *dcbs;
  79. dma_addr_t dcbs_dma;
  80. struct ocelot_fdma_tx_buf bufs[OCELOT_FDMA_TX_RING_SIZE];
  81. /* Protect concurrent xmit calls */
  82. spinlock_t xmit_lock;
  83. u16 next_to_clean;
  84. u16 next_to_use;
  85. };
  86. /**
  87. * struct ocelot_fdma_rx_buf - RX buffer structure
  88. * @page: Struct page used in this buffer
  89. * @page_offset: Current page offset (either 0 or PAGE_SIZE/2)
  90. * @dma_addr: DMA address of the page
  91. */
  92. struct ocelot_fdma_rx_buf {
  93. struct page *page;
  94. u32 page_offset;
  95. dma_addr_t dma_addr;
  96. };
  97. /**
  98. * struct ocelot_fdma_rx_ring - TX ring description of DCBs
  99. *
  100. * @dcbs: DCBs allocated for the ring
  101. * @dcbs_dma: DMA base address of the DCBs
  102. * @bufs: List of RX buffer associated to the DCBs
  103. * @skb: SKB currently received by the netdev
  104. * @next_to_clean: Next DCB to be cleaned NAPI polling
  105. * @next_to_use: Next available DCB to send SKB
  106. * @next_to_alloc: Next buffer that needs to be allocated (page reuse or alloc)
  107. */
  108. struct ocelot_fdma_rx_ring {
  109. struct ocelot_fdma_dcb *dcbs;
  110. dma_addr_t dcbs_dma;
  111. struct ocelot_fdma_rx_buf bufs[OCELOT_FDMA_RX_RING_SIZE];
  112. struct sk_buff *skb;
  113. u16 next_to_clean;
  114. u16 next_to_use;
  115. u16 next_to_alloc;
  116. };
  117. /**
  118. * struct ocelot_fdma - FDMA context
  119. *
  120. * @irq: FDMA interrupt
  121. * @ndev: Net device used to initialize NAPI
  122. * @dcbs_base: Memory coherent DCBs
  123. * @dcbs_dma_base: DMA base address of memory coherent DCBs
  124. * @tx_ring: Injection ring
  125. * @rx_ring: Extraction ring
  126. * @napi: NAPI context
  127. * @ocelot: Back-pointer to ocelot struct
  128. */
  129. struct ocelot_fdma {
  130. int irq;
  131. struct net_device *ndev;
  132. struct ocelot_fdma_dcb *dcbs_base;
  133. dma_addr_t dcbs_dma_base;
  134. struct ocelot_fdma_tx_ring tx_ring;
  135. struct ocelot_fdma_rx_ring rx_ring;
  136. struct napi_struct napi;
  137. struct ocelot *ocelot;
  138. };
  139. void ocelot_fdma_init(struct platform_device *pdev, struct ocelot *ocelot);
  140. void ocelot_fdma_start(struct ocelot *ocelot);
  141. void ocelot_fdma_deinit(struct ocelot *ocelot);
  142. int ocelot_fdma_inject_frame(struct ocelot *fdma, int port, u32 rew_op,
  143. struct sk_buff *skb, struct net_device *dev);
  144. void ocelot_fdma_netdev_init(struct ocelot *ocelot, struct net_device *dev);
  145. void ocelot_fdma_netdev_deinit(struct ocelot *ocelot,
  146. struct net_device *dev);
  147. #endif