Home | History | Annotate | Line # | Download | only in boot
if_de.c revision 1.6
      1  1.6   cegger /*	$NetBSD: if_de.c,v 1.6 2009/03/18 16:00:15 cegger Exp $	*/
      2  1.1    ragge 
      3  1.1    ragge /*
      4  1.1    ragge  * Copyright (c) 2000 Ludd, University of Lule}, Sweden. All rights reserved.
      5  1.1    ragge  *
      6  1.1    ragge  * Redistribution and use in source and binary forms, with or without
      7  1.1    ragge  * modification, are permitted provided that the following conditions
      8  1.1    ragge  * are met:
      9  1.1    ragge  * 1. Redistributions of source code must retain the above copyright
     10  1.1    ragge  *    notice, this list of conditions and the following disclaimer.
     11  1.1    ragge  * 2. Redistributions in binary form must reproduce the above copyright
     12  1.1    ragge  *    notice, this list of conditions and the following disclaimer in the
     13  1.1    ragge  *    documentation and/or other materials provided with the distribution.
     14  1.1    ragge  * 3. All advertising materials mentioning features or use of this software
     15  1.1    ragge  *    must display the following acknowledgement:
     16  1.1    ragge  *      This product includes software developed at Ludd, University of
     17  1.1    ragge  *      Lule}, Sweden and its contributors.
     18  1.1    ragge  * 4. The name of the author may not be used to endorse or promote products
     19  1.1    ragge  *    derived from this software without specific prior written permission
     20  1.1    ragge  *
     21  1.1    ragge  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     22  1.1    ragge  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     23  1.1    ragge  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     24  1.1    ragge  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     25  1.1    ragge  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     26  1.1    ragge  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     27  1.1    ragge  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     28  1.1    ragge  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29  1.1    ragge  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     30  1.1    ragge  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  1.1    ragge  *
     32  1.1    ragge  *	Standalone routine for the DEUNA Ethernet controller.
     33  1.1    ragge  */
     34  1.1    ragge 
     35  1.1    ragge #include <sys/param.h>
     36  1.1    ragge #include <sys/types.h>
     37  1.1    ragge #include <sys/socket.h>
     38  1.1    ragge #include <sys/queue.h>
     39  1.1    ragge 
     40  1.1    ragge #include <net/if.h>
     41  1.1    ragge #include <net/if_ether.h>
     42  1.1    ragge 
     43  1.1    ragge #include <netinet/in.h>
     44  1.1    ragge #include <netinet/in_systm.h>
     45  1.1    ragge 
     46  1.1    ragge #include <lib/libsa/netif.h>
     47  1.1    ragge #include <lib/libsa/stand.h>
     48  1.1    ragge 
     49  1.1    ragge #include "lib/libkern/libkern.h"
     50  1.1    ragge 
     51  1.1    ragge #include <dev/qbus/if_dereg.h>
     52  1.1    ragge 
     53  1.1    ragge #include "arch/vax/include/sid.h"
     54  1.1    ragge #include "arch/vax/include/rpb.h"
     55  1.1    ragge #include "arch/vax/include/pte.h"
     56  1.1    ragge 
     57  1.1    ragge #include "vaxstand.h"
     58  1.1    ragge 
     59  1.5  tsutsui static int de_get(struct iodesc *, void *, size_t, saseconds_t);
     60  1.1    ragge static int de_put(struct iodesc *, void *, size_t);
     61  1.1    ragge static void dewait(char *);
     62  1.1    ragge 
     63  1.1    ragge struct netif_driver de_driver = {
     64  1.1    ragge 	0, 0, 0, 0, de_get, de_put,
     65  1.1    ragge };
     66  1.1    ragge 
     67  1.1    ragge #define NRCV 8		/* allocate 8 receive descriptors */
     68  1.1    ragge #define NXMT 4		/* and 4 transmit - must be >1 */
     69  1.1    ragge 
     70  1.1    ragge struct de_cdata {
     71  1.1    ragge 	/* the following structures are always mapped in */
     72  1.1    ragge         struct  de_pcbb dc_pcbb;        /* port control block */
     73  1.1    ragge         struct  de_ring dc_xrent[NXMT]; /* transmit ring entrys */
     74  1.1    ragge         struct  de_ring dc_rrent[NRCV]; /* receive ring entrys */
     75  1.1    ragge         struct  de_udbbuf dc_udbbuf;    /* UNIBUS data buffer */
     76  1.1    ragge 	char	dc_rbuf[NRCV][ETHER_MAX_LEN];
     77  1.1    ragge 	char	dc_xbuf[NXMT][ETHER_MAX_LEN];
     78  1.1    ragge         /* end mapped area */
     79  1.1    ragge };
     80  1.1    ragge 
     81  1.1    ragge static volatile struct de_cdata *dc, *pdc;
     82  1.1    ragge static volatile char *addr;
     83  1.1    ragge static int crx, ctx;
     84  1.1    ragge #define DE_WCSR(csr, val) *(volatile u_short *)(addr + (csr)) = (val)
     85  1.1    ragge #define DE_WLOW(val) *(volatile u_char *)(addr + DE_PCSR0) = (val)
     86  1.1    ragge #define DE_WHIGH(val) *(volatile u_char *)(addr + DE_PCSR0 + 1) = (val)
     87  1.1    ragge #define DE_RCSR(csr) *(volatile u_short *)(addr + (csr))
     88  1.1    ragge #define LOWORD(x)       ((u_int)(x) & 0xffff)
     89  1.1    ragge #define HIWORD(x)       (((u_int)(x) >> 16) & 0x3)
     90  1.1    ragge #define	dereg(x)	((x) & 017777)
     91  1.1    ragge 
     92  1.1    ragge int
     93  1.1    ragge deopen(struct open_file *f, int adapt, int ctlr, int unit, int part)
     94  1.1    ragge {
     95  1.1    ragge 	int i, cdata, *map, npgs;
     96  1.4      mrg 	u_char eaddr[6];
     97  1.1    ragge 
     98  1.1    ragge 	/* point to the device in memory */
     99  1.1    ragge 	if (askname == 0) /* Override if autoboot */
    100  1.1    ragge 		addr = (char *)bootrpb.csrphy;
    101  1.1    ragge 	else {
    102  1.1    ragge 		addr = (char *)csrbase + dereg(0174510);
    103  1.1    ragge 		bootrpb.csrphy = (int)addr;
    104  1.1    ragge 	}
    105  1.1    ragge #ifdef DEV_DEBUG
    106  1.1    ragge 	printf("deopen: csrbase %x addr %p nexaddr %x\n",
    107  1.1    ragge 	    csrbase, addr, nexaddr);
    108  1.1    ragge #endif
    109  1.1    ragge 	/* reset the device and wait for completion */
    110  1.1    ragge 	DE_WCSR(DE_PCSR0, 0);
    111  1.1    ragge 	{volatile int j = 100; while (--j);}
    112  1.1    ragge 	DE_WCSR(DE_PCSR0, PCSR0_RSET);
    113  1.1    ragge 	dewait("reset");
    114  1.1    ragge 
    115  1.1    ragge 	/* Map in the control structures and buffers */
    116  1.1    ragge 	dc = alloc(sizeof(struct de_cdata));
    117  1.3       he 	pdc = (struct de_cdata *)((int)dc & VAX_PGOFSET);
    118  1.1    ragge 	map = (int *)nexaddr + 512;
    119  1.1    ragge 	npgs = (sizeof(struct de_cdata) >> VAX_PGSHIFT) + 1;
    120  1.1    ragge 	cdata = (int)dc >> VAX_PGSHIFT;
    121  1.1    ragge 	for (i = 0; i < npgs; i++) {
    122  1.1    ragge 		map[i] = PG_V | (cdata + i);
    123  1.1    ragge 	}
    124  1.1    ragge 
    125  1.6   cegger 	memset((char *)dc, 0, sizeof(struct de_cdata));
    126  1.1    ragge 
    127  1.1    ragge 	/* Tell the DEUNA about our PCB */
    128  1.1    ragge 	DE_WCSR(DE_PCSR2, LOWORD(pdc));
    129  1.1    ragge 	DE_WCSR(DE_PCSR3, HIWORD(pdc));
    130  1.1    ragge 	DE_WLOW(CMD_GETPCBB);
    131  1.1    ragge 	dewait("pcbb");
    132  1.1    ragge 
    133  1.1    ragge 	/* Get our address */
    134  1.1    ragge 	dc->dc_pcbb.pcbb0 = FC_RDPHYAD;
    135  1.1    ragge 	DE_WLOW(CMD_GETCMD);
    136  1.1    ragge 	dewait("read physaddr");
    137  1.1    ragge 	bcopy((char *)&dc->dc_pcbb.pcbb2, eaddr, 6);
    138  1.1    ragge 
    139  1.1    ragge 	/* Create and link the descriptors */
    140  1.1    ragge 	for (i=0; i < NRCV; i++) {
    141  1.1    ragge 		volatile struct de_ring *rp = &dc->dc_rrent[i];
    142  1.1    ragge 
    143  1.1    ragge 		rp->r_lenerr = 0;
    144  1.1    ragge 		rp->r_segbl = LOWORD(&pdc->dc_rbuf[i][0]);
    145  1.1    ragge 		rp->r_segbh = HIWORD(&pdc->dc_rbuf[i][0]);
    146  1.1    ragge 		rp->r_flags = RFLG_OWN;
    147  1.1    ragge 		rp->r_slen = ETHER_MAX_LEN;
    148  1.1    ragge 	}
    149  1.1    ragge 	for (i=0; i < NXMT; i++) {
    150  1.1    ragge 		volatile struct de_ring *rp = &dc->dc_xrent[i];
    151  1.1    ragge 
    152  1.1    ragge 		rp->r_segbl = LOWORD(&pdc->dc_xbuf[i][0]);
    153  1.1    ragge 		rp->r_segbh = HIWORD(&pdc->dc_xbuf[i][0]);
    154  1.1    ragge 		rp->r_tdrerr = 0;
    155  1.1    ragge 		rp->r_flags = 0;
    156  1.1    ragge 	}
    157  1.1    ragge 	crx = ctx = 0;
    158  1.1    ragge 
    159  1.1    ragge 	/* set the transmit and receive ring header addresses */
    160  1.1    ragge 	dc->dc_pcbb.pcbb0 = FC_WTRING;
    161  1.1    ragge 	dc->dc_pcbb.pcbb2 = LOWORD(&pdc->dc_udbbuf);
    162  1.1    ragge 	dc->dc_pcbb.pcbb4 = HIWORD(&pdc->dc_udbbuf);
    163  1.1    ragge 
    164  1.1    ragge 	dc->dc_udbbuf.b_tdrbl = LOWORD(&pdc->dc_xrent[0]);
    165  1.1    ragge 	dc->dc_udbbuf.b_tdrbh = HIWORD(&pdc->dc_xrent[0]);
    166  1.1    ragge 	dc->dc_udbbuf.b_telen = sizeof (struct de_ring) / sizeof(u_int16_t);
    167  1.1    ragge 	dc->dc_udbbuf.b_trlen = NXMT;
    168  1.1    ragge 	dc->dc_udbbuf.b_rdrbl = LOWORD(&pdc->dc_rrent[0]);
    169  1.1    ragge 	dc->dc_udbbuf.b_rdrbh = HIWORD(&pdc->dc_rrent[0]);
    170  1.1    ragge 	dc->dc_udbbuf.b_relen = sizeof (struct de_ring) / sizeof(u_int16_t);
    171  1.1    ragge 	dc->dc_udbbuf.b_rrlen = NRCV;
    172  1.1    ragge 
    173  1.1    ragge 	DE_WLOW(CMD_GETCMD);
    174  1.1    ragge 	dewait("wtring");
    175  1.1    ragge 
    176  1.1    ragge 	dc->dc_pcbb.pcbb0 = FC_WTMODE;
    177  1.1    ragge 	dc->dc_pcbb.pcbb2 = MOD_DRDC|MOD_TPAD|MOD_HDX;
    178  1.1    ragge 	DE_WLOW(CMD_GETCMD);
    179  1.1    ragge 	dewait("wtmode");
    180  1.1    ragge 
    181  1.1    ragge 	DE_WLOW(CMD_START);
    182  1.1    ragge 	dewait("start");
    183  1.1    ragge 
    184  1.1    ragge 	DE_WLOW(CMD_PDMD);
    185  1.1    ragge 	dewait("initpoll");
    186  1.1    ragge 	/* Should be running by now */
    187  1.1    ragge 
    188  1.1    ragge 	net_devinit(f, &de_driver, eaddr);
    189  1.1    ragge 
    190  1.1    ragge 	return 0;
    191  1.1    ragge }
    192  1.1    ragge 
    193  1.1    ragge int
    194  1.5  tsutsui de_get(struct iodesc *desc, void *pkt, size_t maxlen, saseconds_t timeout)
    195  1.1    ragge {
    196  1.1    ragge 	volatile int to = 100000 * timeout;
    197  1.1    ragge 	int len, csr0;
    198  1.1    ragge 
    199  1.1    ragge 	if ((csr0 = DE_RCSR(DE_PCSR0)) & PCSR0_INTR)
    200  1.1    ragge 		DE_WHIGH(csr0 >> 8);
    201  1.1    ragge retry:
    202  1.1    ragge 	if (to-- == 0)
    203  1.1    ragge 		return 0;
    204  1.1    ragge 
    205  1.1    ragge 	if (dc->dc_rrent[crx].r_flags & RFLG_OWN)
    206  1.1    ragge 		goto retry;
    207  1.1    ragge 
    208  1.1    ragge 	if (dc->dc_rrent[crx].r_flags & RFLG_ERRS)
    209  1.1    ragge 		len = 0;
    210  1.1    ragge 	else
    211  1.1    ragge 		len = dc->dc_rrent[crx].r_lenerr & RERR_MLEN;
    212  1.1    ragge 
    213  1.1    ragge 	if (len > maxlen)
    214  1.1    ragge 		len = maxlen;
    215  1.1    ragge 	if (len)
    216  1.1    ragge 		bcopy((char *)&dc->dc_rbuf[crx][0], pkt, len);
    217  1.1    ragge 
    218  1.1    ragge 	dc->dc_rrent[crx].r_flags = RFLG_OWN;
    219  1.1    ragge 	dc->dc_rrent[crx].r_lenerr = 0;
    220  1.1    ragge #ifdef DEV_DEBUG
    221  1.2    ragge 	printf("Got packet: len %d idx %d maxlen %ld\n", len, crx, maxlen);
    222  1.1    ragge #endif
    223  1.1    ragge 	if (++crx == NRCV)
    224  1.1    ragge 		crx = 0;
    225  1.1    ragge 
    226  1.1    ragge 	if (len == 0)
    227  1.1    ragge 		goto retry;
    228  1.1    ragge 	return len;
    229  1.1    ragge }
    230  1.1    ragge 
    231  1.1    ragge 
    232  1.1    ragge int
    233  1.1    ragge de_put(struct iodesc *desc, void *pkt, size_t len)
    234  1.1    ragge {
    235  1.1    ragge 	volatile int to = 100000;
    236  1.1    ragge 	int csr0;
    237  1.1    ragge 
    238  1.1    ragge 	if ((csr0 = DE_RCSR(DE_PCSR0)) & PCSR0_INTR)
    239  1.1    ragge 		DE_WHIGH(csr0 >> 8);
    240  1.1    ragge #ifdef DEV_DEBUG
    241  1.2    ragge 	printf("de_put: len %ld\n", len);
    242  1.1    ragge #endif
    243  1.1    ragge retry:
    244  1.1    ragge 	if (to-- == 0)
    245  1.1    ragge 		return -1;
    246  1.1    ragge 
    247  1.1    ragge 	if (dc->dc_xrent[ctx].r_flags & RFLG_OWN)
    248  1.1    ragge 		goto retry;
    249  1.1    ragge 
    250  1.1    ragge 	bcopy(pkt, (char *)&dc->dc_xbuf[ctx][0], len);
    251  1.1    ragge 
    252  1.1    ragge 	dc->dc_xrent[ctx].r_slen = len;
    253  1.1    ragge 	dc->dc_xrent[ctx].r_tdrerr = 0;
    254  1.1    ragge 	dc->dc_xrent[ctx].r_flags = XFLG_OWN|XFLG_STP|XFLG_ENP;
    255  1.1    ragge 
    256  1.1    ragge 	DE_WLOW(CMD_PDMD);
    257  1.1    ragge 	dewait("start");
    258  1.1    ragge 
    259  1.1    ragge 	if (++ctx == NXMT)
    260  1.1    ragge 		ctx = 0;
    261  1.1    ragge 	return len;
    262  1.1    ragge }
    263  1.1    ragge 
    264  1.1    ragge int
    265  1.1    ragge declose(struct open_file *f)
    266  1.1    ragge {
    267  1.1    ragge 	DE_WCSR(DE_PCSR0, PCSR0_RSET);
    268  1.1    ragge 	dewait("close");
    269  1.1    ragge 	return 0;
    270  1.1    ragge }
    271  1.1    ragge 
    272  1.1    ragge void
    273  1.1    ragge dewait(char *fn)
    274  1.1    ragge {
    275  1.1    ragge 	int csr0;
    276  1.1    ragge 
    277  1.1    ragge #ifdef DEV_DEBUG
    278  1.1    ragge 	printf("dewait: %s...", fn);
    279  1.1    ragge #endif
    280  1.1    ragge 	while ((DE_RCSR(DE_PCSR0) & PCSR0_INTR) == 0)
    281  1.1    ragge 		;
    282  1.1    ragge 	csr0 = DE_RCSR(DE_PCSR0);
    283  1.1    ragge 	DE_WHIGH(csr0 >> 8);
    284  1.1    ragge #ifdef DEV_DEBUG
    285  1.1    ragge 	if (csr0 & PCSR0_PCEI)
    286  1.1    ragge 		printf("failed! CSR0 %x", csr0);
    287  1.1    ragge 	else
    288  1.1    ragge 		printf("done");
    289  1.1    ragge 	printf(", PCSR1 %x\n", DE_RCSR(DE_PCSR1));
    290  1.1    ragge #endif
    291  1.1    ragge }
    292