18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Driver for Marvell NETA network controller Buffer Manager. 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright (C) 2015 Marvell 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Marcin Wojtas <mw@semihalf.com> 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * This file is licensed under the terms of the GNU General Public 98c2ecf20Sopenharmony_ci * License version 2. This program is licensed "as is" without any 108c2ecf20Sopenharmony_ci * warranty of any kind, whether express or implied. 118c2ecf20Sopenharmony_ci */ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#ifndef _MVNETA_BM_H_ 148c2ecf20Sopenharmony_ci#define _MVNETA_BM_H_ 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci/* BM Configuration Register */ 178c2ecf20Sopenharmony_ci#define MVNETA_BM_CONFIG_REG 0x0 188c2ecf20Sopenharmony_ci#define MVNETA_BM_STATUS_MASK 0x30 198c2ecf20Sopenharmony_ci#define MVNETA_BM_ACTIVE_MASK BIT(4) 208c2ecf20Sopenharmony_ci#define MVNETA_BM_MAX_IN_BURST_SIZE_MASK 0x60000 218c2ecf20Sopenharmony_ci#define MVNETA_BM_MAX_IN_BURST_SIZE_16BP BIT(18) 228c2ecf20Sopenharmony_ci#define MVNETA_BM_EMPTY_LIMIT_MASK BIT(19) 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci/* BM Activation Register */ 258c2ecf20Sopenharmony_ci#define MVNETA_BM_COMMAND_REG 0x4 268c2ecf20Sopenharmony_ci#define MVNETA_BM_START_MASK BIT(0) 278c2ecf20Sopenharmony_ci#define MVNETA_BM_STOP_MASK BIT(1) 288c2ecf20Sopenharmony_ci#define MVNETA_BM_PAUSE_MASK BIT(2) 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci/* BM Xbar interface Register */ 318c2ecf20Sopenharmony_ci#define MVNETA_BM_XBAR_01_REG 0x8 328c2ecf20Sopenharmony_ci#define MVNETA_BM_XBAR_23_REG 0xc 338c2ecf20Sopenharmony_ci#define MVNETA_BM_XBAR_POOL_REG(pool) \ 348c2ecf20Sopenharmony_ci (((pool) < 2) ? MVNETA_BM_XBAR_01_REG : MVNETA_BM_XBAR_23_REG) 358c2ecf20Sopenharmony_ci#define MVNETA_BM_TARGET_ID_OFFS(pool) (((pool) & 1) ? 16 : 0) 368c2ecf20Sopenharmony_ci#define MVNETA_BM_TARGET_ID_MASK(pool) \ 378c2ecf20Sopenharmony_ci (0xf << MVNETA_BM_TARGET_ID_OFFS(pool)) 388c2ecf20Sopenharmony_ci#define MVNETA_BM_TARGET_ID_VAL(pool, id) \ 398c2ecf20Sopenharmony_ci ((id) << MVNETA_BM_TARGET_ID_OFFS(pool)) 408c2ecf20Sopenharmony_ci#define MVNETA_BM_XBAR_ATTR_OFFS(pool) (((pool) & 1) ? 20 : 4) 418c2ecf20Sopenharmony_ci#define MVNETA_BM_XBAR_ATTR_MASK(pool) \ 428c2ecf20Sopenharmony_ci (0xff << MVNETA_BM_XBAR_ATTR_OFFS(pool)) 438c2ecf20Sopenharmony_ci#define MVNETA_BM_XBAR_ATTR_VAL(pool, attr) \ 448c2ecf20Sopenharmony_ci ((attr) << MVNETA_BM_XBAR_ATTR_OFFS(pool)) 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci/* Address of External Buffer Pointers Pool Register */ 478c2ecf20Sopenharmony_ci#define MVNETA_BM_POOL_BASE_REG(pool) (0x10 + ((pool) << 4)) 488c2ecf20Sopenharmony_ci#define MVNETA_BM_POOL_ENABLE_MASK BIT(0) 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci/* External Buffer Pointers Pool RD pointer Register */ 518c2ecf20Sopenharmony_ci#define MVNETA_BM_POOL_READ_PTR_REG(pool) (0x14 + ((pool) << 4)) 528c2ecf20Sopenharmony_ci#define MVNETA_BM_POOL_SET_READ_PTR_MASK 0xfffc 538c2ecf20Sopenharmony_ci#define MVNETA_BM_POOL_GET_READ_PTR_OFFS 16 548c2ecf20Sopenharmony_ci#define MVNETA_BM_POOL_GET_READ_PTR_MASK 0xfffc0000 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci/* External Buffer Pointers Pool WR pointer */ 578c2ecf20Sopenharmony_ci#define MVNETA_BM_POOL_WRITE_PTR_REG(pool) (0x18 + ((pool) << 4)) 588c2ecf20Sopenharmony_ci#define MVNETA_BM_POOL_SET_WRITE_PTR_OFFS 0 598c2ecf20Sopenharmony_ci#define MVNETA_BM_POOL_SET_WRITE_PTR_MASK 0xfffc 608c2ecf20Sopenharmony_ci#define MVNETA_BM_POOL_GET_WRITE_PTR_OFFS 16 618c2ecf20Sopenharmony_ci#define MVNETA_BM_POOL_GET_WRITE_PTR_MASK 0xfffc0000 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci/* External Buffer Pointers Pool Size Register */ 648c2ecf20Sopenharmony_ci#define MVNETA_BM_POOL_SIZE_REG(pool) (0x1c + ((pool) << 4)) 658c2ecf20Sopenharmony_ci#define MVNETA_BM_POOL_SIZE_MASK 0x3fff 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci/* BM Interrupt Cause Register */ 688c2ecf20Sopenharmony_ci#define MVNETA_BM_INTR_CAUSE_REG (0x50) 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci/* BM interrupt Mask Register */ 718c2ecf20Sopenharmony_ci#define MVNETA_BM_INTR_MASK_REG (0x54) 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci/* Other definitions */ 748c2ecf20Sopenharmony_ci#define MVNETA_BM_SHORT_PKT_SIZE 256 758c2ecf20Sopenharmony_ci#define MVNETA_BM_POOLS_NUM 4 768c2ecf20Sopenharmony_ci#define MVNETA_BM_POOL_CAP_MIN 128 778c2ecf20Sopenharmony_ci#define MVNETA_BM_POOL_CAP_DEF 2048 788c2ecf20Sopenharmony_ci#define MVNETA_BM_POOL_CAP_MAX \ 798c2ecf20Sopenharmony_ci (16 * 1024 - MVNETA_BM_POOL_CAP_ALIGN) 808c2ecf20Sopenharmony_ci#define MVNETA_BM_POOL_CAP_ALIGN 32 818c2ecf20Sopenharmony_ci#define MVNETA_BM_POOL_PTR_ALIGN 32 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci#define MVNETA_BM_POOL_ACCESS_OFFS 8 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci#define MVNETA_BM_BPPI_SIZE 0x100000 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci#define MVNETA_RX_BUF_SIZE(pkt_size) ((pkt_size) + NET_SKB_PAD) 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_cienum mvneta_bm_type { 908c2ecf20Sopenharmony_ci MVNETA_BM_FREE, 918c2ecf20Sopenharmony_ci MVNETA_BM_LONG, 928c2ecf20Sopenharmony_ci MVNETA_BM_SHORT 938c2ecf20Sopenharmony_ci}; 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_cistruct mvneta_bm { 968c2ecf20Sopenharmony_ci void __iomem *reg_base; 978c2ecf20Sopenharmony_ci struct clk *clk; 988c2ecf20Sopenharmony_ci struct platform_device *pdev; 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci struct gen_pool *bppi_pool; 1018c2ecf20Sopenharmony_ci /* BPPI virtual base address */ 1028c2ecf20Sopenharmony_ci void __iomem *bppi_virt_addr; 1038c2ecf20Sopenharmony_ci /* BPPI physical base address */ 1048c2ecf20Sopenharmony_ci dma_addr_t bppi_phys_addr; 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci /* BM pools */ 1078c2ecf20Sopenharmony_ci struct mvneta_bm_pool *bm_pools; 1088c2ecf20Sopenharmony_ci}; 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_cistruct mvneta_bm_pool { 1118c2ecf20Sopenharmony_ci struct hwbm_pool hwbm_pool; 1128c2ecf20Sopenharmony_ci /* Pool number in the range 0-3 */ 1138c2ecf20Sopenharmony_ci u8 id; 1148c2ecf20Sopenharmony_ci enum mvneta_bm_type type; 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci /* Packet size */ 1178c2ecf20Sopenharmony_ci int pkt_size; 1188c2ecf20Sopenharmony_ci /* Size of the buffer acces through DMA*/ 1198c2ecf20Sopenharmony_ci u32 buf_size; 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci /* BPPE virtual base address */ 1228c2ecf20Sopenharmony_ci u32 *virt_addr; 1238c2ecf20Sopenharmony_ci /* BPPE physical base address */ 1248c2ecf20Sopenharmony_ci dma_addr_t phys_addr; 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci /* Ports using BM pool */ 1278c2ecf20Sopenharmony_ci u8 port_map; 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci struct mvneta_bm *priv; 1308c2ecf20Sopenharmony_ci}; 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci/* Declarations and definitions */ 1338c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_MVNETA_BM) 1348c2ecf20Sopenharmony_cistruct mvneta_bm *mvneta_bm_get(struct device_node *node); 1358c2ecf20Sopenharmony_civoid mvneta_bm_put(struct mvneta_bm *priv); 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_civoid mvneta_bm_pool_destroy(struct mvneta_bm *priv, 1388c2ecf20Sopenharmony_ci struct mvneta_bm_pool *bm_pool, u8 port_map); 1398c2ecf20Sopenharmony_civoid mvneta_bm_bufs_free(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool, 1408c2ecf20Sopenharmony_ci u8 port_map); 1418c2ecf20Sopenharmony_ciint mvneta_bm_construct(struct hwbm_pool *hwbm_pool, void *buf); 1428c2ecf20Sopenharmony_ciint mvneta_bm_pool_refill(struct mvneta_bm *priv, 1438c2ecf20Sopenharmony_ci struct mvneta_bm_pool *bm_pool); 1448c2ecf20Sopenharmony_cistruct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv, u8 pool_id, 1458c2ecf20Sopenharmony_ci enum mvneta_bm_type type, u8 port_id, 1468c2ecf20Sopenharmony_ci int pkt_size); 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_cistatic inline void mvneta_bm_pool_put_bp(struct mvneta_bm *priv, 1498c2ecf20Sopenharmony_ci struct mvneta_bm_pool *bm_pool, 1508c2ecf20Sopenharmony_ci dma_addr_t buf_phys_addr) 1518c2ecf20Sopenharmony_ci{ 1528c2ecf20Sopenharmony_ci writel_relaxed(buf_phys_addr, priv->bppi_virt_addr + 1538c2ecf20Sopenharmony_ci (bm_pool->id << MVNETA_BM_POOL_ACCESS_OFFS)); 1548c2ecf20Sopenharmony_ci} 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_cistatic inline u32 mvneta_bm_pool_get_bp(struct mvneta_bm *priv, 1578c2ecf20Sopenharmony_ci struct mvneta_bm_pool *bm_pool) 1588c2ecf20Sopenharmony_ci{ 1598c2ecf20Sopenharmony_ci return readl_relaxed(priv->bppi_virt_addr + 1608c2ecf20Sopenharmony_ci (bm_pool->id << MVNETA_BM_POOL_ACCESS_OFFS)); 1618c2ecf20Sopenharmony_ci} 1628c2ecf20Sopenharmony_ci#else 1638c2ecf20Sopenharmony_cistatic inline void mvneta_bm_pool_destroy(struct mvneta_bm *priv, 1648c2ecf20Sopenharmony_ci struct mvneta_bm_pool *bm_pool, 1658c2ecf20Sopenharmony_ci u8 port_map) {} 1668c2ecf20Sopenharmony_cistatic inline void mvneta_bm_bufs_free(struct mvneta_bm *priv, 1678c2ecf20Sopenharmony_ci struct mvneta_bm_pool *bm_pool, 1688c2ecf20Sopenharmony_ci u8 port_map) {} 1698c2ecf20Sopenharmony_cistatic inline int mvneta_bm_construct(struct hwbm_pool *hwbm_pool, void *buf) 1708c2ecf20Sopenharmony_ci{ return 0; } 1718c2ecf20Sopenharmony_cistatic inline int mvneta_bm_pool_refill(struct mvneta_bm *priv, 1728c2ecf20Sopenharmony_ci struct mvneta_bm_pool *bm_pool) 1738c2ecf20Sopenharmony_ci{ return 0; } 1748c2ecf20Sopenharmony_cistatic inline struct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv, 1758c2ecf20Sopenharmony_ci u8 pool_id, 1768c2ecf20Sopenharmony_ci enum mvneta_bm_type type, 1778c2ecf20Sopenharmony_ci u8 port_id, 1788c2ecf20Sopenharmony_ci int pkt_size) 1798c2ecf20Sopenharmony_ci{ return NULL; } 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_cistatic inline void mvneta_bm_pool_put_bp(struct mvneta_bm *priv, 1828c2ecf20Sopenharmony_ci struct mvneta_bm_pool *bm_pool, 1838c2ecf20Sopenharmony_ci dma_addr_t buf_phys_addr) {} 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_cistatic inline u32 mvneta_bm_pool_get_bp(struct mvneta_bm *priv, 1868c2ecf20Sopenharmony_ci struct mvneta_bm_pool *bm_pool) 1878c2ecf20Sopenharmony_ci{ return 0; } 1888c2ecf20Sopenharmony_cistatic inline struct mvneta_bm *mvneta_bm_get(struct device_node *node) 1898c2ecf20Sopenharmony_ci{ return NULL; } 1908c2ecf20Sopenharmony_cistatic inline void mvneta_bm_put(struct mvneta_bm *priv) {} 1918c2ecf20Sopenharmony_ci#endif /* CONFIG_MVNETA_BM */ 1928c2ecf20Sopenharmony_ci#endif 193