1 /* if_de.c 6.7 84/08/29 */ 2 #include "de.h" 3 #if NDE > 0 4 5 /* 6 * DEC DEUNA interface 7 * 8 * Lou Salkind 9 * New York University 10 * 11 * TODO: 12 * timeout routine (get statistics) 13 */ 14 #include "../machine/pte.h" 15 16 #include "param.h" 17 #include "systm.h" 18 #include "mbuf.h" 19 #include "buf.h" 20 #include "protosw.h" 21 #include "socket.h" 22 #include "vmmac.h" 23 #include "ioctl.h" 24 #include "errno.h" 25 26 #include "../net/if.h" 27 #include "../net/netisr.h" 28 #include "../net/route.h" 29 #include "../netinet/in.h" 30 #include "../netinet/in_systm.h" 31 #include "../netinet/ip.h" 32 #include "../netinet/ip_var.h" 33 #include "../netinet/if_ether.h" 34 #include "../netpup/pup.h" 35 36 #include "../vax/cpu.h" 37 #include "../vax/mtpr.h" 38 #include "if_dereg.h" 39 #include "if_uba.h" 40 #include "../vaxuba/ubareg.h" 41 #include "../vaxuba/ubavar.h" 42 43 #define NXMT 2 /* number of transmit buffers */ 44 #define NRCV 4 /* number of receive buffers (must be > 1) */ 45 #define NTOT (NXMT + NRCV) 46 47 int dedebug = 0; 48 49 int deprobe(), deattach(), deintr(); 50 struct uba_device *deinfo[NDE]; 51 u_short destd[] = { 0 }; 52 struct uba_driver dedriver = 53 { deprobe, 0, deattach, 0, destd, "de", deinfo }; 54 #define DEUNIT(x) minor(x) 55 int deinit(),deoutput(),deioctl(),dereset(); 56 struct mbuf *deget(); 57 58 59 /* 60 * The deuba structures generalizes the ifuba structure 61 * to an arbitrary number of receive and transmit buffers. 62 */ 63 struct ifxmt { 64 struct ifrw x_ifrw; /* mapping information */ 65 struct pte x_map[IF_MAXNUBAMR]; /* output base pages */ 66 short x_xswapd; /* mask of clusters swapped */ 67 struct mbuf *x_xtofree; /* pages being dma'ed out */ 68 }; 69 70 struct deuba { 71 short ifu_uban; /* uba number */ 72 short ifu_hlen; /* local net header length */ 73 struct uba_regs *ifu_uba; /* uba regs, in vm */ 74 struct ifrw ifu_r[NRCV]; /* receive information */ 75 struct ifxmt ifu_w[NXMT]; /* transmit information */ 76 short ifu_flags; /* used during uballoc's */ 77 }; 78 79 /* 80 * Ethernet software status per interface. 81 * 82 * Each interface is referenced by a network interface structure, 83 * ds_if, which the routing code uses to locate the interface. 84 * This structure contains the output queue for the interface, its address, ... 85 * We also have, for each interface, a UBA interface structure, which 86 * contains information about the UNIBUS resources held by the interface: 87 * map registers, buffered data paths, etc. Information is cached in this 88 * structure for use by the if_uba.c routines in running the interface 89 * efficiently. 90 */ 91 struct de_softc { 92 struct arpcom ds_ac; /* Ethernet common part */ 93 #define ds_if ds_ac.ac_if /* network-visible interface */ 94 #define ds_addr ds_ac.ac_enaddr /* hardware Ethernet address */ 95 int ds_flags; 96 #define DSF_LOCK 1 /* lock out destart */ 97 #define DSF_RUNNING 2 98 int ds_ubaddr; /* map info for incore structs */ 99 struct deuba ds_deuba; /* unibus resource structure */ 100 /* the following structures are always mapped in */ 101 struct de_pcbb ds_pcbb; /* port control block */ 102 struct de_ring ds_xrent[NXMT]; /* transmit ring entrys */ 103 struct de_ring ds_rrent[NRCV]; /* receive ring entrys */ 104 struct de_udbbuf ds_udbbuf; /* UNIBUS data buffer */ 105 /* end mapped area */ 106 #define INCORE_BASE(p) ((char *)&(p)->ds_pcbb) 107 #define RVAL_OFF(n) ((char *)&de_softc[0].n - INCORE_BASE(&de_softc[0])) 108 #define LVAL_OFF(n) ((char *)de_softc[0].n - INCORE_BASE(&de_softc[0])) 109 #define PCBB_OFFSET RVAL_OFF(ds_pcbb) 110 #define XRENT_OFFSET LVAL_OFF(ds_xrent) 111 #define RRENT_OFFSET LVAL_OFF(ds_rrent) 112 #define UDBBUF_OFFSET RVAL_OFF(ds_udbbuf) 113 #define INCORE_SIZE RVAL_OFF(ds_xindex) 114 int ds_xindex; /* UNA index into transmit chain */ 115 int ds_rindex; /* UNA index into receive chain */ 116 int ds_xfree; /* index for next transmit buffer */ 117 int ds_nxmit; /* # of transmits in progress */ 118 } de_softc[NDE]; 119 120 deprobe(reg) 121 caddr_t reg; 122 { 123 register int br, cvec; /* r11, r10 value-result */ 124 register struct dedevice *addr = (struct dedevice *)reg; 125 register i; 126 127 #ifdef lint 128 br = 0; cvec = br; br = cvec; 129 i = 0; derint(i); deintr(i); 130 #endif 131 132 addr->pcsr0 = PCSR0_RSET; 133 while ((addr->pcsr0 & PCSR0_INTR) == 0) 134 ; 135 /* make board interrupt by executing a GETPCBB command */ 136 addr->pcsr0 = PCSR0_INTE; 137 addr->pcsr2 = 0; 138 addr->pcsr3 = 0; 139 addr->pcsr0 = PCSR0_INTE|CMD_GETPCBB; 140 DELAY(100000); 141 return(1); 142 } 143 144 /* 145 * Interface exists: make available by filling in network interface 146 * record. System will initialize the interface when it is ready 147 * to accept packets. We get the ethernet address here. 148 */ 149 deattach(ui) 150 struct uba_device *ui; 151 { 152 register struct de_softc *ds = &de_softc[ui->ui_unit]; 153 register struct ifnet *ifp = &ds->ds_if; 154 register struct dedevice *addr = (struct dedevice *)ui->ui_addr; 155 struct sockaddr_in *sin; 156 int csr0; 157 158 ifp->if_unit = ui->ui_unit; 159 ifp->if_name = "de"; 160 ifp->if_mtu = ETHERMTU; 161 162 /* 163 * Reset the board and temporarily map 164 * the pcbb buffer onto the Unibus. 165 */ 166 addr->pcsr0 = PCSR0_RSET; 167 while ((addr->pcsr0 & PCSR0_INTR) == 0) 168 ; 169 csr0 = addr->pcsr0; 170 addr->pchigh = csr0 >> 8; 171 if (csr0 & PCSR0_PCEI) 172 printf("de%d: reset failed, csr0=%b csr1=%b\n", ui->ui_unit, 173 csr0, PCSR0_BITS, addr->pcsr1, PCSR1_BITS); 174 ds->ds_ubaddr = uballoc(ui->ui_ubanum, (char *)&ds->ds_pcbb, 175 sizeof (struct de_pcbb), 0); 176 addr->pcsr2 = ds->ds_ubaddr & 0xffff; 177 addr->pcsr3 = (ds->ds_ubaddr >> 16) & 0x3; 178 addr->pclow = CMD_GETPCBB; 179 while ((addr->pcsr0 & PCSR0_INTR) == 0) 180 ; 181 csr0 = addr->pcsr0; 182 addr->pchigh = csr0 >> 8; 183 if (csr0 & PCSR0_PCEI) 184 printf("de%d: pcbb failed, csr0=%b csr1=%b\n", ui->ui_unit, 185 csr0, PCSR0_BITS, addr->pcsr1, PCSR1_BITS); 186 ds->ds_pcbb.pcbb0 = FC_RDPHYAD; 187 addr->pclow = CMD_GETCMD; 188 while ((addr->pcsr0 & PCSR0_INTR) == 0) 189 ; 190 csr0 = addr->pcsr0; 191 addr->pchigh = csr0 >> 8; 192 if (csr0 & PCSR0_PCEI) 193 printf("de%d: rdphyad failed, csr0=%b csr1=%b\n", ui->ui_unit, 194 csr0, PCSR0_BITS, addr->pcsr1, PCSR1_BITS); 195 ubarelse(ui->ui_ubanum, &ds->ds_ubaddr); 196 if (dedebug) 197 printf("de%d: addr=%d:%d:%d:%d:%d:%d\n", ui->ui_unit, 198 ds->ds_pcbb.pcbb2&0xff, (ds->ds_pcbb.pcbb2>>8)&0xff, 199 ds->ds_pcbb.pcbb4&0xff, (ds->ds_pcbb.pcbb4>>8)&0xff, 200 ds->ds_pcbb.pcbb6&0xff, (ds->ds_pcbb.pcbb6>>8)&0xff); 201 bcopy((caddr_t)&ds->ds_pcbb.pcbb2, (caddr_t)&ds->ds_addr, 202 sizeof (ds->ds_addr)); 203 sin = (struct sockaddr_in *)&ifp->if_addr; 204 sin->sin_family = AF_INET; 205 ifp->if_init = deinit; 206 ifp->if_output = deoutput; 207 ifp->if_ioctl = deioctl; 208 ifp->if_reset = dereset; 209 ds->ds_deuba.ifu_flags = UBA_CANTWAIT; 210 #ifdef notdef 211 /* CAN WE USE BDP's ??? */ 212 ds->ds_deuba.ifu_flags |= UBA_NEEDBDP; 213 #endif 214 if_attach(ifp); 215 } 216 217 /* 218 * Reset of interface after UNIBUS reset. 219 * If interface is on specified uba, reset its state. 220 */ 221 dereset(unit, uban) 222 int unit, uban; 223 { 224 register struct uba_device *ui; 225 226 if (unit >= NDE || (ui = deinfo[unit]) == 0 || ui->ui_alive == 0 || 227 ui->ui_ubanum != uban) 228 return; 229 printf(" de%d", unit); 230 deinit(unit); 231 } 232 233 /* 234 * Initialization of interface; clear recorded pending 235 * operations, and reinitialize UNIBUS usage. 236 */ 237 deinit(unit) 238 int unit; 239 { 240 register struct de_softc *ds = &de_softc[unit]; 241 register struct uba_device *ui = deinfo[unit]; 242 register struct dedevice *addr; 243 register struct ifrw *ifrw; 244 register struct ifxmt *ifxp; 245 struct ifnet *ifp = &ds->ds_if; 246 struct sockaddr_in *sin; 247 int s; 248 struct de_ring *rp; 249 int incaddr; 250 int csr0; 251 252 sin = (struct sockaddr_in *)&ifp->if_addr; 253 if (sin->sin_addr.s_addr == 0) /* if address still unknown */ 254 return; 255 256 if (ifp->if_flags & IFF_RUNNING) 257 goto justarp; 258 if (de_ubainit(&ds->ds_deuba, ui->ui_ubanum, 259 sizeof (struct ether_header), (int)btoc(ETHERMTU)) == 0) { 260 printf("de%d: can't initialize\n", unit); 261 ds->ds_if.if_flags &= ~IFF_UP; 262 return; 263 } 264 ds->ds_ubaddr = uballoc(ui->ui_ubanum, INCORE_BASE(ds), INCORE_SIZE,0); 265 addr = (struct dedevice *)ui->ui_addr; 266 267 /* set the pcbb block address */ 268 incaddr = ds->ds_ubaddr + PCBB_OFFSET; 269 addr->pcsr2 = incaddr & 0xffff; 270 addr->pcsr3 = (incaddr >> 16) & 0x3; 271 addr->pclow = CMD_GETPCBB; 272 while ((addr->pcsr0 & PCSR0_INTR) == 0) 273 ; 274 csr0 = addr->pcsr0; 275 addr->pchigh = csr0 >> 8; 276 if (csr0 & PCSR0_PCEI) 277 printf("de%d: pcbb failed, csr0=%b csr1=%b\n", ui->ui_unit, 278 csr0, PCSR0_BITS, addr->pcsr1, PCSR1_BITS); 279 280 /* set the transmit and receive ring header addresses */ 281 incaddr = ds->ds_ubaddr + UDBBUF_OFFSET; 282 ds->ds_pcbb.pcbb0 = FC_WTRING; 283 ds->ds_pcbb.pcbb2 = incaddr & 0xffff; 284 ds->ds_pcbb.pcbb4 = (incaddr >> 16) & 0x3; 285 286 incaddr = ds->ds_ubaddr + XRENT_OFFSET; 287 ds->ds_udbbuf.b_tdrbl = incaddr & 0xffff; 288 ds->ds_udbbuf.b_tdrbh = (incaddr >> 16) & 0x3; 289 ds->ds_udbbuf.b_telen = sizeof (struct de_ring) / sizeof (short); 290 ds->ds_udbbuf.b_trlen = NXMT; 291 incaddr = ds->ds_ubaddr + RRENT_OFFSET; 292 ds->ds_udbbuf.b_rdrbl = incaddr & 0xffff; 293 ds->ds_udbbuf.b_rdrbh = (incaddr >> 16) & 0x3; 294 ds->ds_udbbuf.b_relen = sizeof (struct de_ring) / sizeof (short); 295 ds->ds_udbbuf.b_rrlen = NRCV; 296 297 addr->pclow = CMD_GETCMD; 298 while ((addr->pcsr0 & PCSR0_INTR) == 0) 299 ; 300 csr0 = addr->pcsr0; 301 addr->pchigh = csr0 >> 8; 302 if (csr0 & PCSR0_PCEI) 303 printf("de%d: wtring failed, csr0=%b csr1=%b\n", ui->ui_unit, 304 csr0, PCSR0_BITS, addr->pcsr1, PCSR1_BITS); 305 306 /* initialize the mode - enable hardware padding */ 307 ds->ds_pcbb.pcbb0 = FC_WTMODE; 308 /* let hardware do padding - set MTCH bit on broadcast */ 309 ds->ds_pcbb.pcbb2 = MOD_TPAD|MOD_HDX; 310 addr->pclow = CMD_GETCMD; 311 while ((addr->pcsr0 & PCSR0_INTR) == 0) 312 ; 313 csr0 = addr->pcsr0; 314 addr->pchigh = csr0 >> 8; 315 if (csr0 & PCSR0_PCEI) 316 printf("de%d: wtmode failed, csr0=%b csr1=%b\n", ui->ui_unit, 317 csr0, PCSR0_BITS, addr->pcsr1, PCSR1_BITS); 318 319 /* set up the receive and transmit ring entries */ 320 ifxp = &ds->ds_deuba.ifu_w[0]; 321 for (rp = &ds->ds_xrent[0]; rp < &ds->ds_xrent[NXMT]; rp++) { 322 rp->r_segbl = ifxp->x_ifrw.ifrw_info & 0xffff; 323 rp->r_segbh = (ifxp->x_ifrw.ifrw_info >> 16) & 0x3; 324 rp->r_flags = 0; 325 ifxp++; 326 } 327 ifrw = &ds->ds_deuba.ifu_r[0]; 328 for (rp = &ds->ds_rrent[0]; rp < &ds->ds_rrent[NRCV]; rp++) { 329 rp->r_slen = sizeof (struct de_buf); 330 rp->r_segbl = ifrw->ifrw_info & 0xffff; 331 rp->r_segbh = (ifrw->ifrw_info >> 16) & 0x3; 332 rp->r_flags = RFLG_OWN; /* hang receive */ 333 ifrw++; 334 } 335 336 /* start up the board (rah rah) */ 337 s = splimp(); 338 ds->ds_rindex = ds->ds_xindex = ds->ds_xfree = 0; 339 ds->ds_if.if_flags |= IFF_UP|IFF_RUNNING; 340 destart(unit); /* queue output packets */ 341 addr->pclow = PCSR0_INTE; /* avoid interlock */ 342 addr->pclow = CMD_START | PCSR0_INTE; 343 ds->ds_flags |= DSF_RUNNING; 344 splx(s); 345 justarp: 346 if_rtinit(&ds->ds_if, RTF_UP); 347 arpwhohas(&ds->ds_ac, &sin->sin_addr); 348 } 349 350 /* 351 * Setup output on interface. 352 * Get another datagram to send off of the interface queue, 353 * and map it to the interface before starting the output. 354 */ 355 destart(unit) 356 int unit; 357 { 358 int len; 359 struct uba_device *ui = deinfo[unit]; 360 struct dedevice *addr = (struct dedevice *)ui->ui_addr; 361 register struct de_softc *ds = &de_softc[unit]; 362 register struct de_ring *rp; 363 struct mbuf *m; 364 register int nxmit; 365 366 /* 367 * the following test is necessary, since 368 * the code is not reentrant and we have 369 * multiple transmission buffers. 370 */ 371 if (ds->ds_flags & DSF_LOCK) 372 return; 373 for (nxmit = ds->ds_nxmit; nxmit < NXMT; nxmit++) { 374 IF_DEQUEUE(&ds->ds_if.if_snd, m); 375 if (m == 0) 376 break; 377 rp = &ds->ds_xrent[ds->ds_xfree]; 378 if (rp->r_flags & XFLG_OWN) 379 panic("deuna xmit in progress"); 380 len = deput(&ds->ds_deuba, ds->ds_xfree, m); 381 if (ds->ds_deuba.ifu_flags & UBA_NEEDBDP) 382 UBAPURGE(ds->ds_deuba.ifu_uba, 383 ds->ds_deuba.ifu_w[ds->ds_xfree].x_ifrw.ifrw_bdp); 384 rp->r_slen = len; 385 rp->r_tdrerr = 0; 386 rp->r_flags = XFLG_STP|XFLG_ENP|XFLG_OWN; 387 388 ds->ds_xfree++; 389 if (ds->ds_xfree == NXMT) 390 ds->ds_xfree = 0; 391 } 392 if (ds->ds_nxmit != nxmit) { 393 ds->ds_nxmit = nxmit; 394 if (ds->ds_flags & DSF_RUNNING) 395 addr->pclow = PCSR0_INTE|CMD_PDMD; 396 } 397 } 398 399 /* 400 * Command done interrupt. 401 */ 402 deintr(unit) 403 int unit; 404 { 405 struct uba_device *ui = deinfo[unit]; 406 register struct dedevice *addr = (struct dedevice *)ui->ui_addr; 407 register struct de_softc *ds = &de_softc[unit]; 408 register struct de_ring *rp; 409 register struct ifxmt *ifxp; 410 short csr0; 411 412 /* save flags right away - clear out interrupt bits */ 413 csr0 = addr->pcsr0; 414 addr->pchigh = csr0 >> 8; 415 416 417 ds->ds_flags |= DSF_LOCK; /* prevent entering destart */ 418 /* 419 * if receive, put receive buffer on mbuf 420 * and hang the request again 421 */ 422 derecv(unit); 423 424 /* 425 * Poll transmit ring and check status. 426 * Be careful about loopback requests. 427 * Then free buffer space and check for 428 * more transmit requests. 429 */ 430 for ( ; ds->ds_nxmit > 0; ds->ds_nxmit--) { 431 rp = &ds->ds_xrent[ds->ds_xindex]; 432 if (rp->r_flags & XFLG_OWN) 433 break; 434 ds->ds_if.if_opackets++; 435 ifxp = &ds->ds_deuba.ifu_w[ds->ds_xindex]; 436 /* check for unusual conditions */ 437 if (rp->r_flags & (XFLG_ERRS|XFLG_MTCH|XFLG_ONE|XFLG_MORE)) { 438 if (rp->r_flags & XFLG_ERRS) { 439 /* output error */ 440 ds->ds_if.if_oerrors++; 441 if (dedebug) 442 printf("de%d: oerror, flags=%b tdrerr=%b (len=%d)\n", 443 unit, rp->r_flags, XFLG_BITS, 444 rp->r_tdrerr, XERR_BITS, rp->r_slen); 445 } else if (rp->r_flags & XFLG_ONE) { 446 /* one collision */ 447 ds->ds_if.if_collisions++; 448 } else if (rp->r_flags & XFLG_MORE) { 449 /* more than one collision */ 450 ds->ds_if.if_collisions += 2; /* guess */ 451 } else if (rp->r_flags & XFLG_MTCH) { 452 /* received our own packet */ 453 ds->ds_if.if_ipackets++; 454 deread(ds, &ifxp->x_ifrw, 455 rp->r_slen - sizeof (struct ether_header)); 456 } 457 } 458 if (ifxp->x_xtofree) { 459 m_freem(ifxp->x_xtofree); 460 ifxp->x_xtofree = 0; 461 } 462 /* check if next transmit buffer also finished */ 463 ds->ds_xindex++; 464 if (ds->ds_xindex == NXMT) 465 ds->ds_xindex = 0; 466 } 467 ds->ds_flags &= ~DSF_LOCK; 468 destart(unit); 469 470 if (csr0 & PCSR0_RCBI) { 471 printf("de%d: buffer unavailable\n", unit); 472 addr->pclow = PCSR0_INTE|CMD_PDMD; 473 } 474 } 475 476 /* 477 * Ethernet interface receiver interface. 478 * If input error just drop packet. 479 * Otherwise purge input buffered data path and examine 480 * packet to determine type. If can't determine length 481 * from type, then have to drop packet. Othewise decapsulate 482 * packet based on type and pass to type specific higher-level 483 * input routine. 484 */ 485 derecv(unit) 486 int unit; 487 { 488 register struct de_softc *ds = &de_softc[unit]; 489 register struct de_ring *rp; 490 int len; 491 492 rp = &ds->ds_rrent[ds->ds_rindex]; 493 while ((rp->r_flags & RFLG_OWN) == 0) { 494 ds->ds_if.if_ipackets++; 495 if (ds->ds_deuba.ifu_flags & UBA_NEEDBDP) 496 UBAPURGE(ds->ds_deuba.ifu_uba, 497 ds->ds_deuba.ifu_r[ds->ds_rindex].ifrw_bdp); 498 len = (rp->r_lenerr&RERR_MLEN) - sizeof (struct ether_header) 499 - 4; /* don't forget checksum! */ 500 /* check for errors */ 501 if ((rp->r_flags & (RFLG_ERRS|RFLG_FRAM|RFLG_OFLO|RFLG_CRC)) || 502 (rp->r_flags&(RFLG_STP|RFLG_ENP)) != (RFLG_STP|RFLG_ENP) || 503 (rp->r_lenerr & (RERR_BUFL|RERR_UBTO|RERR_NCHN)) || 504 len < ETHERMIN || len > ETHERMTU) { 505 ds->ds_if.if_ierrors++; 506 if (dedebug) 507 printf("de%d: ierror, flags=%b lenerr=%b (len=%d)\n", 508 unit, rp->r_flags, RFLG_BITS, rp->r_lenerr, 509 RERR_BITS, len); 510 } else 511 deread(ds, &ds->ds_deuba.ifu_r[ds->ds_rindex], len); 512 513 /* hang the receive buffer again */ 514 rp->r_lenerr = 0; 515 rp->r_flags = RFLG_OWN; 516 517 /* check next receive buffer */ 518 ds->ds_rindex++; 519 if (ds->ds_rindex == NRCV) 520 ds->ds_rindex = 0; 521 rp = &ds->ds_rrent[ds->ds_rindex]; 522 } 523 } 524 525 /* 526 * Pass a packet to the higher levels. 527 * We deal with the trailer protocol here. 528 */ 529 deread(ds, ifrw, len) 530 register struct de_softc *ds; 531 struct ifrw *ifrw; 532 int len; 533 { 534 struct ether_header *eh; 535 struct mbuf *m; 536 int off, resid; 537 int s; 538 register struct ifqueue *inq; 539 540 /* 541 * Deal with trailer protocol: if type is PUP trailer 542 * get true type from first 16-bit word past data. 543 * Remember that type was trailer by setting off. 544 */ 545 eh = (struct ether_header *)ifrw->ifrw_addr; 546 eh->ether_type = ntohs((u_short)eh->ether_type); 547 #define dedataaddr(eh, off, type) ((type)(((caddr_t)((eh)+1)+(off)))) 548 if (eh->ether_type >= ETHERPUP_TRAIL && 549 eh->ether_type < ETHERPUP_TRAIL+ETHERPUP_NTRAILER) { 550 off = (eh->ether_type - ETHERPUP_TRAIL) * 512; 551 if (off >= ETHERMTU) 552 return; /* sanity */ 553 eh->ether_type = ntohs(*dedataaddr(eh, off, u_short *)); 554 resid = ntohs(*(dedataaddr(eh, off+2, u_short *))); 555 if (off + resid > len) 556 return; /* sanity */ 557 len = off + resid; 558 } else 559 off = 0; 560 if (len == 0) 561 return; 562 563 /* 564 * Pull packet off interface. Off is nonzero if packet 565 * has trailing header; deget will then force this header 566 * information to be at the front, but we still have to drop 567 * the type and length which are at the front of any trailer data. 568 */ 569 m = deget(&ds->ds_deuba, ifrw, len, off); 570 if (m == 0) 571 return; 572 if (off) { 573 m->m_off += 2 * sizeof (u_short); 574 m->m_len -= 2 * sizeof (u_short); 575 } 576 switch (eh->ether_type) { 577 578 #ifdef INET 579 case ETHERPUP_IPTYPE: 580 schednetisr(NETISR_IP); 581 inq = &ipintrq; 582 break; 583 584 case ETHERPUP_ARPTYPE: 585 arpinput(&ds->ds_ac, m); 586 return; 587 #endif 588 default: 589 m_freem(m); 590 return; 591 } 592 593 s = splimp(); 594 if (IF_QFULL(inq)) { 595 IF_DROP(inq); 596 splx(s); 597 m_freem(m); 598 return; 599 } 600 IF_ENQUEUE(inq, m); 601 splx(s); 602 } 603 604 /* 605 * Ethernet output routine. 606 * Encapsulate a packet of type family for the local net. 607 * Use trailer local net encapsulation if enough data in first 608 * packet leaves a multiple of 512 bytes of data in remainder. 609 */ 610 deoutput(ifp, m0, dst) 611 struct ifnet *ifp; 612 struct mbuf *m0; 613 struct sockaddr *dst; 614 { 615 int type, s, error; 616 struct ether_addr edst; 617 struct in_addr idst; 618 register struct de_softc *ds = &de_softc[ifp->if_unit]; 619 register struct mbuf *m = m0; 620 register struct ether_header *eh; 621 register int off; 622 623 switch (dst->sa_family) { 624 625 #ifdef INET 626 case AF_INET: 627 idst = ((struct sockaddr_in *)dst)->sin_addr; 628 if (!arpresolve(&ds->ds_ac, m, &idst, &edst)) 629 return (0); /* if not yet resolved */ 630 off = ntohs((u_short)mtod(m, struct ip *)->ip_len) - m->m_len; 631 /* need per host negotiation */ 632 if ((ifp->if_flags & IFF_NOTRAILERS) == 0) 633 if (off > 0 && (off & 0x1ff) == 0 && 634 m->m_off >= MMINOFF + 2 * sizeof (u_short)) { 635 type = ETHERPUP_TRAIL + (off>>9); 636 m->m_off -= 2 * sizeof (u_short); 637 m->m_len += 2 * sizeof (u_short); 638 *mtod(m, u_short *) = htons((u_short)ETHERPUP_IPTYPE); 639 *(mtod(m, u_short *) + 1) = htons((u_short)m->m_len); 640 goto gottrailertype; 641 } 642 type = ETHERPUP_IPTYPE; 643 off = 0; 644 goto gottype; 645 #endif 646 647 case AF_UNSPEC: 648 eh = (struct ether_header *)dst->sa_data; 649 edst = eh->ether_dhost; 650 type = eh->ether_type; 651 goto gottype; 652 653 default: 654 printf("de%d: can't handle af%d\n", ifp->if_unit, 655 dst->sa_family); 656 error = EAFNOSUPPORT; 657 goto bad; 658 } 659 660 gottrailertype: 661 /* 662 * Packet to be sent as trailer: move first packet 663 * (control information) to end of chain. 664 */ 665 while (m->m_next) 666 m = m->m_next; 667 m->m_next = m0; 668 m = m0->m_next; 669 m0->m_next = 0; 670 m0 = m; 671 672 gottype: 673 /* 674 * Add local net header. If no space in first mbuf, 675 * allocate another. 676 */ 677 if (m->m_off > MMAXOFF || 678 MMINOFF + sizeof (struct ether_header) > m->m_off) { 679 m = m_get(M_DONTWAIT, MT_HEADER); 680 if (m == 0) { 681 error = ENOBUFS; 682 goto bad; 683 } 684 m->m_next = m0; 685 m->m_off = MMINOFF; 686 m->m_len = sizeof (struct ether_header); 687 } else { 688 m->m_off -= sizeof (struct ether_header); 689 m->m_len += sizeof (struct ether_header); 690 } 691 eh = mtod(m, struct ether_header *); 692 eh->ether_type = htons((u_short)type); 693 eh->ether_dhost = edst; 694 /* DEUNA fills in source address */ 695 696 /* 697 * Queue message on interface, and start output if interface 698 * not yet active. 699 */ 700 s = splimp(); 701 if (IF_QFULL(&ifp->if_snd)) { 702 IF_DROP(&ifp->if_snd); 703 splx(s); 704 m_freem(m); 705 return (ENOBUFS); 706 } 707 IF_ENQUEUE(&ifp->if_snd, m); 708 destart(ifp->if_unit); 709 splx(s); 710 return (0); 711 712 bad: 713 m_freem(m0); 714 return (error); 715 } 716 717 /* 718 * Routines supporting UNIBUS network interfaces. 719 */ 720 721 /* 722 * Init UNIBUS for interface on uban whose headers of size hlen are to 723 * end on a page boundary. We allocate a UNIBUS map register for the page 724 * with the header, and nmr more UNIBUS map registers for i/o on the adapter, 725 * doing this for each receive and transmit buffer. We also 726 * allocate page frames in the mbuffer pool for these pages. 727 */ 728 de_ubainit(ifu, uban, hlen, nmr) 729 register struct deuba *ifu; 730 int uban, hlen, nmr; 731 { 732 register caddr_t cp, dp; 733 register struct ifrw *ifrw; 734 register struct ifxmt *ifxp; 735 int i, ncl; 736 737 ncl = clrnd(nmr + CLSIZE) / CLSIZE; 738 if (ifu->ifu_r[0].ifrw_addr) 739 /* 740 * If the first read buffer has a non-zero 741 * address, it means we have already allocated core 742 */ 743 cp = ifu->ifu_r[0].ifrw_addr - (CLBYTES - hlen); 744 else { 745 cp = m_clalloc(NTOT * ncl, MPG_SPACE); 746 if (cp == 0) 747 return (0); 748 ifu->ifu_hlen = hlen; 749 ifu->ifu_uban = uban; 750 ifu->ifu_uba = uba_hd[uban].uh_uba; 751 dp = cp + CLBYTES - hlen; 752 for (ifrw = ifu->ifu_r; ifrw < &ifu->ifu_r[NRCV]; ifrw++) { 753 ifrw->ifrw_addr = dp; 754 dp += ncl * CLBYTES; 755 } 756 for (ifxp = ifu->ifu_w; ifxp < &ifu->ifu_w[NXMT]; ifxp++) { 757 ifxp->x_ifrw.ifrw_addr = dp; 758 dp += ncl * CLBYTES; 759 } 760 } 761 /* allocate for receive ring */ 762 for (ifrw = ifu->ifu_r; ifrw < &ifu->ifu_r[NRCV]; ifrw++) { 763 if (de_ubaalloc(ifu, ifrw, nmr) == 0) { 764 struct ifrw *rw; 765 766 for (rw = ifu->ifu_r; rw < ifrw; rw++) 767 ubarelse(ifu->ifu_uban, &rw->ifrw_info); 768 goto bad; 769 } 770 } 771 /* and now transmit ring */ 772 for (ifxp = ifu->ifu_w; ifxp < &ifu->ifu_w[NXMT]; ifxp++) { 773 ifrw = &ifxp->x_ifrw; 774 if (de_ubaalloc(ifu, ifrw, nmr) == 0) { 775 struct ifxmt *xp; 776 777 for (xp = ifu->ifu_w; xp < ifxp; xp++) 778 ubarelse(ifu->ifu_uban, &xp->x_ifrw.ifrw_info); 779 for (ifrw = ifu->ifu_r; ifrw < &ifu->ifu_r[NRCV]; ifrw++) 780 ubarelse(ifu->ifu_uban, &ifrw->ifrw_info); 781 goto bad; 782 } 783 for (i = 0; i < nmr; i++) 784 ifxp->x_map[i] = ifrw->ifrw_mr[i]; 785 ifxp->x_xswapd = 0; 786 } 787 return (1); 788 bad: 789 m_pgfree(cp, NTOT * ncl); 790 ifu->ifu_r[0].ifrw_addr = 0; 791 return(0); 792 } 793 794 /* 795 * Setup either a ifrw structure by allocating UNIBUS map registers, 796 * possibly a buffered data path, and initializing the fields of 797 * the ifrw structure to minimize run-time overhead. 798 */ 799 static 800 de_ubaalloc(ifu, ifrw, nmr) 801 struct deuba *ifu; 802 register struct ifrw *ifrw; 803 int nmr; 804 { 805 register int info; 806 807 info = 808 uballoc(ifu->ifu_uban, ifrw->ifrw_addr, nmr*NBPG + ifu->ifu_hlen, 809 ifu->ifu_flags); 810 if (info == 0) 811 return (0); 812 ifrw->ifrw_info = info; 813 ifrw->ifrw_bdp = UBAI_BDP(info); 814 ifrw->ifrw_proto = UBAMR_MRV | (UBAI_BDP(info) << UBAMR_DPSHIFT); 815 ifrw->ifrw_mr = &ifu->ifu_uba->uba_map[UBAI_MR(info) + 1]; 816 return (1); 817 } 818 819 /* 820 * Pull read data off a interface. 821 * Len is length of data, with local net header stripped. 822 * Off is non-zero if a trailer protocol was used, and 823 * gives the offset of the trailer information. 824 * We copy the trailer information and then all the normal 825 * data into mbufs. When full cluster sized units are present 826 * on the interface on cluster boundaries we can get them more 827 * easily by remapping, and take advantage of this here. 828 */ 829 struct mbuf * 830 deget(ifu, ifrw, totlen, off0) 831 register struct deuba *ifu; 832 register struct ifrw *ifrw; 833 int totlen, off0; 834 { 835 struct mbuf *top, **mp, *m; 836 int off = off0, len; 837 register caddr_t cp = ifrw->ifrw_addr + ifu->ifu_hlen; 838 839 top = 0; 840 mp = ⊤ 841 while (totlen > 0) { 842 MGET(m, M_DONTWAIT, MT_DATA); 843 if (m == 0) 844 goto bad; 845 if (off) { 846 len = totlen - off; 847 cp = ifrw->ifrw_addr + ifu->ifu_hlen + off; 848 } else 849 len = totlen; 850 if (len >= CLBYTES) { 851 struct mbuf *p; 852 struct pte *cpte, *ppte; 853 int x, *ip, i; 854 855 MCLGET(p, 1); 856 if (p == 0) 857 goto nopage; 858 len = m->m_len = CLBYTES; 859 m->m_off = (int)p - (int)m; 860 if (!claligned(cp)) 861 goto copy; 862 863 /* 864 * Switch pages mapped to UNIBUS with new page p, 865 * as quick form of copy. Remap UNIBUS and invalidate. 866 */ 867 cpte = &Mbmap[mtocl(cp)*CLSIZE]; 868 ppte = &Mbmap[mtocl(p)*CLSIZE]; 869 x = btop(cp - ifrw->ifrw_addr); 870 ip = (int *)&ifrw->ifrw_mr[x]; 871 for (i = 0; i < CLSIZE; i++) { 872 struct pte t; 873 t = *ppte; *ppte++ = *cpte; *cpte = t; 874 *ip++ = 875 cpte++->pg_pfnum|ifrw->ifrw_proto; 876 mtpr(TBIS, cp); 877 cp += NBPG; 878 mtpr(TBIS, (caddr_t)p); 879 p += NBPG / sizeof (*p); 880 } 881 goto nocopy; 882 } 883 nopage: 884 m->m_len = MIN(MLEN, len); 885 m->m_off = MMINOFF; 886 copy: 887 bcopy(cp, mtod(m, caddr_t), (unsigned)m->m_len); 888 cp += m->m_len; 889 nocopy: 890 *mp = m; 891 mp = &m->m_next; 892 if (off) { 893 /* sort of an ALGOL-W style for statement... */ 894 off += m->m_len; 895 if (off == totlen) { 896 cp = ifrw->ifrw_addr + ifu->ifu_hlen; 897 off = 0; 898 totlen = off0; 899 } 900 } else 901 totlen -= m->m_len; 902 } 903 return (top); 904 bad: 905 m_freem(top); 906 return (0); 907 } 908 909 /* 910 * Map a chain of mbufs onto a network interface 911 * in preparation for an i/o operation. 912 * The argument chain of mbufs includes the local network 913 * header which is copied to be in the mapped, aligned 914 * i/o space. 915 */ 916 deput(ifu, n, m) 917 struct deuba *ifu; 918 int n; 919 register struct mbuf *m; 920 { 921 register struct mbuf *mp; 922 register caddr_t cp; 923 register struct ifxmt *ifxp; 924 register struct ifrw *ifrw; 925 register int i; 926 int xswapd = 0; 927 int x, cc, t; 928 caddr_t dp; 929 930 ifxp = &ifu->ifu_w[n]; 931 ifrw = &ifxp->x_ifrw; 932 cp = ifrw->ifrw_addr; 933 while (m) { 934 dp = mtod(m, char *); 935 if (claligned(cp) && claligned(dp) && m->m_len == CLBYTES) { 936 struct pte *pte; int *ip; 937 pte = &Mbmap[mtocl(dp)*CLSIZE]; 938 x = btop(cp - ifrw->ifrw_addr); 939 ip = (int *)&ifrw->ifrw_mr[x]; 940 for (i = 0; i < CLSIZE; i++) 941 *ip++ = 942 ifrw->ifrw_proto | pte++->pg_pfnum; 943 xswapd |= 1 << (x>>(CLSHIFT-PGSHIFT)); 944 mp = m->m_next; 945 m->m_next = ifxp->x_xtofree; 946 ifxp->x_xtofree = m; 947 cp += m->m_len; 948 } else { 949 bcopy(mtod(m, caddr_t), cp, (unsigned)m->m_len); 950 cp += m->m_len; 951 MFREE(m, mp); 952 } 953 m = mp; 954 } 955 956 /* 957 * Xswapd is the set of clusters we just mapped out. Ifxp->x_xswapd 958 * is the set of clusters mapped out from before. We compute 959 * the number of clusters involved in this operation in x. 960 * Clusters mapped out before and involved in this operation 961 * should be unmapped so original pages will be accessed by the device. 962 */ 963 cc = cp - ifrw->ifrw_addr; 964 x = ((cc - ifu->ifu_hlen) + CLBYTES - 1) >> CLSHIFT; 965 ifxp->x_xswapd &= ~xswapd; 966 while (i = ffs(ifxp->x_xswapd)) { 967 i--; 968 if (i >= x) 969 break; 970 ifxp->x_xswapd &= ~(1<<i); 971 i *= CLSIZE; 972 for (t = 0; t < CLSIZE; t++) { 973 ifrw->ifrw_mr[i] = ifxp->x_map[i]; 974 i++; 975 } 976 } 977 ifxp->x_xswapd |= xswapd; 978 return (cc); 979 } 980 981 /* 982 * Process an ioctl request. 983 */ 984 deioctl(ifp, cmd, data) 985 register struct ifnet *ifp; 986 int cmd; 987 caddr_t data; 988 { 989 register struct ifreq *ifr = (struct ifreq *)data; 990 int s = splimp(), error = 0; 991 992 switch (cmd) { 993 994 case SIOCSIFADDR: 995 if (ifp->if_flags & IFF_RUNNING) 996 if_rtinit(ifp, -1); /* delete previous route */ 997 desetaddr(ifp, (struct sockaddr_in *)&ifr->ifr_addr); 998 deinit(ifp->if_unit); 999 break; 1000 1001 default: 1002 error = EINVAL; 1003 } 1004 splx(s); 1005 return (error); 1006 } 1007 1008 desetaddr(ifp, sin) 1009 register struct ifnet *ifp; 1010 register struct sockaddr_in *sin; 1011 { 1012 1013 ifp->if_addr = *(struct sockaddr *)sin; 1014 ifp->if_net = in_netof(sin->sin_addr); 1015 ifp->if_host[0] = in_lnaof(sin->sin_addr); 1016 sin = (struct sockaddr_in *)&ifp->if_broadaddr; 1017 sin->sin_family = AF_INET; 1018 sin->sin_addr = if_makeaddr(ifp->if_net, INADDR_ANY); 1019 ifp->if_flags |= IFF_BROADCAST; 1020 } 1021 #endif 1022