]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/SnpDxe/snp.c
1. CoreOpenImageFile(): FilePath should be IN OUT.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / SnpDxe / snp.c
CommitLineData
8a67d61d 1/** @file\r
2Copyright (c) 2004 - 2005, Intel Corporation\r
3All rights reserved. This program and the accompanying materials\r
4are licensed and made available under the terms and conditions of the BSD License\r
5which accompanies this distribution. The full text of the license may be found at\r
6http://opensource.org/licenses/bsd-license.php\r
7\r
8THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
9WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
10\r
11Module name:\r
12 snp.c\r
13\r
14Abstract:\r
15\r
16\r
17**/\r
18\r
19#include "Snp.h"\r
20\r
21EFI_STATUS\r
22pxe_start (\r
23 SNP_DRIVER *snp\r
24 );\r
25EFI_STATUS\r
26pxe_stop (\r
27 SNP_DRIVER *snp\r
28 );\r
29EFI_STATUS\r
30pxe_init (\r
31 SNP_DRIVER *snp,\r
32 UINT16 OpFlags\r
33 );\r
34EFI_STATUS\r
35pxe_shutdown (\r
36 SNP_DRIVER *snp\r
37 );\r
38EFI_STATUS\r
39pxe_get_stn_addr (\r
40 SNP_DRIVER *snp\r
41 );\r
42\r
43EFI_STATUS\r
44EFIAPI\r
45InitializeSnpNiiDriver (\r
46 IN EFI_HANDLE image_handle,\r
47 IN EFI_SYSTEM_TABLE *system_table\r
48 );\r
49\r
50EFI_STATUS\r
51EFIAPI\r
52SimpleNetworkDriverSupported (\r
53 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
54 IN EFI_HANDLE Controller,\r
55 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
56 );\r
57\r
58EFI_STATUS\r
59EFIAPI\r
60SimpleNetworkDriverStart (\r
61 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
62 IN EFI_HANDLE Controller,\r
63 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
64 );\r
65\r
66EFI_STATUS\r
67EFIAPI\r
68SimpleNetworkDriverStop (\r
69 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
70 IN EFI_HANDLE Controller,\r
71 IN UINTN NumberOfChildren,\r
72 IN EFI_HANDLE *ChildHandleBuffer\r
73 );\r
74\r
75//\r
76// Simple Network Protocol Driver Global Variables\r
77//\r
78EFI_DRIVER_BINDING_PROTOCOL mSimpleNetworkDriverBinding = {\r
79 SimpleNetworkDriverSupported,\r
80 SimpleNetworkDriverStart,\r
81 SimpleNetworkDriverStop,\r
82 0xa,\r
83 NULL,\r
84 NULL\r
85};\r
86\r
87//\r
88// Module global variables needed to support undi 3.0 interface\r
89//\r
90EFI_PCI_IO_PROTOCOL *mPciIoFncs;\r
91struct s_v2p *_v2p = NULL; // undi3.0 map_list head\r
92// End Global variables\r
93//\r
94\r
95/**\r
96 This routine maps the given CPU address to a Device address. It creates a\r
97 an entry in the map list with the virtual and physical addresses and the\r
98 un map cookie.\r
99\r
100 @param v2p pointer to return a map list node pointer.\r
101 @param type the direction in which the data flows from the given\r
102 virtual address device->cpu or cpu->device or both\r
103 ways.\r
104 @param vaddr virtual address (or CPU address) to be mapped\r
105 @param bsize size of the buffer to be mapped.\r
106\r
107 @retval EFI_SUCEESS routine has completed the mapping\r
108 @retval other error as indicated.\r
109\r
110**/\r
111EFI_STATUS\r
112add_v2p (\r
113 IN OUT struct s_v2p **v2p,\r
114 EFI_PCI_IO_PROTOCOL_OPERATION type,\r
115 VOID *vaddr,\r
116 UINTN bsize\r
117 )\r
118{\r
119 EFI_STATUS Status;\r
120\r
121 if ((v2p == NULL) || (vaddr == NULL) || (bsize == 0)) {\r
122 return EFI_INVALID_PARAMETER;\r
123 }\r
124\r
125 *v2p = AllocatePool (sizeof (struct s_v2p));\r
126 if (*v2p != NULL) {\r
127 return EFI_OUT_OF_RESOURCES;\r
128 }\r
129\r
130 Status = mPciIoFncs->Map (\r
131 mPciIoFncs,\r
132 type,\r
133 vaddr,\r
134 &bsize,\r
135 &(*v2p)->paddr,\r
136 &(*v2p)->unmap\r
137 );\r
138 if (Status != EFI_SUCCESS) {\r
139 FreePool (*v2p);\r
140 return Status;\r
141 }\r
142 (*v2p)->vaddr = vaddr;\r
143 (*v2p)->bsize = bsize;\r
144 (*v2p)->next = _v2p;\r
145 _v2p = *v2p;\r
146\r
147 return EFI_SUCCESS;\r
148}\r
149\r
150\r
151/**\r
152 This routine searches the linked list of mapped address nodes (for undi3.0\r
153 interface) to find the node that corresponds to the given virtual address and\r
154 returns a pointer to that node.\r
155\r
156 @param v2p pointer to return a map list node pointer.\r
157 @param vaddr virtual address (or CPU address) to be searched in\r
158 the map list\r
159\r
160 @retval EFI_SUCEESS if a match found!\r
161 @retval Other match not found\r
162\r
163**/\r
164EFI_STATUS\r
165find_v2p (\r
166 struct s_v2p **v2p,\r
167 VOID *vaddr\r
168 )\r
169{\r
170 struct s_v2p *v;\r
171\r
172 if (v2p == NULL || vaddr == NULL) {\r
173 return EFI_INVALID_PARAMETER;\r
174 }\r
175\r
176 for (v = _v2p; v != NULL; v = v->next) {\r
177 if (v->vaddr == vaddr) {\r
178 *v2p = v;\r
179 return EFI_SUCCESS;\r
180 }\r
181 }\r
182\r
183 return EFI_NOT_FOUND;\r
184}\r
185\r
186\r
187/**\r
188 This routine unmaps the given virtual address and frees the memory allocated\r
189 for the map list node corresponding to that address.\r
190\r
191 @param vaddr virtual address (or CPU address) to be unmapped\r
192\r
193 @retval EFI_SUCEESS if successfully unmapped\r
194 @retval Other as indicated by the error\r
195\r
196**/\r
197EFI_STATUS\r
198del_v2p (\r
199 VOID *vaddr\r
200 )\r
201{\r
202 struct s_v2p *v;\r
203 struct s_v2p *t;\r
204 EFI_STATUS Status;\r
205\r
206 if (vaddr == NULL) {\r
207 return EFI_INVALID_PARAMETER;\r
208 }\r
209\r
210 if (_v2p == NULL) {\r
211 return EFI_NOT_FOUND;\r
212 }\r
213 //\r
214 // Is our node at the head of the list??\r
215 //\r
216 if ((v = _v2p)->vaddr == vaddr) {\r
217 _v2p = _v2p->next;\r
218\r
219 Status = mPciIoFncs->Unmap (mPciIoFncs, v->unmap);\r
220\r
221 FreePool (v);\r
222\r
223 if (Status) {\r
224 DEBUG ((EFI_D_ERROR, "Unmap failed with status = %x\n", Status));\r
225 }\r
226 return Status;\r
227 }\r
228\r
229 for (; v->next != NULL; v = t) {\r
230 if ((t = v->next)->vaddr == vaddr) {\r
231 v->next = t->next;\r
232 Status = mPciIoFncs->Unmap (mPciIoFncs, t->unmap);\r
233 FreePool (t);\r
234\r
235 if (Status) {\r
236 DEBUG ((EFI_D_ERROR, "Unmap failed with status = %x\n", Status));\r
237 }\r
238 return Status;\r
239 }\r
240 }\r
241\r
242 return EFI_NOT_FOUND;\r
243}\r
244\r
245STATIC\r
246EFI_STATUS\r
247issue_hwundi_command (\r
248 UINT64 cdb\r
249 )\r
250/*++\r
251\r
252Routine Description:\r
253\r
254Arguments:\r
255\r
256Returns:\r
257\r
258--*/\r
259{\r
260 DEBUG ((EFI_D_ERROR, "\nissue_hwundi_command() - This should not be called!"));\r
261\r
262 if (cdb == 0) {\r
263 return EFI_INVALID_PARAMETER;\r
264\r
265 }\r
266 //\r
267 // %%TBD - For now, nothing is done.\r
268 //\r
269 return EFI_UNSUPPORTED;\r
270}\r
271\r
272\r
273/**\r
274 Compute 8-bit checksum of a buffer.\r
275\r
276 @param ptr Pointer to buffer.\r
277 @param len Length of buffer in bytes.\r
278\r
279 @return 8-bit checksum of all bytes in buffer.\r
280 @return If ptr is NULL or len is zero, zero is returned.\r
281\r
282**/\r
283STATIC\r
284UINT8\r
285calc_8bit_cksum (\r
286 VOID *ptr,\r
287 UINTN len\r
288 )\r
289{\r
290 UINT8 *bptr;\r
291 UINT8 cksum;\r
292\r
293 bptr = ptr;\r
294 cksum = 0;\r
295\r
296 if (ptr == NULL || len == 0) {\r
297 return 0;\r
298 }\r
299\r
300 while (len--) {\r
301 cksum = (UINT8) (cksum +*bptr++);\r
302 }\r
303\r
304 return cksum;\r
305}\r
306\r
307\r
308/**\r
309 Test to see if this driver supports Controller. Any Controller\r
310 that contains a Nii protocol can be supported.\r
311\r
312 @param This Protocol instance pointer.\r
313 @param Controller Handle of device to test.\r
314 @param RemainingDevicePath Not used.\r
315\r
316 @retval EFI_SUCCESS This driver supports this device.\r
317 @retval EFI_ALREADY_STARTED This driver is already running on this device.\r
318 @retval other This driver does not support this device.\r
319\r
320**/\r
321EFI_STATUS\r
322EFIAPI\r
323SimpleNetworkDriverSupported (\r
324 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
325 IN EFI_HANDLE Controller,\r
326 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
327 )\r
328{\r
329 EFI_STATUS Status;\r
330 EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *NiiProtocol;\r
331 PXE_UNDI *pxe;\r
332 BOOLEAN IsUndi31;\r
333\r
334 IsUndi31 = FALSE;\r
335 Status = gBS->OpenProtocol (\r
336 Controller,\r
337 &gEfiDevicePathProtocolGuid,\r
338 NULL,\r
339 This->DriverBindingHandle,\r
340 Controller,\r
341 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
342 );\r
343 if (EFI_ERROR (Status)) {\r
344 return Status;\r
345 }\r
346\r
347 Status = gBS->OpenProtocol (\r
348 Controller,\r
349 &gEfiNetworkInterfaceIdentifierProtocolGuid_31,\r
350 (VOID **) &NiiProtocol,\r
351 This->DriverBindingHandle,\r
352 Controller,\r
353 EFI_OPEN_PROTOCOL_BY_DRIVER\r
354 );\r
355 if (Status == EFI_ALREADY_STARTED)\r
356 {\r
357 DEBUG ((EFI_D_INFO, "Support(): Already Started. on handle %x\n", Controller));\r
358 return EFI_ALREADY_STARTED;\r
359 }\r
360\r
361 if (!EFI_ERROR (Status))\r
362 {\r
363 DEBUG ((EFI_D_INFO, "Support(): UNDI3.1 found on handle %x\n", Controller));\r
364 IsUndi31 = TRUE;\r
365 } else {\r
366 //\r
367 // try the older 3.0 driver\r
368 //\r
369 Status = gBS->OpenProtocol (\r
370 Controller,\r
371 &gEfiNetworkInterfaceIdentifierProtocolGuid,\r
372 (VOID **) &NiiProtocol,\r
373 This->DriverBindingHandle,\r
374 Controller,\r
375 EFI_OPEN_PROTOCOL_BY_DRIVER\r
376 );\r
377 if (EFI_ERROR (Status)) {\r
378 return Status;\r
379 }\r
380\r
381 DEBUG ((EFI_D_INFO, "Support(): UNDI3.0 found on handle %x\n", Controller));\r
382 }\r
383 //\r
384 // check the version, we don't want to connect to the undi16\r
385 //\r
386 if (NiiProtocol->Type != EfiNetworkInterfaceUndi) {\r
387 Status = EFI_UNSUPPORTED;\r
388 goto Done;\r
389 }\r
390 //\r
391 // Check to see if !PXE structure is valid. Paragraph alignment of !PXE structure is required.\r
392 //\r
393 if (NiiProtocol->ID & 0x0F) {\r
394 DEBUG ((EFI_D_NET, "\n!PXE structure is not paragraph aligned.\n"));\r
395 Status = EFI_UNSUPPORTED;\r
396 goto Done;\r
397 }\r
398\r
399 pxe = (PXE_UNDI *) (UINTN) (NiiProtocol->ID);\r
400\r
401 //\r
402 // Verify !PXE revisions.\r
403 //\r
404 if (pxe->hw.Signature != PXE_ROMID_SIGNATURE) {\r
405 DEBUG ((EFI_D_NET, "\n!PXE signature is not valid.\n"));\r
406 Status = EFI_UNSUPPORTED;\r
407 goto Done;\r
408 }\r
409\r
410 if (pxe->hw.Rev < PXE_ROMID_REV) {\r
411 DEBUG ((EFI_D_NET, "\n!PXE.Rev is not supported.\n"));\r
412 Status = EFI_UNSUPPORTED;\r
413 goto Done;\r
414 }\r
415\r
416 if (pxe->hw.MajorVer < PXE_ROMID_MAJORVER) {\r
417\r
418 DEBUG ((EFI_D_NET, "\n!PXE.MajorVer is not supported.\n"));\r
419 Status = EFI_UNSUPPORTED;\r
420 goto Done;\r
421\r
422 } else if (pxe->hw.MajorVer == PXE_ROMID_MAJORVER && pxe->hw.MinorVer < PXE_ROMID_MINORVER) {\r
423 DEBUG ((EFI_D_NET, "\n!PXE.MinorVer is not supported."));\r
424 Status = EFI_UNSUPPORTED;\r
425 goto Done;\r
426 }\r
427 //\r
428 // Do S/W UNDI specific checks.\r
429 //\r
430 if ((pxe->hw.Implementation & PXE_ROMID_IMP_HW_UNDI) == 0) {\r
431 if (pxe->sw.EntryPoint < pxe->sw.Len) {\r
432 DEBUG ((EFI_D_NET, "\n!PXE S/W entry point is not valid."));\r
433 Status = EFI_UNSUPPORTED;\r
434 goto Done;\r
435 }\r
436\r
437 if (pxe->sw.BusCnt == 0) {\r
438 DEBUG ((EFI_D_NET, "\n!PXE.BusCnt is zero."));\r
439 Status = EFI_UNSUPPORTED;\r
440 goto Done;\r
441 }\r
442 }\r
443\r
444 Status = EFI_SUCCESS;\r
445 DEBUG ((EFI_D_INFO, "Support(): supported on %x\n", Controller));\r
446\r
447Done:\r
448 if (IsUndi31) {\r
449 gBS->CloseProtocol (\r
450 Controller,\r
451 &gEfiNetworkInterfaceIdentifierProtocolGuid_31,\r
452 This->DriverBindingHandle,\r
453 Controller\r
454 );\r
455\r
456 } else {\r
457 gBS->CloseProtocol (\r
458 Controller,\r
459 &gEfiNetworkInterfaceIdentifierProtocolGuid,\r
460 This->DriverBindingHandle,\r
461 Controller\r
462 );\r
463 }\r
464\r
465 return Status;\r
466}\r
467\r
468\r
469/**\r
470 called for any handle that we said "supported" in the above call!\r
471\r
472 @param This Protocol instance pointer.\r
473 @param Controller Handle of device to start\r
474 @param RemainingDevicePath Not used.\r
475\r
476 @retval EFI_SUCCESS This driver supports this device.\r
477 @retval other This driver failed to start this device.\r
478\r
479**/\r
480EFI_STATUS\r
481EFIAPI\r
482SimpleNetworkDriverStart (\r
483 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
484 IN EFI_HANDLE Controller,\r
485 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
486 )\r
487{\r
488 EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *Nii;\r
489 EFI_DEVICE_PATH_PROTOCOL *NiiDevicePath;\r
490 EFI_STATUS Status;\r
491 PXE_UNDI *pxe;\r
492 SNP_DRIVER *snp;\r
493 VOID *addr;\r
494 VOID *addrUnmap;\r
495 EFI_PHYSICAL_ADDRESS paddr;\r
496 EFI_HANDLE Handle;\r
497 UINTN Size;\r
498 BOOLEAN UndiNew;\r
499 PXE_PCI_CONFIG_INFO ConfigInfo;\r
500 PCI_TYPE00 *ConfigHeader;\r
501 UINT32 *TempBar;\r
502 UINT8 BarIndex;\r
503 PXE_STATFLAGS InitStatFlags;\r
504\r
505 DEBUG ((EFI_D_NET, "\nSnpNotifyNetworkInterfaceIdentifier() "));\r
506\r
507 Status = gBS->OpenProtocol (\r
508 Controller,\r
509 &gEfiDevicePathProtocolGuid,\r
510 (VOID **) &NiiDevicePath,\r
511 This->DriverBindingHandle,\r
512 Controller,\r
513 EFI_OPEN_PROTOCOL_BY_DRIVER\r
514 );\r
515\r
516 if (EFI_ERROR (Status)) {\r
517 return Status;\r
518 }\r
519\r
520 Status = gBS->LocateDevicePath (\r
521 &gEfiPciIoProtocolGuid,\r
522 &NiiDevicePath,\r
523 &Handle\r
524 );\r
525\r
526 if (EFI_ERROR (Status)) {\r
527 return Status;\r
528 }\r
529\r
530 Status = gBS->OpenProtocol (\r
531 Handle,\r
532 &gEfiPciIoProtocolGuid,\r
533 (VOID **) &mPciIoFncs,\r
534 This->DriverBindingHandle,\r
535 Controller,\r
536 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
537 );\r
538 if (EFI_ERROR (Status)) {\r
539 return Status;\r
540 }\r
541 //\r
542 // Get the NII interface. look for 3.1 undi first, if it is not there\r
543 // then look for 3.0, validate the interface.\r
544 //\r
545 Status = gBS->OpenProtocol (\r
546 Controller,\r
547 &gEfiNetworkInterfaceIdentifierProtocolGuid_31,\r
548 (VOID **) &Nii,\r
549 This->DriverBindingHandle,\r
550 Controller,\r
551 EFI_OPEN_PROTOCOL_BY_DRIVER\r
552 );\r
553 if (Status == EFI_ALREADY_STARTED) {\r
554 gBS->CloseProtocol (\r
555 Controller,\r
556 &gEfiDevicePathProtocolGuid,\r
557 This->DriverBindingHandle,\r
558 Controller\r
559 );\r
560 return Status;\r
561 }\r
562\r
563 if (!EFI_ERROR (Status)) {\r
564 //\r
565 // probably not a 3.1 UNDI\r
566 //\r
567 UndiNew = TRUE;\r
568 DEBUG ((EFI_D_INFO, "Start(): UNDI3.1 found\n"));\r
569\r
570 } else {\r
571 UndiNew = FALSE;\r
572 Status = gBS->OpenProtocol (\r
573 Controller,\r
574 &gEfiNetworkInterfaceIdentifierProtocolGuid,\r
575 (VOID **) &Nii,\r
576 This->DriverBindingHandle,\r
577 Controller,\r
578 EFI_OPEN_PROTOCOL_BY_DRIVER\r
579 );\r
580 if (EFI_ERROR (Status)) {\r
581 gBS->CloseProtocol (\r
582 Controller,\r
583 &gEfiDevicePathProtocolGuid,\r
584 This->DriverBindingHandle,\r
585 Controller\r
586 );\r
587\r
588 return Status;\r
589 }\r
590\r
591 DEBUG ((EFI_D_INFO, "Start(): UNDI3.0 found\n"));\r
592 }\r
593\r
594 pxe = (PXE_UNDI *) (UINTN) (Nii->ID);\r
595\r
596 if (calc_8bit_cksum (pxe, pxe->hw.Len) != 0) {\r
597 DEBUG ((EFI_D_NET, "\n!PXE checksum is not correct.\n"));\r
598 goto NiiError;\r
599 }\r
600\r
601 if ((pxe->hw.Implementation & PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED) != 0) {\r
602 //\r
603 // We can get any packets.\r
604 //\r
605 } else if ((pxe->hw.Implementation & PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED) != 0) {\r
606 //\r
607 // We need to be able to get broadcast packets for DHCP.\r
608 // If we do not have promiscuous support, we must at least have\r
609 // broadcast support or we cannot do DHCP!\r
610 //\r
611 } else {\r
612 DEBUG ((EFI_D_NET, "\nUNDI does not have promiscuous or broadcast support."));\r
613 goto NiiError;\r
614 }\r
615 //\r
616 // OK, we like this UNDI, and we know snp is not already there on this handle\r
617 // Allocate and initialize a new simple network protocol structure.\r
618 //\r
619 Status = mPciIoFncs->AllocateBuffer (\r
620 mPciIoFncs,\r
621 AllocateAnyPages,\r
622 EfiBootServicesData,\r
623 SNP_MEM_PAGES (sizeof (SNP_DRIVER)),\r
624 &addr,\r
625 0\r
626 );\r
627\r
628 if (Status != EFI_SUCCESS) {\r
629 DEBUG ((EFI_D_NET, "\nCould not allocate SNP_DRIVER structure.\n"));\r
630 goto NiiError;\r
631 }\r
632\r
633 snp = (SNP_DRIVER *) (UINTN) addr;\r
634\r
635 if (!UndiNew) {\r
636 Size = SNP_MEM_PAGES (sizeof (SNP_DRIVER));\r
637\r
638 Status = mPciIoFncs->Map (\r
639 mPciIoFncs,\r
640 EfiPciIoOperationBusMasterCommonBuffer,\r
641 addr,\r
642 &Size,\r
643 &paddr,\r
644 &addrUnmap\r
645 );\r
646\r
647 ASSERT (paddr);\r
648\r
649 DEBUG ((EFI_D_NET, "\nSNP_DRIVER @ %Xh, sizeof(SNP_DRIVER) == %d", addr, sizeof (SNP_DRIVER)));\r
650 snp = (SNP_DRIVER *) (UINTN) paddr;\r
651 snp->SnpDriverUnmap = addrUnmap;\r
652 }\r
653\r
654 ZeroMem (snp, sizeof (SNP_DRIVER));\r
655\r
656 snp->IoFncs = mPciIoFncs;\r
657 snp->IsOldUndi = (BOOLEAN) (!UndiNew);\r
658\r
659 snp->Signature = SNP_DRIVER_SIGNATURE;\r
660\r
661 EfiInitializeLock (&snp->lock, TPL_NOTIFY);\r
662\r
663 snp->snp.Revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION;\r
664 snp->snp.Start = snp_undi32_start;\r
665 snp->snp.Stop = snp_undi32_stop;\r
666 snp->snp.Initialize = snp_undi32_initialize;\r
667 snp->snp.Reset = snp_undi32_reset;\r
668 snp->snp.Shutdown = snp_undi32_shutdown;\r
669 snp->snp.ReceiveFilters = snp_undi32_receive_filters;\r
670 snp->snp.StationAddress = snp_undi32_station_address;\r
671 snp->snp.Statistics = snp_undi32_statistics;\r
672 snp->snp.MCastIpToMac = snp_undi32_mcast_ip_to_mac;\r
673 snp->snp.NvData = snp_undi32_nvdata;\r
674 snp->snp.GetStatus = snp_undi32_get_status;\r
675 snp->snp.Transmit = snp_undi32_transmit;\r
676 snp->snp.Receive = snp_undi32_receive;\r
677 snp->snp.WaitForPacket = NULL;\r
678\r
679 snp->snp.Mode = &snp->mode;\r
680\r
681 snp->tx_rx_bufsize = 0;\r
682 snp->tx_rx_buffer = NULL;\r
683\r
684 snp->if_num = Nii->IfNum;\r
685\r
686 if ((pxe->hw.Implementation & PXE_ROMID_IMP_HW_UNDI) != 0) {\r
687 snp->is_swundi = FALSE;\r
688 snp->issue_undi32_command = &issue_hwundi_command;\r
689 } else {\r
690 snp->is_swundi = TRUE;\r
691\r
692 if ((pxe->sw.Implementation & PXE_ROMID_IMP_SW_VIRT_ADDR) != 0) {\r
693 snp->issue_undi32_command = (issue_undi32_command) (UINTN) pxe->sw.EntryPoint;\r
694 } else {\r
695 snp->issue_undi32_command = (issue_undi32_command) (UINTN) ((UINT8) (UINTN) pxe + pxe->sw.EntryPoint);\r
696 }\r
697 }\r
698 //\r
699 // Allocate a global CPB and DB buffer for this UNDI interface.\r
700 // we do this because:\r
701 //\r
702 // -UNDI 3.0 wants all the addresses passed to it (even the cpb and db) to be\r
703 // within 2GB limit, create them here and map them so that when undi calls\r
704 // v2p callback to check if the physical address is < 2gb, we will pass.\r
705 //\r
706 // -This is not a requirement for 3.1 or later UNDIs but the code looks\r
707 // simpler if we use the same cpb, db variables for both old and new undi\r
708 // interfaces from all the SNP interface calls (we don't map the buffers\r
709 // for the newer undi interfaces though)\r
710 // .\r
711 // -it is OK to allocate one global set of CPB, DB pair for each UNDI\r
712 // interface as EFI does not multi-task and so SNP will not be re-entered!\r
713 //\r
714 Status = mPciIoFncs->AllocateBuffer (\r
715 mPciIoFncs,\r
716 AllocateAnyPages,\r
717 EfiBootServicesData,\r
718 SNP_MEM_PAGES (4096),\r
719 &addr,\r
720 0\r
721 );\r
722\r
723 if (Status != EFI_SUCCESS) {\r
724 DEBUG ((EFI_D_NET, "\nCould not allocate CPB and DB structures.\n"));\r
725 goto Error_DeleteSNP;\r
726 }\r
727\r
728 if (snp->IsOldUndi) {\r
729 Size = SNP_MEM_PAGES (4096);\r
730\r
731 Status = mPciIoFncs->Map (\r
732 mPciIoFncs,\r
733 EfiPciIoOperationBusMasterCommonBuffer,\r
734 addr,\r
735 &Size,\r
736 &paddr,\r
737 &snp->CpbUnmap\r
738 );\r
739\r
740 ASSERT (paddr);\r
741\r
742 snp->cpb = (VOID *) (UINTN) paddr;\r
743 snp->db = (VOID *) ((UINTN) paddr + 2048);\r
744 } else {\r
745 snp->cpb = (VOID *) (UINTN) addr;\r
746 snp->db = (VOID *) ((UINTN) addr + 2048);\r
747 }\r
748 //\r
749 // pxe_start call is going to give the callback functions to UNDI, these callback\r
750 // functions use the BarIndex values from the snp structure, so these must be initialized\r
751 // with default values before doing a pxe_start. The correct values can be obtained after\r
752 // getting the config information from UNDI\r
753 //\r
754 snp->MemoryBarIndex = 0;\r
755 snp->IoBarIndex = 1;\r
756\r
757 //\r
758 // we need the undi init information many times in this snp code, just get it\r
759 // once here and store it in the snp driver structure. to get Init Info\r
760 // from UNDI we have to start undi first.\r
761 //\r
762 Status = pxe_start (snp);\r
763\r
764 if (Status != EFI_SUCCESS) {\r
765 goto Error_DeleteCPBDB;\r
766 }\r
767\r
768 snp->cdb.OpCode = PXE_OPCODE_GET_INIT_INFO;\r
769 snp->cdb.OpFlags = PXE_OPFLAGS_NOT_USED;\r
770\r
771 snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;\r
772 snp->cdb.CPBaddr = PXE_DBADDR_NOT_USED;\r
773\r
774 snp->cdb.DBsize = sizeof snp->init_info;\r
775 snp->cdb.DBaddr = (UINT64)(UINTN) &snp->init_info;\r
776\r
777 snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;\r
778 snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;\r
779\r
780 snp->cdb.IFnum = snp->if_num;\r
781 snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;\r
782\r
783 DEBUG ((EFI_D_NET, "\nsnp->undi.get_init_info() "));\r
784\r
785 (*snp->issue_undi32_command) ((UINT64)(UINTN) &snp->cdb);\r
786\r
787 //\r
788 // Save the INIT Stat Code...\r
789 //\r
790 InitStatFlags = snp->cdb.StatFlags;\r
791\r
792 if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {\r
793 DEBUG ((EFI_D_NET, "\nsnp->undi.init_info() %xh:%xh\n", snp->cdb.StatFlags, snp->cdb.StatCode));\r
794 pxe_stop (snp);\r
795 goto Error_DeleteCPBDB;\r
796 }\r
797\r
798 snp->cdb.OpCode = PXE_OPCODE_GET_CONFIG_INFO;\r
799 snp->cdb.OpFlags = PXE_OPFLAGS_NOT_USED;\r
800\r
801 snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;\r
802 snp->cdb.CPBaddr = PXE_DBADDR_NOT_USED;\r
803\r
804 snp->cdb.DBsize = sizeof ConfigInfo;\r
805 snp->cdb.DBaddr = (UINT64)(UINTN) &ConfigInfo;\r
806\r
807 snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;\r
808 snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;\r
809\r
810 snp->cdb.IFnum = snp->if_num;\r
811 snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;\r
812\r
813 DEBUG ((EFI_D_NET, "\nsnp->undi.get_config_info() "));\r
814\r
815 (*snp->issue_undi32_command) ((UINT64)(UINTN) &snp->cdb);\r
816\r
817 if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {\r
818 DEBUG ((EFI_D_NET, "\nsnp->undi.config_info() %xh:%xh\n", snp->cdb.StatFlags, snp->cdb.StatCode));\r
819 pxe_stop (snp);\r
820 goto Error_DeleteCPBDB;\r
821 }\r
822 //\r
823 // Find the correct BAR to do IO.\r
824 //\r
825 //\r
826 // Enumerate through the PCI BARs for the device to determine which one is\r
827 // the IO BAR. Save the index of the BAR into the adapter info structure.\r
828 // for regular 32bit BARs, 0 is memory mapped, 1 is io mapped\r
829 //\r
830 ConfigHeader = (PCI_TYPE00 *) &ConfigInfo.Config.Byte[0];\r
831 TempBar = (UINT32 *) &ConfigHeader->Device.Bar[0];\r
832 for (BarIndex = 0; BarIndex <= 5; BarIndex++) {\r
833 if ((*TempBar & PCI_BAR_MEM_MASK) == PCI_BAR_MEM_64BIT) {\r
834 //\r
835 // This is a 64-bit memory bar, skip this and the\r
836 // next bar as well.\r
837 //\r
838 TempBar++;\r
839 }\r
840\r
841 if ((*TempBar & PCI_BAR_IO_MASK) == PCI_BAR_IO_MODE) {\r
842 snp->IoBarIndex = BarIndex;\r
843 break;\r
844 }\r
845\r
846 TempBar++;\r
847 }\r
848\r
849 //\r
850 // We allocate 2 more global buffers for undi 3.0 interface. We use these\r
851 // buffers to pass to undi when the user buffers are beyond 4GB.\r
852 // UNDI 3.0 wants all the addresses passed to it to be\r
853 // within 2GB limit, create them here and map them so that when undi calls\r
854 // v2p callback to check if the physical address is < 2gb, we will pass.\r
855 //\r
856 // For 3.1 and later UNDIs, we do not do this because undi is\r
857 // going to call the map() callback if and only if it wants to use the\r
858 // device address for any address it receives.\r
859 //\r
860 if (snp->IsOldUndi) {\r
861 //\r
862 // buffer for receive\r
863 //\r
864 Size = SNP_MEM_PAGES (snp->init_info.MediaHeaderLen + snp->init_info.FrameDataLen);\r
865 Status = mPciIoFncs->AllocateBuffer (\r
866 mPciIoFncs,\r
867 AllocateAnyPages,\r
868 EfiBootServicesData,\r
869 Size,\r
870 &addr,\r
871 0\r
872 );\r
873\r
874 if (Status != EFI_SUCCESS) {\r
875 DEBUG ((EFI_D_ERROR, "\nCould not allocate receive buffer.\n"));\r
876 goto Error_DeleteCPBDB;\r
877 }\r
878\r
879 Status = mPciIoFncs->Map (\r
880 mPciIoFncs,\r
881 EfiPciIoOperationBusMasterCommonBuffer,\r
882 addr,\r
883 &Size,\r
884 &paddr,\r
885 &snp->ReceiveBufUnmap\r
886 );\r
887\r
888 ASSERT (paddr);\r
889\r
890 snp->receive_buf = (UINT8 *) (UINTN) paddr;\r
891\r
892 //\r
893 // buffer for fill_header\r
894 //\r
895 Size = SNP_MEM_PAGES (snp->init_info.MediaHeaderLen);\r
896 Status = mPciIoFncs->AllocateBuffer (\r
897 mPciIoFncs,\r
898 AllocateAnyPages,\r
899 EfiBootServicesData,\r
900 Size,\r
901 &addr,\r
902 0\r
903 );\r
904\r
905 if (Status != EFI_SUCCESS) {\r
906 DEBUG ((EFI_D_ERROR, "\nCould not allocate fill_header buffer.\n"));\r
907 goto Error_DeleteRCVBuf;\r
908 }\r
909\r
910 Status = mPciIoFncs->Map (\r
911 mPciIoFncs,\r
912 EfiPciIoOperationBusMasterCommonBuffer,\r
913 addr,\r
914 &Size,\r
915 &paddr,\r
916 &snp->FillHdrBufUnmap\r
917 );\r
918\r
919 ASSERT (paddr);\r
920 snp->fill_hdr_buf = (UINT8 *) (UINTN) paddr;\r
921 }\r
922 //\r
923 // Initialize simple network protocol mode structure\r
924 //\r
925 snp->mode.State = EfiSimpleNetworkStopped;\r
926 snp->mode.HwAddressSize = snp->init_info.HWaddrLen;\r
927 snp->mode.MediaHeaderSize = snp->init_info.MediaHeaderLen;\r
928 snp->mode.MaxPacketSize = snp->init_info.FrameDataLen;\r
929 snp->mode.NvRamAccessSize = snp->init_info.NvWidth;\r
930 snp->mode.NvRamSize = snp->init_info.NvCount * snp->mode.NvRamAccessSize;\r
931 snp->mode.IfType = snp->init_info.IFtype;\r
932 snp->mode.MaxMCastFilterCount = snp->init_info.MCastFilterCnt;\r
933 snp->mode.MCastFilterCount = 0;\r
934\r
935 switch (InitStatFlags & PXE_STATFLAGS_CABLE_DETECT_MASK) {\r
936 case PXE_STATFLAGS_CABLE_DETECT_SUPPORTED:\r
937 snp->mode.MediaPresentSupported = TRUE;\r
938 break;\r
939\r
940 case PXE_STATFLAGS_CABLE_DETECT_NOT_SUPPORTED:\r
941 default:\r
942 snp->mode.MediaPresentSupported = FALSE;\r
943 }\r
944\r
945 if ((pxe->hw.Implementation & PXE_ROMID_IMP_STATION_ADDR_SETTABLE) != 0) {\r
946 snp->mode.MacAddressChangeable = TRUE;\r
947 } else {\r
948 snp->mode.MacAddressChangeable = FALSE;\r
949 }\r
950\r
951 if ((pxe->hw.Implementation & PXE_ROMID_IMP_MULTI_FRAME_SUPPORTED) != 0) {\r
952 snp->mode.MultipleTxSupported = TRUE;\r
953 } else {\r
954 snp->mode.MultipleTxSupported = FALSE;\r
955 }\r
956\r
957 snp->mode.ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;\r
958\r
959 if ((pxe->hw.Implementation & PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED) != 0) {\r
960 snp->mode.ReceiveFilterMask |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;\r
961\r
962 }\r
963\r
964 if ((pxe->hw.Implementation & PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED) != 0) {\r
965 snp->mode.ReceiveFilterMask |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS;\r
966\r
967 }\r
968\r
969 if ((pxe->hw.Implementation & PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED) != 0) {\r
970 snp->mode.ReceiveFilterMask |= EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;\r
971\r
972 }\r
973\r
974 if ((pxe->hw.Implementation & PXE_ROMID_IMP_FILTERED_MULTICAST_RX_SUPPORTED) != 0) {\r
975 snp->mode.ReceiveFilterMask |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST;\r
976\r
977 }\r
978\r
979 if (pxe->hw.Implementation & PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED) {\r
980 snp->mode.ReceiveFilterMask |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;\r
981\r
982 }\r
983\r
984 snp->mode.ReceiveFilterSetting = 0;\r
985\r
986 //\r
987 // need to get the station address to save in the mode structure. we need to\r
988 // initialize the UNDI first for this.\r
989 //\r
990 snp->tx_rx_bufsize = snp->init_info.MemoryRequired;\r
991 Status = pxe_init (snp, PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE);\r
992\r
993 if (Status) {\r
994 pxe_stop (snp);\r
995 goto Error_DeleteHdrBuf;\r
996 }\r
997\r
998 Status = pxe_get_stn_addr (snp);\r
999\r
1000 if (Status != EFI_SUCCESS) {\r
1001 DEBUG ((EFI_D_ERROR, "\nsnp->undi.get_station_addr() failed.\n"));\r
1002 pxe_shutdown (snp);\r
1003 pxe_stop (snp);\r
1004 goto Error_DeleteHdrBuf;\r
1005 }\r
1006\r
1007 snp->mode.MediaPresent = FALSE;\r
1008\r
1009 //\r
1010 // We should not leave UNDI started and initialized here. this DriverStart()\r
1011 // routine must only find and attach the SNP interface to UNDI layer that it\r
1012 // finds on the given handle!\r
1013 // The UNDI layer will be started when upper layers call snp->start.\r
1014 // How ever, this DriverStart() must fill up the snp mode structure which\r
1015 // contains the MAC address of the NIC. For this reason we started and\r
1016 // initialized UNDI here, now we are done, do a shutdown and stop of the\r
1017 // UNDI interface!\r
1018 //\r
1019 pxe_shutdown (snp);\r
1020 pxe_stop (snp);\r
1021\r
1022 //\r
1023 // add SNP to the undi handle\r
1024 //\r
1025 Status = gBS->InstallProtocolInterface (\r
1026 &Controller,\r
1027 &gEfiSimpleNetworkProtocolGuid,\r
1028 EFI_NATIVE_INTERFACE,\r
1029 &(snp->snp)\r
1030 );\r
1031\r
1032 if (!EFI_ERROR (Status)) {\r
1033 return Status;\r
1034 }\r
1035\r
1036Error_DeleteHdrBuf:\r
1037 if (snp->IsOldUndi) {\r
1038 Status = mPciIoFncs->Unmap (\r
1039 mPciIoFncs,\r
1040 snp->FillHdrBufUnmap\r
1041 );\r
1042 Size = SNP_MEM_PAGES (snp->init_info.MediaHeaderLen);\r
1043 mPciIoFncs->FreeBuffer (\r
1044 mPciIoFncs,\r
1045 Size,\r
1046 snp->fill_hdr_buf\r
1047 );\r
1048 }\r
1049\r
1050Error_DeleteRCVBuf:\r
1051 if (snp->IsOldUndi) {\r
1052 Status = mPciIoFncs->Unmap (\r
1053 mPciIoFncs,\r
1054 snp->ReceiveBufUnmap\r
1055 );\r
1056 Size = SNP_MEM_PAGES (snp->init_info.MediaHeaderLen + snp->init_info.FrameDataLen);\r
1057 mPciIoFncs->FreeBuffer (\r
1058 mPciIoFncs,\r
1059 Size,\r
1060 snp->receive_buf\r
1061 );\r
1062\r
1063 }\r
1064\r
1065Error_DeleteCPBDB:\r
1066 if (snp->IsOldUndi) {\r
1067 Status = mPciIoFncs->Unmap (\r
1068 mPciIoFncs,\r
1069 snp->CpbUnmap\r
1070 );\r
1071 }\r
1072\r
1073 Status = mPciIoFncs->FreeBuffer (\r
1074 mPciIoFncs,\r
1075 SNP_MEM_PAGES (4096),\r
1076 snp->cpb\r
1077 );\r
1078\r
1079Error_DeleteSNP:\r
1080 if (snp->IsOldUndi) {\r
1081 Status = mPciIoFncs->Unmap (\r
1082 mPciIoFncs,\r
1083 snp->SnpDriverUnmap\r
1084 );\r
1085 }\r
1086\r
1087 mPciIoFncs->FreeBuffer (\r
1088 mPciIoFncs,\r
1089 SNP_MEM_PAGES (sizeof (SNP_DRIVER)),\r
1090 snp\r
1091 );\r
1092NiiError:\r
1093 if (!UndiNew) {\r
1094 gBS->CloseProtocol (\r
1095 Controller,\r
1096 &gEfiNetworkInterfaceIdentifierProtocolGuid,\r
1097 This->DriverBindingHandle,\r
1098 Controller\r
1099 );\r
1100 } else {\r
1101 gBS->CloseProtocol (\r
1102 Controller,\r
1103 &gEfiNetworkInterfaceIdentifierProtocolGuid_31,\r
1104 This->DriverBindingHandle,\r
1105 Controller\r
1106 );\r
1107 }\r
1108\r
1109 gBS->CloseProtocol (\r
1110 Controller,\r
1111 &gEfiDevicePathProtocolGuid,\r
1112 This->DriverBindingHandle,\r
1113 Controller\r
1114 );\r
1115\r
1116 return Status;\r
1117}\r
1118\r
1119\r
1120/**\r
1121\r
1122\r
1123\r
1124**/\r
1125EFI_STATUS\r
1126EFIAPI\r
1127SimpleNetworkDriverStop (\r
1128 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
1129 IN EFI_HANDLE Controller,\r
1130 IN UINTN NumberOfChildren,\r
1131 IN EFI_HANDLE *ChildHandleBuffer\r
1132 )\r
1133{\r
1134 EFI_STATUS Status;\r
1135 EFI_SIMPLE_NETWORK_PROTOCOL *SnpProtocol;\r
1136 SNP_DRIVER *Snp;\r
1137\r
1138 //\r
1139 // Get our context back.\r
1140 //\r
1141 Status = gBS->OpenProtocol (\r
1142 Controller,\r
1143 &gEfiSimpleNetworkProtocolGuid,\r
1144 (VOID **) &SnpProtocol,\r
1145 This->DriverBindingHandle,\r
1146 Controller,\r
1147 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
1148 );\r
1149\r
1150 if (EFI_ERROR (Status)) {\r
1151 return EFI_UNSUPPORTED;\r
1152 }\r
1153\r
1154 Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (SnpProtocol);\r
1155\r
1156 Status = gBS->UninstallProtocolInterface (\r
1157 Controller,\r
1158 &gEfiSimpleNetworkProtocolGuid,\r
1159 &Snp->snp\r
1160 );\r
1161\r
1162 if (EFI_ERROR (Status)) {\r
1163 return Status;\r
1164 }\r
1165\r
1166 if (!Snp->IsOldUndi) {\r
1167 Status = gBS->CloseProtocol (\r
1168 Controller,\r
1169 &gEfiNetworkInterfaceIdentifierProtocolGuid_31,\r
1170 This->DriverBindingHandle,\r
1171 Controller\r
1172 );\r
1173 } else {\r
1174 Status = gBS->CloseProtocol (\r
1175 Controller,\r
1176 &gEfiNetworkInterfaceIdentifierProtocolGuid,\r
1177 This->DriverBindingHandle,\r
1178 Controller\r
1179 );\r
1180 }\r
1181\r
1182 Status = gBS->CloseProtocol (\r
1183 Controller,\r
1184 &gEfiDevicePathProtocolGuid,\r
1185 This->DriverBindingHandle,\r
1186 Controller\r
1187 );\r
1188\r
1189 pxe_shutdown (Snp);\r
1190 pxe_stop (Snp);\r
1191\r
1192 if (Snp->IsOldUndi) {\r
1193 Status = mPciIoFncs->Unmap (\r
1194 mPciIoFncs,\r
1195 Snp->FillHdrBufUnmap\r
1196 );\r
1197\r
1198 mPciIoFncs->FreeBuffer (\r
1199 mPciIoFncs,\r
1200 SNP_MEM_PAGES (Snp->init_info.MediaHeaderLen),\r
1201 Snp->fill_hdr_buf\r
1202 );\r
1203 Status = mPciIoFncs->Unmap (\r
1204 mPciIoFncs,\r
1205 Snp->ReceiveBufUnmap\r
1206 );\r
1207\r
1208 mPciIoFncs->FreeBuffer (\r
1209 mPciIoFncs,\r
1210 SNP_MEM_PAGES (Snp->init_info.MediaHeaderLen + Snp->init_info.FrameDataLen),\r
1211 Snp->receive_buf\r
1212 );\r
1213\r
1214 Status = mPciIoFncs->Unmap (\r
1215 mPciIoFncs,\r
1216 Snp->CpbUnmap\r
1217 );\r
1218 Status = mPciIoFncs->Unmap (\r
1219 mPciIoFncs,\r
1220 Snp->SnpDriverUnmap\r
1221 );\r
1222 }\r
1223\r
1224 mPciIoFncs->FreeBuffer (\r
1225 mPciIoFncs,\r
1226 SNP_MEM_PAGES (4096),\r
1227 Snp->cpb\r
1228 );\r
1229\r
1230 mPciIoFncs->FreeBuffer (\r
1231 mPciIoFncs,\r
1232 SNP_MEM_PAGES (sizeof (SNP_DRIVER)),\r
1233 Snp\r
1234 );\r
1235\r
1236 return Status;\r
1237}\r
1238\r
1239\r
1240/**\r
1241 Install all the driver protocol\r
1242\r
1243 @param entry EFI_IMAGE_ENTRY_POINT)\r
1244\r
1245 @retval EFI_SUCEESS Initialization routine has found UNDI hardware,\r
1246 loaded it's ROM, and installed a notify event for\r
1247 the Network Indentifier Interface Protocol\r
1248 successfully.\r
1249 @retval Other Return value from HandleProtocol for\r
1250 DeviceIoProtocol or LoadedImageProtocol\r
1251\r
1252**/\r
1253EFI_STATUS\r
1254EFIAPI\r
1255InitializeSnpNiiDriver (\r
1256 IN EFI_HANDLE ImageHandle,\r
1257 IN EFI_SYSTEM_TABLE *SystemTable\r
1258 )\r
1259{\r
83cbd279 1260 return EfiLibInstallDriverBindingComponentName2 (\r
1261 ImageHandle,\r
1262 SystemTable,\r
1263 &mSimpleNetworkDriverBinding,\r
1264 NULL,\r
1265 &gSimpleNetworkComponentName,\r
1266 &gSimpleNetworkComponentName2\r
1267 );\r
8a67d61d 1268}\r