This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088
Dependents: MbedFileServer_1768MiniDK2 RedWireBridge IssueDebug_gcc MiMicRemoteMCU-for-Mbed ... more
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 15:46:14 by 1.7.2