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

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

unix.superglobalmegacorp.com

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