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