diff options
| -rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/fw-api.h | 27 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/mac80211.c | 15 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/ops.c | 1 | 
3 files changed, 43 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index 191dcae8ba4..c6384555aab 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h @@ -173,6 +173,8 @@ enum {  	REPLY_DEBUG_CMD = 0xf0,  	DEBUG_LOG_MSG = 0xf7, +	MCAST_FILTER_CMD = 0xd0, +  	/* D3 commands/notifications */  	D3_CONFIG_CMD = 0xd3,  	PROT_OFFLOAD_CONFIG_CMD = 0xd4, @@ -948,4 +950,29 @@ struct iwl_set_calib_default_cmd {  	u8 data[0];  } __packed; /* PHY_CALIB_OVERRIDE_VALUES_S */ +#define MAX_PORT_ID_NUM	2 + +/** + * struct iwl_mcast_filter_cmd - configure multicast filter. + * @filter_own: Set 1 to filter out multicast packets sent by station itself + * @port_id:	Multicast MAC addresses array specifier. This is a strange way + *		to identify network interface adopted in host-device IF. + *		It is used by FW as index in array of addresses. This array has + *		MAX_PORT_ID_NUM members. + * @count:	Number of MAC addresses in the array + * @pass_all:	Set 1 to pass all multicast packets. + * @bssid:	current association BSSID. + * @addr_list:	Place holder for array of MAC addresses. + *		IMPORTANT: add padding if necessary to ensure DWORD alignment. + */ +struct iwl_mcast_filter_cmd { +	u8 filter_own; +	u8 port_id; +	u8 count; +	u8 pass_all; +	u8 bssid[6]; +	u8 reserved[2]; +	u8 addr_list[0]; +} __packed; /* MCAST_FILTERING_CMD_API_S_VER_1 */ +  #endif /* __fw_api_h__ */ diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index dd158ec571f..899b56c85b5 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -701,6 +701,20 @@ static void iwl_mvm_configure_filter(struct ieee80211_hw *hw,  	*total_flags = 0;  } +static int iwl_mvm_configure_mcast_filter(struct iwl_mvm *mvm, +					  struct ieee80211_vif *vif) +{ +	struct iwl_mcast_filter_cmd mcast_filter_cmd = { +		.pass_all = 1, +	}; + +	memcpy(mcast_filter_cmd.bssid, vif->bss_conf.bssid, ETH_ALEN); + +	return iwl_mvm_send_cmd_pdu(mvm, MCAST_FILTER_CMD, CMD_SYNC, +				    sizeof(mcast_filter_cmd), +				    &mcast_filter_cmd); +} +  static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,  					     struct ieee80211_vif *vif,  					     struct ieee80211_bss_conf *bss_conf, @@ -722,6 +736,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,  				return;  			}  			iwl_mvm_bt_coex_vif_assoc(mvm, vif); +			iwl_mvm_configure_mcast_filter(mvm, vif);  		} else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) {  			/* remove AP station now that the MAC is unassoc */  			ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id); diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index fe031d304d1..b29c31a4159 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -292,6 +292,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {  	CMD(BT_COEX_PROT_ENV),  	CMD(BT_PROFILE_NOTIFICATION),  	CMD(BT_CONFIG), +	CMD(MCAST_FILTER_CMD),  };  #undef CMD  |