4 * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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.
34 #ifndef _IXGBE_BYPASS_API_H_
35 #define _IXGBE_BYPASS_API_H_
39 #include "ixgbe_bypass_defines.h"
41 * ixgbe_bypass_rw_generic - Bit bang data into by_pass FW
43 * @hw: pointer to hardware structure
44 * @cmd: Command we send to the FW
45 * @status: The reply from the FW
47 * Bit-bangs the cmd to the by_pass FW status points to what is returned.
49 #define IXGBE_BYPASS_BB_WAIT 1
50 static s32
ixgbe_bypass_rw_generic(struct ixgbe_hw
*hw
, u32 cmd
, u32
*status
)
53 u32 sck
, sdi
, sdo
, dir_sck
, dir_sdi
, dir_sdo
;
57 return IXGBE_ERR_PARAM
;
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
;
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
;
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
;
90 return IXGBE_ERR_DEVICE_NOT_SUPPORTED
;
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 */
100 IXGBE_WRITE_REG(hw
, IXGBE_ESDP
, esdp
);
101 IXGBE_WRITE_FLUSH(hw
);
103 msleep(IXGBE_BYPASS_BB_WAIT
);
105 /* Generate start condition */
107 IXGBE_WRITE_REG(hw
, IXGBE_ESDP
, esdp
);
108 IXGBE_WRITE_FLUSH(hw
);
109 msleep(IXGBE_BYPASS_BB_WAIT
);
112 IXGBE_WRITE_REG(hw
, IXGBE_ESDP
, esdp
);
113 IXGBE_WRITE_FLUSH(hw
);
114 msleep(IXGBE_BYPASS_BB_WAIT
);
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) {
120 IXGBE_WRITE_REG(hw
, IXGBE_ESDP
, esdp
);
123 IXGBE_WRITE_REG(hw
, IXGBE_ESDP
, esdp
);
125 IXGBE_WRITE_FLUSH(hw
);
126 msleep(IXGBE_BYPASS_BB_WAIT
);
129 IXGBE_WRITE_REG(hw
, IXGBE_ESDP
, esdp
);
130 IXGBE_WRITE_FLUSH(hw
);
131 msleep(IXGBE_BYPASS_BB_WAIT
);
134 IXGBE_WRITE_REG(hw
, IXGBE_ESDP
, esdp
);
135 IXGBE_WRITE_FLUSH(hw
);
136 msleep(IXGBE_BYPASS_BB_WAIT
);
138 esdp
= IXGBE_READ_REG(hw
, IXGBE_ESDP
);
140 *status
= (*status
<< 1) | 0x01;
142 *status
= (*status
<< 1) | 0x00;
143 msleep(IXGBE_BYPASS_BB_WAIT
);
149 IXGBE_WRITE_REG(hw
, IXGBE_ESDP
, esdp
);
150 IXGBE_WRITE_FLUSH(hw
);
151 msleep(IXGBE_BYPASS_BB_WAIT
);
154 IXGBE_WRITE_REG(hw
, IXGBE_ESDP
, esdp
);
155 IXGBE_WRITE_FLUSH(hw
);
157 /* set the page bits to match the cmd that the status it belongs to */
158 *status
= (*status
& 0x3fffffff) | (cmd
& 0xc0000000);
164 * ixgbe_bypass_valid_rd_generic - Verify valid return from bit-bang.
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.
172 * @u32 in_reg - The register cmd for the bit-bang read.
173 * @u32 out_reg - The register returned from a bit-bang read.
175 static bool ixgbe_bypass_valid_rd_generic(u32 in_reg
, u32 out_reg
)
179 /* Page must match for all control pages */
180 if ((in_reg
& BYPASS_PAGE_M
) != (out_reg
& BYPASS_PAGE_M
))
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
189 mask
= BYPASS_AUX_ON_M
| BYPASS_MAIN_ON_M
|
190 BYPASS_MAIN_OFF_M
| BYPASS_AUX_OFF_M
|
193 if ((out_reg
& mask
) != (in_reg
& mask
))
196 /* 0x0 is never a valid value for bypass status */
197 if (!(out_reg
& BYPASS_STATUS_OFF_M
))
200 case BYPASS_PAGE_CTL1
:
201 /* All the following can't change since the last write
203 * - time we last sent
205 mask
= BYPASS_CTL1_VALID_M
| BYPASS_CTL1_TIME_M
;
206 if ((out_reg
& mask
) != (in_reg
& mask
))
209 case BYPASS_PAGE_CTL2
:
210 /* All we can check in this page is control number
211 * which is already done above.
216 /* We are as sure as we can be return true */
221 * ixgbe_bypass_set_generic - Set a bypass field in the FW CTRL Regiter.
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)
231 static s32
ixgbe_bypass_set_generic(struct ixgbe_hw
*hw
, u32 ctrl
, u32 event
,
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
;
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
;
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
;
253 return IXGBE_BYPASS_FW_WRITE_FAILURE
;
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
));
259 /* We have give the FW time for the write to stick */
267 * ixgbe_bypass_rd_eep_generic - Read the bypass FW eeprom address.
269 * @hw: pointer to hardware structure
270 * @addr: The bypass eeprom address to read.
271 * @value: The 8b of data at the address above.
273 static s32
ixgbe_bypass_rd_eep_generic(struct ixgbe_hw
*hw
, u32 addr
, u8
*value
)
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
;
285 /* We have give the FW time for the write to stick */
288 /* now read the results */
290 if (ixgbe_bypass_rw_generic(hw
, cmd
, &status
))
291 return IXGBE_ERR_INVALID_ARGUMENT
;
293 *value
= status
& BYPASS_CTL2_DATA_M
;
298 #endif /* RTE_NIC_BYPASS */
300 #endif /* _IXGBE_BYPASS_API_H_ */