mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 10:41:38 -04:00
Merge branch 'for-john' of git://git.sipsolutions.net/mac80211-next
This commit is contained in:
commit
133189a46c
23 changed files with 688 additions and 334 deletions
|
|
@ -689,7 +689,8 @@ static int ieee80211_set_channel(struct wiphy *wiphy,
|
|||
case CHAN_MODE_HOPPING:
|
||||
return -EBUSY;
|
||||
case CHAN_MODE_FIXED:
|
||||
if (local->oper_channel != chan)
|
||||
if (local->oper_channel != chan ||
|
||||
(!sdata && local->_oper_channel_type != channel_type))
|
||||
return -EBUSY;
|
||||
if (!sdata && local->_oper_channel_type == channel_type)
|
||||
return 0;
|
||||
|
|
@ -1529,7 +1530,7 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
|
|||
if (_chg_mesh_attr(NL80211_MESHCONF_TTL, mask))
|
||||
conf->dot11MeshTTL = nconf->dot11MeshTTL;
|
||||
if (_chg_mesh_attr(NL80211_MESHCONF_ELEMENT_TTL, mask))
|
||||
conf->dot11MeshTTL = nconf->element_ttl;
|
||||
conf->element_ttl = nconf->element_ttl;
|
||||
if (_chg_mesh_attr(NL80211_MESHCONF_AUTO_OPEN_PLINKS, mask))
|
||||
conf->auto_open_plinks = nconf->auto_open_plinks;
|
||||
if (_chg_mesh_attr(NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, mask))
|
||||
|
|
@ -1564,17 +1565,16 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
|
|||
* announcements, so require this ifmsh to also be a root node
|
||||
* */
|
||||
if (nconf->dot11MeshGateAnnouncementProtocol &&
|
||||
!conf->dot11MeshHWMPRootMode) {
|
||||
conf->dot11MeshHWMPRootMode = 1;
|
||||
!(conf->dot11MeshHWMPRootMode > IEEE80211_ROOTMODE_ROOT)) {
|
||||
conf->dot11MeshHWMPRootMode = IEEE80211_PROACTIVE_RANN;
|
||||
ieee80211_mesh_root_setup(ifmsh);
|
||||
}
|
||||
conf->dot11MeshGateAnnouncementProtocol =
|
||||
nconf->dot11MeshGateAnnouncementProtocol;
|
||||
}
|
||||
if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_RANN_INTERVAL, mask)) {
|
||||
if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_RANN_INTERVAL, mask))
|
||||
conf->dot11MeshHWMPRannInterval =
|
||||
nconf->dot11MeshHWMPRannInterval;
|
||||
}
|
||||
if (_chg_mesh_attr(NL80211_MESHCONF_FORWARDING, mask))
|
||||
conf->dot11MeshForwarding = nconf->dot11MeshForwarding;
|
||||
if (_chg_mesh_attr(NL80211_MESHCONF_RSSI_THRESHOLD, mask)) {
|
||||
|
|
@ -1590,6 +1590,15 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
|
|||
sdata->vif.bss_conf.ht_operation_mode = nconf->ht_opmode;
|
||||
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT);
|
||||
}
|
||||
if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT, mask))
|
||||
conf->dot11MeshHWMPactivePathToRootTimeout =
|
||||
nconf->dot11MeshHWMPactivePathToRootTimeout;
|
||||
if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ROOT_INTERVAL, mask))
|
||||
conf->dot11MeshHWMProotInterval =
|
||||
nconf->dot11MeshHWMProotInterval;
|
||||
if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, mask))
|
||||
conf->dot11MeshHWMPconfirmationInterval =
|
||||
nconf->dot11MeshHWMPconfirmationInterval;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -2309,6 +2318,21 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
|
|||
|
||||
mutex_lock(&local->mtx);
|
||||
list_for_each_entry_safe(roc, tmp, &local->roc_list, list) {
|
||||
struct ieee80211_roc_work *dep, *tmp2;
|
||||
|
||||
list_for_each_entry_safe(dep, tmp2, &roc->dependents, list) {
|
||||
if (!mgmt_tx && (unsigned long)dep != cookie)
|
||||
continue;
|
||||
else if (mgmt_tx && dep->mgmt_tx_cookie != cookie)
|
||||
continue;
|
||||
/* found dependent item -- just remove it */
|
||||
list_del(&dep->list);
|
||||
mutex_unlock(&local->mtx);
|
||||
|
||||
ieee80211_roc_notify_destroy(dep);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!mgmt_tx && (unsigned long)roc != cookie)
|
||||
continue;
|
||||
else if (mgmt_tx && roc->mgmt_tx_cookie != cookie)
|
||||
|
|
@ -2323,6 +2347,13 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
|
|||
return -ENOENT;
|
||||
}
|
||||
|
||||
/*
|
||||
* We found the item to cancel, so do that. Note that it
|
||||
* may have dependents, which we also cancel (and send
|
||||
* the expired signal for.) Not doing so would be quite
|
||||
* tricky here, but we may need to fix it later.
|
||||
*/
|
||||
|
||||
if (local->ops->remain_on_channel) {
|
||||
if (found->started) {
|
||||
ret = drv_cancel_remain_on_channel(local);
|
||||
|
|
@ -2334,8 +2365,8 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
|
|||
|
||||
list_del(&found->list);
|
||||
|
||||
ieee80211_run_deferred_scan(local);
|
||||
ieee80211_start_next_roc(local);
|
||||
if (found->started)
|
||||
ieee80211_start_next_roc(local);
|
||||
mutex_unlock(&local->mtx);
|
||||
|
||||
ieee80211_roc_notify_destroy(found);
|
||||
|
|
@ -2489,16 +2520,30 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
|
|||
u16 frame_type, bool reg)
|
||||
{
|
||||
struct ieee80211_local *local = wiphy_priv(wiphy);
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
|
||||
if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
|
||||
return;
|
||||
switch (frame_type) {
|
||||
case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH:
|
||||
if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
|
||||
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
|
||||
|
||||
if (reg)
|
||||
local->probe_req_reg++;
|
||||
else
|
||||
local->probe_req_reg--;
|
||||
if (reg)
|
||||
ifibss->auth_frame_registrations++;
|
||||
else
|
||||
ifibss->auth_frame_registrations--;
|
||||
}
|
||||
break;
|
||||
case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ:
|
||||
if (reg)
|
||||
local->probe_req_reg++;
|
||||
else
|
||||
local->probe_req_reg--;
|
||||
|
||||
ieee80211_queue_work(&local->hw, &local->reconfig_filter);
|
||||
ieee80211_queue_work(&local->hw, &local->reconfig_filter);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int ieee80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
|
||||
|
|
|
|||
|
|
@ -468,48 +468,54 @@ IEEE80211_IF_FILE(fwded_unicast, u.mesh.mshstats.fwded_unicast, DEC);
|
|||
IEEE80211_IF_FILE(fwded_frames, u.mesh.mshstats.fwded_frames, DEC);
|
||||
IEEE80211_IF_FILE(dropped_frames_ttl, u.mesh.mshstats.dropped_frames_ttl, DEC);
|
||||
IEEE80211_IF_FILE(dropped_frames_congestion,
|
||||
u.mesh.mshstats.dropped_frames_congestion, DEC);
|
||||
u.mesh.mshstats.dropped_frames_congestion, DEC);
|
||||
IEEE80211_IF_FILE(dropped_frames_no_route,
|
||||
u.mesh.mshstats.dropped_frames_no_route, DEC);
|
||||
u.mesh.mshstats.dropped_frames_no_route, DEC);
|
||||
IEEE80211_IF_FILE(estab_plinks, u.mesh.mshstats.estab_plinks, ATOMIC);
|
||||
|
||||
/* Mesh parameters */
|
||||
IEEE80211_IF_FILE(dot11MeshMaxRetries,
|
||||
u.mesh.mshcfg.dot11MeshMaxRetries, DEC);
|
||||
u.mesh.mshcfg.dot11MeshMaxRetries, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshRetryTimeout,
|
||||
u.mesh.mshcfg.dot11MeshRetryTimeout, DEC);
|
||||
u.mesh.mshcfg.dot11MeshRetryTimeout, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshConfirmTimeout,
|
||||
u.mesh.mshcfg.dot11MeshConfirmTimeout, DEC);
|
||||
u.mesh.mshcfg.dot11MeshConfirmTimeout, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshHoldingTimeout,
|
||||
u.mesh.mshcfg.dot11MeshHoldingTimeout, DEC);
|
||||
u.mesh.mshcfg.dot11MeshHoldingTimeout, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshTTL, u.mesh.mshcfg.dot11MeshTTL, DEC);
|
||||
IEEE80211_IF_FILE(element_ttl, u.mesh.mshcfg.element_ttl, DEC);
|
||||
IEEE80211_IF_FILE(auto_open_plinks, u.mesh.mshcfg.auto_open_plinks, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshMaxPeerLinks,
|
||||
u.mesh.mshcfg.dot11MeshMaxPeerLinks, DEC);
|
||||
u.mesh.mshcfg.dot11MeshMaxPeerLinks, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshHWMPactivePathTimeout,
|
||||
u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout, DEC);
|
||||
u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshHWMPpreqMinInterval,
|
||||
u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval, DEC);
|
||||
u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshHWMPperrMinInterval,
|
||||
u.mesh.mshcfg.dot11MeshHWMPperrMinInterval, DEC);
|
||||
u.mesh.mshcfg.dot11MeshHWMPperrMinInterval, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshHWMPnetDiameterTraversalTime,
|
||||
u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC);
|
||||
u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshHWMPmaxPREQretries,
|
||||
u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries, DEC);
|
||||
u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries, DEC);
|
||||
IEEE80211_IF_FILE(path_refresh_time,
|
||||
u.mesh.mshcfg.path_refresh_time, DEC);
|
||||
u.mesh.mshcfg.path_refresh_time, DEC);
|
||||
IEEE80211_IF_FILE(min_discovery_timeout,
|
||||
u.mesh.mshcfg.min_discovery_timeout, DEC);
|
||||
u.mesh.mshcfg.min_discovery_timeout, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshHWMPRootMode,
|
||||
u.mesh.mshcfg.dot11MeshHWMPRootMode, DEC);
|
||||
u.mesh.mshcfg.dot11MeshHWMPRootMode, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshGateAnnouncementProtocol,
|
||||
u.mesh.mshcfg.dot11MeshGateAnnouncementProtocol, DEC);
|
||||
u.mesh.mshcfg.dot11MeshGateAnnouncementProtocol, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshHWMPRannInterval,
|
||||
u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC);
|
||||
u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshForwarding, u.mesh.mshcfg.dot11MeshForwarding, DEC);
|
||||
IEEE80211_IF_FILE(rssi_threshold, u.mesh.mshcfg.rssi_threshold, DEC);
|
||||
IEEE80211_IF_FILE(ht_opmode, u.mesh.mshcfg.ht_opmode, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshHWMPactivePathToRootTimeout,
|
||||
u.mesh.mshcfg.dot11MeshHWMPactivePathToRootTimeout, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshHWMProotInterval,
|
||||
u.mesh.mshcfg.dot11MeshHWMProotInterval, DEC);
|
||||
IEEE80211_IF_FILE(dot11MeshHWMPconfirmationInterval,
|
||||
u.mesh.mshcfg.dot11MeshHWMPconfirmationInterval, DEC);
|
||||
#endif
|
||||
|
||||
#define DEBUGFS_ADD_MODE(name, mode) \
|
||||
|
|
@ -611,6 +617,9 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata)
|
|||
MESHPARAMS_ADD(dot11MeshGateAnnouncementProtocol);
|
||||
MESHPARAMS_ADD(rssi_threshold);
|
||||
MESHPARAMS_ADD(ht_opmode);
|
||||
MESHPARAMS_ADD(dot11MeshHWMPactivePathToRootTimeout);
|
||||
MESHPARAMS_ADD(dot11MeshHWMProotInterval);
|
||||
MESHPARAMS_ADD(dot11MeshHWMPconfirmationInterval);
|
||||
#undef MESHPARAMS_ADD
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -279,7 +279,7 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta,
|
|||
/* If it fails, maybe we raced another insertion? */
|
||||
if (sta_info_insert_rcu(sta))
|
||||
return sta_info_get(sdata, addr);
|
||||
if (auth) {
|
||||
if (auth && !sdata->u.ibss.auth_frame_registrations) {
|
||||
ibss_vdbg("TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n",
|
||||
sdata->vif.addr, sdata->u.ibss.bssid, addr);
|
||||
ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, NULL, 0,
|
||||
|
|
|
|||
|
|
@ -55,11 +55,14 @@ struct ieee80211_local;
|
|||
#define TU_TO_JIFFIES(x) (usecs_to_jiffies((x) * 1024))
|
||||
#define TU_TO_EXP_TIME(x) (jiffies + TU_TO_JIFFIES(x))
|
||||
|
||||
/*
|
||||
* Some APs experience problems when working with U-APSD. Decrease the
|
||||
* probability of that happening by using legacy mode for all ACs but VO.
|
||||
* The AP that caused us trouble was a Cisco 4410N. It ignores our
|
||||
* setting, and always treats non-VO ACs as legacy.
|
||||
*/
|
||||
#define IEEE80211_DEFAULT_UAPSD_QUEUES \
|
||||
(IEEE80211_WMM_IE_STA_QOSINFO_AC_BK | \
|
||||
IEEE80211_WMM_IE_STA_QOSINFO_AC_BE | \
|
||||
IEEE80211_WMM_IE_STA_QOSINFO_AC_VI | \
|
||||
IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
|
||||
IEEE80211_WMM_IE_STA_QOSINFO_AC_VO
|
||||
|
||||
#define IEEE80211_DEFAULT_MAX_SP_LEN \
|
||||
IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL
|
||||
|
|
@ -508,6 +511,7 @@ struct ieee80211_if_ibss {
|
|||
bool privacy;
|
||||
|
||||
bool control_port;
|
||||
unsigned int auth_frame_registrations;
|
||||
|
||||
u8 bssid[ETH_ALEN] __aligned(2);
|
||||
u8 ssid[IEEE80211_MAX_SSID_LEN];
|
||||
|
|
@ -677,6 +681,9 @@ struct ieee80211_sub_if_data {
|
|||
/* TID bitmap for NoAck policy */
|
||||
u16 noack_map;
|
||||
|
||||
/* bit field of ACM bits (BIT(802.1D tag)) */
|
||||
u8 wmm_acm;
|
||||
|
||||
struct ieee80211_key __rcu *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
|
||||
struct ieee80211_key __rcu *default_unicast_key;
|
||||
struct ieee80211_key __rcu *default_multicast_key;
|
||||
|
|
@ -881,6 +888,9 @@ struct ieee80211_local {
|
|||
/* device is started */
|
||||
bool started;
|
||||
|
||||
/* device is during a HW reconfig */
|
||||
bool in_reconfig;
|
||||
|
||||
/* wowlan is enabled -- don't reconfig on resume */
|
||||
bool wowlan;
|
||||
|
||||
|
|
@ -1019,7 +1029,6 @@ struct ieee80211_local {
|
|||
int total_ps_buffered; /* total number of all buffered unicast and
|
||||
* multicast packets for power saving stations
|
||||
*/
|
||||
unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */
|
||||
|
||||
bool pspolling;
|
||||
bool offchannel_ps_enabled;
|
||||
|
|
|
|||
|
|
@ -808,7 +808,7 @@ static u16 ieee80211_monitor_select_queue(struct net_device *dev,
|
|||
|
||||
hdr = (void *)((u8 *)skb->data + le16_to_cpu(rtap->it_len));
|
||||
|
||||
return ieee80211_select_queue_80211(local, skb, hdr);
|
||||
return ieee80211_select_queue_80211(sdata, skb, hdr);
|
||||
}
|
||||
|
||||
static const struct net_device_ops ieee80211_monitorif_ops = {
|
||||
|
|
|
|||
|
|
@ -345,6 +345,13 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw)
|
|||
ieee80211_stop_queues_by_reason(hw,
|
||||
IEEE80211_QUEUE_STOP_REASON_SUSPEND);
|
||||
|
||||
/*
|
||||
* Stop all Rx during the reconfig. We don't want state changes
|
||||
* or driver callbacks while this is in progress.
|
||||
*/
|
||||
local->in_reconfig = true;
|
||||
barrier();
|
||||
|
||||
schedule_work(&local->restart_work);
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_restart_hw);
|
||||
|
|
@ -455,7 +462,9 @@ static const struct ieee80211_txrx_stypes
|
|||
ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
|
||||
[NL80211_IFTYPE_ADHOC] = {
|
||||
.tx = 0xffff,
|
||||
.rx = BIT(IEEE80211_STYPE_ACTION >> 4),
|
||||
.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
|
||||
BIT(IEEE80211_STYPE_AUTH >> 4) |
|
||||
BIT(IEEE80211_STYPE_DEAUTH >> 4),
|
||||
},
|
||||
[NL80211_IFTYPE_STATION] = {
|
||||
.tx = 0xffff,
|
||||
|
|
|
|||
|
|
@ -443,7 +443,7 @@ static void ieee80211_mesh_path_root_timer(unsigned long data)
|
|||
|
||||
void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh)
|
||||
{
|
||||
if (ifmsh->mshcfg.dot11MeshHWMPRootMode)
|
||||
if (ifmsh->mshcfg.dot11MeshHWMPRootMode > IEEE80211_ROOTMODE_ROOT)
|
||||
set_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags);
|
||||
else {
|
||||
clear_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags);
|
||||
|
|
@ -541,11 +541,17 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
|
|||
static void ieee80211_mesh_rootpath(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
||||
u32 interval;
|
||||
|
||||
mesh_path_tx_root_frame(sdata);
|
||||
|
||||
if (ifmsh->mshcfg.dot11MeshHWMPRootMode == IEEE80211_PROACTIVE_RANN)
|
||||
interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval;
|
||||
else
|
||||
interval = ifmsh->mshcfg.dot11MeshHWMProotInterval;
|
||||
|
||||
mod_timer(&ifmsh->mesh_path_root_timer,
|
||||
round_jiffies(TU_TO_EXP_TIME(
|
||||
ifmsh->mshcfg.dot11MeshHWMPRannInterval)));
|
||||
round_jiffies(TU_TO_EXP_TIME(interval)));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ enum mesh_deferred_task_flags {
|
|||
* an mpath to a hash bucket on a path table.
|
||||
* @rann_snd_addr: the RANN sender address
|
||||
* @rann_metric: the aggregated path metric towards the root node
|
||||
* @last_preq_to_root: Timestamp of last PREQ sent to root
|
||||
* @is_root: the destination station of this path is a root node
|
||||
* @is_gate: the destination station of this path is a mesh gate
|
||||
*
|
||||
|
|
@ -131,6 +132,7 @@ struct mesh_path {
|
|||
spinlock_t state_lock;
|
||||
u8 rann_snd_addr[ETH_ALEN];
|
||||
u32 rann_metric;
|
||||
unsigned long last_preq_to_root;
|
||||
bool is_root;
|
||||
bool is_gate;
|
||||
};
|
||||
|
|
@ -245,7 +247,7 @@ void mesh_rmc_free(struct ieee80211_sub_if_data *sdata);
|
|||
int mesh_rmc_init(struct ieee80211_sub_if_data *sdata);
|
||||
void ieee80211s_init(void);
|
||||
void ieee80211s_update_metric(struct ieee80211_local *local,
|
||||
struct sta_info *stainfo, struct sk_buff *skb);
|
||||
struct sta_info *sta, struct sk_buff *skb);
|
||||
void ieee80211s_stop(void);
|
||||
void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata);
|
||||
void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata);
|
||||
|
|
|
|||
|
|
@ -98,6 +98,8 @@ static inline u32 u16_field_get(u8 *preq_elem, int offset, bool ae)
|
|||
#define max_preq_retries(s) (s->u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries)
|
||||
#define disc_timeout_jiff(s) \
|
||||
msecs_to_jiffies(sdata->u.mesh.mshcfg.min_discovery_timeout)
|
||||
#define root_path_confirmation_jiffies(s) \
|
||||
msecs_to_jiffies(sdata->u.mesh.mshcfg.dot11MeshHWMPconfirmationInterval)
|
||||
|
||||
enum mpath_frame_type {
|
||||
MPATH_PREQ = 0,
|
||||
|
|
@ -303,7 +305,7 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn,
|
|||
}
|
||||
|
||||
void ieee80211s_update_metric(struct ieee80211_local *local,
|
||||
struct sta_info *stainfo, struct sk_buff *skb)
|
||||
struct sta_info *sta, struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
|
||||
|
|
@ -315,15 +317,14 @@ void ieee80211s_update_metric(struct ieee80211_local *local,
|
|||
failed = !(txinfo->flags & IEEE80211_TX_STAT_ACK);
|
||||
|
||||
/* moving average, scaled to 100 */
|
||||
stainfo->fail_avg = ((80 * stainfo->fail_avg + 5) / 100 + 20 * failed);
|
||||
if (stainfo->fail_avg > 95)
|
||||
mesh_plink_broken(stainfo);
|
||||
sta->fail_avg = ((80 * sta->fail_avg + 5) / 100 + 20 * failed);
|
||||
if (sta->fail_avg > 95)
|
||||
mesh_plink_broken(sta);
|
||||
}
|
||||
|
||||
static u32 airtime_link_metric_get(struct ieee80211_local *local,
|
||||
struct sta_info *sta)
|
||||
{
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct rate_info rinfo;
|
||||
/* This should be adjusted for each device */
|
||||
int device_constant = 1 << ARITH_SHIFT;
|
||||
|
|
@ -333,8 +334,6 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
|
|||
u32 tx_time, estimated_retx;
|
||||
u64 result;
|
||||
|
||||
sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
|
||||
|
||||
if (sta->fail_avg >= 100)
|
||||
return MAX_METRIC;
|
||||
|
||||
|
|
@ -519,10 +518,11 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
|
|||
struct mesh_path *mpath = NULL;
|
||||
u8 *target_addr, *orig_addr;
|
||||
const u8 *da;
|
||||
u8 target_flags, ttl;
|
||||
u32 orig_sn, target_sn, lifetime;
|
||||
u8 target_flags, ttl, flags;
|
||||
u32 orig_sn, target_sn, lifetime, orig_metric;
|
||||
bool reply = false;
|
||||
bool forward = true;
|
||||
bool root_is_gate;
|
||||
|
||||
/* Update target SN, if present */
|
||||
target_addr = PREQ_IE_TARGET_ADDR(preq_elem);
|
||||
|
|
@ -530,6 +530,10 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
|
|||
target_sn = PREQ_IE_TARGET_SN(preq_elem);
|
||||
orig_sn = PREQ_IE_ORIG_SN(preq_elem);
|
||||
target_flags = PREQ_IE_TARGET_F(preq_elem);
|
||||
orig_metric = metric;
|
||||
/* Proactive PREQ gate announcements */
|
||||
flags = PREQ_IE_FLAGS(preq_elem);
|
||||
root_is_gate = !!(flags & RANN_FLAG_IS_GATE);
|
||||
|
||||
mhwmp_dbg("received PREQ from %pM", orig_addr);
|
||||
|
||||
|
|
@ -544,6 +548,22 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
|
|||
target_sn = ++ifmsh->sn;
|
||||
ifmsh->last_sn_update = jiffies;
|
||||
}
|
||||
} else if (is_broadcast_ether_addr(target_addr) &&
|
||||
(target_flags & IEEE80211_PREQ_TO_FLAG)) {
|
||||
rcu_read_lock();
|
||||
mpath = mesh_path_lookup(orig_addr, sdata);
|
||||
if (mpath) {
|
||||
if (flags & IEEE80211_PREQ_PROACTIVE_PREP_FLAG) {
|
||||
reply = true;
|
||||
target_addr = sdata->vif.addr;
|
||||
target_sn = ++ifmsh->sn;
|
||||
metric = 0;
|
||||
ifmsh->last_sn_update = jiffies;
|
||||
}
|
||||
if (root_is_gate)
|
||||
mesh_path_add_gate(mpath);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
} else {
|
||||
rcu_read_lock();
|
||||
mpath = mesh_path_lookup(target_addr, sdata);
|
||||
|
|
@ -576,13 +596,14 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
|
|||
cpu_to_le32(target_sn), mgmt->sa, 0, ttl,
|
||||
cpu_to_le32(lifetime), cpu_to_le32(metric),
|
||||
0, sdata);
|
||||
} else
|
||||
} else {
|
||||
ifmsh->mshstats.dropped_frames_ttl++;
|
||||
}
|
||||
}
|
||||
|
||||
if (forward && ifmsh->mshcfg.dot11MeshForwarding) {
|
||||
u32 preq_id;
|
||||
u8 hopcount, flags;
|
||||
u8 hopcount;
|
||||
|
||||
ttl = PREQ_IE_TTL(preq_elem);
|
||||
lifetime = PREQ_IE_LIFETIME(preq_elem);
|
||||
|
|
@ -592,11 +613,17 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
|
|||
}
|
||||
mhwmp_dbg("forwarding the PREQ from %pM", orig_addr);
|
||||
--ttl;
|
||||
flags = PREQ_IE_FLAGS(preq_elem);
|
||||
preq_id = PREQ_IE_PREQ_ID(preq_elem);
|
||||
hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1;
|
||||
da = (mpath && mpath->is_root) ?
|
||||
mpath->rann_snd_addr : broadcast_addr;
|
||||
|
||||
if (flags & IEEE80211_PREQ_PROACTIVE_PREP_FLAG) {
|
||||
target_addr = PREQ_IE_TARGET_ADDR(preq_elem);
|
||||
target_sn = PREQ_IE_TARGET_SN(preq_elem);
|
||||
metric = orig_metric;
|
||||
}
|
||||
|
||||
mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr,
|
||||
cpu_to_le32(orig_sn), target_flags, target_addr,
|
||||
cpu_to_le32(target_sn), da,
|
||||
|
|
@ -744,11 +771,6 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
|
|||
bool root_is_gate;
|
||||
|
||||
ttl = rann->rann_ttl;
|
||||
if (ttl <= 1) {
|
||||
ifmsh->mshstats.dropped_frames_ttl++;
|
||||
return;
|
||||
}
|
||||
ttl--;
|
||||
flags = rann->rann_flags;
|
||||
root_is_gate = !!(flags & RANN_FLAG_IS_GATE);
|
||||
orig_addr = rann->rann_addr;
|
||||
|
|
@ -785,34 +807,49 @@ 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)) {
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
if ((!(mpath->flags & (MESH_PATH_ACTIVE | MESH_PATH_RESOLVING)) ||
|
||||
time_after(jiffies, mpath->exp_time - 1*HZ)) &&
|
||||
!(mpath->flags & MESH_PATH_FIXED)) {
|
||||
(time_after(jiffies, mpath->last_preq_to_root +
|
||||
root_path_confirmation_jiffies(sdata)) ||
|
||||
time_before(jiffies, mpath->last_preq_to_root))) &&
|
||||
!(mpath->flags & MESH_PATH_FIXED) && (ttl != 0)) {
|
||||
mhwmp_dbg("%s time to refresh root mpath %pM", sdata->name,
|
||||
orig_addr);
|
||||
mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH);
|
||||
mpath->last_preq_to_root = jiffies;
|
||||
}
|
||||
|
||||
if ((SN_LT(mpath->sn, orig_sn) || (mpath->sn == orig_sn &&
|
||||
metric < mpath->rann_metric)) && ifmsh->mshcfg.dot11MeshForwarding) {
|
||||
mpath->sn = orig_sn;
|
||||
mpath->rann_metric = metric + metric_txsta;
|
||||
mpath->is_root = true;
|
||||
/* Recording RANNs sender address to send individually
|
||||
* addressed PREQs destined for root mesh STA */
|
||||
memcpy(mpath->rann_snd_addr, mgmt->sa, ETH_ALEN);
|
||||
|
||||
if (root_is_gate)
|
||||
mesh_path_add_gate(mpath);
|
||||
|
||||
if (ttl <= 1) {
|
||||
ifmsh->mshstats.dropped_frames_ttl++;
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
ttl--;
|
||||
|
||||
if (ifmsh->mshcfg.dot11MeshForwarding) {
|
||||
mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr,
|
||||
cpu_to_le32(orig_sn),
|
||||
0, NULL, 0, broadcast_addr,
|
||||
hopcount, ttl, cpu_to_le32(interval),
|
||||
cpu_to_le32(metric + metric_txsta),
|
||||
0, sdata);
|
||||
mpath->sn = orig_sn;
|
||||
mpath->rann_metric = metric + metric_txsta;
|
||||
/* Recording RANNs sender address to send individually
|
||||
* addressed PREQs destined for root mesh STA */
|
||||
memcpy(mpath->rann_snd_addr, mgmt->sa, ETH_ALEN);
|
||||
}
|
||||
|
||||
mpath->is_root = true;
|
||||
|
||||
if (root_is_gate)
|
||||
mesh_path_add_gate(mpath);
|
||||
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
|
|
@ -1157,13 +1194,34 @@ mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata)
|
|||
{
|
||||
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
||||
u32 interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval;
|
||||
u8 flags;
|
||||
u8 flags, target_flags = 0;
|
||||
|
||||
flags = (ifmsh->mshcfg.dot11MeshGateAnnouncementProtocol)
|
||||
? RANN_FLAG_IS_GATE : 0;
|
||||
mesh_path_sel_frame_tx(MPATH_RANN, flags, sdata->vif.addr,
|
||||
|
||||
switch (ifmsh->mshcfg.dot11MeshHWMPRootMode) {
|
||||
case IEEE80211_PROACTIVE_RANN:
|
||||
mesh_path_sel_frame_tx(MPATH_RANN, flags, sdata->vif.addr,
|
||||
cpu_to_le32(++ifmsh->sn),
|
||||
0, NULL, 0, broadcast_addr,
|
||||
0, sdata->u.mesh.mshcfg.element_ttl,
|
||||
0, ifmsh->mshcfg.element_ttl,
|
||||
cpu_to_le32(interval), 0, 0, sdata);
|
||||
break;
|
||||
case IEEE80211_PROACTIVE_PREQ_WITH_PREP:
|
||||
flags |= IEEE80211_PREQ_PROACTIVE_PREP_FLAG;
|
||||
case IEEE80211_PROACTIVE_PREQ_NO_PREP:
|
||||
interval = ifmsh->mshcfg.dot11MeshHWMPactivePathToRootTimeout;
|
||||
target_flags |= IEEE80211_PREQ_TO_FLAG |
|
||||
IEEE80211_PREQ_USN_FLAG;
|
||||
mesh_path_sel_frame_tx(MPATH_PREQ, flags, sdata->vif.addr,
|
||||
cpu_to_le32(++ifmsh->sn), target_flags,
|
||||
(u8 *) broadcast_addr, 0, broadcast_addr,
|
||||
0, ifmsh->mshcfg.element_ttl,
|
||||
cpu_to_le32(interval),
|
||||
0, cpu_to_le32(ifmsh->preq_id++), sdata);
|
||||
break;
|
||||
default:
|
||||
mhwmp_dbg("Proactive mechanism not supported");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1141,7 +1141,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
|
|||
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
|
||||
local->wmm_acm = 0;
|
||||
sdata->wmm_acm = 0;
|
||||
for (; left >= 4; left -= 4, pos += 4) {
|
||||
int aci = (pos[0] >> 5) & 0x03;
|
||||
int acm = (pos[0] >> 4) & 0x01;
|
||||
|
|
@ -1152,21 +1152,21 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
|
|||
case 1: /* AC_BK */
|
||||
queue = 3;
|
||||
if (acm)
|
||||
local->wmm_acm |= BIT(1) | BIT(2); /* BK/- */
|
||||
sdata->wmm_acm |= BIT(1) | BIT(2); /* BK/- */
|
||||
if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
|
||||
uapsd = true;
|
||||
break;
|
||||
case 2: /* AC_VI */
|
||||
queue = 1;
|
||||
if (acm)
|
||||
local->wmm_acm |= BIT(4) | BIT(5); /* CL/VI */
|
||||
sdata->wmm_acm |= BIT(4) | BIT(5); /* CL/VI */
|
||||
if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
|
||||
uapsd = true;
|
||||
break;
|
||||
case 3: /* AC_VO */
|
||||
queue = 0;
|
||||
if (acm)
|
||||
local->wmm_acm |= BIT(6) | BIT(7); /* VO/NC */
|
||||
sdata->wmm_acm |= BIT(6) | BIT(7); /* VO/NC */
|
||||
if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
|
||||
uapsd = true;
|
||||
break;
|
||||
|
|
@ -1174,7 +1174,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
|
|||
default:
|
||||
queue = 2;
|
||||
if (acm)
|
||||
local->wmm_acm |= BIT(0) | BIT(3); /* BE/EE */
|
||||
sdata->wmm_acm |= BIT(0) | BIT(3); /* BE/EE */
|
||||
if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
|
||||
uapsd = true;
|
||||
break;
|
||||
|
|
@ -1275,7 +1275,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
bss_info_changed |= BSS_CHANGED_BEACON_INT;
|
||||
bss_info_changed |= ieee80211_handle_bss_capability(sdata,
|
||||
cbss->capability, bss->has_erp_value, bss->erp_value);
|
||||
bss_conf->assoc_capability, bss->has_erp_value, bss->erp_value);
|
||||
|
||||
sdata->u.mgd.beacon_timeout = usecs_to_jiffies(ieee80211_tu_to_usec(
|
||||
IEEE80211_BEACON_LOSS_COUNT * bss_conf->beacon_int));
|
||||
|
|
@ -3012,7 +3012,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
|
|||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
||||
struct ieee80211_bss *bss = (void *)cbss->priv;
|
||||
struct sta_info *sta;
|
||||
struct sta_info *sta = NULL;
|
||||
bool have_sta = false;
|
||||
int err;
|
||||
int ht_cfreq;
|
||||
|
|
@ -3102,7 +3102,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
|
|||
local->oper_channel = cbss->channel;
|
||||
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
|
||||
|
||||
if (!have_sta) {
|
||||
if (sta) {
|
||||
u32 rates = 0, basic_rates = 0;
|
||||
bool have_higher_than_11mbit;
|
||||
int min_rate = INT_MAX, min_rate_index = -1;
|
||||
|
|
|
|||
|
|
@ -25,8 +25,7 @@
|
|||
* because we *may* be doing work on-operating channel, and want our
|
||||
* hardware unconditionally awake, but still let the AP send us normal frames.
|
||||
*/
|
||||
static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata,
|
||||
bool tell_ap)
|
||||
static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
||||
|
|
@ -47,8 +46,8 @@ static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata,
|
|||
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
|
||||
}
|
||||
|
||||
if (tell_ap && (!local->offchannel_ps_enabled ||
|
||||
!(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)))
|
||||
if (!local->offchannel_ps_enabled ||
|
||||
!(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK))
|
||||
/*
|
||||
* If power save was enabled, no need to send a nullfunc
|
||||
* frame because AP knows that we are sleeping. But if the
|
||||
|
|
@ -133,7 +132,7 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local,
|
|||
if (offchannel_ps_enable &&
|
||||
(sdata->vif.type == NL80211_IFTYPE_STATION) &&
|
||||
sdata->u.mgd.associated)
|
||||
ieee80211_offchannel_ps_enable(sdata, true);
|
||||
ieee80211_offchannel_ps_enable(sdata);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&local->iflist_mtx);
|
||||
|
|
@ -263,6 +262,9 @@ void ieee80211_start_next_roc(struct ieee80211_local *local)
|
|||
roc = list_first_entry(&local->roc_list, struct ieee80211_roc_work,
|
||||
list);
|
||||
|
||||
if (WARN_ON_ONCE(roc->started))
|
||||
return;
|
||||
|
||||
if (local->ops->remain_on_channel) {
|
||||
int ret, duration = roc->duration;
|
||||
|
||||
|
|
@ -378,8 +380,8 @@ void ieee80211_sw_roc_work(struct work_struct *work)
|
|||
|
||||
ieee80211_recalc_idle(local);
|
||||
|
||||
ieee80211_start_next_roc(local);
|
||||
ieee80211_run_deferred_scan(local);
|
||||
if (roc->started)
|
||||
ieee80211_start_next_roc(local);
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
|
|
@ -410,9 +412,6 @@ static void ieee80211_hw_roc_done(struct work_struct *work)
|
|||
/* if there's another roc, start it now */
|
||||
ieee80211_start_next_roc(local);
|
||||
|
||||
/* or scan maybe */
|
||||
ieee80211_run_deferred_scan(local);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&local->mtx);
|
||||
}
|
||||
|
|
@ -455,7 +454,6 @@ void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata)
|
|||
}
|
||||
|
||||
ieee80211_start_next_roc(local);
|
||||
ieee80211_run_deferred_scan(local);
|
||||
mutex_unlock(&local->mtx);
|
||||
|
||||
list_for_each_entry_safe(roc, tmp, &tmp_list, list) {
|
||||
|
|
|
|||
|
|
@ -78,6 +78,16 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
|
|||
if (err < 0) {
|
||||
local->quiescing = false;
|
||||
local->wowlan = false;
|
||||
if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
|
||||
mutex_lock(&local->sta_mtx);
|
||||
list_for_each_entry(sta,
|
||||
&local->sta_list, list) {
|
||||
clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
|
||||
}
|
||||
mutex_unlock(&local->sta_mtx);
|
||||
}
|
||||
ieee80211_wake_queues_by_reason(hw,
|
||||
IEEE80211_QUEUE_STOP_REASON_SUSPEND);
|
||||
return err;
|
||||
} else if (err > 0) {
|
||||
WARN_ON(err != 1);
|
||||
|
|
|
|||
|
|
@ -1935,7 +1935,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
|
|||
ether_addr_equal(sdata->vif.addr, hdr->addr3))
|
||||
return RX_CONTINUE;
|
||||
|
||||
q = ieee80211_select_queue_80211(local, skb, hdr);
|
||||
q = ieee80211_select_queue_80211(sdata, skb, hdr);
|
||||
if (ieee80211_queue_stopped(&local->hw, q)) {
|
||||
IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion);
|
||||
return RX_DROP_MONITOR;
|
||||
|
|
@ -3027,6 +3027,10 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
|
|||
if (unlikely(local->quiescing || local->suspended))
|
||||
goto drop;
|
||||
|
||||
/* We might be during a HW reconfig, prevent Rx for the same reason */
|
||||
if (unlikely(local->in_reconfig))
|
||||
goto drop;
|
||||
|
||||
/*
|
||||
* The same happens when we're not even started,
|
||||
* but that's worth a warning.
|
||||
|
|
|
|||
|
|
@ -1411,6 +1411,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
|
|||
if (ieee80211_sdata_running(sdata))
|
||||
ieee80211_enable_keys(sdata);
|
||||
|
||||
local->in_reconfig = false;
|
||||
barrier();
|
||||
|
||||
wake_up:
|
||||
/*
|
||||
* Clear the WLAN_STA_BLOCK_BA flag so new aggregation
|
||||
|
|
|
|||
|
|
@ -52,11 +52,11 @@ static int wme_downgrade_ac(struct sk_buff *skb)
|
|||
}
|
||||
}
|
||||
|
||||
static u16 ieee80211_downgrade_queue(struct ieee80211_local *local,
|
||||
static u16 ieee80211_downgrade_queue(struct ieee80211_sub_if_data *sdata,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
/* in case we are a client verify acm is not set for this ac */
|
||||
while (unlikely(local->wmm_acm & BIT(skb->priority))) {
|
||||
while (unlikely(sdata->wmm_acm & BIT(skb->priority))) {
|
||||
if (wme_downgrade_ac(skb)) {
|
||||
/*
|
||||
* This should not really happen. The AP has marked all
|
||||
|
|
@ -73,10 +73,11 @@ static u16 ieee80211_downgrade_queue(struct ieee80211_local *local,
|
|||
}
|
||||
|
||||
/* Indicate which queue to use for this fully formed 802.11 frame */
|
||||
u16 ieee80211_select_queue_80211(struct ieee80211_local *local,
|
||||
u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata,
|
||||
struct sk_buff *skb,
|
||||
struct ieee80211_hdr *hdr)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
u8 *p;
|
||||
|
||||
if (local->hw.queues < IEEE80211_NUM_ACS)
|
||||
|
|
@ -94,7 +95,7 @@ u16 ieee80211_select_queue_80211(struct ieee80211_local *local,
|
|||
p = ieee80211_get_qos_ctl(hdr);
|
||||
skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK;
|
||||
|
||||
return ieee80211_downgrade_queue(local, skb);
|
||||
return ieee80211_downgrade_queue(sdata, skb);
|
||||
}
|
||||
|
||||
/* Indicate which queue to use. */
|
||||
|
|
@ -156,7 +157,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
|
|||
* data frame has */
|
||||
skb->priority = cfg80211_classify8021d(skb);
|
||||
|
||||
return ieee80211_downgrade_queue(local, skb);
|
||||
return ieee80211_downgrade_queue(sdata, skb);
|
||||
}
|
||||
|
||||
void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
extern const int ieee802_1d_to_ac[8];
|
||||
|
||||
u16 ieee80211_select_queue_80211(struct ieee80211_local *local,
|
||||
u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata,
|
||||
struct sk_buff *skb,
|
||||
struct ieee80211_hdr *hdr);
|
||||
u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
|
||||
|
|
|
|||
Loading…
Reference in a new issue