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