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