Commit 84226ca1 authored by Gregory Greenman's avatar Gregory Greenman Committed by Luca Coelho
Browse files

iwlwifi: mvm: support offload of AMSDU rate control



Support the new APIs and activate AMSDU based on the
offloaded TLC decisions.

Signed-off-by: default avatarSara Sharon <sara.sharon@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent cf58c9e0
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -92,6 +92,11 @@ enum iwl_data_path_subcmd_ids {
	 */
	TLC_MNG_NOTIF_REQ_CMD = 0x10,

	/**
	 * @TLC_MNG_AMSDU_ENABLE_NOTIF: &struct iwl_tlc_amsdu_notif
	 */
	TLC_MNG_AMSDU_ENABLE_NOTIF = 0xF6,

	/**
	 * @TLC_MNG_UPDATE_NOTIF: &struct iwl_tlc_update_notif
	 */
+16 −2
Original line number Diff line number Diff line
@@ -205,7 +205,7 @@ enum iwl_tlc_mng_ht_rates {
 * @non_ht_supp_rates: bitmap of supported legacy rates
 * @ht_supp_rates: bitmap of supported HT/VHT rates, valid bits are 0-9
 * @mode: &enum iwl_tlc_mng_cfg_mode
 * @reserved2: reserved
 * @amsdu: TX amsdu is supported
 * @he_supp_rates: bitmap of supported HE rates
 * @sgi_ch_width_supp: bitmap of SGI support per channel width
 * @he_gi_support: 11ax HE guard interval
@@ -222,13 +222,27 @@ struct iwl_tlc_config_cmd {
	__le16 non_ht_supp_rates;
	__le16 ht_supp_rates[MAX_RS_ANT_NUM];
	u8 mode;
	u8 reserved2;
	u8 amsdu;
	__le16 he_supp_rates;
	u8 sgi_ch_width_supp;
	u8 he_gi_support;
	__le32 max_ampdu_cnt;
} __packed; /* TLC_MNG_CONFIG_CMD_API_S_VER_1 */

/**
 * struct iwl_tlc_amsdu_notif - TLC AMSDU configuration
 * @sta_id: station id
 * @reserved: reserved
 * @amsdu_size: Max AMSDU size, in bytes
 * @amsdu_enabled: bitmap for per-TID AMSDU enablement
 */
struct iwl_tlc_amsdu_notif {
	u8 sta_id;
	u8 reserved[3];
	__le16 amsdu_size;
	__le16 amsdu_enabled;
} __packed; /* TLC_MNG_AMSDU_ENABLE_NTFY_API_S_VER_1 */

#define IWL_TLC_NOTIF_INIT_RATE_POS 0
#define IWL_TLC_NOTIF_INIT_RATE_MSK BIT(IWL_TLC_NOTIF_INIT_RATE_POS)
#define IWL_TLC_NOTIF_REQ_INTERVAL (500)
+6 −2
Original line number Diff line number Diff line
@@ -250,6 +250,9 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
	RX_HANDLER(TX_CMD, iwl_mvm_rx_tx_cmd, RX_HANDLER_SYNC),
	RX_HANDLER(BA_NOTIF, iwl_mvm_rx_ba_notif, RX_HANDLER_SYNC),

	RX_HANDLER_GRP(DATA_PATH_GROUP, TLC_MNG_UPDATE_NOTIF,
		       iwl_mvm_tlc_update_notif, RX_HANDLER_SYNC),

	RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif,
		   RX_HANDLER_ASYNC_LOCKED),
	RX_HANDLER(BEACON_NOTIFICATION, iwl_mvm_rx_beacon_notif,
@@ -309,6 +312,8 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
		       iwl_mvm_mu_mimo_grp_notif, RX_HANDLER_SYNC),
	RX_HANDLER_GRP(DATA_PATH_GROUP, STA_PM_NOTIF,
		       iwl_mvm_sta_pm_notif, RX_HANDLER_SYNC),
	RX_HANDLER_GRP(DATA_PATH_GROUP, TLC_MNG_AMSDU_ENABLE_NOTIF,
		       iwl_mvm_tlc_amsdu_notif, RX_HANDLER_SYNC),
};
#undef RX_HANDLER
#undef RX_HANDLER_GRP
@@ -445,6 +450,7 @@ static const struct iwl_hcmd_names iwl_mvm_data_path_names[] = {
	HCMD_NAME(DQA_ENABLE_CMD),
	HCMD_NAME(UPDATE_MU_GROUPS_CMD),
	HCMD_NAME(TRIGGER_RX_QUEUES_NOTIF_CMD),
	HCMD_NAME(TLC_MNG_AMSDU_ENABLE_NOTIF),
	HCMD_NAME(STA_PM_NOTIF),
	HCMD_NAME(MU_GROUP_MGMT_NOTIF),
	HCMD_NAME(RX_QUEUES_NOTIFICATION),
@@ -1034,8 +1040,6 @@ static void iwl_mvm_rx_mq(struct iwl_op_mode *op_mode,
		iwl_mvm_rx_queue_notif(mvm, rxb, 0);
	else if (cmd == WIDE_ID(LEGACY_GROUP, FRAME_RELEASE))
		iwl_mvm_rx_frame_release(mvm, napi, rxb, 0);
	else if (cmd == WIDE_ID(DATA_PATH_GROUP, TLC_MNG_UPDATE_NOTIF))
		iwl_mvm_tlc_update_notif(mvm, pkt);
	else
		iwl_mvm_rx_common(mvm, rxb, pkt);
}
+41 −1
Original line number Diff line number Diff line
@@ -228,8 +228,47 @@ static void rs_fw_tlc_mng_notif_req_config(struct iwl_mvm *mvm, u8 sta_id)
		IWL_ERR(mvm, "Failed to send TLC notif request (%d)\n", ret);
}

void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm, struct iwl_rx_packet *pkt)
void iwl_mvm_tlc_amsdu_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
{
	struct iwl_rx_packet *pkt = rxb_addr(rxb);
	struct iwl_tlc_amsdu_notif *notif;
	struct ieee80211_sta *sta;
	struct iwl_mvm_sta *mvmsta;
	u16 size;

	notif = (void *)pkt->data;

	if (WARN_ON(notif->sta_id >= ARRAY_SIZE(mvm->fw_id_to_mac_id)))
		return;

	rcu_read_lock();

	sta = rcu_dereference(mvm->fw_id_to_mac_id[notif->sta_id]);
	if (IS_ERR_OR_NULL(sta)) {
		rcu_read_unlock();
		IWL_ERR(mvm, "Invalid sta id (%d) in FW TLC notification\n",
			notif->sta_id);
		return;
	}

	mvmsta = iwl_mvm_sta_from_mac80211(sta);

	size = min(le16_to_cpu(notif->amsdu_size), sta->max_amsdu_len);
	mvmsta->amsdu_enabled = le16_to_cpu(notif->amsdu_enabled);
	mvmsta->max_amsdu_len = size;

	IWL_DEBUG_RATE(mvm,
		       "AMSDU notification. AMSDU size: %d, AMSDU selected size: %d, AMSDU TID bitmap 0x%X\n",
		       le16_to_cpu(notif->amsdu_size), size,
		       mvmsta->amsdu_enabled);

	rcu_read_unlock();
};

void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm,
			      struct iwl_rx_cmd_buffer *rxb)
{
	struct iwl_rx_packet *pkt = rxb_addr(rxb);
	struct iwl_tlc_update_notif *notif;
	struct iwl_mvm_sta *mvmsta;
	struct iwl_lq_sta_rs_fw *lq_sta;
@@ -273,6 +312,7 @@ void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
		.max_supp_ss = sta->rx_nss,
		.max_ampdu_cnt = cpu_to_le32(mvmsta->max_agg_bufsize),
		.sgi_ch_width_supp = rs_fw_sgi_cw_support(sta),
		.amsdu = iwl_mvm_is_csum_supported(mvm),
	};
	int ret;

+11 −4
Original line number Diff line number Diff line
@@ -1715,12 +1715,18 @@ 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);

	/*
	 * In case TLC offload is not active amsdu_enabled is either 0xFFFF
	 * or 0, since there is no per-TID alg.
	 */
	if ((!is_vht(&tbl->rate) && !is_ht(&tbl->rate)) ||
	    tbl->rate.index < IWL_RATE_MCS_5_INDEX ||
	    scale_action == RS_ACTION_DOWNSCALE)
		mvmsta->tlc_amsdu = false;
		mvmsta->amsdu_enabled = 0;
	else
		mvmsta->tlc_amsdu = true;
		mvmsta->amsdu_enabled = 0xFFFF;

	mvmsta->max_amsdu_len = sta->max_amsdu_len;
}

/*
@@ -3134,7 +3140,8 @@ static void rs_drv_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
	sband = hw->wiphy->bands[band];

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

	for (j = 0; j < LQ_SIZE; j++)
		rs_rate_scale_clear_tbl_windows(mvm, &lq_sta->lq_info[j]);
@@ -3744,7 +3751,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
				(rate->sgi) ? "SGI" : "NGI",
				(rate->ldpc) ? "LDPC" : "BCC",
				(lq_sta->is_agg) ? "AGG on" : "",
				(mvmsta->tlc_amsdu) ? "AMSDU on" : "");
				(mvmsta->amsdu_enabled) ? "AMSDU on" : "");
	}
	desc += scnprintf(buff + desc, bufsz - desc, "last tx rate=0x%X\n",
			lq_sta->last_rate_n_flags);
Loading