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(ð, 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