Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of libMiMic by
fsl_enet_driver.c
00001 /* 00002 * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without modification, 00006 * are permitted provided that the following conditions are met: 00007 * 00008 * o Redistributions of source code must retain the above copyright notice, this list 00009 * of conditions and the following disclaimer. 00010 * 00011 * o Redistributions in binary form must reproduce the above copyright notice, this 00012 * list of conditions and the following disclaimer in the documentation and/or 00013 * other materials provided with the distribution. 00014 * 00015 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its 00016 * contributors may be used to endorse or promote products derived from this 00017 * software without specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 00023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 00026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 */ 00030 00031 /* Modified by mbed for the lwIP port */ 00032 #include "NyLPC_config.h" 00033 #if NyLPC_MCU==NyLPC_MCU_K64F 00034 #include "fsl_enet_driver.h" 00035 #include "fsl_enet_hal.h" 00036 #include "fsl_clock_manager.h" 00037 #include "fsl_interrupt_manager.h" 00038 #include <string.h> 00039 00040 //#include "sys_arch.h" 00041 00042 /******************************************************************************* 00043 * Variables 00044 ******************************************************************************/ 00045 /*! @brief Define ENET's IRQ list */ 00046 00047 void *enetIfHandle; 00048 00049 /*! @brief Define MAC driver API structure and for application of stack adaptor layer*/ 00050 const enet_mac_api_t g_enetMacApi = 00051 { 00052 enet_mac_init, 00053 NULL, // enet_mac_deinit, 00054 NULL, // enet_mac_send, 00055 #if !ENET_RECEIVE_ALL_INTERRUPT 00056 NULL, // enet_mac_receive, 00057 #endif 00058 enet_mii_read, 00059 enet_mii_write, 00060 NULL, // enet_mac_add_multicast_group, 00061 NULL, //enet_mac_leave_multicast_group, 00062 }; 00063 /******************************************************************************* 00064 * Code 00065 ******************************************************************************/ 00066 00067 // NOTE: we need these functions to be non-blocking fpr the PHY task, hence the 00068 // osDelay() below 00069 00070 /*FUNCTION**************************************************************** 00071 * 00072 * Function Name: enet_mii_read 00073 * Return Value: The execution status. 00074 * Description: Read function. 00075 * This interface read data over the (R)MII bus from the specified PHY register, 00076 * This function is called by all PHY interfaces. 00077 *END*********************************************************************/ 00078 uint32_t enet_mii_read(uint32_t instance, uint32_t phyAddr, uint32_t phyReg, uint32_t *dataPtr) 00079 { 00080 uint32_t counter; 00081 00082 /* Check the input parameters*/ 00083 if (!dataPtr) 00084 { 00085 return kStatus_ENET_InvalidInput; 00086 } 00087 00088 /* Check if the mii is enabled*/ 00089 if (!enet_hal_is_mii_enabled(instance)) 00090 { 00091 return kStatus_ENET_Miiuninitialized; 00092 } 00093 00094 /* Clear the MII interrupt event*/ 00095 enet_hal_clear_interrupt(instance, kEnetMiiInterrupt); 00096 00097 /* Read command operation*/ 00098 enet_hal_set_mii_command(instance, phyAddr, phyReg, kEnetReadValidFrame, 0); 00099 00100 /* Poll for MII complete*/ 00101 for (counter = 0; counter < kEnetMaxTimeout; counter++) 00102 { 00103 if (enet_hal_get_interrupt_status(instance, kEnetMiiInterrupt)) 00104 { 00105 break; 00106 } 00107 osDelay(1); 00108 } 00109 00110 /* Check for timeout*/ 00111 if (counter == kEnetMaxTimeout) 00112 { 00113 return kStatus_ENET_TimeOut; 00114 } 00115 00116 /* Get data from mii register*/ 00117 *dataPtr = enet_hal_get_mii_data(instance); 00118 00119 /* Clear MII interrupt event*/ 00120 enet_hal_clear_interrupt(instance, kEnetMiiInterrupt); 00121 00122 return kStatus_ENET_Success; 00123 } 00124 00125 /*FUNCTION**************************************************************** 00126 * 00127 * Function Name: enet_mii_write 00128 * Return Value: The execution status. 00129 * Description: Write function. 00130 * This interface write data over the (R)MII bus to the specified PHY register. 00131 * This function is called by all PHY interfaces. 00132 *END*********************************************************************/ 00133 uint32_t enet_mii_write(uint32_t instance, uint32_t phyAddr, uint32_t phyReg, uint32_t data) 00134 { 00135 uint32_t counter; 00136 00137 /* Check if the mii is enabled*/ 00138 if (!enet_hal_is_mii_enabled(instance)) 00139 { 00140 return kStatus_ENET_Miiuninitialized; 00141 } 00142 00143 /* Clear the MII interrupt event*/ 00144 enet_hal_clear_interrupt(instance, kEnetMiiInterrupt); 00145 00146 /* Read command operation*/ 00147 enet_hal_set_mii_command(instance, phyAddr, phyReg, kEnetWriteValidFrame, data); 00148 00149 /* Poll for MII complete*/ 00150 for (counter = 0; counter < kEnetMaxTimeout; counter++) 00151 { 00152 if (enet_hal_get_interrupt_status(instance, kEnetMiiInterrupt)) 00153 { 00154 break; 00155 } 00156 osDelay(1); 00157 } 00158 00159 /* Check for timeout*/ 00160 if (counter == kEnetMaxTimeout) 00161 { 00162 return kStatus_ENET_TimeOut; 00163 } 00164 00165 /* Clear MII intrrupt event*/ 00166 enet_hal_clear_interrupt(instance, kEnetMiiInterrupt); 00167 00168 return kStatus_ENET_Success; 00169 } 00170 /*FUNCTION**************************************************************** 00171 * 00172 * Function Name: enet_mac_mii_init 00173 * Return Value: The execution status. 00174 * Description:Initialize the ENET Mac mii(mdc/mdio)interface. 00175 *END*********************************************************************/ 00176 uint32_t enet_mac_mii_init(enet_dev_if_t * enetIfPtr) 00177 { 00178 uint32_t frequency; 00179 00180 /* Check the input parameters*/ 00181 if (enetIfPtr == NULL) 00182 { 00183 return kStatus_ENET_InvalidInput; 00184 } 00185 00186 /* Configure mii speed*/ 00187 clock_manager_get_frequency(kSystemClock, &frequency); 00188 enet_hal_config_mii(enetIfPtr->deviceNumber, (frequency/(2 * enetIfPtr->macCfgPtr->miiClock) + 1), 00189 kEnetMdioHoldOneClkCycle, false); 00190 00191 return kStatus_ENET_Success; 00192 } 00193 00194 /*FUNCTION**************************************************************** 00195 * 00196 * Function Name: enet_mac_rxbd_init 00197 * Return Value: The execution status. 00198 * Description:Initialize the ENET receive buffer descriptors. 00199 * Note: If you do receive on receive interrupt handler the receive 00200 * data buffer number can be the same as the receive descriptor numbers. 00201 * But if you are polling receive frames please make sure the receive data 00202 * buffers are more than buffer descriptors to guarantee a good performance. 00203 *END*********************************************************************/ 00204 uint32_t enet_mac_rxbd_init(enet_dev_if_t * enetIfPtr, enet_rxbd_config_t *rxbdCfg) 00205 { 00206 /* Check the input parameters*/ 00207 if ((!enetIfPtr) || (!rxbdCfg)) 00208 { 00209 return kStatus_ENET_InvalidInput; 00210 } 00211 00212 enetIfPtr->macContextPtr->bufferdescSize = enet_hal_get_bd_size(); 00213 00214 /* Initialize the bd status*/ 00215 enetIfPtr->macContextPtr->isRxFull = false; 00216 00217 /* Initialize receive bd base address and current address*/ 00218 enetIfPtr->macContextPtr->rxBdBasePtr = rxbdCfg->rxBdPtrAlign; 00219 enetIfPtr->macContextPtr->rxBdCurPtr = enetIfPtr->macContextPtr->rxBdBasePtr; 00220 enetIfPtr->macContextPtr->rxBdDirtyPtr = enetIfPtr->macContextPtr->rxBdBasePtr; 00221 enet_hal_set_rxbd_address(enetIfPtr->deviceNumber, (uint32_t)(enetIfPtr->macContextPtr->rxBdBasePtr)); 00222 00223 return kStatus_ENET_Success; 00224 } 00225 00226 /*FUNCTION**************************************************************** 00227 * 00228 * Function Name: enet_mac_txbd_init 00229 * Return Value: The execution status. 00230 * Description:Initialize the ENET transmit buffer descriptors. 00231 * This function prepare all of the transmit buffer descriptors. 00232 *END*********************************************************************/ 00233 uint32_t enet_mac_txbd_init(enet_dev_if_t * enetIfPtr, enet_txbd_config_t *txbdCfg) 00234 { 00235 /* Check the input parameters*/ 00236 if ((!enetIfPtr) || (!txbdCfg)) 00237 { 00238 return kStatus_ENET_InvalidInput; 00239 } 00240 00241 /* Initialize the bd status*/ 00242 enetIfPtr->macContextPtr->isTxFull = false; 00243 00244 /* Initialize transmit bd base address and current address*/ 00245 enetIfPtr->macContextPtr->txBdBasePtr = txbdCfg->txBdPtrAlign; 00246 enetIfPtr->macContextPtr->txBdCurPtr = enetIfPtr->macContextPtr->txBdBasePtr; 00247 enetIfPtr->macContextPtr->txBdDirtyPtr = enetIfPtr->macContextPtr->txBdBasePtr; 00248 enet_hal_set_txbd_address(enetIfPtr->deviceNumber, (uint32_t)(enetIfPtr->macContextPtr->txBdBasePtr)); 00249 return kStatus_ENET_Success; 00250 } 00251 00252 /*FUNCTION**************************************************************** 00253 * 00254 * Function Name: enet_mac_configure_fifo_accel 00255 * Return Value: The execution status. 00256 * Description: Configure the ENET FIFO and Accelerator. 00257 *END*********************************************************************/ 00258 uint32_t enet_mac_configure_fifo_accel(enet_dev_if_t * enetIfPtr) 00259 { 00260 enet_config_rx_fifo_t rxFifo; 00261 enet_config_tx_fifo_t txFifo; 00262 00263 /* Check the input parameters*/ 00264 if (!enetIfPtr) 00265 { 00266 return kStatus_ENET_InvalidInput; 00267 } 00268 00269 /* Initialize values that will not be initialized later on */ 00270 rxFifo.rxEmpty = 0; 00271 rxFifo.rxFull = 0; 00272 txFifo.isStoreForwardEnabled = 0; 00273 txFifo.txFifoWrite = 0; 00274 txFifo.txEmpty = 0; 00275 00276 /* Configure tx/rx accelerator*/ 00277 if (enetIfPtr->macCfgPtr->isRxAccelEnabled) 00278 { 00279 enet_hal_config_rx_accelerator(enetIfPtr->deviceNumber, 00280 (enet_config_rx_accelerator_t *)&(enetIfPtr->macCfgPtr->rxAcceler)); 00281 if ((enetIfPtr->macCfgPtr->rxAcceler.isIpcheckEnabled) || (enetIfPtr->macCfgPtr->rxAcceler.isProtocolCheckEnabled)) 00282 { 00283 rxFifo.rxFull = 0; 00284 } 00285 } 00286 if (enetIfPtr->macCfgPtr->isTxAccelEnabled) 00287 { 00288 enet_hal_config_tx_accelerator(enetIfPtr->deviceNumber, 00289 (enet_config_tx_accelerator_t *)&(enetIfPtr->macCfgPtr->txAcceler)); 00290 if ((enetIfPtr->macCfgPtr->txAcceler.isIpCheckEnabled) || (enetIfPtr->macCfgPtr->txAcceler.isProtocolCheckEnabled)) 00291 { 00292 txFifo.isStoreForwardEnabled = 1; 00293 } 00294 } 00295 if (enetIfPtr->macCfgPtr->isStoreAndFwEnabled) 00296 { 00297 rxFifo.rxFull = 0; 00298 txFifo.isStoreForwardEnabled = 1; 00299 } 00300 00301 00302 /* Set TFWR value if STRFWD is not being used */ 00303 if (txFifo.isStoreForwardEnabled == 1) 00304 txFifo.txFifoWrite = 0; 00305 else 00306 /* TFWR value is a trade-off between transmit latency and risk of transmit FIFO underrun due to contention for the system bus 00307 TFWR = 15 means transmission will begin once 960 bytes has been written to the Tx FIFO (for frames larger than 960 bytes) 00308 See Section 45.4.18 - Transmit FIFO Watermark Register of the K64F Reference Manual for details */ 00309 txFifo.txFifoWrite = 15; 00310 00311 /* Configure tx/rx FIFO with default value*/ 00312 rxFifo.rxAlmostEmpty = 4; 00313 rxFifo.rxAlmostFull = 4; 00314 txFifo.txAlmostEmpty = 4; 00315 txFifo.txAlmostFull = 8; 00316 enet_hal_config_rx_fifo(enetIfPtr->deviceNumber, &rxFifo); 00317 enet_hal_config_tx_fifo(enetIfPtr->deviceNumber, &txFifo); 00318 00319 return kStatus_ENET_Success; 00320 } 00321 00322 /*FUNCTION**************************************************************** 00323 * 00324 * Function Name: enet_mac_configure_controller 00325 * Return Value: The execution status. 00326 * Description: Configure the ENET controller with the basic configuration. 00327 *END*********************************************************************/ 00328 uint32_t enet_mac_configure_controller(enet_dev_if_t * enetIfPtr) 00329 { 00330 uint32_t macCtlCfg; 00331 00332 /* Check the input parameters*/ 00333 if (enetIfPtr == NULL) 00334 { 00335 return kStatus_ENET_InvalidInput; 00336 } 00337 00338 macCtlCfg = enetIfPtr->macCfgPtr->macCtlConfigure; 00339 /* Configure rmii/mii interface*/ 00340 enet_hal_config_rmii(enetIfPtr->deviceNumber, enetIfPtr->macCfgPtr->rmiiCfgMode, 00341 enetIfPtr->macCfgPtr->speed, enetIfPtr->macCfgPtr->duplex, false, 00342 (macCtlCfg & kEnetRxMiiLoopback)); 00343 /* Configure receive buffer size*/ 00344 if (enetIfPtr->macCfgPtr->isVlanEnabled) 00345 { 00346 enetIfPtr->maxFrameSize = kEnetMaxFrameVlanSize; 00347 enet_hal_set_rx_max_size(enetIfPtr->deviceNumber, 00348 enetIfPtr->macContextPtr->rxBufferSizeAligned, kEnetMaxFrameVlanSize); 00349 } 00350 else 00351 { 00352 enetIfPtr->maxFrameSize = kEnetMaxFrameSize; 00353 enet_hal_set_rx_max_size(enetIfPtr->deviceNumber, 00354 enetIfPtr->macContextPtr->rxBufferSizeAligned, kEnetMaxFrameSize); 00355 } 00356 00357 /* Set receive controller promiscuous */ 00358 enet_hal_config_promiscuous(enetIfPtr->deviceNumber, macCtlCfg & kEnetRxPromiscuousEnable); 00359 /* Set receive flow control*/ 00360 enet_hal_enable_flowcontrol(enetIfPtr->deviceNumber, (macCtlCfg & kEnetRxFlowControlEnable)); 00361 /* Set received PAUSE frames are forwarded/terminated*/ 00362 enet_hal_enable_pauseforward(enetIfPtr->deviceNumber, (macCtlCfg & kEnetRxPauseFwdEnable)); 00363 /* Set receive broadcast frame reject*/ 00364 enet_hal_enable_broadcastreject(enetIfPtr->deviceNumber, (macCtlCfg & kEnetRxBcRejectEnable)); 00365 /* Set padding is removed from the received frame*/ 00366 enet_hal_enable_padremove(enetIfPtr->deviceNumber, (macCtlCfg & kEnetRxPadRemoveEnable)); 00367 /* Set the crc of the received frame is stripped from the frame*/ 00368 enet_hal_enable_rxcrcforward(enetIfPtr->deviceNumber, (macCtlCfg & kEnetRxCrcFwdEnable)); 00369 /* Set receive payload length check*/ 00370 enet_hal_enable_payloadcheck(enetIfPtr->deviceNumber, (macCtlCfg & kEnetPayloadlenCheckEnable)); 00371 /* Set control sleep mode*/ 00372 enet_hal_enable_sleep(enetIfPtr->deviceNumber, (macCtlCfg & kEnetSleepModeEnable)); 00373 return kStatus_ENET_Success; 00374 } 00375 00376 /*FUNCTION**************************************************************** 00377 * 00378 * Function Name: enet_mac_init 00379 * Return Value: The execution status. 00380 * Description:Initialize the ENET device with the basic configuration 00381 * When ENET is used, this function need to be called by the NET initialize 00382 * interface. 00383 *END*********************************************************************/ 00384 uint32_t enet_mac_init(enet_dev_if_t * enetIfPtr, enet_rxbd_config_t *rxbdCfg, 00385 enet_txbd_config_t *txbdCfg) 00386 { 00387 uint32_t timeOut = 0; 00388 uint32_t devNumber, result = 0; 00389 00390 /* Check the input parameters*/ 00391 if (enetIfPtr == NULL) 00392 { 00393 return kStatus_ENET_InvalidInput; 00394 } 00395 00396 /* Get device number and check the parameter*/ 00397 devNumber = enetIfPtr->deviceNumber; 00398 00399 /* Store the global ENET structure for ISR input parameters for instance 0*/ 00400 if (!devNumber) 00401 { 00402 enetIfHandle = enetIfPtr; 00403 } 00404 00405 /* Turn on ENET module clock gate */ 00406 clock_manager_set_gate(kClockModuleENET, 0U, true); 00407 00408 /* Reset ENET mac*/ 00409 enet_hal_reset_ethernet(devNumber); 00410 while ((!enet_hal_is_reset_completed(devNumber)) && (timeOut < kEnetMaxTimeout)) 00411 { 00412 time_delay(1); 00413 timeOut++; 00414 } 00415 00416 /* Check out if timeout*/ 00417 if (timeOut == kEnetMaxTimeout) 00418 { 00419 return kStatus_ENET_TimeOut; 00420 } 00421 00422 /* Disable all ENET mac interrupt and Clear all interrupt events*/ 00423 enet_hal_config_interrupt(devNumber, kEnetAllInterrupt, false); 00424 enet_hal_clear_interrupt(devNumber, kEnetAllInterrupt); 00425 00426 /* Program this station's physical address*/ 00427 enet_hal_set_mac_address(devNumber, enetIfPtr->macCfgPtr->macAddr); 00428 00429 /* Clear group and individual hash register*/ 00430 enet_hal_set_group_hashtable(devNumber, 0, kEnetSpecialAddressInit); 00431 enet_hal_set_individual_hashtable(devNumber, 0, kEnetSpecialAddressInit); 00432 00433 /* Configure mac controller*/ 00434 result = enet_mac_configure_controller(enetIfPtr); 00435 if(result != kStatus_ENET_Success) 00436 { 00437 return result; 00438 } 00439 /* Clear mib zero counters*/ 00440 enet_hal_clear_mib(devNumber, true); 00441 00442 /* Initialize FIFO and accelerator*/ 00443 result = enet_mac_configure_fifo_accel(enetIfPtr); 00444 if(result != kStatus_ENET_Success) 00445 { 00446 return result; 00447 } 00448 /* Initialize receive buffer descriptors*/ 00449 result = enet_mac_rxbd_init(enetIfPtr, rxbdCfg); 00450 if(result != kStatus_ENET_Success) 00451 { 00452 return result; 00453 } 00454 /* Initialize transmit buffer descriptors*/ 00455 result = enet_mac_txbd_init(enetIfPtr, txbdCfg); 00456 if(result != kStatus_ENET_Success) 00457 { 00458 return result; 00459 } 00460 /* Initialize rmii/mii interface*/ 00461 result = enet_mac_mii_init(enetIfPtr); 00462 if (result != kStatus_ENET_Success) 00463 { 00464 return result; 00465 } 00466 00467 return kStatus_ENET_Success; 00468 } 00469 00470 /******************************************************************************* 00471 * EOF 00472 ******************************************************************************/ 00473 00474 #endif 00475
Generated on Tue Jul 12 2022 16:22:56 by
