xref: /openbmc/linux/drivers/net/ethernet/synopsys/dwc-xlgmac.h (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
165e0ace2SJie Deng /* Synopsys DesignWare Core Enterprise Ethernet (XLGMAC) Driver
265e0ace2SJie Deng  *
365e0ace2SJie Deng  * Copyright (c) 2017 Synopsys, Inc. (www.synopsys.com)
465e0ace2SJie Deng  *
5ea8c1c64SJie Deng  * This program is dual-licensed; you may select either version 2 of
6ea8c1c64SJie Deng  * the GNU General Public License ("GPL") or BSD license ("BSD").
765e0ace2SJie Deng  *
865e0ace2SJie Deng  * This Synopsys DWC XLGMAC software driver and associated documentation
965e0ace2SJie Deng  * (hereinafter the "Software") is an unsupported proprietary work of
1065e0ace2SJie Deng  * Synopsys, Inc. unless otherwise expressly agreed to in writing between
1165e0ace2SJie Deng  * Synopsys and you. The Software IS NOT an item of Licensed Software or a
1265e0ace2SJie Deng  * Licensed Product under any End User Software License Agreement or
1365e0ace2SJie Deng  * Agreement for Licensed Products with Synopsys or any supplement thereto.
1465e0ace2SJie Deng  * Synopsys is a registered trademark of Synopsys, Inc. Other names included
1565e0ace2SJie Deng  * in the SOFTWARE may be the trademarks of their respective owners.
1665e0ace2SJie Deng  */
1765e0ace2SJie Deng 
1865e0ace2SJie Deng #ifndef __DWC_XLGMAC_H__
1965e0ace2SJie Deng #define __DWC_XLGMAC_H__
2065e0ace2SJie Deng 
2165e0ace2SJie Deng #include <linux/dma-mapping.h>
2265e0ace2SJie Deng #include <linux/netdevice.h>
2365e0ace2SJie Deng #include <linux/workqueue.h>
2465e0ace2SJie Deng #include <linux/phy.h>
2565e0ace2SJie Deng #include <linux/if_vlan.h>
2665e0ace2SJie Deng #include <linux/bitops.h>
2765e0ace2SJie Deng #include <linux/timecounter.h>
2865e0ace2SJie Deng 
2965e0ace2SJie Deng #define XLGMAC_DRV_NAME			"dwc-xlgmac"
3065e0ace2SJie Deng #define XLGMAC_DRV_VERSION		"1.0.0"
3165e0ace2SJie Deng #define XLGMAC_DRV_DESC			"Synopsys DWC XLGMAC Driver"
3265e0ace2SJie Deng 
3365e0ace2SJie Deng /* Descriptor related parameters */
3465e0ace2SJie Deng #define XLGMAC_TX_DESC_CNT		1024
3565e0ace2SJie Deng #define XLGMAC_TX_DESC_MIN_FREE		(XLGMAC_TX_DESC_CNT >> 3)
3665e0ace2SJie Deng #define XLGMAC_TX_DESC_MAX_PROC		(XLGMAC_TX_DESC_CNT >> 1)
3765e0ace2SJie Deng #define XLGMAC_RX_DESC_CNT		1024
3865e0ace2SJie Deng #define XLGMAC_RX_DESC_MAX_DIRTY	(XLGMAC_RX_DESC_CNT >> 3)
3965e0ace2SJie Deng 
4065e0ace2SJie Deng /* Descriptors required for maximum contiguous TSO/GSO packet */
41*7c4e983cSAlexander Duyck #define XLGMAC_TX_MAX_SPLIT	\
42*7c4e983cSAlexander Duyck 	((GSO_LEGACY_MAX_SIZE / XLGMAC_TX_MAX_BUF_SIZE) + 1)
4365e0ace2SJie Deng 
4465e0ace2SJie Deng /* Maximum possible descriptors needed for a SKB */
4565e0ace2SJie Deng #define XLGMAC_TX_MAX_DESC_NR	(MAX_SKB_FRAGS + XLGMAC_TX_MAX_SPLIT + 2)
4665e0ace2SJie Deng 
4765e0ace2SJie Deng #define XLGMAC_TX_MAX_BUF_SIZE	(0x3fff & ~(64 - 1))
4865e0ace2SJie Deng #define XLGMAC_RX_MIN_BUF_SIZE	(ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN)
4965e0ace2SJie Deng #define XLGMAC_RX_BUF_ALIGN	64
5065e0ace2SJie Deng 
5165e0ace2SJie Deng /* Maximum Size for Splitting the Header Data
5265e0ace2SJie Deng  * Keep in sync with SKB_ALLOC_SIZE
5365e0ace2SJie Deng  * 3'b000: 64 bytes, 3'b001: 128 bytes
5465e0ace2SJie Deng  * 3'b010: 256 bytes, 3'b011: 512 bytes
5565e0ace2SJie Deng  * 3'b100: 1023 bytes ,   3'b101'3'b111: Reserved
5665e0ace2SJie Deng  */
5765e0ace2SJie Deng #define XLGMAC_SPH_HDSMS_SIZE		3
5865e0ace2SJie Deng #define XLGMAC_SKB_ALLOC_SIZE		512
5965e0ace2SJie Deng 
6065e0ace2SJie Deng #define XLGMAC_MAX_FIFO			81920
6165e0ace2SJie Deng 
6265e0ace2SJie Deng #define XLGMAC_MAX_DMA_CHANNELS		16
6365e0ace2SJie Deng #define XLGMAC_DMA_STOP_TIMEOUT		5
6465e0ace2SJie Deng #define XLGMAC_DMA_INTERRUPT_MASK	0x31c7
6565e0ace2SJie Deng 
6665e0ace2SJie Deng /* Default coalescing parameters */
6765e0ace2SJie Deng #define XLGMAC_INIT_DMA_TX_USECS	1000
6865e0ace2SJie Deng #define XLGMAC_INIT_DMA_TX_FRAMES	25
6965e0ace2SJie Deng #define XLGMAC_INIT_DMA_RX_USECS	30
7065e0ace2SJie Deng #define XLGMAC_INIT_DMA_RX_FRAMES	25
71d4d49bc1SJie Deng #define XLGMAC_MAX_DMA_RIWT		0xff
72d4d49bc1SJie Deng #define XLGMAC_MIN_DMA_RIWT		0x01
7365e0ace2SJie Deng 
7465e0ace2SJie Deng /* Flow control queue count */
7565e0ace2SJie Deng #define XLGMAC_MAX_FLOW_CONTROL_QUEUES	8
7665e0ace2SJie Deng 
7765e0ace2SJie Deng /* System clock is 125 MHz */
7865e0ace2SJie Deng #define XLGMAC_SYSCLOCK			125000000
7965e0ace2SJie Deng 
8065e0ace2SJie Deng /* Maximum MAC address hash table size (256 bits = 8 bytes) */
8165e0ace2SJie Deng #define XLGMAC_MAC_HASH_TABLE_SIZE	8
8265e0ace2SJie Deng 
8365e0ace2SJie Deng /* Receive Side Scaling */
8465e0ace2SJie Deng #define XLGMAC_RSS_HASH_KEY_SIZE	40
8565e0ace2SJie Deng #define XLGMAC_RSS_MAX_TABLE_SIZE	256
8665e0ace2SJie Deng #define XLGMAC_RSS_LOOKUP_TABLE_TYPE	0
8765e0ace2SJie Deng #define XLGMAC_RSS_HASH_KEY_TYPE	1
8865e0ace2SJie Deng 
8965e0ace2SJie Deng #define XLGMAC_STD_PACKET_MTU		1500
9065e0ace2SJie Deng #define XLGMAC_JUMBO_PACKET_MTU		9000
9165e0ace2SJie Deng 
9265e0ace2SJie Deng /* Helper macro for descriptor handling
9365e0ace2SJie Deng  *  Always use XLGMAC_GET_DESC_DATA to access the descriptor data
9465e0ace2SJie Deng  */
9565e0ace2SJie Deng #define XLGMAC_GET_DESC_DATA(ring, idx) ({				\
9665e0ace2SJie Deng 	typeof(ring) _ring = (ring);					\
9765e0ace2SJie Deng 	((_ring)->desc_data_head +					\
9865e0ace2SJie Deng 	 ((idx) & ((_ring)->dma_desc_count - 1)));			\
9965e0ace2SJie Deng })
10065e0ace2SJie Deng 
10165e0ace2SJie Deng #define XLGMAC_GET_REG_BITS(var, pos, len) ({				\
10265e0ace2SJie Deng 	typeof(pos) _pos = (pos);					\
10365e0ace2SJie Deng 	typeof(len) _len = (len);					\
10465e0ace2SJie Deng 	((var) & GENMASK(_pos + _len - 1, _pos)) >> (_pos);		\
10565e0ace2SJie Deng })
10665e0ace2SJie Deng 
10765e0ace2SJie Deng #define XLGMAC_GET_REG_BITS_LE(var, pos, len) ({			\
10865e0ace2SJie Deng 	typeof(pos) _pos = (pos);					\
10965e0ace2SJie Deng 	typeof(len) _len = (len);					\
11065e0ace2SJie Deng 	typeof(var) _var = le32_to_cpu((var));				\
11165e0ace2SJie Deng 	((_var) & GENMASK(_pos + _len - 1, _pos)) >> (_pos);		\
11265e0ace2SJie Deng })
11365e0ace2SJie Deng 
11465e0ace2SJie Deng #define XLGMAC_SET_REG_BITS(var, pos, len, val) ({			\
11565e0ace2SJie Deng 	typeof(var) _var = (var);					\
11665e0ace2SJie Deng 	typeof(pos) _pos = (pos);					\
11765e0ace2SJie Deng 	typeof(len) _len = (len);					\
11865e0ace2SJie Deng 	typeof(val) _val = (val);					\
11965e0ace2SJie Deng 	_val = (_val << _pos) & GENMASK(_pos + _len - 1, _pos);		\
12065e0ace2SJie Deng 	_var = (_var & ~GENMASK(_pos + _len - 1, _pos)) | _val;		\
12165e0ace2SJie Deng })
12265e0ace2SJie Deng 
12365e0ace2SJie Deng #define XLGMAC_SET_REG_BITS_LE(var, pos, len, val) ({			\
12465e0ace2SJie Deng 	typeof(var) _var = (var);					\
12565e0ace2SJie Deng 	typeof(pos) _pos = (pos);					\
12665e0ace2SJie Deng 	typeof(len) _len = (len);					\
12765e0ace2SJie Deng 	typeof(val) _val = (val);					\
12865e0ace2SJie Deng 	_val = (_val << _pos) & GENMASK(_pos + _len - 1, _pos);		\
12965e0ace2SJie Deng 	_var = (_var & ~GENMASK(_pos + _len - 1, _pos)) | _val;		\
13065e0ace2SJie Deng 	cpu_to_le32(_var);						\
13165e0ace2SJie Deng })
13265e0ace2SJie Deng 
13365e0ace2SJie Deng struct xlgmac_pdata;
13465e0ace2SJie Deng 
13565e0ace2SJie Deng enum xlgmac_int {
13665e0ace2SJie Deng 	XLGMAC_INT_DMA_CH_SR_TI,
13765e0ace2SJie Deng 	XLGMAC_INT_DMA_CH_SR_TPS,
13865e0ace2SJie Deng 	XLGMAC_INT_DMA_CH_SR_TBU,
13965e0ace2SJie Deng 	XLGMAC_INT_DMA_CH_SR_RI,
14065e0ace2SJie Deng 	XLGMAC_INT_DMA_CH_SR_RBU,
14165e0ace2SJie Deng 	XLGMAC_INT_DMA_CH_SR_RPS,
14265e0ace2SJie Deng 	XLGMAC_INT_DMA_CH_SR_TI_RI,
14365e0ace2SJie Deng 	XLGMAC_INT_DMA_CH_SR_FBE,
14465e0ace2SJie Deng 	XLGMAC_INT_DMA_ALL,
14565e0ace2SJie Deng };
14665e0ace2SJie Deng 
14765e0ace2SJie Deng struct xlgmac_stats {
14865e0ace2SJie Deng 	/* MMC TX counters */
14965e0ace2SJie Deng 	u64 txoctetcount_gb;
15065e0ace2SJie Deng 	u64 txframecount_gb;
15165e0ace2SJie Deng 	u64 txbroadcastframes_g;
15265e0ace2SJie Deng 	u64 txmulticastframes_g;
15365e0ace2SJie Deng 	u64 tx64octets_gb;
15465e0ace2SJie Deng 	u64 tx65to127octets_gb;
15565e0ace2SJie Deng 	u64 tx128to255octets_gb;
15665e0ace2SJie Deng 	u64 tx256to511octets_gb;
15765e0ace2SJie Deng 	u64 tx512to1023octets_gb;
15865e0ace2SJie Deng 	u64 tx1024tomaxoctets_gb;
15965e0ace2SJie Deng 	u64 txunicastframes_gb;
16065e0ace2SJie Deng 	u64 txmulticastframes_gb;
16165e0ace2SJie Deng 	u64 txbroadcastframes_gb;
16265e0ace2SJie Deng 	u64 txunderflowerror;
16365e0ace2SJie Deng 	u64 txoctetcount_g;
16465e0ace2SJie Deng 	u64 txframecount_g;
16565e0ace2SJie Deng 	u64 txpauseframes;
16665e0ace2SJie Deng 	u64 txvlanframes_g;
16765e0ace2SJie Deng 
16865e0ace2SJie Deng 	/* MMC RX counters */
16965e0ace2SJie Deng 	u64 rxframecount_gb;
17065e0ace2SJie Deng 	u64 rxoctetcount_gb;
17165e0ace2SJie Deng 	u64 rxoctetcount_g;
17265e0ace2SJie Deng 	u64 rxbroadcastframes_g;
17365e0ace2SJie Deng 	u64 rxmulticastframes_g;
17465e0ace2SJie Deng 	u64 rxcrcerror;
17565e0ace2SJie Deng 	u64 rxrunterror;
17665e0ace2SJie Deng 	u64 rxjabbererror;
17765e0ace2SJie Deng 	u64 rxundersize_g;
17865e0ace2SJie Deng 	u64 rxoversize_g;
17965e0ace2SJie Deng 	u64 rx64octets_gb;
18065e0ace2SJie Deng 	u64 rx65to127octets_gb;
18165e0ace2SJie Deng 	u64 rx128to255octets_gb;
18265e0ace2SJie Deng 	u64 rx256to511octets_gb;
18365e0ace2SJie Deng 	u64 rx512to1023octets_gb;
18465e0ace2SJie Deng 	u64 rx1024tomaxoctets_gb;
18565e0ace2SJie Deng 	u64 rxunicastframes_g;
18665e0ace2SJie Deng 	u64 rxlengtherror;
18765e0ace2SJie Deng 	u64 rxoutofrangetype;
18865e0ace2SJie Deng 	u64 rxpauseframes;
18965e0ace2SJie Deng 	u64 rxfifooverflow;
19065e0ace2SJie Deng 	u64 rxvlanframes_gb;
19165e0ace2SJie Deng 	u64 rxwatchdogerror;
19265e0ace2SJie Deng 
19365e0ace2SJie Deng 	/* Extra counters */
19465e0ace2SJie Deng 	u64 tx_tso_packets;
19565e0ace2SJie Deng 	u64 rx_split_header_packets;
196d4d49bc1SJie Deng 	u64 tx_process_stopped;
197d4d49bc1SJie Deng 	u64 rx_process_stopped;
198d4d49bc1SJie Deng 	u64 tx_buffer_unavailable;
19965e0ace2SJie Deng 	u64 rx_buffer_unavailable;
200d4d49bc1SJie Deng 	u64 fatal_bus_error;
201d4d49bc1SJie Deng 	u64 tx_vlan_packets;
202d4d49bc1SJie Deng 	u64 rx_vlan_packets;
203d4d49bc1SJie Deng 	u64 napi_poll_isr;
204d4d49bc1SJie Deng 	u64 napi_poll_txtimer;
20565e0ace2SJie Deng };
20665e0ace2SJie Deng 
20765e0ace2SJie Deng struct xlgmac_ring_buf {
20865e0ace2SJie Deng 	struct sk_buff *skb;
20965e0ace2SJie Deng 	dma_addr_t skb_dma;
21065e0ace2SJie Deng 	unsigned int skb_len;
21165e0ace2SJie Deng };
21265e0ace2SJie Deng 
21365e0ace2SJie Deng /* Common Tx and Rx DMA hardware descriptor */
21465e0ace2SJie Deng struct xlgmac_dma_desc {
21565e0ace2SJie Deng 	__le32 desc0;
21665e0ace2SJie Deng 	__le32 desc1;
21765e0ace2SJie Deng 	__le32 desc2;
21865e0ace2SJie Deng 	__le32 desc3;
21965e0ace2SJie Deng };
22065e0ace2SJie Deng 
22165e0ace2SJie Deng /* Page allocation related values */
22265e0ace2SJie Deng struct xlgmac_page_alloc {
22365e0ace2SJie Deng 	struct page *pages;
22465e0ace2SJie Deng 	unsigned int pages_len;
22565e0ace2SJie Deng 	unsigned int pages_offset;
22665e0ace2SJie Deng 
22765e0ace2SJie Deng 	dma_addr_t pages_dma;
22865e0ace2SJie Deng };
22965e0ace2SJie Deng 
23065e0ace2SJie Deng /* Ring entry buffer data */
23165e0ace2SJie Deng struct xlgmac_buffer_data {
23265e0ace2SJie Deng 	struct xlgmac_page_alloc pa;
23365e0ace2SJie Deng 	struct xlgmac_page_alloc pa_unmap;
23465e0ace2SJie Deng 
23565e0ace2SJie Deng 	dma_addr_t dma_base;
23665e0ace2SJie Deng 	unsigned long dma_off;
23765e0ace2SJie Deng 	unsigned int dma_len;
23865e0ace2SJie Deng };
23965e0ace2SJie Deng 
24065e0ace2SJie Deng /* Tx-related desc data */
24165e0ace2SJie Deng struct xlgmac_tx_desc_data {
24265e0ace2SJie Deng 	unsigned int packets;		/* BQL packet count */
24365e0ace2SJie Deng 	unsigned int bytes;		/* BQL byte count */
24465e0ace2SJie Deng };
24565e0ace2SJie Deng 
24665e0ace2SJie Deng /* Rx-related desc data */
24765e0ace2SJie Deng struct xlgmac_rx_desc_data {
24865e0ace2SJie Deng 	struct xlgmac_buffer_data hdr;	/* Header locations */
24965e0ace2SJie Deng 	struct xlgmac_buffer_data buf;	/* Payload locations */
25065e0ace2SJie Deng 
25165e0ace2SJie Deng 	unsigned short hdr_len;		/* Length of received header */
25265e0ace2SJie Deng 	unsigned short len;		/* Length of received packet */
25365e0ace2SJie Deng };
25465e0ace2SJie Deng 
25565e0ace2SJie Deng struct xlgmac_pkt_info {
25665e0ace2SJie Deng 	struct sk_buff *skb;
25765e0ace2SJie Deng 
25865e0ace2SJie Deng 	unsigned int attributes;
25965e0ace2SJie Deng 
26065e0ace2SJie Deng 	unsigned int errors;
26165e0ace2SJie Deng 
26265e0ace2SJie Deng 	/* descriptors needed for this packet */
26365e0ace2SJie Deng 	unsigned int desc_count;
26465e0ace2SJie Deng 	unsigned int length;
26565e0ace2SJie Deng 
26665e0ace2SJie Deng 	unsigned int tx_packets;
26765e0ace2SJie Deng 	unsigned int tx_bytes;
26865e0ace2SJie Deng 
26965e0ace2SJie Deng 	unsigned int header_len;
27065e0ace2SJie Deng 	unsigned int tcp_header_len;
27165e0ace2SJie Deng 	unsigned int tcp_payload_len;
27265e0ace2SJie Deng 	unsigned short mss;
27365e0ace2SJie Deng 
27465e0ace2SJie Deng 	unsigned short vlan_ctag;
27565e0ace2SJie Deng 
27665e0ace2SJie Deng 	u64 rx_tstamp;
27765e0ace2SJie Deng 
27865e0ace2SJie Deng 	u32 rss_hash;
27965e0ace2SJie Deng 	enum pkt_hash_types rss_hash_type;
28065e0ace2SJie Deng };
28165e0ace2SJie Deng 
28265e0ace2SJie Deng struct xlgmac_desc_data {
28365e0ace2SJie Deng 	/* dma_desc: Virtual address of descriptor
28465e0ace2SJie Deng 	 *  dma_desc_addr: DMA address of descriptor
28565e0ace2SJie Deng 	 */
28665e0ace2SJie Deng 	struct xlgmac_dma_desc *dma_desc;
28765e0ace2SJie Deng 	dma_addr_t dma_desc_addr;
28865e0ace2SJie Deng 
28965e0ace2SJie Deng 	/* skb: Virtual address of SKB
29065e0ace2SJie Deng 	 *  skb_dma: DMA address of SKB data
29165e0ace2SJie Deng 	 *  skb_dma_len: Length of SKB DMA area
29265e0ace2SJie Deng 	 */
29365e0ace2SJie Deng 	struct sk_buff *skb;
29465e0ace2SJie Deng 	dma_addr_t skb_dma;
29565e0ace2SJie Deng 	unsigned int skb_dma_len;
29665e0ace2SJie Deng 
29765e0ace2SJie Deng 	/* Tx/Rx -related data */
29865e0ace2SJie Deng 	struct xlgmac_tx_desc_data tx;
29965e0ace2SJie Deng 	struct xlgmac_rx_desc_data rx;
30065e0ace2SJie Deng 
30165e0ace2SJie Deng 	unsigned int mapped_as_page;
30265e0ace2SJie Deng 
30365e0ace2SJie Deng 	/* Incomplete receive save location.  If the budget is exhausted
30465e0ace2SJie Deng 	 * or the last descriptor (last normal descriptor or a following
30565e0ace2SJie Deng 	 * context descriptor) has not been DMA'd yet the current state
30665e0ace2SJie Deng 	 * of the receive processing needs to be saved.
30765e0ace2SJie Deng 	 */
30865e0ace2SJie Deng 	unsigned int state_saved;
30965e0ace2SJie Deng 	struct {
31065e0ace2SJie Deng 		struct sk_buff *skb;
31165e0ace2SJie Deng 		unsigned int len;
31265e0ace2SJie Deng 		unsigned int error;
31365e0ace2SJie Deng 	} state;
31465e0ace2SJie Deng };
31565e0ace2SJie Deng 
31665e0ace2SJie Deng struct xlgmac_ring {
31765e0ace2SJie Deng 	/* Per packet related information */
31865e0ace2SJie Deng 	struct xlgmac_pkt_info pkt_info;
31965e0ace2SJie Deng 
32065e0ace2SJie Deng 	/* Virtual/DMA addresses of DMA descriptor list and the total count */
32165e0ace2SJie Deng 	struct xlgmac_dma_desc *dma_desc_head;
32265e0ace2SJie Deng 	dma_addr_t dma_desc_head_addr;
32365e0ace2SJie Deng 	unsigned int dma_desc_count;
32465e0ace2SJie Deng 
32565e0ace2SJie Deng 	/* Array of descriptor data corresponding the DMA descriptor
32665e0ace2SJie Deng 	 * (always use the XLGMAC_GET_DESC_DATA macro to access this data)
32765e0ace2SJie Deng 	 */
32865e0ace2SJie Deng 	struct xlgmac_desc_data *desc_data_head;
32965e0ace2SJie Deng 
33065e0ace2SJie Deng 	/* Page allocation for RX buffers */
33165e0ace2SJie Deng 	struct xlgmac_page_alloc rx_hdr_pa;
33265e0ace2SJie Deng 	struct xlgmac_page_alloc rx_buf_pa;
33365e0ace2SJie Deng 
33465e0ace2SJie Deng 	/* Ring index values
33565e0ace2SJie Deng 	 *  cur   - Tx: index of descriptor to be used for current transfer
33665e0ace2SJie Deng 	 *          Rx: index of descriptor to check for packet availability
33765e0ace2SJie Deng 	 *  dirty - Tx: index of descriptor to check for transfer complete
33865e0ace2SJie Deng 	 *          Rx: index of descriptor to check for buffer reallocation
33965e0ace2SJie Deng 	 */
34065e0ace2SJie Deng 	unsigned int cur;
34165e0ace2SJie Deng 	unsigned int dirty;
34265e0ace2SJie Deng 
34365e0ace2SJie Deng 	/* Coalesce frame count used for interrupt bit setting */
34465e0ace2SJie Deng 	unsigned int coalesce_count;
34565e0ace2SJie Deng 
34665e0ace2SJie Deng 	union {
34765e0ace2SJie Deng 		struct {
34865e0ace2SJie Deng 			unsigned int xmit_more;
34965e0ace2SJie Deng 			unsigned int queue_stopped;
35065e0ace2SJie Deng 			unsigned short cur_mss;
35165e0ace2SJie Deng 			unsigned short cur_vlan_ctag;
35265e0ace2SJie Deng 		} tx;
35365e0ace2SJie Deng 	};
35465e0ace2SJie Deng } ____cacheline_aligned;
35565e0ace2SJie Deng 
35665e0ace2SJie Deng struct xlgmac_channel {
35765e0ace2SJie Deng 	char name[16];
35865e0ace2SJie Deng 
35965e0ace2SJie Deng 	/* Address of private data area for device */
36065e0ace2SJie Deng 	struct xlgmac_pdata *pdata;
36165e0ace2SJie Deng 
36265e0ace2SJie Deng 	/* Queue index and base address of queue's DMA registers */
36365e0ace2SJie Deng 	unsigned int queue_index;
36465e0ace2SJie Deng 	void __iomem *dma_regs;
36565e0ace2SJie Deng 
36665e0ace2SJie Deng 	/* Per channel interrupt irq number */
36765e0ace2SJie Deng 	int dma_irq;
36865e0ace2SJie Deng 	char dma_irq_name[IFNAMSIZ + 32];
36965e0ace2SJie Deng 
37065e0ace2SJie Deng 	/* Netdev related settings */
37165e0ace2SJie Deng 	struct napi_struct napi;
37265e0ace2SJie Deng 
37365e0ace2SJie Deng 	unsigned int saved_ier;
37465e0ace2SJie Deng 
37565e0ace2SJie Deng 	unsigned int tx_timer_active;
37665e0ace2SJie Deng 	struct timer_list tx_timer;
37765e0ace2SJie Deng 
37865e0ace2SJie Deng 	struct xlgmac_ring *tx_ring;
37965e0ace2SJie Deng 	struct xlgmac_ring *rx_ring;
38065e0ace2SJie Deng } ____cacheline_aligned;
38165e0ace2SJie Deng 
38265e0ace2SJie Deng struct xlgmac_desc_ops {
383a455fcd7SColin Ian King 	int (*alloc_channels_and_rings)(struct xlgmac_pdata *pdata);
38465e0ace2SJie Deng 	void (*free_channels_and_rings)(struct xlgmac_pdata *pdata);
38565e0ace2SJie Deng 	int (*map_tx_skb)(struct xlgmac_channel *channel,
38665e0ace2SJie Deng 			  struct sk_buff *skb);
38765e0ace2SJie Deng 	int (*map_rx_buffer)(struct xlgmac_pdata *pdata,
38865e0ace2SJie Deng 			     struct xlgmac_ring *ring,
38965e0ace2SJie Deng 			struct xlgmac_desc_data *desc_data);
39065e0ace2SJie Deng 	void (*unmap_desc_data)(struct xlgmac_pdata *pdata,
39165e0ace2SJie Deng 				struct xlgmac_desc_data *desc_data);
39265e0ace2SJie Deng 	void (*tx_desc_init)(struct xlgmac_pdata *pdata);
39365e0ace2SJie Deng 	void (*rx_desc_init)(struct xlgmac_pdata *pdata);
39465e0ace2SJie Deng };
39565e0ace2SJie Deng 
39665e0ace2SJie Deng struct xlgmac_hw_ops {
39765e0ace2SJie Deng 	int (*init)(struct xlgmac_pdata *pdata);
39865e0ace2SJie Deng 	int (*exit)(struct xlgmac_pdata *pdata);
39965e0ace2SJie Deng 
40065e0ace2SJie Deng 	int (*tx_complete)(struct xlgmac_dma_desc *dma_desc);
40165e0ace2SJie Deng 
40265e0ace2SJie Deng 	void (*enable_tx)(struct xlgmac_pdata *pdata);
40365e0ace2SJie Deng 	void (*disable_tx)(struct xlgmac_pdata *pdata);
40465e0ace2SJie Deng 	void (*enable_rx)(struct xlgmac_pdata *pdata);
40565e0ace2SJie Deng 	void (*disable_rx)(struct xlgmac_pdata *pdata);
40665e0ace2SJie Deng 
40765e0ace2SJie Deng 	int (*enable_int)(struct xlgmac_channel *channel,
40865e0ace2SJie Deng 			  enum xlgmac_int int_id);
40965e0ace2SJie Deng 	int (*disable_int)(struct xlgmac_channel *channel,
41065e0ace2SJie Deng 			   enum xlgmac_int int_id);
41165e0ace2SJie Deng 	void (*dev_xmit)(struct xlgmac_channel *channel);
41265e0ace2SJie Deng 	int (*dev_read)(struct xlgmac_channel *channel);
41365e0ace2SJie Deng 
41476660757SJakub Kicinski 	int (*set_mac_address)(struct xlgmac_pdata *pdata, const u8 *addr);
41565e0ace2SJie Deng 	int (*config_rx_mode)(struct xlgmac_pdata *pdata);
41665e0ace2SJie Deng 	int (*enable_rx_csum)(struct xlgmac_pdata *pdata);
41765e0ace2SJie Deng 	int (*disable_rx_csum)(struct xlgmac_pdata *pdata);
41865e0ace2SJie Deng 
41965e0ace2SJie Deng 	/* For MII speed configuration */
42065e0ace2SJie Deng 	int (*set_xlgmii_25000_speed)(struct xlgmac_pdata *pdata);
42165e0ace2SJie Deng 	int (*set_xlgmii_40000_speed)(struct xlgmac_pdata *pdata);
42265e0ace2SJie Deng 	int (*set_xlgmii_50000_speed)(struct xlgmac_pdata *pdata);
42365e0ace2SJie Deng 	int (*set_xlgmii_100000_speed)(struct xlgmac_pdata *pdata);
42465e0ace2SJie Deng 
42565e0ace2SJie Deng 	/* For descriptor related operation */
42665e0ace2SJie Deng 	void (*tx_desc_init)(struct xlgmac_channel *channel);
42765e0ace2SJie Deng 	void (*rx_desc_init)(struct xlgmac_channel *channel);
42865e0ace2SJie Deng 	void (*tx_desc_reset)(struct xlgmac_desc_data *desc_data);
42965e0ace2SJie Deng 	void (*rx_desc_reset)(struct xlgmac_pdata *pdata,
43065e0ace2SJie Deng 			      struct xlgmac_desc_data *desc_data,
43165e0ace2SJie Deng 			unsigned int index);
43265e0ace2SJie Deng 	int (*is_last_desc)(struct xlgmac_dma_desc *dma_desc);
43365e0ace2SJie Deng 	int (*is_context_desc)(struct xlgmac_dma_desc *dma_desc);
43465e0ace2SJie Deng 	void (*tx_start_xmit)(struct xlgmac_channel *channel,
43565e0ace2SJie Deng 			      struct xlgmac_ring *ring);
43665e0ace2SJie Deng 
43765e0ace2SJie Deng 	/* For Flow Control */
43865e0ace2SJie Deng 	int (*config_tx_flow_control)(struct xlgmac_pdata *pdata);
43965e0ace2SJie Deng 	int (*config_rx_flow_control)(struct xlgmac_pdata *pdata);
44065e0ace2SJie Deng 
44165e0ace2SJie Deng 	/* For Vlan related config */
44265e0ace2SJie Deng 	int (*enable_rx_vlan_stripping)(struct xlgmac_pdata *pdata);
44365e0ace2SJie Deng 	int (*disable_rx_vlan_stripping)(struct xlgmac_pdata *pdata);
44465e0ace2SJie Deng 	int (*enable_rx_vlan_filtering)(struct xlgmac_pdata *pdata);
44565e0ace2SJie Deng 	int (*disable_rx_vlan_filtering)(struct xlgmac_pdata *pdata);
44665e0ace2SJie Deng 	int (*update_vlan_hash_table)(struct xlgmac_pdata *pdata);
44765e0ace2SJie Deng 
44865e0ace2SJie Deng 	/* For RX coalescing */
44965e0ace2SJie Deng 	int (*config_rx_coalesce)(struct xlgmac_pdata *pdata);
45065e0ace2SJie Deng 	int (*config_tx_coalesce)(struct xlgmac_pdata *pdata);
45165e0ace2SJie Deng 	unsigned int (*usec_to_riwt)(struct xlgmac_pdata *pdata,
45265e0ace2SJie Deng 				     unsigned int usec);
45365e0ace2SJie Deng 	unsigned int (*riwt_to_usec)(struct xlgmac_pdata *pdata,
45465e0ace2SJie Deng 				     unsigned int riwt);
45565e0ace2SJie Deng 
45665e0ace2SJie Deng 	/* For RX and TX threshold config */
45765e0ace2SJie Deng 	int (*config_rx_threshold)(struct xlgmac_pdata *pdata,
45865e0ace2SJie Deng 				   unsigned int val);
45965e0ace2SJie Deng 	int (*config_tx_threshold)(struct xlgmac_pdata *pdata,
46065e0ace2SJie Deng 				   unsigned int val);
46165e0ace2SJie Deng 
46265e0ace2SJie Deng 	/* For RX and TX Store and Forward Mode config */
46365e0ace2SJie Deng 	int (*config_rsf_mode)(struct xlgmac_pdata *pdata,
46465e0ace2SJie Deng 			       unsigned int val);
46565e0ace2SJie Deng 	int (*config_tsf_mode)(struct xlgmac_pdata *pdata,
46665e0ace2SJie Deng 			       unsigned int val);
46765e0ace2SJie Deng 
46865e0ace2SJie Deng 	/* For TX DMA Operate on Second Frame config */
46965e0ace2SJie Deng 	int (*config_osp_mode)(struct xlgmac_pdata *pdata);
47065e0ace2SJie Deng 
47165e0ace2SJie Deng 	/* For RX and TX PBL config */
47265e0ace2SJie Deng 	int (*config_rx_pbl_val)(struct xlgmac_pdata *pdata);
47365e0ace2SJie Deng 	int (*get_rx_pbl_val)(struct xlgmac_pdata *pdata);
47465e0ace2SJie Deng 	int (*config_tx_pbl_val)(struct xlgmac_pdata *pdata);
47565e0ace2SJie Deng 	int (*get_tx_pbl_val)(struct xlgmac_pdata *pdata);
47665e0ace2SJie Deng 	int (*config_pblx8)(struct xlgmac_pdata *pdata);
47765e0ace2SJie Deng 
47865e0ace2SJie Deng 	/* For MMC statistics */
47965e0ace2SJie Deng 	void (*rx_mmc_int)(struct xlgmac_pdata *pdata);
48065e0ace2SJie Deng 	void (*tx_mmc_int)(struct xlgmac_pdata *pdata);
48165e0ace2SJie Deng 	void (*read_mmc_stats)(struct xlgmac_pdata *pdata);
48265e0ace2SJie Deng 
48365e0ace2SJie Deng 	/* For Receive Side Scaling */
48465e0ace2SJie Deng 	int (*enable_rss)(struct xlgmac_pdata *pdata);
48565e0ace2SJie Deng 	int (*disable_rss)(struct xlgmac_pdata *pdata);
48665e0ace2SJie Deng 	int (*set_rss_hash_key)(struct xlgmac_pdata *pdata,
48765e0ace2SJie Deng 				const u8 *key);
48865e0ace2SJie Deng 	int (*set_rss_lookup_table)(struct xlgmac_pdata *pdata,
48965e0ace2SJie Deng 				    const u32 *table);
49065e0ace2SJie Deng };
49165e0ace2SJie Deng 
49265e0ace2SJie Deng /* This structure contains flags that indicate what hardware features
49365e0ace2SJie Deng  * or configurations are present in the device.
49465e0ace2SJie Deng  */
49565e0ace2SJie Deng struct xlgmac_hw_features {
49665e0ace2SJie Deng 	/* HW Version */
49765e0ace2SJie Deng 	unsigned int version;
49865e0ace2SJie Deng 
49965e0ace2SJie Deng 	/* HW Feature Register0 */
50065e0ace2SJie Deng 	unsigned int phyifsel;		/* PHY interface support */
50165e0ace2SJie Deng 	unsigned int vlhash;		/* VLAN Hash Filter */
50265e0ace2SJie Deng 	unsigned int sma;		/* SMA(MDIO) Interface */
50365e0ace2SJie Deng 	unsigned int rwk;		/* PMT remote wake-up packet */
50465e0ace2SJie Deng 	unsigned int mgk;		/* PMT magic packet */
50565e0ace2SJie Deng 	unsigned int mmc;		/* RMON module */
50665e0ace2SJie Deng 	unsigned int aoe;		/* ARP Offload */
50765e0ace2SJie Deng 	unsigned int ts;		/* IEEE 1588-2008 Advanced Timestamp */
50865e0ace2SJie Deng 	unsigned int eee;		/* Energy Efficient Ethernet */
50965e0ace2SJie Deng 	unsigned int tx_coe;		/* Tx Checksum Offload */
51065e0ace2SJie Deng 	unsigned int rx_coe;		/* Rx Checksum Offload */
51165e0ace2SJie Deng 	unsigned int addn_mac;		/* Additional MAC Addresses */
51265e0ace2SJie Deng 	unsigned int ts_src;		/* Timestamp Source */
51365e0ace2SJie Deng 	unsigned int sa_vlan_ins;	/* Source Address or VLAN Insertion */
51465e0ace2SJie Deng 
51565e0ace2SJie Deng 	/* HW Feature Register1 */
51665e0ace2SJie Deng 	unsigned int rx_fifo_size;	/* MTL Receive FIFO Size */
51765e0ace2SJie Deng 	unsigned int tx_fifo_size;	/* MTL Transmit FIFO Size */
51865e0ace2SJie Deng 	unsigned int adv_ts_hi;		/* Advance Timestamping High Word */
51965e0ace2SJie Deng 	unsigned int dma_width;		/* DMA width */
52065e0ace2SJie Deng 	unsigned int dcb;		/* DCB Feature */
52165e0ace2SJie Deng 	unsigned int sph;		/* Split Header Feature */
52265e0ace2SJie Deng 	unsigned int tso;		/* TCP Segmentation Offload */
52365e0ace2SJie Deng 	unsigned int dma_debug;		/* DMA Debug Registers */
52465e0ace2SJie Deng 	unsigned int rss;		/* Receive Side Scaling */
52565e0ace2SJie Deng 	unsigned int tc_cnt;		/* Number of Traffic Classes */
52665e0ace2SJie Deng 	unsigned int hash_table_size;	/* Hash Table Size */
52765e0ace2SJie Deng 	unsigned int l3l4_filter_num;	/* Number of L3-L4 Filters */
52865e0ace2SJie Deng 
52965e0ace2SJie Deng 	/* HW Feature Register2 */
53065e0ace2SJie Deng 	unsigned int rx_q_cnt;		/* Number of MTL Receive Queues */
53165e0ace2SJie Deng 	unsigned int tx_q_cnt;		/* Number of MTL Transmit Queues */
53265e0ace2SJie Deng 	unsigned int rx_ch_cnt;		/* Number of DMA Receive Channels */
53365e0ace2SJie Deng 	unsigned int tx_ch_cnt;		/* Number of DMA Transmit Channels */
53465e0ace2SJie Deng 	unsigned int pps_out_num;	/* Number of PPS outputs */
53565e0ace2SJie Deng 	unsigned int aux_snap_num;	/* Number of Aux snapshot inputs */
53665e0ace2SJie Deng };
53765e0ace2SJie Deng 
53865e0ace2SJie Deng struct xlgmac_resources {
53965e0ace2SJie Deng 	void __iomem *addr;
54065e0ace2SJie Deng 	int irq;
54165e0ace2SJie Deng };
54265e0ace2SJie Deng 
54365e0ace2SJie Deng struct xlgmac_pdata {
54465e0ace2SJie Deng 	struct net_device *netdev;
54565e0ace2SJie Deng 	struct device *dev;
54665e0ace2SJie Deng 
54765e0ace2SJie Deng 	struct xlgmac_hw_ops hw_ops;
54865e0ace2SJie Deng 	struct xlgmac_desc_ops desc_ops;
54965e0ace2SJie Deng 
55065e0ace2SJie Deng 	/* Device statistics */
55165e0ace2SJie Deng 	struct xlgmac_stats stats;
55265e0ace2SJie Deng 
55365e0ace2SJie Deng 	u32 msg_enable;
55465e0ace2SJie Deng 
55565e0ace2SJie Deng 	/* MAC registers base */
55665e0ace2SJie Deng 	void __iomem *mac_regs;
55765e0ace2SJie Deng 
55865e0ace2SJie Deng 	/* Hardware features of the device */
55965e0ace2SJie Deng 	struct xlgmac_hw_features hw_feat;
56065e0ace2SJie Deng 
56165e0ace2SJie Deng 	struct work_struct restart_work;
56265e0ace2SJie Deng 
56365e0ace2SJie Deng 	/* Rings for Tx/Rx on a DMA channel */
56465e0ace2SJie Deng 	struct xlgmac_channel *channel_head;
56565e0ace2SJie Deng 	unsigned int channel_count;
56665e0ace2SJie Deng 	unsigned int tx_ring_count;
56765e0ace2SJie Deng 	unsigned int rx_ring_count;
56865e0ace2SJie Deng 	unsigned int tx_desc_count;
56965e0ace2SJie Deng 	unsigned int rx_desc_count;
57065e0ace2SJie Deng 	unsigned int tx_q_count;
57165e0ace2SJie Deng 	unsigned int rx_q_count;
57265e0ace2SJie Deng 
57365e0ace2SJie Deng 	/* Tx/Rx common settings */
57465e0ace2SJie Deng 	unsigned int pblx8;
57565e0ace2SJie Deng 
57665e0ace2SJie Deng 	/* Tx settings */
57765e0ace2SJie Deng 	unsigned int tx_sf_mode;
57865e0ace2SJie Deng 	unsigned int tx_threshold;
57965e0ace2SJie Deng 	unsigned int tx_pbl;
58065e0ace2SJie Deng 	unsigned int tx_osp_mode;
58165e0ace2SJie Deng 
58265e0ace2SJie Deng 	/* Rx settings */
58365e0ace2SJie Deng 	unsigned int rx_sf_mode;
58465e0ace2SJie Deng 	unsigned int rx_threshold;
58565e0ace2SJie Deng 	unsigned int rx_pbl;
58665e0ace2SJie Deng 
58765e0ace2SJie Deng 	/* Tx coalescing settings */
58865e0ace2SJie Deng 	unsigned int tx_usecs;
58965e0ace2SJie Deng 	unsigned int tx_frames;
59065e0ace2SJie Deng 
59165e0ace2SJie Deng 	/* Rx coalescing settings */
59265e0ace2SJie Deng 	unsigned int rx_riwt;
59365e0ace2SJie Deng 	unsigned int rx_usecs;
59465e0ace2SJie Deng 	unsigned int rx_frames;
59565e0ace2SJie Deng 
59665e0ace2SJie Deng 	/* Current Rx buffer size */
59765e0ace2SJie Deng 	unsigned int rx_buf_size;
59865e0ace2SJie Deng 
59965e0ace2SJie Deng 	/* Flow control settings */
60065e0ace2SJie Deng 	unsigned int tx_pause;
60165e0ace2SJie Deng 	unsigned int rx_pause;
60265e0ace2SJie Deng 
60365e0ace2SJie Deng 	/* Device interrupt number */
60465e0ace2SJie Deng 	int dev_irq;
60565e0ace2SJie Deng 	unsigned int per_channel_irq;
60665e0ace2SJie Deng 	int channel_irq[XLGMAC_MAX_DMA_CHANNELS];
60765e0ace2SJie Deng 
60865e0ace2SJie Deng 	/* Netdev related settings */
60965e0ace2SJie Deng 	unsigned char mac_addr[ETH_ALEN];
61065e0ace2SJie Deng 	netdev_features_t netdev_features;
61165e0ace2SJie Deng 	struct napi_struct napi;
61265e0ace2SJie Deng 
61365e0ace2SJie Deng 	/* Filtering support */
61465e0ace2SJie Deng 	unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
61565e0ace2SJie Deng 
61665e0ace2SJie Deng 	/* Device clocks */
61765e0ace2SJie Deng 	unsigned long sysclk_rate;
61865e0ace2SJie Deng 
61965e0ace2SJie Deng 	/* RSS addressing mutex */
62065e0ace2SJie Deng 	struct mutex rss_mutex;
62165e0ace2SJie Deng 
62265e0ace2SJie Deng 	/* Receive Side Scaling settings */
62365e0ace2SJie Deng 	u8 rss_key[XLGMAC_RSS_HASH_KEY_SIZE];
62465e0ace2SJie Deng 	u32 rss_table[XLGMAC_RSS_MAX_TABLE_SIZE];
62565e0ace2SJie Deng 	u32 rss_options;
62665e0ace2SJie Deng 
62765e0ace2SJie Deng 	int phy_speed;
62865e0ace2SJie Deng 
62965e0ace2SJie Deng 	char drv_name[32];
63065e0ace2SJie Deng 	char drv_ver[32];
63165e0ace2SJie Deng };
63265e0ace2SJie Deng 
63365e0ace2SJie Deng void xlgmac_init_desc_ops(struct xlgmac_desc_ops *desc_ops);
63465e0ace2SJie Deng void xlgmac_init_hw_ops(struct xlgmac_hw_ops *hw_ops);
63565e0ace2SJie Deng const struct net_device_ops *xlgmac_get_netdev_ops(void);
636d4d49bc1SJie Deng const struct ethtool_ops *xlgmac_get_ethtool_ops(void);
63765e0ace2SJie Deng void xlgmac_dump_tx_desc(struct xlgmac_pdata *pdata,
63865e0ace2SJie Deng 			 struct xlgmac_ring *ring,
63965e0ace2SJie Deng 			 unsigned int idx,
64065e0ace2SJie Deng 			 unsigned int count,
64165e0ace2SJie Deng 			 unsigned int flag);
64265e0ace2SJie Deng void xlgmac_dump_rx_desc(struct xlgmac_pdata *pdata,
64365e0ace2SJie Deng 			 struct xlgmac_ring *ring,
64465e0ace2SJie Deng 			 unsigned int idx);
64565e0ace2SJie Deng void xlgmac_print_pkt(struct net_device *netdev,
64665e0ace2SJie Deng 		      struct sk_buff *skb, bool tx_rx);
64765e0ace2SJie Deng void xlgmac_get_all_hw_features(struct xlgmac_pdata *pdata);
64865e0ace2SJie Deng void xlgmac_print_all_hw_features(struct xlgmac_pdata *pdata);
64965e0ace2SJie Deng int xlgmac_drv_probe(struct device *dev,
65065e0ace2SJie Deng 		     struct xlgmac_resources *res);
65165e0ace2SJie Deng int xlgmac_drv_remove(struct device *dev);
65265e0ace2SJie Deng 
65365e0ace2SJie Deng /* For debug prints */
65465e0ace2SJie Deng #ifdef XLGMAC_DEBUG
65565e0ace2SJie Deng #define XLGMAC_PR(fmt, args...) \
65665e0ace2SJie Deng 	pr_alert("[%s,%d]:" fmt, __func__, __LINE__, ## args)
65765e0ace2SJie Deng #else
65865e0ace2SJie Deng #define XLGMAC_PR(x...)		do { } while (0)
65965e0ace2SJie Deng #endif
66065e0ace2SJie Deng 
66165e0ace2SJie Deng #endif /* __DWC_XLGMAC_H__ */
662