]>
git.saurik.com Git - apple/xnu.git/blob - bsd/if/ppc/if_en.c
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 * Copyright (c) 1997 Apple Computer, Inc.
28 * ethernet driver for mace on-board ethernet
32 * Dieter Siegmund (dieter@next.com) Thu Feb 27 18:25:33 PST 1997
33 * - ripped off code from MK/LINUX, turned it into a polled-mode
34 * driver for the PCI (8500) class machines
36 * Dieter Siegmund (dieter@next.com) Fri Mar 21 12:41:29 PST 1997
37 * - reworked to support a BSD-style interface, and to support kdb polled
38 * interface and interrupt-driven interface concurrently
40 * Justin Walker (justin@apple.com) Tue May 20 10:29:29 PDT 1997
41 * - Added multicast support
43 * Dieter Siegmund (dieter@next.com) Thu May 29 15:02:29 PDT 1997
44 * - fixed problem with sending arp packets for ip address 0.0.0.0
45 * - use kdp_register_send_receive() instead of defining
46 * en_send_pkt/en_recv_pkt routines to avoid name space
47 * collisions with IOEthernetDebugger and allow these routines to be
48 * overridden by a driverkit-style driver
50 * Dieter Siegmund (dieter@apple.com) Tue Jun 24 18:29:15 PDT 1997
51 * - don't let the adapter auto-strip 802.3 receive frames, it messes
52 * up the frame size logic
54 * Dieter Siegmund (dieter@apple.com) Tue Aug 5 16:24:52 PDT 1997
55 * - handle multicast address deletion correctly
59 * Caveat: MACE_DEBUG delimits some code that is getting kind of
60 * stale. Before blindly turning on MACE_DEBUG for your
61 * testing, take a look at the code enabled by it to check
62 * that it is reasonably sane.
66 #include <machdep/ppc/dbdma.h>
67 #include <kern/kdp_en_debugger.h>
69 #define RECEIVE_INT DBDMA_INT_ALWAYS
71 #include <sys/types.h>
72 #include <sys/systm.h>
73 #include <sys/param.h>
74 #include <sys/errno.h>
75 #include <sys/socket.h>
77 #include <net/etherdefs.h>
78 #include <netinet/if_ether.h>
79 #include <sys/sockio.h>
80 #include <netinet/in_var.h>
81 #include <netinet/in.h>
83 #include <mach/mach_types.h>
84 #include <ppc/powermac.h>
85 #include <ppc/interrupts.h>
86 #include <ppc/proc_reg.h>
87 #include <libkern/libkern.h>
88 #include <kern/thread_call.h>
98 static void polled_send_pkt(char * data
, int len
);
99 static void polled_receive_pkt(char *data
, int *len
, int timeout_ms
);
100 void mace_dbdma_rx_intr(int unit
, void *, void *);
101 void mace_dbdma_tx_intr(int, void *, void *);
102 void mace_pci_intr(int, void *);
103 void mace_service_queue(struct ifnet
* ifp
);
106 static int mace_watchdog();
109 static __inline__ vm_offset_t
110 KVTOPHYS(vm_offset_t v
)
115 typedef int (*funcptr
)(char *, int, void *);
119 macAddrsEqual(unsigned char * one
, unsigned char * two
)
123 for (i
= 0; i
< NUM_EN_ADDR_BYTES
; i
++)
124 if (*one
++ != *two
++)
130 static __inline__
int
131 isprint(unsigned char c
)
133 return (c
>= 0x20 && c
<= 0x7e);
137 printEtherHeader(enet_addr_t
* dh
, enet_addr_t
* sh
, u_short etype
)
139 u_char
* dhost
= dh
->ether_addr_octet
;
140 u_char
* shost
= sh
->ether_addr_octet
;
142 printf("Dst: %x:%x:%x:%x:%x:%x Src: %x:%x:%x:%x:%x:%x Type: 0x%x\n",
143 dhost
[0], dhost
[1], dhost
[2], dhost
[3], dhost
[4], dhost
[5],
144 shost
[0], shost
[1], shost
[2], shost
[3], shost
[4], shost
[5],
149 printData(u_char
* data_p
, int n_bytes
)
151 #define CHARS_PER_LINE 16
152 char line_buf
[CHARS_PER_LINE
+ 1];
156 for (line_pos
= 0, offset
= 0; offset
< n_bytes
; offset
++, data_p
++) {
158 printf("%04d ", offset
);
161 line_buf
[line_pos
] = isprint(*data_p
) ? *data_p
: '.';
162 printf(" %02x", *data_p
);
164 if (line_pos
== CHARS_PER_LINE
) {
165 line_buf
[CHARS_PER_LINE
] = '\0';
166 printf(" %s\n", line_buf
);
170 if (line_pos
) { /* need to finish up the line */
171 for (; line_pos
< CHARS_PER_LINE
; line_pos
++) {
173 line_buf
[line_pos
] = ' ';
175 line_buf
[CHARS_PER_LINE
] = '\0';
176 printf(" %s\n", line_buf
);
181 printEtherPacket(enet_addr_t
* dhost
, enet_addr_t
* shost
, u_short type
,
182 u_char
* data_p
, int n_bytes
)
184 printEtherHeader(dhost
, shost
, type
);
185 printData(data_p
, n_bytes
);
189 printContiguousEtherPacket(u_char
* data_p
, int n_bytes
)
191 printEtherPacket((enet_addr_t
*)data_p
,
192 (enet_addr_t
*)(data_p
+ NUM_EN_ADDR_BYTES
),
193 *((u_short
*)(data_p
+ (NUM_EN_ADDR_BYTES
* 2))),
199 #define MACE_DMA_AREA_SIZE (ETHER_RX_NUM_DBDMA_BUFS * ETHERNET_BUF_SIZE + PG_SIZE)
200 static unsigned long mace_rx_dma_area
[(MACE_DMA_AREA_SIZE
+ sizeof(long))/sizeof(long)];
202 static unsigned long mace_tx_dma_area
[(ETHERNET_BUF_SIZE
+ PG_SIZE
+ sizeof(long))/sizeof(long)];
207 * This function computes the Ethernet Hardware address
208 * from PROM. (Its best not to ask how this is done.)
212 mace_swapbits(unsigned char bits
)
214 unsigned char mask
= 0x1, i
, newbits
= 0;
216 for (i
= 0x80; i
; mask
<<= 1, i
>>=1) {
225 mace_get_hwid(unsigned char *hwid_addr
, mace_t
* m
)
229 for (i
= 0; i
< NUM_EN_ADDR_BYTES
; i
++, hwid_addr
+= 16) {
230 m
->macaddr
[i
] = mace_swapbits(*hwid_addr
);
243 dbdma_reset(DBDMA_ETHERNET_RV
);
244 dbdma_reset(DBDMA_ETHERNET_TX
);
251 * This function gets the ethernet address (array of 6 unsigned
252 * bytes) from the MACE board registers.
260 unsigned char ep_temp
;
262 mace
.ereg
->iac
= IAC_PHYADDR
; eieio();
264 for (i
= 0; i
< ETHER_ADD_SIZE
; i
++) {
265 ep_temp
= mace
.ereg
->padr
; eieio();
273 * This function sets the ethernet address (array of 6 unsigned
274 * bytes) on the MACE board.
281 unsigned char status
;
283 if (mace
.chip_id
!= MACE_REVISION_A2
) {
284 mace
.ereg
->iac
= IAC_ADDRCHG
|IAC_PHYADDR
; eieio();
286 while ((status
= mace
.ereg
->iac
)) {
287 if ((status
& IAC_ADDRCHG
) == 0) {
295 /* start to load the address.. */
296 mace
.ereg
->iac
= IAC_PHYADDR
; eieio();
299 for (i
= 0; i
< NUM_EN_ADDR_BYTES
; i
++) {
300 mace
.ereg
->padr
= *(ep
+i
); eieio();
308 * Setup various dbdma pointers.
318 dbdma_regmap_t
* regmap
;
320 #define ALIGN_MASK 0xfffffffcUL
321 if (m
->rv_dma_area
== 0) {
322 m
->rv_dma_area
= (unsigned char *)
323 ((((unsigned long)mace_rx_dma_area
) + 3) & ALIGN_MASK
);
324 m
->rv_dma
= dbdma_alloc(ETHER_RX_NUM_DBDMA_BUFS
+ 2);
325 m
->tx_dma
= dbdma_alloc(TX_NUM_DBDMA
);
326 m
->tx_dma_area
= (unsigned char *)
327 ((((unsigned long)mace_tx_dma_area
) + 3) & ALIGN_MASK
);
330 /* set up a ring of buffers */
332 for (i
= 0; i
< ETHER_RX_NUM_DBDMA_BUFS
; i
++, d
++) {
333 address
= (vm_offset_t
) KVTOPHYS((vm_offset_t
)&m
->rv_dma_area
[i
*ETHERNET_BUF_SIZE
]);
334 DBDMA_BUILD(d
, DBDMA_CMD_IN_LAST
, 0, ETHERNET_BUF_SIZE
,
335 address
, RECEIVE_INT
,
340 /* stop when we hit the end of the list */
341 DBDMA_BUILD(d
, DBDMA_CMD_STOP
, 0, 0, 0, RECEIVE_INT
,
342 DBDMA_WAIT_NEVER
, DBDMA_BRANCH_NEVER
);
345 /* branch to command at "address" ie. element 0 of the "array" */
346 DBDMA_BUILD(d
, DBDMA_CMD_NOP
, 0, 0, 0, DBDMA_INT_NEVER
,
347 DBDMA_WAIT_NEVER
, DBDMA_BRANCH_ALWAYS
);
348 address
= (vm_offset_t
) KVTOPHYS((vm_offset_t
)m
->rv_dma
);
349 dbdma_st4_endian(&d
->d_cmddep
, address
);
352 m
->rv_tail
= ETHER_RX_NUM_DBDMA_BUFS
; /* always contains DBDMA_CMD_STOP */
354 /* stop/init/restart dma channel */
355 dbdma_reset(DBDMA_ETHERNET_RV
);
356 dbdma_reset(DBDMA_ETHERNET_TX
);
358 /* Set the wait value.. */
359 regmap
= DBDMA_REGMAP(DBDMA_ETHERNET_RV
);
360 dbdma_st4_endian(®map
->d_wait
, DBDMA_SET_CNTRL(0x00));
362 /* Set the tx wait value */
363 regmap
= DBDMA_REGMAP(DBDMA_ETHERNET_TX
);
364 dbdma_st4_endian(®map
->d_wait
, DBDMA_SET_CNTRL(0x20));
366 flush_cache_v((vm_offset_t
)m
->rv_dma
,
367 sizeof(dbdma_command_t
) * (ETHER_RX_NUM_DBDMA_BUFS
+ 2));
368 /* start receiving */
369 dbdma_start(DBDMA_ETHERNET_RV
, m
->rv_dma
);
373 static unsigned char testBuffer
[PG_SIZE
* 4];
374 static unsigned char testMsg
[] = "mace ethernet interface test";
381 bzero(testBuffer
, sizeof(testBuffer
));
385 /* send self-addressed packet */
386 bcopy(&mace
.macaddr
[0], tp
, NUM_EN_ADDR_BYTES
);
387 tp
+= NUM_EN_ADDR_BYTES
;
388 bcopy(&mace
.macaddr
[0], tp
, NUM_EN_ADDR_BYTES
);
389 tp
+= NUM_EN_ADDR_BYTES
;
392 bcopy(testMsg
, tp
, sizeof(testMsg
));
393 polled_send_pkt(testBuffer
, 80);
399 * Function: init_mace
402 * Called early on, initializes the adapter and readies it for
403 * kdb kernel debugging.
408 unsigned char status
;
410 struct mace_board
* ereg
;
414 * Only use in-kernel driver for early debugging (bootargs: kdp=1 or kdp=3)
416 if ( (kdp_flag
& 1) == 0 )
421 bzero(&mace
, sizeof(mace
));
423 /* get the ethernet registers' mapped address */
425 = (struct mace_board
*) POWERMAC_IO(PCI_ETHERNET_BASE_PHYS
);
426 mace_get_hwid((unsigned char *)POWERMAC_IO(PCI_ETHERNET_ADDR_PHYS
), m
);
428 /* Reset the board & AMIC.. */
431 /* grab the MACE chip rev */
432 m
->chip_id
= (ereg
->chipid2
<< 8 | ereg
->chipid1
);
434 /* don't auto-strip for 802.3 */
435 m
->ereg
->rcvfc
&= ~(RCVFC_ASTRPRCV
);
437 /* set the ethernet address */
438 mace_seteh(mace
.macaddr
);
440 unsigned char macaddr
[NUM_EN_ADDR_BYTES
];
442 printf("mace ethernet [%02x:%02x:%02x:%02x:%02x:%02x]\n",
443 macaddr
[0], macaddr
[1], macaddr
[2],
444 macaddr
[3], macaddr
[4], macaddr
[5]);
447 /* Now clear the Multicast filter */
448 if (m
->chip_id
!= MACE_REVISION_A2
) {
449 ereg
->iac
= IAC_ADDRCHG
|IAC_LOGADDR
; eieio();
451 while ((status
= ereg
->iac
)) {
452 if ((status
& IAC_ADDRCHG
) == 0)
459 ereg
->iac
= IAC_LOGADDR
; eieio();
464 for (i
=0; i
< 8; i
++)
470 /* register interrupt routines */
473 /* Start the chip... */
474 m
->ereg
->maccc
= MACCC_ENXMT
|MACCC_ENRCV
; eieio();
476 volatile char ch
= mace
.ereg
->ir
; eieio();
479 delay(500); /* paranoia */
480 mace
.ereg
->imr
= 0xfe; eieio();
482 /* register our debugger routines */
483 kdp_register_send_receive((kdp_send_t
)polled_send_pkt
,
484 (kdp_receive_t
)polled_receive_pkt
);
487 printf("Testing 1 2 3\n");
489 printf("Testing 1 2 3\n");
491 printf("Testing 1 2 3\n");
494 static unsigned char buf
[ETHERNET_BUF_SIZE
];
496 int nmpc
= mace
.ereg
->mpc
; eieio();
500 printf("mpc %d\n", mpc
);
502 polled_receive_pkt(buf
, &len
, 100);
504 printf("rx %d\n", len
);
505 printContiguousEtherPacket(buf
, len
);
517 volatile dbdma_regmap_t
* dmap
= DBDMA_REGMAP(DBDMA_ETHERNET_TX
);
518 volatile unsigned long status
;
519 volatile unsigned long intr
;
520 volatile unsigned long branch
;
521 volatile unsigned long wait
;
523 status
= dbdma_ld4_endian(&dmap
->d_status
); eieio();
524 intr
= dbdma_ld4_endian(&dmap
->d_intselect
); eieio();
525 branch
= dbdma_ld4_endian(&dmap
->d_branch
); eieio();
526 wait
= dbdma_ld4_endian(&dmap
->d_wait
); eieio();
527 printf("(%s s=0x%x i=0x%x b=0x%x w=0x%x)", msg
, status
, intr
, branch
,
534 tx_dbdma(char * data
, int len
)
541 page
= ((unsigned long) data
) & PG_MASK
;
542 if ((page
+ len
) <= PG_SIZE
) { /* one piece dma */
543 DBDMA_BUILD(d
, DBDMA_CMD_OUT_LAST
, DBDMA_KEY_STREAM0
,
545 (vm_offset_t
) KVTOPHYS((vm_offset_t
) data
),
547 DBDMA_WAIT_IF_FALSE
, DBDMA_BRANCH_NEVER
);
549 else { /* two piece dma */
550 count
= PG_SIZE
- page
;
551 DBDMA_BUILD(d
, DBDMA_CMD_OUT_MORE
, DBDMA_KEY_STREAM0
,
553 (vm_offset_t
)KVTOPHYS((vm_offset_t
) data
),
555 DBDMA_WAIT_NEVER
, DBDMA_BRANCH_NEVER
);
557 DBDMA_BUILD(d
, DBDMA_CMD_OUT_LAST
, DBDMA_KEY_STREAM0
,
558 len
- count
, (vm_offset_t
)
559 KVTOPHYS((vm_offset_t
)((unsigned char *)data
+ count
)),
561 DBDMA_WAIT_IF_FALSE
, DBDMA_BRANCH_NEVER
);
564 DBDMA_BUILD(d
, DBDMA_CMD_LOAD_QUAD
, DBDMA_KEY_SYSTEM
,
565 1, KVTOPHYS((vm_offset_t
) &mace
.ereg
->xmtfs
),DBDMA_INT_NEVER
,
566 DBDMA_WAIT_NEVER
, DBDMA_BRANCH_NEVER
);
568 DBDMA_BUILD(d
, DBDMA_CMD_LOAD_QUAD
, DBDMA_KEY_SYSTEM
,
569 1, KVTOPHYS((vm_offset_t
) &mace
.ereg
->ir
), DBDMA_INT_ALWAYS
,
570 DBDMA_WAIT_NEVER
, DBDMA_BRANCH_NEVER
);
572 DBDMA_BUILD(d
, DBDMA_CMD_STOP
, 0, 0, 0, 0, 0, 0);
573 flush_cache_v((vm_offset_t
)mace
.tx_dma
, sizeof(dbdma_command_t
) * TX_NUM_DBDMA
);
574 dbdma_start(DBDMA_ETHERNET_TX
, mace
.tx_dma
);
580 waitForDBDMADone(char * msg
)
583 /* wait for tx dma completion */
584 volatile dbdma_regmap_t
* dmap
= DBDMA_REGMAP(DBDMA_ETHERNET_TX
);
586 volatile unsigned long val
;
590 val
= dbdma_ld4_endian(&dmap
->d_status
); eieio();
593 } while ((i
< 100000) && (val
& DBDMA_CNTRL_ACTIVE
));
595 printf("mace(%s): tx_dbdma poll timed out 0x%x", msg
, val
);
600 mace_service_queue(struct ifnet
* ifp
)
602 unsigned char * buf_p
;
607 if (mace
.tx_busy
) { /* transmit in progress? */
611 IF_DEQUEUE(&(ifp
->if_snd
), m
);
616 len
= m
->m_pkthdr
.len
;
618 if (len
> ETHERMAXPACKET
) {
619 printf("mace_start: packet too big (%d), dropping\n", len
);
624 buf_p
= mace
.tx_dma_area
;
626 printf("mace: sending more than one mbuf\n");
628 for (mp
= m
; mp
; mp
= mp
->m_next
) {
631 bcopy(mtod(mp
, caddr_t
), buf_p
, min(mp
->m_len
, len
));
639 BPF_TAP(ifp
->if_bpf
, mace
.tx_dma_area
, m
->m_pkthdr
.len
);
643 printf("tx packet %d\n", m
->m_pkthdr
.len
);
644 printContiguousEtherPacket(mace
.tx_dma_area
, m
->m_pkthdr
.len
);
647 /* fill in the dbdma records and kick off the dma */
648 tx_dbdma(mace
.tx_dma_area
, m
->m_pkthdr
.len
);
657 struct ifnet
* ifp
= &mace
.en_arpcom
.ac_if
;
662 if (mace
.rxintr
== 0) {
663 printf("rx is hung up\n");
668 if (mace
.txintr
== 0 && ifp
->if_snd
.ifq_head
) {
670 dbdma_stop(DBDMA_ETHERNET_TX
);
672 mace_service_queue(ifp
);
676 timeout(mace_watchdog
, 0, 10*hz
); /* just in case we drop an interrupt */
679 #endif /* MACE_DEBUG */
682 mace_start(struct ifnet
* ifp
)
684 // int i = mace.tx_busy;
686 // printf("mace_start %s\n", mace.tx_busy ? "(txBusy)" : "");
687 mace_service_queue(ifp
);
689 // if (mace.tx_busy && !i)
690 // printf("(txStarted)\n");
695 mace_recv_pkt(funcptr pktfunc
, void * p
)
698 struct mace_board
* board
;
704 unsigned short status
;
710 /* remember where the tail was */
712 for (done
= 0; (done
== 0) && (m
->rv_head
!= tail
);) {
713 dbdma_command_t
* dmaHead
;
715 dmaHead
= &m
->rv_dma
[m
->rv_head
];
716 resid
= dbdma_ld4_endian(&dmaHead
->d_status_resid
);
717 status
= (resid
>> 16);
718 bytes
= resid
& 0xffff;
719 bytes
= ETHERNET_BUF_SIZE
- bytes
- 8; /* strip off FCS/CRC */
721 if ((status
& DBDMA_ETHERNET_EOP
) == 0) {
722 /* no packets are ready yet */
726 /* if the packet is good, pass it up */
727 if (bytes
>= (ETHER_MIN_PACKET
- 4)) {
729 dmaPacket
= &m
->rv_dma_area
[m
->rv_head
* ETHERNET_BUF_SIZE
];
730 done
= (*pktfunc
)(dmaPacket
, bytes
, p
);
732 /* mark the head as the new tail in the dma channel command list */
733 DBDMA_BUILD(dmaHead
, DBDMA_CMD_STOP
, 0, 0, 0, RECEIVE_INT
,
734 DBDMA_WAIT_NEVER
, DBDMA_BRANCH_NEVER
);
735 flush_cache_v((vm_offset_t
)dmaHead
, sizeof(*dmaHead
));
738 /* make the tail an available dma'able entry */
740 dbdma_command_t
* dmaTail
;
741 dmaTail
= &m
->rv_dma
[m
->rv_tail
];
742 address
= KVTOPHYS((vm_offset_t
)
743 &m
->rv_dma_area
[m
->rv_tail
*ETHERNET_BUF_SIZE
]);
744 // this command is live so write it carefully
745 DBDMA_ST4_ENDIAN(&dmaTail
->d_address
, address
);
746 dmaTail
->d_status_resid
= 0;
747 dmaTail
->d_cmddep
= 0;
749 DBDMA_ST4_ENDIAN(&dmaTail
->d_cmd_count
,
750 ((DBDMA_CMD_IN_LAST
) << 28) | ((0) << 24) |
751 ((RECEIVE_INT
) << 20) |
752 ((DBDMA_BRANCH_NEVER
) << 18) | ((DBDMA_WAIT_NEVER
) << 16) |
753 (ETHERNET_BUF_SIZE
));
755 flush_cache_v((vm_offset_t
)dmaTail
, sizeof(*dmaTail
));
757 /* head becomes the tail */
758 m
->rv_tail
= m
->rv_head
;
760 /* advance the head */
762 if (m
->rv_head
== (ETHER_RX_NUM_DBDMA_BUFS
+ 1))
767 dbdma_continue(DBDMA_ETHERNET_RV
);
772 /* kdb handle buffer routines */
779 kdb_copy(char * pktBuf
, int len
, void * p
)
781 struct kdbCopy
* cp
= (struct kdbCopy
*)p
;
783 bcopy(pktBuf
, cp
->data
, len
);
785 return (1); /* signal that we're done */
788 /* kdb debugger routines */
790 polled_send_pkt(char * data
, int len
)
792 waitForDBDMADone("mace: polled_send_pkt start");
794 waitForDBDMADone("mace: polled_send_pkt end");
799 polled_receive_pkt(char *data
, int *len
, int timeout_ms
)
808 while (mace_recv_pkt(kdb_copy
, (void *)&cp
) == 0) {
817 /* Bump to force ethernet data to be 4-byte aligned
818 * (since the ethernet header is 14 bytes, and the 802.3 header is
819 * 22 = 14+8 bytes). This assumes that m_data is word-aligned
822 #define ETHER_DATA_ALIGN 2
828 * Called from within mace_recv_pkt to deal with a packet of data.
829 * rxpkt() allocates an mbuf(+cluser) and passes it up to the stacks.
831 * 0 if the packet was copied to an mbuf, 1 otherwise
834 rxpkt(char * data
, int len
, void * p
)
836 struct ether_header
* eh_p
= (struct ether_header
*)data
;
837 struct ifnet
* ifp
= &mace
.en_arpcom
.ac_if
;
844 /* mcast, bcast -- we're interested in either */
845 interesting
= eh_p
->ether_dhost
[0] & 1;
849 * Check if there's a bpf filter listening on this interface.
850 * If so, hand off the raw packet to bpf_tap().
853 BPF_TAP(ifp
->if_bpf
, data
, len
);
856 * Keep the packet if it's a broadcast or has our
857 * physical ethernet address (or if we support
858 * multicast and it's one).
860 if ((interesting
== 0) && bcmp(eh_p
->ether_dhost
, mace
.macaddr
,
861 sizeof(eh_p
->ether_dhost
)) != 0) {
868 * We "know" a full-sized packet fits in one cluster. Set up the
869 * packet header, and if the length is sufficient, attempt to allocate
870 * a cluster. If that fails, fall back to the old way (m_devget()).
871 * Here, we take the simple approach of cluster vs. single mbuf.
873 MGETHDR(m
, M_DONTWAIT
, MT_DATA
);
876 printf("mget failed\n");
881 if (len
> (MHLEN
- ETHER_DATA_ALIGN
))
882 { MCLGET(m
, M_DONTWAIT
);
883 if (m
->m_flags
&M_EXT
) /* MCLGET succeeded */
884 { m
->m_data
+= ETHER_DATA_ALIGN
;
885 bcopy(data
, mtod(m
, caddr_t
), (unsigned)len
);
889 printf("no clusters\n");
892 m
= (struct mbuf
*)m_devget(data
, len
, 0, ifp
, 0);
897 { m
->m_data
+= ETHER_DATA_ALIGN
;
898 bcopy(data
, mtod(m
, caddr_t
), (unsigned)len
);
902 * Current code up the line assumes that the media header's been
903 * stripped, but we'd like to preserve it, just in case someone
906 m
->m_pkthdr
.len
= len
;
908 m
->m_pkthdr
.rcvif
= ifp
;
909 m
->m_data
+= sizeof(*eh_p
);
910 m
->m_len
-= sizeof (*eh_p
);
911 m
->m_pkthdr
.len
-= sizeof(*eh_p
);
912 ether_input(ifp
, eh_p
, m
);
921 mace_recv_pkt(rxpkt
, 0);
925 mace_dbdma_rx_intr(int unit
, void *ignored
, void * arp
)
930 thread_call_func((thread_call_func_t
)rx_intr
, 0, TRUE
);
935 mace_ioctl(struct ifnet
* ifp
,u_long cmd
, caddr_t data
)
939 struct ifaddr
* ifa
= (struct ifaddr
*)data
;
940 struct ifreq
* ifr
= (struct ifreq
*)data
;
941 struct sockaddr_in
* sin
;
943 sin
= (struct sockaddr_in
*)(&((struct ifreq
*)data
)->ifr_addr
);
944 ar
= (struct arpcom
*)ifp
;
948 error
= in_bootp(ifp
, sin
, &mace
.en_arpcom
.ac_enaddr
);
953 ifp
->if_flags
|= (IFF_UP
| IFF_RUNNING
);
955 ifp
->if_flags
|= IFF_UP
;
957 switch (ifa
->ifa_addr
->sa_family
) {
960 * See if another station has *our* IP address.
961 * i.e.: There is an address conflict! If a
962 * conflict exists, a message is sent to the
965 if (IA_SIN(ifa
)->sin_addr
.s_addr
!= 0) { /* don't bother for 0.0.0.0 */
966 ar
->ac_ipaddr
= IA_SIN(ifa
)->sin_addr
;
967 arpwhohas(ar
, &IA_SIN(ifa
)->sin_addr
);
977 * If interface is marked down and it is running, then stop it
979 if ((ifp
->if_flags
& IFF_UP
) == 0 &&
980 (ifp
->if_flags
& IFF_RUNNING
) != 0) {
982 * If interface is marked down and it is running, then
985 ifp
->if_flags
&= ~IFF_RUNNING
;
986 } else if ((ifp
->if_flags
& IFF_UP
) != 0 &&
987 (ifp
->if_flags
& IFF_RUNNING
) == 0) {
989 * If interface is marked up and it is stopped, then
992 ifp
->if_flags
|= IFF_RUNNING
;
996 * If the state of the promiscuous bit changes, the
997 * interface must be reset to effect the change.
999 if (((ifp
->if_flags
^ mace
.promisc
) & IFF_PROMISC
) &&
1000 (ifp
->if_flags
& IFF_RUNNING
)) {
1001 mace
.promisc
= ifp
->if_flags
& IFF_PROMISC
;
1002 mace_sync_promisc(ifp
);
1008 if ((error
= ether_addmulti(ifr
, ar
)) == ENETRESET
)
1009 { if ((error
= mace_addmulti(ifr
, ar
)) != 0)
1011 mace_sync_mcast(ifp
);
1018 struct ether_addr enaddr
[2]; /* [0] - addrlo, [1] - addrhi */
1020 if ((error
= ether_delmulti(ifr
, ar
, enaddr
)) == ENETRESET
) {
1021 if ((error
= mace_delmulti(ifr
, ar
, enaddr
)) != 0) {
1023 mace_sync_mcast(ifp
);
1039 struct ifnet
* ifp
= &mace
.en_arpcom
.ac_if
;
1042 * Only use in-kernel driver for early debugging (bootargs: kdp=1|3)
1044 if ( (kdp_flag
& 1) == 0 )
1053 bzero((caddr_t
)ifp
, sizeof(struct ifnet
));
1054 bcopy(&mace
.macaddr
, &mace
.en_arpcom
.ac_enaddr
, NUM_EN_ADDR_BYTES
);
1056 ifp
->if_name
= "en";
1058 ifp
->if_private
= 0;
1059 ifp
->if_ioctl
= mace_ioctl
;
1060 ifp
->if_start
= mace_start
;
1062 IFF_BROADCAST
| IFF_SIMPLEX
| IFF_NOTRAILERS
| IFF_MULTICAST
;
1064 bpfattach(&ifp
->if_bpf
, ifp
, DLT_EN10MB
, sizeof(struct ether_header
));
1067 ether_ifattach(ifp
);
1071 /* wire in the interrupt routines */
1072 pmac_register_int(PMAC_DMA_ETHERNET_RX
, SPLNET
,
1073 mace_dbdma_rx_intr
, 0);
1074 pmac_register_int(PMAC_DMA_ETHERNET_TX
, SPLNET
,
1075 mace_dbdma_tx_intr
, 0);
1077 // pmac_register_int(PMAC_DEV_ETHERNET, SPLNET, mace_pci_intr);
1080 timeout(mace_watchdog
, 0, 10*hz
); /* just in case we drop an interrupt */
1088 * Service MACE interrupt
1092 mace_pci_intr(int device
, void *ssp
)
1094 unsigned char ir
, retry
, frame
, packet
, length
;
1096 ir
= mace
.ereg
->ir
; eieio(); /* Clear Interrupt */
1097 packet
= mace
.ereg
->mpc
; eieio();
1098 length
= mace
.ereg
->rntpc
; eieio();
1102 if (ir
& IR_XMTINT
) {
1103 retry
= mace
.ereg
->xmtrc
; eieio(); /* Grab transmit retry count */
1104 frame
= mace
.ereg
->xmtfs
; eieio();
1106 // mace_dbdma_tx_intr(device, ssp);
1116 mace_service_queue(&mace
.en_arpcom
.ac_if
);
1120 * mace_dbdma_tx_intr
1122 * DBDMA interrupt routine
1125 mace_dbdma_tx_intr(int unit
, void *ignored
, void * arg
)
1130 thread_call_func((thread_call_func_t
)tx_intr
, 0, TRUE
);