1 /*
2  * Copyright (c) 2018 Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ETH_E1000_PRIV_H
8 #define ETH_E1000_PRIV_H
9 
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13 
14 #define CTRL_SLU	(1 << 6) /* Set Link Up */
15 
16 #define TCTL_EN		(1 << 1)
17 #define RCTL_EN		(1 << 1)
18 
19 #define ICR_TXDW	     (1) /* Transmit Descriptor Written Back */
20 #define ICR_TXQE	(1 << 1) /* Transmit Queue Empty */
21 #define ICR_RXO		(1 << 6) /* Receiver Overrun */
22 
23 #define IMS_RXO		(1 << 6) /* Receiver FIFO Overrun */
24 
25 #define RCTL_MPE	(1 << 4) /* Multicast Promiscuous Enabled */
26 
27 #define TDESC_EOP	     (1) /* End Of Packet */
28 #define TDESC_RS	(1 << 3) /* Report Status */
29 
30 #define RDESC_STA_DD	     (1) /* Descriptor Done */
31 #define TDESC_STA_DD	     (1) /* Descriptor Done */
32 
33 #define ETH_ALEN 6	/* TODO: Add a global reusable definition in OS */
34 
35 enum e1000_reg_t {
36 	CTRL	= 0x0000,	/* Device Control */
37 	ICR	= 0x00C0,	/* Interrupt Cause Read */
38 	ICS	= 0x00C8,	/* Interrupt Cause Set */
39 	IMS	= 0x00D0,	/* Interrupt Mask Set */
40 	RCTL	= 0x0100,	/* Receive Control */
41 	TCTL	= 0x0400,	/* Transmit Control */
42 	RDBAL	= 0x2800,	/* Rx Descriptor Base Address Low */
43 	RDBAH	= 0x2804,	/* Rx Descriptor Base Address High */
44 	RDLEN	= 0x2808,	/* Rx Descriptor Length */
45 	RDH	= 0x2810,	/* Rx Descriptor Head */
46 	RDT	= 0x2818,	/* Rx Descriptor Tail */
47 	TDBAL	= 0x3800,	/* Tx Descriptor Base Address Low */
48 	TDBAH	= 0x3804,	/* Tx Descriptor Base Address High */
49 	TDLEN	= 0x3808,	/* Tx Descriptor Length */
50 	TDH	= 0x3810,	/* Tx Descriptor Head */
51 	TDT	= 0x3818,	/* Tx Descriptor Tail */
52 	RAL	= 0x5400,	/* Receive Address Low */
53 	RAH	= 0x5404,	/* Receive Address High */
54 };
55 
56 /* Legacy TX Descriptor */
57 struct e1000_tx {
58 	uint64_t addr;
59 	uint16_t len;
60 	uint8_t  cso;
61 	uint8_t  cmd;
62 	uint8_t  sta;
63 	uint8_t  css;
64 	uint16_t special;
65 };
66 
67 /* Legacy RX Descriptor */
68 struct e1000_rx {
69 	uint64_t addr;
70 	uint16_t len;
71 	uint16_t csum;
72 	uint8_t  sta;
73 	uint8_t  err;
74 	uint16_t special;
75 };
76 
77 struct e1000_dev {
78 	volatile struct e1000_tx tx __aligned(16);
79 	volatile struct e1000_rx rx __aligned(16);
80 	mm_reg_t address;
81 
82 	/* BDF & DID/VID */
83 	struct pcie_dev *pcie;
84 
85 	/* If VLAN is enabled, there can be multiple VLAN interfaces related to
86 	 * this physical device. In that case, this iface pointer value is not
87 	 * really used for anything.
88 	 */
89 	struct net_if *iface;
90 	uint8_t mac[ETH_ALEN];
91 	uint8_t txb[NET_ETH_MTU];
92 	uint8_t rxb[NET_ETH_MTU];
93 #if defined(CONFIG_ETH_E1000_PTP_CLOCK)
94 	const struct device *ptp_clock;
95 	float clk_ratio;
96 #endif
97 };
98 
99 struct e1000_config {
100 	void (*config_func)(const struct e1000_dev *dev);
101 };
102 
103 static const char *e1000_reg_to_string(enum e1000_reg_t r)
104 	__attribute__((unused));
105 
106 #define iow32(_dev, _reg, _val) do {					\
107 	LOG_DBG("iow32 %s 0x%08x", e1000_reg_to_string(_reg), (_val)); 	\
108 	sys_write32(_val, (_dev)->address + (_reg));			\
109 } while (false)
110 
111 #define ior32(_dev, _reg)						\
112 ({									\
113 	uint32_t val = sys_read32((_dev)->address + (_reg));		\
114 	LOG_DBG("ior32 %s 0x%08x", e1000_reg_to_string(_reg), val); 	\
115 	val;								\
116 })
117 
118 #ifdef __cplusplus
119 }
120 #endif
121 
122 #endif /* ETH_E1000_PRIV_H_ */
123