]> git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/dpdk/drivers/net/ixgbe/ixgbe_bypass_api.h
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / seastar / dpdk / drivers / net / ixgbe / ixgbe_bypass_api.h
1 /*-
2 * BSD LICENSE
3 *
4 * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #ifndef _IXGBE_BYPASS_API_H_
35 #define _IXGBE_BYPASS_API_H_
36
37 #ifdef RTE_NIC_BYPASS
38
39 #include "ixgbe_bypass_defines.h"
40 /**
41 * ixgbe_bypass_rw_generic - Bit bang data into by_pass FW
42 *
43 * @hw: pointer to hardware structure
44 * @cmd: Command we send to the FW
45 * @status: The reply from the FW
46 *
47 * Bit-bangs the cmd to the by_pass FW status points to what is returned.
48 **/
49 #define IXGBE_BYPASS_BB_WAIT 1
50 static s32 ixgbe_bypass_rw_generic(struct ixgbe_hw *hw, u32 cmd, u32 *status)
51 {
52 int i;
53 u32 sck, sdi, sdo, dir_sck, dir_sdi, dir_sdo;
54 u32 esdp;
55
56 if (!status)
57 return IXGBE_ERR_PARAM;
58
59 *status = 0;
60
61 /* SDP vary by MAC type */
62 switch (hw->mac.type) {
63 case ixgbe_mac_82599EB:
64 sck = IXGBE_ESDP_SDP7;
65 sdi = IXGBE_ESDP_SDP0;
66 sdo = IXGBE_ESDP_SDP6;
67 dir_sck = IXGBE_ESDP_SDP7_DIR;
68 dir_sdi = IXGBE_ESDP_SDP0_DIR;
69 dir_sdo = IXGBE_ESDP_SDP6_DIR;
70 break;
71 case ixgbe_mac_X540:
72 sck = IXGBE_ESDP_SDP2;
73 sdi = IXGBE_ESDP_SDP0;
74 sdo = IXGBE_ESDP_SDP1;
75 dir_sck = IXGBE_ESDP_SDP2_DIR;
76 dir_sdi = IXGBE_ESDP_SDP0_DIR;
77 dir_sdo = IXGBE_ESDP_SDP1_DIR;
78 break;
79 case ixgbe_mac_X550:
80 case ixgbe_mac_X550EM_x:
81 case ixgbe_mac_X550EM_a:
82 sck = IXGBE_ESDP_SDP2;
83 sdi = IXGBE_ESDP_SDP0;
84 sdo = IXGBE_ESDP_SDP1;
85 dir_sck = IXGBE_ESDP_SDP2_DIR;
86 dir_sdi = IXGBE_ESDP_SDP0_DIR;
87 dir_sdo = IXGBE_ESDP_SDP1_DIR;
88 break;
89 default:
90 return IXGBE_ERR_DEVICE_NOT_SUPPORTED;
91 }
92
93 /* Set SDP pins direction */
94 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
95 esdp |= dir_sck; /* SCK as output */
96 esdp |= dir_sdi; /* SDI as output */
97 esdp &= ~dir_sdo; /* SDO as input */
98 esdp |= sck;
99 esdp |= sdi;
100 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
101 IXGBE_WRITE_FLUSH(hw);
102 // TODO:
103 msleep(IXGBE_BYPASS_BB_WAIT);
104
105 /* Generate start condition */
106 esdp &= ~sdi;
107 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
108 IXGBE_WRITE_FLUSH(hw);
109 msleep(IXGBE_BYPASS_BB_WAIT);
110
111 esdp &= ~sck;
112 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
113 IXGBE_WRITE_FLUSH(hw);
114 msleep(IXGBE_BYPASS_BB_WAIT);
115
116 /* Clock out the new control word and clock in the status */
117 for (i = 0; i < 32; i++) {
118 if ((cmd >> (31 - i)) & 0x01) {
119 esdp |= sdi;
120 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
121 } else {
122 esdp &= ~sdi;
123 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
124 }
125 IXGBE_WRITE_FLUSH(hw);
126 msleep(IXGBE_BYPASS_BB_WAIT);
127
128 esdp |= sck;
129 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
130 IXGBE_WRITE_FLUSH(hw);
131 msleep(IXGBE_BYPASS_BB_WAIT);
132
133 esdp &= ~sck;
134 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
135 IXGBE_WRITE_FLUSH(hw);
136 msleep(IXGBE_BYPASS_BB_WAIT);
137
138 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
139 if (esdp & sdo)
140 *status = (*status << 1) | 0x01;
141 else
142 *status = (*status << 1) | 0x00;
143 msleep(IXGBE_BYPASS_BB_WAIT);
144 }
145
146 /* stop condition */
147 esdp |= sck;
148 esdp &= ~sdi;
149 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
150 IXGBE_WRITE_FLUSH(hw);
151 msleep(IXGBE_BYPASS_BB_WAIT);
152
153 esdp |= sdi;
154 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
155 IXGBE_WRITE_FLUSH(hw);
156
157 /* set the page bits to match the cmd that the status it belongs to */
158 *status = (*status & 0x3fffffff) | (cmd & 0xc0000000);
159
160 return 0;
161 }
162
163 /**
164 * ixgbe_bypass_valid_rd_generic - Verify valid return from bit-bang.
165 *
166 * If we send a write we can't be sure it took until we can read back
167 * that same register. It can be a problem as some of the feilds may
168 * for valid reasons change between the time wrote the register and
169 * we read it again to verify. So this function check everything we
170 * can check and then assumes it worked.
171 *
172 * @u32 in_reg - The register cmd for the bit-bang read.
173 * @u32 out_reg - The register returned from a bit-bang read.
174 **/
175 static bool ixgbe_bypass_valid_rd_generic(u32 in_reg, u32 out_reg)
176 {
177 u32 mask;
178
179 /* Page must match for all control pages */
180 if ((in_reg & BYPASS_PAGE_M) != (out_reg & BYPASS_PAGE_M))
181 return false;
182
183 switch (in_reg & BYPASS_PAGE_M) {
184 case BYPASS_PAGE_CTL0:
185 /* All the following can't change since the last write
186 * - All the event actions
187 * - The timeout value
188 */
189 mask = BYPASS_AUX_ON_M | BYPASS_MAIN_ON_M |
190 BYPASS_MAIN_OFF_M | BYPASS_AUX_OFF_M |
191 BYPASS_WDTIMEOUT_M |
192 BYPASS_WDT_VALUE_M;
193 if ((out_reg & mask) != (in_reg & mask))
194 return false;
195
196 /* 0x0 is never a valid value for bypass status */
197 if (!(out_reg & BYPASS_STATUS_OFF_M))
198 return false;
199 break;
200 case BYPASS_PAGE_CTL1:
201 /* All the following can't change since the last write
202 * - time valid bit
203 * - time we last sent
204 */
205 mask = BYPASS_CTL1_VALID_M | BYPASS_CTL1_TIME_M;
206 if ((out_reg & mask) != (in_reg & mask))
207 return false;
208 break;
209 case BYPASS_PAGE_CTL2:
210 /* All we can check in this page is control number
211 * which is already done above.
212 */
213 break;
214 }
215
216 /* We are as sure as we can be return true */
217 return true;
218 }
219
220 /**
221 * ixgbe_bypass_set_generic - Set a bypass field in the FW CTRL Regiter.
222 *
223 * @hw: pointer to hardware structure
224 * @cmd: The control word we are setting.
225 * @event: The event we are setting in the FW. This also happens to
226 * be the mask for the event we are setting (handy)
227 * @action: The action we set the event to in the FW. This is in a
228 * bit field that happens to be what we want to put in
229 * the event spot (also handy)
230 **/
231 static s32 ixgbe_bypass_set_generic(struct ixgbe_hw *hw, u32 ctrl, u32 event,
232 u32 action)
233 {
234 u32 by_ctl = 0;
235 u32 cmd, verify;
236 u32 count = 0;
237
238 /* Get current values */
239 cmd = ctrl; /* just reading only need control number */
240 if (ixgbe_bypass_rw_generic(hw, cmd, &by_ctl))
241 return IXGBE_ERR_INVALID_ARGUMENT;
242
243 /* Set to new action */
244 cmd = (by_ctl & ~event) | BYPASS_WE | action;
245 if (ixgbe_bypass_rw_generic(hw, cmd, &by_ctl))
246 return IXGBE_ERR_INVALID_ARGUMENT;
247
248 /* Page 0 force a FW eeprom write which is slow so verify */
249 if ((cmd & BYPASS_PAGE_M) == BYPASS_PAGE_CTL0) {
250 verify = BYPASS_PAGE_CTL0;
251 do {
252 if (count++ > 5)
253 return IXGBE_BYPASS_FW_WRITE_FAILURE;
254
255 if (ixgbe_bypass_rw_generic(hw, verify, &by_ctl))
256 return IXGBE_ERR_INVALID_ARGUMENT;
257 } while (!ixgbe_bypass_valid_rd_generic(cmd, by_ctl));
258 } else {
259 /* We have give the FW time for the write to stick */
260 msleep(100);
261 }
262
263 return 0;
264 }
265
266 /**
267 * ixgbe_bypass_rd_eep_generic - Read the bypass FW eeprom address.
268 *
269 * @hw: pointer to hardware structure
270 * @addr: The bypass eeprom address to read.
271 * @value: The 8b of data at the address above.
272 **/
273 static s32 ixgbe_bypass_rd_eep_generic(struct ixgbe_hw *hw, u32 addr, u8 *value)
274 {
275 u32 cmd;
276 u32 status;
277
278
279 /* send the request */
280 cmd = BYPASS_PAGE_CTL2 | BYPASS_WE;
281 cmd |= (addr << BYPASS_CTL2_OFFSET_SHIFT) & BYPASS_CTL2_OFFSET_M;
282 if (ixgbe_bypass_rw_generic(hw, cmd, &status))
283 return IXGBE_ERR_INVALID_ARGUMENT;
284
285 /* We have give the FW time for the write to stick */
286 msleep(100);
287
288 /* now read the results */
289 cmd &= ~BYPASS_WE;
290 if (ixgbe_bypass_rw_generic(hw, cmd, &status))
291 return IXGBE_ERR_INVALID_ARGUMENT;
292
293 *value = status & BYPASS_CTL2_DATA_M;
294
295 return 0;
296 }
297
298 #endif /* RTE_NIC_BYPASS */
299
300 #endif /* _IXGBE_BYPASS_API_H_ */