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