summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/dev/e1000/e1000_vf.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/dev/e1000/e1000_vf.c')
-rw-r--r--freebsd/sys/dev/e1000/e1000_vf.c64
1 files changed, 36 insertions, 28 deletions
diff --git a/freebsd/sys/dev/e1000/e1000_vf.c b/freebsd/sys/dev/e1000/e1000_vf.c
index de6feb6a..c5fab9b3 100644
--- a/freebsd/sys/dev/e1000/e1000_vf.c
+++ b/freebsd/sys/dev/e1000/e1000_vf.c
@@ -2,7 +2,7 @@
/******************************************************************************
- Copyright (c) 2001-2010, Intel Corporation
+ Copyright (c) 2001-2011, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -40,21 +40,21 @@
#include <rtems/bsd/local/e1000_api.h>
#endif
-static s32 e1000_init_phy_params_vf(struct e1000_hw *hw);
-static s32 e1000_init_nvm_params_vf(struct e1000_hw *hw);
-static void e1000_release_vf(struct e1000_hw *hw);
-static s32 e1000_acquire_vf(struct e1000_hw *hw);
-static s32 e1000_setup_link_vf(struct e1000_hw *hw);
-static s32 e1000_get_bus_info_pcie_vf(struct e1000_hw *hw);
-static s32 e1000_init_mac_params_vf(struct e1000_hw *hw);
-static s32 e1000_check_for_link_vf(struct e1000_hw *hw);
-static s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed,
- u16 *duplex);
-static s32 e1000_init_hw_vf(struct e1000_hw *hw);
-static s32 e1000_reset_hw_vf(struct e1000_hw *hw);
-static void e1000_update_mc_addr_list_vf(struct e1000_hw *hw, u8 *, u32);
-static void e1000_rar_set_vf(struct e1000_hw *, u8 *, u32);
-static s32 e1000_read_mac_addr_vf(struct e1000_hw *);
+static s32 e1000_init_phy_params_vf(struct e1000_hw *hw);
+static s32 e1000_init_nvm_params_vf(struct e1000_hw *hw);
+static void e1000_release_vf(struct e1000_hw *hw);
+static s32 e1000_acquire_vf(struct e1000_hw *hw);
+static s32 e1000_setup_link_vf(struct e1000_hw *hw);
+static s32 e1000_get_bus_info_pcie_vf(struct e1000_hw *hw);
+static s32 e1000_init_mac_params_vf(struct e1000_hw *hw);
+static s32 e1000_check_for_link_vf(struct e1000_hw *hw);
+static s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed,
+ u16 *duplex);
+static s32 e1000_init_hw_vf(struct e1000_hw *hw);
+static s32 e1000_reset_hw_vf(struct e1000_hw *hw);
+static void e1000_update_mc_addr_list_vf(struct e1000_hw *hw, u8 *, u32);
+static void e1000_rar_set_vf(struct e1000_hw *, u8 *, u32);
+static s32 e1000_read_mac_addr_vf(struct e1000_hw *);
/**
* e1000_init_phy_params_vf - Inits PHY params
@@ -223,7 +223,7 @@ static s32 e1000_get_bus_info_pcie_vf(struct e1000_hw *hw)
* the status register's data which is often stale and inaccurate.
**/
static s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed,
- u16 *duplex)
+ u16 *duplex)
{
s32 status;
@@ -292,7 +292,7 @@ static s32 e1000_reset_hw_vf(struct e1000_hw *hw)
ret_val = mbx->ops.read_posted(hw, msgbuf, 3, 0);
if (!ret_val) {
if (msgbuf[0] == (E1000_VF_RESET |
- E1000_VT_MSGTYPE_ACK))
+ E1000_VT_MSGTYPE_ACK))
memcpy(hw->mac.perm_addr, addr, 6);
else
ret_val = -E1000_ERR_MAC_INIT;
@@ -373,11 +373,22 @@ static u32 e1000_hash_mc_addr_vf(struct e1000_hw *hw, u8 *mc_addr)
bit_shift++;
hash_value = hash_mask & (((mc_addr[4] >> (8 - bit_shift)) |
- (((u16) mc_addr[5]) << bit_shift)));
+ (((u16) mc_addr[5]) << bit_shift)));
return hash_value;
}
+static void e1000_write_msg_read_ack(struct e1000_hw *hw,
+ u32 *msg, u16 size)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ u32 retmsg[E1000_VFMAILBOX_SIZE];
+ s32 retval = mbx->ops.write_posted(hw, msg, size, 0);
+
+ if (!retval)
+ mbx->ops.read_posted(hw, retmsg, E1000_VFMAILBOX_SIZE, 0);
+}
+
/**
* e1000_update_mc_addr_list_vf - Update Multicast addresses
* @hw: pointer to the HW structure
@@ -388,9 +399,8 @@ static u32 e1000_hash_mc_addr_vf(struct e1000_hw *hw, u8 *mc_addr)
* The caller must have a packed mc_addr_list of multicast addresses.
**/
void e1000_update_mc_addr_list_vf(struct e1000_hw *hw,
- u8 *mc_addr_list, u32 mc_addr_count)
+ u8 *mc_addr_list, u32 mc_addr_count)
{
- struct e1000_mbx_info *mbx = &hw->mbx;
u32 msgbuf[E1000_VFMAILBOX_SIZE];
u16 *hash_list = (u16 *)&msgbuf[1];
u32 hash_value;
@@ -424,7 +434,7 @@ void e1000_update_mc_addr_list_vf(struct e1000_hw *hw,
mc_addr_list += ETH_ADDR_LEN;
}
- mbx->ops.write_posted(hw, msgbuf, E1000_VFMAILBOX_SIZE, 0);
+ e1000_write_msg_read_ack(hw, msgbuf, E1000_VFMAILBOX_SIZE);
}
/**
@@ -435,7 +445,6 @@ void e1000_update_mc_addr_list_vf(struct e1000_hw *hw,
**/
void e1000_vfta_set_vf(struct e1000_hw *hw, u16 vid, bool set)
{
- struct e1000_mbx_info *mbx = &hw->mbx;
u32 msgbuf[2];
msgbuf[0] = E1000_VF_SET_VLAN;
@@ -444,7 +453,7 @@ void e1000_vfta_set_vf(struct e1000_hw *hw, u16 vid, bool set)
if (set)
msgbuf[0] |= E1000_VF_SET_VLAN_ADD;
- mbx->ops.write_posted(hw, msgbuf, 2, 0);
+ e1000_write_msg_read_ack(hw, msgbuf, 2);
}
/** e1000_rlpml_set_vf - Set the maximum receive packet length
@@ -453,13 +462,12 @@ void e1000_vfta_set_vf(struct e1000_hw *hw, u16 vid, bool set)
**/
void e1000_rlpml_set_vf(struct e1000_hw *hw, u16 max_size)
{
- struct e1000_mbx_info *mbx = &hw->mbx;
u32 msgbuf[2];
msgbuf[0] = E1000_VF_SET_LPE;
msgbuf[1] = max_size;
- mbx->ops.write_posted(hw, msgbuf, 2, 0);
+ e1000_write_msg_read_ack(hw, msgbuf, 2);
}
/**
@@ -536,8 +544,8 @@ static s32 e1000_check_for_link_vf(struct e1000_hw *hw)
* or a virtual function reset
*/
- /* If we were hit with a reset drop the link */
- if (!mbx->ops.check_for_rst(hw, 0))
+ /* If we were hit with a reset or timeout drop the link */
+ if (!mbx->ops.check_for_rst(hw, 0) || !mbx->timeout)
mac->get_link_status = TRUE;
if (!mac->get_link_status)