1
2
3
4
5#ifndef _IXGBE_BYPASS_API_H_
6#define _IXGBE_BYPASS_API_H_
7
8#ifdef RTE_LIBRTE_IXGBE_BYPASS
9
10#include "ixgbe_bypass_defines.h"
11
12
13
14
15
16
17
18
19
20#define IXGBE_BYPASS_BB_WAIT 1
21static s32 ixgbe_bypass_rw_generic(struct ixgbe_hw *hw, u32 cmd, u32 *status)
22{
23 int i;
24 u32 sck, sdi, sdo, dir_sck, dir_sdi, dir_sdo;
25 u32 esdp;
26
27 if (!status)
28 return IXGBE_ERR_PARAM;
29
30 *status = 0;
31
32
33 switch (hw->mac.type) {
34 case ixgbe_mac_82599EB:
35 sck = IXGBE_ESDP_SDP7;
36 sdi = IXGBE_ESDP_SDP0;
37 sdo = IXGBE_ESDP_SDP6;
38 dir_sck = IXGBE_ESDP_SDP7_DIR;
39 dir_sdi = IXGBE_ESDP_SDP0_DIR;
40 dir_sdo = IXGBE_ESDP_SDP6_DIR;
41 break;
42 case ixgbe_mac_X540:
43 sck = IXGBE_ESDP_SDP2;
44 sdi = IXGBE_ESDP_SDP0;
45 sdo = IXGBE_ESDP_SDP1;
46 dir_sck = IXGBE_ESDP_SDP2_DIR;
47 dir_sdi = IXGBE_ESDP_SDP0_DIR;
48 dir_sdo = IXGBE_ESDP_SDP1_DIR;
49 break;
50 case ixgbe_mac_X550:
51 case ixgbe_mac_X550EM_x:
52 case ixgbe_mac_X550EM_a:
53 sck = IXGBE_ESDP_SDP2;
54 sdi = IXGBE_ESDP_SDP0;
55 sdo = IXGBE_ESDP_SDP1;
56 dir_sck = IXGBE_ESDP_SDP2_DIR;
57 dir_sdi = IXGBE_ESDP_SDP0_DIR;
58 dir_sdo = IXGBE_ESDP_SDP1_DIR;
59 break;
60 default:
61 return IXGBE_ERR_DEVICE_NOT_SUPPORTED;
62 }
63
64
65 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
66 esdp |= dir_sck;
67 esdp |= dir_sdi;
68 esdp &= ~dir_sdo;
69 esdp |= sck;
70 esdp |= sdi;
71 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
72 IXGBE_WRITE_FLUSH(hw);
73
74 msleep(IXGBE_BYPASS_BB_WAIT);
75
76
77 esdp &= ~sdi;
78 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
79 IXGBE_WRITE_FLUSH(hw);
80 msleep(IXGBE_BYPASS_BB_WAIT);
81
82 esdp &= ~sck;
83 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
84 IXGBE_WRITE_FLUSH(hw);
85 msleep(IXGBE_BYPASS_BB_WAIT);
86
87
88 for (i = 0; i < 32; i++) {
89 if ((cmd >> (31 - i)) & 0x01) {
90 esdp |= sdi;
91 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
92 } else {
93 esdp &= ~sdi;
94 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
95 }
96 IXGBE_WRITE_FLUSH(hw);
97 msleep(IXGBE_BYPASS_BB_WAIT);
98
99 esdp |= sck;
100 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
101 IXGBE_WRITE_FLUSH(hw);
102 msleep(IXGBE_BYPASS_BB_WAIT);
103
104 esdp &= ~sck;
105 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
106 IXGBE_WRITE_FLUSH(hw);
107 msleep(IXGBE_BYPASS_BB_WAIT);
108
109 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
110 if (esdp & sdo)
111 *status = (*status << 1) | 0x01;
112 else
113 *status = (*status << 1) | 0x00;
114 msleep(IXGBE_BYPASS_BB_WAIT);
115 }
116
117
118 esdp |= sck;
119 esdp &= ~sdi;
120 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
121 IXGBE_WRITE_FLUSH(hw);
122 msleep(IXGBE_BYPASS_BB_WAIT);
123
124 esdp |= sdi;
125 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
126 IXGBE_WRITE_FLUSH(hw);
127
128
129 *status = (*status & 0x3fffffff) | (cmd & 0xc0000000);
130
131 return 0;
132}
133
134
135
136
137
138
139
140
141
142
143
144
145
146static bool ixgbe_bypass_valid_rd_generic(u32 in_reg, u32 out_reg)
147{
148 u32 mask;
149
150
151 if ((in_reg & BYPASS_PAGE_M) != (out_reg & BYPASS_PAGE_M))
152 return false;
153
154 switch (in_reg & BYPASS_PAGE_M) {
155 case BYPASS_PAGE_CTL0:
156
157
158
159
160 mask = BYPASS_AUX_ON_M | BYPASS_MAIN_ON_M |
161 BYPASS_MAIN_OFF_M | BYPASS_AUX_OFF_M |
162 BYPASS_WDTIMEOUT_M |
163 BYPASS_WDT_VALUE_M;
164 if ((out_reg & mask) != (in_reg & mask))
165 return false;
166
167
168 if (!(out_reg & BYPASS_STATUS_OFF_M))
169 return false;
170 break;
171 case BYPASS_PAGE_CTL1:
172
173
174
175
176 mask = BYPASS_CTL1_VALID_M | BYPASS_CTL1_TIME_M;
177 if ((out_reg & mask) != (in_reg & mask))
178 return false;
179 break;
180 case BYPASS_PAGE_CTL2:
181
182
183
184 break;
185 }
186
187
188 return true;
189}
190
191
192
193
194
195
196
197
198
199
200
201
202static s32 ixgbe_bypass_set_generic(struct ixgbe_hw *hw, u32 ctrl, u32 event,
203 u32 action)
204{
205 u32 by_ctl = 0;
206 u32 cmd, verify;
207 u32 count = 0;
208
209
210 cmd = ctrl;
211 if (ixgbe_bypass_rw_generic(hw, cmd, &by_ctl))
212 return IXGBE_ERR_INVALID_ARGUMENT;
213
214
215 cmd = (by_ctl & ~event) | BYPASS_WE | action;
216 if (ixgbe_bypass_rw_generic(hw, cmd, &by_ctl))
217 return IXGBE_ERR_INVALID_ARGUMENT;
218
219
220 if ((cmd & BYPASS_PAGE_M) == BYPASS_PAGE_CTL0) {
221 verify = BYPASS_PAGE_CTL0;
222 do {
223 if (count++ > 5)
224 return IXGBE_BYPASS_FW_WRITE_FAILURE;
225
226 if (ixgbe_bypass_rw_generic(hw, verify, &by_ctl))
227 return IXGBE_ERR_INVALID_ARGUMENT;
228 } while (!ixgbe_bypass_valid_rd_generic(cmd, by_ctl));
229 } else {
230
231 msleep(100);
232 }
233
234 return 0;
235}
236
237
238
239
240
241
242
243
244static s32 ixgbe_bypass_rd_eep_generic(struct ixgbe_hw *hw, u32 addr, u8 *value)
245{
246 u32 cmd;
247 u32 status;
248
249
250
251 cmd = BYPASS_PAGE_CTL2 | BYPASS_WE;
252 cmd |= (addr << BYPASS_CTL2_OFFSET_SHIFT) & BYPASS_CTL2_OFFSET_M;
253 if (ixgbe_bypass_rw_generic(hw, cmd, &status))
254 return IXGBE_ERR_INVALID_ARGUMENT;
255
256
257 msleep(100);
258
259
260 cmd &= ~BYPASS_WE;
261 if (ixgbe_bypass_rw_generic(hw, cmd, &status))
262 return IXGBE_ERR_INVALID_ARGUMENT;
263
264 *value = status & BYPASS_CTL2_DATA_M;
265
266 return 0;
267}
268
269#endif
270
271#endif
272