📄 dm90x0.c
字号:
/**************************************************************************** * Function: read8, read16, read32 * * Description: * Read packet data from the DM90x0 SRAM based on its current I/O mode * * Parameters: * ptr - Location to write the packet data * len - The number of bytes to read * * Returned Value: * None * * Assumptions: * ****************************************************************************/static void read8(uint8 *ptr, int len){ nvdbg("Read %d bytes (8-bit mode)\n", len); for (; len > 0; len--) { *ptr++ = DM9X_DATA; }}static void read16(uint8 *ptr, int len){ register uint16 *ptr16 = (uint16*)ptr; nvdbg("Read %d bytes (16-bit mode)\n", len); for (; len > 0; len -= sizeof(uint16)) { *ptr16++ = DM9X_DATA; }}static void read32(uint8 *ptr, int len){ register uint32 *ptr32 = (uint32*)ptr; nvdbg("Read %d bytes (32-bit mode)\n", len); for (; len > 0; len -= sizeof(uint32)) { *ptr32++ = DM9X_DATA; }}/**************************************************************************** * Function: discard8, discard16, discard32 * * Description: * Read and discard packet data in the DM90x0 SRAM based on its current * I/O mode * * Parameters: * len - The number of bytes to discard * * Returned Value: * None * * Assumptions: * ****************************************************************************/static void discard8(int len){ nvdbg("Discard %d bytes (8-bit mode)\n", len); for (; len > 0; len--) { DM9X_DATA; }}static void discard16(int len){ nvdbg("Discard %d bytes (16-bit mode)\n", len); for (; len > 0; len -= sizeof(uint16)) { DM9X_DATA; }}static void discard32(int len){ nvdbg("Discard %d bytes (32-bit mode)\n", len); for (; len > 0; len -= sizeof(uint32)) { DM9X_DATA; }}/**************************************************************************** * Function: write8, write16, write32 * * Description: * Write packet data into the DM90x0 SRAM based on its current I/O mode * * Parameters: * ptr - Location to write the packet data * len - The number of bytes to read * * Returned Value: * None * * Assumptions: * ****************************************************************************/static void write8(const uint8 *ptr, int len){ nvdbg("Write %d bytes (8-bit mode)\n", len); for (; len > 0; len--) { DM9X_DATA = (*ptr++ & 0xff); }}static void write16(const uint8 *ptr, int len){ register uint16 *ptr16 = (uint16*)ptr; nvdbg("Write %d bytes (16-bit mode)\n", len); for (; len > 0; len -= sizeof(uint16)) { DM9X_DATA = *ptr16++; }}static void write32(const uint8 *ptr, int len){ register uint32 *ptr32 = (uint32*)ptr; nvdbg("Write %d bytes (32-bit mode)\n", len); for (; len > 0; len -= sizeof(uint32)) { DM9X_DATA = *ptr32++; }}/**************************************************************************** * Function: dm9x_readsrom * * Description: * Read a word from SROM * * Parameters: * dm9x - Reference to the driver state structure * offset - SROM offset to read from * * Returned Value: * SROM content at that offset * * Assumptions: * ****************************************************************************/#if 0 /* Not used */static uint16 dm9x_readsrom(struct dm9x_driver_s *dm9x, int offset){ putreg(DM9X_EEPHYA, offset); putreg(DM9X_EEPHYC, DM9X_EEPHYC_ERPRR); up_udelay(200); putreg(DM9X_EEPHYC, 0x00); return (getreg(DM9X_EEPHYDL) + (getreg(DM9X_EEPHYDH) << 8) );}#endif/**************************************************************************** * Function: dm9x_phyread and dm9x_phywrite * * Description: * Read/write data from/to the PHY * * Parameters: * dm9x - Reference to the driver state structure * reg - PHY register offset * value - The value to write to the PHY register (dm9x_write only) * * Returned Value: * The value read from the PHY (dm9x_read only) * * Assumptions: * ****************************************************************************/static uint16 dm9x_phyread(struct dm9x_driver_s *dm9x, int reg){ /* Setup DM9X_EEPHYA, the EEPROM/PHY address register */ putreg(DM9X_EEPHYA, DM9X_EEPHYA_EROA | reg); /* Issue PHY read command pulse in the EEPROM/PHY control register */ putreg(DM9X_EEPHYC, (DM9X_EEPHYC_ERPRR|DM9X_EEPHYC_EPOS)); up_udelay(100); putreg(DM9X_EEPHYC, 0x00); /* Return the data from the EEPROM/PHY data register pair */ return (((uint16)getreg(DM9X_EEPHYDH)) << 8) | (uint16)getreg(DM9X_EEPHYDL);}static void dm9x_phywrite(struct dm9x_driver_s *dm9x, int reg, uint16 value){ /* Setup DM9X_EEPHYA, the EEPROM/PHY address register */ putreg(DM9X_EEPHYA, DM9X_EEPHYA_EROA | reg); /* Put the data to write in the EEPROM/PHY data register pair */ putreg(DM9X_EEPHYDL, (value & 0xff)); putreg(DM9X_EEPHYDH, ((value >> 8) & 0xff)); /* Issue PHY write command pulse in the EEPROM/PHY control register */ putreg(DM9X_EEPHYC, (DM9X_EEPHYC_ERPRW|DM9X_EEPHYC_EPOS)); up_udelay(500); putreg(DM9X_EEPHYC, 0x0);}/**************************************************************************** * Function: dm9x_resetstatistics * * Description: * Reset all DM90x0 statistics * * Parameters: * dm9x - Reference to the driver state structure * * Returned Value: * None * * Assumptions: * ****************************************************************************/#if defined(CONFIG_DM9X_STATS)static void dm9x_resetstatistics(struct dm9x_driver_s *dm9x){ dm9x->dm_ntxpackets = 0; /* Count of packets sent */ dm9x->dm_ntxbytes = 0; /* Count of bytes sent */ dm9x->dm_ntxerrors = 0; /* Count of TX errors */ dm9x->dm_nrxpackets = 0; /* Count of packets received */ dm9x->dm_nrxbytes = 0; /* Count of bytes received */ dm9x->dm_nrxfifoerrors = 0; /* Count of RX FIFO overflow errors */ dm9x->dm_nrxcrcerrors = 0; /* Count of RX CRC errors */ dm9x->dm_nrxlengtherrors = 0; /* Count of RX length errors */ dm9x->dm_nphyserrors = 0; /* Count of physical layer errors */ dm9x->dm_nresets = 0; /* Counts number of resets */ dm9x->dm_ntxtimeouts = 0; /* Counts resets caused by TX timeouts */}#endif/**************************************************************************** * Function: dm9x_dumpstatistics * * Description: * Print the current value of all DM90x0 statistics * * Parameters: * dm9x - Reference to the driver state structure * * Returned Value: * None * * Assumptions: * ****************************************************************************/#if defined(CONFIG_DM9X_STATS) && defined(CONFIG_DEBUG)static void dm9x_dumpstatistics(struct dm9x_driver_s *dm9x){ ndbg("TX packets: %d\n", dm9x->dm_ntxpackets); ndbg(" bytes: %d\n", dm9x->dm_ntxbytes); ndbg(" errors: %d\n", dm9x->dm_ntxerrors); ndbg("RX packets: %d\n", dm9x->dm_nrxpackets); ndbg(" bytes: %d\n", dm9x->dm_nrxbytes); ndbg(" FIFO overflows: %d\n", dm9x->dm_nrxfifoerrors); ndbg(" CRC errors: %d\n", dm9x->dm_nrxcrcerrors); ndbg(" length errors: %d\n", dm9x->dm_nrxlengtherrors); ndbg("Physical layer errors: %d\n", dm9x->dm_nphyserrors); ndbg("Resets: %d\n", dm9x->dm_nresets); ndbg("TX timeout resets: %d\n", dm9x->dm_ntxtimeouts);}#endif/**************************************************************************** * Function: dm9x_rxchecksumready * * Description: * Return TRUE if the RX checksum is available * * Parameters: * rxbyte * * Returned Value: * TRUE: checksum is ready * * Assumptions: * ****************************************************************************/#if defined(CONFIG_DM9X_CHECKSUM)static inline boolean dm9x_rxchecksumready(uint8 rxbyte){ if ((rxbyte & 0x01) == 0) { return FALSE; } return ((rxbyte >> 4) | 0x01) != 0;}#endif/**************************************************************************** * Function: dm9x_transmit * * Description: * Start hardware transmission. Called either from the txdone interrupt * handling or from watchdog based polling. * * Parameters: * dm9x - Reference to the driver state structure * * Returned Value: * OK on success; a negated errno on failure * * Assumptions: * ****************************************************************************/static int dm9x_transmit(struct dm9x_driver_s *dm9x){ /* Check if there is room in the DM90x0 to hold another packet. In 100M mode, * that can be 2 packets, otherwise it is a single packet. */ if (dm9x->dm_ntxpending < 1 || (dm9x->dm_b100M && dm9x->dm_ntxpending < 2)) { /* Increment count of packets transmitted */ dm9x->dm_ntxpending++;#if defined(CONFIG_DM9X_STATS) dm9x->dm_ntxpackets++; dm9x->dm_ntxbytes += dm9x->dm_dev.d_len;#endif /* Disable all DM90x0 interrupts */ putreg(DM9X_IMR, DM9X_IMRDISABLE); /* Set the TX length */ putreg(DM9X_TXPLL, (dm9x->dm_dev.d_len & 0xff)); putreg(DM9X_TXPLH, (dm9x->dm_dev.d_len >> 8) & 0xff); /* Move the data to be sent into TX SRAM */ DM9X_INDEX = DM9X_MWCMD; dm9x->dm_write(dm9x->dm_dev.d_buf, dm9x->dm_dev.d_len);#if !defined(CONFIG_DM9X_ETRANS) /* Issue TX polling command */ putreg(DM9X_TXC, 0x1); /* Cleared after TX complete*/#endif /* Clear count of back-to-back RX packet transfers */ dm9x->ncrxpackets = 0; /* Re-enable DM90x0 interrupts */ putreg(DM9X_IMR, DM9X_IMRENABLE); /* Setup the TX timeout watchdog (perhaps restarting the timer) */ (void)wd_start(dm9x->dm_txtimeout, DM6X_TXTIMEOUT, dm9x_txtimeout, 1, (uint32)dm9x); return OK; } return -EBUSY;}/**************************************************************************** * Function: dm9x_uiptxpoll * * Description: * The transmitter is available, check if uIP has any outgoing packets ready * to send. This is a callback from uip_poll(). uip_poll() may be called: * * 1. When the preceding TX packet send is complete, * 2. When the preceding TX packet send timesout and the DM90x0 is reset * 3. During normal TX polling * * Parameters: * dev - Reference to the NuttX driver state structure * * Returned Value: * OK on success; a negated errno on failure * * Assumptions: * ****************************************************************************/static int dm9x_uiptxpoll(struct uip_driver_s *dev){ struct dm9x_driver_s *dm9x = (struct dm9x_driver_s *)dev->d_private; /* If the polling resulted in data that should be sent out on the network, * the field d_len is set to a value > 0. */ if (dm9x->dm_dev.d_len > 0) { uip_arp_out(&dm9x->dm_dev); dm9x_transmit(dm9x); /* Check if there is room in the DM90x0 to hold another packet. In 100M mode, * that can be 2 packets, otherwise it is a single packet. */ if (dm9x->dm_ntxpending > 1 || !dm9x->dm_b100M) { /* Returning a non-zero value will terminate the poll operation */ return 1; } } /* If zero is returned, the polling will continue until all connections have * been examined. */ return 0;}/**************************************************************************** * Function: dm9x_receive *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -