Commit 4c51541d authored by Benjamin Berg's avatar Benjamin Berg Committed by Johannes Berg
Browse files

wifi: mac80211: keep A-MSDU data in sta and per-link



The A-MSDU data needs to be stored per-link and aggregated into a single
value for the station. Add a new struct ieee_80211_sta_aggregates in
order to store this data and a new function
ieee80211_sta_recalc_aggregates to update the current data for the STA.

Note that in the non MLO case the pointer in ieee80211_sta will directly
reference the data in deflink.agg, which means that recalculation may be
skipped in that case.

Signed-off-by: default avatarBenjamin Berg <benjamin.berg@intel.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 189a0c52
Loading
Loading
Loading
Loading
+8 −6
Original line number Diff line number Diff line
@@ -430,14 +430,16 @@ static ssize_t iwl_dbgfs_amsdu_len_write(struct ieee80211_sta *sta,
		return -EBUSY;

	if (amsdu_len) {
		mvmsta->orig_amsdu_len = sta->max_amsdu_len;
		sta->max_amsdu_len = amsdu_len;
		for (i = 0; i < ARRAY_SIZE(sta->max_tid_amsdu_len); i++)
			sta->max_tid_amsdu_len[i] = amsdu_len;
		mvmsta->orig_amsdu_len = sta->cur->max_amsdu_len;
		sta->deflink.agg.max_amsdu_len = amsdu_len;
		sta->deflink.agg.max_amsdu_len = amsdu_len;
		for (i = 0; i < ARRAY_SIZE(sta->deflink.agg.max_tid_amsdu_len); i++)
			sta->deflink.agg.max_tid_amsdu_len[i] = amsdu_len;
	} else {
		sta->max_amsdu_len = mvmsta->orig_amsdu_len;
		sta->deflink.agg.max_amsdu_len = mvmsta->orig_amsdu_len;
		mvmsta->orig_amsdu_len = 0;
	}

	return count;
}

@@ -451,7 +453,7 @@ static ssize_t iwl_dbgfs_amsdu_len_read(struct file *file,
	char buf[32];
	int pos;

	pos = scnprintf(buf, sizeof(buf), "current %d ", sta->max_amsdu_len);
	pos = scnprintf(buf, sizeof(buf), "current %d ", sta->cur->max_amsdu_len);
	pos += scnprintf(buf + pos, sizeof(buf) - pos, "stored %d\n",
			 mvmsta->orig_amsdu_len);

+1 −1
Original line number Diff line number Diff line
@@ -3193,7 +3193,7 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
						   NL80211_TDLS_SETUP);
		}

		sta->max_rc_amsdu_len = 1;
		sta->deflink.agg.max_rc_amsdu_len = 1;
	} else if (old_state == IEEE80211_STA_NONE &&
		   new_state == IEEE80211_STA_AUTH) {
		/*
+6 −6
Original line number Diff line number Diff line
@@ -340,9 +340,9 @@ void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm,
		u16 size = le32_to_cpu(notif->amsdu_size);
		int i;

		if (sta->max_amsdu_len < size) {
		if (sta->deflink.agg.max_amsdu_len < size) {
			/*
			 * In debug sta->max_amsdu_len < size
			 * In debug sta->deflink.agg.max_amsdu_len < size
			 * so also check with orig_amsdu_len which holds the
			 * original data before debugfs changed the value
			 */
@@ -352,18 +352,18 @@ void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm,

		mvmsta->amsdu_enabled = le32_to_cpu(notif->amsdu_enabled);
		mvmsta->max_amsdu_len = size;
		sta->max_rc_amsdu_len = mvmsta->max_amsdu_len;
		sta->deflink.agg.max_rc_amsdu_len = mvmsta->max_amsdu_len;

		for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
			if (mvmsta->amsdu_enabled & BIT(i))
				sta->max_tid_amsdu_len[i] =
				sta->deflink.agg.max_tid_amsdu_len[i] =
					iwl_mvm_max_amsdu_size(mvm, sta, i);
			else
				/*
				 * Not so elegant, but this will effectively
				 * prevent AMSDU on this TID
				 */
				sta->max_tid_amsdu_len[i] = 1;
				sta->deflink.agg.max_tid_amsdu_len[i] = 1;
		}

		IWL_DEBUG_RATE(mvm,
@@ -450,7 +450,7 @@ void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
	 * since TLC offload works with one mode we can assume
	 * that only vht/ht is used and also set it as station max amsdu
	 */
	sta->max_amsdu_len = max_amsdu_len;
	sta->deflink.agg.max_amsdu_len = max_amsdu_len;

	cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw,
					WIDE_ID(DATA_PATH_GROUP,
+8 −7
Original line number Diff line number Diff line
@@ -1491,7 +1491,7 @@ static void rs_set_amsdu_len(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
	struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
	int i;

	sta->max_amsdu_len = rs_fw_get_max_amsdu_len(sta);
	sta->deflink.agg.max_amsdu_len = rs_fw_get_max_amsdu_len(sta);

	/*
	 * In case TLC offload is not active amsdu_enabled is either 0xFFFF
@@ -1506,22 +1506,23 @@ static void rs_set_amsdu_len(struct iwl_mvm *mvm, struct ieee80211_sta *sta,

	if (mvmsta->vif->bss_conf.he_support &&
	    !iwlwifi_mod_params.disable_11ax)
		mvmsta->max_amsdu_len = sta->max_amsdu_len;
		mvmsta->max_amsdu_len = sta->deflink.agg.max_amsdu_len;
	else
		mvmsta->max_amsdu_len = min_t(int, sta->max_amsdu_len, 8500);
		mvmsta->max_amsdu_len =
			min_t(int, sta->deflink.agg.max_amsdu_len, 8500);

	sta->max_rc_amsdu_len = mvmsta->max_amsdu_len;
	sta->deflink.agg.max_rc_amsdu_len = mvmsta->max_amsdu_len;

	for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
		if (mvmsta->amsdu_enabled)
			sta->max_tid_amsdu_len[i] =
			sta->deflink.agg.max_tid_amsdu_len[i] =
				iwl_mvm_max_amsdu_size(mvm, sta, i);
		else
			/*
			 * Not so elegant, but this will effectively
			 * prevent AMSDU on this TID
			 */
			sta->max_tid_amsdu_len[i] = 1;
			sta->deflink.agg.max_tid_amsdu_len[i] = 1;
	}
}

@@ -2933,7 +2934,7 @@ static void rs_drv_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,

	lq_sta->lq.sta_id = mvmsta->sta_id;
	mvmsta->amsdu_enabled = 0;
	mvmsta->max_amsdu_len = sta->max_amsdu_len;
	mvmsta->max_amsdu_len = sta->cur->max_amsdu_len;

	for (j = 0; j < LQ_SIZE; j++)
		rs_rate_scale_clear_tbl_windows(mvm, &lq_sta->lq_info[j]);
+1 −1
Original line number Diff line number Diff line
@@ -926,7 +926,7 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb,
	 * Take the min of ieee80211 station and mvm station
	 */
	max_amsdu_len =
		min_t(unsigned int, sta->max_amsdu_len,
		min_t(unsigned int, sta->cur->max_amsdu_len,
		      iwl_mvm_max_amsdu_size(mvm, sta, tid));

	/*
Loading