mirror of https://gitee.com/openkylin/linux.git
Only a few changes at this point:
* new channels in 60 GHz * clarify (average) ACK signal reporting API * expose ieee80211_send_layer2_update() for all drivers * start/stop mac80211's TXQs properly when required * avoid regulatory restore with IE ignoring * spelling: contidion -> condition * fully implement WFA Multi-AP backhaul -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEH1e1rEeCd0AIMq6MB8qZga/fl8QFAluGiMwACgkQB8qZga/f l8SHMRAAhlYZNjZIHMqbyqRMFeGkgyfgQRYKb4xhrYr7v0542g5U99MWMNBtUJmq 8aP4dzUFuPkR0qOi220PCs8PBBjuVcdTK1vq7AYiwiK4Um10/MtAlay6BUJFKVqU sJMaMbPy4mB3ocWl/q2K4nKaCZARsr854xwiIJZVwbc8n8t60Mr5ELbzELb5prGS jPpeRzYd7m4y4xnSYaiXWchdNOplFRN04NcuKJx10Pr3oWilGlj/ujGvwp78U6Uy v1H3T9S4XWMFkvl3deeOS6SVkejx76cvH8Ryoq+/qqQsAgs3c9tPQX+mwj6mNicq KsQcMIX6WmHNG5IcyaWat4LzdPgb5Xv31brA5tciZ3jebmIbc0P4dSYDLs7Jq1fg gkYuyNV3Jlwzv93RzqcrxfAIquZAvI7fy4CGiiRwtMk3wuHJlGy21PjGqZtWwqbn v0MbQf9riv1e653ygKSUpm1UoT5HMFbs6ZzbqpSy7Vr0e9+6B78Xkcp5u1DAvIan 09YSqzKlypoGC+/802BL34HTpoUnf/hiBzVjYFmqvL/X2qv7oEUMOIv2x9Lg7NHh NZOPWcwjtPN57UP97Y6gCRAI2kJTigNdVnKISbIzZgNJ/HhB0M7ZmJ2UpB7EuJ1M q5aTIolqdoruwdGJ8d3gRr9xjDcuhhjr+FS8h6KfByJ0Qixroqk= =BW1J -----END PGP SIGNATURE----- Merge tag 'mac80211-next-for-davem-2018-08-29' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next Johannes Berg says: ==================== Only a few changes at this point: * new channels in 60 GHz * clarify (average) ACK signal reporting API * expose ieee80211_send_layer2_update() for all drivers * start/stop mac80211's TXQs properly when required * avoid regulatory restore with IE ignoring * spelling: contidion -> condition * fully implement WFA Multi-AP backhaul ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
f0259b6ac4
|
@ -1436,7 +1436,7 @@ static int wil_freq_debugfs_show(struct seq_file *s, void *data)
|
|||
{
|
||||
struct wil6210_priv *wil = s->private;
|
||||
struct wireless_dev *wdev = wil->main_ndev->ieee80211_ptr;
|
||||
u16 freq = wdev->chandef.chan ? wdev->chandef.chan->center_freq : 0;
|
||||
u32 freq = wdev->chandef.chan ? wdev->chandef.chan->center_freq : 0;
|
||||
|
||||
seq_printf(s, "Freq = %d\n", freq);
|
||||
|
||||
|
|
|
@ -149,7 +149,7 @@ enum ieee80211_channel_flags {
|
|||
*/
|
||||
struct ieee80211_channel {
|
||||
enum nl80211_band band;
|
||||
u16 center_freq;
|
||||
u32 center_freq;
|
||||
u16 hw_value;
|
||||
u32 flags;
|
||||
int max_antenna_gain;
|
||||
|
@ -4732,6 +4732,17 @@ static inline const u8 *cfg80211_find_ext_ie(u8 ext_eid, const u8 *ies, int len)
|
|||
const u8 *cfg80211_find_vendor_ie(unsigned int oui, int oui_type,
|
||||
const u8 *ies, int len);
|
||||
|
||||
/**
|
||||
* cfg80211_send_layer2_update - send layer 2 update frame
|
||||
*
|
||||
* @dev: network device
|
||||
* @addr: STA MAC address
|
||||
*
|
||||
* Wireless drivers can use this function to update forwarding tables in bridge
|
||||
* devices upon STA association.
|
||||
*/
|
||||
void cfg80211_send_layer2_update(struct net_device *dev, const u8 *addr);
|
||||
|
||||
/**
|
||||
* DOC: Regulatory enforcement infrastructure
|
||||
*
|
||||
|
|
|
@ -1504,6 +1504,8 @@ enum ieee80211_vif_flags {
|
|||
* @drv_priv: data area for driver use, will always be aligned to
|
||||
* sizeof(void \*).
|
||||
* @txq: the multicast data TX queue (if driver uses the TXQ abstraction)
|
||||
* @txqs_stopped: per AC flag to indicate that intermediate TXQs are stopped,
|
||||
* protected by fq->lock.
|
||||
*/
|
||||
struct ieee80211_vif {
|
||||
enum nl80211_iftype type;
|
||||
|
@ -1528,6 +1530,8 @@ struct ieee80211_vif {
|
|||
|
||||
unsigned int probe_req_reg;
|
||||
|
||||
bool txqs_stopped[IEEE80211_NUM_ACS];
|
||||
|
||||
/* must be last */
|
||||
u8 drv_priv[0] __aligned(sizeof(void *));
|
||||
};
|
||||
|
|
|
@ -3050,8 +3050,7 @@ enum nl80211_sta_bss_param {
|
|||
* received from the station (u64, usec)
|
||||
* @NL80211_STA_INFO_PAD: attribute used for padding for 64-bit alignment
|
||||
* @NL80211_STA_INFO_ACK_SIGNAL: signal strength of the last ACK frame(u8, dBm)
|
||||
* @NL80211_STA_INFO_DATA_ACK_SIGNAL_AVG: avg signal strength of (data)
|
||||
* ACK frame (s8, dBm)
|
||||
* @NL80211_STA_INFO_ACK_SIGNAL_AVG: avg signal strength of ACK frames (s8, dBm)
|
||||
* @__NL80211_STA_INFO_AFTER_LAST: internal
|
||||
* @NL80211_STA_INFO_MAX: highest possible station info attribute
|
||||
*/
|
||||
|
@ -3091,13 +3090,17 @@ enum nl80211_sta_info {
|
|||
NL80211_STA_INFO_RX_DURATION,
|
||||
NL80211_STA_INFO_PAD,
|
||||
NL80211_STA_INFO_ACK_SIGNAL,
|
||||
NL80211_STA_INFO_DATA_ACK_SIGNAL_AVG,
|
||||
NL80211_STA_INFO_ACK_SIGNAL_AVG,
|
||||
|
||||
/* keep last */
|
||||
__NL80211_STA_INFO_AFTER_LAST,
|
||||
NL80211_STA_INFO_MAX = __NL80211_STA_INFO_AFTER_LAST - 1
|
||||
};
|
||||
|
||||
/* we renamed this - stay compatible */
|
||||
#define NL80211_STA_INFO_DATA_ACK_SIGNAL_AVG NL80211_STA_INFO_ACK_SIGNAL_AVG
|
||||
|
||||
|
||||
/**
|
||||
* enum nl80211_tid_stats - per TID statistics attributes
|
||||
* @__NL80211_TID_STATS_INVALID: attribute number 0 is reserved
|
||||
|
@ -4338,7 +4341,7 @@ enum nl80211_txrate_gi {
|
|||
* enum nl80211_band - Frequency band
|
||||
* @NL80211_BAND_2GHZ: 2.4 GHz ISM band
|
||||
* @NL80211_BAND_5GHZ: around 5 GHz band (4.9 - 5.7 GHz)
|
||||
* @NL80211_BAND_60GHZ: around 60 GHz band (58.32 - 64.80 GHz)
|
||||
* @NL80211_BAND_60GHZ: around 60 GHz band (58.32 - 69.12 GHz)
|
||||
* @NUM_NL80211_BANDS: number of bands, avoid using this in userspace
|
||||
* since newer kernel versions may support more bands
|
||||
*/
|
||||
|
@ -5213,9 +5216,8 @@ enum nl80211_feature_flags {
|
|||
* "radar detected" event.
|
||||
* @NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211: Driver supports sending and
|
||||
* receiving control port frames over nl80211 instead of the netdevice.
|
||||
* @NL80211_EXT_FEATURE_DATA_ACK_SIGNAL_SUPPORT: This Driver support data ack
|
||||
* rssi if firmware support, this flag is to intimate about ack rssi
|
||||
* support to nl80211.
|
||||
* @NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT: This driver/device supports
|
||||
* (average) ACK signal strength reporting.
|
||||
* @NL80211_EXT_FEATURE_TXQS: Driver supports FQ-CoDel-enabled intermediate
|
||||
* TXQs.
|
||||
* @NL80211_EXT_FEATURE_SCAN_RANDOM_SN: Driver/device supports randomizing the
|
||||
|
@ -5255,7 +5257,9 @@ enum nl80211_ext_feature_index {
|
|||
NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN,
|
||||
NL80211_EXT_FEATURE_DFS_OFFLOAD,
|
||||
NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211,
|
||||
NL80211_EXT_FEATURE_DATA_ACK_SIGNAL_SUPPORT,
|
||||
NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT,
|
||||
/* we renamed this - stay compatible */
|
||||
NL80211_EXT_FEATURE_DATA_ACK_SIGNAL_SUPPORT = NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT,
|
||||
NL80211_EXT_FEATURE_TXQS,
|
||||
NL80211_EXT_FEATURE_SCAN_RANDOM_SN,
|
||||
NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT,
|
||||
|
|
|
@ -1092,50 +1092,6 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
|
||||
struct iapp_layer2_update {
|
||||
u8 da[ETH_ALEN]; /* broadcast */
|
||||
u8 sa[ETH_ALEN]; /* STA addr */
|
||||
__be16 len; /* 6 */
|
||||
u8 dsap; /* 0 */
|
||||
u8 ssap; /* 0 */
|
||||
u8 control;
|
||||
u8 xid_info[3];
|
||||
} __packed;
|
||||
|
||||
static void ieee80211_send_layer2_update(struct sta_info *sta)
|
||||
{
|
||||
struct iapp_layer2_update *msg;
|
||||
struct sk_buff *skb;
|
||||
|
||||
/* Send Level 2 Update Frame to update forwarding tables in layer 2
|
||||
* bridge devices */
|
||||
|
||||
skb = dev_alloc_skb(sizeof(*msg));
|
||||
if (!skb)
|
||||
return;
|
||||
msg = skb_put(skb, sizeof(*msg));
|
||||
|
||||
/* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID)
|
||||
* Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */
|
||||
|
||||
eth_broadcast_addr(msg->da);
|
||||
memcpy(msg->sa, sta->sta.addr, ETH_ALEN);
|
||||
msg->len = htons(6);
|
||||
msg->dsap = 0;
|
||||
msg->ssap = 0x01; /* NULL LSAP, CR Bit: Response */
|
||||
msg->control = 0xaf; /* XID response lsb.1111F101.
|
||||
* F=0 (no poll command; unsolicited frame) */
|
||||
msg->xid_info[0] = 0x81; /* XID format identifier */
|
||||
msg->xid_info[1] = 1; /* LLC types/classes: Type 1 LLC */
|
||||
msg->xid_info[2] = 0; /* XID sender's receive window size (RW) */
|
||||
|
||||
skb->dev = sta->sdata->dev;
|
||||
skb->protocol = eth_type_trans(skb, sta->sdata->dev);
|
||||
memset(skb->cb, 0, sizeof(skb->cb));
|
||||
netif_rx_ni(skb);
|
||||
}
|
||||
|
||||
static int sta_apply_auth_flags(struct ieee80211_local *local,
|
||||
struct sta_info *sta,
|
||||
u32 mask, u32 set)
|
||||
|
@ -1499,7 +1455,7 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
|
|||
}
|
||||
|
||||
if (layer2_update)
|
||||
ieee80211_send_layer2_update(sta);
|
||||
cfg80211_send_layer2_update(sta->sdata->dev, sta->sta.addr);
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
|
@ -1601,7 +1557,7 @@ static int ieee80211_change_station(struct wiphy *wiphy,
|
|||
if (test_sta_flag(sta, WLAN_STA_AUTHORIZED))
|
||||
ieee80211_vif_inc_num_mcast(sta->sdata);
|
||||
|
||||
ieee80211_send_layer2_update(sta);
|
||||
cfg80211_send_layer2_update(sta->sdata->dev, sta->sta.addr);
|
||||
}
|
||||
|
||||
err = sta_apply_parameters(local, sta, params);
|
||||
|
|
|
@ -818,6 +818,7 @@ enum txq_info_flags {
|
|||
IEEE80211_TXQ_STOP,
|
||||
IEEE80211_TXQ_AMPDU,
|
||||
IEEE80211_TXQ_NO_AMSDU,
|
||||
IEEE80211_TXQ_STOP_NETIF_TX,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1226,6 +1227,7 @@ struct ieee80211_local {
|
|||
|
||||
struct sk_buff_head pending[IEEE80211_MAX_QUEUES];
|
||||
struct tasklet_struct tx_pending_tasklet;
|
||||
struct tasklet_struct wake_txqs_tasklet;
|
||||
|
||||
atomic_t agg_queue_stop[IEEE80211_MAX_QUEUES];
|
||||
|
||||
|
@ -2038,6 +2040,7 @@ void ieee80211_txq_remove_vlan(struct ieee80211_local *local,
|
|||
struct ieee80211_sub_if_data *sdata);
|
||||
void ieee80211_fill_txq_stats(struct cfg80211_txq_stats *txqstats,
|
||||
struct txq_info *txqi);
|
||||
void ieee80211_wake_txqs(unsigned long data);
|
||||
void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
|
||||
u16 transaction, u16 auth_alg, u16 status,
|
||||
const u8 *extra, size_t extra_len, const u8 *bssid,
|
||||
|
|
|
@ -668,6 +668,10 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
|
|||
tasklet_init(&local->tx_pending_tasklet, ieee80211_tx_pending,
|
||||
(unsigned long)local);
|
||||
|
||||
if (ops->wake_tx_queue)
|
||||
tasklet_init(&local->wake_txqs_tasklet, ieee80211_wake_txqs,
|
||||
(unsigned long)local);
|
||||
|
||||
tasklet_init(&local->tasklet,
|
||||
ieee80211_tasklet_handler,
|
||||
(unsigned long) local);
|
||||
|
|
|
@ -2313,7 +2313,7 @@ __ieee80211_data_to_8023(struct ieee80211_rx_data *rx, bool *port_control)
|
|||
|
||||
if (!sdata->u.mgd.use_4addr)
|
||||
return -1;
|
||||
else
|
||||
else if (!ether_addr_equal(hdr->addr1, sdata->vif.addr))
|
||||
check_port_control = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -2323,13 +2323,13 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo,
|
|||
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL);
|
||||
}
|
||||
|
||||
if (ieee80211_hw_check(&sta->local->hw, REPORTS_TX_ACK_STATUS) &&
|
||||
!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_DATA_ACK_SIGNAL_AVG))) {
|
||||
if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL_AVG)) &&
|
||||
sta->status_stats.ack_signal_filled) {
|
||||
sinfo->avg_ack_signal =
|
||||
-(s8)ewma_avg_signal_read(
|
||||
&sta->status_stats.avg_ack_signal);
|
||||
sinfo->filled |=
|
||||
BIT_ULL(NL80211_STA_INFO_DATA_ACK_SIGNAL_AVG);
|
||||
BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL_AVG);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3466,13 +3466,19 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
|
|||
struct ieee80211_tx_info *info;
|
||||
struct ieee80211_tx_data tx;
|
||||
ieee80211_tx_result r;
|
||||
struct ieee80211_vif *vif;
|
||||
struct ieee80211_vif *vif = txq->vif;
|
||||
|
||||
spin_lock_bh(&fq->lock);
|
||||
|
||||
if (test_bit(IEEE80211_TXQ_STOP, &txqi->flags))
|
||||
if (test_bit(IEEE80211_TXQ_STOP, &txqi->flags) ||
|
||||
test_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txqi->flags))
|
||||
goto out;
|
||||
|
||||
if (vif->txqs_stopped[ieee80211_ac_from_tid(txq->tid)]) {
|
||||
set_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txqi->flags);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Make sure fragments stay together. */
|
||||
skb = __skb_dequeue(&txqi->frags);
|
||||
if (skb)
|
||||
|
@ -3567,6 +3573,7 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
|
|||
}
|
||||
|
||||
IEEE80211_SKB_CB(skb)->control.vif = vif;
|
||||
|
||||
out:
|
||||
spin_unlock_bh(&fq->lock);
|
||||
|
||||
|
|
|
@ -240,6 +240,99 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
|
|||
}
|
||||
EXPORT_SYMBOL(ieee80211_ctstoself_duration);
|
||||
|
||||
static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_vif *vif = &sdata->vif;
|
||||
struct fq *fq = &local->fq;
|
||||
struct ps_data *ps = NULL;
|
||||
struct txq_info *txqi;
|
||||
struct sta_info *sta;
|
||||
int i;
|
||||
|
||||
spin_lock_bh(&fq->lock);
|
||||
|
||||
if (sdata->vif.type == NL80211_IFTYPE_AP)
|
||||
ps = &sdata->bss->ps;
|
||||
|
||||
sdata->vif.txqs_stopped[ac] = false;
|
||||
|
||||
list_for_each_entry_rcu(sta, &local->sta_list, list) {
|
||||
if (sdata != sta->sdata)
|
||||
continue;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
|
||||
struct ieee80211_txq *txq = sta->sta.txq[i];
|
||||
|
||||
txqi = to_txq_info(txq);
|
||||
|
||||
if (ac != txq->ac)
|
||||
continue;
|
||||
|
||||
if (!test_and_clear_bit(IEEE80211_TXQ_STOP_NETIF_TX,
|
||||
&txqi->flags))
|
||||
continue;
|
||||
|
||||
spin_unlock_bh(&fq->lock);
|
||||
drv_wake_tx_queue(local, txqi);
|
||||
spin_lock_bh(&fq->lock);
|
||||
}
|
||||
}
|
||||
|
||||
if (!vif->txq)
|
||||
goto out;
|
||||
|
||||
txqi = to_txq_info(vif->txq);
|
||||
|
||||
if (!test_and_clear_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txqi->flags) ||
|
||||
(ps && atomic_read(&ps->num_sta_ps)) || ac != vif->txq->ac)
|
||||
goto out;
|
||||
|
||||
spin_unlock_bh(&fq->lock);
|
||||
|
||||
drv_wake_tx_queue(local, txqi);
|
||||
return;
|
||||
out:
|
||||
spin_unlock_bh(&fq->lock);
|
||||
}
|
||||
|
||||
void ieee80211_wake_txqs(unsigned long data)
|
||||
{
|
||||
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;
|
||||
|
||||
for (i = 0; i < local->hw.queues; i++) {
|
||||
if (local->queue_stop_reasons[i])
|
||||
continue;
|
||||
|
||||
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
|
||||
list_for_each_entry_rcu(sdata, &local->interfaces, list) {
|
||||
int ac;
|
||||
|
||||
for (ac = 0; ac < n_acs; ac++) {
|
||||
int ac_queue = sdata->vif.hw_queue[ac];
|
||||
|
||||
if (ac_queue == i ||
|
||||
sdata->vif.cab_queue == i)
|
||||
__ieee80211_wake_txqs(sdata, ac);
|
||||
}
|
||||
}
|
||||
spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
|
@ -308,6 +401,9 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
|
|||
rcu_read_unlock();
|
||||
} else
|
||||
tasklet_schedule(&local->tx_pending_tasklet);
|
||||
|
||||
if (local->ops->wake_tx_queue)
|
||||
tasklet_schedule(&local->wake_txqs_tasklet);
|
||||
}
|
||||
|
||||
void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
|
||||
|
@ -351,9 +447,6 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
|
|||
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;
|
||||
|
||||
|
@ -366,8 +459,15 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
|
|||
|
||||
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);
|
||||
sdata->vif.cab_queue == queue) {
|
||||
if (!local->ops->wake_tx_queue) {
|
||||
netif_stop_subqueue(sdata->dev, ac);
|
||||
continue;
|
||||
}
|
||||
spin_lock(&local->fq.lock);
|
||||
sdata->vif.txqs_stopped[ac] = true;
|
||||
spin_unlock(&local->fq.lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
|
|
@ -510,8 +510,8 @@ void rfkill_remove_epo_lock(void)
|
|||
/**
|
||||
* rfkill_is_epo_lock_active - returns true EPO is active
|
||||
*
|
||||
* Returns 0 (false) if there is NOT an active EPO contidion,
|
||||
* and 1 (true) if there is an active EPO contition, which
|
||||
* Returns 0 (false) if there is NOT an active EPO condition,
|
||||
* and 1 (true) if there is an active EPO condition, which
|
||||
* locks all radios in one of the BLOCKED states.
|
||||
*
|
||||
* Can be called in atomic context.
|
||||
|
|
|
@ -4724,10 +4724,11 @@ static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
|
|||
PUT_SINFO_U64(RX_DROP_MISC, rx_dropped_misc);
|
||||
PUT_SINFO_U64(BEACON_RX, rx_beacon);
|
||||
PUT_SINFO(BEACON_SIGNAL_AVG, rx_beacon_signal_avg, u8);
|
||||
PUT_SINFO(ACK_SIGNAL, ack_signal, u8);
|
||||
if (wiphy_ext_feature_isset(&rdev->wiphy,
|
||||
NL80211_EXT_FEATURE_DATA_ACK_SIGNAL_SUPPORT))
|
||||
PUT_SINFO(DATA_ACK_SIGNAL_AVG, avg_ack_signal, s8);
|
||||
NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT)) {
|
||||
PUT_SINFO(ACK_SIGNAL, ack_signal, u8);
|
||||
PUT_SINFO(ACK_SIGNAL_AVG, avg_ack_signal, s8);
|
||||
}
|
||||
|
||||
#undef PUT_SINFO
|
||||
#undef PUT_SINFO_U64
|
||||
|
|
|
@ -3249,13 +3249,59 @@ static void restore_regulatory_settings(bool reset_user)
|
|||
schedule_work(®_work);
|
||||
}
|
||||
|
||||
static bool is_wiphy_all_set_reg_flag(enum ieee80211_regulatory_flags flag)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev;
|
||||
struct wireless_dev *wdev;
|
||||
|
||||
list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
|
||||
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
|
||||
wdev_lock(wdev);
|
||||
if (!(wdev->wiphy->regulatory_flags & flag)) {
|
||||
wdev_unlock(wdev);
|
||||
return false;
|
||||
}
|
||||
wdev_unlock(wdev);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void regulatory_hint_disconnect(void)
|
||||
{
|
||||
/* Restore of regulatory settings is not required when wiphy(s)
|
||||
* ignore IE from connected access point but clearance of beacon hints
|
||||
* is required when wiphy(s) supports beacon hints.
|
||||
*/
|
||||
if (is_wiphy_all_set_reg_flag(REGULATORY_COUNTRY_IE_IGNORE)) {
|
||||
struct reg_beacon *reg_beacon, *btmp;
|
||||
|
||||
if (is_wiphy_all_set_reg_flag(REGULATORY_DISABLE_BEACON_HINTS))
|
||||
return;
|
||||
|
||||
spin_lock_bh(®_pending_beacons_lock);
|
||||
list_for_each_entry_safe(reg_beacon, btmp,
|
||||
®_pending_beacons, list) {
|
||||
list_del(®_beacon->list);
|
||||
kfree(reg_beacon);
|
||||
}
|
||||
spin_unlock_bh(®_pending_beacons_lock);
|
||||
|
||||
list_for_each_entry_safe(reg_beacon, btmp,
|
||||
®_beacon_list, list) {
|
||||
list_del(®_beacon->list);
|
||||
kfree(reg_beacon);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
pr_debug("All devices are disconnected, going to restore regulatory settings\n");
|
||||
restore_regulatory_settings(false);
|
||||
}
|
||||
|
||||
static bool freq_is_chan_12_13_14(u16 freq)
|
||||
static bool freq_is_chan_12_13_14(u32 freq)
|
||||
{
|
||||
if (freq == ieee80211_channel_to_frequency(12, NL80211_BAND_2GHZ) ||
|
||||
freq == ieee80211_channel_to_frequency(13, NL80211_BAND_2GHZ) ||
|
||||
|
|
|
@ -112,7 +112,7 @@
|
|||
} while (0)
|
||||
|
||||
#define CHAN_ENTRY __field(enum nl80211_band, band) \
|
||||
__field(u16, center_freq)
|
||||
__field(u32, center_freq)
|
||||
#define CHAN_ASSIGN(chan) \
|
||||
do { \
|
||||
if (chan) { \
|
||||
|
|
|
@ -88,7 +88,7 @@ int ieee80211_channel_to_frequency(int chan, enum nl80211_band band)
|
|||
return 5000 + chan * 5;
|
||||
break;
|
||||
case NL80211_BAND_60GHZ:
|
||||
if (chan < 5)
|
||||
if (chan < 7)
|
||||
return 56160 + chan * 2160;
|
||||
break;
|
||||
default:
|
||||
|
@ -109,7 +109,7 @@ int ieee80211_frequency_to_channel(int freq)
|
|||
return (freq - 4000) / 5;
|
||||
else if (freq <= 45000) /* DMG band lower limit */
|
||||
return (freq - 5000) / 5;
|
||||
else if (freq >= 58320 && freq <= 64800)
|
||||
else if (freq >= 58320 && freq <= 70200)
|
||||
return (freq - 56160) / 2160;
|
||||
else
|
||||
return 0;
|
||||
|
@ -1568,7 +1568,7 @@ bool ieee80211_chandef_to_operating_class(struct cfg80211_chan_def *chandef,
|
|||
}
|
||||
|
||||
/* 56.16 GHz, channel 1..4 */
|
||||
if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 4) {
|
||||
if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 6) {
|
||||
if (chandef->width >= NL80211_CHAN_WIDTH_40)
|
||||
return false;
|
||||
|
||||
|
@ -1893,3 +1893,48 @@ EXPORT_SYMBOL(rfc1042_header);
|
|||
const unsigned char bridge_tunnel_header[] __aligned(2) =
|
||||
{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
|
||||
EXPORT_SYMBOL(bridge_tunnel_header);
|
||||
|
||||
/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
|
||||
struct iapp_layer2_update {
|
||||
u8 da[ETH_ALEN]; /* broadcast */
|
||||
u8 sa[ETH_ALEN]; /* STA addr */
|
||||
__be16 len; /* 6 */
|
||||
u8 dsap; /* 0 */
|
||||
u8 ssap; /* 0 */
|
||||
u8 control;
|
||||
u8 xid_info[3];
|
||||
} __packed;
|
||||
|
||||
void cfg80211_send_layer2_update(struct net_device *dev, const u8 *addr)
|
||||
{
|
||||
struct iapp_layer2_update *msg;
|
||||
struct sk_buff *skb;
|
||||
|
||||
/* Send Level 2 Update Frame to update forwarding tables in layer 2
|
||||
* bridge devices */
|
||||
|
||||
skb = dev_alloc_skb(sizeof(*msg));
|
||||
if (!skb)
|
||||
return;
|
||||
msg = skb_put(skb, sizeof(*msg));
|
||||
|
||||
/* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID)
|
||||
* Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */
|
||||
|
||||
eth_broadcast_addr(msg->da);
|
||||
ether_addr_copy(msg->sa, addr);
|
||||
msg->len = htons(6);
|
||||
msg->dsap = 0;
|
||||
msg->ssap = 0x01; /* NULL LSAP, CR Bit: Response */
|
||||
msg->control = 0xaf; /* XID response lsb.1111F101.
|
||||
* F=0 (no poll command; unsolicited frame) */
|
||||
msg->xid_info[0] = 0x81; /* XID format identifier */
|
||||
msg->xid_info[1] = 1; /* LLC types/classes: Type 1 LLC */
|
||||
msg->xid_info[2] = 0; /* XID sender's receive window size (RW) */
|
||||
|
||||
skb->dev = dev;
|
||||
skb->protocol = eth_type_trans(skb, dev);
|
||||
memset(skb->cb, 0, sizeof(skb->cb));
|
||||
netif_rx_ni(skb);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_send_layer2_update);
|
||||
|
|
Loading…
Reference in New Issue