xref: /minix/minix/drivers/net/ip1000/ip1000.c (revision 045e0ed3)
1 #include <minix/drivers.h>
2 #include <minix/netdriver.h>
3 #include <machine/pci.h>
4 #include <sys/mman.h>
5 #include "ip1000.h"
6 #include "io.h"
7 
8 /* global value */
9 static NDR_driver g_driver;
10 static int g_instance;
11 
12 /* driver interface */
13 static int NDR_init(unsigned int instance, ether_addr_t *addr);
14 static void NDR_stop(void);
15 static void NDR_mode(unsigned int mode);
16 static ssize_t NDR_recv(struct netdriver_data *data, size_t max);
17 static int NDR_send(struct netdriver_data *data, size_t size);
18 static void NDR_intr(unsigned int mask);
19 static void NDR_stat(eth_stat_t *stat);
20 
21 /* internal function */
22 static int dev_probe(NDR_driver *pdev, int instance);
23 static int dev_init_buf(NDR_driver *pdev);
24 static int dev_init_hw(NDR_driver *pdev, ether_addr_t *addr);
25 static int dev_reset_hw(NDR_driver *pdev);
26 static void dev_conf_addr(NDR_driver *pdev, ether_addr_t *addr);
27 static void dev_handler(NDR_driver *pdev);
28 static void dev_check_ints(NDR_driver *pdev);
29 
30 /* developer interface */
31 static int dev_real_reset(u32_t *base);
32 static int dev_init_io(u32_t *base);
33 static int dev_init_mii(u32_t *base);
34 static void dev_intr_control(u32_t *base, int flag);
35 static void dev_rx_tx_control(u32_t *base, int flag);
36 static void dev_get_addr(u32_t *base, u8_t *pa);
37 static int dev_check_link(u32_t *base);
38 static void dev_set_rec_mode(u32_t *base, int mode);
39 static void dev_start_tx(u32_t *base);
40 static u32_t dev_read_clear_intr_status(u32_t *base);
41 static void dev_init_rx_desc(NDR_desc *desc_start, int index, size_t buf_size,
42 			phys_bytes buf_dma, int max_desc_num, phys_bytes desc_dma_start);
43 static void dev_init_tx_desc(NDR_desc *desc_start, int index, size_t buf_size,
44 			phys_bytes buf_dma, int max_desc_num, phys_bytes desc_dma_start);
45 static void dev_set_desc_reg(u32_t *base, phys_bytes rx_addr,
46 								phys_bytes tx_addr);
47 static int dev_rx_ok_desc(u32_t *base, NDR_desc *desc, int index);
48 static int dev_rx_len_desc(u32_t *base, NDR_desc *desc, int index);
49 static void dev_set_rx_desc_done(u32_t *base, NDR_desc *desc, int index);
50 static void dev_set_tx_desc_prepare(u32_t *base, NDR_desc *desc, int index,
51 										size_t data_size);
52 static int dev_tx_ok_desc(u32_t *base, NDR_desc *desc, int index);
53 static void dev_set_tx_desc_done(u32_t *base, NDR_desc *desc, int index);
54 
55 /* ======= Developer implemented function ======= */
56 /* ====== Self-defined function ======*/
57 static u16_t read_eeprom(u32_t base, int addr) {
58 	u32_t ret, data, val;
59 	int i;
60 
61 	val = EC_READ | (addr & 0xff);
62 	ndr_out16(base, REG_EEPROM_CTRL, val);
63 	for (i = 0; i < 100; i++) {
64 		micro_delay(10000);
65 		data = ndr_in16(base, REG_EEPROM_CTRL);
66 		if (!(data & EC_BUSY)) {
67 			ret = ndr_in16(base, REG_EEPROM_DATA);
68 			break;
69 		}
70 	}
71 	if (i == 100)
72 		printf("IP1000: Fail to read EEPROM\n");
73 	return ret;
74 }
75 
76 static u16_t read_phy_reg(u32_t base, int phy_addr, int phy_reg) {
77 	int i, j, fieldlen[8];
78 	u32_t field[8];
79 	u8_t data, polar;
80 
81 	field[0] = 0xffffffff;		fieldlen[0] = 32;
82 	field[1] = 0x0001;		fieldlen[1] = 2;
83 	field[2] = 0x0002;		fieldlen[2] = 2;
84 	field[3] = phy_addr;		fieldlen[3] = 5;
85 	field[4] = phy_reg;		fieldlen[4] = 5;
86 	field[5] = 0x0000;		fieldlen[5] = 2;
87 	field[6] = 0x0000;		fieldlen[6] = 16;
88 	field[7] = 0x0000;		fieldlen[7] = 1;
89 
90 	polar = ndr_in8(base, REG_PHY_CTRL) & 0x28;
91 	for (i = 0; i < 5; i++) {
92 		for (j = 0; j < fieldlen[i]; j++) {
93 			data = (field[i] >> (fieldlen[i] - j - 1)) << 1;
94 			data = (0x02 & data) | (0x04 | polar);
95 			ndr_out8(base, REG_PHY_CTRL, data);
96 			micro_delay(10);
97 			ndr_out8(base, REG_PHY_CTRL, (data | 0x01));
98 			micro_delay(10);
99 		}
100 	}
101 	ndr_out8(base, REG_PHY_CTRL, (polar | 0x04));
102 	micro_delay(10);
103 	ndr_out8(base, REG_PHY_CTRL, (polar | 0x05));
104 	micro_delay(10);
105 	ndr_out8(base, REG_PHY_CTRL, polar);
106 	micro_delay(10);
107 	data = ndr_in8(base, REG_PHY_CTRL);
108 	ndr_out8(base, REG_PHY_CTRL, (polar | 0x01));
109 	micro_delay(10);
110 	for (i = 0; i < fieldlen[6]; i++) {
111 		ndr_out8(base, REG_PHY_CTRL, polar);
112 		micro_delay(10);
113 		data = ((ndr_in8(base, REG_PHY_CTRL) & 0x02) >> 1) & 0x01;
114 		ndr_out8(base, REG_PHY_CTRL, (polar | 0x01));
115 		micro_delay(10);
116 		field[6] |= (data << (fieldlen[6] - i - 1));
117 	}
118 
119 	for (i = 0; i < 3; i++) {
120 		ndr_out8(base, REG_PHY_CTRL, (polar | 0x04));
121 		micro_delay(10);
122 		ndr_out8(base, REG_PHY_CTRL, (polar | 0x05));
123 		micro_delay(10);
124 	}
125 	ndr_out8(base, REG_PHY_CTRL, (polar | 0x04));
126 	return field[6];
127 }
128 
129 static void write_phy_reg(u32_t base, int phy_addr, int phy_reg, u16_t val) {
130 	int i, j, fieldlen[8];
131 	u32_t field[8];
132 	u8_t data, polar;
133 
134 	field[0] = 0xffffffff;		fieldlen[0] = 32;
135 	field[1] = 0x0001;		fieldlen[1] = 2;
136 	field[2] = 0x0001;		fieldlen[2] = 2;
137 	field[3] = phy_addr;		fieldlen[3] = 5;
138 	field[4] = phy_reg;		fieldlen[4] = 5;
139 	field[5] = 0x0002;		fieldlen[5] = 2;
140 	field[6] = val;			fieldlen[6] = 16;
141 	field[7] = 0x0000;		fieldlen[7] = 1;
142 
143 	polar = ndr_in8(base, REG_PHY_CTRL) & 0x28;
144 	for (i = 0; i < 7; i++) {
145 		for (j = 0; j < fieldlen[i]; j++) {
146 			data = (field[i] >> (field[j] - j - 1)) << 1;
147 			data = (0x02 & data) | (0x04 | polar);
148 			ndr_out8(base, REG_PHY_CTRL, data);
149 			micro_delay(10);
150 			ndr_out8(base, REG_PHY_CTRL, (data | 0x01));
151 			micro_delay(10);
152 		}
153 	}
154 	for (i = 0; i < fieldlen[7]; i ++) {
155 		ndr_out8(base, REG_PHY_CTRL, polar);
156 		micro_delay(10);
157 		field[7] |= ((ndr_in8(base, REG_PHY_CTRL) & 0x02) >> 1)
158 						<< (fieldlen[7] - i -1);
159 		ndr_out8(base, REG_PHY_CTRL, (data | 0x01));
160 		micro_delay(10);
161 	}
162 }
163 
164 /* ====== Developer interface ======*/
165 /* Real hardware reset (### RESET_HARDWARE_CAN_FAIL ###)
166  * -- Return OK means success, Others means failure */
167 static int dev_real_reset(u32_t *base) {
168 	u32_t data, base0 = base[0];
169 	data = ndr_in32(base0, REG_ASIC_CTRL);
170 	ndr_out32(base0, REG_ASIC_CTRL, data | AC_RESET_ALL);
171 	micro_delay(5000);
172 	if (ndr_in32(base0, REG_ASIC_CTRL) & AC_RESET_BUSY)
173 		return -EIO;
174 	return OK;
175 }
176 
177 /* Intialize other hardware I/O registers (### INIT_HARDWARE_IO_CAN_FAIL ###)
178  * -- Return OK means success, Others means failure */
179 static int dev_init_io(u32_t *base) {
180 	u32_t mac_ctrl, physet, mode0, mode1, base0 = base[0];
181 	mode0 = read_eeprom(base0, 6);
182 	mode1 = ndr_in16(base0, REG_ASIC_CTRL);
183 	mode1 &= ~(AC_LED_MODE_B1 | AC_LED_MODE | AC_LED_SPEED);
184 	if ((mode0 & 0x03) > 1)
185 		mode1 |= AC_LED_MODE_B1;
186 	if ((mode0 & 0x01) == 1)
187 		mode1 |= AC_LED_MODE;
188 	if ((mode0 & 0x08) == 8)
189 		mode1 |= AC_LED_SPEED;
190 	ndr_out32(base0, REG_ASIC_CTRL, mode1);
191 	physet = ndr_in8(base0, REG_PHY_SET);
192 	physet = (physet & 0xf8) | ((mode0 & 0x70) >> 4);
193 	ndr_out8(base0, REG_PHY_SET, physet);
194 	mac_ctrl = ndr_in32(base0, REG_MAC_CTRL);
195 	mac_ctrl |= (MC_STAT_DISABLE | MC_TX_FC_ENA | MC_RX_FC_ENA);
196 	ndr_out32(base0, REG_MAC_CTRL, 0);
197 	ndr_out16(base0, REG_MAX_FRAME, RX_BUF_SIZE);
198 	ndr_out8(base0, REG_RX_DMA_PERIOD, 0x01);
199 	ndr_out8(base0, REG_RX_DMA_UTH, 0x30);
200 	ndr_out8(base0, REG_RX_DMA_BTH, 0x30);
201 	ndr_out8(base0, REG_TX_DMA_PERIOD, 0x26);
202 	ndr_out8(base0, REG_TX_DMA_UTH, 0x04);
203 	ndr_out8(base0, REG_TX_DMA_BTH, 0x30);
204 	ndr_out16(base0, REG_FLOW_ON_TH, 0x0740);
205 	ndr_out16(base0, REG_FLOW_OFF_TH, 0x00bf);
206 	ndr_out32(base0, REG_MAC_CTRL, mac_ctrl);
207 	return OK;
208 }
209 
210 /* Intialize MII interface (### MII_INIT_CAN_FAIL ###)
211  * -- Return OK means success, Others means failure */
212 static int dev_init_mii(u32_t *base) {
213 	int i, phyaddr;
214 	u8_t revision;
215 	u16_t phyctrl, cr1000, length, address, value;
216 	u16_t *param;
217 	u32_t status, base0 = base[0];
218 
219 	for (i = 0; i < 32; i++) {
220 		phyaddr = (i + 0x01) % 32;
221 		status = read_phy_reg(base0, phyaddr, 0x01);
222 		if ((status != 0xffff) && (status != 0))
223 			break;
224 	}
225 	if (i == 32)
226 		return -EIO;
227 	if (phyaddr != -1) {
228 		cr1000 = read_phy_reg(base0, phyaddr, 0x09);
229 		cr1000 |= 0x0700;
230 		write_phy_reg(base0, phyaddr, 0x09, cr1000);
231 		phyctrl = read_phy_reg(base0, phyaddr, 0x00);
232 	}
233 
234 	param = &PhyParam[0];
235 	length = (*param) & 0x00ff;
236 	revision = (u8_t)((*param) >> 8);
237 	param++;
238 	while (length != 0) {
239 		if (g_driver.revision == revision) {
240 			while (length > 1) {
241 				address = *param;
242 				value = *(param + 1);
243 				param += 2;
244 				write_phy_reg(base0, phyaddr, address, value);
245 				length -= 4;
246 			}
247 			break;
248 		}
249 		else {
250 			param += length / 2;
251 			length = *param & 0x00ff;
252 			revision = (u8_t)((*param) >> 8);
253 			param++;
254 		}
255 	}
256 	write_phy_reg(base0, phyaddr, 0x00, phyctrl | 0x8200);
257 	return OK;
258 }
259 
260 /* Enable or disable interrupt (### INTR_ENABLE_DISABLE ###) */
261 static void dev_intr_control(u32_t *base, int flag) {
262 	u32_t base0 = base[0];
263 	if (flag == INTR_ENABLE)
264 		ndr_out16(base0, REG_IMR, CMD_INTR_ENABLE);
265 	else if (flag == INTR_DISABLE)
266 		ndr_out16(base0, REG_IMR, 0);
267 }
268 
269 /* Enable or disable Rx/Tx (### RX_TX_ENABLE_DISABLE ###) */
270 static void dev_rx_tx_control(u32_t *base, int flag) {
271 	u32_t data, base0 = base[0];
272 	data = ndr_in32(base0, REG_MAC_CTRL);
273 	if (flag == RX_TX_ENABLE)
274 		ndr_out32(base0, REG_MAC_CTRL, data | (MC_RX_ENABLE | MC_TX_ENABLE));
275 	else if (flag == RX_TX_DISABLE) {
276 		ndr_out32(base0, REG_MAC_CTRL, 0);
277 		ndr_out32(base0, REG_ASIC_CTRL, AC_RESET_ALL);
278 	}
279 }
280 
281 /* Get MAC address to the array 'pa' (### GET_MAC_ADDR ###) */
282 static void dev_get_addr(u32_t *base, u8_t *pa) {
283 	u32_t i, sta_addr[3], base0 = base[0];
284 	for (i = 0; i < 3; i++)	 {
285 		sta_addr[i] = read_eeprom(base0, 16 + i);
286 		ndr_out16(base0, (REG_STA_ADDR0 + i * 2), sta_addr[i]);
287 	}
288 	pa[0] = (u8_t)(ndr_in16(base0, REG_STA_ADDR0) & 0x00ff);
289 	pa[1] = (u8_t)((ndr_in16(base0, REG_STA_ADDR0) & 0xff00) >> 8);
290 	pa[2] = (u8_t)(ndr_in16(base0, REG_STA_ADDR1) & 0x00ff);
291 	pa[3] = (u8_t)((ndr_in16(base0, REG_STA_ADDR1) & 0xff00) >> 8);
292 	pa[4] = (u8_t)(ndr_in16(base0, REG_STA_ADDR2) & 0x00ff);
293 	pa[5] = (u8_t)((ndr_in16(base0, REG_STA_ADDR2) & 0xff00) >> 8);
294 }
295 
296 /* Check link status (### CHECK_LINK ###)
297  * -- Return LINK_UP or LINK_DOWN */
298 static int dev_check_link(u32_t *base) {
299 	u32_t phy_ctrl, mac_ctrl, base0 = base[0];
300 	int ret;
301 	char speed[20], duplex[20];
302 
303 	phy_ctrl = ndr_in8(base0, REG_PHY_CTRL);
304 	mac_ctrl = ndr_in8(base0, REG_MAC_CTRL);
305 	switch (phy_ctrl & PC_LINK_SPEED) {
306 		case PC_LINK_SPEED10:
307 			strcpy(speed, "10Mbps");
308 			ret = LINK_UP;
309 			break;
310 		case PC_LINK_SPEED100:
311 			strcpy(speed, "100Mbps");
312 			ret = LINK_UP;
313 			break;
314 		case PC_LINK_SPEED1000:
315 			strcpy(speed, "1000Mbps");
316 			ret = LINK_UP;
317 			break;
318 		default:
319 			strcpy(speed, "unknown");
320 			ret = LINK_DOWN;
321 			break;
322 	}
323 	if (phy_ctrl & PC_DUPLEX_STS) {
324 		strcpy(duplex, "full");
325 		mac_ctrl |= (MC_DUPLEX_SEL | MC_TX_FC_ENA | MC_RX_FC_ENA);
326 	}
327 	else
328 		strcpy(duplex, "half");
329 	ndr_out32(base0, REG_MAC_CTRL, mac_ctrl);
330 #ifdef MY_DEBUG
331 	printf("NDR: Link speed is %s, %s duplex\n", speed, duplex);
332 #endif
333 	return ret;
334 }
335 
336 /* Set driver receive mode (### SET_REC_MODE ###) */
337 static void dev_set_rec_mode(u32_t *base, int mode) {
338 	u32_t data, base0 = base[0];
339 	data = ndr_in8(base0, REG_RCR);
340 	data &= ~(CMD_RCR_UNICAST | CMD_RCR_MULTICAST | CMD_RCR_BROADCAST);
341 	if (mode & NDEV_PROMISC)
342 		data |= CMD_RCR_UNICAST | CMD_RCR_MULTICAST | CMD_RCR_MULTICAST;
343 	if (mode & NDEV_BROAD)
344 		data |= CMD_RCR_BROADCAST;
345 	if (mode & NDEV_MULTI)
346 		data |= CMD_RCR_MULTICAST;
347 	data |= CMD_RCR_UNICAST;
348 	ndr_out8(base0, REG_RCR, data);
349 }
350 
351 /* Start Tx channel (### START_TX_CHANNEL ###) */
352 static void dev_start_tx(u32_t *base) {
353 	u32_t base0 = base[0];
354 	ndr_out32(base0, REG_DMA_CTRL, CMD_TX_START);
355 }
356 
357 /* Read and clear interrupt (### READ_CLEAR_INTR_STS ###) */
358 static u32_t dev_read_clear_intr_status(u32_t *base) {
359 	u32_t data, base0 = base[0];
360 	data = ndr_in16(base0, REG_ISR);
361 	ndr_out16(base0, REG_ISR, 0);
362 	return data;
363 }
364 
365 /* ---------- WITH DESCRIPTOR ---------- */
366 /* Intialize Rx descriptor (### INIT_RX_DESC ###) */
367 static void dev_init_rx_desc(NDR_desc *desc_start, int index, size_t buf_size,
368 			phys_bytes buf_dma, int max_desc_num, phys_bytes desc_dma_start) {
369 	NDR_desc *desc = desc_start + index;
370 	desc->status = 0;
371 	desc->frag_info = (u64_t)(buf_dma);
372 	desc->frag_info |= ((u64_t)buf_size << 48) & RFI_FRAG_LEN;
373 	if (index == max_desc_num - 1)
374 		desc->next = desc_dma_start;
375 	else
376 		desc->next = desc_dma_start + (index + 1) * sizeof(NDR_desc);
377 }
378 
379 /* Intialize Tx descriptor (### INIT_TX_DESC ###) */
380 static void dev_init_tx_desc(NDR_desc *desc_start, int index, size_t buf_size,
381 			phys_bytes buf_dma, int max_desc_num, phys_bytes desc_dma_start) {
382 	NDR_desc *desc = desc_start + index;
383 	desc->status = TFS_TFD_DONE;
384 	desc->frag_info = (u64_t)(buf_dma);
385 	if (index == max_desc_num - 1)
386 		desc->next = desc_dma_start;
387 	else
388 		desc->next = desc_dma_start + (index + 1) * sizeof(NDR_desc);
389 }
390 
391 /* Set Rx/Tx descriptor address into device register (### SET_DESC_REG ###) */
392 static void dev_set_desc_reg(u32_t *base, phys_bytes rx_addr,
393 								phys_bytes tx_addr) {
394 	u32_t base0 = base[0];
395 	ndr_out32(base0, REG_RX_DESC_BASEL, rx_addr);
396 	ndr_out32(base0, REG_RX_DESC_BASEU, 0);
397 	ndr_out32(base0, REG_TX_DESC_BASEL, tx_addr);
398 	ndr_out32(base0, REG_TX_DESC_BASEU, 0);
399 }
400 
401 /* Check whether Rx is OK from Rx descriptor (### CHECK_RX_OK_FROM_DESC ###)
402  * -- Current buffer number is index
403  * -- Return RX_OK or RX_SUSPEND or RX_ERROR */
404 static int dev_rx_ok_desc(u32_t *base, NDR_desc *desc, int index) {
405 	if (desc->status & RFS_RFD_DONE) {
406 		if (desc->status & RFS_ERROR)
407 			return RX_ERROR;
408 		if ((desc->status & RFS_NORMAL) == RFS_NORMAL)
409 			return RX_OK;
410 	}
411 	return RX_SUSPEND;
412 }
413 
414 /* Get length from Rx descriptor (### GET_RX_LENGTH_FROM_DESC ###)
415  * -- Current buffer number is index
416  * -- Return the length */
417 static int dev_rx_len_desc(u32_t *base, NDR_desc *desc, int index) {
418 	int totlen;
419 	totlen = (int)(desc->status & RFS_FRAME_LEN);
420 	return totlen;
421 }
422 
423 /* Set Rx descriptor after Rx done (### SET_RX_DESC_DONE ###)
424  * -- Current buffer number is index */
425 static void dev_set_rx_desc_done(u32_t *base, NDR_desc *desc, int index) {
426 	desc->status = 0;
427 }
428 
429 /* Set Tx descriptor to prepare transmitting (### SET_TX_DESC_PREPARE)
430  * -- Current buffer number is index */
431 static void dev_set_tx_desc_prepare(u32_t *base, NDR_desc *desc, int index,
432 									size_t data_size) {
433 	desc->status = TFS_TFD_DONE;
434 	desc->status |= (u64_t)(TFS_WORD_ALIGN | (TFS_FRAMEID & index)
435 					| (TFS_FRAG_COUNT & (1 << 24))) | TFS_TX_DMA_INDICATE;
436 	desc->frag_info |= TFI_FRAG_LEN & ((u64_t)((data_size > 60 ? data_size : 60)
437 							& 0xffff) << 48);
438 	desc->status &= (u64_t)(~(TFS_TFD_DONE));
439 }
440 
441 /* Check whether Tx is OK from Tx descriptor (### CHECK_TX_OK_FROM_DESC ###)
442  * -- Current buffer number is index
443  * -- Return TX_OK or TX_SUSPEND or TX_ERROR */
444 static int dev_tx_ok_desc(u32_t *base, NDR_desc *desc, int index) {
445 	if (desc->status & TFS_TFD_DONE)
446 		return TX_OK;
447 	return TX_SUSPEND;
448 }
449 
450 /* Set Tx descriptor after Tx done (### SET_TX_DESC_DONE ###)
451  * -- Current buffer number is index */
452 static void dev_set_tx_desc_done(u32_t *base, NDR_desc *desc, int index) {
453 	desc->status = 0;
454 }
455 
456 /* Driver interface table */
457 static const struct netdriver NDR_table = {
458 	.ndr_init = NDR_init,
459 	.ndr_stop = NDR_stop,
460 	.ndr_mode = NDR_mode,
461 	.ndr_recv = NDR_recv,
462 	.ndr_send = NDR_send,
463 	.ndr_intr = NDR_intr,
464 	.ndr_stat = NDR_stat
465 };
466 
467 int main(int argc, char *argv[]) {
468 	env_setargs(argc, argv);
469 	netdriver_task(&NDR_table);
470 }
471 
472 /* Initialize the driver */
473 static int NDR_init(unsigned int instance, ether_addr_t *addr) {
474 	int i, ret = 0;
475 
476 	/* Intialize driver data structure */
477 	memset(&g_driver, 0, sizeof(g_driver));
478 	g_driver.link = LINK_UNKNOWN;
479 	strcpy(g_driver.name, DRIVER_NAME);
480 	strcat(g_driver.name, "#0");
481 	g_driver.name[strlen(g_driver.name) - 1] += instance;
482 	g_instance = instance;
483 
484 	/* Probe the device */
485 	if (dev_probe(&g_driver, instance)) {
486 		printf("NDR: Device is not found\n");
487 		ret = -ENODEV;
488 		goto err_probe;
489 	}
490 
491 	/* Intialize hardware */
492 	if (dev_init_hw(&g_driver, addr)) {
493 		printf("NDR: Fail to initialize hardware\n");
494 		ret = -EIO;
495 		goto err_init_hw;
496 	}
497 
498 	/* Allocate and initialize buffer */
499 	if (dev_init_buf(&g_driver)) {
500 		printf("NDR: Fail to initialize buffer\n");
501 		ret = -ENODEV;
502 		goto err_init_buf;
503 	}
504 
505 	/* Enable interrupts */
506 	/* ### INTR_ENABLE_DISABLE ### */
507 	dev_intr_control(g_driver.base, INTR_ENABLE);
508 
509 	/* Start Rx and Tx */
510 	/* ### RX_TX_ENABLE_DISABLE ### */
511 	dev_rx_tx_control(g_driver.base, RX_TX_ENABLE);
512 
513 	/* Use a synchronous alarm instead of a watchdog timer */
514 	sys_setalarm(sys_hz(), 0);
515 
516 	/* Clear send and recv flag */
517 	g_driver.send_flag = FALSE;
518 	g_driver.recv_flag = FALSE;
519 
520 	return 0;
521 
522 err_init_buf:
523 err_init_hw:
524 err_probe:
525 	return ret;
526 }
527 
528 /* Stop the driver */
529 static void NDR_stop(void) {
530 	/* Free Rx and Tx buffer*/
531 	free_contig(g_driver.buf, g_driver.buf_size);
532 
533 	/* Stop interrupt */
534 	/* ### INTR_ENABLE_DISABLE ### */
535 	dev_intr_control(g_driver.base, INTR_DISABLE);
536 
537 	/* Stop Rx and Tx */
538 	/* ### RX_TX_ENABLE_DISABLE ### */
539 	dev_rx_tx_control(g_driver.base, RX_TX_DISABLE);
540 }
541 
542 /* Set driver mode */
543 static void NDR_mode(unsigned int mode) {
544 	g_driver.mode = mode;
545 	/* Set driver receive mode */
546 	/* ### SET_REC_MODE ### */
547 	dev_set_rec_mode(g_driver.base, mode);
548 }
549 
550 /* Receive data */
551 static ssize_t NDR_recv(struct netdriver_data *data, size_t max) {
552 	NDR_driver *pdev = &g_driver;
553 	u32_t totlen, packlen;
554 	int index, ret, offset = 0;
555 	NDR_desc *desc;
556 
557 	index = pdev->rx_head;
558 	desc = pdev->rx_desc;
559 	desc += index;
560 	/* Check whether Rx is OK from Rx descriptor */
561 	/* ### CHECK_RX_OK_FROM_DESC ### */
562 	ret = dev_rx_ok_desc(pdev->base, desc, index);
563 	if (ret == RX_SUSPEND)
564 		return SUSPEND;
565 	else if (ret == RX_ERROR)
566 		printf("NDR: Rx error now\n");
567 	/* Get length from Rx descriptor */
568 	/* ### GET_RX_LENGTH_FROM_DESC ### */
569 	totlen = dev_rx_len_desc(pdev->base, desc, index);
570 
571 	/* Get data length */
572 	/* ### Get , int inde, int indexxRx data length ### */
573 	if (totlen < 8 || totlen > 2 * ETH_MAX_PACK_SIZE) {
574 		printf("NDR: Bad data length: %d\n", totlen);
575 		panic(NULL);
576 	}
577 
578 	packlen = totlen;
579 	if (packlen > max)
580 		packlen = max;
581 
582 	/* Copy data to user */
583 	netdriver_copyout(data, 0, pdev->rx[index].buf + offset, packlen);
584 	pdev->stat.ets_packetR++;
585 
586 	/* Set Rx descriptor after Rx done */
587 	/* ### SET_RX_DESC_DONE ### */
588 	dev_set_rx_desc_done(pdev->base, desc, index);
589 	if (index == RX_BUFFER_NUM - 1)
590 		index = 0;
591 	else
592 		index++;
593 	pdev->rx_head = index;
594 
595 #ifdef MY_DEBUG
596 	printf("NDR: Successfully receive a packet, length = %d\n", packlen);
597 #endif
598 
599 	return packlen;
600 }
601 
602 /* Transmit data */
603 static int NDR_send(struct netdriver_data *data, size_t size) {
604 	NDR_driver *pdev = &g_driver;
605 	int tx_head, i;
606 	NDR_desc *desc;
607 
608 	tx_head = pdev->tx_head;
609 	if (pdev->tx[tx_head].busy)
610 		return SUSPEND;
611 
612 	/* Copy data from user */
613 	netdriver_copyin(data, 0, pdev->tx[tx_head].buf, size);
614 
615 	/* Set busy */
616 	pdev->tx[tx_head].busy = TRUE;
617 	pdev->tx_busy_num++;
618 
619 	desc = pdev->tx_desc;
620 	desc += tx_head;
621 	/* Set Tx descriptor to prepare transmitting */
622 	/* ### SET_TX_DESC_PREPARE ### */
623 	dev_set_tx_desc_prepare(pdev->base, desc, tx_head, size);
624 	if (tx_head == TX_BUFFER_NUM - 1)
625 		tx_head = 0;
626 	else
627 		tx_head++;
628 	pdev->tx_head = tx_head;
629 
630 	/* Start Tx channel */
631 	/* ### START_TX ### */
632 	dev_start_tx(pdev->base);
633 
634 	return 0;
635 }
636 
637 /* Handle interrupt */
638 static void NDR_intr(unsigned int mask) {
639 	int s;
640 
641 	/* Run interrupt handler at driver level */
642 	dev_handler(&g_driver);
643 
644 	/* Reenable interrupts for this hook */
645 	if ((s = sys_irqenable(&g_driver.hook)) != OK)
646 		printf("NDR: Cannot enable OS interrupts: %d\n", s);
647 
648 	/* Perform tasks based on the flagged conditions */
649 	dev_check_ints(&g_driver);
650 }
651 
652 /* Get driver status */
653 static void NDR_stat(eth_stat_t *stat) {
654 	memcpy(stat, &g_driver.stat, sizeof(*stat));
655 }
656 
657 /* Match the device and get base address */
658 static int dev_probe(NDR_driver *pdev, int instance) {
659 	int devind, ioflag, i;
660 	u16_t cr, vid, did;
661 	u32_t bar, size, base;
662 	u8_t irq, rev;
663 	u8_t *reg;
664 
665 	/* Find pci device */
666 	pci_init();
667 	if (!pci_first_dev(&devind, &vid, &did))
668 		return -EIO;
669 	while (instance--) {
670 		if (!pci_next_dev(&devind, &vid, &did))
671 			return -EIO;
672 	}
673 	pci_reserve(devind);
674 
675 	/* Enable bus mastering and I/O space */
676 	cr = pci_attr_r16(devind, PCI_CR);
677 	pci_attr_w16(devind, PCI_CR, cr | 0x105);
678 
679 	/* Get base address */
680 	for (i = 0; i < 6; i++)
681 		pdev->base[i] = 0;
682 #ifdef DMA_BASE_IOMAP
683 	for (i = 0; i < 6; i++) {
684 		if (pci_get_bar(devind, PCI_BAR + i * 4, &base, &size, &ioflag)) {
685 			/* printf("NDR: Fail to get PCI BAR\n"); */
686 			continue;
687 		}
688 		if (ioflag) {
689 			/* printf("NDR: PCI BAR is not for memory\n"); */
690 			continue;
691 		}
692 		if ((reg = vm_map_phys(SELF, (void *)base, size)) == MAP_FAILED) {
693 			printf("NDR: Fail to map hardware registers from PCI\n");
694 			return -EIO;
695 		}
696 		pdev->base[i] = (u32_t)reg;
697 	}
698 #else
699 	for (i = 0; i < 6; i++)
700 		pdev->base[i] = pci_attr_r32(devind, PCI_BAR + i * 4) & 0xffffffe0;
701 #endif
702 	pdev->dev_name = pci_dev_name(vid, did);
703 	pdev->irq = pci_attr_r8(devind, PCI_ILR);
704 	pdev->revision = pci_attr_r8(devind, PCI_REV);
705 	pdev->did = did;
706 	pdev->vid = vid;
707 	pdev->devind = devind;
708 
709 #ifdef MY_DEBUG
710 	printf("NDR: Hardware name is %s\n", pdev->dev_name);
711 	for (i = 0; i < 6; i++)
712 		printf("NDR: PCI BAR%d is 0x%08x\n", i, pdev->base[i]);
713 	printf("NDR: IRQ number is 0x%02x\n", pdev->irq);
714 #endif
715 
716 	return 0;
717 }
718 
719 /* Intialize hardware */
720 static int dev_init_hw(NDR_driver *pdev, ether_addr_t *addr) {
721 	int r, ret;
722 
723 	/* Set the OS interrupt handler */
724 	pdev->hook = pdev->irq;
725 	if ((r = sys_irqsetpolicy(pdev->irq, 0, &pdev->hook)) != OK) {
726 		printf("NDR: Fail to set OS IRQ policy: %d\n", r);
727 		ret = -EFAULT;
728 		goto err_irq_policy;
729 	}
730 
731 	/* Reset hardware */
732 	if (dev_reset_hw(pdev)) {
733 		printf("NDR: Fail to reset the device\n");
734 		ret = -EIO;
735 		goto err_reset_hw;
736 	}
737 
738 	/* Enable OS IRQ */
739 	if ((r = sys_irqenable(&pdev->hook)) != OK) {
740 		printf("NDR: Fail to enable OS IRQ: %d\n", r);
741 		ret = -EFAULT;
742 		goto err_irq_enable;
743 	}
744 
745 	/* Configure MAC address */
746 	dev_conf_addr(pdev, addr);
747 
748 	/* Detect link status */
749 	/* ### CHECK_LINK ### */
750 	pdev->link = dev_check_link(pdev->base);
751 #ifdef MY_DEBUG
752 	if (pdev->link)
753 		printf("NDR: Link up\n");
754 	else
755 		printf("NDR: Link down\n");
756 #endif
757 
758 	return 0;
759 
760 err_reset_hw:
761 err_irq_enable:
762 err_irq_policy:
763 	return ret;
764 }
765 
766 /* Reset hardware */
767 static int dev_reset_hw(NDR_driver *pdev) {
768 	int ret;
769 
770 	/* Reset the chip */
771 	/* ### RESET_HARDWARE_CAN_FAIL ### */
772 	if (dev_real_reset(pdev->base)) {
773 		printf("NDR: Fail to reset the hardware\n");
774 		ret = -EIO;
775 		goto err_real_reset;
776 	}
777 
778 	/* Initialize other hardware I/O registers */
779 	/* ### SET_RX_DESC_REG ### */
780 	if (dev_init_io(pdev->base)) {
781 		printf("NDR: Fail to initialize I/O registers\n");
782 		ret = -EIO;
783 		goto err_init_io;
784 	}
785 
786 	/* Initialize MII interface */
787 	/* ### MII_INIT_CAN_FAIL ### */
788 	if (dev_init_mii(pdev->base)) {
789 		printf("NDR: Fail to initialize MII interface\n");
790 		ret = -EIO;
791 		goto err_init_mii;
792 	}
793 
794 	return 0;
795 
796 err_init_mii:
797 err_init_io:
798 err_real_reset:
799 	return ret;
800 }
801 
802 /* Configure MAC address */
803 static void dev_conf_addr(NDR_driver *pdev, ether_addr_t *addr) {
804 	u8_t pa[6];
805 
806 	/* Get MAC address */
807 	/* ### GET_MAC_ADDR ### */
808 	dev_get_addr(pdev->base, pa);
809 	addr->ea_addr[0] = pa[0];
810 	addr->ea_addr[1] = pa[1];
811 	addr->ea_addr[2] = pa[2];
812 	addr->ea_addr[3] = pa[3];
813 	addr->ea_addr[4] = pa[4];
814 	addr->ea_addr[5] = pa[5];
815 #ifdef MY_DEBUG
816 	printf("NDR: Ethernet address is %02x:%02x:%02x:%02x:%02x:%02x\n",
817 			addr->ea_addr[0], addr->ea_addr[1], addr->ea_addr[2],
818 			addr->ea_addr[3], addr->ea_addr[4], addr->ea_addr[5]);
819 #endif
820 }
821 
822 /* Allocate and initialize buffer */
823 static int dev_init_buf(NDR_driver *pdev) {
824 	size_t rx_desc_size, tx_desc_size, rx_buf_size, tx_buf_size, tot_buf_size;
825 	phys_bytes buf_dma;
826 	char *buf;
827 	int i;
828 
829 	/* Build Rx and Tx buffer */
830 	tx_buf_size = TX_BUF_SIZE;
831 	if (tx_buf_size % 4)
832 		tx_buf_size += 4 - (tx_buf_size % 4);
833 	rx_buf_size = RX_BUF_SIZE;
834 	if (rx_buf_size % 4)
835 		rx_buf_size += 4 - (rx_buf_size % 4);
836 	tot_buf_size = TX_BUFFER_NUM * tx_buf_size + RX_BUFFER_NUM * rx_buf_size;
837 	rx_desc_size = RX_BUFFER_NUM * sizeof(NDR_desc);
838 	tx_desc_size = TX_BUFFER_NUM * sizeof(NDR_desc);
839 	tot_buf_size += rx_desc_size + tx_desc_size;
840 	if (tot_buf_size % 4096)
841 		tot_buf_size += 4096 - (tot_buf_size % 4096);
842 
843 	if (!(buf = alloc_contig(tot_buf_size, 0, &buf_dma))) {
844 		printf("NDR: Fail to allocate memory\n");
845 		return -ENOMEM;
846 	}
847 	pdev->buf_size = tot_buf_size;
848 	pdev->buf = buf;
849 
850 	/* Rx descriptor buffer location */
851 	pdev->rx_desc = (NDR_desc *)buf;
852 	pdev->rx_desc_dma = buf_dma;
853 	memset(buf, 0, rx_desc_size);
854 	buf += rx_desc_size;
855 	buf_dma += rx_desc_size;
856 
857 	/* Tx descriptor buffer location */
858 	pdev->tx_desc = (NDR_desc *)buf;
859 	pdev->tx_desc_dma = buf_dma;
860 	memset(buf, 0, tx_desc_size);
861 	buf += tx_desc_size;
862 	buf_dma += tx_desc_size;
863 
864 	/* Rx buffer assignment */
865 	for (i = 0; i < RX_BUFFER_NUM; i++) {
866 		/* Initialize Rx buffer */
867 		pdev->rx[i].buf_dma = buf_dma;
868 		pdev->rx[i].buf = buf;
869 		buf_dma += rx_buf_size;
870 		buf += rx_buf_size;
871 		/* Set Rx descriptor */
872 		/* ### INIT_RX_DESC ### */
873 		dev_init_rx_desc(pdev->rx_desc, i, rx_buf_size, pdev->rx[i].buf_dma,
874 							RX_BUFFER_NUM, pdev->rx_desc_dma);
875 	}
876 
877 	/* Tx buffer assignment */
878 	for (i = 0; i < TX_BUFFER_NUM; i++) {
879 		/* Set Tx buffer */
880 		pdev->tx[i].busy = 0;
881 		pdev->tx[i].buf_dma = buf_dma;
882 		pdev->tx[i].buf = buf;
883 		buf_dma += tx_buf_size;
884 		buf += tx_buf_size;
885 		/* Initialize Tx descriptor */
886 		/* ### INIT_TX_DESC ### */
887 		dev_init_tx_desc(pdev->tx_desc, i, tx_buf_size, pdev->tx[i].buf_dma,
888 							TX_BUFFER_NUM, pdev->tx_desc_dma);
889 	}
890 
891 	/* Set Rx/Tx descriptor address into device register */
892 	/* ### SET_DESC_REG ### */
893 	dev_set_desc_reg(pdev->base, g_driver.rx_desc_dma,
894 						g_driver.tx_desc_dma);
895 
896 	pdev->tx_busy_num = 0;
897 	pdev->tx_head = 0;
898 	pdev->tx_tail = 0;
899 	pdev->rx_head = 0;
900 
901 	return 0;
902 }
903 
904 /* Real handler interrupt */
905 static void dev_handler(NDR_driver *pdev) {
906 	u32_t intr_status;
907 	int tx_head, tx_tail, index, flag = 0, ret;
908 	NDR_desc *desc;
909 
910 	/* Read and clear interrupt status */
911 	/* ### READ_CLEAR_INTR_STS ### */
912 	intr_status = dev_read_clear_intr_status(pdev->base);
913 
914 	/* Enable interrupt */
915 	/* ### INTR_ENABLE_DISABLE ### */
916 	dev_intr_control(pdev->base, INTR_ENABLE);
917 
918 	/* Check link status */
919 	if (intr_status & INTR_STS_LINK) {
920 		pdev->link = dev_check_link(pdev->base);
921 #ifdef MY_DEBUG
922 		printf("NDR: Link state change\n");
923 #endif
924 		flag++;
925 	}
926 	/* Check Rx request status */
927 	if (intr_status & INTR_STS_RX) {
928 		pdev->recv_flag = TRUE;
929 		flag++;
930 	}
931 	/* Check Tx request status */
932 	if (intr_status & INTR_STS_TX) {
933 		pdev->send_flag = TRUE;
934 		flag++;
935 
936 		/* Manage Tx Buffer */
937 		tx_head = pdev->tx_head;
938 		tx_tail = pdev->tx_tail;
939 		while (tx_tail != tx_head) {
940 			if (!pdev->tx[tx_tail].busy)
941 				printf("NDR: Strange, buffer not busy?\n");
942 			index = tx_tail;
943 			desc = pdev->tx_desc;
944 			desc += tx_tail;
945 			/* Check whether Tx is OK from Tx descriptor */
946 			/* ### CHECK_TX_OK_FROM_DESC ### */
947 			ret = dev_tx_ok_desc(pdev->base, desc, index);
948 			if (ret == TX_SUSPEND)
949 				break;
950 			else if (ret == TX_ERROR)
951 				printf("NDR: Tx error now\n");
952 
953 			pdev->stat.ets_packetT++;
954 			pdev->tx[tx_tail].busy = FALSE;
955 			pdev->tx_busy_num--;
956 
957 			if (++tx_tail >= TX_BUFFER_NUM)
958 				tx_tail = 0;
959 
960 			pdev->send_flag = TRUE;
961 			pdev->recv_flag = TRUE;
962 
963 			/* Set Tx descriptor after Tx done */
964 			/* ### SET_TX_DESC_DONE ### */
965 			dev_set_tx_desc_done(pdev->base, desc, index);
966 #ifdef MY_DEBUG
967 			printf("NDR: Successfully send a packet\n");
968 #endif
969 		}
970 		pdev->tx_tail = tx_tail;
971 	}
972 #ifdef MY_DEBUG
973 	if (!flag) {
974 		printf("NDR: Unknown error in interrupt 0x%08x\n", intr_status);
975 		return;
976 	}
977 #endif
978 }
979 
980 /* Check interrupt and perform */
981 static void dev_check_ints(NDR_driver *pdev) {
982 	if (!pdev->recv_flag)
983 		return;
984 	pdev->recv_flag = FALSE;
985 
986 	/* Handle data receive */
987 	netdriver_recv();
988 
989 	/* Handle data transmit */
990 	if (pdev->send_flag) {
991 		pdev->send_flag = FALSE;
992 		netdriver_send();
993 	}
994 }
995