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: Sylwester Dziedziuch <sylwesterx.dziedziuch@intel.com> Signed-off-by: Mateusz Palczewski <mateusz.palczewski@intel.com> Tested-by: Rafal Romanowski <rafal.romanowski@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com> Reviewed-by: Simon Horman <simon.horman@corigine.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
d74aab2ca1
commit
ceb29474bb
1 changed files with 70 additions and 4 deletions
|
@ -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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
|
|
Loading…
Add table
Reference in a new issue