mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 21:24:08 +08:00
Four fixes:
* CRYPTO_SHA256 is needed for regdb validation * mac80211: mesh path metric was wrong in some frames * mac80211: use QoS null-data packets on QoS connections * mac80211: tear down RX aggregation sessions first to drop fewer packets in HW restart scenarios -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEH1e1rEeCd0AIMq6MB8qZga/fl8QFAlob6QMACgkQB8qZga/f l8SAvw/9E4fttLsdBhUT1gUJPoeNWsSXyhdoo0QWHs4Ni//bayNUL/Wx8QL6MGf/ nprgxDygqFXH5iUO2gwpaMl2xeO1N7Px7bpKV/KvrDX/UAaEDyrkg6B87Omx95vT i584pU0LwLVL40CT+saKpF+kChe3S/rMPrAQR0xBNPntyIlo9w0vdOkdTC+vw0br /Nl3YJxpAmOmTDa8tiKLWHg4hSIS3Q7stylUjnEKNev4nBjBaPqfBW6sy/3o4NiR MfSCNvGeipr0QFZT31cHDry1fRZ/RvD23KSYNMggzctpYf6IRuHSEhIS3mW7GLpd GKZyLa7G7mZJAKXJAXOxb2PBBrXl/nTqSHJfme0VroGsYdqLHThXd47/0qaAB4Oo Io84WSmQX41kRyy4KNU7z0OFR9RgLbctdW/hwGeODxKEagGNNjuz+lbzql7jtYLn 8UZK3LZHYC+qribCHR4Uf6A5rJP7bAcl36Ub/8l7AXNVesLagiaE0FGGrewGnE6X 6qQLoYznd4/bjLQLVou56R9/t+o1nUuvmcGMkRxAlhvX3hw5nSUxgkWS/TgCdrBg cKddmM78AfEakjd6e21bH2QI2tG6fXS913lwIOq9JU870yVlNpUEr98t5nwYNP3P l5kzxr237Yj4W9LMUmeZIWo/laiAtgYEeQZAynAZWNxXNBdOvaA= =ODX1 -----END PGP SIGNATURE----- Merge tag 'mac80211-for-davem-2017-11-27' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211 Johannes Berg says: ==================== Four fixes: * CRYPTO_SHA256 is needed for regdb validation * mac80211: mesh path metric was wrong in some frames * mac80211: use QoS null-data packets on QoS connections * mac80211: tear down RX aggregation sessions first to drop fewer packets in HW restart scenarios ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
d3fe1e0185
@ -1113,7 +1113,7 @@ ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp,
|
||||
if (!avp->assoc)
|
||||
return false;
|
||||
|
||||
skb = ieee80211_nullfunc_get(sc->hw, vif);
|
||||
skb = ieee80211_nullfunc_get(sc->hw, vif, false);
|
||||
if (!skb)
|
||||
return false;
|
||||
|
||||
|
@ -198,7 +198,7 @@ void __cw1200_cqm_bssloss_sm(struct cw1200_common *priv,
|
||||
|
||||
priv->bss_loss_state++;
|
||||
|
||||
skb = ieee80211_nullfunc_get(priv->hw, priv->vif);
|
||||
skb = ieee80211_nullfunc_get(priv->hw, priv->vif, false);
|
||||
WARN_ON(!skb);
|
||||
if (skb)
|
||||
cw1200_tx(priv->hw, NULL, skb);
|
||||
@ -2265,7 +2265,7 @@ static int cw1200_upload_null(struct cw1200_common *priv)
|
||||
.rate = 0xFF,
|
||||
};
|
||||
|
||||
frame.skb = ieee80211_nullfunc_get(priv->hw, priv->vif);
|
||||
frame.skb = ieee80211_nullfunc_get(priv->hw, priv->vif, false);
|
||||
if (!frame.skb)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -566,7 +566,7 @@ static int wl1251_build_null_data(struct wl1251 *wl)
|
||||
size = sizeof(struct wl12xx_null_data_template);
|
||||
ptr = NULL;
|
||||
} else {
|
||||
skb = ieee80211_nullfunc_get(wl->hw, wl->vif);
|
||||
skb = ieee80211_nullfunc_get(wl->hw, wl->vif, false);
|
||||
if (!skb)
|
||||
goto out;
|
||||
size = skb->len;
|
||||
|
@ -1069,7 +1069,8 @@ int wl12xx_cmd_build_null_data(struct wl1271 *wl, struct wl12xx_vif *wlvif)
|
||||
ptr = NULL;
|
||||
} else {
|
||||
skb = ieee80211_nullfunc_get(wl->hw,
|
||||
wl12xx_wlvif_to_vif(wlvif));
|
||||
wl12xx_wlvif_to_vif(wlvif),
|
||||
false);
|
||||
if (!skb)
|
||||
goto out;
|
||||
size = skb->len;
|
||||
@ -1096,7 +1097,7 @@ int wl12xx_cmd_build_klv_null_data(struct wl1271 *wl,
|
||||
struct sk_buff *skb = NULL;
|
||||
int ret = -ENOMEM;
|
||||
|
||||
skb = ieee80211_nullfunc_get(wl->hw, vif);
|
||||
skb = ieee80211_nullfunc_get(wl->hw, vif, false);
|
||||
if (!skb)
|
||||
goto out;
|
||||
|
||||
|
@ -4470,18 +4470,24 @@ struct sk_buff *ieee80211_pspoll_get(struct ieee80211_hw *hw,
|
||||
* ieee80211_nullfunc_get - retrieve a nullfunc template
|
||||
* @hw: pointer obtained from ieee80211_alloc_hw().
|
||||
* @vif: &struct ieee80211_vif pointer from the add_interface callback.
|
||||
* @qos_ok: QoS NDP is acceptable to the caller, this should be set
|
||||
* if at all possible
|
||||
*
|
||||
* Creates a Nullfunc template which can, for example, uploaded to
|
||||
* hardware. The template must be updated after association so that correct
|
||||
* BSSID and address is used.
|
||||
*
|
||||
* If @qos_ndp is set and the association is to an AP with QoS/WMM, the
|
||||
* returned packet will be QoS NDP.
|
||||
*
|
||||
* Note: Caller (or hardware) is responsible for setting the
|
||||
* &IEEE80211_FCTL_PM bit as well as Duration and Sequence Control fields.
|
||||
*
|
||||
* Return: The nullfunc template. %NULL on error.
|
||||
*/
|
||||
struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif);
|
||||
struct ieee80211_vif *vif,
|
||||
bool qos_ok);
|
||||
|
||||
/**
|
||||
* ieee80211_probereq_get - retrieve a Probe Request template
|
||||
|
@ -292,7 +292,6 @@ void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta,
|
||||
|
||||
mutex_lock(&sta->ampdu_mlme.mtx);
|
||||
for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
|
||||
___ieee80211_stop_tx_ba_session(sta, i, reason);
|
||||
___ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT,
|
||||
WLAN_REASON_QSTA_LEAVE_QBSS,
|
||||
reason != AGG_STOP_DESTROY_STA &&
|
||||
@ -300,6 +299,9 @@ void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta,
|
||||
}
|
||||
mutex_unlock(&sta->ampdu_mlme.mtx);
|
||||
|
||||
for (i = 0; i < IEEE80211_NUM_TIDS; i++)
|
||||
___ieee80211_stop_tx_ba_session(sta, i, reason);
|
||||
|
||||
/* stopping might queue the work again - so cancel only afterwards */
|
||||
cancel_work_sync(&sta->ampdu_mlme.work);
|
||||
|
||||
|
@ -797,7 +797,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
|
||||
struct mesh_path *mpath;
|
||||
u8 ttl, flags, hopcount;
|
||||
const u8 *orig_addr;
|
||||
u32 orig_sn, metric, metric_txsta, interval;
|
||||
u32 orig_sn, new_metric, orig_metric, last_hop_metric, interval;
|
||||
bool root_is_gate;
|
||||
|
||||
ttl = rann->rann_ttl;
|
||||
@ -808,7 +808,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
|
||||
interval = le32_to_cpu(rann->rann_interval);
|
||||
hopcount = rann->rann_hopcount;
|
||||
hopcount++;
|
||||
metric = le32_to_cpu(rann->rann_metric);
|
||||
orig_metric = le32_to_cpu(rann->rann_metric);
|
||||
|
||||
/* Ignore our own RANNs */
|
||||
if (ether_addr_equal(orig_addr, sdata->vif.addr))
|
||||
@ -825,7 +825,10 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
|
||||
return;
|
||||
}
|
||||
|
||||
metric_txsta = airtime_link_metric_get(local, sta);
|
||||
last_hop_metric = airtime_link_metric_get(local, sta);
|
||||
new_metric = orig_metric + last_hop_metric;
|
||||
if (new_metric < orig_metric)
|
||||
new_metric = MAX_METRIC;
|
||||
|
||||
mpath = mesh_path_lookup(sdata, orig_addr);
|
||||
if (!mpath) {
|
||||
@ -838,7 +841,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
|
||||
}
|
||||
|
||||
if (!(SN_LT(mpath->sn, orig_sn)) &&
|
||||
!(mpath->sn == orig_sn && metric < mpath->rann_metric)) {
|
||||
!(mpath->sn == orig_sn && new_metric < mpath->rann_metric)) {
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
@ -856,7 +859,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
|
||||
}
|
||||
|
||||
mpath->sn = orig_sn;
|
||||
mpath->rann_metric = metric + metric_txsta;
|
||||
mpath->rann_metric = new_metric;
|
||||
mpath->is_root = true;
|
||||
/* Recording RANNs sender address to send individually
|
||||
* addressed PREQs destined for root mesh STA */
|
||||
@ -876,7 +879,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
|
||||
mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr,
|
||||
orig_sn, 0, NULL, 0, broadcast_addr,
|
||||
hopcount, ttl, interval,
|
||||
metric + metric_txsta, 0, sdata);
|
||||
new_metric, 0, sdata);
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
|
@ -895,7 +895,7 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local,
|
||||
struct ieee80211_hdr_3addr *nullfunc;
|
||||
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
||||
|
||||
skb = ieee80211_nullfunc_get(&local->hw, &sdata->vif);
|
||||
skb = ieee80211_nullfunc_get(&local->hw, &sdata->vif, true);
|
||||
if (!skb)
|
||||
return;
|
||||
|
||||
|
@ -4438,13 +4438,15 @@ struct sk_buff *ieee80211_pspoll_get(struct ieee80211_hw *hw,
|
||||
EXPORT_SYMBOL(ieee80211_pspoll_get);
|
||||
|
||||
struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif)
|
||||
struct ieee80211_vif *vif,
|
||||
bool qos_ok)
|
||||
{
|
||||
struct ieee80211_hdr_3addr *nullfunc;
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
struct ieee80211_if_managed *ifmgd;
|
||||
struct ieee80211_local *local;
|
||||
struct sk_buff *skb;
|
||||
bool qos = false;
|
||||
|
||||
if (WARN_ON(vif->type != NL80211_IFTYPE_STATION))
|
||||
return NULL;
|
||||
@ -4453,7 +4455,17 @@ struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,
|
||||
ifmgd = &sdata->u.mgd;
|
||||
local = sdata->local;
|
||||
|
||||
skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*nullfunc));
|
||||
if (qos_ok) {
|
||||
struct sta_info *sta;
|
||||
|
||||
rcu_read_lock();
|
||||
sta = sta_info_get(sdata, ifmgd->bssid);
|
||||
qos = sta && sta->sta.wme;
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
skb = dev_alloc_skb(local->hw.extra_tx_headroom +
|
||||
sizeof(*nullfunc) + 2);
|
||||
if (!skb)
|
||||
return NULL;
|
||||
|
||||
@ -4463,6 +4475,19 @@ struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,
|
||||
nullfunc->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
|
||||
IEEE80211_STYPE_NULLFUNC |
|
||||
IEEE80211_FCTL_TODS);
|
||||
if (qos) {
|
||||
__le16 qos = cpu_to_le16(7);
|
||||
|
||||
BUILD_BUG_ON((IEEE80211_STYPE_QOS_NULLFUNC |
|
||||
IEEE80211_STYPE_NULLFUNC) !=
|
||||
IEEE80211_STYPE_QOS_NULLFUNC);
|
||||
nullfunc->frame_control |=
|
||||
cpu_to_le16(IEEE80211_STYPE_QOS_NULLFUNC);
|
||||
skb->priority = 7;
|
||||
skb_set_queue_mapping(skb, IEEE80211_AC_VO);
|
||||
skb_put_data(skb, &qos, sizeof(qos));
|
||||
}
|
||||
|
||||
memcpy(nullfunc->addr1, ifmgd->bssid, ETH_ALEN);
|
||||
memcpy(nullfunc->addr2, vif->addr, ETH_ALEN);
|
||||
memcpy(nullfunc->addr3, ifmgd->bssid, ETH_ALEN);
|
||||
|
@ -20,6 +20,10 @@ config CFG80211
|
||||
tristate "cfg80211 - wireless configuration API"
|
||||
depends on RFKILL || !RFKILL
|
||||
select FW_LOADER
|
||||
# may need to update this when certificates are changed and are
|
||||
# using a different algorithm, though right now they shouldn't
|
||||
# (this is here rather than below to allow it to be a module)
|
||||
select CRYPTO_SHA256 if CFG80211_USE_KERNEL_REGDB_KEYS
|
||||
---help---
|
||||
cfg80211 is the Linux wireless LAN (802.11) configuration API.
|
||||
Enable this if you have a wireless device.
|
||||
@ -113,6 +117,9 @@ config CFG80211_EXTRA_REGDB_KEYDIR
|
||||
certificates like in the kernel sources (net/wireless/certs/)
|
||||
that shall be accepted for a signed regulatory database.
|
||||
|
||||
Note that you need to also select the correct CRYPTO_<hash> modules
|
||||
for your certificates, and if cfg80211 is built-in they also must be.
|
||||
|
||||
config CFG80211_REG_CELLULAR_HINTS
|
||||
bool "cfg80211 regulatory support for cellular base station hints"
|
||||
depends on CFG80211_CERTIFICATION_ONUS
|
||||
|
Loading…
Reference in New Issue
Block a user