162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2004-2013 Synopsys, Inc. (www.synopsys.com) 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Registers and bits definitions of ARC EMAC 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#ifndef ARC_EMAC_H 962306a36Sopenharmony_ci#define ARC_EMAC_H 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <linux/device.h> 1262306a36Sopenharmony_ci#include <linux/dma-mapping.h> 1362306a36Sopenharmony_ci#include <linux/netdevice.h> 1462306a36Sopenharmony_ci#include <linux/phy.h> 1562306a36Sopenharmony_ci#include <linux/clk.h> 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci/* STATUS and ENABLE Register bit masks */ 1862306a36Sopenharmony_ci#define TXINT_MASK (1 << 0) /* Transmit interrupt */ 1962306a36Sopenharmony_ci#define RXINT_MASK (1 << 1) /* Receive interrupt */ 2062306a36Sopenharmony_ci#define ERR_MASK (1 << 2) /* Error interrupt */ 2162306a36Sopenharmony_ci#define TXCH_MASK (1 << 3) /* Transmit chaining error interrupt */ 2262306a36Sopenharmony_ci#define MSER_MASK (1 << 4) /* Missed packet counter error */ 2362306a36Sopenharmony_ci#define RXCR_MASK (1 << 8) /* RXCRCERR counter rolled over */ 2462306a36Sopenharmony_ci#define RXFR_MASK (1 << 9) /* RXFRAMEERR counter rolled over */ 2562306a36Sopenharmony_ci#define RXFL_MASK (1 << 10) /* RXOFLOWERR counter rolled over */ 2662306a36Sopenharmony_ci#define MDIO_MASK (1 << 12) /* MDIO complete interrupt */ 2762306a36Sopenharmony_ci#define TXPL_MASK (1 << 31) /* Force polling of BD by EMAC */ 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci/* CONTROL Register bit masks */ 3062306a36Sopenharmony_ci#define EN_MASK (1 << 0) /* VMAC enable */ 3162306a36Sopenharmony_ci#define TXRN_MASK (1 << 3) /* TX enable */ 3262306a36Sopenharmony_ci#define RXRN_MASK (1 << 4) /* RX enable */ 3362306a36Sopenharmony_ci#define DSBC_MASK (1 << 8) /* Disable receive broadcast */ 3462306a36Sopenharmony_ci#define ENFL_MASK (1 << 10) /* Enable Full-duplex */ 3562306a36Sopenharmony_ci#define PROM_MASK (1 << 11) /* Promiscuous mode */ 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci/* Buffer descriptor INFO bit masks */ 3862306a36Sopenharmony_ci#define OWN_MASK (1 << 31) /* 0-CPU or 1-EMAC owns buffer */ 3962306a36Sopenharmony_ci#define FIRST_MASK (1 << 16) /* First buffer in chain */ 4062306a36Sopenharmony_ci#define LAST_MASK (1 << 17) /* Last buffer in chain */ 4162306a36Sopenharmony_ci#define LEN_MASK 0x000007FF /* last 11 bits */ 4262306a36Sopenharmony_ci#define CRLS (1 << 21) 4362306a36Sopenharmony_ci#define DEFR (1 << 22) 4462306a36Sopenharmony_ci#define DROP (1 << 23) 4562306a36Sopenharmony_ci#define RTRY (1 << 24) 4662306a36Sopenharmony_ci#define LTCL (1 << 28) 4762306a36Sopenharmony_ci#define UFLO (1 << 29) 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci#define FOR_EMAC OWN_MASK 5062306a36Sopenharmony_ci#define FOR_CPU 0 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci/* ARC EMAC register set combines entries for MAC and MDIO */ 5362306a36Sopenharmony_cienum { 5462306a36Sopenharmony_ci R_ID = 0, 5562306a36Sopenharmony_ci R_STATUS, 5662306a36Sopenharmony_ci R_ENABLE, 5762306a36Sopenharmony_ci R_CTRL, 5862306a36Sopenharmony_ci R_POLLRATE, 5962306a36Sopenharmony_ci R_RXERR, 6062306a36Sopenharmony_ci R_MISS, 6162306a36Sopenharmony_ci R_TX_RING, 6262306a36Sopenharmony_ci R_RX_RING, 6362306a36Sopenharmony_ci R_ADDRL, 6462306a36Sopenharmony_ci R_ADDRH, 6562306a36Sopenharmony_ci R_LAFL, 6662306a36Sopenharmony_ci R_LAFH, 6762306a36Sopenharmony_ci R_MDIO, 6862306a36Sopenharmony_ci}; 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci#define TX_TIMEOUT (400 * HZ / 1000) /* Transmission timeout */ 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci#define ARC_EMAC_NAPI_WEIGHT 40 /* Workload for NAPI */ 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci#define EMAC_BUFFER_SIZE 1536 /* EMAC buffer size */ 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci/** 7762306a36Sopenharmony_ci * struct arc_emac_bd - EMAC buffer descriptor (BD). 7862306a36Sopenharmony_ci * 7962306a36Sopenharmony_ci * @info: Contains status information on the buffer itself. 8062306a36Sopenharmony_ci * @data: 32-bit byte addressable pointer to the packet data. 8162306a36Sopenharmony_ci */ 8262306a36Sopenharmony_cistruct arc_emac_bd { 8362306a36Sopenharmony_ci __le32 info; 8462306a36Sopenharmony_ci dma_addr_t data; 8562306a36Sopenharmony_ci}; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci/* Number of Rx/Tx BD's */ 8862306a36Sopenharmony_ci#define RX_BD_NUM 128 8962306a36Sopenharmony_ci#define TX_BD_NUM 128 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci#define RX_RING_SZ (RX_BD_NUM * sizeof(struct arc_emac_bd)) 9262306a36Sopenharmony_ci#define TX_RING_SZ (TX_BD_NUM * sizeof(struct arc_emac_bd)) 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci/** 9562306a36Sopenharmony_ci * struct buffer_state - Stores Rx/Tx buffer state. 9662306a36Sopenharmony_ci * @sk_buff: Pointer to socket buffer. 9762306a36Sopenharmony_ci * @addr: Start address of DMA-mapped memory region. 9862306a36Sopenharmony_ci * @len: Length of DMA-mapped memory region. 9962306a36Sopenharmony_ci */ 10062306a36Sopenharmony_cistruct buffer_state { 10162306a36Sopenharmony_ci struct sk_buff *skb; 10262306a36Sopenharmony_ci DEFINE_DMA_UNMAP_ADDR(addr); 10362306a36Sopenharmony_ci DEFINE_DMA_UNMAP_LEN(len); 10462306a36Sopenharmony_ci}; 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_cistruct arc_emac_mdio_bus_data { 10762306a36Sopenharmony_ci struct gpio_desc *reset_gpio; 10862306a36Sopenharmony_ci int msec; 10962306a36Sopenharmony_ci}; 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci/** 11262306a36Sopenharmony_ci * struct arc_emac_priv - Storage of EMAC's private information. 11362306a36Sopenharmony_ci * @dev: Pointer to the current device. 11462306a36Sopenharmony_ci * @phy_dev: Pointer to attached PHY device. 11562306a36Sopenharmony_ci * @bus: Pointer to the current MII bus. 11662306a36Sopenharmony_ci * @regs: Base address of EMAC memory-mapped control registers. 11762306a36Sopenharmony_ci * @napi: Structure for NAPI. 11862306a36Sopenharmony_ci * @rxbd: Pointer to Rx BD ring. 11962306a36Sopenharmony_ci * @txbd: Pointer to Tx BD ring. 12062306a36Sopenharmony_ci * @rxbd_dma: DMA handle for Rx BD ring. 12162306a36Sopenharmony_ci * @txbd_dma: DMA handle for Tx BD ring. 12262306a36Sopenharmony_ci * @rx_buff: Storage for Rx buffers states. 12362306a36Sopenharmony_ci * @tx_buff: Storage for Tx buffers states. 12462306a36Sopenharmony_ci * @txbd_curr: Index of Tx BD to use on the next "ndo_start_xmit". 12562306a36Sopenharmony_ci * @txbd_dirty: Index of Tx BD to free on the next Tx interrupt. 12662306a36Sopenharmony_ci * @last_rx_bd: Index of the last Rx BD we've got from EMAC. 12762306a36Sopenharmony_ci * @link: PHY's last seen link state. 12862306a36Sopenharmony_ci * @duplex: PHY's last set duplex mode. 12962306a36Sopenharmony_ci * @speed: PHY's last set speed. 13062306a36Sopenharmony_ci */ 13162306a36Sopenharmony_cistruct arc_emac_priv { 13262306a36Sopenharmony_ci const char *drv_name; 13362306a36Sopenharmony_ci void (*set_mac_speed)(void *priv, unsigned int speed); 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci /* Devices */ 13662306a36Sopenharmony_ci struct device *dev; 13762306a36Sopenharmony_ci struct mii_bus *bus; 13862306a36Sopenharmony_ci struct arc_emac_mdio_bus_data bus_data; 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci void __iomem *regs; 14162306a36Sopenharmony_ci struct clk *clk; 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci struct napi_struct napi; 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci struct arc_emac_bd *rxbd; 14662306a36Sopenharmony_ci struct arc_emac_bd *txbd; 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci dma_addr_t rxbd_dma; 14962306a36Sopenharmony_ci dma_addr_t txbd_dma; 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci struct buffer_state rx_buff[RX_BD_NUM]; 15262306a36Sopenharmony_ci struct buffer_state tx_buff[TX_BD_NUM]; 15362306a36Sopenharmony_ci unsigned int txbd_curr; 15462306a36Sopenharmony_ci unsigned int txbd_dirty; 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci unsigned int last_rx_bd; 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci unsigned int link; 15962306a36Sopenharmony_ci unsigned int duplex; 16062306a36Sopenharmony_ci unsigned int speed; 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci unsigned int rx_missed_errors; 16362306a36Sopenharmony_ci}; 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci/** 16662306a36Sopenharmony_ci * arc_reg_set - Sets EMAC register with provided value. 16762306a36Sopenharmony_ci * @priv: Pointer to ARC EMAC private data structure. 16862306a36Sopenharmony_ci * @reg: Register offset from base address. 16962306a36Sopenharmony_ci * @value: Value to set in register. 17062306a36Sopenharmony_ci */ 17162306a36Sopenharmony_cistatic inline void arc_reg_set(struct arc_emac_priv *priv, int reg, int value) 17262306a36Sopenharmony_ci{ 17362306a36Sopenharmony_ci iowrite32(value, priv->regs + reg * sizeof(int)); 17462306a36Sopenharmony_ci} 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci/** 17762306a36Sopenharmony_ci * arc_reg_get - Gets value of specified EMAC register. 17862306a36Sopenharmony_ci * @priv: Pointer to ARC EMAC private data structure. 17962306a36Sopenharmony_ci * @reg: Register offset from base address. 18062306a36Sopenharmony_ci * 18162306a36Sopenharmony_ci * returns: Value of requested register. 18262306a36Sopenharmony_ci */ 18362306a36Sopenharmony_cistatic inline unsigned int arc_reg_get(struct arc_emac_priv *priv, int reg) 18462306a36Sopenharmony_ci{ 18562306a36Sopenharmony_ci return ioread32(priv->regs + reg * sizeof(int)); 18662306a36Sopenharmony_ci} 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ci/** 18962306a36Sopenharmony_ci * arc_reg_or - Applies mask to specified EMAC register - ("reg" | "mask"). 19062306a36Sopenharmony_ci * @priv: Pointer to ARC EMAC private data structure. 19162306a36Sopenharmony_ci * @reg: Register offset from base address. 19262306a36Sopenharmony_ci * @mask: Mask to apply to specified register. 19362306a36Sopenharmony_ci * 19462306a36Sopenharmony_ci * This function reads initial register value, then applies provided mask 19562306a36Sopenharmony_ci * to it and then writes register back. 19662306a36Sopenharmony_ci */ 19762306a36Sopenharmony_cistatic inline void arc_reg_or(struct arc_emac_priv *priv, int reg, int mask) 19862306a36Sopenharmony_ci{ 19962306a36Sopenharmony_ci unsigned int value = arc_reg_get(priv, reg); 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci arc_reg_set(priv, reg, value | mask); 20262306a36Sopenharmony_ci} 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci/** 20562306a36Sopenharmony_ci * arc_reg_clr - Applies mask to specified EMAC register - ("reg" & ~"mask"). 20662306a36Sopenharmony_ci * @priv: Pointer to ARC EMAC private data structure. 20762306a36Sopenharmony_ci * @reg: Register offset from base address. 20862306a36Sopenharmony_ci * @mask: Mask to apply to specified register. 20962306a36Sopenharmony_ci * 21062306a36Sopenharmony_ci * This function reads initial register value, then applies provided mask 21162306a36Sopenharmony_ci * to it and then writes register back. 21262306a36Sopenharmony_ci */ 21362306a36Sopenharmony_cistatic inline void arc_reg_clr(struct arc_emac_priv *priv, int reg, int mask) 21462306a36Sopenharmony_ci{ 21562306a36Sopenharmony_ci unsigned int value = arc_reg_get(priv, reg); 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci arc_reg_set(priv, reg, value & ~mask); 21862306a36Sopenharmony_ci} 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ciint arc_mdio_probe(struct arc_emac_priv *priv); 22162306a36Sopenharmony_ciint arc_mdio_remove(struct arc_emac_priv *priv); 22262306a36Sopenharmony_ciint arc_emac_probe(struct net_device *ndev, int interface); 22362306a36Sopenharmony_civoid arc_emac_remove(struct net_device *ndev); 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci#endif /* ARC_EMAC_H */ 226