162306a36Sopenharmony_ci/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Microsemi SoCs FDMA driver 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2021 Microchip 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci#ifndef _MSCC_OCELOT_FDMA_H_ 862306a36Sopenharmony_ci#define _MSCC_OCELOT_FDMA_H_ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include "ocelot.h" 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#define MSCC_FDMA_DCB_STAT_BLOCKO(x) (((x) << 20) & GENMASK(31, 20)) 1362306a36Sopenharmony_ci#define MSCC_FDMA_DCB_STAT_BLOCKO_M GENMASK(31, 20) 1462306a36Sopenharmony_ci#define MSCC_FDMA_DCB_STAT_BLOCKO_X(x) (((x) & GENMASK(31, 20)) >> 20) 1562306a36Sopenharmony_ci#define MSCC_FDMA_DCB_STAT_PD BIT(19) 1662306a36Sopenharmony_ci#define MSCC_FDMA_DCB_STAT_ABORT BIT(18) 1762306a36Sopenharmony_ci#define MSCC_FDMA_DCB_STAT_EOF BIT(17) 1862306a36Sopenharmony_ci#define MSCC_FDMA_DCB_STAT_SOF BIT(16) 1962306a36Sopenharmony_ci#define MSCC_FDMA_DCB_STAT_BLOCKL_M GENMASK(15, 0) 2062306a36Sopenharmony_ci#define MSCC_FDMA_DCB_STAT_BLOCKL(x) ((x) & GENMASK(15, 0)) 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#define MSCC_FDMA_DCB_LLP(x) ((x) * 4 + 0x0) 2362306a36Sopenharmony_ci#define MSCC_FDMA_DCB_LLP_PREV(x) ((x) * 4 + 0xA0) 2462306a36Sopenharmony_ci#define MSCC_FDMA_CH_SAFE 0xcc 2562306a36Sopenharmony_ci#define MSCC_FDMA_CH_ACTIVATE 0xd0 2662306a36Sopenharmony_ci#define MSCC_FDMA_CH_DISABLE 0xd4 2762306a36Sopenharmony_ci#define MSCC_FDMA_CH_FORCEDIS 0xd8 2862306a36Sopenharmony_ci#define MSCC_FDMA_EVT_ERR 0x164 2962306a36Sopenharmony_ci#define MSCC_FDMA_EVT_ERR_CODE 0x168 3062306a36Sopenharmony_ci#define MSCC_FDMA_INTR_LLP 0x16c 3162306a36Sopenharmony_ci#define MSCC_FDMA_INTR_LLP_ENA 0x170 3262306a36Sopenharmony_ci#define MSCC_FDMA_INTR_FRM 0x174 3362306a36Sopenharmony_ci#define MSCC_FDMA_INTR_FRM_ENA 0x178 3462306a36Sopenharmony_ci#define MSCC_FDMA_INTR_ENA 0x184 3562306a36Sopenharmony_ci#define MSCC_FDMA_INTR_IDENT 0x188 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci#define MSCC_FDMA_INJ_CHAN 2 3862306a36Sopenharmony_ci#define MSCC_FDMA_XTR_CHAN 0 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci#define OCELOT_FDMA_WEIGHT 32 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci#define OCELOT_FDMA_CH_SAFE_TIMEOUT_US 10 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci#define OCELOT_FDMA_RX_RING_SIZE 512 4562306a36Sopenharmony_ci#define OCELOT_FDMA_TX_RING_SIZE 128 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci#define OCELOT_FDMA_RX_DCB_SIZE (OCELOT_FDMA_RX_RING_SIZE * \ 4862306a36Sopenharmony_ci sizeof(struct ocelot_fdma_dcb)) 4962306a36Sopenharmony_ci#define OCELOT_FDMA_TX_DCB_SIZE (OCELOT_FDMA_TX_RING_SIZE * \ 5062306a36Sopenharmony_ci sizeof(struct ocelot_fdma_dcb)) 5162306a36Sopenharmony_ci/* +4 allows for word alignment after allocation */ 5262306a36Sopenharmony_ci#define OCELOT_DCBS_HW_ALLOC_SIZE (OCELOT_FDMA_RX_DCB_SIZE + \ 5362306a36Sopenharmony_ci OCELOT_FDMA_TX_DCB_SIZE + \ 5462306a36Sopenharmony_ci 4) 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci#define OCELOT_FDMA_RX_SIZE (PAGE_SIZE / 2) 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci#define OCELOT_FDMA_SKBFRAG_OVR (4 + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) 5962306a36Sopenharmony_ci#define OCELOT_FDMA_RXB_SIZE ALIGN_DOWN(OCELOT_FDMA_RX_SIZE - OCELOT_FDMA_SKBFRAG_OVR, 4) 6062306a36Sopenharmony_ci#define OCELOT_FDMA_SKBFRAG_SIZE (OCELOT_FDMA_RXB_SIZE + OCELOT_FDMA_SKBFRAG_OVR) 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ciDECLARE_STATIC_KEY_FALSE(ocelot_fdma_enabled); 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_cistruct ocelot_fdma_dcb { 6562306a36Sopenharmony_ci u32 llp; 6662306a36Sopenharmony_ci u32 datap; 6762306a36Sopenharmony_ci u32 datal; 6862306a36Sopenharmony_ci u32 stat; 6962306a36Sopenharmony_ci} __packed; 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci/** 7262306a36Sopenharmony_ci * struct ocelot_fdma_tx_buf - TX buffer structure 7362306a36Sopenharmony_ci * @skb: SKB currently used in the corresponding DCB. 7462306a36Sopenharmony_ci * @dma_addr: SKB DMA mapped address. 7562306a36Sopenharmony_ci */ 7662306a36Sopenharmony_cistruct ocelot_fdma_tx_buf { 7762306a36Sopenharmony_ci struct sk_buff *skb; 7862306a36Sopenharmony_ci DEFINE_DMA_UNMAP_ADDR(dma_addr); 7962306a36Sopenharmony_ci}; 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci/** 8262306a36Sopenharmony_ci * struct ocelot_fdma_tx_ring - TX ring description of DCBs 8362306a36Sopenharmony_ci * 8462306a36Sopenharmony_ci * @dcbs: DCBs allocated for the ring 8562306a36Sopenharmony_ci * @dcbs_dma: DMA base address of the DCBs 8662306a36Sopenharmony_ci * @bufs: List of TX buffer associated to the DCBs 8762306a36Sopenharmony_ci * @xmit_lock: lock for concurrent xmit access 8862306a36Sopenharmony_ci * @next_to_clean: Next DCB to be cleaned in tx_cleanup 8962306a36Sopenharmony_ci * @next_to_use: Next available DCB to send SKB 9062306a36Sopenharmony_ci */ 9162306a36Sopenharmony_cistruct ocelot_fdma_tx_ring { 9262306a36Sopenharmony_ci struct ocelot_fdma_dcb *dcbs; 9362306a36Sopenharmony_ci dma_addr_t dcbs_dma; 9462306a36Sopenharmony_ci struct ocelot_fdma_tx_buf bufs[OCELOT_FDMA_TX_RING_SIZE]; 9562306a36Sopenharmony_ci /* Protect concurrent xmit calls */ 9662306a36Sopenharmony_ci spinlock_t xmit_lock; 9762306a36Sopenharmony_ci u16 next_to_clean; 9862306a36Sopenharmony_ci u16 next_to_use; 9962306a36Sopenharmony_ci}; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci/** 10262306a36Sopenharmony_ci * struct ocelot_fdma_rx_buf - RX buffer structure 10362306a36Sopenharmony_ci * @page: Struct page used in this buffer 10462306a36Sopenharmony_ci * @page_offset: Current page offset (either 0 or PAGE_SIZE/2) 10562306a36Sopenharmony_ci * @dma_addr: DMA address of the page 10662306a36Sopenharmony_ci */ 10762306a36Sopenharmony_cistruct ocelot_fdma_rx_buf { 10862306a36Sopenharmony_ci struct page *page; 10962306a36Sopenharmony_ci u32 page_offset; 11062306a36Sopenharmony_ci dma_addr_t dma_addr; 11162306a36Sopenharmony_ci}; 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci/** 11462306a36Sopenharmony_ci * struct ocelot_fdma_rx_ring - TX ring description of DCBs 11562306a36Sopenharmony_ci * 11662306a36Sopenharmony_ci * @dcbs: DCBs allocated for the ring 11762306a36Sopenharmony_ci * @dcbs_dma: DMA base address of the DCBs 11862306a36Sopenharmony_ci * @bufs: List of RX buffer associated to the DCBs 11962306a36Sopenharmony_ci * @skb: SKB currently received by the netdev 12062306a36Sopenharmony_ci * @next_to_clean: Next DCB to be cleaned NAPI polling 12162306a36Sopenharmony_ci * @next_to_use: Next available DCB to send SKB 12262306a36Sopenharmony_ci * @next_to_alloc: Next buffer that needs to be allocated (page reuse or alloc) 12362306a36Sopenharmony_ci */ 12462306a36Sopenharmony_cistruct ocelot_fdma_rx_ring { 12562306a36Sopenharmony_ci struct ocelot_fdma_dcb *dcbs; 12662306a36Sopenharmony_ci dma_addr_t dcbs_dma; 12762306a36Sopenharmony_ci struct ocelot_fdma_rx_buf bufs[OCELOT_FDMA_RX_RING_SIZE]; 12862306a36Sopenharmony_ci struct sk_buff *skb; 12962306a36Sopenharmony_ci u16 next_to_clean; 13062306a36Sopenharmony_ci u16 next_to_use; 13162306a36Sopenharmony_ci u16 next_to_alloc; 13262306a36Sopenharmony_ci}; 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci/** 13562306a36Sopenharmony_ci * struct ocelot_fdma - FDMA context 13662306a36Sopenharmony_ci * 13762306a36Sopenharmony_ci * @irq: FDMA interrupt 13862306a36Sopenharmony_ci * @ndev: Net device used to initialize NAPI 13962306a36Sopenharmony_ci * @dcbs_base: Memory coherent DCBs 14062306a36Sopenharmony_ci * @dcbs_dma_base: DMA base address of memory coherent DCBs 14162306a36Sopenharmony_ci * @tx_ring: Injection ring 14262306a36Sopenharmony_ci * @rx_ring: Extraction ring 14362306a36Sopenharmony_ci * @napi: NAPI context 14462306a36Sopenharmony_ci * @ocelot: Back-pointer to ocelot struct 14562306a36Sopenharmony_ci */ 14662306a36Sopenharmony_cistruct ocelot_fdma { 14762306a36Sopenharmony_ci int irq; 14862306a36Sopenharmony_ci struct net_device *ndev; 14962306a36Sopenharmony_ci struct ocelot_fdma_dcb *dcbs_base; 15062306a36Sopenharmony_ci dma_addr_t dcbs_dma_base; 15162306a36Sopenharmony_ci struct ocelot_fdma_tx_ring tx_ring; 15262306a36Sopenharmony_ci struct ocelot_fdma_rx_ring rx_ring; 15362306a36Sopenharmony_ci struct napi_struct napi; 15462306a36Sopenharmony_ci struct ocelot *ocelot; 15562306a36Sopenharmony_ci}; 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_civoid ocelot_fdma_init(struct platform_device *pdev, struct ocelot *ocelot); 15862306a36Sopenharmony_civoid ocelot_fdma_start(struct ocelot *ocelot); 15962306a36Sopenharmony_civoid ocelot_fdma_deinit(struct ocelot *ocelot); 16062306a36Sopenharmony_ciint ocelot_fdma_inject_frame(struct ocelot *fdma, int port, u32 rew_op, 16162306a36Sopenharmony_ci struct sk_buff *skb, struct net_device *dev); 16262306a36Sopenharmony_civoid ocelot_fdma_netdev_init(struct ocelot *ocelot, struct net_device *dev); 16362306a36Sopenharmony_civoid ocelot_fdma_netdev_deinit(struct ocelot *ocelot, 16462306a36Sopenharmony_ci struct net_device *dev); 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci#endif 167