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