int atachkpwr(struct dkdev_ata *l, int n) { struct dvata_chan *chan = &l->chan[n]; CSR_WRITE_1(chan->cmd + _CMD, ATA_CMD_CHKPWR); (void)CSR_READ_1(chan->alt); delay(10 * 1000); return CSR_READ_1(chan->cmd + _NSECT); }
static void dump_regs(Environ *e, Self *s) { dprintf("\n"); dprintf("ethxpro: scb_rus/scb_cus: %#x\n", CSR_READ_1(s, CSR_SCB_RUSCUS)); dprintf("ethxpro: scb_statack: %#x\n", CSR_READ_1(s, CSR_SCB_STATACK)); dprintf("ethxpro: scb_command: %#x\n", CSR_READ_1(s, CSR_SCB_COMMAND)); dprintf("ethxpro: scb_intrcntl: %#x\n", CSR_READ_1(s, CSR_SCB_INTRCNTL)); dprintf("ethxpro: scb_general: %#x\n", CSR_READ_4(s, CSR_SCB_GENERAL)); dprintf("ethxpro: port: %#x\n", CSR_READ_4(s, CSR_PORT)); dprintf("ethxpro: flash control: %#x\n", CSR_READ_2(s, CSR_FLASHCONTROL)); dprintf("ethxpro: eeprom ctrl: %#x\n", CSR_READ_2(s, CSR_EEPROMCONTROL)); dprintf("ethxpro: mdi control: %#x\n", CSR_READ_4(s, CSR_MDICONTROL)); }
/* clear idle and standby timers to spin up the drive */ void wakeup_drive(struct dkdev_ata *l, int n) { struct dvata_chan *chan = &l->chan[n]; CSR_WRITE_1(chan->cmd + _NSECT, 0); CSR_WRITE_1(chan->cmd + _CMD, ATA_CMD_IDLE); (void)CSR_READ_1(chan->alt); delay(10 * 1000); CSR_WRITE_1(chan->cmd + _NSECT, 0); CSR_WRITE_1(chan->cmd + _CMD, ATA_CMD_STANDBY); (void)CSR_READ_1(chan->alt); delay(10 * 1000); }
void ste_txeoc(struct ste_softc *sc) { u_int8_t txstat; struct ifnet *ifp; ifp = &sc->arpcom.ac_if; while ((txstat = CSR_READ_1(sc, STE_TX_STATUS)) & STE_TXSTATUS_TXDONE) { if (txstat & STE_TXSTATUS_UNDERRUN || txstat & STE_TXSTATUS_EXCESSCOLLS || txstat & STE_TXSTATUS_RECLAIMERR) { ifp->if_oerrors++; printf("%s: transmission error: %x\n", sc->sc_dev.dv_xname, txstat); ste_reset(sc); ste_init(sc); if (txstat & STE_TXSTATUS_UNDERRUN && sc->ste_tx_thresh < ETHER_MAX_DIX_LEN) { sc->ste_tx_thresh += STE_MIN_FRAMELEN; printf("%s: tx underrun, increasing tx" " start threshold to %d bytes\n", sc->sc_dev.dv_xname, sc->ste_tx_thresh); } CSR_WRITE_2(sc, STE_TX_STARTTHRESH, sc->ste_tx_thresh); CSR_WRITE_2(sc, STE_TX_RECLAIM_THRESH, (ETHER_MAX_DIX_LEN >> 4)); } ste_init(sc); CSR_WRITE_2(sc, STE_TX_STATUS, txstat); }
static uint32_t vr_mii_bitbang_read(device_t self) { struct vr_softc *sc = device_private(self); return (CSR_READ_1(sc, VR_MIICMD)); }
static void ex_probemedia(void) { int i, j; struct mtabentry *m; /* test for presence of connectors */ GO_WINDOW(3); i = CSR_READ_1(ELINK_W3_RESET_OPTIONS); j = (CSR_READ_2(ELINK_W3_INTERNAL_CONFIG + 2) & CONFIG_MEDIAMASK) >> CONFIG_MEDIAMASK_SHIFT; GO_WINDOW(0); for (ether_medium = 0, m = mediatab; ether_medium < sizeof(mediatab) / sizeof(mediatab[0]); ether_medium++, m++) { if (j == m->address_cfg) { if (!(i & m->config_bit)) { printf("%s not present\n", m->name); goto bad; } printf("using %s\n", m->name); return; } } printf("unknown connector\n"); bad: ether_medium = -1; }
/* * Read a word of data stored in the EEPROM at address 'addr.' */ uint16_t rtk_read_eeprom(struct rtk_softc *sc, int addr, int addr_len) { uint16_t word; int i; /* Enter EEPROM access mode. */ CSR_WRITE_1(sc, RTK_EECMD, RTK_EEMODE_PROGRAM); EE_DELAY(); EE_SET(RTK_EE_SEL); /* * Send address of word we want to read. */ rtk_eeprom_putbyte(sc, addr, addr_len); /* * Start reading bits from EEPROM. */ word = 0; for (i = 16; i > 0; i--) { EE_SET(RTK_EE_CLK); EE_DELAY(); if (CSR_READ_1(sc, RTK_EECMD) & RTK_EE_DATAOUT) word |= 1 << (i - 1); EE_CLR(RTK_EE_CLK); EE_DELAY(); } /* Turn off EEPROM access mode. */ CSR_WRITE_1(sc, RTK_EECMD, RTK_EEMODE_OFF); return word; }
/* wait for the command to be accepted but not necessarily completed */ static void scb_wait(Self *s) { int i = 10000; while (CSR_READ_1(s, CSR_SCB_COMMAND) && --i) DELAY(1); }
static int ex_look_for_card(struct ex_softc *sc) { int count1, count2; /* * Check for the i82595 signature, and check that the round robin * counter actually advances. */ if (((count1 = CSR_READ_1(sc, ID_REG)) & Id_Mask) != Id_Sig) return(0); count2 = CSR_READ_1(sc, ID_REG); count2 = CSR_READ_1(sc, ID_REG); count2 = CSR_READ_1(sc, ID_REG); return((count2 & Counter_bits) == ((count1 + 0xc0) & Counter_bits)); }
/* * Program the 64-bit multicast hash filter. */ static void vr_setmulti(struct vr_softc *sc) { struct ifnet *ifp; int h = 0; uint32_t hashes[2] = { 0, 0 }; struct ether_multistep step; struct ether_multi *enm; int mcnt = 0; uint8_t rxfilt; ifp = &sc->vr_ec.ec_if; rxfilt = CSR_READ_1(sc, VR_RXCFG); if (ifp->if_flags & IFF_PROMISC) { allmulti: ifp->if_flags |= IFF_ALLMULTI; rxfilt |= VR_RXCFG_RX_MULTI; CSR_WRITE_1(sc, VR_RXCFG, rxfilt); CSR_WRITE_4(sc, VR_MAR0, 0xFFFFFFFF); CSR_WRITE_4(sc, VR_MAR1, 0xFFFFFFFF); return; } /* first, zot all the existing hash bits */ CSR_WRITE_4(sc, VR_MAR0, 0); CSR_WRITE_4(sc, VR_MAR1, 0); /* now program new ones */ ETHER_FIRST_MULTI(step, &sc->vr_ec, enm); while (enm != NULL) { if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN) != 0) goto allmulti; h = vr_calchash(enm->enm_addrlo); if (h < 32) hashes[0] |= (1 << h); else hashes[1] |= (1 << (h - 32)); ETHER_NEXT_MULTI(step, enm); mcnt++; } ifp->if_flags &= ~IFF_ALLMULTI; if (mcnt) rxfilt |= VR_RXCFG_RX_MULTI; else rxfilt &= ~VR_RXCFG_RX_MULTI; CSR_WRITE_4(sc, VR_MAR0, hashes[0]); CSR_WRITE_4(sc, VR_MAR1, hashes[1]); CSR_WRITE_1(sc, VR_RXCFG, rxfilt); }
/* * Wait for the previous command to be accepted (but not necessarily * completed). */ static inline void fxp_scb_wait() { int i = 10000; while (CSR_READ_1(FXP_CSR_SCB_COMMAND) && --i) DELAY(1); if (i == 0) printf("fxp: WARNING: SCB timed out!\n"); }
static int probe_drive(struct dkdev_ata *l, int n) { struct dvata_chan *chan = &l->chan[n]; uint16_t *p; int i; CSR_WRITE_1(chan->cmd + _CMD, ATA_CMD_IDENT); (void)CSR_READ_1(chan->alt); delay(10 * 1000); if (spinwait_unbusy(l, n, 1000, NULL) == 0) return 0; p = (uint16_t *)l->iobuf; for (i = 0; i < 512; i += 2) { /* need to have bswap16 */ *p++ = iole16toh(chan->cmd + _DAT); } (void)CSR_READ_1(chan->cmd + _STS); return 1; }
void ste_iff(struct ste_softc *sc) { struct ifnet *ifp = &sc->arpcom.ac_if; struct arpcom *ac = &sc->arpcom; struct ether_multi *enm; struct ether_multistep step; u_int32_t rxmode, hashes[2]; int h = 0; rxmode = CSR_READ_1(sc, STE_RX_MODE); rxmode &= ~(STE_RXMODE_ALLMULTI | STE_RXMODE_BROADCAST | STE_RXMODE_MULTIHASH | STE_RXMODE_PROMISC | STE_RXMODE_UNICAST); bzero(hashes, sizeof(hashes)); ifp->if_flags &= ~IFF_ALLMULTI; /* * Always accept broadcast frames. * Always accept frames destined to our station address. */ rxmode |= STE_RXMODE_BROADCAST | STE_RXMODE_UNICAST; if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) { ifp->if_flags |= IFF_ALLMULTI; rxmode |= STE_RXMODE_ALLMULTI; if (ifp->if_flags & IFF_PROMISC) rxmode |= STE_RXMODE_PROMISC; } else { rxmode |= STE_RXMODE_MULTIHASH; /* now program new ones */ ETHER_FIRST_MULTI(step, ac, enm); while (enm != NULL) { h = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN) & 0x3F; if (h < 32) hashes[0] |= (1 << h); else hashes[1] |= (1 << (h - 32)); ETHER_NEXT_MULTI(step, enm); } } CSR_WRITE_2(sc, STE_MAR0, hashes[0] & 0xFFFF); CSR_WRITE_2(sc, STE_MAR1, (hashes[0] >> 16) & 0xFFFF); CSR_WRITE_2(sc, STE_MAR2, hashes[1] & 0xFFFF); CSR_WRITE_2(sc, STE_MAR3, (hashes[1] >> 16) & 0xFFFF); CSR_WRITE_1(sc, STE_RX_MODE, rxmode); }
void rtk_reset(struct rtk_softc *sc) { int i; CSR_WRITE_1(sc, RTK_COMMAND, RTK_CMD_RESET); for (i = 0; i < RTK_TIMEOUT; i++) { DELAY(10); if ((CSR_READ_1(sc, RTK_COMMAND) & RTK_CMD_RESET) == 0) break; } if (i == RTK_TIMEOUT) printf("%s: reset never completed!\n", device_xname(sc->sc_dev)); }
static int lba_read(struct disk *d, int64_t bno, int bcnt, void *buf) { struct dkdev_ata *l; struct dvata_chan *chan; void (*issue)(struct dvata_chan *, int64_t, int); int n, rdcnt, i, k; uint16_t *p; const char *err; int error; l = d->dvops; n = d->unittag; p = (uint16_t *)buf; chan = &l->chan[n]; error = 0; for ( ; bcnt > 0; bno += rdcnt, bcnt -= rdcnt) { issue = (bno < (1ULL<<28)) ? issue28 : issue48; rdcnt = (bcnt > 255) ? 255 : bcnt; (*issue)(chan, bno, rdcnt); for (k = 0; k < rdcnt; k++) { if (spinwait_unbusy(l, n, 1000, &err) == 0) { printf("%s blk %lld %s\n", d->xname, bno, err); error = EIO; break; } for (i = 0; i < 512; i += 2) { /* arrives in native order */ *p++ = *(uint16_t *)(chan->cmd + _DAT); } /* clear irq if any */ (void)CSR_READ_1(chan->cmd + _STS); } } return error; }
int spinwait_unbusy(struct dkdev_ata *l, int n, int milli, const char **err) { struct dvata_chan *chan = &l->chan[n]; int sts; const char *msg; /* * For best compatibility it is recommended to wait 400ns and * read the alternate status byte four times before the status * is valid. */ delay(1); (void)CSR_READ_1(chan->alt); (void)CSR_READ_1(chan->alt); (void)CSR_READ_1(chan->alt); (void)CSR_READ_1(chan->alt); sts = CSR_READ_1(chan->cmd + _STS); while (milli-- > 0 && sts != 0xff && (sts & (ATA_STS_BUSY|ATA_STS_DRDY)) != ATA_STS_DRDY) { delay(1000); sts = CSR_READ_1(chan->cmd + _STS); } msg = NULL; if (sts == 0xff) msg = "returned 0xff"; else if (sts & ATA_STS_ERR) msg = "returned ERR"; else if (sts & ATA_STS_BUSY) msg = "remains BUSY"; else if ((sts & ATA_STS_DRDY) == 0) msg = "no DRDY"; if (err != NULL) *err = msg; return msg == NULL; }
/* * A frame has been uploaded: pass the resulting mbuf chain up to * the higher level protocols. * * You know there's something wrong with a PCI bus-master chip design. * * The receive operation is badly documented in the datasheet, so I'll * attempt to document it here. The driver provides a buffer area and * places its base address in the RX buffer start address register. * The chip then begins copying frames into the RX buffer. Each frame * is preceded by a 32-bit RX status word which specifies the length * of the frame and certain other status bits. Each frame (starting with * the status word) is also 32-bit aligned. The frame length is in the * first 16 bits of the status word; the lower 15 bits correspond with * the 'rx status register' mentioned in the datasheet. * * Note: to make the Alpha happy, the frame payload needs to be aligned * on a 32-bit boundary. To achieve this, we copy the data to mbuf * shifted forward 2 bytes. */ static void rtk_rxeof(struct rtk_softc *sc) { struct mbuf *m; struct ifnet *ifp; uint8_t *rxbufpos, *dst; u_int total_len, wrap; uint32_t rxstat; uint16_t cur_rx, new_rx; uint16_t limit; uint16_t rx_bytes, max_bytes; ifp = &sc->ethercom.ec_if; cur_rx = (CSR_READ_2(sc, RTK_CURRXADDR) + 16) % RTK_RXBUFLEN; /* Do not try to read past this point. */ limit = CSR_READ_2(sc, RTK_CURRXBUF) % RTK_RXBUFLEN; if (limit < cur_rx) max_bytes = (RTK_RXBUFLEN - cur_rx) + limit; else max_bytes = limit - cur_rx; rx_bytes = 0; while ((CSR_READ_1(sc, RTK_COMMAND) & RTK_CMD_EMPTY_RXBUF) == 0) { rxbufpos = sc->rtk_rx_buf + cur_rx; bus_dmamap_sync(sc->sc_dmat, sc->recv_dmamap, cur_rx, RTK_RXSTAT_LEN, BUS_DMASYNC_POSTREAD); rxstat = le32toh(*(uint32_t *)rxbufpos); bus_dmamap_sync(sc->sc_dmat, sc->recv_dmamap, cur_rx, RTK_RXSTAT_LEN, BUS_DMASYNC_PREREAD); /* * Here's a totally undocumented fact for you. When the * RealTek chip is in the process of copying a packet into * RAM for you, the length will be 0xfff0. If you spot a * packet header with this value, you need to stop. The * datasheet makes absolutely no mention of this and * RealTek should be shot for this. */ total_len = rxstat >> 16; if (total_len == RTK_RXSTAT_UNFINISHED) break; if ((rxstat & RTK_RXSTAT_RXOK) == 0 || total_len < ETHER_MIN_LEN || total_len > (MCLBYTES - RTK_ETHER_ALIGN)) { ifp->if_ierrors++; /* * submitted by:[netbsd-pcmcia:00484] * Takahiro Kambe <*****@*****.**> * obtain from: * FreeBSD if_rl.c rev 1.24->1.25 * */ #if 0 if (rxstat & (RTK_RXSTAT_BADSYM|RTK_RXSTAT_RUNT| RTK_RXSTAT_GIANT|RTK_RXSTAT_CRCERR| RTK_RXSTAT_ALIGNERR)) { CSR_WRITE_2(sc, RTK_COMMAND, RTK_CMD_TX_ENB); CSR_WRITE_2(sc, RTK_COMMAND, RTK_CMD_TX_ENB|RTK_CMD_RX_ENB); CSR_WRITE_4(sc, RTK_RXCFG, RTK_RXCFG_CONFIG); CSR_WRITE_4(sc, RTK_RXADDR, sc->recv_dmamap->dm_segs[0].ds_addr); cur_rx = 0; } break; #else rtk_init(ifp); return; #endif } /* No errors; receive the packet. */ rx_bytes += total_len + RTK_RXSTAT_LEN; /* * Avoid trying to read more bytes than we know * the chip has prepared for us. */ if (rx_bytes > max_bytes) break; /* * Skip the status word, wrapping around to the beginning * of the Rx area, if necessary. */ cur_rx = (cur_rx + RTK_RXSTAT_LEN) % RTK_RXBUFLEN; rxbufpos = sc->rtk_rx_buf + cur_rx; /* * Compute the number of bytes at which the packet * will wrap to the beginning of the ring buffer. */ wrap = RTK_RXBUFLEN - cur_rx; /* * Compute where the next pending packet is. */ if (total_len > wrap) new_rx = total_len - wrap; else new_rx = cur_rx + total_len; /* Round up to 32-bit boundary. */ new_rx = roundup2(new_rx, sizeof(uint32_t)) % RTK_RXBUFLEN; /* * The RealTek chip includes the CRC with every * incoming packet; trim it off here. */ total_len -= ETHER_CRC_LEN; /* * Now allocate an mbuf (and possibly a cluster) to hold * the packet. Note we offset the packet 2 bytes so that * data after the Ethernet header will be 4-byte aligned. */ MGETHDR(m, M_DONTWAIT, MT_DATA); if (m == NULL) { printf("%s: unable to allocate Rx mbuf\n", device_xname(sc->sc_dev)); ifp->if_ierrors++; goto next_packet; } if (total_len > (MHLEN - RTK_ETHER_ALIGN)) { MCLGET(m, M_DONTWAIT); if ((m->m_flags & M_EXT) == 0) { printf("%s: unable to allocate Rx cluster\n", device_xname(sc->sc_dev)); ifp->if_ierrors++; m_freem(m); m = NULL; goto next_packet; } } m->m_data += RTK_ETHER_ALIGN; /* for alignment */ m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = total_len; dst = mtod(m, void *); /* * If the packet wraps, copy up to the wrapping point. */ if (total_len > wrap) { bus_dmamap_sync(sc->sc_dmat, sc->recv_dmamap, cur_rx, wrap, BUS_DMASYNC_POSTREAD); memcpy(dst, rxbufpos, wrap); bus_dmamap_sync(sc->sc_dmat, sc->recv_dmamap, cur_rx, wrap, BUS_DMASYNC_PREREAD); cur_rx = 0; rxbufpos = sc->rtk_rx_buf; total_len -= wrap; dst += wrap; } /* * ...and now the rest. */ bus_dmamap_sync(sc->sc_dmat, sc->recv_dmamap, cur_rx, total_len, BUS_DMASYNC_POSTREAD); memcpy(dst, rxbufpos, total_len); bus_dmamap_sync(sc->sc_dmat, sc->recv_dmamap, cur_rx, total_len, BUS_DMASYNC_PREREAD); next_packet: CSR_WRITE_2(sc, RTK_CURRXADDR, (new_rx - 16) % RTK_RXBUFLEN); cur_rx = new_rx; if (m == NULL) continue; ifp->if_ipackets++; bpf_mtap(ifp, m); /* pass it on. */ (*ifp->if_input)(ifp, m); } }
static void ex_init_locked(struct ex_softc *sc) { struct ifnet * ifp = sc->ifp; int i; unsigned short temp_reg; DODEBUG(Start_End, printf("%s: ex_init: start\n", ifp->if_xname);); sc->tx_timeout = 0; /* * Load the ethernet address into the card. */ CSR_WRITE_1(sc, CMD_REG, Bank2_Sel); temp_reg = CSR_READ_1(sc, EEPROM_REG); if (temp_reg & Trnoff_Enable) CSR_WRITE_1(sc, EEPROM_REG, temp_reg & ~Trnoff_Enable); for (i = 0; i < ETHER_ADDR_LEN; i++) CSR_WRITE_1(sc, I_ADDR_REG0 + i, IF_LLADDR(sc->ifp)[i]); /* * - Setup transmit chaining and discard bad received frames. * - Match broadcast. * - Clear test mode. * - Set receiving mode. */ CSR_WRITE_1(sc, REG1, CSR_READ_1(sc, REG1) | Tx_Chn_Int_Md | Tx_Chn_ErStp | Disc_Bad_Fr); CSR_WRITE_1(sc, REG2, CSR_READ_1(sc, REG2) | No_SA_Ins | RX_CRC_InMem); CSR_WRITE_1(sc, REG3, CSR_READ_1(sc, REG3) & 0x3f /* XXX constants. */ ); /*
/* Probe routine. See if the card is there and at the right place. */ static int el_probe(device_t dev) { struct el_softc *sc; u_short base; /* Just for convenience */ u_char station_addr[ETHER_ADDR_LEN]; int i, rid; /* Grab some info for our structure */ sc = device_get_softc(dev); if (isa_get_logicalid(dev)) /* skip PnP probes */ return (ENXIO); if ((base = bus_get_resource_start(dev, SYS_RES_IOPORT, 0)) == 0) return (ENXIO); /* First check the base */ if((base < 0x280) || (base > 0x3f0)) { device_printf(dev, "ioaddr must be between 0x280 and 0x3f0\n"); return(ENXIO); } /* Temporarily map the resources. */ rid = 0; sc->el_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, EL_IOSIZ, RF_ACTIVE); if (sc->el_res == NULL) return(ENXIO); sc->el_btag = rman_get_bustag(sc->el_res); sc->el_bhandle = rman_get_bushandle(sc->el_res); mtx_init(&sc->el_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF | MTX_RECURSE); EL_LOCK(sc); /* Now attempt to grab the station address from the PROM * and see if it contains the 3com vendor code. */ dprintf(("Probing 3c501 at 0x%x...\n",base)); /* Reset the board */ dprintf(("Resetting board...\n")); CSR_WRITE_1(sc,EL_AC,EL_AC_RESET); DELAY(5); CSR_WRITE_1(sc,EL_AC,0); dprintf(("Reading station address...\n")); /* Now read the address */ for(i=0;i<ETHER_ADDR_LEN;i++) { CSR_WRITE_1(sc,EL_GPBL,i); station_addr[i] = CSR_READ_1(sc,EL_EAW); } /* Now release resources */ bus_release_resource(dev, SYS_RES_IOPORT, rid, sc->el_res); EL_UNLOCK(sc); mtx_destroy(&sc->el_mtx); dprintf(("Address is %6D\n",station_addr, ":")); /* If the vendor code is ok, return a 1. We'll assume that * whoever configured this system is right about the IRQ. */ if((station_addr[0] != 0x02) || (station_addr[1] != 0x60) || (station_addr[2] != 0x8c)) { dprintf(("Bad vendor code.\n")); return(ENXIO); } else { dprintf(("Vendor code ok.\n")); /* Copy the station address into the arpcom structure */ bcopy(station_addr,sc->arpcom.ac_enaddr,ETHER_ADDR_LEN); } device_set_desc(dev, "3Com 3c501 Ethernet"); return(0); }