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

Commit 50d26aa3 authored by Eliad Peller's avatar Eliad Peller Committed by John W. Linville
Browse files

wlcore: save seq num only between recoveries



We want seq num (freed_pkts) to be initialized
on each new connection, but keep persistent
between recoveries/suspends.

Save the freed_pkts in the private block of the
sta struct (we already do a similar thing for
AP's stations).

However, keep the old wlvif->total_freed_pkts
in order to avoid too intrusive change.

Signed-off-by: default avatarEliad Peller <eliad@wizery.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 72fcd3d1
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -372,9 +372,8 @@ void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
	wl1271_tx_reset_link_queues(wl, *hlid);
	wl->links[*hlid].wlvif = NULL;

	if (wlvif->bss_type == BSS_TYPE_STA_BSS ||
	    (wlvif->bss_type == BSS_TYPE_AP_BSS &&
	     *hlid == wlvif->ap.bcast_hlid)) {
	if (wlvif->bss_type == BSS_TYPE_AP_BSS &&
	    *hlid == wlvif->ap.bcast_hlid) {
		/*
		 * save the total freed packets in the wlvif, in case this is
		 * recovery or suspend
+58 −19
Original line number Diff line number Diff line
@@ -898,6 +898,41 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
	wlcore_set_partition(wl, &old_part);
}

static void wlcore_save_freed_pkts(struct wl1271 *wl, struct wl12xx_vif *wlvif,
				   u8 hlid, struct ieee80211_sta *sta)
{
	struct wl1271_station *wl_sta;

	wl_sta = (void *)sta->drv_priv;
	wl_sta->total_freed_pkts = wl->links[hlid].total_freed_pkts;

	/*
	 * increment the initial seq number on recovery to account for
	 * transmitted packets that we haven't yet got in the FW status
	 */
	if (test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags))
		wl_sta->total_freed_pkts +=
				WL1271_TX_SQN_POST_RECOVERY_PADDING;
}

static void wlcore_save_freed_pkts_addr(struct wl1271 *wl,
					struct wl12xx_vif *wlvif,
					u8 hlid, const u8 *addr)
{
	struct ieee80211_sta *sta;
	struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);

	if (WARN_ON(hlid == WL12XX_INVALID_LINK_ID ||
		    is_zero_ether_addr(addr)))
		return;

	rcu_read_lock();
	sta = ieee80211_find_sta(vif, addr);
	if (sta)
		wlcore_save_freed_pkts(wl, wlvif, hlid, sta);
	rcu_read_unlock();
}

static void wlcore_print_recovery(struct wl1271 *wl)
{
	u32 pc = 0;
@@ -961,6 +996,13 @@ static void wl1271_recovery_work(struct work_struct *work)
		wlvif = list_first_entry(&wl->wlvif_list,
				       struct wl12xx_vif, list);
		vif = wl12xx_wlvif_to_vif(wlvif);

		if (wlvif->bss_type == BSS_TYPE_STA_BSS &&
		    test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) {
			wlcore_save_freed_pkts_addr(wl, wlvif, wlvif->sta.hlid,
						    vif->bss_conf.bssid);
		}

		__wl1271_op_remove_interface(wl, vif, false);
	}

@@ -4703,10 +4745,6 @@ static int wl1271_allocate_sta(struct wl1271 *wl,

void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid)
{
	struct wl1271_station *wl_sta;
	struct ieee80211_sta *sta;
	struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);

	if (!test_bit(hlid, wlvif->ap.sta_hlid_map))
		return;

@@ -4718,21 +4756,7 @@ void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid)
	 * save the last used PN in the private part of iee80211_sta,
	 * in case of recovery/suspend
	 */
	rcu_read_lock();
	sta = ieee80211_find_sta(vif, wl->links[hlid].addr);
	if (sta) {
		wl_sta = (void *)sta->drv_priv;
		wl_sta->total_freed_pkts = wl->links[hlid].total_freed_pkts;

		/*
		 * increment the initial seq number on recovery to account for
		 * transmitted packets that we haven't yet got in the FW status
		 */
		if (test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags))
			wl_sta->total_freed_pkts +=
					WL1271_TX_SQN_POST_RECOVERY_PADDING;
	}
	rcu_read_unlock();
	wlcore_save_freed_pkts_addr(wl, wlvif, hlid, wl->links[hlid].addr);

	wl12xx_free_link(wl, wlvif, &hlid);
	wl->active_sta_count--;
@@ -4915,6 +4939,21 @@ static int wl12xx_update_sta_state(struct wl1271 *wl,
		clear_bit(WLVIF_FLAG_STA_STATE_SENT, &wlvif->flags);
	}

	/* save seq number on disassoc (suspend) */
	if (is_sta &&
	    old_state == IEEE80211_STA_ASSOC &&
	    new_state == IEEE80211_STA_AUTH) {
		wlcore_save_freed_pkts(wl, wlvif, wlvif->sta.hlid, sta);
		wlvif->total_freed_pkts = 0;
	}

	/* restore seq number on assoc (resume) */
	if (is_sta &&
	    old_state == IEEE80211_STA_AUTH &&
	    new_state == IEEE80211_STA_ASSOC) {
		wlvif->total_freed_pkts = wl_sta->total_freed_pkts;
	}

	/* clear ROCs on failure or authorization */
	if (is_sta &&
	    (new_state == IEEE80211_STA_AUTHORIZED ||
+8 −9
Original line number Diff line number Diff line
@@ -324,6 +324,7 @@ struct wl1271_station {
	 * total freed FW packets on the link to the STA - used for tracking the
	 * AES/TKIP PN across recoveries. Re-initialized each time from the
	 * wl1271_station structure.
	 * Used in both AP and STA mode.
	 */
	u64 total_freed_pkts;
};
@@ -459,6 +460,13 @@ struct wl12xx_vif {
	/* work for canceling ROC after pending auth reply */
	struct delayed_work pending_auth_complete_work;

	/*
	 * total freed FW packets on the link.
	 * For STA this holds the PN of the link to the AP.
	 * For AP this holds the PN of the broadcast link.
	 */
	u64 total_freed_pkts;

	/*
	 * This struct must be last!
	 * data that has to be saved acrossed reconfigs (e.g. recovery)
@@ -466,15 +474,6 @@ struct wl12xx_vif {
	 */
	struct {
		u8 persistent[0];

		/*
		 * total freed FW packets on the link - used for
		 * storing the AES/TKIP PN during recovery, as this
		 * structure is not zeroed out.
		 * For STA this holds the PN of the link to the AP.
		 * For AP this holds the PN of the broadcast link.
		 */
		u64 total_freed_pkts;
	};
};