if_fxp.c revision 117126
1147072Sbrooks/*- 2147072Sbrooks * Copyright (c) 1995, David Greenman 3147072Sbrooks * Copyright (c) 2001 Jonathan Lemon <jlemon@freebsd.org> 4147072Sbrooks * All rights reserved. 5147072Sbrooks * 6147072Sbrooks * Redistribution and use in source and binary forms, with or without 7147072Sbrooks * modification, are permitted provided that the following conditions 8147072Sbrooks * are met: 9147072Sbrooks * 1. Redistributions of source code must retain the above copyright 10147072Sbrooks * notice unmodified, this list of conditions, and the following 11147072Sbrooks * disclaimer. 12147072Sbrooks * 2. Redistributions in binary form must reproduce the above copyright 13147072Sbrooks * notice, this list of conditions and the following disclaimer in the 14147072Sbrooks * documentation and/or other materials provided with the distribution. 15147072Sbrooks * 16147072Sbrooks * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17147072Sbrooks * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18147072Sbrooks * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19147072Sbrooks * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20147072Sbrooks * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21147072Sbrooks * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22147072Sbrooks * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23147072Sbrooks * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24147072Sbrooks * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25147072Sbrooks * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26147072Sbrooks * SUCH DAMAGE. 27147072Sbrooks * 28147072Sbrooks */ 29147072Sbrooks 30147072Sbrooks/* 31147072Sbrooks * Intel EtherExpress Pro/100B PCI Fast Ethernet driver 32147072Sbrooks */ 33147072Sbrooks 34147072Sbrooks#include <sys/cdefs.h> 35147072Sbrooks__FBSDID("$FreeBSD: head/sys/dev/fxp/if_fxp.c 117126 2003-07-01 15:52:06Z scottl $"); 36147072Sbrooks 37147072Sbrooks#include <sys/param.h> 38147072Sbrooks#include <sys/systm.h> 39147072Sbrooks#include <sys/endian.h> 40147072Sbrooks#include <sys/mbuf.h> 41147072Sbrooks /* #include <sys/mutex.h> */ 42147072Sbrooks#include <sys/kernel.h> 43147072Sbrooks#include <sys/socket.h> 44147072Sbrooks#include <sys/sysctl.h> 45147072Sbrooks 46147072Sbrooks#include <net/if.h> 47147072Sbrooks#include <net/if_dl.h> 48147072Sbrooks#include <net/if_media.h> 49147072Sbrooks 50147072Sbrooks#include <net/bpf.h> 51147072Sbrooks#include <sys/sockio.h> 52147072Sbrooks#include <sys/bus.h> 53147072Sbrooks#include <machine/bus.h> 54147072Sbrooks#include <sys/rman.h> 55147072Sbrooks#include <machine/resource.h> 56149399Sbrooks 57149399Sbrooks#include <net/ethernet.h> 58149399Sbrooks#include <net/if_arp.h> 59147072Sbrooks 60147072Sbrooks#include <machine/clock.h> /* for DELAY */ 61147072Sbrooks 62147085Sbrooks#include <net/if_types.h> 63147085Sbrooks#include <net/if_vlan_var.h> 64147085Sbrooks 65147085Sbrooks#ifdef FXP_IP_CSUM_WAR 66147085Sbrooks#include <netinet/in.h> 67147085Sbrooks#include <netinet/in_systm.h> 68147072Sbrooks#include <netinet/ip.h> 69147072Sbrooks#include <machine/in_cksum.h> 70147072Sbrooks#endif 71147072Sbrooks 72147072Sbrooks#include <pci/pcivar.h> 73147072Sbrooks#include <pci/pcireg.h> /* for PCIM_CMD_xxx */ 74147072Sbrooks 75147072Sbrooks#include <dev/mii/mii.h> 76149639Sbrooks#include <dev/mii/miivar.h> 77147072Sbrooks 78147072Sbrooks#include <dev/fxp/if_fxpreg.h> 79147072Sbrooks#include <dev/fxp/if_fxpvar.h> 80147072Sbrooks#include <dev/fxp/rcvbundl.h> 81147072Sbrooks 82147072SbrooksMODULE_DEPEND(fxp, pci, 1, 1, 1); 83147072SbrooksMODULE_DEPEND(fxp, ether, 1, 1, 1); 84147072SbrooksMODULE_DEPEND(fxp, miibus, 1, 1, 1); 85147072Sbrooks#include "miibus_if.h" 86147072Sbrooks 87147072Sbrooks/* 88147072Sbrooks * NOTE! On the Alpha, we have an alignment constraint. The 89147072Sbrooks * card DMAs the packet immediately following the RFA. However, 90147072Sbrooks * the first thing in the packet is a 14-byte Ethernet header. 91147072Sbrooks * This means that the packet is misaligned. To compensate, 92147072Sbrooks * we actually offset the RFA 2 bytes into the cluster. This 93147072Sbrooks * alignes the packet after the Ethernet header at a 32-bit 94147072Sbrooks * boundary. HOWEVER! This means that the RFA is misaligned! 95147072Sbrooks */ 96147072Sbrooks#define RFA_ALIGNMENT_FUDGE 2 97147072Sbrooks 98231277Sbapt/* 99231277Sbapt * Set initial transmit threshold at 64 (512 bytes). This is 100231277Sbapt * increased by 64 (512 bytes) at a time, to maximum of 192 101147072Sbrooks * (1536 bytes), if an underrun occurs. 102147072Sbrooks */ 103147072Sbrooksstatic int tx_threshold = 64; 104147072Sbrooks 105147072Sbrooks/* 106147072Sbrooks * The configuration byte map has several undefined fields which 107147072Sbrooks * must be one or must be zero. Set up a template for these bits 108147072Sbrooks * only, (assuming a 82557 chip) leaving the actual configuration 109147072Sbrooks * to fxp_init. 110147072Sbrooks * 111147072Sbrooks * See struct fxp_cb_config for the bit definitions. 112147072Sbrooks */ 113147072Sbrooksstatic u_char fxp_cb_config_template[] = { 114147072Sbrooks 0x0, 0x0, /* cb_status */ 115147072Sbrooks 0x0, 0x0, /* cb_command */ 116147072Sbrooks 0x0, 0x0, 0x0, 0x0, /* link_addr */ 117147072Sbrooks 0x0, /* 0 */ 118147072Sbrooks 0x0, /* 1 */ 119147072Sbrooks 0x0, /* 2 */ 120147072Sbrooks 0x0, /* 3 */ 121166602Semaste 0x0, /* 4 */ 122147072Sbrooks 0x0, /* 5 */ 123147072Sbrooks 0x32, /* 6 */ 124149639Sbrooks 0x0, /* 7 */ 125147072Sbrooks 0x0, /* 8 */ 126147072Sbrooks 0x0, /* 9 */ 127147072Sbrooks 0x6, /* 10 */ 128147072Sbrooks 0x0, /* 11 */ 129147072Sbrooks 0x0, /* 12 */ 130147072Sbrooks 0x0, /* 13 */ 131147072Sbrooks 0xf2, /* 14 */ 132209756Sbrian 0x48, /* 15 */ 133147072Sbrooks 0x0, /* 16 */ 134147072Sbrooks 0x40, /* 17 */ 135147072Sbrooks 0xf0, /* 18 */ 136147072Sbrooks 0x0, /* 19 */ 137147072Sbrooks 0x3f, /* 20 */ 138147072Sbrooks 0x5 /* 21 */ 139147072Sbrooks}; 140147072Sbrooks 141147072Sbrooksstruct fxp_ident { 142147072Sbrooks u_int16_t devid; 143147072Sbrooks char *name; 144147072Sbrooks}; 145147072Sbrooks 146147072Sbrooks/* 147147072Sbrooks * Claim various Intel PCI device identifiers for this driver. The 148147072Sbrooks * sub-vendor and sub-device field are extensively used to identify 149147072Sbrooks * particular variants, but we don't currently differentiate between 150147072Sbrooks * them. 151147072Sbrooks */ 152147072Sbrooksstatic struct fxp_ident fxp_ident_table[] = { 153147072Sbrooks { 0x1029, "Intel 82559 PCI/CardBus Pro/100" }, 154147072Sbrooks { 0x1030, "Intel 82559 Pro/100 Ethernet" }, 155147072Sbrooks { 0x1031, "Intel 82801CAM (ICH3) Pro/100 VE Ethernet" }, 156147072Sbrooks { 0x1032, "Intel 82801CAM (ICH3) Pro/100 VE Ethernet" }, 157147072Sbrooks { 0x1033, "Intel 82801CAM (ICH3) Pro/100 VM Ethernet" }, 158147072Sbrooks { 0x1034, "Intel 82801CAM (ICH3) Pro/100 VM Ethernet" }, 159147072Sbrooks { 0x1035, "Intel 82801CAM (ICH3) Pro/100 Ethernet" }, 160147072Sbrooks { 0x1036, "Intel 82801CAM (ICH3) Pro/100 Ethernet" }, 161147072Sbrooks { 0x1037, "Intel 82801CAM (ICH3) Pro/100 Ethernet" }, 162147072Sbrooks { 0x1038, "Intel 82801CAM (ICH3) Pro/100 VM Ethernet" }, 163147072Sbrooks { 0x1039, "Intel 82801DB (ICH4) Pro/100 VE Ethernet" }, 164147072Sbrooks { 0x103A, "Intel 82801DB (ICH4) Pro/100 Ethernet" }, 165147072Sbrooks { 0x103B, "Intel 82801DB (ICH4) Pro/100 VM Ethernet" }, 166147072Sbrooks { 0x103C, "Intel 82801DB (ICH4) Pro/100 Ethernet" }, 167147072Sbrooks { 0x103D, "Intel 82801DB (ICH4) Pro/100 VE Ethernet" }, 168147072Sbrooks { 0x103E, "Intel 82801DB (ICH4) Pro/100 VM Ethernet" }, 169147072Sbrooks { 0x1050, "Intel 82801BA (D865) Pro/100 VE Ethernet" }, 170147072Sbrooks { 0x1059, "Intel 82551QM Pro/100 M Mobile Connection" }, 171147072Sbrooks { 0x1209, "Intel 82559ER Embedded 10/100 Ethernet" }, 172147072Sbrooks { 0x1229, "Intel 82557/8/9 EtherExpress Pro/100(B) Ethernet" }, 173147072Sbrooks { 0x2449, "Intel 82801BA/CAM (ICH2/3) Pro/100 Ethernet" }, 174147072Sbrooks { 0, NULL }, 175147072Sbrooks}; 176147072Sbrooks 177147072Sbrooks#ifdef FXP_IP_CSUM_WAR 178147072Sbrooks#define FXP_CSUM_FEATURES (CSUM_IP | CSUM_TCP | CSUM_UDP) 179147072Sbrooks#else 180147072Sbrooks#define FXP_CSUM_FEATURES (CSUM_TCP | CSUM_UDP) 181147072Sbrooks#endif 182177501Ssam 183147072Sbrooksstatic int fxp_probe(device_t dev); 184177501Ssamstatic int fxp_attach(device_t dev); 185147072Sbrooksstatic int fxp_detach(device_t dev); 186177501Ssamstatic int fxp_shutdown(device_t dev); 187177501Ssamstatic int fxp_suspend(device_t dev); 188177501Ssamstatic int fxp_resume(device_t dev); 189177501Ssam 190177501Ssamstatic void fxp_intr(void *xsc); 191177501Ssamstatic void fxp_intr_body(struct fxp_softc *sc, struct ifnet *ifp, 192177501Ssam u_int8_t statack, int count); 193177501Ssamstatic void fxp_init(void *xsc); 194177501Ssamstatic void fxp_init_body(struct fxp_softc *sc); 195177501Ssamstatic void fxp_tick(void *xsc); 196177501Ssamstatic void fxp_powerstate_d0(device_t dev); 197177501Ssamstatic void fxp_start(struct ifnet *ifp); 198177501Ssamstatic void fxp_start_body(struct ifnet *ifp); 199177501Ssamstatic void fxp_stop(struct fxp_softc *sc); 200177501Ssamstatic void fxp_release(struct fxp_softc *sc); 201177501Ssamstatic int fxp_ioctl(struct ifnet *ifp, u_long command, 202177501Ssam caddr_t data); 203177501Ssamstatic void fxp_watchdog(struct ifnet *ifp); 204177501Ssamstatic int fxp_add_rfabuf(struct fxp_softc *sc, 205177501Ssam struct fxp_rx *rxp); 206147072Sbrooksstatic int fxp_mc_addrs(struct fxp_softc *sc); 207147072Sbrooksstatic void fxp_mc_setup(struct fxp_softc *sc); 208147072Sbrooksstatic u_int16_t fxp_eeprom_getword(struct fxp_softc *sc, int offset, 209147072Sbrooks int autosize); 210209756Sbrianstatic void fxp_eeprom_putword(struct fxp_softc *sc, int offset, 211147072Sbrooks u_int16_t data); 212147072Sbrooksstatic void fxp_autosize_eeprom(struct fxp_softc *sc); 213147072Sbrooksstatic void fxp_read_eeprom(struct fxp_softc *sc, u_short *data, 214147072Sbrooks int offset, int words); 215177501Ssamstatic void fxp_write_eeprom(struct fxp_softc *sc, u_short *data, 216147072Sbrooks int offset, int words); 217147072Sbrooksstatic int fxp_ifmedia_upd(struct ifnet *ifp); 218147072Sbrooksstatic void fxp_ifmedia_sts(struct ifnet *ifp, 219147072Sbrooks struct ifmediareq *ifmr); 220147072Sbrooksstatic int fxp_serial_ifmedia_upd(struct ifnet *ifp); 221247335Sjhbstatic void fxp_serial_ifmedia_sts(struct ifnet *ifp, 222147072Sbrooks struct ifmediareq *ifmr); 223147072Sbrooksstatic volatile int fxp_miibus_readreg(device_t dev, int phy, int reg); 224147072Sbrooksstatic void fxp_miibus_writereg(device_t dev, int phy, int reg, 225147072Sbrooks int value); 226147072Sbrooksstatic void fxp_load_ucode(struct fxp_softc *sc); 227147072Sbrooksstatic int sysctl_int_range(SYSCTL_HANDLER_ARGS, 228147072Sbrooks int low, int high); 229147072Sbrooksstatic int sysctl_hw_fxp_bundle_max(SYSCTL_HANDLER_ARGS); 230147072Sbrooksstatic int sysctl_hw_fxp_int_delay(SYSCTL_HANDLER_ARGS); 231154161Sbrooksstatic __inline void fxp_scb_wait(struct fxp_softc *sc); 232147072Sbrooksstatic __inline void fxp_scb_cmd(struct fxp_softc *sc, int cmd); 233154161Sbrooksstatic __inline void fxp_dma_wait(struct fxp_softc *sc, 234147072Sbrooks volatile u_int16_t *status, bus_dma_tag_t dmat, 235147072Sbrooks bus_dmamap_t map); 236147072Sbrooks 237147072Sbrooksstatic device_method_t fxp_methods[] = { 238154161Sbrooks /* Device interface */ 239154161Sbrooks DEVMETHOD(device_probe, fxp_probe), 240154161Sbrooks DEVMETHOD(device_attach, fxp_attach), 241147072Sbrooks DEVMETHOD(device_detach, fxp_detach), 242147072Sbrooks DEVMETHOD(device_shutdown, fxp_shutdown), 243209756Sbrian DEVMETHOD(device_suspend, fxp_suspend), 244147072Sbrooks DEVMETHOD(device_resume, fxp_resume), 245147072Sbrooks 246147072Sbrooks /* MII interface */ 247147072Sbrooks DEVMETHOD(miibus_readreg, fxp_miibus_readreg), 248147072Sbrooks DEVMETHOD(miibus_writereg, fxp_miibus_writereg), 249147072Sbrooks 250147072Sbrooks { 0, 0 } 251147072Sbrooks}; 252147072Sbrooks 253147072Sbrooksstatic driver_t fxp_driver = { 254147072Sbrooks "fxp", 255209756Sbrian fxp_methods, 256147072Sbrooks sizeof(struct fxp_softc), 257209756Sbrian}; 258209756Sbrian 259209756Sbrianstatic devclass_t fxp_devclass; 260209756Sbrian 261209756SbrianDRIVER_MODULE(fxp, pci, fxp_driver, fxp_devclass, 0, 0); 262209756SbrianDRIVER_MODULE(fxp, cardbus, fxp_driver, fxp_devclass, 0, 0); 263209756SbrianDRIVER_MODULE(miibus, fxp, miibus_driver, miibus_devclass, 0, 0); 264209756Sbrian 265209756Sbrianstatic int fxp_rnr; 266209756SbrianSYSCTL_INT(_hw, OID_AUTO, fxp_rnr, CTLFLAG_RW, &fxp_rnr, 0, "fxp rnr events"); 267209756Sbrian 268209756Sbrianstatic int fxp_noflow; 269209756SbrianSYSCTL_INT(_hw, OID_AUTO, fxp_noflow, CTLFLAG_RW, &fxp_noflow, 0, "fxp flow control disabled"); 270209756SbrianTUNABLE_INT("hw.fxp_noflow", &fxp_noflow); 271209756Sbrian 272209756Sbrian/* 273147072Sbrooks * Wait for the previous command to be accepted (but not necessarily 274147072Sbrooks * completed). 275147072Sbrooks */ 276147072Sbrooksstatic __inline void 277209756Sbrianfxp_scb_wait(struct fxp_softc *sc) 278209756Sbrian{ 279209756Sbrian int i = 10000; 280147072Sbrooks 281209756Sbrian while (CSR_READ_1(sc, FXP_CSR_SCB_COMMAND) && --i) 282247335Sjhb DELAY(2); 283247335Sjhb if (i == 0) 284247335Sjhb device_printf(sc->dev, "SCB timeout: 0x%x 0x%x 0x%x 0x%x\n", 285247335Sjhb CSR_READ_1(sc, FXP_CSR_SCB_COMMAND), 286247335Sjhb CSR_READ_1(sc, FXP_CSR_SCB_STATACK), 287247335Sjhb CSR_READ_1(sc, FXP_CSR_SCB_RUSCUS), 288247335Sjhb CSR_READ_2(sc, FXP_CSR_FLOWCONTROL)); 289247335Sjhb} 290247335Sjhb 291147072Sbrooksstatic __inline void 292147072Sbrooksfxp_scb_cmd(struct fxp_softc *sc, int cmd) 293147072Sbrooks{ 294147072Sbrooks 295209756Sbrian if (cmd == FXP_SCB_COMMAND_CU_RESUME && sc->cu_resume_bug) { 296209756Sbrian CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_CB_COMMAND_NOP); 297209756Sbrian fxp_scb_wait(sc); 298147072Sbrooks } 299209756Sbrian CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, cmd); 300147072Sbrooks} 301147085Sbrooks 302147085Sbrooksstatic __inline void 303147085Sbrooksfxp_dma_wait(struct fxp_softc *sc, volatile u_int16_t *status, 304147085Sbrooks bus_dma_tag_t dmat, bus_dmamap_t map) 305147085Sbrooks{ 306147085Sbrooks int i = 10000; 307148373Ssam 308147085Sbrooks bus_dmamap_sync(dmat, map, BUS_DMASYNC_POSTREAD); 309177501Ssam while (!(le16toh(*status) & FXP_CB_STATUS_C) && --i) { 310177501Ssam DELAY(2); 311177501Ssam bus_dmamap_sync(dmat, map, BUS_DMASYNC_POSTREAD); 312147085Sbrooks } 313177501Ssam if (i == 0) 314177501Ssam device_printf(sc->dev, "DMA timeout\n"); 315177501Ssam} 316177501Ssam 317147351Sbrooks/* 318177501Ssam * Return identification string if this is device is ours. 319147085Sbrooks */ 320147085Sbrooksstatic int 321147085Sbrooksfxp_probe(device_t dev) 322147072Sbrooks{ 323147072Sbrooks u_int16_t devid; 324147072Sbrooks struct fxp_ident *ident; 325147072Sbrooks 326147072Sbrooks if (pci_get_vendor(dev) == FXP_VENDORID_INTEL) { 327147072Sbrooks devid = pci_get_device(dev); 328147072Sbrooks for (ident = fxp_ident_table; ident->name != NULL; ident++) { 329147072Sbrooks if (ident->devid == devid) { 330147072Sbrooks device_set_desc(dev, ident->name); 331147072Sbrooks return (0); 332231277Sbapt } 333231277Sbapt } 334147072Sbrooks } 335147072Sbrooks return (ENXIO); 336147072Sbrooks} 337147072Sbrooks 338147072Sbrooksstatic void 339147072Sbrooksfxp_powerstate_d0(device_t dev) 340147072Sbrooks{ 341147072Sbrooks#if __FreeBSD_version >= 430002 342147072Sbrooks u_int32_t iobase, membase, irq; 343147085Sbrooks 344147072Sbrooks if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) { 345231277Sbapt /* Save important PCI config data. */ 346147072Sbrooks iobase = pci_read_config(dev, FXP_PCI_IOBA, 4); 347147072Sbrooks membase = pci_read_config(dev, FXP_PCI_MMBA, 4); 348147072Sbrooks irq = pci_read_config(dev, PCIR_INTLINE, 4); 349177500Ssam 350147072Sbrooks /* Reset the power state. */ 351231277Sbapt device_printf(dev, "chip is in D%d power mode " 352147072Sbrooks "-- setting to D0\n", pci_get_powerstate(dev)); 353147085Sbrooks 354147085Sbrooks pci_set_powerstate(dev, PCI_POWERSTATE_D0); 355147085Sbrooks 356147072Sbrooks /* Restore PCI config data. */ 357147072Sbrooks pci_write_config(dev, FXP_PCI_IOBA, iobase, 4); 358147072Sbrooks pci_write_config(dev, FXP_PCI_MMBA, membase, 4); 359147072Sbrooks pci_write_config(dev, PCIR_INTLINE, irq, 4); 360147072Sbrooks } 361147072Sbrooks#endif 362147072Sbrooks} 363147072Sbrooks 364147072Sbrooksstatic void 365231277Sbaptfxp_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error) 366231277Sbapt{ 367231277Sbapt u_int32_t *addr; 368147072Sbrooks 369147072Sbrooks if (error) 370147072Sbrooks return; 371147072Sbrooks 372147072Sbrooks KASSERT(nseg == 1, ("too many DMA segments, %d should be 1", nseg)); 373147072Sbrooks addr = arg; 374147072Sbrooks *addr = segs->ds_addr; 375147072Sbrooks} 376147072Sbrooks 377147072Sbrooksstatic int 378147072Sbrooksfxp_attach(device_t dev) 379147072Sbrooks{ 380147072Sbrooks int error = 0; 381147072Sbrooks struct fxp_softc *sc = device_get_softc(dev); 382147072Sbrooks struct ifnet *ifp; 383147072Sbrooks struct fxp_rx *rxp; 384231277Sbapt u_int32_t val; 385231277Sbapt u_int16_t data, myea[ETHER_ADDR_LEN / 2]; 386231277Sbapt int i, rid, m1, m2, prefer_iomap, maxtxseg; 387231277Sbapt int s, ipcbxmit_disable; 388231277Sbapt 389231277Sbapt sc->dev = dev; 390231277Sbapt callout_handle_init(&sc->stat_ch); 391231277Sbapt sysctl_ctx_init(&sc->sysctl_ctx); 392231277Sbapt mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, 393231277Sbapt MTX_DEF); 394231277Sbapt ifmedia_init(&sc->sc_media, 0, fxp_serial_ifmedia_upd, 395231277Sbapt fxp_serial_ifmedia_sts); 396231277Sbapt 397231277Sbapt s = splimp(); 398231277Sbapt 399147072Sbrooks /* 400147072Sbrooks * Enable bus mastering. 401147072Sbrooks */ 402147072Sbrooks pci_enable_busmaster(dev); 403147072Sbrooks val = pci_read_config(dev, PCIR_COMMAND, 2); 404147072Sbrooks 405147072Sbrooks fxp_powerstate_d0(dev); 406147072Sbrooks 407147072Sbrooks /* 408147072Sbrooks * Figure out which we should try first - memory mapping or i/o mapping? 409147072Sbrooks * We default to memory mapping. Then we accept an override from the 410147072Sbrooks * command line. Then we check to see which one is enabled. 411147072Sbrooks */ 412147072Sbrooks m1 = PCIM_CMD_MEMEN; 413147072Sbrooks m2 = PCIM_CMD_PORTEN; 414147072Sbrooks prefer_iomap = 0; 415147072Sbrooks if (resource_int_value(device_get_name(dev), device_get_unit(dev), 416147072Sbrooks "prefer_iomap", &prefer_iomap) == 0 && prefer_iomap != 0) { 417147072Sbrooks m1 = PCIM_CMD_PORTEN; 418147072Sbrooks m2 = PCIM_CMD_MEMEN; 419147072Sbrooks } 420147072Sbrooks 421147072Sbrooks sc->rtp = (m1 == PCIM_CMD_MEMEN)? SYS_RES_MEMORY : SYS_RES_IOPORT; 422231277Sbapt sc->rgd = (m1 == PCIM_CMD_MEMEN)? FXP_PCI_MMBA : FXP_PCI_IOBA; 423231277Sbapt sc->mem = bus_alloc_resource(dev, sc->rtp, &sc->rgd, 424231277Sbapt 0, ~0, 1, RF_ACTIVE); 425231277Sbapt if (sc->mem == NULL) { 426231277Sbapt sc->rtp = 427231277Sbapt (m2 == PCIM_CMD_MEMEN)? SYS_RES_MEMORY : SYS_RES_IOPORT; 428147072Sbrooks sc->rgd = (m2 == PCIM_CMD_MEMEN)? FXP_PCI_MMBA : FXP_PCI_IOBA; 429147072Sbrooks sc->mem = bus_alloc_resource(dev, sc->rtp, &sc->rgd, 430147072Sbrooks 0, ~0, 1, RF_ACTIVE); 431147072Sbrooks } 432147072Sbrooks 433147072Sbrooks if (!sc->mem) { 434147072Sbrooks error = ENXIO; 435147072Sbrooks goto fail; 436161514Sbrian } 437161514Sbrian if (bootverbose) { 438147072Sbrooks device_printf(dev, "using %s space register mapping\n", 439147072Sbrooks sc->rtp == SYS_RES_MEMORY? "memory" : "I/O"); 440147072Sbrooks } 441161514Sbrian 442147072Sbrooks sc->sc_st = rman_get_bustag(sc->mem); 443247335Sjhb sc->sc_sh = rman_get_bushandle(sc->mem); 444147072Sbrooks 445147072Sbrooks /* 446147072Sbrooks * Allocate our interrupt. 447147072Sbrooks */ 448147072Sbrooks rid = 0; 449147072Sbrooks sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, 450147072Sbrooks RF_SHAREABLE | RF_ACTIVE); 451147072Sbrooks if (sc->irq == NULL) { 452147072Sbrooks device_printf(dev, "could not map interrupt\n"); 453147072Sbrooks error = ENXIO; 454147072Sbrooks goto fail; 455147072Sbrooks } 456147072Sbrooks 457147072Sbrooks /* 458147072Sbrooks * Reset to a stable state. 459147072Sbrooks */ 460147072Sbrooks CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SELECTIVE_RESET); 461147072Sbrooks DELAY(10); 462147072Sbrooks 463147072Sbrooks /* 464147072Sbrooks * Find out how large of an SEEPROM we have. 465147072Sbrooks */ 466147072Sbrooks fxp_autosize_eeprom(sc); 467147072Sbrooks 468147072Sbrooks /* 469147072Sbrooks * Determine whether we must use the 503 serial interface. 470147072Sbrooks */ 471147072Sbrooks fxp_read_eeprom(sc, &data, 6, 1); 472147072Sbrooks if ((data & FXP_PHY_DEVICE_MASK) != 0 && 473147072Sbrooks (data & FXP_PHY_SERIAL_ONLY)) 474147072Sbrooks sc->flags |= FXP_FLAG_SERIAL_MEDIA; 475147072Sbrooks 476147072Sbrooks /* 477147072Sbrooks * Create the sysctl tree 478147072Sbrooks */ 479147072Sbrooks sc->sysctl_tree = SYSCTL_ADD_NODE(&sc->sysctl_ctx, 480147072Sbrooks SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO, 481147072Sbrooks device_get_nameunit(dev), CTLFLAG_RD, 0, ""); 482147072Sbrooks if (sc->sysctl_tree == NULL) { 483147072Sbrooks error = ENXIO; 484147072Sbrooks goto fail; 485147072Sbrooks } 486147072Sbrooks SYSCTL_ADD_PROC(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree), 487147072Sbrooks OID_AUTO, "int_delay", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_PRISON, 488147072Sbrooks &sc->tunable_int_delay, 0, sysctl_hw_fxp_int_delay, "I", 489147072Sbrooks "FXP driver receive interrupt microcode bundling delay"); 490147072Sbrooks SYSCTL_ADD_PROC(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree), 491147072Sbrooks OID_AUTO, "bundle_max", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_PRISON, 492147072Sbrooks &sc->tunable_bundle_max, 0, sysctl_hw_fxp_bundle_max, "I", 493147085Sbrooks "FXP driver receive interrupt microcode bundle size limit"); 494147085Sbrooks 495147085Sbrooks /* 496147072Sbrooks * Pull in device tunables. 497147072Sbrooks */ 498147072Sbrooks sc->tunable_int_delay = TUNABLE_INT_DELAY; 499147072Sbrooks sc->tunable_bundle_max = TUNABLE_BUNDLE_MAX; 500147072Sbrooks (void) resource_int_value(device_get_name(dev), device_get_unit(dev), 501147072Sbrooks "int_delay", &sc->tunable_int_delay); 502147072Sbrooks (void) resource_int_value(device_get_name(dev), device_get_unit(dev), 503147072Sbrooks "bundle_max", &sc->tunable_bundle_max); 504147072Sbrooks 505147072Sbrooks /* 506147072Sbrooks * Find out the chip revision; lump all 82557 revs together. 507147072Sbrooks */ 508147072Sbrooks fxp_read_eeprom(sc, &data, 5, 1); 509147072Sbrooks if ((data >> 8) == 1) 510147072Sbrooks sc->revision = FXP_REV_82557; 511147072Sbrooks else 512161514Sbrian sc->revision = pci_get_revid(dev); 513147072Sbrooks 514147072Sbrooks /* 515147072Sbrooks * Enable workarounds for certain chip revision deficiencies. 516147072Sbrooks * 517147072Sbrooks * Systems based on the ICH2/ICH2-M chip from Intel, and possibly 518147072Sbrooks * some systems based a normal 82559 design, have a defect where 519147072Sbrooks * the chip can cause a PCI protocol violation if it receives 520147072Sbrooks * a CU_RESUME command when it is entering the IDLE state. The 521147072Sbrooks * workaround is to disable Dynamic Standby Mode, so the chip never 522147072Sbrooks * deasserts CLKRUN#, and always remains in an active state. 523147072Sbrooks * 524147072Sbrooks * See Intel 82801BA/82801BAM Specification Update, Errata #30. 525147072Sbrooks */ 526147072Sbrooks i = pci_get_device(dev); 527147072Sbrooks if (i == 0x2449 || (i > 0x1030 && i < 0x1039) || 528147072Sbrooks sc->revision >= FXP_REV_82559_A0) { 529147072Sbrooks fxp_read_eeprom(sc, &data, 10, 1); 530147072Sbrooks if (data & 0x02) { /* STB enable */ 531147072Sbrooks u_int16_t cksum; 532147072Sbrooks int i; 533147072Sbrooks 534147072Sbrooks device_printf(dev, 535147072Sbrooks "Disabling dynamic standby mode in EEPROM\n"); 536147072Sbrooks data &= ~0x02; 537147072Sbrooks fxp_write_eeprom(sc, &data, 10, 1); 538147072Sbrooks device_printf(dev, "New EEPROM ID: 0x%x\n", data); 539147072Sbrooks cksum = 0; 540147072Sbrooks for (i = 0; i < (1 << sc->eeprom_size) - 1; i++) { 541147072Sbrooks fxp_read_eeprom(sc, &data, i, 1); 542147072Sbrooks cksum += data; 543147072Sbrooks } 544147072Sbrooks i = (1 << sc->eeprom_size) - 1; 545147072Sbrooks cksum = 0xBABA - cksum; 546147072Sbrooks fxp_read_eeprom(sc, &data, i, 1); 547147072Sbrooks fxp_write_eeprom(sc, &cksum, i, 1); 548147072Sbrooks device_printf(dev, 549147072Sbrooks "EEPROM checksum @ 0x%x: 0x%x -> 0x%x\n", 550147072Sbrooks i, data, cksum); 551147072Sbrooks#if 1 552147072Sbrooks /* 553147072Sbrooks * If the user elects to continue, try the software 554147072Sbrooks * workaround, as it is better than nothing. 555147072Sbrooks */ 556147072Sbrooks sc->flags |= FXP_FLAG_CU_RESUME_BUG; 557147072Sbrooks#endif 558147072Sbrooks } 559147072Sbrooks } 560147072Sbrooks 561147072Sbrooks /* 562147072Sbrooks * If we are not a 82557 chip, we can enable extended features. 563147072Sbrooks */ 564147072Sbrooks if (sc->revision != FXP_REV_82557) { 565147072Sbrooks /* 566147072Sbrooks * If MWI is enabled in the PCI configuration, and there 567147072Sbrooks * is a valid cacheline size (8 or 16 dwords), then tell 568147072Sbrooks * the board to turn on MWI. 569147072Sbrooks */ 570147072Sbrooks if (val & PCIM_CMD_MWRICEN && 571147072Sbrooks pci_read_config(dev, PCIR_CACHELNSZ, 1) != 0) 572147072Sbrooks sc->flags |= FXP_FLAG_MWI_ENABLE; 573147072Sbrooks 574147072Sbrooks /* turn on the extended TxCB feature */ 575147072Sbrooks sc->flags |= FXP_FLAG_EXT_TXCB; 576147072Sbrooks 577147072Sbrooks /* enable reception of long frames for VLAN */ 578147072Sbrooks sc->flags |= FXP_FLAG_LONG_PKT_EN; 579147072Sbrooks } 580147072Sbrooks 581147072Sbrooks /* 582147072Sbrooks * Enable use of extended RFDs and TCBs for 82550 583147072Sbrooks * and later chips. Note: we need extended TXCB support 584147072Sbrooks * too, but that's already enabled by the code above. 585147072Sbrooks * Be careful to do this only on the right devices. 586147072Sbrooks * 587147072Sbrooks * At least some 82550 cards probed as "chip=0x12298086 rev=0x0d" 588147072Sbrooks * truncate packets that end with an mbuf containing 1 to 3 bytes 589147072Sbrooks * when used with this feature enabled in the previous version of the 590147072Sbrooks * driver. This problem appears to be fixed now that the driver 591147072Sbrooks * always sets the hardware parse bit in the IPCB structure, which 592147072Sbrooks * the "Intel 8255x 10/100 Mbps Ethernet Controller Family Open 593147072Sbrooks * Source Software Developer Manual" says is necessary in the 594147072Sbrooks * cases where packet truncation was observed. 595147072Sbrooks * 596147072Sbrooks * The device hint "hint.fxp.UNIT_NUMBER.ipcbxmit_disable" 597147072Sbrooks * allows this feature to be disabled at boot time. 598147072Sbrooks * 599147072Sbrooks * If fxp is not compiled into the kernel, this feature may also 600147072Sbrooks * be disabled at run time: 601147072Sbrooks * # kldunload fxp 602147072Sbrooks * # kenv hint.fxp.0.ipcbxmit_disable=1 603147072Sbrooks * # kldload fxp 604147072Sbrooks */ 605147072Sbrooks 606147072Sbrooks if (resource_int_value("fxp", device_get_unit(dev), "ipcbxmit_disable", 607147072Sbrooks &ipcbxmit_disable) != 0) 608147072Sbrooks ipcbxmit_disable = 0; 609147072Sbrooks if (ipcbxmit_disable == 0 && (sc->revision == FXP_REV_82550 || 610147072Sbrooks sc->revision == FXP_REV_82550_C)) { 611147072Sbrooks sc->rfa_size = sizeof (struct fxp_rfa); 612147072Sbrooks sc->tx_cmd = FXP_CB_COMMAND_IPCBXMIT; 613147072Sbrooks sc->flags |= FXP_FLAG_EXT_RFA; 614147072Sbrooks } else { 615147072Sbrooks sc->rfa_size = sizeof (struct fxp_rfa) - FXP_RFAX_LEN; 616147072Sbrooks sc->tx_cmd = FXP_CB_COMMAND_XMIT; 617147072Sbrooks } 618147072Sbrooks 619147072Sbrooks /* 620147072Sbrooks * Allocate DMA tags and DMA safe memory. 621147072Sbrooks */ 622147072Sbrooks maxtxseg = sc->flags & FXP_FLAG_EXT_RFA ? FXP_NTXSEG - 1 : FXP_NTXSEG; 623147072Sbrooks error = bus_dma_tag_create(NULL, 2, 0, BUS_SPACE_MAXADDR_32BIT, 624147072Sbrooks BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES * maxtxseg, 625147072Sbrooks maxtxseg, MCLBYTES, 0, busdma_lock_mutex, &Giant, &sc->fxp_mtag); 626147072Sbrooks if (error) { 627147072Sbrooks device_printf(dev, "could not allocate dma tag\n"); 628147072Sbrooks goto fail; 629147072Sbrooks } 630147072Sbrooks 631147072Sbrooks error = bus_dma_tag_create(NULL, 4, 0, BUS_SPACE_MAXADDR_32BIT, 632147072Sbrooks BUS_SPACE_MAXADDR, NULL, NULL, sizeof(struct fxp_stats), 1, 633147072Sbrooks sizeof(struct fxp_stats), 0, busdma_lock_mutex, &Giant, 634147072Sbrooks &sc->fxp_stag); 635147072Sbrooks if (error) { 636147072Sbrooks device_printf(dev, "could not allocate dma tag\n"); 637147072Sbrooks goto fail; 638147072Sbrooks } 639147072Sbrooks 640147072Sbrooks error = bus_dmamem_alloc(sc->fxp_stag, (void **)&sc->fxp_stats, 641147072Sbrooks BUS_DMA_NOWAIT, &sc->fxp_smap); 642147072Sbrooks if (error) 643147072Sbrooks goto fail; 644147072Sbrooks error = bus_dmamap_load(sc->fxp_stag, sc->fxp_smap, sc->fxp_stats, 645147072Sbrooks sizeof(struct fxp_stats), fxp_dma_map_addr, &sc->stats_addr, 0); 646147072Sbrooks if (error) { 647147072Sbrooks device_printf(dev, "could not map the stats buffer\n"); 648147072Sbrooks goto fail; 649147072Sbrooks } 650147072Sbrooks bzero(sc->fxp_stats, sizeof(struct fxp_stats)); 651147072Sbrooks 652147072Sbrooks error = bus_dma_tag_create(NULL, 4, 0, BUS_SPACE_MAXADDR_32BIT, 653147072Sbrooks BUS_SPACE_MAXADDR, NULL, NULL, FXP_TXCB_SZ, 1, 654147072Sbrooks FXP_TXCB_SZ, 0, busdma_lock_mutex, &Giant, &sc->cbl_tag); 655147072Sbrooks if (error) { 656147072Sbrooks device_printf(dev, "could not allocate dma tag\n"); 657147072Sbrooks goto fail; 658147072Sbrooks } 659147072Sbrooks 660147072Sbrooks error = bus_dmamem_alloc(sc->cbl_tag, (void **)&sc->fxp_desc.cbl_list, 661147072Sbrooks BUS_DMA_NOWAIT, &sc->cbl_map); 662147072Sbrooks if (error) 663147072Sbrooks goto fail; 664147072Sbrooks bzero(sc->fxp_desc.cbl_list, FXP_TXCB_SZ); 665147072Sbrooks 666147072Sbrooks error = bus_dmamap_load(sc->cbl_tag, sc->cbl_map, 667147072Sbrooks sc->fxp_desc.cbl_list, FXP_TXCB_SZ, fxp_dma_map_addr, 668147072Sbrooks &sc->fxp_desc.cbl_addr, 0); 669147072Sbrooks if (error) { 670147072Sbrooks device_printf(dev, "could not map DMA memory\n"); 671147072Sbrooks goto fail; 672147072Sbrooks } 673147072Sbrooks 674147072Sbrooks error = bus_dma_tag_create(NULL, 4, 0, BUS_SPACE_MAXADDR_32BIT, 675147072Sbrooks BUS_SPACE_MAXADDR, NULL, NULL, sizeof(struct fxp_cb_mcs), 1, 676147072Sbrooks sizeof(struct fxp_cb_mcs), 0, busdma_lock_mutex, &Giant, 677147072Sbrooks &sc->mcs_tag); 678147072Sbrooks if (error) { 679147072Sbrooks device_printf(dev, "could not allocate dma tag\n"); 680147072Sbrooks goto fail; 681147072Sbrooks } 682147072Sbrooks 683147072Sbrooks error = bus_dmamem_alloc(sc->mcs_tag, (void **)&sc->mcsp, 684147072Sbrooks BUS_DMA_NOWAIT, &sc->mcs_map); 685147072Sbrooks if (error) 686147072Sbrooks goto fail; 687147072Sbrooks error = bus_dmamap_load(sc->mcs_tag, sc->mcs_map, sc->mcsp, 688147072Sbrooks sizeof(struct fxp_cb_mcs), fxp_dma_map_addr, &sc->mcs_addr, 0); 689147072Sbrooks if (error) { 690147072Sbrooks device_printf(dev, "can't map the multicast setup command\n"); 691147072Sbrooks goto fail; 692147072Sbrooks } 693147072Sbrooks 694147072Sbrooks /* 695147072Sbrooks * Pre-allocate the TX DMA maps. 696147072Sbrooks */ 697147072Sbrooks for (i = 0; i < FXP_NTXCB; i++) { 698147072Sbrooks error = bus_dmamap_create(sc->fxp_mtag, 0, 699147072Sbrooks &sc->fxp_desc.tx_list[i].tx_map); 700147072Sbrooks if (error) { 701147072Sbrooks device_printf(dev, "can't create DMA map for TX\n"); 702147072Sbrooks goto fail; 703147072Sbrooks } 704147072Sbrooks } 705147072Sbrooks error = bus_dmamap_create(sc->fxp_mtag, 0, &sc->spare_map); 706147072Sbrooks if (error) { 707147072Sbrooks device_printf(dev, "can't create spare DMA map\n"); 708147072Sbrooks goto fail; 709147072Sbrooks } 710147072Sbrooks 711147072Sbrooks /* 712147072Sbrooks * Pre-allocate our receive buffers. 713147072Sbrooks */ 714147072Sbrooks sc->fxp_desc.rx_head = sc->fxp_desc.rx_tail = NULL; 715147072Sbrooks for (i = 0; i < FXP_NRFABUFS; i++) { 716147072Sbrooks rxp = &sc->fxp_desc.rx_list[i]; 717147072Sbrooks error = bus_dmamap_create(sc->fxp_mtag, 0, &rxp->rx_map); 718147072Sbrooks if (error) { 719147072Sbrooks device_printf(dev, "can't create DMA map for RX\n"); 720147072Sbrooks goto fail; 721147072Sbrooks } 722147072Sbrooks if (fxp_add_rfabuf(sc, rxp) != 0) { 723147072Sbrooks error = ENOMEM; 724147072Sbrooks goto fail; 725147072Sbrooks } 726147072Sbrooks } 727147072Sbrooks 728147072Sbrooks /* 729147072Sbrooks * Read MAC address. 730147072Sbrooks */ 731147072Sbrooks fxp_read_eeprom(sc, myea, 0, 3); 732147072Sbrooks sc->arpcom.ac_enaddr[0] = myea[0] & 0xff; 733147072Sbrooks sc->arpcom.ac_enaddr[1] = myea[0] >> 8; 734147072Sbrooks sc->arpcom.ac_enaddr[2] = myea[1] & 0xff; 735147072Sbrooks sc->arpcom.ac_enaddr[3] = myea[1] >> 8; 736147072Sbrooks sc->arpcom.ac_enaddr[4] = myea[2] & 0xff; 737147072Sbrooks sc->arpcom.ac_enaddr[5] = myea[2] >> 8; 738147072Sbrooks device_printf(dev, "Ethernet address %6D%s\n", 739147072Sbrooks sc->arpcom.ac_enaddr, ":", 740147072Sbrooks sc->flags & FXP_FLAG_SERIAL_MEDIA ? ", 10Mbps" : ""); 741147072Sbrooks if (bootverbose) { 742147072Sbrooks device_printf(dev, "PCI IDs: %04x %04x %04x %04x %04x\n", 743147072Sbrooks pci_get_vendor(dev), pci_get_device(dev), 744147072Sbrooks pci_get_subvendor(dev), pci_get_subdevice(dev), 745147072Sbrooks pci_get_revid(dev)); 746147072Sbrooks fxp_read_eeprom(sc, &data, 10, 1); 747147072Sbrooks device_printf(dev, "Dynamic Standby mode is %s\n", 748147072Sbrooks data & 0x02 ? "enabled" : "disabled"); 749147072Sbrooks } 750147072Sbrooks 751147072Sbrooks /* 752147072Sbrooks * If this is only a 10Mbps device, then there is no MII, and 753147072Sbrooks * the PHY will use a serial interface instead. 754147072Sbrooks * 755147072Sbrooks * The Seeq 80c24 AutoDUPLEX(tm) Ethernet Interface Adapter 756147072Sbrooks * doesn't have a programming interface of any sort. The 757147072Sbrooks * media is sensed automatically based on how the link partner 758147072Sbrooks * is configured. This is, in essence, manual configuration. 759147072Sbrooks */ 760147072Sbrooks if (sc->flags & FXP_FLAG_SERIAL_MEDIA) { 761147072Sbrooks ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL); 762147072Sbrooks ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL); 763147072Sbrooks } else { 764147072Sbrooks if (mii_phy_probe(dev, &sc->miibus, fxp_ifmedia_upd, 765147072Sbrooks fxp_ifmedia_sts)) { 766147072Sbrooks device_printf(dev, "MII without any PHY!\n"); 767147072Sbrooks error = ENXIO; 768147072Sbrooks goto fail; 769147072Sbrooks } 770147072Sbrooks } 771147072Sbrooks 772147072Sbrooks ifp = &sc->arpcom.ac_if; 773147072Sbrooks ifp->if_unit = device_get_unit(dev); 774147072Sbrooks ifp->if_name = "fxp"; 775147072Sbrooks ifp->if_output = ether_output; 776147072Sbrooks ifp->if_baudrate = 100000000; 777147072Sbrooks ifp->if_init = fxp_init; 778147072Sbrooks ifp->if_softc = sc; 779147072Sbrooks ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 780147072Sbrooks ifp->if_ioctl = fxp_ioctl; 781147072Sbrooks ifp->if_start = fxp_start; 782147072Sbrooks ifp->if_watchdog = fxp_watchdog; 783147072Sbrooks 784147072Sbrooks /* Enable checksum offload for 82550 or better chips */ 785147072Sbrooks if (sc->flags & FXP_FLAG_EXT_RFA) { 786147072Sbrooks ifp->if_hwassist = FXP_CSUM_FEATURES; 787147072Sbrooks ifp->if_capabilities = IFCAP_HWCSUM; 788147072Sbrooks ifp->if_capenable = ifp->if_capabilities; 789147072Sbrooks } 790147072Sbrooks 791147072Sbrooks /* 792147072Sbrooks * Attach the interface. 793147072Sbrooks */ 794147072Sbrooks ether_ifattach(ifp, sc->arpcom.ac_enaddr); 795147072Sbrooks 796147072Sbrooks /* 797147072Sbrooks * Tell the upper layer(s) we support long frames. 798147072Sbrooks */ 799147072Sbrooks ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header); 800147072Sbrooks ifp->if_capabilities |= IFCAP_VLAN_MTU; 801147072Sbrooks 802147072Sbrooks /* 803147072Sbrooks * Let the system queue as many packets as we have available 804147072Sbrooks * TX descriptors. 805147072Sbrooks */ 806147072Sbrooks ifp->if_snd.ifq_maxlen = FXP_NTXCB - 1; 807147106Sbrooks 808147072Sbrooks /* 809147072Sbrooks * Hook our interrupt after all initialization is complete. 810147072Sbrooks * XXX This driver has been tested with the INTR_MPSAFFE flag set 811147072Sbrooks * however, ifp and its functions are not fully locked so MPSAFE 812147072Sbrooks * should not be used unless you can handle potential data loss. 813147072Sbrooks */ 814147072Sbrooks error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET /*|INTR_MPSAFE*/, 815147072Sbrooks fxp_intr, sc, &sc->ih); 816147072Sbrooks if (error) { 817147072Sbrooks device_printf(dev, "could not setup irq\n"); 818147072Sbrooks ether_ifdetach(&sc->arpcom.ac_if); 819147072Sbrooks goto fail; 820147072Sbrooks } 821147072Sbrooks 822147072Sbrooksfail: 823147072Sbrooks splx(s); 824147072Sbrooks if (error) 825147072Sbrooks fxp_release(sc); 826147072Sbrooks return (error); 827147072Sbrooks} 828147072Sbrooks 829147072Sbrooks/* 830147072Sbrooks * Release all resources. The softc lock should not be held and the 831147072Sbrooks * interrupt should already be torn down. 832147072Sbrooks */ 833147072Sbrooksstatic void 834147072Sbrooksfxp_release(struct fxp_softc *sc) 835147072Sbrooks{ 836147072Sbrooks struct fxp_rx *rxp; 837147072Sbrooks struct fxp_tx *txp; 838147072Sbrooks int i; 839147072Sbrooks 840147072Sbrooks mtx_assert(&sc->sc_mtx, MA_NOTOWNED); 841147072Sbrooks if (sc->ih) 842147072Sbrooks panic("fxp_release() called with intr handle still active"); 843147072Sbrooks if (sc->miibus) 844147072Sbrooks device_delete_child(sc->dev, sc->miibus); 845147072Sbrooks bus_generic_detach(sc->dev); 846147072Sbrooks ifmedia_removeall(&sc->sc_media); 847147072Sbrooks if (sc->fxp_desc.cbl_list) { 848147072Sbrooks bus_dmamap_unload(sc->cbl_tag, sc->cbl_map); 849147072Sbrooks bus_dmamem_free(sc->cbl_tag, sc->fxp_desc.cbl_list, 850147072Sbrooks sc->cbl_map); 851147072Sbrooks } 852147072Sbrooks if (sc->fxp_stats) { 853147072Sbrooks bus_dmamap_unload(sc->fxp_stag, sc->fxp_smap); 854147072Sbrooks bus_dmamem_free(sc->fxp_stag, sc->fxp_stats, sc->fxp_smap); 855147072Sbrooks } 856147072Sbrooks if (sc->mcsp) { 857147072Sbrooks bus_dmamap_unload(sc->mcs_tag, sc->mcs_map); 858147072Sbrooks bus_dmamem_free(sc->mcs_tag, sc->mcsp, sc->mcs_map); 859147072Sbrooks } 860147072Sbrooks if (sc->irq) 861147072Sbrooks bus_release_resource(sc->dev, SYS_RES_IRQ, 0, sc->irq); 862147072Sbrooks if (sc->mem) 863147072Sbrooks bus_release_resource(sc->dev, sc->rtp, sc->rgd, sc->mem); 864147072Sbrooks if (sc->fxp_mtag) { 865147072Sbrooks for (i = 0; i < FXP_NRFABUFS; i++) { 866147072Sbrooks rxp = &sc->fxp_desc.rx_list[i]; 867147072Sbrooks if (rxp->rx_mbuf != NULL) { 868147072Sbrooks bus_dmamap_sync(sc->fxp_mtag, rxp->rx_map, 869147072Sbrooks BUS_DMASYNC_POSTREAD); 870147072Sbrooks bus_dmamap_unload(sc->fxp_mtag, rxp->rx_map); 871147072Sbrooks m_freem(rxp->rx_mbuf); 872147072Sbrooks } 873147072Sbrooks bus_dmamap_destroy(sc->fxp_mtag, rxp->rx_map); 874147072Sbrooks } 875147072Sbrooks bus_dmamap_destroy(sc->fxp_mtag, sc->spare_map); 876147072Sbrooks bus_dma_tag_destroy(sc->fxp_mtag); 877147072Sbrooks } 878147072Sbrooks if (sc->fxp_stag) { 879147072Sbrooks for (i = 0; i < FXP_NTXCB; i++) { 880147072Sbrooks txp = &sc->fxp_desc.tx_list[i]; 881147072Sbrooks if (txp->tx_mbuf != NULL) { 882147072Sbrooks bus_dmamap_sync(sc->fxp_mtag, txp->tx_map, 883147072Sbrooks BUS_DMASYNC_POSTWRITE); 884147072Sbrooks bus_dmamap_unload(sc->fxp_mtag, txp->tx_map); 885147072Sbrooks m_freem(txp->tx_mbuf); 886147072Sbrooks } 887147072Sbrooks bus_dmamap_destroy(sc->fxp_mtag, txp->tx_map); 888147072Sbrooks } 889147072Sbrooks bus_dma_tag_destroy(sc->fxp_stag); 890147072Sbrooks } 891147072Sbrooks if (sc->cbl_tag) 892147072Sbrooks bus_dma_tag_destroy(sc->cbl_tag); 893147072Sbrooks if (sc->mcs_tag) 894147072Sbrooks bus_dma_tag_destroy(sc->mcs_tag); 895147072Sbrooks 896147072Sbrooks sysctl_ctx_free(&sc->sysctl_ctx); 897147072Sbrooks 898147072Sbrooks mtx_destroy(&sc->sc_mtx); 899147072Sbrooks} 900147072Sbrooks 901147072Sbrooks/* 902147072Sbrooks * Detach interface. 903147072Sbrooks */ 904147072Sbrooksstatic int 905147072Sbrooksfxp_detach(device_t dev) 906147072Sbrooks{ 907147072Sbrooks struct fxp_softc *sc = device_get_softc(dev); 908147072Sbrooks int s; 909147072Sbrooks 910147072Sbrooks FXP_LOCK(sc); 911147072Sbrooks s = splimp(); 912147072Sbrooks 913147072Sbrooks sc->suspended = 1; /* Do same thing as we do for suspend */ 914147072Sbrooks /* 915147072Sbrooks * Close down routes etc. 916147072Sbrooks */ 917147072Sbrooks ether_ifdetach(&sc->arpcom.ac_if); 918147072Sbrooks 919147072Sbrooks /* 920147072Sbrooks * Stop DMA and drop transmit queue, but disable interrupts first. 921147072Sbrooks */ 922147072Sbrooks CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL, FXP_SCB_INTR_DISABLE); 923147072Sbrooks fxp_stop(sc); 924147072Sbrooks FXP_UNLOCK(sc); 925147072Sbrooks 926147072Sbrooks /* 927147072Sbrooks * Unhook interrupt before dropping lock. This is to prevent 928147072Sbrooks * races with fxp_intr(). 929147072Sbrooks */ 930147072Sbrooks bus_teardown_intr(sc->dev, sc->irq, sc->ih); 931147072Sbrooks sc->ih = NULL; 932147072Sbrooks 933147072Sbrooks splx(s); 934147072Sbrooks 935147072Sbrooks /* Release our allocated resources. */ 936147072Sbrooks fxp_release(sc); 937147072Sbrooks return (0); 938147072Sbrooks} 939147072Sbrooks 940147072Sbrooks/* 941147072Sbrooks * Device shutdown routine. Called at system shutdown after sync. The 942147072Sbrooks * main purpose of this routine is to shut off receiver DMA so that 943147072Sbrooks * kernel memory doesn't get clobbered during warmboot. 944147072Sbrooks */ 945147072Sbrooksstatic int 946147072Sbrooksfxp_shutdown(device_t dev) 947147072Sbrooks{ 948147072Sbrooks /* 949147072Sbrooks * Make sure that DMA is disabled prior to reboot. Not doing 950147072Sbrooks * do could allow DMA to corrupt kernel memory during the 951147072Sbrooks * reboot before the driver initializes. 952147072Sbrooks */ 953147072Sbrooks fxp_stop((struct fxp_softc *) device_get_softc(dev)); 954147072Sbrooks return (0); 955147072Sbrooks} 956147072Sbrooks 957147072Sbrooks/* 958147072Sbrooks * Device suspend routine. Stop the interface and save some PCI 959147072Sbrooks * settings in case the BIOS doesn't restore them properly on 960147072Sbrooks * resume. 961147072Sbrooks */ 962147072Sbrooksstatic int 963147072Sbrooksfxp_suspend(device_t dev) 964147072Sbrooks{ 965147072Sbrooks struct fxp_softc *sc = device_get_softc(dev); 966147072Sbrooks int i, s; 967147072Sbrooks 968147072Sbrooks FXP_LOCK(sc); 969147072Sbrooks s = splimp(); 970147072Sbrooks 971147072Sbrooks fxp_stop(sc); 972147072Sbrooks 973147072Sbrooks for (i = 0; i < 5; i++) 974147072Sbrooks sc->saved_maps[i] = pci_read_config(dev, PCIR_MAPS + i * 4, 4); 975147072Sbrooks sc->saved_biosaddr = pci_read_config(dev, PCIR_BIOS, 4); 976147072Sbrooks sc->saved_intline = pci_read_config(dev, PCIR_INTLINE, 1); 977147072Sbrooks sc->saved_cachelnsz = pci_read_config(dev, PCIR_CACHELNSZ, 1); 978147072Sbrooks sc->saved_lattimer = pci_read_config(dev, PCIR_LATTIMER, 1); 979147072Sbrooks 980147072Sbrooks sc->suspended = 1; 981147072Sbrooks 982147072Sbrooks FXP_UNLOCK(sc); 983147072Sbrooks splx(s); 984147072Sbrooks return (0); 985147072Sbrooks} 986147072Sbrooks 987147072Sbrooks/* 988147072Sbrooks * Device resume routine. Restore some PCI settings in case the BIOS 989147072Sbrooks * doesn't, re-enable busmastering, and restart the interface if 990147072Sbrooks * appropriate. 991147072Sbrooks */ 992147072Sbrooksstatic int 993147072Sbrooksfxp_resume(device_t dev) 994147072Sbrooks{ 995147072Sbrooks struct fxp_softc *sc = device_get_softc(dev); 996147072Sbrooks struct ifnet *ifp = &sc->sc_if; 997147072Sbrooks u_int16_t pci_command; 998147072Sbrooks int i, s; 999147072Sbrooks 1000147072Sbrooks FXP_LOCK(sc); 1001147072Sbrooks s = splimp(); 1002147072Sbrooks 1003147072Sbrooks fxp_powerstate_d0(dev); 1004147072Sbrooks 1005147072Sbrooks /* better way to do this? */ 1006147072Sbrooks for (i = 0; i < 5; i++) 1007147072Sbrooks pci_write_config(dev, PCIR_MAPS + i * 4, sc->saved_maps[i], 4); 1008147072Sbrooks pci_write_config(dev, PCIR_BIOS, sc->saved_biosaddr, 4); 1009147072Sbrooks pci_write_config(dev, PCIR_INTLINE, sc->saved_intline, 1); 1010147072Sbrooks pci_write_config(dev, PCIR_CACHELNSZ, sc->saved_cachelnsz, 1); 1011147072Sbrooks pci_write_config(dev, PCIR_LATTIMER, sc->saved_lattimer, 1); 1012147072Sbrooks 1013147072Sbrooks /* reenable busmastering */ 1014147072Sbrooks pci_command = pci_read_config(dev, PCIR_COMMAND, 2); 1015147072Sbrooks pci_command |= (PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN); 1016147072Sbrooks pci_write_config(dev, PCIR_COMMAND, pci_command, 2); 1017147072Sbrooks 1018147072Sbrooks CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SELECTIVE_RESET); 1019147072Sbrooks DELAY(10); 1020147072Sbrooks 1021147072Sbrooks /* reinitialize interface if necessary */ 1022147072Sbrooks if (ifp->if_flags & IFF_UP) 1023147072Sbrooks fxp_init_body(sc); 1024147072Sbrooks 1025147072Sbrooks sc->suspended = 0; 1026147072Sbrooks 1027147072Sbrooks FXP_UNLOCK(sc); 1028147072Sbrooks splx(s); 1029147072Sbrooks return (0); 1030147072Sbrooks} 1031147072Sbrooks 1032147072Sbrooksstatic void 1033147072Sbrooksfxp_eeprom_shiftin(struct fxp_softc *sc, int data, int length) 1034147072Sbrooks{ 1035147072Sbrooks u_int16_t reg; 1036147072Sbrooks int x; 1037147072Sbrooks 1038147072Sbrooks /* 1039147072Sbrooks * Shift in data. 1040147072Sbrooks */ 1041147072Sbrooks for (x = 1 << (length - 1); x; x >>= 1) { 1042147072Sbrooks if (data & x) 1043147072Sbrooks reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI; 1044147072Sbrooks else 1045147072Sbrooks reg = FXP_EEPROM_EECS; 1046147072Sbrooks CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg); 1047147072Sbrooks DELAY(1); 1048147072Sbrooks CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg | FXP_EEPROM_EESK); 1049147072Sbrooks DELAY(1); 1050147072Sbrooks CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg); 1051147072Sbrooks DELAY(1); 1052147072Sbrooks } 1053147072Sbrooks} 1054147072Sbrooks 1055147072Sbrooks/* 1056147072Sbrooks * Read from the serial EEPROM. Basically, you manually shift in 1057147072Sbrooks * the read opcode (one bit at a time) and then shift in the address, 1058147072Sbrooks * and then you shift out the data (all of this one bit at a time). 1059147072Sbrooks * The word size is 16 bits, so you have to provide the address for 1060147072Sbrooks * every 16 bits of data. 1061147072Sbrooks */ 1062147072Sbrooksstatic u_int16_t 1063147072Sbrooksfxp_eeprom_getword(struct fxp_softc *sc, int offset, int autosize) 1064147072Sbrooks{ 1065147072Sbrooks u_int16_t reg, data; 1066148465Sbrooks int x; 1067148465Sbrooks 1068148465Sbrooks CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS); 1069148465Sbrooks /* 1070148465Sbrooks * Shift in read opcode. 1071148465Sbrooks */ 1072147072Sbrooks fxp_eeprom_shiftin(sc, FXP_EEPROM_OPC_READ, 3); 1073147072Sbrooks /* 1074147072Sbrooks * Shift in address. 1075147072Sbrooks */ 1076147072Sbrooks data = 0; 1077147072Sbrooks for (x = 1 << (sc->eeprom_size - 1); x; x >>= 1) { 1078147072Sbrooks if (offset & x) 1079147072Sbrooks reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI; 1080147072Sbrooks else 1081147072Sbrooks reg = FXP_EEPROM_EECS; 1082147072Sbrooks CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg); 1083147072Sbrooks DELAY(1); 1084147072Sbrooks CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg | FXP_EEPROM_EESK); 1085147072Sbrooks DELAY(1); 1086147072Sbrooks CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg); 1087147072Sbrooks DELAY(1); 1088147072Sbrooks reg = CSR_READ_2(sc, FXP_CSR_EEPROMCONTROL) & FXP_EEPROM_EEDO; 1089147072Sbrooks data++; 1090147072Sbrooks if (autosize && reg == 0) { 1091147072Sbrooks sc->eeprom_size = data; 1092147072Sbrooks break; 1093147072Sbrooks } 1094147072Sbrooks } 1095147072Sbrooks /* 1096147072Sbrooks * Shift out data. 1097147072Sbrooks */ 1098147072Sbrooks data = 0; 1099147072Sbrooks reg = FXP_EEPROM_EECS; 1100147072Sbrooks for (x = 1 << 15; x; x >>= 1) { 1101147072Sbrooks CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg | FXP_EEPROM_EESK); 1102147072Sbrooks DELAY(1); 1103147072Sbrooks if (CSR_READ_2(sc, FXP_CSR_EEPROMCONTROL) & FXP_EEPROM_EEDO) 1104147072Sbrooks data |= x; 1105147072Sbrooks CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg); 1106147072Sbrooks DELAY(1); 1107147072Sbrooks } 1108147072Sbrooks CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0); 1109147072Sbrooks DELAY(1); 1110147072Sbrooks 1111147072Sbrooks return (data); 1112147072Sbrooks} 1113147072Sbrooks 1114147072Sbrooksstatic void 1115147072Sbrooksfxp_eeprom_putword(struct fxp_softc *sc, int offset, u_int16_t data) 1116147072Sbrooks{ 1117147072Sbrooks int i; 1118147072Sbrooks 1119147072Sbrooks /* 1120147072Sbrooks * Erase/write enable. 1121147072Sbrooks */ 1122147072Sbrooks CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS); 1123147072Sbrooks fxp_eeprom_shiftin(sc, 0x4, 3); 1124147072Sbrooks fxp_eeprom_shiftin(sc, 0x03 << (sc->eeprom_size - 2), sc->eeprom_size); 1125147072Sbrooks CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0); 1126147072Sbrooks DELAY(1); 1127147072Sbrooks /* 1128147072Sbrooks * Shift in write opcode, address, data. 1129147072Sbrooks */ 1130147072Sbrooks CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS); 1131147072Sbrooks fxp_eeprom_shiftin(sc, FXP_EEPROM_OPC_WRITE, 3); 1132147072Sbrooks fxp_eeprom_shiftin(sc, offset, sc->eeprom_size); 1133147072Sbrooks fxp_eeprom_shiftin(sc, data, 16); 1134147072Sbrooks CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0); 1135147072Sbrooks DELAY(1); 1136147072Sbrooks /* 1137147072Sbrooks * Wait for EEPROM to finish up. 1138147072Sbrooks */ 1139147072Sbrooks CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS); 1140147072Sbrooks DELAY(1); 1141147072Sbrooks for (i = 0; i < 1000; i++) { 1142147072Sbrooks if (CSR_READ_2(sc, FXP_CSR_EEPROMCONTROL) & FXP_EEPROM_EEDO) 1143147072Sbrooks break; 1144147072Sbrooks DELAY(50); 1145147072Sbrooks } 1146147072Sbrooks CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0); 1147147072Sbrooks DELAY(1); 1148147072Sbrooks /* 1149147072Sbrooks * Erase/write disable. 1150147072Sbrooks */ 1151147072Sbrooks CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS); 1152147072Sbrooks fxp_eeprom_shiftin(sc, 0x4, 3); 1153147072Sbrooks fxp_eeprom_shiftin(sc, 0, sc->eeprom_size); 1154147072Sbrooks CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0); 1155147072Sbrooks DELAY(1); 1156147072Sbrooks} 1157147072Sbrooks 1158147072Sbrooks/* 1159147072Sbrooks * From NetBSD: 1160147072Sbrooks * 1161147072Sbrooks * Figure out EEPROM size. 1162147072Sbrooks * 1163147072Sbrooks * 559's can have either 64-word or 256-word EEPROMs, the 558 1164147072Sbrooks * datasheet only talks about 64-word EEPROMs, and the 557 datasheet 1165147072Sbrooks * talks about the existance of 16 to 256 word EEPROMs. 1166147072Sbrooks * 1167147072Sbrooks * The only known sizes are 64 and 256, where the 256 version is used 1168147072Sbrooks * by CardBus cards to store CIS information. 1169147072Sbrooks * 1170147072Sbrooks * The address is shifted in msb-to-lsb, and after the last 1171147072Sbrooks * address-bit the EEPROM is supposed to output a `dummy zero' bit, 1172147072Sbrooks * after which follows the actual data. We try to detect this zero, by 1173147072Sbrooks * probing the data-out bit in the EEPROM control register just after 1174147072Sbrooks * having shifted in a bit. If the bit is zero, we assume we've 1175147072Sbrooks * shifted enough address bits. The data-out should be tri-state, 1176147072Sbrooks * before this, which should translate to a logical one. 1177147072Sbrooks */ 1178147072Sbrooksstatic void 1179147072Sbrooksfxp_autosize_eeprom(struct fxp_softc *sc) 1180147072Sbrooks{ 1181147072Sbrooks 1182147072Sbrooks /* guess maximum size of 256 words */ 1183147072Sbrooks sc->eeprom_size = 8; 1184147072Sbrooks 1185147072Sbrooks /* autosize */ 1186147072Sbrooks (void) fxp_eeprom_getword(sc, 0, 1); 1187147072Sbrooks} 1188147072Sbrooks 1189147072Sbrooksstatic void 1190147072Sbrooksfxp_read_eeprom(struct fxp_softc *sc, u_short *data, int offset, int words) 1191147072Sbrooks{ 1192147072Sbrooks int i; 1193147072Sbrooks 1194147072Sbrooks for (i = 0; i < words; i++) 1195147072Sbrooks data[i] = fxp_eeprom_getword(sc, offset + i, 0); 1196147072Sbrooks} 1197147072Sbrooks 1198147072Sbrooksstatic void 1199147072Sbrooksfxp_write_eeprom(struct fxp_softc *sc, u_short *data, int offset, int words) 1200147072Sbrooks{ 1201147072Sbrooks int i; 1202147072Sbrooks 1203147072Sbrooks for (i = 0; i < words; i++) 1204147072Sbrooks fxp_eeprom_putword(sc, offset + i, data[i]); 1205147072Sbrooks} 1206147072Sbrooks 1207147072Sbrooksstatic void 1208147072Sbrooksfxp_dma_map_txbuf(void *arg, bus_dma_segment_t *segs, int nseg, 1209147072Sbrooks bus_size_t mapsize, int error) 1210147072Sbrooks{ 1211147072Sbrooks struct fxp_softc *sc; 1212147072Sbrooks struct fxp_cb_tx *txp; 1213147072Sbrooks int i; 1214147072Sbrooks 1215147072Sbrooks if (error) 1216147072Sbrooks return; 1217147072Sbrooks 1218147072Sbrooks KASSERT(nseg <= FXP_NTXSEG, ("too many DMA segments")); 1219147072Sbrooks 1220147072Sbrooks sc = arg; 1221147072Sbrooks txp = sc->fxp_desc.tx_last->tx_next->tx_cb; 1222147072Sbrooks for (i = 0; i < nseg; i++) { 1223147072Sbrooks KASSERT(segs[i].ds_len <= MCLBYTES, ("segment size too large")); 1224147072Sbrooks /* 1225147072Sbrooks * If this is an 82550/82551, then we're using extended 1226147072Sbrooks * TxCBs _and_ we're using checksum offload. This means 1227147106Sbrooks * that the TxCB is really an IPCB. One major difference 1228147106Sbrooks * between the two is that with plain extended TxCBs, 1229147072Sbrooks * the bottom half of the TxCB contains two entries from 1230147072Sbrooks * the TBD array, whereas IPCBs contain just one entry: 1231147072Sbrooks * one entry (8 bytes) has been sacrificed for the TCP/IP 1232147072Sbrooks * checksum offload control bits. So to make things work 1233147072Sbrooks * right, we have to start filling in the TBD array 1234147072Sbrooks * starting from a different place depending on whether 1235147072Sbrooks * the chip is an 82550/82551 or not. 1236147072Sbrooks */ 1237147072Sbrooks if (sc->flags & FXP_FLAG_EXT_RFA) { 1238147072Sbrooks txp->tbd[i + 1].tb_addr = htole32(segs[i].ds_addr); 1239147072Sbrooks txp->tbd[i + 1].tb_size = htole32(segs[i].ds_len); 1240147072Sbrooks } else { 1241147072Sbrooks txp->tbd[i].tb_addr = htole32(segs[i].ds_addr); 1242147072Sbrooks txp->tbd[i].tb_size = htole32(segs[i].ds_len); 1243147072Sbrooks } 1244147072Sbrooks } 1245147072Sbrooks txp->tbd_number = nseg; 1246147072Sbrooks} 1247147072Sbrooks 1248147072Sbrooks/* 1249147072Sbrooks * Grab the softc lock and call the real fxp_start_body() routine 1250147072Sbrooks */ 1251147072Sbrooksstatic void 1252147072Sbrooksfxp_start(struct ifnet *ifp) 1253147072Sbrooks{ 1254147072Sbrooks struct fxp_softc *sc = ifp->if_softc; 1255147072Sbrooks 1256147072Sbrooks FXP_LOCK(sc); 1257147072Sbrooks fxp_start_body(ifp); 1258147072Sbrooks FXP_UNLOCK(sc); 1259147072Sbrooks} 1260147072Sbrooks 1261147072Sbrooks/* 1262147072Sbrooks * Start packet transmission on the interface. 1263147072Sbrooks * This routine must be called with the softc lock held, and is an 1264147072Sbrooks * internal entry point only. 1265147072Sbrooks */ 1266147072Sbrooksstatic void 1267147072Sbrooksfxp_start_body(struct ifnet *ifp) 1268147072Sbrooks{ 1269147072Sbrooks struct fxp_softc *sc = ifp->if_softc; 1270147072Sbrooks struct fxp_tx *txp; 1271147072Sbrooks struct mbuf *mb_head; 1272147072Sbrooks int error; 1273147072Sbrooks 1274147072Sbrooks mtx_assert(&sc->sc_mtx, MA_OWNED); 1275147072Sbrooks /* 1276147072Sbrooks * See if we need to suspend xmit until the multicast filter 1277147072Sbrooks * has been reprogrammed (which can only be done at the head 1278147072Sbrooks * of the command chain). 1279147106Sbrooks */ 1280147106Sbrooks if (sc->need_mcsetup) { 1281147072Sbrooks return; 1282147072Sbrooks } 1283147072Sbrooks 1284147072Sbrooks txp = NULL; 1285147072Sbrooks 1286147072Sbrooks /* 1287147072Sbrooks * We're finished if there is nothing more to add to the list or if 1288147072Sbrooks * we're all filled up with buffers to transmit. 1289147072Sbrooks * NOTE: One TxCB is reserved to guarantee that fxp_mc_setup() can add 1290147072Sbrooks * a NOP command when needed. 1291147072Sbrooks */ 1292147072Sbrooks while (ifp->if_snd.ifq_head != NULL && sc->tx_queued < FXP_NTXCB - 1) { 1293147072Sbrooks 1294147072Sbrooks /* 1295147072Sbrooks * Grab a packet to transmit. 1296147072Sbrooks */ 1297147072Sbrooks IF_DEQUEUE(&ifp->if_snd, mb_head); 1298147072Sbrooks 1299147072Sbrooks /* 1300147072Sbrooks * Get pointer to next available tx desc. 1301147072Sbrooks */ 1302147072Sbrooks txp = sc->fxp_desc.tx_last->tx_next; 1303147072Sbrooks 1304147072Sbrooks /* 1305147072Sbrooks * A note in Appendix B of the Intel 8255x 10/100 Mbps 1306147072Sbrooks * Ethernet Controller Family Open Source Software 1307147072Sbrooks * Developer Manual says: 1308147072Sbrooks * Using software parsing is only allowed with legal 1309147072Sbrooks * TCP/IP or UDP/IP packets. 1310147072Sbrooks * ... 1311147072Sbrooks * For all other datagrams, hardware parsing must 1312147072Sbrooks * be used. 1313147072Sbrooks * Software parsing appears to truncate ICMP and 1314147072Sbrooks * fragmented UDP packets that contain one to three 1315147072Sbrooks * bytes in the second (and final) mbuf of the packet. 1316147072Sbrooks */ 1317147072Sbrooks if (sc->flags & FXP_FLAG_EXT_RFA) 1318147072Sbrooks txp->tx_cb->ipcb_ip_activation_high = 1319147072Sbrooks FXP_IPCB_HARDWAREPARSING_ENABLE; 1320147072Sbrooks 1321147072Sbrooks /* 1322147072Sbrooks * Deal with TCP/IP checksum offload. Note that 1323147072Sbrooks * in order for TCP checksum offload to work, 1324147072Sbrooks * the pseudo header checksum must have already 1325147072Sbrooks * been computed and stored in the checksum field 1326147072Sbrooks * in the TCP header. The stack should have 1327147072Sbrooks * already done this for us. 1328147072Sbrooks */ 1329147072Sbrooks 1330147072Sbrooks if (mb_head->m_pkthdr.csum_flags) { 1331147072Sbrooks if (mb_head->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { 1332147072Sbrooks txp->tx_cb->ipcb_ip_schedule = 1333147072Sbrooks FXP_IPCB_TCPUDP_CHECKSUM_ENABLE; 1334147072Sbrooks if (mb_head->m_pkthdr.csum_flags & CSUM_TCP) 1335147072Sbrooks txp->tx_cb->ipcb_ip_schedule |= 1336147072Sbrooks FXP_IPCB_TCP_PACKET; 1337147072Sbrooks } 1338147072Sbrooks#ifdef FXP_IP_CSUM_WAR 1339147072Sbrooks /* 1340147072Sbrooks * XXX The 82550 chip appears to have trouble 1341147072Sbrooks * dealing with IP header checksums in very small 1342147072Sbrooks * datagrams, namely fragments from 1 to 3 bytes 1343147072Sbrooks * in size. For example, say you want to transmit 1344147072Sbrooks * a UDP packet of 1473 bytes. The packet will be 1345147072Sbrooks * fragmented over two IP datagrams, the latter 1346147072Sbrooks * containing only one byte of data. The 82550 will 1347147072Sbrooks * botch the header checksum on the 1-byte fragment. 1348147072Sbrooks * As long as the datagram contains 4 or more bytes 1349147072Sbrooks * of data, you're ok. 1350147072Sbrooks * 1351147072Sbrooks * The following code attempts to work around this 1352147072Sbrooks * problem: if the datagram is less than 38 bytes 1353147072Sbrooks * in size (14 bytes ether header, 20 bytes IP header, 1354147072Sbrooks * plus 4 bytes of data), we punt and compute the IP 1355147072Sbrooks * header checksum by hand. This workaround doesn't 1356147072Sbrooks * work very well, however, since it can be fooled 1357147072Sbrooks * by things like VLAN tags and IP options that make 1358147072Sbrooks * the header sizes/offsets vary. 1359147072Sbrooks */ 1360147072Sbrooks 1361147072Sbrooks if (mb_head->m_pkthdr.csum_flags & CSUM_IP) { 1362147072Sbrooks if (mb_head->m_pkthdr.len < 38) { 1363147072Sbrooks struct ip *ip; 1364147072Sbrooks mb_head->m_data += ETHER_HDR_LEN; 1365147072Sbrooks ip = mtod(mb_head, struct ip *); 1366147072Sbrooks ip->ip_sum = in_cksum(mb_head, 1367147072Sbrooks ip->ip_hl << 2); 1368147072Sbrooks mb_head->m_data -= ETHER_HDR_LEN; 1369147072Sbrooks } else { 1370147072Sbrooks txp->tx_cb->ipcb_ip_activation_high = 1371147072Sbrooks FXP_IPCB_HARDWAREPARSING_ENABLE; 1372147072Sbrooks txp->tx_cb->ipcb_ip_schedule |= 1373147072Sbrooks FXP_IPCB_IP_CHECKSUM_ENABLE; 1374147072Sbrooks } 1375147072Sbrooks } 1376147072Sbrooks#endif 1377147072Sbrooks } 1378147072Sbrooks 1379147072Sbrooks /* 1380147072Sbrooks * Go through each of the mbufs in the chain and initialize 1381147072Sbrooks * the transmit buffer descriptors with the physical address 1382147072Sbrooks * and size of the mbuf. 1383147072Sbrooks */ 1384147072Sbrooks error = bus_dmamap_load_mbuf(sc->fxp_mtag, txp->tx_map, 1385147072Sbrooks mb_head, fxp_dma_map_txbuf, sc, 0); 1386147072Sbrooks 1387147072Sbrooks if (error && error != EFBIG) { 1388147072Sbrooks device_printf(sc->dev, "can't map mbuf (error %d)\n", 1389147072Sbrooks error); 1390147072Sbrooks m_freem(mb_head); 1391147072Sbrooks break; 1392147072Sbrooks } 1393147072Sbrooks 1394147072Sbrooks if (error) { 1395147072Sbrooks struct mbuf *mn; 1396147072Sbrooks 1397147072Sbrooks /* 1398147072Sbrooks * We ran out of segments. We have to recopy this 1399147072Sbrooks * mbuf chain first. Bail out if we can't get the 1400147072Sbrooks * new buffers. 1401147072Sbrooks */ 1402147072Sbrooks mn = m_defrag(mb_head, M_DONTWAIT); 1403147072Sbrooks if (mn == NULL) { 1404147072Sbrooks m_freem(mb_head); 1405147072Sbrooks break; 1406147072Sbrooks } else { 1407147072Sbrooks mb_head = mn; 1408147072Sbrooks } 1409147072Sbrooks error = bus_dmamap_load_mbuf(sc->fxp_mtag, txp->tx_map, 1410147072Sbrooks mb_head, fxp_dma_map_txbuf, sc, 0); 1411147072Sbrooks if (error) { 1412147072Sbrooks device_printf(sc->dev, 1413147072Sbrooks "can't map mbuf (error %d)\n", error); 1414147072Sbrooks m_freem(mb_head); 1415147072Sbrooks break; 1416147072Sbrooks } 1417147072Sbrooks } 1418147072Sbrooks 1419147072Sbrooks bus_dmamap_sync(sc->fxp_mtag, txp->tx_map, 1420147072Sbrooks BUS_DMASYNC_PREWRITE); 1421147072Sbrooks 1422147072Sbrooks txp->tx_mbuf = mb_head; 1423147072Sbrooks txp->tx_cb->cb_status = 0; 1424147072Sbrooks txp->tx_cb->byte_count = 0; 1425147072Sbrooks if (sc->tx_queued != FXP_CXINT_THRESH - 1) { 1426147072Sbrooks txp->tx_cb->cb_command = 1427147072Sbrooks htole16(sc->tx_cmd | FXP_CB_COMMAND_SF | 1428147072Sbrooks FXP_CB_COMMAND_S); 1429147072Sbrooks } else { 1430147072Sbrooks txp->tx_cb->cb_command = 1431147072Sbrooks htole16(sc->tx_cmd | FXP_CB_COMMAND_SF | 1432147072Sbrooks FXP_CB_COMMAND_S | FXP_CB_COMMAND_I); 1433147072Sbrooks /* 1434147072Sbrooks * Set a 5 second timer just in case we don't hear 1435147072Sbrooks * from the card again. 1436147072Sbrooks */ 1437147072Sbrooks ifp->if_timer = 5; 1438147072Sbrooks } 1439147072Sbrooks txp->tx_cb->tx_threshold = tx_threshold; 1440147072Sbrooks 1441147072Sbrooks /* 1442147072Sbrooks * Advance the end of list forward. 1443147072Sbrooks */ 1444147072Sbrooks 1445147072Sbrooks#ifdef __alpha__ 1446147072Sbrooks /* 1447147072Sbrooks * On platforms which can't access memory in 16-bit 1448147072Sbrooks * granularities, we must prevent the card from DMA'ing 1449147072Sbrooks * up the status while we update the command field. 1450147072Sbrooks * This could cause us to overwrite the completion status. 1451147072Sbrooks * XXX This is probably bogus and we're _not_ looking 1452147072Sbrooks * for atomicity here. 1453147072Sbrooks */ 1454147072Sbrooks atomic_clear_16(&sc->fxp_desc.tx_last->tx_cb->cb_command, 1455147072Sbrooks htole16(FXP_CB_COMMAND_S)); 1456147072Sbrooks#else 1457147072Sbrooks sc->fxp_desc.tx_last->tx_cb->cb_command &= 1458147072Sbrooks htole16(~FXP_CB_COMMAND_S); 1459147072Sbrooks#endif /*__alpha__*/ 1460147072Sbrooks sc->fxp_desc.tx_last = txp; 1461147072Sbrooks 1462147072Sbrooks /* 1463147072Sbrooks * Advance the beginning of the list forward if there are 1464147072Sbrooks * no other packets queued (when nothing is queued, tx_first 1465147072Sbrooks * sits on the last TxCB that was sent out). 1466147072Sbrooks */ 1467147072Sbrooks if (sc->tx_queued == 0) 1468147072Sbrooks sc->fxp_desc.tx_first = txp; 1469147072Sbrooks 1470147072Sbrooks sc->tx_queued++; 1471147072Sbrooks 1472147072Sbrooks /* 1473147072Sbrooks * Pass packet to bpf if there is a listener. 1474147072Sbrooks */ 1475147072Sbrooks BPF_MTAP(ifp, mb_head); 1476147072Sbrooks } 1477147072Sbrooks bus_dmamap_sync(sc->cbl_tag, sc->cbl_map, BUS_DMASYNC_PREWRITE); 1478147072Sbrooks 1479147072Sbrooks /* 1480147072Sbrooks * We're finished. If we added to the list, issue a RESUME to get DMA 1481147072Sbrooks * going again if suspended. 1482147072Sbrooks */ 1483147072Sbrooks if (txp != NULL) { 1484147072Sbrooks fxp_scb_wait(sc); 1485147072Sbrooks fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_RESUME); 1486147072Sbrooks } 1487147072Sbrooks} 1488147072Sbrooks 1489147072Sbrooks#ifdef DEVICE_POLLING 1490147072Sbrooksstatic poll_handler_t fxp_poll; 1491147072Sbrooks 1492147072Sbrooksstatic void 1493147072Sbrooksfxp_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) 1494147072Sbrooks{ 1495147072Sbrooks struct fxp_softc *sc = ifp->if_softc; 1496147072Sbrooks u_int8_t statack; 1497147072Sbrooks 1498147072Sbrooks FXP_LOCK(sc); 1499147072Sbrooks if (cmd == POLL_DEREGISTER) { /* final call, enable interrupts */ 1500147072Sbrooks CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL, 0); 1501147072Sbrooks FXP_UNLOCK(sc); 1502147072Sbrooks return; 1503147072Sbrooks } 1504147072Sbrooks statack = FXP_SCB_STATACK_CXTNO | FXP_SCB_STATACK_CNA | 1505147072Sbrooks FXP_SCB_STATACK_FR; 1506147072Sbrooks if (cmd == POLL_AND_CHECK_STATUS) { 1507147072Sbrooks u_int8_t tmp; 1508147072Sbrooks 1509147072Sbrooks tmp = CSR_READ_1(sc, FXP_CSR_SCB_STATACK); 1510147072Sbrooks if (tmp == 0xff || tmp == 0) { 1511147072Sbrooks FXP_UNLOCK(sc); 1512147072Sbrooks return; /* nothing to do */ 1513147072Sbrooks } 1514147072Sbrooks tmp &= ~statack; 1515147072Sbrooks /* ack what we can */ 1516147072Sbrooks if (tmp != 0) 1517147072Sbrooks CSR_WRITE_1(sc, FXP_CSR_SCB_STATACK, tmp); 1518147072Sbrooks statack |= tmp; 1519147072Sbrooks } 1520147072Sbrooks fxp_intr_body(sc, ifp, statack, count); 1521147072Sbrooks FXP_UNLOCK(sc); 1522147072Sbrooks} 1523147072Sbrooks#endif /* DEVICE_POLLING */ 1524147072Sbrooks 1525147072Sbrooks/* 1526147072Sbrooks * Process interface interrupts. 1527147072Sbrooks */ 1528147072Sbrooksstatic void 1529147072Sbrooksfxp_intr(void *xsc) 1530147072Sbrooks{ 1531147072Sbrooks struct fxp_softc *sc = xsc; 1532147072Sbrooks struct ifnet *ifp = &sc->sc_if; 1533147072Sbrooks u_int8_t statack; 1534147072Sbrooks 1535147072Sbrooks FXP_LOCK(sc); 1536158353Sbrooks if (sc->suspended) { 1537158353Sbrooks FXP_UNLOCK(sc); 1538158353Sbrooks return; 1539158353Sbrooks } 1540158353Sbrooks 1541158353Sbrooks#ifdef DEVICE_POLLING 1542158353Sbrooks if (ifp->if_flags & IFF_POLLING) { 1543158353Sbrooks FXP_UNLOCK(sc); 1544158353Sbrooks return; 1545158353Sbrooks } 1546158353Sbrooks if (ether_poll_register(fxp_poll, ifp)) { 1547158353Sbrooks /* disable interrupts */ 1548158353Sbrooks CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL, FXP_SCB_INTR_DISABLE); 1549158353Sbrooks fxp_poll(ifp, 0, 1); 1550158353Sbrooks FXP_UNLOCK(sc); 1551158353Sbrooks return; 1552158353Sbrooks } 1553158353Sbrooks#endif 1554147072Sbrooks while ((statack = CSR_READ_1(sc, FXP_CSR_SCB_STATACK)) != 0) { 1555158353Sbrooks /* 1556158353Sbrooks * It should not be possible to have all bits set; the 1557158353Sbrooks * FXP_SCB_INTR_SWI bit always returns 0 on a read. If 1558158353Sbrooks * all bits are set, this may indicate that the card has 1559158353Sbrooks * been physically ejected, so ignore it. 1560158353Sbrooks */ 1561158353Sbrooks if (statack == 0xff) { 1562158353Sbrooks FXP_UNLOCK(sc); 1563158353Sbrooks return; 1564158353Sbrooks } 1565158353Sbrooks 1566158353Sbrooks /* 1567158353Sbrooks * First ACK all the interrupts in this pass. 1568158353Sbrooks */ 1569147072Sbrooks CSR_WRITE_1(sc, FXP_CSR_SCB_STATACK, statack); 1570147072Sbrooks fxp_intr_body(sc, ifp, statack, -1); 1571147072Sbrooks } 1572147072Sbrooks FXP_UNLOCK(sc); 1573147072Sbrooks} 1574147072Sbrooks 1575147072Sbrooksstatic void 1576147072Sbrooksfxp_txeof(struct fxp_softc *sc) 1577147072Sbrooks{ 1578147072Sbrooks struct fxp_tx *txp; 1579147072Sbrooks 1580147072Sbrooks bus_dmamap_sync(sc->cbl_tag, sc->cbl_map, BUS_DMASYNC_PREREAD); 1581147072Sbrooks for (txp = sc->fxp_desc.tx_first; sc->tx_queued && 1582147072Sbrooks (le16toh(txp->tx_cb->cb_status) & FXP_CB_STATUS_C) != 0; 1583147072Sbrooks txp = txp->tx_next) { 1584147072Sbrooks if (txp->tx_mbuf != NULL) { 1585147072Sbrooks bus_dmamap_sync(sc->fxp_mtag, txp->tx_map, 1586147072Sbrooks BUS_DMASYNC_POSTWRITE); 1587147072Sbrooks bus_dmamap_unload(sc->fxp_mtag, txp->tx_map); 1588147072Sbrooks m_freem(txp->tx_mbuf); 1589147072Sbrooks txp->tx_mbuf = NULL; 1590147072Sbrooks /* clear this to reset csum offload bits */ 1591147072Sbrooks txp->tx_cb->tbd[0].tb_addr = 0; 1592147072Sbrooks } 1593147072Sbrooks sc->tx_queued--; 1594147072Sbrooks } 1595147072Sbrooks sc->fxp_desc.tx_first = txp; 1596147072Sbrooks bus_dmamap_sync(sc->cbl_tag, sc->cbl_map, BUS_DMASYNC_PREWRITE); 1597147072Sbrooks} 1598147072Sbrooks 1599147072Sbrooksstatic void 1600147072Sbrooksfxp_intr_body(struct fxp_softc *sc, struct ifnet *ifp, u_int8_t statack, 1601147072Sbrooks int count) 1602147072Sbrooks{ 1603147072Sbrooks struct mbuf *m; 1604147072Sbrooks struct fxp_rx *rxp; 1605147072Sbrooks struct fxp_rfa *rfa; 1606147072Sbrooks int rnr = (statack & FXP_SCB_STATACK_RNR) ? 1 : 0; 1607147072Sbrooks 1608147072Sbrooks mtx_assert(&sc->sc_mtx, MA_OWNED); 1609147072Sbrooks if (rnr) 1610147072Sbrooks fxp_rnr++; 1611147072Sbrooks#ifdef DEVICE_POLLING 1612147072Sbrooks /* Pick up a deferred RNR condition if `count' ran out last time. */ 1613147072Sbrooks if (sc->flags & FXP_FLAG_DEFERRED_RNR) { 1614147072Sbrooks sc->flags &= ~FXP_FLAG_DEFERRED_RNR; 1615147072Sbrooks rnr = 1; 1616147072Sbrooks } 1617147072Sbrooks#endif 1618147072Sbrooks 1619147072Sbrooks /* 1620147072Sbrooks * Free any finished transmit mbuf chains. 1621147072Sbrooks * 1622147072Sbrooks * Handle the CNA event likt a CXTNO event. It used to 1623147072Sbrooks * be that this event (control unit not ready) was not 1624147072Sbrooks * encountered, but it is now with the SMPng modifications. 1625147072Sbrooks * The exact sequence of events that occur when the interface 1626147072Sbrooks * is brought up are different now, and if this event 1627147072Sbrooks * goes unhandled, the configuration/rxfilter setup sequence 1628147072Sbrooks * can stall for several seconds. The result is that no 1629147072Sbrooks * packets go out onto the wire for about 5 to 10 seconds 1630147072Sbrooks * after the interface is ifconfig'ed for the first time. 1631147072Sbrooks */ 1632147072Sbrooks if (statack & (FXP_SCB_STATACK_CXTNO | FXP_SCB_STATACK_CNA)) { 1633147072Sbrooks fxp_txeof(sc); 1634147072Sbrooks 1635147072Sbrooks ifp->if_timer = 0; 1636147072Sbrooks if (sc->tx_queued == 0) { 1637147072Sbrooks if (sc->need_mcsetup) 1638147072Sbrooks fxp_mc_setup(sc); 1639147072Sbrooks } 1640147072Sbrooks /* 1641147072Sbrooks * Try to start more packets transmitting. 1642147072Sbrooks */ 1643147072Sbrooks if (ifp->if_snd.ifq_head != NULL) 1644147072Sbrooks fxp_start_body(ifp); 1645147072Sbrooks } 1646147072Sbrooks 1647147072Sbrooks /* 1648147072Sbrooks * Just return if nothing happened on the receive side. 1649147072Sbrooks */ 1650147072Sbrooks if (!rnr && (statack & FXP_SCB_STATACK_FR) == 0) 1651147072Sbrooks return; 1652147072Sbrooks 1653147072Sbrooks /* 1654147072Sbrooks * Process receiver interrupts. If a no-resource (RNR) 1655147072Sbrooks * condition exists, get whatever packets we can and 1656147072Sbrooks * re-start the receiver. 1657147072Sbrooks * 1658147072Sbrooks * When using polling, we do not process the list to completion, 1659147072Sbrooks * so when we get an RNR interrupt we must defer the restart 1660158353Sbrooks * until we hit the last buffer with the C bit set. 1661158353Sbrooks * If we run out of cycles and rfa_headm has the C bit set, 1662158353Sbrooks * record the pending RNR in the FXP_FLAG_DEFERRED_RNR flag so 1663158353Sbrooks * that the info will be used in the subsequent polling cycle. 1664158353Sbrooks */ 1665158353Sbrooks for (;;) { 1666158353Sbrooks rxp = sc->fxp_desc.rx_head; 1667158353Sbrooks m = rxp->rx_mbuf; 1668158353Sbrooks rfa = (struct fxp_rfa *)(m->m_ext.ext_buf + 1669158353Sbrooks RFA_ALIGNMENT_FUDGE); 1670158353Sbrooks bus_dmamap_sync(sc->fxp_mtag, rxp->rx_map, 1671158353Sbrooks BUS_DMASYNC_POSTREAD); 1672158353Sbrooks 1673158353Sbrooks#ifdef DEVICE_POLLING /* loop at most count times if count >=0 */ 1674158353Sbrooks if (count >= 0 && count-- == 0) { 1675158353Sbrooks if (rnr) { 1676158353Sbrooks /* Defer RNR processing until the next time. */ 1677158353Sbrooks sc->flags |= FXP_FLAG_DEFERRED_RNR; 1678147072Sbrooks rnr = 0; 1679158353Sbrooks } 1680158353Sbrooks break; 1681158353Sbrooks } 1682158353Sbrooks#endif /* DEVICE_POLLING */ 1683158353Sbrooks 1684158353Sbrooks if ((le16toh(rfa->rfa_status) & FXP_RFA_STATUS_C) == 0) 1685158353Sbrooks break; 1686158353Sbrooks 1687158353Sbrooks /* 1688158353Sbrooks * Advance head forward. 1689158353Sbrooks */ 1690158353Sbrooks sc->fxp_desc.rx_head = rxp->rx_next; 1691158353Sbrooks 1692158353Sbrooks /* 1693147072Sbrooks * Add a new buffer to the receive chain. 1694147072Sbrooks * If this fails, the old buffer is recycled 1695147072Sbrooks * instead. 1696147072Sbrooks */ 1697147072Sbrooks if (fxp_add_rfabuf(sc, rxp) == 0) { 1698147072Sbrooks int total_len; 1699147072Sbrooks 1700147072Sbrooks /* 1701147072Sbrooks * Fetch packet length (the top 2 bits of 1702147072Sbrooks * actual_size are flags set by the controller 1703147072Sbrooks * upon completion), and drop the packet in case 1704147072Sbrooks * of bogus length or CRC errors. 1705147072Sbrooks */ 1706147072Sbrooks total_len = le16toh(rfa->actual_size) & 0x3fff; 1707147072Sbrooks if (total_len < sizeof(struct ether_header) || 1708147072Sbrooks total_len > MCLBYTES - RFA_ALIGNMENT_FUDGE - 1709147072Sbrooks sc->rfa_size || 1710147072Sbrooks le16toh(rfa->rfa_status) & FXP_RFA_STATUS_CRC) { 1711147072Sbrooks m_freem(m); 1712147072Sbrooks continue; 1713147072Sbrooks } 1714147072Sbrooks 1715147072Sbrooks /* Do IP checksum checking. */ 1716147072Sbrooks if (le16toh(rfa->rfa_status) & FXP_RFA_STATUS_PARSE) { 1717147072Sbrooks if (rfa->rfax_csum_sts & 1718147072Sbrooks FXP_RFDX_CS_IP_CSUM_BIT_VALID) 1719147072Sbrooks m->m_pkthdr.csum_flags |= 1720147072Sbrooks CSUM_IP_CHECKED; 1721147072Sbrooks if (rfa->rfax_csum_sts & 1722147072Sbrooks FXP_RFDX_CS_IP_CSUM_VALID) 1723147072Sbrooks m->m_pkthdr.csum_flags |= 1724147072Sbrooks CSUM_IP_VALID; 1725147072Sbrooks if ((rfa->rfax_csum_sts & 1726147072Sbrooks FXP_RFDX_CS_TCPUDP_CSUM_BIT_VALID) && 1727147072Sbrooks (rfa->rfax_csum_sts & 1728147072Sbrooks FXP_RFDX_CS_TCPUDP_CSUM_VALID)) { 1729147072Sbrooks m->m_pkthdr.csum_flags |= 1730147072Sbrooks CSUM_DATA_VALID|CSUM_PSEUDO_HDR; 1731147072Sbrooks m->m_pkthdr.csum_data = 0xffff; 1732147072Sbrooks } 1733147072Sbrooks } 1734147072Sbrooks 1735147072Sbrooks m->m_pkthdr.len = m->m_len = total_len; 1736147072Sbrooks m->m_pkthdr.rcvif = ifp; 1737147072Sbrooks 1738147072Sbrooks /* 1739147072Sbrooks * Drop locks before calling if_input() since it 1740147072Sbrooks * may re-enter fxp_start() in the netisr case. 1741147072Sbrooks * This would result in a lock reversal. Better 1742147072Sbrooks * performance might be obtained by chaining all 1743147072Sbrooks * packets received, dropping the lock, and then 1744147072Sbrooks * calling if_input() on each one. 1745147072Sbrooks */ 1746147072Sbrooks FXP_UNLOCK(sc); 1747147072Sbrooks (*ifp->if_input)(ifp, m); 1748147072Sbrooks FXP_LOCK(sc); 1749147072Sbrooks } 1750147072Sbrooks } 1751147072Sbrooks if (rnr) { 1752147072Sbrooks fxp_scb_wait(sc); 1753147072Sbrooks CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, 1754147072Sbrooks sc->fxp_desc.rx_head->rx_addr); 1755147072Sbrooks fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_START); 1756147072Sbrooks } 1757147072Sbrooks} 1758147072Sbrooks 1759147072Sbrooks/* 1760147072Sbrooks * Update packet in/out/collision statistics. The i82557 doesn't 1761147072Sbrooks * allow you to access these counters without doing a fairly 1762147072Sbrooks * expensive DMA to get _all_ of the statistics it maintains, so 1763147072Sbrooks * we do this operation here only once per second. The statistics 1764147072Sbrooks * counters in the kernel are updated from the previous dump-stats 1765147072Sbrooks * DMA and then a new dump-stats DMA is started. The on-chip 1766147072Sbrooks * counters are zeroed when the DMA completes. If we can't start 1767147072Sbrooks * the DMA immediately, we don't wait - we just prepare to read 1768147072Sbrooks * them again next time. 1769147072Sbrooks */ 1770147072Sbrooksstatic void 1771147072Sbrooksfxp_tick(void *xsc) 1772147072Sbrooks{ 1773147072Sbrooks struct fxp_softc *sc = xsc; 1774147072Sbrooks struct ifnet *ifp = &sc->sc_if; 1775147072Sbrooks struct fxp_stats *sp = sc->fxp_stats; 1776147072Sbrooks int s; 1777147072Sbrooks 1778147072Sbrooks FXP_LOCK(sc); 1779147072Sbrooks s = splimp(); 1780147072Sbrooks bus_dmamap_sync(sc->fxp_stag, sc->fxp_smap, BUS_DMASYNC_POSTREAD); 1781147072Sbrooks ifp->if_opackets += le32toh(sp->tx_good); 1782147072Sbrooks ifp->if_collisions += le32toh(sp->tx_total_collisions); 1783147072Sbrooks if (sp->rx_good) { 1784147072Sbrooks ifp->if_ipackets += le32toh(sp->rx_good); 1785147072Sbrooks sc->rx_idle_secs = 0; 1786147072Sbrooks } else { 1787147072Sbrooks /* 1788147072Sbrooks * Receiver's been idle for another second. 1789147072Sbrooks */ 1790147072Sbrooks sc->rx_idle_secs++; 1791147072Sbrooks } 1792147072Sbrooks ifp->if_ierrors += 1793147072Sbrooks le32toh(sp->rx_crc_errors) + 1794147072Sbrooks le32toh(sp->rx_alignment_errors) + 1795147072Sbrooks le32toh(sp->rx_rnr_errors) + 1796147072Sbrooks le32toh(sp->rx_overrun_errors); 1797147072Sbrooks /* 1798147072Sbrooks * If any transmit underruns occured, bump up the transmit 1799147072Sbrooks * threshold by another 512 bytes (64 * 8). 1800147072Sbrooks */ 1801147072Sbrooks if (sp->tx_underruns) { 1802147072Sbrooks ifp->if_oerrors += le32toh(sp->tx_underruns); 1803147072Sbrooks if (tx_threshold < 192) 1804147072Sbrooks tx_threshold += 64; 1805147072Sbrooks } 1806147072Sbrooks 1807147072Sbrooks /* 1808147072Sbrooks * Release any xmit buffers that have completed DMA. This isn't 1809147072Sbrooks * strictly necessary to do here, but it's advantagous for mbufs 1810147072Sbrooks * with external storage to be released in a timely manner rather 1811147072Sbrooks * than being defered for a potentially long time. This limits 1812147072Sbrooks * the delay to a maximum of one second. 1813147072Sbrooks */ 1814147072Sbrooks fxp_txeof(sc); 1815147072Sbrooks 1816147072Sbrooks /* 1817147072Sbrooks * If we haven't received any packets in FXP_MAC_RX_IDLE seconds, 1818147072Sbrooks * then assume the receiver has locked up and attempt to clear 1819147072Sbrooks * the condition by reprogramming the multicast filter. This is 1820147072Sbrooks * a work-around for a bug in the 82557 where the receiver locks 1821147072Sbrooks * up if it gets certain types of garbage in the syncronization 1822147072Sbrooks * bits prior to the packet header. This bug is supposed to only 1823147072Sbrooks * occur in 10Mbps mode, but has been seen to occur in 100Mbps 1824147072Sbrooks * mode as well (perhaps due to a 10/100 speed transition). 1825147072Sbrooks */ 1826147072Sbrooks if (sc->rx_idle_secs > FXP_MAX_RX_IDLE) { 1827147072Sbrooks sc->rx_idle_secs = 0; 1828147072Sbrooks fxp_mc_setup(sc); 1829147072Sbrooks } 1830147072Sbrooks /* 1831147072Sbrooks * If there is no pending command, start another stats 1832147072Sbrooks * dump. Otherwise punt for now. 1833147072Sbrooks */ 1834147072Sbrooks if (CSR_READ_1(sc, FXP_CSR_SCB_COMMAND) == 0) { 1835147072Sbrooks /* 1836147072Sbrooks * Start another stats dump. 1837147072Sbrooks */ 1838147072Sbrooks bus_dmamap_sync(sc->fxp_stag, sc->fxp_smap, 1839147072Sbrooks BUS_DMASYNC_PREREAD); 1840147072Sbrooks fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_DUMPRESET); 1841147072Sbrooks } else { 1842147072Sbrooks /* 1843147072Sbrooks * A previous command is still waiting to be accepted. 1844147072Sbrooks * Just zero our copy of the stats and wait for the 1845147072Sbrooks * next timer event to update them. 1846147072Sbrooks */ 1847147072Sbrooks sp->tx_good = 0; 1848147072Sbrooks sp->tx_underruns = 0; 1849147072Sbrooks sp->tx_total_collisions = 0; 1850147072Sbrooks 1851147072Sbrooks sp->rx_good = 0; 1852147072Sbrooks sp->rx_crc_errors = 0; 1853147072Sbrooks sp->rx_alignment_errors = 0; 1854147072Sbrooks sp->rx_rnr_errors = 0; 1855147072Sbrooks sp->rx_overrun_errors = 0; 1856147072Sbrooks } 1857147072Sbrooks if (sc->miibus != NULL) 1858147072Sbrooks mii_tick(device_get_softc(sc->miibus)); 1859147072Sbrooks 1860147072Sbrooks /* 1861147072Sbrooks * Schedule another timeout one second from now. 1862147072Sbrooks */ 1863147072Sbrooks sc->stat_ch = timeout(fxp_tick, sc, hz); 1864147072Sbrooks FXP_UNLOCK(sc); 1865147072Sbrooks splx(s); 1866147072Sbrooks} 1867147072Sbrooks 1868147072Sbrooks/* 1869147072Sbrooks * Stop the interface. Cancels the statistics updater and resets 1870147072Sbrooks * the interface. 1871147072Sbrooks */ 1872147072Sbrooksstatic void 1873147072Sbrooksfxp_stop(struct fxp_softc *sc) 1874147072Sbrooks{ 1875147072Sbrooks struct ifnet *ifp = &sc->sc_if; 1876147072Sbrooks struct fxp_tx *txp; 1877147072Sbrooks int i; 1878147072Sbrooks 1879147072Sbrooks ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 1880147072Sbrooks ifp->if_timer = 0; 1881147072Sbrooks 1882147072Sbrooks#ifdef DEVICE_POLLING 1883147072Sbrooks ether_poll_deregister(ifp); 1884147072Sbrooks#endif 1885147072Sbrooks /* 1886147072Sbrooks * Cancel stats updater. 1887147072Sbrooks */ 1888147072Sbrooks untimeout(fxp_tick, sc, sc->stat_ch); 1889147072Sbrooks 1890147072Sbrooks /* 1891147072Sbrooks * Issue software reset, which also unloads the microcode. 1892147072Sbrooks */ 1893147072Sbrooks sc->flags &= ~FXP_FLAG_UCODE; 1894147072Sbrooks CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SOFTWARE_RESET); 1895147072Sbrooks DELAY(50); 1896147072Sbrooks 1897147072Sbrooks /* 1898147072Sbrooks * Release any xmit buffers. 1899147072Sbrooks */ 1900147072Sbrooks txp = sc->fxp_desc.tx_list; 1901147072Sbrooks if (txp != NULL) { 1902147072Sbrooks for (i = 0; i < FXP_NTXCB; i++) { 1903147072Sbrooks if (txp[i].tx_mbuf != NULL) { 1904147072Sbrooks bus_dmamap_sync(sc->fxp_mtag, txp[i].tx_map, 1905147072Sbrooks BUS_DMASYNC_POSTWRITE); 1906147072Sbrooks bus_dmamap_unload(sc->fxp_mtag, txp[i].tx_map); 1907147072Sbrooks m_freem(txp[i].tx_mbuf); 1908147072Sbrooks txp[i].tx_mbuf = NULL; 1909147072Sbrooks /* clear this to reset csum offload bits */ 1910147072Sbrooks txp[i].tx_cb->tbd[0].tb_addr = 0; 1911147072Sbrooks } 1912147072Sbrooks } 1913147072Sbrooks } 1914147072Sbrooks bus_dmamap_sync(sc->cbl_tag, sc->cbl_map, BUS_DMASYNC_PREWRITE); 1915147072Sbrooks sc->tx_queued = 0; 1916147072Sbrooks} 1917147072Sbrooks 1918147072Sbrooks/* 1919147072Sbrooks * Watchdog/transmission transmit timeout handler. Called when a 1920147072Sbrooks * transmission is started on the interface, but no interrupt is 1921147072Sbrooks * received before the timeout. This usually indicates that the 1922147072Sbrooks * card has wedged for some reason. 1923147072Sbrooks */ 1924147072Sbrooksstatic void 1925147072Sbrooksfxp_watchdog(struct ifnet *ifp) 1926147072Sbrooks{ 1927147072Sbrooks struct fxp_softc *sc = ifp->if_softc; 1928147072Sbrooks 1929147072Sbrooks FXP_LOCK(sc); 1930147072Sbrooks device_printf(sc->dev, "device timeout\n"); 1931147072Sbrooks ifp->if_oerrors++; 1932147072Sbrooks 1933147072Sbrooks fxp_init_body(sc); 1934147072Sbrooks FXP_UNLOCK(sc); 1935147072Sbrooks} 1936147072Sbrooks 1937147072Sbrooks/* 1938147072Sbrooks * Acquire locks and then call the real initialization function. This 1939147072Sbrooks * is necessary because ether_ioctl() calls if_init() and this would 1940147072Sbrooks * result in mutex recursion if the mutex was held. 1941147072Sbrooks */ 1942147072Sbrooksstatic void 1943147072Sbrooksfxp_init(void *xsc) 1944147072Sbrooks{ 1945147072Sbrooks struct fxp_softc *sc = xsc; 1946147072Sbrooks 1947147072Sbrooks FXP_LOCK(sc); 1948147072Sbrooks fxp_init_body(sc); 1949147072Sbrooks FXP_UNLOCK(sc); 1950147072Sbrooks} 1951147072Sbrooks 1952147072Sbrooks/* 1953147072Sbrooks * Perform device initialization. This routine must be called with the 1954147072Sbrooks * softc lock held. 1955147072Sbrooks */ 1956147072Sbrooksstatic void 1957147072Sbrooksfxp_init_body(struct fxp_softc *sc) 1958147072Sbrooks{ 1959147072Sbrooks struct ifnet *ifp = &sc->sc_if; 1960147072Sbrooks struct fxp_cb_config *cbp; 1961147072Sbrooks struct fxp_cb_ias *cb_ias; 1962147072Sbrooks struct fxp_cb_tx *tcbp; 1963147072Sbrooks struct fxp_tx *txp; 1964147072Sbrooks struct fxp_cb_mcs *mcsp; 1965147072Sbrooks int i, prm, s; 1966147072Sbrooks 1967147072Sbrooks mtx_assert(&sc->sc_mtx, MA_OWNED); 1968147072Sbrooks s = splimp(); 1969147072Sbrooks /* 1970147072Sbrooks * Cancel any pending I/O 1971147072Sbrooks */ 1972147072Sbrooks fxp_stop(sc); 1973147072Sbrooks 1974149727Sbrooks prm = (ifp->if_flags & IFF_PROMISC) ? 1 : 0; 1975149727Sbrooks 1976147072Sbrooks /* 1977147072Sbrooks * Initialize base of CBL and RFA memory. Loading with zero 1978147072Sbrooks * sets it up for regular linear addressing. 1979147072Sbrooks */ 1980147072Sbrooks CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, 0); 1981149727Sbrooks fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_BASE); 1982149727Sbrooks 1983149727Sbrooks fxp_scb_wait(sc); 1984149727Sbrooks fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_BASE); 1985149727Sbrooks 1986149727Sbrooks /* 1987149727Sbrooks * Initialize base of dump-stats buffer. 1988149727Sbrooks */ 1989149727Sbrooks fxp_scb_wait(sc); 1990147072Sbrooks bus_dmamap_sync(sc->fxp_stag, sc->fxp_smap, BUS_DMASYNC_PREREAD); 1991147072Sbrooks CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, sc->stats_addr); 1992149727Sbrooks fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_DUMP_ADR); 1993149727Sbrooks 1994147072Sbrooks /* 1995147072Sbrooks * Attempt to load microcode if requested. 1996147072Sbrooks */ 1997147072Sbrooks if (ifp->if_flags & IFF_LINK0 && (sc->flags & FXP_FLAG_UCODE) == 0) 1998147072Sbrooks fxp_load_ucode(sc); 1999147072Sbrooks 2000147072Sbrooks /* 2001147072Sbrooks * Initialize the multicast address list. 2002147072Sbrooks */ 2003147072Sbrooks if (fxp_mc_addrs(sc)) { 2004147072Sbrooks mcsp = sc->mcsp; 2005147072Sbrooks mcsp->cb_status = 0; 2006147072Sbrooks mcsp->cb_command = 2007147072Sbrooks htole16(FXP_CB_COMMAND_MCAS | FXP_CB_COMMAND_EL); 2008147072Sbrooks mcsp->link_addr = 0xffffffff; 2009147072Sbrooks /* 2010147072Sbrooks * Start the multicast setup command. 2011147072Sbrooks */ 2012147072Sbrooks fxp_scb_wait(sc); 2013147072Sbrooks bus_dmamap_sync(sc->mcs_tag, sc->mcs_map, BUS_DMASYNC_PREWRITE); 2014149727Sbrooks CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, sc->mcs_addr); 2015147072Sbrooks fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START); 2016147072Sbrooks /* ...and wait for it to complete. */ 2017147072Sbrooks fxp_dma_wait(sc, &mcsp->cb_status, sc->mcs_tag, sc->mcs_map); 2018147072Sbrooks bus_dmamap_sync(sc->mcs_tag, sc->mcs_map, 2019147072Sbrooks BUS_DMASYNC_POSTWRITE); 2020147072Sbrooks } 2021147072Sbrooks 2022147072Sbrooks /* 2023147072Sbrooks * We temporarily use memory that contains the TxCB list to 2024147072Sbrooks * construct the config CB. The TxCB list memory is rebuilt 2025147072Sbrooks * later. 2026147072Sbrooks */ 2027147072Sbrooks cbp = (struct fxp_cb_config *)sc->fxp_desc.cbl_list; 2028147072Sbrooks 2029147072Sbrooks /* 2030147072Sbrooks * This bcopy is kind of disgusting, but there are a bunch of must be 2031147072Sbrooks * zero and must be one bits in this structure and this is the easiest 2032147072Sbrooks * way to initialize them all to proper values. 2033147072Sbrooks */ 2034147072Sbrooks bcopy(fxp_cb_config_template, cbp, sizeof(fxp_cb_config_template)); 2035193765Sbrian 2036147072Sbrooks cbp->cb_status = 0; 2037147072Sbrooks cbp->cb_command = htole16(FXP_CB_COMMAND_CONFIG | 2038147072Sbrooks FXP_CB_COMMAND_EL); 2039147072Sbrooks cbp->link_addr = 0xffffffff; /* (no) next command */ 2040147072Sbrooks cbp->byte_count = sc->flags & FXP_FLAG_EXT_RFA ? 32 : 22; 2041147072Sbrooks cbp->rx_fifo_limit = 8; /* rx fifo threshold (32 bytes) */ 2042147072Sbrooks cbp->tx_fifo_limit = 0; /* tx fifo threshold (0 bytes) */ 2043147072Sbrooks cbp->adaptive_ifs = 0; /* (no) adaptive interframe spacing */ 2044147072Sbrooks cbp->mwi_enable = sc->flags & FXP_FLAG_MWI_ENABLE ? 1 : 0; 2045147072Sbrooks cbp->type_enable = 0; /* actually reserved */ 2046147072Sbrooks cbp->read_align_en = sc->flags & FXP_FLAG_READ_ALIGN ? 1 : 0; 2047147072Sbrooks cbp->end_wr_on_cl = sc->flags & FXP_FLAG_WRITE_ALIGN ? 1 : 0; 2048147072Sbrooks cbp->rx_dma_bytecount = 0; /* (no) rx DMA max */ 2049147072Sbrooks cbp->tx_dma_bytecount = 0; /* (no) tx DMA max */ 2050147072Sbrooks cbp->dma_mbce = 0; /* (disable) dma max counters */ 2051147072Sbrooks cbp->late_scb = 0; /* (don't) defer SCB update */ 2052147072Sbrooks cbp->direct_dma_dis = 1; /* disable direct rcv dma mode */ 2053147072Sbrooks cbp->tno_int_or_tco_en =0; /* (disable) tx not okay interrupt */ 2054193765Sbrian cbp->ci_int = 1; /* interrupt on CU idle */ 2055193765Sbrian cbp->ext_txcb_dis = sc->flags & FXP_FLAG_EXT_TXCB ? 0 : 1; 2056193765Sbrian cbp->ext_stats_dis = 1; /* disable extended counters */ 2057193765Sbrian cbp->keep_overrun_rx = 0; /* don't pass overrun frames to host */ 2058193765Sbrian cbp->save_bf = sc->revision == FXP_REV_82557 ? 1 : prm; 2059193765Sbrian cbp->disc_short_rx = !prm; /* discard short packets */ 2060147072Sbrooks cbp->underrun_retry = 1; /* retry mode (once) on DMA underrun */ 2061147072Sbrooks cbp->two_frames = 0; /* do not limit FIFO to 2 frames */ 2062147072Sbrooks cbp->dyn_tbd = 0; /* (no) dynamic TBD mode */ 2063193765Sbrian cbp->ext_rfa = sc->flags & FXP_FLAG_EXT_RFA ? 1 : 0; 2064147072Sbrooks cbp->mediatype = sc->flags & FXP_FLAG_SERIAL_MEDIA ? 0 : 1; 2065147072Sbrooks cbp->csma_dis = 0; /* (don't) disable link */ 2066147072Sbrooks cbp->tcp_udp_cksum = 0; /* (don't) enable checksum */ 2067147072Sbrooks cbp->vlan_tco = 0; /* (don't) enable vlan wakeup */ 2068147072Sbrooks cbp->link_wake_en = 0; /* (don't) assert PME# on link change */ 2069193765Sbrian cbp->arp_wake_en = 0; /* (don't) assert PME# on arp */ 2070147072Sbrooks cbp->mc_wake_en = 0; /* (don't) enable PME# on mcmatch */ 2071147072Sbrooks cbp->nsai = 1; /* (don't) disable source addr insert */ 2072193765Sbrian cbp->preamble_length = 2; /* (7 byte) preamble */ 2073193765Sbrian cbp->loopback = 0; /* (don't) loopback */ 2074193765Sbrian cbp->linear_priority = 0; /* (normal CSMA/CD operation) */ 2075193765Sbrian cbp->linear_pri_mode = 0; /* (wait after xmit only) */ 2076193765Sbrian cbp->interfrm_spacing = 6; /* (96 bits of) interframe spacing */ 2077147072Sbrooks cbp->promiscuous = prm; /* promiscuous mode */ 2078147072Sbrooks cbp->bcast_disable = 0; /* (don't) disable broadcasts */ 2079147072Sbrooks cbp->wait_after_win = 0; /* (don't) enable modified backoff alg*/ 2080147072Sbrooks cbp->ignore_ul = 0; /* consider U/L bit in IA matching */ 2081193765Sbrian cbp->crc16_en = 0; /* (don't) enable crc-16 algorithm */ 2082147072Sbrooks cbp->crscdt = sc->flags & FXP_FLAG_SERIAL_MEDIA ? 1 : 0; 2083147072Sbrooks 2084147072Sbrooks cbp->stripping = !prm; /* truncate rx packet to byte count */ 2085147072Sbrooks cbp->padding = 1; /* (do) pad short tx packets */ 2086147072Sbrooks cbp->rcv_crc_xfer = 0; /* (don't) xfer CRC to host */ 2087147072Sbrooks cbp->long_rx_en = sc->flags & FXP_FLAG_LONG_PKT_EN ? 1 : 0; 2088147072Sbrooks cbp->ia_wake_en = 0; /* (don't) wake up on address match */ 2089147072Sbrooks cbp->magic_pkt_dis = 0; /* (don't) disable magic packet */ 2090147072Sbrooks /* must set wake_en in PMCSR also */ 2091147072Sbrooks cbp->force_fdx = 0; /* (don't) force full duplex */ 2092147072Sbrooks cbp->fdx_pin_en = 1; /* (enable) FDX# pin */ 2093147072Sbrooks cbp->multi_ia = 0; /* (don't) accept multiple IAs */ 2094147072Sbrooks cbp->mc_all = sc->flags & FXP_FLAG_ALL_MCAST ? 1 : 0; 2095147072Sbrooks cbp->gamla_rx = sc->flags & FXP_FLAG_EXT_RFA ? 1 : 0; 2096147072Sbrooks 2097147072Sbrooks if (fxp_noflow || sc->revision == FXP_REV_82557) { 2098147072Sbrooks /* 2099147072Sbrooks * The 82557 has no hardware flow control, the values 2100147072Sbrooks * below are the defaults for the chip. 2101147072Sbrooks */ 2102147072Sbrooks cbp->fc_delay_lsb = 0; 2103147072Sbrooks cbp->fc_delay_msb = 0x40; 2104147072Sbrooks cbp->pri_fc_thresh = 3; 2105147072Sbrooks cbp->tx_fc_dis = 0; 2106147072Sbrooks cbp->rx_fc_restop = 0; 2107147072Sbrooks cbp->rx_fc_restart = 0; 2108147072Sbrooks cbp->fc_filter = 0; 2109147072Sbrooks cbp->pri_fc_loc = 1; 2110147072Sbrooks } else { 2111147072Sbrooks cbp->fc_delay_lsb = 0x1f; 2112147072Sbrooks cbp->fc_delay_msb = 0x01; 2113147072Sbrooks cbp->pri_fc_thresh = 3; 2114147072Sbrooks cbp->tx_fc_dis = 0; /* enable transmit FC */ 2115147072Sbrooks cbp->rx_fc_restop = 1; /* enable FC restop frames */ 2116147072Sbrooks cbp->rx_fc_restart = 1; /* enable FC restart frames */ 2117147072Sbrooks cbp->fc_filter = !prm; /* drop FC frames to host */ 2118147072Sbrooks cbp->pri_fc_loc = 1; /* FC pri location (byte31) */ 2119147072Sbrooks } 2120147072Sbrooks 2121147072Sbrooks /* 2122147072Sbrooks * Start the config command/DMA. 2123147072Sbrooks */ 2124147072Sbrooks fxp_scb_wait(sc); 2125147072Sbrooks bus_dmamap_sync(sc->cbl_tag, sc->cbl_map, BUS_DMASYNC_PREWRITE); 2126147072Sbrooks CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, sc->fxp_desc.cbl_addr); 2127147072Sbrooks fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START); 2128147072Sbrooks /* ...and wait for it to complete. */ 2129147072Sbrooks fxp_dma_wait(sc, &cbp->cb_status, sc->cbl_tag, sc->cbl_map); 2130147072Sbrooks bus_dmamap_sync(sc->cbl_tag, sc->cbl_map, BUS_DMASYNC_POSTWRITE); 2131147072Sbrooks 2132147072Sbrooks /* 2133147072Sbrooks * Now initialize the station address. Temporarily use the TxCB 2134147072Sbrooks * memory area like we did above for the config CB. 2135147072Sbrooks */ 2136147072Sbrooks cb_ias = (struct fxp_cb_ias *)sc->fxp_desc.cbl_list; 2137147072Sbrooks cb_ias->cb_status = 0; 2138147072Sbrooks cb_ias->cb_command = htole16(FXP_CB_COMMAND_IAS | FXP_CB_COMMAND_EL); 2139147072Sbrooks cb_ias->link_addr = 0xffffffff; 2140147072Sbrooks bcopy(sc->arpcom.ac_enaddr, cb_ias->macaddr, 2141147072Sbrooks sizeof(sc->arpcom.ac_enaddr)); 2142147072Sbrooks 2143147072Sbrooks /* 2144147072Sbrooks * Start the IAS (Individual Address Setup) command/DMA. 2145147072Sbrooks */ 2146147072Sbrooks fxp_scb_wait(sc); 2147147072Sbrooks bus_dmamap_sync(sc->cbl_tag, sc->cbl_map, BUS_DMASYNC_PREWRITE); 2148147072Sbrooks fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START); 2149147072Sbrooks /* ...and wait for it to complete. */ 2150147072Sbrooks fxp_dma_wait(sc, &cb_ias->cb_status, sc->cbl_tag, sc->cbl_map); 2151147072Sbrooks bus_dmamap_sync(sc->cbl_tag, sc->cbl_map, BUS_DMASYNC_POSTWRITE); 2152147072Sbrooks 2153147072Sbrooks /* 2154147072Sbrooks * Initialize transmit control block (TxCB) list. 2155147072Sbrooks */ 2156147072Sbrooks txp = sc->fxp_desc.tx_list; 2157147072Sbrooks tcbp = sc->fxp_desc.cbl_list; 2158147072Sbrooks bzero(tcbp, FXP_TXCB_SZ); 2159147072Sbrooks for (i = 0; i < FXP_NTXCB; i++) { 2160147072Sbrooks txp[i].tx_cb = tcbp + i; 2161147072Sbrooks txp[i].tx_mbuf = NULL; 2162147072Sbrooks tcbp[i].cb_status = htole16(FXP_CB_STATUS_C | FXP_CB_STATUS_OK); 2163147072Sbrooks tcbp[i].cb_command = htole16(FXP_CB_COMMAND_NOP); 2164147072Sbrooks tcbp[i].link_addr = htole32(sc->fxp_desc.cbl_addr + 2165147072Sbrooks (((i + 1) & FXP_TXCB_MASK) * sizeof(struct fxp_cb_tx))); 2166147072Sbrooks if (sc->flags & FXP_FLAG_EXT_TXCB) 2167147072Sbrooks tcbp[i].tbd_array_addr = 2168147072Sbrooks htole32(FXP_TXCB_DMA_ADDR(sc, &tcbp[i].tbd[2])); 2169147072Sbrooks else 2170147072Sbrooks tcbp[i].tbd_array_addr = 2171147072Sbrooks htole32(FXP_TXCB_DMA_ADDR(sc, &tcbp[i].tbd[0])); 2172147072Sbrooks txp[i].tx_next = &txp[(i + 1) & FXP_TXCB_MASK]; 2173147072Sbrooks } 2174147072Sbrooks /* 2175147072Sbrooks * Set the suspend flag on the first TxCB and start the control 2176147072Sbrooks * unit. It will execute the NOP and then suspend. 2177147072Sbrooks */ 2178147072Sbrooks tcbp->cb_command = htole16(FXP_CB_COMMAND_NOP | FXP_CB_COMMAND_S); 2179147072Sbrooks bus_dmamap_sync(sc->cbl_tag, sc->cbl_map, BUS_DMASYNC_PREWRITE); 2180147072Sbrooks sc->fxp_desc.tx_first = sc->fxp_desc.tx_last = txp; 2181147072Sbrooks sc->tx_queued = 1; 2182147072Sbrooks 2183147072Sbrooks fxp_scb_wait(sc); 2184147072Sbrooks fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START); 2185147072Sbrooks 2186147072Sbrooks /* 2187147072Sbrooks * Initialize receiver buffer area - RFA. 2188209756Sbrian */ 2189209756Sbrian fxp_scb_wait(sc); 2190147072Sbrooks CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, sc->fxp_desc.rx_head->rx_addr); 2191147072Sbrooks fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_START); 2192147072Sbrooks 2193147072Sbrooks /* 2194147072Sbrooks * Set current media. 2195147072Sbrooks */ 2196147072Sbrooks if (sc->miibus != NULL) 2197147072Sbrooks mii_mediachg(device_get_softc(sc->miibus)); 2198147072Sbrooks 2199147072Sbrooks ifp->if_flags |= IFF_RUNNING; 2200147072Sbrooks ifp->if_flags &= ~IFF_OACTIVE; 2201147072Sbrooks 2202147072Sbrooks /* 2203147072Sbrooks * Enable interrupts. 2204147072Sbrooks */ 2205147072Sbrooks#ifdef DEVICE_POLLING 2206147072Sbrooks /* 2207147072Sbrooks * ... but only do that if we are not polling. And because (presumably) 2208147072Sbrooks * the default is interrupts on, we need to disable them explicitly! 2209147072Sbrooks */ 2210147072Sbrooks if ( ifp->if_flags & IFF_POLLING ) 2211147072Sbrooks CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL, FXP_SCB_INTR_DISABLE); 2212147072Sbrooks else 2213147072Sbrooks#endif /* DEVICE_POLLING */ 2214147072Sbrooks CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL, 0); 2215147072Sbrooks 2216147072Sbrooks /* 2217147072Sbrooks * Start stats updater. 2218147072Sbrooks */ 2219147072Sbrooks sc->stat_ch = timeout(fxp_tick, sc, hz); 2220147072Sbrooks splx(s); 2221147072Sbrooks} 2222147072Sbrooks 2223147072Sbrooksstatic int 2224147072Sbrooksfxp_serial_ifmedia_upd(struct ifnet *ifp) 2225147072Sbrooks{ 2226147072Sbrooks 2227147072Sbrooks return (0); 2228147072Sbrooks} 2229147072Sbrooks 2230147072Sbrooksstatic void 2231147072Sbrooksfxp_serial_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) 2232147072Sbrooks{ 2233147072Sbrooks 2234147072Sbrooks ifmr->ifm_active = IFM_ETHER|IFM_MANUAL; 2235147072Sbrooks} 2236147072Sbrooks 2237147072Sbrooks/* 2238147072Sbrooks * Change media according to request. 2239147072Sbrooks */ 2240147072Sbrooksstatic int 2241147072Sbrooksfxp_ifmedia_upd(struct ifnet *ifp) 2242147072Sbrooks{ 2243147072Sbrooks struct fxp_softc *sc = ifp->if_softc; 2244147072Sbrooks struct mii_data *mii; 2245147072Sbrooks 2246147072Sbrooks mii = device_get_softc(sc->miibus); 2247147072Sbrooks mii_mediachg(mii); 2248147072Sbrooks return (0); 2249147072Sbrooks} 2250147072Sbrooks 2251147072Sbrooks/* 2252147072Sbrooks * Notify the world which media we're using. 2253147072Sbrooks */ 2254147072Sbrooksstatic void 2255147072Sbrooksfxp_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) 2256147072Sbrooks{ 2257147072Sbrooks struct fxp_softc *sc = ifp->if_softc; 2258147072Sbrooks struct mii_data *mii; 2259147072Sbrooks 2260147072Sbrooks mii = device_get_softc(sc->miibus); 2261147072Sbrooks mii_pollstat(mii); 2262147072Sbrooks ifmr->ifm_active = mii->mii_media_active; 2263147072Sbrooks ifmr->ifm_status = mii->mii_media_status; 2264147072Sbrooks 2265147072Sbrooks if (ifmr->ifm_status & IFM_10_T && sc->flags & FXP_FLAG_CU_RESUME_BUG) 2266147072Sbrooks sc->cu_resume_bug = 1; 2267147072Sbrooks else 2268147072Sbrooks sc->cu_resume_bug = 0; 2269147072Sbrooks} 2270147072Sbrooks 2271147072Sbrooks/* 2272147072Sbrooks * Add a buffer to the end of the RFA buffer list. 2273147072Sbrooks * Return 0 if successful, 1 for failure. A failure results in 2274147072Sbrooks * adding the 'oldm' (if non-NULL) on to the end of the list - 2275147072Sbrooks * tossing out its old contents and recycling it. 2276147072Sbrooks * The RFA struct is stuck at the beginning of mbuf cluster and the 2277147072Sbrooks * data pointer is fixed up to point just past it. 2278147072Sbrooks */ 2279147072Sbrooksstatic int 2280147072Sbrooksfxp_add_rfabuf(struct fxp_softc *sc, struct fxp_rx *rxp) 2281147072Sbrooks{ 2282147072Sbrooks struct mbuf *m; 2283147072Sbrooks struct fxp_rfa *rfa, *p_rfa; 2284147072Sbrooks struct fxp_rx *p_rx; 2285147072Sbrooks bus_dmamap_t tmp_map; 2286147072Sbrooks int error; 2287147072Sbrooks 2288147072Sbrooks m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); 2289147072Sbrooks if (m == NULL) 2290147072Sbrooks return (ENOBUFS); 2291147072Sbrooks 2292147072Sbrooks /* 2293147072Sbrooks * Move the data pointer up so that the incoming data packet 2294147072Sbrooks * will be 32-bit aligned. 2295147072Sbrooks */ 2296147072Sbrooks m->m_data += RFA_ALIGNMENT_FUDGE; 2297147072Sbrooks 2298147072Sbrooks /* 2299147072Sbrooks * Get a pointer to the base of the mbuf cluster and move 2300147072Sbrooks * data start past it. 2301147072Sbrooks */ 2302147072Sbrooks rfa = mtod(m, struct fxp_rfa *); 2303147072Sbrooks m->m_data += sc->rfa_size; 2304147072Sbrooks rfa->size = htole16(MCLBYTES - sc->rfa_size - RFA_ALIGNMENT_FUDGE); 2305147072Sbrooks 2306147072Sbrooks /* 2307147072Sbrooks * Initialize the rest of the RFA. Note that since the RFA 2308147072Sbrooks * is misaligned, we cannot store values directly. Instead, 2309147072Sbrooks * we use an optimized, inline copy. 2310147072Sbrooks */ 2311147072Sbrooks 2312147072Sbrooks rfa->rfa_status = 0; 2313147072Sbrooks rfa->rfa_control = htole16(FXP_RFA_CONTROL_EL); 2314147072Sbrooks rfa->actual_size = 0; 2315147072Sbrooks 2316147072Sbrooks le32enc(&rfa->link_addr, 0xffffffff); 2317147072Sbrooks le32enc(&rfa->rbd_addr, 0xffffffff); 2318147072Sbrooks 2319147072Sbrooks /* Map the RFA into DMA memory. */ 2320147072Sbrooks error = bus_dmamap_load(sc->fxp_mtag, sc->spare_map, rfa, 2321147072Sbrooks MCLBYTES - RFA_ALIGNMENT_FUDGE, fxp_dma_map_addr, 2322147072Sbrooks &rxp->rx_addr, 0); 2323147072Sbrooks if (error) { 2324147072Sbrooks m_freem(m); 2325147072Sbrooks return (error); 2326147072Sbrooks } 2327147072Sbrooks 2328147072Sbrooks bus_dmamap_unload(sc->fxp_mtag, rxp->rx_map); 2329147072Sbrooks tmp_map = sc->spare_map; 2330147072Sbrooks sc->spare_map = rxp->rx_map; 2331147072Sbrooks rxp->rx_map = tmp_map; 2332147072Sbrooks rxp->rx_mbuf = m; 2333147072Sbrooks 2334147072Sbrooks bus_dmamap_sync(sc->fxp_mtag, rxp->rx_map, 2335147072Sbrooks BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 2336147072Sbrooks 2337147072Sbrooks /* 2338147072Sbrooks * If there are other buffers already on the list, attach this 2339147072Sbrooks * one to the end by fixing up the tail to point to this one. 2340147072Sbrooks */ 2341147072Sbrooks if (sc->fxp_desc.rx_head != NULL) { 2342231277Sbapt p_rx = sc->fxp_desc.rx_tail; 2343231277Sbapt p_rfa = (struct fxp_rfa *) 2344231277Sbapt (p_rx->rx_mbuf->m_ext.ext_buf + RFA_ALIGNMENT_FUDGE); 2345147072Sbrooks p_rx->rx_next = rxp; 2346147072Sbrooks le32enc(&p_rfa->link_addr, rxp->rx_addr); 2347147072Sbrooks p_rfa->rfa_control = 0; 2348147072Sbrooks bus_dmamap_sync(sc->fxp_mtag, p_rx->rx_map, 2349147072Sbrooks BUS_DMASYNC_PREWRITE); 2350147072Sbrooks } else { 2351147072Sbrooks rxp->rx_next = NULL; 2352147072Sbrooks sc->fxp_desc.rx_head = rxp; 2353147072Sbrooks } 2354147072Sbrooks sc->fxp_desc.rx_tail = rxp; 2355147072Sbrooks return (0); 2356147072Sbrooks} 2357147072Sbrooks 2358147072Sbrooksstatic volatile int 2359147072Sbrooksfxp_miibus_readreg(device_t dev, int phy, int reg) 2360147072Sbrooks{ 2361147072Sbrooks struct fxp_softc *sc = device_get_softc(dev); 2362147072Sbrooks int count = 10000; 2363147072Sbrooks int value; 2364147072Sbrooks 2365147072Sbrooks CSR_WRITE_4(sc, FXP_CSR_MDICONTROL, 2366147072Sbrooks (FXP_MDI_READ << 26) | (reg << 16) | (phy << 21)); 2367147072Sbrooks 2368147072Sbrooks while (((value = CSR_READ_4(sc, FXP_CSR_MDICONTROL)) & 0x10000000) == 0 2369147072Sbrooks && count--) 2370147072Sbrooks DELAY(10); 2371147072Sbrooks 2372147072Sbrooks if (count <= 0) 2373147072Sbrooks device_printf(dev, "fxp_miibus_readreg: timed out\n"); 2374147072Sbrooks 2375147072Sbrooks return (value & 0xffff); 2376147072Sbrooks} 2377147072Sbrooks 2378147072Sbrooksstatic void 2379147072Sbrooksfxp_miibus_writereg(device_t dev, int phy, int reg, int value) 2380147072Sbrooks{ 2381147072Sbrooks struct fxp_softc *sc = device_get_softc(dev); 2382147072Sbrooks int count = 10000; 2383147072Sbrooks 2384147072Sbrooks CSR_WRITE_4(sc, FXP_CSR_MDICONTROL, 2385147072Sbrooks (FXP_MDI_WRITE << 26) | (reg << 16) | (phy << 21) | 2386147072Sbrooks (value & 0xffff)); 2387147072Sbrooks 2388183974Sbrooks while ((CSR_READ_4(sc, FXP_CSR_MDICONTROL) & 0x10000000) == 0 && 2389183974Sbrooks count--) 2390147689Sbrooks DELAY(10); 2391147689Sbrooks 2392147689Sbrooks if (count <= 0) 2393147689Sbrooks device_printf(dev, "fxp_miibus_writereg: timed out\n"); 2394147689Sbrooks} 2395147689Sbrooks 2396183974Sbrooksstatic int 2397183974Sbrooksfxp_ioctl(struct ifnet *ifp, u_long command, caddr_t data) 2398147072Sbrooks{ 2399147072Sbrooks struct fxp_softc *sc = ifp->if_softc; 2400147072Sbrooks struct ifreq *ifr = (struct ifreq *)data; 2401147072Sbrooks struct mii_data *mii; 2402147072Sbrooks int s, error = 0; 2403147072Sbrooks 2404147072Sbrooks /* 2405183974Sbrooks * Detaching causes us to call ioctl with the mutex owned. Preclude 2406183974Sbrooks * that by saying we're busy if the lock is already held. 2407147072Sbrooks */ 2408147072Sbrooks if (mtx_owned(&sc->sc_mtx)) 2409147072Sbrooks return (EBUSY); 2410153287Sbrooks 2411153287Sbrooks FXP_LOCK(sc); 2412147072Sbrooks s = splimp(); 2413147072Sbrooks 2414147686Sbrooks switch (command) { 2415230597Sdumbbell case SIOCSIFFLAGS: 2416149639Sbrooks if (ifp->if_flags & IFF_ALLMULTI) 2417149639Sbrooks sc->flags |= FXP_FLAG_ALL_MCAST; 2418149639Sbrooks else 2419149639Sbrooks sc->flags &= ~FXP_FLAG_ALL_MCAST; 2420153287Sbrooks 2421153287Sbrooks /* 2422149639Sbrooks * If interface is marked up and not running, then start it. 2423149639Sbrooks * If it is marked down and running, stop it. 2424149639Sbrooks * XXX If it's up then re-initialize it. This is so flags 2425147072Sbrooks * such as IFF_PROMISC are handled. 2426147072Sbrooks */ 2427147072Sbrooks if (ifp->if_flags & IFF_UP) { 2428147072Sbrooks fxp_init_body(sc); 2429147072Sbrooks } else { 2430147072Sbrooks if (ifp->if_flags & IFF_RUNNING) 2431147072Sbrooks fxp_stop(sc); 2432147072Sbrooks } 2433147072Sbrooks break; 2434147072Sbrooks 2435147072Sbrooks case SIOCADDMULTI: 2436147072Sbrooks case SIOCDELMULTI: 2437147072Sbrooks if (ifp->if_flags & IFF_ALLMULTI) 2438147072Sbrooks sc->flags |= FXP_FLAG_ALL_MCAST; 2439147072Sbrooks else 2440147072Sbrooks sc->flags &= ~FXP_FLAG_ALL_MCAST; 2441147072Sbrooks /* 2442147072Sbrooks * Multicast list has changed; set the hardware filter 2443147072Sbrooks * accordingly. 2444147072Sbrooks */ 2445147072Sbrooks if ((sc->flags & FXP_FLAG_ALL_MCAST) == 0) 2446147072Sbrooks fxp_mc_setup(sc); 2447147072Sbrooks /* 2448147072Sbrooks * fxp_mc_setup() can set FXP_FLAG_ALL_MCAST, so check it 2449147072Sbrooks * again rather than else {}. 2450147072Sbrooks */ 2451147072Sbrooks if (sc->flags & FXP_FLAG_ALL_MCAST) 2452147072Sbrooks fxp_init_body(sc); 2453147072Sbrooks error = 0; 2454147072Sbrooks break; 2455147072Sbrooks 2456147072Sbrooks case SIOCSIFMEDIA: 2457147072Sbrooks case SIOCGIFMEDIA: 2458147072Sbrooks if (sc->miibus != NULL) { 2459147072Sbrooks mii = device_get_softc(sc->miibus); 2460147072Sbrooks error = ifmedia_ioctl(ifp, ifr, 2461147072Sbrooks &mii->mii_media, command); 2462147072Sbrooks } else { 2463147072Sbrooks error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, command); 2464147072Sbrooks } 2465147072Sbrooks break; 2466183974Sbrooks 2467147072Sbrooks default: 2468147072Sbrooks /* 2469147072Sbrooks * ether_ioctl() will eventually call fxp_start() which 2470166602Semaste * will result in mutex recursion so drop it first. 2471166602Semaste */ 2472166602Semaste FXP_UNLOCK(sc); 2473147072Sbrooks error = ether_ioctl(ifp, command, data); 2474147072Sbrooks } 2475147072Sbrooks if (mtx_owned(&sc->sc_mtx)) 2476147072Sbrooks FXP_UNLOCK(sc); 2477147072Sbrooks splx(s); 2478147072Sbrooks return (error); 2479166602Semaste} 2480147072Sbrooks 2481166602Semaste/* 2482166602Semaste * Fill in the multicast address list and return number of entries. 2483166602Semaste */ 2484166602Semastestatic int 2485166602Semastefxp_mc_addrs(struct fxp_softc *sc) 2486166602Semaste{ 2487166602Semaste struct fxp_cb_mcs *mcsp = sc->mcsp; 2488166602Semaste struct ifnet *ifp = &sc->sc_if; 2489166602Semaste struct ifmultiaddr *ifma; 2490166602Semaste int nmcasts; 2491166602Semaste 2492166602Semaste nmcasts = 0; 2493166602Semaste if ((sc->flags & FXP_FLAG_ALL_MCAST) == 0) { 2494166602Semaste#if __FreeBSD_version < 500000 2495166602Semaste LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 2496166602Semaste#else 2497166602Semaste TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 2498166602Semaste#endif 2499166602Semaste if (ifma->ifma_addr->sa_family != AF_LINK) 2500166602Semaste continue; 2501166602Semaste if (nmcasts >= MAXMCADDR) { 2502166602Semaste sc->flags |= FXP_FLAG_ALL_MCAST; 2503166602Semaste nmcasts = 0; 2504166602Semaste break; 2505166602Semaste } 2506166602Semaste bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr), 2507166602Semaste &sc->mcsp->mc_addr[nmcasts][0], ETHER_ADDR_LEN); 2508166602Semaste nmcasts++; 2509166602Semaste } 2510166602Semaste } 2511166602Semaste mcsp->mc_cnt = htole16(nmcasts * ETHER_ADDR_LEN); 2512166602Semaste return (nmcasts); 2513166602Semaste} 2514166602Semaste 2515166602Semaste/* 2516166602Semaste * Program the multicast filter. 2517166602Semaste * 2518166602Semaste * We have an artificial restriction that the multicast setup command 2519166602Semaste * must be the first command in the chain, so we take steps to ensure 2520166602Semaste * this. By requiring this, it allows us to keep up the performance of 2521166602Semaste * the pre-initialized command ring (esp. link pointers) by not actually 2522166602Semaste * inserting the mcsetup command in the ring - i.e. its link pointer 2523166602Semaste * points to the TxCB ring, but the mcsetup descriptor itself is not part 2524166602Semaste * of it. We then can do 'CU_START' on the mcsetup descriptor and have it 2525166602Semaste * lead into the regular TxCB ring when it completes. 2526166602Semaste * 2527166602Semaste * This function must be called at splimp. 2528166602Semaste */ 2529166602Semastestatic void 2530166602Semastefxp_mc_setup(struct fxp_softc *sc) 2531166602Semaste{ 2532166602Semaste struct fxp_cb_mcs *mcsp = sc->mcsp; 2533166602Semaste struct ifnet *ifp = &sc->sc_if; 2534166602Semaste struct fxp_tx *txp; 2535166602Semaste int count; 2536166602Semaste 2537166602Semaste /* 2538166602Semaste * If there are queued commands, we must wait until they are all 2539166602Semaste * completed. If we are already waiting, then add a NOP command 2540166602Semaste * with interrupt option so that we're notified when all commands 2541166602Semaste * have been completed - fxp_start() ensures that no additional 2542166602Semaste * TX commands will be added when need_mcsetup is true. 2543166602Semaste */ 2544147072Sbrooks if (sc->tx_queued) { 2545147072Sbrooks /* 2546147072Sbrooks * need_mcsetup will be true if we are already waiting for the 2547147072Sbrooks * NOP command to be completed (see below). In this case, bail. 2548147072Sbrooks */ 2549147072Sbrooks if (sc->need_mcsetup) 2550147072Sbrooks return; 2551147072Sbrooks sc->need_mcsetup = 1; 2552147072Sbrooks 2553147072Sbrooks /* 2554147072Sbrooks * Add a NOP command with interrupt so that we are notified 2555147072Sbrooks * when all TX commands have been processed. 2556147072Sbrooks */ 2557147072Sbrooks txp = sc->fxp_desc.tx_last->tx_next; 2558147072Sbrooks txp->tx_mbuf = NULL; 2559147072Sbrooks txp->tx_cb->cb_status = 0; 2560147072Sbrooks txp->tx_cb->cb_command = htole16(FXP_CB_COMMAND_NOP | 2561147072Sbrooks FXP_CB_COMMAND_S | FXP_CB_COMMAND_I); 2562147072Sbrooks /* 2563147072Sbrooks * Advance the end of list forward. 2564147072Sbrooks */ 2565147072Sbrooks sc->fxp_desc.tx_last->tx_cb->cb_command &= 2566147072Sbrooks htole16(~FXP_CB_COMMAND_S); 2567147072Sbrooks bus_dmamap_sync(sc->cbl_tag, sc->cbl_map, BUS_DMASYNC_PREWRITE); 2568149639Sbrooks sc->fxp_desc.tx_last = txp; 2569149639Sbrooks sc->tx_queued++; 2570149639Sbrooks /* 2571149639Sbrooks * Issue a resume in case the CU has just suspended. 2572149639Sbrooks */ 2573149639Sbrooks fxp_scb_wait(sc); 2574149639Sbrooks fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_RESUME); 2575149639Sbrooks /* 2576149639Sbrooks * Set a 5 second timer just in case we don't hear from the 2577149639Sbrooks * card again. 2578149639Sbrooks */ 2579149639Sbrooks ifp->if_timer = 5; 2580149639Sbrooks 2581149639Sbrooks return; 2582149639Sbrooks } 2583149639Sbrooks sc->need_mcsetup = 0; 2584149639Sbrooks 2585149639Sbrooks /* 2586149639Sbrooks * Initialize multicast setup descriptor. 2587149639Sbrooks */ 2588149639Sbrooks mcsp->cb_status = 0; 2589149639Sbrooks mcsp->cb_command = htole16(FXP_CB_COMMAND_MCAS | 2590149639Sbrooks FXP_CB_COMMAND_S | FXP_CB_COMMAND_I); 2591149639Sbrooks mcsp->link_addr = htole32(sc->fxp_desc.cbl_addr); 2592149639Sbrooks txp = &sc->fxp_desc.mcs_tx; 2593149639Sbrooks txp->tx_mbuf = NULL; 2594149639Sbrooks txp->tx_cb = (struct fxp_cb_tx *)sc->mcsp; 2595149639Sbrooks txp->tx_next = sc->fxp_desc.tx_list; 2596149639Sbrooks (void) fxp_mc_addrs(sc); 2597149639Sbrooks sc->fxp_desc.tx_first = sc->fxp_desc.tx_last = txp; 2598149639Sbrooks sc->tx_queued = 1; 2599149639Sbrooks 2600149639Sbrooks /* 2601149639Sbrooks * Wait until command unit is not active. This should never 2602149639Sbrooks * be the case when nothing is queued, but make sure anyway. 2603149639Sbrooks */ 2604149639Sbrooks count = 100; 2605149639Sbrooks while ((CSR_READ_1(sc, FXP_CSR_SCB_RUSCUS) >> 6) == 2606149639Sbrooks FXP_SCB_CUS_ACTIVE && --count) 2607149639Sbrooks DELAY(10); 2608149639Sbrooks if (count == 0) { 2609149639Sbrooks device_printf(sc->dev, "command queue timeout\n"); 2610149639Sbrooks return; 2611149639Sbrooks } 2612149639Sbrooks 2613149639Sbrooks /* 2614147072Sbrooks * Start the multicast setup command. 2615147072Sbrooks */ 2616147072Sbrooks fxp_scb_wait(sc); 2617147072Sbrooks bus_dmamap_sync(sc->mcs_tag, sc->mcs_map, BUS_DMASYNC_PREWRITE); 2618147072Sbrooks CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, sc->mcs_addr); 2619147072Sbrooks fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START); 2620147072Sbrooks 2621147072Sbrooks ifp->if_timer = 2; 2622147072Sbrooks return; 2623147072Sbrooks} 2624147072Sbrooks 2625147072Sbrooksstatic u_int32_t fxp_ucode_d101a[] = D101_A_RCVBUNDLE_UCODE; 2626147072Sbrooksstatic u_int32_t fxp_ucode_d101b0[] = D101_B0_RCVBUNDLE_UCODE; 2627147072Sbrooksstatic u_int32_t fxp_ucode_d101ma[] = D101M_B_RCVBUNDLE_UCODE; 2628147072Sbrooksstatic u_int32_t fxp_ucode_d101s[] = D101S_RCVBUNDLE_UCODE; 2629147072Sbrooksstatic u_int32_t fxp_ucode_d102[] = D102_B_RCVBUNDLE_UCODE; 2630147072Sbrooksstatic u_int32_t fxp_ucode_d102c[] = D102_C_RCVBUNDLE_UCODE; 2631147072Sbrooks 2632147072Sbrooks#define UCODE(x) x, sizeof(x) 2633147072Sbrooks 2634147072Sbrooksstruct ucode { 2635147072Sbrooks u_int32_t revision; 2636147072Sbrooks u_int32_t *ucode; 2637147072Sbrooks int length; 2638147072Sbrooks u_short int_delay_offset; 2639147072Sbrooks u_short bundle_max_offset; 2640147072Sbrooks} ucode_table[] = { 2641147072Sbrooks { FXP_REV_82558_A4, UCODE(fxp_ucode_d101a), D101_CPUSAVER_DWORD, 0 }, 2642147072Sbrooks { FXP_REV_82558_B0, UCODE(fxp_ucode_d101b0), D101_CPUSAVER_DWORD, 0 }, 2643147072Sbrooks { FXP_REV_82559_A0, UCODE(fxp_ucode_d101ma), 2644147072Sbrooks D101M_CPUSAVER_DWORD, D101M_CPUSAVER_BUNDLE_MAX_DWORD }, 2645147072Sbrooks { FXP_REV_82559S_A, UCODE(fxp_ucode_d101s), 2646147072Sbrooks D101S_CPUSAVER_DWORD, D101S_CPUSAVER_BUNDLE_MAX_DWORD }, 2647147072Sbrooks { FXP_REV_82550, UCODE(fxp_ucode_d102), 2648147072Sbrooks D102_B_CPUSAVER_DWORD, D102_B_CPUSAVER_BUNDLE_MAX_DWORD }, 2649147072Sbrooks { FXP_REV_82550_C, UCODE(fxp_ucode_d102c), 2650147072Sbrooks D102_C_CPUSAVER_DWORD, D102_C_CPUSAVER_BUNDLE_MAX_DWORD }, 2651147072Sbrooks { 0, NULL, 0, 0, 0 } 2652147072Sbrooks}; 2653147072Sbrooks 2654147072Sbrooksstatic void 2655147072Sbrooksfxp_load_ucode(struct fxp_softc *sc) 2656147072Sbrooks{ 2657147072Sbrooks struct ucode *uc; 2658147072Sbrooks struct fxp_cb_ucode *cbp; 2659147072Sbrooks 2660147072Sbrooks for (uc = ucode_table; uc->ucode != NULL; uc++) 2661147072Sbrooks if (sc->revision == uc->revision) 2662147072Sbrooks break; 2663147072Sbrooks if (uc->ucode == NULL) 2664147072Sbrooks return; 2665147072Sbrooks cbp = (struct fxp_cb_ucode *)sc->fxp_desc.cbl_list; 2666147072Sbrooks cbp->cb_status = 0; 2667147072Sbrooks cbp->cb_command = htole16(FXP_CB_COMMAND_UCODE | FXP_CB_COMMAND_EL); 2668147072Sbrooks cbp->link_addr = 0xffffffff; /* (no) next command */ 2669147072Sbrooks memcpy(cbp->ucode, uc->ucode, uc->length); 2670147072Sbrooks if (uc->int_delay_offset) 2671147072Sbrooks *(u_int16_t *)&cbp->ucode[uc->int_delay_offset] = 2672147072Sbrooks htole16(sc->tunable_int_delay + sc->tunable_int_delay / 2); 2673147072Sbrooks if (uc->bundle_max_offset) 2674147072Sbrooks *(u_int16_t *)&cbp->ucode[uc->bundle_max_offset] = 2675147072Sbrooks htole16(sc->tunable_bundle_max); 2676147072Sbrooks /* 2677147072Sbrooks * Download the ucode to the chip. 2678147072Sbrooks */ 2679147072Sbrooks fxp_scb_wait(sc); 2680147072Sbrooks bus_dmamap_sync(sc->cbl_tag, sc->cbl_map, BUS_DMASYNC_PREWRITE); 2681147072Sbrooks CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, sc->fxp_desc.cbl_addr); 2682147072Sbrooks fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START); 2683147072Sbrooks /* ...and wait for it to complete. */ 2684147072Sbrooks fxp_dma_wait(sc, &cbp->cb_status, sc->cbl_tag, sc->cbl_map); 2685147072Sbrooks bus_dmamap_sync(sc->cbl_tag, sc->cbl_map, BUS_DMASYNC_POSTWRITE); 2686147072Sbrooks device_printf(sc->dev, 2687147072Sbrooks "Microcode loaded, int_delay: %d usec bundle_max: %d\n", 2688147072Sbrooks sc->tunable_int_delay, 2689147072Sbrooks uc->bundle_max_offset == 0 ? 0 : sc->tunable_bundle_max); 2690147072Sbrooks sc->flags |= FXP_FLAG_UCODE; 2691180130Sed} 2692147072Sbrooks 2693147072Sbrooksstatic int 2694147072Sbrookssysctl_int_range(SYSCTL_HANDLER_ARGS, int low, int high) 2695147072Sbrooks{ 2696147072Sbrooks int error, value; 2697147072Sbrooks 2698147072Sbrooks value = *(int *)arg1; 2699147072Sbrooks error = sysctl_handle_int(oidp, &value, 0, req); 2700147072Sbrooks if (error || !req->newptr) 2701147072Sbrooks return (error); 2702147072Sbrooks if (value < low || value > high) 2703147072Sbrooks return (EINVAL); 2704147072Sbrooks *(int *)arg1 = value; 2705147072Sbrooks return (0); 2706147072Sbrooks} 2707147072Sbrooks 2708147072Sbrooks/* 2709147072Sbrooks * Interrupt delay is expressed in microseconds, a multiplier is used 2710147072Sbrooks * to convert this to the appropriate clock ticks before using. 2711 */ 2712static int 2713sysctl_hw_fxp_int_delay(SYSCTL_HANDLER_ARGS) 2714{ 2715 return (sysctl_int_range(oidp, arg1, arg2, req, 300, 3000)); 2716} 2717 2718static int 2719sysctl_hw_fxp_bundle_max(SYSCTL_HANDLER_ARGS) 2720{ 2721 return (sysctl_int_range(oidp, arg1, arg2, req, 1, 0xffff)); 2722} 2723