summaryrefslogtreecommitdiff
path: root/net/mac80211/tx.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r--net/mac80211/tx.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index d626e6808bef..6ec415f043e1 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1182,9 +1182,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
tx->sta = rcu_dereference(sdata->u.vlan.sta);
if (!tx->sta && sdata->wdev.use_4addr)
return TX_DROP;
- } else if (info->flags & (IEEE80211_TX_INTFL_NL80211_FRAME_TX |
- IEEE80211_TX_CTL_INJECTED) ||
- tx->sdata->control_port_protocol == tx->skb->protocol) {
+ } else if (tx->sdata->control_port_protocol == tx->skb->protocol) {
tx->sta = sta_info_get_bss(sdata, hdr->addr1);
}
if (!tx->sta && !is_multicast_ether_addr(hdr->addr1))
@@ -5404,6 +5402,7 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_local *local = sdata->local;
+ struct sta_info *sta;
struct sk_buff *skb;
struct ethhdr *ehdr;
u32 ctrl_flags = 0;
@@ -5426,8 +5425,7 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
if (cookie)
ctrl_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
- flags |= IEEE80211_TX_INTFL_NL80211_FRAME_TX |
- IEEE80211_TX_CTL_INJECTED;
+ flags |= IEEE80211_TX_INTFL_NL80211_FRAME_TX;
skb = dev_alloc_skb(local->hw.extra_tx_headroom +
sizeof(struct ethhdr) + len);
@@ -5444,10 +5442,25 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
ehdr->h_proto = proto;
skb->dev = dev;
- skb->protocol = htons(ETH_P_802_3);
+ skb->protocol = proto;
skb_reset_network_header(skb);
skb_reset_mac_header(skb);
+ /* update QoS header to prioritize control port frames if possible,
+ * priorization also happens for control port frames send over
+ * AF_PACKET
+ */
+ rcu_read_lock();
+
+ if (ieee80211_lookup_ra_sta(sdata, skb, &sta) == 0 && !IS_ERR(sta)) {
+ u16 queue = __ieee80211_select_queue(sdata, sta, skb);
+
+ skb_set_queue_mapping(skb, queue);
+ skb_get_hash(skb);
+ }
+
+ rcu_read_unlock();
+
/* mutex lock is only needed for incrementing the cookie counter */
mutex_lock(&local->mtx);