Commit ceb29474 authored by Sylwester Dziedziuch's avatar Sylwester Dziedziuch Committed by David S. Miller

i40e: Add support for VF to specify its primary MAC address

Currently in the i40e driver there is no implementation of different
MAC address handling depending on whether it is a legacy or primary.
Introduce new checks for VF to be able to specify its primary MAC
address based on the VIRTCHNL_ETHER_ADDR_PRIMARY type.

Primary MAC address are treated differently compared to legacy
ones in a scenario where:
1. If a unicast MAC is being added and it's specified as
VIRTCHNL_ETHER_ADDR_PRIMARY, then replace the current
default_lan_addr.addr.
2. If a unicast MAC is being deleted and it's type
is specified as VIRTCHNL_ETHER_ADDR_PRIMARY, then zero the
hw_lan_addr.addr.
Signed-off-by: default avatarSylwester Dziedziuch <sylwesterx.dziedziuch@intel.com>
Signed-off-by: default avatarMateusz Palczewski <mateusz.palczewski@intel.com>
Tested-by: default avatarRafal Romanowski <rafal.romanowski@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
Reviewed-by: default avatarSimon Horman <simon.horman@corigine.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d74aab2c
...@@ -2914,6 +2914,72 @@ static inline int i40e_check_vf_permission(struct i40e_vf *vf, ...@@ -2914,6 +2914,72 @@ static inline int i40e_check_vf_permission(struct i40e_vf *vf,
return 0; return 0;
} }
/**
* i40e_vc_ether_addr_type - get type of virtchnl_ether_addr
* @vc_ether_addr: used to extract the type
**/
static u8
i40e_vc_ether_addr_type(struct virtchnl_ether_addr *vc_ether_addr)
{
return vc_ether_addr->type & VIRTCHNL_ETHER_ADDR_TYPE_MASK;
}
/**
* i40e_is_vc_addr_legacy
* @vc_ether_addr: VIRTCHNL structure that contains MAC and type
*
* check if the MAC address is from an older VF
**/
static bool
i40e_is_vc_addr_legacy(struct virtchnl_ether_addr *vc_ether_addr)
{
return i40e_vc_ether_addr_type(vc_ether_addr) ==
VIRTCHNL_ETHER_ADDR_LEGACY;
}
/**
* i40e_is_vc_addr_primary
* @vc_ether_addr: VIRTCHNL structure that contains MAC and type
*
* check if the MAC address is the VF's primary MAC
* This function should only be called when the MAC address in
* virtchnl_ether_addr is a valid unicast MAC
**/
static bool
i40e_is_vc_addr_primary(struct virtchnl_ether_addr *vc_ether_addr)
{
return i40e_vc_ether_addr_type(vc_ether_addr) ==
VIRTCHNL_ETHER_ADDR_PRIMARY;
}
/**
* i40e_update_vf_mac_addr
* @vf: VF to update
* @vc_ether_addr: structure from VIRTCHNL with MAC to add
*
* update the VF's cached hardware MAC if allowed
**/
static void
i40e_update_vf_mac_addr(struct i40e_vf *vf,
struct virtchnl_ether_addr *vc_ether_addr)
{
u8 *mac_addr = vc_ether_addr->addr;
if (!is_valid_ether_addr(mac_addr))
return;
/* If request to add MAC filter is a primary request update its default
* MAC address with the requested one. If it is a legacy request then
* check if current default is empty if so update the default MAC
*/
if (i40e_is_vc_addr_primary(vc_ether_addr)) {
ether_addr_copy(vf->default_lan_addr.addr, mac_addr);
} else if (i40e_is_vc_addr_legacy(vc_ether_addr)) {
if (is_zero_ether_addr(vf->default_lan_addr.addr))
ether_addr_copy(vf->default_lan_addr.addr, mac_addr);
}
}
/** /**
* i40e_vc_add_mac_addr_msg * i40e_vc_add_mac_addr_msg
* @vf: pointer to the VF info * @vf: pointer to the VF info
...@@ -2965,11 +3031,8 @@ static int i40e_vc_add_mac_addr_msg(struct i40e_vf *vf, u8 *msg) ...@@ -2965,11 +3031,8 @@ static int i40e_vc_add_mac_addr_msg(struct i40e_vf *vf, u8 *msg)
spin_unlock_bh(&vsi->mac_filter_hash_lock); spin_unlock_bh(&vsi->mac_filter_hash_lock);
goto error_param; goto error_param;
} }
if (is_valid_ether_addr(al->list[i].addr) &&
is_zero_ether_addr(vf->default_lan_addr.addr))
ether_addr_copy(vf->default_lan_addr.addr,
al->list[i].addr);
} }
i40e_update_vf_mac_addr(vf, &al->list[i]);
} }
spin_unlock_bh(&vsi->mac_filter_hash_lock); spin_unlock_bh(&vsi->mac_filter_hash_lock);
...@@ -3032,6 +3095,9 @@ static int i40e_vc_del_mac_addr_msg(struct i40e_vf *vf, u8 *msg) ...@@ -3032,6 +3095,9 @@ static int i40e_vc_del_mac_addr_msg(struct i40e_vf *vf, u8 *msg)
spin_unlock_bh(&vsi->mac_filter_hash_lock); spin_unlock_bh(&vsi->mac_filter_hash_lock);
if (was_unimac_deleted)
eth_zero_addr(vf->default_lan_addr.addr);
/* program the updated filter list */ /* program the updated filter list */
ret = i40e_sync_vsi_filters(vsi); ret = i40e_sync_vsi_filters(vsi);
if (ret) if (ret)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment