1215911Sjfv/******************************************************************************
2215911Sjfv
3247822Sjfv  Copyright (c) 2001-2013, Intel Corporation
4215911Sjfv  All rights reserved.
5215911Sjfv
6215911Sjfv  Redistribution and use in source and binary forms, with or without
7215911Sjfv  modification, are permitted provided that the following conditions are met:
8215911Sjfv
9215911Sjfv   1. Redistributions of source code must retain the above copyright notice,
10215911Sjfv      this list of conditions and the following disclaimer.
11215911Sjfv
12215911Sjfv   2. Redistributions in binary form must reproduce the above copyright
13215911Sjfv      notice, this list of conditions and the following disclaimer in the
14215911Sjfv      documentation and/or other materials provided with the distribution.
15215911Sjfv
16215911Sjfv   3. Neither the name of the Intel Corporation nor the names of its
17215911Sjfv      contributors may be used to endorse or promote products derived from
18215911Sjfv      this software without specific prior written permission.
19215911Sjfv
20215911Sjfv  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21215911Sjfv  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22215911Sjfv  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23215911Sjfv  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24215911Sjfv  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25215911Sjfv  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26215911Sjfv  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27215911Sjfv  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28215911Sjfv  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29215911Sjfv  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30215911Sjfv  POSSIBILITY OF SUCH DAMAGE.
31215911Sjfv
32215911Sjfv******************************************************************************/
33215911Sjfv/*$FreeBSD$*/
34215911Sjfv
35215911Sjfv
36215911Sjfv#include "ixgbe_api.h"
37215911Sjfv#include "ixgbe_type.h"
38215911Sjfv#include "ixgbe_vf.h"
39215911Sjfv
40215911Sjfv#ifndef IXGBE_VFWRITE_REG
41215911Sjfv#define IXGBE_VFWRITE_REG IXGBE_WRITE_REG
42215911Sjfv#endif
43215911Sjfv#ifndef IXGBE_VFREAD_REG
44215911Sjfv#define IXGBE_VFREAD_REG IXGBE_READ_REG
45215911Sjfv#endif
46215911Sjfv
47215911Sjfv/**
48215911Sjfv *  ixgbe_init_ops_vf - Initialize the pointers for vf
49215911Sjfv *  @hw: pointer to hardware structure
50215911Sjfv *
51215911Sjfv *  This will assign function pointers, adapter-specific functions can
52215911Sjfv *  override the assignment of generic function pointers by assigning
53215911Sjfv *  their own adapter-specific function pointers.
54215911Sjfv *  Does not touch the hardware.
55215911Sjfv **/
56215911Sjfvs32 ixgbe_init_ops_vf(struct ixgbe_hw *hw)
57215911Sjfv{
58215911Sjfv	/* MAC */
59215911Sjfv	hw->mac.ops.init_hw = ixgbe_init_hw_vf;
60215911Sjfv	hw->mac.ops.reset_hw = ixgbe_reset_hw_vf;
61215911Sjfv	hw->mac.ops.start_hw = ixgbe_start_hw_vf;
62215911Sjfv	/* Cannot clear stats on VF */
63215911Sjfv	hw->mac.ops.clear_hw_cntrs = NULL;
64215911Sjfv	hw->mac.ops.get_media_type = NULL;
65215911Sjfv	hw->mac.ops.get_mac_addr = ixgbe_get_mac_addr_vf;
66230775Sjfv	hw->mac.ops.stop_adapter = ixgbe_stop_adapter_vf;
67215911Sjfv	hw->mac.ops.get_bus_info = NULL;
68215911Sjfv
69215911Sjfv	/* Link */
70215911Sjfv	hw->mac.ops.setup_link = ixgbe_setup_mac_link_vf;
71215911Sjfv	hw->mac.ops.check_link = ixgbe_check_mac_link_vf;
72215911Sjfv	hw->mac.ops.get_link_capabilities = NULL;
73215911Sjfv
74215911Sjfv	/* RAR, Multicast, VLAN */
75215911Sjfv	hw->mac.ops.set_rar = ixgbe_set_rar_vf;
76230775Sjfv	hw->mac.ops.set_uc_addr = ixgbevf_set_uc_addr_vf;
77215911Sjfv	hw->mac.ops.init_rx_addrs = NULL;
78215911Sjfv	hw->mac.ops.update_mc_addr_list = ixgbe_update_mc_addr_list_vf;
79215911Sjfv	hw->mac.ops.enable_mc = NULL;
80215911Sjfv	hw->mac.ops.disable_mc = NULL;
81215911Sjfv	hw->mac.ops.clear_vfta = NULL;
82215911Sjfv	hw->mac.ops.set_vfta = ixgbe_set_vfta_vf;
83215911Sjfv
84215911Sjfv	hw->mac.max_tx_queues = 1;
85215911Sjfv	hw->mac.max_rx_queues = 1;
86215911Sjfv
87215911Sjfv	hw->mbx.ops.init_params = ixgbe_init_mbx_params_vf;
88215911Sjfv
89215911Sjfv	return IXGBE_SUCCESS;
90215911Sjfv}
91215911Sjfv
92215911Sjfv/**
93215911Sjfv *  ixgbe_start_hw_vf - Prepare hardware for Tx/Rx
94215911Sjfv *  @hw: pointer to hardware structure
95215911Sjfv *
96215911Sjfv *  Starts the hardware by filling the bus info structure and media type, clears
97215911Sjfv *  all on chip counters, initializes receive address registers, multicast
98215911Sjfv *  table, VLAN filter table, calls routine to set up link and flow control
99215911Sjfv *  settings, and leaves transmit and receive units disabled and uninitialized
100215911Sjfv **/
101215911Sjfvs32 ixgbe_start_hw_vf(struct ixgbe_hw *hw)
102215911Sjfv{
103215911Sjfv	/* Clear adapter stopped flag */
104215911Sjfv	hw->adapter_stopped = FALSE;
105215911Sjfv
106215911Sjfv	return IXGBE_SUCCESS;
107215911Sjfv}
108215911Sjfv
109215911Sjfv/**
110215911Sjfv *  ixgbe_init_hw_vf - virtual function hardware initialization
111215911Sjfv *  @hw: pointer to hardware structure
112215911Sjfv *
113215911Sjfv *  Initialize the hardware by resetting the hardware and then starting
114215911Sjfv *  the hardware
115215911Sjfv **/
116215911Sjfvs32 ixgbe_init_hw_vf(struct ixgbe_hw *hw)
117215911Sjfv{
118215911Sjfv	s32 status = hw->mac.ops.start_hw(hw);
119215911Sjfv
120215911Sjfv	hw->mac.ops.get_mac_addr(hw, hw->mac.addr);
121215911Sjfv
122215911Sjfv	return status;
123215911Sjfv}
124215911Sjfv
125215911Sjfv/**
126215911Sjfv *  ixgbe_reset_hw_vf - Performs hardware reset
127215911Sjfv *  @hw: pointer to hardware structure
128215911Sjfv *
129215911Sjfv *  Resets the hardware by reseting the transmit and receive units, masks and
130215911Sjfv *  clears all interrupts.
131215911Sjfv **/
132215911Sjfvs32 ixgbe_reset_hw_vf(struct ixgbe_hw *hw)
133215911Sjfv{
134215911Sjfv	struct ixgbe_mbx_info *mbx = &hw->mbx;
135215911Sjfv	u32 timeout = IXGBE_VF_INIT_TIMEOUT;
136215911Sjfv	s32 ret_val = IXGBE_ERR_INVALID_MAC_ADDR;
137215911Sjfv	u32 ctrl, msgbuf[IXGBE_VF_PERMADDR_MSG_LEN];
138215911Sjfv	u8 *addr = (u8 *)(&msgbuf[1]);
139215911Sjfv
140215911Sjfv	DEBUGFUNC("ixgbevf_reset_hw_vf");
141215911Sjfv
142215911Sjfv	/* Call adapter stop to disable tx/rx and clear interrupts */
143215911Sjfv	hw->mac.ops.stop_adapter(hw);
144215911Sjfv
145247822Sjfv
146215911Sjfv	DEBUGOUT("Issuing a function level reset to MAC\n");
147215911Sjfv
148230775Sjfv	ctrl = IXGBE_VFREAD_REG(hw, IXGBE_VFCTRL) | IXGBE_CTRL_RST;
149230775Sjfv	IXGBE_VFWRITE_REG(hw, IXGBE_VFCTRL, ctrl);
150230775Sjfv	IXGBE_WRITE_FLUSH(hw);
151215911Sjfv
152230775Sjfv	msec_delay(50);
153230775Sjfv
154215911Sjfv	/* we cannot reset while the RSTI / RSTD bits are asserted */
155215911Sjfv	while (!mbx->ops.check_for_rst(hw, 0) && timeout) {
156215911Sjfv		timeout--;
157215911Sjfv		usec_delay(5);
158215911Sjfv	}
159215911Sjfv
160251964Sjfv	if (!timeout)
161251964Sjfv		return IXGBE_ERR_RESET_FAILED;
162215911Sjfv
163251964Sjfv	/* mailbox timeout can now become active */
164251964Sjfv	mbx->timeout = IXGBE_VF_MBX_INIT_TIMEOUT;
165215911Sjfv
166251964Sjfv	msgbuf[0] = IXGBE_VF_RESET;
167251964Sjfv	mbx->ops.write_posted(hw, msgbuf, 1, 0);
168215911Sjfv
169251964Sjfv	msec_delay(10);
170215911Sjfv
171251964Sjfv	/*
172251964Sjfv	 * set our "perm_addr" based on info provided by PF
173251964Sjfv	 * also set up the mc_filter_type which is piggy backed
174251964Sjfv	 * on the mac address in word 3
175251964Sjfv	 */
176251964Sjfv	ret_val = mbx->ops.read_posted(hw, msgbuf,
177251964Sjfv			IXGBE_VF_PERMADDR_MSG_LEN, 0);
178251964Sjfv	if (ret_val)
179251964Sjfv		return ret_val;
180251964Sjfv
181251964Sjfv	if (msgbuf[0] != (IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_ACK) &&
182251964Sjfv	    msgbuf[0] != (IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_NACK))
183251964Sjfv		return IXGBE_ERR_INVALID_MAC_ADDR;
184251964Sjfv
185251964Sjfv	memcpy(hw->mac.perm_addr, addr, IXGBE_ETH_LENGTH_OF_ADDRESS);
186251964Sjfv	hw->mac.mc_filter_type = msgbuf[IXGBE_VF_MC_TYPE_WORD];
187251964Sjfv
188215911Sjfv	return ret_val;
189215911Sjfv}
190215911Sjfv
191215911Sjfv/**
192230775Sjfv *  ixgbe_stop_adapter_vf - Generic stop Tx/Rx units
193215911Sjfv *  @hw: pointer to hardware structure
194215911Sjfv *
195215911Sjfv *  Sets the adapter_stopped flag within ixgbe_hw struct. Clears interrupts,
196215911Sjfv *  disables transmit and receive units. The adapter_stopped flag is used by
197215911Sjfv *  the shared code and drivers to determine if the adapter is in a stopped
198215911Sjfv *  state and should not touch the hardware.
199215911Sjfv **/
200230775Sjfvs32 ixgbe_stop_adapter_vf(struct ixgbe_hw *hw)
201215911Sjfv{
202215911Sjfv	u32 reg_val;
203215911Sjfv	u16 i;
204215911Sjfv
205215911Sjfv	/*
206215911Sjfv	 * Set the adapter_stopped flag so other driver functions stop touching
207215911Sjfv	 * the hardware
208215911Sjfv	 */
209215911Sjfv	hw->adapter_stopped = TRUE;
210215911Sjfv
211215911Sjfv	/* Clear interrupt mask to stop from interrupts being generated */
212215911Sjfv	IXGBE_VFWRITE_REG(hw, IXGBE_VTEIMC, IXGBE_VF_IRQ_CLEAR_MASK);
213215911Sjfv
214230775Sjfv	/* Clear any pending interrupts, flush previous writes */
215215911Sjfv	IXGBE_VFREAD_REG(hw, IXGBE_VTEICR);
216215911Sjfv
217215911Sjfv	/* Disable the transmit unit.  Each queue must be disabled. */
218230775Sjfv	for (i = 0; i < hw->mac.max_tx_queues; i++)
219230775Sjfv		IXGBE_VFWRITE_REG(hw, IXGBE_VFTXDCTL(i), IXGBE_TXDCTL_SWFLSH);
220230775Sjfv
221230775Sjfv	/* Disable the receive unit by stopping each queue */
222230775Sjfv	for (i = 0; i < hw->mac.max_rx_queues; i++) {
223230775Sjfv		reg_val = IXGBE_VFREAD_REG(hw, IXGBE_VFRXDCTL(i));
224230775Sjfv		reg_val &= ~IXGBE_RXDCTL_ENABLE;
225230775Sjfv		IXGBE_VFWRITE_REG(hw, IXGBE_VFRXDCTL(i), reg_val);
226215911Sjfv	}
227215911Sjfv
228230775Sjfv	/* flush all queues disables */
229230775Sjfv	IXGBE_WRITE_FLUSH(hw);
230230775Sjfv	msec_delay(2);
231230775Sjfv
232215911Sjfv	return IXGBE_SUCCESS;
233215911Sjfv}
234215911Sjfv
235215911Sjfv/**
236215911Sjfv *  ixgbe_mta_vector - Determines bit-vector in multicast table to set
237215911Sjfv *  @hw: pointer to hardware structure
238215911Sjfv *  @mc_addr: the multicast address
239215911Sjfv *
240215911Sjfv *  Extracts the 12 bits, from a multicast address, to determine which
241215911Sjfv *  bit-vector to set in the multicast table. The hardware uses 12 bits, from
242215911Sjfv *  incoming rx multicast addresses, to determine the bit-vector to check in
243215911Sjfv *  the MTA. Which of the 4 combination, of 12-bits, the hardware uses is set
244215911Sjfv *  by the MO field of the MCSTCTRL. The MO field is set during initialization
245215911Sjfv *  to mc_filter_type.
246215911Sjfv **/
247215911Sjfvstatic s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr)
248215911Sjfv{
249215911Sjfv	u32 vector = 0;
250215911Sjfv
251215911Sjfv	switch (hw->mac.mc_filter_type) {
252215911Sjfv	case 0:   /* use bits [47:36] of the address */
253215911Sjfv		vector = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4));
254215911Sjfv		break;
255215911Sjfv	case 1:   /* use bits [46:35] of the address */
256215911Sjfv		vector = ((mc_addr[4] >> 3) | (((u16)mc_addr[5]) << 5));
257215911Sjfv		break;
258215911Sjfv	case 2:   /* use bits [45:34] of the address */
259215911Sjfv		vector = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6));
260215911Sjfv		break;
261215911Sjfv	case 3:   /* use bits [43:32] of the address */
262215911Sjfv		vector = ((mc_addr[4]) | (((u16)mc_addr[5]) << 8));
263215911Sjfv		break;
264215911Sjfv	default:  /* Invalid mc_filter_type */
265215911Sjfv		DEBUGOUT("MC filter type param set incorrectly\n");
266215911Sjfv		ASSERT(0);
267215911Sjfv		break;
268215911Sjfv	}
269215911Sjfv
270215911Sjfv	/* vector can only be 12-bits or boundary will be exceeded */
271215911Sjfv	vector &= 0xFFF;
272215911Sjfv	return vector;
273215911Sjfv}
274215911Sjfv
275247822Sjfvstatic void ixgbevf_write_msg_read_ack(struct ixgbe_hw *hw,
276247822Sjfv					u32 *msg, u16 size)
277247822Sjfv{
278247822Sjfv	struct ixgbe_mbx_info *mbx = &hw->mbx;
279247822Sjfv	u32 retmsg[IXGBE_VFMAILBOX_SIZE];
280247822Sjfv	s32 retval = mbx->ops.write_posted(hw, msg, size, 0);
281247822Sjfv
282247822Sjfv	if (!retval)
283247822Sjfv		mbx->ops.read_posted(hw, retmsg, size, 0);
284247822Sjfv}
285247822Sjfv
286215911Sjfv/**
287215911Sjfv *  ixgbe_set_rar_vf - set device MAC address
288215911Sjfv *  @hw: pointer to hardware structure
289215911Sjfv *  @index: Receive address register to write
290215911Sjfv *  @addr: Address to put into receive address register
291215911Sjfv *  @vmdq: VMDq "set" or "pool" index
292215911Sjfv *  @enable_addr: set flag that address is active
293215911Sjfv **/
294215911Sjfvs32 ixgbe_set_rar_vf(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
295230775Sjfv		     u32 enable_addr)
296215911Sjfv{
297215911Sjfv	struct ixgbe_mbx_info *mbx = &hw->mbx;
298215911Sjfv	u32 msgbuf[3];
299215911Sjfv	u8 *msg_addr = (u8 *)(&msgbuf[1]);
300215911Sjfv	s32 ret_val;
301230775Sjfv	UNREFERENCED_3PARAMETER(vmdq, enable_addr, index);
302215911Sjfv
303215911Sjfv	memset(msgbuf, 0, 12);
304215911Sjfv	msgbuf[0] = IXGBE_VF_SET_MAC_ADDR;
305215911Sjfv	memcpy(msg_addr, addr, 6);
306215911Sjfv	ret_val = mbx->ops.write_posted(hw, msgbuf, 3, 0);
307215911Sjfv
308215911Sjfv	if (!ret_val)
309215911Sjfv		ret_val = mbx->ops.read_posted(hw, msgbuf, 3, 0);
310215911Sjfv
311215911Sjfv	msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS;
312215911Sjfv
313215911Sjfv	/* if nacked the address was rejected, use "perm_addr" */
314215911Sjfv	if (!ret_val &&
315215911Sjfv	    (msgbuf[0] == (IXGBE_VF_SET_MAC_ADDR | IXGBE_VT_MSGTYPE_NACK)))
316215911Sjfv		ixgbe_get_mac_addr_vf(hw, hw->mac.addr);
317215911Sjfv
318215911Sjfv	return ret_val;
319215911Sjfv}
320215911Sjfv
321215911Sjfv/**
322215911Sjfv *  ixgbe_update_mc_addr_list_vf - Update Multicast addresses
323215911Sjfv *  @hw: pointer to the HW structure
324215911Sjfv *  @mc_addr_list: array of multicast addresses to program
325215911Sjfv *  @mc_addr_count: number of multicast addresses to program
326215911Sjfv *  @next: caller supplied function to return next address in list
327215911Sjfv *
328215911Sjfv *  Updates the Multicast Table Array.
329215911Sjfv **/
330215911Sjfvs32 ixgbe_update_mc_addr_list_vf(struct ixgbe_hw *hw, u8 *mc_addr_list,
331230775Sjfv				 u32 mc_addr_count, ixgbe_mc_addr_itr next,
332230775Sjfv				 bool clear)
333215911Sjfv{
334215911Sjfv	struct ixgbe_mbx_info *mbx = &hw->mbx;
335215911Sjfv	u32 msgbuf[IXGBE_VFMAILBOX_SIZE];
336215911Sjfv	u16 *vector_list = (u16 *)&msgbuf[1];
337215911Sjfv	u32 vector;
338215911Sjfv	u32 cnt, i;
339215911Sjfv	u32 vmdq;
340215911Sjfv
341230775Sjfv	UNREFERENCED_1PARAMETER(clear);
342230775Sjfv
343215911Sjfv	DEBUGFUNC("ixgbe_update_mc_addr_list_vf");
344215911Sjfv
345215911Sjfv	/* Each entry in the list uses 1 16 bit word.  We have 30
346215911Sjfv	 * 16 bit words available in our HW msg buffer (minus 1 for the
347215911Sjfv	 * msg type).  That's 30 hash values if we pack 'em right.  If
348215911Sjfv	 * there are more than 30 MC addresses to add then punt the
349215911Sjfv	 * extras for now and then add code to handle more than 30 later.
350215911Sjfv	 * It would be unusual for a server to request that many multi-cast
351215911Sjfv	 * addresses except for in large enterprise network environments.
352215911Sjfv	 */
353215911Sjfv
354215911Sjfv	DEBUGOUT1("MC Addr Count = %d\n", mc_addr_count);
355215911Sjfv
356215911Sjfv	cnt = (mc_addr_count > 30) ? 30 : mc_addr_count;
357215911Sjfv	msgbuf[0] = IXGBE_VF_SET_MULTICAST;
358215911Sjfv	msgbuf[0] |= cnt << IXGBE_VT_MSGINFO_SHIFT;
359215911Sjfv
360215911Sjfv	for (i = 0; i < cnt; i++) {
361215911Sjfv		vector = ixgbe_mta_vector(hw, next(hw, &mc_addr_list, &vmdq));
362215911Sjfv		DEBUGOUT1("Hash value = 0x%03X\n", vector);
363215911Sjfv		vector_list[i] = (u16)vector;
364215911Sjfv	}
365215911Sjfv
366215911Sjfv	return mbx->ops.write_posted(hw, msgbuf, IXGBE_VFMAILBOX_SIZE, 0);
367215911Sjfv}
368215911Sjfv
369215911Sjfv/**
370215911Sjfv *  ixgbe_set_vfta_vf - Set/Unset vlan filter table address
371215911Sjfv *  @hw: pointer to the HW structure
372215911Sjfv *  @vlan: 12 bit VLAN ID
373215911Sjfv *  @vind: unused by VF drivers
374215911Sjfv *  @vlan_on: if TRUE then set bit, else clear bit
375215911Sjfv **/
376215911Sjfvs32 ixgbe_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on)
377215911Sjfv{
378215911Sjfv	struct ixgbe_mbx_info *mbx = &hw->mbx;
379215911Sjfv	u32 msgbuf[2];
380238149Sjfv	s32 ret_val;
381230775Sjfv	UNREFERENCED_1PARAMETER(vind);
382215911Sjfv
383215911Sjfv	msgbuf[0] = IXGBE_VF_SET_VLAN;
384215911Sjfv	msgbuf[1] = vlan;
385215911Sjfv	/* Setting the 8 bit field MSG INFO to TRUE indicates "add" */
386215911Sjfv	msgbuf[0] |= vlan_on << IXGBE_VT_MSGINFO_SHIFT;
387215911Sjfv
388238149Sjfv	ret_val = mbx->ops.write_posted(hw, msgbuf, 2, 0);
389238149Sjfv	if (!ret_val)
390238149Sjfv		ret_val = mbx->ops.read_posted(hw, msgbuf, 1, 0);
391238149Sjfv
392238149Sjfv	if (!ret_val && (msgbuf[0] & IXGBE_VT_MSGTYPE_ACK))
393238149Sjfv		return IXGBE_SUCCESS;
394238149Sjfv
395238149Sjfv	return ret_val | (msgbuf[0] & IXGBE_VT_MSGTYPE_NACK);
396215911Sjfv}
397215911Sjfv
398215911Sjfv/**
399215911Sjfv *  ixgbe_get_num_of_tx_queues_vf - Get number of TX queues
400215911Sjfv *  @hw: pointer to hardware structure
401215911Sjfv *
402215911Sjfv *  Returns the number of transmit queues for the given adapter.
403215911Sjfv **/
404215911Sjfvu32 ixgbe_get_num_of_tx_queues_vf(struct ixgbe_hw *hw)
405215911Sjfv{
406230775Sjfv	UNREFERENCED_1PARAMETER(hw);
407215911Sjfv	return IXGBE_VF_MAX_TX_QUEUES;
408215911Sjfv}
409215911Sjfv
410215911Sjfv/**
411215911Sjfv *  ixgbe_get_num_of_rx_queues_vf - Get number of RX queues
412215911Sjfv *  @hw: pointer to hardware structure
413215911Sjfv *
414215911Sjfv *  Returns the number of receive queues for the given adapter.
415215911Sjfv **/
416215911Sjfvu32 ixgbe_get_num_of_rx_queues_vf(struct ixgbe_hw *hw)
417215911Sjfv{
418230775Sjfv	UNREFERENCED_1PARAMETER(hw);
419215911Sjfv	return IXGBE_VF_MAX_RX_QUEUES;
420215911Sjfv}
421215911Sjfv
422215911Sjfv/**
423215911Sjfv *  ixgbe_get_mac_addr_vf - Read device MAC address
424215911Sjfv *  @hw: pointer to the HW structure
425215911Sjfv **/
426215911Sjfvs32 ixgbe_get_mac_addr_vf(struct ixgbe_hw *hw, u8 *mac_addr)
427215911Sjfv{
428215911Sjfv	int i;
429215911Sjfv
430215911Sjfv	for (i = 0; i < IXGBE_ETH_LENGTH_OF_ADDRESS; i++)
431215911Sjfv		mac_addr[i] = hw->mac.perm_addr[i];
432215911Sjfv
433215911Sjfv	return IXGBE_SUCCESS;
434215911Sjfv}
435215911Sjfv
436230775Sjfvs32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr)
437230775Sjfv{
438230775Sjfv	struct ixgbe_mbx_info *mbx = &hw->mbx;
439230775Sjfv	u32 msgbuf[3];
440230775Sjfv	u8 *msg_addr = (u8 *)(&msgbuf[1]);
441230775Sjfv	s32 ret_val;
442230775Sjfv
443230775Sjfv	memset(msgbuf, 0, sizeof(msgbuf));
444230775Sjfv	/*
445230775Sjfv	 * If index is one then this is the start of a new list and needs
446230775Sjfv	 * indication to the PF so it can do it's own list management.
447230775Sjfv	 * If it is zero then that tells the PF to just clear all of
448230775Sjfv	 * this VF's macvlans and there is no new list.
449230775Sjfv	 */
450230775Sjfv	msgbuf[0] |= index << IXGBE_VT_MSGINFO_SHIFT;
451230775Sjfv	msgbuf[0] |= IXGBE_VF_SET_MACVLAN;
452230775Sjfv	if (addr)
453230775Sjfv		memcpy(msg_addr, addr, 6);
454230775Sjfv	ret_val = mbx->ops.write_posted(hw, msgbuf, 3, 0);
455230775Sjfv
456230775Sjfv	if (!ret_val)
457230775Sjfv		ret_val = mbx->ops.read_posted(hw, msgbuf, 3, 0);
458230775Sjfv
459230775Sjfv	msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS;
460230775Sjfv
461230775Sjfv	if (!ret_val)
462230775Sjfv		if (msgbuf[0] == (IXGBE_VF_SET_MACVLAN | IXGBE_VT_MSGTYPE_NACK))
463230775Sjfv			ret_val = IXGBE_ERR_OUT_OF_MEM;
464230775Sjfv
465230775Sjfv	return ret_val;
466230775Sjfv}
467230775Sjfv
468215911Sjfv/**
469215911Sjfv *  ixgbe_setup_mac_link_vf - Setup MAC link settings
470215911Sjfv *  @hw: pointer to hardware structure
471215911Sjfv *  @speed: new link speed
472215911Sjfv *  @autoneg: TRUE if autonegotiation enabled
473215911Sjfv *  @autoneg_wait_to_complete: TRUE when waiting for completion is needed
474215911Sjfv *
475215911Sjfv *  Set the link speed in the AUTOC register and restarts link.
476215911Sjfv **/
477247822Sjfvs32 ixgbe_setup_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed speed,
478230775Sjfv			    bool autoneg_wait_to_complete)
479215911Sjfv{
480247822Sjfv	UNREFERENCED_3PARAMETER(hw, speed, autoneg_wait_to_complete);
481215911Sjfv	return IXGBE_SUCCESS;
482215911Sjfv}
483215911Sjfv
484215911Sjfv/**
485215911Sjfv *  ixgbe_check_mac_link_vf - Get link/speed status
486215911Sjfv *  @hw: pointer to hardware structure
487215911Sjfv *  @speed: pointer to link speed
488215911Sjfv *  @link_up: TRUE is link is up, FALSE otherwise
489215911Sjfv *  @autoneg_wait_to_complete: TRUE when waiting for completion is needed
490215911Sjfv *
491215911Sjfv *  Reads the links register to determine if link is up and the current speed
492215911Sjfv **/
493215911Sjfvs32 ixgbe_check_mac_link_vf(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
494230775Sjfv			    bool *link_up, bool autoneg_wait_to_complete)
495215911Sjfv{
496247822Sjfv	struct ixgbe_mbx_info *mbx = &hw->mbx;
497247822Sjfv	struct ixgbe_mac_info *mac = &hw->mac;
498247822Sjfv	s32 ret_val = IXGBE_SUCCESS;
499215911Sjfv	u32 links_reg;
500247822Sjfv	u32 in_msg = 0;
501230775Sjfv	UNREFERENCED_1PARAMETER(autoneg_wait_to_complete);
502215911Sjfv
503247822Sjfv	/* If we were hit with a reset drop the link */
504247822Sjfv	if (!mbx->ops.check_for_rst(hw, 0) || !mbx->timeout)
505247822Sjfv		mac->get_link_status = TRUE;
506215911Sjfv
507247822Sjfv	if (!mac->get_link_status)
508247822Sjfv		goto out;
509215911Sjfv
510247822Sjfv	/* if link status is down no point in checking to see if pf is up */
511247822Sjfv	links_reg = IXGBE_READ_REG(hw, IXGBE_VFLINKS);
512247822Sjfv	if (!(links_reg & IXGBE_LINKS_UP))
513247822Sjfv		goto out;
514215911Sjfv
515247822Sjfv	switch (links_reg & IXGBE_LINKS_SPEED_82599) {
516238149Sjfv	case IXGBE_LINKS_SPEED_10G_82599:
517215911Sjfv		*speed = IXGBE_LINK_SPEED_10GB_FULL;
518238149Sjfv		break;
519238149Sjfv	case IXGBE_LINKS_SPEED_1G_82599:
520215911Sjfv		*speed = IXGBE_LINK_SPEED_1GB_FULL;
521238149Sjfv		break;
522238149Sjfv	case IXGBE_LINKS_SPEED_100_82599:
523238149Sjfv		*speed = IXGBE_LINK_SPEED_100_FULL;
524238149Sjfv		break;
525238149Sjfv	}
526215911Sjfv
527247822Sjfv	/* if the read failed it could just be a mailbox collision, best wait
528247822Sjfv	 * until we are called again and don't report an error
529247822Sjfv	 */
530247822Sjfv	if (mbx->ops.read(hw, &in_msg, 1, 0))
531247822Sjfv		goto out;
532247822Sjfv
533247822Sjfv	if (!(in_msg & IXGBE_VT_MSGTYPE_CTS)) {
534247822Sjfv		/* msg is not CTS and is NACK we must have lost CTS status */
535247822Sjfv		if (in_msg & IXGBE_VT_MSGTYPE_NACK)
536247822Sjfv			ret_val = -1;
537247822Sjfv		goto out;
538247822Sjfv	}
539247822Sjfv
540247822Sjfv	/* the pf is talking, if we timed out in the past we reinit */
541247822Sjfv	if (!mbx->timeout) {
542247822Sjfv		ret_val = -1;
543247822Sjfv		goto out;
544247822Sjfv	}
545247822Sjfv
546247822Sjfv	/* if we passed all the tests above then the link is up and we no
547247822Sjfv	 * longer need to check for link
548247822Sjfv	 */
549247822Sjfv	mac->get_link_status = FALSE;
550247822Sjfv
551247822Sjfvout:
552247822Sjfv	*link_up = !mac->get_link_status;
553247822Sjfv	return ret_val;
554247822Sjfv}
555247822Sjfv
556247822Sjfv/**
557247822Sjfv *  ixgbevf_rlpml_set_vf - Set the maximum receive packet length
558247822Sjfv *  @hw: pointer to the HW structure
559247822Sjfv *  @max_size: value to assign to max frame size
560247822Sjfv **/
561247822Sjfvvoid ixgbevf_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size)
562247822Sjfv{
563247822Sjfv	u32 msgbuf[2];
564247822Sjfv
565247822Sjfv	msgbuf[0] = IXGBE_VF_SET_LPE;
566247822Sjfv	msgbuf[1] = max_size;
567247822Sjfv	ixgbevf_write_msg_read_ack(hw, msgbuf, 2);
568247822Sjfv}
569247822Sjfv
570247822Sjfv/**
571247822Sjfv *  ixgbevf_negotiate_api_version - Negotiate supported API version
572247822Sjfv *  @hw: pointer to the HW structure
573247822Sjfv *  @api: integer containing requested API version
574247822Sjfv **/
575247822Sjfvint ixgbevf_negotiate_api_version(struct ixgbe_hw *hw, int api)
576247822Sjfv{
577247822Sjfv	int err;
578247822Sjfv	u32 msg[3];
579247822Sjfv
580247822Sjfv	/* Negotiate the mailbox API version */
581247822Sjfv	msg[0] = IXGBE_VF_API_NEGOTIATE;
582247822Sjfv	msg[1] = api;
583247822Sjfv	msg[2] = 0;
584247822Sjfv	err = hw->mbx.ops.write_posted(hw, msg, 3, 0);
585247822Sjfv
586247822Sjfv	if (!err)
587247822Sjfv		err = hw->mbx.ops.read_posted(hw, msg, 3, 0);
588247822Sjfv
589247822Sjfv	if (!err) {
590247822Sjfv		msg[0] &= ~IXGBE_VT_MSGTYPE_CTS;
591247822Sjfv
592247822Sjfv		/* Store value and return 0 on success */
593247822Sjfv		if (msg[0] == (IXGBE_VF_API_NEGOTIATE | IXGBE_VT_MSGTYPE_ACK)) {
594247822Sjfv			hw->api_version = api;
595247822Sjfv			return 0;
596247822Sjfv		}
597247822Sjfv
598247822Sjfv		err = IXGBE_ERR_INVALID_ARGUMENT;
599247822Sjfv	}
600247822Sjfv
601247822Sjfv	return err;
602247822Sjfv}
603247822Sjfv
604247822Sjfvint ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs,
605247822Sjfv		       unsigned int *default_tc)
606247822Sjfv{
607247822Sjfv	UNREFERENCED_3PARAMETER(hw, num_tcs, default_tc);
608215911Sjfv	return IXGBE_SUCCESS;
609215911Sjfv}
610215911Sjfv
611