xref: /openbmc/linux/net/mac80211/tx.c (revision d2912cb15bdda8ba4a5dd73396ad62641af2f520)
1*d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2e2ebc74dSJohannes Berg /*
3e2ebc74dSJohannes Berg  * Copyright 2002-2005, Instant802 Networks, Inc.
4e2ebc74dSJohannes Berg  * Copyright 2005-2006, Devicescape Software, Inc.
5e2ebc74dSJohannes Berg  * Copyright 2006-2007	Jiri Benc <jbenc@suse.cz>
6e2ebc74dSJohannes Berg  * Copyright 2007	Johannes Berg <johannes@sipsolutions.net>
7d98ad83eSJohannes Berg  * Copyright 2013-2014  Intel Mobile Communications GmbH
8914eac24SSara Sharon  * Copyright (C) 2018 Intel Corporation
9e2ebc74dSJohannes Berg  *
10e2ebc74dSJohannes Berg  * Transmit and frame generation functions.
11e2ebc74dSJohannes Berg  */
12e2ebc74dSJohannes Berg 
13e2ebc74dSJohannes Berg #include <linux/kernel.h>
14e2ebc74dSJohannes Berg #include <linux/slab.h>
15e2ebc74dSJohannes Berg #include <linux/skbuff.h>
16ebceec86SMichael Braun #include <linux/if_vlan.h>
17e2ebc74dSJohannes Berg #include <linux/etherdevice.h>
18e2ebc74dSJohannes Berg #include <linux/bitmap.h>
19d4e46a3dSJohannes Berg #include <linux/rcupdate.h>
20bc3b2d7fSPaul Gortmaker #include <linux/export.h>
21881d966bSEric W. Biederman #include <net/net_namespace.h>
22e2ebc74dSJohannes Berg #include <net/ieee80211_radiotap.h>
23e2ebc74dSJohannes Berg #include <net/cfg80211.h>
24e2ebc74dSJohannes Berg #include <net/mac80211.h>
255caa328eSMichal Kazior #include <net/codel.h>
265caa328eSMichal Kazior #include <net/codel_impl.h>
27e2ebc74dSJohannes Berg #include <asm/unaligned.h>
28fa962b92SMichal Kazior #include <net/fq_impl.h>
29e2ebc74dSJohannes Berg 
30e2ebc74dSJohannes Berg #include "ieee80211_i.h"
3124487981SJohannes Berg #include "driver-ops.h"
322c8dccc7SJohannes Berg #include "led.h"
3333b64eb2SLuis Carlos Cobo #include "mesh.h"
34e2ebc74dSJohannes Berg #include "wep.h"
35e2ebc74dSJohannes Berg #include "wpa.h"
36e2ebc74dSJohannes Berg #include "wme.h"
372c8dccc7SJohannes Berg #include "rate.h"
38e2ebc74dSJohannes Berg 
39e2ebc74dSJohannes Berg /* misc utils */
40e2ebc74dSJohannes Berg 
415a490510SJohannes Berg static inline void ieee80211_tx_stats(struct net_device *dev, u32 len)
425a490510SJohannes Berg {
435a490510SJohannes Berg 	struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats);
445a490510SJohannes Berg 
455a490510SJohannes Berg 	u64_stats_update_begin(&tstats->syncp);
465a490510SJohannes Berg 	tstats->tx_packets++;
475a490510SJohannes Berg 	tstats->tx_bytes += len;
485a490510SJohannes Berg 	u64_stats_update_end(&tstats->syncp);
495a490510SJohannes Berg }
505a490510SJohannes Berg 
51252b86c4SJohannes Berg static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
52252b86c4SJohannes Berg 				 struct sk_buff *skb, int group_addr,
53e2ebc74dSJohannes Berg 				 int next_frag_len)
54e2ebc74dSJohannes Berg {
552103dec1SSimon Wunderlich 	int rate, mrate, erp, dur, i, shift = 0;
562e92e6f2SJohannes Berg 	struct ieee80211_rate *txrate;
57e2ebc74dSJohannes Berg 	struct ieee80211_local *local = tx->local;
588318d78aSJohannes Berg 	struct ieee80211_supported_band *sband;
59358c8d9dSHarvey Harrison 	struct ieee80211_hdr *hdr;
60252b86c4SJohannes Berg 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
612103dec1SSimon Wunderlich 	struct ieee80211_chanctx_conf *chanctx_conf;
622103dec1SSimon Wunderlich 	u32 rate_flags = 0;
632103dec1SSimon Wunderlich 
6495cd470cSFelix Fietkau 	/* assume HW handles this */
6595cd470cSFelix Fietkau 	if (tx->rate.flags & (IEEE80211_TX_RC_MCS | IEEE80211_TX_RC_VHT_MCS))
6695cd470cSFelix Fietkau 		return 0;
6795cd470cSFelix Fietkau 
682103dec1SSimon Wunderlich 	rcu_read_lock();
692103dec1SSimon Wunderlich 	chanctx_conf = rcu_dereference(tx->sdata->vif.chanctx_conf);
702103dec1SSimon Wunderlich 	if (chanctx_conf) {
712103dec1SSimon Wunderlich 		shift = ieee80211_chandef_get_shift(&chanctx_conf->def);
722103dec1SSimon Wunderlich 		rate_flags = ieee80211_chandef_rate_flags(&chanctx_conf->def);
732103dec1SSimon Wunderlich 	}
742103dec1SSimon Wunderlich 	rcu_read_unlock();
75e6a9854bSJohannes Berg 
76e6a9854bSJohannes Berg 	/* uh huh? */
770d528d85SFelix Fietkau 	if (WARN_ON_ONCE(tx->rate.idx < 0))
78e6a9854bSJohannes Berg 		return 0;
79e2ebc74dSJohannes Berg 
802d56577bSJohannes Berg 	sband = local->hw.wiphy->bands[info->band];
810d528d85SFelix Fietkau 	txrate = &sband->bitrates[tx->rate.idx];
828318d78aSJohannes Berg 
838318d78aSJohannes Berg 	erp = txrate->flags & IEEE80211_RATE_ERP_G;
84e2ebc74dSJohannes Berg 
85e2ebc74dSJohannes Berg 	/*
86e2ebc74dSJohannes Berg 	 * data and mgmt (except PS Poll):
87e2ebc74dSJohannes Berg 	 * - during CFP: 32768
88e2ebc74dSJohannes Berg 	 * - during contention period:
89e2ebc74dSJohannes Berg 	 *   if addr1 is group address: 0
90e2ebc74dSJohannes Berg 	 *   if more fragments = 0 and addr1 is individual address: time to
91e2ebc74dSJohannes Berg 	 *      transmit one ACK plus SIFS
92e2ebc74dSJohannes Berg 	 *   if more fragments = 1 and addr1 is individual address: time to
93e2ebc74dSJohannes Berg 	 *      transmit next fragment plus 2 x ACK plus 3 x SIFS
94e2ebc74dSJohannes Berg 	 *
95e2ebc74dSJohannes Berg 	 * IEEE 802.11, 9.6:
96e2ebc74dSJohannes Berg 	 * - control response frame (CTS or ACK) shall be transmitted using the
97e2ebc74dSJohannes Berg 	 *   same rate as the immediately previous frame in the frame exchange
98e2ebc74dSJohannes Berg 	 *   sequence, if this rate belongs to the PHY mandatory rates, or else
99e2ebc74dSJohannes Berg 	 *   at the highest possible rate belonging to the PHY rates in the
100e2ebc74dSJohannes Berg 	 *   BSSBasicRateSet
101e2ebc74dSJohannes Berg 	 */
102252b86c4SJohannes Berg 	hdr = (struct ieee80211_hdr *)skb->data;
103358c8d9dSHarvey Harrison 	if (ieee80211_is_ctl(hdr->frame_control)) {
104e2ebc74dSJohannes Berg 		/* TODO: These control frames are not currently sent by
105ccd7b362SJohannes Berg 		 * mac80211, but should they be implemented, this function
106e2ebc74dSJohannes Berg 		 * needs to be updated to support duration field calculation.
107e2ebc74dSJohannes Berg 		 *
108e2ebc74dSJohannes Berg 		 * RTS: time needed to transmit pending data/mgmt frame plus
109e2ebc74dSJohannes Berg 		 *    one CTS frame plus one ACK frame plus 3 x SIFS
110e2ebc74dSJohannes Berg 		 * CTS: duration of immediately previous RTS minus time
111e2ebc74dSJohannes Berg 		 *    required to transmit CTS and its SIFS
112e2ebc74dSJohannes Berg 		 * ACK: 0 if immediately previous directed data/mgmt had
113e2ebc74dSJohannes Berg 		 *    more=0, with more=1 duration in ACK frame is duration
114e2ebc74dSJohannes Berg 		 *    from previous frame minus time needed to transmit ACK
115e2ebc74dSJohannes Berg 		 *    and its SIFS
116e2ebc74dSJohannes Berg 		 * PS Poll: BIT(15) | BIT(14) | aid
117e2ebc74dSJohannes Berg 		 */
118e2ebc74dSJohannes Berg 		return 0;
119e2ebc74dSJohannes Berg 	}
120e2ebc74dSJohannes Berg 
121e2ebc74dSJohannes Berg 	/* data/mgmt */
122e2ebc74dSJohannes Berg 	if (0 /* FIX: data/mgmt during CFP */)
12303f93c3dSJohannes Berg 		return cpu_to_le16(32768);
124e2ebc74dSJohannes Berg 
125e2ebc74dSJohannes Berg 	if (group_addr) /* Group address as the destination - no ACK */
126e2ebc74dSJohannes Berg 		return 0;
127e2ebc74dSJohannes Berg 
128e2ebc74dSJohannes Berg 	/* Individual destination address:
129e2ebc74dSJohannes Berg 	 * IEEE 802.11, Ch. 9.6 (after IEEE 802.11g changes)
130e2ebc74dSJohannes Berg 	 * CTS and ACK frames shall be transmitted using the highest rate in
131e2ebc74dSJohannes Berg 	 * basic rate set that is less than or equal to the rate of the
132e2ebc74dSJohannes Berg 	 * immediately previous frame and that is using the same modulation
133e2ebc74dSJohannes Berg 	 * (CCK or OFDM). If no basic rate set matches with these requirements,
134e2ebc74dSJohannes Berg 	 * the highest mandatory rate of the PHY that is less than or equal to
135e2ebc74dSJohannes Berg 	 * the rate of the previous frame is used.
136e2ebc74dSJohannes Berg 	 * Mandatory rates for IEEE 802.11g PHY: 1, 2, 5.5, 11, 6, 12, 24 Mbps
137e2ebc74dSJohannes Berg 	 */
138e2ebc74dSJohannes Berg 	rate = -1;
1398318d78aSJohannes Berg 	/* use lowest available if everything fails */
1408318d78aSJohannes Berg 	mrate = sband->bitrates[0].bitrate;
1418318d78aSJohannes Berg 	for (i = 0; i < sband->n_bitrates; i++) {
1428318d78aSJohannes Berg 		struct ieee80211_rate *r = &sband->bitrates[i];
1438318d78aSJohannes Berg 
1448318d78aSJohannes Berg 		if (r->bitrate > txrate->bitrate)
145e2ebc74dSJohannes Berg 			break;
146e2ebc74dSJohannes Berg 
1472103dec1SSimon Wunderlich 		if ((rate_flags & r->flags) != rate_flags)
1482103dec1SSimon Wunderlich 			continue;
1492103dec1SSimon Wunderlich 
150bda3933aSJohannes Berg 		if (tx->sdata->vif.bss_conf.basic_rates & BIT(i))
1512103dec1SSimon Wunderlich 			rate = DIV_ROUND_UP(r->bitrate, 1 << shift);
152e2ebc74dSJohannes Berg 
1538318d78aSJohannes Berg 		switch (sband->band) {
15457fbcce3SJohannes Berg 		case NL80211_BAND_2GHZ: {
1558318d78aSJohannes Berg 			u32 flag;
1568318d78aSJohannes Berg 			if (tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
1578318d78aSJohannes Berg 				flag = IEEE80211_RATE_MANDATORY_G;
1588318d78aSJohannes Berg 			else
1598318d78aSJohannes Berg 				flag = IEEE80211_RATE_MANDATORY_B;
1608318d78aSJohannes Berg 			if (r->flags & flag)
1618318d78aSJohannes Berg 				mrate = r->bitrate;
1628318d78aSJohannes Berg 			break;
1638318d78aSJohannes Berg 		}
16457fbcce3SJohannes Berg 		case NL80211_BAND_5GHZ:
1658318d78aSJohannes Berg 			if (r->flags & IEEE80211_RATE_MANDATORY_A)
1668318d78aSJohannes Berg 				mrate = r->bitrate;
1678318d78aSJohannes Berg 			break;
16857fbcce3SJohannes Berg 		case NL80211_BAND_60GHZ:
1693a0c52a6SVladimir Kondratiev 			/* TODO, for now fall through */
17057fbcce3SJohannes Berg 		case NUM_NL80211_BANDS:
1718318d78aSJohannes Berg 			WARN_ON(1);
1728318d78aSJohannes Berg 			break;
1738318d78aSJohannes Berg 		}
174e2ebc74dSJohannes Berg 	}
175e2ebc74dSJohannes Berg 	if (rate == -1) {
176e2ebc74dSJohannes Berg 		/* No matching basic rate found; use highest suitable mandatory
177e2ebc74dSJohannes Berg 		 * PHY rate */
1782103dec1SSimon Wunderlich 		rate = DIV_ROUND_UP(mrate, 1 << shift);
179e2ebc74dSJohannes Berg 	}
180e2ebc74dSJohannes Berg 
1816674f210SSimon Wunderlich 	/* Don't calculate ACKs for QoS Frames with NoAck Policy set */
1826674f210SSimon Wunderlich 	if (ieee80211_is_data_qos(hdr->frame_control) &&
183c26a0e10SClaudio Pisa 	    *(ieee80211_get_qos_ctl(hdr)) & IEEE80211_QOS_CTL_ACK_POLICY_NOACK)
1846674f210SSimon Wunderlich 		dur = 0;
1856674f210SSimon Wunderlich 	else
186e2ebc74dSJohannes Berg 		/* Time needed to transmit ACK
187e2ebc74dSJohannes Berg 		 * (10 bytes + 4-byte FCS = 112 bits) plus SIFS; rounded up
188e2ebc74dSJohannes Berg 		 * to closest integer */
1894ee73f33SMichal Kazior 		dur = ieee80211_frame_duration(sband->band, 10, rate, erp,
190438b61b7SSimon Wunderlich 				tx->sdata->vif.bss_conf.use_short_preamble,
191438b61b7SSimon Wunderlich 				shift);
192e2ebc74dSJohannes Berg 
193e2ebc74dSJohannes Berg 	if (next_frag_len) {
194e2ebc74dSJohannes Berg 		/* Frame is fragmented: duration increases with time needed to
195e2ebc74dSJohannes Berg 		 * transmit next fragment plus ACK and 2 x SIFS. */
196e2ebc74dSJohannes Berg 		dur *= 2; /* ACK + SIFS */
197e2ebc74dSJohannes Berg 		/* next fragment */
1984ee73f33SMichal Kazior 		dur += ieee80211_frame_duration(sband->band, next_frag_len,
1998318d78aSJohannes Berg 				txrate->bitrate, erp,
200438b61b7SSimon Wunderlich 				tx->sdata->vif.bss_conf.use_short_preamble,
201438b61b7SSimon Wunderlich 				shift);
202e2ebc74dSJohannes Berg 	}
203e2ebc74dSJohannes Berg 
20403f93c3dSJohannes Berg 	return cpu_to_le16(dur);
205e2ebc74dSJohannes Berg }
206e2ebc74dSJohannes Berg 
207e2ebc74dSJohannes Berg /* tx handlers */
2085c1b98a5SKalle Valo static ieee80211_tx_result debug_noinline
2095c1b98a5SKalle Valo ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx)
2105c1b98a5SKalle Valo {
2115c1b98a5SKalle Valo 	struct ieee80211_local *local = tx->local;
2120c74211dSKalle Valo 	struct ieee80211_if_managed *ifmgd;
21394a5b3acSAndrei Otcheretianski 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
2145c1b98a5SKalle Valo 
2155c1b98a5SKalle Valo 	/* driver doesn't support power save */
21630686bf7SJohannes Berg 	if (!ieee80211_hw_check(&local->hw, SUPPORTS_PS))
2175c1b98a5SKalle Valo 		return TX_CONTINUE;
2185c1b98a5SKalle Valo 
2195c1b98a5SKalle Valo 	/* hardware does dynamic power save */
22030686bf7SJohannes Berg 	if (ieee80211_hw_check(&local->hw, SUPPORTS_DYNAMIC_PS))
2215c1b98a5SKalle Valo 		return TX_CONTINUE;
2225c1b98a5SKalle Valo 
2235c1b98a5SKalle Valo 	/* dynamic power save disabled */
2245c1b98a5SKalle Valo 	if (local->hw.conf.dynamic_ps_timeout <= 0)
2255c1b98a5SKalle Valo 		return TX_CONTINUE;
2265c1b98a5SKalle Valo 
2275c1b98a5SKalle Valo 	/* we are scanning, don't enable power save */
2285c1b98a5SKalle Valo 	if (local->scanning)
2295c1b98a5SKalle Valo 		return TX_CONTINUE;
2305c1b98a5SKalle Valo 
2315c1b98a5SKalle Valo 	if (!local->ps_sdata)
2325c1b98a5SKalle Valo 		return TX_CONTINUE;
2335c1b98a5SKalle Valo 
2345c1b98a5SKalle Valo 	/* No point if we're going to suspend */
2355c1b98a5SKalle Valo 	if (local->quiescing)
2365c1b98a5SKalle Valo 		return TX_CONTINUE;
2375c1b98a5SKalle Valo 
2380c74211dSKalle Valo 	/* dynamic ps is supported only in managed mode */
2390c74211dSKalle Valo 	if (tx->sdata->vif.type != NL80211_IFTYPE_STATION)
2400c74211dSKalle Valo 		return TX_CONTINUE;
2410c74211dSKalle Valo 
24294a5b3acSAndrei Otcheretianski 	if (unlikely(info->flags & IEEE80211_TX_INTFL_OFFCHAN_TX_OK))
24394a5b3acSAndrei Otcheretianski 		return TX_CONTINUE;
24494a5b3acSAndrei Otcheretianski 
2450c74211dSKalle Valo 	ifmgd = &tx->sdata->u.mgd;
2460c74211dSKalle Valo 
2470c74211dSKalle Valo 	/*
2480c74211dSKalle Valo 	 * Don't wakeup from power save if u-apsd is enabled, voip ac has
2490c74211dSKalle Valo 	 * u-apsd enabled and the frame is in voip class. This effectively
2500c74211dSKalle Valo 	 * means that even if all access categories have u-apsd enabled, in
2510c74211dSKalle Valo 	 * practise u-apsd is only used with the voip ac. This is a
2520c74211dSKalle Valo 	 * workaround for the case when received voip class packets do not
2530c74211dSKalle Valo 	 * have correct qos tag for some reason, due the network or the
2540c74211dSKalle Valo 	 * peer application.
2550c74211dSKalle Valo 	 *
256dc41e4d4SEliad Peller 	 * Note: ifmgd->uapsd_queues access is racy here. If the value is
2570c74211dSKalle Valo 	 * changed via debugfs, user needs to reassociate manually to have
2580c74211dSKalle Valo 	 * everything in sync.
2590c74211dSKalle Valo 	 */
2604875d30dSJohannes Berg 	if ((ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED) &&
2614875d30dSJohannes Berg 	    (ifmgd->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) &&
2624875d30dSJohannes Berg 	    skb_get_queue_mapping(tx->skb) == IEEE80211_AC_VO)
2630c74211dSKalle Valo 		return TX_CONTINUE;
2640c74211dSKalle Valo 
2655c1b98a5SKalle Valo 	if (local->hw.conf.flags & IEEE80211_CONF_PS) {
2665c1b98a5SKalle Valo 		ieee80211_stop_queues_by_reason(&local->hw,
267445ea4e8SJohannes Berg 						IEEE80211_MAX_QUEUE_MAP,
268cca07b00SLuciano Coelho 						IEEE80211_QUEUE_STOP_REASON_PS,
269cca07b00SLuciano Coelho 						false);
270db28569aSVivek Natarajan 		ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
2715c1b98a5SKalle Valo 		ieee80211_queue_work(&local->hw,
2725c1b98a5SKalle Valo 				     &local->dynamic_ps_disable_work);
2735c1b98a5SKalle Valo 	}
2745c1b98a5SKalle Valo 
2755db1c07cSLuciano Coelho 	/* Don't restart the timer if we're not disassociated */
2765db1c07cSLuciano Coelho 	if (!ifmgd->associated)
2775db1c07cSLuciano Coelho 		return TX_CONTINUE;
2785db1c07cSLuciano Coelho 
2795c1b98a5SKalle Valo 	mod_timer(&local->dynamic_ps_timer, jiffies +
2805c1b98a5SKalle Valo 		  msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
2815c1b98a5SKalle Valo 
2825c1b98a5SKalle Valo 	return TX_CONTINUE;
2835c1b98a5SKalle Valo }
284e2ebc74dSJohannes Berg 
285d9e8a70fSJohannes Berg static ieee80211_tx_result debug_noinline
2865cf121c3SJohannes Berg ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
287e2ebc74dSJohannes Berg {
288358c8d9dSHarvey Harrison 
289e039fa4aSJohannes Berg 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
290e039fa4aSJohannes Berg 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
291c2c98fdeSJohannes Berg 	bool assoc = false;
292e2ebc74dSJohannes Berg 
293e039fa4aSJohannes Berg 	if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED))
2949ae54c84SJohannes Berg 		return TX_CONTINUE;
29558d4185eSJohannes Berg 
296b23b025fSBen Greear 	if (unlikely(test_bit(SCAN_SW_SCANNING, &tx->local->scanning)) &&
297b23b025fSBen Greear 	    test_bit(SDATA_STATE_OFFCHANNEL, &tx->sdata->state) &&
298a9a6ffffSKalle Valo 	    !ieee80211_is_probe_req(hdr->frame_control) &&
299a9a6ffffSKalle Valo 	    !ieee80211_is_nullfunc(hdr->frame_control))
300a9a6ffffSKalle Valo 		/*
301a9a6ffffSKalle Valo 		 * When software scanning only nullfunc frames (to notify
302a9a6ffffSKalle Valo 		 * the sleep state to the AP) and probe requests (for the
303a9a6ffffSKalle Valo 		 * active scan) are allowed, all other frames should not be
304a9a6ffffSKalle Valo 		 * sent and we should not get here, but if we do
305a9a6ffffSKalle Valo 		 * nonetheless, drop them to avoid sending them
306a9a6ffffSKalle Valo 		 * off-channel. See the link below and
307a9a6ffffSKalle Valo 		 * ieee80211_start_scan() for more.
308a9a6ffffSKalle Valo 		 *
309a9a6ffffSKalle Valo 		 * http://article.gmane.org/gmane.linux.kernel.wireless.general/30089
310a9a6ffffSKalle Valo 		 */
3119ae54c84SJohannes Berg 		return TX_DROP;
312e2ebc74dSJohannes Berg 
313239281f8SRostislav Lisovy 	if (tx->sdata->vif.type == NL80211_IFTYPE_OCB)
314239281f8SRostislav Lisovy 		return TX_CONTINUE;
315239281f8SRostislav Lisovy 
3161be7fe8dSBill Jordan 	if (tx->sdata->vif.type == NL80211_IFTYPE_WDS)
3171be7fe8dSBill Jordan 		return TX_CONTINUE;
3181be7fe8dSBill Jordan 
3195cf121c3SJohannes Berg 	if (tx->flags & IEEE80211_TX_PS_BUFFERED)
3209ae54c84SJohannes Berg 		return TX_CONTINUE;
321e2ebc74dSJohannes Berg 
322c2c98fdeSJohannes Berg 	if (tx->sta)
323c2c98fdeSJohannes Berg 		assoc = test_sta_flag(tx->sta, WLAN_STA_ASSOC);
324e2ebc74dSJohannes Berg 
3255cf121c3SJohannes Berg 	if (likely(tx->flags & IEEE80211_TX_UNICAST)) {
326c2c98fdeSJohannes Berg 		if (unlikely(!assoc &&
327358c8d9dSHarvey Harrison 			     ieee80211_is_data(hdr->frame_control))) {
328e2ebc74dSJohannes Berg #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
329bdcbd8e0SJohannes Berg 			sdata_info(tx->sdata,
330bdcbd8e0SJohannes Berg 				   "dropped data frame to not associated station %pM\n",
331bdcbd8e0SJohannes Berg 				   hdr->addr1);
332bdcbd8e0SJohannes Berg #endif
333e2ebc74dSJohannes Berg 			I802_DEBUG_INC(tx->local->tx_handlers_drop_not_assoc);
3349ae54c84SJohannes Berg 			return TX_DROP;
335e2ebc74dSJohannes Berg 		}
33672f15d53SMichael Braun 	} else if (unlikely(ieee80211_is_data(hdr->frame_control) &&
33772f15d53SMichael Braun 			    ieee80211_vif_get_num_mcast_if(tx->sdata) == 0)) {
338e2ebc74dSJohannes Berg 		/*
339e2ebc74dSJohannes Berg 		 * No associated STAs - no need to send multicast
340e2ebc74dSJohannes Berg 		 * frames.
341e2ebc74dSJohannes Berg 		 */
3429ae54c84SJohannes Berg 		return TX_DROP;
343e2ebc74dSJohannes Berg 	}
344e2ebc74dSJohannes Berg 
3459ae54c84SJohannes Berg 	return TX_CONTINUE;
346e2ebc74dSJohannes Berg }
347e2ebc74dSJohannes Berg 
348e2ebc74dSJohannes Berg /* This function is called whenever the AP is about to exceed the maximum limit
349e2ebc74dSJohannes Berg  * of buffered frames for power saving STAs. This situation should not really
350e2ebc74dSJohannes Berg  * happen often during normal operation, so dropping the oldest buffered packet
351e2ebc74dSJohannes Berg  * from each queue should be OK to make some room for new frames. */
352e2ebc74dSJohannes Berg static void purge_old_ps_buffers(struct ieee80211_local *local)
353e2ebc74dSJohannes Berg {
354e2ebc74dSJohannes Berg 	int total = 0, purged = 0;
355e2ebc74dSJohannes Berg 	struct sk_buff *skb;
356e2ebc74dSJohannes Berg 	struct ieee80211_sub_if_data *sdata;
357e2ebc74dSJohannes Berg 	struct sta_info *sta;
358e2ebc74dSJohannes Berg 
35979010420SJohannes Berg 	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
360d012a605SMarco Porsch 		struct ps_data *ps;
361d012a605SMarco Porsch 
362d012a605SMarco Porsch 		if (sdata->vif.type == NL80211_IFTYPE_AP)
363d012a605SMarco Porsch 			ps = &sdata->u.ap.ps;
3643f52b7e3SMarco Porsch 		else if (ieee80211_vif_is_mesh(&sdata->vif))
3653f52b7e3SMarco Porsch 			ps = &sdata->u.mesh.ps;
366d012a605SMarco Porsch 		else
367e2ebc74dSJohannes Berg 			continue;
368d012a605SMarco Porsch 
369d012a605SMarco Porsch 		skb = skb_dequeue(&ps->bc_buf);
370e2ebc74dSJohannes Berg 		if (skb) {
371e2ebc74dSJohannes Berg 			purged++;
3726b07d9caSFelix Fietkau 			ieee80211_free_txskb(&local->hw, skb);
373e2ebc74dSJohannes Berg 		}
374d012a605SMarco Porsch 		total += skb_queue_len(&ps->bc_buf);
375e2ebc74dSJohannes Berg 	}
376e2ebc74dSJohannes Berg 
377948d887dSJohannes Berg 	/*
378948d887dSJohannes Berg 	 * Drop one frame from each station from the lowest-priority
379948d887dSJohannes Berg 	 * AC that has frames at all.
380948d887dSJohannes Berg 	 */
381d0709a65SJohannes Berg 	list_for_each_entry_rcu(sta, &local->sta_list, list) {
382948d887dSJohannes Berg 		int ac;
383948d887dSJohannes Berg 
384948d887dSJohannes Berg 		for (ac = IEEE80211_AC_BK; ac >= IEEE80211_AC_VO; ac--) {
385948d887dSJohannes Berg 			skb = skb_dequeue(&sta->ps_tx_buf[ac]);
386948d887dSJohannes Berg 			total += skb_queue_len(&sta->ps_tx_buf[ac]);
387e2ebc74dSJohannes Berg 			if (skb) {
388e2ebc74dSJohannes Berg 				purged++;
389c3e7724bSFelix Fietkau 				ieee80211_free_txskb(&local->hw, skb);
390948d887dSJohannes Berg 				break;
391e2ebc74dSJohannes Berg 			}
392948d887dSJohannes Berg 		}
393e2ebc74dSJohannes Berg 	}
394d0709a65SJohannes Berg 
395e2ebc74dSJohannes Berg 	local->total_ps_buffered = total;
396bdcbd8e0SJohannes Berg 	ps_dbg_hw(&local->hw, "PS buffers full - purged %d frames\n", purged);
397e2ebc74dSJohannes Berg }
398e2ebc74dSJohannes Berg 
3999ae54c84SJohannes Berg static ieee80211_tx_result
4005cf121c3SJohannes Berg ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx)
401e2ebc74dSJohannes Berg {
402e039fa4aSJohannes Berg 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
403358c8d9dSHarvey Harrison 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
404d012a605SMarco Porsch 	struct ps_data *ps;
405e039fa4aSJohannes Berg 
4067d54d0ddSJohannes Berg 	/*
4077d54d0ddSJohannes Berg 	 * broadcast/multicast frame
4087d54d0ddSJohannes Berg 	 *
4093f52b7e3SMarco Porsch 	 * If any of the associated/peer stations is in power save mode,
4107d54d0ddSJohannes Berg 	 * the frame is buffered to be sent after DTIM beacon frame.
4117d54d0ddSJohannes Berg 	 * This is done either by the hardware or us.
4127d54d0ddSJohannes Berg 	 */
4137d54d0ddSJohannes Berg 
4143f52b7e3SMarco Porsch 	/* powersaving STAs currently only in AP/VLAN/mesh mode */
415d012a605SMarco Porsch 	if (tx->sdata->vif.type == NL80211_IFTYPE_AP ||
416d012a605SMarco Porsch 	    tx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
4173e122be0SJohannes Berg 		if (!tx->sdata->bss)
4183e122be0SJohannes Berg 			return TX_CONTINUE;
4193e122be0SJohannes Berg 
420d012a605SMarco Porsch 		ps = &tx->sdata->bss->ps;
4213f52b7e3SMarco Porsch 	} else if (ieee80211_vif_is_mesh(&tx->sdata->vif)) {
4223f52b7e3SMarco Porsch 		ps = &tx->sdata->u.mesh.ps;
423d012a605SMarco Porsch 	} else {
424d012a605SMarco Porsch 		return TX_CONTINUE;
425d012a605SMarco Porsch 	}
426d012a605SMarco Porsch 
427d012a605SMarco Porsch 
4283e122be0SJohannes Berg 	/* no buffering for ordered frames */
429358c8d9dSHarvey Harrison 	if (ieee80211_has_order(hdr->frame_control))
4309ae54c84SJohannes Berg 		return TX_CONTINUE;
4317d54d0ddSJohannes Berg 
43208b99399SJohannes Berg 	if (ieee80211_is_probe_req(hdr->frame_control))
43308b99399SJohannes Berg 		return TX_CONTINUE;
43408b99399SJohannes Berg 
43530686bf7SJohannes Berg 	if (ieee80211_hw_check(&tx->local->hw, QUEUE_CONTROL))
436f4d57941SJohannes Berg 		info->hw_queue = tx->sdata->vif.cab_queue;
437f4d57941SJohannes Berg 
4389ec1190dSFelix Fietkau 	/* no stations in PS mode and no buffered packets */
4399ec1190dSFelix Fietkau 	if (!atomic_read(&ps->num_sta_ps) && skb_queue_empty(&ps->bc_buf))
4409ae54c84SJohannes Berg 		return TX_CONTINUE;
4417d54d0ddSJohannes Berg 
44262b1208eSJohannes Berg 	info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM;
44362b1208eSJohannes Berg 
44462b517cbSJohannes Berg 	/* device releases frame after DTIM beacon */
44530686bf7SJohannes Berg 	if (!ieee80211_hw_check(&tx->local->hw, HOST_BROADCAST_PS_BUFFERING))
44662b1208eSJohannes Berg 		return TX_CONTINUE;
44762b1208eSJohannes Berg 
4487d54d0ddSJohannes Berg 	/* buffered in mac80211 */
449e2ebc74dSJohannes Berg 	if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER)
450e2ebc74dSJohannes Berg 		purge_old_ps_buffers(tx->local);
45162b1208eSJohannes Berg 
452d012a605SMarco Porsch 	if (skb_queue_len(&ps->bc_buf) >= AP_MAX_BC_BUFFER) {
453bdcbd8e0SJohannes Berg 		ps_dbg(tx->sdata,
454bdcbd8e0SJohannes Berg 		       "BC TX buffer full - dropping the oldest frame\n");
4556b07d9caSFelix Fietkau 		ieee80211_free_txskb(&tx->local->hw, skb_dequeue(&ps->bc_buf));
456e2ebc74dSJohannes Berg 	} else
457e2ebc74dSJohannes Berg 		tx->local->total_ps_buffered++;
45862b1208eSJohannes Berg 
459d012a605SMarco Porsch 	skb_queue_tail(&ps->bc_buf, tx->skb);
46062b1208eSJohannes Berg 
4619ae54c84SJohannes Berg 	return TX_QUEUED;
462e2ebc74dSJohannes Berg }
463e2ebc74dSJohannes Berg 
464fb733336SJouni Malinen static int ieee80211_use_mfp(__le16 fc, struct sta_info *sta,
465fb733336SJouni Malinen 			     struct sk_buff *skb)
466fb733336SJouni Malinen {
467fb733336SJouni Malinen 	if (!ieee80211_is_mgmt(fc))
468fb733336SJouni Malinen 		return 0;
469fb733336SJouni Malinen 
470c2c98fdeSJohannes Berg 	if (sta == NULL || !test_sta_flag(sta, WLAN_STA_MFP))
471fb733336SJouni Malinen 		return 0;
472fb733336SJouni Malinen 
473d8ca16dbSJohannes Berg 	if (!ieee80211_is_robust_mgmt_frame(skb))
474fb733336SJouni Malinen 		return 0;
475fb733336SJouni Malinen 
476fb733336SJouni Malinen 	return 1;
477fb733336SJouni Malinen }
478fb733336SJouni Malinen 
4799ae54c84SJohannes Berg static ieee80211_tx_result
4805cf121c3SJohannes Berg ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
481e2ebc74dSJohannes Berg {
482e2ebc74dSJohannes Berg 	struct sta_info *sta = tx->sta;
483e039fa4aSJohannes Berg 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
48408b99399SJohannes Berg 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
4853393a608SJuuso Oikarinen 	struct ieee80211_local *local = tx->local;
486e2ebc74dSJohannes Berg 
48702f2f1a9SJohannes Berg 	if (unlikely(!sta))
4889ae54c84SJohannes Berg 		return TX_CONTINUE;
489e2ebc74dSJohannes Berg 
490c2c98fdeSJohannes Berg 	if (unlikely((test_sta_flag(sta, WLAN_STA_PS_STA) ||
4915ac2e350SJohannes Berg 		      test_sta_flag(sta, WLAN_STA_PS_DRIVER) ||
4925ac2e350SJohannes Berg 		      test_sta_flag(sta, WLAN_STA_PS_DELIVER)) &&
49302f2f1a9SJohannes Berg 		     !(info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER))) {
494948d887dSJohannes Berg 		int ac = skb_get_queue_mapping(tx->skb);
495948d887dSJohannes Berg 
49608b99399SJohannes Berg 		if (ieee80211_is_mgmt(hdr->frame_control) &&
49708b99399SJohannes Berg 		    !ieee80211_is_bufferable_mmpdu(hdr->frame_control)) {
49808b99399SJohannes Berg 			info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER;
49908b99399SJohannes Berg 			return TX_CONTINUE;
50008b99399SJohannes Berg 		}
50108b99399SJohannes Berg 
502bdcbd8e0SJohannes Berg 		ps_dbg(sta->sdata, "STA %pM aid %d: PS buffer for AC %d\n",
503948d887dSJohannes Berg 		       sta->sta.addr, sta->sta.aid, ac);
504e2ebc74dSJohannes Berg 		if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER)
505e2ebc74dSJohannes Berg 			purge_old_ps_buffers(tx->local);
5061d147bfaSEmmanuel Grumbach 
5071d147bfaSEmmanuel Grumbach 		/* sync with ieee80211_sta_ps_deliver_wakeup */
5081d147bfaSEmmanuel Grumbach 		spin_lock(&sta->ps_lock);
5091d147bfaSEmmanuel Grumbach 		/*
5101d147bfaSEmmanuel Grumbach 		 * STA woke up the meantime and all the frames on ps_tx_buf have
5111d147bfaSEmmanuel Grumbach 		 * been queued to pending queue. No reordering can happen, go
5121d147bfaSEmmanuel Grumbach 		 * ahead and Tx the packet.
5131d147bfaSEmmanuel Grumbach 		 */
5141d147bfaSEmmanuel Grumbach 		if (!test_sta_flag(sta, WLAN_STA_PS_STA) &&
5155ac2e350SJohannes Berg 		    !test_sta_flag(sta, WLAN_STA_PS_DRIVER) &&
5165ac2e350SJohannes Berg 		    !test_sta_flag(sta, WLAN_STA_PS_DELIVER)) {
5171d147bfaSEmmanuel Grumbach 			spin_unlock(&sta->ps_lock);
5181d147bfaSEmmanuel Grumbach 			return TX_CONTINUE;
5191d147bfaSEmmanuel Grumbach 		}
5201d147bfaSEmmanuel Grumbach 
521948d887dSJohannes Berg 		if (skb_queue_len(&sta->ps_tx_buf[ac]) >= STA_MAX_TX_BUFFER) {
522948d887dSJohannes Berg 			struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf[ac]);
523bdcbd8e0SJohannes Berg 			ps_dbg(tx->sdata,
524bdcbd8e0SJohannes Berg 			       "STA %pM TX buffer for AC %d full - dropping oldest frame\n",
525bdcbd8e0SJohannes Berg 			       sta->sta.addr, ac);
526c3e7724bSFelix Fietkau 			ieee80211_free_txskb(&local->hw, old);
527e2ebc74dSJohannes Berg 		} else
528e2ebc74dSJohannes Berg 			tx->local->total_ps_buffered++;
529004c872eSJohannes Berg 
530e039fa4aSJohannes Berg 		info->control.jiffies = jiffies;
5315061b0c2SJohannes Berg 		info->control.vif = &tx->sdata->vif;
5328f77f384SJohannes Berg 		info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
53303c8c06fSJohannes Berg 		info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS;
534948d887dSJohannes Berg 		skb_queue_tail(&sta->ps_tx_buf[ac], tx->skb);
5351d147bfaSEmmanuel Grumbach 		spin_unlock(&sta->ps_lock);
5363393a608SJuuso Oikarinen 
5373393a608SJuuso Oikarinen 		if (!timer_pending(&local->sta_cleanup))
5383393a608SJuuso Oikarinen 			mod_timer(&local->sta_cleanup,
5393393a608SJuuso Oikarinen 				  round_jiffies(jiffies +
5403393a608SJuuso Oikarinen 						STA_INFO_CLEANUP_INTERVAL));
5413393a608SJuuso Oikarinen 
542c868cb35SJohannes Berg 		/*
543c868cb35SJohannes Berg 		 * We queued up some frames, so the TIM bit might
544c868cb35SJohannes Berg 		 * need to be set, recalculate it.
545c868cb35SJohannes Berg 		 */
546c868cb35SJohannes Berg 		sta_info_recalc_tim(sta);
547c868cb35SJohannes Berg 
5489ae54c84SJohannes Berg 		return TX_QUEUED;
549bdcbd8e0SJohannes Berg 	} else if (unlikely(test_sta_flag(sta, WLAN_STA_PS_STA))) {
550bdcbd8e0SJohannes Berg 		ps_dbg(tx->sdata,
551bdcbd8e0SJohannes Berg 		       "STA %pM in PS mode, but polling/in SP -> send frame\n",
552bdcbd8e0SJohannes Berg 		       sta->sta.addr);
553e2ebc74dSJohannes Berg 	}
554e2ebc74dSJohannes Berg 
5559ae54c84SJohannes Berg 	return TX_CONTINUE;
556e2ebc74dSJohannes Berg }
557e2ebc74dSJohannes Berg 
558d9e8a70fSJohannes Berg static ieee80211_tx_result debug_noinline
5595cf121c3SJohannes Berg ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx)
560e2ebc74dSJohannes Berg {
5615cf121c3SJohannes Berg 	if (unlikely(tx->flags & IEEE80211_TX_PS_BUFFERED))
5629ae54c84SJohannes Berg 		return TX_CONTINUE;
563e2ebc74dSJohannes Berg 
5645cf121c3SJohannes Berg 	if (tx->flags & IEEE80211_TX_UNICAST)
565e2ebc74dSJohannes Berg 		return ieee80211_tx_h_unicast_ps_buf(tx);
566e2ebc74dSJohannes Berg 	else
567e2ebc74dSJohannes Berg 		return ieee80211_tx_h_multicast_ps_buf(tx);
568e2ebc74dSJohannes Berg }
569e2ebc74dSJohannes Berg 
570d9e8a70fSJohannes Berg static ieee80211_tx_result debug_noinline
571a621fa4dSJohannes Berg ieee80211_tx_h_check_control_port_protocol(struct ieee80211_tx_data *tx)
572a621fa4dSJohannes Berg {
573a621fa4dSJohannes Berg 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
574a621fa4dSJohannes Berg 
575af61a165SJohannes Berg 	if (unlikely(tx->sdata->control_port_protocol == tx->skb->protocol)) {
576af61a165SJohannes Berg 		if (tx->sdata->control_port_no_encrypt)
577a621fa4dSJohannes Berg 			info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
578af61a165SJohannes Berg 		info->control.flags |= IEEE80211_TX_CTRL_PORT_CTRL_PROTO;
5799c1c98a3SJouni Malinen 		info->flags |= IEEE80211_TX_CTL_USE_MINRATE;
580af61a165SJohannes Berg 	}
581a621fa4dSJohannes Berg 
582a621fa4dSJohannes Berg 	return TX_CONTINUE;
583a621fa4dSJohannes Berg }
584a621fa4dSJohannes Berg 
585a621fa4dSJohannes Berg static ieee80211_tx_result debug_noinline
5865cf121c3SJohannes Berg ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
587e2ebc74dSJohannes Berg {
58846e6de15SJohannes Berg 	struct ieee80211_key *key;
589e039fa4aSJohannes Berg 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
590358c8d9dSHarvey Harrison 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
591d4e46a3dSJohannes Berg 
5923b8d81e0SJohannes Berg 	if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT))
593e2ebc74dSJohannes Berg 		tx->key = NULL;
5942475b1ccSMax Stepanov 	else if (tx->sta &&
5952475b1ccSMax Stepanov 		 (key = rcu_dereference(tx->sta->ptk[tx->sta->ptk_idx])))
596d4e46a3dSJohannes Berg 		tx->key = key;
59746f6b060SMasashi Honma 	else if (ieee80211_is_group_privacy_action(tx->skb) &&
59846f6b060SMasashi Honma 		(key = rcu_dereference(tx->sdata->default_multicast_key)))
59946f6b060SMasashi Honma 		tx->key = key;
6003cfcf6acSJouni Malinen 	else if (ieee80211_is_mgmt(hdr->frame_control) &&
601ecbcd324SJouni Malinen 		 is_multicast_ether_addr(hdr->addr1) &&
602d8ca16dbSJohannes Berg 		 ieee80211_is_robust_mgmt_frame(tx->skb) &&
6033cfcf6acSJouni Malinen 		 (key = rcu_dereference(tx->sdata->default_mgmt_key)))
6043cfcf6acSJouni Malinen 		tx->key = key;
605f7e0104cSJohannes Berg 	else if (is_multicast_ether_addr(hdr->addr1) &&
606f7e0104cSJohannes Berg 		 (key = rcu_dereference(tx->sdata->default_multicast_key)))
607f7e0104cSJohannes Berg 		tx->key = key;
608f7e0104cSJohannes Berg 	else if (!is_multicast_ether_addr(hdr->addr1) &&
609f7e0104cSJohannes Berg 		 (key = rcu_dereference(tx->sdata->default_unicast_key)))
610d4e46a3dSJohannes Berg 		tx->key = key;
611e8f4fb7cSJohannes Berg 	else
61246e6de15SJohannes Berg 		tx->key = NULL;
613e2ebc74dSJohannes Berg 
614e2ebc74dSJohannes Berg 	if (tx->key) {
615813d7669SJohannes Berg 		bool skip_hw = false;
616813d7669SJohannes Berg 
617011bfcc4SJohannes Berg 		/* TODO: add threshold stuff again */
618176e4f84SJohannes Berg 
61997359d12SJohannes Berg 		switch (tx->key->conf.cipher) {
62097359d12SJohannes Berg 		case WLAN_CIPHER_SUITE_WEP40:
62197359d12SJohannes Berg 		case WLAN_CIPHER_SUITE_WEP104:
62297359d12SJohannes Berg 		case WLAN_CIPHER_SUITE_TKIP:
623358c8d9dSHarvey Harrison 			if (!ieee80211_is_data_present(hdr->frame_control))
624176e4f84SJohannes Berg 				tx->key = NULL;
625176e4f84SJohannes Berg 			break;
62697359d12SJohannes Berg 		case WLAN_CIPHER_SUITE_CCMP:
6272b2ba0dbSJouni Malinen 		case WLAN_CIPHER_SUITE_CCMP_256:
62800b9cfa3SJouni Malinen 		case WLAN_CIPHER_SUITE_GCMP:
62900b9cfa3SJouni Malinen 		case WLAN_CIPHER_SUITE_GCMP_256:
630fb733336SJouni Malinen 			if (!ieee80211_is_data_present(hdr->frame_control) &&
631fb733336SJouni Malinen 			    !ieee80211_use_mfp(hdr->frame_control, tx->sta,
63246f6b060SMasashi Honma 					       tx->skb) &&
63346f6b060SMasashi Honma 			    !ieee80211_is_group_privacy_action(tx->skb))
634fb733336SJouni Malinen 				tx->key = NULL;
6353b43a187SKalle Valo 			else
636813d7669SJohannes Berg 				skip_hw = (tx->key->conf.flags &
637e548c49eSJohannes Berg 					   IEEE80211_KEY_FLAG_SW_MGMT_TX) &&
638813d7669SJohannes Berg 					ieee80211_is_mgmt(hdr->frame_control);
639fb733336SJouni Malinen 			break;
64097359d12SJohannes Berg 		case WLAN_CIPHER_SUITE_AES_CMAC:
64156c52da2SJouni Malinen 		case WLAN_CIPHER_SUITE_BIP_CMAC_256:
6428ade538bSJouni Malinen 		case WLAN_CIPHER_SUITE_BIP_GMAC_128:
6438ade538bSJouni Malinen 		case WLAN_CIPHER_SUITE_BIP_GMAC_256:
6443cfcf6acSJouni Malinen 			if (!ieee80211_is_mgmt(hdr->frame_control))
6453cfcf6acSJouni Malinen 				tx->key = NULL;
6463cfcf6acSJouni Malinen 			break;
647e2ebc74dSJohannes Berg 		}
648813d7669SJohannes Berg 
649e54faf29SJohannes Berg 		if (unlikely(tx->key && tx->key->flags & KEY_FLAG_TAINTED &&
650e54faf29SJohannes Berg 			     !ieee80211_is_deauth(hdr->frame_control)))
65195acac61SJohannes Berg 			return TX_DROP;
65295acac61SJohannes Berg 
653f12553ebSJohannes Berg 		if (!skip_hw && tx->key &&
654382b1655SJohannes Berg 		    tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
655813d7669SJohannes Berg 			info->control.hw_key = &tx->key->conf;
656176e4f84SJohannes Berg 	}
657176e4f84SJohannes Berg 
6589ae54c84SJohannes Berg 	return TX_CONTINUE;
659e2ebc74dSJohannes Berg }
660e2ebc74dSJohannes Berg 
661d9e8a70fSJohannes Berg static ieee80211_tx_result debug_noinline
6625cf121c3SJohannes Berg ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
663e2ebc74dSJohannes Berg {
664e039fa4aSJohannes Berg 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
665e6a9854bSJohannes Berg 	struct ieee80211_hdr *hdr = (void *)tx->skb->data;
666e6a9854bSJohannes Berg 	struct ieee80211_supported_band *sband;
667a2c40249SShanyu Zhao 	u32 len;
668e6a9854bSJohannes Berg 	struct ieee80211_tx_rate_control txrc;
6690d528d85SFelix Fietkau 	struct ieee80211_sta_rates *ratetbl = NULL;
670c2c98fdeSJohannes Berg 	bool assoc = false;
671e6a9854bSJohannes Berg 
672e6a9854bSJohannes Berg 	memset(&txrc, 0, sizeof(txrc));
6738318d78aSJohannes Berg 
6742d56577bSJohannes Berg 	sband = tx->local->hw.wiphy->bands[info->band];
675e2ebc74dSJohannes Berg 
676a2c40249SShanyu Zhao 	len = min_t(u32, tx->skb->len + FCS_LEN,
677b9a5f8caSJouni Malinen 			 tx->local->hw.wiphy->frag_threshold);
67858d4185eSJohannes Berg 
679e6a9854bSJohannes Berg 	/* set up the tx rate control struct we give the RC algo */
680005e472bSJohannes Berg 	txrc.hw = &tx->local->hw;
681e6a9854bSJohannes Berg 	txrc.sband = sband;
682e6a9854bSJohannes Berg 	txrc.bss_conf = &tx->sdata->vif.bss_conf;
683e6a9854bSJohannes Berg 	txrc.skb = tx->skb;
684e6a9854bSJohannes Berg 	txrc.reported_rate.idx = -1;
6852d56577bSJohannes Berg 	txrc.rate_idx_mask = tx->sdata->rc_rateidx_mask[info->band];
6862ffbe6d3SFelix Fietkau 
6872ffbe6d3SFelix Fietkau 	if (tx->sdata->rc_has_mcs_mask[info->band])
6882ffbe6d3SFelix Fietkau 		txrc.rate_idx_mcs_mask =
6892ffbe6d3SFelix Fietkau 			tx->sdata->rc_rateidx_mcs_mask[info->band];
6902ffbe6d3SFelix Fietkau 
6918f0729b1SFelix Fietkau 	txrc.bss = (tx->sdata->vif.type == NL80211_IFTYPE_AP ||
6924bb62344SChun-Yeow Yeoh 		    tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
6935765f9f6SBertold Van den Bergh 		    tx->sdata->vif.type == NL80211_IFTYPE_ADHOC ||
6945765f9f6SBertold Van den Bergh 		    tx->sdata->vif.type == NL80211_IFTYPE_OCB);
69558d4185eSJohannes Berg 
696e6a9854bSJohannes Berg 	/* set up RTS protection if desired */
697b9a5f8caSJouni Malinen 	if (len > tx->local->hw.wiphy->rts_threshold) {
6980d528d85SFelix Fietkau 		txrc.rts = true;
699e2ebc74dSJohannes Berg 	}
700e6a9854bSJohannes Berg 
7010d528d85SFelix Fietkau 	info->control.use_rts = txrc.rts;
702991fec09SFelix Fietkau 	info->control.use_cts_prot = tx->sdata->vif.bss_conf.use_cts_prot;
703991fec09SFelix Fietkau 
704e6a9854bSJohannes Berg 	/*
705e6a9854bSJohannes Berg 	 * Use short preamble if the BSS can handle it, but not for
706e6a9854bSJohannes Berg 	 * management frames unless we know the receiver can handle
707e6a9854bSJohannes Berg 	 * that -- the management frame might be to a station that
708e6a9854bSJohannes Berg 	 * just wants a probe response.
709e6a9854bSJohannes Berg 	 */
710e6a9854bSJohannes Berg 	if (tx->sdata->vif.bss_conf.use_short_preamble &&
711e6a9854bSJohannes Berg 	    (ieee80211_is_data(hdr->frame_control) ||
712c2c98fdeSJohannes Berg 	     (tx->sta && test_sta_flag(tx->sta, WLAN_STA_SHORT_PREAMBLE))))
7130d528d85SFelix Fietkau 		txrc.short_preamble = true;
7140d528d85SFelix Fietkau 
7150d528d85SFelix Fietkau 	info->control.short_preamble = txrc.short_preamble;
716e6a9854bSJohannes Berg 
717dfdfc2beSSven Eckelmann 	/* don't ask rate control when rate already injected via radiotap */
718dfdfc2beSSven Eckelmann 	if (info->control.flags & IEEE80211_TX_CTRL_RATE_INJECT)
719dfdfc2beSSven Eckelmann 		return TX_CONTINUE;
720dfdfc2beSSven Eckelmann 
721c2c98fdeSJohannes Berg 	if (tx->sta)
722c2c98fdeSJohannes Berg 		assoc = test_sta_flag(tx->sta, WLAN_STA_ASSOC);
723e6a9854bSJohannes Berg 
724b770b43eSLuis R. Rodriguez 	/*
725b770b43eSLuis R. Rodriguez 	 * Lets not bother rate control if we're associated and cannot
726b770b43eSLuis R. Rodriguez 	 * talk to the sta. This should not happen.
727b770b43eSLuis R. Rodriguez 	 */
728c2c98fdeSJohannes Berg 	if (WARN(test_bit(SCAN_SW_SCANNING, &tx->local->scanning) && assoc &&
729b770b43eSLuis R. Rodriguez 		 !rate_usable_index_exists(sband, &tx->sta->sta),
730b770b43eSLuis R. Rodriguez 		 "%s: Dropped data frame as no usable bitrate found while "
731b770b43eSLuis R. Rodriguez 		 "scanning and associated. Target station: "
732b770b43eSLuis R. Rodriguez 		 "%pM on %d GHz band\n",
73347846c9bSJohannes Berg 		 tx->sdata->name, hdr->addr1,
7342d56577bSJohannes Berg 		 info->band ? 5 : 2))
735b770b43eSLuis R. Rodriguez 		return TX_DROP;
736b770b43eSLuis R. Rodriguez 
737b770b43eSLuis R. Rodriguez 	/*
738b770b43eSLuis R. Rodriguez 	 * If we're associated with the sta at this point we know we can at
739b770b43eSLuis R. Rodriguez 	 * least send the frame at the lowest bit rate.
740b770b43eSLuis R. Rodriguez 	 */
741e6a9854bSJohannes Berg 	rate_control_get_rate(tx->sdata, tx->sta, &txrc);
742e6a9854bSJohannes Berg 
7430d528d85SFelix Fietkau 	if (tx->sta && !info->control.skip_table)
7440d528d85SFelix Fietkau 		ratetbl = rcu_dereference(tx->sta->sta.rates);
7450d528d85SFelix Fietkau 
7460d528d85SFelix Fietkau 	if (unlikely(info->control.rates[0].idx < 0)) {
7470d528d85SFelix Fietkau 		if (ratetbl) {
7480d528d85SFelix Fietkau 			struct ieee80211_tx_rate rate = {
7490d528d85SFelix Fietkau 				.idx = ratetbl->rate[0].idx,
7500d528d85SFelix Fietkau 				.flags = ratetbl->rate[0].flags,
7510d528d85SFelix Fietkau 				.count = ratetbl->rate[0].count
7520d528d85SFelix Fietkau 			};
7530d528d85SFelix Fietkau 
7540d528d85SFelix Fietkau 			if (ratetbl->rate[0].idx < 0)
755e6a9854bSJohannes Berg 				return TX_DROP;
756e6a9854bSJohannes Berg 
7570d528d85SFelix Fietkau 			tx->rate = rate;
7580d528d85SFelix Fietkau 		} else {
7590d528d85SFelix Fietkau 			return TX_DROP;
7600d528d85SFelix Fietkau 		}
7610d528d85SFelix Fietkau 	} else {
7620d528d85SFelix Fietkau 		tx->rate = info->control.rates[0];
7630d528d85SFelix Fietkau 	}
7640d528d85SFelix Fietkau 
765c1ce5a74SHelmut Schaa 	if (txrc.reported_rate.idx < 0) {
7660d528d85SFelix Fietkau 		txrc.reported_rate = tx->rate;
767c1ce5a74SHelmut Schaa 		if (tx->sta && ieee80211_is_data(hdr->frame_control))
768e5a9f8d0SJohannes Berg 			tx->sta->tx_stats.last_rate = txrc.reported_rate;
769c1ce5a74SHelmut Schaa 	} else if (tx->sta)
770e5a9f8d0SJohannes Berg 		tx->sta->tx_stats.last_rate = txrc.reported_rate;
771e6a9854bSJohannes Berg 
7720d528d85SFelix Fietkau 	if (ratetbl)
7730d528d85SFelix Fietkau 		return TX_CONTINUE;
7740d528d85SFelix Fietkau 
775e6a9854bSJohannes Berg 	if (unlikely(!info->control.rates[0].count))
776e6a9854bSJohannes Berg 		info->control.rates[0].count = 1;
777e6a9854bSJohannes Berg 
7789955151dSGábor Stefanik 	if (WARN_ON_ONCE((info->control.rates[0].count > 1) &&
7799955151dSGábor Stefanik 			 (info->flags & IEEE80211_TX_CTL_NO_ACK)))
7809955151dSGábor Stefanik 		info->control.rates[0].count = 1;
7819955151dSGábor Stefanik 
7829ae54c84SJohannes Berg 	return TX_CONTINUE;
783e2ebc74dSJohannes Berg }
784e2ebc74dSJohannes Berg 
785ba8c3d6fSFelix Fietkau static __le16 ieee80211_tx_next_seq(struct sta_info *sta, int tid)
786ba8c3d6fSFelix Fietkau {
787ba8c3d6fSFelix Fietkau 	u16 *seq = &sta->tid_seq[tid];
788ba8c3d6fSFelix Fietkau 	__le16 ret = cpu_to_le16(*seq);
789ba8c3d6fSFelix Fietkau 
790ba8c3d6fSFelix Fietkau 	/* Increase the sequence number. */
791ba8c3d6fSFelix Fietkau 	*seq = (*seq + 0x10) & IEEE80211_SCTL_SEQ;
792ba8c3d6fSFelix Fietkau 
793ba8c3d6fSFelix Fietkau 	return ret;
794ba8c3d6fSFelix Fietkau }
795ba8c3d6fSFelix Fietkau 
796d9e8a70fSJohannes Berg static ieee80211_tx_result debug_noinline
797f591fa5dSJohannes Berg ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
798f591fa5dSJohannes Berg {
799f591fa5dSJohannes Berg 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
800f591fa5dSJohannes Berg 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
801f591fa5dSJohannes Berg 	int tid;
802f591fa5dSJohannes Berg 
80325d834e1SJohannes Berg 	/*
80425d834e1SJohannes Berg 	 * Packet injection may want to control the sequence
80525d834e1SJohannes Berg 	 * number, if we have no matching interface then we
80625d834e1SJohannes Berg 	 * neither assign one ourselves nor ask the driver to.
80725d834e1SJohannes Berg 	 */
8085061b0c2SJohannes Berg 	if (unlikely(info->control.vif->type == NL80211_IFTYPE_MONITOR))
80925d834e1SJohannes Berg 		return TX_CONTINUE;
81025d834e1SJohannes Berg 
811f591fa5dSJohannes Berg 	if (unlikely(ieee80211_is_ctl(hdr->frame_control)))
812f591fa5dSJohannes Berg 		return TX_CONTINUE;
813f591fa5dSJohannes Berg 
814f591fa5dSJohannes Berg 	if (ieee80211_hdrlen(hdr->frame_control) < 24)
815f591fa5dSJohannes Berg 		return TX_CONTINUE;
816f591fa5dSJohannes Berg 
81749a59543SJohannes Berg 	if (ieee80211_is_qos_nullfunc(hdr->frame_control))
81849a59543SJohannes Berg 		return TX_CONTINUE;
81949a59543SJohannes Berg 
82094778280SJohannes Berg 	/*
82194778280SJohannes Berg 	 * Anything but QoS data that has a sequence number field
82294778280SJohannes Berg 	 * (is long enough) gets a sequence number from the global
823c4c205f3SBob Copeland 	 * counter.  QoS data frames with a multicast destination
824c4c205f3SBob Copeland 	 * also use the global counter (802.11-2012 9.3.2.10).
82594778280SJohannes Berg 	 */
826c4c205f3SBob Copeland 	if (!ieee80211_is_data_qos(hdr->frame_control) ||
827c4c205f3SBob Copeland 	    is_multicast_ether_addr(hdr->addr1)) {
828b9771d41SJohannes Berg 		if (tx->flags & IEEE80211_TX_NO_SEQNO)
829b9771d41SJohannes Berg 			return TX_CONTINUE;
83094778280SJohannes Berg 		/* driver should assign sequence number */
831f591fa5dSJohannes Berg 		info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ;
83294778280SJohannes Berg 		/* for pure STA mode without beacons, we can do it */
83394778280SJohannes Berg 		hdr->seq_ctrl = cpu_to_le16(tx->sdata->sequence_number);
83494778280SJohannes Berg 		tx->sdata->sequence_number += 0x10;
83579c892b8SJohannes Berg 		if (tx->sta)
836e5a9f8d0SJohannes Berg 			tx->sta->tx_stats.msdu[IEEE80211_NUM_TIDS]++;
837f591fa5dSJohannes Berg 		return TX_CONTINUE;
838f591fa5dSJohannes Berg 	}
839f591fa5dSJohannes Berg 
840f591fa5dSJohannes Berg 	/*
841f591fa5dSJohannes Berg 	 * This should be true for injected/management frames only, for
842f591fa5dSJohannes Berg 	 * management frames we have set the IEEE80211_TX_CTL_ASSIGN_SEQ
843f591fa5dSJohannes Berg 	 * above since they are not QoS-data frames.
844f591fa5dSJohannes Berg 	 */
845f591fa5dSJohannes Berg 	if (!tx->sta)
846f591fa5dSJohannes Berg 		return TX_CONTINUE;
847f591fa5dSJohannes Berg 
848f591fa5dSJohannes Berg 	/* include per-STA, per-TID sequence counter */
849a1f2ba04SSara Sharon 	tid = ieee80211_get_tid(hdr);
850e5a9f8d0SJohannes Berg 	tx->sta->tx_stats.msdu[tid]++;
851f591fa5dSJohannes Berg 
852ba8c3d6fSFelix Fietkau 	hdr->seq_ctrl = ieee80211_tx_next_seq(tx->sta, tid);
853f591fa5dSJohannes Berg 
854f591fa5dSJohannes Berg 	return TX_CONTINUE;
855f591fa5dSJohannes Berg }
856f591fa5dSJohannes Berg 
857252b86c4SJohannes Berg static int ieee80211_fragment(struct ieee80211_tx_data *tx,
8582de8e0d9SJohannes Berg 			      struct sk_buff *skb, int hdrlen,
8592de8e0d9SJohannes Berg 			      int frag_threshold)
8602de8e0d9SJohannes Berg {
861252b86c4SJohannes Berg 	struct ieee80211_local *local = tx->local;
862a1a3fcecSJohannes Berg 	struct ieee80211_tx_info *info;
863252b86c4SJohannes Berg 	struct sk_buff *tmp;
8642de8e0d9SJohannes Berg 	int per_fragm = frag_threshold - hdrlen - FCS_LEN;
8652de8e0d9SJohannes Berg 	int pos = hdrlen + per_fragm;
8662de8e0d9SJohannes Berg 	int rem = skb->len - hdrlen - per_fragm;
8672de8e0d9SJohannes Berg 
8682de8e0d9SJohannes Berg 	if (WARN_ON(rem < 0))
8692de8e0d9SJohannes Berg 		return -EINVAL;
8702de8e0d9SJohannes Berg 
871252b86c4SJohannes Berg 	/* first fragment was already added to queue by caller */
872252b86c4SJohannes Berg 
8732de8e0d9SJohannes Berg 	while (rem) {
8742de8e0d9SJohannes Berg 		int fraglen = per_fragm;
8752de8e0d9SJohannes Berg 
8762de8e0d9SJohannes Berg 		if (fraglen > rem)
8772de8e0d9SJohannes Berg 			fraglen = rem;
8782de8e0d9SJohannes Berg 		rem -= fraglen;
8792de8e0d9SJohannes Berg 		tmp = dev_alloc_skb(local->tx_headroom +
8802de8e0d9SJohannes Berg 				    frag_threshold +
8812475b1ccSMax Stepanov 				    tx->sdata->encrypt_headroom +
8822de8e0d9SJohannes Berg 				    IEEE80211_ENCRYPT_TAILROOM);
8832de8e0d9SJohannes Berg 		if (!tmp)
8842de8e0d9SJohannes Berg 			return -ENOMEM;
885252b86c4SJohannes Berg 
886252b86c4SJohannes Berg 		__skb_queue_tail(&tx->skbs, tmp);
887252b86c4SJohannes Berg 
8882475b1ccSMax Stepanov 		skb_reserve(tmp,
8892475b1ccSMax Stepanov 			    local->tx_headroom + tx->sdata->encrypt_headroom);
8902475b1ccSMax Stepanov 
8912de8e0d9SJohannes Berg 		/* copy control information */
8922de8e0d9SJohannes Berg 		memcpy(tmp->cb, skb->cb, sizeof(tmp->cb));
893a1a3fcecSJohannes Berg 
894a1a3fcecSJohannes Berg 		info = IEEE80211_SKB_CB(tmp);
895a1a3fcecSJohannes Berg 		info->flags &= ~(IEEE80211_TX_CTL_CLEAR_PS_FILT |
896a1a3fcecSJohannes Berg 				 IEEE80211_TX_CTL_FIRST_FRAGMENT);
897a1a3fcecSJohannes Berg 
898a1a3fcecSJohannes Berg 		if (rem)
899a1a3fcecSJohannes Berg 			info->flags |= IEEE80211_TX_CTL_MORE_FRAMES;
900a1a3fcecSJohannes Berg 
9012de8e0d9SJohannes Berg 		skb_copy_queue_mapping(tmp, skb);
9022de8e0d9SJohannes Berg 		tmp->priority = skb->priority;
9032de8e0d9SJohannes Berg 		tmp->dev = skb->dev;
9042de8e0d9SJohannes Berg 
9052de8e0d9SJohannes Berg 		/* copy header and data */
90659ae1d12SJohannes Berg 		skb_put_data(tmp, skb->data, hdrlen);
90759ae1d12SJohannes Berg 		skb_put_data(tmp, skb->data + pos, fraglen);
9082de8e0d9SJohannes Berg 
9092de8e0d9SJohannes Berg 		pos += fraglen;
9102de8e0d9SJohannes Berg 	}
9112de8e0d9SJohannes Berg 
912252b86c4SJohannes Berg 	/* adjust first fragment's length */
913338f977fSJohannes Berg 	skb_trim(skb, hdrlen + per_fragm);
9142de8e0d9SJohannes Berg 	return 0;
9152de8e0d9SJohannes Berg }
9162de8e0d9SJohannes Berg 
917f591fa5dSJohannes Berg static ieee80211_tx_result debug_noinline
918e2454948SJohannes Berg ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)
919e2454948SJohannes Berg {
9202de8e0d9SJohannes Berg 	struct sk_buff *skb = tx->skb;
9212de8e0d9SJohannes Berg 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
9222de8e0d9SJohannes Berg 	struct ieee80211_hdr *hdr = (void *)skb->data;
923b9a5f8caSJouni Malinen 	int frag_threshold = tx->local->hw.wiphy->frag_threshold;
9242de8e0d9SJohannes Berg 	int hdrlen;
9252de8e0d9SJohannes Berg 	int fragnum;
926e2454948SJohannes Berg 
927252b86c4SJohannes Berg 	/* no matter what happens, tx->skb moves to tx->skbs */
928252b86c4SJohannes Berg 	__skb_queue_tail(&tx->skbs, skb);
929252b86c4SJohannes Berg 	tx->skb = NULL;
930252b86c4SJohannes Berg 
931a26eb27aSJohannes Berg 	if (info->flags & IEEE80211_TX_CTL_DONTFRAG)
932a26eb27aSJohannes Berg 		return TX_CONTINUE;
933a26eb27aSJohannes Berg 
934f3fe4e93SSara Sharon 	if (ieee80211_hw_check(&tx->local->hw, SUPPORTS_TX_FRAG))
935e2454948SJohannes Berg 		return TX_CONTINUE;
936e2454948SJohannes Berg 
937eefce91aSJohannes Berg 	/*
938eefce91aSJohannes Berg 	 * Warn when submitting a fragmented A-MPDU frame and drop it.
9393b8d81e0SJohannes Berg 	 * This scenario is handled in ieee80211_tx_prepare but extra
9408d5e0d58SRon Rindjunsky 	 * caution taken here as fragmented ampdu may cause Tx stop.
941eefce91aSJohannes Berg 	 */
9428b30b1feSSujith 	if (WARN_ON(info->flags & IEEE80211_TX_CTL_AMPDU))
943eefce91aSJohannes Berg 		return TX_DROP;
944eefce91aSJohannes Berg 
945065e9605SHarvey Harrison 	hdrlen = ieee80211_hdrlen(hdr->frame_control);
946e2454948SJohannes Berg 
947a26eb27aSJohannes Berg 	/* internal error, why isn't DONTFRAG set? */
9488ccd8f21SJohannes Berg 	if (WARN_ON(skb->len + FCS_LEN <= frag_threshold))
9492de8e0d9SJohannes Berg 		return TX_DROP;
950e2454948SJohannes Berg 
9512de8e0d9SJohannes Berg 	/*
9522de8e0d9SJohannes Berg 	 * Now fragment the frame. This will allocate all the fragments and
9532de8e0d9SJohannes Berg 	 * chain them (using skb as the first fragment) to skb->next.
9542de8e0d9SJohannes Berg 	 * During transmission, we will remove the successfully transmitted
9552de8e0d9SJohannes Berg 	 * fragments from this list. When the low-level driver rejects one
9562de8e0d9SJohannes Berg 	 * of the fragments then we will simply pretend to accept the skb
9572de8e0d9SJohannes Berg 	 * but store it away as pending.
9582de8e0d9SJohannes Berg 	 */
959252b86c4SJohannes Berg 	if (ieee80211_fragment(tx, skb, hdrlen, frag_threshold))
9602de8e0d9SJohannes Berg 		return TX_DROP;
961e2454948SJohannes Berg 
9622de8e0d9SJohannes Berg 	/* update duration/seq/flags of fragments */
9632de8e0d9SJohannes Berg 	fragnum = 0;
964252b86c4SJohannes Berg 
965252b86c4SJohannes Berg 	skb_queue_walk(&tx->skbs, skb) {
9662de8e0d9SJohannes Berg 		const __le16 morefrags = cpu_to_le16(IEEE80211_FCTL_MOREFRAGS);
967e2454948SJohannes Berg 
9682de8e0d9SJohannes Berg 		hdr = (void *)skb->data;
9692de8e0d9SJohannes Berg 		info = IEEE80211_SKB_CB(skb);
970e6a9854bSJohannes Berg 
971252b86c4SJohannes Berg 		if (!skb_queue_is_last(&tx->skbs, skb)) {
9722de8e0d9SJohannes Berg 			hdr->frame_control |= morefrags;
973e6a9854bSJohannes Berg 			/*
974e6a9854bSJohannes Berg 			 * No multi-rate retries for fragmented frames, that
975e6a9854bSJohannes Berg 			 * would completely throw off the NAV at other STAs.
976e6a9854bSJohannes Berg 			 */
977e6a9854bSJohannes Berg 			info->control.rates[1].idx = -1;
978e6a9854bSJohannes Berg 			info->control.rates[2].idx = -1;
979e6a9854bSJohannes Berg 			info->control.rates[3].idx = -1;
980e3e1a0bcSThomas Huehn 			BUILD_BUG_ON(IEEE80211_TX_MAX_RATES != 4);
981e6a9854bSJohannes Berg 			info->flags &= ~IEEE80211_TX_CTL_RATE_CTRL_PROBE;
9822de8e0d9SJohannes Berg 		} else {
9832de8e0d9SJohannes Berg 			hdr->frame_control &= ~morefrags;
984e6a9854bSJohannes Berg 		}
9852de8e0d9SJohannes Berg 		hdr->seq_ctrl |= cpu_to_le16(fragnum & IEEE80211_SCTL_FRAG);
9862de8e0d9SJohannes Berg 		fragnum++;
987252b86c4SJohannes Berg 	}
988e2454948SJohannes Berg 
989e2454948SJohannes Berg 	return TX_CONTINUE;
990e2454948SJohannes Berg }
991e2454948SJohannes Berg 
992d9e8a70fSJohannes Berg static ieee80211_tx_result debug_noinline
993feff1f2fSJohannes Berg ieee80211_tx_h_stats(struct ieee80211_tx_data *tx)
994feff1f2fSJohannes Berg {
995252b86c4SJohannes Berg 	struct sk_buff *skb;
996560d2682SJohannes Berg 	int ac = -1;
997feff1f2fSJohannes Berg 
998feff1f2fSJohannes Berg 	if (!tx->sta)
999feff1f2fSJohannes Berg 		return TX_CONTINUE;
1000feff1f2fSJohannes Berg 
1001252b86c4SJohannes Berg 	skb_queue_walk(&tx->skbs, skb) {
1002560d2682SJohannes Berg 		ac = skb_get_queue_mapping(skb);
1003e5a9f8d0SJohannes Berg 		tx->sta->tx_stats.bytes[ac] += skb->len;
1004252b86c4SJohannes Berg 	}
1005560d2682SJohannes Berg 	if (ac >= 0)
1006e5a9f8d0SJohannes Berg 		tx->sta->tx_stats.packets[ac]++;
1007feff1f2fSJohannes Berg 
1008feff1f2fSJohannes Berg 	return TX_CONTINUE;
1009feff1f2fSJohannes Berg }
1010feff1f2fSJohannes Berg 
1011feff1f2fSJohannes Berg static ieee80211_tx_result debug_noinline
1012e2454948SJohannes Berg ieee80211_tx_h_encrypt(struct ieee80211_tx_data *tx)
1013e2454948SJohannes Berg {
1014e2454948SJohannes Berg 	if (!tx->key)
1015e2454948SJohannes Berg 		return TX_CONTINUE;
1016e2454948SJohannes Berg 
101797359d12SJohannes Berg 	switch (tx->key->conf.cipher) {
101897359d12SJohannes Berg 	case WLAN_CIPHER_SUITE_WEP40:
101997359d12SJohannes Berg 	case WLAN_CIPHER_SUITE_WEP104:
1020e2454948SJohannes Berg 		return ieee80211_crypto_wep_encrypt(tx);
102197359d12SJohannes Berg 	case WLAN_CIPHER_SUITE_TKIP:
1022e2454948SJohannes Berg 		return ieee80211_crypto_tkip_encrypt(tx);
102397359d12SJohannes Berg 	case WLAN_CIPHER_SUITE_CCMP:
10242b2ba0dbSJouni Malinen 		return ieee80211_crypto_ccmp_encrypt(
10252b2ba0dbSJouni Malinen 			tx, IEEE80211_CCMP_MIC_LEN);
10262b2ba0dbSJouni Malinen 	case WLAN_CIPHER_SUITE_CCMP_256:
10272b2ba0dbSJouni Malinen 		return ieee80211_crypto_ccmp_encrypt(
10282b2ba0dbSJouni Malinen 			tx, IEEE80211_CCMP_256_MIC_LEN);
102997359d12SJohannes Berg 	case WLAN_CIPHER_SUITE_AES_CMAC:
10303cfcf6acSJouni Malinen 		return ieee80211_crypto_aes_cmac_encrypt(tx);
103156c52da2SJouni Malinen 	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
103256c52da2SJouni Malinen 		return ieee80211_crypto_aes_cmac_256_encrypt(tx);
10338ade538bSJouni Malinen 	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
10348ade538bSJouni Malinen 	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
10358ade538bSJouni Malinen 		return ieee80211_crypto_aes_gmac_encrypt(tx);
103600b9cfa3SJouni Malinen 	case WLAN_CIPHER_SUITE_GCMP:
103700b9cfa3SJouni Malinen 	case WLAN_CIPHER_SUITE_GCMP_256:
103800b9cfa3SJouni Malinen 		return ieee80211_crypto_gcmp_encrypt(tx);
10393ffc2a90SJohannes Berg 	default:
1040d32a1028SYoni Divinsky 		return ieee80211_crypto_hw_encrypt(tx);
1041e2454948SJohannes Berg 	}
1042e2454948SJohannes Berg 
1043e2454948SJohannes Berg 	return TX_DROP;
1044e2454948SJohannes Berg }
1045e2454948SJohannes Berg 
1046d9e8a70fSJohannes Berg static ieee80211_tx_result debug_noinline
104703f93c3dSJohannes Berg ieee80211_tx_h_calculate_duration(struct ieee80211_tx_data *tx)
104803f93c3dSJohannes Berg {
1049252b86c4SJohannes Berg 	struct sk_buff *skb;
10502de8e0d9SJohannes Berg 	struct ieee80211_hdr *hdr;
10512de8e0d9SJohannes Berg 	int next_len;
10522de8e0d9SJohannes Berg 	bool group_addr;
105303f93c3dSJohannes Berg 
1054252b86c4SJohannes Berg 	skb_queue_walk(&tx->skbs, skb) {
10552de8e0d9SJohannes Berg 		hdr = (void *) skb->data;
10567e0aae47SJouni Malinen 		if (unlikely(ieee80211_is_pspoll(hdr->frame_control)))
10577e0aae47SJouni Malinen 			break; /* must not overwrite AID */
1058252b86c4SJohannes Berg 		if (!skb_queue_is_last(&tx->skbs, skb)) {
1059252b86c4SJohannes Berg 			struct sk_buff *next = skb_queue_next(&tx->skbs, skb);
1060252b86c4SJohannes Berg 			next_len = next->len;
1061252b86c4SJohannes Berg 		} else
1062252b86c4SJohannes Berg 			next_len = 0;
10632de8e0d9SJohannes Berg 		group_addr = is_multicast_ether_addr(hdr->addr1);
106403f93c3dSJohannes Berg 
10652de8e0d9SJohannes Berg 		hdr->duration_id =
1066252b86c4SJohannes Berg 			ieee80211_duration(tx, skb, group_addr, next_len);
1067252b86c4SJohannes Berg 	}
106803f93c3dSJohannes Berg 
106903f93c3dSJohannes Berg 	return TX_CONTINUE;
107003f93c3dSJohannes Berg }
107103f93c3dSJohannes Berg 
1072e2ebc74dSJohannes Berg /* actual transmit path */
1073e2ebc74dSJohannes Berg 
1074a622ab72SJohannes Berg static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx,
1075a622ab72SJohannes Berg 				  struct sk_buff *skb,
1076a622ab72SJohannes Berg 				  struct ieee80211_tx_info *info,
1077a622ab72SJohannes Berg 				  struct tid_ampdu_tx *tid_tx,
1078a622ab72SJohannes Berg 				  int tid)
1079a622ab72SJohannes Berg {
1080a622ab72SJohannes Berg 	bool queued = false;
1081285fa695SNikolay Martynov 	bool reset_agg_timer = false;
1082aa454580SHelmut Schaa 	struct sk_buff *purge_skb = NULL;
1083a622ab72SJohannes Berg 
1084a622ab72SJohannes Berg 	if (test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) {
1085a622ab72SJohannes Berg 		info->flags |= IEEE80211_TX_CTL_AMPDU;
1086285fa695SNikolay Martynov 		reset_agg_timer = true;
10870ab33703SJohannes Berg 	} else if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state)) {
10880ab33703SJohannes Berg 		/*
10890ab33703SJohannes Berg 		 * nothing -- this aggregation session is being started
10900ab33703SJohannes Berg 		 * but that might still fail with the driver
10910ab33703SJohannes Berg 		 */
1092ba8c3d6fSFelix Fietkau 	} else if (!tx->sta->sta.txq[tid]) {
1093a622ab72SJohannes Berg 		spin_lock(&tx->sta->lock);
1094a622ab72SJohannes Berg 		/*
1095a622ab72SJohannes Berg 		 * Need to re-check now, because we may get here
1096a622ab72SJohannes Berg 		 *
1097a622ab72SJohannes Berg 		 *  1) in the window during which the setup is actually
1098a622ab72SJohannes Berg 		 *     already done, but not marked yet because not all
1099a622ab72SJohannes Berg 		 *     packets are spliced over to the driver pending
1100a622ab72SJohannes Berg 		 *     queue yet -- if this happened we acquire the lock
1101a622ab72SJohannes Berg 		 *     either before or after the splice happens, but
1102a622ab72SJohannes Berg 		 *     need to recheck which of these cases happened.
1103a622ab72SJohannes Berg 		 *
1104a622ab72SJohannes Berg 		 *  2) during session teardown, if the OPERATIONAL bit
1105a622ab72SJohannes Berg 		 *     was cleared due to the teardown but the pointer
1106a622ab72SJohannes Berg 		 *     hasn't been assigned NULL yet (or we loaded it
1107a622ab72SJohannes Berg 		 *     before it was assigned) -- in this case it may
1108a622ab72SJohannes Berg 		 *     now be NULL which means we should just let the
1109a622ab72SJohannes Berg 		 *     packet pass through because splicing the frames
1110a622ab72SJohannes Berg 		 *     back is already done.
1111a622ab72SJohannes Berg 		 */
111240b275b6SJohannes Berg 		tid_tx = rcu_dereference_protected_tid_tx(tx->sta, tid);
1113a622ab72SJohannes Berg 
1114a622ab72SJohannes Berg 		if (!tid_tx) {
1115a622ab72SJohannes Berg 			/* do nothing, let packet pass through */
1116a622ab72SJohannes Berg 		} else if (test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) {
1117a622ab72SJohannes Berg 			info->flags |= IEEE80211_TX_CTL_AMPDU;
1118285fa695SNikolay Martynov 			reset_agg_timer = true;
1119a622ab72SJohannes Berg 		} else {
1120a622ab72SJohannes Berg 			queued = true;
1121f6d4671aSEmmanuel Grumbach 			if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER) {
1122f6d4671aSEmmanuel Grumbach 				clear_sta_flag(tx->sta, WLAN_STA_SP);
1123f6d4671aSEmmanuel Grumbach 				ps_dbg(tx->sta->sdata,
1124f6d4671aSEmmanuel Grumbach 				       "STA %pM aid %d: SP frame queued, close the SP w/o telling the peer\n",
1125f6d4671aSEmmanuel Grumbach 				       tx->sta->sta.addr, tx->sta->sta.aid);
1126f6d4671aSEmmanuel Grumbach 			}
1127a622ab72SJohannes Berg 			info->control.vif = &tx->sdata->vif;
1128a622ab72SJohannes Berg 			info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
1129facde7f3SEmmanuel Grumbach 			info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS;
1130a622ab72SJohannes Berg 			__skb_queue_tail(&tid_tx->pending, skb);
1131aa454580SHelmut Schaa 			if (skb_queue_len(&tid_tx->pending) > STA_MAX_TX_BUFFER)
1132aa454580SHelmut Schaa 				purge_skb = __skb_dequeue(&tid_tx->pending);
1133a622ab72SJohannes Berg 		}
1134a622ab72SJohannes Berg 		spin_unlock(&tx->sta->lock);
1135aa454580SHelmut Schaa 
1136aa454580SHelmut Schaa 		if (purge_skb)
1137c3e7724bSFelix Fietkau 			ieee80211_free_txskb(&tx->local->hw, purge_skb);
1138a622ab72SJohannes Berg 	}
1139a622ab72SJohannes Berg 
1140285fa695SNikolay Martynov 	/* reset session timer */
1141914eac24SSara Sharon 	if (reset_agg_timer)
114212d3952fSFelix Fietkau 		tid_tx->last_tx = jiffies;
1143285fa695SNikolay Martynov 
1144a622ab72SJohannes Berg 	return queued;
1145a622ab72SJohannes Berg }
1146a622ab72SJohannes Berg 
114758d4185eSJohannes Berg /*
114858d4185eSJohannes Berg  * initialises @tx
11497c10770fSJohannes Berg  * pass %NULL for the station if unknown, a valid pointer if known
11507c10770fSJohannes Berg  * or an ERR_PTR() if the station is known not to exist
115158d4185eSJohannes Berg  */
11529ae54c84SJohannes Berg static ieee80211_tx_result
11533b8d81e0SJohannes Berg ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
11543b8d81e0SJohannes Berg 		     struct ieee80211_tx_data *tx,
11557c10770fSJohannes Berg 		     struct sta_info *sta, struct sk_buff *skb)
1156e2ebc74dSJohannes Berg {
11573b8d81e0SJohannes Berg 	struct ieee80211_local *local = sdata->local;
115858d4185eSJohannes Berg 	struct ieee80211_hdr *hdr;
1159e039fa4aSJohannes Berg 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
116068f2b517SJohannes Berg 	int tid;
1161e2ebc74dSJohannes Berg 
1162e2ebc74dSJohannes Berg 	memset(tx, 0, sizeof(*tx));
1163e2ebc74dSJohannes Berg 	tx->skb = skb;
1164e2ebc74dSJohannes Berg 	tx->local = local;
11653b8d81e0SJohannes Berg 	tx->sdata = sdata;
1166252b86c4SJohannes Berg 	__skb_queue_head_init(&tx->skbs);
1167e2ebc74dSJohannes Berg 
1168cd8ffc80SJohannes Berg 	/*
1169cd8ffc80SJohannes Berg 	 * If this flag is set to true anywhere, and we get here,
1170cd8ffc80SJohannes Berg 	 * we are doing the needed processing, so remove the flag
1171cd8ffc80SJohannes Berg 	 * now.
1172cd8ffc80SJohannes Berg 	 */
1173cd8ffc80SJohannes Berg 	info->flags &= ~IEEE80211_TX_INTFL_NEED_TXPROCESSING;
1174cd8ffc80SJohannes Berg 
117558d4185eSJohannes Berg 	hdr = (struct ieee80211_hdr *) skb->data;
117658d4185eSJohannes Berg 
11777c10770fSJohannes Berg 	if (likely(sta)) {
11787c10770fSJohannes Berg 		if (!IS_ERR(sta))
11797c10770fSJohannes Berg 			tx->sta = sta;
11807c10770fSJohannes Berg 	} else {
11813f0e0b22SFelix Fietkau 		if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
1182f14543eeSFelix Fietkau 			tx->sta = rcu_dereference(sdata->u.vlan.sta);
11837c10770fSJohannes Berg 			if (!tx->sta && sdata->wdev.use_4addr)
11843f0e0b22SFelix Fietkau 				return TX_DROP;
11857c10770fSJohannes Berg 		} else if (info->flags & (IEEE80211_TX_INTFL_NL80211_FRAME_TX |
11867c10770fSJohannes Berg 					  IEEE80211_TX_CTL_INJECTED) ||
118766f2c99aSFelix Fietkau 			   tx->sdata->control_port_protocol == tx->skb->protocol) {
1188b4d57adbSFelix Fietkau 			tx->sta = sta_info_get_bss(sdata, hdr->addr1);
11893f0e0b22SFelix Fietkau 		}
11909d6b106bSJohannes Berg 		if (!tx->sta && !is_multicast_ether_addr(hdr->addr1))
1191abe60632SJohannes Berg 			tx->sta = sta_info_get(sdata, hdr->addr1);
11927c10770fSJohannes Berg 	}
119358d4185eSJohannes Berg 
1194cd8ffc80SJohannes Berg 	if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) &&
119549a59543SJohannes Berg 	    !ieee80211_is_qos_nullfunc(hdr->frame_control) &&
119630686bf7SJohannes Berg 	    ieee80211_hw_check(&local->hw, AMPDU_AGGREGATION) &&
119730686bf7SJohannes Berg 	    !ieee80211_hw_check(&local->hw, TX_AMPDU_SETUP_IN_HW)) {
1198cd8ffc80SJohannes Berg 		struct tid_ampdu_tx *tid_tx;
1199cd8ffc80SJohannes Berg 
1200a1f2ba04SSara Sharon 		tid = ieee80211_get_tid(hdr);
12018b30b1feSSujith 
1202a622ab72SJohannes Berg 		tid_tx = rcu_dereference(tx->sta->ampdu_mlme.tid_tx[tid]);
1203a622ab72SJohannes Berg 		if (tid_tx) {
1204a622ab72SJohannes Berg 			bool queued;
1205a622ab72SJohannes Berg 
1206a622ab72SJohannes Berg 			queued = ieee80211_tx_prep_agg(tx, skb, info,
1207a622ab72SJohannes Berg 						       tid_tx, tid);
1208cd8ffc80SJohannes Berg 
1209cd8ffc80SJohannes Berg 			if (unlikely(queued))
1210cd8ffc80SJohannes Berg 				return TX_QUEUED;
12118b30b1feSSujith 		}
1212a622ab72SJohannes Berg 	}
12138b30b1feSSujith 
1214badffb72SJiri Slaby 	if (is_multicast_ether_addr(hdr->addr1)) {
12155cf121c3SJohannes Berg 		tx->flags &= ~IEEE80211_TX_UNICAST;
1216e039fa4aSJohannes Berg 		info->flags |= IEEE80211_TX_CTL_NO_ACK;
12176fd67e93SSimon Wunderlich 	} else
12185cf121c3SJohannes Berg 		tx->flags |= IEEE80211_TX_UNICAST;
121958d4185eSJohannes Berg 
1220a26eb27aSJohannes Berg 	if (!(info->flags & IEEE80211_TX_CTL_DONTFRAG)) {
1221a26eb27aSJohannes Berg 		if (!(tx->flags & IEEE80211_TX_UNICAST) ||
1222a26eb27aSJohannes Berg 		    skb->len + FCS_LEN <= local->hw.wiphy->frag_threshold ||
1223a26eb27aSJohannes Berg 		    info->flags & IEEE80211_TX_CTL_AMPDU)
1224a26eb27aSJohannes Berg 			info->flags |= IEEE80211_TX_CTL_DONTFRAG;
122558d4185eSJohannes Berg 	}
122658d4185eSJohannes Berg 
1227e2ebc74dSJohannes Berg 	if (!tx->sta)
1228e039fa4aSJohannes Berg 		info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
1229f7418bc1SFelix Fietkau 	else if (test_and_clear_sta_flag(tx->sta, WLAN_STA_CLEAR_PS_FILT)) {
1230e039fa4aSJohannes Berg 		info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
1231f7418bc1SFelix Fietkau 		ieee80211_check_fast_xmit(tx->sta);
1232f7418bc1SFelix Fietkau 	}
123358d4185eSJohannes Berg 
1234e039fa4aSJohannes Berg 	info->flags |= IEEE80211_TX_CTL_FIRST_FRAGMENT;
1235e2ebc74dSJohannes Berg 
12369ae54c84SJohannes Berg 	return TX_CONTINUE;
1237e2ebc74dSJohannes Berg }
1238e2ebc74dSJohannes Berg 
123980a83cfcSMichal Kazior static struct txq_info *ieee80211_get_txq(struct ieee80211_local *local,
1240ba8c3d6fSFelix Fietkau 					  struct ieee80211_vif *vif,
1241dbef5362SMichal Kazior 					  struct sta_info *sta,
1242ba8c3d6fSFelix Fietkau 					  struct sk_buff *skb)
1243ba8c3d6fSFelix Fietkau {
1244ba8c3d6fSFelix Fietkau 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1245ba8c3d6fSFelix Fietkau 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1246ba8c3d6fSFelix Fietkau 	struct ieee80211_txq *txq = NULL;
1247ba8c3d6fSFelix Fietkau 
1248c3732a7bSFelix Fietkau 	if ((info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) ||
1249c3732a7bSFelix Fietkau 	    (info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE))
125080a83cfcSMichal Kazior 		return NULL;
1251ba8c3d6fSFelix Fietkau 
1252adf8ed01SJohannes Berg 	if (unlikely(!ieee80211_is_data_present(hdr->frame_control))) {
1253adf8ed01SJohannes Berg 		if ((!ieee80211_is_mgmt(hdr->frame_control) ||
12540eeb2b67SSara Sharon 		     ieee80211_is_bufferable_mmpdu(hdr->frame_control) ||
12550eeb2b67SSara Sharon 		     vif->type == NL80211_IFTYPE_STATION) &&
1256adf8ed01SJohannes Berg 		    sta && sta->uploaded) {
1257adf8ed01SJohannes Berg 			/*
1258adf8ed01SJohannes Berg 			 * This will be NULL if the driver didn't set the
1259adf8ed01SJohannes Berg 			 * opt-in hardware flag.
1260adf8ed01SJohannes Berg 			 */
1261adf8ed01SJohannes Berg 			txq = sta->sta.txq[IEEE80211_NUM_TIDS];
1262adf8ed01SJohannes Berg 		}
1263adf8ed01SJohannes Berg 	} else if (sta) {
1264ba8c3d6fSFelix Fietkau 		u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
1265ba8c3d6fSFelix Fietkau 
1266dbef5362SMichal Kazior 		if (!sta->uploaded)
1267dbef5362SMichal Kazior 			return NULL;
1268dbef5362SMichal Kazior 
1269dbef5362SMichal Kazior 		txq = sta->sta.txq[tid];
1270ba8c3d6fSFelix Fietkau 	} else if (vif) {
1271ba8c3d6fSFelix Fietkau 		txq = vif->txq;
1272ba8c3d6fSFelix Fietkau 	}
1273ba8c3d6fSFelix Fietkau 
1274ba8c3d6fSFelix Fietkau 	if (!txq)
127580a83cfcSMichal Kazior 		return NULL;
1276ba8c3d6fSFelix Fietkau 
127780a83cfcSMichal Kazior 	return to_txq_info(txq);
127880a83cfcSMichal Kazior }
1279ba8c3d6fSFelix Fietkau 
12805caa328eSMichal Kazior static void ieee80211_set_skb_enqueue_time(struct sk_buff *skb)
12815caa328eSMichal Kazior {
12825caa328eSMichal Kazior 	IEEE80211_SKB_CB(skb)->control.enqueue_time = codel_get_time();
12835caa328eSMichal Kazior }
12845caa328eSMichal Kazior 
12855caa328eSMichal Kazior static u32 codel_skb_len_func(const struct sk_buff *skb)
12865caa328eSMichal Kazior {
12875caa328eSMichal Kazior 	return skb->len;
12885caa328eSMichal Kazior }
12895caa328eSMichal Kazior 
12905caa328eSMichal Kazior static codel_time_t codel_skb_time_func(const struct sk_buff *skb)
12915caa328eSMichal Kazior {
12925caa328eSMichal Kazior 	const struct ieee80211_tx_info *info;
12935caa328eSMichal Kazior 
12945caa328eSMichal Kazior 	info = (const struct ieee80211_tx_info *)skb->cb;
12955caa328eSMichal Kazior 	return info->control.enqueue_time;
12965caa328eSMichal Kazior }
12975caa328eSMichal Kazior 
12985caa328eSMichal Kazior static struct sk_buff *codel_dequeue_func(struct codel_vars *cvars,
12995caa328eSMichal Kazior 					  void *ctx)
13005caa328eSMichal Kazior {
13015caa328eSMichal Kazior 	struct ieee80211_local *local;
13025caa328eSMichal Kazior 	struct txq_info *txqi;
13035caa328eSMichal Kazior 	struct fq *fq;
13045caa328eSMichal Kazior 	struct fq_flow *flow;
13055caa328eSMichal Kazior 
13065caa328eSMichal Kazior 	txqi = ctx;
13075caa328eSMichal Kazior 	local = vif_to_sdata(txqi->txq.vif)->local;
13085caa328eSMichal Kazior 	fq = &local->fq;
13095caa328eSMichal Kazior 
13105caa328eSMichal Kazior 	if (cvars == &txqi->def_cvars)
13115caa328eSMichal Kazior 		flow = &txqi->def_flow;
13125caa328eSMichal Kazior 	else
13135caa328eSMichal Kazior 		flow = &fq->flows[cvars - local->cvars];
13145caa328eSMichal Kazior 
13155caa328eSMichal Kazior 	return fq_flow_dequeue(fq, flow);
13165caa328eSMichal Kazior }
13175caa328eSMichal Kazior 
13185caa328eSMichal Kazior static void codel_drop_func(struct sk_buff *skb,
13195caa328eSMichal Kazior 			    void *ctx)
13205caa328eSMichal Kazior {
13215caa328eSMichal Kazior 	struct ieee80211_local *local;
13225caa328eSMichal Kazior 	struct ieee80211_hw *hw;
13235caa328eSMichal Kazior 	struct txq_info *txqi;
13245caa328eSMichal Kazior 
13255caa328eSMichal Kazior 	txqi = ctx;
13265caa328eSMichal Kazior 	local = vif_to_sdata(txqi->txq.vif)->local;
13275caa328eSMichal Kazior 	hw = &local->hw;
13285caa328eSMichal Kazior 
13295caa328eSMichal Kazior 	ieee80211_free_txskb(hw, skb);
13305caa328eSMichal Kazior }
13315caa328eSMichal Kazior 
1332fa962b92SMichal Kazior static struct sk_buff *fq_tin_dequeue_func(struct fq *fq,
1333fa962b92SMichal Kazior 					   struct fq_tin *tin,
1334fa962b92SMichal Kazior 					   struct fq_flow *flow)
1335fa962b92SMichal Kazior {
13365caa328eSMichal Kazior 	struct ieee80211_local *local;
13375caa328eSMichal Kazior 	struct txq_info *txqi;
13385caa328eSMichal Kazior 	struct codel_vars *cvars;
13395caa328eSMichal Kazior 	struct codel_params *cparams;
13405caa328eSMichal Kazior 	struct codel_stats *cstats;
13415caa328eSMichal Kazior 
13425caa328eSMichal Kazior 	local = container_of(fq, struct ieee80211_local, fq);
13435caa328eSMichal Kazior 	txqi = container_of(tin, struct txq_info, tin);
13448d51dbb8SToke Høiland-Jørgensen 	cstats = &txqi->cstats;
13455caa328eSMichal Kazior 
1346484a54c2SToke Høiland-Jørgensen 	if (txqi->txq.sta) {
1347484a54c2SToke Høiland-Jørgensen 		struct sta_info *sta = container_of(txqi->txq.sta,
1348484a54c2SToke Høiland-Jørgensen 						    struct sta_info, sta);
1349484a54c2SToke Høiland-Jørgensen 		cparams = &sta->cparams;
1350484a54c2SToke Høiland-Jørgensen 	} else {
1351484a54c2SToke Høiland-Jørgensen 		cparams = &local->cparams;
1352484a54c2SToke Høiland-Jørgensen 	}
1353484a54c2SToke Høiland-Jørgensen 
13545caa328eSMichal Kazior 	if (flow == &txqi->def_flow)
13555caa328eSMichal Kazior 		cvars = &txqi->def_cvars;
13565caa328eSMichal Kazior 	else
13575caa328eSMichal Kazior 		cvars = &local->cvars[flow - fq->flows];
13585caa328eSMichal Kazior 
13595caa328eSMichal Kazior 	return codel_dequeue(txqi,
13605caa328eSMichal Kazior 			     &flow->backlog,
13615caa328eSMichal Kazior 			     cparams,
13625caa328eSMichal Kazior 			     cvars,
13635caa328eSMichal Kazior 			     cstats,
13645caa328eSMichal Kazior 			     codel_skb_len_func,
13655caa328eSMichal Kazior 			     codel_skb_time_func,
13665caa328eSMichal Kazior 			     codel_drop_func,
13675caa328eSMichal Kazior 			     codel_dequeue_func);
1368fa962b92SMichal Kazior }
1369fa962b92SMichal Kazior 
1370fa962b92SMichal Kazior static void fq_skb_free_func(struct fq *fq,
1371fa962b92SMichal Kazior 			     struct fq_tin *tin,
1372fa962b92SMichal Kazior 			     struct fq_flow *flow,
1373fa962b92SMichal Kazior 			     struct sk_buff *skb)
1374fa962b92SMichal Kazior {
1375fa962b92SMichal Kazior 	struct ieee80211_local *local;
1376fa962b92SMichal Kazior 
1377fa962b92SMichal Kazior 	local = container_of(fq, struct ieee80211_local, fq);
1378fa962b92SMichal Kazior 	ieee80211_free_txskb(&local->hw, skb);
1379fa962b92SMichal Kazior }
1380fa962b92SMichal Kazior 
1381fa962b92SMichal Kazior static struct fq_flow *fq_flow_get_default_func(struct fq *fq,
1382fa962b92SMichal Kazior 						struct fq_tin *tin,
1383fa962b92SMichal Kazior 						int idx,
1384fa962b92SMichal Kazior 						struct sk_buff *skb)
1385fa962b92SMichal Kazior {
1386fa962b92SMichal Kazior 	struct txq_info *txqi;
1387fa962b92SMichal Kazior 
1388fa962b92SMichal Kazior 	txqi = container_of(tin, struct txq_info, tin);
1389fa962b92SMichal Kazior 	return &txqi->def_flow;
1390fa962b92SMichal Kazior }
1391fa962b92SMichal Kazior 
139280a83cfcSMichal Kazior static void ieee80211_txq_enqueue(struct ieee80211_local *local,
139380a83cfcSMichal Kazior 				  struct txq_info *txqi,
139480a83cfcSMichal Kazior 				  struct sk_buff *skb)
139580a83cfcSMichal Kazior {
1396fa962b92SMichal Kazior 	struct fq *fq = &local->fq;
1397fa962b92SMichal Kazior 	struct fq_tin *tin = &txqi->tin;
1398f2af2df8SFelix Fietkau 	u32 flow_idx = fq_flow_idx(fq, skb);
139980a83cfcSMichal Kazior 
14005caa328eSMichal Kazior 	ieee80211_set_skb_enqueue_time(skb);
1401f2af2df8SFelix Fietkau 
1402f2af2df8SFelix Fietkau 	spin_lock_bh(&fq->lock);
1403f2af2df8SFelix Fietkau 	fq_tin_enqueue(fq, tin, flow_idx, skb,
1404fa962b92SMichal Kazior 		       fq_skb_free_func,
1405fa962b92SMichal Kazior 		       fq_flow_get_default_func);
1406f2af2df8SFelix Fietkau 	spin_unlock_bh(&fq->lock);
140780a83cfcSMichal Kazior }
140880a83cfcSMichal Kazior 
14092a9e2579SJohannes Berg static bool fq_vlan_filter_func(struct fq *fq, struct fq_tin *tin,
14102a9e2579SJohannes Berg 				struct fq_flow *flow, struct sk_buff *skb,
14112a9e2579SJohannes Berg 				void *data)
14122a9e2579SJohannes Berg {
14132a9e2579SJohannes Berg 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
14142a9e2579SJohannes Berg 
14152a9e2579SJohannes Berg 	return info->control.vif == data;
14162a9e2579SJohannes Berg }
14172a9e2579SJohannes Berg 
14182a9e2579SJohannes Berg void ieee80211_txq_remove_vlan(struct ieee80211_local *local,
14192a9e2579SJohannes Berg 			       struct ieee80211_sub_if_data *sdata)
14202a9e2579SJohannes Berg {
14212a9e2579SJohannes Berg 	struct fq *fq = &local->fq;
14222a9e2579SJohannes Berg 	struct txq_info *txqi;
14232a9e2579SJohannes Berg 	struct fq_tin *tin;
14242a9e2579SJohannes Berg 	struct ieee80211_sub_if_data *ap;
14252a9e2579SJohannes Berg 
14262a9e2579SJohannes Berg 	if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP_VLAN))
14272a9e2579SJohannes Berg 		return;
14282a9e2579SJohannes Berg 
14292a9e2579SJohannes Berg 	ap = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap);
14302a9e2579SJohannes Berg 
14312a9e2579SJohannes Berg 	if (!ap->vif.txq)
14322a9e2579SJohannes Berg 		return;
14332a9e2579SJohannes Berg 
14342a9e2579SJohannes Berg 	txqi = to_txq_info(ap->vif.txq);
14352a9e2579SJohannes Berg 	tin = &txqi->tin;
14362a9e2579SJohannes Berg 
14372a9e2579SJohannes Berg 	spin_lock_bh(&fq->lock);
14382a9e2579SJohannes Berg 	fq_tin_filter(fq, tin, fq_vlan_filter_func, &sdata->vif,
14392a9e2579SJohannes Berg 		      fq_skb_free_func);
14402a9e2579SJohannes Berg 	spin_unlock_bh(&fq->lock);
14412a9e2579SJohannes Berg }
14422a9e2579SJohannes Berg 
1443fa962b92SMichal Kazior void ieee80211_txq_init(struct ieee80211_sub_if_data *sdata,
1444fa962b92SMichal Kazior 			struct sta_info *sta,
1445fa962b92SMichal Kazior 			struct txq_info *txqi, int tid)
1446fa962b92SMichal Kazior {
1447fa962b92SMichal Kazior 	fq_tin_init(&txqi->tin);
1448fa962b92SMichal Kazior 	fq_flow_init(&txqi->def_flow);
14495caa328eSMichal Kazior 	codel_vars_init(&txqi->def_cvars);
14508d51dbb8SToke Høiland-Jørgensen 	codel_stats_init(&txqi->cstats);
1451bb42f2d1SToke Høiland-Jørgensen 	__skb_queue_head_init(&txqi->frags);
145218667600SToke Høiland-Jørgensen 	INIT_LIST_HEAD(&txqi->schedule_order);
1453fa962b92SMichal Kazior 
1454fa962b92SMichal Kazior 	txqi->txq.vif = &sdata->vif;
1455fa962b92SMichal Kazior 
1456adf8ed01SJohannes Berg 	if (!sta) {
1457fa962b92SMichal Kazior 		sdata->vif.txq = &txqi->txq;
1458fa962b92SMichal Kazior 		txqi->txq.tid = 0;
1459fa962b92SMichal Kazior 		txqi->txq.ac = IEEE80211_AC_BE;
1460adf8ed01SJohannes Berg 
1461adf8ed01SJohannes Berg 		return;
1462fa962b92SMichal Kazior 	}
1463adf8ed01SJohannes Berg 
1464adf8ed01SJohannes Berg 	if (tid == IEEE80211_NUM_TIDS) {
14650eeb2b67SSara Sharon 		if (sdata->vif.type == NL80211_IFTYPE_STATION) {
14660eeb2b67SSara Sharon 			/* Drivers need to opt in to the management MPDU TXQ */
14670eeb2b67SSara Sharon 			if (!ieee80211_hw_check(&sdata->local->hw,
14680eeb2b67SSara Sharon 						STA_MMPDU_TXQ))
1469adf8ed01SJohannes Berg 				return;
14700eeb2b67SSara Sharon 		} else if (!ieee80211_hw_check(&sdata->local->hw,
14710eeb2b67SSara Sharon 					       BUFF_MMPDU_TXQ)) {
14720eeb2b67SSara Sharon 			/* Drivers need to opt in to the bufferable MMPDU TXQ */
14730eeb2b67SSara Sharon 			return;
14740eeb2b67SSara Sharon 		}
1475adf8ed01SJohannes Berg 		txqi->txq.ac = IEEE80211_AC_VO;
1476adf8ed01SJohannes Berg 	} else {
1477adf8ed01SJohannes Berg 		txqi->txq.ac = ieee80211_ac_from_tid(tid);
1478adf8ed01SJohannes Berg 	}
1479adf8ed01SJohannes Berg 
1480adf8ed01SJohannes Berg 	txqi->txq.sta = &sta->sta;
1481adf8ed01SJohannes Berg 	txqi->txq.tid = tid;
1482adf8ed01SJohannes Berg 	sta->sta.txq[tid] = &txqi->txq;
1483fa962b92SMichal Kazior }
1484fa962b92SMichal Kazior 
1485fa962b92SMichal Kazior void ieee80211_txq_purge(struct ieee80211_local *local,
1486fa962b92SMichal Kazior 			 struct txq_info *txqi)
1487fa962b92SMichal Kazior {
1488fa962b92SMichal Kazior 	struct fq *fq = &local->fq;
1489fa962b92SMichal Kazior 	struct fq_tin *tin = &txqi->tin;
1490fa962b92SMichal Kazior 
1491b4809e94SToke Høiland-Jørgensen 	spin_lock_bh(&fq->lock);
1492fa962b92SMichal Kazior 	fq_tin_reset(fq, tin, fq_skb_free_func);
1493bb42f2d1SToke Høiland-Jørgensen 	ieee80211_purge_tx_queue(&local->hw, &txqi->frags);
1494b4809e94SToke Høiland-Jørgensen 	spin_unlock_bh(&fq->lock);
1495b4809e94SToke Høiland-Jørgensen 
149618667600SToke Høiland-Jørgensen 	spin_lock_bh(&local->active_txq_lock[txqi->txq.ac]);
149718667600SToke Høiland-Jørgensen 	list_del_init(&txqi->schedule_order);
149818667600SToke Høiland-Jørgensen 	spin_unlock_bh(&local->active_txq_lock[txqi->txq.ac]);
1499fa962b92SMichal Kazior }
1500fa962b92SMichal Kazior 
15012fe4a29aSToke Høiland-Jørgensen void ieee80211_txq_set_params(struct ieee80211_local *local)
15022fe4a29aSToke Høiland-Jørgensen {
15032fe4a29aSToke Høiland-Jørgensen 	if (local->hw.wiphy->txq_limit)
15042fe4a29aSToke Høiland-Jørgensen 		local->fq.limit = local->hw.wiphy->txq_limit;
15052fe4a29aSToke Høiland-Jørgensen 	else
15062fe4a29aSToke Høiland-Jørgensen 		local->hw.wiphy->txq_limit = local->fq.limit;
15072fe4a29aSToke Høiland-Jørgensen 
15082fe4a29aSToke Høiland-Jørgensen 	if (local->hw.wiphy->txq_memory_limit)
15092fe4a29aSToke Høiland-Jørgensen 		local->fq.memory_limit = local->hw.wiphy->txq_memory_limit;
15102fe4a29aSToke Høiland-Jørgensen 	else
15112fe4a29aSToke Høiland-Jørgensen 		local->hw.wiphy->txq_memory_limit = local->fq.memory_limit;
15122fe4a29aSToke Høiland-Jørgensen 
15132fe4a29aSToke Høiland-Jørgensen 	if (local->hw.wiphy->txq_quantum)
15142fe4a29aSToke Høiland-Jørgensen 		local->fq.quantum = local->hw.wiphy->txq_quantum;
15152fe4a29aSToke Høiland-Jørgensen 	else
15162fe4a29aSToke Høiland-Jørgensen 		local->hw.wiphy->txq_quantum = local->fq.quantum;
15172fe4a29aSToke Høiland-Jørgensen }
15182fe4a29aSToke Høiland-Jørgensen 
1519fa962b92SMichal Kazior int ieee80211_txq_setup_flows(struct ieee80211_local *local)
1520fa962b92SMichal Kazior {
1521fa962b92SMichal Kazior 	struct fq *fq = &local->fq;
1522fa962b92SMichal Kazior 	int ret;
15235caa328eSMichal Kazior 	int i;
15243ff23cd5SToke Høiland-Jørgensen 	bool supp_vht = false;
15253ff23cd5SToke Høiland-Jørgensen 	enum nl80211_band band;
1526fa962b92SMichal Kazior 
1527fa962b92SMichal Kazior 	if (!local->ops->wake_tx_queue)
1528fa962b92SMichal Kazior 		return 0;
1529fa962b92SMichal Kazior 
1530fa962b92SMichal Kazior 	ret = fq_init(fq, 4096);
1531fa962b92SMichal Kazior 	if (ret)
1532fa962b92SMichal Kazior 		return ret;
1533fa962b92SMichal Kazior 
15343ff23cd5SToke Høiland-Jørgensen 	/*
15353ff23cd5SToke Høiland-Jørgensen 	 * If the hardware doesn't support VHT, it is safe to limit the maximum
15363ff23cd5SToke Høiland-Jørgensen 	 * queue size. 4 Mbytes is 64 max-size aggregates in 802.11n.
15373ff23cd5SToke Høiland-Jørgensen 	 */
15383ff23cd5SToke Høiland-Jørgensen 	for (band = 0; band < NUM_NL80211_BANDS; band++) {
15393ff23cd5SToke Høiland-Jørgensen 		struct ieee80211_supported_band *sband;
15403ff23cd5SToke Høiland-Jørgensen 
15413ff23cd5SToke Høiland-Jørgensen 		sband = local->hw.wiphy->bands[band];
15423ff23cd5SToke Høiland-Jørgensen 		if (!sband)
15433ff23cd5SToke Høiland-Jørgensen 			continue;
15443ff23cd5SToke Høiland-Jørgensen 
15453ff23cd5SToke Høiland-Jørgensen 		supp_vht = supp_vht || sband->vht_cap.vht_supported;
15463ff23cd5SToke Høiland-Jørgensen 	}
15473ff23cd5SToke Høiland-Jørgensen 
15483ff23cd5SToke Høiland-Jørgensen 	if (!supp_vht)
15493ff23cd5SToke Høiland-Jørgensen 		fq->memory_limit = 4 << 20; /* 4 Mbytes */
15503ff23cd5SToke Høiland-Jørgensen 
15515caa328eSMichal Kazior 	codel_params_init(&local->cparams);
15525caa328eSMichal Kazior 	local->cparams.interval = MS2TIME(100);
15535caa328eSMichal Kazior 	local->cparams.target = MS2TIME(20);
15545caa328eSMichal Kazior 	local->cparams.ecn = true;
15555caa328eSMichal Kazior 
15565caa328eSMichal Kazior 	local->cvars = kcalloc(fq->flows_cnt, sizeof(local->cvars[0]),
15575caa328eSMichal Kazior 			       GFP_KERNEL);
15585caa328eSMichal Kazior 	if (!local->cvars) {
155959a7c828SMichal Kazior 		spin_lock_bh(&fq->lock);
15605caa328eSMichal Kazior 		fq_reset(fq, fq_skb_free_func);
156159a7c828SMichal Kazior 		spin_unlock_bh(&fq->lock);
15625caa328eSMichal Kazior 		return -ENOMEM;
15635caa328eSMichal Kazior 	}
15645caa328eSMichal Kazior 
15655caa328eSMichal Kazior 	for (i = 0; i < fq->flows_cnt; i++)
15665caa328eSMichal Kazior 		codel_vars_init(&local->cvars[i]);
15675caa328eSMichal Kazior 
15682fe4a29aSToke Høiland-Jørgensen 	ieee80211_txq_set_params(local);
15692fe4a29aSToke Høiland-Jørgensen 
1570fa962b92SMichal Kazior 	return 0;
1571fa962b92SMichal Kazior }
1572fa962b92SMichal Kazior 
1573fa962b92SMichal Kazior void ieee80211_txq_teardown_flows(struct ieee80211_local *local)
1574fa962b92SMichal Kazior {
1575fa962b92SMichal Kazior 	struct fq *fq = &local->fq;
1576fa962b92SMichal Kazior 
1577fa962b92SMichal Kazior 	if (!local->ops->wake_tx_queue)
1578fa962b92SMichal Kazior 		return;
1579fa962b92SMichal Kazior 
15805caa328eSMichal Kazior 	kfree(local->cvars);
15815caa328eSMichal Kazior 	local->cvars = NULL;
15825caa328eSMichal Kazior 
158359a7c828SMichal Kazior 	spin_lock_bh(&fq->lock);
1584fa962b92SMichal Kazior 	fq_reset(fq, fq_skb_free_func);
158559a7c828SMichal Kazior 	spin_unlock_bh(&fq->lock);
1586ba8c3d6fSFelix Fietkau }
1587ba8c3d6fSFelix Fietkau 
1588bb42f2d1SToke Høiland-Jørgensen static bool ieee80211_queue_skb(struct ieee80211_local *local,
1589bb42f2d1SToke Høiland-Jørgensen 				struct ieee80211_sub_if_data *sdata,
1590bb42f2d1SToke Høiland-Jørgensen 				struct sta_info *sta,
1591bb42f2d1SToke Høiland-Jørgensen 				struct sk_buff *skb)
1592bb42f2d1SToke Høiland-Jørgensen {
1593bb42f2d1SToke Høiland-Jørgensen 	struct ieee80211_vif *vif;
1594bb42f2d1SToke Høiland-Jørgensen 	struct txq_info *txqi;
1595bb42f2d1SToke Høiland-Jørgensen 
1596bb42f2d1SToke Høiland-Jørgensen 	if (!local->ops->wake_tx_queue ||
1597bb42f2d1SToke Høiland-Jørgensen 	    sdata->vif.type == NL80211_IFTYPE_MONITOR)
1598bb42f2d1SToke Høiland-Jørgensen 		return false;
1599bb42f2d1SToke Høiland-Jørgensen 
1600bb42f2d1SToke Høiland-Jørgensen 	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
1601bb42f2d1SToke Høiland-Jørgensen 		sdata = container_of(sdata->bss,
1602bb42f2d1SToke Høiland-Jørgensen 				     struct ieee80211_sub_if_data, u.ap);
1603bb42f2d1SToke Høiland-Jørgensen 
1604bb42f2d1SToke Høiland-Jørgensen 	vif = &sdata->vif;
1605dbef5362SMichal Kazior 	txqi = ieee80211_get_txq(local, vif, sta, skb);
1606bb42f2d1SToke Høiland-Jørgensen 
1607bb42f2d1SToke Høiland-Jørgensen 	if (!txqi)
1608bb42f2d1SToke Høiland-Jørgensen 		return false;
1609bb42f2d1SToke Høiland-Jørgensen 
1610bb42f2d1SToke Høiland-Jørgensen 	ieee80211_txq_enqueue(local, txqi, skb);
1611bb42f2d1SToke Høiland-Jørgensen 
161218667600SToke Høiland-Jørgensen 	schedule_and_wake_txq(local, txqi);
1613bb42f2d1SToke Høiland-Jørgensen 
1614bb42f2d1SToke Høiland-Jørgensen 	return true;
1615bb42f2d1SToke Høiland-Jørgensen }
1616bb42f2d1SToke Høiland-Jørgensen 
161711127e91SJohannes Berg static bool ieee80211_tx_frags(struct ieee80211_local *local,
161811127e91SJohannes Berg 			       struct ieee80211_vif *vif,
161911127e91SJohannes Berg 			       struct ieee80211_sta *sta,
162011127e91SJohannes Berg 			       struct sk_buff_head *skbs,
162111127e91SJohannes Berg 			       bool txpending)
1622e2ebc74dSJohannes Berg {
162380a83cfcSMichal Kazior 	struct ieee80211_tx_control control = {};
1624252b86c4SJohannes Berg 	struct sk_buff *skb, *tmp;
16253b8d81e0SJohannes Berg 	unsigned long flags;
1626e2ebc74dSJohannes Berg 
1627252b86c4SJohannes Berg 	skb_queue_walk_safe(skbs, skb, tmp) {
16283a25a8c8SJohannes Berg 		struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
16293a25a8c8SJohannes Berg 		int q = info->hw_queue;
16303a25a8c8SJohannes Berg 
16313a25a8c8SJohannes Berg #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
16323a25a8c8SJohannes Berg 		if (WARN_ON_ONCE(q >= local->hw.queues)) {
16333a25a8c8SJohannes Berg 			__skb_unlink(skb, skbs);
1634c3e7724bSFelix Fietkau 			ieee80211_free_txskb(&local->hw, skb);
16353a25a8c8SJohannes Berg 			continue;
16363a25a8c8SJohannes Berg 		}
16373a25a8c8SJohannes Berg #endif
16383b8d81e0SJohannes Berg 
16393b8d81e0SJohannes Berg 		spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
16403b8d81e0SJohannes Berg 		if (local->queue_stop_reasons[q] ||
16417bb45683SJohannes Berg 		    (!txpending && !skb_queue_empty(&local->pending[q]))) {
16426c17b77bSSeth Forshee 			if (unlikely(info->flags &
1643a7679ed5SSeth Forshee 				     IEEE80211_TX_INTFL_OFFCHAN_TX_OK)) {
1644a7679ed5SSeth Forshee 				if (local->queue_stop_reasons[q] &
1645a7679ed5SSeth Forshee 				    ~BIT(IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL)) {
16466c17b77bSSeth Forshee 					/*
1647a7679ed5SSeth Forshee 					 * Drop off-channel frames if queues
1648a7679ed5SSeth Forshee 					 * are stopped for any reason other
1649a7679ed5SSeth Forshee 					 * than off-channel operation. Never
1650a7679ed5SSeth Forshee 					 * queue them.
16516c17b77bSSeth Forshee 					 */
16526c17b77bSSeth Forshee 					spin_unlock_irqrestore(
1653a7679ed5SSeth Forshee 						&local->queue_stop_reason_lock,
1654a7679ed5SSeth Forshee 						flags);
1655a7679ed5SSeth Forshee 					ieee80211_purge_tx_queue(&local->hw,
1656a7679ed5SSeth Forshee 								 skbs);
16576c17b77bSSeth Forshee 					return true;
16586c17b77bSSeth Forshee 				}
1659a7679ed5SSeth Forshee 			} else {
16606c17b77bSSeth Forshee 
16617bb45683SJohannes Berg 				/*
1662a7679ed5SSeth Forshee 				 * Since queue is stopped, queue up frames for
1663a7679ed5SSeth Forshee 				 * later transmission from the tx-pending
1664a7679ed5SSeth Forshee 				 * tasklet when the queue is woken again.
16657bb45683SJohannes Berg 				 */
1666252b86c4SJohannes Berg 				if (txpending)
1667a7679ed5SSeth Forshee 					skb_queue_splice_init(skbs,
1668a7679ed5SSeth Forshee 							      &local->pending[q]);
16697bb45683SJohannes Berg 				else
16704db4e0a1SJohannes Berg 					skb_queue_splice_tail_init(skbs,
16714db4e0a1SJohannes Berg 								   &local->pending[q]);
16727bb45683SJohannes Berg 
16737bb45683SJohannes Berg 				spin_unlock_irqrestore(&local->queue_stop_reason_lock,
16747bb45683SJohannes Berg 						       flags);
16757bb45683SJohannes Berg 				return false;
16767bb45683SJohannes Berg 			}
1677a7679ed5SSeth Forshee 		}
16783b8d81e0SJohannes Berg 		spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
1679e2530083SJohannes Berg 
168011127e91SJohannes Berg 		info->control.vif = vif;
168180a83cfcSMichal Kazior 		control.sta = sta;
1682ec25acc4SJohannes Berg 
1683252b86c4SJohannes Berg 		__skb_unlink(skb, skbs);
168480a83cfcSMichal Kazior 		drv_tx(local, &control, skb);
1685e2ebc74dSJohannes Berg 	}
16862de8e0d9SJohannes Berg 
168711127e91SJohannes Berg 	return true;
168811127e91SJohannes Berg }
168911127e91SJohannes Berg 
169011127e91SJohannes Berg /*
169111127e91SJohannes Berg  * Returns false if the frame couldn't be transmitted but was queued instead.
169211127e91SJohannes Berg  */
169311127e91SJohannes Berg static bool __ieee80211_tx(struct ieee80211_local *local,
169411127e91SJohannes Berg 			   struct sk_buff_head *skbs, int led_len,
169511127e91SJohannes Berg 			   struct sta_info *sta, bool txpending)
169611127e91SJohannes Berg {
169711127e91SJohannes Berg 	struct ieee80211_tx_info *info;
169811127e91SJohannes Berg 	struct ieee80211_sub_if_data *sdata;
169911127e91SJohannes Berg 	struct ieee80211_vif *vif;
170011127e91SJohannes Berg 	struct ieee80211_sta *pubsta;
170111127e91SJohannes Berg 	struct sk_buff *skb;
170211127e91SJohannes Berg 	bool result = true;
170311127e91SJohannes Berg 	__le16 fc;
170411127e91SJohannes Berg 
170511127e91SJohannes Berg 	if (WARN_ON(skb_queue_empty(skbs)))
170611127e91SJohannes Berg 		return true;
170711127e91SJohannes Berg 
170811127e91SJohannes Berg 	skb = skb_peek(skbs);
170911127e91SJohannes Berg 	fc = ((struct ieee80211_hdr *)skb->data)->frame_control;
171011127e91SJohannes Berg 	info = IEEE80211_SKB_CB(skb);
171111127e91SJohannes Berg 	sdata = vif_to_sdata(info->control.vif);
171211127e91SJohannes Berg 	if (sta && !sta->uploaded)
171311127e91SJohannes Berg 		sta = NULL;
171411127e91SJohannes Berg 
171511127e91SJohannes Berg 	if (sta)
171611127e91SJohannes Berg 		pubsta = &sta->sta;
171711127e91SJohannes Berg 	else
171811127e91SJohannes Berg 		pubsta = NULL;
171911127e91SJohannes Berg 
172011127e91SJohannes Berg 	switch (sdata->vif.type) {
172111127e91SJohannes Berg 	case NL80211_IFTYPE_MONITOR:
1722d8212184SAviya Erenfeld 		if (sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) {
1723c82b5a74SJohannes Berg 			vif = &sdata->vif;
1724c82b5a74SJohannes Berg 			break;
1725c82b5a74SJohannes Berg 		}
17264b6f1dd6SJohannes Berg 		sdata = rcu_dereference(local->monitor_sdata);
17273a25a8c8SJohannes Berg 		if (sdata) {
17284b6f1dd6SJohannes Berg 			vif = &sdata->vif;
17293a25a8c8SJohannes Berg 			info->hw_queue =
17303a25a8c8SJohannes Berg 				vif->hw_queue[skb_get_queue_mapping(skb)];
173130686bf7SJohannes Berg 		} else if (ieee80211_hw_check(&local->hw, QUEUE_CONTROL)) {
173263b4d8b3SJohannes Berg 			ieee80211_purge_tx_queue(&local->hw, skbs);
17333a25a8c8SJohannes Berg 			return true;
17343a25a8c8SJohannes Berg 		} else
173511127e91SJohannes Berg 			vif = NULL;
173611127e91SJohannes Berg 		break;
173711127e91SJohannes Berg 	case NL80211_IFTYPE_AP_VLAN:
173811127e91SJohannes Berg 		sdata = container_of(sdata->bss,
173911127e91SJohannes Berg 				     struct ieee80211_sub_if_data, u.ap);
174011127e91SJohannes Berg 		/* fall through */
174111127e91SJohannes Berg 	default:
174211127e91SJohannes Berg 		vif = &sdata->vif;
174311127e91SJohannes Berg 		break;
174411127e91SJohannes Berg 	}
174511127e91SJohannes Berg 
174611127e91SJohannes Berg 	result = ieee80211_tx_frags(local, vif, pubsta, skbs,
174711127e91SJohannes Berg 				    txpending);
174811127e91SJohannes Berg 
174974e4dbfdSJohannes Berg 	ieee80211_tpt_led_trig_tx(local, fc, led_len);
175074e4dbfdSJohannes Berg 
17514db4e0a1SJohannes Berg 	WARN_ON_ONCE(!skb_queue_empty(skbs));
1752252b86c4SJohannes Berg 
175311127e91SJohannes Berg 	return result;
1754e2ebc74dSJohannes Berg }
1755e2ebc74dSJohannes Berg 
175697b045d6SJohannes Berg /*
175797b045d6SJohannes Berg  * Invoke TX handlers, return 0 on success and non-zero if the
175897b045d6SJohannes Berg  * frame was dropped or queued.
1759bb42f2d1SToke Høiland-Jørgensen  *
1760bb42f2d1SToke Høiland-Jørgensen  * The handlers are split into an early and late part. The latter is everything
1761bb42f2d1SToke Høiland-Jørgensen  * that can be sensitive to reordering, and will be deferred to after packets
1762bb42f2d1SToke Høiland-Jørgensen  * are dequeued from the intermediate queues (when they are enabled).
176397b045d6SJohannes Berg  */
1764bb42f2d1SToke Høiland-Jørgensen static int invoke_tx_handlers_early(struct ieee80211_tx_data *tx)
176597b045d6SJohannes Berg {
176697b045d6SJohannes Berg 	ieee80211_tx_result res = TX_DROP;
176797b045d6SJohannes Berg 
1768d9e8a70fSJohannes Berg #define CALL_TXH(txh) \
17699aa4aee3SJohannes Berg 	do {				\
1770d9e8a70fSJohannes Berg 		res = txh(tx);		\
1771d9e8a70fSJohannes Berg 		if (res != TX_CONTINUE)	\
17729aa4aee3SJohannes Berg 			goto txh_done;	\
17739aa4aee3SJohannes Berg 	} while (0)
177497b045d6SJohannes Berg 
17755c1b98a5SKalle Valo 	CALL_TXH(ieee80211_tx_h_dynamic_ps);
17769aa4aee3SJohannes Berg 	CALL_TXH(ieee80211_tx_h_check_assoc);
17779aa4aee3SJohannes Berg 	CALL_TXH(ieee80211_tx_h_ps_buf);
1778a621fa4dSJohannes Berg 	CALL_TXH(ieee80211_tx_h_check_control_port_protocol);
17799aa4aee3SJohannes Berg 	CALL_TXH(ieee80211_tx_h_select_key);
178030686bf7SJohannes Berg 	if (!ieee80211_hw_check(&tx->local->hw, HAS_RATE_CONTROL))
17819aa4aee3SJohannes Berg 		CALL_TXH(ieee80211_tx_h_rate_ctrl);
1782c6fcf6bcSJohannes Berg 
1783bb42f2d1SToke Høiland-Jørgensen  txh_done:
1784bb42f2d1SToke Høiland-Jørgensen 	if (unlikely(res == TX_DROP)) {
1785bb42f2d1SToke Høiland-Jørgensen 		I802_DEBUG_INC(tx->local->tx_handlers_drop);
1786bb42f2d1SToke Høiland-Jørgensen 		if (tx->skb)
1787bb42f2d1SToke Høiland-Jørgensen 			ieee80211_free_txskb(&tx->local->hw, tx->skb);
1788bb42f2d1SToke Høiland-Jørgensen 		else
1789bb42f2d1SToke Høiland-Jørgensen 			ieee80211_purge_tx_queue(&tx->local->hw, &tx->skbs);
1790bb42f2d1SToke Høiland-Jørgensen 		return -1;
1791bb42f2d1SToke Høiland-Jørgensen 	} else if (unlikely(res == TX_QUEUED)) {
1792bb42f2d1SToke Høiland-Jørgensen 		I802_DEBUG_INC(tx->local->tx_handlers_queued);
1793bb42f2d1SToke Høiland-Jørgensen 		return -1;
1794bb42f2d1SToke Høiland-Jørgensen 	}
1795bb42f2d1SToke Høiland-Jørgensen 
1796bb42f2d1SToke Høiland-Jørgensen 	return 0;
1797bb42f2d1SToke Høiland-Jørgensen }
1798bb42f2d1SToke Høiland-Jørgensen 
1799bb42f2d1SToke Høiland-Jørgensen /*
1800bb42f2d1SToke Høiland-Jørgensen  * Late handlers can be called while the sta lock is held. Handlers that can
1801bb42f2d1SToke Høiland-Jørgensen  * cause packets to be generated will cause deadlock!
1802bb42f2d1SToke Høiland-Jørgensen  */
1803bb42f2d1SToke Høiland-Jørgensen static int invoke_tx_handlers_late(struct ieee80211_tx_data *tx)
1804bb42f2d1SToke Høiland-Jørgensen {
1805bb42f2d1SToke Høiland-Jørgensen 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
1806bb42f2d1SToke Høiland-Jørgensen 	ieee80211_tx_result res = TX_CONTINUE;
1807bb42f2d1SToke Høiland-Jørgensen 
1808aa5b5492SJohannes Berg 	if (unlikely(info->flags & IEEE80211_TX_INTFL_RETRANSMISSION)) {
1809aa5b5492SJohannes Berg 		__skb_queue_tail(&tx->skbs, tx->skb);
1810aa5b5492SJohannes Berg 		tx->skb = NULL;
1811c6fcf6bcSJohannes Berg 		goto txh_done;
1812aa5b5492SJohannes Berg 	}
1813c6fcf6bcSJohannes Berg 
1814c6fcf6bcSJohannes Berg 	CALL_TXH(ieee80211_tx_h_michael_mic_add);
18159aa4aee3SJohannes Berg 	CALL_TXH(ieee80211_tx_h_sequence);
18169aa4aee3SJohannes Berg 	CALL_TXH(ieee80211_tx_h_fragment);
1817d9e8a70fSJohannes Berg 	/* handlers after fragment must be aware of tx info fragmentation! */
18189aa4aee3SJohannes Berg 	CALL_TXH(ieee80211_tx_h_stats);
18199aa4aee3SJohannes Berg 	CALL_TXH(ieee80211_tx_h_encrypt);
182030686bf7SJohannes Berg 	if (!ieee80211_hw_check(&tx->local->hw, HAS_RATE_CONTROL))
18219aa4aee3SJohannes Berg 		CALL_TXH(ieee80211_tx_h_calculate_duration);
1822d9e8a70fSJohannes Berg #undef CALL_TXH
1823d9e8a70fSJohannes Berg 
1824d9e8a70fSJohannes Berg  txh_done:
182597b045d6SJohannes Berg 	if (unlikely(res == TX_DROP)) {
18265479d0e7STomas Winkler 		I802_DEBUG_INC(tx->local->tx_handlers_drop);
1827252b86c4SJohannes Berg 		if (tx->skb)
1828c3e7724bSFelix Fietkau 			ieee80211_free_txskb(&tx->local->hw, tx->skb);
1829252b86c4SJohannes Berg 		else
18301f98ab7fSFelix Fietkau 			ieee80211_purge_tx_queue(&tx->local->hw, &tx->skbs);
183197b045d6SJohannes Berg 		return -1;
183297b045d6SJohannes Berg 	} else if (unlikely(res == TX_QUEUED)) {
18335479d0e7STomas Winkler 		I802_DEBUG_INC(tx->local->tx_handlers_queued);
183497b045d6SJohannes Berg 		return -1;
183597b045d6SJohannes Berg 	}
183697b045d6SJohannes Berg 
183797b045d6SJohannes Berg 	return 0;
183897b045d6SJohannes Berg }
183997b045d6SJohannes Berg 
1840bb42f2d1SToke Høiland-Jørgensen static int invoke_tx_handlers(struct ieee80211_tx_data *tx)
1841bb42f2d1SToke Høiland-Jørgensen {
1842bb42f2d1SToke Høiland-Jørgensen 	int r = invoke_tx_handlers_early(tx);
1843bb42f2d1SToke Høiland-Jørgensen 
1844bb42f2d1SToke Høiland-Jørgensen 	if (r)
1845bb42f2d1SToke Høiland-Jørgensen 		return r;
1846bb42f2d1SToke Høiland-Jørgensen 	return invoke_tx_handlers_late(tx);
1847bb42f2d1SToke Høiland-Jørgensen }
1848bb42f2d1SToke Høiland-Jørgensen 
184906be6b14SFelix Fietkau bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
185006be6b14SFelix Fietkau 			      struct ieee80211_vif *vif, struct sk_buff *skb,
185106be6b14SFelix Fietkau 			      int band, struct ieee80211_sta **sta)
185206be6b14SFelix Fietkau {
185306be6b14SFelix Fietkau 	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
185406be6b14SFelix Fietkau 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
185506be6b14SFelix Fietkau 	struct ieee80211_tx_data tx;
185688724a81SJohannes Berg 	struct sk_buff *skb2;
185706be6b14SFelix Fietkau 
18587c10770fSJohannes Berg 	if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP)
185906be6b14SFelix Fietkau 		return false;
186006be6b14SFelix Fietkau 
186106be6b14SFelix Fietkau 	info->band = band;
186206be6b14SFelix Fietkau 	info->control.vif = vif;
186306be6b14SFelix Fietkau 	info->hw_queue = vif->hw_queue[skb_get_queue_mapping(skb)];
186406be6b14SFelix Fietkau 
186506be6b14SFelix Fietkau 	if (invoke_tx_handlers(&tx))
186606be6b14SFelix Fietkau 		return false;
186706be6b14SFelix Fietkau 
186806be6b14SFelix Fietkau 	if (sta) {
186906be6b14SFelix Fietkau 		if (tx.sta)
187006be6b14SFelix Fietkau 			*sta = &tx.sta->sta;
187106be6b14SFelix Fietkau 		else
187206be6b14SFelix Fietkau 			*sta = NULL;
187306be6b14SFelix Fietkau 	}
187406be6b14SFelix Fietkau 
187588724a81SJohannes Berg 	/* this function isn't suitable for fragmented data frames */
187688724a81SJohannes Berg 	skb2 = __skb_dequeue(&tx.skbs);
187788724a81SJohannes Berg 	if (WARN_ON(skb2 != skb || !skb_queue_empty(&tx.skbs))) {
187888724a81SJohannes Berg 		ieee80211_free_txskb(hw, skb2);
187988724a81SJohannes Berg 		ieee80211_purge_tx_queue(hw, &tx.skbs);
188088724a81SJohannes Berg 		return false;
188188724a81SJohannes Berg 	}
188288724a81SJohannes Berg 
188306be6b14SFelix Fietkau 	return true;
188406be6b14SFelix Fietkau }
188506be6b14SFelix Fietkau EXPORT_SYMBOL(ieee80211_tx_prepare_skb);
188606be6b14SFelix Fietkau 
18877bb45683SJohannes Berg /*
18887bb45683SJohannes Berg  * Returns false if the frame couldn't be transmitted but was queued instead.
18897bb45683SJohannes Berg  */
18907bb45683SJohannes Berg static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata,
18917c10770fSJohannes Berg 			 struct sta_info *sta, struct sk_buff *skb,
1892b9771d41SJohannes Berg 			 bool txpending, u32 txdata_flags)
1893e2ebc74dSJohannes Berg {
18943b8d81e0SJohannes Berg 	struct ieee80211_local *local = sdata->local;
18955cf121c3SJohannes Berg 	struct ieee80211_tx_data tx;
189697b045d6SJohannes Berg 	ieee80211_tx_result res_prepare;
1897e039fa4aSJohannes Berg 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
18987bb45683SJohannes Berg 	bool result = true;
189974e4dbfdSJohannes Berg 	int led_len;
1900e2ebc74dSJohannes Berg 
1901e2ebc74dSJohannes Berg 	if (unlikely(skb->len < 10)) {
1902e2ebc74dSJohannes Berg 		dev_kfree_skb(skb);
19037bb45683SJohannes Berg 		return true;
1904e2ebc74dSJohannes Berg 	}
1905e2ebc74dSJohannes Berg 
190658d4185eSJohannes Berg 	/* initialises tx */
190774e4dbfdSJohannes Berg 	led_len = skb->len;
19087c10770fSJohannes Berg 	res_prepare = ieee80211_tx_prepare(sdata, &tx, sta, skb);
1909e2ebc74dSJohannes Berg 
1910b9771d41SJohannes Berg 	tx.flags |= txdata_flags;
1911b9771d41SJohannes Berg 
1912cd8ffc80SJohannes Berg 	if (unlikely(res_prepare == TX_DROP)) {
1913c3e7724bSFelix Fietkau 		ieee80211_free_txskb(&local->hw, skb);
191455de908aSJohannes Berg 		return true;
1915cd8ffc80SJohannes Berg 	} else if (unlikely(res_prepare == TX_QUEUED)) {
191655de908aSJohannes Berg 		return true;
1917e2ebc74dSJohannes Berg 	}
1918e2ebc74dSJohannes Berg 
19193a25a8c8SJohannes Berg 	/* set up hw_queue value early */
19203a25a8c8SJohannes Berg 	if (!(info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) ||
192130686bf7SJohannes Berg 	    !ieee80211_hw_check(&local->hw, QUEUE_CONTROL))
19223a25a8c8SJohannes Berg 		info->hw_queue =
19233a25a8c8SJohannes Berg 			sdata->vif.hw_queue[skb_get_queue_mapping(skb)];
19243a25a8c8SJohannes Berg 
1925bb42f2d1SToke Høiland-Jørgensen 	if (invoke_tx_handlers_early(&tx))
19266eae4a6cSBob Copeland 		return true;
1927bb42f2d1SToke Høiland-Jørgensen 
1928bb42f2d1SToke Høiland-Jørgensen 	if (ieee80211_queue_skb(local, sdata, tx.sta, tx.skb))
1929bb42f2d1SToke Høiland-Jørgensen 		return true;
1930bb42f2d1SToke Høiland-Jørgensen 
1931bb42f2d1SToke Høiland-Jørgensen 	if (!invoke_tx_handlers_late(&tx))
193274e4dbfdSJohannes Berg 		result = __ieee80211_tx(local, &tx.skbs, led_len,
193374e4dbfdSJohannes Berg 					tx.sta, txpending);
193455de908aSJohannes Berg 
19357bb45683SJohannes Berg 	return result;
1936e2ebc74dSJohannes Berg }
1937e2ebc74dSJohannes Berg 
1938e2ebc74dSJohannes Berg /* device xmit handlers */
1939e2ebc74dSJohannes Berg 
19403bff1865SYogesh Ashok Powar static int ieee80211_skb_resize(struct ieee80211_sub_if_data *sdata,
194123c0752aSJohannes Berg 				struct sk_buff *skb,
194223c0752aSJohannes Berg 				int head_need, bool may_encrypt)
194323c0752aSJohannes Berg {
19443bff1865SYogesh Ashok Powar 	struct ieee80211_local *local = sdata->local;
19459d0f50b8SFelix Fietkau 	struct ieee80211_hdr *hdr;
19469d0f50b8SFelix Fietkau 	bool enc_tailroom;
194723c0752aSJohannes Berg 	int tail_need = 0;
194823c0752aSJohannes Berg 
19499d0f50b8SFelix Fietkau 	hdr = (struct ieee80211_hdr *) skb->data;
19509d0f50b8SFelix Fietkau 	enc_tailroom = may_encrypt &&
19519d0f50b8SFelix Fietkau 		       (sdata->crypto_tx_tailroom_needed_cnt ||
19529d0f50b8SFelix Fietkau 			ieee80211_is_mgmt(hdr->frame_control));
19539d0f50b8SFelix Fietkau 
19549d0f50b8SFelix Fietkau 	if (enc_tailroom) {
195523c0752aSJohannes Berg 		tail_need = IEEE80211_ENCRYPT_TAILROOM;
195623c0752aSJohannes Berg 		tail_need -= skb_tailroom(skb);
195723c0752aSJohannes Berg 		tail_need = max_t(int, tail_need, 0);
195823c0752aSJohannes Berg 	}
195923c0752aSJohannes Berg 
1960c70f59a2SIdo Yariv 	if (skb_cloned(skb) &&
196130686bf7SJohannes Berg 	    (!ieee80211_hw_check(&local->hw, SUPPORTS_CLONED_SKBS) ||
19629d0f50b8SFelix Fietkau 	     !skb_clone_writable(skb, ETH_HLEN) || enc_tailroom))
196323c0752aSJohannes Berg 		I802_DEBUG_INC(local->tx_expand_skb_head_cloned);
19644cd06a34SFelix Fietkau 	else if (head_need || tail_need)
196523c0752aSJohannes Berg 		I802_DEBUG_INC(local->tx_expand_skb_head);
19664cd06a34SFelix Fietkau 	else
19674cd06a34SFelix Fietkau 		return 0;
196823c0752aSJohannes Berg 
196923c0752aSJohannes Berg 	if (pskb_expand_head(skb, head_need, tail_need, GFP_ATOMIC)) {
19700fb9a9ecSJoe Perches 		wiphy_debug(local->hw.wiphy,
19710fb9a9ecSJoe Perches 			    "failed to reallocate TX buffer\n");
197223c0752aSJohannes Berg 		return -ENOMEM;
197323c0752aSJohannes Berg 	}
197423c0752aSJohannes Berg 
197523c0752aSJohannes Berg 	return 0;
197623c0752aSJohannes Berg }
197723c0752aSJohannes Berg 
19787c10770fSJohannes Berg void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
1979b9771d41SJohannes Berg 		    struct sta_info *sta, struct sk_buff *skb,
1980b9771d41SJohannes Berg 		    u32 txdata_flags)
1981e2ebc74dSJohannes Berg {
19823b8d81e0SJohannes Berg 	struct ieee80211_local *local = sdata->local;
1983e039fa4aSJohannes Berg 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
198411b05ba3SColin Ian King 	struct ieee80211_hdr *hdr;
1985e2ebc74dSJohannes Berg 	int headroom;
198623c0752aSJohannes Berg 	bool may_encrypt;
1987e2ebc74dSJohannes Berg 
19883b8d81e0SJohannes Berg 	may_encrypt = !(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT);
198923c0752aSJohannes Berg 
19903b8d81e0SJohannes Berg 	headroom = local->tx_headroom;
199123c0752aSJohannes Berg 	if (may_encrypt)
19922475b1ccSMax Stepanov 		headroom += sdata->encrypt_headroom;
199323c0752aSJohannes Berg 	headroom -= skb_headroom(skb);
199423c0752aSJohannes Berg 	headroom = max_t(int, 0, headroom);
199523c0752aSJohannes Berg 
19963bff1865SYogesh Ashok Powar 	if (ieee80211_skb_resize(sdata, skb, headroom, may_encrypt)) {
1997c3e7724bSFelix Fietkau 		ieee80211_free_txskb(&local->hw, skb);
19983b8d81e0SJohannes Berg 		return;
1999e2ebc74dSJohannes Berg 	}
2000e2ebc74dSJohannes Berg 
2001740c1aa3SSteve deRosier 	hdr = (struct ieee80211_hdr *) skb->data;
20025061b0c2SJohannes Berg 	info->control.vif = &sdata->vif;
2003cd8ffc80SJohannes Berg 
20043f52b7e3SMarco Porsch 	if (ieee80211_vif_is_mesh(&sdata->vif)) {
20053f52b7e3SMarco Porsch 		if (ieee80211_is_data(hdr->frame_control) &&
20063f52b7e3SMarco Porsch 		    is_unicast_ether_addr(hdr->addr1)) {
2007bf7cd94dSJohannes Berg 			if (mesh_nexthop_resolve(sdata, skb))
20083f52b7e3SMarco Porsch 				return; /* skb queued: don't free */
20093f52b7e3SMarco Porsch 		} else {
20103f52b7e3SMarco Porsch 			ieee80211_mps_set_frame_flags(sdata, NULL, hdr);
20113f52b7e3SMarco Porsch 		}
2012cca89496SJavier Cardona 	}
2013cca89496SJavier Cardona 
20142154c81cSJavier Cardona 	ieee80211_set_qos_hdr(sdata, skb);
2015b9771d41SJohannes Berg 	ieee80211_tx(sdata, sta, skb, false, txdata_flags);
2016e2ebc74dSJohannes Berg }
2017e2ebc74dSJohannes Berg 
2018dfdfc2beSSven Eckelmann static bool ieee80211_parse_tx_radiotap(struct ieee80211_local *local,
2019dfdfc2beSSven Eckelmann 					struct sk_buff *skb)
202073b9f03aSJohannes Berg {
202173b9f03aSJohannes Berg 	struct ieee80211_radiotap_iterator iterator;
202273b9f03aSJohannes Berg 	struct ieee80211_radiotap_header *rthdr =
202373b9f03aSJohannes Berg 		(struct ieee80211_radiotap_header *) skb->data;
202473b9f03aSJohannes Berg 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2025dfdfc2beSSven Eckelmann 	struct ieee80211_supported_band *sband =
2026dfdfc2beSSven Eckelmann 		local->hw.wiphy->bands[info->band];
202773b9f03aSJohannes Berg 	int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len,
202873b9f03aSJohannes Berg 						   NULL);
202973b9f03aSJohannes Berg 	u16 txflags;
2030dfdfc2beSSven Eckelmann 	u16 rate = 0;
2031dfdfc2beSSven Eckelmann 	bool rate_found = false;
2032dfdfc2beSSven Eckelmann 	u8 rate_retries = 0;
2033dfdfc2beSSven Eckelmann 	u16 rate_flags = 0;
2034f66b60f6SSven Eckelmann 	u8 mcs_known, mcs_flags, mcs_bw;
2035646e76bbSLorenzo Bianconi 	u16 vht_known;
2036646e76bbSLorenzo Bianconi 	u8 vht_mcs = 0, vht_nss = 0;
2037dfdfc2beSSven Eckelmann 	int i;
203873b9f03aSJohannes Berg 
203973b9f03aSJohannes Berg 	info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
204073b9f03aSJohannes Berg 		       IEEE80211_TX_CTL_DONTFRAG;
204173b9f03aSJohannes Berg 
204273b9f03aSJohannes Berg 	/*
204373b9f03aSJohannes Berg 	 * for every radiotap entry that is present
204473b9f03aSJohannes Berg 	 * (ieee80211_radiotap_iterator_next returns -ENOENT when no more
204573b9f03aSJohannes Berg 	 * entries present, or -EINVAL on error)
204673b9f03aSJohannes Berg 	 */
204773b9f03aSJohannes Berg 
204873b9f03aSJohannes Berg 	while (!ret) {
204973b9f03aSJohannes Berg 		ret = ieee80211_radiotap_iterator_next(&iterator);
205073b9f03aSJohannes Berg 
205173b9f03aSJohannes Berg 		if (ret)
205273b9f03aSJohannes Berg 			continue;
205373b9f03aSJohannes Berg 
205473b9f03aSJohannes Berg 		/* see if this argument is something we can use */
205573b9f03aSJohannes Berg 		switch (iterator.this_arg_index) {
205673b9f03aSJohannes Berg 		/*
205773b9f03aSJohannes Berg 		 * You must take care when dereferencing iterator.this_arg
205873b9f03aSJohannes Berg 		 * for multibyte types... the pointer is not aligned.  Use
205973b9f03aSJohannes Berg 		 * get_unaligned((type *)iterator.this_arg) to dereference
206073b9f03aSJohannes Berg 		 * iterator.this_arg for type "type" safely on all arches.
206173b9f03aSJohannes Berg 		*/
206273b9f03aSJohannes Berg 		case IEEE80211_RADIOTAP_FLAGS:
206373b9f03aSJohannes Berg 			if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) {
206473b9f03aSJohannes Berg 				/*
206573b9f03aSJohannes Berg 				 * this indicates that the skb we have been
206673b9f03aSJohannes Berg 				 * handed has the 32-bit FCS CRC at the end...
206773b9f03aSJohannes Berg 				 * we should react to that by snipping it off
206873b9f03aSJohannes Berg 				 * because it will be recomputed and added
206973b9f03aSJohannes Berg 				 * on transmission
207073b9f03aSJohannes Berg 				 */
207173b9f03aSJohannes Berg 				if (skb->len < (iterator._max_length + FCS_LEN))
207273b9f03aSJohannes Berg 					return false;
207373b9f03aSJohannes Berg 
207473b9f03aSJohannes Berg 				skb_trim(skb, skb->len - FCS_LEN);
207573b9f03aSJohannes Berg 			}
207673b9f03aSJohannes Berg 			if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP)
207773b9f03aSJohannes Berg 				info->flags &= ~IEEE80211_TX_INTFL_DONT_ENCRYPT;
207873b9f03aSJohannes Berg 			if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG)
207973b9f03aSJohannes Berg 				info->flags &= ~IEEE80211_TX_CTL_DONTFRAG;
208073b9f03aSJohannes Berg 			break;
208173b9f03aSJohannes Berg 
208273b9f03aSJohannes Berg 		case IEEE80211_RADIOTAP_TX_FLAGS:
208373b9f03aSJohannes Berg 			txflags = get_unaligned_le16(iterator.this_arg);
208473b9f03aSJohannes Berg 			if (txflags & IEEE80211_RADIOTAP_F_TX_NOACK)
208573b9f03aSJohannes Berg 				info->flags |= IEEE80211_TX_CTL_NO_ACK;
208673b9f03aSJohannes Berg 			break;
208773b9f03aSJohannes Berg 
2088dfdfc2beSSven Eckelmann 		case IEEE80211_RADIOTAP_RATE:
2089dfdfc2beSSven Eckelmann 			rate = *iterator.this_arg;
2090dfdfc2beSSven Eckelmann 			rate_flags = 0;
2091dfdfc2beSSven Eckelmann 			rate_found = true;
2092dfdfc2beSSven Eckelmann 			break;
2093dfdfc2beSSven Eckelmann 
2094dfdfc2beSSven Eckelmann 		case IEEE80211_RADIOTAP_DATA_RETRIES:
2095dfdfc2beSSven Eckelmann 			rate_retries = *iterator.this_arg;
2096dfdfc2beSSven Eckelmann 			break;
2097dfdfc2beSSven Eckelmann 
2098dfdfc2beSSven Eckelmann 		case IEEE80211_RADIOTAP_MCS:
2099dfdfc2beSSven Eckelmann 			mcs_known = iterator.this_arg[0];
2100dfdfc2beSSven Eckelmann 			mcs_flags = iterator.this_arg[1];
2101dfdfc2beSSven Eckelmann 			if (!(mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_MCS))
2102dfdfc2beSSven Eckelmann 				break;
2103dfdfc2beSSven Eckelmann 
2104dfdfc2beSSven Eckelmann 			rate_found = true;
2105dfdfc2beSSven Eckelmann 			rate = iterator.this_arg[2];
2106dfdfc2beSSven Eckelmann 			rate_flags = IEEE80211_TX_RC_MCS;
2107dfdfc2beSSven Eckelmann 
2108dfdfc2beSSven Eckelmann 			if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_GI &&
2109dfdfc2beSSven Eckelmann 			    mcs_flags & IEEE80211_RADIOTAP_MCS_SGI)
2110dfdfc2beSSven Eckelmann 				rate_flags |= IEEE80211_TX_RC_SHORT_GI;
2111dfdfc2beSSven Eckelmann 
2112f66b60f6SSven Eckelmann 			mcs_bw = mcs_flags & IEEE80211_RADIOTAP_MCS_BW_MASK;
2113dfdfc2beSSven Eckelmann 			if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_BW &&
2114f66b60f6SSven Eckelmann 			    mcs_bw == IEEE80211_RADIOTAP_MCS_BW_40)
2115dfdfc2beSSven Eckelmann 				rate_flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
2116dfdfc2beSSven Eckelmann 			break;
2117dfdfc2beSSven Eckelmann 
2118646e76bbSLorenzo Bianconi 		case IEEE80211_RADIOTAP_VHT:
2119646e76bbSLorenzo Bianconi 			vht_known = get_unaligned_le16(iterator.this_arg);
2120646e76bbSLorenzo Bianconi 			rate_found = true;
2121646e76bbSLorenzo Bianconi 
2122646e76bbSLorenzo Bianconi 			rate_flags = IEEE80211_TX_RC_VHT_MCS;
2123646e76bbSLorenzo Bianconi 			if ((vht_known & IEEE80211_RADIOTAP_VHT_KNOWN_GI) &&
2124646e76bbSLorenzo Bianconi 			    (iterator.this_arg[2] &
2125646e76bbSLorenzo Bianconi 			     IEEE80211_RADIOTAP_VHT_FLAG_SGI))
2126646e76bbSLorenzo Bianconi 				rate_flags |= IEEE80211_TX_RC_SHORT_GI;
2127646e76bbSLorenzo Bianconi 			if (vht_known &
2128646e76bbSLorenzo Bianconi 			    IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH) {
2129646e76bbSLorenzo Bianconi 				if (iterator.this_arg[3] == 1)
2130646e76bbSLorenzo Bianconi 					rate_flags |=
2131646e76bbSLorenzo Bianconi 						IEEE80211_TX_RC_40_MHZ_WIDTH;
2132646e76bbSLorenzo Bianconi 				else if (iterator.this_arg[3] == 4)
2133646e76bbSLorenzo Bianconi 					rate_flags |=
2134646e76bbSLorenzo Bianconi 						IEEE80211_TX_RC_80_MHZ_WIDTH;
2135646e76bbSLorenzo Bianconi 				else if (iterator.this_arg[3] == 11)
2136646e76bbSLorenzo Bianconi 					rate_flags |=
2137646e76bbSLorenzo Bianconi 						IEEE80211_TX_RC_160_MHZ_WIDTH;
2138646e76bbSLorenzo Bianconi 			}
2139646e76bbSLorenzo Bianconi 
2140646e76bbSLorenzo Bianconi 			vht_mcs = iterator.this_arg[4] >> 4;
2141646e76bbSLorenzo Bianconi 			vht_nss = iterator.this_arg[4] & 0xF;
2142646e76bbSLorenzo Bianconi 			break;
2143646e76bbSLorenzo Bianconi 
214473b9f03aSJohannes Berg 		/*
214573b9f03aSJohannes Berg 		 * Please update the file
214673b9f03aSJohannes Berg 		 * Documentation/networking/mac80211-injection.txt
214773b9f03aSJohannes Berg 		 * when parsing new fields here.
214873b9f03aSJohannes Berg 		 */
214973b9f03aSJohannes Berg 
215073b9f03aSJohannes Berg 		default:
215173b9f03aSJohannes Berg 			break;
215273b9f03aSJohannes Berg 		}
215373b9f03aSJohannes Berg 	}
215473b9f03aSJohannes Berg 
215573b9f03aSJohannes Berg 	if (ret != -ENOENT) /* ie, if we didn't simply run out of fields */
215673b9f03aSJohannes Berg 		return false;
215773b9f03aSJohannes Berg 
2158dfdfc2beSSven Eckelmann 	if (rate_found) {
2159dfdfc2beSSven Eckelmann 		info->control.flags |= IEEE80211_TX_CTRL_RATE_INJECT;
2160dfdfc2beSSven Eckelmann 
2161dfdfc2beSSven Eckelmann 		for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
2162dfdfc2beSSven Eckelmann 			info->control.rates[i].idx = -1;
2163dfdfc2beSSven Eckelmann 			info->control.rates[i].flags = 0;
2164dfdfc2beSSven Eckelmann 			info->control.rates[i].count = 0;
2165dfdfc2beSSven Eckelmann 		}
2166dfdfc2beSSven Eckelmann 
2167dfdfc2beSSven Eckelmann 		if (rate_flags & IEEE80211_TX_RC_MCS) {
2168dfdfc2beSSven Eckelmann 			info->control.rates[0].idx = rate;
2169646e76bbSLorenzo Bianconi 		} else if (rate_flags & IEEE80211_TX_RC_VHT_MCS) {
2170646e76bbSLorenzo Bianconi 			ieee80211_rate_set_vht(info->control.rates, vht_mcs,
2171646e76bbSLorenzo Bianconi 					       vht_nss);
2172dfdfc2beSSven Eckelmann 		} else {
2173dfdfc2beSSven Eckelmann 			for (i = 0; i < sband->n_bitrates; i++) {
2174dfdfc2beSSven Eckelmann 				if (rate * 5 != sband->bitrates[i].bitrate)
2175dfdfc2beSSven Eckelmann 					continue;
2176dfdfc2beSSven Eckelmann 
2177dfdfc2beSSven Eckelmann 				info->control.rates[0].idx = i;
2178dfdfc2beSSven Eckelmann 				break;
2179dfdfc2beSSven Eckelmann 			}
2180dfdfc2beSSven Eckelmann 		}
2181dfdfc2beSSven Eckelmann 
218207310a63SFelix Fietkau 		if (info->control.rates[0].idx < 0)
218307310a63SFelix Fietkau 			info->control.flags &= ~IEEE80211_TX_CTRL_RATE_INJECT;
218407310a63SFelix Fietkau 
2185dfdfc2beSSven Eckelmann 		info->control.rates[0].flags = rate_flags;
2186dfdfc2beSSven Eckelmann 		info->control.rates[0].count = min_t(u8, rate_retries + 1,
2187dfdfc2beSSven Eckelmann 						     local->hw.max_rate_tries);
2188dfdfc2beSSven Eckelmann 	}
2189dfdfc2beSSven Eckelmann 
219073b9f03aSJohannes Berg 	/*
219173b9f03aSJohannes Berg 	 * remove the radiotap header
219273b9f03aSJohannes Berg 	 * iterator->_max_length was sanity-checked against
219373b9f03aSJohannes Berg 	 * skb->len by iterator init
219473b9f03aSJohannes Berg 	 */
219573b9f03aSJohannes Berg 	skb_pull(skb, iterator._max_length);
219673b9f03aSJohannes Berg 
219773b9f03aSJohannes Berg 	return true;
219873b9f03aSJohannes Berg }
219973b9f03aSJohannes Berg 
2200d0cf9c0dSStephen Hemminger netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
2201e2ebc74dSJohannes Berg 					 struct net_device *dev)
2202e2ebc74dSJohannes Berg {
2203e2ebc74dSJohannes Berg 	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
220455de908aSJohannes Berg 	struct ieee80211_chanctx_conf *chanctx_conf;
2205e2ebc74dSJohannes Berg 	struct ieee80211_radiotap_header *prthdr =
2206e2ebc74dSJohannes Berg 		(struct ieee80211_radiotap_header *)skb->data;
22073b8d81e0SJohannes Berg 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2208f75f5c6fSHelmut Schaa 	struct ieee80211_hdr *hdr;
22095d9cf4a5SJohannes Berg 	struct ieee80211_sub_if_data *tmp_sdata, *sdata;
2210b4932836SJanusz Dziedzic 	struct cfg80211_chan_def *chandef;
22119b8a74e3SAndy Green 	u16 len_rthdr;
22125d9cf4a5SJohannes Berg 	int hdrlen;
2213e2ebc74dSJohannes Berg 
22149b8a74e3SAndy Green 	/* check for not even having the fixed radiotap header part */
22159b8a74e3SAndy Green 	if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
22169b8a74e3SAndy Green 		goto fail; /* too short to be possibly valid */
22179b8a74e3SAndy Green 
22189b8a74e3SAndy Green 	/* is it a header version we can trust to find length from? */
22199b8a74e3SAndy Green 	if (unlikely(prthdr->it_version))
22209b8a74e3SAndy Green 		goto fail; /* only version 0 is supported */
22219b8a74e3SAndy Green 
22229b8a74e3SAndy Green 	/* then there must be a radiotap header with a length we can use */
22239b8a74e3SAndy Green 	len_rthdr = ieee80211_get_radiotap_len(skb->data);
22249b8a74e3SAndy Green 
22259b8a74e3SAndy Green 	/* does the skb contain enough to deliver on the alleged length? */
22269b8a74e3SAndy Green 	if (unlikely(skb->len < len_rthdr))
22279b8a74e3SAndy Green 		goto fail; /* skb too short for claimed rt header extent */
2228e2ebc74dSJohannes Berg 
2229e2ebc74dSJohannes Berg 	/*
2230e2ebc74dSJohannes Berg 	 * fix up the pointers accounting for the radiotap
2231e2ebc74dSJohannes Berg 	 * header still being in there.  We are being given
2232e2ebc74dSJohannes Berg 	 * a precooked IEEE80211 header so no need for
2233e2ebc74dSJohannes Berg 	 * normal processing
2234e2ebc74dSJohannes Berg 	 */
22359b8a74e3SAndy Green 	skb_set_mac_header(skb, len_rthdr);
2236e2ebc74dSJohannes Berg 	/*
22379b8a74e3SAndy Green 	 * these are just fixed to the end of the rt area since we
22389b8a74e3SAndy Green 	 * don't have any better information and at this point, nobody cares
2239e2ebc74dSJohannes Berg 	 */
22409b8a74e3SAndy Green 	skb_set_network_header(skb, len_rthdr);
22419b8a74e3SAndy Green 	skb_set_transport_header(skb, len_rthdr);
2242e2ebc74dSJohannes Berg 
22435d9cf4a5SJohannes Berg 	if (skb->len < len_rthdr + 2)
22445d9cf4a5SJohannes Berg 		goto fail;
22455d9cf4a5SJohannes Berg 
22465d9cf4a5SJohannes Berg 	hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr);
22475d9cf4a5SJohannes Berg 	hdrlen = ieee80211_hdrlen(hdr->frame_control);
22485d9cf4a5SJohannes Berg 
22495d9cf4a5SJohannes Berg 	if (skb->len < len_rthdr + hdrlen)
22505d9cf4a5SJohannes Berg 		goto fail;
22515d9cf4a5SJohannes Berg 
2252f75f5c6fSHelmut Schaa 	/*
2253f75f5c6fSHelmut Schaa 	 * Initialize skb->protocol if the injected frame is a data frame
2254f75f5c6fSHelmut Schaa 	 * carrying a rfc1042 header
2255f75f5c6fSHelmut Schaa 	 */
2256f75f5c6fSHelmut Schaa 	if (ieee80211_is_data(hdr->frame_control) &&
22575d9cf4a5SJohannes Berg 	    skb->len >= len_rthdr + hdrlen + sizeof(rfc1042_header) + 2) {
22585d9cf4a5SJohannes Berg 		u8 *payload = (u8 *)hdr + hdrlen;
22595d9cf4a5SJohannes Berg 
2260b203ca39SJoe Perches 		if (ether_addr_equal(payload, rfc1042_header))
2261f75f5c6fSHelmut Schaa 			skb->protocol = cpu_to_be16((payload[6] << 8) |
2262f75f5c6fSHelmut Schaa 						    payload[7]);
2263f75f5c6fSHelmut Schaa 	}
2264f75f5c6fSHelmut Schaa 
22653b8d81e0SJohannes Berg 	memset(info, 0, sizeof(*info));
22663b8d81e0SJohannes Berg 
22675d9cf4a5SJohannes Berg 	info->flags = IEEE80211_TX_CTL_REQ_TX_STATUS |
226873b9f03aSJohannes Berg 		      IEEE80211_TX_CTL_INJECTED;
226973b9f03aSJohannes Berg 
22705d9cf4a5SJohannes Berg 	rcu_read_lock();
22715d9cf4a5SJohannes Berg 
22725d9cf4a5SJohannes Berg 	/*
22735d9cf4a5SJohannes Berg 	 * We process outgoing injected frames that have a local address
22745d9cf4a5SJohannes Berg 	 * we handle as though they are non-injected frames.
22755d9cf4a5SJohannes Berg 	 * This code here isn't entirely correct, the local MAC address
22765d9cf4a5SJohannes Berg 	 * isn't always enough to find the interface to use; for proper
22775d9cf4a5SJohannes Berg 	 * VLAN/WDS support we will need a different mechanism (which
22785d9cf4a5SJohannes Berg 	 * likely isn't going to be monitor interfaces).
22795d9cf4a5SJohannes Berg 	 */
22805d9cf4a5SJohannes Berg 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
22815d9cf4a5SJohannes Berg 
22825d9cf4a5SJohannes Berg 	list_for_each_entry_rcu(tmp_sdata, &local->interfaces, list) {
22835d9cf4a5SJohannes Berg 		if (!ieee80211_sdata_running(tmp_sdata))
22845d9cf4a5SJohannes Berg 			continue;
22855d9cf4a5SJohannes Berg 		if (tmp_sdata->vif.type == NL80211_IFTYPE_MONITOR ||
22865d9cf4a5SJohannes Berg 		    tmp_sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
22875d9cf4a5SJohannes Berg 		    tmp_sdata->vif.type == NL80211_IFTYPE_WDS)
22885d9cf4a5SJohannes Berg 			continue;
2289b203ca39SJoe Perches 		if (ether_addr_equal(tmp_sdata->vif.addr, hdr->addr2)) {
22905d9cf4a5SJohannes Berg 			sdata = tmp_sdata;
22915d9cf4a5SJohannes Berg 			break;
22925d9cf4a5SJohannes Berg 		}
22935d9cf4a5SJohannes Berg 	}
22947351c6bdSJohannes Berg 
229555de908aSJohannes Berg 	chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
229655de908aSJohannes Berg 	if (!chanctx_conf) {
229755de908aSJohannes Berg 		tmp_sdata = rcu_dereference(local->monitor_sdata);
229855de908aSJohannes Berg 		if (tmp_sdata)
229955de908aSJohannes Berg 			chanctx_conf =
230055de908aSJohannes Berg 				rcu_dereference(tmp_sdata->vif.chanctx_conf);
230155de908aSJohannes Berg 	}
230255de908aSJohannes Berg 
2303b4a7ff75SFelix Fietkau 	if (chanctx_conf)
2304b4932836SJanusz Dziedzic 		chandef = &chanctx_conf->def;
2305b4a7ff75SFelix Fietkau 	else if (!local->use_chanctx)
2306b4932836SJanusz Dziedzic 		chandef = &local->_oper_chandef;
2307b4a7ff75SFelix Fietkau 	else
2308b4a7ff75SFelix Fietkau 		goto fail_rcu;
230955de908aSJohannes Berg 
231055de908aSJohannes Berg 	/*
231155de908aSJohannes Berg 	 * Frame injection is not allowed if beaconing is not allowed
231255de908aSJohannes Berg 	 * or if we need radar detection. Beaconing is usually not allowed when
231355de908aSJohannes Berg 	 * the mode or operation (Adhoc, AP, Mesh) does not support DFS.
231455de908aSJohannes Berg 	 * Passive scan is also used in world regulatory domains where
231555de908aSJohannes Berg 	 * your country is not known and as such it should be treated as
231655de908aSJohannes Berg 	 * NO TX unless the channel is explicitly allowed in which case
231755de908aSJohannes Berg 	 * your current regulatory domain would not have the passive scan
231855de908aSJohannes Berg 	 * flag.
231955de908aSJohannes Berg 	 *
232055de908aSJohannes Berg 	 * Since AP mode uses monitor interfaces to inject/TX management
232155de908aSJohannes Berg 	 * frames we can make AP mode the exception to this rule once it
232255de908aSJohannes Berg 	 * supports radar detection as its implementation can deal with
232355de908aSJohannes Berg 	 * radar detection by itself. We can do that later by adding a
232455de908aSJohannes Berg 	 * monitor flag interfaces used for AP support.
232555de908aSJohannes Berg 	 */
2326b4932836SJanusz Dziedzic 	if (!cfg80211_reg_can_beacon(local->hw.wiphy, chandef,
2327b4932836SJanusz Dziedzic 				     sdata->vif.type))
232855de908aSJohannes Berg 		goto fail_rcu;
232955de908aSJohannes Berg 
233073c4e195SJohannes Berg 	info->band = chandef->chan->band;
2331109843b0SLorenzo Bianconi 
2332109843b0SLorenzo Bianconi 	/* process and remove the injection radiotap header */
2333109843b0SLorenzo Bianconi 	if (!ieee80211_parse_tx_radiotap(local, skb))
2334109843b0SLorenzo Bianconi 		goto fail_rcu;
2335109843b0SLorenzo Bianconi 
2336b9771d41SJohannes Berg 	ieee80211_xmit(sdata, NULL, skb, 0);
23375d9cf4a5SJohannes Berg 	rcu_read_unlock();
23385d9cf4a5SJohannes Berg 
2339e2ebc74dSJohannes Berg 	return NETDEV_TX_OK;
23409b8a74e3SAndy Green 
234155de908aSJohannes Berg fail_rcu:
234255de908aSJohannes Berg 	rcu_read_unlock();
23439b8a74e3SAndy Green fail:
23449b8a74e3SAndy Green 	dev_kfree_skb(skb);
23459b8a74e3SAndy Green 	return NETDEV_TX_OK; /* meaning, we dealt with the skb */
2346e2ebc74dSJohannes Berg }
2347e2ebc74dSJohannes Berg 
234897ffe757SJohannes Berg static inline bool ieee80211_is_tdls_setup(struct sk_buff *skb)
2349ad38bfc9SMatti Gottlieb {
235097ffe757SJohannes Berg 	u16 ethertype = (skb->data[12] << 8) | skb->data[13];
2351ad38bfc9SMatti Gottlieb 
235297ffe757SJohannes Berg 	return ethertype == ETH_P_TDLS &&
235397ffe757SJohannes Berg 	       skb->len > 14 &&
235497ffe757SJohannes Berg 	       skb->data[14] == WLAN_TDLS_SNAP_RFTYPE;
235597ffe757SJohannes Berg }
235697ffe757SJohannes Berg 
235797ffe757SJohannes Berg static int ieee80211_lookup_ra_sta(struct ieee80211_sub_if_data *sdata,
235897ffe757SJohannes Berg 				   struct sk_buff *skb,
235997ffe757SJohannes Berg 				   struct sta_info **sta_out)
236097ffe757SJohannes Berg {
236197ffe757SJohannes Berg 	struct sta_info *sta;
236297ffe757SJohannes Berg 
236397ffe757SJohannes Berg 	switch (sdata->vif.type) {
236497ffe757SJohannes Berg 	case NL80211_IFTYPE_AP_VLAN:
236597ffe757SJohannes Berg 		sta = rcu_dereference(sdata->u.vlan.sta);
236697ffe757SJohannes Berg 		if (sta) {
236797ffe757SJohannes Berg 			*sta_out = sta;
236897ffe757SJohannes Berg 			return 0;
236997ffe757SJohannes Berg 		} else if (sdata->wdev.use_4addr) {
237097ffe757SJohannes Berg 			return -ENOLINK;
237197ffe757SJohannes Berg 		}
237297ffe757SJohannes Berg 		/* fall through */
237397ffe757SJohannes Berg 	case NL80211_IFTYPE_AP:
237497ffe757SJohannes Berg 	case NL80211_IFTYPE_OCB:
237597ffe757SJohannes Berg 	case NL80211_IFTYPE_ADHOC:
237697ffe757SJohannes Berg 		if (is_multicast_ether_addr(skb->data)) {
237797ffe757SJohannes Berg 			*sta_out = ERR_PTR(-ENOENT);
237897ffe757SJohannes Berg 			return 0;
237997ffe757SJohannes Berg 		}
238097ffe757SJohannes Berg 		sta = sta_info_get_bss(sdata, skb->data);
238197ffe757SJohannes Berg 		break;
238297ffe757SJohannes Berg 	case NL80211_IFTYPE_WDS:
238397ffe757SJohannes Berg 		sta = sta_info_get(sdata, sdata->u.wds.remote_addr);
238497ffe757SJohannes Berg 		break;
238597ffe757SJohannes Berg #ifdef CONFIG_MAC80211_MESH
238697ffe757SJohannes Berg 	case NL80211_IFTYPE_MESH_POINT:
238797ffe757SJohannes Berg 		/* determined much later */
238897ffe757SJohannes Berg 		*sta_out = NULL;
238997ffe757SJohannes Berg 		return 0;
239097ffe757SJohannes Berg #endif
239197ffe757SJohannes Berg 	case NL80211_IFTYPE_STATION:
239297ffe757SJohannes Berg 		if (sdata->wdev.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) {
239397ffe757SJohannes Berg 			sta = sta_info_get(sdata, skb->data);
239411d62cafSJohannes Berg 			if (sta && test_sta_flag(sta, WLAN_STA_TDLS_PEER)) {
239511d62cafSJohannes Berg 				if (test_sta_flag(sta,
239611d62cafSJohannes Berg 						  WLAN_STA_TDLS_PEER_AUTH)) {
239797ffe757SJohannes Berg 					*sta_out = sta;
239897ffe757SJohannes Berg 					return 0;
239997ffe757SJohannes Berg 				}
240097ffe757SJohannes Berg 
240197ffe757SJohannes Berg 				/*
240297ffe757SJohannes Berg 				 * TDLS link during setup - throw out frames to
240397ffe757SJohannes Berg 				 * peer. Allow TDLS-setup frames to unauthorized
240497ffe757SJohannes Berg 				 * peers for the special case of a link teardown
240597ffe757SJohannes Berg 				 * after a TDLS sta is removed due to being
240697ffe757SJohannes Berg 				 * unreachable.
240797ffe757SJohannes Berg 				 */
240811d62cafSJohannes Berg 				if (!ieee80211_is_tdls_setup(skb))
240997ffe757SJohannes Berg 					return -EINVAL;
241097ffe757SJohannes Berg 			}
241197ffe757SJohannes Berg 
241297ffe757SJohannes Berg 		}
241397ffe757SJohannes Berg 
241497ffe757SJohannes Berg 		sta = sta_info_get(sdata, sdata->u.mgd.bssid);
241597ffe757SJohannes Berg 		if (!sta)
241697ffe757SJohannes Berg 			return -ENOLINK;
241797ffe757SJohannes Berg 		break;
241897ffe757SJohannes Berg 	default:
241997ffe757SJohannes Berg 		return -EINVAL;
242097ffe757SJohannes Berg 	}
242197ffe757SJohannes Berg 
242297ffe757SJohannes Berg 	*sta_out = sta ?: ERR_PTR(-ENOENT);
242397ffe757SJohannes Berg 	return 0;
2424ad38bfc9SMatti Gottlieb }
2425ad38bfc9SMatti Gottlieb 
2426e2ebc74dSJohannes Berg /**
24274c9451edSJohannes Berg  * ieee80211_build_hdr - build 802.11 header in the given frame
24284c9451edSJohannes Berg  * @sdata: virtual interface to build the header for
24294c9451edSJohannes Berg  * @skb: the skb to build the header in
243024d342c5SLiad Kaufman  * @info_flags: skb flags to set
243106016772SRajkumar Manoharan  * @ctrl_flags: info control flags to set
2432e2ebc74dSJohannes Berg  *
24334c9451edSJohannes Berg  * This function takes the skb with 802.3 header and reformats the header to
24344c9451edSJohannes Berg  * the appropriate IEEE 802.11 header based on which interface the packet is
24354c9451edSJohannes Berg  * being transmitted on.
2436e2ebc74dSJohannes Berg  *
24374c9451edSJohannes Berg  * Note that this function also takes care of the TX status request and
24384c9451edSJohannes Berg  * potential unsharing of the SKB - this needs to be interleaved with the
24394c9451edSJohannes Berg  * header building.
24404c9451edSJohannes Berg  *
24414c9451edSJohannes Berg  * The function requires the read-side RCU lock held
24424c9451edSJohannes Berg  *
24434c9451edSJohannes Berg  * Returns: the (possibly reallocated) skb or an ERR_PTR() code
2444e2ebc74dSJohannes Berg  */
24454c9451edSJohannes Berg static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
24467c10770fSJohannes Berg 					   struct sk_buff *skb, u32 info_flags,
244706016772SRajkumar Manoharan 					   struct sta_info *sta, u32 ctrl_flags)
2448e2ebc74dSJohannes Berg {
2449133b8226SJohannes Berg 	struct ieee80211_local *local = sdata->local;
2450489ee919SFelix Fietkau 	struct ieee80211_tx_info *info;
2451dcf33963SJohannes Berg 	int head_need;
2452065e9605SHarvey Harrison 	u16 ethertype, hdrlen,  meshhdrlen = 0;
2453065e9605SHarvey Harrison 	__le16 fc;
2454e2ebc74dSJohannes Berg 	struct ieee80211_hdr hdr;
2455ff67bb86SWey-Yi Guy 	struct ieee80211s_hdr mesh_hdr __maybe_unused;
2456b8bacc18SChun-Yeow Yeoh 	struct mesh_path __maybe_unused *mppath = NULL, *mpath = NULL;
2457e2ebc74dSJohannes Berg 	const u8 *encaps_data;
2458e2ebc74dSJohannes Berg 	int encaps_len, skip_header_bytes;
245997ffe757SJohannes Berg 	bool wme_sta = false, authorized = false;
246097ffe757SJohannes Berg 	bool tdls_peer;
2461a729cff8SJohannes Berg 	bool multicast;
2462a729cff8SJohannes Berg 	u16 info_id = 0;
246355de908aSJohannes Berg 	struct ieee80211_chanctx_conf *chanctx_conf;
246455de908aSJohannes Berg 	struct ieee80211_sub_if_data *ap_sdata;
246557fbcce3SJohannes Berg 	enum nl80211_band band;
24664c9451edSJohannes Berg 	int ret;
2467e2ebc74dSJohannes Berg 
246897ffe757SJohannes Berg 	if (IS_ERR(sta))
246997ffe757SJohannes Berg 		sta = NULL;
247097ffe757SJohannes Berg 
2471276d9e82SJulius Niedworok #ifdef CONFIG_MAC80211_DEBUGFS
2472276d9e82SJulius Niedworok 	if (local->force_tx_status)
2473276d9e82SJulius Niedworok 		info_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
2474276d9e82SJulius Niedworok #endif
2475276d9e82SJulius Niedworok 
2476e2ebc74dSJohannes Berg 	/* convert Ethernet header to proper 802.11 header (based on
2477e2ebc74dSJohannes Berg 	 * operation mode) */
2478e2ebc74dSJohannes Berg 	ethertype = (skb->data[12] << 8) | skb->data[13];
2479065e9605SHarvey Harrison 	fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA);
2480e2ebc74dSJohannes Berg 
248151fb61e7SJohannes Berg 	switch (sdata->vif.type) {
248205c914feSJohannes Berg 	case NL80211_IFTYPE_AP_VLAN:
248397ffe757SJohannes Berg 		if (sdata->wdev.use_4addr) {
2484f14543eeSFelix Fietkau 			fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
2485f14543eeSFelix Fietkau 			/* RA TA DA SA */
2486f14543eeSFelix Fietkau 			memcpy(hdr.addr1, sta->sta.addr, ETH_ALEN);
248747846c9bSJohannes Berg 			memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN);
2488f14543eeSFelix Fietkau 			memcpy(hdr.addr3, skb->data, ETH_ALEN);
2489f14543eeSFelix Fietkau 			memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
2490f14543eeSFelix Fietkau 			hdrlen = 30;
2491c2c98fdeSJohannes Berg 			authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
2492a74a8c84SJohannes Berg 			wme_sta = sta->sta.wme;
2493f14543eeSFelix Fietkau 		}
249455de908aSJohannes Berg 		ap_sdata = container_of(sdata->bss, struct ieee80211_sub_if_data,
249555de908aSJohannes Berg 					u.ap);
249655de908aSJohannes Berg 		chanctx_conf = rcu_dereference(ap_sdata->vif.chanctx_conf);
24974c9451edSJohannes Berg 		if (!chanctx_conf) {
24984c9451edSJohannes Berg 			ret = -ENOTCONN;
24994c9451edSJohannes Berg 			goto free;
25004c9451edSJohannes Berg 		}
25014bf88530SJohannes Berg 		band = chanctx_conf->def.chan->band;
250297ffe757SJohannes Berg 		if (sdata->wdev.use_4addr)
2503f14543eeSFelix Fietkau 			break;
2504f14543eeSFelix Fietkau 		/* fall through */
2505f14543eeSFelix Fietkau 	case NL80211_IFTYPE_AP:
2506fe80123dSArnd Bergmann 		if (sdata->vif.type == NL80211_IFTYPE_AP)
2507fe80123dSArnd Bergmann 			chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
25084c9451edSJohannes Berg 		if (!chanctx_conf) {
25094c9451edSJohannes Berg 			ret = -ENOTCONN;
25104c9451edSJohannes Berg 			goto free;
25114c9451edSJohannes Berg 		}
2512065e9605SHarvey Harrison 		fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
2513e2ebc74dSJohannes Berg 		/* DA BSSID SA */
2514e2ebc74dSJohannes Berg 		memcpy(hdr.addr1, skb->data, ETH_ALEN);
251547846c9bSJohannes Berg 		memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN);
2516e2ebc74dSJohannes Berg 		memcpy(hdr.addr3, skb->data + ETH_ALEN, ETH_ALEN);
2517e2ebc74dSJohannes Berg 		hdrlen = 24;
25184bf88530SJohannes Berg 		band = chanctx_conf->def.chan->band;
2519cf966838SJohannes Berg 		break;
252005c914feSJohannes Berg 	case NL80211_IFTYPE_WDS:
2521065e9605SHarvey Harrison 		fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
2522e2ebc74dSJohannes Berg 		/* RA TA DA SA */
2523e2ebc74dSJohannes Berg 		memcpy(hdr.addr1, sdata->u.wds.remote_addr, ETH_ALEN);
252447846c9bSJohannes Berg 		memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN);
2525e2ebc74dSJohannes Berg 		memcpy(hdr.addr3, skb->data, ETH_ALEN);
2526e2ebc74dSJohannes Berg 		memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
2527e2ebc74dSJohannes Berg 		hdrlen = 30;
252855de908aSJohannes Berg 		/*
252955de908aSJohannes Berg 		 * This is the exception! WDS style interfaces are prohibited
253055de908aSJohannes Berg 		 * when channel contexts are in used so this must be valid
253155de908aSJohannes Berg 		 */
2532675a0b04SKarl Beldan 		band = local->hw.conf.chandef.chan->band;
2533cf966838SJohannes Berg 		break;
253433b64eb2SLuis Carlos Cobo #ifdef CONFIG_MAC80211_MESH
253505c914feSJohannes Berg 	case NL80211_IFTYPE_MESH_POINT:
2536b8bacc18SChun-Yeow Yeoh 		if (!is_multicast_ether_addr(skb->data)) {
2537163df6cfSChun-Yeow Yeoh 			struct sta_info *next_hop;
2538163df6cfSChun-Yeow Yeoh 			bool mpp_lookup = true;
2539163df6cfSChun-Yeow Yeoh 
2540bf7cd94dSJohannes Berg 			mpath = mesh_path_lookup(sdata, skb->data);
2541163df6cfSChun-Yeow Yeoh 			if (mpath) {
2542163df6cfSChun-Yeow Yeoh 				mpp_lookup = false;
2543163df6cfSChun-Yeow Yeoh 				next_hop = rcu_dereference(mpath->next_hop);
2544163df6cfSChun-Yeow Yeoh 				if (!next_hop ||
2545163df6cfSChun-Yeow Yeoh 				    !(mpath->flags & (MESH_PATH_ACTIVE |
2546163df6cfSChun-Yeow Yeoh 						      MESH_PATH_RESOLVING)))
2547163df6cfSChun-Yeow Yeoh 					mpp_lookup = true;
2548163df6cfSChun-Yeow Yeoh 			}
2549163df6cfSChun-Yeow Yeoh 
2550ab1c7906SHenning Rogge 			if (mpp_lookup) {
2551bf7cd94dSJohannes Berg 				mppath = mpp_path_lookup(sdata, skb->data);
2552ab1c7906SHenning Rogge 				if (mppath)
2553ab1c7906SHenning Rogge 					mppath->exp_time = jiffies;
2554ab1c7906SHenning Rogge 			}
2555163df6cfSChun-Yeow Yeoh 
2556163df6cfSChun-Yeow Yeoh 			if (mppath && mpath)
25572bdaf386SBob Copeland 				mesh_path_del(sdata, mpath->dst);
2558b8bacc18SChun-Yeow Yeoh 		}
255979617deeSYanBo 
2560f76b57b4SJoel A Fernandes 		/*
25619d52501bSJoel A Fernandes 		 * Use address extension if it is a packet from
25629d52501bSJoel A Fernandes 		 * another interface or if we know the destination
25639d52501bSJoel A Fernandes 		 * is being proxied by a portal (i.e. portal address
25649d52501bSJoel A Fernandes 		 * differs from proxied address)
2565f76b57b4SJoel A Fernandes 		 */
2566b203ca39SJoe Perches 		if (ether_addr_equal(sdata->vif.addr, skb->data + ETH_ALEN) &&
2567b203ca39SJoe Perches 		    !(mppath && !ether_addr_equal(mppath->mpp, skb->data))) {
25683c5772a5SJavier Cardona 			hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc,
25693c5772a5SJavier Cardona 					skb->data, skb->data + ETH_ALEN);
2570bf7cd94dSJohannes Berg 			meshhdrlen = ieee80211_new_mesh_header(sdata, &mesh_hdr,
2571bf7cd94dSJohannes Berg 							       NULL, NULL);
257279617deeSYanBo 		} else {
257327f01124SThomas Pedersen 			/* DS -> MBSS (802.11-2012 13.11.3.3).
257427f01124SThomas Pedersen 			 * For unicast with unknown forwarding information,
257527f01124SThomas Pedersen 			 * destination might be in the MBSS or if that fails
257627f01124SThomas Pedersen 			 * forwarded to another mesh gate. In either case
257727f01124SThomas Pedersen 			 * resolution will be handled in ieee80211_xmit(), so
257827f01124SThomas Pedersen 			 * leave the original DA. This also works for mcast */
257927f01124SThomas Pedersen 			const u8 *mesh_da = skb->data;
258079617deeSYanBo 
258127f01124SThomas Pedersen 			if (mppath)
25823c5772a5SJavier Cardona 				mesh_da = mppath->mpp;
258327f01124SThomas Pedersen 			else if (mpath)
25847c41f315SChun-Yeow Yeoh 				mesh_da = mpath->dst;
258527f01124SThomas Pedersen 
25863c5772a5SJavier Cardona 			hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc,
258747846c9bSJohannes Berg 					mesh_da, sdata->vif.addr);
258827f01124SThomas Pedersen 			if (is_multicast_ether_addr(mesh_da))
258927f01124SThomas Pedersen 				/* DA TA mSA AE:SA */
2590bf7cd94dSJohannes Berg 				meshhdrlen = ieee80211_new_mesh_header(
2591bf7cd94dSJohannes Berg 						sdata, &mesh_hdr,
2592bf7cd94dSJohannes Berg 						skb->data + ETH_ALEN, NULL);
25933c5772a5SJavier Cardona 			else
259427f01124SThomas Pedersen 				/* RA TA mDA mSA AE:DA SA */
2595bf7cd94dSJohannes Berg 				meshhdrlen = ieee80211_new_mesh_header(
2596bf7cd94dSJohannes Berg 						sdata, &mesh_hdr, skb->data,
25973c5772a5SJavier Cardona 						skb->data + ETH_ALEN);
259879617deeSYanBo 
259979617deeSYanBo 		}
260055de908aSJohannes Berg 		chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
26014c9451edSJohannes Berg 		if (!chanctx_conf) {
26024c9451edSJohannes Berg 			ret = -ENOTCONN;
26034c9451edSJohannes Berg 			goto free;
26044c9451edSJohannes Berg 		}
26054bf88530SJohannes Berg 		band = chanctx_conf->def.chan->band;
26068828f81aSRajkumar Manoharan 
26078828f81aSRajkumar Manoharan 		/* For injected frames, fill RA right away as nexthop lookup
26088828f81aSRajkumar Manoharan 		 * will be skipped.
26098828f81aSRajkumar Manoharan 		 */
26108828f81aSRajkumar Manoharan 		if ((ctrl_flags & IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP) &&
26118828f81aSRajkumar Manoharan 		    is_zero_ether_addr(hdr.addr1))
26128828f81aSRajkumar Manoharan 			memcpy(hdr.addr1, skb->data, ETH_ALEN);
261333b64eb2SLuis Carlos Cobo 		break;
261433b64eb2SLuis Carlos Cobo #endif
261505c914feSJohannes Berg 	case NL80211_IFTYPE_STATION:
261697ffe757SJohannes Berg 		/* we already did checks when looking up the RA STA */
261797ffe757SJohannes Berg 		tdls_peer = test_sta_flag(sta, WLAN_STA_TDLS_PEER);
2618941c93cdSArik Nemtsov 
261997ffe757SJohannes Berg 		if (tdls_peer) {
2620941c93cdSArik Nemtsov 			/* DA SA BSSID */
2621941c93cdSArik Nemtsov 			memcpy(hdr.addr1, skb->data, ETH_ALEN);
2622941c93cdSArik Nemtsov 			memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
2623941c93cdSArik Nemtsov 			memcpy(hdr.addr3, sdata->u.mgd.bssid, ETH_ALEN);
2624941c93cdSArik Nemtsov 			hdrlen = 24;
2625941c93cdSArik Nemtsov 		}  else if (sdata->u.mgd.use_4addr &&
2626a621fa4dSJohannes Berg 			    cpu_to_be16(ethertype) != sdata->control_port_protocol) {
2627941c93cdSArik Nemtsov 			fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS |
2628941c93cdSArik Nemtsov 					  IEEE80211_FCTL_TODS);
2629f14543eeSFelix Fietkau 			/* RA TA DA SA */
2630941c93cdSArik Nemtsov 			memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN);
263147846c9bSJohannes Berg 			memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN);
2632f14543eeSFelix Fietkau 			memcpy(hdr.addr3, skb->data, ETH_ALEN);
2633f14543eeSFelix Fietkau 			memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
2634f14543eeSFelix Fietkau 			hdrlen = 30;
2635f14543eeSFelix Fietkau 		} else {
2636065e9605SHarvey Harrison 			fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
2637e2ebc74dSJohannes Berg 			/* BSSID SA DA */
2638941c93cdSArik Nemtsov 			memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN);
2639e2ebc74dSJohannes Berg 			memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
2640e2ebc74dSJohannes Berg 			memcpy(hdr.addr3, skb->data, ETH_ALEN);
2641e2ebc74dSJohannes Berg 			hdrlen = 24;
2642f14543eeSFelix Fietkau 		}
264355de908aSJohannes Berg 		chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
26444c9451edSJohannes Berg 		if (!chanctx_conf) {
26454c9451edSJohannes Berg 			ret = -ENOTCONN;
26464c9451edSJohannes Berg 			goto free;
26474c9451edSJohannes Berg 		}
26484bf88530SJohannes Berg 		band = chanctx_conf->def.chan->band;
2649cf966838SJohannes Berg 		break;
2650239281f8SRostislav Lisovy 	case NL80211_IFTYPE_OCB:
2651239281f8SRostislav Lisovy 		/* DA SA BSSID */
2652239281f8SRostislav Lisovy 		memcpy(hdr.addr1, skb->data, ETH_ALEN);
2653239281f8SRostislav Lisovy 		memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
2654239281f8SRostislav Lisovy 		eth_broadcast_addr(hdr.addr3);
2655239281f8SRostislav Lisovy 		hdrlen = 24;
2656239281f8SRostislav Lisovy 		chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
26574c9451edSJohannes Berg 		if (!chanctx_conf) {
26584c9451edSJohannes Berg 			ret = -ENOTCONN;
26594c9451edSJohannes Berg 			goto free;
26604c9451edSJohannes Berg 		}
2661239281f8SRostislav Lisovy 		band = chanctx_conf->def.chan->band;
2662239281f8SRostislav Lisovy 		break;
266305c914feSJohannes Berg 	case NL80211_IFTYPE_ADHOC:
2664e2ebc74dSJohannes Berg 		/* DA SA BSSID */
2665e2ebc74dSJohannes Berg 		memcpy(hdr.addr1, skb->data, ETH_ALEN);
2666e2ebc74dSJohannes Berg 		memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
266746900298SJohannes Berg 		memcpy(hdr.addr3, sdata->u.ibss.bssid, ETH_ALEN);
2668e2ebc74dSJohannes Berg 		hdrlen = 24;
266955de908aSJohannes Berg 		chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
26704c9451edSJohannes Berg 		if (!chanctx_conf) {
26714c9451edSJohannes Berg 			ret = -ENOTCONN;
26724c9451edSJohannes Berg 			goto free;
26734c9451edSJohannes Berg 		}
26744bf88530SJohannes Berg 		band = chanctx_conf->def.chan->band;
2675cf966838SJohannes Berg 		break;
2676cf966838SJohannes Berg 	default:
26774c9451edSJohannes Berg 		ret = -EINVAL;
26784c9451edSJohannes Berg 		goto free;
2679e2ebc74dSJohannes Berg 	}
2680e2ebc74dSJohannes Berg 
2681a729cff8SJohannes Berg 	multicast = is_multicast_ether_addr(hdr.addr1);
268297ffe757SJohannes Berg 
268397ffe757SJohannes Berg 	/* sta is always NULL for mesh */
2684c2c98fdeSJohannes Berg 	if (sta) {
2685c2c98fdeSJohannes Berg 		authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
2686a74a8c84SJohannes Berg 		wme_sta = sta->sta.wme;
268797ffe757SJohannes Berg 	} else if (ieee80211_vif_is_mesh(&sdata->vif)) {
26884777be41SJavier Cardona 		/* For mesh, the use of the QoS header is mandatory */
2689c2c98fdeSJohannes Berg 		wme_sta = true;
269097ffe757SJohannes Berg 	}
26914777be41SJavier Cardona 
2692527871d7SJohannes Berg 	/* receiver does QoS (which also means we do) use it */
2693527871d7SJohannes Berg 	if (wme_sta) {
2694065e9605SHarvey Harrison 		fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
2695e2ebc74dSJohannes Berg 		hdrlen += 2;
2696e2ebc74dSJohannes Berg 	}
2697ce3edf6dSJohannes Berg 
2698ce3edf6dSJohannes Berg 	/*
2699238814fdSJohannes Berg 	 * Drop unicast frames to unauthorised stations unless they are
2700238814fdSJohannes Berg 	 * EAPOL frames from the local station.
2701ce3edf6dSJohannes Berg 	 */
270255182e4aSJohannes Berg 	if (unlikely(!ieee80211_vif_is_mesh(&sdata->vif) &&
2703239281f8SRostislav Lisovy 		     (sdata->vif.type != NL80211_IFTYPE_OCB) &&
2704a6ececf4SSergey Ryazanov 		     !multicast && !authorized &&
270555182e4aSJohannes Berg 		     (cpu_to_be16(ethertype) != sdata->control_port_protocol ||
2706b203ca39SJoe Perches 		      !ether_addr_equal(sdata->vif.addr, skb->data + ETH_ALEN)))) {
2707ce3edf6dSJohannes Berg #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
2708bdcbd8e0SJohannes Berg 		net_info_ratelimited("%s: dropped frame to %pM (unauthorized port)\n",
27094c9451edSJohannes Berg 				    sdata->name, hdr.addr1);
2710ce3edf6dSJohannes Berg #endif
2711ce3edf6dSJohannes Berg 
2712ce3edf6dSJohannes Berg 		I802_DEBUG_INC(local->tx_handlers_drop_unauth_port);
2713ce3edf6dSJohannes Berg 
27144c9451edSJohannes Berg 		ret = -EPERM;
27154c9451edSJohannes Berg 		goto free;
2716e2ebc74dSJohannes Berg 	}
2717e2ebc74dSJohannes Berg 
2718a729cff8SJohannes Berg 	if (unlikely(!multicast && skb->sk &&
2719a729cff8SJohannes Berg 		     skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)) {
2720bf7fa551SAlexander Duyck 		struct sk_buff *ack_skb = skb_clone_sk(skb);
2721a729cff8SJohannes Berg 
2722bf7fa551SAlexander Duyck 		if (ack_skb) {
2723a729cff8SJohannes Berg 			unsigned long flags;
27249475af6eSTejun Heo 			int id;
2725a729cff8SJohannes Berg 
2726a729cff8SJohannes Berg 			spin_lock_irqsave(&local->ack_status_lock, flags);
2727bf7fa551SAlexander Duyck 			id = idr_alloc(&local->ack_status_frames, ack_skb,
27289475af6eSTejun Heo 				       1, 0x10000, GFP_ATOMIC);
2729a729cff8SJohannes Berg 			spin_unlock_irqrestore(&local->ack_status_lock, flags);
2730a729cff8SJohannes Berg 
27319475af6eSTejun Heo 			if (id >= 0) {
2732a729cff8SJohannes Berg 				info_id = id;
2733a729cff8SJohannes Berg 				info_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
2734a729cff8SJohannes Berg 			} else {
2735bf7fa551SAlexander Duyck 				kfree_skb(ack_skb);
2736a729cff8SJohannes Berg 			}
2737a729cff8SJohannes Berg 		}
2738a729cff8SJohannes Berg 	}
2739a729cff8SJohannes Berg 
27407e244707SHelmut Schaa 	/*
27417e244707SHelmut Schaa 	 * If the skb is shared we need to obtain our own copy.
27427e244707SHelmut Schaa 	 */
27437e244707SHelmut Schaa 	if (skb_shared(skb)) {
2744a729cff8SJohannes Berg 		struct sk_buff *tmp_skb = skb;
2745a729cff8SJohannes Berg 
2746a729cff8SJohannes Berg 		/* can't happen -- skb is a clone if info_id != 0 */
2747a729cff8SJohannes Berg 		WARN_ON(info_id);
2748a729cff8SJohannes Berg 
2749f8a0a781SFelix Fietkau 		skb = skb_clone(skb, GFP_ATOMIC);
27507e244707SHelmut Schaa 		kfree_skb(tmp_skb);
27517e244707SHelmut Schaa 
27524c9451edSJohannes Berg 		if (!skb) {
27534c9451edSJohannes Berg 			ret = -ENOMEM;
27544c9451edSJohannes Berg 			goto free;
27554c9451edSJohannes Berg 		}
27567e244707SHelmut Schaa 	}
27577e244707SHelmut Schaa 
2758065e9605SHarvey Harrison 	hdr.frame_control = fc;
2759e2ebc74dSJohannes Berg 	hdr.duration_id = 0;
2760e2ebc74dSJohannes Berg 	hdr.seq_ctrl = 0;
2761e2ebc74dSJohannes Berg 
2762e2ebc74dSJohannes Berg 	skip_header_bytes = ETH_HLEN;
2763e2ebc74dSJohannes Berg 	if (ethertype == ETH_P_AARP || ethertype == ETH_P_IPX) {
2764e2ebc74dSJohannes Berg 		encaps_data = bridge_tunnel_header;
2765e2ebc74dSJohannes Berg 		encaps_len = sizeof(bridge_tunnel_header);
2766e2ebc74dSJohannes Berg 		skip_header_bytes -= 2;
2767e5c5d22eSSimon Horman 	} else if (ethertype >= ETH_P_802_3_MIN) {
2768e2ebc74dSJohannes Berg 		encaps_data = rfc1042_header;
2769e2ebc74dSJohannes Berg 		encaps_len = sizeof(rfc1042_header);
2770e2ebc74dSJohannes Berg 		skip_header_bytes -= 2;
2771e2ebc74dSJohannes Berg 	} else {
2772e2ebc74dSJohannes Berg 		encaps_data = NULL;
2773e2ebc74dSJohannes Berg 		encaps_len = 0;
2774e2ebc74dSJohannes Berg 	}
2775e2ebc74dSJohannes Berg 
2776e2ebc74dSJohannes Berg 	skb_pull(skb, skip_header_bytes);
277723c0752aSJohannes Berg 	head_need = hdrlen + encaps_len + meshhdrlen - skb_headroom(skb);
2778e2ebc74dSJohannes Berg 
277923c0752aSJohannes Berg 	/*
278023c0752aSJohannes Berg 	 * So we need to modify the skb header and hence need a copy of
278123c0752aSJohannes Berg 	 * that. The head_need variable above doesn't, so far, include
278223c0752aSJohannes Berg 	 * the needed header space that we don't need right away. If we
278323c0752aSJohannes Berg 	 * can, then we don't reallocate right now but only after the
278423c0752aSJohannes Berg 	 * frame arrives at the master device (if it does...)
278523c0752aSJohannes Berg 	 *
278623c0752aSJohannes Berg 	 * If we cannot, however, then we will reallocate to include all
278723c0752aSJohannes Berg 	 * the ever needed space. Also, if we need to reallocate it anyway,
278823c0752aSJohannes Berg 	 * make it big enough for everything we may ever need.
278923c0752aSJohannes Berg 	 */
2790e2ebc74dSJohannes Berg 
27913a5be7d4SDavid S. Miller 	if (head_need > 0 || skb_cloned(skb)) {
27922475b1ccSMax Stepanov 		head_need += sdata->encrypt_headroom;
279323c0752aSJohannes Berg 		head_need += local->tx_headroom;
279423c0752aSJohannes Berg 		head_need = max_t(int, 0, head_need);
2795c3e7724bSFelix Fietkau 		if (ieee80211_skb_resize(sdata, skb, head_need, true)) {
2796c3e7724bSFelix Fietkau 			ieee80211_free_txskb(&local->hw, skb);
27971c963becSJohannes Berg 			skb = NULL;
27984c9451edSJohannes Berg 			return ERR_PTR(-ENOMEM);
2799c3e7724bSFelix Fietkau 		}
2800e2ebc74dSJohannes Berg 	}
2801e2ebc74dSJohannes Berg 
2802eae4430eSFelix Fietkau 	if (encaps_data)
2803e2ebc74dSJohannes Berg 		memcpy(skb_push(skb, encaps_len), encaps_data, encaps_len);
2804c29b9b9bSJohannes Berg 
2805e4ab7eb0SYuri Ershov #ifdef CONFIG_MAC80211_MESH
2806eae4430eSFelix Fietkau 	if (meshhdrlen > 0)
280733b64eb2SLuis Carlos Cobo 		memcpy(skb_push(skb, meshhdrlen), &mesh_hdr, meshhdrlen);
2808e4ab7eb0SYuri Ershov #endif
280933b64eb2SLuis Carlos Cobo 
2810065e9605SHarvey Harrison 	if (ieee80211_is_data_qos(fc)) {
2811c29b9b9bSJohannes Berg 		__le16 *qos_control;
2812c29b9b9bSJohannes Berg 
2813d58ff351SJohannes Berg 		qos_control = skb_push(skb, 2);
2814c29b9b9bSJohannes Berg 		memcpy(skb_push(skb, hdrlen - 2), &hdr, hdrlen - 2);
2815c29b9b9bSJohannes Berg 		/*
2816c29b9b9bSJohannes Berg 		 * Maybe we could actually set some fields here, for now just
2817c29b9b9bSJohannes Berg 		 * initialise to zero to indicate no special operation.
2818c29b9b9bSJohannes Berg 		 */
2819c29b9b9bSJohannes Berg 		*qos_control = 0;
2820c29b9b9bSJohannes Berg 	} else
2821e2ebc74dSJohannes Berg 		memcpy(skb_push(skb, hdrlen), &hdr, hdrlen);
2822c29b9b9bSJohannes Berg 
2823d57a544dSZhang Shengju 	skb_reset_mac_header(skb);
2824e2ebc74dSJohannes Berg 
2825489ee919SFelix Fietkau 	info = IEEE80211_SKB_CB(skb);
28263b8d81e0SJohannes Berg 	memset(info, 0, sizeof(*info));
28273b8d81e0SJohannes Berg 
2828a729cff8SJohannes Berg 	info->flags = info_flags;
2829a729cff8SJohannes Berg 	info->ack_frame_id = info_id;
283073c4e195SJohannes Berg 	info->band = band;
283106016772SRajkumar Manoharan 	info->control.flags = ctrl_flags;
2832a729cff8SJohannes Berg 
28334c9451edSJohannes Berg 	return skb;
28344c9451edSJohannes Berg  free:
28354c9451edSJohannes Berg 	kfree_skb(skb);
28364c9451edSJohannes Berg 	return ERR_PTR(ret);
2837e2ebc74dSJohannes Berg }
2838e2ebc74dSJohannes Berg 
283917c18bf8SJohannes Berg /*
284017c18bf8SJohannes Berg  * fast-xmit overview
284117c18bf8SJohannes Berg  *
284217c18bf8SJohannes Berg  * The core idea of this fast-xmit is to remove per-packet checks by checking
284317c18bf8SJohannes Berg  * them out of band. ieee80211_check_fast_xmit() implements the out-of-band
284417c18bf8SJohannes Berg  * checks that are needed to get the sta->fast_tx pointer assigned, after which
284517c18bf8SJohannes Berg  * much less work can be done per packet. For example, fragmentation must be
284617c18bf8SJohannes Berg  * disabled or the fast_tx pointer will not be set. All the conditions are seen
284717c18bf8SJohannes Berg  * in the code here.
284817c18bf8SJohannes Berg  *
284917c18bf8SJohannes Berg  * Once assigned, the fast_tx data structure also caches the per-packet 802.11
285017c18bf8SJohannes Berg  * header and other data to aid packet processing in ieee80211_xmit_fast().
285117c18bf8SJohannes Berg  *
285217c18bf8SJohannes Berg  * The most difficult part of this is that when any of these assumptions
285317c18bf8SJohannes Berg  * change, an external trigger (i.e. a call to ieee80211_clear_fast_xmit(),
285417c18bf8SJohannes Berg  * ieee80211_check_fast_xmit() or friends) is required to reset the data,
285517c18bf8SJohannes Berg  * since the per-packet code no longer checks the conditions. This is reflected
285617c18bf8SJohannes Berg  * by the calls to these functions throughout the rest of the code, and must be
285717c18bf8SJohannes Berg  * maintained if any of the TX path checks change.
285817c18bf8SJohannes Berg  */
285917c18bf8SJohannes Berg 
286017c18bf8SJohannes Berg void ieee80211_check_fast_xmit(struct sta_info *sta)
286117c18bf8SJohannes Berg {
286217c18bf8SJohannes Berg 	struct ieee80211_fast_tx build = {}, *fast_tx = NULL, *old;
286317c18bf8SJohannes Berg 	struct ieee80211_local *local = sta->local;
286417c18bf8SJohannes Berg 	struct ieee80211_sub_if_data *sdata = sta->sdata;
286517c18bf8SJohannes Berg 	struct ieee80211_hdr *hdr = (void *)build.hdr;
286617c18bf8SJohannes Berg 	struct ieee80211_chanctx_conf *chanctx_conf;
286717c18bf8SJohannes Berg 	__le16 fc;
286817c18bf8SJohannes Berg 
286930686bf7SJohannes Berg 	if (!ieee80211_hw_check(&local->hw, SUPPORT_FAST_XMIT))
287017c18bf8SJohannes Berg 		return;
287117c18bf8SJohannes Berg 
287217c18bf8SJohannes Berg 	/* Locking here protects both the pointer itself, and against concurrent
287317c18bf8SJohannes Berg 	 * invocations winning data access races to, e.g., the key pointer that
287417c18bf8SJohannes Berg 	 * is used.
287517c18bf8SJohannes Berg 	 * Without it, the invocation of this function right after the key
287617c18bf8SJohannes Berg 	 * pointer changes wouldn't be sufficient, as another CPU could access
287717c18bf8SJohannes Berg 	 * the pointer, then stall, and then do the cache update after the CPU
287817c18bf8SJohannes Berg 	 * that invalidated the key.
287917c18bf8SJohannes Berg 	 * With the locking, such scenarios cannot happen as the check for the
288017c18bf8SJohannes Berg 	 * key and the fast-tx assignment are done atomically, so the CPU that
288117c18bf8SJohannes Berg 	 * modifies the key will either wait or other one will see the key
288217c18bf8SJohannes Berg 	 * cleared/changed already.
288317c18bf8SJohannes Berg 	 */
288417c18bf8SJohannes Berg 	spin_lock_bh(&sta->lock);
288530686bf7SJohannes Berg 	if (ieee80211_hw_check(&local->hw, SUPPORTS_PS) &&
288630686bf7SJohannes Berg 	    !ieee80211_hw_check(&local->hw, SUPPORTS_DYNAMIC_PS) &&
288717c18bf8SJohannes Berg 	    sdata->vif.type == NL80211_IFTYPE_STATION)
288817c18bf8SJohannes Berg 		goto out;
288917c18bf8SJohannes Berg 
289017c18bf8SJohannes Berg 	if (!test_sta_flag(sta, WLAN_STA_AUTHORIZED))
289117c18bf8SJohannes Berg 		goto out;
289217c18bf8SJohannes Berg 
289317c18bf8SJohannes Berg 	if (test_sta_flag(sta, WLAN_STA_PS_STA) ||
289417c18bf8SJohannes Berg 	    test_sta_flag(sta, WLAN_STA_PS_DRIVER) ||
2895f7418bc1SFelix Fietkau 	    test_sta_flag(sta, WLAN_STA_PS_DELIVER) ||
2896f7418bc1SFelix Fietkau 	    test_sta_flag(sta, WLAN_STA_CLEAR_PS_FILT))
289717c18bf8SJohannes Berg 		goto out;
289817c18bf8SJohannes Berg 
289917c18bf8SJohannes Berg 	if (sdata->noack_map)
290017c18bf8SJohannes Berg 		goto out;
290117c18bf8SJohannes Berg 
290217c18bf8SJohannes Berg 	/* fast-xmit doesn't handle fragmentation at all */
2903725b812cSJohannes Berg 	if (local->hw.wiphy->frag_threshold != (u32)-1 &&
2904f3fe4e93SSara Sharon 	    !ieee80211_hw_check(&local->hw, SUPPORTS_TX_FRAG))
290517c18bf8SJohannes Berg 		goto out;
290617c18bf8SJohannes Berg 
290717c18bf8SJohannes Berg 	rcu_read_lock();
290817c18bf8SJohannes Berg 	chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
290917c18bf8SJohannes Berg 	if (!chanctx_conf) {
291017c18bf8SJohannes Berg 		rcu_read_unlock();
291117c18bf8SJohannes Berg 		goto out;
291217c18bf8SJohannes Berg 	}
291317c18bf8SJohannes Berg 	build.band = chanctx_conf->def.chan->band;
291417c18bf8SJohannes Berg 	rcu_read_unlock();
291517c18bf8SJohannes Berg 
291617c18bf8SJohannes Berg 	fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA);
291717c18bf8SJohannes Berg 
291817c18bf8SJohannes Berg 	switch (sdata->vif.type) {
29193ffd8840SJohannes Berg 	case NL80211_IFTYPE_ADHOC:
29203ffd8840SJohannes Berg 		/* DA SA BSSID */
29213ffd8840SJohannes Berg 		build.da_offs = offsetof(struct ieee80211_hdr, addr1);
29223ffd8840SJohannes Berg 		build.sa_offs = offsetof(struct ieee80211_hdr, addr2);
29233ffd8840SJohannes Berg 		memcpy(hdr->addr3, sdata->u.ibss.bssid, ETH_ALEN);
29243ffd8840SJohannes Berg 		build.hdr_len = 24;
29253ffd8840SJohannes Berg 		break;
292617c18bf8SJohannes Berg 	case NL80211_IFTYPE_STATION:
292717c18bf8SJohannes Berg 		if (test_sta_flag(sta, WLAN_STA_TDLS_PEER)) {
292817c18bf8SJohannes Berg 			/* DA SA BSSID */
292917c18bf8SJohannes Berg 			build.da_offs = offsetof(struct ieee80211_hdr, addr1);
293017c18bf8SJohannes Berg 			build.sa_offs = offsetof(struct ieee80211_hdr, addr2);
293117c18bf8SJohannes Berg 			memcpy(hdr->addr3, sdata->u.mgd.bssid, ETH_ALEN);
293217c18bf8SJohannes Berg 			build.hdr_len = 24;
293317c18bf8SJohannes Berg 			break;
293417c18bf8SJohannes Berg 		}
293517c18bf8SJohannes Berg 
293617c18bf8SJohannes Berg 		if (sdata->u.mgd.use_4addr) {
293717c18bf8SJohannes Berg 			/* non-regular ethertype cannot use the fastpath */
293817c18bf8SJohannes Berg 			fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS |
293917c18bf8SJohannes Berg 					  IEEE80211_FCTL_TODS);
294017c18bf8SJohannes Berg 			/* RA TA DA SA */
294117c18bf8SJohannes Berg 			memcpy(hdr->addr1, sdata->u.mgd.bssid, ETH_ALEN);
294217c18bf8SJohannes Berg 			memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
294317c18bf8SJohannes Berg 			build.da_offs = offsetof(struct ieee80211_hdr, addr3);
294417c18bf8SJohannes Berg 			build.sa_offs = offsetof(struct ieee80211_hdr, addr4);
294517c18bf8SJohannes Berg 			build.hdr_len = 30;
294617c18bf8SJohannes Berg 			break;
294717c18bf8SJohannes Berg 		}
294817c18bf8SJohannes Berg 		fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
294917c18bf8SJohannes Berg 		/* BSSID SA DA */
295017c18bf8SJohannes Berg 		memcpy(hdr->addr1, sdata->u.mgd.bssid, ETH_ALEN);
295117c18bf8SJohannes Berg 		build.da_offs = offsetof(struct ieee80211_hdr, addr3);
295217c18bf8SJohannes Berg 		build.sa_offs = offsetof(struct ieee80211_hdr, addr2);
295317c18bf8SJohannes Berg 		build.hdr_len = 24;
295417c18bf8SJohannes Berg 		break;
295517c18bf8SJohannes Berg 	case NL80211_IFTYPE_AP_VLAN:
295617c18bf8SJohannes Berg 		if (sdata->wdev.use_4addr) {
295717c18bf8SJohannes Berg 			fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS |
295817c18bf8SJohannes Berg 					  IEEE80211_FCTL_TODS);
295917c18bf8SJohannes Berg 			/* RA TA DA SA */
296017c18bf8SJohannes Berg 			memcpy(hdr->addr1, sta->sta.addr, ETH_ALEN);
296117c18bf8SJohannes Berg 			memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
296217c18bf8SJohannes Berg 			build.da_offs = offsetof(struct ieee80211_hdr, addr3);
296317c18bf8SJohannes Berg 			build.sa_offs = offsetof(struct ieee80211_hdr, addr4);
296417c18bf8SJohannes Berg 			build.hdr_len = 30;
296517c18bf8SJohannes Berg 			break;
296617c18bf8SJohannes Berg 		}
296717c18bf8SJohannes Berg 		/* fall through */
296817c18bf8SJohannes Berg 	case NL80211_IFTYPE_AP:
296917c18bf8SJohannes Berg 		fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
297017c18bf8SJohannes Berg 		/* DA BSSID SA */
297117c18bf8SJohannes Berg 		build.da_offs = offsetof(struct ieee80211_hdr, addr1);
297217c18bf8SJohannes Berg 		memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
297317c18bf8SJohannes Berg 		build.sa_offs = offsetof(struct ieee80211_hdr, addr3);
297417c18bf8SJohannes Berg 		build.hdr_len = 24;
297517c18bf8SJohannes Berg 		break;
297617c18bf8SJohannes Berg 	default:
297717c18bf8SJohannes Berg 		/* not handled on fast-xmit */
297817c18bf8SJohannes Berg 		goto out;
297917c18bf8SJohannes Berg 	}
298017c18bf8SJohannes Berg 
298117c18bf8SJohannes Berg 	if (sta->sta.wme) {
298217c18bf8SJohannes Berg 		build.hdr_len += 2;
298317c18bf8SJohannes Berg 		fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
298417c18bf8SJohannes Berg 	}
298517c18bf8SJohannes Berg 
298617c18bf8SJohannes Berg 	/* We store the key here so there's no point in using rcu_dereference()
298717c18bf8SJohannes Berg 	 * but that's fine because the code that changes the pointers will call
298817c18bf8SJohannes Berg 	 * this function after doing so. For a single CPU that would be enough,
298917c18bf8SJohannes Berg 	 * for multiple see the comment above.
299017c18bf8SJohannes Berg 	 */
299117c18bf8SJohannes Berg 	build.key = rcu_access_pointer(sta->ptk[sta->ptk_idx]);
299217c18bf8SJohannes Berg 	if (!build.key)
299317c18bf8SJohannes Berg 		build.key = rcu_access_pointer(sdata->default_unicast_key);
299417c18bf8SJohannes Berg 	if (build.key) {
2995e495c247SJohannes Berg 		bool gen_iv, iv_spc, mmic;
299617c18bf8SJohannes Berg 
299717c18bf8SJohannes Berg 		gen_iv = build.key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV;
299817c18bf8SJohannes Berg 		iv_spc = build.key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE;
29999de18d81SDavid Spinadel 		mmic = build.key->conf.flags &
30009de18d81SDavid Spinadel 			(IEEE80211_KEY_FLAG_GENERATE_MMIC |
30019de18d81SDavid Spinadel 			 IEEE80211_KEY_FLAG_PUT_MIC_SPACE);
300217c18bf8SJohannes Berg 
300317c18bf8SJohannes Berg 		/* don't handle software crypto */
300417c18bf8SJohannes Berg 		if (!(build.key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
300517c18bf8SJohannes Berg 			goto out;
300617c18bf8SJohannes Berg 
300762872a9bSAlexander Wetzel 		/* Key is being removed */
300862872a9bSAlexander Wetzel 		if (build.key->flags & KEY_FLAG_TAINTED)
300962872a9bSAlexander Wetzel 			goto out;
301062872a9bSAlexander Wetzel 
301117c18bf8SJohannes Berg 		switch (build.key->conf.cipher) {
301217c18bf8SJohannes Berg 		case WLAN_CIPHER_SUITE_CCMP:
301317c18bf8SJohannes Berg 		case WLAN_CIPHER_SUITE_CCMP_256:
301496fc6efbSAlexander Wetzel 			if (gen_iv)
301517c18bf8SJohannes Berg 				build.pn_offs = build.hdr_len;
301617c18bf8SJohannes Berg 			if (gen_iv || iv_spc)
301717c18bf8SJohannes Berg 				build.hdr_len += IEEE80211_CCMP_HDR_LEN;
301817c18bf8SJohannes Berg 			break;
301917c18bf8SJohannes Berg 		case WLAN_CIPHER_SUITE_GCMP:
302017c18bf8SJohannes Berg 		case WLAN_CIPHER_SUITE_GCMP_256:
302196fc6efbSAlexander Wetzel 			if (gen_iv)
302217c18bf8SJohannes Berg 				build.pn_offs = build.hdr_len;
302317c18bf8SJohannes Berg 			if (gen_iv || iv_spc)
302417c18bf8SJohannes Berg 				build.hdr_len += IEEE80211_GCMP_HDR_LEN;
302517c18bf8SJohannes Berg 			break;
3026e495c247SJohannes Berg 		case WLAN_CIPHER_SUITE_TKIP:
3027e495c247SJohannes Berg 			/* cannot handle MMIC or IV generation in xmit-fast */
3028e495c247SJohannes Berg 			if (mmic || gen_iv)
302917c18bf8SJohannes Berg 				goto out;
3030e495c247SJohannes Berg 			if (iv_spc)
3031e495c247SJohannes Berg 				build.hdr_len += IEEE80211_TKIP_IV_LEN;
3032e495c247SJohannes Berg 			break;
3033e495c247SJohannes Berg 		case WLAN_CIPHER_SUITE_WEP40:
3034e495c247SJohannes Berg 		case WLAN_CIPHER_SUITE_WEP104:
3035e495c247SJohannes Berg 			/* cannot handle IV generation in fast-xmit */
3036e495c247SJohannes Berg 			if (gen_iv)
3037e495c247SJohannes Berg 				goto out;
3038e495c247SJohannes Berg 			if (iv_spc)
3039e495c247SJohannes Berg 				build.hdr_len += IEEE80211_WEP_IV_LEN;
3040e495c247SJohannes Berg 			break;
3041e495c247SJohannes Berg 		case WLAN_CIPHER_SUITE_AES_CMAC:
3042e495c247SJohannes Berg 		case WLAN_CIPHER_SUITE_BIP_CMAC_256:
3043e495c247SJohannes Berg 		case WLAN_CIPHER_SUITE_BIP_GMAC_128:
3044e495c247SJohannes Berg 		case WLAN_CIPHER_SUITE_BIP_GMAC_256:
3045e495c247SJohannes Berg 			WARN(1,
3046e495c247SJohannes Berg 			     "management cipher suite 0x%x enabled for data\n",
3047e495c247SJohannes Berg 			     build.key->conf.cipher);
3048e495c247SJohannes Berg 			goto out;
3049e495c247SJohannes Berg 		default:
3050e495c247SJohannes Berg 			/* we don't know how to generate IVs for this at all */
3051e495c247SJohannes Berg 			if (WARN_ON(gen_iv))
3052e495c247SJohannes Berg 				goto out;
3053e495c247SJohannes Berg 			/* pure hardware keys are OK, of course */
3054e495c247SJohannes Berg 			if (!(build.key->flags & KEY_FLAG_CIPHER_SCHEME))
3055e495c247SJohannes Berg 				break;
3056e495c247SJohannes Berg 			/* cipher scheme might require space allocation */
3057e495c247SJohannes Berg 			if (iv_spc &&
3058e495c247SJohannes Berg 			    build.key->conf.iv_len > IEEE80211_FAST_XMIT_MAX_IV)
3059e495c247SJohannes Berg 				goto out;
3060e495c247SJohannes Berg 			if (iv_spc)
3061e495c247SJohannes Berg 				build.hdr_len += build.key->conf.iv_len;
306217c18bf8SJohannes Berg 		}
306317c18bf8SJohannes Berg 
306417c18bf8SJohannes Berg 		fc |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
306517c18bf8SJohannes Berg 	}
306617c18bf8SJohannes Berg 
306717c18bf8SJohannes Berg 	hdr->frame_control = fc;
306817c18bf8SJohannes Berg 
306917c18bf8SJohannes Berg 	memcpy(build.hdr + build.hdr_len,
307017c18bf8SJohannes Berg 	       rfc1042_header,  sizeof(rfc1042_header));
307117c18bf8SJohannes Berg 	build.hdr_len += sizeof(rfc1042_header);
307217c18bf8SJohannes Berg 
307317c18bf8SJohannes Berg 	fast_tx = kmemdup(&build, sizeof(build), GFP_ATOMIC);
307417c18bf8SJohannes Berg 	/* if the kmemdup fails, continue w/o fast_tx */
307517c18bf8SJohannes Berg 	if (!fast_tx)
307617c18bf8SJohannes Berg 		goto out;
307717c18bf8SJohannes Berg 
307817c18bf8SJohannes Berg  out:
307917c18bf8SJohannes Berg 	/* we might have raced against another call to this function */
308017c18bf8SJohannes Berg 	old = rcu_dereference_protected(sta->fast_tx,
308117c18bf8SJohannes Berg 					lockdep_is_held(&sta->lock));
308217c18bf8SJohannes Berg 	rcu_assign_pointer(sta->fast_tx, fast_tx);
308317c18bf8SJohannes Berg 	if (old)
308417c18bf8SJohannes Berg 		kfree_rcu(old, rcu_head);
308517c18bf8SJohannes Berg 	spin_unlock_bh(&sta->lock);
308617c18bf8SJohannes Berg }
308717c18bf8SJohannes Berg 
308817c18bf8SJohannes Berg void ieee80211_check_fast_xmit_all(struct ieee80211_local *local)
308917c18bf8SJohannes Berg {
309017c18bf8SJohannes Berg 	struct sta_info *sta;
309117c18bf8SJohannes Berg 
309217c18bf8SJohannes Berg 	rcu_read_lock();
309317c18bf8SJohannes Berg 	list_for_each_entry_rcu(sta, &local->sta_list, list)
309417c18bf8SJohannes Berg 		ieee80211_check_fast_xmit(sta);
309517c18bf8SJohannes Berg 	rcu_read_unlock();
309617c18bf8SJohannes Berg }
309717c18bf8SJohannes Berg 
309817c18bf8SJohannes Berg void ieee80211_check_fast_xmit_iface(struct ieee80211_sub_if_data *sdata)
309917c18bf8SJohannes Berg {
310017c18bf8SJohannes Berg 	struct ieee80211_local *local = sdata->local;
310117c18bf8SJohannes Berg 	struct sta_info *sta;
310217c18bf8SJohannes Berg 
310317c18bf8SJohannes Berg 	rcu_read_lock();
310417c18bf8SJohannes Berg 
310517c18bf8SJohannes Berg 	list_for_each_entry_rcu(sta, &local->sta_list, list) {
310617c18bf8SJohannes Berg 		if (sdata != sta->sdata &&
310717c18bf8SJohannes Berg 		    (!sta->sdata->bss || sta->sdata->bss != sdata->bss))
310817c18bf8SJohannes Berg 			continue;
310917c18bf8SJohannes Berg 		ieee80211_check_fast_xmit(sta);
311017c18bf8SJohannes Berg 	}
311117c18bf8SJohannes Berg 
311217c18bf8SJohannes Berg 	rcu_read_unlock();
311317c18bf8SJohannes Berg }
311417c18bf8SJohannes Berg 
311517c18bf8SJohannes Berg void ieee80211_clear_fast_xmit(struct sta_info *sta)
311617c18bf8SJohannes Berg {
311717c18bf8SJohannes Berg 	struct ieee80211_fast_tx *fast_tx;
311817c18bf8SJohannes Berg 
311917c18bf8SJohannes Berg 	spin_lock_bh(&sta->lock);
312017c18bf8SJohannes Berg 	fast_tx = rcu_dereference_protected(sta->fast_tx,
312117c18bf8SJohannes Berg 					    lockdep_is_held(&sta->lock));
312217c18bf8SJohannes Berg 	RCU_INIT_POINTER(sta->fast_tx, NULL);
312317c18bf8SJohannes Berg 	spin_unlock_bh(&sta->lock);
312417c18bf8SJohannes Berg 
312517c18bf8SJohannes Berg 	if (fast_tx)
312617c18bf8SJohannes Berg 		kfree_rcu(fast_tx, rcu_head);
312717c18bf8SJohannes Berg }
312817c18bf8SJohannes Berg 
31296e0456b5SFelix Fietkau static bool ieee80211_amsdu_realloc_pad(struct ieee80211_local *local,
3130166ac9d5SSara Sharon 					struct sk_buff *skb, int headroom)
31316e0456b5SFelix Fietkau {
3132166ac9d5SSara Sharon 	if (skb_headroom(skb) < headroom) {
31336e0456b5SFelix Fietkau 		I802_DEBUG_INC(local->tx_expand_skb_head);
31346e0456b5SFelix Fietkau 
3135166ac9d5SSara Sharon 		if (pskb_expand_head(skb, headroom, 0, GFP_ATOMIC)) {
31366e0456b5SFelix Fietkau 			wiphy_debug(local->hw.wiphy,
31376e0456b5SFelix Fietkau 				    "failed to reallocate TX buffer\n");
31386e0456b5SFelix Fietkau 			return false;
31396e0456b5SFelix Fietkau 		}
31406e0456b5SFelix Fietkau 	}
31416e0456b5SFelix Fietkau 
31426e0456b5SFelix Fietkau 	return true;
31436e0456b5SFelix Fietkau }
31446e0456b5SFelix Fietkau 
31456e0456b5SFelix Fietkau static bool ieee80211_amsdu_prepare_head(struct ieee80211_sub_if_data *sdata,
31466e0456b5SFelix Fietkau 					 struct ieee80211_fast_tx *fast_tx,
31476e0456b5SFelix Fietkau 					 struct sk_buff *skb)
31486e0456b5SFelix Fietkau {
31496e0456b5SFelix Fietkau 	struct ieee80211_local *local = sdata->local;
31506e0456b5SFelix Fietkau 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
31516e0456b5SFelix Fietkau 	struct ieee80211_hdr *hdr;
315206f2bb1eSMichael Braun 	struct ethhdr *amsdu_hdr;
31536e0456b5SFelix Fietkau 	int hdr_len = fast_tx->hdr_len - sizeof(rfc1042_header);
31546e0456b5SFelix Fietkau 	int subframe_len = skb->len - hdr_len;
31556e0456b5SFelix Fietkau 	void *data;
315606f2bb1eSMichael Braun 	u8 *qc, *h_80211_src, *h_80211_dst;
3157a3e2f4b6SMichael Braun 	const u8 *bssid;
31586e0456b5SFelix Fietkau 
31596e0456b5SFelix Fietkau 	if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)
31606e0456b5SFelix Fietkau 		return false;
31616e0456b5SFelix Fietkau 
31626e0456b5SFelix Fietkau 	if (info->control.flags & IEEE80211_TX_CTRL_AMSDU)
31636e0456b5SFelix Fietkau 		return true;
31646e0456b5SFelix Fietkau 
3165166ac9d5SSara Sharon 	if (!ieee80211_amsdu_realloc_pad(local, skb, sizeof(*amsdu_hdr)))
31666e0456b5SFelix Fietkau 		return false;
31676e0456b5SFelix Fietkau 
316806f2bb1eSMichael Braun 	data = skb_push(skb, sizeof(*amsdu_hdr));
316906f2bb1eSMichael Braun 	memmove(data, data + sizeof(*amsdu_hdr), hdr_len);
31706e0456b5SFelix Fietkau 	hdr = data;
317106f2bb1eSMichael Braun 	amsdu_hdr = data + hdr_len;
317206f2bb1eSMichael Braun 	/* h_80211_src/dst is addr* field within hdr */
317306f2bb1eSMichael Braun 	h_80211_src = data + fast_tx->sa_offs;
317406f2bb1eSMichael Braun 	h_80211_dst = data + fast_tx->da_offs;
317506f2bb1eSMichael Braun 
317606f2bb1eSMichael Braun 	amsdu_hdr->h_proto = cpu_to_be16(subframe_len);
317706f2bb1eSMichael Braun 	ether_addr_copy(amsdu_hdr->h_source, h_80211_src);
317806f2bb1eSMichael Braun 	ether_addr_copy(amsdu_hdr->h_dest, h_80211_dst);
317906f2bb1eSMichael Braun 
3180a3e2f4b6SMichael Braun 	/* according to IEEE 802.11-2012 8.3.2 table 8-19, the outer SA/DA
3181a3e2f4b6SMichael Braun 	 * fields needs to be changed to BSSID for A-MSDU frames depending
3182a3e2f4b6SMichael Braun 	 * on FromDS/ToDS values.
3183a3e2f4b6SMichael Braun 	 */
3184a3e2f4b6SMichael Braun 	switch (sdata->vif.type) {
3185a3e2f4b6SMichael Braun 	case NL80211_IFTYPE_STATION:
3186a3e2f4b6SMichael Braun 		bssid = sdata->u.mgd.bssid;
3187a3e2f4b6SMichael Braun 		break;
3188a3e2f4b6SMichael Braun 	case NL80211_IFTYPE_AP:
3189a3e2f4b6SMichael Braun 	case NL80211_IFTYPE_AP_VLAN:
3190a3e2f4b6SMichael Braun 		bssid = sdata->vif.addr;
3191a3e2f4b6SMichael Braun 		break;
3192a3e2f4b6SMichael Braun 	default:
3193a3e2f4b6SMichael Braun 		bssid = NULL;
3194a3e2f4b6SMichael Braun 	}
3195a3e2f4b6SMichael Braun 
3196a3e2f4b6SMichael Braun 	if (bssid && ieee80211_has_fromds(hdr->frame_control))
3197a3e2f4b6SMichael Braun 		ether_addr_copy(h_80211_src, bssid);
3198a3e2f4b6SMichael Braun 
3199a3e2f4b6SMichael Braun 	if (bssid && ieee80211_has_tods(hdr->frame_control))
3200a3e2f4b6SMichael Braun 		ether_addr_copy(h_80211_dst, bssid);
3201a3e2f4b6SMichael Braun 
32026e0456b5SFelix Fietkau 	qc = ieee80211_get_qos_ctl(hdr);
32036e0456b5SFelix Fietkau 	*qc |= IEEE80211_QOS_CTL_A_MSDU_PRESENT;
32046e0456b5SFelix Fietkau 
32056e0456b5SFelix Fietkau 	info->control.flags |= IEEE80211_TX_CTRL_AMSDU;
32066e0456b5SFelix Fietkau 
32076e0456b5SFelix Fietkau 	return true;
32086e0456b5SFelix Fietkau }
32096e0456b5SFelix Fietkau 
32106e0456b5SFelix Fietkau static bool ieee80211_amsdu_aggregate(struct ieee80211_sub_if_data *sdata,
32116e0456b5SFelix Fietkau 				      struct sta_info *sta,
32126e0456b5SFelix Fietkau 				      struct ieee80211_fast_tx *fast_tx,
32136e0456b5SFelix Fietkau 				      struct sk_buff *skb)
32146e0456b5SFelix Fietkau {
32156e0456b5SFelix Fietkau 	struct ieee80211_local *local = sdata->local;
3216fa962b92SMichal Kazior 	struct fq *fq = &local->fq;
3217fa962b92SMichal Kazior 	struct fq_tin *tin;
3218fa962b92SMichal Kazior 	struct fq_flow *flow;
32196e0456b5SFelix Fietkau 	u8 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
32206e0456b5SFelix Fietkau 	struct ieee80211_txq *txq = sta->sta.txq[tid];
32216e0456b5SFelix Fietkau 	struct txq_info *txqi;
32226e0456b5SFelix Fietkau 	struct sk_buff **frag_tail, *head;
32236e0456b5SFelix Fietkau 	int subframe_len = skb->len - ETH_ALEN;
32246e0456b5SFelix Fietkau 	u8 max_subframes = sta->sta.max_amsdu_subframes;
32256e0456b5SFelix Fietkau 	int max_frags = local->hw.max_tx_fragments;
32266e0456b5SFelix Fietkau 	int max_amsdu_len = sta->sta.max_amsdu_len;
3227eb9b64e3SFelix Fietkau 	int orig_truesize;
3228f2af2df8SFelix Fietkau 	u32 flow_idx;
32296e0456b5SFelix Fietkau 	__be16 len;
32306e0456b5SFelix Fietkau 	void *data;
32316e0456b5SFelix Fietkau 	bool ret = false;
3232fa962b92SMichal Kazior 	unsigned int orig_len;
323366eb02d8SLorenzo Bianconi 	int n = 2, nfrags, pad = 0;
3234166ac9d5SSara Sharon 	u16 hdrlen;
32356e0456b5SFelix Fietkau 
32366e0456b5SFelix Fietkau 	if (!ieee80211_hw_check(&local->hw, TX_AMSDU))
32376e0456b5SFelix Fietkau 		return false;
32386e0456b5SFelix Fietkau 
3239344f8e00SSara Sharon 	if (skb_is_gso(skb))
3240344f8e00SSara Sharon 		return false;
3241344f8e00SSara Sharon 
32426e0456b5SFelix Fietkau 	if (!txq)
32436e0456b5SFelix Fietkau 		return false;
32446e0456b5SFelix Fietkau 
32456e0456b5SFelix Fietkau 	txqi = to_txq_info(txq);
32466e0456b5SFelix Fietkau 	if (test_bit(IEEE80211_TXQ_NO_AMSDU, &txqi->flags))
32476e0456b5SFelix Fietkau 		return false;
32486e0456b5SFelix Fietkau 
32496e0456b5SFelix Fietkau 	if (sta->sta.max_rc_amsdu_len)
32506e0456b5SFelix Fietkau 		max_amsdu_len = min_t(int, max_amsdu_len,
32516e0456b5SFelix Fietkau 				      sta->sta.max_rc_amsdu_len);
32526e0456b5SFelix Fietkau 
3253edba6bdaSSara Sharon 	if (sta->sta.max_tid_amsdu_len[tid])
3254edba6bdaSSara Sharon 		max_amsdu_len = min_t(int, max_amsdu_len,
3255edba6bdaSSara Sharon 				      sta->sta.max_tid_amsdu_len[tid]);
3256edba6bdaSSara Sharon 
3257f2af2df8SFelix Fietkau 	flow_idx = fq_flow_idx(fq, skb);
3258f2af2df8SFelix Fietkau 
3259fa962b92SMichal Kazior 	spin_lock_bh(&fq->lock);
32606e0456b5SFelix Fietkau 
3261fa962b92SMichal Kazior 	/* TODO: Ideally aggregation should be done on dequeue to remain
3262fa962b92SMichal Kazior 	 * responsive to environment changes.
3263fa962b92SMichal Kazior 	 */
3264fa962b92SMichal Kazior 
3265fa962b92SMichal Kazior 	tin = &txqi->tin;
3266f2af2df8SFelix Fietkau 	flow = fq_flow_classify(fq, tin, flow_idx, skb,
3267f2af2df8SFelix Fietkau 				fq_flow_get_default_func);
3268fa962b92SMichal Kazior 	head = skb_peek_tail(&flow->queue);
3269344f8e00SSara Sharon 	if (!head || skb_is_gso(head))
32706e0456b5SFelix Fietkau 		goto out;
32716e0456b5SFelix Fietkau 
3272eb9b64e3SFelix Fietkau 	orig_truesize = head->truesize;
3273fa962b92SMichal Kazior 	orig_len = head->len;
3274fa962b92SMichal Kazior 
32756e0456b5SFelix Fietkau 	if (skb->len + head->len > max_amsdu_len)
32766e0456b5SFelix Fietkau 		goto out;
32776e0456b5SFelix Fietkau 
32786e0456b5SFelix Fietkau 	nfrags = 1 + skb_shinfo(skb)->nr_frags;
32796e0456b5SFelix Fietkau 	nfrags += 1 + skb_shinfo(head)->nr_frags;
32806e0456b5SFelix Fietkau 	frag_tail = &skb_shinfo(head)->frag_list;
32816e0456b5SFelix Fietkau 	while (*frag_tail) {
32826e0456b5SFelix Fietkau 		nfrags += 1 + skb_shinfo(*frag_tail)->nr_frags;
32836e0456b5SFelix Fietkau 		frag_tail = &(*frag_tail)->next;
32846e0456b5SFelix Fietkau 		n++;
32856e0456b5SFelix Fietkau 	}
32866e0456b5SFelix Fietkau 
32876e0456b5SFelix Fietkau 	if (max_subframes && n > max_subframes)
32886e0456b5SFelix Fietkau 		goto out;
32896e0456b5SFelix Fietkau 
32906e0456b5SFelix Fietkau 	if (max_frags && nfrags > max_frags)
32916e0456b5SFelix Fietkau 		goto out;
32926e0456b5SFelix Fietkau 
32939739fe29SSara Sharon 	if (!drv_can_aggregate_in_amsdu(local, head, skb))
32949739fe29SSara Sharon 		goto out;
32959739fe29SSara Sharon 
32961eb50790SLorenzo Bianconi 	if (!ieee80211_amsdu_prepare_head(sdata, fast_tx, head))
32976e0456b5SFelix Fietkau 		goto out;
32986e0456b5SFelix Fietkau 
3299166ac9d5SSara Sharon 	/*
3300166ac9d5SSara Sharon 	 * Pad out the previous subframe to a multiple of 4 by adding the
3301166ac9d5SSara Sharon 	 * padding to the next one, that's being added. Note that head->len
3302166ac9d5SSara Sharon 	 * is the length of the full A-MSDU, but that works since each time
3303166ac9d5SSara Sharon 	 * we add a new subframe we pad out the previous one to a multiple
3304166ac9d5SSara Sharon 	 * of 4 and thus it no longer matters in the next round.
3305166ac9d5SSara Sharon 	 */
3306166ac9d5SSara Sharon 	hdrlen = fast_tx->hdr_len - sizeof(rfc1042_header);
3307166ac9d5SSara Sharon 	if ((head->len - hdrlen) & 3)
3308166ac9d5SSara Sharon 		pad = 4 - ((head->len - hdrlen) & 3);
3309166ac9d5SSara Sharon 
3310166ac9d5SSara Sharon 	if (!ieee80211_amsdu_realloc_pad(local, skb, sizeof(rfc1042_header) +
3311166ac9d5SSara Sharon 						     2 + pad))
3312aa58acf3SJohannes Berg 		goto out_recalc;
33136e0456b5SFelix Fietkau 
33146e0456b5SFelix Fietkau 	ret = true;
33156e0456b5SFelix Fietkau 	data = skb_push(skb, ETH_ALEN + 2);
33166e0456b5SFelix Fietkau 	memmove(data, data + ETH_ALEN + 2, 2 * ETH_ALEN);
33176e0456b5SFelix Fietkau 
33186e0456b5SFelix Fietkau 	data += 2 * ETH_ALEN;
33196e0456b5SFelix Fietkau 	len = cpu_to_be16(subframe_len);
33206e0456b5SFelix Fietkau 	memcpy(data, &len, 2);
33216e0456b5SFelix Fietkau 	memcpy(data + 2, rfc1042_header, sizeof(rfc1042_header));
33226e0456b5SFelix Fietkau 
3323166ac9d5SSara Sharon 	memset(skb_push(skb, pad), 0, pad);
3324166ac9d5SSara Sharon 
33256e0456b5SFelix Fietkau 	head->len += skb->len;
33266e0456b5SFelix Fietkau 	head->data_len += skb->len;
33276e0456b5SFelix Fietkau 	*frag_tail = skb;
33286e0456b5SFelix Fietkau 
3329aa58acf3SJohannes Berg out_recalc:
3330eb9b64e3SFelix Fietkau 	fq->memory_usage += head->truesize - orig_truesize;
3331aa58acf3SJohannes Berg 	if (head->len != orig_len) {
3332fa962b92SMichal Kazior 		flow->backlog += head->len - orig_len;
3333fa962b92SMichal Kazior 		tin->backlog_bytes += head->len - orig_len;
3334fa962b92SMichal Kazior 
3335fa962b92SMichal Kazior 		fq_recalc_backlog(fq, tin, flow);
3336aa58acf3SJohannes Berg 	}
33376e0456b5SFelix Fietkau out:
3338fa962b92SMichal Kazior 	spin_unlock_bh(&fq->lock);
33396e0456b5SFelix Fietkau 
33406e0456b5SFelix Fietkau 	return ret;
33416e0456b5SFelix Fietkau }
33426e0456b5SFelix Fietkau 
3343bb42f2d1SToke Høiland-Jørgensen /*
3344bb42f2d1SToke Høiland-Jørgensen  * Can be called while the sta lock is held. Anything that can cause packets to
3345bb42f2d1SToke Høiland-Jørgensen  * be generated will cause deadlock!
3346bb42f2d1SToke Høiland-Jørgensen  */
3347bb42f2d1SToke Høiland-Jørgensen static void ieee80211_xmit_fast_finish(struct ieee80211_sub_if_data *sdata,
3348bb42f2d1SToke Høiland-Jørgensen 				       struct sta_info *sta, u8 pn_offs,
3349bb42f2d1SToke Høiland-Jørgensen 				       struct ieee80211_key *key,
3350bb42f2d1SToke Høiland-Jørgensen 				       struct sk_buff *skb)
3351bb42f2d1SToke Høiland-Jørgensen {
3352bb42f2d1SToke Høiland-Jørgensen 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
3353bb42f2d1SToke Høiland-Jørgensen 	struct ieee80211_hdr *hdr = (void *)skb->data;
3354bb42f2d1SToke Høiland-Jørgensen 	u8 tid = IEEE80211_NUM_TIDS;
3355bb42f2d1SToke Høiland-Jørgensen 
3356bb42f2d1SToke Høiland-Jørgensen 	if (key)
3357bb42f2d1SToke Høiland-Jørgensen 		info->control.hw_key = &key->conf;
3358bb42f2d1SToke Høiland-Jørgensen 
3359bb42f2d1SToke Høiland-Jørgensen 	ieee80211_tx_stats(skb->dev, skb->len);
3360bb42f2d1SToke Høiland-Jørgensen 
3361bb42f2d1SToke Høiland-Jørgensen 	if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) {
3362bb42f2d1SToke Høiland-Jørgensen 		tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
3363bb42f2d1SToke Høiland-Jørgensen 		hdr->seq_ctrl = ieee80211_tx_next_seq(sta, tid);
3364bb42f2d1SToke Høiland-Jørgensen 	} else {
3365bb42f2d1SToke Høiland-Jørgensen 		info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ;
3366bb42f2d1SToke Høiland-Jørgensen 		hdr->seq_ctrl = cpu_to_le16(sdata->sequence_number);
3367bb42f2d1SToke Høiland-Jørgensen 		sdata->sequence_number += 0x10;
3368bb42f2d1SToke Høiland-Jørgensen 	}
3369bb42f2d1SToke Høiland-Jørgensen 
3370bb42f2d1SToke Høiland-Jørgensen 	if (skb_shinfo(skb)->gso_size)
3371bb42f2d1SToke Høiland-Jørgensen 		sta->tx_stats.msdu[tid] +=
3372bb42f2d1SToke Høiland-Jørgensen 			DIV_ROUND_UP(skb->len, skb_shinfo(skb)->gso_size);
3373bb42f2d1SToke Høiland-Jørgensen 	else
3374bb42f2d1SToke Høiland-Jørgensen 		sta->tx_stats.msdu[tid]++;
3375bb42f2d1SToke Høiland-Jørgensen 
3376bb42f2d1SToke Høiland-Jørgensen 	info->hw_queue = sdata->vif.hw_queue[skb_get_queue_mapping(skb)];
3377bb42f2d1SToke Høiland-Jørgensen 
3378bb42f2d1SToke Høiland-Jørgensen 	/* statistics normally done by ieee80211_tx_h_stats (but that
3379bb42f2d1SToke Høiland-Jørgensen 	 * has to consider fragmentation, so is more complex)
3380bb42f2d1SToke Høiland-Jørgensen 	 */
3381bb42f2d1SToke Høiland-Jørgensen 	sta->tx_stats.bytes[skb_get_queue_mapping(skb)] += skb->len;
3382bb42f2d1SToke Høiland-Jørgensen 	sta->tx_stats.packets[skb_get_queue_mapping(skb)]++;
3383bb42f2d1SToke Høiland-Jørgensen 
3384bb42f2d1SToke Høiland-Jørgensen 	if (pn_offs) {
3385bb42f2d1SToke Høiland-Jørgensen 		u64 pn;
3386bb42f2d1SToke Høiland-Jørgensen 		u8 *crypto_hdr = skb->data + pn_offs;
3387bb42f2d1SToke Høiland-Jørgensen 
3388bb42f2d1SToke Høiland-Jørgensen 		switch (key->conf.cipher) {
3389bb42f2d1SToke Høiland-Jørgensen 		case WLAN_CIPHER_SUITE_CCMP:
3390bb42f2d1SToke Høiland-Jørgensen 		case WLAN_CIPHER_SUITE_CCMP_256:
3391bb42f2d1SToke Høiland-Jørgensen 		case WLAN_CIPHER_SUITE_GCMP:
3392bb42f2d1SToke Høiland-Jørgensen 		case WLAN_CIPHER_SUITE_GCMP_256:
3393bb42f2d1SToke Høiland-Jørgensen 			pn = atomic64_inc_return(&key->conf.tx_pn);
3394bb42f2d1SToke Høiland-Jørgensen 			crypto_hdr[0] = pn;
3395bb42f2d1SToke Høiland-Jørgensen 			crypto_hdr[1] = pn >> 8;
339696fc6efbSAlexander Wetzel 			crypto_hdr[3] = 0x20 | (key->conf.keyidx << 6);
3397bb42f2d1SToke Høiland-Jørgensen 			crypto_hdr[4] = pn >> 16;
3398bb42f2d1SToke Høiland-Jørgensen 			crypto_hdr[5] = pn >> 24;
3399bb42f2d1SToke Høiland-Jørgensen 			crypto_hdr[6] = pn >> 32;
3400bb42f2d1SToke Høiland-Jørgensen 			crypto_hdr[7] = pn >> 40;
3401bb42f2d1SToke Høiland-Jørgensen 			break;
3402bb42f2d1SToke Høiland-Jørgensen 		}
3403bb42f2d1SToke Høiland-Jørgensen 	}
3404bb42f2d1SToke Høiland-Jørgensen }
3405bb42f2d1SToke Høiland-Jørgensen 
340617c18bf8SJohannes Berg static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
3407bb42f2d1SToke Høiland-Jørgensen 				struct sta_info *sta,
340817c18bf8SJohannes Berg 				struct ieee80211_fast_tx *fast_tx,
340917c18bf8SJohannes Berg 				struct sk_buff *skb)
341017c18bf8SJohannes Berg {
341117c18bf8SJohannes Berg 	struct ieee80211_local *local = sdata->local;
341217c18bf8SJohannes Berg 	u16 ethertype = (skb->data[12] << 8) | skb->data[13];
341317c18bf8SJohannes Berg 	int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2);
341417c18bf8SJohannes Berg 	int hw_headroom = sdata->local->hw.extra_tx_headroom;
341517c18bf8SJohannes Berg 	struct ethhdr eth;
341635f432a0SJohannes Berg 	struct ieee80211_tx_info *info;
341717c18bf8SJohannes Berg 	struct ieee80211_hdr *hdr = (void *)fast_tx->hdr;
341817c18bf8SJohannes Berg 	struct ieee80211_tx_data tx;
341917c18bf8SJohannes Berg 	ieee80211_tx_result r;
342017c18bf8SJohannes Berg 	struct tid_ampdu_tx *tid_tx = NULL;
342117c18bf8SJohannes Berg 	u8 tid = IEEE80211_NUM_TIDS;
342217c18bf8SJohannes Berg 
342317c18bf8SJohannes Berg 	/* control port protocol needs a lot of special handling */
342417c18bf8SJohannes Berg 	if (cpu_to_be16(ethertype) == sdata->control_port_protocol)
342517c18bf8SJohannes Berg 		return false;
342617c18bf8SJohannes Berg 
342717c18bf8SJohannes Berg 	/* only RFC 1042 SNAP */
342817c18bf8SJohannes Berg 	if (ethertype < ETH_P_802_3_MIN)
342917c18bf8SJohannes Berg 		return false;
343017c18bf8SJohannes Berg 
343117c18bf8SJohannes Berg 	/* don't handle TX status request here either */
343217c18bf8SJohannes Berg 	if (skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)
343317c18bf8SJohannes Berg 		return false;
343417c18bf8SJohannes Berg 
343517c18bf8SJohannes Berg 	if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) {
343617c18bf8SJohannes Berg 		tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
343717c18bf8SJohannes Berg 		tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]);
3438472be00dSJohannes Berg 		if (tid_tx) {
3439472be00dSJohannes Berg 			if (!test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state))
344017c18bf8SJohannes Berg 				return false;
3441472be00dSJohannes Berg 			if (tid_tx->timeout)
3442472be00dSJohannes Berg 				tid_tx->last_tx = jiffies;
3443472be00dSJohannes Berg 		}
344417c18bf8SJohannes Berg 	}
344517c18bf8SJohannes Berg 
344617c18bf8SJohannes Berg 	/* after this point (skb is modified) we cannot return false */
344717c18bf8SJohannes Berg 
344817c18bf8SJohannes Berg 	if (skb_shared(skb)) {
344917c18bf8SJohannes Berg 		struct sk_buff *tmp_skb = skb;
345017c18bf8SJohannes Berg 
345117c18bf8SJohannes Berg 		skb = skb_clone(skb, GFP_ATOMIC);
345217c18bf8SJohannes Berg 		kfree_skb(tmp_skb);
345317c18bf8SJohannes Berg 
345417c18bf8SJohannes Berg 		if (!skb)
345517c18bf8SJohannes Berg 			return true;
345617c18bf8SJohannes Berg 	}
345717c18bf8SJohannes Berg 
34586e0456b5SFelix Fietkau 	if ((hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) &&
34596e0456b5SFelix Fietkau 	    ieee80211_amsdu_aggregate(sdata, sta, fast_tx, skb))
34606e0456b5SFelix Fietkau 		return true;
34616e0456b5SFelix Fietkau 
346217c18bf8SJohannes Berg 	/* will not be crypto-handled beyond what we do here, so use false
346317c18bf8SJohannes Berg 	 * as the may-encrypt argument for the resize to not account for
346417c18bf8SJohannes Berg 	 * more room than we already have in 'extra_head'
346517c18bf8SJohannes Berg 	 */
346617c18bf8SJohannes Berg 	if (unlikely(ieee80211_skb_resize(sdata, skb,
346717c18bf8SJohannes Berg 					  max_t(int, extra_head + hw_headroom -
346817c18bf8SJohannes Berg 						     skb_headroom(skb), 0),
346917c18bf8SJohannes Berg 					  false))) {
347017c18bf8SJohannes Berg 		kfree_skb(skb);
347117c18bf8SJohannes Berg 		return true;
347217c18bf8SJohannes Berg 	}
347317c18bf8SJohannes Berg 
347417c18bf8SJohannes Berg 	memcpy(&eth, skb->data, ETH_HLEN - 2);
3475d58ff351SJohannes Berg 	hdr = skb_push(skb, extra_head);
347617c18bf8SJohannes Berg 	memcpy(skb->data, fast_tx->hdr, fast_tx->hdr_len);
347717c18bf8SJohannes Berg 	memcpy(skb->data + fast_tx->da_offs, eth.h_dest, ETH_ALEN);
347817c18bf8SJohannes Berg 	memcpy(skb->data + fast_tx->sa_offs, eth.h_source, ETH_ALEN);
347917c18bf8SJohannes Berg 
348035f432a0SJohannes Berg 	info = IEEE80211_SKB_CB(skb);
348117c18bf8SJohannes Berg 	memset(info, 0, sizeof(*info));
348217c18bf8SJohannes Berg 	info->band = fast_tx->band;
348317c18bf8SJohannes Berg 	info->control.vif = &sdata->vif;
348417c18bf8SJohannes Berg 	info->flags = IEEE80211_TX_CTL_FIRST_FRAGMENT |
348517c18bf8SJohannes Berg 		      IEEE80211_TX_CTL_DONTFRAG |
348617c18bf8SJohannes Berg 		      (tid_tx ? IEEE80211_TX_CTL_AMPDU : 0);
3487bb42f2d1SToke Høiland-Jørgensen 	info->control.flags = IEEE80211_TX_CTRL_FAST_XMIT;
348817c18bf8SJohannes Berg 
3489276d9e82SJulius Niedworok #ifdef CONFIG_MAC80211_DEBUGFS
3490276d9e82SJulius Niedworok 	if (local->force_tx_status)
3491276d9e82SJulius Niedworok 		info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
3492276d9e82SJulius Niedworok #endif
3493276d9e82SJulius Niedworok 
3494a786f96dSFelix Fietkau 	if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) {
3495a786f96dSFelix Fietkau 		tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
3496a786f96dSFelix Fietkau 		*ieee80211_get_qos_ctl(hdr) = tid;
3497a786f96dSFelix Fietkau 	}
3498a786f96dSFelix Fietkau 
349917c18bf8SJohannes Berg 	__skb_queue_head_init(&tx.skbs);
350017c18bf8SJohannes Berg 
350117c18bf8SJohannes Berg 	tx.flags = IEEE80211_TX_UNICAST;
350217c18bf8SJohannes Berg 	tx.local = local;
350317c18bf8SJohannes Berg 	tx.sdata = sdata;
350417c18bf8SJohannes Berg 	tx.sta = sta;
350517c18bf8SJohannes Berg 	tx.key = fast_tx->key;
350617c18bf8SJohannes Berg 
350730686bf7SJohannes Berg 	if (!ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL)) {
350817c18bf8SJohannes Berg 		tx.skb = skb;
350917c18bf8SJohannes Berg 		r = ieee80211_tx_h_rate_ctrl(&tx);
351017c18bf8SJohannes Berg 		skb = tx.skb;
351117c18bf8SJohannes Berg 		tx.skb = NULL;
351217c18bf8SJohannes Berg 
351317c18bf8SJohannes Berg 		if (r != TX_CONTINUE) {
351417c18bf8SJohannes Berg 			if (r != TX_QUEUED)
351517c18bf8SJohannes Berg 				kfree_skb(skb);
351617c18bf8SJohannes Berg 			return true;
351717c18bf8SJohannes Berg 		}
351817c18bf8SJohannes Berg 	}
351917c18bf8SJohannes Berg 
3520bb42f2d1SToke Høiland-Jørgensen 	if (ieee80211_queue_skb(local, sdata, sta, skb))
3521bb42f2d1SToke Høiland-Jørgensen 		return true;
352217c18bf8SJohannes Berg 
3523bb42f2d1SToke Høiland-Jørgensen 	ieee80211_xmit_fast_finish(sdata, sta, fast_tx->pn_offs,
3524bb42f2d1SToke Høiland-Jørgensen 				   fast_tx->key, skb);
352517c18bf8SJohannes Berg 
352617c18bf8SJohannes Berg 	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
352717c18bf8SJohannes Berg 		sdata = container_of(sdata->bss,
352817c18bf8SJohannes Berg 				     struct ieee80211_sub_if_data, u.ap);
352917c18bf8SJohannes Berg 
353017c18bf8SJohannes Berg 	__skb_queue_tail(&tx.skbs, skb);
353117c18bf8SJohannes Berg 	ieee80211_tx_frags(local, &sdata->vif, &sta->sta, &tx.skbs, false);
353217c18bf8SJohannes Berg 	return true;
353317c18bf8SJohannes Berg }
353417c18bf8SJohannes Berg 
3535e0e2efffSToke Høiland-Jørgensen struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
3536e0e2efffSToke Høiland-Jørgensen 				     struct ieee80211_txq *txq)
3537e0e2efffSToke Høiland-Jørgensen {
3538e0e2efffSToke Høiland-Jørgensen 	struct ieee80211_local *local = hw_to_local(hw);
3539e0e2efffSToke Høiland-Jørgensen 	struct txq_info *txqi = container_of(txq, struct txq_info, txq);
3540e0e2efffSToke Høiland-Jørgensen 	struct ieee80211_hdr *hdr;
3541e0e2efffSToke Høiland-Jørgensen 	struct sk_buff *skb = NULL;
3542e0e2efffSToke Høiland-Jørgensen 	struct fq *fq = &local->fq;
3543e0e2efffSToke Høiland-Jørgensen 	struct fq_tin *tin = &txqi->tin;
3544bb42f2d1SToke Høiland-Jørgensen 	struct ieee80211_tx_info *info;
3545bb42f2d1SToke Høiland-Jørgensen 	struct ieee80211_tx_data tx;
3546bb42f2d1SToke Høiland-Jørgensen 	ieee80211_tx_result r;
354721a5d4c3SManikanta Pubbisetty 	struct ieee80211_vif *vif = txq->vif;
3548e0e2efffSToke Høiland-Jørgensen 
3549ded4698bSFelix Fietkau begin:
3550e0e2efffSToke Høiland-Jørgensen 	spin_lock_bh(&fq->lock);
3551e0e2efffSToke Høiland-Jørgensen 
355221a5d4c3SManikanta Pubbisetty 	if (test_bit(IEEE80211_TXQ_STOP, &txqi->flags) ||
355321a5d4c3SManikanta Pubbisetty 	    test_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txqi->flags))
3554e0e2efffSToke Høiland-Jørgensen 		goto out;
3555e0e2efffSToke Høiland-Jørgensen 
355621a5d4c3SManikanta Pubbisetty 	if (vif->txqs_stopped[ieee80211_ac_from_tid(txq->tid)]) {
355721a5d4c3SManikanta Pubbisetty 		set_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txqi->flags);
355821a5d4c3SManikanta Pubbisetty 		goto out;
355921a5d4c3SManikanta Pubbisetty 	}
356021a5d4c3SManikanta Pubbisetty 
3561bb42f2d1SToke Høiland-Jørgensen 	/* Make sure fragments stay together. */
3562bb42f2d1SToke Høiland-Jørgensen 	skb = __skb_dequeue(&txqi->frags);
3563bb42f2d1SToke Høiland-Jørgensen 	if (skb)
3564bb42f2d1SToke Høiland-Jørgensen 		goto out;
3565bb42f2d1SToke Høiland-Jørgensen 
3566e0e2efffSToke Høiland-Jørgensen 	skb = fq_tin_dequeue(fq, tin, fq_tin_dequeue_func);
3567e0e2efffSToke Høiland-Jørgensen 	if (!skb)
3568e0e2efffSToke Høiland-Jørgensen 		goto out;
3569e0e2efffSToke Høiland-Jørgensen 
3570ded4698bSFelix Fietkau 	spin_unlock_bh(&fq->lock);
3571ded4698bSFelix Fietkau 
3572e0e2efffSToke Høiland-Jørgensen 	hdr = (struct ieee80211_hdr *)skb->data;
3573bb42f2d1SToke Høiland-Jørgensen 	info = IEEE80211_SKB_CB(skb);
3574bb42f2d1SToke Høiland-Jørgensen 
3575bb42f2d1SToke Høiland-Jørgensen 	memset(&tx, 0, sizeof(tx));
3576bb42f2d1SToke Høiland-Jørgensen 	__skb_queue_head_init(&tx.skbs);
3577bb42f2d1SToke Høiland-Jørgensen 	tx.local = local;
3578bb42f2d1SToke Høiland-Jørgensen 	tx.skb = skb;
3579bb42f2d1SToke Høiland-Jørgensen 	tx.sdata = vif_to_sdata(info->control.vif);
3580bb42f2d1SToke Høiland-Jørgensen 
3581bb42f2d1SToke Høiland-Jørgensen 	if (txq->sta)
3582bb42f2d1SToke Høiland-Jørgensen 		tx.sta = container_of(txq->sta, struct sta_info, sta);
3583bb42f2d1SToke Høiland-Jørgensen 
3584bb42f2d1SToke Høiland-Jørgensen 	/*
3585bb42f2d1SToke Høiland-Jørgensen 	 * The key can be removed while the packet was queued, so need to call
3586bb42f2d1SToke Høiland-Jørgensen 	 * this here to get the current key.
3587bb42f2d1SToke Høiland-Jørgensen 	 */
3588bb42f2d1SToke Høiland-Jørgensen 	r = ieee80211_tx_h_select_key(&tx);
3589bb42f2d1SToke Høiland-Jørgensen 	if (r != TX_CONTINUE) {
3590bb42f2d1SToke Høiland-Jørgensen 		ieee80211_free_txskb(&local->hw, skb);
3591bb42f2d1SToke Høiland-Jørgensen 		goto begin;
3592bb42f2d1SToke Høiland-Jørgensen 	}
3593bb42f2d1SToke Høiland-Jørgensen 
3594c1f4c9edSFelix Fietkau 	if (test_bit(IEEE80211_TXQ_AMPDU, &txqi->flags))
3595c1f4c9edSFelix Fietkau 		info->flags |= IEEE80211_TX_CTL_AMPDU;
3596c1f4c9edSFelix Fietkau 	else
3597c1f4c9edSFelix Fietkau 		info->flags &= ~IEEE80211_TX_CTL_AMPDU;
3598c1f4c9edSFelix Fietkau 
3599bb42f2d1SToke Høiland-Jørgensen 	if (info->control.flags & IEEE80211_TX_CTRL_FAST_XMIT) {
3600e0e2efffSToke Høiland-Jørgensen 		struct sta_info *sta = container_of(txq->sta, struct sta_info,
3601e0e2efffSToke Høiland-Jørgensen 						    sta);
3602bb42f2d1SToke Høiland-Jørgensen 		u8 pn_offs = 0;
3603e0e2efffSToke Høiland-Jørgensen 
3604bb42f2d1SToke Høiland-Jørgensen 		if (tx.key &&
3605bb42f2d1SToke Høiland-Jørgensen 		    (tx.key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV))
3606bb42f2d1SToke Høiland-Jørgensen 			pn_offs = ieee80211_hdrlen(hdr->frame_control);
3607bb42f2d1SToke Høiland-Jørgensen 
3608bb42f2d1SToke Høiland-Jørgensen 		ieee80211_xmit_fast_finish(sta->sdata, sta, pn_offs,
3609bb42f2d1SToke Høiland-Jørgensen 					   tx.key, skb);
3610bb42f2d1SToke Høiland-Jørgensen 	} else {
3611bb42f2d1SToke Høiland-Jørgensen 		if (invoke_tx_handlers_late(&tx))
3612bb42f2d1SToke Høiland-Jørgensen 			goto begin;
3613bb42f2d1SToke Høiland-Jørgensen 
3614bb42f2d1SToke Høiland-Jørgensen 		skb = __skb_dequeue(&tx.skbs);
3615bb42f2d1SToke Høiland-Jørgensen 
3616ded4698bSFelix Fietkau 		if (!skb_queue_empty(&tx.skbs)) {
3617ded4698bSFelix Fietkau 			spin_lock_bh(&fq->lock);
3618bb42f2d1SToke Høiland-Jørgensen 			skb_queue_splice_tail(&tx.skbs, &txqi->frags);
3619ded4698bSFelix Fietkau 			spin_unlock_bh(&fq->lock);
3620ded4698bSFelix Fietkau 		}
3621e0e2efffSToke Høiland-Jørgensen 	}
3622e0e2efffSToke Høiland-Jørgensen 
3623233e98dcSJohannes Berg 	if (skb_has_frag_list(skb) &&
36241e1430d5SJohannes Berg 	    !ieee80211_hw_check(&local->hw, TX_FRAG_LIST)) {
36251e1430d5SJohannes Berg 		if (skb_linearize(skb)) {
36261e1430d5SJohannes Berg 			ieee80211_free_txskb(&local->hw, skb);
36271e1430d5SJohannes Berg 			goto begin;
36281e1430d5SJohannes Berg 		}
36291e1430d5SJohannes Berg 	}
36301e1430d5SJohannes Berg 
363153168215SJohannes Berg 	switch (tx.sdata->vif.type) {
363253168215SJohannes Berg 	case NL80211_IFTYPE_MONITOR:
363353168215SJohannes Berg 		if (tx.sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) {
363453168215SJohannes Berg 			vif = &tx.sdata->vif;
363553168215SJohannes Berg 			break;
363653168215SJohannes Berg 		}
363753168215SJohannes Berg 		tx.sdata = rcu_dereference(local->monitor_sdata);
363853168215SJohannes Berg 		if (tx.sdata) {
363953168215SJohannes Berg 			vif = &tx.sdata->vif;
364053168215SJohannes Berg 			info->hw_queue =
364153168215SJohannes Berg 				vif->hw_queue[skb_get_queue_mapping(skb)];
364253168215SJohannes Berg 		} else if (ieee80211_hw_check(&local->hw, QUEUE_CONTROL)) {
364353168215SJohannes Berg 			ieee80211_free_txskb(&local->hw, skb);
364453168215SJohannes Berg 			goto begin;
364553168215SJohannes Berg 		} else {
364653168215SJohannes Berg 			vif = NULL;
364753168215SJohannes Berg 		}
364853168215SJohannes Berg 		break;
364953168215SJohannes Berg 	case NL80211_IFTYPE_AP_VLAN:
365053168215SJohannes Berg 		tx.sdata = container_of(tx.sdata->bss,
365153168215SJohannes Berg 					struct ieee80211_sub_if_data, u.ap);
365253168215SJohannes Berg 		/* fall through */
365353168215SJohannes Berg 	default:
365453168215SJohannes Berg 		vif = &tx.sdata->vif;
365553168215SJohannes Berg 		break;
365653168215SJohannes Berg 	}
365753168215SJohannes Berg 
365853168215SJohannes Berg 	IEEE80211_SKB_CB(skb)->control.vif = vif;
3659ded4698bSFelix Fietkau 	return skb;
366021a5d4c3SManikanta Pubbisetty 
3661e0e2efffSToke Høiland-Jørgensen out:
3662e0e2efffSToke Høiland-Jørgensen 	spin_unlock_bh(&fq->lock);
3663e0e2efffSToke Høiland-Jørgensen 
3664e0e2efffSToke Høiland-Jørgensen 	return skb;
3665e0e2efffSToke Høiland-Jørgensen }
3666e0e2efffSToke Høiland-Jørgensen EXPORT_SYMBOL(ieee80211_tx_dequeue);
3667e0e2efffSToke Høiland-Jørgensen 
366818667600SToke Høiland-Jørgensen struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac)
366918667600SToke Høiland-Jørgensen {
367018667600SToke Høiland-Jørgensen 	struct ieee80211_local *local = hw_to_local(hw);
36715b989c18SFelix Fietkau 	struct ieee80211_txq *ret = NULL;
367218667600SToke Høiland-Jørgensen 	struct txq_info *txqi = NULL;
367318667600SToke Høiland-Jørgensen 
36745b989c18SFelix Fietkau 	spin_lock_bh(&local->active_txq_lock[ac]);
367518667600SToke Høiland-Jørgensen 
3676b4809e94SToke Høiland-Jørgensen  begin:
367718667600SToke Høiland-Jørgensen 	txqi = list_first_entry_or_null(&local->active_txqs[ac],
367818667600SToke Høiland-Jørgensen 					struct txq_info,
367918667600SToke Høiland-Jørgensen 					schedule_order);
3680b4809e94SToke Høiland-Jørgensen 	if (!txqi)
36815b989c18SFelix Fietkau 		goto out;
368218667600SToke Høiland-Jørgensen 
3683b4809e94SToke Høiland-Jørgensen 	if (txqi->txq.sta) {
3684b4809e94SToke Høiland-Jørgensen 		struct sta_info *sta = container_of(txqi->txq.sta,
3685b4809e94SToke Høiland-Jørgensen 						struct sta_info, sta);
3686b4809e94SToke Høiland-Jørgensen 
3687b4809e94SToke Høiland-Jørgensen 		if (sta->airtime[txqi->txq.ac].deficit < 0) {
3688b4809e94SToke Høiland-Jørgensen 			sta->airtime[txqi->txq.ac].deficit +=
3689b4809e94SToke Høiland-Jørgensen 				sta->airtime_weight;
3690b4809e94SToke Høiland-Jørgensen 			list_move_tail(&txqi->schedule_order,
3691b4809e94SToke Høiland-Jørgensen 				       &local->active_txqs[txqi->txq.ac]);
3692b4809e94SToke Høiland-Jørgensen 			goto begin;
3693b4809e94SToke Høiland-Jørgensen 		}
3694b4809e94SToke Høiland-Jørgensen 	}
3695b4809e94SToke Høiland-Jørgensen 
3696b4809e94SToke Høiland-Jørgensen 
3697b4809e94SToke Høiland-Jørgensen 	if (txqi->schedule_round == local->schedule_round[ac])
36985b989c18SFelix Fietkau 		goto out;
369918667600SToke Høiland-Jørgensen 
370018667600SToke Høiland-Jørgensen 	list_del_init(&txqi->schedule_order);
370118667600SToke Høiland-Jørgensen 	txqi->schedule_round = local->schedule_round[ac];
37025b989c18SFelix Fietkau 	ret = &txqi->txq;
37035b989c18SFelix Fietkau 
37045b989c18SFelix Fietkau out:
37055b989c18SFelix Fietkau 	spin_unlock_bh(&local->active_txq_lock[ac]);
37065b989c18SFelix Fietkau 	return ret;
370718667600SToke Høiland-Jørgensen }
370818667600SToke Høiland-Jørgensen EXPORT_SYMBOL(ieee80211_next_txq);
370918667600SToke Høiland-Jørgensen 
37102b4a6698SFelix Fietkau void __ieee80211_schedule_txq(struct ieee80211_hw *hw,
37112b4a6698SFelix Fietkau 			      struct ieee80211_txq *txq,
37122b4a6698SFelix Fietkau 			      bool force)
371318667600SToke Høiland-Jørgensen {
371418667600SToke Høiland-Jørgensen 	struct ieee80211_local *local = hw_to_local(hw);
371518667600SToke Høiland-Jørgensen 	struct txq_info *txqi = to_txq_info(txq);
371618667600SToke Høiland-Jørgensen 
37175b989c18SFelix Fietkau 	spin_lock_bh(&local->active_txq_lock[txq->ac]);
371818667600SToke Høiland-Jørgensen 
371918667600SToke Høiland-Jørgensen 	if (list_empty(&txqi->schedule_order) &&
37202b4a6698SFelix Fietkau 	    (force || !skb_queue_empty(&txqi->frags) ||
37212b4a6698SFelix Fietkau 	     txqi->tin.backlog_packets)) {
3722b4809e94SToke Høiland-Jørgensen 		/* If airtime accounting is active, always enqueue STAs at the
3723b4809e94SToke Høiland-Jørgensen 		 * head of the list to ensure that they only get moved to the
3724b4809e94SToke Høiland-Jørgensen 		 * back by the airtime DRR scheduler once they have a negative
3725b4809e94SToke Høiland-Jørgensen 		 * deficit. A station that already has a negative deficit will
3726b4809e94SToke Høiland-Jørgensen 		 * get immediately moved to the back of the list on the next
3727b4809e94SToke Høiland-Jørgensen 		 * call to ieee80211_next_txq().
3728b4809e94SToke Høiland-Jørgensen 		 */
3729b4809e94SToke Høiland-Jørgensen 		if (txqi->txq.sta &&
3730b4809e94SToke Høiland-Jørgensen 		    wiphy_ext_feature_isset(local->hw.wiphy,
3731b4809e94SToke Høiland-Jørgensen 					    NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
3732b4809e94SToke Høiland-Jørgensen 			list_add(&txqi->schedule_order,
3733b4809e94SToke Høiland-Jørgensen 				 &local->active_txqs[txq->ac]);
3734b4809e94SToke Høiland-Jørgensen 		else
373518667600SToke Høiland-Jørgensen 			list_add_tail(&txqi->schedule_order,
373618667600SToke Høiland-Jørgensen 				      &local->active_txqs[txq->ac]);
373718667600SToke Høiland-Jørgensen 	}
373818667600SToke Høiland-Jørgensen 
3739390298e8SToke Høiland-Jørgensen 	spin_unlock_bh(&local->active_txq_lock[txq->ac]);
3740390298e8SToke Høiland-Jørgensen }
37412b4a6698SFelix Fietkau EXPORT_SYMBOL(__ieee80211_schedule_txq);
3742390298e8SToke Høiland-Jørgensen 
3743b4809e94SToke Høiland-Jørgensen bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
3744b4809e94SToke Høiland-Jørgensen 				struct ieee80211_txq *txq)
3745b4809e94SToke Høiland-Jørgensen {
3746b4809e94SToke Høiland-Jørgensen 	struct ieee80211_local *local = hw_to_local(hw);
3747b4809e94SToke Høiland-Jørgensen 	struct txq_info *iter, *tmp, *txqi = to_txq_info(txq);
3748b4809e94SToke Høiland-Jørgensen 	struct sta_info *sta;
3749b4809e94SToke Høiland-Jørgensen 	u8 ac = txq->ac;
3750b4809e94SToke Høiland-Jørgensen 
37515b989c18SFelix Fietkau 	spin_lock_bh(&local->active_txq_lock[ac]);
3752b4809e94SToke Høiland-Jørgensen 
3753b4809e94SToke Høiland-Jørgensen 	if (!txqi->txq.sta)
3754b4809e94SToke Høiland-Jørgensen 		goto out;
3755b4809e94SToke Høiland-Jørgensen 
3756b4809e94SToke Høiland-Jørgensen 	if (list_empty(&txqi->schedule_order))
3757b4809e94SToke Høiland-Jørgensen 		goto out;
3758b4809e94SToke Høiland-Jørgensen 
3759b4809e94SToke Høiland-Jørgensen 	list_for_each_entry_safe(iter, tmp, &local->active_txqs[ac],
3760b4809e94SToke Høiland-Jørgensen 				 schedule_order) {
3761b4809e94SToke Høiland-Jørgensen 		if (iter == txqi)
3762b4809e94SToke Høiland-Jørgensen 			break;
3763b4809e94SToke Høiland-Jørgensen 
3764b4809e94SToke Høiland-Jørgensen 		if (!iter->txq.sta) {
3765b4809e94SToke Høiland-Jørgensen 			list_move_tail(&iter->schedule_order,
3766b4809e94SToke Høiland-Jørgensen 				       &local->active_txqs[ac]);
3767b4809e94SToke Høiland-Jørgensen 			continue;
3768b4809e94SToke Høiland-Jørgensen 		}
3769b4809e94SToke Høiland-Jørgensen 		sta = container_of(iter->txq.sta, struct sta_info, sta);
3770b4809e94SToke Høiland-Jørgensen 		if (sta->airtime[ac].deficit < 0)
3771b4809e94SToke Høiland-Jørgensen 			sta->airtime[ac].deficit += sta->airtime_weight;
3772b4809e94SToke Høiland-Jørgensen 		list_move_tail(&iter->schedule_order, &local->active_txqs[ac]);
3773b4809e94SToke Høiland-Jørgensen 	}
3774b4809e94SToke Høiland-Jørgensen 
3775b4809e94SToke Høiland-Jørgensen 	sta = container_of(txqi->txq.sta, struct sta_info, sta);
3776b4809e94SToke Høiland-Jørgensen 	if (sta->airtime[ac].deficit >= 0)
3777b4809e94SToke Høiland-Jørgensen 		goto out;
3778b4809e94SToke Høiland-Jørgensen 
3779b4809e94SToke Høiland-Jørgensen 	sta->airtime[ac].deficit += sta->airtime_weight;
3780b4809e94SToke Høiland-Jørgensen 	list_move_tail(&txqi->schedule_order, &local->active_txqs[ac]);
37815b989c18SFelix Fietkau 	spin_unlock_bh(&local->active_txq_lock[ac]);
3782b4809e94SToke Høiland-Jørgensen 
3783b4809e94SToke Høiland-Jørgensen 	return false;
3784b4809e94SToke Høiland-Jørgensen out:
3785b4809e94SToke Høiland-Jørgensen 	if (!list_empty(&txqi->schedule_order))
3786b4809e94SToke Høiland-Jørgensen 		list_del_init(&txqi->schedule_order);
37875b989c18SFelix Fietkau 	spin_unlock_bh(&local->active_txq_lock[ac]);
3788b4809e94SToke Høiland-Jørgensen 
3789b4809e94SToke Høiland-Jørgensen 	return true;
3790b4809e94SToke Høiland-Jørgensen }
3791b4809e94SToke Høiland-Jørgensen EXPORT_SYMBOL(ieee80211_txq_may_transmit);
3792b4809e94SToke Høiland-Jørgensen 
379318667600SToke Høiland-Jørgensen void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac)
379418667600SToke Høiland-Jørgensen {
379518667600SToke Høiland-Jørgensen 	struct ieee80211_local *local = hw_to_local(hw);
379618667600SToke Høiland-Jørgensen 
379718667600SToke Høiland-Jørgensen 	spin_lock_bh(&local->active_txq_lock[ac]);
379818667600SToke Høiland-Jørgensen 	local->schedule_round[ac]++;
379918667600SToke Høiland-Jørgensen 	spin_unlock_bh(&local->active_txq_lock[ac]);
380018667600SToke Høiland-Jørgensen }
38015b989c18SFelix Fietkau EXPORT_SYMBOL(ieee80211_txq_schedule_start);
380218667600SToke Høiland-Jørgensen 
38034c9451edSJohannes Berg void __ieee80211_subif_start_xmit(struct sk_buff *skb,
38044c9451edSJohannes Berg 				  struct net_device *dev,
380506016772SRajkumar Manoharan 				  u32 info_flags,
380606016772SRajkumar Manoharan 				  u32 ctrl_flags)
38074c9451edSJohannes Berg {
38084c9451edSJohannes Berg 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
38091974da8bSFelix Fietkau 	struct ieee80211_local *local = sdata->local;
381097ffe757SJohannes Berg 	struct sta_info *sta;
381180616c0dSJohannes Berg 	struct sk_buff *next;
38124c9451edSJohannes Berg 
38134c9451edSJohannes Berg 	if (unlikely(skb->len < ETH_HLEN)) {
38144c9451edSJohannes Berg 		kfree_skb(skb);
38154c9451edSJohannes Berg 		return;
38164c9451edSJohannes Berg 	}
38174c9451edSJohannes Berg 
38184c9451edSJohannes Berg 	rcu_read_lock();
38194c9451edSJohannes Berg 
38202d981fddSJohannes Berg 	if (ieee80211_lookup_ra_sta(sdata, skb, &sta))
38212d981fddSJohannes Berg 		goto out_free;
38224c9451edSJohannes Berg 
38231974da8bSFelix Fietkau 	if (IS_ERR(sta))
38241974da8bSFelix Fietkau 		sta = NULL;
38251974da8bSFelix Fietkau 
38261974da8bSFelix Fietkau 	if (local->ops->wake_tx_queue) {
38271974da8bSFelix Fietkau 		u16 queue = __ieee80211_select_queue(sdata, sta, skb);
38281974da8bSFelix Fietkau 		skb_set_queue_mapping(skb, queue);
38291974da8bSFelix Fietkau 	}
38301974da8bSFelix Fietkau 
38311974da8bSFelix Fietkau 	if (sta) {
383217c18bf8SJohannes Berg 		struct ieee80211_fast_tx *fast_tx;
383317c18bf8SJohannes Berg 
383470e53669SWen Gong 		sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift);
383536148c2bSToke Høiland-Jørgensen 
383617c18bf8SJohannes Berg 		fast_tx = rcu_dereference(sta->fast_tx);
383717c18bf8SJohannes Berg 
383817c18bf8SJohannes Berg 		if (fast_tx &&
3839bb42f2d1SToke Høiland-Jørgensen 		    ieee80211_xmit_fast(sdata, sta, fast_tx, skb))
384017c18bf8SJohannes Berg 			goto out;
384117c18bf8SJohannes Berg 	}
384217c18bf8SJohannes Berg 
384380616c0dSJohannes Berg 	if (skb_is_gso(skb)) {
384480616c0dSJohannes Berg 		struct sk_buff *segs;
384580616c0dSJohannes Berg 
384680616c0dSJohannes Berg 		segs = skb_gso_segment(skb, 0);
384780616c0dSJohannes Berg 		if (IS_ERR(segs)) {
384880616c0dSJohannes Berg 			goto out_free;
384980616c0dSJohannes Berg 		} else if (segs) {
385080616c0dSJohannes Berg 			consume_skb(skb);
385180616c0dSJohannes Berg 			skb = segs;
385280616c0dSJohannes Berg 		}
385380616c0dSJohannes Berg 	} else {
3854680a0dabSJohannes Berg 		/* we cannot process non-linear frames on this path */
3855680a0dabSJohannes Berg 		if (skb_linearize(skb)) {
3856680a0dabSJohannes Berg 			kfree_skb(skb);
3857680a0dabSJohannes Berg 			goto out;
3858680a0dabSJohannes Berg 		}
3859680a0dabSJohannes Berg 
386080616c0dSJohannes Berg 		/* the frame could be fragmented, software-encrypted, and other
386180616c0dSJohannes Berg 		 * things so we cannot really handle checksum offload with it -
386280616c0dSJohannes Berg 		 * fix it up in software before we handle anything else.
38632d981fddSJohannes Berg 		 */
38642d981fddSJohannes Berg 		if (skb->ip_summed == CHECKSUM_PARTIAL) {
38652d981fddSJohannes Berg 			skb_set_transport_header(skb,
38662d981fddSJohannes Berg 						 skb_checksum_start_offset(skb));
38672d981fddSJohannes Berg 			if (skb_checksum_help(skb))
38682d981fddSJohannes Berg 				goto out_free;
38692d981fddSJohannes Berg 		}
387080616c0dSJohannes Berg 	}
387180616c0dSJohannes Berg 
387280616c0dSJohannes Berg 	next = skb;
387380616c0dSJohannes Berg 	while (next) {
387480616c0dSJohannes Berg 		skb = next;
387580616c0dSJohannes Berg 		next = skb->next;
387680616c0dSJohannes Berg 
387780616c0dSJohannes Berg 		skb->prev = NULL;
387880616c0dSJohannes Berg 		skb->next = NULL;
38792d981fddSJohannes Berg 
388006016772SRajkumar Manoharan 		skb = ieee80211_build_hdr(sdata, skb, info_flags,
388106016772SRajkumar Manoharan 					  sta, ctrl_flags);
38824c9451edSJohannes Berg 		if (IS_ERR(skb))
38834c9451edSJohannes Berg 			goto out;
38844c9451edSJohannes Berg 
38855a490510SJohannes Berg 		ieee80211_tx_stats(dev, skb->len);
38864c9451edSJohannes Berg 
3887b9771d41SJohannes Berg 		ieee80211_xmit(sdata, sta, skb, 0);
388880616c0dSJohannes Berg 	}
38892d981fddSJohannes Berg 	goto out;
38902d981fddSJohannes Berg  out_free:
38912d981fddSJohannes Berg 	kfree_skb(skb);
38924c9451edSJohannes Berg  out:
38934c9451edSJohannes Berg 	rcu_read_unlock();
38944c9451edSJohannes Berg }
38954c9451edSJohannes Berg 
3896ebceec86SMichael Braun static int ieee80211_change_da(struct sk_buff *skb, struct sta_info *sta)
3897ebceec86SMichael Braun {
3898ebceec86SMichael Braun 	struct ethhdr *eth;
3899ebceec86SMichael Braun 	int err;
3900ebceec86SMichael Braun 
3901ebceec86SMichael Braun 	err = skb_ensure_writable(skb, ETH_HLEN);
3902ebceec86SMichael Braun 	if (unlikely(err))
3903ebceec86SMichael Braun 		return err;
3904ebceec86SMichael Braun 
3905ebceec86SMichael Braun 	eth = (void *)skb->data;
3906ebceec86SMichael Braun 	ether_addr_copy(eth->h_dest, sta->sta.addr);
3907ebceec86SMichael Braun 
3908ebceec86SMichael Braun 	return 0;
3909ebceec86SMichael Braun }
3910ebceec86SMichael Braun 
3911ebceec86SMichael Braun static bool ieee80211_multicast_to_unicast(struct sk_buff *skb,
3912ebceec86SMichael Braun 					   struct net_device *dev)
3913ebceec86SMichael Braun {
3914ebceec86SMichael Braun 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3915ebceec86SMichael Braun 	const struct ethhdr *eth = (void *)skb->data;
3916ebceec86SMichael Braun 	const struct vlan_ethhdr *ethvlan = (void *)skb->data;
3917ebceec86SMichael Braun 	__be16 ethertype;
3918ebceec86SMichael Braun 
3919ebceec86SMichael Braun 	if (likely(!is_multicast_ether_addr(eth->h_dest)))
3920ebceec86SMichael Braun 		return false;
3921ebceec86SMichael Braun 
3922ebceec86SMichael Braun 	switch (sdata->vif.type) {
3923ebceec86SMichael Braun 	case NL80211_IFTYPE_AP_VLAN:
3924ebceec86SMichael Braun 		if (sdata->u.vlan.sta)
3925ebceec86SMichael Braun 			return false;
3926ebceec86SMichael Braun 		if (sdata->wdev.use_4addr)
3927ebceec86SMichael Braun 			return false;
3928ebceec86SMichael Braun 		/* fall through */
3929ebceec86SMichael Braun 	case NL80211_IFTYPE_AP:
3930ebceec86SMichael Braun 		/* check runtime toggle for this bss */
3931ebceec86SMichael Braun 		if (!sdata->bss->multicast_to_unicast)
3932ebceec86SMichael Braun 			return false;
3933ebceec86SMichael Braun 		break;
3934ebceec86SMichael Braun 	default:
3935ebceec86SMichael Braun 		return false;
3936ebceec86SMichael Braun 	}
3937ebceec86SMichael Braun 
3938ebceec86SMichael Braun 	/* multicast to unicast conversion only for some payload */
3939ebceec86SMichael Braun 	ethertype = eth->h_proto;
3940ebceec86SMichael Braun 	if (ethertype == htons(ETH_P_8021Q) && skb->len >= VLAN_ETH_HLEN)
3941ebceec86SMichael Braun 		ethertype = ethvlan->h_vlan_encapsulated_proto;
3942ebceec86SMichael Braun 	switch (ethertype) {
3943ebceec86SMichael Braun 	case htons(ETH_P_ARP):
3944ebceec86SMichael Braun 	case htons(ETH_P_IP):
3945ebceec86SMichael Braun 	case htons(ETH_P_IPV6):
3946ebceec86SMichael Braun 		break;
3947ebceec86SMichael Braun 	default:
3948ebceec86SMichael Braun 		return false;
3949ebceec86SMichael Braun 	}
3950ebceec86SMichael Braun 
3951ebceec86SMichael Braun 	return true;
3952ebceec86SMichael Braun }
3953ebceec86SMichael Braun 
3954ebceec86SMichael Braun static void
3955ebceec86SMichael Braun ieee80211_convert_to_unicast(struct sk_buff *skb, struct net_device *dev,
3956ebceec86SMichael Braun 			     struct sk_buff_head *queue)
3957ebceec86SMichael Braun {
3958ebceec86SMichael Braun 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3959ebceec86SMichael Braun 	struct ieee80211_local *local = sdata->local;
3960ebceec86SMichael Braun 	const struct ethhdr *eth = (struct ethhdr *)skb->data;
3961ebceec86SMichael Braun 	struct sta_info *sta, *first = NULL;
3962ebceec86SMichael Braun 	struct sk_buff *cloned_skb;
3963ebceec86SMichael Braun 
3964ebceec86SMichael Braun 	rcu_read_lock();
3965ebceec86SMichael Braun 
3966ebceec86SMichael Braun 	list_for_each_entry_rcu(sta, &local->sta_list, list) {
3967ebceec86SMichael Braun 		if (sdata != sta->sdata)
3968ebceec86SMichael Braun 			/* AP-VLAN mismatch */
3969ebceec86SMichael Braun 			continue;
3970ebceec86SMichael Braun 		if (unlikely(ether_addr_equal(eth->h_source, sta->sta.addr)))
3971ebceec86SMichael Braun 			/* do not send back to source */
3972ebceec86SMichael Braun 			continue;
3973ebceec86SMichael Braun 		if (!first) {
3974ebceec86SMichael Braun 			first = sta;
3975ebceec86SMichael Braun 			continue;
3976ebceec86SMichael Braun 		}
3977ebceec86SMichael Braun 		cloned_skb = skb_clone(skb, GFP_ATOMIC);
3978ebceec86SMichael Braun 		if (!cloned_skb)
3979ebceec86SMichael Braun 			goto multicast;
3980ebceec86SMichael Braun 		if (unlikely(ieee80211_change_da(cloned_skb, sta))) {
3981ebceec86SMichael Braun 			dev_kfree_skb(cloned_skb);
3982ebceec86SMichael Braun 			goto multicast;
3983ebceec86SMichael Braun 		}
3984ebceec86SMichael Braun 		__skb_queue_tail(queue, cloned_skb);
3985ebceec86SMichael Braun 	}
3986ebceec86SMichael Braun 
3987ebceec86SMichael Braun 	if (likely(first)) {
3988ebceec86SMichael Braun 		if (unlikely(ieee80211_change_da(skb, first)))
3989ebceec86SMichael Braun 			goto multicast;
3990ebceec86SMichael Braun 		__skb_queue_tail(queue, skb);
3991ebceec86SMichael Braun 	} else {
3992ebceec86SMichael Braun 		/* no STA connected, drop */
3993ebceec86SMichael Braun 		kfree_skb(skb);
3994ebceec86SMichael Braun 		skb = NULL;
3995ebceec86SMichael Braun 	}
3996ebceec86SMichael Braun 
3997ebceec86SMichael Braun 	goto out;
3998ebceec86SMichael Braun multicast:
3999ebceec86SMichael Braun 	__skb_queue_purge(queue);
4000ebceec86SMichael Braun 	__skb_queue_tail(queue, skb);
4001ebceec86SMichael Braun out:
4002ebceec86SMichael Braun 	rcu_read_unlock();
4003ebceec86SMichael Braun }
4004ebceec86SMichael Braun 
40054c9451edSJohannes Berg /**
40064c9451edSJohannes Berg  * ieee80211_subif_start_xmit - netif start_xmit function for 802.3 vifs
40074c9451edSJohannes Berg  * @skb: packet to be sent
40084c9451edSJohannes Berg  * @dev: incoming interface
40094c9451edSJohannes Berg  *
40104c9451edSJohannes Berg  * On failure skb will be freed.
40114c9451edSJohannes Berg  */
401224d342c5SLiad Kaufman netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
401324d342c5SLiad Kaufman 				       struct net_device *dev)
401424d342c5SLiad Kaufman {
4015ebceec86SMichael Braun 	if (unlikely(ieee80211_multicast_to_unicast(skb, dev))) {
4016ebceec86SMichael Braun 		struct sk_buff_head queue;
4017ebceec86SMichael Braun 
4018ebceec86SMichael Braun 		__skb_queue_head_init(&queue);
4019ebceec86SMichael Braun 		ieee80211_convert_to_unicast(skb, dev, &queue);
4020ebceec86SMichael Braun 		while ((skb = __skb_dequeue(&queue)))
402106016772SRajkumar Manoharan 			__ieee80211_subif_start_xmit(skb, dev, 0, 0);
4022ebceec86SMichael Braun 	} else {
402306016772SRajkumar Manoharan 		__ieee80211_subif_start_xmit(skb, dev, 0, 0);
4024ebceec86SMichael Braun 	}
4025ebceec86SMichael Braun 
402624d342c5SLiad Kaufman 	return NETDEV_TX_OK;
402724d342c5SLiad Kaufman }
4028e2ebc74dSJohannes Berg 
40297528ec57SJohannes Berg struct sk_buff *
40307528ec57SJohannes Berg ieee80211_build_data_template(struct ieee80211_sub_if_data *sdata,
40317528ec57SJohannes Berg 			      struct sk_buff *skb, u32 info_flags)
40327528ec57SJohannes Berg {
40337528ec57SJohannes Berg 	struct ieee80211_hdr *hdr;
40347528ec57SJohannes Berg 	struct ieee80211_tx_data tx = {
40357528ec57SJohannes Berg 		.local = sdata->local,
40367528ec57SJohannes Berg 		.sdata = sdata,
40377528ec57SJohannes Berg 	};
403897ffe757SJohannes Berg 	struct sta_info *sta;
40397528ec57SJohannes Berg 
40407528ec57SJohannes Berg 	rcu_read_lock();
40417528ec57SJohannes Berg 
404297ffe757SJohannes Berg 	if (ieee80211_lookup_ra_sta(sdata, skb, &sta)) {
404397ffe757SJohannes Berg 		kfree_skb(skb);
404497ffe757SJohannes Berg 		skb = ERR_PTR(-EINVAL);
404597ffe757SJohannes Berg 		goto out;
404697ffe757SJohannes Berg 	}
404797ffe757SJohannes Berg 
404806016772SRajkumar Manoharan 	skb = ieee80211_build_hdr(sdata, skb, info_flags, sta, 0);
40497528ec57SJohannes Berg 	if (IS_ERR(skb))
40507528ec57SJohannes Berg 		goto out;
40517528ec57SJohannes Berg 
40527528ec57SJohannes Berg 	hdr = (void *)skb->data;
40537528ec57SJohannes Berg 	tx.sta = sta_info_get(sdata, hdr->addr1);
40547528ec57SJohannes Berg 	tx.skb = skb;
40557528ec57SJohannes Berg 
40567528ec57SJohannes Berg 	if (ieee80211_tx_h_select_key(&tx) != TX_CONTINUE) {
40577528ec57SJohannes Berg 		rcu_read_unlock();
40587528ec57SJohannes Berg 		kfree_skb(skb);
40597528ec57SJohannes Berg 		return ERR_PTR(-EINVAL);
40607528ec57SJohannes Berg 	}
40617528ec57SJohannes Berg 
40627528ec57SJohannes Berg out:
40637528ec57SJohannes Berg 	rcu_read_unlock();
40647528ec57SJohannes Berg 	return skb;
40657528ec57SJohannes Berg }
40667528ec57SJohannes Berg 
4067e2530083SJohannes Berg /*
4068e2530083SJohannes Berg  * ieee80211_clear_tx_pending may not be called in a context where
4069e2530083SJohannes Berg  * it is possible that it packets could come in again.
4070e2530083SJohannes Berg  */
4071e2ebc74dSJohannes Berg void ieee80211_clear_tx_pending(struct ieee80211_local *local)
4072e2ebc74dSJohannes Berg {
40731f98ab7fSFelix Fietkau 	struct sk_buff *skb;
40742de8e0d9SJohannes Berg 	int i;
4075e2ebc74dSJohannes Berg 
40761f98ab7fSFelix Fietkau 	for (i = 0; i < local->hw.queues; i++) {
40771f98ab7fSFelix Fietkau 		while ((skb = skb_dequeue(&local->pending[i])) != NULL)
40781f98ab7fSFelix Fietkau 			ieee80211_free_txskb(&local->hw, skb);
40791f98ab7fSFelix Fietkau 	}
4080e2ebc74dSJohannes Berg }
4081e2ebc74dSJohannes Berg 
40827bb45683SJohannes Berg /*
40837bb45683SJohannes Berg  * Returns false if the frame couldn't be transmitted but was queued instead,
40847bb45683SJohannes Berg  * which in this case means re-queued -- take as an indication to stop sending
40857bb45683SJohannes Berg  * more pending frames.
40867bb45683SJohannes Berg  */
4087cd8ffc80SJohannes Berg static bool ieee80211_tx_pending_skb(struct ieee80211_local *local,
4088cd8ffc80SJohannes Berg 				     struct sk_buff *skb)
4089cd8ffc80SJohannes Berg {
4090cd8ffc80SJohannes Berg 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
4091cd8ffc80SJohannes Berg 	struct ieee80211_sub_if_data *sdata;
4092cd8ffc80SJohannes Berg 	struct sta_info *sta;
4093cd8ffc80SJohannes Berg 	struct ieee80211_hdr *hdr;
40947bb45683SJohannes Berg 	bool result;
409555de908aSJohannes Berg 	struct ieee80211_chanctx_conf *chanctx_conf;
4096cd8ffc80SJohannes Berg 
40975061b0c2SJohannes Berg 	sdata = vif_to_sdata(info->control.vif);
4098cd8ffc80SJohannes Berg 
4099cd8ffc80SJohannes Berg 	if (info->flags & IEEE80211_TX_INTFL_NEED_TXPROCESSING) {
410055de908aSJohannes Berg 		chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
410155de908aSJohannes Berg 		if (unlikely(!chanctx_conf)) {
410255de908aSJohannes Berg 			dev_kfree_skb(skb);
410355de908aSJohannes Berg 			return true;
410455de908aSJohannes Berg 		}
410573c4e195SJohannes Berg 		info->band = chanctx_conf->def.chan->band;
4106b9771d41SJohannes Berg 		result = ieee80211_tx(sdata, NULL, skb, true, 0);
4107cd8ffc80SJohannes Berg 	} else {
4108252b86c4SJohannes Berg 		struct sk_buff_head skbs;
4109252b86c4SJohannes Berg 
4110252b86c4SJohannes Berg 		__skb_queue_head_init(&skbs);
4111252b86c4SJohannes Berg 		__skb_queue_tail(&skbs, skb);
4112252b86c4SJohannes Berg 
4113cd8ffc80SJohannes Berg 		hdr = (struct ieee80211_hdr *)skb->data;
4114abe60632SJohannes Berg 		sta = sta_info_get(sdata, hdr->addr1);
4115cd8ffc80SJohannes Berg 
411674e4dbfdSJohannes Berg 		result = __ieee80211_tx(local, &skbs, skb->len, sta, true);
4117cd8ffc80SJohannes Berg 	}
4118cd8ffc80SJohannes Berg 
4119cd8ffc80SJohannes Berg 	return result;
4120cd8ffc80SJohannes Berg }
4121cd8ffc80SJohannes Berg 
4122e2530083SJohannes Berg /*
41233b8d81e0SJohannes Berg  * Transmit all pending packets. Called from tasklet.
4124e2530083SJohannes Berg  */
4125e2ebc74dSJohannes Berg void ieee80211_tx_pending(unsigned long data)
4126e2ebc74dSJohannes Berg {
4127e2ebc74dSJohannes Berg 	struct ieee80211_local *local = (struct ieee80211_local *)data;
41282a577d98SJohannes Berg 	unsigned long flags;
4129cd8ffc80SJohannes Berg 	int i;
41303b8d81e0SJohannes Berg 	bool txok;
4131e2ebc74dSJohannes Berg 
4132f0e72851SJohannes Berg 	rcu_read_lock();
41332a577d98SJohannes Berg 
41343b8d81e0SJohannes Berg 	spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
4135176be728SJohannes Berg 	for (i = 0; i < local->hw.queues; i++) {
41362a577d98SJohannes Berg 		/*
41372a577d98SJohannes Berg 		 * If queue is stopped by something other than due to pending
41382a577d98SJohannes Berg 		 * frames, or we have no pending frames, proceed to next queue.
41392a577d98SJohannes Berg 		 */
41403b8d81e0SJohannes Berg 		if (local->queue_stop_reasons[i] ||
41412a577d98SJohannes Berg 		    skb_queue_empty(&local->pending[i]))
4142e2ebc74dSJohannes Berg 			continue;
4143e2530083SJohannes Berg 
41442a577d98SJohannes Berg 		while (!skb_queue_empty(&local->pending[i])) {
41453b8d81e0SJohannes Berg 			struct sk_buff *skb = __skb_dequeue(&local->pending[i]);
41465061b0c2SJohannes Berg 			struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
41475061b0c2SJohannes Berg 
4148a7bc376cSJohannes Berg 			if (WARN_ON(!info->control.vif)) {
4149c3e7724bSFelix Fietkau 				ieee80211_free_txskb(&local->hw, skb);
4150a7bc376cSJohannes Berg 				continue;
4151a7bc376cSJohannes Berg 			}
4152a7bc376cSJohannes Berg 
41533b8d81e0SJohannes Berg 			spin_unlock_irqrestore(&local->queue_stop_reason_lock,
41543b8d81e0SJohannes Berg 						flags);
41552a577d98SJohannes Berg 
41563b8d81e0SJohannes Berg 			txok = ieee80211_tx_pending_skb(local, skb);
41573b8d81e0SJohannes Berg 			spin_lock_irqsave(&local->queue_stop_reason_lock,
41583b8d81e0SJohannes Berg 					  flags);
41593b8d81e0SJohannes Berg 			if (!txok)
41602a577d98SJohannes Berg 				break;
4161e2ebc74dSJohannes Berg 		}
41627236fe29SJohannes Berg 
41637236fe29SJohannes Berg 		if (skb_queue_empty(&local->pending[i]))
41643a25a8c8SJohannes Berg 			ieee80211_propagate_queue_wake(local, i);
4165e2ebc74dSJohannes Berg 	}
41663b8d81e0SJohannes Berg 	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
41672a577d98SJohannes Berg 
4168f0e72851SJohannes Berg 	rcu_read_unlock();
4169e2ebc74dSJohannes Berg }
4170e2ebc74dSJohannes Berg 
4171e2ebc74dSJohannes Berg /* functions for drivers to get certain frames */
4172e2ebc74dSJohannes Berg 
4173eac70c13SMarco Porsch static void __ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata,
41746ec8c332SAndrei Otcheretianski 				       struct ps_data *ps, struct sk_buff *skb,
41756ec8c332SAndrei Otcheretianski 				       bool is_template)
4176e2ebc74dSJohannes Berg {
4177e2ebc74dSJohannes Berg 	u8 *pos, *tim;
4178e2ebc74dSJohannes Berg 	int aid0 = 0;
4179e2ebc74dSJohannes Berg 	int i, have_bits = 0, n1, n2;
4180e2ebc74dSJohannes Berg 
4181e2ebc74dSJohannes Berg 	/* Generate bitmap for TIM only if there are any STAs in power save
4182e2ebc74dSJohannes Berg 	 * mode. */
4183d012a605SMarco Porsch 	if (atomic_read(&ps->num_sta_ps) > 0)
4184e2ebc74dSJohannes Berg 		/* in the hope that this is faster than
4185e2ebc74dSJohannes Berg 		 * checking byte-for-byte */
4186d012a605SMarco Porsch 		have_bits = !bitmap_empty((unsigned long *)ps->tim,
4187e2ebc74dSJohannes Berg 					  IEEE80211_MAX_AID+1);
41886ec8c332SAndrei Otcheretianski 	if (!is_template) {
4189d012a605SMarco Porsch 		if (ps->dtim_count == 0)
4190d012a605SMarco Porsch 			ps->dtim_count = sdata->vif.bss_conf.dtim_period - 1;
4191e2ebc74dSJohannes Berg 		else
4192d012a605SMarco Porsch 			ps->dtim_count--;
41936ec8c332SAndrei Otcheretianski 	}
4194e2ebc74dSJohannes Berg 
41954df864c1SJohannes Berg 	tim = pos = skb_put(skb, 6);
4196e2ebc74dSJohannes Berg 	*pos++ = WLAN_EID_TIM;
4197e2ebc74dSJohannes Berg 	*pos++ = 4;
4198d012a605SMarco Porsch 	*pos++ = ps->dtim_count;
41998860020eSJohannes Berg 	*pos++ = sdata->vif.bss_conf.dtim_period;
4200e2ebc74dSJohannes Berg 
4201d012a605SMarco Porsch 	if (ps->dtim_count == 0 && !skb_queue_empty(&ps->bc_buf))
4202e2ebc74dSJohannes Berg 		aid0 = 1;
4203e2ebc74dSJohannes Berg 
4204d012a605SMarco Porsch 	ps->dtim_bc_mc = aid0 == 1;
4205512119b3SChristian Lamparter 
4206e2ebc74dSJohannes Berg 	if (have_bits) {
4207e2ebc74dSJohannes Berg 		/* Find largest even number N1 so that bits numbered 1 through
4208e2ebc74dSJohannes Berg 		 * (N1 x 8) - 1 in the bitmap are 0 and number N2 so that bits
4209e2ebc74dSJohannes Berg 		 * (N2 + 1) x 8 through 2007 are 0. */
4210e2ebc74dSJohannes Berg 		n1 = 0;
4211e2ebc74dSJohannes Berg 		for (i = 0; i < IEEE80211_MAX_TIM_LEN; i++) {
4212d012a605SMarco Porsch 			if (ps->tim[i]) {
4213e2ebc74dSJohannes Berg 				n1 = i & 0xfe;
4214e2ebc74dSJohannes Berg 				break;
4215e2ebc74dSJohannes Berg 			}
4216e2ebc74dSJohannes Berg 		}
4217e2ebc74dSJohannes Berg 		n2 = n1;
4218e2ebc74dSJohannes Berg 		for (i = IEEE80211_MAX_TIM_LEN - 1; i >= n1; i--) {
4219d012a605SMarco Porsch 			if (ps->tim[i]) {
4220e2ebc74dSJohannes Berg 				n2 = i;
4221e2ebc74dSJohannes Berg 				break;
4222e2ebc74dSJohannes Berg 			}
4223e2ebc74dSJohannes Berg 		}
4224e2ebc74dSJohannes Berg 
4225e2ebc74dSJohannes Berg 		/* Bitmap control */
4226e2ebc74dSJohannes Berg 		*pos++ = n1 | aid0;
4227e2ebc74dSJohannes Berg 		/* Part Virt Bitmap */
42285220da39SEliad Peller 		skb_put(skb, n2 - n1);
4229d012a605SMarco Porsch 		memcpy(pos, ps->tim + n1, n2 - n1 + 1);
4230e2ebc74dSJohannes Berg 
4231e2ebc74dSJohannes Berg 		tim[1] = n2 - n1 + 4;
4232e2ebc74dSJohannes Berg 	} else {
4233e2ebc74dSJohannes Berg 		*pos++ = aid0; /* Bitmap control */
4234e2ebc74dSJohannes Berg 		*pos++ = 0; /* Part Virt Bitmap */
4235e2ebc74dSJohannes Berg 	}
4236e2ebc74dSJohannes Berg }
4237e2ebc74dSJohannes Berg 
4238eac70c13SMarco Porsch static int ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata,
42396ec8c332SAndrei Otcheretianski 				    struct ps_data *ps, struct sk_buff *skb,
42406ec8c332SAndrei Otcheretianski 				    bool is_template)
4241eac70c13SMarco Porsch {
4242eac70c13SMarco Porsch 	struct ieee80211_local *local = sdata->local;
4243eac70c13SMarco Porsch 
4244eac70c13SMarco Porsch 	/*
4245eac70c13SMarco Porsch 	 * Not very nice, but we want to allow the driver to call
4246eac70c13SMarco Porsch 	 * ieee80211_beacon_get() as a response to the set_tim()
4247eac70c13SMarco Porsch 	 * callback. That, however, is already invoked under the
4248eac70c13SMarco Porsch 	 * sta_lock to guarantee consistent and race-free update
4249eac70c13SMarco Porsch 	 * of the tim bitmap in mac80211 and the driver.
4250eac70c13SMarco Porsch 	 */
4251eac70c13SMarco Porsch 	if (local->tim_in_locked_section) {
42526ec8c332SAndrei Otcheretianski 		__ieee80211_beacon_add_tim(sdata, ps, skb, is_template);
4253eac70c13SMarco Porsch 	} else {
42541b91731dSJohannes Berg 		spin_lock_bh(&local->tim_lock);
42556ec8c332SAndrei Otcheretianski 		__ieee80211_beacon_add_tim(sdata, ps, skb, is_template);
42561b91731dSJohannes Berg 		spin_unlock_bh(&local->tim_lock);
4257eac70c13SMarco Porsch 	}
4258eac70c13SMarco Porsch 
4259eac70c13SMarco Porsch 	return 0;
4260eac70c13SMarco Porsch }
4261eac70c13SMarco Porsch 
42621af586c9SAndrei Otcheretianski static void ieee80211_set_csa(struct ieee80211_sub_if_data *sdata,
426373da7d5bSSimon Wunderlich 			      struct beacon_data *beacon)
426473da7d5bSSimon Wunderlich {
426573da7d5bSSimon Wunderlich 	struct probe_resp *resp;
4266cd7760e6SSimon Wunderlich 	u8 *beacon_data;
4267cd7760e6SSimon Wunderlich 	size_t beacon_data_len;
42680d06d9baSAndrei Otcheretianski 	int i;
4269af296bdbSMichal Kazior 	u8 count = beacon->csa_current_counter;
427073da7d5bSSimon Wunderlich 
4271cd7760e6SSimon Wunderlich 	switch (sdata->vif.type) {
4272cd7760e6SSimon Wunderlich 	case NL80211_IFTYPE_AP:
4273cd7760e6SSimon Wunderlich 		beacon_data = beacon->tail;
4274cd7760e6SSimon Wunderlich 		beacon_data_len = beacon->tail_len;
4275cd7760e6SSimon Wunderlich 		break;
4276cd7760e6SSimon Wunderlich 	case NL80211_IFTYPE_ADHOC:
4277cd7760e6SSimon Wunderlich 		beacon_data = beacon->head;
4278cd7760e6SSimon Wunderlich 		beacon_data_len = beacon->head_len;
4279cd7760e6SSimon Wunderlich 		break;
4280b8456a14SChun-Yeow Yeoh 	case NL80211_IFTYPE_MESH_POINT:
4281b8456a14SChun-Yeow Yeoh 		beacon_data = beacon->head;
4282b8456a14SChun-Yeow Yeoh 		beacon_data_len = beacon->head_len;
4283b8456a14SChun-Yeow Yeoh 		break;
4284cd7760e6SSimon Wunderlich 	default:
4285cd7760e6SSimon Wunderlich 		return;
4286cd7760e6SSimon Wunderlich 	}
42870d06d9baSAndrei Otcheretianski 
428873da7d5bSSimon Wunderlich 	rcu_read_lock();
4289af296bdbSMichal Kazior 	for (i = 0; i < IEEE80211_MAX_CSA_COUNTERS_NUM; ++i) {
429073da7d5bSSimon Wunderlich 		resp = rcu_dereference(sdata->u.ap.probe_resp);
429173da7d5bSSimon Wunderlich 
4292af296bdbSMichal Kazior 		if (beacon->csa_counter_offsets[i]) {
4293af296bdbSMichal Kazior 			if (WARN_ON_ONCE(beacon->csa_counter_offsets[i] >=
4294af296bdbSMichal Kazior 					 beacon_data_len)) {
429573da7d5bSSimon Wunderlich 				rcu_read_unlock();
429673da7d5bSSimon Wunderlich 				return;
429773da7d5bSSimon Wunderlich 			}
4298af296bdbSMichal Kazior 
4299af296bdbSMichal Kazior 			beacon_data[beacon->csa_counter_offsets[i]] = count;
4300af296bdbSMichal Kazior 		}
4301af296bdbSMichal Kazior 
4302af296bdbSMichal Kazior 		if (sdata->vif.type == NL80211_IFTYPE_AP && resp)
4303af296bdbSMichal Kazior 			resp->data[resp->csa_counter_offsets[i]] = count;
4304af296bdbSMichal Kazior 	}
430573da7d5bSSimon Wunderlich 	rcu_read_unlock();
430673da7d5bSSimon Wunderlich }
43071af586c9SAndrei Otcheretianski 
4308e996ec2aSWojciech Dubowik static u8 __ieee80211_csa_update_counter(struct beacon_data *beacon)
4309e996ec2aSWojciech Dubowik {
4310e996ec2aSWojciech Dubowik 	beacon->csa_current_counter--;
4311e996ec2aSWojciech Dubowik 
4312e996ec2aSWojciech Dubowik 	/* the counter should never reach 0 */
4313e996ec2aSWojciech Dubowik 	WARN_ON_ONCE(!beacon->csa_current_counter);
4314e996ec2aSWojciech Dubowik 
4315e996ec2aSWojciech Dubowik 	return beacon->csa_current_counter;
4316e996ec2aSWojciech Dubowik }
4317e996ec2aSWojciech Dubowik 
43181af586c9SAndrei Otcheretianski u8 ieee80211_csa_update_counter(struct ieee80211_vif *vif)
43191af586c9SAndrei Otcheretianski {
43201af586c9SAndrei Otcheretianski 	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
4321af296bdbSMichal Kazior 	struct beacon_data *beacon = NULL;
4322af296bdbSMichal Kazior 	u8 count = 0;
432373da7d5bSSimon Wunderlich 
4324af296bdbSMichal Kazior 	rcu_read_lock();
4325af296bdbSMichal Kazior 
4326af296bdbSMichal Kazior 	if (sdata->vif.type == NL80211_IFTYPE_AP)
4327af296bdbSMichal Kazior 		beacon = rcu_dereference(sdata->u.ap.beacon);
4328af296bdbSMichal Kazior 	else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
4329af296bdbSMichal Kazior 		beacon = rcu_dereference(sdata->u.ibss.presp);
4330af296bdbSMichal Kazior 	else if (ieee80211_vif_is_mesh(&sdata->vif))
4331af296bdbSMichal Kazior 		beacon = rcu_dereference(sdata->u.mesh.beacon);
4332af296bdbSMichal Kazior 
4333af296bdbSMichal Kazior 	if (!beacon)
4334af296bdbSMichal Kazior 		goto unlock;
4335af296bdbSMichal Kazior 
4336e996ec2aSWojciech Dubowik 	count = __ieee80211_csa_update_counter(beacon);
43371af586c9SAndrei Otcheretianski 
4338af296bdbSMichal Kazior unlock:
4339af296bdbSMichal Kazior 	rcu_read_unlock();
4340af296bdbSMichal Kazior 	return count;
43410d06d9baSAndrei Otcheretianski }
43421af586c9SAndrei Otcheretianski EXPORT_SYMBOL(ieee80211_csa_update_counter);
43430d06d9baSAndrei Otcheretianski 
434403737001SGregory Greenman void ieee80211_csa_set_counter(struct ieee80211_vif *vif, u8 counter)
434503737001SGregory Greenman {
434603737001SGregory Greenman 	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
434703737001SGregory Greenman 	struct beacon_data *beacon = NULL;
434803737001SGregory Greenman 
434903737001SGregory Greenman 	rcu_read_lock();
435003737001SGregory Greenman 
435103737001SGregory Greenman 	if (sdata->vif.type == NL80211_IFTYPE_AP)
435203737001SGregory Greenman 		beacon = rcu_dereference(sdata->u.ap.beacon);
435303737001SGregory Greenman 	else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
435403737001SGregory Greenman 		beacon = rcu_dereference(sdata->u.ibss.presp);
435503737001SGregory Greenman 	else if (ieee80211_vif_is_mesh(&sdata->vif))
435603737001SGregory Greenman 		beacon = rcu_dereference(sdata->u.mesh.beacon);
435703737001SGregory Greenman 
435803737001SGregory Greenman 	if (!beacon)
435903737001SGregory Greenman 		goto unlock;
436003737001SGregory Greenman 
436103737001SGregory Greenman 	if (counter < beacon->csa_current_counter)
436203737001SGregory Greenman 		beacon->csa_current_counter = counter;
436303737001SGregory Greenman 
436403737001SGregory Greenman unlock:
436503737001SGregory Greenman 	rcu_read_unlock();
436603737001SGregory Greenman }
436703737001SGregory Greenman EXPORT_SYMBOL(ieee80211_csa_set_counter);
436803737001SGregory Greenman 
436973da7d5bSSimon Wunderlich bool ieee80211_csa_is_complete(struct ieee80211_vif *vif)
437073da7d5bSSimon Wunderlich {
437173da7d5bSSimon Wunderlich 	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
437273da7d5bSSimon Wunderlich 	struct beacon_data *beacon = NULL;
437373da7d5bSSimon Wunderlich 	u8 *beacon_data;
437473da7d5bSSimon Wunderlich 	size_t beacon_data_len;
437573da7d5bSSimon Wunderlich 	int ret = false;
437673da7d5bSSimon Wunderlich 
437773da7d5bSSimon Wunderlich 	if (!ieee80211_sdata_running(sdata))
437873da7d5bSSimon Wunderlich 		return false;
437973da7d5bSSimon Wunderlich 
438073da7d5bSSimon Wunderlich 	rcu_read_lock();
438173da7d5bSSimon Wunderlich 	if (vif->type == NL80211_IFTYPE_AP) {
438273da7d5bSSimon Wunderlich 		struct ieee80211_if_ap *ap = &sdata->u.ap;
438373da7d5bSSimon Wunderlich 
438473da7d5bSSimon Wunderlich 		beacon = rcu_dereference(ap->beacon);
438573da7d5bSSimon Wunderlich 		if (WARN_ON(!beacon || !beacon->tail))
438673da7d5bSSimon Wunderlich 			goto out;
438773da7d5bSSimon Wunderlich 		beacon_data = beacon->tail;
438873da7d5bSSimon Wunderlich 		beacon_data_len = beacon->tail_len;
4389cd7760e6SSimon Wunderlich 	} else if (vif->type == NL80211_IFTYPE_ADHOC) {
4390cd7760e6SSimon Wunderlich 		struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
4391cd7760e6SSimon Wunderlich 
4392cd7760e6SSimon Wunderlich 		beacon = rcu_dereference(ifibss->presp);
4393cd7760e6SSimon Wunderlich 		if (!beacon)
4394cd7760e6SSimon Wunderlich 			goto out;
4395cd7760e6SSimon Wunderlich 
4396cd7760e6SSimon Wunderlich 		beacon_data = beacon->head;
4397cd7760e6SSimon Wunderlich 		beacon_data_len = beacon->head_len;
4398b8456a14SChun-Yeow Yeoh 	} else if (vif->type == NL80211_IFTYPE_MESH_POINT) {
4399b8456a14SChun-Yeow Yeoh 		struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
4400b8456a14SChun-Yeow Yeoh 
4401b8456a14SChun-Yeow Yeoh 		beacon = rcu_dereference(ifmsh->beacon);
4402b8456a14SChun-Yeow Yeoh 		if (!beacon)
4403b8456a14SChun-Yeow Yeoh 			goto out;
4404b8456a14SChun-Yeow Yeoh 
4405b8456a14SChun-Yeow Yeoh 		beacon_data = beacon->head;
4406b8456a14SChun-Yeow Yeoh 		beacon_data_len = beacon->head_len;
440773da7d5bSSimon Wunderlich 	} else {
440873da7d5bSSimon Wunderlich 		WARN_ON(1);
440973da7d5bSSimon Wunderlich 		goto out;
441073da7d5bSSimon Wunderlich 	}
441173da7d5bSSimon Wunderlich 
441210d78f27SMichal Kazior 	if (!beacon->csa_counter_offsets[0])
441310d78f27SMichal Kazior 		goto out;
441410d78f27SMichal Kazior 
4415af296bdbSMichal Kazior 	if (WARN_ON_ONCE(beacon->csa_counter_offsets[0] > beacon_data_len))
441673da7d5bSSimon Wunderlich 		goto out;
441773da7d5bSSimon Wunderlich 
4418af296bdbSMichal Kazior 	if (beacon_data[beacon->csa_counter_offsets[0]] == 1)
441973da7d5bSSimon Wunderlich 		ret = true;
442073da7d5bSSimon Wunderlich  out:
442173da7d5bSSimon Wunderlich 	rcu_read_unlock();
442273da7d5bSSimon Wunderlich 
442373da7d5bSSimon Wunderlich 	return ret;
442473da7d5bSSimon Wunderlich }
442573da7d5bSSimon Wunderlich EXPORT_SYMBOL(ieee80211_csa_is_complete);
442673da7d5bSSimon Wunderlich 
44276ec8c332SAndrei Otcheretianski static struct sk_buff *
44286ec8c332SAndrei Otcheretianski __ieee80211_beacon_get(struct ieee80211_hw *hw,
4429eddcbb94SJohannes Berg 		       struct ieee80211_vif *vif,
44306ec8c332SAndrei Otcheretianski 		       struct ieee80211_mutable_offsets *offs,
44316ec8c332SAndrei Otcheretianski 		       bool is_template)
4432e2ebc74dSJohannes Berg {
4433e2ebc74dSJohannes Berg 	struct ieee80211_local *local = hw_to_local(hw);
4434af296bdbSMichal Kazior 	struct beacon_data *beacon = NULL;
44359d139c81SJohannes Berg 	struct sk_buff *skb = NULL;
4436e039fa4aSJohannes Berg 	struct ieee80211_tx_info *info;
4437e2ebc74dSJohannes Berg 	struct ieee80211_sub_if_data *sdata = NULL;
443857fbcce3SJohannes Berg 	enum nl80211_band band;
4439e00cfce0SJouni Malinen 	struct ieee80211_tx_rate_control txrc;
444055de908aSJohannes Berg 	struct ieee80211_chanctx_conf *chanctx_conf;
44411af586c9SAndrei Otcheretianski 	int csa_off_base = 0;
44428318d78aSJohannes Berg 
44435dfdaf58SJohannes Berg 	rcu_read_lock();
4444e2ebc74dSJohannes Berg 
444532bfd35dSJohannes Berg 	sdata = vif_to_sdata(vif);
444655de908aSJohannes Berg 	chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
444733b64eb2SLuis Carlos Cobo 
444855de908aSJohannes Berg 	if (!ieee80211_sdata_running(sdata) || !chanctx_conf)
4449eb3e554bSFelix Fietkau 		goto out;
4450eb3e554bSFelix Fietkau 
44516ec8c332SAndrei Otcheretianski 	if (offs)
44526ec8c332SAndrei Otcheretianski 		memset(offs, 0, sizeof(*offs));
4453eddcbb94SJohannes Berg 
445405c914feSJohannes Berg 	if (sdata->vif.type == NL80211_IFTYPE_AP) {
4455d012a605SMarco Porsch 		struct ieee80211_if_ap *ap = &sdata->u.ap;
4456d012a605SMarco Porsch 
4457af296bdbSMichal Kazior 		beacon = rcu_dereference(ap->beacon);
44583ad97fbcSDan Carpenter 		if (beacon) {
445910d78f27SMichal Kazior 			if (beacon->csa_counter_offsets[0]) {
44601af586c9SAndrei Otcheretianski 				if (!is_template)
4461e996ec2aSWojciech Dubowik 					__ieee80211_csa_update_counter(beacon);
44621af586c9SAndrei Otcheretianski 
44631af586c9SAndrei Otcheretianski 				ieee80211_set_csa(sdata, beacon);
44641af586c9SAndrei Otcheretianski 			}
446573da7d5bSSimon Wunderlich 
4466902acc78SJohannes Berg 			/*
4467902acc78SJohannes Berg 			 * headroom, head length,
4468902acc78SJohannes Berg 			 * tail length and maximum TIM length
4469902acc78SJohannes Berg 			 */
4470902acc78SJohannes Berg 			skb = dev_alloc_skb(local->tx_headroom +
4471902acc78SJohannes Berg 					    beacon->head_len +
447270dabeb7SFelix Fietkau 					    beacon->tail_len + 256 +
447370dabeb7SFelix Fietkau 					    local->hw.extra_beacon_tailroom);
4474e2ebc74dSJohannes Berg 			if (!skb)
44755dfdaf58SJohannes Berg 				goto out;
4476e2ebc74dSJohannes Berg 
4477e2ebc74dSJohannes Berg 			skb_reserve(skb, local->tx_headroom);
447859ae1d12SJohannes Berg 			skb_put_data(skb, beacon->head, beacon->head_len);
4479e2ebc74dSJohannes Berg 
44806ec8c332SAndrei Otcheretianski 			ieee80211_beacon_add_tim(sdata, &ap->ps, skb,
44816ec8c332SAndrei Otcheretianski 						 is_template);
4482e2ebc74dSJohannes Berg 
44836ec8c332SAndrei Otcheretianski 			if (offs) {
44846ec8c332SAndrei Otcheretianski 				offs->tim_offset = beacon->head_len;
44856ec8c332SAndrei Otcheretianski 				offs->tim_length = skb->len - beacon->head_len;
44861af586c9SAndrei Otcheretianski 
44871af586c9SAndrei Otcheretianski 				/* for AP the csa offsets are from tail */
44881af586c9SAndrei Otcheretianski 				csa_off_base = skb->len;
44896ec8c332SAndrei Otcheretianski 			}
4490eddcbb94SJohannes Berg 
44915dfdaf58SJohannes Berg 			if (beacon->tail)
449259ae1d12SJohannes Berg 				skb_put_data(skb, beacon->tail,
449359ae1d12SJohannes Berg 					     beacon->tail_len);
44949d139c81SJohannes Berg 		} else
44959d139c81SJohannes Berg 			goto out;
449605c914feSJohannes Berg 	} else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
449746900298SJohannes Berg 		struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
44989d139c81SJohannes Berg 		struct ieee80211_hdr *hdr;
449933b64eb2SLuis Carlos Cobo 
4500af296bdbSMichal Kazior 		beacon = rcu_dereference(ifibss->presp);
4501af296bdbSMichal Kazior 		if (!beacon)
45029d139c81SJohannes Berg 			goto out;
45039d139c81SJohannes Berg 
450410d78f27SMichal Kazior 		if (beacon->csa_counter_offsets[0]) {
45051af586c9SAndrei Otcheretianski 			if (!is_template)
4506e996ec2aSWojciech Dubowik 				__ieee80211_csa_update_counter(beacon);
4507cd7760e6SSimon Wunderlich 
4508af296bdbSMichal Kazior 			ieee80211_set_csa(sdata, beacon);
45091af586c9SAndrei Otcheretianski 		}
4510cd7760e6SSimon Wunderlich 
4511af296bdbSMichal Kazior 		skb = dev_alloc_skb(local->tx_headroom + beacon->head_len +
451270dabeb7SFelix Fietkau 				    local->hw.extra_beacon_tailroom);
45139d139c81SJohannes Berg 		if (!skb)
45149d139c81SJohannes Berg 			goto out;
4515c3ffeab4SJohannes Berg 		skb_reserve(skb, local->tx_headroom);
451659ae1d12SJohannes Berg 		skb_put_data(skb, beacon->head, beacon->head_len);
45179d139c81SJohannes Berg 
45189d139c81SJohannes Berg 		hdr = (struct ieee80211_hdr *) skb->data;
4519e7827a70SHarvey Harrison 		hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
45209d139c81SJohannes Berg 						 IEEE80211_STYPE_BEACON);
4521902acc78SJohannes Berg 	} else if (ieee80211_vif_is_mesh(&sdata->vif)) {
4522dbf498fbSJavier Cardona 		struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
4523472dbc45SJohannes Berg 
4524af296bdbSMichal Kazior 		beacon = rcu_dereference(ifmsh->beacon);
4525af296bdbSMichal Kazior 		if (!beacon)
4526ac1bd846SJohannes Berg 			goto out;
4527ac1bd846SJohannes Berg 
452810d78f27SMichal Kazior 		if (beacon->csa_counter_offsets[0]) {
45291af586c9SAndrei Otcheretianski 			if (!is_template)
45301af586c9SAndrei Otcheretianski 				/* TODO: For mesh csa_counter is in TU, so
45311af586c9SAndrei Otcheretianski 				 * decrementing it by one isn't correct, but
45321af586c9SAndrei Otcheretianski 				 * for now we leave it consistent with overall
45331af586c9SAndrei Otcheretianski 				 * mac80211's behavior.
45341af586c9SAndrei Otcheretianski 				 */
4535e996ec2aSWojciech Dubowik 				__ieee80211_csa_update_counter(beacon);
45361af586c9SAndrei Otcheretianski 
4537af296bdbSMichal Kazior 			ieee80211_set_csa(sdata, beacon);
45381af586c9SAndrei Otcheretianski 		}
4539b8456a14SChun-Yeow Yeoh 
4540dbf498fbSJavier Cardona 		if (ifmsh->sync_ops)
4541445cd452SMasashi Honma 			ifmsh->sync_ops->adjust_tsf(sdata, beacon);
4542dbf498fbSJavier Cardona 
45433b69a9c5SThomas Pedersen 		skb = dev_alloc_skb(local->tx_headroom +
4544af296bdbSMichal Kazior 				    beacon->head_len +
45453f52b7e3SMarco Porsch 				    256 + /* TIM IE */
4546af296bdbSMichal Kazior 				    beacon->tail_len +
454770dabeb7SFelix Fietkau 				    local->hw.extra_beacon_tailroom);
4548902acc78SJohannes Berg 		if (!skb)
4549902acc78SJohannes Berg 			goto out;
45502b5e1967SThomas Pedersen 		skb_reserve(skb, local->tx_headroom);
455159ae1d12SJohannes Berg 		skb_put_data(skb, beacon->head, beacon->head_len);
45526ec8c332SAndrei Otcheretianski 		ieee80211_beacon_add_tim(sdata, &ifmsh->ps, skb, is_template);
45536ec8c332SAndrei Otcheretianski 
45546ec8c332SAndrei Otcheretianski 		if (offs) {
4555af296bdbSMichal Kazior 			offs->tim_offset = beacon->head_len;
4556af296bdbSMichal Kazior 			offs->tim_length = skb->len - beacon->head_len;
45576ec8c332SAndrei Otcheretianski 		}
45586ec8c332SAndrei Otcheretianski 
455959ae1d12SJohannes Berg 		skb_put_data(skb, beacon->tail, beacon->tail_len);
45609d139c81SJohannes Berg 	} else {
45619d139c81SJohannes Berg 		WARN_ON(1);
456233b64eb2SLuis Carlos Cobo 		goto out;
456333b64eb2SLuis Carlos Cobo 	}
456433b64eb2SLuis Carlos Cobo 
45651af586c9SAndrei Otcheretianski 	/* CSA offsets */
4566af296bdbSMichal Kazior 	if (offs && beacon) {
45671af586c9SAndrei Otcheretianski 		int i;
45681af586c9SAndrei Otcheretianski 
45691af586c9SAndrei Otcheretianski 		for (i = 0; i < IEEE80211_MAX_CSA_COUNTERS_NUM; i++) {
4570af296bdbSMichal Kazior 			u16 csa_off = beacon->csa_counter_offsets[i];
45711af586c9SAndrei Otcheretianski 
45721af586c9SAndrei Otcheretianski 			if (!csa_off)
45731af586c9SAndrei Otcheretianski 				continue;
45741af586c9SAndrei Otcheretianski 
45751af586c9SAndrei Otcheretianski 			offs->csa_counter_offs[i] = csa_off_base + csa_off;
45761af586c9SAndrei Otcheretianski 		}
45771af586c9SAndrei Otcheretianski 	}
45781af586c9SAndrei Otcheretianski 
45794bf88530SJohannes Berg 	band = chanctx_conf->def.chan->band;
458055de908aSJohannes Berg 
4581e039fa4aSJohannes Berg 	info = IEEE80211_SKB_CB(skb);
4582e039fa4aSJohannes Berg 
45833b8d81e0SJohannes Berg 	info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
4584e00cfce0SJouni Malinen 	info->flags |= IEEE80211_TX_CTL_NO_ACK;
4585e039fa4aSJohannes Berg 	info->band = band;
4586e00cfce0SJouni Malinen 
4587e00cfce0SJouni Malinen 	memset(&txrc, 0, sizeof(txrc));
4588e00cfce0SJouni Malinen 	txrc.hw = hw;
4589e31583cdSJohannes Berg 	txrc.sband = local->hw.wiphy->bands[band];
4590e00cfce0SJouni Malinen 	txrc.bss_conf = &sdata->vif.bss_conf;
4591e00cfce0SJouni Malinen 	txrc.skb = skb;
4592e00cfce0SJouni Malinen 	txrc.reported_rate.idx = -1;
459337eb0b16SJouni Malinen 	txrc.rate_idx_mask = sdata->rc_rateidx_mask[band];
45948f0729b1SFelix Fietkau 	txrc.bss = true;
4595e00cfce0SJouni Malinen 	rate_control_get_rate(sdata, NULL, &txrc);
4596e2ebc74dSJohannes Berg 
4597e039fa4aSJohannes Berg 	info->control.vif = vif;
4598f591fa5dSJohannes Berg 
4599a472e71bSJohn W. Linville 	info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT |
4600a472e71bSJohn W. Linville 			IEEE80211_TX_CTL_ASSIGN_SEQ |
4601a472e71bSJohn W. Linville 			IEEE80211_TX_CTL_FIRST_FRAGMENT;
46025dfdaf58SJohannes Berg  out:
46035dfdaf58SJohannes Berg 	rcu_read_unlock();
4604e2ebc74dSJohannes Berg 	return skb;
46056ec8c332SAndrei Otcheretianski 
46066ec8c332SAndrei Otcheretianski }
46076ec8c332SAndrei Otcheretianski 
46086ec8c332SAndrei Otcheretianski struct sk_buff *
46096ec8c332SAndrei Otcheretianski ieee80211_beacon_get_template(struct ieee80211_hw *hw,
46106ec8c332SAndrei Otcheretianski 			      struct ieee80211_vif *vif,
46116ec8c332SAndrei Otcheretianski 			      struct ieee80211_mutable_offsets *offs)
46126ec8c332SAndrei Otcheretianski {
46136ec8c332SAndrei Otcheretianski 	return __ieee80211_beacon_get(hw, vif, offs, true);
46146ec8c332SAndrei Otcheretianski }
46156ec8c332SAndrei Otcheretianski EXPORT_SYMBOL(ieee80211_beacon_get_template);
46166ec8c332SAndrei Otcheretianski 
46176ec8c332SAndrei Otcheretianski struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
46186ec8c332SAndrei Otcheretianski 					 struct ieee80211_vif *vif,
46196ec8c332SAndrei Otcheretianski 					 u16 *tim_offset, u16 *tim_length)
46206ec8c332SAndrei Otcheretianski {
46216ec8c332SAndrei Otcheretianski 	struct ieee80211_mutable_offsets offs = {};
46226ec8c332SAndrei Otcheretianski 	struct sk_buff *bcn = __ieee80211_beacon_get(hw, vif, &offs, false);
462335afa588SHelmut Schaa 	struct sk_buff *copy;
462435afa588SHelmut Schaa 	struct ieee80211_supported_band *sband;
462535afa588SHelmut Schaa 	int shift;
462635afa588SHelmut Schaa 
462735afa588SHelmut Schaa 	if (!bcn)
462835afa588SHelmut Schaa 		return bcn;
46296ec8c332SAndrei Otcheretianski 
46306ec8c332SAndrei Otcheretianski 	if (tim_offset)
46316ec8c332SAndrei Otcheretianski 		*tim_offset = offs.tim_offset;
46326ec8c332SAndrei Otcheretianski 
46336ec8c332SAndrei Otcheretianski 	if (tim_length)
46346ec8c332SAndrei Otcheretianski 		*tim_length = offs.tim_length;
46356ec8c332SAndrei Otcheretianski 
463635afa588SHelmut Schaa 	if (ieee80211_hw_check(hw, BEACON_TX_STATUS) ||
463735afa588SHelmut Schaa 	    !hw_to_local(hw)->monitors)
463835afa588SHelmut Schaa 		return bcn;
463935afa588SHelmut Schaa 
464035afa588SHelmut Schaa 	/* send a copy to monitor interfaces */
464135afa588SHelmut Schaa 	copy = skb_copy(bcn, GFP_ATOMIC);
464235afa588SHelmut Schaa 	if (!copy)
464335afa588SHelmut Schaa 		return bcn;
464435afa588SHelmut Schaa 
464535afa588SHelmut Schaa 	shift = ieee80211_vif_get_shift(vif);
464621a8e9ddSMohammed Shafi Shajakhan 	sband = ieee80211_get_sband(vif_to_sdata(vif));
464721a8e9ddSMohammed Shafi Shajakhan 	if (!sband)
464821a8e9ddSMohammed Shafi Shajakhan 		return bcn;
464921a8e9ddSMohammed Shafi Shajakhan 
465035afa588SHelmut Schaa 	ieee80211_tx_monitor(hw_to_local(hw), copy, sband, 1, shift, false);
465135afa588SHelmut Schaa 
46526ec8c332SAndrei Otcheretianski 	return bcn;
4653e2ebc74dSJohannes Berg }
4654eddcbb94SJohannes Berg EXPORT_SYMBOL(ieee80211_beacon_get_tim);
4655e2ebc74dSJohannes Berg 
465602945821SArik Nemtsov struct sk_buff *ieee80211_proberesp_get(struct ieee80211_hw *hw,
465702945821SArik Nemtsov 					struct ieee80211_vif *vif)
465802945821SArik Nemtsov {
465902945821SArik Nemtsov 	struct ieee80211_if_ap *ap = NULL;
4660aa7a0080SEyal Shapira 	struct sk_buff *skb = NULL;
4661aa7a0080SEyal Shapira 	struct probe_resp *presp = NULL;
466202945821SArik Nemtsov 	struct ieee80211_hdr *hdr;
466302945821SArik Nemtsov 	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
466402945821SArik Nemtsov 
466502945821SArik Nemtsov 	if (sdata->vif.type != NL80211_IFTYPE_AP)
466602945821SArik Nemtsov 		return NULL;
466702945821SArik Nemtsov 
466802945821SArik Nemtsov 	rcu_read_lock();
466902945821SArik Nemtsov 
467002945821SArik Nemtsov 	ap = &sdata->u.ap;
467102945821SArik Nemtsov 	presp = rcu_dereference(ap->probe_resp);
467202945821SArik Nemtsov 	if (!presp)
467302945821SArik Nemtsov 		goto out;
467402945821SArik Nemtsov 
4675aa7a0080SEyal Shapira 	skb = dev_alloc_skb(presp->len);
467602945821SArik Nemtsov 	if (!skb)
467702945821SArik Nemtsov 		goto out;
467802945821SArik Nemtsov 
467959ae1d12SJohannes Berg 	skb_put_data(skb, presp->data, presp->len);
4680aa7a0080SEyal Shapira 
468102945821SArik Nemtsov 	hdr = (struct ieee80211_hdr *) skb->data;
468202945821SArik Nemtsov 	memset(hdr->addr1, 0, sizeof(hdr->addr1));
468302945821SArik Nemtsov 
468402945821SArik Nemtsov out:
468502945821SArik Nemtsov 	rcu_read_unlock();
468602945821SArik Nemtsov 	return skb;
468702945821SArik Nemtsov }
468802945821SArik Nemtsov EXPORT_SYMBOL(ieee80211_proberesp_get);
468902945821SArik Nemtsov 
46907044cc56SKalle Valo struct sk_buff *ieee80211_pspoll_get(struct ieee80211_hw *hw,
46917044cc56SKalle Valo 				     struct ieee80211_vif *vif)
46927044cc56SKalle Valo {
46937044cc56SKalle Valo 	struct ieee80211_sub_if_data *sdata;
46947044cc56SKalle Valo 	struct ieee80211_if_managed *ifmgd;
46957044cc56SKalle Valo 	struct ieee80211_pspoll *pspoll;
46967044cc56SKalle Valo 	struct ieee80211_local *local;
46977044cc56SKalle Valo 	struct sk_buff *skb;
46987044cc56SKalle Valo 
46997044cc56SKalle Valo 	if (WARN_ON(vif->type != NL80211_IFTYPE_STATION))
47007044cc56SKalle Valo 		return NULL;
47017044cc56SKalle Valo 
47027044cc56SKalle Valo 	sdata = vif_to_sdata(vif);
47037044cc56SKalle Valo 	ifmgd = &sdata->u.mgd;
47047044cc56SKalle Valo 	local = sdata->local;
47057044cc56SKalle Valo 
47067044cc56SKalle Valo 	skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*pspoll));
4707d15b8459SJoe Perches 	if (!skb)
47087044cc56SKalle Valo 		return NULL;
4709d15b8459SJoe Perches 
47107044cc56SKalle Valo 	skb_reserve(skb, local->hw.extra_tx_headroom);
47117044cc56SKalle Valo 
4712b080db58SJohannes Berg 	pspoll = skb_put_zero(skb, sizeof(*pspoll));
47137044cc56SKalle Valo 	pspoll->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
47147044cc56SKalle Valo 					    IEEE80211_STYPE_PSPOLL);
47157044cc56SKalle Valo 	pspoll->aid = cpu_to_le16(ifmgd->aid);
47167044cc56SKalle Valo 
47177044cc56SKalle Valo 	/* aid in PS-Poll has its two MSBs each set to 1 */
47187044cc56SKalle Valo 	pspoll->aid |= cpu_to_le16(1 << 15 | 1 << 14);
47197044cc56SKalle Valo 
47207044cc56SKalle Valo 	memcpy(pspoll->bssid, ifmgd->bssid, ETH_ALEN);
47217044cc56SKalle Valo 	memcpy(pspoll->ta, vif->addr, ETH_ALEN);
47227044cc56SKalle Valo 
47237044cc56SKalle Valo 	return skb;
47247044cc56SKalle Valo }
47257044cc56SKalle Valo EXPORT_SYMBOL(ieee80211_pspoll_get);
47267044cc56SKalle Valo 
47277044cc56SKalle Valo struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,
47287b6ddeafSJohannes Berg 				       struct ieee80211_vif *vif,
47297b6ddeafSJohannes Berg 				       bool qos_ok)
47307044cc56SKalle Valo {
47317044cc56SKalle Valo 	struct ieee80211_hdr_3addr *nullfunc;
47327044cc56SKalle Valo 	struct ieee80211_sub_if_data *sdata;
47337044cc56SKalle Valo 	struct ieee80211_if_managed *ifmgd;
47347044cc56SKalle Valo 	struct ieee80211_local *local;
47357044cc56SKalle Valo 	struct sk_buff *skb;
47367b6ddeafSJohannes Berg 	bool qos = false;
47377044cc56SKalle Valo 
47387044cc56SKalle Valo 	if (WARN_ON(vif->type != NL80211_IFTYPE_STATION))
47397044cc56SKalle Valo 		return NULL;
47407044cc56SKalle Valo 
47417044cc56SKalle Valo 	sdata = vif_to_sdata(vif);
47427044cc56SKalle Valo 	ifmgd = &sdata->u.mgd;
47437044cc56SKalle Valo 	local = sdata->local;
47447044cc56SKalle Valo 
47457b6ddeafSJohannes Berg 	if (qos_ok) {
47467b6ddeafSJohannes Berg 		struct sta_info *sta;
47477b6ddeafSJohannes Berg 
47487b6ddeafSJohannes Berg 		rcu_read_lock();
47497b6ddeafSJohannes Berg 		sta = sta_info_get(sdata, ifmgd->bssid);
47507b6ddeafSJohannes Berg 		qos = sta && sta->sta.wme;
47517b6ddeafSJohannes Berg 		rcu_read_unlock();
47527b6ddeafSJohannes Berg 	}
47537b6ddeafSJohannes Berg 
47547b6ddeafSJohannes Berg 	skb = dev_alloc_skb(local->hw.extra_tx_headroom +
47557b6ddeafSJohannes Berg 			    sizeof(*nullfunc) + 2);
4756d15b8459SJoe Perches 	if (!skb)
47577044cc56SKalle Valo 		return NULL;
4758d15b8459SJoe Perches 
47597044cc56SKalle Valo 	skb_reserve(skb, local->hw.extra_tx_headroom);
47607044cc56SKalle Valo 
4761b080db58SJohannes Berg 	nullfunc = skb_put_zero(skb, sizeof(*nullfunc));
47627044cc56SKalle Valo 	nullfunc->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
47637044cc56SKalle Valo 					      IEEE80211_STYPE_NULLFUNC |
47647044cc56SKalle Valo 					      IEEE80211_FCTL_TODS);
47657b6ddeafSJohannes Berg 	if (qos) {
4766e0ba7095SJohannes Berg 		__le16 qoshdr = cpu_to_le16(7);
47677b6ddeafSJohannes Berg 
47687b6ddeafSJohannes Berg 		BUILD_BUG_ON((IEEE80211_STYPE_QOS_NULLFUNC |
47697b6ddeafSJohannes Berg 			      IEEE80211_STYPE_NULLFUNC) !=
47707b6ddeafSJohannes Berg 			     IEEE80211_STYPE_QOS_NULLFUNC);
47717b6ddeafSJohannes Berg 		nullfunc->frame_control |=
47727b6ddeafSJohannes Berg 			cpu_to_le16(IEEE80211_STYPE_QOS_NULLFUNC);
47737b6ddeafSJohannes Berg 		skb->priority = 7;
47747b6ddeafSJohannes Berg 		skb_set_queue_mapping(skb, IEEE80211_AC_VO);
4775e0ba7095SJohannes Berg 		skb_put_data(skb, &qoshdr, sizeof(qoshdr));
47767b6ddeafSJohannes Berg 	}
47777b6ddeafSJohannes Berg 
47787044cc56SKalle Valo 	memcpy(nullfunc->addr1, ifmgd->bssid, ETH_ALEN);
47797044cc56SKalle Valo 	memcpy(nullfunc->addr2, vif->addr, ETH_ALEN);
47807044cc56SKalle Valo 	memcpy(nullfunc->addr3, ifmgd->bssid, ETH_ALEN);
47817044cc56SKalle Valo 
47827044cc56SKalle Valo 	return skb;
47837044cc56SKalle Valo }
47847044cc56SKalle Valo EXPORT_SYMBOL(ieee80211_nullfunc_get);
47857044cc56SKalle Valo 
478605e54ea6SKalle Valo struct sk_buff *ieee80211_probereq_get(struct ieee80211_hw *hw,
4787a344d677SJohannes Berg 				       const u8 *src_addr,
478805e54ea6SKalle Valo 				       const u8 *ssid, size_t ssid_len,
4789b9a9ada1SJohannes Berg 				       size_t tailroom)
479005e54ea6SKalle Valo {
4791a344d677SJohannes Berg 	struct ieee80211_local *local = hw_to_local(hw);
479205e54ea6SKalle Valo 	struct ieee80211_hdr_3addr *hdr;
479305e54ea6SKalle Valo 	struct sk_buff *skb;
479405e54ea6SKalle Valo 	size_t ie_ssid_len;
479505e54ea6SKalle Valo 	u8 *pos;
479605e54ea6SKalle Valo 
479705e54ea6SKalle Valo 	ie_ssid_len = 2 + ssid_len;
479805e54ea6SKalle Valo 
479905e54ea6SKalle Valo 	skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*hdr) +
4800b9a9ada1SJohannes Berg 			    ie_ssid_len + tailroom);
4801d15b8459SJoe Perches 	if (!skb)
480205e54ea6SKalle Valo 		return NULL;
480305e54ea6SKalle Valo 
480405e54ea6SKalle Valo 	skb_reserve(skb, local->hw.extra_tx_headroom);
480505e54ea6SKalle Valo 
4806b080db58SJohannes Berg 	hdr = skb_put_zero(skb, sizeof(*hdr));
480705e54ea6SKalle Valo 	hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
480805e54ea6SKalle Valo 					 IEEE80211_STYPE_PROBE_REQ);
4809e83e6541SJohannes Berg 	eth_broadcast_addr(hdr->addr1);
4810a344d677SJohannes Berg 	memcpy(hdr->addr2, src_addr, ETH_ALEN);
4811e83e6541SJohannes Berg 	eth_broadcast_addr(hdr->addr3);
481205e54ea6SKalle Valo 
481305e54ea6SKalle Valo 	pos = skb_put(skb, ie_ssid_len);
481405e54ea6SKalle Valo 	*pos++ = WLAN_EID_SSID;
481505e54ea6SKalle Valo 	*pos++ = ssid_len;
481688c868c4SStanislaw Gruszka 	if (ssid_len)
481705e54ea6SKalle Valo 		memcpy(pos, ssid, ssid_len);
481805e54ea6SKalle Valo 	pos += ssid_len;
481905e54ea6SKalle Valo 
482005e54ea6SKalle Valo 	return skb;
482105e54ea6SKalle Valo }
482205e54ea6SKalle Valo EXPORT_SYMBOL(ieee80211_probereq_get);
482305e54ea6SKalle Valo 
482432bfd35dSJohannes Berg void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
4825e2ebc74dSJohannes Berg 		       const void *frame, size_t frame_len,
4826e039fa4aSJohannes Berg 		       const struct ieee80211_tx_info *frame_txctl,
4827e2ebc74dSJohannes Berg 		       struct ieee80211_rts *rts)
4828e2ebc74dSJohannes Berg {
4829e2ebc74dSJohannes Berg 	const struct ieee80211_hdr *hdr = frame;
4830e2ebc74dSJohannes Berg 
4831065e9605SHarvey Harrison 	rts->frame_control =
4832065e9605SHarvey Harrison 	    cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
483332bfd35dSJohannes Berg 	rts->duration = ieee80211_rts_duration(hw, vif, frame_len,
483432bfd35dSJohannes Berg 					       frame_txctl);
4835e2ebc74dSJohannes Berg 	memcpy(rts->ra, hdr->addr1, sizeof(rts->ra));
4836e2ebc74dSJohannes Berg 	memcpy(rts->ta, hdr->addr2, sizeof(rts->ta));
4837e2ebc74dSJohannes Berg }
4838e2ebc74dSJohannes Berg EXPORT_SYMBOL(ieee80211_rts_get);
4839e2ebc74dSJohannes Berg 
484032bfd35dSJohannes Berg void ieee80211_ctstoself_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
4841e2ebc74dSJohannes Berg 			     const void *frame, size_t frame_len,
4842e039fa4aSJohannes Berg 			     const struct ieee80211_tx_info *frame_txctl,
4843e2ebc74dSJohannes Berg 			     struct ieee80211_cts *cts)
4844e2ebc74dSJohannes Berg {
4845e2ebc74dSJohannes Berg 	const struct ieee80211_hdr *hdr = frame;
4846e2ebc74dSJohannes Berg 
4847065e9605SHarvey Harrison 	cts->frame_control =
4848065e9605SHarvey Harrison 	    cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS);
484932bfd35dSJohannes Berg 	cts->duration = ieee80211_ctstoself_duration(hw, vif,
485032bfd35dSJohannes Berg 						     frame_len, frame_txctl);
4851e2ebc74dSJohannes Berg 	memcpy(cts->ra, hdr->addr1, sizeof(cts->ra));
4852e2ebc74dSJohannes Berg }
4853e2ebc74dSJohannes Berg EXPORT_SYMBOL(ieee80211_ctstoself_get);
4854e2ebc74dSJohannes Berg 
4855e2ebc74dSJohannes Berg struct sk_buff *
485632bfd35dSJohannes Berg ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
4857e039fa4aSJohannes Berg 			  struct ieee80211_vif *vif)
4858e2ebc74dSJohannes Berg {
4859e2ebc74dSJohannes Berg 	struct ieee80211_local *local = hw_to_local(hw);
4860747cf5e9STomas Winkler 	struct sk_buff *skb = NULL;
48615cf121c3SJohannes Berg 	struct ieee80211_tx_data tx;
4862e2ebc74dSJohannes Berg 	struct ieee80211_sub_if_data *sdata;
4863d012a605SMarco Porsch 	struct ps_data *ps;
4864e039fa4aSJohannes Berg 	struct ieee80211_tx_info *info;
486555de908aSJohannes Berg 	struct ieee80211_chanctx_conf *chanctx_conf;
4866e2ebc74dSJohannes Berg 
486732bfd35dSJohannes Berg 	sdata = vif_to_sdata(vif);
48685dfdaf58SJohannes Berg 
48695dfdaf58SJohannes Berg 	rcu_read_lock();
487055de908aSJohannes Berg 	chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
48715dfdaf58SJohannes Berg 
4872d012a605SMarco Porsch 	if (!chanctx_conf)
4873747cf5e9STomas Winkler 		goto out;
48745dfdaf58SJohannes Berg 
4875d012a605SMarco Porsch 	if (sdata->vif.type == NL80211_IFTYPE_AP) {
4876d012a605SMarco Porsch 		struct beacon_data *beacon =
4877d012a605SMarco Porsch 				rcu_dereference(sdata->u.ap.beacon);
4878d012a605SMarco Porsch 
4879d012a605SMarco Porsch 		if (!beacon || !beacon->head)
4880d012a605SMarco Porsch 			goto out;
4881d012a605SMarco Porsch 
4882d012a605SMarco Porsch 		ps = &sdata->u.ap.ps;
48833f52b7e3SMarco Porsch 	} else if (ieee80211_vif_is_mesh(&sdata->vif)) {
48843f52b7e3SMarco Porsch 		ps = &sdata->u.mesh.ps;
4885d012a605SMarco Porsch 	} else {
4886d012a605SMarco Porsch 		goto out;
4887d012a605SMarco Porsch 	}
4888d012a605SMarco Porsch 
4889d012a605SMarco Porsch 	if (ps->dtim_count != 0 || !ps->dtim_bc_mc)
4890747cf5e9STomas Winkler 		goto out; /* send buffered bc/mc only after DTIM beacon */
4891e039fa4aSJohannes Berg 
4892e2ebc74dSJohannes Berg 	while (1) {
4893d012a605SMarco Porsch 		skb = skb_dequeue(&ps->bc_buf);
4894e2ebc74dSJohannes Berg 		if (!skb)
4895747cf5e9STomas Winkler 			goto out;
4896e2ebc74dSJohannes Berg 		local->total_ps_buffered--;
4897e2ebc74dSJohannes Berg 
4898d012a605SMarco Porsch 		if (!skb_queue_empty(&ps->bc_buf) && skb->len >= 2) {
4899e2ebc74dSJohannes Berg 			struct ieee80211_hdr *hdr =
4900e2ebc74dSJohannes Berg 				(struct ieee80211_hdr *) skb->data;
4901e2ebc74dSJohannes Berg 			/* more buffered multicast/broadcast frames ==> set
4902e2ebc74dSJohannes Berg 			 * MoreData flag in IEEE 802.11 header to inform PS
4903e2ebc74dSJohannes Berg 			 * STAs */
4904e2ebc74dSJohannes Berg 			hdr->frame_control |=
4905e2ebc74dSJohannes Berg 				cpu_to_le16(IEEE80211_FCTL_MOREDATA);
4906e2ebc74dSJohannes Berg 		}
4907e2ebc74dSJohannes Berg 
4908112c44b2SMichael Braun 		if (sdata->vif.type == NL80211_IFTYPE_AP)
4909de74a1d9SMichael Braun 			sdata = IEEE80211_DEV_TO_SUB_IF(skb->dev);
49107c10770fSJohannes Berg 		if (!ieee80211_tx_prepare(sdata, &tx, NULL, skb))
4911e2ebc74dSJohannes Berg 			break;
49126b07d9caSFelix Fietkau 		ieee80211_free_txskb(hw, skb);
4913e2ebc74dSJohannes Berg 	}
4914e039fa4aSJohannes Berg 
4915e039fa4aSJohannes Berg 	info = IEEE80211_SKB_CB(skb);
4916e039fa4aSJohannes Berg 
49175cf121c3SJohannes Berg 	tx.flags |= IEEE80211_TX_PS_BUFFERED;
49184bf88530SJohannes Berg 	info->band = chanctx_conf->def.chan->band;
4919e2ebc74dSJohannes Berg 
492097b045d6SJohannes Berg 	if (invoke_tx_handlers(&tx))
4921e2ebc74dSJohannes Berg 		skb = NULL;
4922747cf5e9STomas Winkler  out:
4923d0709a65SJohannes Berg 	rcu_read_unlock();
4924e2ebc74dSJohannes Berg 
4925e2ebc74dSJohannes Berg 	return skb;
4926e2ebc74dSJohannes Berg }
4927e2ebc74dSJohannes Berg EXPORT_SYMBOL(ieee80211_get_buffered_bc);
49283b8d81e0SJohannes Berg 
4929b6da911bSLiad Kaufman int ieee80211_reserve_tid(struct ieee80211_sta *pubsta, u8 tid)
4930b6da911bSLiad Kaufman {
4931b6da911bSLiad Kaufman 	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
4932b6da911bSLiad Kaufman 	struct ieee80211_sub_if_data *sdata = sta->sdata;
4933b6da911bSLiad Kaufman 	struct ieee80211_local *local = sdata->local;
4934b6da911bSLiad Kaufman 	int ret;
4935b6da911bSLiad Kaufman 	u32 queues;
4936b6da911bSLiad Kaufman 
4937b6da911bSLiad Kaufman 	lockdep_assert_held(&local->sta_mtx);
4938b6da911bSLiad Kaufman 
4939b6da911bSLiad Kaufman 	/* only some cases are supported right now */
4940b6da911bSLiad Kaufman 	switch (sdata->vif.type) {
4941b6da911bSLiad Kaufman 	case NL80211_IFTYPE_STATION:
4942b6da911bSLiad Kaufman 	case NL80211_IFTYPE_AP:
4943b6da911bSLiad Kaufman 	case NL80211_IFTYPE_AP_VLAN:
4944b6da911bSLiad Kaufman 		break;
4945b6da911bSLiad Kaufman 	default:
4946b6da911bSLiad Kaufman 		WARN_ON(1);
4947b6da911bSLiad Kaufman 		return -EINVAL;
4948b6da911bSLiad Kaufman 	}
4949b6da911bSLiad Kaufman 
4950b6da911bSLiad Kaufman 	if (WARN_ON(tid >= IEEE80211_NUM_UPS))
4951b6da911bSLiad Kaufman 		return -EINVAL;
4952b6da911bSLiad Kaufman 
4953b6da911bSLiad Kaufman 	if (sta->reserved_tid == tid) {
4954b6da911bSLiad Kaufman 		ret = 0;
4955b6da911bSLiad Kaufman 		goto out;
4956b6da911bSLiad Kaufman 	}
4957b6da911bSLiad Kaufman 
4958b6da911bSLiad Kaufman 	if (sta->reserved_tid != IEEE80211_TID_UNRESERVED) {
4959b6da911bSLiad Kaufman 		sdata_err(sdata, "TID reservation already active\n");
4960b6da911bSLiad Kaufman 		ret = -EALREADY;
4961b6da911bSLiad Kaufman 		goto out;
4962b6da911bSLiad Kaufman 	}
4963b6da911bSLiad Kaufman 
4964b6da911bSLiad Kaufman 	ieee80211_stop_vif_queues(sdata->local, sdata,
4965b6da911bSLiad Kaufman 				  IEEE80211_QUEUE_STOP_REASON_RESERVE_TID);
4966b6da911bSLiad Kaufman 
4967b6da911bSLiad Kaufman 	synchronize_net();
4968b6da911bSLiad Kaufman 
4969b6da911bSLiad Kaufman 	/* Tear down BA sessions so we stop aggregating on this TID */
497030686bf7SJohannes Berg 	if (ieee80211_hw_check(&local->hw, AMPDU_AGGREGATION)) {
4971b6da911bSLiad Kaufman 		set_sta_flag(sta, WLAN_STA_BLOCK_BA);
4972b6da911bSLiad Kaufman 		__ieee80211_stop_tx_ba_session(sta, tid,
4973b6da911bSLiad Kaufman 					       AGG_STOP_LOCAL_REQUEST);
4974b6da911bSLiad Kaufman 	}
4975b6da911bSLiad Kaufman 
4976b6da911bSLiad Kaufman 	queues = BIT(sdata->vif.hw_queue[ieee802_1d_to_ac[tid]]);
49773b24f4c6SEmmanuel Grumbach 	__ieee80211_flush_queues(local, sdata, queues, false);
4978b6da911bSLiad Kaufman 
4979b6da911bSLiad Kaufman 	sta->reserved_tid = tid;
4980b6da911bSLiad Kaufman 
4981b6da911bSLiad Kaufman 	ieee80211_wake_vif_queues(local, sdata,
4982b6da911bSLiad Kaufman 				  IEEE80211_QUEUE_STOP_REASON_RESERVE_TID);
4983b6da911bSLiad Kaufman 
498430686bf7SJohannes Berg 	if (ieee80211_hw_check(&local->hw, AMPDU_AGGREGATION))
4985b6da911bSLiad Kaufman 		clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
4986b6da911bSLiad Kaufman 
4987b6da911bSLiad Kaufman 	ret = 0;
4988b6da911bSLiad Kaufman  out:
4989b6da911bSLiad Kaufman 	return ret;
4990b6da911bSLiad Kaufman }
4991b6da911bSLiad Kaufman EXPORT_SYMBOL(ieee80211_reserve_tid);
4992b6da911bSLiad Kaufman 
4993b6da911bSLiad Kaufman void ieee80211_unreserve_tid(struct ieee80211_sta *pubsta, u8 tid)
4994b6da911bSLiad Kaufman {
4995b6da911bSLiad Kaufman 	struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
4996b6da911bSLiad Kaufman 	struct ieee80211_sub_if_data *sdata = sta->sdata;
4997b6da911bSLiad Kaufman 
4998b6da911bSLiad Kaufman 	lockdep_assert_held(&sdata->local->sta_mtx);
4999b6da911bSLiad Kaufman 
5000b6da911bSLiad Kaufman 	/* only some cases are supported right now */
5001b6da911bSLiad Kaufman 	switch (sdata->vif.type) {
5002b6da911bSLiad Kaufman 	case NL80211_IFTYPE_STATION:
5003b6da911bSLiad Kaufman 	case NL80211_IFTYPE_AP:
5004b6da911bSLiad Kaufman 	case NL80211_IFTYPE_AP_VLAN:
5005b6da911bSLiad Kaufman 		break;
5006b6da911bSLiad Kaufman 	default:
5007b6da911bSLiad Kaufman 		WARN_ON(1);
5008b6da911bSLiad Kaufman 		return;
5009b6da911bSLiad Kaufman 	}
5010b6da911bSLiad Kaufman 
5011b6da911bSLiad Kaufman 	if (tid != sta->reserved_tid) {
5012b6da911bSLiad Kaufman 		sdata_err(sdata, "TID to unreserve (%d) isn't reserved\n", tid);
5013b6da911bSLiad Kaufman 		return;
5014b6da911bSLiad Kaufman 	}
5015b6da911bSLiad Kaufman 
5016b6da911bSLiad Kaufman 	sta->reserved_tid = IEEE80211_TID_UNRESERVED;
5017b6da911bSLiad Kaufman }
5018b6da911bSLiad Kaufman EXPORT_SYMBOL(ieee80211_unreserve_tid);
5019b6da911bSLiad Kaufman 
502055de908aSJohannes Berg void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata,
502155de908aSJohannes Berg 				 struct sk_buff *skb, int tid,
5022b9771d41SJohannes Berg 				 enum nl80211_band band, u32 txdata_flags)
50233b8d81e0SJohannes Berg {
5024731977e9SAmadeusz Sławiński 	int ac = ieee80211_ac_from_tid(tid);
50253a25a8c8SJohannes Berg 
5026d57a544dSZhang Shengju 	skb_reset_mac_header(skb);
50273a25a8c8SJohannes Berg 	skb_set_queue_mapping(skb, ac);
5028cf6bb79aSHelmut Schaa 	skb->priority = tid;
5029cf0277e7SJohannes Berg 
503089afe614SJohannes Berg 	skb->dev = sdata->dev;
503189afe614SJohannes Berg 
50323d34deb6SJohannes Berg 	/*
50333d34deb6SJohannes Berg 	 * The other path calling ieee80211_xmit is from the tasklet,
50343d34deb6SJohannes Berg 	 * and while we can handle concurrent transmissions locking
50353d34deb6SJohannes Berg 	 * requirements are that we do not come into tx with bhs on.
50363d34deb6SJohannes Berg 	 */
50373d34deb6SJohannes Berg 	local_bh_disable();
503873c4e195SJohannes Berg 	IEEE80211_SKB_CB(skb)->band = band;
5039b9771d41SJohannes Berg 	ieee80211_xmit(sdata, NULL, skb, txdata_flags);
50403d34deb6SJohannes Berg 	local_bh_enable();
50413b8d81e0SJohannes Berg }
504291180649SDenis Kenzior 
504391180649SDenis Kenzior int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
504491180649SDenis Kenzior 			      const u8 *buf, size_t len,
504591180649SDenis Kenzior 			      const u8 *dest, __be16 proto, bool unencrypted)
504691180649SDenis Kenzior {
504791180649SDenis Kenzior 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
504891180649SDenis Kenzior 	struct ieee80211_local *local = sdata->local;
504991180649SDenis Kenzior 	struct sk_buff *skb;
505091180649SDenis Kenzior 	struct ethhdr *ehdr;
505191180649SDenis Kenzior 	u32 flags;
505291180649SDenis Kenzior 
505391180649SDenis Kenzior 	/* Only accept CONTROL_PORT_PROTOCOL configured in CONNECT/ASSOCIATE
505491180649SDenis Kenzior 	 * or Pre-Authentication
505591180649SDenis Kenzior 	 */
505691180649SDenis Kenzior 	if (proto != sdata->control_port_protocol &&
505791180649SDenis Kenzior 	    proto != cpu_to_be16(ETH_P_PREAUTH))
505891180649SDenis Kenzior 		return -EINVAL;
505991180649SDenis Kenzior 
506091180649SDenis Kenzior 	if (unencrypted)
506191180649SDenis Kenzior 		flags = IEEE80211_TX_INTFL_DONT_ENCRYPT;
506291180649SDenis Kenzior 	else
506391180649SDenis Kenzior 		flags = 0;
506491180649SDenis Kenzior 
506591180649SDenis Kenzior 	skb = dev_alloc_skb(local->hw.extra_tx_headroom +
506691180649SDenis Kenzior 			    sizeof(struct ethhdr) + len);
506791180649SDenis Kenzior 	if (!skb)
506891180649SDenis Kenzior 		return -ENOMEM;
506991180649SDenis Kenzior 
507091180649SDenis Kenzior 	skb_reserve(skb, local->hw.extra_tx_headroom + sizeof(struct ethhdr));
507191180649SDenis Kenzior 
507291180649SDenis Kenzior 	skb_put_data(skb, buf, len);
507391180649SDenis Kenzior 
507491180649SDenis Kenzior 	ehdr = skb_push(skb, sizeof(struct ethhdr));
507591180649SDenis Kenzior 	memcpy(ehdr->h_dest, dest, ETH_ALEN);
507691180649SDenis Kenzior 	memcpy(ehdr->h_source, sdata->vif.addr, ETH_ALEN);
507791180649SDenis Kenzior 	ehdr->h_proto = proto;
507891180649SDenis Kenzior 
507991180649SDenis Kenzior 	skb->dev = dev;
508091180649SDenis Kenzior 	skb->protocol = htons(ETH_P_802_3);
508191180649SDenis Kenzior 	skb_reset_network_header(skb);
508291180649SDenis Kenzior 	skb_reset_mac_header(skb);
508391180649SDenis Kenzior 
5084e7441c92SDenis Kenzior 	local_bh_disable();
508506016772SRajkumar Manoharan 	__ieee80211_subif_start_xmit(skb, skb->dev, flags, 0);
5086e7441c92SDenis Kenzior 	local_bh_enable();
508791180649SDenis Kenzior 
508891180649SDenis Kenzior 	return 0;
508991180649SDenis Kenzior }
50908828f81aSRajkumar Manoharan 
50918828f81aSRajkumar Manoharan int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev,
50928828f81aSRajkumar Manoharan 			      const u8 *buf, size_t len)
50938828f81aSRajkumar Manoharan {
50948828f81aSRajkumar Manoharan 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
50958828f81aSRajkumar Manoharan 	struct ieee80211_local *local = sdata->local;
50968828f81aSRajkumar Manoharan 	struct sk_buff *skb;
50978828f81aSRajkumar Manoharan 
50988828f81aSRajkumar Manoharan 	skb = dev_alloc_skb(local->hw.extra_tx_headroom + len +
50998828f81aSRajkumar Manoharan 			    30 + /* header size */
51008828f81aSRajkumar Manoharan 			    18); /* 11s header size */
51018828f81aSRajkumar Manoharan 	if (!skb)
51028828f81aSRajkumar Manoharan 		return -ENOMEM;
51038828f81aSRajkumar Manoharan 
51048828f81aSRajkumar Manoharan 	skb_reserve(skb, local->hw.extra_tx_headroom);
51058828f81aSRajkumar Manoharan 	skb_put_data(skb, buf, len);
51068828f81aSRajkumar Manoharan 
51078828f81aSRajkumar Manoharan 	skb->dev = dev;
51088828f81aSRajkumar Manoharan 	skb->protocol = htons(ETH_P_802_3);
51098828f81aSRajkumar Manoharan 	skb_reset_network_header(skb);
51108828f81aSRajkumar Manoharan 	skb_reset_mac_header(skb);
51118828f81aSRajkumar Manoharan 
51128828f81aSRajkumar Manoharan 	local_bh_disable();
51138828f81aSRajkumar Manoharan 	__ieee80211_subif_start_xmit(skb, skb->dev, 0,
51148828f81aSRajkumar Manoharan 				     IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP);
5115e2ebc74dSJohannes Berg 	local_bh_enable();
5116e2ebc74dSJohannes Berg 
5117e2ebc74dSJohannes Berg 	return 0;
5118e2ebc74dSJohannes Berg }
5119