1 /** @file
2     Implementation of stopping a network interface.
3 
4 Copyright (c) 2004 - 2007, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials are licensed
6 and made available under the terms and conditions of the BSD License which
7 accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9 
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 
13 **/
14 
15 #include "Snp.h"
16 
17 
18 /**
19   Call UNDI to stop the interface and changes the snp state.
20 
21   @param  Snp   Pointer to snp driver structure
22 
23   @retval EFI_SUCCESS            The network interface was stopped.
24   @retval EFI_DEVICE_ERROR       SNP is not initialized.
25 
26 **/
27 EFI_STATUS
PxeStop(SNP_DRIVER * Snp)28 PxeStop (
29   SNP_DRIVER *Snp
30   )
31 {
32   Snp->Cdb.OpCode     = PXE_OPCODE_STOP;
33   Snp->Cdb.OpFlags    = PXE_OPFLAGS_NOT_USED;
34   Snp->Cdb.CPBsize    = PXE_CPBSIZE_NOT_USED;
35   Snp->Cdb.DBsize     = PXE_DBSIZE_NOT_USED;
36   Snp->Cdb.CPBaddr    = PXE_CPBADDR_NOT_USED;
37   Snp->Cdb.DBaddr     = PXE_DBADDR_NOT_USED;
38   Snp->Cdb.StatCode   = PXE_STATCODE_INITIALIZE;
39   Snp->Cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;
40   Snp->Cdb.IFnum      = Snp->IfNum;
41   Snp->Cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;
42 
43   //
44   // Issue UNDI command
45   //
46   DEBUG ((EFI_D_NET, "\nsnp->undi.stop()  "));
47 
48   (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);
49 
50   if (Snp->Cdb.StatCode != PXE_STATCODE_SUCCESS) {
51     DEBUG (
52       (EFI_D_WARN,
53       "\nsnp->undi.stop()  %xh:%xh\n",
54       Snp->Cdb.StatCode,
55       Snp->Cdb.StatFlags)
56       );
57 
58     return EFI_DEVICE_ERROR;
59   }
60   //
61   // Set simple network state to Started and return success.
62   //
63   Snp->Mode.State = EfiSimpleNetworkStopped;
64   return EFI_SUCCESS;
65 }
66 
67 
68 /**
69   Changes the state of a network interface from "started" to "stopped."
70 
71   This function stops a network interface. This call is only valid if the network
72   interface is in the started state. If the network interface was successfully
73   stopped, then EFI_SUCCESS will be returned.
74 
75   @param  This                    A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL
76                                   instance.
77 
78 
79   @retval EFI_SUCCESS             The network interface was stopped.
80   @retval EFI_NOT_STARTED         The network interface has not been started.
81   @retval EFI_INVALID_PARAMETER   This parameter was NULL or did not point to a
82                                   valid EFI_SIMPLE_NETWORK_PROTOCOL structure.
83   @retval EFI_DEVICE_ERROR        The command could not be sent to the network
84                                   interface.
85   @retval EFI_UNSUPPORTED         This function is not supported by the network
86                                   interface.
87 
88 **/
89 EFI_STATUS
90 EFIAPI
SnpUndi32Stop(IN EFI_SIMPLE_NETWORK_PROTOCOL * This)91 SnpUndi32Stop (
92   IN EFI_SIMPLE_NETWORK_PROTOCOL *This
93   )
94 {
95   SNP_DRIVER  *Snp;
96   EFI_TPL     OldTpl;
97   EFI_STATUS  Status;
98 
99   if (This == NULL) {
100     return EFI_INVALID_PARAMETER;
101   }
102 
103   Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
104 
105   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
106 
107   switch (Snp->Mode.State) {
108   case EfiSimpleNetworkStarted:
109     break;
110 
111   case EfiSimpleNetworkStopped:
112     Status = EFI_NOT_STARTED;
113     goto ON_EXIT;
114 
115   default:
116     Status = EFI_DEVICE_ERROR;
117     goto ON_EXIT;
118   }
119 
120   Status = PxeStop (Snp);
121 
122 ON_EXIT:
123   gBS->RestoreTPL (OldTpl);
124 
125   return Status;
126 }
127