Annotation of previous/src/ethernet.c, revision 1.1.1.2

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.