1 1.162 riastrad /* $NetBSD: i82557.c,v 1.162 2024/06/29 12:11:11 riastradh Exp $ */ 2 1.1 thorpej 3 1.1 thorpej /*- 4 1.65 mycroft * Copyright (c) 1997, 1998, 1999, 2001, 2002 The NetBSD Foundation, Inc. 5 1.1 thorpej * All rights reserved. 6 1.1 thorpej * 7 1.1 thorpej * This code is derived from software contributed to The NetBSD Foundation 8 1.1 thorpej * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 1.1 thorpej * NASA Ames Research Center. 10 1.1 thorpej * 11 1.1 thorpej * Redistribution and use in source and binary forms, with or without 12 1.1 thorpej * modification, are permitted provided that the following conditions 13 1.1 thorpej * are met: 14 1.1 thorpej * 1. Redistributions of source code must retain the above copyright 15 1.1 thorpej * notice, this list of conditions and the following disclaimer. 16 1.1 thorpej * 2. Redistributions in binary form must reproduce the above copyright 17 1.1 thorpej * notice, this list of conditions and the following disclaimer in the 18 1.1 thorpej * documentation and/or other materials provided with the distribution. 19 1.1 thorpej * 20 1.1 thorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 1.1 thorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 1.1 thorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 1.1 thorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 1.1 thorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 1.1 thorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 1.1 thorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 1.1 thorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 1.1 thorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 1.1 thorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 1.1 thorpej * POSSIBILITY OF SUCH DAMAGE. 31 1.1 thorpej */ 32 1.1 thorpej 33 1.1 thorpej /* 34 1.1 thorpej * Copyright (c) 1995, David Greenman 35 1.52 thorpej * Copyright (c) 2001 Jonathan Lemon <jlemon (at) freebsd.org> 36 1.1 thorpej * All rights reserved. 37 1.1 thorpej * 38 1.1 thorpej * Redistribution and use in source and binary forms, with or without 39 1.1 thorpej * modification, are permitted provided that the following conditions 40 1.1 thorpej * are met: 41 1.1 thorpej * 1. Redistributions of source code must retain the above copyright 42 1.1 thorpej * notice unmodified, this list of conditions, and the following 43 1.1 thorpej * disclaimer. 44 1.1 thorpej * 2. Redistributions in binary form must reproduce the above copyright 45 1.1 thorpej * notice, this list of conditions and the following disclaimer in the 46 1.1 thorpej * documentation and/or other materials provided with the distribution. 47 1.1 thorpej * 48 1.1 thorpej * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 49 1.1 thorpej * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50 1.1 thorpej * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51 1.1 thorpej * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 52 1.1 thorpej * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 1.1 thorpej * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 1.1 thorpej * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 1.1 thorpej * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 1.1 thorpej * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 1.1 thorpej * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 1.1 thorpej * SUCH DAMAGE. 59 1.1 thorpej * 60 1.52 thorpej * Id: if_fxp.c,v 1.113 2001/05/17 23:50:24 jlemon 61 1.1 thorpej */ 62 1.1 thorpej 63 1.1 thorpej /* 64 1.14 sommerfe * Device driver for the Intel i82557 fast Ethernet controller, 65 1.14 sommerfe * and its successors, the i82558 and i82559. 66 1.1 thorpej */ 67 1.61 lukem 68 1.61 lukem #include <sys/cdefs.h> 69 1.162 riastrad __KERNEL_RCSID(0, "$NetBSD: i82557.c,v 1.162 2024/06/29 12:11:11 riastradh Exp $"); 70 1.1 thorpej 71 1.1 thorpej #include <sys/param.h> 72 1.1 thorpej #include <sys/systm.h> 73 1.24 thorpej #include <sys/callout.h> 74 1.1 thorpej #include <sys/mbuf.h> 75 1.1 thorpej #include <sys/malloc.h> 76 1.1 thorpej #include <sys/kernel.h> 77 1.1 thorpej #include <sys/socket.h> 78 1.1 thorpej #include <sys/ioctl.h> 79 1.1 thorpej #include <sys/errno.h> 80 1.1 thorpej #include <sys/device.h> 81 1.89 thorpej #include <sys/syslog.h> 82 1.136 uebayasi #include <sys/proc.h> 83 1.1 thorpej 84 1.15 thorpej #include <machine/endian.h> 85 1.15 thorpej 86 1.143 riastrad #include <sys/rndsource.h> 87 1.1 thorpej 88 1.1 thorpej #include <net/if.h> 89 1.1 thorpej #include <net/if_dl.h> 90 1.1 thorpej #include <net/if_media.h> 91 1.1 thorpej #include <net/if_ether.h> 92 1.1 thorpej 93 1.125 tsutsui #include <netinet/in.h> 94 1.125 tsutsui #include <netinet/in_systm.h> 95 1.125 tsutsui #include <netinet/ip.h> 96 1.125 tsutsui #include <netinet/tcp.h> 97 1.125 tsutsui #include <netinet/udp.h> 98 1.125 tsutsui 99 1.1 thorpej #include <net/bpf.h> 100 1.1 thorpej 101 1.104 ad #include <sys/bus.h> 102 1.104 ad #include <sys/intr.h> 103 1.1 thorpej 104 1.1 thorpej #include <dev/mii/miivar.h> 105 1.1 thorpej 106 1.1 thorpej #include <dev/ic/i82557reg.h> 107 1.1 thorpej #include <dev/ic/i82557var.h> 108 1.1 thorpej 109 1.64 thorpej #include <dev/microcode/i8255x/rcvbundl.h> 110 1.64 thorpej 111 1.1 thorpej /* 112 1.1 thorpej * NOTE! On the Alpha, we have an alignment constraint. The 113 1.1 thorpej * card DMAs the packet immediately following the RFA. However, 114 1.1 thorpej * the first thing in the packet is a 14-byte Ethernet header. 115 1.1 thorpej * This means that the packet is misaligned. To compensate, 116 1.1 thorpej * we actually offset the RFA 2 bytes into the cluster. This 117 1.161 andvar * aligns the packet after the Ethernet header at a 32-bit 118 1.1 thorpej * boundary. HOWEVER! This means that the RFA is misaligned! 119 1.1 thorpej */ 120 1.1 thorpej #define RFA_ALIGNMENT_FUDGE 2 121 1.1 thorpej 122 1.1 thorpej /* 123 1.52 thorpej * The configuration byte map has several undefined fields which 124 1.52 thorpej * must be one or must be zero. Set up a template for these bits 125 1.52 thorpej * only (assuming an i82557 chip), leaving the actual configuration 126 1.52 thorpej * for fxp_init(). 127 1.52 thorpej * 128 1.52 thorpej * See the definition of struct fxp_cb_config for the bit definitions. 129 1.1 thorpej */ 130 1.127 tsutsui const uint8_t fxp_cb_config_template[] = { 131 1.1 thorpej 0x0, 0x0, /* cb_status */ 132 1.52 thorpej 0x0, 0x0, /* cb_command */ 133 1.52 thorpej 0x0, 0x0, 0x0, 0x0, /* link_addr */ 134 1.52 thorpej 0x0, /* 0 */ 135 1.52 thorpej 0x0, /* 1 */ 136 1.1 thorpej 0x0, /* 2 */ 137 1.1 thorpej 0x0, /* 3 */ 138 1.1 thorpej 0x0, /* 4 */ 139 1.52 thorpej 0x0, /* 5 */ 140 1.52 thorpej 0x32, /* 6 */ 141 1.52 thorpej 0x0, /* 7 */ 142 1.52 thorpej 0x0, /* 8 */ 143 1.1 thorpej 0x0, /* 9 */ 144 1.52 thorpej 0x6, /* 10 */ 145 1.1 thorpej 0x0, /* 11 */ 146 1.52 thorpej 0x0, /* 12 */ 147 1.1 thorpej 0x0, /* 13 */ 148 1.1 thorpej 0xf2, /* 14 */ 149 1.1 thorpej 0x48, /* 15 */ 150 1.1 thorpej 0x0, /* 16 */ 151 1.1 thorpej 0x40, /* 17 */ 152 1.52 thorpej 0xf0, /* 18 */ 153 1.1 thorpej 0x0, /* 19 */ 154 1.1 thorpej 0x3f, /* 20 */ 155 1.53 thorpej 0x5, /* 21 */ 156 1.53 thorpej 0x0, /* 22 */ 157 1.53 thorpej 0x0, /* 23 */ 158 1.53 thorpej 0x0, /* 24 */ 159 1.53 thorpej 0x0, /* 25 */ 160 1.53 thorpej 0x0, /* 26 */ 161 1.53 thorpej 0x0, /* 27 */ 162 1.53 thorpej 0x0, /* 28 */ 163 1.53 thorpej 0x0, /* 29 */ 164 1.53 thorpej 0x0, /* 30 */ 165 1.53 thorpej 0x0, /* 31 */ 166 1.1 thorpej }; 167 1.1 thorpej 168 1.46 thorpej void fxp_mii_initmedia(struct fxp_softc *); 169 1.46 thorpej void fxp_mii_mediastatus(struct ifnet *, struct ifmediareq *); 170 1.46 thorpej 171 1.46 thorpej void fxp_80c24_initmedia(struct fxp_softc *); 172 1.46 thorpej int fxp_80c24_mediachange(struct ifnet *); 173 1.46 thorpej void fxp_80c24_mediastatus(struct ifnet *, struct ifmediareq *); 174 1.46 thorpej 175 1.46 thorpej void fxp_start(struct ifnet *); 176 1.101 christos int fxp_ioctl(struct ifnet *, u_long, void *); 177 1.46 thorpej void fxp_watchdog(struct ifnet *); 178 1.46 thorpej int fxp_init(struct ifnet *); 179 1.46 thorpej void fxp_stop(struct ifnet *, int); 180 1.46 thorpej 181 1.55 thorpej void fxp_txintr(struct fxp_softc *); 182 1.105 tsutsui int fxp_rxintr(struct fxp_softc *); 183 1.55 thorpej 184 1.152 msaitoh void fxp_rx_hwcksum(struct fxp_softc *, struct mbuf *, 185 1.125 tsutsui const struct fxp_rfa *, u_int); 186 1.75 yamt 187 1.46 thorpej void fxp_rxdrain(struct fxp_softc *); 188 1.46 thorpej int fxp_add_rfabuf(struct fxp_softc *, bus_dmamap_t, int); 189 1.150 msaitoh int fxp_mdi_read(device_t, int, int, uint16_t *); 190 1.140 matt void fxp_statchg(struct ifnet *); 191 1.150 msaitoh int fxp_mdi_write(device_t, int, int, uint16_t); 192 1.46 thorpej void fxp_autosize_eeprom(struct fxp_softc*); 193 1.127 tsutsui void fxp_read_eeprom(struct fxp_softc *, uint16_t *, int, int); 194 1.127 tsutsui void fxp_write_eeprom(struct fxp_softc *, uint16_t *, int, int); 195 1.63 thorpej void fxp_eeprom_update_cksum(struct fxp_softc *); 196 1.127 tsutsui void fxp_get_info(struct fxp_softc *, uint8_t *); 197 1.46 thorpej void fxp_tick(void *); 198 1.46 thorpej void fxp_mc_setup(struct fxp_softc *); 199 1.64 thorpej void fxp_load_ucode(struct fxp_softc *); 200 1.1 thorpej 201 1.7 thorpej int fxp_copy_small = 0; 202 1.10 sommerfe 203 1.64 thorpej /* 204 1.64 thorpej * Variables for interrupt mitigating microcode. 205 1.64 thorpej */ 206 1.64 thorpej int fxp_int_delay = 1000; /* usec */ 207 1.64 thorpej int fxp_bundle_max = 6; /* packets */ 208 1.64 thorpej 209 1.1 thorpej struct fxp_phytype { 210 1.1 thorpej int fp_phy; /* type of PHY, -1 for MII at the end. */ 211 1.46 thorpej void (*fp_init)(struct fxp_softc *); 212 1.1 thorpej } fxp_phytype_table[] = { 213 1.1 thorpej { FXP_PHY_80C24, fxp_80c24_initmedia }, 214 1.1 thorpej { -1, fxp_mii_initmedia }, 215 1.1 thorpej }; 216 1.1 thorpej 217 1.1 thorpej /* 218 1.1 thorpej * Set initial transmit threshold at 64 (512 bytes). This is 219 1.1 thorpej * increased by 64 (512 bytes) at a time, to maximum of 192 220 1.1 thorpej * (1536 bytes), if an underrun occurs. 221 1.1 thorpej */ 222 1.1 thorpej static int tx_threshold = 64; 223 1.1 thorpej 224 1.1 thorpej /* 225 1.1 thorpej * Wait for the previous command to be accepted (but not necessarily 226 1.1 thorpej * completed). 227 1.1 thorpej */ 228 1.96 perry static inline void 229 1.46 thorpej fxp_scb_wait(struct fxp_softc *sc) 230 1.1 thorpej { 231 1.1 thorpej int i = 10000; 232 1.1 thorpej 233 1.1 thorpej while (CSR_READ_1(sc, FXP_CSR_SCB_COMMAND) && --i) 234 1.2 thorpej delay(2); 235 1.1 thorpej if (i == 0) 236 1.89 thorpej log(LOG_WARNING, 237 1.114 joerg "%s: WARNING: SCB timed out!\n", device_xname(sc->sc_dev)); 238 1.1 thorpej } 239 1.1 thorpej 240 1.1 thorpej /* 241 1.47 thorpej * Submit a command to the i82557. 242 1.47 thorpej */ 243 1.96 perry static inline void 244 1.127 tsutsui fxp_scb_cmd(struct fxp_softc *sc, uint8_t cmd) 245 1.47 thorpej { 246 1.47 thorpej 247 1.47 thorpej CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, cmd); 248 1.47 thorpej } 249 1.47 thorpej 250 1.47 thorpej /* 251 1.1 thorpej * Finish attaching an i82557 interface. Called by bus-specific front-end. 252 1.1 thorpej */ 253 1.1 thorpej void 254 1.46 thorpej fxp_attach(struct fxp_softc *sc) 255 1.1 thorpej { 256 1.127 tsutsui uint8_t enaddr[ETHER_ADDR_LEN]; 257 1.1 thorpej struct ifnet *ifp; 258 1.1 thorpej bus_dma_segment_t seg; 259 1.1 thorpej int rseg, i, error; 260 1.1 thorpej struct fxp_phytype *fp; 261 1.1 thorpej 262 1.102 ad callout_init(&sc->sc_callout, 0); 263 1.159 thorpej callout_setfunc(&sc->sc_callout, fxp_tick, sc); 264 1.24 thorpej 265 1.75 yamt /* 266 1.128 tsutsui * Enable use of extended RFDs and IPCBs for 82550 and later chips. 267 1.128 tsutsui * Note: to use IPCB we need extended TXCB support too, and 268 1.128 tsutsui * these feature flags should be set in each bus attachment. 269 1.75 yamt */ 270 1.128 tsutsui if (sc->sc_flags & FXPF_EXT_RFA) { 271 1.75 yamt sc->sc_txcmd = htole16(FXP_CB_COMMAND_IPCBXMIT); 272 1.128 tsutsui sc->sc_rfa_size = RFA_EXT_SIZE; 273 1.128 tsutsui } else { 274 1.75 yamt sc->sc_txcmd = htole16(FXP_CB_COMMAND_XMIT); 275 1.128 tsutsui sc->sc_rfa_size = RFA_SIZE; 276 1.128 tsutsui } 277 1.75 yamt 278 1.52 thorpej /* 279 1.1 thorpej * Allocate the control data structures, and create and load the 280 1.1 thorpej * DMA map for it. 281 1.1 thorpej */ 282 1.1 thorpej if ((error = bus_dmamem_alloc(sc->sc_dmat, 283 1.1 thorpej sizeof(struct fxp_control_data), PAGE_SIZE, 0, &seg, 1, &rseg, 284 1.1 thorpej 0)) != 0) { 285 1.114 joerg aprint_error_dev(sc->sc_dev, 286 1.112 cegger "unable to allocate control data, error = %d\n", 287 1.112 cegger error); 288 1.1 thorpej goto fail_0; 289 1.1 thorpej } 290 1.1 thorpej 291 1.1 thorpej if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, 292 1.101 christos sizeof(struct fxp_control_data), (void **)&sc->sc_control_data, 293 1.1 thorpej BUS_DMA_COHERENT)) != 0) { 294 1.121 tsutsui aprint_error_dev(sc->sc_dev, 295 1.121 tsutsui "unable to map control data, error = %d\n", error); 296 1.1 thorpej goto fail_1; 297 1.1 thorpej } 298 1.18 joda sc->sc_cdseg = seg; 299 1.18 joda sc->sc_cdnseg = rseg; 300 1.18 joda 301 1.57 thorpej memset(sc->sc_control_data, 0, sizeof(struct fxp_control_data)); 302 1.1 thorpej 303 1.1 thorpej if ((error = bus_dmamap_create(sc->sc_dmat, 304 1.1 thorpej sizeof(struct fxp_control_data), 1, 305 1.1 thorpej sizeof(struct fxp_control_data), 0, 0, &sc->sc_dmamap)) != 0) { 306 1.121 tsutsui aprint_error_dev(sc->sc_dev, 307 1.121 tsutsui "unable to create control data DMA map, error = %d\n", 308 1.121 tsutsui error); 309 1.1 thorpej goto fail_2; 310 1.1 thorpej } 311 1.1 thorpej 312 1.1 thorpej if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, 313 1.2 thorpej sc->sc_control_data, sizeof(struct fxp_control_data), NULL, 314 1.1 thorpej 0)) != 0) { 315 1.114 joerg aprint_error_dev(sc->sc_dev, 316 1.112 cegger "can't load control data DMA map, error = %d\n", 317 1.112 cegger error); 318 1.1 thorpej goto fail_3; 319 1.1 thorpej } 320 1.1 thorpej 321 1.1 thorpej /* 322 1.1 thorpej * Create the transmit buffer DMA maps. 323 1.1 thorpej */ 324 1.1 thorpej for (i = 0; i < FXP_NTXCB; i++) { 325 1.1 thorpej if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 326 1.124 tsutsui (sc->sc_flags & FXPF_EXT_RFA) ? 327 1.124 tsutsui FXP_IPCB_NTXSEG : FXP_NTXSEG, 328 1.75 yamt MCLBYTES, 0, 0, &FXP_DSTX(sc, i)->txs_dmamap)) != 0) { 329 1.121 tsutsui aprint_error_dev(sc->sc_dev, 330 1.121 tsutsui "unable to create tx DMA map %d, error = %d\n", 331 1.121 tsutsui i, error); 332 1.1 thorpej goto fail_4; 333 1.1 thorpej } 334 1.1 thorpej } 335 1.1 thorpej 336 1.1 thorpej /* 337 1.1 thorpej * Create the receive buffer DMA maps. 338 1.1 thorpej */ 339 1.1 thorpej for (i = 0; i < FXP_NRFABUFS; i++) { 340 1.1 thorpej if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, 341 1.7 thorpej MCLBYTES, 0, 0, &sc->sc_rxmaps[i])) != 0) { 342 1.121 tsutsui aprint_error_dev(sc->sc_dev, 343 1.121 tsutsui "unable to create rx DMA map %d, error = %d\n", 344 1.121 tsutsui i, error); 345 1.1 thorpej goto fail_5; 346 1.1 thorpej } 347 1.1 thorpej } 348 1.1 thorpej 349 1.1 thorpej /* Initialize MAC address and media structures. */ 350 1.1 thorpej fxp_get_info(sc, enaddr); 351 1.1 thorpej 352 1.114 joerg aprint_normal_dev(sc->sc_dev, "Ethernet address %s\n", 353 1.51 thorpej ether_sprintf(enaddr)); 354 1.1 thorpej 355 1.1 thorpej ifp = &sc->sc_ethercom.ec_if; 356 1.1 thorpej 357 1.1 thorpej /* 358 1.1 thorpej * Get info about our media interface, and initialize it. Note 359 1.1 thorpej * the table terminates itself with a phy of -1, indicating 360 1.1 thorpej * that we're using MII. 361 1.1 thorpej */ 362 1.1 thorpej for (fp = fxp_phytype_table; fp->fp_phy != -1; fp++) 363 1.1 thorpej if (fp->fp_phy == sc->phy_primary_device) 364 1.1 thorpej break; 365 1.1 thorpej (*fp->fp_init)(sc); 366 1.1 thorpej 367 1.114 joerg strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 368 1.1 thorpej ifp->if_softc = sc; 369 1.1 thorpej ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 370 1.1 thorpej ifp->if_ioctl = fxp_ioctl; 371 1.1 thorpej ifp->if_start = fxp_start; 372 1.1 thorpej ifp->if_watchdog = fxp_watchdog; 373 1.40 thorpej ifp->if_init = fxp_init; 374 1.40 thorpej ifp->if_stop = fxp_stop; 375 1.43 thorpej IFQ_SET_READY(&ifp->if_snd); 376 1.1 thorpej 377 1.124 tsutsui if (sc->sc_flags & FXPF_EXT_RFA) { 378 1.78 yamt /* 379 1.128 tsutsui * Enable hardware cksum support by EXT_RFA and IPCB. 380 1.128 tsutsui * 381 1.90 yamt * IFCAP_CSUM_IPv4_Tx seems to have a problem, 382 1.78 yamt * at least, on i82550 rev.12. 383 1.117 tsutsui * specifically, it doesn't set ipv4 checksum properly 384 1.117 tsutsui * when sending UDP (and probably TCP) packets with 385 1.117 tsutsui * 20 byte ipv4 header + 1 or 2 byte data, 386 1.117 tsutsui * though ICMP packets seem working. 387 1.78 yamt * FreeBSD driver has related comments. 388 1.117 tsutsui * We've added a workaround to handle the bug by padding 389 1.117 tsutsui * such packets manually. 390 1.78 yamt */ 391 1.75 yamt ifp->if_capabilities = 392 1.118 tsutsui IFCAP_CSUM_IPv4_Tx | IFCAP_CSUM_IPv4_Rx | 393 1.90 yamt IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_TCPv4_Rx | 394 1.90 yamt IFCAP_CSUM_UDPv4_Tx | IFCAP_CSUM_UDPv4_Rx; 395 1.81 yamt sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_HWTAGGING; 396 1.154 msaitoh sc->sc_ethercom.ec_capenable |= ETHERCAP_VLAN_HWTAGGING; 397 1.125 tsutsui } else if (sc->sc_flags & FXPF_82559_RXCSUM) { 398 1.125 tsutsui ifp->if_capabilities = 399 1.125 tsutsui IFCAP_CSUM_TCPv4_Rx | 400 1.125 tsutsui IFCAP_CSUM_UDPv4_Rx; 401 1.75 yamt } 402 1.75 yamt 403 1.75 yamt /* 404 1.39 thorpej * We can support 802.1Q VLAN-sized frames. 405 1.39 thorpej */ 406 1.39 thorpej sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU; 407 1.39 thorpej 408 1.39 thorpej /* 409 1.1 thorpej * Attach the interface. 410 1.1 thorpej */ 411 1.1 thorpej if_attach(ifp); 412 1.147 ozaki if_deferred_start_init(ifp, NULL); 413 1.1 thorpej ether_ifattach(ifp, enaddr); 414 1.114 joerg rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), 415 1.142 tls RND_TYPE_NET, RND_FLAG_DEFAULT); 416 1.1 thorpej 417 1.55 thorpej #ifdef FXP_EVENT_COUNTERS 418 1.55 thorpej evcnt_attach_dynamic(&sc->sc_ev_txstall, EVCNT_TYPE_MISC, 419 1.114 joerg NULL, device_xname(sc->sc_dev), "txstall"); 420 1.55 thorpej evcnt_attach_dynamic(&sc->sc_ev_txintr, EVCNT_TYPE_INTR, 421 1.114 joerg NULL, device_xname(sc->sc_dev), "txintr"); 422 1.55 thorpej evcnt_attach_dynamic(&sc->sc_ev_rxintr, EVCNT_TYPE_INTR, 423 1.114 joerg NULL, device_xname(sc->sc_dev), "rxintr"); 424 1.122 mrg if (sc->sc_flags & FXPF_FC) { 425 1.86 thorpej evcnt_attach_dynamic(&sc->sc_ev_txpause, EVCNT_TYPE_MISC, 426 1.114 joerg NULL, device_xname(sc->sc_dev), "txpause"); 427 1.86 thorpej evcnt_attach_dynamic(&sc->sc_ev_rxpause, EVCNT_TYPE_MISC, 428 1.114 joerg NULL, device_xname(sc->sc_dev), "rxpause"); 429 1.86 thorpej } 430 1.55 thorpej #endif /* FXP_EVENT_COUNTERS */ 431 1.55 thorpej 432 1.34 jhawk /* The attach is successful. */ 433 1.34 jhawk sc->sc_flags |= FXPF_ATTACHED; 434 1.34 jhawk 435 1.1 thorpej return; 436 1.1 thorpej 437 1.1 thorpej /* 438 1.1 thorpej * Free any resources we've allocated during the failed attach 439 1.1 thorpej * attempt. Do this in reverse order and fall though. 440 1.1 thorpej */ 441 1.1 thorpej fail_5: 442 1.1 thorpej for (i = 0; i < FXP_NRFABUFS; i++) { 443 1.7 thorpej if (sc->sc_rxmaps[i] != NULL) 444 1.7 thorpej bus_dmamap_destroy(sc->sc_dmat, sc->sc_rxmaps[i]); 445 1.1 thorpej } 446 1.1 thorpej fail_4: 447 1.1 thorpej for (i = 0; i < FXP_NTXCB; i++) { 448 1.2 thorpej if (FXP_DSTX(sc, i)->txs_dmamap != NULL) 449 1.1 thorpej bus_dmamap_destroy(sc->sc_dmat, 450 1.2 thorpej FXP_DSTX(sc, i)->txs_dmamap); 451 1.1 thorpej } 452 1.1 thorpej bus_dmamap_unload(sc->sc_dmat, sc->sc_dmamap); 453 1.1 thorpej fail_3: 454 1.1 thorpej bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmamap); 455 1.1 thorpej fail_2: 456 1.101 christos bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_control_data, 457 1.1 thorpej sizeof(struct fxp_control_data)); 458 1.1 thorpej fail_1: 459 1.1 thorpej bus_dmamem_free(sc->sc_dmat, &seg, rseg); 460 1.1 thorpej fail_0: 461 1.1 thorpej return; 462 1.1 thorpej } 463 1.1 thorpej 464 1.1 thorpej void 465 1.46 thorpej fxp_mii_initmedia(struct fxp_softc *sc) 466 1.1 thorpej { 467 1.152 msaitoh struct mii_data * const mii = &sc->sc_mii; 468 1.59 enami int flags; 469 1.1 thorpej 470 1.6 thorpej sc->sc_flags |= FXPF_MII; 471 1.6 thorpej 472 1.152 msaitoh mii->mii_ifp = &sc->sc_ethercom.ec_if; 473 1.152 msaitoh mii->mii_readreg = fxp_mdi_read; 474 1.152 msaitoh mii->mii_writereg = fxp_mdi_write; 475 1.152 msaitoh mii->mii_statchg = fxp_statchg; 476 1.110 dyoung 477 1.152 msaitoh sc->sc_ethercom.ec_mii = mii; 478 1.152 msaitoh ifmedia_init(&mii->mii_media, IFM_IMASK, ether_mediachange, 479 1.1 thorpej fxp_mii_mediastatus); 480 1.59 enami 481 1.59 enami flags = MIIF_NOISOLATE; 482 1.122 mrg if (sc->sc_flags & FXPF_FC) 483 1.152 msaitoh flags |= MIIF_FORCEANEG | MIIF_DOPAUSE; 484 1.17 thorpej /* 485 1.17 thorpej * The i82557 wedges if all of its PHYs are isolated! 486 1.17 thorpej */ 487 1.152 msaitoh mii_attach(sc->sc_dev, mii, 0xffffffff, MII_PHY_ANY, 488 1.59 enami MII_OFFSET_ANY, flags); 489 1.152 msaitoh if (LIST_EMPTY(&mii->mii_phys)) { 490 1.152 msaitoh ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL); 491 1.152 msaitoh ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE); 492 1.1 thorpej } else 493 1.152 msaitoh ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO); 494 1.1 thorpej } 495 1.1 thorpej 496 1.1 thorpej void 497 1.46 thorpej fxp_80c24_initmedia(struct fxp_softc *sc) 498 1.1 thorpej { 499 1.152 msaitoh struct mii_data * const mii = &sc->sc_mii; 500 1.1 thorpej 501 1.1 thorpej /* 502 1.1 thorpej * The Seeq 80c24 AutoDUPLEX(tm) Ethernet Interface Adapter 503 1.1 thorpej * doesn't have a programming interface of any sort. The 504 1.1 thorpej * media is sensed automatically based on how the link partner 505 1.1 thorpej * is configured. This is, in essence, manual configuration. 506 1.1 thorpej */ 507 1.121 tsutsui aprint_normal_dev(sc->sc_dev, 508 1.121 tsutsui "Seeq 80c24 AutoDUPLEX media interface present\n"); 509 1.152 msaitoh ifmedia_init(&mii->mii_media, 0, fxp_80c24_mediachange, 510 1.1 thorpej fxp_80c24_mediastatus); 511 1.152 msaitoh ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_MANUAL, 0, NULL); 512 1.152 msaitoh ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_MANUAL); 513 1.1 thorpej } 514 1.1 thorpej 515 1.1 thorpej /* 516 1.1 thorpej * Initialize the interface media. 517 1.1 thorpej */ 518 1.1 thorpej void 519 1.127 tsutsui fxp_get_info(struct fxp_softc *sc, uint8_t *enaddr) 520 1.1 thorpej { 521 1.127 tsutsui uint16_t data, myea[ETHER_ADDR_LEN / 2]; 522 1.1 thorpej 523 1.1 thorpej /* 524 1.1 thorpej * Reset to a stable state. 525 1.1 thorpej */ 526 1.1 thorpej CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SELECTIVE_RESET); 527 1.79 hpeyerl DELAY(100); 528 1.1 thorpej 529 1.13 joda sc->sc_eeprom_size = 0; 530 1.13 joda fxp_autosize_eeprom(sc); 531 1.69 enami if (sc->sc_eeprom_size == 0) { 532 1.114 joerg aprint_error_dev(sc->sc_dev, "failed to detect EEPROM size\n"); 533 1.69 enami sc->sc_eeprom_size = 6; /* XXX panic here? */ 534 1.10 sommerfe } 535 1.10 sommerfe #ifdef DEBUG 536 1.114 joerg aprint_debug_dev(sc->sc_dev, "detected %d word EEPROM\n", 537 1.112 cegger 1 << sc->sc_eeprom_size); 538 1.10 sommerfe #endif 539 1.10 sommerfe 540 1.10 sommerfe /* 541 1.1 thorpej * Get info about the primary PHY 542 1.1 thorpej */ 543 1.1 thorpej fxp_read_eeprom(sc, &data, 6, 1); 544 1.51 thorpej sc->phy_primary_device = 545 1.51 thorpej (data & FXP_PHY_DEVICE_MASK) >> FXP_PHY_DEVICE_SHIFT; 546 1.1 thorpej 547 1.1 thorpej /* 548 1.1 thorpej * Read MAC address. 549 1.1 thorpej */ 550 1.1 thorpej fxp_read_eeprom(sc, myea, 0, 3); 551 1.31 soren enaddr[0] = myea[0] & 0xff; 552 1.31 soren enaddr[1] = myea[0] >> 8; 553 1.31 soren enaddr[2] = myea[1] & 0xff; 554 1.31 soren enaddr[3] = myea[1] >> 8; 555 1.31 soren enaddr[4] = myea[2] & 0xff; 556 1.31 soren enaddr[5] = myea[2] >> 8; 557 1.63 thorpej 558 1.63 thorpej /* 559 1.63 thorpej * Systems based on the ICH2/ICH2-M chip from Intel, as well 560 1.63 thorpej * as some i82559 designs, have a defect where the chip can 561 1.63 thorpej * cause a PCI protocol violation if it receives a CU_RESUME 562 1.63 thorpej * command when it is entering the IDLE state. 563 1.63 thorpej * 564 1.63 thorpej * The work-around is to disable Dynamic Standby Mode, so that 565 1.63 thorpej * the chip never deasserts #CLKRUN, and always remains in the 566 1.63 thorpej * active state. 567 1.63 thorpej * 568 1.63 thorpej * Unfortunately, the only way to disable Dynamic Standby is 569 1.63 thorpej * to frob an EEPROM setting and reboot (the EEPROM setting 570 1.63 thorpej * is only consulted when the PCI bus comes out of reset). 571 1.63 thorpej * 572 1.63 thorpej * See Intel 82801BA/82801BAM Specification Update, Errata #30. 573 1.63 thorpej */ 574 1.63 thorpej if (sc->sc_flags & FXPF_HAS_RESUME_BUG) { 575 1.63 thorpej fxp_read_eeprom(sc, &data, 10, 1); 576 1.63 thorpej if (data & 0x02) { /* STB enable */ 577 1.114 joerg aprint_error_dev(sc->sc_dev, "WARNING: " 578 1.69 enami "Disabling dynamic standby mode in EEPROM " 579 1.112 cegger "to work around a\n"); 580 1.114 joerg aprint_normal_dev(sc->sc_dev, 581 1.112 cegger "WARNING: hardware bug. You must reset " 582 1.112 cegger "the system before using this\n"); 583 1.114 joerg aprint_normal_dev(sc->sc_dev, "WARNING: interface.\n"); 584 1.63 thorpej data &= ~0x02; 585 1.63 thorpej fxp_write_eeprom(sc, &data, 10, 1); 586 1.114 joerg aprint_normal_dev(sc->sc_dev, "new EEPROM ID: 0x%04x\n", 587 1.112 cegger data); 588 1.63 thorpej fxp_eeprom_update_cksum(sc); 589 1.63 thorpej } 590 1.63 thorpej } 591 1.85 thorpej 592 1.93 abs /* Receiver lock-up workaround detection. (FXPF_RECV_WORKAROUND) */ 593 1.93 abs /* Due to false positives we make it conditional on setting link1 */ 594 1.85 thorpej fxp_read_eeprom(sc, &data, 3, 1); 595 1.85 thorpej if ((data & 0x03) != 0x03) { 596 1.121 tsutsui aprint_verbose_dev(sc->sc_dev, 597 1.121 tsutsui "May need receiver lock-up workaround\n"); 598 1.85 thorpej } 599 1.1 thorpej } 600 1.1 thorpej 601 1.62 thorpej static void 602 1.62 thorpej fxp_eeprom_shiftin(struct fxp_softc *sc, int data, int len) 603 1.62 thorpej { 604 1.62 thorpej uint16_t reg; 605 1.62 thorpej int x; 606 1.62 thorpej 607 1.62 thorpej for (x = 1 << (len - 1); x != 0; x >>= 1) { 608 1.79 hpeyerl DELAY(40); 609 1.62 thorpej if (data & x) 610 1.62 thorpej reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI; 611 1.62 thorpej else 612 1.62 thorpej reg = FXP_EEPROM_EECS; 613 1.62 thorpej CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg); 614 1.79 hpeyerl DELAY(40); 615 1.62 thorpej CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 616 1.62 thorpej reg | FXP_EEPROM_EESK); 617 1.79 hpeyerl DELAY(40); 618 1.62 thorpej CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg); 619 1.62 thorpej } 620 1.79 hpeyerl DELAY(40); 621 1.62 thorpej } 622 1.62 thorpej 623 1.1 thorpej /* 624 1.13 joda * Figure out EEPROM size. 625 1.13 joda * 626 1.13 joda * 559's can have either 64-word or 256-word EEPROMs, the 558 627 1.13 joda * datasheet only talks about 64-word EEPROMs, and the 557 datasheet 628 1.77 wiz * talks about the existence of 16 to 256 word EEPROMs. 629 1.13 joda * 630 1.13 joda * The only known sizes are 64 and 256, where the 256 version is used 631 1.13 joda * by CardBus cards to store CIS information. 632 1.13 joda * 633 1.13 joda * The address is shifted in msb-to-lsb, and after the last 634 1.13 joda * address-bit the EEPROM is supposed to output a `dummy zero' bit, 635 1.13 joda * after which follows the actual data. We try to detect this zero, by 636 1.13 joda * probing the data-out bit in the EEPROM control register just after 637 1.13 joda * having shifted in a bit. If the bit is zero, we assume we've 638 1.13 joda * shifted enough address bits. The data-out should be tri-state, 639 1.13 joda * before this, which should translate to a logical one. 640 1.13 joda * 641 1.13 joda * Other ways to do this would be to try to read a register with known 642 1.13 joda * contents with a varying number of address bits, but no such 643 1.13 joda * register seem to be available. The high bits of register 10 are 01 644 1.13 joda * on the 558 and 559, but apparently not on the 557. 645 1.69 enami * 646 1.13 joda * The Linux driver computes a checksum on the EEPROM data, but the 647 1.13 joda * value of this checksum is not very well documented. 648 1.13 joda */ 649 1.13 joda 650 1.13 joda void 651 1.46 thorpej fxp_autosize_eeprom(struct fxp_softc *sc) 652 1.13 joda { 653 1.13 joda int x; 654 1.13 joda 655 1.13 joda CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS); 656 1.79 hpeyerl DELAY(40); 657 1.62 thorpej 658 1.62 thorpej /* Shift in read opcode. */ 659 1.62 thorpej fxp_eeprom_shiftin(sc, FXP_EEPROM_OPC_READ, 3); 660 1.62 thorpej 661 1.13 joda /* 662 1.13 joda * Shift in address, wait for the dummy zero following a correct 663 1.13 joda * address shift. 664 1.13 joda */ 665 1.62 thorpej for (x = 1; x <= 8; x++) { 666 1.13 joda CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS); 667 1.79 hpeyerl DELAY(40); 668 1.13 joda CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 669 1.19 enami FXP_EEPROM_EECS | FXP_EEPROM_EESK); 670 1.79 hpeyerl DELAY(40); 671 1.69 enami if ((CSR_READ_2(sc, FXP_CSR_EEPROMCONTROL) & 672 1.13 joda FXP_EEPROM_EEDO) == 0) 673 1.13 joda break; 674 1.79 hpeyerl DELAY(40); 675 1.13 joda CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS); 676 1.79 hpeyerl DELAY(40); 677 1.13 joda } 678 1.13 joda CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0); 679 1.79 hpeyerl DELAY(40); 680 1.69 enami if (x != 6 && x != 8) { 681 1.13 joda #ifdef DEBUG 682 1.69 enami printf("%s: strange EEPROM size (%d)\n", 683 1.114 joerg device_xname(sc->sc_dev), 1 << x); 684 1.13 joda #endif 685 1.13 joda } else 686 1.13 joda sc->sc_eeprom_size = x; 687 1.13 joda } 688 1.13 joda 689 1.13 joda /* 690 1.1 thorpej * Read from the serial EEPROM. Basically, you manually shift in 691 1.1 thorpej * the read opcode (one bit at a time) and then shift in the address, 692 1.1 thorpej * and then you shift out the data (all of this one bit at a time). 693 1.1 thorpej * The word size is 16 bits, so you have to provide the address for 694 1.1 thorpej * every 16 bits of data. 695 1.1 thorpej */ 696 1.1 thorpej void 697 1.127 tsutsui fxp_read_eeprom(struct fxp_softc *sc, uint16_t *data, int offset, int words) 698 1.1 thorpej { 699 1.127 tsutsui uint16_t reg; 700 1.1 thorpej int i, x; 701 1.1 thorpej 702 1.1 thorpej for (i = 0; i < words; i++) { 703 1.1 thorpej CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS); 704 1.62 thorpej 705 1.62 thorpej /* Shift in read opcode. */ 706 1.62 thorpej fxp_eeprom_shiftin(sc, FXP_EEPROM_OPC_READ, 3); 707 1.62 thorpej 708 1.62 thorpej /* Shift in address. */ 709 1.62 thorpej fxp_eeprom_shiftin(sc, i + offset, sc->sc_eeprom_size); 710 1.62 thorpej 711 1.1 thorpej reg = FXP_EEPROM_EECS; 712 1.1 thorpej data[i] = 0; 713 1.62 thorpej 714 1.62 thorpej /* Shift out data. */ 715 1.1 thorpej for (x = 16; x > 0; x--) { 716 1.1 thorpej CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 717 1.1 thorpej reg | FXP_EEPROM_EESK); 718 1.79 hpeyerl DELAY(40); 719 1.1 thorpej if (CSR_READ_2(sc, FXP_CSR_EEPROMCONTROL) & 720 1.1 thorpej FXP_EEPROM_EEDO) 721 1.1 thorpej data[i] |= (1 << (x - 1)); 722 1.1 thorpej CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg); 723 1.79 hpeyerl DELAY(40); 724 1.1 thorpej } 725 1.1 thorpej CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0); 726 1.79 hpeyerl DELAY(40); 727 1.1 thorpej } 728 1.63 thorpej } 729 1.63 thorpej 730 1.63 thorpej /* 731 1.63 thorpej * Write data to the serial EEPROM. 732 1.63 thorpej */ 733 1.63 thorpej void 734 1.127 tsutsui fxp_write_eeprom(struct fxp_softc *sc, uint16_t *data, int offset, int words) 735 1.63 thorpej { 736 1.63 thorpej int i, j; 737 1.63 thorpej 738 1.63 thorpej for (i = 0; i < words; i++) { 739 1.63 thorpej /* Erase/write enable. */ 740 1.63 thorpej CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS); 741 1.63 thorpej fxp_eeprom_shiftin(sc, FXP_EEPROM_OPC_ERASE, 3); 742 1.63 thorpej fxp_eeprom_shiftin(sc, 0x3 << (sc->sc_eeprom_size - 2), 743 1.63 thorpej sc->sc_eeprom_size); 744 1.63 thorpej CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0); 745 1.63 thorpej DELAY(4); 746 1.63 thorpej 747 1.63 thorpej /* Shift in write opcode, address, data. */ 748 1.63 thorpej CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS); 749 1.63 thorpej fxp_eeprom_shiftin(sc, FXP_EEPROM_OPC_WRITE, 3); 750 1.108 tsutsui fxp_eeprom_shiftin(sc, i + offset, sc->sc_eeprom_size); 751 1.63 thorpej fxp_eeprom_shiftin(sc, data[i], 16); 752 1.63 thorpej CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0); 753 1.63 thorpej DELAY(4); 754 1.63 thorpej 755 1.63 thorpej /* Wait for the EEPROM to finish up. */ 756 1.63 thorpej CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS); 757 1.63 thorpej DELAY(4); 758 1.63 thorpej for (j = 0; j < 1000; j++) { 759 1.63 thorpej if (CSR_READ_2(sc, FXP_CSR_EEPROMCONTROL) & 760 1.63 thorpej FXP_EEPROM_EEDO) 761 1.63 thorpej break; 762 1.63 thorpej DELAY(50); 763 1.63 thorpej } 764 1.63 thorpej CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0); 765 1.63 thorpej DELAY(4); 766 1.63 thorpej 767 1.63 thorpej /* Erase/write disable. */ 768 1.63 thorpej CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS); 769 1.63 thorpej fxp_eeprom_shiftin(sc, FXP_EEPROM_OPC_ERASE, 3); 770 1.63 thorpej fxp_eeprom_shiftin(sc, 0, sc->sc_eeprom_size); 771 1.63 thorpej CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0); 772 1.63 thorpej DELAY(4); 773 1.63 thorpej } 774 1.63 thorpej } 775 1.63 thorpej 776 1.63 thorpej /* 777 1.63 thorpej * Update the checksum of the EEPROM. 778 1.63 thorpej */ 779 1.63 thorpej void 780 1.63 thorpej fxp_eeprom_update_cksum(struct fxp_softc *sc) 781 1.63 thorpej { 782 1.63 thorpej int i; 783 1.63 thorpej uint16_t data, cksum; 784 1.63 thorpej 785 1.63 thorpej cksum = 0; 786 1.63 thorpej for (i = 0; i < (1 << sc->sc_eeprom_size) - 1; i++) { 787 1.63 thorpej fxp_read_eeprom(sc, &data, i, 1); 788 1.63 thorpej cksum += data; 789 1.63 thorpej } 790 1.63 thorpej i = (1 << sc->sc_eeprom_size) - 1; 791 1.63 thorpej cksum = 0xbaba - cksum; 792 1.63 thorpej fxp_read_eeprom(sc, &data, i, 1); 793 1.63 thorpej fxp_write_eeprom(sc, &cksum, i, 1); 794 1.89 thorpej log(LOG_INFO, "%s: EEPROM checksum @ 0x%x: 0x%04x -> 0x%04x\n", 795 1.114 joerg device_xname(sc->sc_dev), i, data, cksum); 796 1.1 thorpej } 797 1.1 thorpej 798 1.1 thorpej /* 799 1.1 thorpej * Start packet transmission on the interface. 800 1.1 thorpej */ 801 1.1 thorpej void 802 1.46 thorpej fxp_start(struct ifnet *ifp) 803 1.1 thorpej { 804 1.1 thorpej struct fxp_softc *sc = ifp->if_softc; 805 1.2 thorpej struct mbuf *m0, *m; 806 1.50 thorpej struct fxp_txdesc *txd; 807 1.2 thorpej struct fxp_txsoft *txs; 808 1.1 thorpej bus_dmamap_t dmamap; 809 1.117 tsutsui int error, lasttx, nexttx, opending, seg, nsegs, len; 810 1.1 thorpej 811 1.1 thorpej /* 812 1.8 thorpej * If we want a re-init, bail out now. 813 1.1 thorpej */ 814 1.8 thorpej if (sc->sc_flags & FXPF_WANTINIT) { 815 1.1 thorpej ifp->if_flags |= IFF_OACTIVE; 816 1.1 thorpej return; 817 1.1 thorpej } 818 1.1 thorpej 819 1.152 msaitoh if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 820 1.8 thorpej return; 821 1.8 thorpej 822 1.1 thorpej /* 823 1.2 thorpej * Remember the previous txpending and the current lasttx. 824 1.1 thorpej */ 825 1.2 thorpej opending = sc->sc_txpending; 826 1.2 thorpej lasttx = sc->sc_txlast; 827 1.1 thorpej 828 1.2 thorpej /* 829 1.2 thorpej * Loop through the send queue, setting up transmit descriptors 830 1.2 thorpej * until we drain the queue, or use up all available transmit 831 1.2 thorpej * descriptors. 832 1.2 thorpej */ 833 1.55 thorpej for (;;) { 834 1.75 yamt struct fxp_tbd *tbdp; 835 1.75 yamt int csum_flags; 836 1.75 yamt 837 1.1 thorpej /* 838 1.2 thorpej * Grab a packet off the queue. 839 1.1 thorpej */ 840 1.43 thorpej IFQ_POLL(&ifp->if_snd, m0); 841 1.2 thorpej if (m0 == NULL) 842 1.2 thorpej break; 843 1.44 thorpej m = NULL; 844 1.1 thorpej 845 1.105 tsutsui if (sc->sc_txpending == FXP_NTXCB - 1) { 846 1.55 thorpej FXP_EVCNT_INCR(&sc->sc_ev_txstall); 847 1.55 thorpej break; 848 1.55 thorpej } 849 1.55 thorpej 850 1.1 thorpej /* 851 1.2 thorpej * Get the next available transmit descriptor. 852 1.1 thorpej */ 853 1.2 thorpej nexttx = FXP_NEXTTX(sc->sc_txlast); 854 1.2 thorpej txd = FXP_CDTX(sc, nexttx); 855 1.2 thorpej txs = FXP_DSTX(sc, nexttx); 856 1.2 thorpej dmamap = txs->txs_dmamap; 857 1.1 thorpej 858 1.1 thorpej /* 859 1.2 thorpej * Load the DMA map. If this fails, the packet either 860 1.2 thorpej * didn't fit in the allotted number of frags, or we were 861 1.2 thorpej * short on resources. In this case, we'll copy and try 862 1.2 thorpej * again. 863 1.1 thorpej */ 864 1.2 thorpej if (bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0, 865 1.152 msaitoh BUS_DMA_WRITE | BUS_DMA_NOWAIT) != 0) { 866 1.2 thorpej MGETHDR(m, M_DONTWAIT, MT_DATA); 867 1.2 thorpej if (m == NULL) { 868 1.89 thorpej log(LOG_ERR, "%s: unable to allocate Tx mbuf\n", 869 1.114 joerg device_xname(sc->sc_dev)); 870 1.2 thorpej break; 871 1.1 thorpej } 872 1.73 matt MCLAIM(m, &sc->sc_ethercom.ec_tx_mowner); 873 1.2 thorpej if (m0->m_pkthdr.len > MHLEN) { 874 1.2 thorpej MCLGET(m, M_DONTWAIT); 875 1.2 thorpej if ((m->m_flags & M_EXT) == 0) { 876 1.121 tsutsui log(LOG_ERR, "%s: unable to allocate " 877 1.121 tsutsui "Tx cluster\n", 878 1.121 tsutsui device_xname(sc->sc_dev)); 879 1.2 thorpej m_freem(m); 880 1.2 thorpej break; 881 1.1 thorpej } 882 1.1 thorpej } 883 1.101 christos m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, void *)); 884 1.2 thorpej m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len; 885 1.2 thorpej error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, 886 1.152 msaitoh m, BUS_DMA_WRITE | BUS_DMA_NOWAIT); 887 1.2 thorpej if (error) { 888 1.89 thorpej log(LOG_ERR, "%s: unable to load Tx buffer, " 889 1.121 tsutsui "error = %d\n", 890 1.121 tsutsui device_xname(sc->sc_dev), error); 891 1.2 thorpej break; 892 1.2 thorpej } 893 1.2 thorpej } 894 1.43 thorpej 895 1.43 thorpej IFQ_DEQUEUE(&ifp->if_snd, m0); 896 1.75 yamt csum_flags = m0->m_pkthdr.csum_flags; 897 1.44 thorpej if (m != NULL) { 898 1.44 thorpej m_freem(m0); 899 1.44 thorpej m0 = m; 900 1.44 thorpej } 901 1.1 thorpej 902 1.2 thorpej /* Initialize the fraglist. */ 903 1.75 yamt tbdp = txd->txd_tbd; 904 1.117 tsutsui len = m0->m_pkthdr.len; 905 1.117 tsutsui nsegs = dmamap->dm_nsegs; 906 1.124 tsutsui if (sc->sc_flags & FXPF_EXT_RFA) 907 1.75 yamt tbdp++; 908 1.117 tsutsui for (seg = 0; seg < nsegs; seg++) { 909 1.75 yamt tbdp[seg].tb_addr = 910 1.15 thorpej htole32(dmamap->dm_segs[seg].ds_addr); 911 1.75 yamt tbdp[seg].tb_size = 912 1.15 thorpej htole32(dmamap->dm_segs[seg].ds_len); 913 1.1 thorpej } 914 1.117 tsutsui if (__predict_false(len <= FXP_IP4CSUMTX_PADLEN && 915 1.117 tsutsui (csum_flags & M_CSUM_IPv4) != 0)) { 916 1.117 tsutsui /* 917 1.117 tsutsui * Pad short packets to avoid ip4csum-tx bug. 918 1.117 tsutsui * 919 1.117 tsutsui * XXX Should we still consider if such short 920 1.117 tsutsui * (36 bytes or less) packets might already 921 1.117 tsutsui * occupy FXP_IPCB_NTXSEG (15) fragments here? 922 1.117 tsutsui */ 923 1.117 tsutsui KASSERT(nsegs < FXP_IPCB_NTXSEG); 924 1.117 tsutsui nsegs++; 925 1.117 tsutsui tbdp[seg].tb_addr = htole32(FXP_CDTXPADADDR(sc)); 926 1.119 tsutsui tbdp[seg].tb_size = 927 1.119 tsutsui htole32(FXP_IP4CSUMTX_PADLEN + 1 - len); 928 1.117 tsutsui } 929 1.1 thorpej 930 1.2 thorpej /* Sync the DMA map. */ 931 1.1 thorpej bus_dmamap_sync(sc->sc_dmat, dmamap, 0, dmamap->dm_mapsize, 932 1.1 thorpej BUS_DMASYNC_PREWRITE); 933 1.1 thorpej 934 1.1 thorpej /* 935 1.2 thorpej * Store a pointer to the packet so we can free it later. 936 1.1 thorpej */ 937 1.2 thorpej txs->txs_mbuf = m0; 938 1.1 thorpej 939 1.1 thorpej /* 940 1.2 thorpej * Initialize the transmit descriptor. 941 1.1 thorpej */ 942 1.15 thorpej /* BIG_ENDIAN: no need to swap to store 0 */ 943 1.50 thorpej txd->txd_txcb.cb_status = 0; 944 1.50 thorpej txd->txd_txcb.cb_command = 945 1.75 yamt sc->sc_txcmd | htole16(FXP_CB_COMMAND_SF); 946 1.50 thorpej txd->txd_txcb.tx_threshold = tx_threshold; 947 1.117 tsutsui txd->txd_txcb.tbd_number = nsegs; 948 1.1 thorpej 949 1.75 yamt KASSERT((csum_flags & (M_CSUM_TCPv6 | M_CSUM_UDPv6)) == 0); 950 1.124 tsutsui if (sc->sc_flags & FXPF_EXT_RFA) { 951 1.75 yamt struct fxp_ipcb *ipcb; 952 1.75 yamt /* 953 1.75 yamt * Deal with TCP/IP checksum offload. Note that 954 1.75 yamt * in order for TCP checksum offload to work, 955 1.75 yamt * the pseudo header checksum must have already 956 1.75 yamt * been computed and stored in the checksum field 957 1.75 yamt * in the TCP header. The stack should have 958 1.75 yamt * already done this for us. 959 1.75 yamt */ 960 1.75 yamt ipcb = &txd->txd_u.txdu_ipcb; 961 1.75 yamt memset(ipcb, 0, sizeof(*ipcb)); 962 1.75 yamt /* 963 1.75 yamt * always do hardware parsing. 964 1.75 yamt */ 965 1.75 yamt ipcb->ipcb_ip_activation_high = 966 1.75 yamt FXP_IPCB_HARDWAREPARSING_ENABLE; 967 1.75 yamt /* 968 1.75 yamt * ip checksum offloading. 969 1.75 yamt */ 970 1.75 yamt if (csum_flags & M_CSUM_IPv4) { 971 1.75 yamt ipcb->ipcb_ip_schedule |= 972 1.75 yamt FXP_IPCB_IP_CHECKSUM_ENABLE; 973 1.75 yamt } 974 1.75 yamt /* 975 1.75 yamt * TCP/UDP checksum offloading. 976 1.75 yamt */ 977 1.75 yamt if (csum_flags & (M_CSUM_TCPv4 | M_CSUM_UDPv4)) { 978 1.75 yamt ipcb->ipcb_ip_schedule |= 979 1.75 yamt FXP_IPCB_TCPUDP_CHECKSUM_ENABLE; 980 1.75 yamt } 981 1.81 yamt 982 1.81 yamt /* 983 1.81 yamt * request VLAN tag insertion if needed. 984 1.81 yamt */ 985 1.148 knakahar if (vlan_has_tag(m0)) { 986 1.148 knakahar ipcb->ipcb_vlan_id = htobe16(vlan_get_tag(m0)); 987 1.94 jdolecek ipcb->ipcb_ip_activation_high |= 988 1.94 jdolecek FXP_IPCB_INSERTVLAN_ENABLE; 989 1.81 yamt } 990 1.75 yamt } else { 991 1.75 yamt KASSERT((csum_flags & 992 1.75 yamt (M_CSUM_IPv4 | M_CSUM_TCPv4 | M_CSUM_UDPv4)) == 0); 993 1.75 yamt } 994 1.75 yamt 995 1.2 thorpej FXP_CDTXSYNC(sc, nexttx, 996 1.152 msaitoh BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 997 1.2 thorpej 998 1.2 thorpej /* Advance the tx pointer. */ 999 1.2 thorpej sc->sc_txpending++; 1000 1.2 thorpej sc->sc_txlast = nexttx; 1001 1.1 thorpej 1002 1.1 thorpej /* 1003 1.1 thorpej * Pass packet to bpf if there is a listener. 1004 1.1 thorpej */ 1005 1.149 msaitoh bpf_mtap(ifp, m0, BPF_D_OUT); 1006 1.1 thorpej } 1007 1.1 thorpej 1008 1.105 tsutsui if (sc->sc_txpending == FXP_NTXCB - 1) { 1009 1.2 thorpej /* No more slots; notify upper layer. */ 1010 1.2 thorpej ifp->if_flags |= IFF_OACTIVE; 1011 1.2 thorpej } 1012 1.2 thorpej 1013 1.2 thorpej if (sc->sc_txpending != opending) { 1014 1.2 thorpej /* 1015 1.2 thorpej * We enqueued packets. If the transmitter was idle, 1016 1.2 thorpej * reset the txdirty pointer. 1017 1.2 thorpej */ 1018 1.2 thorpej if (opending == 0) 1019 1.2 thorpej sc->sc_txdirty = FXP_NEXTTX(lasttx); 1020 1.2 thorpej 1021 1.2 thorpej /* 1022 1.2 thorpej * Cause the chip to interrupt and suspend command 1023 1.2 thorpej * processing once the last packet we've enqueued 1024 1.2 thorpej * has been transmitted. 1025 1.105 tsutsui * 1026 1.105 tsutsui * To avoid a race between updating status bits 1027 1.105 tsutsui * by the fxp chip and clearing command bits 1028 1.105 tsutsui * by this function on machines which don't have 1029 1.105 tsutsui * atomic methods to clear/set bits in memory 1030 1.105 tsutsui * smaller than 32bits (both cb_status and cb_command 1031 1.105 tsutsui * members are uint16_t and in the same 32bit word), 1032 1.105 tsutsui * we have to prepare a dummy TX descriptor which has 1033 1.105 tsutsui * NOP command and just causes a TX completion interrupt. 1034 1.2 thorpej */ 1035 1.105 tsutsui sc->sc_txpending++; 1036 1.105 tsutsui sc->sc_txlast = FXP_NEXTTX(sc->sc_txlast); 1037 1.105 tsutsui txd = FXP_CDTX(sc, sc->sc_txlast); 1038 1.105 tsutsui /* BIG_ENDIAN: no need to swap to store 0 */ 1039 1.105 tsutsui txd->txd_txcb.cb_status = 0; 1040 1.105 tsutsui txd->txd_txcb.cb_command = htole16(FXP_CB_COMMAND_NOP | 1041 1.105 tsutsui FXP_CB_COMMAND_I | FXP_CB_COMMAND_S); 1042 1.2 thorpej FXP_CDTXSYNC(sc, sc->sc_txlast, 1043 1.152 msaitoh BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1044 1.2 thorpej 1045 1.2 thorpej /* 1046 1.2 thorpej * The entire packet chain is set up. Clear the suspend bit 1047 1.2 thorpej * on the command prior to the first packet we set up. 1048 1.2 thorpej */ 1049 1.2 thorpej FXP_CDTXSYNC(sc, lasttx, 1050 1.152 msaitoh BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1051 1.50 thorpej FXP_CDTX(sc, lasttx)->txd_txcb.cb_command &= 1052 1.50 thorpej htole16(~FXP_CB_COMMAND_S); 1053 1.2 thorpej FXP_CDTXSYNC(sc, lasttx, 1054 1.152 msaitoh BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1055 1.2 thorpej 1056 1.2 thorpej /* 1057 1.2 thorpej * Issue a Resume command in case the chip was suspended. 1058 1.2 thorpej */ 1059 1.83 briggs fxp_scb_wait(sc); 1060 1.83 briggs fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_RESUME); 1061 1.1 thorpej 1062 1.2 thorpej /* Set a watchdog timer in case the chip flakes out. */ 1063 1.1 thorpej ifp->if_timer = 5; 1064 1.1 thorpej } 1065 1.1 thorpej } 1066 1.1 thorpej 1067 1.1 thorpej /* 1068 1.1 thorpej * Process interface interrupts. 1069 1.1 thorpej */ 1070 1.1 thorpej int 1071 1.46 thorpej fxp_intr(void *arg) 1072 1.1 thorpej { 1073 1.1 thorpej struct fxp_softc *sc = arg; 1074 1.2 thorpej struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1075 1.7 thorpej bus_dmamap_t rxmap; 1076 1.105 tsutsui int claimed = 0, rnr; 1077 1.160 tsutsui uint8_t statack, rndstat = 0; 1078 1.1 thorpej 1079 1.114 joerg if (!device_is_active(sc->sc_dev) || sc->sc_enabled == 0) 1080 1.20 enami return (0); 1081 1.9 sommerfe /* 1082 1.9 sommerfe * If the interface isn't running, don't try to 1083 1.9 sommerfe * service the interrupt.. just ack it and bail. 1084 1.9 sommerfe */ 1085 1.9 sommerfe if ((ifp->if_flags & IFF_RUNNING) == 0) { 1086 1.9 sommerfe statack = CSR_READ_1(sc, FXP_CSR_SCB_STATACK); 1087 1.9 sommerfe if (statack) { 1088 1.9 sommerfe claimed = 1; 1089 1.9 sommerfe CSR_WRITE_1(sc, FXP_CSR_SCB_STATACK, statack); 1090 1.9 sommerfe } 1091 1.20 enami return (claimed); 1092 1.9 sommerfe } 1093 1.9 sommerfe 1094 1.1 thorpej while ((statack = CSR_READ_1(sc, FXP_CSR_SCB_STATACK)) != 0) { 1095 1.160 tsutsui rndstat = statack; 1096 1.1 thorpej claimed = 1; 1097 1.1 thorpej 1098 1.1 thorpej /* 1099 1.1 thorpej * First ACK all the interrupts in this pass. 1100 1.1 thorpej */ 1101 1.1 thorpej CSR_WRITE_1(sc, FXP_CSR_SCB_STATACK, statack); 1102 1.1 thorpej 1103 1.1 thorpej /* 1104 1.1 thorpej * Process receiver interrupts. If a no-resource (RNR) 1105 1.1 thorpej * condition exists, get whatever packets we can and 1106 1.1 thorpej * re-start the receiver. 1107 1.1 thorpej */ 1108 1.105 tsutsui rnr = (statack & (FXP_SCB_STATACK_RNR | FXP_SCB_STATACK_SWI)) ? 1109 1.105 tsutsui 1 : 0; 1110 1.105 tsutsui if (statack & (FXP_SCB_STATACK_FR | FXP_SCB_STATACK_RNR | 1111 1.105 tsutsui FXP_SCB_STATACK_SWI)) { 1112 1.55 thorpej FXP_EVCNT_INCR(&sc->sc_ev_rxintr); 1113 1.105 tsutsui rnr |= fxp_rxintr(sc); 1114 1.1 thorpej } 1115 1.7 thorpej 1116 1.1 thorpej /* 1117 1.1 thorpej * Free any finished transmit mbuf chains. 1118 1.1 thorpej */ 1119 1.152 msaitoh if (statack & (FXP_SCB_STATACK_CXTNO | FXP_SCB_STATACK_CNA)) { 1120 1.55 thorpej FXP_EVCNT_INCR(&sc->sc_ev_txintr); 1121 1.55 thorpej fxp_txintr(sc); 1122 1.2 thorpej 1123 1.2 thorpej /* 1124 1.55 thorpej * Try to get more packets going. 1125 1.2 thorpej */ 1126 1.147 ozaki if_schedule_deferred_start(ifp); 1127 1.55 thorpej 1128 1.2 thorpej if (sc->sc_txpending == 0) { 1129 1.2 thorpej /* 1130 1.115 ws * Tell them that they can re-init now. 1131 1.2 thorpej */ 1132 1.8 thorpej if (sc->sc_flags & FXPF_WANTINIT) 1133 1.115 ws wakeup(sc); 1134 1.1 thorpej } 1135 1.1 thorpej } 1136 1.105 tsutsui 1137 1.105 tsutsui if (rnr) { 1138 1.105 tsutsui fxp_scb_wait(sc); 1139 1.105 tsutsui fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_ABORT); 1140 1.105 tsutsui rxmap = M_GETCTX(sc->sc_rxq.ifq_head, bus_dmamap_t); 1141 1.105 tsutsui fxp_scb_wait(sc); 1142 1.105 tsutsui CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, 1143 1.105 tsutsui rxmap->dm_segs[0].ds_addr + 1144 1.105 tsutsui RFA_ALIGNMENT_FUDGE); 1145 1.105 tsutsui fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_START); 1146 1.105 tsutsui } 1147 1.1 thorpej } 1148 1.1 thorpej 1149 1.1 thorpej if (claimed) 1150 1.160 tsutsui rnd_add_uint32(&sc->rnd_source, rndstat); 1151 1.1 thorpej return (claimed); 1152 1.55 thorpej } 1153 1.55 thorpej 1154 1.55 thorpej /* 1155 1.55 thorpej * Handle transmit completion interrupts. 1156 1.55 thorpej */ 1157 1.55 thorpej void 1158 1.55 thorpej fxp_txintr(struct fxp_softc *sc) 1159 1.55 thorpej { 1160 1.55 thorpej struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1161 1.55 thorpej struct fxp_txdesc *txd; 1162 1.55 thorpej struct fxp_txsoft *txs; 1163 1.55 thorpej int i; 1164 1.127 tsutsui uint16_t txstat; 1165 1.55 thorpej 1166 1.55 thorpej ifp->if_flags &= ~IFF_OACTIVE; 1167 1.55 thorpej for (i = sc->sc_txdirty; sc->sc_txpending != 0; 1168 1.69 enami i = FXP_NEXTTX(i), sc->sc_txpending--) { 1169 1.55 thorpej txd = FXP_CDTX(sc, i); 1170 1.55 thorpej txs = FXP_DSTX(sc, i); 1171 1.55 thorpej 1172 1.55 thorpej FXP_CDTXSYNC(sc, i, 1173 1.152 msaitoh BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1174 1.55 thorpej 1175 1.105 tsutsui /* skip dummy NOP TX descriptor */ 1176 1.105 tsutsui if ((le16toh(txd->txd_txcb.cb_command) & FXP_CB_COMMAND_CMD) 1177 1.105 tsutsui == FXP_CB_COMMAND_NOP) 1178 1.105 tsutsui continue; 1179 1.105 tsutsui 1180 1.55 thorpej txstat = le16toh(txd->txd_txcb.cb_status); 1181 1.55 thorpej 1182 1.55 thorpej if ((txstat & FXP_CB_STATUS_C) == 0) 1183 1.55 thorpej break; 1184 1.55 thorpej 1185 1.55 thorpej bus_dmamap_sync(sc->sc_dmat, txs->txs_dmamap, 1186 1.55 thorpej 0, txs->txs_dmamap->dm_mapsize, 1187 1.55 thorpej BUS_DMASYNC_POSTWRITE); 1188 1.55 thorpej bus_dmamap_unload(sc->sc_dmat, txs->txs_dmamap); 1189 1.55 thorpej m_freem(txs->txs_mbuf); 1190 1.55 thorpej txs->txs_mbuf = NULL; 1191 1.55 thorpej } 1192 1.55 thorpej 1193 1.55 thorpej /* Update the dirty transmit buffer pointer. */ 1194 1.55 thorpej sc->sc_txdirty = i; 1195 1.55 thorpej 1196 1.55 thorpej /* 1197 1.55 thorpej * Cancel the watchdog timer if there are no pending 1198 1.55 thorpej * transmissions. 1199 1.55 thorpej */ 1200 1.55 thorpej if (sc->sc_txpending == 0) 1201 1.55 thorpej ifp->if_timer = 0; 1202 1.55 thorpej } 1203 1.55 thorpej 1204 1.80 yamt /* 1205 1.80 yamt * fxp_rx_hwcksum: check status of H/W offloading for received packets. 1206 1.80 yamt */ 1207 1.80 yamt 1208 1.125 tsutsui void 1209 1.125 tsutsui fxp_rx_hwcksum(struct fxp_softc *sc, struct mbuf *m, const struct fxp_rfa *rfa, 1210 1.125 tsutsui u_int len) 1211 1.75 yamt { 1212 1.125 tsutsui uint32_t csum_data; 1213 1.75 yamt int csum_flags; 1214 1.75 yamt 1215 1.80 yamt /* 1216 1.125 tsutsui * check H/W Checksumming. 1217 1.80 yamt */ 1218 1.80 yamt 1219 1.125 tsutsui csum_flags = 0; 1220 1.125 tsutsui csum_data = 0; 1221 1.125 tsutsui 1222 1.125 tsutsui if ((sc->sc_flags & FXPF_EXT_RFA) != 0) { 1223 1.125 tsutsui uint8_t csum_stat; 1224 1.125 tsutsui 1225 1.125 tsutsui csum_stat = rfa->cksum_stat; 1226 1.125 tsutsui if ((rfa->rfa_status & htole16(FXP_RFA_STATUS_PARSE)) == 0) 1227 1.125 tsutsui goto out; 1228 1.125 tsutsui 1229 1.125 tsutsui if (csum_stat & FXP_RFDX_CS_IP_CSUM_BIT_VALID) { 1230 1.125 tsutsui csum_flags = M_CSUM_IPv4; 1231 1.125 tsutsui if ((csum_stat & FXP_RFDX_CS_IP_CSUM_VALID) == 0) 1232 1.125 tsutsui csum_flags |= M_CSUM_IPv4_BAD; 1233 1.125 tsutsui } 1234 1.125 tsutsui 1235 1.125 tsutsui if (csum_stat & FXP_RFDX_CS_TCPUDP_CSUM_BIT_VALID) { 1236 1.152 msaitoh csum_flags |= (M_CSUM_TCPv4 | M_CSUM_UDPv4); /* XXX */ 1237 1.125 tsutsui if ((csum_stat & FXP_RFDX_CS_TCPUDP_CSUM_VALID) == 0) 1238 1.125 tsutsui csum_flags |= M_CSUM_TCP_UDP_BAD; 1239 1.125 tsutsui } 1240 1.125 tsutsui 1241 1.125 tsutsui } else if ((sc->sc_flags & FXPF_82559_RXCSUM) != 0) { 1242 1.125 tsutsui struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1243 1.125 tsutsui struct ether_header *eh; 1244 1.125 tsutsui struct ip *ip; 1245 1.125 tsutsui struct udphdr *uh; 1246 1.125 tsutsui u_int hlen, pktlen; 1247 1.80 yamt 1248 1.125 tsutsui if (len < ETHER_HDR_LEN + sizeof(struct ip)) 1249 1.125 tsutsui goto out; 1250 1.125 tsutsui pktlen = len - ETHER_HDR_LEN; 1251 1.125 tsutsui eh = mtod(m, struct ether_header *); 1252 1.125 tsutsui if (ntohs(eh->ether_type) != ETHERTYPE_IP) 1253 1.125 tsutsui goto out; 1254 1.125 tsutsui ip = (struct ip *)((uint8_t *)eh + ETHER_HDR_LEN); 1255 1.125 tsutsui if (ip->ip_v != IPVERSION) 1256 1.125 tsutsui goto out; 1257 1.125 tsutsui 1258 1.125 tsutsui hlen = ip->ip_hl << 2; 1259 1.125 tsutsui if (hlen < sizeof(struct ip)) 1260 1.125 tsutsui goto out; 1261 1.125 tsutsui 1262 1.125 tsutsui /* 1263 1.125 tsutsui * Bail if too short, has random trailing garbage, truncated, 1264 1.125 tsutsui * fragment, or has ethernet pad. 1265 1.125 tsutsui */ 1266 1.125 tsutsui if (ntohs(ip->ip_len) < hlen || 1267 1.125 tsutsui ntohs(ip->ip_len) != pktlen || 1268 1.125 tsutsui (ntohs(ip->ip_off) & (IP_MF | IP_OFFMASK)) != 0) 1269 1.125 tsutsui goto out; 1270 1.80 yamt 1271 1.125 tsutsui switch (ip->ip_p) { 1272 1.125 tsutsui case IPPROTO_TCP: 1273 1.125 tsutsui if ((ifp->if_csum_flags_rx & M_CSUM_TCPv4) == 0 || 1274 1.125 tsutsui pktlen < (hlen + sizeof(struct tcphdr))) 1275 1.125 tsutsui goto out; 1276 1.125 tsutsui csum_flags = 1277 1.125 tsutsui M_CSUM_TCPv4 | M_CSUM_DATA | M_CSUM_NO_PSEUDOHDR; 1278 1.125 tsutsui break; 1279 1.125 tsutsui case IPPROTO_UDP: 1280 1.125 tsutsui if ((ifp->if_csum_flags_rx & M_CSUM_UDPv4) == 0 || 1281 1.125 tsutsui pktlen < (hlen + sizeof(struct udphdr))) 1282 1.125 tsutsui goto out; 1283 1.125 tsutsui uh = (struct udphdr *)((uint8_t *)ip + hlen); 1284 1.125 tsutsui if (uh->uh_sum == 0) 1285 1.125 tsutsui goto out; /* no checksum */ 1286 1.125 tsutsui csum_flags = 1287 1.125 tsutsui M_CSUM_UDPv4 | M_CSUM_DATA | M_CSUM_NO_PSEUDOHDR; 1288 1.125 tsutsui break; 1289 1.125 tsutsui default: 1290 1.125 tsutsui goto out; 1291 1.125 tsutsui } 1292 1.80 yamt 1293 1.125 tsutsui /* Extract computed checksum. */ 1294 1.125 tsutsui csum_data = be16dec(mtod(m, uint8_t *) + len); 1295 1.75 yamt 1296 1.126 tsutsui /* 1297 1.126 tsutsui * The computed checksum includes IP headers, 1298 1.126 tsutsui * so we have to deduct them. 1299 1.126 tsutsui */ 1300 1.126 tsutsui #if 0 1301 1.126 tsutsui /* 1302 1.126 tsutsui * But in TCP/UDP layer we can assume the IP header is valid, 1303 1.126 tsutsui * i.e. a sum of the whole IP header should be 0xffff, 1304 1.126 tsutsui * so we don't have to bother to deduct it. 1305 1.126 tsutsui */ 1306 1.126 tsutsui if (hlen > 0) { 1307 1.126 tsutsui uint32_t hsum; 1308 1.126 tsutsui const uint16_t *iphdr; 1309 1.126 tsutsui hsum = 0; 1310 1.126 tsutsui iphdr = (uint16_t *)ip; 1311 1.126 tsutsui 1312 1.126 tsutsui while (hlen > 1) { 1313 1.126 tsutsui hsum += ntohs(*iphdr++); 1314 1.126 tsutsui hlen -= sizeof(uint16_t); 1315 1.125 tsutsui } 1316 1.126 tsutsui while (hsum >> 16) 1317 1.126 tsutsui hsum = (hsum >> 16) + (hsum & 0xffff); 1318 1.75 yamt 1319 1.129 tsutsui csum_data += (uint16_t)~hsum; 1320 1.75 yamt 1321 1.125 tsutsui while (csum_data >> 16) 1322 1.125 tsutsui csum_data = 1323 1.125 tsutsui (csum_data >> 16) + (csum_data & 0xffff); 1324 1.125 tsutsui } 1325 1.126 tsutsui #endif 1326 1.75 yamt } 1327 1.125 tsutsui out: 1328 1.75 yamt m->m_pkthdr.csum_flags = csum_flags; 1329 1.75 yamt m->m_pkthdr.csum_data = csum_data; 1330 1.75 yamt } 1331 1.75 yamt 1332 1.55 thorpej /* 1333 1.55 thorpej * Handle receive interrupts. 1334 1.55 thorpej */ 1335 1.105 tsutsui int 1336 1.55 thorpej fxp_rxintr(struct fxp_softc *sc) 1337 1.55 thorpej { 1338 1.55 thorpej struct ethercom *ec = &sc->sc_ethercom; 1339 1.55 thorpej struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1340 1.55 thorpej struct mbuf *m, *m0; 1341 1.55 thorpej bus_dmamap_t rxmap; 1342 1.55 thorpej struct fxp_rfa *rfa; 1343 1.105 tsutsui int rnr; 1344 1.127 tsutsui uint16_t len, rxstat; 1345 1.55 thorpej 1346 1.105 tsutsui rnr = 0; 1347 1.105 tsutsui 1348 1.55 thorpej for (;;) { 1349 1.55 thorpej m = sc->sc_rxq.ifq_head; 1350 1.55 thorpej rfa = FXP_MTORFA(m); 1351 1.55 thorpej rxmap = M_GETCTX(m, bus_dmamap_t); 1352 1.55 thorpej 1353 1.55 thorpej FXP_RFASYNC(sc, m, 1354 1.152 msaitoh BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1355 1.55 thorpej 1356 1.55 thorpej rxstat = le16toh(rfa->rfa_status); 1357 1.55 thorpej 1358 1.105 tsutsui if ((rxstat & FXP_RFA_STATUS_RNR) != 0) 1359 1.105 tsutsui rnr = 1; 1360 1.105 tsutsui 1361 1.55 thorpej if ((rxstat & FXP_RFA_STATUS_C) == 0) { 1362 1.55 thorpej /* 1363 1.55 thorpej * We have processed all of the 1364 1.55 thorpej * receive buffers. 1365 1.55 thorpej */ 1366 1.55 thorpej FXP_RFASYNC(sc, m, BUS_DMASYNC_PREREAD); 1367 1.105 tsutsui return rnr; 1368 1.55 thorpej } 1369 1.55 thorpej 1370 1.55 thorpej IF_DEQUEUE(&sc->sc_rxq, m); 1371 1.55 thorpej 1372 1.55 thorpej FXP_RXBUFSYNC(sc, m, BUS_DMASYNC_POSTREAD); 1373 1.55 thorpej 1374 1.55 thorpej len = le16toh(rfa->actual_size) & 1375 1.55 thorpej (m->m_ext.ext_size - 1); 1376 1.125 tsutsui if ((sc->sc_flags & FXPF_82559_RXCSUM) != 0) { 1377 1.125 tsutsui /* Adjust for appended checksum bytes. */ 1378 1.125 tsutsui len -= sizeof(uint16_t); 1379 1.125 tsutsui } 1380 1.55 thorpej 1381 1.55 thorpej if (len < sizeof(struct ether_header)) { 1382 1.55 thorpej /* 1383 1.55 thorpej * Runt packet; drop it now. 1384 1.55 thorpej */ 1385 1.55 thorpej FXP_INIT_RFABUF(sc, m); 1386 1.55 thorpej continue; 1387 1.55 thorpej } 1388 1.55 thorpej 1389 1.55 thorpej /* 1390 1.55 thorpej * If support for 802.1Q VLAN sized frames is 1391 1.55 thorpej * enabled, we need to do some additional error 1392 1.55 thorpej * checking (as we are saving bad frames, in 1393 1.55 thorpej * order to receive the larger ones). 1394 1.55 thorpej */ 1395 1.55 thorpej if ((ec->ec_capenable & ETHERCAP_VLAN_MTU) != 0 && 1396 1.152 msaitoh (rxstat & (FXP_RFA_STATUS_OVERRUN | 1397 1.152 msaitoh FXP_RFA_STATUS_RNR | 1398 1.152 msaitoh FXP_RFA_STATUS_ALIGN | 1399 1.55 thorpej FXP_RFA_STATUS_CRC)) != 0) { 1400 1.55 thorpej FXP_INIT_RFABUF(sc, m); 1401 1.55 thorpej continue; 1402 1.55 thorpej } 1403 1.55 thorpej 1404 1.125 tsutsui /* 1405 1.125 tsutsui * check VLAN tag stripping. 1406 1.125 tsutsui */ 1407 1.125 tsutsui if ((sc->sc_flags & FXPF_EXT_RFA) != 0 && 1408 1.148 knakahar (rfa->rfa_status & htole16(FXP_RFA_STATUS_VLAN)) != 0) 1409 1.148 knakahar vlan_set_tag(m, be16toh(rfa->vlan_id)); 1410 1.125 tsutsui 1411 1.75 yamt /* Do checksum checking. */ 1412 1.152 msaitoh if ((ifp->if_csum_flags_rx & 1413 1.152 msaitoh (M_CSUM_TCPv4 | M_CSUM_UDPv4)) != 0) 1414 1.125 tsutsui fxp_rx_hwcksum(sc, m, rfa, len); 1415 1.75 yamt 1416 1.55 thorpej /* 1417 1.55 thorpej * If the packet is small enough to fit in a 1418 1.55 thorpej * single header mbuf, allocate one and copy 1419 1.55 thorpej * the data into it. This greatly reduces 1420 1.55 thorpej * memory consumption when we receive lots 1421 1.55 thorpej * of small packets. 1422 1.55 thorpej * 1423 1.55 thorpej * Otherwise, we add a new buffer to the receive 1424 1.55 thorpej * chain. If this fails, we drop the packet and 1425 1.55 thorpej * recycle the old buffer. 1426 1.55 thorpej */ 1427 1.55 thorpej if (fxp_copy_small != 0 && len <= MHLEN) { 1428 1.55 thorpej MGETHDR(m0, M_DONTWAIT, MT_DATA); 1429 1.74 yamt if (m0 == NULL) 1430 1.55 thorpej goto dropit; 1431 1.74 yamt MCLAIM(m0, &sc->sc_ethercom.ec_rx_mowner); 1432 1.101 christos memcpy(mtod(m0, void *), 1433 1.101 christos mtod(m, void *), len); 1434 1.75 yamt m0->m_pkthdr.csum_flags = m->m_pkthdr.csum_flags; 1435 1.75 yamt m0->m_pkthdr.csum_data = m->m_pkthdr.csum_data; 1436 1.55 thorpej FXP_INIT_RFABUF(sc, m); 1437 1.55 thorpej m = m0; 1438 1.55 thorpej } else { 1439 1.55 thorpej if (fxp_add_rfabuf(sc, rxmap, 1) != 0) { 1440 1.55 thorpej dropit: 1441 1.157 thorpej if_statinc(ifp, if_ierrors); 1442 1.55 thorpej FXP_INIT_RFABUF(sc, m); 1443 1.55 thorpej continue; 1444 1.55 thorpej } 1445 1.55 thorpej } 1446 1.55 thorpej 1447 1.145 ozaki m_set_rcvif(m, ifp); 1448 1.55 thorpej m->m_pkthdr.len = m->m_len = len; 1449 1.55 thorpej 1450 1.55 thorpej /* Pass it on. */ 1451 1.144 ozaki if_percpuq_enqueue(ifp->if_percpuq, m); 1452 1.55 thorpej } 1453 1.1 thorpej } 1454 1.1 thorpej 1455 1.1 thorpej /* 1456 1.1 thorpej * Update packet in/out/collision statistics. The i82557 doesn't 1457 1.1 thorpej * allow you to access these counters without doing a fairly 1458 1.1 thorpej * expensive DMA to get _all_ of the statistics it maintains, so 1459 1.1 thorpej * we do this operation here only once per second. The statistics 1460 1.1 thorpej * counters in the kernel are updated from the previous dump-stats 1461 1.1 thorpej * DMA and then a new dump-stats DMA is started. The on-chip 1462 1.1 thorpej * counters are zeroed when the DMA completes. If we can't start 1463 1.1 thorpej * the DMA immediately, we don't wait - we just prepare to read 1464 1.1 thorpej * them again next time. 1465 1.1 thorpej */ 1466 1.1 thorpej void 1467 1.46 thorpej fxp_tick(void *arg) 1468 1.1 thorpej { 1469 1.1 thorpej struct fxp_softc *sc = arg; 1470 1.2 thorpej struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1471 1.2 thorpej struct fxp_stats *sp = &sc->sc_control_data->fcd_stats; 1472 1.8 thorpej int s; 1473 1.2 thorpej 1474 1.114 joerg if (!device_is_active(sc->sc_dev)) 1475 1.20 enami return; 1476 1.20 enami 1477 1.2 thorpej s = splnet(); 1478 1.2 thorpej 1479 1.157 thorpej net_stat_ref_t nsr = IF_STAT_GETREF(ifp); 1480 1.157 thorpej 1481 1.32 tsutsui FXP_CDSTATSSYNC(sc, BUS_DMASYNC_POSTREAD); 1482 1.32 tsutsui 1483 1.162 riastrad if_statadd_ref(ifp, nsr, if_opackets, le32toh(sp->tx_good)); 1484 1.162 riastrad if_statadd_ref(ifp, nsr, if_collisions, 1485 1.162 riastrad le32toh(sp->tx_total_collisions)); 1486 1.1 thorpej if (sp->rx_good) { 1487 1.7 thorpej sc->sc_rxidle = 0; 1488 1.85 thorpej } else if (sc->sc_flags & FXPF_RECV_WORKAROUND) { 1489 1.7 thorpej sc->sc_rxidle++; 1490 1.1 thorpej } 1491 1.162 riastrad if_statadd_ref(ifp, nsr, if_ierrors, 1492 1.15 thorpej le32toh(sp->rx_crc_errors) + 1493 1.15 thorpej le32toh(sp->rx_alignment_errors) + 1494 1.15 thorpej le32toh(sp->rx_rnr_errors) + 1495 1.157 thorpej le32toh(sp->rx_overrun_errors)); 1496 1.1 thorpej /* 1497 1.60 wiz * If any transmit underruns occurred, bump up the transmit 1498 1.1 thorpej * threshold by another 512 bytes (64 * 8). 1499 1.1 thorpej */ 1500 1.1 thorpej if (sp->tx_underruns) { 1501 1.162 riastrad if_statadd_ref(ifp, nsr, if_oerrors, 1502 1.162 riastrad le32toh(sp->tx_underruns)); 1503 1.1 thorpej if (tx_threshold < 192) 1504 1.1 thorpej tx_threshold += 64; 1505 1.1 thorpej } 1506 1.86 thorpej #ifdef FXP_EVENT_COUNTERS 1507 1.122 mrg if (sc->sc_flags & FXPF_FC) { 1508 1.86 thorpej sc->sc_ev_txpause.ev_count += sp->tx_pauseframes; 1509 1.86 thorpej sc->sc_ev_rxpause.ev_count += sp->rx_pauseframes; 1510 1.86 thorpej } 1511 1.86 thorpej #endif 1512 1.1 thorpej 1513 1.157 thorpej IF_STAT_PUTREF(ifp); 1514 1.157 thorpej 1515 1.1 thorpej /* 1516 1.87 simonb * If we haven't received any packets in FXP_MAX_RX_IDLE seconds, 1517 1.1 thorpej * then assume the receiver has locked up and attempt to clear 1518 1.8 thorpej * the condition by reprogramming the multicast filter (actually, 1519 1.8 thorpej * resetting the interface). This is a work-around for a bug in 1520 1.8 thorpej * the 82557 where the receiver locks up if it gets certain types 1521 1.70 wiz * of garbage in the synchronization bits prior to the packet header. 1522 1.8 thorpej * This bug is supposed to only occur in 10Mbps mode, but has been 1523 1.8 thorpej * seen to occur in 100Mbps mode as well (perhaps due to a 10/100 1524 1.8 thorpej * speed transition). 1525 1.1 thorpej */ 1526 1.7 thorpej if (sc->sc_rxidle > FXP_MAX_RX_IDLE) { 1527 1.40 thorpej (void) fxp_init(ifp); 1528 1.8 thorpej splx(s); 1529 1.8 thorpej return; 1530 1.1 thorpej } 1531 1.1 thorpej /* 1532 1.1 thorpej * If there is no pending command, start another stats 1533 1.1 thorpej * dump. Otherwise punt for now. 1534 1.1 thorpej */ 1535 1.1 thorpej if (CSR_READ_1(sc, FXP_CSR_SCB_COMMAND) == 0) { 1536 1.1 thorpej /* 1537 1.1 thorpej * Start another stats dump. 1538 1.1 thorpej */ 1539 1.32 tsutsui FXP_CDSTATSSYNC(sc, BUS_DMASYNC_PREREAD); 1540 1.47 thorpej fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_DUMPRESET); 1541 1.1 thorpej } else { 1542 1.1 thorpej /* 1543 1.1 thorpej * A previous command is still waiting to be accepted. 1544 1.1 thorpej * Just zero our copy of the stats and wait for the 1545 1.1 thorpej * next timer event to update them. 1546 1.1 thorpej */ 1547 1.15 thorpej /* BIG_ENDIAN: no swap required to store 0 */ 1548 1.1 thorpej sp->tx_good = 0; 1549 1.1 thorpej sp->tx_underruns = 0; 1550 1.1 thorpej sp->tx_total_collisions = 0; 1551 1.1 thorpej 1552 1.1 thorpej sp->rx_good = 0; 1553 1.1 thorpej sp->rx_crc_errors = 0; 1554 1.1 thorpej sp->rx_alignment_errors = 0; 1555 1.1 thorpej sp->rx_rnr_errors = 0; 1556 1.1 thorpej sp->rx_overrun_errors = 0; 1557 1.122 mrg if (sc->sc_flags & FXPF_FC) { 1558 1.86 thorpej sp->tx_pauseframes = 0; 1559 1.86 thorpej sp->rx_pauseframes = 0; 1560 1.86 thorpej } 1561 1.1 thorpej } 1562 1.1 thorpej 1563 1.6 thorpej if (sc->sc_flags & FXPF_MII) { 1564 1.6 thorpej /* Tick the MII clock. */ 1565 1.6 thorpej mii_tick(&sc->sc_mii); 1566 1.6 thorpej } 1567 1.2 thorpej 1568 1.1 thorpej splx(s); 1569 1.1 thorpej 1570 1.1 thorpej /* 1571 1.1 thorpej * Schedule another timeout one second from now. 1572 1.1 thorpej */ 1573 1.159 thorpej callout_schedule(&sc->sc_callout, hz); 1574 1.1 thorpej } 1575 1.1 thorpej 1576 1.1 thorpej /* 1577 1.7 thorpej * Drain the receive queue. 1578 1.7 thorpej */ 1579 1.7 thorpej void 1580 1.46 thorpej fxp_rxdrain(struct fxp_softc *sc) 1581 1.7 thorpej { 1582 1.7 thorpej bus_dmamap_t rxmap; 1583 1.7 thorpej struct mbuf *m; 1584 1.7 thorpej 1585 1.7 thorpej for (;;) { 1586 1.7 thorpej IF_DEQUEUE(&sc->sc_rxq, m); 1587 1.7 thorpej if (m == NULL) 1588 1.7 thorpej break; 1589 1.7 thorpej rxmap = M_GETCTX(m, bus_dmamap_t); 1590 1.7 thorpej bus_dmamap_unload(sc->sc_dmat, rxmap); 1591 1.7 thorpej FXP_RXMAP_PUT(sc, rxmap); 1592 1.7 thorpej m_freem(m); 1593 1.7 thorpej } 1594 1.7 thorpej } 1595 1.7 thorpej 1596 1.7 thorpej /* 1597 1.1 thorpej * Stop the interface. Cancels the statistics updater and resets 1598 1.1 thorpej * the interface. 1599 1.1 thorpej */ 1600 1.1 thorpej void 1601 1.46 thorpej fxp_stop(struct ifnet *ifp, int disable) 1602 1.1 thorpej { 1603 1.40 thorpej struct fxp_softc *sc = ifp->if_softc; 1604 1.2 thorpej struct fxp_txsoft *txs; 1605 1.1 thorpej int i; 1606 1.1 thorpej 1607 1.1 thorpej /* 1608 1.9 sommerfe * Turn down interface (done early to avoid bad interactions 1609 1.9 sommerfe * between panics, shutdown hooks, and the watchdog timer) 1610 1.9 sommerfe */ 1611 1.9 sommerfe ifp->if_timer = 0; 1612 1.9 sommerfe ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 1613 1.9 sommerfe 1614 1.9 sommerfe /* 1615 1.1 thorpej * Cancel stats updater. 1616 1.1 thorpej */ 1617 1.24 thorpej callout_stop(&sc->sc_callout); 1618 1.12 thorpej if (sc->sc_flags & FXPF_MII) { 1619 1.12 thorpej /* Down the MII. */ 1620 1.12 thorpej mii_down(&sc->sc_mii); 1621 1.12 thorpej } 1622 1.1 thorpej 1623 1.1 thorpej /* 1624 1.64 thorpej * Issue software reset. This unloads any microcode that 1625 1.64 thorpej * might already be loaded. 1626 1.1 thorpej */ 1627 1.64 thorpej sc->sc_flags &= ~FXPF_UCODE_LOADED; 1628 1.64 thorpej CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SOFTWARE_RESET); 1629 1.64 thorpej DELAY(50); 1630 1.1 thorpej 1631 1.1 thorpej /* 1632 1.1 thorpej * Release any xmit buffers. 1633 1.1 thorpej */ 1634 1.2 thorpej for (i = 0; i < FXP_NTXCB; i++) { 1635 1.2 thorpej txs = FXP_DSTX(sc, i); 1636 1.2 thorpej if (txs->txs_mbuf != NULL) { 1637 1.2 thorpej bus_dmamap_unload(sc->sc_dmat, txs->txs_dmamap); 1638 1.2 thorpej m_freem(txs->txs_mbuf); 1639 1.2 thorpej txs->txs_mbuf = NULL; 1640 1.1 thorpej } 1641 1.1 thorpej } 1642 1.2 thorpej sc->sc_txpending = 0; 1643 1.1 thorpej 1644 1.40 thorpej if (disable) { 1645 1.7 thorpej fxp_rxdrain(sc); 1646 1.40 thorpej fxp_disable(sc); 1647 1.1 thorpej } 1648 1.1 thorpej 1649 1.1 thorpej } 1650 1.1 thorpej 1651 1.1 thorpej /* 1652 1.1 thorpej * Watchdog/transmission transmit timeout handler. Called when a 1653 1.1 thorpej * transmission is started on the interface, but no interrupt is 1654 1.1 thorpej * received before the timeout. This usually indicates that the 1655 1.1 thorpej * card has wedged for some reason. 1656 1.1 thorpej */ 1657 1.1 thorpej void 1658 1.46 thorpej fxp_watchdog(struct ifnet *ifp) 1659 1.1 thorpej { 1660 1.1 thorpej struct fxp_softc *sc = ifp->if_softc; 1661 1.1 thorpej 1662 1.114 joerg log(LOG_ERR, "%s: device timeout\n", device_xname(sc->sc_dev)); 1663 1.157 thorpej if_statinc(ifp, if_oerrors); 1664 1.1 thorpej 1665 1.40 thorpej (void) fxp_init(ifp); 1666 1.1 thorpej } 1667 1.1 thorpej 1668 1.2 thorpej /* 1669 1.2 thorpej * Initialize the interface. Must be called at splnet(). 1670 1.2 thorpej */ 1671 1.7 thorpej int 1672 1.46 thorpej fxp_init(struct ifnet *ifp) 1673 1.1 thorpej { 1674 1.40 thorpej struct fxp_softc *sc = ifp->if_softc; 1675 1.1 thorpej struct fxp_cb_config *cbp; 1676 1.1 thorpej struct fxp_cb_ias *cb_ias; 1677 1.50 thorpej struct fxp_txdesc *txd; 1678 1.7 thorpej bus_dmamap_t rxmap; 1679 1.80 yamt int i, prm, save_bf, lrxen, vlan_drop, allm, error = 0; 1680 1.116 tsutsui uint16_t status; 1681 1.1 thorpej 1682 1.40 thorpej if ((error = fxp_enable(sc)) != 0) 1683 1.40 thorpej goto out; 1684 1.40 thorpej 1685 1.1 thorpej /* 1686 1.1 thorpej * Cancel any pending I/O 1687 1.1 thorpej */ 1688 1.40 thorpej fxp_stop(ifp, 0); 1689 1.1 thorpej 1690 1.69 enami /* 1691 1.21 joda * XXX just setting sc_flags to 0 here clears any FXPF_MII 1692 1.21 joda * flag, and this prevents the MII from detaching resulting in 1693 1.21 joda * a panic. The flags field should perhaps be split in runtime 1694 1.21 joda * flags and more static information. For now, just clear the 1695 1.21 joda * only other flag set. 1696 1.21 joda */ 1697 1.21 joda 1698 1.21 joda sc->sc_flags &= ~FXPF_WANTINIT; 1699 1.1 thorpej 1700 1.1 thorpej /* 1701 1.1 thorpej * Initialize base of CBL and RFA memory. Loading with zero 1702 1.1 thorpej * sets it up for regular linear addressing. 1703 1.1 thorpej */ 1704 1.2 thorpej fxp_scb_wait(sc); 1705 1.1 thorpej CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, 0); 1706 1.47 thorpej fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_BASE); 1707 1.1 thorpej 1708 1.1 thorpej fxp_scb_wait(sc); 1709 1.47 thorpej fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_BASE); 1710 1.1 thorpej 1711 1.1 thorpej /* 1712 1.2 thorpej * Initialize the multicast filter. Do this now, since we might 1713 1.2 thorpej * have to setup the config block differently. 1714 1.2 thorpej */ 1715 1.3 thorpej fxp_mc_setup(sc); 1716 1.2 thorpej 1717 1.2 thorpej prm = (ifp->if_flags & IFF_PROMISC) ? 1 : 0; 1718 1.2 thorpej allm = (ifp->if_flags & IFF_ALLMULTI) ? 1 : 0; 1719 1.2 thorpej 1720 1.2 thorpej /* 1721 1.39 thorpej * In order to support receiving 802.1Q VLAN frames, we have to 1722 1.39 thorpej * enable "save bad frames", since they are 4 bytes larger than 1723 1.52 thorpej * the normal Ethernet maximum frame length. On i82558 and later, 1724 1.52 thorpej * we have a better mechanism for this. 1725 1.39 thorpej */ 1726 1.52 thorpej save_bf = 0; 1727 1.52 thorpej lrxen = 0; 1728 1.80 yamt vlan_drop = 0; 1729 1.52 thorpej if (sc->sc_ethercom.ec_capenable & ETHERCAP_VLAN_MTU) { 1730 1.52 thorpej if (sc->sc_rev < FXP_REV_82558_A4) 1731 1.52 thorpej save_bf = 1; 1732 1.52 thorpej else 1733 1.52 thorpej lrxen = 1; 1734 1.80 yamt if (sc->sc_rev >= FXP_REV_82550) 1735 1.80 yamt vlan_drop = 1; 1736 1.52 thorpej } 1737 1.39 thorpej 1738 1.39 thorpej /* 1739 1.1 thorpej * Initialize base of dump-stats buffer. 1740 1.1 thorpej */ 1741 1.1 thorpej fxp_scb_wait(sc); 1742 1.1 thorpej CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, 1743 1.2 thorpej sc->sc_cddma + FXP_CDSTATSOFF); 1744 1.32 tsutsui FXP_CDSTATSSYNC(sc, BUS_DMASYNC_PREREAD); 1745 1.47 thorpej fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_DUMP_ADR); 1746 1.1 thorpej 1747 1.2 thorpej cbp = &sc->sc_control_data->fcd_configcb; 1748 1.2 thorpej memset(cbp, 0, sizeof(struct fxp_cb_config)); 1749 1.1 thorpej 1750 1.1 thorpej /* 1751 1.64 thorpej * Load microcode for this controller. 1752 1.64 thorpej */ 1753 1.64 thorpej fxp_load_ucode(sc); 1754 1.64 thorpej 1755 1.93 abs if ((sc->sc_ethercom.ec_if.if_flags & IFF_LINK1)) 1756 1.93 abs sc->sc_flags |= FXPF_RECV_WORKAROUND; 1757 1.93 abs else 1758 1.93 abs sc->sc_flags &= ~FXPF_RECV_WORKAROUND; 1759 1.93 abs 1760 1.64 thorpej /* 1761 1.2 thorpej * This copy is kind of disgusting, but there are a bunch of must be 1762 1.1 thorpej * zero and must be one bits in this structure and this is the easiest 1763 1.1 thorpej * way to initialize them all to proper values. 1764 1.1 thorpej */ 1765 1.2 thorpej memcpy(cbp, fxp_cb_config_template, sizeof(fxp_cb_config_template)); 1766 1.1 thorpej 1767 1.15 thorpej /* BIG_ENDIAN: no need to swap to store 0 */ 1768 1.1 thorpej cbp->cb_status = 0; 1769 1.15 thorpej cbp->cb_command = htole16(FXP_CB_COMMAND_CONFIG | 1770 1.15 thorpej FXP_CB_COMMAND_EL); 1771 1.15 thorpej /* BIG_ENDIAN: no need to swap to store 0xffffffff */ 1772 1.15 thorpej cbp->link_addr = 0xffffffff; /* (no) next command */ 1773 1.53 thorpej /* bytes in config block */ 1774 1.75 yamt cbp->byte_count = (sc->sc_flags & FXPF_EXT_RFA) ? 1775 1.75 yamt FXP_EXT_CONFIG_LEN : FXP_CONFIG_LEN; 1776 1.1 thorpej cbp->rx_fifo_limit = 8; /* rx fifo threshold (32 bytes) */ 1777 1.1 thorpej cbp->tx_fifo_limit = 0; /* tx fifo threshold (0 bytes) */ 1778 1.1 thorpej cbp->adaptive_ifs = 0; /* (no) adaptive interframe spacing */ 1779 1.52 thorpej cbp->mwi_enable = (sc->sc_flags & FXPF_MWI) ? 1 : 0; 1780 1.52 thorpej cbp->type_enable = 0; /* actually reserved */ 1781 1.52 thorpej cbp->read_align_en = (sc->sc_flags & FXPF_READ_ALIGN) ? 1 : 0; 1782 1.52 thorpej cbp->end_wr_on_cl = (sc->sc_flags & FXPF_WRITE_ALIGN) ? 1 : 0; 1783 1.1 thorpej cbp->rx_dma_bytecount = 0; /* (no) rx DMA max */ 1784 1.1 thorpej cbp->tx_dma_bytecount = 0; /* (no) tx DMA max */ 1785 1.52 thorpej cbp->dma_mbce = 0; /* (disable) dma max counters */ 1786 1.1 thorpej cbp->late_scb = 0; /* (don't) defer SCB update */ 1787 1.52 thorpej cbp->tno_int_or_tco_en =0; /* (disable) tx not okay interrupt */ 1788 1.4 thorpej cbp->ci_int = 1; /* interrupt on CU idle */ 1789 1.52 thorpej cbp->ext_txcb_dis = (sc->sc_flags & FXPF_EXT_TXCB) ? 0 : 1; 1790 1.52 thorpej cbp->ext_stats_dis = 1; /* disable extended counters */ 1791 1.52 thorpej cbp->keep_overrun_rx = 0; /* don't pass overrun frames to host */ 1792 1.39 thorpej cbp->save_bf = save_bf;/* save bad frames */ 1793 1.1 thorpej cbp->disc_short_rx = !prm; /* discard short packets */ 1794 1.1 thorpej cbp->underrun_retry = 1; /* retry mode (1) on DMA underrun */ 1795 1.75 yamt cbp->ext_rfa = (sc->sc_flags & FXPF_EXT_RFA) ? 1 : 0; 1796 1.52 thorpej cbp->two_frames = 0; /* do not limit FIFO to 2 frames */ 1797 1.52 thorpej cbp->dyn_tbd = 0; /* (no) dynamic TBD mode */ 1798 1.51 thorpej /* interface mode */ 1799 1.51 thorpej cbp->mediatype = (sc->sc_flags & FXPF_MII) ? 1 : 0; 1800 1.52 thorpej cbp->csma_dis = 0; /* (don't) disable link */ 1801 1.125 tsutsui cbp->tcp_udp_cksum = (sc->sc_flags & FXPF_82559_RXCSUM) ? 1 : 0; 1802 1.125 tsutsui /* (don't) enable RX checksum */ 1803 1.52 thorpej cbp->vlan_tco = 0; /* (don't) enable vlan wakeup */ 1804 1.52 thorpej cbp->link_wake_en = 0; /* (don't) assert PME# on link change */ 1805 1.52 thorpej cbp->arp_wake_en = 0; /* (don't) assert PME# on arp */ 1806 1.52 thorpej cbp->mc_wake_en = 0; /* (don't) assert PME# on mcmatch */ 1807 1.1 thorpej cbp->nsai = 1; /* (don't) disable source addr insert */ 1808 1.1 thorpej cbp->preamble_length = 2; /* (7 byte) preamble */ 1809 1.1 thorpej cbp->loopback = 0; /* (don't) loopback */ 1810 1.1 thorpej cbp->linear_priority = 0; /* (normal CSMA/CD operation) */ 1811 1.1 thorpej cbp->linear_pri_mode = 0; /* (wait after xmit only) */ 1812 1.1 thorpej cbp->interfrm_spacing = 6; /* (96 bits of) interframe spacing */ 1813 1.1 thorpej cbp->promiscuous = prm; /* promiscuous mode */ 1814 1.1 thorpej cbp->bcast_disable = 0; /* (don't) disable broadcasts */ 1815 1.52 thorpej cbp->wait_after_win = 0; /* (don't) enable modified backoff alg*/ 1816 1.52 thorpej cbp->ignore_ul = 0; /* consider U/L bit in IA matching */ 1817 1.52 thorpej cbp->crc16_en = 0; /* (don't) enable crc-16 algorithm */ 1818 1.52 thorpej cbp->crscdt = (sc->sc_flags & FXPF_MII) ? 0 : 1; 1819 1.1 thorpej cbp->stripping = !prm; /* truncate rx packet to byte count */ 1820 1.1 thorpej cbp->padding = 1; /* (do) pad short tx packets */ 1821 1.1 thorpej cbp->rcv_crc_xfer = 0; /* (don't) xfer CRC to host */ 1822 1.52 thorpej cbp->long_rx_en = lrxen; /* long packet receive enable */ 1823 1.52 thorpej cbp->ia_wake_en = 0; /* (don't) wake up on address match */ 1824 1.52 thorpej cbp->magic_pkt_dis = 0; /* (don't) disable magic packet */ 1825 1.52 thorpej /* must set wake_en in PMCSR also */ 1826 1.1 thorpej cbp->force_fdx = 0; /* (don't) force full duplex */ 1827 1.1 thorpej cbp->fdx_pin_en = 1; /* (enable) FDX# pin */ 1828 1.1 thorpej cbp->multi_ia = 0; /* (don't) accept multiple IAs */ 1829 1.2 thorpej cbp->mc_all = allm; /* accept all multicasts */ 1830 1.75 yamt cbp->ext_rx_mode = (sc->sc_flags & FXPF_EXT_RFA) ? 1 : 0; 1831 1.80 yamt cbp->vlan_drop_en = vlan_drop; 1832 1.1 thorpej 1833 1.122 mrg if (!(sc->sc_flags & FXPF_FC)) { 1834 1.52 thorpej /* 1835 1.52 thorpej * The i82557 has no hardware flow control, the values 1836 1.52 thorpej * here are the defaults for the chip. 1837 1.52 thorpej */ 1838 1.52 thorpej cbp->fc_delay_lsb = 0; 1839 1.52 thorpej cbp->fc_delay_msb = 0x40; 1840 1.52 thorpej cbp->pri_fc_thresh = 3; 1841 1.52 thorpej cbp->tx_fc_dis = 0; 1842 1.52 thorpej cbp->rx_fc_restop = 0; 1843 1.52 thorpej cbp->rx_fc_restart = 0; 1844 1.52 thorpej cbp->fc_filter = 0; 1845 1.52 thorpej cbp->pri_fc_loc = 1; 1846 1.52 thorpej } else { 1847 1.52 thorpej cbp->fc_delay_lsb = 0x1f; 1848 1.52 thorpej cbp->fc_delay_msb = 0x01; 1849 1.52 thorpej cbp->pri_fc_thresh = 3; 1850 1.52 thorpej cbp->tx_fc_dis = 0; /* enable transmit FC */ 1851 1.52 thorpej cbp->rx_fc_restop = 1; /* enable FC restop frames */ 1852 1.52 thorpej cbp->rx_fc_restart = 1; /* enable FC restart frames */ 1853 1.52 thorpej cbp->fc_filter = !prm; /* drop FC frames to host */ 1854 1.52 thorpej cbp->pri_fc_loc = 1; /* FC pri location (byte31) */ 1855 1.86 thorpej cbp->ext_stats_dis = 0; /* enable extended stats */ 1856 1.52 thorpej } 1857 1.52 thorpej 1858 1.152 msaitoh FXP_CDCONFIGSYNC(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1859 1.1 thorpej 1860 1.1 thorpej /* 1861 1.1 thorpej * Start the config command/DMA. 1862 1.1 thorpej */ 1863 1.1 thorpej fxp_scb_wait(sc); 1864 1.2 thorpej CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, sc->sc_cddma + FXP_CDCONFIGOFF); 1865 1.47 thorpej fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START); 1866 1.1 thorpej /* ...and wait for it to complete. */ 1867 1.116 tsutsui for (i = 1000; i > 0; i--) { 1868 1.2 thorpej FXP_CDCONFIGSYNC(sc, 1869 1.152 msaitoh BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1870 1.116 tsutsui status = le16toh(cbp->cb_status); 1871 1.116 tsutsui FXP_CDCONFIGSYNC(sc, BUS_DMASYNC_PREREAD); 1872 1.116 tsutsui if ((status & FXP_CB_STATUS_C) != 0) 1873 1.116 tsutsui break; 1874 1.27 jhawk DELAY(1); 1875 1.152 msaitoh } 1876 1.26 jhawk if (i == 0) { 1877 1.89 thorpej log(LOG_WARNING, "%s: line %d: dmasync timeout\n", 1878 1.114 joerg device_xname(sc->sc_dev), __LINE__); 1879 1.69 enami return (ETIMEDOUT); 1880 1.26 jhawk } 1881 1.1 thorpej 1882 1.1 thorpej /* 1883 1.2 thorpej * Initialize the station address. 1884 1.1 thorpej */ 1885 1.2 thorpej cb_ias = &sc->sc_control_data->fcd_iascb; 1886 1.15 thorpej /* BIG_ENDIAN: no need to swap to store 0 */ 1887 1.1 thorpej cb_ias->cb_status = 0; 1888 1.15 thorpej cb_ias->cb_command = htole16(FXP_CB_COMMAND_IAS | FXP_CB_COMMAND_EL); 1889 1.15 thorpej /* BIG_ENDIAN: no need to swap to store 0xffffffff */ 1890 1.15 thorpej cb_ias->link_addr = 0xffffffff; 1891 1.103 dyoung memcpy(cb_ias->macaddr, CLLADDR(ifp->if_sadl), ETHER_ADDR_LEN); 1892 1.1 thorpej 1893 1.152 msaitoh FXP_CDIASSYNC(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1894 1.1 thorpej 1895 1.1 thorpej /* 1896 1.1 thorpej * Start the IAS (Individual Address Setup) command/DMA. 1897 1.1 thorpej */ 1898 1.1 thorpej fxp_scb_wait(sc); 1899 1.2 thorpej CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, sc->sc_cddma + FXP_CDIASOFF); 1900 1.47 thorpej fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START); 1901 1.1 thorpej /* ...and wait for it to complete. */ 1902 1.155 maxv for (i = 1000; i > 0; i--) { 1903 1.2 thorpej FXP_CDIASSYNC(sc, 1904 1.152 msaitoh BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1905 1.116 tsutsui status = le16toh(cb_ias->cb_status); 1906 1.116 tsutsui FXP_CDIASSYNC(sc, BUS_DMASYNC_PREREAD); 1907 1.116 tsutsui if ((status & FXP_CB_STATUS_C) != 0) 1908 1.116 tsutsui break; 1909 1.27 jhawk DELAY(1); 1910 1.116 tsutsui } 1911 1.26 jhawk if (i == 0) { 1912 1.89 thorpej log(LOG_WARNING, "%s: line %d: dmasync timeout\n", 1913 1.114 joerg device_xname(sc->sc_dev), __LINE__); 1914 1.69 enami return (ETIMEDOUT); 1915 1.26 jhawk } 1916 1.27 jhawk 1917 1.1 thorpej /* 1918 1.2 thorpej * Initialize the transmit descriptor ring. txlast is initialized 1919 1.2 thorpej * to the end of the list so that it will wrap around to the first 1920 1.2 thorpej * descriptor when the first packet is transmitted. 1921 1.1 thorpej */ 1922 1.1 thorpej for (i = 0; i < FXP_NTXCB; i++) { 1923 1.2 thorpej txd = FXP_CDTX(sc, i); 1924 1.50 thorpej memset(txd, 0, sizeof(*txd)); 1925 1.50 thorpej txd->txd_txcb.cb_command = 1926 1.15 thorpej htole16(FXP_CB_COMMAND_NOP | FXP_CB_COMMAND_S); 1927 1.50 thorpej txd->txd_txcb.link_addr = 1928 1.50 thorpej htole32(FXP_CDTXADDR(sc, FXP_NEXTTX(i))); 1929 1.52 thorpej if (sc->sc_flags & FXPF_EXT_TXCB) 1930 1.52 thorpej txd->txd_txcb.tbd_array_addr = 1931 1.52 thorpej htole32(FXP_CDTBDADDR(sc, i) + 1932 1.52 thorpej (2 * sizeof(struct fxp_tbd))); 1933 1.52 thorpej else 1934 1.52 thorpej txd->txd_txcb.tbd_array_addr = 1935 1.52 thorpej htole32(FXP_CDTBDADDR(sc, i)); 1936 1.152 msaitoh FXP_CDTXSYNC(sc, i, 1937 1.152 msaitoh BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1938 1.2 thorpej } 1939 1.2 thorpej sc->sc_txpending = 0; 1940 1.2 thorpej sc->sc_txdirty = 0; 1941 1.2 thorpej sc->sc_txlast = FXP_NTXCB - 1; 1942 1.2 thorpej 1943 1.2 thorpej /* 1944 1.7 thorpej * Initialize the receive buffer list. 1945 1.7 thorpej */ 1946 1.7 thorpej sc->sc_rxq.ifq_maxlen = FXP_NRFABUFS; 1947 1.7 thorpej while (sc->sc_rxq.ifq_len < FXP_NRFABUFS) { 1948 1.7 thorpej rxmap = FXP_RXMAP_GET(sc); 1949 1.7 thorpej if ((error = fxp_add_rfabuf(sc, rxmap, 0)) != 0) { 1950 1.89 thorpej log(LOG_ERR, "%s: unable to allocate or map rx " 1951 1.7 thorpej "buffer %d, error = %d\n", 1952 1.114 joerg device_xname(sc->sc_dev), 1953 1.7 thorpej sc->sc_rxq.ifq_len, error); 1954 1.7 thorpej /* 1955 1.7 thorpej * XXX Should attempt to run with fewer receive 1956 1.7 thorpej * XXX buffers instead of just failing. 1957 1.7 thorpej */ 1958 1.7 thorpej FXP_RXMAP_PUT(sc, rxmap); 1959 1.7 thorpej fxp_rxdrain(sc); 1960 1.7 thorpej goto out; 1961 1.7 thorpej } 1962 1.7 thorpej } 1963 1.8 thorpej sc->sc_rxidle = 0; 1964 1.7 thorpej 1965 1.7 thorpej /* 1966 1.2 thorpej * Give the transmit ring to the chip. We do this by pointing 1967 1.2 thorpej * the chip at the last descriptor (which is a NOP|SUSPEND), and 1968 1.2 thorpej * issuing a start command. It will execute the NOP and then 1969 1.2 thorpej * suspend, pointing at the first descriptor. 1970 1.1 thorpej */ 1971 1.1 thorpej fxp_scb_wait(sc); 1972 1.2 thorpej CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, FXP_CDTXADDR(sc, sc->sc_txlast)); 1973 1.47 thorpej fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START); 1974 1.1 thorpej 1975 1.1 thorpej /* 1976 1.1 thorpej * Initialize receiver buffer area - RFA. 1977 1.1 thorpej */ 1978 1.105 tsutsui #if 0 /* initialization will be done by FXP_SCB_INTRCNTL_REQUEST_SWI later */ 1979 1.7 thorpej rxmap = M_GETCTX(sc->sc_rxq.ifq_head, bus_dmamap_t); 1980 1.1 thorpej fxp_scb_wait(sc); 1981 1.1 thorpej CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, 1982 1.7 thorpej rxmap->dm_segs[0].ds_addr + RFA_ALIGNMENT_FUDGE); 1983 1.47 thorpej fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_START); 1984 1.105 tsutsui #endif 1985 1.1 thorpej 1986 1.6 thorpej if (sc->sc_flags & FXPF_MII) { 1987 1.6 thorpej /* 1988 1.6 thorpej * Set current media. 1989 1.6 thorpej */ 1990 1.110 dyoung if ((error = mii_ifmedia_change(&sc->sc_mii)) != 0) 1991 1.110 dyoung goto out; 1992 1.6 thorpej } 1993 1.1 thorpej 1994 1.2 thorpej /* 1995 1.2 thorpej * ...all done! 1996 1.2 thorpej */ 1997 1.1 thorpej ifp->if_flags |= IFF_RUNNING; 1998 1.1 thorpej ifp->if_flags &= ~IFF_OACTIVE; 1999 1.1 thorpej 2000 1.1 thorpej /* 2001 1.152 msaitoh * Request a software generated interrupt that will be used to 2002 1.105 tsutsui * (re)start the RU processing. If we direct the chip to start 2003 1.105 tsutsui * receiving from the start of queue now, instead of letting the 2004 1.105 tsutsui * interrupt handler first process all received packets, we run 2005 1.105 tsutsui * the risk of having it overwrite mbuf clusters while they are 2006 1.105 tsutsui * being processed or after they have been returned to the pool. 2007 1.105 tsutsui */ 2008 1.105 tsutsui CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL, FXP_SCB_INTRCNTL_REQUEST_SWI); 2009 1.152 msaitoh 2010 1.105 tsutsui /* 2011 1.7 thorpej * Start the one second timer. 2012 1.1 thorpej */ 2013 1.159 thorpej callout_schedule(&sc->sc_callout, hz); 2014 1.2 thorpej 2015 1.2 thorpej /* 2016 1.2 thorpej * Attempt to start output on the interface. 2017 1.2 thorpej */ 2018 1.2 thorpej fxp_start(ifp); 2019 1.7 thorpej 2020 1.7 thorpej out: 2021 1.40 thorpej if (error) { 2022 1.40 thorpej ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 2023 1.40 thorpej ifp->if_timer = 0; 2024 1.89 thorpej log(LOG_ERR, "%s: interface not running\n", 2025 1.114 joerg device_xname(sc->sc_dev)); 2026 1.40 thorpej } 2027 1.7 thorpej return (error); 2028 1.1 thorpej } 2029 1.1 thorpej 2030 1.1 thorpej /* 2031 1.1 thorpej * Notify the world which media we're using. 2032 1.1 thorpej */ 2033 1.1 thorpej void 2034 1.46 thorpej fxp_mii_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) 2035 1.1 thorpej { 2036 1.1 thorpej struct fxp_softc *sc = ifp->if_softc; 2037 1.1 thorpej 2038 1.69 enami if (sc->sc_enabled == 0) { 2039 1.10 sommerfe ifmr->ifm_active = IFM_ETHER | IFM_NONE; 2040 1.10 sommerfe ifmr->ifm_status = 0; 2041 1.10 sommerfe return; 2042 1.10 sommerfe } 2043 1.69 enami 2044 1.110 dyoung ether_mediastatus(ifp, ifmr); 2045 1.1 thorpej } 2046 1.1 thorpej 2047 1.1 thorpej int 2048 1.100 christos fxp_80c24_mediachange(struct ifnet *ifp) 2049 1.1 thorpej { 2050 1.1 thorpej 2051 1.1 thorpej /* Nothing to do here. */ 2052 1.1 thorpej return (0); 2053 1.1 thorpej } 2054 1.1 thorpej 2055 1.1 thorpej void 2056 1.46 thorpej fxp_80c24_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) 2057 1.1 thorpej { 2058 1.1 thorpej struct fxp_softc *sc = ifp->if_softc; 2059 1.1 thorpej 2060 1.1 thorpej /* 2061 1.1 thorpej * Media is currently-selected media. We cannot determine 2062 1.1 thorpej * the link status. 2063 1.1 thorpej */ 2064 1.1 thorpej ifmr->ifm_status = 0; 2065 1.1 thorpej ifmr->ifm_active = sc->sc_mii.mii_media.ifm_cur->ifm_media; 2066 1.1 thorpej } 2067 1.1 thorpej 2068 1.1 thorpej /* 2069 1.1 thorpej * Add a buffer to the end of the RFA buffer list. 2070 1.7 thorpej * Return 0 if successful, error code on failure. 2071 1.7 thorpej * 2072 1.1 thorpej * The RFA struct is stuck at the beginning of mbuf cluster and the 2073 1.1 thorpej * data pointer is fixed up to point just past it. 2074 1.1 thorpej */ 2075 1.1 thorpej int 2076 1.46 thorpej fxp_add_rfabuf(struct fxp_softc *sc, bus_dmamap_t rxmap, int unload) 2077 1.1 thorpej { 2078 1.7 thorpej struct mbuf *m; 2079 1.7 thorpej int error; 2080 1.1 thorpej 2081 1.7 thorpej MGETHDR(m, M_DONTWAIT, MT_DATA); 2082 1.7 thorpej if (m == NULL) 2083 1.7 thorpej return (ENOBUFS); 2084 1.1 thorpej 2085 1.73 matt MCLAIM(m, &sc->sc_ethercom.ec_rx_mowner); 2086 1.7 thorpej MCLGET(m, M_DONTWAIT); 2087 1.7 thorpej if ((m->m_flags & M_EXT) == 0) { 2088 1.7 thorpej m_freem(m); 2089 1.7 thorpej return (ENOBUFS); 2090 1.1 thorpej } 2091 1.1 thorpej 2092 1.7 thorpej if (unload) 2093 1.7 thorpej bus_dmamap_unload(sc->sc_dmat, rxmap); 2094 1.1 thorpej 2095 1.7 thorpej M_SETCTX(m, rxmap); 2096 1.1 thorpej 2097 1.72 thorpej m->m_len = m->m_pkthdr.len = m->m_ext.ext_size; 2098 1.72 thorpej error = bus_dmamap_load_mbuf(sc->sc_dmat, rxmap, m, 2099 1.152 msaitoh BUS_DMA_READ | BUS_DMA_NOWAIT); 2100 1.7 thorpej if (error) { 2101 1.89 thorpej /* XXX XXX XXX */ 2102 1.121 tsutsui aprint_error_dev(sc->sc_dev, 2103 1.121 tsutsui "can't load rx DMA map %d, error = %d\n", 2104 1.112 cegger sc->sc_rxq.ifq_len, error); 2105 1.89 thorpej panic("fxp_add_rfabuf"); 2106 1.1 thorpej } 2107 1.1 thorpej 2108 1.7 thorpej FXP_INIT_RFABUF(sc, m); 2109 1.1 thorpej 2110 1.7 thorpej return (0); 2111 1.1 thorpej } 2112 1.1 thorpej 2113 1.45 lukem int 2114 1.150 msaitoh fxp_mdi_read(device_t self, int phy, int reg, uint16_t *value) 2115 1.1 thorpej { 2116 1.114 joerg struct fxp_softc *sc = device_private(self); 2117 1.1 thorpej int count = 10000; 2118 1.150 msaitoh uint32_t data; 2119 1.1 thorpej 2120 1.1 thorpej CSR_WRITE_4(sc, FXP_CSR_MDICONTROL, 2121 1.1 thorpej (FXP_MDI_READ << 26) | (reg << 16) | (phy << 21)); 2122 1.1 thorpej 2123 1.150 msaitoh while (((data = CSR_READ_4(sc, FXP_CSR_MDICONTROL)) & 2124 1.69 enami 0x10000000) == 0 && count--) 2125 1.1 thorpej DELAY(10); 2126 1.1 thorpej 2127 1.150 msaitoh if (count <= 0) { 2128 1.89 thorpej log(LOG_WARNING, 2129 1.114 joerg "%s: fxp_mdi_read: timed out\n", device_xname(self)); 2130 1.150 msaitoh return ETIMEDOUT; 2131 1.150 msaitoh } 2132 1.1 thorpej 2133 1.150 msaitoh *value = data & 0xffff; 2134 1.150 msaitoh return 0; 2135 1.1 thorpej } 2136 1.1 thorpej 2137 1.1 thorpej void 2138 1.140 matt fxp_statchg(struct ifnet *ifp) 2139 1.1 thorpej { 2140 1.1 thorpej 2141 1.65 mycroft /* Nothing to do. */ 2142 1.1 thorpej } 2143 1.1 thorpej 2144 1.150 msaitoh int 2145 1.150 msaitoh fxp_mdi_write(device_t self, int phy, int reg, uint16_t value) 2146 1.1 thorpej { 2147 1.114 joerg struct fxp_softc *sc = device_private(self); 2148 1.1 thorpej int count = 10000; 2149 1.1 thorpej 2150 1.1 thorpej CSR_WRITE_4(sc, FXP_CSR_MDICONTROL, 2151 1.150 msaitoh (FXP_MDI_WRITE << 26) | (reg << 16) | (phy << 21) | value); 2152 1.1 thorpej 2153 1.69 enami while ((CSR_READ_4(sc, FXP_CSR_MDICONTROL) & 0x10000000) == 0 && 2154 1.1 thorpej count--) 2155 1.1 thorpej DELAY(10); 2156 1.1 thorpej 2157 1.150 msaitoh if (count <= 0) { 2158 1.89 thorpej log(LOG_WARNING, 2159 1.114 joerg "%s: fxp_mdi_write: timed out\n", device_xname(self)); 2160 1.150 msaitoh return ETIMEDOUT; 2161 1.150 msaitoh } 2162 1.150 msaitoh 2163 1.150 msaitoh return 0; 2164 1.1 thorpej } 2165 1.1 thorpej 2166 1.1 thorpej int 2167 1.101 christos fxp_ioctl(struct ifnet *ifp, u_long cmd, void *data) 2168 1.1 thorpej { 2169 1.1 thorpej struct fxp_softc *sc = ifp->if_softc; 2170 1.40 thorpej int s, error; 2171 1.1 thorpej 2172 1.1 thorpej s = splnet(); 2173 1.1 thorpej 2174 1.40 thorpej switch (cmd) { 2175 1.40 thorpej default: 2176 1.111 dyoung if ((error = ether_ioctl(ifp, cmd, data)) != ENETRESET) 2177 1.111 dyoung break; 2178 1.111 dyoung 2179 1.111 dyoung error = 0; 2180 1.111 dyoung 2181 1.111 dyoung if (cmd != SIOCADDMULTI && cmd != SIOCDELMULTI) 2182 1.111 dyoung ; 2183 1.111 dyoung else if (ifp->if_flags & IFF_RUNNING) { 2184 1.111 dyoung /* 2185 1.111 dyoung * Multicast list has changed; set the 2186 1.111 dyoung * hardware filter accordingly. 2187 1.111 dyoung */ 2188 1.115 ws while (sc->sc_txpending) { 2189 1.111 dyoung sc->sc_flags |= FXPF_WANTINIT; 2190 1.115 ws tsleep(sc, PSOCK, "fxp_init", 0); 2191 1.115 ws } 2192 1.115 ws error = fxp_init(ifp); 2193 1.1 thorpej } 2194 1.1 thorpej break; 2195 1.40 thorpej } 2196 1.1 thorpej 2197 1.40 thorpej /* Try to get more packets going. */ 2198 1.40 thorpej if (sc->sc_enabled) 2199 1.40 thorpej fxp_start(ifp); 2200 1.2 thorpej 2201 1.2 thorpej splx(s); 2202 1.1 thorpej return (error); 2203 1.1 thorpej } 2204 1.1 thorpej 2205 1.1 thorpej /* 2206 1.1 thorpej * Program the multicast filter. 2207 1.1 thorpej * 2208 1.2 thorpej * This function must be called at splnet(). 2209 1.1 thorpej */ 2210 1.1 thorpej void 2211 1.46 thorpej fxp_mc_setup(struct fxp_softc *sc) 2212 1.1 thorpej { 2213 1.2 thorpej struct fxp_cb_mcs *mcsp = &sc->sc_control_data->fcd_mcscb; 2214 1.2 thorpej struct ifnet *ifp = &sc->sc_ethercom.ec_if; 2215 1.1 thorpej struct ethercom *ec = &sc->sc_ethercom; 2216 1.1 thorpej struct ether_multi *enm; 2217 1.1 thorpej struct ether_multistep step; 2218 1.26 jhawk int count, nmcasts; 2219 1.116 tsutsui uint16_t status; 2220 1.1 thorpej 2221 1.8 thorpej #ifdef DIAGNOSTIC 2222 1.8 thorpej if (sc->sc_txpending) 2223 1.8 thorpej panic("fxp_mc_setup: pending transmissions"); 2224 1.8 thorpej #endif 2225 1.2 thorpej 2226 1.137 jakllsch 2227 1.137 jakllsch if (ifp->if_flags & IFF_PROMISC) { 2228 1.137 jakllsch ifp->if_flags |= IFF_ALLMULTI; 2229 1.137 jakllsch return; 2230 1.137 jakllsch } else { 2231 1.137 jakllsch ifp->if_flags &= ~IFF_ALLMULTI; 2232 1.137 jakllsch } 2233 1.1 thorpej 2234 1.1 thorpej /* 2235 1.1 thorpej * Initialize multicast setup descriptor. 2236 1.1 thorpej */ 2237 1.1 thorpej nmcasts = 0; 2238 1.153 msaitoh ETHER_LOCK(ec); 2239 1.2 thorpej ETHER_FIRST_MULTI(step, ec, enm); 2240 1.2 thorpej while (enm != NULL) { 2241 1.2 thorpej /* 2242 1.2 thorpej * Check for too many multicast addresses or if we're 2243 1.2 thorpej * listening to a range. Either way, we simply have 2244 1.2 thorpej * to accept all multicasts. 2245 1.2 thorpej */ 2246 1.2 thorpej if (nmcasts >= MAXMCADDR || 2247 1.2 thorpej memcmp(enm->enm_addrlo, enm->enm_addrhi, 2248 1.19 enami ETHER_ADDR_LEN) != 0) { 2249 1.1 thorpej /* 2250 1.2 thorpej * Callers of this function must do the 2251 1.2 thorpej * right thing with this. If we're called 2252 1.2 thorpej * from outside fxp_init(), the caller must 2253 1.2 thorpej * detect if the state if IFF_ALLMULTI changes. 2254 1.2 thorpej * If it does, the caller must then call 2255 1.2 thorpej * fxp_init(), since allmulti is handled by 2256 1.2 thorpej * the config block. 2257 1.1 thorpej */ 2258 1.2 thorpej ifp->if_flags |= IFF_ALLMULTI; 2259 1.153 msaitoh ETHER_UNLOCK(ec); 2260 1.2 thorpej return; 2261 1.1 thorpej } 2262 1.91 christos memcpy(&mcsp->mc_addr[nmcasts][0], enm->enm_addrlo, 2263 1.2 thorpej ETHER_ADDR_LEN); 2264 1.2 thorpej nmcasts++; 2265 1.2 thorpej ETHER_NEXT_MULTI(step, enm); 2266 1.2 thorpej } 2267 1.153 msaitoh ETHER_UNLOCK(ec); 2268 1.2 thorpej 2269 1.15 thorpej /* BIG_ENDIAN: no need to swap to store 0 */ 2270 1.2 thorpej mcsp->cb_status = 0; 2271 1.15 thorpej mcsp->cb_command = htole16(FXP_CB_COMMAND_MCAS | FXP_CB_COMMAND_EL); 2272 1.15 thorpej mcsp->link_addr = htole32(FXP_CDTXADDR(sc, FXP_NEXTTX(sc->sc_txlast))); 2273 1.15 thorpej mcsp->mc_cnt = htole16(nmcasts * ETHER_ADDR_LEN); 2274 1.1 thorpej 2275 1.152 msaitoh FXP_CDMCSSYNC(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 2276 1.1 thorpej 2277 1.1 thorpej /* 2278 1.2 thorpej * Wait until the command unit is not active. This should never 2279 1.2 thorpej * happen since nothing is queued, but make sure anyway. 2280 1.1 thorpej */ 2281 1.27 jhawk count = 100; 2282 1.1 thorpej while ((CSR_READ_1(sc, FXP_CSR_SCB_RUSCUS) >> 6) == 2283 1.26 jhawk FXP_SCB_CUS_ACTIVE && --count) 2284 1.27 jhawk DELAY(1); 2285 1.26 jhawk if (count == 0) { 2286 1.89 thorpej log(LOG_WARNING, "%s: line %d: command queue timeout\n", 2287 1.114 joerg device_xname(sc->sc_dev), __LINE__); 2288 1.26 jhawk return; 2289 1.26 jhawk } 2290 1.1 thorpej 2291 1.1 thorpej /* 2292 1.2 thorpej * Start the multicast setup command/DMA. 2293 1.1 thorpej */ 2294 1.1 thorpej fxp_scb_wait(sc); 2295 1.2 thorpej CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, sc->sc_cddma + FXP_CDMCSOFF); 2296 1.47 thorpej fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START); 2297 1.1 thorpej 2298 1.3 thorpej /* ...and wait for it to complete. */ 2299 1.116 tsutsui for (count = 1000; count > 0; count--) { 2300 1.3 thorpej FXP_CDMCSSYNC(sc, 2301 1.152 msaitoh BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 2302 1.116 tsutsui status = le16toh(mcsp->cb_status); 2303 1.116 tsutsui FXP_CDMCSSYNC(sc, BUS_DMASYNC_PREREAD); 2304 1.116 tsutsui if ((status & FXP_CB_STATUS_C) != 0) 2305 1.116 tsutsui break; 2306 1.27 jhawk DELAY(1); 2307 1.116 tsutsui } 2308 1.26 jhawk if (count == 0) { 2309 1.89 thorpej log(LOG_WARNING, "%s: line %d: dmasync timeout\n", 2310 1.114 joerg device_xname(sc->sc_dev), __LINE__); 2311 1.26 jhawk return; 2312 1.26 jhawk } 2313 1.64 thorpej } 2314 1.64 thorpej 2315 1.64 thorpej static const uint32_t fxp_ucode_d101a[] = D101_A_RCVBUNDLE_UCODE; 2316 1.64 thorpej static const uint32_t fxp_ucode_d101b0[] = D101_B0_RCVBUNDLE_UCODE; 2317 1.64 thorpej static const uint32_t fxp_ucode_d101ma[] = D101M_B_RCVBUNDLE_UCODE; 2318 1.64 thorpej static const uint32_t fxp_ucode_d101s[] = D101S_RCVBUNDLE_UCODE; 2319 1.64 thorpej static const uint32_t fxp_ucode_d102[] = D102_B_RCVBUNDLE_UCODE; 2320 1.64 thorpej static const uint32_t fxp_ucode_d102c[] = D102_C_RCVBUNDLE_UCODE; 2321 1.138 msaitoh static const uint32_t fxp_ucode_d102e[] = D102_E_RCVBUNDLE_UCODE; 2322 1.64 thorpej 2323 1.92 junyoung #define UCODE(x) x, sizeof(x)/sizeof(uint32_t) 2324 1.64 thorpej 2325 1.64 thorpej static const struct ucode { 2326 1.68 thorpej int32_t revision; 2327 1.64 thorpej const uint32_t *ucode; 2328 1.64 thorpej size_t length; 2329 1.64 thorpej uint16_t int_delay_offset; 2330 1.64 thorpej uint16_t bundle_max_offset; 2331 1.64 thorpej } ucode_table[] = { 2332 1.64 thorpej { FXP_REV_82558_A4, UCODE(fxp_ucode_d101a), 2333 1.64 thorpej D101_CPUSAVER_DWORD, 0 }, 2334 1.64 thorpej 2335 1.64 thorpej { FXP_REV_82558_B0, UCODE(fxp_ucode_d101b0), 2336 1.64 thorpej D101_CPUSAVER_DWORD, 0 }, 2337 1.64 thorpej 2338 1.64 thorpej { FXP_REV_82559_A0, UCODE(fxp_ucode_d101ma), 2339 1.64 thorpej D101M_CPUSAVER_DWORD, D101M_CPUSAVER_BUNDLE_MAX_DWORD }, 2340 1.64 thorpej 2341 1.64 thorpej { FXP_REV_82559S_A, UCODE(fxp_ucode_d101s), 2342 1.64 thorpej D101S_CPUSAVER_DWORD, D101S_CPUSAVER_BUNDLE_MAX_DWORD }, 2343 1.64 thorpej 2344 1.64 thorpej { FXP_REV_82550, UCODE(fxp_ucode_d102), 2345 1.64 thorpej D102_B_CPUSAVER_DWORD, D102_B_CPUSAVER_BUNDLE_MAX_DWORD }, 2346 1.64 thorpej 2347 1.64 thorpej { FXP_REV_82550_C, UCODE(fxp_ucode_d102c), 2348 1.64 thorpej D102_C_CPUSAVER_DWORD, D102_C_CPUSAVER_BUNDLE_MAX_DWORD }, 2349 1.64 thorpej 2350 1.138 msaitoh { FXP_REV_82551_F, UCODE(fxp_ucode_d102e), 2351 1.138 msaitoh D102_E_CPUSAVER_DWORD, D102_E_CPUSAVER_BUNDLE_MAX_DWORD }, 2352 1.138 msaitoh 2353 1.138 msaitoh { FXP_REV_82551_10, UCODE(fxp_ucode_d102e), 2354 1.138 msaitoh D102_E_CPUSAVER_DWORD, D102_E_CPUSAVER_BUNDLE_MAX_DWORD }, 2355 1.138 msaitoh 2356 1.64 thorpej { 0, NULL, 0, 0, 0 } 2357 1.64 thorpej }; 2358 1.64 thorpej 2359 1.64 thorpej void 2360 1.64 thorpej fxp_load_ucode(struct fxp_softc *sc) 2361 1.64 thorpej { 2362 1.64 thorpej const struct ucode *uc; 2363 1.64 thorpej struct fxp_cb_ucode *cbp = &sc->sc_control_data->fcd_ucode; 2364 1.92 junyoung int count, i; 2365 1.116 tsutsui uint16_t status; 2366 1.64 thorpej 2367 1.64 thorpej if (sc->sc_flags & FXPF_UCODE_LOADED) 2368 1.64 thorpej return; 2369 1.64 thorpej 2370 1.64 thorpej /* 2371 1.64 thorpej * Only load the uCode if the user has requested that 2372 1.64 thorpej * we do so. 2373 1.64 thorpej */ 2374 1.64 thorpej if ((sc->sc_ethercom.ec_if.if_flags & IFF_LINK0) == 0) { 2375 1.64 thorpej sc->sc_int_delay = 0; 2376 1.64 thorpej sc->sc_bundle_max = 0; 2377 1.64 thorpej return; 2378 1.64 thorpej } 2379 1.64 thorpej 2380 1.64 thorpej for (uc = ucode_table; uc->ucode != NULL; uc++) { 2381 1.64 thorpej if (sc->sc_rev == uc->revision) 2382 1.64 thorpej break; 2383 1.64 thorpej } 2384 1.64 thorpej if (uc->ucode == NULL) 2385 1.64 thorpej return; 2386 1.64 thorpej 2387 1.64 thorpej /* BIG ENDIAN: no need to swap to store 0 */ 2388 1.64 thorpej cbp->cb_status = 0; 2389 1.64 thorpej cbp->cb_command = htole16(FXP_CB_COMMAND_UCODE | FXP_CB_COMMAND_EL); 2390 1.64 thorpej cbp->link_addr = 0xffffffff; /* (no) next command */ 2391 1.92 junyoung for (i = 0; i < uc->length; i++) 2392 1.92 junyoung cbp->ucode[i] = htole32(uc->ucode[i]); 2393 1.64 thorpej 2394 1.64 thorpej if (uc->int_delay_offset) 2395 1.91 christos *(volatile uint16_t *) &cbp->ucode[uc->int_delay_offset] = 2396 1.64 thorpej htole16(fxp_int_delay + (fxp_int_delay / 2)); 2397 1.64 thorpej 2398 1.64 thorpej if (uc->bundle_max_offset) 2399 1.91 christos *(volatile uint16_t *) &cbp->ucode[uc->bundle_max_offset] = 2400 1.64 thorpej htole16(fxp_bundle_max); 2401 1.69 enami 2402 1.152 msaitoh FXP_CDUCODESYNC(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 2403 1.64 thorpej 2404 1.64 thorpej /* 2405 1.64 thorpej * Download the uCode to the chip. 2406 1.64 thorpej */ 2407 1.64 thorpej fxp_scb_wait(sc); 2408 1.64 thorpej CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, sc->sc_cddma + FXP_CDUCODEOFF); 2409 1.64 thorpej fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START); 2410 1.64 thorpej 2411 1.64 thorpej /* ...and wait for it to complete. */ 2412 1.116 tsutsui for (count = 10000; count > 0; count--) { 2413 1.64 thorpej FXP_CDUCODESYNC(sc, 2414 1.152 msaitoh BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 2415 1.116 tsutsui status = le16toh(cbp->cb_status); 2416 1.116 tsutsui FXP_CDUCODESYNC(sc, BUS_DMASYNC_PREREAD); 2417 1.116 tsutsui if ((status & FXP_CB_STATUS_C) != 0) 2418 1.116 tsutsui break; 2419 1.64 thorpej DELAY(2); 2420 1.116 tsutsui } 2421 1.64 thorpej if (count == 0) { 2422 1.64 thorpej sc->sc_int_delay = 0; 2423 1.64 thorpej sc->sc_bundle_max = 0; 2424 1.89 thorpej log(LOG_WARNING, "%s: timeout loading microcode\n", 2425 1.114 joerg device_xname(sc->sc_dev)); 2426 1.64 thorpej return; 2427 1.64 thorpej } 2428 1.64 thorpej 2429 1.64 thorpej if (sc->sc_int_delay != fxp_int_delay || 2430 1.64 thorpej sc->sc_bundle_max != fxp_bundle_max) { 2431 1.64 thorpej sc->sc_int_delay = fxp_int_delay; 2432 1.64 thorpej sc->sc_bundle_max = fxp_bundle_max; 2433 1.89 thorpej log(LOG_INFO, "%s: Microcode loaded: int delay: %d usec, " 2434 1.114 joerg "max bundle: %d\n", device_xname(sc->sc_dev), 2435 1.64 thorpej sc->sc_int_delay, 2436 1.64 thorpej uc->bundle_max_offset == 0 ? 0 : sc->sc_bundle_max); 2437 1.64 thorpej } 2438 1.64 thorpej 2439 1.64 thorpej sc->sc_flags |= FXPF_UCODE_LOADED; 2440 1.10 sommerfe } 2441 1.10 sommerfe 2442 1.10 sommerfe int 2443 1.46 thorpej fxp_enable(struct fxp_softc *sc) 2444 1.10 sommerfe { 2445 1.10 sommerfe 2446 1.10 sommerfe if (sc->sc_enabled == 0 && sc->sc_enable != NULL) { 2447 1.10 sommerfe if ((*sc->sc_enable)(sc) != 0) { 2448 1.89 thorpej log(LOG_ERR, "%s: device enable failed\n", 2449 1.114 joerg device_xname(sc->sc_dev)); 2450 1.10 sommerfe return (EIO); 2451 1.10 sommerfe } 2452 1.10 sommerfe } 2453 1.69 enami 2454 1.10 sommerfe sc->sc_enabled = 1; 2455 1.19 enami return (0); 2456 1.10 sommerfe } 2457 1.10 sommerfe 2458 1.10 sommerfe void 2459 1.46 thorpej fxp_disable(struct fxp_softc *sc) 2460 1.10 sommerfe { 2461 1.19 enami 2462 1.10 sommerfe if (sc->sc_enabled != 0 && sc->sc_disable != NULL) { 2463 1.10 sommerfe (*sc->sc_disable)(sc); 2464 1.10 sommerfe sc->sc_enabled = 0; 2465 1.10 sommerfe } 2466 1.18 joda } 2467 1.18 joda 2468 1.20 enami /* 2469 1.20 enami * fxp_activate: 2470 1.20 enami * 2471 1.20 enami * Handle device activation/deactivation requests. 2472 1.20 enami */ 2473 1.20 enami int 2474 1.114 joerg fxp_activate(device_t self, enum devact act) 2475 1.20 enami { 2476 1.114 joerg struct fxp_softc *sc = device_private(self); 2477 1.20 enami 2478 1.20 enami switch (act) { 2479 1.20 enami case DVACT_DEACTIVATE: 2480 1.20 enami if_deactivate(&sc->sc_ethercom.ec_if); 2481 1.130 dyoung return 0; 2482 1.130 dyoung default: 2483 1.130 dyoung return EOPNOTSUPP; 2484 1.20 enami } 2485 1.20 enami } 2486 1.20 enami 2487 1.20 enami /* 2488 1.20 enami * fxp_detach: 2489 1.20 enami * 2490 1.20 enami * Detach an i82557 interface. 2491 1.20 enami */ 2492 1.18 joda int 2493 1.132 dyoung fxp_detach(struct fxp_softc *sc, int flags) 2494 1.18 joda { 2495 1.18 joda struct ifnet *ifp = &sc->sc_ethercom.ec_if; 2496 1.133 dyoung int i, s; 2497 1.133 dyoung 2498 1.134 dyoung /* Succeed now if there's no work to do. */ 2499 1.134 dyoung if ((sc->sc_flags & FXPF_ATTACHED) == 0) 2500 1.134 dyoung return (0); 2501 1.134 dyoung 2502 1.133 dyoung s = splnet(); 2503 1.133 dyoung /* Stop the interface. Callouts are stopped in it. */ 2504 1.133 dyoung fxp_stop(ifp, 1); 2505 1.133 dyoung splx(s); 2506 1.34 jhawk 2507 1.133 dyoung /* Destroy our callout. */ 2508 1.133 dyoung callout_destroy(&sc->sc_callout); 2509 1.18 joda 2510 1.18 joda if (sc->sc_flags & FXPF_MII) { 2511 1.18 joda /* Detach all PHYs */ 2512 1.18 joda mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY); 2513 1.18 joda } 2514 1.18 joda 2515 1.18 joda rnd_detach_source(&sc->rnd_source); 2516 1.18 joda ether_ifdetach(ifp); 2517 1.18 joda if_detach(ifp); 2518 1.18 joda 2519 1.158 thorpej /* Delete all remaining media. */ 2520 1.158 thorpej ifmedia_fini(&sc->sc_mii.mii_media); 2521 1.158 thorpej 2522 1.18 joda for (i = 0; i < FXP_NRFABUFS; i++) { 2523 1.18 joda bus_dmamap_unload(sc->sc_dmat, sc->sc_rxmaps[i]); 2524 1.18 joda bus_dmamap_destroy(sc->sc_dmat, sc->sc_rxmaps[i]); 2525 1.18 joda } 2526 1.18 joda 2527 1.18 joda for (i = 0; i < FXP_NTXCB; i++) { 2528 1.18 joda bus_dmamap_unload(sc->sc_dmat, FXP_DSTX(sc, i)->txs_dmamap); 2529 1.18 joda bus_dmamap_destroy(sc->sc_dmat, FXP_DSTX(sc, i)->txs_dmamap); 2530 1.18 joda } 2531 1.18 joda 2532 1.18 joda bus_dmamap_unload(sc->sc_dmat, sc->sc_dmamap); 2533 1.18 joda bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmamap); 2534 1.101 christos bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_control_data, 2535 1.19 enami sizeof(struct fxp_control_data)); 2536 1.18 joda bus_dmamem_free(sc->sc_dmat, &sc->sc_cdseg, sc->sc_cdnseg); 2537 1.18 joda 2538 1.18 joda return (0); 2539 1.1 thorpej } 2540