diff options
Diffstat (limited to '')
-rw-r--r-- | drivers/net/ethernet/arc/emac.h | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/drivers/net/ethernet/arc/emac.h b/drivers/net/ethernet/arc/emac.h new file mode 100644 index 000000000..d820ae03a --- /dev/null +++ b/drivers/net/ethernet/arc/emac.h @@ -0,0 +1,225 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2004-2013 Synopsys, Inc. (www.synopsys.com) + * + * Registers and bits definitions of ARC EMAC + */ + +#ifndef ARC_EMAC_H +#define ARC_EMAC_H + +#include <linux/device.h> +#include <linux/dma-mapping.h> +#include <linux/netdevice.h> +#include <linux/phy.h> +#include <linux/clk.h> + +/* STATUS and ENABLE Register bit masks */ +#define TXINT_MASK (1 << 0) /* Transmit interrupt */ +#define RXINT_MASK (1 << 1) /* Receive interrupt */ +#define ERR_MASK (1 << 2) /* Error interrupt */ +#define TXCH_MASK (1 << 3) /* Transmit chaining error interrupt */ +#define MSER_MASK (1 << 4) /* Missed packet counter error */ +#define RXCR_MASK (1 << 8) /* RXCRCERR counter rolled over */ +#define RXFR_MASK (1 << 9) /* RXFRAMEERR counter rolled over */ +#define RXFL_MASK (1 << 10) /* RXOFLOWERR counter rolled over */ +#define MDIO_MASK (1 << 12) /* MDIO complete interrupt */ +#define TXPL_MASK (1 << 31) /* Force polling of BD by EMAC */ + +/* CONTROL Register bit masks */ +#define EN_MASK (1 << 0) /* VMAC enable */ +#define TXRN_MASK (1 << 3) /* TX enable */ +#define RXRN_MASK (1 << 4) /* RX enable */ +#define DSBC_MASK (1 << 8) /* Disable receive broadcast */ +#define ENFL_MASK (1 << 10) /* Enable Full-duplex */ +#define PROM_MASK (1 << 11) /* Promiscuous mode */ + +/* Buffer descriptor INFO bit masks */ +#define OWN_MASK (1 << 31) /* 0-CPU or 1-EMAC owns buffer */ +#define FIRST_MASK (1 << 16) /* First buffer in chain */ +#define LAST_MASK (1 << 17) /* Last buffer in chain */ +#define LEN_MASK 0x000007FF /* last 11 bits */ +#define CRLS (1 << 21) +#define DEFR (1 << 22) +#define DROP (1 << 23) +#define RTRY (1 << 24) +#define LTCL (1 << 28) +#define UFLO (1 << 29) + +#define FOR_EMAC OWN_MASK +#define FOR_CPU 0 + +/* ARC EMAC register set combines entries for MAC and MDIO */ +enum { + R_ID = 0, + R_STATUS, + R_ENABLE, + R_CTRL, + R_POLLRATE, + R_RXERR, + R_MISS, + R_TX_RING, + R_RX_RING, + R_ADDRL, + R_ADDRH, + R_LAFL, + R_LAFH, + R_MDIO, +}; + +#define TX_TIMEOUT (400 * HZ / 1000) /* Transmission timeout */ + +#define ARC_EMAC_NAPI_WEIGHT 40 /* Workload for NAPI */ + +#define EMAC_BUFFER_SIZE 1536 /* EMAC buffer size */ + +/** + * struct arc_emac_bd - EMAC buffer descriptor (BD). + * + * @info: Contains status information on the buffer itself. + * @data: 32-bit byte addressable pointer to the packet data. + */ +struct arc_emac_bd { + __le32 info; + dma_addr_t data; +}; + +/* Number of Rx/Tx BD's */ +#define RX_BD_NUM 128 +#define TX_BD_NUM 128 + +#define RX_RING_SZ (RX_BD_NUM * sizeof(struct arc_emac_bd)) +#define TX_RING_SZ (TX_BD_NUM * sizeof(struct arc_emac_bd)) + +/** + * struct buffer_state - Stores Rx/Tx buffer state. + * @sk_buff: Pointer to socket buffer. + * @addr: Start address of DMA-mapped memory region. + * @len: Length of DMA-mapped memory region. + */ +struct buffer_state { + struct sk_buff *skb; + DEFINE_DMA_UNMAP_ADDR(addr); + DEFINE_DMA_UNMAP_LEN(len); +}; + +struct arc_emac_mdio_bus_data { + struct gpio_desc *reset_gpio; + int msec; +}; + +/** + * struct arc_emac_priv - Storage of EMAC's private information. + * @dev: Pointer to the current device. + * @phy_dev: Pointer to attached PHY device. + * @bus: Pointer to the current MII bus. + * @regs: Base address of EMAC memory-mapped control registers. + * @napi: Structure for NAPI. + * @rxbd: Pointer to Rx BD ring. + * @txbd: Pointer to Tx BD ring. + * @rxbd_dma: DMA handle for Rx BD ring. + * @txbd_dma: DMA handle for Tx BD ring. + * @rx_buff: Storage for Rx buffers states. + * @tx_buff: Storage for Tx buffers states. + * @txbd_curr: Index of Tx BD to use on the next "ndo_start_xmit". + * @txbd_dirty: Index of Tx BD to free on the next Tx interrupt. + * @last_rx_bd: Index of the last Rx BD we've got from EMAC. + * @link: PHY's last seen link state. + * @duplex: PHY's last set duplex mode. + * @speed: PHY's last set speed. + */ +struct arc_emac_priv { + const char *drv_name; + void (*set_mac_speed)(void *priv, unsigned int speed); + + /* Devices */ + struct device *dev; + struct mii_bus *bus; + struct arc_emac_mdio_bus_data bus_data; + + void __iomem *regs; + struct clk *clk; + + struct napi_struct napi; + + struct arc_emac_bd *rxbd; + struct arc_emac_bd *txbd; + + dma_addr_t rxbd_dma; + dma_addr_t txbd_dma; + + struct buffer_state rx_buff[RX_BD_NUM]; + struct buffer_state tx_buff[TX_BD_NUM]; + unsigned int txbd_curr; + unsigned int txbd_dirty; + + unsigned int last_rx_bd; + + unsigned int link; + unsigned int duplex; + unsigned int speed; + + unsigned int rx_missed_errors; +}; + +/** + * arc_reg_set - Sets EMAC register with provided value. + * @priv: Pointer to ARC EMAC private data structure. + * @reg: Register offset from base address. + * @value: Value to set in register. + */ +static inline void arc_reg_set(struct arc_emac_priv *priv, int reg, int value) +{ + iowrite32(value, priv->regs + reg * sizeof(int)); +} + +/** + * arc_reg_get - Gets value of specified EMAC register. + * @priv: Pointer to ARC EMAC private data structure. + * @reg: Register offset from base address. + * + * returns: Value of requested register. + */ +static inline unsigned int arc_reg_get(struct arc_emac_priv *priv, int reg) +{ + return ioread32(priv->regs + reg * sizeof(int)); +} + +/** + * arc_reg_or - Applies mask to specified EMAC register - ("reg" | "mask"). + * @priv: Pointer to ARC EMAC private data structure. + * @reg: Register offset from base address. + * @mask: Mask to apply to specified register. + * + * This function reads initial register value, then applies provided mask + * to it and then writes register back. + */ +static inline void arc_reg_or(struct arc_emac_priv *priv, int reg, int mask) +{ + unsigned int value = arc_reg_get(priv, reg); + + arc_reg_set(priv, reg, value | mask); +} + +/** + * arc_reg_clr - Applies mask to specified EMAC register - ("reg" & ~"mask"). + * @priv: Pointer to ARC EMAC private data structure. + * @reg: Register offset from base address. + * @mask: Mask to apply to specified register. + * + * This function reads initial register value, then applies provided mask + * to it and then writes register back. + */ +static inline void arc_reg_clr(struct arc_emac_priv *priv, int reg, int mask) +{ + unsigned int value = arc_reg_get(priv, reg); + + arc_reg_set(priv, reg, value & ~mask); +} + +int arc_mdio_probe(struct arc_emac_priv *priv); +int arc_mdio_remove(struct arc_emac_priv *priv); +int arc_emac_probe(struct net_device *ndev, int interface); +int arc_emac_remove(struct net_device *ndev); + +#endif /* ARC_EMAC_H */ |