|
|
1.1 ! root 1: /* Previous - iethernet.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 the NEXT. ! 7: ! 8: constants and struct netBSD mb8795reg.h file ! 9: ! 10: */ ! 11: ! 12: #include "ioMem.h" ! 13: #include "ioMemTables.h" ! 14: #include "m68000.h" ! 15: #include "configuration.h" ! 16: #include "esp.h" ! 17: #include "sysReg.h" ! 18: #include "dma.h" ! 19: #include "scsi.h" ! 20: #include "ethernet.h" ! 21: ! 22: #define LOG_EN_LEVEL LOG_WARN ! 23: #define IO_SEG_MASK 0x1FFFF ! 24: ! 25: ! 26: /* Function Prototypes */ ! 27: void EnTx_Lower_IRQ(void); ! 28: void EnRx_Lower_IRQ(void); ! 29: void EnTx_Raise_IRQ(void); ! 30: void EnRx_Raise_IRQ(void); ! 31: ! 32: ! 33: /* Ethernet Regisers */ ! 34: #define EN_TXSTAT 0 ! 35: #define EN_TXMASK 1 ! 36: #define EN_RXSTAT 2 ! 37: #define EN_RXMASK 3 ! 38: #define EN_TXMODE 4 ! 39: #define EN_RXMODE 5 ! 40: ! 41: #define EN_RESET 6 ! 42: ! 43: ! 44: /* Ethernet Register Constants */ ! 45: #define TXSTAT_RDY 0x80 // Ready for Packet ! 46: ! 47: #define RXSTAT_OK 0x80 // Packet received is correct ! 48: ! 49: #define TXMODE_NOLOOP 0x02 // Loop back control disabled ! 50: ! 51: #define RXMODE_ADDRSIZE 0x10 // Reduces NODE match to 5 chars ! 52: #define RXMODE_NOPACKETS 0x00 // Accept no packets ! 53: #define RXMODE_LIMITED 0x01 // Accept Broadcast/limited ! 54: #define RXMODE_NORMAL 0x02 // Accept Broadcast/multicasts ! 55: #define RXMODE_PROMISCUOUS 0x03 // Accept all packets ! 56: #define RXMODE_RESETENABLE 0x04 // One for reset packet enable ! 57: ! 58: #define RESET_VAL 0x80 // Generate Reset ! 59: ! 60: typedef struct { ! 61: Uint8 tx_status; ! 62: Uint8 tx_mask; ! 63: Uint8 tx_mode; ! 64: Uint8 rx_status; ! 65: Uint8 rx_mask; ! 66: Uint8 rx_mode; ! 67: } ETHERNET_CONTROLLER; ! 68: ! 69: ETHERNET_CONTROLLER ethernet; ! 70: ! 71: Uint8 ethernet_buffer[1600]; ! 72: ! 73: ! 74: Uint8 MACaddress[6]; ! 75: ! 76: void Ethernet_Read(void) { ! 77: Uint8 reg = IoAccessCurrentAddress&0x0F; ! 78: Uint8 val; ! 79: ! 80: switch (reg) { ! 81: case EN_TXSTAT: ! 82: val = ethernet.tx_status; ! 83: break; ! 84: case EN_TXMASK: ! 85: val = ethernet.tx_mask; ! 86: break; ! 87: case EN_RXSTAT: ! 88: val = ethernet.rx_status; ! 89: break; ! 90: case EN_RXMASK: ! 91: val = ethernet.rx_mask; ! 92: break; ! 93: case EN_TXMODE: ! 94: val = ethernet.tx_mode; ! 95: break; ! 96: case EN_RXMODE: ! 97: val = ethernet.rx_mode; ! 98: break; ! 99: case EN_RESET: ! 100: break; ! 101: ! 102: /* Read MAC Address */ ! 103: case 8: ! 104: case 9: ! 105: case 10: ! 106: case 11: ! 107: case 12: ! 108: case 13: ! 109: val = MACaddress[reg-8]; ! 110: break; ! 111: default: ! 112: break; ! 113: } ! 114: IoMem[IoAccessCurrentAddress&IO_SEG_MASK] = val; ! 115: ! 116: Log_Printf(LOG_EN_LEVEL, "[Ethernet] read reg %d val %02x PC=%x %s at %d",reg,val,m68k_getpc(),__FILE__,__LINE__); ! 117: } ! 118: ! 119: void Ethernet_Write(void) { ! 120: Uint8 val = IoMem[IoAccessCurrentAddress & IO_SEG_MASK]; ! 121: Uint8 reg = IoAccessCurrentAddress&0xF; ! 122: ! 123: Log_Printf(LOG_EN_LEVEL, "[Ethernet] write reg %d val %02x PC=%x %s at %d",reg,val,m68k_getpc(),__FILE__,__LINE__); ! 124: ! 125: switch (reg) { ! 126: case EN_TXSTAT: ! 127: if (val == 0xFF) ! 128: ethernet.tx_status = 0x80; // ? temp hack ! 129: else ! 130: ethernet.tx_status = val; //ethernet.tx_status & (0xF0 | ~val); ? ! 131: // EnTx_Raise_IRQ(); // check irq ! 132: break; ! 133: case EN_TXMASK: ! 134: ethernet.tx_mask = val & 0xAF; ! 135: // EnTx_Raise_IRQ(); // check irq ! 136: break; ! 137: case EN_RXSTAT: ! 138: if (val == 0xFF) ! 139: ethernet.rx_status = 0x00; ! 140: else ! 141: ethernet.rx_status = val; //ethernet.rx_status & (0x07 | ~val); ? ! 142: // EnRx_Raise_IRQ(); // check irq ! 143: break; ! 144: case EN_RXMASK: ! 145: ethernet.rx_mask = val & 0x9F; ! 146: // EnRx_Raise_IRQ(); // check irq ! 147: break; ! 148: case EN_TXMODE: ! 149: ethernet.tx_mode = val; ! 150: break; ! 151: case EN_RXMODE: ! 152: ethernet.rx_mode = val; ! 153: break; ! 154: case EN_RESET: ! 155: if (val&RESET_VAL) ! 156: Ethernet_Reset(); ! 157: break; ! 158: ! 159: /* Write MAC Address */ ! 160: case 8: ! 161: case 9: ! 162: case 10: ! 163: case 11: ! 164: case 12: ! 165: case 13: ! 166: MACaddress[reg-8] = val; ! 167: break; ! 168: ! 169: default: ! 170: break; ! 171: } ! 172: } ! 173: ! 174: ! 175: void Ethernet_Reset(void) { ! 176: ethernet.tx_status = TXSTAT_RDY; ! 177: ethernet.tx_mask = 0x00; ! 178: ethernet.tx_mode = 0x00; ! 179: ethernet.rx_status = 0x00; ! 180: ethernet.rx_mask = 0x00; ! 181: ethernet.rx_mode = 0x00; ! 182: ! 183: EnTx_Lower_IRQ(); ! 184: EnRx_Lower_IRQ(); ! 185: ! 186: // txlen = rxlen = txcount = 0; ! 187: // set_promisc(true); ! 188: // start_send(); ! 189: } ! 190: ! 191: void Ethernet_Transmit(void) { ! 192: Uint32 size; ! 193: dma_memory_read(ethernet_buffer, &size, CHANNEL_EN_TX); ! 194: ethernet.tx_status = TXSTAT_RDY; ! 195: EnTx_Raise_IRQ(); ! 196: ! 197: Log_Printf(LOG_EN_LEVEL, "Ethernet: Send packet to %02X:%02X:%02X:%02X:%02X:%02X", ! 198: ethernet_buffer[0], ethernet_buffer[1], ethernet_buffer[2], ! 199: ethernet_buffer[3], ethernet_buffer[4], ethernet_buffer[5]); ! 200: ! 201: if (!(ethernet.tx_mode&TXMODE_NOLOOP)) { // if loop back is not disabled ! 202: Ethernet_Receive(ethernet_buffer, size); // loop back ! 203: } ! 204: ! 205: // TODO: send packet to real network ! 206: } ! 207: ! 208: void Ethernet_Receive(Uint8 *packet, Uint32 size) { ! 209: if (Packet_Receiver_Me(packet)) { ! 210: Log_Printf(LOG_EN_LEVEL, "Ethernet: Receive packet from %02X:%02X:%02X:%02X:%02X:%02X", ! 211: packet[6], packet[7], packet[8], packet[9], packet[10], packet[11]); ! 212: ! 213: dma_memory_write(packet, size, CHANNEL_EN_RX); // loop back for experiment ! 214: ethernet.rx_status |= RXSTAT_OK; // packet received is correct ! 215: EnRx_Raise_IRQ(); ! 216: } ! 217: } ! 218: ! 219: ! 220: void EnTx_Lower_IRQ(void) { ! 221: set_interrupt(INT_EN_TX, RELEASE_INT); ! 222: } ! 223: ! 224: void EnRx_Lower_IRQ(void) { ! 225: set_interrupt(INT_EN_RX, RELEASE_INT); ! 226: } ! 227: ! 228: void EnTx_Raise_IRQ(void) { ! 229: set_interrupt(INT_EN_TX, SET_INT); ! 230: } ! 231: ! 232: void EnRx_Raise_IRQ(void) { ! 233: set_interrupt(INT_EN_RX, SET_INT); ! 234: } ! 235: ! 236: ! 237: /* Functions to find out if we are intended to receive a packet */ ! 238: ! 239: bool Packet_Receiver_Me(Uint8 *packet) { ! 240: switch (ethernet.rx_mode&0x03) { ! 241: case RXMODE_NOPACKETS: ! 242: return false; ! 243: ! 244: case RXMODE_NORMAL: ! 245: if (Broadcast(packet) || Me(packet) || Local_Multicast(packet)) ! 246: return true; ! 247: else ! 248: return false; ! 249: ! 250: case RXMODE_LIMITED: ! 251: if (Broadcast(packet) || Me(packet) || Multicast(packet)) ! 252: return true; ! 253: else ! 254: return false; ! 255: ! 256: case RXMODE_PROMISCUOUS: ! 257: return true; ! 258: ! 259: default: return false; ! 260: } ! 261: } ! 262: ! 263: bool Multicast(Uint8 *packet) { ! 264: if (packet[0]&0x01) ! 265: return true; ! 266: else ! 267: return false; ! 268: } ! 269: ! 270: bool Local_Multicast(Uint8 *packet) { ! 271: if (packet[0]&0x01 && ! 272: (packet[0]&0xFE) == MACaddress[0] //&& ! 273: // packet[1] == MACaddress[1] && ! 274: // packet[2] == MACaddress[2] ! 275: ) ! 276: return true; ! 277: else ! 278: return false; ! 279: } ! 280: ! 281: bool Me(Uint8 *packet) { ! 282: if (packet[0] == MACaddress[0] && ! 283: // packet[1] == MACaddress[1] && ! 284: // packet[2] == MACaddress[2] && ! 285: // packet[3] == MACaddress[3] && ! 286: packet[4] == MACaddress[4] && ! 287: (packet[5] == MACaddress[5] || (ethernet.rx_mode&RXMODE_ADDRSIZE))) ! 288: return true; ! 289: else ! 290: return false; ! 291: } ! 292: ! 293: bool Broadcast(Uint8 *packet) { ! 294: if (packet[0] == 0xFF && ! 295: // packet[1] == 0xFF && ! 296: // packet[2] == 0xFF && ! 297: // packet[3] == 0xFF && ! 298: packet[4] == 0xFF && ! 299: packet[5] == 0xFF) ! 300: return true; ! 301: else ! 302: return false; ! 303: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.