fsl_enet.c 125 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416
  1. /*
  2. * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
  3. * Copyright 2016-2017 NXP
  4. * All rights reserved.
  5. *
  6. * SPDX-License-Identifier: BSD-3-Clause
  7. */
  8. #include "fsl_enet.h"
  9. #if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
  10. #include "fsl_cache.h"
  11. #endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
  12. /*******************************************************************************
  13. * Definitions
  14. ******************************************************************************/
  15. /* Component ID definition, used by tools. */
  16. #ifndef FSL_COMPONENT_ID
  17. #define FSL_COMPONENT_ID "platform.drivers.enet"
  18. #endif
  19. /*! @brief IPv4 PTP message IP version offset. */
  20. #define ENET_PTP1588_IPVERSION_OFFSET 0x0EU
  21. /*! @brief IPv4 PTP message UDP protocol offset. */
  22. #define ENET_PTP1588_IPV4_UDP_PROTOCOL_OFFSET 0x17U
  23. /*! @brief IPv4 PTP message UDP port offset. */
  24. #define ENET_PTP1588_IPV4_UDP_PORT_OFFSET 0x24U
  25. /*! @brief IPv4 PTP message UDP message type offset. */
  26. #define ENET_PTP1588_IPV4_UDP_MSGTYPE_OFFSET 0x2AU
  27. /*! @brief IPv4 PTP message UDP version offset. */
  28. #define ENET_PTP1588_IPV4_UDP_VERSION_OFFSET 0x2BU
  29. /*! @brief IPv4 PTP message UDP clock id offset. */
  30. #define ENET_PTP1588_IPV4_UDP_CLKID_OFFSET 0x3EU
  31. /*! @brief IPv4 PTP message UDP sequence id offset. */
  32. #define ENET_PTP1588_IPV4_UDP_SEQUENCEID_OFFSET 0x48U
  33. /*! @brief IPv4 PTP message UDP control offset. */
  34. #define ENET_PTP1588_IPV4_UDP_CTL_OFFSET 0x4AU
  35. /*! @brief IPv6 PTP message UDP protocol offset. */
  36. #define ENET_PTP1588_IPV6_UDP_PROTOCOL_OFFSET 0x14U
  37. /*! @brief IPv6 PTP message UDP port offset. */
  38. #define ENET_PTP1588_IPV6_UDP_PORT_OFFSET 0x38U
  39. /*! @brief IPv6 PTP message UDP message type offset. */
  40. #define ENET_PTP1588_IPV6_UDP_MSGTYPE_OFFSET 0x3EU
  41. /*! @brief IPv6 PTP message UDP version offset. */
  42. #define ENET_PTP1588_IPV6_UDP_VERSION_OFFSET 0x3FU
  43. /*! @brief IPv6 PTP message UDP clock id offset. */
  44. #define ENET_PTP1588_IPV6_UDP_CLKID_OFFSET 0x52U
  45. /*! @brief IPv6 PTP message UDP sequence id offset. */
  46. #define ENET_PTP1588_IPV6_UDP_SEQUENCEID_OFFSET 0x5CU
  47. /*! @brief IPv6 PTP message UDP control offset. */
  48. #define ENET_PTP1588_IPV6_UDP_CTL_OFFSET 0x5EU
  49. /*! @brief PTPv2 message Ethernet packet type offset. */
  50. #define ENET_PTP1588_ETHL2_PACKETTYPE_OFFSET 0x0CU
  51. /*! @brief PTPv2 message Ethernet message type offset. */
  52. #define ENET_PTP1588_ETHL2_MSGTYPE_OFFSET 0x0EU
  53. /*! @brief PTPv2 message Ethernet version type offset. */
  54. #define ENET_PTP1588_ETHL2_VERSION_OFFSET 0X0FU
  55. /*! @brief PTPv2 message Ethernet clock id offset. */
  56. #define ENET_PTP1588_ETHL2_CLOCKID_OFFSET 0x22
  57. /*! @brief PTPv2 message Ethernet sequence id offset. */
  58. #define ENET_PTP1588_ETHL2_SEQUENCEID_OFFSET 0x2c
  59. /*! @brief Packet type Ethernet IEEE802.3 for PTPv2. */
  60. #define ENET_ETHERNETL2 0x88F7U
  61. /*! @brief Packet type IPv4. */
  62. #define ENET_IPV4 0x0800U
  63. /*! @brief Packet type IPv6. */
  64. #define ENET_IPV6 0x86ddU
  65. /*! @brief Packet type VLAN. */
  66. #define ENET_8021QVLAN 0x8100U
  67. /*! @brief UDP protocol type. */
  68. #define ENET_UDPVERSION 0x0011U
  69. /*! @brief Packet IP version IPv4. */
  70. #define ENET_IPV4VERSION 0x0004U
  71. /*! @brief Packet IP version IPv6. */
  72. #define ENET_IPV6VERSION 0x0006U
  73. /*! @brief Ethernet mac address length. */
  74. #define ENET_FRAME_MACLEN 6U
  75. /*! @brief Ethernet VLAN header length. */
  76. #define ENET_FRAME_VLAN_TAGLEN 4U
  77. /*! @brief MDC frequency. */
  78. #define ENET_MDC_FREQUENCY 2500000U
  79. /*! @brief NanoSecond in one second. */
  80. #define ENET_NANOSECOND_ONE_SECOND 1000000000U
  81. /*! @brief Define a common clock cycle delays used for time stamp capture. */
  82. #ifndef ENET_1588TIME_DELAY_COUNT
  83. #define ENET_1588TIME_DELAY_COUNT 10U
  84. #endif
  85. /*! @brief Defines the macro for converting constants from host byte order to network byte order. */
  86. #define ENET_HTONS(n) __REV16(n)
  87. #define ENET_HTONL(n) __REV(n)
  88. #define ENET_NTOHS(n) __REV16(n)
  89. #define ENET_NTOHL(n) __REV(n)
  90. /*! @brief Define the ENET ring/class bumber . */
  91. enum _enet_ring_number
  92. {
  93. kENET_Ring0 = 0U, /*!< ENET ring/class 0. */
  94. #if FSL_FEATURE_ENET_QUEUE > 1
  95. kENET_Ring1 = 1U, /*!< ENET ring/class 1. */
  96. kENET_Ring2 = 2U /*!< ENET ring/class 2. */
  97. #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
  98. };
  99. /*! @brief Define interrupt IRQ handler. */
  100. #if FSL_FEATURE_ENET_QUEUE > 1
  101. typedef void (*enet_isr_ring_t)(ENET_Type *base, enet_handle_t *handle, uint32_t ringId);
  102. #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
  103. typedef void (*enet_isr_t)(ENET_Type *base, enet_handle_t *handle);
  104. /*******************************************************************************
  105. * Prototypes
  106. ******************************************************************************/
  107. /*!
  108. * @brief Get the ENET instance from peripheral base address.
  109. *
  110. * @param base ENET peripheral base address.
  111. * @return ENET instance.
  112. */
  113. uint32_t ENET_GetInstance(ENET_Type *base);
  114. /*!
  115. * @brief Set ENET MAC controller with the configuration.
  116. *
  117. * @param base ENET peripheral base address.
  118. * @param handle The ENET handle pointer.
  119. * @param config ENET Mac configuration.
  120. * @param bufferConfig ENET buffer configuration.
  121. * @param macAddr ENET six-byte mac address.
  122. * @param srcClock_Hz ENET module clock source, normally it's system clock.
  123. */
  124. static void ENET_SetMacController(ENET_Type *base,
  125. enet_handle_t *handle,
  126. const enet_config_t *config,
  127. const enet_buffer_config_t *bufferConfig,
  128. uint8_t *macAddr,
  129. uint32_t srcClock_Hz);
  130. /*!
  131. * @brief Set ENET handler.
  132. *
  133. * @param base ENET peripheral base address.
  134. * @param handle The ENET handle pointer.
  135. * @param config ENET configuration stucture pointer.
  136. * @param bufferConfig ENET buffer configuration.
  137. */
  138. static void ENET_SetHandler(ENET_Type *base,
  139. enet_handle_t *handle,
  140. const enet_config_t *config,
  141. const enet_buffer_config_t *bufferConfig);
  142. /*!
  143. * @brief Set ENET MAC transmit buffer descriptors.
  144. *
  145. * @param handle The ENET handle pointer.
  146. * @param config The ENET configuration structure.
  147. * @param bufferConfig The ENET buffer configuration.
  148. */
  149. static void ENET_SetTxBufferDescriptors(enet_handle_t *handle,
  150. const enet_config_t *config,
  151. const enet_buffer_config_t *bufferConfig);
  152. /*!
  153. * @brief Set ENET MAC receive buffer descriptors.
  154. *
  155. * @param handle The ENET handle pointer.
  156. * @param config The ENET configuration structure.
  157. * @param bufferConfig The ENET buffer configuration.
  158. */
  159. static void ENET_SetRxBufferDescriptors(enet_handle_t *handle,
  160. const enet_config_t *config,
  161. const enet_buffer_config_t *bufferConfig);
  162. /*!
  163. * @brief Updates the ENET read buffer descriptors.
  164. *
  165. * @param base ENET peripheral base address.
  166. * @param handle The ENET handle pointer.
  167. * @param ringId The descriptor ring index, range from 0 ~ FSL_FEATURE_ENET_QUEUE - 1.
  168. * 0 ----- for single ring kinetis platform.
  169. * 0 ~ 2 for mulit-ring supported IMX8qm.
  170. */
  171. static void ENET_UpdateReadBuffers(ENET_Type *base, enet_handle_t *handle, uint32_t ringId);
  172. /*!
  173. * @brief Activates ENET send for multiple tx rings.
  174. *
  175. * @param base ENET peripheral base address.
  176. * @param ringId The descriptor ring index, range from 0 ~ FSL_FEATURE_ENET_QUEUE - 1.
  177. * 0 ----- for single ring kinetis platform.
  178. * 0 ~ 2 for mulit-ring supported IMX8qm.
  179. *
  180. * @note This must be called after the MAC configuration and
  181. * state are ready. It must be called after the ENET_Init() and
  182. * this should be called when the ENET receive required.
  183. */
  184. static void ENET_ActiveSend(ENET_Type *base, uint32_t ringId);
  185. #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
  186. /*!
  187. * @brief Parses the ENET frame for time-stamp process of PTP 1588 frame.
  188. *
  189. * @param data The ENET read data for frame parse.
  190. * @param ptpTsData The ENET PTP message and time-stamp data pointer.
  191. * @param isFastEnabled The fast parse flag.
  192. * - true , Fast processing, only check if this is a PTP message.
  193. * - false, Store the PTP message data after check the PTP message.
  194. */
  195. static bool ENET_Ptp1588ParseFrame(const uint8_t *data, enet_ptp_time_data_t *ptpTsData, bool isFastEnabled);
  196. /*!
  197. * @brief Updates the new PTP 1588 time-stamp to the time-stamp buffer ring.
  198. *
  199. * @param ptpTsDataRing The PTP message and time-stamp data ring pointer.
  200. * @param ptpTimeData The new PTP 1588 time-stamp data pointer.
  201. */
  202. static status_t ENET_Ptp1588UpdateTimeRing(enet_ptp_time_data_ring_t *ptpTsDataRing, enet_ptp_time_data_t *ptpTimeData);
  203. /*!
  204. * @brief Search up the right PTP 1588 time-stamp from the time-stamp buffer ring.
  205. *
  206. * @param ptpTsDataRing The PTP message and time-stamp data ring pointer.
  207. * @param ptpTimeData The find out right PTP 1588 time-stamp data pointer with the specific PTP message.
  208. */
  209. static status_t ENET_Ptp1588SearchTimeRing(enet_ptp_time_data_ring_t *ptpTsDataRing, enet_ptp_time_data_t *ptpTimedata);
  210. /*!
  211. * @brief Store the transmit time-stamp for event PTP frame in the time-stamp buffer ring.
  212. *
  213. * @param base ENET peripheral base address.
  214. * @param handle The ENET handle pointer.
  215. * @param ringId The descriptor ring index, range from 0 ~ FSL_FEATURE_ENET_QUEUE - 1.
  216. * 0 ----- for single ring kinetis platform.
  217. * 0 ~ 2 for mulit-ring supported IMX8qm.
  218. */
  219. static status_t ENET_StoreTxFrameTime(ENET_Type *base, enet_handle_t *handle, uint32_t ringId);
  220. /*!
  221. * @brief Store the receive time-stamp for event PTP frame in the time-stamp buffer ring.
  222. *
  223. * @param base ENET peripheral base address.
  224. * @param handle The ENET handle pointer.
  225. * @param ptpTimeData The PTP 1588 time-stamp data pointer.
  226. */
  227. static status_t ENET_StoreRxFrameTime(ENET_Type *base, enet_handle_t *handle, enet_ptp_time_data_t *ptpTimeData);
  228. #if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_AVB
  229. /*!
  230. * @brief Gets the ring index for transmission.
  231. *
  232. * @param base ENET peripheral base address.
  233. * @param data The ENET transmit data.
  234. * @param handle The ENET handle pointer.
  235. *
  236. * @note This must be called after the MAC configuration and
  237. * state are ready. It must be called after the ENET_Init() and
  238. * this should be called when the ENET receive required.
  239. */
  240. static uint8_t ENET_GetTxRingId(ENET_Type *base, uint8_t *data, enet_handle_t *handle);
  241. #endif /* FSL_FEATURE_ENET_HAS_AVB */
  242. #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
  243. /*******************************************************************************
  244. * Variables
  245. ******************************************************************************/
  246. /*! @brief Pointers to enet handles for each instance. */
  247. static enet_handle_t *s_ENETHandle[FSL_FEATURE_SOC_ENET_COUNT] = {NULL};
  248. /*! @brief Pointers to enet clocks for each instance. */
  249. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  250. const clock_ip_name_t s_enetClock[] = ENET_CLOCKS;
  251. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  252. /*! @brief Pointers to enet transmit IRQ number for each instance. */
  253. static const IRQn_Type s_enetTxIrqId[] = ENET_Transmit_IRQS;
  254. /*! @brief Pointers to enet receive IRQ number for each instance. */
  255. static const IRQn_Type s_enetRxIrqId[] = ENET_Receive_IRQS;
  256. #if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
  257. /*! @brief Pointers to enet timestamp IRQ number for each instance. */
  258. static const IRQn_Type s_enetTsIrqId[] = ENET_1588_Timer_IRQS;
  259. #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
  260. /*! @brief Pointers to enet error IRQ number for each instance. */
  261. static const IRQn_Type s_enetErrIrqId[] = ENET_Error_IRQS;
  262. /*! @brief Pointers to enet bases for each instance. */
  263. static ENET_Type *const s_enetBases[] = ENET_BASE_PTRS;
  264. /* ENET ISR for transactional APIs. */
  265. #if FSL_FEATURE_ENET_QUEUE > 1
  266. static enet_isr_ring_t s_enetTxIsr;
  267. static enet_isr_ring_t s_enetRxIsr;
  268. #else
  269. static enet_isr_t s_enetTxIsr;
  270. static enet_isr_t s_enetRxIsr;
  271. #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
  272. static enet_isr_t s_enetErrIsr;
  273. static enet_isr_t s_enetTsIsr;
  274. /*******************************************************************************
  275. * Code
  276. ******************************************************************************/
  277. uint32_t ENET_GetInstance(ENET_Type *base)
  278. {
  279. uint32_t instance;
  280. /* Find the instance index from base address mappings. */
  281. for (instance = 0; instance < ARRAY_SIZE(s_enetBases); instance++)
  282. {
  283. if (s_enetBases[instance] == base)
  284. {
  285. break;
  286. }
  287. }
  288. assert(instance < ARRAY_SIZE(s_enetBases));
  289. return instance;
  290. }
  291. /*!
  292. * brief Gets the ENET default configuration structure.
  293. *
  294. * The purpose of this API is to get the default ENET MAC controller
  295. * configure structure for ENET_Init(). User may use the initialized
  296. * structure unchanged in ENET_Init(), or modify some fields of the
  297. * structure before calling ENET_Init().
  298. * Example:
  299. code
  300. enet_config_t config;
  301. ENET_GetDefaultConfig(&config);
  302. endcode
  303. * param config The ENET mac controller configuration structure pointer.
  304. */
  305. void ENET_GetDefaultConfig(enet_config_t *config)
  306. {
  307. /* Checks input parameter. */
  308. assert(config);
  309. /* Initializes the MAC configure structure to zero. */
  310. memset(config, 0, sizeof(enet_config_t));
  311. /* Sets MII mode, full duplex, 100Mbps for MAC and PHY data interface. */
  312. #if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB
  313. config->miiMode = kENET_RgmiiMode;
  314. #else
  315. config->miiMode = kENET_RmiiMode;
  316. #endif
  317. config->miiSpeed = kENET_MiiSpeed100M;
  318. config->miiDuplex = kENET_MiiFullDuplex;
  319. config->ringNum = 1;
  320. /* Sets the maximum receive frame length. */
  321. config->rxMaxFrameLen = ENET_FRAME_MAX_FRAMELEN;
  322. }
  323. /*!
  324. * brief Initializes the ENET module.
  325. *
  326. * This function ungates the module clock and initializes it with the ENET configuration.
  327. *
  328. * param base ENET peripheral base address.
  329. * param handle ENET handler pointer.
  330. * param config ENET mac configuration structure pointer.
  331. * The "enet_config_t" type mac configuration return from ENET_GetDefaultConfig
  332. * can be used directly. It is also possible to verify the Mac configuration using other methods.
  333. * param bufferConfig ENET buffer configuration structure pointer.
  334. * The buffer configuration should be prepared for ENET Initialization.
  335. * It is the start address of "ringNum" enet_buffer_config structures.
  336. * To support added multi-ring features in some soc and compatible with the previous
  337. * enet driver version. For single ring supported, this bufferConfig is a buffer
  338. * configure structure pointer, for multi-ring supported and used case, this bufferConfig
  339. * pointer should be a buffer configure structure array pointer.
  340. * param macAddr ENET mac address of Ethernet device. This MAC address should be
  341. * provided.
  342. * param srcClock_Hz The internal module clock source for MII clock.
  343. *
  344. * note ENET has two buffer descriptors legacy buffer descriptors and
  345. * enhanced IEEE 1588 buffer descriptors. The legacy descriptor is used by default. To
  346. * use the IEEE 1588 feature, use the enhanced IEEE 1588 buffer descriptor
  347. * by defining "ENET_ENHANCEDBUFFERDESCRIPTOR_MODE" and calling ENET_Ptp1588Configure()
  348. * to configure the 1588 feature and related buffers after calling ENET_Init().
  349. */
  350. void ENET_Init(ENET_Type *base,
  351. enet_handle_t *handle,
  352. const enet_config_t *config,
  353. const enet_buffer_config_t *bufferConfig,
  354. uint8_t *macAddr,
  355. uint32_t srcClock_Hz)
  356. {
  357. /* Checks input parameters. */
  358. assert(handle);
  359. assert(config);
  360. assert(bufferConfig);
  361. assert(macAddr);
  362. assert(config->ringNum <= FSL_FEATURE_ENET_QUEUE);
  363. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  364. uint32_t instance = ENET_GetInstance(base);
  365. /* Ungate ENET clock. */
  366. CLOCK_EnableClock(s_enetClock[instance]);
  367. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  368. /* Reset ENET module. */
  369. ENET_Reset(base);
  370. /* Initializes the ENET transmit buffer descriptors. */
  371. ENET_SetTxBufferDescriptors(handle, config, bufferConfig);
  372. /* Initializes the ENET receive buffer descriptors. */
  373. ENET_SetRxBufferDescriptors(handle, config, bufferConfig);
  374. /* Initializes the ENET MAC controller with basic function. */
  375. ENET_SetMacController(base, handle, config, bufferConfig, macAddr, srcClock_Hz);
  376. /* Set all buffers or data in handler for data transmit/receive process. */
  377. ENET_SetHandler(base, handle, config, bufferConfig);
  378. }
  379. /*!
  380. * brief Deinitializes the ENET module.
  381. * This function gates the module clock, clears ENET interrupts, and disables the ENET module.
  382. *
  383. * param base ENET peripheral base address.
  384. */
  385. void ENET_Deinit(ENET_Type *base)
  386. {
  387. /* Disable interrupt. */
  388. base->EIMR = 0;
  389. /* Disable ENET. */
  390. base->ECR &= ~ENET_ECR_ETHEREN_MASK;
  391. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  392. /* Disables the clock source. */
  393. CLOCK_DisableClock(s_enetClock[ENET_GetInstance(base)]);
  394. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  395. }
  396. /*!
  397. * brief Sets the callback function.
  398. * This API is provided for the application callback required case when ENET
  399. * interrupt is enabled. This API should be called after calling ENET_Init.
  400. *
  401. * param handle ENET handler pointer. Should be provided by application.
  402. * param callback The ENET callback function.
  403. * param userData The callback function parameter.
  404. */
  405. void ENET_SetCallback(enet_handle_t *handle, enet_callback_t callback, void *userData)
  406. {
  407. assert(handle);
  408. /* Set callback and userData. */
  409. handle->callback = callback;
  410. handle->userData = userData;
  411. }
  412. static void ENET_SetHandler(ENET_Type *base,
  413. enet_handle_t *handle,
  414. const enet_config_t *config,
  415. const enet_buffer_config_t *bufferConfig)
  416. {
  417. uint8_t count;
  418. uint32_t instance = ENET_GetInstance(base);
  419. const enet_buffer_config_t *buffCfg = bufferConfig;
  420. /* Store transfer parameters in handle pointer. */
  421. memset(handle, 0, sizeof(enet_handle_t));
  422. handle->ringNum = (config->ringNum > FSL_FEATURE_ENET_QUEUE) ? FSL_FEATURE_ENET_QUEUE : config->ringNum;
  423. for (count = 0; count < handle->ringNum; count++)
  424. {
  425. assert(buffCfg->rxBuffSizeAlign * buffCfg->rxBdNumber > config->rxMaxFrameLen);
  426. handle->rxBdBase[count] = buffCfg->rxBdStartAddrAlign;
  427. handle->rxBdCurrent[count] = buffCfg->rxBdStartAddrAlign;
  428. handle->rxBuffSizeAlign[count] = buffCfg->rxBuffSizeAlign;
  429. handle->txBdBase[count] = buffCfg->txBdStartAddrAlign;
  430. handle->txBdCurrent[count] = buffCfg->txBdStartAddrAlign;
  431. handle->txBuffSizeAlign[count] = buffCfg->txBuffSizeAlign;
  432. buffCfg++;
  433. }
  434. /* Save the handle pointer in the global variables. */
  435. s_ENETHandle[instance] = handle;
  436. /* Set the IRQ handler when the interrupt is enabled. */
  437. if (config->interrupt & ENET_TX_INTERRUPT)
  438. {
  439. s_enetTxIsr = ENET_TransmitIRQHandler;
  440. EnableIRQ(s_enetTxIrqId[instance]);
  441. }
  442. if (config->interrupt & ENET_RX_INTERRUPT)
  443. {
  444. s_enetRxIsr = ENET_ReceiveIRQHandler;
  445. EnableIRQ(s_enetRxIrqId[instance]);
  446. }
  447. if (config->interrupt & ENET_ERR_INTERRUPT)
  448. {
  449. s_enetErrIsr = ENET_ErrorIRQHandler;
  450. EnableIRQ(s_enetErrIrqId[instance]);
  451. }
  452. }
  453. static void ENET_SetMacController(ENET_Type *base,
  454. enet_handle_t *handle,
  455. const enet_config_t *config,
  456. const enet_buffer_config_t *bufferConfig,
  457. uint8_t *macAddr,
  458. uint32_t srcClock_Hz)
  459. {
  460. #if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB
  461. /* Check the MII mode/speed/duplex setting. */
  462. if (config->miiSpeed == kENET_MiiSpeed1000M)
  463. {
  464. /* Only RGMII mode has the 1000M bit/s. The 1000M only support full duplex. */
  465. assert(config->miiMode == kENET_RgmiiMode);
  466. assert(config->miiDuplex == kENET_MiiFullDuplex);
  467. }
  468. #endif /* FSL_FEATURE_ENET_HAS_AVB */
  469. uint32_t rcr = 0;
  470. uint32_t tcr = 0;
  471. uint32_t ecr = base->ECR;
  472. uint32_t macSpecialConfig = config->macSpecialConfig;
  473. uint32_t maxFrameLen = config->rxMaxFrameLen;
  474. /* Maximum frame length check. */
  475. if ((macSpecialConfig & kENET_ControlVLANTagEnable) && (maxFrameLen <= ENET_FRAME_MAX_FRAMELEN))
  476. {
  477. maxFrameLen = (ENET_FRAME_MAX_FRAMELEN + ENET_FRAME_VLAN_TAGLEN);
  478. #if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB
  479. if (macSpecialConfig & kENET_ControlSVLANEnable)
  480. {
  481. /* Double vlan tag (SVLAN) supported. */
  482. maxFrameLen += ENET_FRAME_VLAN_TAGLEN;
  483. }
  484. ecr |= ((macSpecialConfig & kENET_ControlSVLANEnable) ? (ENET_ECR_SVLANEN_MASK | ENET_ECR_SVLANDBL_MASK) : 0) |
  485. ((macSpecialConfig & kENET_ControlVLANUseSecondTag) ? ENET_ECR_VLANUSE2ND_MASK : 0);
  486. #endif /* FSL_FEATURE_ENET_HAS_AVB */
  487. }
  488. /* Configures MAC receive controller with user configure structure. */
  489. rcr = ((macSpecialConfig & kENET_ControlRxPayloadCheckEnable) ? ENET_RCR_NLC_MASK : 0) |
  490. ((macSpecialConfig & kENET_ControlFlowControlEnable) ? ENET_RCR_CFEN_MASK : 0) |
  491. ((macSpecialConfig & kENET_ControlFlowControlEnable) ? ENET_RCR_FCE_MASK : 0) |
  492. ((macSpecialConfig & kENET_ControlRxPadRemoveEnable) ? ENET_RCR_PADEN_MASK : 0) |
  493. ((macSpecialConfig & kENET_ControlRxBroadCastRejectEnable) ? ENET_RCR_BC_REJ_MASK : 0) |
  494. ((macSpecialConfig & kENET_ControlPromiscuousEnable) ? ENET_RCR_PROM_MASK : 0) |
  495. ENET_RCR_MAX_FL(maxFrameLen) | ENET_RCR_CRCFWD_MASK;
  496. /* Set the RGMII or RMII, MII mode and control register. */
  497. #if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB
  498. if (config->miiMode == kENET_RgmiiMode)
  499. {
  500. rcr |= ENET_RCR_RGMII_EN_MASK;
  501. rcr &= ~ENET_RCR_MII_MODE_MASK;
  502. }
  503. else
  504. {
  505. rcr &= ~ENET_RCR_RGMII_EN_MASK;
  506. #endif /* FSL_FEATURE_ENET_HAS_AVB */
  507. rcr |= ENET_RCR_MII_MODE_MASK;
  508. if (config->miiMode == kENET_RmiiMode)
  509. {
  510. rcr |= ENET_RCR_RMII_MODE_MASK;
  511. }
  512. #if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB
  513. }
  514. #endif /* FSL_FEATURE_ENET_HAS_AVB */
  515. /* Speed. */
  516. if (config->miiSpeed == kENET_MiiSpeed10M)
  517. {
  518. rcr |= ENET_RCR_RMII_10T_MASK;
  519. }
  520. #if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB
  521. if (config->miiSpeed == kENET_MiiSpeed1000M)
  522. {
  523. ecr |= ENET_ECR_SPEED_MASK;
  524. }
  525. #endif /* FSL_FEATURE_ENET_HAS_AVB */
  526. /* Receive setting for half duplex. */
  527. if (config->miiDuplex == kENET_MiiHalfDuplex)
  528. {
  529. rcr |= ENET_RCR_DRT_MASK;
  530. }
  531. /* Sets internal loop only for MII mode. */
  532. if ((config->macSpecialConfig & kENET_ControlMIILoopEnable) && (config->miiMode != kENET_RmiiMode))
  533. {
  534. rcr |= ENET_RCR_LOOP_MASK;
  535. rcr &= ~ENET_RCR_DRT_MASK;
  536. }
  537. base->RCR = rcr;
  538. /* Configures MAC transmit controller: duplex mode, mac address insertion. */
  539. tcr = base->TCR & ~(ENET_TCR_FDEN_MASK | ENET_TCR_ADDINS_MASK);
  540. tcr |= (config->miiDuplex ? ENET_TCR_FDEN_MASK : 0) |
  541. ((macSpecialConfig & kENET_ControlMacAddrInsert) ? ENET_TCR_ADDINS_MASK : 0);
  542. base->TCR = tcr;
  543. /* Configures receive and transmit accelerator. */
  544. base->TACC = config->txAccelerConfig;
  545. base->RACC = config->rxAccelerConfig;
  546. /* Sets the pause duration and FIFO threshold for the flow control enabled case. */
  547. if (macSpecialConfig & kENET_ControlFlowControlEnable)
  548. {
  549. uint32_t reemReg;
  550. base->OPD = config->pauseDuration;
  551. reemReg = ENET_RSEM_RX_SECTION_EMPTY(config->rxFifoEmptyThreshold);
  552. #if defined(FSL_FEATURE_ENET_HAS_RECEIVE_STATUS_THRESHOLD) && FSL_FEATURE_ENET_HAS_RECEIVE_STATUS_THRESHOLD
  553. reemReg |= ENET_RSEM_STAT_SECTION_EMPTY(config->rxFifoStatEmptyThreshold);
  554. #endif /* FSL_FEATURE_ENET_HAS_RECEIVE_STATUS_THRESHOLD */
  555. base->RSEM = reemReg;
  556. }
  557. /* FIFO threshold setting for store and forward enable/disable case. */
  558. if (macSpecialConfig & kENET_ControlStoreAndFwdDisable)
  559. {
  560. /* Transmit fifo watermark settings. */
  561. base->TFWR = config->txFifoWatermark & ENET_TFWR_TFWR_MASK;
  562. /* Receive fifo full threshold settings. */
  563. base->RSFL = config->rxFifoFullThreshold & ENET_RSFL_RX_SECTION_FULL_MASK;
  564. }
  565. else
  566. {
  567. /* Transmit fifo watermark settings. */
  568. base->TFWR = ENET_TFWR_STRFWD_MASK;
  569. base->RSFL = 0;
  570. }
  571. /* Enable store and forward when accelerator is enabled */
  572. if (config->txAccelerConfig & (kENET_TxAccelIpCheckEnabled | kENET_TxAccelProtoCheckEnabled))
  573. {
  574. base->TFWR = ENET_TFWR_STRFWD_MASK;
  575. }
  576. if (config->rxAccelerConfig & (kENET_RxAccelIpCheckEnabled | kENET_RxAccelProtoCheckEnabled))
  577. {
  578. base->RSFL = 0;
  579. }
  580. /* Initializes the ring 0. */
  581. #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
  582. base->TDSR = MEMORY_ConvertMemoryMapAddress((uint32_t)bufferConfig->txBdStartAddrAlign, kMEMORY_Local2DMA);
  583. base->RDSR = MEMORY_ConvertMemoryMapAddress((uint32_t)bufferConfig->rxBdStartAddrAlign, kMEMORY_Local2DMA);
  584. #else
  585. base->TDSR = (uint32_t)bufferConfig->txBdStartAddrAlign;
  586. base->RDSR = (uint32_t)bufferConfig->rxBdStartAddrAlign;
  587. #endif
  588. base->MRBR = bufferConfig->rxBuffSizeAlign;
  589. #if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB
  590. const enet_buffer_config_t *buffCfg = bufferConfig;
  591. if (config->ringNum > 1)
  592. {
  593. /* Initializes the ring 1. */
  594. buffCfg++;
  595. #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
  596. base->TDSR1 = MEMORY_ConvertMemoryMapAddress((uint32_t)buffCfg->txBdStartAddrAlign, kMEMORY_Local2DMA);
  597. base->RDSR1 = MEMORY_ConvertMemoryMapAddress((uint32_t)buffCfg->rxBdStartAddrAlign, kMEMORY_Local2DMA);
  598. #else
  599. base->TDSR1 = (uint32_t)buffCfg->txBdStartAddrAlign;
  600. base->RDSR1 = (uint32_t)buffCfg->rxBdStartAddrAlign;
  601. #endif
  602. base->MRBR1 = buffCfg->rxBuffSizeAlign;
  603. /* Enable the DMAC for ring 1 and with no rx classification set. */
  604. base->DMACFG[0] = ENET_DMACFG_DMA_CLASS_EN_MASK;
  605. }
  606. if (config->ringNum > 2)
  607. {
  608. /* Initializes the ring 2. */
  609. buffCfg++;
  610. #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
  611. base->TDSR2 = MEMORY_ConvertMemoryMapAddress((uint32_t)buffCfg->txBdStartAddrAlign, kMEMORY_Local2DMA);
  612. base->RDSR2 = MEMORY_ConvertMemoryMapAddress((uint32_t)buffCfg->rxBdStartAddrAlign, kMEMORY_Local2DMA);
  613. #else
  614. base->TDSR2 = (uint32_t)buffCfg->txBdStartAddrAlign;
  615. base->RDSR2 = (uint32_t)buffCfg->rxBdStartAddrAlign;
  616. #endif
  617. base->MRBR2 = buffCfg->rxBuffSizeAlign;
  618. /* Enable the DMAC for ring 2 and with no rx classification set. */
  619. base->DMACFG[1] = ENET_DMACFG_DMA_CLASS_EN_MASK;
  620. }
  621. /* Default the class/ring 1 and 2 are not enabled and the receive classification is disabled
  622. * so we set the default transmit scheme with the round-robin mode. beacuse the legacy bd mode
  623. * only support the round-robin mode. if the avb feature is required, just call the setup avb
  624. * feature API. */
  625. base->QOS |= ENET_QOS_TX_SCHEME(1);
  626. #endif /* FSL_FEATURE_ENET_HAS_AVB */
  627. /* Configures the Mac address. */
  628. ENET_SetMacAddr(base, macAddr);
  629. /* Initialize the SMI if uninitialized. */
  630. if (!ENET_GetSMI(base))
  631. {
  632. ENET_SetSMI(base, srcClock_Hz, !!(config->macSpecialConfig & kENET_ControlSMIPreambleDisable));
  633. }
  634. /* Enables Ethernet interrupt, enables the interrupt coalsecing if it is required. */
  635. #if defined(FSL_FEATURE_ENET_HAS_INTERRUPT_COALESCE) && FSL_FEATURE_ENET_HAS_INTERRUPT_COALESCE
  636. if (config->intCoalesceCfg)
  637. {
  638. uint32_t intMask = (ENET_EIMR_TXB_MASK | ENET_EIMR_RXB_MASK);
  639. #if FSL_FEATURE_ENET_QUEUE > 1
  640. uint8_t queue = 0;
  641. intMask |= ENET_EIMR_TXB2_MASK | ENET_EIMR_RXB2_MASK | ENET_EIMR_TXB1_MASK | ENET_EIMR_RXB1_MASK;
  642. #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
  643. /* Clear all buffer interrupts. */
  644. base->EIMR &= ~intMask;
  645. /* Set the interrupt coalescence. */
  646. #if FSL_FEATURE_ENET_QUEUE > 1
  647. for (queue = 0; queue < FSL_FEATURE_ENET_QUEUE; queue++)
  648. {
  649. base->TXIC[queue] = ENET_TXIC_ICFT(config->intCoalesceCfg->txCoalesceFrameCount[queue]) |
  650. config->intCoalesceCfg->txCoalesceTimeCount[queue] | ENET_TXIC_ICCS_MASK |
  651. ENET_TXIC_ICEN_MASK;
  652. base->RXIC[queue] = ENET_RXIC_ICFT(config->intCoalesceCfg->rxCoalesceFrameCount[queue]) |
  653. config->intCoalesceCfg->rxCoalesceTimeCount[queue] | ENET_RXIC_ICCS_MASK |
  654. ENET_RXIC_ICEN_MASK;
  655. }
  656. #else
  657. base->TXIC = ENET_TXIC_ICFT(config->intCoalesceCfg->txCoalesceFrameCount[0]) |
  658. config->intCoalesceCfg->txCoalesceTimeCount[0] | ENET_TXIC_ICCS_MASK | ENET_TXIC_ICEN_MASK;
  659. base->RXIC = ENET_RXIC_ICFT(config->intCoalesceCfg->rxCoalesceFrameCount[0]) |
  660. config->intCoalesceCfg->rxCoalesceTimeCount[0] | ENET_RXIC_ICCS_MASK | ENET_RXIC_ICEN_MASK;
  661. #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
  662. }
  663. #endif /* FSL_FEATURE_ENET_HAS_INTERRUPT_COALESCE */
  664. ENET_EnableInterrupts(base, config->interrupt);
  665. #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
  666. /* Sets the 1588 enhanced feature. */
  667. ecr |= ENET_ECR_EN1588_MASK;
  668. #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
  669. /* Enables Ethernet module after all configuration except the buffer descriptor active. */
  670. ecr |= ENET_ECR_ETHEREN_MASK | ENET_ECR_DBSWP_MASK;
  671. base->ECR = ecr;
  672. }
  673. static void ENET_SetTxBufferDescriptors(enet_handle_t *handle,
  674. const enet_config_t *config,
  675. const enet_buffer_config_t *bufferConfig)
  676. {
  677. assert(config);
  678. assert(bufferConfig);
  679. /* Default single ring is supported. */
  680. uint8_t ringNum;
  681. uint32_t count;
  682. uint32_t txBuffSizeAlign;
  683. uint8_t *txBuffer;
  684. const enet_buffer_config_t *buffCfg = bufferConfig;
  685. /* Check the input parameters. */
  686. for (ringNum = 0; ringNum < config->ringNum; ringNum++)
  687. {
  688. if ((buffCfg->txBdStartAddrAlign > 0) && (buffCfg->txBufferAlign > 0))
  689. {
  690. volatile enet_tx_bd_struct_t *curBuffDescrip = buffCfg->txBdStartAddrAlign;
  691. txBuffSizeAlign = buffCfg->txBuffSizeAlign;
  692. #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
  693. txBuffer = (uint8_t *)MEMORY_ConvertMemoryMapAddress((uint32_t)buffCfg->txBufferAlign, kMEMORY_Local2DMA);
  694. #else
  695. txBuffer = buffCfg->txBufferAlign;
  696. #endif
  697. for (count = 0; count < buffCfg->txBdNumber; count++)
  698. {
  699. /* Set data buffer address. */
  700. curBuffDescrip->buffer = (uint8_t *)((uint32_t)&txBuffer[count * txBuffSizeAlign]);
  701. /* Initializes data length. */
  702. curBuffDescrip->length = 0;
  703. /* Sets the crc. */
  704. curBuffDescrip->control = ENET_BUFFDESCRIPTOR_TX_TRANMITCRC_MASK;
  705. /* Sets the last buffer descriptor with the wrap flag. */
  706. if (count == buffCfg->txBdNumber - 1)
  707. {
  708. curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_WRAP_MASK;
  709. }
  710. #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
  711. /* Enable transmit interrupt for store the transmit timestamp. */
  712. curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_INTERRUPT_MASK;
  713. #if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB
  714. /* Set the type of the frame when the credit-based scheme is used. */
  715. curBuffDescrip->controlExtend1 |= ENET_BD_FTYPE(ringNum);
  716. #endif /* FSL_FEATURE_ENET_HAS_AVB */
  717. #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
  718. /* Increase the index. */
  719. curBuffDescrip++;
  720. }
  721. }
  722. buffCfg++;
  723. }
  724. }
  725. static void ENET_SetRxBufferDescriptors(enet_handle_t *handle,
  726. const enet_config_t *config,
  727. const enet_buffer_config_t *bufferConfig)
  728. {
  729. assert(config);
  730. assert(bufferConfig);
  731. /* Default single ring is supported. */
  732. uint8_t ringNum;
  733. uint32_t count;
  734. uint32_t rxBuffSizeAlign;
  735. uint8_t *rxBuffer;
  736. const enet_buffer_config_t *buffCfg = bufferConfig;
  737. #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
  738. uint32_t mask = (kENET_RxFrameInterrupt | kENET_RxBufferInterrupt);
  739. #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
  740. /* Check the input parameters. */
  741. for (ringNum = 0; ringNum < config->ringNum; ringNum++)
  742. {
  743. assert(buffCfg->rxBuffSizeAlign >= ENET_RX_MIN_BUFFERSIZE);
  744. #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
  745. #if FSL_FEATURE_ENET_QUEUE > 1
  746. if (ringNum == 1)
  747. {
  748. mask = (kENET_RxFrame1Interrupt | kENET_RxBuffer1Interrupt);
  749. }
  750. else if (ringNum == 2)
  751. {
  752. mask = (kENET_RxFrame2Interrupt | kENET_RxBuffer2Interrupt);
  753. }
  754. #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
  755. #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
  756. if ((buffCfg->rxBdStartAddrAlign > 0) && (buffCfg->rxBufferAlign > 0))
  757. {
  758. volatile enet_rx_bd_struct_t *curBuffDescrip = buffCfg->rxBdStartAddrAlign;
  759. rxBuffSizeAlign = buffCfg->rxBuffSizeAlign;
  760. #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
  761. rxBuffer = (uint8_t *)MEMORY_ConvertMemoryMapAddress((uint32_t)buffCfg->rxBufferAlign, kMEMORY_Local2DMA);
  762. #else
  763. rxBuffer = buffCfg->rxBufferAlign;
  764. #endif
  765. #if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
  766. /* Invalidate rx buffers before DMA transfer data into them. */
  767. DCACHE_InvalidateByRange((uint32_t)rxBuffer, (buffCfg->rxBdNumber * rxBuffSizeAlign));
  768. #endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
  769. for (count = 0; count < buffCfg->rxBdNumber; count++)
  770. {
  771. /* Set data buffer and the length. */
  772. curBuffDescrip->buffer = (uint8_t *)((uint32_t)&rxBuffer[count * rxBuffSizeAlign]);
  773. curBuffDescrip->length = 0;
  774. /* Initializes the buffer descriptors with empty bit. */
  775. curBuffDescrip->control = ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK;
  776. /* Sets the last buffer descriptor with the wrap flag. */
  777. if (count == buffCfg->rxBdNumber - 1)
  778. {
  779. curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK;
  780. }
  781. #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
  782. if (config->interrupt & mask)
  783. {
  784. /* Enable receive interrupt. */
  785. curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_RX_INTERRUPT_MASK;
  786. }
  787. else
  788. {
  789. curBuffDescrip->controlExtend1 = 0;
  790. }
  791. #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
  792. /* Increase the index. */
  793. curBuffDescrip++;
  794. }
  795. }
  796. buffCfg++;
  797. }
  798. }
  799. static void ENET_ActiveSend(ENET_Type *base, uint32_t ringId)
  800. {
  801. assert(ringId < FSL_FEATURE_ENET_QUEUE);
  802. switch (ringId)
  803. {
  804. case kENET_Ring0:
  805. base->TDAR = ENET_TDAR_TDAR_MASK;
  806. break;
  807. #if FSL_FEATURE_ENET_QUEUE > 1
  808. case kENET_Ring1:
  809. base->TDAR1 = ENET_TDAR1_TDAR_MASK;
  810. break;
  811. case kENET_Ring2:
  812. base->TDAR2 = ENET_TDAR2_TDAR_MASK;
  813. break;
  814. #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
  815. default:
  816. base->TDAR = ENET_TDAR_TDAR_MASK;
  817. break;
  818. }
  819. }
  820. /*!
  821. * brief Sets the ENET MII speed and duplex.
  822. *
  823. * This API is provided to dynamically change the speed and dulpex for MAC.
  824. *
  825. * param base ENET peripheral base address.
  826. * param speed The speed of the RMII mode.
  827. * param duplex The duplex of the RMII mode.
  828. */
  829. void ENET_SetMII(ENET_Type *base, enet_mii_speed_t speed, enet_mii_duplex_t duplex)
  830. {
  831. uint32_t rcr = base->RCR;
  832. uint32_t tcr = base->TCR;
  833. #if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB
  834. uint32_t ecr = base->ECR;
  835. if (kENET_MiiSpeed1000M == speed)
  836. {
  837. assert(duplex == kENET_MiiFullDuplex);
  838. ecr |= ENET_ECR_SPEED_MASK;
  839. }
  840. else
  841. {
  842. ecr &= ~ENET_ECR_SPEED_MASK;
  843. }
  844. base->ECR = ecr;
  845. #endif /* FSL_FEATURE_ENET_HAS_AVB */
  846. /* Sets speed mode. */
  847. if (kENET_MiiSpeed10M == speed)
  848. {
  849. rcr |= ENET_RCR_RMII_10T_MASK;
  850. }
  851. else
  852. {
  853. rcr &= ~ENET_RCR_RMII_10T_MASK;
  854. }
  855. /* Set duplex mode. */
  856. if (duplex == kENET_MiiHalfDuplex)
  857. {
  858. rcr |= ENET_RCR_DRT_MASK;
  859. tcr &= ~ENET_TCR_FDEN_MASK;
  860. }
  861. else
  862. {
  863. rcr &= ~ENET_RCR_DRT_MASK;
  864. tcr |= ENET_TCR_FDEN_MASK;
  865. }
  866. base->RCR = rcr;
  867. base->TCR = tcr;
  868. }
  869. /*!
  870. * brief Sets the ENET module Mac address.
  871. *
  872. * param base ENET peripheral base address.
  873. * param macAddr The six-byte Mac address pointer.
  874. * The pointer is allocated by application and input into the API.
  875. */
  876. void ENET_SetMacAddr(ENET_Type *base, uint8_t *macAddr)
  877. {
  878. uint32_t address;
  879. /* Set physical address lower register. */
  880. address = (uint32_t)(((uint32_t)macAddr[0] << 24U) | ((uint32_t)macAddr[1] << 16U) | ((uint32_t)macAddr[2] << 8U) |
  881. (uint32_t)macAddr[3]);
  882. base->PALR = address;
  883. /* Set physical address high register. */
  884. address = (uint32_t)(((uint32_t)macAddr[4] << 8U) | ((uint32_t)macAddr[5]));
  885. base->PAUR = address << ENET_PAUR_PADDR2_SHIFT;
  886. }
  887. /*!
  888. * brief Gets the ENET module Mac address.
  889. *
  890. * param base ENET peripheral base address.
  891. * param macAddr The six-byte Mac address pointer.
  892. * The pointer is allocated by application and input into the API.
  893. */
  894. void ENET_GetMacAddr(ENET_Type *base, uint8_t *macAddr)
  895. {
  896. assert(macAddr);
  897. uint32_t address;
  898. /* Get from physical address lower register. */
  899. address = base->PALR;
  900. macAddr[0] = 0xFFU & (address >> 24U);
  901. macAddr[1] = 0xFFU & (address >> 16U);
  902. macAddr[2] = 0xFFU & (address >> 8U);
  903. macAddr[3] = 0xFFU & address;
  904. /* Get from physical address high register. */
  905. address = (base->PAUR & ENET_PAUR_PADDR2_MASK) >> ENET_PAUR_PADDR2_SHIFT;
  906. macAddr[4] = 0xFFU & (address >> 8U);
  907. macAddr[5] = 0xFFU & address;
  908. }
  909. /*!
  910. * brief Sets the ENET SMI(serial management interface)- MII management interface.
  911. *
  912. * param base ENET peripheral base address.
  913. * param srcClock_Hz This is the ENET module clock frequency. Normally it's the system clock. See clock distribution.
  914. * param isPreambleDisabled The preamble disable flag.
  915. * - true Enables the preamble.
  916. * - false Disables the preamble.
  917. */
  918. void ENET_SetSMI(ENET_Type *base, uint32_t srcClock_Hz, bool isPreambleDisabled)
  919. {
  920. assert(srcClock_Hz);
  921. uint32_t clkCycle = 0;
  922. uint32_t speed = 0;
  923. uint32_t mscr = 0;
  924. /* Calculate the MII speed which controls the frequency of the MDC. */
  925. speed = srcClock_Hz / (2 * ENET_MDC_FREQUENCY);
  926. /* Calculate the hold time on the MDIO output. */
  927. clkCycle = (10 + ENET_NANOSECOND_ONE_SECOND / srcClock_Hz - 1) / (ENET_NANOSECOND_ONE_SECOND / srcClock_Hz) - 1;
  928. /* Build the configuration for MDC/MDIO control. */
  929. mscr =
  930. ENET_MSCR_MII_SPEED(speed) | ENET_MSCR_HOLDTIME(clkCycle) | (isPreambleDisabled ? ENET_MSCR_DIS_PRE_MASK : 0);
  931. base->MSCR = mscr;
  932. }
  933. /*!
  934. * brief Starts an SMI write command.
  935. *
  936. * Used for standard IEEE802.3 MDIO Clause 22 format.
  937. *
  938. * param base ENET peripheral base address.
  939. * param phyAddr The PHY address.
  940. * param phyReg The PHY register. Range from 0 ~ 31.
  941. * param operation The write operation.
  942. * param data The data written to PHY.
  943. */
  944. void ENET_StartSMIWrite(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, enet_mii_write_t operation, uint32_t data)
  945. {
  946. uint32_t mmfr = 0;
  947. /* Build MII write command. */
  948. mmfr = ENET_MMFR_ST(1) | ENET_MMFR_OP(operation) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(phyReg) | ENET_MMFR_TA(2) |
  949. (data & 0xFFFF);
  950. base->MMFR = mmfr;
  951. }
  952. /*!
  953. * brief Starts an SMI (Serial Management Interface) read command.
  954. *
  955. * Used for standard IEEE802.3 MDIO Clause 22 format.
  956. *
  957. * param base ENET peripheral base address.
  958. * param phyAddr The PHY address.
  959. * param phyReg The PHY register. Range from 0 ~ 31.
  960. * param operation The read operation.
  961. */
  962. void ENET_StartSMIRead(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, enet_mii_read_t operation)
  963. {
  964. uint32_t mmfr = 0;
  965. /* Build MII read command. */
  966. mmfr = ENET_MMFR_ST(1) | ENET_MMFR_OP(operation) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(phyReg) | ENET_MMFR_TA(2);
  967. base->MMFR = mmfr;
  968. }
  969. #if defined(FSL_FEATURE_ENET_HAS_EXTEND_MDIO) && FSL_FEATURE_ENET_HAS_EXTEND_MDIO
  970. /*!
  971. * brief Starts the extended IEEE802.3 Clause 45 MDIO format SMI write command.
  972. *
  973. * param base ENET peripheral base address.
  974. * param phyAddr The PHY address.
  975. * param phyReg The PHY register. For MDIO IEEE802.3 Clause 45,
  976. * the phyReg is a 21-bits combination of the devaddr (5 bits device address)
  977. * and the regAddr (16 bits phy register): phyReg = (devaddr << 16) | regAddr.
  978. * param data The data written to PHY.
  979. */
  980. void ENET_StartExtC45SMIWrite(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t data)
  981. {
  982. uint32_t mmfr = 0;
  983. /* Parse the address from the input register. */
  984. uint16_t devAddr = (phyReg >> ENET_MMFR_TA_SHIFT) & 0x1FU;
  985. uint16_t regAddr = (uint16_t)(phyReg & 0xFFFFU);
  986. /* Address write firstly. */
  987. mmfr = ENET_MMFR_ST(0) | ENET_MMFR_OP(kENET_MiiAddrWrite_C45) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(devAddr) |
  988. ENET_MMFR_TA(2) | ENET_MMFR_DATA(regAddr);
  989. base->MMFR = mmfr;
  990. /* Build MII write command. */
  991. mmfr = ENET_MMFR_ST(0) | ENET_MMFR_OP(kENET_MiiWriteFrame_C45) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(devAddr) |
  992. ENET_MMFR_TA(2) | ENET_MMFR_DATA(data);
  993. base->MMFR = mmfr;
  994. }
  995. /*!
  996. * brief Starts the extended IEEE802.3 Clause 45 MDIO format SMI read command.
  997. *
  998. * param base ENET peripheral base address.
  999. * param phyAddr The PHY address.
  1000. * param phyReg The PHY register. For MDIO IEEE802.3 Clause 45,
  1001. * the phyReg is a 21-bits combination of the devaddr (5 bits device address)
  1002. * and the regAddr (16 bits phy register): phyReg = (devaddr << 16) | regAddr.
  1003. */
  1004. void ENET_StartExtC45SMIRead(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg)
  1005. {
  1006. uint32_t mmfr = 0;
  1007. /* Parse the address from the input register. */
  1008. uint16_t devAddr = (phyReg >> ENET_MMFR_TA_SHIFT) & 0x1FU;
  1009. uint16_t regAddr = (uint16_t)(phyReg & 0xFFFFU);
  1010. /* Address write firstly. */
  1011. mmfr = ENET_MMFR_ST(0) | ENET_MMFR_OP(kENET_MiiAddrWrite_C45) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(devAddr) |
  1012. ENET_MMFR_TA(2) | ENET_MMFR_DATA(regAddr);
  1013. base->MMFR = mmfr;
  1014. /* Build MII read command. */
  1015. mmfr = ENET_MMFR_ST(0) | ENET_MMFR_OP(kENET_MiiReadFrame_C45) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(devAddr) |
  1016. ENET_MMFR_TA(2);
  1017. base->MMFR = mmfr;
  1018. }
  1019. #endif /* FSL_FEATURE_ENET_HAS_EXTEND_MDIO */
  1020. /*!
  1021. * brief Gets the error statistics of a received frame for ENET single ring.
  1022. *
  1023. * This API must be called after the ENET_GetRxFrameSize and before the ENET_ReadFrame().
  1024. * If the ENET_GetRxFrameSize returns kStatus_ENET_RxFrameError,
  1025. * the ENET_GetRxErrBeforeReadFrame can be used to get the exact error statistics.
  1026. * This is an example.
  1027. * code
  1028. * status = ENET_GetRxFrameSize(&g_handle, &length);
  1029. * if (status == kStatus_ENET_RxFrameError)
  1030. * {
  1031. * // Get the error information of the received frame.
  1032. * ENET_GetRxErrBeforeReadFrame(&g_handle, &eErrStatic);
  1033. * // update the receive buffer.
  1034. * ENET_ReadFrame(EXAMPLE_ENET, &g_handle, NULL, 0);
  1035. * }
  1036. * endcode
  1037. * param handle The ENET handler structure pointer. This is the same handler pointer used in the ENET_Init.
  1038. * param eErrorStatic The error statistics structure pointer.
  1039. */
  1040. void ENET_GetRxErrBeforeReadFrame(enet_handle_t *handle, enet_data_error_stats_t *eErrorStatic)
  1041. {
  1042. assert(handle);
  1043. assert(handle->rxBdCurrent[0]);
  1044. assert(eErrorStatic);
  1045. uint16_t control = 0;
  1046. volatile enet_rx_bd_struct_t *curBuffDescrip = handle->rxBdCurrent[0];
  1047. do
  1048. {
  1049. /* The last buffer descriptor of a frame. */
  1050. if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK)
  1051. {
  1052. control = curBuffDescrip->control;
  1053. if (control & ENET_BUFFDESCRIPTOR_RX_TRUNC_MASK)
  1054. {
  1055. /* The receive truncate error. */
  1056. eErrorStatic->statsRxTruncateErr++;
  1057. }
  1058. if (control & ENET_BUFFDESCRIPTOR_RX_OVERRUN_MASK)
  1059. {
  1060. /* The receive over run error. */
  1061. eErrorStatic->statsRxOverRunErr++;
  1062. }
  1063. if (control & ENET_BUFFDESCRIPTOR_RX_LENVLIOLATE_MASK)
  1064. {
  1065. /* The receive length violation error. */
  1066. eErrorStatic->statsRxLenGreaterErr++;
  1067. }
  1068. if (control & ENET_BUFFDESCRIPTOR_RX_NOOCTET_MASK)
  1069. {
  1070. /* The receive alignment error. */
  1071. eErrorStatic->statsRxAlignErr++;
  1072. }
  1073. if (control & ENET_BUFFDESCRIPTOR_RX_CRC_MASK)
  1074. {
  1075. /* The receive CRC error. */
  1076. eErrorStatic->statsRxFcsErr++;
  1077. }
  1078. #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
  1079. uint16_t controlExt = curBuffDescrip->controlExtend1;
  1080. if (controlExt & ENET_BUFFDESCRIPTOR_RX_MACERR_MASK)
  1081. {
  1082. /* The MAC error. */
  1083. eErrorStatic->statsRxMacErr++;
  1084. }
  1085. if (controlExt & ENET_BUFFDESCRIPTOR_RX_PHYERR_MASK)
  1086. {
  1087. /* The PHY error. */
  1088. eErrorStatic->statsRxPhyErr++;
  1089. }
  1090. if (controlExt & ENET_BUFFDESCRIPTOR_RX_COLLISION_MASK)
  1091. {
  1092. /* The receive collision error. */
  1093. eErrorStatic->statsRxCollisionErr++;
  1094. }
  1095. #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
  1096. break;
  1097. }
  1098. /* Increase the buffer descriptor, if it is the last one, increase to first one of the ring buffer. */
  1099. if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK)
  1100. {
  1101. curBuffDescrip = handle->rxBdBase[0];
  1102. }
  1103. else
  1104. {
  1105. curBuffDescrip++;
  1106. }
  1107. } while (curBuffDescrip != handle->rxBdCurrent[0]);
  1108. }
  1109. /*!
  1110. * brief Gets the size of the read frame for single ring.
  1111. *
  1112. * This function gets a received frame size from the ENET buffer descriptors.
  1113. * note The FCS of the frame is automatically removed by MAC and the size is the length without the FCS.
  1114. * After calling ENET_GetRxFrameSize, ENET_ReadFrame() should be called to update the
  1115. * receive buffers If the result is not "kStatus_ENET_RxFrameEmpty".
  1116. *
  1117. * param handle The ENET handler structure. This is the same handler pointer used in the ENET_Init.
  1118. * param length The length of the valid frame received.
  1119. * retval kStatus_ENET_RxFrameEmpty No frame received. Should not call ENET_ReadFrame to read frame.
  1120. * retval kStatus_ENET_RxFrameError Data error happens. ENET_ReadFrame should be called with NULL data
  1121. * and NULL length to update the receive buffers.
  1122. * retval kStatus_Success Receive a frame Successfully then the ENET_ReadFrame
  1123. * should be called with the right data buffer and the captured data length input.
  1124. */
  1125. status_t ENET_GetRxFrameSize(enet_handle_t *handle, uint32_t *length)
  1126. {
  1127. assert(handle);
  1128. assert(handle->rxBdCurrent[0]);
  1129. assert(length);
  1130. /* Reset the length to zero. */
  1131. *length = 0;
  1132. uint16_t validLastMask = ENET_BUFFDESCRIPTOR_RX_LAST_MASK | ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK;
  1133. volatile enet_rx_bd_struct_t *curBuffDescrip = handle->rxBdCurrent[0];
  1134. /* Check the current buffer descriptor's empty flag. if empty means there is no frame received. */
  1135. if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK)
  1136. {
  1137. return kStatus_ENET_RxFrameEmpty;
  1138. }
  1139. do
  1140. {
  1141. /* Add check for abnormal case. */
  1142. if ((!(curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK)) && (!curBuffDescrip->length))
  1143. {
  1144. return kStatus_ENET_RxFrameError;
  1145. }
  1146. /* Find the last buffer descriptor. */
  1147. if ((curBuffDescrip->control & validLastMask) == ENET_BUFFDESCRIPTOR_RX_LAST_MASK)
  1148. {
  1149. /* The last buffer descriptor in the frame check the status of the received frame. */
  1150. if ((curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_ERR_MASK)
  1151. #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
  1152. || (curBuffDescrip->controlExtend1 & ENET_BUFFDESCRIPTOR_RX_EXT_ERR_MASK)
  1153. #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
  1154. )
  1155. {
  1156. return kStatus_ENET_RxFrameError;
  1157. }
  1158. /* FCS is removed by MAC. */
  1159. *length = curBuffDescrip->length;
  1160. return kStatus_Success;
  1161. }
  1162. /* Increase the buffer descriptor, if it is the last one, increase to first one of the ring buffer. */
  1163. if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK)
  1164. {
  1165. curBuffDescrip = handle->rxBdBase[0];
  1166. }
  1167. else
  1168. {
  1169. curBuffDescrip++;
  1170. }
  1171. } while (curBuffDescrip != handle->rxBdCurrent[0]);
  1172. /* The frame is on processing - set to empty status to make application to receive it next time. */
  1173. return kStatus_ENET_RxFrameEmpty;
  1174. }
  1175. /*!
  1176. * brief Reads a frame from the ENET device for single ring.
  1177. * This function reads a frame (both the data and the length) from the ENET buffer descriptors.
  1178. * The ENET_GetRxFrameSize should be used to get the size of the prepared data buffer.
  1179. * This is an example:
  1180. * code
  1181. * uint32_t length;
  1182. * enet_handle_t g_handle;
  1183. * //Get the received frame size firstly.
  1184. * status = ENET_GetRxFrameSize(&g_handle, &length);
  1185. * if (length != 0)
  1186. * {
  1187. * //Allocate memory here with the size of "length"
  1188. * uint8_t *data = memory allocate interface;
  1189. * if (!data)
  1190. * {
  1191. * ENET_ReadFrame(ENET, &g_handle, NULL, 0);
  1192. * //Add the console warning log.
  1193. * }
  1194. * else
  1195. * {
  1196. * status = ENET_ReadFrame(ENET, &g_handle, data, length);
  1197. * //Call stack input API to deliver the data to stack
  1198. * }
  1199. * }
  1200. * else if (status == kStatus_ENET_RxFrameError)
  1201. * {
  1202. * //Update the received buffer when a error frame is received.
  1203. * ENET_ReadFrame(ENET, &g_handle, NULL, 0);
  1204. * }
  1205. * endcode
  1206. * param base ENET peripheral base address.
  1207. * param handle The ENET handler structure. This is the same handler pointer used in the ENET_Init.
  1208. * param data The data buffer provided by user to store the frame which memory size should be at least "length".
  1209. * param length The size of the data buffer which is still the length of the received frame.
  1210. * return The execute status, successful or failure.
  1211. */
  1212. status_t ENET_ReadFrame(ENET_Type *base, enet_handle_t *handle, uint8_t *data, uint32_t length)
  1213. {
  1214. assert(handle);
  1215. assert(handle->rxBdCurrent[0]);
  1216. uint32_t len = 0;
  1217. uint32_t offset = 0;
  1218. uint16_t control;
  1219. bool isLastBuff = false;
  1220. volatile enet_rx_bd_struct_t *curBuffDescrip = handle->rxBdCurrent[0];
  1221. status_t result = kStatus_Success;
  1222. uint32_t address;
  1223. /* For data-NULL input, only update the buffer descriptor. */
  1224. if (!data)
  1225. {
  1226. do
  1227. {
  1228. /* Update the control flag. */
  1229. control = handle->rxBdCurrent[0]->control;
  1230. /* Updates the receive buffer descriptors. */
  1231. ENET_UpdateReadBuffers(base, handle, 0);
  1232. /* Find the last buffer descriptor for the frame. */
  1233. if (control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK)
  1234. {
  1235. break;
  1236. }
  1237. } while (handle->rxBdCurrent[0] != curBuffDescrip);
  1238. return result;
  1239. }
  1240. else
  1241. {
  1242. /* A frame on one buffer or several receive buffers are both considered. */
  1243. #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
  1244. address = MEMORY_ConvertMemoryMapAddress((uint32_t)curBuffDescrip->buffer, kMEMORY_DMA2Local);
  1245. #else
  1246. address = (uint32_t)curBuffDescrip->buffer;
  1247. #endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
  1248. #if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
  1249. /* Add the cache invalidate maintain. */
  1250. DCACHE_InvalidateByRange(address, handle->rxBuffSizeAlign[0]);
  1251. #endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
  1252. #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
  1253. enet_ptp_time_data_t ptpTimestamp;
  1254. bool isPtpEventMessage = false;
  1255. /* Parse the PTP message according to the header message. */
  1256. isPtpEventMessage = ENET_Ptp1588ParseFrame((uint8_t *)address, &ptpTimestamp, false);
  1257. #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
  1258. while (!isLastBuff)
  1259. {
  1260. /* The last buffer descriptor of a frame. */
  1261. if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK)
  1262. {
  1263. /* This is a valid frame. */
  1264. isLastBuff = true;
  1265. if (length == curBuffDescrip->length)
  1266. {
  1267. /* Copy the frame to user's buffer without FCS. */
  1268. len = curBuffDescrip->length - offset;
  1269. memcpy(data + offset, (void *)address, len);
  1270. #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
  1271. /* Store the PTP 1588 timestamp for received PTP event frame. */
  1272. if (isPtpEventMessage)
  1273. {
  1274. /* Set the timestamp to the timestamp ring. */
  1275. ptpTimestamp.timeStamp.nanosecond = curBuffDescrip->timestamp;
  1276. result = ENET_StoreRxFrameTime(base, handle, &ptpTimestamp);
  1277. }
  1278. #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
  1279. /* Updates the receive buffer descriptors. */
  1280. ENET_UpdateReadBuffers(base, handle, 0);
  1281. return result;
  1282. }
  1283. else
  1284. {
  1285. /* Updates the receive buffer descriptors. */
  1286. ENET_UpdateReadBuffers(base, handle, 0);
  1287. }
  1288. }
  1289. else
  1290. {
  1291. /* Store a frame on several buffer descriptors. */
  1292. isLastBuff = false;
  1293. /* Length check. */
  1294. if (offset >= length)
  1295. {
  1296. break;
  1297. }
  1298. memcpy(data + offset, (void *)address, handle->rxBuffSizeAlign[0]);
  1299. offset += handle->rxBuffSizeAlign[0];
  1300. /* Updates the receive buffer descriptors. */
  1301. ENET_UpdateReadBuffers(base, handle, 0);
  1302. }
  1303. /* Get the current buffer descriptor. */
  1304. curBuffDescrip = handle->rxBdCurrent[0];
  1305. /* Add the cache invalidate maintain. */
  1306. #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
  1307. address = MEMORY_ConvertMemoryMapAddress((uint32_t)curBuffDescrip->buffer, kMEMORY_DMA2Local);
  1308. #else
  1309. address = (uint32_t)curBuffDescrip->buffer;
  1310. #endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
  1311. #if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
  1312. DCACHE_InvalidateByRange(address, handle->rxBuffSizeAlign[0]);
  1313. #endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
  1314. }
  1315. }
  1316. return kStatus_ENET_RxFrameFail;
  1317. }
  1318. static void ENET_UpdateReadBuffers(ENET_Type *base, enet_handle_t *handle, uint32_t ringId)
  1319. {
  1320. assert(handle);
  1321. assert(ringId < FSL_FEATURE_ENET_QUEUE);
  1322. /* Clears status. */
  1323. handle->rxBdCurrent[ringId]->control &= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK;
  1324. /* Sets the receive buffer descriptor with the empty flag. */
  1325. handle->rxBdCurrent[ringId]->control |= ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK;
  1326. /* Increase current buffer descriptor to the next one. */
  1327. if (handle->rxBdCurrent[ringId]->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK)
  1328. {
  1329. handle->rxBdCurrent[ringId] = handle->rxBdBase[ringId];
  1330. }
  1331. else
  1332. {
  1333. handle->rxBdCurrent[ringId]++;
  1334. }
  1335. /* Actives the receive buffer descriptor. */
  1336. switch (ringId)
  1337. {
  1338. case kENET_Ring0:
  1339. base->RDAR = ENET_RDAR_RDAR_MASK;
  1340. break;
  1341. #if FSL_FEATURE_ENET_QUEUE > 1
  1342. case kENET_Ring1:
  1343. base->RDAR1 = ENET_RDAR1_RDAR_MASK;
  1344. break;
  1345. case kENET_Ring2:
  1346. base->RDAR2 = ENET_RDAR2_RDAR_MASK;
  1347. break;
  1348. #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
  1349. default:
  1350. base->RDAR = ENET_RDAR_RDAR_MASK;
  1351. break;
  1352. }
  1353. }
  1354. /*!
  1355. * brief Transmits an ENET frame for single ring.
  1356. * note The CRC is automatically appended to the data. Input the data
  1357. * to send without the CRC.
  1358. *
  1359. *
  1360. * param base ENET peripheral base address.
  1361. * param handle The ENET handler pointer. This is the same handler pointer used in the ENET_Init.
  1362. * param data The data buffer provided by user to be send.
  1363. * param length The length of the data to be send.
  1364. * retval kStatus_Success Send frame succeed.
  1365. * retval kStatus_ENET_TxFrameBusy Transmit buffer descriptor is busy under transmission.
  1366. * The transmit busy happens when the data send rate is over the MAC capacity.
  1367. * The waiting mechanism is recommended to be added after each call return with
  1368. * kStatus_ENET_TxFrameBusy.
  1369. */
  1370. status_t ENET_SendFrame(ENET_Type *base, enet_handle_t *handle, const uint8_t *data, uint32_t length)
  1371. {
  1372. assert(handle);
  1373. assert(data);
  1374. volatile enet_tx_bd_struct_t *curBuffDescrip;
  1375. uint32_t len = 0;
  1376. uint32_t sizeleft = 0;
  1377. uint32_t address;
  1378. /* Check the frame length. */
  1379. if (length > ENET_FRAME_MAX_FRAMELEN)
  1380. {
  1381. return kStatus_ENET_TxFrameOverLen;
  1382. }
  1383. /* Check if the transmit buffer is ready. */
  1384. curBuffDescrip = handle->txBdCurrent[0];
  1385. if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK)
  1386. {
  1387. return kStatus_ENET_TxFrameBusy;
  1388. }
  1389. #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
  1390. bool isPtpEventMessage = false;
  1391. /* Check PTP message with the PTP header. */
  1392. isPtpEventMessage = ENET_Ptp1588ParseFrame(data, NULL, true);
  1393. #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
  1394. /* One transmit buffer is enough for one frame. */
  1395. if (handle->txBuffSizeAlign[0] >= length)
  1396. {
  1397. /* Copy data to the buffer for uDMA transfer. */
  1398. #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
  1399. address = MEMORY_ConvertMemoryMapAddress((uint32_t)curBuffDescrip->buffer, kMEMORY_DMA2Local);
  1400. #else
  1401. address = (uint32_t)curBuffDescrip->buffer;
  1402. #endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
  1403. memcpy((void *)address, data, length);
  1404. #if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
  1405. DCACHE_CleanByRange(address, length);
  1406. #endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
  1407. /* Set data length. */
  1408. curBuffDescrip->length = length;
  1409. #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
  1410. /* For enable the timestamp. */
  1411. if (isPtpEventMessage)
  1412. {
  1413. curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK;
  1414. }
  1415. else
  1416. {
  1417. curBuffDescrip->controlExtend1 &= ~ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK;
  1418. }
  1419. #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
  1420. curBuffDescrip->control |= (ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK);
  1421. /* Increase the buffer descriptor address. */
  1422. if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_WRAP_MASK)
  1423. {
  1424. handle->txBdCurrent[0] = handle->txBdBase[0];
  1425. }
  1426. else
  1427. {
  1428. handle->txBdCurrent[0]++;
  1429. }
  1430. /* Active the transmit buffer descriptor. */
  1431. ENET_ActiveSend(base, 0);
  1432. return kStatus_Success;
  1433. }
  1434. else
  1435. {
  1436. /* One frame requires more than one transmit buffers. */
  1437. do
  1438. {
  1439. #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
  1440. /* For enable the timestamp. */
  1441. if (isPtpEventMessage)
  1442. {
  1443. curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK;
  1444. }
  1445. else
  1446. {
  1447. curBuffDescrip->controlExtend1 &= ~ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK;
  1448. }
  1449. #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
  1450. /* Increase the buffer descriptor address. */
  1451. if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_WRAP_MASK)
  1452. {
  1453. handle->txBdCurrent[0] = handle->txBdBase[0];
  1454. }
  1455. else
  1456. {
  1457. handle->txBdCurrent[0]++;
  1458. }
  1459. /* update the size left to be transmit. */
  1460. sizeleft = length - len;
  1461. #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
  1462. address = MEMORY_ConvertMemoryMapAddress((uint32_t)curBuffDescrip->buffer, kMEMORY_DMA2Local);
  1463. #else
  1464. address = (uint32_t)curBuffDescrip->buffer;
  1465. #endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
  1466. if (sizeleft > handle->txBuffSizeAlign[0])
  1467. {
  1468. /* Data copy. */
  1469. memcpy((void *)address, data + len, handle->txBuffSizeAlign[0]);
  1470. #if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
  1471. /* Add the cache clean maintain. */
  1472. DCACHE_CleanByRange(address, handle->txBuffSizeAlign[0]);
  1473. #endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
  1474. /* Data length update. */
  1475. curBuffDescrip->length = handle->txBuffSizeAlign[0];
  1476. len += handle->txBuffSizeAlign[0];
  1477. /* Sets the control flag. */
  1478. curBuffDescrip->control &= ~ENET_BUFFDESCRIPTOR_TX_LAST_MASK;
  1479. curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_READY_MASK;
  1480. /* Active the transmit buffer descriptor*/
  1481. ENET_ActiveSend(base, 0);
  1482. }
  1483. else
  1484. {
  1485. memcpy((void *)address, data + len, sizeleft);
  1486. #if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
  1487. /* Add the cache clean maintain. */
  1488. DCACHE_CleanByRange(address, sizeleft);
  1489. #endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
  1490. curBuffDescrip->length = sizeleft;
  1491. /* Set Last buffer wrap flag. */
  1492. curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK;
  1493. /* Active the transmit buffer descriptor. */
  1494. ENET_ActiveSend(base, 0);
  1495. return kStatus_Success;
  1496. }
  1497. /* Get the current buffer descriptor address. */
  1498. curBuffDescrip = handle->txBdCurrent[0];
  1499. } while (!(curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK));
  1500. return kStatus_ENET_TxFrameBusy;
  1501. }
  1502. }
  1503. #if FSL_FEATURE_ENET_QUEUE > 1
  1504. /*!
  1505. * brief Gets the error statistics of received frame for extended multi-ring.
  1506. *
  1507. * This API must be called after the ENET_GetRxFrameSizeMultiRing and before the ENET_ReadFrameMultiRing().
  1508. * If the ENET_GetRxFrameSizeMultiRing returns kStatus_ENET_RxFrameError,
  1509. * the ENET_GetRxErrBeforeReadFrameMultiRing can be used to get the exact error statistics.
  1510. *
  1511. * param handle The ENET handler structure pointer. This is the same handler pointer used in the ENET_Init.
  1512. * param eErrorStatic The error statistics structure pointer.
  1513. * param ringId The ring index, range from 0 ~ FSL_FEATURE_ENET_QUEUE - 1.
  1514. */
  1515. void ENET_GetRxErrBeforeReadFrameMultiRing(enet_handle_t *handle,
  1516. enet_data_error_stats_t *eErrorStatic,
  1517. uint32_t ringId)
  1518. {
  1519. assert(handle);
  1520. assert(eErrorStatic);
  1521. assert(ringId < FSL_FEATURE_ENET_QUEUE);
  1522. uint16_t control = 0;
  1523. volatile enet_rx_bd_struct_t *curBuffDescrip = handle->rxBdCurrent[ringId];
  1524. do
  1525. {
  1526. /* The last buffer descriptor of a frame. */
  1527. if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK)
  1528. {
  1529. control = curBuffDescrip->control;
  1530. if (control & ENET_BUFFDESCRIPTOR_RX_TRUNC_MASK)
  1531. {
  1532. /* The receive truncate error. */
  1533. eErrorStatic->statsRxTruncateErr++;
  1534. }
  1535. if (control & ENET_BUFFDESCRIPTOR_RX_OVERRUN_MASK)
  1536. {
  1537. /* The receive over run error. */
  1538. eErrorStatic->statsRxOverRunErr++;
  1539. }
  1540. if (control & ENET_BUFFDESCRIPTOR_RX_LENVLIOLATE_MASK)
  1541. {
  1542. /* The receive length violation error. */
  1543. eErrorStatic->statsRxLenGreaterErr++;
  1544. }
  1545. if (control & ENET_BUFFDESCRIPTOR_RX_NOOCTET_MASK)
  1546. {
  1547. /* The receive alignment error. */
  1548. eErrorStatic->statsRxAlignErr++;
  1549. }
  1550. if (control & ENET_BUFFDESCRIPTOR_RX_CRC_MASK)
  1551. {
  1552. /* The receive CRC error. */
  1553. eErrorStatic->statsRxFcsErr++;
  1554. }
  1555. #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
  1556. uint16_t controlExt = curBuffDescrip->controlExtend1;
  1557. if (controlExt & ENET_BUFFDESCRIPTOR_RX_MACERR_MASK)
  1558. {
  1559. /* The MAC error. */
  1560. eErrorStatic->statsRxMacErr++;
  1561. }
  1562. if (controlExt & ENET_BUFFDESCRIPTOR_RX_PHYERR_MASK)
  1563. {
  1564. /* The PHY error. */
  1565. eErrorStatic->statsRxPhyErr++;
  1566. }
  1567. if (controlExt & ENET_BUFFDESCRIPTOR_RX_COLLISION_MASK)
  1568. {
  1569. /* The receive collision error. */
  1570. eErrorStatic->statsRxCollisionErr++;
  1571. }
  1572. #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
  1573. break;
  1574. }
  1575. /* Increase the buffer descriptor, if it is the last one, increase to first one of the ring buffer. */
  1576. if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK)
  1577. {
  1578. curBuffDescrip = handle->rxBdBase[ringId];
  1579. }
  1580. else
  1581. {
  1582. curBuffDescrip++;
  1583. }
  1584. } while (curBuffDescrip != handle->rxBdCurrent[ringId]);
  1585. }
  1586. /*!
  1587. * brief Gets the size of the read frame for extended mutli-ring.
  1588. *
  1589. * This function gets a received frame size from the ENET buffer descriptors.
  1590. * note The FCS of the frame is automatically removed by MAC and the size is the length without the FCS.
  1591. * After calling ENET_GetRxFrameSizeMultiRing, ENET_ReadFrameMultiRing() should be called to update the
  1592. * receive buffers If the result is not "kStatus_ENET_RxFrameEmpty". The usage is
  1593. * the same to the single ring, refer to ENET_GetRxFrameSize.
  1594. *
  1595. * param handle The ENET handler structure. This is the same handler pointer used in the ENET_Init.
  1596. * param length The length of the valid frame received.
  1597. * param ringId The ring index or ring number;
  1598. * retval kStatus_ENET_RxFrameEmpty No frame received. Should not call ENET_ReadFrameMultiRing to read frame.
  1599. * retval kStatus_ENET_RxFrameError Data error happens. ENET_ReadFrameMultiRing should be called with NULL data
  1600. * and NULL length to update the receive buffers.
  1601. * retval kStatus_Success Receive a frame Successfully then the ENET_ReadFrame
  1602. * should be called with the right data buffer and the captured data length input.
  1603. */
  1604. status_t ENET_GetRxFrameSizeMultiRing(enet_handle_t *handle, uint32_t *length, uint32_t ringId)
  1605. {
  1606. assert(handle);
  1607. assert(length);
  1608. assert(ringId < FSL_FEATURE_ENET_QUEUE);
  1609. /* Reset the length to zero. */
  1610. *length = 0;
  1611. uint16_t validLastMask = ENET_BUFFDESCRIPTOR_RX_LAST_MASK | ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK;
  1612. volatile enet_rx_bd_struct_t *curBuffDescrip;
  1613. curBuffDescrip = handle->rxBdCurrent[ringId];
  1614. /* Check the current buffer descriptor's empty flag. if empty means there is no frame received. */
  1615. if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK)
  1616. {
  1617. return kStatus_ENET_RxFrameEmpty;
  1618. }
  1619. do
  1620. {
  1621. /* Add check for abnormal case. */
  1622. if ((!(curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK)) && (!curBuffDescrip->length))
  1623. {
  1624. return kStatus_ENET_RxFrameError;
  1625. }
  1626. /* Find the last buffer descriptor. */
  1627. if ((curBuffDescrip->control & validLastMask) == ENET_BUFFDESCRIPTOR_RX_LAST_MASK)
  1628. {
  1629. /* The last buffer descriptor in the frame check the status of the received frame. */
  1630. if ((curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_ERR_MASK)
  1631. #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
  1632. || (curBuffDescrip->controlExtend1 & ENET_BUFFDESCRIPTOR_RX_EXT_ERR_MASK)
  1633. #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
  1634. )
  1635. {
  1636. return kStatus_ENET_RxFrameError;
  1637. }
  1638. /* FCS is removed by MAC. */
  1639. *length = curBuffDescrip->length;
  1640. return kStatus_Success;
  1641. }
  1642. /* Increase the buffer descriptor, if it is the last one, increase to first one of the ring buffer. */
  1643. if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK)
  1644. {
  1645. curBuffDescrip = handle->rxBdBase[ringId];
  1646. }
  1647. else
  1648. {
  1649. curBuffDescrip++;
  1650. }
  1651. } while (curBuffDescrip != handle->rxBdCurrent[ringId]);
  1652. /* The frame is on processing - set to empty status to make application to receive it next time. */
  1653. return kStatus_ENET_RxFrameEmpty;
  1654. }
  1655. /*!
  1656. * brief Reads a frame from the ENET device for multi-ring.
  1657. *
  1658. * This function reads a frame (both the data and the length) from the ENET buffer descriptors.
  1659. * The ENET_GetRxFrameSizeMultiRing should be used to get the size of the prepared data buffer.
  1660. * This usage is the same as the single ring, refer to ENET_ReadFrame.
  1661. * param base ENET peripheral base address.
  1662. * param handle The ENET handler structure. This is the same handler pointer used in the ENET_Init.
  1663. * param data The data buffer provided by user to store the frame which memory size should be at least "length".
  1664. * param length The size of the data buffer which is still the length of the received frame.
  1665. * param ringId The ring index or ring number;
  1666. * return The execute status, successful or failure.
  1667. */
  1668. status_t ENET_ReadFrameMultiRing(
  1669. ENET_Type *base, enet_handle_t *handle, uint8_t *data, uint32_t length, uint32_t ringId)
  1670. {
  1671. assert(handle);
  1672. assert(ringId < FSL_FEATURE_ENET_QUEUE);
  1673. uint32_t len = 0;
  1674. uint32_t offset = 0;
  1675. uint16_t control;
  1676. bool isLastBuff = false;
  1677. volatile enet_rx_bd_struct_t *curBuffDescrip = handle->rxBdCurrent[ringId];
  1678. status_t result = kStatus_Success;
  1679. uint32_t address;
  1680. /* For data-NULL input, only update the buffer descriptor. */
  1681. if (!data)
  1682. {
  1683. do
  1684. {
  1685. /* Update the control flag. */
  1686. control = handle->rxBdCurrent[ringId]->control;
  1687. /* Updates the receive buffer descriptors. */
  1688. ENET_UpdateReadBuffers(base, handle, ringId);
  1689. /* Find the last buffer descriptor for the frame. */
  1690. if (control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK)
  1691. {
  1692. break;
  1693. }
  1694. } while (handle->rxBdCurrent[ringId] != curBuffDescrip);
  1695. return result;
  1696. }
  1697. else
  1698. {
  1699. /* A frame on one buffer or several receive buffers are both considered. */
  1700. #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
  1701. address = MEMORY_ConvertMemoryMapAddress((uint32_t)curBuffDescrip->buffer, kMEMORY_DMA2Local);
  1702. #else
  1703. address = (uint32_t)curBuffDescrip->buffer;
  1704. #endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
  1705. #if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
  1706. /* Add the cache invalidate maintain. */
  1707. DCACHE_InvalidateByRange(address, handle->rxBuffSizeAlign[ringId]);
  1708. #endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
  1709. #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
  1710. enet_ptp_time_data_t ptpTimestamp;
  1711. bool isPtpEventMessage = false;
  1712. /* Parse the PTP message according to the header message. */
  1713. isPtpEventMessage = ENET_Ptp1588ParseFrame((uint8_t *)address, &ptpTimestamp, false);
  1714. #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
  1715. while (!isLastBuff)
  1716. {
  1717. /* The last buffer descriptor of a frame. */
  1718. if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK)
  1719. {
  1720. /* This is a valid frame. */
  1721. isLastBuff = true;
  1722. if (length == curBuffDescrip->length)
  1723. {
  1724. /* Copy the frame to user's buffer without FCS. */
  1725. len = curBuffDescrip->length - offset;
  1726. memcpy(data + offset, (void *)address, len);
  1727. #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
  1728. /* Store the PTP 1588 timestamp for received PTP event frame. */
  1729. if (isPtpEventMessage)
  1730. {
  1731. /* Set the timestamp to the timestamp ring. */
  1732. ptpTimestamp.timeStamp.nanosecond = curBuffDescrip->timestamp;
  1733. result = ENET_StoreRxFrameTime(base, handle, &ptpTimestamp);
  1734. }
  1735. #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
  1736. /* Updates the receive buffer descriptors. */
  1737. ENET_UpdateReadBuffers(base, handle, ringId);
  1738. return result;
  1739. }
  1740. else
  1741. {
  1742. /* Updates the receive buffer descriptors. */
  1743. ENET_UpdateReadBuffers(base, handle, ringId);
  1744. }
  1745. }
  1746. else
  1747. {
  1748. /* Store a frame on several buffer descriptors. */
  1749. isLastBuff = false;
  1750. /* Length check. */
  1751. if (offset >= length)
  1752. {
  1753. break;
  1754. }
  1755. memcpy(data + offset, (void *)address, handle->rxBuffSizeAlign[ringId]);
  1756. offset += handle->rxBuffSizeAlign[ringId];
  1757. /* Updates the receive buffer descriptors. */
  1758. ENET_UpdateReadBuffers(base, handle, ringId);
  1759. }
  1760. /* Get the current buffer descriptor. */
  1761. curBuffDescrip = handle->rxBdCurrent[ringId];
  1762. #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
  1763. address = MEMORY_ConvertMemoryMapAddress((uint32_t)curBuffDescrip->buffer, kMEMORY_DMA2Local);
  1764. #else
  1765. address = (uint32_t)curBuffDescrip->buffer;
  1766. #endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
  1767. #if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
  1768. /* Add the cache invalidate maintain. */
  1769. DCACHE_InvalidateByRange(address, handle->rxBuffSizeAlign[ringId]);
  1770. #endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
  1771. }
  1772. }
  1773. return kStatus_ENET_RxFrameFail;
  1774. }
  1775. /*!
  1776. * brief Transmits an ENET frame for extended multi-ring.
  1777. * note The CRC is automatically appended to the data. Input the data
  1778. * to send without the CRC.
  1779. *
  1780. * In this API, multiple-ring are mainly used for extended avb frames are supported.
  1781. * The transmit scheme for avb frames is the credit-based scheme, the AVB class A, AVB class B
  1782. * and the non-AVB frame are transmitted in ring 1, ring 2 and ring 0 independently.
  1783. * So application should care about the transmit ring index when use multiple-ring transmission.
  1784. *
  1785. * param base ENET peripheral base address.
  1786. * param handle The ENET handler pointer. This is the same handler pointer used in the ENET_Init.
  1787. * param data The data buffer provided by user to be send.
  1788. * param length The length of the data to be send.
  1789. * param ringId The ring index for transmission.
  1790. * retval kStatus_Success Send frame succeed.
  1791. * retval kStatus_ENET_TxFrameBusy Transmit buffer descriptor is busy under transmission.
  1792. * The transmit busy happens when the data send rate is over the MAC capacity.
  1793. * The waiting mechanism is recommended to be added after each call return with
  1794. * kStatus_ENET_TxFrameBusy.
  1795. */
  1796. status_t ENET_SendFrameMultiRing(
  1797. ENET_Type *base, enet_handle_t *handle, uint8_t *data, uint32_t length, uint32_t ringId)
  1798. {
  1799. assert(handle);
  1800. assert(data);
  1801. assert(ringId < FSL_FEATURE_ENET_QUEUE);
  1802. volatile enet_tx_bd_struct_t *curBuffDescrip;
  1803. uint32_t len = 0;
  1804. uint32_t sizeleft = 0;
  1805. uint32_t address;
  1806. /* Check the frame length. */
  1807. if (length > ENET_FRAME_MAX_FRAMELEN)
  1808. {
  1809. return kStatus_ENET_TxFrameOverLen;
  1810. }
  1811. /* Check if the transmit buffer is ready. */
  1812. curBuffDescrip = handle->txBdCurrent[ringId];
  1813. if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK)
  1814. {
  1815. return kStatus_ENET_TxFrameBusy;
  1816. }
  1817. #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
  1818. bool isPtpEventMessage = false;
  1819. /* Check PTP message with the PTP header. */
  1820. isPtpEventMessage = ENET_Ptp1588ParseFrame(data, NULL, true);
  1821. #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
  1822. /* One transmit buffer is enough for one frame. */
  1823. if (handle->txBuffSizeAlign[ringId] >= length)
  1824. {
  1825. /* Copy data to the buffer for uDMA transfer. */
  1826. #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
  1827. address = MEMORY_ConvertMemoryMapAddress((uint32_t)curBuffDescrip->buffer, kMEMORY_DMA2Local);
  1828. #else
  1829. address = (uint32_t)curBuffDescrip->buffer;
  1830. #endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
  1831. memcpy((void *)address, data, length);
  1832. #if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
  1833. /* Add the cache clean maintain. */
  1834. DCACHE_CleanByRange(address, length);
  1835. #endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
  1836. /* Set data length. */
  1837. curBuffDescrip->length = length;
  1838. #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
  1839. /* For enable the timestamp. */
  1840. if (isPtpEventMessage)
  1841. {
  1842. curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK;
  1843. }
  1844. else
  1845. {
  1846. curBuffDescrip->controlExtend1 &= ~ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK;
  1847. }
  1848. #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
  1849. curBuffDescrip->control |= (ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK);
  1850. /* Increase the buffer descriptor address. */
  1851. if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_WRAP_MASK)
  1852. {
  1853. handle->txBdCurrent[ringId] = handle->txBdBase[ringId];
  1854. }
  1855. else
  1856. {
  1857. handle->txBdCurrent[ringId]++;
  1858. }
  1859. /* Active the transmit buffer descriptor. */
  1860. ENET_ActiveSend(base, ringId);
  1861. return kStatus_Success;
  1862. }
  1863. else
  1864. {
  1865. /* One frame requires more than one transmit buffers. */
  1866. do
  1867. {
  1868. #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
  1869. /* For enable the timestamp. */
  1870. if (isPtpEventMessage)
  1871. {
  1872. curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK;
  1873. }
  1874. else
  1875. {
  1876. curBuffDescrip->controlExtend1 &= ~ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK;
  1877. }
  1878. #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
  1879. /* Increase the buffer descriptor address. */
  1880. if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_WRAP_MASK)
  1881. {
  1882. handle->txBdCurrent[ringId] = handle->txBdBase[ringId];
  1883. }
  1884. else
  1885. {
  1886. handle->txBdCurrent[ringId]++;
  1887. }
  1888. /* update the size left to be transmit. */
  1889. sizeleft = length - len;
  1890. #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
  1891. address = MEMORY_ConvertMemoryMapAddress((uint32_t)curBuffDescrip->buffer, kMEMORY_DMA2Local);
  1892. #else
  1893. address = (uint32_t)curBuffDescrip->buffer;
  1894. #endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
  1895. if (sizeleft > handle->txBuffSizeAlign[ringId])
  1896. {
  1897. /* Data copy. */
  1898. memcpy((void *)address, data + len, handle->txBuffSizeAlign[ringId]);
  1899. #if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
  1900. /* Add the cache clean maintain. */
  1901. DCACHE_CleanByRange(address, handle->txBuffSizeAlign[ringId]);
  1902. #endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
  1903. /* Data length update. */
  1904. curBuffDescrip->length = handle->txBuffSizeAlign[ringId];
  1905. len += handle->txBuffSizeAlign[ringId];
  1906. /* Sets the control flag. */
  1907. curBuffDescrip->control &= ~ENET_BUFFDESCRIPTOR_TX_LAST_MASK;
  1908. curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_READY_MASK;
  1909. /* Active the transmit buffer descriptor*/
  1910. ENET_ActiveSend(base, ringId);
  1911. }
  1912. else
  1913. {
  1914. memcpy((void *)address, data + len, sizeleft);
  1915. #if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
  1916. /* Add the cache clean maintain. */
  1917. DCACHE_CleanByRange(address, sizeleft);
  1918. #endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
  1919. curBuffDescrip->length = sizeleft;
  1920. /* Set Last buffer wrap flag. */
  1921. curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK;
  1922. /* Active the transmit buffer descriptor. */
  1923. ENET_ActiveSend(base, ringId);
  1924. return kStatus_Success;
  1925. }
  1926. /* Get the current buffer descriptor address. */
  1927. curBuffDescrip = handle->txBdCurrent[ringId];
  1928. } while (!(curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK));
  1929. return kStatus_ENET_TxFrameBusy;
  1930. }
  1931. }
  1932. #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
  1933. /*!
  1934. * brief Adds the ENET device to a multicast group.
  1935. *
  1936. * param base ENET peripheral base address.
  1937. * param address The six-byte multicast group address which is provided by application.
  1938. */
  1939. void ENET_AddMulticastGroup(ENET_Type *base, uint8_t *address)
  1940. {
  1941. assert(address);
  1942. uint32_t crc = 0xFFFFFFFFU;
  1943. uint32_t count1 = 0;
  1944. uint32_t count2 = 0;
  1945. /* Calculates the CRC-32 polynomial on the multicast group address. */
  1946. for (count1 = 0; count1 < ENET_FRAME_MACLEN; count1++)
  1947. {
  1948. uint8_t c = address[count1];
  1949. for (count2 = 0; count2 < 0x08U; count2++)
  1950. {
  1951. if ((c ^ crc) & 1U)
  1952. {
  1953. crc >>= 1U;
  1954. c >>= 1U;
  1955. crc ^= 0xEDB88320U;
  1956. }
  1957. else
  1958. {
  1959. crc >>= 1U;
  1960. c >>= 1U;
  1961. }
  1962. }
  1963. }
  1964. /* Enable a multicast group address. */
  1965. if (!((crc >> 0x1FU) & 1U))
  1966. {
  1967. base->GALR |= 1U << ((crc >> 0x1AU) & 0x1FU);
  1968. }
  1969. else
  1970. {
  1971. base->GAUR |= 1U << ((crc >> 0x1AU) & 0x1FU);
  1972. }
  1973. }
  1974. /*!
  1975. * brief Moves the ENET device from a multicast group.
  1976. *
  1977. * param base ENET peripheral base address.
  1978. * param address The six-byte multicast group address which is provided by application.
  1979. */
  1980. void ENET_LeaveMulticastGroup(ENET_Type *base, uint8_t *address)
  1981. {
  1982. assert(address);
  1983. uint32_t crc = 0xFFFFFFFFU;
  1984. uint32_t count1 = 0;
  1985. uint32_t count2 = 0;
  1986. /* Calculates the CRC-32 polynomial on the multicast group address. */
  1987. for (count1 = 0; count1 < ENET_FRAME_MACLEN; count1++)
  1988. {
  1989. uint8_t c = address[count1];
  1990. for (count2 = 0; count2 < 0x08U; count2++)
  1991. {
  1992. if ((c ^ crc) & 1U)
  1993. {
  1994. crc >>= 1U;
  1995. c >>= 1U;
  1996. crc ^= 0xEDB88320U;
  1997. }
  1998. else
  1999. {
  2000. crc >>= 1U;
  2001. c >>= 1U;
  2002. }
  2003. }
  2004. }
  2005. /* Set the hash table. */
  2006. if (!((crc >> 0x1FU) & 1U))
  2007. {
  2008. base->GALR &= ~(1U << ((crc >> 0x1AU) & 0x1FU));
  2009. }
  2010. else
  2011. {
  2012. base->GAUR &= ~(1U << ((crc >> 0x1AU) & 0x1FU));
  2013. }
  2014. }
  2015. #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
  2016. /*!
  2017. * brief Gets the ENET transmit frame statistics after the data send for single ring.
  2018. *
  2019. * This interface gets the error statistics of the transmit frame.
  2020. * Because the error information is reported by the uDMA after the data delivery, this interface
  2021. * should be called after the data transmit API. It is recommended to call this function on
  2022. * transmit interrupt handler. After calling the ENET_SendFrame, the
  2023. * transmit interrupt notifies the transmit completion.
  2024. *
  2025. * param handle The PTP handler pointer. This is the same handler pointer used in the ENET_Init.
  2026. * param eErrorStatic The error statistics structure pointer.
  2027. * return The execute status.
  2028. */
  2029. status_t ENET_GetTxErrAfterSendFrame(enet_handle_t *handle, enet_data_error_stats_t *eErrorStatic)
  2030. {
  2031. assert(handle);
  2032. assert(eErrorStatic);
  2033. uint16_t control = 0;
  2034. uint16_t controlExt = 0;
  2035. do
  2036. {
  2037. /* Get the current dirty transmit buffer descriptor. */
  2038. control = handle->txBdDirtyStatic[0]->control;
  2039. controlExt = handle->txBdDirtyStatic[0]->controlExtend0;
  2040. /* Get the control status data, If the buffer descriptor has not been processed break out. */
  2041. if (control & ENET_BUFFDESCRIPTOR_TX_READY_MASK)
  2042. {
  2043. return kStatus_ENET_TxFrameBusy;
  2044. }
  2045. /* Increase the transmit dirty static pointer. */
  2046. if (handle->txBdDirtyStatic[0]->control & ENET_BUFFDESCRIPTOR_TX_WRAP_MASK)
  2047. {
  2048. handle->txBdDirtyStatic[0] = handle->txBdBase[0];
  2049. }
  2050. else
  2051. {
  2052. handle->txBdDirtyStatic[0]++;
  2053. }
  2054. /* If the transmit buffer descriptor is ready and the last buffer descriptor, store packet statistic. */
  2055. if (control & ENET_BUFFDESCRIPTOR_TX_LAST_MASK)
  2056. {
  2057. if (controlExt & ENET_BUFFDESCRIPTOR_TX_ERR_MASK)
  2058. {
  2059. /* Transmit error. */
  2060. eErrorStatic->statsTxErr++;
  2061. }
  2062. if (controlExt & ENET_BUFFDESCRIPTOR_TX_EXCCOLLISIONERR_MASK)
  2063. {
  2064. /* Transmit excess collision error. */
  2065. eErrorStatic->statsTxExcessCollisionErr++;
  2066. }
  2067. if (controlExt & ENET_BUFFDESCRIPTOR_TX_LATECOLLISIONERR_MASK)
  2068. {
  2069. /* Transmit late collision error. */
  2070. eErrorStatic->statsTxLateCollisionErr++;
  2071. }
  2072. if (controlExt & ENET_BUFFDESCRIPTOR_TX_UNDERFLOWERR_MASK)
  2073. {
  2074. /* Transmit under flow error. */
  2075. eErrorStatic->statsTxUnderFlowErr++;
  2076. }
  2077. if (controlExt & ENET_BUFFDESCRIPTOR_TX_OVERFLOWERR_MASK)
  2078. {
  2079. /* Transmit over flow error. */
  2080. eErrorStatic->statsTxOverFlowErr++;
  2081. }
  2082. return kStatus_Success;
  2083. }
  2084. } while (handle->txBdDirtyStatic[0] != handle->txBdCurrent[0]);
  2085. return kStatus_ENET_TxFrameFail;
  2086. }
  2087. #if FSL_FEATURE_ENET_QUEUE > 1
  2088. /*!
  2089. * brief Gets the ENET transmit frame statistics after the data send for extended multi-ring.
  2090. *
  2091. * This interface gets the error statistics of the transmit frame.
  2092. * Because the error information is reported by the uDMA after the data delivery, this interface
  2093. * should be called after the data transmit API and shall be called by transmit interrupt handler.
  2094. * After calling the ENET_SendFrame, the transmit interrupt notifies the transmit completion.
  2095. *
  2096. * param handle The PTP handler pointer. This is the same handler pointer used in the ENET_Init.
  2097. * param eErrorStatic The error statistics structure pointer.
  2098. * param ringId The ring index.
  2099. * return The execute status.
  2100. */
  2101. status_t ENET_GetTxErrAfterSendFrameMultiRing(enet_handle_t *handle,
  2102. enet_data_error_stats_t *eErrorStatic,
  2103. uint32_t ringId)
  2104. {
  2105. assert(handle);
  2106. assert(eErrorStatic);
  2107. assert(ringId < FSL_FEATURE_ENET_QUEUE);
  2108. uint16_t control = 0;
  2109. uint16_t controlExt = 0;
  2110. do
  2111. {
  2112. /* Get the current dirty transmit buffer descriptor. */
  2113. control = handle->txBdDirtyStatic[ringId]->control;
  2114. controlExt = handle->txBdDirtyStatic[ringId]->controlExtend0;
  2115. /* Get the control status data, If the buffer descriptor has not been processed break out. */
  2116. if (control & ENET_BUFFDESCRIPTOR_TX_READY_MASK)
  2117. {
  2118. return kStatus_ENET_TxFrameBusy;
  2119. }
  2120. /* Increase the transmit dirty static pointer. */
  2121. if (handle->txBdDirtyStatic[ringId]->control & ENET_BUFFDESCRIPTOR_TX_WRAP_MASK)
  2122. {
  2123. handle->txBdDirtyStatic[ringId] = handle->txBdBase[ringId];
  2124. }
  2125. else
  2126. {
  2127. handle->txBdDirtyStatic[ringId]++;
  2128. }
  2129. /* If the transmit buffer descriptor is ready and the last buffer descriptor, store packet statistic. */
  2130. if (control & ENET_BUFFDESCRIPTOR_TX_LAST_MASK)
  2131. {
  2132. if (controlExt & ENET_BUFFDESCRIPTOR_TX_ERR_MASK)
  2133. {
  2134. /* Transmit error. */
  2135. eErrorStatic->statsTxErr++;
  2136. }
  2137. if (controlExt & ENET_BUFFDESCRIPTOR_TX_EXCCOLLISIONERR_MASK)
  2138. {
  2139. /* Transmit excess collision error. */
  2140. eErrorStatic->statsTxExcessCollisionErr++;
  2141. }
  2142. if (controlExt & ENET_BUFFDESCRIPTOR_TX_LATECOLLISIONERR_MASK)
  2143. {
  2144. /* Transmit late collision error. */
  2145. eErrorStatic->statsTxLateCollisionErr++;
  2146. }
  2147. if (controlExt & ENET_BUFFDESCRIPTOR_TX_UNDERFLOWERR_MASK)
  2148. {
  2149. /* Transmit under flow error. */
  2150. eErrorStatic->statsTxUnderFlowErr++;
  2151. }
  2152. if (controlExt & ENET_BUFFDESCRIPTOR_TX_OVERFLOWERR_MASK)
  2153. {
  2154. /* Transmit over flow error. */
  2155. eErrorStatic->statsTxOverFlowErr++;
  2156. }
  2157. return kStatus_Success;
  2158. }
  2159. } while (handle->txBdDirtyStatic[ringId] != handle->txBdCurrent[ringId]);
  2160. return kStatus_ENET_TxFrameFail;
  2161. }
  2162. #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
  2163. static bool ENET_Ptp1588ParseFrame(const uint8_t *data, enet_ptp_time_data_t *ptpTsData, bool isFastEnabled)
  2164. {
  2165. assert(data);
  2166. if (!isFastEnabled)
  2167. {
  2168. assert(ptpTsData);
  2169. }
  2170. bool isPtpMsg = false;
  2171. const uint8_t *buffer = data;
  2172. uint16_t ptpType;
  2173. /* Check for VLAN frame.
  2174. * Add Double vlan tag check for receiving extended QIN vlan frame. */
  2175. if (*(uint16_t *)(buffer + ENET_PTP1588_ETHL2_PACKETTYPE_OFFSET) == (ENET_HTONS(ENET_8021QVLAN)
  2176. #if defined(FSL_FEATUR_ENET_HAS_AVB) && FSL_FEATURE_HAS_AVB
  2177. || ENET_HTONS(ENET_8021QSVLAN)
  2178. #endif /* FSL_FEATURE_ENET_HAS_AVB */
  2179. ))
  2180. {
  2181. buffer += ENET_FRAME_VLAN_TAGLEN;
  2182. #if defined(FSL_FEATUR_ENET_HAS_AVB) && FSL_FEATURE_HAS_AVB
  2183. if (*(uint16_t *)(buffer + ENET_PTP1588_ETHL2_PACKETTYPE_OFFSET) == ENET_HTONS(ENET_8021QVLAN)
  2184. {
  2185. buffer += ENET_FRAME_VLAN_TAGLEN;
  2186. }
  2187. #endif /* FSL_FEATURE_ENET_HAS_AVB */
  2188. }
  2189. ptpType = *(uint16_t *)(buffer + ENET_PTP1588_ETHL2_PACKETTYPE_OFFSET);
  2190. switch (ENET_HTONS(ptpType))
  2191. { /* Ethernet layer 2. */
  2192. case ENET_ETHERNETL2:
  2193. if ((*(uint8_t *)(buffer + ENET_PTP1588_ETHL2_MSGTYPE_OFFSET) & 0x0F) <= kENET_PtpEventMsgType)
  2194. {
  2195. isPtpMsg = true;
  2196. if (!isFastEnabled)
  2197. {
  2198. /* It's a ptpv2 message and store the ptp header information. */
  2199. ptpTsData->version = (*(uint8_t *)(buffer + ENET_PTP1588_ETHL2_VERSION_OFFSET)) & 0x0F;
  2200. ptpTsData->messageType = (*(uint8_t *)(buffer + ENET_PTP1588_ETHL2_MSGTYPE_OFFSET)) & 0x0F;
  2201. ptpTsData->sequenceId = ENET_HTONS(*(uint16_t *)(buffer + ENET_PTP1588_ETHL2_SEQUENCEID_OFFSET));
  2202. memcpy((void *)&ptpTsData->sourcePortId[0], (void *)(buffer + ENET_PTP1588_ETHL2_CLOCKID_OFFSET),
  2203. kENET_PtpSrcPortIdLen);
  2204. }
  2205. }
  2206. break;
  2207. /* IPV4. */
  2208. case ENET_IPV4:
  2209. if ((*(uint8_t *)(buffer + ENET_PTP1588_IPVERSION_OFFSET) >> 4) == ENET_IPV4VERSION)
  2210. {
  2211. if (((*(uint16_t *)(buffer + ENET_PTP1588_IPV4_UDP_PORT_OFFSET)) == ENET_HTONS(kENET_PtpEventPort)) &&
  2212. (*(uint8_t *)(buffer + ENET_PTP1588_IPV4_UDP_PROTOCOL_OFFSET) == ENET_UDPVERSION))
  2213. {
  2214. /* Set the PTP message flag. */
  2215. isPtpMsg = true;
  2216. if (!isFastEnabled)
  2217. {
  2218. /* It's a IPV4 ptp message and store the ptp header information. */
  2219. ptpTsData->version = (*(uint8_t *)(buffer + ENET_PTP1588_IPV4_UDP_VERSION_OFFSET)) & 0x0F;
  2220. ptpTsData->messageType = (*(uint8_t *)(buffer + ENET_PTP1588_IPV4_UDP_MSGTYPE_OFFSET)) & 0x0F;
  2221. ptpTsData->sequenceId =
  2222. ENET_HTONS(*(uint16_t *)(buffer + ENET_PTP1588_IPV4_UDP_SEQUENCEID_OFFSET));
  2223. memcpy((void *)&ptpTsData->sourcePortId[0],
  2224. (void *)(buffer + ENET_PTP1588_IPV4_UDP_CLKID_OFFSET), kENET_PtpSrcPortIdLen);
  2225. }
  2226. }
  2227. }
  2228. break;
  2229. /* IPV6. */
  2230. case ENET_IPV6:
  2231. if ((*(uint8_t *)(buffer + ENET_PTP1588_IPVERSION_OFFSET) >> 4) == ENET_IPV6VERSION)
  2232. {
  2233. if (((*(uint16_t *)(buffer + ENET_PTP1588_IPV6_UDP_PORT_OFFSET)) == ENET_HTONS(kENET_PtpEventPort)) &&
  2234. (*(uint8_t *)(buffer + ENET_PTP1588_IPV6_UDP_PROTOCOL_OFFSET) == ENET_UDPVERSION))
  2235. {
  2236. /* Set the PTP message flag. */
  2237. isPtpMsg = true;
  2238. if (!isFastEnabled)
  2239. {
  2240. /* It's a IPV6 ptp message and store the ptp header information. */
  2241. ptpTsData->version = (*(uint8_t *)(buffer + ENET_PTP1588_IPV6_UDP_VERSION_OFFSET)) & 0x0F;
  2242. ptpTsData->messageType = (*(uint8_t *)(buffer + ENET_PTP1588_IPV6_UDP_MSGTYPE_OFFSET)) & 0x0F;
  2243. ptpTsData->sequenceId =
  2244. ENET_HTONS(*(uint16_t *)(buffer + ENET_PTP1588_IPV6_UDP_SEQUENCEID_OFFSET));
  2245. memcpy((void *)&ptpTsData->sourcePortId[0],
  2246. (void *)(buffer + ENET_PTP1588_IPV6_UDP_CLKID_OFFSET), kENET_PtpSrcPortIdLen);
  2247. }
  2248. }
  2249. }
  2250. break;
  2251. default:
  2252. break;
  2253. }
  2254. return isPtpMsg;
  2255. }
  2256. /*!
  2257. * brief Configures the ENET PTP IEEE 1588 feature with the basic configuration.
  2258. * The function sets the clock for PTP 1588 timer and enables
  2259. * time stamp interrupts and transmit interrupts for PTP 1588 features.
  2260. * This API should be called when the 1588 feature is enabled
  2261. * or the ENET_ENHANCEDBUFFERDESCRIPTOR_MODE is defined.
  2262. * ENET_Init should be called before calling this API.
  2263. *
  2264. * note The PTP 1588 time-stamp second increase though time-stamp interrupt handler
  2265. * and the transmit time-stamp store is done through transmit interrupt handler.
  2266. * As a result, the TS interrupt and TX interrupt are enabled when you call this API.
  2267. *
  2268. * param base ENET peripheral base address.
  2269. * param handle ENET handler pointer.
  2270. * param ptpConfig The ENET PTP1588 configuration.
  2271. */
  2272. void ENET_Ptp1588Configure(ENET_Type *base, enet_handle_t *handle, enet_ptp_config_t *ptpConfig)
  2273. {
  2274. assert(handle);
  2275. assert(ptpConfig);
  2276. uint8_t count;
  2277. uint32_t instance = ENET_GetInstance(base);
  2278. uint32_t mask = kENET_TxBufferInterrupt;
  2279. #if FSL_FEATURE_ENET_QUEUE > 1
  2280. mask |= kENET_TxBuffer1Interrupt | kENET_TxBuffer2Interrupt;
  2281. #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
  2282. /* Start the 1588 timer. */
  2283. ENET_Ptp1588StartTimer(base, ptpConfig->ptp1588ClockSrc_Hz);
  2284. for (count = 0; count < handle->ringNum; count++)
  2285. {
  2286. handle->txBdDirtyTime[count] = handle->txBdBase[count];
  2287. handle->txBdDirtyStatic[count] = handle->txBdBase[count];
  2288. }
  2289. /* Setting the receive and transmit state for transaction. */
  2290. handle->rxPtpTsDataRing.ptpTsData = ptpConfig->rxPtpTsData;
  2291. handle->rxPtpTsDataRing.size = ptpConfig->ptpTsRxBuffNum;
  2292. handle->rxPtpTsDataRing.front = 0;
  2293. handle->rxPtpTsDataRing.end = 0;
  2294. handle->txPtpTsDataRing.ptpTsData = ptpConfig->txPtpTsData;
  2295. handle->txPtpTsDataRing.size = ptpConfig->ptpTsTxBuffNum;
  2296. handle->txPtpTsDataRing.front = 0;
  2297. handle->txPtpTsDataRing.end = 0;
  2298. handle->msTimerSecond = 0;
  2299. /* Set the IRQ handler when the interrupt is enabled. */
  2300. s_enetTxIsr = ENET_TransmitIRQHandler;
  2301. s_enetTsIsr = ENET_Ptp1588TimerIRQHandler;
  2302. /* Enables the time stamp interrupt and transmit frame interrupt to
  2303. * handle the time-stamp . */
  2304. ENET_EnableInterrupts(base, (ENET_TS_INTERRUPT | ENET_TX_INTERRUPT));
  2305. ENET_DisableInterrupts(base, mask);
  2306. EnableIRQ(s_enetTsIrqId[instance]);
  2307. EnableIRQ(s_enetTxIrqId[instance]);
  2308. }
  2309. /*!
  2310. * brief Starts the ENET PTP 1588 Timer.
  2311. * This function is used to initialize the PTP timer. After the PTP starts,
  2312. * the PTP timer starts running.
  2313. *
  2314. * param base ENET peripheral base address.
  2315. * param ptpClkSrc The clock source of the PTP timer.
  2316. */
  2317. void ENET_Ptp1588StartTimer(ENET_Type *base, uint32_t ptpClkSrc)
  2318. {
  2319. /* Restart PTP 1588 timer, master clock. */
  2320. base->ATCR = ENET_ATCR_RESTART_MASK;
  2321. /* Initializes PTP 1588 timer. */
  2322. base->ATINC = ENET_ATINC_INC(ENET_NANOSECOND_ONE_SECOND / ptpClkSrc);
  2323. base->ATPER = ENET_NANOSECOND_ONE_SECOND;
  2324. /* Sets periodical event and the event signal output assertion and Actives PTP 1588 timer. */
  2325. base->ATCR = ENET_ATCR_PEREN_MASK | ENET_ATCR_PINPER_MASK | ENET_ATCR_EN_MASK;
  2326. }
  2327. /*!
  2328. * brief Gets the current ENET time from the PTP 1588 timer.
  2329. *
  2330. * param base ENET peripheral base address.
  2331. * param handle The ENET state pointer. This is the same state pointer used in the ENET_Init.
  2332. * param ptpTime The PTP timer structure.
  2333. */
  2334. void ENET_Ptp1588GetTimer(ENET_Type *base, enet_handle_t *handle, enet_ptp_time_t *ptpTime)
  2335. {
  2336. assert(handle);
  2337. assert(ptpTime);
  2338. uint16_t count = ENET_1588TIME_DELAY_COUNT;
  2339. uint32_t primask;
  2340. /* Disables the interrupt. */
  2341. primask = DisableGlobalIRQ();
  2342. /* Get the current PTP time. */
  2343. ptpTime->second = handle->msTimerSecond;
  2344. /* Get the nanosecond from the master timer. */
  2345. base->ATCR |= ENET_ATCR_CAPTURE_MASK;
  2346. /* Add at least six clock cycle delay to get accurate time.
  2347. It's the requirement when the 1588 clock source is slower
  2348. than the register clock.
  2349. */
  2350. while (count--)
  2351. {
  2352. __NOP();
  2353. }
  2354. /* Get the captured time. */
  2355. ptpTime->nanosecond = base->ATVR;
  2356. /* Enables the interrupt. */
  2357. EnableGlobalIRQ(primask);
  2358. }
  2359. /*!
  2360. * brief Sets the ENET PTP 1588 timer to the assigned time.
  2361. *
  2362. * param base ENET peripheral base address.
  2363. * param handle The ENET state pointer. This is the same state pointer used in the ENET_Init.
  2364. * param ptpTime The timer to be set to the PTP timer.
  2365. */
  2366. void ENET_Ptp1588SetTimer(ENET_Type *base, enet_handle_t *handle, enet_ptp_time_t *ptpTime)
  2367. {
  2368. assert(handle);
  2369. assert(ptpTime);
  2370. uint32_t primask;
  2371. /* Disables the interrupt. */
  2372. primask = DisableGlobalIRQ();
  2373. /* Sets PTP timer. */
  2374. handle->msTimerSecond = ptpTime->second;
  2375. base->ATVR = ptpTime->nanosecond;
  2376. /* Enables the interrupt. */
  2377. EnableGlobalIRQ(primask);
  2378. }
  2379. /*!
  2380. * brief Adjusts the ENET PTP 1588 timer.
  2381. *
  2382. * param base ENET peripheral base address.
  2383. * param corrIncrease The correction increment value. This value is added every time the correction
  2384. * timer expires. A value less than the PTP timer frequency(1/ptpClkSrc) slows down the timer,
  2385. * a value greater than the 1/ptpClkSrc speeds up the timer.
  2386. * param corrPeriod The PTP timer correction counter wrap-around value. This defines after how
  2387. * many timer clock the correction counter should be reset and trigger a correction
  2388. * increment on the timer. A value of 0 disables the correction counter and no correction occurs.
  2389. */
  2390. void ENET_Ptp1588AdjustTimer(ENET_Type *base, uint32_t corrIncrease, uint32_t corrPeriod)
  2391. {
  2392. /* Set correction for PTP timer increment. */
  2393. base->ATINC = (base->ATINC & ~ENET_ATINC_INC_CORR_MASK) | (corrIncrease << ENET_ATINC_INC_CORR_SHIFT);
  2394. /* Set correction for PTP timer period. */
  2395. base->ATCOR = (base->ATCOR & ~ENET_ATCOR_COR_MASK) | (corrPeriod << ENET_ATCOR_COR_SHIFT);
  2396. }
  2397. static status_t ENET_Ptp1588UpdateTimeRing(enet_ptp_time_data_ring_t *ptpTsDataRing, enet_ptp_time_data_t *ptpTimeData)
  2398. {
  2399. assert(ptpTsDataRing);
  2400. assert(ptpTsDataRing->ptpTsData);
  2401. assert(ptpTimeData);
  2402. uint16_t usedBuffer = 0;
  2403. /* Check if the buffers ring is full. */
  2404. if (ptpTsDataRing->end >= ptpTsDataRing->front)
  2405. {
  2406. usedBuffer = ptpTsDataRing->end - ptpTsDataRing->front;
  2407. }
  2408. else
  2409. {
  2410. usedBuffer = ptpTsDataRing->size - (ptpTsDataRing->front - ptpTsDataRing->end);
  2411. }
  2412. if (usedBuffer == ptpTsDataRing->size)
  2413. {
  2414. return kStatus_ENET_PtpTsRingFull;
  2415. }
  2416. /* Copy the new data into the buffer. */
  2417. memcpy((ptpTsDataRing->ptpTsData + ptpTsDataRing->end), ptpTimeData, sizeof(enet_ptp_time_data_t));
  2418. /* Increase the buffer pointer to the next empty one. */
  2419. ptpTsDataRing->end = (ptpTsDataRing->end + 1) % ptpTsDataRing->size;
  2420. return kStatus_Success;
  2421. }
  2422. static status_t ENET_Ptp1588SearchTimeRing(enet_ptp_time_data_ring_t *ptpTsDataRing, enet_ptp_time_data_t *ptpTimedata)
  2423. {
  2424. assert(ptpTsDataRing);
  2425. assert(ptpTsDataRing->ptpTsData);
  2426. assert(ptpTimedata);
  2427. uint32_t index;
  2428. uint32_t size;
  2429. uint16_t usedBuffer = 0;
  2430. /* Check the PTP 1588 timestamp ring. */
  2431. if (ptpTsDataRing->front == ptpTsDataRing->end)
  2432. {
  2433. return kStatus_ENET_PtpTsRingEmpty;
  2434. }
  2435. /* Search the element in the ring buffer */
  2436. index = ptpTsDataRing->front;
  2437. size = ptpTsDataRing->size;
  2438. while (index != ptpTsDataRing->end)
  2439. {
  2440. if (((ptpTsDataRing->ptpTsData + index)->sequenceId == ptpTimedata->sequenceId) &&
  2441. (!memcmp(((void *)&(ptpTsDataRing->ptpTsData + index)->sourcePortId[0]),
  2442. (void *)&ptpTimedata->sourcePortId[0], kENET_PtpSrcPortIdLen)) &&
  2443. ((ptpTsDataRing->ptpTsData + index)->version == ptpTimedata->version) &&
  2444. ((ptpTsDataRing->ptpTsData + index)->messageType == ptpTimedata->messageType))
  2445. {
  2446. break;
  2447. }
  2448. /* Increase the ptp ring index. */
  2449. index = (index + 1) % size;
  2450. }
  2451. if (index == ptpTsDataRing->end)
  2452. {
  2453. /* Check if buffers is full. */
  2454. if (ptpTsDataRing->end >= ptpTsDataRing->front)
  2455. {
  2456. usedBuffer = ptpTsDataRing->end - ptpTsDataRing->front;
  2457. }
  2458. else
  2459. {
  2460. usedBuffer = ptpTsDataRing->size - (ptpTsDataRing->front - ptpTsDataRing->end);
  2461. }
  2462. if (usedBuffer == ptpTsDataRing->size)
  2463. { /* Drop one in the front. */
  2464. ptpTsDataRing->front = (ptpTsDataRing->front + 1) % size;
  2465. }
  2466. return kStatus_ENET_PtpTsRingFull;
  2467. }
  2468. /* Get the right timestamp of the required ptp messag. */
  2469. ptpTimedata->timeStamp.second = (ptpTsDataRing->ptpTsData + index)->timeStamp.second;
  2470. ptpTimedata->timeStamp.nanosecond = (ptpTsDataRing->ptpTsData + index)->timeStamp.nanosecond;
  2471. /* Increase the index. */
  2472. ptpTsDataRing->front = (ptpTsDataRing->front + 1) % size;
  2473. return kStatus_Success;
  2474. }
  2475. static status_t ENET_StoreRxFrameTime(ENET_Type *base, enet_handle_t *handle, enet_ptp_time_data_t *ptpTimeData)
  2476. {
  2477. assert(handle);
  2478. assert(ptpTimeData);
  2479. bool ptpTimerWrap = false;
  2480. enet_ptp_time_t ptpTimer;
  2481. uint32_t primask;
  2482. /* Disables the interrupt. */
  2483. primask = DisableGlobalIRQ();
  2484. /* Get current PTP timer nanosecond value. */
  2485. ENET_Ptp1588GetTimer(base, handle, &ptpTimer);
  2486. /* Get PTP timer wrap event. */
  2487. ptpTimerWrap = base->EIR & kENET_TsTimerInterrupt;
  2488. /* Get transmit time stamp second. */
  2489. if ((ptpTimer.nanosecond > ptpTimeData->timeStamp.nanosecond) ||
  2490. ((ptpTimer.nanosecond < ptpTimeData->timeStamp.nanosecond) && ptpTimerWrap))
  2491. {
  2492. ptpTimeData->timeStamp.second = handle->msTimerSecond;
  2493. }
  2494. else
  2495. {
  2496. ptpTimeData->timeStamp.second = handle->msTimerSecond - 1;
  2497. }
  2498. /* Enable the interrupt. */
  2499. EnableGlobalIRQ(primask);
  2500. /* Store the timestamp to the receive time stamp ring. */
  2501. /* Check if the buffers ring is full. */
  2502. return ENET_Ptp1588UpdateTimeRing(&handle->rxPtpTsDataRing, ptpTimeData);
  2503. }
  2504. static status_t ENET_StoreTxFrameTime(ENET_Type *base, enet_handle_t *handle, uint32_t ringId)
  2505. {
  2506. assert(handle);
  2507. uint32_t primask;
  2508. bool ptpTimerWrap;
  2509. bool isPtpEventMessage = false;
  2510. enet_ptp_time_data_t ptpTimeData;
  2511. volatile enet_tx_bd_struct_t *curBuffDescrip = handle->txBdDirtyTime[ringId];
  2512. uint32_t address;
  2513. /* Get the control status data, If the buffer descriptor has not been processed break out. */
  2514. if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK)
  2515. {
  2516. return kStatus_ENET_TxFrameBusy;
  2517. }
  2518. /* Parse the PTP message. */
  2519. #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
  2520. address = MEMORY_ConvertMemoryMapAddress((uint32_t)curBuffDescrip->buffer, kMEMORY_DMA2Local);
  2521. #else
  2522. address = (uint32_t)curBuffDescrip->buffer;
  2523. #endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
  2524. isPtpEventMessage = ENET_Ptp1588ParseFrame((uint8_t *)address, &ptpTimeData, false);
  2525. if (isPtpEventMessage)
  2526. {
  2527. /* Only store tx timestamp for ptp event message. */
  2528. do
  2529. {
  2530. /* Increase current buffer descriptor to the next one. */
  2531. if (handle->txBdDirtyTime[ringId]->control & ENET_BUFFDESCRIPTOR_TX_WRAP_MASK)
  2532. {
  2533. handle->txBdDirtyTime[ringId] = handle->txBdBase[ringId];
  2534. }
  2535. else
  2536. {
  2537. handle->txBdDirtyTime[ringId]++;
  2538. }
  2539. /* Do time stamp check on the last buffer descriptor of the frame. */
  2540. if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_LAST_MASK)
  2541. {
  2542. /* Disables the interrupt. */
  2543. primask = DisableGlobalIRQ();
  2544. /* Get current PTP timer nanosecond value. */
  2545. ENET_Ptp1588GetTimer(base, handle, &ptpTimeData.timeStamp);
  2546. /* Get PTP timer wrap event. */
  2547. ptpTimerWrap = base->EIR & kENET_TsTimerInterrupt;
  2548. /* Get transmit time stamp second. */
  2549. if ((ptpTimeData.timeStamp.nanosecond > curBuffDescrip->timestamp) ||
  2550. ((ptpTimeData.timeStamp.nanosecond < curBuffDescrip->timestamp) && ptpTimerWrap))
  2551. {
  2552. ptpTimeData.timeStamp.second = handle->msTimerSecond;
  2553. }
  2554. else
  2555. {
  2556. ptpTimeData.timeStamp.second = handle->msTimerSecond - 1;
  2557. }
  2558. /* Save transmit time stamp nanosecond. */
  2559. ptpTimeData.timeStamp.nanosecond = curBuffDescrip->timestamp;
  2560. /* Enable the interrupt. */
  2561. EnableGlobalIRQ(primask);
  2562. /* Store the timestamp to the transmit timestamp ring. */
  2563. return ENET_Ptp1588UpdateTimeRing(&handle->txPtpTsDataRing, &ptpTimeData);
  2564. }
  2565. /* Get the current transmit buffer descriptor. */
  2566. curBuffDescrip = handle->txBdDirtyTime[ringId];
  2567. /* Get the control status data, If the buffer descriptor has not been processed break out. */
  2568. if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK)
  2569. {
  2570. return kStatus_ENET_TxFrameBusy;
  2571. }
  2572. } while (handle->txBdDirtyTime[ringId] != handle->txBdCurrent[ringId]);
  2573. return kStatus_ENET_TxFrameFail;
  2574. }
  2575. else
  2576. {
  2577. /* Only increase current buffer descriptor to the next one. */
  2578. if (handle->txBdDirtyTime[ringId]->control & ENET_BUFFDESCRIPTOR_TX_WRAP_MASK)
  2579. {
  2580. handle->txBdDirtyTime[ringId] = handle->txBdBase[ringId];
  2581. }
  2582. else
  2583. {
  2584. handle->txBdDirtyTime[ringId]++;
  2585. }
  2586. }
  2587. return kStatus_Success;
  2588. }
  2589. /*!
  2590. * brief Gets the time stamp of the transmit frame.
  2591. *
  2592. * This function is used for PTP stack to get the timestamp captured by the ENET driver.
  2593. *
  2594. * param handle The ENET handler pointer.This is the same state pointer used in
  2595. * ENET_Init.
  2596. * param ptpTimeData The special PTP timestamp data for search the receive timestamp.
  2597. * retval kStatus_Success Get 1588 timestamp success.
  2598. * retval kStatus_ENET_PtpTsRingEmpty 1588 timestamp ring empty.
  2599. * retval kStatus_ENET_PtpTsRingFull 1588 timestamp ring full.
  2600. */
  2601. status_t ENET_GetTxFrameTime(enet_handle_t *handle, enet_ptp_time_data_t *ptpTimeData)
  2602. {
  2603. assert(handle);
  2604. assert(ptpTimeData);
  2605. return ENET_Ptp1588SearchTimeRing(&handle->txPtpTsDataRing, ptpTimeData);
  2606. }
  2607. /*!
  2608. * brief Gets the time stamp of the received frame.
  2609. *
  2610. * This function is used for PTP stack to get the timestamp captured by the ENET driver.
  2611. *
  2612. * param handle The ENET handler pointer.This is the same state pointer used in
  2613. * ENET_Init.
  2614. * param ptpTimeData The special PTP timestamp data for search the receive timestamp.
  2615. * retval kStatus_Success Get 1588 timestamp success.
  2616. * retval kStatus_ENET_PtpTsRingEmpty 1588 timestamp ring empty.
  2617. * retval kStatus_ENET_PtpTsRingFull 1588 timestamp ring full.
  2618. */
  2619. status_t ENET_GetRxFrameTime(enet_handle_t *handle, enet_ptp_time_data_t *ptpTimeData)
  2620. {
  2621. assert(handle);
  2622. assert(ptpTimeData);
  2623. return ENET_Ptp1588SearchTimeRing(&handle->rxPtpTsDataRing, ptpTimeData);
  2624. }
  2625. #if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB
  2626. /*!
  2627. * brief Sets the ENET AVB feature.
  2628. *
  2629. * ENET AVB feature configuration, set the Receive classification match and transmit
  2630. * bandwidth. This API is called when the AVB feature is required.
  2631. *
  2632. * Note: The AVB frames transmission scheme is credit-based tx scheme and it's only supported
  2633. * with the Enhanced buffer descriptors. so the AVB configuration should only done with
  2634. * Enhanced buffer descriptor. so when the AVB feature is required, please make sure the
  2635. * the "ENET_ENHANCEDBUFFERDESCRIPTOR_MODE" is defined.
  2636. *
  2637. * param base ENET peripheral base address.
  2638. * param handle ENET handler pointer.
  2639. * param config The ENET AVB feature configuration structure.
  2640. */
  2641. void ENET_AVBConfigure(ENET_Type *base, enet_handle_t *handle, const enet_avb_config_t *config)
  2642. {
  2643. assert(config);
  2644. uint8_t count = 0;
  2645. for (count = 0; count < FSL_FEATURE_ENET_QUEUE - 1; count++)
  2646. {
  2647. /* Set the AVB receive ring classification match when the match is not 0. */
  2648. if (config->rxClassifyMatch[count])
  2649. {
  2650. base->RCMR[count] = (config->rxClassifyMatch[count] & 0xFFFF) | ENET_RCMR_MATCHEN_MASK;
  2651. }
  2652. /* Set the dma controller for the extended ring. */
  2653. base->DMACFG[count] |= ENET_DMACFG_IDLE_SLOPE(config->idleSlope[count]);
  2654. }
  2655. /* Shall use the credit-based scheme for avb. */
  2656. base->QOS &= ~ENET_QOS_TX_SCHEME_MASK;
  2657. base->QOS |= ENET_QOS_RX_FLUSH0_MASK;
  2658. }
  2659. #endif /* FSL_FETAURE_ENET_HAS_AVB */
  2660. #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
  2661. #if FSL_FEATURE_ENET_QUEUE > 1
  2662. /*!
  2663. * brief The transmit IRQ handler.
  2664. *
  2665. * param base ENET peripheral base address.
  2666. * param handle The ENET handler pointer.
  2667. */
  2668. void ENET_TransmitIRQHandler(ENET_Type *base, enet_handle_t *handle, uint32_t ringId)
  2669. #else
  2670. /*!
  2671. * brief The transmit IRQ handler.
  2672. *
  2673. * param base ENET peripheral base address.
  2674. * param handle The ENET handler pointer.
  2675. */
  2676. void ENET_TransmitIRQHandler(ENET_Type *base, enet_handle_t *handle)
  2677. #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
  2678. {
  2679. assert(handle);
  2680. uint32_t mask = kENET_TxBufferInterrupt | kENET_TxFrameInterrupt;
  2681. #if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) || (FSL_FEATURE_ENET_QUEUE > 1)
  2682. uint32_t index = 0;
  2683. #endif /* ENET_ENHANCEDBUFFERDESCRIPTORMODE || (FSL_FEATURE_ENET_QUEUE > 1) */
  2684. /* Check if the transmit interrupt happen. */
  2685. #if FSL_FEATURE_ENET_QUEUE > 1
  2686. switch (ringId)
  2687. {
  2688. case kENET_Ring1:
  2689. mask = (kENET_TxFrame1Interrupt | kENET_TxBuffer1Interrupt);
  2690. break;
  2691. case kENET_Ring2:
  2692. mask = (kENET_TxFrame2Interrupt | kENET_TxBuffer2Interrupt);
  2693. break;
  2694. default:
  2695. break;
  2696. }
  2697. index = ringId;
  2698. #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
  2699. while (mask & base->EIR)
  2700. {
  2701. #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
  2702. if (base->EIR & kENET_TxFrameInterrupt)
  2703. {
  2704. /* Store the transmit timestamp from the buffer descriptor should be done here. */
  2705. ENET_StoreTxFrameTime(base, handle, index);
  2706. }
  2707. #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
  2708. /* Clear the transmit interrupt event. */
  2709. base->EIR = mask;
  2710. /* Callback function. */
  2711. if (handle->callback)
  2712. {
  2713. #if FSL_FEATURE_ENET_QUEUE > 1
  2714. handle->callback(base, handle, index, kENET_TxEvent, handle->userData);
  2715. #else
  2716. handle->callback(base, handle, kENET_TxEvent, handle->userData);
  2717. #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
  2718. }
  2719. }
  2720. }
  2721. #if FSL_FEATURE_ENET_QUEUE > 1
  2722. /*!
  2723. * brief The receive IRQ handler.
  2724. *
  2725. * param base ENET peripheral base address.
  2726. * param handle The ENET handler pointer.
  2727. */
  2728. void ENET_ReceiveIRQHandler(ENET_Type *base, enet_handle_t *handle, uint32_t ringId)
  2729. #else
  2730. /*!
  2731. * brief The receive IRQ handler.
  2732. *
  2733. * param base ENET peripheral base address.
  2734. * param handle The ENET handler pointer.
  2735. */
  2736. void ENET_ReceiveIRQHandler(ENET_Type *base, enet_handle_t *handle)
  2737. #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
  2738. {
  2739. assert(handle);
  2740. uint32_t mask = kENET_RxFrameInterrupt | kENET_RxBufferInterrupt;
  2741. /* Check if the receive interrupt happen. */
  2742. #if FSL_FEATURE_ENET_QUEUE > 1
  2743. switch (ringId)
  2744. {
  2745. case kENET_Ring1:
  2746. mask = (kENET_RxFrame1Interrupt | kENET_RxBuffer1Interrupt);
  2747. break;
  2748. case kENET_Ring2:
  2749. mask = (kENET_RxFrame2Interrupt | kENET_RxBuffer2Interrupt);
  2750. break;
  2751. default:
  2752. break;
  2753. }
  2754. #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
  2755. while (mask & base->EIR)
  2756. {
  2757. /* Clear the transmit interrupt event. */
  2758. base->EIR = mask;
  2759. /* Callback function. */
  2760. if (handle->callback)
  2761. {
  2762. #if FSL_FEATURE_ENET_QUEUE > 1
  2763. handle->callback(base, handle, ringId, kENET_RxEvent, handle->userData);
  2764. #else
  2765. handle->callback(base, handle, kENET_RxEvent, handle->userData);
  2766. #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
  2767. }
  2768. }
  2769. }
  2770. /*!
  2771. * brief Some special IRQ handler including the error, mii, wakeup irq handler.
  2772. *
  2773. * param base ENET peripheral base address.
  2774. * param handle The ENET handler pointer.
  2775. */
  2776. void ENET_ErrorIRQHandler(ENET_Type *base, enet_handle_t *handle)
  2777. {
  2778. assert(handle);
  2779. uint32_t errMask = kENET_BabrInterrupt | kENET_BabtInterrupt | kENET_EBusERInterrupt | kENET_PayloadRxInterrupt |
  2780. kENET_LateCollisionInterrupt | kENET_RetryLimitInterrupt | kENET_UnderrunInterrupt;
  2781. /* Check if the error interrupt happen. */
  2782. if (kENET_WakeupInterrupt & base->EIR)
  2783. {
  2784. /* Clear the wakeup interrupt. */
  2785. base->EIR = kENET_WakeupInterrupt;
  2786. /* wake up and enter the normal mode. */
  2787. ENET_EnableSleepMode(base, false);
  2788. /* Callback function. */
  2789. if (handle->callback)
  2790. {
  2791. #if FSL_FEATURE_ENET_QUEUE > 1
  2792. handle->callback(base, handle, 0, kENET_WakeUpEvent, handle->userData);
  2793. #else
  2794. handle->callback(base, handle, kENET_WakeUpEvent, handle->userData);
  2795. #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
  2796. }
  2797. }
  2798. else
  2799. {
  2800. /* Clear the error interrupt event status. */
  2801. errMask &= base->EIR;
  2802. base->EIR = errMask;
  2803. /* Callback function. */
  2804. if (handle->callback)
  2805. {
  2806. #if FSL_FEATURE_ENET_QUEUE > 1
  2807. handle->callback(base, handle, 0, kENET_ErrEvent, handle->userData);
  2808. #else
  2809. handle->callback(base, handle, kENET_ErrEvent, handle->userData);
  2810. #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
  2811. }
  2812. }
  2813. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  2814. exception return operation might vector to incorrect interrupt */
  2815. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  2816. __DSB();
  2817. #endif
  2818. }
  2819. #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
  2820. /*!
  2821. * brief The IEEE 1588 PTP time stamp interrupt handler.
  2822. *
  2823. * param base ENET peripheral base address.
  2824. * param handle The ENET state pointer. This is the same state pointer used in the ENET_Init.
  2825. */
  2826. void ENET_Ptp1588TimerIRQHandler(ENET_Type *base, enet_handle_t *handle)
  2827. {
  2828. assert(handle);
  2829. /* Check if the PTP time stamp interrupt happen. */
  2830. if (kENET_TsTimerInterrupt & base->EIR)
  2831. {
  2832. /* Clear the time stamp interrupt. */
  2833. base->EIR = kENET_TsTimerInterrupt;
  2834. /* Increase timer second counter. */
  2835. handle->msTimerSecond++;
  2836. /* Callback function. */
  2837. if (handle->callback)
  2838. {
  2839. #if FSL_FEATURE_ENET_QUEUE > 1
  2840. handle->callback(base, handle, 0, kENET_TimeStampEvent, handle->userData);
  2841. #else
  2842. handle->callback(base, handle, kENET_TimeStampEvent, handle->userData);
  2843. #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
  2844. }
  2845. }
  2846. else
  2847. {
  2848. /* Clear the time stamp interrupt. */
  2849. base->EIR = kENET_TsAvailInterrupt;
  2850. /* Callback function. */
  2851. if (handle->callback)
  2852. {
  2853. #if FSL_FEATURE_ENET_QUEUE > 1
  2854. handle->callback(base, handle, 0, kENET_TimeStampAvailEvent, handle->userData);
  2855. #else
  2856. handle->callback(base, handle, kENET_TimeStampAvailEvent, handle->userData);
  2857. #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
  2858. }
  2859. }
  2860. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  2861. exception return operation might vector to incorrect interrupt */
  2862. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  2863. __DSB();
  2864. #endif
  2865. }
  2866. #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
  2867. /*!
  2868. * brief the common IRQ handler for the tx/rx/error etc irq handler.
  2869. *
  2870. * This is used for the combined tx/rx/error interrupt for single/mutli-ring (frame 0).
  2871. *
  2872. * param base ENET peripheral base address.
  2873. */
  2874. void ENET_CommonFrame0IRQHandler(ENET_Type *base)
  2875. {
  2876. uint32_t event = base->EIR;
  2877. uint32_t instance = ENET_GetInstance(base);
  2878. if (event & (kENET_TxBufferInterrupt | kENET_TxFrameInterrupt))
  2879. {
  2880. #if FSL_FEATURE_ENET_QUEUE > 1
  2881. s_enetTxIsr(base, s_ENETHandle[instance], 0);
  2882. #else
  2883. s_enetTxIsr(base, s_ENETHandle[instance]);
  2884. #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
  2885. }
  2886. if (event & (kENET_RxBufferInterrupt | kENET_RxFrameInterrupt))
  2887. {
  2888. #if FSL_FEATURE_ENET_QUEUE > 1
  2889. s_enetRxIsr(base, s_ENETHandle[instance], 0);
  2890. #else
  2891. s_enetRxIsr(base, s_ENETHandle[instance]);
  2892. #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
  2893. }
  2894. if (event & ENET_TS_INTERRUPT)
  2895. {
  2896. s_enetTsIsr(base, s_ENETHandle[instance]);
  2897. }
  2898. if (event & ENET_ERR_INTERRUPT)
  2899. {
  2900. s_enetErrIsr(base, s_ENETHandle[instance]);
  2901. }
  2902. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  2903. exception return operation might vector to incorrect interrupt */
  2904. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  2905. __DSB();
  2906. #endif
  2907. }
  2908. #if FSL_FEATURE_ENET_QUEUE > 1
  2909. /*!
  2910. * brief the common IRQ handler for the tx/rx irq handler.
  2911. *
  2912. * This is used for the combined tx/rx interrupt for multi-ring (frame 1).
  2913. *
  2914. * param base ENET peripheral base address.
  2915. */
  2916. void ENET_CommonFrame1IRQHandler(ENET_Type *base)
  2917. {
  2918. uint32_t event = base->EIR;
  2919. uint32_t instance = ENET_GetInstance(base);
  2920. if (event & (kENET_TxBuffer1Interrupt | kENET_TxFrame1Interrupt))
  2921. {
  2922. s_enetTxIsr(base, s_ENETHandle[instance], 1);
  2923. }
  2924. if (event & (kENET_RxBuffer1Interrupt | kENET_RxFrame1Interrupt))
  2925. {
  2926. s_enetRxIsr(base, s_ENETHandle[instance], 1);
  2927. }
  2928. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  2929. exception return operation might vector to incorrect interrupt */
  2930. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  2931. __DSB();
  2932. #endif
  2933. }
  2934. /*!
  2935. * brief the common IRQ handler for the tx/rx irq handler.
  2936. *
  2937. * This is used for the combined tx/rx interrupt for multi-ring (frame 2).
  2938. *
  2939. * param base ENET peripheral base address.
  2940. */
  2941. void ENET_CommonFrame2IRQHandler(ENET_Type *base)
  2942. {
  2943. uint32_t event = base->EIR;
  2944. uint32_t instance = ENET_GetInstance(base);
  2945. if (event & (kENET_TxBuffer2Interrupt | kENET_TxFrame2Interrupt))
  2946. {
  2947. s_enetTxIsr(base, s_ENETHandle[instance], 2);
  2948. }
  2949. if (event & (kENET_RxBuffer2Interrupt | kENET_RxFrame2Interrupt))
  2950. {
  2951. s_enetRxIsr(base, s_ENETHandle[instance], 2);
  2952. }
  2953. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  2954. exception return operation might vector to incorrect interrupt */
  2955. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  2956. __DSB();
  2957. #endif
  2958. }
  2959. #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
  2960. #if defined(ENET)
  2961. void ENET_Transmit_IRQHandler(void)
  2962. {
  2963. s_enetTxIsr(ENET, s_ENETHandle[0]);
  2964. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  2965. exception return operation might vector to incorrect interrupt */
  2966. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  2967. __DSB();
  2968. #endif
  2969. }
  2970. void ENET_Receive_IRQHandler(void)
  2971. {
  2972. s_enetRxIsr(ENET, s_ENETHandle[0]);
  2973. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  2974. exception return operation might vector to incorrect interrupt */
  2975. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  2976. __DSB();
  2977. #endif
  2978. }
  2979. void ENET_Error_IRQHandler(void)
  2980. {
  2981. s_enetErrIsr(ENET, s_ENETHandle[0]);
  2982. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  2983. exception return operation might vector to incorrect interrupt */
  2984. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  2985. __DSB();
  2986. #endif
  2987. }
  2988. void ENET_1588_Timer_IRQHandler(void)
  2989. {
  2990. s_enetTsIsr(ENET, s_ENETHandle[0]);
  2991. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  2992. exception return operation might vector to incorrect interrupt */
  2993. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  2994. __DSB();
  2995. #endif
  2996. }
  2997. void ENET_DriverIRQHandler(void)
  2998. {
  2999. ENET_CommonFrame0IRQHandler(ENET);
  3000. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  3001. exception return operation might vector to incorrect interrupt */
  3002. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  3003. __DSB();
  3004. #endif
  3005. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  3006. exception return operation might vector to incorrect interrupt */
  3007. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  3008. __DSB();
  3009. #endif
  3010. }
  3011. #endif
  3012. #if defined(ENET1)
  3013. void ENET1_DriverIRQHandler(void)
  3014. {
  3015. ENET_CommonFrame0IRQHandler(ENET1);
  3016. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  3017. exception return operation might vector to incorrect interrupt */
  3018. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  3019. __DSB();
  3020. #endif
  3021. }
  3022. #endif
  3023. #if defined(ENET2)
  3024. void ENET2_DriverIRQHandler(void)
  3025. {
  3026. ENET_CommonFrame0IRQHandler(ENET2);
  3027. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  3028. exception return operation might vector to incorrect interrupt */
  3029. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  3030. __DSB();
  3031. #endif
  3032. }
  3033. #endif
  3034. #if defined(CONNECTIVITY__ENET0)
  3035. void CONNECTIVITY_ENET0_FRAME0_EVENT_INT_DriverIRQHandler(void)
  3036. {
  3037. ENET_CommonFrame0IRQHandler(CONNECTIVITY__ENET0);
  3038. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  3039. exception return operation might vector to incorrect interrupt */
  3040. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  3041. __DSB();
  3042. #endif
  3043. }
  3044. #if FSL_FEATURE_ENET_QUEUE > 1
  3045. void CONNECTIVITY_ENET0_FRAME1_INT_DriverIRQHandler(void)
  3046. {
  3047. ENET_CommonFrame1IRQHandler(CONNECTIVITY__ENET0);
  3048. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  3049. exception return operation might vector to incorrect interrupt */
  3050. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  3051. __DSB();
  3052. #endif
  3053. }
  3054. void CONNECTIVITY_ENET0_FRAME2_INT_DriverIRQHandler(void)
  3055. {
  3056. ENET_CommonFrame2IRQHandler(CONNECTIVITY__ENET0);
  3057. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  3058. exception return operation might vector to incorrect interrupt */
  3059. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  3060. __DSB();
  3061. #endif
  3062. }
  3063. #endif
  3064. #endif
  3065. #if defined(CONNECTIVITY__ENET1)
  3066. void CONNECTIVITY_ENET1_FRAME0_EVENT_INT_DriverIRQHandler(void)
  3067. {
  3068. ENET_CommonFrame0IRQHandler(CONNECTIVITY__ENET1);
  3069. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  3070. exception return operation might vector to incorrect interrupt */
  3071. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  3072. __DSB();
  3073. #endif
  3074. }
  3075. #if FSL_FEATURE_ENET_QUEUE > 1
  3076. void CONNECTIVITY_ENET1_FRAME1_INT_DriverIRQHandler(void)
  3077. {
  3078. ENET_CommonFrame1IRQHandler(CONNECTIVITY__ENET1);
  3079. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  3080. exception return operation might vector to incorrect interrupt */
  3081. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  3082. __DSB();
  3083. #endif
  3084. }
  3085. void CONNECTIVITY_ENET1_FRAME2_INT_DriverIRQHandler(void)
  3086. {
  3087. ENET_CommonFrame2IRQHandler(CONNECTIVITY__ENET1);
  3088. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  3089. exception return operation might vector to incorrect interrupt */
  3090. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  3091. __DSB();
  3092. #endif
  3093. }
  3094. #endif
  3095. #endif