1 1.101 riastrad /* $NetBSD: dp8390.c,v 1.101 2024/06/29 12:11:11 riastradh Exp $ */ 2 1.1 scottr 3 1.1 scottr /* 4 1.1 scottr * Device driver for National Semiconductor DS8390/WD83C690 based ethernet 5 1.1 scottr * adapters. 6 1.1 scottr * 7 1.1 scottr * Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved. 8 1.1 scottr * 9 1.1 scottr * Copyright (C) 1993, David Greenman. This software may be used, modified, 10 1.1 scottr * copied, distributed, and sold, in both source and binary form provided that 11 1.1 scottr * the above copyright and these terms are retained. Under no circumstances is 12 1.1 scottr * the author responsible for the proper functioning of this software, nor does 13 1.1 scottr * the author assume any responsibility for damages incurred with its use. 14 1.1 scottr */ 15 1.49 lukem 16 1.49 lukem #include <sys/cdefs.h> 17 1.101 riastrad __KERNEL_RCSID(0, "$NetBSD: dp8390.c,v 1.101 2024/06/29 12:11:11 riastradh Exp $"); 18 1.1 scottr 19 1.12 jonathan #include "opt_inet.h" 20 1.1 scottr 21 1.1 scottr #include <sys/param.h> 22 1.1 scottr #include <sys/systm.h> 23 1.1 scottr #include <sys/device.h> 24 1.1 scottr #include <sys/errno.h> 25 1.1 scottr #include <sys/ioctl.h> 26 1.1 scottr #include <sys/mbuf.h> 27 1.1 scottr #include <sys/socket.h> 28 1.1 scottr #include <sys/syslog.h> 29 1.82 riastrad #include <sys/rndsource.h> 30 1.93 msaitoh #include <sys/bus.h> 31 1.20 thorpej 32 1.1 scottr #include <net/if.h> 33 1.1 scottr #include <net/if_dl.h> 34 1.1 scottr #include <net/if_types.h> 35 1.8 thorpej #include <net/if_media.h> 36 1.1 scottr #include <net/if_ether.h> 37 1.88 msaitoh #include <net/bpf.h> 38 1.1 scottr 39 1.1 scottr #ifdef INET 40 1.1 scottr #include <netinet/in.h> 41 1.1 scottr #include <netinet/in_systm.h> 42 1.1 scottr #include <netinet/in_var.h> 43 1.1 scottr #include <netinet/ip.h> 44 1.1 scottr #include <netinet/if_inarp.h> 45 1.1 scottr #endif 46 1.1 scottr 47 1.1 scottr #include <dev/ic/dp8390reg.h> 48 1.1 scottr #include <dev/ic/dp8390var.h> 49 1.1 scottr 50 1.1 scottr #ifdef DEBUG 51 1.51 kristerw int dp8390_debug = 0; 52 1.1 scottr #endif 53 1.1 scottr 54 1.98 thorpej static void dp8390_halt(struct dp8390_softc *); 55 1.98 thorpej 56 1.77 tsutsui static void dp8390_xmit(struct dp8390_softc *); 57 1.1 scottr 58 1.77 tsutsui static void dp8390_read_hdr(struct dp8390_softc *, int, struct dp8390_ring *); 59 1.77 tsutsui static int dp8390_ring_copy(struct dp8390_softc *, int, void *, u_short); 60 1.77 tsutsui static int dp8390_write_mbuf(struct dp8390_softc *, struct mbuf *, int); 61 1.1 scottr 62 1.77 tsutsui static int dp8390_test_mem(struct dp8390_softc *); 63 1.1 scottr 64 1.42 thorpej /* 65 1.42 thorpej * Standard media init routine for the dp8390. 66 1.42 thorpej */ 67 1.42 thorpej void 68 1.42 thorpej dp8390_media_init(struct dp8390_softc *sc) 69 1.42 thorpej { 70 1.42 thorpej 71 1.42 thorpej ifmedia_init(&sc->sc_media, 0, dp8390_mediachange, dp8390_mediastatus); 72 1.93 msaitoh ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_MANUAL, 0, NULL); 73 1.93 msaitoh ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_MANUAL); 74 1.42 thorpej } 75 1.4 scottr 76 1.1 scottr /* 77 1.1 scottr * Do bus-independent setup. 78 1.1 scottr */ 79 1.1 scottr int 80 1.70 dsl dp8390_config(struct dp8390_softc *sc) 81 1.1 scottr { 82 1.1 scottr struct ifnet *ifp = &sc->sc_ec.ec_if; 83 1.42 thorpej int rv; 84 1.1 scottr 85 1.1 scottr rv = 1; 86 1.1 scottr 87 1.76 tsutsui if (sc->test_mem == NULL) 88 1.1 scottr sc->test_mem = dp8390_test_mem; 89 1.76 tsutsui if (sc->read_hdr == NULL) 90 1.76 tsutsui sc->read_hdr = dp8390_read_hdr; 91 1.76 tsutsui if (sc->recv_int == NULL) 92 1.76 tsutsui sc->recv_int = dp8390_rint; 93 1.76 tsutsui if (sc->ring_copy == NULL) 94 1.76 tsutsui sc->ring_copy = dp8390_ring_copy; 95 1.76 tsutsui if (sc->write_mbuf == NULL) 96 1.76 tsutsui sc->write_mbuf = dp8390_write_mbuf; 97 1.1 scottr 98 1.1 scottr /* Allocate one xmit buffer if < 16k, two buffers otherwise. */ 99 1.1 scottr if ((sc->mem_size < 16384) || 100 1.1 scottr (sc->sc_flags & DP8390_NO_MULTI_BUFFERING)) 101 1.1 scottr sc->txb_cnt = 1; 102 1.27 enami else if (sc->mem_size < 8192 * 3) 103 1.27 enami sc->txb_cnt = 2; 104 1.1 scottr else 105 1.27 enami sc->txb_cnt = 3; 106 1.1 scottr 107 1.7 thorpej sc->tx_page_start = sc->mem_start >> ED_PAGE_SHIFT; 108 1.1 scottr sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE; 109 1.1 scottr sc->rec_page_stop = sc->tx_page_start + (sc->mem_size >> ED_PAGE_SHIFT); 110 1.74 tsutsui sc->mem_ring = sc->mem_start + 111 1.74 tsutsui ((sc->txb_cnt * ED_TXBUF_SIZE) << ED_PAGE_SHIFT); 112 1.1 scottr sc->mem_end = sc->mem_start + sc->mem_size; 113 1.1 scottr 114 1.1 scottr /* Now zero memory and verify that it is clear. */ 115 1.1 scottr if ((*sc->test_mem)(sc)) 116 1.1 scottr goto out; 117 1.1 scottr 118 1.1 scottr /* Set interface to stopped condition (reset). */ 119 1.98 thorpej dp8390_halt(sc); 120 1.98 thorpej 121 1.98 thorpej callout_init(&sc->sc_tick_ch, 0); 122 1.1 scottr 123 1.1 scottr /* Initialize ifnet structure. */ 124 1.68 cube strcpy(ifp->if_xname, device_xname(sc->sc_dev)); 125 1.1 scottr ifp->if_softc = sc; 126 1.1 scottr ifp->if_start = dp8390_start; 127 1.1 scottr ifp->if_ioctl = dp8390_ioctl; 128 1.77 tsutsui if (ifp->if_watchdog == NULL) 129 1.1 scottr ifp->if_watchdog = dp8390_watchdog; 130 1.92 msaitoh ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 131 1.41 thorpej IFQ_SET_READY(&ifp->if_snd); 132 1.1 scottr 133 1.43 thorpej /* Print additional info when attached. */ 134 1.68 cube aprint_normal_dev(sc->sc_dev, "Ethernet address %s\n", 135 1.43 thorpej ether_sprintf(sc->sc_enaddr)); 136 1.43 thorpej 137 1.99 thorpej /* 138 1.99 thorpej * Initialize media structures. We'll default to pointing ec_ifmedia 139 1.99 thorpej * at our embedded media structure. A card front-end can initialize 140 1.99 thorpej * ec_mii if it has an MII interface. (Note that sc_media is an 141 1.99 thorpej * alias of sc_mii.mii_media in dp8390_softc.) 142 1.99 thorpej */ 143 1.99 thorpej sc->sc_ec.ec_ifmedia = &sc->sc_media; 144 1.42 thorpej (*sc->sc_media_init)(sc); 145 1.42 thorpej 146 1.93 msaitoh /* We can support 802.1Q VLAN-sized frames. */ 147 1.39 bouyer sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_MTU; 148 1.8 thorpej 149 1.1 scottr /* Attach the interface. */ 150 1.1 scottr if_attach(ifp); 151 1.87 ozaki if_deferred_start_init(ifp, NULL); 152 1.1 scottr ether_ifattach(ifp, sc->sc_enaddr); 153 1.1 scottr 154 1.68 cube rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), 155 1.81 tls RND_TYPE_NET, RND_FLAG_DEFAULT); 156 1.1 scottr 157 1.37 jhawk /* The attach is successful. */ 158 1.37 jhawk sc->sc_flags |= DP8390_ATTACHED; 159 1.37 jhawk 160 1.1 scottr rv = 0; 161 1.77 tsutsui out: 162 1.77 tsutsui return rv; 163 1.1 scottr } 164 1.1 scottr 165 1.1 scottr /* 166 1.8 thorpej * Media change callback. 167 1.8 thorpej */ 168 1.8 thorpej int 169 1.70 dsl dp8390_mediachange(struct ifnet *ifp) 170 1.8 thorpej { 171 1.8 thorpej struct dp8390_softc *sc = ifp->if_softc; 172 1.8 thorpej 173 1.8 thorpej if (sc->sc_mediachange) 174 1.77 tsutsui return (*sc->sc_mediachange)(sc); 175 1.77 tsutsui return 0; 176 1.8 thorpej } 177 1.8 thorpej 178 1.8 thorpej /* 179 1.8 thorpej * Media status callback. 180 1.8 thorpej */ 181 1.8 thorpej void 182 1.70 dsl dp8390_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) 183 1.8 thorpej { 184 1.8 thorpej struct dp8390_softc *sc = ifp->if_softc; 185 1.8 thorpej 186 1.8 thorpej if (sc->sc_enabled == 0) { 187 1.8 thorpej ifmr->ifm_active = IFM_ETHER | IFM_NONE; 188 1.8 thorpej ifmr->ifm_status = 0; 189 1.8 thorpej return; 190 1.8 thorpej } 191 1.8 thorpej 192 1.8 thorpej if (sc->sc_mediastatus) 193 1.8 thorpej (*sc->sc_mediastatus)(sc, ifmr); 194 1.8 thorpej } 195 1.8 thorpej 196 1.8 thorpej /* 197 1.1 scottr * Reset interface. 198 1.1 scottr */ 199 1.1 scottr void 200 1.70 dsl dp8390_reset(struct dp8390_softc *sc) 201 1.1 scottr { 202 1.77 tsutsui int s; 203 1.1 scottr 204 1.1 scottr s = splnet(); 205 1.1 scottr dp8390_stop(sc); 206 1.1 scottr dp8390_init(sc); 207 1.1 scottr splx(s); 208 1.1 scottr } 209 1.1 scottr 210 1.1 scottr /* 211 1.1 scottr * Take interface offline. 212 1.1 scottr */ 213 1.98 thorpej static void 214 1.98 thorpej dp8390_halt(struct dp8390_softc *sc) 215 1.1 scottr { 216 1.1 scottr bus_space_tag_t regt = sc->sc_regt; 217 1.1 scottr bus_space_handle_t regh = sc->sc_regh; 218 1.1 scottr int n = 5000; 219 1.1 scottr 220 1.1 scottr /* Stop everything on the interface, and select page 0 registers. */ 221 1.34 ws NIC_BARRIER(regt, regh); 222 1.1 scottr NIC_PUT(regt, regh, ED_P0_CR, 223 1.1 scottr sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STP); 224 1.34 ws NIC_BARRIER(regt, regh); 225 1.1 scottr 226 1.1 scottr /* 227 1.1 scottr * Wait for interface to enter stopped state, but limit # of checks to 228 1.1 scottr * 'n' (about 5ms). It shouldn't even take 5us on modern DS8390's, but 229 1.1 scottr * just in case it's an old one. 230 1.1 scottr */ 231 1.77 tsutsui while (((NIC_GET(regt, regh, ED_P0_ISR) & ED_ISR_RST) == 0) && --n) 232 1.34 ws DELAY(1); 233 1.98 thorpej } 234 1.44 thorpej 235 1.98 thorpej void 236 1.98 thorpej dp8390_stop(struct dp8390_softc *sc) 237 1.98 thorpej { 238 1.98 thorpej dp8390_halt(sc); 239 1.44 thorpej if (sc->stop_card != NULL) 240 1.44 thorpej (*sc->stop_card)(sc); 241 1.1 scottr } 242 1.1 scottr 243 1.1 scottr /* 244 1.1 scottr * Device timeout/watchdog routine. Entered if the device neglects to generate 245 1.1 scottr * an interrupt after a transmit has been started on it. 246 1.1 scottr */ 247 1.1 scottr 248 1.1 scottr void 249 1.70 dsl dp8390_watchdog(struct ifnet *ifp) 250 1.1 scottr { 251 1.1 scottr struct dp8390_softc *sc = ifp->if_softc; 252 1.1 scottr 253 1.68 cube log(LOG_ERR, "%s: device timeout\n", device_xname(sc->sc_dev)); 254 1.96 thorpej if_statinc(ifp, if_oerrors); 255 1.1 scottr 256 1.1 scottr dp8390_reset(sc); 257 1.1 scottr } 258 1.1 scottr 259 1.1 scottr /* 260 1.1 scottr * Initialize device. 261 1.1 scottr */ 262 1.1 scottr void 263 1.70 dsl dp8390_init(struct dp8390_softc *sc) 264 1.1 scottr { 265 1.1 scottr bus_space_tag_t regt = sc->sc_regt; 266 1.1 scottr bus_space_handle_t regh = sc->sc_regh; 267 1.1 scottr struct ifnet *ifp = &sc->sc_ec.ec_if; 268 1.77 tsutsui uint8_t mcaf[8]; 269 1.1 scottr int i; 270 1.1 scottr 271 1.1 scottr /* 272 1.1 scottr * Initialize the NIC in the exact order outlined in the NS manual. 273 1.1 scottr * This init procedure is "mandatory"...don't change what or when 274 1.1 scottr * things happen. 275 1.1 scottr */ 276 1.1 scottr 277 1.1 scottr /* Reset transmitter flags. */ 278 1.1 scottr ifp->if_timer = 0; 279 1.1 scottr 280 1.1 scottr sc->txb_inuse = 0; 281 1.1 scottr sc->txb_new = 0; 282 1.1 scottr sc->txb_next_tx = 0; 283 1.1 scottr 284 1.1 scottr /* Set interface for page 0, remote DMA complete, stopped. */ 285 1.34 ws NIC_BARRIER(regt, regh); 286 1.1 scottr NIC_PUT(regt, regh, ED_P0_CR, 287 1.1 scottr sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STP); 288 1.34 ws NIC_BARRIER(regt, regh); 289 1.1 scottr 290 1.2 scottr if (sc->dcr_reg & ED_DCR_LS) { 291 1.3 scottr NIC_PUT(regt, regh, ED_P0_DCR, sc->dcr_reg); 292 1.2 scottr } else { 293 1.1 scottr /* 294 1.1 scottr * Set FIFO threshold to 8, No auto-init Remote DMA, byte 295 1.2 scottr * order=80x86, byte-wide DMA xfers, 296 1.1 scottr */ 297 1.1 scottr NIC_PUT(regt, regh, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS); 298 1.1 scottr } 299 1.1 scottr 300 1.1 scottr /* Clear remote byte count registers. */ 301 1.1 scottr NIC_PUT(regt, regh, ED_P0_RBCR0, 0); 302 1.1 scottr NIC_PUT(regt, regh, ED_P0_RBCR1, 0); 303 1.1 scottr 304 1.1 scottr /* Tell RCR to do nothing for now. */ 305 1.33 enami NIC_PUT(regt, regh, ED_P0_RCR, ED_RCR_MON | sc->rcr_proto); 306 1.1 scottr 307 1.1 scottr /* Place NIC in internal loopback mode. */ 308 1.1 scottr NIC_PUT(regt, regh, ED_P0_TCR, ED_TCR_LB0); 309 1.1 scottr 310 1.1 scottr /* Set lower bits of byte addressable framing to 0. */ 311 1.1 scottr if (sc->is790) 312 1.1 scottr NIC_PUT(regt, regh, 0x09, 0); 313 1.1 scottr 314 1.1 scottr /* Initialize receive buffer ring. */ 315 1.1 scottr NIC_PUT(regt, regh, ED_P0_BNRY, sc->rec_page_start); 316 1.1 scottr NIC_PUT(regt, regh, ED_P0_PSTART, sc->rec_page_start); 317 1.1 scottr NIC_PUT(regt, regh, ED_P0_PSTOP, sc->rec_page_stop); 318 1.1 scottr 319 1.1 scottr /* 320 1.1 scottr * Enable the following interrupts: receive/transmit complete, 321 1.1 scottr * receive/transmit error, and Receiver OverWrite. 322 1.1 scottr * 323 1.1 scottr * Counter overflow and Remote DMA complete are *not* enabled. 324 1.1 scottr */ 325 1.1 scottr NIC_PUT(regt, regh, ED_P0_IMR, 326 1.1 scottr ED_IMR_PRXE | ED_IMR_PTXE | ED_IMR_RXEE | ED_IMR_TXEE | 327 1.1 scottr ED_IMR_OVWE); 328 1.1 scottr 329 1.14 mycroft /* 330 1.14 mycroft * Clear all interrupts. A '1' in each bit position clears the 331 1.14 mycroft * corresponding flag. 332 1.14 mycroft */ 333 1.14 mycroft NIC_PUT(regt, regh, ED_P0_ISR, 0xff); 334 1.14 mycroft 335 1.1 scottr /* Program command register for page 1. */ 336 1.34 ws NIC_BARRIER(regt, regh); 337 1.1 scottr NIC_PUT(regt, regh, ED_P0_CR, 338 1.1 scottr sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STP); 339 1.34 ws NIC_BARRIER(regt, regh); 340 1.1 scottr 341 1.1 scottr /* Copy out our station address. */ 342 1.77 tsutsui for (i = 0; i < ETHER_ADDR_LEN; i++) 343 1.77 tsutsui NIC_PUT(regt, regh, ED_P1_PAR0 + i, CLLADDR(ifp->if_sadl)[i]); 344 1.1 scottr 345 1.1 scottr /* Set multicast filter on chip. */ 346 1.1 scottr dp8390_getmcaf(&sc->sc_ec, mcaf); 347 1.1 scottr for (i = 0; i < 8; i++) 348 1.1 scottr NIC_PUT(regt, regh, ED_P1_MAR0 + i, mcaf[i]); 349 1.1 scottr 350 1.1 scottr /* 351 1.1 scottr * Set current page pointer to one page after the boundary pointer, as 352 1.1 scottr * recommended in the National manual. 353 1.1 scottr */ 354 1.1 scottr sc->next_packet = sc->rec_page_start + 1; 355 1.1 scottr NIC_PUT(regt, regh, ED_P1_CURR, sc->next_packet); 356 1.1 scottr 357 1.1 scottr /* Program command register for page 0. */ 358 1.34 ws NIC_BARRIER(regt, regh); 359 1.1 scottr NIC_PUT(regt, regh, ED_P1_CR, 360 1.1 scottr sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STP); 361 1.34 ws NIC_BARRIER(regt, regh); 362 1.1 scottr 363 1.14 mycroft /* Accept broadcast and multicast packets by default. */ 364 1.33 enami i = ED_RCR_AB | ED_RCR_AM | sc->rcr_proto; 365 1.1 scottr if (ifp->if_flags & IFF_PROMISC) { 366 1.1 scottr /* 367 1.1 scottr * Set promiscuous mode. Multicast filter was set earlier so 368 1.1 scottr * that we should receive all multicast packets. 369 1.1 scottr */ 370 1.1 scottr i |= ED_RCR_PRO | ED_RCR_AR | ED_RCR_SEP; 371 1.1 scottr } 372 1.1 scottr NIC_PUT(regt, regh, ED_P0_RCR, i); 373 1.1 scottr 374 1.1 scottr /* Take interface out of loopback. */ 375 1.1 scottr NIC_PUT(regt, regh, ED_P0_TCR, 0); 376 1.1 scottr 377 1.1 scottr /* Do any card-specific initialization, if applicable. */ 378 1.77 tsutsui if (sc->init_card != NULL) 379 1.1 scottr (*sc->init_card)(sc); 380 1.1 scottr 381 1.1 scottr /* Fire up the interface. */ 382 1.34 ws NIC_BARRIER(regt, regh); 383 1.1 scottr NIC_PUT(regt, regh, ED_P0_CR, 384 1.1 scottr sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA); 385 1.1 scottr 386 1.1 scottr /* Set 'running' flag, and clear output active flag. */ 387 1.1 scottr ifp->if_flags |= IFF_RUNNING; 388 1.1 scottr 389 1.1 scottr /* ...and attempt to start output. */ 390 1.1 scottr dp8390_start(ifp); 391 1.1 scottr } 392 1.1 scottr 393 1.1 scottr /* 394 1.1 scottr * This routine actually starts the transmission on the interface. 395 1.1 scottr */ 396 1.76 tsutsui static void 397 1.70 dsl dp8390_xmit(struct dp8390_softc *sc) 398 1.1 scottr { 399 1.1 scottr bus_space_tag_t regt = sc->sc_regt; 400 1.1 scottr bus_space_handle_t regh = sc->sc_regh; 401 1.1 scottr struct ifnet *ifp = &sc->sc_ec.ec_if; 402 1.1 scottr u_short len; 403 1.1 scottr 404 1.14 mycroft #ifdef DIAGNOSTIC 405 1.14 mycroft if ((sc->txb_next_tx + sc->txb_inuse) % sc->txb_cnt != sc->txb_new) 406 1.14 mycroft panic("dp8390_xmit: desync, next_tx=%d inuse=%d cnt=%d new=%d", 407 1.14 mycroft sc->txb_next_tx, sc->txb_inuse, sc->txb_cnt, sc->txb_new); 408 1.14 mycroft 409 1.14 mycroft if (sc->txb_inuse == 0) 410 1.50 provos panic("dp8390_xmit: no packets to xmit"); 411 1.14 mycroft #endif 412 1.14 mycroft 413 1.1 scottr len = sc->txb_len[sc->txb_next_tx]; 414 1.1 scottr 415 1.1 scottr /* Set NIC for page 0 register access. */ 416 1.34 ws NIC_BARRIER(regt, regh); 417 1.1 scottr NIC_PUT(regt, regh, ED_P0_CR, 418 1.1 scottr sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA); 419 1.34 ws NIC_BARRIER(regt, regh); 420 1.1 scottr 421 1.1 scottr /* Set TX buffer start page. */ 422 1.77 tsutsui NIC_PUT(regt, regh, ED_P0_TPSR, 423 1.77 tsutsui sc->tx_page_start + sc->txb_next_tx * ED_TXBUF_SIZE); 424 1.1 scottr 425 1.1 scottr /* Set TX length. */ 426 1.1 scottr NIC_PUT(regt, regh, ED_P0_TBCR0, len); 427 1.1 scottr NIC_PUT(regt, regh, ED_P0_TBCR1, len >> 8); 428 1.1 scottr 429 1.1 scottr /* Set page 0, remote DMA complete, transmit packet, and *start*. */ 430 1.34 ws NIC_BARRIER(regt, regh); 431 1.1 scottr NIC_PUT(regt, regh, ED_P0_CR, 432 1.1 scottr sc->cr_proto | ED_CR_PAGE_0 | ED_CR_TXP | ED_CR_STA); 433 1.1 scottr 434 1.1 scottr /* Point to next transmit buffer slot and wrap if necessary. */ 435 1.14 mycroft if (++sc->txb_next_tx == sc->txb_cnt) 436 1.1 scottr sc->txb_next_tx = 0; 437 1.1 scottr 438 1.1 scottr /* Set a timer just in case we never hear from the board again. */ 439 1.1 scottr ifp->if_timer = 2; 440 1.1 scottr } 441 1.1 scottr 442 1.1 scottr /* 443 1.1 scottr * Start output on interface. 444 1.100 thorpej * We make one assumption here: 445 1.1 scottr * 1) that the current priority is set to splnet _before_ this code 446 1.1 scottr * is called *and* is returned to the appropriate priority after 447 1.1 scottr * return 448 1.1 scottr */ 449 1.1 scottr void 450 1.70 dsl dp8390_start(struct ifnet *ifp) 451 1.1 scottr { 452 1.1 scottr struct dp8390_softc *sc = ifp->if_softc; 453 1.1 scottr struct mbuf *m0; 454 1.1 scottr int buffer; 455 1.1 scottr int len; 456 1.1 scottr 457 1.100 thorpej if ((ifp->if_flags & IFF_RUNNING) == 0) 458 1.1 scottr return; 459 1.1 scottr 460 1.77 tsutsui outloop: 461 1.1 scottr /* See if there is room to put another packet in the buffer. */ 462 1.1 scottr if (sc->txb_inuse == sc->txb_cnt) { 463 1.100 thorpej /* No room. */ 464 1.1 scottr return; 465 1.1 scottr } 466 1.41 thorpej IFQ_DEQUEUE(&ifp->if_snd, m0); 467 1.77 tsutsui if (m0 == NULL) 468 1.1 scottr return; 469 1.1 scottr 470 1.1 scottr /* We need to use m->m_pkthdr.len, so require the header */ 471 1.100 thorpej KASSERT(m0->m_flags & M_PKTHDR); 472 1.1 scottr 473 1.1 scottr /* Tap off here if there is a BPF listener. */ 474 1.89 msaitoh bpf_mtap(ifp, m0, BPF_D_OUT); 475 1.1 scottr 476 1.1 scottr /* txb_new points to next open buffer slot. */ 477 1.1 scottr buffer = sc->mem_start + 478 1.1 scottr ((sc->txb_new * ED_TXBUF_SIZE) << ED_PAGE_SHIFT); 479 1.1 scottr 480 1.76 tsutsui len = (*sc->write_mbuf)(sc, m0, buffer); 481 1.1 scottr 482 1.1 scottr m_freem(m0); 483 1.52 bouyer sc->txb_len[sc->txb_new] = len; 484 1.1 scottr 485 1.1 scottr /* Point to next buffer slot and wrap if necessary. */ 486 1.1 scottr if (++sc->txb_new == sc->txb_cnt) 487 1.1 scottr sc->txb_new = 0; 488 1.1 scottr 489 1.14 mycroft /* Start the first packet transmitting. */ 490 1.14 mycroft if (sc->txb_inuse++ == 0) 491 1.14 mycroft dp8390_xmit(sc); 492 1.1 scottr 493 1.1 scottr /* Loop back to the top to possibly buffer more packets. */ 494 1.1 scottr goto outloop; 495 1.1 scottr } 496 1.1 scottr 497 1.1 scottr /* 498 1.1 scottr * Ethernet interface receiver interrupt. 499 1.1 scottr */ 500 1.1 scottr void 501 1.70 dsl dp8390_rint(struct dp8390_softc *sc) 502 1.1 scottr { 503 1.1 scottr bus_space_tag_t regt = sc->sc_regt; 504 1.1 scottr bus_space_handle_t regh = sc->sc_regh; 505 1.1 scottr struct dp8390_ring packet_hdr; 506 1.1 scottr int packet_ptr; 507 1.77 tsutsui uint16_t len; 508 1.77 tsutsui uint8_t boundary, current; 509 1.77 tsutsui uint8_t nlen; 510 1.1 scottr 511 1.77 tsutsui loop: 512 1.1 scottr /* Set NIC to page 1 registers to get 'current' pointer. */ 513 1.34 ws NIC_BARRIER(regt, regh); 514 1.1 scottr NIC_PUT(regt, regh, ED_P0_CR, 515 1.1 scottr sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STA); 516 1.34 ws NIC_BARRIER(regt, regh); 517 1.1 scottr 518 1.1 scottr /* 519 1.1 scottr * 'sc->next_packet' is the logical beginning of the ring-buffer - i.e. 520 1.1 scottr * it points to where new data has been buffered. The 'CURR' (current) 521 1.1 scottr * register points to the logical end of the ring-buffer - i.e. it 522 1.1 scottr * points to where additional new data will be added. We loop here 523 1.1 scottr * until the logical beginning equals the logical end (or in other 524 1.1 scottr * words, until the ring-buffer is empty). 525 1.1 scottr */ 526 1.1 scottr current = NIC_GET(regt, regh, ED_P1_CURR); 527 1.1 scottr if (sc->next_packet == current) 528 1.1 scottr return; 529 1.1 scottr 530 1.1 scottr /* Set NIC to page 0 registers to update boundary register. */ 531 1.34 ws NIC_BARRIER(regt, regh); 532 1.1 scottr NIC_PUT(regt, regh, ED_P1_CR, 533 1.1 scottr sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA); 534 1.34 ws NIC_BARRIER(regt, regh); 535 1.1 scottr 536 1.1 scottr do { 537 1.1 scottr /* Get pointer to this buffer's header structure. */ 538 1.1 scottr packet_ptr = sc->mem_ring + 539 1.1 scottr ((sc->next_packet - sc->rec_page_start) << ED_PAGE_SHIFT); 540 1.1 scottr 541 1.76 tsutsui (*sc->read_hdr)(sc, packet_ptr, &packet_hdr); 542 1.1 scottr len = packet_hdr.count; 543 1.1 scottr 544 1.1 scottr /* 545 1.1 scottr * Try do deal with old, buggy chips that sometimes duplicate 546 1.1 scottr * the low byte of the length into the high byte. We do this 547 1.1 scottr * by simply ignoring the high byte of the length and always 548 1.1 scottr * recalculating it. 549 1.1 scottr * 550 1.1 scottr * NOTE: sc->next_packet is pointing at the current packet. 551 1.1 scottr */ 552 1.1 scottr if (packet_hdr.next_packet >= sc->next_packet) 553 1.1 scottr nlen = (packet_hdr.next_packet - sc->next_packet); 554 1.1 scottr else 555 1.1 scottr nlen = ((packet_hdr.next_packet - sc->rec_page_start) + 556 1.1 scottr (sc->rec_page_stop - sc->next_packet)); 557 1.1 scottr --nlen; 558 1.1 scottr if ((len & ED_PAGE_MASK) + sizeof(packet_hdr) > ED_PAGE_SIZE) 559 1.1 scottr --nlen; 560 1.1 scottr len = (len & ED_PAGE_MASK) | (nlen << ED_PAGE_SHIFT); 561 1.1 scottr #ifdef DIAGNOSTIC 562 1.1 scottr if (len != packet_hdr.count) { 563 1.68 cube aprint_verbose_dev(sc->sc_dev, "length does not match " 564 1.68 cube "next packet pointer\n"); 565 1.68 cube aprint_verbose_dev(sc->sc_dev, "len %04x nlen %04x " 566 1.68 cube "start %02x first %02x curr %02x next %02x " 567 1.68 cube "stop %02x\n", packet_hdr.count, len, 568 1.1 scottr sc->rec_page_start, sc->next_packet, current, 569 1.1 scottr packet_hdr.next_packet, sc->rec_page_stop); 570 1.1 scottr } 571 1.1 scottr #endif 572 1.1 scottr 573 1.1 scottr /* 574 1.1 scottr * Be fairly liberal about what we allow as a "reasonable" 575 1.1 scottr * length so that a [crufty] packet will make it to BPF (and 576 1.1 scottr * can thus be analyzed). Note that all that is really 577 1.1 scottr * important is that we have a length that will fit into one 578 1.1 scottr * mbuf cluster or less; the upper layer protocols can then 579 1.1 scottr * figure out the length from their own length field(s). 580 1.1 scottr */ 581 1.1 scottr if (len <= MCLBYTES && 582 1.1 scottr packet_hdr.next_packet >= sc->rec_page_start && 583 1.1 scottr packet_hdr.next_packet < sc->rec_page_stop) { 584 1.1 scottr /* Go get packet. */ 585 1.1 scottr dp8390_read(sc, 586 1.1 scottr packet_ptr + sizeof(struct dp8390_ring), 587 1.1 scottr len - sizeof(struct dp8390_ring)); 588 1.1 scottr } else { 589 1.1 scottr /* Really BAD. The ring pointers are corrupted. */ 590 1.1 scottr log(LOG_ERR, "%s: NIC memory corrupt - " 591 1.1 scottr "invalid packet length %d\n", 592 1.68 cube device_xname(sc->sc_dev), len); 593 1.96 thorpej if_statinc(&sc->sc_ec.ec_if, if_ierrors); 594 1.1 scottr dp8390_reset(sc); 595 1.1 scottr return; 596 1.1 scottr } 597 1.1 scottr 598 1.1 scottr /* Update next packet pointer. */ 599 1.1 scottr sc->next_packet = packet_hdr.next_packet; 600 1.1 scottr 601 1.1 scottr /* 602 1.1 scottr * Update NIC boundary pointer - being careful to keep it one 603 1.1 scottr * buffer behind (as recommended by NS databook). 604 1.1 scottr */ 605 1.1 scottr boundary = sc->next_packet - 1; 606 1.1 scottr if (boundary < sc->rec_page_start) 607 1.1 scottr boundary = sc->rec_page_stop - 1; 608 1.1 scottr NIC_PUT(regt, regh, ED_P0_BNRY, boundary); 609 1.1 scottr } while (sc->next_packet != current); 610 1.1 scottr 611 1.1 scottr goto loop; 612 1.1 scottr } 613 1.1 scottr 614 1.1 scottr /* Ethernet interface interrupt processor. */ 615 1.7 thorpej int 616 1.70 dsl dp8390_intr(void *arg) 617 1.1 scottr { 618 1.77 tsutsui struct dp8390_softc *sc = arg; 619 1.1 scottr bus_space_tag_t regt = sc->sc_regt; 620 1.1 scottr bus_space_handle_t regh = sc->sc_regh; 621 1.1 scottr struct ifnet *ifp = &sc->sc_ec.ec_if; 622 1.77 tsutsui uint8_t isr; 623 1.77 tsutsui uint8_t rndisr; 624 1.1 scottr 625 1.93 msaitoh if (sc->sc_enabled == 0 || !device_is_active(sc->sc_dev)) 626 1.77 tsutsui return 0; 627 1.7 thorpej 628 1.1 scottr /* Set NIC to page 0 registers. */ 629 1.34 ws NIC_BARRIER(regt, regh); 630 1.93 msaitoh NIC_PUT(regt, regh, ED_P0_CR, sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA); 631 1.34 ws NIC_BARRIER(regt, regh); 632 1.1 scottr 633 1.1 scottr isr = NIC_GET(regt, regh, ED_P0_ISR); 634 1.77 tsutsui if (isr == 0) 635 1.77 tsutsui return 0; 636 1.1 scottr 637 1.20 thorpej rndisr = isr; 638 1.20 thorpej 639 1.1 scottr /* Loop until there are no more new interrupts. */ 640 1.1 scottr for (;;) { 641 1.1 scottr /* 642 1.1 scottr * Reset all the bits that we are 'acknowledging' by writing a 643 1.1 scottr * '1' to each bit position that was set. 644 1.1 scottr * (Writing a '1' *clears* the bit.) 645 1.1 scottr */ 646 1.1 scottr NIC_PUT(regt, regh, ED_P0_ISR, isr); 647 1.33 enami 648 1.33 enami /* Work around for AX88190 bug */ 649 1.33 enami if ((sc->sc_flags & DP8390_DO_AX88190_WORKAROUND) != 0) 650 1.33 enami while ((NIC_GET(regt, regh, ED_P0_ISR) & isr) != 0) { 651 1.33 enami NIC_PUT(regt, regh, ED_P0_ISR, 0); 652 1.33 enami NIC_PUT(regt, regh, ED_P0_ISR, isr); 653 1.33 enami } 654 1.1 scottr 655 1.1 scottr /* 656 1.1 scottr * Handle transmitter interrupts. Handle these first because 657 1.1 scottr * the receiver will reset the board under some conditions. 658 1.14 mycroft * 659 1.14 mycroft * If the chip was reset while a packet was transmitting, it 660 1.14 mycroft * may still deliver a TX interrupt. In this case, just ignore 661 1.14 mycroft * the interrupt. 662 1.1 scottr */ 663 1.77 tsutsui if ((isr & (ED_ISR_PTX | ED_ISR_TXE)) != 0 && 664 1.14 mycroft sc->txb_inuse != 0) { 665 1.96 thorpej net_stat_ref_t nsr = IF_STAT_GETREF(ifp); 666 1.77 tsutsui uint8_t collisions = 667 1.14 mycroft NIC_GET(regt, regh, ED_P0_NCR) & 0x0f; 668 1.1 scottr 669 1.1 scottr /* 670 1.1 scottr * Check for transmit error. If a TX completed with an 671 1.1 scottr * error, we end up throwing the packet away. Really 672 1.1 scottr * the only error that is possible is excessive 673 1.1 scottr * collisions, and in this case it is best to allow the 674 1.1 scottr * automatic mechanisms of TCP to backoff the flow. Of 675 1.1 scottr * course, with UDP we're screwed, but this is expected 676 1.1 scottr * when a network is heavily loaded. 677 1.1 scottr */ 678 1.77 tsutsui if ((isr & ED_ISR_TXE) != 0) { 679 1.93 msaitoh /* Excessive collisions (16). */ 680 1.1 scottr if ((NIC_GET(regt, regh, ED_P0_TSR) 681 1.1 scottr & ED_TSR_ABT) && (collisions == 0)) { 682 1.1 scottr /* 683 1.1 scottr * When collisions total 16, the P0_NCR 684 1.1 scottr * will indicate 0, and the TSR_ABT is 685 1.1 scottr * set. 686 1.1 scottr */ 687 1.1 scottr collisions = 16; 688 1.1 scottr } 689 1.1 scottr 690 1.1 scottr /* Update output errors counter. */ 691 1.101 riastrad if_statinc_ref(ifp, nsr, if_oerrors); 692 1.1 scottr } else { 693 1.1 scottr /* 694 1.14 mycroft * Throw away the non-error status bits. 695 1.14 mycroft * 696 1.14 mycroft * XXX 697 1.14 mycroft * It may be useful to detect loss of carrier 698 1.14 mycroft * and late collisions here. 699 1.14 mycroft */ 700 1.14 mycroft (void)NIC_GET(regt, regh, ED_P0_TSR); 701 1.14 mycroft 702 1.14 mycroft /* 703 1.1 scottr * Update total number of successfully 704 1.1 scottr * transmitted packets. 705 1.1 scottr */ 706 1.101 riastrad if_statinc_ref(ifp, nsr, if_opackets); 707 1.1 scottr } 708 1.1 scottr 709 1.1 scottr /* Clear watchdog timer. */ 710 1.1 scottr ifp->if_timer = 0; 711 1.1 scottr 712 1.1 scottr /* 713 1.1 scottr * Add in total number of collisions on last 714 1.1 scottr * transmission. 715 1.1 scottr */ 716 1.101 riastrad if (collisions) { 717 1.101 riastrad if_statadd_ref(ifp, nsr, if_collisions, 718 1.101 riastrad collisions); 719 1.101 riastrad } 720 1.96 thorpej 721 1.96 thorpej IF_STAT_PUTREF(ifp); 722 1.1 scottr 723 1.1 scottr /* 724 1.1 scottr * Decrement buffer in-use count if not zero (can only 725 1.93 msaitoh * be zero if a transmitter interrupt occurred while 726 1.93 msaitoh * not actually transmitting). 727 1.1 scottr * If data is ready to transmit, start it transmitting, 728 1.1 scottr * otherwise defer until after handling receiver. 729 1.1 scottr */ 730 1.14 mycroft if (--sc->txb_inuse != 0) 731 1.1 scottr dp8390_xmit(sc); 732 1.1 scottr } 733 1.1 scottr 734 1.1 scottr /* Handle receiver interrupts. */ 735 1.77 tsutsui if ((isr & (ED_ISR_PRX | ED_ISR_RXE | ED_ISR_OVW)) != 0) { 736 1.1 scottr /* 737 1.1 scottr * Overwrite warning. In order to make sure that a 738 1.1 scottr * lockup of the local DMA hasn't occurred, we reset 739 1.1 scottr * and re-init the NIC. The NSC manual suggests only a 740 1.1 scottr * partial reset/re-init is necessary - but some chips 741 1.1 scottr * seem to want more. The DMA lockup has been seen 742 1.1 scottr * only with early rev chips - Methinks this bug was 743 1.1 scottr * fixed in later revs. -DG 744 1.1 scottr */ 745 1.77 tsutsui if ((isr & ED_ISR_OVW) != 0) { 746 1.96 thorpej if_statinc(ifp, if_ierrors); 747 1.1 scottr #ifdef DIAGNOSTIC 748 1.1 scottr log(LOG_WARNING, "%s: warning - receiver " 749 1.1 scottr "ring buffer overrun\n", 750 1.68 cube device_xname(sc->sc_dev)); 751 1.1 scottr #endif 752 1.1 scottr /* Stop/reset/re-init NIC. */ 753 1.1 scottr dp8390_reset(sc); 754 1.1 scottr } else { 755 1.1 scottr /* 756 1.1 scottr * Receiver Error. One or more of: CRC error, 757 1.1 scottr * frame alignment error FIFO overrun, or 758 1.1 scottr * missed packet. 759 1.1 scottr */ 760 1.77 tsutsui if ((isr & ED_ISR_RXE) != 0) { 761 1.96 thorpej if_statinc(ifp, if_ierrors); 762 1.1 scottr #ifdef DEBUG 763 1.4 scottr if (dp8390_debug) { 764 1.4 scottr printf("%s: receive error %x\n", 765 1.68 cube device_xname(sc->sc_dev), 766 1.4 scottr NIC_GET(regt, regh, 767 1.4 scottr ED_P0_RSR)); 768 1.4 scottr } 769 1.1 scottr #endif 770 1.1 scottr } 771 1.1 scottr 772 1.1 scottr /* 773 1.1 scottr * Go get the packet(s) 774 1.1 scottr * XXX - Doing this on an error is dubious 775 1.1 scottr * because there shouldn't be any data to get 776 1.1 scottr * (we've configured the interface to not 777 1.1 scottr * accept packets with errors). 778 1.1 scottr */ 779 1.76 tsutsui (*sc->recv_int)(sc); 780 1.1 scottr } 781 1.1 scottr } 782 1.1 scottr 783 1.1 scottr /* 784 1.1 scottr * If it looks like the transmitter can take more data, attempt 785 1.1 scottr * to start output on the interface. This is done after 786 1.1 scottr * handling the receiver to give the receiver priority. 787 1.1 scottr */ 788 1.87 ozaki if_schedule_deferred_start(ifp); 789 1.1 scottr 790 1.1 scottr /* 791 1.1 scottr * Return NIC CR to standard state: page 0, remote DMA 792 1.1 scottr * complete, start (toggling the TXP bit off, even if was just 793 1.1 scottr * set in the transmit routine, is *okay* - it is 'edge' 794 1.1 scottr * triggered from low to high). 795 1.1 scottr */ 796 1.34 ws NIC_BARRIER(regt, regh); 797 1.1 scottr NIC_PUT(regt, regh, ED_P0_CR, 798 1.1 scottr sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA); 799 1.34 ws NIC_BARRIER(regt, regh); 800 1.1 scottr 801 1.1 scottr /* 802 1.1 scottr * If the Network Talley Counters overflow, read them to reset 803 1.1 scottr * them. It appears that old 8390's won't clear the ISR flag 804 1.1 scottr * otherwise - resulting in an infinite loop. 805 1.1 scottr */ 806 1.77 tsutsui if ((isr & ED_ISR_CNT) != 0) { 807 1.1 scottr (void)NIC_GET(regt, regh, ED_P0_CNTR0); 808 1.1 scottr (void)NIC_GET(regt, regh, ED_P0_CNTR1); 809 1.1 scottr (void)NIC_GET(regt, regh, ED_P0_CNTR2); 810 1.1 scottr } 811 1.1 scottr 812 1.1 scottr isr = NIC_GET(regt, regh, ED_P0_ISR); 813 1.77 tsutsui if (isr == 0) 814 1.20 thorpej goto out; 815 1.1 scottr } 816 1.20 thorpej 817 1.20 thorpej out: 818 1.20 thorpej rnd_add_uint32(&sc->rnd_source, rndisr); 819 1.77 tsutsui return 1; 820 1.1 scottr } 821 1.1 scottr 822 1.1 scottr /* 823 1.1 scottr * Process an ioctl request. This code needs some work - it looks pretty ugly. 824 1.1 scottr */ 825 1.1 scottr int 826 1.70 dsl dp8390_ioctl(struct ifnet *ifp, u_long cmd, void *data) 827 1.1 scottr { 828 1.1 scottr struct dp8390_softc *sc = ifp->if_softc; 829 1.77 tsutsui struct ifaddr *ifa = data; 830 1.8 thorpej int s, error = 0; 831 1.1 scottr 832 1.1 scottr s = splnet(); 833 1.1 scottr 834 1.1 scottr switch (cmd) { 835 1.1 scottr 836 1.69 dyoung case SIOCINITIFADDR: 837 1.7 thorpej if ((error = dp8390_enable(sc)) != 0) 838 1.7 thorpej break; 839 1.1 scottr ifp->if_flags |= IFF_UP; 840 1.1 scottr 841 1.69 dyoung dp8390_init(sc); 842 1.1 scottr switch (ifa->ifa_addr->sa_family) { 843 1.1 scottr #ifdef INET 844 1.1 scottr case AF_INET: 845 1.1 scottr arp_ifinit(ifp, ifa); 846 1.1 scottr break; 847 1.1 scottr #endif 848 1.1 scottr default: 849 1.1 scottr break; 850 1.1 scottr } 851 1.1 scottr break; 852 1.1 scottr 853 1.1 scottr case SIOCSIFFLAGS: 854 1.69 dyoung if ((error = ifioctl_common(ifp, cmd, data)) != 0) 855 1.69 dyoung break; 856 1.93 msaitoh switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) { 857 1.67 dyoung case IFF_RUNNING: 858 1.1 scottr /* 859 1.1 scottr * If interface is marked down and it is running, then 860 1.1 scottr * stop it. 861 1.1 scottr */ 862 1.1 scottr dp8390_stop(sc); 863 1.1 scottr ifp->if_flags &= ~IFF_RUNNING; 864 1.7 thorpej dp8390_disable(sc); 865 1.67 dyoung break; 866 1.67 dyoung case IFF_UP: 867 1.1 scottr /* 868 1.1 scottr * If interface is marked up and it is stopped, then 869 1.1 scottr * start it. 870 1.1 scottr */ 871 1.7 thorpej if ((error = dp8390_enable(sc)) != 0) 872 1.7 thorpej break; 873 1.1 scottr dp8390_init(sc); 874 1.67 dyoung break; 875 1.93 msaitoh case IFF_UP | IFF_RUNNING: 876 1.1 scottr /* 877 1.1 scottr * Reset the interface to pick up changes in any other 878 1.1 scottr * flags that affect hardware registers. 879 1.1 scottr */ 880 1.1 scottr dp8390_stop(sc); 881 1.1 scottr dp8390_init(sc); 882 1.67 dyoung break; 883 1.67 dyoung default: 884 1.67 dyoung break; 885 1.1 scottr } 886 1.1 scottr break; 887 1.1 scottr 888 1.1 scottr case SIOCADDMULTI: 889 1.1 scottr case SIOCDELMULTI: 890 1.7 thorpej if (sc->sc_enabled == 0) { 891 1.7 thorpej error = EIO; 892 1.7 thorpej break; 893 1.7 thorpej } 894 1.7 thorpej 895 1.1 scottr /* Update our multicast list. */ 896 1.65 dyoung if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) { 897 1.1 scottr /* 898 1.1 scottr * Multicast list has changed; set the hardware filter 899 1.1 scottr * accordingly. 900 1.1 scottr */ 901 1.54 thorpej if (ifp->if_flags & IFF_RUNNING) { 902 1.54 thorpej dp8390_stop(sc); /* XXX for ds_setmcaf? */ 903 1.54 thorpej dp8390_init(sc); 904 1.54 thorpej } 905 1.1 scottr error = 0; 906 1.1 scottr } 907 1.8 thorpej break; 908 1.8 thorpej 909 1.1 scottr default: 910 1.69 dyoung error = ether_ioctl(ifp, cmd, data); 911 1.1 scottr break; 912 1.1 scottr } 913 1.1 scottr 914 1.1 scottr splx(s); 915 1.77 tsutsui return error; 916 1.1 scottr } 917 1.1 scottr 918 1.1 scottr /* 919 1.1 scottr * Retrieve packet from buffer memory and send to the next level up via 920 1.1 scottr * ether_input(). If there is a BPF listener, give a copy to BPF, too. 921 1.1 scottr */ 922 1.1 scottr void 923 1.70 dsl dp8390_read(struct dp8390_softc *sc, int buf, u_short len) 924 1.1 scottr { 925 1.1 scottr struct ifnet *ifp = &sc->sc_ec.ec_if; 926 1.1 scottr struct mbuf *m; 927 1.1 scottr 928 1.1 scottr /* Pull packet off interface. */ 929 1.1 scottr m = dp8390_get(sc, buf, len); 930 1.77 tsutsui if (m == NULL) { 931 1.96 thorpej if_statinc(ifp, if_ierrors); 932 1.1 scottr return; 933 1.1 scottr } 934 1.1 scottr 935 1.83 ozaki if_percpuq_enqueue(ifp->if_percpuq, m); 936 1.1 scottr } 937 1.1 scottr 938 1.1 scottr 939 1.1 scottr /* 940 1.1 scottr * Supporting routines. 941 1.1 scottr */ 942 1.1 scottr 943 1.1 scottr /* 944 1.1 scottr * Compute the multicast address filter from the list of multicast addresses we 945 1.1 scottr * need to listen to. 946 1.1 scottr */ 947 1.1 scottr void 948 1.77 tsutsui dp8390_getmcaf(struct ethercom *ec, uint8_t *af) 949 1.1 scottr { 950 1.1 scottr struct ifnet *ifp = &ec->ec_if; 951 1.1 scottr struct ether_multi *enm; 952 1.77 tsutsui uint32_t crc; 953 1.36 thorpej int i; 954 1.1 scottr struct ether_multistep step; 955 1.1 scottr 956 1.1 scottr /* 957 1.1 scottr * Set up multicast address filter by passing all multicast addresses 958 1.1 scottr * through a crc generator, and then using the high order 6 bits as an 959 1.1 scottr * index into the 64 bit logical address filter. The high order bit 960 1.1 scottr * selects the word, while the rest of the bits select the bit within 961 1.1 scottr * the word. 962 1.1 scottr */ 963 1.1 scottr 964 1.1 scottr if (ifp->if_flags & IFF_PROMISC) { 965 1.1 scottr ifp->if_flags |= IFF_ALLMULTI; 966 1.1 scottr for (i = 0; i < 8; i++) 967 1.1 scottr af[i] = 0xff; 968 1.1 scottr return; 969 1.1 scottr } 970 1.1 scottr for (i = 0; i < 8; i++) 971 1.1 scottr af[i] = 0; 972 1.94 msaitoh ETHER_LOCK(ec); 973 1.1 scottr ETHER_FIRST_MULTI(step, ec, enm); 974 1.1 scottr while (enm != NULL) { 975 1.45 thorpej if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 976 1.1 scottr sizeof(enm->enm_addrlo)) != 0) { 977 1.1 scottr /* 978 1.1 scottr * We must listen to a range of multicast addresses. 979 1.1 scottr * For now, just accept all multicasts, rather than 980 1.1 scottr * trying to set only those filter bits needed to match 981 1.1 scottr * the range. (At this time, the only use of address 982 1.1 scottr * ranges is for IP multicast routing, for which the 983 1.1 scottr * range is big enough to require all bits set.) 984 1.1 scottr */ 985 1.1 scottr ifp->if_flags |= IFF_ALLMULTI; 986 1.1 scottr for (i = 0; i < 8; i++) 987 1.1 scottr af[i] = 0xff; 988 1.94 msaitoh ETHER_UNLOCK(ec); 989 1.1 scottr return; 990 1.1 scottr } 991 1.36 thorpej 992 1.36 thorpej crc = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN); 993 1.36 thorpej 994 1.1 scottr /* Just want the 6 most significant bits. */ 995 1.1 scottr crc >>= 26; 996 1.1 scottr 997 1.1 scottr /* Turn on the corresponding bit in the filter. */ 998 1.1 scottr af[crc >> 3] |= 1 << (crc & 0x7); 999 1.1 scottr 1000 1.1 scottr ETHER_NEXT_MULTI(step, enm); 1001 1.1 scottr } 1002 1.94 msaitoh ETHER_UNLOCK(ec); 1003 1.1 scottr ifp->if_flags &= ~IFF_ALLMULTI; 1004 1.1 scottr } 1005 1.1 scottr 1006 1.1 scottr /* 1007 1.17 bad * Copy data from receive buffer to a new mbuf chain allocating mbufs 1008 1.17 bad * as needed. Return pointer to first mbuf in chain. 1009 1.1 scottr * sc = dp8390 info (softc) 1010 1.1 scottr * src = pointer in dp8390 ring buffer 1011 1.17 bad * total_len = amount of data to copy 1012 1.1 scottr */ 1013 1.1 scottr struct mbuf * 1014 1.70 dsl dp8390_get(struct dp8390_softc *sc, int src, u_short total_len) 1015 1.1 scottr { 1016 1.1 scottr struct ifnet *ifp = &sc->sc_ec.ec_if; 1017 1.18 bad struct mbuf *m, *m0, *newm; 1018 1.1 scottr u_short len; 1019 1.1 scottr 1020 1.19 mycroft MGETHDR(m0, M_DONTWAIT, MT_DATA); 1021 1.77 tsutsui if (m0 == NULL) 1022 1.77 tsutsui return NULL; 1023 1.85 ozaki m_set_rcvif(m0, ifp); 1024 1.19 mycroft m0->m_pkthdr.len = total_len; 1025 1.1 scottr len = MHLEN; 1026 1.19 mycroft m = m0; 1027 1.1 scottr 1028 1.1 scottr while (total_len > 0) { 1029 1.1 scottr if (total_len >= MINCLSIZE) { 1030 1.1 scottr MCLGET(m, M_DONTWAIT); 1031 1.19 mycroft if ((m->m_flags & M_EXT) == 0) 1032 1.19 mycroft goto bad; 1033 1.1 scottr len = MCLBYTES; 1034 1.1 scottr } 1035 1.11 thorpej 1036 1.93 msaitoh /* Make sure the data after the Ethernet header is aligned. */ 1037 1.18 bad if (m == m0) { 1038 1.63 christos char *newdata = (char *) 1039 1.11 thorpej ALIGN(m->m_data + sizeof(struct ether_header)) - 1040 1.11 thorpej sizeof(struct ether_header); 1041 1.11 thorpej len -= newdata - m->m_data; 1042 1.11 thorpej m->m_data = newdata; 1043 1.11 thorpej } 1044 1.11 thorpej 1045 1.91 riastrad m->m_len = len = uimin(total_len, len); 1046 1.76 tsutsui src = (*sc->ring_copy)(sc, src, mtod(m, void *), len); 1047 1.19 mycroft 1048 1.1 scottr total_len -= len; 1049 1.18 bad if (total_len > 0) { 1050 1.18 bad MGET(newm, M_DONTWAIT, MT_DATA); 1051 1.77 tsutsui if (newm == NULL) 1052 1.19 mycroft goto bad; 1053 1.18 bad len = MLEN; 1054 1.19 mycroft m = m->m_next = newm; 1055 1.18 bad } 1056 1.1 scottr } 1057 1.1 scottr 1058 1.77 tsutsui return m0; 1059 1.19 mycroft 1060 1.77 tsutsui bad: 1061 1.19 mycroft m_freem(m0); 1062 1.77 tsutsui return NULL; 1063 1.1 scottr } 1064 1.1 scottr 1065 1.1 scottr 1066 1.1 scottr /* 1067 1.1 scottr * Default driver support functions. 1068 1.1 scottr * 1069 1.1 scottr * NOTE: all support functions assume 8-bit shared memory. 1070 1.1 scottr */ 1071 1.1 scottr /* 1072 1.1 scottr * Zero NIC buffer memory and verify that it is clear. 1073 1.1 scottr */ 1074 1.1 scottr static int 1075 1.70 dsl dp8390_test_mem(struct dp8390_softc *sc) 1076 1.1 scottr { 1077 1.1 scottr bus_space_tag_t buft = sc->sc_buft; 1078 1.1 scottr bus_space_handle_t bufh = sc->sc_bufh; 1079 1.1 scottr int i; 1080 1.1 scottr 1081 1.1 scottr bus_space_set_region_1(buft, bufh, sc->mem_start, 0, sc->mem_size); 1082 1.1 scottr 1083 1.1 scottr for (i = 0; i < sc->mem_size; ++i) { 1084 1.1 scottr if (bus_space_read_1(buft, bufh, sc->mem_start + i)) { 1085 1.1 scottr printf(": failed to clear NIC buffer at offset %x - " 1086 1.1 scottr "check configuration\n", (sc->mem_start + i)); 1087 1.1 scottr return 1; 1088 1.1 scottr } 1089 1.1 scottr } 1090 1.1 scottr 1091 1.1 scottr return 0; 1092 1.1 scottr } 1093 1.1 scottr 1094 1.1 scottr /* 1095 1.1 scottr * Read a packet header from the ring, given the source offset. 1096 1.1 scottr */ 1097 1.76 tsutsui static void 1098 1.70 dsl dp8390_read_hdr(struct dp8390_softc *sc, int src, struct dp8390_ring *hdrp) 1099 1.1 scottr { 1100 1.1 scottr bus_space_tag_t buft = sc->sc_buft; 1101 1.1 scottr bus_space_handle_t bufh = sc->sc_bufh; 1102 1.1 scottr 1103 1.1 scottr /* 1104 1.1 scottr * The byte count includes a 4 byte header that was added by 1105 1.1 scottr * the NIC. 1106 1.1 scottr */ 1107 1.1 scottr hdrp->rsr = bus_space_read_1(buft, bufh, src); 1108 1.1 scottr hdrp->next_packet = bus_space_read_1(buft, bufh, src + 1); 1109 1.1 scottr hdrp->count = bus_space_read_1(buft, bufh, src + 2) | 1110 1.1 scottr (bus_space_read_1(buft, bufh, src + 3) << 8); 1111 1.1 scottr } 1112 1.1 scottr 1113 1.1 scottr /* 1114 1.1 scottr * Copy `amount' bytes from a packet in the ring buffer to a linear 1115 1.1 scottr * destination buffer, given a source offset and destination address. 1116 1.1 scottr * Takes into account ring-wrap. 1117 1.1 scottr */ 1118 1.76 tsutsui static int 1119 1.70 dsl dp8390_ring_copy(struct dp8390_softc *sc, int src, void *dst, u_short amount) 1120 1.1 scottr { 1121 1.1 scottr bus_space_tag_t buft = sc->sc_buft; 1122 1.1 scottr bus_space_handle_t bufh = sc->sc_bufh; 1123 1.1 scottr u_short tmp_amount; 1124 1.1 scottr 1125 1.1 scottr /* Does copy wrap to lower addr in ring buffer? */ 1126 1.1 scottr if (src + amount > sc->mem_end) { 1127 1.1 scottr tmp_amount = sc->mem_end - src; 1128 1.1 scottr 1129 1.1 scottr /* Copy amount up to end of NIC memory. */ 1130 1.1 scottr bus_space_read_region_1(buft, bufh, src, dst, tmp_amount); 1131 1.1 scottr 1132 1.1 scottr amount -= tmp_amount; 1133 1.1 scottr src = sc->mem_ring; 1134 1.63 christos dst = (char *)dst + tmp_amount; 1135 1.1 scottr } 1136 1.1 scottr bus_space_read_region_1(buft, bufh, src, dst, amount); 1137 1.1 scottr 1138 1.77 tsutsui return src + amount; 1139 1.1 scottr } 1140 1.1 scottr 1141 1.1 scottr /* 1142 1.1 scottr * Copy a packet from an mbuf to the transmit buffer on the card. 1143 1.1 scottr * 1144 1.1 scottr * Currently uses an extra buffer/extra memory copy, unless the whole 1145 1.1 scottr * packet fits in one mbuf. 1146 1.1 scottr */ 1147 1.76 tsutsui static int 1148 1.70 dsl dp8390_write_mbuf(struct dp8390_softc *sc, struct mbuf *m, int buf) 1149 1.1 scottr { 1150 1.1 scottr bus_space_tag_t buft = sc->sc_buft; 1151 1.1 scottr bus_space_handle_t bufh = sc->sc_bufh; 1152 1.77 tsutsui uint8_t *data; 1153 1.1 scottr int len, totlen = 0; 1154 1.1 scottr 1155 1.1 scottr for (; m ; m = m->m_next) { 1156 1.77 tsutsui data = mtod(m, uint8_t *); 1157 1.1 scottr len = m->m_len; 1158 1.1 scottr if (len > 0) { 1159 1.9 scottr bus_space_write_region_1(buft, bufh, buf, data, len); 1160 1.1 scottr totlen += len; 1161 1.9 scottr buf += len; 1162 1.1 scottr } 1163 1.1 scottr } 1164 1.52 bouyer if (totlen < ETHER_MIN_LEN - ETHER_CRC_LEN) { 1165 1.52 bouyer bus_space_set_region_1(buft, bufh, buf, 0, 1166 1.52 bouyer ETHER_MIN_LEN - ETHER_CRC_LEN - totlen); 1167 1.52 bouyer totlen = ETHER_MIN_LEN - ETHER_CRC_LEN; 1168 1.52 bouyer } 1169 1.77 tsutsui return totlen; 1170 1.7 thorpej } 1171 1.7 thorpej 1172 1.7 thorpej /* 1173 1.7 thorpej * Enable power on the interface. 1174 1.7 thorpej */ 1175 1.7 thorpej int 1176 1.70 dsl dp8390_enable(struct dp8390_softc *sc) 1177 1.7 thorpej { 1178 1.7 thorpej 1179 1.7 thorpej if (sc->sc_enabled == 0 && sc->sc_enable != NULL) { 1180 1.7 thorpej if ((*sc->sc_enable)(sc) != 0) { 1181 1.68 cube aprint_error_dev(sc->sc_dev, 1182 1.68 cube "device enable failed\n"); 1183 1.77 tsutsui return EIO; 1184 1.7 thorpej } 1185 1.7 thorpej } 1186 1.7 thorpej 1187 1.7 thorpej sc->sc_enabled = 1; 1188 1.77 tsutsui return 0; 1189 1.7 thorpej } 1190 1.7 thorpej 1191 1.7 thorpej /* 1192 1.7 thorpej * Disable power on the interface. 1193 1.7 thorpej */ 1194 1.7 thorpej void 1195 1.70 dsl dp8390_disable(struct dp8390_softc *sc) 1196 1.7 thorpej { 1197 1.7 thorpej 1198 1.7 thorpej if (sc->sc_enabled != 0 && sc->sc_disable != NULL) { 1199 1.7 thorpej (*sc->sc_disable)(sc); 1200 1.7 thorpej sc->sc_enabled = 0; 1201 1.7 thorpej } 1202 1.16 thorpej } 1203 1.16 thorpej 1204 1.16 thorpej int 1205 1.71 cegger dp8390_activate(device_t self, enum devact act) 1206 1.16 thorpej { 1207 1.72 dyoung struct dp8390_softc *sc = device_private(self); 1208 1.16 thorpej 1209 1.16 thorpej switch (act) { 1210 1.16 thorpej case DVACT_DEACTIVATE: 1211 1.28 itojun if_deactivate(&sc->sc_ec.ec_if); 1212 1.72 dyoung return 0; 1213 1.72 dyoung default: 1214 1.72 dyoung return EOPNOTSUPP; 1215 1.16 thorpej } 1216 1.28 itojun } 1217 1.28 itojun 1218 1.28 itojun int 1219 1.61 christos dp8390_detach(struct dp8390_softc *sc, int flags) 1220 1.28 itojun { 1221 1.28 itojun struct ifnet *ifp = &sc->sc_ec.ec_if; 1222 1.37 jhawk 1223 1.37 jhawk /* Succeed now if there's no work to do. */ 1224 1.37 jhawk if ((sc->sc_flags & DP8390_ATTACHED) == 0) 1225 1.77 tsutsui return 0; 1226 1.28 itojun 1227 1.31 itojun /* dp8390_disable() checks sc->sc_enabled */ 1228 1.28 itojun dp8390_disable(sc); 1229 1.29 enami 1230 1.42 thorpej if (sc->sc_media_fini != NULL) 1231 1.42 thorpej (*sc->sc_media_fini)(sc); 1232 1.42 thorpej 1233 1.32 enami rnd_detach_source(&sc->rnd_source); 1234 1.32 enami ether_ifdetach(ifp); 1235 1.32 enami if_detach(ifp); 1236 1.28 itojun 1237 1.97 thorpej /* Delete all remaining media. */ 1238 1.97 thorpej ifmedia_fini(&sc->sc_media); 1239 1.97 thorpej 1240 1.77 tsutsui return 0; 1241 1.1 scottr } 1242