xref: /openbmc/linux/drivers/net/ethernet/apm/xgene/xgene_enet_main.h (revision cbecf716ca618fd44feda6bd9a64a8179d031fc5)
11ccea77eSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
2e6ad7673SIyappan Subramanian /* Applied Micro X-Gene SoC Ethernet Driver
3e6ad7673SIyappan Subramanian  *
4e6ad7673SIyappan Subramanian  * Copyright (c) 2014, Applied Micro Circuits Corporation
5e6ad7673SIyappan Subramanian  * Authors: Iyappan Subramanian <isubramanian@apm.com>
6e6ad7673SIyappan Subramanian  *	    Ravi Patel <rapatel@apm.com>
7e6ad7673SIyappan Subramanian  *	    Keyur Chudgar <kchudgar@apm.com>
8e6ad7673SIyappan Subramanian  */
9e6ad7673SIyappan Subramanian 
10e6ad7673SIyappan Subramanian #ifndef __XGENE_ENET_MAIN_H__
11e6ad7673SIyappan Subramanian #define __XGENE_ENET_MAIN_H__
12e6ad7673SIyappan Subramanian 
13de7b5b3dSFeng Kan #include <linux/acpi.h>
14e6ad7673SIyappan Subramanian #include <linux/clk.h>
15de7b5b3dSFeng Kan #include <linux/efi.h>
16b5d7a069SIyappan Subramanian #include <linux/irq.h>
17de7b5b3dSFeng Kan #include <linux/io.h>
18e6ad7673SIyappan Subramanian #include <linux/of_platform.h>
19e6ad7673SIyappan Subramanian #include <linux/of_net.h>
20e6ad7673SIyappan Subramanian #include <linux/of_mdio.h>
21*232e15e1SAndrew Lunn #include <linux/mdio/mdio-xgene.h>
22e6ad7673SIyappan Subramanian #include <linux/module.h>
23e6ad7673SIyappan Subramanian #include <net/ip.h>
24e6ad7673SIyappan Subramanian #include <linux/prefetch.h>
25e6ad7673SIyappan Subramanian #include <linux/if_vlan.h>
26e6ad7673SIyappan Subramanian #include <linux/phy.h>
27e6ad7673SIyappan Subramanian #include "xgene_enet_hw.h"
2876f94a9cSIyappan Subramanian #include "xgene_enet_cle.h"
29bc1b7c13SIyappan Subramanian #include "xgene_enet_ring2.h"
30e6ad7673SIyappan Subramanian 
314902a922SIyappan Subramanian #define ETHER_MIN_PACKET	64
3261c759cdSQuan Nguyen #define ETHER_STD_PACKET	1518
33a9380b0fSIyappan Subramanian #define XGENE_ENET_STD_MTU	1536
34a9380b0fSIyappan Subramanian #define XGENE_ENET_MAX_MTU	9600
35a9380b0fSIyappan Subramanian #define SKB_BUFFER_SIZE		(XGENE_ENET_STD_MTU - NET_IP_ALIGN)
36a9380b0fSIyappan Subramanian 
37949c40bbSIyappan Subramanian #define BUFLEN_16K	(16 * 1024)
38a9380b0fSIyappan Subramanian #define NUM_PKT_BUF	1024
39e6ad7673SIyappan Subramanian #define NUM_BUFPOOL	32
40a9380b0fSIyappan Subramanian #define NUM_NXTBUFPOOL	8
419b00eb49SIyappan Subramanian #define MAX_EXP_BUFFS	256
42e3978673SIyappan Subramanian #define NUM_MSS_REG	4
439b00eb49SIyappan Subramanian #define XGENE_MIN_ENET_FRAME_SIZE	60
44ca626454SKeyur Chudgar 
451b090a48SIyappan Subramanian #define XGENE_MAX_ENET_IRQ	16
461b090a48SIyappan Subramanian #define XGENE_NUM_RX_RING	8
471b090a48SIyappan Subramanian #define XGENE_NUM_TX_RING	8
481b090a48SIyappan Subramanian #define XGENE_NUM_TXC_RING	8
49107dec27SIyappan Subramanian 
50ca626454SKeyur Chudgar #define START_CPU_BUFNUM_0	0
51ca626454SKeyur Chudgar #define START_ETH_BUFNUM_0	2
52ca626454SKeyur Chudgar #define START_BP_BUFNUM_0	0x22
53ca626454SKeyur Chudgar #define START_RING_NUM_0	8
54ca626454SKeyur Chudgar #define START_CPU_BUFNUM_1	12
55ca626454SKeyur Chudgar #define START_ETH_BUFNUM_1	10
56ca626454SKeyur Chudgar #define START_BP_BUFNUM_1	0x2A
57ca626454SKeyur Chudgar #define START_RING_NUM_1	264
58e6ad7673SIyappan Subramanian 
59149e9ab4SIyappan Subramanian #define XG_START_CPU_BUFNUM_1	12
60149e9ab4SIyappan Subramanian #define XG_START_ETH_BUFNUM_1	2
61149e9ab4SIyappan Subramanian #define XG_START_BP_BUFNUM_1	0x22
62149e9ab4SIyappan Subramanian #define XG_START_RING_NUM_1	264
63149e9ab4SIyappan Subramanian 
64bc1b7c13SIyappan Subramanian #define X2_START_CPU_BUFNUM_0	0
65bc1b7c13SIyappan Subramanian #define X2_START_ETH_BUFNUM_0	0
66bc1b7c13SIyappan Subramanian #define X2_START_BP_BUFNUM_0	0x20
67bc1b7c13SIyappan Subramanian #define X2_START_RING_NUM_0	0
68bc1b7c13SIyappan Subramanian #define X2_START_CPU_BUFNUM_1	0xc
69bc1b7c13SIyappan Subramanian #define X2_START_ETH_BUFNUM_1	0
70bc1b7c13SIyappan Subramanian #define X2_START_BP_BUFNUM_1	0x20
71bc1b7c13SIyappan Subramanian #define X2_START_RING_NUM_1	256
72bc1b7c13SIyappan Subramanian 
736772b653SIyappan Subramanian #define IRQ_ID_SIZE		16
746772b653SIyappan Subramanian 
7532f784b5SIyappan Subramanian #define PHY_POLL_LINK_ON	(10 * HZ)
7632f784b5SIyappan Subramanian #define PHY_POLL_LINK_OFF	(PHY_POLL_LINK_ON / 5)
7732f784b5SIyappan Subramanian 
78bc1b7c13SIyappan Subramanian enum xgene_enet_id {
79bc1b7c13SIyappan Subramanian 	XGENE_ENET1 = 1,
80bc1b7c13SIyappan Subramanian 	XGENE_ENET2
81bc1b7c13SIyappan Subramanian };
82bc1b7c13SIyappan Subramanian 
83a9380b0fSIyappan Subramanian enum xgene_enet_buf_len {
84a9380b0fSIyappan Subramanian 	SIZE_2K = 2048,
85a9380b0fSIyappan Subramanian 	SIZE_4K = 4096,
86a9380b0fSIyappan Subramanian 	SIZE_16K = 16384
87a9380b0fSIyappan Subramanian };
88a9380b0fSIyappan Subramanian 
89e6ad7673SIyappan Subramanian /* software context of a descriptor ring */
90e6ad7673SIyappan Subramanian struct xgene_enet_desc_ring {
91e6ad7673SIyappan Subramanian 	struct net_device *ndev;
92e6ad7673SIyappan Subramanian 	u16 id;
93e6ad7673SIyappan Subramanian 	u16 num;
94e6ad7673SIyappan Subramanian 	u16 head;
95e6ad7673SIyappan Subramanian 	u16 tail;
969b00eb49SIyappan Subramanian 	u16 exp_buf_tail;
97e6ad7673SIyappan Subramanian 	u16 slots;
98e6ad7673SIyappan Subramanian 	u16 irq;
996772b653SIyappan Subramanian 	char irq_name[IRQ_ID_SIZE];
100e6ad7673SIyappan Subramanian 	u32 size;
1019dd3c797SIyappan Subramanian 	u32 state[X2_NUM_RING_CONFIG];
102e6ad7673SIyappan Subramanian 	void __iomem *cmd_base;
103e6ad7673SIyappan Subramanian 	void __iomem *cmd;
104e6ad7673SIyappan Subramanian 	dma_addr_t dma;
105ed9b7da0SIyappan Subramanian 	dma_addr_t irq_mbox_dma;
106ed9b7da0SIyappan Subramanian 	void *irq_mbox_addr;
107e6ad7673SIyappan Subramanian 	u16 dst_ring_num;
108a9380b0fSIyappan Subramanian 	u16 nbufpool;
109a9380b0fSIyappan Subramanian 	int npagepool;
110107dec27SIyappan Subramanian 	u8 index;
111a9380b0fSIyappan Subramanian 	u32 flags;
112e6ad7673SIyappan Subramanian 	struct sk_buff *(*rx_skb);
113e6ad7673SIyappan Subramanian 	struct sk_buff *(*cp_skb);
1149b00eb49SIyappan Subramanian 	dma_addr_t *frag_dma_addr;
115a9380b0fSIyappan Subramanian 	struct page *(*frag_page);
116e6ad7673SIyappan Subramanian 	enum xgene_enet_ring_cfgsize cfgsize;
117e6ad7673SIyappan Subramanian 	struct xgene_enet_desc_ring *cp_ring;
118e6ad7673SIyappan Subramanian 	struct xgene_enet_desc_ring *buf_pool;
119d6d48969SIyappan Subramanian 	struct xgene_enet_desc_ring *page_pool;
120e6ad7673SIyappan Subramanian 	struct napi_struct napi;
121e6ad7673SIyappan Subramanian 	union {
122e6ad7673SIyappan Subramanian 		void *desc_addr;
123e6ad7673SIyappan Subramanian 		struct xgene_enet_raw_desc *raw_desc;
124e6ad7673SIyappan Subramanian 		struct xgene_enet_raw_desc16 *raw_desc16;
125e6ad7673SIyappan Subramanian 	};
1269b00eb49SIyappan Subramanian 	__le64 *exp_bufs;
1273bb502f8SIyappan Subramanian 	u64 tx_packets;
1283bb502f8SIyappan Subramanian 	u64 tx_bytes;
129089f97c7SQuan Nguyen 	u64 tx_dropped;
130089f97c7SQuan Nguyen 	u64 tx_errors;
1313bb502f8SIyappan Subramanian 	u64 rx_packets;
1323bb502f8SIyappan Subramanian 	u64 rx_bytes;
1333bb502f8SIyappan Subramanian 	u64 rx_dropped;
1343bb502f8SIyappan Subramanian 	u64 rx_errors;
1353bb502f8SIyappan Subramanian 	u64 rx_length_errors;
1363bb502f8SIyappan Subramanian 	u64 rx_crc_errors;
1373bb502f8SIyappan Subramanian 	u64 rx_frame_errors;
1383bb502f8SIyappan Subramanian 	u64 rx_fifo_errors;
139e6ad7673SIyappan Subramanian };
140e6ad7673SIyappan Subramanian 
141d0eb7458SIyappan Subramanian struct xgene_mac_ops {
142d0eb7458SIyappan Subramanian 	void (*init)(struct xgene_enet_pdata *pdata);
143d0eb7458SIyappan Subramanian 	void (*reset)(struct xgene_enet_pdata *pdata);
144d0eb7458SIyappan Subramanian 	void (*tx_enable)(struct xgene_enet_pdata *pdata);
145d0eb7458SIyappan Subramanian 	void (*rx_enable)(struct xgene_enet_pdata *pdata);
146d0eb7458SIyappan Subramanian 	void (*tx_disable)(struct xgene_enet_pdata *pdata);
147d0eb7458SIyappan Subramanian 	void (*rx_disable)(struct xgene_enet_pdata *pdata);
148ca6d550cSIyappan Subramanian 	void (*get_drop_cnt)(struct xgene_enet_pdata *pdata, u32 *rx, u32 *tx);
1499a8c5ddeSIyappan Subramanian 	void (*set_speed)(struct xgene_enet_pdata *pdata);
150d0eb7458SIyappan Subramanian 	void (*set_mac_addr)(struct xgene_enet_pdata *pdata);
151350b4e33SIyappan Subramanian 	void (*set_framesize)(struct xgene_enet_pdata *pdata, int framesize);
152e3978673SIyappan Subramanian 	void (*set_mss)(struct xgene_enet_pdata *pdata, u16 mss, u8 index);
153dc8385f0SIyappan Subramanian 	void (*link_state)(struct work_struct *work);
154bb64fa09SIyappan Subramanian 	void (*enable_tx_pause)(struct xgene_enet_pdata *pdata, bool enable);
155bb64fa09SIyappan Subramanian 	void (*flowctl_rx)(struct xgene_enet_pdata *pdata, bool enable);
156bb64fa09SIyappan Subramanian 	void (*flowctl_tx)(struct xgene_enet_pdata *pdata, bool enable);
157d0eb7458SIyappan Subramanian };
158d0eb7458SIyappan Subramanian 
159d0eb7458SIyappan Subramanian struct xgene_port_ops {
160c3f4465dSIyappan Subramanian 	int (*reset)(struct xgene_enet_pdata *pdata);
161cb11c062SIyappan Subramanian 	void (*clear)(struct xgene_enet_pdata *pdata,
162cb11c062SIyappan Subramanian 		      struct xgene_enet_desc_ring *ring);
163d0eb7458SIyappan Subramanian 	void (*cle_bypass)(struct xgene_enet_pdata *pdata,
164d6d48969SIyappan Subramanian 			   u32 dst_ring_num, u16 bufpool_id, u16 nxtbufpool_id);
165d0eb7458SIyappan Subramanian 	void (*shutdown)(struct xgene_enet_pdata *pdata);
166d0eb7458SIyappan Subramanian };
167d0eb7458SIyappan Subramanian 
16881cefb81SIyappan Subramanian struct xgene_ring_ops {
16981cefb81SIyappan Subramanian 	u8 num_ring_config;
17081cefb81SIyappan Subramanian 	u8 num_ring_id_shift;
17181cefb81SIyappan Subramanian 	struct xgene_enet_desc_ring * (*setup)(struct xgene_enet_desc_ring *);
17281cefb81SIyappan Subramanian 	void (*clear)(struct xgene_enet_desc_ring *);
17381cefb81SIyappan Subramanian 	void (*wr_cmd)(struct xgene_enet_desc_ring *, int);
17481cefb81SIyappan Subramanian 	u32 (*len)(struct xgene_enet_desc_ring *);
175107dec27SIyappan Subramanian 	void (*coalesce)(struct xgene_enet_desc_ring *);
17681cefb81SIyappan Subramanian };
17781cefb81SIyappan Subramanian 
17876f94a9cSIyappan Subramanian struct xgene_cle_ops {
17976f94a9cSIyappan Subramanian 	int (*cle_init)(struct xgene_enet_pdata *pdata);
18076f94a9cSIyappan Subramanian };
18176f94a9cSIyappan Subramanian 
182e6ad7673SIyappan Subramanian /* ethernet private data */
183e6ad7673SIyappan Subramanian struct xgene_enet_pdata {
184e6ad7673SIyappan Subramanian 	struct net_device *ndev;
185e6ad7673SIyappan Subramanian 	struct mii_bus *mdio_bus;
186e6ad7673SIyappan Subramanian 	int phy_speed;
187e6ad7673SIyappan Subramanian 	struct clk *clk;
188e6ad7673SIyappan Subramanian 	struct platform_device *pdev;
189bc1b7c13SIyappan Subramanian 	enum xgene_enet_id enet_id;
190107dec27SIyappan Subramanian 	struct xgene_enet_desc_ring *tx_ring[XGENE_NUM_TX_RING];
191107dec27SIyappan Subramanian 	struct xgene_enet_desc_ring *rx_ring[XGENE_NUM_RX_RING];
192107dec27SIyappan Subramanian 	u16 tx_level[XGENE_NUM_TX_RING];
193107dec27SIyappan Subramanian 	u16 txc_level[XGENE_NUM_TX_RING];
194e6ad7673SIyappan Subramanian 	char *dev_name;
195e6ad7673SIyappan Subramanian 	u32 rx_buff_cnt;
196e6ad7673SIyappan Subramanian 	u32 tx_qcnt_hi;
197107dec27SIyappan Subramanian 	u32 irqs[XGENE_MAX_ENET_IRQ];
198107dec27SIyappan Subramanian 	u8 rxq_cnt;
199107dec27SIyappan Subramanian 	u8 txq_cnt;
2006772b653SIyappan Subramanian 	u8 cq_cnt;
201e6ad7673SIyappan Subramanian 	void __iomem *eth_csr_addr;
202e6ad7673SIyappan Subramanian 	void __iomem *eth_ring_if_addr;
203e6ad7673SIyappan Subramanian 	void __iomem *eth_diag_csr_addr;
204e6ad7673SIyappan Subramanian 	void __iomem *mcx_mac_addr;
205e6ad7673SIyappan Subramanian 	void __iomem *mcx_mac_csr_addr;
2062d07d8e4SQuan Nguyen 	void __iomem *mcx_stats_addr;
207e6ad7673SIyappan Subramanian 	void __iomem *base_addr;
2083eb7cb9dSIyappan Subramanian 	void __iomem *pcs_addr;
209e6ad7673SIyappan Subramanian 	void __iomem *ring_csr_addr;
210e6ad7673SIyappan Subramanian 	void __iomem *ring_cmd_addr;
211e6ad7673SIyappan Subramanian 	int phy_mode;
2120148d38dSIyappan Subramanian 	enum xgene_enet_rm rm;
21376f94a9cSIyappan Subramanian 	struct xgene_enet_cle cle;
2142d07d8e4SQuan Nguyen 	u64 *extd_stats;
215eaef62a4SQuan Nguyen 	u64 false_rflr;
21661c759cdSQuan Nguyen 	u64 vlan_rjbr;
2172d07d8e4SQuan Nguyen 	spinlock_t stats_lock; /* statistics lock */
2183cdb7309SJulia Lawall 	const struct xgene_mac_ops *mac_ops;
219ae1aed95SIyappan Subramanian 	spinlock_t mac_lock; /* mac lock */
2203cdb7309SJulia Lawall 	const struct xgene_port_ops *port_ops;
22181cefb81SIyappan Subramanian 	struct xgene_ring_ops *ring_ops;
222b555a3d1SJulia Lawall 	const struct xgene_cle_ops *cle_ops;
2230148d38dSIyappan Subramanian 	struct delayed_work link_work;
224ca626454SKeyur Chudgar 	u32 port_id;
225ca626454SKeyur Chudgar 	u8 cpu_bufnum;
226ca626454SKeyur Chudgar 	u8 eth_bufnum;
227ca626454SKeyur Chudgar 	u8 bp_bufnum;
228ca626454SKeyur Chudgar 	u16 ring_num;
229e3978673SIyappan Subramanian 	u32 mss[NUM_MSS_REG];
230e3978673SIyappan Subramanian 	u32 mss_refcnt[NUM_MSS_REG];
231e3978673SIyappan Subramanian 	spinlock_t mss_lock;  /* mss lock */
23216615a4cSIyappan Subramanian 	u8 tx_delay;
23316615a4cSIyappan Subramanian 	u8 rx_delay;
2348089a96fSIyappan Subramanian 	bool mdio_driver;
23527ecf87cSIyappan Subramanian 	struct gpio_desc *sfp_rdy;
236751d6fd1SIyappan Subramanian 	bool sfp_gpio_en;
237bb64fa09SIyappan Subramanian 	u32 pause_autoneg;
238bb64fa09SIyappan Subramanian 	bool tx_pause;
239bb64fa09SIyappan Subramanian 	bool rx_pause;
240e6ad7673SIyappan Subramanian };
241e6ad7673SIyappan Subramanian 
24232f784b5SIyappan Subramanian struct xgene_indirect_ctl {
24332f784b5SIyappan Subramanian 	void __iomem *addr;
24432f784b5SIyappan Subramanian 	void __iomem *ctl;
24532f784b5SIyappan Subramanian 	void __iomem *cmd;
24632f784b5SIyappan Subramanian 	void __iomem *cmd_done;
24732f784b5SIyappan Subramanian };
24832f784b5SIyappan Subramanian 
ndev_to_dev(struct net_device * ndev)249e6ad7673SIyappan Subramanian static inline struct device *ndev_to_dev(struct net_device *ndev)
250e6ad7673SIyappan Subramanian {
251e6ad7673SIyappan Subramanian 	return ndev->dev.parent;
252e6ad7673SIyappan Subramanian }
253e6ad7673SIyappan Subramanian 
xgene_enet_dst_ring_num(struct xgene_enet_desc_ring * ring)25476f94a9cSIyappan Subramanian static inline u16 xgene_enet_dst_ring_num(struct xgene_enet_desc_ring *ring)
25576f94a9cSIyappan Subramanian {
25676f94a9cSIyappan Subramanian 	struct xgene_enet_pdata *pdata = netdev_priv(ring->ndev);
25776f94a9cSIyappan Subramanian 
25876f94a9cSIyappan Subramanian 	return ((u16)pdata->rm << 10) | ring->num;
25976f94a9cSIyappan Subramanian }
26076f94a9cSIyappan Subramanian 
261e6ad7673SIyappan Subramanian void xgene_enet_set_ethtool_ops(struct net_device *netdev);
2622d07d8e4SQuan Nguyen int xgene_extd_stats_init(struct xgene_enet_pdata *pdata);
263e6ad7673SIyappan Subramanian 
264e6ad7673SIyappan Subramanian #endif /* __XGENE_ENET_MAIN_H__ */
265