1 1.125 andvar /* $NetBSD: if_ti.c,v 1.125 2024/11/05 22:00:30 andvar Exp $ */ 2 1.1 drochner 3 1.1 drochner /* 4 1.1 drochner * Copyright (c) 1997, 1998, 1999 5 1.1 drochner * Bill Paul <wpaul (at) ctr.columbia.edu>. All rights reserved. 6 1.1 drochner * 7 1.1 drochner * Redistribution and use in source and binary forms, with or without 8 1.1 drochner * modification, are permitted provided that the following conditions 9 1.1 drochner * are met: 10 1.1 drochner * 1. Redistributions of source code must retain the above copyright 11 1.1 drochner * notice, this list of conditions and the following disclaimer. 12 1.1 drochner * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 drochner * notice, this list of conditions and the following disclaimer in the 14 1.1 drochner * documentation and/or other materials provided with the distribution. 15 1.1 drochner * 3. All advertising materials mentioning features or use of this software 16 1.1 drochner * must display the following acknowledgement: 17 1.1 drochner * This product includes software developed by Bill Paul. 18 1.1 drochner * 4. Neither the name of the author nor the names of any co-contributors 19 1.1 drochner * may be used to endorse or promote products derived from this software 20 1.1 drochner * without specific prior written permission. 21 1.1 drochner * 22 1.1 drochner * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 23 1.1 drochner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 1.1 drochner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 1.1 drochner * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 26 1.1 drochner * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 1.1 drochner * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 1.1 drochner * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 1.1 drochner * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 1.1 drochner * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 1.1 drochner * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 32 1.1 drochner * THE POSSIBILITY OF SUCH DAMAGE. 33 1.1 drochner * 34 1.1 drochner * FreeBSD Id: if_ti.c,v 1.15 1999/08/14 15:45:03 wpaul Exp 35 1.1 drochner */ 36 1.1 drochner 37 1.1 drochner /* 38 1.1 drochner * Alteon Networks Tigon PCI gigabit ethernet driver for FreeBSD. 39 1.1 drochner * Manuals, sample driver and firmware source kits are available 40 1.1 drochner * from http://www.alteon.com/support/openkits. 41 1.66 perry * 42 1.1 drochner * Written by Bill Paul <wpaul (at) ctr.columbia.edu> 43 1.1 drochner * Electrical Engineering Department 44 1.1 drochner * Columbia University, New York City 45 1.1 drochner */ 46 1.1 drochner 47 1.1 drochner /* 48 1.1 drochner * The Alteon Networks Tigon chip contains an embedded R4000 CPU, 49 1.1 drochner * gigabit MAC, dual DMA channels and a PCI interface unit. NICs 50 1.1 drochner * using the Tigon may have anywhere from 512K to 2MB of SRAM. The 51 1.125 andvar * Tigon supports hardware IP, TCP and UDP checksumming, multicast 52 1.1 drochner * filtering and jumbo (9014 byte) frames. The hardware is largely 53 1.1 drochner * controlled by firmware, which must be loaded into the NIC during 54 1.1 drochner * initialization. 55 1.1 drochner * 56 1.1 drochner * The Tigon 2 contains 2 R4000 CPUs and requires a newer firmware 57 1.1 drochner * revision, which supports new features such as extended commands, 58 1.122 msaitoh * extended jumbo receive ring descriptors and a mini receive ring. 59 1.1 drochner * 60 1.1 drochner * Alteon Networks is to be commended for releasing such a vast amount 61 1.1 drochner * of development material for the Tigon NIC without requiring an NDA 62 1.1 drochner * (although they really should have done it a long time ago). With 63 1.1 drochner * any luck, the other vendors will finally wise up and follow Alteon's 64 1.1 drochner * stellar example. 65 1.1 drochner * 66 1.1 drochner * The firmware for the Tigon 1 and 2 NICs is compiled directly into 67 1.1 drochner * this driver by #including it as a C header file. This bloats the 68 1.1 drochner * driver somewhat, but it's the easiest method considering that the 69 1.1 drochner * driver code and firmware code need to be kept in sync. The source 70 1.1 drochner * for the firmware is not provided with the FreeBSD distribution since 71 1.1 drochner * compiling it requires a GNU toolchain targeted for mips-sgi-irix5.3. 72 1.1 drochner * 73 1.1 drochner * The following people deserve special thanks: 74 1.1 drochner * - Terry Murphy of 3Com, for providing a 3c985 Tigon 1 board 75 1.1 drochner * for testing 76 1.1 drochner * - Raymond Lee of Netgear, for providing a pair of Netgear 77 1.1 drochner * GA620 Tigon 2 boards for testing 78 1.3 thorpej * - Ulf Zimmermann, for bringing the GA620 to my attention and 79 1.1 drochner * convincing me to write this driver. 80 1.1 drochner * - Andrew Gallatin for providing FreeBSD/Alpha support. 81 1.1 drochner */ 82 1.43 lukem 83 1.43 lukem #include <sys/cdefs.h> 84 1.125 andvar __KERNEL_RCSID(0, "$NetBSD: if_ti.c,v 1.125 2024/11/05 22:00:30 andvar Exp $"); 85 1.1 drochner 86 1.1 drochner #include "opt_inet.h" 87 1.1 drochner 88 1.1 drochner #include <sys/param.h> 89 1.1 drochner #include <sys/systm.h> 90 1.1 drochner #include <sys/sockio.h> 91 1.1 drochner #include <sys/mbuf.h> 92 1.1 drochner #include <sys/malloc.h> 93 1.1 drochner #include <sys/kernel.h> 94 1.1 drochner #include <sys/socket.h> 95 1.1 drochner #include <sys/queue.h> 96 1.1 drochner #include <sys/device.h> 97 1.9 jdolecek #include <sys/reboot.h> 98 1.1 drochner 99 1.1 drochner #include <net/if.h> 100 1.1 drochner #include <net/if_arp.h> 101 1.1 drochner #include <net/if_ether.h> 102 1.1 drochner #include <net/if_dl.h> 103 1.1 drochner #include <net/if_media.h> 104 1.1 drochner 105 1.1 drochner #include <net/bpf.h> 106 1.1 drochner 107 1.1 drochner #ifdef INET 108 1.1 drochner #include <netinet/in.h> 109 1.1 drochner #include <netinet/if_inarp.h> 110 1.21 thorpej #include <netinet/in_systm.h> 111 1.21 thorpej #include <netinet/ip.h> 112 1.1 drochner #endif 113 1.1 drochner 114 1.2 drochner 115 1.78 ad #include <sys/bus.h> 116 1.1 drochner 117 1.1 drochner #include <dev/pci/pcireg.h> 118 1.1 drochner #include <dev/pci/pcivar.h> 119 1.1 drochner #include <dev/pci/pcidevs.h> 120 1.1 drochner 121 1.1 drochner #include <dev/pci/if_tireg.h> 122 1.28 thorpej 123 1.28 thorpej #include <dev/microcode/tigon/ti_fw.h> 124 1.28 thorpej #include <dev/microcode/tigon/ti_fw2.h> 125 1.1 drochner 126 1.1 drochner /* 127 1.1 drochner * Various supported device vendors/types and their names. 128 1.1 drochner */ 129 1.1 drochner 130 1.19 jdolecek static const struct ti_type ti_devs[] = { 131 1.1 drochner { PCI_VENDOR_ALTEON, PCI_PRODUCT_ALTEON_ACENIC, 132 1.37 thorpej "Alteon AceNIC 1000BASE-SX Ethernet" }, 133 1.15 bouyer { PCI_VENDOR_ALTEON, PCI_PRODUCT_ALTEON_ACENIC_COPPER, 134 1.37 thorpej "Alteon AceNIC 1000BASE-T Ethernet" }, 135 1.1 drochner { PCI_VENDOR_3COM, PCI_PRODUCT_3COM_3C985, 136 1.1 drochner "3Com 3c985-SX Gigabit Ethernet" }, 137 1.1 drochner { PCI_VENDOR_NETGEAR, PCI_PRODUCT_NETGEAR_GA620, 138 1.37 thorpej "Netgear GA620 1000BASE-SX Ethernet" }, 139 1.15 bouyer { PCI_VENDOR_NETGEAR, PCI_PRODUCT_NETGEAR_GA620T, 140 1.37 thorpej "Netgear GA620 1000BASE-T Ethernet" }, 141 1.1 drochner { PCI_VENDOR_SGI, PCI_PRODUCT_SGI_TIGON, 142 1.1 drochner "Silicon Graphics Gigabit Ethernet" }, 143 1.120 msaitoh { PCI_VENDOR_DEC, PCI_PRODUCT_DEC_PN9000SX, 144 1.120 msaitoh "Farallon PN9000SX Gigabit Ethernet" }, 145 1.1 drochner { 0, 0, NULL } 146 1.1 drochner }; 147 1.1 drochner 148 1.64 perry static const struct ti_type *ti_type_match(struct pci_attach_args *); 149 1.84 cegger static int ti_probe(device_t, cfdata_t, void *); 150 1.84 cegger static void ti_attach(device_t, device_t, void *); 151 1.86 tsutsui static bool ti_shutdown(device_t, int); 152 1.64 perry static void ti_txeof_tigon1(struct ti_softc *); 153 1.64 perry static void ti_txeof_tigon2(struct ti_softc *); 154 1.64 perry static void ti_rxeof(struct ti_softc *); 155 1.64 perry 156 1.64 perry static void ti_stats_update(struct ti_softc *); 157 1.108 msaitoh static int ti_encap_tigon1(struct ti_softc *, struct mbuf *, uint32_t *); 158 1.108 msaitoh static int ti_encap_tigon2(struct ti_softc *, struct mbuf *, uint32_t *); 159 1.64 perry 160 1.64 perry static int ti_intr(void *); 161 1.64 perry static void ti_start(struct ifnet *); 162 1.74 christos static int ti_ioctl(struct ifnet *, u_long, void *); 163 1.64 perry static void ti_init(void *); 164 1.64 perry static void ti_init2(struct ti_softc *); 165 1.64 perry static void ti_stop(struct ti_softc *); 166 1.64 perry static void ti_watchdog(struct ifnet *); 167 1.64 perry static int ti_ifmedia_upd(struct ifnet *); 168 1.64 perry static void ti_ifmedia_sts(struct ifnet *, struct ifmediareq *); 169 1.64 perry 170 1.108 msaitoh static uint32_t ti_eeprom_putbyte(struct ti_softc *, int); 171 1.108 msaitoh static uint8_t ti_eeprom_getbyte(struct ti_softc *, int, uint8_t *); 172 1.74 christos static int ti_read_eeprom(struct ti_softc *, void *, int, int); 173 1.64 perry 174 1.64 perry static void ti_add_mcast(struct ti_softc *, struct ether_addr *); 175 1.64 perry static void ti_del_mcast(struct ti_softc *, struct ether_addr *); 176 1.64 perry static void ti_setmulti(struct ti_softc *); 177 1.64 perry 178 1.108 msaitoh static void ti_mem(struct ti_softc *, uint32_t, uint32_t, const void *); 179 1.64 perry static void ti_loadfw(struct ti_softc *); 180 1.64 perry static void ti_cmd(struct ti_softc *, struct ti_cmd_desc *); 181 1.74 christos static void ti_cmd_ext(struct ti_softc *, struct ti_cmd_desc *, void *, int); 182 1.64 perry static void ti_handle_events(struct ti_softc *); 183 1.64 perry static int ti_alloc_jumbo_mem(struct ti_softc *); 184 1.64 perry static void *ti_jalloc(struct ti_softc *); 185 1.74 christos static void ti_jfree(struct mbuf *, void *, size_t, void *); 186 1.64 perry static int ti_newbuf_std(struct ti_softc *, int, struct mbuf *, bus_dmamap_t); 187 1.64 perry static int ti_newbuf_mini(struct ti_softc *, int, struct mbuf *, bus_dmamap_t); 188 1.64 perry static int ti_newbuf_jumbo(struct ti_softc *, int, struct mbuf *); 189 1.64 perry static int ti_init_rx_ring_std(struct ti_softc *); 190 1.64 perry static void ti_free_rx_ring_std(struct ti_softc *); 191 1.64 perry static int ti_init_rx_ring_jumbo(struct ti_softc *); 192 1.64 perry static void ti_free_rx_ring_jumbo(struct ti_softc *); 193 1.64 perry static int ti_init_rx_ring_mini(struct ti_softc *); 194 1.64 perry static void ti_free_rx_ring_mini(struct ti_softc *); 195 1.64 perry static void ti_free_tx_ring(struct ti_softc *); 196 1.64 perry static int ti_init_tx_ring(struct ti_softc *); 197 1.64 perry 198 1.64 perry static int ti_64bitslot_war(struct ti_softc *); 199 1.64 perry static int ti_chipinit(struct ti_softc *); 200 1.64 perry static int ti_gibinit(struct ti_softc *); 201 1.1 drochner 202 1.74 christos static int ti_ether_ioctl(struct ifnet *, u_long, void *); 203 1.1 drochner 204 1.91 chs CFATTACH_DECL_NEW(ti, sizeof(struct ti_softc), 205 1.52 thorpej ti_probe, ti_attach, NULL, NULL); 206 1.1 drochner 207 1.1 drochner /* 208 1.1 drochner * Send an instruction or address to the EEPROM, check for ACK. 209 1.1 drochner */ 210 1.108 msaitoh static uint32_t 211 1.77 tnn ti_eeprom_putbyte(struct ti_softc *sc, int byte) 212 1.1 drochner { 213 1.64 perry int i, ack = 0; 214 1.1 drochner 215 1.1 drochner /* 216 1.1 drochner * Make sure we're in TX mode. 217 1.1 drochner */ 218 1.1 drochner TI_SETBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_TXEN); 219 1.1 drochner 220 1.1 drochner /* 221 1.118 msaitoh * Feed in each bit and strobe the clock. 222 1.1 drochner */ 223 1.1 drochner for (i = 0x80; i; i >>= 1) { 224 1.1 drochner if (byte & i) { 225 1.1 drochner TI_SETBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_DOUT); 226 1.1 drochner } else { 227 1.1 drochner TI_CLRBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_DOUT); 228 1.1 drochner } 229 1.1 drochner DELAY(1); 230 1.1 drochner TI_SETBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_CLK); 231 1.1 drochner DELAY(1); 232 1.1 drochner TI_CLRBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_CLK); 233 1.1 drochner } 234 1.1 drochner 235 1.1 drochner /* 236 1.1 drochner * Turn off TX mode. 237 1.1 drochner */ 238 1.1 drochner TI_CLRBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_TXEN); 239 1.1 drochner 240 1.1 drochner /* 241 1.1 drochner * Check for ack. 242 1.1 drochner */ 243 1.1 drochner TI_SETBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_CLK); 244 1.1 drochner ack = CSR_READ_4(sc, TI_MISC_LOCAL_CTL) & TI_MLC_EE_DIN; 245 1.1 drochner TI_CLRBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_CLK); 246 1.1 drochner 247 1.77 tnn return (ack); 248 1.1 drochner } 249 1.1 drochner 250 1.1 drochner /* 251 1.1 drochner * Read a byte of data stored in the EEPROM at address 'addr.' 252 1.1 drochner * We have to send two address bytes since the EEPROM can hold 253 1.1 drochner * more than 256 bytes of data. 254 1.1 drochner */ 255 1.108 msaitoh static uint8_t 256 1.108 msaitoh ti_eeprom_getbyte(struct ti_softc *sc, int addr, uint8_t *dest) 257 1.1 drochner { 258 1.8 augustss int i; 259 1.108 msaitoh uint8_t byte = 0; 260 1.1 drochner 261 1.77 tnn EEPROM_START(); 262 1.1 drochner 263 1.1 drochner /* 264 1.1 drochner * Send write control code to EEPROM. 265 1.1 drochner */ 266 1.1 drochner if (ti_eeprom_putbyte(sc, EEPROM_CTL_WRITE)) { 267 1.1 drochner printf("%s: failed to send write command, status: %x\n", 268 1.91 chs device_xname(sc->sc_dev), CSR_READ_4(sc, TI_MISC_LOCAL_CTL)); 269 1.77 tnn return (1); 270 1.1 drochner } 271 1.1 drochner 272 1.1 drochner /* 273 1.1 drochner * Send first byte of address of byte we want to read. 274 1.1 drochner */ 275 1.1 drochner if (ti_eeprom_putbyte(sc, (addr >> 8) & 0xFF)) { 276 1.1 drochner printf("%s: failed to send address, status: %x\n", 277 1.91 chs device_xname(sc->sc_dev), CSR_READ_4(sc, TI_MISC_LOCAL_CTL)); 278 1.77 tnn return (1); 279 1.1 drochner } 280 1.1 drochner /* 281 1.1 drochner * Send second byte address of byte we want to read. 282 1.1 drochner */ 283 1.1 drochner if (ti_eeprom_putbyte(sc, addr & 0xFF)) { 284 1.1 drochner printf("%s: failed to send address, status: %x\n", 285 1.91 chs device_xname(sc->sc_dev), CSR_READ_4(sc, TI_MISC_LOCAL_CTL)); 286 1.77 tnn return (1); 287 1.1 drochner } 288 1.1 drochner 289 1.77 tnn EEPROM_STOP(); 290 1.77 tnn EEPROM_START(); 291 1.1 drochner /* 292 1.1 drochner * Send read control code to EEPROM. 293 1.1 drochner */ 294 1.1 drochner if (ti_eeprom_putbyte(sc, EEPROM_CTL_READ)) { 295 1.1 drochner printf("%s: failed to send read command, status: %x\n", 296 1.91 chs device_xname(sc->sc_dev), CSR_READ_4(sc, TI_MISC_LOCAL_CTL)); 297 1.77 tnn return (1); 298 1.1 drochner } 299 1.1 drochner 300 1.1 drochner /* 301 1.1 drochner * Start reading bits from EEPROM. 302 1.1 drochner */ 303 1.1 drochner TI_CLRBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_TXEN); 304 1.1 drochner for (i = 0x80; i; i >>= 1) { 305 1.1 drochner TI_SETBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_CLK); 306 1.1 drochner DELAY(1); 307 1.1 drochner if (CSR_READ_4(sc, TI_MISC_LOCAL_CTL) & TI_MLC_EE_DIN) 308 1.1 drochner byte |= i; 309 1.1 drochner TI_CLRBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_EE_CLK); 310 1.1 drochner DELAY(1); 311 1.1 drochner } 312 1.1 drochner 313 1.77 tnn EEPROM_STOP(); 314 1.1 drochner 315 1.1 drochner /* 316 1.1 drochner * No ACK generated for read, so just return byte. 317 1.1 drochner */ 318 1.1 drochner 319 1.1 drochner *dest = byte; 320 1.1 drochner 321 1.77 tnn return (0); 322 1.1 drochner } 323 1.1 drochner 324 1.1 drochner /* 325 1.1 drochner * Read a sequence of bytes from the EEPROM. 326 1.1 drochner */ 327 1.77 tnn static int 328 1.77 tnn ti_read_eeprom(struct ti_softc *sc, void *destv, int off, int cnt) 329 1.1 drochner { 330 1.74 christos char *dest = destv; 331 1.74 christos int err = 0, i; 332 1.108 msaitoh uint8_t byte = 0; 333 1.1 drochner 334 1.1 drochner for (i = 0; i < cnt; i++) { 335 1.1 drochner err = ti_eeprom_getbyte(sc, off + i, &byte); 336 1.1 drochner if (err) 337 1.1 drochner break; 338 1.1 drochner *(dest + i) = byte; 339 1.1 drochner } 340 1.1 drochner 341 1.77 tnn return (err ? 1 : 0); 342 1.1 drochner } 343 1.1 drochner 344 1.1 drochner /* 345 1.1 drochner * NIC memory access function. Can be used to either clear a section 346 1.68 christos * of NIC local memory or (if tbuf is non-NULL) copy data into it. 347 1.1 drochner */ 348 1.77 tnn static void 349 1.108 msaitoh ti_mem(struct ti_softc *sc, uint32_t addr, uint32_t len, const void *xbuf) 350 1.1 drochner { 351 1.1 drochner int segptr, segsize, cnt; 352 1.68 christos const void *ptr; 353 1.1 drochner 354 1.1 drochner segptr = addr; 355 1.1 drochner cnt = len; 356 1.68 christos ptr = xbuf; 357 1.1 drochner 358 1.77 tnn while (cnt) { 359 1.1 drochner if (cnt < TI_WINLEN) 360 1.1 drochner segsize = cnt; 361 1.1 drochner else 362 1.1 drochner segsize = TI_WINLEN - (segptr % TI_WINLEN); 363 1.1 drochner CSR_WRITE_4(sc, TI_WINBASE, (segptr & ~(TI_WINLEN - 1))); 364 1.68 christos if (xbuf == NULL) { 365 1.6 bouyer bus_space_set_region_4(sc->ti_btag, sc->ti_bhandle, 366 1.6 bouyer TI_WINDOW + (segptr & (TI_WINLEN - 1)), 0, 367 1.6 bouyer segsize / 4); 368 1.6 bouyer } else { 369 1.60 bouyer #ifdef __BUS_SPACE_HAS_STREAM_METHODS 370 1.60 bouyer bus_space_write_region_stream_4(sc->ti_btag, 371 1.60 bouyer sc->ti_bhandle, 372 1.60 bouyer TI_WINDOW + (segptr & (TI_WINLEN - 1)), 373 1.108 msaitoh (const uint32_t *)ptr, segsize / 4); 374 1.60 bouyer #else 375 1.6 bouyer bus_space_write_region_4(sc->ti_btag, sc->ti_bhandle, 376 1.6 bouyer TI_WINDOW + (segptr & (TI_WINLEN - 1)), 377 1.108 msaitoh (const uint32_t *)ptr, segsize / 4); 378 1.60 bouyer #endif 379 1.68 christos ptr = (const char *)ptr + segsize; 380 1.1 drochner } 381 1.1 drochner segptr += segsize; 382 1.1 drochner cnt -= segsize; 383 1.1 drochner } 384 1.1 drochner 385 1.1 drochner return; 386 1.1 drochner } 387 1.1 drochner 388 1.1 drochner /* 389 1.1 drochner * Load firmware image into the NIC. Check that the firmware revision 390 1.1 drochner * is acceptable and see if we want the firmware for the Tigon 1 or 391 1.1 drochner * Tigon 2. 392 1.1 drochner */ 393 1.77 tnn static void 394 1.77 tnn ti_loadfw(struct ti_softc *sc) 395 1.1 drochner { 396 1.77 tnn switch (sc->ti_hwrev) { 397 1.1 drochner case TI_HWREV_TIGON: 398 1.1 drochner if (tigonFwReleaseMajor != TI_FIRMWARE_MAJOR || 399 1.1 drochner tigonFwReleaseMinor != TI_FIRMWARE_MINOR || 400 1.1 drochner tigonFwReleaseFix != TI_FIRMWARE_FIX) { 401 1.1 drochner printf("%s: firmware revision mismatch; want " 402 1.91 chs "%d.%d.%d, got %d.%d.%d\n", device_xname(sc->sc_dev), 403 1.1 drochner TI_FIRMWARE_MAJOR, TI_FIRMWARE_MINOR, 404 1.1 drochner TI_FIRMWARE_FIX, tigonFwReleaseMajor, 405 1.1 drochner tigonFwReleaseMinor, tigonFwReleaseFix); 406 1.1 drochner return; 407 1.1 drochner } 408 1.68 christos ti_mem(sc, tigonFwTextAddr, tigonFwTextLen, tigonFwText); 409 1.68 christos ti_mem(sc, tigonFwDataAddr, tigonFwDataLen, tigonFwData); 410 1.68 christos ti_mem(sc, tigonFwRodataAddr, tigonFwRodataLen, tigonFwRodata); 411 1.1 drochner ti_mem(sc, tigonFwBssAddr, tigonFwBssLen, NULL); 412 1.1 drochner ti_mem(sc, tigonFwSbssAddr, tigonFwSbssLen, NULL); 413 1.1 drochner CSR_WRITE_4(sc, TI_CPU_PROGRAM_COUNTER, tigonFwStartAddr); 414 1.1 drochner break; 415 1.1 drochner case TI_HWREV_TIGON_II: 416 1.1 drochner if (tigon2FwReleaseMajor != TI_FIRMWARE_MAJOR || 417 1.1 drochner tigon2FwReleaseMinor != TI_FIRMWARE_MINOR || 418 1.1 drochner tigon2FwReleaseFix != TI_FIRMWARE_FIX) { 419 1.1 drochner printf("%s: firmware revision mismatch; want " 420 1.91 chs "%d.%d.%d, got %d.%d.%d\n", device_xname(sc->sc_dev), 421 1.1 drochner TI_FIRMWARE_MAJOR, TI_FIRMWARE_MINOR, 422 1.1 drochner TI_FIRMWARE_FIX, tigon2FwReleaseMajor, 423 1.1 drochner tigon2FwReleaseMinor, tigon2FwReleaseFix); 424 1.1 drochner return; 425 1.1 drochner } 426 1.68 christos ti_mem(sc, tigon2FwTextAddr, tigon2FwTextLen, tigon2FwText); 427 1.68 christos ti_mem(sc, tigon2FwDataAddr, tigon2FwDataLen, tigon2FwData); 428 1.1 drochner ti_mem(sc, tigon2FwRodataAddr, tigon2FwRodataLen, 429 1.68 christos tigon2FwRodata); 430 1.1 drochner ti_mem(sc, tigon2FwBssAddr, tigon2FwBssLen, NULL); 431 1.1 drochner ti_mem(sc, tigon2FwSbssAddr, tigon2FwSbssLen, NULL); 432 1.1 drochner CSR_WRITE_4(sc, TI_CPU_PROGRAM_COUNTER, tigon2FwStartAddr); 433 1.1 drochner break; 434 1.1 drochner default: 435 1.1 drochner printf("%s: can't load firmware: unknown hardware rev\n", 436 1.91 chs device_xname(sc->sc_dev)); 437 1.1 drochner break; 438 1.1 drochner } 439 1.1 drochner 440 1.1 drochner return; 441 1.1 drochner } 442 1.1 drochner 443 1.1 drochner /* 444 1.1 drochner * Send the NIC a command via the command ring. 445 1.1 drochner */ 446 1.77 tnn static void 447 1.77 tnn ti_cmd(struct ti_softc *sc, struct ti_cmd_desc *cmd) 448 1.1 drochner { 449 1.108 msaitoh uint32_t index; 450 1.1 drochner 451 1.1 drochner index = sc->ti_cmd_saved_prodidx; 452 1.108 msaitoh CSR_WRITE_4(sc, TI_GCR_CMDRING + (index * 4), *(uint32_t *)(cmd)); 453 1.1 drochner TI_INC(index, TI_CMD_RING_CNT); 454 1.1 drochner CSR_WRITE_4(sc, TI_MB_CMDPROD_IDX, index); 455 1.1 drochner sc->ti_cmd_saved_prodidx = index; 456 1.1 drochner } 457 1.1 drochner 458 1.1 drochner /* 459 1.1 drochner * Send the NIC an extended command. The 'len' parameter specifies the 460 1.1 drochner * number of command slots to include after the initial command. 461 1.1 drochner */ 462 1.77 tnn static void 463 1.77 tnn ti_cmd_ext(struct ti_softc *sc, struct ti_cmd_desc *cmd, void *argv, int len) 464 1.1 drochner { 465 1.108 msaitoh char *arg = argv; 466 1.108 msaitoh uint32_t index; 467 1.8 augustss int i; 468 1.1 drochner 469 1.1 drochner index = sc->ti_cmd_saved_prodidx; 470 1.108 msaitoh CSR_WRITE_4(sc, TI_GCR_CMDRING + (index * 4), *(uint32_t *)(cmd)); 471 1.1 drochner TI_INC(index, TI_CMD_RING_CNT); 472 1.1 drochner for (i = 0; i < len; i++) { 473 1.1 drochner CSR_WRITE_4(sc, TI_GCR_CMDRING + (index * 4), 474 1.108 msaitoh *(uint32_t *)(&arg[i * 4])); 475 1.1 drochner TI_INC(index, TI_CMD_RING_CNT); 476 1.1 drochner } 477 1.1 drochner CSR_WRITE_4(sc, TI_MB_CMDPROD_IDX, index); 478 1.1 drochner sc->ti_cmd_saved_prodidx = index; 479 1.1 drochner } 480 1.1 drochner 481 1.1 drochner /* 482 1.1 drochner * Handle events that have triggered interrupts. 483 1.1 drochner */ 484 1.77 tnn static void 485 1.77 tnn ti_handle_events(struct ti_softc *sc) 486 1.1 drochner { 487 1.1 drochner struct ti_event_desc *e; 488 1.1 drochner 489 1.1 drochner while (sc->ti_ev_saved_considx != sc->ti_ev_prodidx.ti_idx) { 490 1.1 drochner e = &sc->ti_rdata->ti_event_ring[sc->ti_ev_saved_considx]; 491 1.77 tnn switch (TI_EVENT_EVENT(e)) { 492 1.1 drochner case TI_EV_LINKSTAT_CHANGED: 493 1.77 tnn sc->ti_linkstat = TI_EVENT_CODE(e); 494 1.77 tnn if (sc->ti_linkstat == TI_EV_CODE_LINK_UP) 495 1.1 drochner printf("%s: 10/100 link up\n", 496 1.91 chs device_xname(sc->sc_dev)); 497 1.77 tnn else if (sc->ti_linkstat == TI_EV_CODE_GIG_LINK_UP) 498 1.1 drochner printf("%s: gigabit link up\n", 499 1.91 chs device_xname(sc->sc_dev)); 500 1.77 tnn else if (sc->ti_linkstat == TI_EV_CODE_LINK_DOWN) 501 1.1 drochner printf("%s: link down\n", 502 1.91 chs device_xname(sc->sc_dev)); 503 1.1 drochner break; 504 1.1 drochner case TI_EV_ERROR: 505 1.77 tnn if (TI_EVENT_CODE(e) == TI_EV_CODE_ERR_INVAL_CMD) 506 1.1 drochner printf("%s: invalid command\n", 507 1.91 chs device_xname(sc->sc_dev)); 508 1.77 tnn else if (TI_EVENT_CODE(e) == TI_EV_CODE_ERR_UNIMP_CMD) 509 1.1 drochner printf("%s: unknown command\n", 510 1.91 chs device_xname(sc->sc_dev)); 511 1.77 tnn else if (TI_EVENT_CODE(e) == TI_EV_CODE_ERR_BADCFG) 512 1.1 drochner printf("%s: bad config data\n", 513 1.91 chs device_xname(sc->sc_dev)); 514 1.1 drochner break; 515 1.1 drochner case TI_EV_FIRMWARE_UP: 516 1.1 drochner ti_init2(sc); 517 1.1 drochner break; 518 1.1 drochner case TI_EV_STATS_UPDATED: 519 1.1 drochner ti_stats_update(sc); 520 1.1 drochner break; 521 1.1 drochner case TI_EV_RESET_JUMBO_RING: 522 1.1 drochner case TI_EV_MCAST_UPDATED: 523 1.1 drochner /* Who cares. */ 524 1.1 drochner break; 525 1.1 drochner default: 526 1.1 drochner printf("%s: unknown event: %d\n", 527 1.91 chs device_xname(sc->sc_dev), TI_EVENT_EVENT(e)); 528 1.1 drochner break; 529 1.1 drochner } 530 1.1 drochner /* Advance the consumer index. */ 531 1.1 drochner TI_INC(sc->ti_ev_saved_considx, TI_EVENT_RING_CNT); 532 1.1 drochner CSR_WRITE_4(sc, TI_GCR_EVENTCONS_IDX, sc->ti_ev_saved_considx); 533 1.1 drochner } 534 1.1 drochner 535 1.1 drochner return; 536 1.1 drochner } 537 1.1 drochner 538 1.1 drochner /* 539 1.1 drochner * Memory management for the jumbo receive ring is a pain in the 540 1.1 drochner * butt. We need to allocate at least 9018 bytes of space per frame, 541 1.1 drochner * _and_ it has to be contiguous (unless you use the extended 542 1.1 drochner * jumbo descriptor format). Using malloc() all the time won't 543 1.1 drochner * work: malloc() allocates memory in powers of two, which means we 544 1.1 drochner * would end up wasting a considerable amount of space by allocating 545 1.1 drochner * 9K chunks. We don't have a jumbo mbuf cluster pool. Thus, we have 546 1.1 drochner * to do our own memory management. 547 1.1 drochner * 548 1.1 drochner * The driver needs to allocate a contiguous chunk of memory at boot 549 1.1 drochner * time. We then chop this up ourselves into 9K pieces and use them 550 1.1 drochner * as external mbuf storage. 551 1.1 drochner * 552 1.1 drochner * One issue here is how much memory to allocate. The jumbo ring has 553 1.1 drochner * 256 slots in it, but at 9K per slot than can consume over 2MB of 554 1.1 drochner * RAM. This is a bit much, especially considering we also need 555 1.1 drochner * RAM for the standard ring and mini ring (on the Tigon 2). To 556 1.1 drochner * save space, we only actually allocate enough memory for 64 slots 557 1.1 drochner * by default, which works out to between 500 and 600K. This can 558 1.1 drochner * be tuned by changing a #define in if_tireg.h. 559 1.1 drochner */ 560 1.1 drochner 561 1.77 tnn static int 562 1.77 tnn ti_alloc_jumbo_mem(struct ti_softc *sc) 563 1.1 drochner { 564 1.74 christos char *ptr; 565 1.74 christos int i; 566 1.108 msaitoh struct ti_jpool_entry *entry; 567 1.1 drochner bus_dma_segment_t dmaseg; 568 1.1 drochner int error, dmanseg; 569 1.1 drochner 570 1.1 drochner /* Grab a big chunk o' storage. */ 571 1.1 drochner if ((error = bus_dmamem_alloc(sc->sc_dmat, 572 1.13 thorpej TI_JMEM, PAGE_SIZE, 0, &dmaseg, 1, &dmanseg, 573 1.1 drochner BUS_DMA_NOWAIT)) != 0) { 574 1.99 msaitoh aprint_error_dev(sc->sc_dev, 575 1.99 msaitoh "can't allocate jumbo buffer, error = %d\n", error); 576 1.1 drochner return (error); 577 1.1 drochner } 578 1.1 drochner 579 1.1 drochner if ((error = bus_dmamem_map(sc->sc_dmat, &dmaseg, dmanseg, 580 1.74 christos TI_JMEM, (void **)&sc->ti_cdata.ti_jumbo_buf, 581 1.108 msaitoh BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) { 582 1.99 msaitoh aprint_error_dev(sc->sc_dev, 583 1.99 msaitoh "can't map jumbo buffer, error = %d\n", error); 584 1.1 drochner return (error); 585 1.1 drochner } 586 1.1 drochner 587 1.1 drochner if ((error = bus_dmamap_create(sc->sc_dmat, 588 1.1 drochner TI_JMEM, 1, 589 1.1 drochner TI_JMEM, 0, BUS_DMA_NOWAIT, 590 1.1 drochner &sc->jumbo_dmamap)) != 0) { 591 1.99 msaitoh aprint_error_dev(sc->sc_dev, 592 1.99 msaitoh "can't create jumbo buffer DMA map, error = %d\n", error); 593 1.1 drochner return (error); 594 1.1 drochner } 595 1.1 drochner 596 1.1 drochner if ((error = bus_dmamap_load(sc->sc_dmat, sc->jumbo_dmamap, 597 1.1 drochner sc->ti_cdata.ti_jumbo_buf, TI_JMEM, NULL, 598 1.1 drochner BUS_DMA_NOWAIT)) != 0) { 599 1.99 msaitoh aprint_error_dev(sc->sc_dev, 600 1.99 msaitoh "can't load jumbo buffer DMA map, error = %d\n", error); 601 1.1 drochner return (error); 602 1.1 drochner } 603 1.1 drochner sc->jumbo_dmaaddr = sc->jumbo_dmamap->dm_segs[0].ds_addr; 604 1.1 drochner 605 1.1 drochner SIMPLEQ_INIT(&sc->ti_jfree_listhead); 606 1.1 drochner SIMPLEQ_INIT(&sc->ti_jinuse_listhead); 607 1.1 drochner 608 1.1 drochner /* 609 1.1 drochner * Now divide it up into 9K pieces and save the addresses 610 1.15 bouyer * in an array. 611 1.1 drochner */ 612 1.1 drochner ptr = sc->ti_cdata.ti_jumbo_buf; 613 1.1 drochner for (i = 0; i < TI_JSLOTS; i++) { 614 1.15 bouyer sc->ti_cdata.ti_jslots[i] = ptr; 615 1.15 bouyer ptr += TI_JLEN; 616 1.66 perry entry = malloc(sizeof(struct ti_jpool_entry), 617 1.113 chs M_DEVBUF, M_WAITOK); 618 1.1 drochner entry->slot = i; 619 1.1 drochner SIMPLEQ_INSERT_HEAD(&sc->ti_jfree_listhead, entry, 620 1.1 drochner jpool_entries); 621 1.1 drochner } 622 1.1 drochner 623 1.77 tnn return (0); 624 1.1 drochner } 625 1.1 drochner 626 1.1 drochner /* 627 1.1 drochner * Allocate a jumbo buffer. 628 1.1 drochner */ 629 1.77 tnn static void * 630 1.77 tnn ti_jalloc(struct ti_softc *sc) 631 1.1 drochner { 632 1.108 msaitoh struct ti_jpool_entry *entry; 633 1.66 perry 634 1.1 drochner entry = SIMPLEQ_FIRST(&sc->ti_jfree_listhead); 635 1.66 perry 636 1.1 drochner if (entry == NULL) { 637 1.91 chs printf("%s: no free jumbo buffers\n", device_xname(sc->sc_dev)); 638 1.77 tnn return (NULL); 639 1.1 drochner } 640 1.1 drochner 641 1.48 lukem SIMPLEQ_REMOVE_HEAD(&sc->ti_jfree_listhead, jpool_entries); 642 1.1 drochner SIMPLEQ_INSERT_HEAD(&sc->ti_jinuse_listhead, entry, jpool_entries); 643 1.77 tnn 644 1.77 tnn return (sc->ti_cdata.ti_jslots[entry->slot]); 645 1.1 drochner } 646 1.1 drochner 647 1.1 drochner /* 648 1.1 drochner * Release a jumbo buffer. 649 1.1 drochner */ 650 1.77 tnn static void 651 1.77 tnn ti_jfree(struct mbuf *m, void *tbuf, size_t size, void *arg) 652 1.1 drochner { 653 1.1 drochner struct ti_softc *sc; 654 1.108 msaitoh int i, s; 655 1.108 msaitoh struct ti_jpool_entry *entry; 656 1.1 drochner 657 1.1 drochner /* Extract the softc struct pointer. */ 658 1.15 bouyer sc = (struct ti_softc *)arg; 659 1.1 drochner 660 1.1 drochner if (sc == NULL) 661 1.15 bouyer panic("ti_jfree: didn't get softc pointer!"); 662 1.1 drochner 663 1.1 drochner /* calculate the slot this buffer belongs to */ 664 1.1 drochner 665 1.74 christos i = ((char *)tbuf 666 1.74 christos - (char *)sc->ti_cdata.ti_jumbo_buf) / TI_JLEN; 667 1.1 drochner 668 1.1 drochner if ((i < 0) || (i >= TI_JSLOTS)) 669 1.1 drochner panic("ti_jfree: asked to free buffer that we don't manage!"); 670 1.47 thorpej 671 1.47 thorpej s = splvm(); 672 1.15 bouyer entry = SIMPLEQ_FIRST(&sc->ti_jinuse_listhead); 673 1.15 bouyer if (entry == NULL) 674 1.15 bouyer panic("ti_jfree: buffer not in use!"); 675 1.15 bouyer entry->slot = i; 676 1.48 lukem SIMPLEQ_REMOVE_HEAD(&sc->ti_jinuse_listhead, jpool_entries); 677 1.48 lukem SIMPLEQ_INSERT_HEAD(&sc->ti_jfree_listhead, entry, jpool_entries); 678 1.1 drochner 679 1.47 thorpej if (__predict_true(m != NULL)) 680 1.79 ad pool_cache_put(mb_cache, m); 681 1.47 thorpej splx(s); 682 1.1 drochner } 683 1.1 drochner 684 1.1 drochner 685 1.1 drochner /* 686 1.103 dholland * Initialize a standard receive ring descriptor. 687 1.1 drochner */ 688 1.77 tnn static int 689 1.77 tnn ti_newbuf_std(struct ti_softc *sc, int i, struct mbuf *m, bus_dmamap_t dmamap) 690 1.1 drochner { 691 1.1 drochner struct mbuf *m_new = NULL; 692 1.1 drochner struct ti_rx_desc *r; 693 1.1 drochner int error; 694 1.1 drochner 695 1.1 drochner if (dmamap == NULL) { 696 1.1 drochner /* if (m) panic() */ 697 1.1 drochner 698 1.1 drochner if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, 699 1.1 drochner MCLBYTES, 0, BUS_DMA_NOWAIT, 700 1.1 drochner &dmamap)) != 0) { 701 1.99 msaitoh aprint_error_dev(sc->sc_dev, 702 1.99 msaitoh "can't create recv map, error = %d\n", error); 703 1.77 tnn return (ENOMEM); 704 1.1 drochner } 705 1.1 drochner } 706 1.1 drochner sc->std_dmamap[i] = dmamap; 707 1.1 drochner 708 1.1 drochner if (m == NULL) { 709 1.1 drochner MGETHDR(m_new, M_DONTWAIT, MT_DATA); 710 1.1 drochner if (m_new == NULL) { 711 1.99 msaitoh aprint_error_dev(sc->sc_dev, 712 1.99 msaitoh "mbuf allocation failed -- packet dropped!\n"); 713 1.77 tnn return (ENOBUFS); 714 1.1 drochner } 715 1.1 drochner 716 1.1 drochner MCLGET(m_new, M_DONTWAIT); 717 1.1 drochner if (!(m_new->m_flags & M_EXT)) { 718 1.99 msaitoh aprint_error_dev(sc->sc_dev, 719 1.99 msaitoh "cluster allocation failed -- packet dropped!\n"); 720 1.1 drochner m_freem(m_new); 721 1.77 tnn return (ENOBUFS); 722 1.1 drochner } 723 1.1 drochner m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; 724 1.1 drochner m_adj(m_new, ETHER_ALIGN); 725 1.1 drochner 726 1.1 drochner if ((error = bus_dmamap_load(sc->sc_dmat, dmamap, 727 1.74 christos mtod(m_new, void *), m_new->m_len, NULL, 728 1.108 msaitoh BUS_DMA_READ | BUS_DMA_NOWAIT)) != 0) { 729 1.99 msaitoh aprint_error_dev(sc->sc_dev, 730 1.99 msaitoh "can't load recv map, error = %d\n", error); 731 1.94 christos m_freem(m_new); 732 1.1 drochner return (ENOMEM); 733 1.1 drochner } 734 1.1 drochner } else { 735 1.1 drochner m_new = m; 736 1.1 drochner m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; 737 1.1 drochner m_new->m_data = m_new->m_ext.ext_buf; 738 1.1 drochner m_adj(m_new, ETHER_ALIGN); 739 1.1 drochner 740 1.1 drochner /* reuse the dmamap */ 741 1.1 drochner } 742 1.1 drochner 743 1.1 drochner sc->ti_cdata.ti_rx_std_chain[i] = m_new; 744 1.1 drochner r = &sc->ti_rdata->ti_rx_std_ring[i]; 745 1.121 thorpej TI_HOSTADDR(r->ti_addr) = dmamap->dm_segs[0].ds_addr; 746 1.1 drochner r->ti_type = TI_BDTYPE_RECV_BD; 747 1.1 drochner r->ti_flags = 0; 748 1.67 yamt if (sc->ethercom.ec_if.if_capenable & IFCAP_CSUM_IPv4_Rx) 749 1.21 thorpej r->ti_flags |= TI_BDFLAG_IP_CKSUM; 750 1.21 thorpej if (sc->ethercom.ec_if.if_capenable & 751 1.67 yamt (IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx)) 752 1.21 thorpej r->ti_flags |= TI_BDFLAG_TCP_UDP_CKSUM; 753 1.1 drochner r->ti_len = m_new->m_len; /* == ds_len */ 754 1.1 drochner r->ti_idx = i; 755 1.1 drochner 756 1.77 tnn return (0); 757 1.1 drochner } 758 1.1 drochner 759 1.1 drochner /* 760 1.117 msaitoh * Initialize a mini receive ring descriptor. This only applies to 761 1.1 drochner * the Tigon 2. 762 1.1 drochner */ 763 1.77 tnn static int 764 1.77 tnn ti_newbuf_mini(struct ti_softc *sc, int i, struct mbuf *m, bus_dmamap_t dmamap) 765 1.1 drochner { 766 1.1 drochner struct mbuf *m_new = NULL; 767 1.1 drochner struct ti_rx_desc *r; 768 1.1 drochner int error; 769 1.1 drochner 770 1.1 drochner if (dmamap == NULL) { 771 1.1 drochner /* if (m) panic() */ 772 1.1 drochner 773 1.1 drochner if ((error = bus_dmamap_create(sc->sc_dmat, MHLEN, 1, 774 1.1 drochner MHLEN, 0, BUS_DMA_NOWAIT, 775 1.1 drochner &dmamap)) != 0) { 776 1.99 msaitoh aprint_error_dev(sc->sc_dev, 777 1.99 msaitoh "can't create recv map, error = %d\n", error); 778 1.77 tnn return (ENOMEM); 779 1.1 drochner } 780 1.1 drochner } 781 1.1 drochner sc->mini_dmamap[i] = dmamap; 782 1.1 drochner 783 1.1 drochner if (m == NULL) { 784 1.1 drochner MGETHDR(m_new, M_DONTWAIT, MT_DATA); 785 1.1 drochner if (m_new == NULL) { 786 1.99 msaitoh aprint_error_dev(sc->sc_dev, 787 1.99 msaitoh "mbuf allocation failed -- packet dropped!\n"); 788 1.77 tnn return (ENOBUFS); 789 1.1 drochner } 790 1.1 drochner m_new->m_len = m_new->m_pkthdr.len = MHLEN; 791 1.1 drochner m_adj(m_new, ETHER_ALIGN); 792 1.1 drochner 793 1.1 drochner if ((error = bus_dmamap_load(sc->sc_dmat, dmamap, 794 1.74 christos mtod(m_new, void *), m_new->m_len, NULL, 795 1.108 msaitoh BUS_DMA_READ | BUS_DMA_NOWAIT)) != 0) { 796 1.99 msaitoh aprint_error_dev(sc->sc_dev, 797 1.99 msaitoh "can't load recv map, error = %d\n", error); 798 1.95 maxv m_freem(m_new); 799 1.1 drochner return (ENOMEM); 800 1.1 drochner } 801 1.1 drochner } else { 802 1.1 drochner m_new = m; 803 1.1 drochner m_new->m_data = m_new->m_pktdat; 804 1.1 drochner m_new->m_len = m_new->m_pkthdr.len = MHLEN; 805 1.1 drochner m_adj(m_new, ETHER_ALIGN); 806 1.1 drochner 807 1.1 drochner /* reuse the dmamap */ 808 1.1 drochner } 809 1.1 drochner 810 1.1 drochner r = &sc->ti_rdata->ti_rx_mini_ring[i]; 811 1.1 drochner sc->ti_cdata.ti_rx_mini_chain[i] = m_new; 812 1.121 thorpej TI_HOSTADDR(r->ti_addr) = dmamap->dm_segs[0].ds_addr; 813 1.1 drochner r->ti_type = TI_BDTYPE_RECV_BD; 814 1.1 drochner r->ti_flags = TI_BDFLAG_MINI_RING; 815 1.67 yamt if (sc->ethercom.ec_if.if_capenable & IFCAP_CSUM_IPv4_Rx) 816 1.21 thorpej r->ti_flags |= TI_BDFLAG_IP_CKSUM; 817 1.21 thorpej if (sc->ethercom.ec_if.if_capenable & 818 1.67 yamt (IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx)) 819 1.21 thorpej r->ti_flags |= TI_BDFLAG_TCP_UDP_CKSUM; 820 1.1 drochner r->ti_len = m_new->m_len; /* == ds_len */ 821 1.1 drochner r->ti_idx = i; 822 1.1 drochner 823 1.77 tnn return (0); 824 1.1 drochner } 825 1.1 drochner 826 1.1 drochner /* 827 1.1 drochner * Initialize a jumbo receive ring descriptor. This allocates 828 1.1 drochner * a jumbo buffer from the pool managed internally by the driver. 829 1.1 drochner */ 830 1.77 tnn static int 831 1.77 tnn ti_newbuf_jumbo(struct ti_softc *sc, int i, struct mbuf *m) 832 1.1 drochner { 833 1.1 drochner struct mbuf *m_new = NULL; 834 1.1 drochner struct ti_rx_desc *r; 835 1.1 drochner 836 1.1 drochner if (m == NULL) { 837 1.108 msaitoh void * tbuf = NULL; 838 1.1 drochner 839 1.1 drochner /* Allocate the mbuf. */ 840 1.1 drochner MGETHDR(m_new, M_DONTWAIT, MT_DATA); 841 1.1 drochner if (m_new == NULL) { 842 1.99 msaitoh aprint_error_dev(sc->sc_dev, 843 1.99 msaitoh "mbuf allocation failed -- packet dropped!\n"); 844 1.77 tnn return (ENOBUFS); 845 1.1 drochner } 846 1.1 drochner 847 1.1 drochner /* Allocate the jumbo buffer */ 848 1.68 christos tbuf = ti_jalloc(sc); 849 1.68 christos if (tbuf == NULL) { 850 1.1 drochner m_freem(m_new); 851 1.99 msaitoh aprint_error_dev(sc->sc_dev, 852 1.99 msaitoh "jumbo allocation failed -- packet dropped!\n"); 853 1.77 tnn return (ENOBUFS); 854 1.1 drochner } 855 1.1 drochner 856 1.1 drochner /* Attach the buffer to the mbuf. */ 857 1.68 christos MEXTADD(m_new, tbuf, ETHER_MAX_LEN_JUMBO, 858 1.46 thorpej M_DEVBUF, ti_jfree, sc); 859 1.62 yamt m_new->m_flags |= M_EXT_RW; 860 1.46 thorpej m_new->m_len = m_new->m_pkthdr.len = ETHER_MAX_LEN_JUMBO; 861 1.1 drochner } else { 862 1.1 drochner m_new = m; 863 1.1 drochner m_new->m_data = m_new->m_ext.ext_buf; 864 1.22 thorpej m_new->m_ext.ext_size = ETHER_MAX_LEN_JUMBO; 865 1.1 drochner } 866 1.1 drochner 867 1.1 drochner m_adj(m_new, ETHER_ALIGN); 868 1.1 drochner /* Set up the descriptor. */ 869 1.1 drochner r = &sc->ti_rdata->ti_rx_jumbo_ring[i]; 870 1.1 drochner sc->ti_cdata.ti_rx_jumbo_chain[i] = m_new; 871 1.121 thorpej TI_HOSTADDR(r->ti_addr) = sc->jumbo_dmaaddr + 872 1.121 thorpej (mtod(m_new, char *) - (char *)sc->ti_cdata.ti_jumbo_buf); 873 1.1 drochner r->ti_type = TI_BDTYPE_RECV_JUMBO_BD; 874 1.1 drochner r->ti_flags = TI_BDFLAG_JUMBO_RING; 875 1.67 yamt if (sc->ethercom.ec_if.if_capenable & IFCAP_CSUM_IPv4_Rx) 876 1.21 thorpej r->ti_flags |= TI_BDFLAG_IP_CKSUM; 877 1.21 thorpej if (sc->ethercom.ec_if.if_capenable & 878 1.67 yamt (IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx)) 879 1.21 thorpej r->ti_flags |= TI_BDFLAG_TCP_UDP_CKSUM; 880 1.1 drochner r->ti_len = m_new->m_len; 881 1.1 drochner r->ti_idx = i; 882 1.1 drochner 883 1.77 tnn return (0); 884 1.1 drochner } 885 1.1 drochner 886 1.1 drochner /* 887 1.1 drochner * The standard receive ring has 512 entries in it. At 2K per mbuf cluster, 888 1.1 drochner * that's 1MB or memory, which is a lot. For now, we fill only the first 889 1.1 drochner * 256 ring entries and hope that our CPU is fast enough to keep up with 890 1.1 drochner * the NIC. 891 1.1 drochner */ 892 1.77 tnn static int 893 1.77 tnn ti_init_rx_ring_std(struct ti_softc *sc) 894 1.1 drochner { 895 1.8 augustss int i; 896 1.1 drochner struct ti_cmd_desc cmd; 897 1.1 drochner 898 1.1 drochner for (i = 0; i < TI_SSLOTS; i++) { 899 1.1 drochner if (ti_newbuf_std(sc, i, NULL, 0) == ENOBUFS) 900 1.77 tnn return (ENOBUFS); 901 1.119 msaitoh } 902 1.1 drochner 903 1.1 drochner TI_UPDATE_STDPROD(sc, i - 1); 904 1.1 drochner sc->ti_std = i - 1; 905 1.1 drochner 906 1.77 tnn return (0); 907 1.1 drochner } 908 1.1 drochner 909 1.77 tnn static void 910 1.77 tnn ti_free_rx_ring_std(struct ti_softc *sc) 911 1.1 drochner { 912 1.8 augustss int i; 913 1.1 drochner 914 1.1 drochner for (i = 0; i < TI_STD_RX_RING_CNT; i++) { 915 1.1 drochner if (sc->ti_cdata.ti_rx_std_chain[i] != NULL) { 916 1.1 drochner /* if (sc->std_dmamap[i] == 0) panic() */ 917 1.1 drochner bus_dmamap_destroy(sc->sc_dmat, sc->std_dmamap[i]); 918 1.1 drochner sc->std_dmamap[i] = 0; 919 1.123 rin 920 1.123 rin m_freem(sc->ti_cdata.ti_rx_std_chain[i]); 921 1.123 rin sc->ti_cdata.ti_rx_std_chain[i] = NULL; 922 1.1 drochner } 923 1.39 thorpej memset((char *)&sc->ti_rdata->ti_rx_std_ring[i], 0, 924 1.1 drochner sizeof(struct ti_rx_desc)); 925 1.1 drochner } 926 1.1 drochner 927 1.1 drochner return; 928 1.1 drochner } 929 1.1 drochner 930 1.77 tnn static int 931 1.77 tnn ti_init_rx_ring_jumbo(struct ti_softc *sc) 932 1.1 drochner { 933 1.8 augustss int i; 934 1.1 drochner struct ti_cmd_desc cmd; 935 1.1 drochner 936 1.61 he for (i = 0; i < TI_JUMBO_RX_RING_CNT; i++) { 937 1.1 drochner if (ti_newbuf_jumbo(sc, i, NULL) == ENOBUFS) 938 1.77 tnn return (ENOBUFS); 939 1.119 msaitoh } 940 1.1 drochner 941 1.1 drochner TI_UPDATE_JUMBOPROD(sc, i - 1); 942 1.1 drochner sc->ti_jumbo = i - 1; 943 1.1 drochner 944 1.77 tnn return (0); 945 1.1 drochner } 946 1.1 drochner 947 1.77 tnn static void 948 1.77 tnn ti_free_rx_ring_jumbo(struct ti_softc *sc) 949 1.1 drochner { 950 1.8 augustss int i; 951 1.1 drochner 952 1.1 drochner for (i = 0; i < TI_JUMBO_RX_RING_CNT; i++) { 953 1.124 rin m_freem(sc->ti_cdata.ti_rx_jumbo_chain[i]); 954 1.124 rin sc->ti_cdata.ti_rx_jumbo_chain[i] = NULL; 955 1.39 thorpej memset((char *)&sc->ti_rdata->ti_rx_jumbo_ring[i], 0, 956 1.1 drochner sizeof(struct ti_rx_desc)); 957 1.1 drochner } 958 1.1 drochner 959 1.1 drochner return; 960 1.1 drochner } 961 1.1 drochner 962 1.77 tnn static int 963 1.77 tnn ti_init_rx_ring_mini(struct ti_softc *sc) 964 1.1 drochner { 965 1.8 augustss int i; 966 1.1 drochner 967 1.1 drochner for (i = 0; i < TI_MSLOTS; i++) { 968 1.1 drochner if (ti_newbuf_mini(sc, i, NULL, 0) == ENOBUFS) 969 1.77 tnn return (ENOBUFS); 970 1.119 msaitoh } 971 1.1 drochner 972 1.1 drochner TI_UPDATE_MINIPROD(sc, i - 1); 973 1.1 drochner sc->ti_mini = i - 1; 974 1.1 drochner 975 1.77 tnn return (0); 976 1.1 drochner } 977 1.1 drochner 978 1.77 tnn static void 979 1.77 tnn ti_free_rx_ring_mini(struct ti_softc *sc) 980 1.1 drochner { 981 1.8 augustss int i; 982 1.1 drochner 983 1.1 drochner for (i = 0; i < TI_MINI_RX_RING_CNT; i++) { 984 1.1 drochner if (sc->ti_cdata.ti_rx_mini_chain[i] != NULL) { 985 1.1 drochner /* if (sc->mini_dmamap[i] == 0) panic() */ 986 1.1 drochner bus_dmamap_destroy(sc->sc_dmat, sc->mini_dmamap[i]); 987 1.1 drochner sc->mini_dmamap[i] = 0; 988 1.123 rin 989 1.123 rin m_freem(sc->ti_cdata.ti_rx_mini_chain[i]); 990 1.123 rin sc->ti_cdata.ti_rx_mini_chain[i] = NULL; 991 1.1 drochner } 992 1.39 thorpej memset((char *)&sc->ti_rdata->ti_rx_mini_ring[i], 0, 993 1.1 drochner sizeof(struct ti_rx_desc)); 994 1.1 drochner } 995 1.1 drochner 996 1.1 drochner return; 997 1.1 drochner } 998 1.1 drochner 999 1.77 tnn static void 1000 1.77 tnn ti_free_tx_ring(struct ti_softc *sc) 1001 1.1 drochner { 1002 1.8 augustss int i; 1003 1.1 drochner struct txdmamap_pool_entry *dma; 1004 1.1 drochner 1005 1.1 drochner for (i = 0; i < TI_TX_RING_CNT; i++) { 1006 1.1 drochner if (sc->ti_cdata.ti_tx_chain[i] != NULL) { 1007 1.123 rin dma = sc->txdma[i]; 1008 1.123 rin KDASSERT(dma != NULL); 1009 1.123 rin bus_dmamap_sync(sc->sc_dmat, dma->dmamap, 0, 1010 1.123 rin dma->dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE); 1011 1.123 rin bus_dmamap_unload(sc->sc_dmat, dma->dmamap); 1012 1.1 drochner 1013 1.1 drochner SIMPLEQ_INSERT_HEAD(&sc->txdma_list, sc->txdma[i], 1014 1.1 drochner link); 1015 1.123 rin sc->txdma[i] = NULL; 1016 1.123 rin 1017 1.123 rin m_freem(sc->ti_cdata.ti_tx_chain[i]); 1018 1.123 rin sc->ti_cdata.ti_tx_chain[i] = NULL; 1019 1.1 drochner } 1020 1.39 thorpej memset((char *)&sc->ti_rdata->ti_tx_ring[i], 0, 1021 1.1 drochner sizeof(struct ti_tx_desc)); 1022 1.1 drochner } 1023 1.1 drochner 1024 1.1 drochner while ((dma = SIMPLEQ_FIRST(&sc->txdma_list))) { 1025 1.48 lukem SIMPLEQ_REMOVE_HEAD(&sc->txdma_list, link); 1026 1.1 drochner bus_dmamap_destroy(sc->sc_dmat, dma->dmamap); 1027 1.1 drochner free(dma, M_DEVBUF); 1028 1.1 drochner } 1029 1.1 drochner 1030 1.1 drochner return; 1031 1.1 drochner } 1032 1.1 drochner 1033 1.77 tnn static int 1034 1.77 tnn ti_init_tx_ring(struct ti_softc *sc) 1035 1.1 drochner { 1036 1.1 drochner int i, error; 1037 1.1 drochner bus_dmamap_t dmamap; 1038 1.1 drochner struct txdmamap_pool_entry *dma; 1039 1.1 drochner 1040 1.1 drochner sc->ti_txcnt = 0; 1041 1.1 drochner sc->ti_tx_saved_considx = 0; 1042 1.1 drochner CSR_WRITE_4(sc, TI_MB_SENDPROD_IDX, 0); 1043 1.1 drochner 1044 1.1 drochner SIMPLEQ_INIT(&sc->txdma_list); 1045 1.1 drochner for (i = 0; i < TI_RSLOTS; i++) { 1046 1.1 drochner /* I've seen mbufs with 30 fragments. */ 1047 1.99 msaitoh if ((error = bus_dmamap_create(sc->sc_dmat, 1048 1.99 msaitoh ETHER_MAX_LEN_JUMBO, 40, ETHER_MAX_LEN_JUMBO, 0, 1049 1.99 msaitoh BUS_DMA_NOWAIT, &dmamap)) != 0) { 1050 1.99 msaitoh aprint_error_dev(sc->sc_dev, 1051 1.99 msaitoh "can't create tx map, error = %d\n", error); 1052 1.77 tnn return (ENOMEM); 1053 1.1 drochner } 1054 1.1 drochner dma = malloc(sizeof(*dma), M_DEVBUF, M_NOWAIT); 1055 1.1 drochner if (!dma) { 1056 1.99 msaitoh aprint_error_dev(sc->sc_dev, 1057 1.99 msaitoh "can't alloc txdmamap_pool_entry\n"); 1058 1.1 drochner bus_dmamap_destroy(sc->sc_dmat, dmamap); 1059 1.1 drochner return (ENOMEM); 1060 1.1 drochner } 1061 1.1 drochner dma->dmamap = dmamap; 1062 1.1 drochner SIMPLEQ_INSERT_HEAD(&sc->txdma_list, dma, link); 1063 1.1 drochner } 1064 1.1 drochner 1065 1.77 tnn return (0); 1066 1.1 drochner } 1067 1.1 drochner 1068 1.1 drochner /* 1069 1.1 drochner * The Tigon 2 firmware has a new way to add/delete multicast addresses, 1070 1.1 drochner * but we have to support the old way too so that Tigon 1 cards will 1071 1.1 drochner * work. 1072 1.1 drochner */ 1073 1.77 tnn static void 1074 1.77 tnn ti_add_mcast(struct ti_softc *sc, struct ether_addr *addr) 1075 1.1 drochner { 1076 1.1 drochner struct ti_cmd_desc cmd; 1077 1.108 msaitoh uint16_t *m; 1078 1.108 msaitoh uint32_t ext[2] = {0, 0}; 1079 1.1 drochner 1080 1.108 msaitoh m = (uint16_t *)&addr->ether_addr_octet[0]; /* XXX */ 1081 1.1 drochner 1082 1.77 tnn switch (sc->ti_hwrev) { 1083 1.1 drochner case TI_HWREV_TIGON: 1084 1.1 drochner CSR_WRITE_4(sc, TI_GCR_MAR0, htons(m[0])); 1085 1.1 drochner CSR_WRITE_4(sc, TI_GCR_MAR1, (htons(m[1]) << 16) | htons(m[2])); 1086 1.1 drochner TI_DO_CMD(TI_CMD_ADD_MCAST_ADDR, 0, 0); 1087 1.1 drochner break; 1088 1.1 drochner case TI_HWREV_TIGON_II: 1089 1.1 drochner ext[0] = htons(m[0]); 1090 1.1 drochner ext[1] = (htons(m[1]) << 16) | htons(m[2]); 1091 1.74 christos TI_DO_CMD_EXT(TI_CMD_EXT_ADD_MCAST, 0, 0, (void *)&ext, 2); 1092 1.1 drochner break; 1093 1.1 drochner default: 1094 1.91 chs printf("%s: unknown hwrev\n", device_xname(sc->sc_dev)); 1095 1.1 drochner break; 1096 1.1 drochner } 1097 1.1 drochner 1098 1.1 drochner return; 1099 1.1 drochner } 1100 1.1 drochner 1101 1.77 tnn static void 1102 1.77 tnn ti_del_mcast(struct ti_softc *sc, struct ether_addr *addr) 1103 1.1 drochner { 1104 1.1 drochner struct ti_cmd_desc cmd; 1105 1.108 msaitoh uint16_t *m; 1106 1.108 msaitoh uint32_t ext[2] = {0, 0}; 1107 1.1 drochner 1108 1.108 msaitoh m = (uint16_t *)&addr->ether_addr_octet[0]; /* XXX */ 1109 1.1 drochner 1110 1.77 tnn switch (sc->ti_hwrev) { 1111 1.1 drochner case TI_HWREV_TIGON: 1112 1.1 drochner CSR_WRITE_4(sc, TI_GCR_MAR0, htons(m[0])); 1113 1.1 drochner CSR_WRITE_4(sc, TI_GCR_MAR1, (htons(m[1]) << 16) | htons(m[2])); 1114 1.1 drochner TI_DO_CMD(TI_CMD_DEL_MCAST_ADDR, 0, 0); 1115 1.1 drochner break; 1116 1.1 drochner case TI_HWREV_TIGON_II: 1117 1.1 drochner ext[0] = htons(m[0]); 1118 1.1 drochner ext[1] = (htons(m[1]) << 16) | htons(m[2]); 1119 1.74 christos TI_DO_CMD_EXT(TI_CMD_EXT_DEL_MCAST, 0, 0, (void *)&ext, 2); 1120 1.1 drochner break; 1121 1.1 drochner default: 1122 1.91 chs printf("%s: unknown hwrev\n", device_xname(sc->sc_dev)); 1123 1.1 drochner break; 1124 1.1 drochner } 1125 1.1 drochner 1126 1.1 drochner return; 1127 1.1 drochner } 1128 1.1 drochner 1129 1.1 drochner /* 1130 1.1 drochner * Configure the Tigon's multicast address filter. 1131 1.1 drochner * 1132 1.1 drochner * The actual multicast table management is a bit of a pain, thanks to 1133 1.1 drochner * slight brain damage on the part of both Alteon and us. With our 1134 1.1 drochner * multicast code, we are only alerted when the multicast address table 1135 1.1 drochner * changes and at that point we only have the current list of addresses: 1136 1.1 drochner * we only know the current state, not the previous state, so we don't 1137 1.1 drochner * actually know what addresses were removed or added. The firmware has 1138 1.1 drochner * state, but we can't get our grubby mits on it, and there is no 'delete 1139 1.1 drochner * all multicast addresses' command. Hence, we have to maintain our own 1140 1.1 drochner * state so we know what addresses have been programmed into the NIC at 1141 1.1 drochner * any given time. 1142 1.1 drochner */ 1143 1.77 tnn static void 1144 1.77 tnn ti_setmulti(struct ti_softc *sc) 1145 1.1 drochner { 1146 1.109 msaitoh struct ethercom *ec = &sc->ethercom; 1147 1.109 msaitoh struct ifnet *ifp = &ec->ec_if; 1148 1.1 drochner struct ti_cmd_desc cmd; 1149 1.1 drochner struct ti_mc_entry *mc; 1150 1.108 msaitoh uint32_t intrs; 1151 1.108 msaitoh struct ether_multi *enm; 1152 1.108 msaitoh struct ether_multistep step; 1153 1.1 drochner 1154 1.1 drochner /* Disable interrupts. */ 1155 1.1 drochner intrs = CSR_READ_4(sc, TI_MB_HOSTINTR); 1156 1.1 drochner CSR_WRITE_4(sc, TI_MB_HOSTINTR, 1); 1157 1.1 drochner 1158 1.1 drochner /* First, zot all the existing filters. */ 1159 1.20 enami while ((mc = SIMPLEQ_FIRST(&sc->ti_mc_listhead)) != NULL) { 1160 1.1 drochner ti_del_mcast(sc, &mc->mc_addr); 1161 1.48 lukem SIMPLEQ_REMOVE_HEAD(&sc->ti_mc_listhead, mc_entries); 1162 1.1 drochner free(mc, M_DEVBUF); 1163 1.1 drochner } 1164 1.1 drochner 1165 1.20 enami /* 1166 1.20 enami * Remember all multicast addresses so that we can delete them 1167 1.20 enami * later. Punt if there is a range of addresses or memory shortage. 1168 1.20 enami */ 1169 1.110 msaitoh ETHER_LOCK(ec); 1170 1.109 msaitoh ETHER_FIRST_MULTI(step, ec, enm); 1171 1.1 drochner while (enm != NULL) { 1172 1.20 enami if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 1173 1.110 msaitoh ETHER_ADDR_LEN) != 0) { 1174 1.110 msaitoh ETHER_UNLOCK(ec); 1175 1.20 enami goto allmulti; 1176 1.110 msaitoh } 1177 1.20 enami if ((mc = malloc(sizeof(struct ti_mc_entry), M_DEVBUF, 1178 1.110 msaitoh M_NOWAIT)) == NULL) { 1179 1.110 msaitoh ETHER_UNLOCK(ec); 1180 1.20 enami goto allmulti; 1181 1.110 msaitoh } 1182 1.20 enami memcpy(&mc->mc_addr, enm->enm_addrlo, ETHER_ADDR_LEN); 1183 1.1 drochner SIMPLEQ_INSERT_HEAD(&sc->ti_mc_listhead, mc, mc_entries); 1184 1.1 drochner ETHER_NEXT_MULTI(step, enm); 1185 1.1 drochner } 1186 1.110 msaitoh ETHER_UNLOCK(ec); 1187 1.1 drochner 1188 1.20 enami /* Accept only programmed multicast addresses */ 1189 1.20 enami ifp->if_flags &= ~IFF_ALLMULTI; 1190 1.20 enami TI_DO_CMD(TI_CMD_SET_ALLMULTI, TI_CMD_CODE_ALLMULTI_DIS, 0); 1191 1.20 enami 1192 1.20 enami /* Now program new ones. */ 1193 1.48 lukem SIMPLEQ_FOREACH(mc, &sc->ti_mc_listhead, mc_entries) 1194 1.20 enami ti_add_mcast(sc, &mc->mc_addr); 1195 1.20 enami 1196 1.1 drochner /* Re-enable interrupts. */ 1197 1.1 drochner CSR_WRITE_4(sc, TI_MB_HOSTINTR, intrs); 1198 1.1 drochner 1199 1.1 drochner return; 1200 1.20 enami 1201 1.20 enami allmulti: 1202 1.20 enami /* No need to keep individual multicast addresses */ 1203 1.20 enami while ((mc = SIMPLEQ_FIRST(&sc->ti_mc_listhead)) != NULL) { 1204 1.48 lukem SIMPLEQ_REMOVE_HEAD(&sc->ti_mc_listhead, mc_entries); 1205 1.20 enami free(mc, M_DEVBUF); 1206 1.20 enami } 1207 1.20 enami 1208 1.20 enami /* Accept all multicast addresses */ 1209 1.20 enami ifp->if_flags |= IFF_ALLMULTI; 1210 1.20 enami TI_DO_CMD(TI_CMD_SET_ALLMULTI, TI_CMD_CODE_ALLMULTI_ENB, 0); 1211 1.20 enami 1212 1.20 enami /* Re-enable interrupts. */ 1213 1.20 enami CSR_WRITE_4(sc, TI_MB_HOSTINTR, intrs); 1214 1.1 drochner } 1215 1.1 drochner 1216 1.1 drochner /* 1217 1.1 drochner * Check to see if the BIOS has configured us for a 64 bit slot when 1218 1.1 drochner * we aren't actually in one. If we detect this condition, we can work 1219 1.1 drochner * around it on the Tigon 2 by setting a bit in the PCI state register, 1220 1.1 drochner * but for the Tigon 1 we must give up and abort the interface attach. 1221 1.1 drochner */ 1222 1.77 tnn static int 1223 1.77 tnn ti_64bitslot_war(struct ti_softc *sc) 1224 1.1 drochner { 1225 1.1 drochner if (!(CSR_READ_4(sc, TI_PCI_STATE) & TI_PCISTATE_32BIT_BUS)) { 1226 1.1 drochner CSR_WRITE_4(sc, 0x600, 0); 1227 1.1 drochner CSR_WRITE_4(sc, 0x604, 0); 1228 1.1 drochner CSR_WRITE_4(sc, 0x600, 0x5555AAAA); 1229 1.1 drochner if (CSR_READ_4(sc, 0x604) == 0x5555AAAA) { 1230 1.1 drochner if (sc->ti_hwrev == TI_HWREV_TIGON) 1231 1.77 tnn return (EINVAL); 1232 1.1 drochner else { 1233 1.1 drochner TI_SETBIT(sc, TI_PCI_STATE, 1234 1.1 drochner TI_PCISTATE_32BIT_BUS); 1235 1.77 tnn return (0); 1236 1.1 drochner } 1237 1.1 drochner } 1238 1.1 drochner } 1239 1.1 drochner 1240 1.77 tnn return (0); 1241 1.1 drochner } 1242 1.1 drochner 1243 1.1 drochner /* 1244 1.1 drochner * Do endian, PCI and DMA initialization. Also check the on-board ROM 1245 1.1 drochner * self-test results. 1246 1.1 drochner */ 1247 1.77 tnn static int 1248 1.77 tnn ti_chipinit(struct ti_softc *sc) 1249 1.1 drochner { 1250 1.108 msaitoh uint32_t cacheline; 1251 1.108 msaitoh uint32_t pci_writemax = 0; 1252 1.108 msaitoh uint32_t rev; 1253 1.1 drochner 1254 1.1 drochner /* Initialize link to down state. */ 1255 1.1 drochner sc->ti_linkstat = TI_EV_CODE_LINK_DOWN; 1256 1.1 drochner 1257 1.1 drochner /* Set endianness before we access any non-PCI registers. */ 1258 1.1 drochner #if BYTE_ORDER == BIG_ENDIAN 1259 1.1 drochner CSR_WRITE_4(sc, TI_MISC_HOST_CTL, 1260 1.1 drochner TI_MHC_BIGENDIAN_INIT | (TI_MHC_BIGENDIAN_INIT << 24)); 1261 1.1 drochner #else 1262 1.1 drochner CSR_WRITE_4(sc, TI_MISC_HOST_CTL, 1263 1.1 drochner TI_MHC_LITTLEENDIAN_INIT | (TI_MHC_LITTLEENDIAN_INIT << 24)); 1264 1.1 drochner #endif 1265 1.1 drochner 1266 1.1 drochner /* Check the ROM failed bit to see if self-tests passed. */ 1267 1.1 drochner if (CSR_READ_4(sc, TI_CPU_STATE) & TI_CPUSTATE_ROMFAIL) { 1268 1.1 drochner printf("%s: board self-diagnostics failed!\n", 1269 1.91 chs device_xname(sc->sc_dev)); 1270 1.77 tnn return (ENODEV); 1271 1.1 drochner } 1272 1.1 drochner 1273 1.1 drochner /* Halt the CPU. */ 1274 1.1 drochner TI_SETBIT(sc, TI_CPU_STATE, TI_CPUSTATE_HALT); 1275 1.1 drochner 1276 1.1 drochner /* Figure out the hardware revision. */ 1277 1.59 bouyer rev = CSR_READ_4(sc, TI_MISC_HOST_CTL) & TI_MHC_CHIP_REV_MASK; 1278 1.77 tnn switch (rev) { 1279 1.1 drochner case TI_REV_TIGON_I: 1280 1.1 drochner sc->ti_hwrev = TI_HWREV_TIGON; 1281 1.1 drochner break; 1282 1.1 drochner case TI_REV_TIGON_II: 1283 1.1 drochner sc->ti_hwrev = TI_HWREV_TIGON_II; 1284 1.1 drochner break; 1285 1.1 drochner default: 1286 1.59 bouyer printf("%s: unsupported chip revision 0x%x\n", 1287 1.91 chs device_xname(sc->sc_dev), rev); 1288 1.77 tnn return (ENODEV); 1289 1.1 drochner } 1290 1.1 drochner 1291 1.1 drochner /* Do special setup for Tigon 2. */ 1292 1.1 drochner if (sc->ti_hwrev == TI_HWREV_TIGON_II) { 1293 1.1 drochner TI_SETBIT(sc, TI_CPU_CTL_B, TI_CPUSTATE_HALT); 1294 1.1 drochner TI_SETBIT(sc, TI_MISC_LOCAL_CTL, TI_MLC_SRAM_BANK_256K); 1295 1.1 drochner TI_SETBIT(sc, TI_MISC_CONF, TI_MCR_SRAM_SYNCHRONOUS); 1296 1.1 drochner } 1297 1.1 drochner 1298 1.1 drochner /* Set up the PCI state register. */ 1299 1.108 msaitoh CSR_WRITE_4(sc, TI_PCI_STATE, TI_PCI_READ_CMD | TI_PCI_WRITE_CMD); 1300 1.1 drochner if (sc->ti_hwrev == TI_HWREV_TIGON_II) { 1301 1.1 drochner TI_SETBIT(sc, TI_PCI_STATE, TI_PCISTATE_USE_MEM_RD_MULT); 1302 1.1 drochner } 1303 1.1 drochner 1304 1.1 drochner /* Clear the read/write max DMA parameters. */ 1305 1.108 msaitoh TI_CLRBIT(sc, TI_PCI_STATE, 1306 1.108 msaitoh (TI_PCISTATE_WRITE_MAXDMA | TI_PCISTATE_READ_MAXDMA)); 1307 1.1 drochner 1308 1.1 drochner /* Get cache line size. */ 1309 1.1 drochner cacheline = PCI_CACHELINE(CSR_READ_4(sc, PCI_BHLC_REG)); 1310 1.1 drochner 1311 1.1 drochner /* 1312 1.1 drochner * If the system has set enabled the PCI memory write 1313 1.1 drochner * and invalidate command in the command register, set 1314 1.1 drochner * the write max parameter accordingly. This is necessary 1315 1.1 drochner * to use MWI with the Tigon 2. 1316 1.1 drochner */ 1317 1.1 drochner if (CSR_READ_4(sc, PCI_COMMAND_STATUS_REG) 1318 1.1 drochner & PCI_COMMAND_INVALIDATE_ENABLE) { 1319 1.77 tnn switch (cacheline) { 1320 1.1 drochner case 1: 1321 1.1 drochner case 4: 1322 1.1 drochner case 8: 1323 1.1 drochner case 16: 1324 1.1 drochner case 32: 1325 1.1 drochner case 64: 1326 1.1 drochner break; 1327 1.1 drochner default: 1328 1.1 drochner /* Disable PCI memory write and invalidate. */ 1329 1.1 drochner if (bootverbose) 1330 1.1 drochner printf("%s: cache line size %d not " 1331 1.1 drochner "supported; disabling PCI MWI\n", 1332 1.91 chs device_xname(sc->sc_dev), cacheline); 1333 1.1 drochner CSR_WRITE_4(sc, PCI_COMMAND_STATUS_REG, 1334 1.1 drochner CSR_READ_4(sc, PCI_COMMAND_STATUS_REG) 1335 1.1 drochner & ~PCI_COMMAND_INVALIDATE_ENABLE); 1336 1.1 drochner break; 1337 1.1 drochner } 1338 1.1 drochner } 1339 1.1 drochner 1340 1.1 drochner #ifdef __brokenalpha__ 1341 1.1 drochner /* 1342 1.1 drochner * From the Alteon sample driver: 1343 1.1 drochner * Must insure that we do not cross an 8K (bytes) boundary 1344 1.66 perry * for DMA reads. Our highest limit is 1K bytes. This is a 1345 1.66 perry * restriction on some ALPHA platforms with early revision 1346 1.66 perry * 21174 PCI chipsets, such as the AlphaPC 164lx 1347 1.1 drochner */ 1348 1.108 msaitoh TI_SETBIT(sc, TI_PCI_STATE, pci_writemax | TI_PCI_READMAX_1024); 1349 1.1 drochner #else 1350 1.1 drochner TI_SETBIT(sc, TI_PCI_STATE, pci_writemax); 1351 1.1 drochner #endif 1352 1.1 drochner 1353 1.1 drochner /* This sets the min dma param all the way up (0xff). */ 1354 1.1 drochner TI_SETBIT(sc, TI_PCI_STATE, TI_PCISTATE_MINDMA); 1355 1.1 drochner 1356 1.1 drochner /* Configure DMA variables. */ 1357 1.1 drochner #if BYTE_ORDER == BIG_ENDIAN 1358 1.1 drochner CSR_WRITE_4(sc, TI_GCR_OPMODE, TI_OPMODE_BYTESWAP_BD | 1359 1.1 drochner TI_OPMODE_BYTESWAP_DATA | TI_OPMODE_WORDSWAP_BD | 1360 1.1 drochner TI_OPMODE_WARN_ENB | TI_OPMODE_FATAL_ENB | 1361 1.1 drochner TI_OPMODE_DONT_FRAG_JUMBO); 1362 1.1 drochner #else 1363 1.108 msaitoh CSR_WRITE_4(sc, TI_GCR_OPMODE, TI_OPMODE_BYTESWAP_DATA | 1364 1.108 msaitoh TI_OPMODE_WORDSWAP_BD | TI_OPMODE_DONT_FRAG_JUMBO | 1365 1.108 msaitoh TI_OPMODE_WARN_ENB | TI_OPMODE_FATAL_ENB); 1366 1.1 drochner #endif 1367 1.1 drochner 1368 1.1 drochner /* 1369 1.1 drochner * Only allow 1 DMA channel to be active at a time. 1370 1.1 drochner * I don't think this is a good idea, but without it 1371 1.1 drochner * the firmware racks up lots of nicDmaReadRingFull 1372 1.1 drochner * errors. 1373 1.24 bouyer * Incompatible with hardware assisted checksums. 1374 1.1 drochner */ 1375 1.24 bouyer if ((sc->ethercom.ec_if.if_capenable & 1376 1.67 yamt (IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_TCPv4_Rx | 1377 1.67 yamt IFCAP_CSUM_UDPv4_Tx | IFCAP_CSUM_UDPv4_Rx | 1378 1.67 yamt IFCAP_CSUM_IPv4_Tx | IFCAP_CSUM_IPv4_Rx)) == 0) 1379 1.24 bouyer TI_SETBIT(sc, TI_GCR_OPMODE, TI_OPMODE_1_DMA_ACTIVE); 1380 1.1 drochner 1381 1.1 drochner /* Recommended settings from Tigon manual. */ 1382 1.1 drochner CSR_WRITE_4(sc, TI_GCR_DMA_WRITECFG, TI_DMA_STATE_THRESH_8W); 1383 1.1 drochner CSR_WRITE_4(sc, TI_GCR_DMA_READCFG, TI_DMA_STATE_THRESH_8W); 1384 1.1 drochner 1385 1.1 drochner if (ti_64bitslot_war(sc)) { 1386 1.1 drochner printf("%s: bios thinks we're in a 64 bit slot, " 1387 1.91 chs "but we aren't", device_xname(sc->sc_dev)); 1388 1.77 tnn return (EINVAL); 1389 1.1 drochner } 1390 1.1 drochner 1391 1.77 tnn return (0); 1392 1.1 drochner } 1393 1.1 drochner 1394 1.1 drochner /* 1395 1.1 drochner * Initialize the general information block and firmware, and 1396 1.1 drochner * start the CPU(s) running. 1397 1.1 drochner */ 1398 1.77 tnn static int 1399 1.77 tnn ti_gibinit(struct ti_softc *sc) 1400 1.1 drochner { 1401 1.1 drochner struct ti_rcb *rcb; 1402 1.1 drochner int i; 1403 1.1 drochner struct ifnet *ifp; 1404 1.1 drochner 1405 1.1 drochner ifp = &sc->ethercom.ec_if; 1406 1.1 drochner 1407 1.1 drochner /* Disable interrupts for now. */ 1408 1.1 drochner CSR_WRITE_4(sc, TI_MB_HOSTINTR, 1); 1409 1.1 drochner 1410 1.1 drochner /* Tell the chip where to find the general information block. */ 1411 1.1 drochner CSR_WRITE_4(sc, TI_GCR_GENINFO_HI, 0); 1412 1.33 thorpej CSR_WRITE_4(sc, TI_GCR_GENINFO_LO, TI_CDGIBADDR(sc)); 1413 1.1 drochner 1414 1.1 drochner /* Load the firmware into SRAM. */ 1415 1.1 drochner ti_loadfw(sc); 1416 1.1 drochner 1417 1.1 drochner /* Set up the contents of the general info and ring control blocks. */ 1418 1.1 drochner 1419 1.1 drochner /* Set up the event ring and producer pointer. */ 1420 1.1 drochner rcb = &sc->ti_rdata->ti_info.ti_ev_rcb; 1421 1.1 drochner 1422 1.121 thorpej TI_HOSTADDR(rcb->ti_hostaddr) = TI_CDEVENTADDR(sc, 0); 1423 1.1 drochner rcb->ti_flags = 0; 1424 1.121 thorpej TI_HOSTADDR(sc->ti_rdata->ti_info.ti_ev_prodidx_ptr) = 1425 1.121 thorpej TI_CDEVPRODADDR(sc); 1426 1.33 thorpej 1427 1.1 drochner sc->ti_ev_prodidx.ti_idx = 0; 1428 1.1 drochner CSR_WRITE_4(sc, TI_GCR_EVENTCONS_IDX, 0); 1429 1.1 drochner sc->ti_ev_saved_considx = 0; 1430 1.1 drochner 1431 1.1 drochner /* Set up the command ring and producer mailbox. */ 1432 1.1 drochner rcb = &sc->ti_rdata->ti_info.ti_cmd_rcb; 1433 1.1 drochner 1434 1.121 thorpej TI_HOSTADDR(rcb->ti_hostaddr) = TI_GCR_NIC_ADDR(TI_GCR_CMDRING); 1435 1.1 drochner rcb->ti_flags = 0; 1436 1.1 drochner rcb->ti_max_len = 0; 1437 1.1 drochner for (i = 0; i < TI_CMD_RING_CNT; i++) { 1438 1.1 drochner CSR_WRITE_4(sc, TI_GCR_CMDRING + (i * 4), 0); 1439 1.1 drochner } 1440 1.1 drochner CSR_WRITE_4(sc, TI_GCR_CMDCONS_IDX, 0); 1441 1.1 drochner CSR_WRITE_4(sc, TI_MB_CMDPROD_IDX, 0); 1442 1.1 drochner sc->ti_cmd_saved_prodidx = 0; 1443 1.1 drochner 1444 1.1 drochner /* 1445 1.1 drochner * Assign the address of the stats refresh buffer. 1446 1.1 drochner * We re-use the current stats buffer for this to 1447 1.1 drochner * conserve memory. 1448 1.1 drochner */ 1449 1.121 thorpej TI_HOSTADDR(sc->ti_rdata->ti_info.ti_refresh_stats_ptr) = 1450 1.121 thorpej TI_CDSTATSADDR(sc); 1451 1.1 drochner 1452 1.1 drochner /* Set up the standard receive ring. */ 1453 1.1 drochner rcb = &sc->ti_rdata->ti_info.ti_std_rx_rcb; 1454 1.121 thorpej TI_HOSTADDR(rcb->ti_hostaddr) = TI_CDRXSTDADDR(sc, 0); 1455 1.22 thorpej rcb->ti_max_len = ETHER_MAX_LEN; 1456 1.1 drochner rcb->ti_flags = 0; 1457 1.67 yamt if (ifp->if_capenable & IFCAP_CSUM_IPv4_Rx) 1458 1.21 thorpej rcb->ti_flags |= TI_RCB_FLAG_IP_CKSUM; 1459 1.108 msaitoh if (ifp->if_capenable & (IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx)) 1460 1.21 thorpej rcb->ti_flags |= TI_RCB_FLAG_TCP_UDP_CKSUM; 1461 1.65 jdolecek if (VLAN_ATTACHED(&sc->ethercom)) 1462 1.21 thorpej rcb->ti_flags |= TI_RCB_FLAG_VLAN_ASSIST; 1463 1.1 drochner 1464 1.1 drochner /* Set up the jumbo receive ring. */ 1465 1.1 drochner rcb = &sc->ti_rdata->ti_info.ti_jumbo_rx_rcb; 1466 1.121 thorpej TI_HOSTADDR(rcb->ti_hostaddr) = TI_CDRXJUMBOADDR(sc, 0); 1467 1.22 thorpej rcb->ti_max_len = ETHER_MAX_LEN_JUMBO; 1468 1.1 drochner rcb->ti_flags = 0; 1469 1.67 yamt if (ifp->if_capenable & IFCAP_CSUM_IPv4_Rx) 1470 1.21 thorpej rcb->ti_flags |= TI_RCB_FLAG_IP_CKSUM; 1471 1.108 msaitoh if (ifp->if_capenable & (IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx)) 1472 1.21 thorpej rcb->ti_flags |= TI_RCB_FLAG_TCP_UDP_CKSUM; 1473 1.65 jdolecek if (VLAN_ATTACHED(&sc->ethercom)) 1474 1.21 thorpej rcb->ti_flags |= TI_RCB_FLAG_VLAN_ASSIST; 1475 1.1 drochner 1476 1.1 drochner /* 1477 1.1 drochner * Set up the mini ring. Only activated on the 1478 1.1 drochner * Tigon 2 but the slot in the config block is 1479 1.1 drochner * still there on the Tigon 1. 1480 1.1 drochner */ 1481 1.1 drochner rcb = &sc->ti_rdata->ti_info.ti_mini_rx_rcb; 1482 1.121 thorpej TI_HOSTADDR(rcb->ti_hostaddr) = TI_CDRXMINIADDR(sc, 0); 1483 1.2 drochner rcb->ti_max_len = MHLEN - ETHER_ALIGN; 1484 1.1 drochner if (sc->ti_hwrev == TI_HWREV_TIGON) 1485 1.1 drochner rcb->ti_flags = TI_RCB_FLAG_RING_DISABLED; 1486 1.1 drochner else 1487 1.1 drochner rcb->ti_flags = 0; 1488 1.67 yamt if (ifp->if_capenable & IFCAP_CSUM_IPv4_Rx) 1489 1.21 thorpej rcb->ti_flags |= TI_RCB_FLAG_IP_CKSUM; 1490 1.108 msaitoh if (ifp->if_capenable & (IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx)) 1491 1.21 thorpej rcb->ti_flags |= TI_RCB_FLAG_TCP_UDP_CKSUM; 1492 1.65 jdolecek if (VLAN_ATTACHED(&sc->ethercom)) 1493 1.21 thorpej rcb->ti_flags |= TI_RCB_FLAG_VLAN_ASSIST; 1494 1.1 drochner 1495 1.1 drochner /* 1496 1.1 drochner * Set up the receive return ring. 1497 1.1 drochner */ 1498 1.1 drochner rcb = &sc->ti_rdata->ti_info.ti_return_rcb; 1499 1.121 thorpej TI_HOSTADDR(rcb->ti_hostaddr) = TI_CDRXRTNADDR(sc, 0); 1500 1.1 drochner rcb->ti_flags = 0; 1501 1.1 drochner rcb->ti_max_len = TI_RETURN_RING_CNT; 1502 1.121 thorpej TI_HOSTADDR(sc->ti_rdata->ti_info.ti_return_prodidx_ptr) = 1503 1.121 thorpej TI_CDRTNPRODADDR(sc); 1504 1.1 drochner 1505 1.1 drochner /* 1506 1.1 drochner * Set up the tx ring. Note: for the Tigon 2, we have the option 1507 1.1 drochner * of putting the transmit ring in the host's address space and 1508 1.1 drochner * letting the chip DMA it instead of leaving the ring in the NIC's 1509 1.1 drochner * memory and accessing it through the shared memory region. We 1510 1.1 drochner * do this for the Tigon 2, but it doesn't work on the Tigon 1, 1511 1.1 drochner * so we have to revert to the shared memory scheme if we detect 1512 1.1 drochner * a Tigon 1 chip. 1513 1.1 drochner */ 1514 1.1 drochner CSR_WRITE_4(sc, TI_WINBASE, TI_TX_RING_BASE); 1515 1.1 drochner if (sc->ti_hwrev == TI_HWREV_TIGON) { 1516 1.30 thorpej sc->ti_tx_ring_nic = 1517 1.1 drochner (struct ti_tx_desc *)(sc->ti_vhandle + TI_WINDOW); 1518 1.1 drochner } 1519 1.39 thorpej memset((char *)sc->ti_rdata->ti_tx_ring, 0, 1520 1.1 drochner TI_TX_RING_CNT * sizeof(struct ti_tx_desc)); 1521 1.1 drochner rcb = &sc->ti_rdata->ti_info.ti_tx_rcb; 1522 1.1 drochner if (sc->ti_hwrev == TI_HWREV_TIGON) 1523 1.1 drochner rcb->ti_flags = 0; 1524 1.1 drochner else 1525 1.1 drochner rcb->ti_flags = TI_RCB_FLAG_HOST_RING; 1526 1.67 yamt if (ifp->if_capenable & IFCAP_CSUM_IPv4_Tx) 1527 1.21 thorpej rcb->ti_flags |= TI_RCB_FLAG_IP_CKSUM; 1528 1.21 thorpej /* 1529 1.21 thorpej * When we get the packet, there is a pseudo-header seed already 1530 1.21 thorpej * in the th_sum or uh_sum field. Make sure the firmware doesn't 1531 1.21 thorpej * compute the pseudo-header checksum again! 1532 1.21 thorpej */ 1533 1.108 msaitoh if (ifp->if_capenable & (IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_UDPv4_Tx)) 1534 1.108 msaitoh rcb->ti_flags |= TI_RCB_FLAG_TCP_UDP_CKSUM | 1535 1.21 thorpej TI_RCB_FLAG_NO_PHDR_CKSUM; 1536 1.65 jdolecek if (VLAN_ATTACHED(&sc->ethercom)) 1537 1.21 thorpej rcb->ti_flags |= TI_RCB_FLAG_VLAN_ASSIST; 1538 1.1 drochner rcb->ti_max_len = TI_TX_RING_CNT; 1539 1.1 drochner if (sc->ti_hwrev == TI_HWREV_TIGON) 1540 1.121 thorpej TI_HOSTADDR(rcb->ti_hostaddr) = TI_TX_RING_BASE; 1541 1.1 drochner else 1542 1.121 thorpej TI_HOSTADDR(rcb->ti_hostaddr) = TI_CDTXADDR(sc, 0); 1543 1.121 thorpej TI_HOSTADDR(sc->ti_rdata->ti_info.ti_tx_considx_ptr) = 1544 1.121 thorpej TI_CDTXCONSADDR(sc); 1545 1.1 drochner 1546 1.34 thorpej /* 1547 1.34 thorpej * We're done frobbing the General Information Block. Sync 1548 1.34 thorpej * it. Note we take care of the first stats sync here, as 1549 1.34 thorpej * well. 1550 1.34 thorpej */ 1551 1.108 msaitoh TI_CDGIBSYNC(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1552 1.34 thorpej 1553 1.1 drochner /* Set up tuneables */ 1554 1.12 bouyer if (ifp->if_mtu > (ETHERMTU + ETHER_HDR_LEN + ETHER_CRC_LEN) || 1555 1.12 bouyer (sc->ethercom.ec_capenable & ETHERCAP_VLAN_MTU)) 1556 1.1 drochner CSR_WRITE_4(sc, TI_GCR_RX_COAL_TICKS, 1557 1.1 drochner (sc->ti_rx_coal_ticks / 10)); 1558 1.1 drochner else 1559 1.1 drochner CSR_WRITE_4(sc, TI_GCR_RX_COAL_TICKS, sc->ti_rx_coal_ticks); 1560 1.1 drochner CSR_WRITE_4(sc, TI_GCR_TX_COAL_TICKS, sc->ti_tx_coal_ticks); 1561 1.1 drochner CSR_WRITE_4(sc, TI_GCR_STAT_TICKS, sc->ti_stat_ticks); 1562 1.1 drochner CSR_WRITE_4(sc, TI_GCR_RX_MAX_COAL_BD, sc->ti_rx_max_coal_bds); 1563 1.1 drochner CSR_WRITE_4(sc, TI_GCR_TX_MAX_COAL_BD, sc->ti_tx_max_coal_bds); 1564 1.1 drochner CSR_WRITE_4(sc, TI_GCR_TX_BUFFER_RATIO, sc->ti_tx_buf_ratio); 1565 1.1 drochner 1566 1.1 drochner /* Turn interrupts on. */ 1567 1.1 drochner CSR_WRITE_4(sc, TI_GCR_MASK_INTRS, 0); 1568 1.1 drochner CSR_WRITE_4(sc, TI_MB_HOSTINTR, 0); 1569 1.1 drochner 1570 1.1 drochner /* Start CPU. */ 1571 1.108 msaitoh TI_CLRBIT(sc, TI_CPU_STATE, (TI_CPUSTATE_HALT | TI_CPUSTATE_STEP)); 1572 1.1 drochner 1573 1.77 tnn return (0); 1574 1.1 drochner } 1575 1.1 drochner 1576 1.1 drochner /* 1577 1.6 bouyer * look for id in the device list, returning the first match 1578 1.6 bouyer */ 1579 1.19 jdolecek static const struct ti_type * 1580 1.77 tnn ti_type_match(struct pci_attach_args *pa) 1581 1.6 bouyer { 1582 1.108 msaitoh const struct ti_type *t; 1583 1.6 bouyer 1584 1.6 bouyer t = ti_devs; 1585 1.77 tnn while (t->ti_name != NULL) { 1586 1.6 bouyer if ((PCI_VENDOR(pa->pa_id) == t->ti_vid) && 1587 1.6 bouyer (PCI_PRODUCT(pa->pa_id) == t->ti_did)) { 1588 1.6 bouyer return (t); 1589 1.6 bouyer } 1590 1.6 bouyer t++; 1591 1.6 bouyer } 1592 1.6 bouyer 1593 1.77 tnn return (NULL); 1594 1.6 bouyer } 1595 1.6 bouyer 1596 1.6 bouyer /* 1597 1.1 drochner * Probe for a Tigon chip. Check the PCI vendor and device IDs 1598 1.1 drochner * against our list and return its name if we find a match. 1599 1.1 drochner */ 1600 1.72 christos static int 1601 1.84 cegger ti_probe(device_t parent, cfdata_t match, void *aux) 1602 1.1 drochner { 1603 1.108 msaitoh struct pci_attach_args *pa = aux; 1604 1.108 msaitoh const struct ti_type *t; 1605 1.1 drochner 1606 1.6 bouyer t = ti_type_match(pa); 1607 1.1 drochner 1608 1.77 tnn return ((t == NULL) ? 0 : 1); 1609 1.1 drochner } 1610 1.1 drochner 1611 1.72 christos static void 1612 1.84 cegger ti_attach(device_t parent, device_t self, void *aux) 1613 1.1 drochner { 1614 1.108 msaitoh uint32_t command; 1615 1.1 drochner struct ifnet *ifp; 1616 1.1 drochner struct ti_softc *sc; 1617 1.108 msaitoh uint8_t eaddr[ETHER_ADDR_LEN]; 1618 1.1 drochner struct pci_attach_args *pa = aux; 1619 1.1 drochner pci_chipset_tag_t pc = pa->pa_pc; 1620 1.1 drochner pci_intr_handle_t ih; 1621 1.1 drochner const char *intrstr = NULL; 1622 1.1 drochner bus_dma_segment_t dmaseg; 1623 1.6 bouyer int error, dmanseg, nolinear; 1624 1.19 jdolecek const struct ti_type *t; 1625 1.93 christos char intrbuf[PCI_INTRSTR_LEN]; 1626 1.6 bouyer 1627 1.6 bouyer t = ti_type_match(pa); 1628 1.6 bouyer if (t == NULL) { 1629 1.99 msaitoh aprint_error("ti_attach: were did the card go ?\n"); 1630 1.6 bouyer return; 1631 1.6 bouyer } 1632 1.1 drochner 1633 1.99 msaitoh aprint_normal(": %s (rev. 0x%02x)\n", t->ti_name, 1634 1.99 msaitoh PCI_REVISION(pa->pa_class)); 1635 1.1 drochner 1636 1.85 cegger sc = device_private(self); 1637 1.91 chs sc->sc_dev = self; 1638 1.1 drochner 1639 1.1 drochner /* 1640 1.1 drochner * Map control/status registers. 1641 1.1 drochner */ 1642 1.6 bouyer nolinear = 0; 1643 1.6 bouyer if (pci_mapreg_map(pa, 0x10, 1644 1.6 bouyer PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 1645 1.6 bouyer BUS_SPACE_MAP_LINEAR , &sc->ti_btag, &sc->ti_bhandle, 1646 1.6 bouyer NULL, NULL)) { 1647 1.6 bouyer nolinear = 1; 1648 1.6 bouyer if (pci_mapreg_map(pa, 0x10, 1649 1.6 bouyer PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 1650 1.6 bouyer 0 , &sc->ti_btag, &sc->ti_bhandle, NULL, NULL)) { 1651 1.99 msaitoh aprint_error_dev(self, "can't map memory space\n"); 1652 1.6 bouyer return; 1653 1.6 bouyer } 1654 1.1 drochner } 1655 1.6 bouyer if (nolinear == 0) 1656 1.45 eeh sc->ti_vhandle = bus_space_vaddr(sc->ti_btag, sc->ti_bhandle); 1657 1.66 perry else 1658 1.6 bouyer sc->ti_vhandle = NULL; 1659 1.1 drochner 1660 1.1 drochner command = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); 1661 1.1 drochner command |= PCI_COMMAND_MASTER_ENABLE; 1662 1.1 drochner pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, command); 1663 1.1 drochner 1664 1.1 drochner /* Allocate interrupt */ 1665 1.17 sommerfe if (pci_intr_map(pa, &ih)) { 1666 1.91 chs aprint_error_dev(sc->sc_dev, "couldn't map interrupt\n"); 1667 1.54 simonb return; 1668 1.1 drochner } 1669 1.93 christos intrstr = pci_intr_string(pc, ih, intrbuf, sizeof(intrbuf)); 1670 1.106 jdolecek sc->sc_ih = pci_intr_establish_xname(pc, ih, IPL_NET, ti_intr, sc, 1671 1.106 jdolecek device_xname(self)); 1672 1.1 drochner if (sc->sc_ih == NULL) { 1673 1.91 chs aprint_error_dev(sc->sc_dev, "couldn't establish interrupt"); 1674 1.1 drochner if (intrstr != NULL) 1675 1.87 njoly aprint_error(" at %s", intrstr); 1676 1.87 njoly aprint_error("\n"); 1677 1.54 simonb return; 1678 1.1 drochner } 1679 1.91 chs aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr); 1680 1.1 drochner 1681 1.1 drochner if (ti_chipinit(sc)) { 1682 1.81 cegger aprint_error_dev(self, "chip initialization failed\n"); 1683 1.6 bouyer goto fail2; 1684 1.6 bouyer } 1685 1.31 thorpej 1686 1.31 thorpej /* 1687 1.31 thorpej * Deal with some chip diffrences. 1688 1.31 thorpej */ 1689 1.31 thorpej switch (sc->ti_hwrev) { 1690 1.31 thorpej case TI_HWREV_TIGON: 1691 1.31 thorpej sc->sc_tx_encap = ti_encap_tigon1; 1692 1.32 thorpej sc->sc_tx_eof = ti_txeof_tigon1; 1693 1.31 thorpej if (nolinear == 1) 1694 1.98 msaitoh aprint_error_dev(self, 1695 1.98 msaitoh "memory space not mapped linear\n"); 1696 1.31 thorpej break; 1697 1.31 thorpej 1698 1.31 thorpej case TI_HWREV_TIGON_II: 1699 1.31 thorpej sc->sc_tx_encap = ti_encap_tigon2; 1700 1.32 thorpej sc->sc_tx_eof = ti_txeof_tigon2; 1701 1.31 thorpej break; 1702 1.31 thorpej 1703 1.31 thorpej default: 1704 1.99 msaitoh aprint_error_dev(self, "Unknown chip version: %d\n", 1705 1.31 thorpej sc->ti_hwrev); 1706 1.31 thorpej goto fail2; 1707 1.1 drochner } 1708 1.1 drochner 1709 1.1 drochner /* Zero out the NIC's on-board SRAM. */ 1710 1.1 drochner ti_mem(sc, 0x2000, 0x100000 - 0x2000, NULL); 1711 1.1 drochner 1712 1.1 drochner /* Init again -- zeroing memory may have clobbered some registers. */ 1713 1.1 drochner if (ti_chipinit(sc)) { 1714 1.81 cegger aprint_error_dev(self, "chip initialization failed\n"); 1715 1.6 bouyer goto fail2; 1716 1.1 drochner } 1717 1.1 drochner 1718 1.1 drochner /* 1719 1.1 drochner * Get station address from the EEPROM. Note: the manual states 1720 1.1 drochner * that the MAC address is at offset 0x8c, however the data is 1721 1.1 drochner * stored as two longwords (since that's how it's loaded into 1722 1.42 wiz * the NIC). This means the MAC address is actually preceded 1723 1.1 drochner * by two zero bytes. We need to skip over those. 1724 1.1 drochner */ 1725 1.74 christos if (ti_read_eeprom(sc, (void *)&eaddr, 1726 1.1 drochner TI_EE_MAC_OFFSET + 2, ETHER_ADDR_LEN)) { 1727 1.81 cegger aprint_error_dev(self, "failed to read station address\n"); 1728 1.6 bouyer goto fail2; 1729 1.1 drochner } 1730 1.1 drochner 1731 1.1 drochner /* 1732 1.1 drochner * A Tigon chip was detected. Inform the world. 1733 1.1 drochner */ 1734 1.109 msaitoh aprint_normal_dev(self, "Ethernet address %s\n", ether_sprintf(eaddr)); 1735 1.1 drochner 1736 1.121 thorpej sc->sc_dmat = pa->pa_dmat; 1737 1.1 drochner 1738 1.1 drochner /* Allocate the general information block and ring buffers. */ 1739 1.1 drochner if ((error = bus_dmamem_alloc(sc->sc_dmat, 1740 1.13 thorpej sizeof(struct ti_ring_data), PAGE_SIZE, 0, &dmaseg, 1, &dmanseg, 1741 1.1 drochner BUS_DMA_NOWAIT)) != 0) { 1742 1.99 msaitoh aprint_error_dev(self, 1743 1.98 msaitoh "can't allocate ring buffer, error = %d\n", error); 1744 1.6 bouyer goto fail2; 1745 1.1 drochner } 1746 1.1 drochner 1747 1.1 drochner if ((error = bus_dmamem_map(sc->sc_dmat, &dmaseg, dmanseg, 1748 1.74 christos sizeof(struct ti_ring_data), (void **)&sc->ti_rdata, 1749 1.108 msaitoh BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) { 1750 1.99 msaitoh aprint_error_dev(self, 1751 1.98 msaitoh "can't map ring buffer, error = %d\n", error); 1752 1.6 bouyer goto fail2; 1753 1.1 drochner } 1754 1.1 drochner 1755 1.1 drochner if ((error = bus_dmamap_create(sc->sc_dmat, 1756 1.1 drochner sizeof(struct ti_ring_data), 1, 1757 1.1 drochner sizeof(struct ti_ring_data), 0, BUS_DMA_NOWAIT, 1758 1.1 drochner &sc->info_dmamap)) != 0) { 1759 1.99 msaitoh aprint_error_dev(self, 1760 1.98 msaitoh "can't create ring buffer DMA map, error = %d\n", error); 1761 1.6 bouyer goto fail2; 1762 1.1 drochner } 1763 1.1 drochner 1764 1.1 drochner if ((error = bus_dmamap_load(sc->sc_dmat, sc->info_dmamap, 1765 1.1 drochner sc->ti_rdata, sizeof(struct ti_ring_data), NULL, 1766 1.1 drochner BUS_DMA_NOWAIT)) != 0) { 1767 1.99 msaitoh aprint_error_dev(self, 1768 1.98 msaitoh "can't load ring buffer DMA map, error = %d\n", error); 1769 1.6 bouyer goto fail2; 1770 1.1 drochner } 1771 1.1 drochner 1772 1.1 drochner sc->info_dmaaddr = sc->info_dmamap->dm_segs[0].ds_addr; 1773 1.1 drochner 1774 1.39 thorpej memset(sc->ti_rdata, 0, sizeof(struct ti_ring_data)); 1775 1.1 drochner 1776 1.1 drochner /* Try to allocate memory for jumbo buffers. */ 1777 1.1 drochner if (ti_alloc_jumbo_mem(sc)) { 1778 1.81 cegger aprint_error_dev(self, "jumbo buffer allocation failed\n"); 1779 1.6 bouyer goto fail2; 1780 1.1 drochner } 1781 1.1 drochner 1782 1.20 enami SIMPLEQ_INIT(&sc->ti_mc_listhead); 1783 1.20 enami 1784 1.15 bouyer /* 1785 1.36 bjh21 * We really need a better way to tell a 1000baseT card 1786 1.15 bouyer * from a 1000baseSX one, since in theory there could be 1787 1.36 bjh21 * OEMed 1000baseT cards from lame vendors who aren't 1788 1.15 bouyer * clever enough to change the PCI ID. For the moment 1789 1.15 bouyer * though, the AceNIC is the only copper card available. 1790 1.15 bouyer */ 1791 1.15 bouyer if ((PCI_VENDOR(pa->pa_id) == PCI_VENDOR_ALTEON && 1792 1.15 bouyer PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ALTEON_ACENIC_COPPER) || 1793 1.15 bouyer (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_NETGEAR && 1794 1.15 bouyer PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_NETGEAR_GA620T)) 1795 1.15 bouyer sc->ti_copper = 1; 1796 1.15 bouyer else 1797 1.15 bouyer sc->ti_copper = 0; 1798 1.15 bouyer 1799 1.1 drochner /* Set default tuneable values. */ 1800 1.1 drochner sc->ti_stat_ticks = 2 * TI_TICKS_PER_SEC; 1801 1.1 drochner sc->ti_rx_coal_ticks = TI_TICKS_PER_SEC / 5000; 1802 1.1 drochner sc->ti_tx_coal_ticks = TI_TICKS_PER_SEC / 500; 1803 1.1 drochner sc->ti_rx_max_coal_bds = 64; 1804 1.1 drochner sc->ti_tx_max_coal_bds = 128; 1805 1.1 drochner sc->ti_tx_buf_ratio = 21; 1806 1.1 drochner 1807 1.1 drochner /* Set up ifnet structure */ 1808 1.1 drochner ifp = &sc->ethercom.ec_if; 1809 1.1 drochner ifp->if_softc = sc; 1810 1.91 chs strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 1811 1.1 drochner ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 1812 1.1 drochner ifp->if_ioctl = ti_ioctl; 1813 1.1 drochner ifp->if_start = ti_start; 1814 1.1 drochner ifp->if_watchdog = ti_watchdog; 1815 1.16 thorpej IFQ_SET_READY(&ifp->if_snd); 1816 1.16 thorpej 1817 1.16 thorpej #if 0 1818 1.16 thorpej /* 1819 1.16 thorpej * XXX This is not really correct -- we don't necessarily 1820 1.16 thorpej * XXX want to queue up as many as we can transmit at the 1821 1.16 thorpej * XXX upper layer like that. Someone with a board should 1822 1.16 thorpej * XXX check to see how this affects performance. 1823 1.16 thorpej */ 1824 1.1 drochner ifp->if_snd.ifq_maxlen = TI_TX_RING_CNT - 1; 1825 1.16 thorpej #endif 1826 1.1 drochner 1827 1.12 bouyer /* 1828 1.12 bouyer * We can support 802.1Q VLAN-sized frames. 1829 1.12 bouyer */ 1830 1.15 bouyer sc->ethercom.ec_capabilities |= 1831 1.15 bouyer ETHERCAP_VLAN_MTU | ETHERCAP_VLAN_HWTAGGING; 1832 1.112 msaitoh sc->ethercom.ec_capenable |= ETHERCAP_VLAN_HWTAGGING; 1833 1.12 bouyer 1834 1.21 thorpej /* 1835 1.21 thorpej * We can do IPv4, TCPv4, and UDPv4 checksums in hardware. 1836 1.21 thorpej */ 1837 1.67 yamt ifp->if_capabilities |= 1838 1.67 yamt IFCAP_CSUM_IPv4_Tx | IFCAP_CSUM_IPv4_Rx | 1839 1.67 yamt IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_TCPv4_Rx | 1840 1.67 yamt IFCAP_CSUM_UDPv4_Tx | IFCAP_CSUM_UDPv4_Rx; 1841 1.21 thorpej 1842 1.1 drochner /* Set up ifmedia support. */ 1843 1.111 msaitoh sc->ethercom.ec_ifmedia = &sc->ifmedia; 1844 1.1 drochner ifmedia_init(&sc->ifmedia, IFM_IMASK, ti_ifmedia_upd, ti_ifmedia_sts); 1845 1.15 bouyer if (sc->ti_copper) { 1846 1.108 msaitoh /* 1847 1.108 msaitoh * Copper cards allow manual 10/100 mode selection, 1848 1.108 msaitoh * but not manual 1000baseT mode selection. Why? 1849 1.108 msaitoh * Because currently there's no way to specify the 1850 1.108 msaitoh * master/slave setting through the firmware interface, 1851 1.108 msaitoh * so Alteon decided to just bag it and handle it 1852 1.108 msaitoh * via autonegotiation. 1853 1.108 msaitoh */ 1854 1.108 msaitoh ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_10_T, 0, NULL); 1855 1.108 msaitoh ifmedia_add(&sc->ifmedia, 1856 1.108 msaitoh IFM_ETHER | IFM_10_T | IFM_FDX, 0, NULL); 1857 1.108 msaitoh ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_100_TX, 0, NULL); 1858 1.108 msaitoh ifmedia_add(&sc->ifmedia, 1859 1.108 msaitoh IFM_ETHER | IFM_100_TX | IFM_FDX, 0, NULL); 1860 1.108 msaitoh ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_1000_T, 0, NULL); 1861 1.108 msaitoh ifmedia_add(&sc->ifmedia, 1862 1.108 msaitoh IFM_ETHER | IFM_1000_T | IFM_FDX, 0, NULL); 1863 1.15 bouyer } else { 1864 1.15 bouyer /* Fiber cards don't support 10/100 modes. */ 1865 1.108 msaitoh ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_1000_SX, 0, NULL); 1866 1.108 msaitoh ifmedia_add(&sc->ifmedia, 1867 1.108 msaitoh IFM_ETHER | IFM_1000_SX | IFM_FDX, 0, NULL); 1868 1.15 bouyer } 1869 1.108 msaitoh ifmedia_add(&sc->ifmedia, IFM_ETHER | IFM_AUTO, 0, NULL); 1870 1.108 msaitoh ifmedia_set(&sc->ifmedia, IFM_ETHER | IFM_AUTO); 1871 1.1 drochner 1872 1.1 drochner /* 1873 1.1 drochner * Call MI attach routines. 1874 1.1 drochner */ 1875 1.1 drochner if_attach(ifp); 1876 1.100 ozaki if_deferred_start_init(ifp, NULL); 1877 1.1 drochner ether_ifattach(ifp, eaddr); 1878 1.1 drochner 1879 1.86 tsutsui /* 1880 1.86 tsutsui * Add shutdown hook so that DMA is disabled prior to reboot. Not 1881 1.86 tsutsui * doing do could allow DMA to corrupt kernel memory during the 1882 1.86 tsutsui * reboot before the driver initializes. 1883 1.86 tsutsui */ 1884 1.86 tsutsui if (pmf_device_register1(self, NULL, NULL, ti_shutdown)) 1885 1.86 tsutsui pmf_class_network_register(self, ifp); 1886 1.86 tsutsui else 1887 1.86 tsutsui aprint_error_dev(self, "couldn't establish power handler\n"); 1888 1.86 tsutsui 1889 1.6 bouyer return; 1890 1.6 bouyer fail2: 1891 1.6 bouyer pci_intr_disestablish(pc, sc->sc_ih); 1892 1.6 bouyer return; 1893 1.1 drochner } 1894 1.1 drochner 1895 1.1 drochner /* 1896 1.1 drochner * Frame reception handling. This is called if there's a frame 1897 1.1 drochner * on the receive return list. 1898 1.1 drochner * 1899 1.1 drochner * Note: we have to be able to handle three possibilities here: 1900 1.1 drochner * 1) the frame is from the mini receive ring (can only happen) 1901 1.1 drochner * on Tigon 2 boards) 1902 1.25 wiz * 2) the frame is from the jumbo receive ring 1903 1.1 drochner * 3) the frame is from the standard receive ring 1904 1.1 drochner */ 1905 1.1 drochner 1906 1.77 tnn static void 1907 1.77 tnn ti_rxeof(struct ti_softc *sc) 1908 1.1 drochner { 1909 1.1 drochner struct ifnet *ifp; 1910 1.1 drochner struct ti_cmd_desc cmd; 1911 1.1 drochner 1912 1.1 drochner ifp = &sc->ethercom.ec_if; 1913 1.1 drochner 1914 1.77 tnn while (sc->ti_rx_saved_considx != sc->ti_return_prodidx.ti_idx) { 1915 1.1 drochner struct ti_rx_desc *cur_rx; 1916 1.108 msaitoh uint32_t rxidx; 1917 1.1 drochner struct mbuf *m = NULL; 1918 1.21 thorpej struct ether_header *eh; 1919 1.1 drochner bus_dmamap_t dmamap; 1920 1.1 drochner 1921 1.1 drochner cur_rx = 1922 1.1 drochner &sc->ti_rdata->ti_rx_return_ring[sc->ti_rx_saved_considx]; 1923 1.1 drochner rxidx = cur_rx->ti_idx; 1924 1.1 drochner TI_INC(sc->ti_rx_saved_considx, TI_RETURN_RING_CNT); 1925 1.1 drochner 1926 1.1 drochner if (cur_rx->ti_flags & TI_BDFLAG_JUMBO_RING) { 1927 1.1 drochner TI_INC(sc->ti_jumbo, TI_JUMBO_RX_RING_CNT); 1928 1.1 drochner m = sc->ti_cdata.ti_rx_jumbo_chain[rxidx]; 1929 1.1 drochner sc->ti_cdata.ti_rx_jumbo_chain[rxidx] = NULL; 1930 1.1 drochner if (cur_rx->ti_flags & TI_BDFLAG_ERROR) { 1931 1.114 thorpej if_statinc(ifp, if_ierrors); 1932 1.1 drochner ti_newbuf_jumbo(sc, sc->ti_jumbo, m); 1933 1.1 drochner continue; 1934 1.1 drochner } 1935 1.1 drochner if (ti_newbuf_jumbo(sc, sc->ti_jumbo, NULL) 1936 1.1 drochner == ENOBUFS) { 1937 1.114 thorpej if_statinc(ifp, if_ierrors); 1938 1.1 drochner ti_newbuf_jumbo(sc, sc->ti_jumbo, m); 1939 1.1 drochner continue; 1940 1.1 drochner } 1941 1.1 drochner } else if (cur_rx->ti_flags & TI_BDFLAG_MINI_RING) { 1942 1.1 drochner TI_INC(sc->ti_mini, TI_MINI_RX_RING_CNT); 1943 1.1 drochner m = sc->ti_cdata.ti_rx_mini_chain[rxidx]; 1944 1.1 drochner sc->ti_cdata.ti_rx_mini_chain[rxidx] = NULL; 1945 1.1 drochner dmamap = sc->mini_dmamap[rxidx]; 1946 1.1 drochner sc->mini_dmamap[rxidx] = 0; 1947 1.1 drochner if (cur_rx->ti_flags & TI_BDFLAG_ERROR) { 1948 1.114 thorpej if_statinc(ifp, if_ierrors); 1949 1.1 drochner ti_newbuf_mini(sc, sc->ti_mini, m, dmamap); 1950 1.1 drochner continue; 1951 1.1 drochner } 1952 1.1 drochner if (ti_newbuf_mini(sc, sc->ti_mini, NULL, dmamap) 1953 1.1 drochner == ENOBUFS) { 1954 1.114 thorpej if_statinc(ifp, if_ierrors); 1955 1.1 drochner ti_newbuf_mini(sc, sc->ti_mini, m, dmamap); 1956 1.1 drochner continue; 1957 1.1 drochner } 1958 1.1 drochner } else { 1959 1.1 drochner TI_INC(sc->ti_std, TI_STD_RX_RING_CNT); 1960 1.1 drochner m = sc->ti_cdata.ti_rx_std_chain[rxidx]; 1961 1.1 drochner sc->ti_cdata.ti_rx_std_chain[rxidx] = NULL; 1962 1.1 drochner dmamap = sc->std_dmamap[rxidx]; 1963 1.1 drochner sc->std_dmamap[rxidx] = 0; 1964 1.1 drochner if (cur_rx->ti_flags & TI_BDFLAG_ERROR) { 1965 1.114 thorpej if_statinc(ifp, if_ierrors); 1966 1.1 drochner ti_newbuf_std(sc, sc->ti_std, m, dmamap); 1967 1.1 drochner continue; 1968 1.1 drochner } 1969 1.1 drochner if (ti_newbuf_std(sc, sc->ti_std, NULL, dmamap) 1970 1.1 drochner == ENOBUFS) { 1971 1.114 thorpej if_statinc(ifp, if_ierrors); 1972 1.1 drochner ti_newbuf_std(sc, sc->ti_std, m, dmamap); 1973 1.1 drochner continue; 1974 1.1 drochner } 1975 1.1 drochner } 1976 1.1 drochner 1977 1.1 drochner m->m_pkthdr.len = m->m_len = cur_rx->ti_len; 1978 1.97 ozaki m_set_rcvif(m, ifp); 1979 1.1 drochner 1980 1.21 thorpej eh = mtod(m, struct ether_header *); 1981 1.21 thorpej switch (ntohs(eh->ether_type)) { 1982 1.44 itojun #ifdef INET 1983 1.21 thorpej case ETHERTYPE_IP: 1984 1.21 thorpej { 1985 1.21 thorpej struct ip *ip = (struct ip *) (eh + 1); 1986 1.21 thorpej 1987 1.21 thorpej /* 1988 1.21 thorpej * Note the Tigon firmware does not invert 1989 1.21 thorpej * the checksum for us, hence the XOR. 1990 1.21 thorpej */ 1991 1.21 thorpej m->m_pkthdr.csum_flags |= M_CSUM_IPv4; 1992 1.21 thorpej if ((cur_rx->ti_ip_cksum ^ 0xffff) != 0) 1993 1.21 thorpej m->m_pkthdr.csum_flags |= M_CSUM_IPv4_BAD; 1994 1.21 thorpej /* 1995 1.21 thorpej * ntohs() the constant so the compiler can 1996 1.21 thorpej * optimize... 1997 1.21 thorpej * 1998 1.21 thorpej * XXX Figure out a sane way to deal with 1999 1.21 thorpej * fragmented packets. 2000 1.21 thorpej */ 2001 1.108 msaitoh if ((ip->ip_off & htons(IP_MF | IP_OFFMASK)) == 0) { 2002 1.21 thorpej switch (ip->ip_p) { 2003 1.21 thorpej case IPPROTO_TCP: 2004 1.21 thorpej m->m_pkthdr.csum_data = 2005 1.21 thorpej cur_rx->ti_tcp_udp_cksum; 2006 1.21 thorpej m->m_pkthdr.csum_flags |= 2007 1.108 msaitoh M_CSUM_TCPv4 | M_CSUM_DATA; 2008 1.21 thorpej break; 2009 1.21 thorpej case IPPROTO_UDP: 2010 1.21 thorpej m->m_pkthdr.csum_data = 2011 1.21 thorpej cur_rx->ti_tcp_udp_cksum; 2012 1.21 thorpej m->m_pkthdr.csum_flags |= 2013 1.108 msaitoh M_CSUM_UDPv4 | M_CSUM_DATA; 2014 1.21 thorpej break; 2015 1.21 thorpej default: 2016 1.21 thorpej /* Nothing */; 2017 1.21 thorpej } 2018 1.21 thorpej } 2019 1.21 thorpej break; 2020 1.21 thorpej } 2021 1.44 itojun #endif 2022 1.21 thorpej default: 2023 1.21 thorpej /* Nothing. */ 2024 1.21 thorpej break; 2025 1.21 thorpej } 2026 1.1 drochner 2027 1.116 msaitoh if (cur_rx->ti_flags & TI_BDFLAG_VLAN_TAG) 2028 1.116 msaitoh vlan_set_tag(m, cur_rx->ti_vlan_tag); 2029 1.53 itojun 2030 1.96 ozaki if_percpuq_enqueue(ifp->if_percpuq, m); 2031 1.1 drochner } 2032 1.1 drochner 2033 1.1 drochner /* Only necessary on the Tigon 1. */ 2034 1.1 drochner if (sc->ti_hwrev == TI_HWREV_TIGON) 2035 1.1 drochner CSR_WRITE_4(sc, TI_GCR_RXRETURNCONS_IDX, 2036 1.1 drochner sc->ti_rx_saved_considx); 2037 1.1 drochner 2038 1.1 drochner TI_UPDATE_STDPROD(sc, sc->ti_std); 2039 1.1 drochner TI_UPDATE_MINIPROD(sc, sc->ti_mini); 2040 1.1 drochner TI_UPDATE_JUMBOPROD(sc, sc->ti_jumbo); 2041 1.1 drochner } 2042 1.1 drochner 2043 1.77 tnn static void 2044 1.77 tnn ti_txeof_tigon1(struct ti_softc *sc) 2045 1.1 drochner { 2046 1.1 drochner struct ti_tx_desc *cur_tx = NULL; 2047 1.1 drochner struct ifnet *ifp; 2048 1.29 thorpej struct txdmamap_pool_entry *dma; 2049 1.1 drochner 2050 1.1 drochner ifp = &sc->ethercom.ec_if; 2051 1.1 drochner 2052 1.1 drochner /* 2053 1.1 drochner * Go through our tx ring and free mbufs for those 2054 1.1 drochner * frames that have been sent. 2055 1.1 drochner */ 2056 1.1 drochner while (sc->ti_tx_saved_considx != sc->ti_tx_considx.ti_idx) { 2057 1.108 msaitoh uint32_t idx = 0; 2058 1.1 drochner 2059 1.1 drochner idx = sc->ti_tx_saved_considx; 2060 1.32 thorpej if (idx > 383) 2061 1.32 thorpej CSR_WRITE_4(sc, TI_WINBASE, 2062 1.32 thorpej TI_TX_RING_BASE + 6144); 2063 1.32 thorpej else if (idx > 255) 2064 1.32 thorpej CSR_WRITE_4(sc, TI_WINBASE, 2065 1.32 thorpej TI_TX_RING_BASE + 4096); 2066 1.32 thorpej else if (idx > 127) 2067 1.32 thorpej CSR_WRITE_4(sc, TI_WINBASE, 2068 1.32 thorpej TI_TX_RING_BASE + 2048); 2069 1.32 thorpej else 2070 1.32 thorpej CSR_WRITE_4(sc, TI_WINBASE, 2071 1.32 thorpej TI_TX_RING_BASE); 2072 1.32 thorpej cur_tx = &sc->ti_tx_ring_nic[idx % 128]; 2073 1.32 thorpej if (cur_tx->ti_flags & TI_BDFLAG_END) 2074 1.114 thorpej if_statinc(ifp, if_opackets); 2075 1.32 thorpej if (sc->ti_cdata.ti_tx_chain[idx] != NULL) { 2076 1.32 thorpej dma = sc->txdma[idx]; 2077 1.32 thorpej KDASSERT(dma != NULL); 2078 1.32 thorpej bus_dmamap_sync(sc->sc_dmat, dma->dmamap, 0, 2079 1.32 thorpej dma->dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE); 2080 1.32 thorpej bus_dmamap_unload(sc->sc_dmat, dma->dmamap); 2081 1.32 thorpej 2082 1.32 thorpej SIMPLEQ_INSERT_HEAD(&sc->txdma_list, dma, link); 2083 1.32 thorpej sc->txdma[idx] = NULL; 2084 1.123 rin 2085 1.123 rin m_freem(sc->ti_cdata.ti_tx_chain[idx]); 2086 1.123 rin sc->ti_cdata.ti_tx_chain[idx] = NULL; 2087 1.32 thorpej } 2088 1.32 thorpej sc->ti_txcnt--; 2089 1.32 thorpej TI_INC(sc->ti_tx_saved_considx, TI_TX_RING_CNT); 2090 1.32 thorpej ifp->if_timer = 0; 2091 1.32 thorpej } 2092 1.32 thorpej 2093 1.32 thorpej if (cur_tx != NULL) 2094 1.32 thorpej ifp->if_flags &= ~IFF_OACTIVE; 2095 1.32 thorpej } 2096 1.32 thorpej 2097 1.77 tnn static void 2098 1.77 tnn ti_txeof_tigon2(struct ti_softc *sc) 2099 1.32 thorpej { 2100 1.32 thorpej struct ti_tx_desc *cur_tx = NULL; 2101 1.32 thorpej struct ifnet *ifp; 2102 1.32 thorpej struct txdmamap_pool_entry *dma; 2103 1.35 thorpej int firstidx, cnt; 2104 1.32 thorpej 2105 1.32 thorpej ifp = &sc->ethercom.ec_if; 2106 1.32 thorpej 2107 1.32 thorpej /* 2108 1.32 thorpej * Go through our tx ring and free mbufs for those 2109 1.32 thorpej * frames that have been sent. 2110 1.32 thorpej */ 2111 1.35 thorpej firstidx = sc->ti_tx_saved_considx; 2112 1.35 thorpej cnt = 0; 2113 1.32 thorpej while (sc->ti_tx_saved_considx != sc->ti_tx_considx.ti_idx) { 2114 1.108 msaitoh uint32_t idx = 0; 2115 1.32 thorpej 2116 1.32 thorpej idx = sc->ti_tx_saved_considx; 2117 1.32 thorpej cur_tx = &sc->ti_rdata->ti_tx_ring[idx]; 2118 1.1 drochner if (cur_tx->ti_flags & TI_BDFLAG_END) 2119 1.114 thorpej if_statinc(ifp, if_opackets); 2120 1.1 drochner if (sc->ti_cdata.ti_tx_chain[idx] != NULL) { 2121 1.29 thorpej dma = sc->txdma[idx]; 2122 1.29 thorpej KDASSERT(dma != NULL); 2123 1.29 thorpej bus_dmamap_sync(sc->sc_dmat, dma->dmamap, 0, 2124 1.29 thorpej dma->dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE); 2125 1.29 thorpej bus_dmamap_unload(sc->sc_dmat, dma->dmamap); 2126 1.29 thorpej 2127 1.29 thorpej SIMPLEQ_INSERT_HEAD(&sc->txdma_list, dma, link); 2128 1.29 thorpej sc->txdma[idx] = NULL; 2129 1.123 rin 2130 1.123 rin m_freem(sc->ti_cdata.ti_tx_chain[idx]); 2131 1.123 rin sc->ti_cdata.ti_tx_chain[idx] = NULL; 2132 1.1 drochner } 2133 1.35 thorpej cnt++; 2134 1.1 drochner sc->ti_txcnt--; 2135 1.1 drochner TI_INC(sc->ti_tx_saved_considx, TI_TX_RING_CNT); 2136 1.1 drochner ifp->if_timer = 0; 2137 1.1 drochner } 2138 1.1 drochner 2139 1.35 thorpej if (cnt != 0) 2140 1.35 thorpej TI_CDTXSYNC(sc, firstidx, cnt, BUS_DMASYNC_POSTWRITE); 2141 1.35 thorpej 2142 1.1 drochner if (cur_tx != NULL) 2143 1.1 drochner ifp->if_flags &= ~IFF_OACTIVE; 2144 1.1 drochner } 2145 1.1 drochner 2146 1.77 tnn static int 2147 1.77 tnn ti_intr(void *xsc) 2148 1.1 drochner { 2149 1.108 msaitoh struct ti_softc *sc; 2150 1.108 msaitoh struct ifnet *ifp; 2151 1.1 drochner 2152 1.1 drochner sc = xsc; 2153 1.1 drochner ifp = &sc->ethercom.ec_if; 2154 1.1 drochner 2155 1.1 drochner #ifdef notdef 2156 1.1 drochner /* Avoid this for now -- checking this register is expensive. */ 2157 1.1 drochner /* Make sure this is really our interrupt. */ 2158 1.1 drochner if (!(CSR_READ_4(sc, TI_MISC_HOST_CTL) & TI_MHC_INTSTATE)) 2159 1.1 drochner return (0); 2160 1.1 drochner #endif 2161 1.1 drochner 2162 1.103 dholland /* Ack interrupt and stop others from occurring. */ 2163 1.1 drochner CSR_WRITE_4(sc, TI_MB_HOSTINTR, 1); 2164 1.1 drochner 2165 1.1 drochner if (ifp->if_flags & IFF_RUNNING) { 2166 1.1 drochner /* Check RX return ring producer/consumer */ 2167 1.1 drochner ti_rxeof(sc); 2168 1.1 drochner 2169 1.1 drochner /* Check TX ring producer/consumer */ 2170 1.32 thorpej (*sc->sc_tx_eof)(sc); 2171 1.1 drochner } 2172 1.1 drochner 2173 1.1 drochner ti_handle_events(sc); 2174 1.1 drochner 2175 1.1 drochner /* Re-enable interrupts. */ 2176 1.1 drochner CSR_WRITE_4(sc, TI_MB_HOSTINTR, 0); 2177 1.1 drochner 2178 1.100 ozaki if ((ifp->if_flags & IFF_RUNNING) != 0) 2179 1.100 ozaki if_schedule_deferred_start(ifp); 2180 1.1 drochner 2181 1.1 drochner return (1); 2182 1.1 drochner } 2183 1.1 drochner 2184 1.77 tnn static void 2185 1.77 tnn ti_stats_update(struct ti_softc *sc) 2186 1.1 drochner { 2187 1.114 thorpej struct ifnet *ifp = &sc->ethercom.ec_if; 2188 1.1 drochner 2189 1.34 thorpej TI_CDSTATSSYNC(sc, BUS_DMASYNC_POSTREAD); 2190 1.34 thorpej 2191 1.119 msaitoh uint64_t collisions = 2192 1.1 drochner (sc->ti_rdata->ti_info.ti_stats.dot3StatsSingleCollisionFrames + 2193 1.114 thorpej sc->ti_rdata->ti_info.ti_stats.dot3StatsMultipleCollisionFrames + 2194 1.114 thorpej sc->ti_rdata->ti_info.ti_stats.dot3StatsExcessiveCollisions + 2195 1.114 thorpej sc->ti_rdata->ti_info.ti_stats.dot3StatsLateCollisions); 2196 1.114 thorpej if_statadd(ifp, if_collisions, collisions - sc->ti_if_collisions); 2197 1.114 thorpej sc->ti_if_collisions = collisions; 2198 1.1 drochner 2199 1.34 thorpej TI_CDSTATSSYNC(sc, BUS_DMASYNC_PREREAD); 2200 1.1 drochner } 2201 1.1 drochner 2202 1.1 drochner /* 2203 1.118 msaitoh * Encapsulate an mbuf chain in the tx ring by coupling the mbuf data 2204 1.1 drochner * pointers to descriptors. 2205 1.1 drochner */ 2206 1.77 tnn static int 2207 1.108 msaitoh ti_encap_tigon1(struct ti_softc *sc, struct mbuf *m_head, uint32_t *txidx) 2208 1.1 drochner { 2209 1.1 drochner struct ti_tx_desc *f = NULL; 2210 1.108 msaitoh uint32_t frag, cur, cnt = 0; 2211 1.1 drochner struct txdmamap_pool_entry *dma; 2212 1.1 drochner bus_dmamap_t dmamap; 2213 1.1 drochner int error, i; 2214 1.108 msaitoh uint16_t csum_flags = 0; 2215 1.1 drochner 2216 1.1 drochner dma = SIMPLEQ_FIRST(&sc->txdma_list); 2217 1.6 bouyer if (dma == NULL) { 2218 1.6 bouyer return ENOMEM; 2219 1.6 bouyer } 2220 1.1 drochner dmamap = dma->dmamap; 2221 1.1 drochner 2222 1.40 thorpej error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m_head, 2223 1.49 bouyer BUS_DMA_WRITE | BUS_DMA_NOWAIT); 2224 1.1 drochner if (error) { 2225 1.1 drochner struct mbuf *m; 2226 1.68 christos int j = 0; 2227 1.1 drochner for (m = m_head; m; m = m->m_next) 2228 1.68 christos j++; 2229 1.1 drochner printf("ti_encap: bus_dmamap_load_mbuf (len %d, %d frags) " 2230 1.68 christos "error %d\n", m_head->m_pkthdr.len, j, error); 2231 1.1 drochner return (ENOMEM); 2232 1.1 drochner } 2233 1.1 drochner 2234 1.1 drochner cur = frag = *txidx; 2235 1.1 drochner 2236 1.21 thorpej if (m_head->m_pkthdr.csum_flags & M_CSUM_IPv4) { 2237 1.21 thorpej /* IP header checksum field must be 0! */ 2238 1.21 thorpej csum_flags |= TI_BDFLAG_IP_CKSUM; 2239 1.21 thorpej } 2240 1.108 msaitoh if (m_head->m_pkthdr.csum_flags & (M_CSUM_TCPv4 | M_CSUM_UDPv4)) 2241 1.21 thorpej csum_flags |= TI_BDFLAG_TCP_UDP_CKSUM; 2242 1.21 thorpej 2243 1.21 thorpej /* XXX fragmented packet checksum capability? */ 2244 1.21 thorpej 2245 1.1 drochner /* 2246 1.108 msaitoh * Start packing the mbufs in this chain into 2247 1.1 drochner * the fragment pointers. Stop when we run out 2248 1.108 msaitoh * of fragments or hit the end of the mbuf chain. 2249 1.1 drochner */ 2250 1.1 drochner for (i = 0; i < dmamap->dm_nsegs; i++) { 2251 1.31 thorpej if (frag > 383) 2252 1.31 thorpej CSR_WRITE_4(sc, TI_WINBASE, 2253 1.31 thorpej TI_TX_RING_BASE + 6144); 2254 1.31 thorpej else if (frag > 255) 2255 1.31 thorpej CSR_WRITE_4(sc, TI_WINBASE, 2256 1.31 thorpej TI_TX_RING_BASE + 4096); 2257 1.31 thorpej else if (frag > 127) 2258 1.31 thorpej CSR_WRITE_4(sc, TI_WINBASE, 2259 1.31 thorpej TI_TX_RING_BASE + 2048); 2260 1.31 thorpej else 2261 1.31 thorpej CSR_WRITE_4(sc, TI_WINBASE, 2262 1.31 thorpej TI_TX_RING_BASE); 2263 1.31 thorpej f = &sc->ti_tx_ring_nic[frag % 128]; 2264 1.31 thorpej if (sc->ti_cdata.ti_tx_chain[frag] != NULL) 2265 1.31 thorpej break; 2266 1.121 thorpej TI_HOSTADDR(f->ti_addr) = dmamap->dm_segs[i].ds_addr; 2267 1.31 thorpej f->ti_len = dmamap->dm_segs[i].ds_len; 2268 1.31 thorpej f->ti_flags = csum_flags; 2269 1.102 knakahar if (vlan_has_tag(m_head)) { 2270 1.31 thorpej f->ti_flags |= TI_BDFLAG_VLAN_TAG; 2271 1.102 knakahar f->ti_vlan_tag = vlan_get_tag(m_head); 2272 1.31 thorpej } else { 2273 1.31 thorpej f->ti_vlan_tag = 0; 2274 1.31 thorpej } 2275 1.31 thorpej /* 2276 1.31 thorpej * Sanity check: avoid coming within 16 descriptors 2277 1.31 thorpej * of the end of the ring. 2278 1.31 thorpej */ 2279 1.31 thorpej if ((TI_TX_RING_CNT - (sc->ti_txcnt + cnt)) < 16) 2280 1.77 tnn return (ENOBUFS); 2281 1.31 thorpej cur = frag; 2282 1.31 thorpej TI_INC(frag, TI_TX_RING_CNT); 2283 1.31 thorpej cnt++; 2284 1.31 thorpej } 2285 1.31 thorpej 2286 1.31 thorpej if (i < dmamap->dm_nsegs) 2287 1.77 tnn return (ENOBUFS); 2288 1.31 thorpej 2289 1.31 thorpej if (frag == sc->ti_tx_saved_considx) 2290 1.77 tnn return (ENOBUFS); 2291 1.31 thorpej 2292 1.31 thorpej sc->ti_tx_ring_nic[cur % 128].ti_flags |= 2293 1.31 thorpej TI_BDFLAG_END; 2294 1.31 thorpej 2295 1.31 thorpej /* Sync the packet's DMA map. */ 2296 1.31 thorpej bus_dmamap_sync(sc->sc_dmat, dmamap, 0, dmamap->dm_mapsize, 2297 1.31 thorpej BUS_DMASYNC_PREWRITE); 2298 1.31 thorpej 2299 1.31 thorpej sc->ti_cdata.ti_tx_chain[cur] = m_head; 2300 1.48 lukem SIMPLEQ_REMOVE_HEAD(&sc->txdma_list, link); 2301 1.31 thorpej sc->txdma[cur] = dma; 2302 1.31 thorpej sc->ti_txcnt += cnt; 2303 1.31 thorpej 2304 1.31 thorpej *txidx = frag; 2305 1.31 thorpej 2306 1.77 tnn return (0); 2307 1.31 thorpej } 2308 1.31 thorpej 2309 1.77 tnn static int 2310 1.108 msaitoh ti_encap_tigon2(struct ti_softc *sc, struct mbuf *m_head, uint32_t *txidx) 2311 1.31 thorpej { 2312 1.31 thorpej struct ti_tx_desc *f = NULL; 2313 1.108 msaitoh uint32_t frag, firstfrag, cur, cnt = 0; 2314 1.31 thorpej struct txdmamap_pool_entry *dma; 2315 1.31 thorpej bus_dmamap_t dmamap; 2316 1.31 thorpej int error, i; 2317 1.108 msaitoh uint16_t csum_flags = 0; 2318 1.31 thorpej 2319 1.31 thorpej dma = SIMPLEQ_FIRST(&sc->txdma_list); 2320 1.31 thorpej if (dma == NULL) { 2321 1.31 thorpej return ENOMEM; 2322 1.31 thorpej } 2323 1.31 thorpej dmamap = dma->dmamap; 2324 1.31 thorpej 2325 1.40 thorpej error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m_head, 2326 1.49 bouyer BUS_DMA_WRITE | BUS_DMA_NOWAIT); 2327 1.31 thorpej if (error) { 2328 1.31 thorpej struct mbuf *m; 2329 1.68 christos int j = 0; 2330 1.31 thorpej for (m = m_head; m; m = m->m_next) 2331 1.68 christos j++; 2332 1.31 thorpej printf("ti_encap: bus_dmamap_load_mbuf (len %d, %d frags) " 2333 1.68 christos "error %d\n", m_head->m_pkthdr.len, j, error); 2334 1.31 thorpej return (ENOMEM); 2335 1.31 thorpej } 2336 1.31 thorpej 2337 1.35 thorpej cur = firstfrag = frag = *txidx; 2338 1.31 thorpej 2339 1.31 thorpej if (m_head->m_pkthdr.csum_flags & M_CSUM_IPv4) { 2340 1.31 thorpej /* IP header checksum field must be 0! */ 2341 1.31 thorpej csum_flags |= TI_BDFLAG_IP_CKSUM; 2342 1.31 thorpej } 2343 1.108 msaitoh if (m_head->m_pkthdr.csum_flags & (M_CSUM_TCPv4 | M_CSUM_UDPv4)) 2344 1.31 thorpej csum_flags |= TI_BDFLAG_TCP_UDP_CKSUM; 2345 1.31 thorpej 2346 1.31 thorpej /* XXX fragmented packet checksum capability? */ 2347 1.31 thorpej 2348 1.31 thorpej /* 2349 1.108 msaitoh * Start packing the mbufs in this chain into 2350 1.31 thorpej * the fragment pointers. Stop when we run out 2351 1.108 msaitoh * of fragments or hit the end of the mbuf chain. 2352 1.31 thorpej */ 2353 1.31 thorpej for (i = 0; i < dmamap->dm_nsegs; i++) { 2354 1.31 thorpej f = &sc->ti_rdata->ti_tx_ring[frag]; 2355 1.31 thorpej if (sc->ti_cdata.ti_tx_chain[frag] != NULL) 2356 1.31 thorpej break; 2357 1.121 thorpej TI_HOSTADDR(f->ti_addr) = dmamap->dm_segs[i].ds_addr; 2358 1.31 thorpej f->ti_len = dmamap->dm_segs[i].ds_len; 2359 1.31 thorpej f->ti_flags = csum_flags; 2360 1.102 knakahar if (vlan_has_tag(m_head)) { 2361 1.31 thorpej f->ti_flags |= TI_BDFLAG_VLAN_TAG; 2362 1.102 knakahar f->ti_vlan_tag = vlan_get_tag(m_head); 2363 1.31 thorpej } else { 2364 1.31 thorpej f->ti_vlan_tag = 0; 2365 1.31 thorpej } 2366 1.31 thorpej /* 2367 1.31 thorpej * Sanity check: avoid coming within 16 descriptors 2368 1.31 thorpej * of the end of the ring. 2369 1.31 thorpej */ 2370 1.31 thorpej if ((TI_TX_RING_CNT - (sc->ti_txcnt + cnt)) < 16) 2371 1.77 tnn return (ENOBUFS); 2372 1.31 thorpej cur = frag; 2373 1.31 thorpej TI_INC(frag, TI_TX_RING_CNT); 2374 1.31 thorpej cnt++; 2375 1.1 drochner } 2376 1.1 drochner 2377 1.1 drochner if (i < dmamap->dm_nsegs) 2378 1.77 tnn return (ENOBUFS); 2379 1.1 drochner 2380 1.1 drochner if (frag == sc->ti_tx_saved_considx) 2381 1.77 tnn return (ENOBUFS); 2382 1.1 drochner 2383 1.31 thorpej sc->ti_rdata->ti_tx_ring[cur].ti_flags |= TI_BDFLAG_END; 2384 1.29 thorpej 2385 1.29 thorpej /* Sync the packet's DMA map. */ 2386 1.29 thorpej bus_dmamap_sync(sc->sc_dmat, dmamap, 0, dmamap->dm_mapsize, 2387 1.29 thorpej BUS_DMASYNC_PREWRITE); 2388 1.35 thorpej 2389 1.35 thorpej /* Sync the descriptors we are using. */ 2390 1.35 thorpej TI_CDTXSYNC(sc, firstfrag, cnt, BUS_DMASYNC_PREWRITE); 2391 1.29 thorpej 2392 1.1 drochner sc->ti_cdata.ti_tx_chain[cur] = m_head; 2393 1.48 lukem SIMPLEQ_REMOVE_HEAD(&sc->txdma_list, link); 2394 1.1 drochner sc->txdma[cur] = dma; 2395 1.1 drochner sc->ti_txcnt += cnt; 2396 1.1 drochner 2397 1.1 drochner *txidx = frag; 2398 1.1 drochner 2399 1.77 tnn return (0); 2400 1.1 drochner } 2401 1.1 drochner 2402 1.1 drochner /* 2403 1.1 drochner * Main transmit routine. To avoid having to do mbuf copies, we put pointers 2404 1.1 drochner * to the mbuf data regions directly in the transmit descriptors. 2405 1.1 drochner */ 2406 1.77 tnn static void 2407 1.77 tnn ti_start(struct ifnet *ifp) 2408 1.1 drochner { 2409 1.108 msaitoh struct ti_softc *sc; 2410 1.108 msaitoh struct mbuf *m_head = NULL; 2411 1.108 msaitoh uint32_t prodidx = 0; 2412 1.1 drochner 2413 1.1 drochner sc = ifp->if_softc; 2414 1.1 drochner 2415 1.1 drochner prodidx = CSR_READ_4(sc, TI_MB_SENDPROD_IDX); 2416 1.1 drochner 2417 1.16 thorpej while (sc->ti_cdata.ti_tx_chain[prodidx] == NULL) { 2418 1.16 thorpej IFQ_POLL(&ifp->if_snd, m_head); 2419 1.1 drochner if (m_head == NULL) 2420 1.1 drochner break; 2421 1.1 drochner 2422 1.1 drochner /* 2423 1.1 drochner * Pack the data into the transmit ring. If we 2424 1.1 drochner * don't have room, set the OACTIVE flag and wait 2425 1.1 drochner * for the NIC to drain the ring. 2426 1.1 drochner */ 2427 1.31 thorpej if ((*sc->sc_tx_encap)(sc, m_head, &prodidx)) { 2428 1.1 drochner ifp->if_flags |= IFF_OACTIVE; 2429 1.1 drochner break; 2430 1.1 drochner } 2431 1.16 thorpej 2432 1.16 thorpej IFQ_DEQUEUE(&ifp->if_snd, m_head); 2433 1.1 drochner 2434 1.1 drochner /* 2435 1.1 drochner * If there's a BPF listener, bounce a copy of this frame 2436 1.1 drochner * to him. 2437 1.1 drochner */ 2438 1.104 msaitoh bpf_mtap(ifp, m_head, BPF_D_OUT); 2439 1.1 drochner } 2440 1.1 drochner 2441 1.1 drochner /* Transmit */ 2442 1.1 drochner CSR_WRITE_4(sc, TI_MB_SENDPROD_IDX, prodidx); 2443 1.1 drochner 2444 1.108 msaitoh /* Set a timeout in case the chip goes out to lunch. */ 2445 1.1 drochner ifp->if_timer = 5; 2446 1.1 drochner } 2447 1.1 drochner 2448 1.77 tnn static void 2449 1.77 tnn ti_init(void *xsc) 2450 1.1 drochner { 2451 1.1 drochner struct ti_softc *sc = xsc; 2452 1.108 msaitoh int s; 2453 1.1 drochner 2454 1.18 thorpej s = splnet(); 2455 1.1 drochner 2456 1.1 drochner /* Cancel pending I/O and flush buffers. */ 2457 1.1 drochner ti_stop(sc); 2458 1.1 drochner 2459 1.1 drochner /* Init the gen info block, ring control blocks and firmware. */ 2460 1.1 drochner if (ti_gibinit(sc)) { 2461 1.91 chs aprint_error_dev(sc->sc_dev, "initialization failure\n"); 2462 1.1 drochner splx(s); 2463 1.1 drochner return; 2464 1.1 drochner } 2465 1.1 drochner 2466 1.1 drochner splx(s); 2467 1.1 drochner } 2468 1.1 drochner 2469 1.77 tnn static void 2470 1.77 tnn ti_init2(struct ti_softc *sc) 2471 1.1 drochner { 2472 1.1 drochner struct ti_cmd_desc cmd; 2473 1.1 drochner struct ifnet *ifp; 2474 1.108 msaitoh const uint8_t *m; 2475 1.1 drochner struct ifmedia *ifm; 2476 1.1 drochner int tmp; 2477 1.1 drochner 2478 1.1 drochner ifp = &sc->ethercom.ec_if; 2479 1.1 drochner 2480 1.1 drochner /* Specify MTU and interface index. */ 2481 1.91 chs CSR_WRITE_4(sc, TI_GCR_IFINDEX, device_unit(sc->sc_dev)); /* ??? */ 2482 1.23 thorpej 2483 1.23 thorpej tmp = ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN; 2484 1.23 thorpej if (sc->ethercom.ec_capenable & ETHERCAP_VLAN_MTU) 2485 1.23 thorpej tmp += ETHER_VLAN_ENCAP_LEN; 2486 1.23 thorpej CSR_WRITE_4(sc, TI_GCR_IFMTU, tmp); 2487 1.23 thorpej 2488 1.1 drochner TI_DO_CMD(TI_CMD_UPDATE_GENCOM, 0, 0); 2489 1.1 drochner 2490 1.1 drochner /* Load our MAC address. */ 2491 1.108 msaitoh m = (const uint8_t *)CLLADDR(ifp->if_sadl); 2492 1.1 drochner CSR_WRITE_4(sc, TI_GCR_PAR0, (m[0] << 8) | m[1]); 2493 1.1 drochner CSR_WRITE_4(sc, TI_GCR_PAR1, (m[2] << 24) | (m[3] << 16) 2494 1.1 drochner | (m[4] << 8) | m[5]); 2495 1.1 drochner TI_DO_CMD(TI_CMD_SET_MAC_ADDR, 0, 0); 2496 1.1 drochner 2497 1.1 drochner /* Enable or disable promiscuous mode as needed. */ 2498 1.1 drochner if (ifp->if_flags & IFF_PROMISC) { 2499 1.1 drochner TI_DO_CMD(TI_CMD_SET_PROMISC_MODE, TI_CMD_CODE_PROMISC_ENB, 0); 2500 1.1 drochner } else { 2501 1.1 drochner TI_DO_CMD(TI_CMD_SET_PROMISC_MODE, TI_CMD_CODE_PROMISC_DIS, 0); 2502 1.1 drochner } 2503 1.1 drochner 2504 1.1 drochner /* Program multicast filter. */ 2505 1.1 drochner ti_setmulti(sc); 2506 1.1 drochner 2507 1.1 drochner /* 2508 1.1 drochner * If this is a Tigon 1, we should tell the 2509 1.1 drochner * firmware to use software packet filtering. 2510 1.1 drochner */ 2511 1.1 drochner if (sc->ti_hwrev == TI_HWREV_TIGON) { 2512 1.1 drochner TI_DO_CMD(TI_CMD_FDR_FILTERING, TI_CMD_CODE_FILT_ENB, 0); 2513 1.1 drochner } 2514 1.1 drochner 2515 1.1 drochner /* Init RX ring. */ 2516 1.1 drochner ti_init_rx_ring_std(sc); 2517 1.1 drochner 2518 1.1 drochner /* Init jumbo RX ring. */ 2519 1.12 bouyer if (ifp->if_mtu > (MCLBYTES - ETHER_HDR_LEN - ETHER_CRC_LEN)) 2520 1.1 drochner ti_init_rx_ring_jumbo(sc); 2521 1.1 drochner 2522 1.1 drochner /* 2523 1.1 drochner * If this is a Tigon 2, we can also configure the 2524 1.1 drochner * mini ring. 2525 1.1 drochner */ 2526 1.1 drochner if (sc->ti_hwrev == TI_HWREV_TIGON_II) 2527 1.1 drochner ti_init_rx_ring_mini(sc); 2528 1.1 drochner 2529 1.1 drochner CSR_WRITE_4(sc, TI_GCR_RXRETURNCONS_IDX, 0); 2530 1.1 drochner sc->ti_rx_saved_considx = 0; 2531 1.1 drochner 2532 1.1 drochner /* Init TX ring. */ 2533 1.1 drochner ti_init_tx_ring(sc); 2534 1.1 drochner 2535 1.1 drochner /* Tell firmware we're alive. */ 2536 1.1 drochner TI_DO_CMD(TI_CMD_HOST_STATE, TI_CMD_CODE_STACK_UP, 0); 2537 1.1 drochner 2538 1.1 drochner /* Enable host interrupts. */ 2539 1.1 drochner CSR_WRITE_4(sc, TI_MB_HOSTINTR, 0); 2540 1.1 drochner 2541 1.1 drochner ifp->if_flags |= IFF_RUNNING; 2542 1.1 drochner ifp->if_flags &= ~IFF_OACTIVE; 2543 1.1 drochner 2544 1.1 drochner /* 2545 1.1 drochner * Make sure to set media properly. We have to do this 2546 1.1 drochner * here since we have to issue commands in order to set 2547 1.1 drochner * the link negotiation and we can't issue commands until 2548 1.1 drochner * the firmware is running. 2549 1.1 drochner */ 2550 1.1 drochner ifm = &sc->ifmedia; 2551 1.1 drochner tmp = ifm->ifm_media; 2552 1.1 drochner ifm->ifm_media = ifm->ifm_cur->ifm_media; 2553 1.1 drochner ti_ifmedia_upd(ifp); 2554 1.1 drochner ifm->ifm_media = tmp; 2555 1.1 drochner } 2556 1.1 drochner 2557 1.1 drochner /* 2558 1.1 drochner * Set media options. 2559 1.1 drochner */ 2560 1.77 tnn static int 2561 1.77 tnn ti_ifmedia_upd(struct ifnet *ifp) 2562 1.1 drochner { 2563 1.1 drochner struct ti_softc *sc; 2564 1.1 drochner struct ifmedia *ifm; 2565 1.1 drochner struct ti_cmd_desc cmd; 2566 1.1 drochner 2567 1.1 drochner sc = ifp->if_softc; 2568 1.1 drochner ifm = &sc->ifmedia; 2569 1.1 drochner 2570 1.1 drochner if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) 2571 1.77 tnn return (EINVAL); 2572 1.1 drochner 2573 1.77 tnn switch (IFM_SUBTYPE(ifm->ifm_media)) { 2574 1.1 drochner case IFM_AUTO: 2575 1.108 msaitoh CSR_WRITE_4(sc, TI_GCR_GLINK, TI_GLNK_PREF | TI_GLNK_1000MB | 2576 1.108 msaitoh TI_GLNK_FULL_DUPLEX | TI_GLNK_RX_FLOWCTL_Y | 2577 1.108 msaitoh TI_GLNK_AUTONEGENB | TI_GLNK_ENB); 2578 1.108 msaitoh CSR_WRITE_4(sc, TI_GCR_LINK, TI_LNK_100MB | TI_LNK_10MB | 2579 1.108 msaitoh TI_LNK_FULL_DUPLEX | TI_LNK_HALF_DUPLEX | 2580 1.108 msaitoh TI_LNK_AUTONEGENB | TI_LNK_ENB); 2581 1.1 drochner TI_DO_CMD(TI_CMD_LINK_NEGOTIATION, 2582 1.1 drochner TI_CMD_CODE_NEGOTIATE_BOTH, 0); 2583 1.1 drochner break; 2584 1.3 thorpej case IFM_1000_SX: 2585 1.36 bjh21 case IFM_1000_T: 2586 1.107 msaitoh if ((ifm->ifm_media & IFM_FDX) != 0) { 2587 1.15 bouyer CSR_WRITE_4(sc, TI_GCR_GLINK, 2588 1.108 msaitoh TI_GLNK_PREF | TI_GLNK_1000MB | TI_GLNK_FULL_DUPLEX 2589 1.108 msaitoh | TI_GLNK_RX_FLOWCTL_Y | TI_GLNK_ENB); 2590 1.15 bouyer } else { 2591 1.15 bouyer CSR_WRITE_4(sc, TI_GCR_GLINK, 2592 1.108 msaitoh TI_GLNK_PREF | TI_GLNK_1000MB | 2593 1.108 msaitoh TI_GLNK_RX_FLOWCTL_Y | TI_GLNK_ENB); 2594 1.15 bouyer } 2595 1.1 drochner CSR_WRITE_4(sc, TI_GCR_LINK, 0); 2596 1.1 drochner TI_DO_CMD(TI_CMD_LINK_NEGOTIATION, 2597 1.1 drochner TI_CMD_CODE_NEGOTIATE_GIGABIT, 0); 2598 1.1 drochner break; 2599 1.1 drochner case IFM_100_FX: 2600 1.1 drochner case IFM_10_FL: 2601 1.15 bouyer case IFM_100_TX: 2602 1.15 bouyer case IFM_10_T: 2603 1.1 drochner CSR_WRITE_4(sc, TI_GCR_GLINK, 0); 2604 1.108 msaitoh CSR_WRITE_4(sc, TI_GCR_LINK, TI_LNK_ENB | TI_LNK_PREF); 2605 1.15 bouyer if (IFM_SUBTYPE(ifm->ifm_media) == IFM_100_FX || 2606 1.15 bouyer IFM_SUBTYPE(ifm->ifm_media) == IFM_100_TX) { 2607 1.1 drochner TI_SETBIT(sc, TI_GCR_LINK, TI_LNK_100MB); 2608 1.1 drochner } else { 2609 1.1 drochner TI_SETBIT(sc, TI_GCR_LINK, TI_LNK_10MB); 2610 1.1 drochner } 2611 1.107 msaitoh if ((ifm->ifm_media & IFM_FDX) != 0) { 2612 1.1 drochner TI_SETBIT(sc, TI_GCR_LINK, TI_LNK_FULL_DUPLEX); 2613 1.1 drochner } else { 2614 1.1 drochner TI_SETBIT(sc, TI_GCR_LINK, TI_LNK_HALF_DUPLEX); 2615 1.1 drochner } 2616 1.1 drochner TI_DO_CMD(TI_CMD_LINK_NEGOTIATION, 2617 1.1 drochner TI_CMD_CODE_NEGOTIATE_10_100, 0); 2618 1.1 drochner break; 2619 1.1 drochner } 2620 1.1 drochner 2621 1.5 thorpej sc->ethercom.ec_if.if_baudrate = 2622 1.5 thorpej ifmedia_baudrate(ifm->ifm_media); 2623 1.5 thorpej 2624 1.77 tnn return (0); 2625 1.1 drochner } 2626 1.1 drochner 2627 1.1 drochner /* 2628 1.1 drochner * Report current media status. 2629 1.1 drochner */ 2630 1.77 tnn static void 2631 1.77 tnn ti_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) 2632 1.1 drochner { 2633 1.1 drochner struct ti_softc *sc; 2634 1.108 msaitoh uint32_t media = 0; 2635 1.1 drochner 2636 1.1 drochner sc = ifp->if_softc; 2637 1.1 drochner 2638 1.1 drochner ifmr->ifm_status = IFM_AVALID; 2639 1.1 drochner ifmr->ifm_active = IFM_ETHER; 2640 1.1 drochner 2641 1.1 drochner if (sc->ti_linkstat == TI_EV_CODE_LINK_DOWN) 2642 1.1 drochner return; 2643 1.1 drochner 2644 1.1 drochner ifmr->ifm_status |= IFM_ACTIVE; 2645 1.1 drochner 2646 1.15 bouyer if (sc->ti_linkstat == TI_EV_CODE_GIG_LINK_UP) { 2647 1.15 bouyer media = CSR_READ_4(sc, TI_GCR_GLINK_STAT); 2648 1.15 bouyer if (sc->ti_copper) 2649 1.36 bjh21 ifmr->ifm_active |= IFM_1000_T; 2650 1.15 bouyer else 2651 1.15 bouyer ifmr->ifm_active |= IFM_1000_SX; 2652 1.15 bouyer if (media & TI_GLNK_FULL_DUPLEX) 2653 1.15 bouyer ifmr->ifm_active |= IFM_FDX; 2654 1.15 bouyer else 2655 1.15 bouyer ifmr->ifm_active |= IFM_HDX; 2656 1.15 bouyer } else if (sc->ti_linkstat == TI_EV_CODE_LINK_UP) { 2657 1.1 drochner media = CSR_READ_4(sc, TI_GCR_LINK_STAT); 2658 1.15 bouyer if (sc->ti_copper) { 2659 1.15 bouyer if (media & TI_LNK_100MB) 2660 1.15 bouyer ifmr->ifm_active |= IFM_100_TX; 2661 1.15 bouyer if (media & TI_LNK_10MB) 2662 1.15 bouyer ifmr->ifm_active |= IFM_10_T; 2663 1.15 bouyer } else { 2664 1.15 bouyer if (media & TI_LNK_100MB) 2665 1.15 bouyer ifmr->ifm_active |= IFM_100_FX; 2666 1.15 bouyer if (media & TI_LNK_10MB) 2667 1.15 bouyer ifmr->ifm_active |= IFM_10_FL; 2668 1.15 bouyer } 2669 1.1 drochner if (media & TI_LNK_FULL_DUPLEX) 2670 1.1 drochner ifmr->ifm_active |= IFM_FDX; 2671 1.1 drochner if (media & TI_LNK_HALF_DUPLEX) 2672 1.1 drochner ifmr->ifm_active |= IFM_HDX; 2673 1.1 drochner } 2674 1.5 thorpej 2675 1.5 thorpej sc->ethercom.ec_if.if_baudrate = 2676 1.5 thorpej ifmedia_baudrate(sc->ifmedia.ifm_media); 2677 1.1 drochner } 2678 1.1 drochner 2679 1.1 drochner static int 2680 1.77 tnn ti_ether_ioctl(struct ifnet *ifp, u_long cmd, void *data) 2681 1.1 drochner { 2682 1.118 msaitoh struct ifaddr *ifa = (struct ifaddr *)data; 2683 1.1 drochner struct ti_softc *sc = ifp->if_softc; 2684 1.1 drochner 2685 1.26 bouyer if ((ifp->if_flags & IFF_UP) == 0) { 2686 1.26 bouyer ifp->if_flags |= IFF_UP; 2687 1.26 bouyer ti_init(sc); 2688 1.26 bouyer } 2689 1.66 perry 2690 1.1 drochner switch (cmd) { 2691 1.82 dyoung case SIOCINITIFADDR: 2692 1.1 drochner 2693 1.1 drochner switch (ifa->ifa_addr->sa_family) { 2694 1.1 drochner #ifdef INET 2695 1.1 drochner case AF_INET: 2696 1.1 drochner arp_ifinit(ifp, ifa); 2697 1.1 drochner break; 2698 1.1 drochner #endif 2699 1.1 drochner default: 2700 1.1 drochner break; 2701 1.1 drochner } 2702 1.1 drochner break; 2703 1.1 drochner 2704 1.1 drochner default: 2705 1.1 drochner return (EINVAL); 2706 1.1 drochner } 2707 1.1 drochner 2708 1.1 drochner return (0); 2709 1.1 drochner } 2710 1.1 drochner 2711 1.77 tnn static int 2712 1.77 tnn ti_ioctl(struct ifnet *ifp, u_long command, void *data) 2713 1.1 drochner { 2714 1.1 drochner struct ti_softc *sc = ifp->if_softc; 2715 1.118 msaitoh struct ifreq *ifr = (struct ifreq *)data; 2716 1.1 drochner int s, error = 0; 2717 1.1 drochner struct ti_cmd_desc cmd; 2718 1.1 drochner 2719 1.18 thorpej s = splnet(); 2720 1.1 drochner 2721 1.77 tnn switch (command) { 2722 1.82 dyoung case SIOCINITIFADDR: 2723 1.1 drochner error = ti_ether_ioctl(ifp, command, data); 2724 1.1 drochner break; 2725 1.1 drochner case SIOCSIFMTU: 2726 1.80 dyoung if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ETHERMTU_JUMBO) 2727 1.1 drochner error = EINVAL; 2728 1.109 msaitoh else if ((error = ifioctl_common(ifp, command, data)) 2729 1.109 msaitoh == ENETRESET) { 2730 1.1 drochner ti_init(sc); 2731 1.80 dyoung error = 0; 2732 1.1 drochner } 2733 1.1 drochner break; 2734 1.1 drochner case SIOCSIFFLAGS: 2735 1.82 dyoung if ((error = ifioctl_common(ifp, command, data)) != 0) 2736 1.82 dyoung break; 2737 1.1 drochner if (ifp->if_flags & IFF_UP) { 2738 1.1 drochner /* 2739 1.1 drochner * If only the state of the PROMISC flag changed, 2740 1.1 drochner * then just use the 'set promisc mode' command 2741 1.1 drochner * instead of reinitializing the entire NIC. Doing 2742 1.1 drochner * a full re-init means reloading the firmware and 2743 1.1 drochner * waiting for it to start up, which may take a 2744 1.1 drochner * second or two. 2745 1.1 drochner */ 2746 1.1 drochner if (ifp->if_flags & IFF_RUNNING && 2747 1.1 drochner ifp->if_flags & IFF_PROMISC && 2748 1.1 drochner !(sc->ti_if_flags & IFF_PROMISC)) { 2749 1.1 drochner TI_DO_CMD(TI_CMD_SET_PROMISC_MODE, 2750 1.1 drochner TI_CMD_CODE_PROMISC_ENB, 0); 2751 1.1 drochner } else if (ifp->if_flags & IFF_RUNNING && 2752 1.1 drochner !(ifp->if_flags & IFF_PROMISC) && 2753 1.1 drochner sc->ti_if_flags & IFF_PROMISC) { 2754 1.1 drochner TI_DO_CMD(TI_CMD_SET_PROMISC_MODE, 2755 1.1 drochner TI_CMD_CODE_PROMISC_DIS, 0); 2756 1.1 drochner } else 2757 1.1 drochner ti_init(sc); 2758 1.1 drochner } else { 2759 1.1 drochner if (ifp->if_flags & IFF_RUNNING) { 2760 1.1 drochner ti_stop(sc); 2761 1.1 drochner } 2762 1.1 drochner } 2763 1.1 drochner sc->ti_if_flags = ifp->if_flags; 2764 1.1 drochner error = 0; 2765 1.1 drochner break; 2766 1.1 drochner default: 2767 1.80 dyoung if ((error = ether_ioctl(ifp, command, data)) != ENETRESET) 2768 1.80 dyoung break; 2769 1.80 dyoung 2770 1.80 dyoung error = 0; 2771 1.80 dyoung 2772 1.80 dyoung if (command == SIOCSIFCAP) 2773 1.80 dyoung ti_init(sc); 2774 1.80 dyoung else if (command != SIOCADDMULTI && command != SIOCDELMULTI) 2775 1.80 dyoung ; 2776 1.80 dyoung else if (ifp->if_flags & IFF_RUNNING) 2777 1.80 dyoung ti_setmulti(sc); 2778 1.1 drochner break; 2779 1.1 drochner } 2780 1.1 drochner 2781 1.1 drochner (void)splx(s); 2782 1.1 drochner 2783 1.77 tnn return (error); 2784 1.1 drochner } 2785 1.1 drochner 2786 1.77 tnn static void 2787 1.77 tnn ti_watchdog(struct ifnet *ifp) 2788 1.1 drochner { 2789 1.1 drochner struct ti_softc *sc; 2790 1.1 drochner 2791 1.1 drochner sc = ifp->if_softc; 2792 1.1 drochner 2793 1.91 chs aprint_error_dev(sc->sc_dev, "watchdog timeout -- resetting\n"); 2794 1.1 drochner ti_stop(sc); 2795 1.1 drochner ti_init(sc); 2796 1.1 drochner 2797 1.114 thorpej if_statinc(ifp, if_oerrors); 2798 1.1 drochner } 2799 1.1 drochner 2800 1.1 drochner /* 2801 1.1 drochner * Stop the adapter and free any mbufs allocated to the 2802 1.1 drochner * RX and TX lists. 2803 1.1 drochner */ 2804 1.77 tnn static void 2805 1.77 tnn ti_stop(struct ti_softc *sc) 2806 1.1 drochner { 2807 1.1 drochner struct ifnet *ifp; 2808 1.1 drochner struct ti_cmd_desc cmd; 2809 1.1 drochner 2810 1.1 drochner ifp = &sc->ethercom.ec_if; 2811 1.1 drochner 2812 1.1 drochner /* Disable host interrupts. */ 2813 1.1 drochner CSR_WRITE_4(sc, TI_MB_HOSTINTR, 1); 2814 1.1 drochner /* 2815 1.1 drochner * Tell firmware we're shutting down. 2816 1.1 drochner */ 2817 1.1 drochner TI_DO_CMD(TI_CMD_HOST_STATE, TI_CMD_CODE_STACK_DOWN, 0); 2818 1.1 drochner 2819 1.1 drochner /* Halt and reinitialize. */ 2820 1.1 drochner ti_chipinit(sc); 2821 1.1 drochner ti_mem(sc, 0x2000, 0x100000 - 0x2000, NULL); 2822 1.1 drochner ti_chipinit(sc); 2823 1.1 drochner 2824 1.1 drochner /* Free the RX lists. */ 2825 1.1 drochner ti_free_rx_ring_std(sc); 2826 1.1 drochner 2827 1.1 drochner /* Free jumbo RX list. */ 2828 1.1 drochner ti_free_rx_ring_jumbo(sc); 2829 1.1 drochner 2830 1.1 drochner /* Free mini RX list. */ 2831 1.1 drochner ti_free_rx_ring_mini(sc); 2832 1.1 drochner 2833 1.1 drochner /* Free TX buffers. */ 2834 1.1 drochner ti_free_tx_ring(sc); 2835 1.1 drochner 2836 1.1 drochner sc->ti_ev_prodidx.ti_idx = 0; 2837 1.1 drochner sc->ti_return_prodidx.ti_idx = 0; 2838 1.1 drochner sc->ti_tx_considx.ti_idx = 0; 2839 1.1 drochner sc->ti_tx_saved_considx = TI_TXCONS_UNSET; 2840 1.1 drochner 2841 1.1 drochner ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 2842 1.1 drochner } 2843 1.1 drochner 2844 1.1 drochner /* 2845 1.1 drochner * Stop all chip I/O so that the kernel's probe routines don't 2846 1.1 drochner * get confused by errant DMAs when rebooting. 2847 1.1 drochner */ 2848 1.86 tsutsui static bool 2849 1.86 tsutsui ti_shutdown(device_t self, int howto) 2850 1.1 drochner { 2851 1.86 tsutsui struct ti_softc *sc; 2852 1.1 drochner 2853 1.86 tsutsui sc = device_private(self); 2854 1.1 drochner ti_chipinit(sc); 2855 1.86 tsutsui 2856 1.86 tsutsui return true; 2857 1.1 drochner } 2858