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