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 <dhcp_impl.h> 30*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 31*7c478bd9Sstevel@tonic-gate #include <socket_impl.h> 32*7c478bd9Sstevel@tonic-gate #include <socket_inet.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 <netinet/in_systm.h> 38*7c478bd9Sstevel@tonic-gate #include <netinet/in.h> 39*7c478bd9Sstevel@tonic-gate #include <netinet/ip.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 #include <sys/bootdebug.h> 45*7c478bd9Sstevel@tonic-gate #include <sys/ib/clients/ibd/ibd.h> 46*7c478bd9Sstevel@tonic-gate 47*7c478bd9Sstevel@tonic-gate #include "ipv4.h" 48*7c478bd9Sstevel@tonic-gate #include "dhcpv4.h" 49*7c478bd9Sstevel@tonic-gate #include "ipv4_impl.h" 50*7c478bd9Sstevel@tonic-gate #include "mac.h" 51*7c478bd9Sstevel@tonic-gate #include "mac_impl.h" 52*7c478bd9Sstevel@tonic-gate #include "ibd_inet.h" 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate struct ibd_arp { 55*7c478bd9Sstevel@tonic-gate struct arphdr ea_hdr; /* fixed-size header */ 56*7c478bd9Sstevel@tonic-gate ipoib_mac_t arp_sha; /* sender hardware address */ 57*7c478bd9Sstevel@tonic-gate uchar_t arp_spa[4]; /* sender protocol address */ 58*7c478bd9Sstevel@tonic-gate ipoib_mac_t arp_tha; /* target hardware address */ 59*7c478bd9Sstevel@tonic-gate uchar_t arp_tpa[4]; /* target protocol address */ 60*7c478bd9Sstevel@tonic-gate }; 61*7c478bd9Sstevel@tonic-gate 62*7c478bd9Sstevel@tonic-gate extern int errno; 63*7c478bd9Sstevel@tonic-gate ipoib_mac_t ibdbroadcastaddr; 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate /* 66*7c478bd9Sstevel@tonic-gate * Assumptions about OBP behavior (refer FWARC 2002/702, 2003/251): 67*7c478bd9Sstevel@tonic-gate * 1. prom_write() accepts the 20 byte destination address as the 68*7c478bd9Sstevel@tonic-gate * first component in the send buffer. The buffer pointer points 69*7c478bd9Sstevel@tonic-gate * to the start of this 20 byte address. The length parameter is 70*7c478bd9Sstevel@tonic-gate * the IPoIB datagram size with the 20 byte of destination 71*7c478bd9Sstevel@tonic-gate * address. 72*7c478bd9Sstevel@tonic-gate * 2. OBP will not provide max-frame-size, since obp can only 73*7c478bd9Sstevel@tonic-gate * determine that by querying the IBA mcg, and thus the property 74*7c478bd9Sstevel@tonic-gate * has to be /chosen:ipib-frame-size. This will refer to the IPoIB 75*7c478bd9Sstevel@tonic-gate * link MTU as per section 4.0 of ietf i/d, ie, the 4 byte IPoIB 76*7c478bd9Sstevel@tonic-gate * header plus the IP payload mtu. Plus the 20 bytes of addressing 77*7c478bd9Sstevel@tonic-gate * information. 78*7c478bd9Sstevel@tonic-gate * 3. OBP will not provide mac-address property for IPoIB since there 79*7c478bd9Sstevel@tonic-gate * are built in assumptions about 6 byte address with that. Instead, 80*7c478bd9Sstevel@tonic-gate * /chosen:ipib-address will provide the local address. 81*7c478bd9Sstevel@tonic-gate * 4. prom_read() returns 20 byte 0'ed filler followed by 4 byte 82*7c478bd9Sstevel@tonic-gate * IPoIB header followed by IP payload. The return value is -2, 83*7c478bd9Sstevel@tonic-gate * -1, 0, or the length of the received IPoIB datagram alongwith 84*7c478bd9Sstevel@tonic-gate * the 20 bytes MBZ. The buffer pointer points to the start of 85*7c478bd9Sstevel@tonic-gate * the 20 MBZ bytes. The length parameter reflects the max data 86*7c478bd9Sstevel@tonic-gate * size that should be copied into the buffer including the 20 87*7c478bd9Sstevel@tonic-gate * MBZ bytes. 88*7c478bd9Sstevel@tonic-gate * 5. OBP will not provide chosen-network-type, only 89*7c478bd9Sstevel@tonic-gate * network-interface-type = ipib. On an Infiniband device, this 90*7c478bd9Sstevel@tonic-gate * however does not guarantee that it is a network device. 91*7c478bd9Sstevel@tonic-gate * 6. OBP will provide the DHCP client id in /chosen:client-id. 92*7c478bd9Sstevel@tonic-gate * 7. /chosen:ipib-broadcast will provide the broadcast address. 93*7c478bd9Sstevel@tonic-gate * 8. OBP will validate that RARP is not being used before 94*7c478bd9Sstevel@tonic-gate * allowing boot to proceed to inetboot. 95*7c478bd9Sstevel@tonic-gate */ 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate struct arp_packet { 98*7c478bd9Sstevel@tonic-gate ipoib_ptxhdr_t arp_eh; 99*7c478bd9Sstevel@tonic-gate struct ibd_arp arp_ea; 100*7c478bd9Sstevel@tonic-gate }; 101*7c478bd9Sstevel@tonic-gate 102*7c478bd9Sstevel@tonic-gate #define dprintf if (boothowto & RB_DEBUG) printf 103*7c478bd9Sstevel@tonic-gate 104*7c478bd9Sstevel@tonic-gate static char * 105*7c478bd9Sstevel@tonic-gate ibd_print(ipoib_mac_t *ea) 106*7c478bd9Sstevel@tonic-gate { 107*7c478bd9Sstevel@tonic-gate unsigned char *macaddr = (unsigned char *)ea; 108*7c478bd9Sstevel@tonic-gate static char pbuf[(3 * IPOIB_ADDRL) + 1]; 109*7c478bd9Sstevel@tonic-gate int i; 110*7c478bd9Sstevel@tonic-gate char *ptr = pbuf; 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate ptr = pbuf + sprintf(pbuf, "%x", *macaddr++); 113*7c478bd9Sstevel@tonic-gate for (i = 0; i < (IPOIB_ADDRL - 1); i++) 114*7c478bd9Sstevel@tonic-gate ptr += sprintf(ptr, ":%x", *macaddr++); 115*7c478bd9Sstevel@tonic-gate return (pbuf); 116*7c478bd9Sstevel@tonic-gate } 117*7c478bd9Sstevel@tonic-gate 118*7c478bd9Sstevel@tonic-gate 119*7c478bd9Sstevel@tonic-gate /* 120*7c478bd9Sstevel@tonic-gate * Common ARP code. Broadcast the packet and wait for the right response. 121*7c478bd9Sstevel@tonic-gate * 122*7c478bd9Sstevel@tonic-gate * If arp is called for, caller expects a hardware address in the 123*7c478bd9Sstevel@tonic-gate * source hardware address (sha) field of the "out" argument. 124*7c478bd9Sstevel@tonic-gate * 125*7c478bd9Sstevel@tonic-gate * IPoIB does not support RARP (see ibd_revarp()). 126*7c478bd9Sstevel@tonic-gate * 127*7c478bd9Sstevel@tonic-gate * Returns TRUE if transaction succeeded, FALSE otherwise. 128*7c478bd9Sstevel@tonic-gate * 129*7c478bd9Sstevel@tonic-gate * The timeout argument is the number of milliseconds to wait for a 130*7c478bd9Sstevel@tonic-gate * response. An infinite timeout can be specified as 0xffffffff. 131*7c478bd9Sstevel@tonic-gate */ 132*7c478bd9Sstevel@tonic-gate static int 133*7c478bd9Sstevel@tonic-gate ibd_comarp(struct arp_packet *out, uint32_t timeout) 134*7c478bd9Sstevel@tonic-gate { 135*7c478bd9Sstevel@tonic-gate struct arp_packet *in = (struct arp_packet *)mac_state.mac_buf; 136*7c478bd9Sstevel@tonic-gate int count, time, feedback, len, delay = 2; 137*7c478bd9Sstevel@tonic-gate char *ind = "-\\|/"; 138*7c478bd9Sstevel@tonic-gate struct in_addr tmp_ia; 139*7c478bd9Sstevel@tonic-gate uint32_t wait_time; 140*7c478bd9Sstevel@tonic-gate 141*7c478bd9Sstevel@tonic-gate bcopy((caddr_t)&ibdbroadcastaddr, (caddr_t)&out->arp_eh.ipoib_dest, 142*7c478bd9Sstevel@tonic-gate IPOIB_ADDRL); 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate out->arp_ea.arp_hrd = htons(ARPHRD_IB); 145*7c478bd9Sstevel@tonic-gate out->arp_ea.arp_pro = htons(ETHERTYPE_IP); 146*7c478bd9Sstevel@tonic-gate out->arp_ea.arp_hln = IPOIB_ADDRL; 147*7c478bd9Sstevel@tonic-gate out->arp_ea.arp_pln = sizeof (struct in_addr); 148*7c478bd9Sstevel@tonic-gate bcopy(mac_state.mac_addr_buf, (caddr_t)&out->arp_ea.arp_sha, 149*7c478bd9Sstevel@tonic-gate IPOIB_ADDRL); 150*7c478bd9Sstevel@tonic-gate ipv4_getipaddr(&tmp_ia); 151*7c478bd9Sstevel@tonic-gate tmp_ia.s_addr = htonl(tmp_ia.s_addr); 152*7c478bd9Sstevel@tonic-gate bcopy((caddr_t)&tmp_ia, (caddr_t)out->arp_ea.arp_spa, 153*7c478bd9Sstevel@tonic-gate sizeof (struct in_addr)); 154*7c478bd9Sstevel@tonic-gate feedback = 0; 155*7c478bd9Sstevel@tonic-gate 156*7c478bd9Sstevel@tonic-gate wait_time = prom_gettime() + timeout; 157*7c478bd9Sstevel@tonic-gate for (count = 0; timeout == ~0U || prom_gettime() < wait_time; count++) { 158*7c478bd9Sstevel@tonic-gate if (count == IBD_WAITCNT) { 159*7c478bd9Sstevel@tonic-gate /* 160*7c478bd9Sstevel@tonic-gate * Since IPoIB does not support RARP (see ibd_revarp), 161*7c478bd9Sstevel@tonic-gate * we know that out->arp_ea.arp_op == ARPOP_REQUEST. 162*7c478bd9Sstevel@tonic-gate */ 163*7c478bd9Sstevel@tonic-gate bcopy((caddr_t)out->arp_ea.arp_tpa, 164*7c478bd9Sstevel@tonic-gate (caddr_t)&tmp_ia, sizeof (struct in_addr)); 165*7c478bd9Sstevel@tonic-gate printf("\nRequesting MAC address for: %s\n", 166*7c478bd9Sstevel@tonic-gate inet_ntoa(tmp_ia)); 167*7c478bd9Sstevel@tonic-gate } 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate (void) prom_write(mac_state.mac_dev, (caddr_t)out, 170*7c478bd9Sstevel@tonic-gate sizeof (*out), 0, NETWORK); 171*7c478bd9Sstevel@tonic-gate 172*7c478bd9Sstevel@tonic-gate if (count >= IBD_WAITCNT) 173*7c478bd9Sstevel@tonic-gate printf("%c\b", ind[feedback++ % 4]); /* activity */ 174*7c478bd9Sstevel@tonic-gate 175*7c478bd9Sstevel@tonic-gate time = prom_gettime() + (delay * 1000); /* broadcast delay */ 176*7c478bd9Sstevel@tonic-gate while (prom_gettime() <= time) { 177*7c478bd9Sstevel@tonic-gate len = prom_read(mac_state.mac_dev, mac_state.mac_buf, 178*7c478bd9Sstevel@tonic-gate mac_state.mac_mtu, 0, NETWORK); 179*7c478bd9Sstevel@tonic-gate if (len < sizeof (struct arp_packet)) 180*7c478bd9Sstevel@tonic-gate continue; 181*7c478bd9Sstevel@tonic-gate if (in->arp_ea.arp_pro != ntohs(ETHERTYPE_IP)) 182*7c478bd9Sstevel@tonic-gate continue; 183*7c478bd9Sstevel@tonic-gate /* 184*7c478bd9Sstevel@tonic-gate * Since IPoIB does not support RARP (see ibd_revarp), 185*7c478bd9Sstevel@tonic-gate * we know that out->arp_ea.arp_op == ARPOP_REQUEST. 186*7c478bd9Sstevel@tonic-gate */ 187*7c478bd9Sstevel@tonic-gate if (in->arp_eh.ipoib_rhdr.ipoib_type != 188*7c478bd9Sstevel@tonic-gate ntohs(ETHERTYPE_ARP)) 189*7c478bd9Sstevel@tonic-gate continue; 190*7c478bd9Sstevel@tonic-gate if (in->arp_ea.arp_op != ntohs(ARPOP_REPLY)) 191*7c478bd9Sstevel@tonic-gate continue; 192*7c478bd9Sstevel@tonic-gate if (bcmp((caddr_t)in->arp_ea.arp_spa, 193*7c478bd9Sstevel@tonic-gate (caddr_t)out->arp_ea.arp_tpa, 194*7c478bd9Sstevel@tonic-gate sizeof (struct in_addr)) != 0) 195*7c478bd9Sstevel@tonic-gate continue; 196*7c478bd9Sstevel@tonic-gate if (boothowto & RB_VERBOSE) { 197*7c478bd9Sstevel@tonic-gate bcopy((caddr_t)in->arp_ea.arp_spa, 198*7c478bd9Sstevel@tonic-gate (caddr_t)&tmp_ia, 199*7c478bd9Sstevel@tonic-gate sizeof (struct in_addr)); 200*7c478bd9Sstevel@tonic-gate printf("Found %s @ %s\n", 201*7c478bd9Sstevel@tonic-gate inet_ntoa(tmp_ia), 202*7c478bd9Sstevel@tonic-gate ibd_print(&in->arp_ea.arp_sha)); 203*7c478bd9Sstevel@tonic-gate } 204*7c478bd9Sstevel@tonic-gate /* copy hardware addr into "out" for caller */ 205*7c478bd9Sstevel@tonic-gate bcopy((caddr_t)&in->arp_ea.arp_sha, 206*7c478bd9Sstevel@tonic-gate (caddr_t)&out->arp_ea.arp_sha, IPOIB_ADDRL); 207*7c478bd9Sstevel@tonic-gate return (TRUE); 208*7c478bd9Sstevel@tonic-gate } 209*7c478bd9Sstevel@tonic-gate 210*7c478bd9Sstevel@tonic-gate delay = delay * 2; /* Double the request delay */ 211*7c478bd9Sstevel@tonic-gate if (delay > 64) /* maximum delay is 64 seconds */ 212*7c478bd9Sstevel@tonic-gate delay = 64; 213*7c478bd9Sstevel@tonic-gate } 214*7c478bd9Sstevel@tonic-gate return (FALSE); 215*7c478bd9Sstevel@tonic-gate } 216*7c478bd9Sstevel@tonic-gate 217*7c478bd9Sstevel@tonic-gate /* 218*7c478bd9Sstevel@tonic-gate * ARP client side 219*7c478bd9Sstevel@tonic-gate * Broadcasts to determine MAC address given network order IP address. 220*7c478bd9Sstevel@tonic-gate * See RFC 826 221*7c478bd9Sstevel@tonic-gate * 222*7c478bd9Sstevel@tonic-gate * Returns TRUE if successful, FALSE otherwise. 223*7c478bd9Sstevel@tonic-gate */ 224*7c478bd9Sstevel@tonic-gate static int 225*7c478bd9Sstevel@tonic-gate ibd_arp(struct in_addr *ip, void *hap, uint32_t timeout) 226*7c478bd9Sstevel@tonic-gate { 227*7c478bd9Sstevel@tonic-gate ipoib_mac_t *ep = (ipoib_mac_t *)hap; 228*7c478bd9Sstevel@tonic-gate struct arp_packet out; 229*7c478bd9Sstevel@tonic-gate int result; 230*7c478bd9Sstevel@tonic-gate 231*7c478bd9Sstevel@tonic-gate if (!initialized) 232*7c478bd9Sstevel@tonic-gate prom_panic("IPoIB device is not initialized."); 233*7c478bd9Sstevel@tonic-gate 234*7c478bd9Sstevel@tonic-gate bzero((char *)&out, sizeof (struct arp_packet)); 235*7c478bd9Sstevel@tonic-gate 236*7c478bd9Sstevel@tonic-gate out.arp_eh.ipoib_rhdr.ipoib_type = htons(ETHERTYPE_ARP); 237*7c478bd9Sstevel@tonic-gate out.arp_ea.arp_op = htons(ARPOP_REQUEST); 238*7c478bd9Sstevel@tonic-gate bcopy((caddr_t)&ibdbroadcastaddr, (caddr_t)&out.arp_ea.arp_tha, 239*7c478bd9Sstevel@tonic-gate IPOIB_ADDRL); 240*7c478bd9Sstevel@tonic-gate bcopy((caddr_t)ip, (caddr_t)out.arp_ea.arp_tpa, 241*7c478bd9Sstevel@tonic-gate sizeof (struct in_addr)); 242*7c478bd9Sstevel@tonic-gate 243*7c478bd9Sstevel@tonic-gate result = ibd_comarp(&out, timeout); 244*7c478bd9Sstevel@tonic-gate 245*7c478bd9Sstevel@tonic-gate if (result && (ep != NULL)) { 246*7c478bd9Sstevel@tonic-gate bcopy((caddr_t)&out.arp_ea.arp_sha, (caddr_t)ep, IPOIB_ADDRL); 247*7c478bd9Sstevel@tonic-gate } 248*7c478bd9Sstevel@tonic-gate return (result); 249*7c478bd9Sstevel@tonic-gate } 250*7c478bd9Sstevel@tonic-gate 251*7c478bd9Sstevel@tonic-gate /* 252*7c478bd9Sstevel@tonic-gate * Reverse ARP client side 253*7c478bd9Sstevel@tonic-gate * Determine our Internet address given our MAC address 254*7c478bd9Sstevel@tonic-gate * See RFC 903 255*7c478bd9Sstevel@tonic-gate */ 256*7c478bd9Sstevel@tonic-gate static void 257*7c478bd9Sstevel@tonic-gate ibd_revarp(void) 258*7c478bd9Sstevel@tonic-gate { 259*7c478bd9Sstevel@tonic-gate prom_panic("IPoIB can not boot with RARP."); 260*7c478bd9Sstevel@tonic-gate } 261*7c478bd9Sstevel@tonic-gate 262*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 263*7c478bd9Sstevel@tonic-gate static int 264*7c478bd9Sstevel@tonic-gate ibd_header_len(struct inetgram *igm) 265*7c478bd9Sstevel@tonic-gate { 266*7c478bd9Sstevel@tonic-gate /* 267*7c478bd9Sstevel@tonic-gate * We indicate to upper layers to leave enough space 268*7c478bd9Sstevel@tonic-gate * in output buffers for filling in the IPoIB header 269*7c478bd9Sstevel@tonic-gate * and the 20 byte destination address in ibd_output(). 270*7c478bd9Sstevel@tonic-gate */ 271*7c478bd9Sstevel@tonic-gate return (IPOIB_HDRSIZE + IPOIB_ADDRL); 272*7c478bd9Sstevel@tonic-gate } 273*7c478bd9Sstevel@tonic-gate 274*7c478bd9Sstevel@tonic-gate /* 275*7c478bd9Sstevel@tonic-gate * Handle a IP datagram addressed to our MAC address or to the link 276*7c478bd9Sstevel@tonic-gate * layer broadcast address. Also respond to ARP requests. Generates 277*7c478bd9Sstevel@tonic-gate * inetgrams as long as there's data and the mac level IP timeout timer 278*7c478bd9Sstevel@tonic-gate * hasn't expired. As soon as there is no data, we try for 279*7c478bd9Sstevel@tonic-gate * IBD_INPUT_ATTEMPTS for more, then exit the loop, even if there is time 280*7c478bd9Sstevel@tonic-gate * left, since we expect to have data waiting for us when we're called, we just 281*7c478bd9Sstevel@tonic-gate * don't know how much. 282*7c478bd9Sstevel@tonic-gate * 283*7c478bd9Sstevel@tonic-gate * We workaround slow proms (some proms have hard sleeps for as much as 3msec) 284*7c478bd9Sstevel@tonic-gate * even though there are is data waiting. 285*7c478bd9Sstevel@tonic-gate * 286*7c478bd9Sstevel@tonic-gate * Returns the total number of MEDIA_LVL frames placed on the socket. 287*7c478bd9Sstevel@tonic-gate * Caller is expected to free up the inetgram resources. 288*7c478bd9Sstevel@tonic-gate */ 289*7c478bd9Sstevel@tonic-gate static int 290*7c478bd9Sstevel@tonic-gate ibd_input(int index) 291*7c478bd9Sstevel@tonic-gate { 292*7c478bd9Sstevel@tonic-gate struct inetgram *inp; 293*7c478bd9Sstevel@tonic-gate ipoib_ptxhdr_t *eh; 294*7c478bd9Sstevel@tonic-gate int frames = 0; /* successful frames */ 295*7c478bd9Sstevel@tonic-gate int attempts = 0; /* failed attempts after success */ 296*7c478bd9Sstevel@tonic-gate int16_t len = 0, data_len; 297*7c478bd9Sstevel@tonic-gate uint32_t timeout, reltime; 298*7c478bd9Sstevel@tonic-gate uint32_t pre_pr, post_pr; /* prom_read interval */ 299*7c478bd9Sstevel@tonic-gate 300*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 301*7c478bd9Sstevel@tonic-gate int failures = 0; /* total failures */ 302*7c478bd9Sstevel@tonic-gate int total_attempts = 0; /* total prom_read */ 303*7c478bd9Sstevel@tonic-gate int no_data = 0; /* no data in prom */ 304*7c478bd9Sstevel@tonic-gate int arps = 0; /* arp requests processed */ 305*7c478bd9Sstevel@tonic-gate uint32_t tot_pr = 0; /* prom_read time */ 306*7c478bd9Sstevel@tonic-gate uint32_t tot_pc = 0; /* inetgram creation time */ 307*7c478bd9Sstevel@tonic-gate uint32_t pre_pc; 308*7c478bd9Sstevel@tonic-gate uint32_t now; 309*7c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 310*7c478bd9Sstevel@tonic-gate 311*7c478bd9Sstevel@tonic-gate if (!initialized) 312*7c478bd9Sstevel@tonic-gate prom_panic("IPoIB device is not initialized."); 313*7c478bd9Sstevel@tonic-gate 314*7c478bd9Sstevel@tonic-gate if ((reltime = sockets[index].in_timeout) == 0) 315*7c478bd9Sstevel@tonic-gate reltime = mac_state.mac_in_timeout; 316*7c478bd9Sstevel@tonic-gate timeout = prom_gettime() + reltime; 317*7c478bd9Sstevel@tonic-gate 318*7c478bd9Sstevel@tonic-gate do { 319*7c478bd9Sstevel@tonic-gate if (frames > IBD_MAX_FRAMES) { 320*7c478bd9Sstevel@tonic-gate /* someone is trying a denial of service attack */ 321*7c478bd9Sstevel@tonic-gate break; 322*7c478bd9Sstevel@tonic-gate } 323*7c478bd9Sstevel@tonic-gate 324*7c478bd9Sstevel@tonic-gate /* 325*7c478bd9Sstevel@tonic-gate * The following is being paranoid about possible bugs 326*7c478bd9Sstevel@tonic-gate * where prom_read() returns a nonzero length, even when 327*7c478bd9Sstevel@tonic-gate * it's not read a packet; it zeroes out the header to 328*7c478bd9Sstevel@tonic-gate * compensate. Paranoia from calvin prom (V2) days. 329*7c478bd9Sstevel@tonic-gate */ 330*7c478bd9Sstevel@tonic-gate bzero(mac_state.mac_buf, sizeof (ipoib_ptxhdr_t)); 331*7c478bd9Sstevel@tonic-gate 332*7c478bd9Sstevel@tonic-gate /* 333*7c478bd9Sstevel@tonic-gate * Prom_read() will return 0 or -2 if no data is present. A 334*7c478bd9Sstevel@tonic-gate * return value of -1 means an error has occurred. We adjust 335*7c478bd9Sstevel@tonic-gate * the timeout by calling the time spent in prom_read() "free". 336*7c478bd9Sstevel@tonic-gate * prom_read() returns the number of bytes actually read, but 337*7c478bd9Sstevel@tonic-gate * will only copy "len" bytes into our buffer. Adjust in 338*7c478bd9Sstevel@tonic-gate * case the MTU is wrong. 339*7c478bd9Sstevel@tonic-gate */ 340*7c478bd9Sstevel@tonic-gate pre_pr = prom_gettime(); 341*7c478bd9Sstevel@tonic-gate len = prom_read(mac_state.mac_dev, mac_state.mac_buf, 342*7c478bd9Sstevel@tonic-gate mac_state.mac_mtu, 0, NETWORK); 343*7c478bd9Sstevel@tonic-gate post_pr = prom_gettime(); 344*7c478bd9Sstevel@tonic-gate timeout += (post_pr - pre_pr); 345*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 346*7c478bd9Sstevel@tonic-gate tot_pr += (post_pr - pre_pr); 347*7c478bd9Sstevel@tonic-gate total_attempts++; 348*7c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 349*7c478bd9Sstevel@tonic-gate 350*7c478bd9Sstevel@tonic-gate if (len > mac_state.mac_mtu) { 351*7c478bd9Sstevel@tonic-gate dprintf("ibd_input: adjusting MTU %d -> %d\n", 352*7c478bd9Sstevel@tonic-gate mac_state.mac_mtu, len); 353*7c478bd9Sstevel@tonic-gate bkmem_free(mac_state.mac_buf, mac_state.mac_mtu); 354*7c478bd9Sstevel@tonic-gate mac_state.mac_mtu = len; 355*7c478bd9Sstevel@tonic-gate mac_state.mac_buf = bkmem_alloc(mac_state.mac_mtu); 356*7c478bd9Sstevel@tonic-gate if (mac_state.mac_buf == NULL) { 357*7c478bd9Sstevel@tonic-gate prom_panic("ibd_input: Cannot reallocate " 358*7c478bd9Sstevel@tonic-gate "netbuf memory."); 359*7c478bd9Sstevel@tonic-gate } 360*7c478bd9Sstevel@tonic-gate len = 0; /* pretend there was no data */ 361*7c478bd9Sstevel@tonic-gate } 362*7c478bd9Sstevel@tonic-gate 363*7c478bd9Sstevel@tonic-gate if (len == -1) { 364*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 365*7c478bd9Sstevel@tonic-gate failures++; 366*7c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 367*7c478bd9Sstevel@tonic-gate break; 368*7c478bd9Sstevel@tonic-gate } 369*7c478bd9Sstevel@tonic-gate if (len == 0 || len == -2) { 370*7c478bd9Sstevel@tonic-gate if (frames != 0) 371*7c478bd9Sstevel@tonic-gate attempts++; 372*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 373*7c478bd9Sstevel@tonic-gate no_data++; 374*7c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 375*7c478bd9Sstevel@tonic-gate continue; 376*7c478bd9Sstevel@tonic-gate } 377*7c478bd9Sstevel@tonic-gate 378*7c478bd9Sstevel@tonic-gate eh = (ipoib_ptxhdr_t *)mac_state.mac_buf; 379*7c478bd9Sstevel@tonic-gate if (eh->ipoib_rhdr.ipoib_type == ntohs(ETHERTYPE_IP) && 380*7c478bd9Sstevel@tonic-gate len >= (sizeof (ipoib_ptxhdr_t) + sizeof (struct ip))) { 381*7c478bd9Sstevel@tonic-gate 382*7c478bd9Sstevel@tonic-gate int offset; 383*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 384*7c478bd9Sstevel@tonic-gate pre_pc = prom_gettime(); 385*7c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 386*7c478bd9Sstevel@tonic-gate 387*7c478bd9Sstevel@tonic-gate inp = (struct inetgram *)bkmem_zalloc( 388*7c478bd9Sstevel@tonic-gate sizeof (struct inetgram)); 389*7c478bd9Sstevel@tonic-gate if (inp == NULL) { 390*7c478bd9Sstevel@tonic-gate errno = ENOMEM; 391*7c478bd9Sstevel@tonic-gate return (frames == 0 ? -1 : frames); 392*7c478bd9Sstevel@tonic-gate } 393*7c478bd9Sstevel@tonic-gate offset = sizeof (ipoib_ptxhdr_t); 394*7c478bd9Sstevel@tonic-gate data_len = len - offset; 395*7c478bd9Sstevel@tonic-gate inp->igm_mp = allocb(data_len, 0); 396*7c478bd9Sstevel@tonic-gate if (inp->igm_mp == NULL) { 397*7c478bd9Sstevel@tonic-gate errno = ENOMEM; 398*7c478bd9Sstevel@tonic-gate bkmem_free((caddr_t)inp, 399*7c478bd9Sstevel@tonic-gate sizeof (struct inetgram)); 400*7c478bd9Sstevel@tonic-gate return (frames == 0 ? -1 : frames); 401*7c478bd9Sstevel@tonic-gate } 402*7c478bd9Sstevel@tonic-gate bcopy((caddr_t)(mac_state.mac_buf + offset), 403*7c478bd9Sstevel@tonic-gate inp->igm_mp->b_rptr, data_len); 404*7c478bd9Sstevel@tonic-gate inp->igm_mp->b_wptr += data_len; 405*7c478bd9Sstevel@tonic-gate inp->igm_level = NETWORK_LVL; 406*7c478bd9Sstevel@tonic-gate add_grams(&sockets[index].inq, inp); 407*7c478bd9Sstevel@tonic-gate frames++; 408*7c478bd9Sstevel@tonic-gate attempts = 0; 409*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 410*7c478bd9Sstevel@tonic-gate tot_pc += prom_gettime() - pre_pc; 411*7c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 412*7c478bd9Sstevel@tonic-gate continue; 413*7c478bd9Sstevel@tonic-gate } 414*7c478bd9Sstevel@tonic-gate 415*7c478bd9Sstevel@tonic-gate if (eh->ipoib_rhdr.ipoib_type == ntohs(ETHERTYPE_ARP) && 416*7c478bd9Sstevel@tonic-gate len >= sizeof (struct arp_packet)) { 417*7c478bd9Sstevel@tonic-gate 418*7c478bd9Sstevel@tonic-gate struct in_addr ip; 419*7c478bd9Sstevel@tonic-gate struct ibd_arp *ea; 420*7c478bd9Sstevel@tonic-gate 421*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 422*7c478bd9Sstevel@tonic-gate printf("ibd_input: ARP message received\n"); 423*7c478bd9Sstevel@tonic-gate arps++; 424*7c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 425*7c478bd9Sstevel@tonic-gate 426*7c478bd9Sstevel@tonic-gate ea = (struct ibd_arp *)(mac_state.mac_buf + 427*7c478bd9Sstevel@tonic-gate sizeof (ipoib_ptxhdr_t)); 428*7c478bd9Sstevel@tonic-gate if (ea->arp_pro != ntohs(ETHERTYPE_IP)) 429*7c478bd9Sstevel@tonic-gate continue; 430*7c478bd9Sstevel@tonic-gate 431*7c478bd9Sstevel@tonic-gate ipv4_getipaddr(&ip); 432*7c478bd9Sstevel@tonic-gate ip.s_addr = ntohl(ip.s_addr); 433*7c478bd9Sstevel@tonic-gate 434*7c478bd9Sstevel@tonic-gate if (ea->arp_op == ntohs(ARPOP_REQUEST) && 435*7c478bd9Sstevel@tonic-gate ip.s_addr != INADDR_ANY && 436*7c478bd9Sstevel@tonic-gate (bcmp((caddr_t)ea->arp_tpa, (caddr_t)&ip, 437*7c478bd9Sstevel@tonic-gate sizeof (struct in_addr)) == 0)) { 438*7c478bd9Sstevel@tonic-gate ea->arp_op = htons(ARPOP_REPLY); 439*7c478bd9Sstevel@tonic-gate bcopy((caddr_t)&ea->arp_sha, 440*7c478bd9Sstevel@tonic-gate (caddr_t)&eh->ipoib_dest, IPOIB_ADDRL); 441*7c478bd9Sstevel@tonic-gate bcopy((caddr_t)&ea->arp_sha, 442*7c478bd9Sstevel@tonic-gate (caddr_t)&ea->arp_tha, IPOIB_ADDRL); 443*7c478bd9Sstevel@tonic-gate bcopy((caddr_t)ea->arp_spa, 444*7c478bd9Sstevel@tonic-gate (caddr_t)ea->arp_tpa, 445*7c478bd9Sstevel@tonic-gate sizeof (struct in_addr)); 446*7c478bd9Sstevel@tonic-gate bcopy(mac_state.mac_addr_buf, 447*7c478bd9Sstevel@tonic-gate (caddr_t)&ea->arp_sha, 448*7c478bd9Sstevel@tonic-gate mac_state.mac_addr_len); 449*7c478bd9Sstevel@tonic-gate bcopy((caddr_t)&ip, (caddr_t)ea->arp_spa, 450*7c478bd9Sstevel@tonic-gate sizeof (struct in_addr)); 451*7c478bd9Sstevel@tonic-gate (void) prom_write(mac_state.mac_dev, 452*7c478bd9Sstevel@tonic-gate mac_state.mac_buf, 453*7c478bd9Sstevel@tonic-gate sizeof (struct arp_packet), 0, NETWORK); 454*7c478bd9Sstevel@tonic-gate /* don't charge for ARP replies */ 455*7c478bd9Sstevel@tonic-gate timeout += reltime; 456*7c478bd9Sstevel@tonic-gate } 457*7c478bd9Sstevel@tonic-gate } 458*7c478bd9Sstevel@tonic-gate } while (attempts < IBD_INPUT_ATTEMPTS && 459*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 460*7c478bd9Sstevel@tonic-gate (now = prom_gettime()) < timeout); 461*7c478bd9Sstevel@tonic-gate #else 462*7c478bd9Sstevel@tonic-gate prom_gettime() < timeout); 463*7c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 464*7c478bd9Sstevel@tonic-gate 465*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 466*7c478bd9Sstevel@tonic-gate printf("ibd_input(%d): T/S/N/A/F/P/M: %d/%d/%d/%d/%d/%d/%d " 467*7c478bd9Sstevel@tonic-gate "T/O: %d < %d = %s\n", index, total_attempts, frames, no_data, 468*7c478bd9Sstevel@tonic-gate arps, failures, tot_pr, tot_pc, now, timeout, 469*7c478bd9Sstevel@tonic-gate (now < timeout) ? "TRUE" : "FALSE"); 470*7c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 471*7c478bd9Sstevel@tonic-gate return (frames); 472*7c478bd9Sstevel@tonic-gate } 473*7c478bd9Sstevel@tonic-gate 474*7c478bd9Sstevel@tonic-gate /* 475*7c478bd9Sstevel@tonic-gate * Send out an IPoIB datagram. We expect a IP frame appropriately fragmented 476*7c478bd9Sstevel@tonic-gate * at this level. 477*7c478bd9Sstevel@tonic-gate * 478*7c478bd9Sstevel@tonic-gate * Errno is set and -1 is returned if an error occurs. Number of bytes sent 479*7c478bd9Sstevel@tonic-gate * is returned on success. 480*7c478bd9Sstevel@tonic-gate */ 481*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 482*7c478bd9Sstevel@tonic-gate static int 483*7c478bd9Sstevel@tonic-gate ibd_output(int index, struct inetgram *ogp) 484*7c478bd9Sstevel@tonic-gate { 485*7c478bd9Sstevel@tonic-gate int header_len, result; 486*7c478bd9Sstevel@tonic-gate ipoib_ptxhdr_t eh; 487*7c478bd9Sstevel@tonic-gate struct ip *ip; 488*7c478bd9Sstevel@tonic-gate struct in_addr tmpip, ipdst; 489*7c478bd9Sstevel@tonic-gate int broadcast = FALSE; 490*7c478bd9Sstevel@tonic-gate int size; 491*7c478bd9Sstevel@tonic-gate mblk_t *mp; 492*7c478bd9Sstevel@tonic-gate 493*7c478bd9Sstevel@tonic-gate if (!initialized) 494*7c478bd9Sstevel@tonic-gate prom_panic("IPoIB device is not initialized."); 495*7c478bd9Sstevel@tonic-gate 496*7c478bd9Sstevel@tonic-gate if (ogp->igm_level != MEDIA_LVL) { 497*7c478bd9Sstevel@tonic-gate dprintf("ibd_output: frame type wrong: socket: %d\n", 498*7c478bd9Sstevel@tonic-gate index * SOCKETTYPE); 499*7c478bd9Sstevel@tonic-gate errno = EINVAL; 500*7c478bd9Sstevel@tonic-gate return (-1); 501*7c478bd9Sstevel@tonic-gate } 502*7c478bd9Sstevel@tonic-gate 503*7c478bd9Sstevel@tonic-gate header_len = IPOIB_HDRSIZE + IPOIB_ADDRL; 504*7c478bd9Sstevel@tonic-gate mp = ogp->igm_mp; 505*7c478bd9Sstevel@tonic-gate size = mp->b_wptr - mp->b_rptr; 506*7c478bd9Sstevel@tonic-gate if (size > (mac_state.mac_mtu - IPOIB_ADDRL)) { 507*7c478bd9Sstevel@tonic-gate dprintf("ibd_output: frame size too big: %d\n", size); 508*7c478bd9Sstevel@tonic-gate errno = E2BIG; 509*7c478bd9Sstevel@tonic-gate return (-1); 510*7c478bd9Sstevel@tonic-gate } 511*7c478bd9Sstevel@tonic-gate 512*7c478bd9Sstevel@tonic-gate size += header_len; 513*7c478bd9Sstevel@tonic-gate ip = (struct ip *)(mp->b_rptr); 514*7c478bd9Sstevel@tonic-gate 515*7c478bd9Sstevel@tonic-gate eh.ipoib_rhdr.ipoib_type = htons(ETHERTYPE_IP); 516*7c478bd9Sstevel@tonic-gate eh.ipoib_rhdr.ipoib_mbz = 0; 517*7c478bd9Sstevel@tonic-gate bcopy((caddr_t)&ip->ip_dst, (caddr_t)&ipdst, sizeof (ipdst)); 518*7c478bd9Sstevel@tonic-gate 519*7c478bd9Sstevel@tonic-gate if (ipdst.s_addr == htonl(INADDR_BROADCAST)) 520*7c478bd9Sstevel@tonic-gate broadcast = TRUE; /* limited broadcast */ 521*7c478bd9Sstevel@tonic-gate 522*7c478bd9Sstevel@tonic-gate if (!broadcast) { 523*7c478bd9Sstevel@tonic-gate struct in_addr mask; 524*7c478bd9Sstevel@tonic-gate 525*7c478bd9Sstevel@tonic-gate ipv4_getnetmask(&mask); 526*7c478bd9Sstevel@tonic-gate mask.s_addr = htonl(mask.s_addr); 527*7c478bd9Sstevel@tonic-gate if (mask.s_addr != htonl(INADDR_BROADCAST) && 528*7c478bd9Sstevel@tonic-gate (ipdst.s_addr & ~mask.s_addr) == 0) { 529*7c478bd9Sstevel@tonic-gate broadcast = TRUE; /* directed broadcast */ 530*7c478bd9Sstevel@tonic-gate } else { 531*7c478bd9Sstevel@tonic-gate if (ogp->igm_router.s_addr != htonl(INADDR_ANY)) 532*7c478bd9Sstevel@tonic-gate tmpip.s_addr = ogp->igm_router.s_addr; 533*7c478bd9Sstevel@tonic-gate else 534*7c478bd9Sstevel@tonic-gate tmpip.s_addr = ipdst.s_addr; 535*7c478bd9Sstevel@tonic-gate 536*7c478bd9Sstevel@tonic-gate result = mac_get_arp(&tmpip, (void *)&eh.ipoib_dest, 537*7c478bd9Sstevel@tonic-gate IPOIB_ADDRL, mac_state.mac_arp_timeout); 538*7c478bd9Sstevel@tonic-gate if (!result) { 539*7c478bd9Sstevel@tonic-gate errno = ETIMEDOUT; 540*7c478bd9Sstevel@tonic-gate dprintf("ibd_output: ARP request for %s " 541*7c478bd9Sstevel@tonic-gate "timed out.\n", inet_ntoa(tmpip)); 542*7c478bd9Sstevel@tonic-gate return (-1); 543*7c478bd9Sstevel@tonic-gate } 544*7c478bd9Sstevel@tonic-gate } 545*7c478bd9Sstevel@tonic-gate } 546*7c478bd9Sstevel@tonic-gate 547*7c478bd9Sstevel@tonic-gate if (broadcast) 548*7c478bd9Sstevel@tonic-gate bcopy((caddr_t)&ibdbroadcastaddr, (caddr_t)&eh.ipoib_dest, 549*7c478bd9Sstevel@tonic-gate IPOIB_ADDRL); 550*7c478bd9Sstevel@tonic-gate 551*7c478bd9Sstevel@tonic-gate /* add the ibd header */ 552*7c478bd9Sstevel@tonic-gate mp->b_rptr -= sizeof (eh); 553*7c478bd9Sstevel@tonic-gate bcopy((caddr_t)&eh, mp->b_rptr, sizeof (eh)); 554*7c478bd9Sstevel@tonic-gate 555*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 556*7c478bd9Sstevel@tonic-gate printf("ibd_output(%d): level(%d) frame(0x%x) len(%d)\n", 557*7c478bd9Sstevel@tonic-gate index, ogp->igm_level, mp->b_rptr, size); 558*7c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 559*7c478bd9Sstevel@tonic-gate 560*7c478bd9Sstevel@tonic-gate return (prom_write(mac_state.mac_dev, (char *)mp->b_rptr, size, 561*7c478bd9Sstevel@tonic-gate 0, NETWORK)); 562*7c478bd9Sstevel@tonic-gate } 563*7c478bd9Sstevel@tonic-gate 564*7c478bd9Sstevel@tonic-gate void 565*7c478bd9Sstevel@tonic-gate ibd_init(void) 566*7c478bd9Sstevel@tonic-gate { 567*7c478bd9Sstevel@tonic-gate dnode_t chosen; 568*7c478bd9Sstevel@tonic-gate char *mtuprop = "ipib-frame-size"; 569*7c478bd9Sstevel@tonic-gate char *bcastprop = "ipib-broadcast"; 570*7c478bd9Sstevel@tonic-gate char *addrprop = "ipib-address"; 571*7c478bd9Sstevel@tonic-gate char *cidprop = "client-id"; 572*7c478bd9Sstevel@tonic-gate int cidlen; 573*7c478bd9Sstevel@tonic-gate uint8_t dhcpcid[DHCP_MAX_CID_LEN]; 574*7c478bd9Sstevel@tonic-gate 575*7c478bd9Sstevel@tonic-gate mac_state.mac_addr_len = IPOIB_ADDRL; 576*7c478bd9Sstevel@tonic-gate mac_state.mac_addr_buf = bkmem_alloc(mac_state.mac_addr_len); 577*7c478bd9Sstevel@tonic-gate if (mac_state.mac_addr_buf == NULL) 578*7c478bd9Sstevel@tonic-gate prom_panic("ibd_init: Cannot allocate memory."); 579*7c478bd9Sstevel@tonic-gate 580*7c478bd9Sstevel@tonic-gate chosen = prom_finddevice("/chosen"); 581*7c478bd9Sstevel@tonic-gate if (chosen == OBP_NONODE || chosen == OBP_BADNODE) 582*7c478bd9Sstevel@tonic-gate prom_panic("ibd_init: Cannot find /chosen."); 583*7c478bd9Sstevel@tonic-gate 584*7c478bd9Sstevel@tonic-gate if (prom_getprop(chosen, addrprop, (caddr_t)mac_state.mac_addr_buf) != 585*7c478bd9Sstevel@tonic-gate IPOIB_ADDRL) 586*7c478bd9Sstevel@tonic-gate prom_panic("ibd_init: Cannot find /chosen:ipib-address\n."); 587*7c478bd9Sstevel@tonic-gate 588*7c478bd9Sstevel@tonic-gate if (prom_getprop(chosen, bcastprop, (caddr_t)&ibdbroadcastaddr) != 589*7c478bd9Sstevel@tonic-gate IPOIB_ADDRL) 590*7c478bd9Sstevel@tonic-gate prom_panic("ibd_init: Cannot find /chosen:ipib-broadcast\n."); 591*7c478bd9Sstevel@tonic-gate 592*7c478bd9Sstevel@tonic-gate if (((cidlen = prom_getproplen(chosen, cidprop)) <= 0) || 593*7c478bd9Sstevel@tonic-gate (cidlen > DHCP_MAX_CID_LEN) || (prom_getprop(chosen, cidprop, 594*7c478bd9Sstevel@tonic-gate (caddr_t)&dhcpcid) != cidlen)) 595*7c478bd9Sstevel@tonic-gate prom_panic("ibd_init: Invalid /chosen:client-id\n."); 596*7c478bd9Sstevel@tonic-gate dhcp_set_client_id(dhcpcid, cidlen); 597*7c478bd9Sstevel@tonic-gate 598*7c478bd9Sstevel@tonic-gate /* 599*7c478bd9Sstevel@tonic-gate * Note that prom reports mtu including 20 bytes of 600*7c478bd9Sstevel@tonic-gate * addressing information. 601*7c478bd9Sstevel@tonic-gate */ 602*7c478bd9Sstevel@tonic-gate if (prom_getprop(chosen, mtuprop, 603*7c478bd9Sstevel@tonic-gate (caddr_t)&mac_state.mac_mtu) <= 0) 604*7c478bd9Sstevel@tonic-gate mac_state.mac_mtu = IBDSIZE + IPOIB_ADDRL; 605*7c478bd9Sstevel@tonic-gate 606*7c478bd9Sstevel@tonic-gate /* 607*7c478bd9Sstevel@tonic-gate * Tell upper layers that we can support a little 608*7c478bd9Sstevel@tonic-gate * more. We will be taking off these 20 bytes at 609*7c478bd9Sstevel@tonic-gate * the start before we invoke prom_write() to send 610*7c478bd9Sstevel@tonic-gate * over the wire. 611*7c478bd9Sstevel@tonic-gate */ 612*7c478bd9Sstevel@tonic-gate mac_state.mac_arp_timeout = IBD_ARP_TIMEOUT; 613*7c478bd9Sstevel@tonic-gate mac_state.mac_in_timeout = IBD_IN_TIMEOUT; 614*7c478bd9Sstevel@tonic-gate 615*7c478bd9Sstevel@tonic-gate mac_state.mac_arp = ibd_arp; 616*7c478bd9Sstevel@tonic-gate mac_state.mac_rarp = ibd_revarp; 617*7c478bd9Sstevel@tonic-gate mac_state.mac_header_len = ibd_header_len; 618*7c478bd9Sstevel@tonic-gate mac_state.mac_input = ibd_input; 619*7c478bd9Sstevel@tonic-gate mac_state.mac_output = ibd_output; 620*7c478bd9Sstevel@tonic-gate } 621