ofw_net.c revision 91112
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 * $FreeBSD: head/sys/boot/ofw/libofw/ofw_net.c 91112 2002-02-23 04:31:30Z jake $ 2767204Sobrien */ 2867204Sobrien 2967204Sobrien#include <sys/param.h> 3067204Sobrien#include <sys/types.h> 3168548Sbenno#include <sys/socket.h> 3267204Sobrien 3368548Sbenno#include <net/if.h> 3467204Sobrien#include <netinet/in.h> 3567204Sobrien#include <netinet/in_systm.h> 3668548Sbenno#include <netinet/if_ether.h> 3768548Sbenno#include <netinet/ip.h> 3867204Sobrien 3967204Sobrien#include <stand.h> 4067204Sobrien#include <net.h> 4167204Sobrien#include <netif.h> 4267204Sobrien 4368548Sbenno#include "openfirm.h" 4467204Sobrien 4568548Sbennostatic int ofwn_probe(struct netif *, void *); 4668548Sbennostatic int ofwn_match(struct netif *, void *); 4768548Sbennostatic void ofwn_init(struct iodesc *, void *); 4884617Sbennostatic int ofwn_get(struct iodesc *, void *, size_t, time_t); 4984617Sbennostatic int ofwn_put(struct iodesc *, void *, size_t); 5068548Sbennostatic void ofwn_end(struct netif *); 5167204Sobrien 5268548Sbennoextern struct netif_stats ofwn_stats[]; 5368548Sbenno 5468548Sbennostruct netif_dif ofwn_ifs[] = { 5567204Sobrien /* dif_unit dif_nsel dif_stats dif_private */ 5668548Sbenno { 0, 1, &ofwn_stats[0], 0, }, 5767204Sobrien}; 5867204Sobrien 5968548Sbennostruct netif_stats ofwn_stats[NENTS(ofwn_ifs)]; 6067204Sobrien 6167204Sobrienstruct netif_driver ofwnet = { 6267204Sobrien "net", /* netif_bname */ 6367204Sobrien ofwn_match, /* netif_match */ 6467204Sobrien ofwn_probe, /* netif_probe */ 6567204Sobrien ofwn_init, /* netif_init */ 6667204Sobrien ofwn_get, /* netif_get */ 6767204Sobrien ofwn_put, /* netif_put */ 6867204Sobrien ofwn_end, /* netif_end */ 6967204Sobrien ofwn_ifs, /* netif_ifs */ 7067204Sobrien NENTS(ofwn_ifs) /* netif_nifs */ 7167204Sobrien}; 7267204Sobrien 7368548Sbennostatic phandle_t netdevice; 7468548Sbennostatic ihandle_t netinstance; 7568548Sbennostatic ihandle_t memory; 7667204Sobrien 7768548Sbennostatic void *dmabuf; 7868548Sbenno 7968548Sbennostatic int 8067204Sobrienofwn_match(struct netif *nif, void *machdep_hint) 8167204Sobrien{ 8268548Sbenno return 1; 8367204Sobrien} 8467204Sobrien 8568548Sbennostatic int 8667204Sobrienofwn_probe(struct netif *nif, void *machdep_hint) 8767204Sobrien{ 8867204Sobrien return 0; 8967204Sobrien} 9067204Sobrien 9168548Sbennostatic int 9284617Sbennoofwn_put(struct iodesc *desc, void *pkt, size_t len) 9367204Sobrien{ 9468548Sbenno struct ether_header *eh; 9568548Sbenno size_t sendlen; 9668548Sbenno ssize_t rv; 9767204Sobrien 9868548Sbenno#if defined(NETIF_DEBUG) 9968548Sbenno printf("netif_put: desc=0x%x pkt=0x%x len=%d\n", desc, pkt, len); 10068548Sbenno eh = pkt; 10168548Sbenno printf("dst: %s ", ether_sprintf(eh->ether_dhost)); 10268548Sbenno printf("src: %s ", ether_sprintf(eh->ether_shost)); 10368548Sbenno printf("type: 0x%x\n", eh->ether_type & 0xffff); 10467204Sobrien#endif 10568548Sbenno 10668548Sbenno sendlen = len; 10768548Sbenno if (sendlen < 60) { 10868548Sbenno sendlen = 60; 10968548Sbenno#if defined(NETIF_DEBUG) 11068548Sbenno printf("netif_put: length padded to %d\n", sendlen); 11168548Sbenno#endif 11268548Sbenno } 11368548Sbenno 11468548Sbenno if (dmabuf) { 11568548Sbenno bcopy(pkt, dmabuf, sendlen); 11668548Sbenno pkt = dmabuf; 11768548Sbenno } 11868548Sbenno 11968548Sbenno rv = OF_write(netinstance, pkt, len); 12068548Sbenno 12168548Sbenno#if defined(NETIF_DEBUG) 12268548Sbenno printf("netif_put: OF_write returned %d\n", rv); 12368548Sbenno#endif 12468548Sbenno 12568548Sbenno return rv; 12667204Sobrien} 12767204Sobrien 12868548Sbennostatic int 12984617Sbennoofwn_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout) 13067204Sobrien{ 13168548Sbenno time_t t; 13268548Sbenno int length; 13367204Sobrien 13468548Sbenno#if defined(NETIF_DEBUG) 13568548Sbenno printf("netif_get: pkt=%p, maxlen=%d, timeout=%d\n", pkt, len, 13668548Sbenno timeout); 13768548Sbenno#endif 13867204Sobrien 13968548Sbenno t = getsecs(); 14068548Sbenno do { 14168548Sbenno length = OF_read(netinstance, pkt, len); 14268548Sbenno } while ((length == -2 || length == 0) && 14368548Sbenno (getsecs() - t < timeout)); 14467204Sobrien 14568548Sbenno#if defined(NETIF_DEBUG) 14668548Sbenno printf("netif_get: received length=%d (%x)\n", length, length); 14768548Sbenno#endif 14867204Sobrien 14968548Sbenno if (length < 12) 15068548Sbenno return -1; 15167204Sobrien 15268548Sbenno#if defined(NETIF_VERBOSE_DEBUG) 15368548Sbenno { 15468548Sbenno char *ch = pkt; 15568548Sbenno int i; 15667204Sobrien 15768548Sbenno for(i = 0; i < 96; i += 4) { 15868548Sbenno printf("%02x%02x%02x%02x ", ch[i], ch[i+1], 15968548Sbenno ch[i+2], ch[i+3]); 16067204Sobrien } 16168548Sbenno printf("\n"); 16267204Sobrien } 16368548Sbenno#endif 16467204Sobrien 16568548Sbenno#if defined(NETIF_DEBUG) 16668548Sbenno { 16768548Sbenno struct ether_header *eh = pkt; 16867204Sobrien 16968548Sbenno printf("dst: %s ", ether_sprintf(eh->ether_dhost)); 17068548Sbenno printf("src: %s ", ether_sprintf(eh->ether_shost)); 17168548Sbenno printf("type: 0x%x\n", eh->ether_type & 0xffff); 17268548Sbenno } 17368548Sbenno#endif 17467204Sobrien 17568548Sbenno return length; 17668548Sbenno} 17767204Sobrien 17868548Sbennoextern char *strchr(); 17967204Sobrien 18068548Sbennostatic void 18168548Sbennoofwn_init(struct iodesc *desc, void *machdep_hint) 18268548Sbenno{ 18368548Sbenno phandle_t chosen, netdev; 18468548Sbenno char path[64]; 18568548Sbenno char *ch; 18668548Sbenno int pathlen; 18767204Sobrien 18868548Sbenno chosen = OF_finddevice("/chosen"); 18968548Sbenno OF_getprop(chosen, "memory", &memory, sizeof(memory)); 19068548Sbenno pathlen = OF_getprop(chosen, "bootpath", path, 64); 19191112Sjake if ((ch = index(path, ':')) != NULL) 19291112Sjake *ch = '\0'; 19368548Sbenno netdev = OF_finddevice(path); 19491112Sjake#ifdef __sparc64__ 19591112Sjake if (OF_getprop(netdev, "mac-address", desc->myea, 6) == -1) 19691112Sjake#else 19768548Sbenno if (OF_getprop(netdev, "local-mac-address", desc->myea, 6) == -1) 19891112Sjake#endif 19968548Sbenno goto punt; 20068548Sbenno 20167204Sobrien printf("boot: ethernet address: %s\n", ether_sprintf(desc->myea)); 20267204Sobrien 20384617Sbenno if ((netinstance = OF_open(path)) == -1) { 20484617Sbenno printf("Could not open network device.\n"); 20568548Sbenno goto punt; 20684617Sbenno } 20768548Sbenno 20868548Sbenno#if defined(NETIF_DEBUG) 20968548Sbenno printf("ofwn_init: OpenFirmware instance handle: %08x\n", netinstance); 21068548Sbenno#endif 21168548Sbenno 21291112Sjake#ifndef __sparc64__ 21382343Sbenno if (OF_call_method("dma-alloc", netinstance, 1, 1, NULL, &dmabuf) 21482343Sbenno < 0) { 21582343Sbenno printf("Failed to allocate DMA buffer (got %08x).\n", dmabuf); 21668548Sbenno goto punt; 21782343Sbenno } 21868548Sbenno 21968548Sbenno#if defined(NETIF_DEBUG) 22068548Sbenno printf("ofwn_init: allocated DMA buffer: %08x\n", dmabuf); 22168548Sbenno#endif 22291112Sjake#endif 22368548Sbenno 22467204Sobrien return; 22567204Sobrien 22667204Sobrienpunt: 22767204Sobrien printf("\n"); 22868548Sbenno printf("Could not boot from %s.\n", path); 22984617Sbenno OF_enter(); 23067204Sobrien} 23167204Sobrien 23268548Sbennostatic void 23367204Sobrienofwn_end(struct netif *nif) 23467204Sobrien{ 23568548Sbenno OF_call_method("dma-free", netinstance, 2, 0, dmabuf, MAXPHYS); 23668548Sbenno OF_close(netinstance); 23767204Sobrien} 23868548Sbenno 23968548Sbenno#if 0 24068548Sbennoint 24168548Sbennoofwn_getunit(const char *path) 24268548Sbenno{ 24368548Sbenno int i; 24468548Sbenno char newpath[255]; 24568548Sbenno 24668548Sbenno OF_canon(path, newpath, 254); 24768548Sbenno 24868548Sbenno for (i = 0; i < nofwninfo; i++) { 24968548Sbenno printf(">>> test =\t%s\n", ofwninfo[i].ofwn_path); 25068548Sbenno if (strcmp(path, ofwninfo[i].ofwn_path) == 0) 25168548Sbenno return i; 25268548Sbenno 25368548Sbenno if (strcmp(newpath, ofwninfo[i].ofwn_path) == 0) 25468548Sbenno return i; 25568548Sbenno } 25668548Sbenno 25768548Sbenno return -1; 25868548Sbenno} 25968548Sbenno#endif 260