2 * Copyright (c) 2009 Lukas Mejdrech
3 * Copyright (c) 2011 Martin Decky
4 * Copyright (c) 2011 Radim Vansa
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * - The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * This code is based upon the NE2000 driver for MINIX,
33 * distributed according to a BSD-style license.
35 * Copyright (c) 1987, 1997, 2006 Vrije Universiteit
36 * Copyright (c) 1992, 1994 Philip Homburg
37 * Copyright (c) 1996 G. Falzoni
42 * @addtogroup drv_ne2k
48 * @brief NE2000 driver core
50 * NE2000 (based on DP8390) network interface core implementation.
51 * Only the basic NE2000 PIO (ISA) interface is supported, remote
52 * DMA is completely absent from this code for simplicity.
57 #include <byteorder.h>
67 /** 6 * DP_PAGE >= 1514 bytes */
70 /** Type definition of the receive header
77 /** Pointer to next frame */
80 /** Receive Byte Count Low */
83 /** Receive Byte Count High */
87 /** Read a memory block word by word.
89 * @param[in] port Source address.
90 * @param[out] buf Destination buffer.
91 * @param[in] size Memory block size in bytes.
94 static void pio_read_buf_16(void *port
, void *buf
, size_t size
)
98 for (i
= 0; (i
<< 1) < size
; i
++)
99 *((uint16_t *) buf
+ i
) = pio_read_16((ioport16_t
*) (port
));
102 /** Write a memory block word by word.
104 * @param[in] port Destination address.
105 * @param[in] buf Source buffer.
106 * @param[in] size Memory block size in bytes.
109 static void pio_write_buf_16(void *port
, void *buf
, size_t size
)
113 for (i
= 0; (i
<< 1) < size
; i
++)
114 pio_write_16((ioport16_t
*) port
, *((uint16_t *) buf
+ i
));
117 static void ne2k_download(ne2k_t
*ne2k
, void *buf
, size_t addr
, size_t size
)
119 size_t esize
= size
& ~1;
121 pio_write_8(ne2k
->port
+ DP_RBCR0
, esize
& 0xff);
122 pio_write_8(ne2k
->port
+ DP_RBCR1
, (esize
>> 8) & 0xff);
123 pio_write_8(ne2k
->port
+ DP_RSAR0
, addr
& 0xff);
124 pio_write_8(ne2k
->port
+ DP_RSAR1
, (addr
>> 8) & 0xff);
125 pio_write_8(ne2k
->port
+ DP_CR
, CR_DM_RR
| CR_PS_P0
| CR_STA
);
128 pio_read_buf_16(ne2k
->data_port
, buf
, esize
);
136 uint16_t word
= pio_read_16(ne2k
->data_port
);
137 memcpy(buf
, &word
, 1);
141 static void ne2k_upload(ne2k_t
*ne2k
, void *buf
, size_t addr
, size_t size
)
143 size_t esize_ru
= (size
+ 1) & ~1;
144 size_t esize
= size
& ~1;
146 pio_write_8(ne2k
->port
+ DP_RBCR0
, esize_ru
& 0xff);
147 pio_write_8(ne2k
->port
+ DP_RBCR1
, (esize_ru
>> 8) & 0xff);
148 pio_write_8(ne2k
->port
+ DP_RSAR0
, addr
& 0xff);
149 pio_write_8(ne2k
->port
+ DP_RSAR1
, (addr
>> 8) & 0xff);
150 pio_write_8(ne2k
->port
+ DP_CR
, CR_DM_RW
| CR_PS_P0
| CR_STA
);
153 pio_write_buf_16(ne2k
->data_port
, buf
, esize
);
163 memcpy(&word
, buf
, 1);
164 pio_write_16(ne2k
->data_port
, word
);
168 static void ne2k_init(ne2k_t
*ne2k
)
172 /* Reset the ethernet card */
173 uint8_t val
= pio_read_8(ne2k
->port
+ NE2K_RESET
);
175 pio_write_8(ne2k
->port
+ NE2K_RESET
, val
);
178 /* Reset the DP8390 */
179 pio_write_8(ne2k
->port
+ DP_CR
, CR_STP
| CR_DM_ABORT
);
180 for (i
= 0; i
< NE2K_RETRY
; i
++) {
181 if (pio_read_8(ne2k
->port
+ DP_ISR
) != 0)
186 /** Probe and initialize the network interface.
188 * @param[in,out] ne2k Network interface structure.
189 * @param[in] port Device address.
190 * @param[in] irq Device interrupt vector.
192 * @return EOK on success.
193 * @return EXDEV if the network interface was not recognized.
196 int ne2k_probe(ne2k_t
*ne2k
)
202 /* Check if the DP8390 is really there */
203 uint8_t val
= pio_read_8(ne2k
->port
+ DP_CR
);
204 if ((val
& (CR_STP
| CR_TXP
| CR_DM_ABORT
)) != (CR_STP
| CR_DM_ABORT
))
207 /* Disable the receiver and init TCR and DCR */
208 pio_write_8(ne2k
->port
+ DP_RCR
, RCR_MON
);
209 pio_write_8(ne2k
->port
+ DP_TCR
, TCR_NORMAL
);
210 pio_write_8(ne2k
->port
+ DP_DCR
, DCR_WORDWIDE
| DCR_8BYTES
| DCR_BMS
);
212 /* Setup a transfer to get the MAC address */
213 pio_write_8(ne2k
->port
+ DP_RBCR0
, ETH_ADDR
<< 1);
214 pio_write_8(ne2k
->port
+ DP_RBCR1
, 0);
215 pio_write_8(ne2k
->port
+ DP_RSAR0
, 0);
216 pio_write_8(ne2k
->port
+ DP_RSAR1
, 0);
217 pio_write_8(ne2k
->port
+ DP_CR
, CR_DM_RR
| CR_PS_P0
| CR_STA
);
219 for (i
= 0; i
< ETH_ADDR
; i
++)
220 ne2k
->mac
.address
[i
] = pio_read_16(ne2k
->data_port
);
225 void ne2k_set_physical_address(ne2k_t
*ne2k
, const nic_address_t
*address
)
227 memcpy(&ne2k
->mac
, address
, sizeof(nic_address_t
));
229 pio_write_8(ne2k
->port
+ DP_CR
, CR_PS_P0
| CR_DM_ABORT
| CR_STP
);
231 pio_write_8(ne2k
->port
+ DP_RBCR0
, ETH_ADDR
<< 1);
232 pio_write_8(ne2k
->port
+ DP_RBCR1
, 0);
233 pio_write_8(ne2k
->port
+ DP_RSAR0
, 0);
234 pio_write_8(ne2k
->port
+ DP_RSAR1
, 0);
235 pio_write_8(ne2k
->port
+ DP_CR
, CR_DM_RW
| CR_PS_P0
| CR_STA
);
238 for (i
= 0; i
< ETH_ADDR
; i
++)
239 pio_write_16(ne2k
->data_port
, ne2k
->mac
.address
[i
]);
241 //pio_write_8(ne2k->port + DP_CR, CR_PS_P0 | CR_DM_ABORT | CR_STA);
244 /** Start the network interface.
246 * @param[in,out] ne2k Network interface structure.
248 * @return EOK on success.
249 * @return EXDEV if the network interface is disabled.
252 int ne2k_up(ne2k_t
*ne2k
)
260 * Setup send queue. Use the first
261 * SQ_PAGES of NE2000 memory for the send
264 ne2k
->sq
.dirty
= false;
265 ne2k
->sq
.page
= NE2K_START
/ DP_PAGE
;
266 fibril_mutex_initialize(&ne2k
->sq_mutex
);
267 fibril_condvar_initialize(&ne2k
->sq_cv
);
270 * Setup receive ring buffer. Use all the rest
271 * of the NE2000 memory (except the first SQ_PAGES
272 * reserved for the send buffer) for the receive
275 ne2k
->start_page
= ne2k
->sq
.page
+ SQ_PAGES
;
276 ne2k
->stop_page
= ne2k
->sq
.page
+ NE2K_SIZE
/ DP_PAGE
;
279 * Initialization of the DP8390 following the mandatory procedure
280 * in reference manual ("DP8390D/NS32490D NIC Network Interface
281 * Controller", National Semiconductor, July 1995, Page 29).
285 pio_write_8(ne2k
->port
+ DP_CR
, CR_PS_P0
| CR_STP
| CR_DM_ABORT
);
288 pio_write_8(ne2k
->port
+ DP_DCR
, DCR_WORDWIDE
| DCR_8BYTES
| DCR_BMS
);
291 pio_write_8(ne2k
->port
+ DP_RBCR0
, 0);
292 pio_write_8(ne2k
->port
+ DP_RBCR1
, 0);
295 pio_write_8(ne2k
->port
+ DP_RCR
, ne2k
->receive_configuration
);
298 pio_write_8(ne2k
->port
+ DP_TCR
, TCR_INTERNAL
);
301 pio_write_8(ne2k
->port
+ DP_BNRY
, ne2k
->start_page
);
302 pio_write_8(ne2k
->port
+ DP_PSTART
, ne2k
->start_page
);
303 pio_write_8(ne2k
->port
+ DP_PSTOP
, ne2k
->stop_page
);
306 pio_write_8(ne2k
->port
+ DP_ISR
, 0xff);
309 pio_write_8(ne2k
->port
+ DP_IMR
,
310 IMR_PRXE
| IMR_PTXE
| IMR_RXEE
| IMR_TXEE
| IMR_OVWE
| IMR_CNTE
);
313 pio_write_8(ne2k
->port
+ DP_CR
, CR_PS_P1
| CR_DM_ABORT
| CR_STP
);
315 pio_write_8(ne2k
->port
+ DP_PAR0
, ne2k
->mac
.address
[0]);
316 pio_write_8(ne2k
->port
+ DP_PAR1
, ne2k
->mac
.address
[1]);
317 pio_write_8(ne2k
->port
+ DP_PAR2
, ne2k
->mac
.address
[2]);
318 pio_write_8(ne2k
->port
+ DP_PAR3
, ne2k
->mac
.address
[3]);
319 pio_write_8(ne2k
->port
+ DP_PAR4
, ne2k
->mac
.address
[4]);
320 pio_write_8(ne2k
->port
+ DP_PAR5
, ne2k
->mac
.address
[5]);
322 pio_write_8(ne2k
->port
+ DP_MAR0
, 0);
323 pio_write_8(ne2k
->port
+ DP_MAR1
, 0);
324 pio_write_8(ne2k
->port
+ DP_MAR2
, 0);
325 pio_write_8(ne2k
->port
+ DP_MAR3
, 0);
326 pio_write_8(ne2k
->port
+ DP_MAR4
, 0);
327 pio_write_8(ne2k
->port
+ DP_MAR5
, 0);
328 pio_write_8(ne2k
->port
+ DP_MAR6
, 0);
329 pio_write_8(ne2k
->port
+ DP_MAR7
, 0);
331 pio_write_8(ne2k
->port
+ DP_CURR
, ne2k
->start_page
+ 1);
334 pio_write_8(ne2k
->port
+ DP_CR
, CR_PS_P0
| CR_DM_ABORT
| CR_STA
);
337 pio_write_8(ne2k
->port
+ DP_TCR
, TCR_NORMAL
);
339 /* Reset counters by reading */
340 pio_read_8(ne2k
->port
+ DP_CNTR0
);
341 pio_read_8(ne2k
->port
+ DP_CNTR1
);
342 pio_read_8(ne2k
->port
+ DP_CNTR2
);
344 /* Finish the initialization */
349 /** Stop the network interface.
351 * @param[in,out] ne2k Network interface structure.
354 void ne2k_down(ne2k_t
*ne2k
)
356 if ((ne2k
->probed
) && (ne2k
->up
)) {
357 pio_write_8(ne2k
->port
+ DP_CR
, CR_STP
| CR_DM_ABORT
);
363 static void ne2k_reset(ne2k_t
*ne2k
)
367 fibril_mutex_lock(&ne2k
->sq_mutex
);
370 pio_write_8(ne2k
->port
+ DP_CR
, CR_STP
| CR_DM_ABORT
);
371 pio_write_8(ne2k
->port
+ DP_RBCR0
, 0);
372 pio_write_8(ne2k
->port
+ DP_RBCR1
, 0);
374 for (i
= 0; i
< NE2K_RETRY
; i
++) {
375 if ((pio_read_8(ne2k
->port
+ DP_ISR
) & ISR_RST
) != 0)
379 pio_write_8(ne2k
->port
+ DP_TCR
, TCR_1EXTERNAL
| TCR_OFST
);
380 pio_write_8(ne2k
->port
+ DP_CR
, CR_STA
| CR_DM_ABORT
);
381 pio_write_8(ne2k
->port
+ DP_TCR
, TCR_NORMAL
);
383 /* Acknowledge the ISR_RDC (remote DMA) interrupt */
384 for (i
= 0; i
< NE2K_RETRY
; i
++) {
385 if ((pio_read_8(ne2k
->port
+ DP_ISR
) & ISR_RDC
) != 0)
389 uint8_t val
= pio_read_8(ne2k
->port
+ DP_ISR
);
390 pio_write_8(ne2k
->port
+ DP_ISR
, val
& ~ISR_RDC
);
393 * Reset the transmit ring. If we were transmitting a frame,
394 * we pretend that the frame is processed. Higher layers will
395 * retransmit if the frame wasn't actually sent.
397 ne2k
->sq
.dirty
= false;
399 fibril_mutex_unlock(&ne2k
->sq_mutex
);
404 * @param[in,out] ne2k Network interface structure.
405 * @param[in] data Pointer to frame data
406 * @param[in] size Frame size in bytes
409 void ne2k_send(nic_t
*nic_data
, void *data
, size_t size
)
411 ne2k_t
*ne2k
= (ne2k_t
*) nic_get_specific(nic_data
);
413 assert(ne2k
->probed
);
416 fibril_mutex_lock(&ne2k
->sq_mutex
);
418 while (ne2k
->sq
.dirty
) {
419 fibril_condvar_wait(&ne2k
->sq_cv
, &ne2k
->sq_mutex
);
422 if ((size
< ETH_MIN_PACK_SIZE
) || (size
> ETH_MAX_PACK_SIZE_TAGGED
)) {
423 fibril_mutex_unlock(&ne2k
->sq_mutex
);
427 /* Upload the frame to the ethernet card */
428 ne2k_upload(ne2k
, data
, ne2k
->sq
.page
* DP_PAGE
, size
);
429 ne2k
->sq
.dirty
= true;
430 ne2k
->sq
.size
= size
;
432 /* Initialize the transfer */
433 pio_write_8(ne2k
->port
+ DP_TPSR
, ne2k
->sq
.page
);
434 pio_write_8(ne2k
->port
+ DP_TBCR0
, size
& 0xff);
435 pio_write_8(ne2k
->port
+ DP_TBCR1
, (size
>> 8) & 0xff);
436 pio_write_8(ne2k
->port
+ DP_CR
, CR_TXP
| CR_STA
);
437 fibril_mutex_unlock(&ne2k
->sq_mutex
);
440 static nic_frame_t
*ne2k_receive_frame(nic_t
*nic_data
, uint8_t page
,
443 ne2k_t
*ne2k
= (ne2k_t
*) nic_get_specific(nic_data
);
445 nic_frame_t
*frame
= nic_alloc_frame(nic_data
, length
);
449 memset(frame
->data
, 0, length
);
450 uint8_t last
= page
+ length
/ DP_PAGE
;
452 if (last
>= ne2k
->stop_page
) {
453 size_t left
= (ne2k
->stop_page
- page
) * DP_PAGE
454 - sizeof(recv_header_t
);
455 ne2k_download(ne2k
, frame
->data
, page
* DP_PAGE
+ sizeof(recv_header_t
),
457 ne2k_download(ne2k
, frame
->data
+ left
, ne2k
->start_page
* DP_PAGE
,
460 ne2k_download(ne2k
, frame
->data
, page
* DP_PAGE
+ sizeof(recv_header_t
),
466 static void ne2k_receive(nic_t
*nic_data
)
468 ne2k_t
*ne2k
= (ne2k_t
*) nic_get_specific(nic_data
);
470 * Allocate memory for the list of received frames.
471 * If the allocation fails here we still receive the
472 * frames from the network, but they will be lost.
474 nic_frame_list_t
*frames
= nic_alloc_frame_list();
475 size_t frames_count
= 0;
477 /* We may block sending in this loop - after so many received frames there
478 * must be some interrupt pending (for the frames not yet downloaded) and
479 * we will continue in its handler. */
480 while (frames_count
< 16) {
481 //TODO: isn't some locking necessary here?
482 uint8_t boundary
= pio_read_8(ne2k
->port
+ DP_BNRY
) + 1;
484 if (boundary
== ne2k
->stop_page
)
485 boundary
= ne2k
->start_page
;
487 pio_write_8(ne2k
->port
+ DP_CR
, CR_PS_P1
| CR_STA
);
488 uint8_t current
= pio_read_8(ne2k
->port
+ DP_CURR
);
489 pio_write_8(ne2k
->port
+ DP_CR
, CR_PS_P0
| CR_STA
);
490 if (current
== boundary
)
491 /* No more frames to process */
494 recv_header_t header
;
495 size_t size
= sizeof(header
);
496 size_t offset
= boundary
* DP_PAGE
;
498 /* Get the frame header */
499 pio_write_8(ne2k
->port
+ DP_RBCR0
, size
& 0xff);
500 pio_write_8(ne2k
->port
+ DP_RBCR1
, (size
>> 8) & 0xff);
501 pio_write_8(ne2k
->port
+ DP_RSAR0
, offset
& 0xff);
502 pio_write_8(ne2k
->port
+ DP_RSAR1
, (offset
>> 8) & 0xff);
503 pio_write_8(ne2k
->port
+ DP_CR
, CR_DM_RR
| CR_PS_P0
| CR_STA
);
505 pio_read_buf_16(ne2k
->data_port
, (void *) &header
, size
);
508 (((size_t) header
.rbcl
) | (((size_t) header
.rbch
) << 8)) - size
;
509 uint8_t next
= header
.next
;
511 if ((length
< ETH_MIN_PACK_SIZE
)
512 || (length
> ETH_MAX_PACK_SIZE_TAGGED
)) {
514 } else if ((header
.next
< ne2k
->start_page
)
515 || (header
.next
> ne2k
->stop_page
)) {
517 } else if (header
.status
& RSR_FO
) {
519 * This is very serious, so we issue a warning and
524 } else if ((header
.status
& RSR_PRX
) && (ne2k
->up
)) {
525 if (frames
!= NULL
) {
527 ne2k_receive_frame(nic_data
, boundary
, length
);
529 nic_frame_list_append(frames
, frame
);
539 * Update the boundary pointer
540 * to the value of the page
541 * prior to the next frame to
544 if (next
== ne2k
->start_page
)
545 next
= ne2k
->stop_page
- 1;
548 pio_write_8(ne2k
->port
+ DP_BNRY
, next
);
550 nic_received_frame_list(nic_data
, frames
);
553 void ne2k_interrupt(nic_t
*nic_data
, uint8_t isr
, uint8_t tsr
)
555 ne2k_t
*ne2k
= (ne2k_t
*) nic_get_specific(nic_data
);
557 if (isr
& (ISR_PTX
| ISR_TXE
)) {
559 nic_report_collisions(nic_data
,
560 pio_read_8(ne2k
->port
+ DP_NCR
) & 15);
564 // TODO: fix number of sent bytes (but how?)
565 nic_report_send_ok(nic_data
, 1, 0);
566 } else if (tsr
& TSR_ABT
) {
567 nic_report_send_error(nic_data
, NIC_SEC_ABORTED
, 1);
568 } else if (tsr
& TSR_CRS
) {
569 nic_report_send_error(nic_data
, NIC_SEC_CARRIER_LOST
, 1);
570 } else if (tsr
& TSR_FU
) {
572 // if (ne2k->underruns < NE2K_ERL) {
574 } else if (tsr
& TSR_CDH
) {
575 nic_report_send_error(nic_data
, NIC_SEC_HEARTBEAT
, 1);
576 // if (nic_data->stats.send_heartbeat_errors < NE2K_ERL) {
578 } else if (tsr
& TSR_OWC
) {
579 nic_report_send_error(nic_data
, NIC_SEC_WINDOW_ERROR
, 1);
582 fibril_mutex_lock(&ne2k
->sq_mutex
);
583 if (ne2k
->sq
.dirty
) {
584 /* Prepare the buffer for next frame */
585 ne2k
->sq
.dirty
= false;
588 /* Signal a next frame to be sent */
589 fibril_condvar_broadcast(&ne2k
->sq_cv
);
592 // if (ne2k->misses < NE2K_ERL) {
595 fibril_mutex_unlock(&ne2k
->sq_mutex
);
600 for (errors
= pio_read_8(ne2k
->port
+ DP_CNTR0
); errors
> 0; --errors
)
601 nic_report_receive_error(nic_data
, NIC_REC_CRC
, 1);
602 for (errors
= pio_read_8(ne2k
->port
+ DP_CNTR1
); errors
> 0; --errors
)
603 nic_report_receive_error(nic_data
, NIC_REC_FRAME_ALIGNMENT
, 1);
604 for (errors
= pio_read_8(ne2k
->port
+ DP_CNTR2
); errors
> 0; --errors
)
605 nic_report_receive_error(nic_data
, NIC_REC_MISSED
, 1);
608 ne2k_receive(nic_data
);
612 * The chip is stopped, and all arrived
613 * frames are delivered.
618 /* Unmask interrupts to be processed in the next round */
619 pio_write_8(ne2k
->port
+ DP_IMR
,
620 IMR_PRXE
| IMR_PTXE
| IMR_RXEE
| IMR_TXEE
| IMR_OVWE
| IMR_CNTE
);
623 void ne2k_set_accept_bcast(ne2k_t
*ne2k
, int accept
)
626 ne2k
->receive_configuration
|= RCR_AB
;
628 ne2k
->receive_configuration
&= ~RCR_AB
;
630 pio_write_8(ne2k
->port
+ DP_RCR
, ne2k
->receive_configuration
);
633 void ne2k_set_accept_mcast(ne2k_t
*ne2k
, int accept
)
636 ne2k
->receive_configuration
|= RCR_AM
;
638 ne2k
->receive_configuration
&= ~RCR_AM
;
640 pio_write_8(ne2k
->port
+ DP_RCR
, ne2k
->receive_configuration
);
643 void ne2k_set_promisc_phys(ne2k_t
*ne2k
, int promisc
)
646 ne2k
->receive_configuration
|= RCR_PRO
;
648 ne2k
->receive_configuration
&= ~RCR_PRO
;
650 pio_write_8(ne2k
->port
+ DP_RCR
, ne2k
->receive_configuration
);
653 void ne2k_set_mcast_hash(ne2k_t
*ne2k
, uint64_t hash
)
655 /* Select Page 1 and stop all transfers */
656 pio_write_8(ne2k
->port
+ DP_CR
, CR_PS_P1
| CR_DM_ABORT
| CR_STP
);
658 pio_write_8(ne2k
->port
+ DP_MAR0
, (uint8_t) hash
);
659 pio_write_8(ne2k
->port
+ DP_MAR1
, (uint8_t) (hash
>> 8));
660 pio_write_8(ne2k
->port
+ DP_MAR2
, (uint8_t) (hash
>> 16));
661 pio_write_8(ne2k
->port
+ DP_MAR3
, (uint8_t) (hash
>> 24));
662 pio_write_8(ne2k
->port
+ DP_MAR4
, (uint8_t) (hash
>> 32));
663 pio_write_8(ne2k
->port
+ DP_MAR5
, (uint8_t) (hash
>> 40));
664 pio_write_8(ne2k
->port
+ DP_MAR6
, (uint8_t) (hash
>> 48));
665 pio_write_8(ne2k
->port
+ DP_MAR7
, (uint8_t) (hash
>> 56));
667 /* Select Page 0 and resume transfers */
668 pio_write_8(ne2k
->port
+ DP_CR
, CR_PS_P0
| CR_DM_ABORT
| CR_STA
);