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