ixgbe_mbx.c revision 1.14 1 1.14 msaitoh /* $NetBSD: ixgbe_mbx.c,v 1.14 2021/12/24 05:02:11 msaitoh Exp $ */
2 1.7 msaitoh
3 1.1 dyoung /******************************************************************************
4 1.9 msaitoh SPDX-License-Identifier: BSD-3-Clause
5 1.1 dyoung
6 1.14 msaitoh Copyright (c) 2001-2020, Intel Corporation
7 1.1 dyoung All rights reserved.
8 1.7 msaitoh
9 1.7 msaitoh 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.7 msaitoh
12 1.7 msaitoh 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.7 msaitoh
15 1.7 msaitoh 2. Redistributions in binary form must reproduce the above copyright
16 1.7 msaitoh 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.7 msaitoh
19 1.7 msaitoh 3. Neither the name of the Intel Corporation nor the names of its
20 1.7 msaitoh contributors may be used to endorse or promote products derived from
21 1.1 dyoung this software without specific prior written permission.
22 1.7 msaitoh
23 1.1 dyoung THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 1.7 msaitoh AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 1.7 msaitoh IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 1.7 msaitoh ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27 1.7 msaitoh LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 1.7 msaitoh CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 1.7 msaitoh SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 1.7 msaitoh INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 1.7 msaitoh 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.10 msaitoh /*$FreeBSD: head/sys/dev/ixgbe/ixgbe_mbx.c 326022 2017-11-20 19:36:21Z pfg $*/
37 1.1 dyoung
38 1.12 msaitoh #include <sys/cdefs.h>
39 1.14 msaitoh __KERNEL_RCSID(0, "$NetBSD: ixgbe_mbx.c,v 1.14 2021/12/24 05:02:11 msaitoh Exp $");
40 1.12 msaitoh
41 1.1 dyoung #include "ixgbe_type.h"
42 1.1 dyoung #include "ixgbe_mbx.h"
43 1.1 dyoung
44 1.1 dyoung /**
45 1.13 msaitoh * ixgbe_clear_mbx - Clear Mailbox Memory
46 1.13 msaitoh * @hw: pointer to the HW structure
47 1.13 msaitoh * @vf_number: id of mailbox to write
48 1.11 msaitoh *
49 1.13 msaitoh * Set VFMBMEM of given VF to 0x0.
50 1.11 msaitoh **/
51 1.11 msaitoh s32 ixgbe_clear_mbx(struct ixgbe_hw *hw, u16 vf_number)
52 1.11 msaitoh {
53 1.11 msaitoh struct ixgbe_mbx_info *mbx = &hw->mbx;
54 1.11 msaitoh s32 ret_val = IXGBE_SUCCESS;
55 1.11 msaitoh
56 1.11 msaitoh DEBUGFUNC("ixgbe_clear_mbx");
57 1.11 msaitoh
58 1.11 msaitoh if (mbx->ops.clear)
59 1.11 msaitoh ret_val = mbx->ops.clear(hw, vf_number);
60 1.11 msaitoh
61 1.11 msaitoh return ret_val;
62 1.11 msaitoh }
63 1.11 msaitoh
64 1.11 msaitoh /**
65 1.13 msaitoh * ixgbe_poll_for_msg - Wait for message notification
66 1.13 msaitoh * @hw: pointer to the HW structure
67 1.13 msaitoh * @mbx_id: id of mailbox to write
68 1.1 dyoung *
69 1.13 msaitoh * returns SUCCESS if it successfully received a message notification
70 1.1 dyoung **/
71 1.1 dyoung static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
72 1.1 dyoung {
73 1.1 dyoung struct ixgbe_mbx_info *mbx = &hw->mbx;
74 1.1 dyoung int countdown = mbx->timeout;
75 1.1 dyoung
76 1.1 dyoung DEBUGFUNC("ixgbe_poll_for_msg");
77 1.1 dyoung
78 1.1 dyoung if (!countdown || !mbx->ops.check_for_msg)
79 1.1 dyoung goto out;
80 1.1 dyoung
81 1.1 dyoung while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) {
82 1.1 dyoung countdown--;
83 1.1 dyoung if (!countdown)
84 1.1 dyoung break;
85 1.1 dyoung usec_delay(mbx->usec_delay);
86 1.1 dyoung }
87 1.1 dyoung
88 1.4 msaitoh if (countdown == 0)
89 1.4 msaitoh ERROR_REPORT2(IXGBE_ERROR_POLLING,
90 1.4 msaitoh "Polling for VF%d mailbox message timedout", mbx_id);
91 1.4 msaitoh
92 1.1 dyoung out:
93 1.1 dyoung return countdown ? IXGBE_SUCCESS : IXGBE_ERR_MBX;
94 1.1 dyoung }
95 1.1 dyoung
96 1.1 dyoung /**
97 1.13 msaitoh * ixgbe_poll_for_ack - Wait for message acknowledgment
98 1.13 msaitoh * @hw: pointer to the HW structure
99 1.13 msaitoh * @mbx_id: id of mailbox to write
100 1.1 dyoung *
101 1.13 msaitoh * returns SUCCESS if it successfully received a message acknowledgment
102 1.1 dyoung **/
103 1.1 dyoung static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
104 1.1 dyoung {
105 1.1 dyoung struct ixgbe_mbx_info *mbx = &hw->mbx;
106 1.1 dyoung int countdown = mbx->timeout;
107 1.1 dyoung
108 1.1 dyoung DEBUGFUNC("ixgbe_poll_for_ack");
109 1.1 dyoung
110 1.1 dyoung if (!countdown || !mbx->ops.check_for_ack)
111 1.1 dyoung goto out;
112 1.1 dyoung
113 1.1 dyoung while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) {
114 1.1 dyoung countdown--;
115 1.1 dyoung if (!countdown)
116 1.1 dyoung break;
117 1.1 dyoung usec_delay(mbx->usec_delay);
118 1.1 dyoung }
119 1.1 dyoung
120 1.4 msaitoh if (countdown == 0)
121 1.4 msaitoh ERROR_REPORT2(IXGBE_ERROR_POLLING,
122 1.4 msaitoh "Polling for VF%d mailbox ack timedout", mbx_id);
123 1.4 msaitoh
124 1.1 dyoung out:
125 1.1 dyoung return countdown ? IXGBE_SUCCESS : IXGBE_ERR_MBX;
126 1.1 dyoung }
127 1.1 dyoung
128 1.1 dyoung /**
129 1.13 msaitoh * ixgbe_read_posted_mbx - Wait for message notification and receive message
130 1.13 msaitoh * @hw: pointer to the HW structure
131 1.13 msaitoh * @msg: The message buffer
132 1.13 msaitoh * @size: Length of buffer
133 1.13 msaitoh * @mbx_id: id of mailbox to write
134 1.1 dyoung *
135 1.13 msaitoh * returns SUCCESS if it successfully received a message notification and
136 1.13 msaitoh * copied it into the receive buffer.
137 1.1 dyoung **/
138 1.7 msaitoh static s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
139 1.7 msaitoh u16 mbx_id)
140 1.1 dyoung {
141 1.1 dyoung struct ixgbe_mbx_info *mbx = &hw->mbx;
142 1.1 dyoung s32 ret_val = IXGBE_ERR_MBX;
143 1.1 dyoung
144 1.1 dyoung DEBUGFUNC("ixgbe_read_posted_mbx");
145 1.1 dyoung
146 1.1 dyoung if (!mbx->ops.read)
147 1.1 dyoung goto out;
148 1.1 dyoung
149 1.1 dyoung ret_val = ixgbe_poll_for_msg(hw, mbx_id);
150 1.1 dyoung
151 1.1 dyoung /* if ack received read message, otherwise we timed out */
152 1.1 dyoung if (!ret_val)
153 1.1 dyoung ret_val = mbx->ops.read(hw, msg, size, mbx_id);
154 1.1 dyoung out:
155 1.1 dyoung return ret_val;
156 1.1 dyoung }
157 1.1 dyoung
158 1.1 dyoung /**
159 1.13 msaitoh * ixgbe_write_posted_mbx - Write a message to the mailbox, wait for ack
160 1.13 msaitoh * @hw: pointer to the HW structure
161 1.13 msaitoh * @msg: The message buffer
162 1.13 msaitoh * @size: Length of buffer
163 1.13 msaitoh * @mbx_id: id of mailbox to write
164 1.1 dyoung *
165 1.13 msaitoh * returns SUCCESS if it successfully copied message into the buffer and
166 1.13 msaitoh * received an ack to that message within delay * timeout period
167 1.1 dyoung **/
168 1.7 msaitoh static s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
169 1.7 msaitoh u16 mbx_id)
170 1.1 dyoung {
171 1.1 dyoung struct ixgbe_mbx_info *mbx = &hw->mbx;
172 1.1 dyoung s32 ret_val = IXGBE_ERR_MBX;
173 1.1 dyoung
174 1.1 dyoung DEBUGFUNC("ixgbe_write_posted_mbx");
175 1.1 dyoung
176 1.1 dyoung /* exit if either we can't write or there isn't a defined timeout */
177 1.1 dyoung if (!mbx->ops.write || !mbx->timeout)
178 1.1 dyoung goto out;
179 1.1 dyoung
180 1.1 dyoung /* send msg */
181 1.1 dyoung ret_val = mbx->ops.write(hw, msg, size, mbx_id);
182 1.1 dyoung
183 1.1 dyoung /* if msg sent wait until we receive an ack */
184 1.1 dyoung if (!ret_val)
185 1.1 dyoung ret_val = ixgbe_poll_for_ack(hw, mbx_id);
186 1.1 dyoung out:
187 1.1 dyoung return ret_val;
188 1.1 dyoung }
189 1.1 dyoung
190 1.1 dyoung /**
191 1.13 msaitoh * ixgbe_init_mbx_ops_generic - Initialize MB function pointers
192 1.13 msaitoh * @hw: pointer to the HW structure
193 1.1 dyoung *
194 1.13 msaitoh * Setups up the mailbox read and write message function pointers
195 1.1 dyoung **/
196 1.1 dyoung void ixgbe_init_mbx_ops_generic(struct ixgbe_hw *hw)
197 1.1 dyoung {
198 1.1 dyoung struct ixgbe_mbx_info *mbx = &hw->mbx;
199 1.1 dyoung
200 1.1 dyoung mbx->ops.read_posted = ixgbe_read_posted_mbx;
201 1.1 dyoung mbx->ops.write_posted = ixgbe_write_posted_mbx;
202 1.1 dyoung }
203 1.1 dyoung
204 1.1 dyoung /**
205 1.13 msaitoh * ixgbe_read_v2p_mailbox - read v2p mailbox
206 1.13 msaitoh * @hw: pointer to the HW structure
207 1.1 dyoung *
208 1.13 msaitoh * This function is used to read the v2p mailbox without losing the read to
209 1.13 msaitoh * clear status bits.
210 1.1 dyoung **/
211 1.1 dyoung static u32 ixgbe_read_v2p_mailbox(struct ixgbe_hw *hw)
212 1.1 dyoung {
213 1.1 dyoung u32 v2p_mailbox = IXGBE_READ_REG(hw, IXGBE_VFMAILBOX);
214 1.1 dyoung
215 1.1 dyoung v2p_mailbox |= hw->mbx.v2p_mailbox;
216 1.1 dyoung hw->mbx.v2p_mailbox |= v2p_mailbox & IXGBE_VFMAILBOX_R2C_BITS;
217 1.1 dyoung
218 1.1 dyoung return v2p_mailbox;
219 1.1 dyoung }
220 1.1 dyoung
221 1.1 dyoung /**
222 1.13 msaitoh * ixgbe_check_for_bit_vf - Determine if a status bit was set
223 1.13 msaitoh * @hw: pointer to the HW structure
224 1.13 msaitoh * @mask: bitmask for bits to be tested and cleared
225 1.1 dyoung *
226 1.13 msaitoh * This function is used to check for the read to clear bits within
227 1.13 msaitoh * the V2P mailbox.
228 1.1 dyoung **/
229 1.1 dyoung static s32 ixgbe_check_for_bit_vf(struct ixgbe_hw *hw, u32 mask)
230 1.1 dyoung {
231 1.1 dyoung u32 v2p_mailbox = ixgbe_read_v2p_mailbox(hw);
232 1.1 dyoung s32 ret_val = IXGBE_ERR_MBX;
233 1.1 dyoung
234 1.1 dyoung if (v2p_mailbox & mask)
235 1.1 dyoung ret_val = IXGBE_SUCCESS;
236 1.1 dyoung
237 1.1 dyoung hw->mbx.v2p_mailbox &= ~mask;
238 1.1 dyoung
239 1.1 dyoung return ret_val;
240 1.1 dyoung }
241 1.1 dyoung
242 1.1 dyoung /**
243 1.13 msaitoh * ixgbe_check_for_msg_vf - checks to see if the PF has sent mail
244 1.13 msaitoh * @hw: pointer to the HW structure
245 1.13 msaitoh * @mbx_id: id of mailbox to check
246 1.1 dyoung *
247 1.13 msaitoh * returns SUCCESS if the PF has set the Status bit or else ERR_MBX
248 1.1 dyoung **/
249 1.1 dyoung static s32 ixgbe_check_for_msg_vf(struct ixgbe_hw *hw, u16 mbx_id)
250 1.1 dyoung {
251 1.1 dyoung s32 ret_val = IXGBE_ERR_MBX;
252 1.1 dyoung
253 1.2 msaitoh UNREFERENCED_1PARAMETER(mbx_id);
254 1.1 dyoung DEBUGFUNC("ixgbe_check_for_msg_vf");
255 1.1 dyoung
256 1.1 dyoung if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFSTS)) {
257 1.1 dyoung ret_val = IXGBE_SUCCESS;
258 1.8 msaitoh hw->mbx.stats.reqs.ev_count++;
259 1.1 dyoung }
260 1.1 dyoung
261 1.1 dyoung return ret_val;
262 1.1 dyoung }
263 1.1 dyoung
264 1.1 dyoung /**
265 1.13 msaitoh * ixgbe_check_for_ack_vf - checks to see if the PF has ACK'd
266 1.13 msaitoh * @hw: pointer to the HW structure
267 1.13 msaitoh * @mbx_id: id of mailbox to check
268 1.1 dyoung *
269 1.13 msaitoh * returns SUCCESS if the PF has set the ACK bit or else ERR_MBX
270 1.1 dyoung **/
271 1.1 dyoung static s32 ixgbe_check_for_ack_vf(struct ixgbe_hw *hw, u16 mbx_id)
272 1.1 dyoung {
273 1.1 dyoung s32 ret_val = IXGBE_ERR_MBX;
274 1.1 dyoung
275 1.2 msaitoh UNREFERENCED_1PARAMETER(mbx_id);
276 1.1 dyoung DEBUGFUNC("ixgbe_check_for_ack_vf");
277 1.1 dyoung
278 1.1 dyoung if (!ixgbe_check_for_bit_vf(hw, IXGBE_VFMAILBOX_PFACK)) {
279 1.1 dyoung ret_val = IXGBE_SUCCESS;
280 1.8 msaitoh hw->mbx.stats.acks.ev_count++;
281 1.1 dyoung }
282 1.1 dyoung
283 1.1 dyoung return ret_val;
284 1.1 dyoung }
285 1.1 dyoung
286 1.1 dyoung /**
287 1.13 msaitoh * ixgbe_check_for_rst_vf - checks to see if the PF has reset
288 1.13 msaitoh * @hw: pointer to the HW structure
289 1.13 msaitoh * @mbx_id: id of mailbox to check
290 1.1 dyoung *
291 1.13 msaitoh * returns TRUE if the PF has set the reset done bit or else FALSE
292 1.1 dyoung **/
293 1.1 dyoung static s32 ixgbe_check_for_rst_vf(struct ixgbe_hw *hw, u16 mbx_id)
294 1.1 dyoung {
295 1.1 dyoung s32 ret_val = IXGBE_ERR_MBX;
296 1.1 dyoung
297 1.2 msaitoh UNREFERENCED_1PARAMETER(mbx_id);
298 1.1 dyoung DEBUGFUNC("ixgbe_check_for_rst_vf");
299 1.1 dyoung
300 1.1 dyoung if (!ixgbe_check_for_bit_vf(hw, (IXGBE_VFMAILBOX_RSTD |
301 1.2 msaitoh IXGBE_VFMAILBOX_RSTI))) {
302 1.1 dyoung ret_val = IXGBE_SUCCESS;
303 1.8 msaitoh hw->mbx.stats.rsts.ev_count++;
304 1.1 dyoung }
305 1.1 dyoung
306 1.1 dyoung return ret_val;
307 1.1 dyoung }
308 1.1 dyoung
309 1.1 dyoung /**
310 1.13 msaitoh * ixgbe_obtain_mbx_lock_vf - obtain mailbox lock
311 1.13 msaitoh * @hw: pointer to the HW structure
312 1.1 dyoung *
313 1.13 msaitoh * return SUCCESS if we obtained the mailbox lock
314 1.1 dyoung **/
315 1.1 dyoung static s32 ixgbe_obtain_mbx_lock_vf(struct ixgbe_hw *hw)
316 1.1 dyoung {
317 1.1 dyoung s32 ret_val = IXGBE_ERR_MBX;
318 1.1 dyoung
319 1.1 dyoung DEBUGFUNC("ixgbe_obtain_mbx_lock_vf");
320 1.1 dyoung
321 1.1 dyoung /* Take ownership of the buffer */
322 1.1 dyoung IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_VFU);
323 1.1 dyoung
324 1.1 dyoung /* reserve mailbox for vf use */
325 1.1 dyoung if (ixgbe_read_v2p_mailbox(hw) & IXGBE_VFMAILBOX_VFU)
326 1.1 dyoung ret_val = IXGBE_SUCCESS;
327 1.1 dyoung
328 1.1 dyoung return ret_val;
329 1.1 dyoung }
330 1.1 dyoung
331 1.1 dyoung /**
332 1.13 msaitoh * ixgbe_write_mbx_vf - Write a message to the mailbox
333 1.13 msaitoh * @hw: pointer to the HW structure
334 1.13 msaitoh * @msg: The message buffer
335 1.13 msaitoh * @size: Length of buffer
336 1.13 msaitoh * @mbx_id: id of mailbox to write
337 1.1 dyoung *
338 1.13 msaitoh * returns SUCCESS if it successfully copied message into the buffer
339 1.1 dyoung **/
340 1.1 dyoung static s32 ixgbe_write_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
341 1.2 msaitoh u16 mbx_id)
342 1.1 dyoung {
343 1.1 dyoung s32 ret_val;
344 1.1 dyoung u16 i;
345 1.1 dyoung
346 1.2 msaitoh UNREFERENCED_1PARAMETER(mbx_id);
347 1.1 dyoung
348 1.1 dyoung DEBUGFUNC("ixgbe_write_mbx_vf");
349 1.1 dyoung
350 1.1 dyoung /* lock the mailbox to prevent pf/vf race condition */
351 1.1 dyoung ret_val = ixgbe_obtain_mbx_lock_vf(hw);
352 1.1 dyoung if (ret_val)
353 1.1 dyoung goto out_no_write;
354 1.1 dyoung
355 1.1 dyoung /* flush msg and acks as we are overwriting the message buffer */
356 1.1 dyoung ixgbe_check_for_msg_vf(hw, 0);
357 1.1 dyoung ixgbe_check_for_ack_vf(hw, 0);
358 1.1 dyoung
359 1.1 dyoung /* copy the caller specified message to the mailbox memory buffer */
360 1.1 dyoung for (i = 0; i < size; i++)
361 1.1 dyoung IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFMBMEM, i, msg[i]);
362 1.1 dyoung
363 1.1 dyoung /* update stats */
364 1.8 msaitoh hw->mbx.stats.msgs_tx.ev_count++;
365 1.1 dyoung
366 1.1 dyoung /* Drop VFU and interrupt the PF to tell it a message has been sent */
367 1.1 dyoung IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_REQ);
368 1.1 dyoung
369 1.1 dyoung out_no_write:
370 1.1 dyoung return ret_val;
371 1.1 dyoung }
372 1.1 dyoung
373 1.1 dyoung /**
374 1.13 msaitoh * ixgbe_read_mbx_vf - Reads a message from the inbox intended for vf
375 1.13 msaitoh * @hw: pointer to the HW structure
376 1.13 msaitoh * @msg: The message buffer
377 1.13 msaitoh * @size: Length of buffer
378 1.13 msaitoh * @mbx_id: id of mailbox to read
379 1.1 dyoung *
380 1.13 msaitoh * returns SUCCESS if it successfully read message from buffer
381 1.1 dyoung **/
382 1.1 dyoung static s32 ixgbe_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size,
383 1.2 msaitoh u16 mbx_id)
384 1.1 dyoung {
385 1.1 dyoung s32 ret_val = IXGBE_SUCCESS;
386 1.1 dyoung u16 i;
387 1.1 dyoung
388 1.1 dyoung DEBUGFUNC("ixgbe_read_mbx_vf");
389 1.2 msaitoh UNREFERENCED_1PARAMETER(mbx_id);
390 1.1 dyoung
391 1.1 dyoung /* lock the mailbox to prevent pf/vf race condition */
392 1.1 dyoung ret_val = ixgbe_obtain_mbx_lock_vf(hw);
393 1.1 dyoung if (ret_val)
394 1.1 dyoung goto out_no_read;
395 1.1 dyoung
396 1.1 dyoung /* copy the message from the mailbox memory buffer */
397 1.1 dyoung for (i = 0; i < size; i++)
398 1.1 dyoung msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_VFMBMEM, i);
399 1.1 dyoung
400 1.1 dyoung /* Acknowledge receipt and release mailbox, then we're done */
401 1.1 dyoung IXGBE_WRITE_REG(hw, IXGBE_VFMAILBOX, IXGBE_VFMAILBOX_ACK);
402 1.1 dyoung
403 1.1 dyoung /* update stats */
404 1.8 msaitoh hw->mbx.stats.msgs_rx.ev_count++;
405 1.1 dyoung
406 1.1 dyoung out_no_read:
407 1.1 dyoung return ret_val;
408 1.1 dyoung }
409 1.1 dyoung
410 1.1 dyoung /**
411 1.13 msaitoh * ixgbe_init_mbx_params_vf - set initial values for vf mailbox
412 1.13 msaitoh * @hw: pointer to the HW structure
413 1.1 dyoung *
414 1.13 msaitoh * Initializes the hw->mbx struct to correct values for vf mailbox
415 1.1 dyoung */
416 1.1 dyoung void ixgbe_init_mbx_params_vf(struct ixgbe_hw *hw)
417 1.1 dyoung {
418 1.1 dyoung struct ixgbe_mbx_info *mbx = &hw->mbx;
419 1.1 dyoung
420 1.1 dyoung /* start mailbox as timed out and let the reset_hw call set the timeout
421 1.1 dyoung * value to begin communications */
422 1.1 dyoung mbx->timeout = 0;
423 1.1 dyoung mbx->usec_delay = IXGBE_VF_MBX_INIT_DELAY;
424 1.1 dyoung
425 1.1 dyoung mbx->size = IXGBE_VFMAILBOX_SIZE;
426 1.1 dyoung
427 1.1 dyoung mbx->ops.read = ixgbe_read_mbx_vf;
428 1.1 dyoung mbx->ops.write = ixgbe_write_mbx_vf;
429 1.1 dyoung mbx->ops.read_posted = ixgbe_read_posted_mbx;
430 1.1 dyoung mbx->ops.write_posted = ixgbe_write_posted_mbx;
431 1.1 dyoung mbx->ops.check_for_msg = ixgbe_check_for_msg_vf;
432 1.1 dyoung mbx->ops.check_for_ack = ixgbe_check_for_ack_vf;
433 1.1 dyoung mbx->ops.check_for_rst = ixgbe_check_for_rst_vf;
434 1.11 msaitoh mbx->ops.clear = NULL;
435 1.1 dyoung
436 1.8 msaitoh mbx->stats.msgs_tx.ev_count = 0;
437 1.8 msaitoh mbx->stats.msgs_rx.ev_count = 0;
438 1.8 msaitoh mbx->stats.reqs.ev_count = 0;
439 1.8 msaitoh mbx->stats.acks.ev_count = 0;
440 1.8 msaitoh mbx->stats.rsts.ev_count = 0;
441 1.1 dyoung }
442 1.1 dyoung
443 1.1 dyoung static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index)
444 1.1 dyoung {
445 1.1 dyoung u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index));
446 1.1 dyoung s32 ret_val = IXGBE_ERR_MBX;
447 1.1 dyoung
448 1.1 dyoung if (mbvficr & mask) {
449 1.1 dyoung ret_val = IXGBE_SUCCESS;
450 1.1 dyoung IXGBE_WRITE_REG(hw, IXGBE_MBVFICR(index), mask);
451 1.1 dyoung }
452 1.1 dyoung
453 1.1 dyoung return ret_val;
454 1.1 dyoung }
455 1.1 dyoung
456 1.1 dyoung /**
457 1.13 msaitoh * ixgbe_check_for_msg_pf - checks to see if the VF has sent mail
458 1.13 msaitoh * @hw: pointer to the HW structure
459 1.13 msaitoh * @vf_number: the VF index
460 1.1 dyoung *
461 1.13 msaitoh * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
462 1.1 dyoung **/
463 1.1 dyoung static s32 ixgbe_check_for_msg_pf(struct ixgbe_hw *hw, u16 vf_number)
464 1.1 dyoung {
465 1.1 dyoung s32 ret_val = IXGBE_ERR_MBX;
466 1.1 dyoung s32 index = IXGBE_MBVFICR_INDEX(vf_number);
467 1.1 dyoung u32 vf_bit = vf_number % 16;
468 1.1 dyoung
469 1.1 dyoung DEBUGFUNC("ixgbe_check_for_msg_pf");
470 1.1 dyoung
471 1.1 dyoung if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFREQ_VF1 << vf_bit,
472 1.2 msaitoh index)) {
473 1.1 dyoung ret_val = IXGBE_SUCCESS;
474 1.8 msaitoh hw->mbx.stats.reqs.ev_count++;
475 1.1 dyoung }
476 1.1 dyoung
477 1.1 dyoung return ret_val;
478 1.1 dyoung }
479 1.1 dyoung
480 1.1 dyoung /**
481 1.13 msaitoh * ixgbe_check_for_ack_pf - checks to see if the VF has ACKed
482 1.13 msaitoh * @hw: pointer to the HW structure
483 1.13 msaitoh * @vf_number: the VF index
484 1.1 dyoung *
485 1.13 msaitoh * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
486 1.1 dyoung **/
487 1.1 dyoung static s32 ixgbe_check_for_ack_pf(struct ixgbe_hw *hw, u16 vf_number)
488 1.1 dyoung {
489 1.1 dyoung s32 ret_val = IXGBE_ERR_MBX;
490 1.1 dyoung s32 index = IXGBE_MBVFICR_INDEX(vf_number);
491 1.1 dyoung u32 vf_bit = vf_number % 16;
492 1.1 dyoung
493 1.1 dyoung DEBUGFUNC("ixgbe_check_for_ack_pf");
494 1.1 dyoung
495 1.1 dyoung if (!ixgbe_check_for_bit_pf(hw, IXGBE_MBVFICR_VFACK_VF1 << vf_bit,
496 1.2 msaitoh index)) {
497 1.1 dyoung ret_val = IXGBE_SUCCESS;
498 1.8 msaitoh hw->mbx.stats.acks.ev_count++;
499 1.1 dyoung }
500 1.1 dyoung
501 1.1 dyoung return ret_val;
502 1.1 dyoung }
503 1.1 dyoung
504 1.1 dyoung /**
505 1.13 msaitoh * ixgbe_check_for_rst_pf - checks to see if the VF has reset
506 1.13 msaitoh * @hw: pointer to the HW structure
507 1.13 msaitoh * @vf_number: the VF index
508 1.1 dyoung *
509 1.13 msaitoh * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
510 1.1 dyoung **/
511 1.1 dyoung static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)
512 1.1 dyoung {
513 1.1 dyoung u32 reg_offset = (vf_number < 32) ? 0 : 1;
514 1.1 dyoung u32 vf_shift = vf_number % 32;
515 1.1 dyoung u32 vflre = 0;
516 1.1 dyoung s32 ret_val = IXGBE_ERR_MBX;
517 1.1 dyoung
518 1.1 dyoung DEBUGFUNC("ixgbe_check_for_rst_pf");
519 1.1 dyoung
520 1.1 dyoung switch (hw->mac.type) {
521 1.1 dyoung case ixgbe_mac_82599EB:
522 1.1 dyoung vflre = IXGBE_READ_REG(hw, IXGBE_VFLRE(reg_offset));
523 1.1 dyoung break;
524 1.4 msaitoh case ixgbe_mac_X550:
525 1.4 msaitoh case ixgbe_mac_X550EM_x:
526 1.7 msaitoh case ixgbe_mac_X550EM_a:
527 1.2 msaitoh case ixgbe_mac_X540:
528 1.2 msaitoh vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset));
529 1.2 msaitoh break;
530 1.1 dyoung default:
531 1.1 dyoung break;
532 1.1 dyoung }
533 1.1 dyoung
534 1.1 dyoung if (vflre & (1 << vf_shift)) {
535 1.1 dyoung ret_val = IXGBE_SUCCESS;
536 1.1 dyoung IXGBE_WRITE_REG(hw, IXGBE_VFLREC(reg_offset), (1 << vf_shift));
537 1.8 msaitoh hw->mbx.stats.rsts.ev_count++;
538 1.1 dyoung }
539 1.1 dyoung
540 1.1 dyoung return ret_val;
541 1.1 dyoung }
542 1.1 dyoung
543 1.1 dyoung /**
544 1.13 msaitoh * ixgbe_obtain_mbx_lock_pf - obtain mailbox lock
545 1.13 msaitoh * @hw: pointer to the HW structure
546 1.13 msaitoh * @vf_number: the VF index
547 1.1 dyoung *
548 1.13 msaitoh * return SUCCESS if we obtained the mailbox lock
549 1.1 dyoung **/
550 1.1 dyoung static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number)
551 1.1 dyoung {
552 1.1 dyoung s32 ret_val = IXGBE_ERR_MBX;
553 1.1 dyoung u32 p2v_mailbox;
554 1.1 dyoung
555 1.1 dyoung DEBUGFUNC("ixgbe_obtain_mbx_lock_pf");
556 1.1 dyoung
557 1.1 dyoung /* Take ownership of the buffer */
558 1.1 dyoung IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_PFU);
559 1.1 dyoung
560 1.1 dyoung /* reserve mailbox for vf use */
561 1.1 dyoung p2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number));
562 1.1 dyoung if (p2v_mailbox & IXGBE_PFMAILBOX_PFU)
563 1.1 dyoung ret_val = IXGBE_SUCCESS;
564 1.4 msaitoh else
565 1.4 msaitoh ERROR_REPORT2(IXGBE_ERROR_POLLING,
566 1.4 msaitoh "Failed to obtain mailbox lock for VF%d", vf_number);
567 1.4 msaitoh
568 1.1 dyoung
569 1.1 dyoung return ret_val;
570 1.1 dyoung }
571 1.1 dyoung
572 1.1 dyoung /**
573 1.13 msaitoh * ixgbe_write_mbx_pf - Places a message in the mailbox
574 1.13 msaitoh * @hw: pointer to the HW structure
575 1.13 msaitoh * @msg: The message buffer
576 1.13 msaitoh * @size: Length of buffer
577 1.13 msaitoh * @vf_number: the VF index
578 1.1 dyoung *
579 1.13 msaitoh * returns SUCCESS if it successfully copied message into the buffer
580 1.1 dyoung **/
581 1.1 dyoung static s32 ixgbe_write_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
582 1.2 msaitoh u16 vf_number)
583 1.1 dyoung {
584 1.1 dyoung s32 ret_val;
585 1.1 dyoung u16 i;
586 1.1 dyoung
587 1.1 dyoung DEBUGFUNC("ixgbe_write_mbx_pf");
588 1.1 dyoung
589 1.1 dyoung /* lock the mailbox to prevent pf/vf race condition */
590 1.1 dyoung ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
591 1.1 dyoung if (ret_val)
592 1.1 dyoung goto out_no_write;
593 1.1 dyoung
594 1.1 dyoung /* flush msg and acks as we are overwriting the message buffer */
595 1.1 dyoung ixgbe_check_for_msg_pf(hw, vf_number);
596 1.1 dyoung ixgbe_check_for_ack_pf(hw, vf_number);
597 1.1 dyoung
598 1.1 dyoung /* copy the caller specified message to the mailbox memory buffer */
599 1.1 dyoung for (i = 0; i < size; i++)
600 1.1 dyoung IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, msg[i]);
601 1.1 dyoung
602 1.1 dyoung /* Interrupt VF to tell it a message has been sent and release buffer*/
603 1.1 dyoung IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_STS);
604 1.1 dyoung
605 1.1 dyoung /* update stats */
606 1.8 msaitoh hw->mbx.stats.msgs_tx.ev_count++;
607 1.1 dyoung
608 1.1 dyoung out_no_write:
609 1.1 dyoung return ret_val;
610 1.1 dyoung
611 1.1 dyoung }
612 1.1 dyoung
613 1.1 dyoung /**
614 1.13 msaitoh * ixgbe_read_mbx_pf - Read a message from the mailbox
615 1.13 msaitoh * @hw: pointer to the HW structure
616 1.13 msaitoh * @msg: The message buffer
617 1.13 msaitoh * @size: Length of buffer
618 1.13 msaitoh * @vf_number: the VF index
619 1.13 msaitoh *
620 1.13 msaitoh * This function copies a message from the mailbox buffer to the caller's
621 1.13 msaitoh * memory buffer. The presumption is that the caller knows that there was
622 1.13 msaitoh * a message due to a VF request so no polling for message is needed.
623 1.1 dyoung **/
624 1.1 dyoung static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
625 1.2 msaitoh u16 vf_number)
626 1.1 dyoung {
627 1.1 dyoung s32 ret_val;
628 1.1 dyoung u16 i;
629 1.1 dyoung
630 1.1 dyoung DEBUGFUNC("ixgbe_read_mbx_pf");
631 1.1 dyoung
632 1.1 dyoung /* lock the mailbox to prevent pf/vf race condition */
633 1.1 dyoung ret_val = ixgbe_obtain_mbx_lock_pf(hw, vf_number);
634 1.1 dyoung if (ret_val)
635 1.1 dyoung goto out_no_read;
636 1.1 dyoung
637 1.1 dyoung /* copy the message to the mailbox memory buffer */
638 1.1 dyoung for (i = 0; i < size; i++)
639 1.1 dyoung msg[i] = IXGBE_READ_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i);
640 1.1 dyoung
641 1.1 dyoung /* Acknowledge the message and release buffer */
642 1.1 dyoung IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_ACK);
643 1.1 dyoung
644 1.1 dyoung /* update stats */
645 1.8 msaitoh hw->mbx.stats.msgs_rx.ev_count++;
646 1.1 dyoung
647 1.1 dyoung out_no_read:
648 1.1 dyoung return ret_val;
649 1.1 dyoung }
650 1.1 dyoung
651 1.1 dyoung /**
652 1.13 msaitoh * ixgbe_clear_mbx_pf - Clear Mailbox Memory
653 1.13 msaitoh * @hw: pointer to the HW structure
654 1.13 msaitoh * @vf_number: the VF index
655 1.11 msaitoh *
656 1.13 msaitoh * Set VFMBMEM of given VF to 0x0.
657 1.11 msaitoh **/
658 1.11 msaitoh static s32 ixgbe_clear_mbx_pf(struct ixgbe_hw *hw, u16 vf_number)
659 1.11 msaitoh {
660 1.11 msaitoh u16 mbx_size = hw->mbx.size;
661 1.11 msaitoh u16 i;
662 1.11 msaitoh
663 1.11 msaitoh if (vf_number > 63)
664 1.11 msaitoh return IXGBE_ERR_PARAM;
665 1.11 msaitoh
666 1.11 msaitoh for (i = 0; i < mbx_size; ++i)
667 1.11 msaitoh IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_number), i, 0x0);
668 1.11 msaitoh
669 1.11 msaitoh return IXGBE_SUCCESS;
670 1.11 msaitoh }
671 1.11 msaitoh
672 1.11 msaitoh /**
673 1.13 msaitoh * ixgbe_init_mbx_params_pf - set initial values for pf mailbox
674 1.13 msaitoh * @hw: pointer to the HW structure
675 1.1 dyoung *
676 1.13 msaitoh * Initializes the hw->mbx struct to correct values for pf mailbox
677 1.1 dyoung */
678 1.1 dyoung void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
679 1.1 dyoung {
680 1.1 dyoung struct ixgbe_mbx_info *mbx = &hw->mbx;
681 1.1 dyoung
682 1.2 msaitoh if (hw->mac.type != ixgbe_mac_82599EB &&
683 1.4 msaitoh hw->mac.type != ixgbe_mac_X550 &&
684 1.4 msaitoh hw->mac.type != ixgbe_mac_X550EM_x &&
685 1.7 msaitoh hw->mac.type != ixgbe_mac_X550EM_a &&
686 1.2 msaitoh hw->mac.type != ixgbe_mac_X540)
687 1.1 dyoung return;
688 1.1 dyoung
689 1.1 dyoung mbx->timeout = 0;
690 1.1 dyoung mbx->usec_delay = 0;
691 1.1 dyoung
692 1.1 dyoung mbx->size = IXGBE_VFMAILBOX_SIZE;
693 1.1 dyoung
694 1.1 dyoung mbx->ops.read = ixgbe_read_mbx_pf;
695 1.1 dyoung mbx->ops.write = ixgbe_write_mbx_pf;
696 1.1 dyoung mbx->ops.read_posted = ixgbe_read_posted_mbx;
697 1.1 dyoung mbx->ops.write_posted = ixgbe_write_posted_mbx;
698 1.1 dyoung mbx->ops.check_for_msg = ixgbe_check_for_msg_pf;
699 1.1 dyoung mbx->ops.check_for_ack = ixgbe_check_for_ack_pf;
700 1.1 dyoung mbx->ops.check_for_rst = ixgbe_check_for_rst_pf;
701 1.11 msaitoh mbx->ops.clear = ixgbe_clear_mbx_pf;
702 1.1 dyoung
703 1.8 msaitoh mbx->stats.msgs_tx.ev_count = 0;
704 1.8 msaitoh mbx->stats.msgs_rx.ev_count = 0;
705 1.8 msaitoh mbx->stats.reqs.ev_count = 0;
706 1.8 msaitoh mbx->stats.acks.ev_count = 0;
707 1.8 msaitoh mbx->stats.rsts.ev_count = 0;
708 1.1 dyoung }
709