1 | /****************************************************************************** |
2 | |
3 | Copyright (c) 2001-2013, Intel Corporation |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met: |
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | |
12 | 2. Redistributions in binary form must reproduce the above copyright |
13 | notice, this list of conditions and the following disclaimer in the |
14 | documentation and/or other materials provided with the distribution. |
15 | |
16 | 3. Neither the name of the Intel Corporation nor the names of its |
17 | contributors may be used to endorse or promote products derived from |
18 | this software without specific prior written permission. |
19 | |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
23 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
24 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
25 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
26 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
27 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
28 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
29 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
30 | POSSIBILITY OF SUCH DAMAGE. |
31 | |
32 | ******************************************************************************/ |
33 | /*$FreeBSD: head/sys/dev/ixgbe/ixgbe_vf.c 251964 2013-06-18 21:28:19Z jfv $*/ |
34 | /*$NetBSD: ixgbe_vf.c,v 1.6 2016/02/06 02:39:51 riastradh Exp $*/ |
35 | |
36 | |
37 | #include "ixgbe_api.h" |
38 | #include "ixgbe_type.h" |
39 | #include "ixgbe_vf.h" |
40 | |
41 | #ifndef IXGBE_VFWRITE_REG |
42 | #define IXGBE_VFWRITE_REG IXGBE_WRITE_REG |
43 | #endif |
44 | #ifndef IXGBE_VFREAD_REG |
45 | #define IXGBE_VFREAD_REG IXGBE_READ_REG |
46 | #endif |
47 | |
48 | /** |
49 | * ixgbe_init_ops_vf - Initialize the pointers for vf |
50 | * @hw: pointer to hardware structure |
51 | * |
52 | * This will assign function pointers, adapter-specific functions can |
53 | * override the assignment of generic function pointers by assigning |
54 | * their own adapter-specific function pointers. |
55 | * Does not touch the hardware. |
56 | **/ |
57 | s32 ixgbe_init_ops_vf(struct ixgbe_hw *hw) |
58 | { |
59 | /* MAC */ |
60 | hw->mac.ops.init_hw = ixgbe_init_hw_vf; |
61 | hw->mac.ops.reset_hw = ixgbe_reset_hw_vf; |
62 | hw->mac.ops.start_hw = ixgbe_start_hw_vf; |
63 | /* Cannot clear stats on VF */ |
64 | hw->mac.ops.clear_hw_cntrs = NULL; |
65 | hw->mac.ops.get_media_type = NULL; |
66 | hw->mac.ops.get_mac_addr = ixgbe_get_mac_addr_vf; |
67 | hw->mac.ops.stop_adapter = ixgbe_stop_adapter_vf; |
68 | hw->mac.ops.get_bus_info = NULL; |
69 | |
70 | /* Link */ |
71 | hw->mac.ops.setup_link = ixgbe_setup_mac_link_vf; |
72 | hw->mac.ops.check_link = ixgbe_check_mac_link_vf; |
73 | hw->mac.ops.get_link_capabilities = NULL; |
74 | |
75 | /* RAR, Multicast, VLAN */ |
76 | hw->mac.ops.set_rar = ixgbe_set_rar_vf; |
77 | hw->mac.ops.set_uc_addr = ixgbevf_set_uc_addr_vf; |
78 | hw->mac.ops.init_rx_addrs = NULL; |
79 | hw->mac.ops.update_mc_addr_list = ixgbe_update_mc_addr_list_vf; |
80 | hw->mac.ops.enable_mc = NULL; |
81 | hw->mac.ops.disable_mc = NULL; |
82 | hw->mac.ops.clear_vfta = NULL; |
83 | hw->mac.ops.set_vfta = ixgbe_set_vfta_vf; |
84 | |
85 | hw->mac.max_tx_queues = 1; |
86 | hw->mac.max_rx_queues = 1; |
87 | |
88 | hw->mbx.ops.init_params = ixgbe_init_mbx_params_vf; |
89 | |
90 | return IXGBE_SUCCESS; |
91 | } |
92 | |
93 | /** |
94 | * ixgbe_start_hw_vf - Prepare hardware for Tx/Rx |
95 | * @hw: pointer to hardware structure |
96 | * |
97 | * Starts the hardware by filling the bus info structure and media type, clears |
98 | * all on chip counters, initializes receive address registers, multicast |
99 | * table, VLAN filter table, calls routine to set up link and flow control |
100 | * settings, and leaves transmit and receive units disabled and uninitialized |
101 | **/ |
102 | s32 ixgbe_start_hw_vf(struct ixgbe_hw *hw) |
103 | { |
104 | /* Clear adapter stopped flag */ |
105 | hw->adapter_stopped = FALSE; |
106 | |
107 | return IXGBE_SUCCESS; |
108 | } |
109 | |
110 | /** |
111 | * ixgbe_init_hw_vf - virtual function hardware initialization |
112 | * @hw: pointer to hardware structure |
113 | * |
114 | * Initialize the hardware by resetting the hardware and then starting |
115 | * the hardware |
116 | **/ |
117 | s32 ixgbe_init_hw_vf(struct ixgbe_hw *hw) |
118 | { |
119 | s32 status = hw->mac.ops.start_hw(hw); |
120 | |
121 | hw->mac.ops.get_mac_addr(hw, hw->mac.addr); |
122 | |
123 | return status; |
124 | } |
125 | |
126 | /** |
127 | * ixgbe_reset_hw_vf - Performs hardware reset |
128 | * @hw: pointer to hardware structure |
129 | * |
130 | * Resets the hardware by reseting the transmit and receive units, masks and |
131 | * clears all interrupts. |
132 | **/ |
133 | s32 ixgbe_reset_hw_vf(struct ixgbe_hw *hw) |
134 | { |
135 | struct ixgbe_mbx_info *mbx = &hw->mbx; |
136 | u32 timeout = IXGBE_VF_INIT_TIMEOUT; |
137 | s32 ret_val = IXGBE_ERR_INVALID_MAC_ADDR; |
138 | u32 ctrl, msgbuf[IXGBE_VF_PERMADDR_MSG_LEN]; |
139 | u8 *addr = (u8 *)(&msgbuf[1]); |
140 | |
141 | DEBUGFUNC("ixgbevf_reset_hw_vf" ); |
142 | |
143 | /* Call adapter stop to disable tx/rx and clear interrupts */ |
144 | hw->mac.ops.stop_adapter(hw); |
145 | |
146 | |
147 | DEBUGOUT("Issuing a function level reset to MAC\n" ); |
148 | |
149 | ctrl = IXGBE_VFREAD_REG(hw, IXGBE_VFCTRL) | IXGBE_CTRL_RST; |
150 | IXGBE_VFWRITE_REG(hw, IXGBE_VFCTRL, ctrl); |
151 | IXGBE_WRITE_FLUSH(hw); |
152 | |
153 | msec_delay(50); |
154 | |
155 | /* we cannot reset while the RSTI / RSTD bits are asserted */ |
156 | while (!mbx->ops.check_for_rst(hw, 0) && timeout) { |
157 | timeout--; |
158 | usec_delay(5); |
159 | } |
160 | |
161 | if (!timeout) |
162 | return IXGBE_ERR_RESET_FAILED; |
163 | |
164 | /* mailbox timeout can now become active */ |
165 | mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT; |
166 | |
167 | msgbuf[0] = IXGBE_VF_RESET; |
168 | mbx->ops.write_posted(hw, msgbuf, 1, 0); |
169 | |
170 | msec_delay(10); |
171 | |
172 | /* |
173 | * set our "perm_addr" based on info provided by PF |
174 | * also set up the mc_filter_type which is piggy backed |
175 | * on the mac address in word 3 |
176 | */ |
177 | ret_val = mbx->ops.read_posted(hw, msgbuf, |
178 | IXGBE_VF_PERMADDR_MSG_LEN, 0); |
179 | if (ret_val) |
180 | return ret_val; |
181 | |
182 | if (msgbuf[0] != (IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_ACK) && |
183 | msgbuf[0] != (IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_NACK)) |
184 | return IXGBE_ERR_INVALID_MAC_ADDR; |
185 | |
186 | memcpy(hw->mac.perm_addr, addr, IXGBE_ETH_LENGTH_OF_ADDRESS); |
187 | hw->mac.mc_filter_type = msgbuf[IXGBE_VF_MC_TYPE_WORD]; |
188 | |
189 | return ret_val; |
190 | } |
191 | |
192 | /** |
193 | * ixgbe_stop_adapter_vf - Generic stop Tx/Rx units |
194 | * @hw: pointer to hardware structure |
195 | * |
196 | * Sets the adapter_stopped flag within ixgbe_hw struct. Clears interrupts, |
197 | * disables transmit and receive units. The adapter_stopped flag is used by |
198 | * the shared code and drivers to determine if the adapter is in a stopped |
199 | * state and should not touch the hardware. |
200 | **/ |
201 | s32 ixgbe_stop_adapter_vf(struct ixgbe_hw *hw) |
202 | { |
203 | u32 reg_val; |
204 | u16 i; |
205 | |
206 | /* |
207 | * Set the adapter_stopped flag so other driver functions stop touching |
208 | * the hardware |
209 | */ |
210 | hw->adapter_stopped = TRUE; |
211 | |
212 | /* Clear interrupt mask to stop from interrupts being generated */ |
213 | IXGBE_VFWRITE_REG(hw, IXGBE_VTEIMC, IXGBE_VF_IRQ_CLEAR_MASK); |
214 | |
215 | /* Clear any pending interrupts, flush previous writes */ |
216 | IXGBE_VFREAD_REG(hw, IXGBE_VTEICR); |
217 | |
218 | /* Disable the transmit unit. Each queue must be disabled. */ |
219 | for (i = 0; i < hw->mac.max_tx_queues; i++) |
220 | IXGBE_VFWRITE_REG(hw, IXGBE_VFTXDCTL(i), IXGBE_TXDCTL_SWFLSH); |
221 | |
222 | /* Disable the receive unit by stopping each queue */ |
223 | for (i = 0; i < hw->mac.max_rx_queues; i++) { |
224 | reg_val = IXGBE_VFREAD_REG(hw, IXGBE_VFRXDCTL(i)); |
225 | reg_val &= ~IXGBE_RXDCTL_ENABLE; |
226 | IXGBE_VFWRITE_REG(hw, IXGBE_VFRXDCTL(i), reg_val); |
227 | } |
228 | |
229 | /* flush all queues disables */ |
230 | IXGBE_WRITE_FLUSH(hw); |
231 | msec_delay(2); |
232 | |
233 | return IXGBE_SUCCESS; |
234 | } |
235 | |
236 | /** |
237 | * ixgbe_mta_vector - Determines bit-vector in multicast table to set |
238 | * @hw: pointer to hardware structure |
239 | * @mc_addr: the multicast address |
240 | * |
241 | * Extracts the 12 bits, from a multicast address, to determine which |
242 | * bit-vector to set in the multicast table. The hardware uses 12 bits, from |
243 | * incoming rx multicast addresses, to determine the bit-vector to check in |
244 | * the MTA. Which of the 4 combination, of 12-bits, the hardware uses is set |
245 | * by the MO field of the MCSTCTRL. The MO field is set during initialization |
246 | * to mc_filter_type. |
247 | **/ |
248 | static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr) |
249 | { |
250 | u32 vector = 0; |
251 | |
252 | switch (hw->mac.mc_filter_type) { |
253 | case 0: /* use bits [47:36] of the address */ |
254 | vector = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4)); |
255 | break; |
256 | case 1: /* use bits [46:35] of the address */ |
257 | vector = ((mc_addr[4] >> 3) | (((u16)mc_addr[5]) << 5)); |
258 | break; |
259 | case 2: /* use bits [45:34] of the address */ |
260 | vector = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6)); |
261 | break; |
262 | case 3: /* use bits [43:32] of the address */ |
263 | vector = ((mc_addr[4]) | (((u16)mc_addr[5]) << 8)); |
264 | break; |
265 | default: /* Invalid mc_filter_type */ |
266 | DEBUGOUT("MC filter type param set incorrectly\n" ); |
267 | ASSERT(0); |
268 | break; |
269 | } |
270 | |
271 | /* vector can only be 12-bits or boundary will be exceeded */ |
272 | vector &= 0xFFF; |
273 | return vector; |
274 | } |
275 | |
276 | static void ixgbevf_write_msg_read_ack(struct ixgbe_hw *hw, |
277 | u32 *msg, u16 size) |
278 | { |
279 | struct ixgbe_mbx_info *mbx = &hw->mbx; |
280 | u32 retmsg[IXGBE_VFMAILBOX_SIZE]; |
281 | s32 retval = mbx->ops.write_posted(hw, msg, size, 0); |
282 | |
283 | if (!retval) |
284 | mbx->ops.read_posted(hw, retmsg, size, 0); |
285 | } |
286 | |
287 | /** |
288 | * ixgbe_set_rar_vf - set device MAC address |
289 | * @hw: pointer to hardware structure |
290 | * @index: Receive address register to write |
291 | * @addr: Address to put into receive address register |
292 | * @vmdq: VMDq "set" or "pool" index |
293 | * @enable_addr: set flag that address is active |
294 | **/ |
295 | s32 ixgbe_set_rar_vf(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, |
296 | u32 enable_addr) |
297 | { |
298 | struct ixgbe_mbx_info *mbx = &hw->mbx; |
299 | u32 msgbuf[3]; |
300 | u8 *msg_addr = (u8 *)(&msgbuf[1]); |
301 | s32 ret_val; |
302 | UNREFERENCED_3PARAMETER(vmdq, enable_addr, index); |
303 | |
304 | memset(msgbuf, 0, 12); |
305 | msgbuf[0] = IXGBE_VF_SET_MAC_ADDR; |
306 | memcpy(msg_addr, addr, 6); |
307 | ret_val = mbx->ops.write_posted(hw, msgbuf, 3, 0); |
308 | |
309 | if (!ret_val) |
310 | ret_val = mbx->ops.read_posted(hw, msgbuf, 3, 0); |
311 | |
312 | msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS; |
313 | |
314 | /* if nacked the address was rejected, use "perm_addr" */ |
315 | if (!ret_val && |
316 | (msgbuf[0] == (IXGBE_VF_SET_MAC_ADDR | IXGBE_VT_MSGTYPE_NACK))) |
317 | ixgbe_get_mac_addr_vf(hw, hw->mac.addr); |
318 | |
319 | return ret_val; |
320 | } |
321 | |
322 | /** |
323 | * ixgbe_update_mc_addr_list_vf - Update Multicast addresses |
324 | * @hw: pointer to the HW structure |
325 | * @mc_addr_list: array of multicast addresses to program |
326 | * @mc_addr_count: number of multicast addresses to program |
327 | * @next: caller supplied function to return next address in list |
328 | * |
329 | * Updates the Multicast Table Array. |
330 | **/ |
331 | s32 ixgbe_update_mc_addr_list_vf(struct ixgbe_hw *hw, u8 *mc_addr_list, |
332 | u32 mc_addr_count, ixgbe_mc_addr_itr next, |
333 | bool clear) |
334 | { |
335 | struct ixgbe_mbx_info *mbx = &hw->mbx; |
336 | u32 msgbuf[IXGBE_VFMAILBOX_SIZE]; |
337 | u16 *vector_list = (u16 *)&msgbuf[1]; |
338 | u32 vector; |
339 | u32 cnt, i; |
340 | u32 vmdq; |
341 | |
342 | UNREFERENCED_1PARAMETER(clear); |
343 | |
344 | DEBUGFUNC("ixgbe_update_mc_addr_list_vf" ); |
345 | |
346 | /* Each entry in the list uses 1 16 bit word. We have 30 |
347 | * 16 bit words available in our HW msg buffer (minus 1 for the |
348 | * msg type). That's 30 hash values if we pack 'em right. If |
349 | * there are more than 30 MC addresses to add then punt the |
350 | * extras for now and then add code to handle more than 30 later. |
351 | * It would be unusual for a server to request that many multi-cast |
352 | * addresses except for in large enterprise network environments. |
353 | */ |
354 | |
355 | DEBUGOUT1("MC Addr Count = %d\n" , mc_addr_count); |
356 | |
357 | cnt = (mc_addr_count > 30) ? 30 : mc_addr_count; |
358 | msgbuf[0] = IXGBE_VF_SET_MULTICAST; |
359 | msgbuf[0] |= cnt << IXGBE_VT_MSGINFO_SHIFT; |
360 | |
361 | for (i = 0; i < cnt; i++) { |
362 | vector = ixgbe_mta_vector(hw, next(hw, &mc_addr_list, &vmdq)); |
363 | DEBUGOUT1("Hash value = 0x%03X\n" , vector); |
364 | vector_list[i] = (u16)vector; |
365 | } |
366 | |
367 | return mbx->ops.write_posted(hw, msgbuf, IXGBE_VFMAILBOX_SIZE, 0); |
368 | } |
369 | |
370 | /** |
371 | * ixgbe_set_vfta_vf - Set/Unset vlan filter table address |
372 | * @hw: pointer to the HW structure |
373 | * @vlan: 12 bit VLAN ID |
374 | * @vind: unused by VF drivers |
375 | * @vlan_on: if TRUE then set bit, else clear bit |
376 | **/ |
377 | s32 ixgbe_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on) |
378 | { |
379 | struct ixgbe_mbx_info *mbx = &hw->mbx; |
380 | u32 msgbuf[2]; |
381 | s32 ret_val; |
382 | UNREFERENCED_1PARAMETER(vind); |
383 | |
384 | msgbuf[0] = IXGBE_VF_SET_VLAN; |
385 | msgbuf[1] = vlan; |
386 | /* Setting the 8 bit field MSG INFO to TRUE indicates "add" */ |
387 | msgbuf[0] |= (u32)vlan_on << IXGBE_VT_MSGINFO_SHIFT; |
388 | |
389 | ret_val = mbx->ops.write_posted(hw, msgbuf, 2, 0); |
390 | if (!ret_val) |
391 | ret_val = mbx->ops.read_posted(hw, msgbuf, 1, 0); |
392 | |
393 | if (!ret_val && (msgbuf[0] & IXGBE_VT_MSGTYPE_ACK)) |
394 | return IXGBE_SUCCESS; |
395 | |
396 | return ret_val | (msgbuf[0] & IXGBE_VT_MSGTYPE_NACK); |
397 | } |
398 | |
399 | /** |
400 | * ixgbe_get_num_of_tx_queues_vf - Get number of TX queues |
401 | * @hw: pointer to hardware structure |
402 | * |
403 | * Returns the number of transmit queues for the given adapter. |
404 | **/ |
405 | u32 ixgbe_get_num_of_tx_queues_vf(struct ixgbe_hw *hw) |
406 | { |
407 | UNREFERENCED_1PARAMETER(hw); |
408 | return IXGBE_VF_MAX_TX_QUEUES; |
409 | } |
410 | |
411 | /** |
412 | * ixgbe_get_num_of_rx_queues_vf - Get number of RX queues |
413 | * @hw: pointer to hardware structure |
414 | * |
415 | * Returns the number of receive queues for the given adapter. |
416 | **/ |
417 | u32 ixgbe_get_num_of_rx_queues_vf(struct ixgbe_hw *hw) |
418 | { |
419 | UNREFERENCED_1PARAMETER(hw); |
420 | return IXGBE_VF_MAX_RX_QUEUES; |
421 | } |
422 | |
423 | /** |
424 | * ixgbe_get_mac_addr_vf - Read device MAC address |
425 | * @hw: pointer to the HW structure |
426 | **/ |
427 | s32 ixgbe_get_mac_addr_vf(struct ixgbe_hw *hw, u8 *mac_addr) |
428 | { |
429 | int i; |
430 | |
431 | for (i = 0; i < IXGBE_ETH_LENGTH_OF_ADDRESS; i++) |
432 | mac_addr[i] = hw->mac.perm_addr[i]; |
433 | |
434 | return IXGBE_SUCCESS; |
435 | } |
436 | |
437 | s32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr) |
438 | { |
439 | struct ixgbe_mbx_info *mbx = &hw->mbx; |
440 | u32 msgbuf[3]; |
441 | u8 *msg_addr = (u8 *)(&msgbuf[1]); |
442 | s32 ret_val; |
443 | |
444 | memset(msgbuf, 0, sizeof(msgbuf)); |
445 | /* |
446 | * If index is one then this is the start of a new list and needs |
447 | * indication to the PF so it can do it's own list management. |
448 | * If it is zero then that tells the PF to just clear all of |
449 | * this VF's macvlans and there is no new list. |
450 | */ |
451 | msgbuf[0] |= index << IXGBE_VT_MSGINFO_SHIFT; |
452 | msgbuf[0] |= IXGBE_VF_SET_MACVLAN; |
453 | if (addr) |
454 | memcpy(msg_addr, addr, 6); |
455 | ret_val = mbx->ops.write_posted(hw, msgbuf, 3, 0); |
456 | |
457 | if (!ret_val) |
458 | ret_val = mbx->ops.read_posted(hw, msgbuf, 3, 0); |
459 | |
460 | msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS; |
461 | |
462 | if (!ret_val) |
463 | if (msgbuf[0] == (IXGBE_VF_SET_MACVLAN | IXGBE_VT_MSGTYPE_NACK)) |
464 | ret_val = IXGBE_ERR_OUT_OF_MEM; |
465 | |
466 | return ret_val; |
467 | } |
468 | |
469 | /** |
470 | * ixgbe_setup_mac_link_vf - Setup MAC link settings |
471 | * @hw: pointer to hardware structure |
472 | * @speed: new link speed |
473 | * @autoneg: TRUE if autonegotiation enabled |
474 | * @autoneg_wait_to_complete: TRUE when waiting for completion is needed |
475 | * |
476 | * Set the link speed in the AUTOC register and restarts link. |
477 | **/ |
478 | s32 ixgbe_setup_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed speed, |
479 | bool autoneg_wait_to_complete) |
480 | { |
481 | UNREFERENCED_3PARAMETER(hw, speed, autoneg_wait_to_complete); |
482 | return IXGBE_SUCCESS; |
483 | } |
484 | |
485 | /** |
486 | * ixgbe_check_mac_link_vf - Get link/speed status |
487 | * @hw: pointer to hardware structure |
488 | * @speed: pointer to link speed |
489 | * @link_up: TRUE is link is up, FALSE otherwise |
490 | * @autoneg_wait_to_complete: TRUE when waiting for completion is needed |
491 | * |
492 | * Reads the links register to determine if link is up and the current speed |
493 | **/ |
494 | s32 ixgbe_check_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed *speed, |
495 | bool *link_up, bool autoneg_wait_to_complete) |
496 | { |
497 | struct ixgbe_mbx_info *mbx = &hw->mbx; |
498 | struct ixgbe_mac_info *mac = &hw->mac; |
499 | s32 ret_val = IXGBE_SUCCESS; |
500 | u32 links_reg; |
501 | u32 in_msg = 0; |
502 | UNREFERENCED_1PARAMETER(autoneg_wait_to_complete); |
503 | |
504 | /* If we were hit with a reset drop the link */ |
505 | if (!mbx->ops.check_for_rst(hw, 0) || !mbx->timeout) |
506 | mac->get_link_status = TRUE; |
507 | |
508 | if (!mac->get_link_status) |
509 | goto out; |
510 | |
511 | /* if link status is down no point in checking to see if pf is up */ |
512 | links_reg = IXGBE_READ_REG(hw, IXGBE_VFLINKS); |
513 | if (!(links_reg & IXGBE_LINKS_UP)) |
514 | goto out; |
515 | |
516 | switch (links_reg & IXGBE_LINKS_SPEED_82599) { |
517 | case IXGBE_LINKS_SPEED_10G_82599: |
518 | *speed = IXGBE_LINK_SPEED_10GB_FULL; |
519 | break; |
520 | case IXGBE_LINKS_SPEED_1G_82599: |
521 | *speed = IXGBE_LINK_SPEED_1GB_FULL; |
522 | break; |
523 | case IXGBE_LINKS_SPEED_100_82599: |
524 | *speed = IXGBE_LINK_SPEED_100_FULL; |
525 | break; |
526 | } |
527 | |
528 | /* if the read failed it could just be a mailbox collision, best wait |
529 | * until we are called again and don't report an error |
530 | */ |
531 | if (mbx->ops.read(hw, &in_msg, 1, 0)) |
532 | goto out; |
533 | |
534 | if (!(in_msg & IXGBE_VT_MSGTYPE_CTS)) { |
535 | /* msg is not CTS and is NACK we must have lost CTS status */ |
536 | if (in_msg & IXGBE_VT_MSGTYPE_NACK) |
537 | ret_val = -1; |
538 | goto out; |
539 | } |
540 | |
541 | /* the pf is talking, if we timed out in the past we reinit */ |
542 | if (!mbx->timeout) { |
543 | ret_val = -1; |
544 | goto out; |
545 | } |
546 | |
547 | /* if we passed all the tests above then the link is up and we no |
548 | * longer need to check for link |
549 | */ |
550 | mac->get_link_status = FALSE; |
551 | |
552 | out: |
553 | *link_up = !mac->get_link_status; |
554 | return ret_val; |
555 | } |
556 | |
557 | /** |
558 | * ixgbevf_rlpml_set_vf - Set the maximum receive packet length |
559 | * @hw: pointer to the HW structure |
560 | * @max_size: value to assign to max frame size |
561 | **/ |
562 | void ixgbevf_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size) |
563 | { |
564 | u32 msgbuf[2]; |
565 | |
566 | msgbuf[0] = IXGBE_VF_SET_LPE; |
567 | msgbuf[1] = max_size; |
568 | ixgbevf_write_msg_read_ack(hw, msgbuf, 2); |
569 | } |
570 | |
571 | /** |
572 | * ixgbevf_negotiate_api_version - Negotiate supported API version |
573 | * @hw: pointer to the HW structure |
574 | * @api: integer containing requested API version |
575 | **/ |
576 | int ixgbevf_negotiate_api_version(struct ixgbe_hw *hw, int api) |
577 | { |
578 | int err; |
579 | u32 msg[3]; |
580 | |
581 | /* Negotiate the mailbox API version */ |
582 | msg[0] = IXGBE_VF_API_NEGOTIATE; |
583 | msg[1] = api; |
584 | msg[2] = 0; |
585 | err = hw->mbx.ops.write_posted(hw, msg, 3, 0); |
586 | |
587 | if (!err) |
588 | err = hw->mbx.ops.read_posted(hw, msg, 3, 0); |
589 | |
590 | if (!err) { |
591 | msg[0] &= ~IXGBE_VT_MSGTYPE_CTS; |
592 | |
593 | /* Store value and return 0 on success */ |
594 | if (msg[0] == (IXGBE_VF_API_NEGOTIATE | IXGBE_VT_MSGTYPE_ACK)) { |
595 | hw->api_version = api; |
596 | return 0; |
597 | } |
598 | |
599 | err = IXGBE_ERR_INVALID_ARGUMENT; |
600 | } |
601 | |
602 | return err; |
603 | } |
604 | |
605 | int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs, |
606 | unsigned int *default_tc) |
607 | { |
608 | UNREFERENCED_3PARAMETER(hw, num_tcs, default_tc); |
609 | return IXGBE_SUCCESS; |
610 | } |
611 | |
612 | |