MnpConfig.c 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924
  1. /** @file
  2. Implementation of Managed Network Protocol private services.
  3. Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include "MnpImpl.h"
  7. #include "MnpVlan.h"
  8. EFI_SERVICE_BINDING_PROTOCOL mMnpServiceBindingProtocol = {
  9. MnpServiceBindingCreateChild,
  10. MnpServiceBindingDestroyChild
  11. };
  12. EFI_MANAGED_NETWORK_PROTOCOL mMnpProtocolTemplate = {
  13. MnpGetModeData,
  14. MnpConfigure,
  15. MnpMcastIpToMac,
  16. MnpGroups,
  17. MnpTransmit,
  18. MnpReceive,
  19. MnpCancel,
  20. MnpPoll
  21. };
  22. EFI_MANAGED_NETWORK_CONFIG_DATA mMnpDefaultConfigData = {
  23. 10000000,
  24. 10000000,
  25. 0,
  26. FALSE,
  27. FALSE,
  28. FALSE,
  29. FALSE,
  30. FALSE,
  31. FALSE,
  32. FALSE
  33. };
  34. /**
  35. Add Count of net buffers to MnpDeviceData->FreeNbufQue. The length of the net
  36. buffer is specified by MnpDeviceData->BufferLength.
  37. @param[in, out] MnpDeviceData Pointer to the MNP_DEVICE_DATA.
  38. @param[in] Count Number of NET_BUFFERs to add.
  39. @retval EFI_SUCCESS The specified amount of NET_BUFs are allocated
  40. and added to MnpDeviceData->FreeNbufQue.
  41. @retval EFI_OUT_OF_RESOURCES Failed to allocate a NET_BUF structure.
  42. **/
  43. EFI_STATUS
  44. MnpAddFreeNbuf (
  45. IN OUT MNP_DEVICE_DATA *MnpDeviceData,
  46. IN UINTN Count
  47. )
  48. {
  49. EFI_STATUS Status;
  50. UINTN Index;
  51. NET_BUF *Nbuf;
  52. NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
  53. ASSERT ((Count > 0) && (MnpDeviceData->BufferLength > 0));
  54. Status = EFI_SUCCESS;
  55. for (Index = 0; Index < Count; Index++) {
  56. Nbuf = NetbufAlloc (MnpDeviceData->BufferLength + MnpDeviceData->PaddingSize);
  57. if (Nbuf == NULL) {
  58. DEBUG ((DEBUG_ERROR, "MnpAddFreeNbuf: NetBufAlloc failed.\n"));
  59. Status = EFI_OUT_OF_RESOURCES;
  60. break;
  61. }
  62. if (MnpDeviceData->PaddingSize > 0) {
  63. //
  64. // Pad padding bytes before the media header
  65. //
  66. NetbufAllocSpace (Nbuf, MnpDeviceData->PaddingSize, NET_BUF_TAIL);
  67. NetbufTrim (Nbuf, MnpDeviceData->PaddingSize, NET_BUF_HEAD);
  68. }
  69. NetbufQueAppend (&MnpDeviceData->FreeNbufQue, Nbuf);
  70. }
  71. MnpDeviceData->NbufCnt += Index;
  72. return Status;
  73. }
  74. /**
  75. Allocate a free NET_BUF from MnpDeviceData->FreeNbufQue. If there is none
  76. in the queue, first try to allocate some and add them into the queue, then
  77. fetch the NET_BUF from the updated FreeNbufQue.
  78. @param[in, out] MnpDeviceData Pointer to the MNP_DEVICE_DATA.
  79. @return Pointer to the allocated free NET_BUF structure, if NULL the
  80. operation is failed.
  81. **/
  82. NET_BUF *
  83. MnpAllocNbuf (
  84. IN OUT MNP_DEVICE_DATA *MnpDeviceData
  85. )
  86. {
  87. EFI_STATUS Status;
  88. NET_BUF_QUEUE *FreeNbufQue;
  89. NET_BUF *Nbuf;
  90. EFI_TPL OldTpl;
  91. NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
  92. FreeNbufQue = &MnpDeviceData->FreeNbufQue;
  93. OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
  94. //
  95. // Check whether there are available buffers, or else try to add some.
  96. //
  97. if (FreeNbufQue->BufNum == 0) {
  98. if ((MnpDeviceData->NbufCnt + MNP_NET_BUFFER_INCREASEMENT) > MNP_MAX_NET_BUFFER_NUM) {
  99. DEBUG (
  100. (DEBUG_ERROR,
  101. "MnpAllocNbuf: The maximum NET_BUF size is reached for MNP driver instance %p.\n",
  102. MnpDeviceData)
  103. );
  104. Nbuf = NULL;
  105. goto ON_EXIT;
  106. }
  107. Status = MnpAddFreeNbuf (MnpDeviceData, MNP_NET_BUFFER_INCREASEMENT);
  108. if (EFI_ERROR (Status)) {
  109. DEBUG (
  110. (DEBUG_ERROR,
  111. "MnpAllocNbuf: Failed to add NET_BUFs into the FreeNbufQue, %r.\n",
  112. Status)
  113. );
  114. //
  115. // Don't return NULL, perhaps MnpAddFreeNbuf does add some NET_BUFs but
  116. // the amount is less than MNP_NET_BUFFER_INCREASEMENT.
  117. //
  118. }
  119. }
  120. Nbuf = NetbufQueRemove (FreeNbufQue);
  121. //
  122. // Increase the RefCnt.
  123. //
  124. if (Nbuf != NULL) {
  125. NET_GET_REF (Nbuf);
  126. }
  127. ON_EXIT:
  128. gBS->RestoreTPL (OldTpl);
  129. return Nbuf;
  130. }
  131. /**
  132. Try to reclaim the Nbuf into the buffer pool.
  133. @param[in, out] MnpDeviceData Pointer to the mnp device context data.
  134. @param[in, out] Nbuf Pointer to the NET_BUF to free.
  135. **/
  136. VOID
  137. MnpFreeNbuf (
  138. IN OUT MNP_DEVICE_DATA *MnpDeviceData,
  139. IN OUT NET_BUF *Nbuf
  140. )
  141. {
  142. EFI_TPL OldTpl;
  143. NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
  144. ASSERT (Nbuf->RefCnt > 1);
  145. OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
  146. NET_PUT_REF (Nbuf);
  147. if (Nbuf->RefCnt == 1) {
  148. //
  149. // Trim all buffer contained in the Nbuf, then append it to the NbufQue.
  150. //
  151. NetbufTrim (Nbuf, Nbuf->TotalSize, NET_BUF_TAIL);
  152. if (NetbufAllocSpace (Nbuf, NET_VLAN_TAG_LEN, NET_BUF_HEAD) != NULL) {
  153. //
  154. // There is space reserved for vlan tag in the head, reclaim it
  155. //
  156. NetbufTrim (Nbuf, NET_VLAN_TAG_LEN, NET_BUF_TAIL);
  157. }
  158. NetbufQueAppend (&MnpDeviceData->FreeNbufQue, Nbuf);
  159. }
  160. gBS->RestoreTPL (OldTpl);
  161. }
  162. /**
  163. Add Count of TX buffers to MnpDeviceData->AllTxBufList and MnpDeviceData->FreeTxBufList.
  164. The length of the buffer is specified by MnpDeviceData->BufferLength.
  165. @param[in, out] MnpDeviceData Pointer to the MNP_DEVICE_DATA.
  166. @param[in] Count Number of TX buffers to add.
  167. @retval EFI_SUCCESS The specified amount of TX buffers are allocated.
  168. @retval EFI_OUT_OF_RESOURCES Failed to allocate a TX buffer.
  169. **/
  170. EFI_STATUS
  171. MnpAddFreeTxBuf (
  172. IN OUT MNP_DEVICE_DATA *MnpDeviceData,
  173. IN UINTN Count
  174. )
  175. {
  176. EFI_STATUS Status;
  177. UINT32 Index;
  178. MNP_TX_BUF_WRAP *TxBufWrap;
  179. NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
  180. ASSERT ((Count > 0) && (MnpDeviceData->BufferLength > 0));
  181. Status = EFI_SUCCESS;
  182. for (Index = 0; Index < Count; Index++) {
  183. TxBufWrap = (MNP_TX_BUF_WRAP *)AllocatePool (OFFSET_OF (MNP_TX_BUF_WRAP, TxBuf) + MnpDeviceData->BufferLength);
  184. if (TxBufWrap == NULL) {
  185. DEBUG ((DEBUG_ERROR, "MnpAddFreeTxBuf: TxBuf Alloc failed.\n"));
  186. Status = EFI_OUT_OF_RESOURCES;
  187. break;
  188. }
  189. DEBUG ((DEBUG_INFO, "MnpAddFreeTxBuf: Add TxBufWrap %p, TxBuf %p\n", TxBufWrap, TxBufWrap->TxBuf));
  190. TxBufWrap->Signature = MNP_TX_BUF_WRAP_SIGNATURE;
  191. TxBufWrap->InUse = FALSE;
  192. InsertTailList (&MnpDeviceData->FreeTxBufList, &TxBufWrap->WrapEntry);
  193. InsertTailList (&MnpDeviceData->AllTxBufList, &TxBufWrap->AllEntry);
  194. }
  195. MnpDeviceData->TxBufCount += Index;
  196. return Status;
  197. }
  198. /**
  199. Allocate a free TX buffer from MnpDeviceData->FreeTxBufList. If there is none
  200. in the queue, first try to recycle some from SNP, then try to allocate some and add
  201. them into the queue, then fetch the NET_BUF from the updated FreeTxBufList.
  202. @param[in, out] MnpDeviceData Pointer to the MNP_DEVICE_DATA.
  203. @return Pointer to the allocated free NET_BUF structure, if NULL the
  204. operation is failed.
  205. **/
  206. UINT8 *
  207. MnpAllocTxBuf (
  208. IN OUT MNP_DEVICE_DATA *MnpDeviceData
  209. )
  210. {
  211. EFI_TPL OldTpl;
  212. UINT8 *TxBuf;
  213. EFI_STATUS Status;
  214. LIST_ENTRY *Entry;
  215. MNP_TX_BUF_WRAP *TxBufWrap;
  216. NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
  217. OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
  218. if (IsListEmpty (&MnpDeviceData->FreeTxBufList)) {
  219. //
  220. // First try to recycle some TX buffer from SNP
  221. //
  222. Status = MnpRecycleTxBuf (MnpDeviceData);
  223. if (EFI_ERROR (Status)) {
  224. TxBuf = NULL;
  225. goto ON_EXIT;
  226. }
  227. //
  228. // If still no free TX buffer, allocate more.
  229. //
  230. if (IsListEmpty (&MnpDeviceData->FreeTxBufList)) {
  231. if ((MnpDeviceData->TxBufCount + MNP_TX_BUFFER_INCREASEMENT) > MNP_MAX_TX_BUFFER_NUM) {
  232. DEBUG (
  233. (DEBUG_ERROR,
  234. "MnpAllocTxBuf: The maximum TxBuf size is reached for MNP driver instance %p.\n",
  235. MnpDeviceData)
  236. );
  237. TxBuf = NULL;
  238. goto ON_EXIT;
  239. }
  240. Status = MnpAddFreeTxBuf (MnpDeviceData, MNP_TX_BUFFER_INCREASEMENT);
  241. if (IsListEmpty (&MnpDeviceData->FreeTxBufList)) {
  242. DEBUG (
  243. (DEBUG_ERROR,
  244. "MnpAllocNbuf: Failed to add TxBuf into the FreeTxBufList, %r.\n",
  245. Status)
  246. );
  247. TxBuf = NULL;
  248. goto ON_EXIT;
  249. }
  250. }
  251. }
  252. ASSERT (!IsListEmpty (&MnpDeviceData->FreeTxBufList));
  253. Entry = MnpDeviceData->FreeTxBufList.ForwardLink;
  254. RemoveEntryList (MnpDeviceData->FreeTxBufList.ForwardLink);
  255. TxBufWrap = NET_LIST_USER_STRUCT_S (Entry, MNP_TX_BUF_WRAP, WrapEntry, MNP_TX_BUF_WRAP_SIGNATURE);
  256. TxBufWrap->InUse = TRUE;
  257. TxBuf = TxBufWrap->TxBuf;
  258. ON_EXIT:
  259. gBS->RestoreTPL (OldTpl);
  260. return TxBuf;
  261. }
  262. /**
  263. Try to reclaim the TX buffer into the buffer pool.
  264. @param[in, out] MnpDeviceData Pointer to the mnp device context data.
  265. @param[in, out] TxBuf Pointer to the TX buffer to free.
  266. **/
  267. VOID
  268. MnpFreeTxBuf (
  269. IN OUT MNP_DEVICE_DATA *MnpDeviceData,
  270. IN OUT UINT8 *TxBuf
  271. )
  272. {
  273. MNP_TX_BUF_WRAP *TxBufWrap;
  274. EFI_TPL OldTpl;
  275. NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
  276. if (TxBuf == NULL) {
  277. return;
  278. }
  279. TxBufWrap = NET_LIST_USER_STRUCT (TxBuf, MNP_TX_BUF_WRAP, TxBuf);
  280. if (TxBufWrap->Signature != MNP_TX_BUF_WRAP_SIGNATURE) {
  281. DEBUG (
  282. (DEBUG_ERROR,
  283. "MnpFreeTxBuf: Signature check failed in MnpFreeTxBuf.\n")
  284. );
  285. return;
  286. }
  287. if (!TxBufWrap->InUse) {
  288. DEBUG (
  289. (DEBUG_WARN,
  290. "MnpFreeTxBuf: Duplicated recycle report from SNP.\n")
  291. );
  292. return;
  293. }
  294. OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
  295. InsertTailList (&MnpDeviceData->FreeTxBufList, &TxBufWrap->WrapEntry);
  296. TxBufWrap->InUse = FALSE;
  297. gBS->RestoreTPL (OldTpl);
  298. }
  299. /**
  300. Try to recycle all the transmitted buffer address from SNP.
  301. @param[in, out] MnpDeviceData Pointer to the mnp device context data.
  302. @retval EFI_SUCCESS Successed to recyclethe transmitted buffer address.
  303. @retval Others Failed to recyclethe transmitted buffer address.
  304. **/
  305. EFI_STATUS
  306. MnpRecycleTxBuf (
  307. IN OUT MNP_DEVICE_DATA *MnpDeviceData
  308. )
  309. {
  310. UINT8 *TxBuf;
  311. EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
  312. EFI_STATUS Status;
  313. Snp = MnpDeviceData->Snp;
  314. ASSERT (Snp != NULL);
  315. do {
  316. TxBuf = NULL;
  317. Status = Snp->GetStatus (Snp, NULL, (VOID **)&TxBuf);
  318. if (EFI_ERROR (Status)) {
  319. return Status;
  320. }
  321. if (TxBuf != NULL) {
  322. MnpFreeTxBuf (MnpDeviceData, TxBuf);
  323. }
  324. } while (TxBuf != NULL);
  325. return EFI_SUCCESS;
  326. }
  327. /**
  328. Initialize the mnp device context data.
  329. @param[in, out] MnpDeviceData Pointer to the mnp device context data.
  330. @param[in] ImageHandle The driver image handle.
  331. @param[in] ControllerHandle Handle of device to bind driver to.
  332. @retval EFI_SUCCESS The mnp service context is initialized.
  333. @retval EFI_UNSUPPORTED ControllerHandle does not support Simple Network Protocol.
  334. @retval Others Other errors as indicated.
  335. **/
  336. EFI_STATUS
  337. MnpInitializeDeviceData (
  338. IN OUT MNP_DEVICE_DATA *MnpDeviceData,
  339. IN EFI_HANDLE ImageHandle,
  340. IN EFI_HANDLE ControllerHandle
  341. )
  342. {
  343. EFI_STATUS Status;
  344. EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
  345. EFI_SIMPLE_NETWORK_MODE *SnpMode;
  346. MnpDeviceData->Signature = MNP_DEVICE_DATA_SIGNATURE;
  347. MnpDeviceData->ImageHandle = ImageHandle;
  348. MnpDeviceData->ControllerHandle = ControllerHandle;
  349. //
  350. // Copy the MNP Protocol interfaces from the template.
  351. //
  352. CopyMem (&MnpDeviceData->VlanConfig, &mVlanConfigProtocolTemplate, sizeof (EFI_VLAN_CONFIG_PROTOCOL));
  353. //
  354. // Open the Simple Network protocol.
  355. //
  356. Status = gBS->OpenProtocol (
  357. ControllerHandle,
  358. &gEfiSimpleNetworkProtocolGuid,
  359. (VOID **)&Snp,
  360. ImageHandle,
  361. ControllerHandle,
  362. EFI_OPEN_PROTOCOL_BY_DRIVER
  363. );
  364. if (EFI_ERROR (Status)) {
  365. return EFI_UNSUPPORTED;
  366. }
  367. //
  368. // Get MTU from Snp.
  369. //
  370. SnpMode = Snp->Mode;
  371. MnpDeviceData->Snp = Snp;
  372. //
  373. // Initialize the lists.
  374. //
  375. InitializeListHead (&MnpDeviceData->ServiceList);
  376. InitializeListHead (&MnpDeviceData->GroupAddressList);
  377. //
  378. // Get the buffer length used to allocate NET_BUF to hold data received
  379. // from SNP. Do this before fill the FreeNetBufQue.
  380. //
  381. //
  382. MnpDeviceData->BufferLength = SnpMode->MediaHeaderSize + NET_VLAN_TAG_LEN + SnpMode->MaxPacketSize + NET_ETHER_FCS_SIZE;
  383. //
  384. // Make sure the protocol headers immediately following the media header
  385. // 4-byte aligned, and also preserve additional space for VLAN tag
  386. //
  387. MnpDeviceData->PaddingSize = ((4 - SnpMode->MediaHeaderSize) & 0x3) + NET_VLAN_TAG_LEN;
  388. //
  389. // Initialize MAC string which will be used as VLAN configuration variable name
  390. //
  391. Status = NetLibGetMacString (ControllerHandle, ImageHandle, &MnpDeviceData->MacString);
  392. if (EFI_ERROR (Status)) {
  393. goto ERROR;
  394. }
  395. //
  396. // Initialize the FreeNetBufQue and pre-allocate some NET_BUFs.
  397. //
  398. NetbufQueInit (&MnpDeviceData->FreeNbufQue);
  399. Status = MnpAddFreeNbuf (MnpDeviceData, MNP_INIT_NET_BUFFER_NUM);
  400. if (EFI_ERROR (Status)) {
  401. DEBUG ((DEBUG_ERROR, "MnpInitializeDeviceData: MnpAddFreeNbuf failed, %r.\n", Status));
  402. goto ERROR;
  403. }
  404. //
  405. // Get one NET_BUF from the FreeNbufQue for rx cache.
  406. //
  407. MnpDeviceData->RxNbufCache = MnpAllocNbuf (MnpDeviceData);
  408. NetbufAllocSpace (
  409. MnpDeviceData->RxNbufCache,
  410. MnpDeviceData->BufferLength,
  411. NET_BUF_TAIL
  412. );
  413. //
  414. // Allocate buffer pool for tx.
  415. //
  416. InitializeListHead (&MnpDeviceData->FreeTxBufList);
  417. InitializeListHead (&MnpDeviceData->AllTxBufList);
  418. MnpDeviceData->TxBufCount = 0;
  419. //
  420. // Create the system poll timer.
  421. //
  422. Status = gBS->CreateEvent (
  423. EVT_NOTIFY_SIGNAL | EVT_TIMER,
  424. TPL_CALLBACK,
  425. MnpSystemPoll,
  426. MnpDeviceData,
  427. &MnpDeviceData->PollTimer
  428. );
  429. if (EFI_ERROR (Status)) {
  430. DEBUG ((DEBUG_ERROR, "MnpInitializeDeviceData: CreateEvent for poll timer failed.\n"));
  431. goto ERROR;
  432. }
  433. //
  434. // Create the timer for packet timeout check.
  435. //
  436. Status = gBS->CreateEvent (
  437. EVT_NOTIFY_SIGNAL | EVT_TIMER,
  438. TPL_CALLBACK,
  439. MnpCheckPacketTimeout,
  440. MnpDeviceData,
  441. &MnpDeviceData->TimeoutCheckTimer
  442. );
  443. if (EFI_ERROR (Status)) {
  444. DEBUG ((DEBUG_ERROR, "MnpInitializeDeviceData: CreateEvent for packet timeout check failed.\n"));
  445. goto ERROR;
  446. }
  447. //
  448. // Create the timer for media detection.
  449. //
  450. Status = gBS->CreateEvent (
  451. EVT_NOTIFY_SIGNAL | EVT_TIMER,
  452. TPL_CALLBACK,
  453. MnpCheckMediaStatus,
  454. MnpDeviceData,
  455. &MnpDeviceData->MediaDetectTimer
  456. );
  457. if (EFI_ERROR (Status)) {
  458. DEBUG ((DEBUG_ERROR, "MnpInitializeDeviceData: CreateEvent for media detection failed.\n"));
  459. goto ERROR;
  460. }
  461. ERROR:
  462. if (EFI_ERROR (Status)) {
  463. //
  464. // Free the dynamic allocated resources if necessary.
  465. //
  466. if (MnpDeviceData->MacString != NULL) {
  467. FreePool (MnpDeviceData->MacString);
  468. }
  469. if (MnpDeviceData->TimeoutCheckTimer != NULL) {
  470. gBS->CloseEvent (MnpDeviceData->TimeoutCheckTimer);
  471. }
  472. if (MnpDeviceData->MediaDetectTimer != NULL) {
  473. gBS->CloseEvent (MnpDeviceData->MediaDetectTimer);
  474. }
  475. if (MnpDeviceData->PollTimer != NULL) {
  476. gBS->CloseEvent (MnpDeviceData->PollTimer);
  477. }
  478. if (MnpDeviceData->RxNbufCache != NULL) {
  479. MnpFreeNbuf (MnpDeviceData, MnpDeviceData->RxNbufCache);
  480. }
  481. if (MnpDeviceData->FreeNbufQue.BufNum != 0) {
  482. NetbufQueFlush (&MnpDeviceData->FreeNbufQue);
  483. }
  484. //
  485. // Close the Simple Network Protocol.
  486. //
  487. gBS->CloseProtocol (
  488. ControllerHandle,
  489. &gEfiSimpleNetworkProtocolGuid,
  490. ImageHandle,
  491. ControllerHandle
  492. );
  493. }
  494. return Status;
  495. }
  496. /**
  497. Destroy the MNP device context data.
  498. @param[in, out] MnpDeviceData Pointer to the mnp device context data.
  499. @param[in] ImageHandle The driver image handle.
  500. **/
  501. VOID
  502. MnpDestroyDeviceData (
  503. IN OUT MNP_DEVICE_DATA *MnpDeviceData,
  504. IN EFI_HANDLE ImageHandle
  505. )
  506. {
  507. LIST_ENTRY *Entry;
  508. LIST_ENTRY *NextEntry;
  509. MNP_TX_BUF_WRAP *TxBufWrap;
  510. NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
  511. //
  512. // Free Vlan Config variable name string
  513. //
  514. if (MnpDeviceData->MacString != NULL) {
  515. FreePool (MnpDeviceData->MacString);
  516. }
  517. //
  518. // The GroupAddressList must be empty.
  519. //
  520. ASSERT (IsListEmpty (&MnpDeviceData->GroupAddressList));
  521. //
  522. // Close the event.
  523. //
  524. gBS->CloseEvent (MnpDeviceData->TimeoutCheckTimer);
  525. gBS->CloseEvent (MnpDeviceData->MediaDetectTimer);
  526. gBS->CloseEvent (MnpDeviceData->PollTimer);
  527. //
  528. // Free the Tx buffer pool.
  529. //
  530. NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &MnpDeviceData->AllTxBufList) {
  531. TxBufWrap = NET_LIST_USER_STRUCT (Entry, MNP_TX_BUF_WRAP, AllEntry);
  532. RemoveEntryList (Entry);
  533. FreePool (TxBufWrap);
  534. MnpDeviceData->TxBufCount--;
  535. }
  536. ASSERT (IsListEmpty (&MnpDeviceData->AllTxBufList));
  537. ASSERT (MnpDeviceData->TxBufCount == 0);
  538. //
  539. // Free the RxNbufCache.
  540. //
  541. MnpFreeNbuf (MnpDeviceData, MnpDeviceData->RxNbufCache);
  542. //
  543. // Flush the FreeNbufQue.
  544. //
  545. MnpDeviceData->NbufCnt -= MnpDeviceData->FreeNbufQue.BufNum;
  546. NetbufQueFlush (&MnpDeviceData->FreeNbufQue);
  547. //
  548. // Close the Simple Network Protocol.
  549. //
  550. gBS->CloseProtocol (
  551. MnpDeviceData->ControllerHandle,
  552. &gEfiSimpleNetworkProtocolGuid,
  553. ImageHandle,
  554. MnpDeviceData->ControllerHandle
  555. );
  556. }
  557. /**
  558. Create mnp service context data.
  559. @param[in] MnpDeviceData Pointer to the mnp device context data.
  560. @param[in] VlanId The VLAN ID.
  561. @param[in] Priority The VLAN priority. If VlanId is 0,
  562. Priority is ignored.
  563. @return A pointer to MNP_SERVICE_DATA or NULL if failed to create MNP service context.
  564. **/
  565. MNP_SERVICE_DATA *
  566. MnpCreateServiceData (
  567. IN MNP_DEVICE_DATA *MnpDeviceData,
  568. IN UINT16 VlanId,
  569. IN UINT8 Priority OPTIONAL
  570. )
  571. {
  572. EFI_HANDLE MnpServiceHandle;
  573. MNP_SERVICE_DATA *MnpServiceData;
  574. EFI_STATUS Status;
  575. EFI_SIMPLE_NETWORK_MODE *SnpMode;
  576. EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
  577. //
  578. // Initialize the Mnp Service Data.
  579. //
  580. MnpServiceData = AllocateZeroPool (sizeof (MNP_SERVICE_DATA));
  581. if (MnpServiceData == NULL) {
  582. DEBUG ((DEBUG_ERROR, "MnpCreateServiceData: Failed to allocate memory for the new Mnp Service Data.\n"));
  583. return NULL;
  584. }
  585. //
  586. // Add to MNP service list
  587. //
  588. InsertTailList (&MnpDeviceData->ServiceList, &MnpServiceData->Link);
  589. MnpServiceData->Signature = MNP_SERVICE_DATA_SIGNATURE;
  590. MnpServiceData->MnpDeviceData = MnpDeviceData;
  591. //
  592. // Copy the ServiceBinding structure.
  593. //
  594. CopyMem (&MnpServiceData->ServiceBinding, &mMnpServiceBindingProtocol, sizeof (EFI_SERVICE_BINDING_PROTOCOL));
  595. //
  596. // Initialize the lists.
  597. //
  598. InitializeListHead (&MnpServiceData->ChildrenList);
  599. SnpMode = MnpDeviceData->Snp->Mode;
  600. if (VlanId != 0) {
  601. //
  602. // Create VLAN child handle
  603. //
  604. MnpServiceHandle = MnpCreateVlanChild (
  605. MnpDeviceData->ImageHandle,
  606. MnpDeviceData->ControllerHandle,
  607. VlanId,
  608. &MnpServiceData->DevicePath
  609. );
  610. if (MnpServiceHandle == NULL) {
  611. DEBUG ((DEBUG_ERROR, "MnpCreateServiceData: Failed to create child handle.\n"));
  612. return NULL;
  613. }
  614. //
  615. // Open VLAN Config Protocol by child
  616. //
  617. Status = gBS->OpenProtocol (
  618. MnpDeviceData->ControllerHandle,
  619. &gEfiVlanConfigProtocolGuid,
  620. (VOID **)&VlanConfig,
  621. MnpDeviceData->ImageHandle,
  622. MnpServiceHandle,
  623. EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
  624. );
  625. if (EFI_ERROR (Status)) {
  626. goto Exit;
  627. }
  628. //
  629. // Reduce MTU for VLAN device
  630. //
  631. MnpServiceData->Mtu = SnpMode->MaxPacketSize - NET_VLAN_TAG_LEN;
  632. } else {
  633. //
  634. // VlanId set to 0 means rx/tx untagged frame
  635. //
  636. MnpServiceHandle = MnpDeviceData->ControllerHandle;
  637. MnpServiceData->Mtu = SnpMode->MaxPacketSize;
  638. }
  639. MnpServiceData->ServiceHandle = MnpServiceHandle;
  640. MnpServiceData->VlanId = VlanId;
  641. MnpServiceData->Priority = Priority;
  642. //
  643. // Install the MNP Service Binding Protocol
  644. //
  645. Status = gBS->InstallMultipleProtocolInterfaces (
  646. &MnpServiceHandle,
  647. &gEfiManagedNetworkServiceBindingProtocolGuid,
  648. &MnpServiceData->ServiceBinding,
  649. NULL
  650. );
  651. Exit:
  652. if (EFI_ERROR (Status)) {
  653. MnpDestroyServiceData (MnpServiceData);
  654. MnpServiceData = NULL;
  655. }
  656. return MnpServiceData;
  657. }
  658. /**
  659. Destroy the MNP service context data.
  660. @param[in, out] MnpServiceData Pointer to the mnp service context data.
  661. @retval EFI_SUCCESS The mnp service context is destroyed.
  662. @retval Others Errors as indicated.
  663. **/
  664. EFI_STATUS
  665. MnpDestroyServiceData (
  666. IN OUT MNP_SERVICE_DATA *MnpServiceData
  667. )
  668. {
  669. EFI_STATUS Status;
  670. //
  671. // Uninstall the MNP Service Binding Protocol
  672. //
  673. Status = gBS->UninstallMultipleProtocolInterfaces (
  674. MnpServiceData->ServiceHandle,
  675. &gEfiManagedNetworkServiceBindingProtocolGuid,
  676. &MnpServiceData->ServiceBinding,
  677. NULL
  678. );
  679. if (EFI_ERROR (Status)) {
  680. return Status;
  681. }
  682. if (MnpServiceData->VlanId != 0) {
  683. //
  684. // Close VlanConfig Protocol opened by VLAN child handle
  685. //
  686. Status = gBS->CloseProtocol (
  687. MnpServiceData->MnpDeviceData->ControllerHandle,
  688. &gEfiVlanConfigProtocolGuid,
  689. MnpServiceData->MnpDeviceData->ImageHandle,
  690. MnpServiceData->ServiceHandle
  691. );
  692. if (EFI_ERROR (Status)) {
  693. return Status;
  694. }
  695. //
  696. // Uninstall Device Path Protocol to destroy the VLAN child handle
  697. //
  698. Status = gBS->UninstallMultipleProtocolInterfaces (
  699. MnpServiceData->ServiceHandle,
  700. &gEfiDevicePathProtocolGuid,
  701. MnpServiceData->DevicePath,
  702. NULL
  703. );
  704. if (EFI_ERROR (Status)) {
  705. return Status;
  706. }
  707. if (MnpServiceData->DevicePath != NULL) {
  708. FreePool (MnpServiceData->DevicePath);
  709. }
  710. }
  711. //
  712. // Remove from MnpDeviceData service list
  713. //
  714. RemoveEntryList (&MnpServiceData->Link);
  715. FreePool (MnpServiceData);
  716. return Status;
  717. }
  718. /**
  719. Callback function which provided by user to remove one node in NetDestroyLinkList process.
  720. @param[in] Entry The entry to be removed.
  721. @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
  722. @retval EFI_SUCCESS The entry has been removed successfully.
  723. @retval Others Fail to remove the entry.
  724. **/
  725. EFI_STATUS
  726. EFIAPI
  727. MnpDestoryChildEntry (
  728. IN LIST_ENTRY *Entry,
  729. IN VOID *Context
  730. )
  731. {
  732. MNP_INSTANCE_DATA *Instance;
  733. EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
  734. ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *)Context;
  735. Instance = CR (Entry, MNP_INSTANCE_DATA, InstEntry, MNP_INSTANCE_DATA_SIGNATURE);
  736. return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
  737. }
  738. /**
  739. Destroy all child of the MNP service data.
  740. @param[in, out] MnpServiceData Pointer to the mnp service context data.
  741. @retval EFI_SUCCESS All child are destroyed.
  742. @retval Others Failed to destroy all child.
  743. **/
  744. EFI_STATUS
  745. MnpDestroyServiceChild (
  746. IN OUT MNP_SERVICE_DATA *MnpServiceData
  747. )
  748. {
  749. LIST_ENTRY *List;
  750. EFI_STATUS Status;
  751. UINTN ListLength;
  752. List = &MnpServiceData->ChildrenList;
  753. Status = NetDestroyLinkList (
  754. List,
  755. MnpDestoryChildEntry,
  756. &MnpServiceData->ServiceBinding,
  757. &ListLength
  758. );
  759. if (EFI_ERROR (Status) || (ListLength != 0)) {
  760. return EFI_DEVICE_ERROR;
  761. }
  762. return EFI_SUCCESS;
  763. }
  764. /**
  765. Find the MNP Service Data for given VLAN ID.
  766. @param[in] MnpDeviceData Pointer to the mnp device context data.
  767. @param[in] VlanId The VLAN ID.
  768. @return A pointer to MNP_SERVICE_DATA or NULL if not found.
  769. **/
  770. MNP_SERVICE_DATA *
  771. MnpFindServiceData (
  772. IN MNP_DEVICE_DATA *MnpDeviceData,
  773. IN UINT16 VlanId
  774. )
  775. {
  776. LIST_ENTRY *Entry;
  777. MNP_SERVICE_DATA *MnpServiceData;
  778. NET_LIST_FOR_EACH (Entry, &MnpDeviceData->ServiceList) {
  779. //
  780. // Check VLAN ID of each Mnp Service Data
  781. //
  782. MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);
  783. if (MnpServiceData->VlanId == VlanId) {
  784. return MnpServiceData;
  785. }
  786. }
  787. return NULL;
  788. }
  789. /**
  790. Initialize the mnp instance context data.
  791. @param[in] MnpServiceData Pointer to the mnp service context data.
  792. @param[in, out] Instance Pointer to the mnp instance context data
  793. to initialize.
  794. **/
  795. VOID
  796. MnpInitializeInstanceData (
  797. IN MNP_SERVICE_DATA *MnpServiceData,
  798. IN OUT MNP_INSTANCE_DATA *Instance
  799. )
  800. {
  801. NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
  802. ASSERT (Instance != NULL);
  803. //
  804. // Set the signature.
  805. //
  806. Instance->Signature = MNP_INSTANCE_DATA_SIGNATURE;
  807. //
  808. // Copy the MNP Protocol interfaces from the template.
  809. //
  810. CopyMem (&Instance->ManagedNetwork, &mMnpProtocolTemplate, sizeof (Instance->ManagedNetwork));
  811. //
  812. // Copy the default config data.
  813. //
  814. CopyMem (&Instance->ConfigData, &mMnpDefaultConfigData, sizeof (Instance->ConfigData));
  815. //
  816. // Initialize the lists.
  817. //
  818. InitializeListHead (&Instance->GroupCtrlBlkList);
  819. InitializeListHead (&Instance->RcvdPacketQueue);
  820. InitializeListHead (&Instance->RxDeliveredPacketQueue);
  821. //
  822. // Initialize the RxToken Map.
  823. //
  824. NetMapInit (&Instance->RxTokenMap);
  825. //
  826. // Save the MnpServiceData info.
  827. //
  828. Instance->MnpServiceData = MnpServiceData;
  829. }
  830. /**
  831. Check whether the token specified by Arg matches the token in Item.
  832. @param[in] Map Pointer to the NET_MAP.
  833. @param[in] Item Pointer to the NET_MAP_ITEM.
  834. @param[in] Arg Pointer to the Arg, it's a pointer to the token to
  835. check.
  836. @retval EFI_SUCCESS The token specified by Arg is different from the
  837. token in Item.
  838. @retval EFI_ACCESS_DENIED The token specified by Arg is the same as that in
  839. Item.
  840. **/
  841. EFI_STATUS
  842. EFIAPI
  843. MnpTokenExist (
  844. IN NET_MAP *Map,
  845. IN NET_MAP_ITEM *Item,
  846. IN VOID *Arg
  847. )
  848. {
  849. EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token;
  850. EFI_MANAGED_NETWORK_COMPLETION_TOKEN *TokenInItem;
  851. Token = (EFI_MANAGED_NETWORK_COMPLETION_TOKEN *)Arg;
  852. TokenInItem = (EFI_MANAGED_NETWORK_COMPLETION_TOKEN *)Item->Key;
  853. if ((Token == TokenInItem) || (Token->Event == TokenInItem->Event)) {
  854. //
  855. // The token is the same either the two tokens equals or the Events in
  856. // the two tokens are the same.
  857. //
  858. return EFI_ACCESS_DENIED;
  859. }
  860. return EFI_SUCCESS;
  861. }
  862. /**
  863. Cancel the token specified by Arg if it matches the token in Item.
  864. @param[in, out] Map Pointer to the NET_MAP.
  865. @param[in, out] Item Pointer to the NET_MAP_ITEM.
  866. @param[in] Arg Pointer to the Arg, it's a pointer to the
  867. token to cancel.
  868. @retval EFI_SUCCESS The Arg is NULL, and the token in Item is cancelled,
  869. or the Arg isn't NULL, and the token in Item is
  870. different from the Arg.
  871. @retval EFI_ABORTED The Arg isn't NULL, the token in Item mathces the
  872. Arg, and the token is cancelled.
  873. **/
  874. EFI_STATUS
  875. EFIAPI
  876. MnpCancelTokens (
  877. IN OUT NET_MAP *Map,
  878. IN OUT NET_MAP_ITEM *Item,
  879. IN VOID *Arg
  880. )
  881. {
  882. EFI_MANAGED_NETWORK_COMPLETION_TOKEN *TokenToCancel;
  883. if ((Arg != NULL) && (Item->Key != Arg)) {
  884. //
  885. // The token in Item is not the token specified by Arg.
  886. //
  887. return EFI_SUCCESS;
  888. }
  889. TokenToCancel = (EFI_MANAGED_NETWORK_COMPLETION_TOKEN *)Item->Key;
  890. //
  891. // Remove the item from the map.
  892. //
  893. NetMapRemoveItem (Map, Item, NULL);
  894. //
  895. // Cancel this token with status set to EFI_ABORTED.
  896. //
  897. TokenToCancel->Status = EFI_ABORTED;
  898. gBS->SignalEvent (TokenToCancel->Event);
  899. if (Arg != NULL) {
  900. //
  901. // Only abort the token specified by Arg if Arg isn't NULL.
  902. //
  903. return EFI_ABORTED;
  904. }
  905. return EFI_SUCCESS;
  906. }
  907. /**
  908. Start and initialize the simple network.
  909. @param[in] Snp Pointer to the simple network protocol.
  910. @retval EFI_SUCCESS The simple network protocol is started.
  911. @retval Others Other errors as indicated.
  912. **/
  913. EFI_STATUS
  914. MnpStartSnp (
  915. IN EFI_SIMPLE_NETWORK_PROTOCOL *Snp
  916. )
  917. {
  918. EFI_STATUS Status;
  919. ASSERT (Snp != NULL);
  920. //
  921. // Start the simple network.
  922. //
  923. Status = Snp->Start (Snp);
  924. if (!EFI_ERROR (Status)) {
  925. //
  926. // Initialize the simple network.
  927. //
  928. Status = Snp->Initialize (Snp, 0, 0);
  929. }
  930. return Status;
  931. }
  932. /**
  933. Stop the simple network.
  934. @param[in] MnpDeviceData Pointer to the MNP_DEVICE_DATA.
  935. @retval EFI_SUCCESS The simple network is stopped.
  936. @retval Others Other errors as indicated.
  937. **/
  938. EFI_STATUS
  939. MnpStopSnp (
  940. IN MNP_DEVICE_DATA *MnpDeviceData
  941. )
  942. {
  943. EFI_STATUS Status;
  944. EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
  945. Snp = MnpDeviceData->Snp;
  946. ASSERT (Snp != NULL);
  947. //
  948. // Recycle all the transmit buffer from SNP.
  949. //
  950. Status = MnpRecycleTxBuf (MnpDeviceData);
  951. if (EFI_ERROR (Status)) {
  952. return Status;
  953. }
  954. //
  955. // Shut down the simple network.
  956. //
  957. Status = Snp->Shutdown (Snp);
  958. if (!EFI_ERROR (Status)) {
  959. //
  960. // Stop the simple network.
  961. //
  962. Status = Snp->Stop (Snp);
  963. }
  964. return Status;
  965. }
  966. /**
  967. Start the managed network, this function is called when one instance is configured
  968. or reconfigured.
  969. @param[in, out] MnpServiceData Pointer to the mnp service context data.
  970. @param[in] IsConfigUpdate The instance is reconfigured or it's the first
  971. time the instanced is configured.
  972. @param[in] EnableSystemPoll Enable the system polling or not.
  973. @retval EFI_SUCCESS The managed network is started and some
  974. configuration is updated.
  975. @retval Others Other errors as indicated.
  976. **/
  977. EFI_STATUS
  978. MnpStart (
  979. IN OUT MNP_SERVICE_DATA *MnpServiceData,
  980. IN BOOLEAN IsConfigUpdate,
  981. IN BOOLEAN EnableSystemPoll
  982. )
  983. {
  984. EFI_STATUS Status;
  985. EFI_TIMER_DELAY TimerOpType;
  986. MNP_DEVICE_DATA *MnpDeviceData;
  987. NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
  988. Status = EFI_SUCCESS;
  989. MnpDeviceData = MnpServiceData->MnpDeviceData;
  990. if (!IsConfigUpdate) {
  991. //
  992. // If it's not a configuration update, increase the configured children number.
  993. //
  994. MnpDeviceData->ConfiguredChildrenNumber++;
  995. if (MnpDeviceData->ConfiguredChildrenNumber == 1) {
  996. //
  997. // It's the first configured child, start the simple network.
  998. //
  999. Status = MnpStartSnp (MnpDeviceData->Snp);
  1000. if (EFI_ERROR (Status)) {
  1001. DEBUG ((DEBUG_ERROR, "MnpStart: MnpStartSnp failed, %r.\n", Status));
  1002. goto ErrorExit;
  1003. }
  1004. //
  1005. // Start the timeout timer.
  1006. //
  1007. Status = gBS->SetTimer (
  1008. MnpDeviceData->TimeoutCheckTimer,
  1009. TimerPeriodic,
  1010. MNP_TIMEOUT_CHECK_INTERVAL
  1011. );
  1012. if (EFI_ERROR (Status)) {
  1013. DEBUG (
  1014. (DEBUG_ERROR,
  1015. "MnpStart, gBS->SetTimer for TimeoutCheckTimer %r.\n",
  1016. Status)
  1017. );
  1018. goto ErrorExit;
  1019. }
  1020. //
  1021. // Start the media detection timer.
  1022. //
  1023. Status = gBS->SetTimer (
  1024. MnpDeviceData->MediaDetectTimer,
  1025. TimerPeriodic,
  1026. MNP_MEDIA_DETECT_INTERVAL
  1027. );
  1028. if (EFI_ERROR (Status)) {
  1029. DEBUG (
  1030. (DEBUG_ERROR,
  1031. "MnpStart, gBS->SetTimer for MediaDetectTimer %r.\n",
  1032. Status)
  1033. );
  1034. goto ErrorExit;
  1035. }
  1036. }
  1037. }
  1038. if (MnpDeviceData->EnableSystemPoll ^ EnableSystemPoll) {
  1039. //
  1040. // The EnableSystemPoll differs with the current state, disable or enable
  1041. // the system poll.
  1042. //
  1043. TimerOpType = EnableSystemPoll ? TimerPeriodic : TimerCancel;
  1044. Status = gBS->SetTimer (MnpDeviceData->PollTimer, TimerOpType, MNP_SYS_POLL_INTERVAL);
  1045. if (EFI_ERROR (Status)) {
  1046. DEBUG ((DEBUG_ERROR, "MnpStart: gBS->SetTimer for PollTimer failed, %r.\n", Status));
  1047. goto ErrorExit;
  1048. }
  1049. MnpDeviceData->EnableSystemPoll = EnableSystemPoll;
  1050. }
  1051. //
  1052. // Change the receive filters if need.
  1053. //
  1054. Status = MnpConfigReceiveFilters (MnpDeviceData);
  1055. ErrorExit:
  1056. return Status;
  1057. }
  1058. /**
  1059. Stop the managed network.
  1060. @param[in, out] MnpServiceData Pointer to the mnp service context data.
  1061. @retval EFI_SUCCESS The managed network is stopped.
  1062. @retval Others Other errors as indicated.
  1063. **/
  1064. EFI_STATUS
  1065. MnpStop (
  1066. IN OUT MNP_SERVICE_DATA *MnpServiceData
  1067. )
  1068. {
  1069. EFI_STATUS Status;
  1070. MNP_DEVICE_DATA *MnpDeviceData;
  1071. NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
  1072. MnpDeviceData = MnpServiceData->MnpDeviceData;
  1073. ASSERT (MnpDeviceData->ConfiguredChildrenNumber > 0);
  1074. //
  1075. // Configure the receive filters.
  1076. //
  1077. MnpConfigReceiveFilters (MnpDeviceData);
  1078. //
  1079. // Decrease the children number.
  1080. //
  1081. MnpDeviceData->ConfiguredChildrenNumber--;
  1082. if (MnpDeviceData->ConfiguredChildrenNumber > 0) {
  1083. //
  1084. // If there are other configured children, return and keep the timers and
  1085. // simple network unchanged.
  1086. //
  1087. return EFI_SUCCESS;
  1088. }
  1089. //
  1090. // No configured children now.
  1091. //
  1092. if (MnpDeviceData->EnableSystemPoll) {
  1093. //
  1094. // The system poll in on, cancel the poll timer.
  1095. //
  1096. Status = gBS->SetTimer (MnpDeviceData->PollTimer, TimerCancel, 0);
  1097. MnpDeviceData->EnableSystemPoll = FALSE;
  1098. }
  1099. //
  1100. // Cancel the timeout timer.
  1101. //
  1102. Status = gBS->SetTimer (MnpDeviceData->TimeoutCheckTimer, TimerCancel, 0);
  1103. //
  1104. // Cancel the media detect timer.
  1105. //
  1106. Status = gBS->SetTimer (MnpDeviceData->MediaDetectTimer, TimerCancel, 0);
  1107. //
  1108. // Stop the simple network.
  1109. //
  1110. Status = MnpStopSnp (MnpDeviceData);
  1111. return Status;
  1112. }
  1113. /**
  1114. Flush the instance's received data.
  1115. @param[in, out] Instance Pointer to the mnp instance context data.
  1116. **/
  1117. VOID
  1118. MnpFlushRcvdDataQueue (
  1119. IN OUT MNP_INSTANCE_DATA *Instance
  1120. )
  1121. {
  1122. EFI_TPL OldTpl;
  1123. MNP_RXDATA_WRAP *RxDataWrap;
  1124. NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);
  1125. OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
  1126. while (!IsListEmpty (&Instance->RcvdPacketQueue)) {
  1127. //
  1128. // Remove all the Wraps.
  1129. //
  1130. RxDataWrap = NET_LIST_HEAD (&Instance->RcvdPacketQueue, MNP_RXDATA_WRAP, WrapEntry);
  1131. //
  1132. // Recycle the RxDataWrap.
  1133. //
  1134. MnpRecycleRxData (NULL, (VOID *)RxDataWrap);
  1135. Instance->RcvdPacketQueueSize--;
  1136. }
  1137. ASSERT (Instance->RcvdPacketQueueSize == 0);
  1138. gBS->RestoreTPL (OldTpl);
  1139. }
  1140. /**
  1141. Configure the Instance using ConfigData.
  1142. @param[in, out] Instance Pointer to the mnp instance context data.
  1143. @param[in] ConfigData Pointer to the configuration data used to configure
  1144. the instance.
  1145. @retval EFI_SUCCESS The Instance is configured.
  1146. @retval EFI_UNSUPPORTED EnableReceiveTimestamps is on and the
  1147. implementation doesn't support it.
  1148. @retval Others Other errors as indicated.
  1149. **/
  1150. EFI_STATUS
  1151. MnpConfigureInstance (
  1152. IN OUT MNP_INSTANCE_DATA *Instance,
  1153. IN EFI_MANAGED_NETWORK_CONFIG_DATA *ConfigData OPTIONAL
  1154. )
  1155. {
  1156. EFI_STATUS Status;
  1157. MNP_SERVICE_DATA *MnpServiceData;
  1158. MNP_DEVICE_DATA *MnpDeviceData;
  1159. EFI_MANAGED_NETWORK_CONFIG_DATA *OldConfigData;
  1160. EFI_MANAGED_NETWORK_CONFIG_DATA *NewConfigData;
  1161. BOOLEAN IsConfigUpdate;
  1162. NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);
  1163. if ((ConfigData != NULL) && ConfigData->EnableReceiveTimestamps) {
  1164. //
  1165. // Don't support timestamp.
  1166. //
  1167. return EFI_UNSUPPORTED;
  1168. }
  1169. Status = EFI_SUCCESS;
  1170. MnpServiceData = Instance->MnpServiceData;
  1171. MnpDeviceData = MnpServiceData->MnpDeviceData;
  1172. NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
  1173. IsConfigUpdate = (BOOLEAN)((Instance->Configured) && (ConfigData != NULL));
  1174. OldConfigData = &Instance->ConfigData;
  1175. NewConfigData = ConfigData;
  1176. if (NewConfigData == NULL) {
  1177. //
  1178. // Restore back the default config data if a reset of this instance
  1179. // is required.
  1180. //
  1181. NewConfigData = &mMnpDefaultConfigData;
  1182. }
  1183. //
  1184. // Reset the instance's receive filter.
  1185. //
  1186. Instance->ReceiveFilter = 0;
  1187. //
  1188. // Clear the receive counters according to the old ConfigData.
  1189. //
  1190. if (OldConfigData->EnableUnicastReceive) {
  1191. MnpDeviceData->UnicastCount--;
  1192. }
  1193. if (OldConfigData->EnableMulticastReceive) {
  1194. MnpDeviceData->MulticastCount--;
  1195. }
  1196. if (OldConfigData->EnableBroadcastReceive) {
  1197. MnpDeviceData->BroadcastCount--;
  1198. }
  1199. if (OldConfigData->EnablePromiscuousReceive) {
  1200. MnpDeviceData->PromiscuousCount--;
  1201. }
  1202. //
  1203. // Set the receive filter counters and the receive filter of the
  1204. // instance according to the new ConfigData.
  1205. //
  1206. if (NewConfigData->EnableUnicastReceive) {
  1207. MnpDeviceData->UnicastCount++;
  1208. Instance->ReceiveFilter |= MNP_RECEIVE_UNICAST;
  1209. }
  1210. if (NewConfigData->EnableMulticastReceive) {
  1211. MnpDeviceData->MulticastCount++;
  1212. }
  1213. if (NewConfigData->EnableBroadcastReceive) {
  1214. MnpDeviceData->BroadcastCount++;
  1215. Instance->ReceiveFilter |= MNP_RECEIVE_BROADCAST;
  1216. }
  1217. if (NewConfigData->EnablePromiscuousReceive) {
  1218. MnpDeviceData->PromiscuousCount++;
  1219. }
  1220. if (OldConfigData->FlushQueuesOnReset) {
  1221. MnpFlushRcvdDataQueue (Instance);
  1222. }
  1223. if (ConfigData == NULL) {
  1224. Instance->ManagedNetwork.Cancel (&Instance->ManagedNetwork, NULL);
  1225. }
  1226. if (!NewConfigData->EnableMulticastReceive) {
  1227. MnpGroupOp (Instance, FALSE, NULL, NULL);
  1228. }
  1229. //
  1230. // Save the new configuration data.
  1231. //
  1232. CopyMem (OldConfigData, NewConfigData, sizeof (*OldConfigData));
  1233. Instance->Configured = (BOOLEAN)(ConfigData != NULL);
  1234. if (Instance->Configured) {
  1235. //
  1236. // The instance is configured, start the Mnp.
  1237. //
  1238. Status = MnpStart (
  1239. MnpServiceData,
  1240. IsConfigUpdate,
  1241. (BOOLEAN) !NewConfigData->DisableBackgroundPolling
  1242. );
  1243. } else {
  1244. //
  1245. // The instance is changed to the unconfigured state, stop the Mnp.
  1246. //
  1247. Status = MnpStop (MnpServiceData);
  1248. }
  1249. return Status;
  1250. }
  1251. /**
  1252. Configure the Snp receive filters according to the instances' receive filter
  1253. settings.
  1254. @param[in] MnpDeviceData Pointer to the mnp device context data.
  1255. @retval EFI_SUCCESS The receive filters is configured.
  1256. @retval EFI_OUT_OF_RESOURCES The receive filters can't be configured due
  1257. to lack of memory resource.
  1258. **/
  1259. EFI_STATUS
  1260. MnpConfigReceiveFilters (
  1261. IN MNP_DEVICE_DATA *MnpDeviceData
  1262. )
  1263. {
  1264. EFI_STATUS Status;
  1265. EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
  1266. EFI_MAC_ADDRESS *MCastFilter;
  1267. UINT32 MCastFilterCnt;
  1268. UINT32 EnableFilterBits;
  1269. UINT32 DisableFilterBits;
  1270. BOOLEAN ResetMCastFilters;
  1271. LIST_ENTRY *Entry;
  1272. UINT32 Index;
  1273. MNP_GROUP_ADDRESS *GroupAddress;
  1274. NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
  1275. Snp = MnpDeviceData->Snp;
  1276. //
  1277. // Initialize the enable filter and disable filter.
  1278. //
  1279. EnableFilterBits = 0;
  1280. DisableFilterBits = Snp->Mode->ReceiveFilterMask;
  1281. if (MnpDeviceData->UnicastCount != 0) {
  1282. //
  1283. // Enable unicast if any instance wants to receive unicast.
  1284. //
  1285. EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
  1286. }
  1287. if (MnpDeviceData->BroadcastCount != 0) {
  1288. //
  1289. // Enable broadcast if any instance wants to receive broadcast.
  1290. //
  1291. EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
  1292. }
  1293. MCastFilter = NULL;
  1294. MCastFilterCnt = 0;
  1295. ResetMCastFilters = TRUE;
  1296. if ((MnpDeviceData->MulticastCount != 0) && (MnpDeviceData->GroupAddressCount != 0)) {
  1297. //
  1298. // There are instances configured to receive multicast and already some group
  1299. // addresses are joined.
  1300. //
  1301. ResetMCastFilters = FALSE;
  1302. if (MnpDeviceData->GroupAddressCount <= Snp->Mode->MaxMCastFilterCount) {
  1303. //
  1304. // The joind group address is less than simple network's maximum count.
  1305. // Just configure the snp to do the multicast filtering.
  1306. //
  1307. EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST;
  1308. //
  1309. // Allocate pool for the multicast addresses.
  1310. //
  1311. MCastFilterCnt = MnpDeviceData->GroupAddressCount;
  1312. MCastFilter = AllocatePool (sizeof (EFI_MAC_ADDRESS) * MCastFilterCnt);
  1313. if (MCastFilter == NULL) {
  1314. DEBUG ((DEBUG_ERROR, "MnpConfigReceiveFilters: Failed to allocate memory resource for MCastFilter.\n"));
  1315. return EFI_OUT_OF_RESOURCES;
  1316. }
  1317. //
  1318. // Fill the multicast HW address buffer.
  1319. //
  1320. Index = 0;
  1321. NET_LIST_FOR_EACH (Entry, &MnpDeviceData->GroupAddressList) {
  1322. GroupAddress = NET_LIST_USER_STRUCT (Entry, MNP_GROUP_ADDRESS, AddrEntry);
  1323. CopyMem (MCastFilter + Index, &GroupAddress->Address, sizeof (*(MCastFilter + Index)));
  1324. Index++;
  1325. ASSERT (Index <= MCastFilterCnt);
  1326. }
  1327. } else {
  1328. //
  1329. // The maximum multicast is reached, set the filter to be promiscuous
  1330. // multicast.
  1331. //
  1332. if ((Snp->Mode->ReceiveFilterMask & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) {
  1333. EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
  1334. } else {
  1335. //
  1336. // Either MULTICAST or PROMISCUOUS_MULTICAST is not supported by Snp,
  1337. // set the NIC to be promiscuous although this will tremendously degrade
  1338. // the performance.
  1339. //
  1340. EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS;
  1341. }
  1342. }
  1343. }
  1344. if (MnpDeviceData->PromiscuousCount != 0) {
  1345. //
  1346. // Enable promiscuous if any instance wants to receive promiscuous.
  1347. //
  1348. EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS;
  1349. }
  1350. //
  1351. // Set the disable filter.
  1352. //
  1353. DisableFilterBits ^= EnableFilterBits;
  1354. //
  1355. // Configure the receive filters of SNP.
  1356. //
  1357. Status = Snp->ReceiveFilters (
  1358. Snp,
  1359. EnableFilterBits,
  1360. DisableFilterBits,
  1361. ResetMCastFilters,
  1362. MCastFilterCnt,
  1363. MCastFilter
  1364. );
  1365. DEBUG_CODE_BEGIN ();
  1366. if (EFI_ERROR (Status)) {
  1367. DEBUG (
  1368. (DEBUG_ERROR,
  1369. "MnpConfigReceiveFilters: Snp->ReceiveFilters failed, %r.\n",
  1370. Status)
  1371. );
  1372. }
  1373. DEBUG_CODE_END ();
  1374. if (MCastFilter != NULL) {
  1375. //
  1376. // Free the buffer used to hold the group addresses.
  1377. //
  1378. FreePool (MCastFilter);
  1379. }
  1380. return Status;
  1381. }
  1382. /**
  1383. Add a group address control block which controls the MacAddress for
  1384. this instance.
  1385. @param[in, out] Instance Pointer to the mnp instance context data.
  1386. @param[in, out] CtrlBlk Pointer to the group address control block.
  1387. @param[in, out] GroupAddress Pointer to the group address.
  1388. @param[in] MacAddress Pointer to the mac address.
  1389. @param[in] HwAddressSize The hardware address size.
  1390. @retval EFI_SUCCESS The group address control block is added.
  1391. @retval EFI_OUT_OF_RESOURCES Failed due to lack of memory resources.
  1392. **/
  1393. EFI_STATUS
  1394. MnpGroupOpAddCtrlBlk (
  1395. IN OUT MNP_INSTANCE_DATA *Instance,
  1396. IN OUT MNP_GROUP_CONTROL_BLOCK *CtrlBlk,
  1397. IN OUT MNP_GROUP_ADDRESS *GroupAddress OPTIONAL,
  1398. IN EFI_MAC_ADDRESS *MacAddress,
  1399. IN UINT32 HwAddressSize
  1400. )
  1401. {
  1402. MNP_DEVICE_DATA *MnpDeviceData;
  1403. NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);
  1404. MnpDeviceData = Instance->MnpServiceData->MnpDeviceData;
  1405. NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
  1406. if (GroupAddress == NULL) {
  1407. ASSERT (MacAddress != NULL);
  1408. //
  1409. // Allocate a new GroupAddress to be added into MNP's GroupAddressList.
  1410. //
  1411. GroupAddress = AllocatePool (sizeof (MNP_GROUP_ADDRESS));
  1412. if (GroupAddress == NULL) {
  1413. DEBUG ((DEBUG_ERROR, "MnpGroupOpFormCtrlBlk: Failed to allocate memory resource.\n"));
  1414. return EFI_OUT_OF_RESOURCES;
  1415. }
  1416. CopyMem (&GroupAddress->Address, MacAddress, sizeof (GroupAddress->Address));
  1417. GroupAddress->RefCnt = 0;
  1418. InsertTailList (
  1419. &MnpDeviceData->GroupAddressList,
  1420. &GroupAddress->AddrEntry
  1421. );
  1422. MnpDeviceData->GroupAddressCount++;
  1423. }
  1424. //
  1425. // Increase the RefCnt.
  1426. //
  1427. GroupAddress->RefCnt++;
  1428. //
  1429. // Add the CtrlBlk into the instance's GroupCtrlBlkList.
  1430. //
  1431. CtrlBlk->GroupAddress = GroupAddress;
  1432. InsertTailList (&Instance->GroupCtrlBlkList, &CtrlBlk->CtrlBlkEntry);
  1433. return EFI_SUCCESS;
  1434. }
  1435. /**
  1436. Delete a group control block from the instance. If the controlled group address's
  1437. reference count reaches zero, the group address is removed too.
  1438. @param[in] Instance Pointer to the instance context data.
  1439. @param[in] CtrlBlk Pointer to the group control block to delete.
  1440. @return The group address controlled by the control block is no longer used or not.
  1441. **/
  1442. BOOLEAN
  1443. MnpGroupOpDelCtrlBlk (
  1444. IN MNP_INSTANCE_DATA *Instance,
  1445. IN MNP_GROUP_CONTROL_BLOCK *CtrlBlk
  1446. )
  1447. {
  1448. MNP_DEVICE_DATA *MnpDeviceData;
  1449. MNP_GROUP_ADDRESS *GroupAddress;
  1450. NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);
  1451. MnpDeviceData = Instance->MnpServiceData->MnpDeviceData;
  1452. NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
  1453. //
  1454. // Remove and free the CtrlBlk.
  1455. //
  1456. GroupAddress = CtrlBlk->GroupAddress;
  1457. RemoveEntryList (&CtrlBlk->CtrlBlkEntry);
  1458. FreePool (CtrlBlk);
  1459. ASSERT (GroupAddress->RefCnt > 0);
  1460. //
  1461. // Count down the RefCnt.
  1462. //
  1463. GroupAddress->RefCnt--;
  1464. if (GroupAddress->RefCnt == 0) {
  1465. //
  1466. // Free this GroupAddress entry if no instance uses it.
  1467. //
  1468. MnpDeviceData->GroupAddressCount--;
  1469. RemoveEntryList (&GroupAddress->AddrEntry);
  1470. FreePool (GroupAddress);
  1471. return TRUE;
  1472. }
  1473. return FALSE;
  1474. }
  1475. /**
  1476. Do the group operations for this instance.
  1477. @param[in, out] Instance Pointer to the instance context data.
  1478. @param[in] JoinFlag Set to TRUE to join a group. Set to TRUE to
  1479. leave a group/groups.
  1480. @param[in] MacAddress Pointer to the group address to join or leave.
  1481. @param[in] CtrlBlk Pointer to the group control block if JoinFlag
  1482. is FALSE.
  1483. @retval EFI_SUCCESS The group operation finished.
  1484. @retval EFI_OUT_OF_RESOURCES Failed due to lack of memory resources.
  1485. @retval Others Other errors as indicated.
  1486. **/
  1487. EFI_STATUS
  1488. MnpGroupOp (
  1489. IN OUT MNP_INSTANCE_DATA *Instance,
  1490. IN BOOLEAN JoinFlag,
  1491. IN EFI_MAC_ADDRESS *MacAddress OPTIONAL,
  1492. IN MNP_GROUP_CONTROL_BLOCK *CtrlBlk OPTIONAL
  1493. )
  1494. {
  1495. MNP_DEVICE_DATA *MnpDeviceData;
  1496. LIST_ENTRY *Entry;
  1497. LIST_ENTRY *NextEntry;
  1498. MNP_GROUP_ADDRESS *GroupAddress;
  1499. EFI_SIMPLE_NETWORK_MODE *SnpMode;
  1500. MNP_GROUP_CONTROL_BLOCK *NewCtrlBlk;
  1501. EFI_STATUS Status;
  1502. BOOLEAN AddressExist;
  1503. BOOLEAN NeedUpdate;
  1504. NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);
  1505. MnpDeviceData = Instance->MnpServiceData->MnpDeviceData;
  1506. SnpMode = MnpDeviceData->Snp->Mode;
  1507. if (JoinFlag) {
  1508. //
  1509. // A new group address is to be added.
  1510. //
  1511. GroupAddress = NULL;
  1512. AddressExist = FALSE;
  1513. //
  1514. // Allocate memory for the control block.
  1515. //
  1516. NewCtrlBlk = AllocatePool (sizeof (MNP_GROUP_CONTROL_BLOCK));
  1517. if (NewCtrlBlk == NULL) {
  1518. DEBUG ((DEBUG_ERROR, "MnpGroupOp: Failed to allocate memory resource.\n"));
  1519. return EFI_OUT_OF_RESOURCES;
  1520. }
  1521. NET_LIST_FOR_EACH (Entry, &MnpDeviceData->GroupAddressList) {
  1522. //
  1523. // Check whether the MacAddress is already joined by other instances.
  1524. //
  1525. GroupAddress = NET_LIST_USER_STRUCT (Entry, MNP_GROUP_ADDRESS, AddrEntry);
  1526. if (CompareMem (MacAddress, &GroupAddress->Address, SnpMode->HwAddressSize) == 0) {
  1527. AddressExist = TRUE;
  1528. break;
  1529. }
  1530. }
  1531. if (!AddressExist) {
  1532. GroupAddress = NULL;
  1533. }
  1534. //
  1535. // Add the GroupAddress for this instance.
  1536. //
  1537. Status = MnpGroupOpAddCtrlBlk (
  1538. Instance,
  1539. NewCtrlBlk,
  1540. GroupAddress,
  1541. MacAddress,
  1542. SnpMode->HwAddressSize
  1543. );
  1544. if (EFI_ERROR (Status)) {
  1545. return Status;
  1546. }
  1547. NeedUpdate = TRUE;
  1548. } else {
  1549. if (MacAddress != NULL) {
  1550. ASSERT (CtrlBlk != NULL);
  1551. //
  1552. // Leave the specific multicast mac address.
  1553. //
  1554. NeedUpdate = MnpGroupOpDelCtrlBlk (Instance, CtrlBlk);
  1555. } else {
  1556. //
  1557. // Leave all multicast mac addresses.
  1558. //
  1559. NeedUpdate = FALSE;
  1560. NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Instance->GroupCtrlBlkList) {
  1561. NewCtrlBlk = NET_LIST_USER_STRUCT (
  1562. Entry,
  1563. MNP_GROUP_CONTROL_BLOCK,
  1564. CtrlBlkEntry
  1565. );
  1566. //
  1567. // Update is required if the group address left is no longer used
  1568. // by other instances.
  1569. //
  1570. NeedUpdate = MnpGroupOpDelCtrlBlk (Instance, NewCtrlBlk);
  1571. }
  1572. }
  1573. }
  1574. Status = EFI_SUCCESS;
  1575. if (NeedUpdate) {
  1576. //
  1577. // Reconfigure the receive filters if necessary.
  1578. //
  1579. Status = MnpConfigReceiveFilters (MnpDeviceData);
  1580. }
  1581. return Status;
  1582. }