sync comments, fix function header, rename variable name to follow coding style.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / SnpDxe / Get_status.c
1 /** @file\r
2                 Implementation of reading the current interrupt status and recycled transmit\r
3           buffer status from a network interface.\r
4 \r
5 Copyright (c) 2004 - 2007, Intel Corporation. <BR> \r
6 All rights reserved. This program and the accompanying materials are licensed \r
7 and made available under the terms and conditions of the BSD License which \r
8 accompanies this distribution. The full text of the license may be found at \r
9 http://opensource.org/licenses/bsd-license.php \r
10 \r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13 \r
14 **/\r
15 \r
16 #include "Snp.h"\r
17 \r
18 /**\r
19   this routine calls undi to get the status of the interrupts, get the list of\r
20   transmit buffers that completed transmitting!\r
21 \r
22   @param  Snp                     pointer to snp driver structure\r
23   @param  InterruptStatusPtr      a non null pointer gets the interrupt status\r
24   @param  TransmitBufferListPtrs  a non null ointer gets the list of pointers of\r
25                                   previously  transmitted buffers whose\r
26                                   transmission was completed  asynchrnously.\r
27 \r
28 \r
29 **/\r
30 EFI_STATUS\r
31 PxeGetStatus (\r
32   SNP_DRIVER *Snp,\r
33   UINT32     *InterruptStatusPtr,\r
34   VOID       **TransmitBufferListPtr\r
35   )\r
36 {\r
37   PXE_DB_GET_STATUS *Db;\r
38   UINT16            InterruptFlags;\r
39 \r
40   Db                = Snp->Db;\r
41   Snp->Cdb.OpCode   = PXE_OPCODE_GET_STATUS;\r
42 \r
43   Snp->Cdb.OpFlags  = 0;\r
44 \r
45   if (TransmitBufferListPtr != NULL) {\r
46     Snp->Cdb.OpFlags |= PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS;\r
47   }\r
48 \r
49   if (InterruptStatusPtr != NULL) {\r
50     Snp->Cdb.OpFlags |= PXE_OPFLAGS_GET_INTERRUPT_STATUS;\r
51   }\r
52 \r
53   Snp->Cdb.CPBsize  = PXE_CPBSIZE_NOT_USED;\r
54   Snp->Cdb.CPBaddr  = PXE_CPBADDR_NOT_USED;\r
55 \r
56   //\r
57   // size DB for return of one buffer\r
58   //\r
59   Snp->Cdb.DBsize     = (UINT16) ((sizeof (PXE_DB_GET_STATUS) - sizeof (Db->TxBuffer)) + sizeof (Db->TxBuffer[0]));\r
60 \r
61   Snp->Cdb.DBaddr     = (UINT64)(UINTN) Db;\r
62 \r
63   Snp->Cdb.StatCode   = PXE_STATCODE_INITIALIZE;\r
64   Snp->Cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;\r
65   Snp->Cdb.IFnum      = Snp->IfNum;\r
66   Snp->Cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;\r
67 \r
68   //\r
69   // Issue UNDI command and check result.\r
70   //\r
71   DEBUG ((EFI_D_NET, "\nSnp->undi.get_status()  "));\r
72 \r
73   (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);\r
74 \r
75   if (Snp->Cdb.StatCode != EFI_SUCCESS) {\r
76     DEBUG (\r
77       (EFI_D_NET,\r
78       "\nSnp->undi.get_status()  %xh:%xh\n",\r
79       Snp->Cdb.StatFlags,\r
80       Snp->Cdb.StatFlags)\r
81       );\r
82 \r
83     return EFI_DEVICE_ERROR;\r
84   }\r
85   //\r
86   // report the values back..\r
87   //\r
88   if (InterruptStatusPtr != NULL) {\r
89     InterruptFlags      = (UINT16) (Snp->Cdb.StatFlags & PXE_STATFLAGS_GET_STATUS_INTERRUPT_MASK);\r
90 \r
91     *InterruptStatusPtr = 0;\r
92 \r
93     if ((InterruptFlags & PXE_STATFLAGS_GET_STATUS_RECEIVE) == PXE_STATFLAGS_GET_STATUS_RECEIVE) {\r
94       *InterruptStatusPtr |= EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;\r
95     }\r
96 \r
97     if ((InterruptFlags & PXE_STATFLAGS_GET_STATUS_TRANSMIT) == PXE_STATFLAGS_GET_STATUS_TRANSMIT) {\r
98       *InterruptStatusPtr |= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;\r
99     }\r
100 \r
101     if ((InterruptFlags & PXE_STATFLAGS_GET_STATUS_COMMAND) == PXE_STATFLAGS_GET_STATUS_COMMAND) {\r
102       *InterruptStatusPtr |= EFI_SIMPLE_NETWORK_COMMAND_INTERRUPT;\r
103     }\r
104 \r
105     if ((InterruptFlags & PXE_STATFLAGS_GET_STATUS_SOFTWARE) == PXE_STATFLAGS_GET_STATUS_SOFTWARE) {\r
106       *InterruptStatusPtr |= EFI_SIMPLE_NETWORK_COMMAND_INTERRUPT;\r
107     }\r
108 \r
109   }\r
110 \r
111   if (TransmitBufferListPtr != NULL) {\r
112     *TransmitBufferListPtr =\r
113       (\r
114         (Snp->Cdb.StatFlags & PXE_STATFLAGS_GET_STATUS_NO_TXBUFS_WRITTEN) ||\r
115         (Snp->Cdb.StatFlags & PXE_STATFLAGS_GET_STATUS_TXBUF_QUEUE_EMPTY)\r
116       ) ? 0 : (VOID *) (UINTN) Db->TxBuffer[0];\r
117 \r
118   }\r
119 \r
120   return EFI_SUCCESS;\r
121 }\r
122 \r
123 /**\r
124   Reads the current interrupt status and recycled transmit buffer status from a\r
125   network interface.\r
126   \r
127   This function gets the current interrupt and recycled transmit buffer status \r
128   from the network interface. The interrupt status is returned as a bit mask in\r
129   InterruptStatus. If InterruptStatus is NULL, the interrupt status will not be\r
130   read. If TxBuf is not NULL, a recycled transmit buffer address will be retrieved.\r
131   If a recycled transmit buffer address is returned in TxBuf, then the buffer has\r
132   been successfully transmitted, and the status for that buffer is cleared. If\r
133   the status of the network interface is successfully collected, EFI_SUCCESS \r
134   will be returned. If the driver has not been initialized, EFI_DEVICE_ERROR will\r
135   be returned.\r
136 \r
137   @param This            A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.\r
138   @param InterruptStatus A pointer to the bit mask of the currently active \r
139                          interrupts (see "Related Definitions"). If this is NULL,\r
140                          the interrupt status will not be read from the device.\r
141                          If this is not NULL, the interrupt status will be read\r
142                          from the device. When the interrupt status is read, it \r
143                          will also be cleared. Clearing the transmit interrupt does \r
144                          not empty the recycled transmit buffer array.\r
145   @param TxBuf           Recycled transmit buffer address. The network interface\r
146                          will not transmit if its internal recycled transmit \r
147                          buffer array is full. Reading the transmit buffer does\r
148                          not clear the transmit interrupt. If this is NULL, then\r
149                          the transmit buffer status will not be read. If there \r
150                          are no transmit buffers to recycle and TxBuf is not NULL, \r
151                          TxBuf will be set to NULL.\r
152 \r
153   @retval EFI_SUCCESS           The status of the network interface was retrieved.\r
154   @retval EFI_NOT_STARTED       The network interface has not been started.\r
155   @retval EFI_INVALID_PARAMETER This parameter was NULL or did not point to a valid \r
156                                 EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
157   @retval EFI_DEVICE_ERROR      The command could not be sent to the network \r
158                                 interface.\r
159 \r
160 **/\r
161 EFI_STATUS\r
162 EFIAPI\r
163 SnpUndi32GetStatus (\r
164   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
165   OUT UINT32                     *InterruptStatus, OPTIONAL\r
166   OUT VOID                       **TxBuf           OPTIONAL\r
167   )\r
168 {\r
169   SNP_DRIVER  *Snp;\r
170   EFI_TPL     OldTpl;\r
171   EFI_STATUS  Status;\r
172 \r
173   if (This == NULL) {\r
174     return EFI_INVALID_PARAMETER;\r
175   }\r
176 \r
177   if (InterruptStatus == NULL && TxBuf == NULL) {\r
178     return EFI_INVALID_PARAMETER;\r
179   }\r
180 \r
181   Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
182 \r
183   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
184 \r
185   if (Snp == NULL) {\r
186     return EFI_DEVICE_ERROR;\r
187   }\r
188 \r
189   switch (Snp->Mode.State) {\r
190   case EfiSimpleNetworkInitialized:\r
191     break;\r
192 \r
193   case EfiSimpleNetworkStopped:\r
194     Status = EFI_NOT_STARTED;\r
195     goto ON_EXIT;\r
196 \r
197   default:\r
198     Status = EFI_DEVICE_ERROR;\r
199     goto ON_EXIT;\r
200   }\r
201 \r
202   Status = PxeGetStatus (Snp, InterruptStatus, TxBuf);\r
203 \r
204 ON_EXIT:\r
205   gBS->RestoreTPL (OldTpl);\r
206 \r
207   return Status;\r
208 }\r