mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 11:41:38 -04:00
This time we have too many changes to list, highlights:
* virt_wifi - wireless control simulation on top of
another network interface
* hwsim configurability to test capabilities similar
to real hardware
* various mesh improvements
* various radiotap vendor data fixes in mac80211
* finally the nl_set_extack_cookie_u64() we talked
about previously, used for
* peer measurement APIs, right now only with FTM
(flight time measurement) for location
* made nl80211 radio/interface announcements more complete
* various new HE (802.11ax) things:
updates, TWT support, ...
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEH1e1rEeCd0AIMq6MB8qZga/fl8QFAlwaCwkACgkQB8qZga/f
l8S7mA/+I1CJmGC7Pvy+SBFkzoY5zEjjzgZYL6sGo16qMs89NPcURSe5j+uCsDP3
nKEjsvhQMYDfGNLTJJfWbDpGwm9LnKp69AFITlvfzmP6Sm36QMZr7oIC4abi8cW4
osaO3qfdaNoZ//x72jgjrFhUAnphvT2BsRVMNEjz7sXcDd7Jm9NnpRhV8zgXFvLF
dS2Ng51LM/BLMz5jQpyJUDZeeL/iBYybCecyckmVqzXPh1icIZETSqZXiN4ngv2A
6p9BSGNtP6wmjnbkvZz5RDq76VhTPZWsTgTpVb45Wf1k2fm1rB96UgpqvfQtjTgB
+7Zx2WRpMXM5OjGkwaEs8nawFmt7MHCGnhLPLWPCbXc685fhp3OFShysMJdYS/GZ
IIRJ7+IchAQX1yluftB+NkQM9sBDjyseMBwxHRYkj/rQVhoLY1sT+ke7lkuV10o6
DQqfpUTZAsIz7zkuscn7hkNdI/Rjub6BZjbrs1Jt9zSt9WQUBao23XudOI0j5JDa
ErnfC5PISXMQWik5B9M1Zhq3H9qCI2Swh19lMmtxtSDQ9yrLrJkEJ5SA+aHoxNHj
wSxBc3XXSW47qPXGX/D5DNnbOcOrE7kVZuD8YqRsy8VedyjIgEw7oQ21flAD4FC4
R4TgbNkqpfZQsU29gaMkDkYXnfQDB/G9FOk6ARGxjBPjT55Hz0E=
=EpyK
-----END PGP SIGNATURE-----
Merge tag 'mac80211-next-for-davem-2018-12-19' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Johannes Berg says:
====================
This time we have too many changes to list, highlights:
* virt_wifi - wireless control simulation on top of
another network interface
* hwsim configurability to test capabilities similar
to real hardware
* various mesh improvements
* various radiotap vendor data fixes in mac80211
* finally the nl_set_extack_cookie_u64() we talked
about previously, used for
* peer measurement APIs, right now only with FTM
(flight time measurement) for location
* made nl80211 radio/interface announcements more complete
* various new HE (802.11ax) things:
updates, TWT support, ...
====================
Signed-off-by: David S. Miller <[email protected]>
This commit is contained in:
commit
5a862f86b8
41 changed files with 2934 additions and 252 deletions
|
|
@ -57,14 +57,13 @@ comment "Some wireless drivers require a rate control algorithm"
|
|||
depends on MAC80211 && MAC80211_HAS_RC=n
|
||||
|
||||
config MAC80211_MESH
|
||||
bool "Enable mac80211 mesh networking (pre-802.11s) support"
|
||||
bool "Enable mac80211 mesh networking support"
|
||||
depends on MAC80211
|
||||
---help---
|
||||
This options enables support of Draft 802.11s mesh networking.
|
||||
The implementation is based on Draft 2.08 of the Mesh Networking
|
||||
amendment. However, no compliance with that draft is claimed or even
|
||||
possible, as drafts leave a number of identifiers to be defined after
|
||||
ratification. For more information visit http://o11s.org/.
|
||||
Select this option to enable 802.11 mesh operation in mac80211
|
||||
drivers that support it. 802.11 mesh connects multiple stations
|
||||
over (possibly multi-hop) wireless links to form a single logical
|
||||
LAN.
|
||||
|
||||
config MAC80211_LEDS
|
||||
bool "Enable LED triggers"
|
||||
|
|
|
|||
|
|
@ -800,8 +800,8 @@ static int ieee80211_set_ftm_responder_params(
|
|||
u8 *pos;
|
||||
int len;
|
||||
|
||||
if ((!lci || !lci_len) && (!civicloc || !civicloc_len))
|
||||
return 1;
|
||||
if (!lci_len && !civicloc_len)
|
||||
return 0;
|
||||
|
||||
bss_conf = &sdata->vif.bss_conf;
|
||||
old = bss_conf->ftmr_params;
|
||||
|
|
@ -2028,6 +2028,9 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
|
|||
nconf->dot11MeshAwakeWindowDuration;
|
||||
if (_chg_mesh_attr(NL80211_MESHCONF_PLINK_TIMEOUT, mask))
|
||||
conf->plink_timeout = nconf->plink_timeout;
|
||||
if (_chg_mesh_attr(NL80211_MESHCONF_CONNECTED_TO_GATE, mask))
|
||||
conf->dot11MeshConnectedToMeshGate =
|
||||
nconf->dot11MeshConnectedToMeshGate;
|
||||
ieee80211_mbss_info_change_notify(sdata, BSS_CHANGED_BEACON);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -3850,6 +3853,26 @@ ieee80211_get_ftm_responder_stats(struct wiphy *wiphy,
|
|||
return drv_get_ftm_responder_stats(local, sdata, ftm_stats);
|
||||
}
|
||||
|
||||
static int
|
||||
ieee80211_start_pmsr(struct wiphy *wiphy, struct wireless_dev *dev,
|
||||
struct cfg80211_pmsr_request *request)
|
||||
{
|
||||
struct ieee80211_local *local = wiphy_priv(wiphy);
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(dev);
|
||||
|
||||
return drv_start_pmsr(local, sdata, request);
|
||||
}
|
||||
|
||||
static void
|
||||
ieee80211_abort_pmsr(struct wiphy *wiphy, struct wireless_dev *dev,
|
||||
struct cfg80211_pmsr_request *request)
|
||||
{
|
||||
struct ieee80211_local *local = wiphy_priv(wiphy);
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(dev);
|
||||
|
||||
return drv_abort_pmsr(local, sdata, request);
|
||||
}
|
||||
|
||||
const struct cfg80211_ops mac80211_config_ops = {
|
||||
.add_virtual_intf = ieee80211_add_iface,
|
||||
.del_virtual_intf = ieee80211_del_iface,
|
||||
|
|
@ -3945,4 +3968,6 @@ const struct cfg80211_ops mac80211_config_ops = {
|
|||
.tx_control_port = ieee80211_tx_control_port,
|
||||
.get_txq_stats = ieee80211_get_txq_stats,
|
||||
.get_ftm_responder_stats = ieee80211_get_ftm_responder_stats,
|
||||
.start_pmsr = ieee80211_start_pmsr,
|
||||
.abort_pmsr = ieee80211_abort_pmsr,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -641,6 +641,8 @@ IEEE80211_IF_FILE(dot11MeshHWMPconfirmationInterval,
|
|||
IEEE80211_IF_FILE(power_mode, u.mesh.mshcfg.power_mode, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshAwakeWindowDuration,
|
||||
u.mesh.mshcfg.dot11MeshAwakeWindowDuration, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshConnectedToMeshGate,
|
||||
u.mesh.mshcfg.dot11MeshConnectedToMeshGate, DEC);
|
||||
#endif
|
||||
|
||||
#define DEBUGFS_ADD_MODE(name, mode) \
|
||||
|
|
@ -762,6 +764,7 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
|
|||
MESHPARAMS_ADD(dot11MeshHWMPconfirmationInterval);
|
||||
MESHPARAMS_ADD(power_mode);
|
||||
MESHPARAMS_ADD(dot11MeshAwakeWindowDuration);
|
||||
MESHPARAMS_ADD(dot11MeshConnectedToMeshGate);
|
||||
#undef MESHPARAMS_ADD
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -795,22 +795,22 @@ static ssize_t sta_he_capa_read(struct file *file, char __user *userbuf,
|
|||
|
||||
#define PRINT_NSS_SUPP(f, n) \
|
||||
do { \
|
||||
int i; \
|
||||
int _i; \
|
||||
u16 v = le16_to_cpu(nss->f); \
|
||||
p += scnprintf(p, buf_sz + buf - p, n ": %#.4x\n", v); \
|
||||
for (i = 0; i < 8; i += 2) { \
|
||||
switch ((v >> i) & 0x3) { \
|
||||
for (_i = 0; _i < 8; _i += 2) { \
|
||||
switch ((v >> _i) & 0x3) { \
|
||||
case 0: \
|
||||
PRINT(n "-%d-SUPPORT-0-7", i / 2); \
|
||||
PRINT(n "-%d-SUPPORT-0-7", _i / 2); \
|
||||
break; \
|
||||
case 1: \
|
||||
PRINT(n "-%d-SUPPORT-0-9", i / 2); \
|
||||
PRINT(n "-%d-SUPPORT-0-9", _i / 2); \
|
||||
break; \
|
||||
case 2: \
|
||||
PRINT(n "-%d-SUPPORT-0-11", i / 2); \
|
||||
PRINT(n "-%d-SUPPORT-0-11", _i / 2); \
|
||||
break; \
|
||||
case 3: \
|
||||
PRINT(n "-%d-NOT-SUPPORTED", i / 2); \
|
||||
PRINT(n "-%d-NOT-SUPPORTED", _i / 2); \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
|
|
|
|||
|
|
@ -1199,6 +1199,40 @@ drv_get_ftm_responder_stats(struct ieee80211_local *local,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static inline int drv_start_pmsr(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *sdata,
|
||||
struct cfg80211_pmsr_request *request)
|
||||
{
|
||||
int ret = -EOPNOTSUPP;
|
||||
|
||||
might_sleep();
|
||||
if (!check_sdata_in_driver(sdata))
|
||||
return -EIO;
|
||||
|
||||
trace_drv_start_pmsr(local, sdata);
|
||||
|
||||
if (local->ops->start_pmsr)
|
||||
ret = local->ops->start_pmsr(&local->hw, &sdata->vif, request);
|
||||
trace_drv_return_int(local, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void drv_abort_pmsr(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *sdata,
|
||||
struct cfg80211_pmsr_request *request)
|
||||
{
|
||||
trace_drv_abort_pmsr(local, sdata);
|
||||
|
||||
might_sleep();
|
||||
if (!check_sdata_in_driver(sdata))
|
||||
return;
|
||||
|
||||
if (local->ops->abort_pmsr)
|
||||
local->ops->abort_pmsr(&local->hw, &sdata->vif, request);
|
||||
trace_drv_return_void(local);
|
||||
}
|
||||
|
||||
static inline int drv_start_nan(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *sdata,
|
||||
struct cfg80211_nan_conf *conf)
|
||||
|
|
|
|||
|
|
@ -500,6 +500,7 @@ struct ieee80211_if_managed {
|
|||
unsigned int uapsd_max_sp_len;
|
||||
|
||||
int wmm_last_param_set;
|
||||
int mu_edca_last_param_set;
|
||||
|
||||
u8 use_4addr;
|
||||
|
||||
|
|
|
|||
|
|
@ -1801,7 +1801,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
|
|||
}
|
||||
|
||||
ieee80211_assign_perm_addr(local, ndev->perm_addr, type);
|
||||
if (params && is_valid_ether_addr(params->macaddr))
|
||||
if (is_valid_ether_addr(params->macaddr))
|
||||
memcpy(ndev->dev_addr, params->macaddr, ETH_ALEN);
|
||||
else
|
||||
memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN);
|
||||
|
|
@ -1870,11 +1870,9 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
|
|||
ieee80211_setup_sdata(sdata, type);
|
||||
|
||||
if (ndev) {
|
||||
if (params) {
|
||||
ndev->ieee80211_ptr->use_4addr = params->use_4addr;
|
||||
if (type == NL80211_IFTYPE_STATION)
|
||||
sdata->u.mgd.use_4addr = params->use_4addr;
|
||||
}
|
||||
ndev->ieee80211_ptr->use_4addr = params->use_4addr;
|
||||
if (type == NL80211_IFTYPE_STATION)
|
||||
sdata->u.mgd.use_4addr = params->use_4addr;
|
||||
|
||||
ndev->features |= local->hw.netdev_features;
|
||||
|
||||
|
|
|
|||
|
|
@ -1221,8 +1221,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
|
|||
/* add one default STA interface if supported */
|
||||
if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION) &&
|
||||
!ieee80211_hw_check(hw, NO_AUTO_VIF)) {
|
||||
struct vif_params params = {0};
|
||||
|
||||
result = ieee80211_if_add(local, "wlan%d", NET_NAME_ENUM, NULL,
|
||||
NL80211_IFTYPE_STATION, NULL);
|
||||
NL80211_IFTYPE_STATION, ¶ms);
|
||||
if (result)
|
||||
wiphy_warn(local->hw.wiphy,
|
||||
"Failed to add default virtual iface\n");
|
||||
|
|
|
|||
|
|
@ -254,6 +254,9 @@ int mesh_add_meshconf_ie(struct ieee80211_sub_if_data *sdata,
|
|||
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
||||
u8 *pos, neighbors;
|
||||
u8 meshconf_len = sizeof(struct ieee80211_meshconf_ie);
|
||||
bool is_connected_to_gate = ifmsh->num_gates > 0 ||
|
||||
ifmsh->mshcfg.dot11MeshGateAnnouncementProtocol ||
|
||||
ifmsh->mshcfg.dot11MeshConnectedToMeshGate;
|
||||
|
||||
if (skb_tailroom(skb) < 2 + meshconf_len)
|
||||
return -ENOMEM;
|
||||
|
|
@ -278,7 +281,7 @@ int mesh_add_meshconf_ie(struct ieee80211_sub_if_data *sdata,
|
|||
/* Mesh Formation Info - number of neighbors */
|
||||
neighbors = atomic_read(&ifmsh->estab_plinks);
|
||||
neighbors = min_t(int, neighbors, IEEE80211_MAX_MESH_PEERINGS);
|
||||
*pos++ = neighbors << 1;
|
||||
*pos++ = (neighbors << 1) | is_connected_to_gate;
|
||||
/* Mesh capability */
|
||||
*pos = 0x00;
|
||||
*pos |= ifmsh->mshcfg.dot11MeshForwarding ?
|
||||
|
|
@ -1191,7 +1194,8 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
|
|||
if (!sdata->u.mesh.user_mpm ||
|
||||
sdata->u.mesh.mshcfg.rssi_threshold == 0 ||
|
||||
sdata->u.mesh.mshcfg.rssi_threshold < rx_status->signal)
|
||||
mesh_neighbour_update(sdata, mgmt->sa, &elems);
|
||||
mesh_neighbour_update(sdata, mgmt->sa, &elems,
|
||||
rx_status);
|
||||
}
|
||||
|
||||
if (ifmsh->sync_ops)
|
||||
|
|
|
|||
|
|
@ -273,7 +273,8 @@ int mesh_gate_num(struct ieee80211_sub_if_data *sdata);
|
|||
|
||||
/* Mesh plinks */
|
||||
void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
|
||||
u8 *hw_addr, struct ieee802_11_elems *ie);
|
||||
u8 *hw_addr, struct ieee802_11_elems *ie,
|
||||
struct ieee80211_rx_status *rx_status);
|
||||
bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie);
|
||||
u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata);
|
||||
void mesh_plink_timer(struct timer_list *t);
|
||||
|
|
|
|||
|
|
@ -513,7 +513,8 @@ __mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *hw_addr)
|
|||
|
||||
static struct sta_info *
|
||||
mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *addr,
|
||||
struct ieee802_11_elems *elems)
|
||||
struct ieee802_11_elems *elems,
|
||||
struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
struct sta_info *sta = NULL;
|
||||
|
||||
|
|
@ -521,11 +522,17 @@ mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *addr,
|
|||
if (sdata->u.mesh.user_mpm ||
|
||||
sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED) {
|
||||
if (mesh_peer_accepts_plinks(elems) &&
|
||||
mesh_plink_availables(sdata))
|
||||
mesh_plink_availables(sdata)) {
|
||||
int sig = 0;
|
||||
|
||||
if (ieee80211_hw_check(&sdata->local->hw, SIGNAL_DBM))
|
||||
sig = rx_status->signal;
|
||||
|
||||
cfg80211_notify_new_peer_candidate(sdata->dev, addr,
|
||||
elems->ie_start,
|
||||
elems->total_len,
|
||||
GFP_KERNEL);
|
||||
sig, GFP_KERNEL);
|
||||
}
|
||||
} else
|
||||
sta = __mesh_sta_info_alloc(sdata, addr);
|
||||
|
||||
|
|
@ -538,13 +545,15 @@ mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *addr,
|
|||
* @sdata: local meshif
|
||||
* @addr: peer's address
|
||||
* @elems: IEs from beacon or mesh peering frame.
|
||||
* @rx_status: rx status for the frame for signal reporting
|
||||
*
|
||||
* Return existing or newly allocated sta_info under RCU read lock.
|
||||
* (re)initialize with given IEs.
|
||||
*/
|
||||
static struct sta_info *
|
||||
mesh_sta_info_get(struct ieee80211_sub_if_data *sdata,
|
||||
u8 *addr, struct ieee802_11_elems *elems) __acquires(RCU)
|
||||
u8 *addr, struct ieee802_11_elems *elems,
|
||||
struct ieee80211_rx_status *rx_status) __acquires(RCU)
|
||||
{
|
||||
struct sta_info *sta = NULL;
|
||||
|
||||
|
|
@ -555,7 +564,7 @@ mesh_sta_info_get(struct ieee80211_sub_if_data *sdata,
|
|||
} else {
|
||||
rcu_read_unlock();
|
||||
/* can't run atomic */
|
||||
sta = mesh_sta_info_alloc(sdata, addr, elems);
|
||||
sta = mesh_sta_info_alloc(sdata, addr, elems, rx_status);
|
||||
if (!sta) {
|
||||
rcu_read_lock();
|
||||
return NULL;
|
||||
|
|
@ -576,20 +585,25 @@ mesh_sta_info_get(struct ieee80211_sub_if_data *sdata,
|
|||
* @sdata: local meshif
|
||||
* @addr: peer's address
|
||||
* @elems: IEs from beacon or mesh peering frame
|
||||
* @rx_status: rx status for the frame for signal reporting
|
||||
*
|
||||
* Initiates peering if appropriate.
|
||||
*/
|
||||
void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
|
||||
u8 *hw_addr,
|
||||
struct ieee802_11_elems *elems)
|
||||
struct ieee802_11_elems *elems,
|
||||
struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
struct sta_info *sta;
|
||||
u32 changed = 0;
|
||||
|
||||
sta = mesh_sta_info_get(sdata, hw_addr, elems);
|
||||
sta = mesh_sta_info_get(sdata, hw_addr, elems, rx_status);
|
||||
if (!sta)
|
||||
goto out;
|
||||
|
||||
sta->mesh->connected_to_gate = elems->mesh_config->meshconf_form &
|
||||
IEEE80211_MESHCONF_FORM_CONNECTED_TO_GATE;
|
||||
|
||||
if (mesh_peer_accepts_plinks(elems) &&
|
||||
sta->mesh->plink_state == NL80211_PLINK_LISTEN &&
|
||||
sdata->u.mesh.accepting_plinks &&
|
||||
|
|
@ -1069,7 +1083,8 @@ out:
|
|||
static void
|
||||
mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_mgmt *mgmt,
|
||||
struct ieee802_11_elems *elems)
|
||||
struct ieee802_11_elems *elems,
|
||||
struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
|
||||
struct sta_info *sta;
|
||||
|
|
@ -1134,7 +1149,7 @@ mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
|
|||
if (event == OPN_ACPT) {
|
||||
rcu_read_unlock();
|
||||
/* allocate sta entry if necessary and update info */
|
||||
sta = mesh_sta_info_get(sdata, mgmt->sa, elems);
|
||||
sta = mesh_sta_info_get(sdata, mgmt->sa, elems, rx_status);
|
||||
if (!sta) {
|
||||
mpl_dbg(sdata, "Mesh plink: failed to init peer!\n");
|
||||
goto unlock_rcu;
|
||||
|
|
@ -1200,5 +1215,5 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
|
|||
return;
|
||||
}
|
||||
ieee802_11_parse_elems(baseaddr, len - baselen, true, &elems);
|
||||
mesh_process_plink_frame(sdata, mgmt, &elems);
|
||||
mesh_process_plink_frame(sdata, mgmt, &elems, rx_status);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -916,6 +916,15 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
|
|||
ieee80211_add_vht_ie(sdata, skb, sband,
|
||||
&assoc_data->ap_vht_cap);
|
||||
|
||||
/*
|
||||
* If AP doesn't support HT, mark HE as disabled.
|
||||
* If on the 5GHz band, make sure it supports VHT.
|
||||
*/
|
||||
if (ifmgd->flags & IEEE80211_STA_DISABLE_HT ||
|
||||
(sband->band == NL80211_BAND_5GHZ &&
|
||||
ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
|
||||
|
||||
if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HE))
|
||||
ieee80211_add_he_ie(sdata, skb, sband);
|
||||
|
||||
|
|
@ -1869,7 +1878,7 @@ ieee80211_sta_wmm_params(struct ieee80211_local *local,
|
|||
struct ieee80211_tx_queue_params params[IEEE80211_NUM_ACS];
|
||||
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
||||
size_t left;
|
||||
int count, ac;
|
||||
int count, mu_edca_count, ac;
|
||||
const u8 *pos;
|
||||
u8 uapsd_queues = 0;
|
||||
|
||||
|
|
@ -1889,9 +1898,16 @@ ieee80211_sta_wmm_params(struct ieee80211_local *local,
|
|||
uapsd_queues = ifmgd->uapsd_queues;
|
||||
|
||||
count = wmm_param[6] & 0x0f;
|
||||
if (count == ifmgd->wmm_last_param_set)
|
||||
/* -1 is the initial value of ifmgd->mu_edca_last_param_set.
|
||||
* if mu_edca was preset before and now it disappeared tell
|
||||
* the driver about it.
|
||||
*/
|
||||
mu_edca_count = mu_edca ? mu_edca->mu_qos_info & 0x0f : -1;
|
||||
if (count == ifmgd->wmm_last_param_set &&
|
||||
mu_edca_count == ifmgd->mu_edca_last_param_set)
|
||||
return false;
|
||||
ifmgd->wmm_last_param_set = count;
|
||||
ifmgd->mu_edca_last_param_set = mu_edca_count;
|
||||
|
||||
pos = wmm_param + 8;
|
||||
left = wmm_param_len - 8;
|
||||
|
|
@ -3062,6 +3078,19 @@ static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
|
|||
}
|
||||
}
|
||||
|
||||
static bool ieee80211_twt_req_supported(const struct sta_info *sta,
|
||||
const struct ieee802_11_elems *elems)
|
||||
{
|
||||
if (elems->ext_capab_len < 10)
|
||||
return false;
|
||||
|
||||
if (!(elems->ext_capab[9] & WLAN_EXT_CAPA10_TWT_RESPONDER_SUPPORT))
|
||||
return false;
|
||||
|
||||
return sta->sta.he_cap.he_cap_elem.mac_cap_info[0] &
|
||||
IEEE80211_HE_MAC_CAP0_TWT_RES;
|
||||
}
|
||||
|
||||
static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
|
||||
struct cfg80211_bss *cbss,
|
||||
struct ieee80211_mgmt *mgmt, size_t len)
|
||||
|
|
@ -3215,16 +3244,6 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
|
|||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* If AP doesn't support HT, or it doesn't have HE mandatory IEs, mark
|
||||
* HE as disabled. If on the 5GHz band, make sure it supports VHT.
|
||||
*/
|
||||
if (ifmgd->flags & IEEE80211_STA_DISABLE_HT ||
|
||||
(sband->band == NL80211_BAND_5GHZ &&
|
||||
ifmgd->flags & IEEE80211_STA_DISABLE_VHT) ||
|
||||
(!elems.he_cap && !elems.he_operation))
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
|
||||
|
||||
if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HE) &&
|
||||
(!elems.he_cap || !elems.he_operation)) {
|
||||
mutex_unlock(&sdata->local->sta_mtx);
|
||||
|
|
@ -3251,8 +3270,11 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
|
|||
sta);
|
||||
|
||||
bss_conf->he_support = sta->sta.he_cap.has_he;
|
||||
bss_conf->twt_requester =
|
||||
ieee80211_twt_req_supported(sta, &elems);
|
||||
} else {
|
||||
bss_conf->he_support = false;
|
||||
bss_conf->twt_requester = false;
|
||||
}
|
||||
|
||||
if (bss_conf->he_support) {
|
||||
|
|
@ -3337,6 +3359,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
|
|||
* 4-bit value.
|
||||
*/
|
||||
ifmgd->wmm_last_param_set = -1;
|
||||
ifmgd->mu_edca_last_param_set = -1;
|
||||
|
||||
if (ifmgd->flags & IEEE80211_STA_DISABLE_WMM) {
|
||||
ieee80211_set_wmm_default(sdata, false, false);
|
||||
|
|
@ -4660,8 +4683,10 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
|
|||
}
|
||||
}
|
||||
|
||||
if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HE) &&
|
||||
ieee80211_get_he_sta_cap(sband)) {
|
||||
if (!ieee80211_get_he_sta_cap(sband))
|
||||
ifmgd->flags |= IEEE80211_STA_DISABLE_HE;
|
||||
|
||||
if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HE)) {
|
||||
const struct cfg80211_bss_ies *ies;
|
||||
const u8 *he_oper_ie;
|
||||
|
||||
|
|
|
|||
|
|
@ -143,6 +143,9 @@ ieee80211_rx_radiotap_hdrlen(struct ieee80211_local *local,
|
|||
/* allocate extra bitmaps */
|
||||
if (status->chains)
|
||||
len += 4 * hweight8(status->chains);
|
||||
/* vendor presence bitmap */
|
||||
if (status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA)
|
||||
len += 4;
|
||||
|
||||
if (ieee80211_have_rx_timestamp(status)) {
|
||||
len = ALIGN(len, 8);
|
||||
|
|
@ -207,8 +210,6 @@ ieee80211_rx_radiotap_hdrlen(struct ieee80211_local *local,
|
|||
if (status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA) {
|
||||
struct ieee80211_vendor_radiotap *rtap = (void *)skb->data;
|
||||
|
||||
/* vendor presence bitmap */
|
||||
len += 4;
|
||||
/* alignment for fixed 6-byte vendor data header */
|
||||
len = ALIGN(len, 2);
|
||||
/* vendor data header */
|
||||
|
|
@ -753,6 +754,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
|
|||
struct ieee80211_sub_if_data *monitor_sdata =
|
||||
rcu_dereference(local->monitor_sdata);
|
||||
bool only_monitor = false;
|
||||
unsigned int min_head_len;
|
||||
|
||||
if (status->flag & RX_FLAG_RADIOTAP_HE)
|
||||
rtap_space += sizeof(struct ieee80211_radiotap_he);
|
||||
|
|
@ -760,12 +762,18 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
|
|||
if (status->flag & RX_FLAG_RADIOTAP_HE_MU)
|
||||
rtap_space += sizeof(struct ieee80211_radiotap_he_mu);
|
||||
|
||||
if (status->flag & RX_FLAG_RADIOTAP_LSIG)
|
||||
rtap_space += sizeof(struct ieee80211_radiotap_lsig);
|
||||
|
||||
if (unlikely(status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA)) {
|
||||
struct ieee80211_vendor_radiotap *rtap = (void *)origskb->data;
|
||||
struct ieee80211_vendor_radiotap *rtap =
|
||||
(void *)(origskb->data + rtap_space);
|
||||
|
||||
rtap_space += sizeof(*rtap) + rtap->len + rtap->pad;
|
||||
}
|
||||
|
||||
min_head_len = rtap_space;
|
||||
|
||||
/*
|
||||
* First, we may need to make a copy of the skb because
|
||||
* (1) we need to modify it for radiotap (if not present), and
|
||||
|
|
@ -775,18 +783,23 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
|
|||
* the SKB because it has a bad FCS/PLCP checksum.
|
||||
*/
|
||||
|
||||
if (ieee80211_hw_check(&local->hw, RX_INCLUDES_FCS)) {
|
||||
if (unlikely(origskb->len <= FCS_LEN)) {
|
||||
/* driver bug */
|
||||
WARN_ON(1);
|
||||
dev_kfree_skb(origskb);
|
||||
return NULL;
|
||||
if (!(status->flag & RX_FLAG_NO_PSDU)) {
|
||||
if (ieee80211_hw_check(&local->hw, RX_INCLUDES_FCS)) {
|
||||
if (unlikely(origskb->len <= FCS_LEN + rtap_space)) {
|
||||
/* driver bug */
|
||||
WARN_ON(1);
|
||||
dev_kfree_skb(origskb);
|
||||
return NULL;
|
||||
}
|
||||
present_fcs_len = FCS_LEN;
|
||||
}
|
||||
present_fcs_len = FCS_LEN;
|
||||
|
||||
/* also consider the hdr->frame_control */
|
||||
min_head_len += 2;
|
||||
}
|
||||
|
||||
/* ensure hdr->frame_control and vendor radiotap data are in skb head */
|
||||
if (!pskb_may_pull(origskb, 2 + rtap_space)) {
|
||||
/* ensure that the expected data elements are in skb head */
|
||||
if (!pskb_may_pull(origskb, min_head_len)) {
|
||||
dev_kfree_skb(origskb);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -356,7 +356,7 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
|
|||
static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
|
||||
{
|
||||
struct ieee80211_local *local = hw_to_local(hw);
|
||||
bool hw_scan = local->ops->hw_scan;
|
||||
bool hw_scan = test_bit(SCAN_HW_SCANNING, &local->scanning);
|
||||
bool was_scanning = local->scanning;
|
||||
struct cfg80211_scan_request *scan_req;
|
||||
struct ieee80211_sub_if_data *scan_sdata;
|
||||
|
|
@ -606,6 +606,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
|
|||
struct cfg80211_scan_request *req)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
bool hw_scan = local->ops->hw_scan;
|
||||
int rc;
|
||||
|
||||
lockdep_assert_held(&local->mtx);
|
||||
|
|
@ -620,7 +621,8 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (local->ops->hw_scan) {
|
||||
again:
|
||||
if (hw_scan) {
|
||||
u8 *ies;
|
||||
|
||||
local->hw_scan_ies_bufsize = local->scan_ies_len + req->ie_len;
|
||||
|
|
@ -679,7 +681,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
|
|||
else
|
||||
memcpy(local->scan_addr, sdata->vif.addr, ETH_ALEN);
|
||||
|
||||
if (local->ops->hw_scan) {
|
||||
if (hw_scan) {
|
||||
__set_bit(SCAN_HW_SCANNING, &local->scanning);
|
||||
} else if ((req->n_channels == 1) &&
|
||||
(req->channels[0] == local->_oper_chandef.chan)) {
|
||||
|
|
@ -722,7 +724,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
ieee80211_recalc_idle(local);
|
||||
|
||||
if (local->ops->hw_scan) {
|
||||
if (hw_scan) {
|
||||
WARN_ON(!ieee80211_prep_hw_scan(local));
|
||||
rc = drv_hw_scan(local, sdata, local->hw_scan_req);
|
||||
} else {
|
||||
|
|
@ -740,6 +742,18 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
|
|||
RCU_INIT_POINTER(local->scan_sdata, NULL);
|
||||
}
|
||||
|
||||
if (hw_scan && rc == 1) {
|
||||
/*
|
||||
* we can't fall back to software for P2P-GO
|
||||
* as it must update NoA etc.
|
||||
*/
|
||||
if (ieee80211_vif_type_p2p(&sdata->vif) ==
|
||||
NL80211_IFTYPE_P2P_GO)
|
||||
return -EOPNOTSUPP;
|
||||
hw_scan = false;
|
||||
goto again;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2253,11 +2253,8 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo,
|
|||
}
|
||||
|
||||
if (tidstats && !cfg80211_sinfo_alloc_tid_stats(sinfo, GFP_KERNEL)) {
|
||||
for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++) {
|
||||
struct cfg80211_tid_stats *tidstats = &sinfo->pertid[i];
|
||||
|
||||
sta_set_tidstats(sta, tidstats, i);
|
||||
}
|
||||
for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++)
|
||||
sta_set_tidstats(sta, &sinfo->pertid[i], i);
|
||||
}
|
||||
|
||||
if (ieee80211_vif_is_mesh(&sdata->vif)) {
|
||||
|
|
@ -2267,7 +2264,8 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo,
|
|||
BIT_ULL(NL80211_STA_INFO_PLINK_STATE) |
|
||||
BIT_ULL(NL80211_STA_INFO_LOCAL_PM) |
|
||||
BIT_ULL(NL80211_STA_INFO_PEER_PM) |
|
||||
BIT_ULL(NL80211_STA_INFO_NONPEER_PM);
|
||||
BIT_ULL(NL80211_STA_INFO_NONPEER_PM) |
|
||||
BIT_ULL(NL80211_STA_INFO_CONNECTED_TO_GATE);
|
||||
|
||||
sinfo->llid = sta->mesh->llid;
|
||||
sinfo->plid = sta->mesh->plid;
|
||||
|
|
@ -2279,6 +2277,7 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo,
|
|||
sinfo->local_pm = sta->mesh->local_pm;
|
||||
sinfo->peer_pm = sta->mesh->peer_pm;
|
||||
sinfo->nonpeer_pm = sta->mesh->nonpeer_pm;
|
||||
sinfo->connected_to_gate = sta->mesh->connected_to_gate;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -364,6 +364,7 @@ DECLARE_EWMA(mesh_fail_avg, 20, 8)
|
|||
* @nonpeer_pm: STA power save mode towards non-peer neighbors
|
||||
* @processed_beacon: set to true after peer rates and capabilities are
|
||||
* processed
|
||||
* @connected_to_gate: true if mesh STA has a path to a mesh gate
|
||||
* @fail_avg: moving percentage of failed MSDUs
|
||||
*/
|
||||
struct mesh_sta {
|
||||
|
|
@ -381,6 +382,7 @@ struct mesh_sta {
|
|||
u8 plink_retries;
|
||||
|
||||
bool processed_beacon;
|
||||
bool connected_to_gate;
|
||||
|
||||
enum nl80211_plink_state plink_state;
|
||||
u32 plink_timeout;
|
||||
|
|
|
|||
|
|
@ -1052,10 +1052,10 @@ TRACE_EVENT(drv_ampdu_action,
|
|||
);
|
||||
|
||||
TRACE_EVENT(drv_get_survey,
|
||||
TP_PROTO(struct ieee80211_local *local, int idx,
|
||||
TP_PROTO(struct ieee80211_local *local, int _idx,
|
||||
struct survey_info *survey),
|
||||
|
||||
TP_ARGS(local, idx, survey),
|
||||
TP_ARGS(local, _idx, survey),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
LOCAL_ENTRY
|
||||
|
|
@ -1064,7 +1064,7 @@ TRACE_EVENT(drv_get_survey,
|
|||
|
||||
TP_fast_assign(
|
||||
LOCAL_ASSIGN;
|
||||
__entry->idx = idx;
|
||||
__entry->idx = _idx;
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
|
|
@ -1882,6 +1882,18 @@ TRACE_EVENT(drv_del_nan_func,
|
|||
)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(local_sdata_evt, drv_start_pmsr,
|
||||
TP_PROTO(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *sdata),
|
||||
TP_ARGS(local, sdata)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(local_sdata_evt, drv_abort_pmsr,
|
||||
TP_PROTO(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *sdata),
|
||||
TP_ARGS(local, sdata)
|
||||
);
|
||||
|
||||
/*
|
||||
* Tracing for API calls that drivers call.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -3218,6 +3218,9 @@ static bool ieee80211_amsdu_aggregate(struct ieee80211_sub_if_data *sdata,
|
|||
if (!ieee80211_hw_check(&local->hw, TX_AMSDU))
|
||||
return false;
|
||||
|
||||
if (skb_is_gso(skb))
|
||||
return false;
|
||||
|
||||
if (!txq)
|
||||
return false;
|
||||
|
||||
|
|
@ -3242,7 +3245,7 @@ static bool ieee80211_amsdu_aggregate(struct ieee80211_sub_if_data *sdata,
|
|||
tin = &txqi->tin;
|
||||
flow = fq_flow_classify(fq, tin, skb, fq_flow_get_default_func);
|
||||
head = skb_peek_tail(&flow->queue);
|
||||
if (!head)
|
||||
if (!head || skb_is_gso(head))
|
||||
goto out;
|
||||
|
||||
orig_len = head->len;
|
||||
|
|
@ -3583,7 +3586,7 @@ begin:
|
|||
skb_queue_splice_tail(&tx.skbs, &txqi->frags);
|
||||
}
|
||||
|
||||
if (skb && skb_has_frag_list(skb) &&
|
||||
if (skb_has_frag_list(skb) &&
|
||||
!ieee80211_hw_check(&local->hw, TX_FRAG_LIST)) {
|
||||
if (skb_linearize(skb)) {
|
||||
ieee80211_free_txskb(&local->hw, skb);
|
||||
|
|
@ -4579,7 +4582,7 @@ struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,
|
|||
IEEE80211_STYPE_NULLFUNC |
|
||||
IEEE80211_FCTL_TODS);
|
||||
if (qos) {
|
||||
__le16 qos = cpu_to_le16(7);
|
||||
__le16 qoshdr = cpu_to_le16(7);
|
||||
|
||||
BUILD_BUG_ON((IEEE80211_STYPE_QOS_NULLFUNC |
|
||||
IEEE80211_STYPE_NULLFUNC) !=
|
||||
|
|
@ -4588,7 +4591,7 @@ struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,
|
|||
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));
|
||||
skb_put_data(skb, &qoshdr, sizeof(qoshdr));
|
||||
}
|
||||
|
||||
memcpy(nullfunc->addr1, ifmgd->bssid, ETH_ALEN);
|
||||
|
|
|
|||
|
|
@ -299,16 +299,16 @@ out:
|
|||
spin_unlock_bh(&fq->lock);
|
||||
}
|
||||
|
||||
void ieee80211_wake_txqs(unsigned long data)
|
||||
static void
|
||||
__releases(&local->queue_stop_reason_lock)
|
||||
__acquires(&local->queue_stop_reason_lock)
|
||||
_ieee80211_wake_txqs(struct ieee80211_local *local, unsigned long *flags)
|
||||
{
|
||||
struct ieee80211_local *local = (struct ieee80211_local *)data;
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
int n_acs = IEEE80211_NUM_ACS;
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
rcu_read_lock();
|
||||
spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
|
||||
|
||||
if (local->hw.queues < IEEE80211_NUM_ACS)
|
||||
n_acs = 1;
|
||||
|
|
@ -317,7 +317,7 @@ void ieee80211_wake_txqs(unsigned long data)
|
|||
if (local->queue_stop_reasons[i])
|
||||
continue;
|
||||
|
||||
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
|
||||
spin_unlock_irqrestore(&local->queue_stop_reason_lock, *flags);
|
||||
list_for_each_entry_rcu(sdata, &local->interfaces, list) {
|
||||
int ac;
|
||||
|
||||
|
|
@ -329,13 +329,22 @@ void ieee80211_wake_txqs(unsigned long data)
|
|||
__ieee80211_wake_txqs(sdata, ac);
|
||||
}
|
||||
}
|
||||
spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
|
||||
spin_lock_irqsave(&local->queue_stop_reason_lock, *flags);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
void ieee80211_wake_txqs(unsigned long data)
|
||||
{
|
||||
struct ieee80211_local *local = (struct ieee80211_local *)data;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
|
||||
_ieee80211_wake_txqs(local, &flags);
|
||||
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
|
||||
}
|
||||
|
||||
void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
|
|
@ -371,7 +380,8 @@ void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue)
|
|||
|
||||
static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
|
||||
enum queue_stop_reason reason,
|
||||
bool refcounted)
|
||||
bool refcounted,
|
||||
unsigned long *flags)
|
||||
{
|
||||
struct ieee80211_local *local = hw_to_local(hw);
|
||||
|
||||
|
|
@ -405,8 +415,19 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
|
|||
} else
|
||||
tasklet_schedule(&local->tx_pending_tasklet);
|
||||
|
||||
if (local->ops->wake_tx_queue)
|
||||
tasklet_schedule(&local->wake_txqs_tasklet);
|
||||
/*
|
||||
* Calling _ieee80211_wake_txqs here can be a problem because it may
|
||||
* release queue_stop_reason_lock which has been taken by
|
||||
* __ieee80211_wake_queue's caller. It is certainly not very nice to
|
||||
* release someone's lock, but it is fine because all the callers of
|
||||
* __ieee80211_wake_queue call it right before releasing the lock.
|
||||
*/
|
||||
if (local->ops->wake_tx_queue) {
|
||||
if (reason == IEEE80211_QUEUE_STOP_REASON_DRIVER)
|
||||
tasklet_schedule(&local->wake_txqs_tasklet);
|
||||
else
|
||||
_ieee80211_wake_txqs(local, flags);
|
||||
}
|
||||
}
|
||||
|
||||
void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
|
||||
|
|
@ -417,7 +438,7 @@ void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
|
|||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
|
||||
__ieee80211_wake_queue(hw, queue, reason, refcounted);
|
||||
__ieee80211_wake_queue(hw, queue, reason, refcounted, &flags);
|
||||
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
|
||||
}
|
||||
|
||||
|
|
@ -514,7 +535,7 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local,
|
|||
false);
|
||||
__skb_queue_tail(&local->pending[queue], skb);
|
||||
__ieee80211_wake_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
|
||||
false);
|
||||
false, &flags);
|
||||
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
|
||||
}
|
||||
|
||||
|
|
@ -547,7 +568,7 @@ void ieee80211_add_pending_skbs(struct ieee80211_local *local,
|
|||
for (i = 0; i < hw->queues; i++)
|
||||
__ieee80211_wake_queue(hw, i,
|
||||
IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
|
||||
false);
|
||||
false, &flags);
|
||||
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
|
||||
}
|
||||
|
||||
|
|
@ -605,7 +626,7 @@ void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
|
|||
spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
|
||||
|
||||
for_each_set_bit(i, &queues, hw->queues)
|
||||
__ieee80211_wake_queue(hw, i, reason, refcounted);
|
||||
__ieee80211_wake_queue(hw, i, reason, refcounted, &flags);
|
||||
|
||||
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
|
||||
}
|
||||
|
|
@ -1202,6 +1223,8 @@ u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
|
|||
if (pos[0] == WLAN_EID_EXT_HE_MU_EDCA &&
|
||||
elen >= (sizeof(*elems->mu_edca_param_set) + 1)) {
|
||||
elems->mu_edca_param_set = (void *)&pos[1];
|
||||
if (calc_crc)
|
||||
crc = crc32_be(crc, pos - 2, elen + 2);
|
||||
} else if (pos[0] == WLAN_EID_EXT_HE_CAPABILITY) {
|
||||
elems->he_cap = (void *)&pos[1];
|
||||
elems->he_cap_len = elen - 1;
|
||||
|
|
|
|||
Loading…
Reference in a new issue