Marcin Wojtas | dc35a10 | 2016-03-14 09:39:03 +0100 | [diff] [blame] | 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 { |
Gregory CLEMENT | baa11eb | 2016-03-14 09:39:05 +0100 | [diff] [blame] | 111 | struct hwbm_pool hwbm_pool; |
Marcin Wojtas | dc35a10 | 2016-03-14 09:39:03 +0100 | [diff] [blame] | 112 | /* Pool number in the range 0-3 */ |
| 113 | u8 id; |
| 114 | enum mvneta_bm_type type; |
| 115 | |
Marcin Wojtas | dc35a10 | 2016-03-14 09:39:03 +0100 | [diff] [blame] | 116 | /* Packet size */ |
| 117 | int pkt_size; |
Gregory CLEMENT | baa11eb | 2016-03-14 09:39:05 +0100 | [diff] [blame] | 118 | /* Size of the buffer acces through DMA*/ |
| 119 | u32 buf_size; |
Marcin Wojtas | dc35a10 | 2016-03-14 09:39:03 +0100 | [diff] [blame] | 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 */ |
Javier Martinez Canillas | bb15293 | 2016-09-12 10:03:40 -0400 | [diff] [blame] | 133 | #if IS_ENABLED(CONFIG_MVNETA_BM) |
Gregory CLEMENT | 965cbbe | 2018-07-18 18:10:52 +0200 | [diff] [blame] | 134 | struct mvneta_bm *mvneta_bm_get(struct device_node *node); |
| 135 | void mvneta_bm_put(struct mvneta_bm *priv); |
| 136 | |
Marcin Wojtas | dc35a10 | 2016-03-14 09:39:03 +0100 | [diff] [blame] | 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); |
Gregory CLEMENT | baa11eb | 2016-03-14 09:39:05 +0100 | [diff] [blame] | 141 | int mvneta_bm_construct(struct hwbm_pool *hwbm_pool, void *buf); |
Marcin Wojtas | dc35a10 | 2016-03-14 09:39:03 +0100 | [diff] [blame] | 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 |
Ben Dooks (Codethink) | 3f6b2c4 | 2019-10-23 11:01:08 +0100 | [diff] [blame] | 163 | static inline void mvneta_bm_pool_destroy(struct mvneta_bm *priv, |
| 164 | struct mvneta_bm_pool *bm_pool, |
| 165 | u8 port_map) {} |
| 166 | static inline void mvneta_bm_bufs_free(struct mvneta_bm *priv, |
| 167 | struct mvneta_bm_pool *bm_pool, |
| 168 | u8 port_map) {} |
| 169 | static inline int mvneta_bm_construct(struct hwbm_pool *hwbm_pool, void *buf) |
| 170 | { return 0; } |
| 171 | static inline int mvneta_bm_pool_refill(struct mvneta_bm *priv, |
| 172 | struct mvneta_bm_pool *bm_pool) |
| 173 | { return 0; } |
| 174 | static inline struct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv, |
| 175 | u8 pool_id, |
| 176 | enum mvneta_bm_type type, |
| 177 | u8 port_id, |
| 178 | int pkt_size) |
| 179 | { return NULL; } |
Marcin Wojtas | dc35a10 | 2016-03-14 09:39:03 +0100 | [diff] [blame] | 180 | |
| 181 | static inline void mvneta_bm_pool_put_bp(struct mvneta_bm *priv, |
| 182 | struct mvneta_bm_pool *bm_pool, |
| 183 | dma_addr_t buf_phys_addr) {} |
| 184 | |
| 185 | static inline u32 mvneta_bm_pool_get_bp(struct mvneta_bm *priv, |
| 186 | struct mvneta_bm_pool *bm_pool) |
| 187 | { return 0; } |
Ben Dooks (Codethink) | 3f6b2c4 | 2019-10-23 11:01:08 +0100 | [diff] [blame] | 188 | static inline struct mvneta_bm *mvneta_bm_get(struct device_node *node) |
| 189 | { return NULL; } |
| 190 | static inline void mvneta_bm_put(struct mvneta_bm *priv) {} |
Marcin Wojtas | dc35a10 | 2016-03-14 09:39:03 +0100 | [diff] [blame] | 191 | #endif /* CONFIG_MVNETA_BM */ |
| 192 | #endif |