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