📄 drv_8019.lst
字号:
185 1 delay_1ms(10);
186 1
187 1 #endif
188 1
189 1 /* copy RAM data to RTL8019AS iRAM with (from MAC to end of data ) */
190 1 ei_output( EthTxBuf, TX_START_PG << 8, pkLengthInOctets );
191 1
192 1 /* Just send it, and does not check */
193 1 EN0_TCNTLO = pkLengthInOctets& 0xff;
194 1 EN0_TCNTHI = pkLengthInOctets>> 8;
195 1 EN0_TPSR = TX_START_PG;
196 1 EN_CMD = E8390_NODMA + E8390_TRANS + E8390_START;
197 1
198 1 /* Turn 8390 interrupts back on. */
199 1 EN0_IMR = ENISR_ALL;
200 1 return 1;
201 1 }
202
203 /* copy RAM data to RTL8019AS Internal RAM */
204 void ei_output( BYTE *buf, WORD StartAddr, WORD Count )
205 {
206 1 word loop;
207 1
208 1 EN0_ISR = ENISR_RDC;
209 1 /* Now the normal output. */
210 1 EN0_RCNTLO = Count & 0xff;
211 1 EN0_RCNTHI = Count >> 8;
212 1 EN0_RSARLO = StartAddr & 0xFF;
213 1 EN0_RSARHI = StartAddr >> 8;
214 1 EN_CMD = E8390_RWRITE + E8390_START + E8390_PAGE0;
215 1 for(loop=0;loop < Count;loop++){
216 2 EN_DATA = *buf++;
217 2 }
218 1 EN0_ISR = ENISR_RDC; /* Ack intr. to Remote DMA */
219 1 }
220
221 void ei_receive(void) reentrant /* maybe reentrant... */
222 {
223 1 word pkt_len, current_offset;
224 1
225 1 byte rx_pkt=0;
226 1 byte rxing_page, this_frame, next_frame;
227 1
228 1 while ( ++rx_pkt < 10) {
229 2 /* Get the Receive Page, CURR */
230 2 EN_CMD = EN_NODMA + EN_PAGE1 + EN_START;
231 2 rxing_page = EN1_CURPAG;
232 2 EN_CMD = EN_NODMA + EN_PAGE0 + EN_START;
233 2
234 2 /* Remove one frame from the ring. Boundary is always a page behind. */
235 2 this_frame = EN0_BOUNDARY + 1;
236 2
237 2 if (this_frame >= RX_STOP_PG)
238 2 this_frame = RX_START_PG;
C51 COMPILER V7.07 DRV_8019 04/20/2004 18:04:40 PAGE 5
239 2
240 2 if (this_frame == rxing_page) /* Read all the frames? */
241 2 break; /* Done for now */
242 2
243 2 current_offset = (word)(this_frame << 8);
244 2
245 2 /* Get the header of this packet */
246 2 ethernet_get_8390_hdr( current_offset, 4);
247 2 pkt_len = (word)(ethernet_8390_hdr[3]<<8) + ethernet_8390_hdr[2] - 4;
248 2
249 2 next_frame = this_frame + 1 + ((pkt_len+4)>>8);
250 2 //print(" | this : ") ; putb_ser( this_frame ) ;
251 2 //print(" | next : ") ; putb_ser( next_frame ) ;
252 2 //print(" | 8390_hdr[1] : ") ; putb_ser( ethernet_8390_hdr[1] ) ;
253 2 //print("\r\n");
254 2
255 2 if ( ethernet_8390_hdr[1] != next_frame
256 2 && ethernet_8390_hdr[1] != next_frame + 1
257 2 && ethernet_8390_hdr[1] != next_frame - (RX_STOP_PG-RX_START_PG)
258 2 && ethernet_8390_hdr[1] != next_frame + 1 - (RX_STOP_PG-RX_START_PG) ) {
259 3 current_page = rxing_page;
260 3 EN0_BOUNDARY = current_page-1;
261 3 continue;
262 3 }
263 2
264 2 if ( pkt_len > MAX_PACKET_SIZE || pkt_len < MIN_PACKET_SIZE ) {
265 3 //print("\n\rBogus packet size..");
266 3 }
267 2 else if ((ethernet_8390_hdr[0] & 0x0f) == ENRSR_RXOK) {
268 3 //print("\r\nhdr len =");
269 3 //putb_ser(ethernet_8390_hdr[3]);
270 3 //putb_ser(ethernet_8390_hdr[2]);
271 3
272 3 /* If RxBuffer is full, then break */
273 3 if ( EthRxBufWrPtr == EthRxBufRdPtr )
274 3 break;
275 3 ei_input( EthRxBuf[EthRxBufWrPtr], current_offset + 4, pkt_len );
276 3 EthRxBufWrPtr++;
277 3 if ( EthRxBufWrPtr == NBUF ) EthRxBufWrPtr = 0;
278 3 }
279 2
280 2 next_frame = ethernet_8390_hdr[1];
281 2
282 2 /* This _should_ never happen: it's here for avoiding bad clones. */
283 2 if (next_frame >= RX_STOP_PG) { /* next frame inconsistency */
284 3 next_frame = RX_START_PG;
285 3 }
286 2 current_page = next_frame;
287 2 EN0_BOUNDARY = next_frame-1;
288 2 }
289 1
290 1 /* We used to also ack ENISR_OVER here, but that would sometimes mask
291 1 a real overrun, leaving the 8390 in a stopped state with rec'vr off. */
292 1 EN0_ISR = ENISR_RX+ENISR_RX_ERR;
293 1 }
294
295 //void ei_input(byte *buf, word StartAddr, word Count)
296 void ei_input(byte *buf, word StartAddr, word Count) reentrant
297 {
298 1 word loop;
299 1
300 1 EN_CMD = EN_PAGE0 + EN_RREAD + EN_START;
C51 COMPILER V7.07 DRV_8019 04/20/2004 18:04:40 PAGE 6
301 1 /* Set Remote byte count */
302 1 EN0_RCNTLO = (byte)(Count & 0xff); /* Low byte of tx byte count */
303 1 EN0_RCNTHI = (byte)(Count >> 8); /* High byte of tx byte count Transmit byte count register */
304 1
305 1 /* Set Remote Start Address */
306 1 EN0_RSARLO = (byte)(StartAddr & 0xff); /*LSB Remote start address reg */
307 1 EN0_RSARHI = (byte)(StartAddr >> 8); /* MSB Remote start address reg */
308 1
309 1 EN_CMD = EN_PAGE0 + EN_RREAD + EN_START; /* Remote Read, Start the chip, clear reset */
310 1 for(loop=0;loop < Count;loop++){
311 2 *buf++ = EN_DATA;
312 2 }
313 1 EN0_ISR = ENISR_RDC; /* Ack intr. to Remote DMA */
314 1 }
315
316 //void ethernet_get_8390_hdr( word StartAddr, word Count)
317 void ethernet_get_8390_hdr( word StartAddr, word Count) reentrant
318 {
319 1 word loop;
320 1
321 1 EN_CMD = EN_PAGE0 + EN_RREAD + EN_START;
322 1 /* Set Remote byte count */
323 1 EN0_RCNTLO = (byte)(Count & 0xff); /* Low byte of tx byte count */
324 1 EN0_RCNTHI = (byte)(Count >> 8); /* High byte of tx byte count Transmit byte count register */
325 1
326 1 /* Set Remote Start Address */
327 1 EN0_RSARLO = (byte)(StartAddr & 0xff); /*LSB Remote start address reg */
328 1 EN0_RSARHI = (byte)(StartAddr >> 8); /* MSB Remote start address reg */
329 1
330 1 EN_CMD = EN_PAGE0 + EN_RREAD + EN_START; /* Remote Read, Start the chip, clear reset */
331 1 for(loop=0;loop < Count;loop++){
332 2 ethernet_8390_hdr[loop] = EN_DATA;
333 2 }
334 1 EN0_ISR = ENISR_RDC; /* Ack intr. to Remote DMA */
335 1 }
336
337 void ei_rx_overrun( void )
338 {
339 1 byte was_txing, must_resend = 0;
340 1
341 1 //print_int("OVER");
342 1 /* Record whether a Tx was in progress
343 1 and then issue the stop command. */
344 1
345 1 was_txing = EN_CMD & EN_TRANS;
346 1 EN_CMD = EN_NODMA + EN_PAGE0 + EN_STOP;
347 1
348 1 delay_1ms(2); /* I don't know exactly time yet.. at least 2ms */
349 1
350 1 /** Reset RBCR[01] back to zero as per magic incantation. */
351 1 EN0_RCNTLO = 0x00;
352 1 EN0_RCNTHI = 0x00;
353 1
354 1 /* See if any Tx was interrupted or not. According to NS, this
355 1 step is vital, and skipping it will cause no end of havoc. */
356 1 if (was_txing) {
357 2 if (!(EN0_ISR & (ENISR_TX + ENISR_TX_ERR))) must_resend = 1;
358 2 }
359 1
360 1 /* Have to enter loopback mode and then restart the NIC before
361 1 you are allowed to slurp packets up off the ring. */
362 1 EN0_TXCR = E8390_TXOFF;
C51 COMPILER V7.07 DRV_8019 04/20/2004 18:04:40 PAGE 7
363 1 EN_CMD = EN_NODMA + EN_PAGE0 + EN_START;
364 1
365 1 /* Clear the Rx ring of all the debris(颇祈), and ack the interrupt. */
366 1 ei_receive();
367 1 EN0_ISR = ENISR_OVER;
368 1
369 1 /* Leave loopback mode, and resend any packet that got stopped. */
370 1 EN0_TXCR = E8390_TXCONFIG;
371 1 if (must_resend) EN_CMD = EN_NODMA + EN_PAGE0 + EN_START + EN_TRANS;
372 1
373 1 }
374
375 void ethernet_register_test(void) /* All Register test */
376 {
377 1 byte i,read,write;
378 1
379 1 print("\n\r------------------------------------------------------------------------");
380 1 print("\n\rAddr Page0 Page1 Page2 Page3");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -