Annotation of previous_trunk/src/ethernet.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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