Commit ad125c6c authored by David S. Miller's avatar David S. Miller
Browse files

Merge tag 'mac80211-for-net-2019-10-16' of...

Merge tag 'mac80211-for-net-2019-10-16' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211



Johannes Berg says:

====================
A handful of fixes:
 * disable AQL on most drivers, addressing the iwlwifi issues
 * fix double-free on network namespace changes
 * fix TID field in frames injected through monitor interfaces
 * fix ieee80211_calc_rx_airtime()
 * fix NULL pointer dereference in rfkill (and remove BUG_ON)
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 95bed1a9 6fc232db
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -8958,6 +8958,7 @@ int ath10k_mac_register(struct ath10k *ar)
	wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
	wiphy_ext_feature_set(ar->hw->wiphy,
			      NL80211_EXT_FEATURE_SET_SCAN_DWELL);
	wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_AQL);

	if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI, ar->wmi.svc_map) ||
	    test_bit(WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS, ar->wmi.svc_map))
+5 −0
Original line number Diff line number Diff line
@@ -5517,6 +5517,10 @@ enum nl80211_feature_flags {
 *	with VLAN tagged frames and separate VLAN-specific netdevs added using
 *	vconfig similarly to the Ethernet case.
 *
 * @NL80211_EXT_FEATURE_AQL: The driver supports the Airtime Queue Limit (AQL)
 *	feature, which prevents bufferbloat by using the expected transmission
 *	time to limit the amount of data buffered in the hardware.
 *
 * @NUM_NL80211_EXT_FEATURES: number of extended features.
 * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
 */
@@ -5563,6 +5567,7 @@ enum nl80211_ext_feature_index {
	NL80211_EXT_FEATURE_STA_TX_PWR,
	NL80211_EXT_FEATURE_SAE_OFFLOAD,
	NL80211_EXT_FEATURE_VLAN_OFFLOAD,
	NL80211_EXT_FEATURE_AQL,

	/* add new features before the definition below */
	NUM_NL80211_EXT_FEATURES,
+1 −1
Original line number Diff line number Diff line
@@ -442,7 +442,7 @@ u32 ieee80211_calc_rx_airtime(struct ieee80211_hw *hw,
			return 0;

		sband = hw->wiphy->bands[status->band];
		if (!sband || status->rate_idx > sband->n_bitrates)
		if (!sband || status->rate_idx >= sband->n_bitrates)
			return 0;

		rate = &sband->bitrates[status->rate_idx];
+58 −18
Original line number Diff line number Diff line
@@ -201,8 +201,6 @@ static ssize_t sta_airtime_read(struct file *file, char __user *userbuf,
	char *buf = kzalloc(bufsz, GFP_KERNEL), *p = buf;
	u64 rx_airtime = 0, tx_airtime = 0;
	s64 deficit[IEEE80211_NUM_ACS];
	u32 q_depth[IEEE80211_NUM_ACS];
	u32 q_limit_l[IEEE80211_NUM_ACS], q_limit_h[IEEE80211_NUM_ACS];
	ssize_t rv;
	int ac;

@@ -214,6 +212,56 @@ static ssize_t sta_airtime_read(struct file *file, char __user *userbuf,
		rx_airtime += sta->airtime[ac].rx_airtime;
		tx_airtime += sta->airtime[ac].tx_airtime;
		deficit[ac] = sta->airtime[ac].deficit;
		spin_unlock_bh(&local->active_txq_lock[ac]);
	}

	p += scnprintf(p, bufsz + buf - p,
		"RX: %llu us\nTX: %llu us\nWeight: %u\n"
		"Deficit: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n",
		rx_airtime, tx_airtime, sta->airtime_weight,
		deficit[0], deficit[1], deficit[2], deficit[3]);

	rv = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
	kfree(buf);
	return rv;
}

static ssize_t sta_airtime_write(struct file *file, const char __user *userbuf,
				 size_t count, loff_t *ppos)
{
	struct sta_info *sta = file->private_data;
	struct ieee80211_local *local = sta->sdata->local;
	int ac;

	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
		spin_lock_bh(&local->active_txq_lock[ac]);
		sta->airtime[ac].rx_airtime = 0;
		sta->airtime[ac].tx_airtime = 0;
		sta->airtime[ac].deficit = sta->airtime_weight;
		spin_unlock_bh(&local->active_txq_lock[ac]);
	}

	return count;
}
STA_OPS_RW(airtime);

static ssize_t sta_aql_read(struct file *file, char __user *userbuf,
				size_t count, loff_t *ppos)
{
	struct sta_info *sta = file->private_data;
	struct ieee80211_local *local = sta->sdata->local;
	size_t bufsz = 400;
	char *buf = kzalloc(bufsz, GFP_KERNEL), *p = buf;
	u32 q_depth[IEEE80211_NUM_ACS];
	u32 q_limit_l[IEEE80211_NUM_ACS], q_limit_h[IEEE80211_NUM_ACS];
	ssize_t rv;
	int ac;

	if (!buf)
		return -ENOMEM;

	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
		spin_lock_bh(&local->active_txq_lock[ac]);
		q_limit_l[ac] = sta->airtime[ac].aql_limit_low;
		q_limit_h[ac] = sta->airtime[ac].aql_limit_high;
		spin_unlock_bh(&local->active_txq_lock[ac]);
@@ -221,12 +269,8 @@ static ssize_t sta_airtime_read(struct file *file, char __user *userbuf,
	}

	p += scnprintf(p, bufsz + buf - p,
		"RX: %llu us\nTX: %llu us\nWeight: %u\n"
		"Deficit: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n"
		"Q depth: VO: %u us VI: %u us BE: %u us BK: %u us\n"
		"Q limit[low/high]: VO: %u/%u VI: %u/%u BE: %u/%u BK: %u/%u\n",
		rx_airtime, tx_airtime, sta->airtime_weight,
		deficit[0], deficit[1], deficit[2], deficit[3],
		q_depth[0], q_depth[1], q_depth[2], q_depth[3],
		q_limit_l[0], q_limit_h[0], q_limit_l[1], q_limit_h[1],
		q_limit_l[2], q_limit_h[2], q_limit_l[3], q_limit_h[3]),
@@ -236,11 +280,10 @@ static ssize_t sta_airtime_read(struct file *file, char __user *userbuf,
	return rv;
}

static ssize_t sta_airtime_write(struct file *file, const char __user *userbuf,
static ssize_t sta_aql_write(struct file *file, const char __user *userbuf,
				 size_t count, loff_t *ppos)
{
	struct sta_info *sta = file->private_data;
	struct ieee80211_local *local = sta->sdata->local;
	u32 ac, q_limit_l, q_limit_h;
	char _buf[100] = {}, *buf = _buf;

@@ -251,7 +294,7 @@ static ssize_t sta_airtime_write(struct file *file, const char __user *userbuf,
		return -EFAULT;

	buf[sizeof(_buf) - 1] = '\0';
	if (sscanf(buf, "queue limit %u %u %u", &ac, &q_limit_l, &q_limit_h)
	if (sscanf(buf, "limit %u %u %u", &ac, &q_limit_l, &q_limit_h)
	    != 3)
		return -EINVAL;

@@ -261,17 +304,10 @@ static ssize_t sta_airtime_write(struct file *file, const char __user *userbuf,
	sta->airtime[ac].aql_limit_low = q_limit_l;
	sta->airtime[ac].aql_limit_high = q_limit_h;

	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
		spin_lock_bh(&local->active_txq_lock[ac]);
		sta->airtime[ac].rx_airtime = 0;
		sta->airtime[ac].tx_airtime = 0;
		sta->airtime[ac].deficit = sta->airtime_weight;
		spin_unlock_bh(&local->active_txq_lock[ac]);
	}

	return count;
}
STA_OPS_RW(airtime);
STA_OPS_RW(aql);


static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
					size_t count, loff_t *ppos)
@@ -996,6 +1032,10 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
				    NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
		DEBUGFS_ADD(airtime);

	if (wiphy_ext_feature_isset(local->hw.wiphy,
				    NL80211_EXT_FEATURE_AQL))
		DEBUGFS_ADD(aql);

	debugfs_create_xul("driver_buffered_tids", 0400, sta->debugfs_dir,
			   &sta->driver_buffered_tids);

+1 −3
Original line number Diff line number Diff line
@@ -672,9 +672,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
			IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H;
	}

	local->airtime_flags = AIRTIME_USE_TX |
			       AIRTIME_USE_RX |
			       AIRTIME_USE_AQL;
	local->airtime_flags = AIRTIME_USE_TX | AIRTIME_USE_RX;
	local->aql_threshold = IEEE80211_AQL_THRESHOLD;
	atomic_set(&local->aql_total_pending_airtime, 0);

Loading