1 /* $NetBSD: netif_news.c,v 1.4 2003/03/13 14:49:12 drochner Exp $ */ 2 3 /* 4 * Copyright (c) 1995 Gordon W. Ross 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 4. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by Gordon W. Ross 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * The Sun PROM has a fairly general set of network drivers, 35 * so it is easiest to just replace the netif module with 36 * this adaptation to the PROM network interface. 37 */ 38 39 #include <sys/param.h> 40 #include <sys/socket.h> 41 42 #include <net/if.h> 43 #include <net/if_ether.h> 44 45 #include <netinet/in.h> 46 #include <netinet/in_systm.h> 47 48 #include <lib/libsa/stand.h> 49 #include <lib/libsa/net.h> 50 #include <lib/libkern/libkern.h> 51 52 #include <machine/apcall.h> 53 #include <promdev.h> 54 55 #include "netif_news.h" 56 57 #ifdef NETIF_DEBUG 58 int netif_debug; 59 #endif 60 61 static struct iodesc sdesc; 62 63 struct iodesc * 64 socktodesc(sock) 65 int sock; 66 { 67 if (sock != 0) { 68 return(NULL); 69 } 70 return (&sdesc); 71 } 72 73 int 74 netif_news_open(pd) 75 struct romdev *pd; 76 { 77 struct iodesc *io; 78 79 /* find a free socket */ 80 io = &sdesc; 81 if (io->io_netif) { 82 #ifdef DEBUG 83 printf("netif_open: device busy\n"); 84 #endif 85 errno = ENFILE; 86 return (-1); 87 } 88 memset(io, 0, sizeof(*io)); 89 90 io->io_netif = pd; 91 92 /* Put our ethernet address in io->myea */ 93 prom_getether(pd, io->myea); 94 95 return(0); 96 } 97 98 void 99 netif_news_close(fd) 100 int fd; 101 { 102 struct iodesc *io; 103 104 io = &sdesc; 105 io->io_netif = NULL; 106 } 107 108 /* 109 * Send a packet. The ether header is already there. 110 * Return the length sent (or -1 on error). 111 */ 112 ssize_t 113 netif_put(desc, pkt, len) 114 struct iodesc *desc; 115 void *pkt; 116 size_t len; 117 { 118 struct romdev *pd; 119 ssize_t rv; 120 size_t sendlen; 121 122 pd = (struct romdev *)desc->io_netif; 123 124 #ifdef NETIF_DEBUG 125 if (netif_debug) { 126 struct ether_header *eh; 127 128 printf("netif_put: desc=0x%x pkt=0x%x len=%d\n", 129 desc, pkt, len); 130 eh = pkt; 131 printf("dst: %s ", ether_sprintf(eh->ether_dhost)); 132 printf("src: %s ", ether_sprintf(eh->ether_shost)); 133 printf("type: 0x%x\n", eh->ether_type & 0xFFFF); 134 } 135 #endif 136 137 sendlen = len; 138 if (sendlen < 60) { 139 sendlen = 60; 140 #ifdef NETIF_DEBUG 141 printf("netif_put: length padded to %d\n", sendlen); 142 #endif 143 } 144 145 rv = apcall_write(pd->fd, pkt, sendlen); 146 147 #ifdef NETIF_DEBUG 148 if (netif_debug) 149 printf("netif_put: xmit returned %d\n", rv); 150 #endif 151 152 return rv; 153 } 154 155 /* 156 * Receive a packet, including the ether header. 157 * Return the total length received (or -1 on error). 158 */ 159 ssize_t 160 netif_get(desc, pkt, maxlen, timo) 161 struct iodesc *desc; 162 void *pkt; 163 size_t maxlen; 164 time_t timo; 165 { 166 struct romdev *pd; 167 int tick0; 168 ssize_t len; 169 170 pd = (struct romdev *)desc->io_netif; 171 172 #ifdef NETIF_DEBUG 173 if (netif_debug) 174 printf("netif_get: pkt=0x%x, maxlen=%d, tmo=%d\n", 175 pkt, maxlen, timo); 176 #endif 177 178 tick0 = getsecs(); 179 180 do { 181 len = apcall_read(pd->fd, pkt, maxlen); 182 } while ((len == 0) && ((getsecs() - tick0) < timo)); 183 184 #ifdef NETIF_DEBUG 185 if (netif_debug) 186 printf("netif_get: received len=%d\n", len); 187 #endif 188 189 if (len < 12) 190 return -1; 191 192 #ifdef NETIF_DEBUG 193 if (netif_debug) { 194 struct ether_header *eh = pkt; 195 196 printf("dst: %s ", ether_sprintf(eh->ether_dhost)); 197 printf("src: %s ", ether_sprintf(eh->ether_shost)); 198 printf("type: 0x%x\n", eh->ether_type & 0xFFFF); 199 } 200 #endif 201 202 return len; 203 } 204 205 int 206 prom_getether(pd, ea) 207 struct romdev *pd; 208 u_char *ea; 209 { 210 if (apcall_ioctl(pd->fd, APIOCGIFHWADDR, ea)); 211 return -1; 212 213 #ifdef BOOT_DEBUG 214 printf("hardware address %s\n", ether_sprintf(ea)); 215 #endif 216 217 return 0; 218 } 219 220 time_t 221 getsecs() 222 { 223 u_int t[2]; 224 225 apcall_gettimeofday(t); /* time = t[0](s) + t[1](ns) */ 226 return t[0]; 227 } 228