/****************************************************************************************** * FILE PURPOSE: Mac sliver driver ****************************************************************************************** * FILE NAME: gmacsl.c * * DESCRIPTION: The cpgmac sliver driver ******************************************************************************************/ #include "types.h" #include "platform.h" #include "cpmacdrv.h" #include "gmacsl_loc.h" #include "gmacsl_api.h" #include "target.h" /******************************************************************************************** * FUNCTION PURPOSE: Reset the the gmac sliver ******************************************************************************************** * DESCRIPTION: Soft reset is set and polled until clear, or until a timeout occurs ********************************************************************************************/ int16_t hwGmacSlReset (uint16_t port) { uint32_t i; uint32_t v; if (port >= DEVICE_N_GMACSL_PORTS) return (GMACSL_RET_INVALID_PORT); /* Set the soft reset bit */ DEVICE_REG32_W (DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RESET, CPGMAC_REG_RESET_VAL_RESET); /* Wait for the bit to clear */ for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) { v = DEVICE_REG32_R (DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RESET); if ( (v & CPGMAC_REG_RESET_VAL_RESET_MASK) != CPGMAC_REG_RESET_VAL_RESET) return (GMACSL_RET_OK); } /* Timeout on the reset */ return (GMACSL_RET_WARN_RESET_INCOMPLETE); } /* hwGmacSlReset */ /******************************************************************************************* * FUNCTION PURPOSE: Configure the gmac sliver ******************************************************************************************* * DESCRIPTION: The emac sliver is configured. *******************************************************************************************/ int16_t hwGmacSlConfig (uint16_t port, hwGmacSlCfg_t *cfg) { uint32_t v; uint32_t i; int16_t ret = GMACSL_RET_OK; if (port >= DEVICE_N_GMACSL_PORTS) return (GMACSL_RET_INVALID_PORT); if (cfg->maxRxLen > CPGMAC_REG_MAXLEN_LEN) { cfg->maxRxLen = CPGMAC_REG_MAXLEN_LEN; ret = GMACSL_RET_WARN_MAXLEN_TOO_BIG; } /* Must wait if the device is undergoing reset */ for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) { v = DEVICE_REG32_R (DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RESET); if ( (v & CPGMAC_REG_RESET_VAL_RESET_MASK) != CPGMAC_REG_RESET_VAL_RESET) break; } if (i == DEVICE_EMACSL_RESET_POLL_COUNT) return (GMACSL_RET_CONFIG_FAIL_RESET_ACTIVE); DEVICE_REG32_W(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_MAXLEN, cfg->maxRxLen); DEVICE_REG32_W(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_CTL, cfg->ctl); return (ret); } /* hwGmacSlConfig */ int32_t cpmac_drv_start (NET_DRV_DEVICE* ptr_device) { int32_t i; hwGmacSlCfg_t cfg; cfg.maxRxLen = MAX_SIZE_STREAM_BUFFER; cfg.ctl = GMACSL_ENABLE | GMACSL_RX_ENABLE_EXT_CTL; if (ptr_device->port_num == (uint32_t)(-2)) { for (i = 0; i < TARGET_EMAC_N_PORTS; i++) { hwGmacSlReset (i); hwGmacSlConfig (i, &cfg); } } else { hwGmacSlReset (ptr_device->port_num); hwGmacSlConfig (ptr_device->port_num, &cfg); } return (0); } int32_t cpmac_drv_send (NET_DRV_DEVICE* ptr_device, uint8_t* buffer, int num_bytes) { return (targetMacSend ((void *)ptr_device, buffer, num_bytes)); } int32_t cpmac_drv_receive (NET_DRV_DEVICE* ptr_device, uint8_t* buffer) { return (targetMacRcv ((void *)ptr_device, buffer)); } int32_t cpmac_drv_stop (NET_DRV_DEVICE* ptr_device) { hwGmacSlReset (ptr_device->port_num); return (0); }