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