fsl_enet.c 144 KB

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