Skip to content

Commit

Permalink
i40e: Add support for VF to specify its primary MAC address
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Sylwester Dziedziuch authored and David S. Miller committed Apr 2, 2023
1 parent d74aab2 commit ceb2947
Showing 1 changed file with 70 additions and 4 deletions.
74 changes: 70 additions & 4 deletions drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
Original file line number Diff line number Diff line change
Expand Up @@ -2914,6 +2914,72 @@ static inline int i40e_check_vf_permission(struct i40e_vf *vf,
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
* @vf: pointer to the VF info
Expand Down Expand Up @@ -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);
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);

Expand Down Expand Up @@ -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);

if (was_unimac_deleted)
eth_zero_addr(vf->default_lan_addr.addr);

/* program the updated filter list */
ret = i40e_sync_vsi_filters(vsi);
if (ret)
Expand Down

0 comments on commit ceb2947

Please sign in to comment.