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