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