Commit 24f7cf9b authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge tag 'mac80211-next-for-net-next-2021-10-21' of...

Merge tag 'mac80211-next-for-net-next-2021-10-21' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next

Johannes Berg says:

====================
Quite a few changes:
 * the applicable eth_hw_addr_set() and const hw_addr changes
 * various code cleanups/refactorings
 * stack usage reductions across the wireless stack
 * some unstructured find_ie() -> structured find_element()
   changes
 * a few more pieces of multi-BSSID support
 * some 6 GHz regulatory support
 * 6 GHz support in hwsim, for testing userspace code
 * Light Communications (LC, 802.11bb) early band definitions
   to be able to add a first driver soon

* tag 'mac80211-next-for-net-next-2021-10-21' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next: (35 commits)
  cfg80211: fix kernel-doc for MBSSID EMA
  mac80211: Prevent AP probing during suspend
  nl80211: Add LC placeholder band definition to nl80211_band
  ...
====================

Link: https://lore.kernel.org/r/20211021154953.134849-1-johannes@sipsolutions.net


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 07591ebe f9d366d4
Loading
Loading
Loading
Loading
+146 −17
Original line number Diff line number Diff line
@@ -2802,7 +2802,6 @@ static void hwsim_mcast_new_radio(int id, struct genl_info *info,

static const struct ieee80211_sband_iftype_data he_capa_2ghz[] = {
	{
		/* TODO: should we support other types, e.g., P2P?*/
		.types_mask = BIT(NL80211_IFTYPE_STATION) |
			      BIT(NL80211_IFTYPE_AP),
		.he_cap = {
@@ -2850,7 +2849,6 @@ static const struct ieee80211_sband_iftype_data he_capa_2ghz[] = {
	},
#ifdef CONFIG_MAC80211_MESH
	{
		/* TODO: should we support other types, e.g., IBSS?*/
		.types_mask = BIT(NL80211_IFTYPE_MESH_POINT),
		.he_cap = {
			.has_he = true,
@@ -2988,6 +2986,122 @@ static const struct ieee80211_sband_iftype_data he_capa_5ghz[] = {
#endif
};

static const struct ieee80211_sband_iftype_data he_capa_6ghz[] = {
	{
		/* TODO: should we support other types, e.g., P2P?*/
		.types_mask = BIT(NL80211_IFTYPE_STATION) |
			      BIT(NL80211_IFTYPE_AP),
		.he_6ghz_capa = {
			.capa = cpu_to_le16(IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START |
					    IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP |
					    IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN |
					    IEEE80211_HE_6GHZ_CAP_SM_PS |
					    IEEE80211_HE_6GHZ_CAP_RD_RESPONDER |
					    IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS |
					    IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS),
		},
		.he_cap = {
			.has_he = true,
			.he_cap_elem = {
				.mac_cap_info[0] =
					IEEE80211_HE_MAC_CAP0_HTC_HE,
				.mac_cap_info[1] =
					IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US |
					IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8,
				.mac_cap_info[2] =
					IEEE80211_HE_MAC_CAP2_BSR |
					IEEE80211_HE_MAC_CAP2_MU_CASCADING |
					IEEE80211_HE_MAC_CAP2_ACK_EN,
				.mac_cap_info[3] =
					IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
					IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3,
				.mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU,
				.phy_cap_info[0] =
					IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
					IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
					IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G,
				.phy_cap_info[1] =
					IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
					IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
					IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD |
					IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS,
				.phy_cap_info[2] =
					IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US |
					IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ |
					IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ |
					IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO |
					IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO,

				/* Leave all the other PHY capability bytes
				 * unset, as DCM, beam forming, RU and PPE
				 * threshold information are not supported
				 */
			},
			.he_mcs_nss_supp = {
				.rx_mcs_80 = cpu_to_le16(0xfffa),
				.tx_mcs_80 = cpu_to_le16(0xfffa),
				.rx_mcs_160 = cpu_to_le16(0xfffa),
				.tx_mcs_160 = cpu_to_le16(0xfffa),
				.rx_mcs_80p80 = cpu_to_le16(0xfffa),
				.tx_mcs_80p80 = cpu_to_le16(0xfffa),
			},
		},
	},
#ifdef CONFIG_MAC80211_MESH
	{
		/* TODO: should we support other types, e.g., IBSS?*/
		.types_mask = BIT(NL80211_IFTYPE_MESH_POINT),
		.he_6ghz_capa = {
			.capa = cpu_to_le16(IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START |
					    IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP |
					    IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN |
					    IEEE80211_HE_6GHZ_CAP_SM_PS |
					    IEEE80211_HE_6GHZ_CAP_RD_RESPONDER |
					    IEEE80211_HE_6GHZ_CAP_TX_ANTPAT_CONS |
					    IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS),
		},
		.he_cap = {
			.has_he = true,
			.he_cap_elem = {
				.mac_cap_info[0] =
					IEEE80211_HE_MAC_CAP0_HTC_HE,
				.mac_cap_info[1] =
					IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8,
				.mac_cap_info[2] =
					IEEE80211_HE_MAC_CAP2_ACK_EN,
				.mac_cap_info[3] =
					IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
					IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3,
				.mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU,
				.phy_cap_info[0] =
					IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
					IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
					IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G,
				.phy_cap_info[1] =
					IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
					IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
					IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD |
					IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS,
				.phy_cap_info[2] = 0,

				/* Leave all the other PHY capability bytes
				 * unset, as DCM, beam forming, RU and PPE
				 * threshold information are not supported
				 */
			},
			.he_mcs_nss_supp = {
				.rx_mcs_80 = cpu_to_le16(0xfffa),
				.tx_mcs_80 = cpu_to_le16(0xfffa),
				.rx_mcs_160 = cpu_to_le16(0xfffa),
				.tx_mcs_160 = cpu_to_le16(0xfffa),
				.rx_mcs_80p80 = cpu_to_le16(0xfffa),
				.tx_mcs_80p80 = cpu_to_le16(0xfffa),
			},
		},
	},
#endif
};

static void mac80211_hwsim_he_capab(struct ieee80211_supported_band *sband)
{
	u16 n_iftype_data;
@@ -3000,6 +3114,10 @@ static void mac80211_hwsim_he_capab(struct ieee80211_supported_band *sband)
		n_iftype_data = ARRAY_SIZE(he_capa_5ghz);
		sband->iftype_data =
			(struct ieee80211_sband_iftype_data *)he_capa_5ghz;
	} else if (sband->band == NL80211_BAND_6GHZ) {
		n_iftype_data = ARRAY_SIZE(he_capa_6ghz);
		sband->iftype_data =
			(struct ieee80211_sband_iftype_data *)he_capa_6ghz;
	} else {
		return;
	}
@@ -3290,6 +3408,12 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
			sband->vht_cap.vht_mcs.tx_mcs_map =
				sband->vht_cap.vht_mcs.rx_mcs_map;
			break;
		case NL80211_BAND_6GHZ:
			sband->channels = data->channels_6ghz;
			sband->n_channels = ARRAY_SIZE(hwsim_channels_6ghz);
			sband->bitrates = data->rates + 4;
			sband->n_bitrates = ARRAY_SIZE(hwsim_rates) - 4;
			break;
		case NL80211_BAND_S1GHZ:
			memcpy(&sband->s1g_cap, &hwsim_s1g_cap,
			       sizeof(sband->s1g_cap));
@@ -3300,6 +3424,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
			continue;
		}

		if (band != NL80211_BAND_6GHZ){
			sband->ht_cap.ht_supported = true;
			sband->ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
					    IEEE80211_HT_CAP_GRN_FLD |
@@ -3313,6 +3438,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
			sband->ht_cap.mcs.rx_mask[0] = 0xff;
			sband->ht_cap.mcs.rx_mask[1] = 0xff;
			sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
		}

		mac80211_hwsim_he_capab(sband);

@@ -3527,13 +3653,16 @@ static const struct net_device_ops hwsim_netdev_ops = {

static void hwsim_mon_setup(struct net_device *dev)
{
	u8 addr[ETH_ALEN];

	dev->netdev_ops = &hwsim_netdev_ops;
	dev->needs_free_netdev = true;
	ether_setup(dev);
	dev->priv_flags |= IFF_NO_QUEUE;
	dev->type = ARPHRD_IEEE80211_RADIOTAP;
	eth_zero_addr(dev->dev_addr);
	dev->dev_addr[0] = 0x12;
	eth_zero_addr(addr);
	addr[0] = 0x12;
	eth_hw_addr_set(dev, addr);
}

static struct mac80211_hwsim_data *get_hwsim_data_ref_from_addr(const u8 *addr)
+38 −0
Original line number Diff line number Diff line
@@ -1988,6 +1988,44 @@ int ieee80211_get_vht_max_nss(struct ieee80211_vht_cap *cap,
			      int mcs, bool ext_nss_bw_capable,
			      unsigned int max_vht_nss);

/**
 * enum ieee80211_ap_reg_power - regulatory power for a Access Point
 *
 * @IEEE80211_REG_UNSET_AP: Access Point has no regulatory power mode
 * @IEEE80211_REG_LPI: Indoor Access Point
 * @IEEE80211_REG_SP: Standard power Access Point
 * @IEEE80211_REG_VLP: Very low power Access Point
 * @IEEE80211_REG_AP_POWER_AFTER_LAST: internal
 * @IEEE80211_REG_AP_POWER_MAX: maximum value
 */
enum ieee80211_ap_reg_power {
	IEEE80211_REG_UNSET_AP,
	IEEE80211_REG_LPI_AP,
	IEEE80211_REG_SP_AP,
	IEEE80211_REG_VLP_AP,
	IEEE80211_REG_AP_POWER_AFTER_LAST,
	IEEE80211_REG_AP_POWER_MAX =
		IEEE80211_REG_AP_POWER_AFTER_LAST - 1,
};

/**
 * enum ieee80211_client_reg_power - regulatory power for a client
 *
 * @IEEE80211_REG_UNSET_CLIENT: Client has no regulatory power mode
 * @IEEE80211_REG_DEFAULT_CLIENT: Default Client
 * @IEEE80211_REG_SUBORDINATE_CLIENT: Subordinate Client
 * @IEEE80211_REG_CLIENT_POWER_AFTER_LAST: internal
 * @IEEE80211_REG_CLIENT_POWER_MAX: maximum value
 */
enum ieee80211_client_reg_power {
	IEEE80211_REG_UNSET_CLIENT,
	IEEE80211_REG_DEFAULT_CLIENT,
	IEEE80211_REG_SUBORDINATE_CLIENT,
	IEEE80211_REG_CLIENT_POWER_AFTER_LAST,
	IEEE80211_REG_CLIENT_POWER_MAX =
		IEEE80211_REG_CLIENT_POWER_AFTER_LAST - 1,
};

/* 802.11ax HE MAC capabilities */
#define IEEE80211_HE_MAC_CAP0_HTC_HE				0x01
#define IEEE80211_HE_MAC_CAP0_TWT_REQ				0x02
+78 −1
Original line number Diff line number Diff line
@@ -739,6 +739,22 @@ struct cfg80211_tid_config {
	struct cfg80211_tid_cfg tid_conf[];
};

/**
 * struct cfg80211_fils_aad - FILS AAD data
 * @macaddr: STA MAC address
 * @kek: FILS KEK
 * @kek_len: FILS KEK length
 * @snonce: STA Nonce
 * @anonce: AP Nonce
 */
struct cfg80211_fils_aad {
	const u8 *macaddr;
	const u8 *kek;
	u8 kek_len;
	const u8 *snonce;
	const u8 *anonce;
};

/**
 * cfg80211_get_chandef_type - return old channel type from chandef
 * @chandef: the channel definition
@@ -1040,6 +1056,36 @@ struct cfg80211_crypto_settings {
	enum nl80211_sae_pwe_mechanism sae_pwe;
};

/**
 * struct cfg80211_mbssid_config - AP settings for multi bssid
 *
 * @tx_wdev: pointer to the transmitted interface in the MBSSID set
 * @index: index of this AP in the multi bssid group.
 * @ema: set to true if the beacons should be sent out in EMA mode.
 */
struct cfg80211_mbssid_config {
	struct wireless_dev *tx_wdev;
	u8 index;
	bool ema;
};

/**
 * struct cfg80211_mbssid_elems - Multiple BSSID elements
 *
 * @cnt: Number of elements in array %elems.
 *
 * @elem: Array of multiple BSSID element(s) to be added into Beacon frames.
 * @elem.data: Data for multiple BSSID elements.
 * @elem.len: Length of data.
 */
struct cfg80211_mbssid_elems {
	u8 cnt;
	struct {
		const u8 *data;
		size_t len;
	} elem[];
};

/**
 * struct cfg80211_beacon_data - beacon data
 * @head: head portion of beacon (before TIM IE)
@@ -1058,6 +1104,7 @@ struct cfg80211_crypto_settings {
 * @assocresp_ies_len: length of assocresp_ies in octets
 * @probe_resp_len: length of probe response template (@probe_resp)
 * @probe_resp: probe response template (AP mode only)
 * @mbssid_ies: multiple BSSID elements
 * @ftm_responder: enable FTM responder functionality; -1 for no change
 *	(which also implies no change in LCI/civic location data)
 * @lci: Measurement Report element content, starting with Measurement Token
@@ -1075,6 +1122,7 @@ struct cfg80211_beacon_data {
	const u8 *probe_resp;
	const u8 *lci;
	const u8 *civicloc;
	struct cfg80211_mbssid_elems *mbssid_ies;
	s8 ftm_responder;

	size_t head_len, tail_len;
@@ -1189,6 +1237,7 @@ enum cfg80211_ap_settings_flags {
 * @he_oper: HE operation IE (or %NULL if HE isn't enabled)
 * @fils_discovery: FILS discovery transmission parameters
 * @unsol_bcast_probe_resp: Unsolicited broadcast probe response parameters
 * @mbssid_config: AP settings for multiple bssid
 */
struct cfg80211_ap_settings {
	struct cfg80211_chan_def chandef;
@@ -1221,6 +1270,7 @@ struct cfg80211_ap_settings {
	struct cfg80211_he_bss_color he_bss_color;
	struct cfg80211_fils_discovery fils_discovery;
	struct cfg80211_unsol_bcast_probe_resp unsol_bcast_probe_resp;
	struct cfg80211_mbssid_config mbssid_config;
};

/**
@@ -4018,6 +4068,10 @@ struct mgmt_frame_regs {
 * @set_sar_specs: Update the SAR (TX power) settings.
 *
 * @color_change: Initiate a color change.
 *
 * @set_fils_aad: Set FILS AAD data to the AP driver so that the driver can use
 *	those to decrypt (Re)Association Request and encrypt (Re)Association
 *	Response frame.
 */
struct cfg80211_ops {
	int	(*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -4348,6 +4402,8 @@ struct cfg80211_ops {
	int	(*color_change)(struct wiphy *wiphy,
				struct net_device *dev,
				struct cfg80211_color_change_settings *params);
	int     (*set_fils_aad)(struct wiphy *wiphy, struct net_device *dev,
				struct cfg80211_fils_aad *fils_aad);
};

/*
@@ -4981,6 +5037,13 @@ struct wiphy_iftype_akm_suites {
 *	%NL80211_TID_CONFIG_ATTR_RETRY_LONG attributes
 * @sar_capa: SAR control capabilities
 * @rfkill: a pointer to the rfkill structure
 *
 * @mbssid_max_interfaces: maximum number of interfaces supported by the driver
 *	in a multiple BSSID set. This field must be set to a non-zero value
 *	by the driver to advertise MBSSID support.
 * @ema_max_profile_periodicity: maximum profile periodicity supported by
 *	the driver. Setting this field to a non-zero value indicates that the
 *	driver supports enhanced multi-BSSID advertisements (EMA AP).
 */
struct wiphy {
	struct mutex mtx;
@@ -5125,6 +5188,9 @@ struct wiphy {

	struct rfkill *rfkill;

	u8 mbssid_max_interfaces;
	u8 ema_max_profile_periodicity;

	char priv[] __aligned(NETDEV_ALIGN);
};

@@ -5492,7 +5558,7 @@ struct wireless_dev {
	unsigned long unprot_beacon_reported;
};

static inline u8 *wdev_address(struct wireless_dev *wdev)
static inline const u8 *wdev_address(struct wireless_dev *wdev)
{
	if (wdev->netdev)
		return wdev->netdev->dev_addr;
@@ -6310,6 +6376,17 @@ static inline void cfg80211_gen_new_bssid(const u8 *bssid, u8 max_bssid,
	u64_to_ether_addr(new_bssid_u64, new_bssid);
}

/**
 * cfg80211_get_ies_channel_number - returns the channel number from ies
 * @ie: IEs
 * @ielen: length of IEs
 * @band: enum nl80211_band of the channel
 *
 * Returns the channel number, or -1 if none could be determined.
 */
int cfg80211_get_ies_channel_number(const u8 *ie, size_t ielen,
				    enum nl80211_band band);

/**
 * cfg80211_is_element_inherited - returns if element ID should be inherited
 * @element: element to check
+11 −0
Original line number Diff line number Diff line
@@ -632,6 +632,10 @@ struct ieee80211_fils_discovery {
 * @s1g: BSS is S1G BSS (affects Association Request format).
 * @beacon_tx_rate: The configured beacon transmit rate that needs to be passed
 *	to driver when rate control is offloaded to firmware.
 * @power_type: power type of BSS for 6 GHz
 * @tx_pwr_env: transmit power envelope array of BSS.
 * @tx_pwr_env_num: number of @tx_pwr_env.
 * @pwr_reduction: power constraint of BSS.
 */
struct ieee80211_bss_conf {
	const u8 *bssid;
@@ -702,6 +706,10 @@ struct ieee80211_bss_conf {
	u32 unsol_bcast_probe_resp_interval;
	bool s1g;
	struct cfg80211_bitrate_mask beacon_tx_rate;
	enum ieee80211_ap_reg_power power_type;
	struct ieee80211_tx_pwr_env tx_pwr_env[IEEE80211_TPE_MAX_IE_COUNT];
	u8 tx_pwr_env_num;
	u8 pwr_reduction;
};

/**
@@ -1715,6 +1723,7 @@ enum ieee80211_offload_flags {
 *	write-protected by sdata_lock and local->mtx so holding either is fine
 *	for read access.
 * @color_change_color: the bss color that will be used after the change.
 * @mbssid_tx_vif: Pointer to the transmitting interface if MBSSID is enabled.
 */
struct ieee80211_vif {
	enum nl80211_iftype type;
@@ -1746,6 +1755,8 @@ struct ieee80211_vif {
	bool color_change_active;
	u8 color_change_color;

	struct ieee80211_vif *mbssid_tx_vif;

	/* must be last */
	u8 drv_priv[] __aligned(sizeof(void *));
};
+29 −0
Original line number Diff line number Diff line
@@ -13,6 +13,35 @@
 * enum iwl_mvm_vendor_cmd - supported vendor commands
 * @IWL_MVM_VENDOR_CMD_GET_CSME_CONN_INFO: reports CSME connection info.
 * @IWL_MVM_VENDOR_CMD_HOST_GET_OWNERSHIP: asks for ownership on the device.
 *	This is useful when the CSME firmware owns the device and the kernel
 *	wants to use it. In case the CSME firmware has no connection active the
 *	kernel will manage on its own to get ownership of the device.
 *	When the CSME firmware has an active connection, the user space
 *	involvement is required. The kernel will assert the RFKILL signal with
 *	the "device not owned" reason so that nobody can touch the device. Then
 *	the user space can run the following flow to be able to get connected
 *	to the very same AP the CSME firmware is currently connected to:
 *
 *	1) The user space (NetworkManager) boots and sees that the device is
 *	    in RFKILL because the host doesn't own the device
 *	2) The user space asks the kernel what AP the CSME firmware is
 *	   connected to (with %IWL_MVM_VENDOR_CMD_GET_CSME_CONN_INFO)
 *	3) The user space checks if it has a profile that matches the reply
 *	   from the CSME firmware
 *	4) The user space installs a network to the wpa_supplicant with a
 *	   specific BSSID and a specific frequency
 *	5) The user space prevents any type of full scan
 *	6) The user space asks iwlmei to request ownership on the device (with
 *	   this command)
 *	7) iwlmei requests ownership from the CSME firmware
 *	8) The CSME firmware grants ownership
 *	9) iwlmei tells iwlwifi to lift the RFKILL
 *	10) RFKILL OFF is reported to user space
 *	11) The host boots the device, loads the firwmare, and connects to a
 *	    specific BSSID without scanning including IP as fast as it can
 *	12) The host reports to the CSME firmware that there is a connection
 *	13) The TCP connection is preserved and the host has connectivity
 *
 * @IWL_MVM_VENDOR_CMD_ROAMING_FORBIDDEN_EVENT: notifies if roaming is allowed.
 *	It contains a &IWL_MVM_VENDOR_ATTR_ROAMING_FORBIDDEN and a
 *	&IWL_MVM_VENDOR_ATTR_VIF_ADDR attributes.
Loading