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