xref: /netbsd-src/sys/arch/shark/stand/ofwboot/netif_of.c (revision 69cf32a7821304a5f797ce176fd66771e252f0fe)
1*69cf32a7Stsutsui /*	$NetBSD: netif_of.c,v 1.5 2009/01/12 11:32:44 tsutsui Exp $	*/
280675955Sthorpej 
380675955Sthorpej /*
480675955Sthorpej  * Copyright (C) 1995 Wolfgang Solfrank.
580675955Sthorpej  * Copyright (C) 1995 TooLs GmbH.
680675955Sthorpej  * All rights reserved.
780675955Sthorpej  *
880675955Sthorpej  * Redistribution and use in source and binary forms, with or without
980675955Sthorpej  * modification, are permitted provided that the following conditions
1080675955Sthorpej  * are met:
1180675955Sthorpej  * 1. Redistributions of source code must retain the above copyright
1280675955Sthorpej  *    notice, this list of conditions and the following disclaimer.
1380675955Sthorpej  * 2. Redistributions in binary form must reproduce the above copyright
1480675955Sthorpej  *    notice, this list of conditions and the following disclaimer in the
1580675955Sthorpej  *    documentation and/or other materials provided with the distribution.
1680675955Sthorpej  * 3. All advertising materials mentioning features or use of this software
1780675955Sthorpej  *    must display the following acknowledgement:
1880675955Sthorpej  *	This product includes software developed by TooLs GmbH.
1980675955Sthorpej  * 4. The name of TooLs GmbH may not be used to endorse or promote products
2080675955Sthorpej  *    derived from this software without specific prior written permission.
2180675955Sthorpej  *
2280675955Sthorpej  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
2380675955Sthorpej  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2480675955Sthorpej  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2580675955Sthorpej  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2680675955Sthorpej  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2780675955Sthorpej  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
2880675955Sthorpej  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2980675955Sthorpej  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
3080675955Sthorpej  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
3180675955Sthorpej  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3280675955Sthorpej  */
3380675955Sthorpej 
3480675955Sthorpej /*
3580675955Sthorpej  * Open Firmware does most of the job for interfacing to the hardware,
3680675955Sthorpej  * so it is easiest to just replace the netif module with
3780675955Sthorpej  * this adaptation to the PROM network interface.
3880675955Sthorpej  *
3980675955Sthorpej  * Note: this is based in part on sys/arch/sparc/stand/netif_sun.c
4080675955Sthorpej  */
4180675955Sthorpej 
4280675955Sthorpej #include <sys/param.h>
4380675955Sthorpej #include <sys/socket.h>
4480675955Sthorpej 
4580675955Sthorpej #include <net/if.h>
4680675955Sthorpej #include <net/if_ether.h>
4780675955Sthorpej 
4880675955Sthorpej #include <netinet/in.h>
4980675955Sthorpej #include <netinet/in_systm.h>
5080675955Sthorpej 
5180675955Sthorpej #include <lib/libsa/stand.h>
5280675955Sthorpej #include <lib/libsa/net.h>
5380675955Sthorpej 
5480675955Sthorpej #include "ofdev.h"
5580675955Sthorpej #include "openfirm.h"
5680675955Sthorpej 
5766a5580cSdrochner #include "netif_of.h"
5880675955Sthorpej 
5966a5580cSdrochner static struct iodesc sdesc;
6080675955Sthorpej 
6180675955Sthorpej struct iodesc *
socktodesc(int sock)6245879fd7Schristos socktodesc(int sock)
6380675955Sthorpej {
6480675955Sthorpej 	if (sock != 0)
6580675955Sthorpej 		return NULL;
6666a5580cSdrochner 	return &sdesc;
6780675955Sthorpej }
6880675955Sthorpej 
6980675955Sthorpej int
netif_of_open(struct of_dev * op)7045879fd7Schristos netif_of_open(struct of_dev *op)
7180675955Sthorpej {
7280675955Sthorpej 	struct iodesc *io;
7380675955Sthorpej 
7480675955Sthorpej #ifdef	NETIF_DEBUG
7580675955Sthorpej 	printf("netif_open...");
7680675955Sthorpej #endif
7780675955Sthorpej 	/* find a free socket */
7866a5580cSdrochner 	io = &sdesc;
7980675955Sthorpej 	if (io->io_netif) {
8080675955Sthorpej #ifdef	NETIF_DEBUG
8180675955Sthorpej 		printf("device busy\n");
8280675955Sthorpej #endif
8380675955Sthorpej 		errno = ENFILE;
8480675955Sthorpej 		return -1;
8580675955Sthorpej 	}
8645879fd7Schristos 	(void)memset(io, 0, sizeof *io);
8780675955Sthorpej 
8866a5580cSdrochner 	io->io_netif = (void *)op;
8980675955Sthorpej 
9080675955Sthorpej 	/* Put our ethernet address in io->myea */
9180675955Sthorpej 	OF_getprop(OF_instance_to_package(op->handle),
9280675955Sthorpej 		   "mac-address", io->myea, sizeof io->myea);
9380675955Sthorpej 
9480675955Sthorpej #ifdef	NETIF_DEBUG
9580675955Sthorpej 	printf("OK\n");
9680675955Sthorpej #endif
9780675955Sthorpej 	return 0;
9880675955Sthorpej }
9980675955Sthorpej 
10066a5580cSdrochner void
netif_of_close(int fd)10145879fd7Schristos netif_of_close(int fd)
10280675955Sthorpej {
10380675955Sthorpej 	struct iodesc *io;
10480675955Sthorpej 
10580675955Sthorpej #ifdef	NETIF_DEBUG
10680675955Sthorpej 	printf("netif_close(%x)...", fd);
10780675955Sthorpej #endif
10880675955Sthorpej 
10966a5580cSdrochner #ifdef	NETIF_DEBUG
11066a5580cSdrochner 	if (fd != 0) {
11166a5580cSdrochner 		printf("EBADF\n");
11266a5580cSdrochner 		return;
11380675955Sthorpej 	}
11466a5580cSdrochner #endif
11566a5580cSdrochner 
11666a5580cSdrochner 	io = &sdesc;
11766a5580cSdrochner 	io->io_netif = NULL;
11866a5580cSdrochner 
11980675955Sthorpej #ifdef	NETIF_DEBUG
12080675955Sthorpej 	printf("OK\n");
12180675955Sthorpej #endif
12280675955Sthorpej }
12380675955Sthorpej 
12480675955Sthorpej /*
12580675955Sthorpej  * Send a packet.  The ether header is already there.
12680675955Sthorpej  * Return the length sent (or -1 on error).
12780675955Sthorpej  */
12880675955Sthorpej ssize_t
netif_put(struct iodesc * desc,void * pkt,size_t len)12945879fd7Schristos netif_put(struct iodesc *desc, void *pkt, size_t len)
13080675955Sthorpej {
13180675955Sthorpej 	struct of_dev *op;
13280675955Sthorpej 	ssize_t rv;
13380675955Sthorpej 	size_t sendlen;
13480675955Sthorpej 
13566a5580cSdrochner 	op = (struct of_dev *)desc->io_netif;
13680675955Sthorpej 
13780675955Sthorpej #ifdef	NETIF_DEBUG
13880675955Sthorpej 	{
13980675955Sthorpej 		struct ether_header *eh;
14080675955Sthorpej 
14180675955Sthorpej 		printf("netif_put: desc=0x%x pkt=0x%x len=%d\n",
14280675955Sthorpej 		       desc, pkt, len);
14380675955Sthorpej 		eh = pkt;
14480675955Sthorpej 		printf("dst: %s ", ether_sprintf(eh->ether_dhost));
14580675955Sthorpej 		printf("src: %s ", ether_sprintf(eh->ether_shost));
14680675955Sthorpej 		printf("type: 0x%x\n", eh->ether_type & 0xFFFF);
14780675955Sthorpej 	}
14880675955Sthorpej #endif
14980675955Sthorpej 
15080675955Sthorpej 	sendlen = len;
15180675955Sthorpej 	if (sendlen < 60) {
15280675955Sthorpej 		sendlen = 60;
15380675955Sthorpej #ifdef	NETIF_DEBUG
15480675955Sthorpej 		printf("netif_put: length padded to %d\n", sendlen);
15580675955Sthorpej #endif
15680675955Sthorpej 	}
15780675955Sthorpej 
15880675955Sthorpej 	rv = OF_write(op->handle, pkt, sendlen);
15980675955Sthorpej 
16080675955Sthorpej #ifdef	NETIF_DEBUG
16180675955Sthorpej 	printf("netif_put: xmit returned %d\n", rv);
16280675955Sthorpej #endif
16380675955Sthorpej 
16480675955Sthorpej 	return rv;
16580675955Sthorpej }
16680675955Sthorpej 
16780675955Sthorpej /*
16880675955Sthorpej  * Receive a packet, including the ether header.
16980675955Sthorpej  * Return the total length received (or -1 on error).
17080675955Sthorpej  */
17180675955Sthorpej ssize_t
netif_get(struct iodesc * desc,void * pkt,size_t maxlen,saseconds_t timo)172*69cf32a7Stsutsui netif_get(struct iodesc *desc, void *pkt, size_t maxlen, saseconds_t timo)
17380675955Sthorpej {
17480675955Sthorpej 	struct of_dev *op;
17580675955Sthorpej 	int tick0, tmo_ms;
17680675955Sthorpej 	int len;
17780675955Sthorpej 
17866a5580cSdrochner 	op = (struct of_dev *)desc->io_netif;
17980675955Sthorpej 
18080675955Sthorpej #ifdef	NETIF_DEBUG
18180675955Sthorpej 	printf("netif_get: pkt=0x%x, maxlen=%d, tmo=%d\n",
18280675955Sthorpej 	       pkt, maxlen, timo);
18380675955Sthorpej #endif
18480675955Sthorpej 
18580675955Sthorpej 	tmo_ms = timo * 1000;
18680675955Sthorpej 	tick0 = OF_milliseconds();
18780675955Sthorpej 
18880675955Sthorpej 	do {
18980675955Sthorpej 		len = OF_read(op->handle, pkt, maxlen);
19080675955Sthorpej 	} while ((len == -2 || len == 0) &&
19180675955Sthorpej 		 (OF_milliseconds() - tick0 < tmo_ms));
19280675955Sthorpej 
19380675955Sthorpej #ifdef	NETIF_DEBUG
19480675955Sthorpej 	printf("netif_get: received len=%d\n", len);
19580675955Sthorpej #endif
19680675955Sthorpej 
19780675955Sthorpej 	if (len < 12)
19880675955Sthorpej 		return -1;
19980675955Sthorpej 
20080675955Sthorpej #ifdef	NETIF_DEBUG
20180675955Sthorpej 	{
20280675955Sthorpej 		struct ether_header *eh = pkt;
20380675955Sthorpej 
20480675955Sthorpej 		printf("dst: %s ", ether_sprintf(eh->ether_dhost));
20580675955Sthorpej 		printf("src: %s ", ether_sprintf(eh->ether_shost));
20680675955Sthorpej 		printf("type: 0x%x\n", eh->ether_type & 0xFFFF);
20780675955Sthorpej 	}
20880675955Sthorpej #endif
20980675955Sthorpej 
21080675955Sthorpej 	return len;
21180675955Sthorpej }
21280675955Sthorpej 
21380675955Sthorpej /*
21480675955Sthorpej  * Shouldn't really be here, but is used solely for networking, so...
21580675955Sthorpej  */
216*69cf32a7Stsutsui satime_t
getsecs(void)21745879fd7Schristos getsecs(void)
21880675955Sthorpej {
21980675955Sthorpej 	return OF_milliseconds() / 1000;
22080675955Sthorpej }
221