ocelot_fdma.h (5036B)
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 62DECLARE_STATIC_KEY_FALSE(ocelot_fdma_enabled); 63 64struct 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 */ 76struct 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 */ 91struct 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 */ 107struct 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 */ 124struct 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 */ 146struct 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 157void ocelot_fdma_init(struct platform_device *pdev, struct ocelot *ocelot); 158void ocelot_fdma_start(struct ocelot *ocelot); 159void ocelot_fdma_deinit(struct ocelot *ocelot); 160int ocelot_fdma_inject_frame(struct ocelot *fdma, int port, u32 rew_op, 161 struct sk_buff *skb, struct net_device *dev); 162void ocelot_fdma_netdev_init(struct ocelot *ocelot, struct net_device *dev); 163void ocelot_fdma_netdev_deinit(struct ocelot *ocelot, 164 struct net_device *dev); 165 166#endif