Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0db056d3 authored by Sara Sharon's avatar Sara Sharon Committed by Emmanuel Grumbach
Browse files

iwlwifi: mvm: support beacon storing



Currently firmware is configured to filter out beacons. In case
a beacon was changed - it is waking the host.
However, some vendors change their IEs frequently without any
significant change, and redundant wakeups are triggered as a
result.
As a solution disable beacon filtering when entering d0i3.
Instead, firmware will store the latest beacon and upon exiting
d0i3 it will send it up to the host, so the host can act upon
changes (if there were any).
This beacon will arrive as a dedicated notification - support it
as well.

Signed-off-by: default avatarSara Sharon <sara.sharon@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent 7869318e
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -315,6 +315,8 @@ typedef unsigned int __bitwise__ iwl_ucode_tlv_capa_t;
 * @IWL_UCODE_TLV_CAPA_BT_MPLUT_SUPPORT: supports bt-coex Multi-priority LUT
 * @IWL_UCODE_TLV_CAPA_BEACON_ANT_SELECTION: firmware will decide on what
 *	antenna the beacon should be transmitted
 * @IWL_UCODE_TLV_CAPA_BEACON_STORING: firmware will store the latest beacon
 *	from AP and will send it upon d0i3 exit.
 * @IWL_UCODE_TLV_CAPA_LAR_SUPPORT_V2: support LAR API V2
 *
 * @NUM_IWL_UCODE_TLV_CAPA: number of bits used
@@ -346,6 +348,7 @@ enum iwl_ucode_tlv_capa {
	IWL_UCODE_TLV_CAPA_SHORT_PM_TIMEOUTS		= (__force iwl_ucode_tlv_capa_t)65,
	IWL_UCODE_TLV_CAPA_BT_MPLUT_SUPPORT		= (__force iwl_ucode_tlv_capa_t)67,
	IWL_UCODE_TLV_CAPA_BEACON_ANT_SELECTION		= (__force iwl_ucode_tlv_capa_t)71,
	IWL_UCODE_TLV_CAPA_BEACON_STORING		= (__force iwl_ucode_tlv_capa_t)72,
	IWL_UCODE_TLV_CAPA_LAR_SUPPORT_V2		= (__force iwl_ucode_tlv_capa_t)73,

	NUM_IWL_UCODE_TLV_CAPA
+2 −1
Original line number Diff line number Diff line
@@ -853,7 +853,8 @@ iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm,
	wowlan_config_cmd->is_11n_connection =
					ap_sta->ht_cap.ht_supported;
	wowlan_config_cmd->flags = ENABLE_L3_FILTERING |
		ENABLE_NBNS_FILTERING | ENABLE_DHCP_FILTERING;
		ENABLE_NBNS_FILTERING | ENABLE_DHCP_FILTERING |
		ENABLE_STORE_BEACON;

	/* Query the last used seqno and set it */
	ret = iwl_mvm_get_last_nonqos_seq(mvm, vif);
+1 −0
Original line number Diff line number Diff line
@@ -251,6 +251,7 @@ enum iwl_wowlan_flags {
	ENABLE_L3_FILTERING	= BIT(1),
	ENABLE_NBNS_FILTERING	= BIT(2),
	ENABLE_DHCP_FILTERING	= BIT(3),
	ENABLE_STORE_BEACON	= BIT(4),
};

struct iwl_wowlan_config_cmd {
+29 −0
Original line number Diff line number Diff line
@@ -280,11 +280,16 @@ enum iwl_phy_ops_subcmd_ids {
	DTS_MEASUREMENT_NOTIF_WIDE = 0xFF,
};

enum iwl_prot_offload_subcmd_ids {
	STORED_BEACON_NTF = 0xFF,
};

/* command groups */
enum {
	LEGACY_GROUP = 0x0,
	LONG_GROUP = 0x1,
	PHY_OPS_GROUP = 0x4,
	PROT_OFFLOAD_GROUP = 0xb,
};

/**
@@ -1851,4 +1856,28 @@ struct iwl_shared_mem_cfg {
	__le32 page_buff_size;
} __packed; /* SHARED_MEM_ALLOC_API_S_VER_1 */

#define MAX_STORED_BEACON_SIZE 600

/**
 * Stored beacon notification
 *
 * @system_time: system time on air rise
 * @tsf: TSF on air rise
 * @beacon_timestamp: beacon on air rise
 * @phy_flags: general phy flags: band, modulation, etc.
 * @channel: channel this beacon was received on
 * @rates: rate in ucode internal format
 * @byte_count: frame's byte count
 */
struct iwl_stored_beacon_notif {
	__le32 system_time;
	__le64 tsf;
	__le32 beacon_timestamp;
	__le16 phy_flags;
	__le16 channel;
	__le32 rates;
	__le32 byte_count;
	u8 data[MAX_STORED_BEACON_SIZE];
} __packed; /* WOWLAN_STROED_BEACON_INFO_S_VER_1 */

#endif /* __fw_api_h__ */
+39 −2
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@
 *
 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
 * Copyright(c) 2015 Intel Deutschland GmbH
 * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
@@ -34,7 +34,7 @@
 *
 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
 * Copyright(c) 2015 Intel Deutschland GmbH
 * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -1462,3 +1462,40 @@ void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
						   iwl_mvm_beacon_loss_iterator,
						   mb);
}

void iwl_mvm_rx_stored_beacon_notif(struct iwl_mvm *mvm,
				    struct iwl_rx_cmd_buffer *rxb)
{
	struct iwl_rx_packet *pkt = rxb_addr(rxb);
	struct iwl_stored_beacon_notif *sb = (void *)pkt->data;
	struct ieee80211_rx_status rx_status;
	struct sk_buff *skb;
	u32 size = le32_to_cpu(sb->byte_count);

	if (size == 0)
		return;

	skb = alloc_skb(size, GFP_ATOMIC);
	if (!skb) {
		IWL_ERR(mvm, "alloc_skb failed\n");
		return;
	}

	/* update rx_status according to the notification's metadata */
	memset(&rx_status, 0, sizeof(rx_status));
	rx_status.mactime = le64_to_cpu(sb->tsf);
	rx_status.device_timestamp = le32_to_cpu(sb->system_time);
	rx_status.band =
		(sb->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_BAND_24)) ?
				IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
	rx_status.freq =
		ieee80211_channel_to_frequency(le16_to_cpu(sb->channel),
					       rx_status.band);

	/* copy the data */
	memcpy(skb_put(skb, size), sb->data, size);
	memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));

	/* pass it as regular rx to mac80211 */
	ieee80211_rx_napi(mvm->hw, skb, NULL);
}
Loading