|
|
1.1.1.2 root 1: /* Previous - ethernet.c
1.1 root 2:
3: This file is distributed under the GNU Public License, version 2 or at
4: your option any later version. Read the file gpl.txt for details.
5:
1.1.1.3 root 6: Network adapter for non-turbo and turbo NeXT machines.
1.1 root 7:
8: */
9:
10: #include "ioMem.h"
11: #include "ioMemTables.h"
12: #include "m68000.h"
13: #include "configuration.h"
14: #include "sysReg.h"
15: #include "dma.h"
1.1.1.3 root 16: #include "bmap.h"
1.1 root 17: #include "ethernet.h"
1.1.1.2 root 18: #include "enet_slirp.h"
1.1.1.4 ! root 19: #include "enet_pcap.h"
1.1.1.2 root 20: #include "cycInt.h"
21: #include "statusbar.h"
1.1 root 22:
23:
1.1.1.2 root 24: #define LOG_EN_LEVEL LOG_DEBUG
25: #define LOG_EN_REG_LEVEL LOG_DEBUG
26: #define LOG_EN_DATA 0
1.1 root 27:
1.1.1.2 root 28: #define IO_SEG_MASK 0x1FFFF
1.1 root 29:
30:
1.1.1.2 root 31: struct {
1.1 root 32: Uint8 tx_status;
33: Uint8 tx_mask;
34: Uint8 tx_mode;
35: Uint8 rx_status;
36: Uint8 rx_mask;
37: Uint8 rx_mode;
1.1.1.2 root 38: Uint8 reset;
39:
40: Uint8 mac_addr[6];
41: } enet;
1.1 root 42:
1.1.1.2 root 43: bool enet_stopped;
1.1 root 44:
1.1.1.2 root 45: #define TXSTAT_READY 0x80 /* r */
46: #define TXSTAT_NET_BUSY 0x40 /* r */
47: #define TXSTAT_TX_RECVD 0x20 /* r */
48: #define TXSTAT_SHORTED 0x10 /* r */
49: #define TXSTAT_UNDERFLOW 0x08 /* rw */
50: #define TXSTAT_COLL 0x04 /* rw */
51: #define TXSTAT_16COLLS 0x02 /* rw */
52: #define TXSTAT_PAR_ERR 0x01 /* rw */
53:
54: #define TXMASK_PKT_RDY 0x80
55: #define TXMASK_TX_RECVD 0x20
56: #define TXMASK_UNDERFLOW 0x08
57: #define TXMASK_COLL 0x04
58: #define TXMASK_16COLLS 0x02
59: #define TXMASK_PAR_ERR 0x01
60:
61: #define RXSTAT_PKT_OK 0x80 /* rw */
62: #define RXSTAT_RESET_PKT 0x10 /* r */
63: #define RXSTAT_SHORT_PKT 0x08 /* rw */
64: #define RXSTAT_ALIGN_ERR 0x04 /* rw */
65: #define RXSTAT_CRC_ERR 0x02 /* rw */
66: #define RXSTAT_OVERFLOW 0x01 /* rw */
67:
68: #define RXMASK_PKT_OK 0x80
69: #define RXMASK_RESET_PKT 0x10
70: #define RXMASK_SHORT_PKT 0x80
71: #define RXMASK_ALIGN_ERR 0x40
72: #define RXMASK_CRC_ERR 0x20
73: #define RXMASK_OVERFLOW 0x10
74:
75: #define TXMODE_COLL_ATMPT 0xF0 /* r */
76: #define TXMODE_IGNORE_PAR 0x08 /* rw */
77: #define TXMODE_TM 0x04 /* rw */
78: #define TXMODE_DIS_LOOP 0x02 /* rw */
79: #define TXMODE_DIS_CONTNT 0x01 /* rw */
80:
81: #define RXMODE_TEST_CRC 0x80
82: #define RXMODE_ADDR_SIZE 0x10
83: #define RXMODE_ENA_SHORT 0x08
84: #define RXMODE_ENA_RST 0x04
85: #define RXMODE_MATCH_MODE 0x03
86:
87: #define EN_RESET 0x80 /* w */
88:
89:
90: void enet_reset(void);
91:
1.1.1.4 ! root 92: void (*enet_output)(void);
! 93: void (*enet_input)(Uint8 *pkt, int pkt_len);
! 94: void (*enet_start)(Uint8 *mac);
! 95: void (*enet_stop)(void);
! 96:
1.1.1.2 root 97: void EN_TX_Status_Read(void) { // 0x02006000
98: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = enet.tx_status;
99: Log_Printf(LOG_EN_REG_LEVEL,"[EN] Transmitter status read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
100: }
101:
102: void EN_TX_Status_Write(void) {
103: Uint8 val=IoMem[IoAccessCurrentAddress & IO_SEG_MASK];
104: Log_Printf(LOG_EN_REG_LEVEL,"[EN] Transmitter status write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
105: if (ConfigureParams.System.bTurbo) {
106: enet.tx_status&=~val;
107: } else {
108: enet.tx_status&=~(val&0x0F);
1.1 root 109: }
1.1.1.2 root 110:
1.1.1.3 root 111: if ((enet.tx_status&enet.tx_mask&0x0F)==0) {
1.1.1.2 root 112: set_interrupt(INT_EN_TX, RELEASE_INT);
113: }
1.1 root 114: }
115:
1.1.1.2 root 116: void EN_TX_Mask_Read(void) { // 0x02006001
117: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = enet.tx_mask&0xAF;
118: Log_Printf(LOG_EN_REG_LEVEL,"[EN] Transmitter masks read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
119: }
120:
121: void EN_TX_Mask_Write(void) {
122: enet.tx_mask=IoMem[IoAccessCurrentAddress & IO_SEG_MASK];
123: Log_Printf(LOG_EN_REG_LEVEL,"[EN] Transmitter masks write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
1.1 root 124:
1.1.1.3 root 125: if ((enet.tx_status&enet.tx_mask&0x0F)==0) {
1.1.1.2 root 126: set_interrupt(INT_EN_TX, RELEASE_INT);
1.1 root 127: }
128: }
129:
1.1.1.2 root 130: void EN_RX_Status_Read(void) { // 0x02006002
131: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = enet.rx_status;
132: Log_Printf(LOG_EN_REG_LEVEL,"[EN] Receiver status read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
133: }
1.1 root 134:
1.1.1.2 root 135: void EN_RX_Status_Write(void) {
136: Uint8 val=IoMem[IoAccessCurrentAddress & IO_SEG_MASK];
137: Log_Printf(LOG_EN_REG_LEVEL,"[EN] Receiver status write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
138: enet.rx_status&=~(val&0x8F);
1.1 root 139:
1.1.1.2 root 140: if ((enet.rx_status&enet.rx_mask&0x8F)==0) {
141: set_interrupt(INT_EN_RX, RELEASE_INT);
142: }
1.1 root 143: }
144:
1.1.1.2 root 145: void EN_RX_Mask_Read(void) { // 0x02006003
146: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = enet.rx_mask&0x9F;
147: Log_Printf(LOG_EN_REG_LEVEL,"[EN] Receiver masks read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
148: }
149:
150: void EN_RX_Mask_Write(void) {
151: enet.rx_mask=IoMem[IoAccessCurrentAddress & IO_SEG_MASK];
152: Log_Printf(LOG_EN_REG_LEVEL,"[EN] Receiver masks write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
1.1 root 153:
1.1.1.2 root 154: if ((enet.rx_status&enet.rx_mask&0x8F)==0) {
155: set_interrupt(INT_EN_RX, RELEASE_INT);
1.1 root 156: }
157: }
158:
1.1.1.2 root 159: void EN_TX_Mode_Read(void) { // 0x02006004
160: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = enet.tx_mode;
161: Log_Printf(LOG_EN_REG_LEVEL,"[EN] Transmitter mode read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
162: }
163:
164: void EN_TX_Mode_Write(void) {
165: enet.tx_mode=IoMem[IoAccessCurrentAddress & IO_SEG_MASK];
166: Log_Printf(LOG_EN_REG_LEVEL,"[EN] Transmitter mode write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
167: }
168:
169: void EN_RX_Mode_Read(void) { // 0x02006005
170: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = enet.rx_mode;
171: Log_Printf(LOG_EN_REG_LEVEL,"[EN] Receiver mode read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
172: }
173:
174: void EN_RX_Mode_Write(void) {
175: enet.rx_mode=IoMem[IoAccessCurrentAddress & IO_SEG_MASK];
176: Log_Printf(LOG_EN_REG_LEVEL,"[EN] Receiver mode write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
177: }
178:
179: void EN_Reset_Write(void) { // 0x02006006
180: enet.reset=IoMem[IoAccessCurrentAddress & IO_SEG_MASK];
181: Log_Printf(LOG_EN_REG_LEVEL,"[EN] Reset write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
182: enet_reset();
183: }
184:
185: void EN_NodeID0_Read(void) { // 0x02006008
186: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = enet.mac_addr[0];
187: Log_Printf(LOG_EN_REG_LEVEL,"[EN] MAC byte 0 read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
188: }
189:
190: void EN_NodeID0_Write(void) {
191: enet.mac_addr[0]=IoMem[IoAccessCurrentAddress & IO_SEG_MASK];
192: Log_Printf(LOG_EN_REG_LEVEL,"[EN] MAC byte 0 write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
193: }
194:
195: void EN_NodeID1_Read(void) { // 0x02006009
196: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = enet.mac_addr[1];
197: Log_Printf(LOG_EN_REG_LEVEL,"[EN] MAC byte 1 read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
198: }
199:
200: void EN_NodeID1_Write(void) {
201: enet.mac_addr[1]=IoMem[IoAccessCurrentAddress & IO_SEG_MASK];
202: Log_Printf(LOG_EN_REG_LEVEL,"[EN] MAC byte 1 write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
203: }
204:
205: void EN_NodeID2_Read(void) { // 0x0200600a
206: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = enet.mac_addr[2];
207: Log_Printf(LOG_EN_REG_LEVEL,"[EN] MAC byte 2 read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
208: }
209:
210: void EN_NodeID2_Write(void) {
211: enet.mac_addr[2]=IoMem[IoAccessCurrentAddress & IO_SEG_MASK];
212: Log_Printf(LOG_EN_REG_LEVEL,"[EN] MAC byte 2 write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
213: }
214:
215: void EN_NodeID3_Read(void) { // 0x0200600b
216: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = enet.mac_addr[3];
217: Log_Printf(LOG_EN_REG_LEVEL,"[EN] MAC byte 3 read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
218: }
219:
220: void EN_NodeID3_Write(void) {
221: enet.mac_addr[3]=IoMem[IoAccessCurrentAddress & IO_SEG_MASK];
222: Log_Printf(LOG_EN_REG_LEVEL,"[EN] MAC byte 3 write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
223: }
224:
225: void EN_NodeID4_Read(void) { // 0x0200600c
226: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = enet.mac_addr[4];
227: Log_Printf(LOG_EN_REG_LEVEL,"[EN] MAC byte 4 read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
1.1 root 228: }
229:
1.1.1.2 root 230: void EN_NodeID4_Write(void) {
231: enet.mac_addr[4]=IoMem[IoAccessCurrentAddress & IO_SEG_MASK];
232: Log_Printf(LOG_EN_REG_LEVEL,"[EN] MAC byte 4 write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
233: }
234:
235: void EN_NodeID5_Read(void) { // 0x0200600d
236: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = enet.mac_addr[5];
237: Log_Printf(LOG_EN_REG_LEVEL,"[EN] MAC byte 5 read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
238: }
1.1 root 239:
1.1.1.2 root 240: void EN_NodeID5_Write(void) {
241: enet.mac_addr[5]=IoMem[IoAccessCurrentAddress & IO_SEG_MASK];
242: Log_Printf(LOG_EN_REG_LEVEL,"[EN] MAC byte 5 write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
1.1 root 243: }
244:
1.1.1.2 root 245: void EN_CounterLo_Read(void) { // 0x02006007
246: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = ((enet_tx_buffer.limit-enet_tx_buffer.size)*8)&0xFF; /* FIXME: counter value */
247: Log_Printf(LOG_EN_REG_LEVEL,"[EN] Receiver mode read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
1.1 root 248: }
249:
1.1.1.2 root 250: void EN_CounterHi_Read(void) { // 0x0200600f
251: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = (((enet_tx_buffer.limit-enet_tx_buffer.size)*8)>>8)&0x3F; /* FIXME: counter value */
252: Log_Printf(LOG_EN_REG_LEVEL,"[EN] Receiver mode read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
1.1 root 253: }
254:
1.1.1.3 root 255: static void enet_tx_interrupt(Uint8 intr) {
1.1.1.2 root 256: enet.tx_status|=intr;
257: if (enet.tx_status&enet.tx_mask) {
258: set_interrupt(INT_EN_TX, SET_INT);
259: }
1.1 root 260: }
261:
1.1.1.3 root 262: static void enet_rx_interrupt(Uint8 intr) {
1.1.1.2 root 263: enet.rx_status|=intr;
264: if (enet.rx_status&enet.rx_mask) {
265: set_interrupt(INT_EN_RX, SET_INT);
266: }
267: }
1.1 root 268:
269: /* Functions to find out if we are intended to receive a packet */
1.1.1.3 root 270:
271: /* Non-turbo */
272: #define RX_NOPACKETS 0 // Accept no packets
273: #define RX_LIMITED 1 // Accept broadcast/limited
274: #define RX_NORMAL 2 // Accept broadcast/multicast
275: #define RX_PROMISCUOUS 3 // Accept all packets
276:
277: /* Turbo */
278: #define RX_ENABLED 0x80 // Accept packets
279: #define RX_ANY 0x01 // Accept any packets
280: #define RX_OWN 0x02 // Accept own packets
281:
282: static bool recv_multicast(Uint8 *packet) {
1.1.1.2 root 283: if (packet[0]&0x01)
284: return true;
285: else
286: return false;
287: }
288:
1.1.1.3 root 289: static bool recv_local_multicast(Uint8 *packet) {
1.1.1.2 root 290: if (packet[0]&0x01 &&
291: (packet[0]&0xFE) == enet.mac_addr[0] &&
292: packet[1] == enet.mac_addr[1] &&
293: packet[2] == enet.mac_addr[2])
294: return true;
295: else
296: return false;
297: }
1.1 root 298:
1.1.1.3 root 299: static bool recv_me(Uint8 *packet) {
1.1.1.2 root 300: if (packet[0] == enet.mac_addr[0] &&
301: packet[1] == enet.mac_addr[1] &&
302: packet[2] == enet.mac_addr[2] &&
303: packet[3] == enet.mac_addr[3] &&
304: packet[4] == enet.mac_addr[4] &&
305: (packet[5] == enet.mac_addr[5] || (enet.rx_mode&RXMODE_ADDR_SIZE)))
306: return true;
307: else
308: return false;
309: }
310:
1.1.1.3 root 311: static bool recv_me_turbo(Uint8 *packet) {
312: if (packet[0] == enet.mac_addr[0] &&
313: packet[1] == enet.mac_addr[1] &&
314: packet[2] == enet.mac_addr[2] &&
315: packet[3] == enet.mac_addr[3] &&
316: packet[4] == enet.mac_addr[4] &&
317: packet[5] == enet.mac_addr[5])
318: return true;
319: else
320: return false;
321: }
322:
323: static bool recv_broadcast(Uint8 *packet) {
1.1.1.2 root 324: if (packet[0] == 0xFF &&
325: packet[1] == 0xFF &&
326: packet[2] == 0xFF &&
327: packet[3] == 0xFF &&
328: packet[4] == 0xFF &&
329: packet[5] == 0xFF)
330: return true;
331: else
332: return false;
333: }
334:
1.1.1.3 root 335: static bool enet_packet_for_me(Uint8 *packet) {
336:
337: if (ConfigureParams.System.bTurbo) {
338: if (enet.rx_mode&RX_ENABLED) {
339: if (enet.rx_mode&RX_ANY) {
340: return true;
341: } else if (enet.rx_mode&RX_OWN) {
342: if (recv_broadcast(packet) || recv_me_turbo(packet)) {
343: return true;
344: }
345: } else {
346: if (recv_broadcast(packet)) {
347: return true;
348: }
349: }
350: }
351: return false;
352: }
353:
1.1.1.2 root 354: switch (enet.rx_mode&RXMODE_MATCH_MODE) {
355: case RX_NOPACKETS:
1.1 root 356: return false;
357:
1.1.1.2 root 358: case RX_LIMITED:
359: if (recv_broadcast(packet) || recv_me(packet) || recv_local_multicast(packet))
1.1 root 360: return true;
361: else
362: return false;
363:
1.1.1.2 root 364: case RX_NORMAL:
365: if (recv_broadcast(packet) || recv_me(packet) || recv_multicast(packet))
1.1 root 366: return true;
367: else
368: return false;
369:
1.1.1.2 root 370: case RX_PROMISCUOUS:
1.1 root 371: return true;
372:
373: default: return false;
374: }
375: }
376:
1.1.1.2 root 377: void enet_receive(Uint8 *pkt, int len) {
378: if (enet_packet_for_me(pkt)) {
379: #if 1 /* Hack for short packets from SLIRP */
380: if (len<60) {
381: Log_Printf(LOG_WARN, "[EN] HACK: short packet received (%i byte). Fixed.", len);
382: len = 60;
383: }
384: #endif
385: memcpy(enet_rx_buffer.data,pkt,len);
386: enet_rx_buffer.size=enet_rx_buffer.limit=len;
1.1.1.3 root 387: enet.tx_status |= TXSTAT_NET_BUSY;
1.1.1.2 root 388: } else {
389: Log_Printf(LOG_WARN, "[EN] Packet is not for me.");
390: }
1.1 root 391: }
392:
1.1.1.3 root 393: static void print_buf(Uint8 *buf, Uint32 size) {
1.1.1.2 root 394: #if LOG_EN_DATA
395: int i;
396: for (i=0; i<size; i++) {
397: if (i==14 || (i-14)%16==0) {
398: printf("\n");
399: }
400: printf("%02X ",buf[i]);
401: }
402: printf("\n");
403: #endif
1.1 root 404: }
405:
1.1.1.2 root 406:
407: #define ENET_FRAMESIZE_MIN 64 /* 46 byte data and 14 byte header, 4 byte CRC */
408: #define ENET_FRAMESIZE_MAX 1518 /* 1500 byte data and 14 byte header, 4 byte CRC */
409:
410: /* Ethernet periodic check */
1.1.1.3 root 411: #define ENET_IO_DELAY 500 /* use 500 for NeXT hardware test, 20 for status test */
412: #define ENET_IO_SHORT 40 /* use 40 for 68030 hardware test */
1.1.1.2 root 413:
414: enum {
415: RECV_STATE_WAITING,
416: RECV_STATE_RECEIVING
417: } receiver_state;
418:
419: bool tx_done;
420: bool rx_chain;
421: int old_size;
1.1.1.3 root 422: int en_state;
423:
424: #define EN_DISCONNECTED 0
425: #define EN_LOOPBACK 1
426: #define EN_THINWIRE 2
427: #define EN_TWISTEDPAIR 3
1.1.1.2 root 428:
429: /* Fujitsu ethernet controller */
1.1.1.3 root 430: static int enet_state(void) {
431: if (ConfigureParams.System.nMachineType == NEXT_CUBE030) {
432: if (enet.tx_mode&TXMODE_DIS_LOOP) {
433: if (ConfigureParams.Ethernet.bEthernetConnected) {
434: return EN_THINWIRE;
435: }
436: } else {
437: return EN_LOOPBACK;
438: }
439: } else if (bmap_tpe_select) {
440: if (ConfigureParams.Ethernet.bEthernetConnected) {
441: if (ConfigureParams.Ethernet.bTwistedPair) {
442: return EN_TWISTEDPAIR;
443: }
444: }
445: } else {
446: if (enet.tx_mode&TXMODE_DIS_LOOP) {
447: if (ConfigureParams.Ethernet.bEthernetConnected) {
448: if (!ConfigureParams.Ethernet.bTwistedPair) {
449: return EN_THINWIRE;
450: }
451: }
452: } else {
453: return EN_LOOPBACK;
454: }
455: }
456: return EN_DISCONNECTED;
457: }
458:
459: static void enet_io(void) {
460:
461: en_state = enet_state();
462:
1.1.1.2 root 463: /* Receive packet */
464: switch (receiver_state) {
465: case RECV_STATE_WAITING:
466: if (enet_rx_buffer.size>0) {
467: Statusbar_BlinkLed(DEVICE_LED_ENET);
468: Log_Printf(LOG_EN_LEVEL, "[EN] Receiving packet from %02X:%02X:%02X:%02X:%02X:%02X",
469: enet_rx_buffer.data[6], enet_rx_buffer.data[7], enet_rx_buffer.data[8],
470: enet_rx_buffer.data[9], enet_rx_buffer.data[10], enet_rx_buffer.data[11]);
471: print_buf(enet_rx_buffer.data, enet_rx_buffer.size);
472: enet_rx_buffer.size+=4;
473: enet_rx_buffer.limit+=4;
1.1.1.3 root 474: rx_chain = false;
1.1.1.2 root 475: enet.rx_status&=~RXSTAT_PKT_OK;
476: if (enet_rx_buffer.size<ENET_FRAMESIZE_MIN && !(enet.rx_mode&RXMODE_ENA_SHORT)) {
477: Log_Printf(LOG_WARN, "[EN] Received packet is short (%i byte)",enet_rx_buffer.size);
478: enet_rx_interrupt(RXSTAT_SHORT_PKT);
479: enet_rx_buffer.size = 0;
1.1.1.3 root 480: enet.tx_status &= ~TXSTAT_NET_BUSY;
1.1.1.2 root 481: break; /* Keep on waiting for a good packet */
482: } else /* Fall through to receiving state */
483: receiver_state = RECV_STATE_RECEIVING;
1.1.1.3 root 484: } else if (en_state == EN_THINWIRE || en_state == EN_TWISTEDPAIR) {
1.1.1.2 root 485: /* Receive from real world network */
1.1.1.4 ! root 486: enet_output();
1.1.1.2 root 487: break;
488: } else
489: break;
490: case RECV_STATE_RECEIVING:
491: if (enet_rx_buffer.size>0) {
492: old_size = enet_rx_buffer.size;
493: dma_enet_write_memory(rx_chain);
494: if (enet_rx_buffer.size==old_size) {
495: Log_Printf(LOG_WARN, "[EN] Receiving packet: Error! Receiver overflow (DMA disabled)!");
496: enet_rx_interrupt(RXSTAT_OVERFLOW);
497: rx_chain = false;
1.1.1.3 root 498: enet_rx_buffer.size = 0;
499: enet.tx_status &= ~TXSTAT_NET_BUSY;
1.1.1.2 root 500: receiver_state = RECV_STATE_WAITING;
501: break; /* Go back to waiting state */
502: }
503: if (enet_rx_buffer.size>0) {
504: Log_Printf(LOG_WARN, "[EN] Receiving packet: Transfer not complete!");
505: rx_chain = true;
506: break; /* Loop in receiving state */
507: } else { /* done */
508: Log_Printf(LOG_EN_LEVEL, "[EN] Receiving packet: Transfer complete.");
509: rx_chain = false;
510: enet_rx_interrupt(RXSTAT_PKT_OK);
1.1.1.3 root 511: if (en_state == EN_LOOPBACK) { /* same for thin wire loopback? */
1.1.1.2 root 512: enet_tx_interrupt(TXSTAT_TX_RECVD);
513: }
1.1.1.3 root 514: enet.tx_status &= ~TXSTAT_NET_BUSY;
1.1.1.2 root 515: receiver_state = RECV_STATE_WAITING;
516: }
517: }
518: break;
519:
520: default:
521: break;
522: }
523:
524: /* Send packet */
525: if (enet.tx_status&TXSTAT_READY) {
1.1.1.3 root 526: if (en_state != EN_DISCONNECTED) {
527: if (enet.tx_status&TXSTAT_NET_BUSY) {
528: /* Wait until network is free */
529: Log_Printf(LOG_WARN, "[EN] Network is busy. Transmission delayed.");
1.1.1.2 root 530: } else {
1.1.1.3 root 531: old_size = enet_tx_buffer.size;
532: tx_done=dma_enet_read_memory();
533: if (enet_tx_buffer.size>0) {
534: enet.tx_status &= ~TXSTAT_TX_RECVD;
535: if (enet_tx_buffer.size==old_size && !tx_done) {
536: Log_Printf(LOG_WARN, "[EN] Sending packet: Error! Transmitter underflow (no EOP)!");
537: enet_tx_interrupt(TXSTAT_UNDERFLOW);
538: enet_tx_buffer.size=0;
539: } else if (enet_tx_buffer.size>15) {
540: enet_tx_buffer.size-=15;
541: } else if (tx_done) {
542: Log_Printf(LOG_WARN, "[EN] Transmitter error: Early EOP!");
543: enet_tx_buffer.size=0;
544: tx_done = false;
545: }
546: }
547: if (tx_done) {
548: Statusbar_BlinkLed(DEVICE_LED_ENET);
549: Log_Printf(LOG_EN_LEVEL, "[EN] Sending packet to %02X:%02X:%02X:%02X:%02X:%02X",
550: enet_tx_buffer.data[0], enet_tx_buffer.data[1], enet_tx_buffer.data[2],
551: enet_tx_buffer.data[3], enet_tx_buffer.data[4], enet_tx_buffer.data[5]);
552: print_buf(enet_tx_buffer.data, enet_tx_buffer.size);
553: if (en_state == EN_LOOPBACK) {
554: /* Loop back */
555: Log_Printf(LOG_WARN, "[EN] Loopback packet.");
556: enet_receive(enet_tx_buffer.data, enet_tx_buffer.size);
557: } else {
558: /* Send to real world network */
1.1.1.4 ! root 559: enet_input(enet_tx_buffer.data,enet_tx_buffer.size);
1.1.1.3 root 560: /* Simultaneously receive packet on thin ethernet */
561: if (en_state == EN_THINWIRE) {
562: enet_receive(enet_tx_buffer.data, enet_tx_buffer.size);
563: }
564: }
565: enet_tx_buffer.size=0;
1.1.1.2 root 566: }
567: }
568: }
569: }
570: }
571:
572: /* AT&T ethernet controller for turbo systems */
573: #define TXMODE_ENABLE 0x80
574: #define RXMODE_ENABLE 0x80
1.1.1.3 root 575: #define TXMODE_LOOP 0x02
576: #define TXMODE_TPE 0x04
577: #define ENCTRL_TPE 0x40
1.1.1.2 root 578:
579: void EN_Control_Read(void) { // 0x02006006
1.1.1.3 root 580: Uint8 val = enet.reset;
581: if (ConfigureParams.Ethernet.bEthernetConnected && ConfigureParams.Ethernet.bTwistedPair) {
582: val &= ~ENCTRL_TPE;
583: } else {
584: val |= ENCTRL_TPE;
585: }
586: IoMem[IoAccessCurrentAddress & IO_SEG_MASK] = val;
1.1.1.2 root 587: Log_Printf(LOG_EN_REG_LEVEL,"[newEN] Control read at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
588: }
589:
590: void EN_Control_Write(void) {
591: enet.reset=(IoMem[IoAccessCurrentAddress & IO_SEG_MASK])&EN_RESET;
592: Log_Printf(LOG_EN_REG_LEVEL,"[newEN] Control write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
593: enet_reset();
594: }
595:
1.1.1.3 root 596: static int new_enet_state(void) {
597: if (enet.tx_mode&TXMODE_LOOP) {
598: return EN_LOOPBACK;
599: } else if (ConfigureParams.Ethernet.bEthernetConnected) {
600: if (enet.tx_mode&TXMODE_TPE) {
601: if (ConfigureParams.Ethernet.bTwistedPair) {
602: return EN_TWISTEDPAIR;
603: }
604: } else {
605: if (!ConfigureParams.Ethernet.bTwistedPair) {
606: return EN_THINWIRE;
607: }
608: }
609: }
610: return EN_DISCONNECTED;
611: }
612:
613: static void new_enet_io(void) {
614:
615: en_state = new_enet_state();
616:
1.1.1.2 root 617: /* Receive packet */
618: switch (receiver_state) {
619: case RECV_STATE_WAITING:
620: if (enet_rx_buffer.size>0) {
621: Statusbar_BlinkLed(DEVICE_LED_ENET);
622: Log_Printf(LOG_EN_LEVEL, "[newEN] Receiving packet from %02X:%02X:%02X:%02X:%02X:%02X",
623: enet_rx_buffer.data[6], enet_rx_buffer.data[7], enet_rx_buffer.data[8],
624: enet_rx_buffer.data[9], enet_rx_buffer.data[10], enet_rx_buffer.data[11]);
625: print_buf(enet_rx_buffer.data, enet_rx_buffer.size);
626: enet_rx_buffer.size+=4;
627: enet_rx_buffer.limit+=4;
1.1.1.3 root 628: rx_chain = false;
1.1.1.2 root 629: enet.rx_status&=~RXSTAT_PKT_OK;
630: if (enet_rx_buffer.size<ENET_FRAMESIZE_MIN && !(enet.rx_mode&RXMODE_ENA_SHORT)) {
631: Log_Printf(LOG_WARN, "[newEN] Received packet is short (%i byte)",enet_rx_buffer.size);
632: enet_rx_interrupt(RXSTAT_SHORT_PKT);
633: enet_rx_buffer.size = 0;
1.1.1.3 root 634: enet.tx_status &= ~TXSTAT_NET_BUSY;
1.1.1.2 root 635: break; /* Keep on waiting for a good packet */
636: } else /* Fall through to receiving state */
637: receiver_state = RECV_STATE_RECEIVING;
1.1.1.3 root 638: } else if (en_state == EN_THINWIRE || en_state == EN_TWISTEDPAIR) {
1.1.1.2 root 639: /* Receive from real world network */
1.1.1.4 ! root 640: enet_output();
1.1.1.2 root 641: break;
642: } else
643: break;
644: case RECV_STATE_RECEIVING:
645: if (enet_rx_buffer.size>0) {
646: old_size = enet_rx_buffer.size;
647: dma_enet_write_memory(rx_chain);
648: if (enet_rx_buffer.size==old_size) {
649: Log_Printf(LOG_WARN, "[newEN] Receiving packet: Error! Receiver overflow (DMA disabled)!");
650: enet_rx_interrupt(RXSTAT_OVERFLOW);
651: rx_chain = false;
1.1.1.3 root 652: enet_rx_buffer.size = 0;
653: enet.tx_status &= ~TXSTAT_NET_BUSY;
1.1.1.2 root 654: receiver_state = RECV_STATE_WAITING;
655: break; /* Go back to waiting state */
656: }
657: if (enet_rx_buffer.size>0) {
658: Log_Printf(LOG_WARN, "[newEN] Receiving packet: Transfer not complete!");
659: rx_chain = true;
660: break; /* Loop in receiving state */
661: } else { /* done */
662: Log_Printf(LOG_EN_LEVEL, "[newEN] Receiving packet: Transfer complete.");
663: rx_chain = false;
664: enet_rx_interrupt(RXSTAT_PKT_OK);
1.1.1.3 root 665: if (en_state == EN_LOOPBACK) {
1.1.1.2 root 666: enet_tx_interrupt(TXSTAT_TX_RECVD);
667: }
1.1.1.3 root 668: enet.tx_status &= ~TXSTAT_NET_BUSY;
1.1.1.2 root 669: receiver_state = RECV_STATE_WAITING;
670: }
671: }
672: break;
673:
674: default:
675: break;
676: }
677:
678: /* Send packet */
679: if (enet.tx_mode&TXMODE_ENABLE) {
1.1.1.3 root 680: if (en_state != EN_DISCONNECTED) {
681: if (enet.tx_status&TXSTAT_NET_BUSY) {
682: /* Wait until network is free */
683: Log_Printf(LOG_WARN, "[EN] Network is busy. Transmission delayed.");
1.1.1.2 root 684: } else {
1.1.1.3 root 685: dma_enet_read_memory();
686: if (enet_tx_buffer.size>0) {
687: Statusbar_BlinkLed(DEVICE_LED_ENET);
688: Log_Printf(LOG_EN_LEVEL, "[newEN] Sending packet to %02X:%02X:%02X:%02X:%02X:%02X",
689: enet_tx_buffer.data[0], enet_tx_buffer.data[1], enet_tx_buffer.data[2],
690: enet_tx_buffer.data[3], enet_tx_buffer.data[4], enet_tx_buffer.data[5]);
691: print_buf(enet_tx_buffer.data, enet_tx_buffer.size);
692: enet.tx_status &= ~TXSTAT_TX_RECVD;
693: if (en_state == EN_LOOPBACK) {
694: /* Loop back */
695: Log_Printf(LOG_WARN, "[newEN] Loopback packet.");
696: enet_receive(enet_tx_buffer.data, enet_tx_buffer.size);
697: } else {
698: /* Send to real world network */
1.1.1.4 ! root 699: enet_input(enet_tx_buffer.data,enet_tx_buffer.size);
1.1.1.3 root 700: /* Simultaneously receive packet on thin ethernet */
701: if (en_state == EN_THINWIRE) {
702: enet_receive(enet_tx_buffer.data, enet_tx_buffer.size);
703: }
704: }
705: enet_tx_buffer.size=0;
706: enet_tx_interrupt(TXSTAT_READY);
707: }
708: }
709: } else { /* disconnected - strange, but required by ROM and 2.2 kernel */
710: if (ConfigureParams.Ethernet.bEthernetConnected) {
711: if (!ConfigureParams.Ethernet.bTwistedPair) {
712: enet_tx_interrupt(TXSTAT_READY);
1.1.1.2 root 713: }
714: }
715: }
1.1.1.3 root 716: enet.tx_status |= TXSTAT_READY; /* really? */
1.1.1.2 root 717: }
718: }
719:
720: void ENET_IO_Handler(void) {
721: CycInt_AcknowledgeInterrupt();
722:
723: if (enet.reset&EN_RESET) {
724: Log_Printf(LOG_WARN, "Stopping Ethernet Transmitter/Receiver");
725: enet_stopped=true;
1.1.1.4 ! root 726: /* Stop SLIRP/PCAP */
1.1.1.2 root 727: if (ConfigureParams.Ethernet.bEthernetConnected) {
1.1.1.4 ! root 728: enet_stop();
1.1.1.2 root 729: }
730: return;
731: }
732:
733: if (ConfigureParams.System.bTurbo) {
734: new_enet_io();
735: } else {
736: enet_io();
737: }
738:
1.1.1.3 root 739: CycInt_AddRelativeInterruptUs(receiver_state==RECV_STATE_WAITING?ENET_IO_DELAY:ENET_IO_SHORT, 0, INTERRUPT_ENET_IO);
1.1.1.2 root 740: }
741:
742: void enet_reset(void) {
743: if (enet.reset&EN_RESET) {
744: enet.tx_status=ConfigureParams.System.bTurbo?0:TXSTAT_READY;
745: } else if (enet_stopped==true) {
746: Log_Printf(LOG_WARN, "Starting Ethernet Transmitter/Receiver");
747: enet_stopped=false;
1.1.1.3 root 748: CycInt_AddRelativeInterruptUs(ENET_IO_DELAY, 0, INTERRUPT_ENET_IO);
1.1.1.4 ! root 749: /* Start SLIRP/PCAP */
1.1.1.2 root 750: if (ConfigureParams.Ethernet.bEthernetConnected) {
1.1.1.4 ! root 751: enet_start(enet.mac_addr);
1.1.1.2 root 752: }
753: }
754: }
755:
756: void Ethernet_Reset(bool hard) {
1.1.1.4 ! root 757: static int init_done = 0;
! 758:
1.1.1.2 root 759: if (hard) {
760: enet.reset=EN_RESET;
761: enet_stopped=true;
762: enet_rx_buffer.size=enet_tx_buffer.size=0;
763: enet_rx_buffer.limit=enet_tx_buffer.limit=64*1024;
1.1.1.3 root 764: enet.tx_status=ConfigureParams.System.bTurbo?0:TXSTAT_READY;
1.1.1.4 ! root 765: }
! 766:
! 767: if (init_done) {
! 768: /* Stop SLIRP/PCAP */
! 769: enet_stop();
! 770: }
! 771: #if HAVE_PCAP
! 772: if (ConfigureParams.Ethernet.nHostInterface == ENET_PCAP) {
! 773: enet_output = enet_pcap_queue_poll;
! 774: enet_input = enet_pcap_input;
! 775: enet_start = enet_pcap_start;
! 776: enet_stop = enet_pcap_stop;
! 777: } else
! 778: #endif
! 779: {
! 780: enet_output = enet_slirp_queue_poll;
! 781: enet_input = enet_slirp_input;
! 782: enet_start = enet_slirp_start;
! 783: enet_stop = enet_slirp_stop;
! 784: }
! 785: init_done = 1;
! 786:
! 787: if (ConfigureParams.Ethernet.bEthernetConnected && !(enet.reset&EN_RESET)) {
! 788: /* Start SLIRP/PCAP */
! 789: enet_start(enet.mac_addr);
1.1.1.2 root 790: } else {
1.1.1.4 ! root 791: /* Stop SLIRP/PCAP */
! 792: enet_stop();
1.1.1.2 root 793: }
1.1 root 794: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.