1 /* 2 * Driver for Marvell NETA network controller Buffer Manager. 3 * 4 * Copyright (C) 2015 Marvell 5 * 6 * Marcin Wojtas <mw@semihalf.com> 7 * 8 * This file is licensed under the terms of the GNU General Public 9 * License version 2. This program is licensed "as is" without any 10 * warranty of any kind, whether express or implied. 11 */ 12 13 #ifndef _MVNETA_BM_H_ 14 #define _MVNETA_BM_H_ 15 16 /* BM Configuration Register */ 17 #define MVNETA_BM_CONFIG_REG 0x0 18 #define MVNETA_BM_STATUS_MASK 0x30 19 #define MVNETA_BM_ACTIVE_MASK BIT(4) 20 #define MVNETA_BM_MAX_IN_BURST_SIZE_MASK 0x60000 21 #define MVNETA_BM_MAX_IN_BURST_SIZE_16BP BIT(18) 22 #define MVNETA_BM_EMPTY_LIMIT_MASK BIT(19) 23 24 /* BM Activation Register */ 25 #define MVNETA_BM_COMMAND_REG 0x4 26 #define MVNETA_BM_START_MASK BIT(0) 27 #define MVNETA_BM_STOP_MASK BIT(1) 28 #define MVNETA_BM_PAUSE_MASK BIT(2) 29 30 /* BM Xbar interface Register */ 31 #define MVNETA_BM_XBAR_01_REG 0x8 32 #define MVNETA_BM_XBAR_23_REG 0xc 33 #define MVNETA_BM_XBAR_POOL_REG(pool) \ 34 (((pool) < 2) ? MVNETA_BM_XBAR_01_REG : MVNETA_BM_XBAR_23_REG) 35 #define MVNETA_BM_TARGET_ID_OFFS(pool) (((pool) & 1) ? 16 : 0) 36 #define MVNETA_BM_TARGET_ID_MASK(pool) \ 37 (0xf << MVNETA_BM_TARGET_ID_OFFS(pool)) 38 #define MVNETA_BM_TARGET_ID_VAL(pool, id) \ 39 ((id) << MVNETA_BM_TARGET_ID_OFFS(pool)) 40 #define MVNETA_BM_XBAR_ATTR_OFFS(pool) (((pool) & 1) ? 20 : 4) 41 #define MVNETA_BM_XBAR_ATTR_MASK(pool) \ 42 (0xff << MVNETA_BM_XBAR_ATTR_OFFS(pool)) 43 #define MVNETA_BM_XBAR_ATTR_VAL(pool, attr) \ 44 ((attr) << MVNETA_BM_XBAR_ATTR_OFFS(pool)) 45 46 /* Address of External Buffer Pointers Pool Register */ 47 #define MVNETA_BM_POOL_BASE_REG(pool) (0x10 + ((pool) << 4)) 48 #define MVNETA_BM_POOL_ENABLE_MASK BIT(0) 49 50 /* External Buffer Pointers Pool RD pointer Register */ 51 #define MVNETA_BM_POOL_READ_PTR_REG(pool) (0x14 + ((pool) << 4)) 52 #define MVNETA_BM_POOL_SET_READ_PTR_MASK 0xfffc 53 #define MVNETA_BM_POOL_GET_READ_PTR_OFFS 16 54 #define MVNETA_BM_POOL_GET_READ_PTR_MASK 0xfffc0000 55 56 /* External Buffer Pointers Pool WR pointer */ 57 #define MVNETA_BM_POOL_WRITE_PTR_REG(pool) (0x18 + ((pool) << 4)) 58 #define MVNETA_BM_POOL_SET_WRITE_PTR_OFFS 0 59 #define MVNETA_BM_POOL_SET_WRITE_PTR_MASK 0xfffc 60 #define MVNETA_BM_POOL_GET_WRITE_PTR_OFFS 16 61 #define MVNETA_BM_POOL_GET_WRITE_PTR_MASK 0xfffc0000 62 63 /* External Buffer Pointers Pool Size Register */ 64 #define MVNETA_BM_POOL_SIZE_REG(pool) (0x1c + ((pool) << 4)) 65 #define MVNETA_BM_POOL_SIZE_MASK 0x3fff 66 67 /* BM Interrupt Cause Register */ 68 #define MVNETA_BM_INTR_CAUSE_REG (0x50) 69 70 /* BM interrupt Mask Register */ 71 #define MVNETA_BM_INTR_MASK_REG (0x54) 72 73 /* Other definitions */ 74 #define MVNETA_BM_SHORT_PKT_SIZE 256 75 #define MVNETA_BM_POOLS_NUM 4 76 #define MVNETA_BM_POOL_CAP_MIN 128 77 #define MVNETA_BM_POOL_CAP_DEF 2048 78 #define MVNETA_BM_POOL_CAP_MAX \ 79 (16 * 1024 - MVNETA_BM_POOL_CAP_ALIGN) 80 #define MVNETA_BM_POOL_CAP_ALIGN 32 81 #define MVNETA_BM_POOL_PTR_ALIGN 32 82 83 #define MVNETA_BM_POOL_ACCESS_OFFS 8 84 85 #define MVNETA_BM_BPPI_SIZE 0x100000 86 87 #define MVNETA_RX_BUF_SIZE(pkt_size) ((pkt_size) + NET_SKB_PAD) 88 89 enum mvneta_bm_type { 90 MVNETA_BM_FREE, 91 MVNETA_BM_LONG, 92 MVNETA_BM_SHORT 93 }; 94 95 struct mvneta_bm { 96 void __iomem *reg_base; 97 struct clk *clk; 98 struct platform_device *pdev; 99 100 struct gen_pool *bppi_pool; 101 /* BPPI virtual base address */ 102 void __iomem *bppi_virt_addr; 103 /* BPPI physical base address */ 104 dma_addr_t bppi_phys_addr; 105 106 /* BM pools */ 107 struct mvneta_bm_pool *bm_pools; 108 }; 109 110 struct mvneta_bm_pool { 111 struct hwbm_pool hwbm_pool; 112 /* Pool number in the range 0-3 */ 113 u8 id; 114 enum mvneta_bm_type type; 115 116 /* Packet size */ 117 int pkt_size; 118 /* Size of the buffer acces through DMA*/ 119 u32 buf_size; 120 121 /* BPPE virtual base address */ 122 u32 *virt_addr; 123 /* BPPE physical base address */ 124 dma_addr_t phys_addr; 125 126 /* Ports using BM pool */ 127 u8 port_map; 128 129 struct mvneta_bm *priv; 130 }; 131 132 /* Declarations and definitions */ 133 #if IS_ENABLED(CONFIG_MVNETA_BM) 134 struct mvneta_bm *mvneta_bm_get(struct device_node *node); 135 void mvneta_bm_put(struct mvneta_bm *priv); 136 137 void mvneta_bm_pool_destroy(struct mvneta_bm *priv, 138 struct mvneta_bm_pool *bm_pool, u8 port_map); 139 void mvneta_bm_bufs_free(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool, 140 u8 port_map); 141 int mvneta_bm_construct(struct hwbm_pool *hwbm_pool, void *buf); 142 int mvneta_bm_pool_refill(struct mvneta_bm *priv, 143 struct mvneta_bm_pool *bm_pool); 144 struct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv, u8 pool_id, 145 enum mvneta_bm_type type, u8 port_id, 146 int pkt_size); 147 148 static inline void mvneta_bm_pool_put_bp(struct mvneta_bm *priv, 149 struct mvneta_bm_pool *bm_pool, 150 dma_addr_t buf_phys_addr) 151 { 152 writel_relaxed(buf_phys_addr, priv->bppi_virt_addr + 153 (bm_pool->id << MVNETA_BM_POOL_ACCESS_OFFS)); 154 } 155 156 static inline u32 mvneta_bm_pool_get_bp(struct mvneta_bm *priv, 157 struct mvneta_bm_pool *bm_pool) 158 { 159 return readl_relaxed(priv->bppi_virt_addr + 160 (bm_pool->id << MVNETA_BM_POOL_ACCESS_OFFS)); 161 } 162 #else 163 void mvneta_bm_pool_destroy(struct mvneta_bm *priv, 164 struct mvneta_bm_pool *bm_pool, u8 port_map) {} 165 void mvneta_bm_bufs_free(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool, 166 u8 port_map) {} 167 int mvneta_bm_construct(struct hwbm_pool *hwbm_pool, void *buf) { return 0; } 168 int mvneta_bm_pool_refill(struct mvneta_bm *priv, 169 struct mvneta_bm_pool *bm_pool) {return 0; } 170 struct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv, u8 pool_id, 171 enum mvneta_bm_type type, u8 port_id, 172 int pkt_size) { return NULL; } 173 174 static inline void mvneta_bm_pool_put_bp(struct mvneta_bm *priv, 175 struct mvneta_bm_pool *bm_pool, 176 dma_addr_t buf_phys_addr) {} 177 178 static inline u32 mvneta_bm_pool_get_bp(struct mvneta_bm *priv, 179 struct mvneta_bm_pool *bm_pool) 180 { return 0; } 181 struct mvneta_bm *mvneta_bm_get(struct device_node *node) { return NULL; } 182 void mvneta_bm_put(struct mvneta_bm *priv) {} 183 #endif /* CONFIG_MVNETA_BM */ 184 #endif 185