IxEthAccMac.c 73 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617
  1. /**
  2. * @file IxEthAccMac.c
  3. *
  4. * @author Intel Corporation
  5. * @date
  6. *
  7. * @brief MAC control functions
  8. *
  9. * Design Notes:
  10. *
  11. * @par
  12. * IXP400 SW Release version 2.0
  13. *
  14. * -- Copyright Notice --
  15. *
  16. * @par
  17. * Copyright 2001-2005, Intel Corporation.
  18. * All rights reserved.
  19. *
  20. * @par
  21. * SPDX-License-Identifier: BSD-3-Clause
  22. * @par
  23. * -- End of Copyright Notice --
  24. */
  25. #include "IxOsal.h"
  26. #include "IxNpeMh.h"
  27. #ifdef CONFIG_IXP425_COMPONENT_ETHDB
  28. #include "IxEthDB.h"
  29. #endif
  30. #include "IxEthDBPortDefs.h"
  31. #include "IxEthNpe.h"
  32. #include "IxEthAcc.h"
  33. #include "IxEthAccDataPlane_p.h"
  34. #include "IxEthAcc_p.h"
  35. #include "IxEthAccMac_p.h"
  36. /* Maximum number of retries during ixEthAccPortDisable, which
  37. * is approximately 10 seconds
  38. */
  39. #define IX_ETH_ACC_MAX_RETRY 500
  40. /* Maximum number of retries during ixEthAccPortDisable when expecting
  41. * timeout
  42. */
  43. #define IX_ETH_ACC_MAX_RETRY_TIMEOUT 5
  44. #define IX_ETH_ACC_VALIDATE_PORT_ID(portId) \
  45. do \
  46. { \
  47. if(!IX_ETH_ACC_IS_PORT_VALID(portId)) \
  48. { \
  49. return IX_ETH_ACC_INVALID_PORT; \
  50. } \
  51. } while(0)
  52. PUBLIC IxEthAccMacState ixEthAccMacState[IX_ETH_ACC_NUMBER_OF_PORTS];
  53. PRIVATE UINT32 ixEthAccMacBase[IX_ETH_ACC_NUMBER_OF_PORTS];
  54. /*Forward function declarations*/
  55. PRIVATE void
  56. ixEthAccPortDisableRx (IxEthAccPortId portId,
  57. IX_OSAL_MBUF * mBufPtr,
  58. BOOL useMultiBufferCallback);
  59. PRIVATE void
  60. ixEthAccPortDisableRxAndReplenish (IxEthAccPortId portId,
  61. IX_OSAL_MBUF * mBufPtr,
  62. BOOL useMultiBufferCallback);
  63. PRIVATE void
  64. ixEthAccPortDisableTxDone (UINT32 cbTag,
  65. IX_OSAL_MBUF *mbuf);
  66. PRIVATE void
  67. ixEthAccPortDisableTxDoneAndSubmit (UINT32 cbTag,
  68. IX_OSAL_MBUF *mbuf);
  69. PRIVATE void
  70. ixEthAccPortDisableRxCallback (UINT32 cbTag,
  71. IX_OSAL_MBUF * mBufPtr,
  72. UINT32 learnedPortId);
  73. PRIVATE void
  74. ixEthAccPortDisableMultiBufferRxCallback (UINT32 cbTag,
  75. IX_OSAL_MBUF **mBufPtr);
  76. PRIVATE IxEthAccStatus
  77. ixEthAccPortDisableTryTransmit(UINT32 portId);
  78. PRIVATE IxEthAccStatus
  79. ixEthAccPortDisableTryReplenish(UINT32 portId);
  80. PRIVATE IxEthAccStatus
  81. ixEthAccPortMulticastMacAddressGet (IxEthAccPortId portId,
  82. IxEthAccMacAddr *macAddr);
  83. PRIVATE IxEthAccStatus
  84. ixEthAccPortMulticastMacFilterGet (IxEthAccPortId portId,
  85. IxEthAccMacAddr *macAddr);
  86. PRIVATE void
  87. ixEthAccMacNpeStatsMessageCallback (IxNpeMhNpeId npeId,
  88. IxNpeMhMessage msg);
  89. PRIVATE void
  90. ixEthAccMacNpeStatsResetMessageCallback (IxNpeMhNpeId npeId,
  91. IxNpeMhMessage msg);
  92. PRIVATE void
  93. ixEthAccNpeLoopbackMessageCallback (IxNpeMhNpeId npeId,
  94. IxNpeMhMessage msg);
  95. PRIVATE void
  96. ixEthAccMulticastAddressSet(IxEthAccPortId portId);
  97. PRIVATE BOOL
  98. ixEthAccMacEqual(IxEthAccMacAddr *macAddr1,
  99. IxEthAccMacAddr *macAddr2);
  100. PRIVATE void
  101. ixEthAccMacPrint(IxEthAccMacAddr *m);
  102. PRIVATE void
  103. ixEthAccMacStateUpdate(IxEthAccPortId portId);
  104. IxEthAccStatus
  105. ixEthAccMacMemInit(void)
  106. {
  107. ixEthAccMacBase[IX_ETH_PORT_1] =
  108. (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_0_BASE,
  109. IX_OSAL_IXP400_ETHA_MAP_SIZE);
  110. ixEthAccMacBase[IX_ETH_PORT_2] =
  111. (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_1_BASE,
  112. IX_OSAL_IXP400_ETHB_MAP_SIZE);
  113. #ifdef __ixp46X
  114. ixEthAccMacBase[IX_ETH_PORT_3] =
  115. (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_2_BASE,
  116. IX_OSAL_IXP400_ETH_NPEA_MAP_SIZE);
  117. if (ixEthAccMacBase[IX_ETH_PORT_3] == 0)
  118. {
  119. ixOsalLog(IX_OSAL_LOG_LVL_FATAL,
  120. IX_OSAL_LOG_DEV_STDOUT,
  121. "EthAcc: Could not map MAC I/O memory\n",
  122. 0, 0, 0, 0, 0 ,0);
  123. return IX_ETH_ACC_FAIL;
  124. }
  125. #endif
  126. if (ixEthAccMacBase[IX_ETH_PORT_1] == 0
  127. || ixEthAccMacBase[IX_ETH_PORT_2] == 0)
  128. {
  129. ixOsalLog(IX_OSAL_LOG_LVL_FATAL,
  130. IX_OSAL_LOG_DEV_STDOUT,
  131. "EthAcc: Could not map MAC I/O memory\n",
  132. 0, 0, 0, 0, 0 ,0);
  133. return IX_ETH_ACC_FAIL;
  134. }
  135. return IX_ETH_ACC_SUCCESS;
  136. }
  137. void
  138. ixEthAccMacUnload(void)
  139. {
  140. IX_OSAL_MEM_UNMAP(ixEthAccMacBase[IX_ETH_PORT_1]);
  141. IX_OSAL_MEM_UNMAP(ixEthAccMacBase[IX_ETH_PORT_2]);
  142. #ifdef __ixp46X
  143. IX_OSAL_MEM_UNMAP(ixEthAccMacBase[IX_ETH_PORT_3]);
  144. ixEthAccMacBase[IX_ETH_PORT_3] = 0;
  145. #endif
  146. ixEthAccMacBase[IX_ETH_PORT_2] = 0;
  147. ixEthAccMacBase[IX_ETH_PORT_1] = 0;
  148. }
  149. IxEthAccStatus
  150. ixEthAccPortEnablePriv(IxEthAccPortId portId)
  151. {
  152. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  153. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  154. {
  155. IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable port.\n",(INT32)portId,0,0,0,0,0);
  156. return IX_ETH_ACC_SUCCESS ;
  157. }
  158. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  159. {
  160. printf("EthAcc: (Mac) cannot enable port %d, port not initialized\n", portId);
  161. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  162. }
  163. if (ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn == NULL)
  164. {
  165. /* TxDone callback not registered */
  166. printf("EthAcc: (Mac) cannot enable port %d, TxDone callback not registered\n", portId);
  167. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  168. }
  169. if ((ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn == NULL)
  170. && (ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn == NULL))
  171. {
  172. /* Receive callback not registered */
  173. printf("EthAcc: (Mac) cannot enable port %d, Rx callback not registered\n", portId);
  174. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  175. }
  176. if(!ixEthAccMacState[portId].initDone)
  177. {
  178. printf("EthAcc: (Mac) cannot enable port %d, MAC address not set\n", portId);
  179. return (IX_ETH_ACC_MAC_UNINITIALIZED);
  180. }
  181. /* if the state is being set to what it is already at, do nothing*/
  182. if (ixEthAccMacState[portId].enabled)
  183. {
  184. return IX_ETH_ACC_SUCCESS;
  185. }
  186. #ifdef CONFIG_IXP425_COMPONENT_ETHDB
  187. /* enable ethernet database for this port */
  188. if (ixEthDBPortEnable(portId) != IX_ETH_DB_SUCCESS)
  189. {
  190. printf("EthAcc: (Mac) cannot enable port %d, EthDB failure\n", portId);
  191. return IX_ETH_ACC_FAIL;
  192. }
  193. #endif
  194. /* set the MAC core registers */
  195. REG_WRITE(ixEthAccMacBase[portId],
  196. IX_ETH_ACC_MAC_TX_CNTRL2,
  197. IX_ETH_ACC_TX_CNTRL2_RETRIES_MASK);
  198. REG_WRITE(ixEthAccMacBase[portId],
  199. IX_ETH_ACC_MAC_RANDOM_SEED,
  200. IX_ETH_ACC_RANDOM_SEED_DEFAULT);
  201. REG_WRITE(ixEthAccMacBase[portId],
  202. IX_ETH_ACC_MAC_THRESH_P_EMPTY,
  203. IX_ETH_ACC_MAC_THRESH_P_EMPTY_DEFAULT);
  204. REG_WRITE(ixEthAccMacBase[portId],
  205. IX_ETH_ACC_MAC_THRESH_P_FULL,
  206. IX_ETH_ACC_MAC_THRESH_P_FULL_DEFAULT);
  207. REG_WRITE(ixEthAccMacBase[portId],
  208. IX_ETH_ACC_MAC_TX_DEFER,
  209. IX_ETH_ACC_MAC_TX_DEFER_DEFAULT);
  210. REG_WRITE(ixEthAccMacBase[portId],
  211. IX_ETH_ACC_MAC_TX_TWO_DEFER_1,
  212. IX_ETH_ACC_MAC_TX_TWO_DEFER_1_DEFAULT);
  213. REG_WRITE(ixEthAccMacBase[portId],
  214. IX_ETH_ACC_MAC_TX_TWO_DEFER_2,
  215. IX_ETH_ACC_MAC_TX_TWO_DEFER_2_DEFAULT);
  216. REG_WRITE(ixEthAccMacBase[portId],
  217. IX_ETH_ACC_MAC_SLOT_TIME,
  218. IX_ETH_ACC_MAC_SLOT_TIME_DEFAULT);
  219. REG_WRITE(ixEthAccMacBase[portId],
  220. IX_ETH_ACC_MAC_INT_CLK_THRESH,
  221. IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT);
  222. REG_WRITE(ixEthAccMacBase[portId],
  223. IX_ETH_ACC_MAC_BUF_SIZE_TX,
  224. IX_ETH_ACC_MAC_BUF_SIZE_TX_DEFAULT);
  225. REG_WRITE(ixEthAccMacBase[portId],
  226. IX_ETH_ACC_MAC_TX_CNTRL1,
  227. IX_ETH_ACC_TX_CNTRL1_DEFAULT);
  228. REG_WRITE(ixEthAccMacBase[portId],
  229. IX_ETH_ACC_MAC_RX_CNTRL1,
  230. IX_ETH_ACC_RX_CNTRL1_DEFAULT);
  231. /* set the global state */
  232. ixEthAccMacState[portId].portDisableState = ACTIVE;
  233. ixEthAccMacState[portId].enabled = true;
  234. /* rewrite the setup (including mac filtering) depending
  235. * on current options
  236. */
  237. ixEthAccMacStateUpdate(portId);
  238. return IX_ETH_ACC_SUCCESS;
  239. }
  240. /*
  241. * PortDisable local variables. They contain the intermediate steps
  242. * while the port is being disabled and the buffers being drained out
  243. * of the NPE.
  244. */
  245. typedef void (*IxEthAccPortDisableRx)(IxEthAccPortId portId,
  246. IX_OSAL_MBUF * mBufPtr,
  247. BOOL useMultiBufferCallback);
  248. static IxEthAccPortRxCallback
  249. ixEthAccPortDisableFn[IX_ETH_ACC_NUMBER_OF_PORTS];
  250. static IxEthAccPortMultiBufferRxCallback
  251. ixEthAccPortDisableMultiBufferFn[IX_ETH_ACC_NUMBER_OF_PORTS];
  252. static IxEthAccPortDisableRx
  253. ixEthAccPortDisableRxTable[IX_ETH_ACC_NUMBER_OF_PORTS];
  254. static UINT32
  255. ixEthAccPortDisableCbTag[IX_ETH_ACC_NUMBER_OF_PORTS];
  256. static UINT32
  257. ixEthAccPortDisableMultiBufferCbTag[IX_ETH_ACC_NUMBER_OF_PORTS];
  258. static IxEthAccPortTxDoneCallback
  259. ixEthAccPortDisableTxDoneFn[IX_ETH_ACC_NUMBER_OF_PORTS];
  260. static UINT32
  261. ixEthAccPortDisableTxDoneCbTag[IX_ETH_ACC_NUMBER_OF_PORTS];
  262. static UINT32
  263. ixEthAccPortDisableUserBufferCount[IX_ETH_ACC_NUMBER_OF_PORTS];
  264. /*
  265. * PortDisable private callbacks functions. They handle the user
  266. * traffic, and the special buffers (one for tx, one for rx) used
  267. * in portDisable.
  268. */
  269. PRIVATE void
  270. ixEthAccPortDisableTxDone(UINT32 cbTag,
  271. IX_OSAL_MBUF *mbuf)
  272. {
  273. IxEthAccPortId portId = (IxEthAccPortId)cbTag;
  274. volatile IxEthAccPortDisableState *txState = &ixEthAccMacState[portId].txState;
  275. /* check for the special mbuf used in portDisable */
  276. if (mbuf == ixEthAccMacState[portId].portDisableTxMbufPtr)
  277. {
  278. *txState = TRANSMIT_DONE;
  279. }
  280. else
  281. {
  282. /* increment the count of user traffic during portDisable */
  283. ixEthAccPortDisableUserBufferCount[portId]++;
  284. /* call client TxDone function */
  285. ixEthAccPortDisableTxDoneFn[portId](ixEthAccPortDisableTxDoneCbTag[portId], mbuf);
  286. }
  287. }
  288. PRIVATE IxEthAccStatus
  289. ixEthAccPortDisableTryTransmit(UINT32 portId)
  290. {
  291. int key;
  292. IxEthAccStatus status = IX_ETH_ACC_SUCCESS;
  293. volatile IxEthAccPortDisableState *txState = &ixEthAccMacState[portId].txState;
  294. /* transmit the special buffer again if it is transmitted
  295. * and update the txState
  296. * This section is protected because the portDisable context
  297. * run an identical code, so the system keeps transmitting at the
  298. * maximum rate.
  299. */
  300. key = ixOsalIrqLock();
  301. if (*txState == TRANSMIT_DONE)
  302. {
  303. IX_OSAL_MBUF *mbufTxPtr = ixEthAccMacState[portId].portDisableTxMbufPtr;
  304. *txState = TRANSMIT;
  305. status = ixEthAccPortTxFrameSubmit(portId,
  306. mbufTxPtr,
  307. IX_ETH_ACC_TX_DEFAULT_PRIORITY);
  308. }
  309. ixOsalIrqUnlock(key);
  310. return status;
  311. }
  312. PRIVATE void
  313. ixEthAccPortDisableTxDoneAndSubmit(UINT32 cbTag,
  314. IX_OSAL_MBUF *mbuf)
  315. {
  316. IxEthAccPortId portId = (IxEthAccPortId)cbTag;
  317. /* call the callback which forwards the traffic to the client */
  318. ixEthAccPortDisableTxDone(cbTag, mbuf);
  319. /* try to transmit the buffer used in portDisable
  320. * if seen in TxDone
  321. */
  322. ixEthAccPortDisableTryTransmit(portId);
  323. }
  324. PRIVATE void
  325. ixEthAccPortDisableRx (IxEthAccPortId portId,
  326. IX_OSAL_MBUF * mBufPtr,
  327. BOOL useMultiBufferCallback)
  328. {
  329. volatile IxEthAccPortDisableState *rxState = &ixEthAccMacState[portId].rxState;
  330. IX_OSAL_MBUF *mNextPtr;
  331. while (mBufPtr)
  332. {
  333. mNextPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mBufPtr);
  334. IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mBufPtr) = NULL;
  335. /* check for the special mbuf used in portDisable */
  336. if (mBufPtr == ixEthAccMacState[portId].portDisableRxMbufPtr)
  337. {
  338. *rxState = RECEIVE;
  339. }
  340. else
  341. {
  342. /* increment the count of user traffic during portDisable */
  343. ixEthAccPortDisableUserBufferCount[portId]++;
  344. /* reset the received payload length during portDisable */
  345. IX_OSAL_MBUF_MLEN(mBufPtr) = 0;
  346. IX_OSAL_MBUF_PKT_LEN(mBufPtr) = 0;
  347. if (useMultiBufferCallback)
  348. {
  349. /* call the user callback with one unchained
  350. * buffer, without payload. A small array is built
  351. * to be used as a parameter (the user callback expects
  352. * to receive an array ended by a NULL pointer.
  353. */
  354. IX_OSAL_MBUF *mBufPtrArray[2];
  355. mBufPtrArray[0] = mBufPtr;
  356. mBufPtrArray[1] = NULL;
  357. ixEthAccPortDisableMultiBufferFn[portId](
  358. ixEthAccPortDisableMultiBufferCbTag[portId],
  359. mBufPtrArray);
  360. }
  361. else
  362. {
  363. /* call the user callback with a unchained
  364. * buffer, without payload and the destination port is
  365. * unknown.
  366. */
  367. ixEthAccPortDisableFn[portId](
  368. ixEthAccPortDisableCbTag[portId],
  369. mBufPtr,
  370. IX_ETH_DB_UNKNOWN_PORT /* port not found */);
  371. }
  372. }
  373. mBufPtr = mNextPtr;
  374. }
  375. }
  376. PRIVATE IxEthAccStatus
  377. ixEthAccPortDisableTryReplenish(UINT32 portId)
  378. {
  379. int key;
  380. IxEthAccStatus status = IX_ETH_ACC_SUCCESS;
  381. volatile IxEthAccPortDisableState *rxState = &ixEthAccMacState[portId].rxState;
  382. /* replenish with the special buffer again if it is received
  383. * and update the rxState
  384. * This section is protected because the portDisable context
  385. * run an identical code, so the system keeps replenishing at the
  386. * maximum rate.
  387. */
  388. key = ixOsalIrqLock();
  389. if (*rxState == RECEIVE)
  390. {
  391. IX_OSAL_MBUF *mbufRxPtr = ixEthAccMacState[portId].portDisableRxMbufPtr;
  392. *rxState = REPLENISH;
  393. IX_OSAL_MBUF_MLEN(mbufRxPtr) = IX_ETHACC_RX_MBUF_MIN_SIZE;
  394. status = ixEthAccPortRxFreeReplenish(portId, mbufRxPtr);
  395. }
  396. ixOsalIrqUnlock(key);
  397. return status;
  398. }
  399. PRIVATE void
  400. ixEthAccPortDisableRxAndReplenish (IxEthAccPortId portId,
  401. IX_OSAL_MBUF * mBufPtr,
  402. BOOL useMultiBufferCallback)
  403. {
  404. /* call the callback which forwards the traffic to the client */
  405. ixEthAccPortDisableRx(portId, mBufPtr, useMultiBufferCallback);
  406. /* try to replenish with the buffer used in portDisable
  407. * if seen in Rx
  408. */
  409. ixEthAccPortDisableTryReplenish(portId);
  410. }
  411. PRIVATE void
  412. ixEthAccPortDisableRxCallback (UINT32 cbTag,
  413. IX_OSAL_MBUF * mBufPtr,
  414. UINT32 learnedPortId)
  415. {
  416. IxEthAccPortId portId = (IxEthAccPortId)cbTag;
  417. /* call the portDisable receive callback */
  418. (ixEthAccPortDisableRxTable[portId])(portId, mBufPtr, false);
  419. }
  420. PRIVATE void
  421. ixEthAccPortDisableMultiBufferRxCallback (UINT32 cbTag,
  422. IX_OSAL_MBUF **mBufPtr)
  423. {
  424. IxEthAccPortId portId = (IxEthAccPortId)cbTag;
  425. while (*mBufPtr)
  426. {
  427. /* call the portDisable receive callback with one buffer at a time */
  428. (ixEthAccPortDisableRxTable[portId])(portId, *mBufPtr++, true);
  429. }
  430. }
  431. IxEthAccStatus
  432. ixEthAccPortDisablePriv(IxEthAccPortId portId)
  433. {
  434. IxEthAccStatus status = IX_ETH_ACC_SUCCESS;
  435. int key;
  436. int retry, retryTimeout;
  437. volatile IxEthAccPortDisableState *state = &ixEthAccMacState[portId].portDisableState;
  438. volatile IxEthAccPortDisableState *rxState = &ixEthAccMacState[portId].rxState;
  439. volatile IxEthAccPortDisableState *txState = &ixEthAccMacState[portId].txState;
  440. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  441. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  442. {
  443. IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot disable port.\n",(INT32)portId,0,0,0,0,0);
  444. return IX_ETH_ACC_SUCCESS ;
  445. }
  446. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  447. {
  448. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  449. }
  450. /* if the state is being set to what it is already at, do nothing */
  451. if (!ixEthAccMacState[portId].enabled)
  452. {
  453. return IX_ETH_ACC_SUCCESS;
  454. }
  455. *state = DISABLED;
  456. /* disable MAC receive first */
  457. ixEthAccPortRxDisablePriv(portId);
  458. #ifdef CONFIG_IXP425_COMPONENT_ETHDB
  459. /* disable ethernet database for this port - It is done now to avoid
  460. * issuing ELT maintenance after requesting 'port disable' in an NPE
  461. */
  462. if (ixEthDBPortDisable(portId) != IX_ETH_DB_SUCCESS)
  463. {
  464. status = IX_ETH_ACC_FAIL;
  465. IX_ETH_ACC_FATAL_LOG("ixEthAccPortDisable: failed to disable EthDB for this port\n", 0, 0, 0, 0, 0, 0);
  466. }
  467. #endif
  468. /* enter the critical section */
  469. key = ixOsalIrqLock();
  470. /* swap the Rx and TxDone callbacks */
  471. ixEthAccPortDisableFn[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn;
  472. ixEthAccPortDisableMultiBufferFn[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn;
  473. ixEthAccPortDisableCbTag[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag;
  474. ixEthAccPortDisableMultiBufferCbTag[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag;
  475. ixEthAccPortDisableTxDoneFn[portId] = ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn;
  476. ixEthAccPortDisableTxDoneCbTag[portId] = ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag;
  477. ixEthAccPortDisableRxTable[portId] = ixEthAccPortDisableRx;
  478. /* register temporary callbacks */
  479. ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn = ixEthAccPortDisableRxCallback;
  480. ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag = portId;
  481. ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn = ixEthAccPortDisableMultiBufferRxCallback;
  482. ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag = portId;
  483. ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn = ixEthAccPortDisableTxDone;
  484. ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag = portId;
  485. /* initialise the Rx state and Tx states */
  486. *txState = TRANSMIT_DONE;
  487. *rxState = RECEIVE;
  488. /* exit the critical section */
  489. ixOsalIrqUnlock(key);
  490. /* enable a NPE loopback */
  491. if (ixEthAccNpeLoopbackEnablePriv(portId) != IX_ETH_ACC_SUCCESS)
  492. {
  493. status = IX_ETH_ACC_FAIL;
  494. }
  495. if (status == IX_ETH_ACC_SUCCESS)
  496. {
  497. retry = 0;
  498. /* Step 1 : Drain Tx traffic and TxDone queues :
  499. *
  500. * Transmit and replenish at least once with the
  501. * special buffers until both of them are seen
  502. * in the callback hook
  503. *
  504. * (the receive callback keeps replenishing, so once we see
  505. * the special Tx buffer, we can be sure that Tx drain is complete)
  506. */
  507. ixEthAccPortDisableRxTable[portId]
  508. = ixEthAccPortDisableRxAndReplenish;
  509. ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn
  510. = ixEthAccPortDisableTxDone;
  511. do
  512. {
  513. /* keep replenishing */
  514. status = ixEthAccPortDisableTryReplenish(portId);
  515. if (status == IX_ETH_ACC_SUCCESS)
  516. {
  517. /* keep transmitting */
  518. status = ixEthAccPortDisableTryTransmit(portId);
  519. }
  520. if (status == IX_ETH_ACC_SUCCESS)
  521. {
  522. /* wait for some traffic being processed */
  523. ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS);
  524. }
  525. }
  526. while ((status == IX_ETH_ACC_SUCCESS)
  527. && (retry++ < IX_ETH_ACC_MAX_RETRY)
  528. && (*txState == TRANSMIT));
  529. /* Step 2 : Drain Rx traffic, RxFree and Rx queues :
  530. *
  531. * Transmit and replenish at least once with the
  532. * special buffers until both of them are seen
  533. * in the callback hook
  534. * (the transmit callback keeps transmitting, and when we see
  535. * the special Rx buffer, we can be sure that rxFree drain
  536. * is complete)
  537. *
  538. * The nested loop helps to retry if the user was keeping
  539. * replenishing or transmitting during portDisable.
  540. *
  541. * The 2 nested loops ensure more retries if user traffic is
  542. * seen during portDisable : the user should not replenish
  543. * or transmit while portDisable is running. However, because of
  544. * the queueing possibilities in ethAcc dataplane, it is possible
  545. * that a lot of traffic is left in the queues (e.g. when
  546. * transmitting over a low speed link) and therefore, more
  547. * retries are allowed to help flushing the buffers out.
  548. */
  549. ixEthAccPortDisableRxTable[portId]
  550. = ixEthAccPortDisableRx;
  551. ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn
  552. = ixEthAccPortDisableTxDoneAndSubmit;
  553. do
  554. {
  555. do
  556. {
  557. ixEthAccPortDisableUserBufferCount[portId] = 0;
  558. /* keep replenishing */
  559. status = ixEthAccPortDisableTryReplenish(portId);
  560. if (status == IX_ETH_ACC_SUCCESS)
  561. {
  562. /* keep transmitting */
  563. status = ixEthAccPortDisableTryTransmit(portId);
  564. }
  565. if (status == IX_ETH_ACC_SUCCESS)
  566. {
  567. /* wait for some traffic being processed */
  568. ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS);
  569. }
  570. }
  571. while ((status == IX_ETH_ACC_SUCCESS)
  572. && (retry++ < IX_ETH_ACC_MAX_RETRY)
  573. && ((ixEthAccPortDisableUserBufferCount[portId] != 0)
  574. || (*rxState == REPLENISH)));
  575. /* After the first iteration, change the receive callbacks,
  576. * to process only 1 buffer at a time
  577. */
  578. ixEthAccPortDisableRxTable[portId]
  579. = ixEthAccPortDisableRx;
  580. ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn
  581. = ixEthAccPortDisableTxDone;
  582. /* repeat the whole process while user traffic is seen in TxDone
  583. *
  584. * The conditions to stop the loop are
  585. * - Xscale has both Rx and Tx special buffers
  586. * (txState = transmit, rxState = receive)
  587. * - any error in txSubmit or rxReplenish
  588. * - no user traffic seen
  589. * - an excessive amount of retries
  590. */
  591. }
  592. while ((status == IX_ETH_ACC_SUCCESS)
  593. && (retry < IX_ETH_ACC_MAX_RETRY)
  594. && (*txState == TRANSMIT));
  595. /* check the loop exit conditions. The NPE should not hold
  596. * the special buffers.
  597. */
  598. if ((*rxState == REPLENISH) || (*txState == TRANSMIT))
  599. {
  600. status = IX_ETH_ACC_FAIL;
  601. }
  602. if (status == IX_ETH_ACC_SUCCESS)
  603. {
  604. /* Step 3 : Replenish without transmitting until a timeout
  605. * occurs, in order to drain the internal NPE fifos
  606. *
  607. * we can expect a few frames srill held
  608. * in the NPE.
  609. *
  610. * The 2 nested loops take care about the NPE dropping traffic
  611. * (including loopback traffic) when the Rx queue is full.
  612. *
  613. * The timeout value is very conservative
  614. * since the loopback used keeps replenishhing.
  615. *
  616. */
  617. do
  618. {
  619. ixEthAccPortDisableRxTable[portId] = ixEthAccPortDisableRxAndReplenish;
  620. ixEthAccPortDisableUserBufferCount[portId] = 0;
  621. retryTimeout = 0;
  622. do
  623. {
  624. /* keep replenishing */
  625. status = ixEthAccPortDisableTryReplenish(portId);
  626. if (status == IX_ETH_ACC_SUCCESS)
  627. {
  628. /* wait for some traffic being processed */
  629. ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS);
  630. }
  631. }
  632. while ((status == IX_ETH_ACC_SUCCESS)
  633. && (retryTimeout++ < IX_ETH_ACC_MAX_RETRY_TIMEOUT));
  634. /* Step 4 : Transmit once. Stop replenish
  635. *
  636. * After the Rx timeout, we are sure that the NPE does not
  637. * hold any frame in its internal NPE fifos.
  638. *
  639. * At this point, the NPE still holds the last rxFree buffer.
  640. * By transmitting a single frame, this should unblock the
  641. * last rxFree buffer. This code just transmit once and
  642. * wait for both frames seen in TxDone and in rxFree.
  643. *
  644. */
  645. ixEthAccPortDisableRxTable[portId] = ixEthAccPortDisableRx;
  646. status = ixEthAccPortDisableTryTransmit(portId);
  647. /* the NPE should immediatelyt release
  648. * the last Rx buffer and the last transmitted buffer
  649. * unless the last Tx frame was dropped (rx queue full)
  650. */
  651. if (status == IX_ETH_ACC_SUCCESS)
  652. {
  653. retryTimeout = 0;
  654. do
  655. {
  656. ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS);
  657. }
  658. while ((*rxState == REPLENISH)
  659. && (retryTimeout++ < IX_ETH_ACC_MAX_RETRY_TIMEOUT));
  660. }
  661. /* the NPE may have dropped the traffic because of Rx
  662. * queue being full. This code ensures that the last
  663. * Tx and Rx frames are both received.
  664. */
  665. }
  666. while ((status == IX_ETH_ACC_SUCCESS)
  667. && (retry++ < IX_ETH_ACC_MAX_RETRY)
  668. && ((*txState == TRANSMIT)
  669. || (*rxState == REPLENISH)
  670. || (ixEthAccPortDisableUserBufferCount[portId] != 0)));
  671. /* Step 5 : check the final states : the NPE has
  672. * no buffer left, nor in Tx , nor in Rx directions.
  673. */
  674. if ((*rxState == REPLENISH) || (*txState == TRANSMIT))
  675. {
  676. status = IX_ETH_ACC_FAIL;
  677. }
  678. }
  679. /* now all the buffers are drained, disable NPE loopback
  680. * This is done regardless of the logic to drain the queues and
  681. * the internal buffers held by the NPE.
  682. */
  683. if (ixEthAccNpeLoopbackDisablePriv(portId) != IX_ETH_ACC_SUCCESS)
  684. {
  685. status = IX_ETH_ACC_FAIL;
  686. }
  687. }
  688. /* disable MAC Tx and Rx services */
  689. ixEthAccMacState[portId].enabled = false;
  690. ixEthAccMacStateUpdate(portId);
  691. /* restore the Rx and TxDone callbacks (within a critical section) */
  692. key = ixOsalIrqLock();
  693. ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn = ixEthAccPortDisableFn[portId];
  694. ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag = ixEthAccPortDisableCbTag[portId];
  695. ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn = ixEthAccPortDisableMultiBufferFn[portId];
  696. ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag = ixEthAccPortDisableMultiBufferCbTag[portId];
  697. ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn = ixEthAccPortDisableTxDoneFn[portId];
  698. ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag = ixEthAccPortDisableTxDoneCbTag[portId];
  699. ixOsalIrqUnlock(key);
  700. /* the MAC core rx/tx disable may left the MAC hardware in an
  701. * unpredictable state. A hw reset is executed before resetting
  702. * all the MAC parameters to a known value.
  703. */
  704. REG_WRITE(ixEthAccMacBase[portId],
  705. IX_ETH_ACC_MAC_CORE_CNTRL,
  706. IX_ETH_ACC_CORE_RESET);
  707. ixOsalSleep(IX_ETH_ACC_MAC_RESET_DELAY);
  708. /* rewrite all parameters to their current value */
  709. ixEthAccMacStateUpdate(portId);
  710. REG_WRITE(ixEthAccMacBase[portId],
  711. IX_ETH_ACC_MAC_INT_CLK_THRESH,
  712. IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT);
  713. REG_WRITE(ixEthAccMacBase[portId],
  714. IX_ETH_ACC_MAC_CORE_CNTRL,
  715. IX_ETH_ACC_CORE_MDC_EN);
  716. return status;
  717. }
  718. IxEthAccStatus
  719. ixEthAccPortEnabledQueryPriv(IxEthAccPortId portId, BOOL *enabled)
  720. {
  721. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  722. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  723. {
  724. IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable port.\n",(INT32)portId,0,0,0,0,0);
  725. /* Since Eth NPE is not available, port must be disabled */
  726. *enabled = false ;
  727. return IX_ETH_ACC_SUCCESS ;
  728. }
  729. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  730. {
  731. /* Since Eth NPE is not available, port must be disabled */
  732. *enabled = false ;
  733. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  734. }
  735. *enabled = ixEthAccMacState[portId].enabled;
  736. return IX_ETH_ACC_SUCCESS;
  737. }
  738. IxEthAccStatus
  739. ixEthAccPortMacResetPriv(IxEthAccPortId portId)
  740. {
  741. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  742. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  743. {
  744. IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot reset Ethernet coprocessor.\n",(INT32)portId,0,0,0,0,0);
  745. return IX_ETH_ACC_SUCCESS ;
  746. }
  747. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  748. {
  749. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  750. }
  751. REG_WRITE(ixEthAccMacBase[portId],
  752. IX_ETH_ACC_MAC_CORE_CNTRL,
  753. IX_ETH_ACC_CORE_RESET);
  754. ixOsalSleep(IX_ETH_ACC_MAC_RESET_DELAY);
  755. /* rewrite all parameters to their current value */
  756. ixEthAccMacStateUpdate(portId);
  757. REG_WRITE(ixEthAccMacBase[portId],
  758. IX_ETH_ACC_MAC_INT_CLK_THRESH,
  759. IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT);
  760. REG_WRITE(ixEthAccMacBase[portId],
  761. IX_ETH_ACC_MAC_CORE_CNTRL,
  762. IX_ETH_ACC_CORE_MDC_EN);
  763. return IX_ETH_ACC_SUCCESS;
  764. }
  765. IxEthAccStatus
  766. ixEthAccPortLoopbackEnable(IxEthAccPortId portId)
  767. {
  768. UINT32 regval;
  769. /* Turn off promiscuous mode */
  770. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  771. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  772. {
  773. IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable loopback.\n",(INT32)portId,0,0,0,0,0);
  774. return IX_ETH_ACC_SUCCESS ;
  775. }
  776. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  777. {
  778. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  779. }
  780. /* read register */
  781. REG_READ(ixEthAccMacBase[portId],
  782. IX_ETH_ACC_MAC_RX_CNTRL1,
  783. regval);
  784. /* update register */
  785. REG_WRITE(ixEthAccMacBase[portId],
  786. IX_ETH_ACC_MAC_RX_CNTRL1,
  787. regval | IX_ETH_ACC_RX_CNTRL1_LOOP_EN);
  788. return IX_ETH_ACC_SUCCESS;
  789. }
  790. PRIVATE void
  791. ixEthAccNpeLoopbackMessageCallback (IxNpeMhNpeId npeId,
  792. IxNpeMhMessage msg)
  793. {
  794. IxEthAccPortId portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId);
  795. #ifndef NDEBUG
  796. /* Prudent to at least check the port is within range */
  797. if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS)
  798. {
  799. IX_ETH_ACC_FATAL_LOG("IXETHACC:ixEthAccPortDisableMessageCallback: Illegal port: %u\n",
  800. (UINT32) portId, 0, 0, 0, 0, 0);
  801. return;
  802. }
  803. #endif
  804. /* unlock message reception mutex */
  805. ixOsalMutexUnlock(&ixEthAccMacState[portId].npeLoopbackMessageLock);
  806. }
  807. IxEthAccStatus
  808. ixEthAccNpeLoopbackEnablePriv(IxEthAccPortId portId)
  809. {
  810. IX_STATUS npeMhStatus;
  811. IxNpeMhMessage message;
  812. IxEthAccStatus status = IX_ETH_ACC_SUCCESS;
  813. /* Turn off promiscuous mode */
  814. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  815. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  816. {
  817. IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable NPE loopback.\n",(INT32)portId,0,0,0,0,0);
  818. return IX_ETH_ACC_SUCCESS ;
  819. }
  820. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  821. {
  822. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  823. }
  824. /* enable NPE loopback (lsb of the message contains the value 1) */
  825. message.data[0] = (IX_ETHNPE_SETLOOPBACK_MODE << IX_ETH_ACC_MAC_MSGID_SHL)
  826. | 0x01;
  827. message.data[1] = 0;
  828. npeMhStatus = ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId),
  829. message,
  830. IX_ETHNPE_SETLOOPBACK_MODE_ACK,
  831. ixEthAccNpeLoopbackMessageCallback,
  832. IX_NPEMH_SEND_RETRIES_DEFAULT);
  833. if (npeMhStatus != IX_SUCCESS)
  834. {
  835. status = IX_ETH_ACC_FAIL;
  836. }
  837. else
  838. {
  839. /* wait for NPE loopbackEnable response */
  840. if (ixOsalMutexLock(&ixEthAccMacState[portId]. npeLoopbackMessageLock,
  841. IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS)
  842. != IX_SUCCESS)
  843. {
  844. status = IX_ETH_ACC_FAIL;
  845. }
  846. }
  847. return status;
  848. }
  849. IxEthAccStatus
  850. ixEthAccPortTxEnablePriv(IxEthAccPortId portId)
  851. {
  852. UINT32 regval;
  853. /* Turn off promiscuous mode */
  854. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  855. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  856. {
  857. IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable TX.\n",(INT32)portId,0,0,0,0,0);
  858. return IX_ETH_ACC_SUCCESS ;
  859. }
  860. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  861. {
  862. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  863. }
  864. /* read register */
  865. REG_READ(ixEthAccMacBase[portId],
  866. IX_ETH_ACC_MAC_TX_CNTRL1,
  867. regval);
  868. /* update register */
  869. REG_WRITE(ixEthAccMacBase[portId],
  870. IX_ETH_ACC_MAC_TX_CNTRL1,
  871. regval | IX_ETH_ACC_TX_CNTRL1_TX_EN);
  872. return IX_ETH_ACC_SUCCESS;
  873. }
  874. IxEthAccStatus
  875. ixEthAccPortRxEnablePriv(IxEthAccPortId portId)
  876. {
  877. UINT32 regval;
  878. /* Turn off promiscuous mode */
  879. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  880. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  881. {
  882. IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable RX.\n",(INT32)portId,0,0,0,0,0);
  883. return IX_ETH_ACC_SUCCESS ;
  884. }
  885. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  886. {
  887. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  888. }
  889. /* read register */
  890. REG_READ(ixEthAccMacBase[portId],
  891. IX_ETH_ACC_MAC_RX_CNTRL1,
  892. regval);
  893. /* update register */
  894. REG_WRITE(ixEthAccMacBase[portId],
  895. IX_ETH_ACC_MAC_RX_CNTRL1,
  896. regval | IX_ETH_ACC_RX_CNTRL1_RX_EN);
  897. return IX_ETH_ACC_SUCCESS;
  898. }
  899. IxEthAccStatus
  900. ixEthAccPortLoopbackDisable(IxEthAccPortId portId)
  901. {
  902. UINT32 regval;
  903. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  904. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  905. {
  906. IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot disable loopback.\n",(INT32)portId,0,0,0,0,0);
  907. return IX_ETH_ACC_SUCCESS ;
  908. }
  909. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  910. {
  911. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  912. }
  913. /*disable MAC loopabck */
  914. REG_READ(ixEthAccMacBase[portId],
  915. IX_ETH_ACC_MAC_RX_CNTRL1,
  916. regval);
  917. REG_WRITE(ixEthAccMacBase[portId],
  918. IX_ETH_ACC_MAC_RX_CNTRL1,
  919. (regval & ~IX_ETH_ACC_RX_CNTRL1_LOOP_EN));
  920. return IX_ETH_ACC_SUCCESS;
  921. }
  922. IxEthAccStatus
  923. ixEthAccNpeLoopbackDisablePriv(IxEthAccPortId portId)
  924. {
  925. IX_STATUS npeMhStatus;
  926. IxNpeMhMessage message;
  927. IxEthAccStatus status = IX_ETH_ACC_SUCCESS;
  928. /* Turn off promiscuous mode */
  929. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  930. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  931. {
  932. IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable NPE loopback.\n",(INT32)portId,0,0,0,0,0);
  933. return IX_ETH_ACC_SUCCESS ;
  934. }
  935. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  936. {
  937. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  938. }
  939. /* disable NPE loopback (lsb of the message contains the value 0) */
  940. message.data[0] = (IX_ETHNPE_SETLOOPBACK_MODE << IX_ETH_ACC_MAC_MSGID_SHL);
  941. message.data[1] = 0;
  942. npeMhStatus = ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId),
  943. message,
  944. IX_ETHNPE_SETLOOPBACK_MODE_ACK,
  945. ixEthAccNpeLoopbackMessageCallback,
  946. IX_NPEMH_SEND_RETRIES_DEFAULT);
  947. if (npeMhStatus != IX_SUCCESS)
  948. {
  949. status = IX_ETH_ACC_FAIL;
  950. }
  951. else
  952. {
  953. /* wait for NPE loopbackEnable response */
  954. if (ixOsalMutexLock(&ixEthAccMacState[portId].npeLoopbackMessageLock,
  955. IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS)
  956. != IX_SUCCESS)
  957. {
  958. status = IX_ETH_ACC_FAIL;
  959. }
  960. }
  961. return status;
  962. }
  963. IxEthAccStatus
  964. ixEthAccPortTxDisablePriv(IxEthAccPortId portId)
  965. {
  966. UINT32 regval;
  967. /* Turn off promiscuous mode */
  968. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  969. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  970. {
  971. IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot disable TX.\n", (INT32)portId,0,0,0,0,0);
  972. return IX_ETH_ACC_SUCCESS ;
  973. }
  974. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  975. {
  976. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  977. }
  978. /* read register */
  979. REG_READ(ixEthAccMacBase[portId],
  980. IX_ETH_ACC_MAC_TX_CNTRL1,
  981. regval);
  982. /* update register */
  983. REG_WRITE(ixEthAccMacBase[portId],
  984. IX_ETH_ACC_MAC_TX_CNTRL1,
  985. (regval & ~IX_ETH_ACC_TX_CNTRL1_TX_EN));
  986. return IX_ETH_ACC_SUCCESS;
  987. }
  988. IxEthAccStatus
  989. ixEthAccPortRxDisablePriv(IxEthAccPortId portId)
  990. {
  991. UINT32 regval;
  992. /* Turn off promiscuous mode */
  993. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  994. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  995. {
  996. IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot disable RX.\n", (INT32)portId,0,0,0,0,0);
  997. return IX_ETH_ACC_SUCCESS ;
  998. }
  999. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  1000. {
  1001. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  1002. }
  1003. /* read register */
  1004. REG_READ(ixEthAccMacBase[portId],
  1005. IX_ETH_ACC_MAC_RX_CNTRL1,
  1006. regval);
  1007. /* update register */
  1008. REG_WRITE(ixEthAccMacBase[portId],
  1009. IX_ETH_ACC_MAC_RX_CNTRL1,
  1010. (regval & ~IX_ETH_ACC_RX_CNTRL1_RX_EN));
  1011. return IX_ETH_ACC_SUCCESS;
  1012. }
  1013. IxEthAccStatus
  1014. ixEthAccPortPromiscuousModeClearPriv(IxEthAccPortId portId)
  1015. {
  1016. UINT32 regval;
  1017. /* Turn off promiscuous mode */
  1018. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  1019. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  1020. {
  1021. IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot clear promiscuous mode.\n",(INT32)portId,0,0,0,0,0);
  1022. return IX_ETH_ACC_SUCCESS ;
  1023. }
  1024. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  1025. {
  1026. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  1027. }
  1028. /*set bit 5 of Rx control 1 - enable address filtering*/
  1029. REG_READ(ixEthAccMacBase[portId],
  1030. IX_ETH_ACC_MAC_RX_CNTRL1,
  1031. regval);
  1032. REG_WRITE(ixEthAccMacBase[portId],
  1033. IX_ETH_ACC_MAC_RX_CNTRL1,
  1034. regval | IX_ETH_ACC_RX_CNTRL1_ADDR_FLTR_EN);
  1035. ixEthAccMacState[portId].promiscuous = false;
  1036. ixEthAccMulticastAddressSet(portId);
  1037. return IX_ETH_ACC_SUCCESS;
  1038. }
  1039. IxEthAccStatus
  1040. ixEthAccPortPromiscuousModeSetPriv(IxEthAccPortId portId)
  1041. {
  1042. UINT32 regval;
  1043. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  1044. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  1045. {
  1046. IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot set promiscuous mode.\n",(INT32)portId,0,0,0,0,0);
  1047. return IX_ETH_ACC_SUCCESS ;
  1048. }
  1049. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  1050. {
  1051. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  1052. }
  1053. /*
  1054. * Set bit 5 of Rx control 1 - We enable address filtering even in
  1055. * promiscuous mode because we want the MAC to set the appropriate
  1056. * bits in m_flags which doesn't happen if we turn off filtering.
  1057. */
  1058. REG_READ(ixEthAccMacBase[portId],
  1059. IX_ETH_ACC_MAC_RX_CNTRL1,
  1060. regval);
  1061. REG_WRITE(ixEthAccMacBase[portId],
  1062. IX_ETH_ACC_MAC_RX_CNTRL1,
  1063. regval | IX_ETH_ACC_RX_CNTRL1_ADDR_FLTR_EN);
  1064. ixEthAccMacState[portId].promiscuous = true;
  1065. ixEthAccMulticastAddressSet(portId);
  1066. return IX_ETH_ACC_SUCCESS;
  1067. }
  1068. IxEthAccStatus
  1069. ixEthAccPortUnicastMacAddressSetPriv (IxEthAccPortId portId,
  1070. IxEthAccMacAddr *macAddr)
  1071. {
  1072. UINT32 i;
  1073. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  1074. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  1075. {
  1076. IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot set Unicast Mac Address.\n",(INT32)portId,0,0,0,0,0);
  1077. return IX_ETH_ACC_SUCCESS ;
  1078. }
  1079. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  1080. {
  1081. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  1082. }
  1083. if (macAddr == NULL)
  1084. {
  1085. return IX_ETH_ACC_FAIL;
  1086. }
  1087. if ( macAddr->macAddress[0] & IX_ETH_ACC_ETH_MAC_BCAST_MCAST_BIT )
  1088. {
  1089. /* This is a multicast/broadcast address cant set it ! */
  1090. return IX_ETH_ACC_FAIL;
  1091. }
  1092. if ( macAddr->macAddress[0] == 0 &&
  1093. macAddr->macAddress[1] == 0 &&
  1094. macAddr->macAddress[2] == 0 &&
  1095. macAddr->macAddress[3] == 0 &&
  1096. macAddr->macAddress[4] == 0 &&
  1097. macAddr->macAddress[5] == 0 )
  1098. {
  1099. /* This is an invalid mac address cant set it ! */
  1100. return IX_ETH_ACC_FAIL;
  1101. }
  1102. #ifdef CONFIG_IXP425_COMPONENT_ETHDB
  1103. /* update the MAC address in the ethernet database */
  1104. if (ixEthDBPortAddressSet(portId, (IxEthDBMacAddr *) macAddr) != IX_ETH_DB_SUCCESS)
  1105. {
  1106. return IX_ETH_ACC_FAIL;
  1107. }
  1108. #endif
  1109. /*Set the Unicast MAC to the specified value*/
  1110. for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
  1111. {
  1112. REG_WRITE(ixEthAccMacBase[portId],
  1113. IX_ETH_ACC_MAC_UNI_ADDR_1 + i*sizeof(UINT32),
  1114. macAddr->macAddress[i]);
  1115. }
  1116. ixEthAccMacState[portId].initDone = true;
  1117. return IX_ETH_ACC_SUCCESS;
  1118. }
  1119. IxEthAccStatus
  1120. ixEthAccPortUnicastMacAddressGetPriv (IxEthAccPortId portId,
  1121. IxEthAccMacAddr *macAddr)
  1122. {
  1123. /*Return the current value of the Unicast MAC from h/w
  1124. for the specified port*/
  1125. UINT32 i;
  1126. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  1127. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  1128. {
  1129. IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get Unicast Mac Address.\n",(INT32)portId,0,0,0,0,0);
  1130. /* Since Eth Npe is unavailable, return invalid MAC Address = 00:00:00:00:00:00 */
  1131. for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
  1132. {
  1133. macAddr->macAddress[i] = 0;
  1134. }
  1135. return IX_ETH_ACC_SUCCESS ;
  1136. }
  1137. if(!ixEthAccMacState[portId].initDone)
  1138. {
  1139. return (IX_ETH_ACC_MAC_UNINITIALIZED);
  1140. }
  1141. if (macAddr == NULL)
  1142. {
  1143. return IX_ETH_ACC_FAIL;
  1144. }
  1145. for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
  1146. {
  1147. REG_READ(ixEthAccMacBase[portId],
  1148. IX_ETH_ACC_MAC_UNI_ADDR_1 + i*sizeof(UINT32),
  1149. macAddr->macAddress[i]);
  1150. }
  1151. return IX_ETH_ACC_SUCCESS;
  1152. }
  1153. PRIVATE IxEthAccStatus
  1154. ixEthAccPortMulticastMacAddressGet (IxEthAccPortId portId,
  1155. IxEthAccMacAddr *macAddr)
  1156. {
  1157. /*Return the current value of the Multicast MAC from h/w
  1158. for the specified port*/
  1159. UINT32 i;
  1160. for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
  1161. {
  1162. REG_READ(ixEthAccMacBase[portId],
  1163. IX_ETH_ACC_MAC_ADDR_1 + i*sizeof(UINT32),
  1164. macAddr->macAddress[i]);
  1165. }
  1166. return IX_ETH_ACC_SUCCESS;
  1167. }
  1168. PRIVATE IxEthAccStatus
  1169. ixEthAccPortMulticastMacFilterGet (IxEthAccPortId portId,
  1170. IxEthAccMacAddr *macAddr)
  1171. {
  1172. /*Return the current value of the Multicast MAC from h/w
  1173. for the specified port*/
  1174. UINT32 i;
  1175. for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
  1176. {
  1177. REG_READ(ixEthAccMacBase[portId],
  1178. IX_ETH_ACC_MAC_ADDR_MASK_1 + i*sizeof(UINT32),
  1179. macAddr->macAddress[i]);
  1180. }
  1181. return IX_ETH_ACC_SUCCESS;
  1182. }
  1183. IxEthAccStatus
  1184. ixEthAccPortMulticastAddressJoinPriv (IxEthAccPortId portId,
  1185. IxEthAccMacAddr *macAddr)
  1186. {
  1187. UINT32 i;
  1188. IxEthAccMacAddr broadcastAddr = {{0xff,0xff,0xff,0xff,0xff,0xff}};
  1189. /*Check that the port parameter is valid*/
  1190. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  1191. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  1192. {
  1193. IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot join Multicast Mac Address.\n",(INT32)portId,0,0,0,0,0);
  1194. return IX_ETH_ACC_SUCCESS ;
  1195. }
  1196. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  1197. {
  1198. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  1199. }
  1200. /*Check that the mac address is valid*/
  1201. if(macAddr == NULL)
  1202. {
  1203. return IX_ETH_ACC_FAIL;
  1204. }
  1205. /* Check that this is a multicast address */
  1206. if (!(macAddr->macAddress[0] & IX_ETH_ACC_ETH_MAC_BCAST_MCAST_BIT))
  1207. {
  1208. return IX_ETH_ACC_FAIL;
  1209. }
  1210. /* We don't add the Broadcast address */
  1211. if(ixEthAccMacEqual(&broadcastAddr, macAddr))
  1212. {
  1213. return IX_ETH_ACC_FAIL;
  1214. }
  1215. for (i = 0;
  1216. i<ixEthAccMacState[portId].mcastAddrIndex;
  1217. i++)
  1218. {
  1219. /*Check if the current entry already match an existing matches*/
  1220. if(ixEthAccMacEqual(&ixEthAccMacState[portId].mcastAddrsTable[i], macAddr))
  1221. {
  1222. /* Address found in the list and already configured,
  1223. * return a success status
  1224. */
  1225. return IX_ETH_ACC_SUCCESS;
  1226. }
  1227. }
  1228. /* check for availability at the end of the current table */
  1229. if(ixEthAccMacState[portId].mcastAddrIndex >= IX_ETH_ACC_MAX_MULTICAST_ADDRESSES)
  1230. {
  1231. return IX_ETH_ACC_FAIL;
  1232. }
  1233. /*First add the address to the multicast table for the
  1234. specified port*/
  1235. i=ixEthAccMacState[portId].mcastAddrIndex;
  1236. memcpy(&ixEthAccMacState[portId].mcastAddrsTable[i],
  1237. &macAddr->macAddress,
  1238. IX_IEEE803_MAC_ADDRESS_SIZE);
  1239. /*Increment the index into the table, this must be done here
  1240. as MulticastAddressSet below needs to know about the latest
  1241. entry.
  1242. */
  1243. ixEthAccMacState[portId].mcastAddrIndex++;
  1244. /*Then calculate the new value to be written to the address and
  1245. address mask registers*/
  1246. ixEthAccMulticastAddressSet(portId);
  1247. return IX_ETH_ACC_SUCCESS;
  1248. }
  1249. IxEthAccStatus
  1250. ixEthAccPortMulticastAddressJoinAllPriv (IxEthAccPortId portId)
  1251. {
  1252. IxEthAccMacAddr mcastMacAddr = {{0x1,0x0,0x0,0x0,0x0,0x0}};
  1253. /*Check that the port parameter is valid*/
  1254. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  1255. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  1256. {
  1257. IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot join all Multicast Address.\n",(INT32)portId,0,0,0,0,0);
  1258. return IX_ETH_ACC_SUCCESS ;
  1259. }
  1260. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  1261. {
  1262. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  1263. }
  1264. /* remove all entries from the database and
  1265. * insert a multicast entry
  1266. */
  1267. memcpy(&ixEthAccMacState[portId].mcastAddrsTable[0],
  1268. &mcastMacAddr.macAddress,
  1269. IX_IEEE803_MAC_ADDRESS_SIZE);
  1270. ixEthAccMacState[portId].mcastAddrIndex = 1;
  1271. ixEthAccMacState[portId].joinAll = true;
  1272. ixEthAccMulticastAddressSet(portId);
  1273. return IX_ETH_ACC_SUCCESS;
  1274. }
  1275. IxEthAccStatus
  1276. ixEthAccPortMulticastAddressLeavePriv (IxEthAccPortId portId,
  1277. IxEthAccMacAddr *macAddr)
  1278. {
  1279. UINT32 i;
  1280. IxEthAccMacAddr mcastMacAddr = {{0x1,0x0,0x0,0x0,0x0,0x0}};
  1281. /*Check that the port parameter is valid*/
  1282. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  1283. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  1284. {
  1285. IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot leave Multicast Address.\n",(INT32)portId,0,0,0,0,0);
  1286. return IX_ETH_ACC_SUCCESS ;
  1287. }
  1288. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  1289. {
  1290. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  1291. }
  1292. /*Check that the mac address is valid*/
  1293. if(macAddr == NULL)
  1294. {
  1295. return IX_ETH_ACC_FAIL;
  1296. }
  1297. /* Remove this mac address from the mask for the specified port
  1298. * we copy down all entries above the blanked entry, and
  1299. * decrement the index
  1300. */
  1301. i=0;
  1302. while(i<ixEthAccMacState[portId].mcastAddrIndex)
  1303. {
  1304. /*Check if the current entry matches*/
  1305. if(ixEthAccMacEqual(&ixEthAccMacState[portId].mcastAddrsTable[i],
  1306. macAddr))
  1307. {
  1308. if(ixEthAccMacEqual(macAddr, &mcastMacAddr))
  1309. {
  1310. ixEthAccMacState[portId].joinAll = false;
  1311. }
  1312. /*Decrement the index into the multicast address table
  1313. for the current port*/
  1314. ixEthAccMacState[portId].mcastAddrIndex--;
  1315. /*Copy down all entries above the current entry*/
  1316. while(i<ixEthAccMacState[portId].mcastAddrIndex)
  1317. {
  1318. memcpy(&ixEthAccMacState[portId].mcastAddrsTable[i],
  1319. &ixEthAccMacState[portId].mcastAddrsTable[i+1],
  1320. IX_IEEE803_MAC_ADDRESS_SIZE);
  1321. i++;
  1322. }
  1323. /*recalculate the mask and write it to the MAC*/
  1324. ixEthAccMulticastAddressSet(portId);
  1325. return IX_ETH_ACC_SUCCESS;
  1326. }
  1327. /* search the next entry */
  1328. i++;
  1329. }
  1330. /* no matching entry found */
  1331. return IX_ETH_ACC_NO_SUCH_ADDR;
  1332. }
  1333. IxEthAccStatus
  1334. ixEthAccPortMulticastAddressLeaveAllPriv (IxEthAccPortId portId)
  1335. {
  1336. /*Check that the port parameter is valid*/
  1337. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  1338. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  1339. {
  1340. IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot leave all Multicast Address.\n",(INT32)portId,0,0,0,0,0);
  1341. return IX_ETH_ACC_SUCCESS ;
  1342. }
  1343. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  1344. {
  1345. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  1346. }
  1347. ixEthAccMacState[portId].mcastAddrIndex = 0;
  1348. ixEthAccMacState[portId].joinAll = false;
  1349. ixEthAccMulticastAddressSet(portId);
  1350. return IX_ETH_ACC_SUCCESS;
  1351. }
  1352. IxEthAccStatus
  1353. ixEthAccPortUnicastAddressShowPriv (IxEthAccPortId portId)
  1354. {
  1355. IxEthAccMacAddr macAddr;
  1356. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  1357. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  1358. {
  1359. IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot show Unicast Address.\n",(INT32)portId,0,0,0,0,0);
  1360. return IX_ETH_ACC_SUCCESS ;
  1361. }
  1362. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  1363. {
  1364. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  1365. }
  1366. /*Get the MAC (UINICAST) address from hardware*/
  1367. if(ixEthAccPortUnicastMacAddressGetPriv(portId, &macAddr) != IX_ETH_ACC_SUCCESS)
  1368. {
  1369. IX_ETH_ACC_WARNING_LOG("EthAcc: MAC address uninitialised port %u\n",
  1370. (INT32)portId,0,0,0,0,0);
  1371. return IX_ETH_ACC_MAC_UNINITIALIZED;
  1372. }
  1373. /*print it out*/
  1374. ixEthAccMacPrint(&macAddr);
  1375. printf("\n");
  1376. return IX_ETH_ACC_SUCCESS;
  1377. }
  1378. void
  1379. ixEthAccPortMulticastAddressShowPriv(IxEthAccPortId portId)
  1380. {
  1381. IxEthAccMacAddr macAddr;
  1382. UINT32 i;
  1383. if(!IX_ETH_ACC_IS_PORT_VALID(portId))
  1384. {
  1385. return;
  1386. }
  1387. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  1388. {
  1389. IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot show Multicast Address.\n",(INT32)portId,0,0,0,0,0);
  1390. return ;
  1391. }
  1392. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  1393. {
  1394. return;
  1395. }
  1396. printf("Multicast MAC: ");
  1397. /*Get the MAC (MULTICAST) address from hardware*/
  1398. ixEthAccPortMulticastMacAddressGet(portId, &macAddr);
  1399. /*print it out*/
  1400. ixEthAccMacPrint(&macAddr);
  1401. /*Get the MAC (MULTICAST) filter from hardware*/
  1402. ixEthAccPortMulticastMacFilterGet(portId, &macAddr);
  1403. /*print it out*/
  1404. printf(" ( ");
  1405. ixEthAccMacPrint(&macAddr);
  1406. printf(" )\n");
  1407. printf("Constituent Addresses:\n");
  1408. for(i=0;i<ixEthAccMacState[portId].mcastAddrIndex;i++)
  1409. {
  1410. ixEthAccMacPrint(&ixEthAccMacState[portId].mcastAddrsTable[i]);
  1411. printf("\n");
  1412. }
  1413. return;
  1414. }
  1415. /*Set the duplex mode*/
  1416. IxEthAccStatus
  1417. ixEthAccPortDuplexModeSetPriv (IxEthAccPortId portId,
  1418. IxEthAccDuplexMode mode)
  1419. {
  1420. UINT32 txregval;
  1421. UINT32 rxregval;
  1422. /*This is bit 1 of the transmit control reg, set to 1 for half
  1423. duplex, 0 for full duplex*/
  1424. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  1425. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  1426. {
  1427. IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot set Duplex Mode.\n",(INT32)portId,0,0,0,0,0);
  1428. return IX_ETH_ACC_SUCCESS ;
  1429. }
  1430. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  1431. {
  1432. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  1433. }
  1434. REG_READ(ixEthAccMacBase[portId],
  1435. IX_ETH_ACC_MAC_TX_CNTRL1,
  1436. txregval);
  1437. REG_READ(ixEthAccMacBase[portId],
  1438. IX_ETH_ACC_MAC_RX_CNTRL1,
  1439. rxregval);
  1440. if (mode == IX_ETH_ACC_FULL_DUPLEX)
  1441. {
  1442. /*Clear half duplex bit in TX*/
  1443. REG_WRITE(ixEthAccMacBase[portId],
  1444. IX_ETH_ACC_MAC_TX_CNTRL1,
  1445. txregval & ~IX_ETH_ACC_TX_CNTRL1_DUPLEX);
  1446. /*We must set the pause enable in the receive logic when in
  1447. full duplex mode*/
  1448. REG_WRITE(ixEthAccMacBase[portId],
  1449. IX_ETH_ACC_MAC_RX_CNTRL1,
  1450. rxregval | IX_ETH_ACC_RX_CNTRL1_PAUSE_EN);
  1451. ixEthAccMacState[portId].fullDuplex = true;
  1452. }
  1453. else if (mode == IX_ETH_ACC_HALF_DUPLEX)
  1454. {
  1455. /*Set half duplex bit in TX*/
  1456. REG_WRITE(ixEthAccMacBase[portId],
  1457. IX_ETH_ACC_MAC_TX_CNTRL1,
  1458. txregval | IX_ETH_ACC_TX_CNTRL1_DUPLEX);
  1459. /*We must clear pause enable in the receive logic when in
  1460. half duplex mode*/
  1461. REG_WRITE(ixEthAccMacBase[portId],
  1462. IX_ETH_ACC_MAC_RX_CNTRL1,
  1463. rxregval & ~IX_ETH_ACC_RX_CNTRL1_PAUSE_EN);
  1464. ixEthAccMacState[portId].fullDuplex = false;
  1465. }
  1466. else
  1467. {
  1468. return IX_ETH_ACC_FAIL;
  1469. }
  1470. return IX_ETH_ACC_SUCCESS;
  1471. }
  1472. IxEthAccStatus
  1473. ixEthAccPortDuplexModeGetPriv (IxEthAccPortId portId,
  1474. IxEthAccDuplexMode *mode)
  1475. {
  1476. /*Return the duplex mode for the specified port*/
  1477. UINT32 regval;
  1478. /*This is bit 1 of the transmit control reg, set to 1 for half
  1479. duplex, 0 for full duplex*/
  1480. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  1481. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  1482. {
  1483. IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get Duplex Mode.\n",(INT32)portId,0,0,0,0,0);
  1484. /* return hald duplex */
  1485. *mode = IX_ETH_ACC_HALF_DUPLEX ;
  1486. return IX_ETH_ACC_SUCCESS ;
  1487. }
  1488. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  1489. {
  1490. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  1491. }
  1492. if (mode == NULL)
  1493. {
  1494. return (IX_ETH_ACC_FAIL);
  1495. }
  1496. REG_READ(ixEthAccMacBase[portId],
  1497. IX_ETH_ACC_MAC_TX_CNTRL1,
  1498. regval);
  1499. if( regval & IX_ETH_ACC_TX_CNTRL1_DUPLEX)
  1500. {
  1501. *mode = IX_ETH_ACC_HALF_DUPLEX;
  1502. }
  1503. else
  1504. {
  1505. *mode = IX_ETH_ACC_FULL_DUPLEX;
  1506. }
  1507. return IX_ETH_ACC_SUCCESS;
  1508. }
  1509. IxEthAccStatus
  1510. ixEthAccPortTxFrameAppendPaddingEnablePriv (IxEthAccPortId portId)
  1511. {
  1512. UINT32 regval;
  1513. /*Enable FCS computation by the MAC and appending to the
  1514. frame*/
  1515. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  1516. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  1517. {
  1518. IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable Tx Frame Append Padding.\n",(INT32)portId,0,0,0,0,0);
  1519. return IX_ETH_ACC_SUCCESS ;
  1520. }
  1521. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  1522. {
  1523. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  1524. }
  1525. REG_READ(ixEthAccMacBase[portId],
  1526. IX_ETH_ACC_MAC_TX_CNTRL1,
  1527. regval);
  1528. REG_WRITE(ixEthAccMacBase[portId],
  1529. IX_ETH_ACC_MAC_TX_CNTRL1,
  1530. regval |
  1531. IX_ETH_ACC_TX_CNTRL1_PAD_EN);
  1532. ixEthAccMacState[portId].txPADAppend = true;
  1533. return IX_ETH_ACC_SUCCESS;
  1534. }
  1535. IxEthAccStatus
  1536. ixEthAccPortTxFrameAppendPaddingDisablePriv (IxEthAccPortId portId)
  1537. {
  1538. UINT32 regval;
  1539. /*disable FCS computation and appending*/
  1540. /*Set bit 4 of Tx control register one to zero*/
  1541. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  1542. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  1543. {
  1544. IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot disble Tx Frame Append Padding.\n",(INT32)portId,0,0,0,0,0);
  1545. return IX_ETH_ACC_SUCCESS ;
  1546. }
  1547. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  1548. {
  1549. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  1550. }
  1551. REG_READ(ixEthAccMacBase[portId],
  1552. IX_ETH_ACC_MAC_TX_CNTRL1,
  1553. regval);
  1554. REG_WRITE(ixEthAccMacBase[portId],
  1555. IX_ETH_ACC_MAC_TX_CNTRL1,
  1556. regval & ~IX_ETH_ACC_TX_CNTRL1_PAD_EN);
  1557. ixEthAccMacState[portId].txPADAppend = false;
  1558. return IX_ETH_ACC_SUCCESS;
  1559. }
  1560. IxEthAccStatus
  1561. ixEthAccPortTxFrameAppendFCSEnablePriv (IxEthAccPortId portId)
  1562. {
  1563. UINT32 regval;
  1564. /*Enable FCS computation by the MAC and appending to the
  1565. frame*/
  1566. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  1567. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  1568. {
  1569. IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable Tx Frame Append FCS.\n",(INT32)portId,0,0,0,0,0);
  1570. return IX_ETH_ACC_SUCCESS ;
  1571. }
  1572. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  1573. {
  1574. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  1575. }
  1576. REG_READ(ixEthAccMacBase[portId],
  1577. IX_ETH_ACC_MAC_TX_CNTRL1,
  1578. regval);
  1579. REG_WRITE(ixEthAccMacBase[portId],
  1580. IX_ETH_ACC_MAC_TX_CNTRL1,
  1581. regval | IX_ETH_ACC_TX_CNTRL1_FCS_EN);
  1582. ixEthAccMacState[portId].txFCSAppend = true;
  1583. return IX_ETH_ACC_SUCCESS;
  1584. }
  1585. IxEthAccStatus
  1586. ixEthAccPortTxFrameAppendFCSDisablePriv (IxEthAccPortId portId)
  1587. {
  1588. UINT32 regval;
  1589. /*disable FCS computation and appending*/
  1590. /*Set bit 4 of Tx control register one to zero*/
  1591. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  1592. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  1593. {
  1594. IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot disable Tx Frame Append FCS.\n",(INT32)portId,0,0,0,0,0);
  1595. return IX_ETH_ACC_SUCCESS ;
  1596. }
  1597. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  1598. {
  1599. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  1600. }
  1601. REG_READ(ixEthAccMacBase[portId],
  1602. IX_ETH_ACC_MAC_TX_CNTRL1,
  1603. regval);
  1604. REG_WRITE(ixEthAccMacBase[portId],
  1605. IX_ETH_ACC_MAC_TX_CNTRL1,
  1606. regval & ~IX_ETH_ACC_TX_CNTRL1_FCS_EN);
  1607. ixEthAccMacState[portId].txFCSAppend = false;
  1608. return IX_ETH_ACC_SUCCESS;
  1609. }
  1610. IxEthAccStatus
  1611. ixEthAccPortRxFrameAppendFCSEnablePriv (IxEthAccPortId portId)
  1612. {
  1613. /*Set bit 2 of Rx control 1*/
  1614. UINT32 regval;
  1615. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  1616. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  1617. {
  1618. IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable Rx Frame Append FCS.\n",(INT32)portId,0,0,0,0,0);
  1619. return IX_ETH_ACC_SUCCESS ;
  1620. }
  1621. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  1622. {
  1623. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  1624. }
  1625. REG_READ(ixEthAccMacBase[portId],
  1626. IX_ETH_ACC_MAC_RX_CNTRL1,
  1627. regval);
  1628. REG_WRITE(ixEthAccMacBase[portId],
  1629. IX_ETH_ACC_MAC_RX_CNTRL1,
  1630. regval | IX_ETH_ACC_RX_CNTRL1_CRC_EN);
  1631. ixEthAccMacState[portId].rxFCSAppend = true;
  1632. return IX_ETH_ACC_SUCCESS;
  1633. }
  1634. IxEthAccStatus
  1635. ixEthAccPortRxFrameAppendFCSDisablePriv (IxEthAccPortId portId)
  1636. {
  1637. UINT32 regval;
  1638. /*Clear bit 2 of Rx control 1*/
  1639. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  1640. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  1641. {
  1642. IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot disable Rx Frame Append FCS.\n",(INT32)portId,0,0,0,0,0);
  1643. return IX_ETH_ACC_SUCCESS ;
  1644. }
  1645. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  1646. {
  1647. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  1648. }
  1649. REG_READ(ixEthAccMacBase[portId],
  1650. IX_ETH_ACC_MAC_RX_CNTRL1,
  1651. regval);
  1652. REG_WRITE(ixEthAccMacBase[portId],
  1653. IX_ETH_ACC_MAC_RX_CNTRL1,
  1654. regval & ~IX_ETH_ACC_RX_CNTRL1_CRC_EN);
  1655. ixEthAccMacState[portId].rxFCSAppend = false;
  1656. return IX_ETH_ACC_SUCCESS;
  1657. }
  1658. PRIVATE void
  1659. ixEthAccMacNpeStatsMessageCallback (IxNpeMhNpeId npeId,
  1660. IxNpeMhMessage msg)
  1661. {
  1662. IxEthAccPortId portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId);
  1663. #ifndef NDEBUG
  1664. /* Prudent to at least check the port is within range */
  1665. if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS)
  1666. {
  1667. IX_ETH_ACC_FATAL_LOG(
  1668. "IXETHACC:ixEthAccMacNpeStatsMessageCallback: Illegal port: %u\n",
  1669. (UINT32)portId, 0, 0, 0, 0, 0);
  1670. return;
  1671. }
  1672. #endif
  1673. /*Unblock Stats Get call*/
  1674. ixOsalMutexUnlock(&ixEthAccMacState[portId].ackMIBStatsLock);
  1675. }
  1676. PRIVATE void
  1677. ixEthAccMibIIStatsEndianConvert (IxEthEthObjStats *retStats)
  1678. {
  1679. /* endianness conversion */
  1680. /* Rx stats */
  1681. retStats->dot3StatsAlignmentErrors =
  1682. IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsAlignmentErrors);
  1683. retStats->dot3StatsFCSErrors =
  1684. IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsFCSErrors);
  1685. retStats->dot3StatsInternalMacReceiveErrors =
  1686. IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsInternalMacReceiveErrors);
  1687. retStats->RxOverrunDiscards =
  1688. IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxOverrunDiscards);
  1689. retStats->RxLearnedEntryDiscards =
  1690. IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxLearnedEntryDiscards);
  1691. retStats->RxLargeFramesDiscards =
  1692. IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxLargeFramesDiscards);
  1693. retStats->RxSTPBlockedDiscards =
  1694. IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxSTPBlockedDiscards);
  1695. retStats->RxVLANTypeFilterDiscards =
  1696. IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxVLANTypeFilterDiscards);
  1697. retStats->RxVLANIdFilterDiscards =
  1698. IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxVLANIdFilterDiscards);
  1699. retStats->RxInvalidSourceDiscards =
  1700. IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxInvalidSourceDiscards);
  1701. retStats->RxBlackListDiscards =
  1702. IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxBlackListDiscards);
  1703. retStats->RxWhiteListDiscards =
  1704. IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxWhiteListDiscards);
  1705. retStats->RxUnderflowEntryDiscards =
  1706. IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxUnderflowEntryDiscards);
  1707. /* Tx stats */
  1708. retStats->dot3StatsSingleCollisionFrames =
  1709. IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsSingleCollisionFrames);
  1710. retStats->dot3StatsMultipleCollisionFrames =
  1711. IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsMultipleCollisionFrames);
  1712. retStats->dot3StatsDeferredTransmissions =
  1713. IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsDeferredTransmissions);
  1714. retStats->dot3StatsLateCollisions =
  1715. IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsLateCollisions);
  1716. retStats->dot3StatsExcessiveCollsions =
  1717. IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsExcessiveCollsions);
  1718. retStats->dot3StatsInternalMacTransmitErrors =
  1719. IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsInternalMacTransmitErrors);
  1720. retStats->dot3StatsCarrierSenseErrors =
  1721. IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsCarrierSenseErrors);
  1722. retStats->TxLargeFrameDiscards =
  1723. IX_OSAL_SWAP_BE_SHARED_LONG(retStats->TxLargeFrameDiscards);
  1724. retStats->TxVLANIdFilterDiscards =
  1725. IX_OSAL_SWAP_BE_SHARED_LONG(retStats->TxVLANIdFilterDiscards);
  1726. }
  1727. IxEthAccStatus
  1728. ixEthAccMibIIStatsGet (IxEthAccPortId portId,
  1729. IxEthEthObjStats *retStats )
  1730. {
  1731. IxNpeMhMessage message;
  1732. if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
  1733. {
  1734. printf("EthAcc: ixEthAccMibIIStatsGet (Mac) EthAcc service is not initialized\n");
  1735. return (IX_ETH_ACC_FAIL);
  1736. }
  1737. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  1738. if (retStats == NULL)
  1739. {
  1740. printf("EthAcc: ixEthAccMibIIStatsGet (Mac) NULL argument\n");
  1741. return (IX_ETH_ACC_FAIL);
  1742. }
  1743. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  1744. {
  1745. printf("EthAcc: ixEthAccMibIIStatsGet (Mac) NPE for port %d is not available\n", portId);
  1746. IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get MIB II Stats.\n",(INT32)portId,0,0,0,0,0);
  1747. /* Return all zero stats */
  1748. IX_ETH_ACC_MEMSET(retStats, 0, sizeof(IxEthEthObjStats));
  1749. return IX_ETH_ACC_SUCCESS ;
  1750. }
  1751. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  1752. {
  1753. printf("EthAcc: ixEthAccMibIIStatsGet (Mac) port %d is not initialized\n", portId);
  1754. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  1755. }
  1756. IX_OSAL_CACHE_INVALIDATE(retStats, sizeof(IxEthEthObjStats));
  1757. message.data[0] = IX_ETHNPE_GETSTATS << IX_ETH_ACC_MAC_MSGID_SHL;
  1758. message.data[1] = (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS(retStats);
  1759. /* Permit only one task to request MIB statistics Get operation
  1760. at a time */
  1761. ixOsalMutexLock(&ixEthAccMacState[portId].MIBStatsGetAccessLock, IX_OSAL_WAIT_FOREVER);
  1762. if(ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId),
  1763. message,
  1764. IX_ETHNPE_GETSTATS,
  1765. ixEthAccMacNpeStatsMessageCallback,
  1766. IX_NPEMH_SEND_RETRIES_DEFAULT)
  1767. != IX_SUCCESS)
  1768. {
  1769. ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetAccessLock);
  1770. printf("EthAcc: (Mac) StatsGet failed to send NPE message\n");
  1771. return IX_ETH_ACC_FAIL;
  1772. }
  1773. /* Wait for callback invocation indicating response to
  1774. this request - we need this mutex in order to ensure
  1775. that the return from this function is synchronous */
  1776. ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsLock, IX_ETH_ACC_MIB_STATS_DELAY_MSECS);
  1777. /* Permit other tasks to perform MIB statistics Get operation */
  1778. ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetAccessLock);
  1779. ixEthAccMibIIStatsEndianConvert (retStats);
  1780. return IX_ETH_ACC_SUCCESS;
  1781. }
  1782. PRIVATE void
  1783. ixEthAccMacNpeStatsResetMessageCallback (IxNpeMhNpeId npeId,
  1784. IxNpeMhMessage msg)
  1785. {
  1786. IxEthAccPortId portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId);
  1787. #ifndef NDEBUG
  1788. /* Prudent to at least check the port is within range */
  1789. if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS)
  1790. {
  1791. IX_ETH_ACC_FATAL_LOG(
  1792. "IXETHACC:ixEthAccMacNpeStatsResetMessageCallback: Illegal port: %u\n",
  1793. (UINT32)portId, 0, 0, 0, 0, 0);
  1794. return;
  1795. }
  1796. #endif
  1797. /*Unblock Stats Get & reset call*/
  1798. ixOsalMutexUnlock(&ixEthAccMacState[portId].ackMIBStatsResetLock);
  1799. }
  1800. IxEthAccStatus
  1801. ixEthAccMibIIStatsGetClear (IxEthAccPortId portId,
  1802. IxEthEthObjStats *retStats)
  1803. {
  1804. IxNpeMhMessage message;
  1805. if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
  1806. {
  1807. printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) EthAcc service is not initialized\n");
  1808. return (IX_ETH_ACC_FAIL);
  1809. }
  1810. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  1811. if (retStats == NULL)
  1812. {
  1813. printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) NULL argument\n");
  1814. return (IX_ETH_ACC_FAIL);
  1815. }
  1816. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  1817. {
  1818. printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) NPE for port %d is not available\n", portId);
  1819. IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get and clear MIB II Stats.\n", (INT32)portId, 0, 0, 0, 0, 0);
  1820. /* Return all zero stats */
  1821. IX_ETH_ACC_MEMSET(retStats, 0, sizeof(IxEthEthObjStats));
  1822. return IX_ETH_ACC_SUCCESS ;
  1823. }
  1824. if (!IX_ETH_IS_PORT_INITIALIZED(portId))
  1825. {
  1826. printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) port %d is not initialized\n", portId);
  1827. return (IX_ETH_ACC_PORT_UNINITIALIZED);
  1828. }
  1829. IX_OSAL_CACHE_INVALIDATE(retStats, sizeof(IxEthEthObjStats));
  1830. message.data[0] = IX_ETHNPE_RESETSTATS << IX_ETH_ACC_MAC_MSGID_SHL;
  1831. message.data[1] = (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS(retStats);
  1832. /* Permit only one task to request MIB statistics Get-Reset operation at a time */
  1833. ixOsalMutexLock(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock, IX_OSAL_WAIT_FOREVER);
  1834. if(ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId),
  1835. message,
  1836. IX_ETHNPE_RESETSTATS,
  1837. ixEthAccMacNpeStatsResetMessageCallback,
  1838. IX_NPEMH_SEND_RETRIES_DEFAULT)
  1839. != IX_SUCCESS)
  1840. {
  1841. ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock);
  1842. printf("EthAcc: (Mac) ixEthAccMibIIStatsGetClear failed to send NPE message\n");
  1843. return IX_ETH_ACC_FAIL;
  1844. }
  1845. /* Wait for callback invocation indicating response to this request */
  1846. ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsResetLock, IX_ETH_ACC_MIB_STATS_DELAY_MSECS);
  1847. /* permit other tasks to get and reset MIB stats*/
  1848. ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock);
  1849. ixEthAccMibIIStatsEndianConvert(retStats);
  1850. return IX_ETH_ACC_SUCCESS;
  1851. }
  1852. IxEthAccStatus
  1853. ixEthAccMibIIStatsClear (IxEthAccPortId portId)
  1854. {
  1855. static IxEthEthObjStats retStats;
  1856. IxEthAccStatus status;
  1857. if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
  1858. {
  1859. return (IX_ETH_ACC_FAIL);
  1860. }
  1861. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  1862. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  1863. {
  1864. IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot clear MIB II Stats.\n",(INT32)portId,0,0,0,0,0);
  1865. return IX_ETH_ACC_SUCCESS ;
  1866. }
  1867. /* there is no reset operation without a corresponding Get */
  1868. status = ixEthAccMibIIStatsGetClear(portId, &retStats);
  1869. return status;
  1870. }
  1871. /* Initialize the ethernet MAC settings */
  1872. IxEthAccStatus
  1873. ixEthAccMacInit(IxEthAccPortId portId)
  1874. {
  1875. IX_OSAL_MBUF_POOL* portDisablePool;
  1876. UINT8 *data;
  1877. IX_ETH_ACC_VALIDATE_PORT_ID(portId);
  1878. if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
  1879. {
  1880. IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot initialize Mac.\n",(INT32)portId,0,0,0,0,0);
  1881. return IX_ETH_ACC_SUCCESS ;
  1882. }
  1883. if(ixEthAccMacState[portId].macInitialised == false)
  1884. {
  1885. ixEthAccMacState[portId].fullDuplex = true;
  1886. ixEthAccMacState[portId].rxFCSAppend = true;
  1887. ixEthAccMacState[portId].txFCSAppend = true;
  1888. ixEthAccMacState[portId].txPADAppend = true;
  1889. ixEthAccMacState[portId].enabled = false;
  1890. ixEthAccMacState[portId].promiscuous = true;
  1891. ixEthAccMacState[portId].joinAll = false;
  1892. ixEthAccMacState[portId].initDone = false;
  1893. ixEthAccMacState[portId].macInitialised = true;
  1894. /* initialize MIB stats mutexes */
  1895. ixOsalMutexInit(&ixEthAccMacState[portId].ackMIBStatsLock);
  1896. ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsLock, IX_OSAL_WAIT_FOREVER);
  1897. ixOsalMutexInit(&ixEthAccMacState[portId].ackMIBStatsResetLock);
  1898. ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsResetLock, IX_OSAL_WAIT_FOREVER);
  1899. ixOsalMutexInit(&ixEthAccMacState[portId].MIBStatsGetAccessLock);
  1900. ixOsalMutexInit(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock);
  1901. ixOsalMutexInit(&ixEthAccMacState[portId].npeLoopbackMessageLock);
  1902. ixEthAccMacState[portId].portDisableRxMbufPtr = NULL;
  1903. ixEthAccMacState[portId].portDisableTxMbufPtr = NULL;
  1904. portDisablePool = IX_OSAL_MBUF_POOL_INIT(2,
  1905. IX_ETHACC_RX_MBUF_MIN_SIZE,
  1906. "portDisable Pool");
  1907. IX_OSAL_ENSURE(portDisablePool != NULL, "Failed to initialize PortDisable pool");
  1908. ixEthAccMacState[portId].portDisableRxMbufPtr = IX_OSAL_MBUF_POOL_GET(portDisablePool);
  1909. ixEthAccMacState[portId].portDisableTxMbufPtr = IX_OSAL_MBUF_POOL_GET(portDisablePool);
  1910. IX_OSAL_ENSURE(ixEthAccMacState[portId].portDisableRxMbufPtr != NULL,
  1911. "Pool allocation failed");
  1912. IX_OSAL_ENSURE(ixEthAccMacState[portId].portDisableTxMbufPtr != NULL,
  1913. "Pool allocation failed");
  1914. /* fill the payload of the Rx mbuf used in portDisable */
  1915. IX_OSAL_MBUF_MLEN(ixEthAccMacState[portId].portDisableRxMbufPtr) = IX_ETHACC_RX_MBUF_MIN_SIZE;
  1916. memset(IX_OSAL_MBUF_MDATA(ixEthAccMacState[portId].portDisableRxMbufPtr),
  1917. 0xAA,
  1918. IX_ETHACC_RX_MBUF_MIN_SIZE);
  1919. /* fill the payload of the Tx mbuf used in portDisable (64 bytes) */
  1920. IX_OSAL_MBUF_MLEN(ixEthAccMacState[portId].portDisableTxMbufPtr) = 64;
  1921. IX_OSAL_MBUF_PKT_LEN(ixEthAccMacState[portId].portDisableTxMbufPtr) = 64;
  1922. data = (UINT8 *) IX_OSAL_MBUF_MDATA(ixEthAccMacState[portId].portDisableTxMbufPtr);
  1923. memset(data, 0xBB, 64);
  1924. data[0] = 0x00; /* unicast destination MAC address */
  1925. data[6] = 0x00; /* unicast source MAC address */
  1926. data[12] = 0x08; /* typelength : IP frame */
  1927. data[13] = 0x00; /* typelength : IP frame */
  1928. IX_OSAL_CACHE_FLUSH(data, 64);
  1929. }
  1930. IX_OSAL_ASSERT (ixEthAccMacBase[portId] != 0);
  1931. REG_WRITE(ixEthAccMacBase[portId],
  1932. IX_ETH_ACC_MAC_CORE_CNTRL,
  1933. IX_ETH_ACC_CORE_RESET);
  1934. ixOsalSleep(IX_ETH_ACC_MAC_RESET_DELAY);
  1935. REG_WRITE(ixEthAccMacBase[portId],
  1936. IX_ETH_ACC_MAC_CORE_CNTRL,
  1937. IX_ETH_ACC_CORE_MDC_EN);
  1938. REG_WRITE(ixEthAccMacBase[portId],
  1939. IX_ETH_ACC_MAC_INT_CLK_THRESH,
  1940. IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT);
  1941. ixEthAccMacStateUpdate(portId);
  1942. return IX_ETH_ACC_SUCCESS;
  1943. }
  1944. /* PRIVATE Functions*/
  1945. PRIVATE void
  1946. ixEthAccMacStateUpdate(IxEthAccPortId portId)
  1947. {
  1948. UINT32 regval;
  1949. if ( ixEthAccMacState[portId].enabled == false )
  1950. {
  1951. /* Just disable both the transmitter and reciver in the MAC. */
  1952. REG_READ(ixEthAccMacBase[portId],
  1953. IX_ETH_ACC_MAC_RX_CNTRL1,
  1954. regval);
  1955. REG_WRITE(ixEthAccMacBase[portId],
  1956. IX_ETH_ACC_MAC_RX_CNTRL1,
  1957. regval & ~IX_ETH_ACC_RX_CNTRL1_RX_EN);
  1958. REG_READ(ixEthAccMacBase[portId],
  1959. IX_ETH_ACC_MAC_TX_CNTRL1,
  1960. regval);
  1961. REG_WRITE(ixEthAccMacBase[portId],
  1962. IX_ETH_ACC_MAC_TX_CNTRL1,
  1963. regval & ~IX_ETH_ACC_TX_CNTRL1_TX_EN);
  1964. }
  1965. if(ixEthAccMacState[portId].fullDuplex)
  1966. {
  1967. ixEthAccPortDuplexModeSetPriv (portId, IX_ETH_ACC_FULL_DUPLEX);
  1968. }
  1969. else
  1970. {
  1971. ixEthAccPortDuplexModeSetPriv (portId, IX_ETH_ACC_HALF_DUPLEX);
  1972. }
  1973. if(ixEthAccMacState[portId].rxFCSAppend)
  1974. {
  1975. ixEthAccPortRxFrameAppendFCSEnablePriv (portId);
  1976. }
  1977. else
  1978. {
  1979. ixEthAccPortRxFrameAppendFCSDisablePriv (portId);
  1980. }
  1981. if(ixEthAccMacState[portId].txFCSAppend)
  1982. {
  1983. ixEthAccPortTxFrameAppendFCSEnablePriv (portId);
  1984. }
  1985. else
  1986. {
  1987. ixEthAccPortTxFrameAppendFCSDisablePriv (portId);
  1988. }
  1989. if(ixEthAccMacState[portId].txPADAppend)
  1990. {
  1991. ixEthAccPortTxFrameAppendPaddingEnablePriv (portId);
  1992. }
  1993. else
  1994. {
  1995. ixEthAccPortTxFrameAppendPaddingDisablePriv (portId);
  1996. }
  1997. if(ixEthAccMacState[portId].promiscuous)
  1998. {
  1999. ixEthAccPortPromiscuousModeSetPriv(portId);
  2000. }
  2001. else
  2002. {
  2003. ixEthAccPortPromiscuousModeClearPriv(portId);
  2004. }
  2005. if ( ixEthAccMacState[portId].enabled == true )
  2006. {
  2007. /* Enable both the transmitter and reciver in the MAC. */
  2008. REG_READ(ixEthAccMacBase[portId],
  2009. IX_ETH_ACC_MAC_RX_CNTRL1,
  2010. regval);
  2011. REG_WRITE(ixEthAccMacBase[portId],
  2012. IX_ETH_ACC_MAC_RX_CNTRL1,
  2013. regval | IX_ETH_ACC_RX_CNTRL1_RX_EN);
  2014. REG_READ(ixEthAccMacBase[portId],
  2015. IX_ETH_ACC_MAC_TX_CNTRL1,
  2016. regval);
  2017. REG_WRITE(ixEthAccMacBase[portId],
  2018. IX_ETH_ACC_MAC_TX_CNTRL1,
  2019. regval | IX_ETH_ACC_TX_CNTRL1_TX_EN);
  2020. }
  2021. }
  2022. PRIVATE BOOL
  2023. ixEthAccMacEqual(IxEthAccMacAddr *macAddr1,
  2024. IxEthAccMacAddr *macAddr2)
  2025. {
  2026. UINT32 i;
  2027. for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE; i++)
  2028. {
  2029. if(macAddr1->macAddress[i] != macAddr2->macAddress[i])
  2030. {
  2031. return false;
  2032. }
  2033. }
  2034. return true;
  2035. }
  2036. PRIVATE void
  2037. ixEthAccMacPrint(IxEthAccMacAddr *m)
  2038. {
  2039. printf("%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
  2040. m->macAddress[0], m->macAddress[1],
  2041. m->macAddress[2], m->macAddress[3],
  2042. m->macAddress[4], m->macAddress[5]);
  2043. }
  2044. /* Set the multicast address and address mask registers
  2045. *
  2046. * A bit in the address mask register must be set if
  2047. * all multicast addresses always have that bit set, or if
  2048. * all multicast addresses always have that bit cleared.
  2049. *
  2050. * A bit in the address register must be set if all multicast
  2051. * addresses have that bit set, otherwise, it should be cleared
  2052. */
  2053. PRIVATE void
  2054. ixEthAccMulticastAddressSet(IxEthAccPortId portId)
  2055. {
  2056. UINT32 i;
  2057. UINT32 j;
  2058. IxEthAccMacAddr addressMask;
  2059. IxEthAccMacAddr address;
  2060. IxEthAccMacAddr alwaysClearBits;
  2061. IxEthAccMacAddr alwaysSetBits;
  2062. /* calculate alwaysClearBits and alwaysSetBits:
  2063. * alwaysClearBits is calculated by ORing all
  2064. * multicast addresses, those bits that are always
  2065. * clear are clear in the result
  2066. *
  2067. * alwaysSetBits is calculated by ANDing all
  2068. * multicast addresses, those bits that are always set
  2069. * are set in the result
  2070. */
  2071. if (ixEthAccMacState[portId].promiscuous == true)
  2072. {
  2073. /* Promiscuous Mode is set, and filtering
  2074. * allow all packets, and enable the mcast and
  2075. * bcast detection.
  2076. */
  2077. memset(&addressMask.macAddress,
  2078. 0,
  2079. IX_IEEE803_MAC_ADDRESS_SIZE);
  2080. memset(&address.macAddress,
  2081. 0,
  2082. IX_IEEE803_MAC_ADDRESS_SIZE);
  2083. }
  2084. else
  2085. {
  2086. if(ixEthAccMacState[portId].joinAll == true)
  2087. {
  2088. /* Join all is set. The mask and address are
  2089. * the multicast settings.
  2090. */
  2091. IxEthAccMacAddr macAddr = {{0x1,0x0,0x0,0x0,0x0,0x0}};
  2092. memcpy(addressMask.macAddress,
  2093. macAddr.macAddress,
  2094. IX_IEEE803_MAC_ADDRESS_SIZE);
  2095. memcpy(address.macAddress,
  2096. macAddr.macAddress,
  2097. IX_IEEE803_MAC_ADDRESS_SIZE);
  2098. }
  2099. else if(ixEthAccMacState[portId].mcastAddrIndex == 0)
  2100. {
  2101. /* No entry in the filtering database,
  2102. * Promiscuous Mode is cleared, Broadcast filtering
  2103. * is configured.
  2104. */
  2105. memset(addressMask.macAddress,
  2106. IX_ETH_ACC_MAC_ALL_BITS_SET,
  2107. IX_IEEE803_MAC_ADDRESS_SIZE);
  2108. memset(address.macAddress,
  2109. IX_ETH_ACC_MAC_ALL_BITS_SET,
  2110. IX_IEEE803_MAC_ADDRESS_SIZE);
  2111. }
  2112. else
  2113. {
  2114. /* build a mask and an address which mix all entreis
  2115. * from the list of multicast addresses
  2116. */
  2117. memset(alwaysClearBits.macAddress,
  2118. 0,
  2119. IX_IEEE803_MAC_ADDRESS_SIZE);
  2120. memset(alwaysSetBits.macAddress,
  2121. IX_ETH_ACC_MAC_ALL_BITS_SET,
  2122. IX_IEEE803_MAC_ADDRESS_SIZE);
  2123. for(i=0;i<ixEthAccMacState[portId].mcastAddrIndex;i++)
  2124. {
  2125. for(j=0;j<IX_IEEE803_MAC_ADDRESS_SIZE;j++)
  2126. {
  2127. alwaysClearBits.macAddress[j] |=
  2128. ixEthAccMacState[portId].mcastAddrsTable[i].macAddress[j];
  2129. alwaysSetBits.macAddress[j] &=
  2130. ixEthAccMacState[portId].mcastAddrsTable[i].macAddress[j];
  2131. }
  2132. }
  2133. for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
  2134. {
  2135. addressMask.macAddress[i] = alwaysSetBits.macAddress[i]
  2136. | ~alwaysClearBits.macAddress[i];
  2137. address.macAddress[i] = alwaysSetBits.macAddress[i];
  2138. }
  2139. }
  2140. }
  2141. /*write the new addr filtering to h/w*/
  2142. for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
  2143. {
  2144. REG_WRITE(ixEthAccMacBase[portId],
  2145. IX_ETH_ACC_MAC_ADDR_MASK_1+i*sizeof(UINT32),
  2146. addressMask.macAddress[i]);
  2147. REG_WRITE(ixEthAccMacBase[portId],
  2148. IX_ETH_ACC_MAC_ADDR_1+i*sizeof(UINT32),
  2149. address.macAddress[i]);
  2150. }
  2151. }