|
|
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.