1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /* Copyright(c) 2009 - 2018 Intel Corporation. */
3*4882a593Smuzhiyun
4*4882a593Smuzhiyun #include "vf.h"
5*4882a593Smuzhiyun
6*4882a593Smuzhiyun static s32 e1000_check_for_link_vf(struct e1000_hw *hw);
7*4882a593Smuzhiyun static s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed,
8*4882a593Smuzhiyun u16 *duplex);
9*4882a593Smuzhiyun static s32 e1000_init_hw_vf(struct e1000_hw *hw);
10*4882a593Smuzhiyun static s32 e1000_reset_hw_vf(struct e1000_hw *hw);
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun static void e1000_update_mc_addr_list_vf(struct e1000_hw *hw, u8 *,
13*4882a593Smuzhiyun u32, u32, u32);
14*4882a593Smuzhiyun static void e1000_rar_set_vf(struct e1000_hw *, u8 *, u32);
15*4882a593Smuzhiyun static s32 e1000_read_mac_addr_vf(struct e1000_hw *);
16*4882a593Smuzhiyun static s32 e1000_set_uc_addr_vf(struct e1000_hw *hw, u32 subcmd, u8 *addr);
17*4882a593Smuzhiyun static s32 e1000_set_vfta_vf(struct e1000_hw *, u16, bool);
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun /**
20*4882a593Smuzhiyun * e1000_init_mac_params_vf - Inits MAC params
21*4882a593Smuzhiyun * @hw: pointer to the HW structure
22*4882a593Smuzhiyun **/
e1000_init_mac_params_vf(struct e1000_hw * hw)23*4882a593Smuzhiyun static s32 e1000_init_mac_params_vf(struct e1000_hw *hw)
24*4882a593Smuzhiyun {
25*4882a593Smuzhiyun struct e1000_mac_info *mac = &hw->mac;
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun /* VF's have no MTA Registers - PF feature only */
28*4882a593Smuzhiyun mac->mta_reg_count = 128;
29*4882a593Smuzhiyun /* VF's have no access to RAR entries */
30*4882a593Smuzhiyun mac->rar_entry_count = 1;
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun /* Function pointers */
33*4882a593Smuzhiyun /* reset */
34*4882a593Smuzhiyun mac->ops.reset_hw = e1000_reset_hw_vf;
35*4882a593Smuzhiyun /* hw initialization */
36*4882a593Smuzhiyun mac->ops.init_hw = e1000_init_hw_vf;
37*4882a593Smuzhiyun /* check for link */
38*4882a593Smuzhiyun mac->ops.check_for_link = e1000_check_for_link_vf;
39*4882a593Smuzhiyun /* link info */
40*4882a593Smuzhiyun mac->ops.get_link_up_info = e1000_get_link_up_info_vf;
41*4882a593Smuzhiyun /* multicast address update */
42*4882a593Smuzhiyun mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_vf;
43*4882a593Smuzhiyun /* set mac address */
44*4882a593Smuzhiyun mac->ops.rar_set = e1000_rar_set_vf;
45*4882a593Smuzhiyun /* read mac address */
46*4882a593Smuzhiyun mac->ops.read_mac_addr = e1000_read_mac_addr_vf;
47*4882a593Smuzhiyun /* set mac filter */
48*4882a593Smuzhiyun mac->ops.set_uc_addr = e1000_set_uc_addr_vf;
49*4882a593Smuzhiyun /* set vlan filter table array */
50*4882a593Smuzhiyun mac->ops.set_vfta = e1000_set_vfta_vf;
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun return E1000_SUCCESS;
53*4882a593Smuzhiyun }
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun /**
56*4882a593Smuzhiyun * e1000_init_function_pointers_vf - Inits function pointers
57*4882a593Smuzhiyun * @hw: pointer to the HW structure
58*4882a593Smuzhiyun **/
e1000_init_function_pointers_vf(struct e1000_hw * hw)59*4882a593Smuzhiyun void e1000_init_function_pointers_vf(struct e1000_hw *hw)
60*4882a593Smuzhiyun {
61*4882a593Smuzhiyun hw->mac.ops.init_params = e1000_init_mac_params_vf;
62*4882a593Smuzhiyun hw->mbx.ops.init_params = e1000_init_mbx_params_vf;
63*4882a593Smuzhiyun }
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun /**
66*4882a593Smuzhiyun * e1000_get_link_up_info_vf - Gets link info.
67*4882a593Smuzhiyun * @hw: pointer to the HW structure
68*4882a593Smuzhiyun * @speed: pointer to 16 bit value to store link speed.
69*4882a593Smuzhiyun * @duplex: pointer to 16 bit value to store duplex.
70*4882a593Smuzhiyun *
71*4882a593Smuzhiyun * Since we cannot read the PHY and get accurate link info, we must rely upon
72*4882a593Smuzhiyun * the status register's data which is often stale and inaccurate.
73*4882a593Smuzhiyun **/
e1000_get_link_up_info_vf(struct e1000_hw * hw,u16 * speed,u16 * duplex)74*4882a593Smuzhiyun static s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed,
75*4882a593Smuzhiyun u16 *duplex)
76*4882a593Smuzhiyun {
77*4882a593Smuzhiyun s32 status;
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun status = er32(STATUS);
80*4882a593Smuzhiyun if (status & E1000_STATUS_SPEED_1000)
81*4882a593Smuzhiyun *speed = SPEED_1000;
82*4882a593Smuzhiyun else if (status & E1000_STATUS_SPEED_100)
83*4882a593Smuzhiyun *speed = SPEED_100;
84*4882a593Smuzhiyun else
85*4882a593Smuzhiyun *speed = SPEED_10;
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun if (status & E1000_STATUS_FD)
88*4882a593Smuzhiyun *duplex = FULL_DUPLEX;
89*4882a593Smuzhiyun else
90*4882a593Smuzhiyun *duplex = HALF_DUPLEX;
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun return E1000_SUCCESS;
93*4882a593Smuzhiyun }
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun /**
96*4882a593Smuzhiyun * e1000_reset_hw_vf - Resets the HW
97*4882a593Smuzhiyun * @hw: pointer to the HW structure
98*4882a593Smuzhiyun *
99*4882a593Smuzhiyun * VF's provide a function level reset. This is done using bit 26 of ctrl_reg.
100*4882a593Smuzhiyun * This is all the reset we can perform on a VF.
101*4882a593Smuzhiyun **/
e1000_reset_hw_vf(struct e1000_hw * hw)102*4882a593Smuzhiyun static s32 e1000_reset_hw_vf(struct e1000_hw *hw)
103*4882a593Smuzhiyun {
104*4882a593Smuzhiyun struct e1000_mbx_info *mbx = &hw->mbx;
105*4882a593Smuzhiyun u32 timeout = E1000_VF_INIT_TIMEOUT;
106*4882a593Smuzhiyun u32 ret_val = -E1000_ERR_MAC_INIT;
107*4882a593Smuzhiyun u32 msgbuf[3];
108*4882a593Smuzhiyun u8 *addr = (u8 *)(&msgbuf[1]);
109*4882a593Smuzhiyun u32 ctrl;
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun /* assert VF queue/interrupt reset */
112*4882a593Smuzhiyun ctrl = er32(CTRL);
113*4882a593Smuzhiyun ew32(CTRL, ctrl | E1000_CTRL_RST);
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun /* we cannot initialize while the RSTI / RSTD bits are asserted */
116*4882a593Smuzhiyun while (!mbx->ops.check_for_rst(hw) && timeout) {
117*4882a593Smuzhiyun timeout--;
118*4882a593Smuzhiyun udelay(5);
119*4882a593Smuzhiyun }
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun if (timeout) {
122*4882a593Smuzhiyun /* mailbox timeout can now become active */
123*4882a593Smuzhiyun mbx->timeout = E1000_VF_MBX_INIT_TIMEOUT;
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun /* notify PF of VF reset completion */
126*4882a593Smuzhiyun msgbuf[0] = E1000_VF_RESET;
127*4882a593Smuzhiyun mbx->ops.write_posted(hw, msgbuf, 1);
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun mdelay(10);
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun /* set our "perm_addr" based on info provided by PF */
132*4882a593Smuzhiyun ret_val = mbx->ops.read_posted(hw, msgbuf, 3);
133*4882a593Smuzhiyun if (!ret_val) {
134*4882a593Smuzhiyun if (msgbuf[0] == (E1000_VF_RESET |
135*4882a593Smuzhiyun E1000_VT_MSGTYPE_ACK))
136*4882a593Smuzhiyun memcpy(hw->mac.perm_addr, addr, ETH_ALEN);
137*4882a593Smuzhiyun else
138*4882a593Smuzhiyun ret_val = -E1000_ERR_MAC_INIT;
139*4882a593Smuzhiyun }
140*4882a593Smuzhiyun }
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun return ret_val;
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun /**
146*4882a593Smuzhiyun * e1000_init_hw_vf - Inits the HW
147*4882a593Smuzhiyun * @hw: pointer to the HW structure
148*4882a593Smuzhiyun *
149*4882a593Smuzhiyun * Not much to do here except clear the PF Reset indication if there is one.
150*4882a593Smuzhiyun **/
e1000_init_hw_vf(struct e1000_hw * hw)151*4882a593Smuzhiyun static s32 e1000_init_hw_vf(struct e1000_hw *hw)
152*4882a593Smuzhiyun {
153*4882a593Smuzhiyun /* attempt to set and restore our mac address */
154*4882a593Smuzhiyun e1000_rar_set_vf(hw, hw->mac.addr, 0);
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun return E1000_SUCCESS;
157*4882a593Smuzhiyun }
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun /**
160*4882a593Smuzhiyun * e1000_hash_mc_addr_vf - Generate a multicast hash value
161*4882a593Smuzhiyun * @hw: pointer to the HW structure
162*4882a593Smuzhiyun * @mc_addr: pointer to a multicast address
163*4882a593Smuzhiyun *
164*4882a593Smuzhiyun * Generates a multicast address hash value which is used to determine
165*4882a593Smuzhiyun * the multicast filter table array address and new table value. See
166*4882a593Smuzhiyun * e1000_mta_set_generic()
167*4882a593Smuzhiyun **/
e1000_hash_mc_addr_vf(struct e1000_hw * hw,u8 * mc_addr)168*4882a593Smuzhiyun static u32 e1000_hash_mc_addr_vf(struct e1000_hw *hw, u8 *mc_addr)
169*4882a593Smuzhiyun {
170*4882a593Smuzhiyun u32 hash_value, hash_mask;
171*4882a593Smuzhiyun u8 bit_shift = 0;
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun /* Register count multiplied by bits per register */
174*4882a593Smuzhiyun hash_mask = (hw->mac.mta_reg_count * 32) - 1;
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun /* The bit_shift is the number of left-shifts
177*4882a593Smuzhiyun * where 0xFF would still fall within the hash mask.
178*4882a593Smuzhiyun */
179*4882a593Smuzhiyun while (hash_mask >> bit_shift != 0xFF)
180*4882a593Smuzhiyun bit_shift++;
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun hash_value = hash_mask & (((mc_addr[4] >> (8 - bit_shift)) |
183*4882a593Smuzhiyun (((u16)mc_addr[5]) << bit_shift)));
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun return hash_value;
186*4882a593Smuzhiyun }
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun /**
189*4882a593Smuzhiyun * e1000_update_mc_addr_list_vf - Update Multicast addresses
190*4882a593Smuzhiyun * @hw: pointer to the HW structure
191*4882a593Smuzhiyun * @mc_addr_list: array of multicast addresses to program
192*4882a593Smuzhiyun * @mc_addr_count: number of multicast addresses to program
193*4882a593Smuzhiyun * @rar_used_count: the first RAR register free to program
194*4882a593Smuzhiyun * @rar_count: total number of supported Receive Address Registers
195*4882a593Smuzhiyun *
196*4882a593Smuzhiyun * Updates the Receive Address Registers and Multicast Table Array.
197*4882a593Smuzhiyun * The caller must have a packed mc_addr_list of multicast addresses.
198*4882a593Smuzhiyun * The parameter rar_count will usually be hw->mac.rar_entry_count
199*4882a593Smuzhiyun * unless there are workarounds that change this.
200*4882a593Smuzhiyun **/
e1000_update_mc_addr_list_vf(struct e1000_hw * hw,u8 * mc_addr_list,u32 mc_addr_count,u32 rar_used_count,u32 rar_count)201*4882a593Smuzhiyun static void e1000_update_mc_addr_list_vf(struct e1000_hw *hw,
202*4882a593Smuzhiyun u8 *mc_addr_list, u32 mc_addr_count,
203*4882a593Smuzhiyun u32 rar_used_count, u32 rar_count)
204*4882a593Smuzhiyun {
205*4882a593Smuzhiyun struct e1000_mbx_info *mbx = &hw->mbx;
206*4882a593Smuzhiyun u32 msgbuf[E1000_VFMAILBOX_SIZE];
207*4882a593Smuzhiyun u16 *hash_list = (u16 *)&msgbuf[1];
208*4882a593Smuzhiyun u32 hash_value;
209*4882a593Smuzhiyun u32 cnt, i;
210*4882a593Smuzhiyun s32 ret_val;
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun /* Each entry in the list uses 1 16 bit word. We have 30
213*4882a593Smuzhiyun * 16 bit words available in our HW msg buffer (minus 1 for the
214*4882a593Smuzhiyun * msg type). That's 30 hash values if we pack 'em right. If
215*4882a593Smuzhiyun * there are more than 30 MC addresses to add then punt the
216*4882a593Smuzhiyun * extras for now and then add code to handle more than 30 later.
217*4882a593Smuzhiyun * It would be unusual for a server to request that many multi-cast
218*4882a593Smuzhiyun * addresses except for in large enterprise network environments.
219*4882a593Smuzhiyun */
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun cnt = (mc_addr_count > 30) ? 30 : mc_addr_count;
222*4882a593Smuzhiyun msgbuf[0] = E1000_VF_SET_MULTICAST;
223*4882a593Smuzhiyun msgbuf[0] |= cnt << E1000_VT_MSGINFO_SHIFT;
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun for (i = 0; i < cnt; i++) {
226*4882a593Smuzhiyun hash_value = e1000_hash_mc_addr_vf(hw, mc_addr_list);
227*4882a593Smuzhiyun hash_list[i] = hash_value & 0x0FFFF;
228*4882a593Smuzhiyun mc_addr_list += ETH_ALEN;
229*4882a593Smuzhiyun }
230*4882a593Smuzhiyun
231*4882a593Smuzhiyun ret_val = mbx->ops.write_posted(hw, msgbuf, E1000_VFMAILBOX_SIZE);
232*4882a593Smuzhiyun if (!ret_val)
233*4882a593Smuzhiyun mbx->ops.read_posted(hw, msgbuf, 1);
234*4882a593Smuzhiyun }
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun /**
237*4882a593Smuzhiyun * e1000_set_vfta_vf - Set/Unset vlan filter table address
238*4882a593Smuzhiyun * @hw: pointer to the HW structure
239*4882a593Smuzhiyun * @vid: determines the vfta register and bit to set/unset
240*4882a593Smuzhiyun * @set: if true then set bit, else clear bit
241*4882a593Smuzhiyun **/
e1000_set_vfta_vf(struct e1000_hw * hw,u16 vid,bool set)242*4882a593Smuzhiyun static s32 e1000_set_vfta_vf(struct e1000_hw *hw, u16 vid, bool set)
243*4882a593Smuzhiyun {
244*4882a593Smuzhiyun struct e1000_mbx_info *mbx = &hw->mbx;
245*4882a593Smuzhiyun u32 msgbuf[2];
246*4882a593Smuzhiyun s32 err;
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun msgbuf[0] = E1000_VF_SET_VLAN;
249*4882a593Smuzhiyun msgbuf[1] = vid;
250*4882a593Smuzhiyun /* Setting the 8 bit field MSG INFO to true indicates "add" */
251*4882a593Smuzhiyun if (set)
252*4882a593Smuzhiyun msgbuf[0] |= BIT(E1000_VT_MSGINFO_SHIFT);
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun mbx->ops.write_posted(hw, msgbuf, 2);
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun err = mbx->ops.read_posted(hw, msgbuf, 2);
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun msgbuf[0] &= ~E1000_VT_MSGTYPE_CTS;
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun /* if nacked the vlan was rejected */
261*4882a593Smuzhiyun if (!err && (msgbuf[0] == (E1000_VF_SET_VLAN | E1000_VT_MSGTYPE_NACK)))
262*4882a593Smuzhiyun err = -E1000_ERR_MAC_INIT;
263*4882a593Smuzhiyun
264*4882a593Smuzhiyun return err;
265*4882a593Smuzhiyun }
266*4882a593Smuzhiyun
267*4882a593Smuzhiyun /**
268*4882a593Smuzhiyun * e1000_rlpml_set_vf - Set the maximum receive packet length
269*4882a593Smuzhiyun * @hw: pointer to the HW structure
270*4882a593Smuzhiyun * @max_size: value to assign to max frame size
271*4882a593Smuzhiyun **/
e1000_rlpml_set_vf(struct e1000_hw * hw,u16 max_size)272*4882a593Smuzhiyun void e1000_rlpml_set_vf(struct e1000_hw *hw, u16 max_size)
273*4882a593Smuzhiyun {
274*4882a593Smuzhiyun struct e1000_mbx_info *mbx = &hw->mbx;
275*4882a593Smuzhiyun u32 msgbuf[2];
276*4882a593Smuzhiyun s32 ret_val;
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun msgbuf[0] = E1000_VF_SET_LPE;
279*4882a593Smuzhiyun msgbuf[1] = max_size;
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun ret_val = mbx->ops.write_posted(hw, msgbuf, 2);
282*4882a593Smuzhiyun if (!ret_val)
283*4882a593Smuzhiyun mbx->ops.read_posted(hw, msgbuf, 1);
284*4882a593Smuzhiyun }
285*4882a593Smuzhiyun
286*4882a593Smuzhiyun /**
287*4882a593Smuzhiyun * e1000_rar_set_vf - set device MAC address
288*4882a593Smuzhiyun * @hw: pointer to the HW structure
289*4882a593Smuzhiyun * @addr: pointer to the receive address
290*4882a593Smuzhiyun * @index: receive address array register
291*4882a593Smuzhiyun **/
e1000_rar_set_vf(struct e1000_hw * hw,u8 * addr,u32 index)292*4882a593Smuzhiyun static void e1000_rar_set_vf(struct e1000_hw *hw, u8 *addr, u32 index)
293*4882a593Smuzhiyun {
294*4882a593Smuzhiyun struct e1000_mbx_info *mbx = &hw->mbx;
295*4882a593Smuzhiyun u32 msgbuf[3];
296*4882a593Smuzhiyun u8 *msg_addr = (u8 *)(&msgbuf[1]);
297*4882a593Smuzhiyun s32 ret_val;
298*4882a593Smuzhiyun
299*4882a593Smuzhiyun memset(msgbuf, 0, 12);
300*4882a593Smuzhiyun msgbuf[0] = E1000_VF_SET_MAC_ADDR;
301*4882a593Smuzhiyun memcpy(msg_addr, addr, ETH_ALEN);
302*4882a593Smuzhiyun ret_val = mbx->ops.write_posted(hw, msgbuf, 3);
303*4882a593Smuzhiyun
304*4882a593Smuzhiyun if (!ret_val)
305*4882a593Smuzhiyun ret_val = mbx->ops.read_posted(hw, msgbuf, 3);
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun msgbuf[0] &= ~E1000_VT_MSGTYPE_CTS;
308*4882a593Smuzhiyun
309*4882a593Smuzhiyun /* if nacked the address was rejected, use "perm_addr" */
310*4882a593Smuzhiyun if (!ret_val &&
311*4882a593Smuzhiyun (msgbuf[0] == (E1000_VF_SET_MAC_ADDR | E1000_VT_MSGTYPE_NACK)))
312*4882a593Smuzhiyun e1000_read_mac_addr_vf(hw);
313*4882a593Smuzhiyun }
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun /**
316*4882a593Smuzhiyun * e1000_read_mac_addr_vf - Read device MAC address
317*4882a593Smuzhiyun * @hw: pointer to the HW structure
318*4882a593Smuzhiyun **/
e1000_read_mac_addr_vf(struct e1000_hw * hw)319*4882a593Smuzhiyun static s32 e1000_read_mac_addr_vf(struct e1000_hw *hw)
320*4882a593Smuzhiyun {
321*4882a593Smuzhiyun memcpy(hw->mac.addr, hw->mac.perm_addr, ETH_ALEN);
322*4882a593Smuzhiyun
323*4882a593Smuzhiyun return E1000_SUCCESS;
324*4882a593Smuzhiyun }
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun /**
327*4882a593Smuzhiyun * e1000_set_uc_addr_vf - Set or clear unicast filters
328*4882a593Smuzhiyun * @hw: pointer to the HW structure
329*4882a593Smuzhiyun * @sub_cmd: add or clear filters
330*4882a593Smuzhiyun * @addr: pointer to the filter MAC address
331*4882a593Smuzhiyun **/
e1000_set_uc_addr_vf(struct e1000_hw * hw,u32 sub_cmd,u8 * addr)332*4882a593Smuzhiyun static s32 e1000_set_uc_addr_vf(struct e1000_hw *hw, u32 sub_cmd, u8 *addr)
333*4882a593Smuzhiyun {
334*4882a593Smuzhiyun struct e1000_mbx_info *mbx = &hw->mbx;
335*4882a593Smuzhiyun u32 msgbuf[3], msgbuf_chk;
336*4882a593Smuzhiyun u8 *msg_addr = (u8 *)(&msgbuf[1]);
337*4882a593Smuzhiyun s32 ret_val;
338*4882a593Smuzhiyun
339*4882a593Smuzhiyun memset(msgbuf, 0, sizeof(msgbuf));
340*4882a593Smuzhiyun msgbuf[0] |= sub_cmd;
341*4882a593Smuzhiyun msgbuf[0] |= E1000_VF_SET_MAC_ADDR;
342*4882a593Smuzhiyun msgbuf_chk = msgbuf[0];
343*4882a593Smuzhiyun
344*4882a593Smuzhiyun if (addr)
345*4882a593Smuzhiyun memcpy(msg_addr, addr, ETH_ALEN);
346*4882a593Smuzhiyun
347*4882a593Smuzhiyun ret_val = mbx->ops.write_posted(hw, msgbuf, 3);
348*4882a593Smuzhiyun
349*4882a593Smuzhiyun if (!ret_val)
350*4882a593Smuzhiyun ret_val = mbx->ops.read_posted(hw, msgbuf, 3);
351*4882a593Smuzhiyun
352*4882a593Smuzhiyun msgbuf[0] &= ~E1000_VT_MSGTYPE_CTS;
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun if (!ret_val) {
355*4882a593Smuzhiyun msgbuf[0] &= ~E1000_VT_MSGTYPE_CTS;
356*4882a593Smuzhiyun
357*4882a593Smuzhiyun if (msgbuf[0] == (msgbuf_chk | E1000_VT_MSGTYPE_NACK))
358*4882a593Smuzhiyun return -ENOSPC;
359*4882a593Smuzhiyun }
360*4882a593Smuzhiyun
361*4882a593Smuzhiyun return ret_val;
362*4882a593Smuzhiyun }
363*4882a593Smuzhiyun
364*4882a593Smuzhiyun /**
365*4882a593Smuzhiyun * e1000_check_for_link_vf - Check for link for a virtual interface
366*4882a593Smuzhiyun * @hw: pointer to the HW structure
367*4882a593Smuzhiyun *
368*4882a593Smuzhiyun * Checks to see if the underlying PF is still talking to the VF and
369*4882a593Smuzhiyun * if it is then it reports the link state to the hardware, otherwise
370*4882a593Smuzhiyun * it reports link down and returns an error.
371*4882a593Smuzhiyun **/
e1000_check_for_link_vf(struct e1000_hw * hw)372*4882a593Smuzhiyun static s32 e1000_check_for_link_vf(struct e1000_hw *hw)
373*4882a593Smuzhiyun {
374*4882a593Smuzhiyun struct e1000_mbx_info *mbx = &hw->mbx;
375*4882a593Smuzhiyun struct e1000_mac_info *mac = &hw->mac;
376*4882a593Smuzhiyun s32 ret_val = E1000_SUCCESS;
377*4882a593Smuzhiyun u32 in_msg = 0;
378*4882a593Smuzhiyun
379*4882a593Smuzhiyun /* We only want to run this if there has been a rst asserted.
380*4882a593Smuzhiyun * in this case that could mean a link change, device reset,
381*4882a593Smuzhiyun * or a virtual function reset
382*4882a593Smuzhiyun */
383*4882a593Smuzhiyun
384*4882a593Smuzhiyun /* If we were hit with a reset or timeout drop the link */
385*4882a593Smuzhiyun if (!mbx->ops.check_for_rst(hw) || !mbx->timeout)
386*4882a593Smuzhiyun mac->get_link_status = true;
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun if (!mac->get_link_status)
389*4882a593Smuzhiyun goto out;
390*4882a593Smuzhiyun
391*4882a593Smuzhiyun /* if link status is down no point in checking to see if PF is up */
392*4882a593Smuzhiyun if (!(er32(STATUS) & E1000_STATUS_LU))
393*4882a593Smuzhiyun goto out;
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun /* if the read failed it could just be a mailbox collision, best wait
396*4882a593Smuzhiyun * until we are called again and don't report an error
397*4882a593Smuzhiyun */
398*4882a593Smuzhiyun if (mbx->ops.read(hw, &in_msg, 1))
399*4882a593Smuzhiyun goto out;
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun /* if incoming message isn't clear to send we are waiting on response */
402*4882a593Smuzhiyun if (!(in_msg & E1000_VT_MSGTYPE_CTS)) {
403*4882a593Smuzhiyun /* msg is not CTS and is NACK we must have lost CTS status */
404*4882a593Smuzhiyun if (in_msg & E1000_VT_MSGTYPE_NACK)
405*4882a593Smuzhiyun ret_val = -E1000_ERR_MAC_INIT;
406*4882a593Smuzhiyun goto out;
407*4882a593Smuzhiyun }
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun /* the PF is talking, if we timed out in the past we reinit */
410*4882a593Smuzhiyun if (!mbx->timeout) {
411*4882a593Smuzhiyun ret_val = -E1000_ERR_MAC_INIT;
412*4882a593Smuzhiyun goto out;
413*4882a593Smuzhiyun }
414*4882a593Smuzhiyun
415*4882a593Smuzhiyun /* if we passed all the tests above then the link is up and we no
416*4882a593Smuzhiyun * longer need to check for link
417*4882a593Smuzhiyun */
418*4882a593Smuzhiyun mac->get_link_status = false;
419*4882a593Smuzhiyun
420*4882a593Smuzhiyun out:
421*4882a593Smuzhiyun return ret_val;
422*4882a593Smuzhiyun }
423*4882a593Smuzhiyun
424