ofw_net.c revision 133862
167204Sobrien/* 284617Sbenno * Copyright (c) 2000-2001 Benno Rice 367204Sobrien * All rights reserved. 467204Sobrien * 567204Sobrien * Redistribution and use in source and binary forms, with or without 667204Sobrien * modification, are permitted provided that the following conditions 767204Sobrien * are met: 867204Sobrien * 1. Redistributions of source code must retain the above copyright 967204Sobrien * notice, this list of conditions and the following disclaimer. 1067204Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1167204Sobrien * notice, this list of conditions and the following disclaimer in the 1267204Sobrien * documentation and/or other materials provided with the distribution. 1367204Sobrien * 1467204Sobrien * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND 1567204Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1667204Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1767204Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 1867204Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1967204Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2067204Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2167204Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2267204Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2367204Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2467204Sobrien * SUCH DAMAGE. 2567204Sobrien */ 2667204Sobrien 27124140Sobrien#include <sys/cdefs.h> 28124140Sobrien__FBSDID("$FreeBSD: head/sys/boot/ofw/libofw/ofw_net.c 133862 2004-08-16 15:45:27Z marius $"); 29124140Sobrien 3067204Sobrien#include <sys/param.h> 3167204Sobrien#include <sys/types.h> 3268548Sbenno#include <sys/socket.h> 3367204Sobrien 3468548Sbenno#include <net/if.h> 3567204Sobrien#include <netinet/in.h> 3667204Sobrien#include <netinet/in_systm.h> 3768548Sbenno#include <netinet/if_ether.h> 3868548Sbenno#include <netinet/ip.h> 3967204Sobrien 4067204Sobrien#include <stand.h> 4167204Sobrien#include <net.h> 4267204Sobrien#include <netif.h> 4367204Sobrien 4468548Sbenno#include "openfirm.h" 4567204Sobrien 4668548Sbennostatic int ofwn_probe(struct netif *, void *); 4768548Sbennostatic int ofwn_match(struct netif *, void *); 4868548Sbennostatic void ofwn_init(struct iodesc *, void *); 4984617Sbennostatic int ofwn_get(struct iodesc *, void *, size_t, time_t); 5084617Sbennostatic int ofwn_put(struct iodesc *, void *, size_t); 5168548Sbennostatic void ofwn_end(struct netif *); 5267204Sobrien 5368548Sbennoextern struct netif_stats ofwn_stats[]; 5468548Sbenno 5568548Sbennostruct netif_dif ofwn_ifs[] = { 5667204Sobrien /* dif_unit dif_nsel dif_stats dif_private */ 5768548Sbenno { 0, 1, &ofwn_stats[0], 0, }, 5867204Sobrien}; 5967204Sobrien 6068548Sbennostruct netif_stats ofwn_stats[NENTS(ofwn_ifs)]; 6167204Sobrien 6267204Sobrienstruct netif_driver ofwnet = { 6367204Sobrien "net", /* netif_bname */ 6467204Sobrien ofwn_match, /* netif_match */ 6567204Sobrien ofwn_probe, /* netif_probe */ 6667204Sobrien ofwn_init, /* netif_init */ 6767204Sobrien ofwn_get, /* netif_get */ 6867204Sobrien ofwn_put, /* netif_put */ 6967204Sobrien ofwn_end, /* netif_end */ 7067204Sobrien ofwn_ifs, /* netif_ifs */ 7167204Sobrien NENTS(ofwn_ifs) /* netif_nifs */ 7267204Sobrien}; 7367204Sobrien 7468548Sbennostatic phandle_t netdevice; 7568548Sbennostatic ihandle_t netinstance; 7668548Sbennostatic ihandle_t memory; 7767204Sobrien 7868548Sbennostatic void *dmabuf; 7968548Sbenno 8068548Sbennostatic int 8167204Sobrienofwn_match(struct netif *nif, void *machdep_hint) 8267204Sobrien{ 8368548Sbenno return 1; 8467204Sobrien} 8567204Sobrien 8668548Sbennostatic int 8767204Sobrienofwn_probe(struct netif *nif, void *machdep_hint) 8867204Sobrien{ 8967204Sobrien return 0; 9067204Sobrien} 9167204Sobrien 9268548Sbennostatic int 9384617Sbennoofwn_put(struct iodesc *desc, void *pkt, size_t len) 9467204Sobrien{ 9568548Sbenno struct ether_header *eh; 9668548Sbenno size_t sendlen; 9768548Sbenno ssize_t rv; 9867204Sobrien 9968548Sbenno#if defined(NETIF_DEBUG) 10068548Sbenno printf("netif_put: desc=0x%x pkt=0x%x len=%d\n", desc, pkt, len); 10168548Sbenno eh = pkt; 10268548Sbenno printf("dst: %s ", ether_sprintf(eh->ether_dhost)); 10368548Sbenno printf("src: %s ", ether_sprintf(eh->ether_shost)); 10468548Sbenno printf("type: 0x%x\n", eh->ether_type & 0xffff); 10567204Sobrien#endif 10668548Sbenno 10768548Sbenno sendlen = len; 10868548Sbenno if (sendlen < 60) { 10968548Sbenno sendlen = 60; 11068548Sbenno#if defined(NETIF_DEBUG) 11168548Sbenno printf("netif_put: length padded to %d\n", sendlen); 11268548Sbenno#endif 11368548Sbenno } 11468548Sbenno 11568548Sbenno if (dmabuf) { 11668548Sbenno bcopy(pkt, dmabuf, sendlen); 11768548Sbenno pkt = dmabuf; 11868548Sbenno } 11968548Sbenno 12068548Sbenno rv = OF_write(netinstance, pkt, len); 12168548Sbenno 12268548Sbenno#if defined(NETIF_DEBUG) 12368548Sbenno printf("netif_put: OF_write returned %d\n", rv); 12468548Sbenno#endif 12568548Sbenno 12668548Sbenno return rv; 12767204Sobrien} 12867204Sobrien 12968548Sbennostatic int 13084617Sbennoofwn_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout) 13167204Sobrien{ 13268548Sbenno time_t t; 13368548Sbenno int length; 13467204Sobrien 13568548Sbenno#if defined(NETIF_DEBUG) 13668548Sbenno printf("netif_get: pkt=%p, maxlen=%d, timeout=%d\n", pkt, len, 13768548Sbenno timeout); 13868548Sbenno#endif 13967204Sobrien 14068548Sbenno t = getsecs(); 14168548Sbenno do { 14268548Sbenno length = OF_read(netinstance, pkt, len); 14368548Sbenno } while ((length == -2 || length == 0) && 14468548Sbenno (getsecs() - t < timeout)); 14567204Sobrien 14668548Sbenno#if defined(NETIF_DEBUG) 14768548Sbenno printf("netif_get: received length=%d (%x)\n", length, length); 14868548Sbenno#endif 14967204Sobrien 15068548Sbenno if (length < 12) 15168548Sbenno return -1; 15267204Sobrien 15368548Sbenno#if defined(NETIF_VERBOSE_DEBUG) 15468548Sbenno { 15568548Sbenno char *ch = pkt; 15668548Sbenno int i; 15767204Sobrien 15868548Sbenno for(i = 0; i < 96; i += 4) { 15968548Sbenno printf("%02x%02x%02x%02x ", ch[i], ch[i+1], 16068548Sbenno ch[i+2], ch[i+3]); 16167204Sobrien } 16268548Sbenno printf("\n"); 16367204Sobrien } 16468548Sbenno#endif 16567204Sobrien 16668548Sbenno#if defined(NETIF_DEBUG) 16768548Sbenno { 16868548Sbenno struct ether_header *eh = pkt; 16967204Sobrien 17068548Sbenno printf("dst: %s ", ether_sprintf(eh->ether_dhost)); 17168548Sbenno printf("src: %s ", ether_sprintf(eh->ether_shost)); 17268548Sbenno printf("type: 0x%x\n", eh->ether_type & 0xffff); 17368548Sbenno } 17468548Sbenno#endif 17567204Sobrien 17668548Sbenno return length; 17768548Sbenno} 17867204Sobrien 17968548Sbennoextern char *strchr(); 18067204Sobrien 18168548Sbennostatic void 18268548Sbennoofwn_init(struct iodesc *desc, void *machdep_hint) 18368548Sbenno{ 18468548Sbenno phandle_t chosen, netdev; 18568548Sbenno char path[64]; 18668548Sbenno char *ch; 18768548Sbenno int pathlen; 18867204Sobrien 18968548Sbenno chosen = OF_finddevice("/chosen"); 19068548Sbenno OF_getprop(chosen, "memory", &memory, sizeof(memory)); 19168548Sbenno pathlen = OF_getprop(chosen, "bootpath", path, 64); 19291112Sjake if ((ch = index(path, ':')) != NULL) 19391112Sjake *ch = '\0'; 19468548Sbenno netdev = OF_finddevice(path); 19591112Sjake#ifdef __sparc64__ 19691112Sjake if (OF_getprop(netdev, "mac-address", desc->myea, 6) == -1) 19791112Sjake#else 19868548Sbenno if (OF_getprop(netdev, "local-mac-address", desc->myea, 6) == -1) 19991112Sjake#endif 20068548Sbenno goto punt; 20168548Sbenno 20267204Sobrien printf("boot: ethernet address: %s\n", ether_sprintf(desc->myea)); 20367204Sobrien 20484617Sbenno if ((netinstance = OF_open(path)) == -1) { 20584617Sbenno printf("Could not open network device.\n"); 20668548Sbenno goto punt; 20784617Sbenno } 20868548Sbenno 20968548Sbenno#if defined(NETIF_DEBUG) 210133862Smarius printf("ofwn_init: Open Firmware instance handle: %08x\n", netinstance); 21168548Sbenno#endif 21268548Sbenno 21391112Sjake#ifndef __sparc64__ 21498013Sbenno dmabuf = NULL; 21598013Sbenno if (OF_call_method("dma-alloc", netinstance, 1, 1, (64 * 1024), &dmabuf) 21682343Sbenno < 0) { 21782343Sbenno printf("Failed to allocate DMA buffer (got %08x).\n", dmabuf); 21868548Sbenno goto punt; 21982343Sbenno } 22068548Sbenno 22168548Sbenno#if defined(NETIF_DEBUG) 22268548Sbenno printf("ofwn_init: allocated DMA buffer: %08x\n", dmabuf); 22368548Sbenno#endif 22491112Sjake#endif 22568548Sbenno 22667204Sobrien return; 22767204Sobrien 22867204Sobrienpunt: 22967204Sobrien printf("\n"); 23068548Sbenno printf("Could not boot from %s.\n", path); 23184617Sbenno OF_enter(); 23267204Sobrien} 23367204Sobrien 23468548Sbennostatic void 23567204Sobrienofwn_end(struct netif *nif) 23667204Sobrien{ 23768548Sbenno OF_call_method("dma-free", netinstance, 2, 0, dmabuf, MAXPHYS); 23868548Sbenno OF_close(netinstance); 23967204Sobrien} 24068548Sbenno 24168548Sbenno#if 0 24268548Sbennoint 24368548Sbennoofwn_getunit(const char *path) 24468548Sbenno{ 24568548Sbenno int i; 24668548Sbenno char newpath[255]; 24768548Sbenno 24868548Sbenno OF_canon(path, newpath, 254); 24968548Sbenno 25068548Sbenno for (i = 0; i < nofwninfo; i++) { 25168548Sbenno printf(">>> test =\t%s\n", ofwninfo[i].ofwn_path); 25268548Sbenno if (strcmp(path, ofwninfo[i].ofwn_path) == 0) 25368548Sbenno return i; 25468548Sbenno 25568548Sbenno if (strcmp(newpath, ofwninfo[i].ofwn_path) == 0) 25668548Sbenno return i; 25768548Sbenno } 25868548Sbenno 25968548Sbenno return -1; 26068548Sbenno} 26168548Sbenno#endif 262