1/*- 2 * Copyright (c) 2012 The NetBSD Foundation, Inc. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to The NetBSD Foundation 6 * by Paul Fleischer <paul@xpg.dk> 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 */ 29/* 30 * This file is based on arch/sandpoint/stand/netboot/nif.c 31 */ 32 33#include <sys/types.h> 34 35#include <netinet/in.h> 36 37#include <lib/libsa/stand.h> 38#include <lib/libsa/iodesc.h> 39 40#include "dm9k.h" 41#include <arch/evbarm/mini2440/mini2440_bootinfo.h> 42 43extern struct btinfo_rootdevice bi_rdev; 44extern struct btinfo_net bi_net; 45 46struct nifdv { 47 char *name; 48 int (*match)(unsigned, void *); 49 void *(*init)(unsigned, void *); 50 int (*send)(void *, char *, unsigned); 51 int (*recv)(void *, char *, unsigned, unsigned); 52 int (*halt)(void *, int); 53 void *priv; 54}; 55 56 57static struct nifdv vnifdv[] = { 58 {"dme", dm9k_match, dm9k_init, dm9k_send, dm9k_recv} 59}; 60static int nnifdv = sizeof(vnifdv)/sizeof(vnifdv[0]); 61static bool nifmatch[sizeof(nnifdv)]; 62//static uint8_t nifaddr[sizeof(nnifdv)][6]; 63 64static struct iodesc netdesc; 65 66void netif_match(unsigned int tag, uint8_t *macaddr); 67int netif_init(unsigned int tag, uint8_t *macaddr); 68int netif_open(void*); 69int netif_close(int); 70 71void 72netif_match(unsigned int tag, uint8_t *macaddr) 73{ 74 struct nifdv *dv; 75 int n; 76 77 for (n = 0; n < nnifdv; n++) { 78 //memcpy(nifaddr[n], macaddr, sizeof(nifaddr[n])); 79 dv = &vnifdv[n]; 80 if ((*dv->match)(tag, macaddr) > 0) { 81 nifmatch[n] = 1; 82 snprintf(bi_rdev.devname, sizeof(bi_rdev.devname), "%s", dv->name); 83 bi_rdev.cookie = tag; 84 85 snprintf(bi_net.devname, sizeof(bi_net.devname), "%s", dv->name); 86 bi_net.cookie = tag; 87 memcpy(bi_net.mac_address, macaddr, sizeof(bi_net.mac_address)); 88 break; 89 } else { 90 nifmatch[n] = 0; 91 } 92 } 93} 94 95int 96netif_init(unsigned int tag, uint8_t *macaddr) 97{ 98 struct iodesc *s; 99 struct nifdv *dv; 100 int n; 101 uint8_t enaddr[6]; 102 103 for (n = 0; n < nnifdv; n++) { 104 if (nifmatch[n]) { 105 dv = &vnifdv[n]; 106 goto found; 107 } 108 } 109 return 0; 110 found: 111 dv->priv = (*dv->init)(tag, enaddr); 112 s = &netdesc; 113 s->io_netif = dv; 114 memcpy(s->myea, enaddr, sizeof(s->myea)); 115 116 snprintf(bi_rdev.devname, sizeof(bi_rdev.devname), "%s", dv->name); 117 bi_rdev.cookie = tag; 118 119 snprintf(bi_net.devname, sizeof(bi_net.devname), "%s", dv->name); 120 bi_net.cookie = tag; 121 memcpy(bi_net.mac_address, enaddr, sizeof(bi_net.mac_address)); 122 return 1; 123} 124 125int 126netif_open (void *cookie) 127{ 128 return 0; 129} 130 131int 132netif_close (int sock) 133{ 134 return 0; 135} 136 137 138ssize_t 139netif_put(struct iodesc *desc, void *pkt, size_t len) 140{ 141 struct nifdv *dv = desc->io_netif; 142 143 return (*dv->send)(dv->priv, pkt, len); 144 145} 146 147ssize_t 148netif_get(struct iodesc *desc, void *pkt, size_t maxlen, saseconds_t timo) 149{ 150 struct nifdv *dv = desc->io_netif; 151 int len; 152 153 len = (*dv->recv)(dv->priv, pkt, maxlen, timo); 154 return len; 155} 156 157struct iodesc* 158socktodesc (int i) 159{ 160 return (i==0) ? &netdesc : NULL; 161} 162