ixgbe_mbx.c revision 1.6.8.7 1 1.6.8.7 martin /* $NetBSD: ixgbe_mbx.c,v 1.6.8.7 2022/06/03 12:31:10 martin Exp $ */
2 1.6.8.1 snj
3 1.1 dyoung /******************************************************************************
4 1.6.8.1 snj SPDX-License-Identifier: BSD-3-Clause
5 1.1 dyoung
6 1.6.8.5 martin Copyright (c) 2001-2020, Intel Corporation
7 1.1 dyoung All rights reserved.
8 1.6.8.1 snj
9 1.6.8.1 snj Redistribution and use in source and binary forms, with or without
10 1.1 dyoung modification, are permitted provided that the following conditions are met:
11 1.6.8.1 snj
12 1.6.8.1 snj 1. Redistributions of source code must retain the above copyright notice,
13 1.1 dyoung this list of conditions and the following disclaimer.
14 1.6.8.1 snj
15 1.6.8.1 snj 2. Redistributions in binary form must reproduce the above copyright
16 1.6.8.1 snj notice, this list of conditions and the following disclaimer in the
17 1.1 dyoung documentation and/or other materials provided with the distribution.
18 1.6.8.1 snj
19 1.6.8.1 snj 3. Neither the name of the Intel Corporation nor the names of its
20 1.6.8.1 snj contributors may be used to endorse or promote products derived from
21 1.1 dyoung this software without specific prior written permission.
22 1.6.8.1 snj
23 1.1 dyoung THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 1.6.8.1 snj AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 1.6.8.1 snj IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 1.6.8.1 snj ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27 1.6.8.1 snj LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 1.6.8.1 snj CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 1.6.8.1 snj SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 1.6.8.1 snj INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 1.6.8.1 snj CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 1.1 dyoung ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 1.1 dyoung POSSIBILITY OF SUCH DAMAGE.
34 1.1 dyoung
35 1.1 dyoung ******************************************************************************/
36 1.6.8.2 martin /*$FreeBSD: head/sys/dev/ixgbe/ixgbe_mbx.c 326022 2017-11-20 19:36:21Z pfg $*/
37 1.1 dyoung
38 1.6.8.4 martin #include <sys/cdefs.h>
39 1.6.8.7 martin __KERNEL_RCSID(0, "$NetBSD: ixgbe_mbx.c,v 1.6.8.7 2022/06/03 12:31:10 martin Exp $");
40 1.6.8.4 martin
41 1.1 dyoung #include "ixgbe_type.h"
42 1.6.8.7 martin #include "ixgbe_netbsd.h"
43 1.1 dyoung #include "ixgbe_mbx.h"
44 1.1 dyoung
45 1.6.8.6 martin static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id);
46 1.6.8.6 martin static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id);
47 1.6.8.6 martin
48 1.1 dyoung /**
49 1.6.8.5 martin * ixgbe_read_mbx - Reads a message from the mailbox
50 1.6.8.5 martin * @hw: pointer to the HW structure
51 1.6.8.5 martin * @msg: The message buffer
52 1.6.8.5 martin * @size: Length of buffer
53 1.6.8.5 martin * @mbx_id: id of mailbox to read
54 1.6.8.3 martin *
55 1.6.8.5 martin * returns SUCCESS if it successfully read message from buffer
56 1.6.8.5 martin **/
57 1.6.8.5 martin s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
58 1.6.8.5 martin {
59 1.6.8.5 martin struct ixgbe_mbx_info *mbx = &hw->mbx;
60 1.6.8.5 martin
61 1.6.8.5 martin DEBUGFUNC("ixgbe_read_mbx");
62 1.6.8.5 martin
63 1.6.8.5 martin /* limit read to size of mailbox */
64 1.6.8.6 martin if (size > mbx->size) {
65 1.6.8.6 martin ERROR_REPORT3(IXGBE_ERROR_ARGUMENT,
66 1.6.8.6 martin "Invalid mailbox message size %u, changing to %u",
67 1.6.8.6 martin size, mbx->size);
68 1.6.8.5 martin size = mbx->size;
69 1.6.8.6 martin }
70 1.6.8.6 martin
71 1.6.8.6 martin if (mbx->ops[mbx_id].read)
72 1.6.8.6 martin return mbx->ops[mbx_id].read(hw, msg, size, mbx_id);
73 1.6.8.6 martin
74 1.6.8.6 martin return IXGBE_ERR_CONFIG;
75 1.6.8.6 martin }
76 1.6.8.6 martin
77 1.6.8.6 martin /**
78 1.6.8.6 martin * ixgbe_poll_mbx - Wait for message and read it from the mailbox
79 1.6.8.6 martin * @hw: pointer to the HW structure
80 1.6.8.6 martin * @msg: The message buffer
81 1.6.8.6 martin * @size: Length of buffer
82 1.6.8.6 martin * @mbx_id: id of mailbox to read
83 1.6.8.6 martin *
84 1.6.8.6 martin * returns SUCCESS if it successfully read message from buffer
85 1.6.8.6 martin **/
86 1.6.8.6 martin s32 ixgbe_poll_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
87 1.6.8.6 martin {
88 1.6.8.6 martin struct ixgbe_mbx_info *mbx = &hw->mbx;
89 1.6.8.6 martin s32 ret_val;
90 1.6.8.6 martin
91 1.6.8.6 martin DEBUGFUNC("ixgbe_poll_mbx");
92 1.6.8.5 martin
93 1.6.8.6 martin if (!mbx->ops[mbx_id].read || !mbx->ops[mbx_id].check_for_msg ||
94 1.6.8.6 martin !mbx->timeout)
95 1.6.8.6 martin return IXGBE_ERR_CONFIG;
96 1.6.8.6 martin
97 1.6.8.6 martin /* limit read to size of mailbox */
98 1.6.8.6 martin if (size > mbx->size) {
99 1.6.8.6 martin ERROR_REPORT3(IXGBE_ERROR_ARGUMENT,
100 1.6.8.6 martin "Invalid mailbox message size %u, changing to %u",
101 1.6.8.6 martin size, mbx->size);
102 1.6.8.6 martin size = mbx->size;
103 1.6.8.6 martin }
104 1.6.8.6 martin
105 1.6.8.6 martin ret_val = ixgbe_poll_for_msg(hw, mbx_id);
106 1.6.8.6 martin /* if ack received read message, otherwise we timed out */
107 1.6.8.6 martin if (!ret_val)
108 1.6.8.6 martin return mbx->ops[mbx_id].read(hw, msg, size, mbx_id);
109 1.6.8.5 martin
110 1.6.8.5 martin return ret_val;
111 1.6.8.5 martin }
112 1.6.8.5 martin
113 1.6.8.5 martin /**
114 1.6.8.6 martin * ixgbe_write_mbx - Write a message to the mailbox and wait for ACK
115 1.6.8.5 martin * @hw: pointer to the HW structure
116 1.6.8.5 martin * @msg: The message buffer
117 1.6.8.5 martin * @size: Length of buffer
118 1.6.8.5 martin * @mbx_id: id of mailbox to write
119 1.6.8.5 martin *
120 1.6.8.6 martin * returns SUCCESS if it successfully copied message into the buffer and
121 1.6.8.6 martin * received an ACK to that message within specified period
122 1.6.8.5 martin **/
123 1.6.8.5 martin s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
124 1.6.8.5 martin {
125 1.6.8.5 martin struct ixgbe_mbx_info *mbx = &hw->mbx;
126 1.6.8.6 martin s32 ret_val = IXGBE_ERR_MBX;
127 1.6.8.5 martin
128 1.6.8.5 martin DEBUGFUNC("ixgbe_write_mbx");
129 1.6.8.5 martin
130 1.6.8.6 martin /*
131 1.6.8.6 martin * exit if either we can't write, release
132 1.6.8.6 martin * or there is no timeout defined
133 1.6.8.6 martin */
134 1.6.8.6 martin if (!mbx->ops[mbx_id].write || !mbx->ops[mbx_id].check_for_ack ||
135 1.6.8.6 martin !mbx->ops[mbx_id].release || !mbx->timeout)
136 1.6.8.6 martin return IXGBE_ERR_CONFIG;
137 1.6.8.6 martin
138 1.6.8.5 martin if (size > mbx->size) {
139 1.6.8.6 martin ret_val = IXGBE_ERR_PARAM;
140 1.6.8.5 martin ERROR_REPORT2(IXGBE_ERROR_ARGUMENT,
141 1.6.8.6 martin "Invalid mailbox message size %u", size);
142 1.6.8.6 martin } else {
143 1.6.8.6 martin ret_val = mbx->ops[mbx_id].write(hw, msg, size, mbx_id);
144 1.6.8.6 martin }
145 1.6.8.5 martin
146 1.6.8.5 martin return ret_val;
147 1.6.8.5 martin }
148 1.6.8.5 martin
149 1.6.8.5 martin /**
150 1.6.8.5 martin * ixgbe_check_for_msg - checks to see if someone sent us mail
151 1.6.8.5 martin * @hw: pointer to the HW structure
152 1.6.8.5 martin * @mbx_id: id of mailbox to check
153 1.6.8.5 martin *
154 1.6.8.5 martin * returns SUCCESS if the Status bit was found or else ERR_MBX
155 1.6.8.5 martin **/
156 1.6.8.5 martin s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
157 1.6.8.5 martin {
158 1.6.8.5 martin struct ixgbe_mbx_info *mbx = &hw->mbx;
159 1.6.8.6 martin s32 ret_val = IXGBE_ERR_CONFIG;
160 1.6.8.5 martin
161 1.6.8.5 martin DEBUGFUNC("ixgbe_check_for_msg");
162 1.6.8.5 martin
163 1.6.8.6 martin if (mbx->ops[mbx_id].check_for_msg)
164 1.6.8.6 martin ret_val = mbx->ops[mbx_id].check_for_msg(hw, mbx_id);
165 1.6.8.5 martin
166 1.6.8.5 martin return ret_val;
167 1.6.8.5 martin }
168 1.6.8.5 martin
169 1.6.8.5 martin /**
170 1.6.8.5 martin * ixgbe_check_for_ack - checks to see if someone sent us ACK
171 1.6.8.5 martin * @hw: pointer to the HW structure
172 1.6.8.5 martin * @mbx_id: id of mailbox to check
173 1.6.8.5 martin *
174 1.6.8.5 martin * returns SUCCESS if the Status bit was found or else ERR_MBX
175 1.6.8.5 martin **/
176 1.6.8.5 martin s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
177 1.6.8.5 martin {
178 1.6.8.5 martin struct ixgbe_mbx_info *mbx = &hw->mbx;
179 1.6.8.6 martin s32 ret_val = IXGBE_ERR_CONFIG;
180 1.6.8.5 martin
181 1.6.8.5 martin DEBUGFUNC("ixgbe_check_for_ack");
182 1.6.8.5 martin
183 1.6.8.6 martin if (mbx->ops[mbx_id].check_for_ack)
184 1.6.8.6 martin ret_val = mbx->ops[mbx_id].check_for_ack(hw, mbx_id);
185 1.6.8.5 martin
186 1.6.8.5 martin return ret_val;
187 1.6.8.5 martin }
188 1.6.8.5 martin
189 1.6.8.5 martin /**
190 1.6.8.5 martin * ixgbe_check_for_rst - checks to see if other side has reset
191 1.6.8.5 martin * @hw: pointer to the HW structure
192 1.6.8.5 martin * @mbx_id: id of mailbox to check
193 1.6.8.5 martin *
194 1.6.8.5 martin * returns SUCCESS if the Status bit was found or else ERR_MBX
195 1.6.8.5 martin **/
196 1.6.8.5 martin s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id)
197 1.6.8.5 martin {
198 1.6.8.5 martin struct ixgbe_mbx_info *mbx = &hw->mbx;
199 1.6.8.6 martin s32 ret_val = IXGBE_ERR_CONFIG;
200 1.6.8.5 martin
201 1.6.8.5 martin DEBUGFUNC("ixgbe_check_for_rst");
202 1.6.8.5 martin
203 1.6.8.6 martin if (mbx->ops[mbx_id].check_for_rst)
204 1.6.8.6 martin ret_val = mbx->ops[mbx_id].check_for_rst(hw, mbx_id);
205 1.6.8.5 martin
206 1.6.8.5 martin return ret_val;
207 1.6.8.5 martin }
208 1.6.8.5 martin
209 1.6.8.5 martin /**
210 1.6.8.5 martin * ixgbe_clear_mbx - Clear Mailbox Memory
211 1.6.8.5 martin * @hw: pointer to the HW structure
212 1.6.8.6 martin * @mbx_id: id of mailbox to write
213 1.6.8.5 martin *
214 1.6.8.5 martin * Set VFMBMEM of given VF to 0x0.
215 1.6.8.3 martin **/
216 1.6.8.6 martin s32 ixgbe_clear_mbx(struct ixgbe_hw *hw, u16 mbx_id)
217 1.6.8.3 martin {
218 1.6.8.3 martin struct ixgbe_mbx_info *mbx = &hw->mbx;
219 1.6.8.6 martin s32 ret_val = IXGBE_ERR_CONFIG;
220 1.6.8.3 martin
221 1.6.8.3 martin DEBUGFUNC("ixgbe_clear_mbx");
222 1.6.8.3 martin
223 1.6.8.6 martin if (mbx->ops[mbx_id].clear)
224 1.6.8.6 martin ret_val = mbx->ops[mbx_id].clear(hw, mbx_id);
225 1.6.8.3 martin
226 1.6.8.3 martin return ret_val;
227 1.6.8.3 martin }
228 1.6.8.3 martin
229 1.6.8.3 martin /**
230 1.6.8.5 martin * ixgbe_poll_for_msg - Wait for message notification
231 1.6.8.5 martin * @hw: pointer to the HW structure
232 1.6.8.5 martin * @mbx_id: id of mailbox to write
233 1.1 dyoung *
234 1.6.8.5 martin * returns SUCCESS if it successfully received a message notification
235 1.1 dyoung **/
236 1.1 dyoung static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
237 1.1 dyoung {
238 1.1 dyoung struct ixgbe_mbx_info *mbx = &hw->mbx;
239 1.1 dyoung int countdown = mbx->timeout;
240 1.1 dyoung
241 1.1 dyoung DEBUGFUNC("ixgbe_poll_for_msg");
242 1.1 dyoung
243 1.6.8.6 martin if (!countdown || !mbx->ops[mbx_id].check_for_msg)
244 1.6.8.6 martin return IXGBE_ERR_CONFIG;
245 1.1 dyoung
246 1.6.8.6 martin while (countdown && mbx->ops[mbx_id].check_for_msg(hw, mbx_id)) {
247 1.1 dyoung countdown--;
248 1.1 dyoung if (!countdown)
249 1.1 dyoung break;
250 1.1 dyoung usec_delay(mbx->usec_delay);
251 1.1 dyoung }
252 1.1 dyoung
253 1.6.8.6 martin if (countdown == 0) {
254 1.4 msaitoh ERROR_REPORT2(IXGBE_ERROR_POLLING,
255 1.6.8.6 martin "Polling for VF%u mailbox message timedout", mbx_id);
256 1.6.8.6 martin return IXGBE_ERR_TIMEOUT;
257 1.6.8.6 martin }
258 1.4 msaitoh
259 1.6.8.6 martin return IXGBE_SUCCESS;
260 1.1 dyoung }
261 1.1 dyoung
262 1.1 dyoung /**
263 1.6.8.5 martin * ixgbe_poll_for_ack - Wait for message acknowledgment
264 1.6.8.5 martin * @hw: pointer to the HW structure
265 1.6.8.5 martin * @mbx_id: id of mailbox to write
266 1.1 dyoung *
267 1.6.8.5 martin * returns SUCCESS if it successfully received a message acknowledgment
268 1.1 dyoung **/
269 1.1 dyoung static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
270 1.1 dyoung {
271 1.1 dyoung struct ixgbe_mbx_info *mbx = &hw->mbx;
272 1.1 dyoung int countdown = mbx->timeout;
273 1.1 dyoung
274 1.1 dyoung DEBUGFUNC("ixgbe_poll_for_ack");
275 1.1 dyoung
276 1.6.8.6 martin if (!countdown || !mbx->ops[mbx_id].check_for_ack)
277 1.6.8.6 martin return IXGBE_ERR_CONFIG;
278 1.1 dyoung
279 1.6.8.6 martin while (countdown && mbx->ops[mbx_id].check_for_ack(hw, mbx_id)) {
280 1.1 dyoung countdown--;
281 1.1 dyoung if (!countdown)
282 1.1 dyoung break;
283 1.1 dyoung usec_delay(mbx->usec_delay);
284 1.1 dyoung }
285 1.1 dyoung
286 1.6.8.6 martin if (countdown == 0) {
287 1.4 msaitoh ERROR_REPORT2(IXGBE_ERROR_POLLING,
288 1.6.8.6 martin "Polling for VF%u mailbox ack timedout", mbx_id);
289 1.6.8.6 martin return IXGBE_ERR_TIMEOUT;
290 1.6.8.6 martin }
291 1.4 msaitoh
292 1.6.8.6 martin return IXGBE_SUCCESS;
293 1.1 dyoung }
294 1.1 dyoung
295 1.6.8.6 martin
296 1.1 dyoung /**
297 1.6.8.6 martin * ixgbe_read_mailbox_vf - read VF's mailbox register
298 1.6.8.5 martin * @hw: pointer to the HW structure
299 1.1 dyoung *
300 1.6.8.6 martin * This function is used to read the mailbox register dedicated for VF without
301 1.6.8.6 martin * losing the read to clear status bits.
302 1.1 dyoung **/
303 1.6.8.6 martin static u32 ixgbe_read_mailbox_vf(struct ixgbe_hw *hw)
304 1.1 dyoung {
305 1.6.8.6 martin u32 vf_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);
306 1.1 dyoung
307 1.6.8.6 martin vf_mailbox |= hw->mbx.vf_mailbox;
308 1.6.8.6 martin hw->mbx.vf_mailbox |= vf_mailbox & IXGBE_VFMAILBOX_R2C_BITS;
309 1.1 dyoung
310 1.6.8.6 martin return vf_mailbox;
311 1.1 dyoung }
312 1.1 dyoung
313 1.6.8.6 martin static void ixgbe_clear_msg_vf(struct ixgbe_hw *hw)
314 1.1 dyoung {
315 1.6.8.6 martin u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
316 1.1 dyoung
317 1.6.8.6 martin if (vf_mailbox & IXGBE_VFMAILBOX_PFSTS) {
318 1.6.8.7 martin IXGBE_EVC_ADD(&hw->mbx.stats.reqs, 1);
319 1.6.8.6 martin hw->mbx.vf_mailbox &= ~IXGBE_VFMAILBOX_PFSTS;
320 1.6.8.6 martin }
321 1.1 dyoung }
322 1.1 dyoung
323 1.6.8.6 martin static void ixgbe_clear_ack_vf(struct ixgbe_hw *hw)
324 1.1 dyoung {
325 1.6.8.6 martin u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
326 1.1 dyoung
327 1.6.8.6 martin if (vf_mailbox & IXGBE_VFMAILBOX_PFACK) {
328 1.6.8.7 martin IXGBE_EVC_ADD(&hw->mbx.stats.acks, 1);
329 1.6.8.6 martin hw->mbx.vf_mailbox &= ~IXGBE_VFMAILBOX_PFACK;
330 1.6.8.6 martin }
331 1.1 dyoung }
332 1.1 dyoung
333 1.6.8.6 martin static void ixgbe_clear_rst_vf(struct ixgbe_hw *hw)
334 1.1 dyoung {
335 1.6.8.6 martin u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
336 1.1 dyoung
337 1.6.8.6 martin if (vf_mailbox & (IXGBE_VFMAILBOX_RSTI | IXGBE_VFMAILBOX_RSTD)) {
338 1.6.8.7 martin IXGBE_EVC_ADD(&hw->mbx.stats.rsts, 1);
339 1.6.8.6 martin hw->mbx.vf_mailbox &= ~(IXGBE_VFMAILBOX_RSTI |
340 1.6.8.6 martin IXGBE_VFMAILBOX_RSTD);
341 1.6.8.6 martin }
342 1.1 dyoung }
343 1.1 dyoung
344 1.1 dyoung /**
345 1.6.8.5 martin * ixgbe_check_for_bit_vf - Determine if a status bit was set
346 1.6.8.5 martin * @hw: pointer to the HW structure
347 1.6.8.5 martin * @mask: bitmask for bits to be tested and cleared
348 1.1 dyoung *
349 1.6.8.5 martin * This function is used to check for the read to clear bits within
350 1.6.8.5 martin * the V2P mailbox.
351 1.1 dyoung **/
352 1.1 dyoung static s32 ixgbe_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)
353 1.1 dyoung {
354 1.6.8.6 martin u32 vf_mailbox = ixgbe_read_mailbox_vf(hw);
355 1.1 dyoung
356 1.6.8.6 martin if (vf_mailbox & mask)
357 1.6.8.6 martin return IXGBE_SUCCESS;
358 1.1 dyoung
359 1.6.8.6 martin return IXGBE_ERR_MBX;
360 1.1 dyoung }
361 1.1 dyoung
362 1.1 dyoung /**
363 1.6.8.5 martin * ixgbe_check_for_msg_vf - checks to see if the PF has sent mail
364 1.6.8.5 martin * @hw: pointer to the HW structure
365 1.6.8.5 martin * @mbx_id: id of mailbox to check
366 1.1 dyoung *
367 1.6.8.5 martin * returns SUCCESS if the PF has set the Status bit or else ERR_MBX
368 1.1 dyoung **/
369 1.1 dyoung static s32 ixgbe_check_for_msg_vf(struct ixgbe_hw *hw, u16 mbx_id)
370 1.1 dyoung {
371 1.2 msaitoh UNREFERENCED_1PARAMETER(mbx_id);
372 1.1 dyoung DEBUGFUNC("ixgbe_check_for_msg_vf");
373 1.1 dyoung
374 1.1 dyoung if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) {
375 1.6.8.7 martin IXGBE_EVC_ADD(&hw->mbx.stats.reqs, 1);
376 1.6.8.6 martin return IXGBE_SUCCESS;
377 1.1 dyoung }
378 1.1 dyoung
379 1.6.8.6 martin return IXGBE_ERR_MBX;
380 1.1 dyoung }
381 1.1 dyoung
382 1.1 dyoung /**
383 1.6.8.5 martin * ixgbe_check_for_ack_vf - checks to see if the PF has ACK'd
384 1.6.8.5 martin * @hw: pointer to the HW structure
385 1.6.8.5 martin * @mbx_id: id of mailbox to check
386 1.1 dyoung *
387 1.6.8.5 martin * returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
388 1.1 dyoung **/
389 1.1 dyoung static s32 ixgbe_check_for_ack_vf(struct ixgbe_hw *hw, u16 mbx_id)
390 1.1 dyoung {
391 1.2 msaitoh UNREFERENCED_1PARAMETER(mbx_id);
392 1.1 dyoung DEBUGFUNC("ixgbe_check_for_ack_vf");
393 1.1 dyoung
394 1.1 dyoung if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) {
395 1.6.8.6 martin /* TODO: should this be autocleared? */
396 1.6.8.6 martin ixgbe_clear_ack_vf(hw);
397 1.6.8.7 martin IXGBE_EVC_ADD(&hw->mbx.stats.acks, 1);
398 1.6.8.6 martin return IXGBE_SUCCESS;
399 1.1 dyoung }
400 1.1 dyoung
401 1.6.8.6 martin return IXGBE_ERR_MBX;
402 1.1 dyoung }
403 1.1 dyoung
404 1.1 dyoung /**
405 1.6.8.5 martin * ixgbe_check_for_rst_vf - checks to see if the PF has reset
406 1.6.8.5 martin * @hw: pointer to the HW structure
407 1.6.8.5 martin * @mbx_id: id of mailbox to check
408 1.1 dyoung *
409 1.6.8.5 martin * returns TRUE if the PF has set the reset done bit or else FALSE
410 1.1 dyoung **/
411 1.1 dyoung static s32 ixgbe_check_for_rst_vf(struct ixgbe_hw *hw, u16 mbx_id)
412 1.1 dyoung {
413 1.2 msaitoh UNREFERENCED_1PARAMETER(mbx_id);
414 1.1 dyoung DEBUGFUNC("ixgbe_check_for_rst_vf");
415 1.1 dyoung
416 1.6.8.6 martin if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_RSTI |
417 1.6.8.6 martin IXGBE_VFMAILBOX_RSTD)) {
418 1.6.8.6 martin /* TODO: should this be autocleared? */
419 1.6.8.6 martin ixgbe_clear_rst_vf(hw);
420 1.6.8.7 martin IXGBE_EVC_ADD(&hw->mbx.stats.rsts, 1);
421 1.6.8.6 martin return IXGBE_SUCCESS;
422 1.1 dyoung }
423 1.1 dyoung
424 1.6.8.6 martin return IXGBE_ERR_MBX;
425 1.1 dyoung }
426 1.1 dyoung
427 1.1 dyoung /**
428 1.6.8.5 martin * ixgbe_obtain_mbx_lock_vf - obtain mailbox lock
429 1.6.8.5 martin * @hw: pointer to the HW structure
430 1.1 dyoung *
431 1.6.8.5 martin * return SUCCESS if we obtained the mailbox lock
432 1.1 dyoung **/
433 1.1 dyoung static s32 ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw *hw)
434 1.1 dyoung {
435 1.6.8.6 martin struct ixgbe_mbx_info *mbx = &hw->mbx;
436 1.6.8.6 martin int countdown = mbx->timeout;
437 1.1 dyoung s32 ret_val = IXGBE_ERR_MBX;
438 1.6.8.6 martin u32 vf_mailbox;
439 1.1 dyoung
440 1.1 dyoung DEBUGFUNC("ixgbe_obtain_mbx_lock_vf");
441 1.1 dyoung
442 1.6.8.6 martin if (!mbx->timeout)
443 1.6.8.6 martin return IXGBE_ERR_CONFIG;
444 1.1 dyoung
445 1.6.8.6 martin while (countdown--) {
446 1.6.8.6 martin /* Reserve mailbox for VF use */
447 1.6.8.6 martin vf_mailbox = ixgbe_read_mailbox_vf(hw);
448 1.6.8.6 martin vf_mailbox |= IXGBE_VFMAILBOX_VFU;
449 1.6.8.6 martin IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
450 1.6.8.6 martin
451 1.6.8.6 martin /* Verify that VF is the owner of the lock */
452 1.6.8.6 martin if (ixgbe_read_mailbox_vf(hw) & IXGBE_VFMAILBOX_VFU) {
453 1.6.8.6 martin ret_val = IXGBE_SUCCESS;
454 1.6.8.6 martin break;
455 1.6.8.6 martin }
456 1.6.8.6 martin
457 1.6.8.6 martin /* Wait a bit before trying again */
458 1.6.8.6 martin usec_delay(mbx->usec_delay);
459 1.6.8.6 martin }
460 1.6.8.6 martin
461 1.6.8.6 martin if (ret_val != IXGBE_SUCCESS) {
462 1.6.8.6 martin ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
463 1.6.8.6 martin "Failed to obtain mailbox lock");
464 1.6.8.6 martin ret_val = IXGBE_ERR_TIMEOUT;
465 1.6.8.6 martin }
466 1.1 dyoung
467 1.1 dyoung return ret_val;
468 1.1 dyoung }
469 1.1 dyoung
470 1.1 dyoung /**
471 1.6.8.6 martin * ixgbe_release_mbx_lock_dummy - release mailbox lock
472 1.6.8.6 martin * @hw: pointer to the HW structure
473 1.6.8.6 martin * @mbx_id: id of mailbox to read
474 1.6.8.6 martin **/
475 1.6.8.6 martin static void ixgbe_release_mbx_lock_dummy(struct ixgbe_hw *hw, u16 mbx_id)
476 1.6.8.6 martin {
477 1.6.8.6 martin UNREFERENCED_2PARAMETER(hw, mbx_id);
478 1.6.8.6 martin
479 1.6.8.6 martin DEBUGFUNC("ixgbe_release_mbx_lock_dummy");
480 1.6.8.6 martin }
481 1.6.8.6 martin
482 1.6.8.6 martin /**
483 1.6.8.6 martin * ixgbe_release_mbx_lock_vf - release mailbox lock
484 1.6.8.6 martin * @hw: pointer to the HW structure
485 1.6.8.6 martin * @mbx_id: id of mailbox to read
486 1.6.8.6 martin **/
487 1.6.8.6 martin static void ixgbe_release_mbx_lock_vf(struct ixgbe_hw *hw, u16 mbx_id)
488 1.6.8.6 martin {
489 1.6.8.6 martin u32 vf_mailbox;
490 1.6.8.6 martin
491 1.6.8.6 martin UNREFERENCED_1PARAMETER(mbx_id);
492 1.6.8.6 martin
493 1.6.8.6 martin DEBUGFUNC("ixgbe_release_mbx_lock_vf");
494 1.6.8.6 martin
495 1.6.8.6 martin /* Return ownership of the buffer */
496 1.6.8.6 martin vf_mailbox = ixgbe_read_mailbox_vf(hw);
497 1.6.8.6 martin vf_mailbox &= ~IXGBE_VFMAILBOX_VFU;
498 1.6.8.6 martin IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
499 1.6.8.6 martin }
500 1.6.8.6 martin
501 1.6.8.6 martin /**
502 1.6.8.6 martin * ixgbe_write_mbx_vf_legacy - Write a message to the mailbox
503 1.6.8.6 martin * @hw: pointer to the HW structure
504 1.6.8.6 martin * @msg: The message buffer
505 1.6.8.6 martin * @size: Length of buffer
506 1.6.8.6 martin * @mbx_id: id of mailbox to write
507 1.6.8.6 martin *
508 1.6.8.6 martin * returns SUCCESS if it successfully copied message into the buffer
509 1.6.8.6 martin **/
510 1.6.8.6 martin static s32 ixgbe_write_mbx_vf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
511 1.6.8.6 martin u16 mbx_id)
512 1.6.8.6 martin {
513 1.6.8.6 martin s32 ret_val;
514 1.6.8.6 martin u16 i;
515 1.6.8.6 martin
516 1.6.8.6 martin UNREFERENCED_1PARAMETER(mbx_id);
517 1.6.8.6 martin DEBUGFUNC("ixgbe_write_mbx_vf_legacy");
518 1.6.8.6 martin
519 1.6.8.6 martin /* lock the mailbox to prevent pf/vf race condition */
520 1.6.8.6 martin ret_val = ixgbe_obtain_mbx_lock_vf(hw);
521 1.6.8.6 martin if (ret_val)
522 1.6.8.6 martin return ret_val;
523 1.6.8.6 martin
524 1.6.8.6 martin /* flush msg and acks as we are overwriting the message buffer */
525 1.6.8.6 martin ixgbe_check_for_msg_vf(hw, 0);
526 1.6.8.6 martin ixgbe_clear_msg_vf(hw);
527 1.6.8.6 martin ixgbe_check_for_ack_vf(hw, 0);
528 1.6.8.6 martin ixgbe_clear_ack_vf(hw);
529 1.6.8.6 martin
530 1.6.8.6 martin /* copy the caller specified message to the mailbox memory buffer */
531 1.6.8.6 martin for (i = 0; i < size; i++)
532 1.6.8.6 martin IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
533 1.6.8.6 martin
534 1.6.8.6 martin /* update stats */
535 1.6.8.7 martin IXGBE_EVC_ADD(&hw->mbx.stats.msgs_tx, 1);
536 1.6.8.6 martin
537 1.6.8.6 martin /* interrupt the PF to tell it a message has been sent */
538 1.6.8.6 martin IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
539 1.6.8.6 martin
540 1.6.8.6 martin return IXGBE_SUCCESS;
541 1.6.8.6 martin }
542 1.6.8.6 martin
543 1.6.8.6 martin /**
544 1.6.8.5 martin * ixgbe_write_mbx_vf - Write a message to the mailbox
545 1.6.8.5 martin * @hw: pointer to the HW structure
546 1.6.8.5 martin * @msg: The message buffer
547 1.6.8.5 martin * @size: Length of buffer
548 1.6.8.5 martin * @mbx_id: id of mailbox to write
549 1.1 dyoung *
550 1.6.8.5 martin * returns SUCCESS if it successfully copied message into the buffer
551 1.1 dyoung **/
552 1.1 dyoung static s32 ixgbe_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
553 1.2 msaitoh u16 mbx_id)
554 1.1 dyoung {
555 1.6.8.6 martin u32 vf_mailbox;
556 1.1 dyoung s32 ret_val;
557 1.1 dyoung u16 i;
558 1.1 dyoung
559 1.2 msaitoh UNREFERENCED_1PARAMETER(mbx_id);
560 1.1 dyoung
561 1.1 dyoung DEBUGFUNC("ixgbe_write_mbx_vf");
562 1.1 dyoung
563 1.1 dyoung /* lock the mailbox to prevent pf/vf race condition */
564 1.1 dyoung ret_val = ixgbe_obtain_mbx_lock_vf(hw);
565 1.1 dyoung if (ret_val)
566 1.6.8.6 martin goto out;
567 1.1 dyoung
568 1.1 dyoung /* flush msg and acks as we are overwriting the message buffer */
569 1.6.8.6 martin ixgbe_clear_msg_vf(hw);
570 1.6.8.6 martin ixgbe_clear_ack_vf(hw);
571 1.1 dyoung
572 1.1 dyoung /* copy the caller specified message to the mailbox memory buffer */
573 1.1 dyoung for (i = 0; i < size; i++)
574 1.1 dyoung IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
575 1.1 dyoung
576 1.1 dyoung /* update stats */
577 1.6.8.7 martin IXGBE_EVC_ADD(&hw->mbx.stats.msgs_tx, 1);
578 1.1 dyoung
579 1.6.8.6 martin /* interrupt the PF to tell it a message has been sent */
580 1.6.8.6 martin vf_mailbox = ixgbe_read_mailbox_vf(hw);
581 1.6.8.6 martin vf_mailbox |= IXGBE_VFMAILBOX_REQ;
582 1.6.8.6 martin IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
583 1.6.8.6 martin
584 1.6.8.6 martin /* if msg sent wait until we receive an ack */
585 1.6.8.6 martin ixgbe_poll_for_ack(hw, mbx_id);
586 1.6.8.6 martin
587 1.6.8.6 martin out:
588 1.6.8.6 martin hw->mbx.ops[mbx_id].release(hw, mbx_id);
589 1.1 dyoung
590 1.1 dyoung return ret_val;
591 1.1 dyoung }
592 1.1 dyoung
593 1.1 dyoung /**
594 1.6.8.6 martin * ixgbe_read_mbx_vf_legacy - Reads a message from the inbox intended for vf
595 1.6.8.5 martin * @hw: pointer to the HW structure
596 1.6.8.5 martin * @msg: The message buffer
597 1.6.8.5 martin * @size: Length of buffer
598 1.6.8.5 martin * @mbx_id: id of mailbox to read
599 1.1 dyoung *
600 1.6.8.5 martin * returns SUCCESS if it successfully read message from buffer
601 1.1 dyoung **/
602 1.6.8.6 martin static s32 ixgbe_read_mbx_vf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
603 1.6.8.6 martin u16 mbx_id)
604 1.1 dyoung {
605 1.6.8.6 martin s32 ret_val;
606 1.1 dyoung u16 i;
607 1.1 dyoung
608 1.6.8.6 martin DEBUGFUNC("ixgbe_read_mbx_vf_legacy");
609 1.2 msaitoh UNREFERENCED_1PARAMETER(mbx_id);
610 1.1 dyoung
611 1.1 dyoung /* lock the mailbox to prevent pf/vf race condition */
612 1.1 dyoung ret_val = ixgbe_obtain_mbx_lock_vf(hw);
613 1.1 dyoung if (ret_val)
614 1.6.8.6 martin return ret_val;
615 1.1 dyoung
616 1.1 dyoung /* copy the message from the mailbox memory buffer */
617 1.1 dyoung for (i = 0; i < size; i++)
618 1.1 dyoung msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
619 1.1 dyoung
620 1.1 dyoung /* Acknowledge receipt and release mailbox, then we're done */
621 1.1 dyoung IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);
622 1.1 dyoung
623 1.1 dyoung /* update stats */
624 1.6.8.7 martin IXGBE_EVC_ADD(&hw->mbx.stats.msgs_rx, 1);
625 1.1 dyoung
626 1.6.8.6 martin return IXGBE_SUCCESS;
627 1.6.8.6 martin }
628 1.6.8.6 martin
629 1.6.8.6 martin /**
630 1.6.8.6 martin * ixgbe_read_mbx_vf - Reads a message from the inbox intended for vf
631 1.6.8.6 martin * @hw: pointer to the HW structure
632 1.6.8.6 martin * @msg: The message buffer
633 1.6.8.6 martin * @size: Length of buffer
634 1.6.8.6 martin * @mbx_id: id of mailbox to read
635 1.6.8.6 martin *
636 1.6.8.6 martin * returns SUCCESS if it successfully read message from buffer
637 1.6.8.6 martin **/
638 1.6.8.6 martin static s32 ixgbe_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
639 1.6.8.6 martin u16 mbx_id)
640 1.6.8.6 martin {
641 1.6.8.6 martin u32 vf_mailbox;
642 1.6.8.6 martin s32 ret_val;
643 1.6.8.6 martin u16 i;
644 1.6.8.6 martin
645 1.6.8.6 martin DEBUGFUNC("ixgbe_read_mbx_vf");
646 1.6.8.6 martin UNREFERENCED_1PARAMETER(mbx_id);
647 1.6.8.6 martin
648 1.6.8.6 martin /* check if there is a message from PF */
649 1.6.8.6 martin ret_val = ixgbe_check_for_msg_vf(hw, 0);
650 1.6.8.6 martin if (ret_val != IXGBE_SUCCESS)
651 1.6.8.6 martin return IXGBE_ERR_MBX_NOMSG;
652 1.6.8.6 martin
653 1.6.8.6 martin ixgbe_clear_msg_vf(hw);
654 1.6.8.6 martin
655 1.6.8.6 martin /* copy the message from the mailbox memory buffer */
656 1.6.8.6 martin for (i = 0; i < size; i++)
657 1.6.8.6 martin msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
658 1.6.8.6 martin
659 1.6.8.6 martin /* Acknowledge receipt */
660 1.6.8.6 martin vf_mailbox = ixgbe_read_mailbox_vf(hw);
661 1.6.8.6 martin vf_mailbox |= IXGBE_VFMAILBOX_ACK;
662 1.6.8.6 martin IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, vf_mailbox);
663 1.6.8.6 martin
664 1.6.8.6 martin /* update stats */
665 1.6.8.7 martin IXGBE_EVC_ADD(&hw->mbx.stats.msgs_rx, 1);
666 1.6.8.6 martin
667 1.6.8.6 martin return IXGBE_SUCCESS;
668 1.1 dyoung }
669 1.1 dyoung
670 1.1 dyoung /**
671 1.6.8.5 martin * ixgbe_init_mbx_params_vf - set initial values for vf mailbox
672 1.6.8.5 martin * @hw: pointer to the HW structure
673 1.1 dyoung *
674 1.6.8.6 martin * Initializes single set the hw->mbx struct to correct values for vf mailbox
675 1.6.8.6 martin * Set of legacy functions is being used here
676 1.1 dyoung */
677 1.1 dyoung void ixgbe_init_mbx_params_vf(struct ixgbe_hw *hw)
678 1.1 dyoung {
679 1.1 dyoung struct ixgbe_mbx_info *mbx = &hw->mbx;
680 1.1 dyoung
681 1.6.8.6 martin mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
682 1.1 dyoung mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
683 1.1 dyoung
684 1.1 dyoung mbx->size = IXGBE_VFMAILBOX_SIZE;
685 1.1 dyoung
686 1.6.8.6 martin /* VF has only one mailbox connection, no need for more IDs */
687 1.6.8.6 martin mbx->ops[0].release = ixgbe_release_mbx_lock_dummy;
688 1.6.8.6 martin mbx->ops[0].read = ixgbe_read_mbx_vf_legacy;
689 1.6.8.6 martin mbx->ops[0].write = ixgbe_write_mbx_vf_legacy;
690 1.6.8.6 martin mbx->ops[0].check_for_msg = ixgbe_check_for_msg_vf;
691 1.6.8.6 martin mbx->ops[0].check_for_ack = ixgbe_check_for_ack_vf;
692 1.6.8.6 martin mbx->ops[0].check_for_rst = ixgbe_check_for_rst_vf;
693 1.6.8.6 martin mbx->ops[0].clear = NULL;
694 1.1 dyoung
695 1.6.8.7 martin IXGBE_EVC_STORE(&mbx->stats.msgs_tx, 0);
696 1.6.8.7 martin IXGBE_EVC_STORE(&mbx->stats.msgs_rx, 0);
697 1.6.8.7 martin IXGBE_EVC_STORE(&mbx->stats.reqs, 0);
698 1.6.8.7 martin IXGBE_EVC_STORE(&mbx->stats.acks, 0);
699 1.6.8.7 martin IXGBE_EVC_STORE(&mbx->stats.rsts, 0);
700 1.1 dyoung }
701 1.1 dyoung
702 1.6.8.6 martin /**
703 1.6.8.6 martin * ixgbe_upgrade_mbx_params_vf - set initial values for vf mailbox
704 1.6.8.6 martin * @hw: pointer to the HW structure
705 1.6.8.6 martin *
706 1.6.8.6 martin * Initializes the hw->mbx struct to correct values for vf mailbox
707 1.6.8.6 martin */
708 1.6.8.6 martin void ixgbe_upgrade_mbx_params_vf(struct ixgbe_hw *hw)
709 1.6.8.6 martin {
710 1.6.8.6 martin struct ixgbe_mbx_info *mbx = &hw->mbx;
711 1.6.8.6 martin
712 1.6.8.6 martin mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
713 1.6.8.6 martin mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
714 1.6.8.6 martin
715 1.6.8.6 martin mbx->size = IXGBE_VFMAILBOX_SIZE;
716 1.6.8.6 martin
717 1.6.8.6 martin /* VF has only one mailbox connection, no need for more IDs */
718 1.6.8.6 martin mbx->ops[0].release = ixgbe_release_mbx_lock_vf;
719 1.6.8.6 martin mbx->ops[0].read = ixgbe_read_mbx_vf;
720 1.6.8.6 martin mbx->ops[0].write = ixgbe_write_mbx_vf;
721 1.6.8.6 martin mbx->ops[0].check_for_msg = ixgbe_check_for_msg_vf;
722 1.6.8.6 martin mbx->ops[0].check_for_ack = ixgbe_check_for_ack_vf;
723 1.6.8.6 martin mbx->ops[0].check_for_rst = ixgbe_check_for_rst_vf;
724 1.6.8.6 martin mbx->ops[0].clear = NULL;
725 1.6.8.6 martin }
726 1.6.8.6 martin
727 1.6.8.6 martin static void ixgbe_clear_msg_pf(struct ixgbe_hw *hw, u16 vf_id)
728 1.6.8.6 martin {
729 1.6.8.6 martin u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
730 1.6.8.6 martin s32 index = IXGBE_PFMBICR_INDEX(vf_id);
731 1.6.8.6 martin u32 pfmbicr;
732 1.6.8.6 martin
733 1.6.8.6 martin pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index));
734 1.6.8.6 martin
735 1.6.8.6 martin if (pfmbicr & (IXGBE_PFMBICR_VFREQ_VF1 << vf_shift))
736 1.6.8.7 martin IXGBE_EVC_ADD(&hw->mbx.stats.reqs, 1);
737 1.6.8.6 martin
738 1.6.8.6 martin IXGBE_WRITE_REG(hw, IXGBE_PFMBICR(index),
739 1.6.8.6 martin IXGBE_PFMBICR_VFREQ_VF1 << vf_shift);
740 1.6.8.6 martin }
741 1.6.8.6 martin
742 1.6.8.6 martin static void ixgbe_clear_ack_pf(struct ixgbe_hw *hw, u16 vf_id)
743 1.6.8.6 martin {
744 1.6.8.6 martin u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
745 1.6.8.6 martin s32 index = IXGBE_PFMBICR_INDEX(vf_id);
746 1.6.8.6 martin u32 pfmbicr;
747 1.6.8.6 martin
748 1.6.8.6 martin pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index));
749 1.6.8.6 martin
750 1.6.8.6 martin if (pfmbicr & (IXGBE_PFMBICR_VFACK_VF1 << vf_shift))
751 1.6.8.7 martin IXGBE_EVC_ADD(&hw->mbx.stats.acks, 1);
752 1.6.8.6 martin
753 1.6.8.6 martin IXGBE_WRITE_REG(hw, IXGBE_PFMBICR(index),
754 1.6.8.6 martin IXGBE_PFMBICR_VFACK_VF1 << vf_shift);
755 1.6.8.6 martin }
756 1.6.8.6 martin
757 1.1 dyoung static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
758 1.1 dyoung {
759 1.6.8.6 martin u32 pfmbicr = IXGBE_READ_REG(hw, IXGBE_PFMBICR(index));
760 1.1 dyoung
761 1.6.8.6 martin if (pfmbicr & mask)
762 1.6.8.6 martin return IXGBE_SUCCESS;
763 1.1 dyoung
764 1.6.8.6 martin return IXGBE_ERR_MBX;
765 1.1 dyoung }
766 1.1 dyoung
767 1.1 dyoung /**
768 1.6.8.5 martin * ixgbe_check_for_msg_pf - checks to see if the VF has sent mail
769 1.6.8.5 martin * @hw: pointer to the HW structure
770 1.6.8.6 martin * @vf_id: the VF index
771 1.1 dyoung *
772 1.6.8.5 martin * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
773 1.1 dyoung **/
774 1.6.8.6 martin static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_id)
775 1.1 dyoung {
776 1.6.8.6 martin u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
777 1.6.8.6 martin s32 index = IXGBE_PFMBICR_INDEX(vf_id);
778 1.1 dyoung
779 1.1 dyoung DEBUGFUNC("ixgbe_check_for_msg_pf");
780 1.1 dyoung
781 1.6.8.6 martin if (!ixgbe_check_for_bit_pf(hw, IXGBE_PFMBICR_VFREQ_VF1 << vf_shift,
782 1.6.8.6 martin index))
783 1.6.8.6 martin return IXGBE_SUCCESS;
784 1.1 dyoung
785 1.6.8.6 martin return IXGBE_ERR_MBX;
786 1.1 dyoung }
787 1.1 dyoung
788 1.1 dyoung /**
789 1.6.8.5 martin * ixgbe_check_for_ack_pf - checks to see if the VF has ACKed
790 1.6.8.5 martin * @hw: pointer to the HW structure
791 1.6.8.6 martin * @vf_id: the VF index
792 1.1 dyoung *
793 1.6.8.5 martin * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
794 1.1 dyoung **/
795 1.6.8.6 martin static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_id)
796 1.1 dyoung {
797 1.6.8.6 martin u32 vf_shift = IXGBE_PFMBICR_SHIFT(vf_id);
798 1.6.8.6 martin s32 index = IXGBE_PFMBICR_INDEX(vf_id);
799 1.1 dyoung s32 ret_val = IXGBE_ERR_MBX;
800 1.1 dyoung
801 1.1 dyoung DEBUGFUNC("ixgbe_check_for_ack_pf");
802 1.1 dyoung
803 1.6.8.6 martin if (!ixgbe_check_for_bit_pf(hw, IXGBE_PFMBICR_VFACK_VF1 << vf_shift,
804 1.2 msaitoh index)) {
805 1.1 dyoung ret_val = IXGBE_SUCCESS;
806 1.6.8.6 martin /* TODO: should this be autocleared? */
807 1.6.8.6 martin ixgbe_clear_ack_pf(hw, vf_id);
808 1.1 dyoung }
809 1.1 dyoung
810 1.1 dyoung return ret_val;
811 1.1 dyoung }
812 1.1 dyoung
813 1.1 dyoung /**
814 1.6.8.5 martin * ixgbe_check_for_rst_pf - checks to see if the VF has reset
815 1.6.8.5 martin * @hw: pointer to the HW structure
816 1.6.8.6 martin * @vf_id: the VF index
817 1.1 dyoung *
818 1.6.8.5 martin * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
819 1.1 dyoung **/
820 1.6.8.6 martin static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_id)
821 1.1 dyoung {
822 1.6.8.6 martin u32 vf_shift = IXGBE_PFVFLRE_SHIFT(vf_id);
823 1.6.8.6 martin u32 index = IXGBE_PFVFLRE_INDEX(vf_id);
824 1.1 dyoung s32 ret_val = IXGBE_ERR_MBX;
825 1.6.8.6 martin u32 vflre = 0;
826 1.1 dyoung
827 1.1 dyoung DEBUGFUNC("ixgbe_check_for_rst_pf");
828 1.1 dyoung
829 1.1 dyoung switch (hw->mac.type) {
830 1.1 dyoung case ixgbe_mac_82599EB:
831 1.6.8.6 martin vflre = IXGBE_READ_REG(hw, IXGBE_PFVFLRE(index));
832 1.1 dyoung break;
833 1.4 msaitoh case ixgbe_mac_X550:
834 1.4 msaitoh case ixgbe_mac_X550EM_x:
835 1.6.8.1 snj case ixgbe_mac_X550EM_a:
836 1.2 msaitoh case ixgbe_mac_X540:
837 1.6.8.6 martin vflre = IXGBE_READ_REG(hw, IXGBE_PFVFLREC(index));
838 1.2 msaitoh break;
839 1.1 dyoung default:
840 1.1 dyoung break;
841 1.1 dyoung }
842 1.1 dyoung
843 1.1 dyoung if (vflre & (1 << vf_shift)) {
844 1.1 dyoung ret_val = IXGBE_SUCCESS;
845 1.6.8.6 martin IXGBE_WRITE_REG(hw, IXGBE_PFVFLREC(index), (1 << vf_shift));
846 1.6.8.7 martin IXGBE_EVC_ADD(&hw->mbx.stats.rsts, 1);
847 1.1 dyoung }
848 1.1 dyoung
849 1.1 dyoung return ret_val;
850 1.1 dyoung }
851 1.1 dyoung
852 1.1 dyoung /**
853 1.6.8.5 martin * ixgbe_obtain_mbx_lock_pf - obtain mailbox lock
854 1.6.8.5 martin * @hw: pointer to the HW structure
855 1.6.8.6 martin * @vf_id: the VF index
856 1.1 dyoung *
857 1.6.8.5 martin * return SUCCESS if we obtained the mailbox lock
858 1.1 dyoung **/
859 1.6.8.6 martin static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_id)
860 1.1 dyoung {
861 1.6.8.6 martin struct ixgbe_mbx_info *mbx = &hw->mbx;
862 1.6.8.6 martin int countdown = mbx->timeout;
863 1.1 dyoung s32 ret_val = IXGBE_ERR_MBX;
864 1.6.8.6 martin u32 pf_mailbox;
865 1.1 dyoung
866 1.1 dyoung DEBUGFUNC("ixgbe_obtain_mbx_lock_pf");
867 1.1 dyoung
868 1.6.8.6 martin if (!mbx->timeout)
869 1.6.8.6 martin return IXGBE_ERR_CONFIG;
870 1.1 dyoung
871 1.6.8.6 martin while (countdown--) {
872 1.6.8.6 martin /* Reserve mailbox for PF use */
873 1.6.8.6 martin pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
874 1.6.8.6 martin pf_mailbox |= IXGBE_PFMAILBOX_PFU;
875 1.6.8.6 martin IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
876 1.6.8.6 martin
877 1.6.8.6 martin /* Verify that PF is the owner of the lock */
878 1.6.8.6 martin pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
879 1.6.8.6 martin if (pf_mailbox & IXGBE_PFMAILBOX_PFU) {
880 1.6.8.6 martin ret_val = IXGBE_SUCCESS;
881 1.6.8.6 martin break;
882 1.6.8.6 martin }
883 1.4 msaitoh
884 1.6.8.6 martin /* Wait a bit before trying again */
885 1.6.8.6 martin usec_delay(mbx->usec_delay);
886 1.6.8.6 martin }
887 1.6.8.6 martin
888 1.6.8.6 martin if (ret_val != IXGBE_SUCCESS) {
889 1.6.8.6 martin ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
890 1.6.8.6 martin "Failed to obtain mailbox lock");
891 1.6.8.6 martin ret_val = IXGBE_ERR_TIMEOUT;
892 1.6.8.6 martin }
893 1.1 dyoung
894 1.1 dyoung return ret_val;
895 1.1 dyoung }
896 1.1 dyoung
897 1.1 dyoung /**
898 1.6.8.6 martin * ixgbe_release_mbx_lock_pf - release mailbox lock
899 1.6.8.6 martin * @hw: pointer to the HW structure
900 1.6.8.6 martin * @vf_id: the VF index
901 1.6.8.6 martin **/
902 1.6.8.6 martin static void ixgbe_release_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_id)
903 1.6.8.6 martin {
904 1.6.8.6 martin u32 pf_mailbox;
905 1.6.8.6 martin
906 1.6.8.6 martin DEBUGFUNC("ixgbe_release_mbx_lock_pf");
907 1.6.8.6 martin
908 1.6.8.6 martin /* Return ownership of the buffer */
909 1.6.8.6 martin pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
910 1.6.8.6 martin pf_mailbox &= ~IXGBE_PFMAILBOX_PFU;
911 1.6.8.6 martin IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
912 1.6.8.6 martin }
913 1.6.8.6 martin
914 1.6.8.6 martin /**
915 1.6.8.6 martin * ixgbe_write_mbx_pf_legacy - Places a message in the mailbox
916 1.6.8.6 martin * @hw: pointer to the HW structure
917 1.6.8.6 martin * @msg: The message buffer
918 1.6.8.6 martin * @size: Length of buffer
919 1.6.8.6 martin * @vf_id: the VF index
920 1.6.8.6 martin *
921 1.6.8.6 martin * returns SUCCESS if it successfully copied message into the buffer
922 1.6.8.6 martin **/
923 1.6.8.6 martin static s32 ixgbe_write_mbx_pf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
924 1.6.8.6 martin u16 vf_id)
925 1.6.8.6 martin {
926 1.6.8.6 martin s32 ret_val;
927 1.6.8.6 martin u16 i;
928 1.6.8.6 martin
929 1.6.8.6 martin DEBUGFUNC("ixgbe_write_mbx_pf_legacy");
930 1.6.8.6 martin
931 1.6.8.6 martin /* lock the mailbox to prevent pf/vf race condition */
932 1.6.8.6 martin ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id);
933 1.6.8.6 martin if (ret_val)
934 1.6.8.6 martin return ret_val;
935 1.6.8.6 martin
936 1.6.8.6 martin /* flush msg and acks as we are overwriting the message buffer */
937 1.6.8.6 martin ixgbe_check_for_msg_pf(hw, vf_id);
938 1.6.8.6 martin ixgbe_clear_msg_pf(hw, vf_id);
939 1.6.8.6 martin ixgbe_check_for_ack_pf(hw, vf_id);
940 1.6.8.6 martin ixgbe_clear_ack_pf(hw, vf_id);
941 1.6.8.6 martin
942 1.6.8.6 martin /* copy the caller specified message to the mailbox memory buffer */
943 1.6.8.6 martin for (i = 0; i < size; i++)
944 1.6.8.6 martin IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, msg[i]);
945 1.6.8.6 martin
946 1.6.8.6 martin /* Interrupt VF to tell it a message has been sent and release buffer*/
947 1.6.8.6 martin IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), IXGBE_PFMAILBOX_STS);
948 1.6.8.6 martin
949 1.6.8.6 martin /* update stats */
950 1.6.8.7 martin IXGBE_EVC_ADD(&hw->mbx.stats.msgs_tx, 1);
951 1.6.8.6 martin
952 1.6.8.6 martin return IXGBE_SUCCESS;
953 1.6.8.6 martin }
954 1.6.8.6 martin
955 1.6.8.6 martin /**
956 1.6.8.5 martin * ixgbe_write_mbx_pf - Places a message in the mailbox
957 1.6.8.5 martin * @hw: pointer to the HW structure
958 1.6.8.5 martin * @msg: The message buffer
959 1.6.8.5 martin * @size: Length of buffer
960 1.6.8.6 martin * @vf_id: the VF index
961 1.1 dyoung *
962 1.6.8.5 martin * returns SUCCESS if it successfully copied message into the buffer
963 1.1 dyoung **/
964 1.1 dyoung static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
965 1.6.8.6 martin u16 vf_id)
966 1.1 dyoung {
967 1.6.8.6 martin u32 pf_mailbox;
968 1.1 dyoung s32 ret_val;
969 1.1 dyoung u16 i;
970 1.1 dyoung
971 1.1 dyoung DEBUGFUNC("ixgbe_write_mbx_pf");
972 1.1 dyoung
973 1.1 dyoung /* lock the mailbox to prevent pf/vf race condition */
974 1.6.8.6 martin ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id);
975 1.1 dyoung if (ret_val)
976 1.6.8.6 martin goto out;
977 1.1 dyoung
978 1.1 dyoung /* flush msg and acks as we are overwriting the message buffer */
979 1.6.8.6 martin ixgbe_clear_msg_pf(hw, vf_id);
980 1.6.8.6 martin ixgbe_clear_ack_pf(hw, vf_id);
981 1.1 dyoung
982 1.1 dyoung /* copy the caller specified message to the mailbox memory buffer */
983 1.1 dyoung for (i = 0; i < size; i++)
984 1.6.8.6 martin IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, msg[i]);
985 1.1 dyoung
986 1.6.8.6 martin /* Interrupt VF to tell it a message has been sent */
987 1.6.8.6 martin pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
988 1.6.8.6 martin pf_mailbox |= IXGBE_PFMAILBOX_STS;
989 1.6.8.6 martin IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
990 1.6.8.6 martin
991 1.6.8.6 martin /* if msg sent wait until we receive an ack */
992 1.6.8.6 martin ixgbe_poll_for_ack(hw, vf_id);
993 1.1 dyoung
994 1.1 dyoung /* update stats */
995 1.6.8.7 martin IXGBE_EVC_ADD(&hw->mbx.stats.msgs_tx, 1);
996 1.1 dyoung
997 1.6.8.6 martin out:
998 1.6.8.6 martin hw->mbx.ops[vf_id].release(hw, vf_id);
999 1.6.8.6 martin
1000 1.1 dyoung return ret_val;
1001 1.1 dyoung
1002 1.1 dyoung }
1003 1.1 dyoung
1004 1.1 dyoung /**
1005 1.6.8.6 martin * ixgbe_read_mbx_pf_legacy - Read a message from the mailbox
1006 1.6.8.6 martin * @hw: pointer to the HW structure
1007 1.6.8.6 martin * @msg: The message buffer
1008 1.6.8.6 martin * @size: Length of buffer
1009 1.6.8.6 martin * @vf_id: the VF index
1010 1.6.8.6 martin *
1011 1.6.8.6 martin * This function copies a message from the mailbox buffer to the caller's
1012 1.6.8.6 martin * memory buffer. The presumption is that the caller knows that there was
1013 1.6.8.6 martin * a message due to a VF request so no polling for message is needed.
1014 1.6.8.6 martin **/
1015 1.6.8.6 martin static s32 ixgbe_read_mbx_pf_legacy(struct ixgbe_hw *hw, u32 *msg, u16 size,
1016 1.6.8.6 martin u16 vf_id)
1017 1.6.8.6 martin {
1018 1.6.8.6 martin s32 ret_val;
1019 1.6.8.6 martin u16 i;
1020 1.6.8.6 martin
1021 1.6.8.6 martin DEBUGFUNC("ixgbe_read_mbx_pf_legacy");
1022 1.6.8.6 martin
1023 1.6.8.6 martin /* lock the mailbox to prevent pf/vf race condition */
1024 1.6.8.6 martin ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_id);
1025 1.6.8.6 martin if (ret_val != IXGBE_SUCCESS)
1026 1.6.8.6 martin return ret_val;
1027 1.6.8.6 martin
1028 1.6.8.6 martin /* copy the message to the mailbox memory buffer */
1029 1.6.8.6 martin for (i = 0; i < size; i++)
1030 1.6.8.6 martin msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i);
1031 1.6.8.6 martin
1032 1.6.8.6 martin /* Acknowledge the message and release buffer */
1033 1.6.8.6 martin IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), IXGBE_PFMAILBOX_ACK);
1034 1.6.8.6 martin
1035 1.6.8.6 martin /* update stats */
1036 1.6.8.7 martin IXGBE_EVC_ADD(&hw->mbx.stats.msgs_rx, 1);
1037 1.6.8.6 martin
1038 1.6.8.6 martin return IXGBE_SUCCESS;
1039 1.6.8.6 martin }
1040 1.6.8.6 martin
1041 1.6.8.6 martin /**
1042 1.6.8.5 martin * ixgbe_read_mbx_pf - Read a message from the mailbox
1043 1.6.8.5 martin * @hw: pointer to the HW structure
1044 1.6.8.5 martin * @msg: The message buffer
1045 1.6.8.5 martin * @size: Length of buffer
1046 1.6.8.6 martin * @vf_id: the VF index
1047 1.6.8.5 martin *
1048 1.6.8.5 martin * This function copies a message from the mailbox buffer to the caller's
1049 1.6.8.5 martin * memory buffer. The presumption is that the caller knows that there was
1050 1.6.8.5 martin * a message due to a VF request so no polling for message is needed.
1051 1.1 dyoung **/
1052 1.1 dyoung static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
1053 1.6.8.6 martin u16 vf_id)
1054 1.1 dyoung {
1055 1.6.8.6 martin u32 pf_mailbox;
1056 1.1 dyoung s32 ret_val;
1057 1.1 dyoung u16 i;
1058 1.1 dyoung
1059 1.1 dyoung DEBUGFUNC("ixgbe_read_mbx_pf");
1060 1.1 dyoung
1061 1.6.8.6 martin /* check if there is a message from VF */
1062 1.6.8.6 martin ret_val = ixgbe_check_for_msg_pf(hw, vf_id);
1063 1.6.8.6 martin if (ret_val != IXGBE_SUCCESS)
1064 1.6.8.6 martin return IXGBE_ERR_MBX_NOMSG;
1065 1.6.8.6 martin
1066 1.6.8.6 martin ixgbe_clear_msg_pf(hw, vf_id);
1067 1.1 dyoung
1068 1.1 dyoung /* copy the message to the mailbox memory buffer */
1069 1.1 dyoung for (i = 0; i < size; i++)
1070 1.6.8.6 martin msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i);
1071 1.1 dyoung
1072 1.1 dyoung /* Acknowledge the message and release buffer */
1073 1.6.8.6 martin pf_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_id));
1074 1.6.8.6 martin pf_mailbox |= IXGBE_PFMAILBOX_ACK;
1075 1.6.8.6 martin IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_id), pf_mailbox);
1076 1.1 dyoung
1077 1.1 dyoung /* update stats */
1078 1.6.8.7 martin IXGBE_EVC_ADD(&hw->mbx.stats.msgs_rx, 1);
1079 1.1 dyoung
1080 1.6.8.6 martin return IXGBE_SUCCESS;
1081 1.1 dyoung }
1082 1.1 dyoung
1083 1.1 dyoung /**
1084 1.6.8.5 martin * ixgbe_clear_mbx_pf - Clear Mailbox Memory
1085 1.6.8.5 martin * @hw: pointer to the HW structure
1086 1.6.8.6 martin * @vf_id: the VF index
1087 1.6.8.3 martin *
1088 1.6.8.5 martin * Set VFMBMEM of given VF to 0x0.
1089 1.6.8.3 martin **/
1090 1.6.8.6 martin static s32 ixgbe_clear_mbx_pf(struct ixgbe_hw *hw, u16 vf_id)
1091 1.6.8.3 martin {
1092 1.6.8.3 martin u16 mbx_size = hw->mbx.size;
1093 1.6.8.3 martin u16 i;
1094 1.6.8.3 martin
1095 1.6.8.6 martin if (vf_id > 63)
1096 1.6.8.3 martin return IXGBE_ERR_PARAM;
1097 1.6.8.3 martin
1098 1.6.8.3 martin for (i = 0; i < mbx_size; ++i)
1099 1.6.8.6 martin IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_id), i, 0x0);
1100 1.6.8.3 martin
1101 1.6.8.3 martin return IXGBE_SUCCESS;
1102 1.6.8.3 martin }
1103 1.6.8.3 martin
1104 1.6.8.3 martin /**
1105 1.6.8.6 martin * ixgbe_init_mbx_params_pf_id - set initial values for pf mailbox
1106 1.6.8.6 martin * @hw: pointer to the HW structure
1107 1.6.8.6 martin * @vf_id: the VF index
1108 1.6.8.6 martin *
1109 1.6.8.6 martin * Initializes single set of the hw->mbx struct to correct values for pf mailbox
1110 1.6.8.6 martin * Set of legacy functions is being used here
1111 1.6.8.6 martin */
1112 1.6.8.6 martin void ixgbe_init_mbx_params_pf_id(struct ixgbe_hw *hw, u16 vf_id)
1113 1.6.8.6 martin {
1114 1.6.8.6 martin struct ixgbe_mbx_info *mbx = &hw->mbx;
1115 1.6.8.6 martin
1116 1.6.8.6 martin mbx->ops[vf_id].release = ixgbe_release_mbx_lock_dummy;
1117 1.6.8.6 martin mbx->ops[vf_id].read = ixgbe_read_mbx_pf_legacy;
1118 1.6.8.6 martin mbx->ops[vf_id].write = ixgbe_write_mbx_pf_legacy;
1119 1.6.8.6 martin mbx->ops[vf_id].check_for_msg = ixgbe_check_for_msg_pf;
1120 1.6.8.6 martin mbx->ops[vf_id].check_for_ack = ixgbe_check_for_ack_pf;
1121 1.6.8.6 martin mbx->ops[vf_id].check_for_rst = ixgbe_check_for_rst_pf;
1122 1.6.8.6 martin mbx->ops[vf_id].clear = ixgbe_clear_mbx_pf;
1123 1.6.8.6 martin }
1124 1.6.8.6 martin
1125 1.6.8.6 martin /**
1126 1.6.8.5 martin * ixgbe_init_mbx_params_pf - set initial values for pf mailbox
1127 1.6.8.5 martin * @hw: pointer to the HW structure
1128 1.1 dyoung *
1129 1.6.8.6 martin * Initializes all sets of the hw->mbx struct to correct values for pf
1130 1.6.8.6 martin * mailbox. One set corresponds to single VF. It also initializes counters
1131 1.6.8.6 martin * and general variables. A set of legacy functions is used by default.
1132 1.1 dyoung */
1133 1.1 dyoung void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
1134 1.1 dyoung {
1135 1.6.8.6 martin u16 i;
1136 1.1 dyoung struct ixgbe_mbx_info *mbx = &hw->mbx;
1137 1.1 dyoung
1138 1.6.8.6 martin /* Ensure we are not calling this function from VF */
1139 1.2 msaitoh if (hw->mac.type != ixgbe_mac_82599EB &&
1140 1.4 msaitoh hw->mac.type != ixgbe_mac_X550 &&
1141 1.4 msaitoh hw->mac.type != ixgbe_mac_X550EM_x &&
1142 1.6.8.1 snj hw->mac.type != ixgbe_mac_X550EM_a &&
1143 1.2 msaitoh hw->mac.type != ixgbe_mac_X540)
1144 1.1 dyoung return;
1145 1.1 dyoung
1146 1.6.8.6 martin /* Initialize common mailbox settings */
1147 1.6.8.6 martin mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
1148 1.6.8.6 martin mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
1149 1.1 dyoung mbx->size = IXGBE_VFMAILBOX_SIZE;
1150 1.1 dyoung
1151 1.6.8.6 martin /* Initialize counters with zeroes */
1152 1.6.8.7 martin IXGBE_EVC_STORE(&mbx->stats.msgs_tx, 0);
1153 1.6.8.7 martin IXGBE_EVC_STORE(&mbx->stats.msgs_rx, 0);
1154 1.6.8.7 martin IXGBE_EVC_STORE(&mbx->stats.reqs, 0);
1155 1.6.8.7 martin IXGBE_EVC_STORE(&mbx->stats.acks, 0);
1156 1.6.8.7 martin IXGBE_EVC_STORE(&mbx->stats.rsts, 0);
1157 1.6.8.6 martin
1158 1.6.8.6 martin /* No matter of VF number, we initialize params for all 64 VFs. */
1159 1.6.8.6 martin /* TODO: 1. Add a define for max VF and refactor SHARED to get rid
1160 1.6.8.6 martin * of magic number for that (63 or 64 depending on use case.)
1161 1.6.8.6 martin * 2. rewrite the code to dynamically allocate mbx->ops[vf_id] for
1162 1.6.8.6 martin * certain number of VFs instead of default maximum value of 64 (0..63)
1163 1.6.8.6 martin */
1164 1.6.8.6 martin for (i = 0; i < 64; i++)
1165 1.6.8.6 martin ixgbe_init_mbx_params_pf_id(hw, i);
1166 1.6.8.6 martin }
1167 1.6.8.6 martin
1168 1.6.8.6 martin /**
1169 1.6.8.6 martin * ixgbe_upgrade_mbx_params_pf - Upgrade initial values for pf mailbox
1170 1.6.8.6 martin * @hw: pointer to the HW structure
1171 1.6.8.6 martin * @vf_id: the VF index
1172 1.6.8.6 martin *
1173 1.6.8.6 martin * Initializes the hw->mbx struct to new function set for improved
1174 1.6.8.6 martin * stability and handling of messages.
1175 1.6.8.6 martin */
1176 1.6.8.6 martin void ixgbe_upgrade_mbx_params_pf(struct ixgbe_hw *hw, u16 vf_id)
1177 1.6.8.6 martin {
1178 1.6.8.6 martin struct ixgbe_mbx_info *mbx = &hw->mbx;
1179 1.6.8.6 martin
1180 1.6.8.6 martin /* Ensure we are not calling this function from VF */
1181 1.6.8.6 martin if (hw->mac.type != ixgbe_mac_82599EB &&
1182 1.6.8.6 martin hw->mac.type != ixgbe_mac_X550 &&
1183 1.6.8.6 martin hw->mac.type != ixgbe_mac_X550EM_x &&
1184 1.6.8.6 martin hw->mac.type != ixgbe_mac_X550EM_a &&
1185 1.6.8.6 martin hw->mac.type != ixgbe_mac_X540)
1186 1.6.8.6 martin return;
1187 1.6.8.6 martin
1188 1.6.8.6 martin mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
1189 1.6.8.6 martin mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
1190 1.6.8.6 martin mbx->size = IXGBE_VFMAILBOX_SIZE;
1191 1.6.8.6 martin
1192 1.6.8.6 martin mbx->ops[vf_id].release = ixgbe_release_mbx_lock_pf;
1193 1.6.8.6 martin mbx->ops[vf_id].read = ixgbe_read_mbx_pf;
1194 1.6.8.6 martin mbx->ops[vf_id].write = ixgbe_write_mbx_pf;
1195 1.6.8.6 martin mbx->ops[vf_id].check_for_msg = ixgbe_check_for_msg_pf;
1196 1.6.8.6 martin mbx->ops[vf_id].check_for_ack = ixgbe_check_for_ack_pf;
1197 1.6.8.6 martin mbx->ops[vf_id].check_for_rst = ixgbe_check_for_rst_pf;
1198 1.6.8.6 martin mbx->ops[vf_id].clear = ixgbe_clear_mbx_pf;
1199 1.1 dyoung }
1200