Release 4.11 net/mac80211/util.c
/*
* Copyright 2002-2005, Instant802 Networks, Inc.
* Copyright 2005-2006, Devicescape Software, Inc.
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
* Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright (C) 2015-2016 Intel Deutschland GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* utilities for mac80211
*/
#include <net/mac80211.h>
#include <linux/netdevice.h>
#include <linux/export.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
#include <linux/bitmap.h>
#include <linux/crc32.h>
#include <net/net_namespace.h>
#include <net/cfg80211.h>
#include <net/rtnetlink.h>
#include "ieee80211_i.h"
#include "driver-ops.h"
#include "rate.h"
#include "mesh.h"
#include "wme.h"
#include "led.h"
#include "wep.h"
/* privid for wiphys to determine whether they belong to us or not */
const void *const mac80211_wiphy_privid = &mac80211_wiphy_privid;
struct ieee80211_hw *wiphy_to_ieee80211_hw(struct wiphy *wiphy)
{
struct ieee80211_local *local;
BUG_ON(!wiphy);
local = wiphy_priv(wiphy);
return &local->hw;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Luis R. Rodriguez | 36 | 100.00% | 1 | 100.00% |
Total | 36 | 100.00% | 1 | 100.00% |
EXPORT_SYMBOL(wiphy_to_ieee80211_hw);
void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx)
{
struct sk_buff *skb;
struct ieee80211_hdr *hdr;
skb_queue_walk(&tx->skbs, skb) {
hdr = (struct ieee80211_hdr *) skb->data;
hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Berg | 48 | 100.00% | 4 | 100.00% |
Total | 48 | 100.00% | 4 | 100.00% |
int ieee80211_frame_duration(enum nl80211_band band, size_t len,
int rate, int erp, int short_preamble,
int shift)
{
int dur;
/* calculate duration (in microseconds, rounded up to next higher
* integer if it includes a fractional microsecond) to send frame of
* len bytes (does not include FCS) at the given rate. Duration will
* also include SIFS.
*
* rate is in 100 kbps, so divident is multiplied by 10 in the
* DIV_ROUND_UP() operations.
*
* shift may be 2 for 5 MHz channels or 1 for 10 MHz channels, and
* is assumed to be 0 otherwise.
*/
if (band == NL80211_BAND_5GHZ || erp) {
/*
* OFDM:
*
* N_DBPS = DATARATE x 4
* N_SYM = Ceiling((16+8xLENGTH+6) / N_DBPS)
* (16 = SIGNAL time, 6 = tail bits)
* TXTIME = T_PREAMBLE + T_SIGNAL + T_SYM x N_SYM + Signal Ext
*
* T_SYM = 4 usec
* 802.11a - 18.5.2: aSIFSTime = 16 usec
* 802.11g - 19.8.4: aSIFSTime = 10 usec +
* signal ext = 6 usec
*/
dur = 16; /* SIFS + signal ext */
dur += 16; /* IEEE 802.11-2012 18.3.2.4: T_PREAMBLE = 16 usec */
dur += 4; /* IEEE 802.11-2012 18.3.2.4: T_SIGNAL = 4 usec */
/* IEEE 802.11-2012 18.3.2.4: all values above are:
* * times 4 for 5 MHz
* * times 2 for 10 MHz
*/
dur *= 1 << shift;
/* rates should already consider the channel bandwidth,
* don't apply divisor again.
*/
dur += 4 * DIV_ROUND_UP((16 + 8 * (len + 4) + 6) * 10,
4 * rate); /* T_SYM x N_SYM */
} else {
/*
* 802.11b or 802.11g with 802.11b compatibility:
* 18.3.4: TXTIME = PreambleLength + PLCPHeaderTime +
* Ceiling(((LENGTH+PBCC)x8)/DATARATE). PBCC=0.
*
* 802.11 (DS): 15.3.3, 802.11b: 18.3.4
* aSIFSTime = 10 usec
* aPreambleLength = 144 usec or 72 usec with short preamble
* aPLCPHeaderLength = 48 usec or 24 usec with short preamble
*/
dur = 10; /* aSIFSTime = 10 usec */
dur += short_preamble ? (72 + 24) : (144 + 48);
dur += DIV_ROUND_UP(8 * (len + 4) * 10, rate);
}
return dur;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Berg | 118 | 87.41% | 3 | 50.00% |
Simon Wunderlich | 15 | 11.11% | 2 | 33.33% |
Michal Kazior | 2 | 1.48% | 1 | 16.67% |
Total | 135 | 100.00% | 6 | 100.00% |
/* Exported duration function for driver use */
__le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
enum nl80211_band band,
size_t frame_len,
struct ieee80211_rate *rate)
{
struct ieee80211_sub_if_data *sdata;
u16 dur;
int erp, shift = 0;
bool short_preamble = false;
erp = 0;
if (vif) {
sdata = vif_to_sdata(vif);
short_preamble = sdata->vif.bss_conf.use_short_preamble;
if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
erp = rate->flags & IEEE80211_RATE_ERP_G;
shift = ieee80211_vif_get_shift(vif);
}
dur = ieee80211_frame_duration(band, frame_len, rate->bitrate, erp,
short_preamble, shift);
return cpu_to_le16(dur);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Berg | 102 | 83.61% | 6 | 66.67% |
Simon Wunderlich | 13 | 10.66% | 1 | 11.11% |
Michal Kazior | 4 | 3.28% | 1 | 11.11% |
Daniel Drake | 3 | 2.46% | 1 | 11.11% |
Total | 122 | 100.00% | 9 | 100.00% |
EXPORT_SYMBOL(ieee80211_generic_frame_duration);
__le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, size_t frame_len,
const struct ieee80211_tx_info *frame_txctl)
{
struct ieee80211_local *local = hw_to_local(hw);
struct ieee80211_rate *rate;
struct ieee80211_sub_if_data *sdata;
bool short_preamble;
int erp, shift = 0, bitrate;
u16 dur;
struct ieee80211_supported_band *sband;
sband = local->hw.wiphy->bands[frame_txctl->band];
short_preamble = false;
rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx];
erp = 0;
if (vif) {
sdata = vif_to_sdata(vif);
short_preamble = sdata->vif.bss_conf.use_short_preamble;
if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
erp = rate->flags & IEEE80211_RATE_ERP_G;
shift = ieee80211_vif_get_shift(vif);
}
bitrate = DIV_ROUND_UP(rate->bitrate, 1 << shift);
/* CTS duration */
dur = ieee80211_frame_duration(sband->band, 10, bitrate,
erp, short_preamble, shift);
/* Data frame duration */
dur += ieee80211_frame_duration(sband->band, frame_len, bitrate,
erp, short_preamble, shift);
/* ACK duration */
dur += ieee80211_frame_duration(sband->band, 10, bitrate,
erp, short_preamble, shift);
return cpu_to_le16(dur);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Berg | 177 | 78.32% | 8 | 66.67% |
Simon Wunderlich | 32 | 14.16% | 2 | 16.67% |
Michal Kazior | 10 | 4.42% | 1 | 8.33% |
Daniel Drake | 7 | 3.10% | 1 | 8.33% |
Total | 226 | 100.00% | 12 | 100.00% |
EXPORT_SYMBOL(ieee80211_rts_duration);
__le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
size_t frame_len,
const struct ieee80211_tx_info *frame_txctl)
{
struct ieee80211_local *local = hw_to_local(hw);
struct ieee80211_rate *rate;
struct ieee80211_sub_if_data *sdata;
bool short_preamble;
int erp, shift = 0, bitrate;
u16 dur;
struct ieee80211_supported_band *sband;
sband = local->hw.wiphy->bands[frame_txctl->band];
short_preamble = false;
rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx];
erp = 0;
if (vif) {
sdata = vif_to_sdata(vif);
short_preamble = sdata->vif.bss_conf.use_short_preamble;
if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
erp = rate->flags & IEEE80211_RATE_ERP_G;
shift = ieee80211_vif_get_shift(vif);
}
bitrate = DIV_ROUND_UP(rate->bitrate, 1 << shift);
/* Data frame duration */
dur = ieee80211_frame_duration(sband->band, frame_len, bitrate,
erp, short_preamble, shift);
if (!(frame_txctl->flags & IEEE80211_TX_CTL_NO_ACK)) {
/* ACK duration */
dur += ieee80211_frame_duration(sband->band, 10, bitrate,
erp, short_preamble, shift);
}
return cpu_to_le16(dur);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Berg | 175 | 79.91% | 8 | 66.67% |
Simon Wunderlich | 30 | 13.70% | 2 | 16.67% |
Michal Kazior | 7 | 3.20% | 1 | 8.33% |
Daniel Drake | 7 | 3.20% | 1 | 8.33% |
Total | 219 | 100.00% | 12 | 100.00% |
EXPORT_SYMBOL(ieee80211_ctstoself_duration);
void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue)
{
struct ieee80211_sub_if_data *sdata;
int n_acs = IEEE80211_NUM_ACS;
if (local->ops->wake_tx_queue)
return;
if (local->hw.queues < IEEE80211_NUM_ACS)
n_acs = 1;
list_for_each_entry_rcu(sdata, &local->interfaces, list) {
int ac;
if (!sdata->dev)
continue;
if (sdata->vif.cab_queue != IEEE80211_INVAL_HW_QUEUE &&
local->queue_stop_reasons[sdata->vif.cab_queue] != 0)
continue;
for (ac = 0; ac < n_acs; ac++) {
int ac_queue = sdata->vif.hw_queue[ac];
if (ac_queue == queue ||
(sdata->vif.cab_queue == queue &&
local->queue_stop_reasons[ac_queue] == 0 &&
skb_queue_empty(&local->pending[ac_queue])))
netif_wake_subqueue(sdata->dev, ac);
}
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Berg | 154 | 94.48% | 3 | 75.00% |
Michal Kazior | 9 | 5.52% | 1 | 25.00% |
Total | 163 | 100.00% | 4 | 100.00% |
static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
enum queue_stop_reason reason,
bool refcounted)
{
struct ieee80211_local *local = hw_to_local(hw);
trace_wake_queue(local, queue, reason);
if (WARN_ON(queue >= hw->queues))
return;
if (!test_bit(reason, &local->queue_stop_reasons[queue]))
return;
if (!refcounted) {
local->q_stop_reasons[queue][reason] = 0;
} else {
local->q_stop_reasons[queue][reason]--;
if (WARN_ON(local->q_stop_reasons[queue][reason] < 0))
local->q_stop_reasons[queue][reason] = 0;
}
if (local->q_stop_reasons[queue][reason] == 0)
__clear_bit(reason, &local->queue_stop_reasons[queue]);
if (local->queue_stop_reasons[queue] != 0)
/* someone still has this queue stopped */
return;
if (skb_queue_empty(&local->pending[queue])) {
rcu_read_lock();
ieee80211_propagate_queue_wake(local, queue);
rcu_read_unlock();
} else
tasklet_schedule(&local->tx_pending_tasklet);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Berg | 134 | 64.42% | 11 | 78.57% |
Luciano Coelho | 46 | 22.12% | 1 | 7.14% |
Kalle Valo | 26 | 12.50% | 1 | 7.14% |
Tomas Winkler | 2 | 0.96% | 1 | 7.14% |
Total | 208 | 100.00% | 14 | 100.00% |
void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
enum queue_stop_reason reason,
bool refcounted)
{
struct ieee80211_local *local = hw_to_local(hw);
unsigned long flags;
spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
__ieee80211_wake_queue(hw, queue, reason, refcounted);
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Kalle Valo | 60 | 92.31% | 1 | 50.00% |
Luciano Coelho | 5 | 7.69% | 1 | 50.00% |
Total | 65 | 100.00% | 2 | 100.00% |
void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue)
{
ieee80211_wake_queue_by_reason(hw, queue,
IEEE80211_QUEUE_STOP_REASON_DRIVER,
false);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Kalle Valo | 22 | 91.67% | 1 | 50.00% |
Luciano Coelho | 2 | 8.33% | 1 | 50.00% |
Total | 24 | 100.00% | 2 | 100.00% |
EXPORT_SYMBOL(ieee80211_wake_queue);
static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
enum queue_stop_reason reason,
bool refcounted)
{
struct ieee80211_local *local = hw_to_local(hw);
struct ieee80211_sub_if_data *sdata;
int n_acs = IEEE80211_NUM_ACS;
trace_stop_queue(local, queue, reason);
if (WARN_ON(queue >= hw->queues))
return;
if (!refcounted)
local->q_stop_reasons[queue][reason] = 1;
else
local->q_stop_reasons[queue][reason]++;
if (__test_and_set_bit(reason, &local->queue_stop_reasons[queue]))
return;
if (local->ops->wake_tx_queue)
return;
if (local->hw.queues < IEEE80211_NUM_ACS)
n_acs = 1;
rcu_read_lock();
list_for_each_entry_rcu(sdata, &local->interfaces, list) {
int ac;
if (!sdata->dev)
continue;
for (ac = 0; ac < n_acs; ac++) {
if (sdata->vif.hw_queue[ac] == queue ||
sdata->vif.cab_queue == queue)
netif_stop_subqueue(sdata->dev, ac);
}
}
rcu_read_unlock();
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Berg | 155 | 76.73% | 11 | 78.57% |
Luciano Coelho | 29 | 14.36% | 1 | 7.14% |
Kalle Valo | 9 | 4.46% | 1 | 7.14% |
Michal Kazior | 9 | 4.46% | 1 | 7.14% |
Total | 202 | 100.00% | 14 | 100.00% |
void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue,
enum queue_stop_reason reason,
bool refcounted)
{
struct ieee80211_local *local = hw_to_local(hw);
unsigned long flags;
spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
__ieee80211_stop_queue(hw, queue, reason, refcounted);
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Kalle Valo | 60 | 92.31% | 1 | 50.00% |
Luciano Coelho | 5 | 7.69% | 1 | 50.00% |
Total | 65 | 100.00% | 2 | 100.00% |
void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue)
{
ieee80211_stop_queue_by_reason(hw, queue,
IEEE80211_QUEUE_STOP_REASON_DRIVER,
false);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Kalle Valo | 22 | 91.67% | 1 | 50.00% |
Luciano Coelho | 2 | 8.33% | 1 | 50.00% |
Total | 24 | 100.00% | 2 | 100.00% |
EXPORT_SYMBOL(ieee80211_stop_queue);
void ieee80211_add_pending_skb(struct ieee80211_local *local,
struct sk_buff *skb)
{
struct ieee80211_hw *hw = &local->hw;
unsigned long flags;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
int queue = info->hw_queue;
if (WARN_ON(!info->control.vif)) {
ieee80211_free_txskb(&local->hw, skb);
return;
}
spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
__ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
false);
__skb_queue_tail(&local->pending[queue], skb);
__ieee80211_wake_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
false);
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Berg | 116 | 92.06% | 4 | 66.67% |
Felix Fietkau | 6 | 4.76% | 1 | 16.67% |
Luciano Coelho | 4 | 3.17% | 1 | 16.67% |
Total | 126 | 100.00% | 6 | 100.00% |
void ieee80211_add_pending_skbs(struct ieee80211_local *local,
struct sk_buff_head *skbs)
{
struct ieee80211_hw *hw = &local->hw;
struct sk_buff *skb;
unsigned long flags;
int queue, i;
spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
while ((skb = skb_dequeue(skbs))) {
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
if (WARN_ON(!info->control.vif)) {
ieee80211_free_txskb(&local->hw, skb);
continue;
}
queue = info->hw_queue;
__ieee80211_stop_queue(hw, queue,
IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
false);
__skb_queue_tail(&local->pending[queue], skb);
}
for (i = 0; i < hw->queues; i++)
__ieee80211_wake_queue(hw, i,
IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
false);
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Berg | 153 | 93.87% | 7 | 77.78% |
Felix Fietkau | 6 | 3.68% | 1 | 11.11% |
Luciano Coelho | 4 | 2.45% | 1 | 11.11% |
Total | 163 | 100.00% | 9 | 100.00% |
void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
unsigned long queues,
enum queue_stop_reason reason,
bool refcounted)
{
struct ieee80211_local *local = hw_to_local(hw);
unsigned long flags;
int i;
spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
for_each_set_bit(i, &queues, hw->queues)
__ieee80211_stop_queue(hw, i, reason, refcounted);
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Kalle Valo | 45 | 58.44% | 1 | 25.00% |
Johannes Berg | 27 | 35.06% | 2 | 50.00% |
Luciano Coelho | 5 | 6.49% | 1 | 25.00% |
Total | 77 | 100.00% | 4 | 100.00% |
void ieee80211_stop_queues(struct ieee80211_hw *hw)
{
ieee80211_stop_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
IEEE80211_QUEUE_STOP_REASON_DRIVER,
false);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Kalle Valo | 14 | 66.67% | 1 | 25.00% |
Johannes Berg | 5 | 23.81% | 2 | 50.00% |
Luciano Coelho | 2 | 9.52% | 1 | 25.00% |
Total | 21 | 100.00% | 4 | 100.00% |
EXPORT_SYMBOL(ieee80211_stop_queues);
int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue)
{
struct ieee80211_local *local = hw_to_local(hw);
unsigned long flags;
int ret;
if (WARN_ON(queue >= hw->queues))
return true;
spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
ret = test_bit(IEEE80211_QUEUE_STOP_REASON_DRIVER,
&local->queue_stop_reasons[queue]);
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
return ret;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Berg | 46 | 56.10% | 3 | 60.00% |
Tomas Winkler | 30 | 36.59% | 1 | 20.00% |
Thomas Pedersen | 6 | 7.32% | 1 | 20.00% |
Total | 82 | 100.00% | 5 | 100.00% |
EXPORT_SYMBOL(ieee80211_queue_stopped);
void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
unsigned long queues,
enum queue_stop_reason reason,
bool refcounted)
{
struct ieee80211_local *local = hw_to_local(hw);
unsigned long flags;
int i;
spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
for_each_set_bit(i, &queues, hw->queues)
__ieee80211_wake_queue(hw, i, reason, refcounted);
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Kalle Valo | 45 | 58.44% | 1 | 25.00% |
Johannes Berg | 27 | 35.06% | 2 | 50.00% |
Luciano Coelho | 5 | 6.49% | 1 | 25.00% |
Total | 77 | 100.00% | 4 | 100.00% |
void ieee80211_wake_queues(struct ieee80211_hw *hw)
{
ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
IEEE80211_QUEUE_STOP_REASON_DRIVER,
false);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Kalle Valo | 14 | 66.67% | 1 | 25.00% |
Johannes Berg | 5 | 23.81% | 2 | 50.00% |
Luciano Coelho | 2 | 9.52% | 1 | 25.00% |
Total | 21 | 100.00% | 4 | 100.00% |
EXPORT_SYMBOL(ieee80211_wake_queues);
static unsigned int
ieee80211_get_vif_queues(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata)
{
unsigned int queues;
if (sdata && ieee80211_hw_check(&local->hw, QUEUE_CONTROL)) {
int ac;
queues = 0;
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
queues |= BIT(sdata->vif.hw_queue[ac]);
if (sdata->vif.cab_queue != IEEE80211_INVAL_HW_QUEUE)
queues |= BIT(sdata->vif.cab_queue);
} else {
/* all queues */
queues = BIT(local->hw.queues) - 1;
}
return queues;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Berg | 102 | 91.07% | 2 | 66.67% |
Luciano Coelho | 10 | 8.93% | 1 | 33.33% |
Total | 112 | 100.00% | 3 | 100.00% |
void __ieee80211_flush_queues(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
unsigned int queues, bool drop)
{
if (!local->ops->flush)
return;
/*
* If no queue was set, or if the HW doesn't support
* IEEE80211_HW_QUEUE_CONTROL - flush all queues
*/
if (!queues || !ieee80211_hw_check(&local->hw, QUEUE_CONTROL))
queues = ieee80211_get_vif_queues(local, sdata);
ieee80211_stop_queues_by_reason(&local->hw, queues,
IEEE80211_QUEUE_STOP_REASON_FLUSH,
false);
drv_flush(local, sdata, queues, drop);
ieee80211_wake_queues_by_reason(&local->hw, queues,
IEEE80211_QUEUE_STOP_REASON_FLUSH,
false);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Luciano Coelho | 39 | 40.21% | 3 | 33.33% |
Johannes Berg | 37 | 38.14% | 3 | 33.33% |
Liad Kaufman | 15 | 15.46% | 1 | 11.11% |
Emmanuel Grumbach | 6 | 6.19% | 2 | 22.22% |
Total | 97 | 100.00% | 9 | 100.00% |
void ieee80211_flush_queues(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata, bool drop)
{
__ieee80211_flush_queues(local, sdata, 0, drop);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Liad Kaufman | 24 | 82.76% | 1 | 50.00% |
Emmanuel Grumbach | 5 | 17.24% | 1 | 50.00% |
Total | 29 | 100.00% | 2 | 100.00% |
void ieee80211_stop_vif_queues(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
enum queue_stop_reason reason)
{
ieee80211_stop_queues_by_reason(&local->hw,
ieee80211_get_vif_queues(local, sdata),
reason, true);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Luciano Coelho | 38 | 100.00% | 1 | 100.00% |
Total | 38 | 100.00% | 1 | 100.00% |
void ieee80211_wake_vif_queues(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
enum queue_stop_reason reason)
{
ieee80211_wake_queues_by_reason(&local->hw,
ieee80211_get_vif_queues(local, sdata),
reason, true);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Luciano Coelho | 38 | 100.00% | 1 | 100.00% |
Total | 38 | 100.00% | 1 | 100.00% |
static void __iterate_interfaces(struct ieee80211_local *local,
u32 iter_flags,
void (*iterator)(void *data, u8 *mac,
struct ieee80211_vif *vif),
void *data)
{
struct ieee80211_sub_if_data *sdata;
bool active_only = iter_flags & IEEE80211_IFACE_ITER_ACTIVE;
list_for_each_entry_rcu(sdata, &local->interfaces, list) {
switch (sdata->vif.type) {
case NL80211_IFTYPE_MONITOR:
if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE))
continue;
break;
case NL80211_IFTYPE_AP_VLAN:
continue;
default:
break;
}
if (!(iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL) &&
active_only && !(sdata->flags & IEEE80211_SDATA_IN_DRIVER))
continue;
if (ieee80211_sdata_running(sdata) || !active_only)
iterator(data, sdata->vif.addr,
&sdata->vif);
}
sdata = rcu_dereference_check(local->monitor_sdata,
lockdep_is_held(&local->iflist_mtx) ||
lockdep_rtnl_is_held());
if (sdata &&
(iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL || !active_only ||
sdata->flags & IEEE80211_SDATA_IN_DRIVER))
iterator(data, sdata->vif.addr, &sdata->vif);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Berg | 123 | 62.12% | 9 | 69.23% |
Ivo van Doorn | 42 | 21.21% | 1 | 7.69% |
Arik Nemtsov | 16 | 8.08% | 1 | 7.69% |
Felix Fietkau | 14 | 7.07% | 1 | 7.69% |
Aviya Erenfeld | 3 | 1.52% | 1 | 7.69% |
Total | 198 | 100.00% | 13 | 100.00% |
void ieee80211_iterate_interfaces(
struct ieee80211_hw *hw, u32 iter_flags,
void (*iterator)(void *data, u8 *mac,
struct ieee80211_vif *vif),
void *data)
{
struct ieee80211_local *local = hw_to_local(hw);
mutex_lock(&local->iflist_mtx);
__iterate_interfaces(local, iter_flags, iterator, data);
mutex_unlock(&local->iflist_mtx);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Berg | 70 | 94.59% | 2 | 50.00% |
Ivo van Doorn | 2 | 2.70% | 1 | 25.00% |
Arik Nemtsov | 2 | 2.70% | 1 | 25.00% |
Total | 74 | 100.00% | 4 | 100.00% |
EXPORT_SYMBOL_GPL(ieee80211_iterate_interfaces);
void ieee80211_iterate_active_interfaces_atomic(
struct ieee80211_hw *hw, u32 iter_flags,
void (*iterator)(void *data, u8 *mac,
struct ieee80211_vif *vif),
void *data)
{
struct ieee80211_local *local = hw_to_local(hw);
rcu_read_lock();
__iterate_interfaces(local, iter_flags | IEEE80211_IFACE_ITER_ACTIVE,
iterator, data);
rcu_read_unlock();
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Ivo van Doorn | 43 | 65.15% | 1 | 16.67% |
Johannes Berg | 20 | 30.30% | 4 | 66.67% |
Arik Nemtsov | 3 | 4.55% | 1 | 16.67% |
Total | 66 | 100.00% | 6 | 100.00% |
EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic);
void ieee80211_iterate_active_interfaces_rtnl(
struct ieee80211_hw *hw, u32 iter_flags,
void (*iterator)(void *data, u8 *mac,
struct ieee80211_vif *vif),
void *data)
{
struct ieee80211_local *local = hw_to_local(hw);
ASSERT_RTNL();
__iterate_interfaces(local, iter_flags | IEEE80211_IFACE_ITER_ACTIVE,
iterator, data);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Berg | 60 | 95.24% | 5 | 83.33% |
Arik Nemtsov | 3 | 4.76% | 1 | 16.67% |
Total | 63 | 100.00% | 6 | 100.00% |
EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_rtnl);
static void __iterate_stations(struct ieee80211_local *local,
void (*iterator)(void *data,
struct ieee80211_sta *sta),
void *data)
{
struct sta_info *sta;
list_for_each_entry_rcu(sta, &local->sta_list