Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
0002 /*
0003  * Microsemi SoCs FDMA driver
0004  *
0005  * Copyright (c) 2021 Microchip
0006  */
0007 #ifndef _MSCC_OCELOT_FDMA_H_
0008 #define _MSCC_OCELOT_FDMA_H_
0009 
0010 #include "ocelot.h"
0011 
0012 #define MSCC_FDMA_DCB_STAT_BLOCKO(x)    (((x) << 20) & GENMASK(31, 20))
0013 #define MSCC_FDMA_DCB_STAT_BLOCKO_M GENMASK(31, 20)
0014 #define MSCC_FDMA_DCB_STAT_BLOCKO_X(x)  (((x) & GENMASK(31, 20)) >> 20)
0015 #define MSCC_FDMA_DCB_STAT_PD       BIT(19)
0016 #define MSCC_FDMA_DCB_STAT_ABORT    BIT(18)
0017 #define MSCC_FDMA_DCB_STAT_EOF      BIT(17)
0018 #define MSCC_FDMA_DCB_STAT_SOF      BIT(16)
0019 #define MSCC_FDMA_DCB_STAT_BLOCKL_M GENMASK(15, 0)
0020 #define MSCC_FDMA_DCB_STAT_BLOCKL(x)    ((x) & GENMASK(15, 0))
0021 
0022 #define MSCC_FDMA_DCB_LLP(x)        ((x) * 4 + 0x0)
0023 #define MSCC_FDMA_DCB_LLP_PREV(x)   ((x) * 4 + 0xA0)
0024 #define MSCC_FDMA_CH_SAFE       0xcc
0025 #define MSCC_FDMA_CH_ACTIVATE       0xd0
0026 #define MSCC_FDMA_CH_DISABLE        0xd4
0027 #define MSCC_FDMA_CH_FORCEDIS       0xd8
0028 #define MSCC_FDMA_EVT_ERR       0x164
0029 #define MSCC_FDMA_EVT_ERR_CODE      0x168
0030 #define MSCC_FDMA_INTR_LLP      0x16c
0031 #define MSCC_FDMA_INTR_LLP_ENA      0x170
0032 #define MSCC_FDMA_INTR_FRM      0x174
0033 #define MSCC_FDMA_INTR_FRM_ENA      0x178
0034 #define MSCC_FDMA_INTR_ENA      0x184
0035 #define MSCC_FDMA_INTR_IDENT        0x188
0036 
0037 #define MSCC_FDMA_INJ_CHAN      2
0038 #define MSCC_FDMA_XTR_CHAN      0
0039 
0040 #define OCELOT_FDMA_WEIGHT      32
0041 
0042 #define OCELOT_FDMA_CH_SAFE_TIMEOUT_US  10
0043 
0044 #define OCELOT_FDMA_RX_RING_SIZE    512
0045 #define OCELOT_FDMA_TX_RING_SIZE    128
0046 
0047 #define OCELOT_FDMA_RX_DCB_SIZE     (OCELOT_FDMA_RX_RING_SIZE * \
0048                      sizeof(struct ocelot_fdma_dcb))
0049 #define OCELOT_FDMA_TX_DCB_SIZE     (OCELOT_FDMA_TX_RING_SIZE * \
0050                      sizeof(struct ocelot_fdma_dcb))
0051 /* +4 allows for word alignment after allocation */
0052 #define OCELOT_DCBS_HW_ALLOC_SIZE   (OCELOT_FDMA_RX_DCB_SIZE + \
0053                      OCELOT_FDMA_TX_DCB_SIZE + \
0054                      4)
0055 
0056 #define OCELOT_FDMA_RX_SIZE     (PAGE_SIZE / 2)
0057 
0058 #define OCELOT_FDMA_SKBFRAG_OVR     (4 + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
0059 #define OCELOT_FDMA_RXB_SIZE        ALIGN_DOWN(OCELOT_FDMA_RX_SIZE - OCELOT_FDMA_SKBFRAG_OVR, 4)
0060 #define OCELOT_FDMA_SKBFRAG_SIZE    (OCELOT_FDMA_RXB_SIZE + OCELOT_FDMA_SKBFRAG_OVR)
0061 
0062 DECLARE_STATIC_KEY_FALSE(ocelot_fdma_enabled);
0063 
0064 struct ocelot_fdma_dcb {
0065     u32 llp;
0066     u32 datap;
0067     u32 datal;
0068     u32 stat;
0069 } __packed;
0070 
0071 /**
0072  * struct ocelot_fdma_tx_buf - TX buffer structure
0073  * @skb: SKB currently used in the corresponding DCB.
0074  * @dma_addr: SKB DMA mapped address.
0075  */
0076 struct ocelot_fdma_tx_buf {
0077     struct sk_buff *skb;
0078     DEFINE_DMA_UNMAP_ADDR(dma_addr);
0079 };
0080 
0081 /**
0082  * struct ocelot_fdma_tx_ring - TX ring description of DCBs
0083  *
0084  * @dcbs: DCBs allocated for the ring
0085  * @dcbs_dma: DMA base address of the DCBs
0086  * @bufs: List of TX buffer associated to the DCBs
0087  * @xmit_lock: lock for concurrent xmit access
0088  * @next_to_clean: Next DCB to be cleaned in tx_cleanup
0089  * @next_to_use: Next available DCB to send SKB
0090  */
0091 struct ocelot_fdma_tx_ring {
0092     struct ocelot_fdma_dcb *dcbs;
0093     dma_addr_t dcbs_dma;
0094     struct ocelot_fdma_tx_buf bufs[OCELOT_FDMA_TX_RING_SIZE];
0095     /* Protect concurrent xmit calls */
0096     spinlock_t xmit_lock;
0097     u16 next_to_clean;
0098     u16 next_to_use;
0099 };
0100 
0101 /**
0102  * struct ocelot_fdma_rx_buf - RX buffer structure
0103  * @page: Struct page used in this buffer
0104  * @page_offset: Current page offset (either 0 or PAGE_SIZE/2)
0105  * @dma_addr: DMA address of the page
0106  */
0107 struct ocelot_fdma_rx_buf {
0108     struct page *page;
0109     u32 page_offset;
0110     dma_addr_t dma_addr;
0111 };
0112 
0113 /**
0114  * struct ocelot_fdma_rx_ring - TX ring description of DCBs
0115  *
0116  * @dcbs: DCBs allocated for the ring
0117  * @dcbs_dma: DMA base address of the DCBs
0118  * @bufs: List of RX buffer associated to the DCBs
0119  * @skb: SKB currently received by the netdev
0120  * @next_to_clean: Next DCB to be cleaned NAPI polling
0121  * @next_to_use: Next available DCB to send SKB
0122  * @next_to_alloc: Next buffer that needs to be allocated (page reuse or alloc)
0123  */
0124 struct ocelot_fdma_rx_ring {
0125     struct ocelot_fdma_dcb *dcbs;
0126     dma_addr_t dcbs_dma;
0127     struct ocelot_fdma_rx_buf bufs[OCELOT_FDMA_RX_RING_SIZE];
0128     struct sk_buff *skb;
0129     u16 next_to_clean;
0130     u16 next_to_use;
0131     u16 next_to_alloc;
0132 };
0133 
0134 /**
0135  * struct ocelot_fdma - FDMA context
0136  *
0137  * @irq: FDMA interrupt
0138  * @ndev: Net device used to initialize NAPI
0139  * @dcbs_base: Memory coherent DCBs
0140  * @dcbs_dma_base: DMA base address of memory coherent DCBs
0141  * @tx_ring: Injection ring
0142  * @rx_ring: Extraction ring
0143  * @napi: NAPI context
0144  * @ocelot: Back-pointer to ocelot struct
0145  */
0146 struct ocelot_fdma {
0147     int irq;
0148     struct net_device *ndev;
0149     struct ocelot_fdma_dcb *dcbs_base;
0150     dma_addr_t dcbs_dma_base;
0151     struct ocelot_fdma_tx_ring tx_ring;
0152     struct ocelot_fdma_rx_ring rx_ring;
0153     struct napi_struct napi;
0154     struct ocelot *ocelot;
0155 };
0156 
0157 void ocelot_fdma_init(struct platform_device *pdev, struct ocelot *ocelot);
0158 void ocelot_fdma_start(struct ocelot *ocelot);
0159 void ocelot_fdma_deinit(struct ocelot *ocelot);
0160 int ocelot_fdma_inject_frame(struct ocelot *fdma, int port, u32 rew_op,
0161                  struct sk_buff *skb, struct net_device *dev);
0162 void ocelot_fdma_netdev_init(struct ocelot *ocelot, struct net_device *dev);
0163 void ocelot_fdma_netdev_deinit(struct ocelot *ocelot,
0164                    struct net_device *dev);
0165 
0166 #endif