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