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