xref: /freebsd/sys/dev/e1000/e1000_vf.c (revision 71625ec9)
1b8270585SJack F Vogel /******************************************************************************
27282444bSPedro F. Giffuni   SPDX-License-Identifier: BSD-3-Clause
3b8270585SJack F Vogel 
4702cac6cSKevin Bowling   Copyright (c) 2001-2020, Intel Corporation
5b8270585SJack F Vogel   All rights reserved.
6b8270585SJack F Vogel 
7b8270585SJack F Vogel   Redistribution and use in source and binary forms, with or without
8b8270585SJack F Vogel   modification, are permitted provided that the following conditions are met:
9b8270585SJack F Vogel 
10b8270585SJack F Vogel    1. Redistributions of source code must retain the above copyright notice,
11b8270585SJack F Vogel       this list of conditions and the following disclaimer.
12b8270585SJack F Vogel 
13b8270585SJack F Vogel    2. Redistributions in binary form must reproduce the above copyright
14b8270585SJack F Vogel       notice, this list of conditions and the following disclaimer in the
15b8270585SJack F Vogel       documentation and/or other materials provided with the distribution.
16b8270585SJack F Vogel 
17b8270585SJack F Vogel    3. Neither the name of the Intel Corporation nor the names of its
18b8270585SJack F Vogel       contributors may be used to endorse or promote products derived from
19b8270585SJack F Vogel       this software without specific prior written permission.
20b8270585SJack F Vogel 
21b8270585SJack F Vogel   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22b8270585SJack F Vogel   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23b8270585SJack F Vogel   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24b8270585SJack F Vogel   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25b8270585SJack F Vogel   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26b8270585SJack F Vogel   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27b8270585SJack F Vogel   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28b8270585SJack F Vogel   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29b8270585SJack F Vogel   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30b8270585SJack F Vogel   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31b8270585SJack F Vogel   POSSIBILITY OF SUCH DAMAGE.
32b8270585SJack F Vogel 
33b8270585SJack F Vogel ******************************************************************************/
34b8270585SJack F Vogel 
35b8270585SJack F Vogel 
36b8270585SJack F Vogel #include "e1000_api.h"
37b8270585SJack F Vogel 
38b8270585SJack F Vogel 
39b8270585SJack F Vogel static s32 e1000_init_phy_params_vf(struct e1000_hw *hw);
40b8270585SJack F Vogel static s32 e1000_init_nvm_params_vf(struct e1000_hw *hw);
41b8270585SJack F Vogel static void e1000_release_vf(struct e1000_hw *hw);
42b8270585SJack F Vogel static s32 e1000_acquire_vf(struct e1000_hw *hw);
43b8270585SJack F Vogel static s32 e1000_setup_link_vf(struct e1000_hw *hw);
44b8270585SJack F Vogel static s32 e1000_get_bus_info_pcie_vf(struct e1000_hw *hw);
45b8270585SJack F Vogel static s32 e1000_init_mac_params_vf(struct e1000_hw *hw);
46b8270585SJack F Vogel static s32 e1000_check_for_link_vf(struct e1000_hw *hw);
47b8270585SJack F Vogel static s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed,
48b8270585SJack F Vogel 				     u16 *duplex);
49b8270585SJack F Vogel static s32 e1000_init_hw_vf(struct e1000_hw *hw);
50b8270585SJack F Vogel static s32 e1000_reset_hw_vf(struct e1000_hw *hw);
51b8270585SJack F Vogel static void e1000_update_mc_addr_list_vf(struct e1000_hw *hw, u8 *, u32);
528cc64f1eSJack F Vogel static int  e1000_rar_set_vf(struct e1000_hw *, u8 *, u32);
53b8270585SJack F Vogel static s32 e1000_read_mac_addr_vf(struct e1000_hw *);
54b8270585SJack F Vogel 
55b8270585SJack F Vogel /**
56b8270585SJack F Vogel  *  e1000_init_phy_params_vf - Inits PHY params
57b8270585SJack F Vogel  *  @hw: pointer to the HW structure
58b8270585SJack F Vogel  *
59b8270585SJack F Vogel  *  Doesn't do much - there's no PHY available to the VF.
60b8270585SJack F Vogel  **/
e1000_init_phy_params_vf(struct e1000_hw * hw)61b8270585SJack F Vogel static s32 e1000_init_phy_params_vf(struct e1000_hw *hw)
62b8270585SJack F Vogel {
63b8270585SJack F Vogel 	DEBUGFUNC("e1000_init_phy_params_vf");
64b8270585SJack F Vogel 	hw->phy.type = e1000_phy_vf;
65b8270585SJack F Vogel 	hw->phy.ops.acquire = e1000_acquire_vf;
66b8270585SJack F Vogel 	hw->phy.ops.release = e1000_release_vf;
67b8270585SJack F Vogel 
68b8270585SJack F Vogel 	return E1000_SUCCESS;
69b8270585SJack F Vogel }
70b8270585SJack F Vogel 
71b8270585SJack F Vogel /**
72b8270585SJack F Vogel  *  e1000_init_nvm_params_vf - Inits NVM params
73b8270585SJack F Vogel  *  @hw: pointer to the HW structure
74b8270585SJack F Vogel  *
75b8270585SJack F Vogel  *  Doesn't do much - there's no NVM available to the VF.
76b8270585SJack F Vogel  **/
e1000_init_nvm_params_vf(struct e1000_hw * hw)77b8270585SJack F Vogel static s32 e1000_init_nvm_params_vf(struct e1000_hw *hw)
78b8270585SJack F Vogel {
79b8270585SJack F Vogel 	DEBUGFUNC("e1000_init_nvm_params_vf");
80b8270585SJack F Vogel 	hw->nvm.type = e1000_nvm_none;
81b8270585SJack F Vogel 	hw->nvm.ops.acquire = e1000_acquire_vf;
82b8270585SJack F Vogel 	hw->nvm.ops.release = e1000_release_vf;
83b8270585SJack F Vogel 
84b8270585SJack F Vogel 	return E1000_SUCCESS;
85b8270585SJack F Vogel }
86b8270585SJack F Vogel 
87b8270585SJack F Vogel /**
88b8270585SJack F Vogel  *  e1000_init_mac_params_vf - Inits MAC params
89b8270585SJack F Vogel  *  @hw: pointer to the HW structure
90b8270585SJack F Vogel  **/
e1000_init_mac_params_vf(struct e1000_hw * hw)91b8270585SJack F Vogel static s32 e1000_init_mac_params_vf(struct e1000_hw *hw)
92b8270585SJack F Vogel {
93b8270585SJack F Vogel 	struct e1000_mac_info *mac = &hw->mac;
94b8270585SJack F Vogel 
95b8270585SJack F Vogel 	DEBUGFUNC("e1000_init_mac_params_vf");
96b8270585SJack F Vogel 
97b8270585SJack F Vogel 	/* Set media type */
98b8270585SJack F Vogel 	/*
99b8270585SJack F Vogel 	 * Virtual functions don't care what they're media type is as they
100b8270585SJack F Vogel 	 * have no direct access to the PHY, or the media.  That is handled
101b8270585SJack F Vogel 	 * by the physical function driver.
102b8270585SJack F Vogel 	 */
103b8270585SJack F Vogel 	hw->phy.media_type = e1000_media_type_unknown;
104b8270585SJack F Vogel 
105b8270585SJack F Vogel 	/* No ASF features for the VF driver */
1061bbdc25fSKevin Bowling 	mac->asf_firmware_present = false;
107b8270585SJack F Vogel 	/* ARC subsystem not supported */
1081bbdc25fSKevin Bowling 	mac->arc_subsystem_valid = false;
109b8270585SJack F Vogel 	/* Disable adaptive IFS mode so the generic funcs don't do anything */
1101bbdc25fSKevin Bowling 	mac->adaptive_ifs = false;
111b8270585SJack F Vogel 	/* VF's have no MTA Registers - PF feature only */
112b8270585SJack F Vogel 	mac->mta_reg_count = 128;
113b8270585SJack F Vogel 	/* VF's have no access to RAR entries  */
114b8270585SJack F Vogel 	mac->rar_entry_count = 1;
115b8270585SJack F Vogel 
116b8270585SJack F Vogel 	/* Function pointers */
117b8270585SJack F Vogel 	/* link setup */
118b8270585SJack F Vogel 	mac->ops.setup_link = e1000_setup_link_vf;
119b8270585SJack F Vogel 	/* bus type/speed/width */
120b8270585SJack F Vogel 	mac->ops.get_bus_info = e1000_get_bus_info_pcie_vf;
121b8270585SJack F Vogel 	/* reset */
122b8270585SJack F Vogel 	mac->ops.reset_hw = e1000_reset_hw_vf;
123b8270585SJack F Vogel 	/* hw initialization */
124b8270585SJack F Vogel 	mac->ops.init_hw = e1000_init_hw_vf;
125b8270585SJack F Vogel 	/* check for link */
126b8270585SJack F Vogel 	mac->ops.check_for_link = e1000_check_for_link_vf;
127b8270585SJack F Vogel 	/* link info */
128b8270585SJack F Vogel 	mac->ops.get_link_up_info = e1000_get_link_up_info_vf;
129b8270585SJack F Vogel 	/* multicast address update */
130b8270585SJack F Vogel 	mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_vf;
131b8270585SJack F Vogel 	/* set mac address */
132b8270585SJack F Vogel 	mac->ops.rar_set = e1000_rar_set_vf;
133b8270585SJack F Vogel 	/* read mac address */
134b8270585SJack F Vogel 	mac->ops.read_mac_addr = e1000_read_mac_addr_vf;
135b8270585SJack F Vogel 
136b8270585SJack F Vogel 
137b8270585SJack F Vogel 	return E1000_SUCCESS;
138b8270585SJack F Vogel }
139b8270585SJack F Vogel 
140b8270585SJack F Vogel /**
141b8270585SJack F Vogel  *  e1000_init_function_pointers_vf - Inits function pointers
142b8270585SJack F Vogel  *  @hw: pointer to the HW structure
143b8270585SJack F Vogel  **/
e1000_init_function_pointers_vf(struct e1000_hw * hw)144b8270585SJack F Vogel void e1000_init_function_pointers_vf(struct e1000_hw *hw)
145b8270585SJack F Vogel {
146b8270585SJack F Vogel 	DEBUGFUNC("e1000_init_function_pointers_vf");
147b8270585SJack F Vogel 
148b8270585SJack F Vogel 	hw->mac.ops.init_params = e1000_init_mac_params_vf;
149b8270585SJack F Vogel 	hw->nvm.ops.init_params = e1000_init_nvm_params_vf;
150b8270585SJack F Vogel 	hw->phy.ops.init_params = e1000_init_phy_params_vf;
151b8270585SJack F Vogel 	hw->mbx.ops.init_params = e1000_init_mbx_params_vf;
152b8270585SJack F Vogel }
153b8270585SJack F Vogel 
154b8270585SJack F Vogel /**
155b8270585SJack F Vogel  *  e1000_acquire_vf - Acquire rights to access PHY or NVM.
156b8270585SJack F Vogel  *  @hw: pointer to the HW structure
157b8270585SJack F Vogel  *
158b8270585SJack F Vogel  *  There is no PHY or NVM so we want all attempts to acquire these to fail.
159b8270585SJack F Vogel  *  In addition, the MAC registers to access PHY/NVM don't exist so we don't
160b8270585SJack F Vogel  *  even want any SW to attempt to use them.
161b8270585SJack F Vogel  **/
e1000_acquire_vf(struct e1000_hw E1000_UNUSEDARG * hw)1628cc64f1eSJack F Vogel static s32 e1000_acquire_vf(struct e1000_hw E1000_UNUSEDARG *hw)
163b8270585SJack F Vogel {
164b8270585SJack F Vogel 	return -E1000_ERR_PHY;
165b8270585SJack F Vogel }
166b8270585SJack F Vogel 
167b8270585SJack F Vogel /**
168b8270585SJack F Vogel  *  e1000_release_vf - Release PHY or NVM
169b8270585SJack F Vogel  *  @hw: pointer to the HW structure
170b8270585SJack F Vogel  *
171b8270585SJack F Vogel  *  There is no PHY or NVM so we want all attempts to acquire these to fail.
172b8270585SJack F Vogel  *  In addition, the MAC registers to access PHY/NVM don't exist so we don't
173b8270585SJack F Vogel  *  even want any SW to attempt to use them.
174b8270585SJack F Vogel  **/
e1000_release_vf(struct e1000_hw E1000_UNUSEDARG * hw)1758cc64f1eSJack F Vogel static void e1000_release_vf(struct e1000_hw E1000_UNUSEDARG *hw)
176b8270585SJack F Vogel {
177b8270585SJack F Vogel 	return;
178b8270585SJack F Vogel }
179b8270585SJack F Vogel 
180b8270585SJack F Vogel /**
181b8270585SJack F Vogel  *  e1000_setup_link_vf - Sets up link.
182b8270585SJack F Vogel  *  @hw: pointer to the HW structure
183b8270585SJack F Vogel  *
184b8270585SJack F Vogel  *  Virtual functions cannot change link.
185b8270585SJack F Vogel  **/
e1000_setup_link_vf(struct e1000_hw E1000_UNUSEDARG * hw)1868cc64f1eSJack F Vogel static s32 e1000_setup_link_vf(struct e1000_hw E1000_UNUSEDARG *hw)
187b8270585SJack F Vogel {
188b8270585SJack F Vogel 	DEBUGFUNC("e1000_setup_link_vf");
189b8270585SJack F Vogel 
190b8270585SJack F Vogel 	return E1000_SUCCESS;
191b8270585SJack F Vogel }
192b8270585SJack F Vogel 
193b8270585SJack F Vogel /**
194b8270585SJack F Vogel  *  e1000_get_bus_info_pcie_vf - Gets the bus info.
195b8270585SJack F Vogel  *  @hw: pointer to the HW structure
196b8270585SJack F Vogel  *
197b8270585SJack F Vogel  *  Virtual functions are not really on their own bus.
198b8270585SJack F Vogel  **/
e1000_get_bus_info_pcie_vf(struct e1000_hw * hw)199b8270585SJack F Vogel static s32 e1000_get_bus_info_pcie_vf(struct e1000_hw *hw)
200b8270585SJack F Vogel {
201b8270585SJack F Vogel 	struct e1000_bus_info *bus = &hw->bus;
202b8270585SJack F Vogel 
203b8270585SJack F Vogel 	DEBUGFUNC("e1000_get_bus_info_pcie_vf");
204b8270585SJack F Vogel 
205b8270585SJack F Vogel 	/* Do not set type PCI-E because we don't want disable master to run */
206b8270585SJack F Vogel 	bus->type = e1000_bus_type_reserved;
207b8270585SJack F Vogel 	bus->speed = e1000_bus_speed_2500;
208b8270585SJack F Vogel 
209b8270585SJack F Vogel 	return 0;
210b8270585SJack F Vogel }
211b8270585SJack F Vogel 
212b8270585SJack F Vogel /**
213b8270585SJack F Vogel  *  e1000_get_link_up_info_vf - Gets link info.
214b8270585SJack F Vogel  *  @hw: pointer to the HW structure
215b8270585SJack F Vogel  *  @speed: pointer to 16 bit value to store link speed.
216b8270585SJack F Vogel  *  @duplex: pointer to 16 bit value to store duplex.
217b8270585SJack F Vogel  *
218b8270585SJack F Vogel  *  Since we cannot read the PHY and get accurate link info, we must rely upon
219b8270585SJack F Vogel  *  the status register's data which is often stale and inaccurate.
220b8270585SJack F Vogel  **/
e1000_get_link_up_info_vf(struct e1000_hw * hw,u16 * speed,u16 * duplex)221b8270585SJack F Vogel static s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed,
222b8270585SJack F Vogel 				     u16 *duplex)
223b8270585SJack F Vogel {
224b8270585SJack F Vogel 	s32 status;
225b8270585SJack F Vogel 
226b8270585SJack F Vogel 	DEBUGFUNC("e1000_get_link_up_info_vf");
227b8270585SJack F Vogel 
228b8270585SJack F Vogel 	status = E1000_READ_REG(hw, E1000_STATUS);
229b8270585SJack F Vogel 	if (status & E1000_STATUS_SPEED_1000) {
230b8270585SJack F Vogel 		*speed = SPEED_1000;
231b8270585SJack F Vogel 		DEBUGOUT("1000 Mbs, ");
232b8270585SJack F Vogel 	} else if (status & E1000_STATUS_SPEED_100) {
233b8270585SJack F Vogel 		*speed = SPEED_100;
234b8270585SJack F Vogel 		DEBUGOUT("100 Mbs, ");
235b8270585SJack F Vogel 	} else {
236b8270585SJack F Vogel 		*speed = SPEED_10;
237b8270585SJack F Vogel 		DEBUGOUT("10 Mbs, ");
238b8270585SJack F Vogel 	}
239b8270585SJack F Vogel 
240b8270585SJack F Vogel 	if (status & E1000_STATUS_FD) {
241b8270585SJack F Vogel 		*duplex = FULL_DUPLEX;
242b8270585SJack F Vogel 		DEBUGOUT("Full Duplex\n");
243b8270585SJack F Vogel 	} else {
244b8270585SJack F Vogel 		*duplex = HALF_DUPLEX;
245b8270585SJack F Vogel 		DEBUGOUT("Half Duplex\n");
246b8270585SJack F Vogel 	}
247b8270585SJack F Vogel 
248b8270585SJack F Vogel 	return E1000_SUCCESS;
249b8270585SJack F Vogel }
250b8270585SJack F Vogel 
251b8270585SJack F Vogel /**
252b8270585SJack F Vogel  *  e1000_reset_hw_vf - Resets the HW
253b8270585SJack F Vogel  *  @hw: pointer to the HW structure
254b8270585SJack F Vogel  *
255b8270585SJack F Vogel  *  VF's provide a function level reset. This is done using bit 26 of ctrl_reg.
256b8270585SJack F Vogel  *  This is all the reset we can perform on a VF.
257b8270585SJack F Vogel  **/
e1000_reset_hw_vf(struct e1000_hw * hw)258b8270585SJack F Vogel static s32 e1000_reset_hw_vf(struct e1000_hw *hw)
259b8270585SJack F Vogel {
260b8270585SJack F Vogel 	struct e1000_mbx_info *mbx = &hw->mbx;
261b8270585SJack F Vogel 	u32 timeout = E1000_VF_INIT_TIMEOUT;
262b8270585SJack F Vogel 	s32 ret_val = -E1000_ERR_MAC_INIT;
263b8270585SJack F Vogel 	u32 ctrl, msgbuf[3];
264b8270585SJack F Vogel 	u8 *addr = (u8 *)(&msgbuf[1]);
265b8270585SJack F Vogel 
266b8270585SJack F Vogel 	DEBUGFUNC("e1000_reset_hw_vf");
267b8270585SJack F Vogel 
268b8270585SJack F Vogel 	DEBUGOUT("Issuing a function level reset to MAC\n");
269b8270585SJack F Vogel 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
270b8270585SJack F Vogel 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);
271b8270585SJack F Vogel 
272b8270585SJack F Vogel 	/* we cannot reset while the RSTI / RSTD bits are asserted */
273b8270585SJack F Vogel 	while (!mbx->ops.check_for_rst(hw, 0) && timeout) {
274b8270585SJack F Vogel 		timeout--;
275b8270585SJack F Vogel 		usec_delay(5);
276b8270585SJack F Vogel 	}
277b8270585SJack F Vogel 
278b8270585SJack F Vogel 	if (timeout) {
279b8270585SJack F Vogel 		/* mailbox timeout can now become active */
280b8270585SJack F Vogel 		mbx->timeout = E1000_VF_MBX_INIT_TIMEOUT;
281b8270585SJack F Vogel 
282b8270585SJack F Vogel 		msgbuf[0] = E1000_VF_RESET;
283b8270585SJack F Vogel 		mbx->ops.write_posted(hw, msgbuf, 1, 0);
284b8270585SJack F Vogel 
285b8270585SJack F Vogel 		msec_delay(10);
286b8270585SJack F Vogel 
287b8270585SJack F Vogel 		/* set our "perm_addr" based on info provided by PF */
288b8270585SJack F Vogel 		ret_val = mbx->ops.read_posted(hw, msgbuf, 3, 0);
289b8270585SJack F Vogel 		if (!ret_val) {
290b8270585SJack F Vogel 			if (msgbuf[0] == (E1000_VF_RESET |
291b8270585SJack F Vogel 			    E1000_VT_MSGTYPE_ACK))
292b8270585SJack F Vogel 				memcpy(hw->mac.perm_addr, addr, 6);
293b8270585SJack F Vogel 			else
294b8270585SJack F Vogel 				ret_val = -E1000_ERR_MAC_INIT;
295b8270585SJack F Vogel 		}
296b8270585SJack F Vogel 	}
297b8270585SJack F Vogel 
298b8270585SJack F Vogel 	return ret_val;
299b8270585SJack F Vogel }
300b8270585SJack F Vogel 
301b8270585SJack F Vogel /**
302b8270585SJack F Vogel  *  e1000_init_hw_vf - Inits the HW
303b8270585SJack F Vogel  *  @hw: pointer to the HW structure
304b8270585SJack F Vogel  *
305b8270585SJack F Vogel  *  Not much to do here except clear the PF Reset indication if there is one.
306b8270585SJack F Vogel  **/
e1000_init_hw_vf(struct e1000_hw * hw)307b8270585SJack F Vogel static s32 e1000_init_hw_vf(struct e1000_hw *hw)
308b8270585SJack F Vogel {
309b8270585SJack F Vogel 	DEBUGFUNC("e1000_init_hw_vf");
310b8270585SJack F Vogel 
311b8270585SJack F Vogel 	/* attempt to set and restore our mac address */
312b8270585SJack F Vogel 	e1000_rar_set_vf(hw, hw->mac.addr, 0);
313b8270585SJack F Vogel 
314b8270585SJack F Vogel 	return E1000_SUCCESS;
315b8270585SJack F Vogel }
316b8270585SJack F Vogel 
317b8270585SJack F Vogel /**
318b8270585SJack F Vogel  *  e1000_rar_set_vf - set device MAC address
319b8270585SJack F Vogel  *  @hw: pointer to the HW structure
320b8270585SJack F Vogel  *  @addr: pointer to the receive address
321b8270585SJack F Vogel  *  @index receive address array register
322b8270585SJack F Vogel  **/
e1000_rar_set_vf(struct e1000_hw * hw,u8 * addr,u32 E1000_UNUSEDARG index)3238cc64f1eSJack F Vogel static int e1000_rar_set_vf(struct e1000_hw *hw, u8 *addr,
3248cc64f1eSJack F Vogel 			     u32 E1000_UNUSEDARG index)
325b8270585SJack F Vogel {
326b8270585SJack F Vogel 	struct e1000_mbx_info *mbx = &hw->mbx;
327b8270585SJack F Vogel 	u32 msgbuf[3];
328b8270585SJack F Vogel 	u8 *msg_addr = (u8 *)(&msgbuf[1]);
329b8270585SJack F Vogel 	s32 ret_val;
330b8270585SJack F Vogel 
331b8270585SJack F Vogel 	memset(msgbuf, 0, 12);
332b8270585SJack F Vogel 	msgbuf[0] = E1000_VF_SET_MAC_ADDR;
333b8270585SJack F Vogel 	memcpy(msg_addr, addr, 6);
334b8270585SJack F Vogel 	ret_val = mbx->ops.write_posted(hw, msgbuf, 3, 0);
335b8270585SJack F Vogel 
336b8270585SJack F Vogel 	if (!ret_val)
337b8270585SJack F Vogel 		ret_val = mbx->ops.read_posted(hw, msgbuf, 3, 0);
338b8270585SJack F Vogel 
339b8270585SJack F Vogel 	msgbuf[0] &= ~E1000_VT_MSGTYPE_CTS;
340b8270585SJack F Vogel 
341b8270585SJack F Vogel 	/* if nacked the address was rejected, use "perm_addr" */
342b8270585SJack F Vogel 	if (!ret_val &&
343b8270585SJack F Vogel 	    (msgbuf[0] == (E1000_VF_SET_MAC_ADDR | E1000_VT_MSGTYPE_NACK)))
344b8270585SJack F Vogel 		e1000_read_mac_addr_vf(hw);
3458cc64f1eSJack F Vogel 
3468cc64f1eSJack F Vogel 	return E1000_SUCCESS;
347b8270585SJack F Vogel }
348b8270585SJack F Vogel 
349b8270585SJack F Vogel /**
350b8270585SJack F Vogel  *  e1000_hash_mc_addr_vf - Generate a multicast hash value
351b8270585SJack F Vogel  *  @hw: pointer to the HW structure
352b8270585SJack F Vogel  *  @mc_addr: pointer to a multicast address
353b8270585SJack F Vogel  *
354b8270585SJack F Vogel  *  Generates a multicast address hash value which is used to determine
355b8270585SJack F Vogel  *  the multicast filter table array address and new table value.
356b8270585SJack F Vogel  **/
e1000_hash_mc_addr_vf(struct e1000_hw * hw,u8 * mc_addr)357b8270585SJack F Vogel static u32 e1000_hash_mc_addr_vf(struct e1000_hw *hw, u8 *mc_addr)
358b8270585SJack F Vogel {
359b8270585SJack F Vogel 	u32 hash_value, hash_mask;
360b8270585SJack F Vogel 	u8 bit_shift = 0;
361b8270585SJack F Vogel 
362b8270585SJack F Vogel 	DEBUGFUNC("e1000_hash_mc_addr_generic");
363b8270585SJack F Vogel 
364b8270585SJack F Vogel 	/* Register count multiplied by bits per register */
365b8270585SJack F Vogel 	hash_mask = (hw->mac.mta_reg_count * 32) - 1;
366b8270585SJack F Vogel 
367b8270585SJack F Vogel 	/*
368b8270585SJack F Vogel 	 * The bit_shift is the number of left-shifts
369b8270585SJack F Vogel 	 * where 0xFF would still fall within the hash mask.
370b8270585SJack F Vogel 	 */
371b8270585SJack F Vogel 	while (hash_mask >> bit_shift != 0xFF)
372b8270585SJack F Vogel 		bit_shift++;
373b8270585SJack F Vogel 
374b8270585SJack F Vogel 	hash_value = hash_mask & (((mc_addr[4] >> (8 - bit_shift)) |
375b8270585SJack F Vogel 				  (((u16) mc_addr[5]) << bit_shift)));
376b8270585SJack F Vogel 
377b8270585SJack F Vogel 	return hash_value;
378b8270585SJack F Vogel }
379b8270585SJack F Vogel 
e1000_write_msg_read_ack(struct e1000_hw * hw,u32 * msg,u16 size)3804dab5c37SJack F Vogel static void e1000_write_msg_read_ack(struct e1000_hw *hw,
3814dab5c37SJack F Vogel 				     u32 *msg, u16 size)
3824dab5c37SJack F Vogel {
3834dab5c37SJack F Vogel 	struct e1000_mbx_info *mbx = &hw->mbx;
3844dab5c37SJack F Vogel 	u32 retmsg[E1000_VFMAILBOX_SIZE];
3854dab5c37SJack F Vogel 	s32 retval = mbx->ops.write_posted(hw, msg, size, 0);
3864dab5c37SJack F Vogel 
3874dab5c37SJack F Vogel 	if (!retval)
3884dab5c37SJack F Vogel 		mbx->ops.read_posted(hw, retmsg, E1000_VFMAILBOX_SIZE, 0);
3894dab5c37SJack F Vogel }
3904dab5c37SJack F Vogel 
391b8270585SJack F Vogel /**
392b8270585SJack F Vogel  *  e1000_update_mc_addr_list_vf - Update Multicast addresses
393b8270585SJack F Vogel  *  @hw: pointer to the HW structure
394b8270585SJack F Vogel  *  @mc_addr_list: array of multicast addresses to program
395b8270585SJack F Vogel  *  @mc_addr_count: number of multicast addresses to program
396b8270585SJack F Vogel  *
397b8270585SJack F Vogel  *  Updates the Multicast Table Array.
398b8270585SJack F Vogel  *  The caller must have a packed mc_addr_list of multicast addresses.
399b8270585SJack F Vogel  **/
e1000_update_mc_addr_list_vf(struct e1000_hw * hw,u8 * mc_addr_list,u32 mc_addr_count)400b8270585SJack F Vogel void e1000_update_mc_addr_list_vf(struct e1000_hw *hw,
401b8270585SJack F Vogel 				  u8 *mc_addr_list, u32 mc_addr_count)
402b8270585SJack F Vogel {
403b8270585SJack F Vogel 	u32 msgbuf[E1000_VFMAILBOX_SIZE];
404b8270585SJack F Vogel 	u16 *hash_list = (u16 *)&msgbuf[1];
405b8270585SJack F Vogel 	u32 hash_value;
406b8270585SJack F Vogel 	u32 i;
407b8270585SJack F Vogel 
408b8270585SJack F Vogel 	DEBUGFUNC("e1000_update_mc_addr_list_vf");
409b8270585SJack F Vogel 
410b8270585SJack F Vogel 	/* Each entry in the list uses 1 16 bit word.  We have 30
411b8270585SJack F Vogel 	 * 16 bit words available in our HW msg buffer (minus 1 for the
412b8270585SJack F Vogel 	 * msg type).  That's 30 hash values if we pack 'em right.  If
413b8270585SJack F Vogel 	 * there are more than 30 MC addresses to add then punt the
414b8270585SJack F Vogel 	 * extras for now and then add code to handle more than 30 later.
415b8270585SJack F Vogel 	 * It would be unusual for a server to request that many multi-cast
416b8270585SJack F Vogel 	 * addresses except for in large enterprise network environments.
417b8270585SJack F Vogel 	 */
418b8270585SJack F Vogel 
419b8270585SJack F Vogel 	DEBUGOUT1("MC Addr Count = %d\n", mc_addr_count);
420b8270585SJack F Vogel 
421ecf2a89aSYong Wang 	msgbuf[0] = E1000_VF_SET_MULTICAST;
422ecf2a89aSYong Wang 
423b8270585SJack F Vogel 	if (mc_addr_count > 30) {
424b8270585SJack F Vogel 		msgbuf[0] |= E1000_VF_SET_MULTICAST_OVERFLOW;
425b8270585SJack F Vogel 		mc_addr_count = 30;
426b8270585SJack F Vogel 	}
427b8270585SJack F Vogel 
428b8270585SJack F Vogel 	msgbuf[0] |= mc_addr_count << E1000_VT_MSGINFO_SHIFT;
429b8270585SJack F Vogel 
430b8270585SJack F Vogel 	for (i = 0; i < mc_addr_count; i++) {
431b8270585SJack F Vogel 		hash_value = e1000_hash_mc_addr_vf(hw, mc_addr_list);
432b8270585SJack F Vogel 		DEBUGOUT1("Hash value = 0x%03X\n", hash_value);
433b8270585SJack F Vogel 		hash_list[i] = hash_value & 0x0FFF;
434e81998f4SEric Joyner 		mc_addr_list += ETHER_ADDR_LEN;
435b8270585SJack F Vogel 	}
436b8270585SJack F Vogel 
4374dab5c37SJack F Vogel 	e1000_write_msg_read_ack(hw, msgbuf, E1000_VFMAILBOX_SIZE);
438b8270585SJack F Vogel }
439b8270585SJack F Vogel 
440b8270585SJack F Vogel /**
441b8270585SJack F Vogel  *  e1000_vfta_set_vf - Set/Unset vlan filter table address
442b8270585SJack F Vogel  *  @hw: pointer to the HW structure
443b8270585SJack F Vogel  *  @vid: determines the vfta register and bit to set/unset
4441bbdc25fSKevin Bowling  *  @set: if true then set bit, else clear bit
445b8270585SJack F Vogel  **/
e1000_vfta_set_vf(struct e1000_hw * hw,u16 vid,bool set)446b8270585SJack F Vogel void e1000_vfta_set_vf(struct e1000_hw *hw, u16 vid, bool set)
447b8270585SJack F Vogel {
448b8270585SJack F Vogel 	u32 msgbuf[2];
449b8270585SJack F Vogel 
450b8270585SJack F Vogel 	msgbuf[0] = E1000_VF_SET_VLAN;
451b8270585SJack F Vogel 	msgbuf[1] = vid;
4521bbdc25fSKevin Bowling 	/* Setting the 8 bit field MSG INFO to true indicates "add" */
453b8270585SJack F Vogel 	if (set)
454b8270585SJack F Vogel 		msgbuf[0] |= E1000_VF_SET_VLAN_ADD;
455b8270585SJack F Vogel 
4564dab5c37SJack F Vogel 	e1000_write_msg_read_ack(hw, msgbuf, 2);
457b8270585SJack F Vogel }
458b8270585SJack F Vogel 
459b8270585SJack F Vogel /** e1000_rlpml_set_vf - Set the maximum receive packet length
460b8270585SJack F Vogel  *  @hw: pointer to the HW structure
461b8270585SJack F Vogel  *  @max_size: value to assign to max frame size
462b8270585SJack F Vogel  **/
e1000_rlpml_set_vf(struct e1000_hw * hw,u16 max_size)463b8270585SJack F Vogel void e1000_rlpml_set_vf(struct e1000_hw *hw, u16 max_size)
464b8270585SJack F Vogel {
465b8270585SJack F Vogel 	u32 msgbuf[2];
466b8270585SJack F Vogel 
467b8270585SJack F Vogel 	msgbuf[0] = E1000_VF_SET_LPE;
468b8270585SJack F Vogel 	msgbuf[1] = max_size;
469b8270585SJack F Vogel 
4704dab5c37SJack F Vogel 	e1000_write_msg_read_ack(hw, msgbuf, 2);
471b8270585SJack F Vogel }
472b8270585SJack F Vogel 
473b8270585SJack F Vogel /**
474b8270585SJack F Vogel  *  e1000_promisc_set_vf - Set flags for Unicast or Multicast promisc
475b8270585SJack F Vogel  *  @hw: pointer to the HW structure
476b8270585SJack F Vogel  *  @uni: boolean indicating unicast promisc status
477b8270585SJack F Vogel  *  @multi: boolean indicating multicast promisc status
478b8270585SJack F Vogel  **/
e1000_promisc_set_vf(struct e1000_hw * hw,enum e1000_promisc_type type)479b8270585SJack F Vogel s32 e1000_promisc_set_vf(struct e1000_hw *hw, enum e1000_promisc_type type)
480b8270585SJack F Vogel {
481b8270585SJack F Vogel 	struct e1000_mbx_info *mbx = &hw->mbx;
482b8270585SJack F Vogel 	u32 msgbuf = E1000_VF_SET_PROMISC;
483b8270585SJack F Vogel 	s32 ret_val;
484b8270585SJack F Vogel 
485b8270585SJack F Vogel 	switch (type) {
486b8270585SJack F Vogel 	case e1000_promisc_multicast:
487b8270585SJack F Vogel 		msgbuf |= E1000_VF_SET_PROMISC_MULTICAST;
488b8270585SJack F Vogel 		break;
489b8270585SJack F Vogel 	case e1000_promisc_enabled:
490b8270585SJack F Vogel 		msgbuf |= E1000_VF_SET_PROMISC_MULTICAST;
491a5b0fd9cSToomas Soome 		/* FALLTHROUGH */
492b8270585SJack F Vogel 	case e1000_promisc_unicast:
493b8270585SJack F Vogel 		msgbuf |= E1000_VF_SET_PROMISC_UNICAST;
494a5b0fd9cSToomas Soome 		/* FALLTHROUGH */
495b8270585SJack F Vogel 	case e1000_promisc_disabled:
496b8270585SJack F Vogel 		break;
497b8270585SJack F Vogel 	default:
498b8270585SJack F Vogel 		return -E1000_ERR_MAC_INIT;
499b8270585SJack F Vogel 	}
500b8270585SJack F Vogel 
501b8270585SJack F Vogel 	 ret_val = mbx->ops.write_posted(hw, &msgbuf, 1, 0);
502b8270585SJack F Vogel 
503b8270585SJack F Vogel 	if (!ret_val)
504b8270585SJack F Vogel 		ret_val = mbx->ops.read_posted(hw, &msgbuf, 1, 0);
505b8270585SJack F Vogel 
506b8270585SJack F Vogel 	if (!ret_val && !(msgbuf & E1000_VT_MSGTYPE_ACK))
507b8270585SJack F Vogel 		ret_val = -E1000_ERR_MAC_INIT;
508b8270585SJack F Vogel 
509b8270585SJack F Vogel 	return ret_val;
510b8270585SJack F Vogel }
511b8270585SJack F Vogel 
512b8270585SJack F Vogel /**
513b8270585SJack F Vogel  *  e1000_read_mac_addr_vf - Read device MAC address
514b8270585SJack F Vogel  *  @hw: pointer to the HW structure
515b8270585SJack F Vogel  **/
e1000_read_mac_addr_vf(struct e1000_hw * hw)516b8270585SJack F Vogel static s32 e1000_read_mac_addr_vf(struct e1000_hw *hw)
517b8270585SJack F Vogel {
518b8270585SJack F Vogel 	int i;
519b8270585SJack F Vogel 
520e81998f4SEric Joyner 	for (i = 0; i < ETHER_ADDR_LEN; i++)
521b8270585SJack F Vogel 		hw->mac.addr[i] = hw->mac.perm_addr[i];
522b8270585SJack F Vogel 
523b8270585SJack F Vogel 	return E1000_SUCCESS;
524b8270585SJack F Vogel }
525b8270585SJack F Vogel 
526b8270585SJack F Vogel /**
527b8270585SJack F Vogel  *  e1000_check_for_link_vf - Check for link for a virtual interface
528b8270585SJack F Vogel  *  @hw: pointer to the HW structure
529b8270585SJack F Vogel  *
530b8270585SJack F Vogel  *  Checks to see if the underlying PF is still talking to the VF and
531b8270585SJack F Vogel  *  if it is then it reports the link state to the hardware, otherwise
532b8270585SJack F Vogel  *  it reports link down and returns an error.
533b8270585SJack F Vogel  **/
e1000_check_for_link_vf(struct e1000_hw * hw)534b8270585SJack F Vogel static s32 e1000_check_for_link_vf(struct e1000_hw *hw)
535b8270585SJack F Vogel {
536b8270585SJack F Vogel 	struct e1000_mbx_info *mbx = &hw->mbx;
537b8270585SJack F Vogel 	struct e1000_mac_info *mac = &hw->mac;
538b8270585SJack F Vogel 	s32 ret_val = E1000_SUCCESS;
539b8270585SJack F Vogel 	u32 in_msg = 0;
540b8270585SJack F Vogel 
541b8270585SJack F Vogel 	DEBUGFUNC("e1000_check_for_link_vf");
542b8270585SJack F Vogel 
543b8270585SJack F Vogel 	/*
544b8270585SJack F Vogel 	 * We only want to run this if there has been a rst asserted.
545b8270585SJack F Vogel 	 * in this case that could mean a link change, device reset,
546b8270585SJack F Vogel 	 * or a virtual function reset
547b8270585SJack F Vogel 	 */
548b8270585SJack F Vogel 
549f0ecc46dSJack F Vogel 	/* If we were hit with a reset or timeout drop the link */
550f0ecc46dSJack F Vogel 	if (!mbx->ops.check_for_rst(hw, 0) || !mbx->timeout)
5511bbdc25fSKevin Bowling 		mac->get_link_status = true;
552b8270585SJack F Vogel 
553b8270585SJack F Vogel 	if (!mac->get_link_status)
554b8270585SJack F Vogel 		goto out;
555b8270585SJack F Vogel 
556b8270585SJack F Vogel 	/* if link status is down no point in checking to see if pf is up */
557b8270585SJack F Vogel 	if (!(E1000_READ_REG(hw, E1000_STATUS) & E1000_STATUS_LU))
558b8270585SJack F Vogel 		goto out;
559b8270585SJack F Vogel 
560b8270585SJack F Vogel 	/* if the read failed it could just be a mailbox collision, best wait
561b8270585SJack F Vogel 	 * until we are called again and don't report an error */
562b8270585SJack F Vogel 	if (mbx->ops.read(hw, &in_msg, 1, 0))
563b8270585SJack F Vogel 		goto out;
564b8270585SJack F Vogel 
565b8270585SJack F Vogel 	/* if incoming message isn't clear to send we are waiting on response */
566b8270585SJack F Vogel 	if (!(in_msg & E1000_VT_MSGTYPE_CTS)) {
567b8270585SJack F Vogel 		/* message is not CTS and is NACK we have lost CTS status */
568b8270585SJack F Vogel 		if (in_msg & E1000_VT_MSGTYPE_NACK)
569b8270585SJack F Vogel 			ret_val = -E1000_ERR_MAC_INIT;
570b8270585SJack F Vogel 		goto out;
571b8270585SJack F Vogel 	}
572b8270585SJack F Vogel 
573b8270585SJack F Vogel 	/* at this point we know the PF is talking to us, check and see if
574b8270585SJack F Vogel 	 * we are still accepting timeout or if we had a timeout failure.
575b8270585SJack F Vogel 	 * if we failed then we will need to reinit */
576b8270585SJack F Vogel 	if (!mbx->timeout) {
577b8270585SJack F Vogel 		ret_val = -E1000_ERR_MAC_INIT;
578b8270585SJack F Vogel 		goto out;
579b8270585SJack F Vogel 	}
580b8270585SJack F Vogel 
581b8270585SJack F Vogel 	/* if we passed all the tests above then the link is up and we no
582b8270585SJack F Vogel 	 * longer need to check for link */
5831bbdc25fSKevin Bowling 	mac->get_link_status = false;
584b8270585SJack F Vogel 
585b8270585SJack F Vogel out:
586b8270585SJack F Vogel 	return ret_val;
587b8270585SJack F Vogel }
588b8270585SJack F Vogel 
589