/* * MII entry points. */ uint16_t efe_mii_read(void *arg, uint8_t phy, uint8_t reg) { efe_t *efep = arg; PUTCSR(efep, CSR_MMCTL, MMCTL_READ | reg << MMCTL_PHYREG | phy << MMCTL_PHYADDR); for (int i = 0; i < MII_DELAY_CYCLES; ++i) { if (!(GETCSR(efep, CSR_MMCTL) & MMCTL_READ)) { return ((uint16_t)GETCSR(efep, CSR_MMDATA)); } drv_usecwait(MII_DELAY); } efe_error(efep->efe_dip, "timed out reading from MII!"); return (0); }
inline int efe_eeprom_readbit(efe_t *efep) { PUTCSR(efep, CSR_EECTL, EECTL_ENABLE | EECTL_EECS); drv_usecwait(EEPROM_DELAY); PUTCSR(efep, CSR_EECTL, EECTL_ENABLE | EECTL_EECS | EECTL_EESK); drv_usecwait(EEPROM_DELAY); PUTCSR(efep, CSR_EECTL, EECTL_ENABLE | EECTL_EECS); drv_usecwait(EEPROM_DELAY); return (!!(GETCSR(efep, CSR_EECTL) & EECTL_EEDO)); }
void efe_mii_write(void *arg, uint8_t phy, uint8_t reg, uint16_t data) { efe_t *efep = arg; PUTCSR(efep, CSR_MMDATA, data); PUTCSR(efep, CSR_MMCTL, MMCTL_WRITE | reg << MMCTL_PHYREG | phy << MMCTL_PHYADDR); for (int i = 0; i < MII_DELAY_CYCLES; ++i) { if (!(GETCSR(efep, CSR_MMCTL) & MMCTL_WRITE)) { return; } drv_usecwait(MII_DELAY); } efe_error(efep->efe_dip, "timed out writing to MII!"); }
void efe_eeprom_read(efe_t *efep, uint8_t *buf, size_t len, uint8_t addr) { int addrlen; ASSERT(len & ~0x1); /* non-zero; word-aligned */ PUTCSR(efep, CSR_EECTL, EECTL_ENABLE | EECTL_EECS); drv_usecwait(EEPROM_DELAY); addrlen = (GETCSR(efep, CSR_EECTL) & EECTL_SIZE ? AT93C46_ADDRLEN : AT93C56_ADDRLEN); for (int i = 0; i < len / sizeof (uint16_t); ++i) { uint16_t val = efe_eeprom_readw(efep, addrlen, addr + i); bcopy(&val, buf, sizeof (uint16_t)); buf += sizeof (uint16_t); } }
void efe_stop_dma(efe_t *efep) { ASSERT(mutex_owned(&efep->efe_intrlock)); ASSERT(mutex_owned(&efep->efe_txlock)); PUTCSR(efep, CSR_COMMAND, COMMAND_STOP_RDMA | COMMAND_STOP_TDMA); for (int i = 0; i < STOP_DELAY_CYCLES; ++i) { uint32_t status = GETCSR(efep, CSR_INTSTAT); if (status & INTSTAT_RXIDLE && status & INTSTAT_TXIDLE) { return; } drv_usecwait(STOP_DELAY); } efe_error(efep->efe_dip, "timed out stopping DMA engine!"); }
/* * ISR/periodic callbacks. */ uint_t efe_intr(caddr_t arg1, caddr_t arg2) { efe_t *efep = (void *)arg1; uint32_t status; mblk_t *mp = NULL; _NOTE(ARGUNUSED(arg2)); mutex_enter(&efep->efe_intrlock); if (efep->efe_flags & FLAG_SUSPENDED) { mutex_exit(&efep->efe_intrlock); return (DDI_INTR_UNCLAIMED); } status = GETCSR(efep, CSR_INTSTAT); if (!(status & INTSTAT_ACTV)) { mutex_exit(&efep->efe_intrlock); return (DDI_INTR_UNCLAIMED); } PUTCSR(efep, CSR_INTSTAT, status); if (status & INTSTAT_RCC) { mp = efe_recv(efep); } if (status & INTSTAT_RQE) { efep->efe_ierrors++; efep->efe_macrcv_errors++; /* Kick the receiver */ PUTCSR(efep, CSR_COMMAND, COMMAND_RXQUEUED); } if (status & INTSTAT_TXC) { mutex_enter(&efep->efe_txlock); efe_send_done(efep); mutex_exit(&efep->efe_txlock); } if (status & INTSTAT_FATAL) { mutex_enter(&efep->efe_txlock); efe_error(efep->efe_dip, "bus error; resetting!"); efe_restart(efep); mutex_exit(&efep->efe_txlock); } mutex_exit(&efep->efe_intrlock); if (mp != NULL) { mac_rx(efep->efe_mh, NULL, mp); } if (status & INTSTAT_TXC) { mac_tx_update(efep->efe_mh); } if (status & INTSTAT_FATAL) { mii_reset(efep->efe_miih); } return (DDI_INTR_CLAIMED); }
long siglab_disable_denormals() { int _savemxcsr = GETCSR(); SETCSR(_savemxcsr | 0x8040); return _savemxcsr; }