1 | /** @file
|
---|
2 |
|
---|
3 | This file implements the hardware register access functions of the e1000 driver.
|
---|
4 |
|
---|
5 | Copyright (c) 2021-2024, Oracle and/or its affiliates.<BR>
|
---|
6 |
|
---|
7 | SPDX-License-Identifier: BSD-2-Clause-Patent
|
---|
8 |
|
---|
9 | **/
|
---|
10 |
|
---|
11 | #include <IndustryStandard/Pci.h>
|
---|
12 | #include <Library/UefiLib.h>
|
---|
13 | #include <Library/UefiBootServicesTableLib.h>
|
---|
14 |
|
---|
15 | #include "E1kNet.h"
|
---|
16 |
|
---|
17 | EFI_STATUS
|
---|
18 | EFIAPI
|
---|
19 | E1kNetRegWrite32 (
|
---|
20 | IN E1K_NET_DEV *Dev,
|
---|
21 | IN UINT32 Addr,
|
---|
22 | IN UINT32 Data
|
---|
23 | )
|
---|
24 | {
|
---|
25 | EFI_STATUS Status;
|
---|
26 |
|
---|
27 | Status = Dev->PciIo->Io.Write (
|
---|
28 | Dev->PciIo,
|
---|
29 | EfiPciIoWidthUint32,
|
---|
30 | PCI_BAR_IDX2,
|
---|
31 | 0, // IOADDR
|
---|
32 | 1,
|
---|
33 | &Addr
|
---|
34 | );
|
---|
35 | if (!EFI_ERROR (Status))
|
---|
36 | {
|
---|
37 | Status = Dev->PciIo->Io.Write (
|
---|
38 | Dev->PciIo,
|
---|
39 | EfiPciIoWidthUint32,
|
---|
40 | PCI_BAR_IDX2,
|
---|
41 | 4, // IODATA
|
---|
42 | 1,
|
---|
43 | &Data
|
---|
44 | );
|
---|
45 | }
|
---|
46 |
|
---|
47 | return Status;
|
---|
48 | }
|
---|
49 |
|
---|
50 | EFI_STATUS
|
---|
51 | EFIAPI
|
---|
52 | E1kNetRegRead32 (
|
---|
53 | IN E1K_NET_DEV *Dev,
|
---|
54 | IN UINT32 Addr,
|
---|
55 | OUT UINT32 *Data
|
---|
56 | )
|
---|
57 | {
|
---|
58 | EFI_STATUS Status;
|
---|
59 |
|
---|
60 | Status = Dev->PciIo->Io.Write (
|
---|
61 | Dev->PciIo,
|
---|
62 | EfiPciIoWidthUint32,
|
---|
63 | PCI_BAR_IDX2,
|
---|
64 | 0, // IOADDR
|
---|
65 | 1,
|
---|
66 | &Addr
|
---|
67 | );
|
---|
68 | if (!EFI_ERROR (Status))
|
---|
69 | {
|
---|
70 | return Dev->PciIo->Io.Read (
|
---|
71 | Dev->PciIo,
|
---|
72 | EfiPciIoWidthUint32,
|
---|
73 | PCI_BAR_IDX2,
|
---|
74 | 4, // IODATA
|
---|
75 | 1,
|
---|
76 | Data
|
---|
77 | );
|
---|
78 | }
|
---|
79 |
|
---|
80 | return Status;
|
---|
81 | }
|
---|
82 |
|
---|
83 | EFI_STATUS
|
---|
84 | EFIAPI
|
---|
85 | E1kNetRegSet32 (
|
---|
86 | IN E1K_NET_DEV *Dev,
|
---|
87 | IN UINT32 Addr,
|
---|
88 | IN UINT32 Set)
|
---|
89 | {
|
---|
90 | UINT32 Reg;
|
---|
91 | EFI_STATUS Status;
|
---|
92 |
|
---|
93 | Status = E1kNetRegRead32 (Dev, Addr, &Reg);
|
---|
94 | if (EFI_ERROR (Status)) {
|
---|
95 | return Status;
|
---|
96 | }
|
---|
97 |
|
---|
98 | Reg |= Set;
|
---|
99 | Status = E1kNetRegWrite32 (Dev, Addr, Reg);
|
---|
100 | if (EFI_ERROR (Status)) {
|
---|
101 | return Status;
|
---|
102 | }
|
---|
103 |
|
---|
104 | return EFI_SUCCESS;
|
---|
105 | }
|
---|
106 |
|
---|
107 | EFI_STATUS
|
---|
108 | EFIAPI
|
---|
109 | E1kNetRegClear32 (
|
---|
110 | IN E1K_NET_DEV *Dev,
|
---|
111 | IN UINT32 Addr,
|
---|
112 | IN UINT32 Clear)
|
---|
113 | {
|
---|
114 | UINT32 Reg;
|
---|
115 | EFI_STATUS Status;
|
---|
116 |
|
---|
117 | Status = E1kNetRegRead32 (Dev, Addr, &Reg);
|
---|
118 | if (EFI_ERROR (Status)) {
|
---|
119 | return Status;
|
---|
120 | }
|
---|
121 |
|
---|
122 | Reg &= ~Clear;
|
---|
123 | Status = E1kNetRegWrite32 (Dev, Addr, Reg);
|
---|
124 | if (EFI_ERROR (Status)) {
|
---|
125 | return Status;
|
---|
126 | }
|
---|
127 |
|
---|
128 | return EFI_SUCCESS;
|
---|
129 | }
|
---|
130 |
|
---|
131 | EFI_STATUS
|
---|
132 | EFIAPI
|
---|
133 | E1kNetDevReset (
|
---|
134 | IN E1K_NET_DEV *Dev
|
---|
135 | )
|
---|
136 | {
|
---|
137 | EFI_STATUS Status;
|
---|
138 |
|
---|
139 | //
|
---|
140 | // Reset hardware
|
---|
141 | //
|
---|
142 | Status = E1kNetRegSet32 (Dev, E1K_REG_CTRL, E1K_REG_CTRL_RST);
|
---|
143 | if (EFI_ERROR (Status)) {
|
---|
144 | return Status;
|
---|
145 | }
|
---|
146 |
|
---|
147 | //
|
---|
148 | // Wait for the reset to complete
|
---|
149 | //
|
---|
150 | for (;;)
|
---|
151 | {
|
---|
152 | UINT32 Ctrl;
|
---|
153 |
|
---|
154 | Status = E1kNetRegRead32 (Dev, E1K_REG_CTRL, &Ctrl);
|
---|
155 | if (EFI_ERROR (Status)) {
|
---|
156 | return Status;
|
---|
157 | }
|
---|
158 |
|
---|
159 | /// @todo Timeout?
|
---|
160 | if (!(Ctrl & E1K_REG_CTRL_RST))
|
---|
161 | break;
|
---|
162 | }
|
---|
163 |
|
---|
164 | //
|
---|
165 | // Reset the PHY.
|
---|
166 | //
|
---|
167 | Status = E1kNetRegSet32 (Dev, E1K_REG_CTRL, E1K_REG_CTRL_PHY_RST);
|
---|
168 | if (EFI_ERROR (Status)) {
|
---|
169 | return Status;
|
---|
170 | }
|
---|
171 |
|
---|
172 | //
|
---|
173 | // Wait for the specified amount of 3us and de-assert the PHY reset signal.
|
---|
174 | //
|
---|
175 | gBS->Stall(3);
|
---|
176 | Status = E1kNetRegClear32 (Dev, E1K_REG_CTRL, E1K_REG_CTRL_PHY_RST);
|
---|
177 | if (EFI_ERROR (Status)) {
|
---|
178 | return Status;
|
---|
179 | }
|
---|
180 |
|
---|
181 | return EFI_SUCCESS;
|
---|
182 | }
|
---|