1 /* ENC28J60 Stand-alone Ethernet Controller with SPI
2  *
3  * Copyright (c) 2016 Intel Corporation
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <zephyr/kernel.h>
9 #include <zephyr/drivers/gpio.h>
10 #include <zephyr/drivers/spi.h>
11 
12 #ifndef _ENC28J60_
13 #define _ENC28J60_
14 
15 /* Any Bank Registers */
16 #define ENC28J60_REG_EIE   0x1B
17 #define ENC28J60_REG_EIR   0x1C
18 #define ENC28J60_REG_ESTAT 0x1D
19 #define ENC28J60_REG_ECON2 0x1E
20 #define ENC28J60_REG_ECON1 0x1F
21 
22 /* Register Encoding
23  * Nibble 3  : 0x0 ETH Register
24  *             0x1 MAC Register
25  *             0x2 MII Register
26  * Nibble 2  : Bank number
27  * Nibble 1-0: Register address
28  */
29 
30 /* Bank 0 Registers */
31 #define ENC28J60_REG_ERDPTL   0x0000
32 #define ENC28J60_REG_ERDPTH   0x0001
33 #define ENC28J60_REG_EWRPTL   0x0002
34 #define ENC28J60_REG_EWRPTH   0x0003
35 #define ENC28J60_REG_ETXSTL   0x0004
36 #define ENC28J60_REG_ETXSTH   0x0005
37 #define ENC28J60_REG_ETXNDL   0x0006
38 #define ENC28J60_REG_ETXNDH   0x0007
39 #define ENC28J60_REG_ERXSTL   0x0008
40 #define ENC28J60_REG_ERXSTH   0x0009
41 #define ENC28J60_REG_ERXNDL   0x000A
42 #define ENC28J60_REG_ERXNDH   0x000B
43 #define ENC28J60_REG_ERXRDPTL 0x000C
44 #define ENC28J60_REG_ERXRDPTH 0x000D
45 #define ENC28J60_REG_ERXWRPTL 0x000E
46 #define ENC28J60_REG_ERXWRPTH 0x000F
47 #define ENC28J60_REG_EDMASTL  0x0010
48 #define ENC28J60_REG_EDMASTH  0x0011
49 #define ENC28J60_REG_EDMANDL  0x0012
50 #define ENC28J60_REG_EDMANDH  0x0013
51 #define ENC28J60_REG_EDMADSTL 0x0014
52 #define ENC28J60_REG_EDMADSTH 0x0015
53 #define ENC28J60_REG_EDMACSL  0x0016
54 #define ENC28J60_REG_EDMACSH  0x0017
55 
56 /* Bank 1 Registers */
57 #define ENC28J60_REG_EHT0    0x0100
58 #define ENC28J60_REG_EHT1    0x0101
59 #define ENC28J60_REG_EHT2    0x0102
60 #define ENC28J60_REG_EHT3    0x0103
61 #define ENC28J60_REG_EHT4    0x0104
62 #define ENC28J60_REG_EHT5    0x0105
63 #define ENC28J60_REG_EHT6    0x0106
64 #define ENC28J60_REG_EHT7    0x0107
65 #define ENC28J60_REG_EPMM0   0x0108
66 #define ENC28J60_REG_EPMM1   0x0109
67 #define ENC28J60_REG_EPMM2   0x010A
68 #define ENC28J60_REG_EPMM3   0x010B
69 #define ENC28J60_REG_EPMM4   0x010C
70 #define ENC28J60_REG_EPMM5   0x010D
71 #define ENC28J60_REG_EPMM6   0x010E
72 #define ENC28J60_REG_EPMM7   0x010F
73 #define ENC28J60_REG_EPMCSL  0x0110
74 #define ENC28J60_REG_EPMCSH  0x0111
75 #define ENC28J60_REG_EPMOL   0x0114
76 #define ENC28J60_REG_EPMOH   0x0115
77 #define ENC28J60_REG_EWOLIE  0x0116
78 #define ENC28J60_REG_EWOLIR  0x0117
79 #define ENC28J60_REG_ERXFCON 0x0118
80 #define ENC28J60_REG_EPKTCNT 0x0119
81 
82 /* Bank 2 Registers */
83 #define ENC28J60_REG_MACON1   0x1200
84 #define ENC28J60_REG_MACON3   0x1202
85 #define ENC28J60_REG_MACON4   0x1203
86 #define ENC28J60_REG_MABBIPG  0x1204
87 #define ENC28J60_REG_MAIPGL   0x1206
88 #define ENC28J60_REG_MAIPGH   0x1207
89 #define ENC28J60_REG_MACLCON1 0x1208
90 #define ENC28J60_REG_MACLCON2 0x1209
91 #define ENC28J60_REG_MAMXFLL  0x120A
92 #define ENC28J60_REG_MAMXFLH  0x120B
93 #define ENC28J60_REG_MAPHSUP  0x120C
94 #define ENC28J60_REG_MICON    0x2211
95 #define ENC28J60_REG_MICMD    0x2212
96 #define ENC28J60_REG_MIREGADR 0x2214
97 #define ENC28J60_REG_MIWRL    0x2216
98 #define ENC28J60_REG_MIWRH    0x2217
99 #define ENC28J60_REG_MIRDL    0x2218
100 #define ENC28J60_REG_MIRDH    0x2219
101 
102 /* Bank 3 Registers */
103 #define ENC28J60_REG_MAADR5   0x1300
104 #define ENC28J60_REG_MAADR6   0x1301
105 #define ENC28J60_REG_MAADR3   0x1302
106 #define ENC28J60_REG_MAADR4   0x1303
107 #define ENC28J60_REG_MAADR1   0x1304
108 #define ENC28J60_REG_MAADR2   0x1305
109 #define ENC28J60_REG_EBSTSD   0x0306
110 #define ENC28J60_REG_EBSTCON  0x0307
111 #define ENC28J60_REG_EBSTCSL  0x0308
112 #define ENC28J60_REG_EBSTCSH  0x0309
113 #define ENC28J60_REG_MISTAT   0x230A
114 #define ENC28J60_REG_EREVID   0x0312
115 #define ENC28J60_REG_ECOCON   0x0315
116 #define ENC28J60_REG_EFLOCON  0x0317
117 #define ENC28J60_REG_EPAUSL   0x0318
118 #define ENC28J60_REG_EPAUSH   0x0319
119 
120 /* PHY Registers */
121 #define ENC28J60_PHY_PHCON1  0x00
122 #define ENC28J60_PHY_PHSTAT1 0x01
123 #define ENC28J60_PHY_PHID1   0x02
124 #define ENC28J60_PHY_PHID2   0x03
125 #define ENC28J60_PHY_PHCON2  0x10
126 #define ENC28J60_PHY_PHSTAT2 0x11
127 #define ENC28J60_PHY_PHIE    0x12
128 #define ENC28J60_PHY_PHIR    0x13
129 #define ENC28J60_PHY_PHLCON  0x14
130 
131 /* SPI Instruction Opcodes */
132 #define  ENC28J60_SPI_RCR (0x0)
133 #define  ENC28J60_SPI_RBM (0x3A)
134 #define  ENC28J60_SPI_WCR (0x2 << 5)
135 #define  ENC28J60_SPI_WBM (0x7A)
136 #define  ENC28J60_SPI_BFS (0x4 << 5)
137 #define  ENC28J60_SPI_BFC (0x5 << 5)
138 #define  ENC28J60_SPI_SC  (0xFF)
139 
140 /* Significant bits */
141 #define ENC28J60_BIT_MICMD_MIIRD   (0x01)
142 #define ENC28J60_BIT_MISTAT_BUSY   (0x01)
143 #define ENC28J60_BIT_ESTAT_CLKRDY  (0x01)
144 #define ENC28J60_BIT_MACON1_RXPAUS (0x04)
145 #define ENC28J60_BIT_MACON1_TXPAUS (0x08)
146 #define ENC28J60_BIT_MACON1_MARXEN (0x01)
147 #define ENC28J60_BIT_MACON2_MARST  (0x80)
148 #define ENC28J60_BIT_MACON3_FULDPX (0x01)
149 #define ENC28J60_BIT_ECON1_TXRST   (0x80)
150 #define ENC28J60_BIT_ECON1_TXRTS   (0x08)
151 #define ENC28J60_BIT_ECON1_RXEN    (0x04)
152 #define ENC28J60_BIT_ECON2_PKTDEC  (0x40)
153 #define ENC28J60_BIT_EIE_TXIE      (0x08)
154 #define ENC28J60_BIT_EIE_PKTIE     (0x40)
155 #define ENC28J60_BIT_EIE_LINKIE    (0x10)
156 #define ENC28J60_BIT_EIE_INTIE     (0x80)
157 #define ENC28J60_BIT_EIR_PKTIF     (0x40)
158 #define ENC28J60_BIT_EIR_DMAIF     (0x20)
159 #define ENC28J60_BIT_EIR_LINKIF    (0x10)
160 #define ENC28J60_BIT_EIR_TXIF      (0x08)
161 #define ENC28J60_BIT_EIR_WOLIF     (0x04)
162 #define ENC28J60_BIT_EIR_TXERIF    (0x02)
163 #define ENC28J60_BIT_EIR_RXERIF    (0x01)
164 #define ENC28J60_BIT_ESTAT_TXABRT  (0x02)
165 #define ENC28J60_BIT_ESTAT_LATECOL (0x10)
166 #define ENC28J60_BIT_PHCON1_PDPXMD (0x0100)
167 #define ENC28J60_BIT_PHCON2_HDLDIS (0x0100)
168 #define ENC28J60_BIT_PHSTAT2_LSTAT (0x0400)
169 #define ENC28J60_BIT_PHIE_PGEIE    (0x0002)
170 #define ENC28J60_BIT_PHIE_PLNKIE   (0x0010)
171 
172 /* Driver Static Configuration */
173 
174 /*  Receive filters enabled:
175  *  - Unicast
176  *  - Multicast
177  *  - Broadcast
178  *  - CRC Check
179  *
180  * Used as default if hw-rx-filter property
181  * absent in DT
182  */
183 #define ENC28J60_RECEIVE_FILTERS 0xA3
184 
185 /*  MAC configuration:
186  *  - Automatic Padding
187  *  - Automatic CRC
188  *  - Frame Length Checking
189  */
190 #define ENC28J60_MAC_CONFIG   0x32
191 #define ENC28J60_MAC_BBIPG_HD 0x12
192 #define ENC28J60_MAC_BBIPG_FD 0x15
193 #define ENC28J60_MAC_NBBIPGL  0x12
194 #define ENC28J60_MAC_NBBIPGH  0x0C
195 #define ENC28J60_PHY_LEDCONF  0x3422
196 /* Status Vector size plus per packet control byte: 8 bytes */
197 #define ENC28J60_SV_SIZE 8
198 /* Per Packet Control Byte configured to follow MACON3 configuration */
199 #define ENC28J60_PPCTL_BYTE 0x0
200 
201 /* Start of RX buffer, (must be zero, Rev. B4 Errata point 5) */
202 #define ENC28J60_RXSTART 0x0000
203 /* End of RX buffer, room for 2 packets */
204 #define ENC28J60_RXEND 0x0BFF
205 
206 /* Start of TX buffer, room for 1 packet */
207 #define ENC28J60_TXSTART 0x0C00
208 /* End of TX buffer */
209 #define ENC28J60_TXEND 0x11FF
210 
211 /* Status vectors array size */
212 #define TSV_SIZE 7
213 #define RSV_SIZE 4
214 
215 /* Microchip's OUI*/
216 #define MICROCHIP_OUI_B0 0x00
217 #define MICROCHIP_OUI_B1 0x04
218 #define MICROCHIP_OUI_B2 0xA3
219 
220 #define MAX_BUFFER_LENGTH 128
221 
222 struct eth_enc28j60_config {
223 	struct spi_dt_spec spi;
224 	struct gpio_dt_spec interrupt;
225 	uint8_t full_duplex;
226 	int32_t timeout;
227 	uint8_t hw_rx_filter;
228 	bool random_mac;
229 };
230 
231 struct eth_enc28j60_runtime {
232 	struct net_if *iface;
233 	K_KERNEL_STACK_MEMBER(thread_stack,
234 			      CONFIG_ETH_ENC28J60_RX_THREAD_STACK_SIZE);
235 	struct k_thread thread;
236 	uint8_t mac_address[6];
237 	struct gpio_callback gpio_cb;
238 	struct k_sem tx_rx_sem;
239 	struct k_sem int_sem;
240 	bool iface_initialized : 1;
241 	bool iface_carrier_on_init : 1;
242 };
243 
244 #endif /*_ENC28J60_*/
245