]>
git.saurik.com Git - apple/xnu.git/blob - bsd/if/ppc/if_en.c
a1b2a1b9656430f32a45ab250343fc20e2eac885
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright (c) 1997 Apple Computer, Inc.
25 * ethernet driver for mace on-board ethernet
29 * Dieter Siegmund (dieter@next.com) Thu Feb 27 18:25:33 PST 1997
30 * - ripped off code from MK/LINUX, turned it into a polled-mode
31 * driver for the PCI (8500) class machines
33 * Dieter Siegmund (dieter@next.com) Fri Mar 21 12:41:29 PST 1997
34 * - reworked to support a BSD-style interface, and to support kdb polled
35 * interface and interrupt-driven interface concurrently
37 * Justin Walker (justin@apple.com) Tue May 20 10:29:29 PDT 1997
38 * - Added multicast support
40 * Dieter Siegmund (dieter@next.com) Thu May 29 15:02:29 PDT 1997
41 * - fixed problem with sending arp packets for ip address 0.0.0.0
42 * - use kdp_register_send_receive() instead of defining
43 * en_send_pkt/en_recv_pkt routines to avoid name space
44 * collisions with IOEthernetDebugger and allow these routines to be
45 * overridden by a driverkit-style driver
47 * Dieter Siegmund (dieter@apple.com) Tue Jun 24 18:29:15 PDT 1997
48 * - don't let the adapter auto-strip 802.3 receive frames, it messes
49 * up the frame size logic
51 * Dieter Siegmund (dieter@apple.com) Tue Aug 5 16:24:52 PDT 1997
52 * - handle multicast address deletion correctly
56 * Caveat: MACE_DEBUG delimits some code that is getting kind of
57 * stale. Before blindly turning on MACE_DEBUG for your
58 * testing, take a look at the code enabled by it to check
59 * that it is reasonably sane.
63 #include <machdep/ppc/dbdma.h>
64 #include <kern/kdp_en_debugger.h>
66 #define RECEIVE_INT DBDMA_INT_ALWAYS
68 #include <sys/types.h>
69 #include <sys/systm.h>
70 #include <sys/param.h>
71 #include <sys/errno.h>
72 #include <sys/socket.h>
74 #include <net/etherdefs.h>
75 #include <netinet/if_ether.h>
76 #include <sys/sockio.h>
77 #include <netinet/in_var.h>
78 #include <netinet/in.h>
80 #include <mach/mach_types.h>
81 #include <ppc/powermac.h>
82 #include <ppc/interrupts.h>
83 #include <ppc/proc_reg.h>
84 #include <libkern/libkern.h>
85 #include <kern/thread_call.h>
95 static void polled_send_pkt(char * data
, int len
);
96 static void polled_receive_pkt(char *data
, int *len
, int timeout_ms
);
97 void mace_dbdma_rx_intr(int unit
, void *, void *);
98 void mace_dbdma_tx_intr(int, void *, void *);
99 void mace_pci_intr(int, void *);
100 void mace_service_queue(struct ifnet
* ifp
);
103 static int mace_watchdog();
106 static __inline__ vm_offset_t
107 KVTOPHYS(vm_offset_t v
)
112 typedef int (*funcptr
)(char *, int, void *);
116 macAddrsEqual(unsigned char * one
, unsigned char * two
)
120 for (i
= 0; i
< NUM_EN_ADDR_BYTES
; i
++)
121 if (*one
++ != *two
++)
127 static __inline__
int
128 isprint(unsigned char c
)
130 return (c
>= 0x20 && c
<= 0x7e);
134 printEtherHeader(enet_addr_t
* dh
, enet_addr_t
* sh
, u_short etype
)
136 u_char
* dhost
= dh
->ether_addr_octet
;
137 u_char
* shost
= sh
->ether_addr_octet
;
139 printf("Dst: %x:%x:%x:%x:%x:%x Src: %x:%x:%x:%x:%x:%x Type: 0x%x\n",
140 dhost
[0], dhost
[1], dhost
[2], dhost
[3], dhost
[4], dhost
[5],
141 shost
[0], shost
[1], shost
[2], shost
[3], shost
[4], shost
[5],
146 printData(u_char
* data_p
, int n_bytes
)
148 #define CHARS_PER_LINE 16
149 char line_buf
[CHARS_PER_LINE
+ 1];
153 for (line_pos
= 0, offset
= 0; offset
< n_bytes
; offset
++, data_p
++) {
155 printf("%04d ", offset
);
158 line_buf
[line_pos
] = isprint(*data_p
) ? *data_p
: '.';
159 printf(" %02x", *data_p
);
161 if (line_pos
== CHARS_PER_LINE
) {
162 line_buf
[CHARS_PER_LINE
] = '\0';
163 printf(" %s\n", line_buf
);
167 if (line_pos
) { /* need to finish up the line */
168 for (; line_pos
< CHARS_PER_LINE
; line_pos
++) {
170 line_buf
[line_pos
] = ' ';
172 line_buf
[CHARS_PER_LINE
] = '\0';
173 printf(" %s\n", line_buf
);
178 printEtherPacket(enet_addr_t
* dhost
, enet_addr_t
* shost
, u_short type
,
179 u_char
* data_p
, int n_bytes
)
181 printEtherHeader(dhost
, shost
, type
);
182 printData(data_p
, n_bytes
);
186 printContiguousEtherPacket(u_char
* data_p
, int n_bytes
)
188 printEtherPacket((enet_addr_t
*)data_p
,
189 (enet_addr_t
*)(data_p
+ NUM_EN_ADDR_BYTES
),
190 *((u_short
*)(data_p
+ (NUM_EN_ADDR_BYTES
* 2))),
196 #define MACE_DMA_AREA_SIZE (ETHER_RX_NUM_DBDMA_BUFS * ETHERNET_BUF_SIZE + PG_SIZE)
197 static unsigned long mace_rx_dma_area
[(MACE_DMA_AREA_SIZE
+ sizeof(long))/sizeof(long)];
199 static unsigned long mace_tx_dma_area
[(ETHERNET_BUF_SIZE
+ PG_SIZE
+ sizeof(long))/sizeof(long)];
204 * This function computes the Ethernet Hardware address
205 * from PROM. (Its best not to ask how this is done.)
209 mace_swapbits(unsigned char bits
)
211 unsigned char mask
= 0x1, i
, newbits
= 0;
213 for (i
= 0x80; i
; mask
<<= 1, i
>>=1) {
222 mace_get_hwid(unsigned char *hwid_addr
, mace_t
* m
)
226 for (i
= 0; i
< NUM_EN_ADDR_BYTES
; i
++, hwid_addr
+= 16) {
227 m
->macaddr
[i
] = mace_swapbits(*hwid_addr
);
240 dbdma_reset(DBDMA_ETHERNET_RV
);
241 dbdma_reset(DBDMA_ETHERNET_TX
);
248 * This function gets the ethernet address (array of 6 unsigned
249 * bytes) from the MACE board registers.
257 unsigned char ep_temp
;
259 mace
.ereg
->iac
= IAC_PHYADDR
; eieio();
261 for (i
= 0; i
< ETHER_ADD_SIZE
; i
++) {
262 ep_temp
= mace
.ereg
->padr
; eieio();
270 * This function sets the ethernet address (array of 6 unsigned
271 * bytes) on the MACE board.
278 unsigned char status
;
280 if (mace
.chip_id
!= MACE_REVISION_A2
) {
281 mace
.ereg
->iac
= IAC_ADDRCHG
|IAC_PHYADDR
; eieio();
283 while ((status
= mace
.ereg
->iac
)) {
284 if ((status
& IAC_ADDRCHG
) == 0) {
292 /* start to load the address.. */
293 mace
.ereg
->iac
= IAC_PHYADDR
; eieio();
296 for (i
= 0; i
< NUM_EN_ADDR_BYTES
; i
++) {
297 mace
.ereg
->padr
= *(ep
+i
); eieio();
305 * Setup various dbdma pointers.
315 dbdma_regmap_t
* regmap
;
317 #define ALIGN_MASK 0xfffffffcUL
318 if (m
->rv_dma_area
== 0) {
319 m
->rv_dma_area
= (unsigned char *)
320 ((((unsigned long)mace_rx_dma_area
) + 3) & ALIGN_MASK
);
321 m
->rv_dma
= dbdma_alloc(ETHER_RX_NUM_DBDMA_BUFS
+ 2);
322 m
->tx_dma
= dbdma_alloc(TX_NUM_DBDMA
);
323 m
->tx_dma_area
= (unsigned char *)
324 ((((unsigned long)mace_tx_dma_area
) + 3) & ALIGN_MASK
);
327 /* set up a ring of buffers */
329 for (i
= 0; i
< ETHER_RX_NUM_DBDMA_BUFS
; i
++, d
++) {
330 address
= (vm_offset_t
) KVTOPHYS((vm_offset_t
)&m
->rv_dma_area
[i
*ETHERNET_BUF_SIZE
]);
331 DBDMA_BUILD(d
, DBDMA_CMD_IN_LAST
, 0, ETHERNET_BUF_SIZE
,
332 address
, RECEIVE_INT
,
337 /* stop when we hit the end of the list */
338 DBDMA_BUILD(d
, DBDMA_CMD_STOP
, 0, 0, 0, RECEIVE_INT
,
339 DBDMA_WAIT_NEVER
, DBDMA_BRANCH_NEVER
);
342 /* branch to command at "address" ie. element 0 of the "array" */
343 DBDMA_BUILD(d
, DBDMA_CMD_NOP
, 0, 0, 0, DBDMA_INT_NEVER
,
344 DBDMA_WAIT_NEVER
, DBDMA_BRANCH_ALWAYS
);
345 address
= (vm_offset_t
) KVTOPHYS((vm_offset_t
)m
->rv_dma
);
346 dbdma_st4_endian(&d
->d_cmddep
, address
);
349 m
->rv_tail
= ETHER_RX_NUM_DBDMA_BUFS
; /* always contains DBDMA_CMD_STOP */
351 /* stop/init/restart dma channel */
352 dbdma_reset(DBDMA_ETHERNET_RV
);
353 dbdma_reset(DBDMA_ETHERNET_TX
);
355 /* Set the wait value.. */
356 regmap
= DBDMA_REGMAP(DBDMA_ETHERNET_RV
);
357 dbdma_st4_endian(®map
->d_wait
, DBDMA_SET_CNTRL(0x00));
359 /* Set the tx wait value */
360 regmap
= DBDMA_REGMAP(DBDMA_ETHERNET_TX
);
361 dbdma_st4_endian(®map
->d_wait
, DBDMA_SET_CNTRL(0x20));
363 flush_cache_v((vm_offset_t
)m
->rv_dma
,
364 sizeof(dbdma_command_t
) * (ETHER_RX_NUM_DBDMA_BUFS
+ 2));
365 /* start receiving */
366 dbdma_start(DBDMA_ETHERNET_RV
, m
->rv_dma
);
370 static unsigned char testBuffer
[PG_SIZE
* 4];
371 static unsigned char testMsg
[] = "mace ethernet interface test";
378 bzero(testBuffer
, sizeof(testBuffer
));
382 /* send self-addressed packet */
383 bcopy(&mace
.macaddr
[0], tp
, NUM_EN_ADDR_BYTES
);
384 tp
+= NUM_EN_ADDR_BYTES
;
385 bcopy(&mace
.macaddr
[0], tp
, NUM_EN_ADDR_BYTES
);
386 tp
+= NUM_EN_ADDR_BYTES
;
389 bcopy(testMsg
, tp
, sizeof(testMsg
));
390 polled_send_pkt(testBuffer
, 80);
396 * Function: init_mace
399 * Called early on, initializes the adapter and readies it for
400 * kdb kernel debugging.
405 unsigned char status
;
407 struct mace_board
* ereg
;
411 * Only use in-kernel driver for early debugging (bootargs: kdp=1 or kdp=3)
413 if ( (kdp_flag
& 1) == 0 )
418 bzero(&mace
, sizeof(mace
));
420 /* get the ethernet registers' mapped address */
422 = (struct mace_board
*) POWERMAC_IO(PCI_ETHERNET_BASE_PHYS
);
423 mace_get_hwid((unsigned char *)POWERMAC_IO(PCI_ETHERNET_ADDR_PHYS
), m
);
425 /* Reset the board & AMIC.. */
428 /* grab the MACE chip rev */
429 m
->chip_id
= (ereg
->chipid2
<< 8 | ereg
->chipid1
);
431 /* don't auto-strip for 802.3 */
432 m
->ereg
->rcvfc
&= ~(RCVFC_ASTRPRCV
);
434 /* set the ethernet address */
435 mace_seteh(mace
.macaddr
);
437 unsigned char macaddr
[NUM_EN_ADDR_BYTES
];
439 printf("mace ethernet [%02x:%02x:%02x:%02x:%02x:%02x]\n",
440 macaddr
[0], macaddr
[1], macaddr
[2],
441 macaddr
[3], macaddr
[4], macaddr
[5]);
444 /* Now clear the Multicast filter */
445 if (m
->chip_id
!= MACE_REVISION_A2
) {
446 ereg
->iac
= IAC_ADDRCHG
|IAC_LOGADDR
; eieio();
448 while ((status
= ereg
->iac
)) {
449 if ((status
& IAC_ADDRCHG
) == 0)
456 ereg
->iac
= IAC_LOGADDR
; eieio();
461 for (i
=0; i
< 8; i
++)
467 /* register interrupt routines */
470 /* Start the chip... */
471 m
->ereg
->maccc
= MACCC_ENXMT
|MACCC_ENRCV
; eieio();
473 volatile char ch
= mace
.ereg
->ir
; eieio();
476 delay(500); /* paranoia */
477 mace
.ereg
->imr
= 0xfe; eieio();
479 /* register our debugger routines */
480 kdp_register_send_receive((kdp_send_t
)polled_send_pkt
,
481 (kdp_receive_t
)polled_receive_pkt
);
484 printf("Testing 1 2 3\n");
486 printf("Testing 1 2 3\n");
488 printf("Testing 1 2 3\n");
491 static unsigned char buf
[ETHERNET_BUF_SIZE
];
493 int nmpc
= mace
.ereg
->mpc
; eieio();
497 printf("mpc %d\n", mpc
);
499 polled_receive_pkt(buf
, &len
, 100);
501 printf("rx %d\n", len
);
502 printContiguousEtherPacket(buf
, len
);
514 volatile dbdma_regmap_t
* dmap
= DBDMA_REGMAP(DBDMA_ETHERNET_TX
);
515 volatile unsigned long status
;
516 volatile unsigned long intr
;
517 volatile unsigned long branch
;
518 volatile unsigned long wait
;
520 status
= dbdma_ld4_endian(&dmap
->d_status
); eieio();
521 intr
= dbdma_ld4_endian(&dmap
->d_intselect
); eieio();
522 branch
= dbdma_ld4_endian(&dmap
->d_branch
); eieio();
523 wait
= dbdma_ld4_endian(&dmap
->d_wait
); eieio();
524 printf("(%s s=0x%x i=0x%x b=0x%x w=0x%x)", msg
, status
, intr
, branch
,
531 tx_dbdma(char * data
, int len
)
538 page
= ((unsigned long) data
) & PG_MASK
;
539 if ((page
+ len
) <= PG_SIZE
) { /* one piece dma */
540 DBDMA_BUILD(d
, DBDMA_CMD_OUT_LAST
, DBDMA_KEY_STREAM0
,
542 (vm_offset_t
) KVTOPHYS((vm_offset_t
) data
),
544 DBDMA_WAIT_IF_FALSE
, DBDMA_BRANCH_NEVER
);
546 else { /* two piece dma */
547 count
= PG_SIZE
- page
;
548 DBDMA_BUILD(d
, DBDMA_CMD_OUT_MORE
, DBDMA_KEY_STREAM0
,
550 (vm_offset_t
)KVTOPHYS((vm_offset_t
) data
),
552 DBDMA_WAIT_NEVER
, DBDMA_BRANCH_NEVER
);
554 DBDMA_BUILD(d
, DBDMA_CMD_OUT_LAST
, DBDMA_KEY_STREAM0
,
555 len
- count
, (vm_offset_t
)
556 KVTOPHYS((vm_offset_t
)((unsigned char *)data
+ count
)),
558 DBDMA_WAIT_IF_FALSE
, DBDMA_BRANCH_NEVER
);
561 DBDMA_BUILD(d
, DBDMA_CMD_LOAD_QUAD
, DBDMA_KEY_SYSTEM
,
562 1, KVTOPHYS((vm_offset_t
) &mace
.ereg
->xmtfs
),DBDMA_INT_NEVER
,
563 DBDMA_WAIT_NEVER
, DBDMA_BRANCH_NEVER
);
565 DBDMA_BUILD(d
, DBDMA_CMD_LOAD_QUAD
, DBDMA_KEY_SYSTEM
,
566 1, KVTOPHYS((vm_offset_t
) &mace
.ereg
->ir
), DBDMA_INT_ALWAYS
,
567 DBDMA_WAIT_NEVER
, DBDMA_BRANCH_NEVER
);
569 DBDMA_BUILD(d
, DBDMA_CMD_STOP
, 0, 0, 0, 0, 0, 0);
570 flush_cache_v((vm_offset_t
)mace
.tx_dma
, sizeof(dbdma_command_t
) * TX_NUM_DBDMA
);
571 dbdma_start(DBDMA_ETHERNET_TX
, mace
.tx_dma
);
577 waitForDBDMADone(char * msg
)
580 /* wait for tx dma completion */
581 volatile dbdma_regmap_t
* dmap
= DBDMA_REGMAP(DBDMA_ETHERNET_TX
);
583 volatile unsigned long val
;
587 val
= dbdma_ld4_endian(&dmap
->d_status
); eieio();
590 } while ((i
< 100000) && (val
& DBDMA_CNTRL_ACTIVE
));
592 printf("mace(%s): tx_dbdma poll timed out 0x%x", msg
, val
);
597 mace_service_queue(struct ifnet
* ifp
)
599 unsigned char * buf_p
;
604 if (mace
.tx_busy
) { /* transmit in progress? */
608 IF_DEQUEUE(&(ifp
->if_snd
), m
);
613 len
= m
->m_pkthdr
.len
;
615 if (len
> ETHERMAXPACKET
) {
616 printf("mace_start: packet too big (%d), dropping\n", len
);
621 buf_p
= mace
.tx_dma_area
;
623 printf("mace: sending more than one mbuf\n");
625 for (mp
= m
; mp
; mp
= mp
->m_next
) {
628 bcopy(mtod(mp
, caddr_t
), buf_p
, min(mp
->m_len
, len
));
636 BPF_TAP(ifp
->if_bpf
, mace
.tx_dma_area
, m
->m_pkthdr
.len
);
640 printf("tx packet %d\n", m
->m_pkthdr
.len
);
641 printContiguousEtherPacket(mace
.tx_dma_area
, m
->m_pkthdr
.len
);
644 /* fill in the dbdma records and kick off the dma */
645 tx_dbdma(mace
.tx_dma_area
, m
->m_pkthdr
.len
);
654 struct ifnet
* ifp
= &mace
.en_arpcom
.ac_if
;
659 if (mace
.rxintr
== 0) {
660 printf("rx is hung up\n");
665 if (mace
.txintr
== 0 && ifp
->if_snd
.ifq_head
) {
667 dbdma_stop(DBDMA_ETHERNET_TX
);
669 mace_service_queue(ifp
);
673 timeout(mace_watchdog
, 0, 10*hz
); /* just in case we drop an interrupt */
676 #endif /* MACE_DEBUG */
679 mace_start(struct ifnet
* ifp
)
681 // int i = mace.tx_busy;
683 // printf("mace_start %s\n", mace.tx_busy ? "(txBusy)" : "");
684 mace_service_queue(ifp
);
686 // if (mace.tx_busy && !i)
687 // printf("(txStarted)\n");
692 mace_recv_pkt(funcptr pktfunc
, void * p
)
695 struct mace_board
* board
;
701 unsigned short status
;
707 /* remember where the tail was */
709 for (done
= 0; (done
== 0) && (m
->rv_head
!= tail
);) {
710 dbdma_command_t
* dmaHead
;
712 dmaHead
= &m
->rv_dma
[m
->rv_head
];
713 resid
= dbdma_ld4_endian(&dmaHead
->d_status_resid
);
714 status
= (resid
>> 16);
715 bytes
= resid
& 0xffff;
716 bytes
= ETHERNET_BUF_SIZE
- bytes
- 8; /* strip off FCS/CRC */
718 if ((status
& DBDMA_ETHERNET_EOP
) == 0) {
719 /* no packets are ready yet */
723 /* if the packet is good, pass it up */
724 if (bytes
>= (ETHER_MIN_PACKET
- 4)) {
726 dmaPacket
= &m
->rv_dma_area
[m
->rv_head
* ETHERNET_BUF_SIZE
];
727 done
= (*pktfunc
)(dmaPacket
, bytes
, p
);
729 /* mark the head as the new tail in the dma channel command list */
730 DBDMA_BUILD(dmaHead
, DBDMA_CMD_STOP
, 0, 0, 0, RECEIVE_INT
,
731 DBDMA_WAIT_NEVER
, DBDMA_BRANCH_NEVER
);
732 flush_cache_v((vm_offset_t
)dmaHead
, sizeof(*dmaHead
));
735 /* make the tail an available dma'able entry */
737 dbdma_command_t
* dmaTail
;
738 dmaTail
= &m
->rv_dma
[m
->rv_tail
];
739 address
= KVTOPHYS((vm_offset_t
)
740 &m
->rv_dma_area
[m
->rv_tail
*ETHERNET_BUF_SIZE
]);
741 // this command is live so write it carefully
742 DBDMA_ST4_ENDIAN(&dmaTail
->d_address
, address
);
743 dmaTail
->d_status_resid
= 0;
744 dmaTail
->d_cmddep
= 0;
746 DBDMA_ST4_ENDIAN(&dmaTail
->d_cmd_count
,
747 ((DBDMA_CMD_IN_LAST
) << 28) | ((0) << 24) |
748 ((RECEIVE_INT
) << 20) |
749 ((DBDMA_BRANCH_NEVER
) << 18) | ((DBDMA_WAIT_NEVER
) << 16) |
750 (ETHERNET_BUF_SIZE
));
752 flush_cache_v((vm_offset_t
)dmaTail
, sizeof(*dmaTail
));
754 /* head becomes the tail */
755 m
->rv_tail
= m
->rv_head
;
757 /* advance the head */
759 if (m
->rv_head
== (ETHER_RX_NUM_DBDMA_BUFS
+ 1))
764 dbdma_continue(DBDMA_ETHERNET_RV
);
769 /* kdb handle buffer routines */
776 kdb_copy(char * pktBuf
, int len
, void * p
)
778 struct kdbCopy
* cp
= (struct kdbCopy
*)p
;
780 bcopy(pktBuf
, cp
->data
, len
);
782 return (1); /* signal that we're done */
785 /* kdb debugger routines */
787 polled_send_pkt(char * data
, int len
)
789 waitForDBDMADone("mace: polled_send_pkt start");
791 waitForDBDMADone("mace: polled_send_pkt end");
796 polled_receive_pkt(char *data
, int *len
, int timeout_ms
)
805 while (mace_recv_pkt(kdb_copy
, (void *)&cp
) == 0) {
814 /* Bump to force ethernet data to be 4-byte aligned
815 * (since the ethernet header is 14 bytes, and the 802.3 header is
816 * 22 = 14+8 bytes). This assumes that m_data is word-aligned
819 #define ETHER_DATA_ALIGN 2
825 * Called from within mace_recv_pkt to deal with a packet of data.
826 * rxpkt() allocates an mbuf(+cluser) and passes it up to the stacks.
828 * 0 if the packet was copied to an mbuf, 1 otherwise
831 rxpkt(char * data
, int len
, void * p
)
833 struct ether_header
* eh_p
= (struct ether_header
*)data
;
834 struct ifnet
* ifp
= &mace
.en_arpcom
.ac_if
;
841 /* mcast, bcast -- we're interested in either */
842 interesting
= eh_p
->ether_dhost
[0] & 1;
846 * Check if there's a bpf filter listening on this interface.
847 * If so, hand off the raw packet to bpf_tap().
850 BPF_TAP(ifp
->if_bpf
, data
, len
);
853 * Keep the packet if it's a broadcast or has our
854 * physical ethernet address (or if we support
855 * multicast and it's one).
857 if ((interesting
== 0) && bcmp(eh_p
->ether_dhost
, mace
.macaddr
,
858 sizeof(eh_p
->ether_dhost
)) != 0) {
865 * We "know" a full-sized packet fits in one cluster. Set up the
866 * packet header, and if the length is sufficient, attempt to allocate
867 * a cluster. If that fails, fall back to the old way (m_devget()).
868 * Here, we take the simple approach of cluster vs. single mbuf.
870 MGETHDR(m
, M_DONTWAIT
, MT_DATA
);
873 printf("mget failed\n");
878 if (len
> (MHLEN
- ETHER_DATA_ALIGN
))
879 { MCLGET(m
, M_DONTWAIT
);
880 if (m
->m_flags
&M_EXT
) /* MCLGET succeeded */
881 { m
->m_data
+= ETHER_DATA_ALIGN
;
882 bcopy(data
, mtod(m
, caddr_t
), (unsigned)len
);
886 printf("no clusters\n");
889 m
= (struct mbuf
*)m_devget(data
, len
, 0, ifp
, 0);
894 { m
->m_data
+= ETHER_DATA_ALIGN
;
895 bcopy(data
, mtod(m
, caddr_t
), (unsigned)len
);
899 * Current code up the line assumes that the media header's been
900 * stripped, but we'd like to preserve it, just in case someone
903 m
->m_pkthdr
.len
= len
;
905 m
->m_pkthdr
.rcvif
= ifp
;
906 m
->m_data
+= sizeof(*eh_p
);
907 m
->m_len
-= sizeof (*eh_p
);
908 m
->m_pkthdr
.len
-= sizeof(*eh_p
);
909 ether_input(ifp
, eh_p
, m
);
918 mace_recv_pkt(rxpkt
, 0);
922 mace_dbdma_rx_intr(int unit
, void *ignored
, void * arp
)
927 thread_call_func((thread_call_func_t
)rx_intr
, 0, TRUE
);
932 mace_ioctl(struct ifnet
* ifp
,u_long cmd
, caddr_t data
)
936 struct ifaddr
* ifa
= (struct ifaddr
*)data
;
937 struct ifreq
* ifr
= (struct ifreq
*)data
;
938 struct sockaddr_in
* sin
;
940 sin
= (struct sockaddr_in
*)(&((struct ifreq
*)data
)->ifr_addr
);
941 ar
= (struct arpcom
*)ifp
;
945 error
= in_bootp(ifp
, sin
, &mace
.en_arpcom
.ac_enaddr
);
950 ifp
->if_flags
|= (IFF_UP
| IFF_RUNNING
);
952 ifp
->if_flags
|= IFF_UP
;
954 switch (ifa
->ifa_addr
->sa_family
) {
957 * See if another station has *our* IP address.
958 * i.e.: There is an address conflict! If a
959 * conflict exists, a message is sent to the
962 if (IA_SIN(ifa
)->sin_addr
.s_addr
!= 0) { /* don't bother for 0.0.0.0 */
963 ar
->ac_ipaddr
= IA_SIN(ifa
)->sin_addr
;
964 arpwhohas(ar
, &IA_SIN(ifa
)->sin_addr
);
974 * If interface is marked down and it is running, then stop it
976 if ((ifp
->if_flags
& IFF_UP
) == 0 &&
977 (ifp
->if_flags
& IFF_RUNNING
) != 0) {
979 * If interface is marked down and it is running, then
982 ifp
->if_flags
&= ~IFF_RUNNING
;
983 } else if ((ifp
->if_flags
& IFF_UP
) != 0 &&
984 (ifp
->if_flags
& IFF_RUNNING
) == 0) {
986 * If interface is marked up and it is stopped, then
989 ifp
->if_flags
|= IFF_RUNNING
;
993 * If the state of the promiscuous bit changes, the
994 * interface must be reset to effect the change.
996 if (((ifp
->if_flags
^ mace
.promisc
) & IFF_PROMISC
) &&
997 (ifp
->if_flags
& IFF_RUNNING
)) {
998 mace
.promisc
= ifp
->if_flags
& IFF_PROMISC
;
999 mace_sync_promisc(ifp
);
1005 if ((error
= ether_addmulti(ifr
, ar
)) == ENETRESET
)
1006 { if ((error
= mace_addmulti(ifr
, ar
)) != 0)
1008 mace_sync_mcast(ifp
);
1015 struct ether_addr enaddr
[2]; /* [0] - addrlo, [1] - addrhi */
1017 if ((error
= ether_delmulti(ifr
, ar
, enaddr
)) == ENETRESET
) {
1018 if ((error
= mace_delmulti(ifr
, ar
, enaddr
)) != 0) {
1020 mace_sync_mcast(ifp
);
1036 struct ifnet
* ifp
= &mace
.en_arpcom
.ac_if
;
1039 * Only use in-kernel driver for early debugging (bootargs: kdp=1|3)
1041 if ( (kdp_flag
& 1) == 0 )
1050 bzero((caddr_t
)ifp
, sizeof(struct ifnet
));
1051 bcopy(&mace
.macaddr
, &mace
.en_arpcom
.ac_enaddr
, NUM_EN_ADDR_BYTES
);
1053 ifp
->if_name
= "en";
1055 ifp
->if_private
= 0;
1056 ifp
->if_ioctl
= mace_ioctl
;
1057 ifp
->if_start
= mace_start
;
1059 IFF_BROADCAST
| IFF_SIMPLEX
| IFF_NOTRAILERS
| IFF_MULTICAST
;
1061 bpfattach(&ifp
->if_bpf
, ifp
, DLT_EN10MB
, sizeof(struct ether_header
));
1064 ether_ifattach(ifp
);
1068 /* wire in the interrupt routines */
1069 pmac_register_int(PMAC_DMA_ETHERNET_RX
, SPLNET
,
1070 mace_dbdma_rx_intr
, 0);
1071 pmac_register_int(PMAC_DMA_ETHERNET_TX
, SPLNET
,
1072 mace_dbdma_tx_intr
, 0);
1074 // pmac_register_int(PMAC_DEV_ETHERNET, SPLNET, mace_pci_intr);
1077 timeout(mace_watchdog
, 0, 10*hz
); /* just in case we drop an interrupt */
1085 * Service MACE interrupt
1089 mace_pci_intr(int device
, void *ssp
)
1091 unsigned char ir
, retry
, frame
, packet
, length
;
1093 ir
= mace
.ereg
->ir
; eieio(); /* Clear Interrupt */
1094 packet
= mace
.ereg
->mpc
; eieio();
1095 length
= mace
.ereg
->rntpc
; eieio();
1099 if (ir
& IR_XMTINT
) {
1100 retry
= mace
.ereg
->xmtrc
; eieio(); /* Grab transmit retry count */
1101 frame
= mace
.ereg
->xmtfs
; eieio();
1103 // mace_dbdma_tx_intr(device, ssp);
1113 mace_service_queue(&mace
.en_arpcom
.ac_if
);
1117 * mace_dbdma_tx_intr
1119 * DBDMA interrupt routine
1122 mace_dbdma_tx_intr(int unit
, void *ignored
, void * arg
)
1127 thread_call_func((thread_call_func_t
)tx_intr
, 0, TRUE
);