6c5bf15e8b4cbede41271ebfceaf8c59c2797969
[mirror_edk2.git] / MdeModulePkg / Universal / Network / SnpDxe / Mcast_ip_to_mac.c
1 /** @file\r
2 Copyright (c) 2004 - 2007, Intel Corporation\r
3 All rights reserved. This program and the accompanying materials\r
4 are licensed and made available under the terms and conditions of the BSD License\r
5 which accompanies this distribution.  The full text of the license may be found at\r
6 http://opensource.org/licenses/bsd-license.php\r
7 \r
8 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
9 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
10 \r
11 Module name:\r
12   mcast_ip_to_mac.c\r
13 \r
14 Abstract:\r
15 \r
16 Revision history:\r
17   2000-Feb-17 M(f)J   Genesis.\r
18 \r
19 **/\r
20 \r
21 #include "Snp.h"\r
22 \r
23 /**\r
24   this routine calls undi to convert an multicast IP address to a MAC address\r
25 \r
26   @param  snp   pointer to snp driver structure\r
27   @param  IPv6  flag to indicate if this is an ipv6 address\r
28   @param  IP    multicast IP address\r
29   @param  MAC   pointer to hold the return MAC address\r
30 \r
31 \r
32 **/\r
33 EFI_STATUS\r
34 pxe_ip2mac (\r
35   IN SNP_DRIVER          *snp,\r
36   IN BOOLEAN             IPv6,\r
37   IN EFI_IP_ADDRESS      *IP,\r
38   IN OUT EFI_MAC_ADDRESS *MAC\r
39   )\r
40 {\r
41   PXE_CPB_MCAST_IP_TO_MAC *cpb;\r
42   PXE_DB_MCAST_IP_TO_MAC  *db;\r
43 \r
44   cpb                 = snp->cpb;\r
45   db                  = snp->db;\r
46   snp->cdb.OpCode     = PXE_OPCODE_MCAST_IP_TO_MAC;\r
47   snp->cdb.OpFlags    = (UINT16) (IPv6 ? PXE_OPFLAGS_MCAST_IPV6_TO_MAC : PXE_OPFLAGS_MCAST_IPV4_TO_MAC);\r
48   snp->cdb.CPBsize    = sizeof (PXE_CPB_MCAST_IP_TO_MAC);\r
49   snp->cdb.DBsize     = sizeof (PXE_DB_MCAST_IP_TO_MAC);\r
50 \r
51   snp->cdb.CPBaddr    = (UINT64)(UINTN) cpb;\r
52   snp->cdb.DBaddr     = (UINT64)(UINTN) db;\r
53 \r
54   snp->cdb.StatCode   = PXE_STATCODE_INITIALIZE;\r
55   snp->cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;\r
56   snp->cdb.IFnum      = snp->if_num;\r
57   snp->cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;\r
58 \r
59   CopyMem (&cpb->IP, IP, sizeof (PXE_IP_ADDR));\r
60 \r
61   //\r
62   // Issue UNDI command and check result.\r
63   //\r
64   DEBUG ((EFI_D_NET, "\nsnp->undi.mcast_ip_to_mac()  "));\r
65 \r
66   (*snp->issue_undi32_command) ((UINT64)(UINTN) &snp->cdb);\r
67 \r
68   switch (snp->cdb.StatCode) {\r
69   case PXE_STATCODE_SUCCESS:\r
70     break;\r
71 \r
72   case PXE_STATCODE_INVALID_CPB:\r
73     return EFI_INVALID_PARAMETER;\r
74 \r
75   case PXE_STATCODE_UNSUPPORTED:\r
76     DEBUG (\r
77       (EFI_D_NET,\r
78       "\nsnp->undi.mcast_ip_to_mac()  %xh:%xh\n",\r
79       snp->cdb.StatFlags,\r
80       snp->cdb.StatCode)\r
81       );\r
82     return EFI_UNSUPPORTED;\r
83 \r
84   default:\r
85     //\r
86     // UNDI command failed.  Return EFI_DEVICE_ERROR\r
87     // to caller.\r
88     //\r
89     DEBUG (\r
90       (EFI_D_NET,\r
91       "\nsnp->undi.mcast_ip_to_mac()  %xh:%xh\n",\r
92       snp->cdb.StatFlags,\r
93       snp->cdb.StatCode)\r
94       );\r
95 \r
96     return EFI_DEVICE_ERROR;\r
97   }\r
98 \r
99   CopyMem (MAC, &db->MAC, sizeof (PXE_MAC_ADDR));\r
100   return EFI_SUCCESS;\r
101 }\r
102 \r
103 \r
104 /**\r
105   This is the SNP interface routine for converting a multicast IP address to\r
106   a MAC address.\r
107   This routine basically retrieves snp structure, checks the SNP state and\r
108   calls the pxe_ip2mac routine to actually do the conversion\r
109 \r
110   @param  this  context pointer\r
111   @param  IPv6  flag to indicate if this is an ipv6 address\r
112   @param  IP    multicast IP address\r
113   @param  MAC   pointer to hold the return MAC address\r
114 \r
115 \r
116 **/\r
117 EFI_STATUS\r
118 EFIAPI\r
119 snp_undi32_mcast_ip_to_mac (\r
120   IN EFI_SIMPLE_NETWORK_PROTOCOL *this,\r
121   IN BOOLEAN                     IPv6,\r
122   IN EFI_IP_ADDRESS              *IP,\r
123   OUT EFI_MAC_ADDRESS            *MAC\r
124   )\r
125 {\r
126   SNP_DRIVER  *snp;\r
127   EFI_TPL     OldTpl;\r
128   EFI_STATUS  Status;\r
129 \r
130   //\r
131   // Get pointer to SNP driver instance for *this.\r
132   //\r
133   if (this == NULL) {\r
134     return EFI_INVALID_PARAMETER;\r
135   }\r
136 \r
137   if (IP == NULL || MAC == NULL) {\r
138     return EFI_INVALID_PARAMETER;\r
139   }\r
140 \r
141   snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);\r
142 \r
143   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
144 \r
145   switch (snp->mode.State) {\r
146   case EfiSimpleNetworkInitialized:\r
147     break;\r
148 \r
149   case EfiSimpleNetworkStopped:\r
150     Status = EFI_NOT_STARTED;\r
151     goto ON_EXIT;\r
152 \r
153   default:\r
154     Status = EFI_DEVICE_ERROR;\r
155     goto ON_EXIT;\r
156   }\r
157 \r
158   Status = pxe_ip2mac (snp, IPv6, IP, MAC);\r
159 \r
160 ON_EXIT:\r
161   gBS->RestoreTPL (OldTpl);\r
162 \r
163   return Status;\r
164 }\r