xref: /titanic_53/usr/src/stand/lib/inet/mac.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
30*7c478bd9Sstevel@tonic-gate #include <socket_impl.h>
31*7c478bd9Sstevel@tonic-gate #include <socket_inet.h>
32*7c478bd9Sstevel@tonic-gate #include <sys/param.h>
33*7c478bd9Sstevel@tonic-gate #include <sys/time.h>
34*7c478bd9Sstevel@tonic-gate #include <sys/socket.h>
35*7c478bd9Sstevel@tonic-gate #include <net/if.h>
36*7c478bd9Sstevel@tonic-gate #include <net/if_arp.h>
37*7c478bd9Sstevel@tonic-gate #include <net/if_types.h>
38*7c478bd9Sstevel@tonic-gate #include <netinet/in_systm.h>
39*7c478bd9Sstevel@tonic-gate #include <netinet/in.h>
40*7c478bd9Sstevel@tonic-gate #include <netinet/if_ether.h>
41*7c478bd9Sstevel@tonic-gate #include <sys/promif.h>
42*7c478bd9Sstevel@tonic-gate #include <sys/prom_plat.h>
43*7c478bd9Sstevel@tonic-gate #include <sys/salib.h>
44*7c478bd9Sstevel@tonic-gate 
45*7c478bd9Sstevel@tonic-gate #include "mac.h"
46*7c478bd9Sstevel@tonic-gate #include "mac_impl.h"
47*7c478bd9Sstevel@tonic-gate #include "atm_inet.h"
48*7c478bd9Sstevel@tonic-gate #include "ethernet_inet.h"
49*7c478bd9Sstevel@tonic-gate #include "fddi_inet.h"
50*7c478bd9Sstevel@tonic-gate #include "token_inet.h"
51*7c478bd9Sstevel@tonic-gate #include "ibd_inet.h"
52*7c478bd9Sstevel@tonic-gate 
53*7c478bd9Sstevel@tonic-gate /*
54*7c478bd9Sstevel@tonic-gate  * MAC layer interface
55*7c478bd9Sstevel@tonic-gate  */
56*7c478bd9Sstevel@tonic-gate boolean_t		initialized;	/* Boolean state */
57*7c478bd9Sstevel@tonic-gate struct mac_type		mac_state;
58*7c478bd9Sstevel@tonic-gate int			arp_index;	/* current arp table index */
59*7c478bd9Sstevel@tonic-gate static struct arptable	atable[ARP_TABLE_SIZE];
60*7c478bd9Sstevel@tonic-gate 
61*7c478bd9Sstevel@tonic-gate #if	!defined(__i386)
62*7c478bd9Sstevel@tonic-gate struct ofw_net_types {
63*7c478bd9Sstevel@tonic-gate 	char	*n_name;	/* OFW network media name */
64*7c478bd9Sstevel@tonic-gate 	int	n_type;		/* IFT */
65*7c478bd9Sstevel@tonic-gate } ofw_types[] = {
66*7c478bd9Sstevel@tonic-gate 	{ "atm",	IFT_ATM	},
67*7c478bd9Sstevel@tonic-gate 	{ "ethernet",	IFT_ETHER },
68*7c478bd9Sstevel@tonic-gate 	{ "fddi",	IFT_FDDI },
69*7c478bd9Sstevel@tonic-gate 	{ "token-ring",	IFT_ISO88025 },
70*7c478bd9Sstevel@tonic-gate 	{ "ipib",	IFT_IB }
71*7c478bd9Sstevel@tonic-gate };
72*7c478bd9Sstevel@tonic-gate #endif	/* !__i386 */
73*7c478bd9Sstevel@tonic-gate 
74*7c478bd9Sstevel@tonic-gate /*
75*7c478bd9Sstevel@tonic-gate  * given the mac type, initialize the mac interface state.
76*7c478bd9Sstevel@tonic-gate  */
77*7c478bd9Sstevel@tonic-gate void
78*7c478bd9Sstevel@tonic-gate mac_init(char *bootdevicename)
79*7c478bd9Sstevel@tonic-gate {
80*7c478bd9Sstevel@tonic-gate 	int		type = 0;
81*7c478bd9Sstevel@tonic-gate #if !defined(__i386)
82*7c478bd9Sstevel@tonic-gate 	static char	*mtu_name = "max-frame-size";
83*7c478bd9Sstevel@tonic-gate 	static char	*chosen_net = "chosen-network-type";
84*7c478bd9Sstevel@tonic-gate 	static char	*supported_net = "supported-network-types";
85*7c478bd9Sstevel@tonic-gate 	static char	*netiftype = "network-interface-type";
86*7c478bd9Sstevel@tonic-gate 	dnode_t		node;
87*7c478bd9Sstevel@tonic-gate 	char		*wp, *media_type;
88*7c478bd9Sstevel@tonic-gate 	int		len = 0, i;
89*7c478bd9Sstevel@tonic-gate #endif	/* !__i386 */
90*7c478bd9Sstevel@tonic-gate 	char		tmpbuf[MAXNAMELEN];
91*7c478bd9Sstevel@tonic-gate 	char		devname[MAXNAMELEN];
92*7c478bd9Sstevel@tonic-gate 
93*7c478bd9Sstevel@tonic-gate 	if (initialized)
94*7c478bd9Sstevel@tonic-gate 		return;
95*7c478bd9Sstevel@tonic-gate 
96*7c478bd9Sstevel@tonic-gate 	mac_state.mac_in_timeout = MAC_IN_TIMEOUT;
97*7c478bd9Sstevel@tonic-gate 
98*7c478bd9Sstevel@tonic-gate #ifdef	DEBUG
99*7c478bd9Sstevel@tonic-gate 	printf("mac_init: device path: %s\n", bootdevicename);
100*7c478bd9Sstevel@tonic-gate #endif	/* DEBUG */
101*7c478bd9Sstevel@tonic-gate 
102*7c478bd9Sstevel@tonic-gate 	if ((mac_state.mac_dev = prom_open(bootdevicename)) == 0) {
103*7c478bd9Sstevel@tonic-gate 		(void) snprintf(tmpbuf, sizeof (tmpbuf),
104*7c478bd9Sstevel@tonic-gate 		    "Cannot prom_open network device %s.", bootdevicename);
105*7c478bd9Sstevel@tonic-gate 		prom_panic(tmpbuf);
106*7c478bd9Sstevel@tonic-gate 	}
107*7c478bd9Sstevel@tonic-gate 
108*7c478bd9Sstevel@tonic-gate #if !defined(__i386)
109*7c478bd9Sstevel@tonic-gate 	(void) prom_devname_from_pathname(bootdevicename, devname);
110*7c478bd9Sstevel@tonic-gate #else
111*7c478bd9Sstevel@tonic-gate 	(void) strcpy(devname, bootdevicename);
112*7c478bd9Sstevel@tonic-gate #endif	/* !__i386 */
113*7c478bd9Sstevel@tonic-gate 
114*7c478bd9Sstevel@tonic-gate #ifdef	DEBUG
115*7c478bd9Sstevel@tonic-gate 	printf("mac_init: Network device name: %s\n", devname);
116*7c478bd9Sstevel@tonic-gate #endif	/* DEBUG */
117*7c478bd9Sstevel@tonic-gate 
118*7c478bd9Sstevel@tonic-gate #if !defined(__i386)
119*7c478bd9Sstevel@tonic-gate 	/*
120*7c478bd9Sstevel@tonic-gate 	 * Ask the prom for our MTU and media type. "chosen-network-type"
121*7c478bd9Sstevel@tonic-gate 	 * is of the form of "<network type>,<speed (Mbps)>,<connector type>,
122*7c478bd9Sstevel@tonic-gate 	 * <duplex mode>: e.g.: "ethernet,100,rj45,full"
123*7c478bd9Sstevel@tonic-gate 	 */
124*7c478bd9Sstevel@tonic-gate 	node = prom_finddevice(devname);
125*7c478bd9Sstevel@tonic-gate 	if (node != OBP_NONODE && node != OBP_BADNODE) {
126*7c478bd9Sstevel@tonic-gate 		if (prom_getproplen(node, mtu_name) == sizeof (ihandle_t)) {
127*7c478bd9Sstevel@tonic-gate 			(void) prom_getprop(node, mtu_name,
128*7c478bd9Sstevel@tonic-gate 			    (caddr_t)&mac_state.mac_mtu);
129*7c478bd9Sstevel@tonic-gate 		}
130*7c478bd9Sstevel@tonic-gate 		bzero(tmpbuf, sizeof (tmpbuf));
131*7c478bd9Sstevel@tonic-gate 		/*
132*7c478bd9Sstevel@tonic-gate 		 * The following order of looking for properties is
133*7c478bd9Sstevel@tonic-gate 		 * from FWARC 2002/345.
134*7c478bd9Sstevel@tonic-gate 		 */
135*7c478bd9Sstevel@tonic-gate 		if ((len = prom_getproplen(node, netiftype)) > 0 &&
136*7c478bd9Sstevel@tonic-gate 		    len < sizeof (tmpbuf)) {
137*7c478bd9Sstevel@tonic-gate 			(void) prom_getprop(node, netiftype, tmpbuf);
138*7c478bd9Sstevel@tonic-gate 		} else if ((len = prom_getproplen(node, chosen_net)) > 0 &&
139*7c478bd9Sstevel@tonic-gate 		    len < sizeof (tmpbuf)) {
140*7c478bd9Sstevel@tonic-gate 			(void) prom_getprop(node, chosen_net, tmpbuf);
141*7c478bd9Sstevel@tonic-gate 		} else if ((len = prom_getproplen(node, supported_net)) > 0 &&
142*7c478bd9Sstevel@tonic-gate 		    len < sizeof (tmpbuf)) {
143*7c478bd9Sstevel@tonic-gate 			(void) prom_getprop(node, supported_net, tmpbuf);
144*7c478bd9Sstevel@tonic-gate 		}
145*7c478bd9Sstevel@tonic-gate 		media_type = NULL;
146*7c478bd9Sstevel@tonic-gate 		if (len > 0) {
147*7c478bd9Sstevel@tonic-gate 			if ((wp = strstr(tmpbuf, ",")) != NULL)
148*7c478bd9Sstevel@tonic-gate 				*wp = '\0';
149*7c478bd9Sstevel@tonic-gate 			media_type = tmpbuf;
150*7c478bd9Sstevel@tonic-gate 		}
151*7c478bd9Sstevel@tonic-gate 		if (media_type != NULL) {
152*7c478bd9Sstevel@tonic-gate #ifdef	DEBUG
153*7c478bd9Sstevel@tonic-gate 			printf("mac_init: Media type: %s\n", media_type);
154*7c478bd9Sstevel@tonic-gate #endif	/* DEBUG */
155*7c478bd9Sstevel@tonic-gate 			for (i = 0; i < sizeof (ofw_types) /
156*7c478bd9Sstevel@tonic-gate 			    sizeof (struct ofw_net_types); i++) {
157*7c478bd9Sstevel@tonic-gate 				if (strcmp(ofw_types[i].n_name,
158*7c478bd9Sstevel@tonic-gate 				    media_type) == 0) {
159*7c478bd9Sstevel@tonic-gate 					type = ofw_types[i].n_type;
160*7c478bd9Sstevel@tonic-gate 					break;
161*7c478bd9Sstevel@tonic-gate 				}
162*7c478bd9Sstevel@tonic-gate 			}
163*7c478bd9Sstevel@tonic-gate 		}
164*7c478bd9Sstevel@tonic-gate 	}
165*7c478bd9Sstevel@tonic-gate #else
166*7c478bd9Sstevel@tonic-gate 	type = IFT_ETHER;	/* default to ethernet */
167*7c478bd9Sstevel@tonic-gate #endif	/* !__i386 */
168*7c478bd9Sstevel@tonic-gate 
169*7c478bd9Sstevel@tonic-gate 	switch (type) {
170*7c478bd9Sstevel@tonic-gate 	case IFT_ATM:
171*7c478bd9Sstevel@tonic-gate 		/*
172*7c478bd9Sstevel@tonic-gate 		 * ATM is currently treated mostly like ethernet,
173*7c478bd9Sstevel@tonic-gate 		 * with the exception that the MTU is most likely
174*7c478bd9Sstevel@tonic-gate 		 * different.
175*7c478bd9Sstevel@tonic-gate 		 */
176*7c478bd9Sstevel@tonic-gate 		mac_state.mac_type = IFT_ATM;
177*7c478bd9Sstevel@tonic-gate 		mac_state.mac_arp_timeout = ATM_ARP_TIMEOUT;
178*7c478bd9Sstevel@tonic-gate 		mac_state.mac_in_timeout = ATM_IN_TIMEOUT;
179*7c478bd9Sstevel@tonic-gate 		if (mac_state.mac_mtu == 0)
180*7c478bd9Sstevel@tonic-gate 			mac_state.mac_mtu = ATMSIZE;
181*7c478bd9Sstevel@tonic-gate 		mac_state.mac_addr_len = sizeof (ether_addr_t);
182*7c478bd9Sstevel@tonic-gate 		mac_state.mac_addr_buf = bkmem_alloc(mac_state.mac_addr_len);
183*7c478bd9Sstevel@tonic-gate 		if (mac_state.mac_addr_buf == NULL)
184*7c478bd9Sstevel@tonic-gate 			prom_panic("mac_init: Cannot allocate memory.");
185*7c478bd9Sstevel@tonic-gate 		if (prom_getmacaddr(mac_state.mac_dev,
186*7c478bd9Sstevel@tonic-gate 		    (caddr_t)mac_state.mac_addr_buf) != 0)
187*7c478bd9Sstevel@tonic-gate 			prom_panic("mac_init: Cannot obtain MAC address.");
188*7c478bd9Sstevel@tonic-gate 		mac_state.mac_arp = ether_arp;
189*7c478bd9Sstevel@tonic-gate 		mac_state.mac_rarp = ether_revarp;
190*7c478bd9Sstevel@tonic-gate 		mac_state.mac_header_len = ether_header_len;
191*7c478bd9Sstevel@tonic-gate 		mac_state.mac_input = ether_input;
192*7c478bd9Sstevel@tonic-gate 		mac_state.mac_output = ether_output;
193*7c478bd9Sstevel@tonic-gate 		break;
194*7c478bd9Sstevel@tonic-gate 
195*7c478bd9Sstevel@tonic-gate 	case IFT_FDDI:
196*7c478bd9Sstevel@tonic-gate 		/*
197*7c478bd9Sstevel@tonic-gate 		 * FDDI is currently treated mostly like ethernet,
198*7c478bd9Sstevel@tonic-gate 		 * with the exception that the MTU is most likely
199*7c478bd9Sstevel@tonic-gate 		 * different.
200*7c478bd9Sstevel@tonic-gate 		 */
201*7c478bd9Sstevel@tonic-gate 		mac_state.mac_type = IFT_FDDI;
202*7c478bd9Sstevel@tonic-gate 		mac_state.mac_arp_timeout = FDDI_ARP_TIMEOUT;
203*7c478bd9Sstevel@tonic-gate 		mac_state.mac_in_timeout = FDDI_IN_TIMEOUT;
204*7c478bd9Sstevel@tonic-gate 		if (mac_state.mac_mtu == 0)
205*7c478bd9Sstevel@tonic-gate 			mac_state.mac_mtu = FDDISIZE;
206*7c478bd9Sstevel@tonic-gate 		mac_state.mac_addr_len = sizeof (ether_addr_t);
207*7c478bd9Sstevel@tonic-gate 		mac_state.mac_addr_buf = bkmem_alloc(mac_state.mac_addr_len);
208*7c478bd9Sstevel@tonic-gate 		if (mac_state.mac_addr_buf == NULL)
209*7c478bd9Sstevel@tonic-gate 			prom_panic("mac_init: Cannot allocate memory.");
210*7c478bd9Sstevel@tonic-gate 		if (prom_getmacaddr(mac_state.mac_dev,
211*7c478bd9Sstevel@tonic-gate 		    (caddr_t)mac_state.mac_addr_buf) != 0)
212*7c478bd9Sstevel@tonic-gate 			prom_panic("mac_init: Cannot obtain MAC address.");
213*7c478bd9Sstevel@tonic-gate 		mac_state.mac_arp = ether_arp;
214*7c478bd9Sstevel@tonic-gate 		mac_state.mac_rarp = ether_revarp;
215*7c478bd9Sstevel@tonic-gate 		mac_state.mac_header_len = ether_header_len;
216*7c478bd9Sstevel@tonic-gate 		mac_state.mac_input = ether_input;
217*7c478bd9Sstevel@tonic-gate 		mac_state.mac_output = ether_output;
218*7c478bd9Sstevel@tonic-gate 		break;
219*7c478bd9Sstevel@tonic-gate 
220*7c478bd9Sstevel@tonic-gate 	case IFT_ISO88025:
221*7c478bd9Sstevel@tonic-gate 		/*
222*7c478bd9Sstevel@tonic-gate 		 * Token ring is currently treated mostly like ethernet,
223*7c478bd9Sstevel@tonic-gate 		 * with the exception that the MTU is most likely different.
224*7c478bd9Sstevel@tonic-gate 		 */
225*7c478bd9Sstevel@tonic-gate 		mac_state.mac_type = IFT_ISO88025;
226*7c478bd9Sstevel@tonic-gate 		mac_state.mac_arp_timeout = TOKEN_ARP_TIMEOUT;
227*7c478bd9Sstevel@tonic-gate 		mac_state.mac_in_timeout = TOKEN_IN_TIMEOUT;
228*7c478bd9Sstevel@tonic-gate 		if (mac_state.mac_mtu == 0)
229*7c478bd9Sstevel@tonic-gate 			mac_state.mac_mtu = TOKENSIZE;
230*7c478bd9Sstevel@tonic-gate 		mac_state.mac_addr_len = sizeof (ether_addr_t);
231*7c478bd9Sstevel@tonic-gate 		mac_state.mac_addr_buf = bkmem_alloc(mac_state.mac_addr_len);
232*7c478bd9Sstevel@tonic-gate 		if (mac_state.mac_addr_buf == NULL)
233*7c478bd9Sstevel@tonic-gate 			prom_panic("mac_init: Cannot allocate memory.");
234*7c478bd9Sstevel@tonic-gate 		if (prom_getmacaddr(mac_state.mac_dev,
235*7c478bd9Sstevel@tonic-gate 		    (caddr_t)mac_state.mac_addr_buf) != 0)
236*7c478bd9Sstevel@tonic-gate 			prom_panic("mac_init: Cannot obtain MAC address.");
237*7c478bd9Sstevel@tonic-gate 		mac_state.mac_arp = ether_arp;
238*7c478bd9Sstevel@tonic-gate 		mac_state.mac_rarp = ether_revarp;
239*7c478bd9Sstevel@tonic-gate 		mac_state.mac_header_len = ether_header_len;
240*7c478bd9Sstevel@tonic-gate 		mac_state.mac_input = ether_input;
241*7c478bd9Sstevel@tonic-gate 		mac_state.mac_output = ether_output;
242*7c478bd9Sstevel@tonic-gate 		break;
243*7c478bd9Sstevel@tonic-gate 
244*7c478bd9Sstevel@tonic-gate 	case IFT_IB:
245*7c478bd9Sstevel@tonic-gate 		mac_state.mac_type = IFT_IB;
246*7c478bd9Sstevel@tonic-gate 		ibd_init();
247*7c478bd9Sstevel@tonic-gate 		break;
248*7c478bd9Sstevel@tonic-gate 
249*7c478bd9Sstevel@tonic-gate 	case IFT_ETHER:
250*7c478bd9Sstevel@tonic-gate 		/* FALLTHRU - default to ethernet */
251*7c478bd9Sstevel@tonic-gate 	default:
252*7c478bd9Sstevel@tonic-gate 		mac_state.mac_type = IFT_ETHER;
253*7c478bd9Sstevel@tonic-gate 		mac_state.mac_mtu = ETHERSIZE;
254*7c478bd9Sstevel@tonic-gate 		mac_state.mac_arp_timeout = ETHER_ARP_TIMEOUT;
255*7c478bd9Sstevel@tonic-gate 		mac_state.mac_in_timeout = ETHER_IN_TIMEOUT;
256*7c478bd9Sstevel@tonic-gate 		if (mac_state.mac_mtu == 0)
257*7c478bd9Sstevel@tonic-gate 			mac_state.mac_mtu = ETHERSIZE;
258*7c478bd9Sstevel@tonic-gate 		mac_state.mac_addr_len = sizeof (ether_addr_t);
259*7c478bd9Sstevel@tonic-gate 		mac_state.mac_addr_buf = bkmem_alloc(mac_state.mac_addr_len);
260*7c478bd9Sstevel@tonic-gate 		if (mac_state.mac_addr_buf == NULL)
261*7c478bd9Sstevel@tonic-gate 			prom_panic("mac_init: Cannot allocate memory.");
262*7c478bd9Sstevel@tonic-gate 		if (prom_getmacaddr(mac_state.mac_dev,
263*7c478bd9Sstevel@tonic-gate 		    (caddr_t)mac_state.mac_addr_buf) != 0)
264*7c478bd9Sstevel@tonic-gate 			prom_panic("mac_init: Cannot obtain MAC address.");
265*7c478bd9Sstevel@tonic-gate 		mac_state.mac_arp = ether_arp;
266*7c478bd9Sstevel@tonic-gate 		mac_state.mac_rarp = ether_revarp;
267*7c478bd9Sstevel@tonic-gate 		mac_state.mac_header_len = ether_header_len;
268*7c478bd9Sstevel@tonic-gate 		mac_state.mac_input = ether_input;
269*7c478bd9Sstevel@tonic-gate 		mac_state.mac_output = ether_output;
270*7c478bd9Sstevel@tonic-gate 		break;
271*7c478bd9Sstevel@tonic-gate 	}
272*7c478bd9Sstevel@tonic-gate 
273*7c478bd9Sstevel@tonic-gate 	mac_state.mac_buf = bkmem_alloc(mac_state.mac_mtu);
274*7c478bd9Sstevel@tonic-gate 	if (mac_state.mac_buf == NULL)
275*7c478bd9Sstevel@tonic-gate 		prom_panic("mac_init: Cannot allocate netbuf memory.");
276*7c478bd9Sstevel@tonic-gate 	else
277*7c478bd9Sstevel@tonic-gate 		initialized = B_TRUE;
278*7c478bd9Sstevel@tonic-gate }
279*7c478bd9Sstevel@tonic-gate 
280*7c478bd9Sstevel@tonic-gate void
281*7c478bd9Sstevel@tonic-gate mac_fini()
282*7c478bd9Sstevel@tonic-gate {
283*7c478bd9Sstevel@tonic-gate 	if (mac_state.mac_addr_buf != NULL) {
284*7c478bd9Sstevel@tonic-gate 		bkmem_free((caddr_t)mac_state.mac_addr_buf,
285*7c478bd9Sstevel@tonic-gate 		    mac_state.mac_addr_len);
286*7c478bd9Sstevel@tonic-gate 		mac_state.mac_addr_buf = NULL;
287*7c478bd9Sstevel@tonic-gate 	}
288*7c478bd9Sstevel@tonic-gate 	if (mac_state.mac_buf != NULL) {
289*7c478bd9Sstevel@tonic-gate 		bkmem_free(mac_state.mac_buf, mac_state.mac_mtu);
290*7c478bd9Sstevel@tonic-gate 		mac_state.mac_buf = NULL;
291*7c478bd9Sstevel@tonic-gate 	}
292*7c478bd9Sstevel@tonic-gate 	(void) prom_close(mac_state.mac_dev);
293*7c478bd9Sstevel@tonic-gate 	initialized = B_FALSE;
294*7c478bd9Sstevel@tonic-gate }
295*7c478bd9Sstevel@tonic-gate 
296*7c478bd9Sstevel@tonic-gate /* MAC layer specific socket initialization */
297*7c478bd9Sstevel@tonic-gate void
298*7c478bd9Sstevel@tonic-gate mac_socket_init(struct inetboot_socket *isp)
299*7c478bd9Sstevel@tonic-gate {
300*7c478bd9Sstevel@tonic-gate 	isp->input[MEDIA_LVL] = mac_state.mac_input;
301*7c478bd9Sstevel@tonic-gate 	isp->output[MEDIA_LVL] = mac_state.mac_output;
302*7c478bd9Sstevel@tonic-gate 	isp->close[MEDIA_LVL] = NULL;
303*7c478bd9Sstevel@tonic-gate 	isp->headerlen[MEDIA_LVL] = mac_state.mac_header_len;
304*7c478bd9Sstevel@tonic-gate 	isp->in_timeout = mac_state.mac_in_timeout;
305*7c478bd9Sstevel@tonic-gate }
306*7c478bd9Sstevel@tonic-gate 
307*7c478bd9Sstevel@tonic-gate /*
308*7c478bd9Sstevel@tonic-gate  * Add an entry to the ARP table. All values in table are network order.
309*7c478bd9Sstevel@tonic-gate  * No checking is done to determine whether there's duplicates.
310*7c478bd9Sstevel@tonic-gate  */
311*7c478bd9Sstevel@tonic-gate void
312*7c478bd9Sstevel@tonic-gate mac_set_arp(struct in_addr *ip, void *hp, int hl)
313*7c478bd9Sstevel@tonic-gate {
314*7c478bd9Sstevel@tonic-gate 	atable[arp_index].ia.s_addr = ip->s_addr;
315*7c478bd9Sstevel@tonic-gate 	bcopy(hp, (char *)atable[arp_index].ha, hl);
316*7c478bd9Sstevel@tonic-gate 	atable[arp_index].hl = hl;
317*7c478bd9Sstevel@tonic-gate 	arp_index++;
318*7c478bd9Sstevel@tonic-gate 	if (arp_index >= ARP_TABLE_SIZE)
319*7c478bd9Sstevel@tonic-gate 		arp_index = 0;
320*7c478bd9Sstevel@tonic-gate }
321*7c478bd9Sstevel@tonic-gate 
322*7c478bd9Sstevel@tonic-gate /*
323*7c478bd9Sstevel@tonic-gate  * Retrieve an entry from the ARP table using network-order IP address as
324*7c478bd9Sstevel@tonic-gate  * search criteria. HW address buffer is filled in up to hl in len. (make
325*7c478bd9Sstevel@tonic-gate  * sure the buffer is big enough given the mac type)
326*7c478bd9Sstevel@tonic-gate  *
327*7c478bd9Sstevel@tonic-gate  * Returns TRUE if successful, FALSE otherwise. Will wait timeout milliseconds
328*7c478bd9Sstevel@tonic-gate  * for a response.
329*7c478bd9Sstevel@tonic-gate  */
330*7c478bd9Sstevel@tonic-gate int
331*7c478bd9Sstevel@tonic-gate mac_get_arp(struct in_addr *ip, void *hp, int hl, uint32_t timeout)
332*7c478bd9Sstevel@tonic-gate {
333*7c478bd9Sstevel@tonic-gate 	int i, result;
334*7c478bd9Sstevel@tonic-gate 
335*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < ARP_TABLE_SIZE; i++) {
336*7c478bd9Sstevel@tonic-gate 		if (ip->s_addr == atable[i].ia.s_addr) {
337*7c478bd9Sstevel@tonic-gate 			bcopy((char *)atable[i].ha, hp, hl);
338*7c478bd9Sstevel@tonic-gate 			return (TRUE);
339*7c478bd9Sstevel@tonic-gate 		}
340*7c478bd9Sstevel@tonic-gate 	}
341*7c478bd9Sstevel@tonic-gate 
342*7c478bd9Sstevel@tonic-gate 	/* Not found. ARP for it. */
343*7c478bd9Sstevel@tonic-gate 	bzero(hp, hl);
344*7c478bd9Sstevel@tonic-gate 	result = mac_state.mac_arp(ip, hp, timeout);
345*7c478bd9Sstevel@tonic-gate 
346*7c478bd9Sstevel@tonic-gate 	if (result) {
347*7c478bd9Sstevel@tonic-gate 		/* Cool - add it to the arp table */
348*7c478bd9Sstevel@tonic-gate 		mac_set_arp(ip, hp, hl);
349*7c478bd9Sstevel@tonic-gate 	}
350*7c478bd9Sstevel@tonic-gate 	return (result);
351*7c478bd9Sstevel@tonic-gate }
352*7c478bd9Sstevel@tonic-gate 
353*7c478bd9Sstevel@tonic-gate int
354*7c478bd9Sstevel@tonic-gate mac_get_mtu(void)
355*7c478bd9Sstevel@tonic-gate {
356*7c478bd9Sstevel@tonic-gate 	if (!initialized)
357*7c478bd9Sstevel@tonic-gate 		return (-1);
358*7c478bd9Sstevel@tonic-gate 	else
359*7c478bd9Sstevel@tonic-gate 		return (mac_state.mac_mtu);
360*7c478bd9Sstevel@tonic-gate }
361*7c478bd9Sstevel@tonic-gate 
362*7c478bd9Sstevel@tonic-gate int
363*7c478bd9Sstevel@tonic-gate mac_get_dev(void)
364*7c478bd9Sstevel@tonic-gate {
365*7c478bd9Sstevel@tonic-gate 	if (!initialized)
366*7c478bd9Sstevel@tonic-gate 		return (-1);
367*7c478bd9Sstevel@tonic-gate 	else
368*7c478bd9Sstevel@tonic-gate 		return (mac_state.mac_dev);
369*7c478bd9Sstevel@tonic-gate }
370*7c478bd9Sstevel@tonic-gate 
371*7c478bd9Sstevel@tonic-gate uint8_t *
372*7c478bd9Sstevel@tonic-gate mac_get_addr_buf(void)
373*7c478bd9Sstevel@tonic-gate {
374*7c478bd9Sstevel@tonic-gate 	if (!initialized)
375*7c478bd9Sstevel@tonic-gate 		return (NULL);
376*7c478bd9Sstevel@tonic-gate 	else
377*7c478bd9Sstevel@tonic-gate 		return (mac_state.mac_addr_buf);
378*7c478bd9Sstevel@tonic-gate }
379*7c478bd9Sstevel@tonic-gate 
380*7c478bd9Sstevel@tonic-gate int
381*7c478bd9Sstevel@tonic-gate mac_get_addr_len(void)
382*7c478bd9Sstevel@tonic-gate {
383*7c478bd9Sstevel@tonic-gate 	if (!initialized)
384*7c478bd9Sstevel@tonic-gate 		return (-1);
385*7c478bd9Sstevel@tonic-gate 	else
386*7c478bd9Sstevel@tonic-gate 		return (mac_state.mac_addr_len);
387*7c478bd9Sstevel@tonic-gate }
388*7c478bd9Sstevel@tonic-gate 
389*7c478bd9Sstevel@tonic-gate int
390*7c478bd9Sstevel@tonic-gate mac_get_type(void)
391*7c478bd9Sstevel@tonic-gate {
392*7c478bd9Sstevel@tonic-gate 	if (!initialized)
393*7c478bd9Sstevel@tonic-gate 		return (-1);
394*7c478bd9Sstevel@tonic-gate 	else
395*7c478bd9Sstevel@tonic-gate 		return (mac_state.mac_type);
396*7c478bd9Sstevel@tonic-gate }
397*7c478bd9Sstevel@tonic-gate 
398*7c478bd9Sstevel@tonic-gate int
399*7c478bd9Sstevel@tonic-gate mac_get_arp_timeout(void)
400*7c478bd9Sstevel@tonic-gate {
401*7c478bd9Sstevel@tonic-gate 	if (!initialized)
402*7c478bd9Sstevel@tonic-gate 		return (-1);
403*7c478bd9Sstevel@tonic-gate 	else
404*7c478bd9Sstevel@tonic-gate 		return (mac_state.mac_arp_timeout);
405*7c478bd9Sstevel@tonic-gate }
406*7c478bd9Sstevel@tonic-gate 
407*7c478bd9Sstevel@tonic-gate int
408*7c478bd9Sstevel@tonic-gate mac_get_hdr_len(void)
409*7c478bd9Sstevel@tonic-gate {
410*7c478bd9Sstevel@tonic-gate 	if (!initialized)
411*7c478bd9Sstevel@tonic-gate 		return (-1);
412*7c478bd9Sstevel@tonic-gate 	else
413*7c478bd9Sstevel@tonic-gate 		return (mac_state.mac_header_len(NULL));
414*7c478bd9Sstevel@tonic-gate }
415*7c478bd9Sstevel@tonic-gate 
416*7c478bd9Sstevel@tonic-gate int
417*7c478bd9Sstevel@tonic-gate mac_call_arp(struct in_addr *addr, void *buf, uint32_t timeout)
418*7c478bd9Sstevel@tonic-gate {
419*7c478bd9Sstevel@tonic-gate 	return (mac_state.mac_arp(addr, buf, timeout));
420*7c478bd9Sstevel@tonic-gate }
421*7c478bd9Sstevel@tonic-gate 
422*7c478bd9Sstevel@tonic-gate void
423*7c478bd9Sstevel@tonic-gate mac_call_rarp(void)
424*7c478bd9Sstevel@tonic-gate {
425*7c478bd9Sstevel@tonic-gate 	mac_state.mac_rarp();
426*7c478bd9Sstevel@tonic-gate }
427*7c478bd9Sstevel@tonic-gate 
428*7c478bd9Sstevel@tonic-gate /*
429*7c478bd9Sstevel@tonic-gate  * Map a IFT_ type to an RFC 1700 arp hwtype.
430*7c478bd9Sstevel@tonic-gate  */
431*7c478bd9Sstevel@tonic-gate uint8_t
432*7c478bd9Sstevel@tonic-gate mac_arp_type(uint8_t ift_type)
433*7c478bd9Sstevel@tonic-gate {
434*7c478bd9Sstevel@tonic-gate 	uint8_t arptype;
435*7c478bd9Sstevel@tonic-gate 
436*7c478bd9Sstevel@tonic-gate 	switch (ift_type) {
437*7c478bd9Sstevel@tonic-gate 	case IFT_ISO88025:
438*7c478bd9Sstevel@tonic-gate 		arptype = 4;	/* token ring */
439*7c478bd9Sstevel@tonic-gate 		break;
440*7c478bd9Sstevel@tonic-gate 	case IFT_ATM:
441*7c478bd9Sstevel@tonic-gate 		arptype = 16;	/* ATM */
442*7c478bd9Sstevel@tonic-gate 		break;
443*7c478bd9Sstevel@tonic-gate 	case IFT_FDDI:
444*7c478bd9Sstevel@tonic-gate 		arptype = 18;	/* Fiber Channel */
445*7c478bd9Sstevel@tonic-gate 		break;
446*7c478bd9Sstevel@tonic-gate 	case IFT_IB:
447*7c478bd9Sstevel@tonic-gate 		arptype = 32;	/* Infiniband */
448*7c478bd9Sstevel@tonic-gate 		break;
449*7c478bd9Sstevel@tonic-gate 	case IFT_ETHER:
450*7c478bd9Sstevel@tonic-gate 		/* FALLTHRU */
451*7c478bd9Sstevel@tonic-gate 	default:
452*7c478bd9Sstevel@tonic-gate 		arptype = 1;	/* default to ethernet */
453*7c478bd9Sstevel@tonic-gate 		break;
454*7c478bd9Sstevel@tonic-gate 	}
455*7c478bd9Sstevel@tonic-gate 	return (arptype);
456*7c478bd9Sstevel@tonic-gate }
457