18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2004-2013 Synopsys, Inc. (www.synopsys.com) 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Registers and bits definitions of ARC EMAC 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#ifndef ARC_EMAC_H 98c2ecf20Sopenharmony_ci#define ARC_EMAC_H 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <linux/device.h> 128c2ecf20Sopenharmony_ci#include <linux/dma-mapping.h> 138c2ecf20Sopenharmony_ci#include <linux/netdevice.h> 148c2ecf20Sopenharmony_ci#include <linux/phy.h> 158c2ecf20Sopenharmony_ci#include <linux/clk.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci/* STATUS and ENABLE Register bit masks */ 188c2ecf20Sopenharmony_ci#define TXINT_MASK (1 << 0) /* Transmit interrupt */ 198c2ecf20Sopenharmony_ci#define RXINT_MASK (1 << 1) /* Receive interrupt */ 208c2ecf20Sopenharmony_ci#define ERR_MASK (1 << 2) /* Error interrupt */ 218c2ecf20Sopenharmony_ci#define TXCH_MASK (1 << 3) /* Transmit chaining error interrupt */ 228c2ecf20Sopenharmony_ci#define MSER_MASK (1 << 4) /* Missed packet counter error */ 238c2ecf20Sopenharmony_ci#define RXCR_MASK (1 << 8) /* RXCRCERR counter rolled over */ 248c2ecf20Sopenharmony_ci#define RXFR_MASK (1 << 9) /* RXFRAMEERR counter rolled over */ 258c2ecf20Sopenharmony_ci#define RXFL_MASK (1 << 10) /* RXOFLOWERR counter rolled over */ 268c2ecf20Sopenharmony_ci#define MDIO_MASK (1 << 12) /* MDIO complete interrupt */ 278c2ecf20Sopenharmony_ci#define TXPL_MASK (1 << 31) /* Force polling of BD by EMAC */ 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci/* CONTROL Register bit masks */ 308c2ecf20Sopenharmony_ci#define EN_MASK (1 << 0) /* VMAC enable */ 318c2ecf20Sopenharmony_ci#define TXRN_MASK (1 << 3) /* TX enable */ 328c2ecf20Sopenharmony_ci#define RXRN_MASK (1 << 4) /* RX enable */ 338c2ecf20Sopenharmony_ci#define DSBC_MASK (1 << 8) /* Disable receive broadcast */ 348c2ecf20Sopenharmony_ci#define ENFL_MASK (1 << 10) /* Enable Full-duplex */ 358c2ecf20Sopenharmony_ci#define PROM_MASK (1 << 11) /* Promiscuous mode */ 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci/* Buffer descriptor INFO bit masks */ 388c2ecf20Sopenharmony_ci#define OWN_MASK (1 << 31) /* 0-CPU or 1-EMAC owns buffer */ 398c2ecf20Sopenharmony_ci#define FIRST_MASK (1 << 16) /* First buffer in chain */ 408c2ecf20Sopenharmony_ci#define LAST_MASK (1 << 17) /* Last buffer in chain */ 418c2ecf20Sopenharmony_ci#define LEN_MASK 0x000007FF /* last 11 bits */ 428c2ecf20Sopenharmony_ci#define CRLS (1 << 21) 438c2ecf20Sopenharmony_ci#define DEFR (1 << 22) 448c2ecf20Sopenharmony_ci#define DROP (1 << 23) 458c2ecf20Sopenharmony_ci#define RTRY (1 << 24) 468c2ecf20Sopenharmony_ci#define LTCL (1 << 28) 478c2ecf20Sopenharmony_ci#define UFLO (1 << 29) 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci#define FOR_EMAC OWN_MASK 508c2ecf20Sopenharmony_ci#define FOR_CPU 0 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci/* ARC EMAC register set combines entries for MAC and MDIO */ 538c2ecf20Sopenharmony_cienum { 548c2ecf20Sopenharmony_ci R_ID = 0, 558c2ecf20Sopenharmony_ci R_STATUS, 568c2ecf20Sopenharmony_ci R_ENABLE, 578c2ecf20Sopenharmony_ci R_CTRL, 588c2ecf20Sopenharmony_ci R_POLLRATE, 598c2ecf20Sopenharmony_ci R_RXERR, 608c2ecf20Sopenharmony_ci R_MISS, 618c2ecf20Sopenharmony_ci R_TX_RING, 628c2ecf20Sopenharmony_ci R_RX_RING, 638c2ecf20Sopenharmony_ci R_ADDRL, 648c2ecf20Sopenharmony_ci R_ADDRH, 658c2ecf20Sopenharmony_ci R_LAFL, 668c2ecf20Sopenharmony_ci R_LAFH, 678c2ecf20Sopenharmony_ci R_MDIO, 688c2ecf20Sopenharmony_ci}; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci#define TX_TIMEOUT (400 * HZ / 1000) /* Transmission timeout */ 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci#define ARC_EMAC_NAPI_WEIGHT 40 /* Workload for NAPI */ 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci#define EMAC_BUFFER_SIZE 1536 /* EMAC buffer size */ 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci/** 778c2ecf20Sopenharmony_ci * struct arc_emac_bd - EMAC buffer descriptor (BD). 788c2ecf20Sopenharmony_ci * 798c2ecf20Sopenharmony_ci * @info: Contains status information on the buffer itself. 808c2ecf20Sopenharmony_ci * @data: 32-bit byte addressable pointer to the packet data. 818c2ecf20Sopenharmony_ci */ 828c2ecf20Sopenharmony_cistruct arc_emac_bd { 838c2ecf20Sopenharmony_ci __le32 info; 848c2ecf20Sopenharmony_ci dma_addr_t data; 858c2ecf20Sopenharmony_ci}; 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci/* Number of Rx/Tx BD's */ 888c2ecf20Sopenharmony_ci#define RX_BD_NUM 128 898c2ecf20Sopenharmony_ci#define TX_BD_NUM 128 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci#define RX_RING_SZ (RX_BD_NUM * sizeof(struct arc_emac_bd)) 928c2ecf20Sopenharmony_ci#define TX_RING_SZ (TX_BD_NUM * sizeof(struct arc_emac_bd)) 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci/** 958c2ecf20Sopenharmony_ci * struct buffer_state - Stores Rx/Tx buffer state. 968c2ecf20Sopenharmony_ci * @sk_buff: Pointer to socket buffer. 978c2ecf20Sopenharmony_ci * @addr: Start address of DMA-mapped memory region. 988c2ecf20Sopenharmony_ci * @len: Length of DMA-mapped memory region. 998c2ecf20Sopenharmony_ci */ 1008c2ecf20Sopenharmony_cistruct buffer_state { 1018c2ecf20Sopenharmony_ci struct sk_buff *skb; 1028c2ecf20Sopenharmony_ci DEFINE_DMA_UNMAP_ADDR(addr); 1038c2ecf20Sopenharmony_ci DEFINE_DMA_UNMAP_LEN(len); 1048c2ecf20Sopenharmony_ci}; 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_cistruct arc_emac_mdio_bus_data { 1078c2ecf20Sopenharmony_ci struct gpio_desc *reset_gpio; 1088c2ecf20Sopenharmony_ci int msec; 1098c2ecf20Sopenharmony_ci}; 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci/** 1128c2ecf20Sopenharmony_ci * struct arc_emac_priv - Storage of EMAC's private information. 1138c2ecf20Sopenharmony_ci * @dev: Pointer to the current device. 1148c2ecf20Sopenharmony_ci * @phy_dev: Pointer to attached PHY device. 1158c2ecf20Sopenharmony_ci * @bus: Pointer to the current MII bus. 1168c2ecf20Sopenharmony_ci * @regs: Base address of EMAC memory-mapped control registers. 1178c2ecf20Sopenharmony_ci * @napi: Structure for NAPI. 1188c2ecf20Sopenharmony_ci * @rxbd: Pointer to Rx BD ring. 1198c2ecf20Sopenharmony_ci * @txbd: Pointer to Tx BD ring. 1208c2ecf20Sopenharmony_ci * @rxbd_dma: DMA handle for Rx BD ring. 1218c2ecf20Sopenharmony_ci * @txbd_dma: DMA handle for Tx BD ring. 1228c2ecf20Sopenharmony_ci * @rx_buff: Storage for Rx buffers states. 1238c2ecf20Sopenharmony_ci * @tx_buff: Storage for Tx buffers states. 1248c2ecf20Sopenharmony_ci * @txbd_curr: Index of Tx BD to use on the next "ndo_start_xmit". 1258c2ecf20Sopenharmony_ci * @txbd_dirty: Index of Tx BD to free on the next Tx interrupt. 1268c2ecf20Sopenharmony_ci * @last_rx_bd: Index of the last Rx BD we've got from EMAC. 1278c2ecf20Sopenharmony_ci * @link: PHY's last seen link state. 1288c2ecf20Sopenharmony_ci * @duplex: PHY's last set duplex mode. 1298c2ecf20Sopenharmony_ci * @speed: PHY's last set speed. 1308c2ecf20Sopenharmony_ci */ 1318c2ecf20Sopenharmony_cistruct arc_emac_priv { 1328c2ecf20Sopenharmony_ci const char *drv_name; 1338c2ecf20Sopenharmony_ci void (*set_mac_speed)(void *priv, unsigned int speed); 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci /* Devices */ 1368c2ecf20Sopenharmony_ci struct device *dev; 1378c2ecf20Sopenharmony_ci struct mii_bus *bus; 1388c2ecf20Sopenharmony_ci struct arc_emac_mdio_bus_data bus_data; 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci void __iomem *regs; 1418c2ecf20Sopenharmony_ci struct clk *clk; 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci struct napi_struct napi; 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci struct arc_emac_bd *rxbd; 1468c2ecf20Sopenharmony_ci struct arc_emac_bd *txbd; 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci dma_addr_t rxbd_dma; 1498c2ecf20Sopenharmony_ci dma_addr_t txbd_dma; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci struct buffer_state rx_buff[RX_BD_NUM]; 1528c2ecf20Sopenharmony_ci struct buffer_state tx_buff[TX_BD_NUM]; 1538c2ecf20Sopenharmony_ci unsigned int txbd_curr; 1548c2ecf20Sopenharmony_ci unsigned int txbd_dirty; 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci unsigned int last_rx_bd; 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci unsigned int link; 1598c2ecf20Sopenharmony_ci unsigned int duplex; 1608c2ecf20Sopenharmony_ci unsigned int speed; 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci unsigned int rx_missed_errors; 1638c2ecf20Sopenharmony_ci}; 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci/** 1668c2ecf20Sopenharmony_ci * arc_reg_set - Sets EMAC register with provided value. 1678c2ecf20Sopenharmony_ci * @priv: Pointer to ARC EMAC private data structure. 1688c2ecf20Sopenharmony_ci * @reg: Register offset from base address. 1698c2ecf20Sopenharmony_ci * @value: Value to set in register. 1708c2ecf20Sopenharmony_ci */ 1718c2ecf20Sopenharmony_cistatic inline void arc_reg_set(struct arc_emac_priv *priv, int reg, int value) 1728c2ecf20Sopenharmony_ci{ 1738c2ecf20Sopenharmony_ci iowrite32(value, priv->regs + reg * sizeof(int)); 1748c2ecf20Sopenharmony_ci} 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci/** 1778c2ecf20Sopenharmony_ci * arc_reg_get - Gets value of specified EMAC register. 1788c2ecf20Sopenharmony_ci * @priv: Pointer to ARC EMAC private data structure. 1798c2ecf20Sopenharmony_ci * @reg: Register offset from base address. 1808c2ecf20Sopenharmony_ci * 1818c2ecf20Sopenharmony_ci * returns: Value of requested register. 1828c2ecf20Sopenharmony_ci */ 1838c2ecf20Sopenharmony_cistatic inline unsigned int arc_reg_get(struct arc_emac_priv *priv, int reg) 1848c2ecf20Sopenharmony_ci{ 1858c2ecf20Sopenharmony_ci return ioread32(priv->regs + reg * sizeof(int)); 1868c2ecf20Sopenharmony_ci} 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci/** 1898c2ecf20Sopenharmony_ci * arc_reg_or - Applies mask to specified EMAC register - ("reg" | "mask"). 1908c2ecf20Sopenharmony_ci * @priv: Pointer to ARC EMAC private data structure. 1918c2ecf20Sopenharmony_ci * @reg: Register offset from base address. 1928c2ecf20Sopenharmony_ci * @mask: Mask to apply to specified register. 1938c2ecf20Sopenharmony_ci * 1948c2ecf20Sopenharmony_ci * This function reads initial register value, then applies provided mask 1958c2ecf20Sopenharmony_ci * to it and then writes register back. 1968c2ecf20Sopenharmony_ci */ 1978c2ecf20Sopenharmony_cistatic inline void arc_reg_or(struct arc_emac_priv *priv, int reg, int mask) 1988c2ecf20Sopenharmony_ci{ 1998c2ecf20Sopenharmony_ci unsigned int value = arc_reg_get(priv, reg); 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci arc_reg_set(priv, reg, value | mask); 2028c2ecf20Sopenharmony_ci} 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci/** 2058c2ecf20Sopenharmony_ci * arc_reg_clr - Applies mask to specified EMAC register - ("reg" & ~"mask"). 2068c2ecf20Sopenharmony_ci * @priv: Pointer to ARC EMAC private data structure. 2078c2ecf20Sopenharmony_ci * @reg: Register offset from base address. 2088c2ecf20Sopenharmony_ci * @mask: Mask to apply to specified register. 2098c2ecf20Sopenharmony_ci * 2108c2ecf20Sopenharmony_ci * This function reads initial register value, then applies provided mask 2118c2ecf20Sopenharmony_ci * to it and then writes register back. 2128c2ecf20Sopenharmony_ci */ 2138c2ecf20Sopenharmony_cistatic inline void arc_reg_clr(struct arc_emac_priv *priv, int reg, int mask) 2148c2ecf20Sopenharmony_ci{ 2158c2ecf20Sopenharmony_ci unsigned int value = arc_reg_get(priv, reg); 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci arc_reg_set(priv, reg, value & ~mask); 2188c2ecf20Sopenharmony_ci} 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ciint arc_mdio_probe(struct arc_emac_priv *priv); 2218c2ecf20Sopenharmony_ciint arc_mdio_remove(struct arc_emac_priv *priv); 2228c2ecf20Sopenharmony_ciint arc_emac_probe(struct net_device *ndev, int interface); 2238c2ecf20Sopenharmony_ciint arc_emac_remove(struct net_device *ndev); 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci#endif /* ARC_EMAC_H */ 226